Skip to content

Commit

Permalink
[lldb][AArch64] Mark mismatched tags in tag read output
Browse files Browse the repository at this point in the history
The "memory tag read" command will now tell you
when the allocation tag read does not match the logical
tag.

(lldb) memory tag read mte_buf+(8*16) mte_buf+(8*16)+48
Logical tag: 0x9
Allocation tags:
[0xfffff7ff7080, 0xfffff7ff7090): 0x8 (mismatch)
[0xfffff7ff7090, 0xfffff7ff70a0): 0x9
[0xfffff7ff70a0, 0xfffff7ff70b0): 0xa (mismatch)

The logical tag will be taken from the start address
so the end could have a different tag. You could for example
read from ptr_to_array_1 to ptr_to_array_2. Where the latter
is tagged differently to prevent buffer overflow.

The existing command will read 1 granule if you leave
off the end address. So you can also use it as a quick way
to check a single location.

(lldb) memory tag read mte_buf
Logical tag: 0x9
Allocation tags:
[0xfffff7ff7000, 0xfffff7ff7010): 0x0 (mismatch)

This avoids the need for a seperate "memory tag check" command.

Reviewed By: omjavaid

Differential Revision: https://reviews.llvm.org/D106880
  • Loading branch information
DavidSpickett committed Jul 30, 2021
1 parent 555cd03 commit 98b5659
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 30 deletions.
12 changes: 7 additions & 5 deletions lldb/source/Commands/CommandObjectMemoryTag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class CommandObjectMemoryTagRead : public CommandObjectParsed {
public:
CommandObjectMemoryTagRead(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "tag",
"Read memory tags for the given range of memory.",
"Read memory tags for the given range of memory."
" Mismatched tags will be marked.",
nullptr,
eCommandRequiresTarget | eCommandRequiresProcess |
eCommandProcessMustBePaused) {
Expand Down Expand Up @@ -100,16 +101,17 @@ class CommandObjectMemoryTagRead : public CommandObjectParsed {
return false;
}

result.AppendMessageWithFormatv("Logical tag: {0:x}",
tag_manager->GetLogicalTag(start_addr));
lldb::addr_t logical_tag = tag_manager->GetLogicalTag(start_addr);
result.AppendMessageWithFormatv("Logical tag: {0:x}", logical_tag);
result.AppendMessage("Allocation tags:");

addr_t addr = tagged_range->GetRangeBase();
for (auto tag : *tags) {
addr_t next_addr = addr + tag_manager->GetGranuleSize();
// Showing tagged adresses here until we have non address bit handling
result.AppendMessageWithFormatv("[{0:x}, {1:x}): {2:x}", addr, next_addr,
tag);
result.AppendMessageWithFormatv("[{0:x}, {1:x}): {2:x}{3}", addr,
next_addr, tag,
logical_tag == tag ? "" : " (mismatch)");
addr = next_addr;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,20 @@ def test_mte_tag_read(self):
self.expect("memory tag read mte_buf",
patterns=["Logical tag: 0x9\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x0$"])
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x0 \(mismatch\)$"])

# Range of <1 granule is rounded up to 1 granule
self.expect("memory tag read mte_buf mte_buf+8",
patterns=["Logical tag: 0x9\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x0$"])
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x0 \(mismatch\)$"])

# Start address is aligned down, end aligned up
self.expect("memory tag read mte_buf+8 mte_buf+24",
patterns=["Logical tag: 0x9\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x0\n"
"\[0x[0-9A-Fa-f]+10, 0x[0-9A-Fa-f]+20\): 0x1$"])
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x0 \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+10, 0x[0-9A-Fa-f]+20\): 0x1 \(mismatch\)$"])

# You may read up to the end of the tagged region
# Layout is mte_buf, mte_buf_2, non_mte_buf.
Expand All @@ -119,15 +119,23 @@ def test_mte_tag_read(self):
self.expect("memory tag read mte_buf+page_size-16 mte_buf+page_size+16",
patterns=["Logical tag: 0x9\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+f0, 0x[0-9A-Fa-f]+00\): 0xf\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x0$"])
"\[0x[0-9A-Fa-f]+f0, 0x[0-9A-Fa-f]+00\): 0xf \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x0 \(mismatch\)$"])

# Tags in start/end are ignored when creating the range.
# So this is not an error despite start/end having different tags
self.expect("memory tag read mte_buf mte_buf_alt_tag+16 ",
self.expect("memory tag read mte_buf mte_buf_alt_tag+16",
patterns=["Logical tag: 0x9\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x0$"])
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x0 \(mismatch\)$"])

# Mismatched tags are marked. The logical tag is taken from the start address.
self.expect("memory tag read mte_buf+(8*16) mte_buf_alt_tag+(8*16)+48",
patterns=["Logical tag: 0x9\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+80, 0x[0-9A-Fa-f]+90\): 0x8 \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+90, 0x[0-9A-Fa-f]+a0\): 0x9\n"
"\[0x[0-9A-Fa-f]+a0, 0x[0-9A-Fa-f]+b0\): 0xa \(mismatch\)$"])

@skipUnlessArch("aarch64")
@skipUnlessPlatform(["linux"])
Expand Down Expand Up @@ -162,24 +170,24 @@ def test_mte_tag_write(self):
patterns=["Logical tag: 0x9\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x9\n"
"\[0x[0-9A-Fa-f]+10, 0x[0-9A-Fa-f]+20\): 0x1$"])
"\[0x[0-9A-Fa-f]+10, 0x[0-9A-Fa-f]+20\): 0x1 \(mismatch\)$"])

