Skip to content

Commit 0a4b496

Browse files
authored
Merge pull request #93 from rchildre3/feature/update-libfuzzer-15-deps
Update libFuzzer to compiler-rt 15 and Rust deps
2 parents 413820e + 03a00b2 commit 0a4b496

39 files changed

+935
-372
lines changed

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,14 @@ Released YYYY-MM-DD.
88

99
### Changed
1010

11-
* TODO (or remove section if none)
11+
* Updated to `libFuzzer` commit `df90d22` (`release/15.x`).
12+
* LLVM 16's [upcoming change][llvm_cxx17] to build requirements to C++17
13+
necessitate reflecting those changes. (`libFuzzer` updates contain C++14 code)
14+
* Drastically reduce build times by using parallel C++ compilation jobs
15+
* Updated `rand` dependency from 0.8.3 to 0.8.5
16+
* Updated `flate2` dependency from 1.0.20 to 1.0.24
17+
18+
[llvm_cxx17]: https://llvm.org/docs/ReleaseNotes.html#update-on-required-toolchains-to-build-llvm
1219

1320
### Deprecated
1421

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ arbitrary = "1"
1313
once_cell = "1"
1414

1515
[build-dependencies]
16-
cc = "1.0"
16+
cc = { version = "1.0", features = ["parallel"] }
1717

1818
[features]
1919
arbitrary-derive = ["arbitrary/derive"]
@@ -26,5 +26,5 @@ members = [
2626
]
2727

2828
[dev-dependencies]
29-
flate2 = "1.0.20"
30-
rand = "0.8.3"
29+
flate2 = "1.0.24"
30+
rand = "0.8.5"

build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn main() {
2626
println!("cargo:rerun-if-changed={}", source.display());
2727
build.file(source.to_str().unwrap());
2828
}
29-
build.flag("-std=c++11");
29+
build.flag("-std=c++17");
3030
build.flag("-fno-omit-frame-pointer");
3131
build.flag("-w");
3232
build.cpp(true);

example_mutator/fuzz/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ edition = "2018"
88
cargo-fuzz = true
99

1010
[dependencies]
11-
flate2 = "1.0.20"
11+
flate2 = "1.0.24"
1212
libfuzzer-sys = { path = "../.." }
1313

1414
[[bin]]

