aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2022-10-11 17:26:56 -0700
committerJohn Baldwin <jhb@FreeBSD.org>2022-10-13 11:25:32 -0700
commitd16bdb3d994a9d40f728892511a42f9cd5c71e6a (patch)
treea44e435551a3b554a21cc65319621948c5f7dc09
parent039008c7310919c8422b3ab0c9aeb791c6ef2a19 (diff)
downloadfsf-binutils-gdb-d16bdb3d994a9d40f728892511a42f9cd5c71e6a.zip
fsf-binutils-gdb-d16bdb3d994a9d40f728892511a42f9cd5c71e6a.tar.gz
fsf-binutils-gdb-d16bdb3d994a9d40f728892511a42f9cd5c71e6a.tar.bz2
bfd/binutils: Support for CHERI-RISC-V memory tag segments.
-rw-r--r--bfd/elfnn-riscv.c46
-rw-r--r--binutils/readelf.c1
-rw-r--r--include/elf/riscv.h3
3 files changed, 50 insertions, 0 deletions
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index f880de4..6812807 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -5181,6 +5181,51 @@ riscv_elf_additional_program_headers (bfd *abfd,
return ret;
}
+/* Process any RISC-V-specific program segment types. */
+
+static bool
+riscv_section_from_phdr (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Phdr *hdr,
+ int hdr_index ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED)
+{
+ if (hdr == NULL)
+ return false;
+
+ /* Right now we only handle the PT_RISCV_MEMTAG_CHERI segment types. */
+ if (hdr->p_type != PT_RISCV_MEMTAG_CHERI)
+ return false;
+
+ if (hdr->p_filesz > 0)
+ {
+ asection *newsect = bfd_make_section_anyway (abfd, "memtag.cheri");
+
+ if (newsect == NULL)
+ return false;
+
+ unsigned int opb = bfd_octets_per_byte (abfd, NULL);
+
+ /* p_vaddr holds the original start address of the tagged memory
+ range. */
+ newsect->vma = hdr->p_vaddr / opb;
+
+ /* p_filesz holds the storage size of the packed tags. */
+ newsect->size = hdr->p_filesz;
+ newsect->filepos = hdr->p_offset;
+
+ /* p_memsz holds the size of the memory range that contains tags. The
+ section's rawsize field is reused for this purpose. */
+ newsect->rawsize = hdr->p_memsz;
+
+ /* Make sure the section's flags has SEC_HAS_CONTENTS set, otherwise
+ BFD will return all zeroes when attempting to get contents from this
+ section. */
+ newsect->flags |= SEC_HAS_CONTENTS;
+ }
+
+ return true;
+}
+
static bool
riscv_elf_modify_segment_map (bfd *abfd,
struct bfd_link_info *info ATTRIBUTE_UNUSED)
@@ -5277,6 +5322,7 @@ riscv_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
#define elf_backend_object_p riscv_elf_object_p
#define elf_backend_write_core_note riscv_write_core_note
#define elf_backend_maybe_function_sym riscv_maybe_function_sym
+#define elf_backend_section_from_phdr riscv_section_from_phdr
#define elf_info_to_howto_rel NULL
#define elf_info_to_howto riscv_info_to_howto_rela
#define bfd_elfNN_bfd_relax_section _bfd_riscv_relax_section
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 3d0024e..76e1377 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -4583,6 +4583,7 @@ get_riscv_segment_type (unsigned long type)
switch (type)
{
case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
+ case PT_RISCV_MEMTAG_CHERI: return "RISCV_MEMTAG_CHERI";
default: return NULL;
}
}
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index 34b02f0..2ba97a8 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -137,6 +137,9 @@ END_RELOC_NUMBERS (R_RISCV_max)
/* Location of RISC-V ELF attribute section. */
#define PT_RISCV_ATTRIBUTES 0x70000003
+/* CHERI memory tag segment type. */
+#define PT_RISCV_MEMTAG_CHERI 0x7fffffff
+
/* Object attributes. */
enum
{