Skip to content

Commit 288dc9f

Browse files
committed
[lldb][Mach-O] Fix several bugs in x86_64 Mach-O corefile (llvm#146460)
reading, and one bug in the new RegisterContextUnifiedCore class. The PR I landed a few days ago to allow Mach-O corefiles to augment their registers with additional per-thread registers in metadata exposed a few bugs in the x86_64 corefile reader when running under different CI environments. It also showed a bug in my RegisterContextUnifiedCore class where I wasn't properly handling lookups of unknown registers (e.g. the LLDB_GENERIC_RA when debugging an intel target). The Mach-O x86_64 corefile support would say that it had fpu & exc registers available in every corefile, regardless of whether they were actually present. It would only read the bytes for the first register flavor in the LC_THREAD, the GPRs, but it read them incorrectly, so sometimes you got more register context than you'd expect. The LC_THREAD register context specifies a flavor and the number of uint32_t words; the ObjectFileMachO method would read that number of uint64_t's, exceeding the GPR register space, but it was followed by FPU and then EXC register space so it didn't crash. If you had a corefile with GPR and EXC register bytes, it would be written into the GPR and then FPU register areas, with zeroes filling out the rest of the context. (cherry picked from commit e94c609)
1 parent 2940c22 commit 288dc9f

File tree

2 files changed

+32
-42
lines changed

2 files changed

+32
-42
lines changed

lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -187,46 +187,32 @@ class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64 {
187187
SetError(GPRRegSet, Read, -1);
188188
SetError(FPURegSet, Read, -1);
189189
SetError(EXCRegSet, Read, -1);
190-
bool done = false;
191190

192-
while (!done) {
191+
while (offset < data.GetByteSize()) {
193192
int flavor = data.GetU32(&offset);
194193
if (flavor == 0)
195-
done = true;
196-
else {
197-
uint32_t i;
198-
uint32_t count = data.GetU32(&offset);
199-
switch (flavor) {
200-
case GPRRegSet:
201-
for (i = 0; i < count; ++i)
202-
(&gpr.rax)[i] = data.GetU64(&offset);
203-
SetError(GPRRegSet, Read, 0);
204-
done = true;
205-
206-
break;
207-
case FPURegSet:
208-
// TODO: fill in FPU regs....
209-
// SetError (FPURegSet, Read, -1);
210-
done = true;
211-
212-
break;
213-
case EXCRegSet:
214-
exc.trapno = data.GetU32(&offset);
215-
exc.err = data.GetU32(&offset);
216-
exc.faultvaddr = data.GetU64(&offset);
217-
SetError(EXCRegSet, Read, 0);
218-
done = true;
219-
break;
220-
case 7:
221-
case 8:
222-
case 9:
223-
// fancy flavors that encapsulate of the above flavors...
224-
break;
225-
226-
default:
227-
done = true;
228-
break;
229-
}
194+
break;
195+
uint32_t count = data.GetU32(&offset);
196+
switch (flavor) {
197+
case GPRRegSet: {
198+
uint32_t *gpr_data = reinterpret_cast<uint32_t *>(&gpr.rax);
199+
for (uint32_t i = 0; i < count && offset < data.GetByteSize(); ++i)
200+
gpr_data[i] = data.GetU32(&offset);
201+
SetError(GPRRegSet, Read, 0);
202+
} break;
203+
case FPURegSet:
204+
// TODO: fill in FPU regs....
205+
SetError(FPURegSet, Read, -1);
206+
break;
207+
case EXCRegSet:
208+
exc.trapno = data.GetU32(&offset);
209+
exc.err = data.GetU32(&offset);
210+
exc.faultvaddr = data.GetU64(&offset);
211+
SetError(EXCRegSet, Read, 0);
212+
break;
213+
default:
214+
offset += count * 4;
215+
break;
230216
}
231217
}
232218
}
@@ -356,11 +342,11 @@ class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64 {
356342
}
357343

358344
protected:
359-
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return 0; }
345+
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }
360346

361-
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return 0; }
347+
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }
362348

363-
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return 0; }
349+
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }
364350

365351
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
366352
return 0;

lldb/source/Plugins/Process/mach-core/RegisterContextUnifiedCore.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,15 +262,19 @@ size_t RegisterContextUnifiedCore::GetRegisterCount() {
262262

263263
const RegisterInfo *
264264
RegisterContextUnifiedCore::GetRegisterInfoAtIndex(size_t reg) {
265-
return &m_register_infos[reg];
265+
if (reg < m_register_infos.size())
266+
return &m_register_infos[reg];
267+
return nullptr;
266268
}
267269

268270
size_t RegisterContextUnifiedCore::GetRegisterSetCount() {
269271
return m_register_sets.size();
270272
}
271273

272274
const RegisterSet *RegisterContextUnifiedCore::GetRegisterSet(size_t set) {
273-
return &m_register_sets[set];
275+
if (set < m_register_sets.size())
276+
return &m_register_sets[set];
277+
return nullptr;
274278
}
275279

276280
bool RegisterContextUnifiedCore::ReadRegister(

0 commit comments

Comments
 (0)