From 88dfa0922adabeb88806a08e63a2c7683eb40c2b Mon Sep 17 00:00:00 2001 From: 2over12 Date: Sun, 30 Apr 2023 09:55:46 -0400 Subject: [PATCH] add name --- include/remill/Arch/Arch.h | 6 ++- include/remill/Arch/Name.h | 1 + lib/Arch/Arch.cpp | 10 +++++ lib/Arch/Instruction.cpp | 1 + lib/Arch/Name.cpp | 3 +- lib/Arch/Sleigh/AArch64Arch.cpp | 71 +++++++++++++++++++++++++++++++++ lib/Arch/Sleigh/AArch64Arch.h | 50 +++++++++++++++++++++++ 7 files changed, 140 insertions(+), 2 deletions(-) diff --git a/include/remill/Arch/Arch.h b/include/remill/Arch/Arch.h index 56870e2a..3853d3b1 100644 --- a/include/remill/Arch/Arch.h +++ b/include/remill/Arch/Arch.h @@ -39,10 +39,10 @@ #include #include #include +#include #include #include #include -#include #include "Instruction.h" @@ -421,6 +421,10 @@ class Arch { static ArchPtr GetAArch64(llvm::LLVMContext *context, OSName os, ArchName arch_name); + // Defined in `lib/Arch/Sleigh/AArch64Arch.cpp`. + static ArchPtr GetAArch64Sleigh(llvm::LLVMContext *context, OSName os, + ArchName arch_name); + // Defined in `lib/Arch/Sleigh/X86Arch.cpp` static ArchPtr GetSleighX86(llvm::LLVMContext *context, OSName os, ArchName arch_name); diff --git a/include/remill/Arch/Name.h b/include/remill/Arch/Name.h index c9de645d..8bc57056 100644 --- a/include/remill/Arch/Name.h +++ b/include/remill/Arch/Name.h @@ -112,6 +112,7 @@ enum ArchName : uint32_t { kArchAArch32LittleEndian, kArchAArch64LittleEndian, + kArchAArch64LittleEndian_SLEIGH, kArchSparc32, kArchSparc64, diff --git a/lib/Arch/Arch.cpp b/lib/Arch/Arch.cpp index c6370138..fde5377e 100644 --- a/lib/Arch/Arch.cpp +++ b/lib/Arch/Arch.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include "remill/Arch/Arch.h" + #include #include #include @@ -60,6 +62,7 @@ static unsigned AddressSize(ArchName arch_name) { case kArchAMD64_AVX512: case kArchAMD64_SLEIGH: case kArchAArch64LittleEndian: + case kArchAArch64LittleEndian_SLEIGH: case kArchSparc64: return 64; } return 0; @@ -107,6 +110,7 @@ ArchLocker Arch::Lock(ArchName arch_name_) { switch (arch_name_) { case ArchName::kArchAArch32LittleEndian: case ArchName::kArchThumb2LittleEndian: + case ArchName::kArchAArch64LittleEndian_SLEIGH: case ArchName::kArchAMD64_SLEIGH: case ArchName::kArchX86_SLEIGH: case ArchName::kArchPPC: return &gSleighArchLock; @@ -158,6 +162,12 @@ auto Arch::GetArchByName(llvm::LLVMContext *context_, OSName os_name_, LOG(FATAL) << "Unrecognized architecture."; return nullptr; + case kArchAArch64LittleEndian_SLEIGH: { + DLOG(INFO) + << "Using architecture: AArch64 Sleigh, feature set: Little Endian"; + return GetAArch64Sleigh(context_, os_name_, arch_name_); + } + case kArchAArch64LittleEndian: { DLOG(INFO) << "Using architecture: AArch64, feature set: Little Endian"; return GetAArch64(context_, os_name_, arch_name_); diff --git a/lib/Arch/Instruction.cpp b/lib/Arch/Instruction.cpp index af82c9d7..b7c350f5 100644 --- a/lib/Arch/Instruction.cpp +++ b/lib/Arch/Instruction.cpp @@ -667,6 +667,7 @@ std::string Instruction::Serialize(void) const { case kArchX86_SLEIGH: ss << "X86"; break; case kArchThumb2LittleEndian: ss << "Thumb2"; break; case kArchAArch32LittleEndian: ss << "AArch32"; break; + case kArchAArch64LittleEndian_SLEIGH: case kArchAArch64LittleEndian: ss << "AArch64"; break; case kArchSparc32: ss << "SPARC32"; break; case kArchSparc64: ss << "SPARC64"; break; diff --git a/lib/Arch/Name.cpp b/lib/Arch/Name.cpp index 5d5d6ee0..5d1e8513 100644 --- a/lib/Arch/Name.cpp +++ b/lib/Arch/Name.cpp @@ -64,7 +64,6 @@ ArchName GetArchName(std::string_view arch_name) { } else if (arch_name == "thumb2") { return kArchThumb2LittleEndian; - } else if (arch_name == "aarch64") { return kArchAArch64LittleEndian; @@ -77,6 +76,8 @@ ArchName GetArchName(std::string_view arch_name) { } else if (arch_name == "ppc") { return kArchPPC; + } else if (arch_name == "aarch64_sleigh") { + return kArchAArch64LittleEndian_SLEIGH; } else { return kArchInvalid; } diff --git a/lib/Arch/Sleigh/AArch64Arch.cpp b/lib/Arch/Sleigh/AArch64Arch.cpp index e69de29b..cf9f6316 100644 --- a/lib/Arch/Sleigh/AArch64Arch.cpp +++ b/lib/Arch/Sleigh/AArch64Arch.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include + +#include "remill/Arch/Instruction.h" +#include "remill/Arch/Name.h" +#include "remill/BC/ABI.h" +#include "remill/BC/Util.h" +#include "remill/BC/Version.h" +#include "remill/OS/OS.h" +// clang-format off +#include + +// clang-format on + +#include // For `ArchImpl`. + +#include "AArch64Arch.h" + +namespace remill { + + +AArch64Arch::AArch64Arch(llvm::LLVMContext *context_, OSName os_name_, + ArchName arch_name_) + : ArchBase(context_, os_name_, arch_name_), + AArch64ArchBase(context_, os_name_, arch_name_), + decoder(*this) {} + +AArch64Arch::~AArch64Arch(void) {} + +OperandLifter::OpLifterPtr AArch64Arch::DefaultLifter( + const remill::IntrinsicTable &intrinsics_table) const { + return std::make_shared(this, intrinsics_table); +} + +bool AArch64Arch::DecodeInstruction(uint64_t address, + std::string_view inst_bytes, + Instruction &inst, + DecodingContext context) const { + inst.pc = address; + inst.next_pc = address + inst_bytes.size(); // Default fall-through. + inst.branch_taken_pc = 0; + inst.branch_not_taken_pc = 0; + inst.has_branch_taken_delay_slot = false; + inst.has_branch_not_taken_delay_slot = false; + inst.arch_name = arch_name; + inst.sub_arch_name = arch_name; + inst.branch_taken_arch_name = arch_name; + inst.arch = this; + inst.category = Instruction::kCategoryInvalid; + inst.operands.clear(); + inst.flows = Instruction::InvalidInsn(); + + return this->decoder.DecodeInstruction(address, inst_bytes, inst, context); +} + +DecodingContext AArch64Arch::CreateInitialContext(void) const { + return DecodingContext(); +} + + +// TODO(pag): We pretend that these are singletons, but they aren't really! +Arch::ArchPtr Arch::GetAArch64Sleigh(llvm::LLVMContext *context_, + OSName os_name_, ArchName arch_name_) { + return std::make_unique(context_, os_name_, arch_name_); +} + + +} // namespace remill \ No newline at end of file diff --git a/lib/Arch/Sleigh/AArch64Arch.h b/lib/Arch/Sleigh/AArch64Arch.h index e69de29b..58ecc943 100644 --- a/lib/Arch/Sleigh/AArch64Arch.h +++ b/lib/Arch/Sleigh/AArch64Arch.h @@ -0,0 +1,50 @@ +#include + +#include "Arch.h" + +namespace remill { + +class SleighAArch64Decoder final : public remill::sleigh::SleighDecoder { + public: + SleighAArch64Decoder(const remill::Arch &arch); + + + virtual llvm::Value *LiftPcFromCurrPc(llvm::IRBuilder<> &bldr, llvm::Value *, + size_t curr_insn_size, + const DecodingContext &) const final; + + void + InitializeSleighContext(uint64_t addr, + remill::sleigh::SingleInstructionSleighContext &ctxt, + const ContextValues &context_values) const final; +}; + +class AArch64Arch final : public AArch64ArchBase { + public: + AArch64Arch(llvm::LLVMContext *context_, OSName os_name_, + ArchName arch_name_); + + virtual ~AArch64Arch(void); + + + virtual DecodingContext CreateInitialContext(void) const override; + + bool DecodeInstruction(uint64_t address, std::string_view instr_bytes, + Instruction &inst, + DecodingContext context) const override; + + + OperandLifter::OpLifterPtr + DefaultLifter(const remill::IntrinsicTable &intrinsics) const override; + + // Maximum number of bytes in an instruction for this particular architecture. + uint64_t MaxInstructionSize(const DecodingContext &, bool) const override; + static bool IsThumb(const DecodingContext &context); + + AArch64Arch(void) = delete; + + private: + SleighAArch64Decoder decoder; +}; + +} // namespace remill