Skip to content

Commit

Permalink
Merge branch 'development' into f-HelperAnalysesExistingModule
Browse files Browse the repository at this point in the history
  • Loading branch information
MMory authored Sep 21, 2023
2 parents 3dfb3a4 + 1fafc44 commit 685fb81
Show file tree
Hide file tree
Showing 16 changed files with 358 additions and 117 deletions.
9 changes: 1 addition & 8 deletions include/phasar/ControlFlow/ICFGBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,7 @@ template <typename Derived> class ICFGBase {
n_t>);
return self().getReturnSitesOfCallAtImpl(Inst);
}
/// Returns an iterable range of all global initializer functions
[[nodiscard]] decltype(auto)
getGlobalInitializers(ByConstRef<f_t> Fun) const {
static_assert(
is_iterable_over_v<decltype(self().getGlobalInitializersImpl(Fun)),
f_t>);
return self().getGlobalInitializersImpl(Fun);
}

/// Prints the underlying call-graph as DOT to the given output-stream
void print(llvm::raw_ostream &OS = llvm::outs()) const {
self().printImpl(OS);
Expand Down
10 changes: 9 additions & 1 deletion include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@
namespace psr {

class LLVMBasedICFG;
class LLVMBasedBackwardICFG;
template <typename N, typename F> class CallGraph;

template <>
struct CFGTraits<LLVMBasedBackwardICFG> : CFGTraits<LLVMBasedBackwardCFG> {};

class LLVMBasedBackwardICFG : public LLVMBasedBackwardCFG,
public ICFGBase<LLVMBasedBackwardCFG> {
public ICFGBase<LLVMBasedBackwardICFG> {
friend ICFGBase;

class LLVMBackwardRet {
Expand Down Expand Up @@ -60,6 +65,7 @@ class LLVMBasedBackwardICFG : public LLVMBasedBackwardCFG,
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;

llvm::LLVMContext BackwardRetsCtx;
llvm::DenseMap<const llvm::Function *, LLVMBackwardRet> BackwardRets;
Expand All @@ -68,6 +74,8 @@ class LLVMBasedBackwardICFG : public LLVMBasedBackwardCFG,

LLVMBasedICFG *ForwardICFG{};
};

extern template class ICFGBase<LLVMBasedBackwardICFG>;
} // namespace psr

#endif
14 changes: 14 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
static constexpr llvm::StringLiteral GlobalCRuntimeModelName =
"__psrCRuntimeGlobalCtorsModel";

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

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

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

/// 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 @@ -119,6 +128,9 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
/// Gets the underlying IRDB
[[nodiscard]] LLVMProjectIRDB *getIRDB() const noexcept { return IRDB; }

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

using CFGBase::print;
using ICFGBase::print;

Expand Down Expand Up @@ -150,6 +162,8 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
LLVMProjectIRDB *IRDB = nullptr;
MaybeUniquePtr<LLVMTypeHierarchy, true> TH;
};

extern template class ICFGBase<LLVMBasedICFG>;
} // namespace psr

#endif
46 changes: 25 additions & 21 deletions include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMFlowFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ mapFactsToCallee(const llvm::CallBase *CallSite, const llvm::Function *DestFun,
///
/// Propagates the return value back to the call-site and based on the
/// PropagateParameter predicate propagates back parameters holding as dataflow
/// facts.
/// facts. The resulting out-set of dataflow facts can be post-processed if
/// necessary.
///
/// Let a call-site cs: r = fun(..., ax, ...) a function prototype fun(...,
/// px, ...) and an exit statement exit: return rv.
Expand All @@ -252,30 +253,30 @@ mapFactsToCallee(const llvm::CallBase *CallSite, const llvm::Function *DestFun,
/// f(x) = ({ax} if PropagateParameter(ax, x) else {}) union ({r} if
/// PropagateRet(rv, x) else {}).
///
template <typename D = const llvm::Value *, typename Container = std::set<D>,
typename FnParam = std::equal_to<D>,
typename FnRet = std::equal_to<D>,
typename DCtor = DefaultConstruct<D>,
typename = std::enable_if_t<
std::is_invocable_r_v<bool, FnParam, const llvm::Value *, D> &&
std::is_invocable_r_v<bool, FnRet, const llvm::Value *, D>>>
FlowFunctionPtrType<D, Container>
mapFactsToCaller(const llvm::CallBase *CallSite,
const llvm::Instruction *ExitInst,
FnParam &&PropagateParameter = {}, FnRet &&PropagateRet = {},
DCtor &&FactConstructor = {}, bool PropagateGlobals = true,
bool PropagateZeroToCaller = true) {
template <
typename D = const llvm::Value *, typename Container = std::set<D>,
typename FnParam = std::equal_to<D>, typename FnRet = std::equal_to<D>,
typename DCtor = DefaultConstruct<D>, typename PostProcessFn = IgnoreArgs,
typename = std::enable_if_t<
std::is_invocable_r_v<bool, FnParam, const llvm::Value *, D> &&
std::is_invocable_r_v<bool, FnRet, const llvm::Value *, D>>>
FlowFunctionPtrType<D, Container> mapFactsToCaller(
const llvm::CallBase *CallSite, const llvm::Instruction *ExitInst,
FnParam &&PropagateParameter = {}, FnRet &&PropagateRet = {},
DCtor &&FactConstructor = {}, bool PropagateGlobals = true,
bool PropagateZeroToCaller = true, PostProcessFn &&PostProcess = {}) {

struct Mapper : public FlowFunction<D, Container> {
Mapper(const llvm::CallBase *CallSite, const llvm::Instruction *ExitInst,
bool PropagateGlobals, FnParam &&PropagateParameter,
FnRet &&PropagateRet, DCtor &&FactConstructor,
bool PropagateZeroToCaller)
bool PropagateZeroToCaller, PostProcessFn &&PostProcess)
: CSAndPropGlob(CallSite, PropagateGlobals),
ExitInstAndPropZero(ExitInst, PropagateZeroToCaller),
PropArg(std::forward<FnParam>(PropagateParameter)),
PropRet(std::forward<FnRet>(PropagateRet)),
FactConstructor(std::forward<DCtor>(FactConstructor)) {}
FactConstructor(std::forward<DCtor>(FactConstructor)),
PostProcess(std::forward<PostProcessFn>(PostProcess)) {}

Container computeTargets(D Source) override {
Container Res;
Expand Down Expand Up @@ -337,6 +338,8 @@ mapFactsToCaller(const llvm::CallBase *CallSite,
}
}

std::invoke(PostProcess, Res);

return Res;
}

Expand All @@ -346,13 +349,14 @@ mapFactsToCaller(const llvm::CallBase *CallSite,
[[no_unique_address]] std::decay_t<FnParam> PropArg;
[[no_unique_address]] std::decay_t<FnRet> PropRet;
[[no_unique_address]] std::decay_t<DCtor> FactConstructor;
[[no_unique_address]] std::decay_t<PostProcessFn> PostProcess;
};

return std::make_shared<Mapper>(CallSite, ExitInst, PropagateGlobals,
std::forward<FnParam>(PropagateParameter),
std::forward<FnRet>(PropagateRet),
std::forward<DCtor>(FactConstructor),
PropagateZeroToCaller);
return std::make_shared<Mapper>(
CallSite, ExitInst, PropagateGlobals,
std::forward<FnParam>(PropagateParameter),
std::forward<FnRet>(PropagateRet), std::forward<DCtor>(FactConstructor),
PropagateZeroToCaller, std::forward<PostProcessFn>(PostProcess));
}

//===----------------------------------------------------------------------===//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ class IFDSTaintAnalysis
*/
IFDSTaintAnalysis(const LLVMProjectIRDB *IRDB, LLVMAliasInfoRef PT,
const LLVMTaintConfig *Config,
std::vector<std::string> EntryPoints = {"main"});
std::vector<std::string> EntryPoints = {"main"},
bool TaintMainArgs = true);

~IFDSTaintAnalysis() override = default;

Expand Down Expand Up @@ -85,6 +86,7 @@ class IFDSTaintAnalysis
private:
const LLVMTaintConfig *Config{};
LLVMAliasInfoRef PT{};
bool TaintMainArgs{};

bool isSourceCall(const llvm::CallBase *CB,
const llvm::Function *Callee) const;
Expand Down
4 changes: 4 additions & 0 deletions include/phasar/Utils/TypeTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,10 @@ template <typename T> struct DefaultConstruct {
}
};

struct IgnoreArgs {
template <typename... U> void operator()(U &&.../*Val*/) noexcept {}
};

template <typename T> void reserveIfPossible(T &Container, size_t Capacity) {
if constexpr (detail::has_reserve<T>::value) {
Container.reserve(Capacity);
Expand Down
9 changes: 8 additions & 1 deletion lib/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

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

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

namespace psr {
Expand Down Expand Up @@ -68,4 +67,12 @@ void LLVMBasedBackwardICFG::printImpl(llvm::raw_ostream &OS) const {
nlohmann::json LLVMBasedBackwardICFG::getAsJsonImpl() const {
return ForwardICFG->getAsJson();
}

auto LLVMBasedBackwardICFG::getCallGraphImpl() const noexcept
-> const CallGraph<n_t, f_t> & {
return ForwardICFG->getCallGraph();
}

template class ICFGBase<LLVMBasedBackwardICFG>;

} // namespace psr
16 changes: 16 additions & 0 deletions lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#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"
Expand Down Expand Up @@ -380,6 +381,19 @@ LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB,

LLVMBasedICFG::~LLVMBasedICFG() = default;

bool LLVMBasedICFG::isPhasarGenerated(const llvm::Function &F) noexcept {
if (F.hasName()) {
llvm::StringRef FunctionName = F.getName();
return llvm::StringSwitch<bool>(FunctionName)
.Cases(GlobalCRuntimeModelName, GlobalCRuntimeDtorModelName,
GlobalCRuntimeDtorsCallerName,
GlobalCRuntimeUserEntrySelectorName, true)
.Default(false);
}

return false;
}

[[nodiscard]] FunctionRange LLVMBasedICFG::getAllFunctionsImpl() const {
return IRDB->getAllFunctions();
}
Expand Down Expand Up @@ -443,4 +457,6 @@ void LLVMBasedICFG::printImpl(llvm::raw_ostream &OS) const {
[this](n_t Inst) { return IRDB->getInstructionId(Inst); });
}

template class ICFGBase<LLVMBasedICFG>;

} // namespace psr
11 changes: 6 additions & 5 deletions lib/PhasarLLVM/ControlFlow/LLVMBasedICFGGlobalsImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,10 @@ static llvm::Function *createDtorCallerForModule(
&RegisteredDtors) {

auto *PhasarDtorCaller = llvm::cast<llvm::Function>(
Mod.getOrInsertFunction("__psrGlobalDtorsCaller." +
getReducedModuleName(Mod),
llvm::Type::getVoidTy(Mod.getContext()))
Mod.getOrInsertFunction(
LLVMBasedICFG::GlobalCRuntimeDtorsCallerName.str() + '.' +
getReducedModuleName(Mod),
llvm::Type::getVoidTy(Mod.getContext()))
.getCallee());

auto *BB =
Expand Down Expand Up @@ -195,7 +196,7 @@ static std::pair<llvm::Function *, bool> buildCRuntimeGlobalDtorsModel(

auto &CTX = M.getContext();
auto *Cleanup = llvm::cast<llvm::Function>(
M.getOrInsertFunction("__psrCRuntimeGlobalDtorsModel",
M.getOrInsertFunction(LLVMBasedICFG::GlobalCRuntimeDtorModelName,
llvm::Type::getVoidTy(CTX))
.getCallee());

Expand Down Expand Up @@ -301,7 +302,7 @@ llvm::Function *LLVMBasedICFG::buildCRuntimeGlobalCtorsDtorsModel(
} else {

auto UEntrySelectorFn = M.getOrInsertFunction(
"__psrCRuntimeUserEntrySelector", llvm::Type::getInt32Ty(CTX));
GlobalCRuntimeUserEntrySelectorName, llvm::Type::getInt32Ty(CTX));

auto *UEntrySelector = IRB.CreateCall(UEntrySelectorFn);

Expand Down
Loading

0 comments on commit 685fb81

Please sign in to comment.