On Wed, Dec 5, 2012 at 3:39 PM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > Another problem from the compiler side when working on the asan testsuite > is that at higher -O* levels the __asan_report_* noreturn calls are > cross-jumped, but the library relies on their locus to print accurrate > locations when symbolized. Without it, asan might report an error > completely elsewhere in a function.
In LLVM we solve this problem by inserting an empty volatile asm blob after the __asan_report_* calls. Hacky, but works remarkably well. --kcc > > This patch disables cross-jumping of such builtins. > Alternatively, I could introduce some attribute (no_cross_jump?), > ECF_NO_CROSS_JUMP, add those attributes to those builtins (and let users > add those too to functions they wish), and look at ECF_NO_CROSS_JUMP instead > during cross-jumping. > > 2012-12-05 Jakub Jelinek <ja...@redhat.com> > > * sanitizer.def: Add comment about importance of ordering of > BUILT_IN_ASAN_REPORT* builtins. > * cfgcleanup.c (old_insns_match_p): Don't cross-jump __asan_report_* > builtins. > > --- gcc/sanitizer.def.jj 2012-12-04 14:19:36.000000000 +0100 > +++ gcc/sanitizer.def 2012-12-05 09:38:01.205958515 +0100 > @@ -29,6 +29,8 @@ along with GCC; see the file COPYING3. > /* Address Sanitizer */ > DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init", > BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST) > +/* Do not reorder the BUILT_IN_ASAN_REPORT* builtins, e.g. cfgcleanup.c > + relies on this order. */ > DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD1, "__asan_report_load1", > BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST) > DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD2, "__asan_report_load2", > --- gcc/cfgcleanup.c.jj 2012-11-20 09:37:47.000000000 +0100 > +++ gcc/cfgcleanup.c 2012-12-05 09:37:23.389181984 +0100 > @@ -1138,6 +1138,28 @@ old_insns_match_p (int mode ATTRIBUTE_UN > CALL_INSN_FUNCTION_USAGE (i2)) > || SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2)) > return dir_none; > + > + /* For address sanitizer, never crossjump __asan_report_* builtins, > + otherwise errors might be reported on incorrect lines. */ > + if (flag_asan) > + { > + rtx call = get_call_rtx_from (i1); > + if (call && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF) > + { > + rtx symbol = XEXP (XEXP (call, 0), 0); > + if (SYMBOL_REF_DECL (symbol) > + && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL) > + { > + if ((DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (symbol)) > + == BUILT_IN_NORMAL) > + && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol)) > + >= BUILT_IN_ASAN_REPORT_LOAD1 > + && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol)) > + <= BUILT_IN_ASAN_REPORT_STORE16) > + return dir_none; > + } > + } > + } > } > > #ifdef STACK_REGS > > Jakub