Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@
#include "phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h"
#include "phasar/Utils/MaybeUniquePtr.h"

namespace llvm {
class CallBase;
} // namespace llvm

namespace psr {
class DIBasedTypeHierarchy;

Expand Down
4 changes: 0 additions & 4 deletions include/phasar/PhasarLLVM/ControlFlow/Resolver/NOResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@

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

namespace llvm {
class CallBase;
} // namespace llvm

namespace psr {

/// \brief A resolver that doesn't resolve indirect- and virtual calls
Expand Down
23 changes: 1 addition & 22 deletions include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,8 @@
#include "phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"

#include <set>
#include <string>
#include <utility>
#include <vector>

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

namespace psr {

class DIBasedTypeHierarchy;

/// \brief A resolver that uses alias information to resolve indirect and
/// virtual calls
class OTFResolver : public Resolver {
Expand All @@ -54,18 +40,11 @@ class OTFResolver : public Resolver {
void resolveFunctionPointer(FunctionSetTy &PossibleTargets,
const llvm::CallBase *CallSite) override;

static std::set<const llvm::Type *>
getReachableTypes(const LLVMAliasInfo::AliasSetTy &Values);

static std::vector<std::pair<const llvm::Value *, const llvm::Value *>>
getActualFormalPointerPairs(const llvm::CallBase *CallSite,
const llvm::Function *CalleeTarget);

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

[[nodiscard]] bool
mutatesHelperAnalysisInformation() const noexcept override {
return true;
return !PT.isInterProcedural();
}

protected:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,10 @@
#include <vector>

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

namespace psr {
class DIBasedTypeHierarchy;

/// \brief A resolver that performs Rapid Type Analysis to resolve calls
/// to C++ virtual functions. Requires debug information.
Expand Down
65 changes: 43 additions & 22 deletions include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"

#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/DerivedTypes.h"

#include <memory>
Expand All @@ -44,6 +45,10 @@ enum class CallGraphAnalysisType;
[[nodiscard]] std::optional<unsigned>
getVFTIndex(const llvm::CallBase *CallSite);

/// Similar to getVFTIndex(), but also returns a pointer to the vtable
[[nodiscard]] std::optional<std::pair<const llvm::Value *, uint64_t>>
getVFTIndexAndVT(const llvm::CallBase *CallSite);

/// Assuming that `CallSite` is a call to a non-static member function,
/// retrieves the type of the receiver. Returns nullptr, if the receiver-type
/// could not be extracted
Expand All @@ -67,43 +72,40 @@ getReceiverType(const llvm::CallBase *CallSite);
[[nodiscard]] bool isVirtualCall(const llvm::Instruction *Inst,
const LLVMVFTableProvider &VTP);

/// A variant of F->hasAddressTaken() that is better suited for our use cases.
///
/// Especially, it filteres out global aliases.
[[nodiscard]] bool isAddressTakenFunction(const llvm::Function *F);

/// \brief A base class for call-target resolvers. Used to build call graphs.
///
/// Create a specific resolver by making a new class, inheriting this resolver
/// class and implementing the virtual functions as needed.
class Resolver {
protected:
const LLVMProjectIRDB *IRDB;
const LLVMVFTableProvider *VTP;

const llvm::Function *
getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx,
const llvm::CallBase *CallSite,
const llvm::DIType *ReceiverType) {
if (!VTP) {
return nullptr;
}
return psr::getNonPureVirtualVFTEntry(T, Idx, CallSite, *VTP, ReceiverType);
}

public:
using FunctionSetTy = llvm::SmallDenseSet<const llvm::Function *, 4>;

Resolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP);

virtual ~Resolver() = default;

virtual void preCall(const llvm::Instruction *Inst);
[[deprecated("With the removal of DTAResolver, this is not used "
"anymore")]] virtual void
preCall(const llvm::Instruction *Inst);

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

virtual void postCall(const llvm::Instruction *Inst);
[[deprecated("With the removal of DTAResolver, this is not used "
"anymore")]] virtual void
postCall(const llvm::Instruction *Inst);

[[nodiscard]] FunctionSetTy
resolveIndirectCall(const llvm::CallBase *CallSite);

virtual void otherInst(const llvm::Instruction *Inst);
[[deprecated("With the removal of DTAResolver, this is not used "
"anymore")]] virtual void
otherInst(const llvm::Instruction *Inst);

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

Expand All @@ -115,11 +117,30 @@ class Resolver {
// Conservatively returns true. Override if possible
return true;
}
static std::unique_ptr<Resolver> create(CallGraphAnalysisType Ty,
const LLVMProjectIRDB *IRDB,
const LLVMVFTableProvider *VTP,
const DIBasedTypeHierarchy *TH,
LLVMAliasInfoRef PT = nullptr);

[[nodiscard]] llvm::ArrayRef<const llvm::Function *>
getAddressTakenFunctions();

[[nodiscard]] static std::unique_ptr<Resolver>
create(CallGraphAnalysisType Ty, const LLVMProjectIRDB *IRDB,
const LLVMVFTableProvider *VTP, const DIBasedTypeHierarchy *TH,
LLVMAliasInfoRef PT = nullptr);

protected:
const llvm::Function *
getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx,
const llvm::CallBase *CallSite,
const llvm::DIType *ReceiverType) {
if (!VTP) {
return nullptr;
}
return psr::getNonPureVirtualVFTEntry(T, Idx, CallSite, *VTP, ReceiverType);
}

const LLVMProjectIRDB *IRDB{};
const LLVMVFTableProvider *VTP{};
std::optional<llvm::SmallVector<const llvm::Function *, 0>>
AddressTakenFunctions{};

protected:
virtual void resolveVirtualCall(FunctionSetTy &PossibleTargets,
Expand Down
9 changes: 1 addition & 8 deletions lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,9 @@ bool Builder::processFunction(const llvm::Function *F) {
for (const auto &I : llvm::instructions(F)) {
const auto *CS = llvm::dyn_cast<llvm::CallBase>(&I);
if (!CS) {
Res->otherInst(&I);
continue;
}

Res->preCall(&I);
scope_exit PostCall = [&] { Res->postCall(&I); };

FixpointReached &=
fillPossibleTargets(PossibleTargets, *Res, CS, IndirectCalls);

Expand Down Expand Up @@ -203,9 +199,6 @@ bool Builder::constructDynamicCall(const llvm::Instruction *CS) {
"Looking into dynamic call-site: ");
PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", " " << llvmIRToString(CS));

Res->preCall(CallSite);
scope_exit PostCall = [&] { Res->postCall(CallSite); };

// call the resolve routine

auto PossibleTargets = Res->resolveIndirectCall(CallSite);
Expand Down Expand Up @@ -275,7 +268,7 @@ auto psr::buildLLVMBasedCallGraph(
PT = PTOwn.asRef();
}

auto Res = Resolver::create(CGType, &IRDB, &VTP, &TH);
auto Res = Resolver::create(CGType, &IRDB, &VTP, &TH, PT);
return buildLLVMBasedCallGraph(IRDB, *Res, EntryPoints, S);
}

Expand Down
5 changes: 0 additions & 5 deletions lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,10 @@
#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h"
#include "phasar/Utils/Logger.h"

#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Module.h"

#include <memory>

using namespace std;
using namespace psr;

CHAResolver::CHAResolver(const LLVMProjectIRDB *IRDB,
Expand Down
6 changes: 0 additions & 6 deletions lib/PhasarLLVM/ControlFlow/Resolver/NOResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,8 @@

#include "phasar/PhasarLLVM/ControlFlow/Resolver/NOResolver.h"

#include <set>

using namespace psr;

namespace psr {

NOResolver::NOResolver(const LLVMProjectIRDB *IRDB,
const LLVMVFTableProvider *VTP)
: Resolver(IRDB, VTP) {}
Expand All @@ -33,5 +29,3 @@ void NOResolver::resolveFunctionPointer(FunctionSetTy & /*PossibleTargets*/,
const llvm::CallBase * /*CallSite*/) {}

std::string NOResolver::str() const { return "NOResolver"; }

} // namespace psr
Loading
Loading