* Makefile.in (DRIVER_DEFINES): Define ENABLE_SHARED_LIBGCC and
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 7 Jan 2001 09:42:49 +0000 (09:42 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 7 Jan 2001 09:42:49 +0000 (09:42 +0000)
        NO_SHARED_LIBGCC_MULTILIB as required for the target.
        * gcc.c (init_spec): Massage the existing libgcc_spec into a
        variant that handles a shared libgcc.
        (process_command): Always validate -{static,shared}-libgcc.
        (do_spec_1): New 'M' case.
        * invoke.text (Link Options): Document -{static,shared}-libgcc.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@38762 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/Makefile.in
gcc/gcc.c
gcc/invoke.texi

index 567f293..c2fdbf9 100644 (file)
@@ -1,5 +1,15 @@
 2001-01-07  Richard Henderson  <rth@redhat.com>
 
+       * Makefile.in (DRIVER_DEFINES): Define ENABLE_SHARED_LIBGCC and
+       NO_SHARED_LIBGCC_MULTILIB as required for the target.
+       * gcc.c (init_spec): Massage the existing libgcc_spec into a
+       variant that handles a shared libgcc.
+       (process_command): Always validate -{static,shared}-libgcc.
+       (do_spec_1): New 'M' case.
+       * invoke.text (Link Options): Document -{static,shared}-libgcc.
+
+2001-01-07  Richard Henderson  <rth@redhat.com>
+
        * Makefile.in (slibdir): New variable.
        (libgcc.mk): Pass SHLIB_INSTALL to mklibgcc.
        (installdirs): Create slibdir.
index b52678d..74ced6e 100644 (file)
@@ -1248,7 +1248,10 @@ DRIVER_DEFINES = \
   -DDEFAULT_TARGET_VERSION=\"$(version)\" \
   -DDEFAULT_TARGET_MACHINE=\"$(target_alias)\" \
   -DSTANDARD_BINDIR_PREFIX=\"$(bindir)/\" \
-  -DTOOLDIR_BASE_PREFIX=\"$(unlibsubdir)/../\"
+  -DTOOLDIR_BASE_PREFIX=\"$(unlibsubdir)/../\" \
+  `test "$SHLIB_LINK" -a "@enable_shared@" = "yes" && echo "-DENABLE_SHARED_LIBGCC"` \
+  `test "$SHLIB_MULTILIB" && echo "-DNO_SHARED_LIBGCC_MULTILIB"`
+
 gcc.o: gcc.c $(CONFIG_H) system.h intl.h multilib.h \
     Makefile $(lang_specs_files) prefix.h $(GCC_H)
        $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
index 65fa520..9d73608 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -373,10 +373,12 @@ or with constant text in a single argument.
  %l     process LINK_SPEC as a spec.
  %L     process LIB_SPEC as a spec.
  %G     process LIBGCC_SPEC as a spec.
+ %M     output multilib_dir with directory separators replaced with "_";
+       if multilib_dir is not set or is ".", output "".
  %S     process STARTFILE_SPEC as a spec.  A capital S is actually used here.
  %E     process ENDFILE_SPEC as a spec.  A capital E is actually used here.
  %c    process SIGNED_CHAR_SPEC as a spec.
- %C     process CPP_SPEC as a spec.  A capital C is actually used here.
+ %C     process CPP_SPEC as a spec.
  %1    process CC1_SPEC as a spec.
  %2    process CC1PLUS_SPEC as a spec.
  %|    output "-" if the input for the current command is coming from a pipe.
@@ -1283,6 +1285,80 @@ init_spec ()
       next = sl;
     }
 
+#ifdef ENABLE_SHARED_LIBGCC
+  /* ??? If neither -shared-libgcc nor --static-libgcc was
+     seen, then we should be making an educated guess.  Some proposed
+     heuristics for ELF include:
+
+       (1) If "-Wl,--export-dynamic", then it's a fair bet that the
+           program will be doing dynamic loading, which will likely
+           need the shared libgcc.
+
+       (2) If "-ldl", then it's also a fair bet that we're doing
+           dynamic loading.
+
+       (3) For each ET_DYN we're linking against (either through -lfoo
+           or /some/path/foo.so), check to see whether it or one of
+           its dependancies depends on a shared libgcc.
+
+       (4) If "-shared"
+
+           If the runtime is fixed to look for program headers instead
+           of calling __register_frame_info at all, for each object,
+           use the shared libgcc if any EH symbol referenced.
+
+           If crtstuff is fixed to not invoke __register_frame_info
+           automatically, for each object, use the shared libgcc if
+           any non-empty unwind section found.
+
+     Doing any of this probably requires invoking an external program to
+     do the actual object file scanning.  */
+  {
+    const char *p = libgcc_spec;
+    int in_sep = 1;
+    /* Transform the extant libgcc_spec into one that uses the shared libgcc
+       when given the proper command line arguments.  */
+    while (*p)
+      {
+       const char *r;
+        if (in_sep && *p == '-' && strncmp (p, "-lgcc", 5) == 0)
+         {
+#ifdef NO_SHARED_LIBGCC_MULTILIB
+           r = "%{shared-libgcc:-lgcc_s}%{!shared-libgcc:-lgcc}";
+#else
+           r = "%{shared-libgcc:-lgcc_s%M}%{!shared-libgcc:-lgcc}";
+#endif
+           obstack_grow (&obstack, r, strlen(r));
+           p += 5;
+           in_sep = 0;
+         }
+       else if (in_sep && *p == 'l' && strncmp (p, "libgcc.a%s", 10) == 0)
+         {
+           /* Ug.  We don't know shared library extensions.  Hope that
+              systems that use this form don't do shared libraries.  */
+#ifdef NO_SHARED_LIBGCC_MULTILIB
+           r = "%{shared-libgcc:-lgcc_s}%{!shared-libgcc:libgcc.a%s}";
+#else
+           r = "%{shared-libgcc:-lgcc_s%M}%{!shared-libgcc:libgcc.a%s}";
+#endif
+           obstack_grow (&obstack, r, strlen(r));
+           p += 10;
+           in_sep = 0;
+         }
+       else
+         {
+           obstack_1grow (&obstack, *p);
+           in_sep = (*p == ' ');
+           p += 1;
+         }
+      }
+
+    obstack_1grow (&obstack, '\0');
+    libgcc_spec = obstack_finish (&obstack);
+  }
+#endif
+
   specs = sl;
 }
 \f
