[PATCH] RISC-V: Add PT_RISCV_ATTRIBUTES and add it to PHDR.

Fangrui Song i@maskray.me
Thu Jun 17 08:05:48 GMT 2021


On 2021-06-17, Kito Cheng wrote:
>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

I left a comment there. What features make a runtime detection check via
PT_RISCV_ATTRIBUTES appealing?

> bfd/elfnn-riscv.c                          | 59 ++++++++++++++++++++++
> binutils/readelf.c                         | 14 +++++
> include/elf/riscv.h                        |  5 ++
> ld/testsuite/ld-elf/orphan-region.ld       |  2 +-
> ld/testsuite/ld-riscv-elf/attr-phdr.d      | 19 +++++++
> ld/testsuite/ld-riscv-elf/attr-phdr.s      |  9 ++++
> ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |  1 +
> 7 files changed, 108 insertions(+), 1 deletion(-)
> create mode 100644 ld/testsuite/ld-riscv-elf/attr-phdr.d
> create mode 100644 ld/testsuite/ld-riscv-elf/attr-phdr.s
>
>diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
>index eef1e800221..cc59914dde1 100644
>--- a/bfd/elfnn-riscv.c
>+++ b/bfd/elfnn-riscv.c
>@@ -5134,6 +5134,62 @@ 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"))
>+    ++ret;

Using section types is the spirit of ELF.

>+  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");
>+  if (s != NULL)
>+    {
>+      for (m = elf_seg_map (abfd); m != NULL; m = m->next)
>+	if (m->p_type == PT_RISCV_ATTRIBUTES)
>+	  break;
>+      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
>@@ -5166,6 +5222,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
>
>diff --git a/binutils/readelf.c b/binutils/readelf.c
>index 20100f11ce6..35e9326b49c 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,10 @@ 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 0b49ddcacf6..8e95a89c72a 100644
>--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
>+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
>@@ -109,6 +109,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} \
>-- 
>2.31.1
>


More information about the Binutils mailing list