mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-25 14:30:06 +00:00
PowerPC64: Report overflow on @h and @ha relocations
This patch updates glibc in accordance with the binutils patch checked in here: https://sourceware.org/ml/binutils/2013-10/msg00372.html This changes the various R_PPC64_..._HI and _HA relocations to report 32-bit overflows. The motivation is that existing uses of @h / @ha are to build up 32-bit offsets (for the "medium model" TOC access that GCC now defaults to), and we'd really like to see failures at link / load time rather than silent truncations. For those rare cases where a modifier is needed to build up a 64-bit constant, new relocations _HIGH / _HIGHA are supported. The patch also fixes a bug in overflow checking for the R_PPC64_ADDR30 and R_PPC64_ADDR32 relocations.
This commit is contained in:
parent
5162e7dd96
commit
7ec07d9a7b
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
|||||||
|
2013-12-04 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* 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 <Ulrich.Weigand@de.ibm.com>
|
2013-12-04 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
|
* sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
|
||||||
|
11
elf/elf.h
11
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_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */
|
||||||
#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */
|
#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_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. */
|
/* GNU extension to support local ifunc. */
|
||||||
#define R_PPC64_JMP_IREL 247
|
#define R_PPC64_JMP_IREL 247
|
||||||
|
@ -668,11 +668,25 @@ elf_machine_rela (struct link_map *map,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case R_PPC64_TPREL16_HI:
|
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);
|
value = elf_machine_tprel (map, sym_map, sym, reloc);
|
||||||
*(Elf64_Half *) reloc_addr = PPC_HI (value);
|
*(Elf64_Half *) reloc_addr = PPC_HI (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_PPC64_TPREL16_HA:
|
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);
|
value = elf_machine_tprel (map, sym_map, sym, reloc);
|
||||||
*(Elf64_Half *) reloc_addr = PPC_HA (value);
|
*(Elf64_Half *) reloc_addr = PPC_HA (value);
|
||||||
break;
|
break;
|
||||||
@ -709,17 +723,23 @@ elf_machine_rela (struct link_map *map,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case R_PPC64_ADDR16_HI:
|
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);
|
*(Elf64_Half *) reloc_addr = PPC_HI (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_PPC64_ADDR16_HA:
|
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);
|
*(Elf64_Half *) reloc_addr = PPC_HA (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_PPC64_ADDR30:
|
case R_PPC64_ADDR30:
|
||||||
{
|
{
|
||||||
Elf64_Addr delta = value - (Elf64_Xword) reloc_addr;
|
Elf64_Addr delta = value - (Elf64_Xword) reloc_addr;
|
||||||
if (dont_expect ((delta + 0x80000000) >= 0x10000000
|
if (dont_expect ((delta + 0x80000000) >= 0x100000000LL
|
||||||
|| (delta & 3) != 0))
|
|| (delta & 3) != 0))
|
||||||
_dl_reloc_overflow (map, "R_PPC64_ADDR30", reloc_addr, refsym);
|
_dl_reloc_overflow (map, "R_PPC64_ADDR30", reloc_addr, refsym);
|
||||||
BIT_INSERT (*(Elf64_Word *) reloc_addr, delta, 0xfffffffc);
|
BIT_INSERT (*(Elf64_Word *) reloc_addr, delta, 0xfffffffc);
|
||||||
@ -755,7 +775,7 @@ elf_machine_rela (struct link_map *map,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case R_PPC64_ADDR32:
|
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);
|
_dl_reloc_overflow (map, "R_PPC64_ADDR32", reloc_addr, refsym);
|
||||||
*(Elf64_Word *) reloc_addr = value;
|
*(Elf64_Word *) reloc_addr = value;
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user