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