Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split LLVMBasedICFG #726

Open
wants to merge 11 commits into
base: development
Choose a base branch
from
1 change: 1 addition & 0 deletions include/phasar/PhasarLLVM/ControlFlow.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_H
#define PHASAR_PHASARLLVM_CONTROLFLOW_H

#include "phasar/PhasarLLVM/ControlFlow/EntryFunctionUtils.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardCFG.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h"
Expand Down
31 changes: 31 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/EntryFunctionUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/******************************************************************************
* Copyright (c) 2024 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_UTILS_ENTRYFUNCTIONUTILS_H
#define PHASAR_PHASARLLVM_UTILS_ENTRYFUNCTIONUTILS_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/Function.h"

#include <string>
#include <vector>

namespace psr {
class LLVMProjectIRDB;

[[nodiscard]] std::vector<const llvm::Function *>
getEntryFunctions(const LLVMProjectIRDB &IRDB,
llvm::ArrayRef<std::string> EntryPoints);

[[nodiscard]] std::vector<llvm::Function *>
getEntryFunctionsMut(LLVMProjectIRDB &IRDB,
llvm::ArrayRef<std::string> EntryPoints);
} // namespace psr

#endif // PHASAR_PHASARLLVM_UTILS_ENTRYFUNCTIONUTILS_H
45 changes: 45 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/GlobalCtorsDtorsModel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/******************************************************************************
* Copyright (c) 2024 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_GLOBALCTORSDTORSMODEL_H
#define PHASAR_PHASARLLVM_CONTROLFLOW_GLOBALCTORSDTORSMODEL_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/Function.h"

namespace psr {
class LLVMProjectIRDB;

class GlobalCtorsDtorsModel {
public:
static constexpr llvm::StringLiteral ModelName =
"__psrCRuntimeGlobalCtorsModel";

static constexpr llvm::StringLiteral DtorModelName =
"__psrCRuntimeGlobalDtorsModel";

static constexpr llvm::StringLiteral DtorsCallerName =
"__psrGlobalDtorsCaller";

static constexpr llvm::StringLiteral UserEntrySelectorName =
"__psrCRuntimeUserEntrySelector";

static llvm::Function *
buildModel(LLVMProjectIRDB &IRDB,
llvm::ArrayRef<llvm::Function *> UserEntryPoints);
static llvm::Function *
buildModel(LLVMProjectIRDB &IRDB,
llvm::ArrayRef<std::string> UserEntryPoints);

/// Returns true, if a function was generated by phasar.
[[nodiscard]] static bool isPhasarGenerated(const llvm::Function &F) noexcept;
};
} // namespace psr

#endif // PHASAR_PHASARLLVM_CONTROLFLOW_GLOBALCTORSDTORSMODEL_H
25 changes: 25 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedCallGraph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/******************************************************************************
* Copyright (c) 2024 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPH_H
#define PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPH_H

#include "phasar/ControlFlow/CallGraph.h"

namespace llvm {
class Instruction;
class Function;
} // namespace llvm

namespace psr {
using LLVMBasedCallGraph =
CallGraph<const llvm::Instruction *, const llvm::Function *>;
} // namespace psr

#endif // PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPH_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/******************************************************************************
* Copyright (c) 2024 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPHBUILDER_H
#define PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPHBUILDER_H

#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCallGraph.h"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
#include "phasar/Utils/Soundness.h"

namespace psr {
class LLVMProjectIRDB;
enum class CallGraphAnalysisType;
class LLVMTypeHierarchy;
class LLVMVFTableProvider;
class Resolver;

[[nodiscard]] LLVMBasedCallGraph
buildLLVMBasedCallGraph(LLVMProjectIRDB &IRDB, CallGraphAnalysisType CGType,
llvm::ArrayRef<const llvm::Function *> EntryPoints,
LLVMTypeHierarchy &TH, LLVMVFTableProvider &VTP,
LLVMAliasInfoRef PT = nullptr,
Soundness S = Soundness::Soundy);

[[nodiscard]] LLVMBasedCallGraph
buildLLVMBasedCallGraph(const LLVMProjectIRDB &IRDB, Resolver &CGResolver,
llvm::ArrayRef<const llvm::Function *> EntryPoints,
Soundness S = Soundness::Soundy);

[[nodiscard]] LLVMBasedCallGraph
buildLLVMBasedCallGraph(LLVMProjectIRDB &IRDB, CallGraphAnalysisType CGType,
llvm::ArrayRef<std::string> EntryPoints,
LLVMTypeHierarchy &TH, LLVMVFTableProvider &VTP,
LLVMAliasInfoRef PT = nullptr,
Soundness S = Soundness::Soundy);

[[nodiscard]] LLVMBasedCallGraph
buildLLVMBasedCallGraph(const LLVMProjectIRDB &IRDB, Resolver &CGResolver,
llvm::ArrayRef<std::string> EntryPoints,
Soundness S = Soundness::Soundy);
} // namespace psr

#endif // PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDCALLGRAPHBUILDER_H
46 changes: 23 additions & 23 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@
#include "phasar/ControlFlow/CallGraph.h"
#include "phasar/ControlFlow/CallGraphAnalysisType.h"
#include "phasar/ControlFlow/ICFGBase.h"
#include "phasar/PhasarLLVM/ControlFlow/GlobalCtorsDtorsModel.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCallGraph.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
#include "phasar/PhasarLLVM/Utils/LLVMBasedContainerConfig.h"
#include "phasar/Utils/MaybeUniquePtr.h"
#include "phasar/Utils/Soundness.h"

#include "llvm/ADT/ArrayRef.h"
Expand All @@ -34,8 +37,7 @@
#include "llvm/Support/raw_ostream.h"

#include "nlohmann/json.hpp"

#include <memory>
#include "nlohmann/json_fwd.hpp"

namespace psr {
class LLVMTypeHierarchy;
Expand All @@ -48,20 +50,10 @@ template <> struct CFGTraits<LLVMBasedICFG> : CFGTraits<LLVMBasedCFG> {};
class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
friend ICFGBase;

struct Builder;

public:
// For backward compatibility
static constexpr llvm::StringLiteral GlobalCRuntimeModelName =
"__psrCRuntimeGlobalCtorsModel";

static constexpr llvm::StringLiteral GlobalCRuntimeDtorModelName =
"__psrCRuntimeGlobalDtorsModel";

static constexpr llvm::StringLiteral GlobalCRuntimeDtorsCallerName =
"__psrGlobalDtorsCaller";

static constexpr llvm::StringLiteral GlobalCRuntimeUserEntrySelectorName =
"__psrCRuntimeUserEntrySelector";
GlobalCtorsDtorsModel::ModelName;

/// Constructs the ICFG based on the given IRDB and the entry-points using a
/// fixpoint iteration. This may take a long time.
Expand Down Expand Up @@ -97,10 +89,16 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
bool IncludeGlobals = true);

/// Creates an ICFG with an already given call-graph
explicit LLVMBasedICFG(CallGraph<n_t, f_t> CG, LLVMProjectIRDB *IRDB);
explicit LLVMBasedICFG(CallGraph<n_t, f_t> CG, const LLVMProjectIRDB *IRDB);

explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB,
explicit LLVMBasedICFG(const LLVMProjectIRDB *IRDB,
const nlohmann::json &SerializedCG);
// To avoid ambiguity with the first ctor (json implicitly converts to
// CallGraphAnalysisType for whatever reason)
explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB,
const nlohmann::json &SerializedCG)
: LLVMBasedICFG(static_cast<const LLVMProjectIRDB *>(IRDB),
SerializedCG) {}

// Deleter of LLVMTypeHierarchy may be unknown here...
~LLVMBasedICFG();
Expand Down Expand Up @@ -133,10 +131,13 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
}

/// Gets the underlying IRDB
[[nodiscard]] LLVMProjectIRDB *getIRDB() const noexcept { return IRDB; }
[[nodiscard]] const LLVMProjectIRDB *getIRDB() const noexcept { return IRDB; }

/// Returns true, if a function was generated by phasar.
[[nodiscard]] static bool isPhasarGenerated(const llvm::Function &) noexcept;
[[nodiscard]] static bool
isPhasarGenerated(const llvm::Function &F) noexcept {
return GlobalCtorsDtorsModel::isPhasarGenerated(F);
}

using CFGBase::print;
using ICFGBase::print;
Expand All @@ -156,22 +157,21 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
getReturnSitesOfCallAtImpl(n_t Inst) const;
void printImpl(llvm::raw_ostream &OS) const;
[[nodiscard]] nlohmann::json getAsJsonImpl() const;
[[nodiscard]] const CallGraph<n_t, f_t> &getCallGraphImpl() const noexcept {
[[nodiscard]] const LLVMBasedCallGraph &getCallGraphImpl() const noexcept {
return CG;
}

[[nodiscard]] llvm::Function *buildCRuntimeGlobalCtorsDtorsModel(
llvm::Module &M, llvm::ArrayRef<llvm::Function *> UserEntryPoints);

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

// ---

CallGraph<const llvm::Instruction *, const llvm::Function *> CG;
LLVMProjectIRDB *IRDB = nullptr;
LLVMBasedCallGraph CG;
const LLVMProjectIRDB *IRDB = nullptr;
LLVMVFTableProvider VTP;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

namespace llvm {
class CallBase;
class Function;
} // namespace llvm

namespace psr {
Expand All @@ -38,6 +37,11 @@ class CHAResolver : public Resolver {

[[nodiscard]] std::string str() const override;

[[nodiscard]] bool
mutatesHelperAnalysisInformation() const noexcept override {
return false;
}

protected:
MaybeUniquePtr<const LLVMTypeHierarchy, true> TH;
};
Expand Down
28 changes: 16 additions & 12 deletions include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@ class DTAResolver : public CHAResolver {
public:
using TypeGraph_t = CachedTypeGraph;

DTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP,
const LLVMTypeHierarchy *TH);

~DTAResolver() override = default;

FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override;

void otherInst(const llvm::Instruction *Inst) override;

[[nodiscard]] std::string str() const override;

[[nodiscard]] bool
mutatesHelperAnalysisInformation() const noexcept override {
return false;
}

protected:
TypeGraph_t TypeGraph;

Expand All @@ -53,18 +69,6 @@ class DTAResolver : public CHAResolver {
* of vtable)
*/
bool heuristicAntiConstructorVtablePos(const llvm::BitCastInst *BitCast);

