Home | History | Annotate | Download | only in tools
      1 #
      2 # Copyright (C) 2015 The Android Open Source Project
      3 #
      4 # Licensed under the Apache License, Version 2.0 (the 'License');
      5 # you may not use this file except in compliance with the License.
      6 # You may obtain a copy of the License at
      7 #
      8 #      http://www.apache.org/licenses/LICENSE-2.0
      9 #
     10 # Unless required by applicable law or agreed to in writing, software
     11 # distributed under the License is distributed on an 'AS IS' BASIS,
     12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 # See the License for the specific language governing permissions and
     14 # limitations under the License.
     15 #
     16 import glob
     17 import os
     18 import re
     19 import subprocess
     20 
     21 
     22 def GetFromTxt(txt_file):
     23     symbols = set()
     24     f = open(txt_file, 'r')
     25     for line in f.read().splitlines():
     26         symbols.add(line)
     27     f.close()
     28     return symbols
     29 
     30 
     31 def GetFromElf(elf_file, sym_type='--dyn-syms'):
     32     # pylint: disable=line-too-long
     33     # Example readelf output:
     34     #     264: 0001623c         4 FUNC        GLOBAL DEFAULT        8 cabsf
     35     #     266: 00016244         4 FUNC        GLOBAL DEFAULT        8 dremf
     36     #     267: 00019018         4 OBJECT    GLOBAL DEFAULT     11 __fe_dfl_env
     37     #     268: 00000000         0 FUNC        GLOBAL DEFAULT    UND __aeabi_dcmplt
     38 
     39     r = re.compile(
     40         r' +\d+: [0-9a-f]+ +\d+ (I?FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)')
     41 
     42     symbols = set()
     43 
     44     output = subprocess.check_output(['readelf', sym_type, '-W', elf_file])
     45     for line in output.split('\n'):
     46         if ' HIDDEN ' in line or ' UND ' in line:
     47             continue
     48         m = r.match(line)
     49         if m:
     50             symbol = m.group(2)
     51             symbol = re.sub('@.*', '', symbol)
     52             symbols.add(symbol)
     53 
     54     return symbols
     55 
     56 
     57 def GetFromAndroidStaticLib(files):
     58     out_dir = os.environ['ANDROID_PRODUCT_OUT']
     59     lib_dir = os.path.join(out_dir, 'obj')
     60 
     61     results = set()
     62     for f in files:
     63         static_lib_dir = os.path.join(
     64             lib_dir,
     65             'STATIC_LIBRARIES',
     66             '{}_intermediates'.format(os.path.splitext(f)[0]))
     67         results |= GetFromElf(
     68             os.path.join(static_lib_dir, f),
     69             sym_type='--syms')
     70     return results
     71 
     72 
     73 def GetFromAndroidSo(files):
     74     out_dir = os.environ['ANDROID_PRODUCT_OUT']
     75     lib_dir = os.path.join(out_dir, 'system/lib64')
     76     if not os.path.isdir(lib_dir):
     77         lib_dir = os.path.join(out_dir, 'system/lib')
     78 
     79     results = set()
     80     for f in files:
     81         results |= GetFromElf(os.path.join(lib_dir, f))
     82     return results
     83 
     84 
     85 def GetFromSystemSo(files):
     86     lib_dir = '/lib/x86_64-linux-gnu'
     87     results = set()
     88     for f in files:
     89         results |= GetFromElf(glob.glob(os.path.join(lib_dir, f))[-1])
     90     return results
     91