Home | History | Annotate | Download | only in scripts
      1 #!/usr/bin/env python
      2 #===- lib/dfsan/scripts/build-libc-list.py ---------------------------------===#
      3 #
      4 #                     The LLVM Compiler Infrastructure
      5 #
      6 # This file is distributed under the University of Illinois Open Source
      7 # License. See LICENSE.TXT for details.
      8 #
      9 #===------------------------------------------------------------------------===#
     10 # The purpose of this script is to identify every function symbol in a set of
     11 # libraries (in this case, libc and libgcc) so that they can be marked as
     12 # uninstrumented, thus allowing the instrumentation pass to treat calls to those
     13 # functions correctly.
     14 
     15 import os
     16 import subprocess
     17 import sys
     18 from optparse import OptionParser
     19 
     20 def defined_function_list(object):
     21   functions = []
     22   readelf_proc = subprocess.Popen(['readelf', '-s', '-W', object],
     23                                   stdout=subprocess.PIPE)
     24   readelf = readelf_proc.communicate()[0].split('\n')
     25   if readelf_proc.returncode != 0:
     26     raise subprocess.CalledProcessError(readelf_proc.returncode, 'readelf')
     27   for line in readelf:
     28     if (line[31:35] == 'FUNC' or line[31:36] == 'IFUNC') and \
     29        line[39:44] != 'LOCAL' and \
     30        line[55:58] != 'UND':
     31       function_name = line[59:].split('@')[0]
     32       functions.append(function_name)
     33   return functions
     34 
     35 p = OptionParser()
     36 
     37 p.add_option('--libc-dso-path', metavar='PATH',
     38              help='path to libc DSO directory',
     39              default='/lib/x86_64-linux-gnu')
     40 p.add_option('--libc-archive-path', metavar='PATH',
     41              help='path to libc archive directory',
     42              default='/usr/lib/x86_64-linux-gnu')
     43 
     44 p.add_option('--libgcc-dso-path', metavar='PATH',
     45              help='path to libgcc DSO directory',
     46              default='/lib/x86_64-linux-gnu')
     47 p.add_option('--libgcc-archive-path', metavar='PATH',
     48              help='path to libgcc archive directory',
     49              default='/usr/lib/gcc/x86_64-linux-gnu/4.6')
     50 
     51 p.add_option('--with-libstdcxx', action='store_true',
     52              dest='with_libstdcxx',
     53              help='include libstdc++ in the list (inadvisable)')
     54 p.add_option('--libstdcxx-dso-path', metavar='PATH',
     55              help='path to libstdc++ DSO directory',
     56              default='/usr/lib/x86_64-linux-gnu')
     57 
     58 (options, args) = p.parse_args()
     59 
     60 libs = [os.path.join(options.libc_dso_path, name) for name in
     61         ['ld-linux-x86-64.so.2',
     62          'libanl.so.1',
     63          'libBrokenLocale.so.1',
     64          'libcidn.so.1',
     65          'libcrypt.so.1',
     66          'libc.so.6',
     67          'libdl.so.2',
     68          'libm.so.6',
     69          'libnsl.so.1',
     70          'libpthread.so.0',
     71          'libresolv.so.2',
     72          'librt.so.1',
     73          'libthread_db.so.1',
     74          'libutil.so.1']]
     75 libs += [os.path.join(options.libc_archive_path, name) for name in
     76          ['libc_nonshared.a',
     77           'libpthread_nonshared.a']]
     78 
     79 libs.append(os.path.join(options.libgcc_dso_path, 'libgcc_s.so.1'))
     80 libs.append(os.path.join(options.libgcc_archive_path, 'libgcc.a'))
     81 
     82 if options.with_libstdcxx:
     83   libs.append(os.path.join(options.libstdcxx_dso_path, 'libstdc++.so.6'))
     84 
     85 functions = []
     86 for l in libs:
     87   if os.path.exists(l):
     88     functions += defined_function_list(l)
     89   else:
     90     print >> sys.stderr, 'warning: library %s not found' % l
     91 
     92 functions = list(set(functions))
     93 functions.sort()
     94 
     95 for f in functions:
     96   print 'fun:%s=uninstrumented' % f
     97