diff --git a/ChangeLog b/ChangeLog index 80b0a757a3..4ac339664a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2013-12-04 Alan Modra + + * elf/elf.h (R_PPC64_TLSGD, R_PPC64_TLSLD, R_PPC64_TOCSAVE): Define. + (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA): Likewise. + (R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA): Likewise. + (R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): Likewise. + + * sysdeps/powerpc/powerpc64/dl-machine.h (elf_machine_rela): Add + overflow checking for R_PPC64_ADDR16_HI, R_PPC64_ADDR16_HA, + R_PPC64_TPREL16_HI, and R_PPC64_TPREL16_HA. + Support new R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA, + R_PPC64_TPREL16_HIGH, and R_PPC64_TPREL16_HIGHA relocations. + Fix overflow checking for R_PPC64_ADDR30 and R_PPC64_ADDR32. + 2013-12-04 Ulrich Weigand * sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S diff --git a/elf/elf.h b/elf/elf.h index a05ea3b640..6e2552e35d 100644 --- a/elf/elf.h +++ b/elf/elf.h @@ -2252,6 +2252,17 @@ typedef Elf32_Addr Elf32_Conflict; #define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ #define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ #define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ +#define R_PPC64_TLSGD 107 /* none (sym+add)@tlsgd */ +#define R_PPC64_TLSLD 108 /* none (sym+add)@tlsld */ +#define R_PPC64_TOCSAVE 109 /* none */ + +/* Added when HA and HI relocs were changed to report overflows. */ +#define R_PPC64_ADDR16_HIGH 110 +#define R_PPC64_ADDR16_HIGHA 111 +#define R_PPC64_TPREL16_HIGH 112 +#define R_PPC64_TPREL16_HIGHA 113 +#define R_PPC64_DTPREL16_HIGH 114 +#define R_PPC64_DTPREL16_HIGHA 115 /* GNU extension to support local ifunc. */ #define R_PPC64_JMP_IREL 247 diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h index 18cf15738a..19fa4fab4b 100644 --- a/sysdeps/powerpc/powerpc64/dl-machine.h +++ b/sysdeps/powerpc/powerpc64/dl-machine.h @@ -668,11 +668,25 @@ elf_machine_rela (struct link_map *map, break; case R_PPC64_TPREL16_HI: + value = elf_machine_tprel (map, sym_map, sym, reloc); + if (dont_expect (value + 0x80000000 >= 0x100000000LL)) + _dl_reloc_overflow (map, "R_PPC64_TPREL16_HI", reloc_addr, refsym); + *(Elf64_Half *) reloc_addr = PPC_HI (value); + break; + + case R_PPC64_TPREL16_HIGH: value = elf_machine_tprel (map, sym_map, sym, reloc); *(Elf64_Half *) reloc_addr = PPC_HI (value); break; case R_PPC64_TPREL16_HA: + value = elf_machine_tprel (map, sym_map, sym, reloc); + if (dont_expect (value + 0x80008000 >= 0x100000000LL)) + _dl_reloc_overflow (map, "R_PPC64_TPREL16_HA", reloc_addr, refsym); + *(Elf64_Half *) reloc_addr = PPC_HA (value); + break; + + case R_PPC64_TPREL16_HIGHA: value = elf_machine_tprel (map, sym_map, sym, reloc); *(Elf64_Half *) reloc_addr = PPC_HA (value); break; @@ -709,17 +723,23 @@ elf_machine_rela (struct link_map *map, break; case R_PPC64_ADDR16_HI: + if (dont_expect (value + 0x80000000 >= 0x100000000LL)) + _dl_reloc_overflow (map, "R_PPC64_ADDR16_HI", reloc_addr, refsym); + case R_PPC64_ADDR16_HIGH: *(Elf64_Half *) reloc_addr = PPC_HI (value); break; case R_PPC64_ADDR16_HA: + if (dont_expect (value + 0x80008000 >= 0x100000000LL)) + _dl_reloc_overflow (map, "R_PPC64_ADDR16_HA", reloc_addr, refsym); + case R_PPC64_ADDR16_HIGHA: *(Elf64_Half *) reloc_addr = PPC_HA (value); break; case R_PPC64_ADDR30: { Elf64_Addr delta = value - (Elf64_Xword) reloc_addr; - if (dont_expect ((delta + 0x80000000) >= 0x10000000 + if (dont_expect ((delta + 0x80000000) >= 0x100000000LL || (delta & 3) != 0)) _dl_reloc_overflow (map, "R_PPC64_ADDR30", reloc_addr, refsym); BIT_INSERT (*(Elf64_Word *) reloc_addr, delta, 0xfffffffc); @@ -755,7 +775,7 @@ elf_machine_rela (struct link_map *map, return; case R_PPC64_ADDR32: - if (dont_expect ((value + 0x80000000) >= 0x10000000)) + if (dont_expect ((value + 0x80000000) >= 0x100000000LL)) _dl_reloc_overflow (map, "R_PPC64_ADDR32", reloc_addr, refsym); *(Elf64_Word *) reloc_addr = value; return;