Browse Source

Richard Sandiford writes: add support for init/fini arrays in shared flat libraries

Mike Frysinger 17 years ago
parent
commit
808694e8a3

+ 9 - 0
Makefile.in

@@ -246,6 +246,15 @@ ifeq ($(DOPIC),y)
 	fi
 	fi
 endif
 endif
 endif
 endif
+ifeq ($(HAVE_SHARED_FLAT),y)
+	for file in lib/lib*.gdb; do \
+		if test -f $$file; then \
+			$(INSTALL) -m 755 $$file $(PREFIX)$(DEVEL_PREFIX)lib; \
+			$(INSTALL) -m 755 `echo $$file | sed 's/\.gdb$$//'` \
+			  $(PREFIX)$(DEVEL_PREFIX)lib; \
+		fi; \
+	done
+endif
 
 
 # Installs run-time libraries
 # Installs run-time libraries
 install_runtime:
 install_runtime:

+ 27 - 1
Makerules

@@ -11,6 +11,9 @@ libs: $(lib-so-y) $(lib-a-y)
 $(lib-so-y): $(interp)
 $(lib-so-y): $(interp)
 else
 else
 .LIBPATTERNS: "lib%.a"
 .LIBPATTERNS: "lib%.a"
+ifeq ($(HAVE_SHARED_FLAT),y)
+libs: $(lib-gdb-y)
+endif
 libs: $(lib-a-y)
 libs: $(lib-a-y)
 endif
 endif
 objs: all_objs
 objs: all_objs
@@ -131,6 +134,29 @@ define link.so
 	$(Q)$(LN) -sf $(1) $@
 	$(Q)$(LN) -sf $(1) $@
 endef
 endef
 
 
+# CRT files needed by link-flat.so
+LINK_FLAT_CRTS := $(top_builddir)lib/Scrt1.o $(top_builddir)lib/crti.o \
+	$(top_builddir)lib/crtn.o
+
+# Create a shared flat library from the archive named by the first dependency.
+# $@ names the shared library's .gdb file, not the flat file itself.
+# (This is because the .gdb suffix makes the ELF file more distinctive
+# than the suffixless flat file.)
+#
+# Argument 1 is the shared library file -- i.e. $(@:.gdb=) -- and argument 2
+# is the shared library identifier.  If it wasn't for $(disp_ld), we could
+# avoid passing $(@:.gdb=) as an argument and use $(@:.gdb=) instead of $(1).
+define link-flat.so
+	$(Q)$(INSTALL) -d $(dir $@)
+	$(Q)$(RM) $(1) $@
+	@$(disp_ld)
+	$(Q)$(LD) $(LDFLAGS-$(notdir $@)) -o $(1) \
+		-elf2flt -shared-lib-id $(2) $(top_builddir)lib/Scrt1.o \
+		$(top_builddir)/lib/crti.o --whole-archive $(firstword $^) \
+		--no-whole-archive $(LIBS-$(notdir $@)) $(LIBGCC) \
+		$(top_builddir)/lib/crtn.o
+endef
+
 define linkm.so
 define linkm.so
 	$(Q)$(INSTALL) -d $(dir $@)
 	$(Q)$(INSTALL) -d $(dir $@)
 	$(Q)$(RM) $@ $@.$(2) $(dir $@)$(1)
 	$(Q)$(RM) $@ $@.$(2) $(dir $@)$(1)
@@ -181,7 +207,7 @@ $(headers_dep):
 
 
 CRT := crt1
 CRT := crt1
 
 
-ifeq ($(HAVE_SHARED),y)
+ifeq ($(HAVE_SHARED)$(HAVE_SHARED_FLAT),y)
 CRTS=$(top_builddir)lib/$(CRT).o $(top_builddir)lib/S$(CRT).o
 CRTS=$(top_builddir)lib/$(CRT).o $(top_builddir)lib/S$(CRT).o
 else
 else
 CRTS=$(top_builddir)lib/$(CRT).o
 CRTS=$(top_builddir)lib/$(CRT).o

