[PATCH v2] Add PT_RISCV_ATTRIBUTES and add it to PHDR.

Nelson Chu nelson.chu@sifive.com
Tue Jun 29 08:21:45 GMT 2021


I will accept this change after the 2.37 branch is created, if no one
has strong objections, since I have heard that there are a bunch of
things related to this one for a long time.

Besides, I notice that you have updated the
testsuite/ld-elf/orphan-region.ld and readelf.c file, I think these
needs the approval from the global maintainers.

Thanks
Nelson

On Tue, Jun 29, 2021 at 2:36 PM Kito Cheng <kito.cheng@sifive.com> 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
>
> V2 Changes:
>         - Add few more comment.
>         - Add ChangeLog.
>         - Add RISCV_ATTRIBUTES_SECTION_NAME to prevent magic string
>         literal appear again and again.
>         - Still using section name rather than checking section type,
>         since I think it would be more easy to read.

I see that most of the targets, including arm and mips, search the
section by name in the elf_modify_segment_map, so I also prefer to
keep the it.

> 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.
> ---
>  bfd/elfnn-riscv.c                          | 65 +++++++++++++++++++++-
>  binutils/readelf.c                         | 13 +++++
>  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, 112 insertions(+), 2 deletions(-)
>  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 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 f7c64329f37..2ae7564ddb6 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} \
> --
> 2.31.1
>


More information about the Binutils mailing list