NPTL is no longer an add-on!
[platform/upstream/glibc.git] / scripts / abilist.awk
1 # This awk script processes the output of objdump --dynamic-syms
2 # into a simple format that should not change when the ABI is not changing.
3
4 BEGIN {
5   if (combine_fullname)
6     combine = 1;
7   if (combine)
8     parse_names = 1;
9 }
10
11 # Per-file header.
12 /[^ :]+\.so\.[0-9.]+:[  ]+.file format .*$/ {
13   emit(0);
14
15   seen_opd = 0;
16
17   sofullname = $1;
18   sub(/:$/, "", sofullname);
19   soname = sofullname;
20   sub(/^.*\//, "", soname);
21   sub(/\.so\.[0-9.]+$/, "", soname);
22
23   suppress = ((filename_regexp != "" && sofullname !~ filename_regexp) \
24               || (libname_regexp != "" && soname !~ libname_regexp));
25
26   next
27 }
28
29 suppress { next }
30
31 # Normalize columns.
32 /^[0-9a-fA-F]+      / { sub(/      /, "  -   ") }
33
34 # Skip undefineds.
35 $4 == "*UND*" { next }
36
37 # Skip locals.
38 $2 == "l" { next }
39
40 # If the target uses ST_OTHER, it will be output before the symbol name.
41 $2 == "g" || $2 == "w" && (NF == 7 || NF == 8) {
42   weak = $2;
43   type = $3;
44   size = $5;
45   sub(/^0*/, "", size);
46   size = " 0x" size;
47   version = $6;
48   symbol = $NF;
49   gsub(/[()]/, "", version);
50
51   # binutils versions up through at least 2.23 have some bugs that
52   # caused STV_HIDDEN symbols to appear in .dynsym, though that is useless.
53   if (NF > 7 && $7 == ".hidden") next;
54
55   if (version == "GLIBC_PRIVATE") next;
56
57   desc = "";
58   if (type == "D" && $4 == ".tbss") {
59     type = "T";
60   }
61   else if (type == "D" && $4 == ".opd") {
62     type = "F";
63     size = "";
64     if (seen_opd < 0)
65       type = "O";
66     seen_opd = 1;
67   }
68   else if (type == "D" && NF == 8 && $7 == "0x80") {
69     # Alpha functions avoiding plt entry in users
70     type = "F";
71     size = "";
72     seen_opd = -1;
73   }
74   else if ($4 == "*ABS*") {
75     type = "A";
76     size = "";
77   }
78   else if (type == "DO") {
79     type = "D";
80   }
81   else if (type == "DF") {
82     if (symbol ~ /^\./ && seen_opd >= 0)
83       next;
84     seen_opd = -1;
85     type = "F";
86     size = "";
87   }
88   else if (type == "iD" && ($4 == ".text" || $4 == ".opd")) {
89     # Indirect functions.
90     type = "F";
91     size = "";
92   }
93   else {
94     desc = symbol " " version " " weak " ? " type " " $4 " " $5;
95   }
96   if (size == " 0x") {
97     desc = symbol " " version " " weak " ? " type " " $4 " " $5;
98   }
99
100   # Disabled -- weakness should not matter to shared library ABIs any more.
101   #if (weak == "w") type = tolower(type);
102   if (desc == "")
103     desc = " " symbol " " type size;
104
105   if (combine)
106     version = soname " " version (combine_fullname ? " " sofullname : "");
107
108   if (version in versions) {
109     versions[version] = versions[version] "\n" desc;
110   }
111   else {
112     versions[version] = desc;
113   }
114   next;
115 }
116
117 # Header crapola.
118 NF == 0 || /DYNAMIC SYMBOL TABLE/ || /file format/ { next }
119
120 {
121   print "Don't grok this line:", $0
122 }
123
124 function emit(end) {
125   if (!end && (combine || ! parse_names || soname == ""))
126     return;
127   tofile = parse_names && !combine;
128
129   nverslist = 0;
130   for (version in versions) {
131     if (nverslist == 0) {
132       verslist = version;
133       nverslist = 1;
134       continue;
135     }
136     split(verslist, s, "\n");
137     if (version < s[1]) {
138       verslist = version;
139       for (i = 1; i <= nverslist; ++i) {
140         verslist = verslist "\n" s[i];
141       }
142     }
143     else {
144       verslist = s[1];
145       for (i = 2; i <= nverslist; ++i) {
146         if (version < s[i]) break;
147         verslist = verslist "\n" s[i];
148       }
149       verslist = verslist "\n" version;
150       for (; i <= nverslist; ++i) {
151         verslist = verslist "\n" s[i];
152       }
153     }
154     ++nverslist;
155   }
156
157   if (tofile) {
158     out = prefix soname ".symlist";
159     if (soname in outfiles)
160       out = out "." ++outfiles[soname];
161     else
162       outfiles[soname] = 1;
163     printf "" > out;
164   }
165
166   split(verslist, order, "\n");
167   for (i = 1; i <= nverslist; ++i) {
168     version = order[i];
169
170     if (tofile) {
171       print version >> out;
172       close(out);
173       outpipe = "sort >> " out;
174     }
175     else {
176       if (combine)
177         print "";
178       print prefix version;
179       outpipe = "sort";
180     }
181     print versions[version] | outpipe;
182     close(outpipe);
183
184     delete versions[version];
185   }
186   for (version in versions)
187     delete versions[version];
188
189   if (tofile)
190     print "wrote", out, "for", sofullname;
191 }
192
193 END {
194   emit(1);
195 }