Skip to content

Commit e61d518

Browse files
authored
Merge pull request #6993 from apple/cp/109185291-strip-unaddressable-bits-from-pc-sp-fp-59
Cp/109185291 strip unaddressable bits from pc sp fp 59
2 parents 2ca279e + 447cc61 commit e61d518

File tree

1 file changed

+71
-41
lines changed

1 file changed

+71
-41
lines changed

lldb/source/Target/RegisterContextUnwind.cpp

Lines changed: 71 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
#include "lldb/Utility/RegisterValue.h"
3838
#include "lldb/Utility/VASPrintf.h"
3939
#include "lldb/lldb-private.h"
40+
41+
#include <cassert>
4042
#include <memory>
4143

4244
using namespace lldb;
@@ -135,9 +137,8 @@ void RegisterContextUnwind::InitializeZerothFrame() {
135137
// (which would be a no-op in frame 0 where we get it from the register set,
136138
// but still a good idea to make the call here for other ABIs that may
137139
// exist.)
138-
ABI *abi = process->GetABI().get();
139-
if (abi)
140-
current_pc = abi->FixCodeAddress(current_pc);
140+
if (ABISP abi_sp = process->GetABI())
141+
current_pc = abi_sp->FixCodeAddress(current_pc);
141142

142143
UnwindPlanSP lang_runtime_plan_sp = LanguageRuntime::GetRuntimeUnwindPlan(
143144
m_thread, this, m_behaves_like_zeroth_frame);
@@ -289,6 +290,13 @@ void RegisterContextUnwind::InitializeZerothFrame() {
289290
} else
290291
ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa);
291292

293+
if (m_cfa == LLDB_INVALID_ADDRESS && m_afa == LLDB_INVALID_ADDRESS) {
294+
UnwindLogMsg(
295+
"could not read CFA or AFA values for first frame, not valid.");
296+
m_frame_type = eNotAValidFrame;
297+
return;
298+
}
299+
292300
UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64
293301
" afa is 0x%" PRIx64 " using %s UnwindPlan",
294302
(uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()),
@@ -346,17 +354,23 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
346354

347355
// Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
348356
// this will strip bit zero in case we read a PC from memory or from the LR.
349-
ABI *abi = process->GetABI().get();
350-
if (abi)
351-
pc = abi->FixCodeAddress(pc);
357+
ABISP abi_sp = process->GetABI();
358+
if (abi_sp)
359+
pc = abi_sp->FixCodeAddress(pc);
352360

353361
if (log) {
354362
UnwindLogMsg("pc = 0x%" PRIx64, pc);
355363
addr_t reg_val;
356-
if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
364+
if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val)) {
365+
if (abi_sp)
366+
reg_val = abi_sp->FixDataAddress(reg_val);
357367
UnwindLogMsg("fp = 0x%" PRIx64, reg_val);
358-
if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
368+
}
369+
if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val)) {
370+
if (abi_sp)
371+
reg_val = abi_sp->FixDataAddress(reg_val);
359372
UnwindLogMsg("sp = 0x%" PRIx64, reg_val);
373+
}
360374
}
361375

362376
// A pc of 0x0 means it's the end of the stack crawl unless we're above a trap
@@ -415,11 +429,11 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
415429
}
416430
}
417431

