Report overflow on PowerPC64 @h and @ha relocations.
authorAlan Modra <amodra@gmail.com>
Tue, 29 Oct 2013 06:23:25 +0000 (16:53 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 30 Oct 2013 03:03:15 +0000 (13:33 +1030)
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.

13 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf64-ppc.c
bfd/libbfd.h
bfd/reloc.c
elfcpp/ChangeLog
elfcpp/powerpc.h
gas/ChangeLog
gas/config/tc-ppc.c
gold/ChangeLog
gold/powerpc.cc
include/elf/ChangeLog
include/elf/ppc64.h

index 059998e1521e607e0715e8aa1fb79605b7dc88b4..304442fb9a68f1186e3538c3a6502edf2540f6d0 100644 (file)
@@ -1,3 +1,19 @@
+2013-10-30  Alan Modra  <amodra@gmail.com>
+
+       * 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.
+
 2013-10-29  Roland McGrath  <mcgrathr@google.com>
 
        * elf64-x86-64.c (elf_x86_64_nacl_plt0_entry): Correct 9-byte nop
index 810e1729c06025f1ed8be566fd94ae92795d41f6..644f89de77c3f7d1a4bef78ef22d6620466f2c05 100644 (file)
@@ -3223,6 +3223,8 @@ instruction.  */
   BFD_RELOC_PPC64_TOC16_LO_DS,
   BFD_RELOC_PPC64_PLTGOT16_DS,
   BFD_RELOC_PPC64_PLTGOT16_LO_DS,
+  BFD_RELOC_PPC64_ADDR16_HIGH,
+  BFD_RELOC_PPC64_ADDR16_HIGHA,
 
 /* PowerPC and PowerPC64 thread-local storage relocations.  */
   BFD_RELOC_PPC_TLS,
@@ -3267,6 +3269,10 @@ instruction.  */
   BFD_RELOC_PPC64_DTPREL16_HIGHERA,
   BFD_RELOC_PPC64_DTPREL16_HIGHEST,
   BFD_RELOC_PPC64_DTPREL16_HIGHESTA,
+  BFD_RELOC_PPC64_TPREL16_HIGH,
+  BFD_RELOC_PPC64_TPREL16_HIGHA,
+  BFD_RELOC_PPC64_DTPREL16_HIGH,
+  BFD_RELOC_PPC64_DTPREL16_HIGHA,
 
 /* IBM 370/390 relocations  */
   BFD_RELOC_I370_D12,
index 3df01f64f83f4058f5c55d0bcb4469f1ad270f5d..63d4eb99a85c90fb5efd290faff7083e6b9fb9c7 100644 (file)
@@ -309,7 +309,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_PPC64_ADDR16_HI",   /* name */
         FALSE,                 /* partial_inplace */
@@ -325,7 +325,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_ha_reloc,    /* special_function */
         "R_PPC64_ADDR16_HA",   /* name */
         FALSE,                 /* partial_inplace */
@@ -487,7 +487,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont,/* complain_on_overflow */
+        complain_overflow_signed,/* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_GOT16_HI",    /* name */
         FALSE,                 /* partial_inplace */
@@ -503,7 +503,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont,/* complain_on_overflow */
+        complain_overflow_signed,/* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_GOT16_HA",    /* name */
         FALSE,                 /* partial_inplace */
@@ -680,7 +680,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_PLT16_HI",    /* name */
         FALSE,                 /* partial_inplace */
@@ -696,7 +696,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_PLT16_HA",    /* name */
         FALSE,                 /* partial_inplace */
@@ -741,7 +741,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_sectoff_reloc, /* special_function */
         "R_PPC64_SECTOFF_HI",  /* name */
         FALSE,                 /* partial_inplace */
@@ -756,7 +756,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_sectoff_ha_reloc, /* special_function */
         "R_PPC64_SECTOFF_HA",  /* name */
         FALSE,                 /* partial_inplace */
@@ -963,7 +963,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_toc_reloc,   /* special_function */
         "R_PPC64_TOC16_HI",    /* name */
         FALSE,                 /* partial_inplace */
@@ -982,7 +982,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_toc_ha_reloc, /* special_function */
         "R_PPC64_TOC16_HA",    /* name */
         FALSE,                 /* partial_inplace */
@@ -1054,7 +1054,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_PLTGOT16_HI", /* name */
         FALSE,                 /* partial_inplace */
@@ -1072,7 +1072,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont,/* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_PLTGOT16_HA", /* name */
         FALSE,                 /* partial_inplace */
@@ -1374,7 +1374,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_DTPREL16_HI", /* name */
         FALSE,                 /* partial_inplace */
@@ -1389,7 +1389,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_DTPREL16_HA", /* name */
         FALSE,                 /* partial_inplace */
@@ -1540,7 +1540,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_TPREL16_HI",  /* name */
         FALSE,                 /* partial_inplace */
@@ -1555,7 +1555,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_TPREL16_HA",  /* name */
         FALSE,                 /* partial_inplace */
@@ -1692,7 +1692,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_GOT_TLSGD16_HI", /* name */
         FALSE,                 /* partial_inplace */
@@ -1707,7 +1707,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_GOT_TLSGD16_HA", /* name */
         FALSE,                 /* partial_inplace */
@@ -1754,7 +1754,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_GOT_TLSLD16_HI", /* name */
         FALSE,                 /* partial_inplace */
@@ -1769,7 +1769,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_GOT_TLSLD16_HA", /* name */
         FALSE,                 /* partial_inplace */
@@ -1815,7 +1815,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_GOT_DTPREL16_HI", /* name */
         FALSE,                 /* partial_inplace */
@@ -1830,7 +1830,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_GOT_DTPREL16_HA", /* name */
         FALSE,                 /* partial_inplace */
@@ -1876,7 +1876,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_GOT_TPREL16_HI", /* name */
         FALSE,                 /* partial_inplace */
@@ -1891,7 +1891,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_unhandled_reloc, /* special_function */
         "R_PPC64_GOT_TPREL16_HA", /* name */
         FALSE,                 /* partial_inplace */
@@ -1964,7 +1964,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_PPC64_REL16_HI",    /* name */
         FALSE,                 /* partial_inplace */
@@ -1980,7 +1980,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         16,                    /* bitsize */
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         ppc64_elf_ha_reloc,    /* special_function */
         "R_PPC64_REL16_HA",    /* name */
         FALSE,                 /* partial_inplace */
@@ -1988,6 +1988,96 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
         0xffff,                /* dst_mask */
         TRUE),                 /* pcrel_offset */
 
