This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][M68K] Fix shared libraries on uClinux


Hello,

At the moment binaries built for M68K uClinux -mid-shared-library fail with 'Illegal instruction' error. The problem is in assembler piece of libgcc that provides FP routines for FPU-less cores.

The attached patch fixes this problem. OK for trunk?

Analysis:

1. Libstdc++ library is compiled with -mid-shared-library.

2. A program that has floating point operation (e.g., compare) is compiled for an fpu-less CPU. This FP operation is implemented with couple of functions: implementation (__cmpsf_internal) and wrapper (__eqsf2). To handle FP operation an object file is being included from libgcc.a (_eqsf2.o). As we compile against shared libstdc++, which already has linked in __cmpsf_internal, we only link in the wrapper (__eqsf2) to executable.

3. The wrapper (_eqsf2) contains PC-relative relocation to call the implementation (__cmpsf_internal). When the wrapper is being linked into the executable, this relocation resolves to symbol in the shared library (libstdc++) and PC-relative offset is written to the binary. The linker assumes that the binary will be loaded at address 0x0. At runtime the binary is not being loaded at 0x0 and the wrong offset triggers jump to nowhere.

The attached patch fixes this problem by using GOT instead of PC-relative addressing and by hiding implementation functions so that only wrappers are visible to outside world.


-- MaximK CodeSourcery
2008-11-19  Nathan Sidwell  <nathan@codesourcery.com>
	    Maxim Kuvyrkov  <maxim@codesourcery.com>

	* config/m68k/lb1sf68.asm (PICCALL, PICJUMP): Use GOT instead of
	PC-relative addressing when compiling for uclinux PIC.
	(__cmpdf_internal, __cmpsf_internal): Hide.
	(__cmpdf, __cmpsf): Use PIC call sequence.
Index: config/m68k/lb1sf68.asm
===================================================================
--- config/m68k/lb1sf68.asm	(revision 141999)
+++ config/m68k/lb1sf68.asm	(working copy)
@@ -129,30 +129,6 @@ Boston, MA 02110-1301, USA.  */
 
 #else /* __PIC__ */
 
-	/* Common for Linux and uClinux, the latter with either
-	   -mid-shared-library or -msep-data.  */
-
-	.macro PICCALL addr
-#if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__)
-	lea	\addr-.-8,a0
-	jsr	pc@(a0)
-#else
-	bsr	\addr
-#endif
-	.endm
-
-	.macro PICJUMP addr
-	/* ISA C has no bra.l instruction, and since this assembly file
-	   gets assembled into multiple object files, we avoid the
-	   bra instruction entirely.  */
-#if defined (__mcoldfire__) && !defined (__mcfisab__)
-	lea	\addr-.-8,a0
-	jmp	pc@(a0)
-#else
-	bra	\addr
-#endif
-	.endm
-
 # if defined (__uClinux__)
 
 	/* Versions for uClinux */
@@ -171,6 +147,16 @@ Boston, MA 02110-1301, USA.  */
 	movel	\sym@GOT(\areg), sp@-
 	.endm
 
+	.macro PICCALL addr
+	PICLEA	\addr,a0
+	jsr	a0@
+	.endm
+
+	.macro PICJUMP addr
+	PICLEA	\addr,a0
+	jmp	a0@
+	.endm
+
 #  else /* !__ID_SHARED_LIBRARY__ */
 
 	/* Versions for -msep-data */
@@ -183,6 +169,27 @@ Boston, MA 02110-1301, USA.  */
 	movel	\sym@GOT(a5), sp@-
 	.endm
 
+	.macro PICCALL addr
+#if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__)
+	lea	\addr-.-8,a0
+	jsr	pc@(a0)
+#else
+	bsr	\addr
+#endif
+	.endm
+
+	.macro PICJUMP addr
+	/* ISA C has no bra.l instruction, and since this assembly file
+	   gets assembled into multiple object files, we avoid the
+	   bra instruction entirely.  */
+#if defined (__mcoldfire__) && !defined (__mcfisab__)
+	lea	\addr-.-8,a0
+	jmp	pc@(a0)
+#else
+	bra	\addr
+#endif
+	.endm
+
 #  endif
 
 # else /* !__uClinux__ */
@@ -201,6 +208,27 @@ Boston, MA 02110-1301, USA.  */
 	movel	\sym@GOT(\areg), sp@-
 	.endm
 
+	.macro PICCALL addr
+#if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__)
+	lea	\addr-.-8,a0
+	jsr	pc@(a0)
+#else
+	bsr	\addr
+#endif
+	.endm
+
+	.macro PICJUMP addr
+	/* ISA C has no bra.l instruction, and since this assembly file
+	   gets assembled into multiple object files, we avoid the
+	   bra instruction entirely.  */
+#if defined (__mcoldfire__) && !defined (__mcfisab__)
+	lea	\addr-.-8,a0
+	jmp	pc@(a0)
+#else
+	bra	\addr
+#endif
+	.endm
+
 # endif
 #endif /* __PIC__ */
 
@@ -648,6 +676,7 @@ ROUND_TO_MINUS    = 3 | round result tow
 	.globl SYM (__negdf2)
 	.globl SYM (__cmpdf2)
 	.globl SYM (__cmpdf2_internal)
+	.hidden SYM (__cmpdf2_internal)
 
 	.text
 	.even
@@ -2410,7 +2439,7 @@ SYM (__cmpdf2):
 	movl	a6@(16),sp@-
 	movl	a6@(12),sp@-
 	movl	a6@(8),sp@-
-	bsr	SYM (__cmpdf2_internal)
+	PICCALL	SYM (__cmpdf2_internal)
 	unlk	a6
 	rts
 
@@ -2562,6 +2591,7 @@ ROUND_TO_MINUS    = 3 | round result tow
 	.globl SYM (__negsf2)
 	.globl SYM (__cmpsf2)
 	.globl SYM (__cmpsf2_internal)
+	.hidden SYM (__cmpsf2_internal)
 
 | These are common routines to return and signal exceptions.	
 
@@ -3816,7 +3846,7 @@ SYM (__cmpsf2):
 	pea	1
 	movl	a6@(12),sp@-
 	movl	a6@(8),sp@-
-	bsr (__cmpsf2_internal)
+	PICCALL SYM (__cmpsf2_internal)
 	unlk	a6
 	rts
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]