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