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("_sigtramp");
223 m_trap_handlers.push_back("__kernel_rt_sigreturn");
224 m_trap_handlers.push_back("__restore_rt");
225 m_trap_handlers.push_back("__vdso_rt_sigreturn");
226}
227
229GetAArch64TrapHandlerUnwindPlan(llvm::StringRef name) {
230 UnwindPlanSP unwind_plan_sp;
231 if (name != "__kernel_rt_sigreturn")
232 return unwind_plan_sp;
233
234 UnwindPlan::Row row;
235
236 // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
237 // - 128-byte siginfo struct
238 // - ucontext struct:
239 // - 8-byte long (uc_flags)
240 // - 8-byte pointer (uc_link)
241 // - 24-byte stack_t
242 // - 128-byte signal set
243 // - 8 bytes of padding because sigcontext has 16-byte alignment
244 // - sigcontext/mcontext_t
245 // [1]
246 // https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/signal.c
247 int32_t offset = 128 + 8 + 8 + 24 + 128 + 8;
248 // Then sigcontext[2] is:
249 // - 8 byte fault address
250 // - 31 8 byte registers
251 // - 8 byte sp
252 // - 8 byte pc
253 // [2]
254 // https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/sigcontext.h
255
256 // Skip fault address
257 offset += 8;
259
293
294 // The sigcontext may also contain floating point and SVE registers.
295 // However this would require a dynamic unwind plan so they are not included
296 // here.
297
298 unwind_plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
299 unwind_plan_sp->AppendRow(std::move(row));
300 unwind_plan_sp->SetSourceName("AArch64 Linux sigcontext");
301 unwind_plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
302 // Because sp is the same throughout the function
303 unwind_plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
304 unwind_plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolYes);
305
306 return unwind_plan_sp;
307}
308
310 uint32_t fp_flags) {
311 if (name != "__vdso_rt_sigreturn")
312 return {};
313
314 UnwindPlan::Row row;
315
316 // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
317 // - 128-byte siginfo struct
318 // - ucontext struct:
319 // - 8-byte long (uc_flags)
320 // - 8-byte pointer (*uc_link)
321 // - 24-byte struct (uc_stack)
322 // - 8-byte struct (uc_sigmask)
323 // - 120-byte of padding to allow sigset_t to be expanded in the future
324 // - 8 bytes of padding because sigcontext has 16-byte alignment
325 // - struct sigcontext uc_mcontext
326 // [1]
327 // https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/signal.c
328
329 constexpr size_t siginfo_size = 128;
330 constexpr size_t uc_flags_size = 8;
331 constexpr size_t uc_link_ptr_size = 8;
332 constexpr size_t uc_stack_size = 24;
333 constexpr size_t uc_sigmask_size = 8;
334 constexpr size_t padding_size = 128;
335
336 constexpr size_t offset = siginfo_size + uc_flags_size + uc_link_ptr_size +
337 uc_stack_size + uc_sigmask_size + padding_size;
338
339 // In user_regs_struct GPRs are always 64-bit length
340 size_t gpr_size = 8;
342 for (uint32_t reg_num = gpr_first_riscv; reg_num < gpr_first_riscv + 32;
343 ++reg_num)
344 row.SetRegisterLocationToAtCFAPlusOffset(reg_num, reg_num * gpr_size,
345 false);
346
347 size_t fpr_size = 0;
348 switch (fp_flags) {
350 fpr_size = 0;
351 break;
353 fpr_size = 4;
354 break;
356 fpr_size = 8;
357 break;
359 fpr_size = 16;
360 break;
361 }
362
363 if (fpr_size != 0) {
364 for (uint32_t reg_num = fpr_first_riscv; reg_num < fpr_first_riscv + 32;
365 ++reg_num) {
366 size_t fpr_offset =
367 gpr_size * 32 + (reg_num - fpr_first_riscv) * fpr_size;
368 row.SetRegisterLocationToAtCFAPlusOffset(reg_num, fpr_offset, false);
369 }
370
371 size_t fpr_fcsr_offset = gpr_size * 32 + fpr_size * 32;
373 false);
374 }
375
376 UnwindPlanSP unwind_plan_sp = std::make_shared<UnwindPlan>(eRegisterKindLLDB);
377 unwind_plan_sp->AppendRow(std::move(row));
378 unwind_plan_sp->SetSourceName("RISC-V Linux sigcontext");
379 unwind_plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
380 unwind_plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
381 unwind_plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolYes);
382
383 return unwind_plan_sp;
384}
385
388 llvm::StringRef name) {
389 llvm::Triple triple = arch.GetTriple();
390 if (triple.isAArch64())
392 if (triple.isRISCV()) {
393 uint32_t fp_flags = arch.GetFlags() & ArchSpec::eRISCV_float_abi_mask;
394 return GetRISCVTrapHandlerUnwindPlan(name, fp_flags);
395 }
396 return {};
397}
398
400 addr_t addr, addr_t length,
401 unsigned prot, unsigned flags,
402 addr_t fd, addr_t offset) {
403 uint64_t flags_platform = 0;
404 uint64_t map_anon = arch.IsMIPS() ? 0x800 : MAP_ANON;
405
406 if (flags & eMmapFlagsPrivate)
407 flags_platform |= MAP_PRIVATE;
408 if (flags & eMmapFlagsAnon)
409 flags_platform |= map_anon;
410
411 MmapArgList args({addr, length, prot, flags_platform, fd, offset});
412 return args;
413}
414
415CompilerType PlatformLinux::GetSiginfoType(const llvm::Triple &triple) {
416 {
417 std::lock_guard<std::mutex> guard(m_mutex);
418 if (!m_type_system)
419 m_type_system = std::make_shared<TypeSystemClang>("siginfo", triple);
420 }
421 TypeSystemClang *ast = m_type_system.get();
422
423 bool si_errno_then_code = true;
424
425 switch (triple.getArch()) {
426 case llvm::Triple::mips:
427 case llvm::Triple::mipsel:
428 case llvm::Triple::mips64:
429 case llvm::Triple::mips64el:
430 // mips has si_code and si_errno swapped
431 si_errno_then_code = false;
432 break;
433 default:
434 break;
435 }
436
437 // generic types
438 CompilerType int_type = ast->GetBasicType(eBasicTypeInt);
440 CompilerType short_type = ast->GetBasicType(eBasicTypeShort);
441 CompilerType long_type = ast->GetBasicType(eBasicTypeLong);
443
444 // platform-specific types
445 CompilerType &pid_type = int_type;
446 CompilerType &uid_type = uint_type;
447 CompilerType &clock_type = long_type;
448 CompilerType &band_type = long_type;
449
450 CompilerType sigval_type = ast->CreateRecordType(
451 nullptr, OptionalClangModuleID(), "__lldb_sigval_t",
452 llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
453 ast->StartTagDeclarationDefinition(sigval_type);
454 ast->AddFieldToRecordType(sigval_type, "sival_int", int_type, 0);
455 ast->AddFieldToRecordType(sigval_type, "sival_ptr", voidp_type, 0);
456 ast->CompleteTagDeclarationDefinition(sigval_type);
457
458 CompilerType sigfault_bounds_type = ast->CreateRecordType(
459 nullptr, OptionalClangModuleID(), "",
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 }),
469 0);
470 ast->AddFieldToRecordType(sigfault_bounds_type, "_pkey", uint_type, 0);
471 ast->CompleteTagDeclarationDefinition(sigfault_bounds_type);
472
473 // siginfo_t
474 CompilerType siginfo_type = ast->CreateRecordType(
475 nullptr, OptionalClangModuleID(), "__lldb_siginfo_t",
476 llvm::to_underlying(clang::TagTypeKind::Struct), lldb::eLanguageTypeC);
477 ast->StartTagDeclarationDefinition(siginfo_type);
478 ast->AddFieldToRecordType(siginfo_type, "si_signo", int_type, 0);
479
480 if (si_errno_then_code) {
481 ast->AddFieldToRecordType(siginfo_type, "si_errno", int_type, 0);
482 ast->AddFieldToRecordType(siginfo_type, "si_code", int_type, 0);
483 } else {
484 ast->AddFieldToRecordType(siginfo_type, "si_code", int_type, 0);
485 ast->AddFieldToRecordType(siginfo_type, "si_errno", int_type, 0);
486 }
487
488 // the structure is padded on 64-bit arches to fix alignment
489 if (triple.isArch64Bit())
490 ast->AddFieldToRecordType(siginfo_type, "__pad0", int_type, 0);
491
492 // union used to hold the signal data
493 CompilerType union_type = ast->CreateRecordType(
494 nullptr, OptionalClangModuleID(), "",
495 llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
496 ast->StartTagDeclarationDefinition(union_type);
497
498 ast->AddFieldToRecordType(
499 union_type, "_kill",
500 ast->CreateStructForIdentifier(llvm::StringRef(),
501 {
502 {"si_pid", pid_type},
503 {"si_uid", uid_type},
504 }),
505 0);
506
507 ast->AddFieldToRecordType(
508 union_type, "_timer",
509 ast->CreateStructForIdentifier(llvm::StringRef(),
510 {
511 {"si_tid", int_type},
512 {"si_overrun", int_type},
513 {"si_sigval", sigval_type},
514 }),
515 0);
516
517 ast->AddFieldToRecordType(
518 union_type, "_rt",
519 ast->CreateStructForIdentifier(llvm::StringRef(),
520 {
521 {"si_pid", pid_type},
522 {"si_uid", uid_type},
523 {"si_sigval", sigval_type},
524 }),
525 0);
526
527 ast->AddFieldToRecordType(
528 union_type, "_sigchld",
529 ast->CreateStructForIdentifier(llvm::StringRef(),
530 {
531 {"si_pid", pid_type},
532 {"si_uid", uid_type},
533 {"si_status", int_type},
534 {"si_utime", clock_type},
535 {"si_stime", clock_type},
536 }),
537 0);
538
539 ast->AddFieldToRecordType(
540 union_type, "_sigfault",
541 ast->CreateStructForIdentifier(llvm::StringRef(),
542 {
543 {"si_addr", voidp_type},
544 {"si_addr_lsb", short_type},
545 {"_bounds", sigfault_bounds_type},
546 }),
547 0);
548
549 ast->AddFieldToRecordType(
550 union_type, "_sigpoll",
551 ast->CreateStructForIdentifier(llvm::StringRef(),
552 {
553 {"si_band", band_type},
554 {"si_fd", int_type},
555 }),
556 0);
557
558 // NB: SIGSYS is not present on ia64 but we don't seem to support that
559 ast->AddFieldToRecordType(
560 union_type, "_sigsys",
561 ast->CreateStructForIdentifier(llvm::StringRef(),
562 {
563 {"_call_addr", voidp_type},
564 {"_syscall", int_type},
565 {"_arch", uint_type},
566 }),
567 0);
568
569 ast->CompleteTagDeclarationDefinition(union_type);
570 ast->AddFieldToRecordType(siginfo_type, "_sifields", union_type, 0);
571
572 ast->CompleteTagDeclarationDefinition(siginfo_type);
573 return siginfo_type;
574}
575
576static std::string GetDescriptionFromSiginfo(lldb::ValueObjectSP siginfo_sp) {
577 if (!siginfo_sp)
578 return "";
579
580 lldb_private::LinuxSignals linux_signals;
581 int code = siginfo_sp->GetChildMemberWithName("si_code")->GetValueAsSigned(0);
582 int signo =
583 siginfo_sp->GetChildMemberWithName("si_signo")->GetValueAsSigned(-1);
584
585 auto sifields = siginfo_sp->GetChildMemberWithName("_sifields");
586 if (!sifields)
587 return linux_signals.GetSignalDescription(signo, code);
588
589 // declare everything that we can populate later.
590 std::optional<lldb::addr_t> addr;
591 std::optional<lldb::addr_t> upper;
592 std::optional<lldb::addr_t> lower;
593 std::optional<uint32_t> pid;
594 std::optional<uint32_t> uid;
595
596 // The negative si_codes are special and mean this signal was sent from user
597 // space not the kernel. These take precedence because they break some of the
598 // invariants around kernel sent signals. Such as SIGSEGV won't have an
599 // address.
600 if (code < 0) {
601 auto sikill = sifields->GetChildMemberWithName("_kill");
602 if (sikill) {
603 auto pid_sp = sikill->GetChildMemberWithName("si_pid");
604 if (pid_sp)
605 pid = pid_sp->GetValueAsUnsigned(-1);
606 auto uid_sp = sikill->GetChildMemberWithName("si_uid");
607 if (uid_sp)
608 uid = uid_sp->GetValueAsUnsigned(-1);
609 }
610 } else {
611
612 switch (signo) {
613 case SIGILL:
614 case SIGFPE:
615 case SIGBUS: {
616 auto sigfault = sifields->GetChildMemberWithName("_sigfault");
617 if (!sigfault)
618 break;
619
620 auto addr_sp = sigfault->GetChildMemberWithName("si_addr");
621 if (addr_sp)
622 addr = addr_sp->GetValueAsUnsigned(-1);
623 break;
624 }
625 case SIGSEGV: {
626 auto sigfault = sifields->GetChildMemberWithName("_sigfault");
627 if (!sigfault)
628 break;
629
630 auto addr_sp = sigfault->GetChildMemberWithName("si_addr");
631 if (addr_sp)
632 addr = addr_sp->GetValueAsUnsigned(-1);
633
634 auto bounds_sp = sigfault->GetChildMemberWithName("_bounds");
635 if (!bounds_sp)
636 break;
637
638 auto addr_bnds_sp = bounds_sp->GetChildMemberWithName("_addr_bnd");
639 if (!addr_bnds_sp)
640 break;
641
642 auto lower_sp = addr_bnds_sp->GetChildMemberWithName("_lower");
643 if (lower_sp)
644 lower = lower_sp->GetValueAsUnsigned(-1);
645
646 auto upper_sp = addr_bnds_sp->GetChildMemberWithName("_upper");
647 if (upper_sp)
648 upper = upper_sp->GetValueAsUnsigned(-1);
649
650 break;
651 }
652 default:
653 break;
654 }
655 }
656
657 return linux_signals.GetSignalDescription(signo, code, addr, lower, upper,
658 pid, uid);
659}
660
662 ValueObjectSP siginfo_sp = thread.GetSiginfoValue();
663 if (!siginfo_sp)
664 return {};
665 auto signo_sp = siginfo_sp->GetChildMemberWithName("si_signo");
666 auto sicode_sp = siginfo_sp->GetChildMemberWithName("si_code");
667 if (!signo_sp || !sicode_sp)
668 return {};
669
670 std::string siginfo_description = GetDescriptionFromSiginfo(siginfo_sp);
671 if (siginfo_description.empty())
673 thread, signo_sp->GetValueAsUnsigned(-1));
674
676 thread, signo_sp->GetValueAsUnsigned(-1), siginfo_description.c_str(),
677 sicode_sp->GetValueAsUnsigned(0));
678}
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
static uint32_t g_initialize_count
#define MAP_ANON
#define MAP_PRIVATE
static std::string GetDescriptionFromSiginfo(lldb::ValueObjectSP siginfo_sp)
#define SIGILL
static lldb::UnwindPlanSP GetRISCVTrapHandlerUnwindPlan(llvm::StringRef name, uint32_t fp_flags)
#define SIGFPE
static lldb::UnwindPlanSP GetAArch64TrapHandlerUnwindPlan(llvm::StringRef name)
#define SIGSEGV
#define SIGBUS
#define LLDB_PLUGIN_DEFINE(PluginName)
PlatformPOSIX(bool is_host)
Default Constructor.
An architecture specification class.
Definition ArchSpec.h:32
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:547
bool IsMIPS() const
if MIPS architecture return true.
Definition ArchSpec.cpp:752
uint32_t GetFlags() const
Definition ArchSpec.h:618
@ eRISCV_float_abi_double
single precision floating point, +f
Definition ArchSpec.h:98
@ eRISCV_float_abi_soft
RVC, +c.
Definition ArchSpec.h:96
@ eRISCV_float_abi_quad
double precision floating point, +d
Definition ArchSpec.h:99
@ eRISCV_float_abi_mask
quad precision floating point, +q
Definition ArchSpec.h:100
@ eRISCV_float_abi_single
soft float
Definition ArchSpec.h:97
Generic representation of a type in a programming language.
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
A file utility class.
Definition FileSpec.h:56
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:380
bool Test(ValueType bit) const
Test a single flag bit.
Definition Flags.h:96
Linux specific set of Unix signals.
static void Terminate()
Definition Platform.cpp:154
static void SetHostPlatform(const lldb::PlatformSP &platform_sp)
Definition Platform.cpp:161
virtual void GetStatus(Stream &strm)
Report the current status for this platform.
Definition Platform.cpp:353
static void Initialize()
Definition Platform.cpp:152
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:556
std::vector< std::string > m_trap_handlers
Definition Platform.h:1089
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)
CompilerType CreateStructForIdentifier(llvm::StringRef type_name, const std::initializer_list< std::pair< const char *, CompilerType > > &type_fields, bool packed=false)
CompilerType CreateRecordType(clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, llvm::StringRef name, int kind, lldb::LanguageType language, std::optional< ClangASTMetadata > metadata=std::nullopt, bool exports_symbols=false)
static bool CompleteTagDeclarationDefinition(const CompilerType &type)
static bool StartTagDeclarationDefinition(const CompilerType &type)
static clang::FieldDecl * AddFieldToRecordType(const CompilerType &type, llvm::StringRef name, const CompilerType &field_type, uint32_t bitfield_bit_size)
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
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
lldb::UnwindPlanSP GetTrapHandlerUnwindPlan(const ArchSpec &arch, llvm::StringRef name) override
Try to get a specific unwind plan for a named trap handler.
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:338
llvm::SmallVector< lldb::addr_t, 6 > MmapArgList
Definition Platform.h:68
@ 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