This revision was automatically updated to reflect the committed changes.
Closed by commit rG787f91b0bb34: [lldb] Remove non-address bits from addresses 
given to memory tag commands (authored by DavidSpickett).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117672/new/

https://reviews.llvm.org/D117672

Files:
  lldb/source/Commands/CommandObjectMemoryTag.cpp
  
lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
  lldb/test/API/linux/aarch64/mte_tag_access/main.c

Index: lldb/test/API/linux/aarch64/mte_tag_access/main.c
===================================================================
--- lldb/test/API/linux/aarch64/mte_tag_access/main.c
+++ lldb/test/API/linux/aarch64/mte_tag_access/main.c
@@ -71,8 +71,9 @@
   // tag
   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.
+  // The memory tag manager 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, value)                                             \
   (char *)((size_t)(ptr) | ((size_t)((value)&0xf) << 60))
   // mte_buf_alt_tag's nibble > mte_buf to check that lldb isn't just removing
@@ -82,6 +83,15 @@
   mte_buf_2 = SET_TOP_NIBBLE(mte_buf_2, 0xC);
   mte_read_only = SET_TOP_NIBBLE(mte_read_only, 0xD);
 
+// The top level commands should be removing all non-address bits, including
+// pointer signatures. This signs ptr with PAC key A. That signature goes
+// in some bits other than the top byte.
+#define sign_ptr(ptr) __asm__ __volatile__("pacdza %0" : "=r"(ptr) : "r"(ptr))
+  sign_ptr(mte_buf);
+  sign_ptr(mte_buf_alt_tag);
+  sign_ptr(mte_buf_2);
+  sign_ptr(mte_read_only);
+
   // Breakpoint here
   return 0;
 }
Index: lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
===================================================================
--- lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
+++ lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
@@ -20,6 +20,11 @@
         if not self.isAArch64MTE():
             self.skipTest('Target must support MTE.')
 
+        # Required to check that commands remove non-address bits
+        # other than the memory tags.
+        if not self.isAArch64PAuth():
+            self.skipTest('Target must support pointer authentication')
+
         self.build()
         self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
 
Index: lldb/source/Commands/CommandObjectMemoryTag.cpp
===================================================================
--- lldb/source/Commands/CommandObjectMemoryTag.cpp
+++ lldb/source/Commands/CommandObjectMemoryTag.cpp
@@ -12,6 +12,7 @@
 #include "lldb/Interpreter/OptionArgParser.h"
 #include "lldb/Interpreter/OptionGroupFormat.h"
 #include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Target/ABI.h"
 #include "lldb/Target/Process.h"
 
 using namespace lldb;
@@ -85,6 +86,17 @@
     // If this fails the list of regions is cleared, so we don't need to read
     // the return status here.
     process->GetMemoryRegions(memory_regions);
+
+    lldb::addr_t logical_tag = tag_manager->GetLogicalTag(start_addr);
+
+    // The tag manager only removes tag bits. These addresses may include other
+    // non-address bits that must also be ignored.
+    ABISP abi = process->GetABI();
+    if (abi) {
+      start_addr = abi->FixDataAddress(start_addr);
+      end_addr = abi->FixDataAddress(end_addr);
+    }
+
     llvm::Expected<MemoryTagManager::TagRange> tagged_range =
         tag_manager->MakeTaggedRange(start_addr, end_addr, memory_regions);
 
@@ -101,7 +113,6 @@
       return false;
     }
 
-    lldb::addr_t logical_tag = tag_manager->GetLogicalTag(start_addr);
     result.AppendMessageWithFormatv("Logical tag: {0:x}", logical_tag);
     result.AppendMessage("Allocation tags:");
 
@@ -231,6 +242,12 @@
     // the return status here.
     process->GetMemoryRegions(memory_regions);
 
+    // The tag manager only removes tag bits. These addresses may include other
+    // non-address bits that must also be ignored.
+    ABISP abi = process->GetABI();
+    if (abi)
+      start_addr = abi->FixDataAddress(start_addr);
+
     // We have to assume start_addr is not granule aligned.
     // So if we simply made a range:
     // (start_addr, start_addr + (N * granule_size))
@@ -254,6 +271,10 @@
       end_addr =
           aligned_start_addr + (tags.size() * tag_manager->GetGranuleSize());
 
+    // Remove non-address bits that aren't memory tags
+    if (abi)
+      end_addr = abi->FixDataAddress(end_addr);
+
     // 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.
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
  • [Lldb-commits] [PATCH] D11... David Spickett via Phabricator via lldb-commits
    • [Lldb-commits] [PATCH... David Spickett via Phabricator via lldb-commits

Reply via email to