| 1 |
BEGIN {
|
| 2 |
COUNT = split(ENVIRON["SYMBOLS"], SYMBOLS);
|
| 3 |
}
|
| 4 |
|
| 5 |
/^ OS\/ABI:/ {
|
| 6 |
ABI = $NF
|
| 7 |
}
|
| 8 |
|
| 9 |
{
|
| 10 |
# Unstripped libc's have '.symtab' section as well, and
|
| 11 |
# we should stop processing when we hit that
|
| 12 |
if ($0 ~ "^Symbol (.*)table '.symtab'")
|
| 13 |
nextfile;
|
| 14 |
|
| 15 |
for (x in SYMBOLS) {
|
| 16 |
sym_regex = "^" SYMBOLS[x] "(@|$)";
|
| 17 |
# On x86, x86_64 and others, $8 is the symbol name, but on
|
| 18 |
# alpha, its $10, so rather use $NF, as it should be the
|
| 19 |
# last field
|
| 20 |
if ($NF ~ sym_regex) {
|
| 21 |
split($NF, symbol_array, /@|@@/);
|
| 22 |
|
| 23 |
# Don't add local symbols of versioned libc's
|
| 24 |
if (VERSIONED_LIBC && !symbol_array[2])
|
| 25 |
continue;
|
| 26 |
|
| 27 |
# We have a versioned libc
|
| 28 |
if (symbol_array[2] && !VERSIONED_LIBC)
|
| 29 |
VERSIONED_LIBC = 1;
|
| 30 |
|
| 31 |
ADD = 1;
|
| 32 |
# Check that we do not add duplicates
|
| 33 |
for (y in PROCESSED_SYMBOLS) {
|
| 34 |
if (y == $NF) {
|
| 35 |
ADD = 0;
|
| 36 |
break;
|
| 37 |
}
|
| 38 |
}
|
| 39 |
|
| 40 |
if (ADD) {
|
| 41 |
SYMBOL_LIST[symbol_array[1]] = SYMBOL_LIST[symbol_array[1]] " " $NF;
|
| 42 |
PROCESSED_SYMBOLS[$NF] = $NF;
|
| 43 |
}
|
| 44 |
}
|
| 45 |
|
| 46 |
sym_regex = "^__" SYMBOLS[x] "(@@|$)";
|
| 47 |
if (($5 == "WEAK") && ($NF ~ sym_regex)) {
|
| 48 |
split($NF, symbol_array, /@@/);
|
| 49 |
|
| 50 |
# Don't add local symbols of versioned libc's
|
| 51 |
if (VERSIONED_LIBC && !symbol_array[2])
|
| 52 |
continue;
|
| 53 |
|
| 54 |
# Blacklist __getcwd on FreeBSD
|
| 55 |
# Unleashed - May 2006
|
| 56 |
if ((symbol_array[1] == "__getcwd") && (ABI == "FreeBSD"))
|
| 57 |
continue;
|
| 58 |
|
| 59 |
# We have a versioned libc
|
| 60 |
if (symbol_array[2] && !VERSIONED_LIBC)
|
| 61 |
VERSIONED_LIBC = 1;
|
| 62 |
|
| 63 |
ADD = 1;
|
| 64 |
# Check that we do not add duplicates
|
| 65 |
for (y in PROCESSED_SYMBOLS) {
|
| 66 |
if (y == $NF) {
|
| 67 |
ADD = 0;
|
| 68 |
break;
|
| 69 |
}
|
| 70 |
}
|
| 71 |
|
| 72 |
if (ADD) {
|
| 73 |
WEAK_SYMBOLS[SYMBOLS[x]] = WEAK_SYMBOLS[SYMBOLS[x]] " " $NF;
|
| 74 |
PROCESSED_SYMBOLS[$NF] = $NF;
|
| 75 |
}
|
| 76 |
}
|
| 77 |
}
|
| 78 |
}
|
| 79 |
|
| 80 |
END {
|
| 81 |
printf("#ifndef __symbols_h\n");
|
| 82 |
printf("#define __symbols_h\n\n");
|
| 83 |
|
| 84 |
# We use the order in SYMBOLS, as some wrappers depends on others ...
|
| 85 |
for (i = 1; i <= COUNT; i++) {
|
| 86 |
sym_index = SYMBOLS[i];
|
| 87 |
split(SYMBOL_LIST[sym_index], sym_full_names);
|
| 88 |
|
| 89 |
for (x in sym_full_names) {
|
| 90 |
split(sym_full_names[x], symbol_array, /@|@@/);
|
| 91 |
|
| 92 |
# Defualt symbol have '@@' and not '@', so name it by
|
| 93 |
# prepending '__' rather than the symbol version so
|
| 94 |
# that we know what the name is in libsandbox.c ...
|
| 95 |
# Also do this for non-versioned libc's ...
|
| 96 |
if (sym_full_names[x] ~ /@@/ || !symbol_array[2]) {
|
| 97 |
sym_real_name = sym_index "_DEFAULT";
|
| 98 |
} else {
|
| 99 |
sym_real_name = sym_full_names[x];
|
| 100 |
gsub(/@|\./, "_", sym_real_name);
|
| 101 |
}
|
| 102 |
|
| 103 |
printf("#define symname_%s \"%s\"\n", sym_real_name, sym_index);
|
| 104 |
|
| 105 |
# We handle non-versioned libc's by setting symver_*
|
| 106 |
# to NULL ...
|
| 107 |
if (!symbol_array[2])
|
| 108 |
printf("#define symver_%s NULL\n", sym_real_name);
|
| 109 |
else
|
| 110 |
printf("#define symver_%s \"%s\"\n", sym_real_name,
|
| 111 |
symbol_array[2]);
|
| 112 |
|
| 113 |
printf("#define EXTERN_NAME %s\n", sym_index);
|
| 114 |
printf("#define WRAPPER_NAME %s\n", sym_real_name);
|
| 115 |
printf("#define WRAPPER_TRUE_NAME true_%s\n", sym_real_name);
|
| 116 |
printf("#define WRAPPER_SYMNAME symname_%s\n", sym_real_name);
|
| 117 |
printf("#define WRAPPER_SYMVER symver_%s\n", sym_real_name);
|
| 118 |
printf("#include \"wrapper-funcs/%s.c\"\n", sym_index);
|
| 119 |
printf("#undef EXTERN_NAME\n");
|
| 120 |
printf("#undef WRAPPER_NAME\n");
|
| 121 |
printf("#undef WRAPPER_TRUE_NAME\n");
|
| 122 |
printf("#undef WRAPPER_SYMNAME\n");
|
| 123 |
printf("#undef WRAPPER_SYMVER\n");
|
| 124 |
|
| 125 |
if (symbol_array[2]) {
|
| 126 |
# Only add symbol versions for versioned libc's
|
| 127 |
if (sym_full_names[x] ~ /@@/)
|
| 128 |
printf("default_symbol_version(%s, %s, %s);\n",
|
| 129 |
sym_real_name, sym_index, symbol_array[2]);
|
| 130 |
else
|
| 131 |
printf("symbol_version(%s, %s, %s);\n",
|
| 132 |
sym_real_name, sym_index, symbol_array[2]);
|
| 133 |
} else {
|
| 134 |
# For non-versioned libc's we use strong aliases
|
| 135 |
printf("strong_alias(%s, %s);\n", sym_real_name,
|
| 136 |
sym_index);
|
| 137 |
}
|
| 138 |
|
| 139 |
if (WEAK_SYMBOLS[sym_index]) {
|
| 140 |
split(WEAK_SYMBOLS[sym_index], sym_weak_full);
|
| 141 |
|
| 142 |
for (y in sym_weak_full) {
|
| 143 |
split(sym_weak_full[y], sym_weak_array, /@@/);
|
| 144 |
|
| 145 |
# Add weak symbols for libc's like glibc that
|
| 146 |
# have them
|
| 147 |
if (sym_weak_array[1] == "__" sym_index)
|
| 148 |
printf("weak_alias(%s, %s);\n",
|
| 149 |
sym_real_name,
|
| 150 |
sym_weak_array[1]);
|
| 151 |
}
|
| 152 |
}
|
| 153 |
|
| 154 |
printf("\n");
|
| 155 |
}
|
| 156 |
}
|
| 157 |
|
| 158 |
printf("#endif /* __symbols_h */\n");
|
| 159 |
}
|