added more lifters...

merge-requests/12/head
_xeroxz 3 years ago
parent 4fe8c63f49
commit 93402767a9

@ -54,6 +54,7 @@ list(APPEND vmdevirt_SOURCES
"src/lifters/popvsp.cpp" "src/lifters/popvsp.cpp"
"src/lifters/pushvsp.cpp" "src/lifters/pushvsp.cpp"
"src/lifters/read.cpp" "src/lifters/read.cpp"
"src/lifters/readcr8.cpp"
"src/lifters/sflags.cpp" "src/lifters/sflags.cpp"
"src/lifters/shl.cpp" "src/lifters/shl.cpp"
"src/lifters/shr.cpp" "src/lifters/shr.cpp"

@ -34,17 +34,18 @@ namespace vm
static lifter_callback_t addq, adddw, addw; static lifter_callback_t addq, adddw, addw;
static lifter_callback_t sregq, sregdw, sregb; static lifter_callback_t sregq, sregdw, sregb;
static lifter_callback_t lregq, lregdw; static lifter_callback_t lregq, lregdw;
static lifter_callback_t imulq; static lifter_callback_t imulq;
static lifter_callback_t pushvsp; static lifter_callback_t pushvsp;
static lifter_callback_t popvsp; static lifter_callback_t popvsp;
static lifter_callback_t writeq, writedw; static lifter_callback_t writeq, writedw;
static lifter_callback_t readq, readdw, readb; static lifter_callback_t readq, readdw, readw, readb;
static lifter_callback_t nandq, nanddw, nandb; static lifter_callback_t nandq, nanddw, nandb;
static lifter_callback_t shrq; static lifter_callback_t shrq, shrdw;
static lifter_callback_t shlq;
static lifter_callback_t jmp; static lifter_callback_t jmp;
static lifter_callback_t lflagsq; static lifter_callback_t lflagsq;
static lifter_callback_t vmexit; static lifter_callback_t vmexit;
static lifter_callback_t readcr8;
std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq }, std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq },
{ vm::handler::LCONSTDW, &lconstdw }, { vm::handler::LCONSTDW, &lconstdw },
@ -58,9 +59,11 @@ namespace vm
{ vm::handler::ADDDW, &adddw }, { vm::handler::ADDDW, &adddw },
{ vm::handler::ADDW, &addw }, { vm::handler::ADDW, &addw },
{ vm::handler::SHRQ, &shrq }, { vm::handler::SHRQ, &shrq },
{ vm::handler::SHRDW, &shrdw },
{ vm::handler::SHLQ, &shlq },
{ vm::handler::IMULQ, &imulq }, { vm::handler::IMULQ, &imulq },
{ vm::handler::PUSHVSP, &pushvsp }, { vm::handler::PUSHVSPQ, &pushvsp },
{ vm::handler::POPVSP, &popvsp }, { vm::handler::POPVSPQ, &popvsp },
{ vm::handler::SREGQ, &sregq }, { vm::handler::SREGQ, &sregq },
{ vm::handler::SREGDW, &sregdw }, { vm::handler::SREGDW, &sregdw },
{ vm::handler::SREGB, &sregb }, { vm::handler::SREGB, &sregb },
@ -68,6 +71,7 @@ namespace vm
{ vm::handler::LREGDW, &lregdw }, { vm::handler::LREGDW, &lregdw },
{ vm::handler::READQ, &readq }, { vm::handler::READQ, &readq },
{ vm::handler::READDW, &readdw }, { vm::handler::READDW, &readdw },
{ vm::handler::READW, &readw },
{ vm::handler::READB, &readb }, { vm::handler::READB, &readb },
{ vm::handler::WRITEQ, &writeq }, { vm::handler::WRITEQ, &writeq },
{ vm::handler::WRITEDW, &writedw }, { vm::handler::WRITEDW, &writedw },
@ -75,6 +79,7 @@ namespace vm
{ vm::handler::NANDDW, &nanddw }, { vm::handler::NANDDW, &nanddw },
{ vm::handler::NANDB, &nandb }, { vm::handler::NANDB, &nandb },
{ vm::handler::LFLAGSQ, &lflagsq }, { vm::handler::LFLAGSQ, &lflagsq },
{ vm::handler::READCR8, &readcr8 },
{ vm::handler::JMP, &jmp }, { vm::handler::JMP, &jmp },
{ vm::handler::VMEXIT, &vmexit } }; { vm::handler::VMEXIT, &vmexit } };

