Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
namespace psr {
class LLVMTypeHierarchy;
class LLVMProjectIRDB;
class Resolver;

class LLVMBasedICFG;
template <> struct CFGTraits<LLVMBasedICFG> : CFGTraits<LLVMBasedCFG> {};
Expand Down Expand Up @@ -87,6 +88,11 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
LLVMAliasInfoRef PT = nullptr,
Soundness S = Soundness::Soundy,
bool IncludeGlobals = true);
explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
llvm::ArrayRef<std::string> EntryPoints = {},
LLVMTypeHierarchy *TH = nullptr,
Soundness S = Soundness::Soundy,
bool IncludeGlobals = true);

/// Creates an ICFG with an already given call-graph
explicit LLVMBasedICFG(CallGraph<n_t, f_t> CG, LLVMProjectIRDB *IRDB,
Expand Down Expand Up @@ -157,6 +163,10 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
[[nodiscard]] llvm::Function *buildCRuntimeGlobalCtorsDtorsModel(
llvm::Module &M, llvm::ArrayRef<llvm::Function *> UserEntryPoints);

void initialize(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
llvm::ArrayRef<std::string> EntryPoints,
LLVMTypeHierarchy *TH, Soundness S, bool IncludeGlobals);

// ---

CallGraph<const llvm::Instruction *, const llvm::Function *> CG;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,14 @@ class Value;

namespace psr {

class LLVMBasedICFG;
class LLVMTypeHierarchy;

class OTFResolver : public Resolver {
protected:
LLVMBasedICFG &ICF;
LLVMAliasInfoRef PT;

public:
OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH, LLVMBasedICFG &ICF,
OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH,
LLVMAliasInfoRef PT);

~OTFResolver() override = default;
Expand Down
8 changes: 4 additions & 4 deletions include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ namespace psr {
class LLVMProjectIRDB;
class LLVMTypeHierarchy;
enum class CallGraphAnalysisType;
class LLVMBasedICFG;
class LLVMPointsToInfo;

[[nodiscard]] std::optional<unsigned>
Expand Down Expand Up @@ -83,9 +82,10 @@ class Resolver {

[[nodiscard]] virtual std::string str() const = 0;

static std::unique_ptr<Resolver>
create(CallGraphAnalysisType Ty, LLVMProjectIRDB *IRDB, LLVMTypeHierarchy *TH,
LLVMBasedICFG *ICF = nullptr, LLVMAliasInfoRef PT = nullptr);
static std::unique_ptr<Resolver> create(CallGraphAnalysisType Ty,
LLVMProjectIRDB *IRDB,
LLVMTypeHierarchy *TH,
LLVMAliasInfoRef PT = nullptr);
};
} // namespace psr

Expand Down
58 changes: 37 additions & 21 deletions lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"

#include "phasar/Config/Configuration.h"
#include "phasar/ControlFlow/CallGraph.h"
#include "phasar/ControlFlow/CallGraphAnalysisType.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h"
Expand All @@ -24,27 +23,22 @@
#include "phasar/Utils/MaybeUniquePtr.h"
#include "phasar/Utils/PAMMMacros.h"
#include "phasar/Utils/Soundness.h"
#include "phasar/Utils/TypeTraits.h"
#include "phasar/Utils/Utilities.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/Support/ErrorHandling.h"

#include <cstdint>
#include <utility>

namespace psr {
struct LLVMBasedICFG::Builder {
LLVMProjectIRDB *IRDB = nullptr;
LLVMAliasInfoRef PT{};
LLVMTypeHierarchy *TH{};
Resolver *Res = nullptr;
CallGraphBuilder<const llvm::Instruction *, const llvm::Function *>
CGBuilder{};
std::unique_ptr<Resolver> Res = nullptr;
llvm::DenseSet<const llvm::Function *> VisitedFunctions{};
llvm::SmallVector<llvm::Function *, 1> UserEntryPoints{};

Expand Down Expand Up @@ -321,6 +315,28 @@ bool LLVMBasedICFG::Builder::constructDynamicCall(const llvm::Instruction *CS) {
return NewTargetsFound;
}

void LLVMBasedICFG::initialize(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
llvm::ArrayRef<std::string> EntryPoints,
LLVMTypeHierarchy *TH, Soundness S,
bool IncludeGlobals) {
Builder B{IRDB, this->TH.get(), &CGResolver};

B.initEntryPoints(EntryPoints);
B.initGlobalsAndWorkList(this, IncludeGlobals);

PHASAR_LOG_LEVEL_CAT(
INFO, "LLVMBasedICFG",
"Starting ICFG construction "
<< std::chrono::steady_clock::now().time_since_epoch().count());

this->CG = B.buildCallGraph(S);

PHASAR_LOG_LEVEL_CAT(
INFO, "LLVMBasedICFG",
"Finished ICFG construction "
<< std::chrono::steady_clock::now().time_since_epoch().count());
}

LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB,
CallGraphAnalysisType CGType,
llvm::ArrayRef<std::string> EntryPoints,
Expand All @@ -333,29 +349,29 @@ LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB,
this->TH = std::make_unique<LLVMTypeHierarchy>(*IRDB);
}

Builder B{IRDB, PT, this->TH.get()};
LLVMAliasInfo PTOwn;

if (!PT && CGType == CallGraphAnalysisType::OTF) {
PTOwn = std::make_unique<LLVMAliasSet>(IRDB);
B.PT = PTOwn.asRef();
PT = PTOwn.asRef();
}

B.Res = Resolver::create(CGType, IRDB, this->TH.get(), this, B.PT);
B.initEntryPoints(EntryPoints);
B.initGlobalsAndWorkList(this, IncludeGlobals);
auto CGRes = Resolver::create(CGType, IRDB, this->TH.get(), PT);
initialize(IRDB, *CGRes, EntryPoints, TH, S, IncludeGlobals);
}

PHASAR_LOG_LEVEL_CAT(
INFO, "LLVMBasedICFG",
"Starting ICFG construction "
<< std::chrono::steady_clock::now().time_since_epoch().count());
LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
llvm::ArrayRef<std::string> EntryPoints,
LLVMTypeHierarchy *TH, Soundness S,
bool IncludeGlobals)
: IRDB(IRDB), TH(TH) {
assert(IRDB != nullptr);

this->CG = B.buildCallGraph(S);
if (!TH) {
this->TH = std::make_unique<LLVMTypeHierarchy>(*IRDB);
}

PHASAR_LOG_LEVEL_CAT(
INFO, "LLVMBasedICFG",
"Finished ICFG construction "
<< std::chrono::steady_clock::now().time_since_epoch().count());
initialize(IRDB, CGResolver, EntryPoints, TH, S, IncludeGlobals);
}

LLVMBasedICFG::LLVMBasedICFG(CallGraph<n_t, f_t> CG, LLVMProjectIRDB *IRDB,
Expand Down
6 changes: 3 additions & 3 deletions lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
using namespace psr;

OTFResolver::OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH,
LLVMBasedICFG &ICF, LLVMAliasInfoRef PT)
: Resolver(IRDB, TH), ICF(ICF), PT(PT) {}
LLVMAliasInfoRef PT)
: Resolver(IRDB, TH), PT(PT) {}

