diff --git a/libc/Android.mk b/libc/Android.mk
index faca333..67fc01c 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -122,6 +122,7 @@ libc_common_src_files := \
 	stdio/vsnprintf.c \
 	stdio/vsprintf.c \
 	stdio/vscanf.c \
+	stdio/vsscanf.c \
 	stdio/wbuf.c \
 	stdio/wsetup.c \
 	stdlib/_rand48.c \
@@ -200,12 +201,14 @@ libc_common_src_files := \
 	tzcode/localtime.c \
 	tzcode/strftime.c \
 	tzcode/strptime.c \
+	arch-arm/bionic/__clzsi2.S \
 	arch-arm/bionic/__get_pc.S \
 	arch-arm/bionic/__get_sp.S \
 	arch-arm/bionic/_exit_with_stack_teardown.S \
 	arch-arm/bionic/_setjmp.S \
 	arch-arm/bionic/atomics_arm.S \
 	arch-arm/bionic/clone.S \
+	arch-arm/bionic/ffs.S \
 	arch-arm/bionic/memcmp.S \
 	arch-arm/bionic/memcmp16.S \
 	arch-arm/bionic/memcpy.S \
diff --git a/libc/arch-arm/bionic/atomics_arm.S b/libc/arch-arm/bionic/atomics_arm.S
index b2da09f..a05641f 100644
--- a/libc/arch-arm/bionic/atomics_arm.S
+++ b/libc/arch-arm/bionic/atomics_arm.S
@@ -46,9 +46,15 @@ __atomic_dec:
 1: @ atomic_dec
     ldr     r0, [r2]
     mov     r3, #kernel_atomic_base
-    add     lr, pc, #4
     sub     r1, r0, #1
+#ifndef __ARM_ARCH_4__
+    mov     lr, pc
     add     pc, r3, #(kernel_cmpxchg - kernel_atomic_base)
+#else
+    add     ip, r3, #(kernel_cmpxchg - kernel_atomic_base)
+    mov     lr, pc
+    bx      ip
+#endif
     bcc     1b
     add     r0, r1, #1
     ldmia   sp!, {r4, lr}
@@ -60,9 +66,15 @@ __atomic_inc:
 1: @ atomic_inc
     ldr     r0, [r2]
     mov     r3, #kernel_atomic_base
-    add     lr, pc, #4
     add     r1, r0, #1
+#ifndef __ARM_ARCH_4__
+    mov     lr, pc
     add     pc, r3, #(kernel_cmpxchg - kernel_atomic_base)
+#else
+    add     ip, r3, #(kernel_cmpxchg - kernel_atomic_base)
+    mov     lr, pc
+    bx      ip
+#endif
     bcc     1b
     sub     r0, r1, #1
     ldmia   sp!, {r4, lr}
@@ -74,9 +86,15 @@ __atomic_cmpxchg:
     mov     r4, r0          /* r4 = save oldvalue */
 1: @ atomic_cmpxchg
     mov     r3, #kernel_atomic_base
-    add     lr, pc, #4
     mov     r0, r4          /* r0 = oldvalue */
+#ifndef __ARM_ARCH_4__
+    mov     lr, pc
     add     pc, r3, #(kernel_cmpxchg - kernel_atomic_base)
+#else
+    add     ip, r3, #(kernel_cmpxchg - kernel_atomic_base)
+    mov     lr, pc
+    bx      ip
+#endif
     bcs     2f              /* swap was made. we're good, return. */
     ldr     r3, [r2]        /* swap not made, see if it's because *ptr!=oldvalue */
     cmp     r3, r4
@@ -91,9 +109,15 @@ __atomic_cmpxchg:
 __atomic_cmpxchg:
     stmdb   sp!, {r4, lr}
     mov     r4, r0          /* r4 = save oldvalue */
-1:  add     lr, pc, #4
-    mov     r0, r4          /* r0 = oldvalue */
+1:  mov     r0, r4          /* r0 = oldvalue */
+#ifndef __ARM_ARCH_4__
+    mov     lr, pc
     mov     pc, #KUSER_CMPXCHG