@ -20,6 +20,15 @@ namespace vm
rtn->push( 4, t3 ); rtn->push( 4, t3 );
}; };
lifters_t::lifter_callback_t lifters_t::readw =
[ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr,
llvm::IRBuilder<> *ir_builder ) {
auto t1 = rtn->pop( 8 );
auto t2 = ir_builder->CreateIntToPtr( t1, llvm::PointerType::get( ir_builder->getInt16Ty(), 0ull ) );
auto t3 = ir_builder->CreateLoad( ir_builder->getInt16Ty(), t2 );
rtn->push( 2, t3 );
};
lifters_t::lifter_callback_t lifters_t::readb = lifters_t::lifter_callback_t lifters_t::readb =
[ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr,
llvm::IRBuilder<> *ir_builder ) { llvm::IRBuilder<> *ir_builder ) {

@ -0,0 +1,26 @@
#include <vm_lifters.hpp>
namespace vm
{
lifters_t::lifter_callback_t lifters_t::readcr8 =
[ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr,
llvm::IRBuilder<> *ir_builder ) {
llvm::Function *readcr8_intrin = nullptr;
if ( !( readcr8_intrin = rtn->llvm_module->getFunction( "readcr8" ) ) )
{
readcr8_intrin = llvm::Function::Create( llvm::FunctionType::get( ir_builder->getInt64Ty(), false ),
llvm::GlobalValue::LinkageTypes::ExternalLinkage );
auto entry_block = llvm::BasicBlock::Create( ir_builder->getContext(), "", readcr8_intrin );
auto ib = ir_builder->GetInsertBlock();
ir_builder->SetInsertPoint( entry_block );
auto intrin = llvm::InlineAsm::get( llvm::FunctionType::get( ir_builder->getVoidTy(), false ),
"mov rax, cr8; ret", "", false, false, llvm::InlineAsm::AD_Intel );
ir_builder->CreateCall( intrin );
ir_builder->CreateRetVoid(); // TODO: dont return VOID here...
ir_builder->SetInsertPoint( ib );
}
auto t1 = ir_builder->CreateCall( readcr8_intrin );
rtn->push( 8, t1 );
};
}

@ -0,0 +1,19 @@
#include <vm_lifters.hpp>
namespace vm
{
lifters_t::lifter_callback_t lifters_t::shlq =
[ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr,
llvm::IRBuilder<> *ir_builder ) {
auto t1 = rtn->pop( 8 );
auto t2 = rtn->pop( 2 );
auto t3 = ir_builder->CreateIntCast( t2, llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), false );
auto t4 = ir_builder->CreateShl( t1, t3 );
auto &vmp_rtn = rtn->vmp_rtns.back();
// TODO: update rflags...
rtn->push( 8, t4 );
rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) );
};
}

@ -2,7 +2,6 @@
namespace vm namespace vm
{ {
// our undefined behavior is that we don't model cases where the shift count is zero...
llvm::Value *lifters_t::shr_flags( vm::devirt_t *rtn, std::uint8_t byte_size, llvm::Value *lhs, llvm::Value *rhs, llvm::Value *lifters_t::shr_flags( vm::devirt_t *rtn, std::uint8_t byte_size, llvm::Value *lhs, llvm::Value *rhs,
llvm::Value *result ) llvm::Value *result )
{ {
@ -10,19 +9,18 @@ namespace vm
auto msb = rtn->ir_builder->CreateLShr( lhs, ( byte_size * 8 ) - 1 ); auto msb = rtn->ir_builder->CreateLShr( lhs, ( byte_size * 8 ) - 1 );
auto cf = rtn->ir_builder->CreateZExt( msb, llvm::IntegerType::get( *rtn->llvm_ctx, 64 ) ); auto cf = rtn->ir_builder->CreateZExt( msb, llvm::IntegerType::get( *rtn->llvm_ctx, 64 ) );
auto of = auto of = rtn->sf( byte_size, lhs );
rtn->sf( byte_size, lhs ); // we reuse the compute_sf helper since the flag expression is the same
auto sf = rtn->sf( byte_size, result ); auto sf = rtn->sf( byte_size, result );
auto zf = rtn->zf( byte_size, result ); auto zf = rtn->zf( byte_size, result );
auto pf = llvm::ConstantInt::get( llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), 0 ); auto pf = llvm::ConstantInt::get( llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), 0 );
return rtn->flags( cf, pf, llvm::ConstantInt::get( llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), 0 ), return rtn->flags( cf, pf, llvm::ConstantInt::get( llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), 0 ), zf, sf,
zf, sf, of ); of );
} }
lifters_t::lifter_callback_t lifters_t::shrq = lifters_t::lifter_callback_t lifters_t::shrq =
[ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr,
const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { llvm::IRBuilder<> *ir_builder ) {
auto t1 = rtn->pop( 8 ); auto t1 = rtn->pop( 8 );
auto t2 = rtn->pop( 2 ); auto t2 = rtn->pop( 2 );
auto t3 = ir_builder->CreateIntCast( t2, llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), false ); auto t3 = ir_builder->CreateIntCast( t2, llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), false );
@ -34,4 +32,19 @@ namespace vm
rtn->push( 8, t4 ); rtn->push( 8, t4 );
rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) );
}; };
lifters_t::lifter_callback_t lifters_t::shrdw =
[ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr,
llvm::IRBuilder<> *ir_builder ) {
auto t1 = rtn->pop( 4 );
auto t2 = rtn->pop( 2 );
auto t3 = ir_builder->CreateIntCast( t2, llvm::IntegerType::get( *rtn->llvm_ctx, 32 ), false );
auto t4 = ir_builder->CreateLShr( t1, t3 );
auto &vmp_rtn = rtn->vmp_rtns.back();
auto flags = lifters_t::shr_flags( rtn, 4, t1, t3, t4 );
ir_builder->CreateStore( flags, vmp_rtn->flags );
rtn->push( 4, t4 );
rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) );
};
} // namespace vm } // namespace vm
Loading…
Cancel
Save