2006-09-07 Carlos O'Donell <carlos@systemhalted.org>

* sysdeps/hppa/dl-machine.h (elf_machine_fixup_plt): Remove
	lvalue cast.
	* sysdeps/hppa/dl-trampoline.S (_dl_fixup): Correct stack usage.
	(_dl_runtime_profile): LA fixups.
	* sysdeps/unix/sysv/linux/hppa/clone.S: Correct stack usage. Return
	-1 on error. Use branch and link for error handler funciton.
	* sysdeps/unix/sysv/linux/hppa/sysdep.h: Correct stack usage.
	Avoid register shuffling.
	* sysdeps/unix/sysv/linux/hppa/bits/atomic.h (ASM_EAGAIN): Define
	as -EAGAIN.
	* sysdeps/unix/sysv/linux/hppa/bits/mman.h: Adjust definitions to
	match required standards.
	* sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h
	(lll_futex_wait): Return __ret.
	(lll_futex_timed_wait): Likewise.
	(lll_futex_wake): Likewise.
	(lll_futex_requeue): Likewise.
	* sysdeps/unix/sysv/linux/hppa/nptl/pt-vfork.S: Correct stack
	usage and adjust error return.
	* sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h: Adjust
	stack usage for gdb, and avoid extra register loads.
	* sysdeps/unix/sysv/linux/hppa/nptl/unwind-forcedunwind.c: Copy
	nptl/sysdeps/pthread/unwind-forcedunwind.c.
	(LIBGCC_SO): Define and use.
	* sysdeps/unix/sysv/linux/hppa/nptl/unwind-resume.c: Copy
	nptl/sysdeps/pthread/unwind-resume.c.
	(LIBGCC_SO): Define and use.
This commit is contained in:
Carlos O'Donell 2006-09-07 16:34:43 +00:00
parent 34cb4e8082
commit 0daa050021
12 changed files with 498 additions and 235 deletions

View File

@ -1,3 +1,33 @@
2006-09-07 Carlos O'Donell <carlos@systemhalted.org>
* sysdeps/hppa/dl-machine.h (elf_machine_fixup_plt): Remove
lvalue cast.
* sysdeps/hppa/dl-trampoline.S (_dl_fixup): Correct stack usage.
(_dl_runtime_profile): LA fixups.
* sysdeps/unix/sysv/linux/hppa/clone.S: Correct stack usage. Return
-1 on error. Use branch and link for error handler funciton.
* sysdeps/unix/sysv/linux/hppa/sysdep.h: Correct stack usage.
Avoid register shuffling.
* sysdeps/unix/sysv/linux/hppa/bits/atomic.h (ASM_EAGAIN): Define
as -EAGAIN.
* sysdeps/unix/sysv/linux/hppa/bits/mman.h: Adjust definitions to
match required standards.
* sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h
(lll_futex_wait): Return __ret.
(lll_futex_timed_wait): Likewise.
(lll_futex_wake): Likewise.
(lll_futex_requeue): Likewise.
* sysdeps/unix/sysv/linux/hppa/nptl/pt-vfork.S: Correct stack
usage and adjust error return.
* sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h: Adjust
stack usage for gdb, and avoid extra register loads.
* sysdeps/unix/sysv/linux/hppa/nptl/unwind-forcedunwind.c: Copy
nptl/sysdeps/pthread/unwind-forcedunwind.c.
(LIBGCC_SO): Define and use.
* sysdeps/unix/sysv/linux/hppa/nptl/unwind-resume.c: Copy
nptl/sysdeps/pthread/unwind-resume.c.
(LIBGCC_SO): Define and use.
2006-08-13 Carlos O'Donell <carlos@systemhalted.org>
* sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h (FUTEX_LOCK_PI,

View File

@ -123,12 +123,13 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
const Elf32_Rela *reloc,
Elf32_Addr *reloc_addr, struct fdesc value)
{
volatile Elf32_Addr *rfdesc = reloc_addr;
/* map is the link_map for the caller, t is the link_map for the object
being called */
reloc_addr[1] = value.gp;
rfdesc[1] = value.gp;
/* Need to ensure that the gp is visible before the code
entry point is updated */
((volatile Elf32_Addr *) reloc_addr)[0] = value.ip;
rfdesc[0] = value.ip;
return value;
}

View File