+#else
+    mov     ip, #KUSER_CMPXCHG
+    mov     lr, pc
+    bx      ip
+#endif
     bcs     2f              /* swap was made. we're good, return. */
     ldr     r3, [r2]        /* swap not made, see if it's because *ptr!=oldvalue */
     cmp     r3, r4
@@ -106,9 +130,15 @@ __atomic_dec:
     stmdb   sp!, {r4, lr}
     mov     r2, r0          /* address */
 1:  ldr     r0, [r2]        /* oldvalue */
-    add     lr, pc, #4
     sub     r1, r0, #1      /* newvalue = oldvalue - 1 */
+#ifndef __ARM_ARCH_4__
+    mov     lr, pc
     mov     pc, #KUSER_CMPXCHG
+#else
+    mov     ip, #KUSER_CMPXCHG
+    mov     lr, pc
+    bx      ip
+#endif
     bcc     1b              /* no swap, try again until we get it right */
     mov     r0, ip          /* swapped, return the old value */
     ldmia   sp!, {r4, lr}
@@ -119,9 +149,15 @@ __atomic_inc:
     stmdb   sp!, {r4, lr}
     mov     r2, r0          /* address */
 1:  ldr     r0, [r2]        /* oldvalue */
-    add     lr, pc, #4
     add     r1, r0, #1      /* newvalue = oldvalue + 1 */
+#ifndef __ARM_ARCH_4__
+    mov     lr, pc
     mov     pc, #KUSER_CMPXCHG
+#else
+    mov     ip, #KUSER_CMPXCHG
+    mov     lr, pc
+    bx      ip
+#endif
     bcc     1b              /* no swap, try again until we get it right */
     mov     r0, ip          /* swapped, return the old value */
     ldmia   sp!, {r4, lr}
diff --git a/libc/arch-arm/bionic/memcmp.S b/libc/arch-arm/bionic/memcmp.S
index d19dfb9..aa2eb23 100644
--- a/libc/arch-arm/bionic/memcmp.S
+++ b/libc/arch-arm/bionic/memcmp.S
@@ -41,9 +41,10 @@
  */
 
 memcmp:
