// 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); }
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; }
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; }
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; }
// 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; }
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; } }
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(); }
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; }
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 ® : 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 ® : 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 ® : 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 ® : 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 ® : 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; } } }