Skip to content

Commit 1c4e3cb

Browse files
committed
Improve file IO + enable DominatorTree analysis injection into the IDEExtendedTaintAnalysis
1 parent 16c859b commit 1c4e3cb

6 files changed

Lines changed: 85 additions & 64 deletions

File tree

include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/IDEExtendedTaintAnalysis.h

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h"
3737
#include "phasar/PhasarLLVM/Domain/AnalysisDomain.h"
3838
#include "phasar/PhasarLLVM/TaintConfig/TaintConfig.h"
39+
#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h"
3940
#include "phasar/PhasarLLVM/Utils/BasicBlockOrdering.h"
4041
#include "phasar/PhasarLLVM/Utils/LatticeDomain.h"
4142
#include "phasar/Utils/LLVMShorthands.h"
@@ -44,7 +45,6 @@
4445
namespace psr {
4546

4647
class ProjectIRDB;
47-
class LLVMTypeHierarchy;
4848
class LLVMBasedICFG;
4949
class LLVMPointsToInfo;
5050

@@ -62,21 +62,15 @@ class IDEExtendedTaintAnalysis
6262
using base_t = IDETabulationProblem<IDEExtendedTaintAnalysisDomain>;
6363

6464
public:
65-
using n_t =
66-
typename IDETabulationProblem<IDEExtendedTaintAnalysisDomain>::n_t;
67-
using f_t =
68-
typename IDETabulationProblem<IDEExtendedTaintAnalysisDomain>::f_t;
69-
using d_t =
70-
typename IDETabulationProblem<IDEExtendedTaintAnalysisDomain>::d_t;
71-
using l_t =
72-
typename IDETabulationProblem<IDEExtendedTaintAnalysisDomain>::l_t;
73-
using FlowFunctionPtrType = typename IDETabulationProblem<
65+
using typename IDETabulationProblem<IDEExtendedTaintAnalysisDomain>::n_t;
66+
using typename IDETabulationProblem<IDEExtendedTaintAnalysisDomain>::f_t;
67+
using typename IDETabulationProblem<IDEExtendedTaintAnalysisDomain>::d_t;
68+
using typename IDETabulationProblem<IDEExtendedTaintAnalysisDomain>::l_t;
69+
using typename IDETabulationProblem<
7470
IDEExtendedTaintAnalysisDomain>::FlowFunctionPtrType;
75-
using EdgeFunctionPtrType = typename IDETabulationProblem<
71+
using typename IDETabulationProblem<
7672
IDEExtendedTaintAnalysisDomain>::EdgeFunctionPtrType;
7773

78-
// using FunctionInfoSetTy = XTaint::FunctionInfoSetTy;
79-
8074
using config_callback_t = TaintConfig::TaintDescriptionCallBackTy;
8175

8276
private:
@@ -146,11 +140,25 @@ class IDEExtendedTaintAnalysis
146140
public:
147141
/// Constructor. If EntryPoints is empty, use the TaintAPI functions as
148142
/// entrypoints.
143+
/// The GetDomTree parameter can be used to inject a custom DominatorTree
144+
/// analysis or the results from a LLVM pass computing dominator trees
145+
template <typename GetDomTree = DefaultDominatorTreeAnalysis>
149146
IDEExtendedTaintAnalysis(const ProjectIRDB *IRDB, const LLVMTypeHierarchy *TH,
150147
const LLVMBasedICFG *ICF, LLVMPointsToInfo *PT,
151148
const TaintConfig *TSF,
152149
std::set<std::string> EntryPoints, unsigned Bound,
153-
bool DisableStrongUpdates);
150+
bool DisableStrongUpdates,
151+
GetDomTree &&GDT = DefaultDominatorTreeAnalysis{})
152+
: base_t(IRDB, TH, ICF, PT, std::move(EntryPoints)), AnalysisBase(TSF),
153+
BBO(std::forward<GetDomTree>(GDT)),
154+
FactFactory(IRDB->getNumInstructions()),
155+
DL((*IRDB->getAllModules().begin())->getDataLayout()), Bound(Bound),
156+
PostProcessed(DisableStrongUpdates),
157+
DisableStrongUpdates(DisableStrongUpdates) {
158+
base_t::ZeroValue = createZeroValue();
159+
160+
FactFactory.setDataLayout(DL);
161+
}
154162

155163
~IDEExtendedTaintAnalysis() override = default;
156164

