On Thu, Nov 22, 2012 at 6:45 AM, H.J. Lu <[email protected]> wrote:
> Hi,
>
> libasan should come first before any language-specific
> adjustment/addition. Otherwise, we got
>
> g++ -fsanitize=address -static-libasan ...
>
> /usr/local/bin/ld: error:
> /export/build/gnu/gcc-asan/build-x86_64-linux/prev-x86_64-unknown-linux-gnu/libsanitizer/asan/.libs/libasan.a(asan_new_delete.o):
> multiple definition of 'operator delete(void*)'
> /usr/local/bin/ld:
> /export/build/gnu/gcc-asan/build-x86_64-linux/prev-x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.a(del_op.o):
> previous definition here
>
> This patch adds prepend_lang_specific_driver to prepend command line before
> language-specific adjustment/addition of flags. OK to install?
>
> Thanks.
>
>
> H.J.
> ---
> 2012-11-22 H.J. Lu <[email protected]>
>
> PR driver/55374
> * gcc.c (prepend_lang_specific_driver): New function.
> (process_command): Use it.
>
> diff --git a/gcc/gcc.c b/gcc/gcc.c
> index 0f8bcea..41474aa 100644
> --- a/gcc/gcc.c
> +++ b/gcc/gcc.c
> @@ -3604,6 +3604,80 @@ set_option_handlers (struct cl_option_handlers
> *handlers)
> handlers->handlers[2].mask = CL_TARGET;
> }
>
> +/* Prepend command line before language-specific adjustment/addition of
> + flags. */
> +
> +void
> +prepend_lang_specific_driver (struct cl_decoded_option **in_decoded_options,
> + unsigned int *in_decoded_options_count,
> + int *in_added_libraries)
> +{
> + unsigned int i, argc;
> +
> + /* The new argument list will be contained in this. */
> + struct cl_decoded_option *new_decoded_options;
> +
> + /* The argument list. */
> + struct cl_decoded_option *decoded_options;
> +
> + bool add_libasan = false;
> + bool static_libasan = false;
> +
> + argc = *in_decoded_options_count;
> + decoded_options = *in_decoded_options;
> +
> + for (i = 1; i < argc; i++)
> + switch (decoded_options[i].opt_index)
> + {
> + case OPT_fsanitize_address:
> + add_libasan = true;
> + break;
> + case OPT_static_libasan:
> + static_libasan = true;
> + break;
> + }
> +
> + if (add_libasan)
> + {
> + /* Add -lasan before language-specific adjustment/addition. */
> + unsigned int added_argc;
> +
> + added_argc = 1;
> +#ifdef HAVE_LD_STATIC_DYNAMIC
> + if (static_libasan)
> + added_argc += 2;
> +#endif
> +
> + new_decoded_options = XNEWVEC (struct cl_decoded_option,
> + argc + added_argc);
> +
> + i = 0;
> + do
> + {
> + new_decoded_options[i] = decoded_options[i];
> + i++;
> + }
> + while (i < argc);
> +
> +#ifdef HAVE_LD_STATIC_DYNAMIC
> + if (static_libasan)
> + generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
> + &new_decoded_options[i++]);
> +#endif
> + generate_option (OPT_l, "asan", 1, CL_DRIVER,
> + &new_decoded_options[i++]);
> +#ifdef HAVE_LD_STATIC_DYNAMIC
> + if (static_libasan)
> + generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
> + &new_decoded_options[i++]);
> +#endif
> +
> + *in_decoded_options_count = i;
> + *in_decoded_options = new_decoded_options;
> + *in_added_libraries = 1;
> + }
> +}
> +
> /* Create the vector `switches' and its contents.
> Store its length in `n_switches'. */
>
> @@ -3695,6 +3769,11 @@ process_command (unsigned int decoded_options_count,
> or an automatically created GCC_EXEC_PREFIX from
> decoded_options[0].arg. */
>
> + /* Prepend command line before language-specific adjustment/addition of
> + flags. */
> + prepend_lang_specific_driver (&decoded_options, &decoded_options_count,
> + &added_libraries);
> +
> /* Do language-specific adjustment/addition of flags. */
> lang_specific_driver (&decoded_options, &decoded_options_count,
> &added_libraries);
PING.
A simple testcase:
[hjl@gnu-6 gcc]$ cat /tmp/bad.cc
#include <new>
int
main ()
{
int *buf = new int(30);
buf[30]=1;
return 0;
}
[hjl@gnu-6 gcc]$ ./release/usr/gcc-4.8.0/bin/g++ -fsanitize=address /tmp/bad.cc
-static-libasan -static-libstdc++
/export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libasan.a(asan_new_delete.o):
In function `operator new(unsigned long)':
/export/gnu/import/git/gcc/libsanitizer/asan/asan_new_delete.cc:41: multiple
definition of `operator new(unsigned long)'
/export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libstdc++.a(new_op.o):/export/gnu/import/git/gcc/libstdc++-v3/libsupc++/new_op.cc:45:
first defined here
/export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libasan.a(asan_new_delete.o):
In function `operator delete(void*)':
/export/gnu/import/git/gcc/libsanitizer/asan/asan_new_delete.cc:54: multiple
definition of `operator delete(void*)'
/export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libstdc++.a(del_op.o):/export/gnu/import/git/gcc/libstdc++-v3/libsupc++/del_op.cc:46:
first defined here
collect2: error: ld returned 1 exit status
[hjl@gnu-6 gcc]$
[rep[hjl@gnu-6 gcc]$ cat /tmp/bad.cc
#include <new>
int
main ()
{
int *buf = new int(30);
buf[30]=1;
return 0;
}
[hjl@gnu-6 gcc]$ ./release/usr/gcc-4.8.0/bin/g++ -fsanitize=address /tmp/bad.cc
-static-libasan -static-libstdc++
/export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libasan.a(asan_new_delete.o):
In function `operator new(unsigned long)':
/export/gnu/import/git/gcc/libsanitizer/asan/asan_new_delete.cc:41: multiple
definition of `operator new(unsigned long)'
/export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libstdc++.a(new_op.o):/export/gnu/import/git/gcc/libstdc++-v3/libsupc++/new_op.cc:45:
first defined here
/export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libasan.a(asan_new_delete.o):
In function `operator delete(void*)':
/export/gnu/import/git/gcc/libsanitizer/asan/asan_new_delete.cc:54: multiple
definition of `operator delete(void*)'
/export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libstdc++.a(del_op.o):/export/gnu/import/git/gcc/libstdc++-v3/libsupc++/del_op.cc:46:
first defined here
collect2: error: ld returned 1 exit status
[hjl@gnu-6 gcc]$
--
H.J.