//===-- PlatformLinux.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "PlatformLinux.h"
#include "lldb/Host/Config.h"

#include <cstdio>
#if LLDB_ENABLE_POSIX
#include <sys/utsname.h>
#endif

#include "Plugins/Process/Utility/LinuxSignals.h"
#include "Register/Arch/lldb-riscv-register-enums.h"
#include "Utility/ARM64_DWARF_Registers.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"

// Define these constants from Linux mman.h for use when targeting remote linux
// systems even when host has different values.
#define MAP_PRIVATE 2
#define MAP_ANON 0x20

// For other platforms that use platform linux
#ifndef SIGILL
#define SIGILL 4
#endif
#ifndef SIGBUS
#define SIGBUS 7
#endif
#ifndef SIGFPE
#define SIGFPE 8
#endif
#ifndef SIGSEGV
#define SIGSEGV 11
#endif

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::platform_linux;

LLDB_PLUGIN_DEFINE(PlatformLinux)

static uint32_t g_initialize_count = 0;


PlatformSP PlatformLinux::CreateInstance(bool force, const ArchSpec *arch) {
  Log *log = GetLog(LLDBLog::Platform);
  LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,
           arch ? arch->GetArchitectureName() : "<null>",
           arch ? arch->GetTriple().getTriple() : "<null>");

  bool create = force;
  if (!create && arch && arch->IsValid()) {
    const llvm::Triple &triple = arch->GetTriple();
    switch (triple.getOS()) {
    case llvm::Triple::Linux:
      create = true;
      break;

#if defined(__linux__)
    // Only accept "unknown" for the OS if the host is linux and it "unknown"
    // wasn't specified (it was just returned because it was NOT specified)
    case llvm::Triple::OSType::UnknownOS:
      create = !arch->TripleOSWasSpecified();
      break;
#endif
    default:
      break;
    }
  }

  LLDB_LOG(log, "create = {0}", create);
  if (create) {
    return PlatformSP(new PlatformLinux(false));
  }
  return PlatformSP();
}

llvm::StringRef PlatformLinux::GetPluginDescriptionStatic(bool is_host) {
  if (is_host)
    return "Local Linux user platform plug-in.";
  return "Remote Linux user platform plug-in.";
}

void PlatformLinux::Initialize() {
  PlatformPOSIX::Initialize();

  if (g_initialize_count++ == 0) {
#if defined(__linux__) && !defined(__ANDROID__)
    PlatformSP default_platform_sp(new PlatformLinux(true));
    default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
    Platform::SetHostPlatform(default_platform_sp);
#endif
    PluginManager::RegisterPlugin(
        PlatformLinux::GetPluginNameStatic(false),
        PlatformLinux::GetPluginDescriptionStatic(false),
        PlatformLinux::CreateInstance, nullptr);
  }
}

void PlatformLinux::Terminate() {
  if (g_initialize_count > 0) {
    if (--g_initialize_count == 0) {
      PluginManager::UnregisterPlugin(PlatformLinux::CreateInstance);
    }
  }

  PlatformPOSIX::Terminate();
}

/// Default Constructor
PlatformLinux::PlatformLinux(bool is_host)
    : PlatformPOSIX(is_host) // This is the local host platform
{
  if (is_host) {
    ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
    m_supported_architectures.push_back(hostArch);
    if (hostArch.GetTriple().isArch64Bit()) {
      m_supported_architectures.push_back(
          HostInfo::GetArchitecture(HostInfo::eArchKind32));
    }
  } else {
    m_supported_architectures = CreateArchList(
        {llvm::Triple::x86_64, llvm::Triple::x86, llvm::Triple::arm,
         llvm::Triple::aarch64, llvm::Triple::mips64, llvm::Triple::mips64,
         llvm::Triple::hexagon, llvm::Triple::mips, llvm::Triple::mips64el,
         llvm::Triple::mipsel, llvm::Triple::msp430, llvm::Triple::systemz,
         llvm::Triple::loongarch64, llvm::Triple::ppc64le,
         llvm::Triple::riscv64},
        llvm::Triple::Linux);
  }
}

std::vector<ArchSpec>
PlatformLinux::GetSupportedArchitectures(const ArchSpec &process_host_arch) {
  if (m_remote_platform_sp)
    return m_remote_platform_sp->GetSupportedArchitectures(process_host_arch);
  return m_supported_architectures;
}