@@ -283,12 +291,15 @@ class IDEExtendedTaintAnalysis
283291
template <unsigned BOUND = 3, bool USE_STRONG_UPDATES = true>
284292
class IDEExtendedTaintAnalysis : public XTaint::IDEExtendedTaintAnalysis {
285293
public:
294+
template <typename GetDomTree = DefaultDominatorTreeAnalysis>
286295
IDEExtendedTaintAnalysis(const ProjectIRDB *IRDB, const LLVMTypeHierarchy *TH,
287296
const LLVMBasedICFG *ICF, LLVMPointsToInfo *PT,
288297
const TaintConfig &TSF,
289-
std::set<std::string> EntryPoints = {})
298+
std::set<std::string> EntryPoints = {},
299+
GetDomTree &&GDT = DefaultDominatorTreeAnalysis{})
290300
: XTaint::IDEExtendedTaintAnalysis(IRDB, TH, ICF, PT, &TSF, EntryPoints,
291-
BOUND, !USE_STRONG_UPDATES) {}
301+
BOUND, !USE_STRONG_UPDATES,
302+
std::forward<GetDomTree>(GDT)) {}
292303

293304
using ConfigurationTy = TaintConfig;
294305
};

include/phasar/PhasarLLVM/Utils/BasicBlockOrdering.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
#define PHASAR_PHASARLLVM_UTILS_BASICBLOCKORDERING_H_
1212

1313
#include <memory>
14+
#include <type_traits>
1415

1516
#include "llvm/ADT/DenseMap.h"
17+
#include "llvm/ADT/FunctionExtras.h"
1618

1719
#include "phasar/DB/ProjectIRDB.h"
1820

@@ -24,15 +26,29 @@ class DominatorTree;
2426
} // namespace llvm
2527

