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