Alexey Samsonov | e5fa243 | 2013-08-27 15:08:02 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | #===- lib/sanitizer_common/scripts/gen_dynamic_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 | # |
| 11 | # Generates the list of functions that should be exported from sanitizer |
| 12 | # runtimes. The output format is recognized by --dynamic-list linker option. |
| 13 | # Usage: |
| 14 | # gen_dynamic_list.py libclang_rt.*san*.a [ files ... ] |
| 15 | # |
| 16 | #===------------------------------------------------------------------------===# |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 17 | import argparse |
Alexey Samsonov | e5fa243 | 2013-08-27 15:08:02 +0000 | [diff] [blame] | 18 | import os |
Alexey Samsonov | fb23e2f | 2013-08-29 15:45:41 +0000 | [diff] [blame] | 19 | import re |
Alexey Samsonov | e5fa243 | 2013-08-27 15:08:02 +0000 | [diff] [blame] | 20 | import subprocess |
| 21 | import sys |
| 22 | |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 23 | new_delete = set([ |
| 24 | '_Znam', '_ZnamRKSt9nothrow_t', # operator new[](unsigned long) |
| 25 | '_Znwm', '_ZnwmRKSt9nothrow_t', # operator new(unsigned long) |
| 26 | '_Znaj', '_ZnajRKSt9nothrow_t', # operator new[](unsigned int) |
| 27 | '_Znwj', '_ZnwjRKSt9nothrow_t', # operator new(unsigned int) |
| 28 | '_ZdaPv', '_ZdaPvRKSt9nothrow_t', # operator delete[](void *) |
| 29 | '_ZdlPv', '_ZdlPvRKSt9nothrow_t', # operator delete(void *) |
| 30 | '_ZdaPvm', # operator delete[](void*, unsigned long) |
| 31 | '_ZdlPvm', # operator delete(void*, unsigned long) |
| 32 | '_ZdaPvj', # operator delete[](void*, unsigned int) |
| 33 | '_ZdlPvj', # operator delete(void*, unsigned int) |
| 34 | ]) |
Alexey Samsonov | fb23e2f | 2013-08-29 15:45:41 +0000 | [diff] [blame] | 35 | |
Alexey Samsonov | 4207870 | 2013-10-26 12:54:03 +0000 | [diff] [blame] | 36 | versioned_functions = set(['memcpy', 'pthread_attr_getaffinity_np', |
| 37 | 'pthread_cond_broadcast', |
Alexey Samsonov | 8e05fda | 2013-09-20 08:37:57 +0000 | [diff] [blame] | 38 | 'pthread_cond_destroy', 'pthread_cond_init', |
| 39 | 'pthread_cond_signal', 'pthread_cond_timedwait', |
| 40 | 'pthread_cond_wait', 'realpath', |
| 41 | 'sched_getaffinity']) |
Alexey Samsonov | fb23e2f | 2013-08-29 15:45:41 +0000 | [diff] [blame] | 42 | |
Alexey Samsonov | e5fa243 | 2013-08-27 15:08:02 +0000 | [diff] [blame] | 43 | def get_global_functions(library): |
| 44 | functions = [] |
Alexey Samsonov | fb23e2f | 2013-08-29 15:45:41 +0000 | [diff] [blame] | 45 | nm_proc = subprocess.Popen(['nm', library], stdout=subprocess.PIPE, |
| 46 | stderr=subprocess.PIPE) |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 47 | nm_out = nm_proc.communicate()[0].decode().split('\n') |
Alexey Samsonov | e5fa243 | 2013-08-27 15:08:02 +0000 | [diff] [blame] | 48 | if nm_proc.returncode != 0: |
| 49 | raise subprocess.CalledProcessError(nm_proc.returncode, 'nm') |
Stephen Hines | 6d18623 | 2014-11-26 17:56:19 -0800 | [diff] [blame] | 50 | func_symbols = ['T', 'W'] |
| 51 | # On PowerPC, nm prints function descriptors from .data section. |
| 52 | if os.uname()[4] in ["powerpc", "ppc64"]: |
| 53 | func_symbols += ['D'] |
Alexey Samsonov | e5fa243 | 2013-08-27 15:08:02 +0000 | [diff] [blame] | 54 | for line in nm_out: |
| 55 | cols = line.split(' ') |
Stephen Hines | 6d18623 | 2014-11-26 17:56:19 -0800 | [diff] [blame] | 56 | if len(cols) == 3 and cols[1] in func_symbols : |
Alexey Samsonov | e5fa243 | 2013-08-27 15:08:02 +0000 | [diff] [blame] | 57 | functions.append(cols[2]) |
| 58 | return functions |
| 59 | |
Alexey Samsonov | fb23e2f | 2013-08-29 15:45:41 +0000 | [diff] [blame] | 60 | def main(argv): |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 61 | parser = argparse.ArgumentParser() |
| 62 | parser.add_argument('--version-list', action='store_true') |
| 63 | parser.add_argument('--extra', default=[], action='append') |
| 64 | parser.add_argument('libraries', default=[], nargs='+') |
| 65 | args = parser.parse_args() |
| 66 | |
Alexey Samsonov | fb23e2f | 2013-08-29 15:45:41 +0000 | [diff] [blame] | 67 | result = [] |
Alexey Samsonov | e5fa243 | 2013-08-27 15:08:02 +0000 | [diff] [blame] | 68 | |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 69 | all_functions = [] |
| 70 | for library in args.libraries: |
| 71 | all_functions.extend(get_global_functions(library)) |
Alexey Samsonov | fb23e2f | 2013-08-29 15:45:41 +0000 | [diff] [blame] | 72 | function_set = set(all_functions) |
| 73 | for func in all_functions: |
| 74 | # Export new/delete operators. |
| 75 | if func in new_delete: |
| 76 | result.append(func) |
| 77 | continue |
| 78 | # Export interceptors. |
| 79 | match = re.match('__interceptor_(.*)', func) |
| 80 | if match: |
| 81 | result.append(func) |
| 82 | # We have to avoid exporting the interceptors for versioned library |
| 83 | # functions due to gold internal error. |
| 84 | orig_name = match.group(1) |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 85 | if orig_name in function_set and (args.version_list or orig_name not in versioned_functions): |
Alexey Samsonov | fb23e2f | 2013-08-29 15:45:41 +0000 | [diff] [blame] | 86 | result.append(orig_name) |
| 87 | continue |
| 88 | # Export sanitizer interface functions. |
| 89 | if re.match('__sanitizer_(.*)', func): |
| 90 | result.append(func) |
Alexey Samsonov | e5fa243 | 2013-08-27 15:08:02 +0000 | [diff] [blame] | 91 | |
Alexey Samsonov | fb23e2f | 2013-08-29 15:45:41 +0000 | [diff] [blame] | 92 | # Additional exported functions from files. |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 93 | for fname in args.extra: |
Alexey Samsonov | fb23e2f | 2013-08-29 15:45:41 +0000 | [diff] [blame] | 94 | f = open(fname, 'r') |
| 95 | for line in f: |
| 96 | result.append(line.rstrip()) |
| 97 | # Print the resulting list in the format recognized by ld. |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 98 | print('{') |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 99 | if args.version_list: |
| 100 | print('global:') |
Alexey Samsonov | fb23e2f | 2013-08-29 15:45:41 +0000 | [diff] [blame] | 101 | result.sort() |
| 102 | for f in result: |
Pirama Arumuga Nainar | 799172d | 2016-03-03 15:50:30 -0800 | [diff] [blame^] | 103 | print(u' %s;' % f) |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 104 | if args.version_list: |
| 105 | print('local:') |
| 106 | print(' *;') |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 107 | print('};') |
Alexey Samsonov | e5fa243 | 2013-08-27 15:08:02 +0000 | [diff] [blame] | 108 | |
Alexey Samsonov | fb23e2f | 2013-08-29 15:45:41 +0000 | [diff] [blame] | 109 | if __name__ == '__main__': |
| 110 | main(sys.argv) |