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
9 changes: 9 additions & 0 deletions BreakingChanges.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

## development HEAD

- The API of the `TypeHierarchy` interface (and thus the `LLVMTypeHierarchy` and `DIBasedTypeHierarchy` as well) has changed:
- No handling of the super-type relation (only sub-types)
- No VTable handling anymore -- has been out-sourced into `LLVMVFTableProvider`
- minor API changes
- The constructors of the call-graph resolvers have changed. They:
- take the `LLVMProjectIRDB` as pointer-to-const
- take an additional second parameter of type `const LLVMVFTableProvider *`
- not necessarily require a `LLVMTypeHierarchy` anymore
- Some constructors of `LLVMBasedICFG` do not accept a `LLVMTypeHierarchy` pointer anymore
- Removed IfdsFieldSensTaintAnalysis as it relies on LLVM's deprecated typed-pointers.

## v2403
Expand Down
21 changes: 11 additions & 10 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,12 @@
#include "phasar/ControlFlow/CallGraphAnalysisType.h"
#include "phasar/ControlFlow/ICFGBase.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.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/MemoryResource.h"
#include "phasar/Utils/Soundness.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
Expand Down Expand Up @@ -90,17 +88,19 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
bool IncludeGlobals = true);
explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
llvm::ArrayRef<std::string> EntryPoints = {},
LLVMTypeHierarchy *TH = nullptr,
Soundness S = Soundness::Soundy,
bool IncludeGlobals = true);
explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
LLVMVFTableProvider VTP,
llvm::ArrayRef<std::string> EntryPoints = {},
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,
LLVMTypeHierarchy *TH = nullptr);
explicit LLVMBasedICFG(CallGraph<n_t, f_t> CG, LLVMProjectIRDB *IRDB);

explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB,
const nlohmann::json &SerializedCG,
LLVMTypeHierarchy *TH = nullptr);
const nlohmann::json &SerializedCG);

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

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

// ---

CallGraph<const llvm::Instruction *, const llvm::Function *> CG;
LLVMProjectIRDB *IRDB = nullptr;
MaybeUniquePtr<LLVMTypeHierarchy, true> TH;
LLVMVFTableProvider VTP;
};