@@ -3552,7 +3628,7 @@ process_command (argc, argv)
            switches[n_switches].part1     = "--target-help";
            switches[n_switches].args      = 0;
            switches[n_switches].live_cond = SWITCH_OK;
-           switches[n_switches].validated     = 0;
+           switches[n_switches].validated = 0;
 
            n_switches++;
         }
@@ -3570,7 +3646,7 @@ process_command (argc, argv)
              switches[n_switches].part1     = "--help";
              switches[n_switches].args      = 0;
              switches[n_switches].live_cond = SWITCH_OK;
-             switches[n_switches].validated     = 0;
+             switches[n_switches].validated = 0;
 
              n_switches++;
            }
@@ -3697,8 +3773,10 @@ process_command (argc, argv)
 
          switches[n_switches].live_cond = SWITCH_OK;
          switches[n_switches].validated = 0;
-         /* This is always valid, since gcc.c itself understands it.  */
-         if (!strcmp (p, "save-temps"))
+         /* These are always valid, since gcc.c itself understands it.  */
+         if (!strcmp (p, "save-temps")
+             || !strcmp (p, "static-libgcc")
+             || !strcmp (p, "shared-libgcc"))
            switches[n_switches].validated = 1;
          else
            {
@@ -4346,6 +4424,23 @@ do_spec_1 (spec, inswitch, soft_matched_part)
              return value;
            break;
 
+         case 'M':
+           if (multilib_dir && strcmp (multilib_dir, ".") != 0)
+             {
+               char *p;
+               const char *q;
+               size_t len;
+
+               len = strlen (multilib_dir);
+               obstack_blank (&obstack, len + 1);
+               p = obstack_next_free (&obstack) - len;
+
+               *p++ = '_';
+               for (q = multilib_dir; *q ; ++q, ++p)
+                 *p = (IS_DIR_SEPARATOR (*q) ? '_' : *q);
+             }
+           break;
+
          case 'p':
            {
              char *x = (char *) alloca (strlen (cpp_predefines) + 1);
index c8cdb1a..941029f 100644 (file)
@@ -276,7 +276,7 @@ in the following sections.
 @smallexample
 @var{object-file-name}  -l@var{library}
 -nostartfiles  -nodefaultlibs  -nostdlib
--s  -static  -shared  -symbolic
+-s  -static  -static-libgcc  -shared  -shared-libgcc  -symbolic
 -Wl,@var{option}  -Xlinker @var{option}
 -u @var{symbol}
 @end smallexample
@@ -3502,6 +3502,25 @@ libraries to link against.  Failing to supply the correct flags may lead
 to subtle defects. Supplying them in cases where they are not necessary
 is innocuous.}
 
+@item -shared-libgcc
+@itemx -static-libgcc
+On systems that provide @file{libgcc} as a shared library, these options
+force the use of either the shared or static version respectively.
+If no shared version of @file{libgcc} was built when the compiler was
+configured, these options have no effect.
+
+There are several situations in which an application should use the
+shared @file{libgcc} instead of the static version.  The most common
+of these is when the application wishes to throw and catch exceptions
+across different shared libraries.  In that case, each of the libraries
+as well as the application itself should use the shared @file{libgcc}.
+
+At present the GCC driver makes no attempt to recognize the situations
+in which the shared @file{libgcc} should be used, and defaults to using
+the static @file{libgcc} always.  This will likely change in the future,
+at which time @samp{-static-libgcc} becomes useful as a means for 
+overriding GCC's choice.
+
 @item -symbolic
 Bind references to global symbols when building a shared object.  Warn
 about any unresolved references (unless overridden by the link editor