@ -1,5 +1,5 @@
/* PLT trampolines. hppa version.
Copyright (C) 2005 Free Software Foundation, Inc.
Copyright (C) 2005, 2006 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
@ -21,9 +21,9 @@
/* This code gets called via the .plt stub, and is used in
dl-runtime.c to call the `_dl_fixup' function and then redirect
to the address it returns. `_dl_fixup' takes two
arguments, however `_dl_profile_fixup' takes a number of
parameters for use with library auditing (LA).
to the address it returns. `_dl_fixup' takes two arguments, however
`_dl_profile_fixup' takes a number of parameters for use with
library auditing (LA).
WARNING: This template is also used by gcc's __cffc, and expects
that the "bl" for _dl_runtime_resolve exist at a particular offset.
@ -34,43 +34,46 @@
Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp. */
/* FAKE bl to provide gcc's __cffc with fixup loc. */
/* RELOCATION MARKER: bl to provide gcc's __cffc with fixup loc. */
.text
/* THIS CODE DOES NOT EXECUTE */
bl _dl_fixup, %r2
.text
.align 4
.global _dl_runtime_resolve
.type _dl_runtime_resolve,@function
cfi_startproc
.align 4
_dl_runtime_resolve:
.PROC
.CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=3
.ENTRY
/* SAVE_RP says we do */
stw %rp, -20(%sp)
stw %rp, -20(%sp)
/* Save static link register */
stw %r29,-16(%sp)
/* Save argument registers in the call stack frame. */
/* Save argument registers */
stw %r26,-36(%sp)
stw %r25,-40(%sp)
stw %r24,-44(%sp)
stw %r23,-48(%sp)
/* Build a call frame, and save structure pointer. */
copy %sp, %r26 /* Copy previous sp */
copy %sp, %r1 /* Copy previous sp */
/* Save function result address (on entry) */
stwm %r28,128(%sp)
/* Save floating point argument registers */
ldo -56(%sp),%r26
fstd,ma %fr4,-8(%r26)
fstd,ma %fr5,-8(%r26)
fstd,ma %fr6,-8(%r26)
fstd %fr7,0(%r26)
/* Fillin some frame info to follow ABI */
stw %r1,-4(%sp) /* Previous sp */
stw %r21,-32(%sp) /* PIC register value */
stw %r26,-4(%sp) /* Previous sp */
/* Save input floating point registers. This must be done
in the new frame since the previous frame doesn't have
enough space */
ldo -56(%sp),%r1
fstd,ma %fr4,-8(%r1)
fstd,ma %fr5,-8(%r1)
fstd,ma %fr6,-8(%r1)
fstd,ma %fr7,-8(%r1)
/* Set up args to fixup func, needs only two arguments */
ldw 8+4(%r20),%r26 /* (1) got[1] == struct link_map */
@ -81,15 +84,15 @@ _dl_runtime_resolve:
copy %r21,%r19 /* set fixup func ltp */
/* Load up the returned func descriptor */
copy %ret0, %r22
copy %ret1, %r19
copy %r28, %r22
copy %r29, %r19
/* Reload arguments fp args */
ldo -80(%sp),%r26
fldd,ma 8(%r26),%fr7
fldd,ma 8(%r26),%fr6
fldd,ma 8(%r26),%fr5
fldd 0(%r26),%fr4
ldo -56(%sp),%r1
fldd,ma -8(%r1),%fr4
fldd,ma -8(%r1),%fr5
fldd,ma -8(%r1),%fr6
fldd,ma -8(%r1),%fr7
/* Adjust sp, and restore function result address*/
ldwm -128(%sp),%r28
@ -107,91 +110,179 @@ _dl_runtime_resolve:
ldw -20(%sp),%rp
.EXIT
.PROCEND
cfi_endproc
.size _dl_runtime_resolve, . - _dl_runtime_resolve
/* FIXME:
Need to largely rewrite the bottom half of
this code in order to save and restore the
LA struct from the stack along with
interpreted parameters.
*/
.text
.align 4
.global _dl_runtime_profile
.type _dl_runtime_profile,@function
cfi_startproc
.align 4
_dl_runtime_profile:
.PROC
.CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=3
.CALLINFO FRAME=192,CALLS,SAVE_RP,ENTRY_GR=3
.ENTRY
/* SAVE_RP says we do */
stw %rp, -20(%sp)
stw %rp, -20(%sp)
/* Save static link register */
stw %r29,-16(%sp)
/* Save argument registers in the call stack frame. */
stw %r26,-36(%sp)
stw %r25,-40(%sp)
stw %r24,-44(%sp)
stw %r23,-48(%sp)
/* Build a call frame, and save structure pointer. */
copy %sp, %r26 /* Copy previous sp */
copy %sp, %r1 /* Copy previous sp */
/* Save function result address (on entry) */
stwm %r28,128(%sp)
/* Save floating point argument registers */
ldo -56(%sp),%r26
fstd,ma %fr4,-8(%r26)
fstd,ma %fr5,-8(%r26)
fstd,ma %fr6,-8(%r26)
fstd %fr7,0(%r26)
stwm %r28,192(%sp)
/* Fillin some frame info to follow ABI */
stw %r1,-4(%sp) /* Previous sp */
stw %r21,-32(%sp) /* PIC register value */
stw %r26,-4(%sp) /* Previous sp */
/* Create La_hppa_retval */
/* -140, lrv_r28
-136, lrv_r29
-132, 4 byte pad
-128, lr_fr4 (8 bytes) */
/* Create save space for _dl_profile_fixup arguments
-120, Saved reloc offset
-116, Saved struct link_map
-112, *framesizep */
/* Create La_hppa_regs */
/* 32-bit registers */
stw %r26,-108(%sp)
stw %r25,-104(%sp)
stw %r24,-100(%sp)
stw %r23,-96(%sp)
/* -92, 4 byte pad */
/* 64-bit floating point registers */
ldo -88(%sp),%r1
fstd,ma %fr4,8(%r1)
fstd,ma %fr5,8(%r1)
fstd,ma %fr6,8(%r1)
fstd,ma %fr7,8(%r1)
/* 32-bit stack pointer and return register */
stw %sp,-56(%sp)
stw %r2,-52(%sp)
/* Set up args to fixup func, needs five arguments */
ldw 8+4(%r20),%r26 /* (1) got[1] == struct link_map */
stw %r26,-116(%sp) /* Save struct link_map */
copy %r19,%r25 /* (2) reloc offset */
stw %r25,-120(%sp) /* Save reloc offset */
copy %rp,%r24 /* (3) profile_fixup needs rp */
copy %r0,%r23 /* (4) regs */
ldo -56(%sp), %r1
ldo -56(%sp),%r23 /* (4) La_hppa_regs */
ldo -112(%sp), %r1
stw %r1, -52(%sp) /* (5) long int *framesizep */
/* Call the real address resolver. */
bl _dl_profile_fixup,%rp
copy %r21,%r19 /* set fixup func ltp */
/* Load up the returned func descriptor */
copy %ret0, %r22
copy %ret1, %r19
/* Load up the returned function descriptor */
copy %r28, %r22
copy %r29, %r19
/* Reload arguments fp args */
ldo -80(%sp),%r26
fldd,ma 8(%r26),%fr7
fldd,ma 8(%r26),%fr6
fldd,ma 8(%r26),%fr5
fldd 0(%r26),%fr4
/* Restore gr/fr/sp/rp */
ldw -108(%sp),%r26
ldw -104(%sp),%r25
ldw -100(%sp),%r24
ldw -96(%sp),%r23
/* -92, 4 byte pad, skip */
ldo -88(%sp),%r1
fldd,ma 8(%r1),%fr4
fldd,ma 8(%r1),%fr5
fldd,ma 8(%r1),%fr6
fldd,ma 8(%r1),%fr7
ldw -52(%sp),%rp
/* Reload static link register -(192+16) without adjusting stack */
ldw -208(%sp),%r29
/* *framesizep is >= 0 if we have to run pltexit */
ldw -112(%sp),%r28
cmpb,>>=,N %r0,%r28,L(cpe)
/* Adjust sp, and restore function result address*/
ldwm -128(%sp),%r28
/* Reload static link register */
ldw -16(%sp),%r29
/* Reload general args */
ldw -36(%sp),%r26
ldw -40(%sp),%r25
ldw -44(%sp),%r24
ldw -48(%sp),%r23
ldwm -192(%sp),%r28
/* Jump to new function, but return to previous function */
bv %r0(%r22)
ldw -20(%sp),%rp
/* NO RETURN */
L(nf):
/* Call the returned function descriptor */
bv %r0(%r22)
nop
b,n L(cont)
L(cpe):
/* We are going to call the resolved function, but we have a
stack frame in the middle. We use the value of framesize to
guess how much extra frame we need, and how much frame to
copy forward. */
/* Round to nearest multiple of 64 */
addi 63, %r28, %r28
depi 0, 27, 6, %r28
/* Calcualte start of stack copy */
ldo -192(%sp),%r2
/* Increate the stack by *framesizep */
copy %sp, %r1
add %sp, %r28, %sp
/* Save stack pointer */
stw %r1, -4(%sp)
/* Single byte copy of prevous stack onto newly allocated stack */
1: ldb %r28(%r2), %r1
add %r28, %sp, %r26
stb %r1, 0(%r26)
addi,< -1,%r28,%r28
b,n 1b
/* Retore r28 and r27 and r2 already points at -192(%sp) */
ldw 0(%r2),%r28
ldw 84(%r2),%r26
/* Calculate address of L(cont) */
b,l L(nf),%r2
depwi 0,31,2,%r2
L(cont):
/* Undo fake stack */
ldw -4(%sp),%r1
copy %r1, %sp
/* Arguments to _dl_call_pltexit */
ldw -116(%sp), %r26 /* (1) got[1] == struct link_map */
ldw -120(%sp), %r25 /* (2) reloc offsets */
ldo -56(%sp), %r24 /* (3) *La_hppa_regs */
ldo -124(%sp), %r23 /* (4) *La_hppa_retval */
/* Fill *La_hppa_retval */
stw %r28,-140(%sp)
stw %r29,-136(%sp)
ldo -128(%sp), %r1
fstd %fr4,0(%r1)
/* Call _dl_call_pltexit */
bl _dl_call_pltexit,%rp
nop
/* Restore *La_hppa_retval */
ldw -140(%sp), %r28
ldw -136(%sp), %r29
ldo -128(%sp), %r1
fldd 0(%r1), %fr4
/* Unwind the stack */
ldo 192(%sp),%sp
/* Retore callers rp */
ldw -20(%sp),%rp
/* Return */
bv,n 0(%r2)
.EXIT
.PROCEND
.size _dl_runtime_profile, . - _dl_runtime_profile