# You can write multiple tags, range calculated for you
self.expect("memory tag write mte_buf 10 11 12")
self.expect("memory tag read mte_buf mte_buf+48",
patterns=["Logical tag: 0x9\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0xa\n"
"\[0x[0-9A-Fa-f]+10, 0x[0-9A-Fa-f]+20\): 0xb\n"
"\[0x[0-9A-Fa-f]+20, 0x[0-9A-Fa-f]+30\): 0xc$"])
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0xa \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+10, 0x[0-9A-Fa-f]+20\): 0xb \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+20, 0x[0-9A-Fa-f]+30\): 0xc \(mismatch\)$"])

# You may write up to the end of a tagged region
# (mte_buf_2's intial tags will all be 0)
self.expect("memory tag write mte_buf_2+page_size-16 0xe")
self.expect("memory tag read mte_buf_2+page_size-16 mte_buf_2+page_size",
patterns=["Logical tag: 0x0\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+, 0x[0-9A-Fa-f]+\): 0xe$"])
"\[0x[0-9A-Fa-f]+, 0x[0-9A-Fa-f]+\): 0xe \(mismatch\)$"])

# Ranges with any part outside the region will error
self.expect("memory tag write mte_buf_2+page_size-16 6 7",
Expand All @@ -202,15 +210,15 @@ def test_mte_tag_write(self):
self.expect("memory tag read mte_buf+page_size-16 mte_buf+page_size+16",
patterns=["Logical tag: 0x9\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+f0, 0x[0-9A-Fa-f]+00\): 0x1\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x2$"])
"\[0x[0-9A-Fa-f]+f0, 0x[0-9A-Fa-f]+00\): 0x1 \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x2 \(mismatch\)$"])

# Even if a page is read only the debugger can still write to it
self.expect("memory tag write mte_read_only 1")
self.expect("memory tag read mte_read_only",
patterns=["Logical tag: 0x0\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x1$"])
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x1 \(mismatch\)$"])

# Trying to write a value > maximum tag value is an error
self.expect("memory tag write mte_buf 99",
Expand Down Expand Up @@ -244,9 +252,9 @@ def test_mte_tag_write(self):
self.expect("memory tag read mte_buf_2 mte_buf_2+64",
patterns=["Logical tag: 0x0\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x4\n"
"\[0x[0-9A-Fa-f]+10, 0x[0-9A-Fa-f]+20\): 0x5\n"
"\[0x[0-9A-Fa-f]+20, 0x[0-9A-Fa-f]+30\): 0x4\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x4 \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+10, 0x[0-9A-Fa-f]+20\): 0x5 \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+20, 0x[0-9A-Fa-f]+30\): 0x4 \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+30, 0x[0-9A-Fa-f]+40\): 0x0$"])

# Since this aligns like tag read does, the start is aligned down and the end up.
Expand All @@ -258,17 +266,17 @@ def test_mte_tag_write(self):
self.expect("memory tag read mte_buf_2 mte_buf_2+48",
patterns=["Logical tag: 0x0\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x6\n"
"\[0x[0-9A-Fa-f]+10, 0x[0-9A-Fa-f]+20\): 0x6\n"
"\[0x[0-9A-Fa-f]+20, 0x[0-9A-Fa-f]+30\): 0x4$"])
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x6 \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+10, 0x[0-9A-Fa-f]+20\): 0x6 \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+20, 0x[0-9A-Fa-f]+30\): 0x4 \(mismatch\)$"])

# If we do the same with a misaligned end, it also moves but upward.
# The intial range is 2 granules but the final range is mte_buf_2 -> mte_buf_2+48
self.expect("memory tag write mte_buf_2+8 3 -end-addr mte_buf_2+32+8")
self.expect("memory tag read mte_buf_2 mte_buf_2+64",
patterns=["Logical tag: 0x0\n"
"Allocation tags:\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x3\n"
"\[0x[0-9A-Fa-f]+10, 0x[0-9A-Fa-f]+20\): 0x3\n"
"\[0x[0-9A-Fa-f]+20, 0x[0-9A-Fa-f]+30\): 0x3\n"
"\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x3 \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+10, 0x[0-9A-Fa-f]+20\): 0x3 \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+20, 0x[0-9A-Fa-f]+30\): 0x3 \(mismatch\)\n"
"\[0x[0-9A-Fa-f]+30, 0x[0-9A-Fa-f]+40\): 0x0$"])

0 comments on commit 98b5659

Please sign in to comment.