[llvm] 068f14f - [lldb] Add --show-tags option to "memory find"

David Spickett via llvm-commits llvm-commits at lists.llvm.org
Thu May 19 06:40:08 PDT 2022


Author: David Spickett
Date: 2022-05-19T14:40:01+01:00
New Revision: 068f14f1e4ec69d218df544487f9420f2b3ab29b

URL: https://github.com/llvm/llvm-project/commit/068f14f1e4ec69d218df544487f9420f2b3ab29b
DIFF: https://github.com/llvm/llvm-project/commit/068f14f1e4ec69d218df544487f9420f2b3ab29b.diff

LOG: [lldb] Add --show-tags option to "memory find"

This is off by default. If you get a result and that
memory has memory tags, when --show-tags is given you'll
see the tags inline with the memory content.

```
(lldb) memory read mte_buf mte_buf+64 --show-tags
<...>
0xfffff7ff8020: 00 00 00 00 00 00 00 00 0d f0 fe ca 00 00 00 00 ................ (tag: 0x2)
<...>
(lldb) memory find -e 0xcafef00d mte_buf mte_buf+64 --show-tags
data found at location: 0xfffff7ff8028
0xfffff7ff8028: 0d f0 fe ca 00 00 00 00 00 00 00 00 00 00 00 00 ................ (tags: 0x2 0x3)
0xfffff7ff8038: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ (tags: 0x3 0x4)
```

The logic for handling alignments is the same as for memory read
so in the above example because the line starts misaligned to the
granule it covers 2 granules.

Depends on D125089

Reviewed By: omjavaid

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

Added: 
    