View File

@ -60,7 +60,7 @@ typedef uintmax_t uatomic_max_t;
#define LWS_CAS 0x0
/* Note r31 is the link register */
#define LWS_CLOBBER "r1", "r26", "r25", "r24", "r23", "r22", "r21", "r20", "r28", "r31", "memory"
#define ASM_EAGAIN "11"
#define ASM_EAGAIN -EAGAIN
#if __ASSUME_LWS_CAS
/* The only basic operation needed is compare and exchange. */

View File

@ -21,12 +21,12 @@
# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
#endif
/* these are basically taken from the kernel definitions */
/* These are taken from the kernel definitions. */
#define PROT_READ 0x1 /* page can be read */
#define PROT_WRITE 0x2 /* page can be written */
#define PROT_EXEC 0x4 /* page can be executed */
#define PROT_NONE 0x0 /* page can not be accessed */
#define PROT_READ 0x1 /* Page can be read */
#define PROT_WRITE 0x2 /* Page can be written */
#define PROT_EXEC 0x4 /* Page can be executed */
#define PROT_NONE 0x0 /* Page can not be accessed */
#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
growsdown vma (mprotect only). */
#define PROT_GROWSUP 0x02000000 /* Extend change to start of
@ -34,33 +34,53 @@
#define MAP_SHARED 0x01 /* Share changes */
#define MAP_PRIVATE 0x02 /* Changes are private */
#define MAP_TYPE 0x03 /* Mask for type of mapping */
#ifdef __USE_MISC
# define MAP_TYPE 0x03 /* Mask for type of mapping */
#endif
/* Other flags. */
#define MAP_FIXED 0x04 /* Interpret addr exactly */
#define MAP_ANONYMOUS 0x10 /* don't use a file */
#ifdef __USE_MISC
# define MAP_FILE 0x0
# define MAP_ANONYMOUS 0x10 /* Don't use a file */
# define MAP_ANON MAP_ANONYMOUS
# define MAP_VARIABLE 0
#endif
#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
#define MAP_LOCKED 0x2000 /* pages are locked */
#define MAP_NORESERVE 0x4000 /* don't check for reservations */
#define MAP_GROWSDOWN 0x8000 /* stack-like segment */
#define MAP_POPULATE 0x10000 /* populate (prefault) pagetables */
#define MAP_NONBLOCK 0x20000 /* do not block on IO */
/* These are Linux-specific. */
#ifdef __USE_MISC
# define MAP_DENYWRITE 0x0800 /* ETXTBSY */
# define MAP_EXECUTABLE 0x1000 /* Mark it as an executable */
# define MAP_LOCKED 0x2000 /* Pages are locked */
# define MAP_NORESERVE 0x4000 /* Don't check for reservations */
# define MAP_GROWSDOWN 0x8000 /* Stack-like segment */
# define MAP_POPULATE 0x10000 /* Populate (prefault) pagetables */
# define MAP_NONBLOCK 0x20000 /* Do not block on IO */
#endif
#define MS_SYNC 1 /* synchronous memory sync */
#define MS_ASYNC 2 /* sync memory asynchronously */
#define MS_INVALIDATE 4 /* invalidate the caches */
/* Flags to "msync" */
#define MS_SYNC 1 /* Synchronous memory sync */
#define MS_ASYNC 2 /* Sync memory asynchronously */
#define MS_INVALIDATE 4 /* Invalidate the caches */
#define MCL_CURRENT 1 /* lock all current mappings */
#define MCL_FUTURE 2 /* lock all future mappings */
/* Flags to "mlockall" */
#define MCL_CURRENT 1 /* Lock all current mappings */
#define MCL_FUTURE 2 /* Lock all future mappings */
/* Advice to "madvise" */
/* Flags for `mremap'. */
#ifdef __USE_GNU
# define MREMAP_MAYMOVE 1
# define MREMAP_FIXED 2
#endif
/* Advice to "madvise" */
#ifdef __USE_BSD
# define MADV_NORMAL 0 /* no further special treatment */
# define MADV_RANDOM 1 /* expect random page references */
# define MADV_SEQUENTIAL 2 /* expect sequential page references */
# define MADV_WILLNEED 3 /* will need these pages */
# define MADV_DONTNEED 4 /* dont need these pages */
# define MADV_SPACEAVAIL 5 /* insure that resources are reserved */
# define MADV_NORMAL 0 /* No further special treatment */
# define MADV_RANDOM 1 /* Expect random page references */
# define MADV_SEQUENTIAL 2 /* Expect sequential page references */
# define MADV_WILLNEED 3 /* Will need these pages */
# define MADV_DONTNEED 4 /* Dont need these pages */
# define MADV_SPACEAVAIL 5 /* Insure that resources are reserved */
# define MADV_VPS_PURGE 6 /* Purge pages from VM page cache */
# define MADV_VPS_INHERIT 7 /* Inherit parents page size */
# define MADV_REMOVE 9 /* Remove these pages and resources. */
@ -78,15 +98,11 @@
#define MADV_16M_PAGES 24 /* Use 16 Megabyte pages */
#define MADV_64M_PAGES 26 /* Use 64 Megabyte pages */
/* compatibility flags */
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FILE 0
#define MAP_VARIABLE 0
/* Flags for `mremap'. */
#ifdef __USE_GNU
# define MREMAP_MAYMOVE 1
# define MREMAP_FIXED 2
/* The POSIX people had to invent similar names for the same things. */
#ifdef __USE_XOPEN2K
# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
#endif

