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