Check branch displacement overflow in x86-64 PLT entry
authorH.J. Lu <hjl.tools@gmail.com>
Sat, 22 Nov 2014 16:58:07 +0000 (08:58 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Sat, 22 Nov 2014 16:58:07 +0000 (08:58 -0800)
Displacement of branch to PLT0 in x86-64 PLT entry is signed 32-bit.
This patch adds a sanity check.  We will only see the failure when PLT
size is > 2GB.

* elf64-x86-64.c (elf_x86_64_finish_dynamic_symbol): Check
branch displacement overflow in PLT entry.

bfd/ChangeLog
bfd/elf64-x86-64.c

index 5700c51..040576a 100644 (file)
@@ -1,3 +1,8 @@
+2014-11-22  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elf64-x86-64.c (elf_x86_64_finish_dynamic_symbol): Check
+       branch displacement overflow in PLT entry.
+
 2014-11-21  Nick Clifton  <nickc@redhat.com>
 
        PR binutils/17512
index c64ff4f..8859429 100644 (file)
@@ -4906,11 +4906,19 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
       /* Don't fill PLT entry for static executables.  */
       if (plt == htab->elf.splt)
        {
+         bfd_vma plt0_offset = h->plt.offset + plt_plt_insn_end;
+
          /* Put relocation index.  */
          bfd_put_32 (output_bfd, plt_index,
                      plt->contents + h->plt.offset + abed->plt_reloc_offset);
-         /* Put offset for jmp .PLT0.  */
-         bfd_put_32 (output_bfd, - (h->plt.offset + plt_plt_insn_end),
+
+         /* Put offset for jmp .PLT0 and check for overflow.  We don't
+            check relocation index for overflow since branch displacement
+            will overflow first.  */
+         if (plt0_offset > 0x80000000)
+           info->callbacks->einfo (_("%F%B: branch displacement overflow in PLT entry for `%s'\n"),
+                                   output_bfd, h->root.root.string);
+         bfd_put_32 (output_bfd, - plt0_offset,
                      plt->contents + h->plt.offset + plt_plt_offset);
        }