This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] RISC-V: Add special_function for ADD and SUB relocations
- From: Palmer Dabbelt <palmer at dabbelt dot com>
- To: binutils at sourceware dot org
- Cc: patches at groups dot riscv dot org, Kuan-Lin Chen <rufus at andestech dot com>
- Date: Wed, 26 Jul 2017 20:02:41 -0700
- Subject: [PATCH] RISC-V: Add special_function for ADD and SUB relocations
- Authentication-results: sourceware.org; auth=none
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