void PlatformLinux::GetStatus(Stream &strm) {
  Platform::GetStatus(strm);

#if LLDB_ENABLE_POSIX
  // Display local kernel information only when we are running in host mode.
  // Otherwise, we would end up printing non-Linux information (when running on
  // Mac OS for example).
  if (IsHost()) {
    struct utsname un;

    if (uname(&un))
      return;

    strm.Printf("    Kernel: %s\n", un.sysname);
    strm.Printf("   Release: %s\n", un.release);
    strm.Printf("   Version: %s\n", un.version);
  }
#endif
}

uint32_t
PlatformLinux::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {
  uint32_t resume_count = 0;

  // Always resume past the initial stop when we use eLaunchFlagDebug
  if (launch_info.GetFlags().Test(eLaunchFlagDebug)) {
    // Resume past the stop for the final exec into the true inferior.
    ++resume_count;
  }

  // If we're not launching a shell, we're done.
  const FileSpec &shell = launch_info.GetShell();
  if (!shell)
    return resume_count;

  std::string shell_string = shell.GetPath();
  // We're in a shell, so for sure we have to resume past the shell exec.
  ++resume_count;

  // Figure out what shell we're planning on using.
  const char *shell_name = strrchr(shell_string.c_str(), '/');
  if (shell_name == nullptr)
    shell_name = shell_string.c_str();
  else
    shell_name++;

  if (strcmp(shell_name, "csh") == 0 || strcmp(shell_name, "tcsh") == 0 ||
      strcmp(shell_name, "zsh") == 0 || strcmp(shell_name, "sh") == 0) {
    // These shells seem to re-exec themselves.  Add another resume.
    ++resume_count;
  }

  return resume_count;
}

bool PlatformLinux::CanDebugProcess() {
  if (IsHost()) {
    return true;
  } else {
    // If we're connected, we can debug.
    return IsConnected();
  }
}

void PlatformLinux::CalculateTrapHandlerSymbolNames() {
  m_trap_handlers.push_back("_sigtramp");
  m_trap_handlers.push_back("__kernel_rt_sigreturn");
  m_trap_handlers.push_back("__restore_rt");
  m_trap_handlers.push_back("__vdso_rt_sigreturn");
}

static lldb::UnwindPlanSP
GetAArch64TrapHandlerUnwindPlan(llvm::StringRef name) {
  UnwindPlanSP unwind_plan_sp;
  if (name != "__kernel_rt_sigreturn")
    return unwind_plan_sp;

  UnwindPlan::Row row;

  // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
  //  - 128-byte siginfo struct
  //  - ucontext struct:
  //     - 8-byte long (uc_flags)
  //     - 8-byte pointer (uc_link)
  //     - 24-byte stack_t
  //     - 128-byte signal set
  //     - 8 bytes of padding because sigcontext has 16-byte alignment
  //     - sigcontext/mcontext_t
  // [1]
  // https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/signal.c
  int32_t offset = 128 + 8 + 8 + 24 + 128 + 8;
  // Then sigcontext[2] is:
  // - 8 byte fault address
  // - 31 8 byte registers
  // - 8 byte sp
  // - 8 byte pc
  // [2]
  // https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/sigcontext.h

  // Skip fault address
  offset += 8;
  row.GetCFAValue().SetIsRegisterPlusOffset(arm64_dwarf::sp, offset);

  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x0, 0 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x1, 1 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x2, 2 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x3, 3 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x4, 4 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x5, 5 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x6, 6 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x7, 7 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x8, 8 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x9, 9 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x10, 10 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x11, 11 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x12, 12 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x13, 13 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x14, 14 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x15, 15 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x16, 16 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x17, 17 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x18, 18 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x19, 19 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x20, 20 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x21, 21 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x22, 22 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x23, 23 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x24, 24 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x25, 25 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x26, 26 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x27, 27 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x28, 28 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::fp, 29 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x30, 30 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::sp, 31 * 8, false);
  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::pc, 32 * 8, false);

  // The sigcontext may also contain floating point and SVE registers.
  // However this would require a dynamic unwind plan so they are not included
  // here.

  unwind_plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
  unwind_plan_sp->AppendRow(std::move(row));
  unwind_plan_sp->SetSourceName("AArch64 Linux sigcontext");
  unwind_plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
  // Because sp is the same throughout the function
  unwind_plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
  unwind_plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolYes);

  return unwind_plan_sp;
}

