aboutsummaryrefslogtreecommitdiff
path: root/bfd/elfxx-riscv.c
diff options
context:
space:
mode:
authorKuan-Lin Chen <rufus@andestech.com>2019-11-14 14:24:22 +0800
committerNelson Chu <nelson@rivosinc.com>2023-05-19 16:24:10 +0800
commitf1cd8b94e7c941c2a9107c1112ab2339916b8efd (patch)
tree158d8ac0400a52e839bd8fabfec6bd15a8a1bdfe /bfd/elfxx-riscv.c
parent26e91972538544a237897baa5c806a008d36a88c (diff)
downloadgdb-f1cd8b94e7c941c2a9107c1112ab2339916b8efd.zip
gdb-f1cd8b94e7c941c2a9107c1112ab2339916b8efd.tar.gz
gdb-f1cd8b94e7c941c2a9107c1112ab2339916b8efd.tar.bz2
RISC-V: Support subtraction of .uleb128.
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/commit/96d6e190e9fc04a8517f9ff7fb9aed3e9876cbd6 There are some known limitations for now, * Do not shrink the length of the uleb128 value, even if the value is reduced after relaxations. Also reports error if the length grows up. * The R_RISCV_SET_ULEB128 needs to be paired with and be placed before the R_RISCV_SUB_ULEB128. bfd/ * bfd-in2.h: Regenerated. * elfnn-riscv.c (perform_relocation): Perform R_RISCV_SUB_ULEB128 and R_RISCV_SET_ULEB128 relocations. Do not shrink the length of the uleb128 value, and report error if the length grows up. Called the generic functions, _bfd_read_unsigned_leb128 and _bfd_write_unsigned_leb128, to encode the uleb128 into the section contents. (riscv_elf_relocate_section): Make sure that the R_RISCV_SET_ULEB128 must be paired with and be placed before the R_RISCV_SUB_ULEB128. * elfxx-riscv.c (howto_table): Added R_RISCV_SUB_ULEB128 and R_RISCV_SET_ULEB128. (riscv_reloc_map): Likewise. (riscv_elf_ignore_reloc): New function. * libbfd.h: Regenerated. * reloc.c (BFD_RELOC_RISCV_SET_ULEB128, BFD_RELOC_RISCV_SUB_ULEB128): New relocations to support .uleb128 subtraction. gas/ * config/tc-riscv.c (md_apply_fix): Added BFD_RELOC_RISCV_SET_ULEB128 and BFD_RELOC_RISCV_SUB_ULEB128. (s_riscv_leb128): Updated to allow uleb128 subtraction. (riscv_insert_uleb128_fixes): New function, scan uleb128 subtraction expressions and insert fixups for them. (riscv_md_finish): Called riscv_insert_uleb128_fixes for all sections. include/ * elf/riscv.h ((R_RISCV_SET_ULEB128, (R_RISCV_SUB_ULEB128): Defined. ld/ * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated. * testsuite/ld-riscv-elf/uleb128*: New testcase for uleb128 subtraction. binutils/ * testsuite/binutils-all/nm.exp: Updated since RISCV supports .uleb128.
Diffstat (limited to 'bfd/elfxx-riscv.c')
-rw-r--r--bfd/elfxx-riscv.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index bd0c7c8..7f45324 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -38,6 +38,8 @@
relocations for the debug info. */
static bfd_reloc_status_type riscv_elf_add_sub_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type riscv_elf_ignore_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
/* The relocation table used for SHT_RELA sections. */
@@ -844,6 +846,39 @@ static reloc_howto_type howto_table[] =
0, /* src_mask */
0xffffffff, /* dst_mask */
false), /* pcrel_offset */
+
+ /* Reserved for R_RISCV_PLT32. */
+ EMPTY_HOWTO (59),
+
+ /* N-bit in-place setting, for unsigned-leb128 local label subtraction. */
+ HOWTO (R_RISCV_SET_ULEB128, /* type */
+ 0, /* rightshift */
+ 0, /* size */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ riscv_elf_ignore_reloc, /* special_function */
+ "R_RISCV_SET_ULEB128", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* N-bit in-place addition, for unsigned-leb128 local label subtraction. */
+ HOWTO (R_RISCV_SUB_ULEB128, /* type */
+ 0, /* rightshift */
+ 0, /* size */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ riscv_elf_ignore_reloc, /* special_function */
+ "R_RISCV_SUB_ULEB128", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
};
/* A mapping from BFD reloc types to RISC-V ELF reloc types. */
@@ -905,6 +940,8 @@ static const struct elf_reloc_map riscv_reloc_map[] =
{ BFD_RELOC_RISCV_SET16, R_RISCV_SET16 },
{ BFD_RELOC_RISCV_SET32, R_RISCV_SET32 },
{ BFD_RELOC_RISCV_32_PCREL, R_RISCV_32_PCREL },
+ { BFD_RELOC_RISCV_SET_ULEB128, R_RISCV_SET_ULEB128 },
+ { BFD_RELOC_RISCV_SUB_ULEB128, R_RISCV_SUB_ULEB128 },
};
/* Given a BFD reloc type, return a howto structure. */
@@ -1010,6 +1047,23 @@ riscv_elf_add_sub_reloc (bfd *abfd,
return bfd_reloc_ok;
}
+/* Special handler for relocations which don't have to be relocated.
+ This function just simply return bfd_reloc_ok. */
+
+static bfd_reloc_status_type
+riscv_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+}
+
/* Always add the IMPLICIT for the SUBSET. */
static bool