summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lib/Fuzzer/FuzzerUtil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/lib/Fuzzer/FuzzerUtil.cpp')
-rw-r--r--gnu/llvm/lib/Fuzzer/FuzzerUtil.cpp131
1 files changed, 108 insertions, 23 deletions
diff --git a/gnu/llvm/lib/Fuzzer/FuzzerUtil.cpp b/gnu/llvm/lib/Fuzzer/FuzzerUtil.cpp
index d7226cfce96..c2ae94c4d3d 100644
--- a/gnu/llvm/lib/Fuzzer/FuzzerUtil.cpp
+++ b/gnu/llvm/lib/Fuzzer/FuzzerUtil.cpp
@@ -12,21 +12,32 @@
#include "FuzzerInternal.h"
#include <sstream>
#include <iomanip>
+#include <sys/resource.h>
#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
#include <cassert>
+#include <chrono>
#include <cstring>
#include <signal.h>
#include <sstream>
#include <unistd.h>
+#include <errno.h>
+#include <thread>
namespace fuzzer {
-void Print(const Unit &v, const char *PrintAfter) {
- for (auto x : v)
- Printf("0x%x,", (unsigned) x);
+void PrintHexArray(const uint8_t *Data, size_t Size,
+ const char *PrintAfter) {
+ for (size_t i = 0; i < Size; i++)
+ Printf("0x%x,", (unsigned)Data[i]);
Printf("%s", PrintAfter);
}
+void Print(const Unit &v, const char *PrintAfter) {
+ PrintHexArray(v.data(), v.size(), PrintAfter);
+}
+
void PrintASCIIByte(uint8_t Byte) {
if (Byte == '\\')
Printf("\\\\");
@@ -44,10 +55,12 @@ void PrintASCII(const uint8_t *Data, size_t Size, const char *PrintAfter) {
Printf("%s", PrintAfter);
}
+void PrintASCII(const Word &W, const char *PrintAfter) {
+ PrintASCII(W.data(), W.size(), PrintAfter);
+}
+
void PrintASCII(const Unit &U, const char *PrintAfter) {
- for (auto X : U)
- PrintASCIIByte(X);
- Printf("%s", PrintAfter);
+ PrintASCII(U.data(), U.size(), PrintAfter);
}
std::string Hash(const Unit &U) {
@@ -63,22 +76,73 @@ static void AlarmHandler(int, siginfo_t *, void *) {
Fuzzer::StaticAlarmCallback();
}
-void SetTimer(int Seconds) {
- struct itimerval T {{Seconds, 0}, {Seconds, 0}};
- int Res = setitimer(ITIMER_REAL, &T, nullptr);
- assert(Res == 0);
+static void CrashHandler(int, siginfo_t *, void *) {
+ Fuzzer::StaticCrashSignalCallback();
+}
+
+static void InterruptHandler(int, siginfo_t *, void *) {
+ Fuzzer::StaticInterruptCallback();
+}
+
+static void SetSigaction(int signum,
+ void (*callback)(int, siginfo_t *, void *)) {
struct sigaction sigact;
memset(&sigact, 0, sizeof(sigact));
- sigact.sa_sigaction = AlarmHandler;
- Res = sigaction(SIGALRM, &sigact, 0);
- assert(Res == 0);
+ sigact.sa_sigaction = callback;
+ if (sigaction(signum, &sigact, 0)) {
+ Printf("libFuzzer: sigaction failed with %d\n", errno);
+ exit(1);
+ }
}
+void SetTimer(int Seconds) {
+ struct itimerval T {{Seconds, 0}, {Seconds, 0}};
+ if (setitimer(ITIMER_REAL, &T, nullptr)) {
+ Printf("libFuzzer: setitimer failed with %d\n", errno);
+ exit(1);
+ }
+ SetSigaction(SIGALRM, AlarmHandler);
+}
+
+void SetSigSegvHandler() { SetSigaction(SIGSEGV, CrashHandler); }
+void SetSigBusHandler() { SetSigaction(SIGBUS, CrashHandler); }
+void SetSigAbrtHandler() { SetSigaction(SIGABRT, CrashHandler); }
+void SetSigIllHandler() { SetSigaction(SIGILL, CrashHandler); }
+void SetSigFpeHandler() { SetSigaction(SIGFPE, CrashHandler); }
+void SetSigIntHandler() { SetSigaction(SIGINT, InterruptHandler); }
+void SetSigTermHandler() { SetSigaction(SIGTERM, InterruptHandler); }
+
int NumberOfCpuCores() {
- FILE *F = popen("nproc", "r");
- int N = 0;
- fscanf(F, "%d", &N);
- fclose(F);
+ const char *CmdLine = nullptr;
+ if (LIBFUZZER_LINUX) {
+ CmdLine = "nproc";
+ } else if (LIBFUZZER_APPLE) {
+ CmdLine = "sysctl -n hw.ncpu";
+ } else {
+ assert(0 && "NumberOfCpuCores() is not implemented for your platform");
+ }
+
+ FILE *F = popen(CmdLine, "r");
+ int N = 1;
+ if (!F || fscanf(F, "%d", &N) != 1) {
+ Printf("WARNING: Failed to parse output of command \"%s\" in %s(). "
+ "Assuming CPU count of 1.\n",
+ CmdLine, __func__);
+ N = 1;
+ }
+
+ if (pclose(F)) {
+ Printf("WARNING: Executing command \"%s\" failed in %s(). "
+ "Assuming CPU count of 1.\n",
+ CmdLine, __func__);
+ N = 1;
+ }
+ if (N < 1) {
+ Printf("WARNING: Reported CPU count (%d) from command \"%s\" was invalid "
+ "in %s(). Assuming CPU count of 1.\n",
+ N, CmdLine, __func__);
+ N = 1;
+ }
return N;
}
@@ -86,9 +150,10 @@ int ExecuteCommand(const std::string &Command) {
return system(Command.c_str());
}
-bool ToASCII(Unit &U) {
+bool ToASCII(uint8_t *Data, size_t Size) {
bool Changed = false;
- for (auto &X : U) {
+ for (size_t i = 0; i < Size; i++) {
+ uint8_t &X = Data[i];
auto NewX = X;
NewX &= 127;
if (!isspace(NewX) && !isprint(NewX))
@@ -99,9 +164,11 @@ bool ToASCII(Unit &U) {
return Changed;
}
-bool IsASCII(const Unit &U) {
- for (auto X : U)
- if (!(isprint(X) || isspace(X))) return false;
+bool IsASCII(const Unit &U) { return IsASCII(U.data(), U.size()); }
+
+bool IsASCII(const uint8_t *Data, size_t Size) {
+ for (size_t i = 0; i < Size; i++)
+ if (!(isprint(Data[i]) || isspace(Data[i]))) return false;
return true;
}
@@ -178,8 +245,11 @@ bool ParseDictionaryFile(const std::string &Text, std::vector<Unit> *Units) {
return true;
}
-int GetPid() { return getpid(); }
+void SleepSeconds(int Seconds) {
+ std::this_thread::sleep_for(std::chrono::seconds(Seconds));
+}
+int GetPid() { return getpid(); }
std::string Base64(const Unit &U) {
static const char Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -209,4 +279,19 @@ std::string Base64(const Unit &U) {
return Res;
}
+size_t GetPeakRSSMb() {
+ struct rusage usage;
+ if (getrusage(RUSAGE_SELF, &usage))
+ return 0;
+ if (LIBFUZZER_LINUX) {
+ // ru_maxrss is in KiB
+ return usage.ru_maxrss >> 10;
+ } else if (LIBFUZZER_APPLE) {
+ // ru_maxrss is in bytes
+ return usage.ru_maxrss >> 20;
+ }
+ assert(0 && "GetPeakRSSMb() is not implemented for your platform");
+ return 0;
+}
+
} // namespace fuzzer