1 //===-- ABISysV_mips.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_mips.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_mips) 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[] = { 81 {"r0", 82 "zero", 83 4, 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 4, 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 {"r2", 106 "v0", 107 4, 108 0, 109 eEncodingUint, 110 eFormatHex, 111 {dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 112 LLDB_INVALID_REGNUM}, 113 nullptr, 114 nullptr, 115 nullptr, 116 }, 117 {"r3", 118 "v1", 119 4, 120 0, 121 eEncodingUint, 122 eFormatHex, 123 {dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 124 LLDB_INVALID_REGNUM}, 125 nullptr, 126 nullptr, 127 nullptr, 128 }, 129 {"r4", 130 nullptr, 131 4, 132 0, 133 eEncodingUint, 134 eFormatHex, 135 {dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, 136 LLDB_INVALID_REGNUM}, 137 nullptr, 138 nullptr, 139 nullptr, 140 }, 141 {"r5", 142 nullptr, 143 4, 144 0, 145 eEncodingUint, 146 eFormatHex, 147 {dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, 148 LLDB_INVALID_REGNUM}, 149 nullptr, 150 nullptr, 151 nullptr, 152 }, 153 {"r6", 154 nullptr, 155 4, 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 nullptr, 164 }, 165 {"r7", 166 nullptr, 167 4, 168 0, 169 eEncodingUint, 170 eFormatHex, 171 {dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, 172 LLDB_INVALID_REGNUM}, 173 nullptr, 174 nullptr, 175 nullptr, 176 }, 177 {"r8", 178 "arg5", 179 4, 180 0, 181 eEncodingUint, 182 eFormatHex, 183 {dwarf_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 184 LLDB_INVALID_REGNUM}, 185 nullptr, 186 nullptr, 187 nullptr, 188 }, 189 {"r9", 190 "arg6", 191 4, 192 0, 193 eEncodingUint, 194 eFormatHex, 195 {dwarf_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 196 LLDB_INVALID_REGNUM}, 197 nullptr, 198 nullptr, 199 nullptr, 200 }, 201 {"r10", 202 "arg7", 203 4, 204 0, 205 eEncodingUint, 206 eFormatHex, 207 {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 208 LLDB_INVALID_REGNUM}, 209 nullptr, 210 nullptr, 211 nullptr, 212 }, 213 {"r11", 214 "arg8", 215 4, 216 0, 217 eEncodingUint, 218 eFormatHex, 219 {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 220 LLDB_INVALID_REGNUM}, 221 nullptr, 222 nullptr, 223 nullptr, 224 }, 225 {"r12", 226 nullptr, 227 4, 228 0, 229 eEncodingUint, 230 eFormatHex, 231 {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 232 LLDB_INVALID_REGNUM}, 233 nullptr, 234 nullptr, 235 nullptr, 236 }, 237 {"r13", 238 nullptr, 239 4, 240 0, 241 eEncodingUint, 242 eFormatHex, 243 {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 244 LLDB_INVALID_REGNUM}, 245 nullptr, 246 nullptr, 247 nullptr, 248 }, 249 {"r14", 250 nullptr, 251 4, 252 0, 253 eEncodingUint, 254 eFormatHex, 255 {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 256 LLDB_INVALID_REGNUM}, 257 nullptr, 258 nullptr, 259 nullptr, 260 }, 261 {"r15", 262 nullptr, 263 4, 264 0, 265 eEncodingUint, 266 eFormatHex, 267 {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 268 LLDB_INVALID_REGNUM}, 269 nullptr, 270 nullptr, 271 nullptr, 272 }, 273 {"r16", 274 nullptr, 275 4, 276 0, 277 eEncodingUint, 278 eFormatHex, 279 {dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 280 LLDB_INVALID_REGNUM}, 281 nullptr, 282 nullptr, 283 nullptr, 284 }, 285 {"r17", 286 nullptr, 287 4, 288 0, 289 eEncodingUint, 290 eFormatHex, 291 {dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 292 LLDB_INVALID_REGNUM}, 293 nullptr, 294 nullptr, 295 nullptr, 296 }, 297 {"r18", 298 nullptr, 299 4, 300 0, 301 eEncodingUint, 302 eFormatHex, 303 {dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 304 LLDB_INVALID_REGNUM}, 305 nullptr, 306 nullptr, 307 nullptr, 308 }, 309 {"r19", 310 nullptr, 311 4, 312 0, 313 eEncodingUint, 314 eFormatHex, 315 {dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 316 LLDB_INVALID_REGNUM}, 317 nullptr, 318 nullptr, 319 nullptr, 320 }, 321 {"r20", 322 nullptr, 323 4, 324 0, 325 eEncodingUint, 326 eFormatHex, 327 {dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 328 LLDB_INVALID_REGNUM}, 329 nullptr, 330 nullptr, 331 nullptr, 332 }, 333 {"r21", 334 nullptr, 335 4, 336 0, 337 eEncodingUint, 338 eFormatHex, 339 {dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 340 LLDB_INVALID_REGNUM}, 341 nullptr, 342 nullptr, 343 nullptr, 344 }, 345 {"r22", 346 nullptr, 347 4, 348 0, 349 eEncodingUint, 350 eFormatHex, 351 {dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 352 LLDB_INVALID_REGNUM}, 353 nullptr, 354 nullptr, 355 nullptr, 356 }, 357 {"r23", 358 nullptr, 359 4, 360 0, 361 eEncodingUint, 362 eFormatHex, 363 {dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 364 LLDB_INVALID_REGNUM}, 365 nullptr, 366 nullptr, 367 nullptr, 368 }, 369 {"r24", 370 nullptr, 371 4, 372 0, 373 eEncodingUint, 374 eFormatHex, 375 {dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 376 LLDB_INVALID_REGNUM}, 377 nullptr, 378 nullptr, 379 nullptr, 380 }, 381 {"r25", 382 nullptr, 383 4, 384 0, 385 eEncodingUint, 386 eFormatHex, 387 {dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 388 LLDB_INVALID_REGNUM}, 389 nullptr, 390 nullptr, 391 nullptr, 392 }, 393 {"r26", 394 nullptr, 395 4, 396 0, 397 eEncodingUint, 398 eFormatHex, 399 {dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 400 LLDB_INVALID_REGNUM}, 401 nullptr, 402 nullptr, 403 nullptr, 404 }, 405 {"r27", 406 nullptr, 407 4, 408 0, 409 eEncodingUint, 410 eFormatHex, 411 {dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 412 LLDB_INVALID_REGNUM}, 413 nullptr, 414 nullptr, 415 nullptr, 416 }, 417 {"r28", 418 "gp", 419 4, 420 0, 421 eEncodingUint, 422 eFormatHex, 423 {dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 424 LLDB_INVALID_REGNUM}, 425 nullptr, 426 nullptr, 427 nullptr, 428 }, 429 {"r29", 430 nullptr, 431 4, 432 0, 433 eEncodingUint, 434 eFormatHex, 435 {dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, 436 LLDB_INVALID_REGNUM}, 437 nullptr, 438 nullptr, 439 nullptr, 440 }, 441 {"r30", 442 nullptr, 443 4, 444 0, 445 eEncodingUint, 446 eFormatHex, 447 {dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, 448 LLDB_INVALID_REGNUM}, 449 nullptr, 450 nullptr, 451 nullptr, 452 }, 453 {"r31", 454 nullptr, 455 4, 456 0, 457 eEncodingUint, 458 eFormatHex, 459 {dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, 460 LLDB_INVALID_REGNUM}, 461 nullptr, 462 nullptr, 463 nullptr, 464 }, 465 {"sr", 466 nullptr, 467 4, 468 0, 469 eEncodingUint, 470 eFormatHex, 471 {dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 472 LLDB_INVALID_REGNUM}, 473 nullptr, 474 nullptr, 475 nullptr, 476 }, 477 {"lo", 478 nullptr, 479 4, 480 0, 481 eEncodingUint, 482 eFormatHex, 483 {dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 484 LLDB_INVALID_REGNUM}, 485 nullptr, 486 nullptr, 487 nullptr, 488 }, 489 {"hi", 490 nullptr, 491 4, 492 0, 493 eEncodingUint, 494 eFormatHex, 495 {dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 496 LLDB_INVALID_REGNUM}, 497 nullptr, 498 nullptr, 499 nullptr, 500 }, 501 {"bad", 502 nullptr, 503 4, 504 0, 505 eEncodingUint, 506 eFormatHex, 507 {dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 508 LLDB_INVALID_REGNUM}, 509 nullptr, 510 nullptr, 511 nullptr, 512 }, 513 {"cause", 514 nullptr, 515 4, 516 0, 517 eEncodingUint, 518 eFormatHex, 519 {dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 520 LLDB_INVALID_REGNUM}, 521 nullptr, 522 nullptr, 523 nullptr, 524 }, 525 {"pc", 526 nullptr, 527 4, 528 0, 529 eEncodingUint, 530 eFormatHex, 531 {dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, 532 LLDB_INVALID_REGNUM}, 533 nullptr, 534 nullptr, 535 nullptr, 536 }, 537 }; 538 539 static const uint32_t k_num_register_infos = std::size(g_register_infos); 540 541 const lldb_private::RegisterInfo * 542 ABISysV_mips::GetRegisterInfoArray(uint32_t &count) { 543 count = k_num_register_infos; 544 return g_register_infos; 545 } 546 547 size_t ABISysV_mips::GetRedZoneSize() const { return 0; } 548 549 // Static Functions 550 551 ABISP 552 ABISysV_mips::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { 553 const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); 554 if ((arch_type == llvm::Triple::mips) || 555 (arch_type == llvm::Triple::mipsel)) { 556 return ABISP( 557 new ABISysV_mips(std::move(process_sp), MakeMCRegisterInfo(arch))); 558 } 559 return ABISP(); 560 } 561 562 bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp, 563 addr_t func_addr, addr_t return_addr, 564 llvm::ArrayRef<addr_t> args) const { 565 Log *log = GetLog(LLDBLog::Expressions); 566 567 if (log) { 568 StreamString s; 569 s.Printf("ABISysV_mips::PrepareTrivialCall (tid = 0x%" PRIx64 570 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 571 ", return_addr = 0x%" PRIx64, 572 thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, 573 (uint64_t)return_addr); 574 575 for (size_t i = 0; i < args.size(); ++i) 576 s.Printf(", arg%zd = 0x%" PRIx64, i + 1, args[i]); 577 s.PutCString(")"); 578 log->PutString(s.GetString()); 579 } 580 581 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 582 if (!reg_ctx) 583 return false; 584 585 const RegisterInfo *reg_info = nullptr; 586 587 RegisterValue reg_value; 588 589 // Argument registers 590 const char *reg_names[] = {"r4", "r5", "r6", "r7"}; 591 592 llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end(); 593 594 // Write arguments to registers 595 for (size_t i = 0; i < std::size(reg_names); ++i) { 596 if (ai == ae) 597 break; 598 599 reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, 600 LLDB_REGNUM_GENERIC_ARG1 + i); 601 LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, 602 args[i], reg_info->name); 603 604 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) 605 return false; 606 607 ++ai; 608 } 609 610 // If we have more than 4 arguments --Spill onto the stack 611 if (ai != ae) { 612 // No of arguments to go on stack 613 size_t num_stack_regs = args.size(); 614 615 // Allocate needed space for args on the stack 616 sp -= (num_stack_regs * 4); 617 618 // Keep the stack 8 byte aligned 619 sp &= ~(8ull - 1ull); 620 621 // just using arg1 to get the right size 622 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( 623 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); 624 625 addr_t arg_pos = sp + 16; 626 627 size_t i = 4; 628 for (; ai != ae; ++ai) { 629 reg_value.SetUInt32(*ai); 630 LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") at 0x%" PRIx64 "", 631 i + 1, args[i], arg_pos); 632 633 if (reg_ctx 634 ->WriteRegisterValueToMemory(reg_info, arg_pos, 635 reg_info->byte_size, reg_value) 636 .Fail()) 637 return false; 638 arg_pos += reg_info->byte_size; 639 i++; 640 } 641 } 642 643 Status error; 644 const RegisterInfo *pc_reg_info = 645 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 646 const RegisterInfo *sp_reg_info = 647 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 648 const RegisterInfo *ra_reg_info = 649 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); 650 const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0); 651 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0); 652 653 LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0); 654 655 /* Write r0 with 0, in case we are stopped in syscall, 656 * such setting prevents automatic decrement of the PC. 657 * This clears the bug 23659 for MIPS. 658 */ 659 if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0)) 660 return false; 661 662 LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); 663 664 // Set "sp" to the requested value 665 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) 666 return false; 667 668 LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr); 669 670 // Set "ra" to the return address 671 if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr)) 672 return false; 673 674 LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr); 675 676 // Set pc to the address of the called function. 677 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) 678 return false; 679 680 LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr); 681 682 // All callers of position independent functions must place the address of 683 // the called function in t9 (r25) 684 if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr)) 685 return false; 686 687 return true; 688 } 689 690 bool ABISysV_mips::GetArgumentValues(Thread &thread, ValueList &values) const { 691 return false; 692 } 693 694 Status ABISysV_mips::SetReturnValueObject(lldb::StackFrameSP &frame_sp, 695 lldb::ValueObjectSP &new_value_sp) { 696 Status error; 697 if (!new_value_sp) { 698 error = Status::FromErrorString("Empty value object for return value."); 699 return error; 700 } 701 702 CompilerType compiler_type = new_value_sp->GetCompilerType(); 703 if (!compiler_type) { 704 error = Status::FromErrorString("Null clang type for return value."); 705 return error; 706 } 707 708 Thread *thread = frame_sp->GetThread().get(); 709 710 bool is_signed; 711 uint32_t count; 712 bool is_complex; 713 714 RegisterContext *reg_ctx = thread->GetRegisterContext().get(); 715 716 bool set_it_simple = false; 717 if (compiler_type.IsIntegerOrEnumerationType(is_signed) || 718 compiler_type.IsPointerType()) { 719 DataExtractor data; 720 Status data_error; 721 size_t num_bytes = new_value_sp->GetData(data, data_error); 722 if (data_error.Fail()) { 723 error = Status::FromErrorStringWithFormat( 724 "Couldn't convert return value to raw data: %s", 725 data_error.AsCString()); 726 return error; 727 } 728 729 lldb::offset_t offset = 0; 730 if (num_bytes <= 8) { 731 const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0); 732 if (num_bytes <= 4) { 733 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); 734 735 if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) 736 set_it_simple = true; 737 } else { 738 uint32_t raw_value = data.GetMaxU32(&offset, 4); 739 740 if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) { 741 const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0); 742 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset); 743 744 if (reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value)) 745 set_it_simple = true; 746 } 747 } 748 } else { 749 error = Status::FromErrorString( 750 "We don't support returning longer than 64 bit " 751 "integer values at present."); 752 } 753 } else if (compiler_type.IsFloatingPointType(count, is_complex)) { 754 if (is_complex) 755 error = Status::FromErrorString( 756 "We don't support returning complex values at present"); 757 else 758 error = Status::FromErrorString( 759 "We don't support returning float values at present"); 760 } 761 762 if (!set_it_simple) 763 error = Status::FromErrorString( 764 "We only support setting simple integer return types at present."); 765 766 return error; 767 } 768 769 ValueObjectSP ABISysV_mips::GetReturnValueObjectSimple( 770 Thread &thread, CompilerType &return_compiler_type) const { 771 ValueObjectSP return_valobj_sp; 772 return return_valobj_sp; 773 } 774 775 ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl( 776 Thread &thread, CompilerType &return_compiler_type) const { 777 ValueObjectSP return_valobj_sp; 778 Value value; 779 780 if (!return_compiler_type) 781 return return_valobj_sp; 782 783 ExecutionContext exe_ctx(thread.shared_from_this()); 784 if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr) 785 return return_valobj_sp; 786 787 Target *target = exe_ctx.GetTargetPtr(); 788 const ArchSpec target_arch = target->GetArchitecture(); 789 ByteOrder target_byte_order = target_arch.GetByteOrder(); 790 value.SetCompilerType(return_compiler_type); 791 uint32_t fp_flag = 792 target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask; 793 794 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 795 if (!reg_ctx) 796 return return_valobj_sp; 797 798 bool is_signed = false; 799 bool is_complex = false; 800 uint32_t count = 0; 801 802 // In MIPS register "r2" (v0) holds the integer function return values 803 const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoByName("r2", 0); 804 std::optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread); 805 if (!bit_width) 806 return return_valobj_sp; 807 if (return_compiler_type.IsIntegerOrEnumerationType(is_signed)) { 808 switch (*bit_width) { 809 default: 810 return return_valobj_sp; 811 case 64: { 812 const RegisterInfo *r3_reg_info = reg_ctx->GetRegisterInfoByName("r3", 0); 813 uint64_t raw_value; 814 raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX; 815 raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0) & 816 UINT32_MAX)) 817 << 32; 818 if (is_signed) 819 value.GetScalar() = (int64_t)raw_value; 820 else 821 value.GetScalar() = (uint64_t)raw_value; 822 } break; 823 case 32: 824 if (is_signed) 825 value.GetScalar() = (int32_t)( 826 reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX); 827 else 828 value.GetScalar() = (uint32_t)( 829 reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX); 830 break; 831 case 16: 832 if (is_signed) 833 value.GetScalar() = (int16_t)( 834 reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX); 835 else 836 value.GetScalar() = (uint16_t)( 837 reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX); 838 break; 839 case 8: 840 if (is_signed) 841 value.GetScalar() = (int8_t)( 842 reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX); 843 else 844 value.GetScalar() = (uint8_t)( 845 reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX); 846 break; 847 } 848 } else if (return_compiler_type.IsPointerType()) { 849 uint32_t ptr = 850 thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_reg_info, 0) & 851 UINT32_MAX; 852 value.GetScalar() = ptr; 853 } else if (return_compiler_type.IsAggregateType()) { 854 // Structure/Vector is always passed in memory and pointer to that memory 855 // is passed in r2. 856 uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned( 857 reg_ctx->GetRegisterInfoByName("r2", 0), 0); 858 // We have got the address. Create a memory object out of it 859 return_valobj_sp = ValueObjectMemory::Create( 860 &thread, "", Address(mem_address, nullptr), return_compiler_type); 861 return return_valobj_sp; 862 } else if (return_compiler_type.IsFloatingPointType(count, is_complex)) { 863 if (IsSoftFloat(fp_flag)) { 864 uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0); 865 if (count != 1 && is_complex) 866 return return_valobj_sp; 867 switch (*bit_width) { 868 default: 869 return return_valobj_sp; 870 case 32: 871 static_assert(sizeof(float) == sizeof(uint32_t)); 872 value.GetScalar() = *((float *)(&raw_value)); 873 break; 874 case 64: 875 static_assert(sizeof(double) == sizeof(uint64_t)); 876 const RegisterInfo *r3_reg_info = 877 reg_ctx->GetRegisterInfoByName("r3", 0); 878 if (target_byte_order == eByteOrderLittle) 879 raw_value = 880 ((reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0)) << 32) | 881 raw_value; 882 else 883 raw_value = (raw_value << 32) | 884 reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0); 885 value.GetScalar() = *((double *)(&raw_value)); 886 break; 887 } 888 } 889 890 else { 891 const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0); 892 RegisterValue f0_value; 893 DataExtractor f0_data; 894 reg_ctx->ReadRegister(f0_info, f0_value); 895 f0_value.GetData(f0_data); 896 lldb::offset_t offset = 0; 897 898 if (count == 1 && !is_complex) { 899 switch (*bit_width) { 900 default: 901 return return_valobj_sp; 902 case 64: { 903 static_assert(sizeof(double) == sizeof(uint64_t)); 904 const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0); 905 RegisterValue f1_value; 906 DataExtractor f1_data; 907 reg_ctx->ReadRegister(f1_info, f1_value); 908 DataExtractor *copy_from_extractor = nullptr; 909 WritableDataBufferSP data_sp(new DataBufferHeap(8, 0)); 910 DataExtractor return_ext( 911 data_sp, target_byte_order, 912 target->GetArchitecture().GetAddressByteSize()); 913 914 if (target_byte_order == eByteOrderLittle) { 915 copy_from_extractor = &f0_data; 916 copy_from_extractor->CopyByteOrderedData( 917 offset, 4, data_sp->GetBytes(), 4, target_byte_order); 918 f1_value.GetData(f1_data); 919 copy_from_extractor = &f1_data; 920 copy_from_extractor->CopyByteOrderedData( 921 offset, 4, data_sp->GetBytes() + 4, 4, target_byte_order); 922 } else { 923 copy_from_extractor = &f0_data; 924 copy_from_extractor->CopyByteOrderedData( 925 offset, 4, data_sp->GetBytes() + 4, 4, target_byte_order); 926 f1_value.GetData(f1_data); 927 copy_from_extractor = &f1_data; 928 copy_from_extractor->CopyByteOrderedData( 929 offset, 4, data_sp->GetBytes(), 4, target_byte_order); 930 } 931 value.GetScalar() = (double)return_ext.GetDouble(&offset); 932 break; 933 } 934 case 32: { 935 static_assert(sizeof(float) == sizeof(uint32_t)); 936 value.GetScalar() = (float)f0_data.GetFloat(&offset); 937 break; 938 } 939 } 940 } else { 941 // not handled yet 942 return return_valobj_sp; 943 } 944 } 945 } else { 946 // not handled yet 947 return return_valobj_sp; 948 } 949 950 // If we get here, we have a valid Value, so make our ValueObject out of it: 951 952 return_valobj_sp = ValueObjectConstResult::Create( 953 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 954 return return_valobj_sp; 955 } 956 957 bool ABISysV_mips::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { 958 unwind_plan.Clear(); 959 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 960 961 UnwindPlan::RowSP row(new UnwindPlan::Row); 962 963 // Our Call Frame Address is the stack pointer value 964 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0); 965 966 // The previous PC is in the RA 967 row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true); 968 unwind_plan.AppendRow(row); 969 970 // All other registers are the same. 971 972 unwind_plan.SetSourceName("mips at-func-entry default"); 973 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 974 unwind_plan.SetReturnAddressRegister(dwarf_r31); 975 return true; 976 } 977 978 bool ABISysV_mips::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { 979 unwind_plan.Clear(); 980 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 981 982 UnwindPlan::RowSP row(new UnwindPlan::Row); 983 984 row->SetUnspecifiedRegistersAreUndefined(true); 985 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0); 986 987 row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true); 988 989 unwind_plan.AppendRow(row); 990 unwind_plan.SetSourceName("mips default unwind plan"); 991 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 992 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); 993 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 994 return true; 995 } 996 997 bool ABISysV_mips::RegisterIsVolatile(const RegisterInfo *reg_info) { 998 return !RegisterIsCalleeSaved(reg_info); 999 } 1000 1001 bool ABISysV_mips::IsSoftFloat(uint32_t fp_flags) const { 1002 return (fp_flags == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT); 1003 } 1004 1005 bool ABISysV_mips::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { 1006 if (reg_info) { 1007 // Preserved registers are : 1008 // r16-r23, r28, r29, r30, r31 1009 const char *name = reg_info->name; 1010 1011 if (name[0] == 'r') { 1012 switch (name[1]) { 1013 case '1': 1014 if (name[2] == '6' || name[2] == '7' || name[2] == '8' || 1015 name[2] == '9') // r16-r19 1016 return name[3] == '\0'; 1017 break; 1018 case '2': 1019 if (name[2] == '0' || name[2] == '1' || name[2] == '2' || 1020 name[2] == '3' // r20-r23 1021 || name[2] == '8' || name[2] == '9') // r28 and r29 1022 return name[3] == '\0'; 1023 break; 1024 case '3': 1025 if (name[2] == '0' || name[2] == '1') // r30 and r31 1026 return name[3] == '\0'; 1027 break; 1028 } 1029 1030 if (name[0] == 'g' && name[1] == 'p' && name[2] == '\0') // gp (r28) 1031 return true; 1032 if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp (r29) 1033 return true; 1034 if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp (r30) 1035 return true; 1036 if (name[0] == 'r' && name[1] == 'a' && name[2] == '\0') // ra (r31) 1037 return true; 1038 } 1039 } 1040 return false; 1041 } 1042 1043 void ABISysV_mips::Initialize() { 1044 PluginManager::RegisterPlugin( 1045 GetPluginNameStatic(), "System V ABI for mips targets", CreateInstance); 1046 } 1047 1048 void ABISysV_mips::Terminate() { 1049 PluginManager::UnregisterPlugin(CreateInstance); 1050 } 1051