diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2015-03-09 13:22:01 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2015-03-11 09:40:28 -0700 |
commit | 688e958c81f230b5860b57590f45f1bc729ba2cf (patch) | |
tree | 889e0d4d54134c351c6c3510021c846dd0f497ae /scripts/check-localplt.awk | |
parent | a2d4cf72c0ab07d4e58b42c01ac3ed2b95ca8d9b (diff) | |
download | glibc-688e958c81f230b5860b57590f45f1bc729ba2cf.tar.gz glibc-688e958c81f230b5860b57590f45f1bc729ba2cf.tar.xz glibc-688e958c81f230b5860b57590f45f1bc729ba2cf.zip |
Extend local PLT reference check hjl/pr18078
On x86, linker in binutils 2.26 and newer consolidates R_*_JUMP_SLOT with R_*_GLOB_DAT relocation against the same symbol. This patch extends local PLT reference check to support alternate relocations. [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.
Diffstat (limited to 'scripts/check-localplt.awk')
-rw-r--r-- | scripts/check-localplt.awk | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/scripts/check-localplt.awk b/scripts/check-localplt.awk index bb1b912131..3965292888 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); } |