Skip to content

Commit 59f257a

Browse files
fabianbs96MMory
andauthored
Refactor TypeHierarchy Interface (#721)
* Split TH and VTable into two interfaces + refactor TH interface * Add vtable unittest back * Add breaking changes * minor fix * Add ctor to LLVMBasedICFG that allows passing in an LLVMVFTableProvider * minor --------- Co-authored-by: Martin Mory <[email protected]>
1 parent 24bba27 commit 59f257a

26 files changed

+501
-1395
lines changed

BreakingChanges.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
## development HEAD
44

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

716
## v2403

include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,12 @@
2121
#include "phasar/ControlFlow/CallGraphAnalysisType.h"
2222
#include "phasar/ControlFlow/ICFGBase.h"
2323
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h"
24+
#include "phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h"
2425
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
2526
#include "phasar/PhasarLLVM/Utils/LLVMBasedContainerConfig.h"
26-
#include "phasar/Utils/MaybeUniquePtr.h"
27-
#include "phasar/Utils/MemoryResource.h"
2827
#include "phasar/Utils/Soundness.h"
2928

3029
#include "llvm/ADT/ArrayRef.h"
31-
#include "llvm/ADT/DenseMap.h"
3230
#include "llvm/ADT/SmallVector.h"
3331
#include "llvm/IR/Function.h"
3432
#include "llvm/IR/Instruction.h"
@@ -90,17 +88,19 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
9088
bool IncludeGlobals = true);
9189
explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
9290
llvm::ArrayRef<std::string> EntryPoints = {},
93-
LLVMTypeHierarchy *TH = nullptr,
91+
Soundness S = Soundness::Soundy,
92+
bool IncludeGlobals = true);
93+
explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
94+
LLVMVFTableProvider VTP,
95+
llvm::ArrayRef<std::string> EntryPoints = {},
9496
Soundness S = Soundness::Soundy,
9597
bool IncludeGlobals = true);
9698

9799
/// Creates an ICFG with an already given call-graph
98-
explicit LLVMBasedICFG(CallGraph<n_t, f_t> CG, LLVMProjectIRDB *IRDB,
99-
LLVMTypeHierarchy *TH = nullptr);
100+
explicit LLVMBasedICFG(CallGraph<n_t, f_t> CG, LLVMProjectIRDB *IRDB);
100101

101102
explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB,
102-
const nlohmann::json &SerializedCG,
103-
LLVMTypeHierarchy *TH = nullptr);
103+
const nlohmann::json &SerializedCG);
104104

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

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

170171
// ---
171172

172173
CallGraph<const llvm::Instruction *, const llvm::Function *> CG;
173174
LLVMProjectIRDB *IRDB = nullptr;
174-
MaybeUniquePtr<LLVMTypeHierarchy, true> TH;
175+
LLVMVFTableProvider VTP;
175176
};
176177

177178
extern template class ICFGBase<LLVMBasedICFG>;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/******************************************************************************
2+
* Copyright (c) 2024 Fabian Schiebel.
3+
* All rights reserved. This program and the accompanying materials are made
4+
* available under the terms of LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Fabian Schiebel and others
8+
*****************************************************************************/
9+
10+
#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_LLVMVFTABLEPROVIDER_H
11+
#define PHASAR_PHASARLLVM_CONTROLFLOW_LLVMVFTABLEPROVIDER_H
12+
13+
#include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h"
14+
15+
#include <unordered_map>
16+
17+
namespace llvm {
18+
class Module;
19+
class StructType;
20+
class GlobalVariable;
21+
} // namespace llvm
22+
23+
namespace psr {
24+
class LLVMProjectIRDB;
25+
26+
class LLVMVFTableProvider {
27+
public:
28+
explicit LLVMVFTableProvider(const llvm::Module &Mod);
29+
explicit LLVMVFTableProvider(const LLVMProjectIRDB &IRDB);
30+
31+
[[nodiscard]] bool hasVFTable(const llvm::StructType *Type) const;
32+
[[nodiscard]] const LLVMVFTable *
33+
getVFTableOrNull(const llvm::StructType *Type) const;
34+
35+
private:
36+
std::unordered_map<const llvm::StructType *, LLVMVFTable> TypeVFTMap;
37+
};
38+
} // namespace psr
39+
40+
#endif // PHASAR_PHASARLLVM_CONTROLFLOW_LLVMVFTABLEPROVIDER_H

include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,28 @@
1818
#define PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_CHARESOLVER_H_
1919

2020
#include "phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h"
21+
#include "phasar/Utils/MaybeUniquePtr.h"
2122

2223
namespace llvm {
2324
class CallBase;
2425
class Function;
2526
} // namespace llvm
2627

2728
namespace psr {
29+
class LLVMTypeHierarchy;
2830
class CHAResolver : public Resolver {
2931
public:
30-
CHAResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH);
32+
CHAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP,
33+
const LLVMTypeHierarchy *TH);
3134

3235
~CHAResolver() override = default;
3336

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

