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: Add special_function for ADD and SUB relocations


From: Kuan-Lin Chen <rufus@andestech.com>

This function allows these relocations to be filled out both in the
pre-linked and post-linked file.  This is necessary to make pre-linked
debug info work, as due to linker relaxations we need to emit
relocations for the debug info.

bfd/ChangeLog

2017-07-06  Kuan-Lin Chen  <rufus@andestech.com>

        * elfxx-riscv.c (riscv_elf_add_sub_reloc): New function.
        * (howto_table) [R_RISCV_ADD8]: Use riscv_elf_add_sub_reloc.
        [R_RISCV_ADD16]: Likewise.
        [R_RISCV_ADD32]: Likewise.
        [R_RISCV_ADD64]: Likewise.
        [R_RISCV_SUB6]: Likewise.
        [R_RISCV_SUB8]: Likewise.
        [R_RISCV_SUB16]: Likewise.
        [R_RISCV_SUB32]: Likewise.
        [R_RISCV_SUB64]: Likewise.
---
 bfd/elfxx-riscv.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 63 insertions(+), 9 deletions(-)

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 5fa98f37e9..3a0c069d96 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -32,6 +32,13 @@
 
 #define MINUS_ONE ((bfd_vma)0 - 1)
 
+/* Special handler for ADD/SUB relocations that allows them to be filled out
+ * both in the pre-linked and post-linked file.  This is necessary to make
+ * pre-linked debug info work, as due to linker relaxations we need to emit
+ * relocations for the debug info. */
+static bfd_reloc_status_type riscv_elf_add_sub_reloc
+(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
 /* The relocation table used for SHT_RELA sections.  */
 
 static reloc_howto_type howto_table[] =
@@ -480,7 +487,7 @@ static reloc_howto_type howto_table[] =
 	 FALSE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-	 bfd_elf_generic_reloc,		/* special_function */
+	 riscv_elf_add_sub_reloc,	/* special_function */
 	 "R_RISCV_ADD8",		/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
@@ -495,7 +502,7 @@ static reloc_howto_type howto_table[] =
 	 FALSE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-	 bfd_elf_generic_reloc,		/* special_function */
+	 riscv_elf_add_sub_reloc,	/* special_function */
 	 "R_RISCV_ADD16",		/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
@@ -510,7 +517,7 @@ static reloc_howto_type howto_table[] =
 	 FALSE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-	 bfd_elf_generic_reloc,		/* special_function */
+	 riscv_elf_add_sub_reloc,	/* special_function */
 	 "R_RISCV_ADD32",		/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
@@ -525,7 +532,7 @@ static reloc_howto_type howto_table[] =
 	 FALSE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-	 bfd_elf_generic_reloc,		/* special_function */
+	 riscv_elf_add_sub_reloc,	/* special_function */
 	 "R_RISCV_ADD64",		/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
@@ -540,7 +547,7 @@ static reloc_howto_type howto_table[] =
 	 FALSE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-	 bfd_elf_generic_reloc,		/* special_function */
+	 riscv_elf_add_sub_reloc,	/* special_function */
 	 "R_RISCV_SUB8",		/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
@@ -555,7 +562,7 @@ static reloc_howto_type howto_table[] =
 	 FALSE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-	 bfd_elf_generic_reloc,		/* special_function */
+	 riscv_elf_add_sub_reloc,	/* special_function */
 	 "R_RISCV_SUB16",		/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
@@ -570,7 +577,7 @@ static reloc_howto_type howto_table[] =
 	 FALSE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-	 bfd_elf_generic_reloc,		/* special_function */
+	 riscv_elf_add_sub_reloc,	/* special_function */
 	 "R_RISCV_SUB32",		/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
@@ -585,7 +592,7 @@ static reloc_howto_type howto_table[] =
 	 FALSE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-	 bfd_elf_generic_reloc,		/* special_function */
+	 riscv_elf_add_sub_reloc,	/* special_function */
 	 "R_RISCV_SUB64",		/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
@@ -767,7 +774,7 @@ static reloc_howto_type howto_table[] =
 	 FALSE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-	 bfd_elf_generic_reloc,		/* special_function */
+	 riscv_elf_add_sub_reloc,	/* special_function */
 	 "R_RISCV_SUB6",		/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
@@ -951,3 +958,50 @@ riscv_elf_rtype_to_howto (unsigned int r_type)
     }
   return &howto_table[r_type];
 }
+
+/* special_function of RISCV_ADD and RISCV_SUB relocations.  */
+static bfd_reloc_status_type
+riscv_elf_add_sub_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+			 void *data, asection *input_section,
+			 bfd *output_bfd,
+			 char **error_message ATTRIBUTE_UNUSED)
+{
+  reloc_howto_type *howto = reloc_entry->howto;
+  bfd_vma relocation;
+
+  if (output_bfd != NULL
+      && (symbol->flags & BSF_SECTION_SYM) == 0
+      && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
+    {
+      reloc_entry->address += input_section->output_offset;
+      return bfd_reloc_ok;
+    }
+
+  if (output_bfd != NULL)
+    return bfd_reloc_continue;
+
+  relocation = symbol->value + symbol->section->output_section->vma
+    + symbol->section->output_offset + reloc_entry->addend;
+  bfd_vma old_value = bfd_get (howto->bitsize, abfd,
+			       data + reloc_entry->address);
+
+  switch (howto->type)
+    {
+    case R_RISCV_ADD8:
+    case R_RISCV_ADD16:
+    case R_RISCV_ADD32:
+    case R_RISCV_ADD64:
+      relocation = old_value + relocation;
+      break;
+    case R_RISCV_SUB6:
+    case R_RISCV_SUB8:
+    case R_RISCV_SUB16:
+    case R_RISCV_SUB32:
+    case R_RISCV_SUB64:
+      relocation = old_value - relocation;
+      break;
+    }
+  bfd_put (howto->bitsize, abfd, relocation, data + reloc_entry->address);
+
+  return bfd_reloc_ok;
+}
-- 
2.13.0


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