18#include "llvm/IR/DerivedTypes.h"
19#include "llvm/Support/MathExtras.h"
20#include "llvm/TargetParser/Triple.h"
38#define DEFINE_REG_NAME(reg_num) ConstString(#reg_num).GetCString()
39#define DEFINE_REG_NAME_STR(reg_name) ConstString(reg_name).GetCString()
44#define DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, generic_num) \
46 DEFINE_REG_NAME(dwarf_num), DEFINE_REG_NAME_STR(str_name), \
47 0, 0, eEncodingInvalid, eFormatDefault, \
48 { dwarf_num, dwarf_num, generic_num, LLDB_INVALID_REGNUM, dwarf_num }, \
49 nullptr, nullptr, nullptr, \
52#define DEFINE_REGISTER_STUB(dwarf_num, str_name) \
53 DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, LLDB_INVALID_REGNUM)
63 r0, r1, r2, r3, r4, r5, r6, r7,
r8,
r9,
r10,
r11,
r12,
r13,
r14,
r15, r16,
64 r17, r18, r19, r20, r21, r22, r23, r24, r25, r26,
65 r27,
fp = r27, r28,
sp = r28, r29, r30, r31, blink = r31,
66 r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46,
67 r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60,
68 r63 = 63,
pc = 70, status32 = 74
140 count = dwarf::g_register_infos.size();
141 return dwarf::g_register_infos.
data();
153 const uint32_t rf_entries_bit = 1U << 9U;
165 return llvm::Triple::arc == arch.
GetTriple().getArch() ?
174 return llvm::alignTo(size_in_bytes,
word_size);
179 size_t total_size = 0;
180 for (
const auto &arg : args)
191 llvm::ArrayRef<addr_t> args)
const {
198 llvm::ArrayRef<ABI::CallArgument> args)
const {
203 uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
208 uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
213 uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
224 for (
const auto &arg : args) {
232 if (process->WriteMemory(
sp, arg.data_up.get(), arg.size,
error) < arg.size
237 *
const_cast<addr_t *
>(&arg.value) =
sp;
241 assert(!prototype.isFunctionVarArg());
242 assert(prototype.getFunctionNumParams() == args.size());
249 args_size <= regs_for_args_count ? 0 : args_size - regs_for_args_count;
255 for (
const auto &arg : args) {
256 auto value =
reinterpret_cast<const uint8_t *
>(&arg.value);
261 while (size > 0 && reg_index < regs_for_args_count) {
262 size_t byte_index = 0;
265 while (byte_index < end) {
266 reg_value[byte_index++] = *(value++);
271 reg_value[byte_index++] = 0;
276 if (!reg_ctx->WriteRegister(
285 if (reg_index < regs_for_args_count || size == 0)
289 if (process->WriteMemory(
sp - offset, value, size,
error) < size ||
300 reg_ctx->WriteRegisterFromUnsigned(pc_reg,
pc);
301 reg_ctx->WriteRegisterFromUnsigned(ra_reg,
ra);
302 reg_ctx->WriteRegisterFromUnsigned(sp_reg,
sp);
319 CompilerType compiler_type = new_value_sp->GetCompilerType();
320 if (!compiler_type) {
325 auto ®_ctx = *frame_sp->GetThread()->GetRegisterContext();
327 bool is_signed =
false;
330 result.
SetErrorString(
"We don't support returning other types at present");
335 size_t num_bytes = new_value_sp->
GetData(data, result);
339 "Couldn't convert return value to raw data: %s", result.
AsCString());
345 uint64_t raw_value = data.
GetMaxU64(&offset, num_bytes);
349 if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) {
361 if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) {
370 "We don't support returning large integer values at present.");
376 raw_value &= std::numeric_limits<T>::max();
378 scalar =
static_cast<typename std::make_signed<T>::type
>(raw_value);
380 scalar =
static_cast<T
>(raw_value);
384 uint8_t size_in_bytes,
bool is_signed) {
385 switch (size_in_bytes) {
389 case sizeof(uint64_t):
390 SetInteger<uint64_t>(scalar, raw_value, is_signed);
393 case sizeof(uint32_t):
394 SetInteger<uint32_t>(scalar, raw_value, is_signed);
397 case sizeof(uint16_t):
398 SetInteger<uint16_t>(scalar, raw_value, is_signed);
401 case sizeof(uint8_t):
402 SetInteger<uint8_t>(scalar, raw_value, is_signed);
410 uint8_t size_in_bytes) {
411 switch (size_in_bytes) {
415 case sizeof(uint64_t):
416 scalar = *
reinterpret_cast<double *
>(&raw_value);
419 case sizeof(uint32_t):
420 scalar = *
reinterpret_cast<float *
>(&raw_value);
428 uint8_t size_in_bytes) {
434 reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0) &
UINT32_MAX;
436 if (
sizeof(uint64_t) == size_in_bytes)
437 raw_value |= (reg_ctx->ReadRegisterAsUnsigned(
458 const uint32_t type_flags = compiler_type.
GetTypeInfo();
460 if (type_flags & eTypeIsInteger) {
461 const size_t byte_size = compiler_type.
GetByteSize(&thread).value_or(0);
464 const bool is_signed = (type_flags & eTypeIsSigned) != 0;
471 else if (type_flags & eTypeIsPointer) {
474 value.
GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0);
479 else if (type_flags & eTypeIsFloat) {
480 uint32_t float_count = 0;
481 bool is_complex =
false;
484 1 == float_count && !is_complex) {
485 const size_t byte_size = compiler_type.
GetByteSize(&thread).value_or(0);
504 if (!return_compiler_type)
505 return return_valobj_sp;
512 llvm::Type &retType)
const {
519 if (retType.isVoidTy()) {
523 else if (retType.isIntegerTy()) {
524 size_t byte_size = retType.getPrimitiveSizeInBits();
526 byte_size /= CHAR_BIT;
530 const bool is_signed =
false;
535 else if (retType.isPointerTy()) {
538 value.
GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0);
542 else if (retType.isFloatingPointTy()) {
543 const size_t byte_size = retType.getPrimitiveSizeInBits() / CHAR_BIT;
564 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf::sp, 0);
567 row->SetRegisterLocationToRegister(dwarf::pc, dwarf::blink,
true);
582 if (
nullptr == reg_info)
590 static const std::string ra_reg_name =
"blink";
591 return ra_reg_name == reg_info->
name;
static const RegisterInfo g_register_infos[]
#define DEFINE_REGISTER_STUB(dwarf_num, str_name)
static void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed)
static bool SetSizedInteger(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes, bool is_signed)
static const size_t word_size
static size_t TotalArgsSizeInWords(const llvm::ArrayRef< ABI::CallArgument > &args)
#define DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, generic_num)
static const size_t reg_size
static bool SetSizedFloat(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes)
static uint64_t ReadRawValue(const RegisterContextSP ®_ctx, uint8_t size_in_bytes)
static size_t AugmentArgSize(size_t size_in_bytes)
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
lldb::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
RegisterFileFlag m_is_reg_file_reduced
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) 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
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
size_t GetRedZoneSize() const override
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
static llvm::StringRef GetPluginNameStatic()
bool IsRegisterFileReduced(lldb_private::RegisterContext ®_ctx) const
static std::unique_ptr< llvm::MCRegisterInfo > MakeMCRegisterInfo(const ArchSpec &arch)
Utility function to construct a MCRegisterInfo using the ArchSpec triple.
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 IsFloatingPointType(uint32_t &count, bool &is_complex) const
bool IsIntegerOrEnumerationType(bool &is_signed) const
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
bool IsPointerType(CompilerType *pointee_type=nullptr) const
A uniqued constant string class.
"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)
uint64_t ReadRegisterAsUnsigned(uint32_t reg, uint64_t fail_value)
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
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.
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
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 *)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS)
const Scalar & GetScalar() const
void SetCompilerType(const CompilerType &compiler_type)
void SetValueType(ValueType value_type)
#define LLDB_REGNUM_GENERIC_RA
#define LLDB_REGNUM_GENERIC_ARG8
#define LLDB_REGNUM_GENERIC_ARG6
#define LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_ARG4
#define LLDB_REGNUM_GENERIC_ARG3
#define LLDB_REGNUM_GENERIC_ARG1
#define LLDB_REGNUM_GENERIC_ARG7
#define LLDB_REGNUM_GENERIC_FLAGS
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_ARG2
#define LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_FP
#define LLDB_REGNUM_GENERIC_ARG5
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
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ 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.
llvm::ArrayRef< uint8_t > data(const uint8_t *context_base) const
const char * name
Name of this register, can't be NULL.