aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2013-10-29 16:53:25 +1030
committerAlan Modra <amodra@gmail.com>2013-10-30 13:33:15 +1030
commitf9c6b9078c54ea0f018b673e2ff128e61a0aa666 (patch)
treed930fc55471caaf4b267600004868317e1d5e3d0 /gold
parente17aaa33b10ed1d047a01cefb5547844c0597836 (diff)
downloadgdb-f9c6b9078c54ea0f018b673e2ff128e61a0aa666.zip
gdb-f9c6b9078c54ea0f018b673e2ff128e61a0aa666.tar.gz
gdb-f9c6b9078c54ea0f018b673e2ff128e61a0aa666.tar.bz2
Report overflow on PowerPC64 @h and @ha relocations.
This changes the behaviour of @h and @ha on PowerPC64 to report errors on 32-bit overflow. The motivation for this change is that on PowerPC64, most uses of @h and @ha modifiers and their corresponding relocations are to build up 32-bit offsets. We'd like to know when such offsets overflow. Only rarely do people use @h or @ha with the high 32-bit modifiers to build a 64-bit constant. Those uses will now need to use two new modifiers, @high and @higha, if the constant isn't known at assembly time. For now, we won't report overflow at assembly time.. This also fixes an error when applying some of the HIGHER and HIGHEST relocations. include/elf/ * ppc64.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA, R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA, R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): New. (IS_PPC64_TLS_RELOC): Match new tls relocs. bfd/ * reloc.c (BFD_RELOC_PPC64_ADDR16_HIGH, BFD_RELOC_PPC64_ADDR16_HIGHA, BFD_RELOC_PPC64_TPREL16_HIGH, BFD_RELOC_PPC64_TPREL16_HIGHA, BFD_RELOC_PPC64_DTPREL16_HIGH, BFD_RELOC_PPC64_DTPREL16_HIGHA): New. * elf64-ppc.c (ppc64_elf_howto_raw): Add entries for new relocs. Make all _HA and _HI relocs report signed overflow. (ppc64_elf_reloc_type_lookup): Handle new relocs. (must_be_dyn_reloc, ppc64_elf_check_relocs): Likewise. (dec_dynrel_count, ppc64_elf_relocate_section): Likewise. (ppc64_elf_relocate_section): Don't apply 0x8000 adjust to R_PPC64_TPREL16_HIGHER, R_PPC64_TPREL16_HIGHEST, R_PPC64_DTPREL16_HIGHER, and R_PPC64_DTPREL16_HIGHEST. * libbfd.h: Regenerate. * bfd-in2.h: Regenerate. gas/ * config/tc-ppc.c (SEX16): Don't mask. (REPORT_OVERFLOW_HI): Define as zero. (ppc_elf_suffix): Support @high, @higha, @dtprel@high, @dtprel@higha, @tprel@high, and @tprel@higha modifiers. (md_assemble): Ignore X_unsigned when applying 16-bit insn fields. Add (disabled) code to check @h and @ha reloc overflow for powerpc64. Handle new relocs. (md_apply_fix): Similarly. elfcpp/ * powerpc.h (R_PPC64_ADDR16_HIGH, R_PPC64_ADDR16_HIGHA, R_PPC64_TPREL16_HIGH, R_PPC64_TPREL16_HIGHA, R_PPC64_DTPREL16_HIGH, R_PPC64_DTPREL16_HIGHA): Define. gold/ * powerpc.cc (Target_powerpc::Scan::check_non_pic): Handle new relocs. (Target_powerpc::Scan::global, local): Likewise. (Target_powerpc::Relocate::relocate): Likewise. Check for overflow on all ppc64 @h and @ha relocs.
Diffstat (limited to 'gold')
-rw-r--r--gold/ChangeLog7
-rw-r--r--gold/powerpc.cc130
2 files changed, 98 insertions, 39 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 2d16bbc..5607cb3 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,10 @@
+2013-10-30 Alan Modra <amodra@gmail.com>
+
+ * powerpc.cc (Target_powerpc::Scan::check_non_pic): Handle new relocs.
+ (Target_powerpc::Scan::global, local): Likewise.
+ (Target_powerpc::Relocate::relocate): Likewise. Check for overflow
+ on all ppc64 @h and @ha relocs.
+
2013-10-14 Alan Modra <amodra@gmail.com>
* output.h (Output_data_got::add_constant): Tidy.
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 880b367..75fc604 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -4877,6 +4877,8 @@ Target_powerpc<size, big_endian>::Scan::check_non_pic(Relobj* object,
case elfcpp::R_PPC64_JMP_IREL:
case elfcpp::R_PPC64_ADDR16_DS:
case elfcpp::R_PPC64_ADDR16_LO_DS:
+ case elfcpp::R_PPC64_ADDR16_HIGH:
+ case elfcpp::R_PPC64_ADDR16_HIGHA:
case elfcpp::R_PPC64_ADDR16_HIGHER:
case elfcpp::R_PPC64_ADDR16_HIGHEST:
case elfcpp::R_PPC64_ADDR16_HIGHERA:
@@ -4885,6 +4887,8 @@ Target_powerpc<size, big_endian>::Scan::check_non_pic(Relobj* object,
case elfcpp::R_POWERPC_ADDR30:
case elfcpp::R_PPC64_TPREL16_DS:
case elfcpp::R_PPC64_TPREL16_LO_DS:
+ case elfcpp::R_PPC64_TPREL16_HIGH:
+ case elfcpp::R_PPC64_TPREL16_HIGHA:
case elfcpp::R_PPC64_TPREL16_HIGHER:
case elfcpp::R_PPC64_TPREL16_HIGHEST:
case elfcpp::R_PPC64_TPREL16_HIGHERA:
@@ -5057,7 +5061,6 @@ Target_powerpc<size, big_endian>::Scan::local(
case elfcpp::R_POWERPC_GNU_VTINHERIT:
case elfcpp::R_POWERPC_GNU_VTENTRY:
case elfcpp::R_PPC64_TOCSAVE:
- case elfcpp::R_PPC_EMB_MRKREF:
case elfcpp::R_POWERPC_TLS:
break;
@@ -5094,6 +5097,8 @@ Target_powerpc<size, big_endian>::Scan::local(
case elfcpp::R_POWERPC_ADDR16_HI:
case elfcpp::R_POWERPC_ADDR16_HA:
case elfcpp::R_POWERPC_UADDR16:
+ case elfcpp::R_PPC64_ADDR16_HIGH:
+ case elfcpp::R_PPC64_ADDR16_HIGHA:
case elfcpp::R_PPC64_ADDR16_HIGHER:
case elfcpp::R_PPC64_ADDR16_HIGHERA:
case elfcpp::R_PPC64_ADDR16_HIGHEST:
@@ -5152,31 +5157,35 @@ Target_powerpc<size, big_endian>::Scan::local(
case elfcpp::R_POWERPC_REL16_HI:
case elfcpp::R_POWERPC_REL16_HA:
case elfcpp::R_POWERPC_SECTOFF:
- case elfcpp::R_POWERPC_TPREL16:
- case elfcpp::R_POWERPC_DTPREL16:
case elfcpp::R_POWERPC_SECTOFF_LO:
- case elfcpp::R_POWERPC_TPREL16_LO:
- case elfcpp::R_POWERPC_DTPREL16_LO:
case elfcpp::R_POWERPC_SECTOFF_HI:
- case elfcpp::R_POWERPC_TPREL16_HI:
- case elfcpp::R_POWERPC_DTPREL16_HI:
case elfcpp::R_POWERPC_SECTOFF_HA:
+ case elfcpp::R_PPC64_SECTOFF_DS:
+ case elfcpp::R_PPC64_SECTOFF_LO_DS:
+ case elfcpp::R_POWERPC_TPREL16:
+ case elfcpp::R_POWERPC_TPREL16_LO:
+ case elfcpp::R_POWERPC_TPREL16_HI:
case elfcpp::R_POWERPC_TPREL16_HA:
- case elfcpp::R_POWERPC_DTPREL16_HA:
- case elfcpp::R_PPC64_DTPREL16_HIGHER:
+ case elfcpp::R_PPC64_TPREL16_DS:
+ case elfcpp::R_PPC64_TPREL16_LO_DS:
+ case elfcpp::R_PPC64_TPREL16_HIGH:
+ case elfcpp::R_PPC64_TPREL16_HIGHA:
case elfcpp::R_PPC64_TPREL16_HIGHER:
- case elfcpp::R_PPC64_DTPREL16_HIGHERA:
case elfcpp::R_PPC64_TPREL16_HIGHERA:
- case elfcpp::R_PPC64_DTPREL16_HIGHEST:
case elfcpp::R_PPC64_TPREL16_HIGHEST:
- case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
case elfcpp::R_PPC64_TPREL16_HIGHESTA:
- case elfcpp::R_PPC64_TPREL16_DS:
- case elfcpp::R_PPC64_TPREL16_LO_DS:
+ case elfcpp::R_POWERPC_DTPREL16:
+ case elfcpp::R_POWERPC_DTPREL16_LO:
+ case elfcpp::R_POWERPC_DTPREL16_HI:
+ case elfcpp::R_POWERPC_DTPREL16_HA:
case elfcpp::R_PPC64_DTPREL16_DS:
case elfcpp::R_PPC64_DTPREL16_LO_DS:
- case elfcpp::R_PPC64_SECTOFF_DS:
- case elfcpp::R_PPC64_SECTOFF_LO_DS:
+ case elfcpp::R_PPC64_DTPREL16_HIGH:
+ case elfcpp::R_PPC64_DTPREL16_HIGHA:
+ case elfcpp::R_PPC64_DTPREL16_HIGHER:
+ case elfcpp::R_PPC64_DTPREL16_HIGHERA:
+ case elfcpp::R_PPC64_DTPREL16_HIGHEST:
+ case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
case elfcpp::R_PPC64_TLSGD:
case elfcpp::R_PPC64_TLSLD:
break;
@@ -5407,7 +5416,6 @@ Target_powerpc<size, big_endian>::Scan::global(
case elfcpp::R_POWERPC_GNU_VTINHERIT:
case elfcpp::R_POWERPC_GNU_VTENTRY:
case elfcpp::R_PPC_LOCAL24PC:
- case elfcpp::R_PPC_EMB_MRKREF:
case elfcpp::R_POWERPC_TLS:
break;
@@ -5456,6 +5464,8 @@ Target_powerpc<size, big_endian>::Scan::global(
case elfcpp::R_POWERPC_ADDR16_HI:
case elfcpp::R_POWERPC_ADDR16_HA:
case elfcpp::R_POWERPC_UADDR16:
+ case elfcpp::R_PPC64_ADDR16_HIGH:
+ case elfcpp::R_PPC64_ADDR16_HIGHA:
case elfcpp::R_PPC64_ADDR16_HIGHER:
case elfcpp::R_PPC64_ADDR16_HIGHERA:
case elfcpp::R_PPC64_ADDR16_HIGHEST:
@@ -5581,31 +5591,35 @@ Target_powerpc<size, big_endian>::Scan::global(
case elfcpp::R_POWERPC_REL16_HI:
case elfcpp::R_POWERPC_REL16_HA:
case elfcpp::R_POWERPC_SECTOFF:
- case elfcpp::R_POWERPC_TPREL16:
- case elfcpp::R_POWERPC_DTPREL16:
case elfcpp::R_POWERPC_SECTOFF_LO:
- case elfcpp::R_POWERPC_TPREL16_LO:
- case elfcpp::R_POWERPC_DTPREL16_LO:
case elfcpp::R_POWERPC_SECTOFF_HI:
- case elfcpp::R_POWERPC_TPREL16_HI:
- case elfcpp::R_POWERPC_DTPREL16_HI:
case elfcpp::R_POWERPC_SECTOFF_HA:
+ case elfcpp::R_PPC64_SECTOFF_DS:
+ case elfcpp::R_PPC64_SECTOFF_LO_DS:
+ case elfcpp::R_POWERPC_TPREL16:
+ case elfcpp::R_POWERPC_TPREL16_LO:
+ case elfcpp::R_POWERPC_TPREL16_HI:
case elfcpp::R_POWERPC_TPREL16_HA:
- case elfcpp::R_POWERPC_DTPREL16_HA:
- case elfcpp::R_PPC64_DTPREL16_HIGHER:
+ case elfcpp::R_PPC64_TPREL16_DS:
+ case elfcpp::R_PPC64_TPREL16_LO_DS:
+ case elfcpp::R_PPC64_TPREL16_HIGH:
+ case elfcpp::R_PPC64_TPREL16_HIGHA:
case elfcpp::R_PPC64_TPREL16_HIGHER:
- case elfcpp::R_PPC64_DTPREL16_HIGHERA:
case elfcpp::R_PPC64_TPREL16_HIGHERA:
- case elfcpp::R_PPC64_DTPREL16_HIGHEST:
case elfcpp::R_PPC64_TPREL16_HIGHEST:
- case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
case elfcpp::R_PPC64_TPREL16_HIGHESTA:
- case elfcpp::R_PPC64_TPREL16_DS:
- case elfcpp::R_PPC64_TPREL16_LO_DS:
+ case elfcpp::R_POWERPC_DTPREL16:
+ case elfcpp::R_POWERPC_DTPREL16_LO:
+ case elfcpp::R_POWERPC_DTPREL16_HI:
+ case elfcpp::R_POWERPC_DTPREL16_HA:
case elfcpp::R_PPC64_DTPREL16_DS:
case elfcpp::R_PPC64_DTPREL16_LO_DS:
- case elfcpp::R_PPC64_SECTOFF_DS:
- case elfcpp::R_PPC64_SECTOFF_LO_DS:
+ case elfcpp::R_PPC64_DTPREL16_HIGH:
+ case elfcpp::R_PPC64_DTPREL16_HIGHA:
+ case elfcpp::R_PPC64_DTPREL16_HIGHER:
+ case elfcpp::R_PPC64_DTPREL16_HIGHERA:
+ case elfcpp::R_PPC64_DTPREL16_HIGHEST:
+ case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
case elfcpp::R_PPC64_TLSGD:
case elfcpp::R_PPC64_TLSLD:
break;
@@ -6748,8 +6762,10 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
case elfcpp::R_PPC64_TPREL16_DS:
case elfcpp::R_PPC64_TPREL16_LO_DS:
+ case elfcpp::R_PPC64_TPREL16_HIGH:
+ case elfcpp::R_PPC64_TPREL16_HIGHA:
if (size != 64)
- // R_PPC_TLSGD and R_PPC_TLSLD
+ // R_PPC_TLSGD, R_PPC_TLSLD, R_PPC_EMB_RELST_LO, R_PPC_EMB_RELST_HI
break;
case elfcpp::R_POWERPC_TPREL16:
case elfcpp::R_POWERPC_TPREL16_LO:
@@ -6779,6 +6795,8 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
case elfcpp::R_POWERPC_DTPREL16_HI:
case elfcpp::R_POWERPC_DTPREL16_HA:
case elfcpp::R_POWERPC_DTPREL:
+ case elfcpp::R_PPC64_DTPREL16_HIGH:
+ case elfcpp::R_PPC64_DTPREL16_HIGHA:
// tls symbol values are relative to tls_segment()->vaddr()
value -= dtp_offset;
break;
@@ -6919,6 +6937,34 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
overflow = Reloc::CHECK_BITFIELD;
break;
+ case elfcpp::R_POWERPC_ADDR16_HI:
+ case elfcpp::R_POWERPC_ADDR16_HA:
+ case elfcpp::R_POWERPC_GOT16_HI:
+ case elfcpp::R_POWERPC_GOT16_HA:
+ case elfcpp::R_POWERPC_PLT16_HI:
+ case elfcpp::R_POWERPC_PLT16_HA:
+ case elfcpp::R_POWERPC_SECTOFF_HI:
+ case elfcpp::R_POWERPC_SECTOFF_HA:
+ case elfcpp::R_PPC64_TOC16_HI:
+ case elfcpp::R_PPC64_TOC16_HA:
+ case elfcpp::R_PPC64_PLTGOT16_HI:
+ case elfcpp::R_PPC64_PLTGOT16_HA:
+ case elfcpp::R_POWERPC_TPREL16_HI:
+ case elfcpp::R_POWERPC_TPREL16_HA:
+ case elfcpp::R_POWERPC_DTPREL16_HI:
+ case elfcpp::R_POWERPC_DTPREL16_HA:
+ case elfcpp::R_POWERPC_GOT_TLSGD16_HI:
+ case elfcpp::R_POWERPC_GOT_TLSGD16_HA:
+ case elfcpp::R_POWERPC_GOT_TLSLD16_HI:
+ case elfcpp::R_POWERPC_GOT_TLSLD16_HA:
+ case elfcpp::R_POWERPC_GOT_TPREL16_HI:
+ case elfcpp::R_POWERPC_GOT_TPREL16_HA:
+ case elfcpp::R_POWERPC_GOT_DTPREL16_HI:
+ case elfcpp::R_POWERPC_GOT_DTPREL16_HA:
+ case elfcpp::R_POWERPC_REL16_HI:
+ case elfcpp::R_POWERPC_REL16_HA:
+ if (size == 32)
+ break;
case elfcpp::R_POWERPC_REL24:
case elfcpp::R_PPC_PLTREL24:
case elfcpp::R_PPC_LOCAL24PC:
@@ -6952,7 +6998,6 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
case elfcpp::R_POWERPC_TLS:
case elfcpp::R_POWERPC_GNU_VTINHERIT:
case elfcpp::R_POWERPC_GNU_VTENTRY:
- case elfcpp::R_PPC_EMB_MRKREF:
break;
case elfcpp::R_PPC64_ADDR64:
@@ -7023,6 +7068,12 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
status = Reloc::addr16_u(view, value, overflow);
break;
+ case elfcpp::R_PPC64_ADDR16_HIGH:
+ case elfcpp::R_PPC64_TPREL16_HIGH:
+ case elfcpp::R_PPC64_DTPREL16_HIGH:
+ if (size == 32)
+ // R_PPC_EMB_MRKREF, R_PPC_EMB_RELST_LO, R_PPC_EMB_RELST_HA
+ goto unsupp;
case elfcpp::R_POWERPC_ADDR16_HI:
case elfcpp::R_POWERPC_REL16_HI:
case elfcpp::R_PPC64_TOC16_HI:
@@ -7037,6 +7088,12 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
Reloc::addr16_hi(view, value);
break;
+ case elfcpp::R_PPC64_ADDR16_HIGHA:
+ case elfcpp::R_PPC64_TPREL16_HIGHA:
+ case elfcpp::R_PPC64_DTPREL16_HIGHA:
+ if (size == 32)
+ // R_PPC_EMB_RELSEC16, R_PPC_EMB_RELST_HI, R_PPC_EMB_BIT_FLD
+ goto unsupp;
case elfcpp::R_POWERPC_ADDR16_HA:
case elfcpp::R_POWERPC_REL16_HA:
case elfcpp::R_PPC64_TOC16_HA:
@@ -7161,11 +7218,6 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
case elfcpp::R_PPC64_PLT16_LO_DS:
case elfcpp::R_PPC64_PLTGOT16_DS:
case elfcpp::R_PPC64_PLTGOT16_LO_DS:
- case elfcpp::R_PPC_EMB_RELSEC16:
- case elfcpp::R_PPC_EMB_RELST_LO:
- case elfcpp::R_PPC_EMB_RELST_HI:
- case elfcpp::R_PPC_EMB_RELST_HA:
- case elfcpp::R_PPC_EMB_BIT_FLD:
case elfcpp::R_PPC_EMB_RELSDA:
case elfcpp::R_PPC_TOC16:
default: