Beispiel #1
0
// Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
static void
ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
                     ArchSpec &arch)
{
    lldb::offset_t offset = 0;
    bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
                 arch.GetMachine() == llvm::Triple::mips64 ||
                 arch.GetMachine() == llvm::Triple::ppc64 ||
                 arch.GetMachine() == llvm::Triple::x86_64);
    int pr_version = data.GetU32(&offset);

    Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
    if (log)
    {
        if (pr_version > 1)
            log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version);
    }

    // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
    if (lp64)
        offset += 32;
    else
        offset += 16;

    thread_data.signo = data.GetU32(&offset); // pr_cursig
    thread_data.tid = data.GetU32(&offset); // pr_pid
    if (lp64)
        offset += 4;

    size_t len = data.GetByteSize() - offset;
    thread_data.gpregset = DataExtractor(data, offset, len);
}
Beispiel #2
0
RegisterContextSP
ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) {
  RegisterContextSP reg_ctx_sp;
  uint32_t concrete_frame_idx = 0;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));

  if (frame)
    concrete_frame_idx = frame->GetConcreteFrameIndex();

  if (concrete_frame_idx == 0) {
    if (m_thread_reg_ctx_sp)
      return m_thread_reg_ctx_sp;

    ProcessMinidump *process =
        static_cast<ProcessMinidump *>(GetProcess().get());
    ArchSpec arch = process->GetArchitecture();
    RegisterInfoInterface *reg_interface = nullptr;

    // TODO write other register contexts and add them here
    switch (arch.GetMachine()) {
    case llvm::Triple::x86: {
      reg_interface = new RegisterContextLinux_i386(arch);
      lldb::DataBufferSP buf =
          ConvertMinidumpContext_x86_32(m_gpregset_data, reg_interface);
      DataExtractor gpregs(buf, lldb::eByteOrderLittle, 4);
      DataExtractor fpregs;
      m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
          *this, reg_interface, gpregs, fpregs));
      break;
    }
    case llvm::Triple::x86_64: {
      reg_interface = new RegisterContextLinux_x86_64(arch);
      lldb::DataBufferSP buf =
          ConvertMinidumpContext_x86_64(m_gpregset_data, reg_interface);
      DataExtractor gpregs(buf, lldb::eByteOrderLittle, 8);
      DataExtractor fpregs;
      m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
          *this, reg_interface, gpregs, fpregs));
      break;
    }
    default:
      break;
    }

    if (!reg_interface) {
      if (log)
        log->Printf("elf-core::%s:: Architecture(%d) not supported",
                    __FUNCTION__, arch.GetMachine());
      assert(false && "Architecture not supported");
    }

    reg_ctx_sp = m_thread_reg_ctx_sp;
  } else if (m_unwinder_ap) {
    reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame);
  }

  return reg_ctx_sp;
}
Beispiel #3
0
unsigned
POSIXThread::GetRegisterIndexFromOffset(unsigned offset)
{
    unsigned reg = LLDB_INVALID_REGNUM;
    ArchSpec arch = HostInfo::GetArchitecture();

    switch (arch.GetMachine())
    {
    default:
        llvm_unreachable("CPU type not supported!");
        break;

    case llvm::Triple::aarch64:
    case llvm::Triple::arm:
    case llvm::Triple::mips64:
    case llvm::Triple::ppc:
    case llvm::Triple::ppc64:
    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
        {
            POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
            reg = reg_ctx->GetRegisterIndexFromOffset(offset);
        }
        break;
    }
    return reg;
}
Beispiel #4
0
size_t
PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target, 
                                                BreakpointSite *bp_site)
{
    ArchSpec arch = target.GetArchitecture();
    const uint8_t *trap_opcode = NULL;
    size_t trap_opcode_size = 0;

    switch (arch.GetMachine())
    {
    default:
        assert(false && "CPU type not supported!");
        break;
            
    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
        {
            static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };
            trap_opcode = g_i386_breakpoint_opcode;
            trap_opcode_size = sizeof(g_i386_breakpoint_opcode);
        }
        break;
    case llvm::Triple::hexagon:
        return 0;
    }

    if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
        return trap_opcode_size;
    return 0;
}
Beispiel #5
0
// Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
static void
ParseFreeBSDPrStatus(ThreadData *thread_data, DataExtractor &data,
                     ArchSpec &arch)
{
    lldb::offset_t offset = 0;
    bool have_padding = (arch.GetMachine() == llvm::Triple::mips64 ||
                         arch.GetMachine() == llvm::Triple::x86_64);
    int pr_version = data.GetU32(&offset);

    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
    if (log)
    {
        if (pr_version > 1)
            log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version);
    }

    if (have_padding)
        offset += 4;
    offset += 28;       // pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
    thread_data->signo = data.GetU32(&offset); // pr_cursig
    offset += 4;        // pr_pid
    if (have_padding)
        offset += 4;
    
    size_t len = data.GetByteSize() - offset;
    thread_data->gpregset = DataExtractor(data, offset, len);
}
size_t
ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
{
    static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xD4 };
    static const uint8_t g_i386_opcode[] = { 0xCC };

    ArchSpec arch = GetTarget().GetArchitecture();
    const uint8_t *opcode = NULL;
    size_t opcode_size = 0;

    switch (arch.GetMachine())
    {
    default:
        assert(false && "CPU type not supported!");
        break;

    case llvm::Triple::aarch64:
        opcode = g_aarch64_opcode;
        opcode_size = sizeof(g_aarch64_opcode);
        break;

    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
        opcode = g_i386_opcode;
        opcode_size = sizeof(g_i386_opcode);
        break;
    }

    bp_site->SetTrapOpcode(opcode, opcode_size);
    return opcode_size;
}
Beispiel #7
0
size_t
PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
{
    ArchSpec arch = target.GetArchitecture();
    const uint8_t *trap_opcode = NULL;
    size_t trap_opcode_size = 0;

    switch (arch.GetMachine())
    {
    default:
        llvm_unreachable("Unhandled architecture in PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode()");
        break;
    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
        {
            static const uint8_t g_i386_opcode[] = { 0xCC };
            trap_opcode = g_i386_opcode;
            trap_opcode_size = sizeof(g_i386_opcode);
        }
        break;
    }

    if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
        return trap_opcode_size;

    return 0;
}
RegisterContextSP
TargetThreadWindowsLive::CreateRegisterContextForFrameIndex(uint32_t idx) {
  if (!m_reg_context_sp) {
    ArchSpec arch = HostInfo::GetArchitecture();
    switch (arch.GetMachine()) {
    case llvm::Triple::x86:
#if defined(_WIN64)
// FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
#else
      m_reg_context_sp.reset(new RegisterContextWindowsLive_x86(*this, idx));
#endif
      break;
    case llvm::Triple::x86_64:
#if defined(_WIN64)
      m_reg_context_sp.reset(new RegisterContextWindowsLive_x64(*this, idx));
#else
// LLDB is 32-bit, but the target process is 64-bit.  We probably can't debug
// this.
#endif
    default:
      break;
    }
  }
  return m_reg_context_sp;
}
size_t
ProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
{
    static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xD4 };
    static const uint8_t g_i386_opcode[] = { 0xCC };

    ArchSpec arch = GetTarget().GetArchitecture();
    const uint8_t *opcode = NULL;
    size_t opcode_size = 0;

    switch (arch.GetMachine())
    {
    default:
        assert(false && "CPU type not supported!");
        break;

    case llvm::Triple::arm:
        {
            // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
            // but the linux kernel does otherwise.
            static const uint8_t g_arm_breakpoint_opcode[] = { 0xf0, 0x01, 0xf0, 0xe7 };
            static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde };

            lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
            AddressClass addr_class = eAddressClassUnknown;

            if (bp_loc_sp)
                addr_class = bp_loc_sp->GetAddress ().GetAddressClass ();

            if (addr_class == eAddressClassCodeAlternateISA
                || (addr_class == eAddressClassUnknown
                    && bp_loc_sp->GetAddress().GetOffset() & 1))
            {
                opcode = g_thumb_breakpoint_opcode;
                opcode_size = sizeof(g_thumb_breakpoint_opcode);
            }
            else
            {
                opcode = g_arm_breakpoint_opcode;
                opcode_size = sizeof(g_arm_breakpoint_opcode);
            }
        }
        break;
    case llvm::Triple::aarch64:
        opcode = g_aarch64_opcode;
        opcode_size = sizeof(g_aarch64_opcode);
        break;

    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
        opcode = g_i386_opcode;
        opcode_size = sizeof(g_i386_opcode);
        break;
    }

    bp_site->SetTrapOpcode(opcode, opcode_size);
    return opcode_size;
}
static uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch) {
  switch (target_arch.GetMachine()) {
  case llvm::Triple::systemz:
    return k_num_user_registers_s390x + k_num_linux_registers_s390x;
  default:
    assert(false && "Unhandled target architecture.");
    return 0;
  }
}
static uint32_t
GetRegisterInfoCount (const ArchSpec &target_arch)
{
    switch (target_arch.GetMachine())
    {
        case llvm::Triple::mips64:
        case llvm::Triple::mips64el:
            return static_cast<uint32_t> (sizeof (g_register_infos_mips64) / sizeof (g_register_infos_mips64 [0]));
        default:
            assert(false && "Unhandled target architecture.");
            return 0;
    }
}
static uint32_t
GetUserRegisterInfoCount (const ArchSpec &target_arch)
{
    switch (target_arch.GetMachine())
    {
        case llvm::Triple::x86:
            return static_cast<uint32_t> (k_num_user_registers_i386);
        case llvm::Triple::x86_64:
            return static_cast<uint32_t> (k_num_user_registers_x86_64);
        default:
            assert(false && "Unhandled target architecture.");
            return 0;
    }
}
NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64 (const ArchSpec& target_arch,
                                                                      NativeThreadProtocol &native_thread, 
                                                                      uint32_t concrete_frame_idx) :
    NativeRegisterContextLinux (native_thread, concrete_frame_idx, CreateRegisterInfoInterface(target_arch))
{
    switch (target_arch.GetMachine ())
    {
        case llvm::Triple::mips:
        case llvm::Triple::mipsel:
            m_reg_info.num_registers        = k_num_registers_mips;
            m_reg_info.num_gpr_registers    = k_num_gpr_registers_mips;
            m_reg_info.num_fpr_registers    = k_num_fpr_registers_mips;
            m_reg_info.last_gpr             = k_last_gpr_mips;
            m_reg_info.first_fpr            = k_first_fpr_mips;
            m_reg_info.last_fpr             = k_last_fpr_mips;
            m_reg_info.first_msa            = k_first_msa_mips;
            m_reg_info.last_msa             = k_last_msa_mips;
            break;
        case llvm::Triple::mips64:
        case llvm::Triple::mips64el:
            m_reg_info.num_registers        = k_num_registers_mips64;
            m_reg_info.num_gpr_registers    = k_num_gpr_registers_mips64;
            m_reg_info.num_fpr_registers    = k_num_fpr_registers_mips64;
            m_reg_info.last_gpr             = k_last_gpr_mips64;
            m_reg_info.first_fpr            = k_first_fpr_mips64;
            m_reg_info.last_fpr             = k_last_fpr_mips64;
            m_reg_info.first_msa            = k_first_msa_mips64;
            m_reg_info.last_msa             = k_last_msa_mips64;
            break;
        default:
            assert(false && "Unhandled target architecture.");
            break;
    }

    // Initialize m_iovec to point to the buffer and buffer size
    // using the conventions of Berkeley style UIO structures, as required
    // by PTRACE extensions.
    m_iovec.iov_base = &m_msa;
    m_iovec.iov_len = sizeof(MSA_linux_mips);

    // init h/w watchpoint addr map
    for (int index = 0;index <= MAX_NUM_WP; index++)
        hw_addr_map[index] = LLDB_INVALID_ADDRESS;

    ::memset(&m_gpr, 0, sizeof(GPR_linux_mips));
    ::memset(&m_fpr, 0, sizeof(FPR_linux_mips));
    ::memset(&m_msa, 0, sizeof(MSA_linux_mips));
}
static uint32_t
GetRegisterInfoCount (const ArchSpec &target_arch)
{
    switch (target_arch.GetMachine())
    {
        case llvm::Triple::x86:
            {
                assert (!GetPrivateRegisterInfoVector ().empty () && "i386 register info not yet filled.");
                return static_cast<uint32_t> (GetPrivateRegisterInfoVector ().size ());
            }
        case llvm::Triple::x86_64:
            return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
        default:
            assert(false && "Unhandled target architecture.");
            return 0;
    }
}
Beispiel #15
0
Unwind *
ThreadGDBRemote::GetUnwinder ()
{
    if (m_unwinder_ap.get() == NULL)
    {
        const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ());
        const llvm::Triple::ArchType machine = target_arch.GetMachine();
        if (machine == llvm::Triple::x86_64 || machine == llvm::Triple::x86)
        {
            m_unwinder_ap.reset (new UnwindLLDB (*this));
        }
#if defined(__APPLE__)
        else
        {
            m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this));
        }
