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