10#include "llvm/ADT/STLExtras.h"
11#include "llvm/TargetParser/Triple.h"
75 if (arch.
GetTriple().getVendor() != llvm::Triple::Apple) {
76 if (arch.
GetTriple().getArch() == llvm::Triple::x86) {
86 llvm::ArrayRef<addr_t> args)
const {
109 sp -= 4 * args.size();
112 sp &= ~(16ull - 1ull);
119 reg_info_32, arg_pos, reg_info_32->
byte_size, reg_value);
129 reg_info_32,
sp, reg_info_32->
byte_size, reg_value);
145 bool is_signed,
Process *process,
146 addr_t ¤t_stack_argument) {
147 uint32_t byte_size = (bit_width + (8 - 1)) / 8;
154 is_signed, scalar,
error)) {
155 current_stack_argument += byte_size;
162 unsigned int num_values = values.
GetSize();
163 unsigned int value_index;
175 addr_t current_stack_argument =
sp + 4;
177 for (value_index = 0; value_index < num_values; ++value_index) {
185 std::optional<uint64_t> bit_size = compiler_type.
GetBitSize(&thread);
190 thread.
GetProcess().get(), current_stack_argument);
193 thread.
GetProcess().get(), current_stack_argument);
208 CompilerType compiler_type = new_value_sp->GetCompilerType();
209 if (!compiler_type) {
214 const uint32_t type_flags = compiler_type.
GetTypeInfo();
215 Thread *thread = frame_sp->GetThread().get();
219 size_t num_bytes = new_value_sp->GetData(data, data_error);
220 bool register_write_successful =
true;
222 if (data_error.
Fail()) {
224 "Couldn't convert return value to raw data: %s",
233 if (type_flags & eTypeIsPointer)
235 if (num_bytes !=
sizeof(uint32_t)) {
242 uint32_t raw_value = data.
GetMaxU32(&offset, num_bytes);
243 register_write_successful =
245 }
else if ((type_flags & eTypeIsScalar) ||
246 (type_flags & eTypeIsEnumeration))
251 if (type_flags & eTypeIsInteger)
261 uint32_t raw_value_low = data.
GetMaxU32(&offset, 4);
263 uint32_t raw_value_high = data.
GetMaxU32(&offset, num_bytes - offset);
264 register_write_successful =
272 uint32_t raw_value = data.
GetMaxU32(&offset, num_bytes);
273 register_write_successful =
278 }
else if (type_flags & eTypeIsEnumeration)
280 uint32_t raw_value = data.
GetMaxU32(&offset, num_bytes);
281 register_write_successful =
283 }
else if (type_flags & eTypeIsFloat)
302 uint32_t value_fstat_u32 = 0x00003800;
310 uint32_t value_ftag_u32 = 0x00000080;
314 long double value_long_dbl = 0.0;
316 value_long_dbl = data.
GetFloat(&offset);
317 else if (num_bytes == 8)
318 value_long_dbl = data.
GetDouble(&offset);
319 else if (num_bytes == 12)
323 "Invalid number of bytes for this return type");
329 register_write_successful =
333 }
else if (num_bytes == 16)
336 "Implementation is missing for this clang type.");
348 "Currently only Integral and Floating Point clang "
349 "types are supported.");
351 if (!register_write_successful)
361 if (!return_compiler_type)
362 return return_valobj_sp;
368 return return_valobj_sp;
370 const uint32_t type_flags = return_compiler_type.
GetTypeInfo();
381 if (type_flags & eTypeIsPointer)
390 }
else if ((type_flags & eTypeIsScalar) ||
391 (type_flags & eTypeIsEnumeration))
394 std::optional<uint64_t> byte_size =
397 return return_valobj_sp;
398 bool success =
false;
400 if (type_flags & eTypeIsInteger)
402 const bool is_signed = ((type_flags & eTypeIsSigned) != 0);
411 switch (*byte_size) {
422 value.
GetScalar() = (int64_t)(raw_value);
424 value.
GetScalar() = (uint64_t)(raw_value);
438 value.
GetScalar() = (int16_t)(raw_value & UINT16_MAX);
440 value.
GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
446 value.
GetScalar() = (int8_t)(raw_value & UINT8_MAX);
448 value.
GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
456 }
else if (type_flags & eTypeIsEnumeration)
465 }
else if (type_flags & eTypeIsFloat)
467 if (*byte_size <= 12)
479 if (*byte_size == 4) {
480 float value_float = (float)value_long_double;
483 }
else if (*byte_size == 8) {
487 double value_double = (double)value_long_double;
490 }
else if (*byte_size == 12) {
501 }
else if (*byte_size == 16)
507 &thread,
"",
Address(storage_addr,
nullptr), return_compiler_type);
514 }
else if (type_flags & eTypeIsComplex)
517 }
else if (type_flags & eTypeIsVector)
519 std::optional<uint64_t> byte_size =
521 if (byte_size && *byte_size > 0) {
523 if (vec_reg ==
nullptr)
527 if (*byte_size <= vec_reg->byte_size) {
530 std::unique_ptr<DataBufferHeap> heap_data_up(
532 const ByteOrder byte_order = process_sp->GetByteOrder();
537 heap_data_up->GetByteSize(),
538 byte_order,
error)) {
541 process_sp->GetTarget()
543 .GetAddressByteSize());
545 &thread, return_compiler_type,
ConstString(
""), data);
549 }
else if (*byte_size <= vec_reg->byte_size * 2) {
555 std::unique_ptr<DataBufferHeap> heap_data_up(
557 const ByteOrder byte_order = process_sp->GetByteOrder();
565 *vec_reg, heap_data_up->GetBytes(), vec_reg->
byte_size,
566 byte_order,
error) &&
569 heap_data_up->GetBytes() + vec_reg->
byte_size,
570 heap_data_up->GetByteSize() - vec_reg->
byte_size,
571 byte_order,
error)) {
574 process_sp->GetTarget()
576 .GetAddressByteSize());
578 &thread, return_compiler_type,
ConstString(
""), data);
590 return return_valobj_sp;
597 if (!return_compiler_type)
598 return return_valobj_sp;
602 if (return_valobj_sp)
603 return return_valobj_sp;
607 return return_valobj_sp;
616 &thread,
"",
Address(storage_addr,
nullptr), return_compiler_type);
619 return return_valobj_sp;
634 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 4);
635 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4,
false);
636 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0,
true);
657 const int32_t ptr_size = 4;
659 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
661 row->SetUnspecifiedRegistersAreUndefined(
true);
663 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2,
true);
664 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1,
true);
665 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0,
true);
683 const char *name = reg_info->
name;
684 if (name[0] ==
'e') {
687 if (name[2] ==
'x' || name[2] ==
'p')
688 return name[3] ==
'\0';
692 return name[3] ==
'\0';
696 return name[3] ==
'\0';
699 if (name[2] ==
'i' || name[2] ==
'p')
700 return name[3] ==
'\0';
705 if (name[0] ==
's' && name[1] ==
'p' && name[2] ==
'\0')
707 if (name[0] ==
'f' && name[1] ==
'p' && name[2] ==
'\0')
709 if (name[0] ==
'p' && name[1] ==
'c' && name[2] ==
'\0')
static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, bool is_signed, Process *process, addr_t ¤t_stack_argument)
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_PLUGIN_DEFINE(PluginName)
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info)
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
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
lldb::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
static llvm::StringRef GetPluginNameStatic()
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
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.
llvm::Triple & GetTriple()
Architecture triple accessor.
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.
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.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A plug-in interface definition class for debugging a process.
size_t ReadScalarIntegerFromMemory(lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Status &error)
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
Convert from a given register numbering scheme to the lldb register numbering scheme.
uint64_t GetSP(uint64_t fail_value=LLDB_INVALID_ADDRESS)
virtual bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value)=0
virtual Status WriteRegisterValueToMemory(const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue ®_value)
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 SetLongDouble(long double f)
void SetUInt32(uint32_t uint, Type t=eTypeUInt32)
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
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.
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
virtual lldb::RegisterContextSP GetRegisterContext()=0
lldb::ProcessSP GetProcess() const
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
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_PC
A class that represents a running process on the host machine.
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::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 byte_size
Size in bytes of the register.
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.