RISC-V: Use pc-relative relocation for FDE initial location
authorKuan-Lin Chen <rufus@andestech.com>
Thu, 8 Jun 2017 18:54:14 +0000 (11:54 -0700)
committerPalmer Dabbelt <palmer@dabbelt.com>
Tue, 27 Jun 2017 01:26:40 +0000 (18:26 -0700)
The symbol address in .eh_frame may be adjusted in
_bfd_elf_discard_section_eh_frame, and the content of .eh_frame will be
adjusted in _bfd_elf_write_section_eh_frame. Therefore, we cannot insert
a relocation whose addend symbol is in .eh_frame. Othrewise, the value
may be adjusted twice.

bfd/ChangeLog
2017-06-26  Kuan-Lin Chen  <rufus@andestech.com>

* elfnn-riscv.c (perform_relocation): Support the new
R_RISCV_32_PCREL relocation.
(riscv_elf_relocate_section): Likewise.
* elfxx-riscv.c (howto_table): Likewise.
(riscv_reloc_map): Likewise.
* bfd-in2.h (BFD_RELOC_RISCV_32_PCREL): New relocation.
* libbfd.h: Regenerate.

gas/ChangeLog
2017-06-26  Kuan-Lin Chen  <rufus@andestech.com>

* config/tc-riscv.c (md_apply_fix) [BFD_RELOC_32]: Convert to a
R_RISCV_32_PCREL relocation.

include/ChangeLog
2017-06-26  Kuan-Lin Chen  <rufus@andestech.com>

* elf/riscv.h (R_RISCV_32_PCREL): New.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/elfnn-riscv.c
bfd/elfxx-riscv.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-riscv.c
include/ChangeLog
include/elf/riscv.h

index f440f8f57253176ea49751793c926454ab383f1b..3cab920a60a8460539c1f36592b6134e3c421922 100644 (file)
@@ -1,3 +1,13 @@
+2017-06-26  Kuan-Lin Chen  <rufus@andestech.com>
+
+       * elfnn-riscv.c (perform_relocation): Support the new
+       R_RISCV_32_PCREL relocation.
+       (riscv_elf_relocate_section): Likewise.
+       * elfxx-riscv.c (howto_table): Likewise.
+       (riscv_reloc_map): Likewise.
+       * bfd-in2.h (BFD_RELOC_RISCV_32_PCREL): New relocation.
+       * libbfd.h: Regenerate.
+
 2017-06-27  Alan Modra  <amodra@gmail.com>
 
        PR binutils/21665
index 45f665b57fcbc3d381a112a83cf88bdb007a3b97..8c312e3f9efed14ed7948623ebf9756d9685f8f8 100644 (file)
@@ -4771,6 +4771,7 @@ number for the SBIC, SBIS, SBI and CBI instructions  */
   BFD_RELOC_RISCV_SET8,
   BFD_RELOC_RISCV_SET16,
   BFD_RELOC_RISCV_SET32,
+  BFD_RELOC_RISCV_32_PCREL,
 
 /* Renesas RL78 Relocations.  */
   BFD_RELOC_RL78_NEG8,
index 4e3cf552b1a9323c4eb26f962272898f664a03ba..455f2ff2922e2ebca58c2129d31b38a06e4655eb 100644 (file)
@@ -1566,6 +1566,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_SET8:
     case R_RISCV_SET16:
     case R_RISCV_SET32:
+    case R_RISCV_32_PCREL:
     case R_RISCV_TLS_DTPREL32:
     case R_RISCV_TLS_DTPREL64:
       break;
@@ -1849,6 +1850,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
        case R_RISCV_SET8:
        case R_RISCV_SET16:
        case R_RISCV_SET32:
+       case R_RISCV_32_PCREL:
          /* These require no special handling beyond perform_relocation.  */
          break;
 
index 6936722f9d5c6b76c916db3a7749bf2d810f1fce..5fa98f37e98e28ad1fbfb22b697a52dcdcd13a80 100644 (file)
@@ -833,6 +833,21 @@ static reloc_howto_type howto_table[] =
         0,                             /* src_mask */
         MINUS_ONE,                     /* dst_mask */
         FALSE),                        /* pcrel_offset */
+
+  /* 32-bit PC relative.  */
+  HOWTO (R_RISCV_32_PCREL,             /* type */
+        0,                             /* rightshift */
+        2,                             /* size */
+        32,                            /* bitsize */
+        TRUE,                          /* pc_relative */
+        0,                             /* bitpos */
+        complain_overflow_dont,        /* complain_on_overflow */
+        bfd_elf_generic_reloc,         /* special_function */
+        "R_RISCV_32_PCREL",            /* name */
+        FALSE,                         /* partial_inplace */
+        0,                             /* src_mask */
+        MINUS_ONE,                     /* dst_mask */
+        FALSE),                        /* pcrel_offset */
 };
 
 /* A mapping from BFD reloc types to RISC-V ELF reloc types.  */
