1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
BEGIN {
split(" " SYMBOLS_LIST, SYMBOLS);
}
/^ OS\/ABI:/ {
ABI = $NF
}
{
# Unstripped libc's have '.symtab' section as well, and
# we should stop processing when we hit that
if ($0 ~ "^Symbol (.*)table '.symtab'")
nextfile;
for (x in SYMBOLS) {
sym_regex = "^" SYMBOLS[x] "(@|$)";
# On x86, x86_64 and others, $8 is the symbol name, but on
# alpha, its $10, so rather use $NF, as it should be the
# last field
if ($NF ~ sym_regex) {
split($NF, symbol_array, /@|@@/);
# Don't add local symbols of versioned libc's
if (VERSIONED_LIBC && !symbol_array[2])
continue;
# Handle non-versioned libc's like uClibc ...
if (!symbol_array[2])
symbol_array[2] = "";
# We have a versioned libc
if (symbol_array[2] && !VERSIONED_LIBC)
VERSIONED_LIBC = 1;
ADD = 1;
# Check that we do not add duplicates
for (y in PROCESSED_SYMBOLS) {
if (y == $NF) {
ADD = 0;
break;
}
}
if (ADD) {
SYMBOL_LIST[symbol_array[2]] = SYMBOL_LIST[symbol_array[2]] " " symbol_array[1];
PROCESSED_SYMBOLS[$NF] = $NF;
}
}
sym_regex = "^__" SYMBOLS[x] "(@@|$)";
if (($5 == "WEAK") && ($NF ~ sym_regex)) {
split($NF, symbol_array, /@@/);
# Don't add local symbols of versioned libc's
if (VERSIONED_LIBC && !symbol_array[2])
continue;
# Blacklist __getcwd on FreeBSD
# Unleashed - May 2006
if ((symbol_array[1] == "__getcwd") && (ABI == "FreeBSD"))
continue;
# Handle non-versioned libc's like uClibc ...
if (!symbol_array[2])
symbol_array[2] = "";
# We have a versioned libc
if (symbol_array[2] && !VERSIONED_LIBC)
VERSIONED_LIBC = 1;
ADD = 1;
# Check that we do not add duplicates
for (y in PROCESSED_SYMBOLS) {
if (y == $NF) {
ADD = 0;
break;
}
}
if (ADD) {
SYMBOL_LIST[symbol_array[2]] = SYMBOL_LIST[symbol_array[2]] " " symbol_array[1];
PROCESSED_SYMBOLS[$NF] = $NF;
}
}
}
}
END {
COUNT = 0;
delete VERSION_LIST
for (sym_version in SYMBOL_LIST)
if (sym_version)
VERSION_LIST[COUNT++] = sym_version;
# We need the symbol versions sorted alphabetically ...
if (COUNT)
asort(VERSION_LIST);
else
# Handle non-versioned libc's like uClibc ...
COUNT = 1;
for (i = 1; i <= COUNT; ++i) {
if (VERSION_LIST[i]) {
sym_version = VERSION_LIST[i];
printf("%s {\n", sym_version);
} else {
# Handle non-versioned libc's like uClibc ...
sym_version = "";
printf("{\n");
}
printf(" global:\n");
split(SYMBOL_LIST[sym_version], sym_names);
for (x in sym_names) {
printf(" %s;\n", sym_names[x]);
}
if (!old_sym_version) {
printf(" local:\n");
printf(" *;\n");
printf("};\n");
} else {
printf("} %s;\n", old_sym_version);
}
old_sym_version = sym_version;
}
}
|