Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
Expand Down Expand Up @@ -53,6 +55,7 @@
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/CallGraphUpdater.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

using namespace std;
using namespace llvm;
Expand Down Expand Up @@ -146,6 +149,27 @@ typedef struct BranchSidesComplexity {
FalseSideComp(FC) {}
} BranchSidesComplexity;

typedef struct AlwaysQuotedString {
std::string &Storage;
explicit AlwaysQuotedString(std::string &S) : Storage(S) {}
};

template <> struct yaml::ScalarTraits<AlwaysQuotedString> {
static void output(const AlwaysQuotedString &S, void *Ctx, raw_ostream &OS) {
OS << S.Storage;
}

static StringRef input(StringRef Scalar, void *Ctx, AlwaysQuotedString &S) {
S.Storage = Scalar.str();
return StringRef();
}

static QuotingType mustQuote(StringRef) {
return QuotingType::Double;
}
};


// YAML mappings for outputting the typedefs above
template <> struct yaml::MappingTraits<FuzzerFunctionWrapper> {
static void mapping(IO &io, FuzzerFunctionWrapper &Func) {
Expand Down Expand Up @@ -286,10 +310,15 @@ typedef struct FunctionDebugWrapperS {

template <> struct yaml::MappingTraits<FunctionDebugWrapper> {
static void mapping(IO &io, FunctionDebugWrapper &fw) {
io.mapRequired("name", fw.funcName);
// Ensure function names are always quoted which forces pyyaml to treat them as strings
// https://github.com/yaml/pyyaml/issues/613
AlwaysQuotedString QuotedName(fw.funcName);
AlwaysQuotedString QuotedRawName(fw.rawName);

io.mapRequired("name", QuotedName);
io.mapRequired("file_location", fw.fileLocation);
io.mapRequired("type_arguments", fw.argTypes);
io.mapRequired("raw_name", fw.rawName);
io.mapRequired("raw_name", QuotedRawName);
io.mapRequired("is_public", fw.isPublic);
io.mapRequired("is_private", fw.isPrivate);
}
Expand Down Expand Up @@ -880,6 +909,7 @@ void FuzzIntrospector::makeDefaultConfig() {
"llvm[.]",
"sanitizer_cov",
"sancov[.]module",
"__fuzz_introspector_keep_alive", // FuzzIntrospector association internals
};

std::vector<string> *current = &ConfigFuncsToAvoid;
Expand Down Expand Up @@ -971,6 +1001,17 @@ bool FuzzIntrospector::runOnModule(Module &M) {
FuzzIntrospectorTag, "FuzzIntrospectorTag");
GV->setInitializer(FuzzIntrospectorTag);

// Create a function that will be a global constructor to avoid Rust aggressively
// stripping the unused global variable away
FunctionType *FT = FunctionType::get(Type::getVoidTy(M.getContext()), false);
Function *F = Function::Create(FT, GlobalValue::InternalLinkage,
"__fuzz_introspector_keep_alive", &M);
BasicBlock *BB = BasicBlock::Create(M.getContext(), "entry", F);
IRBuilder<> Builder(BB);
Builder.CreateLoad(GV->getValueType(), GV, true, "volatile_read");
Builder.CreateRetVoid();
llvm::appendToGlobalCtors(M, F, 0);

extractFuzzerReachabilityGraph(M, "LLVMFuzzerTestOneInput");
dumpCalltree(&FuzzerCalltree, nextCalltreeFile);

Expand Down