Hi,
as noted in bugzilla, ASan inserts redzones forĀ `.LDFCM*' variables and breaks internal ABI between GCC and libstdc++ because libstdc++ tries to obtain a pointer to `typeinfo for (anonymous namespace)::SomeRandomType' from a constant offset from `.LDFCM*' labels and hits these redzones. This can be trivially fixed by not sanitizing `.LDFCM*' variables (and other debug variables) at all.
Attached patch is tested/bootstrapped on x86_64-unknown-linux-gnu and ppc64le-redhat-linux targets.
Is it OK for trunk now, or should I wait for stage 1? -Maxim
gcc/ PR sanitizer/78651 * dwarf2asm.c (dw2_output_indirect_constant_1): Call assemble_variable with new parameter. * output.h (assemble_variable): Add new parameter. * varasm.c (assemble_variable): Add new parameter. Do not protect variable with ASan if is_debug_var is true. gcc/testsuite/ChangeLog: PR sanitizer/78651 * g++.dg/asan/pr78651.C: New test. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b5b5559..a26f05e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-03-19 Maxim Ostapenko <m.ostape...@samsung.com> + + PR sanitizer/78651 + * dwarf2asm.c (dw2_output_indirect_constant_1): Call assemble_variable + with new parameter. + * output.h (assemble_variable): Add new parameter. + * varasm.c (assemble_variable): Add new parameter. Do not protect + variable with ASan if is_debug_var is true. + 2018-03-19 Richard Biener <rguent...@suse.de> PR tree-optimization/84929 diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c index e9b18b8..5c90994 100644 --- a/gcc/dwarf2asm.c +++ b/gcc/dwarf2asm.c @@ -967,7 +967,7 @@ dw2_output_indirect_constant_1 (const char *sym, tree id) } sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym); - assemble_variable (decl, 1, 1, 1); + assemble_variable (decl, 1, 1, 1, 1); assemble_integer (sym_ref, POINTER_SIZE_UNITS, POINTER_SIZE, 1); return 0; diff --git a/gcc/output.h b/gcc/output.h index f708cc7..678c370 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -200,7 +200,7 @@ extern void assemble_end_function (tree, const char *); to define things that have had only tentative definitions. DONT_OUTPUT_DATA if nonzero means don't actually output the initial value (that will be done by the caller). */ -extern void assemble_variable (tree, int, int, int); +extern void assemble_variable (tree, int, int, int, int is_debug_var = 0); /* Put the vtable verification constructor initialization function into the preinit array. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 868d8e8..6ff9217 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-03-19 Maxim Ostapenko <m.ostape...@samsung.com> + + PR sanitizer/78651 + * g++.dg/asan/pr78651.C: New test. + 2018-03-19 Richard Biener <rguent...@suse.de> PR tree-optimization/84929 diff --git a/gcc/testsuite/g++.dg/asan/pr78651.C b/gcc/testsuite/g++.dg/asan/pr78651.C new file mode 100644 index 0000000..3f14be7 --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/pr78651.C @@ -0,0 +1,24 @@ +// { dg-do run { target fpic } } + +struct A { }; + +namespace { + +void thisThrows () { + throw A(); +} + +struct SomeRandomType {}; +} + +int main() { + try { + thisThrows(); + } + catch (SomeRandomType) { + throw; + } + catch (A) { + } + return 0; +} diff --git a/gcc/varasm.c b/gcc/varasm.c index 2b5c70c..b18d011 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -2158,11 +2158,14 @@ assemble_undefined_decl (tree decl) AT_END is nonzero if this is the special handling, at end of compilation, to define things that have had only tentative definitions. DONT_OUTPUT_DATA if nonzero means don't actually output the - initial value (that will be done by the caller). */ + initial value (that will be done by the caller). + IS_DEBUG_VAR if nonzero that we are assembling debug variable. + This information is useful for ASan, see pr78651. */ void assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED, - int at_end ATTRIBUTE_UNUSED, int dont_output_data) + int at_end ATTRIBUTE_UNUSED, int dont_output_data, + int is_debug_var) { const char *name; rtx decl_rtl, symbol; @@ -2258,6 +2261,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED, align_variable (decl, dont_output_data); if ((flag_sanitize & SANITIZE_ADDRESS) + && !is_debug_var && asan_protect_global (decl)) { asan_protected = true;