From 728616ce099317e11ee2de3a7df0ee4414994f3b Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 17 May 2024 09:46:24 +0200 Subject: [PATCH 1/4] some changes --- include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h | 2 +- include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h | 6 +++--- lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp | 9 +++++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h index 333ce033fe..63a913eea2 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h @@ -162,7 +162,7 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { } [[nodiscard]] llvm::Function *buildCRuntimeGlobalCtorsDtorsModel( - llvm::Module &M, llvm::ArrayRef UserEntryPoints); + LLVMProjectIRDB &IRDB, llvm::ArrayRef UserEntryPoints); void initialize(LLVMProjectIRDB *IRDB, Resolver &CGResolver, llvm::ArrayRef EntryPoints, Soundness S, diff --git a/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h b/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h index ba92829e59..3e255c2fcc 100644 --- a/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h +++ b/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h @@ -22,9 +22,9 @@ struct FunctionData { std::string Name; TaintCategory ReturnCat{}; - std::vector SourceValues; - std::vector SinkValues; - std::vector SanitizerValues; + std::vector SourceValues{}; + std::vector SinkValues{}; + std::vector SanitizerValues{}; bool HasAllSinkParam = false; }; diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp index 23dbdcc28d..536e412fa4 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp @@ -353,6 +353,15 @@ LLVMTypeHierarchy::getTypeName(const llvm::StructType *Type) const { return Type->getStructName(); } +const llvm::GlobalVariable * +LLVMTypeHierarchy::getVFTableGlobal(const llvm::StructType *Type) const { + auto Name = removeStructOrClassPrefix(*Type); + if (auto It = ClearNameTVMap.find(Name); It != ClearNameTVMap.end()) { + return It->second; + } + return nullptr; +} + void LLVMTypeHierarchy::print(llvm::raw_ostream &OS) const { OS << "Type Hierarchy:\n"; vertex_iterator UI; From 2cef28a91d2a101a399ba767a6f8f4b109322097 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 21 May 2024 10:55:23 +0200 Subject: [PATCH 2/4] minor in CG --- .../ControlFlow/LLVMBasedCallGraphBuilder.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp index 74e8a97169..d1c9aca227 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp @@ -106,7 +106,8 @@ static bool fillPossibleTargets( Resolver::FunctionSetTy &PossibleTargets, Resolver &Res, const llvm::CallBase *CS, llvm::DenseMap &IndirectCalls) { - if (const auto *StaticCallee = CS->getCalledFunction()) { + if (const auto *StaticCallee = llvm::dyn_cast( + CS->getCalledOperand()->stripPointerCastsAndAliases())) { PossibleTargets.insert(StaticCallee); PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", @@ -115,16 +116,7 @@ static bool fillPossibleTargets( return true; } - // still try to resolve the called function statically - const llvm::Value *SV = CS->getCalledOperand()->stripPointerCastsAndAliases(); - if (const auto *ValueFunction = llvm::dyn_cast(SV)) { - PossibleTargets.insert(ValueFunction); - PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", - "Found static call-site: " << llvmIRToString(CS)); - return true; - } - - if (llvm::isa(SV)) { + if (llvm::isa(CS->getCalledOperand())) { return true; } From 7cfe14fb0cfb01c4efad43fb80e8c9561d104e75 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 15 Dec 2024 11:44:29 +0100 Subject: [PATCH 3/4] minor --- lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp index 536e412fa4..23dbdcc28d 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp @@ -353,15 +353,6 @@ LLVMTypeHierarchy::getTypeName(const llvm::StructType *Type) const { return Type->getStructName(); } -const llvm::GlobalVariable * -LLVMTypeHierarchy::getVFTableGlobal(const llvm::StructType *Type) const { - auto Name = removeStructOrClassPrefix(*Type); - if (auto It = ClearNameTVMap.find(Name); It != ClearNameTVMap.end()) { - return It->second; - } - return nullptr; -} - void LLVMTypeHierarchy::print(llvm::raw_ostream &OS) const { OS << "Type Hierarchy:\n"; vertex_iterator UI; From fe488cad8183a34d75a0f87f821eea5b75009beb Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 4 Jun 2024 16:01:26 +0200 Subject: [PATCH 4/4] Quick-fix LLVMTypeHierarchyTest --- .../TypeHierarchy/LLVMTypeHierarchy.cpp | 45 ++++++++++++------- lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp | 20 ++------- .../TypeHierarchy/LLVMTypeHierarchyTest.cpp | 8 ++-- 3 files changed, 35 insertions(+), 38 deletions(-) diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp index 23dbdcc28d..62872851b9 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp @@ -146,10 +146,12 @@ LLVMTypeHierarchy::removeStructOrClassPrefix(const llvm::StructType &T) { std::string LLVMTypeHierarchy::removeStructOrClassPrefix(llvm::StringRef TypeName) { if (TypeName.startswith(StructPrefix)) { - return TypeName.drop_front(StructPrefix.size()).str(); + TypeName = TypeName.drop_front(StructPrefix.size()); + } else if (TypeName.startswith(ClassPrefix)) { + TypeName = TypeName.drop_front(ClassPrefix.size()); } - if (TypeName.startswith(ClassPrefix)) { - return TypeName.drop_front(ClassPrefix.size()).str(); + if (TypeName.endswith(".base")) { + TypeName = TypeName.drop_back(llvm::StringRef(".base").size()); } return TypeName.str(); } @@ -231,18 +233,15 @@ LLVMTypeHierarchy::getSubTypes(const llvm::Module & /*M*/, if (const auto *I = llvm::dyn_cast(TI->getInitializer())) { for (const auto &Op : I->operands()) { - if (auto *CE = llvm::dyn_cast(Op)) { - if (auto *BC = llvm::dyn_cast(CE)) { - if (BC->getOperand(0)->hasName()) { - auto Name = BC->getOperand(0)->getName(); - if (Name.find(TypeInfoPrefix) != llvm::StringRef::npos) { - auto ClearName = - removeTypeInfoPrefix(llvm::demangle(Name.str())); - if (auto TypeIt = ClearNameTypeMap.find(ClearName); - TypeIt != ClearNameTypeMap.end()) { - SubTypes.push_back(TypeIt->second); - } - } + const auto *CE = Op->stripPointerCastsAndAliases(); + + if (CE->hasName()) { + auto Name = CE->getName(); + if (Name.find(TypeInfoPrefix) != llvm::StringRef::npos) { + auto ClearName = removeTypeInfoPrefix(llvm::demangle(Name.str())); + if (auto TypeIt = ClearNameTypeMap.find(ClearName); + TypeIt != ClearNameTypeMap.end()) { + SubTypes.push_back(TypeIt->second); } } } @@ -329,8 +328,9 @@ LLVMTypeHierarchy::getSubTypes(const llvm::StructType *Type) const { return {}; } -const llvm::StructType * -LLVMTypeHierarchy::getType(llvm::StringRef TypeName) const { +template +static const llvm::StructType *getTypeImpl(const GraphT &TypeGraph, + llvm::StringRef TypeName) { for (auto V : boost::make_iterator_range(boost::vertices(TypeGraph))) { if (TypeGraph[V].Type->getName() == TypeName) { return TypeGraph[V].Type; @@ -339,6 +339,17 @@ LLVMTypeHierarchy::getType(llvm::StringRef TypeName) const { return nullptr; } +const llvm::StructType * +LLVMTypeHierarchy::getType(llvm::StringRef TypeName) const { + if (const auto *Ty = getTypeImpl(TypeGraph, TypeName)) { + return Ty; + } + + // Sometimes, clang adds a .base suffix + std::string TN = TypeName.str() + ".base"; + return getTypeImpl(TypeGraph, TypeName); +} + std::vector LLVMTypeHierarchy::getAllTypes() const { std::vector Types; Types.reserve(boost::num_vertices(TypeGraph)); diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp index 2b6b443ef9..b25822da84 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp @@ -82,22 +82,10 @@ LLVMVFTable::getVFVectorFromIRVTable(const llvm::ConstantStruct &VT) { // is RTTI for (const auto *It = std::next(CA->operands().begin(), 2); It != CA->operands().end(); ++It) { - const auto &COp = *It; - if (const auto *CE = llvm::dyn_cast(COp)) { - if (const auto *BC = llvm::dyn_cast(CE)) { - // if the entry is a GlobalAlias, get its Aliasee - auto *Entry = BC->getOperand(0); - while (auto *GA = llvm::dyn_cast(Entry)) { - Entry = GA->getAliasee(); - } - auto *F = llvm::dyn_cast(Entry); - VFS.push_back(F); - } else { - VFS.push_back(nullptr); - } - } else { - VFS.push_back(nullptr); - } + const auto *Entry = It->get()->stripPointerCastsAndAliases(); + + const auto *F = llvm::dyn_cast(Entry); + VFS.push_back(F); } } } diff --git a/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp b/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp index 0fa9a40bda..e8d700cf6b 100644 --- a/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp +++ b/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp @@ -27,8 +27,9 @@ TEST(LTHTest, BasicTHReconstruction_1) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "type_hierarchies/type_hierarchy_1_cpp.ll"); LLVMTypeHierarchy LTH(IRDB); - EXPECT_EQ(LTH.hasType(LTH.getType("struct.Base")), true); - EXPECT_EQ(LTH.hasType(LTH.getType("struct.Child")), true); + + ASSERT_EQ(LTH.hasType(LTH.getType("struct.Base")), true); + ASSERT_EQ(LTH.hasType(LTH.getType("struct.Child")), true); EXPECT_EQ(LTH.getAllTypes().size(), 2U); EXPECT_EQ( LTH.isSubType(LTH.getType("struct.Base"), LTH.getType("struct.Child")), @@ -163,12 +164,10 @@ TEST(LTHTest, BasicTHReconstruction_7) { LLVMTypeHierarchy LTH(IRDB); EXPECT_EQ(LTH.hasType(LTH.getType("struct.Base")), true); EXPECT_EQ(LTH.hasType(LTH.getType("struct.Child")), true); - // has three types because of padding (introduction of intermediate type) EXPECT_EQ(LTH.getAllTypes().size(), 3U); EXPECT_EQ( LTH.isSubType(LTH.getType("struct.Base"), LTH.getType("struct.Child")), true); - EXPECT_EQ(LTH.getSubTypes(LTH.getType("struct.Base")).size(), 2U); EXPECT_EQ(LTH.getSubTypes(LTH.getType("struct.Child")).size(), 1U); auto BaseReachable = LTH.getSubTypes(LTH.getType("struct.Base")); @@ -268,7 +267,6 @@ TEST(LTHTest, TransitivelyReachableTypes) { ASSERT_TRUE(ReachableTypesNonvirtualstruct3.size() == 1U); ASSERT_TRUE(ReachableTypesBase4.count(TH4.getType("struct.Base"))); - ASSERT_FALSE(ReachableTypesBase4.count(TH4.getType("struct.Base.base"))); ASSERT_TRUE(ReachableTypesBase4.count(TH4.getType("struct.Child"))); ASSERT_TRUE(ReachableTypesBase4.size() == 2U); ASSERT_TRUE(ReachableTypesChild4.count(TH4.getType("struct.Child")));