extern template class ICFGBase<LLVMBasedICFG>;
Expand Down
40 changes: 40 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/******************************************************************************
* 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_LLVMVFTABLEPROVIDER_H
#define PHASAR_PHASARLLVM_CONTROLFLOW_LLVMVFTABLEPROVIDER_H

#include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h"

#include <unordered_map>

namespace llvm {
class Module;
class StructType;
class GlobalVariable;
} // namespace llvm

namespace psr {
class LLVMProjectIRDB;

class LLVMVFTableProvider {
public:
explicit LLVMVFTableProvider(const llvm::Module &Mod);
explicit LLVMVFTableProvider(const LLVMProjectIRDB &IRDB);

[[nodiscard]] bool hasVFTable(const llvm::StructType *Type) const;
[[nodiscard]] const LLVMVFTable *
getVFTableOrNull(const llvm::StructType *Type) const;

private:
std::unordered_map<const llvm::StructType *, LLVMVFTable> TypeVFTMap;
};
} // namespace psr

#endif // PHASAR_PHASARLLVM_CONTROLFLOW_LLVMVFTABLEPROVIDER_H
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,28 @@
#define PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_CHARESOLVER_H_

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

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

namespace psr {
class LLVMTypeHierarchy;
class CHAResolver : public Resolver {
public:
CHAResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH);
CHAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP,
const LLVMTypeHierarchy *TH);

~CHAResolver() override = default;

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

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

protected:
MaybeUniquePtr<const LLVMTypeHierarchy, true> TH;
};
} // namespace psr

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include "phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h"
#include "phasar/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.h"
// To switch the TypeGraph
//#include "phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h"
// #include "phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h"

#include <string>

Expand Down Expand Up @@ -55,7 +55,8 @@ class DTAResolver : public CHAResolver {
bool heuristicAntiConstructorVtablePos(const llvm::BitCastInst *BitCast);

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

~DTAResolver() override = default;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class NOResolver final : public Resolver {
const llvm::CallBase *CallSite);

public:
NOResolver(LLVMProjectIRDB &IRDB);
NOResolver(const LLVMProjectIRDB *IRDB);

~NOResolver() override = default;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_OTFRESOLVER_H_
#define PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_OTFRESOLVER_H_

#include "phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h"
#include "phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"

#include <set>
Expand All @@ -42,7 +42,7 @@ class OTFResolver : public Resolver {
LLVMAliasInfoRef PT;

public:
OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH,
OTFResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP,
LLVMAliasInfoRef PT);

~OTFResolver() override = default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class StructType;
namespace psr {
class RTAResolver : public CHAResolver {
public:
RTAResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH);
RTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP,
const LLVMTypeHierarchy *TH);

~RTAResolver() override = default;

Expand Down
15 changes: 8 additions & 7 deletions include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ class StructType;

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

[[nodiscard]] std::optional<unsigned>
getVFTIndex(const llvm::CallBase *CallSite);
Expand All @@ -51,10 +51,10 @@ getReceiverType(const llvm::CallBase *CallSite);

class Resolver {
protected:
LLVMProjectIRDB &IRDB;
LLVMTypeHierarchy *TH;
const LLVMProjectIRDB *IRDB;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is it a pointer now?

const LLVMVFTableProvider *VTP;

Resolver(LLVMProjectIRDB &IRDB);
Resolver(const LLVMProjectIRDB *IRDB);

const llvm::Function *
getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx,
Expand All @@ -63,7 +63,7 @@ class Resolver {
public:
using FunctionSetTy = llvm::SmallDenseSet<const llvm::Function *, 4>;

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

virtual ~Resolver() = default;

Expand All @@ -83,8 +83,9 @@ class Resolver {
[[nodiscard]] virtual std::string str() const = 0;

static std::unique_ptr<Resolver> create(CallGraphAnalysisType Ty,
LLVMProjectIRDB *IRDB,
LLVMTypeHierarchy *TH,
const LLVMProjectIRDB *IRDB,
const LLVMVFTableProvider *VTP,
const LLVMTypeHierarchy *TH,
LLVMAliasInfoRef PT = nullptr);
};
} // namespace psr
Expand Down
35 changes: 12 additions & 23 deletions include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ class DIBasedTypeHierarchy
return TypeToVertex.count(Type);
}

[[nodiscard]] bool isSubType(ClassType Type, ClassType SubType) override {
[[nodiscard]] bool isSubType(ClassType Type,
ClassType SubType) const override {
return llvm::is_contained(subTypesOf(Type), SubType);
}

[[nodiscard]] std::set<ClassType> getSubTypes(ClassType Type) override {
[[nodiscard]] std::set<ClassType> getSubTypes(ClassType Type) const override {
const auto &Range = subTypesOf(Type);
return {Range.begin(), Range.end()};
}
Expand All @@ -51,39 +52,27 @@ class DIBasedTypeHierarchy
[[nodiscard]] llvm::iterator_range<const ClassType *>
subTypesOf(ClassType Ty) const noexcept;

[[nodiscard]] bool isSuperType(ClassType Type, ClassType SuperType) override;

/// Not supported yet
[[nodiscard]] std::set<ClassType> getSuperTypes(ClassType Type) override;

[[nodiscard]] ClassType
getType(std::string TypeName) const noexcept override {
getType(llvm::StringRef TypeName) const noexcept override {
return NameToType.lookup(TypeName);
}

[[nodiscard]] std::set<ClassType> getAllTypes() const override {
[[nodiscard]] std::vector<ClassType> getAllTypes() const override {
return {VertexTypes.begin(), VertexTypes.end()};
}

[[nodiscard]] const auto &getAllVTables() const noexcept { return VTables; }

[[nodiscard]] std::string getTypeName(ClassType Type) const override {
return Type->getName().str();
[[nodiscard]] llvm::StringRef getTypeName(ClassType Type) const override {
return Type->getName();
}

[[nodiscard]] bool hasVFTable(ClassType Type) const override;

[[nodiscard]] const VFTable<f_t> *getVFTable(ClassType Type) const override {
auto It = TypeToVertex.find(Type);
if (It == TypeToVertex.end()) {
return nullptr;
}
return &VTables[It->second];
[[nodiscard]] size_t size() const noexcept override {
return VertexTypes.size();
}
[[nodiscard]] bool empty() const noexcept override {
return VertexTypes.empty();
}

[[nodiscard]] size_t size() const override { return VertexTypes.size(); }

[[nodiscard]] bool empty() const override { return VertexTypes.empty(); }

void print(llvm::raw_ostream &OS = llvm::outs()) const override;

Expand Down
Loading