On Sat, Dec 8, 2012 at 9:13 AM, H.J. Lu <hjl.to...@gmail.com> wrote:
> 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]$

PING.

-- 
H.J.

Reply via email to