gen_dynamic_list.py revision 8e05fda2a6b24a0aa293239ebc1c121d18b5a07f
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#===------------------------------------------------------------------------===# 17import os 18import re 19import subprocess 20import sys 21 22new_delete = set(['_ZdaPv', '_ZdaPvRKSt9nothrow_t', 23 '_ZdlPv', '_ZdlPvRKSt9nothrow_t', 24 '_Znam', '_ZnamRKSt9nothrow_t', 25 '_Znwm', '_ZnwmRKSt9nothrow_t']) 26 27versioned_functions = set(['memcpy', 'pthread_cond_broadcast', 28 'pthread_cond_destroy', 'pthread_cond_init', 29 'pthread_cond_signal', 'pthread_cond_timedwait', 30 'pthread_cond_wait', 'realpath', 31 'sched_getaffinity']) 32 33def get_global_functions(library): 34 functions = [] 35 nm_proc = subprocess.Popen(['nm', library], stdout=subprocess.PIPE, 36 stderr=subprocess.PIPE) 37 nm_out = nm_proc.communicate()[0].split('\n') 38 if nm_proc.returncode != 0: 39 raise subprocess.CalledProcessError(nm_proc.returncode, 'nm') 40 for line in nm_out: 41 cols = line.split(' ') 42 if (len(cols) == 3 and cols[1] in ('T', 'W')) : 43 functions.append(cols[2]) 44 return functions 45 46def main(argv): 47 result = [] 48 49 library = argv[1] 50 all_functions = get_global_functions(library) 51 function_set = set(all_functions) 52 for func in all_functions: 53 # Export new/delete operators. 54 if func in new_delete: 55 result.append(func) 56 continue 57 # Export interceptors. 58 match = re.match('__interceptor_(.*)', func) 59 if match: 60 result.append(func) 61 # We have to avoid exporting the interceptors for versioned library 62 # functions due to gold internal error. 63 orig_name = match.group(1) 64 if orig_name in function_set and orig_name not in versioned_functions: 65 result.append(orig_name) 66 continue 67 # Export sanitizer interface functions. 68 if re.match('__sanitizer_(.*)', func): 69 result.append(func) 70 71 # Additional exported functions from files. 72 for fname in argv[2:]: 73 f = open(fname, 'r') 74 for line in f: 75 result.append(line.rstrip()) 76 # Print the resulting list in the format recognized by ld. 77 print '{' 78 result.sort() 79 for f in result: 80 print ' ' + f + ';' 81 print '};' 82 83if __name__ == '__main__': 84 main(sys.argv) 85