1ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===- FuzzerCrossOver.cpp - Cross over two test inputs -------------------===//
2ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//
3ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//                     The LLVM Compiler Infrastructure
4ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//
5ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// This file is distributed under the University of Illinois Open Source
6ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// License. See LICENSE.TXT for details.
7ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//
8ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===//
9ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Cross over test inputs.
10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===//
11ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include <cstring>
136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
14ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "FuzzerInternal.h"
15ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
16ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesnamespace fuzzer {
17ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Cross Data1 and Data2, store the result (up to MaxOutSize bytes) in Out.
19f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarsize_t MutationDispatcher::CrossOver(const uint8_t *Data1, size_t Size1,
20f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                     const uint8_t *Data2, size_t Size2,
21f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                     uint8_t *Out, size_t MaxOutSize) {
226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  assert(Size1 || Size2);
23f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MaxOutSize = Rand(MaxOutSize) + 1;
246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  size_t OutPos = 0;
256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  size_t Pos1 = 0;
266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  size_t Pos2 = 0;
276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  size_t *InPos = &Pos1;
286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  size_t InSize = Size1;
296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const uint8_t *Data = Data1;
306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool CurrentlyUsingFirstData = true;
316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  while (OutPos < MaxOutSize && (Pos1 < Size1 || Pos2 < Size2)) {
326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // Merge a part of Data into Out.
336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    size_t OutSizeLeft = MaxOutSize - OutPos;
346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (*InPos < InSize) {
356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      size_t InSizeLeft = InSize - *InPos;
366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      size_t MaxExtraSize = std::min(OutSizeLeft, InSizeLeft);
37f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      size_t ExtraSize = Rand(MaxExtraSize) + 1;
386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      memcpy(Out + OutPos, Data + *InPos, ExtraSize);
396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      OutPos += ExtraSize;
406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      (*InPos) += ExtraSize;
41ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // Use the other input data on the next iteration.
436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    InPos  = CurrentlyUsingFirstData ? &Pos2 : &Pos1;
446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    InSize = CurrentlyUsingFirstData ? Size2 : Size1;
456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Data   = CurrentlyUsingFirstData ? Data2 : Data1;
466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    CurrentlyUsingFirstData = !CurrentlyUsingFirstData;
47ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return OutPos;
49ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
50ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
51ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}  // namespace fuzzer
52