aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/elfnn-aarch64.c89
-rw-r--r--binutils/readelf.c1
-rw-r--r--include/elf/aarch64.h3
3 files changed, 93 insertions, 0 deletions
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 251a27e..cf4db84 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -8169,6 +8169,89 @@ elfNN_aarch64_section_from_shdr (bfd *abfd,
return true;
}
+/* Process any AArch64-specific program segment types. */
+
+static bool
+elfNN_aarch64_section_from_phdr (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Phdr *hdr,
+ int hdr_index ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED)
+{
+ /* Right now we only handle the PT_AARCH64_MEMTAG_MTE segment type. */
+ if (hdr == NULL || hdr->p_type != PT_AARCH64_MEMTAG_MTE)
+ return false;
+
+ if (hdr->p_filesz > 0)
+ {
+ /* Sections created from memory tag p_type's are always named
+ "memtag". This makes it easier for tools (for example, GDB)
+ to find them. */
+ asection *newsect = bfd_make_section_anyway (abfd, "memtag");
+
+ 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;
+}
+
+/* Implements the bfd_elf_modify_headers hook for aarch64. */
+
+static bool
+elfNN_aarch64_modify_headers (bfd *abfd,
+ struct bfd_link_info *info)
+{
+ struct elf_segment_map *m;
+ unsigned int segment_count = 0;
+ Elf_Internal_Phdr *p;
+
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next, segment_count++)
+ {
+ /* We are only interested in the memory tag segment that will be dumped
+ to a core file. If we have no memory tags or this isn't a core file we
+ are dealing with, just skip this segment. */
+ if (m->p_type != PT_AARCH64_MEMTAG_MTE
+ || bfd_get_format (abfd) != bfd_core)
+ continue;
+
+ /* For memory tag segments in core files, the size of the file contents
+ is smaller than the size of the memory range. Adjust the memory size
+ accordingly. The real memory size is held in the section's rawsize
+ field. */
+ if (m->count > 0)
+ {
+ p = elf_tdata (abfd)->phdr;
+ p += m->idx;
+ p->p_memsz = m->sections[0]->rawsize;
+ p->p_flags = 0;
+ p->p_paddr = 0;
+ p->p_align = 0;
+ }
+ }
+
+ /* Give the generic code a chance to handle the headers. */
+ return _bfd_elf_modify_headers (abfd, info);
+}
+
/* A structure used to record a list of sections, independently
of the next and prev fields in the asection structure. */
typedef struct section_list
@@ -10086,6 +10169,12 @@ const struct elf_size_info elfNN_aarch64_size_info =
#define elf_backend_section_from_shdr \
elfNN_aarch64_section_from_shdr
+#define elf_backend_section_from_phdr \
+ elfNN_aarch64_section_from_phdr
+
+#define elf_backend_modify_headers \
+ elfNN_aarch64_modify_headers
+
#define elf_backend_size_dynamic_sections \
elfNN_aarch64_size_dynamic_sections
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 0f5977b..6b7692d 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -4493,6 +4493,7 @@ get_aarch64_segment_type (unsigned long type)
switch (type)
{
case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
+ case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
default: return NULL;
}
}
diff --git a/include/elf/aarch64.h b/include/elf/aarch64.h
index 703a62b..e368ff2 100644
--- a/include/elf/aarch64.h
+++ b/include/elf/aarch64.h
@@ -27,6 +27,9 @@
/* Processor specific program header types. */
#define PT_AARCH64_ARCHEXT (PT_LOPROC + 0)
+/* MTE memory tag segment type. */
+#define PT_AARCH64_MEMTAG_MTE (PT_LOPROC + 0x2)
+
/* Additional section types. */
#define SHT_AARCH64_ATTRIBUTES 0x70000003 /* Section holds attributes. */