Skip to content

Commit 99c40e6

Browse files
author
Tamas Berghammer
committedAug 20, 2015
Improve instruction emulation based stack unwinding
On ARM there is no difference petween a pop and a load instruction so a register can be loaded multiple times during the function. Add check to threat the load as a restore only if it do the restore from the same location where the register was saved. Differential revision: http://reviews.llvm.org/D11947 llvm-svn: 245546
1 parent 0e1d729 commit 99c40e6

File tree

3 files changed

+24
-10
lines changed

3 files changed

+24
-10
lines changed
 

‎lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding enco
578578
{
579579
if (BitIsSet (registers, i))
580580
{
581-
context.SetRegisterPlusOffset (sp_reg, addr - sp);
581+
context.SetAddress(addr);
582582
data = MemARead(context, addr, 4, 0, &success);
583583
if (!success)
584584
return false;
@@ -2214,7 +2214,7 @@ EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding enc
22142214
for (i=0; i<regs; ++i)
22152215
{
22162216
GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2217-
context.SetRegisterPlusOffset (sp_reg, addr - sp);
2217+
context.SetAddress(addr);
22182218
data = MemARead(context, addr, reg_byte_size, 0, &success);
22192219
if (!success)
22202220
return false;
@@ -3516,7 +3516,10 @@ EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding enco
35163516
context.type = EmulateInstruction::eContextRegisterPlusOffset;
35173517
context.SetRegisterPlusOffset (dwarf_reg, offset);
35183518
if (wback && (n == 13)) // Pop Instruction
3519+
{
35193520
context.type = EmulateInstruction::eContextPopRegisterOffStack;
3521+
context.SetAddress(base_address + offset);
3522+
}
35203523

35213524
// R[i] = MemA [address, 4]; address = address + 4;
35223525
uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
@@ -10307,7 +10310,7 @@ EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEnc
1030710310
context.type = eContextPopRegisterOffStack;
1030810311
else
1030910312
context.type = eContextRegisterLoad;
10310-
context.SetRegisterPlusOffset (base_reg, address - Rn);
10313+
context.SetAddress(address);
1031110314

1031210315
const uint32_t addr_byte_size = GetAddressByteSize();
1031310316
uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
@@ -10437,7 +10440,7 @@ EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEnco
1043710440
context.type = eContextPopRegisterOffStack;
1043810441
else
1043910442
context.type = eContextRegisterLoad;
10440-
context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10443+
context.SetAddress(address);
1044110444

1044210445
// R[t] = MemA[address,4];
1044310446
const uint32_t addr_byte_size = GetAddressByteSize();

‎lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -768,8 +768,6 @@ EmulateInstructionARM64::EmulateLDPSTP (const uint32_t opcode)
768768
Context context_t;
769769
Context context_t2;
770770

771-
context_t.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, 0);
772-
context_t2.SetRegisterToRegisterPlusOffset (reg_info_Rt2, reg_info_base, size);
773771
uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
774772
Error error;
775773

@@ -787,6 +785,8 @@ EmulateInstructionARM64::EmulateLDPSTP (const uint32_t opcode)
787785
context_t.type = eContextRegisterStore;
788786
context_t2.type = eContextRegisterStore;
789787
}
788+
context_t.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, 0);
789+
context_t2.SetRegisterToRegisterPlusOffset (reg_info_Rt2, reg_info_base, size);
790790

791791
if (!ReadRegister (&reg_info_Rt, data_Rt))
792792
return false;
@@ -820,6 +820,8 @@ EmulateInstructionARM64::EmulateLDPSTP (const uint32_t opcode)
820820
context_t.type = eContextRegisterLoad;
821821
context_t2.type = eContextRegisterLoad;
822822
}
823+
context_t.SetAddress(address);
824+
context_t2.SetAddress(address + size);
823825

824826
if (rt_unknown)
825827
memset (buffer, 'U', reg_info_Rt.byte_size);
@@ -950,15 +952,14 @@ EmulateInstructionARM64::EmulateLDRSTRImm (const uint32_t opcode)
950952
return false;
951953

952954
Context context;
953-
context.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, postindex ? 0 : offset);
954-
955955
switch (memop)
956956
{
957957
case MemOp_STORE:
958958
if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is based off of the sp or fp register
959959
context.type = eContextPushRegisterOnStack;
960960
else
961961
context.type = eContextRegisterStore;
962+
context.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, postindex ? 0 : offset);
962963

963964
if (!ReadRegister (&reg_info_Rt, data_Rt))
964965
return false;
@@ -975,6 +976,7 @@ EmulateInstructionARM64::EmulateLDRSTRImm (const uint32_t opcode)
975976
context.type = eContextPopRegisterOffStack;
976977
else
977978
context.type = eContextRegisterLoad;
979+
context.SetAddress(address);
978980

979981
if (!ReadMemory (context, address, buffer, reg_info_Rt.byte_size))
980982
return false;

‎lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -580,8 +580,17 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
580580
const uint32_t generic_regnum = reg_info->kinds[eRegisterKindGeneric];
581581
if (reg_num != LLDB_INVALID_REGNUM && generic_regnum != LLDB_REGNUM_GENERIC_SP)
582582
{
583-
m_curr_row->SetRegisterLocationToSame (reg_num, /*must_replace*/ false);
584-
m_curr_row_modified = true;
583+
if (context.info_type == EmulateInstruction::eInfoTypeAddress)
584+
{
585+
if (m_pushed_regs.find (reg_num) != m_pushed_regs.end () &&
586+
context.info.address == m_pushed_regs[reg_num])
587+
{
588+
m_curr_row->SetRegisterLocationToSame (reg_num, /*must_replace*/ false);
589+
m_curr_row_modified = true;
590+
}
591+
}
592+
else
593+
assert (!"unhandled case, add code to handle this!");
585594
}
586595
}
587596
}

0 commit comments

Comments
 (0)