Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,14 @@
add_lldb_library(lldbPluginInstructionARM PLUGIN
EmulateInstructionARM.cpp
EmulationStateARM.cpp
LINK_LIBS
lldbCore
lldbHost
lldbInterpreter
lldbSymbol
lldbTarget
lldbPluginProcessUtility
LINK_COMPONENTS
Support
)

View File

@@ -0,0 +1 @@
262a7914d249d8333d1efc8876a0ec35fe4c3ec4

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,357 @@
//===-- EmulationStateARM.cpp -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "EmulationStateARM.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Interpreter/OptionValueArray.h"
#include "lldb/Interpreter/OptionValueDictionary.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "Utility/ARM_DWARF_Registers.h"
using namespace lldb;
using namespace lldb_private;
EmulationStateARM::EmulationStateARM() : m_gpr(), m_vfp_regs(), m_memory() {
ClearPseudoRegisters();
}
EmulationStateARM::~EmulationStateARM() {}
bool EmulationStateARM::LoadPseudoRegistersFromFrame(StackFrame &frame) {
RegisterContext *reg_ctx = frame.GetRegisterContext().get();
bool success = true;
uint32_t reg_num;
for (int i = dwarf_r0; i < dwarf_r0 + 17; ++i) {
reg_num =
reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
RegisterValue reg_value;
if (reg_ctx->ReadRegister(reg_info, reg_value)) {
m_gpr[i - dwarf_r0] = reg_value.GetAsUInt32();
} else
success = false;
}
for (int i = dwarf_d0; i < dwarf_d0 + 32; ++i) {
reg_num =
reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
RegisterValue reg_value;
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
if (reg_ctx->ReadRegister(reg_info, reg_value)) {
uint64_t value = reg_value.GetAsUInt64();
uint32_t idx = i - dwarf_d0;
if (i < 16) {
m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
} else
m_vfp_regs.d_regs[idx - 16] = value;
} else
success = false;
}
return success;
}
bool EmulationStateARM::StorePseudoRegisterValue(uint32_t reg_num,
uint64_t value) {
if (reg_num <= dwarf_cpsr)
m_gpr[reg_num - dwarf_r0] = (uint32_t)value;
else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
uint32_t idx = reg_num - dwarf_s0;
m_vfp_regs.s_regs[idx] = (uint32_t)value;
} else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
uint32_t idx = reg_num - dwarf_d0;
if (idx < 16) {
m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
} else
m_vfp_regs.d_regs[idx - 16] = value;
} else
return false;
return true;
}
uint64_t EmulationStateARM::ReadPseudoRegisterValue(uint32_t reg_num,
bool &success) {
uint64_t value = 0;
success = true;
if (reg_num <= dwarf_cpsr)
value = m_gpr[reg_num - dwarf_r0];
else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
uint32_t idx = reg_num - dwarf_s0;
value = m_vfp_regs.d_regs[idx];
} else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
uint32_t idx = reg_num - dwarf_d0;
if (idx < 16)
value = (uint64_t)m_vfp_regs.s_regs[idx * 2] |
((uint64_t)m_vfp_regs.s_regs[idx * 2 + 1] >> 32);
else
value = m_vfp_regs.d_regs[idx - 16];
} else
success = false;
return value;
}
void EmulationStateARM::ClearPseudoRegisters() {
for (int i = 0; i < 17; ++i)
m_gpr[i] = 0;
for (int i = 0; i < 32; ++i)
m_vfp_regs.s_regs[i] = 0;
for (int i = 0; i < 16; ++i)
m_vfp_regs.d_regs[i] = 0;
}
void EmulationStateARM::ClearPseudoMemory() { m_memory.clear(); }
bool EmulationStateARM::StoreToPseudoAddress(lldb::addr_t p_address,
uint32_t value) {
m_memory[p_address] = value;
return true;
}
uint32_t EmulationStateARM::ReadFromPseudoAddress(lldb::addr_t p_address,
bool &success) {
std::map<lldb::addr_t, uint32_t>::iterator pos;
uint32_t ret_val = 0;
success = true;
pos = m_memory.find(p_address);
if (pos != m_memory.end())
ret_val = pos->second;
else
success = false;
return ret_val;
}
size_t EmulationStateARM::ReadPseudoMemory(
EmulateInstruction *instruction, void *baton,
const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst,
size_t length) {
if (!baton)
return 0;
bool success = true;
EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
if (length <= 4) {
uint32_t value = pseudo_state->ReadFromPseudoAddress(addr, success);
if (!success)
return 0;
if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
value = llvm::ByteSwap_32(value);
*((uint32_t *)dst) = value;
} else if (length == 8) {
uint32_t value1 = pseudo_state->ReadFromPseudoAddress(addr, success);
if (!success)
return 0;
uint32_t value2 = pseudo_state->ReadFromPseudoAddress(addr + 4, success);
if (!success)
return 0;
if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
value1 = llvm::ByteSwap_32(value1);
value2 = llvm::ByteSwap_32(value2);
}
((uint32_t *)dst)[0] = value1;
((uint32_t *)dst)[1] = value2;
} else
success = false;
if (success)
return length;
return 0;
}
size_t EmulationStateARM::WritePseudoMemory(
EmulateInstruction *instruction, void *baton,
const EmulateInstruction::Context &context, lldb::addr_t addr,
const void *dst, size_t length) {
if (!baton)
return 0;
EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
if (length <= 4) {
uint32_t value;
memcpy (&value, dst, sizeof (uint32_t));
if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
value = llvm::ByteSwap_32(value);
pseudo_state->StoreToPseudoAddress(addr, value);
return length;
} else if (length == 8) {
uint32_t value1;
uint32_t value2;
memcpy (&value1, dst, sizeof (uint32_t));
memcpy(&value2, static_cast<const uint8_t *>(dst) + sizeof(uint32_t),
sizeof(uint32_t));
if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
value1 = llvm::ByteSwap_32(value1);
value2 = llvm::ByteSwap_32(value2);
}
pseudo_state->StoreToPseudoAddress(addr, value1);
pseudo_state->StoreToPseudoAddress(addr + 4, value2);
return length;
}
return 0;
}
bool EmulationStateARM::ReadPseudoRegister(
EmulateInstruction *instruction, void *baton,
const lldb_private::RegisterInfo *reg_info,
lldb_private::RegisterValue &reg_value) {
if (!baton || !reg_info)
return false;
bool success = true;
EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
uint64_t reg_uval =
pseudo_state->ReadPseudoRegisterValue(dwarf_reg_num, success);
if (success)
success = reg_value.SetUInt(reg_uval, reg_info->byte_size);
return success;
}
bool EmulationStateARM::WritePseudoRegister(
EmulateInstruction *instruction, void *baton,
const EmulateInstruction::Context &context,
const lldb_private::RegisterInfo *reg_info,
const lldb_private::RegisterValue &reg_value) {
if (!baton || !reg_info)
return false;
EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
return pseudo_state->StorePseudoRegisterValue(dwarf_reg_num,
reg_value.GetAsUInt64());
}
bool EmulationStateARM::CompareState(EmulationStateARM &other_state) {
bool match = true;
for (int i = 0; match && i < 17; ++i) {
if (m_gpr[i] != other_state.m_gpr[i])
match = false;
}
for (int i = 0; match && i < 32; ++i) {
if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i])
match = false;
}
for (int i = 0; match && i < 16; ++i) {
if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i])
match = false;
}
return match;
}
bool EmulationStateARM::LoadStateFromDictionary(
OptionValueDictionary *test_data) {
static ConstString memory_key("memory");
static ConstString registers_key("registers");
if (!test_data)
return false;
OptionValueSP value_sp = test_data->GetValueForKey(memory_key);
// Load memory, if present.
if (value_sp.get() != NULL) {
static ConstString address_key("address");
static ConstString data_key("data");
uint64_t start_address = 0;
OptionValueDictionary *mem_dict = value_sp->GetAsDictionary();
value_sp = mem_dict->GetValueForKey(address_key);
if (value_sp.get() == NULL)
return false;
else
start_address = value_sp->GetUInt64Value();
value_sp = mem_dict->GetValueForKey(data_key);
OptionValueArray *mem_array = value_sp->GetAsArray();
if (!mem_array)
return false;
uint32_t num_elts = mem_array->GetSize();
uint32_t address = (uint32_t)start_address;
for (uint32_t i = 0; i < num_elts; ++i) {
value_sp = mem_array->GetValueAtIndex(i);
if (value_sp.get() == NULL)
return false;
uint64_t value = value_sp->GetUInt64Value();
StoreToPseudoAddress(address, value);
address = address + 4;
}
}
value_sp = test_data->GetValueForKey(registers_key);
if (value_sp.get() == NULL)
return false;
// Load General Registers
OptionValueDictionary *reg_dict = value_sp->GetAsDictionary();
StreamString sstr;
for (int i = 0; i < 16; ++i) {
sstr.Clear();
sstr.Printf("r%d", i);
ConstString reg_name(sstr.GetString());
value_sp = reg_dict->GetValueForKey(reg_name);
if (value_sp.get() == NULL)
return false;
uint64_t reg_value = value_sp->GetUInt64Value();
StorePseudoRegisterValue(dwarf_r0 + i, reg_value);
}
static ConstString cpsr_name("cpsr");
value_sp = reg_dict->GetValueForKey(cpsr_name);
if (value_sp.get() == NULL)
return false;
StorePseudoRegisterValue(dwarf_cpsr, value_sp->GetUInt64Value());
// Load s/d Registers
for (int i = 0; i < 32; ++i) {
sstr.Clear();
sstr.Printf("s%d", i);
ConstString reg_name(sstr.GetString());
value_sp = reg_dict->GetValueForKey(reg_name);
if (value_sp.get() == NULL)
return false;
uint64_t reg_value = value_sp->GetUInt64Value();
StorePseudoRegisterValue(dwarf_s0 + i, reg_value);
}
return true;
}