2628
namespace psr {
27-
/// Provides a simple partial ordering of BasicBlocks based on LLVM's
28-
/// DominatorTree.
29-
class BasicBlockOrdering {
29+
30+
class DefaultDominatorTreeAnalysis {
3031
llvm::DenseMap<const llvm::Function *, std::unique_ptr<llvm::DominatorTree>>
3132
Dom;
3233

33-
llvm::DominatorTree &getDom(const llvm::Function *F);
34+
public:
35+
llvm::DominatorTree &operator()(const llvm::Function *F);
36+
};
37+
38+
/// Provides a simple partial ordering of BasicBlocks based on LLVM's
39+
/// DominatorTree.
40+
class BasicBlockOrdering {
41+
/// Note: Cannot use std::function, because we need to support move-only
42+
/// functors(e.g. DefaultDominatorTreeAnalysis)
43+
llvm::unique_function<llvm::DominatorTree &(const llvm::Function *)> getDom;
3444

3545
public:
46+
template <
47+
typename DTA,
48+
typename = std::enable_if_t<!std::is_same_v<
49+
BasicBlockOrdering, std::remove_reference_t<std::decay_t<DTA>>>>>
50+
explicit BasicBlockOrdering(DTA &&Dta) : getDom(std::forward<DTA>(Dta)) {}
51+
3652
bool mustComeBefore(const llvm::Instruction *LHS,
3753
const llvm::Instruction *RHS);
3854
};

include/phasar/Utils/IO.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,19 @@
1818
#define PHASAR_UTILS_IO_H
1919

2020
#include <filesystem>
21+
#include <memory>
2122
#include <string>
2223

24+
#include "llvm/Support/MemoryBuffer.h"
25+
2326
namespace psr {
2427

2528
std::string readTextFile(const std::filesystem::path &Path);
2629

27-
void writeTextFile(const std::filesystem::path &Path,
28-
const std::string &Content);
30+
std::unique_ptr<llvm::MemoryBuffer> readFile(const std::filesystem::path &Path);
31+
std::unique_ptr<llvm::MemoryBuffer> readFile(const llvm::Twine &Path);
32+
33+
void writeTextFile(const std::filesystem::path &Path, llvm::StringRef Content);
2934

3035
} // namespace psr
3136

lib/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/IDEExtendedTaintAnalysis.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,20 @@
3333

3434
namespace psr::XTaint {
3535

36-
IDEExtendedTaintAnalysis::IDEExtendedTaintAnalysis(
37-
const ProjectIRDB *IRDB, const LLVMTypeHierarchy *TH,
38-
const LLVMBasedICFG *ICF, LLVMPointsToInfo *PT, const TaintConfig *TSF,
39-
std::set<std::string> EntryPoints, unsigned Bound,
40-
bool DisableStrongUpdates)
41-
: base_t(IRDB, TH, ICF, PT, std::move(EntryPoints)), AnalysisBase(TSF),
42-
FactFactory(IRDB->getNumInstructions()),
43-
DL((*IRDB->getAllModules().begin())->getDataLayout()), Bound(Bound),
44-
PostProcessed(DisableStrongUpdates),
45-
DisableStrongUpdates(DisableStrongUpdates) {
46-
base_t::ZeroValue = createZeroValue();
47-
48-
FactFactory.setDataLayout(DL);
49-
}
36+
// IDEExtendedTaintAnalysis::IDEExtendedTaintAnalysis(
37+
// const ProjectIRDB *IRDB, const LLVMTypeHierarchy *TH,
38+
// const LLVMBasedICFG *ICF, LLVMPointsToInfo *PT, const TaintConfig *TSF,
39+
// std::set<std::string> EntryPoints, unsigned Bound,
40+
// bool DisableStrongUpdates)
41+
// : base_t(IRDB, TH, ICF, PT, std::move(EntryPoints)), AnalysisBase(TSF),
42+
// FactFactory(IRDB->getNumInstructions()),
43+
// DL((*IRDB->getAllModules().begin())->getDataLayout()), Bound(Bound),
44+
// PostProcessed(DisableStrongUpdates),
45+
// DisableStrongUpdates(DisableStrongUpdates) {
46+
// base_t::ZeroValue = createZeroValue();
47+
48+
// FactFactory.setDataLayout(DL);
49+
// }
5050

5151
InitialSeeds<IDEExtendedTaintAnalysis::n_t, IDEExtendedTaintAnalysis::d_t,
5252
IDEExtendedTaintAnalysis::l_t>

lib/PhasarLLVM/Utils/BasicBlockOrdering.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111
namespace psr {
1212

13-
llvm::DominatorTree &BasicBlockOrdering::getDom(const llvm::Function *F) {
13+
llvm::DominatorTree &
14+
DefaultDominatorTreeAnalysis::operator()(const llvm::Function *F) {
1415
auto &Ret = Dom[F];
1516
if (!Ret) {
1617
Ret =

lib/Utils/IO.cpp

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <string>
2222
#include <system_error>
2323

24+
#include "llvm/Support/MemoryBuffer.h"
2425
#include "llvm/Support/raw_ostream.h"
2526

2627
#include "phasar/Utils/IO.h"
@@ -29,43 +30,30 @@
2930
namespace psr {
3031

3132
std::string readTextFile(const std::filesystem::path &Path) {
32-
if (!(std::filesystem::exists(Path) &&
33-
std::filesystem::is_regular_file(Path))) {
34-
throw std::ios_base::failure("File does not exist: " + Path.string());
35-
}
36-
37-
auto NumBytes = std::filesystem::file_size(Path);
38-
39-
auto *F = std::fopen(Path.c_str(), "r");
40-
41-
if (!F) {
42-
throw std::ios_base::failure("Could not open file: " + Path.string());
43-
}
44-
45-
auto CloseFile = scope_exit([F]() { std::fclose(F); });
46-
47-
std::string Contents;
48-
49-
/// TODO: Get rid of the zero-initialization of the string
50-
Contents.resize(NumBytes);
33+
auto Buffer = readFile(Path);
34+
return Buffer->getBuffer().str();
35+
}
5136

52-
auto ReadBytes = std::fread(Contents.data(), 1, NumBytes, F);
37+
std::unique_ptr<llvm::MemoryBuffer>
38+
readFile(const std::filesystem::path &Path) {
39+
return readFile(llvm::StringRef(Path.string()));
40+
}
41+
std::unique_ptr<llvm::MemoryBuffer> readFile(const llvm::Twine &Path) {
42+
auto Ret = llvm::MemoryBuffer::getFile(Path);
5343

54-
if (ReadBytes != NumBytes) {
55-
throw std::ios_base::failure("Could not read file: " + Path.string());
44+
if (!Ret) {
45+
throw std::system_error(Ret.getError());
5646
}
5747

58-
return Contents;
48+
return std::move(Ret.get());
5949
}
6050

61-
void writeTextFile(const std::filesystem::path &Path,
62-
const std::string &Content) {
51+
void writeTextFile(const std::filesystem::path &Path, llvm::StringRef Content) {
6352
std::error_code EC;
6453
llvm::raw_fd_ostream ROS(Path.string(), EC);
6554

6655
if (EC) {
67-
throw std::ios_base::failure("Error creating the file: " + Path.string() +
68-
"; " + EC.message());
56+
throw std::system_error(EC);
6957
}
7058

7159
ROS.write(Content.data(), Content.size());

0 commit comments

Comments
 (0)