From: Kito Cheng Date: Tue, 29 Jun 2021 06:36:35 +0000 (+0800) Subject: RISC-V: Add PT_RISCV_ATTRIBUTES and add it to PHDR. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fbc95f1e11facf233e89a9c2b4dde06b9aaf4b86;p=binutils-gdb.git RISC-V: Add PT_RISCV_ATTRIBUTES and add it to PHDR. We added PT_RISCV_ATTRIBUTES to program header to make .riscv.attribute easier to find in dynamic loader or kernel. Ref: https://github.com/riscv/riscv-elf-psabi-doc/pull/71 ChangeLog: bfd/ * elfnn-riscv.c(RISCV_ATTRIBUTES_SECTION_NAME): New. (riscv_elf_additional_program_headers): Ditto. (riscv_elf_modify_segment_map): Ditto. (elf_backend_additional_program_headers): Ditto. (elf_backend_modify_segment_map): Ditto. (elf_backend_obj_attrs_section): Use RISCV_ATTRIBUTES_SECTION_NAME rather than string literal. binutils/ * readelf.c(get_riscv_segment_type): New. (get_segment_type): Handle EM_RISCV. include/ * elf/riscv.h (PT_RISCV_ATTRIBUTES): New. * testsuite/ld-elf/orphan-region.ld: Discard .riscv.attributes section for simplify testcase. * testsuite/ld-riscv-elf/attr-phdr.d: New. * testsuite/ld-riscv-elf/attr-phdr.s: Ditto. * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Add attr-phdr to testcase. --- diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index f206708a9f3..4db3ca4e4b9 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -62,6 +62,8 @@ #define ELF_MAXPAGESIZE 0x1000 #define ELF_COMMONPAGESIZE 0x1000 +#define RISCV_ATTRIBUTES_SECTION_NAME ".riscv.attributes" + /* RISC-V ELF linker hash entry. */ struct riscv_elf_link_hash_entry @@ -5158,6 +5160,64 @@ riscv_elf_is_target_special_symbol (bfd *abfd, asymbol *sym) || _bfd_elf_is_local_label_name (abfd, sym->name)); } +static int +riscv_elf_additional_program_headers (bfd *abfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED) +{ + asection *s; + int ret = 0; + + /* See if we need a PT_RISCV_ATTRIBUTES segment. */ + if (bfd_get_section_by_name (abfd, RISCV_ATTRIBUTES_SECTION_NAME)) + ++ret; + + return ret; +} + +static bool +riscv_elf_modify_segment_map (bfd *abfd, + struct bfd_link_info *info) +{ + asection *s; + struct elf_segment_map *m, **pm; + size_t amt; + + /* If there is a .riscv.attributes section, we need a PT_RISCV_ATTRIBUTES + segment. */ + s = bfd_get_section_by_name (abfd, RISCV_ATTRIBUTES_SECTION_NAME); + if (s != NULL) + { + for (m = elf_seg_map (abfd); m != NULL; m = m->next) + if (m->p_type == PT_RISCV_ATTRIBUTES) + break; + /* If there is already a PT_RISCV_ATTRIBUTES header, avoid adding + another. */ + if (m == NULL) + { + amt = sizeof (*m); + m = bfd_zalloc (abfd, amt); + if (m == NULL) + return false; + + m->p_type = PT_RISCV_ATTRIBUTES; + m->count = 1; + m->sections[0] = s; + + /* We want to put it after the PHDR and INTERP segments. */ + pm = &elf_seg_map (abfd); + while (*pm != NULL + && ((*pm)->p_type == PT_PHDR + || (*pm)->p_type == PT_INTERP)) + pm = &(*pm)->next; + + m->next = *pm; + *pm = m; + } + } + + return true; +} + #define TARGET_LITTLE_SYM riscv_elfNN_vec #define TARGET_LITTLE_NAME "elfNN-littleriscv" #define TARGET_BIG_SYM riscv_elfNN_be_vec @@ -5190,6 +5250,9 @@ riscv_elf_is_target_special_symbol (bfd *abfd, asymbol *sym) #define elf_info_to_howto riscv_info_to_howto_rela #define bfd_elfNN_bfd_relax_section _bfd_riscv_relax_section #define bfd_elfNN_mkobject elfNN_riscv_mkobject +#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_init_index_section _bfd_elf_init_1_index_section @@ -5211,6 +5274,6 @@ riscv_elf_is_target_special_symbol (bfd *abfd, asymbol *sym) #undef elf_backend_obj_attrs_section_type #define elf_backend_obj_attrs_section_type SHT_RISCV_ATTRIBUTES #undef elf_backend_obj_attrs_section -#define elf_backend_obj_attrs_section ".riscv.attributes" +#define elf_backend_obj_attrs_section RISCV_ATTRIBUTES_SECTION_NAME #include "elfNN-target.h" diff --git a/binutils/readelf.c b/binutils/readelf.c index a6073f7ec80..22153394800 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -4094,6 +4094,16 @@ get_tic6x_segment_type (unsigned long type) } } +static const char * +get_riscv_segment_type (unsigned long type) +{ + switch (type) + { + case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES"; + default: return NULL; + } +} + static const char * get_hpux_segment_type (unsigned long type, unsigned e_machine) { @@ -4203,6 +4213,9 @@ get_segment_type (Filedata * filedata, unsigned long p_type) case EM_S390_OLD: result = get_s390_segment_type (p_type); break; + case EM_RISCV: + result = get_riscv_segment_type (p_type); + break; default: result = NULL; break; diff --git a/include/elf/riscv.h b/include/elf/riscv.h index fb376a096ab..80822835cd9 100644 --- a/include/elf/riscv.h +++ b/include/elf/riscv.h @@ -120,6 +120,11 @@ END_RELOC_NUMBERS (R_RISCV_max) /* Additional section types. */ #define SHT_RISCV_ATTRIBUTES 0x70000003 /* Section holds attributes. */ +/* Processor specific program header types. */ + +/* Location of RISC-V ELF attribute section. */ +#define PT_RISCV_ATTRIBUTES 0x70000003 + /* Object attributes. */ enum { diff --git a/ld/testsuite/ld-elf/orphan-region.ld b/ld/testsuite/ld-elf/orphan-region.ld index 2abf8bcb02a..71834df647a 100644 --- a/ld/testsuite/ld-elf/orphan-region.ld +++ b/ld/testsuite/ld-elf/orphan-region.ld @@ -7,5 +7,5 @@ SECTIONS { .text : ALIGN (4) { *(.text) } > region .rodata : ALIGN (4) { *(.rodata) } > region - /DISCARD/ : { *(.reginfo) *(.MIPS.abiflags) *(.trampolines) } + /DISCARD/ : { *(.reginfo) *(.MIPS.abiflags) *(.trampolines) *(.riscv.attributes) } } diff --git a/ld/testsuite/ld-riscv-elf/attr-phdr.d b/ld/testsuite/ld-riscv-elf/attr-phdr.d new file mode 100644 index 00000000000..43f2ea5077c --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/attr-phdr.d @@ -0,0 +1,19 @@ +#name: PT_RISCV_ATTRIBUTES check +#source: attr-phdr.s +#as: -march=rv32ic +#ld: -m[riscv_choose_ilp32_emul] +#readelf: -l + +Elf file type is EXEC \(Executable file\) +Entry point .* +There are .* program headers, starting at offset .* + +Program Headers: + Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align + RISCV_ATTRIBUT .* + LOAD .* + + Section to Segment mapping: + Segment Sections... + 00 .riscv.attributes + 01 .text diff --git a/ld/testsuite/ld-riscv-elf/attr-phdr.s b/ld/testsuite/ld-riscv-elf/attr-phdr.s new file mode 100644 index 00000000000..f075248ccfd --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/attr-phdr.s @@ -0,0 +1,9 @@ + .attribute arch, "rv32i2p0_m2p0" + .option nopic + .text + .align 1 + .globl _start + .type _start, @function +_start: + ret + .size _start, .-_start diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index 1f1245af707..1f6eceb3ae8 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -112,6 +112,7 @@ if [istarget "riscv*-*-*"] { run_dump_test "attr-merge-priv-spec-failed-04" run_dump_test "attr-merge-priv-spec-failed-05" run_dump_test "attr-merge-priv-spec-failed-06" + run_dump_test "attr-phdr" run_ld_link_tests [list \ [list "Weak reference 32" "-T weakref.ld -m[riscv_choose_ilp32_emul]" "" \ "-march=rv32i -mabi=ilp32" {weakref32.s} \