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