From 4501dad2c08ffeef7e7de6b27d1c2d59c0077a5f Mon Sep 17 00:00:00 2001 From: Alessandro Di Federico Date: Wed, 11 Jan 2017 15:25:53 +0100 Subject: [PATCH] Introduce the `--no-link` option Introduce an option to prevent `revamb` from linking in all the QEMU helpers. This is useful if the output doesn't need to be compiled, but just analyzed. --- codegenerator.cpp | 17 ++++++++++------- codegenerator.h | 6 +++++- main.cpp | 8 ++++++-- variablemanager.cpp | 7 ++++++- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/codegenerator.cpp b/codegenerator.cpp index aad5d09ad..e2d5b9dd9 100644 --- a/codegenerator.cpp +++ b/codegenerator.cpp @@ -73,7 +73,8 @@ CodeGenerator::CodeGenerator(BinaryFile &Binary, std::string BBSummary, bool EnableOSRA, bool EnableTracing, - bool DetectFunctionBoundaries) : + bool DetectFunctionBoundaries, + bool EnableLinking) : TargetArchitecture(Target), Context(getGlobalContext()), TheModule((new Module("top", Context))), @@ -82,7 +83,8 @@ CodeGenerator::CodeGenerator(BinaryFile &Binary, Binary(Binary), EnableOSRA(EnableOSRA), EnableTracing(EnableTracing), - DetectFunctionBoundaries(DetectFunctionBoundaries) + DetectFunctionBoundaries(DetectFunctionBoundaries), + EnableLinking(EnableLinking) { OriginalInstrMDKind = Context.getMDKindID("oi"); PTCInstrMDKind = Context.getMDKindID("pi"); @@ -875,11 +877,12 @@ void CodeGenerator::translate(uint64_t VirtualAddress, GV.setLinkage(GlobalValue::InternalLinkage); } - Linker TheLinker(*TheModule); - bool Result = TheLinker.linkInModule(std::move(HelpersModule), - Linker::LinkOnlyNeeded); - assert(!Result && "Linking failed"); - (void) Result; + if (EnableLinking) { + Linker TheLinker(*TheModule); + bool Result = TheLinker.linkInModule(std::move(HelpersModule), + Linker::LinkOnlyNeeded); + assert(!Result && "Linking failed"); + } Variables.setDataLayout(&TheModule->getDataLayout()); diff --git a/codegenerator.h b/codegenerator.h index 0353cb6ad..6d932580d 100644 --- a/codegenerator.h +++ b/codegenerator.h @@ -63,6 +63,8 @@ public: /// \param EnableTracing specify whether tracing in the ouptut binary should /// be enabled, that is, whether calls to an external `newPC` function /// should be removed at the end of the translation or not. + /// \param EnableLinking specifying whether linking to QEMU helpers should be + /// performed or not. CodeGenerator(BinaryFile &Binary, Architecture &Target, std::string Output, @@ -74,7 +76,8 @@ public: std::string BBSummary, bool EnableOSRA, bool EnableTracing, - bool DetectFunctionBoundaries); + bool DetectFunctionBoundaries, + bool EnableLinking); ~CodeGenerator(); @@ -123,6 +126,7 @@ private: std::string BBSummaryPath; std::string FunctionListPath; bool DetectFunctionBoundaries; + bool EnableLinking; }; #endif // _CODEGENERATOR_H diff --git a/main.cpp b/main.cpp index 4f813e115..0f739f89d 100644 --- a/main.cpp +++ b/main.cpp @@ -52,6 +52,7 @@ struct ProgramParameters { bool EnableTracing; bool UseSections; bool DetectFunctionsBoundaries; + bool NoLink; }; using LibraryDestructor = GenericFunctor; @@ -178,7 +179,9 @@ static int parseArgs(int Argc, const char *Argv[], &DebugLoggingString, "enable verbose logging."), OPT_BOOLEAN('O', "no-osra", &Parameters->NoOSRA, - "disable OSRA"), + "disable OSRA."), + OPT_BOOLEAN('L', "no-link", &Parameters->NoLink, + "do not link the output to QEMU helpers."), OPT_BOOLEAN('t', "tracing", &Parameters->EnableTracing, "enable PC tracing in the output binary (through newPC)"), OPT_BOOLEAN('S', "use-sections", &Parameters->UseSections, @@ -287,7 +290,8 @@ int main(int argc, const char *argv[]) { std::string(Parameters.BBSummaryPath), !Parameters.NoOSRA, Parameters.EnableTracing, - Parameters.DetectFunctionsBoundaries); + Parameters.DetectFunctionsBoundaries, + !Parameters.NoLink); Generator.translate(Parameters.EntryPointAddress, "root"); diff --git a/variablemanager.cpp b/variablemanager.cpp index f25305351..e01d49733 100644 --- a/variablemanager.cpp +++ b/variablemanager.cpp @@ -296,7 +296,12 @@ bool CorrectCPUStateUsagePass::runOnModule(Module& TheModule) { continue; } - assert(!Callee->empty() && "external functions are not supported"); + assert((Callee->getName().startswith("helper") + || !Callee->empty()) + && "external functions are not supported"); + + if (Callee->empty()) + break; // TODO: move all the specialization-handling code outside // Is the callee already a specialization?