11#include "llvm/ADT/STLExtras.h"
12#include "llvm/ADT/StringSwitch.h"
13#include "llvm/TargetParser/Triple.h"
117 if (arch.
GetTriple().getArch() == llvm::Triple::x86_64 &&
127 llvm::ArrayRef<addr_t> args)
const {
132 s.
Printf(
"ABIWindows_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
133 ", sp = 0x%" PRIx64
", func_addr = 0x%" PRIx64
134 ", return_addr = 0x%" PRIx64,
135 thread.
GetID(), (uint64_t)
sp, (uint64_t)func_addr,
136 (uint64_t)return_addr);
138 for (
size_t i = 0; i < args.size(); ++i)
139 s.
Printf(
", arg%" PRIu64
" = 0x%" PRIx64,
static_cast<uint64_t
>(i + 1),
154 for (
size_t i = 0; i < args.size(); ++i) {
157 LLDB_LOGF(log,
"About to write arg%" PRIu64
" (0x%" PRIx64
") into %s",
158 static_cast<uint64_t
>(i + 1), args[i], reg_info->
name);
165 LLDB_LOGF(log,
"16-byte aligning SP: 0x%" PRIx64
" to 0x%" PRIx64,
166 (uint64_t)
sp, (uint64_t)(
sp & ~0xfull));
181 "Pushing the return address onto the stack: 0x%" PRIx64
183 (uint64_t)
sp, (uint64_t)return_addr);
186 if (!process_sp->WritePointerToMemory(
sp, return_addr,
error))
191 LLDB_LOGF(log,
"Writing SP: 0x%" PRIx64, (uint64_t)
sp);
198 LLDB_LOGF(log,
"Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
207 bool is_signed,
Thread &thread,
208 uint32_t *argument_register_ids,
209 unsigned int ¤t_argument_register,
210 addr_t ¤t_stack_argument) {
214 if (current_argument_register < 4) {
216 argument_register_ids[current_argument_register], 0);
217 current_argument_register++;
222 uint32_t byte_size = (bit_width + (CHAR_BIT - 1)) / CHAR_BIT;
224 if (thread.
GetProcess()->ReadScalarIntegerFromMemory(
225 current_stack_argument, byte_size, is_signed, scalar,
error)) {
226 current_stack_argument += byte_size;
234 unsigned int num_values = values.
GetSize();
235 unsigned int value_index;
252 addr_t current_stack_argument =
sp + 8;
254 uint32_t argument_register_ids[4];
256 argument_register_ids[0] =
259 argument_register_ids[1] =
262 argument_register_ids[2] =
265 argument_register_ids[3] =
269 unsigned int current_argument_register = 0;
271 for (value_index = 0; value_index < num_values; ++value_index) {
278 std::optional<uint64_t> bit_size = compiler_type.
GetBitSize(&thread);
285 argument_register_ids, current_argument_register,
286 current_stack_argument);
289 argument_register_ids, current_argument_register,
290 current_stack_argument);
301 error.SetErrorString(
"Empty value object for return value.");
305 CompilerType compiler_type = new_value_sp->GetCompilerType();
306 if (!compiler_type) {
307 error.SetErrorString(
"Null clang type for return value.");
311 Thread *thread = frame_sp->GetThread().get();
319 bool set_it_simple =
false;
326 size_t num_bytes = new_value_sp->GetData(data, data_error);
327 if (data_error.
Fail()) {
328 error.SetErrorStringWithFormat(
329 "Couldn't convert return value to raw data: %s",
334 if (num_bytes <= 8) {
335 uint64_t raw_value = data.
GetMaxU64(&offset, num_bytes);
338 set_it_simple =
true;
340 error.SetErrorString(
"We don't support returning longer than 64 bit "
341 "integer values at present.");
345 error.SetErrorString(
346 "We don't support returning complex values at present");
348 std::optional<uint64_t> bit_width =
351 error.SetErrorString(
"can't get type size");
354 if (*bit_width <= 64) {
360 size_t num_bytes = new_value_sp->GetData(data, data_error);
361 if (data_error.
Fail()) {
362 error.SetErrorStringWithFormat(
363 "Couldn't convert return value to raw data: %s",
368 unsigned char buffer[16];
372 xmm0_value.
SetBytes(buffer, 16, byte_order);
374 set_it_simple =
true;
377 error.SetErrorString(
378 "Windows-x86_64 doesn't allow FP larger than 64 bits.");
383 if (!set_it_simple) {
390 error.SetErrorString(
"We only support setting simple integer and float "
391 "return types at present.");
402 if (!return_compiler_type)
403 return return_valobj_sp;
409 return return_valobj_sp;
411 const uint32_t type_flags = return_compiler_type.
GetTypeInfo();
412 if (type_flags & eTypeIsScalar) {
415 bool success =
false;
416 if (type_flags & eTypeIsInteger) {
418 std::optional<uint64_t> byte_size =
421 return return_valobj_sp;
424 const bool is_signed = (type_flags & eTypeIsSigned) != 0;
425 switch (*byte_size) {
429 case sizeof(uint64_t):
431 value.
GetScalar() = (int64_t)(raw_value);
433 value.
GetScalar() = (uint64_t)(raw_value);
437 case sizeof(uint32_t):
445 case sizeof(uint16_t):
447 value.
GetScalar() = (int16_t)(raw_value & UINT16_MAX);
449 value.
GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
453 case sizeof(uint8_t):
455 value.
GetScalar() = (int8_t)(raw_value & UINT8_MAX);
457 value.
GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
461 }
else if (type_flags & eTypeIsFloat) {
462 if (type_flags & eTypeIsComplex) {
465 std::optional<uint64_t> byte_size =
467 if (byte_size && *byte_size <=
sizeof(
long double)) {
473 if (xmm0_value.
GetData(data)) {
475 if (*byte_size ==
sizeof(
float)) {
478 }
else if (*byte_size ==
sizeof(
double)) {
492 }
else if ((type_flags & eTypeIsPointer) ||
493 (type_flags & eTypeInstanceIsPointer)) {
502 }
else if (type_flags & eTypeIsVector) {
503 std::optional<uint64_t> byte_size =
505 if (byte_size && *byte_size > 0) {
508 if (xmm_reg ==
nullptr)
512 if (*byte_size <= xmm_reg->byte_size) {
515 std::unique_ptr<DataBufferHeap> heap_data_up(
517 const ByteOrder byte_order = process_sp->GetByteOrder();
522 heap_data_up->GetByteSize(),
523 byte_order,
error)) {
526 process_sp->GetTarget()
528 .GetAddressByteSize());
530 &thread, return_compiler_type,
ConstString(
""), data);
539 return return_valobj_sp;
550 uint32_t data_byte_offset,
551 std::vector<uint32_t> &aggregate_field_offsets,
552 std::vector<CompilerType> &aggregate_compiler_types) {
554 const uint32_t num_children = return_compiler_type.
GetNumFields();
555 for (uint32_t idx = 0; idx < num_children; ++idx) {
561 uint64_t field_bit_offset = 0;
563 idx, name, &field_bit_offset,
nullptr,
nullptr);
564 std::optional<uint64_t> field_bit_width =
568 if (!field_bit_width || *field_bit_width == 0) {
572 if (field_bit_offset % *field_bit_width != 0) {
577 uint32_t field_byte_offset = field_bit_offset / 8 + data_byte_offset;
579 const uint32_t field_type_flags = field_compiler_type.
GetTypeInfo();
583 aggregate_field_offsets.push_back(field_byte_offset);
584 aggregate_compiler_types.push_back(field_compiler_type);
585 }
else if (field_type_flags & eTypeHasChildren) {
587 field_byte_offset, aggregate_field_offsets,
588 aggregate_compiler_types)) {
600 if (!return_compiler_type) {
601 return return_valobj_sp;
606 if (return_valobj_sp) {
607 return return_valobj_sp;
612 return return_valobj_sp;
615 std::optional<uint64_t> bit_width = return_compiler_type.
GetBitSize(&thread);
617 return return_valobj_sp;
622 return return_valobj_sp;
627 uint32_t max_register_value_bit_width = 64;
637 bool is_memory = *bit_width > max_register_value_bit_width ||
638 *bit_width & (*bit_width - 1);
639 std::vector<uint32_t> aggregate_field_offsets;
640 std::vector<CompilerType> aggregate_compiler_types;
643 0, aggregate_field_offsets,
644 aggregate_compiler_types)) {
653 reg_ctx_sp->GetRegisterInfoByName(
"rax", 0);
655 reg_ctx_sp->ReadRegister(rax_info, rax_value);
659 uint32_t used_bytes =
664 if (aggregate_field_offsets.size())
665 used_bytes = aggregate_field_offsets[0];
667 const uint32_t num_children = aggregate_compiler_types.size();
668 for (uint32_t idx = 0; idx < num_children; idx++) {
673 CompilerType field_compiler_type = aggregate_compiler_types[idx];
674 uint32_t field_byte_width = (uint32_t) (*field_compiler_type.
GetByteSize(&thread));
675 uint32_t field_byte_offset = aggregate_field_offsets[idx];
679 if (used_bytes >= 8 || used_bytes + field_byte_width > 8) {
680 return return_valobj_sp;
684 uint32_t copy_from_offset = 0;
688 copy_from_extractor = &rax_data;
689 copy_from_offset = used_bytes;
690 used_bytes += field_byte_width;
695 if (!copy_from_extractor) {
696 return return_valobj_sp;
698 if (copy_from_offset + field_byte_width >
700 return return_valobj_sp;
703 field_byte_width, data_sp->GetBytes() + field_byte_offset,
704 field_byte_width, byte_order);
710 &thread, return_compiler_type,
ConstString(
""), return_ext);
730 &thread,
"",
Address(storage_addr,
nullptr), return_compiler_type);
732 return return_valobj_sp;
747 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
748 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8,
false);
749 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0,
true);
769 const int32_t ptr_size = 8;
770 row->GetCFAValue().SetIsRegisterPlusOffset(
dwarf_rbp, 2 * ptr_size);
772 row->SetUnspecifiedRegistersAreUndefined(
true);
774 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2,
true);
775 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1,
true);
776 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0,
true);
793 assert(reg_info->
name !=
nullptr &&
"unnamed register?");
794 std::string Name = std::string(reg_info->
name);
796 llvm::StringSwitch<bool>(Name)
797 .Cases(
"rbx",
"ebx",
"rbp",
"ebp",
"rdi",
"edi",
"rsi",
"esi",
true)
798 .Cases(
"rsp",
"esp",
"r12",
"r13",
"r14",
"r15",
"sp",
"fp",
true)
799 .Cases(
"xmm6",
"xmm7",
"xmm8",
"xmm9",
"xmm10",
"xmm11",
"xmm12",
800 "xmm13",
"xmm14",
"xmm15",
true)
802 return IsCalleeSaved;
806 return llvm::StringSwitch<uint32_t>(reg)
static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, bool is_signed, Thread &thread, uint32_t *argument_register_ids, unsigned int ¤t_argument_register, addr_t ¤t_stack_argument)
static bool FlattenAggregateType(Thread &thread, ExecutionContext &exe_ctx, CompilerType &return_compiler_type, uint32_t data_byte_offset, std::vector< uint32_t > &aggregate_field_offsets, std::vector< CompilerType > &aggregate_compiler_types)
static bool FlattenAggregateType(Thread &thread, ExecutionContext &exe_ctx, CompilerType &return_compiler_type, uint32_t data_byte_offset, std::vector< uint32_t > &aggregate_field_offsets, std::vector< CompilerType > &aggregate_compiler_types)
static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, bool is_signed, Thread &thread, uint32_t *argument_register_ids, unsigned int ¤t_argument_register, addr_t ¤t_stack_argument)
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
#define LLDB_PLUGIN_DEFINE(PluginName)
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
static llvm::StringRef GetPluginNameStatic()
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
lldb::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
bool GetPointerReturnRegister(const char *&name) override
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
size_t GetRedZoneSize() const override
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, lldb::addr_t functionAddress, lldb::addr_t returnAddress, llvm::ArrayRef< lldb::addr_t > args) const override
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info)
uint32_t GetGenericNum(llvm::StringRef reg) override
Return the generic number of the given register.
static std::unique_ptr< llvm::MCRegisterInfo > MakeMCRegisterInfo(const ArchSpec &arch)
Utility function to construct a MCRegisterInfo using the ArchSpec triple.
A section + offset based address class.
An architecture specification class.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
llvm::Triple & GetTriple()
Architecture triple accessor.
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Generic representation of a type in a programming language.
std::optional< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
CompilerType GetFieldAtIndex(size_t idx, std::string &name, uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) const
bool IsFloatingPointType(uint32_t &count, bool &is_complex) const
uint32_t GetNumFields() const
bool IsIntegerOrEnumerationType(bool &is_signed) const
bool IsAggregateType() const
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
std::optional< uint64_t > GetBitSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bits.
bool IsPointerType(CompilerType *pointee_type=nullptr) const
A uniqued constant string class.
A subclass of DataBuffer that stores a data buffer on the heap.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
Target * GetTargetPtr() const
Returns a pointer to the target object.
void PutString(llvm::StringRef str)
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
uint64_t GetSP(uint64_t fail_value=LLDB_INVALID_ADDRESS)
virtual bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value)=0
const RegisterInfo * GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num)
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value)=0
bool GetData(DataExtractor &data) const
uint32_t GetAsMemoryData(const RegisterInfo ®_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
bool SignExtend(uint32_t bit_pos)
bool Fail() const
Test for error condition.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
const ArchSpec & GetArchitecture() const
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
virtual lldb::RegisterContextSP GetRegisterContext()=0
lldb::ProcessSP GetProcess() const
void SetRegisterKind(lldb::RegisterKind kind)
void AppendRow(const RowSP &row_sp)
std::shared_ptr< Row > RowSP
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
void SetSourceName(const char *)
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Value * GetValueAtIndex(size_t idx)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, llvm::StringRef name, const Address &address, lldb::TypeSP &type_sp)
const Scalar & GetScalar() const
void SetCompilerType(const CompilerType &compiler_type)
void SetValueType(ValueType value_type)
const CompilerType & GetCompilerType()
#define LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_ARG4
#define LLDB_REGNUM_GENERIC_ARG3
#define LLDB_REGNUM_GENERIC_ARG1
#define LLDB_REGNUM_GENERIC_FLAGS
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_ARG2
#define LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_FP
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::Process > ProcessSP
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindLLDB
lldb's internal register numbers
@ eRegisterKindDWARF
the register numbers seen DWARF
Every register is described in detail including its name, alternate name (optional),...
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
const char * name
Name of this register, can't be NULL.
lldb::user_id_t GetID() const
Get accessor for the user ID.