960 lines · cpp
1//===-- ABISysV_x86_64.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "ABISysV_x86_64.h"10 11#include "llvm/ADT/STLExtras.h"12#include "llvm/ADT/StringSwitch.h"13#include "llvm/TargetParser/Triple.h"14 15#include "lldb/Core/Module.h"16#include "lldb/Core/PluginManager.h"17#include "lldb/Core/Value.h"18#include "lldb/Symbol/UnwindPlan.h"19#include "lldb/Target/Process.h"20#include "lldb/Target/RegisterContext.h"21#include "lldb/Target/StackFrame.h"22#include "lldb/Target/Target.h"23#include "lldb/Target/Thread.h"24#include "lldb/Utility/ConstString.h"25#include "lldb/Utility/DataExtractor.h"26#include "lldb/Utility/LLDBLog.h"27#include "lldb/Utility/Log.h"28#include "lldb/Utility/RegisterValue.h"29#include "lldb/Utility/Status.h"30#include "lldb/ValueObject/ValueObjectConstResult.h"31#include "lldb/ValueObject/ValueObjectMemory.h"32#include "lldb/ValueObject/ValueObjectRegister.h"33 34#include <optional>35#include <vector>36 37using namespace lldb;38using namespace lldb_private;39 40LLDB_PLUGIN_DEFINE(ABISysV_x86_64)41 42enum dwarf_regnums {43 dwarf_rax = 0,44 dwarf_rdx,45 dwarf_rcx,46 dwarf_rbx,47 dwarf_rsi,48 dwarf_rdi,49 dwarf_rbp,50 dwarf_rsp,51 dwarf_r8,52 dwarf_r9,53 dwarf_r10,54 dwarf_r11,55 dwarf_r12,56 dwarf_r13,57 dwarf_r14,58 dwarf_r15,59 dwarf_rip,60};61 62bool ABISysV_x86_64::GetPointerReturnRegister(const char *&name) {63 name = "rax";64 return true;65}66 67size_t ABISysV_x86_64::GetRedZoneSize() const { return 128; }68 69// Static Functions70 71ABISP72ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {73 const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();74 const llvm::Triple::OSType os_type = arch.GetTriple().getOS();75 const llvm::Triple::EnvironmentType os_env =76 arch.GetTriple().getEnvironment();77 if (arch_type == llvm::Triple::x86_64) {78 switch(os_type) {79 case llvm::Triple::OSType::IOS:80 case llvm::Triple::OSType::TvOS:81 case llvm::Triple::OSType::WatchOS:82 case llvm::Triple::OSType::XROS:83 switch (os_env) {84 case llvm::Triple::EnvironmentType::MacABI:85 case llvm::Triple::EnvironmentType::Simulator:86 case llvm::Triple::EnvironmentType::UnknownEnvironment:87 // UnknownEnvironment is needed for older compilers that don't88 // support the simulator environment.89 return ABISP(new ABISysV_x86_64(std::move(process_sp),90 MakeMCRegisterInfo(arch)));91 default:92 return ABISP();93 }94 case llvm::Triple::OSType::Darwin:95 case llvm::Triple::OSType::FreeBSD:96 case llvm::Triple::OSType::Linux:97 case llvm::Triple::OSType::MacOSX:98 case llvm::Triple::OSType::NetBSD:99 case llvm::Triple::OSType::OpenBSD:100 case llvm::Triple::OSType::Solaris:101 case llvm::Triple::OSType::UnknownOS:102 return ABISP(103 new ABISysV_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch)));104 default:105 return ABISP();106 }107 }108 return ABISP();109}110 111bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,112 addr_t func_addr, addr_t return_addr,113 llvm::ArrayRef<addr_t> args) const {114 Log *log = GetLog(LLDBLog::Expressions);115 116 if (log) {117 StreamString s;118 s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64119 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64120 ", return_addr = 0x%" PRIx64,121 thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,122 (uint64_t)return_addr);123 124 for (size_t i = 0; i < args.size(); ++i)125 s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),126 args[i]);127 s.PutCString(")");128 log->PutString(s.GetString());129 }130 131 RegisterContext *reg_ctx = thread.GetRegisterContext().get();132 if (!reg_ctx)133 return false;134 135 const RegisterInfo *reg_info = nullptr;136 137 if (args.size() > 6) // TODO handle more than 6 arguments138 return false;139 140 for (size_t i = 0; i < args.size(); ++i) {141 reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,142 LLDB_REGNUM_GENERIC_ARG1 + i);143 LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",144 static_cast<uint64_t>(i + 1), args[i], reg_info->name);145 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))146 return false;147 }148 149 // First, align the SP150 151 LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,152 (uint64_t)sp, (uint64_t)(sp & ~0xfull));153 154 sp &= ~(0xfull); // 16-byte alignment155 156 sp -= 8;157 158 Status error;159 const RegisterInfo *pc_reg_info =160 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);161 const RegisterInfo *sp_reg_info =162 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);163 ProcessSP process_sp(thread.GetProcess());164 165 RegisterValue reg_value;166 LLDB_LOGF(log,167 "Pushing the return address onto the stack: 0x%" PRIx64168 ": 0x%" PRIx64,169 (uint64_t)sp, (uint64_t)return_addr);170 171 // Save return address onto the stack172 if (!process_sp->WritePointerToMemory(sp, return_addr, error))173 return false;174 175 // %rsp is set to the actual stack value.176 177 LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);178 179 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))180 return false;181 182 // %rip is set to the address of the called function.183 184 LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);185 186 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))187 return false;188 189 return true;190}191 192static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,193 bool is_signed, Thread &thread,194 uint32_t *argument_register_ids,195 unsigned int ¤t_argument_register,196 addr_t ¤t_stack_argument) {197 if (bit_width > 64)198 return false; // Scalar can't hold large integer arguments199 200 if (current_argument_register < 6) {201 scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(202 argument_register_ids[current_argument_register], 0);203 current_argument_register++;204 if (is_signed)205 scalar.SignExtend(bit_width);206 } else {207 uint32_t byte_size = (bit_width + (8 - 1)) / 8;208 Status error;209 if (thread.GetProcess()->ReadScalarIntegerFromMemory(210 current_stack_argument, byte_size, is_signed, scalar, error)) {211 current_stack_argument += byte_size;212 return true;213 }214 return false;215 }216 return true;217}218 219bool ABISysV_x86_64::GetArgumentValues(Thread &thread,220 ValueList &values) const {221 unsigned int num_values = values.GetSize();222 unsigned int value_index;223 224 // Extract the register context so we can read arguments from registers225 226 RegisterContext *reg_ctx = thread.GetRegisterContext().get();227 228 if (!reg_ctx)229 return false;230 231 // Get the pointer to the first stack argument so we have a place to start232 // when reading data233 234 addr_t sp = reg_ctx->GetSP(0);235 236 if (!sp)237 return false;238 239 addr_t current_stack_argument = sp + 8; // jump over return address240 241 uint32_t argument_register_ids[6];242 243 argument_register_ids[0] =244 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)245 ->kinds[eRegisterKindLLDB];246 argument_register_ids[1] =247 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)248 ->kinds[eRegisterKindLLDB];249 argument_register_ids[2] =250 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)251 ->kinds[eRegisterKindLLDB];252 argument_register_ids[3] =253 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)254 ->kinds[eRegisterKindLLDB];255 argument_register_ids[4] =256 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)257 ->kinds[eRegisterKindLLDB];258 argument_register_ids[5] =259 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)260 ->kinds[eRegisterKindLLDB];261 262 unsigned int current_argument_register = 0;263 264 for (value_index = 0; value_index < num_values; ++value_index) {265 Value *value = values.GetValueAtIndex(value_index);266 267 if (!value)268 return false;269 270 // We currently only support extracting values with Clang QualTypes. Do we271 // care about others?272 CompilerType compiler_type = value->GetCompilerType();273 std::optional<uint64_t> bit_size =274 llvm::expectedToOptional(compiler_type.GetBitSize(&thread));275 if (!bit_size)276 return false;277 bool is_signed;278 279 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {280 ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,281 argument_register_ids, current_argument_register,282 current_stack_argument);283 } else if (compiler_type.IsPointerType()) {284 ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,285 argument_register_ids, current_argument_register,286 current_stack_argument);287 }288 }289 290 return true;291}292 293Status ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,294 lldb::ValueObjectSP &new_value_sp) {295 Status error;296 if (!new_value_sp) {297 error = Status::FromErrorString("Empty value object for return value.");298 return error;299 }300 301 CompilerType compiler_type = new_value_sp->GetCompilerType();302 if (!compiler_type) {303 error = Status::FromErrorString("Null clang type for return value.");304 return error;305 }306 307 Thread *thread = frame_sp->GetThread().get();308 309 bool is_signed;310 bool is_complex;311 312 RegisterContext *reg_ctx = thread->GetRegisterContext().get();313 314 bool set_it_simple = false;315 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||316 compiler_type.IsPointerType()) {317 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);318 319 DataExtractor data;320 Status data_error;321 size_t num_bytes = new_value_sp->GetData(data, data_error);322 if (data_error.Fail()) {323 error = Status::FromErrorStringWithFormat(324 "Couldn't convert return value to raw data: %s",325 data_error.AsCString());326 return error;327 }328 lldb::offset_t offset = 0;329 if (num_bytes <= 8) {330 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);331 332 if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))333 set_it_simple = true;334 } else {335 error = Status::FromErrorString(336 "We don't support returning longer than 64 bit "337 "integer values at present.");338 }339 } else if (compiler_type.IsFloatingPointType(is_complex)) {340 if (is_complex)341 error = Status::FromErrorString(342 "We don't support returning complex values at present");343 else {344 std::optional<uint64_t> bit_width =345 llvm::expectedToOptional(compiler_type.GetBitSize(frame_sp.get()));346 if (!bit_width) {347 error = Status::FromErrorString("can't get type size");348 return error;349 }350 if (*bit_width <= 64) {351 const RegisterInfo *xmm0_info =352 reg_ctx->GetRegisterInfoByName("xmm0", 0);353 RegisterValue xmm0_value;354 DataExtractor data;355 Status data_error;356 size_t num_bytes = new_value_sp->GetData(data, data_error);357 if (data_error.Fail()) {358 error = Status::FromErrorStringWithFormat(359 "Couldn't convert return value to raw data: %s",360 data_error.AsCString());361 return error;362 }363 364 unsigned char buffer[16];365 ByteOrder byte_order = data.GetByteOrder();366 367 data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);368 xmm0_value.SetBytes(buffer, 16, byte_order);369 reg_ctx->WriteRegister(xmm0_info, xmm0_value);370 set_it_simple = true;371 } else {372 // FIXME - don't know how to do 80 bit long doubles yet.373 error = Status::FromErrorString(374 "We don't support returning float values > 64 bits at present");375 }376 }377 }378 379 if (!set_it_simple) {380 // Okay we've got a structure or something that doesn't fit in a simple381 // register. We should figure out where it really goes, but we don't382 // support this yet.383 error = Status::FromErrorString(384 "We only support setting simple integer and float "385 "return types at present.");386 }387 388 return error;389}390 391ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(392 Thread &thread, CompilerType &return_compiler_type) const {393 ValueObjectSP return_valobj_sp;394 Value value;395 396 if (!return_compiler_type)397 return return_valobj_sp;398 399 // value.SetContext (Value::eContextTypeClangType, return_value_type);400 value.SetCompilerType(return_compiler_type);401 402 RegisterContext *reg_ctx = thread.GetRegisterContext().get();403 if (!reg_ctx)404 return return_valobj_sp;405 406 const uint32_t type_flags = return_compiler_type.GetTypeInfo();407 if (type_flags & eTypeIsScalar) {408 value.SetValueType(Value::ValueType::Scalar);409 410 bool success = false;411 if (type_flags & eTypeIsInteger) {412 // Extract the register context so we can read arguments from registers413 414 std::optional<uint64_t> byte_size =415 llvm::expectedToOptional(return_compiler_type.GetByteSize(&thread));416 if (!byte_size)417 return return_valobj_sp;418 uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(419 reg_ctx->GetRegisterInfoByName("rax", 0), 0);420 const bool is_signed = (type_flags & eTypeIsSigned) != 0;421 switch (*byte_size) {422 default:423 break;424 425 case sizeof(uint64_t):426 if (is_signed)427 value.GetScalar() = (int64_t)(raw_value);428 else429 value.GetScalar() = (uint64_t)(raw_value);430 success = true;431 break;432 433 case sizeof(uint32_t):434 if (is_signed)435 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);436 else437 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);438 success = true;439 break;440 441 case sizeof(uint16_t):442 if (is_signed)443 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);444 else445 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);446 success = true;447 break;448 449 case sizeof(uint8_t):450 if (is_signed)451 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);452 else453 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);454 success = true;455 break;456 }457 } else if (type_flags & eTypeIsFloat) {458 if (type_flags & eTypeIsComplex) {459 // Don't handle complex yet.460 } else {461 std::optional<uint64_t> byte_size =462 llvm::expectedToOptional(return_compiler_type.GetByteSize(&thread));463 if (byte_size && *byte_size <= sizeof(long double)) {464 const RegisterInfo *xmm0_info =465 reg_ctx->GetRegisterInfoByName("xmm0", 0);466 RegisterValue xmm0_value;467 if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) {468 DataExtractor data;469 if (xmm0_value.GetData(data)) {470 lldb::offset_t offset = 0;471 if (*byte_size == sizeof(float)) {472 value.GetScalar() = (float)data.GetFloat(&offset);473 success = true;474 } else if (*byte_size == sizeof(double)) {475 value.GetScalar() = (double)data.GetDouble(&offset);476 success = true;477 } else if (*byte_size == sizeof(long double)) {478 // Don't handle long double since that can be encoded as 80 bit479 // floats...480 }481 }482 }483 }484 }485 }486 487 if (success)488 return_valobj_sp = ValueObjectConstResult::Create(489 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));490 } else if (type_flags & eTypeIsPointer) {491 unsigned rax_id =492 reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];493 value.GetScalar() =494 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,495 0);496 value.SetValueType(Value::ValueType::Scalar);497 return_valobj_sp = ValueObjectConstResult::Create(498 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));499 } else if (type_flags & eTypeIsVector) {500 std::optional<uint64_t> byte_size =501 llvm::expectedToOptional(return_compiler_type.GetByteSize(&thread));502 if (byte_size && *byte_size > 0) {503 const RegisterInfo *altivec_reg =504 reg_ctx->GetRegisterInfoByName("xmm0", 0);505 if (altivec_reg == nullptr)506 altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);507 508 if (altivec_reg) {509 if (*byte_size <= altivec_reg->byte_size) {510 ProcessSP process_sp(thread.GetProcess());511 if (process_sp) {512 std::unique_ptr<DataBufferHeap> heap_data_up(513 new DataBufferHeap(*byte_size, 0));514 const ByteOrder byte_order = process_sp->GetByteOrder();515 RegisterValue reg_value;516 if (reg_ctx->ReadRegister(altivec_reg, reg_value)) {517 Status error;518 if (reg_value.GetAsMemoryData(519 *altivec_reg, heap_data_up->GetBytes(),520 heap_data_up->GetByteSize(), byte_order, error)) {521 DataExtractor data(DataBufferSP(heap_data_up.release()),522 byte_order,523 process_sp->GetTarget()524 .GetArchitecture()525 .GetAddressByteSize());526 return_valobj_sp = ValueObjectConstResult::Create(527 &thread, return_compiler_type, ConstString(""), data);528 }529 }530 }531 } else if (*byte_size <= altivec_reg->byte_size * 2) {532 const RegisterInfo *altivec_reg2 =533 reg_ctx->GetRegisterInfoByName("xmm1", 0);534 if (altivec_reg2) {535 ProcessSP process_sp(thread.GetProcess());536 if (process_sp) {537 std::unique_ptr<DataBufferHeap> heap_data_up(538 new DataBufferHeap(*byte_size, 0));539 const ByteOrder byte_order = process_sp->GetByteOrder();540 RegisterValue reg_value;541 RegisterValue reg_value2;542 if (reg_ctx->ReadRegister(altivec_reg, reg_value) &&543 reg_ctx->ReadRegister(altivec_reg2, reg_value2)) {544 545 Status error;546 if (reg_value.GetAsMemoryData(547 *altivec_reg, heap_data_up->GetBytes(),548 altivec_reg->byte_size, byte_order, error) &&549 reg_value2.GetAsMemoryData(550 *altivec_reg2,551 heap_data_up->GetBytes() + altivec_reg->byte_size,552 heap_data_up->GetByteSize() - altivec_reg->byte_size,553 byte_order, error)) {554 DataExtractor data(DataBufferSP(heap_data_up.release()),555 byte_order,556 process_sp->GetTarget()557 .GetArchitecture()558 .GetAddressByteSize());559 return_valobj_sp = ValueObjectConstResult::Create(560 &thread, return_compiler_type, ConstString(""), data);561 }562 }563 }564 }565 }566 }567 }568 }569 570 return return_valobj_sp;571}572 573// The compiler will flatten the nested aggregate type into single574// layer and push the value to stack575// This helper function will flatten an aggregate type576// and return true if it can be returned in register(s) by value577// return false if the aggregate is in memory578static bool FlattenAggregateType(579 Thread &thread, ExecutionContext &exe_ctx,580 CompilerType &return_compiler_type,581 uint32_t data_byte_offset,582 std::vector<uint32_t> &aggregate_field_offsets,583 std::vector<CompilerType> &aggregate_compiler_types) {584 585 const uint32_t num_children = return_compiler_type.GetNumFields();586 for (uint32_t idx = 0; idx < num_children; ++idx) {587 std::string name;588 bool is_signed;589 bool is_complex;590 591 uint64_t field_bit_offset = 0;592 CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(593 idx, name, &field_bit_offset, nullptr, nullptr);594 std::optional<uint64_t> field_bit_width =595 llvm::expectedToOptional(field_compiler_type.GetBitSize(&thread));596 597 // if we don't know the size of the field (e.g. invalid type), exit598 if (!field_bit_width || *field_bit_width == 0) {599 return false;600 }601 602 uint32_t field_byte_offset = field_bit_offset / 8 + data_byte_offset;603 604 const uint32_t field_type_flags = field_compiler_type.GetTypeInfo();605 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||606 field_compiler_type.IsPointerType() ||607 field_compiler_type.IsFloatingPointType(is_complex)) {608 aggregate_field_offsets.push_back(field_byte_offset);609 aggregate_compiler_types.push_back(field_compiler_type);610 } else if (field_type_flags & eTypeHasChildren) {611 if (!FlattenAggregateType(thread, exe_ctx, field_compiler_type,612 field_byte_offset, aggregate_field_offsets,613 aggregate_compiler_types)) {614 return false;615 }616 }617 }618 return true;619}620 621ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(622 Thread &thread, CompilerType &return_compiler_type) const {623 ValueObjectSP return_valobj_sp;624 625 if (!return_compiler_type)626 return return_valobj_sp;627 628 ExecutionContext exe_ctx(thread.shared_from_this());629 return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);630 if (return_valobj_sp)631 return return_valobj_sp;632 633 RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();634 if (!reg_ctx_sp)635 return return_valobj_sp;636 637 std::optional<uint64_t> bit_width =638 llvm::expectedToOptional(return_compiler_type.GetBitSize(&thread));639 if (!bit_width)640 return return_valobj_sp;641 if (return_compiler_type.IsAggregateType()) {642 Target *target = exe_ctx.GetTargetPtr();643 bool is_memory = true;644 std::vector<uint32_t> aggregate_field_offsets;645 std::vector<CompilerType> aggregate_compiler_types;646 auto ts = return_compiler_type.GetTypeSystem();647 if (ts && ts->CanPassInRegisters(return_compiler_type) &&648 *bit_width <= 128 &&649 FlattenAggregateType(thread, exe_ctx, return_compiler_type, 0,650 aggregate_field_offsets,651 aggregate_compiler_types)) {652 ByteOrder byte_order = target->GetArchitecture().GetByteOrder();653 WritableDataBufferSP data_sp(new DataBufferHeap(16, 0));654 DataExtractor return_ext(data_sp, byte_order,655 target->GetArchitecture().GetAddressByteSize());656 657 const RegisterInfo *rax_info =658 reg_ctx_sp->GetRegisterInfoByName("rax", 0);659 const RegisterInfo *rdx_info =660 reg_ctx_sp->GetRegisterInfoByName("rdx", 0);661 const RegisterInfo *xmm0_info =662 reg_ctx_sp->GetRegisterInfoByName("xmm0", 0);663 const RegisterInfo *xmm1_info =664 reg_ctx_sp->GetRegisterInfoByName("xmm1", 0);665 666 RegisterValue rax_value, rdx_value, xmm0_value, xmm1_value;667 reg_ctx_sp->ReadRegister(rax_info, rax_value);668 reg_ctx_sp->ReadRegister(rdx_info, rdx_value);669 reg_ctx_sp->ReadRegister(xmm0_info, xmm0_value);670 reg_ctx_sp->ReadRegister(xmm1_info, xmm1_value);671 672 DataExtractor rax_data, rdx_data, xmm0_data, xmm1_data;673 674 rax_value.GetData(rax_data);675 rdx_value.GetData(rdx_data);676 xmm0_value.GetData(xmm0_data);677 xmm1_value.GetData(xmm1_data);678 679 uint32_t fp_bytes =680 0; // Tracks how much of the xmm registers we've consumed so far681 uint32_t integer_bytes =682 0; // Tracks how much of the rax/rds registers we've consumed so far683 684 // in case of the returned type is a subclass of non-abstract-base class685 // it will have a padding to skip the base content686 if (aggregate_field_offsets.size()) {687 fp_bytes = aggregate_field_offsets[0];688 integer_bytes = aggregate_field_offsets[0];689 }690 691 const uint32_t num_children = aggregate_compiler_types.size();692 693 // Since we are in the small struct regime, assume we are not in memory.694 is_memory = false;695 for (uint32_t idx = 0; idx < num_children; idx++) {696 bool is_signed;697 bool is_complex;698 699 CompilerType field_compiler_type = aggregate_compiler_types[idx];700 uint32_t field_byte_width =701 (uint32_t)(llvm::expectedToOptional(702 field_compiler_type.GetByteSize(&thread))703 .value_or(0));704 uint32_t field_byte_offset = aggregate_field_offsets[idx];705 706 uint32_t field_bit_width = field_byte_width * 8;707 708 DataExtractor *copy_from_extractor = nullptr;709 uint32_t copy_from_offset = 0;710 711 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||712 field_compiler_type.IsPointerType()) {713 if (integer_bytes < 8) {714 if (integer_bytes + field_byte_width <= 8) {715 // This is in RAX, copy from register to our result structure:716 copy_from_extractor = &rax_data;717 copy_from_offset = integer_bytes;718 integer_bytes += field_byte_width;719 } else {720 // The next field wouldn't fit in the remaining space, so we721 // pushed it to rdx.722 copy_from_extractor = &rdx_data;723 copy_from_offset = 0;724 integer_bytes = 8 + field_byte_width;725 }726 } else if (integer_bytes + field_byte_width <= 16) {727 copy_from_extractor = &rdx_data;728 copy_from_offset = integer_bytes - 8;729 integer_bytes += field_byte_width;730 } else {731 // The last field didn't fit. I can't see how that would happen732 // w/o the overall size being greater than 16 bytes. For now,733 // return a nullptr return value object.734 return return_valobj_sp;735 }736 } else if (field_compiler_type.IsFloatingPointType(is_complex)) {737 // Structs with long doubles are always passed in memory.738 if (field_bit_width == 128) {739 is_memory = true;740 break;741 } else if (field_bit_width == 64) {742 // These have to be in a single xmm register.743 if (fp_bytes == 0)744 copy_from_extractor = &xmm0_data;745 else746 copy_from_extractor = &xmm1_data;747 748 copy_from_offset = 0;749 fp_bytes += field_byte_width;750 } else if (field_bit_width == 32) {751 // This one is kind of complicated. If we are in an "eightbyte"752 // with another float, we'll be stuffed into an xmm register with753 // it. If we are in an "eightbyte" with one or more ints, then we754 // will be stuffed into the appropriate GPR with them.755 bool in_gpr;756 if (field_byte_offset % 8 == 0) {757 // We are at the beginning of one of the eightbytes, so check the758 // next element (if any)759 if (idx == num_children - 1) {760 in_gpr = false;761 } else {762 CompilerType next_field_compiler_type =763 aggregate_compiler_types[idx + 1];764 if (next_field_compiler_type.IsIntegerOrEnumerationType(765 is_signed)) {766 in_gpr = true;767 } else {768 copy_from_offset = 0;769 in_gpr = false;770 }771 }772 } else if (field_byte_offset % 4 == 0) {773 // We are inside of an eightbyte, so see if the field before us774 // is floating point: This could happen if somebody put padding775 // in the structure.776 if (idx == 0) {777 in_gpr = false;778 } else {779 CompilerType prev_field_compiler_type =780 aggregate_compiler_types[idx - 1];781 if (prev_field_compiler_type.IsIntegerOrEnumerationType(782 is_signed)) {783 in_gpr = true;784 } else {785 copy_from_offset = 4;786 in_gpr = false;787 }788 }789 } else {790 is_memory = true;791 continue;792 }793 794 // Okay, we've figured out whether we are in GPR or XMM, now figure795 // out which one.796 if (in_gpr) {797 if (integer_bytes < 8) {798 // This is in RAX, copy from register to our result structure:799 copy_from_extractor = &rax_data;800 copy_from_offset = integer_bytes;801 integer_bytes += field_byte_width;802 } else {803 copy_from_extractor = &rdx_data;804 copy_from_offset = integer_bytes - 8;805 integer_bytes += field_byte_width;806 }807 } else {808 if (fp_bytes < 8)809 copy_from_extractor = &xmm0_data;810 else811 copy_from_extractor = &xmm1_data;812 813 fp_bytes += field_byte_width;814 }815 }816 }817 // These two tests are just sanity checks. If I somehow get the type818 // calculation wrong above it is better to just return nothing than to819 // assert or crash.820 if (!copy_from_extractor)821 return return_valobj_sp;822 if (copy_from_offset + field_byte_width >823 copy_from_extractor->GetByteSize())824 return return_valobj_sp;825 copy_from_extractor->CopyByteOrderedData(826 copy_from_offset, field_byte_width,827 data_sp->GetBytes() + field_byte_offset, field_byte_width,828 byte_order);829 }830 if (!is_memory) {831 // The result is in our data buffer. Let's make a variable object out832 // of it:833 return_valobj_sp = ValueObjectConstResult::Create(834 &thread, return_compiler_type, ConstString(""), return_ext);835 }836 }837 838 // FIXME: This is just taking a guess, rax may very well no longer hold the839 // return storage location.840 // If we are going to do this right, when we make a new frame we should841 // check to see if it uses a memory return, and if we are at the first842 // instruction and if so stash away the return location. Then we would843 // only return the memory return value if we know it is valid.844 845 if (is_memory) {846 unsigned rax_id =847 reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];848 lldb::addr_t storage_addr =849 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,850 0);851 return_valobj_sp = ValueObjectMemory::Create(852 &thread, "", Address(storage_addr, nullptr), return_compiler_type);853 }854 }855 856 return return_valobj_sp;857}858 859// This defines the CFA as rsp+8860// the saved pc is at CFA-8 (i.e. rsp+0)861// The saved rsp is CFA+0862 863UnwindPlanSP ABISysV_x86_64::CreateFunctionEntryUnwindPlan() {864 uint32_t sp_reg_num = dwarf_rsp;865 uint32_t pc_reg_num = dwarf_rip;866 867 UnwindPlan::Row row;868 row.GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);869 row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);870 row.SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);871 872 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);873 plan_sp->AppendRow(std::move(row));874 plan_sp->SetSourceName("x86_64 at-func-entry default");875 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);876 return plan_sp;877}878 879// This defines the CFA as rbp+16880// The saved pc is at CFA-8 (i.e. rbp+8)881// The saved rbp is at CFA-16 (i.e. rbp+0)882// The saved rsp is CFA+0883 884UnwindPlanSP ABISysV_x86_64::CreateDefaultUnwindPlan() {885 uint32_t fp_reg_num = dwarf_rbp;886 uint32_t sp_reg_num = dwarf_rsp;887 uint32_t pc_reg_num = dwarf_rip;888 889 UnwindPlan::Row row;890 891 const int32_t ptr_size = 8;892 row.GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);893 row.SetOffset(0);894 row.SetUnspecifiedRegistersAreUndefined(true);895 896 row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);897 row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);898 row.SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);899 900 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);901 plan_sp->AppendRow(std::move(row));902 plan_sp->SetSourceName("x86_64 default unwind plan");903 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);904 plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);905 plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);906 return plan_sp;907}908 909bool ABISysV_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) {910 return !RegisterIsCalleeSaved(reg_info);911}912 913// See "Register Usage" in the914// "System V Application Binary Interface"915// "AMD64 Architecture Processor Supplement" (or "x86-64(tm) Architecture916// Processor Supplement" in earlier revisions) (this doc is also commonly917// referred to as the x86-64/AMD64 psABI) Edited by Michael Matz, Jan Hubicka,918// Andreas Jaeger, and Mark Mitchell current version is 0.99.6 released919// 2012-07-02 at http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf920// It's being revised & updated at https://github.com/hjl-tools/x86-psABI/921 922bool ABISysV_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {923 if (!reg_info)924 return false;925 assert(reg_info->name != nullptr && "unnamed register?");926 std::string Name = std::string(reg_info->name);927 bool IsCalleeSaved =928 llvm::StringSwitch<bool>(Name)929 .Cases({"r12", "r13", "r14", "r15", "rbp", "ebp", "rbx", "ebx"}, true)930 .Cases({"rip", "eip", "rsp", "esp", "sp", "fp", "pc"}, true)931 .Default(false);932 return IsCalleeSaved;933}934 935uint32_t ABISysV_x86_64::GetGenericNum(llvm::StringRef name) {936 return llvm::StringSwitch<uint32_t>(name)937 .Case("rip", LLDB_REGNUM_GENERIC_PC)938 .Case("rsp", LLDB_REGNUM_GENERIC_SP)939 .Case("rbp", LLDB_REGNUM_GENERIC_FP)940 .Case("rflags", LLDB_REGNUM_GENERIC_FLAGS)941 // gdbserver uses eflags942 .Case("eflags", LLDB_REGNUM_GENERIC_FLAGS)943 .Case("rdi", LLDB_REGNUM_GENERIC_ARG1)944 .Case("rsi", LLDB_REGNUM_GENERIC_ARG2)945 .Case("rdx", LLDB_REGNUM_GENERIC_ARG3)946 .Case("rcx", LLDB_REGNUM_GENERIC_ARG4)947 .Case("r8", LLDB_REGNUM_GENERIC_ARG5)948 .Case("r9", LLDB_REGNUM_GENERIC_ARG6)949 .Default(LLDB_INVALID_REGNUM);950}951 952void ABISysV_x86_64::Initialize() {953 PluginManager::RegisterPlugin(954 GetPluginNameStatic(), "System V ABI for x86_64 targets", CreateInstance);955}956 957void ABISysV_x86_64::Terminate() {958 PluginManager::UnregisterPlugin(CreateInstance);959}960