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