diff options
author | Kuan-Lin Chen <rufus@andestech.com> | 2019-11-14 14:24:22 +0800 |
---|---|---|
committer | Nelson Chu <nelson@rivosinc.com> | 2023-05-19 16:24:10 +0800 |
commit | f1cd8b94e7c941c2a9107c1112ab2339916b8efd (patch) | |
tree | 158d8ac0400a52e839bd8fabfec6bd15a8a1bdfe /bfd/elfxx-riscv.c | |
parent | 26e91972538544a237897baa5c806a008d36a88c (diff) | |
download | gdb-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.c | 54 |
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 |