am 4fdbadde: Atomic/SMP update.
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 11407b9..bf65a6f 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -244,6 +244,7 @@
 int     init_module(void *, unsigned long, const char *)  128
 int     delete_module(const char*, unsigned int)   129
 int     klogctl:syslog(int, char *, int)   103
+int     sysinfo(struct sysinfo *)  116
 
 # futex
 int	futex(void *, int, int, void *, void *, int) 240
diff --git a/libc/arch-arm/bionic/_setjmp.S b/libc/arch-arm/bionic/_setjmp.S
index 6a27af2..5626219 100644
--- a/libc/arch-arm/bionic/_setjmp.S
+++ b/libc/arch-arm/bionic/_setjmp.S
@@ -3,6 +3,7 @@
 
 /*
  * Copyright (c) 1997 Mark Brinicombe
+ * Copyright (c) 2010 Android Open Source Project.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,6 +36,7 @@
 
 #include <machine/asm.h>
 #include <machine/setjmp.h>
+#include <machine/cpu-features.h>
 
 /*
  * C library -- _setjmp, _longjmp
@@ -51,18 +53,20 @@
 
 ENTRY(_setjmp)
 	ldr	r1, .L_setjmp_magic
-	str	r1, [r0], #4
-#ifdef SOFTFLOAT
-	add	r0, r0, #52
-#else
-	/* Store fp registers */
-	sfm	f4, 4, [r0], #48
-	/* Store fpsr */
-	rfs	r1
-	str	r1, [r0], #0x0004
-#endif	/* SOFTFLOAT */
-	/* Store integer registers */
-        stmia	r0, {r4-r14}
+	str	r1, [r0, #(_JB_MAGIC * 4)]
+
+	/* Store core registers */
+	add     r1, r0, #(_JB_CORE_BASE * 4)
+	stmia   r1, {r4-r14}
+
+#ifdef __ARM_HAVE_VFP
+	/* Store floating-point registers */
+	add     r1, r0, #(_JB_FLOAT_BASE * 4)
+	vstmia  r1, {d8-d15}
+	/* Store floating-point state */
+	fmrx    r1, fpscr
+	str     r1, [r0, #(_JB_FLOAT_STATE * 4)]
+#endif  /* __ARM_HAVE_VFP */
 
         mov	r0, #0x00000000
         bx      lr
@@ -72,21 +76,22 @@
 
 ENTRY(_longjmp)
 	ldr	r2, .L_setjmp_magic
-	ldr	r3, [r0], #4
+	ldr	r3, [r0, #(_JB_MAGIC * 4)]
 	teq	r2, r3
 	bne	botch
 
-#ifdef SOFTFLOAT
-	add	r0, r0, #52
-#else
-	/* Restore fp registers */
-	lfm	f4, 4, [r0], #48
-	/* Restore fpsr */
-	ldr	r4, [r0], #0x0004
-	wfs	r4
-#endif	/* SOFTFLOAT */
-       	/* Restore integer registers */
-        ldmia	r0, {r4-r14}
+#ifdef __ARM_HAVE_VFP
+	/* Restore floating-point registers */
+	add     r2, r0, #(_JB_FLOAT_BASE * 4)
+	vldmia  r2, {d8-d15}
+	/* Restore floating-point state */
+	ldr     r2, [r0, #(_JB_FLOAT_STATE * 4)]
+	fmxr    fpscr, r2
+#endif /* __ARM_HAVE_VFP */
+
+	/* Restore core registers */
+	add     r2, r0, #(_JB_CORE_BASE * 4)
+	ldmia   r2, {r4-r14}
 
 	/* Validate sp and r14 */
 	teq	sp, #0
diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S
index a9f6ea4..59aff66 100644
--- a/libc/arch-arm/bionic/setjmp.S
+++ b/libc/arch-arm/bionic/setjmp.S
@@ -3,6 +3,7 @@
 
 /*
  * Copyright (c) 1997 Mark Brinicombe
+ * Copyright (c) 2010 Android Open Source Project.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,6 +36,7 @@
 
 #include <machine/asm.h>
 #include <machine/setjmp.h>
+#include <machine/cpu-features.h>
 
 /*
  * C library -- setjmp, longjmp
@@ -57,24 +59,26 @@
 	ldmfd	sp!, {r0, r14}
 
 	/* Store signal mask */
-	str	r1, [r0, #(25 * 4)]
+	str	r1, [r0, #(_JB_SIGMASK * 4)]
 
 	ldr	r1, .Lsetjmp_magic
-	str	r1, [r0], #4
+	str	r1, [r0, #(_JB_MAGIC * 4)]
 
-#ifdef SOFTFLOAT
-	add	r0, r0, #52
-#else
-	/* Store fp registers */
-	sfm	f4, 4, [r0], #48
-	/* Store fpsr */
-	rfs	r1
-	str	r1, [r0], #0x0004
-#endif	/*SOFTFLOAT*/
-	/* Store integer registers */
-        stmia	r0, {r4-r14}
-        mov	r0, #0x00000000
-        bx      lr
+	/* Store core registers */
+	add     r1, r0, #(_JB_CORE_BASE * 4)
+	stmia   r1, {r4-r14}
+
+#ifdef __ARM_HAVE_VFP
+	/* Store floating-point registers */
+	add     r1, r0, #(_JB_FLOAT_BASE * 4)
+	vstmia  r1, {d8-d15}
+	/* Store floating-point state */
+	fmrx    r1, fpscr
+	str     r1, [r0, #(_JB_FLOAT_STATE * 4)]
+#endif  /* __ARM_HAVE_VFP */
+
+	mov	r0, #0x00000000
+	bx      lr
 
 .Lsetjmp_magic:
 	.word	_JB_MAGIC_SETJMP
@@ -82,12 +86,12 @@
 
 ENTRY(longjmp)
 	ldr	r2, .Lsetjmp_magic
-	ldr	r3, [r0]
+	ldr	r3, [r0, #(_JB_MAGIC * 4)]
 	teq	r2, r3
 	bne	botch
 
 	/* Fetch signal mask */
-	ldr	r2, [r0, #(25 * 4)]
+	ldr	r2, [r0, #(_JB_SIGMASK * 4)]
 
 	/* Set signal mask */
 	stmfd	sp!, {r0, r1, r14}
@@ -99,18 +103,18 @@
 	add	sp, sp, #4	/* unalign the stack */
 	ldmfd	sp!, {r0, r1, r14} 
 
-	add	r0, r0, #4
-#ifdef SOFTFLOAT
-	add	r0, r0, #52
-#else
-	/* Restore fp registers */
-	lfm	f4, 4, [r0], #48
-	/* Restore FPSR */
-	ldr	r4, [r0], #0x0004
-	wfs	r4
-#endif	/* SOFTFLOAT */
-	/* Restore integer registers */
-        ldmia	r0, {r4-r14}
+#ifdef __ARM_HAVE_VFP
+	/* Restore floating-point registers */
+	add     r2, r0, #(_JB_FLOAT_BASE * 4)
+	vldmia  r2, {d8-d15}
+	/* Restore floating-point state */
+	ldr     r2, [r0, #(_JB_FLOAT_STATE * 4)]
+	fmxr    fpscr, r2
+#endif /* __ARM_HAVE_VFP */
+
+	/* Restore core registers */
+	add     r2, r0, #(_JB_CORE_BASE * 4)
+	ldmia   r2, {r4-r14}
 
 	/* Validate sp and r14 */
 	teq	sp, #0
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/libc/arch-arm/include/machine/cpu-features.h
index 0f969fa..39c1db3 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/libc/arch-arm/include/machine/cpu-features.h
@@ -170,6 +170,19 @@
 #  define __ARM_HAVE_LDREXD
 #endif
 
+/* define _ARM_HAVE_VFP if we have VFPv3
+ */
+#if __ARM_ARCH__ >= 7 && defined __VFP_FP__
+#  define __ARM_HAVE_VFP
+#endif
+
+/* define _ARM_HAVE_NEON for ARMv7 architecture if we support the
+ * Neon SIMD instruction set extensions. This also implies
+ * that VFPv3-D32 is supported.
+ */
+#if __ARM_ARCH__ >= 7 && defined __ARM_NEON__
+#  define __ARM_HAVE_NEON
+#endif
 
 /* Assembly-only macros */
 
diff --git a/libc/arch-arm/include/machine/setjmp.h b/libc/arch-arm/include/machine/setjmp.h
index f20cab2..0941202 100644
--- a/libc/arch-arm/include/machine/setjmp.h
+++ b/libc/arch-arm/include/machine/setjmp.h
@@ -1,87 +1,82 @@
-/*	$OpenBSD: setjmp.h,v 1.1 2004/02/01 05:09:49 drahn Exp $	*/
-/*	$NetBSD: setjmp.h,v 1.2 2001/08/25 14:45:59 bjh21 Exp $	*/
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
 
 /*
  * machine/setjmp.h: machine dependent setjmp-related information.
  */
 
-#ifdef __ELF__
-#define	_JBLEN	64		/* size, in longs, of a jmp_buf */
-#else
-#define	_JBLEN	29		/* size, in longs, of a jmp_buf */
-#endif
-
-/*
- * NOTE: The internal structure of a jmp_buf is *PRIVATE*
- *       This information is provided as there is software
- *       that fiddles with this with obtain the stack pointer
- *	 (yes really ! and its commercial !).
+/* _JBLEN is the size of a jmp_buf in longs.
+ * Do not modify this value or you will break the ABI !
  *
- * Description of the setjmp buffer
- *
- * word  0	magic number	(dependant on creator)
- *       1 -  3	f4		fp register 4
- *	 4 -  6	f5		fp register 5
- *	 7 -  9 f6		fp register 6
- *	10 - 12	f7		fp register 7
- *	13	fpsr		fp status register
- *	14	r4		register 4
- *	15	r5		register 5
- *	16	r6		register 6
- *	17	r7		register 7
- *	18	r8		register 8
- *	19	r9		register 9
- *	20	r10		register 10 (sl)
- *	21	r11		register 11 (fp)
- *	22	r12		register 12 (ip)
- *	23	r13		register 13 (sp)
- *	24	r14		register 14 (lr)
- *	25	signal mask	(dependant on magic)
- *	26	(con't)
- *	27	(con't)
- *	28	(con't)
- *
- * The magic number number identifies the jmp_buf and
- * how the buffer was created as well as providing
- * a sanity check
- *
- * A side note I should mention - Please do not tamper
- * with the floating point fields. While they are
- * always saved and restored at the moment this cannot
- * be garenteed especially if the compiler happens
- * to be generating soft-float code so no fp
- * registers will be used.
- *
- * Whilst this can be seen an encouraging people to
- * use the setjmp buffer in this way I think that it
- * is for the best then if changes occur compiles will
- * break rather than just having new builds falling over
- * mysteriously.
+ * This value comes from the original OpenBSD ARM-specific header
+ * that was replaced by this one.
  */
+#define _JBLEN  64
+
+/* According to the ARM AAPCS document, we only need to save
+ * the following registers:
+ *
+ *  Core   r4-r14
+ *
+ *  VFP    d8-d15  (see section 5.1.2.1)
+ *
+ *      Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine
+ *      calls; registers s0-s15 (d0-d7, q0-q3) do not need to be preserved
+ *      (and can be used for passing arguments or returning results in standard
+ *      procedure-call variants). Registers d16-d31 (q8-q15), if present, do
+ *      not need to be preserved.
+ *
+ *  FPSCR  saved because GLibc does saves it too.
+ *
+ */
+
+/* The internal structure of a jmp_buf is totally private.
+ * Current layout (may change in the future):
+ *
+ * word   name         description
+ * 0      magic        magic number
+ * 1      sigmask      signal mask (not used with _setjmp / _longjmp)
+ * 2      float_base   base of float registers (d8 to d15)
+ * 18     float_state  floating-point status and control register
+ * 19     core_base    base of core registers (r4 to r14)
+ * 30     reserved     reserved entries (room to grow)
+ * 64
+ *
+ * NOTE: float_base must be at an even word index, since the
+ *       FP registers will be loaded/stored with instructions
+ *       that expect 8-byte alignment.
+ */
+
+#define _JB_MAGIC       0
+#define _JB_SIGMASK     (_JB_MAGIC+1)
+#define _JB_FLOAT_BASE  (_JB_SIGMASK+1)
+#define _JB_FLOAT_STATE (_JB_FLOAT_BASE + (15-8+1)*2)
+#define _JB_CORE_BASE   (_JB_FLOAT_STATE+1)
 
 #define _JB_MAGIC__SETJMP	0x4278f500
 #define _JB_MAGIC_SETJMP	0x4278f501
-
-/* Valid for all jmp_buf's */
-
-#define _JB_MAGIC		 0
-#define _JB_REG_F4		 1
-#define _JB_REG_F5		 4
-#define _JB_REG_F6		 7
-#define _JB_REG_F7		10
-#define _JB_REG_FPSR		13
-#define _JB_REG_R4		14
-#define _JB_REG_R5		15
-#define _JB_REG_R6		16
-#define _JB_REG_R7		17
-#define _JB_REG_R8		18
-#define _JB_REG_R9		19
-#define _JB_REG_R10		20
-#define _JB_REG_R11		21
-#define _JB_REG_R12		22
-#define _JB_REG_R13		23
-#define _JB_REG_R14		24
-
-/* Only valid with the _JB_MAGIC_SETJMP magic */
-
-#define _JB_SIGMASK		25
diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk
index 9cdd28a..f6312e5 100644
--- a/libc/arch-arm/syscalls.mk
+++ b/libc/arch-arm/syscalls.mk
@@ -161,6 +161,7 @@
 syscall_src += arch-arm/syscalls/init_module.S
 syscall_src += arch-arm/syscalls/delete_module.S
 syscall_src += arch-arm/syscalls/klogctl.S
+syscall_src += arch-arm/syscalls/sysinfo.S
 syscall_src += arch-arm/syscalls/futex.S
 syscall_src += arch-arm/syscalls/epoll_create.S
 syscall_src += arch-arm/syscalls/epoll_ctl.S
diff --git a/libc/arch-arm/syscalls/sysinfo.S b/libc/arch-arm/syscalls/sysinfo.S
new file mode 100644
index 0000000..197324d
--- /dev/null
+++ b/libc/arch-arm/syscalls/sysinfo.S
@@ -0,0 +1,19 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type sysinfo, #function
+    .globl sysinfo
+    .align 4
+    .fnstart
+
+sysinfo:
+    .save   {r4, r7}
+    stmfd   sp!, {r4, r7}
+    ldr     r7, =__NR_sysinfo
+    swi     #0
+    ldmfd   sp!, {r4, r7}
+    movs    r0, r0
+    bxpl    lr
+    b       __set_syscall_errno
+    .fnend
diff --git a/libc/arch-sh/syscalls.mk b/libc/arch-sh/syscalls.mk
index ab2f3d1..a8a151a 100644
--- a/libc/arch-sh/syscalls.mk
+++ b/libc/arch-sh/syscalls.mk
@@ -150,6 +150,7 @@
 syscall_src += arch-sh/syscalls/init_module.S
 syscall_src += arch-sh/syscalls/delete_module.S
 syscall_src += arch-sh/syscalls/klogctl.S
+syscall_src += arch-sh/syscalls/sysinfo.S
 syscall_src += arch-sh/syscalls/futex.S
 syscall_src += arch-sh/syscalls/epoll_create.S
 syscall_src += arch-sh/syscalls/epoll_ctl.S
diff --git a/libc/arch-sh/syscalls/sysinfo.S b/libc/arch-sh/syscalls/sysinfo.S
new file mode 100644
index 0000000..ae042ab
--- /dev/null
+++ b/libc/arch-sh/syscalls/sysinfo.S
@@ -0,0 +1,32 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type sysinfo, @function
+    .globl sysinfo
+    .align 4
+
+sysinfo:
+
+    /* invoke trap */
+    mov.l   0f, r3  /* trap num */
+    trapa   #(1 + 0x10)
+
+    /* check return value */
+    cmp/pz  r0
+    bt      __NR_sysinfo_end
+
+    /* keep error number */
+    sts.l   pr, @-r15
+    mov.l   1f, r1
+    jsr     @r1
+    mov     r0, r4
+    lds.l   @r15+, pr
+
+__NR_sysinfo_end:
+    rts
+    nop
+
+    .align  2
+0:  .long   __NR_sysinfo
+1:  .long   __set_syscall_errno
diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk
index ab026fe..bd9a9ab 100644
--- a/libc/arch-x86/syscalls.mk
+++ b/libc/arch-x86/syscalls.mk
@@ -164,6 +164,7 @@
 syscall_src += arch-x86/syscalls/init_module.S
 syscall_src += arch-x86/syscalls/delete_module.S
 syscall_src += arch-x86/syscalls/klogctl.S
+syscall_src += arch-x86/syscalls/sysinfo.S
 syscall_src += arch-x86/syscalls/futex.S
 syscall_src += arch-x86/syscalls/epoll_create.S
 syscall_src += arch-x86/syscalls/epoll_ctl.S
diff --git a/libc/arch-x86/syscalls/sysinfo.S b/libc/arch-x86/syscalls/sysinfo.S
new file mode 100644
index 0000000..c60c37b
--- /dev/null
+++ b/libc/arch-x86/syscalls/sysinfo.S
@@ -0,0 +1,23 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type sysinfo, @function
+    .globl sysinfo
+    .align 4
+
+sysinfo:
+    pushl   %ebx
+    mov     8(%esp), %ebx
+    movl    $__NR_sysinfo, %eax
+    int     $0x80
+    cmpl    $-129, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %ebx
+    ret
diff --git a/libc/docs/CHANGES.TXT b/libc/docs/CHANGES.TXT
index a66e737..0599788 100644
--- a/libc/docs/CHANGES.TXT
+++ b/libc/docs/CHANGES.TXT
@@ -5,9 +5,16 @@
 
 - <pthread.h>: Add reader/writer locks implementation.
 
+- <math.h>: Added sincos() and sincosf() (GLibc compatibility).
+
+- <sys/sysinfo.h>: Added missing sysinfo() system call implementation
+  (the function was already declared in the header though).
+
 -------------------------------------------------------------------------------
 Differences between Android 2.2. and Android 2.1:
 
+- Support FP register save/load in setjmp()/longjmp() on ARMv7 builds.
+
 - Add support for SH-4 CPU architecture !
 
 - __atomic_swap(): use LDREX/STREX CPU instructions on ARMv6 and higher.
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 41e8d26..5a991ac 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -135,7 +135,7 @@
 extern int    ptsname_r(int, char*, size_t);
 extern int    getpt(void);
 
-static __inline__ int grantpt(int __fd)
+static __inline__ int grantpt(int __fd __attribute((unused)))
 {
   (void)__fd;
   return 0;     /* devpts does this all for us! */
diff --git a/libc/include/sys/linux-syscalls.h b/libc/include/sys/linux-syscalls.h
index 6e373e0..5f03863 100644
--- a/libc/include/sys/linux-syscalls.h
+++ b/libc/include/sys/linux-syscalls.h
@@ -126,6 +126,7 @@
 #define __NR_init_module                  (__NR_SYSCALL_BASE + 128)
 #define __NR_delete_module                (__NR_SYSCALL_BASE + 129)
 #define __NR_syslog                       (__NR_SYSCALL_BASE + 103)
+#define __NR_sysinfo                      (__NR_SYSCALL_BASE + 116)
 #define __NR_futex                        (__NR_SYSCALL_BASE + 240)
 #define __NR_poll                         (__NR_SYSCALL_BASE + 168)
 
diff --git a/libc/include/sys/linux-unistd.h b/libc/include/sys/linux-unistd.h
index b0e7822..27db2a9 100644
--- a/libc/include/sys/linux-unistd.h
+++ b/libc/include/sys/linux-unistd.h
@@ -192,6 +192,7 @@
 int              init_module (void *, unsigned long, const char *);
 int              delete_module (const char*, unsigned int);
 int              klogctl (int, char *, int);
+int              sysinfo (struct sysinfo *);
 int              futex (void *, int, int, void *, void *, int);
 int              epoll_create (int size);
 int              epoll_ctl (int epfd, int op, int fd, struct epoll_event *event);
diff --git a/libm/Android.mk b/libm/Android.mk
index fa73aff..28e8f33 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -3,6 +3,7 @@
 libm_common_src_files:= \
 	isinf.c  \
 	fpclassify.c \
+	sincos.c \
 	bsdsrc/b_exp.c \
 	bsdsrc/b_log.c \
 	bsdsrc/b_tgamma.c \
diff --git a/libm/include/math.h b/libm/include/math.h
index ef6a9e6..6c0d4eb 100644
--- a/libm/include/math.h
+++ b/libm/include/math.h
@@ -480,6 +480,12 @@
 #endif
 long double	truncl(long double);
 
+/* BIONIC: GLibc compatibility - required by the ARM toolchain */
+#ifdef _GNU_SOURCE
+void  sincos(double x, double *sin, double *cos);
+void  sincosf(float x, float *sin, float *cos);
+#endif
+
 /* #endif */ /* __ISO_C_VISIBLE >= 1999 */
 __END_DECLS
 
diff --git a/libm/sincos.c b/libm/sincos.c
new file mode 100644
index 0000000..ddbc420
--- /dev/null
+++ b/libm/sincos.c
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#define _GNU_SOURCE 1
+#include <math.h>
+
+void  sincos(double x, double *psin, double *pcos)
+{
+    *psin = sin(x);
+    *pcos = cos(x);
+}
+
+void  sincosf(float x, float *psin, float *pcos)
+{
+    *psin = sinf(x);
+    *pcos = cosf(x);
+}
diff --git a/libthread_db/include/thread_db.h b/libthread_db/include/thread_db.h
index 9c76d40..1b36cb2 100644
--- a/libthread_db/include/thread_db.h
+++ b/libthread_db/include/thread_db.h
@@ -10,6 +10,8 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+typedef void *psaddr_t;
+typedef pid_t lwpid_t;
 
 #define TD_THR_ANY_USER_FLAGS       0xffffffff
 #define TD_THR_LOWEST_PRIORITY      -20
@@ -67,6 +69,7 @@
 typedef struct
 {
     pid_t pid;
+    struct ps_prochandle *ph;
 } td_thragent_t;
 
 typedef struct
@@ -123,19 +126,37 @@
 extern "C"{
 #endif
 
-extern td_err_e td_ta_new(struct ps_prochandle const * proc_handle, td_thragent_t ** thread_agent);
+extern td_err_e td_ta_new(struct ps_prochandle * proc_handle, td_thragent_t ** thread_agent);
+
+extern td_err_e td_ta_delete(td_thragent_t * ta);
 
 extern td_err_e td_ta_set_event(td_thragent_t const * agent, td_thr_events_t * event);
 
 extern td_err_e td_ta_event_addr(td_thragent_t const * agent, td_event_e event, td_notify_t * notify);
 
+extern td_err_e td_ta_clear_event(const td_thragent_t * ta_arg,
+				  td_thr_events_t * event);
+
 extern td_err_e td_ta_event_getmsg(td_thragent_t const * agent, td_event_msg_t * event);
 
+extern td_err_e td_ta_map_lwp2thr(td_thragent_t const * agent, lwpid_t lwpid,
+				  td_thrhandle_t *th);
+
+extern td_err_e td_thr_get_info(td_thrhandle_t const * handle,
+				td_thrinfo_t * info);
+
+extern td_err_e td_thr_event_enable(td_thrhandle_t const * handle,
+				    td_event_e event);
+
 extern td_err_e td_ta_thr_iter(td_thragent_t const * agent, td_thr_iter_f * func, void * cookie,
                                td_thr_state_e state, int32_t prio, sigset_t * sigmask, uint32_t user_flags);
 
 extern char const ** td_symbol_list(void);
 
+extern td_err_e td_thr_tls_get_addr(const td_thrhandle_t * th,
+				    psaddr_t map_address, size_t offset,
+				    psaddr_t * address);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libthread_db/libthread_db.c b/libthread_db/libthread_db.c
index f1a78ac..2cf4d38 100644
--- a/libthread_db/libthread_db.c
+++ b/libthread_db/libthread_db.c
@@ -10,12 +10,7 @@
 #include <stdio.h>
 
 extern int ps_pglobal_lookup (void *, const char *obj, const char *name, void **sym_addr);
-
-struct ps_prochandle
-{
-    pid_t pid;
-};
-
+extern pid_t ps_getpid(struct ps_prochandle *ph);
 
 /*
  * This is the list of "special" symbols we care about whose addresses are
@@ -41,7 +36,7 @@
 
 
 td_err_e
-td_ta_new(struct ps_prochandle const * proc_handle, td_thragent_t ** agent_out)
+td_ta_new(struct ps_prochandle * proc_handle, td_thragent_t ** agent_out)
 {
     td_thragent_t * agent;
 
@@ -50,7 +45,8 @@
         return TD_MALLOC;
     }
 
-    agent->pid = proc_handle->pid;
+    agent->pid = ps_getpid(proc_handle);
+    agent->ph = proc_handle;
     *agent_out = agent;
 
     return TD_OK;
@@ -58,14 +54,28 @@
 
 
 td_err_e
+td_ta_delete(td_thragent_t * ta)
+{
+    free(ta);
+    // FIXME: anything else to do?
+    return TD_OK;
+}
+
+
+/* NOTE: not used by gdb 7.0 */
+
+td_err_e
 td_ta_set_event(td_thragent_t const * agent, td_thr_events_t * events)
 {
     return TD_OK;
 }
 
 
+/* NOTE: not used by gdb 7.0 */
 static td_thrhandle_t gEventMsgHandle;
 
+/* NOTE: not used by gdb 7.0 */
+
 static int
 _event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr)
 {
@@ -83,6 +93,8 @@
     return 0;
 }
 
+/* NOTE: not used by gdb 7.0 */
+
 td_err_e
 td_ta_event_getmsg(td_thragent_t const * agent, td_event_msg_t * event)
 {
@@ -107,6 +119,16 @@
 
 
 td_err_e
+td_ta_map_lwp2thr(td_thragent_t const * agent, lwpid_t lwpid,
+		  td_thrhandle_t *th)
+{
+    th->pid = ps_getpid(agent->ph);
+    th->tid = lwpid;
+    return TD_OK;
+}
+
+
+td_err_e
 td_thr_get_info(td_thrhandle_t const * handle, td_thrinfo_t * info)
 {
     info->ti_tid = handle->tid;
@@ -117,6 +139,8 @@
 }
 
 
+/* NOTE: not used by gdb 7.0 */
+
 td_err_e
 td_thr_event_enable(td_thrhandle_t const * handle, td_event_e event)
 {
@@ -125,6 +149,8 @@
 }
 
 
+/* NOTE: not used by gdb 7.0 */
+
 td_err_e
 td_ta_event_addr(td_thragent_t const * agent, td_event_e event, td_notify_t * notify_out)
 {
@@ -149,6 +175,15 @@
 
 
 td_err_e
+td_ta_clear_event(const td_thragent_t * ta_arg, td_thr_events_t * event)
+{
+    /* Given that gdb 7.0 doesn't use thread events,
+       there's nothing we need to do here.  */
+    return TD_OK;
+}
+
+
+td_err_e
 td_ta_thr_iter(td_thragent_t const * agent, td_thr_iter_f * func, void * cookie,
                td_thr_state_e state, int32_t prio, sigset_t * sigmask, uint32_t user_flags)
 {
@@ -170,8 +205,8 @@
             continue;
         }
         handle.tid = atoi(entry->d_name);
-        err = func(&handle, cookie);
-        if (err) {
+        if (func(&handle, cookie) != 0) {
+	    err = TD_DBERR;
             break;
         }
     }
@@ -181,3 +216,9 @@
     return err;
 }
 
+td_err_e
+td_thr_tls_get_addr(const td_thrhandle_t * th,
+		    psaddr_t map_address, size_t offset, psaddr_t * address)
+{
+    return TD_NOAPLIC; // FIXME: TODO
+}