Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set up an initial development environment #12

Merged
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
86 changes: 49 additions & 37 deletions PreciseLeakSanitizer/PreciseLeakSanitizer.cpp
Original file line number Diff line number Diff line change
@@ -1,63 +1,75 @@
#include "llvm/Pass.h"
#include "PreciseLeakSanitizer.h"

#include "llvm/IR/IRBuilder.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

using namespace llvm;

namespace {
void PreciseLeakSanVisitor::visitStoreInst(StoreInst &I) { return; }

void PreciseLeakSanVisitor::visitReturnInst(ReturnInst &I) { return; }

struct PreciseLeakSanitizer : public PassInfoMixin<PreciseLeakSanitizer> {
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) {
bool transformed = false;
for (auto &F : M) {
for (auto &BB : F) {
for (auto &I : BB) {
if (auto *CI = dyn_cast<CallInst>(&I)) {
IRBuilder builder(CI);
void PreciseLeakSanVisitor::visitCallInst(CallInst &I) { return; }

if (CI->getName() == "malloc") {
void PreciseLeakSanVisitor::visitCallMalloc(CallInst &I) { return; }

} else if (CI->getName() == "calloc") {
void PreciseLeakSanVisitor::visitCallCalloc(CallInst &I) { return; }

} else if (CI->getName() == "realloc") {
void PreciseLeakSanVisitor::visitCallNew(CallInst &I) { return; }

} else if (CI->getName() == "new") {
void PreciseLeakSanVisitor::visitCallArrTyNew(CallInst &I) { return; }

} else if (CI->getName() == "new[]") {
void PreciseLeakSanVisitor::visitCallFree(CallInst &I) { return; }

} else if (CI->getName() == "free") {
void PreciseLeakSanVisitor::visitCallMemset(CallInst &I) { return; }

} else if (CI->getName() == "memset") {
void PreciseLeakSanVisitor::visitCallMemcpy(CallInst &I) { return; }

} else if (CI->getName() == "memcpy") {
void PreciseLeakSanVisitor::visitCallMemmove(CallInst &I) { return; }

} else if (CI->getName() == "memmove") {
void PreciseLeakSanVisitor::visitCallBzero(CallInst &I) { return; }

} else if (CI->getName() == "bzero") {
}
} else if (auto *SI = dyn_cast<StoreInst>(&I)) {
bool PreciseLeakSanitizer::initializeModule(Module &M) { return false; }

} else if (auto *RI = dyn_cast<ReturnInst>(&I)) {
}
}
bool PreciseLeakSanitizer::run(Module &M) {
for (Function &F : M) {
for (BasicBlock &BB : F) {
for (Instruction &I : BB) {
PreciseLeakSanVisitor().visit(I);
}
}
return (transformed ? PreservedAnalyses::none() : PreservedAnalyses::all());
};
};
}
return false;
}

} // namespace
PreservedAnalyses PreciseLeakSanitizerPass::run(Module &M,
ModuleAnalysisManager &) {
return (PreciseLeakSanitizer().run(M) ? PreservedAnalyses::none()
: PreservedAnalyses::all());
}

extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
llvmGetPassPluginInfo() {
return {.APIVersion = LLVM_PLUGIN_API_VERSION,
.PluginName = "PreciseLeakSanitizer",
.PluginVersion = "v0.1",
.RegisterPassBuilderCallbacks = [](PassBuilder &PB) {
llvm::PassPluginLibraryInfo getPreciseLeakSanitizerPluginInfo() {
return {LLVM_PLUGIN_API_VERSION, "precise-leak-sanitizer",
LLVM_VERSION_STRING, [](PassBuilder &PB) {
PB.registerPipelineParsingCallback(
[](StringRef Name, ModulePassManager &MPM,
ArrayRef<PassBuilder::PipelineElement>) {
if (Name == "precise-leak-sanitizer") {
MPM.addPass(PreciseLeakSanitizerPass());
return true;
}
return false;
});
PB.registerPipelineStartEPCallback(
[](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(PreciseLeakSanitizer());
MPM.addPass(PreciseLeakSanitizerPass());
});
}};
}

extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
llvmGetPassPluginInfo() {
return getPreciseLeakSanitizerPluginInfo();
}
57 changes: 57 additions & 0 deletions PreciseLeakSanitizer/PreciseLeakSanitizer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#ifndef PRECISE_LEAK_SANITIZER_H
#define PRECISE_LEAK_SANITIZER_H

#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"

using namespace llvm;

class PreciseLeakSanitizer {
private:
friend class PreciseLeakSanVisitor;

Module *Mod;
LLVMContext *Ctx;

// RT library functions
FunctionType *RefCountFnTy;
FunctionType *AllocSizeAlignFnTy;
FunctionType *InitDynAllocShadowMemFnTy;
FunctionCallee RefCountFn;
FunctionCallee AllocSizeAlignFn;
FunctionCallee InitDynAllocShadowMemFn;
StringRef RefCountFnName = "refCount";
StringRef AllocSizeAlignFnName = "allocSizeAlign";
StringRef InitDynAllocShadowMemFnName = "initDynAllocShadowMem";

bool initializeModule(Module &M);

public:
bool run(Module &M);
};

class PreciseLeakSanVisitor : public InstVisitor<PreciseLeakSanVisitor> {
public:
void visitStoreInst(StoreInst &I);
void visitReturnInst(ReturnInst &I);
void visitCallInst(CallInst &I);

private:
void visitCallMalloc(CallInst &I);
void visitCallCalloc(CallInst &I);
void visitCallNew(CallInst &I);
void visitCallArrTyNew(CallInst &I);
void visitCallFree(CallInst &I);
void visitCallMemset(CallInst &I);
void visitCallMemcpy(CallInst &I);
void visitCallMemmove(CallInst &I);
void visitCallBzero(CallInst &I);
};

struct PreciseLeakSanitizerPass
: public PassInfoMixin<PreciseLeakSanitizerPass> {
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
};

#endif
26 changes: 25 additions & 1 deletion RuntimeLibrary/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,25 @@
add_library(plsan plsan.cpp)
cmake_minimum_required(VERSION 3.10)

project(Plsan)

# Add source files to the project
set(SOURCES
plsan.cpp
plsan_storage.cpp
plsan_handler.cpp
plsan_shadow.cpp
)

# Add header files to the project
set(HEADERS
plsan.h
plsan_storage.h
plsan_handler.h
plsan_shadow.h
)

# Add library target
add_library(plsan STATIC ${SOURCES} ${HEADERS})

# Specify include directories
target_include_directories(plsan PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
26 changes: 26 additions & 0 deletions RuntimeLibrary/plsan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@
* collisons with the program. For example: __foo(), __bar(), etc.
*/

#include "plsan.h"

#include <cstddef>

__plsan::Plsan *plsan;

/* Initialization routines called before main() */
__attribute__((constructor)) void __plsan_init() { /* TODO: */
plsan = new __plsan::Plsan();
}

purplepig4657 marked this conversation as resolved.
Show resolved Hide resolved
/* finialization routines called after main()*/
__attribute__((destructor)) void __plsan_fini() { delete plsan; }

void __plsan_alloc(void *addr, size_t size) {
/* TODO: initialize references */
}
Expand All @@ -24,3 +32,21 @@ void __plsan_exit_func() {
* 2) or the address of a buffer is return value
*/
}

namespace __plsan {

Plsan::Plsan() {
shadow = new PlsanShadow();
storage = new PlsanStorage();
handler = new PlsanHandler();
}

void Plsan::enter_func() {
// enter_func
}

void Plsan::exit_func() {
// exit_func
}

} // namespace __plsan
26 changes: 26 additions & 0 deletions RuntimeLibrary/plsan.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef PLSAN_H
#define PLSAN_H

#include "plsan_handler.h"
#include "plsan_shadow.h"
#include "plsan_storage.h"

namespace __plsan {

class Plsan {
public:
Plsan();
// long align_size(long size);

void enter_func();
void exit_func();

private:
PlsanShadow *shadow;
PlsanStorage *storage;
PlsanHandler *handler;
};

} // namespace __plsan

#endif
11 changes: 11 additions & 0 deletions RuntimeLibrary/plsan_handler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "plsan_handler.h"

namespace __plsan {

void PlsanHandler::exception_check(RefCountAnalysis ref_count_analysis) {
AddrType addrType;
ExceptionType exceptionType;
std::tie(addrType, exceptionType) = ref_count_analysis;
}

} // namespace __plsan
21 changes: 21 additions & 0 deletions RuntimeLibrary/plsan_handler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef PLSAN_HANDLER_H
#define PLSAN_HANDLER_H

#include <tuple>

namespace __plsan {

enum AddrType { NonDynAlloc, DynAlloc };
enum ExceptionType { None, RefCountZero };
// Something stack trace data structure here.

using RefCountAnalysis = std::tuple<AddrType, ExceptionType /*, StackTrace*/>;

class PlsanHandler {
public:
void exception_check(RefCountAnalysis ref_count_analysis);
};

} // namespace __plsan

#endif
22 changes: 22 additions & 0 deletions RuntimeLibrary/plsan_shadow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "plsan_shadow.h"

#include <sys/mman.h>

namespace __plsan {

PlsanShadow::PlsanShadow() {
shadow_addr = mmap(NULL, MMAP_SIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
if (shadow_addr == MAP_FAILED)
throw "mmap failed\n";
}

purplepig4657 marked this conversation as resolved.
Show resolved Hide resolved
PlsanShadow::~PlsanShadow() { munmap(shadow_addr, MMAP_SIZE); }

void PlsanShadow::alloc_shadow(void *addr, size_t size) {}

void PlsanShadow::update_reference(void **lhs, void *rhs) {}

void *PlsanShadow::addr_to_shadow_addr(void *addr) { return 0; }

} // namespace __plsan
24 changes: 24 additions & 0 deletions RuntimeLibrary/plsan_shadow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef PLSAN_SHADOW_H
#define PLSAN_SHADOW_H

#include <cstddef>

namespace __plsan {

#define MMAP_SIZE ((1L << 48) / 16)

class PlsanShadow {
public:
PlsanShadow();
~PlsanShadow();
void alloc_shadow(void *addr, size_t size);
void update_reference(void **lhs, void *rhs);

private:
void *shadow_addr;
void *addr_to_shadow_addr(void *addr);
};

} // namespace __plsan

#endif
11 changes: 11 additions & 0 deletions RuntimeLibrary/plsan_storage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "plsan_storage.h"

void PlsanStorage::push_function() {}

void PlsanStorage::pop_function() {}

void PlsanStorage::add_mem_addr() {}

LocalDynAllocStorage PlsanStorage::get_function_stack() {
return function_stack;
}
19 changes: 19 additions & 0 deletions RuntimeLibrary/plsan_storage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef PLSAN_STORAGE_H
#define PLSAN_STORAGE_H

#include <stack>

using LocalDynAllocStorage = std::stack<std::stack<void *>>;

class PlsanStorage {
public:
void push_function();
void pop_function();
void add_mem_addr();
LocalDynAllocStorage get_function_stack();

private:
LocalDynAllocStorage function_stack;
};

#endif