+#ifndef __ARM_ARCH_4__
         pld         [r0, #0]
         pld         [r1, #0]
-
+#endif
         /* take of the case where length is 0 or the buffers are the same */
         cmp         r0, r1
         cmpne       r2, #0
@@ -52,9 +53,11 @@ memcmp:
 
         /* save registers */
         stmfd       sp!, {r4, lr}
-        
+
+#ifndef __ARM_ARCH_4__
         pld         [r0, #32]
         pld         [r1, #32]
+#endif
 
         /* since r0 hold the result, move the first source
          * pointer somewhere else
@@ -104,8 +107,11 @@ memcmp:
         subs        r2, r2, #(32 + 4)
         bmi         1f
         
-0:      pld         [r4, #64]
+0:
+#ifndef __ARM_ARCH_4__
+        pld         [r4, #64]
         pld         [r1, #64]
+#endif
         ldr         r0, [r4], #4
         ldr         lr, [r1, #4]!
         eors        r0, r0, ip
@@ -192,8 +198,11 @@ memcmp:
         bic         r1, r1, #3
         ldr         lr, [r1], #4
 
-6:      pld         [r1, #64]
+6:
+#ifndef __ARM_ARCH_4__
+        pld         [r1, #64]
         pld         [r4, #64]
+#endif
         mov         ip, lr, lsr #16
         ldr         lr, [r1], #4
         ldr         r0, [r4], #4
diff --git a/libc/arch-arm/bionic/memcmp16.S b/libc/arch-arm/bionic/memcmp16.S
index c6e6d39..f92bca8 100644
--- a/libc/arch-arm/bionic/memcmp16.S
+++ b/libc/arch-arm/bionic/memcmp16.S
@@ -41,8 +41,10 @@
  */
 
 __memcmp16:
+#ifndef __ARM_ARCH_4__
         pld         [r0, #0]
         pld         [r1, #0]
+#endif
 
         /* take of the case where length is nul or the buffers are the same */
         cmp         r0, r1
@@ -64,8 +66,10 @@ __memcmp16:
         bpl         0f
 
         /* small blocks (less then 12 words) */
+#ifndef __ARM_ARCH_4__
         pld         [r0, #32]
         pld         [r1, #32]
+#endif
 
 1:      ldrh        r0, [r3], #2
         ldrh        ip, [r1], #2
@@ -113,8 +117,10 @@ __memcmp16:
         bmi         1f
         
 0:
+#ifndef __ARM_ARCH_4__
         pld         [r3, #64]
         pld         [r1, #64]
+#endif
         ldr         r0, [r3], #4
         ldr         lr, [r1, #4]!
         eors        r0, r0, ip
@@ -195,8 +201,10 @@ __memcmp16:
         sub         r2, r2, #8
 
 6:
+#ifndef __ARM_ARCH_4__
         pld         [r3, #64]
         pld         [r1, #64]
+#endif
         mov         ip, lr, lsr #16
         ldr         lr, [r1], #4
         ldr         r0, [r3], #4
diff --git a/libc/arch-arm/bionic/memcpy.S b/libc/arch-arm/bionic/memcpy.S
index f6e4a7d..41c5a80 100644
--- a/libc/arch-arm/bionic/memcpy.S
+++ b/libc/arch-arm/bionic/memcpy.S
@@ -52,9 +52,11 @@ memcpy:
 
         // preload the destination because we'll align it to a cache line
         // with small writes. Also start the source "pump".
+#ifndef __ARM_ARCH_4__
         pld         [r0, #0]
         pld         [r1, #0]
         pld         [r1, #32]
+#endif
 
 		/* it simplifies things to take care of len<4 early */
 		cmp			r2, #4
@@ -142,7 +144,9 @@ cached_aligned32:
         add         r12, r12, #64
 
 1:      ldmia		r1!, { r4-r11 }
+#ifndef __ARM_ARCH_4__
         pld         [r12, #64]
+#endif
         subs        r2, r2, #32
 
         // NOTE: if r12 is more than 64 ahead of r1, the following ldrhi
@@ -263,7 +267,9 @@ loop16:
         ldr         r12, [r1], #4
 1:      mov         r4, r12
 		ldmia		r1!, {   r5,r6,r7,  r8,r9,r10,r11}
+#ifndef __ARM_ARCH_4__
         pld         [r1, #64]
+#endif
 		subs		r2, r2, #32
         ldrhs       r12, [r1], #4
 		orr			r3, r3, r4,		lsl #16
@@ -290,7 +296,9 @@ loop8:
         ldr         r12, [r1], #4
 1:      mov         r4, r12
 		ldmia		r1!, {   r5,r6,r7,  r8,r9,r10,r11}
+#ifndef __ARM_ARCH_4__
         pld         [r1, #64]
+#endif
 		subs		r2, r2, #32
         ldrhs       r12, [r1], #4
 		orr			r3, r3, r4,		lsl #24
@@ -317,7 +325,9 @@ loop24:
         ldr         r12, [r1], #4
 1:      mov         r4, r12
 		ldmia		r1!, {   r5,r6,r7,  r8,r9,r10,r11}
+#ifndef __ARM_ARCH_4__
         pld         [r1, #64]
+#endif
 		subs		r2, r2, #32
         ldrhs       r12, [r1], #4
 		orr			r3, r3, r4,		lsl #8
diff --git a/libc/arch-arm/bionic/strlen.c b/libc/arch-arm/bionic/strlen.c
index 3d1fe45..3a49b2b 100644
--- a/libc/arch-arm/bionic/strlen.c
+++ b/libc/arch-arm/bionic/strlen.c
@@ -62,7 +62,9 @@ size_t strlen(const char *s)
         "ldr     %[v], [ %[s] ], #4         \n"
         "sub     %[l], %[l], %[s]           \n"
         "0:                                 \n"
+#ifndef __ARM_ARCH_4__
         "pld     [ %[s], #64 ]              \n"
+#endif
         "sub     %[t], %[v], %[mask], lsr #7\n"
         "and     %[t], %[t], %[mask]        \n"
         "bics    %[t], %[t], %[v]           \n"
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index fe7033d..843c774 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -194,6 +194,10 @@
 #define	__used		/* delete */
 #endif
 
+#ifdef __section
+#undef __section
+#endif
+
 #if __GNUC_PREREQ__(2, 7)
 #define	__packed	__attribute__((__packed__))
 #define	__aligned(x)	__attribute__((__aligned__(x)))
@@ -323,6 +327,14 @@
 #endif
 
 /*
+ * There might be some kernel routines marked as "deprecated" in some
+ * include headers.
+ */
+#ifndef __deprecated
+# define __deprecated	/* DO-NOT-USE */
+#endif
+
+/*
  * Macros for manipulating "link sets".  Link sets are arrays of pointers
  * to objects, which are gathered up by the linker.
  *
diff --git a/libc/include/sys/limits.h b/libc/include/sys/limits.h
index 41d02ff..ffa014a 100644
--- a/libc/include/sys/limits.h
+++ b/libc/include/sys/limits.h
@@ -125,8 +125,13 @@
 
 /* Bionic: the following has been optimized out from our processed kernel headers */
 
-#define  CHILD_MAX   999
-#define  OPEN_MAX    256
+#ifndef CHILD_MAX
+#define CHILD_MAX	999
+#endif
+
+#ifndef OPEN_MAX
+#define OPEN_MAX	256
+#endif
 
 /* Bionic-specific definitions */
 
diff --git a/libc/include/sys/tls.h b/libc/include/sys/tls.h
index d59f1c3..9053f7f 100644
--- a/libc/include/sys/tls.h
+++ b/libc/include/sys/tls.h
@@ -70,7 +70,8 @@ extern int __set_tls(void *ptr);
 
 /* get the TLS */
 #ifdef __arm__
-#  define __get_tls() ( *((volatile void **) 0xffff0ff0) )
+typedef void* (__get_tls_t)(void);
+static const __get_tls_t* __get_tls = (const __get_tls_t *)0xffff0fe0;
 #else
 extern void*  __get_tls( void );
 #endif
diff --git a/libc/include/termios.h b/libc/include/termios.h
index 043fe16..e0a93db 100644
--- a/libc/include/termios.h
+++ b/libc/include/termios.h
@@ -36,6 +36,24 @@
 
 __BEGIN_DECLS
 
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14
+#define N_HCI		15  /* Bluetooth HCI UART */
+
 /* Redefine these to match their ioctl number */
 #undef  TCSANOW
 #define TCSANOW    TCSETS
@@ -46,6 +64,10 @@ __BEGIN_DECLS
 #undef  TCSAFLUSH
 #define TCSAFLUSH  TCSETSF
 
+#ifndef N_TTY
+#define N_TTY		0
+#endif
+
 static __inline__ int tcgetattr(int fd, struct termios *s)
 {
     return ioctl(fd, TCGETS, s);
diff --git a/linker/Android.mk b/linker/Android.mk
index 5d11148..5a0ad4e 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -29,6 +29,7 @@ else
 endif
 
 LOCAL_MODULE:= linker
+LOCAL_ARM_MODE:= arm
 
 LOCAL_STATIC_LIBRARIES := libcutils libc
 
diff --git a/linker/arch/arm/begin.S b/linker/arch/arm/begin.S
index f9b3bac..3a01c19 100644
--- a/linker/arch/arm/begin.S
+++ b/linker/arch/arm/begin.S
@@ -9,7 +9,7 @@ _start:
 	bl	__linker_init
 
 	/* linker init returns the _entry address in the main image */
-	mov	pc, r0
+	bx	r0
 
 	.section .ctors, "wa"
 	.globl __CTOR_LIST__
