From f9bbf43f58e59ddf741ec94d5426907dcc78a99e Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 29 Apr 2015 11:52:16 -0700 Subject: Enable -fsymbolic in LTO if -Bsymbolic is used 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 20c253326f8..ccbf4c395c9 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 67c9b4f7c7d..77d93b099bf 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -23967,7 +23967,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 -- cgit v1.2.1