Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
39645 views
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-exception
6
//
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/Core/ValueObjectConstResult.h"
21
#include "lldb/Core/ValueObjectMemory.h"
22
#include "lldb/Core/ValueObjectRegister.h"
23
#include "lldb/Symbol/UnwindPlan.h"
24
#include "lldb/Target/Process.h"
25
#include "lldb/Target/RegisterContext.h"
26
#include "lldb/Target/StackFrame.h"
27
#include "lldb/Target/Target.h"
28
#include "lldb/Target/Thread.h"
29
#include "lldb/Utility/ConstString.h"
30
#include "lldb/Utility/DataExtractor.h"
31
#include "lldb/Utility/LLDBLog.h"
32
#include "lldb/Utility/Log.h"
33
#include "lldb/Utility/RegisterValue.h"
34
#include "lldb/Utility/Status.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_STRUCT
41
#include "Plugins/Process/Utility/RegisterInfos_ppc64.h"
42
#undef DECLARE_REGISTER_INFOS_PPC64_STRUCT
43
44
#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
45
#include "Plugins/Process/Utility/RegisterInfos_ppc64le.h"
46
#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
47
#include <optional>
48
49
using namespace lldb;
50
using namespace lldb_private;
51
52
LLDB_PLUGIN_DEFINE(ABISysV_ppc64)
53
54
const lldb_private::RegisterInfo *
55
ABISysV_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
65
size_t ABISysV_ppc64::GetRedZoneSize() const { return 224; }
66
67
lldb::ByteOrder ABISysV_ppc64::GetByteOrder() const {
68
return GetProcessSP()->GetByteOrder();
69
}
70
71
// Static Functions
72
73
ABISP
74
ABISysV_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
82
bool 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%" PRIx64
90
", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
91
", 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 arguments
109
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 SP
121
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 alignment
126
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%" PRIx64
144
"(+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
else
167
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
200
static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
201
bool is_signed, Thread &thread,
202
uint32_t *argument_register_ids,
203
unsigned int &current_argument_register,
204
addr_t &current_stack_argument) {
205
if (bit_width > 64)
206
return false; // Scalar can't hold large integer arguments
207
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
227
bool 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 registers
232
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 start
239
// when reading data
240
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
else
250
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_ctx
259
->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 we
273
// care about others?
274
CompilerType compiler_type = value->GetCompilerType();
275
std::optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
276
if (!bit_size)
277
return false;
278
bool is_signed;
279
280
if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
281
ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
282
argument_register_ids, current_argument_register,
283
current_stack_argument);
284
} else if (compiler_type.IsPointerType()) {
285
ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
286
argument_register_ids, current_argument_register,
287
current_stack_argument);
288
}
289
}
290
291
return true;
292
}
293
294
Status ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
295
lldb::ValueObjectSP &new_value_sp) {
296
Status error;
297
if (!new_value_sp) {
298
error.SetErrorString("Empty value object for return value.");
299
return error;
300
}
301
302
CompilerType compiler_type = new_value_sp->GetCompilerType();
303
if (!compiler_type) {
304
error.SetErrorString("Null clang type for return value.");
305
return error;
306
}
307
308
Thread *thread = frame_sp->GetThread().get();
309
310
bool is_signed;
311
uint32_t count;
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.SetErrorStringWithFormat(
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.SetErrorString("We don't support returning longer than 64 bit "
338
"integer values at present.");
339
}
340
} else if (compiler_type.IsFloatingPointType(count, is_complex)) {
341
if (is_complex)
342
error.SetErrorString(
343
"We don't support returning complex values at present");
344
else {
345
std::optional<uint64_t> bit_width =
346
compiler_type.GetBitSize(frame_sp.get());
347
if (!bit_width) {
348
error.SetErrorString("can't get size of type");
349
return error;
350
}
351
if (*bit_width <= 64) {
352
DataExtractor data;
353
Status data_error;
354
size_t num_bytes = new_value_sp->GetData(data, data_error);
355
if (data_error.Fail()) {
356
error.SetErrorStringWithFormat(
357
"Couldn't convert return value to raw data: %s",
358
data_error.AsCString());
359
return error;
360
}
361
362
unsigned char buffer[16];
363
ByteOrder byte_order = data.GetByteOrder();
364
365
data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
366
set_it_simple = true;
367
} else {
368
// FIXME - don't know how to do 80 bit long doubles yet.
369
error.SetErrorString(
370
"We don't support returning float values > 64 bits at present");
371
}
372
}
373
}
374
375
if (!set_it_simple) {
376
// Okay we've got a structure or something that doesn't fit in a simple
377
// register. We should figure out where it really goes, but we don't
378
// support this yet.
379
error.SetErrorString("We only support setting simple integer and float "
380
"return types at present.");
381
}
382
383
return error;
384
}
385
386
//
387
// ReturnValueExtractor
388
//
389
390
namespace {
391
392
#define LOG_PREFIX "ReturnValueExtractor: "
393
394
class ReturnValueExtractor {
395
// This class represents a register, from which data may be extracted.
396
//
397
// It may be constructed by directly specifying its index (where 0 is the
398
// first register used to return values) or by specifying the offset of a
399
// given struct field, in which case the appropriated register index will be
400
// calculated.
401
class Register {
402
public:
403
enum Type {
404
GPR, // General Purpose Register
405
FPR // Floating Point Register
406
};
407
408
// main constructor
409
//
410
// offs - field offset in struct
411
Register(Type ty, uint32_t index, uint32_t offs, RegisterContext *reg_ctx,
412
ByteOrder byte_order)
413
: m_index(index), m_offs(offs % sizeof(uint64_t)),
414
m_avail(sizeof(uint64_t) - m_offs), m_type(ty), m_reg_ctx(reg_ctx),
415
m_byte_order(byte_order) {}
416
417
// explicit index, no offset
418
Register(Type ty, uint32_t index, RegisterContext *reg_ctx,
419
ByteOrder byte_order)
420
: Register(ty, index, 0, reg_ctx, byte_order) {}
421
422
// GPR, calculate index from offs
423
Register(uint32_t offs, RegisterContext *reg_ctx, ByteOrder byte_order)
424
: Register(GPR, offs / sizeof(uint64_t), offs, reg_ctx, byte_order) {}
425
426
uint32_t Index() const { return m_index; }
427
428
// register offset where data is located
429
uint32_t Offs() const { return m_offs; }
430
431
// available bytes in this register
432
uint32_t Avail() const { return m_avail; }
433
434
bool IsValid() const {
435
if (m_index > 7) {
436
LLDB_LOG(m_log, LOG_PREFIX
437
"No more than 8 registers should be used to return values");
438
return false;
439
}
440
return true;
441
}
442
443
std::string GetName() const {
444
if (m_type == GPR)
445
return ("r" + llvm::Twine(m_index + 3)).str();
446
else
447
return ("f" + llvm::Twine(m_index + 1)).str();
448
}
449
450
// get raw register data
451
bool GetRawData(uint64_t &raw_data) {
452
const RegisterInfo *reg_info =
453
m_reg_ctx->GetRegisterInfoByName(GetName());
454
if (!reg_info) {
455
LLDB_LOG(m_log, LOG_PREFIX "Failed to get RegisterInfo");
456
return false;
457
}
458
459
RegisterValue reg_val;
460
if (!m_reg_ctx->ReadRegister(reg_info, reg_val)) {
461
LLDB_LOG(m_log, LOG_PREFIX "ReadRegister() failed");
462
return false;
463
}
464
465
Status error;
466
uint32_t rc = reg_val.GetAsMemoryData(
467
*reg_info, &raw_data, sizeof(raw_data), m_byte_order, error);
468
if (rc != sizeof(raw_data)) {
469
LLDB_LOG(m_log, LOG_PREFIX "GetAsMemoryData() failed");
470
return false;
471
}
472
473
return true;
474
}
475
476
private:
477
uint32_t m_index;
478
uint32_t m_offs;
479
uint32_t m_avail;
480
Type m_type;
481
RegisterContext *m_reg_ctx;
482
ByteOrder m_byte_order;
483
Log *m_log = GetLog(LLDBLog::Expressions);
484
};
485
486
Register GetGPR(uint32_t index) const {
487
return Register(Register::GPR, index, m_reg_ctx, m_byte_order);
488
}
489
490
Register GetFPR(uint32_t index) const {
491
return Register(Register::FPR, index, m_reg_ctx, m_byte_order);
492
}
493
494
Register GetGPRByOffs(uint32_t offs) const {
495
return Register(offs, m_reg_ctx, m_byte_order);
496
}
497
498
public:
499
// factory
500
static llvm::Expected<ReturnValueExtractor> Create(Thread &thread,
501
CompilerType &type) {
502
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
503
if (!reg_ctx)
504
return llvm::createStringError(LOG_PREFIX
505
"Failed to get RegisterContext");
506
507
ProcessSP process_sp = thread.GetProcess();
508
if (!process_sp)
509
return llvm::createStringError(LOG_PREFIX "GetProcess() failed");
510
511
return ReturnValueExtractor(thread, type, reg_ctx, process_sp);
512
}
513
514
// main method: get value of the type specified at construction time
515
ValueObjectSP GetValue() {
516
const uint32_t type_flags = m_type.GetTypeInfo();
517
518
// call the appropriate type handler
519
ValueSP value_sp;
520
ValueObjectSP valobj_sp;
521
if (type_flags & eTypeIsScalar) {
522
if (type_flags & eTypeIsInteger) {
523
value_sp = GetIntegerValue(0);
524
} else if (type_flags & eTypeIsFloat) {
525
if (type_flags & eTypeIsComplex) {
526
LLDB_LOG(m_log, LOG_PREFIX "Complex numbers are not supported yet");
527
return ValueObjectSP();
528
} else {
529
value_sp = GetFloatValue(m_type, 0);
530
}
531
}
532
} else if (type_flags & eTypeIsPointer) {
533
value_sp = GetPointerValue(0);
534
}
535
536
if (value_sp) {
537
valobj_sp = ValueObjectConstResult::Create(
538
m_thread.GetStackFrameAtIndex(0).get(), *value_sp, ConstString(""));
539
} else if (type_flags & eTypeIsVector) {
540
valobj_sp = GetVectorValueObject();
541
} else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) {
542
valobj_sp = GetStructValueObject();
543
}
544
545
return valobj_sp;
546
}
547
548
private:
549
// data
550
Thread &m_thread;
551
CompilerType &m_type;
552
uint64_t m_byte_size;
553
std::unique_ptr<DataBufferHeap> m_data_up;
554
int32_t m_src_offs = 0;
555
int32_t m_dst_offs = 0;
556
bool m_packed = false;
557
Log *m_log = GetLog(LLDBLog::Expressions);
558
RegisterContext *m_reg_ctx;
559
ProcessSP m_process_sp;
560
ByteOrder m_byte_order;
561
uint32_t m_addr_size;
562
563
// methods
564
565
// constructor
566
ReturnValueExtractor(Thread &thread, CompilerType &type,
567
RegisterContext *reg_ctx, ProcessSP process_sp)
568
: m_thread(thread), m_type(type),
569
m_byte_size(m_type.GetByteSize(&thread).value_or(0)),
570
m_data_up(new DataBufferHeap(m_byte_size, 0)), m_reg_ctx(reg_ctx),
571
m_process_sp(process_sp), m_byte_order(process_sp->GetByteOrder()),
572
m_addr_size(
573
process_sp->GetTarget().GetArchitecture().GetAddressByteSize()) {}
574
575
// build a new scalar value
576
ValueSP NewScalarValue(CompilerType &type) {
577
ValueSP value_sp(new Value);
578
value_sp->SetCompilerType(type);
579
value_sp->SetValueType(Value::ValueType::Scalar);
580
return value_sp;
581
}
582
583
// get an integer value in the specified register
584
ValueSP GetIntegerValue(uint32_t reg_index) {
585
uint64_t raw_value;
586
auto reg = GetGPR(reg_index);
587
if (!reg.GetRawData(raw_value))
588
return ValueSP();
589
590
// build value from data
591
ValueSP value_sp(NewScalarValue(m_type));
592
593
uint32_t type_flags = m_type.GetTypeInfo();
594
bool is_signed = (type_flags & eTypeIsSigned) != 0;
595
596
switch (m_byte_size) {
597
case sizeof(uint64_t):
598
if (is_signed)
599
value_sp->GetScalar() = (int64_t)(raw_value);
600
else
601
value_sp->GetScalar() = (uint64_t)(raw_value);
602
break;
603
604
case sizeof(uint32_t):
605
if (is_signed)
606
value_sp->GetScalar() = (int32_t)(raw_value & UINT32_MAX);
607
else
608
value_sp->GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
609
break;
610
611
case sizeof(uint16_t):
612
if (is_signed)
613
value_sp->GetScalar() = (int16_t)(raw_value & UINT16_MAX);
614
else
615
value_sp->GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
616
break;
617
618
case sizeof(uint8_t):
619
if (is_signed)
620
value_sp->GetScalar() = (int8_t)(raw_value & UINT8_MAX);
621
else
622
value_sp->GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
623
break;
624
625
default:
626
llvm_unreachable("Invalid integer size");
627
}
628
629
return value_sp;
630
}
631
632
// get a floating point value on the specified register
633
ValueSP GetFloatValue(CompilerType &type, uint32_t reg_index) {
634
uint64_t raw_data;
635
auto reg = GetFPR(reg_index);
636
if (!reg.GetRawData(raw_data))
637
return {};
638
639
// build value from data
640
ValueSP value_sp(NewScalarValue(type));
641
642
DataExtractor de(&raw_data, sizeof(raw_data), m_byte_order, m_addr_size);
643
644
offset_t offset = 0;
645
std::optional<uint64_t> byte_size = type.GetByteSize(m_process_sp.get());
646
if (!byte_size)
647
return {};
648
switch (*byte_size) {
649
case sizeof(float):
650
value_sp->GetScalar() = (float)de.GetDouble(&offset);
651
break;
652
653
case sizeof(double):
654
value_sp->GetScalar() = de.GetDouble(&offset);
655
break;
656
657
default:
658
llvm_unreachable("Invalid floating point size");
659
}
660
661
return value_sp;
662
}
663
664
// get pointer value from register
665
ValueSP GetPointerValue(uint32_t reg_index) {
666
uint64_t raw_data;
667
auto reg = GetGPR(reg_index);
668
if (!reg.GetRawData(raw_data))
669
return ValueSP();
670
671
// build value from raw data
672
ValueSP value_sp(NewScalarValue(m_type));
673
value_sp->GetScalar() = raw_data;
674
return value_sp;
675
}
676
677
// build the ValueObject from our data buffer
678
ValueObjectSP BuildValueObject() {
679
DataExtractor de(DataBufferSP(m_data_up.release()), m_byte_order,
680
m_addr_size);
681
return ValueObjectConstResult::Create(&m_thread, m_type, ConstString(""),
682
de);
683
}
684
685
// get a vector return value
686
ValueObjectSP GetVectorValueObject() {
687
const uint32_t MAX_VRS = 2;
688
689
// get first V register used to return values
690
const RegisterInfo *vr[MAX_VRS];
691
vr[0] = m_reg_ctx->GetRegisterInfoByName("vr2");
692
if (!vr[0]) {
693
LLDB_LOG(m_log, LOG_PREFIX "Failed to get vr2 RegisterInfo");
694
return ValueObjectSP();
695
}
696
697
const uint32_t vr_size = vr[0]->byte_size;
698
size_t vrs = 1;
699
if (m_byte_size > 2 * vr_size) {
700
LLDB_LOG(
701
m_log, LOG_PREFIX
702
"Returning vectors that don't fit in 2 VR regs is not supported");
703
return ValueObjectSP();
704
}
705
706
// load vr3, if needed
707
if (m_byte_size > vr_size) {
708
vrs++;
709
vr[1] = m_reg_ctx->GetRegisterInfoByName("vr3");
710
if (!vr[1]) {
711
LLDB_LOG(m_log, LOG_PREFIX "Failed to get vr3 RegisterInfo");
712
return ValueObjectSP();
713
}
714
}
715
716
// Get the whole contents of vector registers and let the logic here
717
// arrange the data properly.
718
719
RegisterValue vr_val[MAX_VRS];
720
Status error;
721
std::unique_ptr<DataBufferHeap> vr_data(
722
new DataBufferHeap(vrs * vr_size, 0));
723
724
for (uint32_t i = 0; i < vrs; i++) {
725
if (!m_reg_ctx->ReadRegister(vr[i], vr_val[i])) {
726
LLDB_LOG(m_log, LOG_PREFIX "Failed to read vector register contents");
727
return ValueObjectSP();
728
}
729
if (!vr_val[i].GetAsMemoryData(*vr[i], vr_data->GetBytes() + i * vr_size,
730
vr_size, m_byte_order, error)) {
731
LLDB_LOG(m_log, LOG_PREFIX "Failed to extract vector register bytes");
732
return ValueObjectSP();
733
}
734
}
735
736
// The compiler generated code seems to always put the vector elements at
737
// the end of the vector register, in case they don't occupy all of it.
738
// This offset variable handles this.
739
uint32_t offs = 0;
740
if (m_byte_size < vr_size)
741
offs = vr_size - m_byte_size;
742
743
// copy extracted data to our buffer
744
memcpy(m_data_up->GetBytes(), vr_data->GetBytes() + offs, m_byte_size);
745
return BuildValueObject();
746
}
747
748
// get a struct return value
749
ValueObjectSP GetStructValueObject() {
750
// case 1: get from stack
751
if (m_byte_size > 2 * sizeof(uint64_t)) {
752
uint64_t addr;
753
auto reg = GetGPR(0);
754
if (!reg.GetRawData(addr))
755
return {};
756
757
Status error;
758
size_t rc = m_process_sp->ReadMemory(addr, m_data_up->GetBytes(),
759
m_byte_size, error);
760
if (rc != m_byte_size) {
761
LLDB_LOG(m_log, LOG_PREFIX "Failed to read memory pointed by r3");
762
return ValueObjectSP();
763
}
764
return BuildValueObject();
765
}
766
767
// get number of children
768
const bool omit_empty_base_classes = true;
769
auto n_or_err = m_type.GetNumChildren(omit_empty_base_classes, nullptr);
770
if (!n_or_err) {
771
LLDB_LOG_ERROR(m_log, n_or_err.takeError(), LOG_PREFIX "{0}");
772
return {};
773
}
774
uint32_t n = *n_or_err;
775
if (!n) {
776
LLDB_LOG(m_log, LOG_PREFIX "No children found in struct");
777
return {};
778
}
779
780
// case 2: homogeneous double or float aggregate
781
CompilerType elem_type;
782
if (m_type.IsHomogeneousAggregate(&elem_type)) {
783
uint32_t type_flags = elem_type.GetTypeInfo();
784
std::optional<uint64_t> elem_size =
785
elem_type.GetByteSize(m_process_sp.get());
786
if (!elem_size)
787
return {};
788
if (type_flags & eTypeIsComplex || !(type_flags & eTypeIsFloat)) {
789
LLDB_LOG(m_log,
790
LOG_PREFIX "Unexpected type found in homogeneous aggregate");
791
return {};
792
}
793
794
for (uint32_t i = 0; i < n; i++) {
795
ValueSP val_sp = GetFloatValue(elem_type, i);
796
if (!val_sp)
797
return {};
798
799
// copy to buffer
800
Status error;
801
size_t rc = val_sp->GetScalar().GetAsMemoryData(
802
m_data_up->GetBytes() + m_dst_offs, *elem_size, m_byte_order,
803
error);
804
if (rc != *elem_size) {
805
LLDB_LOG(m_log, LOG_PREFIX "Failed to get float data");
806
return {};
807
}
808
m_dst_offs += *elem_size;
809
}
810
return BuildValueObject();
811
}
812
813
// case 3: get from GPRs
814
815
// first, check if this is a packed struct or not
816
auto ast = m_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
817
if (ast) {
818
clang::RecordDecl *record_decl = TypeSystemClang::GetAsRecordDecl(m_type);
819
820
if (record_decl) {
821
auto attrs = record_decl->attrs();
822
for (const auto &attr : attrs) {
823
if (attr->getKind() == clang::attr::Packed) {
824
m_packed = true;
825
break;
826
}
827
}
828
}
829
}
830
831
LLDB_LOG(m_log, LOG_PREFIX "{0} struct",
832
m_packed ? "packed" : "not packed");
833
834
for (uint32_t i = 0; i < n; i++) {
835
std::string name;
836
uint32_t size;
837
(void)GetChildType(i, name, size);
838
// NOTE: the offset returned by GetChildCompilerTypeAtIndex()
839
// can't be used because it never considers alignment bytes
840
// between struct fields.
841
LLDB_LOG(m_log, LOG_PREFIX "field={0}, size={1}", name, size);
842
if (!ExtractField(size))
843
return ValueObjectSP();
844
}
845
846
return BuildValueObject();
847
}
848
849
// extract 'size' bytes at 'offs' from GPRs
850
bool ExtractFromRegs(int32_t offs, uint32_t size, void *buf) {
851
while (size) {
852
auto reg = GetGPRByOffs(offs);
853
if (!reg.IsValid())
854
return false;
855
856
uint32_t n = std::min(reg.Avail(), size);
857
uint64_t raw_data;
858
859
if (!reg.GetRawData(raw_data))
860
return false;
861
862
memcpy(buf, (char *)&raw_data + reg.Offs(), n);
863
offs += n;
864
size -= n;
865
buf = (char *)buf + n;
866
}
867
return true;
868
}
869
870
// extract one field from GPRs and put it in our buffer
871
bool ExtractField(uint32_t size) {
872
auto reg = GetGPRByOffs(m_src_offs);
873
if (!reg.IsValid())
874
return false;
875
876
// handle padding
877
if (!m_packed) {
878
uint32_t n = m_src_offs % size;
879
880
// not 'size' bytes aligned
881
if (n) {
882
LLDB_LOG(m_log,
883
LOG_PREFIX "Extracting {0} alignment bytes at offset {1}", n,
884
m_src_offs);
885
// get alignment bytes
886
if (!ExtractFromRegs(m_src_offs, n, m_data_up->GetBytes() + m_dst_offs))
887
return false;
888
m_src_offs += n;
889
m_dst_offs += n;
890
}
891
}
892
893
// get field
894
LLDB_LOG(m_log, LOG_PREFIX "Extracting {0} field bytes at offset {1}", size,
895
m_src_offs);
896
if (!ExtractFromRegs(m_src_offs, size, m_data_up->GetBytes() + m_dst_offs))
897
return false;
898
m_src_offs += size;
899
m_dst_offs += size;
900
return true;
901
}
902
903
// get child
904
llvm::Expected<CompilerType> GetChildType(uint32_t i, std::string &name,
905
uint32_t &size) {
906
// GetChild constant inputs
907
const bool transparent_pointers = false;
908
const bool omit_empty_base_classes = true;
909
const bool ignore_array_bounds = false;
910
// GetChild output params
911
int32_t child_offs;
912
uint32_t child_bitfield_bit_size;
913
uint32_t child_bitfield_bit_offset;
914
bool child_is_base_class;
915
bool child_is_deref_of_parent;
916
ValueObject *valobj = nullptr;
917
uint64_t language_flags;
918
ExecutionContext exe_ctx;
919
m_thread.CalculateExecutionContext(exe_ctx);
920
921
return m_type.GetChildCompilerTypeAtIndex(
922
&exe_ctx, i, transparent_pointers, omit_empty_base_classes,
923
ignore_array_bounds, name, size, child_offs, child_bitfield_bit_size,
924
child_bitfield_bit_offset, child_is_base_class,
925
child_is_deref_of_parent, valobj, language_flags);
926
}
927
};
928
929
#undef LOG_PREFIX
930
931
} // anonymous namespace
932
933
ValueObjectSP
934
ABISysV_ppc64::GetReturnValueObjectSimple(Thread &thread,
935
CompilerType &type) const {
936
if (!type)
937
return ValueObjectSP();
938
939
auto exp_extractor = ReturnValueExtractor::Create(thread, type);
940
if (!exp_extractor) {
941
Log *log = GetLog(LLDBLog::Expressions);
942
LLDB_LOG_ERROR(log, exp_extractor.takeError(),
943
"Extracting return value failed: {0}");
944
return ValueObjectSP();
945
}
946
947
return exp_extractor.get().GetValue();
948
}
949
950
ValueObjectSP ABISysV_ppc64::GetReturnValueObjectImpl(
951
Thread &thread, CompilerType &return_compiler_type) const {
952
return GetReturnValueObjectSimple(thread, return_compiler_type);
953
}
954
955
bool ABISysV_ppc64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
956
unwind_plan.Clear();
957
unwind_plan.SetRegisterKind(eRegisterKindDWARF);
958
959
uint32_t lr_reg_num;
960
uint32_t sp_reg_num;
961
uint32_t pc_reg_num;
962
963
if (GetByteOrder() == lldb::eByteOrderLittle) {
964
lr_reg_num = ppc64le_dwarf::dwarf_lr_ppc64le;
965
sp_reg_num = ppc64le_dwarf::dwarf_r1_ppc64le;
966
pc_reg_num = ppc64le_dwarf::dwarf_pc_ppc64le;
967
} else {
968
lr_reg_num = ppc64_dwarf::dwarf_lr_ppc64;
969
sp_reg_num = ppc64_dwarf::dwarf_r1_ppc64;
970
pc_reg_num = ppc64_dwarf::dwarf_pc_ppc64;
971
}
972
973
UnwindPlan::RowSP row(new UnwindPlan::Row);
974
975
// Our Call Frame Address is the stack pointer value
976
row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
977
978
// The previous PC is in the LR
979
row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
980
unwind_plan.AppendRow(row);
981
982
// All other registers are the same.
983
984
unwind_plan.SetSourceName("ppc64 at-func-entry default");
985
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
986
987
return true;
988
}
989
990
bool ABISysV_ppc64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
991
unwind_plan.Clear();
992
unwind_plan.SetRegisterKind(eRegisterKindDWARF);
993
994
uint32_t sp_reg_num;
995
uint32_t pc_reg_num;
996
uint32_t cr_reg_num;
997
998
if (GetByteOrder() == lldb::eByteOrderLittle) {
999
sp_reg_num = ppc64le_dwarf::dwarf_r1_ppc64le;
1000
pc_reg_num = ppc64le_dwarf::dwarf_lr_ppc64le;
1001
cr_reg_num = ppc64le_dwarf::dwarf_cr_ppc64le;
1002
} else {
1003
sp_reg_num = ppc64_dwarf::dwarf_r1_ppc64;
1004
pc_reg_num = ppc64_dwarf::dwarf_lr_ppc64;
1005
cr_reg_num = ppc64_dwarf::dwarf_cr_ppc64;
1006
}
1007
1008
UnwindPlan::RowSP row(new UnwindPlan::Row);
1009
const int32_t ptr_size = 8;
1010
row->SetUnspecifiedRegistersAreUndefined(true);
1011
row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num);
1012
1013
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 2, true);
1014
row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1015
row->SetRegisterLocationToAtCFAPlusOffset(cr_reg_num, ptr_size, true);
1016
1017
unwind_plan.AppendRow(row);
1018
unwind_plan.SetSourceName("ppc64 default unwind plan");
1019
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1020
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1021
unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1022
unwind_plan.SetReturnAddressRegister(pc_reg_num);
1023
return true;
1024
}
1025
1026
bool ABISysV_ppc64::RegisterIsVolatile(const RegisterInfo *reg_info) {
1027
return !RegisterIsCalleeSaved(reg_info);
1028
}
1029
1030
// See "Register Usage" in the
1031
// "System V Application Binary Interface"
1032
// "64-bit PowerPC ELF Application Binary Interface Supplement" current version
1033
// is 2 released 2015 at
1034
// https://members.openpowerfoundation.org/document/dl/576
1035
bool ABISysV_ppc64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1036
if (reg_info) {
1037
// Preserved registers are :
1038
// r1,r2,r13-r31
1039
// cr2-cr4 (partially preserved)
1040
// f14-f31 (not yet)
1041
// v20-v31 (not yet)
1042
// vrsave (not yet)
1043
1044
const char *name = reg_info->name;
1045
if (name[0] == 'r') {
1046
if ((name[1] == '1' || name[1] == '2') && name[2] == '\0')
1047
return true;
1048
if (name[1] == '1' && name[2] > '2')
1049
return true;
1050
if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')
1051
return true;
1052
}
1053
1054
if (name[0] == 'f' && name[1] >= '0' && name[2] <= '9') {
1055
if (name[2] == '\0')
1056
return false;
1057
if (name[1] == '1' && name[2] >= '4')
1058
return true;
1059
if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')
1060
return true;
1061
}
1062
1063
if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
1064
return true;
1065
if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
1066
return false;
1067
if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
1068
return true;
1069
}
1070
return false;
1071
}
1072
1073
void ABISysV_ppc64::Initialize() {
1074
PluginManager::RegisterPlugin(
1075
GetPluginNameStatic(), "System V ABI for ppc64 targets", CreateInstance);
1076
}
1077
1078
void ABISysV_ppc64::Terminate() {
1079
PluginManager::UnregisterPlugin(CreateInstance);
1080
}
1081
1082