16e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne#!/usr/bin/env python 26e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne#===- lib/dfsan/scripts/build-libc-list.py ---------------------------------===# 36e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne# 46e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne# The LLVM Compiler Infrastructure 56e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne# 66e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne# This file is distributed under the University of Illinois Open Source 76e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne# License. See LICENSE.TXT for details. 86e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne# 96e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne#===------------------------------------------------------------------------===# 106e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne# The purpose of this script is to identify every function symbol in a set of 116e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne# libraries (in this case, libc and libgcc) so that they can be marked as 126e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne# uninstrumented, thus allowing the instrumentation pass to treat calls to those 136e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne# functions correctly. 146e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 156e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourneimport os 166e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourneimport subprocess 176e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourneimport sys 186e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbournefrom optparse import OptionParser 196e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 206e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbournedef defined_function_list(object): 216e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne functions = [] 226e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne readelf_proc = subprocess.Popen(['readelf', '-s', '-W', object], 236e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne stdout=subprocess.PIPE) 246e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne readelf = readelf_proc.communicate()[0].split('\n') 256e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne if readelf_proc.returncode != 0: 266e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne raise subprocess.CalledProcessError(readelf_proc.returncode, 'readelf') 276e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne for line in readelf: 286e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne if (line[31:35] == 'FUNC' or line[31:36] == 'IFUNC') and \ 296e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne line[55:58] != 'UND': 306e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne function_name = line[59:].split('@')[0] 316e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne functions.append(function_name) 326e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne return functions 336e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 346e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbournep = OptionParser() 352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesp.add_option('--libc-dso-path', metavar='PATH', 372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines help='path to libc DSO directory', 386e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne default='/lib/x86_64-linux-gnu') 392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesp.add_option('--libc-archive-path', metavar='PATH', 402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines help='path to libc archive directory', 416e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne default='/usr/lib/x86_64-linux-gnu') 422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesp.add_option('--libgcc-dso-path', metavar='PATH', 442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines help='path to libgcc DSO directory', 452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines default='/lib/x86_64-linux-gnu') 462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesp.add_option('--libgcc-archive-path', metavar='PATH', 472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines help='path to libgcc archive directory', 486e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne default='/usr/lib/gcc/x86_64-linux-gnu/4.6') 492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 506e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbournep.add_option('--with-libstdcxx', action='store_true', 516e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne dest='with_libstdcxx', 526e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne help='include libstdc++ in the list (inadvisable)') 532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesp.add_option('--libstdcxx-dso-path', metavar='PATH', 542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines help='path to libstdc++ DSO directory', 552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines default='/usr/lib/x86_64-linux-gnu') 562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 576e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne(options, args) = p.parse_args() 586e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hineslibs = [os.path.join(options.libc_dso_path, name) for name in 606e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne ['ld-linux-x86-64.so.2', 616e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'libanl.so.1', 626e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'libBrokenLocale.so.1', 636e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'libcidn.so.1', 646e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'libcrypt.so.1', 656e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'libc.so.6', 666e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'libdl.so.2', 676e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'libm.so.6', 686e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'libnsl.so.1', 696e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'libpthread.so.0', 706e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'libresolv.so.2', 716e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'librt.so.1', 726e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'libthread_db.so.1', 736e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'libutil.so.1']] 742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hineslibs += [os.path.join(options.libc_archive_path, name) for name in 756e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne ['libc_nonshared.a', 766e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 'libpthread_nonshared.a']] 772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hineslibs.append(os.path.join(options.libgcc_dso_path, 'libgcc_s.so.1')) 792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hineslibs.append(os.path.join(options.libgcc_archive_path, 'libgcc.a')) 802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 816e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourneif options.with_libstdcxx: 822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines libs.append(os.path.join(options.libstdcxx_dso_path, 'libstdc++.so.6')) 836e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 846e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbournefunctions = [] 856e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbournefor l in libs: 866e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne if os.path.exists(l): 876e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne functions += defined_function_list(l) 886e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne else: 896e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne print >> sys.stderr, 'warning: library %s not found' % l 906e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 916e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbournefunctions = list(set(functions)) 926e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbournefunctions.sort() 936e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne 946e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbournefor f in functions: 956e4c46dc162803cc99c2a5e068fc28adb873a431Peter Collingbourne print 'fun:%s=uninstrumented' % f 96