https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/147011

>From bf1838f4676bab0f7c998d3dbb03b6b593103335 Mon Sep 17 00:00:00 2001
From: Jason Molenda <jmole...@apple.com>
Date: Fri, 4 Jul 2025 00:11:30 -0700
Subject: [PATCH 1/2] [lldb] Pass address expression command args through
 FixAnyAddress

Commands that take an address expression/address through the
OptionArgParser::ToAddress method, which has filtered this
user-specified address through one of the Process Fix methods to
clear non-addressable bits (MTE, PAC, top byte ignore, etc).  We
don't know what class of address this is, IMEM or DMEM, but this
method is passing the addresses through Process::FixCodeAddress,
and on at least one target, FixCodeAddress clears low bits which
are invalid for instructions.

Correct this to use FixAnyAddress, which doesn't make alignment
assumptions.

The actual issue found was by people debugging on a 32-bit ARM
Cortex-M part, who tried to do a memory read from an odd address,
and lldb returned results starting at the next lower even address.

rdar://154885727
---
 lldb/source/Interpreter/OptionArgParser.cpp   |  3 +-
 .../TestArmMachoCorefileRegctx.py             |  3 +-
 .../create-arm-corefiles.cpp                  | 63 ++++++++++++++++---
 3 files changed, 58 insertions(+), 11 deletions(-)

diff --git a/lldb/source/Interpreter/OptionArgParser.cpp 
b/lldb/source/Interpreter/OptionArgParser.cpp
index 2d393a57452ee..616f6e3dc8820 100644
--- a/lldb/source/Interpreter/OptionArgParser.cpp
+++ b/lldb/source/Interpreter/OptionArgParser.cpp
@@ -175,8 +175,7 @@ lldb::addr_t OptionArgParser::ToAddress(const 
ExecutionContext *exe_ctx,
   lldb::addr_t addr = *maybe_addr;
 
   if (Process *process = exe_ctx->GetProcessPtr())
-    if (ABISP abi_sp = process->GetABI())
-      addr = abi_sp->FixCodeAddress(addr);
+    addr = process->FixAnyAddress(addr);
 
   return addr;
 }
diff --git 
a/lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py 
b/lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py
index 4190ea3ac3318..8e34a292e4d5e 100644
--- a/lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py
+++ b/lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py
@@ -1,6 +1,5 @@
 """Test that Mach-O armv7/arm64 corefile register contexts are read by lldb."""
 
-
 import os
 import re
 import subprocess
@@ -44,6 +43,8 @@ def test_armv7_corefile(self):
         self.assertTrue(exception.IsValid())
         self.assertEqual(exception.GetValueAsUnsigned(), 0x00003F5C)
 
