@@ -34,6 +34,8 @@ __visible int plugin_is_GPL_compatible;
34
34
static int track_frame_size = -1 ;
35
35
static bool build_for_x86 = false;
36
36
static const char track_function [] = "stackleak_track_stack" ;
37
+ static bool disable = false;
38
+ static bool verbose = false;
37
39
38
40
/*
39
41
* Mark these global variables (roots) for gcc garbage collector since
@@ -46,6 +48,7 @@ static struct plugin_info stackleak_plugin_info = {
46
48
.help = "track-min-size=nn\ttrack stack for functions with a stack frame size >= nn bytes\n"
47
49
"arch=target_arch\tspecify target build arch\n"
48
50
"disable\t\tdo not activate the plugin\n"
51
+ "verbose\t\tprint info about the instrumentation\n"
49
52
};
50
53
51
54
static void add_stack_tracking_gcall (gimple_stmt_iterator * gsi , bool after )
@@ -102,6 +105,10 @@ static tree get_current_stack_pointer_decl(void)
102
105
return var ;
103
106
}
104
107
108
+ if (verbose ) {
109
+ fprintf (stderr , "stackleak: missing current_stack_pointer in %s()\n" ,
110
+ DECL_NAME_POINTER (current_function_decl ));
111
+ }
105
112
return NULL_TREE ;
106
113
}
107
114
@@ -195,6 +202,11 @@ static unsigned int stackleak_instrument_execute(void)
195
202
if (!is_alloca (stmt ))
196
203
continue ;
197
204
205
+ if (verbose ) {
206
+ fprintf (stderr , "stackleak: be careful, alloca() in %s()\n" ,
207
+ DECL_NAME_POINTER (current_function_decl ));
208
+ }
209
+
198
210
/* Insert stackleak_track_stack() call after alloca() */
199
211
add_stack_tracking (& gsi , true);
200
212
if (bb == entry_bb )
@@ -384,13 +396,31 @@ static bool remove_stack_tracking_gasm(void)
384
396
*/
385
397
static unsigned int stackleak_cleanup_execute (void )
386
398
{
399
+ const char * fn = DECL_NAME_POINTER (current_function_decl );
387
400
bool removed = false;
388
401
389
- if (cfun -> calls_alloca )
402
+ /*
403
+ * Leave stack tracking in functions that call alloca().
404
+ * Additional case:
405
+ * gcc before version 7 called allocate_dynamic_stack_space() from
406
+ * expand_stack_vars() for runtime alignment of constant-sized stack
407
+ * variables. That caused cfun->calls_alloca to be set for functions
408
+ * that in fact don't use alloca().
409
+ * For more info see gcc commit 7072df0aae0c59ae437e.
410
+ * Let's leave such functions instrumented as well.
411
+ */
412
+ if (cfun -> calls_alloca ) {
413
+ if (verbose )
414
+ fprintf (stderr , "stackleak: instrument %s(): calls_alloca\n" , fn );
390
415
return 0 ;
416
+ }
391
417
392
- if (large_stack_frame ())
418
+ /* Leave stack tracking in functions with large stack frame */
419
+ if (large_stack_frame ()) {
420
+ if (verbose )
421
+ fprintf (stderr , "stackleak: instrument %s()\n" , fn );
393
422
return 0 ;
423
+ }
394
424
395
425
if (lookup_attribute_spec (get_identifier ("no_caller_saved_registers" )))
396
426
removed = remove_stack_tracking_gasm ();
@@ -516,9 +546,6 @@ __visible int plugin_init(struct plugin_name_args *plugin_info,
516
546
517
547
/* Parse the plugin arguments */
518
548
for (i = 0 ; i < argc ; i ++ ) {
519
- if (!strcmp (argv [i ].key , "disable" ))
520
- return 0 ;
521
-
522
549
if (!strcmp (argv [i ].key , "track-min-size" )) {
523
550
if (!argv [i ].value ) {
524
551
error (G_ ("no value supplied for option '-fplugin-arg-%s-%s'" ),
@@ -541,13 +568,23 @@ __visible int plugin_init(struct plugin_name_args *plugin_info,
541
568
542
569
if (!strcmp (argv [i ].value , "x86" ))
543
570
build_for_x86 = true;
571
+ } else if (!strcmp (argv [i ].key , "disable" )) {
572
+ disable = true;
573
+ } else if (!strcmp (argv [i ].key , "verbose" )) {
574
+ verbose = true;
544
575
} else {
545
576
error (G_ ("unknown option '-fplugin-arg-%s-%s'" ),
546
577
plugin_name , argv [i ].key );
547
578
return 1 ;
548
579
}
549
580
}
550
581
582
+ if (disable ) {
583
+ if (verbose )
584
+ fprintf (stderr , "stackleak: disabled for this translation unit\n" );
585
+ return 0 ;
586
+ }
587
+
551
588
/* Give the information about the plugin */
552
589
register_callback (plugin_name , PLUGIN_INFO , NULL ,
553
590
& stackleak_plugin_info );
0 commit comments