This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] RISC-V: Use pc-relative relocation for FDE initial location


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]