From 61cc8f0247183db21f13a0cb883a1ffd03f92f43 Mon Sep 17 00:00:00 2001 From: Artem Dinaburg Date: Wed, 16 Dec 2020 15:45:16 -0500 Subject: [PATCH 1/2] Gate inline assembly references of registers not in the spec vi a feature flag --- lib/Lift.cpp | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/lib/Lift.cpp b/lib/Lift.cpp index 5b2f230c9..f18192050 100644 --- a/lib/Lift.cpp +++ b/lib/Lift.cpp @@ -31,6 +31,12 @@ #include "anvill/Program.h" #include "anvill/Util.h" +#include + +DEFINE_bool( + feature_inline_asm_for_unspec_registers, false, + "Use an InlineAsm call to get values of registeres referenced in a function, but not present in it's specification"); + namespace anvill { namespace { @@ -206,19 +212,39 @@ static void DefineNativeToLiftedWrapper(const remill::Arch *arch, // the spec could feasibly miss some dependencies, and so after optimization, // we'll be able to observe uses of `__anvill_reg_*` globals, and handle // them appropriately. - arch->ForEachRegister([=, &ir](const remill::Register *reg_) { - if (auto reg = reg_->EnclosingRegister(); reg_ == reg) { - std::stringstream ss; - ss << "# read register " << reg->name; + if (FLAGS_feature_inline_asm_for_unspec_registers) { - llvm::InlineAsm *read_reg = - llvm::InlineAsm::get(llvm::FunctionType::get(reg->type, false), - ss.str(), "=r", true /* hasSideEffects */); + arch->ForEachRegister([=, &ir](const remill::Register *reg_) { + if (auto reg = reg_->EnclosingRegister(); reg_ == reg) { + std::stringstream ss; + ss << "# read register " << reg->name; - const auto reg_ptr = reg->AddressOf(state_ptr, block); - ir.CreateStore(ir.CreateCall(read_reg), reg_ptr); - } - }); + llvm::InlineAsm *read_reg = + llvm::InlineAsm::get(llvm::FunctionType::get(reg->type, false), + ss.str(), "=r", true /* hasSideEffects */); + + const auto reg_ptr = reg->AddressOf(state_ptr, block); + ir.CreateStore(ir.CreateCall(read_reg), reg_ptr); + } + }); + } else { + + arch->ForEachRegister([=, &ir](const remill::Register *reg_) { + if (auto reg = reg_->EnclosingRegister(); reg_ == reg) { + std::stringstream ss; + ss << "__anvill_reg_" << reg->name; + const auto reg_name = ss.str(); + auto reg_global = module->getGlobalVariable(reg_name); + if (!reg_global) { + reg_global = new llvm::GlobalVariable( + *module, reg->type, false, llvm::GlobalValue::ExternalLinkage, + nullptr, reg_name); + } + auto reg_ptr = reg->AddressOf(state_ptr, block); + ir.CreateStore(ir.CreateLoad(reg_global), reg_ptr); + } + }); + } // Store the program counter into the state. auto pc_reg = arch->RegisterByName(arch->ProgramCounterRegisterName()); From 1076660cc3dc013a30375957d0298e52968fb929 Mon Sep 17 00:00:00 2001 From: Artem Dinaburg Date: Wed, 16 Dec 2020 16:28:42 -0500 Subject: [PATCH 2/2] Address PR comments: move feature flag if inside loop --- lib/Lift.cpp | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/lib/Lift.cpp b/lib/Lift.cpp index f18192050..2196451fd 100644 --- a/lib/Lift.cpp +++ b/lib/Lift.cpp @@ -212,27 +212,23 @@ static void DefineNativeToLiftedWrapper(const remill::Arch *arch, // the spec could feasibly miss some dependencies, and so after optimization, // we'll be able to observe uses of `__anvill_reg_*` globals, and handle // them appropriately. - if (FLAGS_feature_inline_asm_for_unspec_registers) { - arch->ForEachRegister([=, &ir](const remill::Register *reg_) { - if (auto reg = reg_->EnclosingRegister(); reg_ == reg) { - std::stringstream ss; + arch->ForEachRegister([=, &ir](const remill::Register *reg_) { + if (auto reg = reg_->EnclosingRegister(); reg_ == reg) { + std::stringstream ss; + const auto reg_ptr = reg->AddressOf(state_ptr, block); + + if (FLAGS_feature_inline_asm_for_unspec_registers) { ss << "# read register " << reg->name; llvm::InlineAsm *read_reg = llvm::InlineAsm::get(llvm::FunctionType::get(reg->type, false), ss.str(), "=r", true /* hasSideEffects */); - const auto reg_ptr = reg->AddressOf(state_ptr, block); ir.CreateStore(ir.CreateCall(read_reg), reg_ptr); - } - }); - } else { - - arch->ForEachRegister([=, &ir](const remill::Register *reg_) { - if (auto reg = reg_->EnclosingRegister(); reg_ == reg) { - std::stringstream ss; + } else { ss << "__anvill_reg_" << reg->name; + const auto reg_name = ss.str(); auto reg_global = module->getGlobalVariable(reg_name); if (!reg_global) { @@ -240,11 +236,11 @@ static void DefineNativeToLiftedWrapper(const remill::Arch *arch, *module, reg->type, false, llvm::GlobalValue::ExternalLinkage, nullptr, reg_name); } - auto reg_ptr = reg->AddressOf(state_ptr, block); + ir.CreateStore(ir.CreateLoad(reg_global), reg_ptr); } - }); - } + } + }); // Store the program counter into the state. auto pc_reg = arch->RegisterByName(arch->ProgramCounterRegisterName());