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