On Thu, Nov 22, 2012 at 6:45 AM, H.J. Lu <hjl.to...@gmail.com> 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  <hongjiu...@intel.com>
>
>         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.

Reply via email to