#endif
    }
    return m_unwinder_ap.get();
}
Beispiel #16
0
const char *FreeBSDThread::GetRegisterName(unsigned reg) {
  const char *name = nullptr;
  ArchSpec arch = HostInfo::GetArchitecture();

  switch (arch.GetMachine()) {
  default:
    assert(false && "CPU type not supported!");
    break;

  case llvm::Triple::aarch64:
  case llvm::Triple::arm:
  case llvm::Triple::mips64:
  case llvm::Triple::ppc:
  case llvm::Triple::ppc64:
  case llvm::Triple::x86:
  case llvm::Triple::x86_64:
    name = GetRegisterContext()->GetRegisterName(reg);
    break;
  }
  return name;
}
NativeRegisterContextLinux_s390x::NativeRegisterContextLinux_s390x(
    const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
    uint32_t concrete_frame_idx)
    : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
                                 CreateRegisterInfoInterface(target_arch)) {
  // Set up data about ranges of valid registers.
  switch (target_arch.GetMachine()) {
  case llvm::Triple::systemz:
    m_reg_info.num_registers = k_num_registers_s390x;
    m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
    m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
    m_reg_info.last_gpr = k_last_gpr_s390x;
    m_reg_info.first_fpr = k_first_fpr_s390x;
    m_reg_info.last_fpr = k_last_fpr_s390x;
    break;
  default:
    assert(false && "Unhandled target architecture.");
    break;
  }

  // Clear out the watchpoint state.
  m_watchpoint_addr = LLDB_INVALID_ADDRESS;
}
RegisterContextSP
ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
{
    RegisterContextSP reg_ctx_sp;
    uint32_t concrete_frame_idx = 0;
    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));

    if (frame)
        concrete_frame_idx = frame->GetConcreteFrameIndex ();

    if (concrete_frame_idx == 0)
    {
        if (m_thread_reg_ctx_sp)
            return m_thread_reg_ctx_sp;

        ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
        ArchSpec arch = process->GetArchitecture();
        RegisterInfoInterface *reg_interface = NULL;

        switch (arch.GetTriple().getOS())
        {
            case llvm::Triple::FreeBSD:
            {
                switch (arch.GetMachine())
                {
                    case llvm::Triple::mips64:
                        reg_interface = new RegisterContextFreeBSD_mips64(arch);
                        break;
                    case llvm::Triple::x86:
                        reg_interface = new RegisterContextFreeBSD_i386(arch);
                        break;
                    case llvm::Triple::x86_64:
                        reg_interface = new RegisterContextFreeBSD_x86_64(arch);
                        break;
                    default:
                        break;
                }
                break;
            }
 
            case llvm::Triple::Linux:
            {
                switch (arch.GetMachine())
                {
                    case llvm::Triple::x86_64:
                        reg_interface = new RegisterContextLinux_x86_64(arch);
                        break;
                    default:
                        break;
                }
                break;
            }

            default:
                break;
        }

        if (!reg_interface) {
            if (log)
                log->Printf ("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
                             __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
                assert (false && "Architecture or OS not supported");
        }

        switch (arch.GetMachine())
        {
            case llvm::Triple::mips64:
                m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
                break;
            case llvm::Triple::x86:
            case llvm::Triple::x86_64:
                m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
                break;
            default:
                break;
        }

        reg_ctx_sp = m_thread_reg_ctx_sp;
    }
    else if (m_unwinder_ap.get())
    {
        reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
    }
    return reg_ctx_sp;
}
size_t
PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target, 
                                                BreakpointSite *bp_site)
{
    ArchSpec arch = target.GetArchitecture();
    const uint8_t *trap_opcode = NULL;
    size_t trap_opcode_size = 0;

    switch (arch.GetMachine())
    {
    default:
        assert(false && "CPU type not supported!");
        break;
            
    case llvm::Triple::aarch64:
        {
            static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 };
            trap_opcode = g_aarch64_opcode;
            trap_opcode_size = sizeof(g_aarch64_opcode);
        }
        break;
    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
        {
            static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };
            trap_opcode = g_i386_breakpoint_opcode;
            trap_opcode_size = sizeof(g_i386_breakpoint_opcode);
        }
        break;
    case llvm::Triple::hexagon:
        {
            static const uint8_t g_hex_opcode[] = { 0x0c, 0xdb, 0x00, 0x54 };
            trap_opcode = g_hex_opcode;
            trap_opcode_size = sizeof(g_hex_opcode);
        }
        break;
    case llvm::Triple::arm:
        {
            // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
            // but the linux kernel does otherwise.
            static const uint8_t g_arm_breakpoint_opcode[] = { 0xf0, 0x01, 0xf0, 0xe7 };
            static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde };

            lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
            AddressClass addr_class = eAddressClassUnknown;

            if (bp_loc_sp)
                addr_class = bp_loc_sp->GetAddress ().GetAddressClass ();

            if (addr_class == eAddressClassCodeAlternateISA 
                || (addr_class == eAddressClassUnknown 
                    && bp_loc_sp->GetAddress().GetOffset() & 1))
            {
                trap_opcode = g_thumb_breakpoint_opcode;
                trap_opcode_size = sizeof(g_thumb_breakpoint_opcode);
            }
            else
            {
                trap_opcode = g_arm_breakpoint_opcode;
                trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
            }
        }
        break;
    case llvm::Triple::mips64:
        {
            static const uint8_t g_hex_opcode[] = { 0x00, 0x00, 0x00, 0x0d };
            trap_opcode = g_hex_opcode;
            trap_opcode_size = sizeof(g_hex_opcode);
        }
        break;
    }

    if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
        return trap_opcode_size;
    return 0;
}
RegisterContextSP
ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) {
  RegisterContextSP reg_ctx_sp;
  uint32_t concrete_frame_idx = 0;

  if (frame)
    concrete_frame_idx = frame->GetConcreteFrameIndex();

  if (concrete_frame_idx == 0) {
    if (m_thread_reg_ctx_sp)
      return m_thread_reg_ctx_sp;

    ProcessMinidump *process =
        static_cast<ProcessMinidump *>(GetProcess().get());
    ArchSpec arch = process->GetArchitecture();
    RegisterInfoInterface *reg_interface = nullptr;

    // TODO write other register contexts and add them here
    switch (arch.GetMachine()) {
    case llvm::Triple::x86: {
      reg_interface = new RegisterContextLinux_i386(arch);
      lldb::DataBufferSP buf =
          ConvertMinidumpContext_x86_32(m_gpregset_data, reg_interface);
      DataExtractor gpregset(buf, lldb::eByteOrderLittle, 4);
      m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
          *this, reg_interface, gpregset, {}));
      break;
    }
    case llvm::Triple::x86_64: {
      reg_interface = new RegisterContextLinux_x86_64(arch);
      lldb::DataBufferSP buf =
          ConvertMinidumpContext_x86_64(m_gpregset_data, reg_interface);
      DataExtractor gpregset(buf, lldb::eByteOrderLittle, 8);
      m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
          *this, reg_interface, gpregset, {}));
      break;
    }
    case llvm::Triple::aarch64: {
      DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(),
                         lldb::eByteOrderLittle, 8);
      m_thread_reg_ctx_sp.reset(new RegisterContextMinidump_ARM64(*this, data));
      break;
    }
    case llvm::Triple::arm: {
      DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(),
                         lldb::eByteOrderLittle, 8);
      const bool apple = arch.GetTriple().getVendor() == llvm::Triple::Apple;
      m_thread_reg_ctx_sp.reset(
          new RegisterContextMinidump_ARM(*this, data, apple));
      break;
    }
    default:
      break;
    }

    reg_ctx_sp = m_thread_reg_ctx_sp;
  } else if (m_unwinder_ap) {
    reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame);
  }

  return reg_ctx_sp;
}
Beispiel #21
0
size_t
PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
{
    ArchSpec arch = target.GetArchitecture();
    const uint8_t *trap_opcode = NULL;
    size_t trap_opcode_size = 0;

    switch (arch.GetMachine())
    {
    default:
        assert(false && "Unhandled architecture in PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode()");
        break;
    case llvm::Triple::aarch64:
        {
            static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 };
            trap_opcode = g_aarch64_opcode;
            trap_opcode_size = sizeof(g_aarch64_opcode);
        }
        break;
    // TODO: support big-endian arm and thumb trap codes.
    case llvm::Triple::arm:
        {
            static const uint8_t g_arm_breakpoint_opcode[] = { 0xfe, 0xde, 0xff, 0xe7 };
            static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde };

            lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
            AddressClass addr_class = eAddressClassUnknown;

            if (bp_loc_sp)
                addr_class = bp_loc_sp->GetAddress ().GetAddressClass ();

            if (addr_class == eAddressClassCodeAlternateISA
                || (addr_class == eAddressClassUnknown && (bp_site->GetLoadAddress() & 1)))
            {
                // TODO: Enable when FreeBSD supports thumb breakpoints.
                // FreeBSD kernel as of 10.x, does not support thumb breakpoints
                trap_opcode = g_thumb_breakpoint_opcode;
                trap_opcode_size = 0;
            }
            else
            {
                trap_opcode = g_arm_breakpoint_opcode;
                trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
            }
        }
        break;
    case llvm::Triple::mips64:
        {
            static const uint8_t g_hex_opcode[] = { 0x00, 0x00, 0x00, 0x0d };
            trap_opcode = g_hex_opcode;
            trap_opcode_size = sizeof(g_hex_opcode);
        }
        break;
    case llvm::Triple::mips64el:
        {
            static const uint8_t g_hex_opcode[] = { 0x0d, 0x00, 0x00, 0x00 };
            trap_opcode = g_hex_opcode;
            trap_opcode_size = sizeof(g_hex_opcode);
        }
        break;
    case llvm::Triple::ppc:
    case llvm::Triple::ppc64:
        {
            static const uint8_t g_ppc_opcode[] = { 0x7f, 0xe0, 0x00, 0x08 };
            trap_opcode = g_ppc_opcode;
            trap_opcode_size = sizeof(g_ppc_opcode);
        }
        break;
    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
        {
            static const uint8_t g_i386_opcode[] = { 0xCC };
            trap_opcode = g_i386_opcode;
            trap_opcode_size = sizeof(g_i386_opcode);
        }
        break;
    }

    if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
        return trap_opcode_size;
    return 0;
}
std::unique_ptr<Architecture> ArchitectureArm::Create(const ArchSpec &arch) {
  if (arch.GetMachine() != llvm::Triple::arm)
    return nullptr;
  return std::unique_ptr<Architecture>(new ArchitectureArm());
}
void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
  if (m_finalized)
    return;

  m_finalized = true;
  const size_t num_sets = m_sets.size();
  for (size_t set = 0; set < num_sets; ++set) {
    assert(m_sets.size() == m_set_reg_nums.size());
    m_sets[set].num_registers = m_set_reg_nums[set].size();
    m_sets[set].registers = &m_set_reg_nums[set][0];
  }

  // sort and unique all value registers and make sure each is terminated with
  // LLDB_INVALID_REGNUM

  for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(),
                                 end = m_value_regs_map.end();
       pos != end; ++pos) {
    if (pos->second.size() > 1) {
      std::sort(pos->second.begin(), pos->second.end());
      reg_num_collection::iterator unique_end =
          std::unique(pos->second.begin(), pos->second.end());
      if (unique_end != pos->second.end())
        pos->second.erase(unique_end, pos->second.end());
    }
    assert(!pos->second.empty());
    if (pos->second.back() != LLDB_INVALID_REGNUM)
      pos->second.push_back(LLDB_INVALID_REGNUM);
  }

  // Now update all value_regs with each register info as needed
  const size_t num_regs = m_regs.size();
  for (size_t i = 0; i < num_regs; ++i) {
    if (m_value_regs_map.find(i) != m_value_regs_map.end())
      m_regs[i].value_regs = m_value_regs_map[i].data();
    else
      m_regs[i].value_regs = NULL;
  }

  // Expand all invalidation dependencies
  for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),
                                 end = m_invalidate_regs_map.end();
       pos != end; ++pos) {
    const uint32_t reg_num = pos->first;

    if (m_regs[reg_num].value_regs) {
      reg_num_collection extra_invalid_regs;
      for (const uint32_t invalidate_reg_num : pos->second) {
        reg_to_regs_map::iterator invalidate_pos =
            m_invalidate_regs_map.find(invalidate_reg_num);
        if (invalidate_pos != m_invalidate_regs_map.end()) {
          for (const uint32_t concrete_invalidate_reg_num :
               invalidate_pos->second) {
            if (concrete_invalidate_reg_num != reg_num)
              extra_invalid_regs.push_back(concrete_invalidate_reg_num);
          }
        }
      }
      pos->second.insert(pos->second.end(), extra_invalid_regs.begin(),
                         extra_invalid_regs.end());
    }
  }

  // sort and unique all invalidate registers and make sure each is terminated
  // with
  // LLDB_INVALID_REGNUM
  for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),
                                 end = m_invalidate_regs_map.end();
       pos != end; ++pos) {
    if (pos->second.size() > 1) {
      std::sort(pos->second.begin(), pos->second.end());
      reg_num_collection::iterator unique_end =
          std::unique(pos->second.begin(), pos->second.end());
      if (unique_end != pos->second.end())
        pos->second.erase(unique_end, pos->second.end());
    }
    assert(!pos->second.empty());
    if (pos->second.back() != LLDB_INVALID_REGNUM)
      pos->second.push_back(LLDB_INVALID_REGNUM);
  }

  // Now update all invalidate_regs with each register info as needed
  for (size_t i = 0; i < num_regs; ++i) {
    if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end())
      m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data();
    else
      m_regs[i].invalidate_regs = NULL;
  }

  // Check if we need to automatically set the generic registers in case
  // they weren't set
  bool generic_regs_specified = false;
  for (const auto &reg : m_regs) {
    if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) {
      generic_regs_specified = true;
      break;
    }
  }

  if (!generic_regs_specified) {
    switch (arch.GetMachine()) {
    case llvm::Triple::aarch64:
    case llvm::Triple::aarch64_be:
      for (auto &reg : m_regs) {
        if (strcmp(reg.name, "pc") == 0)
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
        else if ((strcmp(reg.name, "fp") == 0) ||
                 (strcmp(reg.name, "x29") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
        else if ((strcmp(reg.name, "lr") == 0) ||
                 (strcmp(reg.name, "x30") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
        else if ((strcmp(reg.name, "sp") == 0) ||
                 (strcmp(reg.name, "x31") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
        else if (strcmp(reg.name, "cpsr") == 0)
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
      }
      break;

    case llvm::Triple::arm:
    case llvm::Triple::armeb:
    case llvm::Triple::thumb:
    case llvm::Triple::thumbeb:
      for (auto &reg : m_regs) {
        if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
        else if ((strcmp(reg.name, "sp") == 0) ||
                 (strcmp(reg.name, "r13") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
        else if ((strcmp(reg.name, "lr") == 0) ||
                 (strcmp(reg.name, "r14") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
        else if ((strcmp(reg.name, "r7") == 0) &&
                 arch.GetTriple().getVendor() == llvm::Triple::Apple)
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
        else if ((strcmp(reg.name, "r11") == 0) &&
                 arch.GetTriple().getVendor() != llvm::Triple::Apple)
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
        else if (strcmp(reg.name, "fp") == 0)
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
        else if (strcmp(reg.name, "cpsr") == 0)
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
      }
      break;

    case llvm::Triple::x86:
      for (auto &reg : m_regs) {
        if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
        else if ((strcmp(reg.name, "esp") == 0) ||
                 (strcmp(reg.name, "sp") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
        else if ((strcmp(reg.name, "ebp") == 0) ||
                 (strcmp(reg.name, "fp") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
        else if ((strcmp(reg.name, "eflags") == 0) ||
                 (strcmp(reg.name, "flags") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
      }
      break;

    case llvm::Triple::x86_64:
      for (auto &reg : m_regs) {
        if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
        else if ((strcmp(reg.name, "rsp") == 0) ||
                 (strcmp(reg.name, "sp") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
        else if ((strcmp(reg.name, "rbp") == 0) ||
                 (strcmp(reg.name, "fp") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
        else if ((strcmp(reg.name, "rflags") == 0) ||
                 (strcmp(reg.name, "flags") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
      }
      break;

    default:
      break;
    }
  }
}