2 # ===- lib/sanitizer_common/scripts/gen_dynamic_list.py ---------------------===#
4 # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 # See https://llvm.org/LICENSE.txt for license information.
6 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 # ===------------------------------------------------------------------------===#
10 # Generates the list of functions that should be exported from sanitizer
11 # runtimes. The output format is recognized by --dynamic-list linker option.
13 # gen_dynamic_list.py libclang_rt.*san*.a [ files ... ]
15 # ===------------------------------------------------------------------------===#
16 from __future__
import print_function
27 "_ZnamRKSt9nothrow_t", # operator new[](unsigned long)
29 "_ZnwmRKSt9nothrow_t", # operator new(unsigned long)
31 "_ZnajRKSt9nothrow_t", # operator new[](unsigned int)
33 "_ZnwjRKSt9nothrow_t", # operator new(unsigned int)
34 # operator new(unsigned long, std::align_val_t)
35 "_ZnwmSt11align_val_t",
36 "_ZnwmSt11align_val_tRKSt9nothrow_t",
37 # operator new(unsigned int, std::align_val_t)
38 "_ZnwjSt11align_val_t",
39 "_ZnwjSt11align_val_tRKSt9nothrow_t",
40 # operator new[](unsigned long, std::align_val_t)
41 "_ZnamSt11align_val_t",
42 "_ZnamSt11align_val_tRKSt9nothrow_t",
43 # operator new[](unsigned int, std::align_val_t)
44 "_ZnajSt11align_val_t",
45 "_ZnajSt11align_val_tRKSt9nothrow_t",
47 "_ZdaPvRKSt9nothrow_t", # operator delete[](void *)
49 "_ZdlPvRKSt9nothrow_t", # operator delete(void *)
50 "_ZdaPvm", # operator delete[](void*, unsigned long)
51 "_ZdlPvm", # operator delete(void*, unsigned long)
52 "_ZdaPvj", # operator delete[](void*, unsigned int)
53 "_ZdlPvj", # operator delete(void*, unsigned int)
54 # operator delete(void*, std::align_val_t)
55 "_ZdlPvSt11align_val_t",
56 "_ZdlPvSt11align_val_tRKSt9nothrow_t",
57 # operator delete[](void*, std::align_val_t)
58 "_ZdaPvSt11align_val_t",
59 "_ZdaPvSt11align_val_tRKSt9nothrow_t",
60 # operator delete(void*, unsigned long, std::align_val_t)
61 "_ZdlPvmSt11align_val_t",
62 # operator delete[](void*, unsigned long, std::align_val_t)
63 "_ZdaPvmSt11align_val_t",
64 # operator delete(void*, unsigned int, std::align_val_t)
65 "_ZdlPvjSt11align_val_t",
66 # operator delete[](void*, unsigned int, std::align_val_t)
67 "_ZdaPvjSt11align_val_t",
71 versioned_functions
= set(
74 "pthread_attr_getaffinity_np",
75 "pthread_cond_broadcast",
76 "pthread_cond_destroy",
78 "pthread_cond_signal",
79 "pthread_cond_timedwait",
87 def get_global_functions(nm_executable
, library
):
89 nm
= os
.environ
.get("NM", nm_executable
)
90 nm_proc
= subprocess
.Popen(
91 [nm
, library
], stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
93 nm_out
= nm_proc
.communicate()[0].decode().split("\n")
94 if nm_proc
.returncode
!= 0:
95 raise subprocess
.CalledProcessError(nm_proc
.returncode
, nm
)
96 func_symbols
= ["T", "W"]
97 # On PowerPC, nm prints function descriptors from .data section.
98 if platform
.uname()[4] in ["powerpc", "ppc64"]:
101 cols
= line
.split(" ")
102 if len(cols
) == 3 and cols
[1] in func_symbols
:
103 functions
.append(cols
[2])
108 parser
= argparse
.ArgumentParser()
109 parser
.add_argument("--version-list", action
="store_true")
110 parser
.add_argument("--extra", default
=[], action
="append")
111 parser
.add_argument("libraries", default
=[], nargs
="+")
112 parser
.add_argument("--nm-executable", required
=True)
113 parser
.add_argument("-o", "--output", required
=True)
114 args
= parser
.parse_args()
119 for library
in args
.libraries
:
120 all_functions
.extend(get_global_functions(args
.nm_executable
, library
))
121 function_set
= set(all_functions
)
122 for func
in all_functions
:
123 # Export new/delete operators.
124 if func
in new_delete
:
127 # Export interceptors.
128 match
= re
.match("_?__interceptor_(.*)", func
)
131 # We have to avoid exporting the interceptors for versioned library
132 # functions due to gold internal error.
133 orig_name
= match
.group(1)
134 if orig_name
in function_set
and (
135 args
.version_list
or orig_name
not in versioned_functions
137 result
.add(orig_name
)
139 # Export sanitizer interface functions.
140 if re
.match("__sanitizer_(.*)", func
):
143 # Additional exported functions from files.
144 for fname
in args
.extra
:
147 result
.add(line
.rstrip())
148 # Print the resulting list in the format recognized by ld.
149 with
open(args
.output
, "w") as f
:
151 if args
.version_list
:
152 print("global:", file=f
)
153 for sym
in sorted(result
):
154 print(" %s;" % sym
, file=f
)
155 if args
.version_list
:
156 print("local:", file=f
)
161 if __name__
== "__main__":