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