Modified: 
    lldb/include/lldb/Interpreter/OptionGroupMemoryTag.h
    lldb/source/Commands/CommandObjectMemory.cpp
    lldb/source/Interpreter/OptionGroupMemoryTag.cpp
    lldb/test/API/commands/help/TestHelp.py
    lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
    lldb/test/API/linux/aarch64/mte_tag_access/main.c
    llvm/docs/ReleaseNotes.rst

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Interpreter/OptionGroupMemoryTag.h b/lldb/include/lldb/Interpreter/OptionGroupMemoryTag.h
index 956ec3f07a9b..918ea3ad96df 100644
--- a/lldb/include/lldb/Interpreter/OptionGroupMemoryTag.h
+++ b/lldb/include/lldb/Interpreter/OptionGroupMemoryTag.h
@@ -16,7 +16,10 @@ namespace lldb_private {
 
 class OptionGroupMemoryTag : public OptionGroup {
 public:
-  OptionGroupMemoryTag();
+  OptionGroupMemoryTag(
+      // Whether to note that --show-tags does not apply to binary output.
+      // "memory read" wants this but "memory find" does not.
+      bool note_binary = false);
 
   ~OptionGroupMemoryTag() override = default;
 
@@ -33,6 +36,7 @@ class OptionGroupMemoryTag : public OptionGroup {
 
 protected:
   OptionValueBoolean m_show_tags;
+  OptionDefinition m_option_definition;
 };
 
 } // namespace lldb_private

diff  --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp
index 7005db308806..b7678add5399 100644
--- a/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -288,7 +288,7 @@ class CommandObjectMemoryRead : public CommandObjectParsed {
             "Read from the memory of the current target process.", nullptr,
             eCommandRequiresTarget | eCommandProcessMustBePaused),
         m_format_options(eFormatBytesWithASCII, 1, 8),
-
+        m_memory_tag_options(/*note_binary=*/true),
         m_prev_format_options(eFormatBytesWithASCII, 1, 8) {
     CommandArgumentEntry arg1;
     CommandArgumentEntry arg2;
@@ -975,6 +975,8 @@ class CommandObjectMemoryFind : public CommandObjectParsed {
     m_arguments.push_back(arg2);
 
     m_option_group.Append(&m_memory_options);
+    m_option_group.Append(&m_memory_tag_options, LLDB_OPT_SET_ALL,
+                          LLDB_OPT_SET_ALL);
     m_option_group.Finalize();
   }
 
@@ -1139,7 +1141,9 @@ class CommandObjectMemoryFind : public CommandObjectParsed {
         DumpDataExtractor(
             data, &result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1,
             dumpbuffer.GetByteSize(), 16,
-            found_location + m_memory_options.m_offset.GetCurrentValue(), 0, 0);
+            found_location + m_memory_options.m_offset.GetCurrentValue(), 0, 0,
+            m_exe_ctx.GetBestExecutionContextScope(),
+            m_memory_tag_options.GetShowTags().GetCurrentValue());
         result.GetOutputStream().EOL();
       }
 
@@ -1182,6 +1186,7 @@ class CommandObjectMemoryFind : public CommandObjectParsed {
 
   OptionGroupOptions m_option_group;
   OptionGroupFindMemory m_memory_options;
+  OptionGroupMemoryTag m_memory_tag_options;
 };
 
 #define LLDB_OPTIONS_memory_write

diff  --git a/lldb/source/Interpreter/OptionGroupMemoryTag.cpp b/lldb/source/Interpreter/OptionGroupMemoryTag.cpp
index f63dfd6bcac6..6752b6c8acf2 100644
--- a/lldb/source/Interpreter/OptionGroupMemoryTag.cpp
+++ b/lldb/source/Interpreter/OptionGroupMemoryTag.cpp
@@ -13,25 +13,26 @@
 using namespace lldb;
 using namespace lldb_private;
 
-OptionGroupMemoryTag::OptionGroupMemoryTag() : m_show_tags(false, false) {}
-
 static const uint32_t SHORT_OPTION_SHOW_TAGS = 0x54414753; // 'tags'
 
-static constexpr OptionDefinition g_option_table[] = {
-    {LLDB_OPT_SET_1,
-     false,
-     "show-tags",
-     SHORT_OPTION_SHOW_TAGS,
-     OptionParser::eNoArgument,
-     nullptr,
-     {},
-     0,
-     eArgTypeNone,
-     "Include memory tags in output (does not apply to binary output)."},
-};
+OptionGroupMemoryTag::OptionGroupMemoryTag(bool note_binary /*=false*/)
+    : m_show_tags(false, false), m_option_definition{
+                                     LLDB_OPT_SET_1,
+                                     false,
+                                     "show-tags",
+                                     SHORT_OPTION_SHOW_TAGS,
+                                     OptionParser::eNoArgument,
+                                     nullptr,
+                                     {},
+                                     0,
+                                     eArgTypeNone,
+                                     note_binary
+                                         ? "Include memory tags in output "
+                                           "(does not apply to binary output)."
+                                         : "Include memory tags in output."} {}
 
 llvm::ArrayRef<OptionDefinition> OptionGroupMemoryTag::GetDefinitions() {
-  return llvm::makeArrayRef(g_option_table);
+  return llvm::makeArrayRef(m_option_definition);
 }
 
 Status
@@ -40,7 +41,7 @@ OptionGroupMemoryTag::SetOptionValue(uint32_t option_idx,
                                      ExecutionContext *execution_context) {
   assert(option_idx == 0 && "Only one option in memory tag group!");
 
-  switch (g_option_table[0].short_option) {
+  switch (m_option_definition.short_option) {
   case SHORT_OPTION_SHOW_TAGS:
     m_show_tags.SetCurrentValue(true);
     m_show_tags.SetOptionWasSet();

diff  --git a/lldb/test/API/commands/help/TestHelp.py b/lldb/test/API/commands/help/TestHelp.py
index 14f4472741bd..e3363e870e5d 100644
--- a/lldb/test/API/commands/help/TestHelp.py
+++ b/lldb/test/API/commands/help/TestHelp.py
@@ -303,3 +303,13 @@ def test_help_detailed_information_ordering(self):
 
         self.assertEqual(sorted(short_options), short_options,
                          "Short option help displayed in an incorrect order!")
+
+    @no_debug_info_test
+    def test_help_show_tags(self):
+        """ Check that memory find and memory read have the --show-tags option
+            but only memory read mentions binary output. """
+        self.expect("help memory read", patterns=[
+                    "--show-tags\n\s+Include memory tags in output "
+                    "\(does not apply to binary output\)."])
+        self.expect("help memory find", patterns=[
+                    "--show-tags\n\s+Include memory tags in output."])

diff  --git a/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py b/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
index 8ca5db4a659b..ec5d110461aa 100644
--- a/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
+++ b/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
@@ -441,3 +441,34 @@ def test_mte_memory_read_tag_display_repeated(self):
         # A fresh command reverts to the default of tags being off.
         self.expect("memory read mte_buf mte_buf+16 -f \"x\"",
                     patterns=["0x[0-9A-fa-f]+00: 0x0+ 0x0+ 0x0+ 0x0+"])
+
+    @skipUnlessArch("aarch64")
+    @skipUnlessPlatform(["linux"])
+    @skipUnlessAArch64MTELinuxCompiler
+    def test_mte_memory_find(self):
+        """Test the --show-tags option with memory find."""
+        self.setup_mte_test()
+
+        # No result, nothing changes.
+        self.expect("memory find -s \"foo\" mte_buf mte_buf+32 --show-tags",
+            substrs=["data not found within the range."])
+
+        cmd = "memory find -s \"LLDB\" mte_buf+64 mte_buf+512"
+        found_pattern = "data found at location: 0x[0-9A-Fa-f]+80"
+        results_patterns = [
+            "0x[0-9A-Fa-f]+80: 4c 4c 44 42 (00 )+ LLDB\.+",
+            "0x[0-9A-Fa-f]+90: 00 00 00 00 (00 )+ \.+"
+        ]
+
+        # Default is not to show tags
+        self.expect(cmd, patterns=[found_pattern, *results_patterns])
+        self.expect(cmd + " --show-tags", patterns=[found_pattern,
+                    results_patterns[0] + " \(tag: 0x8\)",
+                    results_patterns[1] + " \(tag: 0x9\)"])
+
+        # Uses the same logic as memory read to handle misalignment.
+        self.expect("memory find -s \"DB\" mte_buf+64 mte_buf+512 --show-tags",
+            patterns=[
+                "data found at location: 0x[0-9A-Fa-f]+82\n"
+                "0x[0-9A-Fa-f]+82: 44 42 (00 )+ DB\.+ \(tags: 0x8 0x9\)\n",
+                "0x[0-9A-Fa-f]+92: 00 00 (00 )+ ..\.+ \(tags: 0x9 0xa\)"])

diff  --git a/lldb/test/API/linux/aarch64/mte_tag_access/main.c b/lldb/test/API/linux/aarch64/mte_tag_access/main.c
index 5a466b166009..934cce8c3fa6 100644
--- a/lldb/test/API/linux/aarch64/mte_tag_access/main.c
+++ b/lldb/test/API/linux/aarch64/mte_tag_access/main.c
@@ -2,6 +2,7 @@
 #include <asm/hwcap.h>
 #include <asm/mman.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/auxv.h>
 #include <sys/mman.h>
 #include <sys/prctl.h>
@@ -53,6 +54,9 @@ int main(int argc, char const *argv[]) {
   char *non_mte_buf = checked_mmap(page_size, PROT_READ);
   char *mte_read_only = checked_mmap(page_size, mte_prot);
 
+  // Target value for "memory find" testing.
+  strncpy(mte_buf+128, "LLDB", 4);
+
   // Set incrementing tags until end of the first page
   char *tagged_ptr = mte_buf;
   // This ignores tag bits when subtracting the addresses

diff  --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 101cec511792..340c30d17776 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -176,6 +176,9 @@ Changes to LLDB
   memory regions (including unmapped ranges). This is the equivalent
   of using address 0 then repeating the command until all regions
   have been listed.
+* Added "--show-tags" option to the "memory find" command. This is off by default.
+  When enabled, if the target value is found in tagged memory, the tags for that
+  memory will be shown inline with the memory contents.
 
 Changes to Sanitizers
 ---------------------


        


More information about the llvm-commits mailing list