Fix pylibdexfile

pylibdexfile dynamically links to libdexfiled. This updates
pylibdexfile to match recent changes to libdexfiled that
(intentionally) broke backwards compatibility.

Test: ./art/tools/bisect_profile.py --apk ~/imgur.apk --output-source bad-compile.txt bad-compile.prof
Bug: 183942773
Bug: 123517037
Change-Id: Ie03f40041912e154996f5fbd0557da2d571b77fc
diff --git a/tools/pylibdexfile.py b/tools/pylibdexfile.py
index 953cf0d..83e7685 100644
--- a/tools/pylibdexfile.py
+++ b/tools/pylibdexfile.py
@@ -25,41 +25,29 @@
 import zipfile
 
 libdexfile = CDLL(
-    os.path.expandvars("$ANDROID_HOST_OUT/lib64/libdexfile.so"))
+    os.path.expandvars("$ANDROID_HOST_OUT/lib64/libdexfiled.so"))
 
-DexFileStr = c_void_p
 ExtDexFile = c_void_p
 
-
 class ExtMethodInfo(Structure):
   """Output format for MethodInfo"""
-  _fields_ = [("offset", c_int32), ("len", c_int32), ("name", DexFileStr)]
+  _fields_ = [("sizeof_struct", c_size_t),
+              ("addr", c_int32),
+              ("size", c_int32),
+              ("name", POINTER(c_char)),
+              ("name_size", c_size_t)]
 
-
-AllMethodsCallback = CFUNCTYPE(c_int, POINTER(ExtMethodInfo), c_void_p)
-libdexfile.ExtDexFileOpenFromFd.argtypes = [
-    c_int, c_size_t, c_char_p,
-    POINTER(DexFileStr),
-    POINTER(ExtDexFile)
-]
-libdexfile.ExtDexFileOpenFromFd.restype = c_int
+AllMethodsCallback = CFUNCTYPE(c_int, c_void_p, POINTER(ExtMethodInfo))
 libdexfile.ExtDexFileOpenFromMemory.argtypes = [
     c_void_p,
-    POINTER(c_size_t), c_char_p,
-    POINTER(DexFileStr),
+    POINTER(c_size_t),
+    c_char_p,
     POINTER(ExtDexFile)
 ]
 libdexfile.ExtDexFileOpenFromMemory.restype = c_int
-libdexfile.ExtDexFileFree.argtypes = [ExtDexFile]
 libdexfile.ExtDexFileGetAllMethodInfos.argtypes = [
     ExtDexFile, c_int, AllMethodsCallback, c_void_p
 ]
-libdexfile.ExtDexFileGetString.argtypes = [
-    DexFileStr, POINTER(c_size_t)
-]
-libdexfile.ExtDexFileGetString.restype = c_char_p
-libdexfile.ExtDexFileFreeString.argtypes = [DexFileStr]
-
 
 class DexClass(object):
   """Accessor for DexClass Data"""
@@ -103,11 +91,9 @@
   """Method info wrapper"""
 
   def __init__(self, mi):
-    self.offset = mi.offset
-    self.len = mi.len
-    self.name = libdexfile.ExtDexFileGetString(
-        mi.name, byref(c_size_t(0))).decode("utf-8")
-    libdexfile.ExtDexFileFreeString(mi.name)
+    self.offset = mi.addr
+    self.len = mi.size
+    self.name = string_at(mi.name, mi.name_size).decode("utf-8")
 
   def __repr__(self):
     return "(" + self.name + ")"
@@ -159,7 +145,7 @@
     meths = []
 
     @AllMethodsCallback
-    def my_cb(info, _):
+    def my_cb(_, info):
       """Callback visitor for method infos"""
       meths.append(Method(info[0]))
       return 0
@@ -168,37 +154,6 @@
                                            c_int(1), my_cb, c_void_p())
     return meths
 
-
-class FdDexFile(BaseDexFile):
-  """DexFile using an opened file-descriptor"""
-
-  def __init__(self, fd, loc):
-    super().__init__()
-    res_fle_ptr = pointer(c_void_p())
-    err_ptr = pointer(c_void_p())
-    res = libdexfile.ExtDexFileOpenFromFd(
-        c_int(fd), 0, create_string_buffer(bytes(loc, "utf-8")), err_ptr,
-        res_fle_ptr)
-    if res == 0:
-      err = libdexfile.ExtDexFileGetString(err_ptr.contents,
-                                           byref(c_size_t()))
-      out = Exception("Failed to open file: {}. Error was: {}".format(loc, err))
-      libdexfile.ExtDexFileFreeString(err_ptr.contents)
-      raise out
-    self.ext_dex_file_ = res_fle_ptr.contents
-
-
-class FileDexFile(FdDexFile):
-  """DexFile using a file"""
-
-  def __init__(self, file, loc):
-    if type(file) == str:
-      self.file = open(file, "rb")
-    else:
-      self.file = file
-    super().__init__(self.file.fileno(), loc)
-
-
 class MemDexFile(BaseDexFile):
   """DexFile using memory"""
 
@@ -208,18 +163,24 @@
     # Don't want GC to screw us over.
     self.mem_ref = (c_byte * len(dat)).from_buffer_copy(dat)
     res_fle_ptr = pointer(c_void_p())
-    err_ptr = pointer(c_void_p())
     res = libdexfile.ExtDexFileOpenFromMemory(
         self.mem_ref, byref(c_size_t(len(dat))),
-        create_string_buffer(bytes(loc, "utf-8")), err_ptr, res_fle_ptr)
-    if res == 0:
-      err = libdexfile.ExtDexFileGetString(err_ptr.contents,
-                                           byref(c_size_t()))
-      out = Exception("Failed to open file: {}. Error was: {}".format(loc, err))
-      libdexfile.ExtDexFileFreeString(err_ptr.contents)
-      raise out
+        create_string_buffer(bytes(loc, "utf-8")), res_fle_ptr)
+    if res != 0:
+      raise Exception("Failed to open file: {}. Error {}.".format(loc, res))
     self.ext_dex_file_ = res_fle_ptr.contents
 
+class FileDexFile(MemDexFile):
+  """DexFile using a file"""
+
+  def __init__(self, file, loc):
+    if type(file) == str:
+      self.file = open(file, "rb")
+      self.loc = file
+    else:
+      self.file = file
+      self.loc = "file_obj"
+    super().__init__(self.file.read(), self.loc)
 
 def OpenJar(fle):
   """Opens all classes[0-9]*.dex files in a zip archive"""