public inbox for libc-ports@sourceware.org
 help / color / mirror / Atom feed
* [ARM] getcontext routines v2
@ 2012-02-24  1:34 Michael Hope
  2012-02-24 15:39 ` Carlos O'Donell
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Hope @ 2012-02-24  1:34 UTC (permalink / raw)
  To: libc-ports

This is an implementation of getcontext, makecontext, setcontext and swapcontext for ARM Linux and continues on from Dave Gilbert's original version[1].

The changes in this version are:
  * Use the GNU coding style
  * Use ucontext_i.sym to pull constants and struct offsets into the assembly code
  * Match the style of the MIPS and Tile implementations

These routines survive basic testing.  A full GLIBC, QEMU, and GNU pth test run is under way.

-- Michael

[1] http://sourceware.org/ml/libc-ports/2011-12/msg00047.html

diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile
index d91b968..a981736 100644
--- a/sysdeps/unix/sysv/linux/arm/Makefile
+++ b/sysdeps/unix/sysv/linux/arm/Makefile
@@ -20,3 +20,7 @@ endif
  ifeq ($(subdir),resource)
  sysdep_routines += oldgetrlimit64
  endif
+
+ifeq ($(subdir),stdlib)
+gen-as-const-headers += ucontext_i.sym
+endif
diff --git a/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S
new file mode 100644
index 0000000..11a49e3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S
@@ -0,0 +1,114 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+
+#include "ucontext_i.h"
+
+    .syntax unified
+    .text
+
+/* int getcontext (ucontext_t *ucp) */
+
+ENTRY(__getcontext)
+    /* No need to save r0-r3, d0-d7, or d16-d31.  */
+    add    r1, r0, #MCONTEXT_ARM_R4
+    stmia   r1, {r4-r11}
+
+    /* Save R13 separately as Thumb can't STM it.  */
+    str     r13, [r0, #MCONTEXT_ARM_SP]
+    str     r14, [r0, #MCONTEXT_ARM_LR]
+    /* Return to LR */
+    str     r14, [r0, #MCONTEXT_ARM_PC]
+    /* Return zero */
+    mov     r2, #0
+    str     r2, [r0, #MCONTEXT_ARM_R0]
+
+    /* Save ucontext_t * across the next call.  */
+    mov    r4, r0
+
+    /* __sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */
+    mov     r0, #SIG_BLOCK
+    mov     r1, #0
+    add     r2, r4, #UCONTEXT_SIGMASK
+    bl      PLTJMP(__sigprocmask)
+
+    /* Store FP regs.  Much of the FP code is copied from arm/eabi/setjmp.S.  */
+
+#ifdef PIC
+        ldr     r2, 1f
+        ldr     r1, Lrtld_global_ro
+0:      add     r2, pc, r2
+        ldr     r2, [r2, r1]
+        ldr     r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
+#else
+        ldr     r2, Lhwcap
+        ldr     r2, [r2, #0]
+#endif
+
+    add    r0, r4, #UCONTEXT_REGSPACE
+
+        tst     r2, #HWCAP_ARM_VFP
+        beq     Lno_vfp
+
+        /* Store the VFP registers.
+           Don't use VFP instructions directly because this code
+           is used in non-VFP multilibs.  */
+        /* Following instruction is vstmia r0!, {d8-d15}.  */
+        stc     p11, cr8, [r0], #64
+        /* Store the floating-point status register.  */
+        /* Following instruction is vmrs r1, fpscr.  */
+        mrc     p10, 7, r1, cr1, cr0, 0
+        str     r1, [r0], #4
+Lno_vfp:
+
+        tst     r2, #HWCAP_ARM_IWMMXT
+        beq     Lno_iwmmxt
+
+        /* Save the call-preserved iWMMXt registers.  */
+        /* Following instructions are wstrd wr10, [r0], #8 (etc.)  */
+        stcl    p1, cr10, [r0], #8
+        stcl    p1, cr11, [r0], #8
+        stcl    p1, cr12, [r0], #8
+        stcl    p1, cr13, [r0], #8
+        stcl    p1, cr14, [r0], #8
+        stcl    p1, cr15, [r0], #8
+Lno_iwmmxt:
+
+    /* Restore the clobbered R4 and LR.  */
+    ldr    r14, [r4, #MCONTEXT_ARM_LR]
+    ldr    r4, [r4, #MCONTEXT_ARM_R4]
+
+    mov    r0, #0
+
+    DO_RET(r14)
+
+END(__getcontext)
+
+#ifdef PIC
+1:      .long   _GLOBAL_OFFSET_TABLE_ - 0b - 8
+Lrtld_global_ro:
+        .long   C_SYMBOL_NAME(_rtld_global_ro)(GOT)
+#else
+Lhwcap:
+        .long   C_SYMBOL_NAME(_dl_hwcap)
+#endif
+
+
+weak_alias(__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c b/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c
new file mode 100644
index 0000000..a4c8233
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c
@@ -0,0 +1,75 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdarg.h>
+#include <ucontext.h>
+
+extern void __setcontext_orexit_r4 (void);
+
+/* Number of arguments that go in registers.  */
+#define NREG_ARGS  4
+
+/* Take a context previously prepared via getcontext() and set to
+   call func() with the given int only args.  */
+void
+makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+  unsigned long *funcstack;
+  va_list vl;
+  unsigned long *regptr;
+  unsigned int reg;
+  int misaligned;
+
+  /* Start at the top of stack.  */
+  funcstack = (unsigned long *) (ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
+
+  /* Ensure the stack stays eight byte aligned.  */
+  misaligned = ((unsigned long) funcstack & 4) != 0;
+
+  if ((argc > NREG_ARGS) && (argc & 1) != 0)
+    misaligned = !misaligned;
+
+  if (misaligned)
+    funcstack -= 1;
+
+  va_start (vl, argc);
+
+  /* Reserve space for the on-stack arguments.  */
+  if (argc > NREG_ARGS)
+    funcstack -= (argc - NREG_ARGS);
+
+  /* R4 of the context points to the link context, and ends up being passed
+     to __setcontext_orexit_r4 where it ends up either calling setcontext or
+     if 0 ends up as the conveniently correct param to exit().  */
+  ucp->uc_mcontext.arm_r4 = (unsigned long) ucp->uc_link;
+  ucp->uc_mcontext.arm_sp = (unsigned long) funcstack;
+  ucp->uc_mcontext.arm_lr = (unsigned long) __setcontext_orexit_r4;
+  ucp->uc_mcontext.arm_pc = (unsigned long) func;
+
+  /* The first four arguments go into registers.  */
+  regptr = &(ucp->uc_mcontext.arm_r0);
+
+  for (reg = 0; (reg < argc) && (reg < NREG_ARGS); reg++)
+    *regptr++ = va_arg (vl, unsigned long);
+
+  /* And the remainder on the stack.  */
+  for (; reg < argc; reg++)
+    *funcstack++ = va_arg (vl, unsigned long);
+
+  va_end (vl);
+}
diff --git a/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S
new file mode 100644
index 0000000..6add16a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S
@@ -0,0 +1,103 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+
+#include "ucontext_i.h"
+
+    .syntax unified
+    .text
+
+/* int setcontext (const ucontext_t *ucp) */
+
+ENTRY(__setcontext)
+    mov    r4, r0
+    add    r0, r0, #UCONTEXT_REGSPACE
+
+        /* Restore the VFP registers.  Copied from arm/eabi/__longjmp.S.  */
+#ifdef PIC
+        ldr     r2, 1f
+        ldr     r1, Lrtld_global_ro
+0:      add     r2, pc, r2
+        ldr     r2, [r2, r1]
+        ldr     r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
+#else
+        ldr     r2, Lhwcap
+        ldr     r2, [r2, #0]
+#endif
+
+        tst     r2, #HWCAP_ARM_VFP
+        beq     Lno_vfp_sc
+
+        /* Following instruction is vldmia r0!, {d8-d15}.  */
+        ldc     p11, cr8, [r0], #64
+        /* Restore the floating-point status register.  */
+        ldr     r1, [r0], #4
+        /* Following instruction is fmxr fpscr, r1.  */
+        mcr     p10, 7, r1, cr1, cr0, 0
+Lno_vfp_sc:
+        tst     r2, #HWCAP_ARM_IWMMXT
+        beq     Lno_iwmmxt_sc
+
+        /* Restore the call-preserved iWMMXt registers.  */
+        /* Following instructions are wldrd wr10, [r0], #8 (etc.)  */
+        ldcl    p1, cr10, [r0], #8
+        ldcl    p1, cr11, [r0], #8
+        ldcl    p1, cr12, [r0], #8
+        ldcl    p1, cr13, [r0], #8
+        ldcl    p1, cr14, [r0], #8
+        ldcl    p1, cr15, [r0], #8
+Lno_iwmmxt_sc:
+
+    /* Now bring back the signal status.  */
+    mov    r0, #SIG_SETMASK
+    add    r1, r4, #UCONTEXT_SIGMASK
+    mov    r2, #0
+    bl    PLTJMP(__sigprocmask)
+
+        /* Loading r0-r3 makes makecontext easier.  */
+        add     r14, r4, #MCONTEXT_ARM_R0
+        ldmia   r14, {r0-r12}
+        ldr     r13, [r14, #(MCONTEXT_ARM_SP - MCONTEXT_ARM_R0)]
+        add     r14, r14, #(MCONTEXT_ARM_LR - MCONTEXT_ARM_R0)
+        ldmia   r14, {r14, pc}
+
+END(setcontext)
+
+        /* The function called via a setcontext on a context that makecontext
+           tweeked returns here (by it's LR), R4 should hold the context we're
+           supposed to run next, if 0 we exit.  */
+ENTRY(__setcontext_orexit_r4)
+        movs    r0, r4
+        bne     PLTJMP(__setcontext)
+
+        @ New context was 0 - exit
+        b       PLTJMP(_exit)
+END(__setcontext_orexit_r4)
+
+#ifdef PIC
+1:      .long   _GLOBAL_OFFSET_TABLE_ - 0b - 8
+Lrtld_global_ro:
+        .long   C_SYMBOL_NAME(_rtld_global_ro)(GOT)
+#else
+Lhwcap:
+        .long   C_SYMBOL_NAME(_dl_hwcap)
+#endif
+
+weak_alias(__setcontext, setcontext)
diff --git a/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S
new file mode 100644
index 0000000..efb881a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S
@@ -0,0 +1,64 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+    .syntax unified
+    .text
+
+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
+
+ENTRY(swapcontext)
+
+    /* Have getcontext() do most of the work then fix up
+       LR afterwards.  Save R3 to keep the stack aligned.  */
+    push    {r0,r1,r3,r14}
+    cfi_adjust_cfa_offset (16)
+    cfi_rel_offset (r0,0)
+    cfi_rel_offset (r1,4)
+    cfi_rel_offset (r3,8)
+    cfi_rel_offset (r14,12)
+
+    bl    __getcontext
+    mov    r4, r0
+
+    pop    {r0,r1,r3,r14}
+    cfi_adjust_cfa_offset (-16)
+    cfi_restore (r0)
+    cfi_restore (r1)
+    cfi_restore (r3)
+    cfi_restore (r14)
+
+    /* Exit if getcontext() failed.  */
+    cmp     r4, #0
+    itt    ne
+    movne    r0, r4
+    RETINSTR(ne, r14)
+
+    /* Fix up LR and the PC.  */
+    str    r13,[r0, #MCONTEXT_ARM_SP]
+    str    r14,[r0, #MCONTEXT_ARM_LR]
+    str    r14,[r0, #MCONTEXT_ARM_PC]
+
+    /* And swap using swapcontext().  */
+    mov    r0, r1
+    b    __setcontext
+
+END(swapcontext)
diff --git a/sysdeps/unix/sysv/linux/arm/ucontext_i.sym b/sysdeps/unix/sysv/linux/arm/ucontext_i.sym
new file mode 100644
index 0000000..306292f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/ucontext_i.sym
@@ -0,0 +1,30 @@
+#include <inttypes.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/ucontext.h>
+
+SIG_BLOCK
+SIG_SETMASK
+
+-- Offsets of the fields in the ucontext_t structure.
+#define ucontext(member)    offsetof (ucontext_t, member)
+#define mcontext(member)    ucontext (uc_mcontext.member)
+
+UCONTEXT_FLAGS            ucontext (uc_flags)
+UCONTEXT_LINK            ucontext (uc_link)
+UCONTEXT_STACK            ucontext (uc_stack)
+UCONTEXT_MCONTEXT        ucontext (uc_mcontext)
+UCONTEXT_SIGMASK        ucontext (uc_sigmask)
+
+UCONTEXT_REGSPACE        ucontext (uc_regspace)
+
+MCONTEXT_TRAP_NO        mcontext (trap_no)
+MCONTEXT_ERROR_CODE        mcontext (error_code)
+MCONTEXT_OLDMASK        mcontext (oldmask)
+MCONTEXT_ARM_R0            mcontext (arm_r0)
+MCONTEXT_ARM_R4            mcontext (arm_r4)
+MCONTEXT_ARM_SP            mcontext (arm_sp)
+MCONTEXT_ARM_LR            mcontext (arm_lr)
+MCONTEXT_ARM_PC            mcontext (arm_pc)
+MCONTEXT_ARM_CPSR        mcontext (arm_cpsr)
+MCONTEXT_FAULT_ADDRESS        mcontext (fault_address)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [ARM] getcontext routines v2
  2012-02-24  1:34 [ARM] getcontext routines v2 Michael Hope
@ 2012-02-24 15:39 ` Carlos O'Donell
  2012-02-27 22:03   ` Michael Hope
  0 siblings, 1 reply; 9+ messages in thread
From: Carlos O'Donell @ 2012-02-24 15:39 UTC (permalink / raw)
  To: Michael Hope; +Cc: libc-ports

On Thu, Feb 23, 2012 at 8:34 PM, Michael Hope <michael.hope@linaro.org> wrote:
> This is an implementation of getcontext, makecontext, setcontext and
> swapcontext for ARM Linux and continues on from Dave Gilbert's original
> version[1].
>
> The changes in this version are:
>  * Use the GNU coding style
>  * Use ucontext_i.sym to pull constants and struct offsets into the assembly
> code
>  * Match the style of the MIPS and Tile implementations
>
> These routines survive basic testing.  A full GLIBC, QEMU, and GNU pth test
> run is under way.

I looked over things briefly and the formatting and license looks OK.
Do you and Dave have FSF copyright assignments in place?

I also have two comments.

(1) Is setcontext correctly implemented?

Your setcontext doesn't iterate over uc_link, instead you appear to rely
on makecontext having set a special return handler and input arguments.

The special return handler won't be set of the user manually sets uc_link
in the context, which I believe is an allowed operation (only uc_mcontext
is forbidden to be modified).

I'd be interested in seeing if you pass all of the glibc tests.

(2) Please also post a GNU ChangeLog with your patches.

Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [ARM] getcontext routines v2
  2012-02-24 15:39 ` Carlos O'Donell