+ 0 - 13
Rules.mak

@@ -506,16 +506,3 @@ ifeq ($(UCLIBC_CTOR_DTOR),y)
 SHARED_START_FILES:=$(top_builddir)lib/crti.o $(LIBGCC_DIR)crtbeginS.o
 SHARED_START_FILES:=$(top_builddir)lib/crti.o $(LIBGCC_DIR)crtbeginS.o
 SHARED_END_FILES:=$(LIBGCC_DIR)crtendS.o $(top_builddir)lib/crtn.o
 SHARED_END_FILES:=$(LIBGCC_DIR)crtendS.o $(top_builddir)lib/crtn.o
 endif
 endif
-
-########################################
-#
-# uClinux shared lib support
-#
-
-ifeq ($(CONFIG_BINFMT_SHARED_FLAT),y)
-  # For the shared version of this, we specify no stack and its library ID
-  FLTFLAGS += -s 0
-  LIBID=1
-  export LIBID FLTFLAGS
-  SHARED_TARGET = lib/libc
-endif

+ 24 - 0
extra/Configs/Config.in

@@ -196,6 +196,30 @@ config DOPIC
 	  If you wish to build all of uClibc as PIC objects, then answer Y here.
 	  If you wish to build all of uClibc as PIC objects, then answer Y here.
 	  If you are unsure, then you should answer N.
 	  If you are unsure, then you should answer N.
 
 
+config HAVE_SHARED_FLAT
+	bool "Generate a flat-format shared library"
+	default n
+	depends on !ARCH_USE_MMU
+	help
+	  Answer Y here if you are using uClinux and wish to build uClibc
+	  as a flat-format shared library.
+
+config SHARED_FLAT_ID
+	int "Shared library id"
+	default 1
+	depends on HAVE_SHARED_FLAT
+	help
+	  When using flat shared libraries, every library has a unique
+	  system-wide identifier.  Identifier 0 is reserved for
+	  executables and true shared libraries have identifiers
+	  starting at 1.  The maximum shared library identifier is
+	  determined by the kernel and is usually 3.  Shared library
+	  N must be available on the target system as "/lib/libN.so".
+
+	  When a shared C library is used, it usually has identifier 1,
+	  but you can use this option to select a different identifier
+	  if you need to.
+
 config HAVE_NO_SHARED
 config HAVE_NO_SHARED
 	bool
 	bool
 	default n
 	default n

+ 4 - 0
libc/Makefile.in

@@ -50,6 +50,7 @@ libc-multi-y = $(filter-out $(libc-nomulti-y:.o=.c),$(all_sources))
 endif
 endif
 
 
 lib-a-y += $(top_builddir)lib/libc.a
 lib-a-y += $(top_builddir)lib/libc.a
+lib-gdb-y += $(top_builddir)lib/libc.gdb
 lib-so-y += $(libc)
 lib-so-y += $(libc)
 objclean-y += libc_clean
 objclean-y += libc_clean
 
 
@@ -89,5 +90,8 @@ $(top_builddir)lib/libc.a: $(libc-a-y) | $(crt-y)
 	$(do_strip)
 	$(do_strip)
 	$(do_ar)
 	$(do_ar)
 
 
