From 808694e8a330e32741b7781467610d8cec99ae6e Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 8 Dec 2006 22:53:40 +0000 Subject: Richard Sandiford writes: add support for init/fini arrays in shared flat libraries --- libc/sysdeps/linux/m68k/bsd-setjmp.S | 4 +-- libc/sysdeps/linux/m68k/clone.S | 11 +++++-- libc/sysdeps/linux/m68k/crt1.S | 41 +++++++++++++++++++---- libc/sysdeps/linux/m68k/crti.S | 22 ++++--------- libc/sysdeps/linux/m68k/crtn.S | 27 ++++----------- libc/sysdeps/linux/m68k/m68k_pic.S | 64 ++++++++++++++++++++++++++++++++++++ libc/sysdeps/linux/m68k/setjmp.S | 4 +-- 7 files changed, 123 insertions(+), 50 deletions(-) create mode 100644 libc/sysdeps/linux/m68k/m68k_pic.S (limited to 'libc/sysdeps') diff --git a/libc/sysdeps/linux/m68k/bsd-setjmp.S b/libc/sysdeps/linux/m68k/bsd-setjmp.S index b83573c80..fdd7540a6 100644 --- a/libc/sysdeps/linux/m68k/bsd-setjmp.S +++ b/libc/sysdeps/linux/m68k/bsd-setjmp.S @@ -5,6 +5,7 @@ #define _ASM #define _SETJMP_H #include +#include "m68k_pic.S" .globl setjmp; .type setjmp,@function @@ -18,6 +19,5 @@ setjmp: fmovemx %fp2-%fp7, %a0@(JB_FPREGS) #endif clrl %d0 - lea __sigjmp_save-.-8, %a0 - jmp 0(%pc, %a0) + JUMP __sigjmp_save,%a0 diff --git a/libc/sysdeps/linux/m68k/clone.S b/libc/sysdeps/linux/m68k/clone.S index 8ef916e91..7eddff10c 100644 --- a/libc/sysdeps/linux/m68k/clone.S +++ b/libc/sysdeps/linux/m68k/clone.S @@ -8,6 +8,7 @@ #include #include #include +#include "m68k_pic.S" /* 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 %d1, %a0 tstl %d1 - jbeq __syscall_error + beq.w __syscall_error_trampoline movel 8(%sp), %d1 /* no NULL stack pointers */ movel %d1, %a1 tstl %d1 - jbeq __syscall_error + beq.w __syscall_error_trampoline /* Allocate space and copy the argument onto the new stack. */ movel 16(%sp), -(%a1) @@ -50,7 +51,7 @@ clone: #endif tstl %d0 - jbmi __syscall_error + bmi.w __syscall_error_trampoline beq.w thread_start rts @@ -62,3 +63,7 @@ thread_start: movel #__NR_exit, %d0 trap #0 /*jsr exit*/ + +__syscall_error_trampoline: + JUMP __syscall_error,%a0 + diff --git a/libc/sysdeps/linux/m68k/crt1.S b/libc/sysdeps/linux/m68k/crt1.S index 9ce14e594..a5f973fe2 100644 --- a/libc/sysdeps/linux/m68k/crt1.S +++ b/libc/sysdeps/linux/m68k/crt1.S @@ -34,6 +34,10 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include +#include "m68k_pic.S" + +#ifndef L_Scrt1 /* 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, most registers' values are unspecified, except for: @@ -60,8 +64,6 @@ 8(%sp) envp */ -#include - .text .type _init,%function .type _fini,%function @@ -76,6 +78,17 @@ _start: the outermost frame obviously. */ 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 arguments for `main': argc, argv. envp will be determined later in __libc_start_main. */ @@ -100,19 +113,35 @@ _start: /* Push the address of our own entry points to `.fini' and `.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. */ 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 let the libc call main. */ - jbsr __uClibc_main + CALL __uClibc_main,%a1 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. */ .data diff --git a/libc/sysdeps/linux/m68k/crti.S b/libc/sysdeps/linux/m68k/crti.S index ccfe99133..1b4b643b6 100644 --- a/libc/sysdeps/linux/m68k/crti.S +++ b/libc/sysdeps/linux/m68k/crti.S @@ -1,27 +1,17 @@ - .file "initfini.c" -#APP - +#include "m68k_pic.S" + .section .init -#NO_APP .align 2 .globl _init .type _init, @function _init: - link.w %a6,#0 -#APP - - .align 2 - + link.w %a6,#0 + INIT_GP .section .fini -#NO_APP .align 2 .globl _fini .type _fini, @function _fini: - link.w %a6,#0 -#APP - .align 2 - - - .ident "GCC: (GNU) 3.3.2" + link.w %a6,#0 + INIT_GP diff --git a/libc/sysdeps/linux/m68k/crtn.S b/libc/sysdeps/linux/m68k/crtn.S index d29c02dec..2a29b8726 100644 --- a/libc/sysdeps/linux/m68k/crtn.S +++ b/libc/sysdeps/linux/m68k/crtn.S @@ -1,26 +1,11 @@ - .file "initfini.c" -#APP - +#include "m68k_pic.S" + .section .init -#NO_APP - .align 2 - .globl _init - .type _init, @function -#NO_APP - unlk %a6 + FINI_GP + unlk %a6 rts - .size _init, .-_init -#APP .section .fini -#NO_APP - .align 2 - .globl _fini - .type _fini, @function -#NO_APP - unlk %a6 + FINI_GP + unlk %a6 rts - .size _fini, .-_fini -#APP - - .ident "GCC: (GNU) 3.3.2" diff --git a/libc/sysdeps/linux/m68k/m68k_pic.S b/libc/sysdeps/linux/m68k/m68k_pic.S new file mode 100644 index 000000000..e01e33b83 --- /dev/null +++ b/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 + + /* 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 " ", where is + * a text address. 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 " when is a text address. + * 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 diff --git a/libc/sysdeps/linux/m68k/setjmp.S b/libc/sysdeps/linux/m68k/setjmp.S index d7ca5dd6d..4adda0af5 100644 --- a/libc/sysdeps/linux/m68k/setjmp.S +++ b/libc/sysdeps/linux/m68k/setjmp.S @@ -5,6 +5,7 @@ #define _ASM #define _SETJMP_H #include +#include "m68k_pic.S" .globl __sigsetjmp; .type __sigsetjmp,@function @@ -18,6 +19,5 @@ __sigsetjmp: fmovemx %fp2-%fp7, %a0@(JB_FPREGS) #endif clrl %d0 - lea __sigjmp_save-.-8, %a0 - jmp 0(%pc, %a0) + JUMP __sigjmp_save,%a0 -- cgit v1.2.3