RISC-V: For PCREL_LO12, fix addend handling in auipc lookup.
authorJim Wilson <jimw@sifive.com>
Mon, 24 Sep 2018 21:36:41 +0000 (14:36 -0700)
committerJim Wilson <jimw@sifive.com>
Mon, 24 Sep 2018 21:36:41 +0000 (14:36 -0700)
bfd/
* elfnn-riscv.c (_bfd_riscv_relax_pc) <R_RISCV_PCREL_LO12_I>: New local
hi_sec_off which is symbol address with addend subtracted.  Use in
riscv_find_pcgp_hi_reloc and riscv_record_pcgp_lo_reloc calls.

bfd/ChangeLog
bfd/elfnn-riscv.c

index d14cca0ab76046044dcf189d425dcc072ae1d36f..e8e31952caf2490fd9181df08eaa3e28468b0634 100644 (file)
@@ -1,5 +1,9 @@
 2018-09-24  Jim Wilson  <jimw@sifive.com>
 
+       * elfnn-riscv.c (_bfd_riscv_relax_pc) <R_RISCV_PCREL_LO12_I>: New local
+       hi_sec_off which is symbol address with addend subtracted.  Use in
+       riscv_find_pcgp_hi_reloc and riscv_record_pcgp_lo_reloc calls.
+
        * elfnn-riscv.c (riscv_resolve_pcrel_lo_relocs): Add check for reloc
        overflow with addend.  Use reloc_dangerous instead of reloc_overflow.
        Add strings for the two errors handled here.
index 63ff07e13ac96d805979946be0f78f74b8d94869..f3e2cc7c3771ed908640a7ae9847bad9e8f18bf8 100644 (file)
@@ -3226,11 +3226,16 @@ _bfd_riscv_relax_pc  (bfd *abfd,
     case R_RISCV_PCREL_LO12_I:
     case R_RISCV_PCREL_LO12_S:
       {
+       /* If the %lo has an addend, it isn't for the label pointing at the
+          hi part instruction, but rather for the symbol pointed at by the
+          hi part instruction.  So we must subtract it here for the lookup.
+          It is still used below in the final symbol address.  */
+       bfd_vma hi_sec_off = symval - sec_addr (sym_sec) - rel->r_addend;
        riscv_pcgp_hi_reloc *hi = riscv_find_pcgp_hi_reloc (pcgp_relocs,
-                                                           symval - sec_addr(sym_sec));
+                                                           hi_sec_off);
        if (hi == NULL)
          {
-           riscv_record_pcgp_lo_reloc (pcgp_relocs, symval - sec_addr(sym_sec));
+           riscv_record_pcgp_lo_reloc (pcgp_relocs, hi_sec_off);
            return TRUE;
          }