public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* We still need those old frame functions in libgcc.a
@ 1997-12-15 22:55 H.J. Lu
  0 siblings, 0 replies; 5+ messages in thread
From: H.J. Lu @ 1997-12-15 22:55 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc2, egcs

Let me try again to explain why we need to keep the
old __register_frame in libgcc.a.

A. __register_frame and shared libraries.

1. gcc builds shared libraries with crtbegin.o.
2. crtbegin.o calls __register_frame.
3. gcc builds shared libraries with -lgcc.
4. The shared libraries built by gcc have __register_frame
   which is visible by linker because of 1, 2, 3.

If we leave -lgcc out, linker will leave __register_frame
undefined in shared libraries, we have to keep
__register_frame in libgcc.a in new gcc. Otherwise, during
the link time, ld will find undefined __register_frame
referenced by shared libraries when new gcc is used.

B. We have to keep __register_frame in libgcc.a.

1. Say binary "foo" needs libbar.so, since __register_frame
is in libbar.so, linker will leave __register_frame
undefined in foo and the dynamic linker will find
__register_frame in libbar.so at the runtime.
2. If we remove __register_frame from libgcc.a in new
gcc and we rebuild libbar.so with the new gcc, now
libbar.so won't have __register_frame. Now the dynamic
linker won't find __register_frame at the run time
since it is no longer in libbar.so. We are in a big trouble.

Kenner, please keep __register_frame and its friends
in libgcc.a. Otherwise, gcc 2.8.0 is incompatible with
other gcc snapshots and egcs. Here is the patch.

Thanks.


-- 
H.J. Lu (hjl@gnu.org)
---
Sat Dec 13 21:46:53 1997  H.J. Lu  (hjl@gnu.org)

	* frame.h (__register_frame, __register_frame_table,
	__deregister_frame): New.

	* frame.c (__register_frame, __register_frame_table,
	__deregister_frame): New.

	* frame.c (__deregister_frame_info): Return void *.
	* frame.h (__deregister_frame_info): Ditto.
	* collect2.c (__deregister_frame_info): Ditto.
	
Index: frame.h
===================================================================
RCS file: /home/work/cvs/gnu/gcc/frame.h,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 frame.h
--- frame.h	1997/12/13 19:42:41	1.1.1.3
+++ frame.h	1997/12/14 05:37:59
@@ -34,6 +34,10 @@
   struct object *next;
 };
 
+extern void __register_frame (void * );
+extern void __register_frame_table (void *);
+extern void __deregister_frame (void *);
+
 /* Called either from crtbegin.o or a static constructor to register the
    unwind info for an object or translation unit, respectively.  */
 
@@ -46,7 +50,7 @@
 
 /* Called from crtend.o to deregister the unwind info for an object.  */
 
-extern void __deregister_frame_info (void *);
+extern void *__deregister_frame_info (void *);
 
 /* Called from __throw to find the registers to restore for a given
    PC_TARGET.  The caller should allocate a local variable of `struct
Index: collect2.c
===================================================================
RCS file: /home/work/cvs/gnu/gcc/collect2.c,v
retrieving revision 1.1.1.31
diff -u -r1.1.1.31 collect2.c
--- collect2.c	1997/12/13 19:42:32	1.1.1.31
+++ collect2.c	1997/12/14 05:38:18
@@ -1788,7 +1788,7 @@
       fprintf (stream, "};\n");
 
       fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
-      fprintf (stream, "extern void __deregister_frame_info (void *);\n");
+      fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
 
       fprintf (stream, "static void reg_frame () {\n");
       fprintf (stream, "\tstatic struct object ob;\n");
@@ -1874,7 +1874,7 @@
       fprintf (stream, "};\n");
 
       fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
-      fprintf (stream, "extern void __deregister_frame_info (void *);\n");
+      fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
 
       fprintf (stream, "static void reg_frame () {\n");
       fprintf (stream, "\tstatic struct object ob;\n");
Index: frame.c
===================================================================
RCS file: /home/work/cvs/gnu/gcc/frame.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 frame.c
--- frame.c	1997/12/13 19:42:38	1.1.1.4
+++ frame.c	1997/12/14 05:42:12
@@ -513,6 +513,13 @@
   objects = ob;
 }
 
+void
+__register_frame (void *begin)
+{
+  struct object *ob = (struct object *) malloc (sizeof (struct object));
+  __register_frame_info (begin, ob);                       
+}
+
 /* Similar, but BEGIN is actually a pointer to a table of unwind entries
    for different translation units.  Called from the file generated by
    collect2.  */
