1*08b48e0bSAndroid Build Coastguard Worker /* GCC plugin for cmplog routines instrumentation of code for AFL++.
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-2020 AFLplusplus Project. All rights reserved.
6*08b48e0bSAndroid Build Coastguard Worker Copyright 2019-2024 AdaCore
7*08b48e0bSAndroid Build Coastguard Worker
8*08b48e0bSAndroid Build Coastguard Worker Written by Alexandre Oliva <[email protected]>, based on the AFL++
9*08b48e0bSAndroid Build Coastguard Worker LLVM CmpLog Routines pass by Andrea Fioraldi
10*08b48e0bSAndroid Build Coastguard Worker <[email protected]>, and on the AFL GCC CmpLog pass.
11*08b48e0bSAndroid Build Coastguard Worker
12*08b48e0bSAndroid Build Coastguard Worker This program is free software: you can redistribute it and/or modify
13*08b48e0bSAndroid Build Coastguard Worker it under the terms of the GNU General Public License as published by
14*08b48e0bSAndroid Build Coastguard Worker the Free Software Foundation, either version 3 of the License, or
15*08b48e0bSAndroid Build Coastguard Worker (at your option) any later version.
16*08b48e0bSAndroid Build Coastguard Worker
17*08b48e0bSAndroid Build Coastguard Worker This program is distributed in the hope that it will be useful,
18*08b48e0bSAndroid Build Coastguard Worker but WITHOUT ANY WARRANTY; without even the implied warranty of
19*08b48e0bSAndroid Build Coastguard Worker MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20*08b48e0bSAndroid Build Coastguard Worker GNU General Public License for more details.
21*08b48e0bSAndroid Build Coastguard Worker
22*08b48e0bSAndroid Build Coastguard Worker You should have received a copy of the GNU General Public License
23*08b48e0bSAndroid Build Coastguard Worker along with this program. If not, see <http://www.gnu.org/licenses/>.
24*08b48e0bSAndroid Build Coastguard Worker
25*08b48e0bSAndroid Build Coastguard Worker */
26*08b48e0bSAndroid Build Coastguard Worker
27*08b48e0bSAndroid Build Coastguard Worker #include "afl-gcc-common.h"
28*08b48e0bSAndroid Build Coastguard Worker
29*08b48e0bSAndroid Build Coastguard Worker /* This plugin, being under the same license as GCC, satisfies the
30*08b48e0bSAndroid Build Coastguard Worker "GPL-compatible Software" definition in the GCC RUNTIME LIBRARY
31*08b48e0bSAndroid Build Coastguard Worker EXCEPTION, so it can be part of an "Eligible" "Compilation
32*08b48e0bSAndroid Build Coastguard Worker Process". */
33*08b48e0bSAndroid Build Coastguard Worker int plugin_is_GPL_compatible = 1;
34*08b48e0bSAndroid Build Coastguard Worker
35*08b48e0bSAndroid Build Coastguard Worker namespace {
36*08b48e0bSAndroid Build Coastguard Worker
37*08b48e0bSAndroid Build Coastguard Worker static const struct pass_data afl_cmptrs_pass_data = {
38*08b48e0bSAndroid Build Coastguard Worker
39*08b48e0bSAndroid Build Coastguard Worker .type = GIMPLE_PASS,
40*08b48e0bSAndroid Build Coastguard Worker .name = "aflcmptrs",
41*08b48e0bSAndroid Build Coastguard Worker .optinfo_flags = OPTGROUP_NONE,
42*08b48e0bSAndroid Build Coastguard Worker .tv_id = TV_NONE,
43*08b48e0bSAndroid Build Coastguard Worker .properties_required = 0,
44*08b48e0bSAndroid Build Coastguard Worker .properties_provided = 0,
45*08b48e0bSAndroid Build Coastguard Worker .properties_destroyed = 0,
46*08b48e0bSAndroid Build Coastguard Worker .todo_flags_start = 0,
47*08b48e0bSAndroid Build Coastguard Worker .todo_flags_finish = (TODO_update_ssa | TODO_cleanup_cfg | TODO_verify_il |
48*08b48e0bSAndroid Build Coastguard Worker TODO_rebuild_cgraph_edges),
49*08b48e0bSAndroid Build Coastguard Worker
50*08b48e0bSAndroid Build Coastguard Worker };
51*08b48e0bSAndroid Build Coastguard Worker
52*08b48e0bSAndroid Build Coastguard Worker struct afl_cmptrs_pass : afl_base_pass {
53*08b48e0bSAndroid Build Coastguard Worker
afl_cmptrs_pass__anon21d00caf0111::afl_cmptrs_pass54*08b48e0bSAndroid Build Coastguard Worker afl_cmptrs_pass(bool quiet)
55*08b48e0bSAndroid Build Coastguard Worker : afl_base_pass(quiet, /*debug=*/false, afl_cmptrs_pass_data),
56*08b48e0bSAndroid Build Coastguard Worker tp8u(),
57*08b48e0bSAndroid Build Coastguard Worker cmptrs_hooks() {
58*08b48e0bSAndroid Build Coastguard Worker
59*08b48e0bSAndroid Build Coastguard Worker }
60*08b48e0bSAndroid Build Coastguard Worker
61*08b48e0bSAndroid Build Coastguard Worker /* A pointer type to a unsigned 8-bit integral type. */
62*08b48e0bSAndroid Build Coastguard Worker tree tp8u;
63*08b48e0bSAndroid Build Coastguard Worker
64*08b48e0bSAndroid Build Coastguard Worker /* Declarations for the various cmptrs hook functions, allocated on
65*08b48e0bSAndroid Build Coastguard Worker demand.. [0] is for compares between any pointers, [1] is for
66*08b48e0bSAndroid Build Coastguard Worker compares between G++ std::string, [2] is for compares between G++
67*08b48e0bSAndroid Build Coastguard Worker std::string and GCC C strings, [3] and [4] are analogous to [1]
68*08b48e0bSAndroid Build Coastguard Worker and [2] but for LLVM C++ strings. */
69*08b48e0bSAndroid Build Coastguard Worker tree cmptrs_hooks[5];
70*08b48e0bSAndroid Build Coastguard Worker
cmptrs_hook__anon21d00caf0111::afl_cmptrs_pass71*08b48e0bSAndroid Build Coastguard Worker tree cmptrs_hook(unsigned i) {
72*08b48e0bSAndroid Build Coastguard Worker
73*08b48e0bSAndroid Build Coastguard Worker if (!tp8u) {
74*08b48e0bSAndroid Build Coastguard Worker
75*08b48e0bSAndroid Build Coastguard Worker tree t8u;
76*08b48e0bSAndroid Build Coastguard Worker if (BITS_PER_UNIT == 8)
77*08b48e0bSAndroid Build Coastguard Worker t8u = unsigned_char_type_node;
78*08b48e0bSAndroid Build Coastguard Worker else
79*08b48e0bSAndroid Build Coastguard Worker t8u = build_nonstandard_integer_type(8, 1);
80*08b48e0bSAndroid Build Coastguard Worker tp8u = build_pointer_type(t8u);
81*08b48e0bSAndroid Build Coastguard Worker
82*08b48e0bSAndroid Build Coastguard Worker }
83*08b48e0bSAndroid Build Coastguard Worker
84*08b48e0bSAndroid Build Coastguard Worker if (i <= ARRAY_SIZE(cmptrs_hooks) && cmptrs_hooks[i])
85*08b48e0bSAndroid Build Coastguard Worker return cmptrs_hooks[i];
86*08b48e0bSAndroid Build Coastguard Worker
87*08b48e0bSAndroid Build Coastguard Worker const char *n = NULL;
88*08b48e0bSAndroid Build Coastguard Worker
89*08b48e0bSAndroid Build Coastguard Worker switch (i) {
90*08b48e0bSAndroid Build Coastguard Worker
91*08b48e0bSAndroid Build Coastguard Worker case 0:
92*08b48e0bSAndroid Build Coastguard Worker n = "__cmplog_rtn_hook";
93*08b48e0bSAndroid Build Coastguard Worker break;
94*08b48e0bSAndroid Build Coastguard Worker
95*08b48e0bSAndroid Build Coastguard Worker case 1:
96*08b48e0bSAndroid Build Coastguard Worker n = "__cmplog_rtn_gcc_stdstring_stdstring";
97*08b48e0bSAndroid Build Coastguard Worker break;
98*08b48e0bSAndroid Build Coastguard Worker
99*08b48e0bSAndroid Build Coastguard Worker case 2:
100*08b48e0bSAndroid Build Coastguard Worker n = "__cmplog_rtn_gcc_stdstring_cstring";
101*08b48e0bSAndroid Build Coastguard Worker break;
102*08b48e0bSAndroid Build Coastguard Worker
103*08b48e0bSAndroid Build Coastguard Worker case 3:
104*08b48e0bSAndroid Build Coastguard Worker n = "__cmplog_rtn_llvm_stdstring_stdstring";
105*08b48e0bSAndroid Build Coastguard Worker break;
106*08b48e0bSAndroid Build Coastguard Worker
107*08b48e0bSAndroid Build Coastguard Worker case 4:
108*08b48e0bSAndroid Build Coastguard Worker n = "__cmplog_rtn_llvm_stdstring_cstring";
109*08b48e0bSAndroid Build Coastguard Worker break;
110*08b48e0bSAndroid Build Coastguard Worker
111*08b48e0bSAndroid Build Coastguard Worker default:
112*08b48e0bSAndroid Build Coastguard Worker gcc_unreachable();
113*08b48e0bSAndroid Build Coastguard Worker
114*08b48e0bSAndroid Build Coastguard Worker }
115*08b48e0bSAndroid Build Coastguard Worker
116*08b48e0bSAndroid Build Coastguard Worker tree fnt = build_function_type_list(void_type_node, tp8u, tp8u, NULL_TREE);
117*08b48e0bSAndroid Build Coastguard Worker tree t = cmptrs_hooks[i] = build_fn_decl(n, fnt);
118*08b48e0bSAndroid Build Coastguard Worker
119*08b48e0bSAndroid Build Coastguard Worker /* Mark the newly-created decl as non-throwing, so that we can
120*08b48e0bSAndroid Build Coastguard Worker insert call within basic blocks. */
121*08b48e0bSAndroid Build Coastguard Worker TREE_NOTHROW(t) = 1;
122*08b48e0bSAndroid Build Coastguard Worker
123*08b48e0bSAndroid Build Coastguard Worker return t;
124*08b48e0bSAndroid Build Coastguard Worker
125*08b48e0bSAndroid Build Coastguard Worker }
126*08b48e0bSAndroid Build Coastguard Worker
127*08b48e0bSAndroid Build Coastguard Worker /* Return true if T is the char* type. */
is_c_string__anon21d00caf0111::afl_cmptrs_pass128*08b48e0bSAndroid Build Coastguard Worker bool is_c_string(tree t) {
129*08b48e0bSAndroid Build Coastguard Worker
130*08b48e0bSAndroid Build Coastguard Worker return (POINTER_TYPE_P(t) &&
131*08b48e0bSAndroid Build Coastguard Worker TYPE_MAIN_VARIANT(TREE_TYPE(t)) == char_type_node);
132*08b48e0bSAndroid Build Coastguard Worker
133*08b48e0bSAndroid Build Coastguard Worker }
134*08b48e0bSAndroid Build Coastguard Worker
135*08b48e0bSAndroid Build Coastguard Worker /* Return true if T is an indirect std::string type. The LLVM pass
136*08b48e0bSAndroid Build Coastguard Worker tests portions of the mangled name of the callee. We could do
137*08b48e0bSAndroid Build Coastguard Worker that in GCC too, but computing the mangled name may cause
138*08b48e0bSAndroid Build Coastguard Worker template instantiations and get symbols defined that could
139*08b48e0bSAndroid Build Coastguard Worker otherwise be considered unused. We check for compatible layout,
140*08b48e0bSAndroid Build Coastguard Worker and class, namespace, and field names. These have been unchanged
141*08b48e0bSAndroid Build Coastguard Worker since at least GCC 7, probably longer, up to GCC 11. Odds are
142*08b48e0bSAndroid Build Coastguard Worker that, if it were to change in significant ways, mangling would
143*08b48e0bSAndroid Build Coastguard Worker also change to flag the incompatibility, and we'd have to use a
144*08b48e0bSAndroid Build Coastguard Worker different hook anyway. */
is_gxx_std_string__anon21d00caf0111::afl_cmptrs_pass145*08b48e0bSAndroid Build Coastguard Worker bool is_gxx_std_string(tree t) {
146*08b48e0bSAndroid Build Coastguard Worker
147*08b48e0bSAndroid Build Coastguard Worker /* We need a pointer or reference type. */
148*08b48e0bSAndroid Build Coastguard Worker if (!POINTER_TYPE_P(t)) return false;
149*08b48e0bSAndroid Build Coastguard Worker
150*08b48e0bSAndroid Build Coastguard Worker /* Get to the pointed-to type. */
151*08b48e0bSAndroid Build Coastguard Worker t = TREE_TYPE(t);
152*08b48e0bSAndroid Build Coastguard Worker if (!t) return false;
153*08b48e0bSAndroid Build Coastguard Worker
154*08b48e0bSAndroid Build Coastguard Worker /* Select the main variant, so that can compare types with pointers. */
155*08b48e0bSAndroid Build Coastguard Worker t = TYPE_MAIN_VARIANT(t);
156*08b48e0bSAndroid Build Coastguard Worker
157*08b48e0bSAndroid Build Coastguard Worker /* We expect it to be a record type. */
158*08b48e0bSAndroid Build Coastguard Worker if (TREE_CODE(t) != RECORD_TYPE) return false;
159*08b48e0bSAndroid Build Coastguard Worker
160*08b48e0bSAndroid Build Coastguard Worker /* The type has an identifier. */
161*08b48e0bSAndroid Build Coastguard Worker if (!TYPE_IDENTIFIER(t)) return false;
162*08b48e0bSAndroid Build Coastguard Worker
163*08b48e0bSAndroid Build Coastguard Worker /* The type of the template is basic_string. */
164*08b48e0bSAndroid Build Coastguard Worker if (strcmp(IDENTIFIER_POINTER(TYPE_IDENTIFIER(t)), "basic_string") != 0)
165*08b48e0bSAndroid Build Coastguard Worker return false;
166*08b48e0bSAndroid Build Coastguard Worker
167*08b48e0bSAndroid Build Coastguard Worker /* It's declared in an internal namespace named __cxx11. */
168*08b48e0bSAndroid Build Coastguard Worker tree c = DECL_CONTEXT(TYPE_NAME(t));
169*08b48e0bSAndroid Build Coastguard Worker if (!c || TREE_CODE(c) != NAMESPACE_DECL ||
170*08b48e0bSAndroid Build Coastguard Worker strcmp(IDENTIFIER_POINTER(DECL_NAME(c)), "__cxx11") != 0)
171*08b48e0bSAndroid Build Coastguard Worker return false;
172*08b48e0bSAndroid Build Coastguard Worker
173*08b48e0bSAndroid Build Coastguard Worker /* The __cxx11 namespace is a member of namespace std. */
174*08b48e0bSAndroid Build Coastguard Worker c = DECL_CONTEXT(c);
175*08b48e0bSAndroid Build Coastguard Worker if (!c || TREE_CODE(c) != NAMESPACE_DECL ||
176*08b48e0bSAndroid Build Coastguard Worker strcmp(IDENTIFIER_POINTER(DECL_NAME(c)), "std") != 0)
177*08b48e0bSAndroid Build Coastguard Worker return false;
178*08b48e0bSAndroid Build Coastguard Worker
179*08b48e0bSAndroid Build Coastguard Worker /* And the std namespace is in the global namespace. */
180*08b48e0bSAndroid Build Coastguard Worker c = DECL_CONTEXT(c);
181*08b48e0bSAndroid Build Coastguard Worker if (c && TREE_CODE(c) != TRANSLATION_UNIT_DECL) return false;
182*08b48e0bSAndroid Build Coastguard Worker
183*08b48e0bSAndroid Build Coastguard Worker /* Check that the first nonstatic data member of the record type
184*08b48e0bSAndroid Build Coastguard Worker is named _M_dataplus. */
185*08b48e0bSAndroid Build Coastguard Worker for (c = TYPE_FIELDS(t); c; c = DECL_CHAIN(c))
186*08b48e0bSAndroid Build Coastguard Worker if (TREE_CODE(c) == FIELD_DECL) break;
187*08b48e0bSAndroid Build Coastguard Worker if (!c || !integer_zerop(DECL_FIELD_BIT_OFFSET(c)) ||
188*08b48e0bSAndroid Build Coastguard Worker strcmp(IDENTIFIER_POINTER(DECL_NAME(c)), "_M_dataplus") != 0)
189*08b48e0bSAndroid Build Coastguard Worker return false;
190*08b48e0bSAndroid Build Coastguard Worker
191*08b48e0bSAndroid Build Coastguard Worker /* Check that the second nonstatic data member of the record type
192*08b48e0bSAndroid Build Coastguard Worker is named _M_string_length. */
193*08b48e0bSAndroid Build Coastguard Worker tree f2;
194*08b48e0bSAndroid Build Coastguard Worker for (f2 = DECL_CHAIN(c); f2; f2 = DECL_CHAIN(f2))
195*08b48e0bSAndroid Build Coastguard Worker if (TREE_CODE(f2) == FIELD_DECL) break;
196*08b48e0bSAndroid Build Coastguard Worker if (!f2 /* No need to check this field's offset. */
197*08b48e0bSAndroid Build Coastguard Worker || strcmp(IDENTIFIER_POINTER(DECL_NAME(f2)), "_M_string_length") != 0)
198*08b48e0bSAndroid Build Coastguard Worker return false;
199*08b48e0bSAndroid Build Coastguard Worker
200*08b48e0bSAndroid Build Coastguard Worker /* The type of the second data member is size_t. */
201*08b48e0bSAndroid Build Coastguard Worker if (!TREE_TYPE(f2) || TYPE_MAIN_VARIANT(TREE_TYPE(f2)) != size_type_node)
202*08b48e0bSAndroid Build Coastguard Worker return false;
203*08b48e0bSAndroid Build Coastguard Worker
204*08b48e0bSAndroid Build Coastguard Worker /* Now go back to the first data member. Its type should be a
205*08b48e0bSAndroid Build Coastguard Worker record type named _Alloc_hider. */
206*08b48e0bSAndroid Build Coastguard Worker c = TREE_TYPE(c);
207*08b48e0bSAndroid Build Coastguard Worker if (!c || TREE_CODE(c) != RECORD_TYPE || !TYPE_IDENTIFIER(t) ||
208*08b48e0bSAndroid Build Coastguard Worker strcmp(IDENTIFIER_POINTER(TYPE_IDENTIFIER(c)), "_Alloc_hider") != 0)
209*08b48e0bSAndroid Build Coastguard Worker return false;
210*08b48e0bSAndroid Build Coastguard Worker
211*08b48e0bSAndroid Build Coastguard Worker /* And its first data member is named _M_p. */
212*08b48e0bSAndroid Build Coastguard Worker for (c = TYPE_FIELDS(c); c; c = DECL_CHAIN(c))
213*08b48e0bSAndroid Build Coastguard Worker if (TREE_CODE(c) == FIELD_DECL) break;
214*08b48e0bSAndroid Build Coastguard Worker if (!c || !integer_zerop(DECL_FIELD_BIT_OFFSET(c)) ||
215*08b48e0bSAndroid Build Coastguard Worker strcmp(IDENTIFIER_POINTER(DECL_NAME(c)), "_M_p") != 0)
216*08b48e0bSAndroid Build Coastguard Worker return false;
217*08b48e0bSAndroid Build Coastguard Worker
218*08b48e0bSAndroid Build Coastguard Worker /* For the basic_string<char> type we're interested in, the type
219*08b48e0bSAndroid Build Coastguard Worker of the data member is the C string type. */
220*08b48e0bSAndroid Build Coastguard Worker if (!is_c_string(TREE_TYPE(c))) return false;
221*08b48e0bSAndroid Build Coastguard Worker
222*08b48e0bSAndroid Build Coastguard Worker /* This might not be the real thing, but the bits that matter for
223*08b48e0bSAndroid Build Coastguard Worker the hook are there. */
224*08b48e0bSAndroid Build Coastguard Worker
225*08b48e0bSAndroid Build Coastguard Worker return true;
226*08b48e0bSAndroid Build Coastguard Worker
227*08b48e0bSAndroid Build Coastguard Worker }
228*08b48e0bSAndroid Build Coastguard Worker
229*08b48e0bSAndroid Build Coastguard Worker /* ??? This is not implemented. What would the point be of
230*08b48e0bSAndroid Build Coastguard Worker recognizing LLVM's string type in GCC? */
is_llvm_std_string__anon21d00caf0111::afl_cmptrs_pass231*08b48e0bSAndroid Build Coastguard Worker bool is_llvm_std_string(tree t) {
232*08b48e0bSAndroid Build Coastguard Worker
233*08b48e0bSAndroid Build Coastguard Worker return false;
234*08b48e0bSAndroid Build Coastguard Worker
235*08b48e0bSAndroid Build Coastguard Worker }
236*08b48e0bSAndroid Build Coastguard Worker
execute__anon21d00caf0111::afl_cmptrs_pass237*08b48e0bSAndroid Build Coastguard Worker virtual unsigned int execute(function *fn) {
238*08b48e0bSAndroid Build Coastguard Worker
239*08b48e0bSAndroid Build Coastguard Worker if (!isInInstrumentList(fn)) return 0;
240*08b48e0bSAndroid Build Coastguard Worker
241*08b48e0bSAndroid Build Coastguard Worker basic_block bb;
242*08b48e0bSAndroid Build Coastguard Worker FOR_EACH_BB_FN(bb, fn) {
243*08b48e0bSAndroid Build Coastguard Worker
244*08b48e0bSAndroid Build Coastguard Worker for (gimple_stmt_iterator gsi = gsi_after_labels(bb); !gsi_end_p(gsi);
245*08b48e0bSAndroid Build Coastguard Worker gsi_next(&gsi)) {
246*08b48e0bSAndroid Build Coastguard Worker
247*08b48e0bSAndroid Build Coastguard Worker gimple stmt = gsi_stmt(gsi);
248*08b48e0bSAndroid Build Coastguard Worker
249*08b48e0bSAndroid Build Coastguard Worker /* We're only interested in GIMPLE_CALLs. */
250*08b48e0bSAndroid Build Coastguard Worker if (gimple_code(stmt) != GIMPLE_CALL) continue;
251*08b48e0bSAndroid Build Coastguard Worker
252*08b48e0bSAndroid Build Coastguard Worker if (gimple_call_num_args(stmt) < 2) continue;
253*08b48e0bSAndroid Build Coastguard Worker
254*08b48e0bSAndroid Build Coastguard Worker gcall *c = as_a<gcall *>(stmt);
255*08b48e0bSAndroid Build Coastguard Worker
256*08b48e0bSAndroid Build Coastguard Worker tree callee_type = gimple_call_fntype(c);
257*08b48e0bSAndroid Build Coastguard Worker
258*08b48e0bSAndroid Build Coastguard Worker if (!callee_type || !TYPE_ARG_TYPES(callee_type) ||
259*08b48e0bSAndroid Build Coastguard Worker !TREE_CHAIN(TYPE_ARG_TYPES(callee_type)))
260*08b48e0bSAndroid Build Coastguard Worker continue;
261*08b48e0bSAndroid Build Coastguard Worker
262*08b48e0bSAndroid Build Coastguard Worker tree arg_type[2] = {
263*08b48e0bSAndroid Build Coastguard Worker
264*08b48e0bSAndroid Build Coastguard Worker TYPE_MAIN_VARIANT(TREE_VALUE(TYPE_ARG_TYPES(callee_type))),
265*08b48e0bSAndroid Build Coastguard Worker TYPE_MAIN_VARIANT(
266*08b48e0bSAndroid Build Coastguard Worker TREE_VALUE(TREE_CHAIN(TYPE_ARG_TYPES(callee_type))))};
267*08b48e0bSAndroid Build Coastguard Worker
268*08b48e0bSAndroid Build Coastguard Worker tree fn = NULL;
269*08b48e0bSAndroid Build Coastguard Worker /* Callee arglist starts with two GCC std::string arguments. */
270*08b48e0bSAndroid Build Coastguard Worker if (arg_type[0] == arg_type[1] && is_gxx_std_string(arg_type[0]))
271*08b48e0bSAndroid Build Coastguard Worker fn = cmptrs_hook(1);
272*08b48e0bSAndroid Build Coastguard Worker /* Callee arglist starts with GCC std::string and C string. */
273*08b48e0bSAndroid Build Coastguard Worker else if (is_gxx_std_string(arg_type[0]) && is_c_string(arg_type[1]))
274*08b48e0bSAndroid Build Coastguard Worker fn = cmptrs_hook(2);
275*08b48e0bSAndroid Build Coastguard Worker /* Callee arglist starts with two LLVM std::string arguments. */
276*08b48e0bSAndroid Build Coastguard Worker else if (arg_type[0] == arg_type[1] && is_llvm_std_string(arg_type[0]))
277*08b48e0bSAndroid Build Coastguard Worker fn = cmptrs_hook(3);
278*08b48e0bSAndroid Build Coastguard Worker /* Callee arglist starts with LLVM std::string and C string. */
279*08b48e0bSAndroid Build Coastguard Worker else if (is_llvm_std_string(arg_type[0]) && is_c_string(arg_type[1]))
280*08b48e0bSAndroid Build Coastguard Worker fn = cmptrs_hook(4);
281*08b48e0bSAndroid Build Coastguard Worker /* Callee arglist starts with two pointers to the same type,
282*08b48e0bSAndroid Build Coastguard Worker and callee returns a value. */
283*08b48e0bSAndroid Build Coastguard Worker else if (arg_type[0] == arg_type[1] && POINTER_TYPE_P(arg_type[0]) &&
284*08b48e0bSAndroid Build Coastguard Worker (TYPE_MAIN_VARIANT(gimple_call_return_type(c)) !=
285*08b48e0bSAndroid Build Coastguard Worker void_type_node))
286*08b48e0bSAndroid Build Coastguard Worker fn = cmptrs_hook(0);
287*08b48e0bSAndroid Build Coastguard Worker else
288*08b48e0bSAndroid Build Coastguard Worker continue;
289*08b48e0bSAndroid Build Coastguard Worker
290*08b48e0bSAndroid Build Coastguard Worker tree arg[2] = {gimple_call_arg(c, 0), gimple_call_arg(c, 1)};
291*08b48e0bSAndroid Build Coastguard Worker
292*08b48e0bSAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(arg); i++) {
293*08b48e0bSAndroid Build Coastguard Worker
294*08b48e0bSAndroid Build Coastguard Worker tree c = fold_convert_loc(UNKNOWN_LOCATION, tp8u, arg[i]);
295*08b48e0bSAndroid Build Coastguard Worker if (!is_gimple_val(c)) {
296*08b48e0bSAndroid Build Coastguard Worker
297*08b48e0bSAndroid Build Coastguard Worker tree s = make_ssa_name(tp8u);
298*08b48e0bSAndroid Build Coastguard Worker gimple g = gimple_build_assign(s, c);
299*08b48e0bSAndroid Build Coastguard Worker c = s;
300*08b48e0bSAndroid Build Coastguard Worker gsi_insert_before(&gsi, g, GSI_SAME_STMT);
301*08b48e0bSAndroid Build Coastguard Worker
302*08b48e0bSAndroid Build Coastguard Worker }
303*08b48e0bSAndroid Build Coastguard Worker
304*08b48e0bSAndroid Build Coastguard Worker arg[i] = c;
305*08b48e0bSAndroid Build Coastguard Worker
306*08b48e0bSAndroid Build Coastguard Worker }
307*08b48e0bSAndroid Build Coastguard Worker
308*08b48e0bSAndroid Build Coastguard Worker gimple call = gimple_build_call(fn, 2, arg[0], arg[1]);
309*08b48e0bSAndroid Build Coastguard Worker gsi_insert_before(&gsi, call, GSI_SAME_STMT);
310*08b48e0bSAndroid Build Coastguard Worker
311*08b48e0bSAndroid Build Coastguard Worker }
312*08b48e0bSAndroid Build Coastguard Worker
313*08b48e0bSAndroid Build Coastguard Worker }
314*08b48e0bSAndroid Build Coastguard Worker
315*08b48e0bSAndroid Build Coastguard Worker return 0;
316*08b48e0bSAndroid Build Coastguard Worker
317*08b48e0bSAndroid Build Coastguard Worker }
318*08b48e0bSAndroid Build Coastguard Worker
319*08b48e0bSAndroid Build Coastguard Worker };
320*08b48e0bSAndroid Build Coastguard Worker
321*08b48e0bSAndroid Build Coastguard Worker static struct plugin_info afl_cmptrs_plugin = {
322*08b48e0bSAndroid Build Coastguard Worker
323*08b48e0bSAndroid Build Coastguard Worker .version = "20220420",
324*08b48e0bSAndroid Build Coastguard Worker .help = G_("AFL gcc cmptrs plugin\n\
325*08b48e0bSAndroid Build Coastguard Worker \n\
326*08b48e0bSAndroid Build Coastguard Worker Set AFL_QUIET in the environment to silence it.\n\
327*08b48e0bSAndroid Build Coastguard Worker "),
328*08b48e0bSAndroid Build Coastguard Worker
329*08b48e0bSAndroid Build Coastguard Worker };
330*08b48e0bSAndroid Build Coastguard Worker
331*08b48e0bSAndroid Build Coastguard Worker } // namespace
332*08b48e0bSAndroid Build Coastguard Worker
333*08b48e0bSAndroid Build Coastguard Worker /* This is the function GCC calls when loading a plugin. Initialize
334*08b48e0bSAndroid Build Coastguard Worker and register further callbacks. */
plugin_init(struct plugin_name_args * info,struct plugin_gcc_version * version)335*08b48e0bSAndroid Build Coastguard Worker int plugin_init(struct plugin_name_args *info,
336*08b48e0bSAndroid Build Coastguard Worker struct plugin_gcc_version *version) {
337*08b48e0bSAndroid Build Coastguard Worker
338*08b48e0bSAndroid Build Coastguard Worker if (!plugin_default_version_check(version, &gcc_version))
339*08b48e0bSAndroid Build Coastguard Worker FATAL(G_("GCC and plugin have incompatible versions, expected GCC %s, "
340*08b48e0bSAndroid Build Coastguard Worker "is %s"),
341*08b48e0bSAndroid Build Coastguard Worker gcc_version.basever, version->basever);
342*08b48e0bSAndroid Build Coastguard Worker
343*08b48e0bSAndroid Build Coastguard Worker /* Show a banner. */
344*08b48e0bSAndroid Build Coastguard Worker bool quiet = false;
345*08b48e0bSAndroid Build Coastguard Worker if (isatty(2) && !getenv("AFL_QUIET"))
346*08b48e0bSAndroid Build Coastguard Worker SAYF(cCYA "afl-gcc-cmptrs-pass " cBRI VERSION cRST
347*08b48e0bSAndroid Build Coastguard Worker " by <[email protected]>\n");
348*08b48e0bSAndroid Build Coastguard Worker else
349*08b48e0bSAndroid Build Coastguard Worker quiet = true;
350*08b48e0bSAndroid Build Coastguard Worker
351*08b48e0bSAndroid Build Coastguard Worker const char *name = info->base_name;
352*08b48e0bSAndroid Build Coastguard Worker register_callback(name, PLUGIN_INFO, NULL, &afl_cmptrs_plugin);
353*08b48e0bSAndroid Build Coastguard Worker
354*08b48e0bSAndroid Build Coastguard Worker afl_cmptrs_pass *aflp = new afl_cmptrs_pass(quiet);
355*08b48e0bSAndroid Build Coastguard Worker struct register_pass_info pass_info = {
356*08b48e0bSAndroid Build Coastguard Worker
357*08b48e0bSAndroid Build Coastguard Worker .pass = aflp,
358*08b48e0bSAndroid Build Coastguard Worker .reference_pass_name = "ssa",
359*08b48e0bSAndroid Build Coastguard Worker .ref_pass_instance_number = 1,
360*08b48e0bSAndroid Build Coastguard Worker .pos_op = PASS_POS_INSERT_AFTER,
361*08b48e0bSAndroid Build Coastguard Worker
362*08b48e0bSAndroid Build Coastguard Worker };
363*08b48e0bSAndroid Build Coastguard Worker
364*08b48e0bSAndroid Build Coastguard Worker register_callback(name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
365*08b48e0bSAndroid Build Coastguard Worker
366*08b48e0bSAndroid Build Coastguard Worker return 0;
367*08b48e0bSAndroid Build Coastguard Worker
368*08b48e0bSAndroid Build Coastguard Worker }
369*08b48e0bSAndroid Build Coastguard Worker
370