17841, 17912, 17916, 17930, 17932, 17944, 17949, 17964, 17965, 17967,
17969, 17977, 17978, 17987, 17991, 17996, 17998, 17999, 18007, 18019,
18020, 18029, 18030, 18032, 18034, 18036, 18038, 18039, 18042, 18043,
- 18046, 18047, 18049, 18068, 18080, 18093, 18100, 18104, 18110, 18111,
- 18116, 18125, 18128, 18134, 18138, 18185, 18196, 18197, 18206, 18210,
- 18211, 18217, 18219, 18220, 18221, 18234, 18244, 18245, 18247, 18287,
- 18319, 18324, 18333, 18346, 18371, 18383, 18397, 18400, 18409, 18410,
- 18412, 18418, 18422, 18434, 18444, 18457, 18468, 18469, 18470, 18479,
- 18483, 18495, 18496, 18497, 18498, 18502, 18507, 18508, 18512, 18513,
- 18519, 18520, 18522, 18527, 18528, 18529, 18530, 18532, 18533, 18534,
- 18536, 18539, 18540, 18542, 18544, 18545, 18546, 18547, 18549, 18553,
- 18557, 18558, 18569, 18583, 18585, 18586, 18592, 18593, 18594, 18602,
- 18612, 18613, 18619, 18633, 18641, 18643, 18648, 18657, 18676, 18694,
- 18696.
+ 18046, 18047, 18049, 18068, 18078, 18080, 18093, 18100, 18104, 18110,
+ 18111, 18116, 18125, 18128, 18134, 18138, 18185, 18196, 18197, 18206,
+ 18210, 18211, 18217, 18219, 18220, 18221, 18234, 18244, 18245, 18247,
+ 18287, 18319, 18324, 18333, 18346, 18371, 18383, 18397, 18400, 18409,
+ 18410, 18412, 18418, 18422, 18434, 18444, 18457, 18468, 18469, 18470,
+ 18479, 18483, 18495, 18496, 18497, 18498, 18502, 18507, 18508, 18512,
+ 18513, 18519, 18520, 18522, 18527, 18528, 18529, 18530, 18532, 18533,
+ 18534, 18536, 18539, 18540, 18542, 18544, 18545, 18546, 18547, 18549,
+ 18553, 18557, 18558, 18569, 18583, 18585, 18586, 18592, 18593, 18594,
+ 18602, 18612, 18613, 18619, 18633, 18641, 18643, 18648, 18657, 18676,
+ 18694, 18696.
* Cache information can be queried via sysconf() function on s390 e.g. with
_SC_LEVEL1_ICACHE_SIZE as argument.
# Each line is either a comment starting with # or it looks like:
# libfoo.so: function
# or
+# libfoo.so: function + {RELA|REL} RELOC
+# or
# libfoo.so: function ?
-# The latter means that a PLT entry for function is optional in libfoo.so.
-# The former means one is required.
+# The first entry means that one is required.
+# The second entry means that one is required and relocation may also be
+# {RELA|REL} RELOC.
+# The third entry means that a PLT entry for function is optional in
+# libfoo.so.
# The second file argument is - and this (stdin) receives the output
# of the check-localplt program.
FILENAME != "-" && /^#/ { next }
FILENAME != "-" {
- if (NF != 2 && !(NF == 3 && $3 == "?")) {
+ if (NF == 5 && $3 == "+" && ($4 == "RELA" || $4 == "REL")) {
+ accept_type[$1 " " $2] = $4;
+ accept_reloc[$1 " " $2] = $5;
+ } else if (NF != 2 && !(NF == 3 && $3 == "?")) {
printf "%s:%d: bad data line: %s\n", FILENAME, FNR, $0 > "/dev/stderr";
result = 2;
} else {
next;
}
-NF != 2 {
+NF != 2 && !(NF == 4 && ($3 == "RELA" || $3 == "REL")) {
print "Unexpected output from check-localplt:", $0 > "/dev/stderr";
result = 2;
next
{
key = $1 " " $2
- if (key in accept) {
+ if ($3 == "RELA" || $3 == "REL") {
+ # Entries like:
+ # libc.so: free + RELA R_X86_64_GLOB_DAT
+ # may be ignored.
+ if (key in accept_type && accept_type[key] == $3 && accept_reloc[key] == $4) {
+ # Match
+ # libc.so: free + RELA R_X86_64_GLOB_DAT
+ delete accept_type[key]
+ }
+ } else if (NF == 2 && key in accept_reloc) {
+ # Match
+ # libc.so: free
+ # against
+ # libc.so: free + RELA R_X86_64_GLOB_DAT
+ if (key in accept_type)
+ delete accept_type[key]
+ } else if (key in accept) {
delete accept[key]
} else {
print "Extra PLT reference:", $0;
}
}
+ for (key in accept_type) {
+ # It's mandatory.
+ print "Missing required PLT or " accept_reloc[key] " reference:", key;
+ result = 1;
+ }
+
exit(result);
}
}
lastfile = FILENAME;
jmprel_offset = 0;
+ rela_offset = 0;
+ rel_offset = 0;
delete section_offset_by_address;
}
}
}
+in_relocs && relocs_offset == rela_offset && NF >= 5 {
+ # Relocations against GNU_IFUNC symbols are not shown as an hexadecimal
+ # value, but rather as the resolver symbol followed by ().
+ if ($4 ~ /\(\)/) {
+ print whatfile, gensub(/@.*/, "", "g", $5), "RELA", $3
+ } else {
+ symval = strtonum("0x" $4);
+ if (symval != 0)
+ print whatfile, gensub(/@.*/, "", "g", $5), "RELA", $3
+ }
+}
+
+in_relocs && relocs_offset == rel_offset && NF >= 5 {
+ # Relocations against GNU_IFUNC symbols are not shown as an hexadecimal
+ # value, but rather as the resolver symbol followed by ().
+ if ($4 ~ /\(\)/) {
+ print whatfile, gensub(/@.*/, "", "g", $5), "REL", $3
+ } else {
+ symval = strtonum("0x" $4);
+ if (symval != 0)
+ print whatfile, gensub(/@.*/, "", "g", $5), "REL", $3
+ }
+}
+
in_relocs { next }
$1 == "Relocation" && $2 == "section" && $5 == "offset" {
next
}
+$2 == "(RELA)" {
+ rela_addr = strtonum($3);
+ if (rela_addr in section_offset_by_address) {
+ rela_offset = section_offset_by_address[rela_addr];
+ } else {
+ print FILENAME ": *** DT_RELA does not match any section's address";
+ result = 2;
+ }
+ next
+}
+
+$2 == "(REL)" {
+ rel_addr = strtonum($3);
+ if (rel_addr in section_offset_by_address) {
+ rel_offset = section_offset_by_address[rel_addr];
+ } else {
+ print FILENAME ": *** DT_REL does not match any section's address";
+ result = 2;
+ }
+ next
+}
END { exit(result) }