View File

@@ -0,0 +1,80 @@
//===-- lldb_EmulationStateARM.h --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef lldb_EmulationStateARM_h_
#define lldb_EmulationStateARM_h_
#include <map>
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Opcode.h"
class EmulationStateARM {
public:
EmulationStateARM();
virtual ~EmulationStateARM();
bool StorePseudoRegisterValue(uint32_t reg_num, uint64_t value);
uint64_t ReadPseudoRegisterValue(uint32_t reg_num, bool &success);
bool StoreToPseudoAddress(lldb::addr_t p_address, uint32_t value);
uint32_t ReadFromPseudoAddress(lldb::addr_t p_address, bool &success);
void ClearPseudoRegisters();
void ClearPseudoMemory();
bool LoadPseudoRegistersFromFrame(lldb_private::StackFrame &frame);
bool LoadStateFromDictionary(lldb_private::OptionValueDictionary *test_data);
bool CompareState(EmulationStateARM &other_state);
static size_t
ReadPseudoMemory(lldb_private::EmulateInstruction *instruction, void *baton,
const lldb_private::EmulateInstruction::Context &context,
lldb::addr_t addr, void *dst, size_t length);
static size_t
WritePseudoMemory(lldb_private::EmulateInstruction *instruction, void *baton,
const lldb_private::EmulateInstruction::Context &context,
lldb::addr_t addr, const void *dst, size_t length);
static bool ReadPseudoRegister(lldb_private::EmulateInstruction *instruction,
void *baton,
const lldb_private::RegisterInfo *reg_info,
lldb_private::RegisterValue &reg_value);
static bool
WritePseudoRegister(lldb_private::EmulateInstruction *instruction,
void *baton,
const lldb_private::EmulateInstruction::Context &context,
const lldb_private::RegisterInfo *reg_info,
const lldb_private::RegisterValue &reg_value);
private:
uint32_t m_gpr[17];
struct _sd_regs {
uint32_t s_regs[32]; // sregs 0 - 31 & dregs 0 - 15
uint64_t d_regs[16]; // dregs 16-31
} m_vfp_regs;
std::map<lldb::addr_t, uint32_t> m_memory; // Eventually will want to change
// uint32_t to a data buffer heap
// type.
DISALLOW_COPY_AND_ASSIGN(EmulationStateARM);
};
#endif // lldb_EmulationStateARM_h_

