Fix build id check for libraries.
The current build id check uses the file utility. Unfortunately, it doesn't work on all systems. Replace with a call to llvm-readelf and get the bitness and build id using that data. Other small modifications: - Only attempt to get the full path for a library once for each library. - Do not add directories into the symbol libraries. Test: Unit tests pass. Test: Running using a libart.so that file doesn't understand and Test: verifying the line numbers are correct. Change-Id: I12c3d3c4599d201c3c01feeb48448fee6c633d71
This commit is contained in:
@@ -60,6 +60,7 @@ class TraceConverter:
|
|||||||
width = "{8}"
|
width = "{8}"
|
||||||
spacing = ""
|
spacing = ""
|
||||||
apk_info = dict()
|
apk_info = dict()
|
||||||
|
lib_to_path = dict()
|
||||||
|
|
||||||
register_names = {
|
register_names = {
|
||||||
"arm": "r0|r1|r2|r3|r4|r5|r6|r7|r8|r9|sl|fp|ip|sp|lr|pc|cpsr",
|
"arm": "r0|r1|r2|r3|r4|r5|r6|r7|r8|r9|sl|fp|ip|sp|lr|pc|cpsr",
|
||||||
@@ -72,8 +73,9 @@ class TraceConverter:
|
|||||||
|
|
||||||
# We use the "file" command line tool to extract BuildId from ELF files.
|
# We use the "file" command line tool to extract BuildId from ELF files.
|
||||||
ElfInfo = collections.namedtuple("ElfInfo", ["bitness", "build_id"])
|
ElfInfo = collections.namedtuple("ElfInfo", ["bitness", "build_id"])
|
||||||
file_tool_output = re.compile(r"ELF (?P<bitness>32|64)-bit .*"
|
readelf_output = re.compile(r"Class:\s*ELF(?P<bitness>32|64).*"
|
||||||
r"BuildID(\[.*\])?=(?P<build_id>[0-9a-f]+)")
|
r"Build ID:\s*(?P<build_id>[0-9a-f]+)",
|
||||||
|
flags=re.DOTALL)
|
||||||
|
|
||||||
def UpdateAbiRegexes(self):
|
def UpdateAbiRegexes(self):
|
||||||
if symbol.ARCH == "arm64" or symbol.ARCH == "mips64" or symbol.ARCH == "x86_64":
|
if symbol.ARCH == "arm64" or symbol.ARCH == "mips64" or symbol.ARCH == "x86_64":
|
||||||
@@ -317,14 +319,16 @@ class TraceConverter:
|
|||||||
def GlobSymbolsDir(self, symbols_dir):
|
def GlobSymbolsDir(self, symbols_dir):
|
||||||
files_by_basename = {}
|
files_by_basename = {}
|
||||||
for path in sorted(pathlib.Path(symbols_dir).glob("**/*")):
|
for path in sorted(pathlib.Path(symbols_dir).glob("**/*")):
|
||||||
|
if os.path.isdir(path):
|
||||||
|
next
|
||||||
files_by_basename.setdefault(path.name, []).append(path)
|
files_by_basename.setdefault(path.name, []).append(path)
|
||||||
return files_by_basename
|
return files_by_basename
|
||||||
|
|
||||||
# Use the "file" command line tool to find the bitness and build_id of given ELF file.
|
# Use the "file" command line tool to find the bitness and build_id of given ELF file.
|
||||||
@functools.lru_cache(maxsize=None)
|
@functools.lru_cache(maxsize=None)
|
||||||
def GetLibraryInfo(self, lib):
|
def GetLibraryInfo(self, lib):
|
||||||
stdout = subprocess.check_output(["file", lib], text=True)
|
stdout = subprocess.check_output([symbol.ToolPath("llvm-readelf"), "-h", "-n", lib], text=True)
|
||||||
match = self.file_tool_output.search(stdout)
|
match = self.readelf_output.search(stdout)
|
||||||
if match:
|
if match:
|
||||||
return self.ElfInfo(bitness=match.group("bitness"), build_id=match.group("build_id"))
|
return self.ElfInfo(bitness=match.group("bitness"), build_id=match.group("build_id"))
|
||||||
return None
|
return None
|
||||||
@@ -339,6 +343,14 @@ class TraceConverter:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def GetLibPath(self, lib):
|
def GetLibPath(self, lib):
|
||||||
|
if lib in self.lib_to_path:
|
||||||
|
return self.lib_to_path[lib]
|
||||||
|
|
||||||
|
lib_path = self.FindLibPath(lib)
|
||||||
|
self.lib_to_path[lib] = lib_path
|
||||||
|
return lib_path
|
||||||
|
|
||||||
|
def FindLibPath(self, lib):
|
||||||
symbol_dir = symbol.SYMBOLS_DIR
|
symbol_dir = symbol.SYMBOLS_DIR
|
||||||
if os.path.isfile(symbol_dir + lib):
|
if os.path.isfile(symbol_dir + lib):
|
||||||
return lib
|
return lib
|
||||||
|
|||||||
Reference in New Issue
Block a user