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