View File

@@ -0,0 +1,11 @@
add_lldb_library(lldbPluginInstructionARM64 PLUGIN
EmulateInstructionARM64.cpp
LINK_LIBS
lldbCore
lldbInterpreter
lldbSymbol
lldbPluginProcessUtility
LINK_COMPONENTS
Support
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,205 @@
//===-- EmulateInstructionARM64.h -------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef EmulateInstructionARM64_h_
#define EmulateInstructionARM64_h_
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "Plugins/Process/Utility/ARMDefines.h"
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Interpreter/OptionValue.h"
#include "lldb/Utility/Status.h"
class EmulateInstructionARM64 : public lldb_private::EmulateInstruction {
public:
EmulateInstructionARM64(const lldb_private::ArchSpec &arch)
: EmulateInstruction(arch), m_opcode_pstate(), m_emulated_pstate(),
m_ignore_conditions(false) {}
static void Initialize();
static void Terminate();
static lldb_private::ConstString GetPluginNameStatic();
static const char *GetPluginDescriptionStatic();
static lldb_private::EmulateInstruction *
CreateInstance(const lldb_private::ArchSpec &arch,
lldb_private::InstructionType inst_type);
static bool SupportsEmulatingInstructionsOfTypeStatic(
lldb_private::InstructionType inst_type) {
switch (inst_type) {
case lldb_private::eInstructionTypeAny:
case lldb_private::eInstructionTypePrologueEpilogue:
return true;
case lldb_private::eInstructionTypePCModifying:
case lldb_private::eInstructionTypeAll:
return false;
}
return false;
}
lldb_private::ConstString GetPluginName() override;
uint32_t GetPluginVersion() override { return 1; }
bool SetTargetTriple(const lldb_private::ArchSpec &arch) override;
bool SupportsEmulatingInstructionsOfType(
lldb_private::InstructionType inst_type) override {
return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
}
bool ReadInstruction() override;
bool EvaluateInstruction(uint32_t evaluate_options) override;
bool TestEmulation(lldb_private::Stream *out_stream,
lldb_private::ArchSpec &arch,
lldb_private::OptionValueDictionary *test_data) override {
return false;
}
bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
lldb_private::RegisterInfo &reg_info) override;
bool
CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
typedef enum { AddrMode_OFF, AddrMode_PRE, AddrMode_POST } AddrMode;
typedef enum {
BranchType_CALL,
BranchType_ERET,
BranchType_DRET,
BranchType_RET,
BranchType_JMP
} BranchType;
typedef enum { CountOp_CLZ, CountOp_CLS, CountOp_CNT } CountOp;
typedef enum { RevOp_RBIT, RevOp_REV16, RevOp_REV32, RevOp_REV64 } RevOp;
typedef enum { BitwiseOp_NOT, BitwiseOp_RBIT } BitwiseOp;
typedef enum { EL0 = 0, EL1 = 1, EL2 = 2, EL3 = 3 } ExceptionLevel;
typedef enum {
ExtendType_SXTB,
ExtendType_SXTH,
ExtendType_SXTW,
ExtendType_SXTX,
ExtendType_UXTB,
ExtendType_UXTH,
ExtendType_UXTW,
ExtendType_UXTX
} ExtendType;
typedef enum { ExtractType_LEFT, ExtractType_RIGHT } ExtractType;
typedef enum { LogicalOp_AND, LogicalOp_EOR, LogicalOp_ORR } LogicalOp;
typedef enum { MemOp_LOAD, MemOp_STORE, MemOp_PREFETCH, MemOp_NOP } MemOp;
typedef enum { MoveWideOp_N, MoveWideOp_Z, MoveWideOp_K } MoveWideOp;
typedef enum {
ShiftType_LSL,
ShiftType_LSR,
ShiftType_ASR,
ShiftType_ROR
} ShiftType;
typedef enum { SP0 = 0, SPx = 1 } StackPointerSelection;
typedef enum {
Unpredictable_WBOVERLAP,
Unpredictable_LDPOVERLAP
} Unpredictable;
typedef enum {
Constraint_NONE,
Constraint_UNKNOWN,
Constraint_SUPPRESSWB,
Constraint_NOP
} ConstraintType;
typedef enum {
AccType_NORMAL,
AccType_UNPRIV,
AccType_STREAM,
AccType_ALIGNED,
AccType_ORDERED
} AccType;
typedef struct {
uint32_t N : 1, V : 1, C : 1,
Z : 1, // condition code flags – can also be accessed as
// PSTATE.[N,Z,C,V]
Q : 1, // AArch32 only – CSPR.Q bit
IT : 8, // AArch32 only – CPSR.IT bits
J : 1, // AArch32 only – CSPR.J bit
T : 1, // AArch32 only – CPSR.T bit
SS : 1, // Single step process state bit
IL : 1, // Illegal state bit
D : 1, A : 1, I : 1,
F : 1, // Interrupt masks – can also be accessed as PSTATE.[D,A,I,F]
E : 1, // AArch32 only – CSPR.E bit
M : 5, // AArch32 only – mode encodings
RW : 1, // Current register width – 0 is AArch64, 1 is AArch32
EL : 2, // Current exception level (see ExceptionLevel enum)
SP : 1; // AArch64 only - Stack Pointer selection (see
// StackPointerSelection enum)
} ProcState;
protected:
typedef struct {
uint32_t mask;
uint32_t value;
uint32_t vfp_variants;
bool (EmulateInstructionARM64::*callback)(const uint32_t opcode);
const char *name;
} Opcode;
static Opcode *GetOpcodeForInstruction(const uint32_t opcode);
uint32_t GetFramePointerRegisterNumber() const;
bool BranchTo(const Context &context, uint32_t N, lldb::addr_t target);
bool ConditionHolds(const uint32_t cond);
bool UsingAArch32();
bool EmulateADDSUBImm(const uint32_t opcode);
template <AddrMode a_mode> bool EmulateLDPSTP(const uint32_t opcode);
template <AddrMode a_mode> bool EmulateLDRSTRImm(const uint32_t opcode);
bool EmulateB(const uint32_t opcode);
bool EmulateBcond(const uint32_t opcode);
bool EmulateCBZ(const uint32_t opcode);
bool EmulateTBZ(const uint32_t opcode);
ProcState m_opcode_pstate;
ProcState m_emulated_pstate; // This can get updated by the opcode.
bool m_ignore_conditions;
};
#endif // EmulateInstructionARM64_h_

