Patchwork [ubsan] Instrument __builtin_unreachable

login
register
mail settings
Submitter Marek Polacek
Date July 14, 2013, 5:51 p.m.
Message ID <20130714175142.GI3697@redhat.com>
Download mbox | patch
Permalink /patch/258904/
State New
Headers show

Comments

Marek Polacek - July 14, 2013, 5:51 p.m.
On Sun, Jul 14, 2013 at 03:44:40PM +0200, Jakub Jelinek wrote:
> On Sun, Jul 14, 2013 at 07:39:38AM +0200, Marek Polacek wrote:
> > This patch implements sanitizing of the __builtin_unreachable call.
> > A call to __builtin_unreachable only emits BARRIER, if we actually get to it,
> > the behavior is undefined.  So, we just replace the call with a call to
> > the ubsan library, it then issues an error and dies.
> > 
> > The patch is long because I had to pluck some code out of c-family/c-ubsan.c
> > (otherwise we couldn't call ubsan_* routines from builtins.c), I've put
> > the code into ubsan.c.
> > 
> > Commited to ubsan branch.  Comments?
> 
> > --- gcc/builtins.c.mp	2013-07-13 20:01:33.862643705 +0200
> > +++ gcc/builtins.c	2013-07-14 03:11:23.471284429 +0200
> > @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3.
> >  #include "value-prof.h"
> >  #include "diagnostic-core.h"
> >  #include "builtins.h"
> > +#include "ubsan.h"
> 
> You haven't added builtins.o : ubsan.h dependency to the Makefile.in.
> Please double check that for the C/C++ files you've added #include
> in the past you have it recorded in Makefile.in too.

Yeah, fixed with:

2013-07-14  Marek Polacek  <polacek@redhat.com>

	* Makefile.in (c-family/c-ubsan.o): Add alloc-pool.h, CGRAPH_H,
	GIMPLE_H, HASH_TABLE_H, output.h, toplev.h and ubsan.h dependencies.
	(builtins.o): Add ubsan.h dependency.


	Marek

> Otherwise it looks good to me.

Thanks, will put both patches on the ubsan branch.

	Marek

Patch

--- gcc/Makefile.in.mp	2013-07-14 18:09:19.770341832 +0200
+++ gcc/Makefile.in	2013-07-14 18:15:04.330055011 +0200
@@ -2023,8 +2023,9 @@  c-family/stub-objc.o : c-family/stub-obj
 	coretypes.h $(TREE_H) $(C_COMMON_H) c-family/c-objc.h
 
 c-family/c-ubsan.o : c-family/c-ubsan.c $(CONFIG_H) $(SYSTEM_H) \
-	coretypes.h $(TREE_H) $(C_COMMON_H) c-family/c-ubsan.h
-
+	coretypes.h $(TREE_H) $(C_COMMON_H) c-family/c-ubsan.h \
+	alloc-pool.h $(CGRAPH_H) $(GIMPLE_H) $(HASH_TABLE_H) output.h \
+	toplev.h ubsan.h
 default-c.o: config/default-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
   $(C_TARGET_H) $(C_TARGET_DEF_H)
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
@@ -2261,11 +2262,11 @@  tsan.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_
    $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(CGRAPH_H) $(GGC_H) \
    $(BASIC_BLOCK_H) $(FLAGS_H) $(FUNCTION_H) \
    $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) tree-iterator.h \
-   intl.h cfghooks.h output.h options.h c-family/c-common.h tsan.h asan.h \
+   intl.h cfghooks.h output.h options.h $(C_COMMON_H) tsan.h asan.h \
    tree-ssa-propagate.h
 ubsan.o : ubsan.c ubsan.h $(CONFIG_H) $(SYSTEM_H) $(GIMPLE_H) \
    output.h coretypes.h $(TREE_H) alloc-pool.h $(CGRAPH_H) $(HASH_TABLE_H) \
