diff options
Diffstat (limited to 'source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp')
-rw-r--r-- | source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp | 443 |
1 files changed, 211 insertions, 232 deletions
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp index d011314b09632..e2691be603ece 100644 --- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp +++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp @@ -13,8 +13,8 @@ // Project includes #include "lldb/Core/ArchSpec.h" #include "lldb/Symbol/Function.h" -#include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Symbol.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -25,251 +25,230 @@ using namespace lldb; using namespace lldb_private; -UnwindMacOSXFrameBackchain::UnwindMacOSXFrameBackchain (Thread &thread) : - Unwind (thread), - m_cursors() -{ -} - -uint32_t -UnwindMacOSXFrameBackchain::DoGetFrameCount() -{ - if (m_cursors.empty()) - { - ExecutionContext exe_ctx (m_thread.shared_from_this()); - Target *target = exe_ctx.GetTargetPtr(); - if (target) - { - const ArchSpec& target_arch = target->GetArchitecture (); - // Frame zero should always be supplied by the thread... - exe_ctx.SetFrameSP (m_thread.GetStackFrameAtIndex (0)); - - if (target_arch.GetAddressByteSize() == 8) - GetStackFrameData_x86_64 (exe_ctx); - else - GetStackFrameData_i386 (exe_ctx); - } +UnwindMacOSXFrameBackchain::UnwindMacOSXFrameBackchain(Thread &thread) + : Unwind(thread), m_cursors() {} + +uint32_t UnwindMacOSXFrameBackchain::DoGetFrameCount() { + if (m_cursors.empty()) { + ExecutionContext exe_ctx(m_thread.shared_from_this()); + Target *target = exe_ctx.GetTargetPtr(); + if (target) { + const ArchSpec &target_arch = target->GetArchitecture(); + // Frame zero should always be supplied by the thread... + exe_ctx.SetFrameSP(m_thread.GetStackFrameAtIndex(0)); + + if (target_arch.GetAddressByteSize() == 8) + GetStackFrameData_x86_64(exe_ctx); + else + GetStackFrameData_i386(exe_ctx); } - return m_cursors.size(); + } + return m_cursors.size(); } -bool -UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc) -{ - const uint32_t frame_count = GetFrameCount(); - if (idx < frame_count) - { - if (m_cursors[idx].pc == LLDB_INVALID_ADDRESS) - return false; - if (m_cursors[idx].fp == LLDB_INVALID_ADDRESS) - return false; - - pc = m_cursors[idx].pc; - cfa = m_cursors[idx].fp; - - return true; - } - return false; +bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(uint32_t idx, + addr_t &cfa, + addr_t &pc) { + const uint32_t frame_count = GetFrameCount(); + if (idx < frame_count) { + if (m_cursors[idx].pc == LLDB_INVALID_ADDRESS) + return false; + if (m_cursors[idx].fp == LLDB_INVALID_ADDRESS) + return false; + + pc = m_cursors[idx].pc; + cfa = m_cursors[idx].fp; + + return true; + } + return false; } - + lldb::RegisterContextSP -UnwindMacOSXFrameBackchain::DoCreateRegisterContextForFrame (StackFrame *frame) -{ - lldb::RegisterContextSP reg_ctx_sp; - uint32_t concrete_idx = frame->GetConcreteFrameIndex (); - const uint32_t frame_count = GetFrameCount(); - if (concrete_idx < frame_count) - reg_ctx_sp.reset (new RegisterContextMacOSXFrameBackchain (m_thread, concrete_idx, m_cursors[concrete_idx])); - return reg_ctx_sp; +UnwindMacOSXFrameBackchain::DoCreateRegisterContextForFrame(StackFrame *frame) { + lldb::RegisterContextSP reg_ctx_sp; + uint32_t concrete_idx = frame->GetConcreteFrameIndex(); + const uint32_t frame_count = GetFrameCount(); + if (concrete_idx < frame_count) + reg_ctx_sp.reset(new RegisterContextMacOSXFrameBackchain( + m_thread, concrete_idx, m_cursors[concrete_idx])); + return reg_ctx_sp; } -size_t -UnwindMacOSXFrameBackchain::GetStackFrameData_i386 (const ExecutionContext &exe_ctx) -{ - m_cursors.clear(); - - StackFrame *first_frame = exe_ctx.GetFramePtr(); - - Process *process = exe_ctx.GetProcessPtr(); - if (process == NULL) - return 0; - - std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair; - - struct Frame_i386 - { - uint32_t fp; - uint32_t pc; - }; - - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - assert (reg_ctx); - - Cursor cursor; - cursor.pc = reg_ctx->GetPC (LLDB_INVALID_ADDRESS); - cursor.fp = reg_ctx->GetFP (0); - - Frame_i386 frame = { static_cast<uint32_t>(cursor.fp), static_cast<uint32_t>(cursor.pc) }; - - m_cursors.push_back(cursor); - - const size_t k_frame_size = sizeof(frame); - Error error; - while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) - { - // Read both the FP and PC (8 bytes) - if (process->ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size) - break; - if (frame.pc >= 0x1000) - { - cursor.pc = frame.pc; - cursor.fp = frame.fp; - m_cursors.push_back (cursor); - } +size_t UnwindMacOSXFrameBackchain::GetStackFrameData_i386( + const ExecutionContext &exe_ctx) { + m_cursors.clear(); + + StackFrame *first_frame = exe_ctx.GetFramePtr(); + + Process *process = exe_ctx.GetProcessPtr(); + if (process == NULL) + return 0; + + std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair; + + struct Frame_i386 { + uint32_t fp; + uint32_t pc; + }; + + RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); + assert(reg_ctx); + + Cursor cursor; + cursor.pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS); + cursor.fp = reg_ctx->GetFP(0); + + Frame_i386 frame = {static_cast<uint32_t>(cursor.fp), + static_cast<uint32_t>(cursor.pc)}; + + m_cursors.push_back(cursor); + + const size_t k_frame_size = sizeof(frame); + Error error; + while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) { + // Read both the FP and PC (8 bytes) + if (process->ReadMemory(frame.fp, &frame.fp, k_frame_size, error) != + k_frame_size) + break; + if (frame.pc >= 0x1000) { + cursor.pc = frame.pc; + cursor.fp = frame.fp; + m_cursors.push_back(cursor); } - if (!m_cursors.empty()) - { - lldb::addr_t first_frame_pc = m_cursors.front().pc; - if (first_frame_pc != LLDB_INVALID_ADDRESS) - { - const uint32_t resolve_scope = eSymbolContextModule | - eSymbolContextCompUnit | - eSymbolContextFunction | - eSymbolContextSymbol; - - SymbolContext first_frame_sc (first_frame->GetSymbolContext(resolve_scope)); - const AddressRange *addr_range_ptr = NULL; - AddressRange range; - if (first_frame_sc.function) - addr_range_ptr = &first_frame_sc.function->GetAddressRange(); - else if (first_frame_sc.symbol) - { - range.GetBaseAddress() = first_frame_sc.symbol->GetAddress(); - range.SetByteSize (first_frame_sc.symbol->GetByteSize()); - addr_range_ptr = ⦥ - } - - if (addr_range_ptr) - { - if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress()) - { - // We are at the first instruction, so we can recover the - // previous PC by dereferencing the SP - lldb::addr_t first_frame_sp = reg_ctx->GetSP (0); - // Read the real second frame return address into frame.pc - if (first_frame_sp && process->ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc)) - { - cursor.fp = m_cursors.front().fp; - cursor.pc = frame.pc; // Set the new second frame PC - - // Insert the second frame - m_cursors.insert(m_cursors.begin()+1, cursor); - - m_cursors.front().fp = first_frame_sp; - } - } - } + } + if (!m_cursors.empty()) { + lldb::addr_t first_frame_pc = m_cursors.front().pc; + if (first_frame_pc != LLDB_INVALID_ADDRESS) { + const uint32_t resolve_scope = + eSymbolContextModule | eSymbolContextCompUnit | + eSymbolContextFunction | eSymbolContextSymbol; + + SymbolContext first_frame_sc( + first_frame->GetSymbolContext(resolve_scope)); + const AddressRange *addr_range_ptr = NULL; + AddressRange range; + if (first_frame_sc.function) + addr_range_ptr = &first_frame_sc.function->GetAddressRange(); + else if (first_frame_sc.symbol) { + range.GetBaseAddress() = first_frame_sc.symbol->GetAddress(); + range.SetByteSize(first_frame_sc.symbol->GetByteSize()); + addr_range_ptr = ⦥ + } + + if (addr_range_ptr) { + if (first_frame->GetFrameCodeAddress() == + addr_range_ptr->GetBaseAddress()) { + // We are at the first instruction, so we can recover the + // previous PC by dereferencing the SP + lldb::addr_t first_frame_sp = reg_ctx->GetSP(0); + // Read the real second frame return address into frame.pc + if (first_frame_sp && + process->ReadMemory(first_frame_sp, &frame.pc, sizeof(frame.pc), + error) == sizeof(frame.pc)) { + cursor.fp = m_cursors.front().fp; + cursor.pc = frame.pc; // Set the new second frame PC + + // Insert the second frame + m_cursors.insert(m_cursors.begin() + 1, cursor); + + m_cursors.front().fp = first_frame_sp; + } } + } } -// uint32_t i=0; -// printf(" PC FP\n"); -// printf(" ------------------ ------------------ \n"); -// for (i=0; i<m_cursors.size(); ++i) -// { -// printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 "\n", i, m_cursors[i].pc, m_cursors[i].fp); -// } - return m_cursors.size(); + } + // uint32_t i=0; + // printf(" PC FP\n"); + // printf(" ------------------ ------------------ \n"); + // for (i=0; i<m_cursors.size(); ++i) + // { + // printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 "\n", i, + // m_cursors[i].pc, m_cursors[i].fp); + // } + return m_cursors.size(); } +size_t UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64( + const ExecutionContext &exe_ctx) { + m_cursors.clear(); -size_t -UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64 (const ExecutionContext &exe_ctx) -{ - m_cursors.clear(); - - Process *process = exe_ctx.GetProcessPtr(); - if (process == NULL) - return 0; - - StackFrame *first_frame = exe_ctx.GetFramePtr(); - - std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair; - - struct Frame_x86_64 - { - uint64_t fp; - uint64_t pc; - }; - - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - assert (reg_ctx); - - Cursor cursor; - cursor.pc = reg_ctx->GetPC (LLDB_INVALID_ADDRESS); - cursor.fp = reg_ctx->GetFP (0); - - Frame_x86_64 frame = { cursor.fp, cursor.pc }; - - m_cursors.push_back(cursor); - Error error; - const size_t k_frame_size = sizeof(frame); - while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) - { - // Read both the FP and PC (16 bytes) - if (process->ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size) - break; - - if (frame.pc >= 0x1000) - { - cursor.pc = frame.pc; - cursor.fp = frame.fp; - m_cursors.push_back (cursor); - } + Process *process = exe_ctx.GetProcessPtr(); + if (process == NULL) + return 0; + + StackFrame *first_frame = exe_ctx.GetFramePtr(); + + std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair; + + struct Frame_x86_64 { + uint64_t fp; + uint64_t pc; + }; + + RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); + assert(reg_ctx); + + Cursor cursor; + cursor.pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS); + cursor.fp = reg_ctx->GetFP(0); + + Frame_x86_64 frame = {cursor.fp, cursor.pc}; + + m_cursors.push_back(cursor); + Error error; + const size_t k_frame_size = sizeof(frame); + while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) { + // Read both the FP and PC (16 bytes) + if (process->ReadMemory(frame.fp, &frame.fp, k_frame_size, error) != + k_frame_size) + break; + + if (frame.pc >= 0x1000) { + cursor.pc = frame.pc; + cursor.fp = frame.fp; + m_cursors.push_back(cursor); } - if (!m_cursors.empty()) - { - lldb::addr_t first_frame_pc = m_cursors.front().pc; - if (first_frame_pc != LLDB_INVALID_ADDRESS) - { - const uint32_t resolve_scope = eSymbolContextModule | - eSymbolContextCompUnit | - eSymbolContextFunction | - eSymbolContextSymbol; - - SymbolContext first_frame_sc(first_frame->GetSymbolContext(resolve_scope)); - const AddressRange *addr_range_ptr = NULL; - AddressRange range; - if (first_frame_sc.function) - addr_range_ptr = &first_frame_sc.function->GetAddressRange(); - else if (first_frame_sc.symbol) - { - range.GetBaseAddress() = first_frame_sc.symbol->GetAddress(); - range.SetByteSize (first_frame_sc.symbol->GetByteSize()); - addr_range_ptr = ⦥ - } - - if (addr_range_ptr) - { - if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress()) - { - // We are at the first instruction, so we can recover the - // previous PC by dereferencing the SP - lldb::addr_t first_frame_sp = reg_ctx->GetSP (0); - // Read the real second frame return address into frame.pc - if (process->ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc)) - { - cursor.fp = m_cursors.front().fp; - cursor.pc = frame.pc; // Set the new second frame PC - - // Insert the second frame - m_cursors.insert(m_cursors.begin()+1, cursor); - - m_cursors.front().fp = first_frame_sp; - } - } - } + } + if (!m_cursors.empty()) { + lldb::addr_t first_frame_pc = m_cursors.front().pc; + if (first_frame_pc != LLDB_INVALID_ADDRESS) { + const uint32_t resolve_scope = + eSymbolContextModule | eSymbolContextCompUnit | + eSymbolContextFunction | eSymbolContextSymbol; + + SymbolContext first_frame_sc( + first_frame->GetSymbolContext(resolve_scope)); + const AddressRange *addr_range_ptr = NULL; + AddressRange range; + if (first_frame_sc.function) + addr_range_ptr = &first_frame_sc.function->GetAddressRange(); + else if (first_frame_sc.symbol) { + range.GetBaseAddress() = first_frame_sc.symbol->GetAddress(); + range.SetByteSize(first_frame_sc.symbol->GetByteSize()); + addr_range_ptr = ⦥ + } + + if (addr_range_ptr) { + if (first_frame->GetFrameCodeAddress() == + addr_range_ptr->GetBaseAddress()) { + // We are at the first instruction, so we can recover the + // previous PC by dereferencing the SP + lldb::addr_t first_frame_sp = reg_ctx->GetSP(0); + // Read the real second frame return address into frame.pc + if (process->ReadMemory(first_frame_sp, &frame.pc, sizeof(frame.pc), + error) == sizeof(frame.pc)) { + cursor.fp = m_cursors.front().fp; + cursor.pc = frame.pc; // Set the new second frame PC + + // Insert the second frame + m_cursors.insert(m_cursors.begin() + 1, cursor); + + m_cursors.front().fp = first_frame_sp; + } } + } } - return m_cursors.size(); + } + return m_cursors.size(); } - |