forked from OSchip/llvm-project
[lldb] Delete UnwindMacOSXFrameBackchain
Summary: It isn't used anywhere (except on imaginary triples like sparc-apple-ios) and it also violates plugin separation. This patch deletes it and declares UnwindLLDB to be _the_ lldb unwinder. Reviewers: jasonmolenda, JDevlieghere, xiaobai Subscribers: jyknight, mgorny, krytarowski, fedor.sergeev, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D75680
This commit is contained in:
parent
45e2c6d956
commit
71c1c18474
|
@ -27,7 +27,6 @@ add_lldb_library(lldbPluginProcessUtility
|
|||
RegisterContextLinux_mips.cpp
|
||||
RegisterContextLinux_s390x.cpp
|
||||
RegisterContextLLDB.cpp
|
||||
RegisterContextMacOSXFrameBackchain.cpp
|
||||
RegisterContextMach_arm.cpp
|
||||
RegisterContextMach_i386.cpp
|
||||
RegisterContextMach_x86_64.cpp
|
||||
|
@ -52,7 +51,6 @@ add_lldb_library(lldbPluginProcessUtility
|
|||
StopInfoMachException.cpp
|
||||
ThreadMemory.cpp
|
||||
UnwindLLDB.cpp
|
||||
UnwindMacOSXFrameBackchain.cpp
|
||||
|
||||
LINK_LIBS
|
||||
lldbBreakpoint
|
||||
|
|
|
@ -1,160 +0,0 @@
|
|||
//===-- RegisterContextMacOSXFrameBackchain.cpp ---------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "RegisterContextMacOSXFrameBackchain.h"
|
||||
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Utility/DataBufferHeap.h"
|
||||
#include "lldb/Utility/DataExtractor.h"
|
||||
#include "lldb/Utility/RegisterValue.h"
|
||||
#include "lldb/Utility/Scalar.h"
|
||||
#include "lldb/Utility/StreamString.h"
|
||||
#include "lldb/Utility/StringExtractorGDBRemote.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
// RegisterContextMacOSXFrameBackchain constructor
|
||||
RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain(
|
||||
Thread &thread, uint32_t concrete_frame_idx,
|
||||
const UnwindMacOSXFrameBackchain::Cursor &cursor)
|
||||
: RegisterContext(thread, concrete_frame_idx), m_cursor(cursor),
|
||||
m_cursor_is_valid(true) {}
|
||||
|
||||
// Destructor
|
||||
RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain() {}
|
||||
|
||||
void RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters() {
|
||||
m_cursor_is_valid = false;
|
||||
}
|
||||
|
||||
size_t RegisterContextMacOSXFrameBackchain::GetRegisterCount() {
|
||||
return m_thread.GetRegisterContext()->GetRegisterCount();
|
||||
}
|
||||
|
||||
const RegisterInfo *
|
||||
RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex(size_t reg) {
|
||||
return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
|
||||
}
|
||||
|
||||
size_t RegisterContextMacOSXFrameBackchain::GetRegisterSetCount() {
|
||||
return m_thread.GetRegisterContext()->GetRegisterSetCount();
|
||||
}
|
||||
|
||||
const RegisterSet *
|
||||
RegisterContextMacOSXFrameBackchain::GetRegisterSet(size_t reg_set) {
|
||||
return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
|
||||
}
|
||||
|
||||
bool RegisterContextMacOSXFrameBackchain::ReadRegister(
|
||||
const RegisterInfo *reg_info, RegisterValue &value) {
|
||||
if (!m_cursor_is_valid)
|
||||
return false;
|
||||
|
||||
uint64_t reg_value = LLDB_INVALID_ADDRESS;
|
||||
|
||||
switch (reg_info->kinds[eRegisterKindGeneric]) {
|
||||
case LLDB_REGNUM_GENERIC_PC:
|
||||
if (m_cursor.pc == LLDB_INVALID_ADDRESS)
|
||||
return false;
|
||||
reg_value = m_cursor.pc;
|
||||
break;
|
||||
|
||||
case LLDB_REGNUM_GENERIC_FP:
|
||||
if (m_cursor.fp == LLDB_INVALID_ADDRESS)
|
||||
return false;
|
||||
reg_value = m_cursor.fp;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (reg_info->encoding) {
|
||||
case eEncodingInvalid:
|
||||
case eEncodingVector:
|
||||
break;
|
||||
|
||||
case eEncodingUint:
|
||||
case eEncodingSint:
|
||||
value.SetUInt(reg_value, reg_info->byte_size);
|
||||
return true;
|
||||
|
||||
case eEncodingIEEE754:
|
||||
switch (reg_info->byte_size) {
|
||||
case sizeof(float):
|
||||
if (sizeof(float) == sizeof(uint32_t)) {
|
||||
value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
|
||||
return true;
|
||||
} else if (sizeof(float) == sizeof(uint64_t)) {
|
||||
value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case sizeof(double):
|
||||
if (sizeof(double) == sizeof(uint32_t)) {
|
||||
value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
|
||||
return true;
|
||||
} else if (sizeof(double) == sizeof(uint64_t)) {
|
||||
value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
// TOOD: need a better way to detect when "long double" types are
|
||||
// the same bytes size as "double"
|
||||
#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && \
|
||||
!defined(_MSC_VER) && !defined(__mips__) && !defined(__powerpc__) && \
|
||||
!defined(__ANDROID__)
|
||||
case sizeof(long double):
|
||||
if (sizeof(long double) == sizeof(uint32_t)) {
|
||||
value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
|
||||
return true;
|
||||
} else if (sizeof(long double) == sizeof(uint64_t)) {
|
||||
value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RegisterContextMacOSXFrameBackchain::WriteRegister(
|
||||
const RegisterInfo *reg_info, const RegisterValue &value) {
|
||||
// Not supported yet. We could easily add support for this by remembering the
|
||||
// address of each entry (it would need to be part of the cursor)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues(
|
||||
lldb::DataBufferSP &data_sp) {
|
||||
// libunwind frames can't handle this it doesn't always have all register
|
||||
// values. This call should only be called on frame zero anyway so there
|
||||
// shouldn't be any problem
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues(
|
||||
const lldb::DataBufferSP &data_sp) {
|
||||
// Since this class doesn't respond to "ReadAllRegisterValues()", it must not
|
||||
// have been the one that saved all the register values. So we just let the
|
||||
// thread's register context (the register context for frame zero) do the
|
||||
// writing.
|
||||
return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber(
|
||||
lldb::RegisterKind kind, uint32_t num) {
|
||||
return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
|
||||
kind, num);
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
//===-- RegisterContextMacOSXFrameBackchain.h -------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACOSXFRAMEBACKCHAIN_H
|
||||
#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACOSXFRAMEBACKCHAIN_H
|
||||
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/lldb-private.h"
|
||||
|
||||
#include "UnwindMacOSXFrameBackchain.h"
|
||||
|
||||
class RegisterContextMacOSXFrameBackchain
|
||||
: public lldb_private::RegisterContext {
|
||||
public:
|
||||
RegisterContextMacOSXFrameBackchain(
|
||||
lldb_private::Thread &thread, uint32_t concrete_frame_idx,
|
||||
const UnwindMacOSXFrameBackchain::Cursor &cursor);
|
||||
|
||||
~RegisterContextMacOSXFrameBackchain() override;
|
||||
|
||||
void InvalidateAllRegisters() override;
|
||||
|
||||
size_t GetRegisterCount() override;
|
||||
|
||||
const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
|
||||
|
||||
size_t GetRegisterSetCount() override;
|
||||
|
||||
const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
|
||||
|
||||
bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
|
||||
lldb_private::RegisterValue &value) override;
|
||||
|
||||
bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
|
||||
const lldb_private::RegisterValue &value) override;
|
||||
|
||||
bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
|
||||
|
||||
bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
|
||||
|
||||
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
|
||||
uint32_t num) override;
|
||||
|
||||
private:
|
||||
UnwindMacOSXFrameBackchain::Cursor m_cursor;
|
||||
bool m_cursor_is_valid;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RegisterContextMacOSXFrameBackchain);
|
||||
};
|
||||
|
||||
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACOSXFRAMEBACKCHAIN_H
|
|
@ -1,247 +0,0 @@
|
|||
//===-- UnwindMacOSXFrameBackchain.cpp ------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Symbol/Function.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"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Utility/ArchSpec.h"
|
||||
|
||||
#include "RegisterContextMacOSXFrameBackchain.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
return m_cursors.size();
|
||||
}
|
||||
|
||||
bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(
|
||||
uint32_t idx, addr_t &cfa, addr_t &pc, bool &behaves_like_zeroth_frame) {
|
||||
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;
|
||||
behaves_like_zeroth_frame = (idx == 0);
|
||||
|
||||
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 = std::make_shared<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 == nullptr)
|
||||
return 0;
|
||||
|
||||
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);
|
||||
Status 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 SymbolContextItem resolve_scope =
|
||||
eSymbolContextModule | eSymbolContextCompUnit |
|
||||
eSymbolContextFunction | eSymbolContextSymbol;
|
||||
|
||||
SymbolContext first_frame_sc(
|
||||
first_frame->GetSymbolContext(resolve_scope));
|
||||
const AddressRange *addr_range_ptr = nullptr;
|
||||
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();
|
||||
}
|
||||
|
||||
size_t UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64(
|
||||
const ExecutionContext &exe_ctx) {
|
||||
m_cursors.clear();
|
||||
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
if (process == nullptr)
|
||||
return 0;
|
||||
|
||||
StackFrame *first_frame = exe_ctx.GetFramePtr();
|
||||
|
||||
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);
|
||||
Status 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 SymbolContextItem resolve_scope =
|
||||
eSymbolContextModule | eSymbolContextCompUnit |
|
||||
eSymbolContextFunction | eSymbolContextSymbol;
|
||||
|
||||
SymbolContext first_frame_sc(
|
||||
first_frame->GetSymbolContext(resolve_scope));
|
||||
const AddressRange *addr_range_ptr = nullptr;
|
||||
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();
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
//===-- UnwindMacOSXFrameBackchain.h ----------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_UNWINDMACOSXFRAMEBACKCHAIN_H
|
||||
#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_UNWINDMACOSXFRAMEBACKCHAIN_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "lldb/Target/Unwind.h"
|
||||
#include "lldb/lldb-private.h"
|
||||
|
||||
class UnwindMacOSXFrameBackchain : public lldb_private::Unwind {
|
||||
public:
|
||||
UnwindMacOSXFrameBackchain(lldb_private::Thread &thread);
|
||||
|
||||
~UnwindMacOSXFrameBackchain() override = default;
|
||||
|
||||
protected:
|
||||
void DoClear() override { m_cursors.clear(); }
|
||||
|
||||
uint32_t DoGetFrameCount() override;
|
||||
|
||||
bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
|
||||
lldb::addr_t &pc,
|
||||
bool &behaves_like_zeroth_frame) override;
|
||||
|
||||
lldb::RegisterContextSP
|
||||
DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
|
||||
|
||||
friend class RegisterContextMacOSXFrameBackchain;
|
||||
|
||||
struct Cursor {
|
||||
lldb::addr_t pc; // Program counter
|
||||
lldb::addr_t fp; // Frame pointer for us with backchain
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<Cursor> m_cursors;
|
||||
|
||||
size_t GetStackFrameData_i386(const lldb_private::ExecutionContext &exe_ctx);
|
||||
|
||||
size_t
|
||||
GetStackFrameData_x86_64(const lldb_private::ExecutionContext &exe_ctx);
|
||||
|
||||
// For UnwindMacOSXFrameBackchain only
|
||||
DISALLOW_COPY_AND_ASSIGN(UnwindMacOSXFrameBackchain);
|
||||
};
|
||||
|
||||
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_UNWINDMACOSXFRAMEBACKCHAIN_H
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "Plugins/Process/Utility/UnwindLLDB.h"
|
||||
#include "Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h"
|
||||
#include "lldb/Breakpoint/BreakpointLocation.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/FormatEntity.h"
|
||||
|
@ -2101,35 +2100,8 @@ size_t Thread::GetStackFrameStatus(Stream &strm, uint32_t first_frame,
|
|||
}
|
||||
|
||||
Unwind *Thread::GetUnwinder() {
|
||||
if (!m_unwinder_up) {
|
||||
const ArchSpec target_arch(CalculateTarget()->GetArchitecture());
|
||||
const llvm::Triple::ArchType machine = target_arch.GetMachine();
|
||||
switch (machine) {
|
||||
case llvm::Triple::x86_64:
|
||||
case llvm::Triple::x86:
|
||||
case llvm::Triple::arm:
|
||||
case llvm::Triple::aarch64:
|
||||
case llvm::Triple::aarch64_32:
|
||||
case llvm::Triple::thumb:
|
||||
case llvm::Triple::mips:
|
||||
case llvm::Triple::mipsel:
|
||||
case llvm::Triple::mips64:
|
||||
case llvm::Triple::mips64el:
|
||||
case llvm::Triple::ppc:
|
||||
case llvm::Triple::ppc64:
|
||||
case llvm::Triple::ppc64le:
|
||||
case llvm::Triple::systemz:
|
||||
case llvm::Triple::hexagon:
|
||||
case llvm::Triple::arc:
|
||||
m_unwinder_up.reset(new UnwindLLDB(*this));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (target_arch.GetTriple().getVendor() == llvm::Triple::Apple)
|
||||
m_unwinder_up.reset(new UnwindMacOSXFrameBackchain(*this));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!m_unwinder_up)
|
||||
m_unwinder_up.reset(new UnwindLLDB(*this));
|
||||
return m_unwinder_up.get();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue