1169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert#
2169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert# Copyright (C) 2015 The Android Open Source Project
3169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert#
4169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert# Licensed under the Apache License, Version 2.0 (the 'License');
5169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert# you may not use this file except in compliance with the License.
6169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert# You may obtain a copy of the License at
7169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert#
8169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert#      http://www.apache.org/licenses/LICENSE-2.0
9169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert#
10169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert# Unless required by applicable law or agreed to in writing, software
11169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert# distributed under the License is distributed on an 'AS IS' BASIS,
12169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert# See the License for the specific language governing permissions and
14169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert# limitations under the License.
15169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert#
16169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albertimport glob
17169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albertimport os
18169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albertimport re
19169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albertimport subprocess
20169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert
21169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert
22169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albertdef GetFromTxt(txt_file):
23169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    symbols = set()
24169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    f = open(txt_file, 'r')
25169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    for line in f.read().splitlines():
26169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert        symbols.add(line)
27169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    f.close()
28169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    return symbols
29169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert
30169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert
319c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albertdef GetFromElf(elf_file, sym_type='--dyn-syms'):
32169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    # pylint: disable=line-too-long
33169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    # Example readelf output:
34169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    #     264: 0001623c         4 FUNC        GLOBAL DEFAULT        8 cabsf
35169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    #     266: 00016244         4 FUNC        GLOBAL DEFAULT        8 dremf
36169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    #     267: 00019018         4 OBJECT    GLOBAL DEFAULT     11 __fe_dfl_env
37169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    #     268: 00000000         0 FUNC        GLOBAL DEFAULT    UND __aeabi_dcmplt
38169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert
39169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    r = re.compile(
40169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert        r' +\d+: [0-9a-f]+ +\d+ (I?FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)')
41169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert
42169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    symbols = set()
43169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert
449c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert    output = subprocess.check_output(['readelf', sym_type, '-W', elf_file])
45169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    for line in output.split('\n'):
46169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert        if ' HIDDEN ' in line or ' UND ' in line:
47169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert            continue
48169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert        m = r.match(line)
49169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert        if m:
50169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert            symbol = m.group(2)
51169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert            symbol = re.sub('@.*', '', symbol)
52169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert            symbols.add(symbol)
53169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert
54169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    return symbols
55169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert
56169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert
579c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albertdef GetFromAndroidStaticLib(files):
589c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert    out_dir = os.environ['ANDROID_PRODUCT_OUT']
599c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert    lib_dir = os.path.join(out_dir, 'obj')
609c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert
619c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert    results = set()
629c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert    for f in files:
639c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert        static_lib_dir = os.path.join(
649c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert            lib_dir,
659c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert            'STATIC_LIBRARIES',
669c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert            '{}_intermediates'.format(os.path.splitext(f)[0]))
679c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert        results |= GetFromElf(
689c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert            os.path.join(static_lib_dir, f),
699c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert            sym_type='--syms')
709c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert    return results
719c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert
729c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert
73169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albertdef GetFromAndroidSo(files):
74169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    out_dir = os.environ['ANDROID_PRODUCT_OUT']
75169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    lib_dir = os.path.join(out_dir, 'system/lib64')
76169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    if not os.path.isdir(lib_dir):
77169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert        lib_dir = os.path.join(out_dir, 'system/lib')
78169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert
79169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    results = set()
80169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    for f in files:
819c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert        results |= GetFromElf(os.path.join(lib_dir, f))
82169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    return results
83169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert
84169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert
85169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albertdef GetFromSystemSo(files):
86169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    lib_dir = '/lib/x86_64-linux-gnu'
87169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    results = set()
88169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    for f in files:
899c3fd59b00d6f477b1a7f8611cb4f829d64aa7eaDan Albert        results |= GetFromElf(glob.glob(os.path.join(lib_dir, f))[-1])
90169eb664511ecd5f7dfa6f0cb9ea668000373d96Dan Albert    return results
91