1079 lines · cpp
1//===-- ABISysV_ppc64.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_ppc64.h"10 11#include "llvm/ADT/STLExtras.h"12#include "llvm/TargetParser/Triple.h"13 14#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"15#include "Utility/PPC64LE_DWARF_Registers.h"16#include "Utility/PPC64_DWARF_Registers.h"17#include "lldb/Core/Module.h"18#include "lldb/Core/PluginManager.h"19#include "lldb/Core/Value.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 "lldb/ValueObject/ValueObjectConstResult.h"33#include "lldb/ValueObject/ValueObjectMemory.h"34#include "lldb/ValueObject/ValueObjectRegister.h"35 36#include "clang/AST/ASTContext.h"37#include "clang/AST/Attr.h"38#include "clang/AST/Decl.h"39 40#define DECLARE_REGISTER_INFOS_PPC64_STRUCT41#include "Plugins/Process/Utility/RegisterInfos_ppc64.h"42#undef DECLARE_REGISTER_INFOS_PPC64_STRUCT43 44#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT45#include "Plugins/Process/Utility/RegisterInfos_ppc64le.h"46#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT47#include <optional>48 49using namespace lldb;50using namespace lldb_private;51 52LLDB_PLUGIN_DEFINE(ABISysV_ppc64)53 54const lldb_private::RegisterInfo *55ABISysV_ppc64::GetRegisterInfoArray(uint32_t &count) {56 if (GetByteOrder() == lldb::eByteOrderLittle) {57 count = std::size(g_register_infos_ppc64le);58 return g_register_infos_ppc64le;59 } else {60 count = std::size(g_register_infos_ppc64);61 return g_register_infos_ppc64;62 }63}64 65size_t ABISysV_ppc64::GetRedZoneSize() const { return 224; }66 67lldb::ByteOrder ABISysV_ppc64::GetByteOrder() const {68 return GetProcessSP()->GetByteOrder();69}70 71// Static Functions72 73ABISP74ABISysV_ppc64::CreateInstance(lldb::ProcessSP process_sp,75 const ArchSpec &arch) {76 if (arch.GetTriple().isPPC64())77 return ABISP(78 new ABISysV_ppc64(std::move(process_sp), MakeMCRegisterInfo(arch)));79 return ABISP();80}81 82bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,83 addr_t func_addr, addr_t return_addr,84 llvm::ArrayRef<addr_t> args) const {85 Log *log = GetLog(LLDBLog::Expressions);86 87 if (log) {88 StreamString s;89 s.Printf("ABISysV_ppc64::PrepareTrivialCall (tid = 0x%" PRIx6490 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx6491 ", return_addr = 0x%" PRIx64,92 thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,93 (uint64_t)return_addr);94 95 for (size_t i = 0; i < args.size(); ++i)96 s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),97 args[i]);98 s.PutCString(")");99 log->PutString(s.GetString());100 }101 102 RegisterContext *reg_ctx = thread.GetRegisterContext().get();103 if (!reg_ctx)104 return false;105 106 const RegisterInfo *reg_info = nullptr;107 108 if (args.size() > 8) // TODO handle more than 8 arguments109 return false;110 111 for (size_t i = 0; i < args.size(); ++i) {112 reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,113 LLDB_REGNUM_GENERIC_ARG1 + i);114 LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",115 static_cast<uint64_t>(i + 1), args[i], reg_info->name);116 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))117 return false;118 }119 120 // First, align the SP121 122 LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,123 (uint64_t)sp, (uint64_t)(sp & ~0xfull));124 125 sp &= ~(0xfull); // 16-byte alignment126 127 sp -= 544; // allocate frame to save TOC, RA and SP.128 129 Status error;130 uint64_t reg_value;131 const RegisterInfo *pc_reg_info =132 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);133 const RegisterInfo *sp_reg_info =134 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);135 ProcessSP process_sp(thread.GetProcess());136 const RegisterInfo *lr_reg_info =137 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);138 const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoAtIndex(2);139 const RegisterInfo *r12_reg_info = reg_ctx->GetRegisterInfoAtIndex(12);140 141 // Save return address onto the stack.142 LLDB_LOGF(log,143 "Pushing the return address onto the stack: 0x%" PRIx64144 "(+16): 0x%" PRIx64,145 (uint64_t)sp, (uint64_t)return_addr);146 if (!process_sp->WritePointerToMemory(sp + 16, return_addr, error))147 return false;148 149 // Write the return address to link register.150 LLDB_LOGF(log, "Writing LR: 0x%" PRIx64, (uint64_t)return_addr);151 if (!reg_ctx->WriteRegisterFromUnsigned(lr_reg_info, return_addr))152 return false;153 154 // Write target address to %r12 register.155 LLDB_LOGF(log, "Writing R12: 0x%" PRIx64, (uint64_t)func_addr);156 if (!reg_ctx->WriteRegisterFromUnsigned(r12_reg_info, func_addr))157 return false;158 159 // Read TOC pointer value.160 reg_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0);161 162 // Write TOC pointer onto the stack.163 uint64_t stack_offset;164 if (GetByteOrder() == lldb::eByteOrderLittle)165 stack_offset = 24;166 else167 stack_offset = 40;168 169 LLDB_LOGF(log, "Writing R2 (TOC) at SP(0x%" PRIx64 ")+%d: 0x%" PRIx64,170 (uint64_t)(sp + stack_offset), (int)stack_offset,171 (uint64_t)reg_value);172 if (!process_sp->WritePointerToMemory(sp + stack_offset, reg_value, error))173 return false;174 175 // Read the current SP value.176 reg_value = reg_ctx->ReadRegisterAsUnsigned(sp_reg_info, 0);177 178 // Save current SP onto the stack.179 LLDB_LOGF(log, "Writing SP at SP(0x%" PRIx64 ")+0: 0x%" PRIx64, (uint64_t)sp,180 (uint64_t)reg_value);181 if (!process_sp->WritePointerToMemory(sp, reg_value, error))182 return false;183 184 // %r1 is set to the actual stack value.185 LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);186 187 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))188 return false;189 190 // %pc is set to the address of the called function.191 192 LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);193 194 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))195 return false;196 197 return true;198}199 200static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,201 bool is_signed, Thread &thread,202 uint32_t *argument_register_ids,203 unsigned int ¤t_argument_register,204 addr_t ¤t_stack_argument) {205 if (bit_width > 64)206 return false; // Scalar can't hold large integer arguments207 208 if (current_argument_register < 6) {209 scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(210 argument_register_ids[current_argument_register], 0);211 current_argument_register++;212 if (is_signed)213 scalar.SignExtend(bit_width);214 } else {215 uint32_t byte_size = (bit_width + (8 - 1)) / 8;216 Status error;217 if (thread.GetProcess()->ReadScalarIntegerFromMemory(218 current_stack_argument, byte_size, is_signed, scalar, error)) {219 current_stack_argument += byte_size;220 return true;221 }222 return false;223 }224 return true;225}226 227bool ABISysV_ppc64::GetArgumentValues(Thread &thread, ValueList &values) const {228 unsigned int num_values = values.GetSize();229 unsigned int value_index;230 231 // Extract the register context so we can read arguments from registers232 233 RegisterContext *reg_ctx = thread.GetRegisterContext().get();234 235 if (!reg_ctx)236 return false;237 238 // Get the pointer to the first stack argument so we have a place to start239 // when reading data240 241 addr_t sp = reg_ctx->GetSP(0);242 243 if (!sp)244 return false;245 246 uint64_t stack_offset;247 if (GetByteOrder() == lldb::eByteOrderLittle)248 stack_offset = 32;249 else250 stack_offset = 48;251 252 // jump over return address.253 addr_t current_stack_argument = sp + stack_offset;254 uint32_t argument_register_ids[8];255 256 for (size_t i = 0; i < 8; ++i) {257 argument_register_ids[i] =258 reg_ctx259 ->GetRegisterInfo(eRegisterKindGeneric,260 LLDB_REGNUM_GENERIC_ARG1 + i)261 ->kinds[eRegisterKindLLDB];262 }263 264 unsigned int current_argument_register = 0;265 266 for (value_index = 0; value_index < num_values; ++value_index) {267 Value *value = values.GetValueAtIndex(value_index);268 269 if (!value)270 return false;271 272 // We currently only support extracting values with Clang QualTypes. Do we273 // care about others?274 CompilerType compiler_type = value->GetCompilerType();275 std::optional<uint64_t> bit_size =276 llvm::expectedToOptional(compiler_type.GetBitSize(&thread));277 if (!bit_size)278 return false;279 bool is_signed;280 281 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {282 ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,283 argument_register_ids, current_argument_register,284 current_stack_argument);285 } else if (compiler_type.IsPointerType()) {286 ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,287 argument_register_ids, current_argument_register,288 current_stack_argument);289 }290 }291 292 return true;293}294 295Status ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,296 lldb::ValueObjectSP &new_value_sp) {297 Status error;298 if (!new_value_sp) {299 error = Status::FromErrorString("Empty value object for return value.");300 return error;301 }302 303 CompilerType compiler_type = new_value_sp->GetCompilerType();304 if (!compiler_type) {305 error = Status::FromErrorString("Null clang type for return value.");306 return error;307 }308 309 Thread *thread = frame_sp->GetThread().get();310 311 bool is_signed;312 bool is_complex;313 314 RegisterContext *reg_ctx = thread->GetRegisterContext().get();315 316 bool set_it_simple = false;317 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||318 compiler_type.IsPointerType()) {319 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);320 321 DataExtractor data;322 Status data_error;323 size_t num_bytes = new_value_sp->GetData(data, data_error);324 if (data_error.Fail()) {325 error = Status::FromErrorStringWithFormat(326 "Couldn't convert return value to raw data: %s",327 data_error.AsCString());328 return error;329 }330 lldb::offset_t offset = 0;331 if (num_bytes <= 8) {332 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);333 334 if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))335 set_it_simple = true;336 } else {337 error = Status::FromErrorString(338 "We don't support returning longer than 64 bit "339 "integer values at present.");340 }341 } else if (compiler_type.IsFloatingPointType(is_complex)) {342 if (is_complex)343 error = Status::FromErrorString(344 "We don't support returning complex values at present");345 else {346 std::optional<uint64_t> bit_width =347 llvm::expectedToOptional(compiler_type.GetBitSize(frame_sp.get()));348 if (!bit_width) {349 error = Status::FromErrorString("can't get size of type");350 return error;351 }352 if (*bit_width <= 64) {353 DataExtractor data;354 Status data_error;355 size_t num_bytes = new_value_sp->GetData(data, data_error);356 if (data_error.Fail()) {357 error = Status::FromErrorStringWithFormat(358 "Couldn't convert return value to raw data: %s",359 data_error.AsCString());360 return error;361 }362 363 unsigned char buffer[16];364 ByteOrder byte_order = data.GetByteOrder();365 366 data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);367 set_it_simple = true;368 } else {369 // FIXME - don't know how to do 80 bit long doubles yet.370 error = Status::FromErrorString(371 "We don't support returning float values > 64 bits at present");372 }373 }374 }375 376 if (!set_it_simple) {377 // Okay we've got a structure or something that doesn't fit in a simple378 // register. We should figure out where it really goes, but we don't379 // support this yet.380 error = Status::FromErrorString(381 "We only support setting simple integer and float "382 "return types at present.");383 }384 385 return error;386}387 388//389// ReturnValueExtractor390//391 392namespace {393 394#define LOG_PREFIX "ReturnValueExtractor: "395 396class ReturnValueExtractor {397 // This class represents a register, from which data may be extracted.398 //399 // It may be constructed by directly specifying its index (where 0 is the400 // first register used to return values) or by specifying the offset of a401 // given struct field, in which case the appropriated register index will be402 // calculated.403 class Register {404 public:405 enum Type {406 GPR, // General Purpose Register407 FPR // Floating Point Register408 };409 410 // main constructor411 //412 // offs - field offset in struct413 Register(Type ty, uint32_t index, uint32_t offs, RegisterContext *reg_ctx,414 ByteOrder byte_order)415 : m_index(index), m_offs(offs % sizeof(uint64_t)),416 m_avail(sizeof(uint64_t) - m_offs), m_type(ty), m_reg_ctx(reg_ctx),417 m_byte_order(byte_order) {}418 419 // explicit index, no offset420 Register(Type ty, uint32_t index, RegisterContext *reg_ctx,421 ByteOrder byte_order)422 : Register(ty, index, 0, reg_ctx, byte_order) {}423 424 // GPR, calculate index from offs425 Register(uint32_t offs, RegisterContext *reg_ctx, ByteOrder byte_order)426 : Register(GPR, offs / sizeof(uint64_t), offs, reg_ctx, byte_order) {}427 428 uint32_t Index() const { return m_index; }429 430 // register offset where data is located431 uint32_t Offs() const { return m_offs; }432 433 // available bytes in this register434 uint32_t Avail() const { return m_avail; }435 436 bool IsValid() const {437 if (m_index > 7) {438 LLDB_LOG(m_log, LOG_PREFIX439 "No more than 8 registers should be used to return values");440 return false;441 }442 return true;443 }444 445 std::string GetName() const {446 if (m_type == GPR)447 return ("r" + llvm::Twine(m_index + 3)).str();448 else449 return ("f" + llvm::Twine(m_index + 1)).str();450 }451 452 // get raw register data453 bool GetRawData(uint64_t &raw_data) {454 const RegisterInfo *reg_info =455 m_reg_ctx->GetRegisterInfoByName(GetName());456 if (!reg_info) {457 LLDB_LOG(m_log, LOG_PREFIX "Failed to get RegisterInfo");458 return false;459 }460 461 RegisterValue reg_val;462 if (!m_reg_ctx->ReadRegister(reg_info, reg_val)) {463 LLDB_LOG(m_log, LOG_PREFIX "ReadRegister() failed");464 return false;465 }466 467 Status error;468 uint32_t rc = reg_val.GetAsMemoryData(469 *reg_info, &raw_data, sizeof(raw_data), m_byte_order, error);470 if (rc != sizeof(raw_data)) {471 LLDB_LOG(m_log, LOG_PREFIX "GetAsMemoryData() failed");472 return false;473 }474 475 return true;476 }477 478 private:479 uint32_t m_index;480 uint32_t m_offs;481 uint32_t m_avail;482 Type m_type;483 RegisterContext *m_reg_ctx;484 ByteOrder m_byte_order;485 Log *m_log = GetLog(LLDBLog::Expressions);486 };487 488 Register GetGPR(uint32_t index) const {489 return Register(Register::GPR, index, m_reg_ctx, m_byte_order);490 }491 492 Register GetFPR(uint32_t index) const {493 return Register(Register::FPR, index, m_reg_ctx, m_byte_order);494 }495 496 Register GetGPRByOffs(uint32_t offs) const {497 return Register(offs, m_reg_ctx, m_byte_order);498 }499 500public:501 // factory502 static llvm::Expected<ReturnValueExtractor> Create(Thread &thread,503 CompilerType &type) {504 RegisterContext *reg_ctx = thread.GetRegisterContext().get();505 if (!reg_ctx)506 return llvm::createStringError(LOG_PREFIX507 "Failed to get RegisterContext");508 509 ProcessSP process_sp = thread.GetProcess();510 if (!process_sp)511 return llvm::createStringError(LOG_PREFIX "GetProcess() failed");512 513 return ReturnValueExtractor(thread, type, reg_ctx, process_sp);514 }515 516 // main method: get value of the type specified at construction time517 ValueObjectSP GetValue() {518 const uint32_t type_flags = m_type.GetTypeInfo();519 520 // call the appropriate type handler521 ValueSP value_sp;522 ValueObjectSP valobj_sp;523 if (type_flags & eTypeIsScalar) {524 if (type_flags & eTypeIsInteger) {525 value_sp = GetIntegerValue(0);526 } else if (type_flags & eTypeIsFloat) {527 if (type_flags & eTypeIsComplex) {528 LLDB_LOG(m_log, LOG_PREFIX "Complex numbers are not supported yet");529 return ValueObjectSP();530 } else {531 value_sp = GetFloatValue(m_type, 0);532 }533 }534 } else if (type_flags & eTypeIsPointer) {535 value_sp = GetPointerValue(0);536 }537 538 if (value_sp) {539 valobj_sp = ValueObjectConstResult::Create(540 m_thread.GetStackFrameAtIndex(0).get(), *value_sp, ConstString(""));541 } else if (type_flags & eTypeIsVector) {542 valobj_sp = GetVectorValueObject();543 } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) {544 valobj_sp = GetStructValueObject();545 }546 547 return valobj_sp;548 }549 550private:551 // data552 Thread &m_thread;553 CompilerType &m_type;554 uint64_t m_byte_size;555 std::unique_ptr<DataBufferHeap> m_data_up;556 int32_t m_src_offs = 0;557 int32_t m_dst_offs = 0;558 bool m_packed = false;559 Log *m_log = GetLog(LLDBLog::Expressions);560 RegisterContext *m_reg_ctx;561 ProcessSP m_process_sp;562 ByteOrder m_byte_order;563 uint32_t m_addr_size;564 565 // methods566 567 // constructor568 ReturnValueExtractor(Thread &thread, CompilerType &type,569 RegisterContext *reg_ctx, ProcessSP process_sp)570 : m_thread(thread), m_type(type),571 m_byte_size(572 llvm::expectedToOptional(m_type.GetByteSize(&thread)).value_or(0)),573 m_data_up(new DataBufferHeap(m_byte_size, 0)), m_reg_ctx(reg_ctx),574 m_process_sp(process_sp), m_byte_order(process_sp->GetByteOrder()),575 m_addr_size(576 process_sp->GetTarget().GetArchitecture().GetAddressByteSize()) {}577 578 // build a new scalar value579 ValueSP NewScalarValue(CompilerType &type) {580 ValueSP value_sp(new Value);581 value_sp->SetCompilerType(type);582 value_sp->SetValueType(Value::ValueType::Scalar);583 return value_sp;584 }585 586 // get an integer value in the specified register587 ValueSP GetIntegerValue(uint32_t reg_index) {588 uint64_t raw_value;589 auto reg = GetGPR(reg_index);590 if (!reg.GetRawData(raw_value))591 return ValueSP();592 593 // build value from data594 ValueSP value_sp(NewScalarValue(m_type));595 596 uint32_t type_flags = m_type.GetTypeInfo();597 bool is_signed = (type_flags & eTypeIsSigned) != 0;598 599 switch (m_byte_size) {600 case sizeof(uint64_t):601 if (is_signed)602 value_sp->GetScalar() = (int64_t)(raw_value);603 else604 value_sp->GetScalar() = (uint64_t)(raw_value);605 break;606 607 case sizeof(uint32_t):608 if (is_signed)609 value_sp->GetScalar() = (int32_t)(raw_value & UINT32_MAX);610 else611 value_sp->GetScalar() = (uint32_t)(raw_value & UINT32_MAX);612 break;613 614 case sizeof(uint16_t):615 if (is_signed)616 value_sp->GetScalar() = (int16_t)(raw_value & UINT16_MAX);617 else618 value_sp->GetScalar() = (uint16_t)(raw_value & UINT16_MAX);619 break;620 621 case sizeof(uint8_t):622 if (is_signed)623 value_sp->GetScalar() = (int8_t)(raw_value & UINT8_MAX);624 else625 value_sp->GetScalar() = (uint8_t)(raw_value & UINT8_MAX);626 break;627 628 default:629 llvm_unreachable("Invalid integer size");630 }631 632 return value_sp;633 }634 635 // get a floating point value on the specified register636 ValueSP GetFloatValue(CompilerType &type, uint32_t reg_index) {637 uint64_t raw_data;638 auto reg = GetFPR(reg_index);639 if (!reg.GetRawData(raw_data))640 return {};641 642 // build value from data643 ValueSP value_sp(NewScalarValue(type));644 645 DataExtractor de(&raw_data, sizeof(raw_data), m_byte_order, m_addr_size);646 647 lldb::offset_t offset = 0;648 std::optional<uint64_t> byte_size =649 llvm::expectedToOptional(type.GetByteSize(m_process_sp.get()));650 if (!byte_size)651 return {};652 switch (*byte_size) {653 case sizeof(float):654 value_sp->GetScalar() = (float)de.GetDouble(&offset);655 break;656 657 case sizeof(double):658 value_sp->GetScalar() = de.GetDouble(&offset);659 break;660 661 default:662 llvm_unreachable("Invalid floating point size");663 }664 665 return value_sp;666 }667 668 // get pointer value from register669 ValueSP GetPointerValue(uint32_t reg_index) {670 uint64_t raw_data;671 auto reg = GetGPR(reg_index);672 if (!reg.GetRawData(raw_data))673 return ValueSP();674 675 // build value from raw data676 ValueSP value_sp(NewScalarValue(m_type));677 value_sp->GetScalar() = raw_data;678 return value_sp;679 }680 681 // build the ValueObject from our data buffer682 ValueObjectSP BuildValueObject() {683 DataExtractor de(DataBufferSP(m_data_up.release()), m_byte_order,684 m_addr_size);685 return ValueObjectConstResult::Create(&m_thread, m_type, ConstString(""),686 de);687 }688 689 // get a vector return value690 ValueObjectSP GetVectorValueObject() {691 const uint32_t MAX_VRS = 2;692 693 // get first V register used to return values694 const RegisterInfo *vr[MAX_VRS];695 vr[0] = m_reg_ctx->GetRegisterInfoByName("vr2");696 if (!vr[0]) {697 LLDB_LOG(m_log, LOG_PREFIX "Failed to get vr2 RegisterInfo");698 return ValueObjectSP();699 }700 701 const uint32_t vr_size = vr[0]->byte_size;702 size_t vrs = 1;703 if (m_byte_size > 2 * vr_size) {704 LLDB_LOG(705 m_log, LOG_PREFIX706 "Returning vectors that don't fit in 2 VR regs is not supported");707 return ValueObjectSP();708 }709 710 // load vr3, if needed711 if (m_byte_size > vr_size) {712 vrs++;713 vr[1] = m_reg_ctx->GetRegisterInfoByName("vr3");714 if (!vr[1]) {715 LLDB_LOG(m_log, LOG_PREFIX "Failed to get vr3 RegisterInfo");716 return ValueObjectSP();717 }718 }719 720 // Get the whole contents of vector registers and let the logic here721 // arrange the data properly.722 723 RegisterValue vr_val[MAX_VRS];724 Status error;725 std::unique_ptr<DataBufferHeap> vr_data(726 new DataBufferHeap(vrs * vr_size, 0));727 728 for (uint32_t i = 0; i < vrs; i++) {729 if (!m_reg_ctx->ReadRegister(vr[i], vr_val[i])) {730 LLDB_LOG(m_log, LOG_PREFIX "Failed to read vector register contents");731 return ValueObjectSP();732 }733 if (!vr_val[i].GetAsMemoryData(*vr[i], vr_data->GetBytes() + i * vr_size,734 vr_size, m_byte_order, error)) {735 LLDB_LOG(m_log, LOG_PREFIX "Failed to extract vector register bytes");736 return ValueObjectSP();737 }738 }739 740 // The compiler generated code seems to always put the vector elements at741 // the end of the vector register, in case they don't occupy all of it.742 // This offset variable handles this.743 uint32_t offs = 0;744 if (m_byte_size < vr_size)745 offs = vr_size - m_byte_size;746 747 // copy extracted data to our buffer748 memcpy(m_data_up->GetBytes(), vr_data->GetBytes() + offs, m_byte_size);749 return BuildValueObject();750 }751 752 // get a struct return value753 ValueObjectSP GetStructValueObject() {754 // case 1: get from stack755 if (m_byte_size > 2 * sizeof(uint64_t)) {756 uint64_t addr;757 auto reg = GetGPR(0);758 if (!reg.GetRawData(addr))759 return {};760 761 Status error;762 size_t rc = m_process_sp->ReadMemory(addr, m_data_up->GetBytes(),763 m_byte_size, error);764 if (rc != m_byte_size) {765 LLDB_LOG(m_log, LOG_PREFIX "Failed to read memory pointed by r3");766 return ValueObjectSP();767 }768 return BuildValueObject();769 }770 771 // get number of children772 const bool omit_empty_base_classes = true;773 auto n_or_err = m_type.GetNumChildren(omit_empty_base_classes, nullptr);774 if (!n_or_err) {775 LLDB_LOG_ERROR(m_log, n_or_err.takeError(), LOG_PREFIX "{0}");776 return {};777 }778 uint32_t n = *n_or_err;779 if (!n) {780 LLDB_LOG(m_log, LOG_PREFIX "No children found in struct");781 return {};782 }783 784 // case 2: homogeneous double or float aggregate785 CompilerType elem_type;786 if (m_type.IsHomogeneousAggregate(&elem_type)) {787 uint32_t type_flags = elem_type.GetTypeInfo();788 std::optional<uint64_t> elem_size =789 llvm::expectedToOptional(elem_type.GetByteSize(m_process_sp.get()));790 if (!elem_size)791 return {};792 if (type_flags & eTypeIsComplex || !(type_flags & eTypeIsFloat)) {793 LLDB_LOG(m_log,794 LOG_PREFIX "Unexpected type found in homogeneous aggregate");795 return {};796 }797 798 for (uint32_t i = 0; i < n; i++) {799 ValueSP val_sp = GetFloatValue(elem_type, i);800 if (!val_sp)801 return {};802 803 // copy to buffer804 Status error;805 size_t rc = val_sp->GetScalar().GetAsMemoryData(806 m_data_up->GetBytes() + m_dst_offs, *elem_size, m_byte_order,807 error);808 if (rc != *elem_size) {809 LLDB_LOG(m_log, LOG_PREFIX "Failed to get float data");810 return {};811 }812 m_dst_offs += *elem_size;813 }814 return BuildValueObject();815 }816 817 // case 3: get from GPRs818 819 // first, check if this is a packed struct or not820 auto ast = m_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();821 if (ast) {822 clang::RecordDecl *record_decl = TypeSystemClang::GetAsRecordDecl(m_type);823 824 if (record_decl) {825 auto attrs = record_decl->attrs();826 for (const auto &attr : attrs) {827 if (attr->getKind() == clang::attr::Packed) {828 m_packed = true;829 break;830 }831 }832 }833 }834 835 LLDB_LOG(m_log, LOG_PREFIX "{0} struct",836 m_packed ? "packed" : "not packed");837 838 for (uint32_t i = 0; i < n; i++) {839 std::string name;840 uint32_t size;841 (void)GetChildType(i, name, size);842 // NOTE: the offset returned by GetChildCompilerTypeAtIndex()843 // can't be used because it never considers alignment bytes844 // between struct fields.845 LLDB_LOG(m_log, LOG_PREFIX "field={0}, size={1}", name, size);846 if (!ExtractField(size))847 return ValueObjectSP();848 }849 850 return BuildValueObject();851 }852 853 // extract 'size' bytes at 'offs' from GPRs854 bool ExtractFromRegs(int32_t offs, uint32_t size, void *buf) {855 while (size) {856 auto reg = GetGPRByOffs(offs);857 if (!reg.IsValid())858 return false;859 860 uint32_t n = std::min(reg.Avail(), size);861 uint64_t raw_data;862 863 if (!reg.GetRawData(raw_data))864 return false;865 866 memcpy(buf, (char *)&raw_data + reg.Offs(), n);867 offs += n;868 size -= n;869 buf = (char *)buf + n;870 }871 return true;872 }873 874 // extract one field from GPRs and put it in our buffer875 bool ExtractField(uint32_t size) {876 auto reg = GetGPRByOffs(m_src_offs);877 if (!reg.IsValid())878 return false;879 880 // handle padding881 if (!m_packed) {882 uint32_t n = m_src_offs % size;883 884 // not 'size' bytes aligned885 if (n) {886 LLDB_LOG(m_log,887 LOG_PREFIX "Extracting {0} alignment bytes at offset {1}", n,888 m_src_offs);889 // get alignment bytes890 if (!ExtractFromRegs(m_src_offs, n, m_data_up->GetBytes() + m_dst_offs))891 return false;892 m_src_offs += n;893 m_dst_offs += n;894 }895 }896 897 // get field898 LLDB_LOG(m_log, LOG_PREFIX "Extracting {0} field bytes at offset {1}", size,899 m_src_offs);900 if (!ExtractFromRegs(m_src_offs, size, m_data_up->GetBytes() + m_dst_offs))901 return false;902 m_src_offs += size;903 m_dst_offs += size;904 return true;905 }906 907 // get child908 llvm::Expected<CompilerType> GetChildType(uint32_t i, std::string &name,909 uint32_t &size) {910 // GetChild constant inputs911 const bool transparent_pointers = false;912 const bool omit_empty_base_classes = true;913 const bool ignore_array_bounds = false;914 // GetChild output params915 int32_t child_offs;916 uint32_t child_bitfield_bit_size;917 uint32_t child_bitfield_bit_offset;918 bool child_is_base_class;919 bool child_is_deref_of_parent;920 ValueObject *valobj = nullptr;921 uint64_t language_flags;922 ExecutionContext exe_ctx;923 m_thread.CalculateExecutionContext(exe_ctx);924 925 return m_type.GetChildCompilerTypeAtIndex(926 &exe_ctx, i, transparent_pointers, omit_empty_base_classes,927 ignore_array_bounds, name, size, child_offs, child_bitfield_bit_size,928 child_bitfield_bit_offset, child_is_base_class,929 child_is_deref_of_parent, valobj, language_flags);930 }931};932 933#undef LOG_PREFIX934 935} // anonymous namespace936 937ValueObjectSP938ABISysV_ppc64::GetReturnValueObjectSimple(Thread &thread,939 CompilerType &type) const {940 if (!type)941 return ValueObjectSP();942 943 auto exp_extractor = ReturnValueExtractor::Create(thread, type);944 if (!exp_extractor) {945 Log *log = GetLog(LLDBLog::Expressions);946 LLDB_LOG_ERROR(log, exp_extractor.takeError(),947 "Extracting return value failed: {0}");948 return ValueObjectSP();949 }950 951 return exp_extractor.get().GetValue();952}953 954ValueObjectSP ABISysV_ppc64::GetReturnValueObjectImpl(955 Thread &thread, CompilerType &return_compiler_type) const {956 return GetReturnValueObjectSimple(thread, return_compiler_type);957}958 959UnwindPlanSP ABISysV_ppc64::CreateFunctionEntryUnwindPlan() {960 961 uint32_t lr_reg_num;962 uint32_t sp_reg_num;963 uint32_t pc_reg_num;964 965 if (GetByteOrder() == lldb::eByteOrderLittle) {966 lr_reg_num = ppc64le_dwarf::dwarf_lr_ppc64le;967 sp_reg_num = ppc64le_dwarf::dwarf_r1_ppc64le;968 pc_reg_num = ppc64le_dwarf::dwarf_pc_ppc64le;969 } else {970 lr_reg_num = ppc64_dwarf::dwarf_lr_ppc64;971 sp_reg_num = ppc64_dwarf::dwarf_r1_ppc64;972 pc_reg_num = ppc64_dwarf::dwarf_pc_ppc64;973 }974 975 UnwindPlan::Row row;976 977 // Our Call Frame Address is the stack pointer value978 row.GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);979 980 // The previous PC is in the LR. All other registers are the same.981 row.SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);982 983 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);984 plan_sp->AppendRow(std::move(row));985 plan_sp->SetSourceName("ppc64 at-func-entry default");986 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);987 return plan_sp;988}989 990UnwindPlanSP ABISysV_ppc64::CreateDefaultUnwindPlan() {991 uint32_t sp_reg_num;992 uint32_t pc_reg_num;993 uint32_t cr_reg_num;994 995 if (GetByteOrder() == lldb::eByteOrderLittle) {996 sp_reg_num = ppc64le_dwarf::dwarf_r1_ppc64le;997 pc_reg_num = ppc64le_dwarf::dwarf_lr_ppc64le;998 cr_reg_num = ppc64le_dwarf::dwarf_cr_ppc64le;999 } else {1000 sp_reg_num = ppc64_dwarf::dwarf_r1_ppc64;1001 pc_reg_num = ppc64_dwarf::dwarf_lr_ppc64;1002 cr_reg_num = ppc64_dwarf::dwarf_cr_ppc64;1003 }1004 1005 UnwindPlan::Row row;1006 const int32_t ptr_size = 8;1007 row.SetUnspecifiedRegistersAreUndefined(true);1008 row.GetCFAValue().SetIsRegisterDereferenced(sp_reg_num);1009 1010 row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 2, true);1011 row.SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);1012 row.SetRegisterLocationToAtCFAPlusOffset(cr_reg_num, ptr_size, true);1013 1014 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);1015 plan_sp->AppendRow(std::move(row));1016 plan_sp->SetSourceName("ppc64 default unwind plan");1017 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);1018 plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);1019 plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);1020 plan_sp->SetReturnAddressRegister(pc_reg_num);1021 return plan_sp;1022}1023 1024bool ABISysV_ppc64::RegisterIsVolatile(const RegisterInfo *reg_info) {1025 return !RegisterIsCalleeSaved(reg_info);1026}1027 1028// See "Register Usage" in the1029// "System V Application Binary Interface"1030// "64-bit PowerPC ELF Application Binary Interface Supplement" current version1031// is 2 released 2015 at1032// https://members.openpowerfoundation.org/document/dl/5761033bool ABISysV_ppc64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {1034 if (reg_info) {1035 // Preserved registers are :1036 // r1,r2,r13-r311037 // cr2-cr4 (partially preserved)1038 // f14-f31 (not yet)1039 // v20-v31 (not yet)1040 // vrsave (not yet)1041 1042 const char *name = reg_info->name;1043 if (name[0] == 'r') {1044 if ((name[1] == '1' || name[1] == '2') && name[2] == '\0')1045 return true;1046 if (name[1] == '1' && name[2] > '2')1047 return true;1048 if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')1049 return true;1050 }1051 1052 if (name[0] == 'f' && name[1] >= '0' && name[2] <= '9') {1053 if (name[2] == '\0')1054 return false;1055 if (name[1] == '1' && name[2] >= '4')1056 return true;1057 if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')1058 return true;1059 }1060 1061 if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp1062 return true;1063 if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp1064 return false;1065 if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc1066 return true;1067 }1068 return false;1069}1070 1071void ABISysV_ppc64::Initialize() {1072 PluginManager::RegisterPlugin(1073 GetPluginNameStatic(), "System V ABI for ppc64 targets", CreateInstance);1074}1075 1076void ABISysV_ppc64::Terminate() {1077 PluginManager::UnregisterPlugin(CreateInstance);1078}1079