xref: /aosp_15_r20/external/AFLplusplus/instrumentation/afl-gcc-common.h (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker /* GCC plugin common infrastructure for AFL++ instrumentation passes.
2*08b48e0bSAndroid Build Coastguard Worker 
3*08b48e0bSAndroid Build Coastguard Worker    Copyright 2014-2019 Free Software Foundation, Inc
4*08b48e0bSAndroid Build Coastguard Worker    Copyright 2015, 2016 Google Inc. All rights reserved.
5*08b48e0bSAndroid Build Coastguard Worker    Copyright 2019-2024 AdaCore
6*08b48e0bSAndroid Build Coastguard Worker 
7*08b48e0bSAndroid Build Coastguard Worker    Written by Alexandre Oliva <[email protected]>, based on the AFL++
8*08b48e0bSAndroid Build Coastguard Worker    GCC plugin.
9*08b48e0bSAndroid Build Coastguard Worker 
10*08b48e0bSAndroid Build Coastguard Worker    This program is free software: you can redistribute it and/or modify
11*08b48e0bSAndroid Build Coastguard Worker    it under the terms of the GNU General Public License as published by
12*08b48e0bSAndroid Build Coastguard Worker    the Free Software Foundation, either version 3 of the License, or
13*08b48e0bSAndroid Build Coastguard Worker    (at your option) any later version.
14*08b48e0bSAndroid Build Coastguard Worker 
15*08b48e0bSAndroid Build Coastguard Worker    This program is distributed in the hope that it will be useful,
16*08b48e0bSAndroid Build Coastguard Worker    but WITHOUT ANY WARRANTY; without even the implied warranty of
17*08b48e0bSAndroid Build Coastguard Worker    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*08b48e0bSAndroid Build Coastguard Worker    GNU General Public License for more details.
19*08b48e0bSAndroid Build Coastguard Worker 
20*08b48e0bSAndroid Build Coastguard Worker    You should have received a copy of the GNU General Public License
21*08b48e0bSAndroid Build Coastguard Worker    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22*08b48e0bSAndroid Build Coastguard Worker 
23*08b48e0bSAndroid Build Coastguard Worker  */
24*08b48e0bSAndroid Build Coastguard Worker 
25*08b48e0bSAndroid Build Coastguard Worker #include "../include/config.h"
26*08b48e0bSAndroid Build Coastguard Worker #include "../include/debug.h"
27*08b48e0bSAndroid Build Coastguard Worker 
28*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
29*08b48e0bSAndroid Build Coastguard Worker #include <stdlib.h>
30*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h>
31*08b48e0bSAndroid Build Coastguard Worker 
32*08b48e0bSAndroid Build Coastguard Worker #ifdef likely
33*08b48e0bSAndroid Build Coastguard Worker   #undef likely
34*08b48e0bSAndroid Build Coastguard Worker #endif
35*08b48e0bSAndroid Build Coastguard Worker #ifdef unlikely
36*08b48e0bSAndroid Build Coastguard Worker   #undef unlikely
37*08b48e0bSAndroid Build Coastguard Worker #endif
38*08b48e0bSAndroid Build Coastguard Worker 
39*08b48e0bSAndroid Build Coastguard Worker #include <list>
40*08b48e0bSAndroid Build Coastguard Worker #include <string>
41*08b48e0bSAndroid Build Coastguard Worker #include <fstream>
42*08b48e0bSAndroid Build Coastguard Worker 
43*08b48e0bSAndroid Build Coastguard Worker #include <algorithm>
44*08b48e0bSAndroid Build Coastguard Worker #include <fnmatch.h>
45*08b48e0bSAndroid Build Coastguard Worker 
46*08b48e0bSAndroid Build Coastguard Worker #include <gcc-plugin.h>
47*08b48e0bSAndroid Build Coastguard Worker #include <plugin-version.h>
48*08b48e0bSAndroid Build Coastguard Worker #include <toplev.h>
49*08b48e0bSAndroid Build Coastguard Worker #include <tree-pass.h>
50*08b48e0bSAndroid Build Coastguard Worker #include <context.h>
51*08b48e0bSAndroid Build Coastguard Worker #include <tree.h>
52*08b48e0bSAndroid Build Coastguard Worker #include <gimplify.h>
53*08b48e0bSAndroid Build Coastguard Worker #include <basic-block.h>
54*08b48e0bSAndroid Build Coastguard Worker #include <tree-ssa-alias.h>
55*08b48e0bSAndroid Build Coastguard Worker #include <gimple-expr.h>
56*08b48e0bSAndroid Build Coastguard Worker #include <gimple.h>
57*08b48e0bSAndroid Build Coastguard Worker #include <gimple-iterator.h>
58*08b48e0bSAndroid Build Coastguard Worker #include <stringpool.h>
59*08b48e0bSAndroid Build Coastguard Worker #include <gimple-ssa.h>
60*08b48e0bSAndroid Build Coastguard Worker #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \
61*08b48e0bSAndroid Build Coastguard Worker     60200                                               /* >= version 6.2.0 */
62*08b48e0bSAndroid Build Coastguard Worker   #include <tree-vrp.h>
63*08b48e0bSAndroid Build Coastguard Worker #endif
64*08b48e0bSAndroid Build Coastguard Worker #include <tree-ssanames.h>
65*08b48e0bSAndroid Build Coastguard Worker #include <tree-phinodes.h>
66*08b48e0bSAndroid Build Coastguard Worker #include <ssa-iterators.h>
67*08b48e0bSAndroid Build Coastguard Worker 
68*08b48e0bSAndroid Build Coastguard Worker #include <intl.h>
69*08b48e0bSAndroid Build Coastguard Worker 
70*08b48e0bSAndroid Build Coastguard Worker namespace {
71*08b48e0bSAndroid Build Coastguard Worker 
72*08b48e0bSAndroid Build Coastguard Worker struct afl_base_pass : gimple_opt_pass {
73*08b48e0bSAndroid Build Coastguard Worker 
afl_base_passafl_base_pass74*08b48e0bSAndroid Build Coastguard Worker   afl_base_pass(bool quiet, bool debug, struct pass_data const &pd)
75*08b48e0bSAndroid Build Coastguard Worker       : gimple_opt_pass(pd, g), be_quiet(quiet), debug(debug) {
76*08b48e0bSAndroid Build Coastguard Worker 
77*08b48e0bSAndroid Build Coastguard Worker     initInstrumentList();
78*08b48e0bSAndroid Build Coastguard Worker 
79*08b48e0bSAndroid Build Coastguard Worker   }
80*08b48e0bSAndroid Build Coastguard Worker 
81*08b48e0bSAndroid Build Coastguard Worker   /* Are we outputting to a non-terminal, or running with AFL_QUIET
82*08b48e0bSAndroid Build Coastguard Worker      set?  */
83*08b48e0bSAndroid Build Coastguard Worker   const bool be_quiet;
84*08b48e0bSAndroid Build Coastguard Worker 
85*08b48e0bSAndroid Build Coastguard Worker   /* Are we running with AFL_DEBUG set?  */
86*08b48e0bSAndroid Build Coastguard Worker   const bool debug;
87*08b48e0bSAndroid Build Coastguard Worker 
88*08b48e0bSAndroid Build Coastguard Worker #define report_fatal_error(msg) BADF(msg)
89*08b48e0bSAndroid Build Coastguard Worker 
90*08b48e0bSAndroid Build Coastguard Worker   std::list<std::string> allowListFiles;
91*08b48e0bSAndroid Build Coastguard Worker   std::list<std::string> allowListFunctions;
92*08b48e0bSAndroid Build Coastguard Worker   std::list<std::string> denyListFiles;
93*08b48e0bSAndroid Build Coastguard Worker   std::list<std::string> denyListFunctions;
94*08b48e0bSAndroid Build Coastguard Worker 
95*08b48e0bSAndroid Build Coastguard Worker   /* Note: this ignore check is also called in isInInstrumentList() */
isIgnoreFunctionafl_base_pass96*08b48e0bSAndroid Build Coastguard Worker   bool isIgnoreFunction(function *F) {
97*08b48e0bSAndroid Build Coastguard Worker 
98*08b48e0bSAndroid Build Coastguard Worker     // Starting from "LLVMFuzzer" these are functions used in libfuzzer based
99*08b48e0bSAndroid Build Coastguard Worker     // fuzzing campaign installations, e.g. oss-fuzz
100*08b48e0bSAndroid Build Coastguard Worker 
101*08b48e0bSAndroid Build Coastguard Worker     static constexpr const char *ignoreList[] = {
102*08b48e0bSAndroid Build Coastguard Worker 
103*08b48e0bSAndroid Build Coastguard Worker         "asan.",
104*08b48e0bSAndroid Build Coastguard Worker         "llvm.",
105*08b48e0bSAndroid Build Coastguard Worker         "sancov.",
106*08b48e0bSAndroid Build Coastguard Worker         "__ubsan_",
107*08b48e0bSAndroid Build Coastguard Worker         "ign.",
108*08b48e0bSAndroid Build Coastguard Worker         "__afl_",
109*08b48e0bSAndroid Build Coastguard Worker         "_fini",
110*08b48e0bSAndroid Build Coastguard Worker         "__libc_csu",
111*08b48e0bSAndroid Build Coastguard Worker         "__asan",
112*08b48e0bSAndroid Build Coastguard Worker         "__msan",
113*08b48e0bSAndroid Build Coastguard Worker         "__cmplog",
114*08b48e0bSAndroid Build Coastguard Worker         "__sancov",
115*08b48e0bSAndroid Build Coastguard Worker         "msan.",
116*08b48e0bSAndroid Build Coastguard Worker         "LLVMFuzzerM",
117*08b48e0bSAndroid Build Coastguard Worker         "LLVMFuzzerC",
118*08b48e0bSAndroid Build Coastguard Worker         "LLVMFuzzerI",
119*08b48e0bSAndroid Build Coastguard Worker         "__decide_deferred",
120*08b48e0bSAndroid Build Coastguard Worker         "maybe_duplicate_stderr",
121*08b48e0bSAndroid Build Coastguard Worker         "discard_output",
122*08b48e0bSAndroid Build Coastguard Worker         "close_stdout",
123*08b48e0bSAndroid Build Coastguard Worker         "dup_and_close_stderr",
124*08b48e0bSAndroid Build Coastguard Worker         "maybe_close_fd_mask",
125*08b48e0bSAndroid Build Coastguard Worker         "ExecuteFilesOnyByOne"
126*08b48e0bSAndroid Build Coastguard Worker 
127*08b48e0bSAndroid Build Coastguard Worker     };
128*08b48e0bSAndroid Build Coastguard Worker 
129*08b48e0bSAndroid Build Coastguard Worker     const char *name = IDENTIFIER_POINTER(DECL_NAME(F->decl));
130*08b48e0bSAndroid Build Coastguard Worker     int         len = IDENTIFIER_LENGTH(DECL_NAME(F->decl));
131*08b48e0bSAndroid Build Coastguard Worker 
132*08b48e0bSAndroid Build Coastguard Worker     for (auto const &ignoreListFunc : ignoreList) {
133*08b48e0bSAndroid Build Coastguard Worker 
134*08b48e0bSAndroid Build Coastguard Worker       if (strncmp(name, ignoreListFunc, len) == 0) { return true; }
135*08b48e0bSAndroid Build Coastguard Worker 
136*08b48e0bSAndroid Build Coastguard Worker     }
137*08b48e0bSAndroid Build Coastguard Worker 
138*08b48e0bSAndroid Build Coastguard Worker     return false;
139*08b48e0bSAndroid Build Coastguard Worker 
140*08b48e0bSAndroid Build Coastguard Worker   }
141*08b48e0bSAndroid Build Coastguard Worker 
initInstrumentListafl_base_pass142*08b48e0bSAndroid Build Coastguard Worker   void initInstrumentList() {
143*08b48e0bSAndroid Build Coastguard Worker 
144*08b48e0bSAndroid Build Coastguard Worker     char *allowlist = getenv("AFL_GCC_ALLOWLIST");
145*08b48e0bSAndroid Build Coastguard Worker     if (!allowlist) allowlist = getenv("AFL_GCC_INSTRUMENT_FILE");
146*08b48e0bSAndroid Build Coastguard Worker     if (!allowlist) allowlist = getenv("AFL_GCC_WHITELIST");
147*08b48e0bSAndroid Build Coastguard Worker     if (!allowlist) allowlist = getenv("AFL_LLVM_ALLOWLIST");
148*08b48e0bSAndroid Build Coastguard Worker     if (!allowlist) allowlist = getenv("AFL_LLVM_INSTRUMENT_FILE");
149*08b48e0bSAndroid Build Coastguard Worker     if (!allowlist) allowlist = getenv("AFL_LLVM_WHITELIST");
150*08b48e0bSAndroid Build Coastguard Worker     char *denylist = getenv("AFL_GCC_DENYLIST");
151*08b48e0bSAndroid Build Coastguard Worker     if (!denylist) denylist = getenv("AFL_GCC_BLOCKLIST");
152*08b48e0bSAndroid Build Coastguard Worker     if (!denylist) denylist = getenv("AFL_LLVM_DENYLIST");
153*08b48e0bSAndroid Build Coastguard Worker     if (!denylist) denylist = getenv("AFL_LLVM_BLOCKLIST");
154*08b48e0bSAndroid Build Coastguard Worker 
155*08b48e0bSAndroid Build Coastguard Worker     if (allowlist && denylist)
156*08b48e0bSAndroid Build Coastguard Worker       FATAL(
157*08b48e0bSAndroid Build Coastguard Worker           "You can only specify either AFL_GCC_ALLOWLIST or AFL_GCC_DENYLIST "
158*08b48e0bSAndroid Build Coastguard Worker           "but not both!");
159*08b48e0bSAndroid Build Coastguard Worker 
160*08b48e0bSAndroid Build Coastguard Worker     if (allowlist) {
161*08b48e0bSAndroid Build Coastguard Worker 
162*08b48e0bSAndroid Build Coastguard Worker       std::string   line;
163*08b48e0bSAndroid Build Coastguard Worker       std::ifstream fileStream;
164*08b48e0bSAndroid Build Coastguard Worker       fileStream.open(allowlist);
165*08b48e0bSAndroid Build Coastguard Worker       if (!fileStream) report_fatal_error("Unable to open AFL_GCC_ALLOWLIST");
166*08b48e0bSAndroid Build Coastguard Worker       getline(fileStream, line);
167*08b48e0bSAndroid Build Coastguard Worker 
168*08b48e0bSAndroid Build Coastguard Worker       while (fileStream) {
169*08b48e0bSAndroid Build Coastguard Worker 
170*08b48e0bSAndroid Build Coastguard Worker         int         is_file = -1;
171*08b48e0bSAndroid Build Coastguard Worker         std::size_t npos;
172*08b48e0bSAndroid Build Coastguard Worker         std::string original_line = line;
173*08b48e0bSAndroid Build Coastguard Worker 
174*08b48e0bSAndroid Build Coastguard Worker         line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
175*08b48e0bSAndroid Build Coastguard Worker                    line.end());
176*08b48e0bSAndroid Build Coastguard Worker 
177*08b48e0bSAndroid Build Coastguard Worker         // remove # and following
178*08b48e0bSAndroid Build Coastguard Worker         if ((npos = line.find("#")) != std::string::npos)
179*08b48e0bSAndroid Build Coastguard Worker           line = line.substr(0, npos);
180*08b48e0bSAndroid Build Coastguard Worker 
181*08b48e0bSAndroid Build Coastguard Worker         if (line.compare(0, 4, "fun:") == 0) {
182*08b48e0bSAndroid Build Coastguard Worker 
183*08b48e0bSAndroid Build Coastguard Worker           is_file = 0;
184*08b48e0bSAndroid Build Coastguard Worker           line = line.substr(4);
185*08b48e0bSAndroid Build Coastguard Worker 
186*08b48e0bSAndroid Build Coastguard Worker         } else if (line.compare(0, 9, "function:") == 0) {
187*08b48e0bSAndroid Build Coastguard Worker 
188*08b48e0bSAndroid Build Coastguard Worker           is_file = 0;
189*08b48e0bSAndroid Build Coastguard Worker           line = line.substr(9);
190*08b48e0bSAndroid Build Coastguard Worker 
191*08b48e0bSAndroid Build Coastguard Worker         } else if (line.compare(0, 4, "src:") == 0) {
192*08b48e0bSAndroid Build Coastguard Worker 
193*08b48e0bSAndroid Build Coastguard Worker           is_file = 1;
194*08b48e0bSAndroid Build Coastguard Worker           line = line.substr(4);
195*08b48e0bSAndroid Build Coastguard Worker 
196*08b48e0bSAndroid Build Coastguard Worker         } else if (line.compare(0, 7, "source:") == 0) {
197*08b48e0bSAndroid Build Coastguard Worker 
198*08b48e0bSAndroid Build Coastguard Worker           is_file = 1;
199*08b48e0bSAndroid Build Coastguard Worker           line = line.substr(7);
200*08b48e0bSAndroid Build Coastguard Worker 
201*08b48e0bSAndroid Build Coastguard Worker         }
202*08b48e0bSAndroid Build Coastguard Worker 
203*08b48e0bSAndroid Build Coastguard Worker         if (line.find(":") != std::string::npos) {
204*08b48e0bSAndroid Build Coastguard Worker 
205*08b48e0bSAndroid Build Coastguard Worker           FATAL("invalid line in AFL_GCC_ALLOWLIST: %s", original_line.c_str());
206*08b48e0bSAndroid Build Coastguard Worker 
207*08b48e0bSAndroid Build Coastguard Worker         }
208*08b48e0bSAndroid Build Coastguard Worker 
209*08b48e0bSAndroid Build Coastguard Worker         if (line.length() > 0) {
210*08b48e0bSAndroid Build Coastguard Worker 
211*08b48e0bSAndroid Build Coastguard Worker           // if the entry contains / or . it must be a file
212*08b48e0bSAndroid Build Coastguard Worker           if (is_file == -1)
213*08b48e0bSAndroid Build Coastguard Worker             if (line.find("/") != std::string::npos ||
214*08b48e0bSAndroid Build Coastguard Worker                 line.find(".") != std::string::npos)
215*08b48e0bSAndroid Build Coastguard Worker               is_file = 1;
216*08b48e0bSAndroid Build Coastguard Worker           // otherwise it is a function
217*08b48e0bSAndroid Build Coastguard Worker 
218*08b48e0bSAndroid Build Coastguard Worker           if (is_file == 1)
219*08b48e0bSAndroid Build Coastguard Worker             allowListFiles.push_back(line);
220*08b48e0bSAndroid Build Coastguard Worker           else
221*08b48e0bSAndroid Build Coastguard Worker             allowListFunctions.push_back(line);
222*08b48e0bSAndroid Build Coastguard Worker 
223*08b48e0bSAndroid Build Coastguard Worker         }
224*08b48e0bSAndroid Build Coastguard Worker 
225*08b48e0bSAndroid Build Coastguard Worker         getline(fileStream, line);
226*08b48e0bSAndroid Build Coastguard Worker 
227*08b48e0bSAndroid Build Coastguard Worker       }
228*08b48e0bSAndroid Build Coastguard Worker 
229*08b48e0bSAndroid Build Coastguard Worker       if (debug)
230*08b48e0bSAndroid Build Coastguard Worker         DEBUGF("loaded allowlist with %zu file and %zu function entries\n",
231*08b48e0bSAndroid Build Coastguard Worker                allowListFiles.size(), allowListFunctions.size());
232*08b48e0bSAndroid Build Coastguard Worker 
233*08b48e0bSAndroid Build Coastguard Worker     }
234*08b48e0bSAndroid Build Coastguard Worker 
235*08b48e0bSAndroid Build Coastguard Worker     if (denylist) {
236*08b48e0bSAndroid Build Coastguard Worker 
237*08b48e0bSAndroid Build Coastguard Worker       std::string   line;
238*08b48e0bSAndroid Build Coastguard Worker       std::ifstream fileStream;
239*08b48e0bSAndroid Build Coastguard Worker       fileStream.open(denylist);
240*08b48e0bSAndroid Build Coastguard Worker       if (!fileStream) report_fatal_error("Unable to open AFL_GCC_DENYLIST");
241*08b48e0bSAndroid Build Coastguard Worker       getline(fileStream, line);
242*08b48e0bSAndroid Build Coastguard Worker 
243*08b48e0bSAndroid Build Coastguard Worker       while (fileStream) {
244*08b48e0bSAndroid Build Coastguard Worker 
245*08b48e0bSAndroid Build Coastguard Worker         int         is_file = -1;
246*08b48e0bSAndroid Build Coastguard Worker         std::size_t npos;
247*08b48e0bSAndroid Build Coastguard Worker         std::string original_line = line;
248*08b48e0bSAndroid Build Coastguard Worker 
249*08b48e0bSAndroid Build Coastguard Worker         line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
250*08b48e0bSAndroid Build Coastguard Worker                    line.end());
251*08b48e0bSAndroid Build Coastguard Worker 
252*08b48e0bSAndroid Build Coastguard Worker         // remove # and following
253*08b48e0bSAndroid Build Coastguard Worker         if ((npos = line.find("#")) != std::string::npos)
254*08b48e0bSAndroid Build Coastguard Worker           line = line.substr(0, npos);
255*08b48e0bSAndroid Build Coastguard Worker 
256*08b48e0bSAndroid Build Coastguard Worker         if (line.compare(0, 4, "fun:") == 0) {
257*08b48e0bSAndroid Build Coastguard Worker 
258*08b48e0bSAndroid Build Coastguard Worker           is_file = 0;
259*08b48e0bSAndroid Build Coastguard Worker           line = line.substr(4);
260*08b48e0bSAndroid Build Coastguard Worker 
261*08b48e0bSAndroid Build Coastguard Worker         } else if (line.compare(0, 9, "function:") == 0) {
262*08b48e0bSAndroid Build Coastguard Worker 
263*08b48e0bSAndroid Build Coastguard Worker           is_file = 0;
264*08b48e0bSAndroid Build Coastguard Worker           line = line.substr(9);
265*08b48e0bSAndroid Build Coastguard Worker 
266*08b48e0bSAndroid Build Coastguard Worker         } else if (line.compare(0, 4, "src:") == 0) {
267*08b48e0bSAndroid Build Coastguard Worker 
268*08b48e0bSAndroid Build Coastguard Worker           is_file = 1;
269*08b48e0bSAndroid Build Coastguard Worker           line = line.substr(4);
270*08b48e0bSAndroid Build Coastguard Worker 
271*08b48e0bSAndroid Build Coastguard Worker         } else if (line.compare(0, 7, "source:") == 0) {
272*08b48e0bSAndroid Build Coastguard Worker 
273*08b48e0bSAndroid Build Coastguard Worker           is_file = 1;
274*08b48e0bSAndroid Build Coastguard Worker           line = line.substr(7);
275*08b48e0bSAndroid Build Coastguard Worker 
276*08b48e0bSAndroid Build Coastguard Worker         }
277*08b48e0bSAndroid Build Coastguard Worker 
278*08b48e0bSAndroid Build Coastguard Worker         if (line.find(":") != std::string::npos) {
279*08b48e0bSAndroid Build Coastguard Worker 
280*08b48e0bSAndroid Build Coastguard Worker           FATAL("invalid line in AFL_GCC_DENYLIST: %s", original_line.c_str());
281*08b48e0bSAndroid Build Coastguard Worker 
282*08b48e0bSAndroid Build Coastguard Worker         }
283*08b48e0bSAndroid Build Coastguard Worker 
284*08b48e0bSAndroid Build Coastguard Worker         if (line.length() > 0) {
285*08b48e0bSAndroid Build Coastguard Worker 
286*08b48e0bSAndroid Build Coastguard Worker           // if the entry contains / or . it must be a file
287*08b48e0bSAndroid Build Coastguard Worker           if (is_file == -1)
288*08b48e0bSAndroid Build Coastguard Worker             if (line.find("/") != std::string::npos ||
289*08b48e0bSAndroid Build Coastguard Worker                 line.find(".") != std::string::npos)
290*08b48e0bSAndroid Build Coastguard Worker               is_file = 1;
291*08b48e0bSAndroid Build Coastguard Worker           // otherwise it is a function
292*08b48e0bSAndroid Build Coastguard Worker 
293*08b48e0bSAndroid Build Coastguard Worker           if (is_file == 1)
294*08b48e0bSAndroid Build Coastguard Worker             denyListFiles.push_back(line);
295*08b48e0bSAndroid Build Coastguard Worker           else
296*08b48e0bSAndroid Build Coastguard Worker             denyListFunctions.push_back(line);
297*08b48e0bSAndroid Build Coastguard Worker 
298*08b48e0bSAndroid Build Coastguard Worker         }
299*08b48e0bSAndroid Build Coastguard Worker 
300*08b48e0bSAndroid Build Coastguard Worker         getline(fileStream, line);
301*08b48e0bSAndroid Build Coastguard Worker 
302*08b48e0bSAndroid Build Coastguard Worker       }
303*08b48e0bSAndroid Build Coastguard Worker 
304*08b48e0bSAndroid Build Coastguard Worker       if (debug)
305*08b48e0bSAndroid Build Coastguard Worker         DEBUGF("loaded denylist with %zu file and %zu function entries\n",
306*08b48e0bSAndroid Build Coastguard Worker                denyListFiles.size(), denyListFunctions.size());
307*08b48e0bSAndroid Build Coastguard Worker 
308*08b48e0bSAndroid Build Coastguard Worker     }
309*08b48e0bSAndroid Build Coastguard Worker 
310*08b48e0bSAndroid Build Coastguard Worker   }
311*08b48e0bSAndroid Build Coastguard Worker 
312*08b48e0bSAndroid Build Coastguard Worker   /* Returns the source file name attached to the function declaration F. If
313*08b48e0bSAndroid Build Coastguard Worker      there is no source location information, returns an empty string.  */
getSourceNameafl_base_pass314*08b48e0bSAndroid Build Coastguard Worker   std::string getSourceName(function *F) {
315*08b48e0bSAndroid Build Coastguard Worker 
316*08b48e0bSAndroid Build Coastguard Worker     return DECL_SOURCE_FILE(F->decl) ? DECL_SOURCE_FILE(F->decl) : "";
317*08b48e0bSAndroid Build Coastguard Worker 
318*08b48e0bSAndroid Build Coastguard Worker   }
319*08b48e0bSAndroid Build Coastguard Worker 
isInInstrumentListafl_base_pass320*08b48e0bSAndroid Build Coastguard Worker   bool isInInstrumentList(function *F) {
321*08b48e0bSAndroid Build Coastguard Worker 
322*08b48e0bSAndroid Build Coastguard Worker     bool return_default = true;
323*08b48e0bSAndroid Build Coastguard Worker 
324*08b48e0bSAndroid Build Coastguard Worker     // is this a function with code? If it is external we don't instrument it
325*08b48e0bSAndroid Build Coastguard Worker     // anyway and it can't be in the instrument file list. Or if it is it is
326*08b48e0bSAndroid Build Coastguard Worker     // ignored.
327*08b48e0bSAndroid Build Coastguard Worker     if (isIgnoreFunction(F)) return false;
328*08b48e0bSAndroid Build Coastguard Worker 
329*08b48e0bSAndroid Build Coastguard Worker     if (!denyListFiles.empty() || !denyListFunctions.empty()) {
330*08b48e0bSAndroid Build Coastguard Worker 
331*08b48e0bSAndroid Build Coastguard Worker       if (!denyListFunctions.empty()) {
332*08b48e0bSAndroid Build Coastguard Worker 
333*08b48e0bSAndroid Build Coastguard Worker         std::string instFunction = IDENTIFIER_POINTER(DECL_NAME(F->decl));
334*08b48e0bSAndroid Build Coastguard Worker 
335*08b48e0bSAndroid Build Coastguard Worker         for (std::list<std::string>::iterator it = denyListFunctions.begin();
336*08b48e0bSAndroid Build Coastguard Worker              it != denyListFunctions.end(); ++it) {
337*08b48e0bSAndroid Build Coastguard Worker 
338*08b48e0bSAndroid Build Coastguard Worker           /* We don't check for filename equality here because
339*08b48e0bSAndroid Build Coastguard Worker            * filenames might actually be full paths. Instead we
340*08b48e0bSAndroid Build Coastguard Worker            * check that the actual filename ends in the filename
341*08b48e0bSAndroid Build Coastguard Worker            * specified in the list. We also allow UNIX-style pattern
342*08b48e0bSAndroid Build Coastguard Worker            * matching */
343*08b48e0bSAndroid Build Coastguard Worker 
344*08b48e0bSAndroid Build Coastguard Worker           if (instFunction.length() >= it->length()) {
345*08b48e0bSAndroid Build Coastguard Worker 
346*08b48e0bSAndroid Build Coastguard Worker             if (fnmatch(("*" + *it).c_str(), instFunction.c_str(), 0) == 0) {
347*08b48e0bSAndroid Build Coastguard Worker 
348*08b48e0bSAndroid Build Coastguard Worker               if (debug)
349*08b48e0bSAndroid Build Coastguard Worker                 DEBUGF(
350*08b48e0bSAndroid Build Coastguard Worker                     "Function %s is in the deny function list, not "
351*08b48e0bSAndroid Build Coastguard Worker                     "instrumenting ... \n",
352*08b48e0bSAndroid Build Coastguard Worker                     instFunction.c_str());
353*08b48e0bSAndroid Build Coastguard Worker               return false;
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 
359*08b48e0bSAndroid Build Coastguard Worker         }
360*08b48e0bSAndroid Build Coastguard Worker 
361*08b48e0bSAndroid Build Coastguard Worker       }
362*08b48e0bSAndroid Build Coastguard Worker 
363*08b48e0bSAndroid Build Coastguard Worker       if (!denyListFiles.empty()) {
364*08b48e0bSAndroid Build Coastguard Worker 
365*08b48e0bSAndroid Build Coastguard Worker         std::string source_file = getSourceName(F);
366*08b48e0bSAndroid Build Coastguard Worker 
367*08b48e0bSAndroid Build Coastguard Worker         if (!source_file.empty()) {
368*08b48e0bSAndroid Build Coastguard Worker 
369*08b48e0bSAndroid Build Coastguard Worker           for (std::list<std::string>::iterator it = denyListFiles.begin();
370*08b48e0bSAndroid Build Coastguard Worker                it != denyListFiles.end(); ++it) {
371*08b48e0bSAndroid Build Coastguard Worker 
372*08b48e0bSAndroid Build Coastguard Worker             /* We don't check for filename equality here because
373*08b48e0bSAndroid Build Coastguard Worker              * filenames might actually be full paths. Instead we
374*08b48e0bSAndroid Build Coastguard Worker              * check that the actual filename ends in the filename
375*08b48e0bSAndroid Build Coastguard Worker              * specified in the list. We also allow UNIX-style pattern
376*08b48e0bSAndroid Build Coastguard Worker              * matching */
377*08b48e0bSAndroid Build Coastguard Worker 
378*08b48e0bSAndroid Build Coastguard Worker             if (source_file.length() >= it->length()) {
379*08b48e0bSAndroid Build Coastguard Worker 
380*08b48e0bSAndroid Build Coastguard Worker               if (fnmatch(("*" + *it).c_str(), source_file.c_str(), 0) == 0) {
381*08b48e0bSAndroid Build Coastguard Worker 
382*08b48e0bSAndroid Build Coastguard Worker                 return false;
383*08b48e0bSAndroid Build Coastguard Worker 
384*08b48e0bSAndroid Build Coastguard Worker               }
385*08b48e0bSAndroid Build Coastguard Worker 
386*08b48e0bSAndroid Build Coastguard Worker             }
387*08b48e0bSAndroid Build Coastguard Worker 
388*08b48e0bSAndroid Build Coastguard Worker           }
389*08b48e0bSAndroid Build Coastguard Worker 
390*08b48e0bSAndroid Build Coastguard Worker         } else {
391*08b48e0bSAndroid Build Coastguard Worker 
392*08b48e0bSAndroid Build Coastguard Worker           // we could not find out the location. in this case we say it is not
393*08b48e0bSAndroid Build Coastguard Worker           // in the instrument file list
394*08b48e0bSAndroid Build Coastguard Worker           if (!be_quiet)
395*08b48e0bSAndroid Build Coastguard Worker             WARNF(
396*08b48e0bSAndroid Build Coastguard Worker                 "No debug information found for function %s, will be "
397*08b48e0bSAndroid Build Coastguard Worker                 "instrumented (recompile with -g -O[1-3]).",
398*08b48e0bSAndroid Build Coastguard Worker                 IDENTIFIER_POINTER(DECL_NAME(F->decl)));
399*08b48e0bSAndroid Build Coastguard Worker 
400*08b48e0bSAndroid Build Coastguard Worker         }
401*08b48e0bSAndroid Build Coastguard Worker 
402*08b48e0bSAndroid Build Coastguard Worker       }
403*08b48e0bSAndroid Build Coastguard Worker 
404*08b48e0bSAndroid Build Coastguard Worker     }
405*08b48e0bSAndroid Build Coastguard Worker 
406*08b48e0bSAndroid Build Coastguard Worker     // if we do not have a instrument file list return true
407*08b48e0bSAndroid Build Coastguard Worker     if (!allowListFiles.empty() || !allowListFunctions.empty()) {
408*08b48e0bSAndroid Build Coastguard Worker 
409*08b48e0bSAndroid Build Coastguard Worker       return_default = false;
410*08b48e0bSAndroid Build Coastguard Worker 
411*08b48e0bSAndroid Build Coastguard Worker       if (!allowListFunctions.empty()) {
412*08b48e0bSAndroid Build Coastguard Worker 
413*08b48e0bSAndroid Build Coastguard Worker         std::string instFunction = IDENTIFIER_POINTER(DECL_NAME(F->decl));
414*08b48e0bSAndroid Build Coastguard Worker 
415*08b48e0bSAndroid Build Coastguard Worker         for (std::list<std::string>::iterator it = allowListFunctions.begin();
416*08b48e0bSAndroid Build Coastguard Worker              it != allowListFunctions.end(); ++it) {
417*08b48e0bSAndroid Build Coastguard Worker 
418*08b48e0bSAndroid Build Coastguard Worker           /* We don't check for filename equality here because
419*08b48e0bSAndroid Build Coastguard Worker            * filenames might actually be full paths. Instead we
420*08b48e0bSAndroid Build Coastguard Worker            * check that the actual filename ends in the filename
421*08b48e0bSAndroid Build Coastguard Worker            * specified in the list. We also allow UNIX-style pattern
422*08b48e0bSAndroid Build Coastguard Worker            * matching */
423*08b48e0bSAndroid Build Coastguard Worker 
424*08b48e0bSAndroid Build Coastguard Worker           if (instFunction.length() >= it->length()) {
425*08b48e0bSAndroid Build Coastguard Worker 
426*08b48e0bSAndroid Build Coastguard Worker             if (fnmatch(("*" + *it).c_str(), instFunction.c_str(), 0) == 0) {
427*08b48e0bSAndroid Build Coastguard Worker 
428*08b48e0bSAndroid Build Coastguard Worker               if (debug)
429*08b48e0bSAndroid Build Coastguard Worker                 DEBUGF(
430*08b48e0bSAndroid Build Coastguard Worker                     "Function %s is in the allow function list, instrumenting "
431*08b48e0bSAndroid Build Coastguard Worker                     "... \n",
432*08b48e0bSAndroid Build Coastguard Worker                     instFunction.c_str());
433*08b48e0bSAndroid Build Coastguard Worker               return true;
434*08b48e0bSAndroid Build Coastguard Worker 
435*08b48e0bSAndroid Build Coastguard Worker             }
436*08b48e0bSAndroid Build Coastguard Worker 
437*08b48e0bSAndroid Build Coastguard Worker           }
438*08b48e0bSAndroid Build Coastguard Worker 
439*08b48e0bSAndroid Build Coastguard Worker         }
440*08b48e0bSAndroid Build Coastguard Worker 
441*08b48e0bSAndroid Build Coastguard Worker       }
442*08b48e0bSAndroid Build Coastguard Worker 
443*08b48e0bSAndroid Build Coastguard Worker       if (!allowListFiles.empty()) {
444*08b48e0bSAndroid Build Coastguard Worker 
445*08b48e0bSAndroid Build Coastguard Worker         std::string source_file = getSourceName(F);
446*08b48e0bSAndroid Build Coastguard Worker 
447*08b48e0bSAndroid Build Coastguard Worker         if (!source_file.empty()) {
448*08b48e0bSAndroid Build Coastguard Worker 
449*08b48e0bSAndroid Build Coastguard Worker           for (std::list<std::string>::iterator it = allowListFiles.begin();
450*08b48e0bSAndroid Build Coastguard Worker                it != allowListFiles.end(); ++it) {
451*08b48e0bSAndroid Build Coastguard Worker 
452*08b48e0bSAndroid Build Coastguard Worker             /* We don't check for filename equality here because
453*08b48e0bSAndroid Build Coastguard Worker              * filenames might actually be full paths. Instead we
454*08b48e0bSAndroid Build Coastguard Worker              * check that the actual filename ends in the filename
455*08b48e0bSAndroid Build Coastguard Worker              * specified in the list. We also allow UNIX-style pattern
456*08b48e0bSAndroid Build Coastguard Worker              * matching */
457*08b48e0bSAndroid Build Coastguard Worker 
458*08b48e0bSAndroid Build Coastguard Worker             if (source_file.length() >= it->length()) {
459*08b48e0bSAndroid Build Coastguard Worker 
460*08b48e0bSAndroid Build Coastguard Worker               if (fnmatch(("*" + *it).c_str(), source_file.c_str(), 0) == 0) {
461*08b48e0bSAndroid Build Coastguard Worker 
462*08b48e0bSAndroid Build Coastguard Worker                 if (debug)
463*08b48e0bSAndroid Build Coastguard Worker                   DEBUGF(
464*08b48e0bSAndroid Build Coastguard Worker                       "Function %s is in the allowlist (%s), instrumenting ... "
465*08b48e0bSAndroid Build Coastguard Worker                       "\n",
466*08b48e0bSAndroid Build Coastguard Worker                       IDENTIFIER_POINTER(DECL_NAME(F->decl)),
467*08b48e0bSAndroid Build Coastguard Worker                       source_file.c_str());
468*08b48e0bSAndroid Build Coastguard Worker                 return true;
469*08b48e0bSAndroid Build Coastguard Worker 
470*08b48e0bSAndroid Build Coastguard Worker               }
471*08b48e0bSAndroid Build Coastguard Worker 
472*08b48e0bSAndroid Build Coastguard Worker             }
473*08b48e0bSAndroid Build Coastguard Worker 
474*08b48e0bSAndroid Build Coastguard Worker           }
475*08b48e0bSAndroid Build Coastguard Worker 
476*08b48e0bSAndroid Build Coastguard Worker         } else {
477*08b48e0bSAndroid Build Coastguard Worker 
478*08b48e0bSAndroid Build Coastguard Worker           // we could not find out the location. In this case we say it is not
479*08b48e0bSAndroid Build Coastguard Worker           // in the instrument file list
480*08b48e0bSAndroid Build Coastguard Worker           if (!be_quiet)
481*08b48e0bSAndroid Build Coastguard Worker             WARNF(
482*08b48e0bSAndroid Build Coastguard Worker                 "No debug information found for function %s, will not be "
483*08b48e0bSAndroid Build Coastguard Worker                 "instrumented (recompile with -g -O[1-3]).",
484*08b48e0bSAndroid Build Coastguard Worker                 IDENTIFIER_POINTER(DECL_NAME(F->decl)));
485*08b48e0bSAndroid Build Coastguard Worker           return false;
486*08b48e0bSAndroid Build Coastguard Worker 
487*08b48e0bSAndroid Build Coastguard Worker         }
488*08b48e0bSAndroid Build Coastguard Worker 
489*08b48e0bSAndroid Build Coastguard Worker       }
490*08b48e0bSAndroid Build Coastguard Worker 
491*08b48e0bSAndroid Build Coastguard Worker     }
492*08b48e0bSAndroid Build Coastguard Worker 
493*08b48e0bSAndroid Build Coastguard Worker     return return_default;
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 
499*08b48e0bSAndroid Build Coastguard Worker }  // namespace
500*08b48e0bSAndroid Build Coastguard Worker 
501*08b48e0bSAndroid Build Coastguard Worker // compatibility for older gcc versions
502*08b48e0bSAndroid Build Coastguard Worker #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \
503*08b48e0bSAndroid Build Coastguard Worker     60200                                               /* >= version 6.2.0 */
504*08b48e0bSAndroid Build Coastguard Worker   #define gimple gimple *
505*08b48e0bSAndroid Build Coastguard Worker #else
506*08b48e0bSAndroid Build Coastguard Worker   #define gimple gimple
507*08b48e0bSAndroid Build Coastguard Worker #endif
508*08b48e0bSAndroid Build Coastguard Worker 
509