View File

@ -27,11 +27,19 @@
#include <bits/errno.h>
/* Non-thread code calls __clone with the following parameters:
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)
NPTL Code will call __clone with the following parameters:
int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
int *parent_tidptr, struct user_desc *newtls, int *child_pidptr)
int clone(int (*fn)(void *arg),
void *child_stack,
int flags,
void *arg,
int *parent_tidptr,
struct user_desc *newtls,
int *child_pidptr)
The code should not mangle the extra input registers.
Syscall expects: Input to __clone:
@ -43,32 +51,37 @@
r23 - struct user_desc newtls pointer. (stack - 56)
r22 - child tid pointer. (stack - 60)
r20 - clone syscall number (constant)
Return:
On success the thread ID of the child process is returend in
the callers context.
On error return -1, and set errno to the value returned by
the syscall.
*/
.text
ENTRY(__clone)
/* Prologue */
stwm %r3, 64(%sp)
stw %sp, -4(%sp)
stw %r19, -32(%sp)
/* Sanity check arguments. */
ldi -EINVAL,%ret0
comib,=,n 0,%arg0,.Lerror /* no NULL function pointers */
comib,=,n 0,%arg1,.Lerror /* no NULL stack pointers */
comib,=,n 0, %arg0, .LerrorSanity /* no NULL function pointers */
comib,=,n 0, %arg1, .LerrorSanity /* no NULL stack pointers */
/* Save the fn ptr and arg on the new stack. */
stwm %r26,64(%r25)
stw %r23,-60(%r25)
stwm %r26, 64(%r25)
stw %r23, -60(%r25)
/* Clone arguments are (int flags, void * child_stack) */
copy %r24,%r26 /* flags are first */
copy %r24, %r26 /* flags are first */
/* User stack pointer is in the correct register already */
/* Load args from stack... */
ldw -52(%sp), %r24 /* Load parent_tidptr */
ldw -56(%sp), %r23 /* Load newtls */
ldw -60(%sp), %r22 /* Load child_tidptr */
/* Create frame to get r3 free */
copy %sp, %r21
stwm %r3, 64(%sp)
stw %r21, -4(%sp)
ldw -116(%sp), %r24 /* Load parent_tidptr */
ldw -120(%sp), %r23 /* Load newtls */
ldw -124(%sp), %r22 /* Load child_tidptr */
/* Save the PIC register. */
#ifdef PIC
@ -76,19 +89,20 @@ ENTRY(__clone)
#endif
/* Do the system call */
ble 0x100(%sr2,%r0)
ldi __NR_clone,%r20
ble 0x100(%sr2, %r0)
ldi __NR_clone, %r20
ldi -4096,%r1
comclr,>>= %r1,%ret0,%r0 /* Note: unsigned compare. */
ldi -4096, %r1
comclr,>>= %r1, %ret0, %r0 /* Note: unsigned compare. */
b,n .LerrorRest
comib,=,n 0,%ret0,thread_start
comib,=,n 0, %ret0, .LthreadStart
/* Successful return from the parent
No need to restore the PIC register,
since we return immediately. */
ldw -84(%sp), %rp
bv %r0(%rp)
ldwm -64(%sp), %r3
@ -97,36 +111,40 @@ ENTRY(__clone)
#ifdef PIC
copy %r3, %r19 /* parent */
#endif
/* Something bad happened -- no child created */
.Lerror:
/* Set errno, save ret0 so we return with that value. */
copy %ret0, %r3
b __syscall_error
sub %r0,%ret0,%arg0
copy %r3, %ret0
/* Return after setting errno, and restoring ret0 */
bl __syscall_error, %rp
sub %r0, %ret0, %arg0
ldw -84(%sp), %rp
/* Return after setting errno, ret0 is set to -1 by __syscall_error. */
bv %r0(%rp)
ldwm -64(%sp), %r3
thread_start:
.LerrorSanity:
/* Sanity checks failed, return -1, and set errno to EINVAL. */
bl __syscall_error, %rp
ldi EINVAL, %arg0
/* Lazy, don't restore r19 */
ldw -84(%sp), %rp
bv %r0(%rp)
ldwm -64(%sp), %r3
.LthreadStart:
/* Load up the arguments. */
ldw -60(%sr0, %sp),%arg0
ldw -64(%sr0, %sp),%r22
ldw -60(%sp), %arg0
ldw -64(%sp), %r22
/* $$dyncall fixes childs PIC register */
/* Call the user's function */
bl $$dyncall,%r31
copy %r31,%rp
bl $$dyncall, %r31
copy %r31, %rp
bl _exit,%rp
copy %ret0,%arg0
bl _exit, %rp
copy %ret0, %arg0
/* Die horribly. */
iitlbp %r0,(%sr0,%r0)
/* We should not return from _exit. */
iitlbp %r0, (%sr0, %r0)
PSEUDO_END(__clone)

View File

@ -25,34 +25,10 @@
#include <sysdep.h>
#include <atomic.h>
#if 0
/* The hppa only has one atomic read and modify memory operation,
load and clear, so hppa spinlocks must use zero to signify that
someone is holding the lock. The address used for the ldcw
semaphore must be 16-byte aligned. */
#define __ldcw(a) \
({ \
unsigned int __ret; \
__asm__ __volatile__("ldcw 0(%1),%0" \
: "=r" (__ret) : "r" (a) : "memory"); \
__ret; \
})
/* Because malloc only guarantees 8-byte alignment for malloc'd data,
and GCC only guarantees 8-byte alignment for stack locals, we can't
be assured of 16-byte alignment for atomic lock data even if we
specify "__attribute ((aligned(16)))" in the type declaration. So,
we use a struct containing an array of four ints for the atomic lock
type and dynamically select the 16-byte aligned int from the array
for the semaphore. */
#define __PA_LDCW_ALIGNMENT 16
#define __ldcw_align(a) ({ \
volatile unsigned int __ret = (unsigned int) a; \
if ((__ret & ~(__PA_LDCW_ALIGNMENT - 1)) < (unsigned int) a) \
__ret = (__ret & ~(__PA_LDCW_ALIGNMENT - 1)) + __PA_LDCW_ALIGNMENT; \
(unsigned int *) __ret; \
})
#endif
load and clear, so hppa uses a kernel helper routine to implement
compare_and_exchange. See atomic.h for the userspace calling
sequence. */
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
@ -64,11 +40,7 @@
#define FUTEX_UNLOCK_PI 7
#define FUTEX_TRYLOCK_PI 8
/* Initializer for compatibility lock. */
#if 0
#define LLL_INITIALIZER_NOT_ZERO
#define LLL_MUTEX_LOCK_INITIALIZER ((__atomic_lock_t){ { 1, 1, 1, 1 } })
#endif
/* Initialize locks to zero. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
@ -82,7 +54,7 @@ typedef int lll_lock_t;
long int __ret; \
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), FUTEX_WAIT, (val), 0); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
__ret; \
})
#define lll_futex_timed_wait(futexp, val, timespec) \
@ -91,7 +63,7 @@ typedef int lll_lock_t;
long int __ret; \
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), FUTEX_WAIT, (val), (timespec)); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
__ret; \
})
#define lll_futex_wake(futexp, nr) \
@ -100,7 +72,7 @@ typedef int lll_lock_t;
long int __ret; \
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), FUTEX_WAKE, (nr), 0); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
__ret; \
})
#define lll_robust_mutex_dead(futexv) \
@ -120,7 +92,7 @@ typedef int lll_lock_t;
__ret = INTERNAL_SYSCALL (futex, __err, 6, \
(futexp), FUTEX_CMP_REQUEUE, (nr_wake), \
(nr_move), (mutex), (val)); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
__ret; \
})
/* Returns non-zero if error happened, zero if success. */
@ -253,25 +225,12 @@ __lll_mutex_unlock_force (lll_lock_t *futex)
}
#define lll_mutex_unlock_force(futex) __lll_mutex_unlock_force(&(futex))
static inline int __attribute__ ((always_inline))
__lll_mutex_islocked (lll_lock_t *futex)
{
return (*futex != 0);
}
#define lll_mutex_islocked(futex) __lll_mutex_islocked(&(futex))
#define lll_mutex_islocked(futex) \
(futex != 0)
/* Our internal lock implementation is identical to the binary-compatible
mutex implementation. */
/* Initializers for lock. */
#if 0
#define LLL_LOCK_INITIALIZER ((__atomic_lock_t){ { 1, 1, 1, 1 } })
#define LLL_LOCK_INITIALIZER_CONST { { 1, 1, 1, 1 } }
#define LLL_LOCK_INITIALIZER_LOCKED ((__atomic_lock_t){ { 0, 0, 0, 0 } })
#endif
#define LLL_LOCK_INITIALIZER (0)
#define LLL_LOCK_INITIALIZER_CONST (0)
#define LLL_LOCK_INITIALIZER_LOCKED (1)

