Merge glibc-ports into ports/ directory.
[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   if (version == "GLIBC_PRIVATE") next;
52
53   desc = "";
54   if (type == "D" && $4 == ".tbss") {
55     type = "T";
56   }
57   else if (type == "D" && $4 == ".opd") {
58     type = "F";
59     size = "";
60     if (seen_opd < 0)
61       type = "O";
62     seen_opd = 1;
63   }
64   else if (type == "D" && NF == 8 && $7 == "0x80") {
65     # Alpha functions avoiding plt entry in users
66     type = "F";
67     size = "";
68     seen_opd = -1;
69   }
70   else if ($4 == "*ABS*") {
71     type = "A";
72     size = "";
73   }
74   else if (type == "DO") {
75     type = "D";
76   }
77   else if (type == "DF") {
78     if (symbol ~ /^\./ && seen_opd >= 0)
79       next;
80     seen_opd = -1;
81     type = "F";
82     size = "";
83   }
84   else if (type == "iD" && $4 == ".text") {
85     # Indirect functions.
86     type = "F";
87     size = "";
88   }
89   else {
90     desc = symbol " " version " " weak " ? " type " " $4 " " $5;
91   }
92   if (size == " 0x") {
93     desc = symbol " " version " " weak " ? " type " " $4 " " $5;
94   }
95
96   # Disabled -- weakness should not matter to shared library ABIs any more.
97   #if (weak == "w") type = tolower(type);
98   if (desc == "")
99     desc = " " symbol " " type size;
100
101   if (combine)
102     version = soname " " version (combine_fullname ? " " sofullname : "");
103
104   if (version in versions) {
105     versions[version] = versions[version] "\n" desc;
106   }
107   else {
108     versions[version] = desc;
109   }
110   next;
111 }
112
113 # Header crapola.
114 NF == 0 || /DYNAMIC SYMBOL TABLE/ || /file format/ { next }
115
116 {
117   print "Don't grok this line:", $0
118 }
119
120 function emit(end) {
121   if (!end && (combine || ! parse_names || soname == ""))
122     return;
123   tofile = parse_names && !combine;
124
125   nverslist = 0;
126   for (version in versions) {
127     if (nverslist == 0) {
128       verslist = version;
129       nverslist = 1;
130       continue;
131     }
132     split(verslist, s, "\n");
133     if (version < s[1]) {
134       verslist = version;
135       for (i = 1; i <= nverslist; ++i) {
136         verslist = verslist "\n" s[i];
137       }
138     }
139     else {
140       verslist = s[1];
141       for (i = 2; i <= nverslist; ++i) {
142         if (version < s[i]) break;
143         verslist = verslist "\n" s[i];
144       }
145       verslist = verslist "\n" version;
146       for (; i <= nverslist; ++i) {
147         verslist = verslist "\n" s[i];
148       }
149     }
150     ++nverslist;
151   }
152
153   if (tofile) {
154     out = prefix soname ".symlist";
155     if (soname in outfiles)
156       out = out "." ++outfiles[soname];
157     else
158       outfiles[soname] = 1;
159     printf "" > out;
160   }
161
162   split(verslist, order, "\n");
163   for (i = 1; i <= nverslist; ++i) {
164     version = order[i];
165
166     if (tofile) {
167       print version >> out;
168       close(out);
169       outpipe = "sort >> " out;
170     }
171     else {
172       if (combine)
173         print "";
174       print prefix version;
175       outpipe = "sort";
176     }
177     print versions[version] | outpipe;
178     close(outpipe);
179
180     delete versions[version];
181   }
182   for (version in versions)
183     delete versions[version];
184
185   if (tofile)
186     print "wrote", out, "for", sofullname;
187 }
188
189 END {
190   emit(1);
191 }