build-libc-list.py revision 6e4c46dc162803cc99c2a5e068fc28adb873a431
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
15import os
16import subprocess
17import sys
18from optparse import OptionParser
19
20def 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[55:58] != 'UND':
30      function_name = line[59:].split('@')[0]
31      functions.append(function_name)
32  return functions
33
34p = OptionParser()
35p.add_option('--lib', metavar='PATH',
36             help='path to lib directory to use',
37             default='/lib/x86_64-linux-gnu')
38p.add_option('--usrlib', metavar='PATH',
39             help='path to usr/lib directory to use',
40             default='/usr/lib/x86_64-linux-gnu')
41p.add_option('--gcclib', metavar='PATH',
42             help='path to gcc lib directory to use',
43             default='/usr/lib/gcc/x86_64-linux-gnu/4.6')
44p.add_option('--with-libstdcxx', action='store_true',
45             dest='with_libstdcxx',
46             help='include libstdc++ in the list (inadvisable)')
47(options, args) = p.parse_args()
48
49libs = [os.path.join(options.lib, name) for name in
50        ['ld-linux-x86-64.so.2',
51         'libanl.so.1',
52         'libBrokenLocale.so.1',
53         'libcidn.so.1',
54         'libcrypt.so.1',
55         'libc.so.6',
56         'libdl.so.2',
57         'libm.so.6',
58         'libnsl.so.1',
59         'libpthread.so.0',
60         'libresolv.so.2',
61         'librt.so.1',
62         'libthread_db.so.1',
63         'libutil.so.1']]
64libs += [os.path.join(options.usrlib, name) for name in
65         ['libc_nonshared.a',
66          'libpthread_nonshared.a']]
67gcclibs = ['libgcc.a',
68           'libgcc_s.so']
69if options.with_libstdcxx:
70  gcclibs += ['libstdc++.so']
71libs += [os.path.join(options.gcclib, name) for name in gcclibs]
72
73functions = []
74for l in libs:
75  if os.path.exists(l):
76    functions += defined_function_list(l)
77  else:
78    print >> sys.stderr, 'warning: library %s not found' % l
79
80functions = list(set(functions))
81functions.sort()
82
83for f in functions:
84  print 'fun:%s=uninstrumented' % f
85