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