Index: compiler-rt/lib/fuzzer/CMakeLists.txt =================================================================== --- compiler-rt/lib/fuzzer/CMakeLists.txt +++ compiler-rt/lib/fuzzer/CMakeLists.txt @@ -1,23 +1,12 @@ -set(LIBFUZZER_SOURCES - FuzzerCrossOver.cpp - FuzzerDataFlowTrace.cpp +set(LIBFUZZER_BASE_SOURCES FuzzerDeprecated.cpp - FuzzerDriver.cpp - FuzzerDSORelative.cpp FuzzerExtFunctionsDlsym.cpp FuzzerExtFunctionsWeak.cpp FuzzerExtFunctionsWindows.cpp - FuzzerExtraCounters.cpp - FuzzerFork.cpp FuzzerIO.cpp FuzzerIOPosix.cpp FuzzerIOWindows.cpp - FuzzerLoop.cpp - FuzzerMerge.cpp FuzzerMonitor.cpp - FuzzerMutate.cpp - FuzzerSHA1.cpp - FuzzerTracePC.cpp FuzzerUtil.cpp FuzzerUtilDarwin.cpp FuzzerUtilFuchsia.cpp @@ -25,31 +14,47 @@ FuzzerUtilPosix.cpp FuzzerUtilWindows.cpp) +set(LIBFUZZER_BASE_HEADERS + FuzzerDefs.h + FuzzerExtFunctions.def + FuzzerExtFunctions.h + FuzzerLock.h + FuzzerMonitor.h + FuzzerIO.h + FuzzerPlatform.h + FuzzerUtil.h) + +set(LIBFUZZER_SOURCES + FuzzerCrossOver.cpp + FuzzerDataFlowTrace.cpp + FuzzerDriver.cpp + FuzzerDSORelative.cpp + FuzzerExtraCounters.cpp + FuzzerFork.cpp + FuzzerLoop.cpp + FuzzerMerge.cpp + FuzzerMutate.cpp + FuzzerSHA1.cpp + FuzzerTracePC.cpp) + set(LIBFUZZER_HEADERS FuzzerBuiltins.h FuzzerBuiltinsMsvc.h FuzzerCommand.h FuzzerCorpus.h FuzzerDataFlowTrace.h - FuzzerDefs.h FuzzerDictionary.h FuzzerDSORelative.h - FuzzerExtFunctions.def - FuzzerExtFunctions.h FuzzerFlags.def FuzzerFork.h - FuzzerIO.h FuzzerInterface.h FuzzerInternal.h - FuzzerLock.h FuzzerMerge.h - FuzzerMonitor.h FuzzerMutate.h FuzzerOptions.h FuzzerRandom.h FuzzerSHA1.h FuzzerTracePC.h - FuzzerUtil.h FuzzerValueBitMap.h) include_directories(../../include) @@ -61,18 +66,10 @@ } " HAS_THREAD_LOCAL) -set(LIBFUZZER_CFLAGS ${COMPILER_RT_COMMON_CFLAGS}) - -if(OS_NAME MATCHES "Linux|Fuchsia" AND - COMPILER_RT_LIBCXX_PATH AND - COMPILER_RT_LIBCXXABI_PATH) - list(APPEND LIBFUZZER_CFLAGS -D_LIBCPP_ABI_VERSION=Fuzzer) - list(APPEND LIBFUZZER_CFLAGS -D_LIBCPP_ABI_VERSION=Fuzzer) - append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ LIBFUZZER_CFLAGS) -elseif(TARGET cxx-headers OR HAVE_LIBCXX) - # libFuzzer uses C++ standard library headers. - set(LIBFUZZER_DEPS cxx-headers) -endif() +set(LIBFUZZER_CFLAGS + ${COMPILER_RT_COMMON_CFLAGS} + -I${COMPILER_RT_SOURCE_DIR}/lib/fuzzer + -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) append_list_if(COMPILER_RT_HAS_OMIT_FRAME_POINTER_FLAG -fno-omit-frame-pointer LIBFUZZER_CFLAGS) @@ -91,59 +88,10 @@ endif() endif() -list(APPEND LIBFUZZER_CFLAGS -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) - -add_compiler_rt_component(fuzzer) - -add_compiler_rt_object_libraries(RTfuzzer - OS ${FUZZER_SUPPORTED_OS} - ARCHS ${FUZZER_SUPPORTED_ARCH} - SOURCES ${LIBFUZZER_SOURCES} - ADDITIONAL_HEADERS ${LIBFUZZER_HEADERS} - CFLAGS ${LIBFUZZER_CFLAGS} - DEPS ${LIBFUZZER_DEPS}) - -add_compiler_rt_object_libraries(RTfuzzer_main - OS ${FUZZER_SUPPORTED_OS} - ARCHS ${FUZZER_SUPPORTED_ARCH} - SOURCES FuzzerMain.cpp - CFLAGS ${LIBFUZZER_CFLAGS} - DEPS ${LIBFUZZER_DEPS}) - -add_compiler_rt_object_libraries(RTfuzzer_interceptors - OS ${FUZZER_SUPPORTED_OS} - ARCHS ${FUZZER_SUPPORTED_ARCH} - SOURCES FuzzerInterceptors.cpp - CFLAGS ${LIBFUZZER_CFLAGS} - DEPS ${LIBFUZZER_DEPS}) - -add_compiler_rt_runtime(clang_rt.fuzzer - STATIC - OS ${FUZZER_SUPPORTED_OS} - ARCHS ${FUZZER_SUPPORTED_ARCH} - OBJECT_LIBS RTfuzzer RTfuzzer_main - CFLAGS ${LIBFUZZER_CFLAGS} - PARENT_TARGET fuzzer) - -add_compiler_rt_runtime(clang_rt.fuzzer_no_main - STATIC - OS ${FUZZER_SUPPORTED_OS} - ARCHS ${FUZZER_SUPPORTED_ARCH} - OBJECT_LIBS RTfuzzer - CFLAGS ${LIBFUZZER_CFLAGS} - PARENT_TARGET fuzzer) - -add_compiler_rt_runtime(clang_rt.fuzzer_interceptors - STATIC - OS ${FUZZER_SUPPORTED_OS} - ARCHS ${FUZZER_SUPPORTED_ARCH} - OBJECT_LIBS RTfuzzer_interceptors - CFLAGS ${LIBFUZZER_CFLAGS} - PARENT_TARGET fuzzer) - if(OS_NAME MATCHES "Linux|Fuchsia" AND COMPILER_RT_LIBCXX_PATH AND COMPILER_RT_LIBCXXABI_PATH) + set(USE_LIBCXX_FUZZER ON) macro(partially_link_libcxx name dir arch) if(${arch} MATCHES "i386") set(EMULATION_ARGUMENT "-m" "elf_i386") @@ -152,15 +100,18 @@ endif() set(cxx_${arch}_merge_dir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${arch}_merge.dir") file(MAKE_DIRECTORY ${cxx_${arch}_merge_dir}) - add_custom_command(TARGET clang_rt.${name}-${arch} POST_BUILD - COMMAND ${CMAKE_LINKER} ${EMULATION_ARGUMENT} --whole-archive "$" --no-whole-archive ${dir}/lib/libc++.a -r -o ${name}.o + add_custom_command(TARGET ${name}-${arch} POST_BUILD + COMMAND ${CMAKE_LINKER} ${EMULATION_ARGUMENT} + --whole-archive "$" + --no-whole-archive ${dir}/lib/libc++.a -r -o ${name}.o COMMAND ${CMAKE_OBJCOPY} --localize-hidden ${name}.o - COMMAND ${CMAKE_COMMAND} -E remove "$" - COMMAND ${CMAKE_AR} qcs "$" ${name}.o - WORKING_DIRECTORY ${cxx_${arch}_merge_dir} - ) + COMMAND ${CMAKE_COMMAND} -E remove "$" + COMMAND ${CMAKE_AR} qcs "$" ${name}.o + WORKING_DIRECTORY ${cxx_${arch}_merge_dir}) endmacro() - + list(APPEND LIBFUZZER_CFLAGS -D_LIBCPP_ABI_VERSION=Fuzzer) + list(APPEND LIBFUZZER_CFLAGS -D_LIBCPP_ABI_VERSION=Fuzzer) + append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ LIBFUZZER_CFLAGS) foreach(arch ${FUZZER_SUPPORTED_ARCH}) get_target_flags_for_arch(${arch} TARGET_CFLAGS) set(LIBCXX_${arch}_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libcxx_fuzzer_${arch}) @@ -170,18 +121,82 @@ -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF -DLIBCXX_ABI_NAMESPACE=__Fuzzer) - target_compile_options(RTfuzzer.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1) - add_dependencies(RTfuzzer.${arch} libcxx_fuzzer_${arch}-build) - target_compile_options(RTfuzzer_main.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1) - add_dependencies(RTfuzzer_main.${arch} libcxx_fuzzer_${arch}-build) - target_compile_options(RTfuzzer_interceptors.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1) - add_dependencies(RTfuzzer_interceptors.${arch} libcxx_fuzzer_${arch}-build) - partially_link_libcxx(fuzzer_no_main ${LIBCXX_${arch}_PREFIX} ${arch}) - partially_link_libcxx(fuzzer_interceptors ${LIBCXX_${arch}_PREFIX} ${arch}) - partially_link_libcxx(fuzzer ${LIBCXX_${arch}_PREFIX} ${arch}) + set(LIBCXX_FUZZER_${arch}_DEPS libcxx_fuzzer_${arch}-build) + set(LIBCXX_FUZZER_${arch}_CFLAGS -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1) + set(LIBCXX_FUZZER_${arch}_LINK_FLAGS ${LIBCXX_${arch}_PREFIX}/lib/libc++.a) endforeach() +else() + set(USE_LIBCXX_FUZZER OFF) + if(TARGET cxx-headers OR HAVE_LIBCXX) + # libFuzzer uses C++ standard library headers. + set(LIBFUZZER_DEPS cxx-headers) + endif() endif() +function(add_libfuzzer_objects name) + cmake_parse_arguments(LOCAL "" "" "SOURCES;HEADERS;CFLAGS" "" ${ARGN}) + if (NOT DEFINED LOCAL_CFLAGS) + set(LOCAL_CFLAGS ${LIBFUZZER_CFLAGS}) + endif() + add_compiler_rt_object_libraries(${name} + OS ${FUZZER_SUPPORTED_OS} + ARCHS ${FUZZER_SUPPORTED_ARCH} + SOURCES ${LOCAL_SOURCES} + ADDITIONAL_HEADERS ${LOCAL_HEADERS} + CFLAGS ${LOCAL_CFLAGS} + DEPS ${LIBFUZZER_DEPS}) + if(USE_LIBCXX_FUZZER) + foreach(arch ${FUZZER_SUPPORTED_ARCH}) + target_compile_options(${name}.${arch} PRIVATE ${LIBCXX_FUZZER_${arch}_CFLAGS}) + add_dependencies(${name}.${arch} ${LIBCXX_FUZZER_${arch}_DEPS}) + endforeach() + endif() +endfunction() + +add_libfuzzer_objects(RTfuzzer_base + SOURCES ${LIBFUZZER_BASE_SOURCES} + HEADERS ${LIBFUZZER_BASE_HEADERS}) + +add_libfuzzer_objects(RTfuzzer + SOURCES ${LIBFUZZER_SOURCES} + HEADERS ${LIBFUZZER_HEADERS}) + +add_libfuzzer_objects(RTfuzzer_main + SOURCES FuzzerMain.cpp) + +add_libfuzzer_objects(RTfuzzer_interceptors + SOURCES FuzzerInterceptors.cpp) + +add_compiler_rt_component(fuzzer) + +function(add_libfuzzer_runtime name) + cmake_parse_arguments(LOCAL "" "" "OBJECT_LIBS" "" ${ARGN}) + add_compiler_rt_runtime(clang_rt.${name} + STATIC + OS ${FUZZER_SUPPORTED_OS} + ARCHS ${FUZZER_SUPPORTED_ARCH} + OBJECT_LIBS ${LOCAL_OBJECT_LIBS} + CFLAGS ${LIBFUZZER_CFLAGS} + PARENT_TARGET fuzzer) + if(USE_LIBCXX_FUZZER) + foreach(arch ${FUZZER_SUPPORTED_ARCH}) + partially_link_libcxx(clang_rt.${name} ${LIBCXX_${arch}_PREFIX} ${arch}) + endforeach() + endif() +endfunction() + +add_libfuzzer_runtime(fuzzer + OBJECT_LIBS RTfuzzer_base + RTfuzzer + RTfuzzer_main) + +add_libfuzzer_runtime(fuzzer_no_main + OBJECT_LIBS RTfuzzer_base + RTfuzzer) + +add_libfuzzer_runtime(fuzzer_interceptors + OBJECT_LIBS RTfuzzer_interceptors) + if(COMPILER_RT_INCLUDE_TESTS) add_subdirectory(tests) endif() Index: compiler-rt/lib/fuzzer/build.sh =================================================================== --- compiler-rt/lib/fuzzer/build.sh +++ compiler-rt/lib/fuzzer/build.sh @@ -1,11 +1,53 @@ #!/bin/sh + +set -euo pipefail + LIBFUZZER_SRC_DIR=$(dirname $0) + +DEFAULT_CFLAGS="-g" +DEFAULT_CFLAGS+=" -O2" +DEFAULT_CFLAGS+=" -fno-omit-frame-pointer" +DEFAULT_CFLAGS+=" -std=c++11" +DEFAULT_CFLAGS+=" -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS" +DEFAULT_CFLAGS+=" -I${LIBFUZZER_SRC_DIR}" + CXX="${CXX:-clang}" +CFLAGS="${CFLAGS:-${DEFAULT_CFLAGS}}" + for f in $LIBFUZZER_SRC_DIR/*.cpp; do - $CXX -g -O2 -fno-omit-frame-pointer -std=c++11 $f -c & + $CXX $CFLAGS $f -c & done + wait + rm -f libFuzzer.a -ar ru libFuzzer.a Fuzzer*.o -rm -f Fuzzer*.o +ar r libFuzzer.a \ + FuzzerDeprecated.o \ + FuzzerExtFunctionsDlsym.o \ + FuzzerExtFunctionsWeak.o \ + FuzzerExtFunctionsWindows.o \ + FuzzerIO.o \ + FuzzerIOPosix.o \ + FuzzerIOWindows.o \ + FuzzerMonitor.o \ + FuzzerUtil.o \ + FuzzerUtilDarwin.o \ + FuzzerUtilFuchsia.o \ + FuzzerUtilLinux.o \ + FuzzerUtilPosix.o \ + FuzzerUtilWindows.o \ + FuzzerCrossOver.o \ + FuzzerDataFlowTrace.o \ + FuzzerDriver.o \ + FuzzerDSORelative.o \ + FuzzerExtraCounters.o \ + FuzzerFork.o \ + FuzzerLoop.o \ + FuzzerMain.o \ + FuzzerMerge.o \ + FuzzerMonitor.o \ + FuzzerMutate.o \ + FuzzerSHA1.o \ + FuzzerTracePC.o +rm -f Fuzzer*.o Index: compiler-rt/lib/fuzzer/tests/CMakeLists.txt =================================================================== --- compiler-rt/lib/fuzzer/tests/CMakeLists.txt +++ compiler-rt/lib/fuzzer/tests/CMakeLists.txt @@ -11,12 +11,6 @@ set(FUZZER_SUPPORTED_OS osx) endif() -add_custom_target(FuzzerUnitTests) -set_target_properties(FuzzerUnitTests PROPERTIES FOLDER "Compiler-RT Tests") - -add_custom_target(FuzzedDataProviderUnitTests) -set_target_properties(FuzzedDataProviderUnitTests PROPERTIES FOLDER "Compiler-RT Tests") - set(LIBFUZZER_UNITTEST_LINK_FLAGS ${COMPILER_RT_UNITTEST_LINK_FLAGS}) list(APPEND LIBFUZZER_UNITTEST_LINK_FLAGS --driver-mode=g++) @@ -41,51 +35,66 @@ list(APPEND LIBFUZZER_UNITTEST_CFLAGS "-fvisibility=hidden") endif() -if(COMPILER_RT_DEFAULT_TARGET_ARCH IN_LIST FUZZER_SUPPORTED_ARCH) - # libFuzzer unit tests are only run on the host machine. - set(arch ${COMPILER_RT_DEFAULT_TARGET_ARCH}) - - set(LIBFUZZER_TEST_RUNTIME RTFuzzerTest.${arch}) +# Compile and register compiler-rt/lib/fuzzer unit tests. +# Like generate_libfuzzer_test_executable above, but can derive most names from +# a single prefix string if not explicitly provided. +# generate_libfuzzer_unittests( +# SUITE +# NAME +# SOURCES +# RUNTIME +# DEPS +# ) +function(generate_libfuzzer_unittests test_suite arch) + cmake_parse_arguments(TEST "" "SUITE;NAME;RUNTIME" + "SOURCES;OBJECTS;OBJECT_LIBS;DEPS" ${ARGN}) + string(REPLACE "UnitTests" "" TEST_PREFIX ${test_suite}) + if (NOT DEFINED TEST_NAME) + set(TEST_NAME ${TEST_PREFIX}-${arch}-Test) + endif() + list(APPEND TEST_SOURCES ${COMPILER_RT_GTEST_SOURCE}) + set(suffix) if(APPLE) - set(LIBFUZZER_TEST_RUNTIME_OBJECTS - $) + set(suffix ${FUZZER_SUPPORTED_OS}) else() - set(LIBFUZZER_TEST_RUNTIME_OBJECTS - $) + set(suffix ${arch}) + endif() + if (NOT DEFINED TEST_RUNTIME) + set(TEST_RUNTIME RT${TEST_PREFIX}Test) + foreach(object_lib ${TEST_OBJECT_LIBS}) + list(APPEND TEST_OBJECTS $) + endforeach() + add_library(${TEST_RUNTIME}.${arch} STATIC ${TEST_OBJECTS}) + set_target_properties(${TEST_RUNTIME}.${arch} PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + FOLDER "Compiler-RT Runtime tests") endif() - add_library(${LIBFUZZER_TEST_RUNTIME} STATIC - ${LIBFUZZER_TEST_RUNTIME_OBJECTS}) - set_target_properties(${LIBFUZZER_TEST_RUNTIME} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + add_custom_target(${test_suite}) + set(${test_suite}_objects) + generate_compiler_rt_tests(${test_suite}_objects ${test_suite} ${TEST_NAME} ${arch} + SOURCES ${TEST_SOURCES} + RUNTIME ${TEST_RUNTIME}.${arch} + DEPS gtest ${TEST_DEPS} ${LIBCXX_FUZZER_${arch}_DEPS} + CFLAGS ${LIBFUZZER_UNITTEST_CFLAGS} ${LIBCXX_FUZZER_${arch}_CFLAGS} + LINK_FLAGS ${LIBFUZZER_UNITTEST_LINK_FLAGS} ${LIBCXX_FUZZER_${arch}_LINK_FLAGS}) + set_target_properties(${test_suite} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} FOLDER "Compiler-RT Runtime tests") +endfunction() - if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND - COMPILER_RT_LIBCXX_PATH AND - COMPILER_RT_LIBCXXABI_PATH) - file(GLOB libfuzzer_headers ../*.h) - set(LIBFUZZER_TEST_RUNTIME_DEPS libcxx_fuzzer_${arch}-build ${libfuzzer_headers}) - set(LIBFUZZER_TEST_RUNTIME_CFLAGS -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1) - set(LIBFUZZER_TEST_RUNTIME_LINK_FLAGS ${LIBCXX_${arch}_PREFIX}/lib/libc++.a) - endif() +if(COMPILER_RT_DEFAULT_TARGET_ARCH IN_LIST FUZZER_SUPPORTED_ARCH) + # libFuzzer unit tests are only run on the host machine. + set(arch ${COMPILER_RT_DEFAULT_TARGET_ARCH}) - set(FuzzerTestObjects) - generate_compiler_rt_tests(FuzzerTestObjects - FuzzerUnitTests "Fuzzer-${arch}-Test" ${arch} - SOURCES FuzzerUnittest.cpp ${COMPILER_RT_GTEST_SOURCE} - RUNTIME ${LIBFUZZER_TEST_RUNTIME} - DEPS gtest ${LIBFUZZER_TEST_RUNTIME_DEPS} FuzzerTestUtil.h - CFLAGS ${LIBFUZZER_UNITTEST_CFLAGS} ${LIBFUZZER_TEST_RUNTIME_CFLAGS} - LINK_FLAGS ${LIBFUZZER_UNITTEST_LINK_FLAGS} ${LIBFUZZER_TEST_RUNTIME_LINK_FLAGS}) - set_target_properties(FuzzerUnitTests PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + generate_libfuzzer_unittests(FuzzerUnitTests ${arch} + SOURCES FuzzerUnittest.cpp + OBJECT_LIBS RTfuzzer_base + RTfuzzer) - set(FuzzedDataProviderTestObjects) - generate_compiler_rt_tests(FuzzedDataProviderTestObjects - FuzzedDataProviderUnitTests "FuzzerUtils-${arch}-Test" ${arch} - SOURCES FuzzedDataProviderUnittest.cpp ${COMPILER_RT_GTEST_SOURCE} - DEPS gtest ${LIBFUZZER_TEST_RUNTIME_DEPS} ${COMPILER_RT_SOURCE_DIR}/include/fuzzer/FuzzedDataProvider.h - CFLAGS ${LIBFUZZER_UNITTEST_CFLAGS} ${LIBFUZZER_TEST_RUNTIME_CFLAGS} - LINK_FLAGS ${LIBFUZZER_UNITTEST_LINK_FLAGS} ${LIBFUZZER_TEST_RUNTIME_LINK_FLAGS}) - set_target_properties(FuzzedDataProviderUnitTests PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + generate_libfuzzer_unittests(FuzzedDataProviderUnitTests ${arch} + NAME FuzzerUtils-${arch}-Test + SOURCES FuzzedDataProviderUnittest.cpp + OBJECT_LIBS RTfuzzer_base + RTfuzzer + DEPS ${COMPILER_RT_SOURCE_DIR}/include/fuzzer/FuzzedDataProvider.h) endif()