]> git.ipfire.org Git - thirdparty/glibc.git/blame - scripts/abilist.awk
* scripts/abilist.awk: If variable `parse_names' is set, grok the file
[thirdparty/glibc.git] / scripts / abilist.awk
CommitLineData
6e3d59bc
RM
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
15a686af
RM
4BEGIN {
5 if (parse_names)
6 out = "/dev/stderr";
7 else
8 out = "/dev/stdout";
9}
10
11# Per-file header.
12/[^ :]+\.so\.[0-9]+:[ ]+.file format .*$/ {
13 if (parse_names && soname != "")
14 emit(1);
15
16 sofullname = $1;
17 sub(/:$/, "", sofullname);
18 soname = sofullname;
19 sub(/^.*\//, "", soname);
20 sub(/\.so\.[0-9]+$/, "", soname);
21
22 next
23}
24
6e3d59bc
RM
25# Normalize columns.
26/^[0-9a-fA-F]+ / { sub(/ /, " - ") }
27
28# Skip undefineds.
29$4 == "*UND*" { next }
30
31# Skip locals.
32$2 == "l" { next }
33
34$2 == "g" || $2 == "w" && NF == 7 {
c823a4d2 35 weak = $2;
6e3d59bc 36 type = $3;
56c71d45
RM
37 size = $5;
38 sub(/^0*/, "", size);
c823a4d2 39 size = " 0x" size;
6e3d59bc
RM
40 version = $6;
41 symbol = $7;
42 gsub(/[()]/, "", version);
43
44 if (version == "GLIBC_PRIVATE") next;
45
46 if (type == "D" && $4 == ".tbss") {
c823a4d2 47 type = "T";
6e3d59bc 48 }
5d0bbaaf 49 else if (type == "D" && $4 == ".opd") {
c823a4d2
RM
50 type = "O";
51 size = "";
5d0bbaaf 52 }
6e3d59bc 53 else if (type == "DO" && $4 == "*ABS*") {
c823a4d2
RM
54 type = "A";
55 size = "";
6e3d59bc
RM
56 }
57 else if (type == "DO") {
c823a4d2 58 type = "D";
6e3d59bc
RM
59 }
60 else if (type == "DF") {
c823a4d2
RM
61 type = "F";
62 size = "";
6e3d59bc
RM
63 }
64 else {
15a686af 65 print symbol, version, weak, "?", type, $4, $5 >> out;
c823a4d2 66 next;
6e3d59bc 67 }
620656a3 68 if (size == " 0x") {
15a686af 69 print symbol, version, weak, "?", type, $4, $5 >> out;
620656a3
RM
70 next;
71 }
6e3d59bc 72
44aeb486
RM
73 # Disabled -- weakness should not matter to shared library ABIs any more.
74 #if (weak == "w") type = tolower(type);
75 desc = " " symbol " " type size;
c823a4d2
RM
76
77 if (version in versions) {
78 versions[version] = versions[version] "\n" desc;
79 }
80 else {
81 versions[version] = desc;
82 }
6e3d59bc
RM
83 next;
84}
85
86# Header crapola.
87NF == 0 || /DYNAMIC SYMBOL TABLE/ || /file format/ { next }
88
89{
15a686af 90 print "Don't grok this line:", $0 >> out
6e3d59bc 91}
c823a4d2 92
15a686af
RM
93function emit(tofile) {
94 if (tofile) {
95 out = prefix soname ".symlist";
96 if (soname in outfiles)
97 out = out "." ++outfiles[soname];
98 else
99 outfiles[soname] = 1;
100 }
101 else
102 out = "/dev/stdout";
103
c823a4d2
RM
104 nverlist = 0;
105 for (version in versions) {
106 if (nverslist == 0) {
107 verslist = version;
108 nverslist = 1;
109 continue;
110 }
111 split(verslist, s, "\n");
112 if (version < s[1]) {
113 verslist = version;
114 for (i = 1; i <= nverslist; ++i) {
115 verslist = verslist "\n" s[i];
116 }
117 }
118 else {
119 verslist = s[1];
120 for (i = 2; i <= nverslist; ++i) {
121 if (version < s[i]) break;
122 verslist = verslist "\n" s[i];
123 }
124 verslist = verslist "\n" version;
125 for (; i <= nverslist; ++i) {
126 verslist = verslist "\n" s[i];
127 }
128 }
129 ++nverslist;
130 }
131
132 split(verslist, order, "\n");
133 for (i = 1; i <= nverslist; ++i) {
134 version = order[i];
135
15a686af
RM
136 print version >> out;
137 outpipe = "sort >> " out;
c823a4d2
RM
138 print versions[version] | outpipe;
139 close(outpipe);
15a686af
RM
140
141 delete versions[version];
142 }
143
144 if (tofile)
145 print "wrote", out, "for", sofullname;
146}
147
148END {
149 if (! parse_names)
150 emit(0);
151 else if (soname != "") {
152 emit(1);
c823a4d2
RM
153 }
154}