1//===-- ABISysV_riscv.cpp ------------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===---------------------------------------------------------------------===// 8 9#include "ABISysV_riscv.h" 10 11#include <array> 12#include <limits> 13 14#include "llvm/IR/DerivedTypes.h" 15 16#include "lldb/Core/PluginManager.h" 17#include "lldb/Core/Value.h" 18#include "lldb/Core/ValueObjectConstResult.h" 19#include "lldb/Target/RegisterContext.h" 20#include "lldb/Target/StackFrame.h" 21#include "lldb/Target/Thread.h" 22#include "lldb/Utility/RegisterValue.h" 23 24#define DEFINE_REG_NAME(reg_num) ConstString(#reg_num).GetCString() 25#define DEFINE_REG_NAME_STR(reg_name) ConstString(reg_name).GetCString() 26 27// The ABI is not a source of such information as size, offset, encoding, etc. 28// of a register. Just provides correct dwarf and eh_frame numbers. 29 30#define DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, generic_num) \ 31 { \ 32 DEFINE_REG_NAME(dwarf_num), DEFINE_REG_NAME_STR(str_name), 0, 0, \ 33 eEncodingInvalid, eFormatDefault, \ 34 {dwarf_num, dwarf_num, generic_num, LLDB_INVALID_REGNUM, dwarf_num}, \ 35 nullptr, nullptr, nullptr, \ 36 } 37 38#define DEFINE_REGISTER_STUB(dwarf_num, str_name) \ 39 DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, LLDB_INVALID_REGNUM) 40 41using namespace lldb; 42using namespace lldb_private; 43 44LLDB_PLUGIN_DEFINE_ADV(ABISysV_riscv, ABIRISCV) 45 46namespace { 47namespace dwarf { 48enum regnums { 49 zero, 50 ra, 51 sp, 52 gp, 53 tp, 54 t0, 55 t1, 56 t2, 57 fp, 58 s0 = fp, 59 s1, 60 a0, 61 a1, 62 a2, 63 a3, 64 a4, 65 a5, 66 a6, 67 a7, 68 s2, 69 s3, 70 s4, 71 s5, 72 s6, 73 s7, 74 s8, 75 s9, 76 s10, 77 s11, 78 t3, 79 t4, 80 t5, 81 t6, 82 pc 83}; 84 85static const std::array<RegisterInfo, 33> g_register_infos = { 86 {DEFINE_REGISTER_STUB(zero, nullptr), 87 DEFINE_GENERIC_REGISTER_STUB(ra, nullptr, LLDB_REGNUM_GENERIC_RA), 88 DEFINE_GENERIC_REGISTER_STUB(sp, nullptr, LLDB_REGNUM_GENERIC_SP), 89 DEFINE_REGISTER_STUB(gp, nullptr), 90 DEFINE_REGISTER_STUB(tp, nullptr), 91 DEFINE_REGISTER_STUB(t0, nullptr), 92 DEFINE_REGISTER_STUB(t1, nullptr), 93 DEFINE_REGISTER_STUB(t2, nullptr), 94 DEFINE_GENERIC_REGISTER_STUB(fp, nullptr, LLDB_REGNUM_GENERIC_FP), 95 DEFINE_REGISTER_STUB(s1, nullptr), 96 DEFINE_GENERIC_REGISTER_STUB(a0, nullptr, LLDB_REGNUM_GENERIC_ARG1), 97 DEFINE_GENERIC_REGISTER_STUB(a1, nullptr, LLDB_REGNUM_GENERIC_ARG2), 98 DEFINE_GENERIC_REGISTER_STUB(a2, nullptr, LLDB_REGNUM_GENERIC_ARG3), 99 DEFINE_GENERIC_REGISTER_STUB(a3, nullptr, LLDB_REGNUM_GENERIC_ARG4), 100 DEFINE_GENERIC_REGISTER_STUB(a4, nullptr, LLDB_REGNUM_GENERIC_ARG5), 101 DEFINE_GENERIC_REGISTER_STUB(a5, nullptr, LLDB_REGNUM_GENERIC_ARG6), 102 DEFINE_GENERIC_REGISTER_STUB(a6, nullptr, LLDB_REGNUM_GENERIC_ARG7), 103 DEFINE_GENERIC_REGISTER_STUB(a7, nullptr, LLDB_REGNUM_GENERIC_ARG8), 104 DEFINE_REGISTER_STUB(s2, nullptr), 105 DEFINE_REGISTER_STUB(s3, nullptr), 106 DEFINE_REGISTER_STUB(s4, nullptr), 107 DEFINE_REGISTER_STUB(s5, nullptr), 108 DEFINE_REGISTER_STUB(s6, nullptr), 109 DEFINE_REGISTER_STUB(s7, nullptr), 110 DEFINE_REGISTER_STUB(s8, nullptr), 111 DEFINE_REGISTER_STUB(s9, nullptr), 112 DEFINE_REGISTER_STUB(s10, nullptr), 113 DEFINE_REGISTER_STUB(s11, nullptr), 114 DEFINE_REGISTER_STUB(t3, nullptr), 115 DEFINE_REGISTER_STUB(t4, nullptr), 116 DEFINE_REGISTER_STUB(t5, nullptr), 117 DEFINE_REGISTER_STUB(t6, nullptr), 118 DEFINE_GENERIC_REGISTER_STUB(pc, nullptr, LLDB_REGNUM_GENERIC_PC)}}; 119} // namespace dwarf 120} // namespace 121 122const RegisterInfo *ABISysV_riscv::GetRegisterInfoArray(uint32_t &count) { 123 count = dwarf::g_register_infos.size(); 124 return dwarf::g_register_infos.data(); 125} 126 127//------------------------------------------------------------------ 128// Static Functions 129//------------------------------------------------------------------ 130 131ABISP 132ABISysV_riscv::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) { 133 llvm::Triple::ArchType machine = arch.GetTriple().getArch(); 134 135 if (llvm::Triple::riscv32 != machine && llvm::Triple::riscv64 != machine) 136 return ABISP(); 137 138 ABISysV_riscv *abi = new ABISysV_riscv(std::move(process_sp), 139 MakeMCRegisterInfo(arch)); 140 if (abi) 141 abi->SetIsRV64((llvm::Triple::riscv64 == machine) ? true : false); 142 return ABISP(abi); 143} 144 145static inline size_t AugmentArgSize(bool is_rv64, size_t size_in_bytes) { 146 size_t word_size = is_rv64 ? 8 : 4; 147 return llvm::alignTo(size_in_bytes, word_size); 148} 149 150static size_t 151TotalArgsSizeInWords(bool is_rv64, 152 const llvm::ArrayRef<ABI::CallArgument> &args) { 153 size_t reg_size = is_rv64 ? 8 : 4; 154 size_t word_size = reg_size; 155 size_t total_size = 0; 156 for (const auto &arg : args) 157 total_size += 158 (ABI::CallArgument::TargetValue == arg.type ? AugmentArgSize(is_rv64, 159 arg.size) 160 : reg_size) / 161 word_size; 162 163 return total_size; 164} 165 166bool ABISysV_riscv::PrepareTrivialCall(Thread &thread, addr_t sp, 167 addr_t func_addr, addr_t return_addr, 168 llvm::ArrayRef<addr_t> args) const { 169 // TODO: Implement 170 return false; 171} 172 173bool ABISysV_riscv::PrepareTrivialCall( 174 Thread &thread, addr_t sp, addr_t pc, addr_t ra, llvm::Type &prototype, 175 llvm::ArrayRef<ABI::CallArgument> args) const { 176 auto reg_ctx = thread.GetRegisterContext(); 177 if (!reg_ctx) 178 return false; 179 180 uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( 181 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 182 if (pc_reg == LLDB_INVALID_REGNUM) 183 return false; 184 185 uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( 186 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); 187 if (ra_reg == LLDB_INVALID_REGNUM) 188 return false; 189 190 uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( 191 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 192 if (sp_reg == LLDB_INVALID_REGNUM) 193 return false; 194 195 Status error; 196 ProcessSP process = thread.GetProcess(); 197 if (!process) 198 return false; 199 200 size_t reg_size = m_is_rv64 ? 8 : 4; 201 size_t word_size = reg_size; 202 // Push host data onto target. 203 for (const auto &arg : args) { 204 // Skip over target values. 205 if (arg.type == ABI::CallArgument::TargetValue) 206 continue; 207 208 // Create space on the host stack for this data 4-byte aligned. 209 sp -= AugmentArgSize(m_is_rv64, arg.size); 210 211 if (process->WriteMemory(sp, arg.data_up.get(), arg.size, error) < 212 arg.size || 213 error.Fail()) 214 return false; 215 216 // Update the argument with the target pointer. 217 *const_cast<addr_t *>(&arg.value) = sp; 218 } 219 220 // Make sure number of parameters matches prototype. 221 assert(prototype.getFunctionNumParams() == args.size()); 222 223 const size_t num_args = args.size(); 224 const size_t regs_for_args_count = 8U; 225 const size_t num_args_in_regs = 226 num_args > regs_for_args_count ? regs_for_args_count : num_args; 227 228 // Number of arguments passed on stack. 229 size_t args_size = TotalArgsSizeInWords(m_is_rv64, args); 230 auto on_stack = 231 args_size <= regs_for_args_count ? 0 : args_size - regs_for_args_count; 232 auto offset = on_stack * word_size; 233 234 uint8_t reg_value[8]; 235 size_t reg_index = LLDB_REGNUM_GENERIC_ARG1; 236 237 for (size_t i = 0; i < args_size; ++i) { 238 auto value = reinterpret_cast<const uint8_t *>(&args[i].value); 239 auto size = 240 ABI::CallArgument::TargetValue == args[i].type ? args[i].size : reg_size; 241 242 // Pass arguments via registers. 243 if (i < num_args_in_regs) { 244 // copy value to register, padding if arg is smaller than register 245 auto end = size < reg_size ? size : reg_size; 246 memcpy(reg_value, value, end); 247 if (reg_size > end) 248 memset(reg_value + end, 0, reg_size - end); 249 250 RegisterValue reg_val_obj(llvm::ArrayRef(reg_value, reg_size), 251 eByteOrderLittle); 252 if (!reg_ctx->WriteRegister( 253 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_index), 254 reg_val_obj)) 255 return false; 256 257 // NOTE: It's unsafe to iterate through LLDB_REGNUM_GENERICs 258 // But the "a" registers are sequential in the RISC-V register space 259 ++reg_index; 260 } 261 262 if (reg_index < regs_for_args_count || size == 0) 263 continue; 264 265 // Remaining arguments are passed on the stack. 266 if (process->WriteMemory(sp - offset, value, size, error) < size || 267 !error.Success()) 268 return false; 269 270 offset -= AugmentArgSize(m_is_rv64, size); 271 } 272 273 // Set stack pointer immediately below arguments. 274 sp -= on_stack * word_size; 275 276 // Update registers with current function call state. 277 reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc); 278 reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra); 279 reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp); 280 281 return true; 282} 283 284bool ABISysV_riscv::GetArgumentValues(Thread &thread, ValueList &values) const { 285 // TODO: Implement 286 return false; 287} 288 289Status ABISysV_riscv::SetReturnValueObject(StackFrameSP &frame_sp, 290 ValueObjectSP &new_value_sp) { 291 Status result; 292 if (!new_value_sp) { 293 result.SetErrorString("Empty value object for return value."); 294 return result; 295 } 296 297 CompilerType compiler_type = new_value_sp->GetCompilerType(); 298 if (!compiler_type) { 299 result.SetErrorString("Null clang type for return value."); 300 return result; 301 } 302 303 auto ®_ctx = *frame_sp->GetThread()->GetRegisterContext(); 304 305 bool is_signed = false; 306 if (!compiler_type.IsIntegerOrEnumerationType(is_signed) && 307 !compiler_type.IsPointerType()) { 308 result.SetErrorString("We don't support returning other types at present"); 309 return result; 310 } 311 312 DataExtractor data; 313 size_t num_bytes = new_value_sp->GetData(data, result); 314 315 if (result.Fail()) { 316 result.SetErrorStringWithFormat( 317 "Couldn't convert return value to raw data: %s", result.AsCString()); 318 return result; 319 } 320 321 size_t reg_size = m_is_rv64 ? 8 : 4; 322 if (num_bytes <= 2 * reg_size) { 323 offset_t offset = 0; 324 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); 325 326 auto reg_info = 327 reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); 328 if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) { 329 result.SetErrorStringWithFormat("Couldn't write value to register %s", 330 reg_info->name); 331 return result; 332 } 333 334 if (num_bytes <= reg_size) 335 return result; // Successfully written. 336 337 // for riscv32, get the upper 32 bits from raw_value and write them 338 // for riscv64, get the next 64 bits from data and write them 339 if (4 == reg_size) 340 raw_value >>= 32; 341 else 342 raw_value = data.GetMaxU64(&offset, num_bytes - reg_size); 343 reg_info = 344 reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2); 345 if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) { 346 result.SetErrorStringWithFormat("Couldn't write value to register %s", 347 reg_info->name); 348 } 349 350 return result; 351 } 352 353 result.SetErrorString( 354 "We don't support returning large integer values at present."); 355 return result; 356} 357 358template <typename T> 359static void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed) { 360 raw_value &= std::numeric_limits<T>::max(); 361 if (is_signed) 362 scalar = static_cast<typename std::make_signed<T>::type>(raw_value); 363 else 364 scalar = static_cast<T>(raw_value); 365} 366 367static bool SetSizedInteger(Scalar &scalar, uint64_t raw_value, 368 uint8_t size_in_bytes, bool is_signed) { 369 switch (size_in_bytes) { 370 default: 371 return false; 372 373 case sizeof(uint64_t): 374 SetInteger<uint64_t>(scalar, raw_value, is_signed); 375 break; 376 377 case sizeof(uint32_t): 378 SetInteger<uint32_t>(scalar, raw_value, is_signed); 379 break; 380 381 case sizeof(uint16_t): 382 SetInteger<uint16_t>(scalar, raw_value, is_signed); 383 break; 384 385 case sizeof(uint8_t): 386 SetInteger<uint8_t>(scalar, raw_value, is_signed); 387 break; 388 } 389 390 return true; 391} 392 393static bool SetSizedFloat(Scalar &scalar, uint64_t raw_value, 394 uint8_t size_in_bytes) { 395 switch (size_in_bytes) { 396 default: 397 return false; 398 399 case sizeof(uint64_t): 400 scalar = *reinterpret_cast<double *>(&raw_value); 401 break; 402 403 case sizeof(uint32_t): 404 scalar = *reinterpret_cast<float *>(&raw_value); 405 break; 406 } 407 408 return true; 409} 410 411static ValueObjectSP GetValObjFromIntRegs(Thread &thread, 412 const RegisterContextSP ®_ctx, 413 llvm::Triple::ArchType machine, 414 uint32_t type_flags, 415 uint32_t byte_size) { 416 Value value; 417 ValueObjectSP return_valobj_sp; 418 auto reg_info_a0 = 419 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); 420 auto reg_info_a1 = 421 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2); 422 uint64_t raw_value; 423 424 switch (byte_size) { 425 case sizeof(uint32_t): 426 // Read a0 to get the arg 427 raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0) & UINT32_MAX; 428 break; 429 case sizeof(uint64_t): 430 // Read a0 to get the arg on riscv64, a0 and a1 on riscv32 431 if (llvm::Triple::riscv32 == machine) { 432 raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0) & UINT32_MAX; 433 raw_value |= 434 (reg_ctx->ReadRegisterAsUnsigned(reg_info_a1, 0) & UINT32_MAX) << 32U; 435 } else { 436 raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0); 437 } 438 break; 439 case 16: { 440 // Read a0 and a1 to get the arg on riscv64, not supported on riscv32 441 if (llvm::Triple::riscv32 == machine) 442 return return_valobj_sp; 443 444 // Create the ValueObjectSP here and return 445 std::unique_ptr<DataBufferHeap> heap_data_up( 446 new DataBufferHeap(byte_size, 0)); 447 const ByteOrder byte_order = thread.GetProcess()->GetByteOrder(); 448 RegisterValue reg_value_a0, reg_value_a1; 449 if (reg_ctx->ReadRegister(reg_info_a0, reg_value_a0) && 450 reg_ctx->ReadRegister(reg_info_a1, reg_value_a1)) { 451 Status error; 452 if (reg_value_a0.GetAsMemoryData(*reg_info_a0, 453 heap_data_up->GetBytes() + 0, 8, 454 byte_order, error) && 455 reg_value_a1.GetAsMemoryData(*reg_info_a1, 456 heap_data_up->GetBytes() + 8, 8, 457 byte_order, error)) { 458 value.SetBytes(heap_data_up.release(), byte_size); 459 return ValueObjectConstResult::Create( 460 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 461 } 462 } 463 break; 464 } 465 default: 466 return return_valobj_sp; 467 } 468 469 if (type_flags & eTypeIsInteger) { 470 const bool is_signed = (type_flags & eTypeIsSigned) != 0; 471 if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed)) 472 return return_valobj_sp; 473 } else if (type_flags & eTypeIsFloat) { 474 if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size)) 475 return return_valobj_sp; 476 } else 477 return return_valobj_sp; 478 479 value.SetValueType(Value::ValueType::Scalar); 480 return_valobj_sp = ValueObjectConstResult::Create( 481 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 482 return return_valobj_sp; 483} 484 485static ValueObjectSP 486GetValObjFromFPRegs(Thread &thread, const RegisterContextSP ®_ctx, 487 llvm::Triple::ArchType machine, uint32_t arch_fp_flags, 488 uint32_t type_flags, uint32_t byte_size) { 489 auto reg_info_fa0 = reg_ctx->GetRegisterInfoByName("fa0"); 490 bool use_fp_regs = false; 491 ValueObjectSP return_valobj_sp; 492 493 switch (arch_fp_flags) { 494 // fp return value in integer registers a0 and possibly a1 495 case ArchSpec::eRISCV_float_abi_soft: 496 return_valobj_sp = 497 GetValObjFromIntRegs(thread, reg_ctx, machine, type_flags, byte_size); 498 return return_valobj_sp; 499 // fp return value in fp register fa0 (only float) 500 case ArchSpec::eRISCV_float_abi_single: 501 if (byte_size <= 4) 502 use_fp_regs = true; 503 break; 504 // fp return value in fp registers fa0 (float, double) 505 case ArchSpec::eRISCV_float_abi_double: 506 [[fallthrough]]; 507 // fp return value in fp registers fa0 (float, double, quad) 508 // not implemented; act like they're doubles 509 case ArchSpec::eRISCV_float_abi_quad: 510 if (byte_size <= 8) 511 use_fp_regs = true; 512 break; 513 } 514 515 if (use_fp_regs) { 516 uint64_t raw_value; 517 Value value; 518 raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_fa0, 0); 519 if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size)) 520 return return_valobj_sp; 521 value.SetValueType(Value::ValueType::Scalar); 522 return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), 523 value, ConstString("")); 524 } 525 // we should never reach this, but if we do, use the integer registers 526 return GetValObjFromIntRegs(thread, reg_ctx, machine, type_flags, byte_size); 527} 528 529ValueObjectSP 530ABISysV_riscv::GetReturnValueObjectSimple(Thread &thread, 531 CompilerType &compiler_type) const { 532 ValueObjectSP return_valobj_sp; 533 534 if (!compiler_type) 535 return return_valobj_sp; 536 537 auto reg_ctx = thread.GetRegisterContext(); 538 if (!reg_ctx) 539 return return_valobj_sp; 540 541 Value value; 542 value.SetCompilerType(compiler_type); 543 544 const uint32_t type_flags = compiler_type.GetTypeInfo(); 545 const size_t byte_size = compiler_type.GetByteSize(&thread).value_or(0); 546 const ArchSpec arch = thread.GetProcess()->GetTarget().GetArchitecture(); 547 const llvm::Triple::ArchType machine = arch.GetMachine(); 548 549 // Integer return type. 550 if (type_flags & eTypeIsInteger) { 551 return_valobj_sp = 552 GetValObjFromIntRegs(thread, reg_ctx, machine, type_flags, byte_size); 553 return return_valobj_sp; 554 } 555 // Pointer return type. 556 else if (type_flags & eTypeIsPointer) { 557 auto reg_info_a0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, 558 LLDB_REGNUM_GENERIC_ARG1); 559 value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0); 560 value.SetValueType(Value::ValueType::Scalar); 561 return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), 562 value, ConstString("")); 563 } 564 // Floating point return type. 565 else if (type_flags & eTypeIsFloat) { 566 uint32_t float_count = 0; 567 bool is_complex = false; 568 569 if (compiler_type.IsFloatingPointType(float_count, is_complex) && 570 float_count == 1 && !is_complex) { 571 const uint32_t arch_fp_flags = 572 arch.GetFlags() & ArchSpec::eRISCV_float_abi_mask; 573 return_valobj_sp = GetValObjFromFPRegs( 574 thread, reg_ctx, machine, arch_fp_flags, type_flags, byte_size); 575 return return_valobj_sp; 576 } 577 } 578 // Unsupported return type. 579 return return_valobj_sp; 580} 581 582ValueObjectSP 583ABISysV_riscv::GetReturnValueObjectImpl(lldb_private::Thread &thread, 584 llvm::Type &type) const { 585 Value value; 586 ValueObjectSP return_valobj_sp; 587 588 auto reg_ctx = thread.GetRegisterContext(); 589 if (!reg_ctx) 590 return return_valobj_sp; 591 592 uint32_t type_flags = 0; 593 if (type.isIntegerTy()) 594 type_flags = eTypeIsInteger; 595 else if (type.isVoidTy()) 596 type_flags = eTypeIsPointer; 597 else if (type.isFloatTy()) 598 type_flags = eTypeIsFloat; 599 600 const uint32_t byte_size = type.getPrimitiveSizeInBits() / CHAR_BIT; 601 const ArchSpec arch = thread.GetProcess()->GetTarget().GetArchitecture(); 602 const llvm::Triple::ArchType machine = arch.GetMachine(); 603 604 // Integer return type. 605 if (type_flags & eTypeIsInteger) { 606 return_valobj_sp = 607 GetValObjFromIntRegs(thread, reg_ctx, machine, type_flags, byte_size); 608 return return_valobj_sp; 609 } 610 // Pointer return type. 611 else if (type_flags & eTypeIsPointer) { 612 auto reg_info_a0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, 613 LLDB_REGNUM_GENERIC_ARG1); 614 value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0); 615 value.SetValueType(Value::ValueType::Scalar); 616 return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), 617 value, ConstString("")); 618 } 619 // Floating point return type. 620 else if (type_flags & eTypeIsFloat) { 621 const uint32_t arch_fp_flags = 622 arch.GetFlags() & ArchSpec::eRISCV_float_abi_mask; 623 return_valobj_sp = GetValObjFromFPRegs( 624 thread, reg_ctx, machine, arch_fp_flags, type_flags, byte_size); 625 return return_valobj_sp; 626 } 627 // Unsupported return type. 628 return return_valobj_sp; 629} 630 631ValueObjectSP ABISysV_riscv::GetReturnValueObjectImpl( 632 Thread &thread, CompilerType &return_compiler_type) const { 633 ValueObjectSP return_valobj_sp; 634 635 if (!return_compiler_type) 636 return return_valobj_sp; 637 638 ExecutionContext exe_ctx(thread.shared_from_this()); 639 return GetReturnValueObjectSimple(thread, return_compiler_type); 640} 641 642bool ABISysV_riscv::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { 643 unwind_plan.Clear(); 644 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 645 646 uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC; 647 uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP; 648 uint32_t ra_reg_num = LLDB_REGNUM_GENERIC_RA; 649 650 UnwindPlan::RowSP row(new UnwindPlan::Row); 651 652 // Define CFA as the stack pointer 653 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0); 654 655 // Previous frame's pc is in ra 656 657 row->SetRegisterLocationToRegister(pc_reg_num, ra_reg_num, true); 658 unwind_plan.AppendRow(row); 659 unwind_plan.SetSourceName("riscv function-entry unwind plan"); 660 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 661 662 return true; 663} 664 665bool ABISysV_riscv::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { 666 unwind_plan.Clear(); 667 unwind_plan.SetRegisterKind(eRegisterKindGeneric); 668 669 uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC; 670 uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP; 671 672 UnwindPlan::RowSP row(new UnwindPlan::Row); 673 674 // Define the CFA as the current frame pointer value. 675 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 0); 676 row->SetOffset(0); 677 678 int reg_size = 4; 679 if (m_is_rv64) 680 reg_size = 8; 681 682 // Assume the ra reg (return pc) and caller's frame pointer 683 // have been spilled to stack already. 684 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, reg_size * -2, true); 685 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, reg_size * -1, true); 686 687 unwind_plan.AppendRow(row); 688 unwind_plan.SetSourceName("riscv default unwind plan"); 689 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 690 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); 691 return true; 692} 693 694bool ABISysV_riscv::RegisterIsVolatile(const RegisterInfo *reg_info) { 695 return !RegisterIsCalleeSaved(reg_info); 696} 697 698bool ABISysV_riscv::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { 699 if (!reg_info) 700 return false; 701 702 const char *name = reg_info->name; 703 ArchSpec arch = GetProcessSP()->GetTarget().GetArchitecture(); 704 uint32_t arch_flags = arch.GetFlags(); 705 // floating point registers are only callee saved when using 706 // F, D or Q hardware floating point ABIs 707 bool is_hw_fp = (arch_flags & ArchSpec::eRISCV_float_abi_mask) != 0; 708 709 bool is_callee_saved = 710 llvm::StringSwitch<bool>(name) 711 // integer ABI names 712 .Cases("ra", "sp", "fp", true) 713 .Cases("s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", 714 true) 715 .Cases("s10", "s11", true) 716 // integer hardware names 717 .Cases("x1", "x2", "x8", "x9", "x18", "x19", "x20", "x21", "x22", 718 true) 719 .Cases("x23", "x24", "x25", "x26", "x27", true) 720 // floating point ABI names 721 .Cases("fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", 722 is_hw_fp) 723 .Cases("fs8", "fs9", "fs10", "fs11", is_hw_fp) 724 // floating point hardware names 725 .Cases("f8", "f9", "f18", "f19", "f20", "f21", "f22", "f23", is_hw_fp) 726 .Cases("f24", "f25", "f26", "f27", is_hw_fp) 727 .Default(false); 728 729 return is_callee_saved; 730} 731 732void ABISysV_riscv::Initialize() { 733 PluginManager::RegisterPlugin( 734 GetPluginNameStatic(), "System V ABI for RISCV targets", CreateInstance); 735} 736 737void ABISysV_riscv::Terminate() { 738 PluginManager::UnregisterPlugin(CreateInstance); 739} 740 741static uint32_t GetGenericNum(llvm::StringRef name) { 742 return llvm::StringSwitch<uint32_t>(name) 743 .Case("pc", LLDB_REGNUM_GENERIC_PC) 744 .Cases("ra", "x1", LLDB_REGNUM_GENERIC_RA) 745 .Cases("sp", "x2", LLDB_REGNUM_GENERIC_SP) 746 .Cases("fp", "s0", LLDB_REGNUM_GENERIC_FP) 747 .Case("a0", LLDB_REGNUM_GENERIC_ARG1) 748 .Case("a1", LLDB_REGNUM_GENERIC_ARG2) 749 .Case("a2", LLDB_REGNUM_GENERIC_ARG3) 750 .Case("a3", LLDB_REGNUM_GENERIC_ARG4) 751 .Case("a4", LLDB_REGNUM_GENERIC_ARG5) 752 .Case("a5", LLDB_REGNUM_GENERIC_ARG6) 753 .Case("a6", LLDB_REGNUM_GENERIC_ARG7) 754 .Case("a7", LLDB_REGNUM_GENERIC_ARG8) 755 .Default(LLDB_INVALID_REGNUM); 756} 757 758void ABISysV_riscv::AugmentRegisterInfo( 759 std::vector<lldb_private::DynamicRegisterInfo::Register> ®s) { 760 lldb_private::RegInfoBasedABI::AugmentRegisterInfo(regs); 761 762 for (auto it : llvm::enumerate(regs)) { 763 // Set alt name for certain registers for convenience 764 if (it.value().name == "zero") 765 it.value().alt_name.SetCString("x0"); 766 else if (it.value().name == "ra") 767 it.value().alt_name.SetCString("x1"); 768 else if (it.value().name == "sp") 769 it.value().alt_name.SetCString("x2"); 770 else if (it.value().name == "gp") 771 it.value().alt_name.SetCString("x3"); 772 else if (it.value().name == "fp") 773 it.value().alt_name.SetCString("s0"); 774 else if (it.value().name == "s0") 775 it.value().alt_name.SetCString("x8"); 776 777 // Set generic regnum so lldb knows what the PC, etc is 778 it.value().regnum_generic = GetGenericNum(it.value().name.GetStringRef()); 779 } 780} 781