7#include "llvm/Support/Win64EH.h"
16 return static_cast<const T *
>(data_extractor.
GetData(&offset, size));
63 uint32_t unwind_info_rva)
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 =
110 if (!runtime_function) {
147 uint32_t 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];
192 uint8_t o =
m_iterator.IsChained() ? 0 : code.u.CodeOffset;
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});
225 if (
m_iterator.GetUnwindInfo()->getFrameRegister())
227 m_iterator.GetUnwindInfo()->getFrameRegister());
232 static_cast<uint32_t
>(
m_iterator.GetUnwindInfo()->getFrameOffset()) *
241 case UOP_SaveNonVolBig: {
259 case UOP_SpareCode: {
264 case UOP_SaveXMM128Big: {
279 case UOP_PushMachFrame: {
329 result =
m_iterator.GetUnwindCode()->FrameOffset;
334 result +=
static_cast<uint32_t
>(
m_iterator.GetUnwindCode()->FrameOffset)
344 result =
m_iterator.GetUnwindCode()->FrameOffset;
352 EHProgram::const_iterator end);
364 EHProgram::const_iterator end)
375 bool frame_pointer_found =
false;
376 for (EHProgram::const_iterator it =
m_begin; it !=
m_end; ++it) {
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) {
398 it->reg, rsp_frame_offset - cfa_frame_offset,
false);
399 rsp_frame_offset += it->frame_offset;
402 rsp_frame_offset += it->frame_offset;
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)
440 exception_dir_size)) {}
445 const RuntimeFunction *runtime_function =
447 if (!runtime_function)
453 runtime_function->StartAddress);
459 llvm::ArrayRef<lldb_private::AddressRange> ranges,
462 if (ranges.size() != 1)
466 const RuntimeFunction *runtime_function =
468 if (!runtime_function)
472 plan_up->SetSourceName(
"PE EH info");
476 if (!builder.
Build())
479 std::vector<UnwindPlan::Row> rows;
484 if (it->offset == last_offset)
491 last_offset = it->offset;
494 for (
auto it = rows.rbegin(); it != rows.rend(); ++it)
495 plan_up->AppendRow(std::move(*it));
499 runtime_function->EndAddress - runtime_function->StartAddress)});
500 plan_up->SetUnwindPlanValidAtAllInstructions(
eLazyBoolNo);
511 uint32_t end =
m_exception_dir.GetByteSize() /
sizeof(RuntimeFunction);
512 while (begin < end) {
513 uint32_t curr = (begin + end) / 2;
515 offset_t offset = curr *
sizeof(RuntimeFunction);
516 const auto *runtime_function =
518 if (!runtime_function)
521 if (runtime_function->StartAddress < rva + size &&
522 runtime_function->EndAddress > rva)
523 return runtime_function;
525 if (runtime_function->StartAddress >= rva + size)
528 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)
UnwindPlan::Row BuildUnwindPlanRow() const
EHProgram::const_iterator m_end
EHProgram::const_iterator m_begin
int32_t GetCFAFrameOffset() const
bool GetAddressRange(lldb_private::Address addr, lldb_private::AddressRange &range) override
ObjectFilePECOFF & m_object_file
std::unique_ptr< lldb_private::UnwindPlan > GetUnwindPlan(const lldb_private::Address &addr) 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 SetIsRegisterPlusOffset(uint32_t reg_num, int32_t offset)
bool SetRegisterLocationToIsCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
void SetOffset(int64_t offset)
bool SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
const FAValue & GetCFAValue() const
#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