From 9db0819efcc859f1b86006b28c5084b5ff8068ab Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 7 Jan 2001 01:42:49 -0800 Subject: [PATCH] Makefile.in (DRIVER_DEFINES): Define ENABLE_SHARED_LIBGCC and NO_SHARED_LIBGCC_MULTILIB as required for the... * 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. From-SVN: r38762 --- gcc/ChangeLog | 10 +++++ gcc/Makefile.in | 5 ++- gcc/gcc.c | 105 +++++++++++++++++++++++++++++++++++++++++++++--- gcc/invoke.texi | 21 +++++++++- 4 files changed, 134 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 567f293d58c..c2fdbf949c1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2001-01-07 Richard Henderson + + * 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 * Makefile.in (slibdir): New variable. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index b52678db6a3..74ced6eafab 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -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) \ diff --git a/gcc/gcc.c b/gcc/gcc.c index 65fa5206a8e..9d73608fa5a 100644 --- 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; } @@ -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); diff --git a/gcc/invoke.texi b/gcc/invoke.texi index c8cdb1a6692..941029f0074 100644 --- a/gcc/invoke.texi +++ b/gcc/invoke.texi @@ -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 -- 2.30.2