aboutsummaryrefslogtreecommitdiff
blob: 260933faee0a9e9b1b0187f73746f49d5bdd2fcb (plain)
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
BEGIN {
	split(ENVIRON["SYMBOLS"], SYMBOLS);
}

{
	# 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;

			# 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 {
	for (sym_version in SYMBOL_LIST) {
		if (sym_version)
			VERSIONS = VERSIONS " " sym_version;
	}

	# We need the symbol versions sorted alphabetically ...
	if (VERSIONS) {
		split(VERSIONS, VERSION_LIST);
		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;
	}
}