-   toplev.h c-family/c-common.h c-family/c-ubsan.h
+   toplev.h $(C_COMMON_H)
 tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \
    $(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(BITMAP_H) \
    $(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \
@@ -2823,7 +2824,7 @@  builtins.o : builtins.c builtins.h $(CON
    hard-reg-set.h $(DIAGNOSTIC_CORE_H) hard-reg-set.h $(EXCEPT_H) \
    $(TM_P_H) $(PREDICT_H) $(LIBFUNCS_H) langhooks.h $(BASIC_BLOCK_H) \
    tree-mudflap.h realmpfr.h $(BUILTINS_DEF) $(MACHMODE_H) \
-   $(DIAGNOSTIC_CORE_H) $(TREE_FLOW_H) value-prof.h
+   $(DIAGNOSTIC_CORE_H) $(TREE_FLOW_H) value-prof.h ubsan.h
 calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(TREE_H) $(FLAGS_H) $(EXPR_H) $(OPTABS_H) langhooks.h $(TARGET_H) \
    $(LIBFUNCS_H) $(REGS_H) $(DIAGNOSTIC_CORE_H) output.h \

> >  #ifndef PAD_VARARGS_DOWN
> > @@ -10281,6 +10282,11 @@ fold_builtin_0 (location_t loc, tree fnd
> >      case BUILT_IN_CLASSIFY_TYPE:
> >        return fold_builtin_classify_type (NULL_TREE);
> >  
> > +    case BUILT_IN_UNREACHABLE:
> > +      if (flag_sanitize & SANITIZE_UNDEFINED)
> > +	return ubsan_instrument_unreachable (loc);
> > +      break;
> 
> If you have committed your fsanitize= option handling patch,
> I'd expect the above to be actually SANITIZE_UNREACHABLE or
> whatever the option is plus changes to add SANITIZE_UNREACHABLE
> to SANITIZE_UNDEFINED, and parsing unrechable string in *opts.c.

Right, done with following patch.  Sorry for that.

2013-07-14  Marek Polacek  <polacek@redhat.com>

	* opts.c (common_handle_option): Add -fsanitize=unreachable option.
	* builtins.c (fold_builtin_0): Use SANITIZE_UNREACHABLE instead of
	SANITIZE_UNDEFINED.
	* flag-types.h (enum sanitize_code): Add SANITIZE_UNREACHABLE.

--- gcc/opts.c.mp	2013-07-14 18:30:44.548918471 +0200
+++ gcc/opts.c	2013-07-14 18:31:39.483143160 +0200
@@ -1423,6 +1423,8 @@  common_handle_option (struct gcc_options
 	      { "integer-divide-by-zero", SANITIZE_DIVIDE,
 		sizeof "integer-divide-by-zero" - 1 },
 	      { "undefined", SANITIZE_UNDEFINED, sizeof "undefined" - 1 },
+	      { "unreachable", SANITIZE_UNREACHABLE,
+		sizeof "unreachable" - 1 },
 	      { NULL, 0, 0 }
 	    };
 	    const char *comma;
--- gcc/builtins.c.mp	2013-07-14 18:28:11.995229992 +0200
+++ gcc/builtins.c	2013-07-14 18:28:37.246416948 +0200
@@ -10283,7 +10283,7 @@  fold_builtin_0 (location_t loc, tree fnd
       return fold_builtin_classify_type (NULL_TREE);
 
     case BUILT_IN_UNREACHABLE:
-      if (flag_sanitize & SANITIZE_UNDEFINED)
+      if (flag_sanitize & SANITIZE_UNREACHABLE)
 	return ubsan_instrument_unreachable (loc);
       break;
 
--- gcc/flag-types.h.mp	2013-07-14 18:28:41.481434976 +0200
+++ gcc/flag-types.h	2013-07-14 18:29:41.123680421 +0200
@@ -200,7 +200,8 @@  enum sanitize_code {
   /* UndefinedBehaviorSanitizer.  */
   SANITIZE_SHIFT = 1 << 2,
   SANITIZE_DIVIDE = 1 << 3,
-  SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE
+  SANITIZE_UNREACHABLE = 1 << 4,
+  SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE
 };
 
 #endif /* ! GCC_FLAG_TYPES_H */