[llvm-branch-commits] [lldb] 45d9885 - [lldb] Add "memory tag write" command

David Spickett via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Aug 3 06:52:45 PDT 2021


Author: David Spickett
Date: 2021-08-03T12:25:35Z
New Revision: 45d98857f8f979552d7e1e7e781d6ca92a5e9a48

URL: https://github.com/llvm/llvm-project/commit/45d98857f8f979552d7e1e7e781d6ca92a5e9a48
DIFF: https://github.com/llvm/llvm-project/commit/45d98857f8f979552d7e1e7e781d6ca92a5e9a48.diff

LOG: [lldb] Add "memory tag write" command

This adds a new command for writing memory tags.
It is based on the existing "memory write" command.

Syntax: memory tag write <address-expression> <value> [<value> [...]]
(where "value" is a tag value)

(lldb) memory tag write mte_buf 1 2
(lldb) memory tag read mte_buf mte_buf+32
Logical tag: 0x0
Allocation tags:
[0xfffff7ff9000, 0xfffff7ff9010): 0x1
[0xfffff7ff9010, 0xfffff7ff9020): 0x2

The range you are writing to will be calculated by
aligning the address down to a granule boundary then
adding as many granules as there are tags.

(a repeating mode with an end address will be in a follow
up patch)

This is why "memory tag write" uses MakeTaggedRange but has
some extra steps to get this specific behaviour.

The command does all the usual argument validation:
* Address must evaluate
* You must supply at least one tag value
  (though lldb-server would just treat that as a nop anyway)
* Those tag values must be valid for your tagging scheme
  (e.g. for MTE the value must be > 0 and < 0xf)
* The calculated range must be memory tagged

That last error will show you the final range, not just
the start address you gave the command.

(lldb) memory tag write mte_buf_2+page_size-16 6
(lldb) memory tag write mte_buf_2+page_size-16 6 7
error: Address range 0xfffff7ffaff0:0xfffff7ffb010 is not in a memory tagged region

(note that we do not check if the region is writeable
since lldb can write to it anyway)

The read and write tag tests have been merged into
a single set of "tag access" tests as their test programs would
have been almost identical.
(also I have renamed some of the buffers to better
show what each one is used for)

Reviewed By: omjavaid

Differential Revision: https://reviews.llvm.org/D105182

(cherry picked from commit 6a7a2ee8161da84d9a58a88b497b0b47c8df99f3)

Added: 
    lldb/test/API/linux/aarch64/mte_tag_access/Makefile
    lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
    lldb/test/API/linux/aarch64/mte_tag_access/main.c

Modified: 
    lldb/source/Commands/CommandObjectMemoryTag.cpp
    lldb/test/API/functionalities/memory/tag/TestMemoryTag.py

Removed: 
    lldb/test/API/linux/aarch64/mte_tag_read/Makefile
    lldb/test/API/linux/aarch64/mte_tag_read/TestAArch64LinuxMTEMemoryTagRead.py
    lldb/test/API/linux/aarch64/mte_tag_read/main.c


################################################################################
diff  --git a/lldb/source/Commands/CommandObjectMemoryTag.cpp b/lldb/source/Commands/CommandObjectMemoryTag.cpp
index 1dfb32a92f3bb..7c244befe0da4 100644
--- a/lldb/source/Commands/CommandObjectMemoryTag.cpp
+++ b/lldb/source/Commands/CommandObjectMemoryTag.cpp
@@ -115,6 +115,114 @@ class CommandObjectMemoryTagRead : public CommandObjectParsed {
   }
 };
 
