Skip to content

Commit bf1838f

Browse files
committed
[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
1 parent 59e812f commit bf1838f

File tree

3 files changed

+58
-11
lines changed

3 files changed

+58
-11
lines changed

lldb/source/Interpreter/OptionArgParser.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,7 @@ lldb::addr_t OptionArgParser::ToAddress(const ExecutionContext *exe_ctx,
175175
lldb::addr_t addr = *maybe_addr;
176176

177177
if (Process *process = exe_ctx->GetProcessPtr())
178-
if (ABISP abi_sp = process->GetABI())
179-
addr = abi_sp->FixCodeAddress(addr);
178+
addr = process->FixAnyAddress(addr);
180179

181180
return addr;
182181
}

lldb/test/API/macosx/arm-corefile-regctx/TestArmMachoCorefileRegctx.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Test that Mach-O armv7/arm64 corefile register contexts are read by lldb."""
22

3-
43
import os
54
import re
65
import subprocess
@@ -44,6 +43,8 @@ def test_armv7_corefile(self):
4443
self.assertTrue(exception.IsValid())
4544
self.assertEqual(exception.GetValueAsUnsigned(), 0x00003F5C)
4645

46+
self.expect("x/4bx $sp-1", substrs=["0x000dffff", "0xff 0x00 0x01 0x02"])
47+
4748
def test_arm64_corefile(self):
4849
### Create corefile
4950
retcode = call(self.create_corefile + " arm64 " + self.corefile, shell=True)

lldb/test/API/macosx/arm-corefile-regctx/create-arm-corefiles.cpp

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,30 @@
1010
// only defines the ARM register context constants when building on
1111
// an arm system. We're creating fake corefiles, and might be
1212
// creating them on an intel system.
13+
#ifndef ARM_THREAD_STATE
1314
#define ARM_THREAD_STATE 1
15+
#endif
16+
#ifndef ARM_THREAD_STATE_COUNT
1417
#define ARM_THREAD_STATE_COUNT 17
18+
#endif
19+
#ifndef ARM_EXCEPTION_STATE
1520
#define ARM_EXCEPTION_STATE 3
21+
#endif
22+
#ifndef ARM_EXCEPTION_STATE_COUNT
1623
#define ARM_EXCEPTION_STATE_COUNT 3
24+
#endif
25+
#ifndef ARM_THREAD_STATE64
1726
#define ARM_THREAD_STATE64 6
27+
#endif
28+
#ifndef ARM_THREAD_STATE64_COUNT
1829
#define ARM_THREAD_STATE64_COUNT 68
30+
#endif
31+
#ifndef ARM_EXCEPTION_STATE64
1932
#define ARM_EXCEPTION_STATE64 7
33+
#endif
34+
#ifndef ARM_EXCEPTION_STATE64_COUNT
2035
#define ARM_EXCEPTION_STATE64_COUNT 4
21-
36+
#endif
2237

2338
union uint32_buf {
2439
uint8_t bytebuf[4];
@@ -129,6 +144,24 @@ std::vector<uint8_t> arm64_lc_thread_load_command() {
129144
return data;
130145
}
131146

147+
std::vector<uint8_t> lc_segment(uint32_t fileoff) {
148+
std::vector<uint8_t> data;
149+
add_uint32(data, LC_SEGMENT); // segment_command.cmd
150+
add_uint32(data, sizeof(struct segment_command)); // segment_command.cmdsize
151+
for (int i = 0; i < 16; i++)
152+
data.push_back(0); // segment_command.segname[16]
153+
add_uint32(data, 0x000e0000 - 512); // segment_command.vmaddr
154+
add_uint32(data, 1024); // segment_command.vmsize
155+
add_uint32(data, fileoff); // segment_command.fileoff
156+
add_uint32(data, 1024); // segment_command.filesize
157+
add_uint32(data, 3); // segment_command.maxprot
158+
add_uint32(data, 3); // segment_command.initprot
159+
add_uint32(data, 0); // segment_command.nsects
160+
add_uint32(data, 0); // segment_command.flags
161+
162+
return data;
163+
}
164+
132165
enum arch { unspecified, armv7, arm64 };
133166

134167
int main(int argc, char **argv) {
@@ -157,10 +190,12 @@ int main(int argc, char **argv) {
157190

158191
// First add all the load commands / payload so we can figure out how large
159192
// the load commands will actually be.
160-
if (arch == armv7)
193+
if (arch == armv7) {
161194
load_commands.push_back(armv7_lc_thread_load_command());
162-
else if (arch == arm64)
195+
load_commands.push_back(lc_segment(0));
196+
} else if (arch == arm64) {
163197
load_commands.push_back(arm64_lc_thread_load_command());
198+
}
164199

165200
int size_of_load_commands = 0;
166201
for (const auto &lc : load_commands)
@@ -174,19 +209,31 @@ int main(int argc, char **argv) {
174209
load_commands.clear();
175210
payload.clear();
176211

177-
if (arch == armv7)
212+
int payload_fileoff = (header_and_load_cmd_room + 4096 - 1) & ~(4096 - 1);
213+
214+
if (arch == armv7) {
178215
load_commands.push_back(armv7_lc_thread_load_command());
179-
else if (arch == arm64)
216+
load_commands.push_back(lc_segment(payload_fileoff));
217+
} else if (arch == arm64) {
180218
load_commands.push_back(arm64_lc_thread_load_command());
219+
}
220+
221+
if (arch == armv7)
222+
for (int i = 0; i < 1024; i++) // from segment_command.filesize
223+
payload.push_back(i);
181224

182225
struct mach_header_64 mh;
183-
mh.magic = MH_MAGIC_64;
226+
int header_size;
184227
if (arch == armv7) {
228+
mh.magic = MH_MAGIC;
185229
mh.cputype = CPU_TYPE_ARM;
186230
mh.cpusubtype = CPU_SUBTYPE_ARM_V7M;
231+
header_size = sizeof(struct mach_header);
187232
} else if (arch == arm64) {
233+
mh.magic = MH_MAGIC_64;
188234
mh.cputype = CPU_TYPE_ARM64;
189235
mh.cpusubtype = CPU_SUBTYPE_ARM64_ALL;
236+
header_size = sizeof(struct mach_header_64);
190237
}
191238
mh.filetype = MH_CORE;
192239
mh.ncmds = load_commands.size();
@@ -201,12 +248,12 @@ int main(int argc, char **argv) {
201248
exit(1);
202249
}
203250

204-
fwrite(&mh, sizeof(struct mach_header_64), 1, f);
251+
fwrite(&mh, header_size, 1, f);
205252

206253
for (const auto &lc : load_commands)
207254
fwrite(lc.data(), lc.size(), 1, f);
208255

209-
fseek(f, header_and_load_cmd_room, SEEK_SET);
256+
fseek(f, payload_fileoff, SEEK_SET);
210257

211258
fwrite(payload.data(), payload.size(), 1, f);
212259

0 commit comments

Comments
 (0)