xref: /aosp_15_r20/external/llvm/lib/Fuzzer/FuzzerCrossOver.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- FuzzerCrossOver.cpp - Cross over two test inputs -------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker // Cross over test inputs.
10*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
11*9880d681SAndroid Build Coastguard Worker 
12*9880d681SAndroid Build Coastguard Worker #include <cstring>
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "FuzzerInternal.h"
15*9880d681SAndroid Build Coastguard Worker 
16*9880d681SAndroid Build Coastguard Worker namespace fuzzer {
17*9880d681SAndroid Build Coastguard Worker 
18*9880d681SAndroid Build Coastguard Worker // Cross Data1 and Data2, store the result (up to MaxOutSize bytes) in Out.
CrossOver(const uint8_t * Data1,size_t Size1,const uint8_t * Data2,size_t Size2,uint8_t * Out,size_t MaxOutSize)19*9880d681SAndroid Build Coastguard Worker size_t MutationDispatcher::CrossOver(const uint8_t *Data1, size_t Size1,
20*9880d681SAndroid Build Coastguard Worker                                      const uint8_t *Data2, size_t Size2,
21*9880d681SAndroid Build Coastguard Worker                                      uint8_t *Out, size_t MaxOutSize) {
22*9880d681SAndroid Build Coastguard Worker   assert(Size1 || Size2);
23*9880d681SAndroid Build Coastguard Worker   MaxOutSize = Rand(MaxOutSize) + 1;
24*9880d681SAndroid Build Coastguard Worker   size_t OutPos = 0;
25*9880d681SAndroid Build Coastguard Worker   size_t Pos1 = 0;
26*9880d681SAndroid Build Coastguard Worker   size_t Pos2 = 0;
27*9880d681SAndroid Build Coastguard Worker   size_t *InPos = &Pos1;
28*9880d681SAndroid Build Coastguard Worker   size_t InSize = Size1;
29*9880d681SAndroid Build Coastguard Worker   const uint8_t *Data = Data1;
30*9880d681SAndroid Build Coastguard Worker   bool CurrentlyUsingFirstData = true;
31*9880d681SAndroid Build Coastguard Worker   while (OutPos < MaxOutSize && (Pos1 < Size1 || Pos2 < Size2)) {
32*9880d681SAndroid Build Coastguard Worker     // Merge a part of Data into Out.
33*9880d681SAndroid Build Coastguard Worker     size_t OutSizeLeft = MaxOutSize - OutPos;
34*9880d681SAndroid Build Coastguard Worker     if (*InPos < InSize) {
35*9880d681SAndroid Build Coastguard Worker       size_t InSizeLeft = InSize - *InPos;
36*9880d681SAndroid Build Coastguard Worker       size_t MaxExtraSize = std::min(OutSizeLeft, InSizeLeft);
37*9880d681SAndroid Build Coastguard Worker       size_t ExtraSize = Rand(MaxExtraSize) + 1;
38*9880d681SAndroid Build Coastguard Worker       memcpy(Out + OutPos, Data + *InPos, ExtraSize);
39*9880d681SAndroid Build Coastguard Worker       OutPos += ExtraSize;
40*9880d681SAndroid Build Coastguard Worker       (*InPos) += ExtraSize;
41*9880d681SAndroid Build Coastguard Worker     }
42*9880d681SAndroid Build Coastguard Worker     // Use the other input data on the next iteration.
43*9880d681SAndroid Build Coastguard Worker     InPos  = CurrentlyUsingFirstData ? &Pos2 : &Pos1;
44*9880d681SAndroid Build Coastguard Worker     InSize = CurrentlyUsingFirstData ? Size2 : Size1;
45*9880d681SAndroid Build Coastguard Worker     Data   = CurrentlyUsingFirstData ? Data2 : Data1;
46*9880d681SAndroid Build Coastguard Worker     CurrentlyUsingFirstData = !CurrentlyUsingFirstData;
47*9880d681SAndroid Build Coastguard Worker   }
48*9880d681SAndroid Build Coastguard Worker   return OutPos;
49*9880d681SAndroid Build Coastguard Worker }
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker }  // namespace fuzzer
52