+#define LLDB_OPTIONS_memory_tag_write
+#include "CommandOptions.inc"
+
+class CommandObjectMemoryTagWrite : public CommandObjectParsed {
+public:
+  CommandObjectMemoryTagWrite(CommandInterpreter &interpreter)
+      : CommandObjectParsed(interpreter, "tag",
+                            "Write memory tags starting from the granule that "
+                            "contains the given address.",
+                            nullptr,
+                            eCommandRequiresTarget | eCommandRequiresProcess |
+                                eCommandProcessMustBePaused) {
+    // Address
+    m_arguments.push_back(
+        CommandArgumentEntry{CommandArgumentData(eArgTypeAddressOrExpression)});
+    // One or more tag values
+    m_arguments.push_back(CommandArgumentEntry{
+        CommandArgumentData(eArgTypeValue, eArgRepeatPlus)});
+  }
+
+  ~CommandObjectMemoryTagWrite() override = default;
+
+protected:
+  bool DoExecute(Args &command, CommandReturnObject &result) override {
+    if (command.GetArgumentCount() < 2) {
+      result.AppendError("wrong number of arguments; expected "
+                         "<address-expression> <tag> [<tag> [...]]");
+      return false;
+    }
+
+    Status error;
+    addr_t start_addr = OptionArgParser::ToAddress(
+        &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error);
+    if (start_addr == LLDB_INVALID_ADDRESS) {
+      result.AppendErrorWithFormatv("Invalid address expression, {0}",
+                                    error.AsCString());
+      return false;
+    }
+
+    command.Shift(); // shift off start address
+
+    std::vector<lldb::addr_t> tags;
+    for (auto &entry : command) {
+      lldb::addr_t tag_value;
+      // getAsInteger returns true on failure
+      if (entry.ref().getAsInteger(0, tag_value)) {
+        result.AppendErrorWithFormat(
+            "'%s' is not a valid unsigned decimal string value.\n",
+            entry.c_str());
+        return false;
+      }
+      tags.push_back(tag_value);
+    }
+
+    Process *process = m_exe_ctx.GetProcessPtr();
+    llvm::Expected<const MemoryTagManager *> tag_manager_or_err =
+        process->GetMemoryTagManager();
+
+    if (!tag_manager_or_err) {
+      result.SetError(Status(tag_manager_or_err.takeError()));
+      return false;
+    }
+
+    const MemoryTagManager *tag_manager = *tag_manager_or_err;
+
+    MemoryRegionInfos memory_regions;
+    // If this fails the list of regions is cleared, so we don't need to read
+    // the return status here.
+    process->GetMemoryRegions(memory_regions);
+
+    // We have to assume start_addr is not granule aligned.
+    // So if we simply made a range:
+    // (start_addr, start_addr + (N * granule_size))
+    // We would end up with a range that isn't N granules but N+1
+    // granules. To avoid this we'll align the start first using the method that
+    // doesn't check memory attributes. (if the final range is untagged we'll
+    // handle that error later)
+    lldb::addr_t aligned_start_addr =
+        tag_manager->ExpandToGranule(MemoryTagManager::TagRange(start_addr, 1))
+            .GetRangeBase();
+
+    // Now we've aligned the start address so if we ask for another range
+    // using the number of tags N, we'll get back a range that is also N
+    // granules in size.
+    llvm::Expected<MemoryTagManager::TagRange> tagged_range =
+        tag_manager->MakeTaggedRange(
+            aligned_start_addr,
+            aligned_start_addr + (tags.size() * tag_manager->GetGranuleSize()),
+            memory_regions);
+
+    if (!tagged_range) {
+      result.SetError(Status(tagged_range.takeError()));
+      return false;
+    }
+
+    Status status = process->WriteMemoryTags(tagged_range->GetRangeBase(),
+                                             tagged_range->GetByteSize(), tags);
+
+    if (status.Fail()) {
+      result.SetError(status);
+      return false;
+    }
+
+    result.SetStatus(eReturnStatusSuccessFinishResult);
+    return true;
+  }
+};
+
 CommandObjectMemoryTag::CommandObjectMemoryTag(CommandInterpreter &interpreter)
     : CommandObjectMultiword(
           interpreter, "tag", "Commands for manipulating memory tags",
@@ -123,6 +231,11 @@ CommandObjectMemoryTag::CommandObjectMemoryTag(CommandInterpreter &interpreter)
       new CommandObjectMemoryTagRead(interpreter));
   read_command_object->SetCommandName("memory tag read");
   LoadSubCommand("read", read_command_object);
+
+  CommandObjectSP write_command_object(
+      new CommandObjectMemoryTagWrite(interpreter));
+  write_command_object->SetCommandName("memory tag write");
+  LoadSubCommand("write", write_command_object);
 }
 
 CommandObjectMemoryTag::~CommandObjectMemoryTag() = default;

diff  --git a/lldb/test/API/functionalities/memory/tag/TestMemoryTag.py b/lldb/test/API/functionalities/memory/tag/TestMemoryTag.py
index d6b4169b1bfda..f54e18485d1fc 100644
--- a/lldb/test/API/functionalities/memory/tag/TestMemoryTag.py
+++ b/lldb/test/API/functionalities/memory/tag/TestMemoryTag.py
@@ -39,3 +39,4 @@ def test_memory_tag_read_unsupported(self):
             expected = "error: This architecture does not support memory tagging"
 
         self.expect("memory tag read 0 1", substrs=[expected], error=True)
