[PATCH] [AArch64] Support AArch64 MTE memory tag dumps in core files
Luis Machado
luis.machado@arm.com
Wed May 11 15:13:13 GMT 2022
Alan,
Does this updated version look OK to you?
On 5/3/22 12:33, Luis Machado via Binutils wrote:
> v3:
>
> - Update the segment name from PT_ARM_MEMTAG_MTE to PT_AARCH64_MEMTAG_MTE
> and change its value to PT_LOPROC + 0x2, as PT_LOPROC + 0x1 was taken.
>
> v2:
>
> - Drop arch-specific fields from the generic section data structure.
> - Use the rawsize field of the section structure to store the original
> memory range of the memory-tagged area.
> - Implement the bfd_elf_modify_headers for aarch64, to adjust the values
> for the memory tag segment according to the Linux Kernel's format.
>
> --
>
> The Linux kernel can dump memory tag segments to a core file, one segment
> per mapped range. The format and documentation can be found in the Linux
> kernel tree [1].
>
> The following patch adjusts bfd and binutils so they can handle this new
> segment type and display it accordingly. It also adds code required so GDB
> can properly read/dump core file data containing memory tags.
>
> Upon reading, each segment that contains memory tags gets mapped to a
> section named "memtag". These sections will be used by GDB to lookup the tag
> data. There can be multiple such sections with the same name, and they are not
> numbered to simplify GDB's handling and lookup.
>
> There is another patch for GDB that enables both reading
> and dumping of memory tag segments.
>
> Tested on aarch64-linux Ubuntu 20.04.
>
> [1] Documentation/arm64/memory-tagging-extension.rst (Core Dump Support)
> ---
> bfd/elfnn-aarch64.c | 89 +++++++++++++++++++++++++++++++++++++++++++
> binutils/readelf.c | 1 +
> include/elf/aarch64.h | 3 ++
> 3 files changed, 93 insertions(+)
>
> diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
> index 4926bab9cf2..3eee97b7ada 100644
> --- a/bfd/elfnn-aarch64.c
> +++ b/bfd/elfnn-aarch64.c
> @@ -8158,6 +8158,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
> @@ -10059,6 +10142,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 d45e0920788..ea20479daef 100644
> --- a/binutils/readelf.c
> +++ b/binutils/readelf.c
> @@ -4499,6 +4499,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 703a62baeca..e368ff2dffe 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. */
>
More information about the Binutils
mailing list