static lldb::UnwindPlanSP GetRISCVTrapHandlerUnwindPlan(llvm::StringRef name,
                                                        uint32_t fp_flags) {
  if (name != "__vdso_rt_sigreturn")
    return {};

  UnwindPlan::Row row;

  // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
  //  - 128-byte siginfo struct
  //  - ucontext struct:
  //     - 8-byte long (uc_flags)
  //     - 8-byte pointer (*uc_link)
  //     - 24-byte struct (uc_stack)
  //     - 8-byte struct (uc_sigmask)
  //     - 120-byte of padding to allow sigset_t to be expanded in the future
  //     - 8 bytes of padding because sigcontext has 16-byte alignment
  //     - struct sigcontext uc_mcontext
  // [1]
  // https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/signal.c

  constexpr size_t siginfo_size = 128;
  constexpr size_t uc_flags_size = 8;
  constexpr size_t uc_link_ptr_size = 8;
  constexpr size_t uc_stack_size = 24;
  constexpr size_t uc_sigmask_size = 8;
  constexpr size_t padding_size = 128;

  constexpr size_t offset = siginfo_size + uc_flags_size + uc_link_ptr_size +
                            uc_stack_size + uc_sigmask_size + padding_size;

  // In user_regs_struct GPRs are always 64-bit length
  size_t gpr_size = 8;
  row.GetCFAValue().SetIsRegisterPlusOffset(gpr_sp_riscv, offset);
  for (uint32_t reg_num = gpr_first_riscv; reg_num < gpr_first_riscv + 32;
       ++reg_num)
    row.SetRegisterLocationToAtCFAPlusOffset(reg_num, reg_num * gpr_size,
                                             false);

  size_t fpr_size = 0;
  switch (fp_flags) {
  case ArchSpec::eRISCV_float_abi_soft:
    fpr_size = 0;
    break;
  case ArchSpec::eRISCV_float_abi_single:
    fpr_size = 4;
    break;
  case ArchSpec::eRISCV_float_abi_double:
    fpr_size = 8;
    break;
  case ArchSpec::eRISCV_float_abi_quad:
    fpr_size = 16;
    break;
  }

  if (fpr_size != 0) {
    for (uint32_t reg_num = fpr_first_riscv; reg_num < fpr_first_riscv + 32;
         ++reg_num) {
      size_t fpr_offset =
          gpr_size * 32 + (reg_num - fpr_first_riscv) * fpr_size;
      row.SetRegisterLocationToAtCFAPlusOffset(reg_num, fpr_offset, false);
    }

    size_t fpr_fcsr_offset = gpr_size * 32 + fpr_size * 32;
    row.SetRegisterLocationToAtCFAPlusOffset(fpr_fcsr_riscv, fpr_fcsr_offset,
                                             false);
  }

  UnwindPlanSP unwind_plan_sp = std::make_shared<UnwindPlan>(eRegisterKindLLDB);
  unwind_plan_sp->AppendRow(std::move(row));
  unwind_plan_sp->SetSourceName("RISC-V Linux sigcontext");
  unwind_plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
  unwind_plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
  unwind_plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolYes);

  return unwind_plan_sp;
}

lldb::UnwindPlanSP
PlatformLinux::GetTrapHandlerUnwindPlan(const ArchSpec &arch,
                                        llvm::StringRef name) {
  llvm::Triple triple = arch.GetTriple();
  if (triple.isAArch64())
    return GetAArch64TrapHandlerUnwindPlan(name);
  if (triple.isRISCV()) {
    uint32_t fp_flags = arch.GetFlags() & ArchSpec::eRISCV_float_abi_mask;
    return GetRISCVTrapHandlerUnwindPlan(name, fp_flags);
  }
  return {};
}

MmapArgList PlatformLinux::GetMmapArgumentList(const ArchSpec &arch,
                                               addr_t addr, addr_t length,
                                               unsigned prot, unsigned flags,
                                               addr_t fd, addr_t offset) {
  uint64_t flags_platform = 0;
  uint64_t map_anon = arch.IsMIPS() ? 0x800 : MAP_ANON;

  if (flags & eMmapFlagsPrivate)
    flags_platform |= MAP_PRIVATE;
  if (flags & eMmapFlagsAnon)
    flags_platform |= map_anon;

  MmapArgList args({addr, length, prot, flags_platform, fd, offset});
  return args;
}