public:
DTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP,
const LLVMTypeHierarchy *TH);

~DTAResolver() override = default;

FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override;

void otherInst(const llvm::Instruction *Inst) override;

[[nodiscard]] std::string str() const override;
};
} // namespace psr

Expand Down
24 changes: 6 additions & 18 deletions include/phasar/PhasarLLVM/ControlFlow/Resolver/NOResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,39 +13,27 @@
#include "phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h"

namespace llvm {
class Instruction;
class CallBase;
class Function;
class StructType;
} // namespace llvm

namespace psr {

class NOResolver final : public Resolver {
protected:
const llvm::Function *
getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx,
const llvm::CallBase *CallSite);

public:
NOResolver(const LLVMProjectIRDB *IRDB);
NOResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP);

~NOResolver() override = default;

void preCall(const llvm::Instruction *Inst) override;

void handlePossibleTargets(const llvm::CallBase *CallSite,
FunctionSetTy &PossibleTargets) override;

void postCall(const llvm::Instruction *Inst) override;

FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override;

FunctionSetTy resolveFunctionPointer(const llvm::CallBase *CallSite) override;

void otherInst(const llvm::Instruction *Inst) override;

[[nodiscard]] std::string str() const override;

[[nodiscard]] bool
mutatesHelperAnalysisInformation() const noexcept override {
return false;
}
};
} // namespace psr

Expand Down
Loading
Loading