2006-09-07 Carlos O'Donell <carlos@systemhalted.org>
authorCarlos O'Donell <carlos@systemhalted.org>
Thu, 7 Sep 2006 16:34:43 +0000 (16:34 +0000)
committerCarlos O'Donell <carlos@systemhalted.org>
Thu, 7 Sep 2006 16:34:43 +0000 (16:34 +0000)
* 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.

12 files changed:
ChangeLog.hppa
sysdeps/hppa/dl-machine.h
sysdeps/hppa/dl-trampoline.S
sysdeps/unix/sysv/linux/hppa/bits/atomic.h
sysdeps/unix/sysv/linux/hppa/bits/mman.h
sysdeps/unix/sysv/linux/hppa/clone.S
sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h
sysdeps/unix/sysv/linux/hppa/nptl/pt-vfork.S
sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h
sysdeps/unix/sysv/linux/hppa/nptl/unwind-forcedunwind.c
sysdeps/unix/sysv/linux/hppa/nptl/unwind-resume.c
sysdeps/unix/sysv/linux/hppa/sysdep.h

index 1f90c8d..b0ccb98 100644 (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,
index dd5a281..67536c3 100644 (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;
 }
 
index c476138..e0d3b9b 100644 (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.
    
    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, %r       /* 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, %r       /* 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
-
-       /* 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
+       /* Load up the returned function descriptor */
+       copy    %r28, %r22
+       copy    %r29, %r19
+
+       /* 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
 
-
-
index 36a5407..ee381dc 100644 (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.  */
index 54531ec..f065322 100644 (file)
 # 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
 
 #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.  */
 #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
-
-
index 1884518..2319895 100644 (file)
 #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:
        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
+
+.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
 
-thread_start:
+.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)
 
index a5412bf..3b2b0f1 100644 (file)
 #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
 #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)
index a44e785..83a70b7 100644 (file)
 
        /* 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)
index 748fe69..2d3de3e 100644 (file)
 # 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 */
index c8142cb..8666bbb 100644 (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
    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);
+}
index 6d1da85..a7485e9 100644 (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
    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);
+}
index b302d37..5b12bc5 100644 (file)
 
 #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    \
        /* 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))