diff options
author | Nelson Chu <nelson.chu@sifive.com> | 2021-08-11 01:26:39 -0700 |
---|---|---|
committer | Nelson Chu <nelson.chu@sifive.com> | 2021-11-19 09:32:19 +0800 |
commit | 8155b8539b55bca87378129e02009cd8907d8c8c (patch) | |
tree | 30524e98925e912c02387ae7b2bd0c58b9bb6ff4 /bfd | |
parent | fccf4ba5adaf69cac1875a194d8ee99dabf50c70 (diff) | |
download | gdb-8155b8539b55bca87378129e02009cd8907d8c8c.zip gdb-8155b8539b55bca87378129e02009cd8907d8c8c.tar.gz gdb-8155b8539b55bca87378129e02009cd8907d8c8c.tar.bz2 |
RISC-V: Support STO_RISCV_VARIANT_CC and DT_RISCV_VARIANT_CC.
This is the original discussion,
https://github.com/riscv/riscv-elf-psabi-doc/pull/190
And here is the glibc part,
https://sourceware.org/pipermail/libc-alpha/2021-August/129931.html
For binutils part, we need to support a new direcitve: .variant_cc.
The function symbol marked by .variant_cc means it need to be resolved
directly without resolver for dynamic linker. We also add a new dynamic
entry, STO_RISCV_VARIANT_CC, to indicate there are symbols with the
special attribute in the dynamic symbol table of the object.
I heard that llvm already have supported this in their mainline, so
I think it's time to commit this.
bfd/
* elfnn-riscv.c (riscv_elf_link_hash_table): Added variant_cc
flag. It is used to check if relocations for variant CC symbols
may be present.
(allocate_dynrelocs): If the symbol has STO_RISCV_VARIANT_CC
flag, then raise the variant_cc flag of riscv_elf_link_hash_table.
(riscv_elf_size_dynamic_sections): Added dynamic entry for
variant_cc.
(riscv_elf_merge_symbol_attribute): New function, used to merge
non-visibility st_other attributes, including STO_RISCV_VARIANT_CC.
binutils/
* readelf.c (get_riscv_dynamic_type): New function.
(get_dynamic_type): Called get_riscv_dynamic_type for riscv targets.
(get_riscv_symbol_other): New function.
(get_symbol_other): Called get_riscv_symbol_other for riscv targets.
gas/
* config/tc-riscv.c (s_variant_cc): Marked symbol that it follows a
variant CC convention.
(riscv_elf_copy_symbol_attributes): Same as elf_copy_symbol_attributes,
but without copying st_other. If a function symbol has special st_other
value set via directives, then attaching an IFUNC resolver to that symbol
should not override the st_other setting.
(riscv_pseudo_table): Support variant_cc diretive.
* config/tc-riscv.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Defined.
* testsuite/gas/riscv/variant_cc-set.d: New testcase.
* testsuite/gas/riscv/variant_cc-set.s: Likewise.
* testsuite/gas/riscv/variant_cc.d: Likewise.
* testsuite/gas/riscv/variant_cc.s: Likewise.
include/
* elf/riscv.h (DT_RISCV_VARIANT_CC): Defined to (DT_LOPROC + 1).
(STO_RISCV_VARIANT_CC): Defined to 0x80.
ld/
* testsuite/ld-riscv-elf/variant_cc-1.s: New testcase.
* testsuite/ld-riscv-elf/variant_cc-2.s: Likewise.
* testsuite/ld-riscv-elf/variant_cc-now.d: Likewise.
* testsuite/ld-riscv-elf/variant_cc-r.d: Likewise.
* testsuite/ld-riscv-elf/variant_cc-shared.d: Likewise.
* testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/elfnn-riscv.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 36cbf1e..d8c9066 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -134,6 +134,9 @@ struct riscv_elf_link_hash_table /* The data segment phase, don't relax the section when it is exp_seg_relro_adjust. */ int *data_segment_phase; + + /* Relocations for variant CC symbols may be present. */ + int variant_cc; }; /* Instruction access functions. */ @@ -1172,6 +1175,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) h->root.u.def.section = s; h->root.u.def.value = h->plt.offset; } + + /* If the symbol has STO_RISCV_VARIANT_CC flag, then raise the + variant_cc flag of riscv_elf_link_hash_table. */ + if (h->other & STO_RISCV_VARIANT_CC) + htab->variant_cc = 1; } else { @@ -1555,7 +1563,18 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) return false; } - return _bfd_elf_add_dynamic_tags (output_bfd, info, true); + /* Add dynamic entries. */ + if (elf_hash_table (info)->dynamic_sections_created) + { + if (!_bfd_elf_add_dynamic_tags (output_bfd, info, true)) + return false; + + if (htab->variant_cc + && !_bfd_elf_add_dynamic_entry (info, DT_RISCV_VARIANT_CC, 0)) + return false; + } + + return true; } #define TP_OFFSET 0 @@ -5227,6 +5246,28 @@ riscv_elf_modify_segment_map (bfd *abfd, return true; } +/* Merge non-visibility st_other attributes. */ + +static void +riscv_elf_merge_symbol_attribute (struct elf_link_hash_entry *h, + unsigned int st_other, + bool definition ATTRIBUTE_UNUSED, + bool dynamic ATTRIBUTE_UNUSED) +{ + unsigned int isym_sto = st_other & ~ELF_ST_VISIBILITY (-1); + unsigned int h_sto = h->other & ~ELF_ST_VISIBILITY (-1); + + if (isym_sto == h_sto) + return; + + if (isym_sto & ~STO_RISCV_VARIANT_CC) + _bfd_error_handler (_("unknown attribute for symbol `%s': 0x%02x"), + h->root.root.string, isym_sto); + + if (isym_sto & STO_RISCV_VARIANT_CC) + h->other |= STO_RISCV_VARIANT_CC; +} + #define TARGET_LITTLE_SYM riscv_elfNN_vec #define TARGET_LITTLE_NAME "elfNN-littleriscv" #define TARGET_BIG_SYM riscv_elfNN_be_vec @@ -5263,6 +5304,7 @@ riscv_elf_modify_segment_map (bfd *abfd, #define elf_backend_additional_program_headers \ riscv_elf_additional_program_headers #define elf_backend_modify_segment_map riscv_elf_modify_segment_map +#define elf_backend_merge_symbol_attribute riscv_elf_merge_symbol_attribute #define elf_backend_init_index_section _bfd_elf_init_1_index_section |