+$(top_builddir)lib/libc.gdb: $(top_builddir)lib/libc.a $(LINK_FLAT_CRTS)
+	$(call link-flat.so,$(@:.gdb=),$(SHARED_FLAT_ID))
+
 libc_clean:
 libc_clean:
 	$(RM) $(libc_OUT)/*.{o,os,oS,a}
 	$(RM) $(libc_OUT)/*.{o,os,oS,a}

+ 3 - 1
libc/misc/internals/Makefile.in

@@ -18,7 +18,9 @@ MISC_INTERNALS_OBJ := $(patsubst %.c,$(MISC_INTERNALS_OUT)/%.o,$(CSRC))
 libc-y += $(MISC_INTERNALS_OBJ)
 libc-y += $(MISC_INTERNALS_OBJ)
 libc-shared-y += $(MISC_INTERNALS_OUT)/__uClibc_main.oS
 libc-shared-y += $(MISC_INTERNALS_OUT)/__uClibc_main.oS
 libc-static-y += $(MISC_INTERNALS_OUT)/__uClibc_main.o
 libc-static-y += $(MISC_INTERNALS_OUT)/__uClibc_main.o
-
+libc-static-$(HAVE_SHARED_FLAT) += \
+  $(MISC_INTERNALS_OUT)/shared_flat_initfini.o \
+  $(MISC_INTERNALS_OUT)/shared_flat_add_library.o
 libc-nomulti-y += $(MISC_INTERNALS_OUT)/__uClibc_main.o
 libc-nomulti-y += $(MISC_INTERNALS_OUT)/__uClibc_main.o
 
 
 objclean-y += misc_internals_objclean
 objclean-y += misc_internals_objclean

+ 12 - 4
libc/misc/internals/__uClibc_main.c

@@ -88,7 +88,9 @@ extern void weak_function _locale_init(void) attribute_hidden;
 extern void weak_function __pthread_initialize_minimal(void);
 extern void weak_function __pthread_initialize_minimal(void);
 #endif
 #endif
 
 
-#ifdef __UCLIBC_CTOR_DTOR__
+/* If __HAVE_SHARED_FLAT__, all array initialisation and finalisation
+ * is handled by the routines passed to __uClibc_main().  */
+#if defined (__UCLIBC_CTOR_DTOR__) && !defined (__HAVE_SHARED_FLAT__)
 extern void _dl_app_init_array(void);
 extern void _dl_app_init_array(void);
 extern void _dl_app_fini_array(void);
 extern void _dl_app_fini_array(void);
 # ifndef SHARED
 # ifndef SHARED
