From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1585) id 5DFAC3858439; Tue, 19 Jul 2022 14:24:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5DFAC3858439 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Luis Machado To: bfd-cvs@sourceware.org Subject: [binutils-gdb] [AArch64] Support AArch64 MTE memory tag dumps in core files X-Act-Checkin: binutils-gdb X-Git-Author: Luis Machado X-Git-Refname: refs/heads/master X-Git-Oldrev: 3c539d41b48e5a70cc22b0151ee79b8bd752341d X-Git-Newrev: d0ff5ca959df91dcef16ec57154ff199fad5a4e4 Message-Id: <20220719142453.5DFAC3858439@sourceware.org> Date: Tue, 19 Jul 2022 14:24:53 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Jul 2022 14:24:53 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dd0ff5ca959df= 91dcef16ec57154ff199fad5a4e4 commit d0ff5ca959df91dcef16ec57154ff199fad5a4e4 Author: Luis Machado Date: Tue Jun 28 12:57:34 2022 +0100 [AArch64] Support AArch64 MTE memory tag dumps in core files =20 The Linux kernel can dump memory tag segments to a core file, one segme= nt per mapped range. The format and documentation can be found in the Linux kernel tree [1]. =20 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. =20 Upon reading, each segment that contains memory tags gets mapped to a section named "memtag". These sections will be used by GDB to lookup th= e tag data. There can be multiple such sections with the same name, and they = are not numbered to simplify GDB's handling and lookup. =20 There is another patch for GDB that enables both reading and dumping of memory tag segments. =20 Tested on aarch64-linux Ubuntu 20.04. =20 [1] Documentation/arm64/memory-tagging-extension.rst (Core Dump Support) Diff: --- 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 251a27edb57..cf4db849282 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -8169,6 +8169,89 @@ elfNN_aarch64_section_from_shdr (bfd *abfd, return true; } =20 +/* 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 =3D=3D NULL || hdr->p_type !=3D 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 =3D bfd_make_section_anyway (abfd, "memtag"); + + if (newsect =3D=3D NULL) + return false; + + unsigned int opb =3D bfd_octets_per_byte (abfd, NULL); + + /* p_vaddr holds the original start address of the tagged memory + range. */ + newsect->vma =3D hdr->p_vaddr / opb; + + /* p_filesz holds the storage size of the packed tags. */ + newsect->size =3D hdr->p_filesz; + newsect->filepos =3D hdr->p_offset; + + /* p_memsz holds the size of the memory range that contains tags. T= he + section's rawsize field is reused for this purpose. */ + newsect->rawsize =3D 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 |=3D 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 =3D 0; + Elf_Internal_Phdr *p; + + for (m =3D elf_seg_map (abfd); m !=3D NULL; m =3D m->next, segment_count= ++) + { + /* We are only interested in the memory tag segment that will be dum= ped + 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 !=3D PT_AARCH64_MEMTAG_MTE + || bfd_get_format (abfd) !=3D bfd_core) + continue; + + /* For memory tag segments in core files, the size of the file conte= nts + 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 =3D elf_tdata (abfd)->phdr; + p +=3D m->idx; + p->p_memsz =3D m->sections[0]->rawsize; + p->p_flags =3D 0; + p->p_paddr =3D 0; + p->p_align =3D 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= =3D #define elf_backend_section_from_shdr \ elfNN_aarch64_section_from_shdr =20 +#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 =20 diff --git a/binutils/readelf.c b/binutils/readelf.c index 0f5977bc072..6b7692d9dd5 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 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) =20 +/* MTE memory tag segment type. */ +#define PT_AARCH64_MEMTAG_MTE (PT_LOPROC + 0x2) + /* Additional section types. */ #define SHT_AARCH64_ATTRIBUTES 0x70000003 /* Section holds attributes. */