12#include "llvm-c/Disassembler.h"
13#include "llvm/ADT/STLExtras.h"
14#include "llvm/Support/TargetSelect.h"
52 if (process_sp.get() ==
nullptr)
54 std::vector<uint8_t> function_text(func.
GetByteSize());
56 if (process_sp->GetTarget().ReadMemory(
62 function_text.data(), func.
GetByteSize(), func, unwind_plan);
69 bool do_augment_unwindplan =
true;
76 if (process_sp.get() ==
nullptr)
79 wordsize = process_sp->GetTarget().GetArchitecture().GetAddressByteSize();
92 if (first_row->GetCFAValue().GetValueType() !=
95 first_row->GetCFAValue().GetRegisterNumber()) !=
97 first_row->GetCFAValue().GetOffset() != wordsize) {
101 if (!first_row->GetRegisterInfo(
105 first_row_pc_loc.
GetOffset() != -wordsize) {
112 if (first_row != last_row &&
113 first_row->GetOffset() != last_row->GetOffset()) {
120 if (first_row->GetCFAValue().GetValueType() ==
121 last_row->GetCFAValue().GetValueType() &&
122 first_row->GetCFAValue().GetRegisterNumber() ==
123 last_row->GetCFAValue().GetRegisterNumber() &&
124 first_row->GetCFAValue().GetOffset() ==
125 last_row->GetCFAValue().GetOffset()) {
130 if (last_row->GetRegisterInfo(
142 if (first_row_pc_loc.
GetOffset() == -wordsize) {
150 if (do_augment_unwindplan) {
155 std::vector<uint8_t> function_text(func.
GetByteSize());
157 if (process_sp->GetTarget().ReadMemory(
163 function_text.data(), func.
GetByteSize(), func, unwind_plan, reg_ctx);
181 llvm::SmallVector<uint8_t, 4> opcode_data;
185 Target &target(process_sp->GetTarget());
189 uint8_t i386_push_mov[] = {0x55, 0x89, 0xe5};
190 uint8_t x86_64_push_mov[] = {0x55, 0x48, 0x89, 0xe5};
192 if (memcmp(opcode_data.data(), i386_push_mov,
sizeof(i386_push_mov)) ==
194 memcmp(opcode_data.data(), x86_64_push_mov,
195 sizeof(x86_64_push_mov)) == 0) {
196 ABISP abi_sp = process_sp->GetABI();
198 return abi_sp->CreateDefaultUnwindPlan(unwind_plan);
208 Address &first_non_prologue_insn) {
214 if (target ==
nullptr)
220 std::vector<uint8_t> function_text(func.
GetByteSize());
226 function_text.data(), func.
GetByteSize(), offset)) {
228 first_non_prologue_insn.
Slide(offset);
236 const llvm::Triple::ArchType cpu = arch.
GetMachine();
237 if (cpu == llvm::Triple::x86 || cpu == llvm::Triple::x86_64)
252 return "i386 and x86_64 assembly language profiler plugin.";
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
A class to represent register numbers, and able to convert between different register numbering schem...
uint32_t GetAsKind(lldb::RegisterKind kind)
static llvm::StringRef GetPluginDescriptionStatic()
~UnwindAssembly_x86() override
static llvm::StringRef GetPluginNameStatic()
bool GetFastUnwindPlan(lldb_private::AddressRange &func, lldb_private::Thread &thread, lldb_private::UnwindPlan &unwind_plan) override
bool AugmentUnwindPlanFromCallSite(lldb_private::AddressRange &func, lldb_private::Thread &thread, lldb_private::UnwindPlan &unwind_plan) override
static lldb_private::UnwindAssembly * CreateInstance(const lldb_private::ArchSpec &arch)
lldb_private::x86AssemblyInspectionEngine * m_assembly_inspection_engine
bool GetNonCallSiteUnwindPlanFromAssembly(lldb_private::AddressRange &func, lldb_private::Thread &thread, lldb_private::UnwindPlan &unwind_plan) override
bool FirstNonPrologueInsn(lldb_private::AddressRange &func, const lldb_private::ExecutionContext &exe_ctx, lldb_private::Address &first_non_prologue_insn) override
A section + offset based address range class.
Address & GetBaseAddress()
Get accessor for the base address of the range.
lldb::addr_t GetByteSize() const
Get accessor for the byte size of this range.
A section + offset based address class.
bool Slide(int64_t offset)
bool IsValid() const
Check if the object state is valid.
An architecture specification class.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
Target * GetTargetPtr() const
Returns a pointer to the target object.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
virtual size_t ReadMemory(const Address &addr, void *dst, size_t dst_len, Status &error, bool force_live_memory=false, lldb::addr_t *load_addr_ptr=nullptr)
virtual lldb::RegisterContextSP GetRegisterContext()=0
lldb::ProcessSP GetProcess() const
bool IsAtCFAPlusOffset() const
int32_t GetOffset() const
UnwindPlan::RowSP GetRowForFunctionOffset(int offset) const
lldb::RegisterKind GetRegisterKind() const
std::shared_ptr< Row > RowSP
bool FindFirstNonPrologueInstruction(uint8_t *data, size_t size, size_t &offset)
bool AugmentUnwindPlanFromCallSite(uint8_t *data, size_t size, lldb_private::AddressRange &func_range, lldb_private::UnwindPlan &unwind_plan, lldb::RegisterContextSP ®_ctx)
Take an existing UnwindPlan, probably from eh_frame which may be missing description of the epilogue ...
void Initialize(lldb::RegisterContextSP ®_ctx)
One of the two initialize methods that can be called on this object; they must be called before any o...
bool GetNonCallSiteUnwindPlanFromAssembly(uint8_t *data, size_t size, lldb_private::AddressRange &func_range, lldb_private::UnwindPlan &unwind_plan)
Create an UnwindPlan for a "non-call site" stack frame situation.
#define LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_PC
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target