+        self.expect("x/4bx $sp-1", substrs=["0x000dffff", "0xff 0x00 0x01 
0x02"])
+
     def test_arm64_corefile(self):
         ### Create corefile
         retcode = call(self.create_corefile + " arm64 " + self.corefile, 
shell=True)
diff --git a/lldb/test/API/macosx/arm-corefile-regctx/create-arm-corefiles.cpp 
b/lldb/test/API/macosx/arm-corefile-regctx/create-arm-corefiles.cpp
index 5517a2397ae52..2bcc48497bdc4 100644
--- a/lldb/test/API/macosx/arm-corefile-regctx/create-arm-corefiles.cpp
+++ b/lldb/test/API/macosx/arm-corefile-regctx/create-arm-corefiles.cpp
@@ -10,15 +10,30 @@
 // only defines the ARM register context constants when building on
 // an arm system.  We're creating fake corefiles, and might be
 // creating them on an intel system.
+#ifndef ARM_THREAD_STATE
 #define ARM_THREAD_STATE 1
+#endif
+#ifndef ARM_THREAD_STATE_COUNT
 #define ARM_THREAD_STATE_COUNT 17
+#endif
+#ifndef ARM_EXCEPTION_STATE
 #define ARM_EXCEPTION_STATE 3
+#endif
+#ifndef ARM_EXCEPTION_STATE_COUNT
 #define ARM_EXCEPTION_STATE_COUNT 3
+#endif
+#ifndef ARM_THREAD_STATE64
 #define ARM_THREAD_STATE64 6
+#endif
+#ifndef ARM_THREAD_STATE64_COUNT
 #define ARM_THREAD_STATE64_COUNT 68
+#endif
+#ifndef ARM_EXCEPTION_STATE64
 #define ARM_EXCEPTION_STATE64 7
+#endif
+#ifndef ARM_EXCEPTION_STATE64_COUNT
 #define ARM_EXCEPTION_STATE64_COUNT 4
-
+#endif
 
 union uint32_buf {
   uint8_t bytebuf[4];
@@ -129,6 +144,24 @@ std::vector<uint8_t> arm64_lc_thread_load_command() {
   return data;
 }
 
+std::vector<uint8_t> lc_segment(uint32_t fileoff) {
+  std::vector<uint8_t> data;
+  add_uint32(data, LC_SEGMENT);                     // segment_command.cmd
+  add_uint32(data, sizeof(struct segment_command)); // segment_command.cmdsize
+  for (int i = 0; i < 16; i++)
+    data.push_back(0);                // segment_command.segname[16]
+  add_uint32(data, 0x000e0000 - 512); // segment_command.vmaddr
+  add_uint32(data, 1024);             // segment_command.vmsize
+  add_uint32(data, fileoff);          // segment_command.fileoff
+  add_uint32(data, 1024);             // segment_command.filesize
+  add_uint32(data, 3);                // segment_command.maxprot
+  add_uint32(data, 3);                // segment_command.initprot
+  add_uint32(data, 0);                // segment_command.nsects
+  add_uint32(data, 0);                // segment_command.flags
+
+  return data;
+}
+
 enum arch { unspecified, armv7, arm64 };
 
 int main(int argc, char **argv) {
@@ -157,10 +190,12 @@ int main(int argc, char **argv) {
 
   // First add all the load commands / payload so we can figure out how large
   // the load commands will actually be.
-  if (arch == armv7)
+  if (arch == armv7) {
     load_commands.push_back(armv7_lc_thread_load_command());
-  else if (arch == arm64)
+    load_commands.push_back(lc_segment(0));
+  } else if (arch == arm64) {
     load_commands.push_back(arm64_lc_thread_load_command());
+  }
 
   int size_of_load_commands = 0;
   for (const auto &lc : load_commands)
@@ -174,19 +209,31 @@ int main(int argc, char **argv) {
   load_commands.clear();
   payload.clear();
 
-  if (arch == armv7)
+  int payload_fileoff = (header_and_load_cmd_room + 4096 - 1) & ~(4096 - 1);
+
+  if (arch == armv7) {
     load_commands.push_back(armv7_lc_thread_load_command());
-  else if (arch == arm64)
+    load_commands.push_back(lc_segment(payload_fileoff));
+  } else if (arch == arm64) {
     load_commands.push_back(arm64_lc_thread_load_command());
+  }
+
+  if (arch == armv7)
+    for (int i = 0; i < 1024; i++) // from segment_command.filesize
+      payload.push_back(i);
 
   struct mach_header_64 mh;
-  mh.magic = MH_MAGIC_64;
+  int header_size;
   if (arch == armv7) {
+    mh.magic = MH_MAGIC;
     mh.cputype = CPU_TYPE_ARM;
     mh.cpusubtype = CPU_SUBTYPE_ARM_V7M;
+    header_size = sizeof(struct mach_header);
   } else if (arch == arm64) {
+    mh.magic = MH_MAGIC_64;
     mh.cputype = CPU_TYPE_ARM64;
     mh.cpusubtype = CPU_SUBTYPE_ARM64_ALL;
+    header_size = sizeof(struct mach_header_64);
   }
   mh.filetype = MH_CORE;
   mh.ncmds = load_commands.size();
@@ -201,12 +248,12 @@ int main(int argc, char **argv) {
     exit(1);
   }
 
-  fwrite(&mh, sizeof(struct mach_header_64), 1, f);
+  fwrite(&mh, header_size, 1, f);
 
   for (const auto &lc : load_commands)
     fwrite(lc.data(), lc.size(), 1, f);
 
-  fseek(f, header_and_load_cmd_room, SEEK_SET);
+  fseek(f, payload_fileoff, SEEK_SET);
 
   fwrite(payload.data(), payload.size(), 1, f);
 

>From 33e24cafab820131d92f9f879568896599aaacc0 Mon Sep 17 00:00:00 2001
From: Jason Molenda <jmole...@apple.com>
Date: Sat, 5 Jul 2025 23:29:42 -0700
Subject: [PATCH 2/2] Add a comment explaining what the memory read alias is
 doing.  Tighten up how much data is being stored in the corefile.

---
 .../TestArmMachoCorefileRegctx.py             |  5 +++-
 .../create-arm-corefiles.cpp                  | 30 +++++++++++--------
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git 
a/lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py 
b/lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py
index 8e34a292e4d5e..6754288a65e1a 100644
--- a/lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py
+++ b/lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py
@@ -43,7 +43,10 @@ def test_armv7_corefile(self):
         self.assertTrue(exception.IsValid())
         self.assertEqual(exception.GetValueAsUnsigned(), 0x00003F5C)
 
-        self.expect("x/4bx $sp-1", substrs=["0x000dffff", "0xff 0x00 0x01 
0x02"])
+        # read 4 bytes starting at $sp-1 (an odd/unaligned address on this 
arch),
+        # formatted hex.
+        # aka `mem read -f x -s 1 -c 4 $sp-1`
+        self.expect("x/4bx $sp-1", substrs=["0x000dffff", "0x1f 0x20 0x21 
0x22"])
 
     def test_arm64_corefile(self):
         ### Create corefile
diff --git a/lldb/test/API/macosx/arm-corefile-regctx/create-arm-corefiles.cpp 
b/lldb/test/API/macosx/arm-corefile-regctx/create-arm-corefiles.cpp
index 2bcc48497bdc4..f2a95a9aaecaa 100644
--- a/lldb/test/API/macosx/arm-corefile-regctx/create-arm-corefiles.cpp
+++ b/lldb/test/API/macosx/arm-corefile-regctx/create-arm-corefiles.cpp
@@ -144,20 +144,22 @@ std::vector<uint8_t> arm64_lc_thread_load_command() {
   return data;
 }
 
-std::vector<uint8_t> lc_segment(uint32_t fileoff) {
+std::vector<uint8_t> lc_segment(uint32_t fileoff,
+                                uint32_t lc_segment_data_size) {
   std::vector<uint8_t> data;
+  uint32_t start_vmaddr = 0x000e0000 - (lc_segment_data_size / 2);
   add_uint32(data, LC_SEGMENT);                     // segment_command.cmd
   add_uint32(data, sizeof(struct segment_command)); // segment_command.cmdsize
   for (int i = 0; i < 16; i++)
-    data.push_back(0);                // segment_command.segname[16]
-  add_uint32(data, 0x000e0000 - 512); // segment_command.vmaddr
-  add_uint32(data, 1024);             // segment_command.vmsize
-  add_uint32(data, fileoff);          // segment_command.fileoff
-  add_uint32(data, 1024);             // segment_command.filesize
-  add_uint32(data, 3);                // segment_command.maxprot
-  add_uint32(data, 3);                // segment_command.initprot
-  add_uint32(data, 0);                // segment_command.nsects
-  add_uint32(data, 0);                // segment_command.flags
+    data.push_back(0);                    // segment_command.segname[16]
+  add_uint32(data, start_vmaddr);         // segment_command.vmaddr
+  add_uint32(data, lc_segment_data_size); // segment_command.vmsize
+  add_uint32(data, fileoff);              // segment_command.fileoff
+  add_uint32(data, lc_segment_data_size); // segment_command.filesize
+  add_uint32(data, 3);                    // segment_command.maxprot
+  add_uint32(data, 3);                    // segment_command.initprot
+  add_uint32(data, 0);                    // segment_command.nsects
+  add_uint32(data, 0);                    // segment_command.flags
 
   return data;
 }
@@ -192,7 +194,7 @@ int main(int argc, char **argv) {
   // the load commands will actually be.
   if (arch == armv7) {
     load_commands.push_back(armv7_lc_thread_load_command());
-    load_commands.push_back(lc_segment(0));
+    load_commands.push_back(lc_segment(0, 0));
   } else if (arch == arm64) {
     load_commands.push_back(arm64_lc_thread_load_command());
   }
@@ -211,15 +213,17 @@ int main(int argc, char **argv) {
 
   int payload_fileoff = (header_and_load_cmd_room + 4096 - 1) & ~(4096 - 1);
 
+  const int lc_segment_data_size = 64;
   if (arch == armv7) {
     load_commands.push_back(armv7_lc_thread_load_command());
-    load_commands.push_back(lc_segment(payload_fileoff));
+    load_commands.push_back(lc_segment(payload_fileoff, lc_segment_data_size));
   } else if (arch == arm64) {
     load_commands.push_back(arm64_lc_thread_load_command());
   }
 
   if (arch == armv7)
-    for (int i = 0; i < 1024; i++) // from segment_command.filesize
+    for (int i = 0; i < lc_segment_data_size;
+         i++) // from segment_command.filesize
       payload.push_back(i);
 
   struct mach_header_64 mh;

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to