1 //===-- ABISysV_ppc64.cpp ---------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "ABISysV_ppc64.h"
14 // Other libraries and framework includes
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/Triple.h"
19 #include "Utility/PPC64LE_DWARF_Registers.h"
20 #include "Utility/PPC64_DWARF_Registers.h"
21 #include "lldb/Core/Module.h"
22 #include "lldb/Core/PluginManager.h"
23 #include "lldb/Core/RegisterValue.h"
24 #include "lldb/Core/Value.h"
25 #include "lldb/Core/ValueObjectConstResult.h"
26 #include "lldb/Core/ValueObjectMemory.h"
27 #include "lldb/Core/ValueObjectRegister.h"
28 #include "lldb/Symbol/ClangASTContext.h"
29 #include "lldb/Symbol/UnwindPlan.h"
30 #include "lldb/Target/Process.h"
31 #include "lldb/Target/RegisterContext.h"
32 #include "lldb/Target/StackFrame.h"
33 #include "lldb/Target/Target.h"
34 #include "lldb/Target/Thread.h"
35 #include "lldb/Utility/ConstString.h"
36 #include "lldb/Utility/DataExtractor.h"
37 #include "lldb/Utility/Log.h"
38 #include "lldb/Utility/Status.h"
40 #include "clang/AST/ASTContext.h"
41 #include "clang/AST/Attr.h"
42 #include "clang/AST/Decl.h"
44 #define DECLARE_REGISTER_INFOS_PPC64_STRUCT
45 #include "Plugins/Process/Utility/RegisterInfos_ppc64.h"
46 #undef DECLARE_REGISTER_INFOS_PPC64_STRUCT
48 #define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
49 #include "Plugins/Process/Utility/RegisterInfos_ppc64le.h"
50 #undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
53 using namespace lldb_private;
55 const lldb_private::RegisterInfo *
56 ABISysV_ppc64::GetRegisterInfoArray(uint32_t &count) {
57 if (GetByteOrder() == lldb::eByteOrderLittle) {
58 count = llvm::array_lengthof(g_register_infos_ppc64le);
59 return g_register_infos_ppc64le;
61 count = llvm::array_lengthof(g_register_infos_ppc64);
62 return g_register_infos_ppc64;
66 size_t ABISysV_ppc64::GetRedZoneSize() const { return 224; }
68 lldb::ByteOrder ABISysV_ppc64::GetByteOrder() const {
69 return GetProcessSP()->GetByteOrder();
72 //------------------------------------------------------------------
74 //------------------------------------------------------------------
77 ABISysV_ppc64::CreateInstance(lldb::ProcessSP process_sp,
78 const ArchSpec &arch) {
79 if (arch.GetTriple().getArch() == llvm::Triple::ppc64 ||
80 arch.GetTriple().getArch() == llvm::Triple::ppc64le) {
81 return ABISP(new ABISysV_ppc64(process_sp));
86 bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
87 addr_t func_addr, addr_t return_addr,
88 llvm::ArrayRef<addr_t> args) const {
89 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
93 s.Printf("ABISysV_ppc64::PrepareTrivialCall (tid = 0x%" PRIx64
94 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
95 ", return_addr = 0x%" PRIx64,
96 thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
97 (uint64_t)return_addr);
99 for (size_t i = 0; i < args.size(); ++i)
100 s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
103 log->PutString(s.GetString());
106 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
110 const RegisterInfo *reg_info = nullptr;
112 if (args.size() > 8) // TODO handle more than 8 arguments
115 for (size_t i = 0; i < args.size(); ++i) {
116 reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
117 LLDB_REGNUM_GENERIC_ARG1 + i);
119 log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
120 static_cast<uint64_t>(i + 1), args[i], reg_info->name);
121 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
125 // First, align the SP
128 log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
129 (uint64_t)sp, (uint64_t)(sp & ~0xfull));
131 sp &= ~(0xfull); // 16-byte alignment
133 sp -= 544; // allocate frame to save TOC, RA and SP.
137 const RegisterInfo *pc_reg_info =
138 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
139 const RegisterInfo *sp_reg_info =
140 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
141 ProcessSP process_sp(thread.GetProcess());
142 const RegisterInfo *lr_reg_info =
143 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
144 const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoAtIndex(2);
145 const RegisterInfo *r12_reg_info = reg_ctx->GetRegisterInfoAtIndex(12);
147 // Save return address onto the stack.
149 log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
151 (uint64_t)sp, (uint64_t)return_addr);
152 if (!process_sp->WritePointerToMemory(sp + 16, return_addr, error))
155 // Write the return address to link register.
157 log->Printf("Writing LR: 0x%" PRIx64, (uint64_t)return_addr);
158 if (!reg_ctx->WriteRegisterFromUnsigned(lr_reg_info, return_addr))
161 // Write target address to %r12 register.
163 log->Printf("Writing R12: 0x%" PRIx64, (uint64_t)func_addr);
164 if (!reg_ctx->WriteRegisterFromUnsigned(r12_reg_info, func_addr))
167 // Read TOC pointer value.
168 reg_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0);
170 // Write TOC pointer onto the stack.
171 uint64_t stack_offset;
172 if (GetByteOrder() == lldb::eByteOrderLittle)
178 log->Printf("Writing R2 (TOC) at SP(0x%" PRIx64 ")+%d: 0x%" PRIx64,
179 (uint64_t)(sp + stack_offset), (int)stack_offset,
180 (uint64_t)reg_value);
181 if (!process_sp->WritePointerToMemory(sp + stack_offset, reg_value, error))
184 // Read the current SP value.
185 reg_value = reg_ctx->ReadRegisterAsUnsigned(sp_reg_info, 0);
187 // Save current SP onto the stack.
189 log->Printf("Writing SP at SP(0x%" PRIx64 ")+0: 0x%" PRIx64, (uint64_t)sp,
190 (uint64_t)reg_value);
191 if (!process_sp->WritePointerToMemory(sp, reg_value, error))
194 // %r1 is set to the actual stack value.
196 log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
198 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
201 // %pc is set to the address of the called function.
204 log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
206 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
212 static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
213 bool is_signed, Thread &thread,
214 uint32_t *argument_register_ids,
215 unsigned int ¤t_argument_register,
216 addr_t ¤t_stack_argument) {
218 return false; // Scalar can't hold large integer arguments
220 if (current_argument_register < 6) {
221 scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
222 argument_register_ids[current_argument_register], 0);
223 current_argument_register++;
225 scalar.SignExtend(bit_width);
227 uint32_t byte_size = (bit_width + (8 - 1)) / 8;
229 if (thread.GetProcess()->ReadScalarIntegerFromMemory(
230 current_stack_argument, byte_size, is_signed, scalar, error)) {
231 current_stack_argument += byte_size;
239 bool ABISysV_ppc64::GetArgumentValues(Thread &thread, ValueList &values) const {
240 unsigned int num_values = values.GetSize();
241 unsigned int value_index;
243 // Extract the register context so we can read arguments from registers
245 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
250 // Get the pointer to the first stack argument so we have a place to start
253 addr_t sp = reg_ctx->GetSP(0);
258 uint64_t stack_offset;
259 if (GetByteOrder() == lldb::eByteOrderLittle)
264 // jump over return address.
265 addr_t current_stack_argument = sp + stack_offset;
266 uint32_t argument_register_ids[8];
268 for (size_t i = 0; i < 8; ++i) {
269 argument_register_ids[i] =
271 ->GetRegisterInfo(eRegisterKindGeneric,
272 LLDB_REGNUM_GENERIC_ARG1 + i)
273 ->kinds[eRegisterKindLLDB];
276 unsigned int current_argument_register = 0;
278 for (value_index = 0; value_index < num_values; ++value_index) {
279 Value *value = values.GetValueAtIndex(value_index);
284 // We currently only support extracting values with Clang QualTypes. Do we
285 // care about others?
286 CompilerType compiler_type = value->GetCompilerType();
291 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
292 ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
293 is_signed, thread, argument_register_ids,
294 current_argument_register, current_stack_argument);
295 } else if (compiler_type.IsPointerType()) {
296 ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
297 false, thread, argument_register_ids,
298 current_argument_register, current_stack_argument);
305 Status ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
306 lldb::ValueObjectSP &new_value_sp) {
309 error.SetErrorString("Empty value object for return value.");
313 CompilerType compiler_type = new_value_sp->GetCompilerType();
314 if (!compiler_type) {
315 error.SetErrorString("Null clang type for return value.");
319 Thread *thread = frame_sp->GetThread().get();
325 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
327 bool set_it_simple = false;
328 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
329 compiler_type.IsPointerType()) {
330 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
334 size_t num_bytes = new_value_sp->GetData(data, data_error);
335 if (data_error.Fail()) {
336 error.SetErrorStringWithFormat(
337 "Couldn't convert return value to raw data: %s",
338 data_error.AsCString());
341 lldb::offset_t offset = 0;
342 if (num_bytes <= 8) {
343 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
345 if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
346 set_it_simple = true;
348 error.SetErrorString("We don't support returning longer than 64 bit "
349 "integer values at present.");
351 } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
353 error.SetErrorString(
354 "We don't support returning complex values at present");
356 size_t bit_width = compiler_type.GetBitSize(frame_sp.get());
357 if (bit_width <= 64) {
360 size_t num_bytes = new_value_sp->GetData(data, data_error);
361 if (data_error.Fail()) {
362 error.SetErrorStringWithFormat(
363 "Couldn't convert return value to raw data: %s",
364 data_error.AsCString());
368 unsigned char buffer[16];
369 ByteOrder byte_order = data.GetByteOrder();
371 data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
372 set_it_simple = true;
374 // FIXME - don't know how to do 80 bit long doubles yet.
375 error.SetErrorString(
376 "We don't support returning float values > 64 bits at present");
381 if (!set_it_simple) {
382 // Okay we've got a structure or something that doesn't fit in a simple
383 // register. We should figure out where it really goes, but we don't
385 error.SetErrorString("We only support setting simple integer and float "
386 "return types at present.");
393 // ReturnValueExtractor
398 #define LOG_PREFIX "ReturnValueExtractor: "
400 class ReturnValueExtractor {
401 // This class represents a register, from which data may be extracted.
403 // It may be constructed by directly specifying its index (where 0 is the
404 // first register used to return values) or by specifying the offset of a
405 // given struct field, in which case the appropriated register index will be
410 GPR, // General Purpose Register
411 FPR // Floating Point Register
416 // offs - field offset in struct
417 Register(Type ty, uint32_t index, uint32_t offs, RegisterContext *reg_ctx,
418 ByteOrder byte_order)
419 : m_index(index), m_offs(offs % sizeof(uint64_t)),
420 m_avail(sizeof(uint64_t) - m_offs), m_type(ty), m_reg_ctx(reg_ctx),
421 m_byte_order(byte_order) {}
423 // explicit index, no offset
424 Register(Type ty, uint32_t index, RegisterContext *reg_ctx,
425 ByteOrder byte_order)
426 : Register(ty, index, 0, reg_ctx, byte_order) {}
428 // GPR, calculate index from offs
429 Register(uint32_t offs, RegisterContext *reg_ctx, ByteOrder byte_order)
430 : Register(GPR, offs / sizeof(uint64_t), offs, reg_ctx, byte_order) {}
432 uint32_t Index() const { return m_index; }
434 // register offset where data is located
435 uint32_t Offs() const { return m_offs; }
437 // available bytes in this register
438 uint32_t Avail() const { return m_avail; }
440 bool IsValid() const {
442 LLDB_LOG(m_log, LOG_PREFIX
443 "No more than 8 registers should be used to return values");
449 std::string GetName() const {
451 return ("r" + llvm::Twine(m_index + 3)).str();
453 return ("f" + llvm::Twine(m_index + 1)).str();
456 // get raw register data
457 bool GetRawData(uint64_t &raw_data) {
458 const RegisterInfo *reg_info =
459 m_reg_ctx->GetRegisterInfoByName(GetName());
461 LLDB_LOG(m_log, LOG_PREFIX "Failed to get RegisterInfo");
465 RegisterValue reg_val;
466 if (!m_reg_ctx->ReadRegister(reg_info, reg_val)) {
467 LLDB_LOG(m_log, LOG_PREFIX "ReadRegister() failed");
472 uint32_t rc = reg_val.GetAsMemoryData(
473 reg_info, &raw_data, sizeof(raw_data), m_byte_order, error);
474 if (rc != sizeof(raw_data)) {
475 LLDB_LOG(m_log, LOG_PREFIX "GetAsMemoryData() failed");
487 RegisterContext *m_reg_ctx;
488 ByteOrder m_byte_order;
490 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
493 Register GetGPR(uint32_t index) const {
494 return Register(Register::GPR, index, m_reg_ctx, m_byte_order);
497 Register GetFPR(uint32_t index) const {
498 return Register(Register::FPR, index, m_reg_ctx, m_byte_order);
501 Register GetGPRByOffs(uint32_t offs) const {
502 return Register(offs, m_reg_ctx, m_byte_order);
507 static llvm::Expected<ReturnValueExtractor> Create(Thread &thread,
508 CompilerType &type) {
509 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
511 return llvm::make_error<llvm::StringError>(
512 LOG_PREFIX "Failed to get RegisterContext",
513 llvm::inconvertibleErrorCode());
515 ProcessSP process_sp = thread.GetProcess();
517 return llvm::make_error<llvm::StringError>(
518 LOG_PREFIX "GetProcess() failed", llvm::inconvertibleErrorCode());
520 return ReturnValueExtractor(thread, type, reg_ctx, process_sp);
523 // main method: get value of the type specified at construction time
524 ValueObjectSP GetValue() {
525 const uint32_t type_flags = m_type.GetTypeInfo();
527 // call the appropriate type handler
529 ValueObjectSP valobj_sp;
530 if (type_flags & eTypeIsScalar) {
531 if (type_flags & eTypeIsInteger) {
532 value_sp = GetIntegerValue(0);
533 } else if (type_flags & eTypeIsFloat) {
534 if (type_flags & eTypeIsComplex) {
535 LLDB_LOG(m_log, LOG_PREFIX "Complex numbers are not supported yet");
536 return ValueObjectSP();
538 value_sp = GetFloatValue(m_type, 0);
541 } else if (type_flags & eTypeIsPointer) {
542 value_sp = GetPointerValue(0);
546 valobj_sp = ValueObjectConstResult::Create(
547 m_thread.GetStackFrameAtIndex(0).get(), *value_sp, ConstString(""));
548 } else if (type_flags & eTypeIsVector) {
549 valobj_sp = GetVectorValueObject();
550 } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) {
551 valobj_sp = GetStructValueObject();
560 CompilerType &m_type;
561 uint64_t m_byte_size;
562 std::unique_ptr<DataBufferHeap> m_data_ap;
563 int32_t m_src_offs = 0;
564 int32_t m_dst_offs = 0;
565 bool m_packed = false;
566 Log *m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
567 RegisterContext *m_reg_ctx;
568 ProcessSP m_process_sp;
569 ByteOrder m_byte_order;
570 uint32_t m_addr_size;
575 ReturnValueExtractor(Thread &thread, CompilerType &type,
576 RegisterContext *reg_ctx, ProcessSP process_sp)
577 : m_thread(thread), m_type(type),
578 m_byte_size(m_type.GetByteSize(nullptr)),
579 m_data_ap(new DataBufferHeap(m_byte_size, 0)), m_reg_ctx(reg_ctx),
580 m_process_sp(process_sp), m_byte_order(process_sp->GetByteOrder()),
582 process_sp->GetTarget().GetArchitecture().GetAddressByteSize()) {}
584 // build a new scalar value
585 ValueSP NewScalarValue(CompilerType &type) {
586 ValueSP value_sp(new Value);
587 value_sp->SetCompilerType(type);
588 value_sp->SetValueType(Value::eValueTypeScalar);
592 // get an integer value in the specified register
593 ValueSP GetIntegerValue(uint32_t reg_index) {
595 auto reg = GetGPR(reg_index);
596 if (!reg.GetRawData(raw_value))
599 // build value from data
600 ValueSP value_sp(NewScalarValue(m_type));
602 uint32_t type_flags = m_type.GetTypeInfo();
603 bool is_signed = (type_flags & eTypeIsSigned) != 0;
605 switch (m_byte_size) {
606 case sizeof(uint64_t):
608 value_sp->GetScalar() = (int64_t)(raw_value);
610 value_sp->GetScalar() = (uint64_t)(raw_value);
613 case sizeof(uint32_t):
615 value_sp->GetScalar() = (int32_t)(raw_value & UINT32_MAX);
617 value_sp->GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
620 case sizeof(uint16_t):
622 value_sp->GetScalar() = (int16_t)(raw_value & UINT16_MAX);
624 value_sp->GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
627 case sizeof(uint8_t):
629 value_sp->GetScalar() = (int8_t)(raw_value & UINT8_MAX);
631 value_sp->GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
635 llvm_unreachable("Invalid integer size");
641 // get a floating point value on the specified register
642 ValueSP GetFloatValue(CompilerType &type, uint32_t reg_index) {
644 auto reg = GetFPR(reg_index);
645 if (!reg.GetRawData(raw_data))
648 // build value from data
649 ValueSP value_sp(NewScalarValue(type));
651 DataExtractor de(&raw_data, sizeof(raw_data), m_byte_order, m_addr_size);
654 size_t byte_size = type.GetByteSize(nullptr);
657 value_sp->GetScalar() = (float)de.GetDouble(&offset);
661 value_sp->GetScalar() = de.GetDouble(&offset);
665 llvm_unreachable("Invalid floating point size");
671 // get pointer value from register
672 ValueSP GetPointerValue(uint32_t reg_index) {
674 auto reg = GetGPR(reg_index);
675 if (!reg.GetRawData(raw_data))
678 // build value from raw data
679 ValueSP value_sp(NewScalarValue(m_type));
680 value_sp->GetScalar() = raw_data;
684 // build the ValueObject from our data buffer
685 ValueObjectSP BuildValueObject() {
686 DataExtractor de(DataBufferSP(m_data_ap.release()), m_byte_order,
688 return ValueObjectConstResult::Create(&m_thread, m_type, ConstString(""),
692 // get a vector return value
693 ValueObjectSP GetVectorValueObject() {
694 const uint32_t MAX_VRS = 2;
696 // get first V register used to return values
697 const RegisterInfo *vr[MAX_VRS];
698 vr[0] = m_reg_ctx->GetRegisterInfoByName("vr2");
700 LLDB_LOG(m_log, LOG_PREFIX "Failed to get vr2 RegisterInfo");
701 return ValueObjectSP();
704 const uint32_t vr_size = vr[0]->byte_size;
706 if (m_byte_size > 2 * vr_size) {
709 "Returning vectors that don't fit in 2 VR regs is not supported");
710 return ValueObjectSP();
713 // load vr3, if needed
714 if (m_byte_size > vr_size) {
716 vr[1] = m_reg_ctx->GetRegisterInfoByName("vr3");
718 LLDB_LOG(m_log, LOG_PREFIX "Failed to get vr3 RegisterInfo");
719 return ValueObjectSP();
723 // Get the whole contents of vector registers and let the logic here
724 // arrange the data properly.
726 RegisterValue vr_val[MAX_VRS];
728 std::unique_ptr<DataBufferHeap> vr_data(
729 new DataBufferHeap(vrs * vr_size, 0));
731 for (uint32_t i = 0; i < vrs; i++) {
732 if (!m_reg_ctx->ReadRegister(vr[i], vr_val[i])) {
733 LLDB_LOG(m_log, LOG_PREFIX "Failed to read vector register contents");
734 return ValueObjectSP();
736 if (!vr_val[i].GetAsMemoryData(vr[i], vr_data->GetBytes() + i * vr_size,
737 vr_size, m_byte_order, error)) {
738 LLDB_LOG(m_log, LOG_PREFIX "Failed to extract vector register bytes");
739 return ValueObjectSP();
743 // The compiler generated code seems to always put the vector elements at
744 // the end of the vector register, in case they don't occupy all of it.
745 // This offset variable handles this.
747 if (m_byte_size < vr_size)
748 offs = vr_size - m_byte_size;
750 // copy extracted data to our buffer
751 memcpy(m_data_ap->GetBytes(), vr_data->GetBytes() + offs, m_byte_size);
752 return BuildValueObject();
755 // get a struct return value
756 ValueObjectSP GetStructValueObject() {
757 // case 1: get from stack
758 if (m_byte_size > 2 * sizeof(uint64_t)) {
760 auto reg = GetGPR(0);
761 if (!reg.GetRawData(addr))
762 return ValueObjectSP();
765 size_t rc = m_process_sp->ReadMemory(addr, m_data_ap->GetBytes(),
767 if (rc != m_byte_size) {
768 LLDB_LOG(m_log, LOG_PREFIX "Failed to read memory pointed by r3");
769 return ValueObjectSP();
771 return BuildValueObject();
774 // get number of children
775 const bool omit_empty_base_classes = true;
776 uint32_t n = m_type.GetNumChildren(omit_empty_base_classes);
778 LLDB_LOG(m_log, LOG_PREFIX "No children found in struct");
779 return ValueObjectSP();
782 // case 2: homogeneous double or float aggregate
783 CompilerType elem_type;
784 if (m_type.IsHomogeneousAggregate(&elem_type)) {
785 uint32_t type_flags = elem_type.GetTypeInfo();
786 uint64_t elem_size = elem_type.GetByteSize(nullptr);
787 if (type_flags & eTypeIsComplex || !(type_flags & eTypeIsFloat)) {
789 LOG_PREFIX "Unexpected type found in homogeneous aggregate");
790 return ValueObjectSP();
793 for (uint32_t i = 0; i < n; i++) {
794 ValueSP val_sp = GetFloatValue(elem_type, i);
796 return ValueObjectSP();
800 size_t rc = val_sp->GetScalar().GetAsMemoryData(
801 m_data_ap->GetBytes() + m_dst_offs, elem_size, m_byte_order, error);
802 if (rc != elem_size) {
803 LLDB_LOG(m_log, LOG_PREFIX "Failed to get float data");
804 return ValueObjectSP();
806 m_dst_offs += elem_size;
808 return BuildValueObject();
811 // case 3: get from GPRs
813 // first, check if this is a packed struct or not
814 ClangASTContext *ast =
815 llvm::dyn_cast<ClangASTContext>(m_type.GetTypeSystem());
817 clang::RecordDecl *record_decl = ClangASTContext::GetAsRecordDecl(m_type);
820 auto attrs = record_decl->attrs();
821 for (const auto &attr : attrs) {
822 if (attr->getKind() == clang::attr::Packed) {
830 LLDB_LOG(m_log, LOG_PREFIX "{0} struct",
831 m_packed ? "packed" : "not packed");
833 for (uint32_t i = 0; i < n; i++) {
836 GetChildType(i, name, size);
837 // NOTE: the offset returned by GetChildCompilerTypeAtIndex()
838 // can't be used because it never considers alignment bytes
839 // between struct fields.
840 LLDB_LOG(m_log, LOG_PREFIX "field={0}, size={1}", name, size);
841 if (!ExtractField(size))
842 return ValueObjectSP();
845 return BuildValueObject();
848 // extract 'size' bytes at 'offs' from GPRs
849 bool ExtractFromRegs(int32_t offs, uint32_t size, void *buf) {
851 auto reg = GetGPRByOffs(offs);
855 uint32_t n = std::min(reg.Avail(), size);
858 if (!reg.GetRawData(raw_data))
861 memcpy(buf, (char *)&raw_data + reg.Offs(), n);
864 buf = (char *)buf + n;
869 // extract one field from GPRs and put it in our buffer
870 bool ExtractField(uint32_t size) {
871 auto reg = GetGPRByOffs(m_src_offs);
877 uint32_t n = m_src_offs % size;
879 // not 'size' bytes aligned
882 LOG_PREFIX "Extracting {0} alignment bytes at offset {1}", n,
884 // get alignment bytes
885 if (!ExtractFromRegs(m_src_offs, n, m_data_ap->GetBytes() + m_dst_offs))
893 LLDB_LOG(m_log, LOG_PREFIX "Extracting {0} field bytes at offset {1}", size,
895 if (!ExtractFromRegs(m_src_offs, size, m_data_ap->GetBytes() + m_dst_offs))
903 CompilerType GetChildType(uint32_t i, std::string &name, uint32_t &size) {
904 // GetChild constant inputs
905 const bool transparent_pointers = false;
906 const bool omit_empty_base_classes = true;
907 const bool ignore_array_bounds = false;
908 // GetChild output params
910 uint32_t child_bitfield_bit_size;
911 uint32_t child_bitfield_bit_offset;
912 bool child_is_base_class;
913 bool child_is_deref_of_parent;
914 ValueObject *valobj = nullptr;
915 uint64_t language_flags;
916 ExecutionContext exe_ctx;
917 m_thread.CalculateExecutionContext(exe_ctx);
919 return m_type.GetChildCompilerTypeAtIndex(
920 &exe_ctx, i, transparent_pointers, omit_empty_base_classes,
921 ignore_array_bounds, name, size, child_offs, child_bitfield_bit_size,
922 child_bitfield_bit_offset, child_is_base_class,
923 child_is_deref_of_parent, valobj, language_flags);
929 } // anonymous namespace
932 ABISysV_ppc64::GetReturnValueObjectSimple(Thread &thread,
933 CompilerType &type) const {
935 return ValueObjectSP();
937 auto exp_extractor = ReturnValueExtractor::Create(thread, type);
938 if (!exp_extractor) {
939 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
940 LLDB_LOG_ERROR(log, exp_extractor.takeError(),
941 "Extracting return value failed: {0}");
942 return ValueObjectSP();
945 return exp_extractor.get().GetValue();
948 ValueObjectSP ABISysV_ppc64::GetReturnValueObjectImpl(
949 Thread &thread, CompilerType &return_compiler_type) const {
950 return GetReturnValueObjectSimple(thread, return_compiler_type);
953 bool ABISysV_ppc64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
955 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
961 if (GetByteOrder() == lldb::eByteOrderLittle) {
962 lr_reg_num = ppc64le_dwarf::dwarf_lr_ppc64le;
963 sp_reg_num = ppc64le_dwarf::dwarf_r1_ppc64le;
964 pc_reg_num = ppc64le_dwarf::dwarf_pc_ppc64le;
966 lr_reg_num = ppc64_dwarf::dwarf_lr_ppc64;
967 sp_reg_num = ppc64_dwarf::dwarf_r1_ppc64;
968 pc_reg_num = ppc64_dwarf::dwarf_pc_ppc64;
971 UnwindPlan::RowSP row(new UnwindPlan::Row);
973 // Our Call Frame Address is the stack pointer value
974 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
976 // The previous PC is in the LR
977 row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
978 unwind_plan.AppendRow(row);
980 // All other registers are the same.
982 unwind_plan.SetSourceName("ppc64 at-func-entry default");
983 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
988 bool ABISysV_ppc64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
990 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
996 if (GetByteOrder() == lldb::eByteOrderLittle) {
997 sp_reg_num = ppc64le_dwarf::dwarf_r1_ppc64le;
998 pc_reg_num = ppc64le_dwarf::dwarf_lr_ppc64le;
999 cr_reg_num = ppc64le_dwarf::dwarf_cr_ppc64le;
1001 sp_reg_num = ppc64_dwarf::dwarf_r1_ppc64;
1002 pc_reg_num = ppc64_dwarf::dwarf_lr_ppc64;
1003 cr_reg_num = ppc64_dwarf::dwarf_cr_ppc64;
1006 UnwindPlan::RowSP row(new UnwindPlan::Row);
1007 const int32_t ptr_size = 8;
1008 row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num);
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);
1014 unwind_plan.AppendRow(row);
1015 unwind_plan.SetSourceName("ppc64 default unwind plan");
1016 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1017 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1018 unwind_plan.SetReturnAddressRegister(pc_reg_num);
1022 bool ABISysV_ppc64::RegisterIsVolatile(const RegisterInfo *reg_info) {
1023 return !RegisterIsCalleeSaved(reg_info);
1026 // See "Register Usage" in the
1027 // "System V Application Binary Interface"
1028 // "64-bit PowerPC ELF Application Binary Interface Supplement" current version
1029 // is 2 released 2015 at
1030 // https://members.openpowerfoundation.org/document/dl/576
1031 bool ABISysV_ppc64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1033 // Preserved registers are :
1035 // cr2-cr4 (partially preserved)
1036 // f14-f31 (not yet)
1037 // v20-v31 (not yet)
1040 const char *name = reg_info->name;
1041 if (name[0] == 'r') {
1042 if ((name[1] == '1' || name[1] == '2') && name[2] == '\0')
1044 if (name[1] == '1' && name[2] > '2')
1046 if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')
1050 if (name[0] == 'f' && name[1] >= '0' && name[2] <= '9') {
1051 if (name[2] == '\0')
1053 if (name[1] == '1' && name[2] >= '4')
1055 if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')
1059 if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
1061 if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
1063 if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
1069 void ABISysV_ppc64::Initialize() {
1070 PluginManager::RegisterPlugin(
1071 GetPluginNameStatic(), "System V ABI for ppc64 targets", CreateInstance);
1074 void ABISysV_ppc64::Terminate() {
1075 PluginManager::UnregisterPlugin(CreateInstance);
1078 lldb_private::ConstString ABISysV_ppc64::GetPluginNameStatic() {
1079 static ConstString g_name("sysv-ppc64");
1083 //------------------------------------------------------------------
1084 // PluginInterface protocol
1085 //------------------------------------------------------------------
1087 lldb_private::ConstString ABISysV_ppc64::GetPluginName() {
1088 return GetPluginNameStatic();
1091 uint32_t ABISysV_ppc64::GetPluginVersion() { return 1; }