34
34
35
35
using namespace e9frontend ;
36
36
37
- #include " e9cfg.cpp"
38
-
39
37
#define AREA_BASE 0x200000
40
38
#define AREA_SIZE ((size_t )1 << 16 )
41
39
@@ -79,6 +77,12 @@ struct BB
79
77
typedef std::map<intptr_t , BB> CFG;
80
78
#define BB_INDIRECT (-1 )
81
79
80
+ /*
81
+ * Misc.
82
+ */
83
+ typedef std::map<BB *, BB *> Paths;
84
+ typedef std::map<intptr_t , unsigned > Ids;
85
+
82
86
/*
83
87
* To compile:
84
88
* $ g++ -std=c++11 -fPIC -shared -o e9afl.so -O2 e9afl.cpp \
@@ -186,7 +190,7 @@ extern void *e9_plugin_init_v1(FILE *out, const ELF *elf)
186
190
<< " {\" int32\" :" << stack_adjust << " }," ;
187
191
code << " \" $instruction\" ,\" $continue\" " ;
188
192
189
- sendTrampolineMessage (out, " afl" , code.str ().c_str ());
193
+ sendTrampolineMessage (out, " $ afl" , code.str ().c_str ());
190
194
191
195
return nullptr ;
192
196
}
@@ -217,7 +221,7 @@ static void addPredecessor(intptr_t pred, intptr_t succ,
217
221
static void addSuccessor (intptr_t pred, intptr_t succ,
218
222
const Targets &targets, CFG &cfg)
219
223
{
220
- auto i = targets.find (pred);
224
+ auto i = targets.lower_bound (pred);
221
225
if (i == targets.end ())
222
226
return ;
223
227
auto j = cfg.find (pred);
@@ -314,17 +318,26 @@ static void buildCFG(const ELF *elf, const Instr *Is, size_t size,
314
318
/*
315
319
* Attempt to optimize away a bad block.
316
320
*/
317
- typedef std::map<BB * , BB *> Paths ;
321
+ static void optimizeBlock (CFG &cfg , BB &bb) ;
318
322
static void optimizePaths (CFG &cfg, BB *pred_bb, BB *succ_bb, Paths &paths)
319
323
{
320
324
auto i = paths.find (succ_bb);
321
325
if (i != paths.end ())
322
326
{
323
327
// Multiple paths to succ_bb;
328
+ BB *unopt_bb = nullptr ;
324
329
if (pred_bb != nullptr )
325
- pred_bb-> optimized = false ;
330
+ unopt_bb = pred_bb ;
326
331
else if (i->second != nullptr )
327
- i->second ->optimized = false ;
332
+ unopt_bb = i->second ;
333
+
334
+ // Note: (unopt_bb == nullptr) can happen in degenerate cases, e.g.:
335
+ // jne .Lnext; .Lnext: ...
336
+ if (unopt_bb != nullptr )
337
+ {
338
+ unopt_bb->optimized = false ;
339
+ optimizeBlock (cfg, *unopt_bb);
340
+ }
328
341
return ;
329
342
}
330
343
paths.insert ({succ_bb, pred_bb});
@@ -339,7 +352,7 @@ static void optimizePaths(CFG &cfg, BB *pred_bb, BB *succ_bb, Paths &paths)
339
352
optimizePaths (cfg, pred_bb, succ_bb, paths);
340
353
}
341
354
}
342
- static void optimizeBlock (CFG &cfg, intptr_t entry, BB &bb)
355
+ static void optimizeBlock (CFG &cfg, BB &bb)
343
356
{
344
357
if (bb.optimized )
345
358
return ;
@@ -355,39 +368,40 @@ static void optimizeBlock(CFG &cfg, intptr_t entry, BB &bb)
355
368
/*
356
369
* Verify the optimization is correct (for debugging).
357
370
*/
358
- static void verify (CFG &cfg, const std::map< intptr_t , unsigned > &bbs , BB *bb,
371
+ static void verify (CFG &cfg, const Ids &ids, intptr_t curr , BB *bb,
359
372
std::set<BB *> &seen)
360
373
{
374
+ unsigned id = ids.find (curr)->second ;
361
375
for (auto succ: bb->succs )
362
376
{
363
377
auto i = cfg.find (succ);
364
378
BB *succ_bb = (i == cfg.end ()? nullptr : &i->second );
365
379
if (succ_bb == nullptr )
366
- fprintf (stderr, " indirect" );
380
+ fprintf (stderr, " BB_%u-> indirect" , id );
367
381
else
368
- {
369
- auto j = bbs.find (succ);
370
- fprintf (stderr, " BB_%u" , j->second );
371
- }
382
+ fprintf (stderr, " BB_%u->BB_%u" , id, ids.find (succ)->second );
372
383
auto r = seen.insert (succ_bb);
373
384
if (!r.second )
374
385
{
375
386
putc (' \n ' , stderr);
376
387
error (" multiple non-instrumented paths detected" );
377
388
}
378
- if (succ_bb != nullptr && succ_bb->instrument < 0 )
379
- verify (cfg, bbs , succ_bb, seen);
389
+ if (succ_bb != nullptr && succ_bb->optimized )
390
+ verify (cfg, ids, succ , succ_bb, seen);
380
391
}
381
392
}
382
- static void verify (CFG &cfg, const std::map< intptr_t , unsigned > &bbs )
393
+ static void verify (CFG &cfg, const Ids &ids )
383
394
{
384
395
putc (' \n ' , stderr);
385
396
for (auto &entry: cfg)
386
397
{
387
- auto i = bbs.find (entry.first );
388
- fprintf (stderr, " \33 [32mVERIFY\33 [0m BB_%u:" , i->second );
398
+ BB *bb = &entry.second ;
399
+ if (bb->optimized )
400
+ continue ;
401
+ fprintf (stderr, " \33 [32mVERIFY\33 [0m BB_%u:" ,
402
+ ids.find (entry.first )->second );
389
403
std::set<BB *> seen;
390
- verify (cfg, bbs, & entry.second , seen);
404
+ verify (cfg, ids, entry.first , bb , seen);
391
405
putc (' \n ' , stderr);
392
406
}
393
407
putc (' \n ' , stderr);
@@ -463,7 +477,7 @@ static void calcInstrumentPoints(const ELF *elf, const Instr *Is, size_t size,
463
477
// Step #3: Optimize away bad blocks:
464
478
if (option_Oblock == OPTION_DEFAULT)
465
479
for (auto &entry: cfg)
466
- optimizeBlock (cfg, entry.first , entry. second );
480
+ optimizeBlock (cfg, entry.second );
467
481
468
482
// Step #4: Collect final instrumentation points.
469
483
for (auto &entry: cfg)
@@ -473,12 +487,12 @@ static void calcInstrumentPoints(const ELF *elf, const Instr *Is, size_t size,
473
487
}
474
488
475
489
// Setp #5: Print debugging information (if necessary)
476
- std::map< intptr_t , unsigned > bbs ;
490
+ Ids ids ;
477
491
if (option_debug == OPTION_ALWAYS)
478
492
{
479
493
unsigned bb = 0 ;
480
494
for (const auto &entry: targets)
481
- bbs .insert ({entry.first , bb++});
495
+ ids .insert ({entry.first , bb++});
482
496
}
483
497
for (size_t i = 0 ; (option_debug == OPTION_ALWAYS) && i < size; i++)
484
498
{
@@ -488,7 +502,7 @@ static void calcInstrumentPoints(const ELF *elf, const Instr *Is, size_t size,
488
502
auto j = cfg.find (I->address );
489
503
if (j != cfg.end ())
490
504
{
491
- auto l = bbs .find (I->address );
505
+ auto l = ids .find (I->address );
492
506
fprintf (stderr, " \n # \33 [32mBB_%u\33 [0m%s%s\n " , l->second ,
493
507
(j->second .bad ? " [\33 [31mBAD\33 [0m]" : " " ),
494
508
(j->second .bad && !j->second .optimized ?
@@ -504,7 +518,7 @@ static void calcInstrumentPoints(const ELF *elf, const Instr *Is, size_t size,
504
518
fprintf (stderr, " indirect" );
505
519
continue ;
506
520
}
507
- auto l = bbs .find (pred);
521
+ auto l = ids .find (pred);
508
522
fprintf (stderr, " BB_%u" , l->second );
509
523
}
510
524
fprintf (stderr, " \n # succs = " );
@@ -518,7 +532,7 @@ static void calcInstrumentPoints(const ELF *elf, const Instr *Is, size_t size,
518
532
fprintf (stderr, " indirect" );
519
533
continue ;
520
534
}
521
- auto l = bbs .find (pred);
535
+ auto l = ids .find (pred);
522
536
fprintf (stderr, " BB_%u" , l->second );
523
537
}
524
538
putc (' \n ' , stderr);
@@ -530,7 +544,7 @@ static void calcInstrumentPoints(const ELF *elf, const Instr *Is, size_t size,
530
544
fprintf (stderr, " %lx: %s\n " , I->address , I->string .instr );
531
545
}
532
546
if (option_debug == OPTION_ALWAYS)
533
- verify (cfg, bbs );
547
+ verify (cfg, ids );
534
548
}
535
549
536
550
/*
@@ -595,6 +609,6 @@ extern void e9_plugin_patch_v1(FILE *out, const ELF *elf,
595
609
metadata[2 ].name = nullptr ;
596
610
metadata[2 ].data = nullptr ;
597
611
598
- sendPatchMessage (out, " afl" , info->offset , metadata);
612
+ sendPatchMessage (out, " $ afl" , info->offset , metadata);
599
613
}
600
614
0 commit comments