mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 13:30:06 +00:00
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:
parent
34cb4e8082
commit
0daa050021
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,13 +34,15 @@
|
||||
|
||||
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
|
||||
@ -50,27 +52,28 @@ _dl_runtime_resolve:
|
||||
|
||||
/* 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)
|
||||
|
||||
/* 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
|
||||
|
||||
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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 */
|
||||
|
||||
/* 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
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user