@@ -894,6 +909,7 @@ static const struct elf_reloc_map riscv_reloc_map[] =
   { BFD_RELOC_RISCV_SET8, R_RISCV_SET8 },
   { BFD_RELOC_RISCV_SET16, R_RISCV_SET16 },
   { BFD_RELOC_RISCV_SET32, R_RISCV_SET32 },
+  { BFD_RELOC_RISCV_32_PCREL, R_RISCV_32_PCREL },
 };
 
 /* Given a BFD reloc type, return a howto structure.  */
index 09df3b2e0507491fcb4357d632d07c6c89bfd571..ae9bf7681445383d06d71f9652ebedaa29672c32 100644 (file)
@@ -2215,6 +2215,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_RISCV_SET8",
   "BFD_RELOC_RISCV_SET16",
   "BFD_RELOC_RISCV_SET32",
+  "BFD_RELOC_RISCV_32_PCREL",
   "BFD_RELOC_RL78_NEG8",
   "BFD_RELOC_RL78_NEG16",
   "BFD_RELOC_RL78_NEG24",
index 024056f11816f7f6c504dff281fbdd7395bdbde6..aa70fa5874044ab3b9b3374a9ea2309ef6425f8d 100644 (file)
@@ -5155,6 +5155,8 @@ ENUMX
   BFD_RELOC_RISCV_SET16
 ENUMX
   BFD_RELOC_RISCV_SET32
+ENUMX
+  BFD_RELOC_RISCV_32_PCREL
 ENUMDOC
   RISC-V relocations.
 
index 6d3281d4f2a8479a63785594d11cf4976fbdff9e..a4b99155fba5f9c9a80b3418705ddb37a6061b9a 100644 (file)
@@ -1,3 +1,8 @@
+2017-06-26  Kuan-Lin Chen  <rufus@andestech.com>
+
+       * config/tc-riscv.c (md_apply_fix) [BFD_RELOC_32]: Convert to a
+       R_RISCV_32_PCREL relocation.
+
 2017-06-26  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR gas/21661
index afda6c51248b9d1dc53d319e47875a1c13c38e65..55c41c5db3c9240e8da3cdf8906cfb745d041c6f 100644 (file)
@@ -1871,6 +1871,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
   bfd_boolean relaxable = FALSE;
   offsetT loc;
+  segT sub_segment;
 
   /* Remember value for tc_gen_reloc.  */
   fixP->fx_addnumber = *valP;
@@ -1919,8 +1920,25 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
                      _("TLS relocation against a constant"));
       break;
 
-    case BFD_RELOC_64:
     case BFD_RELOC_32:
+      /* Use pc-relative relocation for FDE initial location.
+        The symbol address in .eh_frame may be adjusted in
+        _bfd_elf_discard_section_eh_frame, and the content of
+        .eh_frame will be adjusted in _bfd_elf_write_section_eh_frame.
+        Therefore, we cannot insert a relocation whose addend symbol is
+        in .eh_frame. Othrewise, the value may be adjusted twice.*/
+      if (fixP->fx_addsy && fixP->fx_subsy
+         && (sub_segment = S_GET_SEGMENT (fixP->fx_subsy))
+         && strcmp (sub_segment->name, ".eh_frame") == 0
+         && S_GET_VALUE (fixP->fx_subsy)
+            == fixP->fx_frag->fr_address + fixP->fx_where)
+       {
+         fixP->fx_r_type = BFD_RELOC_RISCV_32_PCREL;
+         fixP->fx_subsy = NULL;
+         break;
+       }
+      /* Fall through.  */
+    case BFD_RELOC_64:
     case BFD_RELOC_16:
     case BFD_RELOC_8:
     case BFD_RELOC_RISCV_CFA:
index 91cb91fb861d7b96318386bc098476b70656181d..243c7303cd6eef886aa57bf1bd0c6e65f5967423 100644 (file)
@@ -1,3 +1,7 @@
+2017-06-26  Kuan-Lin Chen  <rufus@andestech.com>
+
+       * elf/riscv.h (R_RISCV_32_PCREL): New.
+
 2017-06-24  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        * elf/arm.h (TAG_CPU_ARCH_V8R): New macro.
index daa44639263c17a2202aa01dbba6115b0d4040be..eecacf89c7e6d7777b4e2b5eea22b74803822777 100644 (file)
@@ -87,6 +87,7 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
   RELOC_NUMBER (R_RISCV_SET8, 54)
   RELOC_NUMBER (R_RISCV_SET16, 55)
   RELOC_NUMBER (R_RISCV_SET32, 56)
+  RELOC_NUMBER (R_RISCV_32_PCREL, 57)
 END_RELOC_NUMBERS (R_RISCV_max)
 
 /* Processor specific flags for the ELF header e_flags field.  */