This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

-shared-libgcc


Part two of using the shared libgcc is to add driver options to
allow access to it.

We recognize -static-libgcc and -shared-libgcc on all targets and
ignore them if we didn't build a shared libgcc with the compiler.

At some point in the future I'd like to (somehow) add smarts to
recognize the common cases of when using the shared libgcc is
required.  The most common being "building any c++ shared library"
and "linking against a c++ shared library that uses libgcc.so".
How to go about doing this in any remotely portable manner has
temporarily eluded me.  So for now we just default to using the
static libgcc.

I tried to modify libstdc++-v3 to use "-shared-libgcc", but it
seems that libtool filters that out of the options that actually
make it to the gcc invocation.  I couldn't even figure out _where_
libtool processes arguments, much less modify it to dtrt.  I'm
hoping that Alexandre or someone will take care of this.  ;-)

Tested on alphaev6-linux and powerpc-aix4.3.3.0.



r~


        * 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.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.577
diff -c -p -d -r1.577 Makefile.in
*** Makefile.in	2001/01/07 09:27:23	1.577
--- Makefile.in	2001/01/07 09:36:52
*************** DRIVER_DEFINES = \
*** 1248,1254 ****
    -DDEFAULT_TARGET_VERSION=\"$(version)\" \
    -DDEFAULT_TARGET_MACHINE=\"$(target_alias)\" \
    -DSTANDARD_BINDIR_PREFIX=\"$(bindir)/\" \
!   -DTOOLDIR_BASE_PREFIX=\"$(unlibsubdir)/../\"
  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) \
--- 1248,1257 ----
    -DDEFAULT_TARGET_VERSION=\"$(version)\" \
    -DDEFAULT_TARGET_MACHINE=\"$(target_alias)\" \
    -DSTANDARD_BINDIR_PREFIX=\"$(bindir)/\" \
!   -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: gcc.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gcc.c,v
retrieving revision 1.193
diff -c -p -d -r1.193 gcc.c
*** gcc.c	2001/01/06 00:15:29	1.193
--- gcc.c	2001/01/07 09:36:52
*************** or with constant text in a single argume
*** 373,382 ****
   %l     process LINK_SPEC as a spec.
   %L     process LIB_SPEC as a spec.
   %G     process LIBGCC_SPEC as a spec.
   %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.
   %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.
--- 373,384 ----
   %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.
   %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.
*************** init_spec ()
*** 1283,1288 ****
--- 1285,1364 ----
        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;
  }
  
*************** process_command (argc, argv)
*** 3552,3558 ****
             switches[n_switches].part1     = "--target-help";
             switches[n_switches].args      = 0;
             switches[n_switches].live_cond = SWITCH_OK;
!            switches[n_switches].validated     = 0;
  
             n_switches++;
          }
--- 3628,3634 ----
             switches[n_switches].part1     = "--target-help";
             switches[n_switches].args      = 0;
             switches[n_switches].live_cond = SWITCH_OK;
!            switches[n_switches].validated = 0;
  
             n_switches++;
          }
*************** process_command (argc, argv)
*** 3570,3576 ****
  	      switches[n_switches].part1     = "--help";
  	      switches[n_switches].args      = 0;
  	      switches[n_switches].live_cond = SWITCH_OK;
! 	      switches[n_switches].validated     = 0;
  
  	      n_switches++;
  	    }
--- 3646,3652 ----
  	      switches[n_switches].part1     = "--help";
  	      switches[n_switches].args      = 0;
  	      switches[n_switches].live_cond = SWITCH_OK;
! 	      switches[n_switches].validated = 0;
  
  	      n_switches++;
  	    }
*************** process_command (argc, argv)
*** 3697,3704 ****
  
  	  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"))
  	    switches[n_switches].validated = 1;
  	  else
  	    {
--- 3773,3782 ----
  
  	  switches[n_switches].live_cond = SWITCH_OK;
  	  switches[n_switches].validated = 0;
! 	  /* 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
  	    {
*************** do_spec_1 (spec, inswitch, soft_matched_
*** 4344,4349 ****
--- 4422,4444 ----
  	    value = do_spec_1 (libgcc_spec, 0, NULL_PTR);
  	    if (value != 0)
  	      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':
Index: invoke.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/invoke.texi,v
retrieving revision 1.253
diff -c -p -d -r1.253 invoke.texi
*** invoke.texi	2001/01/02 19:24:26	1.253
--- invoke.texi	2001/01/07 09:36:54
*************** in the following sections.
*** 276,282 ****
  @smallexample
  @var{object-file-name}  -l@var{library}
  -nostartfiles  -nodefaultlibs  -nostdlib
! -s  -static  -shared  -symbolic
  -Wl,@var{option}  -Xlinker @var{option}
  -u @var{symbol}
  @end smallexample
--- 276,282 ----
  @smallexample
  @var{object-file-name}  -l@var{library}
  -nostartfiles  -nodefaultlibs  -nostdlib
! -s  -static  -static-libgcc  -shared  -shared-libgcc  -symbolic
  -Wl,@var{option}  -Xlinker @var{option}
  -u @var{symbol}
  @end smallexample
*************** multi-libbed systems, @code{gcc -shared}
*** 3501,3506 ****
--- 3501,3525 ----
  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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]