1 # Combine version map fragments into version scripts for our shared objects.
2 # Copyright (C) 1998-2021 Free Software Foundation, Inc.
3 # Written by Ulrich Drepper <drepper@cygnus.com>, 1998.
5 # This script expects the following variables to be defined:
6 # defsfile name of Versions.def file
7 # buildroot name of build directory with trailing slash
8 # move_if_change move-if-change command
10 # Read definitions for the versions.
15 while (getline < defsfile
) {
16 if (/^
[a
-zA
-Z0
-9_.
]+ \
{/) {
19 while (getline < defsfile
&& !
/^
}/) {
21 renamed
[curlib
"::" $
1] = $
3;
24 versions
[curlib
"::" $
1] =
1;
30 tmpfile = buildroot
"Versions.tmp";
32 sort =
"sort -t. -k 1,1 -k 2n,2n -k 3 > " tmpfile
;
35 # GNU awk does not implement the ord and chr functions.
36 # <https://www.gnu.org/software/gawk/manual/html_node/Ordinal-Functions.html>
37 # says that they are "written very nicely", using code similar to what
40 return sprintf("%c", c
)
44 for (c =
1; c
< 127; c
++) {
45 ord_table
[chr
(c
)] = c
;
53 printf("Invalid character reference: '%c'\n", c
) > "/dev/stderr";
58 # Remove comment lines.
63 # This matches the beginning of the version information for a new library.
67 printf("no versions defined for %s\n", $
1) > "/dev/stderr";
73 # This matches the beginning of a new version for the current library.
75 if (renamed
[actlib
"::" $
1])
76 actver = renamed
[actlib
"::" $
1];
77 else if (!versions
[actlib
"::" $
1] && $
1 != "GLIBC_PRIVATE") {
78 printf("version %s not defined for %s\n", $
1, actlib
) > "/dev/stderr";
86 # This matches lines with names to be added to the current version in the
87 # current library. This is the only place where we print something to
88 # the intermediate file.
91 # Ensure GLIBC_ versions come always first
92 sub(/^GLIBC_
/," GLIBC_",sortver
)
93 printf("%s %s %s\n", actlib
, sortver
, $
0) | sort
;
96 # Some targets do not set the ABI baseline for libdl. As a result,
97 # symbols originally in libdl need to be moved under historic symbol
98 # versions, without altering the baseline version for libc itself.
99 /^
*!libc_pre_versions
/ {
100 libc_pre_versions_active =
1;
103 function libc_pre_versions
() {
104 # No local: * here, so that we do not have to update this script
105 # if symbols are moved into libc. The abilist files and the other
106 # targets (with a real GLIBC_2.0 baseline) provide testing
117 function closeversion
(name
, oldname
) {
118 printf(" local:\n *;\n") > outfile
;
119 # This version inherits from the last one only if they
120 # have the same nonnumeric prefix, i.e. GLIBC_x.y and GLIBC_x.z
121 # or FOO_x and FOO_y but not GLIBC_x and FOO_y.
123 sub(/[0-9.
]+/,".+",pfx
);
124 if (oldname ==
"" || name !~ pfx
) print "};" > outfile
;
125 else printf("} %s;\n", oldname
) > outfile
;
128 function close_and_move
(name
, real_name
) {
130 system(move_if_change
" " name
" " real_name
" >&2");
133 # ELF hash, for use with symbol versions.
134 function elf_hash
(s
, i
, acc
) {
136 for (i =
1; i
<=
length(s
); ++i
) {
137 acc = and
(lshift
(acc
, 4) + ord
(substr(s
, i
, 1)), 0xffffffff);
138 top = and
(acc
, 0xf0000000);
139 acc = and
(xor
(acc
, rshift
(top
, 24)), compl
(top
));
144 # Now print the accumulated information.
149 system("rm -f " tmpfile
);
155 real_first_ver_header = buildroot
"first-versions.h"
156 first_ver_header = real_first_ver_header
"T"
157 printf("#ifndef _FIRST_VERSIONS_H\n") > first_ver_header
;
158 printf("#define _FIRST_VERSIONS_H\n") > first_ver_header
;
159 real_ldbl_compat_header = buildroot
"ldbl-compat-choose.h"
160 ldbl_compat_header = real_ldbl_compat_header
"T"
161 printf("#ifndef _LDBL_COMPAT_CHOOSE_H\n") > ldbl_compat_header
;
162 printf("#define _LDBL_COMPAT_CHOOSE_H\n") > ldbl_compat_header
;
163 printf("#ifndef LONG_DOUBLE_COMPAT\n") > ldbl_compat_header
;
164 printf("# error LONG_DOUBLE_COMPAT not defined\n") > ldbl_compat_header
;
165 printf("#endif\n") > ldbl_compat_header
;
166 printf("version-maps =");
167 while (getline < tmpfile
) {
170 closeversion
(oldver
, veryoldver
);
172 close_and_move
(outfile
, real_outfile
);
175 real_outfile = buildroot oldlib
".map";
176 outfile = real_outfile
"T";
177 if ($
1 ==
"libc" && libc_pre_versions_active
) {
178 veryoldver = libc_pre_versions
();
182 printf(" %s.map", oldlib
);
186 closeversion
(oldver
, veryoldver
);
189 printf("%s {\n global:\n", $
2) > outfile
;
192 printf(" ") > outfile
;
193 for (n =
3; n
<=
NF; ++n
) {
194 printf(" %s", $n
) > outfile
;
197 first_ver_macro =
"FIRST_VERSION_" oldlib
"_" sym
;
198 if (!
(first_ver_macro in first_ver_seen
) \
199 && oldver ~
"^GLIBC_[0-9]" \
200 && sym ~
"^[A-Za-z0-9_]*$") {
202 printf("#define %s_STRING \"%s\"\n", first_ver_macro
, ver_val
) > first_ver_header
;
203 printf("#define %s_HASH 0x%x\n", first_ver_macro
, elf_hash
(ver_val
)) > first_ver_header
;
204 gsub("\\.", "_", ver_val
);
205 printf("#define %s %s\n", first_ver_macro
, ver_val
) > first_ver_header
;
206 first_ver_seen
[first_ver_macro
] =
1;
207 if (oldlib ==
"libc" || oldlib ==
"libm") {
208 printf("#if LONG_DOUBLE_COMPAT (%s, %s)\n",
209 oldlib
, ver_val
) > ldbl_compat_header
;
210 printf("# define LONG_DOUBLE_COMPAT_CHOOSE_%s_%s(a, b) a\n",
211 oldlib
, sym
) > ldbl_compat_header
;
212 printf("#else\n") > ldbl_compat_header
;
213 printf("# define LONG_DOUBLE_COMPAT_CHOOSE_%s_%s(a, b) b\n",
214 oldlib
, sym
) > ldbl_compat_header
;
215 printf("#endif\n") > ldbl_compat_header
;
219 printf("\n") > outfile
;
222 printf("#endif /* first-versions.h */\n") > first_ver_header
;
223 printf("#endif /* ldbl-compat-choose.h */\n") > ldbl_compat_header
;
224 closeversion
(oldver
, veryoldver
);
225 close_and_move
(outfile
, real_outfile
);
226 close_and_move
(first_ver_header
, real_first_ver_header
);
227 close_and_move
(ldbl_compat_header
, real_ldbl_compat_header
);
228 #system("rm -f " tmpfile);