@ 2012-02-27 22:03   ` Michael Hope
  2012-02-27 23:06     ` Carlos O'Donell
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Hope @ 2012-02-27 22:03 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: libc-ports

On Sat, Feb 25, 2012 at 4:39 AM, Carlos O'Donell <carlos@systemhalted.org> wrote:
> On Thu, Feb 23, 2012 at 8:34 PM, Michael Hope <michael.hope@linaro.org> wrote:
>> This is an implementation of getcontext, makecontext, setcontext and
>> swapcontext for ARM Linux and continues on from Dave Gilbert's original
>> version[1].
>>
>> The changes in this version are:
>>  * Use the GNU coding style
>>  * Use ucontext_i.sym to pull constants and struct offsets into the assembly
>> code
>>  * Match the style of the MIPS and Tile implementations
>>
>> These routines survive basic testing.  A full GLIBC, QEMU, and GNU pth test
>> run is under way.
>
> I looked over things briefly and the formatting and license looks OK.
> Do you and Dave have FSF copyright assignments in place?

Yes.  Linaro has an assignment agreement for GCC, GDB, binutils, and GLIBC under case #664398.

> I also have two comments.
>
> (1) Is setcontext correctly implemented?
>
> Your setcontext doesn't iterate over uc_link, instead you appear to rely
> on makecontext having set a special return handler and input arguments.
>
> The special return handler won't be set of the user manually sets uc_link
> in the context, which I believe is an allowed operation (only uc_mcontext
> is forbidden to be modified).

