1 //===-- ABIMacOSX_arm64.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 "ABIMacOSX_arm64.h" 10 11 #include <vector> 12 13 #include "llvm/ADT/STLExtras.h" 14 #include "llvm/ADT/Triple.h" 15 16 #include "lldb/Core/Module.h" 17 #include "lldb/Core/PluginManager.h" 18 #include "lldb/Core/Value.h" 19 #include "lldb/Core/ValueObjectConstResult.h" 20 #include "lldb/Symbol/UnwindPlan.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/RegisterContext.h" 23 #include "lldb/Target/Target.h" 24 #include "lldb/Target/Thread.h" 25 #include "lldb/Utility/ConstString.h" 26 #include "lldb/Utility/LLDBLog.h" 27 #include "lldb/Utility/Log.h" 28 #include "lldb/Utility/RegisterValue.h" 29 #include "lldb/Utility/Scalar.h" 30 #include "lldb/Utility/Status.h" 31 32 #include "Utility/ARM64_DWARF_Registers.h" 33 34 using namespace lldb; 35 using namespace lldb_private; 36 37 static const char *pluginDesc = "Mac OS X ABI for arm64 targets"; 38 39 size_t ABIMacOSX_arm64::GetRedZoneSize() const { return 128; } 40 41 // Static Functions 42 43 ABISP 44 ABIMacOSX_arm64::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) { 45 const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); 46 const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor(); 47 48 if (vendor_type == llvm::Triple::Apple) { 49 if (arch_type == llvm::Triple::aarch64 || 50 arch_type == llvm::Triple::aarch64_32) { 51 return ABISP( 52 new ABIMacOSX_arm64(std::move(process_sp), MakeMCRegisterInfo(arch))); 53 } 54 } 55 56 return ABISP(); 57 } 58 59 bool ABIMacOSX_arm64::PrepareTrivialCall( 60 Thread &thread, lldb::addr_t sp, lldb::addr_t func_addr, 61 lldb::addr_t return_addr, llvm::ArrayRef<lldb::addr_t> args) const { 62 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 63 if (!reg_ctx) 64 return false; 65 66 Log *log = GetLog(LLDBLog::Expressions); 67 68 if (log) { 69 StreamString s; 70 s.Printf("ABIMacOSX_arm64::PrepareTrivialCall (tid = 0x%" PRIx64 71 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 72 ", return_addr = 0x%" PRIx64, 73 thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, 74 (uint64_t)return_addr); 75 76 for (size_t i = 0; i < args.size(); ++i) 77 s.Printf(", arg%d = 0x%" PRIx64, static_cast<int>(i + 1), args[i]); 78 s.PutCString(")"); 79 log->PutString(s.GetString()); 80 } 81 82 const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( 83 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 84 const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( 85 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 86 const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( 87 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); 88 89 // x0 - x7 contain first 8 simple args 90 if (args.size() > 8) // TODO handle more than 8 arguments 91 return false; 92 93 for (size_t i = 0; i < args.size(); ++i) { 94 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( 95 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); 96 LLDB_LOGF(log, "About to write arg%d (0x%" PRIx64 ") into %s", 97 static_cast<int>(i + 1), args[i], reg_info->name); 98 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) 99 return false; 100 } 101 102 // Set "lr" to the return address 103 if (!reg_ctx->WriteRegisterFromUnsigned( 104 reg_ctx->GetRegisterInfoAtIndex(ra_reg_num), return_addr)) 105 return false; 106 107 // Set "sp" to the requested value 108 if (!reg_ctx->WriteRegisterFromUnsigned( 109 reg_ctx->GetRegisterInfoAtIndex(sp_reg_num), sp)) 110 return false; 111 112 // Set "pc" to the address requested 113 if (!reg_ctx->WriteRegisterFromUnsigned( 114 reg_ctx->GetRegisterInfoAtIndex(pc_reg_num), func_addr)) 115 return false; 116 117 return true; 118 } 119 120 bool ABIMacOSX_arm64::GetArgumentValues(Thread &thread, 121 ValueList &values) const { 122 uint32_t num_values = values.GetSize(); 123 124 ExecutionContext exe_ctx(thread.shared_from_this()); 125 126 // Extract the register context so we can read arguments from registers 127 128 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 129 130 if (!reg_ctx) 131 return false; 132 133 addr_t sp = 0; 134 135 for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) { 136 // We currently only support extracting values with Clang QualTypes. Do we 137 // care about others? 138 Value *value = values.GetValueAtIndex(value_idx); 139 140 if (!value) 141 return false; 142 143 CompilerType value_type = value->GetCompilerType(); 144 llvm::Optional<uint64_t> bit_size = value_type.GetBitSize(&thread); 145 if (!bit_size) 146 return false; 147 148 bool is_signed = false; 149 size_t bit_width = 0; 150 if (value_type.IsIntegerOrEnumerationType(is_signed)) { 151 bit_width = *bit_size; 152 } else if (value_type.IsPointerOrReferenceType()) { 153 bit_width = *bit_size; 154 } else { 155 // We only handle integer, pointer and reference types currently... 156 return false; 157 } 158 159 if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) { 160 if (value_idx < 8) { 161 // Arguments 1-6 are in x0-x5... 162 const RegisterInfo *reg_info = nullptr; 163 // Search by generic ID first, then fall back to by name 164 uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( 165 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx); 166 if (arg_reg_num != LLDB_INVALID_REGNUM) { 167 reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num); 168 } else { 169 switch (value_idx) { 170 case 0: 171 reg_info = reg_ctx->GetRegisterInfoByName("x0"); 172 break; 173 case 1: 174 reg_info = reg_ctx->GetRegisterInfoByName("x1"); 175 break; 176 case 2: 177 reg_info = reg_ctx->GetRegisterInfoByName("x2"); 178 break; 179 case 3: 180 reg_info = reg_ctx->GetRegisterInfoByName("x3"); 181 break; 182 case 4: 183 reg_info = reg_ctx->GetRegisterInfoByName("x4"); 184 break; 185 case 5: 186 reg_info = reg_ctx->GetRegisterInfoByName("x5"); 187 break; 188 case 6: 189 reg_info = reg_ctx->GetRegisterInfoByName("x6"); 190 break; 191 case 7: 192 reg_info = reg_ctx->GetRegisterInfoByName("x7"); 193 break; 194 } 195 } 196 197 if (reg_info) { 198 RegisterValue reg_value; 199 200 if (reg_ctx->ReadRegister(reg_info, reg_value)) { 201 if (is_signed) 202 reg_value.SignExtend(bit_width); 203 if (!reg_value.GetScalarValue(value->GetScalar())) 204 return false; 205 continue; 206 } 207 } 208 return false; 209 } else { 210 if (sp == 0) { 211 // Read the stack pointer if we already haven't read it 212 sp = reg_ctx->GetSP(0); 213 if (sp == 0) 214 return false; 215 } 216 217 // Arguments 5 on up are on the stack 218 const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8; 219 Status error; 220 if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory( 221 sp, arg_byte_size, is_signed, value->GetScalar(), error)) 222 return false; 223 224 sp += arg_byte_size; 225 // Align up to the next 8 byte boundary if needed 226 if (sp % 8) { 227 sp >>= 3; 228 sp += 1; 229 sp <<= 3; 230 } 231 } 232 } 233 } 234 return true; 235 } 236 237 Status 238 ABIMacOSX_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, 239 lldb::ValueObjectSP &new_value_sp) { 240 Status error; 241 if (!new_value_sp) { 242 error.SetErrorString("Empty value object for return value."); 243 return error; 244 } 245 246 CompilerType return_value_type = new_value_sp->GetCompilerType(); 247 if (!return_value_type) { 248 error.SetErrorString("Null clang type for return value."); 249 return error; 250 } 251 252 Thread *thread = frame_sp->GetThread().get(); 253 254 RegisterContext *reg_ctx = thread->GetRegisterContext().get(); 255 256 if (reg_ctx) { 257 DataExtractor data; 258 Status data_error; 259 const uint64_t byte_size = new_value_sp->GetData(data, data_error); 260 if (data_error.Fail()) { 261 error.SetErrorStringWithFormat( 262 "Couldn't convert return value to raw data: %s", 263 data_error.AsCString()); 264 return error; 265 } 266 267 const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr); 268 if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { 269 if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { 270 // Extract the register context so we can read arguments from registers 271 lldb::offset_t offset = 0; 272 if (byte_size <= 16) { 273 const RegisterInfo *x0_info = reg_ctx->GetRegisterInfoByName("x0", 0); 274 if (byte_size <= 8) { 275 uint64_t raw_value = data.GetMaxU64(&offset, byte_size); 276 277 if (!reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value)) 278 error.SetErrorString("failed to write register x0"); 279 } else { 280 uint64_t raw_value = data.GetMaxU64(&offset, 8); 281 282 if (reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value)) { 283 const RegisterInfo *x1_info = 284 reg_ctx->GetRegisterInfoByName("x1", 0); 285 raw_value = data.GetMaxU64(&offset, byte_size - offset); 286 287 if (!reg_ctx->WriteRegisterFromUnsigned(x1_info, raw_value)) 288 error.SetErrorString("failed to write register x1"); 289 } 290 } 291 } else { 292 error.SetErrorString("We don't support returning longer than 128 bit " 293 "integer values at present."); 294 } 295 } else if (type_flags & eTypeIsFloat) { 296 if (type_flags & eTypeIsComplex) { 297 // Don't handle complex yet. 298 error.SetErrorString( 299 "returning complex float values are not supported"); 300 } else { 301 const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0); 302 303 if (v0_info) { 304 if (byte_size <= 16) { 305 if (byte_size <= RegisterValue::GetMaxByteSize()) { 306 RegisterValue reg_value; 307 error = reg_value.SetValueFromData(v0_info, data, 0, true); 308 if (error.Success()) { 309 if (!reg_ctx->WriteRegister(v0_info, reg_value)) 310 error.SetErrorString("failed to write register v0"); 311 } 312 } else { 313 error.SetErrorStringWithFormat( 314 "returning float values with a byte size of %" PRIu64 315 " are not supported", 316 byte_size); 317 } 318 } else { 319 error.SetErrorString("returning float values longer than 128 " 320 "bits are not supported"); 321 } 322 } else { 323 error.SetErrorString("v0 register is not available on this target"); 324 } 325 } 326 } 327 } else if (type_flags & eTypeIsVector) { 328 if (byte_size > 0) { 329 const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0); 330 331 if (v0_info) { 332 if (byte_size <= v0_info->byte_size) { 333 RegisterValue reg_value; 334 error = reg_value.SetValueFromData(v0_info, data, 0, true); 335 if (error.Success()) { 336 if (!reg_ctx->WriteRegister(v0_info, reg_value)) 337 error.SetErrorString("failed to write register v0"); 338 } 339 } 340 } 341 } 342 } 343 } else { 344 error.SetErrorString("no registers are available"); 345 } 346 347 return error; 348 } 349 350 bool ABIMacOSX_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { 351 unwind_plan.Clear(); 352 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 353 354 uint32_t lr_reg_num = arm64_dwarf::lr; 355 uint32_t sp_reg_num = arm64_dwarf::sp; 356 uint32_t pc_reg_num = arm64_dwarf::pc; 357 358 UnwindPlan::RowSP row(new UnwindPlan::Row); 359 360 // Our previous Call Frame Address is the stack pointer 361 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0); 362 363 // Our previous PC is in the LR 364 row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true); 365 366 unwind_plan.AppendRow(row); 367 368 // All other registers are the same. 369 370 unwind_plan.SetSourceName("arm64 at-func-entry default"); 371 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 372 373 return true; 374 } 375 376 bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { 377 unwind_plan.Clear(); 378 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 379 380 uint32_t fp_reg_num = arm64_dwarf::fp; 381 uint32_t pc_reg_num = arm64_dwarf::pc; 382 383 UnwindPlan::RowSP row(new UnwindPlan::Row); 384 const int32_t ptr_size = 8; 385 386 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); 387 row->SetOffset(0); 388 row->SetUnspecifiedRegistersAreUndefined(true); 389 390 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); 391 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); 392 393 unwind_plan.AppendRow(row); 394 unwind_plan.SetSourceName("arm64-apple-darwin default unwind plan"); 395 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 396 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); 397 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 398 return true; 399 } 400 401 // AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says 402 // registers x19 through x28 and sp are callee preserved. v8-v15 are non- 403 // volatile (and specifically only the lower 8 bytes of these regs), the rest 404 // of the fp/SIMD registers are volatile. 405 // 406 // v. https://github.com/ARM-software/abi-aa/blob/main/aapcs64/ 407 408 // We treat x29 as callee preserved also, else the unwinder won't try to 409 // retrieve fp saves. 410 411 bool ABIMacOSX_arm64::RegisterIsVolatile(const RegisterInfo *reg_info) { 412 if (reg_info) { 413 const char *name = reg_info->name; 414 415 // Sometimes we'll be called with the "alternate" name for these registers; 416 // recognize them as non-volatile. 417 418 if (name[0] == 'p' && name[1] == 'c') // pc 419 return false; 420 if (name[0] == 'f' && name[1] == 'p') // fp 421 return false; 422 if (name[0] == 's' && name[1] == 'p') // sp 423 return false; 424 if (name[0] == 'l' && name[1] == 'r') // lr 425 return false; 426 427 if (name[0] == 'x') { 428 // Volatile registers: x0-x18, x30 (lr) 429 // Return false for the non-volatile gpr regs, true for everything else 430 switch (name[1]) { 431 case '1': 432 switch (name[2]) { 433 case '9': 434 return false; // x19 is non-volatile 435 default: 436 return true; 437 } 438 break; 439 case '2': 440 switch (name[2]) { 441 case '0': 442 case '1': 443 case '2': 444 case '3': 445 case '4': 446 case '5': 447 case '6': 448 case '7': 449 case '8': 450 return false; // x20 - 28 are non-volatile 451 case '9': 452 return false; // x29 aka fp treat as non-volatile on Darwin 453 default: 454 return true; 455 } 456 case '3': // x30 aka lr treat as non-volatile 457 if (name[2] == '0') 458 return false; 459 break; 460 default: 461 return true; 462 } 463 } else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd') { 464 // Volatile registers: v0-7, v16-v31 465 // Return false for non-volatile fp/SIMD regs, true for everything else 466 switch (name[1]) { 467 case '8': 468 case '9': 469 return false; // v8-v9 are non-volatile 470 case '1': 471 switch (name[2]) { 472 case '0': 473 case '1': 474 case '2': 475 case '3': 476 case '4': 477 case '5': 478 return false; // v10-v15 are non-volatile 479 default: 480 return true; 481 } 482 default: 483 return true; 484 } 485 } 486 } 487 return true; 488 } 489 490 static bool LoadValueFromConsecutiveGPRRegisters( 491 ExecutionContext &exe_ctx, RegisterContext *reg_ctx, 492 const CompilerType &value_type, 493 bool is_return_value, // false => parameter, true => return value 494 uint32_t &NGRN, // NGRN (see ABI documentation) 495 uint32_t &NSRN, // NSRN (see ABI documentation) 496 DataExtractor &data) { 497 llvm::Optional<uint64_t> byte_size = 498 value_type.GetByteSize(exe_ctx.GetBestExecutionContextScope()); 499 if (!byte_size || *byte_size == 0) 500 return false; 501 502 std::unique_ptr<DataBufferHeap> heap_data_up( 503 new DataBufferHeap(*byte_size, 0)); 504 const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder(); 505 Status error; 506 507 CompilerType base_type; 508 const uint32_t homogeneous_count = 509 value_type.IsHomogeneousAggregate(&base_type); 510 if (homogeneous_count > 0 && homogeneous_count <= 8) { 511 // Make sure we have enough registers 512 if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) { 513 if (!base_type) 514 return false; 515 llvm::Optional<uint64_t> base_byte_size = 516 base_type.GetByteSize(exe_ctx.GetBestExecutionContextScope()); 517 if (!base_byte_size) 518 return false; 519 uint32_t data_offset = 0; 520 521 for (uint32_t i = 0; i < homogeneous_count; ++i) { 522 char v_name[8]; 523 ::snprintf(v_name, sizeof(v_name), "v%u", NSRN); 524 const RegisterInfo *reg_info = 525 reg_ctx->GetRegisterInfoByName(v_name, 0); 526 if (reg_info == nullptr) 527 return false; 528 529 if (*base_byte_size > reg_info->byte_size) 530 return false; 531 532 RegisterValue reg_value; 533 534 if (!reg_ctx->ReadRegister(reg_info, reg_value)) 535 return false; 536 537 // Make sure we have enough room in "heap_data_up" 538 if ((data_offset + *base_byte_size) <= heap_data_up->GetByteSize()) { 539 const size_t bytes_copied = reg_value.GetAsMemoryData( 540 reg_info, heap_data_up->GetBytes() + data_offset, *base_byte_size, 541 byte_order, error); 542 if (bytes_copied != *base_byte_size) 543 return false; 544 data_offset += bytes_copied; 545 ++NSRN; 546 } else 547 return false; 548 } 549 data.SetByteOrder(byte_order); 550 data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize()); 551 data.SetData(DataBufferSP(heap_data_up.release())); 552 return true; 553 } 554 } 555 556 const size_t max_reg_byte_size = 16; 557 if (*byte_size <= max_reg_byte_size) { 558 size_t bytes_left = *byte_size; 559 uint32_t data_offset = 0; 560 while (data_offset < *byte_size) { 561 if (NGRN >= 8) 562 return false; 563 564 uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( 565 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN); 566 if (reg_num == LLDB_INVALID_REGNUM) 567 return false; 568 569 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num); 570 if (reg_info == nullptr) 571 return false; 572 573 RegisterValue reg_value; 574 575 if (!reg_ctx->ReadRegister(reg_info, reg_value)) 576 return false; 577 578 const size_t curr_byte_size = std::min<size_t>(8, bytes_left); 579 const size_t bytes_copied = reg_value.GetAsMemoryData( 580 reg_info, heap_data_up->GetBytes() + data_offset, curr_byte_size, 581 byte_order, error); 582 if (bytes_copied == 0) 583 return false; 584 if (bytes_copied >= bytes_left) 585 break; 586 data_offset += bytes_copied; 587 bytes_left -= bytes_copied; 588 ++NGRN; 589 } 590 } else { 591 const RegisterInfo *reg_info = nullptr; 592 if (is_return_value) { 593 // The Darwin arm64 ABI doesn't write the return location back to x8 594 // before returning from the function the way the x86_64 ABI does. So 595 // we can't reconstruct stack based returns on exit from the function: 596 return false; 597 } else { 598 // We are assuming we are stopped at the first instruction in a function 599 // and that the ABI is being respected so all parameters appear where 600 // they should be (functions with no external linkage can legally violate 601 // the ABI). 602 if (NGRN >= 8) 603 return false; 604 605 uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( 606 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN); 607 if (reg_num == LLDB_INVALID_REGNUM) 608 return false; 609 reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num); 610 if (reg_info == nullptr) 611 return false; 612 ++NGRN; 613 } 614 615 if (reg_info == nullptr) 616 return false; 617 618 const lldb::addr_t value_addr = 619 reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS); 620 621 if (value_addr == LLDB_INVALID_ADDRESS) 622 return false; 623 624 if (exe_ctx.GetProcessRef().ReadMemory( 625 value_addr, heap_data_up->GetBytes(), heap_data_up->GetByteSize(), 626 error) != heap_data_up->GetByteSize()) { 627 return false; 628 } 629 } 630 631 data.SetByteOrder(byte_order); 632 data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize()); 633 data.SetData(DataBufferSP(heap_data_up.release())); 634 return true; 635 } 636 637 ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl( 638 Thread &thread, CompilerType &return_compiler_type) const { 639 ValueObjectSP return_valobj_sp; 640 Value value; 641 642 ExecutionContext exe_ctx(thread.shared_from_this()); 643 if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr) 644 return return_valobj_sp; 645 646 // value.SetContext (Value::eContextTypeClangType, return_compiler_type); 647 value.SetCompilerType(return_compiler_type); 648 649 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 650 if (!reg_ctx) 651 return return_valobj_sp; 652 653 llvm::Optional<uint64_t> byte_size = 654 return_compiler_type.GetByteSize(&thread); 655 if (!byte_size) 656 return return_valobj_sp; 657 658 const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr); 659 if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { 660 value.SetValueType(Value::ValueType::Scalar); 661 662 bool success = false; 663 if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { 664 // Extract the register context so we can read arguments from registers 665 if (*byte_size <= 8) { 666 const RegisterInfo *x0_reg_info = 667 reg_ctx->GetRegisterInfoByName("x0", 0); 668 if (x0_reg_info) { 669 uint64_t raw_value = 670 thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info, 671 0); 672 const bool is_signed = (type_flags & eTypeIsSigned) != 0; 673 switch (*byte_size) { 674 default: 675 break; 676 case 16: // uint128_t 677 // In register x0 and x1 678 { 679 const RegisterInfo *x1_reg_info = 680 reg_ctx->GetRegisterInfoByName("x1", 0); 681 682 if (x1_reg_info) { 683 if (*byte_size <= 684 x0_reg_info->byte_size + x1_reg_info->byte_size) { 685 std::unique_ptr<DataBufferHeap> heap_data_up( 686 new DataBufferHeap(*byte_size, 0)); 687 const ByteOrder byte_order = 688 exe_ctx.GetProcessRef().GetByteOrder(); 689 RegisterValue x0_reg_value; 690 RegisterValue x1_reg_value; 691 if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) && 692 reg_ctx->ReadRegister(x1_reg_info, x1_reg_value)) { 693 Status error; 694 if (x0_reg_value.GetAsMemoryData( 695 x0_reg_info, heap_data_up->GetBytes() + 0, 8, 696 byte_order, error) && 697 x1_reg_value.GetAsMemoryData( 698 x1_reg_info, heap_data_up->GetBytes() + 8, 8, 699 byte_order, error)) { 700 DataExtractor data( 701 DataBufferSP(heap_data_up.release()), byte_order, 702 exe_ctx.GetProcessRef().GetAddressByteSize()); 703 704 return_valobj_sp = ValueObjectConstResult::Create( 705 &thread, return_compiler_type, ConstString(""), data); 706 return return_valobj_sp; 707 } 708 } 709 } 710 } 711 } 712 break; 713 case sizeof(uint64_t): 714 if (is_signed) 715 value.GetScalar() = (int64_t)(raw_value); 716 else 717 value.GetScalar() = (uint64_t)(raw_value); 718 success = true; 719 break; 720 721 case sizeof(uint32_t): 722 if (is_signed) 723 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); 724 else 725 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); 726 success = true; 727 break; 728 729 case sizeof(uint16_t): 730 if (is_signed) 731 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); 732 else 733 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); 734 success = true; 735 break; 736 737 case sizeof(uint8_t): 738 if (is_signed) 739 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); 740 else 741 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); 742 success = true; 743 break; 744 } 745 } 746 } 747 } else if (type_flags & eTypeIsFloat) { 748 if (type_flags & eTypeIsComplex) { 749 // Don't handle complex yet. 750 } else { 751 if (*byte_size <= sizeof(long double)) { 752 const RegisterInfo *v0_reg_info = 753 reg_ctx->GetRegisterInfoByName("v0", 0); 754 RegisterValue v0_value; 755 if (reg_ctx->ReadRegister(v0_reg_info, v0_value)) { 756 DataExtractor data; 757 if (v0_value.GetData(data)) { 758 lldb::offset_t offset = 0; 759 if (*byte_size == sizeof(float)) { 760 value.GetScalar() = data.GetFloat(&offset); 761 success = true; 762 } else if (*byte_size == sizeof(double)) { 763 value.GetScalar() = data.GetDouble(&offset); 764 success = true; 765 } else if (*byte_size == sizeof(long double)) { 766 value.GetScalar() = data.GetLongDouble(&offset); 767 success = true; 768 } 769 } 770 } 771 } 772 } 773 } 774 775 if (success) 776 return_valobj_sp = ValueObjectConstResult::Create( 777 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 778 } else if (type_flags & eTypeIsVector) { 779 if (*byte_size > 0) { 780 781 const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0); 782 783 if (v0_info) { 784 if (*byte_size <= v0_info->byte_size) { 785 std::unique_ptr<DataBufferHeap> heap_data_up( 786 new DataBufferHeap(*byte_size, 0)); 787 const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder(); 788 RegisterValue reg_value; 789 if (reg_ctx->ReadRegister(v0_info, reg_value)) { 790 Status error; 791 if (reg_value.GetAsMemoryData(v0_info, heap_data_up->GetBytes(), 792 heap_data_up->GetByteSize(), 793 byte_order, error)) { 794 DataExtractor data(DataBufferSP(heap_data_up.release()), 795 byte_order, 796 exe_ctx.GetProcessRef().GetAddressByteSize()); 797 return_valobj_sp = ValueObjectConstResult::Create( 798 &thread, return_compiler_type, ConstString(""), data); 799 } 800 } 801 } 802 } 803 } 804 } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) { 805 DataExtractor data; 806 807 uint32_t NGRN = 0; // Search ABI docs for NGRN 808 uint32_t NSRN = 0; // Search ABI docs for NSRN 809 const bool is_return_value = true; 810 if (LoadValueFromConsecutiveGPRRegisters( 811 exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN, 812 data)) { 813 return_valobj_sp = ValueObjectConstResult::Create( 814 &thread, return_compiler_type, ConstString(""), data); 815 } 816 } 817 return return_valobj_sp; 818 } 819 820 lldb::addr_t ABIMacOSX_arm64::FixAddress(addr_t pc, addr_t mask) { 821 lldb::addr_t pac_sign_extension = 0x0080000000000000ULL; 822 // Darwin systems originally couldn't determine the proper value 823 // dynamically, so the most common value was hardcoded. This has 824 // largely been cleaned up, but there are still a handful of 825 // environments that assume the default value is set to this value 826 // and there's no dynamic value to correct it. 827 // When no mask is specified, set it to 39 bits of addressing (0..38). 828 if (mask == 0) { 829 // ~((1ULL<<39)-1) 830 mask = 0xffffff8000000000; 831 } 832 return (pc & pac_sign_extension) ? pc | mask : pc & (~mask); 833 } 834 835 void ABIMacOSX_arm64::Initialize() { 836 PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc, 837 CreateInstance); 838 } 839 840 void ABIMacOSX_arm64::Terminate() { 841 PluginManager::UnregisterPlugin(CreateInstance); 842 } 843