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