+2002-02-25 Alexandre Oliva <aoliva@redhat.com>
+
+ * gcc.c (init_gcc_specs): Get -shared-libgcc along with -shared to
+ link with shared_name only.
+ * doc/invoke.texi (Link Options): Document new behavior.
+
2002-02-25 Aldy Hernandez <aldyh@redhat.com>
* c-typeck.c (push_init_level): Handle vectors.
across different shared libraries. In that case, each of the libraries
as well as the application itself should use the shared @file{libgcc}.
-Therefore, whenever you specify the @option{-shared} option, the GCC
-driver automatically adds @option{-shared-libgcc}, unless you explicitly
-specify @option{-static-libgcc}. The G++ driver automatically adds
-@option{-shared-libgcc} when you build a main executable as well because
-for C++ programs that is typically the right thing to do.
-(Exception-handling will not work reliably otherwise.)
-
-However, when linking a main executable written in C, you must
-explicitly say @option{-shared-libgcc} if you want to use the shared
+Therefore, the G++ and GCJ drivers automatically add
+@option{-shared-libgcc} whenever you build a shared library or a main
+executable, because C++ and Java programs typically use exceptions, so
+this is the right thing to do.
+
+If, instead, you use the GCC driver to create shared libraries, you may
+find that they will not always be linked with the shared @file{libgcc}.
+If GCC finds, at its configuration time, that you have a GNU linker that
+does not support option @option{--eh-frame-hdr}, it will link the shared
+version of @file{libgcc} into shared libraries by default. Otherwise,
+it will take advantage of the linker and optimize away the linking with
+the shared version of @file{libgcc}, linking with the static version of
+libgcc by default. This allows exceptions to propagate through such
+shared libraries, without incurring relocation costs at library load
+time.
+
+However, if a library or main executable is supposed to throw or catch
+exceptions, you must link it using the G++ or GCJ driver, as appropriate
+for the languages used in the program, or using the option
+@option{-shared-libgcc}, such that it is linked with the shared
@file{libgcc}.
@item -symbolic
const char *static_name;
const char *eh_name;
{
- char buffer[128];
- const char *p;
+ char *buf;
- /* If we see -shared-libgcc, then use the shared version. */
- sprintf (buffer, "%%{shared-libgcc:%s %s}", shared_name, static_name);
- obstack_grow (obstack, buffer, strlen (buffer));
- /* If we see -static-libgcc, then use the static version. */
- sprintf (buffer, "%%{static-libgcc:%s %s}", static_name, eh_name);
- obstack_grow (obstack, buffer, strlen (buffer));
- /* Otherwise, if we see -shared, then use the shared version
- if using EH registration routines or static version without
- exception handling routines otherwise. */
- p = "%{!shared-libgcc:%{!static-libgcc:%{shared:";
- obstack_grow (obstack, p, strlen (p));
+ buf = concat ("%{!shared:%{!shared-libgcc:", static_name, " ",
+ eh_name, "}%{shared-libgcc:", shared_name, " ",
+ static_name, "}}",
+ "%{shared:%{static-libgcc:", static_name, " ",
+ eh_name, "}%{!static-libgcc:",
#ifdef LINK_EH_SPEC
- sprintf (buffer, "%s}}}", static_name);
+ "%{shared-libgcc:", shared_name,
+ "}%{!shared-libgcc:", static_name, "}",
#else
- sprintf (buffer, "%s}}}", shared_name);
+ shared_name,
#endif
- obstack_grow (obstack, buffer, strlen (buffer));
- /* Otherwise, use the static version. */
- sprintf (buffer,
- "%%{!shared-libgcc:%%{!static-libgcc:%%{!shared:%s %s}}}",
- static_name, eh_name);
- obstack_grow (obstack, buffer, strlen (buffer));
+ "}}", NULL);
+
+ obstack_grow (obstack, buf, strlen (buf));
+ free (buf);
}
#endif /* ENABLE_SHARED_LIBGCC */