LLDB mainline
ABISysV_loongarch.cpp
Go to the documentation of this file.
1//===-- ABISysV_loongarch.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_loongarch.h"
10
11#include <array>
12#include <limits>
13#include <sstream>
14
15#include "llvm/ADT/StringRef.h"
16#include "llvm/IR/DerivedTypes.h"
17#include "llvm/Support/MathExtras.h"
18
21#include "lldb/Core/Value.h"
24#include "lldb/Target/Thread.h"
28
29#define DEFINE_REG_NAME(reg_num) ConstString(#reg_num).GetCString()
30#define DEFINE_REG_NAME_STR(reg_name) ConstString(reg_name).GetCString()
31
32// The ABI is not a source of such information as size, offset, encoding, etc.
33// of a register. Just provides correct dwarf and eh_frame numbers.
34
35#define DEFINE_GENERIC_REGISTER_STUB(dwarf_num, generic_num) \
36 { \
37 DEFINE_REG_NAME(dwarf_num), \
38 DEFINE_REG_NAME_STR(nullptr), \
39 0, \
40 0, \
41 eEncodingInvalid, \
42 eFormatDefault, \
43 {dwarf_num, dwarf_num, generic_num, LLDB_INVALID_REGNUM, dwarf_num}, \
44 nullptr, \
45 nullptr, \
46 nullptr, \
47 }
48
49#define DEFINE_REGISTER_STUB(dwarf_num) \
50 DEFINE_GENERIC_REGISTER_STUB(dwarf_num, LLDB_INVALID_REGNUM)
51
52using namespace lldb;
53using namespace lldb_private;
54
56
57namespace {
58namespace dwarf {
59enum regnums {
60 r0,
61 r1,
62 ra = r1,
63 r2,
64 r3,
65 sp = r3,
66 r4,
67 r5,
68 r6,
69 r7,
70 r8,
71 r9,
72 r10,
73 r11,
74 r12,
75 r13,
76 r14,
77 r15,
78 r16,
79 r17,
80 r18,
81 r19,
82 r20,
83 r21,
84 r22,
85 fp = r22,
86 r23,
87 r24,
88 r25,
89 r26,
90 r27,
91 r28,
92 r29,
93 r30,
94 r31,
95 pc
96};
97
98static const std::array<RegisterInfo, 33> g_register_infos = {
132} // namespace dwarf
133} // namespace
134
135// Number of argument registers (the base integer calling convention
136// provides 8 argument registers, a0-a7)
137static constexpr size_t g_regs_for_args_count = 8U;
138
140 count = dwarf::g_register_infos.size();
141 return dwarf::g_register_infos.data();
142}
143
144//------------------------------------------------------------------
145// Static Functions
146//------------------------------------------------------------------
147
148ABISP
150 llvm::Triple::ArchType machine = arch.GetTriple().getArch();
151
152 if (llvm::Triple::loongarch32 != machine &&
153 llvm::Triple::loongarch64 != machine)
154 return ABISP();
155
156 ABISysV_loongarch *abi =
157 new ABISysV_loongarch(std::move(process_sp), MakeMCRegisterInfo(arch));
158 if (abi)
159 abi->SetIsLA64(llvm::Triple::loongarch64 == machine);
160 return ABISP(abi);
161}
162
163static bool UpdateRegister(RegisterContext *reg_ctx,
164 const lldb::RegisterKind reg_kind,
165 const uint32_t reg_num, const addr_t value) {
167
168 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(reg_kind, reg_num);
169
170 LLDB_LOG(log, "Writing {0}: 0x{1:x}", reg_info->name,
171 static_cast<uint64_t>(value));
172 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, value)) {
173 LLDB_LOG(log, "Writing {0}: failed", reg_info->name);
174 return false;
175 }
176 return true;
177}
178
179static void LogInitInfo(Log &log, const Thread &thread, addr_t sp,
180 addr_t func_addr, addr_t return_addr,
181 const llvm::ArrayRef<addr_t> args) {
182 std::stringstream ss;
183 ss << "ABISysV_loongarch::PrepareTrivialCall"
184 << " (tid = 0x" << std::hex << thread.GetID() << ", sp = 0x" << sp
185 << ", func_addr = 0x" << func_addr << ", return_addr = 0x" << return_addr;
186
187 for (auto [idx, arg] : enumerate(args))
188 ss << ", arg" << std::dec << idx << " = 0x" << std::hex << arg;
189 ss << ")";
190 log.PutString(ss.str());
191}
192
194 addr_t func_addr, addr_t return_addr,
195 llvm::ArrayRef<addr_t> args) const {
197 if (log)
198 LogInitInfo(*log, thread, sp, func_addr, return_addr, args);
199
200 const auto reg_ctx_sp = thread.GetRegisterContext();
201 if (!reg_ctx_sp) {
202 LLDB_LOG(log, "Failed to get RegisterContext");
203 return false;
204 }
205
206 if (args.size() > g_regs_for_args_count) {
207 LLDB_LOG(log, "Function has {0} arguments, but only {1} are allowed!",
208 args.size(), g_regs_for_args_count);
209 return false;
210 }
211
212 // Write arguments to registers
213 for (auto [idx, arg] : enumerate(args)) {
214 const RegisterInfo *reg_info = reg_ctx_sp->GetRegisterInfo(
216 LLDB_LOG(log, "About to write arg{0} ({1:x}) into {2}", idx, arg,
217 reg_info->name);
218
219 if (!reg_ctx_sp->WriteRegisterFromUnsigned(reg_info, arg)) {
220 LLDB_LOG(log, "Failed to write arg{0} ({1:x}) into {2}", idx, arg,
221 reg_info->name);
222 return false;
223 }
224 }
225
226 if (!UpdateRegister(reg_ctx_sp.get(), eRegisterKindGeneric,
227 LLDB_REGNUM_GENERIC_PC, func_addr))
228 return false;
229 if (!UpdateRegister(reg_ctx_sp.get(), eRegisterKindGeneric,
231 return false;
232 if (!UpdateRegister(reg_ctx_sp.get(), eRegisterKindGeneric,
233 LLDB_REGNUM_GENERIC_RA, return_addr))
234 return false;
235
236 LLDB_LOG(log, "ABISysV_loongarch::{0}() success", __FUNCTION__);
237 return true;
238}
239
241 ValueList &values) const {
242 // TODO: Implement
243 return false;
244}
245
247 ValueObjectSP &new_value_sp) {
248 Status result;
249 if (!new_value_sp) {
250 result = Status::FromErrorString("Empty value object for return value.");
251 return result;
252 }
253
254 CompilerType compiler_type = new_value_sp->GetCompilerType();
255 if (!compiler_type) {
256 result = Status::FromErrorString("Null clang type for return value.");
257 return result;
258 }
259
260 auto &reg_ctx = *frame_sp->GetThread()->GetRegisterContext();
261
262 bool is_signed = false;
263 if (!compiler_type.IsIntegerOrEnumerationType(is_signed) &&
264 !compiler_type.IsPointerType()) {
266 "We don't support returning other types at present");
267 return result;
268 }
269
270 DataExtractor data;
271 size_t num_bytes = new_value_sp->GetData(data, result);
272
273 if (result.Fail()) {
275 "Couldn't convert return value to raw data: %s", result.AsCString());
276 return result;
277 }
278
279 size_t reg_size = m_is_la64 ? 8 : 4;
280 // Currently, we only support sizeof(data) <= 2 * reg_size.
281 // 1. If the (`size` <= reg_size), the `data` will be returned through `ARG1`.
282 // 2. If the (`size` > reg_size && `size` <= 2 * reg_size), the `data` will be
283 // returned through a pair of registers (ARG1 and ARG2), and the lower-ordered
284 // bits in the `ARG1`.
285 if (num_bytes > 2 * reg_size) {
287 "We don't support returning large integer values at present.");
288 return result;
289 }
290
291 offset_t offset = 0;
292 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
293 // According to psABI, i32 (no matter signed or unsigned) should be
294 // sign-extended in register.
295 if (4 == num_bytes && m_is_la64)
296 raw_value = llvm::SignExtend64<32>(raw_value);
297 auto reg_info =
298 reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
299 if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) {
301 "Couldn't write value to register %s", reg_info->name);
302 return result;
303 }
304
305 if (num_bytes <= reg_size)
306 return result; // Successfully written.
307
308 // For loongarch32, get the upper 32 bits from raw_value and write them.
309 // For loongarch64, get the next 64 bits from data and write them.
310 if (4 == reg_size)
311 raw_value >>= 32;
312 else
313 raw_value = data.GetMaxU64(&offset, num_bytes - reg_size);
314
315 reg_info =
316 reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
317 if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value))
319 "Couldn't write value to register %s", reg_info->name);
320
321 return result;
322}
323
324template <typename T>
325static void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed) {
326 static_assert(std::is_unsigned<T>::value, "T must be an unsigned type.");
327 raw_value &= std::numeric_limits<T>::max();
328 if (is_signed)
329 scalar = static_cast<typename std::make_signed<T>::type>(raw_value);
330 else
331 scalar = static_cast<T>(raw_value);
332}
333
334static bool SetSizedInteger(Scalar &scalar, uint64_t raw_value,
335 uint8_t size_in_bytes, bool is_signed) {
336 switch (size_in_bytes) {
337 default:
338 return false;
339
340 case sizeof(uint64_t):
341 SetInteger<uint64_t>(scalar, raw_value, is_signed);
342 break;
343
344 case sizeof(uint32_t):
345 SetInteger<uint32_t>(scalar, raw_value, is_signed);
346 break;
347
348 case sizeof(uint16_t):
349 SetInteger<uint16_t>(scalar, raw_value, is_signed);
350 break;
351
352 case sizeof(uint8_t):
353 SetInteger<uint8_t>(scalar, raw_value, is_signed);
354 break;
355 }
356
357 return true;
358}
359
360static bool SetSizedFloat(Scalar &scalar, uint64_t raw_value,
361 uint8_t size_in_bytes) {
362 switch (size_in_bytes) {
363 default:
364 return false;
365
366 case sizeof(uint64_t):
367 scalar = *reinterpret_cast<double *>(&raw_value);
368 break;
369
370 case sizeof(uint32_t):
371 scalar = *reinterpret_cast<float *>(&raw_value);
372 break;
373 }
374
375 return true;
376}
377
379 const RegisterContextSP &reg_ctx,
380 llvm::Triple::ArchType machine,
381 uint32_t type_flags,
382 uint32_t byte_size) {
383 Value value;
384 ValueObjectSP return_valobj_sp;
385 auto *reg_info_a0 =
386 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
387 auto *reg_info_a1 =
388 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
389 uint64_t raw_value = 0;
390
391 switch (byte_size) {
392 case sizeof(uint32_t):
393 // Read a0 to get the arg
394 raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0) & UINT32_MAX;
395 break;
396 case sizeof(uint64_t):
397 // Read a0 to get the arg on loongarch64, a0 and a1 on loongarch32
398 if (llvm::Triple::loongarch32 == machine) {
399 raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0) & UINT32_MAX;
400 raw_value |=
401 (reg_ctx->ReadRegisterAsUnsigned(reg_info_a1, 0) & UINT32_MAX) << 32U;
402 } else {
403 raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0);
404 }
405 break;
406 case 16: {
407 // Read a0 and a1 to get the arg on loongarch64, not supported on
408 // loongarch32
409 if (llvm::Triple::loongarch32 == machine)
410 return return_valobj_sp;
411
412 // Create the ValueObjectSP here and return
413 std::unique_ptr<DataBufferHeap> heap_data_up(
414 new DataBufferHeap(byte_size, 0));
415 const ByteOrder byte_order = thread.GetProcess()->GetByteOrder();
416 RegisterValue reg_value_a0, reg_value_a1;
417 if (reg_ctx->ReadRegister(reg_info_a0, reg_value_a0) &&
418 reg_ctx->ReadRegister(reg_info_a1, reg_value_a1)) {
420 if (reg_value_a0.GetAsMemoryData(*reg_info_a0,
421 heap_data_up->GetBytes() + 0, 8,
422 byte_order, error) &&
423 reg_value_a1.GetAsMemoryData(*reg_info_a1,
424 heap_data_up->GetBytes() + 8, 8,
425 byte_order, error)) {
426 value.SetBytes(heap_data_up.release(), byte_size);
428 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
429 }
430 }
431 break;
432 }
433 default:
434 return return_valobj_sp;
435 }
436
437 if (type_flags & eTypeIsInteger) {
438 if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size,
439 type_flags & eTypeIsSigned))
440 return return_valobj_sp;
441 } else if (type_flags & eTypeIsFloat) {
442 if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size))
443 return return_valobj_sp;
444 } else
445 return return_valobj_sp;
446
448 return_valobj_sp = ValueObjectConstResult::Create(
449 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
450 return return_valobj_sp;
451}
452
454 const RegisterContextSP &reg_ctx,
455 llvm::Triple::ArchType machine,
456 uint32_t type_flags,
457 uint32_t byte_size) {
458 auto *reg_info_fa0 = reg_ctx->GetRegisterInfoByName("f0");
459 bool use_fp_regs = false;
460 ValueObjectSP return_valobj_sp;
461
462 if (byte_size <= 8)
463 use_fp_regs = true;
464
465 if (use_fp_regs) {
466 uint64_t raw_value;
467 Value value;
468 raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info_fa0, 0);
469 if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size))
470 return return_valobj_sp;
472 return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
473 value, ConstString(""));
474 }
475 // we should never reach this, but if we do, use the integer registers
476 return GetValObjFromIntRegs(thread, reg_ctx, machine, type_flags, byte_size);
477}
478
480 Thread &thread, CompilerType &compiler_type) const {
481 ValueObjectSP return_valobj_sp;
482
483 if (!compiler_type)
484 return return_valobj_sp;
485
486 auto reg_ctx = thread.GetRegisterContext();
487 if (!reg_ctx)
488 return return_valobj_sp;
489
490 Value value;
491 value.SetCompilerType(compiler_type);
492
493 const uint32_t type_flags = compiler_type.GetTypeInfo();
494 const size_t byte_size =
495 llvm::expectedToOptional(compiler_type.GetByteSize(&thread)).value_or(0);
496 const ArchSpec arch = thread.GetProcess()->GetTarget().GetArchitecture();
497 const llvm::Triple::ArchType machine = arch.GetMachine();
498
499 if (type_flags & eTypeIsInteger) {
500 return_valobj_sp =
501 GetValObjFromIntRegs(thread, reg_ctx, machine, type_flags, byte_size);
502 return return_valobj_sp;
503 }
504 if (type_flags & eTypeIsPointer) {
505 const auto *reg_info_a0 = reg_ctx->GetRegisterInfo(
507 value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_a0, 0);
509 return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
510 value, ConstString(""));
511 }
512 if (type_flags & eTypeIsFloat) {
513 uint32_t float_count = 0;
514 bool is_complex = false;
515
516 if (compiler_type.IsFloatingPointType(float_count, is_complex) &&
517 float_count == 1 && !is_complex) {
518 return_valobj_sp =
519 GetValObjFromFPRegs(thread, reg_ctx, machine, type_flags, byte_size);
520 return return_valobj_sp;
521 }
522 }
523 return return_valobj_sp;
524}
525
527 Thread &thread, CompilerType &return_compiler_type) const {
528 ValueObjectSP return_valobj_sp;
529
530 if (!return_compiler_type)
531 return return_valobj_sp;
532
533 ExecutionContext exe_ctx(thread.shared_from_this());
534 return GetReturnValueObjectSimple(thread, return_compiler_type);
535}
536
538 uint32_t pc_reg_num = loongarch_dwarf::dwarf_gpr_pc;
539 uint32_t sp_reg_num = loongarch_dwarf::dwarf_gpr_sp;
540 uint32_t ra_reg_num = loongarch_dwarf::dwarf_gpr_ra;
541
542 UnwindPlan::Row row;
543
544 // Define CFA as the stack pointer
545 row.GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
546
547 // Previous frame's pc is in ra
548 row.SetRegisterLocationToRegister(pc_reg_num, ra_reg_num, true);
549
550 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
551 plan_sp->AppendRow(std::move(row));
552 plan_sp->SetSourceName("loongarch function-entry unwind plan");
553 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
554 return plan_sp;
555}
556
558 uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
559 uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
560
561 UnwindPlan::Row row;
562
563 // Define the CFA as the current frame pointer value.
564 row.GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 0);
565
566 int reg_size = 4;
567 if (m_is_la64)
568 reg_size = 8;
569
570 // Assume the ra reg (return pc) and caller's frame pointer
571 // have been spilled to stack already.
572 row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, reg_size * -2, true);
573 row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, reg_size * -1, true);
574
575 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindGeneric);
576 plan_sp->AppendRow(std::move(row));
577 plan_sp->SetSourceName("loongarch default unwind plan");
578 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
579 plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
580 return plan_sp;
581}
582
584 return !RegisterIsCalleeSaved(reg_info);
585}
586
588 if (!reg_info)
589 return false;
590
591 const char *name = reg_info->name;
592 ArchSpec arch = GetProcessSP()->GetTarget().GetArchitecture();
593 uint32_t arch_flags = arch.GetFlags();
594 // Floating point registers are only callee saved when using
595 // F or D hardware floating point ABIs.
596 bool is_hw_fp = (arch_flags & ArchSpec::eLoongArch_abi_mask) != 0;
597
598 return llvm::StringSwitch<bool>(name)
599 // integer ABI names
600 .Cases("ra", "sp", "fp", true)
601 .Cases("s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", true)
602 // integer hardware names
603 .Cases("r1", "r3", "r22", true)
604 .Cases("r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "31", true)
605 // floating point ABI names
606 .Cases("fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", is_hw_fp)
607 // floating point hardware names
608 .Cases("f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", is_hw_fp)
609 .Default(false);
610}
611
614 "System V ABI for LoongArch targets",
616}
617
621
622static uint32_t GetGenericNum(llvm::StringRef name) {
623 return llvm::StringSwitch<uint32_t>(name)
624 .Case("pc", LLDB_REGNUM_GENERIC_PC)
625 .Cases("ra", "r1", LLDB_REGNUM_GENERIC_RA)
626 .Cases("sp", "r3", LLDB_REGNUM_GENERIC_SP)
627 .Cases("fp", "r22", LLDB_REGNUM_GENERIC_FP)
628 .Cases("a0", "r4", LLDB_REGNUM_GENERIC_ARG1)
629 .Cases("a1", "r5", LLDB_REGNUM_GENERIC_ARG2)
630 .Cases("a2", "r6", LLDB_REGNUM_GENERIC_ARG3)
631 .Cases("a3", "r7", LLDB_REGNUM_GENERIC_ARG4)
632 .Cases("a4", "r8", LLDB_REGNUM_GENERIC_ARG5)
633 .Cases("a5", "r9", LLDB_REGNUM_GENERIC_ARG6)
634 .Cases("a6", "r10", LLDB_REGNUM_GENERIC_ARG7)
635 .Cases("a7", "r11", LLDB_REGNUM_GENERIC_ARG8)
636 .Default(LLDB_INVALID_REGNUM);
637}
638
640 std::vector<lldb_private::DynamicRegisterInfo::Register> &regs) {
642
643 static const llvm::StringMap<llvm::StringRef> isa_to_abi_alias_map = {
644 {"r0", "zero"}, {"r1", "ra"}, {"r2", "tp"}, {"r3", "sp"},
645 {"r4", "a0"}, {"r5", "a1"}, {"r6", "a2"}, {"r7", "a3"},
646 {"r8", "a4"}, {"r9", "a5"}, {"r10", "a6"}, {"r11", "a7"},
647 {"r12", "t0"}, {"r13", "t1"}, {"r14", "t2"}, {"r15", "t3"},
648 {"r16", "t4"}, {"r17", "t5"}, {"r18", "t6"}, {"r19", "t7"},
649 {"r20", "t8"}, {"r22", "fp"}, {"r23", "s0"}, {"r24", "s1"},
650 {"r25", "s2"}, {"r26", "s3"}, {"r27", "s4"}, {"r28", "s5"},
651 {"r29", "s6"}, {"r30", "s7"}, {"r31", "s8"}};
652
653 for (auto it : llvm::enumerate(regs)) {
654 llvm::StringRef reg_name = it.value().name.GetStringRef();
655
656 // Set alt name for certain registers for convenience
657 llvm::StringRef alias_name = isa_to_abi_alias_map.lookup(reg_name);
658 if (!alias_name.empty())
659 it.value().alt_name.SetString(alias_name);
660
661 // Set generic regnum so lldb knows what the PC, etc is
662 it.value().regnum_generic = GetGenericNum(reg_name);
663 }
664}
static const RegisterInfo g_register_infos[]
#define DEFINE_REGISTER_STUB(dwarf_num, str_name)
#define DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, generic_num)
static const size_t reg_size
static ValueObjectSP GetValObjFromIntRegs(Thread &thread, const RegisterContextSP &reg_ctx, llvm::Triple::ArchType machine, uint32_t type_flags, uint32_t byte_size)
static bool UpdateRegister(RegisterContext *reg_ctx, const lldb::RegisterKind reg_kind, const uint32_t reg_num, const addr_t value)
static void LogInitInfo(Log &log, const Thread &thread, addr_t sp, addr_t func_addr, addr_t return_addr, const llvm::ArrayRef< addr_t > args)
static void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed)
static ValueObjectSP GetValObjFromFPRegs(Thread &thread, const RegisterContextSP &reg_ctx, llvm::Triple::ArchType machine, uint32_t type_flags, uint32_t byte_size)
static uint32_t GetGenericNum(llvm::StringRef name)
static bool SetSizedInteger(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes, bool is_signed)
static constexpr size_t g_regs_for_args_count
static bool SetSizedFloat(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes)
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:369
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info)
bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, lldb::addr_t functionAddress, lldb::addr_t returnAddress, llvm::ArrayRef< lldb::addr_t > args) const override
const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override
lldb::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
void AugmentRegisterInfo(std::vector< lldb_private::DynamicRegisterInfo::Register > &regs) override
void SetIsLA64(bool is_la64)
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
lldb::UnwindPlanSP CreateDefaultUnwindPlan() override
static llvm::StringRef GetPluginNameStatic()
lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() override
static std::unique_ptr< llvm::MCRegisterInfo > MakeMCRegisterInfo(const ArchSpec &arch)
Utility function to construct a MCRegisterInfo using the ArchSpec triple.
Definition ABI.cpp:234
lldb::ProcessSP GetProcessSP() const
Request to get a Process shared pointer.
Definition ABI.h:97
An architecture specification class.
Definition ArchSpec.h:31
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:468
@ eLoongArch_abi_mask
double precision floating point, +d
Definition ArchSpec.h:116
uint32_t GetFlags() const
Definition ArchSpec.h:539
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition ArchSpec.cpp:677
Generic representation of a type in a programming language.
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
bool IsFloatingPointType(uint32_t &count, bool &is_complex) const
bool IsIntegerOrEnumerationType(bool &is_signed) const
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
bool IsPointerType(CompilerType *pointee_type=nullptr) const
A uniqued constant string class.
Definition ConstString.h:40
A subclass of DataBuffer that stores a data buffer on the heap.
An data extractor class.
const void * GetData(lldb::offset_t *offset_ptr, lldb::offset_t length) const
Extract length bytes from *offset_ptr.
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void PutString(llvm::StringRef str)
Definition Log.cpp:147
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
void AugmentRegisterInfo(std::vector< DynamicRegisterInfo::Register > &regs) override
Definition ABI.cpp:251
const RegisterInfo * GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num)
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
uint32_t GetAsMemoryData(const RegisterInfo &reg_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Fail() const
Test for error condition.
Definition Status.cpp:294
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition Status.cpp:195
void SetIsRegisterPlusOffset(uint32_t reg_num, int32_t offset)
Definition UnwindPlan.h:240
bool SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
const FAValue & GetCFAValue() const
Definition UnwindPlan.h:365
bool SetRegisterLocationToRegister(uint32_t reg_num, uint32_t other_reg_num, bool can_replace)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS)
const Scalar & GetScalar() const
See comment on m_scalar to understand what GetScalar returns.
Definition Value.h:113
@ Scalar
A raw scalar value.
Definition Value.h:45
void SetCompilerType(const CompilerType &compiler_type)
Definition Value.cpp:276
void SetValueType(ValueType value_type)
Definition Value.h:89
void SetBytes(const void *bytes, int len)
Definition Value.cpp:90
#define LLDB_REGNUM_GENERIC_RA
#define LLDB_REGNUM_GENERIC_ARG8
#define LLDB_REGNUM_GENERIC_ARG6
#define LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_ARG4
#define LLDB_REGNUM_GENERIC_ARG3
#define LLDB_REGNUM_GENERIC_ARG1
#define LLDB_REGNUM_GENERIC_ARG7
#define UINT32_MAX
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_ARG2
#define LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_FP
#define LLDB_REGNUM_GENERIC_ARG5
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
uint64_t offset_t
Definition lldb-types.h:85
std::shared_ptr< lldb_private::Process > ProcessSP
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::UnwindPlan > UnwindPlanSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
RegisterKind
Register numbering types.
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindDWARF
the register numbers seen DWARF
Every register is described in detail including its name, alternate name (optional),...
const char * name
Name of this register, can't be NULL.