15#include "llvm/ADT/STLExtras.h"
16#include "llvm/IR/DerivedTypes.h"
28#define DEFINE_REG_NAME(reg_num) ConstString(#reg_num).GetCString()
29#define DEFINE_REG_NAME_STR(reg_name) ConstString(reg_name).GetCString()
34#define DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, generic_num) \
36 DEFINE_REG_NAME(dwarf_num), DEFINE_REG_NAME_STR(str_name), 0, 0, \
37 eEncodingInvalid, eFormatDefault, \
38 {dwarf_num, dwarf_num, generic_num, LLDB_INVALID_REGNUM, dwarf_num}, \
39 nullptr, nullptr, nullptr, \
42#define DEFINE_REGISTER_STUB(dwarf_num, str_name) \
43 DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, LLDB_INVALID_REGNUM)
131 count = dwarf::g_register_infos.size();
132 return dwarf::g_register_infos.
data();
141 llvm::Triple::ArchType machine = arch.
GetTriple().getArch();
143 if (llvm::Triple::riscv32 != machine && llvm::Triple::riscv64 != machine)
149 abi->
SetIsRV64((llvm::Triple::riscv64 == machine) ?
true :
false);
155 return llvm::alignTo(size_in_bytes,
word_size);
160 const llvm::ArrayRef<ABI::CallArgument> &args) {
163 size_t total_size = 0;
164 for (
const auto &arg : args)
176 const uint32_t reg_num,
const addr_t value) {
182 static_cast<uint64_t
>(value));
192 const llvm::ArrayRef<addr_t> args) {
193 std::stringstream ss;
194 ss <<
"ABISysV_riscv::PrepareTrivialCall"
195 <<
" (tid = 0x" << std::hex << thread.
GetID() <<
", sp = 0x" <<
sp
196 <<
", func_addr = 0x" << func_addr <<
", return_addr = 0x" << return_addr;
198 for (
auto [idx, arg] : enumerate(args))
199 ss <<
", arg" << std::dec << idx <<
" = 0x" << std::hex << arg;
206 llvm::ArrayRef<addr_t> args)
const {
213 LLDB_LOG(log,
"Failed to get RegisterContext");
218 LLDB_LOG(log,
"Function has {0} arguments, but only {1} are allowed!",
224 for (
auto [idx, arg] : enumerate(args)) {
225 const RegisterInfo *reg_info = reg_ctx_sp->GetRegisterInfo(
227 LLDB_LOG(log,
"About to write arg{0} (0x{1:x}) into {2}", idx, arg,
230 if (!reg_ctx_sp->WriteRegisterFromUnsigned(reg_info, arg)) {
231 LLDB_LOG(log,
"Failed to write arg{0} (0x{1:x}) into {2}", idx, arg,
247 LLDB_LOG(log,
"ABISysV_riscv::{0}() success", __FUNCTION__);
253 llvm::ArrayRef<ABI::CallArgument> args)
const {
258 uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
263 uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
268 uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
281 for (
const auto &arg : args) {
289 if (process->WriteMemory(
sp, arg.data_up.get(), arg.size,
error) <
295 *
const_cast<addr_t *
>(&arg.value) =
sp;
299 assert(prototype.getFunctionNumParams() == args.size());
301 const size_t num_args = args.size();
302 const size_t num_args_in_regs =
312 uint8_t reg_value[8];
315 for (
size_t i = 0; i < args_size; ++i) {
316 auto value =
reinterpret_cast<const uint8_t *
>(&args[i].value);
321 if (i < num_args_in_regs) {
324 memcpy(reg_value, value, end);
326 memset(reg_value + end, 0,
reg_size - end);
330 if (!reg_ctx->WriteRegister(
344 if (process->WriteMemory(
sp - offset, value, size,
error) < size ||
355 reg_ctx->WriteRegisterFromUnsigned(pc_reg,
pc);
356 reg_ctx->WriteRegisterFromUnsigned(ra_reg,
ra);
357 reg_ctx->WriteRegisterFromUnsigned(sp_reg,
sp);
375 CompilerType compiler_type = new_value_sp->GetCompilerType();
376 if (!compiler_type) {
381 auto ®_ctx = *frame_sp->GetThread()->GetRegisterContext();
383 bool is_signed =
false;
387 "We don't support returning other types at present");
392 size_t num_bytes = new_value_sp->
GetData(data, result);
396 "Couldn't convert return value to raw data: %s", result.
AsCString());
403 uint64_t raw_value = data.
GetMaxU64(&offset, num_bytes);
407 if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) {
409 "Couldn't write value to register %s", reg_info->
name);
424 if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) {
426 "Couldn't write value to register %s", reg_info->
name);
433 "We don't support returning large integer values at present.");
439 raw_value &= std::numeric_limits<T>::max();
441 scalar =
static_cast<typename std::make_signed<T>::type
>(raw_value);
443 scalar =
static_cast<T
>(raw_value);
447 uint8_t size_in_bytes,
bool is_signed) {
448 switch (size_in_bytes) {
452 case sizeof(uint64_t):
453 SetInteger<uint64_t>(scalar, raw_value, is_signed);
456 case sizeof(uint32_t):
457 SetInteger<uint32_t>(scalar, raw_value, is_signed);
460 case sizeof(uint16_t):
461 SetInteger<uint16_t>(scalar, raw_value, is_signed);
464 case sizeof(uint8_t):
465 SetInteger<uint8_t>(scalar, raw_value, is_signed);
473 uint8_t size_in_bytes) {
474 switch (size_in_bytes) {
478 case sizeof(uint64_t):
479 scalar = *
reinterpret_cast<double *
>(&raw_value);
482 case sizeof(uint32_t):
483 scalar = *
reinterpret_cast<float *
>(&raw_value);
492 llvm::Triple::ArchType machine,
494 uint32_t byte_size) {
504 case sizeof(uint32_t):
506 raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0) &
UINT32_MAX;
508 case sizeof(uint64_t):
510 if (llvm::Triple::riscv32 == machine) {
511 raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0) &
UINT32_MAX;
513 (reg_ctx->ReadRegisterAsUnsigned(reg_info_a1, 0) &
UINT32_MAX) << 32U;
515 raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0);
520 if (llvm::Triple::riscv32 == machine)
521 return return_valobj_sp;
524 std::unique_ptr<DataBufferHeap> heap_data_up(
528 if (reg_ctx->ReadRegister(reg_info_a0, reg_value_a0) &&
529 reg_ctx->ReadRegister(reg_info_a1, reg_value_a1)) {
532 heap_data_up->GetBytes() + 0, 8,
533 byte_order,
error) &&
535 heap_data_up->GetBytes() + 8, 8,
536 byte_order,
error)) {
537 value.
SetBytes(heap_data_up.release(), byte_size);
545 return return_valobj_sp;
548 if (type_flags & eTypeIsInteger) {
549 const bool is_signed = (type_flags & eTypeIsSigned) != 0;
551 return return_valobj_sp;
552 }
else if (type_flags & eTypeIsFloat) {
554 return return_valobj_sp;
556 return return_valobj_sp;
561 return return_valobj_sp;
566 llvm::Triple::ArchType machine, uint32_t arch_fp_flags,
567 uint32_t type_flags, uint32_t byte_size) {
568 auto reg_info_fa0 = reg_ctx->GetRegisterInfoByName(
"fa0");
569 bool use_fp_regs =
false;
572 switch (arch_fp_flags) {
577 return return_valobj_sp;
597 raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_fa0, 0);
599 return return_valobj_sp;
614 return return_valobj_sp;
618 return return_valobj_sp;
623 const uint32_t type_flags = compiler_type.
GetTypeInfo();
624 const size_t byte_size = compiler_type.
GetByteSize(&thread).value_or(0);
626 const llvm::Triple::ArchType machine = arch.
GetMachine();
629 if (type_flags & eTypeIsInteger) {
632 return return_valobj_sp;
635 else if (type_flags & eTypeIsPointer) {
638 value.
GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0);
644 else if (type_flags & eTypeIsFloat) {
645 uint32_t float_count = 0;
646 bool is_complex =
false;
649 float_count == 1 && !is_complex) {
650 const uint32_t arch_fp_flags =
653 thread, reg_ctx, machine, arch_fp_flags, type_flags, byte_size);
654 return return_valobj_sp;
658 return return_valobj_sp;
663 llvm::Type &type)
const {
669 return return_valobj_sp;
671 uint32_t type_flags = 0;
672 if (type.isIntegerTy())
673 type_flags = eTypeIsInteger;
674 else if (type.isVoidTy())
675 type_flags = eTypeIsPointer;
676 else if (type.isFloatTy())
677 type_flags = eTypeIsFloat;
679 const uint32_t byte_size = type.getPrimitiveSizeInBits() / CHAR_BIT;
681 const llvm::Triple::ArchType machine = arch.
GetMachine();
684 if (type_flags & eTypeIsInteger) {
687 return return_valobj_sp;
690 else if (type_flags & eTypeIsPointer) {
693 value.
GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0);
699 else if (type_flags & eTypeIsFloat) {
700 const uint32_t arch_fp_flags =
703 thread, reg_ctx, machine, arch_fp_flags, type_flags, byte_size);
704 return return_valobj_sp;
707 return return_valobj_sp;
714 if (!return_compiler_type)
715 return return_valobj_sp;
732 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
736 row->SetRegisterLocationToRegister(pc_reg_num, ra_reg_num,
true);
738 unwind_plan.
SetSourceName(
"riscv function-entry unwind plan");
754 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 0);
763 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num,
reg_size * -2,
true);
764 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num,
reg_size * -1,
true);
781 const char *name = reg_info->
name;
783 uint32_t arch_flags = arch.
GetFlags();
788 bool is_callee_saved =
789 llvm::StringSwitch<bool>(name)
791 .Cases(
"ra",
"sp",
"fp",
true)
792 .Cases(
"s0",
"s1",
"s2",
"s3",
"s4",
"s5",
"s6",
"s7",
"s8",
"s9",
794 .Cases(
"s10",
"s11",
true)
796 .Cases(
"x1",
"x2",
"x8",
"x9",
"x18",
"x19",
"x20",
"x21",
"x22",
798 .Cases(
"x23",
"x24",
"x25",
"x26",
"x27",
true)
800 .Cases(
"fs0",
"fs1",
"fs2",
"fs3",
"fs4",
"fs5",
"fs6",
"fs7",
802 .Cases(
"fs8",
"fs9",
"fs10",
"fs11", is_hw_fp)
804 .Cases(
"f8",
"f9",
"f18",
"f19",
"f20",
"f21",
"f22",
"f23", is_hw_fp)
805 .Cases(
"f24",
"f25",
"f26",
"f27", is_hw_fp)
808 return is_callee_saved;
821 return llvm::StringSwitch<uint32_t>(name)
838 std::vector<lldb_private::DynamicRegisterInfo::Register> ®s) {
841 for (
auto it : llvm::enumerate(regs)) {
843 if (it.value().name ==
"zero")
844 it.value().alt_name.SetCString(
"x0");
845 else if (it.value().name ==
"ra")
846 it.value().alt_name.SetCString(
"x1");
847 else if (it.value().name ==
"sp")
848 it.value().alt_name.SetCString(
"x2");
849 else if (it.value().name ==
"gp")
850 it.value().alt_name.SetCString(
"x3");
851 else if (it.value().name ==
"fp")
852 it.value().alt_name.SetCString(
"s0");
853 else if (it.value().name ==
"s0")
854 it.value().alt_name.SetCString(
"x8");
857 it.value().regnum_generic =
GetGenericNum(it.value().name.GetStringRef());
static const RegisterInfo g_register_infos[]
#define DEFINE_REGISTER_STUB(dwarf_num, str_name)
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 size_t AugmentArgSize(size_t size_in_bytes)
static ValueObjectSP GetValObjFromIntRegs(Thread &thread, const RegisterContextSP ®_ctx, llvm::Triple::ArchType machine, uint32_t type_flags, uint32_t byte_size)
static bool UpdateRegister(RegisterContext *reg_ctx, const lldb::RegisterKind reg_kind, const uint32_t reg_num, const addr_t value)
static void LogInitInfo(Log &log, const Thread &thread, addr_t sp, addr_t func_addr, addr_t return_addr, const llvm::ArrayRef< addr_t > args)
static ValueObjectSP GetValObjFromFPRegs(Thread &thread, const RegisterContextSP ®_ctx, llvm::Triple::ArchType machine, uint32_t type_flags, uint32_t byte_size)
static uint32_t GetGenericNum(llvm::StringRef name)
static constexpr size_t g_regs_for_args_count
static ValueObjectSP GetValObjFromIntRegs(Thread &thread, const RegisterContextSP ®_ctx, llvm::Triple::ArchType machine, uint32_t type_flags, uint32_t byte_size)
static bool UpdateRegister(RegisterContext *reg_ctx, const lldb::RegisterKind reg_kind, const uint32_t reg_num, const addr_t value)
static void LogInitInfo(Log &log, const Thread &thread, addr_t sp, addr_t func_addr, addr_t return_addr, const llvm::ArrayRef< addr_t > args)
static size_t TotalArgsSizeInWords(bool is_rv64, const llvm::ArrayRef< ABI::CallArgument > &args)
static size_t AugmentArgSize(bool is_rv64, size_t size_in_bytes)
static void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed)
static uint32_t GetGenericNum(llvm::StringRef name)
static bool SetSizedInteger(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes, bool is_signed)
static constexpr size_t g_regs_for_args_count
static ValueObjectSP GetValObjFromFPRegs(Thread &thread, const RegisterContextSP ®_ctx, llvm::Triple::ArchType machine, uint32_t arch_fp_flags, uint32_t type_flags, uint32_t byte_size)
static bool SetSizedFloat(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes)
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
static llvm::StringRef GetPluginNameStatic()
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info)
void SetIsRV64(bool is_rv64)
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
void AugmentRegisterInfo(std::vector< lldb_private::DynamicRegisterInfo::Register > ®s) override
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) 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::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
static std::unique_ptr< llvm::MCRegisterInfo > MakeMCRegisterInfo(const ArchSpec &arch)
Utility function to construct a MCRegisterInfo using the ArchSpec triple.
lldb::ProcessSP GetProcessSP() const
Request to get a Process shared pointer.
An architecture specification class.
llvm::Triple & GetTriple()
Architecture triple accessor.
uint32_t GetFlags() const
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
@ eRISCV_float_abi_double
single precision floating point, +f
@ eRISCV_float_abi_soft
RVC, +c.
@ eRISCV_float_abi_quad
double precision floating point, +d
@ eRISCV_float_abi_mask
quad precision floating point, +q
@ eRISCV_float_abi_single
soft float
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.
A subclass of DataBuffer that stores a data buffer on the heap.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void PutString(llvm::StringRef str)
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
void AugmentRegisterInfo(std::vector< DynamicRegisterInfo::Register > ®s) override
const RegisterInfo * GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num)
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
uint32_t GetAsMemoryData(const RegisterInfo ®_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
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 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)
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
RegisterInfo * GetRegisterInfo() const
void SetCompilerType(const CompilerType &compiler_type)
void SetValueType(ValueType value_type)
void SetBytes(const void *bytes, int len)
#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_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.
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::RegisterContext > RegisterContextSP
RegisterKind
Register numbering types.
@ 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),...
llvm::ArrayRef< uint8_t > data(const uint8_t *context_base) const
const char * name
Name of this register, can't be NULL.
lldb::user_id_t GetID() const
Get accessor for the user ID.