blob: b8b79b5994b7b67ebb2a574db7f62ec8f9f293ec [file] [log] [blame]
Alexey Samsonove5fa2432013-08-27 15:08:02 +00001#!/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 Nainarcdce50b2015-07-01 12:26:56 -070017import argparse
Alexey Samsonove5fa2432013-08-27 15:08:02 +000018import os
Alexey Samsonovfb23e2f2013-08-29 15:45:41 +000019import re
Alexey Samsonove5fa2432013-08-27 15:08:02 +000020import subprocess
21import sys
22
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070023new_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 Samsonovfb23e2f2013-08-29 15:45:41 +000035
Alexey Samsonov42078702013-10-26 12:54:03 +000036versioned_functions = set(['memcpy', 'pthread_attr_getaffinity_np',
37 'pthread_cond_broadcast',
Alexey Samsonov8e05fda2013-09-20 08:37:57 +000038 'pthread_cond_destroy', 'pthread_cond_init',
39 'pthread_cond_signal', 'pthread_cond_timedwait',
40 'pthread_cond_wait', 'realpath',
41 'sched_getaffinity'])
Alexey Samsonovfb23e2f2013-08-29 15:45:41 +000042
Alexey Samsonove5fa2432013-08-27 15:08:02 +000043def get_global_functions(library):
44 functions = []
Alexey Samsonovfb23e2f2013-08-29 15:45:41 +000045 nm_proc = subprocess.Popen(['nm', library], stdout=subprocess.PIPE,
46 stderr=subprocess.PIPE)
Stephen Hines2d1fdb22014-05-28 23:58:16 -070047 nm_out = nm_proc.communicate()[0].decode().split('\n')
Alexey Samsonove5fa2432013-08-27 15:08:02 +000048 if nm_proc.returncode != 0:
49 raise subprocess.CalledProcessError(nm_proc.returncode, 'nm')
Stephen Hines6d186232014-11-26 17:56:19 -080050 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 Samsonove5fa2432013-08-27 15:08:02 +000054 for line in nm_out:
55 cols = line.split(' ')
Stephen Hines6d186232014-11-26 17:56:19 -080056 if len(cols) == 3 and cols[1] in func_symbols :
Alexey Samsonove5fa2432013-08-27 15:08:02 +000057 functions.append(cols[2])
58 return functions
59
Alexey Samsonovfb23e2f2013-08-29 15:45:41 +000060def main(argv):
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070061 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 Samsonovfb23e2f2013-08-29 15:45:41 +000067 result = []
Alexey Samsonove5fa2432013-08-27 15:08:02 +000068
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070069 all_functions = []
70 for library in args.libraries:
71 all_functions.extend(get_global_functions(library))
Alexey Samsonovfb23e2f2013-08-29 15:45:41 +000072 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 Nainarcdce50b2015-07-01 12:26:56 -070085 if orig_name in function_set and (args.version_list or orig_name not in versioned_functions):
Alexey Samsonovfb23e2f2013-08-29 15:45:41 +000086 result.append(orig_name)
87 continue
88 # Export sanitizer interface functions.
89 if re.match('__sanitizer_(.*)', func):
90 result.append(func)
Alexey Samsonove5fa2432013-08-27 15:08:02 +000091
Alexey Samsonovfb23e2f2013-08-29 15:45:41 +000092 # Additional exported functions from files.
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070093 for fname in args.extra:
Alexey Samsonovfb23e2f2013-08-29 15:45:41 +000094 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 Hines2d1fdb22014-05-28 23:58:16 -070098 print('{')
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070099 if args.version_list:
100 print('global:')
Alexey Samsonovfb23e2f2013-08-29 15:45:41 +0000101 result.sort()
102 for f in result:
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800103 print(u' %s;' % f)
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -0700104 if args.version_list:
105 print('local:')
106 print(' *;')
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700107 print('};')
Alexey Samsonove5fa2432013-08-27 15:08:02 +0000108
Alexey Samsonovfb23e2f2013-08-29 15:45:41 +0000109if __name__ == '__main__':
110 main(sys.argv)