When -Bsymbolic is passed to linker, references to global symbols
defined in the shared library are resolved locally.  We should pass
-fsymbolic to GCC in this case.

        * collect2.c (main): Add -fsymbolic to COLLECT_GCC_OPTIONS if
        -Bsymbolic is used.
        * doc/invoke.texi: Updated.
---
 gcc/collect2.c      | 51 +++++++++++++++++++++++++++++++++++++++++++++++++--
 gcc/doc/invoke.texi |  3 ++-
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/gcc/collect2.c b/gcc/collect2.c
index 20c2533..ccbf4c3 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -1044,7 +1044,8 @@ main (int argc, char **argv)
 #ifndef HAVE_LD_DEMANGLE
   current_demangling_style = auto_demangling;
 #endif
-  p = getenv ("COLLECT_GCC_OPTIONS");
+  char *gcc_options = getenv ("COLLECT_GCC_OPTIONS");
+  p = gcc_options;
   while (p && *p)
     {
       const char *q = extract_string (&p);
@@ -1231,7 +1232,8 @@ main (int argc, char **argv)
      AIX support needs to know if -shared has been specified before
      parsing commandline arguments.  */
 
-  p = getenv ("COLLECT_GCC_OPTIONS");
+  int add_fsymbolic = -1;
+  p = gcc_options;
   while (p && *p)
     {
       const char *q = extract_string (&p);
@@ -1241,6 +1243,9 @@ main (int argc, char **argv)
        *c_ptr++ = xstrdup (q);
       if (strcmp (q, "-shared") == 0)
        shared_obj = 1;
+      else if (strcmp (q, "-fsymbolic") == 0
+              || strcmp (q, "-fno-symbolic") == 0)
+       add_fsymbolic = 0;
       if (*q == '-' && q[1] == 'B')
        {
          *c_ptr++ = xstrdup (q);
@@ -1278,6 +1283,13 @@ main (int argc, char **argv)
        {
          switch (arg[1])
            {
+           case 'B':
+             /* Add -fsymbolic to COLLECT_GCC_OPTIONS if -Bsymbolic is
+                used.  */
+             if (add_fsymbolic == -1 && !strcmp (arg + 2, "symbolic"))
+               add_fsymbolic = 1;
+             break;
+
            case 'd':
              if (!strcmp (arg, "-debug"))
                {
@@ -1495,6 +1507,41 @@ main (int argc, char **argv)
        }
     }
 
+  if (add_fsymbolic > 0)
+    {
+      /* Add -fsymbolic to COLLECT_GCC_OPTIONS.  */
+      size_t sizeof_env = sizeof "COLLECT_GCC_OPTIONS=";
+      size_t sizeof_fsymbolic = sizeof "\'-fsymbolic\' ";
+      size_t len = strlen (gcc_options);
+      size_t next, start;
+      char *first;
+      char *options = (char *) xmalloc (sizeof_env + len +
+                                       sizeof_fsymbolic - 1);
+      memcpy (options, "COLLECT_GCC_OPTIONS=", sizeof_env - 1);
+      first = strchr (gcc_options, '\'');
+      if (first == NULL)
+       fatal_error (input_location, "malformed COLLECT_GCC_OPTIONS: %s",
+                    gcc_options);
+      next = sizeof_env - 1;
+      if (first != gcc_options)
+       {
+         size_t first_len = first - gcc_options;
+         memcpy (options + next, gcc_options, first_len);
+         next += first_len;
+         start = first_len;
+       }
+      else
+       start = 0;
+      memcpy (options + next, "\'-fsymbolic\' ", sizeof_fsymbolic - 1);
+      next += sizeof_fsymbolic - 1;
+      memcpy (options + next, gcc_options + start, len);
+      next += len;
+      options[next] = '\0';
+      putenv (options);
+      if (verbose)
+       fprintf (stderr, "%s\n", options);
+    }
+
 #ifdef COLLECT_EXPORT_LIST
   /* This is added only for debugging purposes.  */
   if (debug)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 5293a25..47baaa3 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -23952,7 +23952,8 @@ which controls how references to global symbols are 
bound.  The
 local definitions and external references globally.  This option
 avoids copy relocations in position-independent executables and
 optimizes global symbol references in shared library created by
-linker option, @option{-Bsymbolic}.
+linker option, @option{-Bsymbolic}.  This option is enabled by default
+with @option{-flto} when @option{-Bsymbolic} is used.
 
 @item -fno-ident
 @opindex fno-ident
-- 
2.4.3

Reply via email to