xref: /aosp_15_r20/external/AFLplusplus/instrumentation/afl-llvm-common.cc (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker #define AFL_LLVM_PASS
2*08b48e0bSAndroid Build Coastguard Worker 
3*08b48e0bSAndroid Build Coastguard Worker #include "config.h"
4*08b48e0bSAndroid Build Coastguard Worker #include "debug.h"
5*08b48e0bSAndroid Build Coastguard Worker 
6*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
7*08b48e0bSAndroid Build Coastguard Worker #include <stdlib.h>
8*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h>
9*08b48e0bSAndroid Build Coastguard Worker #include <sys/time.h>
10*08b48e0bSAndroid Build Coastguard Worker #include <fnmatch.h>
11*08b48e0bSAndroid Build Coastguard Worker 
12*08b48e0bSAndroid Build Coastguard Worker #include <list>
13*08b48e0bSAndroid Build Coastguard Worker #include <string>
14*08b48e0bSAndroid Build Coastguard Worker #include <fstream>
15*08b48e0bSAndroid Build Coastguard Worker #include <cmath>
16*08b48e0bSAndroid Build Coastguard Worker 
17*08b48e0bSAndroid Build Coastguard Worker #include <llvm/Support/raw_ostream.h>
18*08b48e0bSAndroid Build Coastguard Worker 
19*08b48e0bSAndroid Build Coastguard Worker #define IS_EXTERN extern
20*08b48e0bSAndroid Build Coastguard Worker #include "afl-llvm-common.h"
21*08b48e0bSAndroid Build Coastguard Worker 
22*08b48e0bSAndroid Build Coastguard Worker using namespace llvm;
23*08b48e0bSAndroid Build Coastguard Worker 
24*08b48e0bSAndroid Build Coastguard Worker static std::list<std::string> allowListFiles;
25*08b48e0bSAndroid Build Coastguard Worker static std::list<std::string> allowListFunctions;
26*08b48e0bSAndroid Build Coastguard Worker static std::list<std::string> denyListFiles;
27*08b48e0bSAndroid Build Coastguard Worker static std::list<std::string> denyListFunctions;
28*08b48e0bSAndroid Build Coastguard Worker 
getBBName(const llvm::BasicBlock * BB)29*08b48e0bSAndroid Build Coastguard Worker char *getBBName(const llvm::BasicBlock *BB) {
30*08b48e0bSAndroid Build Coastguard Worker 
31*08b48e0bSAndroid Build Coastguard Worker   static char *name;
32*08b48e0bSAndroid Build Coastguard Worker 
33*08b48e0bSAndroid Build Coastguard Worker   if (!BB->getName().empty()) {
34*08b48e0bSAndroid Build Coastguard Worker 
35*08b48e0bSAndroid Build Coastguard Worker     name = strdup(BB->getName().str().c_str());
36*08b48e0bSAndroid Build Coastguard Worker     return name;
37*08b48e0bSAndroid Build Coastguard Worker 
38*08b48e0bSAndroid Build Coastguard Worker   }
39*08b48e0bSAndroid Build Coastguard Worker 
40*08b48e0bSAndroid Build Coastguard Worker   std::string        Str;
41*08b48e0bSAndroid Build Coastguard Worker   raw_string_ostream OS(Str);
42*08b48e0bSAndroid Build Coastguard Worker 
43*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 4 || \
44*08b48e0bSAndroid Build Coastguard Worker     (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
45*08b48e0bSAndroid Build Coastguard Worker   BB->printAsOperand(OS, false);
46*08b48e0bSAndroid Build Coastguard Worker #endif
47*08b48e0bSAndroid Build Coastguard Worker   name = strdup(OS.str().c_str());
48*08b48e0bSAndroid Build Coastguard Worker   return name;
49*08b48e0bSAndroid Build Coastguard Worker 
50*08b48e0bSAndroid Build Coastguard Worker }
51*08b48e0bSAndroid Build Coastguard Worker 
52*08b48e0bSAndroid Build Coastguard Worker /* Function that we never instrument or analyze */
53*08b48e0bSAndroid Build Coastguard Worker /* Note: this ignore check is also called in isInInstrumentList() */
isIgnoreFunction(const llvm::Function * F)54*08b48e0bSAndroid Build Coastguard Worker bool isIgnoreFunction(const llvm::Function *F) {
55*08b48e0bSAndroid Build Coastguard Worker 
56*08b48e0bSAndroid Build Coastguard Worker   // Starting from "LLVMFuzzer" these are functions used in libfuzzer based
57*08b48e0bSAndroid Build Coastguard Worker   // fuzzing campaign installations, e.g. oss-fuzz
58*08b48e0bSAndroid Build Coastguard Worker 
59*08b48e0bSAndroid Build Coastguard Worker   static constexpr const char *ignoreList[] = {
60*08b48e0bSAndroid Build Coastguard Worker 
61*08b48e0bSAndroid Build Coastguard Worker       "asan.",
62*08b48e0bSAndroid Build Coastguard Worker       "llvm.",
63*08b48e0bSAndroid Build Coastguard Worker       "sancov.",
64*08b48e0bSAndroid Build Coastguard Worker       "__ubsan",
65*08b48e0bSAndroid Build Coastguard Worker       "ign.",
66*08b48e0bSAndroid Build Coastguard Worker       "__afl",
67*08b48e0bSAndroid Build Coastguard Worker       "_fini",
68*08b48e0bSAndroid Build Coastguard Worker       "__libc_",
69*08b48e0bSAndroid Build Coastguard Worker       "__asan",
70*08b48e0bSAndroid Build Coastguard Worker       "__msan",
71*08b48e0bSAndroid Build Coastguard Worker       "__cmplog",
72*08b48e0bSAndroid Build Coastguard Worker       "__sancov",
73*08b48e0bSAndroid Build Coastguard Worker       "__san",
74*08b48e0bSAndroid Build Coastguard Worker       "__cxx_",
75*08b48e0bSAndroid Build Coastguard Worker       "__decide_deferred",
76*08b48e0bSAndroid Build Coastguard Worker       "_GLOBAL",
77*08b48e0bSAndroid Build Coastguard Worker       "_ZZN6__asan",
78*08b48e0bSAndroid Build Coastguard Worker       "_ZZN6__lsan",
79*08b48e0bSAndroid Build Coastguard Worker       "msan.",
80*08b48e0bSAndroid Build Coastguard Worker       "LLVMFuzzerM",
81*08b48e0bSAndroid Build Coastguard Worker       "LLVMFuzzerC",
82*08b48e0bSAndroid Build Coastguard Worker       "LLVMFuzzerI",
83*08b48e0bSAndroid Build Coastguard Worker       "maybe_duplicate_stderr",
84*08b48e0bSAndroid Build Coastguard Worker       "discard_output",
85*08b48e0bSAndroid Build Coastguard Worker       "close_stdout",
86*08b48e0bSAndroid Build Coastguard Worker       "dup_and_close_stderr",
87*08b48e0bSAndroid Build Coastguard Worker       "maybe_close_fd_mask",
88*08b48e0bSAndroid Build Coastguard Worker       "ExecuteFilesOnyByOne"
89*08b48e0bSAndroid Build Coastguard Worker 
90*08b48e0bSAndroid Build Coastguard Worker   };
91*08b48e0bSAndroid Build Coastguard Worker 
92*08b48e0bSAndroid Build Coastguard Worker   for (auto const &ignoreListFunc : ignoreList) {
93*08b48e0bSAndroid Build Coastguard Worker 
94*08b48e0bSAndroid Build Coastguard Worker     if (F->getName().startswith(ignoreListFunc)) { return true; }
95*08b48e0bSAndroid Build Coastguard Worker 
96*08b48e0bSAndroid Build Coastguard Worker   }
97*08b48e0bSAndroid Build Coastguard Worker 
98*08b48e0bSAndroid Build Coastguard Worker   static constexpr const char *ignoreSubstringList[] = {
99*08b48e0bSAndroid Build Coastguard Worker 
100*08b48e0bSAndroid Build Coastguard Worker       "__asan",     "__msan",       "__ubsan",    "__lsan",  "__san",
101*08b48e0bSAndroid Build Coastguard Worker       "__sanitize", "DebugCounter", "DwarfDebug", "DebugLoc"
102*08b48e0bSAndroid Build Coastguard Worker 
103*08b48e0bSAndroid Build Coastguard Worker   };
104*08b48e0bSAndroid Build Coastguard Worker 
105*08b48e0bSAndroid Build Coastguard Worker   // This check is very sensitive, we must be sure to not include patterns
106*08b48e0bSAndroid Build Coastguard Worker   // that are part of user-written C++ functions like the ones including
107*08b48e0bSAndroid Build Coastguard Worker   // std::string as parameter (see #1927) as the mangled type is inserted in the
108*08b48e0bSAndroid Build Coastguard Worker   // mangled name of the user-written function
109*08b48e0bSAndroid Build Coastguard Worker   for (auto const &ignoreListFunc : ignoreSubstringList) {
110*08b48e0bSAndroid Build Coastguard Worker 
111*08b48e0bSAndroid Build Coastguard Worker     // hexcoder: F->getName().contains() not avaiilable in llvm 3.8.0
112*08b48e0bSAndroid Build Coastguard Worker     if (StringRef::npos != F->getName().find(ignoreListFunc)) { return true; }
113*08b48e0bSAndroid Build Coastguard Worker 
114*08b48e0bSAndroid Build Coastguard Worker   }
115*08b48e0bSAndroid Build Coastguard Worker 
116*08b48e0bSAndroid Build Coastguard Worker   return false;
117*08b48e0bSAndroid Build Coastguard Worker 
118*08b48e0bSAndroid Build Coastguard Worker }
119*08b48e0bSAndroid Build Coastguard Worker 
initInstrumentList()120*08b48e0bSAndroid Build Coastguard Worker void initInstrumentList() {
121*08b48e0bSAndroid Build Coastguard Worker 
122*08b48e0bSAndroid Build Coastguard Worker   char *allowlist = getenv("AFL_LLVM_ALLOWLIST");
123*08b48e0bSAndroid Build Coastguard Worker   if (!allowlist) allowlist = getenv("AFL_LLVM_INSTRUMENT_FILE");
124*08b48e0bSAndroid Build Coastguard Worker   if (!allowlist) allowlist = getenv("AFL_LLVM_WHITELIST");
125*08b48e0bSAndroid Build Coastguard Worker   char *denylist = getenv("AFL_LLVM_DENYLIST");
126*08b48e0bSAndroid Build Coastguard Worker   if (!denylist) denylist = getenv("AFL_LLVM_BLOCKLIST");
127*08b48e0bSAndroid Build Coastguard Worker 
128*08b48e0bSAndroid Build Coastguard Worker   if (allowlist && denylist)
129*08b48e0bSAndroid Build Coastguard Worker     FATAL(
130*08b48e0bSAndroid Build Coastguard Worker         "You can only specify either AFL_LLVM_ALLOWLIST or AFL_LLVM_DENYLIST "
131*08b48e0bSAndroid Build Coastguard Worker         "but not both!");
132*08b48e0bSAndroid Build Coastguard Worker 
133*08b48e0bSAndroid Build Coastguard Worker   if (allowlist) {
134*08b48e0bSAndroid Build Coastguard Worker 
135*08b48e0bSAndroid Build Coastguard Worker     std::string   line;
136*08b48e0bSAndroid Build Coastguard Worker     std::ifstream fileStream;
137*08b48e0bSAndroid Build Coastguard Worker     fileStream.open(allowlist);
138*08b48e0bSAndroid Build Coastguard Worker     if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_ALLOWLIST");
139*08b48e0bSAndroid Build Coastguard Worker     getline(fileStream, line);
140*08b48e0bSAndroid Build Coastguard Worker 
141*08b48e0bSAndroid Build Coastguard Worker     while (fileStream) {
142*08b48e0bSAndroid Build Coastguard Worker 
143*08b48e0bSAndroid Build Coastguard Worker       int         is_file = -1;
144*08b48e0bSAndroid Build Coastguard Worker       std::size_t npos;
145*08b48e0bSAndroid Build Coastguard Worker       std::string original_line = line;
146*08b48e0bSAndroid Build Coastguard Worker 
147*08b48e0bSAndroid Build Coastguard Worker       line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
148*08b48e0bSAndroid Build Coastguard Worker                  line.end());
149*08b48e0bSAndroid Build Coastguard Worker 
150*08b48e0bSAndroid Build Coastguard Worker       // remove # and following
151*08b48e0bSAndroid Build Coastguard Worker       if ((npos = line.find("#")) != std::string::npos)
152*08b48e0bSAndroid Build Coastguard Worker         line = line.substr(0, npos);
153*08b48e0bSAndroid Build Coastguard Worker 
154*08b48e0bSAndroid Build Coastguard Worker       if (line.compare(0, 4, "fun:") == 0) {
155*08b48e0bSAndroid Build Coastguard Worker 
156*08b48e0bSAndroid Build Coastguard Worker         is_file = 0;
157*08b48e0bSAndroid Build Coastguard Worker         line = line.substr(4);
158*08b48e0bSAndroid Build Coastguard Worker 
159*08b48e0bSAndroid Build Coastguard Worker       } else if (line.compare(0, 9, "function:") == 0) {
160*08b48e0bSAndroid Build Coastguard Worker 
161*08b48e0bSAndroid Build Coastguard Worker         is_file = 0;
162*08b48e0bSAndroid Build Coastguard Worker         line = line.substr(9);
163*08b48e0bSAndroid Build Coastguard Worker 
164*08b48e0bSAndroid Build Coastguard Worker       } else if (line.compare(0, 4, "src:") == 0) {
165*08b48e0bSAndroid Build Coastguard Worker 
166*08b48e0bSAndroid Build Coastguard Worker         is_file = 1;
167*08b48e0bSAndroid Build Coastguard Worker         line = line.substr(4);
168*08b48e0bSAndroid Build Coastguard Worker 
169*08b48e0bSAndroid Build Coastguard Worker       } else if (line.compare(0, 7, "source:") == 0) {
170*08b48e0bSAndroid Build Coastguard Worker 
171*08b48e0bSAndroid Build Coastguard Worker         is_file = 1;
172*08b48e0bSAndroid Build Coastguard Worker         line = line.substr(7);
173*08b48e0bSAndroid Build Coastguard Worker 
174*08b48e0bSAndroid Build Coastguard Worker       }
175*08b48e0bSAndroid Build Coastguard Worker 
176*08b48e0bSAndroid Build Coastguard Worker       if (line.find(":") != std::string::npos) {
177*08b48e0bSAndroid Build Coastguard Worker 
178*08b48e0bSAndroid Build Coastguard Worker         FATAL("invalid line in AFL_LLVM_ALLOWLIST: %s", original_line.c_str());
179*08b48e0bSAndroid Build Coastguard Worker 
180*08b48e0bSAndroid Build Coastguard Worker       }
181*08b48e0bSAndroid Build Coastguard Worker 
182*08b48e0bSAndroid Build Coastguard Worker       if (line.length() > 0) {
183*08b48e0bSAndroid Build Coastguard Worker 
184*08b48e0bSAndroid Build Coastguard Worker         // if the entry contains / or . it must be a file
185*08b48e0bSAndroid Build Coastguard Worker         if (is_file == -1)
186*08b48e0bSAndroid Build Coastguard Worker           if (line.find("/") != std::string::npos ||
187*08b48e0bSAndroid Build Coastguard Worker               line.find(".") != std::string::npos)
188*08b48e0bSAndroid Build Coastguard Worker             is_file = 1;
189*08b48e0bSAndroid Build Coastguard Worker         // otherwise it is a function
190*08b48e0bSAndroid Build Coastguard Worker 
191*08b48e0bSAndroid Build Coastguard Worker         if (is_file == 1)
192*08b48e0bSAndroid Build Coastguard Worker           allowListFiles.push_back(line);
193*08b48e0bSAndroid Build Coastguard Worker         else
194*08b48e0bSAndroid Build Coastguard Worker           allowListFunctions.push_back(line);
195*08b48e0bSAndroid Build Coastguard Worker 
196*08b48e0bSAndroid Build Coastguard Worker       }
197*08b48e0bSAndroid Build Coastguard Worker 
198*08b48e0bSAndroid Build Coastguard Worker       getline(fileStream, line);
199*08b48e0bSAndroid Build Coastguard Worker 
200*08b48e0bSAndroid Build Coastguard Worker     }
201*08b48e0bSAndroid Build Coastguard Worker 
202*08b48e0bSAndroid Build Coastguard Worker     if (debug)
203*08b48e0bSAndroid Build Coastguard Worker       DEBUGF("loaded allowlist with %zu file and %zu function entries\n",
204*08b48e0bSAndroid Build Coastguard Worker              allowListFiles.size() / 4, allowListFunctions.size() / 4);
205*08b48e0bSAndroid Build Coastguard Worker 
206*08b48e0bSAndroid Build Coastguard Worker   }
207*08b48e0bSAndroid Build Coastguard Worker 
208*08b48e0bSAndroid Build Coastguard Worker   if (denylist) {
209*08b48e0bSAndroid Build Coastguard Worker 
210*08b48e0bSAndroid Build Coastguard Worker     std::string   line;
211*08b48e0bSAndroid Build Coastguard Worker     std::ifstream fileStream;
212*08b48e0bSAndroid Build Coastguard Worker     fileStream.open(denylist);
213*08b48e0bSAndroid Build Coastguard Worker     if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_DENYLIST");
214*08b48e0bSAndroid Build Coastguard Worker     getline(fileStream, line);
215*08b48e0bSAndroid Build Coastguard Worker 
216*08b48e0bSAndroid Build Coastguard Worker     while (fileStream) {
217*08b48e0bSAndroid Build Coastguard Worker 
218*08b48e0bSAndroid Build Coastguard Worker       int         is_file = -1;
219*08b48e0bSAndroid Build Coastguard Worker       std::size_t npos;
220*08b48e0bSAndroid Build Coastguard Worker       std::string original_line = line;
221*08b48e0bSAndroid Build Coastguard Worker 
222*08b48e0bSAndroid Build Coastguard Worker       line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
223*08b48e0bSAndroid Build Coastguard Worker                  line.end());
224*08b48e0bSAndroid Build Coastguard Worker 
225*08b48e0bSAndroid Build Coastguard Worker       // remove # and following
226*08b48e0bSAndroid Build Coastguard Worker       if ((npos = line.find("#")) != std::string::npos)
227*08b48e0bSAndroid Build Coastguard Worker         line = line.substr(0, npos);
228*08b48e0bSAndroid Build Coastguard Worker 
229*08b48e0bSAndroid Build Coastguard Worker       if (line.compare(0, 4, "fun:") == 0) {
230*08b48e0bSAndroid Build Coastguard Worker 
231*08b48e0bSAndroid Build Coastguard Worker         is_file = 0;
232*08b48e0bSAndroid Build Coastguard Worker         line = line.substr(4);
233*08b48e0bSAndroid Build Coastguard Worker 
234*08b48e0bSAndroid Build Coastguard Worker       } else if (line.compare(0, 9, "function:") == 0) {
235*08b48e0bSAndroid Build Coastguard Worker 
236*08b48e0bSAndroid Build Coastguard Worker         is_file = 0;
237*08b48e0bSAndroid Build Coastguard Worker         line = line.substr(9);
238*08b48e0bSAndroid Build Coastguard Worker 
239*08b48e0bSAndroid Build Coastguard Worker       } else if (line.compare(0, 4, "src:") == 0) {
240*08b48e0bSAndroid Build Coastguard Worker 
241*08b48e0bSAndroid Build Coastguard Worker         is_file = 1;
242*08b48e0bSAndroid Build Coastguard Worker         line = line.substr(4);
243*08b48e0bSAndroid Build Coastguard Worker 
244*08b48e0bSAndroid Build Coastguard Worker       } else if (line.compare(0, 7, "source:") == 0) {
245*08b48e0bSAndroid Build Coastguard Worker 
246*08b48e0bSAndroid Build Coastguard Worker         is_file = 1;
247*08b48e0bSAndroid Build Coastguard Worker         line = line.substr(7);
248*08b48e0bSAndroid Build Coastguard Worker 
249*08b48e0bSAndroid Build Coastguard Worker       }
250*08b48e0bSAndroid Build Coastguard Worker 
251*08b48e0bSAndroid Build Coastguard Worker       if (line.find(":") != std::string::npos) {
252*08b48e0bSAndroid Build Coastguard Worker 
253*08b48e0bSAndroid Build Coastguard Worker         FATAL("invalid line in AFL_LLVM_DENYLIST: %s", original_line.c_str());
254*08b48e0bSAndroid Build Coastguard Worker 
255*08b48e0bSAndroid Build Coastguard Worker       }
256*08b48e0bSAndroid Build Coastguard Worker 
257*08b48e0bSAndroid Build Coastguard Worker       if (line.length() > 0) {
258*08b48e0bSAndroid Build Coastguard Worker 
259*08b48e0bSAndroid Build Coastguard Worker         // if the entry contains / or . it must be a file
260*08b48e0bSAndroid Build Coastguard Worker         if (is_file == -1)
261*08b48e0bSAndroid Build Coastguard Worker           if (line.find("/") != std::string::npos ||
262*08b48e0bSAndroid Build Coastguard Worker               line.find(".") != std::string::npos)
263*08b48e0bSAndroid Build Coastguard Worker             is_file = 1;
264*08b48e0bSAndroid Build Coastguard Worker         // otherwise it is a function
265*08b48e0bSAndroid Build Coastguard Worker 
266*08b48e0bSAndroid Build Coastguard Worker         if (is_file == 1)
267*08b48e0bSAndroid Build Coastguard Worker           denyListFiles.push_back(line);
268*08b48e0bSAndroid Build Coastguard Worker         else
269*08b48e0bSAndroid Build Coastguard Worker           denyListFunctions.push_back(line);
270*08b48e0bSAndroid Build Coastguard Worker 
271*08b48e0bSAndroid Build Coastguard Worker       }
272*08b48e0bSAndroid Build Coastguard Worker 
273*08b48e0bSAndroid Build Coastguard Worker       getline(fileStream, line);
274*08b48e0bSAndroid Build Coastguard Worker 
275*08b48e0bSAndroid Build Coastguard Worker     }
276*08b48e0bSAndroid Build Coastguard Worker 
277*08b48e0bSAndroid Build Coastguard Worker     if (debug)
278*08b48e0bSAndroid Build Coastguard Worker       DEBUGF("loaded denylist with %zu file and %zu function entries\n",
279*08b48e0bSAndroid Build Coastguard Worker              denyListFiles.size() / 4, denyListFunctions.size() / 4);
280*08b48e0bSAndroid Build Coastguard Worker 
281*08b48e0bSAndroid Build Coastguard Worker   }
282*08b48e0bSAndroid Build Coastguard Worker 
283*08b48e0bSAndroid Build Coastguard Worker }
284*08b48e0bSAndroid Build Coastguard Worker 
scanForDangerousFunctions(llvm::Module * M)285*08b48e0bSAndroid Build Coastguard Worker void scanForDangerousFunctions(llvm::Module *M) {
286*08b48e0bSAndroid Build Coastguard Worker 
287*08b48e0bSAndroid Build Coastguard Worker   if (!M) return;
288*08b48e0bSAndroid Build Coastguard Worker 
289*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 4 || \
290*08b48e0bSAndroid Build Coastguard Worker     (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9)
291*08b48e0bSAndroid Build Coastguard Worker 
292*08b48e0bSAndroid Build Coastguard Worker   for (GlobalIFunc &IF : M->ifuncs()) {
293*08b48e0bSAndroid Build Coastguard Worker 
294*08b48e0bSAndroid Build Coastguard Worker     StringRef ifunc_name = IF.getName();
295*08b48e0bSAndroid Build Coastguard Worker     Constant *r = IF.getResolver();
296*08b48e0bSAndroid Build Coastguard Worker     if (r->getNumOperands() == 0) { continue; }
297*08b48e0bSAndroid Build Coastguard Worker     StringRef r_name = cast<Function>(r->getOperand(0))->getName();
298*08b48e0bSAndroid Build Coastguard Worker     if (!be_quiet)
299*08b48e0bSAndroid Build Coastguard Worker       fprintf(stderr,
300*08b48e0bSAndroid Build Coastguard Worker               "Note: Found an ifunc with name %s that points to resolver "
301*08b48e0bSAndroid Build Coastguard Worker               "function %s, we will not instrument this, putting it into the "
302*08b48e0bSAndroid Build Coastguard Worker               "block list.\n",
303*08b48e0bSAndroid Build Coastguard Worker               ifunc_name.str().c_str(), r_name.str().c_str());
304*08b48e0bSAndroid Build Coastguard Worker     denyListFunctions.push_back(r_name.str());
305*08b48e0bSAndroid Build Coastguard Worker 
306*08b48e0bSAndroid Build Coastguard Worker   }
307*08b48e0bSAndroid Build Coastguard Worker 
308*08b48e0bSAndroid Build Coastguard Worker   GlobalVariable *GV = M->getNamedGlobal("llvm.global_ctors");
309*08b48e0bSAndroid Build Coastguard Worker   if (GV && !GV->isDeclaration() && !GV->hasLocalLinkage()) {
310*08b48e0bSAndroid Build Coastguard Worker 
311*08b48e0bSAndroid Build Coastguard Worker     ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
312*08b48e0bSAndroid Build Coastguard Worker 
313*08b48e0bSAndroid Build Coastguard Worker     if (InitList) {
314*08b48e0bSAndroid Build Coastguard Worker 
315*08b48e0bSAndroid Build Coastguard Worker       for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
316*08b48e0bSAndroid Build Coastguard Worker 
317*08b48e0bSAndroid Build Coastguard Worker         if (ConstantStruct *CS =
318*08b48e0bSAndroid Build Coastguard Worker                 dyn_cast<ConstantStruct>(InitList->getOperand(i))) {
319*08b48e0bSAndroid Build Coastguard Worker 
320*08b48e0bSAndroid Build Coastguard Worker           if (CS->getNumOperands() >= 2) {
321*08b48e0bSAndroid Build Coastguard Worker 
322*08b48e0bSAndroid Build Coastguard Worker             if (CS->getOperand(1)->isNullValue())
323*08b48e0bSAndroid Build Coastguard Worker               break;  // Found a null terminator, stop here.
324*08b48e0bSAndroid Build Coastguard Worker 
325*08b48e0bSAndroid Build Coastguard Worker             ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0));
326*08b48e0bSAndroid Build Coastguard Worker             int          Priority = CI ? CI->getSExtValue() : 0;
327*08b48e0bSAndroid Build Coastguard Worker 
328*08b48e0bSAndroid Build Coastguard Worker             Constant *FP = CS->getOperand(1);
329*08b48e0bSAndroid Build Coastguard Worker             if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
330*08b48e0bSAndroid Build Coastguard Worker               if (CE->isCast()) FP = CE->getOperand(0);
331*08b48e0bSAndroid Build Coastguard Worker             if (Function *F = dyn_cast<Function>(FP)) {
332*08b48e0bSAndroid Build Coastguard Worker 
333*08b48e0bSAndroid Build Coastguard Worker               if (!F->isDeclaration() &&
334*08b48e0bSAndroid Build Coastguard Worker                   strncmp(F->getName().str().c_str(), "__afl", 5) != 0) {
335*08b48e0bSAndroid Build Coastguard Worker 
336*08b48e0bSAndroid Build Coastguard Worker                 if (!be_quiet)
337*08b48e0bSAndroid Build Coastguard Worker                   fprintf(stderr,
338*08b48e0bSAndroid Build Coastguard Worker                           "Note: Found constructor function %s with prio "
339*08b48e0bSAndroid Build Coastguard Worker                           "%u, we will not instrument this, putting it into a "
340*08b48e0bSAndroid Build Coastguard Worker                           "block list.\n",
341*08b48e0bSAndroid Build Coastguard Worker                           F->getName().str().c_str(), Priority);
342*08b48e0bSAndroid Build Coastguard Worker                 denyListFunctions.push_back(F->getName().str());
343*08b48e0bSAndroid Build Coastguard Worker 
344*08b48e0bSAndroid Build Coastguard Worker               }
345*08b48e0bSAndroid Build Coastguard Worker 
346*08b48e0bSAndroid Build Coastguard Worker             }
347*08b48e0bSAndroid Build Coastguard Worker 
348*08b48e0bSAndroid Build Coastguard Worker           }
349*08b48e0bSAndroid Build Coastguard Worker 
350*08b48e0bSAndroid Build Coastguard Worker         }
351*08b48e0bSAndroid Build Coastguard Worker 
352*08b48e0bSAndroid Build Coastguard Worker       }
353*08b48e0bSAndroid Build Coastguard Worker 
354*08b48e0bSAndroid Build Coastguard Worker     }
355*08b48e0bSAndroid Build Coastguard Worker 
356*08b48e0bSAndroid Build Coastguard Worker   }
357*08b48e0bSAndroid Build Coastguard Worker 
358*08b48e0bSAndroid Build Coastguard Worker #endif
359*08b48e0bSAndroid Build Coastguard Worker 
360*08b48e0bSAndroid Build Coastguard Worker }
361*08b48e0bSAndroid Build Coastguard Worker 
getSourceName(llvm::Function * F)362*08b48e0bSAndroid Build Coastguard Worker static std::string getSourceName(llvm::Function *F) {
363*08b48e0bSAndroid Build Coastguard Worker 
364*08b48e0bSAndroid Build Coastguard Worker   // let's try to get the filename for the function
365*08b48e0bSAndroid Build Coastguard Worker   auto                 bb = &F->getEntryBlock();
366*08b48e0bSAndroid Build Coastguard Worker   BasicBlock::iterator IP = bb->getFirstInsertionPt();
367*08b48e0bSAndroid Build Coastguard Worker   IRBuilder<>          IRB(&(*IP));
368*08b48e0bSAndroid Build Coastguard Worker   DebugLoc             Loc = IP->getDebugLoc();
369*08b48e0bSAndroid Build Coastguard Worker 
370*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 4 || \
371*08b48e0bSAndroid Build Coastguard Worker     (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
372*08b48e0bSAndroid Build Coastguard Worker   if (Loc) {
373*08b48e0bSAndroid Build Coastguard Worker 
374*08b48e0bSAndroid Build Coastguard Worker     StringRef   instFilename;
375*08b48e0bSAndroid Build Coastguard Worker     DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
376*08b48e0bSAndroid Build Coastguard Worker 
377*08b48e0bSAndroid Build Coastguard Worker     if (cDILoc) { instFilename = cDILoc->getFilename(); }
378*08b48e0bSAndroid Build Coastguard Worker 
379*08b48e0bSAndroid Build Coastguard Worker     if (instFilename.str().empty() && cDILoc) {
380*08b48e0bSAndroid Build Coastguard Worker 
381*08b48e0bSAndroid Build Coastguard Worker       /* If the original location is empty, try using the inlined location
382*08b48e0bSAndroid Build Coastguard Worker        */
383*08b48e0bSAndroid Build Coastguard Worker       DILocation *oDILoc = cDILoc->getInlinedAt();
384*08b48e0bSAndroid Build Coastguard Worker       if (oDILoc) { instFilename = oDILoc->getFilename(); }
385*08b48e0bSAndroid Build Coastguard Worker 
386*08b48e0bSAndroid Build Coastguard Worker     }
387*08b48e0bSAndroid Build Coastguard Worker 
388*08b48e0bSAndroid Build Coastguard Worker     return instFilename.str();
389*08b48e0bSAndroid Build Coastguard Worker 
390*08b48e0bSAndroid Build Coastguard Worker   }
391*08b48e0bSAndroid Build Coastguard Worker 
392*08b48e0bSAndroid Build Coastguard Worker #else
393*08b48e0bSAndroid Build Coastguard Worker   if (!Loc.isUnknown()) {
394*08b48e0bSAndroid Build Coastguard Worker 
395*08b48e0bSAndroid Build Coastguard Worker     DILocation cDILoc(Loc.getAsMDNode(F->getContext()));
396*08b48e0bSAndroid Build Coastguard Worker 
397*08b48e0bSAndroid Build Coastguard Worker     StringRef instFilename = cDILoc.getFilename();
398*08b48e0bSAndroid Build Coastguard Worker 
399*08b48e0bSAndroid Build Coastguard Worker     /* Continue only if we know where we actually are */
400*08b48e0bSAndroid Build Coastguard Worker     return instFilename.str();
401*08b48e0bSAndroid Build Coastguard Worker 
402*08b48e0bSAndroid Build Coastguard Worker   }
403*08b48e0bSAndroid Build Coastguard Worker 
404*08b48e0bSAndroid Build Coastguard Worker #endif
405*08b48e0bSAndroid Build Coastguard Worker 
406*08b48e0bSAndroid Build Coastguard Worker   return std::string("");
407*08b48e0bSAndroid Build Coastguard Worker 
408*08b48e0bSAndroid Build Coastguard Worker }
409*08b48e0bSAndroid Build Coastguard Worker 
isInInstrumentList(llvm::Function * F,std::string Filename)410*08b48e0bSAndroid Build Coastguard Worker bool isInInstrumentList(llvm::Function *F, std::string Filename) {
411*08b48e0bSAndroid Build Coastguard Worker 
412*08b48e0bSAndroid Build Coastguard Worker   bool return_default = true;
413*08b48e0bSAndroid Build Coastguard Worker 
414*08b48e0bSAndroid Build Coastguard Worker   // is this a function with code? If it is external we don't instrument it
415*08b48e0bSAndroid Build Coastguard Worker   // anyway and it can't be in the instrument file list. Or if it is it is
416*08b48e0bSAndroid Build Coastguard Worker   // ignored.
417*08b48e0bSAndroid Build Coastguard Worker   if (!F->size() || isIgnoreFunction(F)) return false;
418*08b48e0bSAndroid Build Coastguard Worker 
419*08b48e0bSAndroid Build Coastguard Worker   if (!denyListFiles.empty() || !denyListFunctions.empty()) {
420*08b48e0bSAndroid Build Coastguard Worker 
421*08b48e0bSAndroid Build Coastguard Worker     if (!denyListFunctions.empty()) {
422*08b48e0bSAndroid Build Coastguard Worker 
423*08b48e0bSAndroid Build Coastguard Worker       std::string instFunction = F->getName().str();
424*08b48e0bSAndroid Build Coastguard Worker 
425*08b48e0bSAndroid Build Coastguard Worker       for (std::list<std::string>::iterator it = denyListFunctions.begin();
426*08b48e0bSAndroid Build Coastguard Worker            it != denyListFunctions.end(); ++it) {
427*08b48e0bSAndroid Build Coastguard Worker 
428*08b48e0bSAndroid Build Coastguard Worker         /* We don't check for filename equality here because
429*08b48e0bSAndroid Build Coastguard Worker          * filenames might actually be full paths. Instead we
430*08b48e0bSAndroid Build Coastguard Worker          * check that the actual filename ends in the filename
431*08b48e0bSAndroid Build Coastguard Worker          * specified in the list. We also allow UNIX-style pattern
432*08b48e0bSAndroid Build Coastguard Worker          * matching */
433*08b48e0bSAndroid Build Coastguard Worker 
434*08b48e0bSAndroid Build Coastguard Worker         if (instFunction.length() >= it->length()) {
435*08b48e0bSAndroid Build Coastguard Worker 
436*08b48e0bSAndroid Build Coastguard Worker           if (fnmatch(("*" + *it).c_str(), instFunction.c_str(), 0) == 0) {
437*08b48e0bSAndroid Build Coastguard Worker 
438*08b48e0bSAndroid Build Coastguard Worker             if (debug)
439*08b48e0bSAndroid Build Coastguard Worker               DEBUGF(
440*08b48e0bSAndroid Build Coastguard Worker                   "Function %s is in the deny function list, not instrumenting "
441*08b48e0bSAndroid Build Coastguard Worker                   "... \n",
442*08b48e0bSAndroid Build Coastguard Worker                   instFunction.c_str());
443*08b48e0bSAndroid Build Coastguard Worker             return false;
444*08b48e0bSAndroid Build Coastguard Worker 
445*08b48e0bSAndroid Build Coastguard Worker           }
446*08b48e0bSAndroid Build Coastguard Worker 
447*08b48e0bSAndroid Build Coastguard Worker         }
448*08b48e0bSAndroid Build Coastguard Worker 
449*08b48e0bSAndroid Build Coastguard Worker       }
450*08b48e0bSAndroid Build Coastguard Worker 
451*08b48e0bSAndroid Build Coastguard Worker     }
452*08b48e0bSAndroid Build Coastguard Worker 
453*08b48e0bSAndroid Build Coastguard Worker     if (!denyListFiles.empty()) {
454*08b48e0bSAndroid Build Coastguard Worker 
455*08b48e0bSAndroid Build Coastguard Worker       std::string source_file = getSourceName(F);
456*08b48e0bSAndroid Build Coastguard Worker 
457*08b48e0bSAndroid Build Coastguard Worker       if (source_file.empty()) { source_file = Filename; }
458*08b48e0bSAndroid Build Coastguard Worker 
459*08b48e0bSAndroid Build Coastguard Worker       if (!source_file.empty()) {
460*08b48e0bSAndroid Build Coastguard Worker 
461*08b48e0bSAndroid Build Coastguard Worker         for (std::list<std::string>::iterator it = denyListFiles.begin();
462*08b48e0bSAndroid Build Coastguard Worker              it != denyListFiles.end(); ++it) {
463*08b48e0bSAndroid Build Coastguard Worker 
464*08b48e0bSAndroid Build Coastguard Worker           /* We don't check for filename equality here because
465*08b48e0bSAndroid Build Coastguard Worker            * filenames might actually be full paths. Instead we
466*08b48e0bSAndroid Build Coastguard Worker            * check that the actual filename ends in the filename
467*08b48e0bSAndroid Build Coastguard Worker            * specified in the list. We also allow UNIX-style pattern
468*08b48e0bSAndroid Build Coastguard Worker            * matching */
469*08b48e0bSAndroid Build Coastguard Worker 
470*08b48e0bSAndroid Build Coastguard Worker           if (source_file.length() >= it->length()) {
471*08b48e0bSAndroid Build Coastguard Worker 
472*08b48e0bSAndroid Build Coastguard Worker             if (fnmatch(("*" + *it).c_str(), source_file.c_str(), 0) == 0) {
473*08b48e0bSAndroid Build Coastguard Worker 
474*08b48e0bSAndroid Build Coastguard Worker               return false;
475*08b48e0bSAndroid Build Coastguard Worker 
476*08b48e0bSAndroid Build Coastguard Worker             }
477*08b48e0bSAndroid Build Coastguard Worker 
478*08b48e0bSAndroid Build Coastguard Worker           }
479*08b48e0bSAndroid Build Coastguard Worker 
480*08b48e0bSAndroid Build Coastguard Worker         }
481*08b48e0bSAndroid Build Coastguard Worker 
482*08b48e0bSAndroid Build Coastguard Worker       } else {
483*08b48e0bSAndroid Build Coastguard Worker 
484*08b48e0bSAndroid Build Coastguard Worker         // we could not find out the location. in this case we say it is not
485*08b48e0bSAndroid Build Coastguard Worker         // in the instrument file list
486*08b48e0bSAndroid Build Coastguard Worker         if (!be_quiet)
487*08b48e0bSAndroid Build Coastguard Worker           WARNF(
488*08b48e0bSAndroid Build Coastguard Worker               "No debug information found for function %s, will be "
489*08b48e0bSAndroid Build Coastguard Worker               "instrumented (recompile with -g -O[1-3] and use a modern llvm).",
490*08b48e0bSAndroid Build Coastguard Worker               F->getName().str().c_str());
491*08b48e0bSAndroid Build Coastguard Worker 
492*08b48e0bSAndroid Build Coastguard Worker       }
493*08b48e0bSAndroid Build Coastguard Worker 
494*08b48e0bSAndroid Build Coastguard Worker     }
495*08b48e0bSAndroid Build Coastguard Worker 
496*08b48e0bSAndroid Build Coastguard Worker   }
497*08b48e0bSAndroid Build Coastguard Worker 
498*08b48e0bSAndroid Build Coastguard Worker   // if we do not have a instrument file list return true
499*08b48e0bSAndroid Build Coastguard Worker   if (!allowListFiles.empty() || !allowListFunctions.empty()) {
500*08b48e0bSAndroid Build Coastguard Worker 
501*08b48e0bSAndroid Build Coastguard Worker     return_default = false;
502*08b48e0bSAndroid Build Coastguard Worker 
503*08b48e0bSAndroid Build Coastguard Worker     if (!allowListFunctions.empty()) {
504*08b48e0bSAndroid Build Coastguard Worker 
505*08b48e0bSAndroid Build Coastguard Worker       std::string instFunction = F->getName().str();
506*08b48e0bSAndroid Build Coastguard Worker 
507*08b48e0bSAndroid Build Coastguard Worker       for (std::list<std::string>::iterator it = allowListFunctions.begin();
508*08b48e0bSAndroid Build Coastguard Worker            it != allowListFunctions.end(); ++it) {
509*08b48e0bSAndroid Build Coastguard Worker 
510*08b48e0bSAndroid Build Coastguard Worker         /* We don't check for filename equality here because
511*08b48e0bSAndroid Build Coastguard Worker          * filenames might actually be full paths. Instead we
512*08b48e0bSAndroid Build Coastguard Worker          * check that the actual filename ends in the filename
513*08b48e0bSAndroid Build Coastguard Worker          * specified in the list. We also allow UNIX-style pattern
514*08b48e0bSAndroid Build Coastguard Worker          * matching */
515*08b48e0bSAndroid Build Coastguard Worker 
516*08b48e0bSAndroid Build Coastguard Worker         if (instFunction.length() >= it->length()) {
517*08b48e0bSAndroid Build Coastguard Worker 
518*08b48e0bSAndroid Build Coastguard Worker           if (fnmatch(("*" + *it).c_str(), instFunction.c_str(), 0) == 0) {
519*08b48e0bSAndroid Build Coastguard Worker 
520*08b48e0bSAndroid Build Coastguard Worker             if (debug)
521*08b48e0bSAndroid Build Coastguard Worker               DEBUGF(
522*08b48e0bSAndroid Build Coastguard Worker                   "Function %s is in the allow function list, instrumenting "
523*08b48e0bSAndroid Build Coastguard Worker                   "... \n",
524*08b48e0bSAndroid Build Coastguard Worker                   instFunction.c_str());
525*08b48e0bSAndroid Build Coastguard Worker             return true;
526*08b48e0bSAndroid Build Coastguard Worker 
527*08b48e0bSAndroid Build Coastguard Worker           }
528*08b48e0bSAndroid Build Coastguard Worker 
529*08b48e0bSAndroid Build Coastguard Worker         }
530*08b48e0bSAndroid Build Coastguard Worker 
531*08b48e0bSAndroid Build Coastguard Worker       }
532*08b48e0bSAndroid Build Coastguard Worker 
533*08b48e0bSAndroid Build Coastguard Worker     }
534*08b48e0bSAndroid Build Coastguard Worker 
535*08b48e0bSAndroid Build Coastguard Worker     if (!allowListFiles.empty()) {
536*08b48e0bSAndroid Build Coastguard Worker 
537*08b48e0bSAndroid Build Coastguard Worker       std::string source_file = getSourceName(F);
538*08b48e0bSAndroid Build Coastguard Worker 
539*08b48e0bSAndroid Build Coastguard Worker       if (source_file.empty()) { source_file = Filename; }
540*08b48e0bSAndroid Build Coastguard Worker 
541*08b48e0bSAndroid Build Coastguard Worker       if (!source_file.empty()) {
542*08b48e0bSAndroid Build Coastguard Worker 
543*08b48e0bSAndroid Build Coastguard Worker         for (std::list<std::string>::iterator it = allowListFiles.begin();
544*08b48e0bSAndroid Build Coastguard Worker              it != allowListFiles.end(); ++it) {
545*08b48e0bSAndroid Build Coastguard Worker 
546*08b48e0bSAndroid Build Coastguard Worker           /* We don't check for filename equality here because
547*08b48e0bSAndroid Build Coastguard Worker            * filenames might actually be full paths. Instead we
548*08b48e0bSAndroid Build Coastguard Worker            * check that the actual filename ends in the filename
549*08b48e0bSAndroid Build Coastguard Worker            * specified in the list. We also allow UNIX-style pattern
550*08b48e0bSAndroid Build Coastguard Worker            * matching */
551*08b48e0bSAndroid Build Coastguard Worker 
552*08b48e0bSAndroid Build Coastguard Worker           if (source_file.length() >= it->length()) {
553*08b48e0bSAndroid Build Coastguard Worker 
554*08b48e0bSAndroid Build Coastguard Worker             if (fnmatch(("*" + *it).c_str(), source_file.c_str(), 0) == 0) {
555*08b48e0bSAndroid Build Coastguard Worker 
556*08b48e0bSAndroid Build Coastguard Worker               if (debug)
557*08b48e0bSAndroid Build Coastguard Worker                 DEBUGF(
558*08b48e0bSAndroid Build Coastguard Worker                     "Function %s is in the allowlist (%s), instrumenting ... "
559*08b48e0bSAndroid Build Coastguard Worker                     "\n",
560*08b48e0bSAndroid Build Coastguard Worker                     F->getName().str().c_str(), source_file.c_str());
561*08b48e0bSAndroid Build Coastguard Worker               return true;
562*08b48e0bSAndroid Build Coastguard Worker 
563*08b48e0bSAndroid Build Coastguard Worker             }
564*08b48e0bSAndroid Build Coastguard Worker 
565*08b48e0bSAndroid Build Coastguard Worker           }
566*08b48e0bSAndroid Build Coastguard Worker 
567*08b48e0bSAndroid Build Coastguard Worker         }
568*08b48e0bSAndroid Build Coastguard Worker 
569*08b48e0bSAndroid Build Coastguard Worker       } else {
570*08b48e0bSAndroid Build Coastguard Worker 
571*08b48e0bSAndroid Build Coastguard Worker         // we could not find out the location. In this case we say it is not
572*08b48e0bSAndroid Build Coastguard Worker         // in the instrument file list
573*08b48e0bSAndroid Build Coastguard Worker         if (!be_quiet)
574*08b48e0bSAndroid Build Coastguard Worker           WARNF(
575*08b48e0bSAndroid Build Coastguard Worker               "No debug information found for function %s, will not be "
576*08b48e0bSAndroid Build Coastguard Worker               "instrumented (recompile with -g -O[1-3] and use a modern llvm).",
577*08b48e0bSAndroid Build Coastguard Worker               F->getName().str().c_str());
578*08b48e0bSAndroid Build Coastguard Worker         return false;
579*08b48e0bSAndroid Build Coastguard Worker 
580*08b48e0bSAndroid Build Coastguard Worker       }
581*08b48e0bSAndroid Build Coastguard Worker 
582*08b48e0bSAndroid Build Coastguard Worker     }
583*08b48e0bSAndroid Build Coastguard Worker 
584*08b48e0bSAndroid Build Coastguard Worker   }
585*08b48e0bSAndroid Build Coastguard Worker 
586*08b48e0bSAndroid Build Coastguard Worker   return return_default;
587*08b48e0bSAndroid Build Coastguard Worker 
588*08b48e0bSAndroid Build Coastguard Worker }
589*08b48e0bSAndroid Build Coastguard Worker 
590*08b48e0bSAndroid Build Coastguard Worker // Calculate the number of average collisions that would occur if all
591*08b48e0bSAndroid Build Coastguard Worker // location IDs would be assigned randomly (like normal afl/AFL++).
592*08b48e0bSAndroid Build Coastguard Worker // This uses the "balls in bins" algorithm.
calculateCollisions(uint32_t edges)593*08b48e0bSAndroid Build Coastguard Worker unsigned long long int calculateCollisions(uint32_t edges) {
594*08b48e0bSAndroid Build Coastguard Worker 
595*08b48e0bSAndroid Build Coastguard Worker   double                 bins = MAP_SIZE;
596*08b48e0bSAndroid Build Coastguard Worker   double                 balls = edges;
597*08b48e0bSAndroid Build Coastguard Worker   double                 step1 = 1 - (1 / bins);
598*08b48e0bSAndroid Build Coastguard Worker   double                 step2 = pow(step1, balls);
599*08b48e0bSAndroid Build Coastguard Worker   double                 step3 = bins * step2;
600*08b48e0bSAndroid Build Coastguard Worker   double                 step4 = round(step3);
601*08b48e0bSAndroid Build Coastguard Worker   unsigned long long int empty = step4;
602*08b48e0bSAndroid Build Coastguard Worker   unsigned long long int collisions = edges - (MAP_SIZE - empty);
603*08b48e0bSAndroid Build Coastguard Worker   return collisions;
604*08b48e0bSAndroid Build Coastguard Worker 
605*08b48e0bSAndroid Build Coastguard Worker }
606*08b48e0bSAndroid Build Coastguard Worker 
607