View File

@@ -0,0 +1,4 @@
add_subdirectory(ARM)
add_subdirectory(ARM64)
add_subdirectory(MIPS)
add_subdirectory(MIPS64)

View File

@@ -0,0 +1,18 @@
if(Mips IN_LIST LLVM_TARGETS_TO_BUILD)
set(mips_target Mips)
endif()
add_lldb_library(lldbPluginInstructionMIPS PLUGIN
EmulateInstructionMIPS.cpp
LINK_LIBS
lldbCore
lldbInterpreter
lldbSymbol
lldbTarget
lldbPluginProcessUtility
LINK_COMPONENTS
MC
Support
${mips_target}
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,219 @@
//===-- EmulateInstructionMIPS.h ------------------------------------*- C++
//-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef EmulateInstructionMIPS_h_
#define EmulateInstructionMIPS_h_
namespace llvm {
class MCDisassembler;
class MCSubtargetInfo;
class MCRegisterInfo;
class MCAsmInfo;
class MCContext;
class MCInstrInfo;
class MCInst;
}
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Interpreter/OptionValue.h"
#include "lldb/Utility/Status.h"
class EmulateInstructionMIPS : public lldb_private::EmulateInstruction {
public:
static void Initialize();
static void Terminate();
static lldb_private::ConstString GetPluginNameStatic();
static const char *GetPluginDescriptionStatic();
static lldb_private::EmulateInstruction *
CreateInstance(const lldb_private::ArchSpec &arch,
lldb_private::InstructionType inst_type);
static bool SupportsEmulatingInstructionsOfTypeStatic(
lldb_private::InstructionType inst_type) {
switch (inst_type) {
case lldb_private::eInstructionTypeAny:
case lldb_private::eInstructionTypePrologueEpilogue:
case lldb_private::eInstructionTypePCModifying:
return true;
case lldb_private::eInstructionTypeAll:
return false;
}
return false;
}
lldb_private::ConstString GetPluginName() override;
uint32_t GetPluginVersion() override { return 1; }
bool SetTargetTriple(const lldb_private::ArchSpec &arch) override;
EmulateInstructionMIPS(const lldb_private::ArchSpec &arch);
bool SupportsEmulatingInstructionsOfType(
lldb_private::InstructionType inst_type) override {
return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
}
bool ReadInstruction() override;
bool EvaluateInstruction(uint32_t evaluate_options) override;
bool SetInstruction(const lldb_private::Opcode &insn_opcode,
const lldb_private::Address &inst_addr,
lldb_private::Target *target) override;
bool TestEmulation(lldb_private::Stream *out_stream,
lldb_private::ArchSpec &arch,
lldb_private::OptionValueDictionary *test_data) override {
return false;
}
bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
lldb_private::RegisterInfo &reg_info) override;
bool
CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
protected:
typedef struct {
const char *op_name;
bool (EmulateInstructionMIPS::*callback)(llvm::MCInst &insn);
const char *insn_name;
} MipsOpcode;
static MipsOpcode *GetOpcodeForInstruction(const char *op_name);
uint32_t GetSizeOfInstruction(lldb_private::DataExtractor &data,
uint64_t inst_addr);
bool Emulate_ADDiu(llvm::MCInst &insn);
bool Emulate_SUBU_ADDU(llvm::MCInst &insn);
bool Emulate_LUI(llvm::MCInst &insn);
bool Emulate_SW(llvm::MCInst &insn);
bool Emulate_LW(llvm::MCInst &insn);
bool Emulate_ADDIUSP(llvm::MCInst &insn);
bool Emulate_ADDIUS5(llvm::MCInst &insn);
bool Emulate_SWSP(llvm::MCInst &insn);
bool Emulate_SWM16_32(llvm::MCInst &insn);
bool Emulate_LWSP(llvm::MCInst &insn);
bool Emulate_LWM16_32(llvm::MCInst &insn);
bool Emulate_JRADDIUSP(llvm::MCInst &insn);
bool Emulate_LDST_Imm(llvm::MCInst &insn);
bool Emulate_LDST_Reg(llvm::MCInst &insn);
bool Emulate_BXX_3ops(llvm::MCInst &insn);
bool Emulate_BXX_3ops_C(llvm::MCInst &insn);
bool Emulate_BXX_2ops(llvm::MCInst &insn);
bool Emulate_BXX_2ops_C(llvm::MCInst &insn);
bool Emulate_Bcond_Link_C(llvm::MCInst &insn);
bool Emulate_Bcond_Link(llvm::MCInst &insn);
bool Emulate_FP_branch(llvm::MCInst &insn);
bool Emulate_3D_branch(llvm::MCInst &insn);
bool Emulate_BAL(llvm::MCInst &insn);
bool Emulate_BALC(llvm::MCInst &insn);
bool Emulate_BC(llvm::MCInst &insn);
bool Emulate_J(llvm::MCInst &insn);
bool Emulate_JAL(llvm::MCInst &insn);
bool Emulate_JALR(llvm::MCInst &insn);
bool Emulate_JIALC(llvm::MCInst &insn);
bool Emulate_JIC(llvm::MCInst &insn);
bool Emulate_JR(llvm::MCInst &insn);
bool Emulate_BC1EQZ(llvm::MCInst &insn);
bool Emulate_BC1NEZ(llvm::MCInst &insn);
bool Emulate_BNZB(llvm::MCInst &insn);
bool Emulate_BNZH(llvm::MCInst &insn);
bool Emulate_BNZW(llvm::MCInst &insn);
bool Emulate_BNZD(llvm::MCInst &insn);
bool Emulate_BZB(llvm::MCInst &insn);
bool Emulate_BZH(llvm::MCInst &insn);
bool Emulate_BZW(llvm::MCInst &insn);
bool Emulate_BZD(llvm::MCInst &insn);
bool Emulate_MSA_Branch_DF(llvm::MCInst &insn, int element_byte_size,
bool bnz);
bool Emulate_BNZV(llvm::MCInst &insn);
bool Emulate_BZV(llvm::MCInst &insn);
bool Emulate_MSA_Branch_V(llvm::MCInst &insn, bool bnz);
bool Emulate_B16_MM(llvm::MCInst &insn);
bool Emulate_Branch_MM(llvm::MCInst &insn);
bool Emulate_JALRx16_MM(llvm::MCInst &insn);
bool Emulate_JALx(llvm::MCInst &insn);
bool Emulate_JALRS(llvm::MCInst &insn);
bool nonvolatile_reg_p(uint32_t regnum);
const char *GetRegisterName(unsigned reg_num, bool altnernate_name);
private:
std::unique_ptr<llvm::MCDisassembler> m_disasm;
std::unique_ptr<llvm::MCDisassembler> m_alt_disasm;
std::unique_ptr<llvm::MCSubtargetInfo> m_subtype_info;
std::unique_ptr<llvm::MCSubtargetInfo> m_alt_subtype_info;
std::unique_ptr<llvm::MCRegisterInfo> m_reg_info;
std::unique_ptr<llvm::MCAsmInfo> m_asm_info;
std::unique_ptr<llvm::MCContext> m_context;
std::unique_ptr<llvm::MCInstrInfo> m_insn_info;
uint32_t m_next_inst_size;
bool m_use_alt_disaasm;
};
#endif // EmulateInstructionMIPS_h_