libfuzzer/CMakeLists.txt

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ set(LIBFUZZER_SOURCES
66
FuzzerExtFunctionsWeak.cpp
77
FuzzerExtFunctionsWindows.cpp
88
FuzzerExtraCounters.cpp
9+
FuzzerExtraCountersDarwin.cpp
10+
FuzzerExtraCountersWindows.cpp
911
FuzzerFork.cpp
1012
FuzzerIO.cpp
1113
FuzzerIOPosix.cpp
@@ -64,18 +66,19 @@ if(OS_NAME MATCHES "Linux|Fuchsia" AND
6466
append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ LIBFUZZER_CFLAGS)
6567
elseif(TARGET cxx-headers OR HAVE_LIBCXX)
6668
# libFuzzer uses C++ standard library headers.
69+
list(APPEND LIBFUZZER_CFLAGS ${COMPILER_RT_CXX_CFLAGS})
6770
set(LIBFUZZER_DEPS cxx-headers)
6871
endif()
6972

7073
append_list_if(COMPILER_RT_HAS_OMIT_FRAME_POINTER_FLAG -fno-omit-frame-pointer LIBFUZZER_CFLAGS)
7174

7275
if (CMAKE_CXX_FLAGS MATCHES "fsanitize-coverage")
73-
list(APPEND LIBFUZZER_CFLAGS -fno-sanitize-coverage=trace-pc-guard,edge,trace-cmp,indirect-calls,8bit-counters)
76+
list(APPEND LIBFUZZER_CFLAGS -fsanitize-coverage=0)
7477
endif()
7578

7679
if(MSVC)
7780
# Silence warnings by turning off exceptions in MSVC headers and avoid an
78-
# error by unecessarily defining thread_local when it isn't even used on
81+
# error by unnecessarily defining thread_local when it isn't even used on
7982
# Windows.
8083
list(APPEND LIBFUZZER_CFLAGS -D_HAS_EXCEPTIONS=0)
8184
else()
@@ -136,15 +139,15 @@ if(OS_NAME MATCHES "Linux|Fuchsia" AND
136139
COMPILER_RT_LIBCXX_PATH AND
137140
COMPILER_RT_LIBCXXABI_PATH)
138141
macro(partially_link_libcxx name dir arch)
139-
if(${arch} MATCHES "i386")
140-
set(EMULATION_ARGUMENT "-m" "elf_i386")
141-
else()
142-
set(EMULATION_ARGUMENT "")
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})
143146
endif()
144147
set(cxx_${arch}_merge_dir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${arch}_merge.dir")
145148
file(MAKE_DIRECTORY ${cxx_${arch}_merge_dir})
146149
add_custom_command(TARGET clang_rt.${name}-${arch} POST_BUILD
147-
COMMAND ${CMAKE_LINKER} ${EMULATION_ARGUMENT} --whole-archive "$<TARGET_LINKER_FILE:clang_rt.${name}-${arch}>" --no-whole-archive ${dir}/lib/libc++.a -r -o ${name}.o
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
148151
COMMAND ${CMAKE_OBJCOPY} --localize-hidden ${name}.o
149152
COMMAND ${CMAKE_COMMAND} -E remove "$<TARGET_LINKER_FILE:clang_rt.${name}-${arch}>"
150153
COMMAND ${CMAKE_AR} qcs "$<TARGET_LINKER_FILE:clang_rt.${name}-${arch}>" ${name}.o
@@ -160,7 +163,8 @@ if(OS_NAME MATCHES "Linux|Fuchsia" AND
160163
CMAKE_ARGS -DCMAKE_CXX_COMPILER_WORKS=ON
161164
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
162165
-DLIBCXXABI_ENABLE_EXCEPTIONS=OFF
163-
-DLIBCXX_ABI_NAMESPACE=__Fuzzer)
166+
-DLIBCXX_ABI_NAMESPACE=__Fuzzer
167+
-DLIBCXX_ENABLE_EXCEPTIONS=OFF)
164168
target_compile_options(RTfuzzer.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)
165169
add_dependencies(RTfuzzer.${arch} libcxx_fuzzer_${arch}-build)
166170
target_compile_options(RTfuzzer_main.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)

libfuzzer/FuzzerBuiltinsMsvc.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ inline uint32_t Clzll(uint64_t X) {
4141
#if !defined(_M_ARM) && !defined(_M_X64)
4242
// Scan the high 32 bits.
4343
if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X >> 32)))
44-
return static_cast<int>(63 - (LeadZeroIdx + 32)); // Create a bit offset from the MSB.
44+
return static_cast<int>(
45+
63 - (LeadZeroIdx + 32)); // Create a bit offset from the MSB.
4546
// Scan the low 32 bits.
4647
if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X)))
4748
return static_cast<int>(63 - LeadZeroIdx);