CompilerType PlatformLinux::GetSiginfoType(const llvm::Triple &triple) {
  {
    std::lock_guard<std::mutex> guard(m_mutex);
    if (!m_type_system)
      m_type_system = std::make_shared<TypeSystemClang>("siginfo", triple);
  }
  TypeSystemClang *ast = m_type_system.get();

  bool si_errno_then_code = true;

  switch (triple.getArch()) {
  case llvm::Triple::mips:
  case llvm::Triple::mipsel:
  case llvm::Triple::mips64:
  case llvm::Triple::mips64el:
    // mips has si_code and si_errno swapped
    si_errno_then_code = false;
    break;
  default:
    break;
  }

  // generic types
  CompilerType int_type = ast->GetBasicType(eBasicTypeInt);
  CompilerType uint_type = ast->GetBasicType(eBasicTypeUnsignedInt);
  CompilerType short_type = ast->GetBasicType(eBasicTypeShort);
  CompilerType long_type = ast->GetBasicType(eBasicTypeLong);
  CompilerType voidp_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();

  // platform-specific types
  CompilerType &pid_type = int_type;
  CompilerType &uid_type = uint_type;
  CompilerType &clock_type = long_type;
  CompilerType &band_type = long_type;

  CompilerType sigval_type = ast->CreateRecordType(
      nullptr, OptionalClangModuleID(), "__lldb_sigval_t",
      llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
  ast->StartTagDeclarationDefinition(sigval_type);
  ast->AddFieldToRecordType(sigval_type, "sival_int", int_type, 0);
  ast->AddFieldToRecordType(sigval_type, "sival_ptr", voidp_type, 0);
  ast->CompleteTagDeclarationDefinition(sigval_type);

  CompilerType sigfault_bounds_type = ast->CreateRecordType(
      nullptr, OptionalClangModuleID(), "",
      llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
  ast->StartTagDeclarationDefinition(sigfault_bounds_type);
  ast->AddFieldToRecordType(
      sigfault_bounds_type, "_addr_bnd",
      ast->CreateStructForIdentifier(llvm::StringRef(),
                                     {
                                         {"_lower", voidp_type},
                                         {"_upper", voidp_type},
                                     }),
      0);
  ast->AddFieldToRecordType(sigfault_bounds_type, "_pkey", uint_type, 0);
  ast->CompleteTagDeclarationDefinition(sigfault_bounds_type);

  // siginfo_t
  CompilerType siginfo_type = ast->CreateRecordType(
      nullptr, OptionalClangModuleID(), "__lldb_siginfo_t",
      llvm::to_underlying(clang::TagTypeKind::Struct), lldb::eLanguageTypeC);
  ast->StartTagDeclarationDefinition(siginfo_type);
  ast->AddFieldToRecordType(siginfo_type, "si_signo", int_type, 0);

  if (si_errno_then_code) {
    ast->AddFieldToRecordType(siginfo_type, "si_errno", int_type, 0);
    ast->AddFieldToRecordType(siginfo_type, "si_code", int_type, 0);
  } else {
    ast->AddFieldToRecordType(siginfo_type, "si_code", int_type, 0);
    ast->AddFieldToRecordType(siginfo_type, "si_errno", int_type, 0);
  }

  // the structure is padded on 64-bit arches to fix alignment
  if (triple.isArch64Bit())
    ast->AddFieldToRecordType(siginfo_type, "__pad0", int_type, 0);

  // union used to hold the signal data
  CompilerType union_type = ast->CreateRecordType(
      nullptr, OptionalClangModuleID(), "",
      llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
  ast->StartTagDeclarationDefinition(union_type);

  ast->AddFieldToRecordType(
      union_type, "_kill",
      ast->CreateStructForIdentifier(llvm::StringRef(),
                                     {
                                         {"si_pid", pid_type},
                                         {"si_uid", uid_type},
                                     }),
      0);

  ast->AddFieldToRecordType(
      union_type, "_timer",
      ast->CreateStructForIdentifier(llvm::StringRef(),
                                     {
                                         {"si_tid", int_type},
                                         {"si_overrun", int_type},
                                         {"si_sigval", sigval_type},
                                     }),
      0);

  ast->AddFieldToRecordType(
      union_type, "_rt",
      ast->CreateStructForIdentifier(llvm::StringRef(),
                                     {
                                         {"si_pid", pid_type},
                                         {"si_uid", uid_type},
                                         {"si_sigval", sigval_type},
                                     }),
      0);

  ast->AddFieldToRecordType(
      union_type, "_sigchld",
      ast->CreateStructForIdentifier(llvm::StringRef(),
                                     {
                                         {"si_pid", pid_type},
                                         {"si_uid", uid_type},
                                         {"si_status", int_type},
                                         {"si_utime", clock_type},
                                         {"si_stime", clock_type},
                                     }),
      0);

  ast->AddFieldToRecordType(
      union_type, "_sigfault",
      ast->CreateStructForIdentifier(llvm::StringRef(),
                                     {
                                         {"si_addr", voidp_type},
                                         {"si_addr_lsb", short_type},
                                         {"_bounds", sigfault_bounds_type},
                                     }),
      0);

  ast->AddFieldToRecordType(
      union_type, "_sigpoll",
      ast->CreateStructForIdentifier(llvm::StringRef(),
                                     {
                                         {"si_band", band_type},
                                         {"si_fd", int_type},
                                     }),
      0);

  // NB: SIGSYS is not present on ia64 but we don't seem to support that
  ast->AddFieldToRecordType(
      union_type, "_sigsys",
      ast->CreateStructForIdentifier(llvm::StringRef(),
                                     {
                                         {"_call_addr", voidp_type},
                                         {"_syscall", int_type},
                                         {"_arch", uint_type},
                                     }),
      0);

  ast->CompleteTagDeclarationDefinition(union_type);
  ast->AddFieldToRecordType(siginfo_type, "_sifields", union_type, 0);

  ast->CompleteTagDeclarationDefinition(siginfo_type);
  return siginfo_type;
}

static std::string GetDescriptionFromSiginfo(lldb::ValueObjectSP siginfo_sp) {
  if (!siginfo_sp)
    return "";

  lldb_private::LinuxSignals linux_signals;
  int code = siginfo_sp->GetChildMemberWithName("si_code")->GetValueAsSigned(0);
  int signo =
      siginfo_sp->GetChildMemberWithName("si_signo")->GetValueAsSigned(-1);

  auto sifields = siginfo_sp->GetChildMemberWithName("_sifields");
  if (!sifields)
    return linux_signals.GetSignalDescription(signo, code);

  // declare everything that we can populate later.
  std::optional<lldb::addr_t> addr;
  std::optional<lldb::addr_t> upper;
  std::optional<lldb::addr_t> lower;
  std::optional<uint32_t> pid;
  std::optional<uint32_t> uid;

  // The negative si_codes are special and mean this signal was sent from user
  // space not the kernel. These take precedence because they break some of the
  // invariants around kernel sent signals. Such as SIGSEGV won't have an
  // address.
  if (code < 0) {
    auto sikill = sifields->GetChildMemberWithName("_kill");
    if (sikill) {
      auto pid_sp = sikill->GetChildMemberWithName("si_pid");
      if (pid_sp)
        pid = pid_sp->GetValueAsUnsigned(-1);
      auto uid_sp = sikill->GetChildMemberWithName("si_uid");
      if (uid_sp)
        uid = uid_sp->GetValueAsUnsigned(-1);
    }
  } else {

    switch (signo) {
    case SIGILL:
    case SIGFPE:
    case SIGBUS: {
      auto sigfault = sifields->GetChildMemberWithName("_sigfault");
      if (!sigfault)
        break;

      auto addr_sp = sigfault->GetChildMemberWithName("si_addr");
      if (addr_sp)
        addr = addr_sp->GetValueAsUnsigned(-1);
      break;
    }
    case SIGSEGV: {
      auto sigfault = sifields->GetChildMemberWithName("_sigfault");
      if (!sigfault)
        break;

      auto addr_sp = sigfault->GetChildMemberWithName("si_addr");
      if (addr_sp)
        addr = addr_sp->GetValueAsUnsigned(-1);

      auto bounds_sp = sigfault->GetChildMemberWithName("_bounds");
      if (!bounds_sp)
        break;

      auto addr_bnds_sp = bounds_sp->GetChildMemberWithName("_addr_bnd");
      if (!addr_bnds_sp)
        break;

      auto lower_sp = addr_bnds_sp->GetChildMemberWithName("_lower");
      if (lower_sp)
        lower = lower_sp->GetValueAsUnsigned(-1);

      auto upper_sp = addr_bnds_sp->GetChildMemberWithName("_upper");
      if (upper_sp)
        upper = upper_sp->GetValueAsUnsigned(-1);

      break;
    }
    default:
      break;
    }
  }

  return linux_signals.GetSignalDescription(signo, code, addr, lower, upper,
                                            pid, uid);
}

lldb::StopInfoSP PlatformLinux::GetStopInfoFromSiginfo(Thread &thread) {
  ValueObjectSP siginfo_sp = thread.GetSiginfoValue();
  if (!siginfo_sp)
    return {};
  auto signo_sp = siginfo_sp->GetChildMemberWithName("si_signo");
  auto sicode_sp = siginfo_sp->GetChildMemberWithName("si_code");
  if (!signo_sp || !sicode_sp)
    return {};

  std::string siginfo_description = GetDescriptionFromSiginfo(siginfo_sp);
  if (siginfo_description.empty())
    return StopInfo::CreateStopReasonWithSignal(
        thread, signo_sp->GetValueAsUnsigned(-1));

  return StopInfo::CreateStopReasonWithSignal(
      thread, signo_sp->GetValueAsUnsigned(-1), siginfo_description.c_str(),
      sicode_sp->GetValueAsUnsigned(0));
}
