1set(LIBFUZZER_SOURCES
2  FuzzerCrossOver.cpp
3  FuzzerDataFlowTrace.cpp
4  FuzzerDriver.cpp
5  FuzzerExtFunctionsDlsym.cpp
6  FuzzerExtFunctionsWeak.cpp
7  FuzzerExtFunctionsWindows.cpp
8  FuzzerExtraCounters.cpp
9  FuzzerExtraCountersDarwin.cpp
10  FuzzerExtraCountersWindows.cpp
11  FuzzerFork.cpp
12  FuzzerIO.cpp
13  FuzzerIOPosix.cpp
14  FuzzerIOWindows.cpp
15  FuzzerLoop.cpp
16  FuzzerMerge.cpp
17  FuzzerMutate.cpp
18  FuzzerSHA1.cpp
19  FuzzerTracePC.cpp
20  FuzzerUtil.cpp
21  FuzzerUtilDarwin.cpp
22  FuzzerUtilFuchsia.cpp
23  FuzzerUtilLinux.cpp
24  FuzzerUtilPosix.cpp
25  FuzzerUtilWindows.cpp)
26
27set(LIBFUZZER_HEADERS
28  FuzzerBuiltins.h
29  FuzzerBuiltinsMsvc.h
30  FuzzerCommand.h
31  FuzzerCorpus.h
32  FuzzerDataFlowTrace.h
33  FuzzerDefs.h
34  FuzzerDictionary.h
35  FuzzerExtFunctions.def
36  FuzzerExtFunctions.h
37  FuzzerFlags.def
38  FuzzerFork.h
39  FuzzerIO.h
40  FuzzerInterface.h
41  FuzzerInternal.h
42  FuzzerMerge.h
43  FuzzerMutate.h
44  FuzzerOptions.h
45  FuzzerRandom.h
46  FuzzerSHA1.h
47  FuzzerTracePC.h
48  FuzzerUtil.h
49  FuzzerValueBitMap.h)
50
51include_directories(../../include)
52
53CHECK_CXX_SOURCE_COMPILES("
54  static thread_local int blah;
55  int main() {
56  return 0;
57  }
58  " HAS_THREAD_LOCAL)
59
60set(LIBFUZZER_CFLAGS ${COMPILER_RT_COMMON_CFLAGS})
61
62if(OS_NAME MATCHES "Linux|Fuchsia" AND
63   COMPILER_RT_LIBCXX_PATH AND
64   COMPILER_RT_LIBCXXABI_PATH)
65  list(APPEND LIBFUZZER_CFLAGS -D_LIBCPP_ABI_VERSION=Fuzzer)
66  append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ LIBFUZZER_CFLAGS)
67elseif(TARGET cxx-headers OR HAVE_LIBCXX)
68  # libFuzzer uses C++ standard library headers.
69  list(APPEND LIBFUZZER_CFLAGS ${COMPILER_RT_CXX_CFLAGS})
70  set(LIBFUZZER_DEPS cxx-headers)
71endif()
72
73append_list_if(COMPILER_RT_HAS_OMIT_FRAME_POINTER_FLAG -fno-omit-frame-pointer LIBFUZZER_CFLAGS)
74
75if (CMAKE_CXX_FLAGS MATCHES "fsanitize-coverage")
76  list(APPEND LIBFUZZER_CFLAGS -fsanitize-coverage=0)
77endif()
78
79if(MSVC)
80  # Silence warnings by turning off exceptions in MSVC headers and avoid an
81  # error by unnecessarily defining thread_local when it isn't even used on
82  # Windows.
83  list(APPEND LIBFUZZER_CFLAGS -D_HAS_EXCEPTIONS=0)
84else()
85  if(NOT HAS_THREAD_LOCAL)
86    list(APPEND LIBFUZZER_CFLAGS -Dthread_local=__thread)
87  endif()
88endif()
89
90add_compiler_rt_component(fuzzer)
91
92add_compiler_rt_object_libraries(RTfuzzer
93  OS ${FUZZER_SUPPORTED_OS}
94  ARCHS ${FUZZER_SUPPORTED_ARCH}
95  SOURCES ${LIBFUZZER_SOURCES}
96  ADDITIONAL_HEADERS ${LIBFUZZER_HEADERS}
97  CFLAGS ${LIBFUZZER_CFLAGS}
98  DEPS ${LIBFUZZER_DEPS})
99
100add_compiler_rt_object_libraries(RTfuzzer_main
101  OS ${FUZZER_SUPPORTED_OS}
102  ARCHS ${FUZZER_SUPPORTED_ARCH}
103  SOURCES FuzzerMain.cpp
104  CFLAGS ${LIBFUZZER_CFLAGS}
105  DEPS ${LIBFUZZER_DEPS})
106
107add_compiler_rt_object_libraries(RTfuzzer_interceptors
108  OS ${FUZZER_SUPPORTED_OS}
109  ARCHS ${FUZZER_SUPPORTED_ARCH}
110  SOURCES FuzzerInterceptors.cpp
111  CFLAGS ${LIBFUZZER_CFLAGS}
112  DEPS ${LIBFUZZER_DEPS})
113
114add_compiler_rt_runtime(clang_rt.fuzzer
115  STATIC
116  OS ${FUZZER_SUPPORTED_OS}
117  ARCHS ${FUZZER_SUPPORTED_ARCH}
118  OBJECT_LIBS RTfuzzer RTfuzzer_main
119  CFLAGS ${LIBFUZZER_CFLAGS}
120  PARENT_TARGET fuzzer)
121
122add_compiler_rt_runtime(clang_rt.fuzzer_no_main
123  STATIC
124  OS ${FUZZER_SUPPORTED_OS}
125  ARCHS ${FUZZER_SUPPORTED_ARCH}
126  OBJECT_LIBS RTfuzzer
127  CFLAGS ${LIBFUZZER_CFLAGS}
128  PARENT_TARGET fuzzer)
129
130add_compiler_rt_runtime(clang_rt.fuzzer_interceptors
131  STATIC
132  OS ${FUZZER_SUPPORTED_OS}
133  ARCHS ${FUZZER_SUPPORTED_ARCH}
134  OBJECT_LIBS RTfuzzer_interceptors
135  CFLAGS ${LIBFUZZER_CFLAGS}
136  PARENT_TARGET fuzzer)
137
138if(OS_NAME MATCHES "Linux|Fuchsia" AND
139   COMPILER_RT_LIBCXX_PATH AND
140   COMPILER_RT_LIBCXXABI_PATH)
141  macro(partially_link_libcxx name dir arch)
142    get_target_flags_for_arch(${arch} target_cflags)
143    if(CMAKE_CXX_COMPILER_ID MATCHES Clang)
144      get_compiler_rt_target(${arch} target)
145      set(target_cflags --target=${target} ${target_cflags})
146    endif()
147    set(cxx_${arch}_merge_dir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${arch}_merge.dir")
148    file(MAKE_DIRECTORY ${cxx_${arch}_merge_dir})
149    add_custom_command(TARGET clang_rt.${name}-${arch} POST_BUILD
150      COMMAND ${CMAKE_CXX_COMPILER} ${target_cflags} -Wl,--whole-archive "$<TARGET_LINKER_FILE:clang_rt.${name}-${arch}>" -Wl,--no-whole-archive ${dir}/lib/libc++.a -r -o ${name}.o
151      COMMAND ${CMAKE_OBJCOPY} --localize-hidden ${name}.o
152      COMMAND ${CMAKE_COMMAND} -E remove "$<TARGET_LINKER_FILE:clang_rt.${name}-${arch}>"
153      COMMAND ${CMAKE_AR} qcs "$<TARGET_LINKER_FILE:clang_rt.${name}-${arch}>" ${name}.o
154      WORKING_DIRECTORY ${cxx_${arch}_merge_dir}
155    )
156  endmacro()
157
158  foreach(arch ${FUZZER_SUPPORTED_ARCH})
159    get_target_flags_for_arch(${arch} TARGET_CFLAGS)
160    set(LIBCXX_${arch}_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libcxx_fuzzer_${arch})
161    add_custom_libcxx(libcxx_fuzzer_${arch} ${LIBCXX_${arch}_PREFIX}
162      CFLAGS ${TARGET_CFLAGS}
163      CMAKE_ARGS -DCMAKE_CXX_COMPILER_WORKS=ON
164                 -DCMAKE_POSITION_INDEPENDENT_CODE=ON
165                 -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF
166                 -DLIBCXX_ABI_NAMESPACE=__Fuzzer
167                 -DLIBCXX_ENABLE_EXCEPTIONS=OFF)
168    target_compile_options(RTfuzzer.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)
169    add_dependencies(RTfuzzer.${arch} libcxx_fuzzer_${arch}-build)
170    target_compile_options(RTfuzzer_main.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)
171    add_dependencies(RTfuzzer_main.${arch} libcxx_fuzzer_${arch}-build)
172    target_compile_options(RTfuzzer_interceptors.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)
173    add_dependencies(RTfuzzer_interceptors.${arch} libcxx_fuzzer_${arch}-build)
174    partially_link_libcxx(fuzzer_no_main ${LIBCXX_${arch}_PREFIX} ${arch})
175    partially_link_libcxx(fuzzer_interceptors ${LIBCXX_${arch}_PREFIX} ${arch})
176    partially_link_libcxx(fuzzer ${LIBCXX_${arch}_PREFIX} ${arch})
177  endforeach()
178endif()
179
180if(COMPILER_RT_INCLUDE_TESTS)
181  add_subdirectory(tests)
182endif()
183