llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Jason Molenda (jasonmolenda) <details> <summary>Changes</summary> 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 --- Full diff: https://github.com/llvm/llvm-project/pull/147011.diff 3 Files Affected: - (modified) lldb/source/Interpreter/OptionArgParser.cpp (+1-2) - (modified) lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py (+2-1) - (modified) lldb/test/API/macosx/arm-corefile-regctx/create-arm-corefiles.cpp (+55-8) ``````````diff 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); `````````` </details> https://github.com/llvm/llvm-project/pull/147011 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits