mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
DetectABI: inline helpers
Inline `revng_inline` helper calls into each outlined stub which is consumed by `analyzeABI`, so the analysis can observe the reads and writes the helper performs on the floating point registers. The helper module is linked only once at the beginning of the pass, to avoid double linking issues.
This commit is contained in:
committed by
Alessandro Di Federico
parent
06733a9f3a
commit
6a56557177
@@ -35,6 +35,7 @@ target_link_libraries(
|
||||
revngEarlyFunctionAnalysis
|
||||
revngBasicAnalyses
|
||||
revngABI
|
||||
revngInlineHelpers
|
||||
revngSupport
|
||||
revngModel
|
||||
revngPipes
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "revng/EarlyFunctionAnalysis/DetectABI.h"
|
||||
#include "revng/EarlyFunctionAnalysis/FunctionEdgeBase.h"
|
||||
#include "revng/EarlyFunctionAnalysis/FunctionSummaryOracle.h"
|
||||
#include "revng/InlineHelpers/InlineHelpers.h"
|
||||
#include "revng/InlineHelpers/LinkHelpersToInline.h"
|
||||
#include "revng/Model/Binary.h"
|
||||
#include "revng/Model/NameBuilder.h"
|
||||
#include "revng/Model/Pass/DeduplicateCollidingNames.h"
|
||||
@@ -107,6 +109,7 @@ public:
|
||||
Manager.add(new LoadModelWrapperPass(ModelWrapper(Global->get())));
|
||||
Manager.add(new CollectFunctionsFromCalleesWrapperPass());
|
||||
Manager.add(new ControlFlowGraphCachePass(CFGs));
|
||||
Manager.add(new LinkHelpersToInlinePass());
|
||||
Manager.add(new efa::DetectABIPass());
|
||||
Manager.add(new CollectFunctionsFromUnusedAddressesWrapperPass());
|
||||
Manager.add(new efa::DetectABIPass());
|
||||
@@ -451,7 +454,7 @@ void DetectABI::analyzeABI() {
|
||||
revng_log(Log, "Running ABI analyses");
|
||||
LoggerIndent Indent(Log);
|
||||
|
||||
llvm::Task Task(2, "analyzeABI");
|
||||
llvm::Task Task(3, "analyzeABI");
|
||||
std::map<MetaAddress, std::unique_ptr<OutlinedFunction>> Functions;
|
||||
|
||||
// Create all temporary functions
|
||||
@@ -463,6 +466,23 @@ void DetectABI::analyzeABI() {
|
||||
Functions[Function.Entry()] = std::move(NewFunction);
|
||||
}
|
||||
|
||||
// Inline `revng_inline`-tagged helper calls so the subsequent ABI dataflow
|
||||
// analysis can observe the helpers' register reads and writes directly.
|
||||
// `InlineHelpersPass` only inlines into `Isolated` functions, so we tag the
|
||||
// outlined stubs as such. These stubs are temporary and are discarded with
|
||||
// the cloned module once the analysis ends, so the tag never escapes.
|
||||
// Helpers whose per-call critical arguments are not LLVM constants here
|
||||
// survive un-inlined and are consumed as opaque calls by the analysis.
|
||||
for (auto &[Entry, OutlinedFn] : Functions)
|
||||
FunctionTags::Isolated.addTo(OutlinedFn->Function.get());
|
||||
|
||||
Task.advance("Inline helpers");
|
||||
{
|
||||
llvm::legacy::PassManager PM;
|
||||
PM.add(new InlineHelpersPass());
|
||||
PM.run(M);
|
||||
}
|
||||
|
||||
// Push this into analyzeFunction
|
||||
OpaqueRegisterUser RegisterUser(&M);
|
||||
|
||||
@@ -1117,6 +1137,14 @@ llvm::Error DetectABI::run(Model &Model,
|
||||
revng::pipes::CFGMap CFGs("");
|
||||
ControlFlowGraphCache FMC(CFGs);
|
||||
|
||||
// Link helper bodies once at the start of the analysis, to avoid relinking
|
||||
// for every `inline-helpers` call
|
||||
{
|
||||
llvm::legacy::PassManager PM;
|
||||
PM.add(new LinkHelpersToInlinePass());
|
||||
PM.run(Module);
|
||||
}
|
||||
|
||||
collectFunctionsFromCallees(Module, GCBI, Binary);
|
||||
efa::runDetectABI(Module, GCBI, FMC, TupleModel);
|
||||
collectFunctionsFromUnusedAddresses(Module, GCBI, Binary, FMC);
|
||||
|
||||
Reference in New Issue
Block a user