LLDB mainline
PlatformLinux.cpp
Go to the documentation of this file.
1//===-- PlatformLinux.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 "PlatformLinux.h"
10#include "lldb/Host/Config.h"
11
12#include <cstdio>
13#if LLDB_ENABLE_POSIX
14#include <sys/utsname.h>
15#endif
16
20#include "lldb/Core/Debugger.h"
22#include "lldb/Host/HostInfo.h"
24#include "lldb/Target/Process.h"
25#include "lldb/Target/Target.h"
29#include "lldb/Utility/Log.h"
30#include "lldb/Utility/State.h"
31#include "lldb/Utility/Status.h"
33
34// Define these constants from Linux mman.h for use when targeting remote linux
35// systems even when host has different values.
36#define MAP_PRIVATE 2
37#define MAP_ANON 0x20
38
39// For other platforms that use platform linux
40#ifndef SIGILL
41#define SIGILL 4
42#endif
43#ifndef SIGBUS
44#define SIGBUS 7
45#endif
46#ifndef SIGFPE
47#define SIGFPE 8
48#endif
49#ifndef SIGSEGV
50#define SIGSEGV 11
51#endif
52
53using namespace lldb;
54using namespace lldb_private;
55using namespace lldb_private::platform_linux;
56
58
59static uint32_t g_initialize_count = 0;
60
61
64 LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,
65 arch ? arch->GetArchitectureName() : "<null>",
66 arch ? arch->GetTriple().getTriple() : "<null>");
67
68 bool create = force;
69 if (!create && arch && arch->IsValid()) {
70 const llvm::Triple &triple = arch->GetTriple();
71 switch (triple.getOS()) {
72 case llvm::Triple::Linux:
73 create = true;
74 break;
75
76#if defined(__linux__)
77 // Only accept "unknown" for the OS if the host is linux and it "unknown"
78 // wasn't specified (it was just returned because it was NOT specified)
79 case llvm::Triple::OSType::UnknownOS:
80 create = !arch->TripleOSWasSpecified();
81 break;
82#endif
83 default:
84 break;
85 }
86 }
87
88 LLDB_LOG(log, "create = {0}", create);
89 if (create) {
90 return PlatformSP(new PlatformLinux(false));
91 }
92 return PlatformSP();
93}
94
95llvm::StringRef PlatformLinux::GetPluginDescriptionStatic(bool is_host) {
96 if (is_host)
97 return "Local Linux user platform plug-in.";
98 return "Remote Linux user platform plug-in.";
99}
100
103
104 if (g_initialize_count++ == 0) {
105#if defined(__linux__) && !defined(__ANDROID__)
106 PlatformSP default_platform_sp(new PlatformLinux(true));
107 default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
108 Platform::SetHostPlatform(default_platform_sp);
109#endif
114 }
115}
116
126
127/// Default Constructor
129 : PlatformPOSIX(is_host) // This is the local host platform
130{
131 if (is_host) {
132 ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
133 m_supported_architectures.push_back(hostArch);
134 if (hostArch.GetTriple().isArch64Bit()) {
136 HostInfo::GetArchitecture(HostInfo::eArchKind32));
137 }
138 } else {
140 {llvm::Triple::x86_64, llvm::Triple::x86, llvm::Triple::arm,
141 llvm::Triple::aarch64, llvm::Triple::mips64, llvm::Triple::mips64,
142 llvm::Triple::hexagon, llvm::Triple::mips, llvm::Triple::mips64el,
143 llvm::Triple::mipsel, llvm::Triple::msp430, llvm::Triple::systemz,
144 llvm::Triple::loongarch64, llvm::Triple::ppc64le,
145 llvm::Triple::riscv64},
146 llvm::Triple::Linux);
147 }
148}
149
150std::vector<ArchSpec>
153 return m_remote_platform_sp->GetSupportedArchitectures(process_host_arch);
155}
156
159
160#if LLDB_ENABLE_POSIX
161 // Display local kernel information only when we are running in host mode.
162 // Otherwise, we would end up printing non-Linux information (when running on
163 // Mac OS for example).
164 if (IsHost()) {
165 struct utsname un;
166
167 if (uname(&un))
168 return;
169
170 strm.Printf(" Kernel: %s\n", un.sysname);
171 strm.Printf(" Release: %s\n", un.release);
172 strm.Printf(" Version: %s\n", un.version);
173 }
174#endif
175}
176
177uint32_t
179 uint32_t resume_count = 0;
180
181 // Always resume past the initial stop when we use eLaunchFlagDebug
182 if (launch_info.GetFlags().Test(eLaunchFlagDebug)) {
183 // Resume past the stop for the final exec into the true inferior.
184 ++resume_count;
185 }
186
187 // If we're not launching a shell, we're done.
188 const FileSpec &shell = launch_info.GetShell();
189 if (!shell)
190 return resume_count;
191
192 std::string shell_string = shell.GetPath();
193 // We're in a shell, so for sure we have to resume past the shell exec.
194 ++resume_count;
195
196 // Figure out what shell we're planning on using.
197 const char *shell_name = strrchr(shell_string.c_str(), '/');
198 if (shell_name == nullptr)
199 shell_name = shell_string.c_str();
200 else
201 shell_name++;
202
203 if (strcmp(shell_name, "csh") == 0 || strcmp(shell_name, "tcsh") == 0 ||
204 strcmp(shell_name, "zsh") == 0 || strcmp(shell_name, "sh") == 0) {
205 // These shells seem to re-exec themselves. Add another resume.
206 ++resume_count;
207 }
208
209 return resume_count;
210}
211
213 if (IsHost()) {
214 return true;
215 } else {
216 // If we're connected, we can debug.
217 return IsConnected();
218 }
219}
220
222 m_trap_handlers.push_back(ConstString("_sigtramp"));
223 m_trap_handlers.push_back(ConstString("__kernel_rt_sigreturn"));
224 m_trap_handlers.push_back(ConstString("__restore_rt"));
225 m_trap_handlers.push_back(ConstString("__vdso_rt_sigreturn"));
226}
227
229 UnwindPlanSP unwind_plan_sp;
230 if (name != "__kernel_rt_sigreturn")
231 return unwind_plan_sp;
232
233 UnwindPlan::Row row;
234
235 // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
236 // - 128-byte siginfo struct
237 // - ucontext struct:
238 // - 8-byte long (uc_flags)
239 // - 8-byte pointer (uc_link)
240 // - 24-byte stack_t
241 // - 128-byte signal set
242 // - 8 bytes of padding because sigcontext has 16-byte alignment
243 // - sigcontext/mcontext_t
244 // [1]
245 // https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/signal.c
246 int32_t offset = 128 + 8 + 8 + 24 + 128 + 8;
247 // Then sigcontext[2] is:
248 // - 8 byte fault address
249 // - 31 8 byte registers
250 // - 8 byte sp
251 // - 8 byte pc
252 // [2]
253 // https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/sigcontext.h
254
255 // Skip fault address
256 offset += 8;
258
292
293 // The sigcontext may also contain floating point and SVE registers.
294 // However this would require a dynamic unwind plan so they are not included
295 // here.
296
297 unwind_plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
298 unwind_plan_sp->AppendRow(std::move(row));
299 unwind_plan_sp->SetSourceName("AArch64 Linux sigcontext");
300 unwind_plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
301 // Because sp is the same throughout the function
302 unwind_plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
303 unwind_plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolYes);
304
305 return unwind_plan_sp;
306}
307
309 uint32_t fp_flags) {
310 if (name != "__vdso_rt_sigreturn")
311 return {};
312
313 UnwindPlan::Row row;
314
315 // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
316 // - 128-byte siginfo struct
317 // - ucontext struct:
318 // - 8-byte long (uc_flags)
319 // - 8-byte pointer (*uc_link)
320 // - 24-byte struct (uc_stack)
321 // - 8-byte struct (uc_sigmask)
322 // - 120-byte of padding to allow sigset_t to be expanded in the future
323 // - 8 bytes of padding because sigcontext has 16-byte alignment
324 // - struct sigcontext uc_mcontext
325 // [1]
326 // https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/signal.c
327
328 constexpr size_t siginfo_size = 128;
329 constexpr size_t uc_flags_size = 8;
330 constexpr size_t uc_link_ptr_size = 8;
331 constexpr size_t uc_stack_size = 24;
332 constexpr size_t uc_sigmask_size = 8;
333 constexpr size_t padding_size = 128;
334
335 constexpr size_t offset = siginfo_size + uc_flags_size + uc_link_ptr_size +
336 uc_stack_size + uc_sigmask_size + padding_size;
337
338 // In user_regs_struct GPRs are always 64-bit length
339 size_t gpr_size = 8;
341 for (uint32_t reg_num = gpr_first_riscv; reg_num < gpr_first_riscv + 32;
342 ++reg_num)
343 row.SetRegisterLocationToAtCFAPlusOffset(reg_num, reg_num * gpr_size,
344 false);
345
346 size_t fpr_size = 0;
347 switch (fp_flags) {
349 fpr_size = 0;
350 break;
352 fpr_size = 4;
353 break;
355 fpr_size = 8;
356 break;
358 fpr_size = 16;
359 break;
360 }
361
362 if (fpr_size != 0) {
363 for (uint32_t reg_num = fpr_first_riscv; reg_num < fpr_first_riscv + 32;
364 ++reg_num) {
365 size_t fpr_offset =
366 gpr_size * 32 + (reg_num - fpr_first_riscv) * fpr_size;
367 row.SetRegisterLocationToAtCFAPlusOffset(reg_num, fpr_offset, false);
368 }
369
370 size_t fpr_fcsr_offset = gpr_size * 32 + fpr_size * 32;
372 false);
373 }
374
375 UnwindPlanSP unwind_plan_sp = std::make_shared<UnwindPlan>(eRegisterKindLLDB);
376 unwind_plan_sp->AppendRow(std::move(row));
377 unwind_plan_sp->SetSourceName("RISC-V Linux sigcontext");
378 unwind_plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
379 unwind_plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
380 unwind_plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolYes);
381
382 return unwind_plan_sp;
383}
384
386 ConstString name) {
387 llvm::Triple triple = arch.GetTriple();
388 if (triple.isAArch64())
390 if (triple.isRISCV()) {
391 uint32_t fp_flags = arch.GetFlags() & ArchSpec::eRISCV_float_abi_mask;
392 return GetRISCVTrapHandlerUnwindPlan(name, fp_flags);
393 }
394 return {};
395}
396
398 addr_t addr, addr_t length,
399 unsigned prot, unsigned flags,
400 addr_t fd, addr_t offset) {
401 uint64_t flags_platform = 0;
402 uint64_t map_anon = arch.IsMIPS() ? 0x800 : MAP_ANON;
403
404 if (flags & eMmapFlagsPrivate)
405 flags_platform |= MAP_PRIVATE;
406 if (flags & eMmapFlagsAnon)
407 flags_platform |= map_anon;
408
409 MmapArgList args({addr, length, prot, flags_platform, fd, offset});
410 return args;
411}
412
413CompilerType PlatformLinux::GetSiginfoType(const llvm::Triple &triple) {
414 {
415 std::lock_guard<std::mutex> guard(m_mutex);
416 if (!m_type_system)
417 m_type_system = std::make_shared<TypeSystemClang>("siginfo", triple);
418 }
419 TypeSystemClang *ast = m_type_system.get();
420
421 bool si_errno_then_code = true;
422
423 switch (triple.getArch()) {
424 case llvm::Triple::mips:
425 case llvm::Triple::mipsel:
426 case llvm::Triple::mips64:
427 case llvm::Triple::mips64el:
428 // mips has si_code and si_errno swapped
429 si_errno_then_code = false;
430 break;
431 default:
432 break;
433 }
434
435 // generic types
436 CompilerType int_type = ast->GetBasicType(eBasicTypeInt);
438 CompilerType short_type = ast->GetBasicType(eBasicTypeShort);
439 CompilerType long_type = ast->GetBasicType(eBasicTypeLong);
441
442 // platform-specific types
443 CompilerType &pid_type = int_type;
444 CompilerType &uid_type = uint_type;
445 CompilerType &clock_type = long_type;
446 CompilerType &band_type = long_type;
447
448 CompilerType sigval_type = ast->CreateRecordType(
449 nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_sigval_t",
450 llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
451 ast->StartTagDeclarationDefinition(sigval_type);
452 ast->AddFieldToRecordType(sigval_type, "sival_int", int_type,
454 ast->AddFieldToRecordType(sigval_type, "sival_ptr", voidp_type,
456 ast->CompleteTagDeclarationDefinition(sigval_type);
457
458 CompilerType sigfault_bounds_type = ast->CreateRecordType(
460 llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
461 ast->StartTagDeclarationDefinition(sigfault_bounds_type);
463 sigfault_bounds_type, "_addr_bnd",
464 ast->CreateStructForIdentifier(llvm::StringRef(),
465 {
466 {"_lower", voidp_type},
467 {"_upper", voidp_type},
468 }),
470 ast->AddFieldToRecordType(sigfault_bounds_type, "_pkey", uint_type,
472 ast->CompleteTagDeclarationDefinition(sigfault_bounds_type);
473
474 // siginfo_t
475 CompilerType siginfo_type = ast->CreateRecordType(
476 nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_siginfo_t",
477 llvm::to_underlying(clang::TagTypeKind::Struct), lldb::eLanguageTypeC);
478 ast->StartTagDeclarationDefinition(siginfo_type);
479 ast->AddFieldToRecordType(siginfo_type, "si_signo", int_type,
481
482 if (si_errno_then_code) {
483 ast->AddFieldToRecordType(siginfo_type, "si_errno", int_type,
485 ast->AddFieldToRecordType(siginfo_type, "si_code", int_type,
487 } else {
488 ast->AddFieldToRecordType(siginfo_type, "si_code", int_type,
490 ast->AddFieldToRecordType(siginfo_type, "si_errno", int_type,
492 }
493
494 // the structure is padded on 64-bit arches to fix alignment
495 if (triple.isArch64Bit())
496 ast->AddFieldToRecordType(siginfo_type, "__pad0", int_type,
498
499 // union used to hold the signal data
500 CompilerType union_type = ast->CreateRecordType(
502 llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
503 ast->StartTagDeclarationDefinition(union_type);
504
505 ast->AddFieldToRecordType(
506 union_type, "_kill",
507 ast->CreateStructForIdentifier(llvm::StringRef(),
508 {
509 {"si_pid", pid_type},
510 {"si_uid", uid_type},
511 }),
513
514 ast->AddFieldToRecordType(
515 union_type, "_timer",
516 ast->CreateStructForIdentifier(llvm::StringRef(),
517 {
518 {"si_tid", int_type},
519 {"si_overrun", int_type},
520 {"si_sigval", sigval_type},
521 }),
523
524 ast->AddFieldToRecordType(
525 union_type, "_rt",
526 ast->CreateStructForIdentifier(llvm::StringRef(),
527 {
528 {"si_pid", pid_type},
529 {"si_uid", uid_type},
530 {"si_sigval", sigval_type},
531 }),
533
534 ast->AddFieldToRecordType(
535 union_type, "_sigchld",
536 ast->CreateStructForIdentifier(llvm::StringRef(),
537 {
538 {"si_pid", pid_type},
539 {"si_uid", uid_type},
540 {"si_status", int_type},
541 {"si_utime", clock_type},
542 {"si_stime", clock_type},
543 }),
545
546 ast->AddFieldToRecordType(
547 union_type, "_sigfault",
548 ast->CreateStructForIdentifier(llvm::StringRef(),
549 {
550 {"si_addr", voidp_type},
551 {"si_addr_lsb", short_type},
552 {"_bounds", sigfault_bounds_type},
553 }),
555
556 ast->AddFieldToRecordType(
557 union_type, "_sigpoll",
558 ast->CreateStructForIdentifier(llvm::StringRef(),
559 {
560 {"si_band", band_type},
561 {"si_fd", int_type},
562 }),
564
565 // NB: SIGSYS is not present on ia64 but we don't seem to support that
566 ast->AddFieldToRecordType(
567 union_type, "_sigsys",
568 ast->CreateStructForIdentifier(llvm::StringRef(),
569 {
570 {"_call_addr", voidp_type},
571 {"_syscall", int_type},
572 {"_arch", uint_type},
573 }),
575
576 ast->CompleteTagDeclarationDefinition(union_type);
577 ast->AddFieldToRecordType(siginfo_type, "_sifields", union_type,
579
580 ast->CompleteTagDeclarationDefinition(siginfo_type);
581 return siginfo_type;
582}
583
584static std::string GetDescriptionFromSiginfo(lldb::ValueObjectSP siginfo_sp) {
585 if (!siginfo_sp)
586 return "";
587
588 lldb_private::LinuxSignals linux_signals;
589 int code = siginfo_sp->GetChildMemberWithName("si_code")->GetValueAsSigned(0);
590 int signo =
591 siginfo_sp->GetChildMemberWithName("si_signo")->GetValueAsSigned(-1);
592
593 auto sifields = siginfo_sp->GetChildMemberWithName("_sifields");
594 if (!sifields)
595 return linux_signals.GetSignalDescription(signo, code);
596
597 // declare everything that we can populate later.
598 std::optional<lldb::addr_t> addr;
599 std::optional<lldb::addr_t> upper;
600 std::optional<lldb::addr_t> lower;
601 std::optional<uint32_t> pid;
602 std::optional<uint32_t> uid;
603
604 // The negative si_codes are special and mean this signal was sent from user
605 // space not the kernel. These take precedence because they break some of the
606 // invariants around kernel sent signals. Such as SIGSEGV won't have an
607 // address.
608 if (code < 0) {
609 auto sikill = sifields->GetChildMemberWithName("_kill");
610 if (sikill) {
611 auto pid_sp = sikill->GetChildMemberWithName("si_pid");
612 if (pid_sp)
613 pid = pid_sp->GetValueAsUnsigned(-1);
614 auto uid_sp = sikill->GetChildMemberWithName("si_uid");
615 if (uid_sp)
616 uid = uid_sp->GetValueAsUnsigned(-1);
617 }
618 } else {
619
620 switch (signo) {
621 case SIGILL:
622 case SIGFPE:
623 case SIGBUS: {
624 auto sigfault = sifields->GetChildMemberWithName("_sigfault");
625 if (!sigfault)
626 break;
627
628 auto addr_sp = sigfault->GetChildMemberWithName("si_addr");
629 if (addr_sp)
630 addr = addr_sp->GetValueAsUnsigned(-1);
631 break;
632 }
633 case SIGSEGV: {
634 auto sigfault = sifields->GetChildMemberWithName("_sigfault");
635 if (!sigfault)
636 break;
637
638 auto addr_sp = sigfault->GetChildMemberWithName("si_addr");
639 if (addr_sp)
640 addr = addr_sp->GetValueAsUnsigned(-1);
641
642 auto bounds_sp = sigfault->GetChildMemberWithName("_bounds");
643 if (!bounds_sp)
644 break;
645
646 auto addr_bnds_sp = bounds_sp->GetChildMemberWithName("_addr_bnd");
647 if (!addr_bnds_sp)
648 break;
649
650 auto lower_sp = addr_bnds_sp->GetChildMemberWithName("_lower");
651 if (lower_sp)
652 lower = lower_sp->GetValueAsUnsigned(-1);
653
654 auto upper_sp = addr_bnds_sp->GetChildMemberWithName("_upper");
655 if (upper_sp)
656 upper = upper_sp->GetValueAsUnsigned(-1);
657
658 break;
659 }
660 default:
661 break;
662 }
663 }
664
665 return linux_signals.GetSignalDescription(signo, code, addr, lower, upper,
666 pid, uid);
667}
668
670 ValueObjectSP siginfo_sp = thread.GetSiginfoValue();
671 if (!siginfo_sp)
672 return {};
673 auto signo_sp = siginfo_sp->GetChildMemberWithName("si_signo");
674 auto sicode_sp = siginfo_sp->GetChildMemberWithName("si_code");
675 if (!signo_sp || !sicode_sp)
676 return {};
677
678 std::string siginfo_description = GetDescriptionFromSiginfo(siginfo_sp);
679 if (siginfo_description.empty())
681 thread, signo_sp->GetValueAsUnsigned(-1));
682
684 thread, signo_sp->GetValueAsUnsigned(-1), siginfo_description.c_str(),
685 sicode_sp->GetValueAsUnsigned(0));
686}
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:369
static uint32_t g_initialize_count
#define MAP_ANON
#define MAP_PRIVATE
static lldb::UnwindPlanSP GetAArch64TrapHandlerUnwindPlan(ConstString name)
static std::string GetDescriptionFromSiginfo(lldb::ValueObjectSP siginfo_sp)
#define SIGILL
#define SIGFPE
static lldb::UnwindPlanSP GetRISCVTrapHandlerUnwindPlan(ConstString name, uint32_t fp_flags)
#define SIGSEGV
#define SIGBUS
#define LLDB_PLUGIN_DEFINE(PluginName)
PlatformPOSIX(bool is_host)
Default Constructor.
An architecture specification class.
Definition ArchSpec.h:31
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:468
bool IsMIPS() const
if MIPS architecture return true.
Definition ArchSpec.cpp:555
uint32_t GetFlags() const
Definition ArchSpec.h:539
@ eRISCV_float_abi_double
single precision floating point, +f
Definition ArchSpec.h:97
@ eRISCV_float_abi_soft
RVC, +c.
Definition ArchSpec.h:95
@ eRISCV_float_abi_quad
double precision floating point, +d
Definition ArchSpec.h:98
@ eRISCV_float_abi_mask
quad precision floating point, +q
Definition ArchSpec.h:99
@ eRISCV_float_abi_single
soft float
Definition ArchSpec.h:96
Generic representation of a type in a programming language.
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
A uniqued constant string class.
Definition ConstString.h:40
A file utility class.
Definition FileSpec.h:57
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
bool Test(ValueType bit) const
Test a single flag bit.
Definition Flags.h:96
Linux specific set of Unix signals.
std::vector< ConstString > m_trap_handlers
Definition Platform.h:1024
static void Terminate()
Definition Platform.cpp:138
static void SetHostPlatform(const lldb::PlatformSP &platform_sp)
Definition Platform.cpp:145
virtual void GetStatus(Stream &strm)
Report the current status for this platform.
Definition Platform.cpp:247
static void Initialize()
Definition Platform.cpp:136
static std::vector< ArchSpec > CreateArchList(llvm::ArrayRef< llvm::Triple::ArchType > archs, llvm::Triple::OSType os)
Create a list of ArchSpecs with the given OS and a architectures.
bool IsHost() const
Definition Platform.h:503
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
const FileSpec & GetShell() const
static lldb::StopInfoSP CreateStopReasonWithSignal(Thread &thread, int signo, const char *description=nullptr, std::optional< int > code=std::nullopt)
A stream class that can stream formatted output to a file.
Definition Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
A TypeSystem implementation based on Clang.
CompilerType GetBasicType(lldb::BasicType type)
static clang::FieldDecl * AddFieldToRecordType(const CompilerType &type, llvm::StringRef name, const CompilerType &field_type, lldb::AccessType access, uint32_t bitfield_bit_size)
CompilerType CreateStructForIdentifier(llvm::StringRef type_name, const std::initializer_list< std::pair< const char *, CompilerType > > &type_fields, bool packed=false)
static bool CompleteTagDeclarationDefinition(const CompilerType &type)
CompilerType CreateRecordType(clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, lldb::AccessType access_type, llvm::StringRef name, int kind, lldb::LanguageType language, std::optional< ClangASTMetadata > metadata=std::nullopt, bool exports_symbols=false)
static bool StartTagDeclarationDefinition(const CompilerType &type)
std::string GetSignalDescription(int32_t signo, std::optional< int32_t > code=std::nullopt, std::optional< lldb::addr_t > addr=std::nullopt, std::optional< lldb::addr_t > lower=std::nullopt, std::optional< lldb::addr_t > upper=std::nullopt, std::optional< uint32_t > pid=std::nullopt, std::optional< uint32_t > uid=std::nullopt) const
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
lldb::UnwindPlanSP GetTrapHandlerUnwindPlan(const ArchSpec &arch, ConstString name) override
Try to get a specific unwind plan for a named trap handler.
void GetStatus(Stream &strm) override
Report the current status for this platform.
void CalculateTrapHandlerSymbolNames() override
Ask the Platform subclass to fill in the list of trap handler names.
PlatformLinux(bool is_host)
Default Constructor.
std::vector< ArchSpec > GetSupportedArchitectures(const ArchSpec &process_host_arch) override
Get the platform's supported architectures in the order in which they should be searched.
lldb::StopInfoSP GetStopInfoFromSiginfo(Thread &thread) override
std::shared_ptr< TypeSystemClang > m_type_system
static llvm::StringRef GetPluginDescriptionStatic(bool is_host)
static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch)
static llvm::StringRef GetPluginNameStatic(bool is_host)
MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr, lldb::addr_t length, unsigned prot, unsigned flags, lldb::addr_t fd, lldb::addr_t offset) override
uint32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) override
std::vector< ArchSpec > m_supported_architectures
bool CanDebugProcess() override
Not all platforms will support debugging a process by spawning somehow halted for a debugger (specifi...
CompilerType GetSiginfoType(const llvm::Triple &triple) override
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
llvm::SmallVector< lldb::addr_t, 6 > MmapArgList
Definition Platform.h:64
@ eMmapFlagsPrivate
Definition Platform.h:46
@ eBasicTypeUnsignedInt
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::Platform > PlatformSP
@ eLanguageTypeC
Non-standardized C, such as K&R.
std::shared_ptr< lldb_private::UnwindPlan > UnwindPlanSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
uint64_t addr_t
Definition lldb-types.h:80
@ eRegisterKindLLDB
lldb's internal register numbers
@ eRegisterKindDWARF
the register numbers seen DWARF