From: Alan Hayward via Gdb-patches <gdb-patches@sourceware.org>
To: Luis Machado <luis.machado@linaro.org>
Cc: "david.spickett@linaro.org" <david.spickett@linaro.org>,
Catalin Marinas <Catalin.Marinas@arm.com>,
"gdb-patches\\@sourceware.org" <gdb-patches@sourceware.org>
Subject: Re: [PATCH,v5][AArch64] MTE corefile support
Date: Thu, 24 Jun 2021 15:18:26 +0000 [thread overview]
Message-ID: <BA2F4E48-49F5-488D-AC51-803B1F1F3CE6@arm.com> (raw)
In-Reply-To: <eb0b42ec-bd2f-c716-ff08-14ad07fe61ce@linaro.org>
On 24 Jun 2021, at 15:37, Luis Machado <luis.machado@linaro.org<mailto:luis.machado@linaro.org>> wrote:
On 6/24/21 11:00 AM, Alan Hayward wrote:
On 1 Jun 2021, at 18:45, Luis Machado <luis.machado@linaro.org<mailto:luis.machado@linaro.org>> wrote:
Updates on v5:
- Fixed format warning output.
Updates on v4:
- Calculate sizes based on individual struct field sizes.
Updates on v3:
- Addressed review comments.
- New files gdbsupport/memtag.h, gdb/memtag.h and gdb/memtag.c.
- Updated code documentation.
- Removed code duplication.
Updates on v2:
- Reworked core_target::fetch_memtags to handle cases where address + len runs
over the NT_MEMTAG note.
- Turned a few magic numbers into constants. There is an unfortunate duplication
of a constant (NT_MEMTAG_HEADER_SIZE). It is a generic constant, but there is
no file generic enough that gets included by both corelow and linux-tdep.
- More sanity checks to make sure the note format is correct.
- Documented aarch64_linux_decode_memtag_note a little more.
---
Teach GDB how to dump memory tags when using the gcore command and how
to read them back from a core file generated via gcore or the kernel.
Each tagged memory range (listed in /proc/<pid>/smaps) gets dumped to its
own NT_MEMTAG note. A section named ".memtag" is created for each of those
when reading the core file back.
Dumping memory tags
-
When using the gcore command to dump a core file, GDB will go through the maps
in /proc/<pid>/smaps looking for tagged ranges. Each of those entries gets
passed to an arch-specific gdbarch hook that generates a vector of blobs of
memory tag data that are blindly put into a NT_MEMTAG note.
The vector is used because we may have, in the future, multiple tag types for
a particular memory range.
Each of the NT_MEMTAG notes have a generic header and a arch-specific header,
like so:
struct tag_dump_header
{
uint16_t format; // Only NT_MEMTAG_TYPE_AARCH_MTE at present
uint64_t start_vma;
uint64_t end_vma;
};
struct tag_dump_mte
{
uint16_t granule_byte_size;
uint16_t tag_bit_size;
uint16_t __unused;
};
The only bits meant to be generic are the tag_dump_format, start_vma and
end_vma fields.
The format-specific data is supposed to be opaque and only useful for the
arch-specific code.
We can extend the format in the future to make room for other memory tag
layouts.
Reading memory tags
-
When reading a core file that contains NT_MEMTAG entries, GDB will use
a different approach to check for tagged memory range. Rather than looking
at /proc/<pid>/smaps, it will now look for ".memtag" sections with the right
memory range.
When reading tags, GDB will now use the core target's implementation of
fetch_memtags (store_memtags doesn't exist for core targets). Then the data
is fed into an arch-specific hook that will decode the memory tag format and
return a vector of tags.
I've added a test to exercise writing and reading of memory tags in core
files.
gdb/ChangeLog:
YYYY-MM-DD Luis Machado <luis.machado@linaro.org<mailto:luis.machado@linaro.org>>
* Makefile.in (COMMON_SFILES): Add memtag.c.
* NEWS: Mention core file support for memory tagging.
* aarch64-linux-tdep.c: Include elf/common.h.
Include gdbsupport/memtag.h.
(MAX_TAGS_TO_TRANSFER): New constant.
(aarch64_linux_create_memtag_notes_from_range): New function.
(aarch64_linux_decode_memtag_note): Likewise.
(aarch64_linux_init_abi): Register new core file hooks.
(NT_MEMTAG_TOTAL_HEADER_SIZE): New constant.
* arch/aarch64-mte-linux.h (tag_dump_mte): New struct.
(AARCH64_MTE_TAG_BIT_SIZE): New constant.
* corelow.c: Include gdbsupport/memtag.h and memtag.h.
(core_target) <supports_memory_tagging, fetch_memtags>: New
method overrides.
* gdbarch.c: Regenerate.
* gdbarch.h: Likewise.
* gdbarch.sh (create_memtag_notes_from_range): New hook.
(decode_memtag_note): Likewise.
* linux-tdep.c: Include gdbsupport/memtag.h and memtag.h.
(linux_address_in_memtag_page): Renamed to...
(linux_process_address_in_memtag_page): ... this.
(linux_core_file_address_in_memtag_page): New function.
(linux_address_in_memtag_page): Likewise.
(linux_make_memtag_corefile_notes): Likewise.
(linux_make_corefile_notes): Handle memory tag notes.
* memtag.c: New file.
* memtag.h: New file.
gdb/doc/ChangeLog:
YYYY-MM-DD Luis Machado <luis.machado@linaro.org<mailto:luis.machado@linaro.org>>
* gdb.texinfo (AArch64 Memory Tagging Extension): Mention support
for memory tagging in core files.
gdb/testsuite/ChangeLog:
YYYY-MM-DD Luis Machado <luis.machado@linaro.org<mailto:luis.machado@linaro.org>>
* gdb.arch/aarch64-mte-gcore.c: New file.
* gdb.arch/aarch64-mte-gcore.exp: New file.
gdbsupport/ChangeLog:
YYYY-MM-DD Luis Machado <luis.machado@linaro.org<mailto:luis.machado@linaro.org>>
* memtag.h: New file.
---
gdb/Makefile.in | 1 +
gdb/NEWS | 4 +
gdb/aarch64-linux-tdep.c | 221 +++++++++++++++++++
gdb/arch/aarch64-mte-linux.h | 17 ++
gdb/corelow.c | 63 ++++++
gdb/doc/gdb.texinfo | 4 +
gdb/gdbarch.c | 64 ++++++
gdb/gdbarch.h | 16 ++
gdb/gdbarch.sh | 6 +
gdb/linux-tdep.c | 97 +++++++-
gdb/memtag.c | 88 ++++++++
gdb/memtag.h | 46 ++++
gdb/testsuite/gdb.arch/aarch64-mte-gcore.c | 93 ++++++++
gdb/testsuite/gdb.arch/aarch64-mte-gcore.exp | 111 ++++++++++
gdbsupport/memtag.h | 39 ++++
15 files changed, 867 insertions(+), 3 deletions(-)
create mode 100644 gdb/memtag.c
create mode 100644 gdb/memtag.h
create mode 100644 gdb/testsuite/gdb.arch/aarch64-mte-gcore.c
create mode 100644 gdb/testsuite/gdb.arch/aarch64-mte-gcore.exp
create mode 100644 gdbsupport/memtag.h
Note there were a few minor merge conflicts, nothing to worry about though.
I'll check again and will refresh the patch.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index f664d964536..12fb3b390b1 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1100,6 +1100,7 @@ COMMON_SFILES = \
memattr.c \
memory-map.c \
memrange.c \
+ memtag.c \
minidebug.c \
minsyms.c \
mipsread.c \
diff --git a/gdb/NEWS b/gdb/NEWS
index ab678acec8b..58b9f739d4f 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,10 @@
*** Changes since GDB 10
+* GDB now supports dumping memory tag data for AArch64 MTE. It also supports
+ reading memory tag data for AArch64 MTE from core files generated by
+ the gcore command or the Linux kernel.
+
* GDB now supports general memory tagging functionality if the underlying
architecture supports the proper primitives and hooks. Currently this is
enabled only for AArch64 MTE.
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index e9761ed2189..04498f3b6c0 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -52,6 +52,9 @@
#include "value.h"
#include "gdbsupport/selftest.h"
+#include "gdbsupport/memtag.h"
+
+#include "elf/common.h"
/* Signal frame handling.
@@ -1779,6 +1782,213 @@ aarch64_linux_report_signal_info (struct gdbarch *gdbarch,
}
}
+/* Memory tag note header size. Includes both the generic and the
+ arch-specific parts. */
+#define NT_MEMTAG_TOTAL_HEADER_SIZE (NT_MEMTAG_GENERIC_HEADER_SIZE \
+ + NT_MEMTAG_MTE_HEADER_SIZE)
+
+/* Maximum number of tags to request. */
+#define MAX_TAGS_TO_TRANSFER 1024
+
+/* AArch64 Linux implementation of the aarch64_create_memtag_notes_from_range
+ gdbarch hook. Create core file notes for memory tags. */
+
+static std::vector<gdb::byte_vector>
+aarch64_linux_create_memtag_notes_from_range (struct gdbarch *gdbarch,
+ CORE_ADDR start_address,
+ CORE_ADDR end_address)
+{
+ /* We only handle MTE tags for now. */
+
+ /* Figure out how many tags we need to store in this memory range. */
+ size_t granules = aarch64_mte_get_tag_granules (start_address,
+ end_address - start_address,
+ AARCH64_MTE_GRANULE_SIZE);
+
+ /* Vector of memory tag notes. Add the MTE note (we only have MTE tags
+ at the moment). */
+ std::vector<gdb::byte_vector> notes (1);
+
+ /* If there are no tag granules to fetch, just return. */
+ if (granules == 0)
+ return notes;
+
+ /* Adjust the MTE note size to hold the header + tags. */
+ notes[0].resize (NT_MEMTAG_TOTAL_HEADER_SIZE + granules);
Should this be NT_MEMTAG_TOTAL_HEADER_SIZE + (granules * AARCH64_MTE_GRANULE_SIZE)
Get_granules has already divided by the granule size.
We are storing 1 tag per byte. So the number of granules is the number of tags. If we multiply by AARCH64_MTE_GRANULE_SIZE, we will have 16 times more tags.
Ahh, right.
(Of course - this sort of buffer overrun is exactly what mte prevents :) )
+
+ CORE_ADDR address = start_address;
+ /* Vector of tags. */
+ gdb::byte_vector tags;
+
+ while (granules > 0)
+ {
+ /* Transfer tags in chunks. */
+ gdb::byte_vector tags_read;
+ size_t xfer_len
+ = (granules >= MAX_TAGS_TO_TRANSFER)?
+ MAX_TAGS_TO_TRANSFER * AARCH64_MTE_GRANULE_SIZE :
+ granules * AARCH64_MTE_GRANULE_SIZE;
+
+ if (!target_fetch_memtags (address, xfer_len, tags_read,
+ static_cast<int> (memtag_type::allocation)))
+ {
+ warning (_("Failed to read MTE tags from memory range [%s,%s]."),
+ phex_nz (start_address, sizeof (start_address)),
+ phex_nz (end_address, sizeof (end_address)));
+ notes.resize (0);
If you do the original resize after the while loop, then there would be no need to resize here.
I'm not sure I understand. Where do you suggest the resizing to be placed?
So something like:
std::vector<gdb::byte_vector> notes (1);
while (granules > 0)
{
...
If (!fetch())
return notes
...
}
notes[0].resize (NT_MEMTAG_TOTAL_HEADER_SIZE + all_granules);
Now I write it out, you’ll need to keep a copy of the original number of granules.
Given this is only going to happen on a rare failure, then maybe its not worth the change.
Ok, happy with all those then.
Rest of the patch looks good to me too.
Alan.
next prev parent reply other threads:[~2021-06-24 15:20 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-18 20:20 [PATCH] [AArch64] " Luis Machado via Gdb-patches
2021-05-19 10:01 ` David Spickett via Gdb-patches
2021-05-19 11:11 ` Luis Machado via Gdb-patches
2021-05-19 12:13 ` Eli Zaretskii via Gdb-patches
2021-05-21 15:12 ` Alan Hayward via Gdb-patches
2021-05-21 15:30 ` Luis Machado via Gdb-patches
2021-05-21 17:20 ` John Baldwin
2021-05-24 13:41 ` Luis Machado via Gdb-patches
2021-05-24 8:07 ` Alan Hayward via Gdb-patches
2021-05-24 12:45 ` Luis Machado via Gdb-patches
2021-05-26 14:08 ` [PATCH,v2] " Luis Machado via Gdb-patches
2021-05-29 3:14 ` Simon Marchi via Gdb-patches
2021-05-31 14:12 ` Luis Machado via Gdb-patches
2021-05-31 14:49 ` Simon Marchi via Gdb-patches
2021-05-31 14:56 ` Luis Machado via Gdb-patches
2021-05-31 14:15 ` [PATCH,v3][AArch64] " Luis Machado via Gdb-patches
2021-05-31 16:44 ` [PATCH,v4][AArch64] " Luis Machado via Gdb-patches
2021-06-01 17:45 ` [PATCH,v5][AArch64] " Luis Machado via Gdb-patches
2021-06-15 14:10 ` [Ping][PATCH,v5][AArch64] " Luis Machado via Gdb-patches
2021-06-24 14:00 ` [PATCH,v5][AArch64] " Alan Hayward via Gdb-patches
2021-06-24 14:37 ` Luis Machado via Gdb-patches
2021-06-24 15:18 ` Alan Hayward via Gdb-patches [this message]
2021-07-01 13:50 ` [PING][PATCH,v5][AArch64] " Luis Machado via Gdb-patches
2021-07-11 14:22 ` Joel Brobecker
2021-07-14 13:07 ` Catalin Marinas via Gdb-patches
2021-07-29 2:26 ` Simon Marchi via Gdb-patches
2021-07-29 16:03 ` John Baldwin
2021-07-29 18:10 ` Catalin Marinas via Gdb-patches
2021-07-29 18:20 ` Simon Marchi via Gdb-patches
2021-08-01 15:44 ` Joel Brobecker
2021-08-02 12:06 ` Luis Machado via Gdb-patches
2021-07-19 19:05 ` Luis Machado via Gdb-patches
2021-07-27 16:10 ` Luis Machado via Gdb-patches
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=BA2F4E48-49F5-488D-AC51-803B1F1F3CE6@arm.com \
--to=gdb-patches@sourceware.org \
--cc=Alan.Hayward@arm.com \
--cc=Catalin.Marinas@arm.com \
--cc=david.spickett@linaro.org \
--cc=luis.machado@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox