aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Jaeger <aj@suse.de>2001-06-06 11:57:49 +0000
committerAndreas Jaeger <aj@suse.de>2001-06-06 11:57:49 +0000
commit8aaf02b5663f7669d192ffddf56b776f1b8092ef (patch)
treeb08f28f41251b73cf263732a4605bc40f9d388a6
parenta18f73be580ea822075b931f8f4d368b368d0e06 (diff)
downloadglibc-8aaf02b5663f7669d192ffddf56b776f1b8092ef.zip
glibc-8aaf02b5663f7669d192ffddf56b776f1b8092ef.tar.gz
glibc-8aaf02b5663f7669d192ffddf56b776f1b8092ef.tar.bz2
HPPA setjmp implementation.
-rw-r--r--sysdeps/hppa/bsd-_setjmp.S36
-rw-r--r--sysdeps/hppa/bsd-setjmp.S36
-rw-r--r--sysdeps/hppa/dl-machine.h319
-rw-r--r--sysdeps/unix/sysv/linux/hppa/getrlimit.c1
-rw-r--r--sysdeps/unix/sysv/linux/hppa/setrlimit.c1
-rw-r--r--sysdeps/unix/sysv/linux/hppa/syscall.S13
-rw-r--r--sysdeps/unix/sysv/linux/hppa/syscalls.list2
-rw-r--r--sysdeps/unix/sysv/linux/hppa/sysdep.c27
8 files changed, 262 insertions, 173 deletions
diff --git a/sysdeps/hppa/bsd-_setjmp.S b/sysdeps/hppa/bsd-_setjmp.S
new file mode 100644
index 0000000..487e8c7
--- /dev/null
+++ b/sysdeps/hppa/bsd-_setjmp.S
@@ -0,0 +1,36 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. HPPA version.
+ Copyright (C) 2001 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. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+ .text
+ .align 4
+ .globl _setjmp
+ .export _setjmp, code
+ .level 2.0
+ .proc
+ .callinfo
+ .import __sigsetjmp
+_setjmp:
+ b __sigsetjmp
+ ldi 0, %r25
+
+ .procend
diff --git a/sysdeps/hppa/bsd-setjmp.S b/sysdeps/hppa/bsd-setjmp.S
new file mode 100644
index 0000000..2614b49
--- /dev/null
+++ b/sysdeps/hppa/bsd-setjmp.S
@@ -0,0 +1,36 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. HPPA version.
+ Copyright (C) 2001 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. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+ .text
+ .align 4
+ .globl setjmp
+ .export setjmp, code
+ .level 2.0
+ .proc
+ .callinfo
+ .import __sigsetjmp
+setjmp:
+ b __sigsetjmp
+ ldi 1, %r25
+
+ .procend
diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h
index 6f2020c..4616334 100644
--- a/sysdeps/hppa/dl-machine.h
+++ b/sysdeps/hppa/dl-machine.h
@@ -75,11 +75,11 @@ elf_machine_dynamic (void)
#if 0
/* Use this method if GOT address not yet set up. */
- asm ("\
- b,l 1f,%0
- depi 0,31,2,%0
-1: addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 8),%0
- ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 12)(%%r1),%0"
+ asm (
+" b,l 1f,%0\n"
+" depi 0,31,2,%0\n"
+"1: addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 8),%0\n"
+" ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 12)(%%r1),%0\n"
: "=r" (dynamic) : : "r1");
#else
/* This works because we already have our GOT address available. */
@@ -95,13 +95,13 @@ elf_machine_load_address (void)
{
Elf32_Addr dynamic, dynamic_linkaddress;
- asm ("\
- b,l 1f,%0
- depi 0,31,2,%0
-1: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%0
- ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%%r1),%1
- addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%0
- ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%%r1),%0"
+ asm (
+" b,l 1f,%0\n"
+" depi 0,31,2,%0\n"
+"1: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%0\n"
+" ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%%r1),%1\n"
+" addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%0\n"
+" ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%%r1),%0\n"
: "=r" (dynamic_linkaddress), "=r" (dynamic) : : "r1");
return dynamic - dynamic_linkaddress;
@@ -250,153 +250,154 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
#define RTLD_START \
/* Set up dp for any non-PIC lib constructors that may be called. */ \
-static struct link_map * set_dp (struct link_map *map) \
-{ \
- register Elf32_Addr dp asm ("%r27"); \
- dp = D_PTR (map, l_info[DT_PLTGOT]); \
- asm volatile ("" : : "r" (dp)); \
- return map; \
-} \
- \
-asm ("\
- .text
- .globl _start
- .type _start,@function
-_start:
- /* The kernel does not give us an initial stack frame. */
- ldo 64(%sp),%sp
- /* Save the relevant arguments (yes, those are the correct
- registers, the kernel is weird) in their stack slots. */
- stw %r25,-40(%sp) /* argc */
- stw %r24,-44(%sp) /* argv */
-
- /* We need the LTP, and we need it now. */
- /* $PIC_pcrel$0 points 8 bytes past the current instruction,
- just like a branch reloc. This sequence gets us the runtime
- address of _DYNAMIC. */
- bl 0f,%r19
- depi 0,31,2,%r19 /* clear priviledge bits */
-0: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%r19
- ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%r1),%r26
-
- /* Also get the link time address from the first entry of the GOT. */
- addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%r19
- ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%r1),%r20
-
- sub %r26,%r20,%r20 /* Calculate load offset */
-
- /* Rummage through the dynamic entries, looking for DT_PLTGOT. */
- ldw,ma 8(%r26),%r19
-1: cmpib,=,n 3,%r19,2f /* tag == DT_PLTGOT? */
- cmpib,<>,n 0,%r19,1b
- ldw,ma 8(%r26),%r19
-
- /* Uh oh! We didn't find one. Abort. */
- iitlbp %r0,(%r0)
-
-2: ldw -4(%r26),%r19 /* Found it, load value. */
- add %r19,%r20,%r19 /* And add the load offset. */
-
- /* Our initial stack layout is rather different from everyone
- else's due to the unique PA-RISC ABI. As far as I know it
- looks like this:
-
- ----------------------------------- (this frame created above)
- | 32 bytes of magic |
- |---------------------------------|
- | 32 bytes argument/sp save area |
- |---------------------------------| ((current->mm->env_end) + 63 & ~63)
- | N bytes of slack |
- |---------------------------------|
- | envvar and arg strings |
- |---------------------------------|
- | ELF auxiliary info |
- | (up to 28 words) |
- |---------------------------------|
- | Environment variable pointers |
- | upwards to NULL |
- |---------------------------------|
- | Argument pointers |
- | upwards to NULL |
- |---------------------------------|
- | argc (1 word) |
- -----------------------------------
-
- So, obviously, we can't just pass %sp to _dl_start. That's
- okay, argv-4 will do just fine.
-
- The pleasant part of this is that if we need to skip
- arguments we can just decrement argc and move argv, because
- the stack pointer is utterly unrelated to the location of
- the environment and argument vectors. */
-
- /* This is always within range so we'll be okay. */
- bl _dl_start,%rp
- ldo -4(%r24),%r26
-
- .globl _dl_start_user
- .type _dl_start_user,@function
-_dl_start_user:
- /* Save the entry point in %r3. */
- copy %ret0,%r3
-
- /* Remember the lowest stack address. */
- addil LT'__libc_stack_end,%r19
- ldw RT'__libc_stack_end(%r1),%r20
- stw %sp,0(%r20)
-
- /* See if we were called as a command with the executable file
- name as an extra leading argument. */
- addil LT'_dl_skip_args,%r19
- ldw RT'_dl_skip_args(%r1),%r20
- ldw 0(%r20),%r20
-
- ldw -40(%sp),%r25 /* argc */
- comib,= 0,%r20,.Lnofix /* FIXME: will be mispredicted */
- ldw -44(%sp),%r24 /* argv (delay slot) */
-
- sub %r25,%r20,%r25
- stw %r25,-40(%sp)
- sh2add %r20,%r24,%r24
- stw %r24,-44(%sp)
-
-.Lnofix:
- addil LT'_dl_loaded,%r19
- ldw RT'_dl_loaded(%r1),%r26
- bl set_dp, %r2
- ldw 0(%r26),%r26
-
- /* Call _dl_init(_dl_loaded, argc, argv, envp). */
- copy %r28,%r26
-
- /* envp = argv + argc + 1 */
- sh2add %r25,%r24,%r23
- bl _dl_init,%r2
- ldo 4(%r23),%r23 /* delay slot */
-
- /* Reload argc, argv to the registers start.S expects them in (feh) */
- ldw -40(%sp),%r25
- ldw -44(%sp),%r24
-
- /* _dl_fini does have a PLT slot now. I don't know how to get
- to it though, so this hack will remain. */
- .section .data
-__dl_fini_plabel:
- .word _dl_fini
- .word 0xdeadbeef
- .previous
-
- /* %r3 contains a function pointer, we need to mask out the lower
- * bits and load the gp and jump address. */
- depi 0,31,2,%r3
- ldw 0(%r3),%r2
- addil LT'__dl_fini_plabel,%r19
- ldw RT'__dl_fini_plabel(%r1),%r23
- stw %r19,4(%r23)
- ldw 4(%r3),%r19 /* load the object's gp */
- bv %r0(%r2)
- depi 2,31,2,%r23 /* delay slot */
-");
+static struct link_map * \
+set_dp (struct link_map *map) \
+{ \
+ register Elf32_Addr dp asm ("%r27"); \
+ dp = D_PTR (map, l_info[DT_PLTGOT]); \
+ asm volatile ("" : : "r" (dp)); \
+ return map; \
+} \
+ \
+asm ( \
+" .text\n" \
+" .globl _start\n" \
+" .type _start,@function\n" \
+"_start:\n" \
+ /* The kernel does not give us an initial stack frame. */ \
+" ldo 64(%sp),%sp\n" \
+ /* Save the relevant arguments (yes, those are the correct \
+ registers, the kernel is weird) in their stack slots. */ \
+" stw %r25,-40(%sp)\n" /* argc */ \
+" stw %r24,-44(%sp)\n" /* argv */ \
+ \
+ /* We need the LTP, and we need it now. */ \
+ /* $PIC_pcrel$0 points 8 bytes past the current instruction, \
+ just like a branch reloc. This sequence gets us the runtime \
+ address of _DYNAMIC. */ \
+" bl 0f,%r19\n" \
+" depi 0,31,2,%r19\n" /* clear priviledge bits */ \
+"0: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%r19\n" \
+" ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%r1),%r26\n" \
+ \
+ /* Also get the link time address from the first entry of the GOT. */ \
+" addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%r19\n" \
+" ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%r1),%r20\n" \
+ \
+" sub %r26,%r20,%r20\n" /* Calculate load offset */ \
+ \
+ /* Rummage through the dynamic entries, looking for DT_PLTGOT. */ \
+" ldw,ma 8(%r26),%r19\n" \
+"1: cmpib,=,n 3,%r19,2f\n" /* tag == DT_PLTGOT? */ \
+" cmpib,<>,n 0,%r19,1b\n" \
+" ldw,ma 8(%r26),%r19\n" \
+ \
+ /* Uh oh! We didn't find one. Abort. */ \
+" iitlbp %r0,(%r0)\n" \
+ \
+"2: ldw -4(%r26),%r19\n" /* Found it, load value. */ \
+" add %r19,%r20,%r19\n" /* And add the load offset. */ \
+ \
+ /* Our initial stack layout is rather different from everyone \
+ else's due to the unique PA-RISC ABI. As far as I know it \
+ looks like this: \
+ \
+ ----------------------------------- (this frame created above) \
+ | 32 bytes of magic | \
+ |---------------------------------| \
+ | 32 bytes argument/sp save area | \
+ |---------------------------------| ((current->mm->env_end) + 63 & ~63) \
+ | N bytes of slack | \
+ |---------------------------------| \
+ | envvar and arg strings | \
+ |---------------------------------| \
+ | ELF auxiliary info | \
+ | (up to 28 words) | \
+ |---------------------------------| \
+ | Environment variable pointers | \
+ | upwards to NULL | \
+ |---------------------------------| \
+ | Argument pointers | \
+ | upwards to NULL | \
+ |---------------------------------| \
+ | argc (1 word) | \
+ ----------------------------------- \
+ \
+ So, obviously, we can't just pass %sp to _dl_start. That's \
+ okay, argv-4 will do just fine. \
+ \
+ The pleasant part of this is that if we need to skip \
+ arguments we can just decrement argc and move argv, because \
+ the stack pointer is utterly unrelated to the location of \
+ the environment and argument vectors. */ \
+ \
+ /* This is always within range so we'll be okay. */ \
+" bl _dl_start,%rp\n" \
+" ldo -4(%r24),%r26\n" \
+ \
+" .globl _dl_start_user\n" \
+" .type _dl_start_user,@function\n" \
+"_dl_start_user:\n" \
+ /* Save the entry point in %r3. */ \
+" copy %ret0,%r3\n" \
+ \
+ /* Remember the lowest stack address. */ \
+" addil LT'__libc_stack_end,%r19\n" \
+" ldw RT'__libc_stack_end(%r1),%r20\n" \
+" stw %sp,0(%r20)\n" \
+ \
+ /* See if we were called as a command with the executable file \
+ name as an extra leading argument. */ \
+" addil LT'_dl_skip_args,%r19\n" \
+" ldw RT'_dl_skip_args(%r1),%r20\n" \
+" ldw 0(%r20),%r20\n" \
+ \
+" ldw -40(%sp),%r25\n" /* argc */ \
+" comib,= 0,%r20,.Lnofix\n" /* FIXME: will be mispredicted */ \
+" ldw -44(%sp),%r24\n" /* argv (delay slot) */ \
+ \
+" sub %r25,%r20,%r25\n" \
+" stw %r25,-40(%sp)\n" \
+" sh2add %r20,%r24,%r24\n" \
+" stw %r24,-44(%sp)\n" \
+ \
+".Lnofix:\n" \
+" addil LT'_dl_loaded,%r19\n" \
+" ldw RT'_dl_loaded(%r1),%r26\n" \
+" bl set_dp, %r2\n" \
+" ldw 0(%r26),%r26\n" \
+ \
+ /* Call _dl_init(_dl_loaded, argc, argv, envp). */ \
+" copy %r28,%r26\n" \
+ \
+ /* envp = argv + argc + 1 */ \
+" sh2add %r25,%r24,%r23\n" \
+" bl _dl_init,%r2\n" \
+" ldo 4(%r23),%r23\n" /* delay slot */ \
+ \
+ /* Reload argc, argv to the registers start.S expects them in (feh) */ \
+" ldw -40(%sp),%r25\n" \
+" ldw -44(%sp),%r24\n" \
+ \
+ /* _dl_fini does have a PLT slot now. I don't know how to get \
+ to it though, so this hack will remain. */ \
+" .section .data\n" \
+"__dl_fini_plabel:\n" \
+" .word _dl_fini\n" \
+" .word 0xdeadbeef\n" \
+" .previous\n" \
+ \
+ /* %r3 contains a function pointer, we need to mask out the lower \
+ * bits and load the gp and jump address. */ \
+" depi 0,31,2,%r3\n" \
+" ldw 0(%r3),%r2\n" \
+" addil LT'__dl_fini_plabel,%r19\n" \
+" ldw RT'__dl_fini_plabel(%r1),%r23\n" \
+" stw %r19,4(%r23)\n" \
+" ldw 4(%r3),%r19\n" /* load the object's gp */ \
+" bv %r0(%r2)\n" \
+" depi 2,31,2,%r23\n" /* delay slot */ \
+ );
/* This code gets called via the .plt stub, and is used in
diff --git a/sysdeps/unix/sysv/linux/hppa/getrlimit.c b/sysdeps/unix/sysv/linux/hppa/getrlimit.c
deleted file mode 100644
index fc06dbd..0000000
--- a/sysdeps/unix/sysv/linux/hppa/getrlimit.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/unix/sysv/linux/i386/getrlimit.c>
diff --git a/sysdeps/unix/sysv/linux/hppa/setrlimit.c b/sysdeps/unix/sysv/linux/hppa/setrlimit.c
deleted file mode 100644
index bfaef74..0000000
--- a/sysdeps/unix/sysv/linux/hppa/setrlimit.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/unix/sysv/linux/i386/setrlimit.c>
diff --git a/sysdeps/unix/sysv/linux/hppa/syscall.S b/sysdeps/unix/sysv/linux/hppa/syscall.S
index 413c572..96b5b92 100644
--- a/sysdeps/unix/sysv/linux/hppa/syscall.S
+++ b/sysdeps/unix/sysv/linux/hppa/syscall.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1998, 2001 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
@@ -16,13 +16,4 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <sysdep.h>
-
-/* Please consult the file sysdeps/unix/sysv/linux/i386/sysdep.h for
- more information about the value -4095 used below.*/
-
- .text
-ENTRY (syscall)
- b .
- nop
-
+/* HPPA implements syscall() in 'C'; see sysdep.c. */
diff --git a/sysdeps/unix/sysv/linux/hppa/syscalls.list b/sysdeps/unix/sysv/linux/hppa/syscalls.list
index 6d7cd6a..ed9f1a3 100644
--- a/sysdeps/unix/sysv/linux/hppa/syscalls.list
+++ b/sysdeps/unix/sysv/linux/hppa/syscalls.list
@@ -35,3 +35,5 @@ socketpair - socketpair i:iiif __socketpair socketpair
getresuid - getresuid i:ppp getresuid
getresgid - getresgid i:ppp getresgid
+setrlimit - setrlimit i:ip __setrlimit setrlimit
+getrlimit - getrlimit i:ip __getrlimit getrlimit
diff --git a/sysdeps/unix/sysv/linux/hppa/sysdep.c b/sysdeps/unix/sysv/linux/hppa/sysdep.c
index 0559cc7..e185da5 100644
--- a/sysdeps/unix/sysv/linux/hppa/sysdep.c
+++ b/sysdeps/unix/sysv/linux/hppa/sysdep.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2001 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
@@ -32,3 +32,28 @@ __syscall_error (int err_no)
#undef errno
int errno = 0;
weak_alias (errno, _errno)
+
+
+/* HPPA implements syscall() in 'C'; the assembler version would
+ typically be in syscall.S. */
+
+int
+syscall (int sysnum, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5)
+{
+ long __sys_res;
+ {
+ register unsigned long __res asm("r28");
+ LOAD_ARGS_6(arg0, arg1, arg2, arg3, arg4, arg5)
+ asm volatile ("ble 0x100(%%sr2, %%r0)\n\t"
+ "copy %1, %%r20"
+ : "=r" (__res)
+ : "r" (sysnum) ASM_ARGS_6);
+ __sys_res = __res;
+ }
+ if ((unsigned long) __sys_res >= (unsigned long)-4095)
+ {
+ __set_errno(-__sys_res);
+ __sys_res = -1;
+ }
+ return __sys_res;
+}