View File

@ -50,6 +50,10 @@
/* r26, r25, r24, r23 are free since vfork has no arguments */
ENTRY(__vfork)
/* Prologue */
stwm %r3, 64(%sp)
stw %sp, -4(%sp)
stw %r19, -32(%sp)
/* Save the PIC register. */
#ifdef PIC
@ -72,9 +76,12 @@ ENTRY(__vfork)
b,n .Lerror
/* Return, no need to restore the PIC register. */
bv,n %r0(%rp)
ldw -84(%sp), %rp
bv %r0(%rp)
ldwm -64(%sp), %r3
.Lerror:
sub %r0,%ret0,%r3
SYSCALL_ERROR_HANDLER
/* Restore the PIC register (in delay slot) on error */
#ifdef PIC
@ -82,8 +89,11 @@ ENTRY(__vfork)
#else
nop
#endif
sub %r0,%ret0,%arg0
/* Return error */
/* Write syscall return into errno location */
stw %r3, 0(%ret0)
ldw -84(%sp), %rp
bv %r0(%rp)
ldwm -64(%sp), %r3
PSEUDO_END (__vfork)
libc_hidden_def (__vfork)
weak_alias (__vfork, vfork)

View File

@ -63,11 +63,9 @@
# define PSEUDO(name, syscall_name, args) \
ENTRY (name) \
DOARGS_##args ASM_LINE_SEP \
copy TREG, %r1 ASM_LINE_SEP \
copy %sp, TREG ASM_LINE_SEP \
stwm %r1, 64(%sp) ASM_LINE_SEP \
stw %rp, -20(%sp) ASM_LINE_SEP \
stw TREG, -4(%sp) ASM_LINE_SEP \
stwm TREG, 64(%sp) ASM_LINE_SEP \
stw %sp, -4(%sp) ASM_LINE_SEP \
stw %r19, -32(%sp) ASM_LINE_SEP \
/* Done setting up frame, continue... */ ASM_LINE_SEP \
SINGLE_THREAD_P ASM_LINE_SEP \
cmpib,<>,n 0,%ret0,L(pseudo_cancel) ASM_LINE_SEP \
@ -91,7 +89,7 @@ L(unthreaded): ASM_LINE_SEP \
stw TREG, 0(%sr0,%ret0) ASM_LINE_SEP \
b L(pre_end) ASM_LINE_SEP \
/* return -1 as error */ ASM_LINE_SEP \
ldo -1(%r0), %ret0 /* delay */ ASM_LINE_SEP \
ldi -1, %ret0 /* delay */ ASM_LINE_SEP \
L(pseudo_cancel): ASM_LINE_SEP \
PUSHARGS_##args /* Save args */ ASM_LINE_SEP \
/* Save r19 into TREG */ ASM_LINE_SEP \
@ -125,13 +123,13 @@ L(pseudo_cancel): ASM_LINE_SEP \
/* store into errno location */ ASM_LINE_SEP \
stw TREG, 0(%sr0,%ret0) ASM_LINE_SEP \
/* return -1 */ ASM_LINE_SEP \
ldo -1(%r0), %ret0 ASM_LINE_SEP \
ldi -1, %ret0 ASM_LINE_SEP \
L(pre_end): ASM_LINE_SEP \
/* Restore rp before exit */ ASM_LINE_SEP \
ldw -84(%sr0,%sp), %rp ASM_LINE_SEP \
/* No need to LOAD_PIC */ ASM_LINE_SEP \
/* Undo frame */ ASM_LINE_SEP \
ldwm -64(%sp),TREG ASM_LINE_SEP \
/* No need to LOAD_PIC */ ASM_LINE_SEP
/* Restore rp before exit */ ASM_LINE_SEP \
ldw -20(%sp), %rp ASM_LINE_SEP
/* Save arguments into our frame */
# define PUSHARGS_0 /* nothing to do */

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2005 Free Software Foundation, Inc.
/* Copyright (C) 2005, 2006 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,6 +16,100 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define LIBGCC_S_SO "libgcc_s.so.2"
#include <sysdeps/pthread/unwind-forcedunwind.c>
#include <dlfcn.h>
#include <stdio.h>
#include <unwind.h>
#include <pthreadP.h>
#define LIBGCC_S_SO "libgcc_s.so.4"
static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
static _Unwind_Reason_Code (*libgcc_s_personality)
(int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
struct _Unwind_Context *);
static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
(struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *);
#ifndef LIBGCC_S_SO
#define LIBGCC_S_SO "libgcc_s.so.1"
#endif
void
__attribute_noinline__
pthread_cancel_init (void)
{
void *resume, *personality, *forcedunwind, *getcfa;
void *handle;
if (__builtin_expect (libgcc_s_getcfa != NULL, 1))
{
/* Force gcc to reload all values. */
asm volatile ("" ::: "memory");
return;
}
handle = __libc_dlopen (LIBGCC_S_SO);
if (handle == NULL
|| (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
|| (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL
|| (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind"))
== NULL
|| (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL
#ifdef ARCH_CANCEL_INIT
|| ARCH_CANCEL_INIT (handle)
#endif
)
__libc_fatal ("libgcc_s.so must be installed for pthread_cancel to work\n");
libgcc_s_resume = resume;
libgcc_s_personality = personality;
libgcc_s_forcedunwind = forcedunwind;
/* Make sure libgcc_s_getcfa is written last. Otherwise,
pthread_cancel_init might return early even when the pointer the
caller is interested in is not initialized yet. */
atomic_write_barrier ();
libgcc_s_getcfa = getcfa;
}
void
_Unwind_Resume (struct _Unwind_Exception *exc)
{
if (__builtin_expect (libgcc_s_resume == NULL, 0))
pthread_cancel_init ();
libgcc_s_resume (exc);
}
_Unwind_Reason_Code
__gcc_personality_v0 (int version, _Unwind_Action actions,
_Unwind_Exception_Class exception_class,
struct _Unwind_Exception *ue_header,
struct _Unwind_Context *context)
{
if (__builtin_expect (libgcc_s_personality == NULL, 0))
pthread_cancel_init ();
return libgcc_s_personality (version, actions, exception_class,
ue_header, context);
}
_Unwind_Reason_Code
_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
void *stop_argument)
{
if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0))
pthread_cancel_init ();
return libgcc_s_forcedunwind (exc, stop, stop_argument);
}
_Unwind_Word
_Unwind_GetCFA (struct _Unwind_Context *context)
{
if (__builtin_expect (libgcc_s_getcfa == NULL, 0))
pthread_cancel_init ();
return libgcc_s_getcfa (context);
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2005 Free Software Foundation, Inc.
/* Copyright (C) 2005, 2006 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,6 +16,55 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define LIBGCC_S_SO "libgcc_s.so.2"
#include <sysdeps/pthread/unwind-resume.c>
#include <dlfcn.h>
#include <stdio.h>
#include <unwind.h>
#define LIBGCC_S_SO "libgcc_s.so.4"
static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
static _Unwind_Reason_Code (*libgcc_s_personality)
(int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
struct _Unwind_Context *);
#ifndef LIBGCC_S_SO
#error LIBGCC_S_SO
#define LIBGCC_S_SO "libgcc_s.so.1"
#endif
static void
init (void)
{
void *resume, *personality;
void *handle;
handle = __libc_dlopen (LIBGCC_S_SO);
if (handle == NULL
|| (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
|| (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL)
__libc_fatal ("libgcc_s.so must be installed for pthread_cancel to work\n");
libgcc_s_resume = resume;
libgcc_s_personality = personality;
}
void
_Unwind_Resume (struct _Unwind_Exception *exc)
{
if (__builtin_expect (libgcc_s_resume == NULL, 0))
init ();
libgcc_s_resume (exc);
}
_Unwind_Reason_Code
__gcc_personality_v0 (int version, _Unwind_Action actions,
_Unwind_Exception_Class exception_class,
struct _Unwind_Exception *ue_header,
struct _Unwind_Context *context)
{
if (__builtin_expect (libgcc_s_personality == NULL, 0))
init ();
return libgcc_s_personality (version, actions, exception_class,
ue_header, context);
}

View File

@ -278,12 +278,10 @@
#undef DO_CALL
#define DO_CALL(syscall_name, args) \
copy TREG,%r1 ASM_LINE_SEP \
copy %sp,TREG ASM_LINE_SEP \
/* Create a frame */ ASM_LINE_SEP \
stwm %r1, 64(%sp) ASM_LINE_SEP \
stw %rp, -20(%sp) ASM_LINE_SEP \
stw TREG, -4(%sp) ASM_LINE_SEP \
stwm TREG, 64(%sp) ASM_LINE_SEP \
stw %sp, -4(%sp) ASM_LINE_SEP \
stw %r19, -32(%sp) ASM_LINE_SEP \
/* Save r19 */ ASM_LINE_SEP \
SAVE_PIC(TREG) ASM_LINE_SEP \
/* Do syscall, delay loads # */ ASM_LINE_SEP \
@ -304,10 +302,10 @@
/* return -1 as error */ ASM_LINE_SEP \
ldo -1(%r0), %ret0 ASM_LINE_SEP \
L(pre_end): ASM_LINE_SEP \
/* Restore return pointer */ ASM_LINE_SEP \
ldw -84(%sp),%rp ASM_LINE_SEP \
/* Restore our frame, restoring TREG */ ASM_LINE_SEP \
ldwm -64(%sp), TREG ASM_LINE_SEP
ldwm -64(%sp), TREG ASM_LINE_SEP \
/* Restore return pointer */ ASM_LINE_SEP \
ldw -20(%sp),%rp ASM_LINE_SEP
/* We do nothing with the return, except hand it back to someone else */
#undef DO_CALL_NOERRNO
@ -386,10 +384,9 @@ L(pre_end): ASM_LINE_SEP \
#undef INTERNAL_SYSCALL_DECL
#define INTERNAL_SYSCALL_DECL(err)
/* Equivalent to (val < 0)&&(val > -4095) which is what we want */
#undef INTERNAL_SYSCALL_ERROR_P
#define INTERNAL_SYSCALL_ERROR_P(val, err) \
((unsigned long)val >= (unsigned long)-4095)
((val < 0) && (val > -4095))
#undef INTERNAL_SYSCALL_ERRNO
#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))