aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@sifive.com>2021-06-29 14:36:35 +0800
committerNelson Chu <nelson.chu@sifive.com>2021-07-06 11:34:36 +0800
commitfbc95f1e11facf233e89a9c2b4dde06b9aaf4b86 (patch)
tree810aa9b4b50933cd6e9e7f844d15886db695fd2a
parent07b2745f850232e1c2fdafb0f65ea88e6127218b (diff)
downloadgdb-fbc95f1e11facf233e89a9c2b4dde06b9aaf4b86.zip
gdb-fbc95f1e11facf233e89a9c2b4dde06b9aaf4b86.tar.gz
gdb-fbc95f1e11facf233e89a9c2b4dde06b9aaf4b86.tar.bz2
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.
-rw-r--r--bfd/elfnn-riscv.c65
-rw-r--r--binutils/readelf.c13
-rw-r--r--include/elf/riscv.h5
-rw-r--r--ld/testsuite/ld-elf/orphan-region.ld2
-rw-r--r--ld/testsuite/ld-riscv-elf/attr-phdr.d19
-rw-r--r--ld/testsuite/ld-riscv-elf/attr-phdr.s9
-rw-r--r--ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp1
7 files changed, 112 insertions, 2 deletions
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index f206708..4db3ca4 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 a6073f7..2215339 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -4095,6 +4095,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)
{
if (e_machine == EM_PARISC)
@@ -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 fb376a0..8082283 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 2abf8bc..71834df 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 0000000..43f2ea5
--- /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 0000000..f075248
--- /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 1f1245a..1f6eceb 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} \