1 /*
2 american fuzzy lop++ - debug / error handling macros
3 ----------------------------------------------------
4
5 Originally written by Michal Zalewski
6
7 Now maintained by Marc Heuse <[email protected]>,
8 Heiko Eißfeldt <[email protected]>,
9 Andrea Fioraldi <[email protected]>,
10 Dominik Maier <[email protected]>
11
12 Copyright 2016, 2017 Google Inc. All rights reserved.
13 Copyright 2019-2024 AFLplusplus Project. All rights reserved.
14
15 Licensed under the Apache License, Version 2.0 (the "License");
16 you may not use this file except in compliance with the License.
17 You may obtain a copy of the License at:
18
19 https://www.apache.org/licenses/LICENSE-2.0
20
21 */
22
23 #ifndef _HAVE_DEBUG_H
24 #define _HAVE_DEBUG_H
25
26 #include <errno.h>
27
28 #include "types.h"
29 #include "config.h"
30
31 /*******************
32 * Terminal colors *
33 *******************/
34
35 #ifndef MESSAGES_TO_STDOUT
36 #define MESSAGES_TO_STDOUT
37 #endif
38
39 #ifdef USE_COLOR
40
41 #define cBLK "\x1b[0;30m"
42 #define cRED "\x1b[0;31m"
43 #define cGRN "\x1b[0;32m"
44 #define cBRN "\x1b[0;33m"
45 #define cBLU "\x1b[0;34m"
46 #define cMGN "\x1b[0;35m"
47 #define cCYA "\x1b[0;36m"
48 #define cLGR "\x1b[0;37m"
49 #define cGRA "\x1b[1;90m"
50 #define cLRD "\x1b[1;91m"
51 #define cLGN "\x1b[1;92m"
52 #define cYEL "\x1b[1;93m"
53 #define cLBL "\x1b[1;94m"
54 #define cPIN "\x1b[1;95m"
55 #define cLCY "\x1b[1;96m"
56 #define cBRI "\x1b[1;97m"
57 #define cRST "\x1b[0m"
58
59 #define bgBLK "\x1b[40m"
60 #define bgRED "\x1b[41m"
61 #define bgGRN "\x1b[42m"
62 #define bgBRN "\x1b[43m"
63 #define bgBLU "\x1b[44m"
64 #define bgMGN "\x1b[45m"
65 #define bgCYA "\x1b[46m"
66 #define bgLGR "\x1b[47m"
67 #define bgGRA "\x1b[100m"
68 #define bgLRD "\x1b[101m"
69 #define bgLGN "\x1b[102m"
70 #define bgYEL "\x1b[103m"
71 #define bgLBL "\x1b[104m"
72 #define bgPIN "\x1b[105m"
73 #define bgLCY "\x1b[106m"
74 #define bgBRI "\x1b[107m"
75
76 #else
77
78 #define cBLK ""
79 #define cRED ""
80 #define cGRN ""
81 #define cBRN ""
82 #define cBLU ""
83 #define cMGN ""
84 #define cCYA ""
85 #define cLGR ""
86 #define cGRA ""
87 #define cLRD ""
88 #define cLGN ""
89 #define cYEL ""
90 #define cLBL ""
91 #define cPIN ""
92 #define cLCY ""
93 #define cBRI ""
94 #define cRST ""
95
96 #define bgBLK ""
97 #define bgRED ""
98 #define bgGRN ""
99 #define bgBRN ""
100 #define bgBLU ""
101 #define bgMGN ""
102 #define bgCYA ""
103 #define bgLGR ""
104 #define bgGRA ""
105 #define bgLRD ""
106 #define bgLGN ""
107 #define bgYEL ""
108 #define bgLBL ""
109 #define bgPIN ""
110 #define bgLCY ""
111 #define bgBRI ""
112
113 #endif /* ^USE_COLOR */
114
115 /*************************
116 * Box drawing sequences *
117 *************************/
118
119 #ifdef FANCY_BOXES_NO_UTF
120
121 #define SET_G1 "\x1b)0" /* Set G1 for box drawing */
122 #define RESET_G1 "\x1b)B" /* Reset G1 to ASCII */
123 #define bSTART "\x0e" /* Enter G1 drawing mode */
124 #define bSTOP "\x0f" /* Leave G1 drawing mode */
125 #define bH "q" /* Horizontal line */
126 #define bV "x" /* Vertical line */
127 #define bLT "l" /* Left top corner */
128 #define bRT "k" /* Right top corner */
129 #define bLB "m" /* Left bottom corner */
130 #define bRB "j" /* Right bottom corner */
131 #define bX "n" /* Cross */
132 #define bVR "t" /* Vertical, branch right */
133 #define bVL "u" /* Vertical, branch left */
134 #define bHT "v" /* Horizontal, branch top */
135 #define bHB "w" /* Horizontal, branch bottom */
136
137 #else
138
139 #ifdef FANCY_BOXES
140
141 #define SET_G1 ""
142 #define RESET_G1 ""
143 #define bSTART ""
144 #define bSTOP ""
145 #define bH "\u2500" /* Horizontal line */
146 #define bV "\u2502" /* Vertical line */
147 #define bLT "\u250c" /* Left top corner */
148 #define bRT "\u2510" /* Right top corner */
149 #define bLB "\u2514" /* Left bottom corner */
150 #define bRB "\u2518" /* Right bottom corner */
151 #define bX "\u253c" /* Cross */
152 #define bVR "\u251c" /* Vertical, branch right */
153 #define bVL "\u2524" /* Vertical, branch left */
154 #define bHT "\u2534" /* Horizontal, branch top */
155 #define bHB "\u252c" /* Horizontal, branch bottom */
156
157 #else
158
159 #define SET_G1 ""
160 #define RESET_G1 ""
161 #define bSTART ""
162 #define bSTOP ""
163 #define bH "-"
164 #define bV "|"
165 #define bLT "+"
166 #define bRT "+"
167 #define bLB "+"
168 #define bRB "+"
169 #define bX "+"
170 #define bVR "+"
171 #define bVL "+"
172 #define bHT "+"
173 #define bHB "+"
174
175 #endif
176 #endif /* ^FANCY_BOXES */
177
178 /***********************
179 * Misc terminal codes *
180 ***********************/
181
182 #define TERM_HOME "\x1b[H"
183 #define TERM_CLEAR TERM_HOME "\x1b[2J"
184 #define cEOL "\x1b[0K"
185 #define CURSOR_HIDE "\x1b[?25l"
186 #define CURSOR_SHOW "\x1b[?25h"
187
188 /************************
189 * Debug & error macros *
190 ************************/
191
192 #if defined USE_COLOR && !defined ALWAYS_COLORED
193 #include <unistd.h>
194 #pragma GCC diagnostic ignored "-Wformat-security"
colorfilter(const char * x)195 static inline const char *colorfilter(const char *x) {
196
197 static int once = 1;
198 static int disabled = 0;
199
200 if (once) {
201
202 /* when there is no tty -> we always want filtering
203 * when AFL_NO_UI is set filtering depends on AFL_NO_COLOR
204 * otherwise we want always colors
205 */
206 disabled =
207 isatty(2) && (!getenv("AFL_NO_UI") ||
208 (!getenv("AFL_NO_COLOR") && !getenv("AFL_NO_COLOUR")));
209 once = 0;
210
211 }
212
213 if (likely(disabled)) return x;
214
215 static char monochromestring[4096];
216 char *d = monochromestring;
217 int in_seq = 0;
218
219 while (*x) {
220
221 if (in_seq && *x == 'm') {
222
223 in_seq = 0;
224
225 } else {
226
227 if (!in_seq && *x == '\x1b') { in_seq = 1; }
228 if (!in_seq) { *d++ = *x; }
229
230 }
231
232 ++x;
233
234 }
235
236 *d = '\0';
237 return monochromestring;
238
239 }
240
241 #else
242 #define colorfilter(x) x /* no filtering necessary */
243 #endif
244
245 /* macro magic to transform the first parameter to SAYF
246 * through colorfilter which strips coloring */
247 #define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, \
248 _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, \
249 _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, \
250 _39, _40, NAME, ...) \
251 NAME
252
253 #define SAYF(...) \
254 GET_MACRO(__VA_ARGS__, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \
255 SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \
256 SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \
257 SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \
258 SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \
259 SAYF_N, SAYF_1) \
260 (__VA_ARGS__)
261
262 #define SAYF_1(x) MY_SAYF(colorfilter(x))
263 #define SAYF_N(x, ...) MY_SAYF(colorfilter(x), __VA_ARGS__)
264
265 /* Just print stuff to the appropriate stream. */
266 #ifdef MESSAGES_TO_STDOUT
267 #define MY_SAYF(x...) printf(x)
268 #else
269 #define MY_SAYF(x...) fprintf(stderr, x)
270 #endif /* ^MESSAGES_TO_STDOUT */
271
272 /* Show a prefixed warning. */
273
274 #define WARNF(x...) \
275 do { \
276 \
277 SAYF(cYEL "[!] " cBRI "WARNING: " cRST x); \
278 SAYF(cRST "\n"); \
279 \
280 } while (0)
281
282 /* Show a prefixed "doing something" message. */
283
284 #define ACTF(x...) \
285 do { \
286 \
287 SAYF(cLBL "[*] " cRST x); \
288 SAYF(cRST "\n"); \
289 \
290 } while (0)
291
292 /* Show a prefixed "success" message. */
293
294 #define OKF(x...) \
295 do { \
296 \
297 SAYF(cLGN "[+] " cRST x); \
298 SAYF(cRST "\n"); \
299 \
300 } while (0)
301
302 /* Show a prefixed fatal error message (not used in afl). */
303
304 #define BADF(x...) \
305 do { \
306 \
307 SAYF(cLRD "\n[-] " cRST x); \
308 SAYF(cRST "\n"); \
309 \
310 } while (0)
311
312 /* Die with a verbose non-OS fatal error message. */
313
314 #define FATAL(x...) \
315 do { \
316 \
317 SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
318 "\n[-] PROGRAM ABORT : " cRST x); \
319 SAYF(cLRD "\n Location : " cRST "%s(), %s:%u\n\n", __func__, \
320 __FILE__, (u32)__LINE__); \
321 exit(1); \
322 \
323 } while (0)
324
325 /* Die by calling abort() to provide a core dump. */
326
327 #define ABORT(x...) \
328 do { \
329 \
330 SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
331 "\n[-] PROGRAM ABORT : " cRST x); \
332 SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n\n", __func__, \
333 __FILE__, (u32)__LINE__); \
334 abort(); \
335 \
336 } while (0)
337
338 /* Die while also including the output of perror(). */
339
340 #define PFATAL(x...) \
341 do { \
342 \
343 fflush(stdout); \
344 SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
345 "\n[-] SYSTEM ERROR : " cRST x); \
346 SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n", __func__, \
347 __FILE__, (u32)__LINE__); \
348 SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \
349 exit(1); \
350 \
351 } while (0)
352
353 /* Die with FATAL() or PFATAL() depending on the value of res (used to
354 interpret different failure modes for read(), write(), etc). */
355
356 #define RPFATAL(res, x...) \
357 do { \
358 \
359 if (res < 0) \
360 PFATAL(x); \
361 else \
362 FATAL(x); \
363 \
364 } while (0)
365
366 /* Show a prefixed debug output. */
367
368 #define DEBUGF(x...) \
369 do { \
370 \
371 fprintf(stderr, cMGN "[D] " cBRI "DEBUG: " cRST x); \
372 fprintf(stderr, cRST ""); \
373 \
374 } while (0)
375
376 /* Error-checking versions of read() and write() that call RPFATAL() as
377 appropriate. */
378
379 #define ck_write(fd, buf, len, fn) \
380 do { \
381 \
382 if (len <= 0) break; \
383 int _fd = (fd); \
384 s32 _written = 0, _off = 0, _len = (s32)(len); \
385 \
386 do { \
387 \
388 s32 _res = write(_fd, (buf) + _off, _len); \
389 if (_res != _len && (_res > 0 && _written + _res != _len)) { \
390 \
391 if (_res > 0) { \
392 \
393 _written += _res; \
394 _len -= _res; \
395 _off += _res; \
396 \
397 } else { \
398 \
399 RPFATAL(_res, "Short write to %s, fd %d (%d of %d bytes)", fn, _fd, \
400 _res, _len); \
401 \
402 } \
403 \
404 } else { \
405 \
406 break; \
407 \
408 } \
409 \
410 } while (1); \
411 \
412 \
413 \
414 } while (0)
415
416 #define ck_read(fd, buf, len, fn) \
417 do { \
418 \
419 s32 _len = (s32)(len); \
420 s32 _res = read(fd, buf, _len); \
421 if (_res != _len) RPFATAL(_res, "Short read from %s", fn); \
422 \
423 } while (0)
424
425 #endif /* ! _HAVE_DEBUG_H */
426
427