Merge "Add ndk_missing_symbols.py."
This commit is contained in:
commit
4f11c59b3f
@ -1,11 +1,27 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/env python2
|
||||||
|
#
|
||||||
|
# Copyright (C) 2015 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.
|
||||||
|
#
|
||||||
|
# pylint: disable=bad-indentation,bad-continuation
|
||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import symbols
|
||||||
|
|
||||||
only_unwanted = False
|
only_unwanted = False
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
if sys.argv[1] in ('-u', '--unwanted'):
|
if sys.argv[1] in ('-u', '--unwanted'):
|
||||||
@ -16,62 +32,18 @@ arch = re.sub(r'.*/linux-x86/([^/]+)/.*', r'\1', toolchain)
|
|||||||
if arch == 'aarch64':
|
if arch == 'aarch64':
|
||||||
arch = 'arm64'
|
arch = 'arm64'
|
||||||
|
|
||||||
def GetSymbolsFromTxt(txt_file):
|
|
||||||
symbols = set()
|
|
||||||
f = open(txt_file, 'r')
|
|
||||||
for line in f.read().splitlines():
|
|
||||||
symbols.add(line)
|
|
||||||
f.close()
|
|
||||||
return symbols
|
|
||||||
|
|
||||||
def GetSymbolsFromSo(so_file):
|
|
||||||
# Example readelf output:
|
|
||||||
# 264: 0001623c 4 FUNC GLOBAL DEFAULT 8 cabsf
|
|
||||||
# 266: 00016244 4 FUNC GLOBAL DEFAULT 8 dremf
|
|
||||||
# 267: 00019018 4 OBJECT GLOBAL DEFAULT 11 __fe_dfl_env
|
|
||||||
# 268: 00000000 0 FUNC GLOBAL DEFAULT UND __aeabi_dcmplt
|
|
||||||
|
|
||||||
r = re.compile(r' +\d+: [0-9a-f]+ +\d+ (I?FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)')
|
|
||||||
|
|
||||||
symbols = set()
|
|
||||||
|
|
||||||
for line in subprocess.check_output(['readelf', '--dyn-syms', '-W', so_file]).split('\n'):
|
|
||||||
if ' HIDDEN ' in line or ' UND ' in line:
|
|
||||||
continue
|
|
||||||
m = r.match(line)
|
|
||||||
if m:
|
|
||||||
symbol = m.group(2)
|
|
||||||
symbol = re.sub('@.*', '', symbol)
|
|
||||||
symbols.add(symbol)
|
|
||||||
|
|
||||||
return symbols
|
|
||||||
|
|
||||||
def GetSymbolsFromAndroidSo(*files):
|
|
||||||
symbols = set()
|
|
||||||
for f in files:
|
|
||||||
symbols = symbols | GetSymbolsFromSo('%s/system/lib64/%s' % (os.environ['ANDROID_PRODUCT_OUT'], f))
|
|
||||||
return symbols
|
|
||||||
|
|
||||||
def GetSymbolsFromSystemSo(*files):
|
|
||||||
symbols = set()
|
|
||||||
for f in files:
|
|
||||||
f = glob.glob('/lib/x86_64-linux-gnu/%s' % f)[-1]
|
|
||||||
symbols = symbols | GetSymbolsFromSo(f)
|
|
||||||
return symbols
|
|
||||||
|
|
||||||
def MangleGlibcNameToBionic(name):
|
def MangleGlibcNameToBionic(name):
|
||||||
if name in glibc_to_bionic_names:
|
if name in glibc_to_bionic_names:
|
||||||
return glibc_to_bionic_names[name]
|
return glibc_to_bionic_names[name]
|
||||||
return name
|
return name
|
||||||
|
|
||||||
def GetNdkIgnored():
|
def GetNdkIgnored(arch): # pylint: disable=redefined-outer-name
|
||||||
global arch
|
ignored_symbols = set()
|
||||||
symbols = set()
|
|
||||||
files = glob.glob('%s/ndk/build/tools/unwanted-symbols/%s/*' %
|
files = glob.glob('%s/ndk/build/tools/unwanted-symbols/%s/*' %
|
||||||
(os.getenv('ANDROID_BUILD_TOP'), arch))
|
(os.getenv('ANDROID_BUILD_TOP'), arch))
|
||||||
for f in files:
|
for f in files:
|
||||||
symbols |= set(open(f, 'r').read().splitlines())
|
ignored_symbols |= set(open(f, 'r').read().splitlines())
|
||||||
return symbols
|
return ignored_symbols
|
||||||
|
|
||||||
glibc_to_bionic_names = {
|
glibc_to_bionic_names = {
|
||||||
'__res_init': 'res_init',
|
'__res_init': 'res_init',
|
||||||
@ -81,10 +53,19 @@ glibc_to_bionic_names = {
|
|||||||
'__xpg_basename': '__gnu_basename',
|
'__xpg_basename': '__gnu_basename',
|
||||||
}
|
}
|
||||||
|
|
||||||
glibc = GetSymbolsFromSystemSo('libc.so.*', 'librt.so.*', 'libpthread.so.*', 'libresolv.so.*', 'libm.so.*', 'libutil.so.*')
|
glibc = symbols.GetFromSystemSo([
|
||||||
bionic = GetSymbolsFromAndroidSo('libc.so', 'libm.so')
|
'libc.so.*',
|
||||||
posix = GetSymbolsFromTxt(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'posix-2013.txt'))
|
'librt.so.*',
|
||||||
ndk_ignored = GetNdkIgnored()
|
'libpthread.so.*',
|
||||||
|
'libresolv.so.*',
|
||||||
|
'libm.so.*',
|
||||||
|
'libutil.so.*',
|
||||||
|
])
|
||||||
|
|
||||||
|
bionic = symbols.GetFromAndroidSo(['libc.so', 'libm.so'])
|
||||||
|
this_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
posix = symbols.GetFromTxt(os.path.join(this_dir, 'posix-2013.txt'))
|
||||||
|
ndk_ignored = GetNdkIgnored(arch)
|
||||||
|
|
||||||
glibc = set(map(MangleGlibcNameToBionic, glibc))
|
glibc = set(map(MangleGlibcNameToBionic, glibc))
|
||||||
|
|
||||||
|
44
libc/tools/ndk_missing_symbols.py
Executable file
44
libc/tools/ndk_missing_symbols.py
Executable file
@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env python2
|
||||||
|
#
|
||||||
|
# Copyright (C) 2015 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 os
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
import symbols
|
||||||
|
|
||||||
|
|
||||||
|
def adb_pull(src, dst):
|
||||||
|
with open(os.devnull, 'w') as devnull:
|
||||||
|
subprocess.check_call(['adb', 'pull', src, dst],
|
||||||
|
stdout=devnull, stderr=devnull)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
tmp_dir = tempfile.mkdtemp()
|
||||||
|
adb_pull('/system/lib/libc.so', tmp_dir)
|
||||||
|
adb_pull('/system/lib/libm.so', tmp_dir)
|
||||||
|
|
||||||
|
current = symbols.GetFromAndroidSo(['libc.so', 'libm.so'])
|
||||||
|
device = (symbols.GetFromSo(os.path.join(tmp_dir, 'libc.so')) |
|
||||||
|
symbols.GetFromSo(os.path.join(tmp_dir, 'libm.so')))
|
||||||
|
|
||||||
|
for symbol in sorted(current - device):
|
||||||
|
print symbol
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
74
libc/tools/symbols.py
Normal file
74
libc/tools/symbols.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2015 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 glob
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
def GetFromTxt(txt_file):
|
||||||
|
symbols = set()
|
||||||
|
f = open(txt_file, 'r')
|
||||||
|
for line in f.read().splitlines():
|
||||||
|
symbols.add(line)
|
||||||
|
f.close()
|
||||||
|
return symbols
|
||||||
|
|
||||||
|
|
||||||
|
def GetFromSo(so_file):
|
||||||
|
# pylint: disable=line-too-long
|
||||||
|
# Example readelf output:
|
||||||
|
# 264: 0001623c 4 FUNC GLOBAL DEFAULT 8 cabsf
|
||||||
|
# 266: 00016244 4 FUNC GLOBAL DEFAULT 8 dremf
|
||||||
|
# 267: 00019018 4 OBJECT GLOBAL DEFAULT 11 __fe_dfl_env
|
||||||
|
# 268: 00000000 0 FUNC GLOBAL DEFAULT UND __aeabi_dcmplt
|
||||||
|
|
||||||
|
r = re.compile(
|
||||||
|
r' +\d+: [0-9a-f]+ +\d+ (I?FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)')
|
||||||
|
|
||||||
|
symbols = set()
|
||||||
|
|
||||||
|
output = subprocess.check_output(['readelf', '--dyn-syms', '-W', so_file])
|
||||||
|
for line in output.split('\n'):
|
||||||
|
if ' HIDDEN ' in line or ' UND ' in line:
|
||||||
|
continue
|
||||||
|
m = r.match(line)
|
||||||
|
if m:
|
||||||
|
symbol = m.group(2)
|
||||||
|
symbol = re.sub('@.*', '', symbol)
|
||||||
|
symbols.add(symbol)
|
||||||
|
|
||||||
|
return symbols
|
||||||
|
|
||||||
|
|
||||||
|
def GetFromAndroidSo(files):
|
||||||
|
out_dir = os.environ['ANDROID_PRODUCT_OUT']
|
||||||
|
lib_dir = os.path.join(out_dir, 'system/lib64')
|
||||||
|
if not os.path.isdir(lib_dir):
|
||||||
|
lib_dir = os.path.join(out_dir, 'system/lib')
|
||||||
|
|
||||||
|
results = set()
|
||||||
|
for f in files:
|
||||||
|
results |= GetFromSo(os.path.join(lib_dir, f))
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def GetFromSystemSo(files):
|
||||||
|
lib_dir = '/lib/x86_64-linux-gnu'
|
||||||
|
results = set()
|
||||||
|
for f in files:
|
||||||
|
results |= GetFromSo(glob.glob(os.path.join(lib_dir, f))[-1])
|
||||||
|
return results
|
Loading…
x
Reference in New Issue
Block a user