libfuzzer/FuzzerCommand.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class Command final {
3333

3434
Command() : CombinedOutAndErr(false) {}
3535

36-
explicit Command(const Vector<std::string> &ArgsToAdd)
36+
explicit Command(const std::vector<std::string> &ArgsToAdd)
3737
: Args(ArgsToAdd), CombinedOutAndErr(false) {}
3838

3939
explicit Command(const Command &Other)
@@ -58,7 +58,7 @@ class Command final {
5858

5959
// Gets all of the current command line arguments, **including** those after
6060
// "-ignore-remaining-args=1".
61-
const Vector<std::string> &getArguments() const { return Args; }
61+
const std::vector<std::string> &getArguments() const { return Args; }
6262

6363
// Adds the given argument before "-ignore_remaining_args=1", or at the end
6464
// if that flag isn't present.
@@ -68,7 +68,7 @@ class Command final {
6868

6969
// Adds all given arguments before "-ignore_remaining_args=1", or at the end
7070
// if that flag isn't present.
71-
void addArguments(const Vector<std::string> &ArgsToAdd) {
71+
void addArguments(const std::vector<std::string> &ArgsToAdd) {
7272
Args.insert(endMutableArgs(), ArgsToAdd.begin(), ArgsToAdd.end());
7373
}
7474

@@ -155,16 +155,16 @@ class Command final {
155155
Command(Command &&Other) = delete;
156156
Command &operator=(Command &&Other) = delete;
157157

158-
Vector<std::string>::iterator endMutableArgs() {
158+
std::vector<std::string>::iterator endMutableArgs() {
159159
return std::find(Args.begin(), Args.end(), ignoreRemainingArgs());
160160
}
161161

162-
Vector<std::string>::const_iterator endMutableArgs() const {
162+
std::vector<std::string>::const_iterator endMutableArgs() const {
163163
return std::find(Args.begin(), Args.end(), ignoreRemainingArgs());
164164
}
165165

166166
// The command arguments. Args[0] is the command name.
167-
Vector<std::string> Args;
167+
std::vector<std::string> Args;
168168

169169
// True indicates stderr is redirected to stdout.
170170
bool CombinedOutAndErr;

libfuzzer/FuzzerCorpus.h

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ struct InputInfo {
3939
bool MayDeleteFile = false;
4040
bool Reduced = false;
4141
bool HasFocusFunction = false;
42-
Vector<uint32_t> UniqFeatureSet;
43-
Vector<uint8_t> DataFlowTraceForFocusFunction;
42+
std::vector<uint32_t> UniqFeatureSet;
43+
std::vector<uint8_t> DataFlowTraceForFocusFunction;
4444
// Power schedule.
4545
bool NeedsEnergyUpdate = false;
4646
double Energy = 0.0;
4747
double SumIncidence = 0.0;
48-
Vector<std::pair<uint32_t, uint16_t>> FeatureFreqs;
48+
std::vector<std::pair<uint32_t, uint16_t>> FeatureFreqs;
4949

5050
// Delete feature Idx and its frequency from FeatureFreqs.
5151
bool DeleteFeatureFreq(uint32_t Idx) {
@@ -209,7 +209,7 @@ class InputCorpus {
209209
InputInfo *AddToCorpus(const Unit &U, size_t NumFeatures, bool MayDeleteFile,
210210
bool HasFocusFunction, bool NeverReduce,
211211
std::chrono::microseconds TimeOfUnit,
212-
const Vector<uint32_t> &FeatureSet,
212+
const std::vector<uint32_t> &FeatureSet,
213213
const DataFlowTrace &DFT, const InputInfo *BaseII) {
214214
assert(!U.empty());
215215
if (FeatureDebug)
@@ -258,7 +258,7 @@ class InputCorpus {
258258
}
259259

260260
// Debug-only
261-
void PrintFeatureSet(const Vector<uint32_t> &FeatureSet) {
261+
void PrintFeatureSet(const std::vector<uint32_t> &FeatureSet) {
262262
if (!FeatureDebug) return;
263263
Printf("{");
264264
for (uint32_t Feature: FeatureSet)
@@ -284,14 +284,16 @@ class InputCorpus {
284284
}
285285
}
286286

287-
void Replace(InputInfo *II, const Unit &U) {
287+
void Replace(InputInfo *II, const Unit &U,
288+
std::chrono::microseconds TimeOfUnit) {
288289
assert(II->U.size() > U.size());
289290
Hashes.erase(Sha1ToString(II->Sha1));
290291
DeleteFile(*II);
291292
ComputeSHA1(U.data(), U.size(), II->Sha1);
292293
Hashes.insert(Sha1ToString(II->Sha1));
293294
II->U = U;
294295
II->Reduced = true;
296+
II->TimeOfUnit = TimeOfUnit;
295297
DistributionNeedsUpdate = true;
296298
}
297299

@@ -325,7 +327,8 @@ class InputCorpus {
325327
const auto &II = *Inputs[i];
326328
Printf(" [% 3zd %s] sz: % 5zd runs: % 5zd succ: % 5zd focus: %d\n", i,
327329
Sha1ToString(II.Sha1).c_str(), II.U.size(),
328-
II.NumExecutedMutations, II.NumSuccessfullMutations, II.HasFocusFunction);
330+
II.NumExecutedMutations, II.NumSuccessfullMutations,
331+
II.HasFocusFunction);
329332
}
330333
}
331334

@@ -563,11 +566,11 @@ class InputCorpus {
563566
}
564567
std::piecewise_constant_distribution<double> CorpusDistribution;
565568

566-
Vector<double> Intervals;
567-
Vector<double> Weights;
569+
std::vector<double> Intervals;
570+
std::vector<double> Weights;
568571

569572
std::unordered_set<std::string> Hashes;
570-
Vector<InputInfo*> Inputs;
573+
std::vector<InputInfo *> Inputs;
571574

572575
size_t NumAddedFeatures = 0;
573576
size_t NumUpdatedFeatures = 0;
@@ -577,7 +580,7 @@ class InputCorpus {
577580
bool DistributionNeedsUpdate = true;
578581
uint16_t FreqOfMostAbundantRareFeature = 0;
579582
uint16_t GlobalFeatureFreqs[kFeatureSetSize] = {};
580-
Vector<uint32_t> RareFeatures;
583+
std::vector<uint32_t> RareFeatures;
581584

582585
std::string OutputCorpus;
583586
};

libfuzzer/FuzzerDataFlowTrace.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ bool BlockCoverage::AppendCoverage(const std::string &S) {
3737
// Coverage lines have this form:
3838
// CN X Y Z T
3939
// where N is the number of the function, T is the total number of instrumented
40-
// BBs, and X,Y,Z, if present, are the indecies of covered BB.
40+
// BBs, and X,Y,Z, if present, are the indices of covered BB.
4141
// BB #0, which is the entry block, is not explicitly listed.
4242
bool BlockCoverage::AppendCoverage(std::istream &IN) {
4343
std::string L;
@@ -52,7 +52,7 @@ bool BlockCoverage::AppendCoverage(std::istream &IN) {
5252
continue;
5353
}
5454
if (L[0] != 'C') continue;
55-
Vector<uint32_t> CoveredBlocks;
55+
std::vector<uint32_t> CoveredBlocks;
5656
while (true) {
5757
uint32_t BB = 0;
5858
SS >> BB;
@@ -68,7 +68,7 @@ bool BlockCoverage::AppendCoverage(std::istream &IN) {
6868
auto It = Functions.find(FunctionId);
6969
auto &Counters =
7070
It == Functions.end()
71-
? Functions.insert({FunctionId, Vector<uint32_t>(NumBlocks)})
71+
? Functions.insert({FunctionId, std::vector<uint32_t>(NumBlocks)})
7272
.first->second
7373
: It->second;
7474

@@ -86,8 +86,8 @@ bool BlockCoverage::AppendCoverage(std::istream &IN) {
8686
// * any uncovered function gets weight 0.
8787
// * a function with lots of uncovered blocks gets bigger weight.
8888
// * a function with a less frequently executed code gets bigger weight.
89-
Vector<double> BlockCoverage::FunctionWeights(size_t NumFunctions) const {
90-
Vector<double> Res(NumFunctions);
89+
std::vector<double> BlockCoverage::FunctionWeights(size_t NumFunctions) const {
90+
std::vector<double> Res(NumFunctions);
9191
for (auto It : Functions) {
9292
auto FunctionID = It.first;
9393
auto Counters = It.second;
@@ -104,7 +104,7 @@ Vector<double> BlockCoverage::FunctionWeights(size_t NumFunctions) const {
104104
}
105105

106106
void DataFlowTrace::ReadCoverage(const std::string &DirPath) {
107-
Vector<SizedFile> Files;
107+
std::vector<SizedFile> Files;
108108
GetSizedFilesFromDir(DirPath, &Files);
109109
for (auto &SF : Files) {
110110
auto Name = Basename(SF.File);
@@ -115,16 +115,16 @@ void DataFlowTrace::ReadCoverage(const std::string &DirPath) {
115115
}
116116
}
117117

118-
static void DFTStringAppendToVector(Vector<uint8_t> *DFT,
118+
static void DFTStringAppendToVector(std::vector<uint8_t> *DFT,
119119
const std::string &DFTString) {
120120
assert(DFT->size() == DFTString.size());
121121
for (size_t I = 0, Len = DFT->size(); I < Len; I++)
122122
(*DFT)[I] = DFTString[I] == '1';
123123
}
124124

125-
// converts a string of '0' and '1' into a Vector<uint8_t>
126-
static Vector<uint8_t> DFTStringToVector(const std::string &DFTString) {
127-
Vector<uint8_t> DFT(DFTString.size());
125+
// converts a string of '0' and '1' into a std::vector<uint8_t>
126+
static std::vector<uint8_t> DFTStringToVector(const std::string &DFTString) {
127+
std::vector<uint8_t> DFT(DFTString.size());
128128
DFTStringAppendToVector(&DFT, DFTString);
129129
return DFT;
130130
}
@@ -159,14 +159,14 @@ static bool ParseDFTLine(const std::string &Line, size_t *FunctionNum,
159159
}
160160

161161
bool DataFlowTrace::Init(const std::string &DirPath, std::string *FocusFunction,
162-
Vector<SizedFile> &CorporaFiles, Random &Rand) {
162+
std::vector<SizedFile> &CorporaFiles, Random &Rand) {
163163
if (DirPath.empty()) return false;
164164
Printf("INFO: DataFlowTrace: reading from '%s'\n", DirPath.c_str());
165-
Vector<SizedFile> Files;
165+
std::vector<SizedFile> Files;
166166
GetSizedFilesFromDir(DirPath, &Files);
167167
std::string L;
168168
size_t FocusFuncIdx = SIZE_MAX;
169-
Vector<std::string> FunctionNames;
169+
std::vector<std::string> FunctionNames;
170170

171171
// Collect the hashes of the corpus files.
172172
for (auto &SF : CorporaFiles)
@@ -191,7 +191,7 @@ bool DataFlowTrace::Init(const std::string &DirPath, std::string *FocusFunction,
191191
// * chooses a random function according to the weights.
192192
ReadCoverage(DirPath);
193193
auto Weights = Coverage.FunctionWeights(NumFunctions);
194-
Vector<double> Intervals(NumFunctions + 1);
194+
std::vector<double> Intervals(NumFunctions + 1);
195195
std::iota(Intervals.begin(), Intervals.end(), 0);
196196
auto Distribution = std::piecewise_constant_distribution<double>(
197197
Intervals.begin(), Intervals.end(), Weights.begin());
@@ -247,7 +247,7 @@ bool DataFlowTrace::Init(const std::string &DirPath, std::string *FocusFunction,
247247
}
248248

249249
int CollectDataFlow(const std::string &DFTBinary, const std::string &DirPath,
250-
const Vector<SizedFile> &CorporaFiles) {
250+
const std::vector<SizedFile> &CorporaFiles) {
251251
Printf("INFO: collecting data flow: bin: %s dir: %s files: %zd\n",
252252
DFTBinary.c_str(), DirPath.c_str(), CorporaFiles.size());
253253
if (CorporaFiles.empty()) {
@@ -265,7 +265,7 @@ int CollectDataFlow(const std::string &DFTBinary, const std::string &DirPath,
265265
// we then request tags in [0,Size/2) and [Size/2, Size), and so on.
266266
// Function number => DFT.
267267
auto OutPath = DirPlusFile(DirPath, Hash(FileToVector(F.File)));
268-
std::unordered_map<size_t, Vector<uint8_t>> DFTMap;
268+
std::unordered_map<size_t, std::vector<uint8_t>> DFTMap;
269269
std::unordered_set<std::string> Cov;
270270
Command Cmd;
271271
Cmd.addArgument(DFTBinary);

0 commit comments

Comments
 (0)