testing a new method for dealing with the stack...

merge-requests/2/head
_xeroxz 3 years ago
parent e45edafb81
commit 9ff8014de8

@ -38,11 +38,12 @@ namespace vm
std::uintptr_t rtn_begin, std::vector< vm::instrs::code_block_t > vmp2_code_blocks ); std::uintptr_t rtn_begin, std::vector< vm::instrs::code_block_t > vmp2_code_blocks );
llvm_function_t *lift( void ); llvm_function_t *lift( void );
private: private:
llvm_context_t *llvm_ctx; llvm_context_t *llvm_ctx;
llvm_module_t *llvm_module; llvm_module_t *llvm_module;
llvm_function_t *llvm_fptr; llvm_function_t *llvm_fptr;
llvm_alloca_inst_t *flags; llvm_alloca_inst_t *flags, *stack;
vm::ctx_t *vm_ctx; vm::ctx_t *vm_ctx;
std::uintptr_t rtn_begin; std::uintptr_t rtn_begin;

@ -5,6 +5,8 @@ namespace vm
lifters_t::lifter_callback_t lifters_t::pushvsp = lifters_t::lifter_callback_t lifters_t::pushvsp =
[ & ]( vm::vmp_rtn_t *rtn, const vm::instrs::code_block_t &vm_code_block, [ & ]( vm::vmp_rtn_t *rtn, const vm::instrs::code_block_t &vm_code_block,
const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) {
auto sp = rtn->pop( 8 );
auto sp_ptr = ir_builder->CreateIntToPtr( sp, llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ) );
ir_builder->CreateStore( sp_ptr, rtn->stack );
}; };
} }

@ -13,6 +13,9 @@ namespace vm
ir_builder = std::make_shared< llvm_irbuilder_t >( *llvm_ctx ); ir_builder = std::make_shared< llvm_irbuilder_t >( *llvm_ctx );
ir_builder->SetInsertPoint( llvm_code_blocks[ 0 ].second ); ir_builder->SetInsertPoint( llvm_code_blocks[ 0 ].second );
flags = ir_builder->CreateAlloca( ir_builder->getInt64Ty(), nullptr, "flags" ); flags = ir_builder->CreateAlloca( ir_builder->getInt64Ty(), nullptr, "flags" );
stack = ir_builder->CreateAlloca( llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ), nullptr, "sp" );
ir_builder->CreateStore( llvm_fptr->getArg( 0 ), stack );
create_virtual_registers(); create_virtual_registers();
} }
@ -30,7 +33,7 @@ namespace vm
// function has no arguments and returns void... maybe change this in the future as i learn // function has no arguments and returns void... maybe change this in the future as i learn
// more and more LLVM... // more and more LLVM...
auto func_ty = llvm::FunctionType::get( llvm::Type::getVoidTy( *llvm_ctx ), auto func_ty = llvm::FunctionType::get( llvm::Type::getVoidTy( *llvm_ctx ),
{ llvm::PointerType::getInt64PtrTy( *llvm_ctx ) }, false ); { llvm::PointerType::getInt8PtrTy( *llvm_ctx ) }, false );
// convert the rtn_begin address to a hex string and prepend "rtn_" to it... // convert the rtn_begin address to a hex string and prepend "rtn_" to it...
std::stringstream rtn_name; std::stringstream rtn_name;
@ -38,7 +41,6 @@ namespace vm
llvm_fptr = llvm::Function::Create( func_ty, llvm::GlobalValue::LinkageTypes::ExternalLinkage, llvm_fptr = llvm::Function::Create( func_ty, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
rtn_name.str().c_str(), *llvm_module ); rtn_name.str().c_str(), *llvm_module );
for ( const auto &vmp2_code_block : vmp2_code_blocks ) for ( const auto &vmp2_code_block : vmp2_code_blocks )
{ {
// create basic block name... block_xxxxxxxx format... // create basic block name... block_xxxxxxxx format...
@ -52,29 +54,34 @@ namespace vm
void vmp_rtn_t::push( std::uint8_t num_bytes, llvm_value_t *val ) void vmp_rtn_t::push( std::uint8_t num_bytes, llvm_value_t *val )
{ {
// sub rsp, num_bytes // sub rsp, num_bytes
auto rsp = llvm_fptr->getArg( 0 ); auto rsp_addr = ir_builder->CreateLoad( stack );
auto rsp_i64 = ir_builder->CreatePtrToInt( rsp, ir_builder->getInt64Ty() ); auto rsp_i64 = ir_builder->CreatePtrToInt( rsp_addr, ir_builder->getInt64Ty() );
auto sub_rsp_val = ir_builder->CreateSub( rsp_i64, ir_builder->getInt64( num_bytes ) ); auto sub_rsp_val = ir_builder->CreateSub( rsp_i64, ir_builder->getInt64( num_bytes ) );
ir_builder->CreateStore( sub_rsp_val, rsp ); ir_builder->CreateStore(
ir_builder->CreateIntToPtr( sub_rsp_val, llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ) ), stack );
// mov [rsp], val // mov [rsp], val
rsp_addr = ir_builder->CreateLoad( stack );
auto rsp_cast_ptr = ir_builder->CreatePointerCast( auto rsp_cast_ptr = ir_builder->CreatePointerCast(
rsp, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), false ) ); rsp_addr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), false ) );
ir_builder->CreateStore( val, rsp_cast_ptr ); ir_builder->CreateStore( val, rsp_cast_ptr );
} }
llvm_value_t *vmp_rtn_t::pop( std::uint8_t num_bytes ) llvm_value_t *vmp_rtn_t::pop( std::uint8_t num_bytes )
{ {
// mov rax, [rsp] // mov rax, [rsp]
auto rsp = llvm_fptr->getArg( 0 ); auto rsp_addr = ir_builder->CreateLoad( stack );
auto rsp_cast_ptr = ir_builder->CreatePointerCast( auto rsp_cast_ptr = ir_builder->CreatePointerCast(
rsp, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), false ) ); rsp_addr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), false ) );
auto pop_val = ir_builder->CreateLoad( rsp_cast_ptr ); auto pop_val = ir_builder->CreateLoad( rsp_cast_ptr );
// add rsp, num_bytes // add rsp, num_bytes
auto rsp_i64 = ir_builder->CreatePtrToInt( rsp, ir_builder->getInt64Ty() ); auto rsp_i64 = ir_builder->CreatePtrToInt( rsp_addr, ir_builder->getInt64Ty() );
auto sub_rsp_val = ir_builder->CreateAdd( rsp_i64, ir_builder->getInt64( num_bytes ) ); auto sub_rsp_val = ir_builder->CreateAdd( rsp_i64, ir_builder->getInt64( num_bytes ) );
ir_builder->CreateStore( sub_rsp_val, rsp ); auto sub_rsp_val_ptr =
ir_builder->CreateIntToPtr( sub_rsp_val, llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ) );
ir_builder->CreateStore( sub_rsp_val_ptr, stack );
return pop_val; return pop_val;
} }

Loading…
Cancel
Save