1 //===-- IRMutator.h - Mutation engine for fuzzing IR ------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Provides the IRMutator class, which drives mutations on IR based on a 11 // configurable set of strategies. Some common strategies are also included 12 // here. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_FUZZMUTATE_IRMUTATOR_H 17 #define LLVM_FUZZMUTATE_IRMUTATOR_H 18 19 #include "llvm/ADT/Optional.h" 20 #include "llvm/FuzzMutate/OpDescriptor.h" 21 #include "llvm/Support/ErrorHandling.h" 22 23 namespace llvm { 24 class BasicBlock; 25 class Function; 26 class Instruction; 27 class Module; 28 29 struct RandomIRBuilder; 30 31 /// Base class for describing how to mutate a module. mutation functions for 32 /// each IR unit forward to the contained unit. 33 class IRMutationStrategy { 34 public: 35 virtual ~IRMutationStrategy() = default; 36 37 /// Provide a weight to bias towards choosing this strategy for a mutation. 38 /// 39 /// The value of the weight is arbitrary, but a good default is "the number of 40 /// distinct ways in which this strategy can mutate a unit". This can also be 41 /// used to prefer strategies that shrink the overall size of the result when 42 /// we start getting close to \c MaxSize. 43 virtual uint64_t getWeight(size_t CurrentSize, size_t MaxSize, 44 uint64_t CurrentWeight) = 0; 45 46 /// @{ 47 /// Mutators for each IR unit. By default these forward to a contained 48 /// instance of the next smaller unit. 49 virtual void mutate(Module &M, RandomIRBuilder &IB); 50 virtual void mutate(Function &F, RandomIRBuilder &IB); 51 virtual void mutate(BasicBlock &BB, RandomIRBuilder &IB); mutate(Instruction & I,RandomIRBuilder & IB)52 virtual void mutate(Instruction &I, RandomIRBuilder &IB) { 53 llvm_unreachable("Strategy does not implement any mutators"); 54 } 55 /// @} 56 }; 57 58 using TypeGetter = std::function<Type *(LLVMContext &)>; 59 60 /// Entry point for configuring and running IR mutations. 61 class IRMutator { 62 std::vector<TypeGetter> AllowedTypes; 63 std::vector<std::unique_ptr<IRMutationStrategy>> Strategies; 64 65 public: IRMutator(std::vector<TypeGetter> && AllowedTypes,std::vector<std::unique_ptr<IRMutationStrategy>> && Strategies)66 IRMutator(std::vector<TypeGetter> &&AllowedTypes, 67 std::vector<std::unique_ptr<IRMutationStrategy>> &&Strategies) 68 : AllowedTypes(std::move(AllowedTypes)), 69 Strategies(std::move(Strategies)) {} 70 71 void mutateModule(Module &M, int Seed, size_t CurSize, size_t MaxSize); 72 }; 73 74 /// Strategy that injects operations into the function. 75 class InjectorIRStrategy : public IRMutationStrategy { 76 std::vector<fuzzerop::OpDescriptor> Operations; 77 78 Optional<fuzzerop::OpDescriptor> chooseOperation(Value *Src, 79 RandomIRBuilder &IB); 80 81 public: InjectorIRStrategy(std::vector<fuzzerop::OpDescriptor> && Operations)82 InjectorIRStrategy(std::vector<fuzzerop::OpDescriptor> &&Operations) 83 : Operations(std::move(Operations)) {} 84 static std::vector<fuzzerop::OpDescriptor> getDefaultOps(); 85 getWeight(size_t CurrentSize,size_t MaxSize,uint64_t CurrentWeight)86 uint64_t getWeight(size_t CurrentSize, size_t MaxSize, 87 uint64_t CurrentWeight) override { 88 return Operations.size(); 89 } 90 91 using IRMutationStrategy::mutate; 92 void mutate(Function &F, RandomIRBuilder &IB) override; 93 void mutate(BasicBlock &BB, RandomIRBuilder &IB) override; 94 }; 95 96 class InstDeleterIRStrategy : public IRMutationStrategy { 97 public: 98 uint64_t getWeight(size_t CurrentSize, size_t MaxSize, 99 uint64_t CurrentWeight) override; 100 101 using IRMutationStrategy::mutate; 102 void mutate(Function &F, RandomIRBuilder &IB) override; 103 void mutate(Instruction &Inst, RandomIRBuilder &IB) override; 104 }; 105 106 } // end llvm namespace 107 108 #endif // LLVM_FUZZMUTATE_IRMUTATOR_H 109