This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] PowerPC64: Report overflow on @h and @ha relocations
- From: Adhemerval Zanella <azanella at linux dot vnet dot ibm dot com>
- To: libc-alpha at sourceware dot org
- Date: Mon, 18 Nov 2013 17:44:33 -0200
- Subject: Re: [PATCH] PowerPC64: Report overflow on @h and @ha relocations
- Authentication-results: sourceware.org; auth=none
- References: <201311122120 dot rACLKYbU017239 at d06av02 dot portsmouth dot uk dot ibm dot com>
This patch is ok, thanks.
On 12-11-2013 19:20, Ulrich Weigand wrote:
> [PATCH] PowerPC64: Report overflow on @h and @ha relocations
>
> Hello,
>
> 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.
>
> Tested on powerpc64-linux and powerpc64le-linux.
>
> OK for mainline?
>
> Bye,
> Ulrich
>
> ChangeLog:
>
> 2013-11-12 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.
>
>
> Index: glibc/elf/elf.h
> ===================================================================
> --- glibc.orig/elf/elf.h
> +++ glibc/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
> Index: glibc/sysdeps/powerpc/powerpc64/dl-machine.h
> ===================================================================
> --- glibc.orig/sysdeps/powerpc/powerpc64/dl-machine.h
> +++ glibc/sysdeps/powerpc/powerpc64/dl-machine.h
> @@ -669,11 +669,25 @@ elf_machine_rela (struct link_map *map,
>
> 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;