It's correct to the specification and matches the MIPS and Tile ports.  From IEEE 1003.1:2004:

"""The uc_link member is used to determine the context that shall be resumed when the context being modified by makecontext() returns. The application shall ensure that the uc_link member is initialized prior to the call to makecontext()."""

There's no mention of uc_link being used except when the makecontext() child completes.

I've changed the function to __startcontext() to match the other ports and added a weak_alias on __makecontext for consistency.

> I'd be interested in seeing if you pass all of the glibc tests.

There are no regressions between EGLIBC trunk and trunk + this patch.  stdlib/bug-getcontext now passes.  The (small) GNU pth testsuite passes.

> (2) Please also post a GNU ChangeLog with your patches.

Done.

-- Michael

diff --git a/ChangeLog.arm b/ChangeLog.arm
index 9eef7e7..7ecb11b 100644
--- a/ChangeLog.arm
+++ b/ChangeLog.arm
@@ -1,3 +1,13 @@
+2012-02-27  Michael Hope  <michael.hope@linaro.org>
+
+	* sysdeps/unix/sysv/linux/arm/eabi/getcontext.S: New file.
+	* sysdeps/unix/sysv/linux/arm/eabi/makecontext.c: New file.
+	* sysdeps/unix/sysv/linux/arm/eabi/setcontext.S: New file.
+	* sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S: New file.
+	* sysdeps/unix/sysv/linux/arm/ucontext_i.sym: New file.
+	* sysdeps/unix/sysv/linux/arm/Makefile (gen-as-const-headers): Add
+	ucontext_i.sym.
+
  2012-02-17  Aurelien Jarno  <aurelien@aurel32.net>

  	* sysdeps/arm/libm-test-ulps: Adjust ULPs for jn tests.
diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile
index d91b968..a981736 100644
--- a/sysdeps/unix/sysv/linux/arm/Makefile
+++ b/sysdeps/unix/sysv/linux/arm/Makefile
@@ -20,3 +20,7 @@ endif
  ifeq ($(subdir),resource)
  sysdep_routines += oldgetrlimit64
  endif