View File

@@ -0,0 +1,18 @@
if(Mips IN_LIST LLVM_TARGETS_TO_BUILD)
set(mips_target Mips)
endif()
add_lldb_library(lldbPluginInstructionMIPS64 PLUGIN
EmulateInstructionMIPS64.cpp
LINK_LIBS
lldbCore
lldbHost
lldbInterpreter
lldbSymbol
lldbPluginProcessUtility
LINK_COMPONENTS
MC
Support
${mips_target}
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,187 @@
//===-- EmulateInstructionMIPS64.h ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef EmulateInstructionMIPS64_h_
#define EmulateInstructionMIPS64_h_
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Interpreter/OptionValue.h"
#include "lldb/Utility/Status.h"
namespace llvm {
class MCDisassembler;
class MCSubtargetInfo;
class MCRegisterInfo;
class MCAsmInfo;
class MCContext;
class MCInstrInfo;
class MCInst;
} // namespace llvm
class EmulateInstructionMIPS64 : public lldb_private::EmulateInstruction {
public:
EmulateInstructionMIPS64(const lldb_private::ArchSpec &arch);
static void Initialize();
static void Terminate();
static lldb_private::ConstString GetPluginNameStatic();
static const char *GetPluginDescriptionStatic();
static lldb_private::EmulateInstruction *
CreateInstance(const lldb_private::ArchSpec &arch,
lldb_private::InstructionType inst_type);
static bool SupportsEmulatingInstructionsOfTypeStatic(
lldb_private::InstructionType inst_type) {
switch (inst_type) {
case lldb_private::eInstructionTypeAny:
case lldb_private::eInstructionTypePrologueEpilogue:
case lldb_private::eInstructionTypePCModifying:
return true;
case lldb_private::eInstructionTypeAll:
return false;
}
return false;
}
lldb_private::ConstString GetPluginName() override;
uint32_t GetPluginVersion() override { return 1; }
bool SetTargetTriple(const lldb_private::ArchSpec &arch) override;
bool SupportsEmulatingInstructionsOfType(
lldb_private::InstructionType inst_type) override {
return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
}
bool ReadInstruction() override;
bool EvaluateInstruction(uint32_t evaluate_options) override;
bool TestEmulation(lldb_private::Stream *out_stream,
lldb_private::ArchSpec &arch,
lldb_private::OptionValueDictionary *test_data) override {
return false;
}
bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
lldb_private::RegisterInfo &reg_info) override;
bool
CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
protected:
typedef struct {
const char *op_name;
bool (EmulateInstructionMIPS64::*callback)(llvm::MCInst &insn);
const char *insn_name;
} MipsOpcode;
static MipsOpcode *GetOpcodeForInstruction(const char *op_name);
bool Emulate_DADDiu(llvm::MCInst &insn);
bool Emulate_DSUBU_DADDU(llvm::MCInst &insn);
bool Emulate_LUI(llvm::MCInst &insn);
bool Emulate_SD(llvm::MCInst &insn);
bool Emulate_LD(llvm::MCInst &insn);
bool Emulate_LDST_Imm(llvm::MCInst &insn);
bool Emulate_LDST_Reg(llvm::MCInst &insn);
bool Emulate_BXX_3ops(llvm::MCInst &insn);
bool Emulate_BXX_3ops_C(llvm::MCInst &insn);
bool Emulate_BXX_2ops(llvm::MCInst &insn);
bool Emulate_BXX_2ops_C(llvm::MCInst &insn);
bool Emulate_Bcond_Link_C(llvm::MCInst &insn);
bool Emulate_Bcond_Link(llvm::MCInst &insn);
bool Emulate_FP_branch(llvm::MCInst &insn);
bool Emulate_3D_branch(llvm::MCInst &insn);
bool Emulate_BAL(llvm::MCInst &insn);
bool Emulate_BALC(llvm::MCInst &insn);
bool Emulate_BC(llvm::MCInst &insn);
bool Emulate_J(llvm::MCInst &insn);
bool Emulate_JAL(llvm::MCInst &insn);
bool Emulate_JALR(llvm::MCInst &insn);
bool Emulate_JIALC(llvm::MCInst &insn);
bool Emulate_JIC(llvm::MCInst &insn);
bool Emulate_JR(llvm::MCInst &insn);
bool Emulate_BC1EQZ(llvm::MCInst &insn);
bool Emulate_BC1NEZ(llvm::MCInst &insn);
bool Emulate_BNZB(llvm::MCInst &insn);
bool Emulate_BNZH(llvm::MCInst &insn);
bool Emulate_BNZW(llvm::MCInst &insn);
bool Emulate_BNZD(llvm::MCInst &insn);
bool Emulate_BZB(llvm::MCInst &insn);
bool Emulate_BZH(llvm::MCInst &insn);
bool Emulate_BZW(llvm::MCInst &insn);
bool Emulate_BZD(llvm::MCInst &insn);
bool Emulate_MSA_Branch_DF(llvm::MCInst &insn, int element_byte_size,
bool bnz);
bool Emulate_BNZV(llvm::MCInst &insn);
bool Emulate_BZV(llvm::MCInst &insn);
bool Emulate_MSA_Branch_V(llvm::MCInst &insn, bool bnz);
bool nonvolatile_reg_p(uint64_t regnum);
const char *GetRegisterName(unsigned reg_num, bool altnernate_name);
private:
std::unique_ptr<llvm::MCDisassembler> m_disasm;
std::unique_ptr<llvm::MCSubtargetInfo> m_subtype_info;
std::unique_ptr<llvm::MCRegisterInfo> m_reg_info;
std::unique_ptr<llvm::MCAsmInfo> m_asm_info;
std::unique_ptr<llvm::MCContext> m_context;
std::unique_ptr<llvm::MCInstrInfo> m_insn_info;
};
#endif // EmulateInstructionMIPS64_h_