2fb6e0587cf40b58c7a61368502751b0f42a383c
[oota-llvm.git] / lib / Fuzzer / FuzzerUtil.cpp
1 //===- FuzzerUtil.cpp - Misc utils ----------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // Misc utils.
10 //===----------------------------------------------------------------------===//
11
12 #include "FuzzerInternal.h"
13 #include <iostream>
14 #include <sys/time.h>
15 #include <cassert>
16 #include <cstring>
17 #include <signal.h>
18 #include <unistd.h>
19
20 namespace fuzzer {
21
22 void Print(const Unit &v, const char *PrintAfter) {
23   for (auto x : v)
24     std::cerr << "0x" << std::hex << (unsigned) x << std::dec << ",";
25   std::cerr << PrintAfter;
26 }
27
28 void PrintASCII(const Unit &U, const char *PrintAfter) {
29   for (auto X : U) {
30     if (isprint(X))
31       std::cerr << X;
32     else
33       std::cerr << "\\x" << std::hex << (int)(unsigned)X << std::dec;
34   }
35   std::cerr << PrintAfter;
36 }
37
38 // Try to compute a SHA1 sum of this Unit using an external 'sha1sum' command.
39 // We can not use the SHA1 function from openssl directly because
40 //  a) openssl may not be available,
41 //  b) we may be fuzzing openssl itself.
42 // This is all very sad, suggestions are welcome.
43 static std::string TrySha1(const Unit &in) {
44   char TempPath[] = "/tmp/fuzzer-tmp-XXXXXX";
45   int FD = mkstemp(TempPath);
46   if (FD < 0) return "";
47   ssize_t Written = write(FD, in.data(), in.size());
48   close(FD);
49   if (static_cast<size_t>(Written) != in.size()) return "";
50
51   std::string Cmd = "sha1sum < ";
52   Cmd += TempPath;
53   FILE *F = popen(Cmd.c_str(), "r");
54   if (!F) return "";
55   char Sha1[41];
56   fgets(Sha1, sizeof(Sha1), F);
57   fclose(F);
58
59   unlink(TempPath);
60   return Sha1;
61 }
62
63 std::string Hash(const Unit &in) {
64   std::string Sha1 = TrySha1(in);
65   if (!Sha1.empty())
66     return Sha1;
67
68   size_t h1 = 0, h2 = 0;
69   for (auto x : in) {
70     h1 += x;
71     h1 *= 5;
72     h2 += x;
73     h2 *= 7;
74   }
75   return std::to_string(h1) + std::to_string(h2);
76 }
77
78 static void AlarmHandler(int, siginfo_t *, void *) {
79   Fuzzer::StaticAlarmCallback();
80 }
81
82 void SetTimer(int Seconds) {
83   struct itimerval T {{Seconds, 0}, {Seconds, 0}};
84   std::cerr << "SetTimer " << Seconds << "\n";
85   int Res = setitimer(ITIMER_REAL, &T, nullptr);
86   assert(Res == 0);
87   struct sigaction sigact;
88   memset(&sigact, 0, sizeof(sigact));
89   sigact.sa_sigaction = AlarmHandler;
90   Res = sigaction(SIGALRM, &sigact, 0);
91   assert(Res == 0);
92 }
93
94 int NumberOfCpuCores() {
95   FILE *F = popen("nproc", "r");
96   int N = 0;
97   fscanf(F, "%d", &N);
98   fclose(F);
99   return N;
100 }
101
102 }  // namespace fuzzer