7#include "llvm/Support/Win64EH.h"
16 return static_cast<const T *
>(data_extractor.
GetData(&offset, size));
63 uint32_t unwind_info_rva)
64 : m_object_file(object_file),
65 m_unwind_info_rva(unwind_info_rva), m_unwind_code_offset{} {}
68 static constexpr int UNWIND_INFO_SIZE = 4;
101 uint32_t runtime_function_rva =
105 runtime_function_rva,
sizeof(RuntimeFunction));
108 const auto *runtime_function =
109 TypedRead<RuntimeFunction>(runtime_function_data, offset);
110 if (!runtime_function) {
147 uint32_t unwind_info_rva)
148 : m_iterator(object_file, unwind_info_rva) {}
164 static uint32_t machine_to_lldb_register[] = {
170 if (machine_reg >= std::size(machine_to_lldb_register))
173 return machine_to_lldb_register[machine_reg];
177 static uint32_t xmm_to_lldb_register[] = {
185 if (xmm_reg >= std::size(xmm_to_lldb_register))
188 return xmm_to_lldb_register[xmm_reg];
193 uint8_t unwind_operation = code.getUnwindOp();
194 uint8_t operation_info = code.getOpInfo();
196 switch (unwind_operation) {
197 case UOP_PushNonVol: {
207 case UOP_AllocLarge: {
217 case UOP_AllocSmall: {
220 static_cast<uint32_t
>(operation_info) * 8 + 8});
241 case UOP_SaveNonVolBig: {
259 case UOP_SpareCode: {
264 case UOP_SaveXMM128Big: {
279 case UOP_PushMachFrame: {
352 EHProgram::const_iterator end);
364 EHProgram::const_iterator end)
365 : m_begin(begin), m_end(end) {}
368 std::unique_ptr<UnwindPlan::Row> row = std::make_unique<UnwindPlan::Row>();
371 row->SetOffset(
m_begin->offset);
375 bool frame_pointer_found =
false;
376 for (EHProgram::const_iterator it =
m_begin; it !=
m_end; ++it) {
379 row->GetCFAValue().SetIsRegisterPlusOffset(it->reg, cfa_frame_offset -
381 frame_pointer_found =
true;
386 if (frame_pointer_found)
389 if (!frame_pointer_found)
393 int32_t rsp_frame_offset = 0;
394 for (EHProgram::const_iterator it =
m_begin; it !=
m_end; ++it) {
397 row->SetRegisterLocationToAtCFAPlusOffset(
398 it->reg, rsp_frame_offset - cfa_frame_offset,
false);
399 rsp_frame_offset += it->frame_offset;
402 rsp_frame_offset += it->frame_offset;
405 row->SetRegisterLocationToAtCFAPlusOffset(
406 it->reg, it->frame_offset - cfa_frame_offset,
false);
421 for (EHProgram::const_iterator it =
m_begin; it !=
m_end; ++it) {
425 result += it->frame_offset;
436 uint32_t exception_dir_rva,
437 uint32_t exception_dir_size)
438 : m_object_file(object_file),
439 m_exception_dir(object_file.ReadImageDataByRVA(exception_dir_rva,
440 exception_dir_size)) {}
445 const RuntimeFunction *runtime_function =
447 if (!runtime_function)
453 runtime_function->StartAddress);
471 const RuntimeFunction *runtime_function =
473 if (!runtime_function)
477 if (!builder.
Build())
480 std::vector<UnwindPlan::RowSP> rows;
485 if (it->offset == last_offset)
492 last_offset = it->offset;
495 for (
auto it = rows.rbegin(); it != rows.rend(); ++it)
500 runtime_function->EndAddress - runtime_function->StartAddress));
513 while (begin < end) {
514 uint32_t curr = (begin + end) / 2;
516 offset_t offset = curr *
sizeof(RuntimeFunction);
517 const auto *runtime_function =
519 if (!runtime_function)
522 if (runtime_function->StartAddress < rva + size &&
523 runtime_function->EndAddress > rva)
524 return runtime_function;
526 if (runtime_function->StartAddress >= rva + size)
529 if (runtime_function->EndAddress <= rva)
std::vector< EHInstruction > EHProgram
static const T * TypedRead(const DataExtractor &data_extractor, offset_t &offset, offset_t size=sizeof(T))
static uint32_t ConvertXMMToLLDBRegister(uint8_t xmm_reg)
const EHProgram & GetProgram() const
static uint32_t ConvertMachineToLLDBRegister(uint8_t machine_reg)
bool ProcessUnwindCode(UnwindCode code)
EHProgramBuilder(ObjectFilePECOFF &object_file, uint32_t unwind_info_rva)
UnwindCodesIterator m_iterator
bool ParseFrameOffset(uint32_t &result)
bool ParseBigOrScaledFrameOffset(uint32_t &result, bool big, uint32_t scale)
bool ParseBigFrameOffset(uint32_t &result)
EHProgramRange(EHProgram::const_iterator begin, EHProgram::const_iterator end)
std::unique_ptr< UnwindPlan::Row > BuildUnwindPlanRow() const
EHProgram::const_iterator m_end
EHProgram::const_iterator m_begin
int32_t GetCFAFrameOffset() const
lldb_private::DataExtractor ReadImageDataByRVA(uint32_t rva, size_t size)
lldb_private::Address GetAddress(uint32_t rva)
uint32_t GetRVA(const lldb_private::Address &addr) const
bool GetAddressRange(lldb_private::Address addr, lldb_private::AddressRange &range) override
ObjectFilePECOFF & m_object_file
bool GetUnwindPlan(const lldb_private::Address &addr, lldb_private::UnwindPlan &unwind_plan) override
const llvm::Win64EH::RuntimeFunction * FindRuntimeFunctionIntersectsWithRange(const lldb_private::AddressRange &range) const
PECallFrameInfo(ObjectFilePECOFF &object_file, uint32_t exception_dir_rva, uint32_t exception_dir_size)
lldb_private::DataExtractor m_exception_dir
DataExtractor m_unwind_info_data
uint32_t m_unwind_info_rva
ObjectFilePECOFF & m_object_file
const UnwindInfo * GetUnwindInfo() const
DataExtractor m_unwind_code_data
offset_t m_unwind_code_offset
const UnwindInfo * m_unwind_info
UnwindCodesIterator(ObjectFilePECOFF &object_file, uint32_t unwind_info_rva)
const UnwindCode * m_unwind_code
const UnwindCode * GetUnwindCode() const
A section + offset based address range class.
Address & GetBaseAddress()
Get accessor for the base address of the range.
void Clear()
Clear the object's state.
void SetByteSize(lldb::addr_t byte_size)
Set accessor for the byte size of this range.
lldb::addr_t GetByteSize() const
Get accessor for the byte size of this range.
A section + offset based address class.
void SetRegisterKind(lldb::RegisterKind kind)
void SetPlanValidAddressRange(const AddressRange &range)
void AppendRow(const RowSP &row_sp)
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
void SetSourceName(const char *)
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
#define LLDB_INVALID_REGNUM
A class that represents a running process on the host machine.
@ eRegisterKindLLDB
lldb's internal register numbers
@ SET_FRAME_POINTER_REGISTER