@@ -530,9 +537,16 @@
   objects = ob;
 }
 
+void
+__register_frame_table (void *begin)
+{
+  struct object *ob = (struct object *) malloc (sizeof (struct object));
+  __register_frame_info_table (begin, ob);
+}
+
 /* Called from crtend.o to deregister the unwind info for an object.  */
 
-void
+void *
 __deregister_frame_info (void *begin)
 {
   struct object **p = &objects;
@@ -548,11 +562,17 @@
 	  if (ob->pc_begin)
 	    free (ob->fde_array);
 
-	  return;
+	  return (void *) ob;
 	}
       p = &((*p)->next);
     }
   abort ();
+}
+
+void
+__deregister_frame (void *begin)
+{
+  free (__deregister_frame_info (begin));
 }
 
 /* Called from __throw to find the registers to restore for a given

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: We still need those old frame functions in libgcc.a
@ 1997-12-20  7:15 Andrew Zabolotny
  0 siblings, 0 replies; 5+ messages in thread
From: Andrew Zabolotny @ 1997-12-20  7:15 UTC (permalink / raw)
  To: egcs

On Tue, 16 Dec 1997 16:57:07 -0800 (PST), H.J. Lu wrote:

>__register_frame/__register_frame_info is referenced by
>every single binary, shared library or program, via
>crtbegin.o on platforms which use DWARF2 unwind info.
Some time ago somebody asked about executable size increase with egcs...
This is the
cause, and this is not very good: __main pulls in register_frame with all
frame exception info
from libgcc, even used with -fno-exceptions, and (at least on i?86) they
are of a considerable size.
This is annoying for lots of small executables.

Greetings,
    _\ndy@teamOS/2


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: We still need those old frame functions in libgcc.a
  1997-12-16 16:37 ` Jason Merrill
  1997-12-16 18:39   ` H.J. Lu
@ 1997-12-16 18:49   ` Jeffrey A Law
  1 sibling, 0 replies; 5+ messages in thread
From: Jeffrey A Law @ 1997-12-16 18:49 UTC (permalink / raw)
  To: Jason Merrill; +Cc: egcs, gcc2

  In message < u9afe0ztxj.fsf@yorick.cygnus.com >you write:
  > > If we leave -lgcc out, linker will leave __register_frame
  > > undefined in shared libraries, we have to keep
  > > __register_frame in libgcc.a in new gcc. Otherwise, during
  > > the link time, ld will find undefined __register_frame
  > > referenced by shared libraries when new gcc is used.
  > 
  > So don't leave out -lgcc.
Right.  HJ's even sent me a patch to fix this for sparc-linux.

ptx4 & sco5 are still broken in this regard according to HJ.  



  > > B. We have to keep __register_frame in libgcc.a.
  > 
  > > 1. Say binary "foo" needs libbar.so, since __register_frame
  > > is in libbar.so, linker will leave __register_frame
  > > undefined in foo and the dynamic linker will find
  > > __register_frame in libbar.so at the runtime.
  > 
  > Why would the linker add undefined symbols that are not used by foo, but
  > rather shared libraries linked with foo?  I don't think any linker actually
  > works that way.  libbar.so can look out for its own undefined symbols.
What I think HJ was trying to say was that no definition of
__register_frame will exist in foo since it can be satisfied from the copy
that existed in libbar.so when foo was originally linked against libbar.so.

This is how the GNU linker works:

First, we'll create a shared library which contains a reference to __divdi3:

[law@ralph /puke/law] cat foo.c
blah ()
{
long long x, y = 1;
return x / y;
}

[law@ralph /puke/law] gcc -fPIC -o libfoo.so foo.c -shared
[law@ralph /puke/law] nm libfoo.so | grep divdi3
000006a4 T __divdi3

Note the copy of __divdi3 in libfoo.so.

Now we'll create a main program that also uses __divdi3 and links
against libfoo.so:

[law@ralph /puke/law] gcc k.c -L./ -lfoo
[law@ralph /puke/law] ldd a.out
        libfoo.so => ./libfoo.so
        libc.so.5 => /lib/libc.so.5
[law@ralph /puke/law] nm a.out | grep divdi3
         U __divdi3
[law@ralph /puke/law] ./a.out

Note that a.out depends on libfoo and that "__divdi3" is considered
undefined in a.out since it will be satisfied by the libfoo.so
shared library.  Note that the program successfully runs.

Now we change libfoo.sl so that it no longer has a reference to __divdi3:

[law@ralph /puke/law] cat foo.c
blah ()
{
long long x, y = 1;
return x * y;
}

[law@ralph /puke/law] gcc -fPIC -o libfoo.so foo.c -shared
[law@ralph /puke/law] nm libfoo.so | grep divdi3

Now we we try to run a.out, which depends on libfoo.so it will fail:

[law@ralph /puke/law] ./a.out
./a.out: can't resolve symbol '__divdi3'



We run into basically the same situation with __register_frame.

jeff

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: We still need those old frame functions in libgcc.a
  1997-12-16 16:37 ` Jason Merrill
@ 1997-12-16 18:39   ` H.J. Lu
  1997-12-16 18:49   ` Jeffrey A Law
  1 sibling, 0 replies; 5+ messages in thread
From: H.J. Lu @ 1997-12-16 18:39 UTC (permalink / raw)
  To: egcs; +Cc: gcc2

> > 1. Say binary "foo" needs libbar.so, since __register_frame
> > is in libbar.so, linker will leave __register_frame
> > undefined in foo and the dynamic linker will find
> > __register_frame in libbar.so at the runtime.
> 
> Why would the linker add undefined symbols that are not used by foo, but
> rather shared libraries linked with foo?  I don't think any linker actually
> works that way.  libbar.so can look out for its own undefined symbols.
> 

__register_frame/__register_frame_info is referenced by
every single binary, shared library or program, via
crtbegin.o on platforms which use DWARF2 unwind info.


H.J.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: We still need those old frame functions in libgcc.a
       [not found] <m0xh7F0-0004ecC.cygnus.egcs@ocean.lucon.org>
@ 1997-12-16 16:37 ` Jason Merrill
  1997-12-16 18:39   ` H.J. Lu
  1997-12-16 18:49   ` Jeffrey A Law
  0 siblings, 2 replies; 5+ messages in thread
From: Jason Merrill @ 1997-12-16 16:37 UTC (permalink / raw)
  To: egcs, gcc2

>>>>> H J Lu <hjl@lucon.org> writes:

> Let me try again to explain why we need to keep the
> old __register_frame in libgcc.a.

I disagree.

> A. __register_frame and shared libraries.

> 1. gcc builds shared libraries with crtbegin.o.
> 2. crtbegin.o calls __register_frame.
> 3. gcc builds shared libraries with -lgcc.
> 4. The shared libraries built by gcc have __register_frame
>    which is visible by linker because of 1, 2, 3.

Sure, fine.

> If we leave -lgcc out, linker will leave __register_frame
> undefined in shared libraries, we have to keep
> __register_frame in libgcc.a in new gcc. Otherwise, during
> the link time, ld will find undefined __register_frame
> referenced by shared libraries when new gcc is used.

So don't leave out -lgcc.

> B. We have to keep __register_frame in libgcc.a.

> 1. Say binary "foo" needs libbar.so, since __register_frame
> is in libbar.so, linker will leave __register_frame
> undefined in foo and the dynamic linker will find
> __register_frame in libbar.so at the runtime.

Why would the linker add undefined symbols that are not used by foo, but
rather shared libraries linked with foo?  I don't think any linker actually
works that way.  libbar.so can look out for its own undefined symbols.

> 2. If we remove __register_frame from libgcc.a in new
> gcc and we rebuild libbar.so with the new gcc, now
> libbar.so won't have __register_frame. Now the dynamic
> linker won't find __register_frame at the run time
> since it is no longer in libbar.so. We are in a big trouble.

No, we aren't, because now nobody wants __register_frame.

Jason

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~1997-12-20  7:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-12-15 22:55 We still need those old frame functions in libgcc.a H.J. Lu
     [not found] <m0xh7F0-0004ecC.cygnus.egcs@ocean.lucon.org>
1997-12-16 16:37 ` Jason Merrill
1997-12-16 18:39   ` H.J. Lu
1997-12-16 18:49   ` Jeffrey A Law
1997-12-20  7:15 Andrew Zabolotny

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).