418-
if (abi) {
432+
if (abi_sp) {
419433
m_fast_unwind_plan_sp.reset();
420434
m_full_unwind_plan_sp =
421435
std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
422-
abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp);
436+
abi_sp->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp);
423437
if (m_frame_type != eSkipFrame) // don't override eSkipFrame
424438
{
425439
m_frame_type = eNormalFrame;
@@ -1742,8 +1756,8 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() {
17421756
if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
17431757
old_caller_pc_value = reg_value.GetAsUInt64();
17441758
if (ProcessSP process_sp = m_thread.GetProcess()) {
1745-
if (ABISP abi = process_sp->GetABI())
1746-
old_caller_pc_value = abi->FixCodeAddress(old_caller_pc_value);
1759+
if (ABISP abi_sp = process_sp->GetABI())
1760+
old_caller_pc_value = abi_sp->FixCodeAddress(old_caller_pc_value);
17471761
}
17481762
}
17491763
}
@@ -1802,8 +1816,8 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() {
18021816
reg_value)) {
18031817
new_caller_pc_value = reg_value.GetAsUInt64();
18041818
if (ProcessSP process_sp = m_thread.GetProcess()) {
1805-
if (ABISP abi = process_sp->GetABI())
1806-
new_caller_pc_value = abi->FixCodeAddress(new_caller_pc_value);
1819+
if (ABISP abi_sp = process_sp->GetABI())
1820+
new_caller_pc_value = abi_sp->FixCodeAddress(new_caller_pc_value);
18071821
}
18081822
}
18091823
}
@@ -1944,6 +1958,7 @@ bool RegisterContextUnwind::ReadFrameAddress(
19441958

19451959
address = LLDB_INVALID_ADDRESS;
19461960
addr_t cfa_reg_contents;
1961+
ABISP abi_sp = m_thread.GetProcess()->GetABI();
19471962

19481963
switch (fa.GetValueType()) {
19491964
case UnwindPlan::Row::FAValue::isRegisterDereferenced: {
@@ -1954,11 +1969,13 @@ bool RegisterContextUnwind::ReadFrameAddress(
19541969
GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB));
19551970
RegisterValue reg_value;
19561971
if (reg_info) {
1972+
if (abi_sp)
1973+
cfa_reg_contents = abi_sp->FixDataAddress(cfa_reg_contents);
19571974
Status error = ReadRegisterValueFromMemory(
19581975
reg_info, cfa_reg_contents, reg_info->byte_size, reg_value);
19591976
if (error.Success()) {
19601977
address = reg_value.GetAsUInt64();
1961-
if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
1978+
if (abi_sp)
19621979
address = abi_sp->FixCodeAddress(address);
19631980
UnwindLogMsg(
19641981
"CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64
@@ -1980,6 +1997,8 @@ bool RegisterContextUnwind::ReadFrameAddress(
19801997
RegisterNumber cfa_reg(m_thread, row_register_kind,
19811998
fa.GetRegisterNumber());
19821999
if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
2000+
if (abi_sp)
2001+
cfa_reg_contents = abi_sp->FixDataAddress(cfa_reg_contents);
19832002
if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 ||
19842003
cfa_reg_contents == 1) {
19852004
UnwindLogMsg(
@@ -2067,6 +2086,8 @@ lldb::addr_t RegisterContextUnwind::GetReturnAddressHint(int32_t plan_offset) {
20672086
return LLDB_INVALID_ADDRESS;
20682087
if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol)
20692088
return LLDB_INVALID_ADDRESS;
2089+
if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
2090+
hint = abi_sp->FixCodeAddress(hint);
20702091

20712092
hint += plan_offset;
20722093

@@ -2116,28 +2137,46 @@ bool RegisterContextUnwind::ReadGPRValue(lldb::RegisterKind register_kind,
21162137
}
21172138

21182139
const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum);
2140+
assert(reg_info);
2141+
if (!reg_info) {
2142+
UnwindLogMsg(
2143+
"Could not find RegisterInfo definition for lldb register number %d",
2144+
lldb_regnum);
2145+
return false;
2146+
}
2147+
2148+
uint32_t generic_regnum = LLDB_INVALID_REGNUM;
2149+
if (register_kind == eRegisterKindGeneric)
2150+
generic_regnum = regnum;
2151+
else
2152+
m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
2153+
register_kind, regnum, eRegisterKindGeneric, generic_regnum);
2154+
ABISP abi_sp = m_thread.GetProcess()->GetABI();
2155+
21192156
RegisterValue reg_value;
21202157
// if this is frame 0 (currently executing frame), get the requested reg
21212158
// contents from the actual thread registers
21222159
if (IsFrameZero()) {
21232160
if (m_thread.GetRegisterContext()->ReadRegister(reg_info, reg_value)) {
21242161
value = reg_value.GetAsUInt64();
2162+
if (abi_sp && generic_regnum != LLDB_INVALID_REGNUM) {
2163+
if (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
2164+
generic_regnum == LLDB_REGNUM_GENERIC_RA)
2165+
value = abi_sp->FixCodeAddress(value);
2166+
if (generic_regnum == LLDB_REGNUM_GENERIC_SP ||
2167+
generic_regnum == LLDB_REGNUM_GENERIC_FP)
2168+
value = abi_sp->FixDataAddress(value);
2169+
}
21252170
return true;
21262171
}
21272172
return false;
21282173
}
21292174

21302175
bool pc_register = false;
2131-
uint32_t generic_regnum;
2132-
if (register_kind == eRegisterKindGeneric &&
2133-
(regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA)) {
2176+
if (generic_regnum != LLDB_INVALID_REGNUM &&
2177+
(generic_regnum == LLDB_REGNUM_GENERIC_PC ||
2178+
generic_regnum == LLDB_REGNUM_GENERIC_RA))
21342179
pc_register = true;
2135-
} else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
2136-
register_kind, regnum, eRegisterKindGeneric, generic_regnum) &&
2137-
(generic_regnum == LLDB_REGNUM_GENERIC_PC ||
2138-
generic_regnum == LLDB_REGNUM_GENERIC_RA)) {
2139-
pc_register = true;
2140-
}
21412180

21422181
lldb_private::UnwindLLDB::RegisterLocation regloc;
21432182
if (!m_parent_unwind.SearchForSavedLocationForRegister(
@@ -2147,9 +2186,8 @@ bool RegisterContextUnwind::ReadGPRValue(lldb::RegisterKind register_kind,
21472186
if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
21482187
value = reg_value.GetAsUInt64();
21492188
if (pc_register) {
2150-
if (ProcessSP process_sp = m_thread.GetProcess()) {
2151-
if (ABISP abi = process_sp->GetABI())
2152-
value = abi->FixCodeAddress(value);
2189+
if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) {
2190+
value = abi_sp->FixCodeAddress(value);
21532191
}
21542192
}
21552193
return true;
@@ -2198,10 +2236,8 @@ bool RegisterContextUnwind::ReadRegister(const RegisterInfo *reg_info,
21982236
if (is_pc_regnum && value.GetType() == RegisterValue::eTypeUInt64) {
21992237
addr_t reg_value = value.GetAsUInt64(LLDB_INVALID_ADDRESS);
22002238
if (reg_value != LLDB_INVALID_ADDRESS) {
2201-
if(ProcessSP process_sp = m_thread.GetProcess()) {
2202-
if (ABISP abi = process_sp->GetABI())
2203-
value = abi->FixCodeAddress(reg_value);
2204-
}
2239+
if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
2240+
value = abi_sp->FixCodeAddress(reg_value);
22052241
}
22062242
}
22072243
}
@@ -2283,9 +2319,8 @@ bool RegisterContextUnwind::GetStartPC(addr_t &start_pc) {
22832319
ProcessSP process_sp (m_thread.GetProcess());
22842320
if (process_sp)
22852321
{
2286-
ABI *abi = process_sp->GetABI().get();
2287-
if (abi)
2288-
start_pc = abi->FixCodeAddress(start_pc);
2322+
if (ABISP abi_sp = process_sp->GetABI())
2323+
start_pc = abi_sp->FixCodeAddress(start_pc);
22892324
}
22902325
}
22912326
return read_successfully;
@@ -2313,13 +2348,8 @@ bool RegisterContextUnwind::ReadPC(addr_t &pc) {
23132348
// through a NULL pointer -- we want to be able to unwind past that frame
23142349
// to help find the bug.
23152350

2316-
ProcessSP process_sp (m_thread.GetProcess());
2317-
if (process_sp)
2318-
{
2319-
ABI *abi = process_sp->GetABI().get();
2320-
if (abi)
2321-
pc = abi->FixCodeAddress(pc);
2322-
}
2351+
if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
2352+
pc = abi_sp->FixCodeAddress(pc);
23232353

23242354
return !(m_all_registers_available == false &&
23252355
above_trap_handler == false && (pc == 0 || pc == 1));

0 commit comments

Comments
 (0)