+  /* Like R_PPC64_ADDR16_HI, but no overflow.  */
+  HOWTO (R_PPC64_ADDR16_HIGH,  /* type */
+        16,                    /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_PPC64_ADDR16_HIGH", /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* Like R_PPC64_ADDR16_HA, but no overflow.  */
+  HOWTO (R_PPC64_ADDR16_HIGHA, /* type */
+        16,                    /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        ppc64_elf_ha_reloc,    /* special_function */
+        "R_PPC64_ADDR16_HIGHA",        /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* Like R_PPC64_DTPREL16_HI, but no overflow.  */
+  HOWTO (R_PPC64_DTPREL16_HIGH,
+        16,                    /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        ppc64_elf_unhandled_reloc, /* special_function */
+        "R_PPC64_DTPREL16_HIGH", /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* Like R_PPC64_DTPREL16_HA, but no overflow.  */
+  HOWTO (R_PPC64_DTPREL16_HIGHA,
+        16,                    /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        ppc64_elf_unhandled_reloc, /* special_function */
+        "R_PPC64_DTPREL16_HIGHA", /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* Like R_PPC64_TPREL16_HI, but no overflow.  */
+  HOWTO (R_PPC64_TPREL16_HIGH,
+        16,                    /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        ppc64_elf_unhandled_reloc, /* special_function */
+        "R_PPC64_TPREL16_HIGH",        /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* Like R_PPC64_TPREL16_HA, but no overflow.  */
+  HOWTO (R_PPC64_TPREL16_HIGHA,
+        16,                    /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        ppc64_elf_unhandled_reloc, /* special_function */
+        "R_PPC64_TPREL16_HIGHA",       /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
   /* GNU extension to record C++ vtable hierarchy.  */
   HOWTO (R_PPC64_GNU_VTINHERIT,        /* type */
         0,                     /* rightshift */
@@ -2066,8 +2156,12 @@ ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
       break;
     case BFD_RELOC_HI16:                       r = R_PPC64_ADDR16_HI;
       break;
+    case BFD_RELOC_PPC64_ADDR16_HIGH:          r = R_PPC64_ADDR16_HIGH;
+      break;
     case BFD_RELOC_HI16_S:                     r = R_PPC64_ADDR16_HA;
       break;
+    case BFD_RELOC_PPC64_ADDR16_HIGHA:         r = R_PPC64_ADDR16_HIGHA;
+      break;
     case BFD_RELOC_PPC_BA16:                   r = R_PPC64_ADDR14;
       break;
     case BFD_RELOC_PPC_BA16_BRTAKEN:           r = R_PPC64_ADDR14_BRTAKEN;
@@ -2186,8 +2280,12 @@ ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
       break;
     case BFD_RELOC_PPC_TPREL16_HI:             r = R_PPC64_TPREL16_HI;
       break;
+    case BFD_RELOC_PPC64_TPREL16_HIGH:         r = R_PPC64_TPREL16_HIGH;
+      break;
     case BFD_RELOC_PPC_TPREL16_HA:             r = R_PPC64_TPREL16_HA;
       break;
+    case BFD_RELOC_PPC64_TPREL16_HIGHA:                r = R_PPC64_TPREL16_HIGHA;
+      break;
     case BFD_RELOC_PPC_TPREL:                  r = R_PPC64_TPREL64;
       break;
     case BFD_RELOC_PPC_DTPREL16:               r = R_PPC64_DTPREL16;
@@ -2196,8 +2294,12 @@ ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
       break;
     case BFD_RELOC_PPC_DTPREL16_HI:            r = R_PPC64_DTPREL16_HI;
       break;
+    case BFD_RELOC_PPC64_DTPREL16_HIGH:                r = R_PPC64_DTPREL16_HIGH;
+      break;
     case BFD_RELOC_PPC_DTPREL16_HA:            r = R_PPC64_DTPREL16_HA;
       break;
+    case BFD_RELOC_PPC64_DTPREL16_HIGHA:       r = R_PPC64_DTPREL16_HIGHA;
+      break;
     case BFD_RELOC_PPC_DTPREL:                 r = R_PPC64_DTPREL64;
       break;
     case BFD_RELOC_PPC_GOT_TLSGD16:            r = R_PPC64_GOT_TLSGD16;
@@ -3514,6 +3616,8 @@ must_be_dyn_reloc (struct bfd_link_info *info,
     case R_PPC64_TPREL16_HA:
     case R_PPC64_TPREL16_DS:
     case R_PPC64_TPREL16_LO_DS:
+    case R_PPC64_TPREL16_HIGH:
+    case R_PPC64_TPREL16_HIGHA:
     case R_PPC64_TPREL16_HIGHER:
     case R_PPC64_TPREL16_HIGHERA:
     case R_PPC64_TPREL16_HIGHEST:
@@ -5208,6 +5312,8 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_PPC64_DTPREL16_HA:
        case R_PPC64_DTPREL16_DS:
        case R_PPC64_DTPREL16_LO_DS:
+       case R_PPC64_DTPREL16_HIGH:
+       case R_PPC64_DTPREL16_HIGHA:
        case R_PPC64_DTPREL16_HIGHER:
        case R_PPC64_DTPREL16_HIGHERA:
        case R_PPC64_DTPREL16_HIGHEST:
@@ -5368,6 +5474,8 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_PPC64_TPREL16_HA:
        case R_PPC64_TPREL16_DS:
        case R_PPC64_TPREL16_LO_DS:
+       case R_PPC64_TPREL16_HIGH:
+       case R_PPC64_TPREL16_HIGHA:
        case R_PPC64_TPREL16_HIGHER:
        case R_PPC64_TPREL16_HIGHERA:
        case R_PPC64_TPREL16_HIGHEST:
@@ -5421,6 +5529,8 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_PPC64_ADDR16_DS:
        case R_PPC64_ADDR16_HA:
        case R_PPC64_ADDR16_HI:
+       case R_PPC64_ADDR16_HIGH:
+       case R_PPC64_ADDR16_HIGHA:
        case R_PPC64_ADDR16_HIGHER:
        case R_PPC64_ADDR16_HIGHERA:
        case R_PPC64_ADDR16_HIGHEST:
@@ -7052,6 +7162,8 @@ dec_dynrel_count (bfd_vma r_info,
     case R_PPC64_TPREL16_HA:
     case R_PPC64_TPREL16_DS:
     case R_PPC64_TPREL16_LO_DS:
+    case R_PPC64_TPREL16_HIGH:
+    case R_PPC64_TPREL16_HIGHA:
     case R_PPC64_TPREL16_HIGHER:
     case R_PPC64_TPREL16_HIGHERA:
     case R_PPC64_TPREL16_HIGHEST:
@@ -7073,6 +7185,8 @@ dec_dynrel_count (bfd_vma r_info,
     case R_PPC64_ADDR16_DS:
     case R_PPC64_ADDR16_HA:
     case R_PPC64_ADDR16_HI:
+    case R_PPC64_ADDR16_HIGH:
+    case R_PPC64_ADDR16_HIGHA:
     case R_PPC64_ADDR16_HIGHER:
     case R_PPC64_ADDR16_HIGHERA:
     case R_PPC64_ADDR16_HIGHEST:
@@ -13531,6 +13645,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
        case R_PPC64_TPREL16_HA:
        case R_PPC64_TPREL16_DS:
        case R_PPC64_TPREL16_LO_DS:
+       case R_PPC64_TPREL16_HIGH:
+       case R_PPC64_TPREL16_HIGHA:
        case R_PPC64_TPREL16_HIGHER:
        case R_PPC64_TPREL16_HIGHERA:
        case R_PPC64_TPREL16_HIGHEST:
@@ -13565,6 +13681,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
        case R_PPC64_DTPREL16_HA:
        case R_PPC64_DTPREL16_DS:
        case R_PPC64_DTPREL16_LO_DS:
+       case R_PPC64_DTPREL16_HIGH:
+       case R_PPC64_DTPREL16_HIGHA:
        case R_PPC64_DTPREL16_HIGHER:
        case R_PPC64_DTPREL16_HIGHERA:
        case R_PPC64_DTPREL16_HIGHEST:
@@ -13597,6 +13715,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
        case R_PPC64_ADDR16_DS:
        case R_PPC64_ADDR16_HA:
        case R_PPC64_ADDR16_HI:
+       case R_PPC64_ADDR16_HIGH:
+       case R_PPC64_ADDR16_HIGHA:
        case R_PPC64_ADDR16_HIGHER:
        case R_PPC64_ADDR16_HIGHERA:
        case R_PPC64_ADDR16_HIGHEST:
@@ -13911,21 +14031,20 @@ ppc64_elf_relocate_section (bfd *output_bfd,
        default:
          break;
 
-       case R_PPC64_ADDR16_HA:
        case R_PPC64_REL16_HA:
+       case R_PPC64_ADDR16_HA:
+       case R_PPC64_ADDR16_HIGHA:
        case R_PPC64_ADDR16_HIGHERA:
        case R_PPC64_ADDR16_HIGHESTA:
        case R_PPC64_TOC16_HA:
        case R_PPC64_SECTOFF_HA:
        case R_PPC64_TPREL16_HA:
-       case R_PPC64_DTPREL16_HA:
-       case R_PPC64_TPREL16_HIGHER:
+       case R_PPC64_TPREL16_HIGHA:
        case R_PPC64_TPREL16_HIGHERA:
-       case R_PPC64_TPREL16_HIGHEST:
        case R_PPC64_TPREL16_HIGHESTA:
-       case R_PPC64_DTPREL16_HIGHER:
+       case R_PPC64_DTPREL16_HA:
+       case R_PPC64_DTPREL16_HIGHA:
        case R_PPC64_DTPREL16_HIGHERA:
-       case R_PPC64_DTPREL16_HIGHEST:
        case R_PPC64_DTPREL16_HIGHESTA:
          /* It's just possible that this symbol is a weak symbol
             that's not actually defined anywhere. In that case,
index 1381803f001e01ef67bf0b33054a53463b155aa7..4f98108afd57c304a3526ffdefc674b7f1784924 100644 (file)
@@ -1397,6 +1397,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_PPC64_TOC16_LO_DS",
   "BFD_RELOC_PPC64_PLTGOT16_DS",
   "BFD_RELOC_PPC64_PLTGOT16_LO_DS",
+  "BFD_RELOC_PPC64_ADDR16_HIGH",
+  "BFD_RELOC_PPC64_ADDR16_HIGHA",
   "BFD_RELOC_PPC_TLS",
   "BFD_RELOC_PPC_TLSGD",
   "BFD_RELOC_PPC_TLSLD",
@@ -1439,6 +1441,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_PPC64_DTPREL16_HIGHERA",
   "BFD_RELOC_PPC64_DTPREL16_HIGHEST",
   "BFD_RELOC_PPC64_DTPREL16_HIGHESTA",
+  "BFD_RELOC_PPC64_TPREL16_HIGH",
+  "BFD_RELOC_PPC64_TPREL16_HIGHA",
+  "BFD_RELOC_PPC64_DTPREL16_HIGH",
+  "BFD_RELOC_PPC64_DTPREL16_HIGHA",
   "BFD_RELOC_I370_D12",
   "BFD_RELOC_CTOR",
   "BFD_RELOC_ARM_PCREL_BRANCH",
index 25c089c5e2e9a65fd504a5f9674c0c90586fd133..8778e1d46579ea115ab074889534601f3a53985b 100644 (file)
@@ -2891,6 +2891,10 @@ ENUMX
   BFD_RELOC_PPC64_PLTGOT16_DS
 ENUMX
   BFD_RELOC_PPC64_PLTGOT16_LO_DS
+ENUMX
+  BFD_RELOC_PPC64_ADDR16_HIGH
+ENUMX
+  BFD_RELOC_PPC64_ADDR16_HIGHA
 ENUMDOC
   Power(rs6000) and PowerPC relocations.
 
@@ -2978,6 +2982,14 @@ ENUMX
   BFD_RELOC_PPC64_DTPREL16_HIGHEST
 ENUMX
   BFD_RELOC_PPC64_DTPREL16_HIGHESTA
+ENUMX
+  BFD_RELOC_PPC64_TPREL16_HIGH
+ENUMX
+  BFD_RELOC_PPC64_TPREL16_HIGHA
+ENUMX
+  BFD_RELOC_PPC64_DTPREL16_HIGH
+ENUMX
+  BFD_RELOC_PPC64_DTPREL16_HIGHA
 ENUMDOC
   PowerPC and PowerPC64 thread-local storage relocations.
 
index 41897fb856d99dd388459f5985607524799c5e3f..0c9c00139312aa004b8531c0e641dbe309af27bb 100644 (file)
@@ -1,3 +1,9 @@
+2013-10-30  Alan Modra  <amodra@gmail.com>
+
+       * 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.
+
 2013-03-01  Cary Coutant  <ccoutant@google.com>
 
        * dwarf.h (enum DW_LANG): Adjust spacing for consistency.
index 2c803af94e3b3ccdc55ae7d1d9c15c02171eec9f..fb4256bdafe8d77e1c9d2b0a096c9e3685086816 100644 (file)
@@ -164,11 +164,17 @@ enum
   R_PPC_EMB_SDA21 = 109,
   R_PPC64_TOCSAVE = 109,
   R_PPC_EMB_MRKREF = 110,
+  R_PPC64_ADDR16_HIGH = 110,
   R_PPC_EMB_RELSEC16 = 111,
+  R_PPC64_ADDR16_HIGHA = 111,
   R_PPC_EMB_RELST_LO = 112,
+  R_PPC64_TPREL16_HIGH = 112,
   R_PPC_EMB_RELST_HI = 113,
+  R_PPC64_TPREL16_HIGHA = 113,
   R_PPC_EMB_RELST_HA = 114,
+  R_PPC64_DTPREL16_HIGH = 114,
   R_PPC_EMB_BIT_FLD = 115,
+  R_PPC64_DTPREL16_HIGHA = 115,
   R_PPC_EMB_RELSDA = 116,
 
   R_PPC_VLE_REL8 = 216,
index 1490eeaf943ef2880fdb4297f4faf59e08087b8d..a1b71b0758242c7125a7d1d61addb302574aaa01 100644 (file)
@@ -1,3 +1,14 @@
+2013-10-30  Alan Modra  <amodra@gmail.com>
+
+       * 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.
+
 2013-10-18  Chao-ying Fu  <Chao-ying.Fu@imgtec.com>
 
        * config/tc-mips.c (fpr_read_mask): Test MSA registers.
index 6b54f5ad8ebcb979abe24e9428d65246a6631c8e..34afc916903925001b5f816957f7265c34af654b 100644 (file)
@@ -86,7 +86,11 @@ static int set_target_endian = 0;
    compensating for #lo being treated as a signed number.  */
 #define PPC_HIGHESTA(v) PPC_HIGHEST ((v) + 0x8000)
 
-#define SEX16(val) ((((val) & 0xffff) ^ 0x8000) - 0x8000)
+#define SEX16(val) (((val) ^ 0x8000) - 0x8000)
+
+/* For the time being on ppc64, don't report overflow on @h and @ha
+   applied to constants.  */
+#define REPORT_OVERFLOW_HI 0
 
 static bfd_boolean reg_names_p = TARGET_REG_NAMES_P;
 
@@ -1923,6 +1927,8 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
     MAP32 ("bitfld",           BFD_RELOC_PPC_EMB_BIT_FLD),
     MAP32 ("relsda",           BFD_RELOC_PPC_EMB_RELSDA),
     MAP32 ("xgot",             BFD_RELOC_PPC_TOC16),
+    MAP64 ("high",             BFD_RELOC_PPC64_ADDR16_HIGH),
+    MAP64 ("higha",            BFD_RELOC_PPC64_ADDR16_HIGHA),
     MAP64 ("higher",           BFD_RELOC_PPC64_HIGHER),
     MAP64 ("highera",          BFD_RELOC_PPC64_HIGHER_S),
     MAP64 ("highest",          BFD_RELOC_PPC64_HIGHEST),
@@ -1932,10 +1938,14 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
     MAP64 ("toc@l",            BFD_RELOC_PPC64_TOC16_LO),
     MAP64 ("toc@h",            BFD_RELOC_PPC64_TOC16_HI),
     MAP64 ("toc@ha",           BFD_RELOC_PPC64_TOC16_HA),
+    MAP64 ("dtprel@high",      BFD_RELOC_PPC64_DTPREL16_HIGH),
+    MAP64 ("dtprel@higha",     BFD_RELOC_PPC64_DTPREL16_HIGHA),
     MAP64 ("dtprel@higher",    BFD_RELOC_PPC64_DTPREL16_HIGHER),
     MAP64 ("dtprel@highera",   BFD_RELOC_PPC64_DTPREL16_HIGHERA),
     MAP64 ("dtprel@highest",   BFD_RELOC_PPC64_DTPREL16_HIGHEST),
     MAP64 ("dtprel@highesta",  BFD_RELOC_PPC64_DTPREL16_HIGHESTA),
+    MAP64 ("tprel@high",       BFD_RELOC_PPC64_TPREL16_HIGH),
+    MAP64 ("tprel@higha",      BFD_RELOC_PPC64_TPREL16_HIGHA),
     MAP64 ("tprel@higher",     BFD_RELOC_PPC64_TPREL16_HIGHER),
     MAP64 ("tprel@highera",    BFD_RELOC_PPC64_TPREL16_HIGHERA),
     MAP64 ("tprel@highest",    BFD_RELOC_PPC64_TPREL16_HIGHEST),
@@ -2810,55 +2820,76 @@ md_assemble (char *str)
                break;
 
              case BFD_RELOC_LO16:
-               /* X_unsigned is the default, so if the user has done
-                  something which cleared it, we always produce a
-                  signed value.  */
-               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
-                 ex.X_add_number &= 0xffff;
-               else
+               ex.X_add_number &= 0xffff;
+               if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
                  ex.X_add_number = SEX16 (ex.X_add_number);
                break;
 
              case BFD_RELOC_HI16:
-               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
-                 ex.X_add_number = PPC_HI (ex.X_add_number);
-               else
-                 ex.X_add_number = SEX16 (PPC_HI (ex.X_add_number));
+               if (REPORT_OVERFLOW_HI && ppc_obj64)
+                 {
+                   /* PowerPC64 @h is tested for overflow.  */
+                   ex.X_add_number = (addressT) ex.X_add_number >> 16;
+                   if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+                     {
+                       addressT sign = (((addressT) -1 >> 16) + 1) >> 1;
+                       ex.X_add_number
+                         = ((addressT) ex.X_add_number ^ sign) - sign;
+                     }
+                   break;
+                 }
+               /* Fall thru */
+
+             case BFD_RELOC_PPC64_ADDR16_HIGH:
+               ex.X_add_number = PPC_HI (ex.X_add_number);
+               if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+                 ex.X_add_number = SEX16 (ex.X_add_number);
                break;
 
              case BFD_RELOC_HI16_S:
-               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
-                 ex.X_add_number = PPC_HA (ex.X_add_number);
-               else
-                 ex.X_add_number = SEX16 (PPC_HA (ex.X_add_number));
+               if (REPORT_OVERFLOW_HI && ppc_obj64)
+                 {
+                   /* PowerPC64 @ha is tested for overflow.  */
+                   ex.X_add_number
+                     = ((addressT) ex.X_add_number + 0x8000) >> 16;
+                   if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+                     {
+                       addressT sign = (((addressT) -1 >> 16) + 1) >> 1;
+                       ex.X_add_number
+                         = ((addressT) ex.X_add_number ^ sign) - sign;
+                     }
+                   break;
+                 }
+               /* Fall thru */
+
+             case BFD_RELOC_PPC64_ADDR16_HIGHA:
+               ex.X_add_number = PPC_HA (ex.X_add_number);
+               if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+                 ex.X_add_number = SEX16 (ex.X_add_number);
                break;
 
              case BFD_RELOC_PPC64_HIGHER:
-               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
-                 ex.X_add_number = PPC_HIGHER (ex.X_add_number);
-               else
-                 ex.X_add_number = SEX16 (PPC_HIGHER (ex.X_add_number));
+               ex.X_add_number = PPC_HIGHER (ex.X_add_number);
+               if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+                 ex.X_add_number = SEX16 (ex.X_add_number);
                break;
 
              case BFD_RELOC_PPC64_HIGHER_S:
-               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
-                 ex.X_add_number = PPC_HIGHERA (ex.X_add_number);
-               else
-                 ex.X_add_number = SEX16 (PPC_HIGHERA (ex.X_add_number));
+               ex.X_add_number = PPC_HIGHERA (ex.X_add_number);
+               if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+                 ex.X_add_number = SEX16 (ex.X_add_number);
                break;
 
              case BFD_RELOC_PPC64_HIGHEST:
-               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
-                 ex.X_add_number = PPC_HIGHEST (ex.X_add_number);
-               else
-                 ex.X_add_number = SEX16 (PPC_HIGHEST (ex.X_add_number));
+               ex.X_add_number = PPC_HIGHEST (ex.X_add_number);
+               if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+                 ex.X_add_number = SEX16 (ex.X_add_number);
                break;
 
              case BFD_RELOC_PPC64_HIGHEST_S:
-               if (ex.X_unsigned && ! (operand->flags & PPC_OPERAND_SIGNED))
-                 ex.X_add_number = PPC_HIGHESTA (ex.X_add_number);
-               else
-                 ex.X_add_number = SEX16 (PPC_HIGHESTA (ex.X_add_number));
+               ex.X_add_number = PPC_HIGHESTA (ex.X_add_number);
+               if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+                 ex.X_add_number = SEX16 (ex.X_add_number);
                break;
              }
 #endif /* OBJ_ELF */
@@ -6390,25 +6421,51 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       fieldval = value & 0xffff;
     sign_extend_16:
       if (operand != NULL && (operand->flags & PPC_OPERAND_SIGNED) != 0)
-       fieldval = (fieldval ^ 0x8000) - 0x8000;
+       fieldval = SEX16 (fieldval);
       fixP->fx_no_overflow = 1;
       break;
 
+    case BFD_RELOC_HI16:
+    case BFD_RELOC_HI16_PCREL:
 #ifdef OBJ_ELF
+      if (REPORT_OVERFLOW_HI && ppc_obj64)
+       {
+         fieldval = value >> 16;
+         if (operand != NULL && (operand->flags & PPC_OPERAND_SIGNED) != 0)
+           {
+             valueT sign = (((valueT) -1 >> 16) + 1) >> 1;
+             fieldval = ((valueT) fieldval ^ sign) - sign;
+           }
+         break;
+       }
+      /* Fall thru */
+
     case BFD_RELOC_PPC_VLE_HI16A:
     case BFD_RELOC_PPC_VLE_HI16D:
+    case BFD_RELOC_PPC64_ADDR16_HIGH:
 #endif
-    case BFD_RELOC_HI16:
-    case BFD_RELOC_HI16_PCREL:
       fieldval = PPC_HI (value);
       goto sign_extend_16;
 
+    case BFD_RELOC_HI16_S:
+    case BFD_RELOC_HI16_S_PCREL:
 #ifdef OBJ_ELF
+      if (REPORT_OVERFLOW_HI && ppc_obj64)
+       {
+         fieldval = (value + 0x8000) >> 16;
+         if (operand != NULL && (operand->flags & PPC_OPERAND_SIGNED) != 0)
+           {
+             valueT sign = (((valueT) -1 >> 16) + 1) >> 1;
+             fieldval = ((valueT) fieldval ^ sign) - sign;
+           }
+         break;
+       }
+      /* Fall thru */
+
     case BFD_RELOC_PPC_VLE_HA16A:
     case BFD_RELOC_PPC_VLE_HA16D:
+    case BFD_RELOC_PPC64_ADDR16_HIGHA:
 #endif
-    case BFD_RELOC_HI16_S:
-    case BFD_RELOC_HI16_S_PCREL:
       fieldval = PPC_HA (value);
       goto sign_extend_16;
 
@@ -6471,10 +6528,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
        case BFD_RELOC_PPC_GOT_DTPREL16_HA:
        case BFD_RELOC_PPC64_TPREL16_DS:
        case BFD_RELOC_PPC64_TPREL16_LO_DS:
+       case BFD_RELOC_PPC64_TPREL16_HIGH:
+       case BFD_RELOC_PPC64_TPREL16_HIGHA:
        case BFD_RELOC_PPC64_TPREL16_HIGHER:
        case BFD_RELOC_PPC64_TPREL16_HIGHERA:
        case BFD_RELOC_PPC64_TPREL16_HIGHEST:
        case BFD_RELOC_PPC64_TPREL16_HIGHESTA:
+       case BFD_RELOC_PPC64_DTPREL16_HIGH:
+       case BFD_RELOC_PPC64_DTPREL16_HIGHA:
        case BFD_RELOC_PPC64_DTPREL16_DS:
        case BFD_RELOC_PPC64_DTPREL16_LO_DS:
        case BFD_RELOC_PPC64_DTPREL16_HIGHER:
@@ -6660,6 +6721,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
        case BFD_RELOC_PPC64_HIGHER_S:
        case BFD_RELOC_PPC64_HIGHEST:
        case BFD_RELOC_PPC64_HIGHEST_S:
+       case BFD_RELOC_PPC64_ADDR16_HIGH:
+       case BFD_RELOC_PPC64_ADDR16_HIGHA:
          break;
 
        case BFD_RELOC_PPC_DTPMOD:
@@ -6736,10 +6799,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
        case BFD_RELOC_PPC64_TOC16_LO:
        case BFD_RELOC_PPC64_TOC16_HI:
        case BFD_RELOC_PPC64_TOC16_HA:
+       case BFD_RELOC_PPC64_DTPREL16_HIGH:
+       case BFD_RELOC_PPC64_DTPREL16_HIGHA:
        case BFD_RELOC_PPC64_DTPREL16_HIGHER:
        case BFD_RELOC_PPC64_DTPREL16_HIGHERA:
        case BFD_RELOC_PPC64_DTPREL16_HIGHEST:
        case BFD_RELOC_PPC64_DTPREL16_HIGHESTA:
+       case BFD_RELOC_PPC64_TPREL16_HIGH:
+       case BFD_RELOC_PPC64_TPREL16_HIGHA:
        case BFD_RELOC_PPC64_TPREL16_HIGHER:
        case BFD_RELOC_PPC64_TPREL16_HIGHERA:
        case BFD_RELOC_PPC64_TPREL16_HIGHEST:
index 2d16bbc1609516dc5ae1f2ccd49fed73c72aec01..5607cb3eb9c4cedd896731871fab417d28e07ea0 100644 (file)
@@ -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.
index 880b367c44c343e1bff9ba380d24099f860e12e8..75fc604cf2736b679c1c6d84bd9688376b8d309f 100644 (file)
@@ -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:
index c2577e88990b75707ff35f9e42552b169a23a8bd..fae0bf89e4e6751df44b461b3fc0b7cc6dd3fee6 100644 (file)
@@ -1,3 +1,10 @@
+2013-10-30  Alan Modra  <amodra@gmail.com>
+
+       * 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.
+
 2013-10-14  Chao-ying Fu  <Chao-ying.Fu@imgtec.com>
 
        * mips.h (enum): Add Tag_GNU_MIPS_ABI_MSA.
index f1c80f18868758baebe880d4f0d17fd45a3c2e65..221786f1ac182b0585535c754f15bc51f005ebbe 100644 (file)
@@ -141,6 +141,14 @@ START_RELOC_NUMBERS (elf_ppc64_reloc_type)
   RELOC_NUMBER (R_PPC64_TLSLD,            108)
   RELOC_NUMBER (R_PPC64_TOCSAVE,          109)
 
+/* Added when HA and HI relocs were changed to report overflows.  */
+  RELOC_NUMBER (R_PPC64_ADDR16_HIGH,      110)
+  RELOC_NUMBER (R_PPC64_ADDR16_HIGHA,     111)
+  RELOC_NUMBER (R_PPC64_TPREL16_HIGH,     112)
+  RELOC_NUMBER (R_PPC64_TPREL16_HIGHA,    113)
+  RELOC_NUMBER (R_PPC64_DTPREL16_HIGH,    114)
+  RELOC_NUMBER (R_PPC64_DTPREL16_HIGHA,           115)
+
 #ifndef RELOC_MACROS_GEN_FUNC
 /* Fake relocation only used internally by ld.  */
   RELOC_NUMBER (R_PPC64_LO_DS_OPT,        128)
@@ -161,8 +169,9 @@ START_RELOC_NUMBERS (elf_ppc64_reloc_type)
 
 END_RELOC_NUMBERS (R_PPC64_max)
 
-#define IS_PPC64_TLS_RELOC(R) \
-  ((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA)
+#define IS_PPC64_TLS_RELOC(R)                                          \
+  (((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA)            \
+   || ((R) >= R_PPC64_TPREL16_HIGH && (R) <= R_PPC64_DTPREL16_HIGHA))
 
 /* Specify the start of the .glink section.  */
 #define DT_PPC64_GLINK         DT_LOPROC