+        self.expect("memory tag write 0 1 2", substrs=[expected], error=True)

diff  --git a/lldb/test/API/linux/aarch64/mte_tag_read/Makefile b/lldb/test/API/linux/aarch64/mte_tag_access/Makefile
similarity index 100%
rename from lldb/test/API/linux/aarch64/mte_tag_read/Makefile
rename to lldb/test/API/linux/aarch64/mte_tag_access/Makefile

diff  --git a/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py b/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
new file mode 100644
index 0000000000000..b8a2852adb857
--- /dev/null
+++ b/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
@@ -0,0 +1,218 @@
+"""
+Test "memory tag read" and "memory tag write" commands
+on AArch64 Linux with MTE.
+"""
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class AArch64LinuxMTEMemoryTagAccessTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    NO_DEBUG_INFO_TESTCASE = True
+
+    def setup_mte_test(self):
+        if not self.isAArch64MTE():
+            self.skipTest('Target must support MTE.')
+
+        self.build()
+        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_break_set_by_file_and_line(self, "main.c",
+            line_number('main.c', '// Breakpoint here'),
+            num_expected_locations=1)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        if self.process().GetState() == lldb.eStateExited:
+            self.fail("Test program failed to run.")
+
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs=['stopped',
+                     'stop reason = breakpoint'])
+
+    @skipUnlessArch("aarch64")
+    @skipUnlessPlatform(["linux"])
+    @skipUnlessAArch64MTELinuxCompiler
+    def test_mte_tag_read(self):
+        self.setup_mte_test()
+
+        # Argument validation
+        self.expect("memory tag read",
+                substrs=["error: wrong number of arguments; expected at least <address-expression>, "
+                         "at most <address-expression> <end-address-expression>"],
+                error=True)
+        self.expect("memory tag read mte_buf buf+16 32",
+                substrs=["error: wrong number of arguments; expected at least <address-expression>, "
+                         "at most <address-expression> <end-address-expression>"],
+                error=True)
+        self.expect("memory tag read not_a_symbol",
+                substrs=["error: Invalid address expression, address expression \"not_a_symbol\" "
+                         "evaluation failed"],
+                error=True)
+        self.expect("memory tag read mte_buf not_a_symbol",
+                substrs=["error: Invalid end address expression, address expression \"not_a_symbol\" "
+                         "evaluation failed"],
+                error=True)
+        # Inverted range
+        self.expect("memory tag read mte_buf mte_buf-16",
+                patterns=["error: End address \(0x[A-Fa-f0-9]+\) must be "
+                          "greater than the start address \(0x[A-Fa-f0-9]+\)"],
+                error=True)
+        # Range of length 0
+        self.expect("memory tag read mte_buf mte_buf",
+                patterns=["error: End address \(0x[A-Fa-f0-9]+\) must be "
+                          "greater than the start address \(0x[A-Fa-f0-9]+\)"],
+                error=True)
+
+
+        # Can't read from a region without tagging
+        self.expect("memory tag read non_mte_buf",
+                patterns=["error: Address range 0x[0-9A-Fa-f]+00:0x[0-9A-Fa-f]+10 is not "
+                         "in a memory tagged region"],
+                error=True)
+
+        # If there's no end address we assume 1 granule
+        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$"])
+
+        # 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$"])
+
+        # 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$"])
+
+        # You may read up to the end of the tagged region
+        # Layout is mte_buf, mte_buf_2, non_mte_buf.
+        # So we read from the end of mte_buf_2 here.
+        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]+\): 0x0$"])
+
+        # Ranges with any part outside the region will error
+        self.expect("memory tag read mte_buf_2+page_size-16 mte_buf_2+page_size+32",
+                patterns=["error: Address range 0x[0-9A-fa-f]+f0:0x[0-9A-Fa-f]+20 "
+                          "is not in a memory tagged region"],
+                error=True)
+        self.expect("memory tag read mte_buf_2+page_size",
+                patterns=["error: Address range 0x[0-9A-fa-f]+00:0x[0-9A-Fa-f]+10 "
+                          "is not in a memory tagged region"],
+                error=True)
+
+        # You can read a range that spans more than one mapping
+        # This spills into mte_buf2 which is also MTE
+        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$"])
+
+        # Tags in start/end are ignored when creating the range.
+        # So this is not an error despite start/end having 
diff erent tags
+        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$"])
+
+    @skipUnlessArch("aarch64")
+    @skipUnlessPlatform(["linux"])
+    @skipUnlessAArch64MTELinuxCompiler
+    def test_mte_tag_write(self):
+        self.setup_mte_test()
+
+        # Argument validation
+        self.expect("memory tag write",
+                substrs=[" wrong number of arguments; expected "
+                         "<address-expression> <tag> [<tag> [...]]"],
+                error=True)
+        self.expect("memory tag write mte_buf",
+                substrs=[" wrong number of arguments; expected "
+                         "<address-expression> <tag> [<tag> [...]]"],
+                error=True)
+        self.expect("memory tag write not_a_symbol 9",
+                substrs=["error: Invalid address expression, address expression \"not_a_symbol\" "
+                         "evaluation failed"],
+                error=True)
+
+        # Can't write to a region without tagging
+        self.expect("memory tag write non_mte_buf 9",
+                patterns=["error: Address range 0x[0-9A-Fa-f]+00:0x[0-9A-Fa-f]+10 is not "
+                         "in a memory tagged region"],
+                error=True)
+
+        # Start address is aligned down so we write to the granule that contains it
+        self.expect("memory tag write mte_buf+8 9")
+        # Make sure we only modified the first granule
+        self.expect("memory tag read mte_buf mte_buf+32",
+                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$"])
+
+        # 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$"])
+
+        # 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$"])
+
+        # Ranges with any part outside the region will error
+        self.expect("memory tag write mte_buf_2+page_size-16 6 7",
+                patterns=["error: Address range 0x[0-9A-fa-f]+f0:0x[0-9A-Fa-f]+10 "
+                          "is not in a memory tagged region"],
+                error=True)
+        self.expect("memory tag write mte_buf_2+page_size 6",
+                patterns=["error: Address range 0x[0-9A-fa-f]+00:0x[0-9A-Fa-f]+10 "
+                          "is not in a memory tagged region"],
+                error=True)
+        self.expect("memory tag write mte_buf_2+page_size 6 7 8",
+                patterns=["error: Address range 0x[0-9A-fa-f]+00:0x[0-9A-Fa-f]+30 "
+                          "is not in a memory tagged region"],
+                error=True)
+
+        # You can write to a range that spans two mappings, as long
+        # as they are both tagged.
+        # buf and buf2 are next to each other so this wirtes into buf2.
+        self.expect("memory tag write mte_buf+page_size-16 1 2")
+        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$"])
+
+        # 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$"])
+
+        # Trying to write a value > maximum tag value is an error
+        self.expect("memory tag write mte_buf 99",
+                patterns=["error: Found tag 0x63 which is > max MTE tag value of 0xf."],
+                error=True)

diff  --git a/lldb/test/API/linux/aarch64/mte_tag_read/main.c b/lldb/test/API/linux/aarch64/mte_tag_access/main.c
similarity index 50%
rename from lldb/test/API/linux/aarch64/mte_tag_read/main.c
rename to lldb/test/API/linux/aarch64/mte_tag_access/main.c
index f35f1a794ddbc..ecafe3ae7bd34 100644
--- a/lldb/test/API/linux/aarch64/mte_tag_read/main.c
+++ b/lldb/test/API/linux/aarch64/mte_tag_access/main.c
@@ -1,11 +1,22 @@
 #include <arm_acle.h>
 #include <asm/hwcap.h>
 #include <asm/mman.h>
+#include <stdlib.h>
 #include <sys/auxv.h>
 #include <sys/mman.h>
 #include <sys/prctl.h>
 #include <unistd.h>
 
+// This file uses ACLE intrinsics as detailed in:
+// https://developer.arm.com/documentation/101028/0012/10--Memory-tagging-intrinsics?lang=en
+
+char *checked_mmap(size_t page_size, int prot) {
+  char *ptr = mmap(0, page_size, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  if (ptr == MAP_FAILED)
+    exit(1);
+  return ptr;
+}
+
 int main(int argc, char const *argv[]) {
   // We assume that the test runner has checked we're on an MTE system
 
@@ -20,38 +31,32 @@ int main(int argc, char const *argv[]) {
 
   size_t page_size = sysconf(_SC_PAGESIZE);
 
-  // Allocate memory with MTE
-  // We ask for two pages. One is read only so that we get
-  // 2 mappings in /proc/.../smaps so we can check reading
-  // a range across mappings.
-  // The first allocation will start at the highest address,
-  // so we allocate buf2 first to get:
-  // <low address> | buf | buf2 | <high address>
-  int prot = PROT_READ | PROT_MTE;
-  int flags = MAP_PRIVATE | MAP_ANONYMOUS;
-
-  char *buf2 = mmap(0, page_size, prot, flags, -1, 0);
-  if (buf2 == MAP_FAILED)
-    return 1;
-
-  // Writeable so we can set tags on it later
-  char *buf = mmap(0, page_size, prot | PROT_WRITE, flags, -1, 0);
-  if (buf == MAP_FAILED)
-    return 1;
+  // We're going to mmap pages in this order:
+  // <high addres>
+  // MTE read/write
+  // MTE read/write executable
+  // non MTE
+  // MTE read only
+  // <low address>
+  //
+  // This means that the first two MTE pages end up next
+  // to each other. Since the second one is also executable
+  // it will create a new entry in /proc/smaps.
+  int mte_prot = PROT_READ | PROT_MTE;
 
+  char *mte_buf_2 = checked_mmap(page_size, mte_prot | PROT_WRITE);
+  char *mte_buf = checked_mmap(page_size, mte_prot | PROT_WRITE | PROT_EXEC);
   // We expect the mappings to be next to each other
-  if (buf2 - buf != page_size)
+  if (mte_buf_2 - mte_buf != page_size)
     return 1;
 
-  // And without MTE
-  char *non_mte_buf = mmap(0, page_size, PROT_READ | PROT_WRITE, flags, -1, 0);
-  if (non_mte_buf == MAP_FAILED)
-    return 1;
+  char *non_mte_buf = checked_mmap(page_size, PROT_READ);
+  char *mte_read_only = checked_mmap(page_size, mte_prot);
 
   // Set incrementing tags until end of the first page
-  char *tagged_ptr = buf;
+  char *tagged_ptr = mte_buf;
   // This ignores tag bits when subtracting the addresses
-  while (__arm_mte_ptr
diff (tagged_ptr, buf) < page_size) {
+  while (__arm_mte_ptr
diff (tagged_ptr, mte_buf) < page_size) {
     // Set the allocation tag for this location
     __arm_mte_set_tag(tagged_ptr);
     // + 16 for 16 byte granules
@@ -61,16 +66,17 @@ int main(int argc, char const *argv[]) {
   }
 
   // Tag the original pointer with 9
-  buf = __arm_mte_create_random_tag(buf, ~(1 << 9));
+  mte_buf = __arm_mte_create_random_tag(mte_buf, ~(1 << 9));
   // A 
diff erent tag so that buf_alt_tag > buf if you don't handle the tag
-  char *buf_alt_tag = __arm_mte_create_random_tag(buf, ~(1 << 10));
+  char *mte_buf_alt_tag = __arm_mte_create_random_tag(mte_buf, ~(1 << 10));
 
   // lldb should be removing the whole top byte, not just the tags.
   // So fill 63-60 with something non zero so we'll fail if we only remove tags.
 #define SET_TOP_NIBBLE(ptr) (char *)((size_t)(ptr) | (0xA << 60))
-  buf = SET_TOP_NIBBLE(buf);
-  buf_alt_tag = SET_TOP_NIBBLE(buf_alt_tag);
-  buf2 = SET_TOP_NIBBLE(buf2);
+  mte_buf = SET_TOP_NIBBLE(mte_buf);
+  mte_buf_alt_tag = SET_TOP_NIBBLE(mte_buf_alt_tag);
+  mte_buf_2 = SET_TOP_NIBBLE(mte_buf_2);
+  mte_read_only = SET_TOP_NIBBLE(mte_read_only);
 
   // Breakpoint here
   return 0;

diff  --git a/lldb/test/API/linux/aarch64/mte_tag_read/TestAArch64LinuxMTEMemoryTagRead.py b/lldb/test/API/linux/aarch64/mte_tag_read/TestAArch64LinuxMTEMemoryTagRead.py
deleted file mode 100644
index aa79397c1c27a..0000000000000
--- a/lldb/test/API/linux/aarch64/mte_tag_read/TestAArch64LinuxMTEMemoryTagRead.py
+++ /dev/null
@@ -1,126 +0,0 @@
-"""
-Test "memory tag read" command on AArch64 Linux with MTE.
-"""
-
-
-import lldb
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
-
-
-class AArch64LinuxMTEMemoryTagReadTestCase(TestBase):
-
-    mydir = TestBase.compute_mydir(__file__)
-
-    NO_DEBUG_INFO_TESTCASE = True
-
-    @skipUnlessArch("aarch64")
-    @skipUnlessPlatform(["linux"])
-    @skipUnlessAArch64MTELinuxCompiler
-    def test_mte_tag_read(self):
-        if not self.isAArch64MTE():
-            self.skipTest('Target must support MTE.')
-
-        self.build()
-        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
-
-        lldbutil.run_break_set_by_file_and_line(self, "main.c",
-            line_number('main.c', '// Breakpoint here'),
-            num_expected_locations=1)
-
-        self.runCmd("run", RUN_SUCCEEDED)
-
-        if self.process().GetState() == lldb.eStateExited:
-            self.fail("Test program failed to run.")
-
-        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
-            substrs=['stopped',
-                     'stop reason = breakpoint'])
-
-        # Argument validation
-        self.expect("memory tag read",
-                substrs=["error: wrong number of arguments; expected at least <address-expression>, "
-                         "at most <address-expression> <end-address-expression>"],
-                error=True)
-        self.expect("memory tag read buf buf+16 32",
-                substrs=["error: wrong number of arguments; expected at least <address-expression>, "
-                         "at most <address-expression> <end-address-expression>"],
-                error=True)
-        self.expect("memory tag read not_a_symbol",
-                substrs=["error: Invalid address expression, address expression \"not_a_symbol\" "
-                         "evaluation failed"],
-                error=True)
-        self.expect("memory tag read buf not_a_symbol",
-                substrs=["error: Invalid end address expression, address expression \"not_a_symbol\" "
-                         "evaluation failed"],
-                error=True)
-        # Inverted range
-        self.expect("memory tag read buf buf-16",
-                patterns=["error: End address \(0x[A-Fa-f0-9]+\) must be "
-                          "greater than the start address \(0x[A-Fa-f0-9]+\)"],
-                error=True)
-        # Range of length 0
-        self.expect("memory tag read buf buf",
-                patterns=["error: End address \(0x[A-Fa-f0-9]+\) must be "
-                          "greater than the start address \(0x[A-Fa-f0-9]+\)"],
-                error=True)
-
-
-        # Can't read from a region without tagging
-        self.expect("memory tag read non_mte_buf",
-                patterns=["error: Address range 0x[0-9A-Fa-f]+00:0x[0-9A-Fa-f]+10 is not "
-                         "in a memory tagged region"],
-                error=True)
-
-        # If there's no end address we assume 1 granule
-        self.expect("memory tag read buf",
-                patterns=["Logical tag: 0x9\n"
-                          "Allocation tags:\n"
-                          "\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x0$"])
-
-        # Range of <1 granule is rounded up to 1 granule
-        self.expect("memory tag read buf buf+8",
-                patterns=["Logical tag: 0x9\n"
-                          "Allocation tags:\n"
-                          "\[0x[0-9A-Fa-f]+00, 0x[0-9A-Fa-f]+10\): 0x0$"])
-
-        # Start address is aligned down, end aligned up
-        self.expect("memory tag read buf+8 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$"])
-
-        # You may read up to the end of the tagged region
-        # Layout is buf (MTE), buf2 (MTE), <unmapped/non MTE>
-        # so we read from the end of buf2 here.
-        self.expect("memory tag read buf2+page_size-16 buf2+page_size",
-                patterns=["Logical tag: 0x0\n"
-                          "Allocation tags:\n"
-                          "\[0x[0-9A-Fa-f]+, 0x[0-9A-Fa-f]+\): 0x0$"])
-
-        # Ranges with any part outside the region will error
-        self.expect("memory tag read buf2+page_size-16 buf2+page_size+32",
-                patterns=["error: Address range 0x[0-9A-fa-f]+f0:0x[0-9A-Fa-f]+20 "
-                          "is not in a memory tagged region"],
-                error=True)
-        self.expect("memory tag read buf2+page_size",
-                patterns=["error: Address range 0x[0-9A-fa-f]+00:0x[0-9A-Fa-f]+10 "
-                          "is not in a memory tagged region"],
-                error=True)
-
-        # You can read a range that spans more than one mapping
-        # This spills into buf2 which is also MTE
-        self.expect("memory tag read buf+page_size-16 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$"])
-
-        # Tags in start/end are ignored when creating the range.
-        # So this is not an error despite start/end having 
diff erent tags
-        self.expect("memory tag read buf 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$"])


        


More information about the llvm-branch-commits mailing list