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