]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
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 \ | |
92a42be0 | 29 | line[39:44] != 'LOCAL' and \ |
1a4d82fc JJ |
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 |