+
+ifeq ($(subdir),stdlib)
+gen-as-const-headers += ucontext_i.sym
+endif
diff --git a/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S
new file mode 100644
index 0000000..11a49e3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S
@@ -0,0 +1,114 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+
+#include "ucontext_i.h"
+
+	.syntax unified
+	.text
+
+/* int getcontext (ucontext_t *ucp) */
+
+ENTRY(__getcontext)
+	/* No need to save r0-r3, d0-d7, or d16-d31.  */
+	add	r1, r0, #MCONTEXT_ARM_R4
+	stmia   r1, {r4-r11}
+
+	/* Save R13 separately as Thumb can't STM it.  */
+	str     r13, [r0, #MCONTEXT_ARM_SP]
+	str     r14, [r0, #MCONTEXT_ARM_LR]
+	/* Return to LR */
+	str     r14, [r0, #MCONTEXT_ARM_PC]
+	/* Return zero */
+	mov     r2, #0
+	str     r2, [r0, #MCONTEXT_ARM_R0]
+
+	/* Save ucontext_t * across the next call.  */
+	mov	r4, r0
+	
+	/* __sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */
+	mov     r0, #SIG_BLOCK
+	mov     r1, #0
+	add     r2, r4, #UCONTEXT_SIGMASK
+	bl      PLTJMP(__sigprocmask)
+	
+	/* Store FP regs.  Much of the FP code is copied from arm/eabi/setjmp.S.  */
+
+#ifdef PIC
+        ldr     r2, 1f
+        ldr     r1, Lrtld_global_ro
+0:      add     r2, pc, r2
+        ldr     r2, [r2, r1]
+        ldr     r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
+#else
+        ldr     r2, Lhwcap
+        ldr     r2, [r2, #0]
+#endif
+
+	add	r0, r4, #UCONTEXT_REGSPACE
+
+        tst     r2, #HWCAP_ARM_VFP
+        beq     Lno_vfp
+
+        /* Store the VFP registers.
+           Don't use VFP instructions directly because this code
+           is used in non-VFP multilibs.  */
+        /* Following instruction is vstmia r0!, {d8-d15}.  */
+        stc     p11, cr8, [r0], #64
+        /* Store the floating-point status register.  */
+        /* Following instruction is vmrs r1, fpscr.  */
+        mrc     p10, 7, r1, cr1, cr0, 0
+        str     r1, [r0], #4
+Lno_vfp:
+
+        tst     r2, #HWCAP_ARM_IWMMXT
+        beq     Lno_iwmmxt
+
+        /* Save the call-preserved iWMMXt registers.  */
+        /* Following instructions are wstrd wr10, [r0], #8 (etc.)  */
+        stcl    p1, cr10, [r0], #8
+        stcl    p1, cr11, [r0], #8
+        stcl    p1, cr12, [r0], #8
+        stcl    p1, cr13, [r0], #8
+        stcl    p1, cr14, [r0], #8
+        stcl    p1, cr15, [r0], #8
+Lno_iwmmxt:
+
+	/* Restore the clobbered R4 and LR.  */
+	ldr	r14, [r4, #MCONTEXT_ARM_LR]
+	ldr	r4, [r4, #MCONTEXT_ARM_R4]
+
+	mov	r0, #0
+
+	DO_RET(r14)
+
+END(__getcontext)
+
+#ifdef PIC
+1:      .long   _GLOBAL_OFFSET_TABLE_ - 0b - 8
+Lrtld_global_ro:
+        .long   C_SYMBOL_NAME(_rtld_global_ro)(GOT)
+#else
+Lhwcap:
+        .long   C_SYMBOL_NAME(_dl_hwcap)
+#endif
+
+
+weak_alias(__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c b/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c
new file mode 100644
index 0000000..66f8456
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c
@@ -0,0 +1,74 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdarg.h>
+#include <ucontext.h>
+
+/* Number of arguments that go in registers.  */
+#define NREG_ARGS  4
+
+/* Take a context previously prepared via getcontext() and set to
+   call func() with the given int only args.  */
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+  extern void __startcontext (void);
+  unsigned long *funcstack;
+  va_list vl;
+  unsigned long *regptr;
+  unsigned int reg;
+  int misaligned;
+
+  /* Start at the top of stack.  */
+  funcstack = (unsigned long *) (ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
+
+  /* Ensure the stack stays eight byte aligned.  */
+  misaligned = ((unsigned long) funcstack & 4) != 0;
+
+  if ((argc > NREG_ARGS) && (argc & 1) != 0)
+    misaligned = !misaligned;
+
+  if (misaligned)
+    funcstack -= 1;
+
+  va_start (vl, argc);
+
+  /* Reserve space for the on-stack arguments.  */
+  if (argc > NREG_ARGS)
+    funcstack -= (argc - NREG_ARGS);
+
+  ucp->uc_mcontext.arm_sp = (unsigned long) funcstack;
+  ucp->uc_mcontext.arm_pc = (unsigned long) func;
+
+  /* Exit to startcontext() with the next context in R4 */
+  ucp->uc_mcontext.arm_r4 = (unsigned long) ucp->uc_link;
+  ucp->uc_mcontext.arm_lr = (unsigned long) __startcontext;
+
+  /* The first four arguments go into registers.  */
+  regptr = &(ucp->uc_mcontext.arm_r0);
+
+  for (reg = 0; (reg < argc) && (reg < NREG_ARGS); reg++)
+    *regptr++ = va_arg (vl, unsigned long);
+
+  /* And the remainder on the stack.  */
+  for (; reg < argc; reg++)
+    *funcstack++ = va_arg (vl, unsigned long);
+
+  va_end (vl);
+}
+weak_alias (__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S
new file mode 100644
index 0000000..f07af7f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S
@@ -0,0 +1,102 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+
+#include "ucontext_i.h"
+
+	.syntax unified
+	.text
+
+/* int setcontext (const ucontext_t *ucp) */
+
+ENTRY(__setcontext)
+	mov	r4, r0
+	add	r0, r0, #UCONTEXT_REGSPACE
+
+        /* Restore the VFP registers.  Copied from arm/eabi/__longjmp.S.  */
+#ifdef PIC
+        ldr     r2, 1f
+        ldr     r1, Lrtld_global_ro
+0:      add     r2, pc, r2
+        ldr     r2, [r2, r1]
+        ldr     r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
+#else
+        ldr     r2, Lhwcap
+        ldr     r2, [r2, #0]
+#endif
+
+        tst     r2, #HWCAP_ARM_VFP
+        beq     Lno_vfp_sc
+
+        /* Following instruction is vldmia r0!, {d8-d15}.  */
+        ldc     p11, cr8, [r0], #64
+        /* Restore the floating-point status register.  */
+        ldr     r1, [r0], #4
+        /* Following instruction is fmxr fpscr, r1.  */
+        mcr     p10, 7, r1, cr1, cr0, 0
+Lno_vfp_sc:
+        tst     r2, #HWCAP_ARM_IWMMXT
+        beq     Lno_iwmmxt_sc
+
+        /* Restore the call-preserved iWMMXt registers.  */
+        /* Following instructions are wldrd wr10, [r0], #8 (etc.)  */
+        ldcl    p1, cr10, [r0], #8
+        ldcl    p1, cr11, [r0], #8
+        ldcl    p1, cr12, [r0], #8
+        ldcl    p1, cr13, [r0], #8
+        ldcl    p1, cr14, [r0], #8
+        ldcl    p1, cr15, [r0], #8
+Lno_iwmmxt_sc:
+
+	/* Now bring back the signal status.  */
+	mov	r0, #SIG_SETMASK
+	add	r1, r4, #UCONTEXT_SIGMASK
+	mov	r2, #0
+	bl	PLTJMP(__sigprocmask)
+
+        /* Loading r0-r3 makes makecontext easier.  */
+        add     r14, r4, #MCONTEXT_ARM_R0
+        ldmia   r14, {r0-r12}
+        ldr     r13, [r14, #(MCONTEXT_ARM_SP - MCONTEXT_ARM_R0)]
+        add     r14, r14, #(MCONTEXT_ARM_LR - MCONTEXT_ARM_R0)
+        ldmia   r14, {r14, pc}
+
+END(setcontext)
+weak_alias(__setcontext, setcontext)
+
+	/* Called when a makecontext() context returns.  Start the
+	   context in R4 or fall through to exit().  */
+ENTRY(__startcontext)
+        movs    r0, r4
+        bne     PLTJMP(__setcontext)
+
+        @ New context was 0 - exit
+        b       PLTJMP(_exit)
+END(__startcontext)
+
+#ifdef PIC
+1:      .long   _GLOBAL_OFFSET_TABLE_ - 0b - 8
+Lrtld_global_ro:
+        .long   C_SYMBOL_NAME(_rtld_global_ro)(GOT)
+#else
+Lhwcap:
+        .long   C_SYMBOL_NAME(_dl_hwcap)
+#endif
+
diff --git a/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S
new file mode 100644
index 0000000..efb881a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S
@@ -0,0 +1,64 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+	.syntax unified
+	.text
+
+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
+
+ENTRY(swapcontext)
+
+	/* Have getcontext() do most of the work then fix up
+	   LR afterwards.  Save R3 to keep the stack aligned.  */
+	push	{r0,r1,r3,r14}
+	cfi_adjust_cfa_offset (16)
+	cfi_rel_offset (r0,0)
+	cfi_rel_offset (r1,4)
+	cfi_rel_offset (r3,8)
+	cfi_rel_offset (r14,12)
+
+	bl	__getcontext
+	mov	r4, r0
+
+	pop	{r0,r1,r3,r14}
+	cfi_adjust_cfa_offset (-16)
+	cfi_restore (r0)
+	cfi_restore (r1)
+	cfi_restore (r3)
+	cfi_restore (r14)
+
+	/* Exit if getcontext() failed.  */
+	cmp 	r4, #0
+	itt	ne
+	movne	r0, r4
+	RETINSTR(ne, r14)
+	
+	/* Fix up LR and the PC.  */
+	str	r13,[r0, #MCONTEXT_ARM_SP]
+	str	r14,[r0, #MCONTEXT_ARM_LR]
+	str	r14,[r0, #MCONTEXT_ARM_PC]
+
+	/* And swap using swapcontext().  */
+	mov	r0, r1
+	b	__setcontext
+
+END(swapcontext)
diff --git a/sysdeps/unix/sysv/linux/arm/ucontext_i.sym b/sysdeps/unix/sysv/linux/arm/ucontext_i.sym
new file mode 100644
index 0000000..306292f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/ucontext_i.sym
@@ -0,0 +1,30 @@
+#include <inttypes.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/ucontext.h>
+
+SIG_BLOCK
+SIG_SETMASK
+
+-- Offsets of the fields in the ucontext_t structure.
+#define ucontext(member)	offsetof (ucontext_t, member)
+#define mcontext(member)	ucontext (uc_mcontext.member)
+
+UCONTEXT_FLAGS			ucontext (uc_flags)
+UCONTEXT_LINK			ucontext (uc_link)
+UCONTEXT_STACK			ucontext (uc_stack)
+UCONTEXT_MCONTEXT		ucontext (uc_mcontext)
+UCONTEXT_SIGMASK		ucontext (uc_sigmask)
+
+UCONTEXT_REGSPACE		ucontext (uc_regspace)
+
+MCONTEXT_TRAP_NO		mcontext (trap_no)
+MCONTEXT_ERROR_CODE		mcontext (error_code)
+MCONTEXT_OLDMASK		mcontext (oldmask)
+MCONTEXT_ARM_R0			mcontext (arm_r0)
+MCONTEXT_ARM_R4			mcontext (arm_r4)
+MCONTEXT_ARM_SP			mcontext (arm_sp)
+MCONTEXT_ARM_LR			mcontext (arm_lr)
+MCONTEXT_ARM_PC			mcontext (arm_pc)
+MCONTEXT_ARM_CPSR		mcontext (arm_cpsr)
+MCONTEXT_FAULT_ADDRESS		mcontext (fault_address)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [ARM] getcontext routines v2
  2012-02-27 22:03   ` Michael Hope
@ 2012-02-27 23:06     ` Carlos O'Donell
  2012-02-27 23:22       ` Michael Hope
  0 siblings, 1 reply; 9+ messages in thread
From: Carlos O'Donell @ 2012-02-27 23:06 UTC (permalink / raw)
  To: Michael Hope; +Cc: libc-ports

On Mon, Feb 27, 2012 at 5:03 PM, Michael Hope <michael.hope@linaro.org> wrote:
>> I looked over things briefly and the formatting and license looks OK.
>> Do you and Dave have FSF copyright assignments in place?
>
> Yes.  Linaro has an assignment agreement for GCC, GDB, binutils, and GLIBC
> under case #664398.

Excellent. Thanks.

>> (1) Is setcontext correctly implemented?
> It's correct to the specification and matches the MIPS and Tile ports.  From
> IEEE 1003.1:2004:

I've gone and re-read the standard, and I agree with you.

Personally I think there is a QoI issue here, but you meet the
standard which is the right thing to do.

>> I'd be interested in seeing if you pass all of the glibc tests.
> There are no regressions between EGLIBC trunk and trunk + this patch.
>  stdlib/bug-getcontext now passes.  The (small) GNU pth testsuite passes.

Perfect.

>> (2) Please also post a GNU ChangeLog with your patches.
> Done.

Thanks.

> -- Michael
>
> diff --git a/ChangeLog.arm b/ChangeLog.arm
> index 9eef7e7..7ecb11b 100644
> --- a/ChangeLog.arm
> +++ b/ChangeLog.arm
> @@ -1,3 +1,13 @@
> +2012-02-27  Michael Hope  <michael.hope@linaro.org>
> +
> +       * sysdeps/unix/sysv/linux/arm/eabi/getcontext.S: New file.
> +       * sysdeps/unix/sysv/linux/arm/eabi/makecontext.c: New file.
> +       * sysdeps/unix/sysv/linux/arm/eabi/setcontext.S: New file.
> +       * sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S: New file.
> +       * sysdeps/unix/sysv/linux/arm/ucontext_i.sym: New file.
> +       * sysdeps/unix/sysv/linux/arm/Makefile (gen-as-const-headers): Add
> +       ucontext_i.sym.
> +
>  2012-02-17  Aurelien Jarno  <aurelien@aurel32.net>
>
>        * sysdeps/arm/libm-test-ulps: Adjust ULPs for jn tests.
>
> diff --git a/sysdeps/unix/sysv/linux/arm/Makefile
> b/sysdeps/unix/sysv/linux/arm/Makefile
> index d91b968..a981736 100644
> --- a/sysdeps/unix/sysv/linux/arm/Makefile
> +++ b/sysdeps/unix/sysv/linux/arm/Makefile
> @@ -20,3 +20,7 @@ endif
>  ifeq ($(subdir),resource)
>  sysdep_routines += oldgetrlimit64
>  endif
> +
> +ifeq ($(subdir),stdlib)
> +gen-as-const-headers += ucontext_i.sym
> +endif
> diff --git a/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S
> b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S
> new file mode 100644
> index 0000000..11a49e3
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S
> @@ -0,0 +1,114 @@
> +/* Copyright (C) 2012 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, write to the Free
> +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
> +   02111-1307 USA.  */
> +

This should be:
~~~
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */
~~~

We don't use the address form of the license.

Please repost the patch with the license change and I'll check it in.

Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [ARM] getcontext routines v2
  2012-02-27 23:06     ` Carlos O'Donell
@ 2012-02-27 23:22       ` Michael Hope
  2012-03-04 21:17         ` Michael Hope
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Hope @ 2012-02-27 23:22 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: libc-ports

On 28/02/12 12:05, Carlos O'Donell wrote:
> On Mon, Feb 27, 2012 at 5:03 PM, Michael Hope<michael.hope@linaro.org>  wrote:
>>> I looked over things briefly and the formatting and license looks OK.
>>> Do you and Dave have FSF copyright assignments in place?
>>
>> Yes.  Linaro has an assignment agreement for GCC, GDB, binutils, and GLIBC
>> under case #664398.
>
> Excellent. Thanks.
>
>>> (1) Is setcontext correctly implemented?
>> It's correct to the specification and matches the MIPS and Tile ports.  From
>> IEEE 1003.1:2004:
>
> I've gone and re-read the standard, and I agree with you.
>
> Personally I think there is a QoI issue here, but you meet the
> standard which is the right thing to do.

Agreed.  Being able to change uc_link while in a makecontext() child would be nice.

>> +++ b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S
>> @@ -0,0 +1,114 @@
>> +/* Copyright (C) 2012 Free Software Foundation, Inc.
>> +   This file is part of the GNU C Library.
>> +
>> +   The GNU C Library is free software; you can redistribute it and/or
>> +   modify it under the terms of the GNU Lesser General Public
>> +   License as published by the Free Software Foundation; either
>> +   version 2.1 of the License, or (at your option) any later version.
>> +
>> +   The GNU C Library is distributed in the hope that it will be useful,
>> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> +   Lesser General Public License for more details.
>> +
>> +   You should have received a copy of the GNU Lesser General Public
>> +   License along with the GNU C Library; if not, write to the Free
>> +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
>> +   02111-1307 USA.  */
>> +
>
> This should be:
> ~~~
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
> ~~~
>
> We don't use the address form of the license.
>
> Please repost the patch with the license change and I'll check it in.

Updated to match the recent MIPS commits.

-- Michael

diff --git a/ChangeLog.arm b/ChangeLog.arm
index 9eef7e7..7ecb11b 100644
--- a/ChangeLog.arm
+++ b/ChangeLog.arm
@@ -1,3 +1,13 @@
+2012-02-27  Michael Hope  <michael.hope@linaro.org>
+
+	* sysdeps/unix/sysv/linux/arm/eabi/getcontext.S: New file.
+	* sysdeps/unix/sysv/linux/arm/eabi/makecontext.c: New file.
+	* sysdeps/unix/sysv/linux/arm/eabi/setcontext.S: New file.
+	* sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S: New file.
+	* sysdeps/unix/sysv/linux/arm/ucontext_i.sym: New file.
+	* sysdeps/unix/sysv/linux/arm/Makefile (gen-as-const-headers): Add
+	ucontext_i.sym.
+
  2012-02-17  Aurelien Jarno  <aurelien@aurel32.net>

  	* sysdeps/arm/libm-test-ulps: Adjust ULPs for jn tests.
diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile
index d91b968..a981736 100644
--- a/sysdeps/unix/sysv/linux/arm/Makefile
+++ b/sysdeps/unix/sysv/linux/arm/Makefile
@@ -20,3 +20,7 @@ endif
  ifeq ($(subdir),resource)
  sysdep_routines += oldgetrlimit64
  endif
+
+ifeq ($(subdir),stdlib)
+gen-as-const-headers += ucontext_i.sym
+endif
diff --git a/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S
new file mode 100644
index 0000000..4266287
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S
@@ -0,0 +1,113 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+
+#include "ucontext_i.h"
+
+	.syntax unified
+	.text
+
+/* int getcontext (ucontext_t *ucp) */
+
+ENTRY(__getcontext)
+	/* No need to save r0-r3, d0-d7, or d16-d31.  */
+	add	r1, r0, #MCONTEXT_ARM_R4
+	stmia   r1, {r4-r11}
+
+	/* Save R13 separately as Thumb can't STM it.  */
+	str     r13, [r0, #MCONTEXT_ARM_SP]
+	str     r14, [r0, #MCONTEXT_ARM_LR]
+	/* Return to LR */
+	str     r14, [r0, #MCONTEXT_ARM_PC]
+	/* Return zero */
+	mov     r2, #0
+	str     r2, [r0, #MCONTEXT_ARM_R0]
+
+	/* Save ucontext_t * across the next call.  */
+	mov	r4, r0
+	
+	/* __sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */
+	mov     r0, #SIG_BLOCK
+	mov     r1, #0
+	add     r2, r4, #UCONTEXT_SIGMASK
+	bl      PLTJMP(__sigprocmask)
+	
+	/* Store FP regs.  Much of the FP code is copied from arm/eabi/setjmp.S.  */
+
+#ifdef PIC
+        ldr     r2, 1f
+        ldr     r1, Lrtld_global_ro
+0:      add     r2, pc, r2
+        ldr     r2, [r2, r1]
+        ldr     r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
+#else
+        ldr     r2, Lhwcap
+        ldr     r2, [r2, #0]
+#endif
+
+	add	r0, r4, #UCONTEXT_REGSPACE
+
+        tst     r2, #HWCAP_ARM_VFP
+        beq     Lno_vfp
+
+        /* Store the VFP registers.
+           Don't use VFP instructions directly because this code
+           is used in non-VFP multilibs.  */
+        /* Following instruction is vstmia r0!, {d8-d15}.  */
+        stc     p11, cr8, [r0], #64
+        /* Store the floating-point status register.  */
+        /* Following instruction is vmrs r1, fpscr.  */
+        mrc     p10, 7, r1, cr1, cr0, 0
+        str     r1, [r0], #4
+Lno_vfp:
+
+        tst     r2, #HWCAP_ARM_IWMMXT
+        beq     Lno_iwmmxt
+
+        /* Save the call-preserved iWMMXt registers.  */
+        /* Following instructions are wstrd wr10, [r0], #8 (etc.)  */
+        stcl    p1, cr10, [r0], #8
+        stcl    p1, cr11, [r0], #8
+        stcl    p1, cr12, [r0], #8
+        stcl    p1, cr13, [r0], #8
+        stcl    p1, cr14, [r0], #8
+        stcl    p1, cr15, [r0], #8
+Lno_iwmmxt:
+
+	/* Restore the clobbered R4 and LR.  */
+	ldr	r14, [r4, #MCONTEXT_ARM_LR]
+	ldr	r4, [r4, #MCONTEXT_ARM_R4]
+
+	mov	r0, #0
+
+	DO_RET(r14)
+
+END(__getcontext)
+
+#ifdef PIC
+1:      .long   _GLOBAL_OFFSET_TABLE_ - 0b - 8
+Lrtld_global_ro:
+        .long   C_SYMBOL_NAME(_rtld_global_ro)(GOT)
+#else
+Lhwcap:
+        .long   C_SYMBOL_NAME(_dl_hwcap)
+#endif
+
+
+weak_alias(__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c b/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c
new file mode 100644
index 0000000..d6ae6f0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdarg.h>
+#include <ucontext.h>
+
+/* Number of arguments that go in registers.  */
+#define NREG_ARGS  4
+
+/* Take a context previously prepared via getcontext() and set to
+   call func() with the given int only args.  */
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+  extern void __startcontext (void);
+  unsigned long *funcstack;
+  va_list vl;
+  unsigned long *regptr;
+  unsigned int reg;
+  int misaligned;
+
+  /* Start at the top of stack.  */
+  funcstack = (unsigned long *) (ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
+
+  /* Ensure the stack stays eight byte aligned.  */
+  misaligned = ((unsigned long) funcstack & 4) != 0;
+
+  if ((argc > NREG_ARGS) && (argc & 1) != 0)
+    misaligned = !misaligned;
+
+  if (misaligned)
+    funcstack -= 1;
+
+  va_start (vl, argc);
+
+  /* Reserve space for the on-stack arguments.  */
+  if (argc > NREG_ARGS)
+    funcstack -= (argc - NREG_ARGS);
+
+  ucp->uc_mcontext.arm_sp = (unsigned long) funcstack;
+  ucp->uc_mcontext.arm_pc = (unsigned long) func;
+
+  /* Exit to startcontext() with the next context in R4 */
+  ucp->uc_mcontext.arm_r4 = (unsigned long) ucp->uc_link;
+  ucp->uc_mcontext.arm_lr = (unsigned long) __startcontext;
+
+  /* The first four arguments go into registers.  */
+  regptr = &(ucp->uc_mcontext.arm_r0);
+
+  for (reg = 0; (reg < argc) && (reg < NREG_ARGS); reg++)
+    *regptr++ = va_arg (vl, unsigned long);
+
+  /* And the remainder on the stack.  */
+  for (; reg < argc; reg++)
+    *funcstack++ = va_arg (vl, unsigned long);
+
+  va_end (vl);
+}
+weak_alias (__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S
new file mode 100644
index 0000000..78003f5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S
@@ -0,0 +1,101 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+
+#include "ucontext_i.h"
+
+	.syntax unified
+	.text
+
+/* int setcontext (const ucontext_t *ucp) */
+
+ENTRY(__setcontext)
+	mov	r4, r0
+	add	r0, r0, #UCONTEXT_REGSPACE
+
+        /* Restore the VFP registers.  Copied from arm/eabi/__longjmp.S.  */
+#ifdef PIC
+        ldr     r2, 1f
+        ldr     r1, Lrtld_global_ro
+0:      add     r2, pc, r2
+        ldr     r2, [r2, r1]
+        ldr     r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
+#else
+        ldr     r2, Lhwcap
+        ldr     r2, [r2, #0]
+#endif
+
+        tst     r2, #HWCAP_ARM_VFP
+        beq     Lno_vfp_sc
+
+        /* Following instruction is vldmia r0!, {d8-d15}.  */
+        ldc     p11, cr8, [r0], #64
+        /* Restore the floating-point status register.  */
+        ldr     r1, [r0], #4
+        /* Following instruction is fmxr fpscr, r1.  */
+        mcr     p10, 7, r1, cr1, cr0, 0
+Lno_vfp_sc:
+        tst     r2, #HWCAP_ARM_IWMMXT
+        beq     Lno_iwmmxt_sc
+
+        /* Restore the call-preserved iWMMXt registers.  */
+        /* Following instructions are wldrd wr10, [r0], #8 (etc.)  */
+        ldcl    p1, cr10, [r0], #8
+        ldcl    p1, cr11, [r0], #8
+        ldcl    p1, cr12, [r0], #8
+        ldcl    p1, cr13, [r0], #8
+        ldcl    p1, cr14, [r0], #8
+        ldcl    p1, cr15, [r0], #8
+Lno_iwmmxt_sc:
+
+	/* Now bring back the signal status.  */
+	mov	r0, #SIG_SETMASK
+	add	r1, r4, #UCONTEXT_SIGMASK
+	mov	r2, #0
+	bl	PLTJMP(__sigprocmask)
+
+        /* Loading r0-r3 makes makecontext easier.  */
+        add     r14, r4, #MCONTEXT_ARM_R0
+        ldmia   r14, {r0-r12}
+        ldr     r13, [r14, #(MCONTEXT_ARM_SP - MCONTEXT_ARM_R0)]
+        add     r14, r14, #(MCONTEXT_ARM_LR - MCONTEXT_ARM_R0)
+        ldmia   r14, {r14, pc}
+
+END(setcontext)
+weak_alias(__setcontext, setcontext)
+
+	/* Called when a makecontext() context returns.  Start the
+	   context in R4 or fall through to exit().  */
+ENTRY(__startcontext)
+        movs    r0, r4
+        bne     PLTJMP(__setcontext)
+
+        @ New context was 0 - exit
+        b       PLTJMP(_exit)
+END(__startcontext)
+
+#ifdef PIC
+1:      .long   _GLOBAL_OFFSET_TABLE_ - 0b - 8
+Lrtld_global_ro:
+        .long   C_SYMBOL_NAME(_rtld_global_ro)(GOT)
+#else
+Lhwcap:
+        .long   C_SYMBOL_NAME(_dl_hwcap)
+#endif
+
diff --git a/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S
new file mode 100644
index 0000000..09492d0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S
@@ -0,0 +1,63 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+	.syntax unified
+	.text
+
+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
+
+ENTRY(swapcontext)
+
+	/* Have getcontext() do most of the work then fix up
+	   LR afterwards.  Save R3 to keep the stack aligned.  */
+	push	{r0,r1,r3,r14}
+	cfi_adjust_cfa_offset (16)
+	cfi_rel_offset (r0,0)
+	cfi_rel_offset (r1,4)
+	cfi_rel_offset (r3,8)
+	cfi_rel_offset (r14,12)
+
+	bl	__getcontext
+	mov	r4, r0
+
+	pop	{r0,r1,r3,r14}
+	cfi_adjust_cfa_offset (-16)
+	cfi_restore (r0)
+	cfi_restore (r1)
+	cfi_restore (r3)
+	cfi_restore (r14)
+
+	/* Exit if getcontext() failed.  */
+	cmp 	r4, #0
+	itt	ne
+	movne	r0, r4
+	RETINSTR(ne, r14)
+	
+	/* Fix up LR and the PC.  */
+	str	r13,[r0, #MCONTEXT_ARM_SP]
+	str	r14,[r0, #MCONTEXT_ARM_LR]
+	str	r14,[r0, #MCONTEXT_ARM_PC]
+
+	/* And swap using swapcontext().  */
+	mov	r0, r1
+	b	__setcontext
+
+END(swapcontext)
diff --git a/sysdeps/unix/sysv/linux/arm/ucontext_i.sym b/sysdeps/unix/sysv/linux/arm/ucontext_i.sym
new file mode 100644
index 0000000..306292f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/ucontext_i.sym
@@ -0,0 +1,30 @@
+#include <inttypes.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/ucontext.h>
+
+SIG_BLOCK
+SIG_SETMASK
+
+-- Offsets of the fields in the ucontext_t structure.
+#define ucontext(member)	offsetof (ucontext_t, member)
+#define mcontext(member)	ucontext (uc_mcontext.member)
+
+UCONTEXT_FLAGS			ucontext (uc_flags)
+UCONTEXT_LINK			ucontext (uc_link)
+UCONTEXT_STACK			ucontext (uc_stack)
+UCONTEXT_MCONTEXT		ucontext (uc_mcontext)
+UCONTEXT_SIGMASK		ucontext (uc_sigmask)
+
+UCONTEXT_REGSPACE		ucontext (uc_regspace)
+
+MCONTEXT_TRAP_NO		mcontext (trap_no)
+MCONTEXT_ERROR_CODE		mcontext (error_code)
+MCONTEXT_OLDMASK		mcontext (oldmask)
+MCONTEXT_ARM_R0			mcontext (arm_r0)
+MCONTEXT_ARM_R4			mcontext (arm_r4)
+MCONTEXT_ARM_SP			mcontext (arm_sp)
+MCONTEXT_ARM_LR			mcontext (arm_lr)
+MCONTEXT_ARM_PC			mcontext (arm_pc)
+MCONTEXT_ARM_CPSR		mcontext (arm_cpsr)
+MCONTEXT_FAULT_ADDRESS		mcontext (fault_address)


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [ARM] getcontext routines v2
  2012-02-27 23:22       ` Michael Hope
@ 2012-03-04 21:17         ` Michael Hope
  2012-03-05 15:59           ` Carlos O'Donell
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Hope @ 2012-03-04 21:17 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: libc-ports

On Tue, Feb 28, 2012 at 12:21 PM, Michael Hope <michael.hope@linaro.org> wrote:
> On 28/02/12 12:05, Carlos O'Donell wrote:
>>
>> On Mon, Feb 27, 2012 at 5:03 PM, Michael Hope<michael.hope@linaro.org>
>>  wrote:
>>>>
>>>> I looked over things briefly and the formatting and license looks OK.
>>>> Do you and Dave have FSF copyright assignments in place?
>>>
>>>
>>> Yes.  Linaro has an assignment agreement for GCC, GDB, binutils, and
>>> GLIBC
>>> under case #664398.
>>
>>
>> Excellent. Thanks.
>>
>>>> (1) Is setcontext correctly implemented?
>>>
>>> It's correct to the specification and matches the MIPS and Tile ports.
>>>  From
>>> IEEE 1003.1:2004:
>>
>>
>> I've gone and re-read the standard, and I agree with you.
>>
>> Personally I think there is a QoI issue here, but you meet the
>> standard which is the right thing to do.
>
>
> Agreed.  Being able to change uc_link while in a makecontext() child would
> be nice.

Ping?

-- Michael

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [ARM] getcontext routines v2
  2012-03-04 21:17         ` Michael Hope
@ 2012-03-05 15:59           ` Carlos O'Donell
  2012-03-05 22:37             ` Joseph S. Myers
  0 siblings, 1 reply; 9+ messages in thread
From: Carlos O'Donell @ 2012-03-05 15:59 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Michael Hope, libc-ports

On Sun, Mar 4, 2012 at 4:17 PM, Michael Hope <michael.hope@linaro.org> wrote:
> Ping?

http://sourceware.org/ml/libc-ports/2012-02/msg00077.html

Joseph,

I've reviewed this patch twice and plan to commit this at the end of the day.

Do you have any objections?

Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [ARM] getcontext routines v2
  2012-03-05 15:59           ` Carlos O'Donell
@ 2012-03-05 22:37             ` Joseph S. Myers
  2012-03-06 15:22               ` Carlos O'Donell
  0 siblings, 1 reply; 9+ messages in thread
From: Joseph S. Myers @ 2012-03-05 22:37 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: Michael Hope, libc-ports

On Mon, 5 Mar 2012, Carlos O'Donell wrote:

> On Sun, Mar 4, 2012 at 4:17 PM, Michael Hope <michael.hope@linaro.org> wrote:
> > Ping?
> 
> http://sourceware.org/ml/libc-ports/2012-02/msg00077.html
> 
> Joseph,
> 
> I've reviewed this patch twice and plan to commit this at the end of the day.
> 
> Do you have any objections?

I have no objections.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [ARM] getcontext routines v2
  2012-03-05 22:37             ` Joseph S. Myers
@ 2012-03-06 15:22               ` Carlos O'Donell
  0 siblings, 0 replies; 9+ messages in thread
From: Carlos O'Donell @ 2012-03-06 15:22 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Michael Hope, libc-ports

On Mon, Mar 5, 2012 at 5:37 PM, Joseph S. Myers <joseph@codesourcery.com> wrote:
> On Mon, 5 Mar 2012, Carlos O'Donell wrote:
>
>> On Sun, Mar 4, 2012 at 4:17 PM, Michael Hope <michael.hope@linaro.org> wrote:
>> > Ping?
>>
>> http://sourceware.org/ml/libc-ports/2012-02/msg00077.html
>>
>> Joseph,
>>
>> I've reviewed this patch twice and plan to commit this at the end of the day.
>>
>> Do you have any objections?
>
> I have no objections.

Checked into ports.

Thanks for the ping Michael.

Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-03-06 15:22 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-24  1:34 [ARM] getcontext routines v2 Michael Hope
2012-02-24 15:39 ` Carlos O'Donell
2012-02-27 22:03   ` Michael Hope
2012-02-27 23:06     ` Carlos O'Donell
2012-02-27 23:22       ` Michael Hope
2012-03-04 21:17         ` Michael Hope
2012-03-05 15:59           ` Carlos O'Donell
2012-03-05 22:37             ` Joseph S. Myers
2012-03-06 15:22               ` Carlos O'Donell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).