mirror of
https://github.com/lifting-bits/remill
synced 2026-06-21 13:56:07 +00:00
Support PowerPC syscall (#653)
* Support PowerPC syscall * Enable PowerPC syscall unit test * Create stub sync hyper call * Cleanup * Fix `ConstantInt` call * Use `LoadMemoryPointerRef` util
This commit is contained in:
@@ -95,6 +95,7 @@ class SyncHyperCall {
|
||||
kSPARCTrapCondVS,
|
||||
|
||||
kPPCEmulateInstruction,
|
||||
kPPCSysCall,
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
@@ -423,4 +423,6 @@ __remill_sparc64_emulate_instruction(Memory *);
|
||||
[[gnu::used, gnu::const]] extern Memory *
|
||||
__remill_ppc_emulate_instruction(Memory *);
|
||||
|
||||
[[gnu::used, gnu::const]] extern Memory *__remill_ppc_syscall(Memory *);
|
||||
|
||||
} // extern C
|
||||
|
||||
@@ -42,6 +42,7 @@ class IntrinsicTable {
|
||||
llvm::Function *const missing_block;
|
||||
|
||||
// OS interaction.
|
||||
llvm::Function *const sync_hyper_call;
|
||||
llvm::Function *const async_hyper_call;
|
||||
|
||||
// Memory read intrinsics.
|
||||
|
||||
@@ -386,6 +386,10 @@ Memory *__remill_sync_hyper_call(State &state, Memory *mem,
|
||||
mem = __remill_ppc_emulate_instruction(mem);
|
||||
break;
|
||||
|
||||
case SyncHyperCall::kPPCSysCall:
|
||||
mem = __remill_ppc_syscall(mem);
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
default: __builtin_unreachable(); break;
|
||||
|
||||
@@ -79,6 +79,7 @@ IntrinsicTable::IntrinsicTable(llvm::Module *module)
|
||||
missing_block(FindIntrinsic(module, "__remill_missing_block")),
|
||||
|
||||
// OS interaction.
|
||||
sync_hyper_call(FindIntrinsic(module, "__remill_sync_hyper_call")),
|
||||
async_hyper_call(FindIntrinsic(module, "__remill_async_hyper_call")),
|
||||
|
||||
// Memory access.
|
||||
|
||||
@@ -22,12 +22,15 @@
|
||||
#include <llvm/IR/DerivedTypes.h>
|
||||
#include <llvm/IR/Value.h>
|
||||
#include <llvm/IR/Verifier.h>
|
||||
#include <remill/Arch/Name.h>
|
||||
#include <remill/Arch/Runtime/HyperCall.h>
|
||||
#include <remill/BC/ABI.h>
|
||||
#include <remill/BC/IntrinsicTable.h>
|
||||
#include <remill/BC/PCodeCFG.h>
|
||||
#include <remill/BC/SleighLifter.h>
|
||||
#include <remill/BC/Util.h>
|
||||
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <optional>
|
||||
#include <sleigh/pcoderaw.hh>
|
||||
@@ -74,6 +77,7 @@ static size_t kNextPcArgNum = 3;
|
||||
|
||||
|
||||
static const std::string kEqualityClaimName = "claim_eq";
|
||||
static const std::string kSysCallName = "syscall";
|
||||
|
||||
static bool isVarnodeInConstantSpace(VarnodeData vnode) {
|
||||
auto spc = vnode.getAddr().getSpace();
|
||||
@@ -1263,6 +1267,25 @@ class SleighLifter::PcodeToLLVMEmitIntoBlock {
|
||||
vars[2]);
|
||||
return kLiftedInstruction;
|
||||
}
|
||||
if (other_func_name == kSysCallName &&
|
||||
insn.arch_name == ArchName::kArchPPC) {
|
||||
DLOG(INFO) << "Invoking syscall";
|
||||
|
||||
const auto mem_ptr_ref = LoadMemoryPointerRef(bldr.GetInsertBlock());
|
||||
|
||||
// Get a LLVM value for the sync hyper call enumeration.
|
||||
auto hyper_call_int =
|
||||
static_cast<uint32_t>(SyncHyperCall::Name::kPPCSysCall);
|
||||
auto hyper_call = llvm::ConstantInt::get(
|
||||
llvm::IntegerType::get(this->context, 32), hyper_call_int);
|
||||
std::array<llvm::Value *, 3> args = {state_pointer, mem_ptr_ref,
|
||||
hyper_call};
|
||||
|
||||
bldr.CreateCall(insn_lifter_parent.GetIntrinsicTable()->sync_hyper_call,
|
||||
args);
|
||||
|
||||
return kLiftedInstruction;
|
||||
}
|
||||
DLOG(ERROR) << "Unsupported pcode intrinsic: " << *other_func_name;
|
||||
}
|
||||
return kLiftedUnsupportedInstruction;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <llvm/Support/TargetSelect.h>
|
||||
#include <llvm/Transforms/Utils/Cloning.h>
|
||||
#include <remill/Arch/Arch.h>
|
||||
#include <remill/Arch/Runtime/HyperCall.h>
|
||||
#include <remill/BC/InstructionLifter.h>
|
||||
#include <remill/BC/IntrinsicTable.h>
|
||||
#include <remill/BC/Lifter.h>
|
||||
@@ -185,6 +186,15 @@ MemoryHandler *__remill_write_memory_64(MemoryHandler *memory, uint64_t addr,
|
||||
memory->WriteMemory<uint64_t>(addr, value);
|
||||
return memory;
|
||||
}
|
||||
|
||||
struct State;
|
||||
|
||||
// PowerPC syscalls leave a `__remill_sync_hyper_call` invocation.
|
||||
// Create an empty stub implementation so we can still execute our LLVM code.
|
||||
MemoryHandler *__remill_sync_hyper_call(State &state, MemoryHandler *mem,
|
||||
SyncHyperCall::Name call) {
|
||||
return mem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -760,8 +760,7 @@ TEST(PPCVLELifts, PPCVLEConvertFloatToSignedInteger) {
|
||||
}
|
||||
|
||||
// Test syscall
|
||||
// TODO(wtan): Disabled, callother not supported
|
||||
TEST(PPCVLELifts, DISABLED_PPCVLESyscall) {
|
||||
TEST(PPCVLELifts, PPCVLESyscall) {
|
||||
llvm::LLVMContext curr_context;
|
||||
// e_sc
|
||||
std::string insn_data("\x7c\x00\x00\x48", 4);
|
||||
|
||||
Reference in New Issue
Block a user