This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] RISC-V: Use pc-relative relocation for FDE initial location
- From: Palmer Dabbelt <palmer at dabbelt dot com>
- To: binutils at sourceware dot org
- Cc: patches at groups dot riscv dot org
- Cc: Kuan-Lin Chen <rufus at andestech dot com>
- Date: Thu, 22 Jun 2017 18:54:04 -0700
- Subject: [PATCH] RISC-V: Use pc-relative relocation for FDE initial location
- Authentication-results: sourceware.org; auth=none
From: Kuan-Lin Chen <rufus@andestech.com>
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-08 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-08 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-08 Kuan-Lin Chen <rufus@andestech.com>
* elf/riscv.h (R_RISCV_32_PCREL): New.
---
bfd/ChangeLog | 10 ++++++++++
bfd/bfd-in2.h | 1 +
bfd/elfnn-riscv.c | 2 ++
bfd/elfxx-riscv.c | 16 ++++++++++++++++
bfd/libbfd.h | 1 +
bfd/reloc.c | 2 ++
gas/ChangeLog | 5 +++++
gas/config/tc-riscv.c | 20 +++++++++++++++++++-
include/ChangeLog | 4 ++++
include/elf/riscv.h | 1 +
10 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 4d2acc5fc9..e3f4bfc7ea 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,13 @@
+2017-06-08 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-22 H.J. Lu <hongjiu.lu@intel.com>
* elf64-x86-64.c (elf_x86_64_link_setup_gnu_properties): Move
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 434879355b..2b68b57481 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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,
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 4e3cf552b1..455f2ff292 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -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;
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 6936722f9d..5fa98f37e9 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -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. */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 09df3b2e05..ae9bf76814 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -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",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index ee01d88833..685ff41e16 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -5155,6 +5155,8 @@ ENUMX
BFD_RELOC_RISCV_SET16
ENUMX
BFD_RELOC_RISCV_SET32
+ENUMX
+ BFD_RELOC_RISCV_32_PCREL
ENUMDOC
RISC-V relocations.
diff --git a/gas/ChangeLog b/gas/ChangeLog
index e5130e73cc..5dce7597c3 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2017-06-08 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-05-11 Andrew Waterman <andrew@sifive.com>
* config/tc-riscv.c (riscv_ip): Changes as_warn to as_bad for improper
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index afda6c5124..55c41c5db3 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -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:
diff --git a/include/ChangeLog b/include/ChangeLog
index d8730deab1..1a8a3fcc71 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2017-06-08 Kuan-Lin Chen <rufus@andestech.com>
+
+ * elf/riscv.h (R_RISCV_32_PCREL): New.
+
2017-06-22 H.J. Lu <hongjiu.lu@intel.com>
* bfdlink.h (bfd_link_info): Add shstk.
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index daa4463926..eecacf89c7 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -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. */
--
2.13.0