diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/powerpc')
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/_exit.S | 26 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/bits/mman.h | 26 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/brk.S (renamed from sysdeps/unix/sysv/linux/powerpc/brk.c) | 52 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/clone.S | 29 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/profil-counter.h | 14 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/sigreturn.S | 9 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/socket.S | 14 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/syscall.S | 8 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/sysdep.h | 111 |
9 files changed, 161 insertions, 128 deletions
diff --git a/sysdeps/unix/sysv/linux/powerpc/_exit.S b/sysdeps/unix/sysv/linux/powerpc/_exit.S deleted file mode 100644 index a1ca375d54..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/_exit.S +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include <sysdep.h> - -/* The 'exit' syscall does not return. */ - - .text -ENTRY(_exit) - DO_CALL (SYS_ify (exit)) -PSEUDO_END (_exit) diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/mman.h b/sysdeps/unix/sysv/linux/powerpc/bits/mman.h index da5ad0eb45..6d240c4b7a 100644 --- a/sysdeps/unix/sysv/linux/powerpc/bits/mman.h +++ b/sysdeps/unix/sysv/linux/powerpc/bits/mman.h @@ -1,4 +1,4 @@ -/* Definitions for POSIX memory map inerface. Linux/MIPS version. +/* Definitions for POSIX memory map inerface. Linux/PowerPC version. Copyright (C) 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -46,26 +46,15 @@ #define MAP_FIXED 0x010 /* Interpret addr exactly. */ #ifdef __USE_MISC # define MAP_FILE 0x000 -# define MAP_ANONYMOUS 0x800 /* Don't use a file. */ +# define MAP_ANONYMOUS 0x020 /* Don't use a file. */ # define MAP_ANON MAP_ANONYMOUS #endif -/* Not used by Linux, but here to make sure we don't clash with ABI - defines. */ -#ifdef __USE_MISC -# define MAP_RENAME 0x020 /* Assign page to file. */ -# define MAP_AUTOGROW 0x040 /* File may grow by writing. */ -# define MAP_LOCAL 0x080 /* Copy on fork/sproc. */ -# define MAP_AUTORSRV 0x100 /* Logical swap reserved on demand. */ -#endif - /* These are Linux-specific. */ #ifdef __USE_MISC -# define MAP_GROWSDOWN 0x1000 /* Stack-like segment. */ -# define MAP_DENYWRITE 0x2000 /* ETXTBSY */ -# define MAP_EXECUTABLE 0x4000 /* Mark it as an executable. */ -# define MAP_LOCKED 0x8000 /* Lock the mapping. */ -# define MAP_NORESERVE 0x0400 /* Don't check for reservations. */ +# define MAP_GROWSDOWN 0x0100 /* Stack-like segment. */ +# define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +# define MAP_EXECUTABLE 0x1000 /* Mark it as an executable. */ #endif /* Flags to `msync'. */ @@ -74,10 +63,11 @@ #define MS_INVALIDATE 2 /* Invalidate the caches. */ /* Flags for `mlockall'. */ -#define MCL_CURRENT 1 /* Lock all currently mapped pages. */ -#define MCL_FUTURE 2 /* Lock all additions to address +#define MCL_CURRENT 0x2000 /* Lock all currently mapped pages. */ +#define MCL_FUTURE 0x4000 /* Lock all additions to address space. */ + /* Flags for `mremap'. */ #ifdef __USE_GNU # define MREMAP_MAYMOVE 1 diff --git a/sysdeps/unix/sysv/linux/powerpc/brk.c b/sysdeps/unix/sysv/linux/powerpc/brk.S index e9826bd098..f4a3f3bcec 100644 --- a/sysdeps/unix/sysv/linux/powerpc/brk.c +++ b/sysdeps/unix/sysv/linux/powerpc/brk.S @@ -18,30 +18,32 @@ Boston, MA 02111-1307, USA. */ #include <sysdep.h> -#include <errno.h> +#define _ERRNO_H 1 +#include <bits/errno.h> + + .comm __curbrk,4,4 + .section ".text" +ENTRY(__brk) + stwu %r1,-16(%r1) + stw %r3,8(%r1) + DO_CALL(SYS_ify(brk)) + lwz %r6,8(%r1) +#ifdef PIC + mflr %r4 + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr %r5 + lwz %r5,__curbrk@got(%r5) + mtlr %r4 + stw %r3,0(%r5) +#else + stw %r3,__curbrk@sdarel(%r13) +#endif + cmplw %r6,%r3 + addi %r1,%r1,16 + li %r3,0 + blelr+ + li %r3,ENOMEM + b JUMPTARGET(__syscall_error) +END (__brk) -void *__curbrk; - -int -__brk (void *addr) -{ - register void *syscall_arg asm ("r3") = addr; - register int syscall_number asm ("r0") = SYS_ify (brk); - register void *newbrk asm ("r3"); - asm ("sc" - : "=r" (newbrk) - : "r" (syscall_arg), "r" (syscall_number) - : "r4","r5","r6","r7","r8","r9","r10","r11","r12", - "ctr", "mq", "cr0", "cr1", "cr6", "cr7"); - - __curbrk = newbrk; - - if (newbrk < addr) - { - __set_errno (ENOMEM); - return -1; - } - - return 0; -} weak_alias (__brk, brk) diff --git a/sysdeps/unix/sysv/linux/powerpc/clone.S b/sysdeps/unix/sysv/linux/powerpc/clone.S index cca63fe0bc..6209922b6b 100644 --- a/sysdeps/unix/sysv/linux/powerpc/clone.S +++ b/sysdeps/unix/sysv/linux/powerpc/clone.S @@ -30,13 +30,12 @@ ENTRY(__clone) /* Set up stack frame, save registers. */ stwu %r1,-32(%r1) - stw %r31,16(%r1) - stw %r30,20(%r1) - /* Check for child_stack == NULL || fn == NULL. */ cmpwi %cr0,%r4,0 - beq- %cr0,badargs + stw %r31,16(%r1) cmpwi %cr1,%r3,0 + stw %r30,20(%r1) + beq- %cr0,badargs beq- %cr1,badargs /* Set up stack frame for child. */ @@ -45,7 +44,7 @@ ENTRY(__clone) li %r0,0 stw %r0,0(%r4) - /* Save new stack, fn, args across syscall. */ + /* Save fn, args across syscall. */ mr %r30,%r3 /* Function in r30. */ mr %r31,%r6 /* Arguments in r31. */ @@ -70,21 +69,15 @@ child: mr %r3,%r31 blrl /* Call _exit with result from procedure. */ -#ifdef PIC - b _exit@plt -#else - b _exit -#endif + b JUMPTARGET(_exit) badargs: - li 3,-EINVAL + li %r3,EINVAL error: -#ifdef PIC - b __syscall_error@plt -#else - b __syscall_error -#endif - -PSEUDO_END (__clone) + lwz %r31,16(%r1) + lwz %r30,20(%r1) + addi %r1,%r1,32 + b JUMPTARGET(__syscall_error) +END (__clone) weak_alias (__clone, clone) diff --git a/sysdeps/unix/sysv/linux/powerpc/profil-counter.h b/sysdeps/unix/sysv/linux/powerpc/profil-counter.h index fed0913574..4be6f11270 100644 --- a/sysdeps/unix/sysv/linux/powerpc/profil-counter.h +++ b/sysdeps/unix/sysv/linux/powerpc/profil-counter.h @@ -17,10 +17,18 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <signal.h> +#include <sys/ptrace.h> + +/* You can also do this by using + void + profil_counter (int signo, struct pt_regs *pt) + { + profil_count ((void *) pt->nip); + } + */ void -profil_counter (int signo, struct sigcontext sc) +profil_counter (int signo, void **regs) { - profil_count ((void *) sc.regs->nip); + profil_count (regs[PT_NIP]); } diff --git a/sysdeps/unix/sysv/linux/powerpc/sigreturn.S b/sysdeps/unix/sysv/linux/powerpc/sigreturn.S index 748c26761f..9b9413e2f3 100644 --- a/sysdeps/unix/sysv/linux/powerpc/sigreturn.S +++ b/sysdeps/unix/sysv/linux/powerpc/sigreturn.S @@ -18,9 +18,6 @@ #include <sysdep.h> -/* The 'sigreturn' syscall does not return. */ - - .text -ENTRY(__sigreturn) - DO_CALL(SYS_ify(sigreturn)) -PSEUDO_END (__sigreturn) +PSEUDO (__sigreturn, sigreturn, 1) + /* Shouldn't get here. */ +PSEUDO_END(__sigreturn) diff --git a/sysdeps/unix/sysv/linux/powerpc/socket.S b/sysdeps/unix/sysv/linux/powerpc/socket.S index 904bca4dc3..681f7e6445 100644 --- a/sysdeps/unix/sysv/linux/powerpc/socket.S +++ b/sysdeps/unix/sysv/linux/powerpc/socket.S @@ -71,17 +71,11 @@ ENTRY(P(__,socket)) #if NARGS >= 9 #error too many arguments! #endif - li %r3,P(SOCKOP_,socket) - addi %r4,%r1,stackblock + li %r3,P(SOCKOP_,socket) + addi %r4,%r1,stackblock DO_CALL(SYS_ify(socketcall)) - addi %r1,%r1,48 - bnslr -#ifdef PIC - b __syscall_error@plt -#else - b __syscall_error -#endif - + addi %r1,%r1,48 + PSEUDO_RET PSEUDO_END (P(__,socket)) weak_alias (P(__,socket), socket) diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S index 2cb548245b..4d55076907 100644 --- a/sysdeps/unix/sysv/linux/powerpc/syscall.S +++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S @@ -18,7 +18,6 @@ #include <sysdep.h> - .text ENTRY (syscall) mr %r0,%r3 mr %r3,%r4 @@ -27,10 +26,5 @@ ENTRY (syscall) mr %r6,%r7 mr %r7,%r8 sc - bnslr -#ifdef PIC - b __syscall_error@plt -#else - b __syscall_error -#endif + PSEUDO_RET PSEUDO_END (syscall) diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/sysdep.h index 577809acb8..944793d56f 100644 --- a/sysdeps/unix/sysv/linux/powerpc/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/sysdep.h @@ -31,32 +31,113 @@ #ifdef ASSEMBLER -#define ENTRY(name) \ - .globl name; \ - .type name,@function; \ - .align 2; \ +/* This seems to always be the case on PPC. */ +#define ALIGNARG(log2) log2 +/* For ELF we need the `.type' directive to make shared libs work right. */ +#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg; +#define ASM_SIZE_DIRECTIVE(name) .size name,.-name + +/* If compiled for profiling, call `_mcount' at the start of each function. */ +#ifdef PROF +/* The mcount code relies on a the return address being on the stack + to locate our caller and so it can restore it; so store one just + for its benefit. */ +#ifdef PIC +#define CALL_MCOUNT \ + .pushsection; \ + .section ".data"; \ + .align ALIGNARG(2); \ +0:.long 0; \ + .previous; \ + mflr %r0; \ + stw %r0,4(%r1); \ + bl _GLOBAL_OFFSET_TABLE_@local-4; \ + mflr %r11; \ + lwz %r0,0b@got(%r11); \ + bl JUMPTARGET(_mcount); +#else /* PIC */ +#define CALL_MCOUNT \ + .section ".data"; \ + .align ALIGNARG(2); \ +0:.long 0; \ + .previous; \ + mflr %r0; \ + lis %r11,0b@ha; \ + stw %r0,4(%r1); \ + addi %r0,%r11,0b@l; \ + bl JUMPTARGET(_mcount); +#endif /* PIC */ +#else /* PROF */ +#define CALL_MCOUNT /* Do nothing. */ +#endif /* PROF */ + +#define ENTRY(name) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ + ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ + .align ALIGNARG(2); \ + C_LABEL(name) \ + CALL_MCOUNT + +#define EALIGN_W_0 /* No words to insert. */ +#define EALIGN_W_1 nop +#define EALIGN_W_2 nop;nop +#define EALIGN_W_3 nop;nop;nop +#define EALIGN_W_4 EALIGN_W_3;nop +#define EALIGN_W_5 EALIGN_W_4;nop +#define EALIGN_W_6 EALIGN_W_5;nop +#define EALIGN_W_7 EALIGN_W_6;nop + +/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes + past a 2^align boundary. */ +#ifdef PROF +#define EALIGN(name, alignt, words) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ + ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ + .align ALIGNARG(2); \ + C_LABEL(name) \ + CALL_MCOUNT \ + b 0f; \ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + 0: +#else /* PROF */ +#define EALIGN(name, alignt, words) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ + ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ C_LABEL(name) +#endif + +#undef END +#define END(name) \ + ASM_SIZE_DIRECTIVE(name) #define DO_CALL(syscall) \ li 0,syscall; \ sc #ifdef PIC +#define JUMPTARGET(name) name##@plt +#else +#define JUMPTARGET(name) name +#endif + #define PSEUDO(name, syscall_name, args) \ .section ".text"; \ ENTRY (name) \ - DO_CALL (SYS_ify (syscall_name)); \ + DO_CALL (SYS_ify (syscall_name)); + +#define PSEUDO_RET \ bnslr; \ - b __syscall_error@plt -#else -#define PSEUDO(name, syscall_name, args) \ - .section ".text"; \ - ENTRY (name) \ - DO_CALL (SYS_ify (syscall_name)); \ - bnslr; \ - b __syscall_error -#endif + b JUMPTARGET(__syscall_error) +#define ret PSEUDO_RET + +#undef PSEUDO_END +#define PSEUDO_END(name) \ + END (name) -#define ret /* Nothing (should be 'blr', but never reached). */ +/* Local labels stripped out by the linker. */ +#define L(x) .L##x #endif /* ASSEMBLER */ |