1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00
llvm-mirror/include/llvm/FuzzMutate/IRMutator.h
Justin Bogner c5917e5476 Re-apply "Introduce FuzzMutate library"
Same as r311392 with some fixes for library dependencies. Thanks to
Chapuni for helping work those out!

Original commit message:

This introduces the FuzzMutate library, which provides structured
fuzzing for LLVM IR, as described in my EuroLLVM 2017 talk. Most of
the basic mutators to inject and delete IR are provided, with support
for most basic operations.

llvm-svn: 311402
2017-08-21 22:57:06 +00:00

107 lines
3.6 KiB
C++

//===-- IRMutator.h - Mutation engine for fuzzing IR ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Provides the IRMutator class, which drives mutations on IR based on a
// configurable set of strategies. Some common strategies are also included
// here.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_FUZZMUTATE_IRMUTATOR_H
#define LLVM_FUZZMUTATE_IRMUTATOR_H
#include "llvm/FuzzMutate/OpDescriptor.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
class BasicBlock;
class Function;
class Instruction;
class Module;
struct RandomIRBuilder;
/// Base class for describing how to mutate a module. mutation functions for
/// each IR unit forward to the contained unit.
class IRMutationStrategy {
public:
virtual ~IRMutationStrategy() = default;
/// Provide a weight to bias towards choosing this strategy for a mutation.
///
/// The value of the weight is arbitrary, but a good default is "the number of
/// distinct ways in which this strategy can mutate a unit". This can also be
/// used to prefer strategies that shrink the overall size of the result when
/// we start getting close to \c MaxSize.
virtual uint64_t getWeight(size_t CurrentSize, size_t MaxSize,
uint64_t CurrentWeight) = 0;
/// @{
/// Mutators for each IR unit. By default these forward to a contained
/// instance of the next smaller unit.
virtual void mutate(Module &M, RandomIRBuilder &IB);
virtual void mutate(Function &F, RandomIRBuilder &IB);
virtual void mutate(BasicBlock &BB, RandomIRBuilder &IB);
virtual void mutate(Instruction &I, RandomIRBuilder &IB) {
llvm_unreachable("Strategy does not implement any mutators");
}
/// @}
};
using TypeGetter = std::function<Type *(LLVMContext &)>;
/// Entry point for configuring and running IR mutations.
class IRMutator {
std::vector<TypeGetter> AllowedTypes;
std::vector<std::unique_ptr<IRMutationStrategy>> Strategies;
public:
IRMutator(std::vector<TypeGetter> &&AllowedTypes,
std::vector<std::unique_ptr<IRMutationStrategy>> &&Strategies)
: AllowedTypes(std::move(AllowedTypes)),
Strategies(std::move(Strategies)) {}
void mutateModule(Module &M, int Seed, size_t CurSize, size_t MaxSize);
};
/// Strategy that injects operations into the function.
class InjectorIRStrategy : public IRMutationStrategy {
std::vector<fuzzerop::OpDescriptor> Operations;
fuzzerop::OpDescriptor chooseOperation(Value *Src, RandomIRBuilder &IB);
public:
InjectorIRStrategy(std::vector<fuzzerop::OpDescriptor> &&Operations)
: Operations(std::move(Operations)) {}
static std::vector<fuzzerop::OpDescriptor> getDefaultOps();
uint64_t getWeight(size_t CurrentSize, size_t MaxSize,
uint64_t CurrentWeight) override {
return Operations.size();
}
using IRMutationStrategy::mutate;
void mutate(Function &F, RandomIRBuilder &IB) override;
void mutate(BasicBlock &BB, RandomIRBuilder &IB) override;
};
class InstDeleterIRStrategy : public IRMutationStrategy {
public:
uint64_t getWeight(size_t CurrentSize, size_t MaxSize,
uint64_t CurrentWeight) override;
using IRMutationStrategy::mutate;
void mutate(Function &F, RandomIRBuilder &IB) override;
void mutate(Instruction &Inst, RandomIRBuilder &IB) override;
};
} // end llvm namespace
#endif // LLVM_FUZZMUTATE_IRMUTATOR_H