3639
[[nodiscard]] std::string str() const override;
40+
41+
protected:
42+
MaybeUniquePtr<const LLVMTypeHierarchy, true> TH;
3743
};
3844
} // namespace psr
3945

include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include "phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h"
2121
#include "phasar/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.h"
2222
// To switch the TypeGraph
23-
//#include "phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h"
23+
// #include "phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h"
2424

2525
#include <string>
2626

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

5757
public:
58-
DTAResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH);
58+
DTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP,
59+
const LLVMTypeHierarchy *TH);
5960

6061
~DTAResolver() override = default;
6162

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class NOResolver final : public Resolver {
2828
const llvm::CallBase *CallSite);
2929

3030
public:
31-
NOResolver(LLVMProjectIRDB &IRDB);
31+
NOResolver(const LLVMProjectIRDB *IRDB);
3232

3333
~NOResolver() override = default;
3434

include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_OTFRESOLVER_H_
1818
#define PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_OTFRESOLVER_H_
1919

20-
#include "phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h"
20+
#include "phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h"
2121
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
2222

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

4444
public:
45-
OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH,
45+
OTFResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP,
4646
LLVMAliasInfoRef PT);
4747

4848
~OTFResolver() override = default;

include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ class StructType;
3131
namespace psr {
3232
class RTAResolver : public CHAResolver {
3333
public:
34-
RTAResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH);
34+
RTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP,
35+
const LLVMTypeHierarchy *TH);
3536

3637
~RTAResolver() override = default;
3738

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ class StructType;
3434

3535
namespace psr {
3636
class LLVMProjectIRDB;
37+
class LLVMVFTableProvider;
3738
class LLVMTypeHierarchy;
3839
enum class CallGraphAnalysisType;
39-
class LLVMPointsToInfo;
4040

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

5252
class Resolver {
5353
protected:
54-
LLVMProjectIRDB &IRDB;
55-
LLVMTypeHierarchy *TH;
54+
const LLVMProjectIRDB *IRDB;
55+
const LLVMVFTableProvider *VTP;
5656

57-
Resolver(LLVMProjectIRDB &IRDB);
57+
Resolver(const LLVMProjectIRDB *IRDB);
5858

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

66-
Resolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH);
66+
Resolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP);
6767

6868
virtual ~Resolver() = default;
6969

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

8585
static std::unique_ptr<Resolver> create(CallGraphAnalysisType Ty,
86-
LLVMProjectIRDB *IRDB,
87-
LLVMTypeHierarchy *TH,
86+
const LLVMProjectIRDB *IRDB,
87+
const LLVMVFTableProvider *VTP,
88+
const LLVMTypeHierarchy *TH,
8889
LLVMAliasInfoRef PT = nullptr);
8990
};
9091
} // namespace psr

include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@ class DIBasedTypeHierarchy
3838
return TypeToVertex.count(Type);
3939
}
4040

41-
[[nodiscard]] bool isSubType(ClassType Type, ClassType SubType) override {
41+
[[nodiscard]] bool isSubType(ClassType Type,
42+
ClassType SubType) const override {
4243
return llvm::is_contained(subTypesOf(Type), SubType);
4344
}
4445

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

54-
[[nodiscard]] bool isSuperType(ClassType Type, ClassType SuperType) override;
55-
56-
/// Not supported yet
57-
[[nodiscard]] std::set<ClassType> getSuperTypes(ClassType Type) override;
58-
5955
[[nodiscard]] ClassType
60-
getType(std::string TypeName) const noexcept override {
56+
getType(llvm::StringRef TypeName) const noexcept override {
6157
return NameToType.lookup(TypeName);
6258
}
6359

64-
[[nodiscard]] std::set<ClassType> getAllTypes() const override {
60+
[[nodiscard]] std::vector<ClassType> getAllTypes() const override {
6561
return {VertexTypes.begin(), VertexTypes.end()};
6662
}
6763

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

70-
[[nodiscard]] std::string getTypeName(ClassType Type) const override {
71-
return Type->getName().str();
66+
[[nodiscard]] llvm::StringRef getTypeName(ClassType Type) const override {
67+
return Type->getName();
7268
}
7369

74-
[[nodiscard]] bool hasVFTable(ClassType Type) const override;
75-
76-
[[nodiscard]] const VFTable<f_t> *getVFTable(ClassType Type) const override {
77-
auto It = TypeToVertex.find(Type);
78-
if (It == TypeToVertex.end()) {
79-
return nullptr;
80-
}
81-
return &VTables[It->second];
70+
[[nodiscard]] size_t size() const noexcept override {
71+
return VertexTypes.size();
72+
}
73+
[[nodiscard]] bool empty() const noexcept override {
74+
return VertexTypes.empty();
8275
}
83-
84-
[[nodiscard]] size_t size() const override { return VertexTypes.size(); }
85-
86-
[[nodiscard]] bool empty() const override { return VertexTypes.empty(); }
8776

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

0 commit comments

Comments
 (0)