aboutsummaryrefslogtreecommitdiff
blob: c236d67a8c92bd6ef24f5906378793dd5d025b12 (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
123
124
125
126
127
128
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] "(@|$)";
		if ($8 ~ sym_regex) {
			split($8, 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 == $8) {
					ADD = 0;
					break;
				}
			}
			
			if (ADD) {
				SYMBOL_LIST[symbol_array[2]] = SYMBOL_LIST[symbol_array[2]] " " symbol_array[1];
				PROCESSED_SYMBOLS[$8] = $8;
			}
		}

		sym_regex = "^__" SYMBOLS[x] "(@|$)";
		if (($5 == "WEAK") && ($8 ~ sym_regex)) {
			split($8, 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 == $8) {
					ADD = 0;
					break;
				}
			}
			
			if (ADD) {
				WEAK_SYMBOLS[symbol_array[2]] = WEAK_SYMBOLS[symbol_array[2]] " " symbol_array[1];
				PROCESSED_SYMBOLS[$8] = $8;
			}
		}
	}
}

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]);

			split(WEAK_SYMBOLS[sym_version], sym_weak_names);

			for (y in sym_weak_names) {
				# Add weak symbols for libc's like glibc that
				# have them
				if (sym_weak_names[y] == "__" sym_names[x])
					printf("    %s;\n", sym_weak_names[y]);
			}
		}
		
		if (!old_sym_version) {
			printf("  local:\n");
			printf("    *;\n");
			printf("};\n");
		} else {
			printf("} %s;\n", old_sym_version);
		}
		
		old_sym_version = sym_version;
	}
}