1 //===-- ABISysV_mips64.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_mips64.h" 10 11 #include "llvm/ADT/STLExtras.h" 12 #include "llvm/ADT/Triple.h" 13 14 #include "lldb/Core/Module.h" 15 #include "lldb/Core/PluginManager.h" 16 #include "lldb/Core/Value.h" 17 #include "lldb/Core/ValueObjectConstResult.h" 18 #include "lldb/Core/ValueObjectMemory.h" 19 #include "lldb/Core/ValueObjectRegister.h" 20 #include "lldb/Symbol/UnwindPlan.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/RegisterContext.h" 23 #include "lldb/Target/StackFrame.h" 24 #include "lldb/Target/Target.h" 25 #include "lldb/Target/Thread.h" 26 #include "lldb/Utility/ConstString.h" 27 #include "lldb/Utility/DataExtractor.h" 28 #include "lldb/Utility/LLDBLog.h" 29 #include "lldb/Utility/Log.h" 30 #include "lldb/Utility/RegisterValue.h" 31 #include "lldb/Utility/Status.h" 32 #include <optional> 33 34 using namespace lldb; 35 using namespace lldb_private; 36 37 LLDB_PLUGIN_DEFINE(ABISysV_mips64) 38 39 enum dwarf_regnums { 40 dwarf_r0 = 0, 41 dwarf_r1, 42 dwarf_r2, 43 dwarf_r3, 44 dwarf_r4, 45 dwarf_r5, 46 dwarf_r6, 47 dwarf_r7, 48 dwarf_r8, 49 dwarf_r9, 50 dwarf_r10, 51 dwarf_r11, 52 dwarf_r12, 53 dwarf_r13, 54 dwarf_r14, 55 dwarf_r15, 56 dwarf_r16, 57 dwarf_r17, 58 dwarf_r18, 59 dwarf_r19, 60 dwarf_r20, 61 dwarf_r21, 62 dwarf_r22, 63 dwarf_r23, 64 dwarf_r24, 65 dwarf_r25, 66 dwarf_r26, 67 dwarf_r27, 68 dwarf_r28, 69 dwarf_r29, 70 dwarf_r30, 71 dwarf_r31, 72 dwarf_sr, 73 dwarf_lo, 74 dwarf_hi, 75 dwarf_bad, 76 dwarf_cause, 77 dwarf_pc 78 }; 79 80 static const RegisterInfo g_register_infos_mips64[] = { 81 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME 82 // DWARF GENERIC PROCESS PLUGIN 83 // LLDB NATIVE 84 // ======== ====== == === ============= ========== ============= 85 // ================= ==================== ================= 86 // ==================== 87 {"r0", 88 "zero", 89 8, 90 0, 91 eEncodingUint, 92 eFormatHex, 93 {dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 94 LLDB_INVALID_REGNUM}, 95 nullptr, 96 nullptr, 97 }, 98 {"r1", 99 "AT", 100 8, 101 0, 102 eEncodingUint, 103 eFormatHex, 104 {dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 105 LLDB_INVALID_REGNUM}, 106 nullptr, 107 nullptr, 108 }, 109 {"r2", 110 "v0", 111 8, 112 0, 113 eEncodingUint, 114 eFormatHex, 115 {dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 116 LLDB_INVALID_REGNUM}, 117 nullptr, 118 nullptr, 119 }, 120 {"r3", 121 "v1", 122 8, 123 0, 124 eEncodingUint, 125 eFormatHex, 126 {dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 127 LLDB_INVALID_REGNUM}, 128 nullptr, 129 nullptr, 130 }, 131 {"r4", 132 nullptr, 133 8, 134 0, 135 eEncodingUint, 136 eFormatHex, 137 {dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, 138 LLDB_INVALID_REGNUM}, 139 nullptr, 140 nullptr, 141 }, 142 {"r5", 143 nullptr, 144 8, 145 0, 146 eEncodingUint, 147 eFormatHex, 148 {dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, 149 LLDB_INVALID_REGNUM}, 150 nullptr, 151 nullptr, 152 }, 153 {"r6", 154 nullptr, 155 8, 156 0, 157 eEncodingUint, 158 eFormatHex, 159 {dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, 160 LLDB_INVALID_REGNUM}, 161 nullptr, 162 nullptr, 163 }, 164 {"r7", 165 nullptr, 166 8, 167 0, 168 eEncodingUint, 169 eFormatHex, 170 {dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, 171 LLDB_INVALID_REGNUM}, 172 nullptr, 173 nullptr, 174 }, 175 {"r8", 176 nullptr, 177 8, 178 0, 179 eEncodingUint, 180 eFormatHex, 181 {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, 182 LLDB_INVALID_REGNUM}, 183 nullptr, 184 nullptr, 185 }, 186 {"r9", 187 nullptr, 188 8, 189 0, 190 eEncodingUint, 191 eFormatHex, 192 {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, 193 LLDB_INVALID_REGNUM}, 194 nullptr, 195 nullptr, 196 }, 197 {"r10", 198 nullptr, 199 8, 200 0, 201 eEncodingUint, 202 eFormatHex, 203 {dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, 204 LLDB_INVALID_REGNUM}, 205 nullptr, 206 nullptr, 207 }, 208 {"r11", 209 nullptr, 210 8, 211 0, 212 eEncodingUint, 213 eFormatHex, 214 {dwarf_r11, dwarf_r11, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, 215 LLDB_INVALID_REGNUM}, 216 nullptr, 217 nullptr, 218 }, 219 {"r12", 220 nullptr, 221 8, 222 0, 223 eEncodingUint, 224 eFormatHex, 225 {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 226 LLDB_INVALID_REGNUM}, 227 nullptr, 228 nullptr, 229 }, 230 {"r13", 231 nullptr, 232 8, 233 0, 234 eEncodingUint, 235 eFormatHex, 236 {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 237 LLDB_INVALID_REGNUM}, 238 nullptr, 239 nullptr, 240 }, 241 {"r14", 242 nullptr, 243 8, 244 0, 245 eEncodingUint, 246 eFormatHex, 247 {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 248 LLDB_INVALID_REGNUM}, 249 nullptr, 250 nullptr, 251 }, 252 {"r15", 253 nullptr, 254 8, 255 0, 256 eEncodingUint, 257 eFormatHex, 258 {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 259 LLDB_INVALID_REGNUM}, 260 nullptr, 261 nullptr, 262 }, 263 {"r16", 264 nullptr, 265 8, 266 0, 267 eEncodingUint, 268 eFormatHex, 269 {dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 270 LLDB_INVALID_REGNUM}, 271 nullptr, 272 nullptr, 273 }, 274 {"r17", 275 nullptr, 276 8, 277 0, 278 eEncodingUint, 279 eFormatHex, 280 {dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 281 LLDB_INVALID_REGNUM}, 282 nullptr, 283 nullptr, 284 }, 285 {"r18", 286 nullptr, 287 8, 288 0, 289 eEncodingUint, 290 eFormatHex, 291 {dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 292 LLDB_INVALID_REGNUM}, 293 nullptr, 294 nullptr, 295 }, 296 {"r19", 297 nullptr, 298 8, 299 0, 300 eEncodingUint, 301 eFormatHex, 302 {dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 303 LLDB_INVALID_REGNUM}, 304 nullptr, 305 nullptr, 306 }, 307 {"r20", 308 nullptr, 309 8, 310 0, 311 eEncodingUint, 312 eFormatHex, 313 {dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 314 LLDB_INVALID_REGNUM}, 315 nullptr, 316 nullptr, 317 }, 318 {"r21", 319 nullptr, 320 8, 321 0, 322 eEncodingUint, 323 eFormatHex, 324 {dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 325 LLDB_INVALID_REGNUM}, 326 nullptr, 327 nullptr, 328 }, 329 {"r22", 330 nullptr, 331 8, 332 0, 333 eEncodingUint, 334 eFormatHex, 335 {dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 336 LLDB_INVALID_REGNUM}, 337 nullptr, 338 nullptr, 339 }, 340 {"r23", 341 nullptr, 342 8, 343 0, 344 eEncodingUint, 345 eFormatHex, 346 {dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 347 LLDB_INVALID_REGNUM}, 348 nullptr, 349 nullptr, 350 }, 351 {"r24", 352 nullptr, 353 8, 354 0, 355 eEncodingUint, 356 eFormatHex, 357 {dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 358 LLDB_INVALID_REGNUM}, 359 nullptr, 360 nullptr, 361 }, 362 {"r25", 363 nullptr, 364 8, 365 0, 366 eEncodingUint, 367 eFormatHex, 368 {dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 369 LLDB_INVALID_REGNUM}, 370 nullptr, 371 nullptr, 372 }, 373 {"r26", 374 nullptr, 375 8, 376 0, 377 eEncodingUint, 378 eFormatHex, 379 {dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 380 LLDB_INVALID_REGNUM}, 381 nullptr, 382 nullptr, 383 }, 384 {"r27", 385 nullptr, 386 8, 387 0, 388 eEncodingUint, 389 eFormatHex, 390 {dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 391 LLDB_INVALID_REGNUM}, 392 nullptr, 393 nullptr, 394 }, 395 {"r28", 396 "gp", 397 8, 398 0, 399 eEncodingUint, 400 eFormatHex, 401 {dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 402 LLDB_INVALID_REGNUM}, 403 nullptr, 404 nullptr, 405 }, 406 {"r29", 407 nullptr, 408 8, 409 0, 410 eEncodingUint, 411 eFormatHex, 412 {dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, 413 LLDB_INVALID_REGNUM}, 414 nullptr, 415 nullptr, 416 }, 417 {"r30", 418 nullptr, 419 8, 420 0, 421 eEncodingUint, 422 eFormatHex, 423 {dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, 424 LLDB_INVALID_REGNUM}, 425 nullptr, 426 nullptr, 427 }, 428 {"r31", 429 nullptr, 430 8, 431 0, 432 eEncodingUint, 433 eFormatHex, 434 {dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, 435 LLDB_INVALID_REGNUM}, 436 nullptr, 437 nullptr, 438 }, 439 {"sr", 440 nullptr, 441 4, 442 0, 443 eEncodingUint, 444 eFormatHex, 445 {dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 446 LLDB_INVALID_REGNUM}, 447 nullptr, 448 nullptr, 449 }, 450 {"lo", 451 nullptr, 452 8, 453 0, 454 eEncodingUint, 455 eFormatHex, 456 {dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 457 LLDB_INVALID_REGNUM}, 458 nullptr, 459 nullptr, 460 }, 461 {"hi", 462 nullptr, 463 8, 464 0, 465 eEncodingUint, 466 eFormatHex, 467 {dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 468 LLDB_INVALID_REGNUM}, 469 nullptr, 470 nullptr, 471 }, 472 {"bad", 473 nullptr, 474 8, 475 0, 476 eEncodingUint, 477 eFormatHex, 478 {dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 479 LLDB_INVALID_REGNUM}, 480 nullptr, 481 nullptr, 482 }, 483 {"cause", 484 nullptr, 485 8, 486 0, 487 eEncodingUint, 488 eFormatHex, 489 {dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 490 LLDB_INVALID_REGNUM}, 491 nullptr, 492 nullptr, 493 }, 494 {"pc", 495 nullptr, 496 8, 497 0, 498 eEncodingUint, 499 eFormatHex, 500 {dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, 501 LLDB_INVALID_REGNUM}, 502 nullptr, 503 nullptr, 504 }, 505 }; 506 507 static const uint32_t k_num_register_infos = std::size(g_register_infos_mips64); 508 509 const lldb_private::RegisterInfo * 510 ABISysV_mips64::GetRegisterInfoArray(uint32_t &count) { 511 count = k_num_register_infos; 512 return g_register_infos_mips64; 513 } 514 515 size_t ABISysV_mips64::GetRedZoneSize() const { return 0; } 516 517 // Static Functions 518 519 ABISP 520 ABISysV_mips64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { 521 if (arch.GetTriple().isMIPS64()) 522 return ABISP( 523 new ABISysV_mips64(std::move(process_sp), MakeMCRegisterInfo(arch))); 524 return ABISP(); 525 } 526 527 bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp, 528 addr_t func_addr, addr_t return_addr, 529 llvm::ArrayRef<addr_t> args) const { 530 Log *log = GetLog(LLDBLog::Expressions); 531 532 if (log) { 533 StreamString s; 534 s.Printf("ABISysV_mips64::PrepareTrivialCall (tid = 0x%" PRIx64 535 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 536 ", return_addr = 0x%" PRIx64, 537 thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, 538 (uint64_t)return_addr); 539 540 for (size_t i = 0; i < args.size(); ++i) 541 s.Printf(", arg%zd = 0x%" PRIx64, i + 1, args[i]); 542 s.PutCString(")"); 543 log->PutString(s.GetString()); 544 } 545 546 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 547 if (!reg_ctx) 548 return false; 549 550 const RegisterInfo *reg_info = nullptr; 551 552 if (args.size() > 8) // TODO handle more than 8 arguments 553 return false; 554 555 for (size_t i = 0; i < args.size(); ++i) { 556 reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, 557 LLDB_REGNUM_GENERIC_ARG1 + i); 558 LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, 559 args[i], reg_info->name); 560 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) 561 return false; 562 } 563 564 // First, align the SP 565 566 LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, 567 (uint64_t)sp, (uint64_t)(sp & ~0xfull)); 568 569 sp &= ~(0xfull); // 16-byte alignment 570 571 Status error; 572 const RegisterInfo *pc_reg_info = 573 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 574 const RegisterInfo *sp_reg_info = 575 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 576 const RegisterInfo *ra_reg_info = 577 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); 578 const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0); 579 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0); 580 581 LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0); 582 583 /* Write r0 with 0, in case we are stopped in syscall, 584 * such setting prevents automatic decrement of the PC. 585 * This clears the bug 23659 for MIPS. 586 */ 587 if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0)) 588 return false; 589 590 LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); 591 592 // Set "sp" to the requested value 593 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) 594 return false; 595 596 LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr); 597 598 // Set "ra" to the return address 599 if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr)) 600 return false; 601 602 LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr); 603 604 // Set pc to the address of the called function. 605 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) 606 return false; 607 608 LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr); 609 610 // All callers of position independent functions must place the address of 611 // the called function in t9 (r25) 612 if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr)) 613 return false; 614 615 return true; 616 } 617 618 bool ABISysV_mips64::GetArgumentValues(Thread &thread, 619 ValueList &values) const { 620 return false; 621 } 622 623 Status ABISysV_mips64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, 624 lldb::ValueObjectSP &new_value_sp) { 625 Status error; 626 if (!new_value_sp) { 627 error.SetErrorString("Empty value object for return value."); 628 return error; 629 } 630 631 CompilerType compiler_type = new_value_sp->GetCompilerType(); 632 if (!compiler_type) { 633 error.SetErrorString("Null clang type for return value."); 634 return error; 635 } 636 637 Thread *thread = frame_sp->GetThread().get(); 638 639 RegisterContext *reg_ctx = thread->GetRegisterContext().get(); 640 641 if (!reg_ctx) 642 error.SetErrorString("no registers are available"); 643 644 DataExtractor data; 645 Status data_error; 646 size_t num_bytes = new_value_sp->GetData(data, data_error); 647 if (data_error.Fail()) { 648 error.SetErrorStringWithFormat( 649 "Couldn't convert return value to raw data: %s", 650 data_error.AsCString()); 651 return error; 652 } 653 654 const uint32_t type_flags = compiler_type.GetTypeInfo(nullptr); 655 656 if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { 657 if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { 658 lldb::offset_t offset = 0; 659 660 if (num_bytes <= 16) { 661 const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0); 662 if (num_bytes <= 8) { 663 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); 664 665 if (!reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) 666 error.SetErrorString("failed to write register r2"); 667 } else { 668 uint64_t raw_value = data.GetMaxU64(&offset, 8); 669 if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) { 670 const RegisterInfo *r3_info = 671 reg_ctx->GetRegisterInfoByName("r3", 0); 672 raw_value = data.GetMaxU64(&offset, num_bytes - offset); 673 674 if (!reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value)) 675 error.SetErrorString("failed to write register r3"); 676 } else 677 error.SetErrorString("failed to write register r2"); 678 } 679 } else { 680 error.SetErrorString("We don't support returning longer than 128 bit " 681 "integer values at present."); 682 } 683 } else if (type_flags & eTypeIsFloat) { 684 error.SetErrorString("TODO: Handle Float Types."); 685 } 686 } else if (type_flags & eTypeIsVector) { 687 error.SetErrorString("returning vector values are not supported"); 688 } 689 690 return error; 691 } 692 693 ValueObjectSP ABISysV_mips64::GetReturnValueObjectSimple( 694 Thread &thread, CompilerType &return_compiler_type) const { 695 ValueObjectSP return_valobj_sp; 696 return return_valobj_sp; 697 } 698 699 ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( 700 Thread &thread, CompilerType &return_compiler_type) const { 701 ValueObjectSP return_valobj_sp; 702 Value value; 703 Status error; 704 705 ExecutionContext exe_ctx(thread.shared_from_this()); 706 if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr) 707 return return_valobj_sp; 708 709 value.SetCompilerType(return_compiler_type); 710 711 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 712 if (!reg_ctx) 713 return return_valobj_sp; 714 715 Target *target = exe_ctx.GetTargetPtr(); 716 const ArchSpec target_arch = target->GetArchitecture(); 717 ByteOrder target_byte_order = target_arch.GetByteOrder(); 718 std::optional<uint64_t> byte_size = return_compiler_type.GetByteSize(&thread); 719 if (!byte_size) 720 return return_valobj_sp; 721 const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr); 722 uint32_t fp_flag = 723 target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask; 724 725 const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0); 726 const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0); 727 assert(r2_info && r3_info && "Basic registers should always be present."); 728 729 if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { 730 value.SetValueType(Value::ValueType::Scalar); 731 732 bool success = false; 733 if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { 734 // Extract the register context so we can read arguments from registers 735 // In MIPS register "r2" (v0) holds the integer function return values 736 737 uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0); 738 739 const bool is_signed = (type_flags & eTypeIsSigned) != 0; 740 switch (*byte_size) { 741 default: 742 break; 743 744 case sizeof(uint64_t): 745 if (is_signed) 746 value.GetScalar() = (int64_t)(raw_value); 747 else 748 value.GetScalar() = (uint64_t)(raw_value); 749 success = true; 750 break; 751 752 case sizeof(uint32_t): 753 if (is_signed) 754 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); 755 else 756 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); 757 success = true; 758 break; 759 760 case sizeof(uint16_t): 761 if (is_signed) 762 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); 763 else 764 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); 765 success = true; 766 break; 767 768 case sizeof(uint8_t): 769 if (is_signed) 770 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); 771 else 772 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); 773 success = true; 774 break; 775 } 776 } else if (type_flags & eTypeIsFloat) { 777 if (type_flags & eTypeIsComplex) { 778 // Don't handle complex yet. 779 } else if (IsSoftFloat(fp_flag)) { 780 uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0); 781 switch (*byte_size) { 782 case 4: 783 value.GetScalar() = *((float *)(&raw_value)); 784 success = true; 785 break; 786 case 8: 787 value.GetScalar() = *((double *)(&raw_value)); 788 success = true; 789 break; 790 case 16: 791 uint64_t result[2]; 792 if (target_byte_order == eByteOrderLittle) { 793 result[0] = raw_value; 794 result[1] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0); 795 value.GetScalar() = *((long double *)(result)); 796 } else { 797 result[0] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0); 798 result[1] = raw_value; 799 value.GetScalar() = *((long double *)(result)); 800 } 801 success = true; 802 break; 803 } 804 805 } else { 806 if (*byte_size <= sizeof(long double)) { 807 const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0); 808 809 RegisterValue f0_value; 810 DataExtractor f0_data; 811 812 reg_ctx->ReadRegister(f0_info, f0_value); 813 814 f0_value.GetData(f0_data); 815 816 lldb::offset_t offset = 0; 817 if (*byte_size == sizeof(float)) { 818 value.GetScalar() = (float)f0_data.GetFloat(&offset); 819 success = true; 820 } else if (*byte_size == sizeof(double)) { 821 value.GetScalar() = (double)f0_data.GetDouble(&offset); 822 success = true; 823 } else if (*byte_size == sizeof(long double)) { 824 const RegisterInfo *f2_info = 825 reg_ctx->GetRegisterInfoByName("f2", 0); 826 RegisterValue f2_value; 827 DataExtractor f2_data; 828 reg_ctx->ReadRegister(f2_info, f2_value); 829 DataExtractor *copy_from_extractor = nullptr; 830 WritableDataBufferSP data_sp(new DataBufferHeap(16, 0)); 831 DataExtractor return_ext( 832 data_sp, target_byte_order, 833 target->GetArchitecture().GetAddressByteSize()); 834 835 if (target_byte_order == eByteOrderLittle) { 836 copy_from_extractor = &f0_data; 837 copy_from_extractor->CopyByteOrderedData( 838 0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order); 839 f2_value.GetData(f2_data); 840 copy_from_extractor = &f2_data; 841 copy_from_extractor->CopyByteOrderedData( 842 0, 8, data_sp->GetBytes() + 8, *byte_size - 8, 843 target_byte_order); 844 } else { 845 copy_from_extractor = &f0_data; 846 copy_from_extractor->CopyByteOrderedData( 847 0, 8, data_sp->GetBytes() + 8, *byte_size - 8, 848 target_byte_order); 849 f2_value.GetData(f2_data); 850 copy_from_extractor = &f2_data; 851 copy_from_extractor->CopyByteOrderedData( 852 0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order); 853 } 854 855 return_valobj_sp = ValueObjectConstResult::Create( 856 &thread, return_compiler_type, ConstString(""), return_ext); 857 return return_valobj_sp; 858 } 859 } 860 } 861 } 862 863 if (success) 864 return_valobj_sp = ValueObjectConstResult::Create( 865 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 866 } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass || 867 type_flags & eTypeIsVector) { 868 // Any structure of up to 16 bytes in size is returned in the registers. 869 if (*byte_size <= 16) { 870 WritableDataBufferSP data_sp(new DataBufferHeap(16, 0)); 871 DataExtractor return_ext(data_sp, target_byte_order, 872 target->GetArchitecture().GetAddressByteSize()); 873 874 RegisterValue r2_value, r3_value, f0_value, f1_value, f2_value; 875 // Tracks how much bytes of r2 and r3 registers we've consumed so far 876 uint32_t integer_bytes = 0; 877 878 // True if return values are in FP return registers. 879 bool use_fp_regs = false; 880 // True if we found any non floating point field in structure. 881 bool found_non_fp_field = false; 882 // True if return values are in r2 register. 883 bool use_r2 = false; 884 // True if return values are in r3 register. 885 bool use_r3 = false; 886 // True if the result is copied into our data buffer 887 bool sucess = false; 888 std::string name; 889 bool is_complex; 890 uint32_t count; 891 const uint32_t num_children = return_compiler_type.GetNumFields(); 892 893 // A structure consisting of one or two FP values (and nothing else) will 894 // be returned in the two FP return-value registers i.e fp0 and fp2. 895 if (num_children <= 2) { 896 uint64_t field_bit_offset = 0; 897 898 // Check if this structure contains only floating point fields 899 for (uint32_t idx = 0; idx < num_children; idx++) { 900 CompilerType field_compiler_type = 901 return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset, 902 nullptr, nullptr); 903 904 if (field_compiler_type.IsFloatingPointType(count, is_complex)) 905 use_fp_regs = true; 906 else 907 found_non_fp_field = true; 908 } 909 910 if (use_fp_regs && !found_non_fp_field) { 911 // We have one or two FP-only values in this structure. Get it from 912 // f0/f2 registers. 913 DataExtractor f0_data, f1_data, f2_data; 914 const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0); 915 const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0); 916 const RegisterInfo *f2_info = reg_ctx->GetRegisterInfoByName("f2", 0); 917 918 reg_ctx->ReadRegister(f0_info, f0_value); 919 reg_ctx->ReadRegister(f2_info, f2_value); 920 921 f0_value.GetData(f0_data); 922 923 for (uint32_t idx = 0; idx < num_children; idx++) { 924 CompilerType field_compiler_type = 925 return_compiler_type.GetFieldAtIndex( 926 idx, name, &field_bit_offset, nullptr, nullptr); 927 std::optional<uint64_t> field_byte_width = 928 field_compiler_type.GetByteSize(&thread); 929 if (!field_byte_width) 930 return return_valobj_sp; 931 932 DataExtractor *copy_from_extractor = nullptr; 933 uint64_t return_value[2]; 934 offset_t offset = 0; 935 936 if (idx == 0) { 937 // This case is for long double type. 938 if (*field_byte_width == 16) { 939 940 // If structure contains long double type, then it is returned 941 // in fp0/fp1 registers. 942 if (target_byte_order == eByteOrderLittle) { 943 return_value[0] = f0_data.GetU64(&offset); 944 reg_ctx->ReadRegister(f1_info, f1_value); 945 f1_value.GetData(f1_data); 946 offset = 0; 947 return_value[1] = f1_data.GetU64(&offset); 948 } else { 949 return_value[1] = f0_data.GetU64(&offset); 950 reg_ctx->ReadRegister(f1_info, f1_value); 951 f1_value.GetData(f1_data); 952 offset = 0; 953 return_value[0] = f1_data.GetU64(&offset); 954 } 955 956 f0_data.SetData(return_value, *field_byte_width, 957 target_byte_order); 958 } 959 copy_from_extractor = &f0_data; // This is in f0, copy from 960 // register to our result 961 // structure 962 } else { 963 f2_value.GetData(f2_data); 964 // This is in f2, copy from register to our result structure 965 copy_from_extractor = &f2_data; 966 } 967 968 // Sanity check to avoid crash 969 if (!copy_from_extractor || 970 *field_byte_width > copy_from_extractor->GetByteSize()) 971 return return_valobj_sp; 972 973 // copy the register contents into our data buffer 974 copy_from_extractor->CopyByteOrderedData( 975 0, *field_byte_width, 976 data_sp->GetBytes() + (field_bit_offset / 8), *field_byte_width, 977 target_byte_order); 978 } 979 980 // The result is in our data buffer. Create a variable object out of 981 // it 982 return_valobj_sp = ValueObjectConstResult::Create( 983 &thread, return_compiler_type, ConstString(""), return_ext); 984 985 return return_valobj_sp; 986 } 987 } 988 989 // If we reach here, it means this structure either contains more than 990 // two fields or it contains at least one non floating point type. In 991 // that case, all fields are returned in GP return registers. 992 for (uint32_t idx = 0; idx < num_children; idx++) { 993 uint64_t field_bit_offset = 0; 994 bool is_signed; 995 uint32_t padding; 996 997 CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex( 998 idx, name, &field_bit_offset, nullptr, nullptr); 999 std::optional<uint64_t> field_byte_width = 1000 field_compiler_type.GetByteSize(&thread); 1001 1002 // if we don't know the size of the field (e.g. invalid type), just 1003 // bail out 1004 if (!field_byte_width || *field_byte_width == 0) 1005 break; 1006 1007 uint32_t field_byte_offset = field_bit_offset / 8; 1008 1009 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) || 1010 field_compiler_type.IsPointerType() || 1011 field_compiler_type.IsFloatingPointType(count, is_complex)) { 1012 padding = field_byte_offset - integer_bytes; 1013 1014 if (integer_bytes < 8) { 1015 // We have not yet consumed r2 completely. 1016 if (integer_bytes + *field_byte_width + padding <= 8) { 1017 // This field fits in r2, copy its value from r2 to our result 1018 // structure 1019 integer_bytes = integer_bytes + *field_byte_width + 1020 padding; // Increase the consumed bytes. 1021 use_r2 = true; 1022 } else { 1023 // There isn't enough space left in r2 for this field, so this 1024 // will be in r3. 1025 integer_bytes = integer_bytes + *field_byte_width + 1026 padding; // Increase the consumed bytes. 1027 use_r3 = true; 1028 } 1029 } 1030 // We already have consumed at-least 8 bytes that means r2 is done, 1031 // and this field will be in r3. Check if this field can fit in r3. 1032 else if (integer_bytes + *field_byte_width + padding <= 16) { 1033 integer_bytes = integer_bytes + *field_byte_width + padding; 1034 use_r3 = true; 1035 } else { 1036 // There isn't any space left for this field, this should not 1037 // happen as we have already checked the overall size is not 1038 // greater than 16 bytes. For now, return a nullptr return value 1039 // object. 1040 return return_valobj_sp; 1041 } 1042 } 1043 } 1044 // Vector types up to 16 bytes are returned in GP return registers 1045 if (type_flags & eTypeIsVector) { 1046 if (*byte_size <= 8) 1047 use_r2 = true; 1048 else { 1049 use_r2 = true; 1050 use_r3 = true; 1051 } 1052 } 1053 1054 if (use_r2) { 1055 reg_ctx->ReadRegister(r2_info, r2_value); 1056 1057 const size_t bytes_copied = r2_value.GetAsMemoryData( 1058 *r2_info, data_sp->GetBytes(), r2_info->byte_size, 1059 target_byte_order, error); 1060 if (bytes_copied != r2_info->byte_size) 1061 return return_valobj_sp; 1062 sucess = true; 1063 } 1064 if (use_r3) { 1065 reg_ctx->ReadRegister(r3_info, r3_value); 1066 const size_t bytes_copied = r3_value.GetAsMemoryData( 1067 *r3_info, data_sp->GetBytes() + r2_info->byte_size, 1068 r3_info->byte_size, target_byte_order, error); 1069 1070 if (bytes_copied != r3_info->byte_size) 1071 return return_valobj_sp; 1072 sucess = true; 1073 } 1074 if (sucess) { 1075 // The result is in our data buffer. Create a variable object out of 1076 // it 1077 return_valobj_sp = ValueObjectConstResult::Create( 1078 &thread, return_compiler_type, ConstString(""), return_ext); 1079 } 1080 return return_valobj_sp; 1081 } 1082 1083 // Any structure/vector greater than 16 bytes in size is returned in 1084 // memory. The pointer to that memory is returned in r2. 1085 uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned( 1086 reg_ctx->GetRegisterInfoByName("r2", 0), 0); 1087 1088 // We have got the address. Create a memory object out of it 1089 return_valobj_sp = ValueObjectMemory::Create( 1090 &thread, "", Address(mem_address, nullptr), return_compiler_type); 1091 } 1092 return return_valobj_sp; 1093 } 1094 1095 bool ABISysV_mips64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { 1096 unwind_plan.Clear(); 1097 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 1098 1099 UnwindPlan::RowSP row(new UnwindPlan::Row); 1100 1101 // Our Call Frame Address is the stack pointer value 1102 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0); 1103 1104 // The previous PC is in the RA 1105 row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true); 1106 unwind_plan.AppendRow(row); 1107 1108 // All other registers are the same. 1109 1110 unwind_plan.SetSourceName("mips64 at-func-entry default"); 1111 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 1112 unwind_plan.SetReturnAddressRegister(dwarf_r31); 1113 return true; 1114 } 1115 1116 bool ABISysV_mips64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { 1117 unwind_plan.Clear(); 1118 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 1119 1120 UnwindPlan::RowSP row(new UnwindPlan::Row); 1121 1122 row->SetUnspecifiedRegistersAreUndefined(true); 1123 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0); 1124 1125 row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true); 1126 1127 unwind_plan.AppendRow(row); 1128 unwind_plan.SetSourceName("mips64 default unwind plan"); 1129 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 1130 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); 1131 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 1132 return true; 1133 } 1134 1135 bool ABISysV_mips64::RegisterIsVolatile(const RegisterInfo *reg_info) { 1136 return !RegisterIsCalleeSaved(reg_info); 1137 } 1138 1139 bool ABISysV_mips64::IsSoftFloat(uint32_t fp_flag) const { 1140 return (fp_flag == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT); 1141 } 1142 1143 bool ABISysV_mips64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { 1144 if (reg_info) { 1145 // Preserved registers are : 1146 // r16-r23, r28, r29, r30, r31 1147 1148 int reg = ((reg_info->byte_offset) / 8); 1149 1150 bool save = (reg >= 16) && (reg <= 23); 1151 save |= (reg >= 28) && (reg <= 31); 1152 1153 return save; 1154 } 1155 return false; 1156 } 1157 1158 void ABISysV_mips64::Initialize() { 1159 PluginManager::RegisterPlugin( 1160 GetPluginNameStatic(), "System V ABI for mips64 targets", CreateInstance); 1161 } 1162 1163 void ABISysV_mips64::Terminate() { 1164 PluginManager::UnregisterPlugin(CreateInstance); 1165 } 1166