void OTFResolver::preCall(const llvm::Instruction *Inst) {}

Expand All @@ -55,7 +55,7 @@ void OTFResolver::handlePossibleTargets(const llvm::CallBase *CallSite,
}
// handle return value
if (CalleeTarget->getReturnType()->isPointerTy()) {
for (const auto &ExitPoint : ICF.getExitPointsOf(CalleeTarget)) {
for (const auto &ExitPoint : psr::getAllExitPoints(CalleeTarget)) {
// get the function's return value
if (const auto *Ret = llvm::dyn_cast<llvm::ReturnInst>(ExitPoint)) {
// introduce alias to the returned value
Expand Down
5 changes: 1 addition & 4 deletions lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ void RTAResolver::resolveAllocatedStructTypes() {
}

llvm::DenseSet<const llvm::StructType *> AllocatedStructTypes;
const llvm::StringSet<> MemAllocatingFunctions = {"_Znwm", "_Znam", "malloc",
"calloc", "realloc"};

for (const auto *Fun : IRDB.getAllFunctions()) {
for (const auto &Inst : llvm::instructions(Fun)) {
Expand All @@ -114,8 +112,7 @@ void RTAResolver::resolveAllocatedStructTypes() {
// check if an instance of a user-defined type is allocated on the
// heap

if (!MemAllocatingFunctions.contains(
CallSite->getCalledFunction()->getName())) {
if (!isHeapAllocatingFunction(CallSite->getCalledFunction())) {
continue;
}
/// TODO: Does this iteration over the users make sense?
Expand Down
6 changes: 2 additions & 4 deletions lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ auto Resolver::resolveFunctionPointer(const llvm::CallBase *CallSite)
FunctionSetTy CalleeTargets;

for (const auto *F : IRDB.getAllFunctions()) {
if (isConsistentCall(CallSite, F)) {
if (F->hasAddressTaken() && isConsistentCall(CallSite, F)) {
CalleeTargets.insert(F);
}
}
Expand All @@ -158,7 +158,6 @@ void Resolver::otherInst(const llvm::Instruction *Inst) {}
std::unique_ptr<Resolver> Resolver::create(CallGraphAnalysisType Ty,
LLVMProjectIRDB *IRDB,
LLVMTypeHierarchy *TH,
LLVMBasedICFG *ICF,
LLVMAliasInfoRef PT) {
assert(IRDB != nullptr);

Expand All @@ -179,9 +178,8 @@ std::unique_ptr<Resolver> Resolver::create(CallGraphAnalysisType Ty,
"The VTA callgraph algorithm is not implemented yet");
case CallGraphAnalysisType::OTF:
assert(TH != nullptr);
assert(ICF != nullptr);
assert(PT);
return std::make_unique<OTFResolver>(*IRDB, *TH, *ICF, PT);
return std::make_unique<OTFResolver>(*IRDB, *TH, PT);
case CallGraphAnalysisType::Invalid:
llvm::report_fatal_error("Invalid callgraph algorithm specified");
}
Expand Down
2 changes: 1 addition & 1 deletion utils/InstallAptDependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ set -e

sudo apt-get update
sudo apt-get install git -y
sudo apt-get install zlib1g-dev python3 g++ ninja-build cmake -y
sudo apt-get install zlib1g-dev python3 python3-pip g++ ninja-build cmake -y