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
This commit is contained in:
Richard Henderson 2001-01-07 01:42:49 -08:00 committed by Richard Henderson
parent 2bbea3a6c7
commit 9db0819efc
4 changed files with 134 additions and 7 deletions

View File

@ -1,3 +1,13 @@
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.

View 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) \

105
gcc/gcc.c
View File

@ -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);

View 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