@@ -247,9 +249,11 @@ libc_hidden_proto(__uClibc_fini)
 void __uClibc_fini(void)
 void __uClibc_fini(void)
 {
 {
 #ifdef __UCLIBC_CTOR_DTOR__
 #ifdef __UCLIBC_CTOR_DTOR__
+    /* If __HAVE_SHARED_FLAT__, all array finalisation is handled
+     * by __app_fini.  */
 # ifdef SHARED
 # ifdef SHARED
     _dl_app_fini_array();
     _dl_app_fini_array();
-# else
+# elif !defined (__HAVE_SHARED_FLAT__)
     size_t i = __fini_array_end - __fini_array_start;
     size_t i = __fini_array_end - __fini_array_start;
     while (i-- > 0)
     while (i-- > 0)
 	(*__fini_array_start [i]) ();
 	(*__fini_array_start [i]) ();
@@ -348,7 +352,9 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
     /* Arrange for the application's dtors to run before we exit.  */
     /* Arrange for the application's dtors to run before we exit.  */
     __app_fini = app_fini;
     __app_fini = app_fini;
 
 
-# ifndef SHARED
+    /* If __HAVE_SHARED_FLAT__, all array initialisation is handled
+     * by __app_init.  */
+# if !defined (SHARED) && !defined (__HAVE_SHARED_FLAT__)
     /* For dynamically linked executables the preinit array is executed by
     /* For dynamically linked executables the preinit array is executed by
        the dynamic linker (before initializing any shared object).
        the dynamic linker (before initializing any shared object).
        For static executables, preinit happens rights before init.  */
        For static executables, preinit happens rights before init.  */
@@ -363,9 +369,11 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
     if (app_init!=NULL) {
     if (app_init!=NULL) {
 	app_init();
 	app_init();
     }
     }
+    /* If __HAVE_SHARED_FLAT__, all array initialisation is handled
+     * by __app_init.  */
 # ifdef SHARED
 # ifdef SHARED
     _dl_app_init_array();
     _dl_app_init_array();
-# else
+# elif !defined (__HAVE_SHARED_FLAT__)
     {
     {
 	const size_t size = __init_array_end - __init_array_start;
 	const size_t size = __init_array_end - __init_array_start;
 	size_t i;
 	size_t i;

+ 46 - 0
libc/misc/internals/shared_flat_add_library.c

@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2006 CodeSourcery Inc
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * This file defines __shared_flat_add_library.  If a library has
+ * initialistion and finalisation code, it should use this routine
+ * to register itself.
+ */
+#include "shared_flat_lib.h"
+
+/* The initialisation and finalisation symbols for this library.  */
+extern void _init(void) attribute_hidden weak_function;
+extern void _fini(void) attribute_hidden weak_function;
+extern void (*__preinit_array_start[])(void) attribute_hidden;
+extern void (*__preinit_array_end[])(void) attribute_hidden;
+extern void (*__init_array_start[])(void) attribute_hidden;
+extern void (*__init_array_end[])(void) attribute_hidden;
+extern void (*__fini_array_start[])(void) attribute_hidden;
+extern void (*__fini_array_end[])(void) attribute_hidden;
+
+/* The shared_flat_lib structure that describes this library.  */
+static struct shared_flat_lib this_lib = {
+	0,
+	0,
+	__preinit_array_start,
+	__preinit_array_end,
+	__init_array_start,
+	__init_array_end,
+	__fini_array_start,
+	__fini_array_end,
+	_init,
+	_fini
+};
+
+/* Add this_lib to the end of the global list. */
+void __shared_flat_add_library(void) attribute_hidden;
+void __shared_flat_add_library(void)
+{
+	this_lib.prev = __last_shared_lib;
+	if (this_lib.prev)
+		this_lib.prev->next = &this_lib;
+	else
+		__first_shared_lib = &this_lib;
+	__last_shared_lib = &this_lib;
+}

+ 53 - 0
libc/misc/internals/shared_flat_initfini.c

@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2006 CodeSourcery Inc
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * This file defines the main initialisation and finalisation code for
+ * shared flat libraries.  It in turn calls the initialisation and
+ * finalisation code for each registered library.
+ */
+#include "shared_flat_lib.h"
+
+/* A doubly-linked list of shared libraries.  Those nearer the head
+ * of the list should be initialised first and finalised last.  */
+struct shared_flat_lib *__first_shared_lib;
+struct shared_flat_lib *__last_shared_lib;
+
+void __shared_flat_init(void)
+{
+	struct shared_flat_lib *lib;
+	void (**start)(void);
+	void (**end)(void);
+
+	for (lib = __first_shared_lib; lib; lib = lib->next) {
+		end = lib->preinit_array_end;
+		for (start = lib->preinit_array_start; start < end; start++)
+			(*start)();
+	}
+
+	for (lib = __first_shared_lib; lib; lib = lib->next) {
+		if (lib->init)
+			lib->init();
+
+		end = lib->init_array_end;
+		for (start = lib->init_array_start; start < end; start++)
+			(*start)();
+	}
+}
+
+void __shared_flat_fini(void)
+{
+	struct shared_flat_lib *lib;
+	void (**start)(void);
+	void (**end)(void);
+
+	for (lib = __last_shared_lib; lib; lib = lib->prev) {
+		start = lib->fini_array_start;
+		for (end = lib->fini_array_end; end > start;)
+			(*--end)();
+
+		if (lib->fini)
+			lib->fini();
+	}
+}

+ 35 - 0
libc/misc/internals/shared_flat_lib.h

@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2006 CodeSourcery Inc
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * This file defines the shared_flat_lib structure and the global library
+ * list.   The structure is used to provide something close to ELF-like
+ * initialisation and finalisation when using shared flat libraries.
+ */
+#ifndef __SHARED_FLAT_LIB__
+#define __SHARED_FLAT_LIB__
+
+struct shared_flat_lib {
+	struct shared_flat_lib *prev;
+	struct shared_flat_lib *next;
+	/* .preinit_array is usually only supported for executables.
+	 * However, the distinction between the executable and its
+	 * shared libraries isn't as pronounced for flat files; a shared
+	 * library is really just a part of an executable that can be
+	 * shared with other executables.  We therefore allow
+	 * .preinit_array to be used in libraries too.  */
+	void (**preinit_array_start)(void);
+	void (**preinit_array_end)(void);
+	void (**init_array_start)(void);
+	void (**init_array_end)(void);
+	void (**fini_array_start)(void);
+	void (**fini_array_end)(void);
+	void (*init)(void);
+	void (*fini)(void);
+};
+
+extern struct shared_flat_lib *__first_shared_lib;
+extern struct shared_flat_lib *__last_shared_lib;
+
+#endif

+ 2 - 2
libc/sysdeps/linux/m68k/bsd-setjmp.S

@@ -5,6 +5,7 @@
 #define _ASM
 #define _ASM
 #define _SETJMP_H
 #define _SETJMP_H
 #include <bits/setjmp.h>
 #include <bits/setjmp.h>
+#include "m68k_pic.S"
 
 
 .globl setjmp;
 .globl setjmp;
 .type  setjmp,@function
 .type  setjmp,@function
@@ -18,6 +19,5 @@ setjmp:
 	fmovemx %fp2-%fp7, %a0@(JB_FPREGS)
 	fmovemx %fp2-%fp7, %a0@(JB_FPREGS)
 #endif
 #endif
 	clrl	%d0
 	clrl	%d0
-	lea		__sigjmp_save-.-8, %a0
-	jmp		0(%pc, %a0)
+	JUMP	__sigjmp_save,%a0
 
 

+ 8 - 3
libc/sysdeps/linux/m68k/clone.S

@@ -8,6 +8,7 @@
 #include <features.h>
 #include <features.h>
 #include <bits/errno.h>
 #include <bits/errno.h>
 #include <sys/syscall.h>
 #include <sys/syscall.h>
+#include "m68k_pic.S"
 
 
 /* int _clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
 /* int _clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
 
 
@@ -21,11 +22,11 @@ clone:
 	movel   4(%sp), %d1             /* no NULL function pointers */
 	movel   4(%sp), %d1             /* no NULL function pointers */
 	movel	%d1, %a0
 	movel	%d1, %a0
 	tstl    %d1
 	tstl    %d1
-	jbeq    __syscall_error
+	beq.w	__syscall_error_trampoline
 	movel   8(%sp), %d1             /* no NULL stack pointers */
 	movel   8(%sp), %d1             /* no NULL stack pointers */
 	movel	%d1, %a1
 	movel	%d1, %a1
 	tstl    %d1
 	tstl    %d1
-	jbeq    __syscall_error
+	beq.w   __syscall_error_trampoline
 
 
 	/* Allocate space and copy the argument onto the new stack.  */
 	/* Allocate space and copy the argument onto the new stack.  */
 	movel   16(%sp), -(%a1)
 	movel   16(%sp), -(%a1)
@@ -50,7 +51,7 @@ clone:
 #endif
 #endif
 
 
 	tstl    %d0
 	tstl    %d0
-	jbmi    __syscall_error
+	bmi.w   __syscall_error_trampoline
 	beq.w   thread_start
 	beq.w   thread_start
 
 
 	rts
 	rts
@@ -62,3 +63,7 @@ thread_start:
 	movel	#__NR_exit, %d0
 	movel	#__NR_exit, %d0
 	trap	#0
 	trap	#0
 	/*jsr    exit*/
 	/*jsr    exit*/
+
+__syscall_error_trampoline:
+	JUMP	__syscall_error,%a0
+

+ 35 - 6
libc/sysdeps/linux/m68k/crt1.S

@@ -34,6 +34,10 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
    02111-1307 USA.  */
 
 
+#include <features.h>
+#include "m68k_pic.S"
+
+#ifndef L_Scrt1
 /* This is the canonical entry point, usually the first thing in the text
 /* This is the canonical entry point, usually the first thing in the text
    segment.  The SVR4/m68k ABI says that when the entry point runs,
    segment.  The SVR4/m68k ABI says that when the entry point runs,
    most registers' values are unspecified, except for:
    most registers' values are unspecified, except for:
@@ -60,8 +64,6 @@
 		8(%sp)			envp
 		8(%sp)			envp
 */
 */
 
 
-#include <features.h>
-
 	.text
 	.text
 	.type	_init,%function
 	.type	_init,%function
 	.type	_fini,%function
 	.type	_fini,%function
@@ -76,6 +78,17 @@ _start:
 	   the outermost frame obviously.  */
 	   the outermost frame obviously.  */
 	sub.l %fp, %fp
 	sub.l %fp, %fp
 
 
+#if !defined __ARCH_USE_MMU__ && defined __PIC__
+	/* Set up the global pointer.  The GOT is at the beginning of the
+	   data segment, whose address is in %d5.  */
+	move.l %d5,%a5
+	.equ have_current_got, 1
+#endif
+	
+#ifdef __HAVE_SHARED_FLAT__
+	CALL __shared_flat_add_library,%a1
+#endif
+
 	/* Extract the arguments as encoded on the stack and set up the
 	/* Extract the arguments as encoded on the stack and set up the
 	   arguments for `main': argc, argv.  envp will be determined
 	   arguments for `main': argc, argv.  envp will be determined
 	   later in __libc_start_main.  */
 	   later in __libc_start_main.  */
@@ -100,19 +113,35 @@ _start:
 
 
 	/* Push the address of our own entry points to `.fini' and
 	/* Push the address of our own entry points to `.fini' and
 	   `.init'.  */
 	   `.init'.  */
-	pea _fini
-	pea _init
+#if defined __HAVE_SHARED_FLAT__
+	PEA_TEXT __shared_flat_fini,%a1
+	PEA_TEXT __shared_flat_init,%a1
+#else
+	PEA_TEXT _fini,%a1
+	PEA_TEXT _init,%a1
+#endif
 
 
 	pea (%a0)		/* Push second argument: argv.  */
 	pea (%a0)		/* Push second argument: argv.  */
 	move.l %d0, -(%sp)	/* Push first argument: argc.  */
 	move.l %d0, -(%sp)	/* Push first argument: argc.  */
 
 
-	pea main
+	PEA_TEXT main,%a1
 
 
 	/* Call the user's main function, and exit with its value.  But
 	/* Call the user's main function, and exit with its value.  But
 	   let the libc call main.  */
 	   let the libc call main.  */
-	jbsr __uClibc_main
+	CALL __uClibc_main,%a1
 
 
 	illegal			/* Crash if somehow `exit' does return.  */
 	illegal			/* Crash if somehow `exit' does return.  */
+#else
+	.text
+	.globl lib_main
+	.hidden lib_main
+	.type lib_main,@function
+lib_main:
+	move.l %d5,%a5
+	JUMP __shared_flat_add_library,%a0
+
+	.hidden _current_shared_library_a5_offset_
+#endif
 
 
 /* Define a symbol for the first piece of initialized data.  */
 /* Define a symbol for the first piece of initialized data.  */
 	.data
 	.data

+ 6 - 16
libc/sysdeps/linux/m68k/crti.S

@@ -1,27 +1,17 @@
-	.file	"initfini.c"
-#APP
-	
+#include "m68k_pic.S"
+
 	.section .init
 	.section .init
-#NO_APP
 	.align	2
 	.align	2
 	.globl	_init
 	.globl	_init
 	.type	_init, @function
 	.type	_init, @function
 _init:
 _init:
-	link.w %a6,#0
-#APP
-	
-	.align 2
-	
+	link.w	%a6,#0
+	INIT_GP
 	
 	
 	.section .fini
 	.section .fini
-#NO_APP
 	.align	2
 	.align	2
 	.globl	_fini
 	.globl	_fini
 	.type	_fini, @function
 	.type	_fini, @function
 _fini:
 _fini:
-	link.w %a6,#0
-#APP
-	.align 2
-	
-	
-	.ident	"GCC: (GNU) 3.3.2"
+	link.w	%a6,#0
+	INIT_GP

+ 6 - 21
libc/sysdeps/linux/m68k/crtn.S

@@ -1,26 +1,11 @@
-	.file	"initfini.c"
-#APP
-	
+#include "m68k_pic.S"
+
 	.section .init
 	.section .init
-#NO_APP
-	.align	2
-	.globl	_init
-	.type	_init, @function
-#NO_APP
-	unlk %a6
+	FINI_GP
+	unlk	%a6
 	rts
 	rts
-	.size	_init, .-_init
-#APP
 	
 	
 	.section .fini
 	.section .fini
-#NO_APP
-	.align	2
-	.globl	_fini
-	.type	_fini, @function
-#NO_APP
-	unlk %a6
+	FINI_GP
+	unlk	%a6
 	rts
 	rts
-	.size	_fini, .-_fini
-#APP
-	
-	.ident	"GCC: (GNU) 3.3.2"

+ 64 - 0
libc/sysdeps/linux/m68k/m68k_pic.S

@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 CodeSourcery Inc
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * This file defines some m68k assembly macros for handling the differences
+ * between PIC and non-PIC.
+ */
+#include <features.h>
+
+	/* When assembling code for shared flat libraries, this is nonzero
+	 * if %a5 points the current library's GOT.  */
+	.equ	have_current_got, 0
+
+	/* Perform the equivalent of "<op> <target>", where <target> is
+	 * a text address.  <tmp> is available as a temporary address
+	 * register.  */
+	.macro	DO_TEXT op,target,tmp
+#if defined __HAVE_SHARED_FLAT__
+	.ifne	have_current_got
+	move.l \target@GOT(%a5),\tmp
+	.else
+	move.l _current_shared_library_a5_offset_(%a5),\tmp
+	move.l \target@GOT(\tmp),\tmp
+	.endif
+	\op (\tmp)
+#elif defined __PIC__
+	lea \target-.-8,\tmp
+	\op (%pc,\tmp)
+#else
+	\op \target
+#endif
+	.endm
+
+	/* Do "pea <target>" when <target> is a text address.
+	 * <tmp> is available as a temporary register.  */
+	.macro PEA_TEXT target,tmp
+	DO_TEXT pea,\target,\tmp
+	.endm
+
+	/* Likewise jsr.  */
+	.macro CALL target,tmp
+	DO_TEXT jsr,\target,\tmp
+	.endm
+
+	/* Likewise jmp.  */
+	.macro JUMP target,tmp
+	DO_TEXT jmp,\target,\tmp
+	.endm
+
+	/* Initialize the global pointer, if functions need to do that.  */
+	.macro INIT_GP
+#if defined __HAVE_SHARED_FLAT__
+	move.l	%a5,-(%sp)
+	move.l _current_shared_library_a5_offset_(%a5),%a5
+#endif
+	.endm
+
+	/* Undo the effects of INIT_GP.  */
+	.macro FINI_GP
+#if defined __HAVE_SHARED_FLAT__
+	move.l	(%sp)+,%a5
+#endif
+	.endm

+ 2 - 2
libc/sysdeps/linux/m68k/setjmp.S

@@ -5,6 +5,7 @@
 #define _ASM
 #define _ASM
 #define _SETJMP_H
 #define _SETJMP_H
 #include <bits/setjmp.h>
 #include <bits/setjmp.h>
+#include "m68k_pic.S"
 
 
 .globl __sigsetjmp;
 .globl __sigsetjmp;
 .type  __sigsetjmp,@function
 .type  __sigsetjmp,@function
@@ -18,6 +19,5 @@ __sigsetjmp:
 	fmovemx %fp2-%fp7, %a0@(JB_FPREGS)
 	fmovemx %fp2-%fp7, %a0@(JB_FPREGS)
 #endif
 #endif
 	clrl	%d0
 	clrl	%d0
-	lea		__sigjmp_save-.-8, %a0
-	jmp		0(%pc, %a0)
+	JUMP	__sigjmp_save,%a0