diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-06-29 07:30:35 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-06-29 07:30:35 +0000 |
commit | 69fdb035569978319eb451e3551f3c6d71d0b78a (patch) | |
tree | 7c4b817e2c3cbabcf83fb1c796906d137299c5ca | |
parent | 4dcb7fefa3fc3fae50b743b6381b18d24b3d9594 (diff) | |
parent | 48f39a910eadd51a45dd45404c00acad2fbf6c3f (diff) | |
download | vndk-oreo-m6-s4-release.tar.gz |
release-request-fbba21d1-17b5-4752-9864-95770e5db190-for-git_oc-mr1-release-4144771 snap-temp-L10300000078657232android-wear-8.1.0_r1android-security-8.1.0_r93android-security-8.1.0_r92android-security-8.1.0_r91android-security-8.1.0_r90android-security-8.1.0_r89android-security-8.1.0_r88android-security-8.1.0_r87android-security-8.1.0_r86android-security-8.1.0_r85android-security-8.1.0_r84android-security-8.1.0_r83android-security-8.1.0_r82android-cts-8.1_r9android-cts-8.1_r8android-cts-8.1_r7android-cts-8.1_r6android-cts-8.1_r5android-cts-8.1_r4android-cts-8.1_r3android-cts-8.1_r25android-cts-8.1_r24android-cts-8.1_r23android-cts-8.1_r22android-cts-8.1_r21android-cts-8.1_r20android-cts-8.1_r2android-cts-8.1_r19android-cts-8.1_r18android-cts-8.1_r17android-cts-8.1_r16android-cts-8.1_r15android-cts-8.1_r14android-cts-8.1_r13android-cts-8.1_r12android-cts-8.1_r11android-cts-8.1_r10android-cts-8.1_r1android-8.1.0_r9android-8.1.0_r81android-8.1.0_r80android-8.1.0_r8android-8.1.0_r79android-8.1.0_r78android-8.1.0_r77android-8.1.0_r76android-8.1.0_r75android-8.1.0_r74android-8.1.0_r73android-8.1.0_r72android-8.1.0_r71android-8.1.0_r70android-8.1.0_r7android-8.1.0_r69android-8.1.0_r68android-8.1.0_r67android-8.1.0_r66android-8.1.0_r65android-8.1.0_r64android-8.1.0_r63android-8.1.0_r62android-8.1.0_r61android-8.1.0_r60android-8.1.0_r6android-8.1.0_r53android-8.1.0_r52android-8.1.0_r51android-8.1.0_r50android-8.1.0_r5android-8.1.0_r48android-8.1.0_r47android-8.1.0_r46android-8.1.0_r45android-8.1.0_r43android-8.1.0_r42android-8.1.0_r41android-8.1.0_r40android-8.1.0_r4android-8.1.0_r39android-8.1.0_r38android-8.1.0_r37android-8.1.0_r36android-8.1.0_r35android-8.1.0_r33android-8.1.0_r32android-8.1.0_r31android-8.1.0_r30android-8.1.0_r3android-8.1.0_r29android-8.1.0_r28android-8.1.0_r27android-8.1.0_r26android-8.1.0_r25android-8.1.0_r23android-8.1.0_r22android-8.1.0_r21android-8.1.0_r20android-8.1.0_r2android-8.1.0_r19android-8.1.0_r18android-8.1.0_r17android-8.1.0_r16android-8.1.0_r15android-8.1.0_r14android-8.1.0_r13android-8.1.0_r12android-8.1.0_r11android-8.1.0_r10android-8.1.0_r1security-oc-mr1-releaseoreo-mr1-wear-releaseoreo-mr1-security-releaseoreo-mr1-s1-releaseoreo-mr1-releaseoreo-mr1-cuttlefish-testingoreo-mr1-cts-releaseoreo-m8-releaseoreo-m7-releaseoreo-m6-s4-releaseoreo-m6-s3-releaseoreo-m6-s2-releaseoreo-m5-releaseoreo-m4-s9-releaseoreo-m4-s8-releaseoreo-m4-s7-releaseoreo-m4-s6-releaseoreo-m4-s5-releaseoreo-m4-s4-releaseoreo-m4-s3-releaseoreo-m4-s2-releaseoreo-m4-s12-releaseoreo-m4-s11-releaseoreo-m4-s10-releaseoreo-m4-s1-releaseoreo-m3-releaseoreo-m2-s5-releaseoreo-m2-s4-releaseoreo-m2-s3-releaseoreo-m2-s2-releaseoreo-m2-s1-releaseoreo-m2-release
Change-Id: I133563ba3560338e72691459eaf886dba723a379
-rwxr-xr-x | golden/dump_abi.py | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/golden/dump_abi.py b/golden/dump_abi.py new file mode 100755 index 0000000..e4202d1 --- /dev/null +++ b/golden/dump_abi.py @@ -0,0 +1,260 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import argparse +import importlib +import os +import subprocess +import sys + + +class ExternalModules(object): + """This class imports modules dynamically and keeps them as attributes. + + Assume the user runs this script in the source directory. The VTS modules + are outside the search path and thus have to be imported dynamically. + + Attribtues: + elf_parser: The elf_parser module. + vtable_parser: The vtable_parser module. + """ + @classmethod + def ImportParsers(cls, import_dir): + """Imports elf_parser and vtable_parser. + + Args: + import_dir: The directory containing vts.utils.python.library.*. + """ + sys.path.append(import_dir) + cls.elf_parser = importlib.import_module( + "vts.utils.python.library.elf_parser") + cls.vtable_parser = importlib.import_module( + "vts.utils.python.library.vtable_parser") + + +def GetBuildVariable(build_top_dir, var): + """Gets value of a variable from build config. + + Args: + build_top_dir: The path to root directory of Android source. + var: The name of the variable. + + Returns: + A string which is the value of the variable. + """ + build_core = os.path.join(build_top_dir, "build", "core") + env = dict(os.environ) + env["CALLED_FROM_SETUP"] = "true" + env["BUILD_SYSTEM"] = build_core + cmd = ["make", "--no-print-directory", + "-f", os.path.join(build_core, "config.mk"), + "dumpvar-" + var] + proc = subprocess.Popen(cmd, env=env, cwd=build_top_dir, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = proc.communicate() + if stderr: + sys.exit("Cannot get variable: cmd=%s\nstdout=%s\nstderr=%s" % ( + cmd, stdout, stderr)) + return stdout.strip() + + +def FindBinary(file_name): + """Finds an executable binary in environment variable PATH. + + Args: + file_name: The file name to find. + + Returns: + A string which is the path to the binary. + """ + cmd = ["which", file_name] + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = proc.communicate() + if proc.returncode: + sys.exit("Cannot find file: cmd=%s\nstdout=%s\nstderr=%s" % ( + cmd, stdout, stderr)) + return stdout + + +def DumpSymbols(lib_path, dump_path): + """Dump symbols from a library to a dump file. + + The dump file is a sorted list of symbols. Each line contains one symbol. + + Args: + lib_path: The path to the library. + dump_path: The path to the dump file. + + Returns: + A string which is the description about the result. + + Raises: + elf_parser.ElfError if fails to load the library. + IOError if fails to write to the dump. + """ + elf_parser = ExternalModules.elf_parser + parser = None + try: + parser = elf_parser.ElfParser(lib_path) + symbols = parser.ListGlobalDynamicSymbols() + finally: + if parser: + parser.Close() + if not symbols: + return "No symbols" + symbols.sort() + with open(dump_path, "w") as dump_file: + dump_file.write("\n".join(symbols) + "\n") + return "Output: " + dump_path + + +def DumpVtables(lib_path, dump_path, dumper_dir): + """Dump vtables from a library to a dump file. + + The dump file is the raw output of vndk-vtable-dumper. + + Args: + lib_path: The path to the library. + dump_path: The path to the text file. + dumper_dir: The path to the directory containing the dumper executable + and library. + + Returns: + A string which is the description about the result. + + Raises: + vtable_parser.VtableError if fails to load the library. + IOError if fails to write to the dump. + """ + vtable_parser = ExternalModules.vtable_parser + parser = vtable_parser.VtableParser(dumper_dir) + vtables = parser.CallVtableDumper(lib_path) + if not vtables: + return "No vtables" + with open(dump_path, "w+") as dump_file: + dump_file.write(vtables) + return "Output: " + dump_path + + +def GetSystemLibDirByArch(product_dir, arch_name): + """Returns the directory containing libraries for specific architecture. + + Args: + product_dir: The path to the product output directory in Android source. + arch_name: The name of the CPU architecture. + + Returns: + The path to the directory containing the libraries. + """ + if arch_name in ("arm", "x86", "mips"): + src_dir = os.path.join(product_dir, "system", "lib") + elif arch_name in ("arm64", "x86_64", "mips64"): + src_dir = os.path.join(product_dir, "system", "lib64") + else: + sys.exit("Unknown target arch " + str(target_arch)) + return src_dir + + +def DumpAbi(output_dir, input_files, product_dir, archs, dumper_dir): + """Generates dump from libraries. + + Args: + output_dir: The output directory of dump files. + input_files: A list of strings. Each element can be .so file or a text + file which contains list of libraries. + product_dir: The path to the product output directory in Android source. + archs: A list of strings which are the CPU architectures of the + libraries. + dumper_dir: The path to the directory containing the vtable dumper + executable and library. + """ + # Get names of the libraries to dump + lib_names = [] + for input_file in input_files: + if input_file.endswith(".so"): + lib_names.append(input_file) + else: + with open(input_file, "r") as lib_list: + lib_names.extend(line.strip() for line in lib_list + if line.strip()) + # Create the dumps + for arch in archs: + lib_dir = GetSystemLibDirByArch(product_dir, arch) + dump_dir = os.path.join(output_dir, arch) + if not os.path.exists(dump_dir): + os.makedirs(dump_dir) + for lib_name in lib_names: + lib_path = os.path.join(lib_dir, lib_name) + symbol_dump_path = os.path.join(dump_dir, lib_name + "_symbol.dump") + vtable_dump_path = os.path.join(dump_dir, lib_name + "_vtable.dump") + print(lib_path) + print(DumpSymbols(lib_path, symbol_dump_path)) + print(DumpVtables(lib_path, vtable_dump_path, dumper_dir)) + print("") + + +def main(): + # Parse arguments + arg_parser = argparse.ArgumentParser() + arg_parser.add_argument("file", nargs="*", + help="the library to dump. Can be .so file or a" + "text file containing list of libraries.") + arg_parser.add_argument("--dumper-dir", "-d", action="store", + help="the path to the directory containing " + "bin/vndk-vtable-dumper.") + arg_parser.add_argument("--import-path", "-i", action="store", + help="the directory for VTS python modules. " + "Default value is $ANDROID_BUILD_TOP/test") + arg_parser.add_argument("--output", "-o", action="store", required=True, + help="output directory for ABI reference dump.") + args = arg_parser.parse_args() + + # Get product directory + product_dir = os.getenv("ANDROID_PRODUCT_OUT") + if not product_dir: + sys.exit("env var ANDROID_PRODUCT_OUT is not set") + print("ANDROID_PRODUCT_OUT=" + product_dir) + + # Get target architectures + build_top_dir = os.getenv("ANDROID_BUILD_TOP") + if not build_top_dir: + sys.exit("env var ANDROID_BUILD_TOP is not set") + target_arch = GetBuildVariable(build_top_dir, "TARGET_ARCH") + target_2nd_arch = GetBuildVariable(build_top_dir, "TARGET_2ND_ARCH") + print("TARGET_ARCH=" + target_arch) + print("TARGET_2ND_ARCH=" + target_2nd_arch) + archs = [target_arch] + if target_2nd_arch: + archs.append(target_2nd_arch) + + # Import elf_parser and vtable_parser + ExternalModules.ImportParsers(args.import_path if args.import_path else + os.path.join(build_top_dir, "test")) + + # Find vtable dumper + if args.dumper_dir: + dumper_dir = args.dumper_dir + else: + dumper_path = FindBinary(vtable_parser.VtableParser.VNDK_VTABLE_DUMPER) + dumper_dir = os.path.dirname(os.path.dirname(dumper_path)) + print("DUMPER_DIR=" + dumper_dir) + + DumpAbi(args.output, args.file, product_dir, archs, dumper_dir) + + +if __name__ == "__main__": + main() |