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