[uClibc]setjmp() and dynamic loading segfault

michaels at jungo.com michaels at jungo.com
Mon Mar 5 17:33:57 UTC 2001


Hi,

Seems like the mystery is solved: the symbols (__sigsetjmp and __setjmp)
were not defined as functions in *.S, and as a result dynamic linker did
not do the correct resolve for __sigjmp_save (which is in libuClibc) but
silently continue execution until the end of program's address space,
causing segfault at its end. Symptom: the symbol __sigsetjmp was mapped
to .bss (!!!) and not *UND* as usual. 

Quick fix: define the symbol's type to be function and then in dynamic
table it is correctly resolved for the binary. 

Patch attached. I also corrected several other *.S to reflect this bug
correction.

Manuel Novoa III wrote:
> For what it is worth, if I statically link the setjmp.o file with your example
> program, but link the rest of uClibc dynamically, it runs fine.  See if that
> works for you until it gets fixed.

When statically linking setjmp.o, it is supposed that you posess the
compiled sources, which is not always the case in my company's
environement...
 
Sincerely yours,
Michael Shmulevich
______________________________________
Software Developer
Jungo - R&D 
email: michaels at jungo.com
web: http://www.jungo.com
Phone: 1-877-514-0537(USA)  +972-9-8859365(Worldwide) ext. 233
Fax:   1-877-514-0538(USA)  +972-9-8859366(Worldwide)
-------------- next part --------------
Index: clone.S
===================================================================
RCS file: /var/cvs/uClibc/sysdeps/linux/i386/clone.S,v
retrieving revision 1.3
diff -d -u -r1.3 clone.S
--- clone.S	2000/10/30 21:43:47	1.3
+++ clone.S	2001/03/05 17:31:43
@@ -27,6 +27,7 @@
 
         .text
 .globl __clone;
+.type	 __clone, at function
 .align 4;                                                               \
 __clone:
 	/* Sanity check arguments.  */
Index: longjmp.S
===================================================================
RCS file: /var/cvs/uClibc/sysdeps/linux/i386/longjmp.S,v
retrieving revision 1.3
diff -d -u -r1.3 longjmp.S
--- longjmp.S	2000/10/30 21:43:47	1.3
+++ longjmp.S	2001/03/05 17:31:43
@@ -22,6 +22,7 @@
 #include <bits/setjmp.h>
 
 .globl longjmp;
+.type	longjmp, at function
 .align 4;                                                               \
 longjmp:
 	movl 4(%esp), %ecx	/* User's jmp_buf in %ecx.  */
Index: setjmp.S
===================================================================
RCS file: /var/cvs/uClibc/sysdeps/linux/i386/setjmp.S,v
retrieving revision 1.5
diff -d -u -r1.5 setjmp.S
--- setjmp.S	2000/10/30 22:09:42	1.5
+++ setjmp.S	2001/03/05 17:31:43
@@ -22,6 +22,7 @@
 #include <bits/setjmp.h>
 
 .globl __setjmp;
+.type	 __setjmp, at function
 .align 4;                                                               \
 __setjmp:
 	popl %eax		/* Pop return address.  */
@@ -31,6 +32,7 @@
 	pushl %eax		/* Push back return address.  */
 
 .globl __sigsetjmp;
+.type	 __sigsetjmp, at function
 .align 4;                                                               \
 __sigsetjmp:
 	movl 4(%esp), %eax	/* User's jmp_buf in %eax.  */
@@ -45,15 +47,15 @@
      	movl %ecx, (JB_PC*4)(%eax)
 
 	/* Make a tail call to __sigjmp_save; it takes the same args.  */
-#ifdef	PIC
+#if defined(PIC)
 	/* We cannot use the PLT, because it requires that %ebx be set, but
            we can't save and restore our caller's value.  Instead, we do an
            indirect jump through the GOT, using for the temporary register
            %ecx, which is call-clobbered.  */
-	call L(here)
-L(here):
+	call Lhere
+Lhere:
 	popl %ecx
-	addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ecx
+	addl $_GLOBAL_OFFSET_TABLE_+[.-Lhere], %ecx
 	movl (__sigjmp_save)(%ecx), %ecx
 	jmp *%ecx
 #else


More information about the uClibc mailing list