xref: /aosp_15_r20/external/AFLplusplus/instrumentation/afl-gcc-cmplog-pass.so.cc (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
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