aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--NEWS22
-rw-r--r--scripts/check-localplt.awk40
-rw-r--r--scripts/localplt.awk47
-rw-r--r--sysdeps/unix/sysv/linux/i386/localplt.data8
-rw-r--r--sysdeps/x86_64/localplt.data19
6 files changed, 127 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 9a5e489..6f393fd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2015-07-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #18078]
+ * scripts/check-localplt.awk: Support alternate relocations.
+ * scripts/localplt.awk: Also check relocations in DT_RELA/DT_REL
+ sections.
+ * sysdeps/unix/sysv/linux/i386/localplt.data: Mark free and
+ malloc entries with + REL R_386_GLOB_DAT.
+ * sysdeps/x86_64/localplt.data: New file.
+
2015-07-29 Andrew Senkevich <andrew.senkevich@intel.com>
[BZ #18731]
diff --git a/NEWS b/NEWS
index 5698310..5be4917 100644
--- a/NEWS
+++ b/NEWS
@@ -18,17 +18,17 @@ Version 2.22
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.
diff --git a/scripts/check-localplt.awk b/scripts/check-localplt.awk
index bb1b912..3965292 100644
--- a/scripts/check-localplt.awk
+++ b/scripts/check-localplt.awk
@@ -3,9 +3,14 @@
# 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.
@@ -14,7 +19,10 @@ BEGIN { result = 0 }
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 {
@@ -23,7 +31,7 @@ FILENAME != "-" {
next;
}
-NF != 2 {
+NF != 2 && !(NF == 4 && ($3 == "RELA" || $3 == "REL")) {
print "Unexpected output from check-localplt:", $0 > "/dev/stderr";
result = 2;
next
@@ -31,7 +39,23 @@ NF != 2 {
{
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;
@@ -49,5 +73,11 @@ END {
}
}
+ for (key in accept_type) {
+ # It's mandatory.
+ print "Missing required PLT or " accept_reloc[key] " reference:", key;
+ result = 1;
+ }
+
exit(result);
}
diff --git a/scripts/localplt.awk b/scripts/localplt.awk
index 84c94d1..f75b3b4 100644
--- a/scripts/localplt.awk
+++ b/scripts/localplt.awk
@@ -13,6 +13,8 @@ FILENAME != lastfile {
}
lastfile = FILENAME;
jmprel_offset = 0;
+ rela_offset = 0;
+ rel_offset = 0;
delete section_offset_by_address;
}
@@ -43,6 +45,30 @@ in_relocs && relocs_offset == jmprel_offset && NF >= 5 {
}
}
+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" {
@@ -62,4 +88,25 @@ $2 == "(JMPREL)" {
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) }
diff --git a/sysdeps/unix/sysv/linux/i386/localplt.data b/sysdeps/unix/sysv/linux/i386/localplt.data
index b25abf8..2e03821 100644
--- a/sysdeps/unix/sysv/linux/i386/localplt.data
+++ b/sysdeps/unix/sysv/linux/i386/localplt.data
@@ -1,7 +1,9 @@
+# Linker in binutils 2.26 and newer consolidates R_X86_64_JUMP_SLOT
+# relocation with R_386_GLOB_DAT relocation against the same symbol.
libc.so: _Unwind_Find_FDE
libc.so: calloc
-libc.so: free
-libc.so: malloc
+libc.so: free + REL R_386_GLOB_DAT
+libc.so: malloc + REL R_386_GLOB_DAT
libc.so: memalign
libc.so: realloc
libm.so: matherr
@@ -12,4 +14,4 @@ ld.so: __libc_memalign
ld.so: malloc
ld.so: calloc
ld.so: realloc
-ld.so: free
+ld.so: free + REL R_386_GLOB_DAT
diff --git a/sysdeps/x86_64/localplt.data b/sysdeps/x86_64/localplt.data
new file mode 100644
index 0000000..d140476
--- /dev/null
+++ b/sysdeps/x86_64/localplt.data
@@ -0,0 +1,19 @@
+# See scripts/check-localplt.awk for how this file is processed.
+# PLT use is required for the malloc family and for matherr because
+# users can define their own functions and have library internals call them.
+# Linker in binutils 2.26 and newer consolidates R_X86_64_JUMP_SLOT
+# relocation with R_X86_64_GLOB_DAT relocation against the same symbol.
+libc.so: calloc
+libc.so: free + RELA R_X86_64_GLOB_DAT
+libc.so: malloc + RELA R_X86_64_GLOB_DAT
+libc.so: memalign
+libc.so: realloc
+libm.so: matherr
+# The dynamic loader uses __libc_memalign internally to allocate aligned
+# TLS storage. The other malloc family of functions are expected to allow
+# user symbol interposition.
+ld.so: __libc_memalign
+ld.so: malloc
+ld.so: calloc
+ld.so: realloc
+ld.so: free + RELA R_X86_64_GLOB_DAT