|
|
|
@ -13,9 +13,10 @@ namespace vm
|
|
|
|
|
ir_builder = std::make_shared< llvm_irbuilder_t >( *llvm_ctx );
|
|
|
|
|
ir_builder->SetInsertPoint( llvm_code_blocks[ 0 ].second );
|
|
|
|
|
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_stack();
|
|
|
|
|
// TODO: copy arg1 (array) onto the local stack...
|
|
|
|
|
// ir_builder->CreateMemCpy(...
|
|
|
|
|
create_virtual_registers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -32,8 +33,9 @@ namespace vm
|
|
|
|
|
{
|
|
|
|
|
// function has no arguments and returns void... maybe change this in the future as i learn
|
|
|
|
|
// more and more LLVM...
|
|
|
|
|
auto func_ty = llvm::FunctionType::get( llvm::Type::getVoidTy( *llvm_ctx ),
|
|
|
|
|
{ llvm::PointerType::getInt8PtrTy( *llvm_ctx ) }, false );
|
|
|
|
|
auto func_ty =
|
|
|
|
|
llvm::FunctionType::get( llvm::Type::getVoidTy( *llvm_ctx ),
|
|
|
|
|
{ llvm::ArrayType::get( llvm::IntegerType::get( *llvm_ctx, 64 ), 21 ) }, false );
|
|
|
|
|
|
|
|
|
|
// convert the rtn_begin address to a hex string and prepend "rtn_" to it...
|
|
|
|
|
std::stringstream rtn_name;
|
|
|
|
@ -41,6 +43,7 @@ namespace vm
|
|
|
|
|
llvm_fptr = llvm::Function::Create( func_ty, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
|
|
|
|
|
rtn_name.str().c_str(), *llvm_module );
|
|
|
|
|
|
|
|
|
|
llvm_fptr->setCallingConv( llvm::CallingConv::X86_FastCall );
|
|
|
|
|
for ( const auto &vmp2_code_block : vmp2_code_blocks )
|
|
|
|
|
{
|
|
|
|
|
// create basic block name... block_xxxxxxxx format...
|
|
|
|
@ -53,36 +56,53 @@ namespace vm
|
|
|
|
|
|
|
|
|
|
void vmp_rtn_t::push( std::uint8_t num_bytes, llvm_value_t *val )
|
|
|
|
|
{
|
|
|
|
|
// sub rsp, num_bytes
|
|
|
|
|
auto rsp_addr = ir_builder->CreateLoad( stack );
|
|
|
|
|
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 ) );
|
|
|
|
|
ir_builder->CreateStore(
|
|
|
|
|
ir_builder->CreateIntToPtr( sub_rsp_val, llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ) ), stack );
|
|
|
|
|
|
|
|
|
|
// mov [rsp], val
|
|
|
|
|
rsp_addr = ir_builder->CreateLoad( stack );
|
|
|
|
|
auto rsp_cast_ptr = ir_builder->CreatePointerCast(
|
|
|
|
|
rsp_addr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), false ) );
|
|
|
|
|
ir_builder->CreateStore( val, rsp_cast_ptr );
|
|
|
|
|
auto spi = ir_builder->CreateLoad( ir_builder->getInt64Ty(), stack_ptr, false );
|
|
|
|
|
spi->setAlignment( llvm::Align( 1 ) );
|
|
|
|
|
|
|
|
|
|
auto new_spi = ir_builder->CreateSub( spi, llvm::ConstantInt::get( ir_builder->getInt64Ty(), num_bytes ) );
|
|
|
|
|
ir_builder->CreateStore( new_spi, stack_ptr )->setAlignment( llvm::Align( 1 ) );
|
|
|
|
|
|
|
|
|
|
auto *i64_zero = llvm::ConstantInt::get( *llvm_ctx, llvm::APInt( 64, 0 ) );
|
|
|
|
|
llvm_value_t *indices[ 2 ] = { i64_zero, new_spi };
|
|
|
|
|
auto stack_ptr = ir_builder->CreateInBoundsGEP( virtual_stack, llvm::ArrayRef< llvm_value_t * >( indices, 2 ) );
|
|
|
|
|
|
|
|
|
|
if ( num_bytes > 1 )
|
|
|
|
|
{
|
|
|
|
|
auto casted_ptr = ir_builder->CreatePointerCast(
|
|
|
|
|
stack_ptr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), 0 ) );
|
|
|
|
|
|
|
|
|
|
ir_builder->CreateStore( val, casted_ptr )->setAlignment( llvm::Align( 1 ) );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
ir_builder->CreateStore( val, stack_ptr )->setAlignment( llvm::Align( 1 ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llvm_value_t *vmp_rtn_t::pop( std::uint8_t num_bytes )
|
|
|
|
|
{
|
|
|
|
|
// mov rax, [rsp]
|
|
|
|
|
auto rsp_addr = ir_builder->CreateLoad( stack );
|
|
|
|
|
auto rsp_cast_ptr = ir_builder->CreatePointerCast(
|
|
|
|
|
rsp_addr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), false ) );
|
|
|
|
|
auto pop_val = ir_builder->CreateLoad( rsp_cast_ptr );
|
|
|
|
|
|
|
|
|
|
// add rsp, num_bytes
|
|
|
|
|
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_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;
|
|
|
|
|
llvm_value_t *output_value = nullptr;
|
|
|
|
|
auto current_spi = ir_builder->CreateLoad( ir_builder->getInt64Ty(), stack_ptr, false );
|
|
|
|
|
current_spi->setAlignment( llvm::Align( 1 ) );
|
|
|
|
|
|
|
|
|
|
llvm_value_t *i64_zero = llvm::ConstantInt::get( *llvm_ctx, llvm::APInt( 64, 0 ) );
|
|
|
|
|
llvm_value_t *indices[ 2 ] = { i64_zero, current_spi };
|
|
|
|
|
auto top_stack = ir_builder->CreateInBoundsGEP( virtual_stack, llvm::ArrayRef< llvm::Value * >( indices, 2 ) );
|
|
|
|
|
|
|
|
|
|
if ( num_bytes > 1 )
|
|
|
|
|
{
|
|
|
|
|
auto casted_ptr = ir_builder->CreatePointerCast(
|
|
|
|
|
top_stack, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), 0 ) );
|
|
|
|
|
|
|
|
|
|
output_value = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), casted_ptr );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
output_value = ir_builder->CreateLoad( ir_builder->getInt8Ty(), top_stack );
|
|
|
|
|
|
|
|
|
|
static_cast< llvm::LoadInst * >( output_value )->setAlignment( llvm::Align( 1 ) );
|
|
|
|
|
auto new_spi = ir_builder->CreateAdd(
|
|
|
|
|
current_spi, llvm::ConstantInt::get( llvm::IntegerType::get( *llvm_ctx, 64 ), num_bytes ) );
|
|
|
|
|
|
|
|
|
|
ir_builder->CreateStore( new_spi, stack_ptr )->setAlignment( llvm::Align( 1 ) );
|
|
|
|
|
return output_value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llvm_value_t *vmp_rtn_t::load_value( std::uint8_t byte_size, llvm_global_value_t *var )
|
|
|
|
@ -92,9 +112,13 @@ namespace vm
|
|
|
|
|
auto cast_ptr = ir_builder->CreatePointerCast(
|
|
|
|
|
var, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), 0 ) );
|
|
|
|
|
|
|
|
|
|
return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), cast_ptr );
|
|
|
|
|
auto result = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), cast_ptr );
|
|
|
|
|
result->setAlignment( llvm::Align( 1 ) );
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), var );
|
|
|
|
|
auto result = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), var );
|
|
|
|
|
result->setAlignment( llvm::Align( 1 ) );
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llvm_value_t *vmp_rtn_t::load_value( std::uint8_t byte_size, llvm_alloca_inst_t *var )
|
|
|
|
@ -104,9 +128,14 @@ namespace vm
|
|
|
|
|
auto cast_ptr = ir_builder->CreatePointerCast(
|
|
|
|
|
var, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), 0 ) );
|
|
|
|
|
|
|
|
|
|
return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), cast_ptr );
|
|
|
|
|
auto result = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), cast_ptr );
|
|
|
|
|
result->setAlignment( llvm::Align( 1 ) );
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), var );
|
|
|
|
|
|
|
|
|
|
auto result = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), var );
|
|
|
|
|
result->setAlignment( llvm::Align( 1 ) );
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llvm_function_t *vmp_rtn_t::lift( void )
|
|
|
|
@ -131,6 +160,18 @@ namespace vm
|
|
|
|
|
return llvm_fptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void vmp_rtn_t::create_virtual_stack( void )
|
|
|
|
|
{
|
|
|
|
|
// allocate stack space...
|
|
|
|
|
virtual_stack = ir_builder->CreateAlloca( llvm::ArrayType::get( llvm::IntegerType::get( *llvm_ctx, 8 ), 1024 ),
|
|
|
|
|
nullptr, "stack" );
|
|
|
|
|
|
|
|
|
|
// allocate stack pointer...
|
|
|
|
|
stack_ptr = ir_builder->CreateAlloca( llvm::IntegerType::get( *llvm_ctx, 64 ), nullptr, "sp" );
|
|
|
|
|
ir_builder->CreateStore( llvm::ConstantInt::get( llvm::IntegerType::getInt64Ty( *llvm_ctx ), 1024 ),
|
|
|
|
|
stack_ptr );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llvm_value_t *vmp_rtn_t::compute_sf( std::uint8_t byte_size, llvm_value_t *val )
|
|
|
|
|
{
|
|
|
|
|
auto op_size = llvm::IntegerType::get( *llvm_ctx, byte_size * 8 );
|
|
|
|
|