1*08b48e0bSAndroid Build Coastguard Worker /* GCC plugin for cmplog 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 pass by Andrea Fioraldi <[email protected]>, and
10*08b48e0bSAndroid Build Coastguard Worker on the AFL GCC 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_cmplog_pass_data = {
38*08b48e0bSAndroid Build Coastguard Worker
39*08b48e0bSAndroid Build Coastguard Worker .type = GIMPLE_PASS,
40*08b48e0bSAndroid Build Coastguard Worker .name = "aflcmplog",
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_cmplog_pass : afl_base_pass {
53*08b48e0bSAndroid Build Coastguard Worker
afl_cmplog_pass__anon0e48c2980111::afl_cmplog_pass54*08b48e0bSAndroid Build Coastguard Worker afl_cmplog_pass(bool quiet)
55*08b48e0bSAndroid Build Coastguard Worker : afl_base_pass(quiet, /*debug=*/false, afl_cmplog_pass_data),
56*08b48e0bSAndroid Build Coastguard Worker t8u(),
57*08b48e0bSAndroid Build Coastguard Worker cmplog_hooks() {
58*08b48e0bSAndroid Build Coastguard Worker
59*08b48e0bSAndroid Build Coastguard Worker }
60*08b48e0bSAndroid Build Coastguard Worker
61*08b48e0bSAndroid Build Coastguard Worker /* An unsigned 8-bit integral type. */
62*08b48e0bSAndroid Build Coastguard Worker tree t8u;
63*08b48e0bSAndroid Build Coastguard Worker
64*08b48e0bSAndroid Build Coastguard Worker /* Declarations for the various cmplog hook functions, allocated on demand..
65*08b48e0bSAndroid Build Coastguard Worker [0] is for __cmplog_ins_hookN, that accepts non-power-of-2 sizes.
66*08b48e0bSAndroid Build Coastguard Worker [n in 1..5] are for unsigned ints of 2^{n-1} bytes. */
67*08b48e0bSAndroid Build Coastguard Worker tree cmplog_hooks[6];
68*08b48e0bSAndroid Build Coastguard Worker
cmplog_hook__anon0e48c2980111::afl_cmplog_pass69*08b48e0bSAndroid Build Coastguard Worker tree cmplog_hook(unsigned i) {
70*08b48e0bSAndroid Build Coastguard Worker
71*08b48e0bSAndroid Build Coastguard Worker tree t, fnt;
72*08b48e0bSAndroid Build Coastguard Worker
73*08b48e0bSAndroid Build Coastguard Worker if (!t8u) {
74*08b48e0bSAndroid Build Coastguard Worker
75*08b48e0bSAndroid Build Coastguard Worker if (BITS_PER_UNIT == 8)
76*08b48e0bSAndroid Build Coastguard Worker t8u = unsigned_char_type_node;
77*08b48e0bSAndroid Build Coastguard Worker else
78*08b48e0bSAndroid Build Coastguard Worker t8u = build_nonstandard_integer_type(8, 1);
79*08b48e0bSAndroid Build Coastguard Worker
80*08b48e0bSAndroid Build Coastguard Worker }
81*08b48e0bSAndroid Build Coastguard Worker
82*08b48e0bSAndroid Build Coastguard Worker if (i <= ARRAY_SIZE(cmplog_hooks) && cmplog_hooks[i])
83*08b48e0bSAndroid Build Coastguard Worker return cmplog_hooks[i];
84*08b48e0bSAndroid Build Coastguard Worker
85*08b48e0bSAndroid Build Coastguard Worker switch (i) {
86*08b48e0bSAndroid Build Coastguard Worker
87*08b48e0bSAndroid Build Coastguard Worker case 0:
88*08b48e0bSAndroid Build Coastguard Worker #ifdef uint128_type_node
89*08b48e0bSAndroid Build Coastguard Worker t = uint128_type_node;
90*08b48e0bSAndroid Build Coastguard Worker #else
91*08b48e0bSAndroid Build Coastguard Worker t = build_nonstandard_integer_type(128, 1);
92*08b48e0bSAndroid Build Coastguard Worker #endif
93*08b48e0bSAndroid Build Coastguard Worker fnt =
94*08b48e0bSAndroid Build Coastguard Worker build_function_type_list(void_type_node, t, t, t8u, t8u, NULL_TREE);
95*08b48e0bSAndroid Build Coastguard Worker t = cmplog_hooks[0] = build_fn_decl("__cmplog_ins_hookN", fnt);
96*08b48e0bSAndroid Build Coastguard Worker break;
97*08b48e0bSAndroid Build Coastguard Worker
98*08b48e0bSAndroid Build Coastguard Worker case 1:
99*08b48e0bSAndroid Build Coastguard Worker t = t8u;
100*08b48e0bSAndroid Build Coastguard Worker fnt = build_function_type_list(void_type_node, t, t, t8u, NULL_TREE);
101*08b48e0bSAndroid Build Coastguard Worker t = cmplog_hooks[1] = build_fn_decl("__cmplog_ins_hook1", fnt);
102*08b48e0bSAndroid Build Coastguard Worker break;
103*08b48e0bSAndroid Build Coastguard Worker
104*08b48e0bSAndroid Build Coastguard Worker case 2:
105*08b48e0bSAndroid Build Coastguard Worker t = uint16_type_node;
106*08b48e0bSAndroid Build Coastguard Worker fnt = build_function_type_list(void_type_node, t, t, t8u, NULL_TREE);
107*08b48e0bSAndroid Build Coastguard Worker t = cmplog_hooks[2] = build_fn_decl("__cmplog_ins_hook2", fnt);
108*08b48e0bSAndroid Build Coastguard Worker break;
109*08b48e0bSAndroid Build Coastguard Worker
110*08b48e0bSAndroid Build Coastguard Worker case 3:
111*08b48e0bSAndroid Build Coastguard Worker t = uint32_type_node;
112*08b48e0bSAndroid Build Coastguard Worker fnt = build_function_type_list(void_type_node, t, t, t8u, NULL_TREE);
113*08b48e0bSAndroid Build Coastguard Worker t = cmplog_hooks[3] = build_fn_decl("__cmplog_ins_hook4", fnt);
114*08b48e0bSAndroid Build Coastguard Worker break;
115*08b48e0bSAndroid Build Coastguard Worker
116*08b48e0bSAndroid Build Coastguard Worker case 4:
117*08b48e0bSAndroid Build Coastguard Worker t = uint64_type_node;
118*08b48e0bSAndroid Build Coastguard Worker fnt = build_function_type_list(void_type_node, t, t, t8u, NULL_TREE);
119*08b48e0bSAndroid Build Coastguard Worker t = cmplog_hooks[4] = build_fn_decl("__cmplog_ins_hook8", fnt);
120*08b48e0bSAndroid Build Coastguard Worker break;
121*08b48e0bSAndroid Build Coastguard Worker
122*08b48e0bSAndroid Build Coastguard Worker case 5:
123*08b48e0bSAndroid Build Coastguard Worker #ifdef uint128_type_node
124*08b48e0bSAndroid Build Coastguard Worker t = uint128_type_node;
125*08b48e0bSAndroid Build Coastguard Worker #else
126*08b48e0bSAndroid Build Coastguard Worker t = build_nonstandard_integer_type(128, 1);
127*08b48e0bSAndroid Build Coastguard Worker #endif
128*08b48e0bSAndroid Build Coastguard Worker fnt = build_function_type_list(void_type_node, t, t, t8u, NULL_TREE);
129*08b48e0bSAndroid Build Coastguard Worker t = cmplog_hooks[5] = build_fn_decl("__cmplog_ins_hook16", fnt);
130*08b48e0bSAndroid Build Coastguard Worker break;
131*08b48e0bSAndroid Build Coastguard Worker
132*08b48e0bSAndroid Build Coastguard Worker default:
133*08b48e0bSAndroid Build Coastguard Worker gcc_unreachable();
134*08b48e0bSAndroid Build Coastguard Worker
135*08b48e0bSAndroid Build Coastguard Worker }
136*08b48e0bSAndroid Build Coastguard Worker
137*08b48e0bSAndroid Build Coastguard Worker /* Mark the newly-created decl as non-throwing, so that we can
138*08b48e0bSAndroid Build Coastguard Worker insert call within basic blocks. */
139*08b48e0bSAndroid Build Coastguard Worker TREE_NOTHROW(t) = 1;
140*08b48e0bSAndroid Build Coastguard Worker
141*08b48e0bSAndroid Build Coastguard Worker return t;
142*08b48e0bSAndroid Build Coastguard Worker
143*08b48e0bSAndroid Build Coastguard Worker }
144*08b48e0bSAndroid Build Coastguard Worker
145*08b48e0bSAndroid Build Coastguard Worker /* Insert a cmplog hook call before GSI for a CODE compare between
146*08b48e0bSAndroid Build Coastguard Worker LHS and RHS. */
insert_cmplog_call__anon0e48c2980111::afl_cmplog_pass147*08b48e0bSAndroid Build Coastguard Worker void insert_cmplog_call(gimple_stmt_iterator gsi, tree_code code, tree lhs,
148*08b48e0bSAndroid Build Coastguard Worker tree rhs) {
149*08b48e0bSAndroid Build Coastguard Worker
150*08b48e0bSAndroid Build Coastguard Worker gcc_checking_assert(TYPE_MAIN_VARIANT(TREE_TYPE(lhs)) ==
151*08b48e0bSAndroid Build Coastguard Worker TYPE_MAIN_VARIANT(TREE_TYPE(rhs)));
152*08b48e0bSAndroid Build Coastguard Worker
153*08b48e0bSAndroid Build Coastguard Worker tree fn;
154*08b48e0bSAndroid Build Coastguard Worker bool pass_n = false;
155*08b48e0bSAndroid Build Coastguard Worker
156*08b48e0bSAndroid Build Coastguard Worker /* Obtain the compare operand size as a constant. */
157*08b48e0bSAndroid Build Coastguard Worker tree st = TREE_TYPE(lhs);
158*08b48e0bSAndroid Build Coastguard Worker tree szt = TYPE_SIZE(st);
159*08b48e0bSAndroid Build Coastguard Worker
160*08b48e0bSAndroid Build Coastguard Worker if (!tree_fits_uhwi_p(szt)) return;
161*08b48e0bSAndroid Build Coastguard Worker
162*08b48e0bSAndroid Build Coastguard Worker unsigned HOST_WIDE_INT sz = tree_to_uhwi(szt);
163*08b48e0bSAndroid Build Coastguard Worker
164*08b48e0bSAndroid Build Coastguard Worker /* Round it up. */
165*08b48e0bSAndroid Build Coastguard Worker if (sz % 8) sz = (((sz - 1) / 8) + 1) * 8;
166*08b48e0bSAndroid Build Coastguard Worker
167*08b48e0bSAndroid Build Coastguard Worker /* Select the hook function to call, based on the size. */
168*08b48e0bSAndroid Build Coastguard Worker switch (sz) {
169*08b48e0bSAndroid Build Coastguard Worker
170*08b48e0bSAndroid Build Coastguard Worker default:
171*08b48e0bSAndroid Build Coastguard Worker fn = cmplog_hook(0);
172*08b48e0bSAndroid Build Coastguard Worker pass_n = true;
173*08b48e0bSAndroid Build Coastguard Worker break;
174*08b48e0bSAndroid Build Coastguard Worker
175*08b48e0bSAndroid Build Coastguard Worker case 8:
176*08b48e0bSAndroid Build Coastguard Worker fn = cmplog_hook(1);
177*08b48e0bSAndroid Build Coastguard Worker break;
178*08b48e0bSAndroid Build Coastguard Worker
179*08b48e0bSAndroid Build Coastguard Worker case 16:
180*08b48e0bSAndroid Build Coastguard Worker fn = cmplog_hook(2);
181*08b48e0bSAndroid Build Coastguard Worker break;
182*08b48e0bSAndroid Build Coastguard Worker
183*08b48e0bSAndroid Build Coastguard Worker case 32:
184*08b48e0bSAndroid Build Coastguard Worker fn = cmplog_hook(3);
185*08b48e0bSAndroid Build Coastguard Worker break;
186*08b48e0bSAndroid Build Coastguard Worker
187*08b48e0bSAndroid Build Coastguard Worker case 64:
188*08b48e0bSAndroid Build Coastguard Worker fn = cmplog_hook(4);
189*08b48e0bSAndroid Build Coastguard Worker break;
190*08b48e0bSAndroid Build Coastguard Worker
191*08b48e0bSAndroid Build Coastguard Worker case 128:
192*08b48e0bSAndroid Build Coastguard Worker fn = cmplog_hook(5);
193*08b48e0bSAndroid Build Coastguard Worker break;
194*08b48e0bSAndroid Build Coastguard Worker
195*08b48e0bSAndroid Build Coastguard Worker }
196*08b48e0bSAndroid Build Coastguard Worker
197*08b48e0bSAndroid Build Coastguard Worker /* Set attr according to the compare operation. */
198*08b48e0bSAndroid Build Coastguard Worker unsigned char attr = 0;
199*08b48e0bSAndroid Build Coastguard Worker
200*08b48e0bSAndroid Build Coastguard Worker switch (code) {
201*08b48e0bSAndroid Build Coastguard Worker
202*08b48e0bSAndroid Build Coastguard Worker case UNORDERED_EXPR:
203*08b48e0bSAndroid Build Coastguard Worker case ORDERED_EXPR:
204*08b48e0bSAndroid Build Coastguard Worker /* ??? */
205*08b48e0bSAndroid Build Coastguard Worker /* Fallthrough. */
206*08b48e0bSAndroid Build Coastguard Worker case NE_EXPR:
207*08b48e0bSAndroid Build Coastguard Worker case LTGT_EXPR:
208*08b48e0bSAndroid Build Coastguard Worker break;
209*08b48e0bSAndroid Build Coastguard Worker
210*08b48e0bSAndroid Build Coastguard Worker case EQ_EXPR:
211*08b48e0bSAndroid Build Coastguard Worker case UNEQ_EXPR:
212*08b48e0bSAndroid Build Coastguard Worker attr += 1;
213*08b48e0bSAndroid Build Coastguard Worker break;
214*08b48e0bSAndroid Build Coastguard Worker
215*08b48e0bSAndroid Build Coastguard Worker case GT_EXPR:
216*08b48e0bSAndroid Build Coastguard Worker case UNGT_EXPR:
217*08b48e0bSAndroid Build Coastguard Worker attr += 2;
218*08b48e0bSAndroid Build Coastguard Worker break;
219*08b48e0bSAndroid Build Coastguard Worker
220*08b48e0bSAndroid Build Coastguard Worker case GE_EXPR:
221*08b48e0bSAndroid Build Coastguard Worker case UNGE_EXPR:
222*08b48e0bSAndroid Build Coastguard Worker attr += 3;
223*08b48e0bSAndroid Build Coastguard Worker break;
224*08b48e0bSAndroid Build Coastguard Worker
225*08b48e0bSAndroid Build Coastguard Worker case LT_EXPR:
226*08b48e0bSAndroid Build Coastguard Worker case UNLT_EXPR:
227*08b48e0bSAndroid Build Coastguard Worker attr += 4;
228*08b48e0bSAndroid Build Coastguard Worker break;
229*08b48e0bSAndroid Build Coastguard Worker
230*08b48e0bSAndroid Build Coastguard Worker case LE_EXPR:
231*08b48e0bSAndroid Build Coastguard Worker case UNLE_EXPR:
232*08b48e0bSAndroid Build Coastguard Worker attr += 5;
233*08b48e0bSAndroid Build Coastguard Worker break;
234*08b48e0bSAndroid Build Coastguard Worker
235*08b48e0bSAndroid Build Coastguard Worker default:
236*08b48e0bSAndroid Build Coastguard Worker gcc_unreachable();
237*08b48e0bSAndroid Build Coastguard Worker
238*08b48e0bSAndroid Build Coastguard Worker }
239*08b48e0bSAndroid Build Coastguard Worker
240*08b48e0bSAndroid Build Coastguard Worker if (FLOAT_TYPE_P(TREE_TYPE(lhs))) {
241*08b48e0bSAndroid Build Coastguard Worker
242*08b48e0bSAndroid Build Coastguard Worker attr += 8;
243*08b48e0bSAndroid Build Coastguard Worker
244*08b48e0bSAndroid Build Coastguard Worker tree t = build_nonstandard_integer_type(sz, 1);
245*08b48e0bSAndroid Build Coastguard Worker
246*08b48e0bSAndroid Build Coastguard Worker tree s = make_ssa_name(t);
247*08b48e0bSAndroid Build Coastguard Worker gimple g = gimple_build_assign(s, VIEW_CONVERT_EXPR,
248*08b48e0bSAndroid Build Coastguard Worker build1(VIEW_CONVERT_EXPR, t, lhs));
249*08b48e0bSAndroid Build Coastguard Worker lhs = s;
250*08b48e0bSAndroid Build Coastguard Worker gsi_insert_before(&gsi, g, GSI_SAME_STMT);
251*08b48e0bSAndroid Build Coastguard Worker
252*08b48e0bSAndroid Build Coastguard Worker s = make_ssa_name(t);
253*08b48e0bSAndroid Build Coastguard Worker g = gimple_build_assign(s, VIEW_CONVERT_EXPR,
254*08b48e0bSAndroid Build Coastguard Worker build1(VIEW_CONVERT_EXPR, t, rhs));
255*08b48e0bSAndroid Build Coastguard Worker rhs = s;
256*08b48e0bSAndroid Build Coastguard Worker gsi_insert_before(&gsi, g, GSI_SAME_STMT);
257*08b48e0bSAndroid Build Coastguard Worker
258*08b48e0bSAndroid Build Coastguard Worker }
259*08b48e0bSAndroid Build Coastguard Worker
260*08b48e0bSAndroid Build Coastguard Worker /* Convert the operands to the hook arg type, if needed. */
261*08b48e0bSAndroid Build Coastguard Worker tree t = TREE_VALUE(TYPE_ARG_TYPES(TREE_TYPE(fn)));
262*08b48e0bSAndroid Build Coastguard Worker
263*08b48e0bSAndroid Build Coastguard Worker lhs = fold_convert_loc(UNKNOWN_LOCATION, t, lhs);
264*08b48e0bSAndroid Build Coastguard Worker if (!is_gimple_val(lhs)) {
265*08b48e0bSAndroid Build Coastguard Worker
266*08b48e0bSAndroid Build Coastguard Worker tree s = make_ssa_name(t);
267*08b48e0bSAndroid Build Coastguard Worker gimple g = gimple_build_assign(s, lhs);
268*08b48e0bSAndroid Build Coastguard Worker lhs = s;
269*08b48e0bSAndroid Build Coastguard Worker gsi_insert_before(&gsi, g, GSI_SAME_STMT);
270*08b48e0bSAndroid Build Coastguard Worker
271*08b48e0bSAndroid Build Coastguard Worker }
272*08b48e0bSAndroid Build Coastguard Worker
273*08b48e0bSAndroid Build Coastguard Worker rhs = fold_convert_loc(UNKNOWN_LOCATION, t, rhs);
274*08b48e0bSAndroid Build Coastguard Worker if (!is_gimple_val(rhs)) {
275*08b48e0bSAndroid Build Coastguard Worker
276*08b48e0bSAndroid Build Coastguard Worker tree s = make_ssa_name(t);
277*08b48e0bSAndroid Build Coastguard Worker gimple g = gimple_build_assign(s, rhs);
278*08b48e0bSAndroid Build Coastguard Worker rhs = s;
279*08b48e0bSAndroid Build Coastguard Worker gsi_insert_before(&gsi, g, GSI_SAME_STMT);
280*08b48e0bSAndroid Build Coastguard Worker
281*08b48e0bSAndroid Build Coastguard Worker }
282*08b48e0bSAndroid Build Coastguard Worker
283*08b48e0bSAndroid Build Coastguard Worker /* Insert the call. */
284*08b48e0bSAndroid Build Coastguard Worker tree att = build_int_cst(t8u, attr);
285*08b48e0bSAndroid Build Coastguard Worker gimple call;
286*08b48e0bSAndroid Build Coastguard Worker if (pass_n)
287*08b48e0bSAndroid Build Coastguard Worker call = gimple_build_call(fn, 4, lhs, rhs, att,
288*08b48e0bSAndroid Build Coastguard Worker build_int_cst(t8u, sz / 8 - 1));
289*08b48e0bSAndroid Build Coastguard Worker else
290*08b48e0bSAndroid Build Coastguard Worker call = gimple_build_call(fn, 3, lhs, rhs, att);
291*08b48e0bSAndroid Build Coastguard Worker
292*08b48e0bSAndroid Build Coastguard Worker gsi_insert_before(&gsi, call, GSI_SAME_STMT);
293*08b48e0bSAndroid Build Coastguard Worker
294*08b48e0bSAndroid Build Coastguard Worker }
295*08b48e0bSAndroid Build Coastguard Worker
execute__anon0e48c2980111::afl_cmplog_pass296*08b48e0bSAndroid Build Coastguard Worker virtual unsigned int execute(function *fn) {
297*08b48e0bSAndroid Build Coastguard Worker
298*08b48e0bSAndroid Build Coastguard Worker if (!isInInstrumentList(fn)) return 0;
299*08b48e0bSAndroid Build Coastguard Worker
300*08b48e0bSAndroid Build Coastguard Worker basic_block bb;
301*08b48e0bSAndroid Build Coastguard Worker FOR_EACH_BB_FN(bb, fn) {
302*08b48e0bSAndroid Build Coastguard Worker
303*08b48e0bSAndroid Build Coastguard Worker /* A GIMPLE_COND or GIMPLE_SWITCH will always be the last stmt
304*08b48e0bSAndroid Build Coastguard Worker in a BB. */
305*08b48e0bSAndroid Build Coastguard Worker gimple_stmt_iterator gsi = gsi_last_bb(bb);
306*08b48e0bSAndroid Build Coastguard Worker if (gsi_end_p(gsi)) continue;
307*08b48e0bSAndroid Build Coastguard Worker
308*08b48e0bSAndroid Build Coastguard Worker gimple stmt = gsi_stmt(gsi);
309*08b48e0bSAndroid Build Coastguard Worker
310*08b48e0bSAndroid Build Coastguard Worker if (gimple_code(stmt) == GIMPLE_COND) {
311*08b48e0bSAndroid Build Coastguard Worker
312*08b48e0bSAndroid Build Coastguard Worker tree_code code = gimple_cond_code(stmt);
313*08b48e0bSAndroid Build Coastguard Worker tree lhs = gimple_cond_lhs(stmt);
314*08b48e0bSAndroid Build Coastguard Worker tree rhs = gimple_cond_rhs(stmt);
315*08b48e0bSAndroid Build Coastguard Worker
316*08b48e0bSAndroid Build Coastguard Worker insert_cmplog_call(gsi, code, lhs, rhs);
317*08b48e0bSAndroid Build Coastguard Worker
318*08b48e0bSAndroid Build Coastguard Worker } else if (gimple_code(stmt) == GIMPLE_SWITCH) {
319*08b48e0bSAndroid Build Coastguard Worker
320*08b48e0bSAndroid Build Coastguard Worker gswitch *sw = as_a<gswitch *>(stmt);
321*08b48e0bSAndroid Build Coastguard Worker tree lhs = gimple_switch_index(sw);
322*08b48e0bSAndroid Build Coastguard Worker
323*08b48e0bSAndroid Build Coastguard Worker for (int i = 0, e = gimple_switch_num_labels(sw); i < e; i++) {
324*08b48e0bSAndroid Build Coastguard Worker
325*08b48e0bSAndroid Build Coastguard Worker tree clx = gimple_switch_label(sw, i);
326*08b48e0bSAndroid Build Coastguard Worker tree rhsl = CASE_LOW(clx);
327*08b48e0bSAndroid Build Coastguard Worker /* Default case labels exprs don't have a CASE_LOW. */
328*08b48e0bSAndroid Build Coastguard Worker if (!rhsl) continue;
329*08b48e0bSAndroid Build Coastguard Worker tree rhsh = CASE_HIGH(clx);
330*08b48e0bSAndroid Build Coastguard Worker /* If there is a CASE_HIGH, issue range compares. */
331*08b48e0bSAndroid Build Coastguard Worker if (rhsh) {
332*08b48e0bSAndroid Build Coastguard Worker
333*08b48e0bSAndroid Build Coastguard Worker insert_cmplog_call(gsi, GE_EXPR, lhs, rhsl);
334*08b48e0bSAndroid Build Coastguard Worker insert_cmplog_call(gsi, LE_EXPR, lhs, rhsh);
335*08b48e0bSAndroid Build Coastguard Worker
336*08b48e0bSAndroid Build Coastguard Worker }
337*08b48e0bSAndroid Build Coastguard Worker
338*08b48e0bSAndroid Build Coastguard Worker /* Otherwise, use a single equality compare. */
339*08b48e0bSAndroid Build Coastguard Worker else
340*08b48e0bSAndroid Build Coastguard Worker insert_cmplog_call(gsi, EQ_EXPR, lhs, rhsl);
341*08b48e0bSAndroid Build Coastguard Worker
342*08b48e0bSAndroid Build Coastguard Worker }
343*08b48e0bSAndroid Build Coastguard Worker
344*08b48e0bSAndroid Build Coastguard Worker } else
345*08b48e0bSAndroid Build Coastguard Worker
346*08b48e0bSAndroid Build Coastguard Worker continue;
347*08b48e0bSAndroid Build Coastguard Worker
348*08b48e0bSAndroid Build Coastguard Worker }
349*08b48e0bSAndroid Build Coastguard Worker
350*08b48e0bSAndroid Build Coastguard Worker return 0;
351*08b48e0bSAndroid Build Coastguard Worker
352*08b48e0bSAndroid Build Coastguard Worker }
353*08b48e0bSAndroid Build Coastguard Worker
354*08b48e0bSAndroid Build Coastguard Worker };
355*08b48e0bSAndroid Build Coastguard Worker
356*08b48e0bSAndroid Build Coastguard Worker static struct plugin_info afl_cmplog_plugin = {
357*08b48e0bSAndroid Build Coastguard Worker
358*08b48e0bSAndroid Build Coastguard Worker .version = "20220420",
359*08b48e0bSAndroid Build Coastguard Worker .help = G_("AFL gcc cmplog plugin\n\
360*08b48e0bSAndroid Build Coastguard Worker \n\
361*08b48e0bSAndroid Build Coastguard Worker Set AFL_QUIET in the environment to silence it.\n\
362*08b48e0bSAndroid Build Coastguard Worker "),
363*08b48e0bSAndroid Build Coastguard Worker
364*08b48e0bSAndroid Build Coastguard Worker };
365*08b48e0bSAndroid Build Coastguard Worker
366*08b48e0bSAndroid Build Coastguard Worker } // namespace
367*08b48e0bSAndroid Build Coastguard Worker
368*08b48e0bSAndroid Build Coastguard Worker /* This is the function GCC calls when loading a plugin. Initialize
369*08b48e0bSAndroid Build Coastguard Worker and register further callbacks. */
plugin_init(struct plugin_name_args * info,struct plugin_gcc_version * version)370*08b48e0bSAndroid Build Coastguard Worker int plugin_init(struct plugin_name_args *info,
371*08b48e0bSAndroid Build Coastguard Worker struct plugin_gcc_version *version) {
372*08b48e0bSAndroid Build Coastguard Worker
373*08b48e0bSAndroid Build Coastguard Worker if (!plugin_default_version_check(version, &gcc_version))
374*08b48e0bSAndroid Build Coastguard Worker FATAL(G_("GCC and plugin have incompatible versions, expected GCC %s, "
375*08b48e0bSAndroid Build Coastguard Worker "is %s"),
376*08b48e0bSAndroid Build Coastguard Worker gcc_version.basever, version->basever);
377*08b48e0bSAndroid Build Coastguard Worker
378*08b48e0bSAndroid Build Coastguard Worker /* Show a banner. */
379*08b48e0bSAndroid Build Coastguard Worker bool quiet = false;
380*08b48e0bSAndroid Build Coastguard Worker if (isatty(2) && !getenv("AFL_QUIET"))
381*08b48e0bSAndroid Build Coastguard Worker SAYF(cCYA "afl-gcc-cmplog-pass " cBRI VERSION cRST
382*08b48e0bSAndroid Build Coastguard Worker " by <[email protected]>\n");
383*08b48e0bSAndroid Build Coastguard Worker else
384*08b48e0bSAndroid Build Coastguard Worker quiet = true;
385*08b48e0bSAndroid Build Coastguard Worker
386*08b48e0bSAndroid Build Coastguard Worker const char *name = info->base_name;
387*08b48e0bSAndroid Build Coastguard Worker register_callback(name, PLUGIN_INFO, NULL, &afl_cmplog_plugin);
388*08b48e0bSAndroid Build Coastguard Worker
389*08b48e0bSAndroid Build Coastguard Worker afl_cmplog_pass *aflp = new afl_cmplog_pass(quiet);
390*08b48e0bSAndroid Build Coastguard Worker struct register_pass_info pass_info = {
391*08b48e0bSAndroid Build Coastguard Worker
392*08b48e0bSAndroid Build Coastguard Worker .pass = aflp,
393*08b48e0bSAndroid Build Coastguard Worker .reference_pass_name = "ssa",
394*08b48e0bSAndroid Build Coastguard Worker .ref_pass_instance_number = 1,
395*08b48e0bSAndroid Build Coastguard Worker .pos_op = PASS_POS_INSERT_AFTER,
396*08b48e0bSAndroid Build Coastguard Worker
397*08b48e0bSAndroid Build Coastguard Worker };
398*08b48e0bSAndroid Build Coastguard Worker
399*08b48e0bSAndroid Build Coastguard Worker register_callback(name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
400*08b48e0bSAndroid Build Coastguard Worker
401*08b48e0bSAndroid Build Coastguard Worker return 0;
402*08b48e0bSAndroid Build Coastguard Worker
403*08b48e0bSAndroid Build Coastguard Worker }
404*08b48e0bSAndroid Build Coastguard Worker
405