xref: /netbsd-src/external/bsd/compiler_rt/lib/clang/lib/netbsd/gen_dynamic_list.sh (revision 2d8e86c2f207da6fbbd50f11b6f33765ebdfa0e9)
1#!/bin/sh
2#===- lib/sanitizer_common/scripts/gen_dynamic_list.sh ---------------------===#
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.sh libclang_rt.*san*.a [ files ... ]
15#
16#===------------------------------------------------------------------------===#
17
18usage() {
19	echo "usage: gen_dynamic_list.py [-h] [--version-list] [--extra EXTRA]"
20	echo "                           libraries [libraries ...]"
21}
22
23get_global_functions() {
24	# On PowerPC, nm prints function descriptors from .data section.
25	$my_file $1 | grep -q "PowerPC"
26	if [ $? -eq 0 ]; then
27		export func_symbols="T|W|D"
28	else
29		export func_symbols="T|W"
30	fi
31
32	$my_nm $1 > $tmpfile1
33	if [ $? -ne 0 ]; then
34		printf 'Error calling: %s %s... bailing out\n' "$my_nm" "$1"
35		exit 1
36	fi
37
38	$my_awk '{if(NF == 3 && $2 ~ ENVIRON["func_symbols"]){print $3}}' \
39		$tmpfile1 >> $tmpfile2
40}
41
42version_list=
43extra=
44
45tmpfile1=`mktemp /tmp/${0##*/}.XXXXXX` || exit 1
46tmpfile2=`mktemp /tmp/${0##*/}.XXXXXX` || exit 1
47
48trap "rm -f $tmpfile1 $tmpfile2" EXIT
49
50my_nm=${NM:-nm}
51my_awk=${AWK:-awk}
52my_file=${FILE:-file}
53
54while :; do
55	case $1 in
56		-h|--help)
57			usage
58			exit
59			;;
60		--extra)
61			if [ "x$2" = "x" ]; then
62				usage
63				printf 'Error missing argument for the option\n'
64			else
65				extra=$2
66				shift
67			fi
68			;;
69		--extra=?*)
70			extra=${1#*=}
71			;;
72		--extra=)
73			usage
74			printf 'Error missing argument: %s\n' "$1"
75			;;
76		--version-list)
77			version_list=1
78			;;
79		--)
80			shift
81			break
82			;;
83		-?*)
84			usage
85			printf 'Error parsing argument: %s\n' "$1"
86			;;
87		*)
88			if [ "x$1" = "x" ]; then
89				break
90			else
91				get_global_functions "$1"
92			fi
93			;;
94	esac
95	shift
96done
97
98export version_list
99
100cat $tmpfile2 > /tmp/A
101
102$my_awk "
103BEGIN {
104	# operator new[](unsigned long)
105	new_delete[\"_Znam\"] = 1
106	new_delete[\"_ZnamRKSt9nothrow_t\"] = 1
107	# operator new(unsigned long)
108	new_delete[\"_Znwm\"] = 1
109	new_delete[\"_ZnwmRKSt9nothrow_t\"] = 1
110	# operator new[](unsigned int)
111	new_delete[\"_Znaj\"] = 1
112	new_delete[\"_ZnajRKSt9nothrow_t\"] = 1
113	# operator new(unsigned int)
114	new_delete[\"_Znwj\"] = 1
115	new_delete[\"_ZnwjRKSt9nothrow_t\"] = 1
116	# operator new(unsigned long, std::align_val_t)
117	new_delete[\"_ZnwmSt11align_val_t\"] = 1
118	new_delete[\"_ZnwmSt11align_val_tRKSt9nothrow_t\"] = 1
119	# operator new(unsigned int, std::align_val_t)
120	new_delete[\"_ZnwjSt11align_val_t\"] = 1
121	new_delete[\"_ZnwjSt11align_val_tRKSt9nothrow_t\"] = 1
122	# operator new[](unsigned long, std::align_val_t)
123	new_delete[\"_ZnamSt11align_val_t\"] = 1
124	new_delete[\"_ZnamSt11align_val_tRKSt9nothrow_t\"] = 1
125	# operator new[](unsigned int, std::align_val_t)
126	new_delete[\"_ZnajSt11align_val_t\"] = 1
127	new_delete[\"_ZnajSt11align_val_tRKSt9nothrow_t\"] = 1
128	# operator delete[](void *)
129	new_delete[\"_ZdaPv\"] = 1
130	new_delete[\"_ZdaPvRKSt9nothrow_t\"] = 1
131	# operator delete(void *)
132	new_delete[\"_ZdlPv\"] = 1
133	new_delete[\"_ZdlPvRKSt9nothrow_t\"] = 1
134	# operator delete[](void*, unsigned long)
135	new_delete[\"_ZdaPvm\"] = 1
136	# operator delete(void*, unsigned long)
137	new_delete[\"_ZdlPvm\"] = 1
138	# operator delete[](void*, unsigned int)
139	new_delete[\"_ZdaPvj\"] = 1
140	# operator delete(void*, unsigned int)
141	new_delete[\"_ZdlPvj\"] = 1
142	# operator delete(void*, std::align_val_t)
143	new_delete[\"_ZdlPvSt11align_val_t\"] = 1
144	new_delete[\"_ZdlPvSt11align_val_tRKSt9nothrow_t\"] = 1
145	# operator delete[](void*, std::align_val_t)
146	new_delete[\"_ZdaPvSt11align_val_t\"] = 1
147	new_delete[\"_ZdaPvSt11align_val_tRKSt9nothrow_t\"] = 1
148	# operator delete(void*, unsigned long,  std::align_val_t)
149	new_delete[\"_ZdlPvmSt11align_val_t\"] = 1
150	# operator delete[](void*, unsigned long, std::align_val_t)
151	new_delete[\"_ZdaPvmSt11align_val_t\"] = 1
152	# operator delete(void*, unsigned int,  std::align_val_t)
153	new_delete[\"_ZdlPvjSt11align_val_t\"] = 1
154	# operator delete[](void*, unsigned int, std::align_val_t)
155	new_delete[\"_ZdaPvjSt11align_val_t\"] = 1
156
157	versioned_functions[\"memcpy\"] = 1
158	versioned_functions[\"pthread_attr_getaffinity_np\"] = 1
159	versioned_functions[\"pthread_cond_broadcast\"] = 1
160	versioned_functions[\"pthread_cond_destroy\"] = 1
161	versioned_functions[\"pthread_cond_init\"] = 1
162	versioned_functions[\"pthread_cond_signal\"] = 1
163	versioned_functions[\"pthread_cond_timedwait\"] = 1
164	versioned_functions[\"pthread_cond_wait\"] = 1
165	versioned_functions[\"realpath\"] = 1
166	versioned_functions[\"sched_getaffinity\"] = 1
167
168	len = 0
169}
170NR==FNR {
171	function_set[\$0] = 1
172	next
173}
174{
175	if (\$0 in new_delete) {
176		result[len++] = \$0
177		next
178	}
179	if (substr(\$0, 1, 14) == \"__interceptor_\") {
180		result[len++] = \$0
181		# We have to avoid exporting the interceptors for versioned library
182		# functions due to gold internal error.
183		orig_name = substr(\$0, 15)
184		if ((orig_name in function_set) &&
185		    (ENVIRON["version_list"] == "1" ||
186		    !(orig_name in versioned_functions))) {
187			result[len++] = orig_name
188		}
189		next
190	}
191	if (substr(\$0, 1, 12) == \"__sanitizer_\") {
192		result[len++] = \$0
193		next
194	}
195}
196END {
197	for (i in result) {
198		print result[i]
199	}
200}
201" $tmpfile2 $tmpfile2 > $tmpfile1
202
203if [ "x$extra" != "x" ]; then
204	cat $extra >> $tmpfile1
205fi
206
207sort $tmpfile1 -o $tmpfile2
208
209echo "{"
210if [ "x$version_list" != "x" ]; then
211	echo "global:"
212fi
213$my_awk '{print "  " $0 ";"}' $tmpfile2
214if [ "x$version_list" != "x" ]; then
215	echo "local:"
216	echo "  *;"
217fi
218echo "};"
219