--- /dev/null
+diff -urN uClibc-0.9.27/extra/Configs/Config.h8300 uClibc-0.9.27-uc0/extra/Configs/Config.h8300
+--- uClibc-0.9.27/extra/Configs/Config.h8300 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/extra/Configs/Config.h8300 2005-01-26 07:37:19.000000000 +0100
+@@ -7,7 +7,6 @@
+ bool
+ select ARCH_HAS_NO_MMU
+ select ARCH_HAS_C_SYMBOL_PREFIX
+- select HAVE_NO_SHARED
+ select ARCH_HAS_NO_LDSO
+ default y
+
+@@ -36,6 +35,14 @@
+
+ endchoice
+
++config CONFIG_BINFMT_SHARED_FLAT
++ bool "Build Shared Library"
++ default n
++
++config UCLIBC_HAS_SOFT_FLOAT
++ bool
++ default n
++
+ config ARCH_CFLAGS
+ string
+
+diff -urN uClibc-0.9.27/extra/Configs/Config.in uClibc-0.9.27-uc0/extra/Configs/Config.in
+--- uClibc-0.9.27/extra/Configs/Config.in 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/extra/Configs/Config.in 2006-02-27 08:31:05.000000000 +0100
+@@ -383,6 +383,12 @@
+
+ Unless you use uClibc with C++, you should probably answer N.
+
++config COMPAT_ATEXIT
++ bool "Old (visible) atexit Support"
++ default n
++ help
++ Enable this option if you want to update from 0.9.28 to svn/0.9.29, else
++ you will be missing atexit() until you rebuild all apps.
+
+ config HAS_SHADOW
+ bool "Shadow Password Support"
+diff -urN uClibc-0.9.27/extra/Configs/Config.in.arch uClibc-0.9.27-uc0/extra/Configs/Config.in.arch
+--- uClibc-0.9.27/extra/Configs/Config.in.arch 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/extra/Configs/Config.in.arch 2006-07-28 07:00:26.000000000 +0200
+@@ -99,9 +99,9 @@
+ work at all. You have been warned.
+
+ config UCLIBC_UCLINUX_BROKEN_MUNMAP
+- bool
++ bool "If munmap expects 0 for the size"
+ depends on !ARCH_HAS_MMU
+- default y
++ default n
+
+ config EXCLUDE_BRK
+ bool
+diff -urN uClibc-0.9.27/extra/Configs/Config.m68k uClibc-0.9.27-uc0/extra/Configs/Config.m68k
+--- uClibc-0.9.27/extra/Configs/Config.m68k 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/extra/Configs/Config.m68k 2005-01-26 07:37:19.000000000 +0100
+@@ -17,9 +17,9 @@
+ bool
+ default y
+
+-config ARCH_CFLAGS
+- string
+- default "-Wa,--bitwise-or"
++# config ARCH_CFLAGS
++# string
++# default "-Wa,--bitwise-or"
+
+ config ARCH_LDFLAGS
+ string
+diff -urN uClibc-0.9.27/extra/Configs/Config.microblaze uClibc-0.9.27-uc0/extra/Configs/Config.microblaze
+--- uClibc-0.9.27/extra/Configs/Config.microblaze 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/extra/Configs/Config.microblaze 2005-01-26 07:37:19.000000000 +0100
+@@ -9,7 +9,7 @@
+ config HAVE_ELF
+ bool
+ select ARCH_HAS_NO_MMU
+- select ARCH_HAS_C_SYMBOL_PREFIX
++ select ARCH_BIG_ENDIAN
+ select HAVE_NO_SHARED
+ select ARCH_HAS_NO_LDSO
+ default y
+@@ -18,8 +18,8 @@
+ bool
+ default y
+
+-config ARCH_CFLAGS
+- string
++#config ARCH_CFLAGS
++# string
+
+ config ARCH_LDFLAGS
+ string
+@@ -27,7 +27,7 @@
+ config LIBGCC_CFLAGS
+ string
+
+-config CROSS
+- string
+- default "mb-"
++config HAVE_ELF
++ bool
++ default y
+
+diff -urN uClibc-0.9.27/extra/Configs/Config.sh uClibc-0.9.27-uc0/extra/Configs/Config.sh
+--- uClibc-0.9.27/extra/Configs/Config.sh 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/extra/Configs/Config.sh 2005-02-10 03:09:15.000000000 +0100
+@@ -58,7 +58,6 @@
+
+ config CONFIG_SH4
+ select ARCH_HAS_MMU
+- select FORCE_SHAREABLE_TEXT_SEGMENTS
+ bool "SH4"
+
+ config CONFIG_SH5
+diff -urN uClibc-0.9.27/extra/scripts/fix_includes.sh uClibc-0.9.27-uc0/extra/scripts/fix_includes.sh
+--- uClibc-0.9.27/extra/scripts/fix_includes.sh 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/extra/scripts/fix_includes.sh 2005-07-08 03:26:56.000000000 +0200
+@@ -51,8 +51,8 @@
+ HAS_MMU="y";
+ while [ -n "$1" ]; do
+ case $1 in
+- -k ) shift; if [ -n "$1" ]; then KERNEL_SOURCE=$1; shift; else usage; fi; ;;
+- -t ) shift; if [ -n "$1" ]; then TARGET_ARCH=$1; shift; else usage; fi; ;;
++ -k ) shift; if [ -n "$1" ]; then KERNEL_SOURCE="$1"; shift; else usage; fi; ;;
++ -t ) shift; if [ -n "$1" ]; then TARGET_ARCH="$1"; shift; else usage; fi; ;;
+ -n ) shift; HAS_MMU="n"; ;;
+ -* ) usage; ;;
+ * ) usage; ;;
+@@ -167,6 +167,11 @@
+ ln -fs $KERNEL_SOURCE/include/asm include/asm
+ fi;
+
++# 2.4 nommu targets may need include/asm-arch
++if [ "$HAS_MMU" != "y" ] && [ -d $KERNEL_SOURCE/include/asm-$TARGET_ARCH ]; then
++ ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm-$TARGET_ARCH
++fi
++
+
+ # Annoyingly, 2.6.x kernel headers also need an include/asm-generic/ directory
+ if [ $VERSION -eq 2 ] && [ $PATCHLEVEL -ge 6 ] ; then
+diff -urN uClibc-0.9.27/include/atomic.h uClibc-0.9.27-uc0/include/atomic.h
+--- uClibc-0.9.27/include/atomic.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/include/atomic.h 2006-01-16 07:46:31.000000000 +0100
+@@ -0,0 +1,261 @@
++/* Internal macros for atomic operations for GNU C Library.
++ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
++
++ 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. */
++
++#ifndef _ATOMIC_H
++#define _ATOMIC_H 1
++
++#include <stdlib.h>
++
++#include <bits/atomic.h>
++
++/* Wrapper macros to call pre_NN_post (mem, ...) where NN is the
++ bit width of *MEM. The calling macro puts parens around MEM
++ and following args. */
++#define __atomic_val_bysize(pre, post, mem, ...) \
++ ({ \
++ __typeof (*mem) __result; \
++ if (sizeof (*mem) == 1) \
++ __result = pre##_8_##post (mem, __VA_ARGS__); \
++ else if (sizeof (*mem) == 2) \
++ __result = pre##_16_##post (mem, __VA_ARGS__); \
++ else if (sizeof (*mem) == 4) \
++ __result = pre##_32_##post (mem, __VA_ARGS__); \
++ else if (sizeof (*mem) == 8) \
++ __result = pre##_64_##post (mem, __VA_ARGS__); \
++ else \
++ abort (); \
++ __result; \
++ })
++#define __atomic_bool_bysize(pre, post, mem, ...) \
++ ({ \
++ int __result; \
++ if (sizeof (*mem) == 1) \
++ __result = pre##_8_##post (mem, __VA_ARGS__); \
++ else if (sizeof (*mem) == 2) \
++ __result = pre##_16_##post (mem, __VA_ARGS__); \
++ else if (sizeof (*mem) == 4) \
++ __result = pre##_32_##post (mem, __VA_ARGS__); \
++ else if (sizeof (*mem) == 8) \
++ __result = pre##_64_##post (mem, __VA_ARGS__); \
++ else \
++ abort (); \
++ __result; \
++ })
++
++
++/* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL.
++ Return the old *MEM value. */
++#if !defined atomic_compare_and_exchange_val_acq \
++ && defined __arch_compare_and_exchange_val_32_acq
++# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
++ __atomic_val_bysize (__arch_compare_and_exchange_val,acq, \
++ mem, newval, oldval)
++#endif
++
++
++#ifndef atomic_compare_and_exchange_val_rel
++# define atomic_compare_and_exchange_val_rel(mem, newval, oldval) \
++ atomic_compare_and_exchange_val_acq (mem, newval, oldval)
++#endif
++
++
++/* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL.
++ Return zero if *MEM was changed or non-zero if no exchange happened. */
++#ifndef atomic_compare_and_exchange_bool_acq
++# ifdef __arch_compare_and_exchange_bool_32_acq
++# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
++ __atomic_bool_bysize (__arch_compare_and_exchange_bool,acq, \
++ mem, newval, oldval)
++# else
++# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
++ ({ /* Cannot use __oldval here, because macros later in this file might \
++ call this macro with __oldval argument. */ \
++ __typeof (oldval) __old = (oldval); \
++ atomic_compare_and_exchange_val_acq (mem, newval, __old) != __old; \
++ })
++# endif
++#endif
++
++
++#ifndef atomic_compare_and_exchange_bool_rel
++# define atomic_compare_and_exchange_bool_rel(mem, newval, oldval) \
++ atomic_compare_and_exchange_bool_acq (mem, newval, oldval)
++#endif
++
++
++/* Store NEWVALUE in *MEM and return the old value. */
++#ifndef atomic_exchange_acq
++# define atomic_exchange_acq(mem, newvalue) \
++ ({ __typeof (*(mem)) __oldval; \
++ __typeof (mem) __memp = (mem); \
++ __typeof (*(mem)) __value = (newvalue); \
++ \
++ do \
++ __oldval = (*__memp); \
++ while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
++ __value, \
++ __oldval),\
++ 0)); \
++ \
++ __oldval; })
++#endif
++
++#ifndef atomic_exchange_rel
++# define atomic_exchange_rel(mem, newvalue) atomic_exchange_acq (mem, newvalue)
++#endif
++
++
++/* Add VALUE to *MEM and return the old value of *MEM. */
++#ifndef atomic_exchange_and_add
++# define atomic_exchange_and_add(mem, value) \
++ ({ __typeof (*(mem)) __oldval; \
++ __typeof (mem) __memp = (mem); \
++ __typeof (*(mem)) __value = (value); \
++ \
++ do \
++ __oldval = (*__memp); \
++ while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
++ __oldval \
++ + __value,\
++ __oldval),\
++ 0)); \
++ \
++ __oldval; })
++#endif
++
++
++#ifndef atomic_add
++# define atomic_add(mem, value) (void) atomic_exchange_and_add ((mem), (value))
++#endif
++
++
++#ifndef atomic_increment
++# define atomic_increment(mem) atomic_add ((mem), 1)
++#endif
++
++
++#ifndef atomic_increment_val
++# define atomic_increment_val(mem) (atomic_exchange_and_add ((mem), 1) + 1)
++#endif
++
++
++/* Add one to *MEM and return true iff it's now zero. */
++#ifndef atomic_increment_and_test
++# define atomic_increment_and_test(mem) \
++ (atomic_exchange_and_add ((mem), 1) + 1 == 0)
++#endif
++
++
++#ifndef atomic_decrement
++# define atomic_decrement(mem) atomic_add ((mem), -1)
++#endif
++
++
++#ifndef atomic_decrement_val
++# define atomic_decrement_val(mem) (atomic_exchange_and_add ((mem), -1) - 1)
++#endif
++
++
++/* Subtract 1 from *MEM and return true iff it's now zero. */
++#ifndef atomic_decrement_and_test
++# define atomic_decrement_and_test(mem) \
++ (atomic_exchange_and_add ((mem), -1) == 1)
++#endif
++
++
++/* Decrement *MEM if it is > 0, and return the old value. */
++#ifndef atomic_decrement_if_positive
++# define atomic_decrement_if_positive(mem) \
++ ({ __typeof (*(mem)) __oldval; \
++ __typeof (mem) __memp = (mem); \
++ \
++ do \
++ { \
++ __oldval = *__memp; \
++ if (__builtin_expect (__oldval <= 0, 0)) \
++ break; \
++ } \
++ while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
++ __oldval \
++ - 1, \
++ __oldval),\
++ 0));\
++ __oldval; })
++#endif
++
++
++#ifndef atomic_add_negative
++# define atomic_add_negative(mem, value) \
++ ({ __typeof (value) __aan_value = (value); \
++ atomic_exchange_and_add (mem, __aan_value) < -__aan_value; })
++#endif
++
++
++#ifndef atomic_add_zero
++# define atomic_add_zero(mem, value) \
++ ({ __typeof (value) __aaz_value = (value); \
++ atomic_exchange_and_add (mem, __aaz_value) == -__aaz_value; })
++#endif
++
++
++#ifndef atomic_bit_set
++# define atomic_bit_set(mem, bit) \
++ (void) atomic_bit_test_set(mem, bit)
++#endif
++
++
++#ifndef atomic_bit_test_set
++# define atomic_bit_test_set(mem, bit) \
++ ({ __typeof (*(mem)) __oldval; \
++ __typeof (mem) __memp = (mem); \
++ __typeof (*(mem)) __mask = ((__typeof (*(mem))) 1 << (bit)); \
++ \
++ do \
++ __oldval = (*__memp); \
++ while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
++ __oldval \
++ | __mask, \
++ __oldval),\
++ 0)); \
++ \
++ __oldval & __mask; })
++#endif
++
++
++#ifndef atomic_full_barrier
++# define atomic_full_barrier() __asm ("" ::: "memory")
++#endif
++
++
++#ifndef atomic_read_barrier
++# define atomic_read_barrier() atomic_full_barrier ()
++#endif
++
++
++#ifndef atomic_write_barrier
++# define atomic_write_barrier() atomic_full_barrier ()
++#endif
++
++
++#ifndef atomic_delay
++# define atomic_delay() do { /* nothing */ } while (0)
++#endif
++
++#endif /* atomic.h */
+diff -urN uClibc-0.9.27/include/dlfcn.h uClibc-0.9.27-uc0/include/dlfcn.h
+--- uClibc-0.9.27/include/dlfcn.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/include/dlfcn.h 2005-01-26 07:37:19.000000000 +0100
+@@ -59,7 +59,7 @@
+ /* When any of the above functions fails, call this function
+ to return a string describing the error. Each call resets
+ the error string so that a following call returns null. */
+-extern char *dlerror (void) __THROW;
++extern const char *dlerror (void) __THROW;
+
+ #ifdef __USE_GNU
+ /* Structure containing information about object searched using
+diff -urN uClibc-0.9.27/include/elf.h uClibc-0.9.27-uc0/include/elf.h
+--- uClibc-0.9.27/include/elf.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/include/elf.h 2005-01-26 07:37:19.000000000 +0100
+@@ -2546,6 +2546,25 @@
+ #define R_V850_NUM 25
+
+
++//jari
++#define EM_XILINX_MICROBLAZE 0xbaab
++
++/* Microblaze Relocations */
++#define R_MICROBLAZE_NONE 0
++#define R_MICROBLAZE_32 1
++#define R_MICROBLAZE_32_PCREL 2
++#define R_MICROBLAZE_64_PCREL 3
++#define R_MICROBLAZE_32_PCREL_LO 4
++#define R_MICROBLAZE_64 5
++#define R_MICROBLAZE_32_LO 6
++#define R_MICROBLAZE_SRO32 7
++#define R_MICROBLAZE_SRW32 8
++#define R_MICROBLAZE_64_NONE 9
++#define R_MICROBLAZE_32_SYM_OP_SYM 10
++/* Keep this the last entry. */
++#define R_MICROBLAZE_NUM 11
++
++
+ #define R_H8_NONE 0
+ #define R_H8_DIR32 1
+ #define R_H8_DIR32_28 2
+diff -urN uClibc-0.9.27/include/features.h uClibc-0.9.27-uc0/include/features.h
+--- uClibc-0.9.27/include/features.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/include/features.h 2005-07-08 03:33:44.000000000 +0200
+@@ -365,6 +365,11 @@
+ extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+ /* This comes between the return type and function name in
+ * a function definition to make that definition weak. */
++#if __GNUC__ == 2
++# define weak_decl(name) __asm__(".weak " #name ";");
++#else
++# define weak_decl(name)
++#endif
+ # define weak_function __attribute__ ((weak))
+ # define weak_const_function __attribute__ ((weak, __const__))
+ /* Tacking on "\n\t#" to the section name makes gcc put it's bogus
+diff -urN uClibc-0.9.27/include/net/if_arp.h uClibc-0.9.27-uc0/include/net/if_arp.h
+--- uClibc-0.9.27/include/net/if_arp.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/include/net/if_arp.h 2005-01-26 07:37:19.000000000 +0100
+@@ -96,7 +96,7 @@
+ #define ARPHRD_ADAPT 264
+ #define ARPHRD_ROSE 270
+ #define ARPHRD_X25 271 /* CCITT X.25. */
+-#define ARPHDR_HWX25 272 /* Boards with X.25 in firmware. */
++#define ARPHRD_HWX25 272 /* Boards with X.25 in firmware. */
+ #define ARPHRD_PPP 512
+ #define ARPHRD_CISCO 513 /* Cisco HDLC. */
+ #define ARPHRD_HDLC ARPHRD_CISCO
+@@ -123,6 +123,7 @@
+ #define ARPHRD_FCPP 784 /* Point to point fibrechanel. */
+ #define ARPHRD_FCAL 785 /* Fibrechanel arbitrated loop. */
+ #define ARPHRD_FCPL 786 /* Fibrechanel public loop. */
++#define ARPHRD_FCPFABRIC 787 /* Fibrechanel fabric. */
+ #define ARPHRD_FCFABRIC 787 /* Fibrechanel fabric. */
+ #define ARPHRD_IEEE802_TR 800 /* Magic type ident for TR. */
+ #define ARPHRD_IEEE80211 801 /* IEEE 802.11. */
+diff -urN uClibc-0.9.27/include/net/if.h uClibc-0.9.27-uc0/include/net/if.h
+--- uClibc-0.9.27/include/net/if.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/include/net/if.h 2003-09-10 07:17:26.000000000 +0200
+@@ -75,8 +75,10 @@
+
+ IFF_PORTSEL = 0x2000, /* Can set media type. */
+ # define IFF_PORTSEL IFF_PORTSEL
+- IFF_AUTOMEDIA = 0x4000 /* Auto media select active. */
++ IFF_AUTOMEDIA = 0x4000, /* Auto media select active. */
+ # define IFF_AUTOMEDIA IFF_AUTOMEDIA
++ IFF_DYNAMIC = 0x8000 /* dialup device with changing addresses*/
++# define IFF_DYNAMIC IFF_DYNAMIC
+ };
+
+ /* The ifaddr structure contains information about one address of an
+diff -urN uClibc-0.9.27/include/netinet/in.h uClibc-0.9.27-uc0/include/netinet/in.h
+--- uClibc-0.9.27/include/netinet/in.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/include/netinet/in.h 2006-07-06 13:44:28.000000000 +0200
+@@ -79,6 +79,8 @@
+ #define IPPROTO_PIM IPPROTO_PIM
+ IPPROTO_COMP = 108, /* Compression Header Protocol. */
+ #define IPPROTO_COMP IPPROTO_COMP
++ IPPROTO_SCTP = 132, /* Stream Control Transmission Protocol. */
++#define IPPROTO_SCTP IPPROTO_SCTP
+ IPPROTO_RAW = 255, /* Raw IP packets. */
+ #define IPPROTO_RAW IPPROTO_RAW
+ IPPROTO_MAX
+diff -urN uClibc-0.9.27/include/stdint.h uClibc-0.9.27-uc0/include/stdint.h
+--- uClibc-0.9.27/include/stdint.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/include/stdint.h 2004-05-13 03:48:57.000000000 +0200
+@@ -238,7 +238,7 @@
+ # define UINTPTR_MAX (4294967295U)
+ # endif
+
+-#if !defined(__H8300H__) && !defined(__H8300S__)
++#if (__LONG_MAX__ != __LONG_LONG_MAX__) /* long long check */
+ /* Minimum for largest signed integral type. */
+ # define INTMAX_MIN (-__INT64_C(9223372036854775807)-1)
+ /* Maximum for largest signed integral type. */
+@@ -253,7 +253,7 @@
+ # define INTMAX_MAX (LONG_LONG_MAX)
+
+ /* Maximum for largest unsigned integral type. */
+-# define UINTMAX_MAX (LONG_LONG_MAX<<1+1)
++# define UINTMAX_MAX (LONG_LONG_MAX*2+1)
+ #endif
+
+ /* Limits of other integer types. */
+diff -urN uClibc-0.9.27/ldso/ldso/dl-startup.c uClibc-0.9.27-uc0/ldso/ldso/dl-startup.c
+--- uClibc-0.9.27/ldso/ldso/dl-startup.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/ldso/ldso/dl-startup.c 2005-02-10 06:07:27.000000000 +0100
+@@ -282,7 +282,7 @@
+ SEND_STDERR("scanning DYNAMIC section\n");
+ #endif
+ tpnt->dynamic_addr = dpnt;
+-#ifdef __mips__
++#if defined(__mips__) || defined(__sh__)
+ /* MIPS cannot call functions here, must inline */
+ __dl_parse_dynamic_info(dpnt, tpnt->dynamic_info, NULL);
+ #else
+diff -urN uClibc-0.9.27/ldso/ldso/ldso.c uClibc-0.9.27-uc0/ldso/ldso/ldso.c
+--- uClibc-0.9.27/ldso/ldso/ldso.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/ldso/ldso/ldso.c 2006-02-27 08:31:07.000000000 +0100
+@@ -71,8 +71,8 @@
+ {
+ }
+
+-static unsigned char *_dl_malloc_addr = 0; /* Lets _dl_malloc use the already allocated memory page */
+-static unsigned char *_dl_mmap_zero = 0; /* Also used by _dl_malloc */
++unsigned char *_dl_malloc_addr = 0; /* Lets _dl_malloc use the already allocated memory page */
++unsigned char *_dl_mmap_zero = 0; /* Also used by _dl_malloc */
+
+ #if defined (__SUPPORT_LD_DEBUG__)
+ static void debug_fini (int status, void *arg)
+diff -urN uClibc-0.9.27/ldso/ldso/Makefile uClibc-0.9.27-uc0/ldso/ldso/Makefile
+--- uClibc-0.9.27/ldso/ldso/Makefile 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/ldso/ldso/Makefile 2005-01-26 07:37:20.000000000 +0100
+@@ -56,7 +56,7 @@
+ OBJS=$(AOBJS) $(COBJS)
+
+ ifneq ($(strip $(SUPPORT_LD_DEBUG)),y)
+-LDFLAGS+=-s
++# LDFLAGS+=-s
+ endif
+
+ ifeq ($(strip $(SUPPORT_LD_DEBUG)),y)
+@@ -70,6 +70,9 @@
+ #This stuff will not work with -fomit-frame-pointer
+ XXFLAGS := $(XXFLAGS:-fomit-frame-pointer=)
+
++#This stuff will not work with -fomit-frame-pointer
++XXFLAGS := $(XXFLAGS:-fomit-frame-pointer=)
++
+ all: lib
+
+ lib:: $(OBJS) $(DLINK_OBJS)
+diff -urN uClibc-0.9.27/ldso/libdl/libdl.c uClibc-0.9.27-uc0/ldso/libdl/libdl.c
+--- uClibc-0.9.27/ldso/libdl/libdl.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/ldso/libdl/libdl.c 2005-01-26 12:53:44.000000000 +0100
+@@ -547,7 +547,7 @@
+ return do_dlclose(vhandle, 1);
+ }
+
+-char *dlerror(void)
++const char *dlerror(void)
+ {
+ const char *retval;
+
+diff -urN uClibc-0.9.27/libc/inet/rpc/rpc_thread.c uClibc-0.9.27-uc0/libc/inet/rpc/rpc_thread.c
+--- uClibc-0.9.27/libc/inet/rpc/rpc_thread.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/inet/rpc/rpc_thread.c 2005-07-08 03:33:44.000000000 +0200
+@@ -35,6 +35,7 @@
+ }
+
+
++weak_decl(__pthread_once)
+ extern int weak_function __pthread_once (pthread_once_t *__once_control,
+ void (*__init_routine) (void));
+
+diff -urN uClibc-0.9.27/libc/misc/assert/__assert.c uClibc-0.9.27-uc0/libc/misc/assert/__assert.c
+--- uClibc-0.9.27/libc/misc/assert/__assert.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/misc/assert/__assert.c 2005-01-26 07:37:22.000000000 +0100
+@@ -31,6 +31,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
++#include <syslog.h>
+ #include <bits/uClibc_uintmaxtostr.h>
+
+ /* Get the prototype from assert.h as a double-check. */
+@@ -65,6 +66,19 @@
+ ((function == NULL) ? "?function?" : function),
+ assertion
+ );
++ syslog(LOG_ERR,
++#if 0
++ /* TODO: support program_name like glibc? */
++ "%s: %s: %d: %s: Assertion `%s' failed.\n", program_name,
++#else
++ "%s: %d: %s: Assertion `%s' failed.\n",
++#endif
++ filename,
++ linenumber,
++ /* Function name isn't available with some compilers. */
++ ((function == NULL) ? "?function?" : function),
++ assertion
++ );
+ }
+ abort();
+ }
+diff -urN uClibc-0.9.27/libc/misc/internals/__errno_location.c uClibc-0.9.27-uc0/libc/misc/internals/__errno_location.c
+--- uClibc-0.9.27/libc/misc/internals/__errno_location.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/misc/internals/__errno_location.c 2005-07-08 03:33:44.000000000 +0200
+@@ -1,6 +1,7 @@
+ #include <errno.h>
+ #undef errno
+
++weak_decl(__errno_location)
+ int * weak_const_function __errno_location (void)
+ {
+ return &errno;
+diff -urN uClibc-0.9.27/libc/misc/internals/__h_errno_location.c uClibc-0.9.27-uc0/libc/misc/internals/__h_errno_location.c
+--- uClibc-0.9.27/libc/misc/internals/__h_errno_location.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/misc/internals/__h_errno_location.c 2005-07-08 03:33:44.000000000 +0200
+@@ -3,6 +3,7 @@
+ #include <netdb.h>
+ #undef h_errno
+
++weak_decl(__h_errno_location)
+ int * weak_const_function __h_errno_location (void)
+ {
+ return &h_errno;
+diff -urN uClibc-0.9.27/libc/misc/internals/__uClibc_main.c uClibc-0.9.27-uc0/libc/misc/internals/__uClibc_main.c
+--- uClibc-0.9.27/libc/misc/internals/__uClibc_main.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/misc/internals/__uClibc_main.c 2006-04-24 15:45:17.000000000 +0200
+@@ -33,13 +33,18 @@
+ * Prototypes.
+ */
+ extern int main(int argc, char **argv, char **envp);
++weak_decl(_stdio_init)
++weak_decl(__errno_location)
++weak_decl(__h_errno_location)
+ extern void weak_function _stdio_init(void);
+ extern int *weak_const_function __errno_location(void);
+ extern int *weak_const_function __h_errno_location(void);
+ #ifdef __UCLIBC_HAS_LOCALE__
++weak_decl(_locale_init)
+ extern void weak_function _locale_init(void);
+ #endif
+ #ifdef __UCLIBC_HAS_THREADS__
++weak_decl(__pthread_initialize_minimal)
+ extern void weak_function __pthread_initialize_minimal(void);
+ #endif
+
+@@ -66,6 +71,7 @@
+ extern int __libc_fcntl(int fd, int cmd, ...);
+ extern int __libc_open(const char *file, int flags, ...);
+
++#ifdef __ARCH_HAS_MMU__
+ static void __check_one_fd(int fd, int mode)
+ {
+ /* Check if the specified fd is already open */
+@@ -103,6 +109,7 @@
+ }
+ return 1;
+ }
++#endif
+
+
+ /* __uClibc_init completely initialize uClibc so it is ready to use.
+diff -urN uClibc-0.9.27/libc/misc/locale/locale.c uClibc-0.9.27-uc0/libc/misc/locale/locale.c
+--- uClibc-0.9.27/libc/misc/locale/locale.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/misc/locale/locale.c 2005-07-08 03:33:45.000000000 +0200
+@@ -1376,11 +1376,13 @@
+
+ #ifdef __UCLIBC_HAS_THREADS__
+
++weak_decl(__curlocale)
+ __locale_t weak_const_function __curlocale(void)
+ {
+ return __curlocale_var; /* This is overriden by the thread version. */
+ }
+
++weak_decl(__curlocale_set)
+ __locale_t weak_function __curlocale_set(__locale_t newloc)
+ {
+ __locale_t oldloc = __curlocale_var;
+diff -urN uClibc-0.9.27/libc/misc/regex/regex.c uClibc-0.9.27-uc0/libc/misc/regex/regex.c
+--- uClibc-0.9.27/libc/misc/regex/regex.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/misc/regex/regex.c 2005-07-08 03:33:45.000000000 +0200
+@@ -7955,12 +7955,14 @@
+ /* BSD has one and only one pattern buffer. */
+ static struct re_pattern_buffer re_comp_buf;
+
+-char *
+ #ifdef _LIBC
+ /* Make these definitions weak in libc, so POSIX programs can redefine
+ these names if they don't use our functions, and still use
+ regcomp/regexec below without link errors. */
+-weak_function
++weak_decl(re_comp)
++char *weak_function
++#else
++char *
+ #endif
+ re_comp (s)
+ const char *s;
+@@ -8009,9 +8011,11 @@
+ }
+
+
+-int
+ #ifdef _LIBC
+-weak_function
++weak_decl(re_exec)
++int weak_function
++#else
++int
+ #endif
+ re_exec (s)
+ const char *s;
+diff -urN uClibc-0.9.27/libc/misc/time/time.c uClibc-0.9.27-uc0/libc/misc/time/time.c
+--- uClibc-0.9.27/libc/misc/time/time.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/misc/time/time.c 2005-01-26 07:37:23.000000000 +0100
+@@ -602,7 +602,7 @@
+ {
+ long sec;
+ int i, isdst, isleap, day, day0, monlen, mday;
+- int oday; /* Note: oday can be uninitialized. */
++ int oday=0; /* Note: oday can be uninitialized. */
+
+ isdst = 0;
+ if (r[1].tzname[0] != 0) {
+@@ -2003,7 +2003,7 @@
+ {
+ register int *p;
+ time_t t1, t, v;
+- int wday; /* Note: wday can be uninitialized. */
++ int wday=0; /* Note: wday can be uninitialized. */
+
+ {
+ register const uint16_t *vp;
+diff -urN uClibc-0.9.27/libc/misc/wchar/wchar.c uClibc-0.9.27-uc0/libc/misc/wchar/wchar.c
+--- uClibc-0.9.27/libc/misc/wchar/wchar.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/misc/wchar/wchar.c 2005-07-08 03:33:45.000000000 +0200
+@@ -1274,6 +1274,7 @@
+ return 0; /* No matching codeset! */
+ }
+
++weak_decl(iconv_open)
+ iconv_t weak_function iconv_open(const char *tocode, const char *fromcode)
+ {
+ register _UC_iconv_t *px;
+@@ -1296,6 +1297,7 @@
+ return (iconv_t)(-1);
+ }
+
++weak_decl(iconv_close)
+ int weak_function iconv_close(iconv_t cd)
+ {
+ free(cd);
+@@ -1303,6 +1305,7 @@
+ return 0;
+ }
+
++weak_decl(iconv)
+ size_t weak_function iconv(iconv_t cd, char **__restrict inbuf,
+ size_t *__restrict inbytesleft,
+ char **__restrict outbuf,
+diff -urN uClibc-0.9.27/libc/stdio/Makefile uClibc-0.9.27-uc0/libc/stdio/Makefile
+--- uClibc-0.9.27/libc/stdio/Makefile 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/stdio/Makefile 2005-07-14 07:40:58.000000000 +0200
+@@ -130,6 +130,16 @@
+ $(CC) $(CFLAGS) -c $< -o $@
+ $(STRIPTOOL) -x -R .note -R .comment $@
+
++ifeq ($(TARGET_m68k),y)
++# The old gcc-2.95.3 m68k-elf compiler (and probably quite a few newer
++# versions) have an optimization bug that occassionaly produces a compiler
++# internal error. To work around this reduce optimization to -O0 for the
++# _fpmaxtostr.o.
++_fpmaxtostr.o: _fpmaxtostr.c
++ $(CC) $(CFLAGS) -O0 -c $< -o $@
++ $(STRIPTOOL) -x -R .note -R .comment $@
++endif
++
+ %_unlocked.o : %.c
+ $(CC) $(CFLAGS) -D__DO_UNLOCKED -c $< -o $@
+ $(STRIPTOOL) -x -R .note -R .comment $@
+diff -urN uClibc-0.9.27/libc/stdio/scanf.c uClibc-0.9.27-uc0/libc/stdio/scanf.c
+--- uClibc-0.9.27/libc/stdio/scanf.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/stdio/scanf.c 2005-07-08 06:39:35.000000000 +0200
+@@ -237,7 +237,9 @@
+ f.__user_locking = 1; /* Set user locking. */
+ __stdio_init_mutex(&f.__lock);
+ #endif
++#ifdef __STDIO_HAS_OPENLIST
+ f.__nextopen = NULL;
++#endif
+
+ /* Set these last since __bufgetc initialization depends on
+ * __user_locking and only gets set if user locking is on. */
+@@ -284,7 +286,9 @@
+ f.f.__user_locking = 1; /* Set user locking. */
+ __stdio_init_mutex(&f.f.__lock);
+ #endif
++#ifdef __STDIO_HAS_OPENLIST
+ f.f.__nextopen = NULL;
++#endif
+
+ return vfscanf(&f.f, fmt, ap);
+ }
+@@ -415,7 +419,9 @@
+ f.__user_locking = 1; /* Set user locking. */
+ __stdio_init_mutex(&f.__lock);
+ #endif
++#ifdef __STDIO_HAS_OPENLIST
+ f.__nextopen = NULL;
++#endif
+
+ return vfwscanf(&f, format, arg);
+ }
+diff -urN uClibc-0.9.27/libc/stdio/vasprintf.c uClibc-0.9.27-uc0/libc/stdio/vasprintf.c
+--- uClibc-0.9.27/libc/stdio/vasprintf.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/stdio/vasprintf.c 2005-07-08 03:32:57.000000000 +0200
+@@ -17,6 +17,27 @@
+ #warning Skipping vasprintf since no vsnprintf!
+ #else
+
++/**********************************************************************/
++/* Deal with pre-C99 compilers. */
++
++#ifndef va_copy
++
++#ifdef __va_copy
++#define va_copy(A,B) __va_copy(A,B)
++#else
++ /* TODO -- maybe create a bits/vacopy.h for arch specific versions
++ * to ensure we get the right behavior? Either that or fall back
++ * on the portable (but costly in size) method of using a va_list *.
++ * That means a pointer derefs in the va_arg() invocations... */
++#warning Neither va_copy (C99/SUSv3) or __va_copy is defined. Using a simple copy instead. But you should really check that this is appropriate...
++ /* the glibc manual suggests that this will usually suffice when
++ __va_copy doesn't exist. */
++#define va_copy(A,B) A = B
++#endif
++
++#endif /* va_copy */
++/**********************************************************************/
++
+ int vasprintf(char **__restrict buf, const char * __restrict format,
+ va_list arg)
+ {
+diff -urN uClibc-0.9.27/libc/stdio/vdprintf.c uClibc-0.9.27-uc0/libc/stdio/vdprintf.c
+--- uClibc-0.9.27/libc/stdio/vdprintf.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/stdio/vdprintf.c 2005-07-08 06:39:35.000000000 +0200
+@@ -45,7 +45,9 @@
+ f.__user_locking = 1; /* Set user locking. */
+ __stdio_init_mutex(&f.__lock);
+ #endif
++#ifdef __STDIO_HAS_OPENLIST
+ f.__nextopen = NULL;
++#endif
+
+ rv = vfprintf(&f, format, arg);
+
+diff -urN uClibc-0.9.27/libc/stdio/vsnprintf.c uClibc-0.9.27-uc0/libc/stdio/vsnprintf.c
+--- uClibc-0.9.27/libc/stdio/vsnprintf.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/stdio/vsnprintf.c 2005-07-08 06:39:35.000000000 +0200
+@@ -43,7 +43,9 @@
+ f.__user_locking = 1; /* Set user locking. */
+ __stdio_init_mutex(&f.__lock);
+ #endif
++#ifdef __STDIO_HAS_OPENLIST
+ f.__nextopen = NULL;
++#endif
+
+ if (size > SIZE_MAX - (size_t) buf) {
+ size = SIZE_MAX - (size_t) buf;
+@@ -111,7 +113,9 @@
+ f.f.__user_locking = 1; /* Set user locking. */
+ __stdio_init_mutex(&f.f.__lock);
+ #endif
++#ifdef __STDIO_HAS_OPENLIST
+ f.f.__nextopen = NULL;
++#endif
+
+ rv = vfprintf((FILE *) &f, format, arg);
+ if (size) {
+@@ -195,7 +199,9 @@
+ f.__user_locking = 1; /* Set user locking. */
+ __stdio_init_mutex(&f.__lock);
+ #endif
++#ifdef __STDIO_HAS_OPENLIST
+ f.__nextopen = NULL;
++#endif
+
+ rv = vfprintf(&f, format, arg);
+
+diff -urN uClibc-0.9.27/libc/stdlib/atexit.c uClibc-0.9.27-uc0/libc/stdlib/atexit.c
+--- uClibc-0.9.27/libc/stdlib/atexit.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/stdlib/atexit.c 2006-05-25 16:01:12.000000000 +0200
+@@ -32,6 +32,9 @@
+ * August 2002 Erik Andersen
+ * Added locking so atexit and friends can be thread safe
+ *
++ * August 2005 Stephen Warren
++ * Added __cxa_atexit and __cxa_finalize support
++ *
+ */
+
+ #define _GNU_SOURCE
+@@ -39,7 +42,7 @@
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <errno.h>
+-
++#include <atomic.h>
+
+ #ifdef __UCLIBC_HAS_THREADS__
+ #include <pthread.h>
+@@ -54,9 +57,12 @@
+
+ typedef void (*aefuncp) (void); /* atexit function pointer */
+ typedef void (*oefuncp) (int, void *); /* on_exit function pointer */
++typedef void (*cxaefuncp) (void *); /* __cxa_atexit function pointer */
+ typedef enum {
+- ef_atexit,
+- ef_on_exit
++ ef_free,
++ ef_in_use,
++ ef_on_exit,
++ ef_cxa_atexit
+ } ef_type; /* exit function types */
+
+ /* this is in the L_exit object */
+@@ -67,13 +73,21 @@
+ extern int __exit_count;
+ extern void __exit_handler(int);
+ struct exit_function {
+- ef_type type; /* ef_atexit or ef_on_exit */
++ /*
++ * 'type' should be of type of the 'enum ef_type' above but since we
++ * need this element in an atomic operation we have to use 'long int'.
++ */
++ long int type; /* enum ef_type */
+ union {
+- aefuncp atexit;
+- struct {
+- oefuncp func;
+- void *arg;
+- } on_exit;
++ struct {
++ oefuncp func;
++ void *arg;
++ } on_exit;
++ struct {
++ cxaefuncp func;
++ void *arg;
++ void* dso_handle;
++ } cxa_atexit;
+ } funcs;
+ };
+ #ifdef __UCLIBC_DYNAMIC_ATEXIT__
+@@ -81,46 +95,41 @@
+ #else
+ extern struct exit_function __exit_function_table[__UCLIBC_MAX_ATEXIT];
+ #endif
++extern struct exit_function *__new_exitfn (void);
+
+-#ifdef L_atexit
+- /*
++/* this is in the L___cxa_atexit object */
++extern int __cxa_atexit (cxaefuncp, void *arg, void *dso_handle);
++
++
++/* remove old_atexit after 0.9.29 */
++#if defined(L_atexit) || defined(L_old_atexit)
++extern void *__dso_handle __attribute__ ((__weak__));
++
++/*
+ * register a function to be called at normal program termination
+ * (the registered function takes no arguments)
+- */
+-int atexit(aefuncp func)
++ */
++#ifdef L_atexit
++int attribute_hidden atexit(aefuncp func)
++#else
++int old_atexit(aefuncp func)
++#endif
+ {
+- struct exit_function *efp;
+-
+- LOCK;
+- if (func) {
+-#ifdef __UCLIBC_DYNAMIC_ATEXIT__
+- /* If we are out of function table slots, make some more */
+- if (__exit_slots < __exit_count+1) {
+- efp=realloc(__exit_function_table,
+- (__exit_slots+20)*sizeof(struct exit_function));
+- if (efp==NULL) {
+- UNLOCK;
+- __set_errno(ENOMEM);
+- return -1;
+- }
+- __exit_function_table = efp;
+- __exit_slots+=20;
+- }
++ /*
++ * glibc casts aefuncp to cxaefuncp.
++ * This seems dodgy, but I guess callling a function with more
++ * parameters than it needs will work everywhere?
++ */
++#ifdef ARCH_HAS_MMU
++ return __cxa_atexit((cxaefuncp)func, NULL,
++ &__dso_handle == NULL ? NULL : __dso_handle);
+ #else
+- if (__exit_count >= __UCLIBC_MAX_ATEXIT) {
+- UNLOCK;
+- __set_errno(ENOMEM);
+- return -1;
+- }
++ return __cxa_atexit((cxaefuncp)func, NULL, NULL);
+ #endif
+- __exit_cleanup = __exit_handler; /* enable cleanup */
+- efp = &__exit_function_table[__exit_count++];
+- efp->type = ef_atexit;
+- efp->funcs.atexit = func;
+- }
+- UNLOCK;
+- return 0;
+ }
++#ifndef L_atexit
++weak_alias(old_atexit,atexit);
++#endif
+ #endif
+
+ #ifdef L_on_exit
+@@ -133,41 +142,92 @@
+ int on_exit(oefuncp func, void *arg)
+ {
+ struct exit_function *efp;
++
++ if (func == NULL) {
++ return 0;
++ }
+
+- LOCK;
+- if (func) {
+-#ifdef __UCLIBC_DYNAMIC_ATEXIT__
+- /* If we are out of function table slots, make some more */
+- if (__exit_slots < __exit_count+1) {
+- efp=realloc(__exit_function_table,
+- (__exit_slots+20)*sizeof(struct exit_function));
+- if (efp==NULL) {
+- UNLOCK;
+- __set_errno(ENOMEM);
+- return -1;
+- }
+- __exit_function_table=efp;
+- __exit_slots+=20;
+- }
+-#else
+- if (__exit_count >= __UCLIBC_MAX_ATEXIT) {
+- UNLOCK;
+- __set_errno(ENOMEM);
+- return -1;
+- }
++ efp = __new_exitfn();
++ if (efp == NULL) {
++ return -1;
++ }
++
++ efp->funcs.on_exit.func = func;
++ efp->funcs.on_exit.arg = arg;
++ /* assign last for thread safety, since we're now unlocked */
++ efp->type = ef_on_exit;
++
++ return 0;
++}
+ #endif
+
+- __exit_cleanup = __exit_handler; /* enable cleanup */
+- efp = &__exit_function_table[__exit_count++];
+- efp->type = ef_on_exit;
+- efp->funcs.on_exit.func = func;
+- efp->funcs.on_exit.arg = arg;
++#ifdef L___cxa_atexit
++extern int __cxa_atexit (cxaefuncp func, void *arg, void *dso_handle)
++{
++ struct exit_function *efp;
++
++ if (func == NULL) {
++ return 0;
+ }
+- UNLOCK;
++
++ efp = __new_exitfn();
++ if (efp == NULL) {
++ return -1;
++ }
++
++ efp->funcs.cxa_atexit.func = func;
++ efp->funcs.cxa_atexit.arg = arg;
++ efp->funcs.cxa_atexit.dso_handle = dso_handle;
++ /* assign last for thread safety, since we're now unlocked */
++ efp->type = ef_cxa_atexit;
++
+ return 0;
+ }
+ #endif
+
++#ifdef L___cxa_finalize
++/*
++ * If D is non-NULL, call all functions registered with `__cxa_atexit'
++ * with the same dso handle. Otherwise, if D is NULL, call all of the
++ * registered handlers.
++ */
++void __cxa_finalize (void *dso_handle)
++{
++ struct exit_function *efp;
++ int exit_count_snapshot = __exit_count;
++
++ /* In reverse order */
++ while (exit_count_snapshot) {
++ efp = &__exit_function_table[--exit_count_snapshot];
++
++ /*
++ * We check dso_handle match before we verify the type of the union entry.
++ * However, the atomic_exchange will validate that we were really "allowed"
++ * to read dso_handle...
++ */
++ if ((dso_handle == NULL || dso_handle == efp->funcs.cxa_atexit.dso_handle)
++ /* We don't want to run this cleanup more than once. */
++ && !atomic_compare_and_exchange_bool_acq(&efp->type, ef_free, ef_cxa_atexit)
++ ) {
++ /* glibc passes status (0) too, but that's not in the prototype */
++ (*efp->funcs.cxa_atexit.func)(efp->funcs.cxa_atexit.arg);
++ }
++ }
++
++#if 0 /* haven't looked into this yet... */
++ /*
++ * Remove the registered fork handlers. We do not have to
++ * unregister anything if the program is going to terminate anyway.
++ */
++#ifdef UNREGISTER_ATFORK
++ if (d != NULL) {
++ UNREGISTER_ATFORK (d);
++ }
++#endif
++#endif
++}
++#endif
++
+ #ifdef L___exit_handler
+ int __exit_count = 0; /* Number of registered exit functions */
+ #ifdef __UCLIBC_DYNAMIC_ATEXIT__
+@@ -177,6 +237,45 @@
+ struct exit_function __exit_function_table[__UCLIBC_MAX_ATEXIT];
+ #endif
+
++/*
++ * Find and return a new exit_function pointer, for atexit,
++ * onexit and __cxa_atexit to initialize
++ */
++struct exit_function *__new_exitfn(void)
++{
++ struct exit_function *efp;
++
++ LOCK;
++
++#ifdef __UCLIBC_DYNAMIC_ATEXIT__
++ /* If we are out of function table slots, make some more */
++ if (__exit_slots < __exit_count+1) {
++ efp=realloc(__exit_function_table,
++ (__exit_slots+20)*sizeof(struct exit_function));
++ if (efp == NULL) {
++ UNLOCK;
++ __set_errno(ENOMEM);
++ return 0;
++ }
++ __exit_function_table = efp;
++ __exit_slots += 20;
++ }
++#else
++ if (__exit_count >= __UCLIBC_MAX_ATEXIT) {
++ UNLOCK;
++ __set_errno(ENOMEM);
++ return 0;
++ }
++#endif
++
++ __exit_cleanup = __exit_handler; /* enable cleanup */
++ efp = &__exit_function_table[__exit_count++];
++ efp->type = ef_in_use;
++
++ UNLOCK;
++
++ return efp;
++}
+
+ /*
+ * Handle the work of executing the registered exit functions
+@@ -196,11 +295,12 @@
+ (efp->funcs.on_exit.func) (status, efp->funcs.on_exit.arg);
+ }
+ break;
+- case ef_atexit:
+- if (efp->funcs.atexit) {
+- (efp->funcs.atexit) ();
+- }
+- break;
++ case ef_cxa_atexit:
++ if (efp->funcs.cxa_atexit.func) {
++ /* glibc passes status too, but that's not in the prototype */
++ (efp->funcs.cxa_atexit.func) (efp->funcs.cxa_atexit.arg);
++ }
++ break;
+ }
+ }
+ #ifdef __UCLIBC_DYNAMIC_ATEXIT__
+@@ -212,6 +312,7 @@
+ #endif
+
+ #ifdef L_exit
++weak_decl(_stdio_term)
+ extern void weak_function _stdio_term(void);
+ void (*__exit_cleanup) (int) = 0;
+ #ifdef __UCLIBC_HAS_THREADS__
+diff -urN uClibc-0.9.27/libc/stdlib/bsd_getpt.c uClibc-0.9.27-uc0/libc/stdlib/bsd_getpt.c
+--- uClibc-0.9.27/libc/stdlib/bsd_getpt.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/stdlib/bsd_getpt.c 2004-06-21 01:49:19.000000000 +0200
+@@ -35,7 +35,7 @@
+
+ /* Letters indicating the position within a series. */
+ #ifndef PTYNAME2
+-#define PTYNAME2 "0123456789abcdefghijklmnopqrstuv";
++#define PTYNAME2 "0123456789abcdefghijklmnopqrstuv"
+ #endif
+ const char _ptyname2[] = PTYNAME2;
+
+diff -urN uClibc-0.9.27/libc/stdlib/getpt.c uClibc-0.9.27-uc0/libc/stdlib/getpt.c
+--- uClibc-0.9.27/libc/stdlib/getpt.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/stdlib/getpt.c 2004-06-21 01:49:19.000000000 +0200
+@@ -82,6 +82,8 @@
+ close (fd);
+ #if !defined __UNIX98PTY_ONLY__
+ have_no_dev_ptmx = 1;
++#else
++ return -1;
+ #endif
+ #endif
+ }
+@@ -102,8 +104,8 @@
+ }
+
+ #if !defined __UNIX98PTY_ONLY__
+-# define PTYNAME1 "pqrstuvwxyzabcde";
+-# define PTYNAME2 "0123456789abcdef";
++# define PTYNAME1 "pqrstuvwxyzabcde"
++# define PTYNAME2 "0123456789abcdef"
+
+ # define __getpt __bsd_getpt
+ # include "bsd_getpt.c"
+diff -urN uClibc-0.9.27/libc/stdlib/Makefile uClibc-0.9.27-uc0/libc/stdlib/Makefile
+--- uClibc-0.9.27/libc/stdlib/Makefile 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/stdlib/Makefile 2006-02-27 08:31:09.000000000 +0100
+@@ -79,7 +79,10 @@
+ # wcstod wcstof wcstold
+
+ MSRC2 = atexit.c
+-MOBJ2 = atexit.o on_exit.o __exit_handler.o exit.o
++MOBJ2 = on_exit.o __cxa_atexit.o __cxa_finalize.o __exit_handler.o exit.o
++ifeq ($(COMPAT_ATEXIT),y)
++MOBJ2 += old_atexit.o
++endif
+
+ CSRC = abort.c getenv.c mkdtemp.c mktemp.c realpath.c mkstemp.c mkstemp64.c \
+ rand.c random.c random_r.c setenv.c system.c div.c ldiv.c lldiv.c \
+@@ -117,7 +120,7 @@
+ $(CC) $(CFLAGS) -DL_$* -D__UCLIBC_DO_XLOCALE $< -c -o $*.o
+ $(STRIPTOOL) -x -R .note -R .comment $*.o
+
+-$(MOBJ2): $(MSRC2)
++$(MOBJ2) atexit.o: $(MSRC2)
+ $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+ $(STRIPTOOL) -x -R .note -R .comment $*.o
+
+diff -urN uClibc-0.9.27/libc/stdlib/malloc-simple/alloc.c uClibc-0.9.27-uc0/libc/stdlib/malloc-simple/alloc.c
+--- uClibc-0.9.27/libc/stdlib/malloc-simple/alloc.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/stdlib/malloc-simple/alloc.c 2005-07-08 03:33:45.000000000 +0200
+@@ -101,6 +101,7 @@
+ #endif
+
+ #ifdef L_free
++weak_decl(__libc_free_aligned)
+ extern int weak_function __libc_free_aligned(void *ptr);
+ void free(void *ptr)
+ {
+@@ -123,7 +124,7 @@
+ #ifdef L_memalign
+ #ifdef __UCLIBC_HAS_THREADS__
+ #include <pthread.h>
+-pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
++static pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+ # define LOCK __pthread_mutex_lock(&__malloc_lock)
+ # define UNLOCK __pthread_mutex_unlock(&__malloc_lock);
+ #else
+diff -urN uClibc-0.9.27/libc/stdlib/malloc-standard/free.c uClibc-0.9.27-uc0/libc/stdlib/malloc-standard/free.c
+--- uClibc-0.9.27/libc/stdlib/malloc-standard/free.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/stdlib/malloc-standard/free.c 2006-02-27 08:31:09.000000000 +0100
+@@ -16,6 +16,7 @@
+
+ #include "malloc.h"
+
++static int __malloc_trim(size_t pad, mstate av);
+
+ /* ------------------------- malloc_trim -------------------------
+ malloc_trim(size_t pad);
+diff -urN uClibc-0.9.27/libc/stdlib/stdlib.c uClibc-0.9.27-uc0/libc/stdlib/stdlib.c
+--- uClibc-0.9.27/libc/stdlib/stdlib.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/stdlib/stdlib.c 2005-01-26 07:37:23.000000000 +0100
+@@ -36,7 +36,6 @@
+ #define _GNU_SOURCE
+ #include <limits.h>
+ #include <stdint.h>
+-#include <inttypes.h>
+ #include <ctype.h>
+ #include <errno.h>
+ #include <assert.h>
+@@ -50,7 +49,10 @@
+ #define abs __ignore_abs
+ #endif
+ #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
++#define strtoimax __ignore_strtoimax
++#define strtoumax __ignore_strtoumax
+ #define llabs __ignore_llabs
++#define imaxabs __ignore_imaxabs
+ #define atoll __ignore_atoll
+ #define strtoll __ignore_strtoll
+ #define strtoull __ignore_strtoull
+@@ -62,6 +64,7 @@
+ #define wcstoull_l __ignore_wcstoull_l
+ #endif
+
++#include <inttypes.h>
+ #include <stdlib.h>
+ #include <locale.h>
+
+@@ -117,6 +120,9 @@
+ #endif
+ #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
+ #undef llabs
++#undef imaxabs
++#undef strtoimax
++#undef strtoumax
+ #undef atoll
+ #undef strtoll
+ #undef strtoull
+@@ -543,7 +549,7 @@
+
+ #if defined(L__stdlib_strto_ll) || defined(L__stdlib_strto_ll_l)
+
+-#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
++#if defined(ULLONG_MAX) // && (LLONG_MAX > LONG_MAX)
+
+ #if defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l)
+ #define _stdlib_strto_ll _stdlib_wcsto_ll
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/alpha/bits/atomic.h uClibc-0.9.27-uc0/libc/sysdeps/linux/alpha/bits/atomic.h
+--- uClibc-0.9.27/libc/sysdeps/linux/alpha/bits/atomic.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/alpha/bits/atomic.h 2006-01-16 07:46:31.000000000 +0100
+@@ -0,0 +1,369 @@
++/* Copyright (C) 2003 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 <stdint.h>
++
++typedef int8_t atomic8_t;
++typedef uint8_t uatomic8_t;
++typedef int_fast8_t atomic_fast8_t;
++typedef uint_fast8_t uatomic_fast8_t;
++
++typedef int16_t atomic16_t;
++typedef uint16_t uatomic16_t;
++typedef int_fast16_t atomic_fast16_t;
++typedef uint_fast16_t uatomic_fast16_t;
++
++typedef int32_t atomic32_t;
++typedef uint32_t uatomic32_t;
++typedef int_fast32_t atomic_fast32_t;
++typedef uint_fast32_t uatomic_fast32_t;
++
++typedef int64_t atomic64_t;
++typedef uint64_t uatomic64_t;
++typedef int_fast64_t atomic_fast64_t;
++typedef uint_fast64_t uatomic_fast64_t;
++
++typedef intptr_t atomicptr_t;
++typedef uintptr_t uatomicptr_t;
++typedef intmax_t atomic_max_t;
++typedef uintmax_t uatomic_max_t;
++
++
++#ifdef UP
++# define __MB /* nothing */
++#else
++# define __MB " mb\n"
++#endif
++
++
++/* Compare and exchange. For all of the "xxx" routines, we expect a
++ "__prev" and a "__cmp" variable to be provided by the enclosing scope,
++ in which values are returned. */
++
++#define __arch_compare_and_exchange_xxx_8_int(mem, new, old, mb1, mb2) \
++({ \
++ unsigned long __tmp, __snew, __addr64; \
++ __asm__ __volatile__ ( \
++ mb1 \
++ " andnot %[__addr8],7,%[__addr64]\n" \
++ " insbl %[__new],%[__addr8],%[__snew]\n" \
++ "1: ldq_l %[__tmp],0(%[__addr64])\n" \
++ " extbl %[__tmp],%[__addr8],%[__prev]\n" \
++ " cmpeq %[__prev],%[__old],%[__cmp]\n" \
++ " beq %[__cmp],2f\n" \
++ " mskbl %[__tmp],%[__addr8],%[__tmp]\n" \
++ " or %[__snew],%[__tmp],%[__tmp]\n" \
++ " stq_c %[__tmp],0(%[__addr64])\n" \
++ " beq %[__tmp],1b\n" \
++ mb2 \
++ "2:" \
++ : [__prev] "=&r" (__prev), \
++ [__snew] "=&r" (__snew), \
++ [__tmp] "=&r" (__tmp), \
++ [__cmp] "=&r" (__cmp), \
++ [__addr64] "=&r" (__addr64) \
++ : [__addr8] "r" (mem), \
++ [__old] "Ir" ((uint64_t)(uint8_t)(uint64_t)(old)), \
++ [__new] "r" (new) \
++ : "memory"); \
++})
++
++#define __arch_compare_and_exchange_xxx_16_int(mem, new, old, mb1, mb2) \
++({ \
++ unsigned long __tmp, __snew, __addr64; \
++ __asm__ __volatile__ ( \
++ mb1 \
++ " andnot %[__addr16],7,%[__addr64]\n" \
++ " inswl %[__new],%[__addr16],%[__snew]\n" \
++ "1: ldq_l %[__tmp],0(%[__addr64])\n" \
++ " extwl %[__tmp],%[__addr16],%[__prev]\n" \
++ " cmpeq %[__prev],%[__old],%[__cmp]\n" \
++ " beq %[__cmp],2f\n" \
++ " mskwl %[__tmp],%[__addr16],%[__tmp]\n" \
++ " or %[__snew],%[__tmp],%[__tmp]\n" \
++ " stq_c %[__tmp],0(%[__addr64])\n" \
++ " beq %[__tmp],1b\n" \
++ mb2 \
++ "2:" \
++ : [__prev] "=&r" (__prev), \
++ [__snew] "=&r" (__snew), \
++ [__tmp] "=&r" (__tmp), \
++ [__cmp] "=&r" (__cmp), \
++ [__addr64] "=&r" (__addr64) \
++ : [__addr16] "r" (mem), \
++ [__old] "Ir" ((uint64_t)(uint16_t)(uint64_t)(old)), \
++ [__new] "r" (new) \
++ : "memory"); \
++})
++
++#define __arch_compare_and_exchange_xxx_32_int(mem, new, old, mb1, mb2) \
++({ \
++ __asm__ __volatile__ ( \
++ mb1 \
++ "1: ldl_l %[__prev],%[__mem]\n" \
++ " cmpeq %[__prev],%[__old],%[__cmp]\n" \
++ " beq %[__cmp],2f\n" \
++ " mov %[__new],%[__cmp]\n" \
++ " stl_c %[__cmp],%[__mem]\n" \
++ " beq %[__cmp],1b\n" \
++ mb2 \
++ "2:" \
++ : [__prev] "=&r" (__prev), \
++ [__cmp] "=&r" (__cmp) \
++ : [__mem] "m" (*(mem)), \
++ [__old] "Ir" ((uint64_t)(atomic32_t)(uint64_t)(old)), \
++ [__new] "Ir" (new) \
++ : "memory"); \
++})
++
++#define __arch_compare_and_exchange_xxx_64_int(mem, new, old, mb1, mb2) \
++({ \
++ __asm__ __volatile__ ( \
++ mb1 \
++ "1: ldq_l %[__prev],%[__mem]\n" \
++ " cmpeq %[__prev],%[__old],%[__cmp]\n" \
++ " beq %[__cmp],2f\n" \
++ " mov %[__new],%[__cmp]\n" \
++ " stq_c %[__cmp],%[__mem]\n" \
++ " beq %[__cmp],1b\n" \
++ mb2 \
++ "2:" \
++ : [__prev] "=&r" (__prev), \
++ [__cmp] "=&r" (__cmp) \
++ : [__mem] "m" (*(mem)), \
++ [__old] "Ir" ((uint64_t)(old)), \
++ [__new] "Ir" (new) \
++ : "memory"); \
++})
++
++/* For all "bool" routines, we return FALSE if exchange succesful. */
++
++#define __arch_compare_and_exchange_bool_8_int(mem, new, old, mb1, mb2) \
++({ unsigned long __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_8_int(mem, new, old, mb1, mb2); \
++ !__cmp; })
++
++#define __arch_compare_and_exchange_bool_16_int(mem, new, old, mb1, mb2) \
++({ unsigned long __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_16_int(mem, new, old, mb1, mb2); \
++ !__cmp; })
++
++#define __arch_compare_and_exchange_bool_32_int(mem, new, old, mb1, mb2) \
++({ unsigned long __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_32_int(mem, new, old, mb1, mb2); \
++ !__cmp; })
++
++#define __arch_compare_and_exchange_bool_64_int(mem, new, old, mb1, mb2) \
++({ unsigned long __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_64_int(mem, new, old, mb1, mb2); \
++ !__cmp; })
++
++/* For all "val" routines, return the old value whether exchange
++ successful or not. */
++
++#define __arch_compare_and_exchange_val_8_int(mem, new, old, mb1, mb2) \
++({ unsigned long __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_8_int(mem, new, old, mb1, mb2); \
++ (typeof (*mem))__prev; })
++
++#define __arch_compare_and_exchange_val_16_int(mem, new, old, mb1, mb2) \
++({ unsigned long __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_16_int(mem, new, old, mb1, mb2); \
++ (typeof (*mem))__prev; })
++
++#define __arch_compare_and_exchange_val_32_int(mem, new, old, mb1, mb2) \
++({ unsigned long __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_32_int(mem, new, old, mb1, mb2); \
++ (typeof (*mem))__prev; })
++
++#define __arch_compare_and_exchange_val_64_int(mem, new, old, mb1, mb2) \
++({ unsigned long __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_64_int(mem, new, old, mb1, mb2); \
++ (typeof (*mem))__prev; })
++
++/* Compare and exchange with "acquire" semantics, ie barrier after. */
++
++#define atomic_compare_and_exchange_bool_acq(mem, new, old) \
++ __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
++ mem, new, old, "", __MB)
++
++#define atomic_compare_and_exchange_val_acq(mem, new, old) \
++ __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
++ mem, new, old, "", __MB)
++
++/* Compare and exchange with "release" semantics, ie barrier before. */
++
++#define atomic_compare_and_exchange_bool_rel(mem, new, old) \
++ __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
++ mem, new, old, __MB, "")
++
++#define atomic_compare_and_exchange_val_rel(mem, new, old) \
++ __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
++ mem, new, old, __MB, "")
++
++
++/* Atomically store value and return the previous value. */
++
++#define __arch_exchange_8_int(mem, value, mb1, mb2) \
++({ \
++ unsigned long __ret, __tmp, __addr64, __sval; \
++ __asm__ __volatile__ ( \
++ mb1 \
++ " andnot %[__addr8],7,%[__addr64]\n" \
++ " insbl %[__value],%[__addr8],%[__sval]\n" \
++ "1: ldq_l %[__tmp],0(%[__addr64])\n" \
++ " extbl %[__tmp],%[__addr8],%[__ret]\n" \
++ " mskbl %[__tmp],%[__addr8],%[__tmp]\n" \
++ " or %[__sval],%[__tmp],%[__tmp]\n" \
++ " stq_c %[__tmp],0(%[__addr64])\n" \
++ " beq %[__tmp],1b\n" \
++ mb2 \
++ : [__ret] "=&r" (__ret), \
++ [__sval] "=&r" (__sval), \
++ [__tmp] "=&r" (__tmp), \
++ [__addr64] "=&r" (__addr64) \
++ : [__addr8] "r" (mem), \
++ [__value] "r" (value) \
++ : "memory"); \
++ __ret; })
++
++#define __arch_exchange_16_int(mem, value, mb1, mb2) \
++({ \
++ unsigned long __ret, __tmp, __addr64, __sval; \
++ __asm__ __volatile__ ( \
++ mb1 \
++ " andnot %[__addr16],7,%[__addr64]\n" \
++ " inswl %[__value],%[__addr16],%[__sval]\n" \
++ "1: ldq_l %[__tmp],0(%[__addr64])\n" \
++ " extwl %[__tmp],%[__addr16],%[__ret]\n" \
++ " mskwl %[__tmp],%[__addr16],%[__tmp]\n" \
++ " or %[__sval],%[__tmp],%[__tmp]\n" \
++ " stq_c %[__tmp],0(%[__addr64])\n" \
++ " beq %[__tmp],1b\n" \
++ mb2 \
++ : [__ret] "=&r" (__ret), \
++ [__sval] "=&r" (__sval), \
++ [__tmp] "=&r" (__tmp), \
++ [__addr64] "=&r" (__addr64) \
++ : [__addr16] "r" (mem), \
++ [__value] "r" (value) \
++ : "memory"); \
++ __ret; })
++
++#define __arch_exchange_32_int(mem, value, mb1, mb2) \
++({ \
++ signed int __ret, __tmp; \
++ __asm__ __volatile__ ( \
++ mb1 \
++ "1: ldl_l %[__ret],%[__mem]\n" \
++ " mov %[__val],%[__tmp]\n" \
++ " stl_c %[__tmp],%[__mem]\n" \
++ " beq %[__tmp],1b\n" \
++ mb2 \
++ : [__ret] "=&r" (__ret), \
++ [__tmp] "=&r" (__tmp) \
++ : [__mem] "m" (*(mem)), \
++ [__val] "Ir" (value) \
++ : "memory"); \
++ __ret; })
++
++#define __arch_exchange_64_int(mem, value, mb1, mb2) \
++({ \
++ unsigned long __ret, __tmp; \
++ __asm__ __volatile__ ( \
++ mb1 \
++ "1: ldq_l %[__ret],%[__mem]\n" \
++ " mov %[__val],%[__tmp]\n" \
++ " stq_c %[__tmp],%[__mem]\n" \
++ " beq %[__tmp],1b\n" \
++ mb2 \
++ : [__ret] "=&r" (__ret), \
++ [__tmp] "=&r" (__tmp) \
++ : [__mem] "m" (*(mem)), \
++ [__val] "Ir" (value) \
++ : "memory"); \
++ __ret; })
++
++#define atomic_exchange_acq(mem, value) \
++ __atomic_val_bysize (__arch_exchange, int, mem, value, "", __MB)
++
++#define atomic_exchange_rel(mem, value) \
++ __atomic_val_bysize (__arch_exchange, int, mem, value, __MB, "")
++
++
++/* Atomically add value and return the previous (unincremented) value. */
++
++#define __arch_exchange_and_add_8_int(mem, value, mb1, mb2) \
++ ({ __builtin_trap (); 0; })
++
++#define __arch_exchange_and_add_16_int(mem, value, mb1, mb2) \
++ ({ __builtin_trap (); 0; })
++
++#define __arch_exchange_and_add_32_int(mem, value, mb1, mb2) \
++({ \
++ signed int __ret, __tmp; \
++ __asm__ __volatile__ ( \
++ mb1 \
++ "1: ldl_l %[__ret],%[__mem]\n" \
++ " addl %[__ret],%[__val],%[__tmp]\n" \
++ " stl_c %[__tmp],%[__mem]\n" \
++ " beq %[__tmp],1b\n" \
++ mb2 \
++ : [__ret] "=&r" (__ret), \
++ [__tmp] "=&r" (__tmp) \
++ : [__mem] "m" (*(mem)), \
++ [__val] "Ir" ((signed int)(value)) \
++ : "memory"); \
++ __ret; })
++
++#define __arch_exchange_and_add_64_int(mem, value, mb1, mb2) \
++({ \
++ unsigned long __ret, __tmp; \
++ __asm__ __volatile__ ( \
++ mb1 \
++ "1: ldq_l %[__ret],%[__mem]\n" \
++ " addq %[__ret],%[__val],%[__tmp]\n" \
++ " stq_c %[__tmp],%[__mem]\n" \
++ " beq %[__tmp],1b\n" \
++ mb2 \
++ : [__ret] "=&r" (__ret), \
++ [__tmp] "=&r" (__tmp) \
++ : [__mem] "m" (*(mem)), \
++ [__val] "Ir" ((unsigned long)(value)) \
++ : "memory"); \
++ __ret; })
++
++/* ??? Barrier semantics for atomic_exchange_and_add appear to be
++ undefined. Use full barrier for now, as that's safe. */
++#define atomic_exchange_and_add(mem, value) \
++ __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, __MB, __MB)
++
++
++/* ??? Blah, I'm lazy. Implement these later. Can do better than the
++ compare-and-exchange loop provided by generic code.
++
++#define atomic_decrement_if_positive(mem)
++#define atomic_bit_test_set(mem, bit)
++
++*/
++
++#ifndef UP
++# define atomic_full_barrier() __asm ("mb" : : : "memory");
++# define atomic_read_barrier() __asm ("mb" : : : "memory");
++# define atomic_write_barrier() __asm ("wmb" : : : "memory");
++#endif
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/arm/crt0.S uClibc-0.9.27-uc0/libc/sysdeps/linux/arm/crt0.S
+--- uClibc-0.9.27/libc/sysdeps/linux/arm/crt0.S 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/arm/crt0.S 2005-07-08 00:57:15.000000000 +0200
+@@ -96,11 +96,14 @@
+ #ifdef __PIC__
+ /* Store the address of _init in r3 as an argument to main() */
+ adr r5, .L_init
+- ldr r3, .L_init
++ ldr r6, .L_init
++ ldr r3, .L_init+4
++ sub r3, r3, r6
+ add r3, r3, r5
+
+ /* Push _fini onto the stack as the final argument to main() */
+- ldr r4, .L_init + 4
++ ldr r4, .L_init+8
++ sub r4, r4, r6
+ add r4, r4, r5
+ #else
+ /* Store the address of _init in r3 as an argument to main() */
+@@ -122,8 +125,9 @@
+
+ #if (defined L_crt1 ) && defined __UCLIBC_CTOR_DTOR__ && defined __PIC__
+ .L_init:
+- .word _init - .L_init
+- .word _fini - .L_init
++ .word .L_init
++ .word _init
++ .word _fini
+ #endif
+
+ /* We need this stuff to make gdb behave itself, otherwise
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/arm/sys/ucontext.h uClibc-0.9.27-uc0/libc/sysdeps/linux/arm/sys/ucontext.h
+--- uClibc-0.9.27/libc/sysdeps/linux/arm/sys/ucontext.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/arm/sys/ucontext.h 2005-01-26 07:37:24.000000000 +0100
+@@ -87,7 +87,7 @@
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+- struct sigcontext uc_mcontext;
++ mcontext_t uc_mcontext;
+ sigset_t uc_sigmask; /* mask last for extensibility */
+ } ucontext_t;
+
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/common/bits/atomic.h uClibc-0.9.27-uc0/libc/sysdeps/linux/common/bits/atomic.h
+--- uClibc-0.9.27/libc/sysdeps/linux/common/bits/atomic.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/common/bits/atomic.h 2006-01-16 07:46:31.000000000 +0100
+@@ -0,0 +1,43 @@
++/* Copyright (C) 2003 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
++
++ 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. */
++
++#ifndef _BITS_ATOMIC_H
++#define _BITS_ATOMIC_H 1
++
++/* We have by default no support for atomic operations. So define
++ them non-atomic. If this is a problem somebody will have to come
++ up with real definitions. */
++
++/* The only basic operation needed is compare and exchange. */
++#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
++ ({ __typeof (mem) __gmemp = (mem); \
++ __typeof (*mem) __gret = *__gmemp; \
++ __typeof (*mem) __gnewval = (newval); \
++ \
++ if (__gret == (oldval)) \
++ *__gmemp = __gnewval; \
++ __gret; })
++
++#define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
++ ({ __typeof (mem) __gmemp = (mem); \
++ __typeof (*mem) __gnewval = (newval); \
++ \
++ *__gmemp == (oldval) ? (*__gmemp = __gnewval, 0) : 1; })
++
++#endif /* bits/atomic.h */
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/common/bits/uClibc_stdio.h uClibc-0.9.27-uc0/libc/sysdeps/linux/common/bits/uClibc_stdio.h
+--- uClibc-0.9.27/libc/sysdeps/linux/common/bits/uClibc_stdio.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/common/bits/uClibc_stdio.h 2005-07-08 06:39:36.000000000 +0200
+@@ -457,6 +457,8 @@
+
+ #else
+
++#define __stdin stdin
++
+ #endif /* __STDIO_GETC_MACRO */
+
+
+@@ -515,5 +517,8 @@
+
+ # endif
+ # endif
++#else
++
++#define __stdout stdout
+
+ #endif /* __STDIO_PUTC_MACRO */
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/common/cmsg_nxthdr.c uClibc-0.9.27-uc0/libc/sysdeps/linux/common/cmsg_nxthdr.c
+--- uClibc-0.9.27/libc/sysdeps/linux/common/cmsg_nxthdr.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/common/cmsg_nxthdr.c 2005-02-28 07:06:19.000000000 +0100
+@@ -34,7 +34,7 @@
+ if ((unsigned char *) (cmsg + 1) >= ((unsigned char *) mhdr->msg_control
+ + mhdr->msg_controllen)
+ || ((unsigned char *) cmsg + CMSG_ALIGN (cmsg->cmsg_len)
+- >= ((unsigned char *) mhdr->msg_control + mhdr->msg_controllen)))
++ > ((unsigned char *) mhdr->msg_control + mhdr->msg_controllen)))
+ /* No more entries. */
+ return NULL;
+ return cmsg;
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/common/create_module.c uClibc-0.9.27-uc0/libc/sysdeps/linux/common/create_module.c
+--- uClibc-0.9.27/libc/sysdeps/linux/common/create_module.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/common/create_module.c 2005-01-26 12:53:45.000000000 +0100
+@@ -32,6 +32,7 @@
+ #ifdef __NR_create_module
+
+ #if defined(__i386__) || defined(__m68k__) || defined(__arm__) || defined(__cris__) || defined(__i960__)
++#ifdef __NR_create_module
+ #define __NR___create_module __NR_create_module
+ #ifdef __STR_NR_create_module
+ #define __STR_NR___create_module __STR_NR_create_module
+@@ -51,6 +52,13 @@
+ }
+ return ret;
+ }
++#else
++unsigned long create_module(const char *name, size_t size)
++{
++ __set_errno(ENOSYS);
++ return(-1);
++}
++#endif
+ #elif defined(__alpha__)
+ #define __NR___create_module __NR_create_module
+ /* Alpha doesn't have the same problem, exactly, but a bug in older
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/common/pread_write.c uClibc-0.9.27-uc0/libc/sysdeps/linux/common/pread_write.c
+--- uClibc-0.9.27/libc/sysdeps/linux/common/pread_write.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/common/pread_write.c 2003-10-08 07:46:43.000000000 +0200
+@@ -48,7 +48,7 @@
+
+ ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
+ {
+- return(__syscall_pread(fd,buf,count,__LONG_LONG_PAIR (offset >> 31, offset)));
++ return(__syscall_pread(fd,buf,count,__LONG_LONG_PAIR ((off_t)0, offset)));
+ }
+ weak_alias (__libc_pread, pread)
+
+@@ -73,7 +73,7 @@
+
+ ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
+ {
+- return(__syscall_pwrite(fd,buf,count,__LONG_LONG_PAIR (offset >> 31, offset)));
++ return(__syscall_pwrite(fd,buf,count,__LONG_LONG_PAIR ((off_t)0, offset)));
+ }
+ weak_alias (__libc_pwrite, pwrite)
+
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/cris/crt0.c uClibc-0.9.27-uc0/libc/sysdeps/linux/cris/crt0.c
+--- uClibc-0.9.27/libc/sysdeps/linux/cris/crt0.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/cris/crt0.c 2005-07-08 03:33:45.000000000 +0200
+@@ -32,6 +32,8 @@
+ extern void __uClibc_start_main(int argc, char **argv, char **envp,
+ void (*app_init)(void), void (*app_fini)(void))
+ __attribute__ ((__noreturn__));
++weak_decl(_init)
++weak_decl(_fini)
+ extern void weak_function _init(void);
+ extern void weak_function _fini(void);
+
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/i386/bits/atomic.h uClibc-0.9.27-uc0/libc/sysdeps/linux/i386/bits/atomic.h
+--- uClibc-0.9.27/libc/sysdeps/linux/i386/bits/atomic.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/i386/bits/atomic.h 2006-01-16 07:46:31.000000000 +0100
+@@ -0,0 +1,366 @@
++/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
++
++ 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 <stdint.h>
++
++
++typedef int8_t atomic8_t;
++typedef uint8_t uatomic8_t;
++typedef int_fast8_t atomic_fast8_t;
++typedef uint_fast8_t uatomic_fast8_t;
++
++typedef int16_t atomic16_t;
++typedef uint16_t uatomic16_t;
++typedef int_fast16_t atomic_fast16_t;
++typedef uint_fast16_t uatomic_fast16_t;
++
++typedef int32_t atomic32_t;
++typedef uint32_t uatomic32_t;
++typedef int_fast32_t atomic_fast32_t;
++typedef uint_fast32_t uatomic_fast32_t;
++
++typedef int64_t atomic64_t;
++typedef uint64_t uatomic64_t;
++typedef int_fast64_t atomic_fast64_t;
++typedef uint_fast64_t uatomic_fast64_t;
++
++typedef intptr_t atomicptr_t;
++typedef uintptr_t uatomicptr_t;
++typedef intmax_t atomic_max_t;
++typedef uintmax_t uatomic_max_t;
++
++
++#ifndef LOCK_PREFIX
++# ifdef UP
++# define LOCK_PREFIX /* nothing */
++# else
++# define LOCK_PREFIX "lock;"
++# endif
++#endif
++
++
++#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
++ ({ __typeof (*mem) ret; \
++ __asm __volatile (LOCK_PREFIX "cmpxchgb %b2, %1" \
++ : "=a" (ret), "=m" (*mem) \
++ : "q" (newval), "m" (*mem), "0" (oldval)); \
++ ret; })
++
++#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
++ ({ __typeof (*mem) ret; \
++ __asm __volatile (LOCK_PREFIX "cmpxchgw %w2, %1" \
++ : "=a" (ret), "=m" (*mem) \
++ : "r" (newval), "m" (*mem), "0" (oldval)); \
++ ret; })
++
++#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
++ ({ __typeof (*mem) ret; \
++ __asm __volatile (LOCK_PREFIX "cmpxchgl %2, %1" \
++ : "=a" (ret), "=m" (*mem) \
++ : "r" (newval), "m" (*mem), "0" (oldval)); \
++ ret; })
++
++/* XXX We do not really need 64-bit compare-and-exchange. At least
++ not in the moment. Using it would mean causing portability
++ problems since not many other 32-bit architectures have support for
++ such an operation. So don't define any code for now. If it is
++ really going to be used the code below can be used on Intel Pentium
++ and later, but NOT on i486. */
++#if 1
++# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
++ ({ __typeof (*mem) ret = *(mem); abort (); ret = (newval); ret = (oldval); })
++#else
++# ifdef __PIC__
++# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
++ ({ __typeof (*mem) ret; \
++ __asm __volatile ("xchgl %2, %%ebx\n\t" \
++ LOCK_PREFIX "cmpxchg8b %1\n\t" \
++ "xchgl %2, %%ebx" \
++ : "=A" (ret), "=m" (*mem) \
++ : "DS" (((unsigned long long int) (newval)) \
++ & 0xffffffff), \
++ "c" (((unsigned long long int) (newval)) >> 32), \
++ "m" (*mem), "a" (((unsigned long long int) (oldval)) \
++ & 0xffffffff), \
++ "d" (((unsigned long long int) (oldval)) >> 32)); \
++ ret; })
++# else
++# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
++ ({ __typeof (*mem) ret; \
++ __asm __volatile (LOCK_PREFIX "cmpxchg8b %1" \
++ : "=A" (ret), "=m" (*mem) \
++ : "b" (((unsigned long long int) (newval)) \
++ & 0xffffffff), \
++ "c" (((unsigned long long int) (newval)) >> 32), \
++ "m" (*mem), "a" (((unsigned long long int) (oldval)) \
++ & 0xffffffff), \
++ "d" (((unsigned long long int) (oldval)) >> 32)); \
++ ret; })
++# endif
++#endif
++
++
++/* Note that we need no lock prefix. */
++#define atomic_exchange_acq(mem, newvalue) \
++ ({ __typeof (*mem) result; \
++ if (sizeof (*mem) == 1) \
++ __asm __volatile ("xchgb %b0, %1" \
++ : "=r" (result), "=m" (*mem) \
++ : "0" (newvalue), "m" (*mem)); \
++ else if (sizeof (*mem) == 2) \
++ __asm __volatile ("xchgw %w0, %1" \
++ : "=r" (result), "=m" (*mem) \
++ : "0" (newvalue), "m" (*mem)); \
++ else if (sizeof (*mem) == 4) \
++ __asm __volatile ("xchgl %0, %1" \
++ : "=r" (result), "=m" (*mem) \
++ : "0" (newvalue), "m" (*mem)); \
++ else \
++ { \
++ result = 0; \
++ abort (); \
++ } \
++ result; })
++
++
++#define atomic_exchange_and_add(mem, value) \
++ ({ __typeof (*mem) __result; \
++ __typeof (value) __addval = (value); \
++ if (sizeof (*mem) == 1) \
++ __asm __volatile (LOCK_PREFIX "xaddb %b0, %1" \
++ : "=r" (__result), "=m" (*mem) \
++ : "0" (__addval), "m" (*mem)); \
++ else if (sizeof (*mem) == 2) \
++ __asm __volatile (LOCK_PREFIX "xaddw %w0, %1" \
++ : "=r" (__result), "=m" (*mem) \
++ : "0" (__addval), "m" (*mem)); \
++ else if (sizeof (*mem) == 4) \
++ __asm __volatile (LOCK_PREFIX "xaddl %0, %1" \
++ : "=r" (__result), "=m" (*mem) \
++ : "0" (__addval), "m" (*mem)); \
++ else \
++ { \
++ __typeof (mem) __memp = (mem); \
++ __typeof (*mem) __tmpval; \
++ __result = *__memp; \
++ do \
++ __tmpval = __result; \
++ while ((__result = __arch_compare_and_exchange_val_64_acq \
++ (__memp, __result + __addval, __result)) == __tmpval); \
++ } \
++ __result; })
++
++
++#define atomic_add(mem, value) \
++ (void) ({ if (__builtin_constant_p (value) && (value) == 1) \
++ atomic_increment (mem); \
++ else if (__builtin_constant_p (value) && (value) == -1) \
++ atomic_decrement (mem); \
++ else if (sizeof (*mem) == 1) \
++ __asm __volatile (LOCK_PREFIX "addb %b1, %0" \
++ : "=m" (*mem) \
++ : "ir" (value), "m" (*mem)); \
++ else if (sizeof (*mem) == 2) \
++ __asm __volatile (LOCK_PREFIX "addw %w1, %0" \
++ : "=m" (*mem) \
++ : "ir" (value), "m" (*mem)); \
++ else if (sizeof (*mem) == 4) \
++ __asm __volatile (LOCK_PREFIX "addl %1, %0" \
++ : "=m" (*mem) \
++ : "ir" (value), "m" (*mem)); \
++ else \
++ { \
++ __typeof (value) __addval = (value); \
++ __typeof (mem) __memp = (mem); \
++ __typeof (*mem) __oldval = *__memp; \
++ __typeof (*mem) __tmpval; \
++ do \
++ __tmpval = __oldval; \
++ while ((__oldval = __arch_compare_and_exchange_val_64_acq \
++ (__memp, __oldval + __addval, __oldval)) == __tmpval); \
++ } \
++ })
++
++
++#define atomic_add_negative(mem, value) \
++ ({ unsigned char __result; \
++ if (sizeof (*mem) == 1) \
++ __asm __volatile (LOCK_PREFIX "addb %b2, %0; sets %1" \
++ : "=m" (*mem), "=qm" (__result) \
++ : "iq" (value), "m" (*mem)); \
++ else if (sizeof (*mem) == 2) \
++ __asm __volatile (LOCK_PREFIX "addw %w2, %0; sets %1" \
++ : "=m" (*mem), "=qm" (__result) \
++ : "ir" (value), "m" (*mem)); \
++ else if (sizeof (*mem) == 4) \
++ __asm __volatile (LOCK_PREFIX "addl %2, %0; sets %1" \
++ : "=m" (*mem), "=qm" (__result) \
++ : "ir" (value), "m" (*mem)); \
++ else \
++ abort (); \
++ __result; })
++
++
++#define atomic_add_zero(mem, value) \
++ ({ unsigned char __result; \
++ if (sizeof (*mem) == 1) \
++ __asm __volatile (LOCK_PREFIX "addb %b2, %0; setz %1" \
++ : "=m" (*mem), "=qm" (__result) \
++ : "ir" (value), "m" (*mem)); \
++ else if (sizeof (*mem) == 2) \
++ __asm __volatile (LOCK_PREFIX "addw %w2, %0; setz %1" \
++ : "=m" (*mem), "=qm" (__result) \
++ : "ir" (value), "m" (*mem)); \
++ else if (sizeof (*mem) == 4) \
++ __asm __volatile (LOCK_PREFIX "addl %2, %0; setz %1" \
++ : "=m" (*mem), "=qm" (__result) \
++ : "ir" (value), "m" (*mem)); \
++ else \
++ abort (); \
++ __result; })
++
++
++#define atomic_increment(mem) \
++ (void) ({ if (sizeof (*mem) == 1) \
++ __asm __volatile (LOCK_PREFIX "incb %b0" \
++ : "=m" (*mem) \
++ : "m" (*mem)); \
++ else if (sizeof (*mem) == 2) \
++ __asm __volatile (LOCK_PREFIX "incw %w0" \
++ : "=m" (*mem) \
++ : "m" (*mem)); \
++ else if (sizeof (*mem) == 4) \
++ __asm __volatile (LOCK_PREFIX "incl %0" \
++ : "=m" (*mem) \
++ : "m" (*mem)); \
++ else \
++ { \
++ __typeof (mem) __memp = (mem); \
++ __typeof (*mem) __oldval = *__memp; \
++ __typeof (*mem) __tmpval; \
++ do \
++ __tmpval = __oldval; \
++ while ((__oldval = __arch_compare_and_exchange_val_64_acq \
++ (__memp, __oldval + 1, __oldval)) == __tmpval); \
++ } \
++ })
++
++
++#define atomic_increment_and_test(mem) \
++ ({ unsigned char __result; \
++ if (sizeof (*mem) == 1) \
++ __asm __volatile (LOCK_PREFIX "incb %0; sete %b1" \
++ : "=m" (*mem), "=qm" (__result) \
++ : "m" (*mem)); \
++ else if (sizeof (*mem) == 2) \
++ __asm __volatile (LOCK_PREFIX "incw %0; sete %w1" \
++ : "=m" (*mem), "=qm" (__result) \
++ : "m" (*mem)); \
++ else if (sizeof (*mem) == 4) \
++ __asm __volatile (LOCK_PREFIX "incl %0; sete %1" \
++ : "=m" (*mem), "=qm" (__result) \
++ : "m" (*mem)); \
++ else \
++ abort (); \
++ __result; })
++
++
++#define atomic_decrement(mem) \
++ (void) ({ if (sizeof (*mem) == 1) \
++ __asm __volatile (LOCK_PREFIX "decb %b0" \
++ : "=m" (*mem) \
++ : "m" (*mem)); \
++ else if (sizeof (*mem) == 2) \
++ __asm __volatile (LOCK_PREFIX "decw %w0" \
++ : "=m" (*mem) \
++ : "m" (*mem)); \
++ else if (sizeof (*mem) == 4) \
++ __asm __volatile (LOCK_PREFIX "decl %0" \
++ : "=m" (*mem) \
++ : "m" (*mem)); \
++ else \
++ { \
++ __typeof (mem) __memp = (mem); \
++ __typeof (*mem) __oldval = *__memp; \
++ __typeof (*mem) __tmpval; \
++ do \
++ __tmpval = __oldval; \
++ while ((__oldval = __arch_compare_and_exchange_val_64_acq \
++ (__memp, __oldval - 1, __oldval)) == __tmpval); \
++ } \
++ })
++
++
++#define atomic_decrement_and_test(mem) \
++ ({ unsigned char __result; \
++ if (sizeof (*mem) == 1) \
++ __asm __volatile (LOCK_PREFIX "decb %b0; sete %1" \
++ : "=m" (*mem), "=qm" (__result) \
++ : "m" (*mem)); \
++ else if (sizeof (*mem) == 2) \
++ __asm __volatile (LOCK_PREFIX "decw %w0; sete %1" \
++ : "=m" (*mem), "=qm" (__result) \
++ : "m" (*mem)); \
++ else if (sizeof (*mem) == 4) \
++ __asm __volatile (LOCK_PREFIX "decl %0; sete %1" \
++ : "=m" (*mem), "=qm" (__result) \
++ : "m" (*mem)); \
++ else \
++ abort (); \
++ __result; })
++
++
++#define atomic_bit_set(mem, bit) \
++ (void) ({ if (sizeof (*mem) == 1) \
++ __asm __volatile (LOCK_PREFIX "orb %b2, %0" \
++ : "=m" (*mem) \
++ : "m" (*mem), "ir" (1 << (bit))); \
++ else if (sizeof (*mem) == 2) \
++ __asm __volatile (LOCK_PREFIX "orw %w2, %0" \
++ : "=m" (*mem) \
++ : "m" (*mem), "ir" (1 << (bit))); \
++ else if (sizeof (*mem) == 4) \
++ __asm __volatile (LOCK_PREFIX "orl %2, %0" \
++ : "=m" (*mem) \
++ : "m" (*mem), "ir" (1 << (bit))); \
++ else \
++ abort (); \
++ })
++
++
++#define atomic_bit_test_set(mem, bit) \
++ ({ unsigned char __result; \
++ if (sizeof (*mem) == 1) \
++ __asm __volatile (LOCK_PREFIX "btsb %3, %1; setc %0" \
++ : "=q" (__result), "=m" (*mem) \
++ : "m" (*mem), "ir" (bit)); \
++ else if (sizeof (*mem) == 2) \
++ __asm __volatile (LOCK_PREFIX "btsw %3, %1; setc %0" \
++ : "=q" (__result), "=m" (*mem) \
++ : "m" (*mem), "ir" (bit)); \
++ else if (sizeof (*mem) == 4) \
++ __asm __volatile (LOCK_PREFIX "btsl %3, %1; setc %0" \
++ : "=q" (__result), "=m" (*mem) \
++ : "m" (*mem), "ir" (bit)); \
++ else \
++ abort (); \
++ __result; })
++
++
++#define atomic_delay() asm ("rep; nop")
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/m68k/Makefile uClibc-0.9.27-uc0/libc/sysdeps/linux/m68k/Makefile
+--- uClibc-0.9.27/libc/sysdeps/linux/m68k/Makefile 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/m68k/Makefile 2005-01-26 07:37:25.000000000 +0100
+@@ -33,7 +33,7 @@
+ SSRC= __longjmp.S bsd-_setjmp.S bsd-setjmp.S clone.S setjmp.S vfork.S
+ SOBJS=$(patsubst %.S,%.o, $(SSRC))
+
+-CSRC=ptrace.c brk.c
++CSRC=ptrace.c brk.c syscall.c
+ COBJS=$(patsubst %.c,%.o, $(CSRC))
+
+ OBJS=$(SOBJS) $(MOBJ) $(COBJS)
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/m68k/sys/ucontext.h uClibc-0.9.27-uc0/libc/sysdeps/linux/m68k/sys/ucontext.h
+--- uClibc-0.9.27/libc/sysdeps/linux/m68k/sys/ucontext.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/m68k/sys/ucontext.h 2006-07-28 08:09:17.000000000 +0200
+@@ -79,10 +79,10 @@
+ /* Structure to describe FPU registers. */
+ typedef struct fpregset
+ {
+- int f_fpregs[8][3];
+ int f_pcr;
+ int f_psr;
+ int f_fpiaddr;
++ int f_fpregs[8][3];
+ } fpregset_t;
+
+ /* Context to describe whole processor state. */
+@@ -96,14 +96,13 @@
+ #define MCONTEXT_VERSION 2
+
+ /* Userlevel context. */
+-typedef struct ucontext
+-{
+- unsigned long int uc_flags;
++typedef struct ucontext {
++ unsigned long uc_flags;
+ struct ucontext *uc_link;
+- __sigset_t uc_sigmask;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+- long int uc_filler[174];
++ unsigned long uc_filler[80];
++ __sigset_t uc_sigmask; /* mask last for extensibility */
+ } ucontext_t;
+
+ #endif /* sys/ucontext.h */
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/m68k/syscall.c uClibc-0.9.27-uc0/libc/sysdeps/linux/m68k/syscall.c
+--- uClibc-0.9.27/libc/sysdeps/linux/m68k/syscall.c 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/m68k/syscall.c 2004-10-06 10:04:19.000000000 +0200
+@@ -0,0 +1,57 @@
++/* syscall for m68k/uClibc
++ *
++ * Copyright (C) 2004 by Christian Magnusson <mag@mag.cx>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU Library General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ * This program 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 Library General Public License
++ * for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this program; if not, write to the Free Software Foundation,
++ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <features.h>
++#include <errno.h>
++#include <sys/types.h>
++#include <sys/syscall.h>
++
++long syscall(long sysnum, long a, long b, long c, long d, long e, long f)
++{
++ long __res;
++ __asm__ __volatile__ ("movel %7, %%d6\n\t"\
++ "movel %6, %%d5\n\t"\
++ "movel %5, %%d4\n\t"\
++ "movel %4, %%d3\n\t"\
++ "movel %3, %%d2\n\t"\
++ "movel %2, %%d1\n\t"\
++ "movel %1, %%d0\n\t"\
++ "trap #0\n\t"\
++ "movel %%d0, %0"\
++ : "=g" (__res)\
++ : "g" (sysnum),\
++ "a" ((long)a),\
++ "a" ((long)b),\
++ "a" ((long)c),\
++ "a" ((long)d),\
++ "a" ((long)e),\
++ "g" ((long)f)\
++ : "cc", "%d0", "%d1", "%d2", "%d3",\
++ "%d4", "%d5", "%d6");
++
++#if 1
++ __syscall_return(long,__res);
++#else
++ if ((unsigned long)(__res) >= (unsigned long)(-125)) {
++ errno = -__res;
++ __res = -1;
++ }
++ return (long)__res;
++#endif
++}
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/microblaze/bits/setjmp.h uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/bits/setjmp.h
+--- uClibc-0.9.27/libc/sysdeps/linux/microblaze/bits/setjmp.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/bits/setjmp.h 2003-12-01 06:55:42.000000000 +0100
+@@ -25,12 +25,16 @@
+ /* Link pointer. */
+ void *__lp;
+
+- /* Callee-saved registers r18-r30. */
+- int __regs[13];
++ /* SDA pointers */
++ void *__SDA;
++ void *__SDA2;
++
++ /* Callee-saved registers r18-r31. */
++ int __regs[14];
+ } __jmp_buf[1];
+ #endif
+
+-#define JB_SIZE (4 * 15)
++#define JB_SIZE (4 * 18)
+
+ /* Test if longjmp to JMPBUF would unwind the frame
+ containing a local variable at ADDRESS. */
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/microblaze/clone.c uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/clone.c
+--- uClibc-0.9.27/libc/sysdeps/linux/microblaze/clone.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/clone.c 2005-08-05 03:10:51.000000000 +0200
+@@ -19,32 +19,36 @@
+ int
+ clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg)
+ {
+- register unsigned long rval asm (SYSCALL_RET) = -EINVAL;
++ register unsigned long rval = -EINVAL;
+
+ if (fn && child_stack)
+ {
+- register unsigned long syscall asm (SYSCALL_NUM);
+- register unsigned long arg0 asm (SYSCALL_ARG0);
+- register unsigned long arg1 asm (SYSCALL_ARG1);
++ register unsigned long arg0;
++ register unsigned long arg1;
+
+ /* Clone this thread. */
+ arg0 = flags;
+ arg1 = (unsigned long)child_stack;
+- syscall = __NR_clone;
+- asm volatile ("bralid r17, trap;nop;"
+- : "=r" (rval), "=r" (syscall)
+- : "1" (syscall), "r" (arg0), "r" (arg1)
+- : SYSCALL_CLOBBERS);
++ asm volatile ( "addik r12, r0, %1 \n\t"
++ "addk r5, r0, %2 \n\t"
++ "addk r6, r0, %3 \n\t"
++ "brki r14, 0x08 \n\t"
++ "addk %0, r3, r0 \n\t"
++ : "=r" (rval)
++ : "i" (__NR_clone), "r" (arg0), "r" (arg1)
++ : "r3", "r5", "r6", "r12", "r14", "cc");
+
+ if (rval == 0)
+ /* In child thread, call FN and exit. */
+ {
+ arg0 = (*fn) (arg);
+- syscall = __NR_exit;
+- asm volatile ("bralid r17, trap;nop;"
+- : "=r" (rval), "=r" (syscall)
+- : "1" (syscall), "r" (arg0)
+- : SYSCALL_CLOBBERS);
++ asm volatile ("addik r12, r0, %1 \n\t"
++ "addk r5, r0, %2 \n\t"
++ "brki r14, 0x08 \n\t"
++ "addk %0, r0, r3 \n\t"
++ : "=r" (rval)
++ : "i" (__NR_exit), "r" (arg0)
++ : "r3", "r5", "r12", "r14", "cc");
+ }
+ }
+
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/microblaze/fixdfsi.c uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/fixdfsi.c
+--- uClibc-0.9.27/libc/sysdeps/linux/microblaze/fixdfsi.c 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/fixdfsi.c 2004-03-02 06:47:36.000000000 +0100
+@@ -0,0 +1,85 @@
++/*
++** libgcc support for software floating point.
++** Copyright (C) 1991 by Pipeline Associates, Inc. All rights reserved.
++** Permission is granted to do *anything* you want with this file,
++** commercial or otherwise, provided this message remains intact. So there!
++** I would appreciate receiving any updates/patches/changes that anyone
++** makes, and am willing to be the repository for said changes (am I
++** making a big mistake?).
++
++Warning! Only single-precision is actually implemented. This file
++won't really be much use until double-precision is supported.
++
++However, once that is done, this file might eventually become a
++replacement for libgcc1.c. It might also make possible
++cross-compilation for an IEEE target machine from a non-IEEE
++host such as a VAX.
++
++If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
++
++--> Double precision floating support added by James Carlson on 20 April 1998.
++
++**
++** Pat Wood
++** Pipeline Associates, Inc.
++** pipeline!phw@motown.com or
++** sun!pipeline!phw or
++** uunet!motown!pipeline!phw
++**
++** 05/01/91 -- V1.0 -- first release to gcc mailing lists
++** 05/04/91 -- V1.1 -- added float and double prototypes and return values
++** -- fixed problems with adding and subtracting zero
++** -- fixed rounding in truncdfsf2
++** -- fixed SWAP define and tested on 386
++*/
++
++/*
++** The following are routines that replace the libgcc soft floating point
++** routines that are called automatically when -msoft-float is selected.
++** The support single and double precision IEEE format, with provisions
++** for byte-swapped machines (tested on 386). Some of the double-precision
++** routines work at full precision, but most of the hard ones simply punt
++** and call the single precision routines, producing a loss of accuracy.
++** long long support is not assumed or included.
++** Overall accuracy is close to IEEE (actually 68882) for single-precision
++** arithmetic. I think there may still be a 1 in 1000 chance of a bit
++** being rounded the wrong way during a multiply. I'm not fussy enough to
++** bother with it, but if anyone is, knock yourself out.
++**
++** Efficiency has only been addressed where it was obvious that something
++** would make a big difference. Anyone who wants to do this right for
++** best speed should go in and rewrite in assembler.
++**
++** I have tested this only on a 68030 workstation and 386/ix integrated
++** in with -msoft-float.
++*/
++
++#include "floatlib.h"
++
++/* convert double to int */
++long
++__fixdfsi (double a1)
++{
++ register union double_long dl1;
++ register int exp;
++ register long l;
++
++ dl1.d = a1;
++
++ if (!dl1.l.upper && !dl1.l.lower)
++ return (0);
++
++ exp = EXPD (dl1) - EXCESSD - 31;
++ l = MANTD (dl1);
++
++ if (exp > 0)
++ return SIGND(dl1) ? (1<<31) : ((1ul<<31)-1);
++
++ /* shift down until exp = 0 or l = 0 */
++ if (exp < 0 && exp > -32 && l)
++ l >>= -exp;
++ else
++ return (0);
++
++ return (SIGND (dl1) ? -l : l);
++}
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/microblaze/floatlib.h uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/floatlib.h
+--- uClibc-0.9.27/libc/sysdeps/linux/microblaze/floatlib.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/floatlib.h 2004-03-02 06:47:36.000000000 +0100
+@@ -0,0 +1,144 @@
++/*
++** libgcc support for software floating point.
++** Copyright (C) 1991 by Pipeline Associates, Inc. All rights reserved.
++** Permission is granted to do *anything* you want with this file,
++** commercial or otherwise, provided this message remains intact. So there!
++** I would appreciate receiving any updates/patches/changes that anyone
++** makes, and am willing to be the repository for said changes (am I
++** making a big mistake?).
++
++Warning! Only single-precision is actually implemented. This file
++won't really be much use until double-precision is supported.
++
++However, once that is done, this file might eventually become a
++replacement for libgcc1.c. It might also make possible
++cross-compilation for an IEEE target machine from a non-IEEE
++host such as a VAX.
++
++If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
++
++--> Double precision floating support added by James Carlson on 20 April 1998.
++
++**
++** Pat Wood
++** Pipeline Associates, Inc.
++** pipeline!phw@motown.com or
++** sun!pipeline!phw or
++** uunet!motown!pipeline!phw
++**
++** 05/01/91 -- V1.0 -- first release to gcc mailing lists
++** 05/04/91 -- V1.1 -- added float and double prototypes and return values
++** -- fixed problems with adding and subtracting zero
++** -- fixed rounding in truncdfsf2
++** -- fixed SWAP define and tested on 386
++*/
++
++/*
++** The following are routines that replace the libgcc soft floating point
++** routines that are called automatically when -msoft-float is selected.
++** The support single and double precision IEEE format, with provisions
++** for byte-swapped machines (tested on 386). Some of the double-precision
++** routines work at full precision, but most of the hard ones simply punt
++** and call the single precision routines, producing a loss of accuracy.
++** long long support is not assumed or included.
++** Overall accuracy is close to IEEE (actually 68882) for single-precision
++** arithmetic. I think there may still be a 1 in 1000 chance of a bit
++** being rounded the wrong way during a multiply. I'm not fussy enough to
++** bother with it, but if anyone is, knock yourself out.
++**
++** Efficiency has only been addressed where it was obvious that something
++** would make a big difference. Anyone who wants to do this right for
++** best speed should go in and rewrite in assembler.
++**
++** I have tested this only on a 68030 workstation and 386/ix integrated
++** in with -msoft-float.
++*/
++
++#ifndef __FLOAT_LIB_H__
++#define __FLOAT_LIB_H__
++/* the following deal with IEEE single-precision numbers */
++#define EXCESS 126
++#define SIGNBIT 0x80000000
++#define HIDDEN (1 << 23)
++#define SIGN(fp) ((fp) & SIGNBIT)
++#define EXP(fp) (((fp) >> 23) & 0xFF)
++#define MANT(fp) (((fp) & 0x7FFFFF) | HIDDEN)
++#define PACK(s,e,m) ((s) | ((e) << 23) | (m))
++
++/* the following deal with IEEE double-precision numbers */
++#define EXCESSD 1022
++#define HIDDEND (1 << 20)
++#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
++#define SIGND(fp) ((fp.l.upper) & SIGNBIT)
++#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
++ (fp.l.lower >> 22))
++#define HIDDEND_LL ((long long)1 << 52)
++#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
++#define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m))
++
++/* define SWAP for 386/960 reverse-byte-order brain-damaged CPUs */
++union double_long {
++ double d;
++#ifdef SWAP
++ struct {
++ unsigned long lower;
++ long upper;
++ } l;
++#else
++ struct {
++ long upper;
++ unsigned long lower;
++ } l;
++#endif
++ long long ll;
++};
++
++union float_long
++ {
++ float f;
++ long l;
++ };
++
++#endif
++
++/* Functions defined in different files */
++
++float __addsf3 (float, float);
++float __subsf3 (float, float);
++long __cmpsf2 (float, float);
++float __mulsf3 (float, float);
++float __divsf3 (float, float);
++double __floatsidf (register long);
++double __floatdidf (register long long);
++float __floatsisf (register long );
++float __floatdisf (register long long );
++float __negsf2 (float);
++double __negdf2 (double);
++double __extendsfdf2 (float);
++float __truncdfsf2 (double);
++long __cmpdf2 (double, double);
++long __fixsfsi (float);
++long __fixdfsi (double);
++long long __fixdfdi (double);
++unsigned long __fixunsdfsi (double);
++unsigned long long __fixunsdfdi (double);
++double __adddf3 (double, double);
++double __subdf3 (double, double);
++double __muldf3 (double, double);
++double __divdf3 (double, double);
++int __gtdf2 (double, double);
++int __gedf2 (double, double);
++int __ltdf2 (double, double);
++int __ledf2 (double, double);
++int __eqdf2 (double, double);
++int __nedf2 (double, double);
++int __gtsf2 (float, float);
++int __gesf2 (float, float);
++int __ltsf2 (float, float);
++int __lesf2 (float, float);
++int __eqsf2 (float, float);
++int __nesf2 (float, float);
++
++
++
++
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/microblaze/initfini.awk uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/initfini.awk
+--- uClibc-0.9.27/libc/sysdeps/linux/microblaze/initfini.awk 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/initfini.awk 2005-08-10 13:46:42.000000000 +0200
+@@ -0,0 +1,121 @@
++#! /usr/bin/awk -f
++# Contributed by Christian MICHON <christian_michon@yahoo.fr> to
++# eliminate the compile time dependancy on perl introduced by
++# Erik's older initfini.pl
++# vim:ai:sw=2:
++
++BEGIN \
++{ alignval="";
++ endp=0;
++ end=0;
++ system("touch crt[in].S");
++ system("/bin/rm -f crt[in].S");
++ omitcrti=0;
++ omitcrtn=0;
++ glb_idx = 0;
++ while(getline < "initfini.S")
++ { if(/\.endp/) {endp=1}
++ if(/\.end/) {end=1}
++ if(/\.align/) {alignval=$2}
++# here comes some special stuff for the SuperH targets
++# We search for all labels, which uses the _GLOBAL_OFFSET_TABLE_
++# or a call_gmon_start function reference, and store
++# them in the glb_label array.
++ if(/_init_EPILOG_BEGINS/) {glb_idx=1;glb_idx_arr[glb_idx]=0}
++ if(/_fini_EPILOG_BEGINS/) {glb_idx=2;glb_idx_arr[glb_idx]=0}
++ if(/EPILOG_ENDS/) {glb_idx=0}
++ if(/_GLOBAL_OFFSET_TABLE_/||/call_gmon_start/) {
++ glb_label[glb_idx,glb_idx_arr[glb_idx]] = last;
++ glb_idx_arr[glb_idx] += 1;
++ glb_label[glb_idx,glb_idx_arr[glb_idx]] = $0;
++ glb_idx_arr[glb_idx] += 1;
++ }
++ last = $1;
++ }
++ close("initfini.S");
++}
++# special rules for the SuperH targets (They do nothing on other targets)
++/SH_GLB_BEGINS/ && glb_idx_arr[1]==0 && glb_idx_arr[2]==0 {omitcrti +=1}
++/_init_SH_GLB/ {glb_idx=1}
++/_fini_SH_GLB/ {glb_idx=2}
++/SH_GLB_ENDS/ {omitcrti -=1}
++/SH_GLB/ \
++{
++ if (glb_idx>0)
++ {
++ for (i=0;i<glb_idx_arr[glb_idx];i+=1) {
++ print glb_label[glb_idx,i] >> "crti.S";
++ }
++ glb_idx = 0;
++ }
++ next;
++}
++# special rules for H8/300 (sorry quick hack)
++/.h8300h/ {end=0}
++
++# rules for all targets
++/HEADER_ENDS/{omitcrti=1;omitcrtn=1;getline}
++/PROLOG_BEGINS/{omitcrti=0;omitcrtn=0;getline}
++/i_am_not_a_leaf/{getline}
++/_init:/||/_fini:/{omitcrtn=1}
++/PROLOG_PAUSES/{omitcrti=1;getline}
++/PROLOG_UNPAUSES/{omitcrti=0;getline}
++/PROLOG_ENDS/{omitcrti=1;getline}
++/EPILOG_BEGINS/{omitcrtn=0;getline}
++/EPILOG_ENDS/{omitcrtn=1;getline}
++/TRAILER_BEGINS/{omitcrti=0;omitcrtn=0;getline}
++/GMON_STUFF_BEGINS/{omitcrtn=1;getline}
++/GMON_STUFF_PAUSES/{omitcrtn=0;getline}
++/GMON_STUFF_UNPAUSES/{omitcrtn=1;getline}
++/GMON_STUFF_ENDS/{omitcrtn=0;getline}
++
++/_GLOBAL_OFFSET_TABLE_/||/gmon_start/ \
++{
++ if(omitcrti==0) {print >> "crti.S";}
++ next; # no gmon_start or GLOBAL_OFFSET_TABLE references in crtn.S
++}
++
++/END_INIT/ \
++{ if(endp)
++ { gsub("END_INIT",".endp _init",$0)
++ }
++ else
++ { if(end)
++ { gsub("END_INIT",".end _init",$0)
++ }
++ else
++ { gsub("END_INIT","",$0)
++ }
++ }
++}
++
++/END_FINI/ \
++{ if(endp)
++ { gsub("END_FINI",".endp _fini",$0)
++ }
++ else
++ { if(end)
++ { gsub("END_FINI",".end _fini",$0)
++ }
++ else
++ { gsub("END_FINI","",$0)
++ }
++ }
++}
++
++/ALIGN/ \
++{ if(alignval!="")
++ { gsub("ALIGN",sprintf(".align %s",alignval),$0)
++ }
++ else
++ { gsub("ALIGN","",$0)
++ }
++}
++
++omitcrti==0 {print >> "crti.S"}
++omitcrtn==0 {print >> "crtn.S"}
++
++END \
++{ close("crti.S");
++ close("crtn.S");
++}
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/microblaze/initfini.c uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/initfini.c
+--- uClibc-0.9.27/libc/sysdeps/linux/microblaze/initfini.c 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/initfini.c 2005-08-10 13:46:42.000000000 +0200
+@@ -0,0 +1,172 @@
++/* Special .init and .fini section support.
++ Copyright (C) 1995, 1996, 1997, 2000 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.
++
++ In addition to the permissions in the GNU Lesser General Public
++ License, the Free Software Foundation gives you unlimited
++ permission to link the compiled version of this file with other
++ programs, and to distribute those programs without any restriction
++ coming from the use of this file. (The GNU Lesser General Public
++ License restrictions do apply in other respects; for example, they
++ cover modification of the file, and distribution when not linked
++ into another program.)
++
++ 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 file is compiled into assembly code which is then munged by a sed
++ script into two files: crti.s and crtn.s.
++
++ * crti.s puts a function prologue at the beginning of the
++ .init and .fini sections and defines global symbols for
++ those addresses, so they can be called as functions.
++
++ * crtn.s puts the corresponding function epilogues
++ in the .init and .fini sections. */
++
++#include <features.h>
++
++
++/* We use embedded asm for .section unconditionally, as this makes it
++ easier to insert the necessary directives into crtn.S. */
++#define SECTION(x) asm (".section " x );
++
++/* Declare symbols as hidden. Hidden symbols are only seen by
++ * the link editor and not by the dynamic loader. */
++#ifdef __HAVE_DOT_HIDDEN__
++# define HIDDEN(func) asm (".hidden " #func );
++#else
++# define HIDDEN(func)
++#endif
++
++#if defined(__sh__) && !defined(__SH5__)
++ /* The macro insert this sh specific stuff:
++ @_SH_GLB_BEGINS
++ bra 1f
++ nop
++ ALIGN
++ @func_SH_GLB_LABEL
++ 1:
++ @_SH_GLB_ENDS
++ */
++#define GLB_STUFF(func) asm ("\n/*@_SH_GLB_BEGINS*/"); \
++ asm ("\n\tbra\t1f\n\tnop\n\tALIGN\n/*@" #func"_SH_GLB_LABEL*/\n1:"); \
++ asm ("\n/*@_SH_GLB_ENDS*/");
++#else
++#define GLB_STUFF(func)
++#endif
++
++/* The initial common code ends here. */
++asm ("\n/*@HEADER_ENDS*/");
++
++/* To determine whether we need .end and .align: */
++//asm ("\n/*@TESTS_BEGIN*/");
++extern void dummy (void (*foo) (void));
++void
++dummy (void (*foo) (void))
++{
++ if (foo)
++ (*foo) ();
++}
++//asm ("\n/*@TESTS_END*/");
++
++/* The beginning of _init: */
++asm ("\n/*@_init_PROLOG_BEGINS*/");
++
++#ifdef GMON_SUPPORT
++asm ("\n/*@_init_GMON_STUFF_BEGINS*/");
++static void
++call_gmon_start(void)
++{
++ extern void __gmon_start__ (void) __attribute__ ((weak)); /*weak_extern (__gmon_start__);*/
++ void (*gmon_start) (void) = __gmon_start__;
++
++ if (gmon_start)
++ gmon_start ();
++}
++asm ("\n/*@_init_GMON_STUFF_PAUSES*/");
++#endif
++
++SECTION (".init")
++HIDDEN(_init)
++
++extern void i_am_not_a_leaf (void);
++extern void _init (void);
++void _init (void)
++{
++#ifdef GMON_SUPPORT
++asm ("\n/*@_init_GMON_STUFF_UNPAUSES*/");
++ /* We cannot use the normal constructor mechanism in gcrt1.o because it
++ appears before crtbegin.o in the link, so the header elt of .ctors
++ would come after the elt for __gmon_start__. One approach is for
++ gcrt1.o to reference a symbol which would be defined by some library
++ module which has a constructor; but then user code's constructors
++ would come first, and not be profiled. */
++ call_gmon_start ();
++asm ("\n/*@_init_GMON_STUFF_ENDS*/");
++#else
++ asm ("\n/*@_init_PROLOG_PAUSES*/");
++ {
++ /* Let GCC know that _init is not a leaf function by having a dummy
++ * function call here. We arrange for this call to be omitted from
++ * either crt file. */
++ i_am_not_a_leaf ();
++ }
++ asm ("\n/*@_init_PROLOG_UNPAUSES*/");
++#endif
++
++ GLB_STUFF(_init)
++ asm ("ALIGN");
++ asm("END_INIT");
++ /* Now the epilog. */
++ asm ("\n/*@_init_PROLOG_ENDS*/");
++ asm ("\n/*@_init_EPILOG_BEGINS*/");
++}
++
++/* End of the _init epilog, beginning of the _fini prolog. */
++asm ("\n/*@_init_EPILOG_ENDS*/");
++asm ("\n/*@_fini_PROLOG_BEGINS*/");
++
++SECTION (".fini")
++HIDDEN(_fini)
++
++extern void i_am_not_a_leaf2 (void);
++extern void _fini (void);
++void _fini (void)
++{
++
++ /* End of the _fini prolog. */
++ GLB_STUFF(_fini)
++ asm ("ALIGN");
++ asm ("END_FINI");
++ asm ("\n/*@_fini_PROLOG_ENDS*/");
++
++ {
++ /* Let GCC know that _fini is not a leaf function by having a dummy
++ function call here. We arrange for this call to be omitted from
++ either crt file. */
++ i_am_not_a_leaf2 ();
++ }
++
++ /* Beginning of the _fini epilog. */
++ asm ("\n/*@_fini_EPILOG_BEGINS*/");
++}
++
++/* End of the _fini epilog. Any further generated assembly (e.g. .ident)
++ is shared between both crt files. */
++asm ("\n/*@_fini_EPILOG_ENDS*/");
++asm ("\n/*@TRAILER_BEGINS*/");
++
++/* End of file. */
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/microblaze/__longjmp.S uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/__longjmp.S
+--- uClibc-0.9.27/libc/sysdeps/linux/microblaze/__longjmp.S 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/__longjmp.S 2003-12-01 06:55:42.000000000 +0100
+@@ -23,19 +23,21 @@
+ /* load registers from memory to r5 (arg0)*/
+ lwi r1, r5, 0
+ lwi r15, r5, 4
+- lwi r18, r5, 8
+- lwi r19, r5, 12
+- lwi r20, r5, 16
+- lwi r21, r5, 20
+- lwi r22, r5, 24
+- lwi r23, r5, 28
+- lwi r24, r5, 32
+- lwi r25, r5, 36
+- lwi r26, r5, 40
+- lwi r27, r5, 44
+- lwi r28, r5, 48
+- lwi r29, r5, 52
+- lwi r30, r5, 56
++ lwi r2, r5, 8
++ lwi r13, r5, 12
++ lwi r18, r5, 16
++ lwi r19, r5, 20
++ lwi r20, r5, 24
++ lwi r21, r5, 28
++ lwi r22, r5, 32
++ lwi r23, r5, 36
++ lwi r24, r5, 40
++ lwi r25, r5, 44
++ lwi r26, r5, 48
++ lwi r27, r5, 52
++ lwi r28, r5, 56
++ lwi r29, r5, 60
++ lwi r30, r5, 64
+
+ addi r3, r0, 1 // return val
+ rtsd r15, 8 // normal return
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/microblaze/Makefile uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/Makefile
+--- uClibc-0.9.27/libc/sysdeps/linux/microblaze/Makefile 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/Makefile 2005-08-10 13:46:42.000000000 +0200
+@@ -21,7 +21,7 @@
+ include $(TOPDIR)Rules.mak
+
+ #FIXME -- this arch should include its own crti.S and crtn.S
+-UCLIBC_CTOR_DTOR=n
++UCLIBC_CTOR_DTOR=y
+
+ CFLAGS+=-I..
+ ASFLAGS+=-I.. -D__ASSEMBLER -DASM_GLOBAL_DIRECTIVE=.globl
+@@ -35,7 +35,7 @@
+ SSRC = setjmp.S __longjmp.S vfork.S
+ SOBJS = $(patsubst %.S,%.o, $(SSRC))
+
+-CSRC = mmap.c syscall.c clone.c
++CSRC = mmap.c syscall.c clone.c fixdfsi.c
+ COBJS = $(patsubst %.c,%.o, $(CSRC))
+
+ OBJS = $(SOBJS) $(COBJS)
+@@ -46,6 +46,7 @@
+
+ ar-target: $(OBJS) $(CRT0_OBJ) $(CTOR_TARGETS)
+ $(AR) $(ARFLAGS) $(LIBC) $(OBJS)
++ mkdir -p $(TOPDIR)lib/
+ cp $(CRT0_OBJ) $(TOPDIR)lib/
+
+ $(CRT0_OBJ): $(CRT0_SRC)
+@@ -61,25 +62,18 @@
+ $(STRIPTOOL) -x -R .note -R .comment $*.o
+
+ ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
+-crti.o: crti.S
+- $(CC) $(ASFLAGS) -c crti.S -o crti.o
++initfini.S: initfini.c
++ $(CC) $(SAFECFLAGS) -I$(TOPDIR)include -c initfini.c -S -o initfini.S
++
++crti.S crtn.S: initfini.S initfini.awk
++ awk -f initfini.awk initfini.S
+
+ $(TOPDIR)lib/crti.o: crti.o
+ $(INSTALL) -d $(TOPDIR)lib/
+- cp crti.o $(TOPDIR)lib/
+-
+-crtn.o: crtn.S
+- $(CC) $(ASFLAGS) -c crtn.S -o crtn.o
++ $(AR) $(ARFLAGS) $(TOPDIR)lib/crti.o
+
+ $(TOPDIR)lib/crtn.o: crtn.o
+ $(INSTALL) -d $(TOPDIR)lib/
+- cp crtn.o $(TOPDIR)lib/
+-else
+-$(TOPDIR)lib/crti.o:
+- $(INSTALL) -d $(TOPDIR)lib/
+- $(AR) $(ARFLAGS) $(TOPDIR)lib/crti.o
+-$(TOPDIR)lib/crtn.o:
+- $(INSTALL) -d $(TOPDIR)lib/
+ $(AR) $(ARFLAGS) $(TOPDIR)lib/crtn.o
+ endif
+
+@@ -89,4 +83,10 @@
+ clean:
+ $(RM) *.[oa] *~ core
+ $(RM) bits/sysnum.h
++ ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
++ $(RM) initfini.S
++ $(RM) crti.S
++ $(RM) crto.S
++ endif
++
+
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/microblaze/setjmp.S uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/setjmp.S
+--- uClibc-0.9.27/libc/sysdeps/linux/microblaze/setjmp.S 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/setjmp.S 2003-12-01 06:55:42.000000000 +0100
+@@ -33,19 +33,22 @@
+ /* Save registers relative to r5 (arg0)*/
+ swi r1, r5, 0 /* stack pointer */
+ swi r15, r5, 4 /* link register */
+- swi r18, r5, 8 /* assembler temp */
+- swi r19, r5, 12 /* now call-preserved regs */
+- swi r20, r5, 16
+- swi r21, r5, 20
+- swi r22, r5, 24
+- swi r23, r5, 28
+- swi r24, r5, 32
+- swi r25, r5, 36
+- swi r26, r5, 40
+- swi r27, r5, 44
+- swi r28, r5, 48
+- swi r29, r5, 52
+- swi r30, r5, 56
++ swi r2, r5, 8 /* SDA and SDA2 ptrs */
++ swi r13, r5, 12
++ swi r18, r5, 16 /* assembler temp */
++ swi r19, r5, 20 /* now call-preserved regs */
++ swi r20, r5, 24
++ swi r21, r5, 28
++ swi r22, r5, 32
++ swi r23, r5, 36
++ swi r24, r5, 40
++ swi r25, r5, 44
++ swi r26, r5, 48
++ swi r27, r5, 52
++ swi r28, r5, 56
++ swi r29, r5, 60
++ swi r30, r5, 64
++ swi r31, r5, 68
+
+ /* Make a tail call to __sigjmp_save; it takes the same args. */
+ braid C_SYMBOL_NAME(__sigjmp_save)
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/microblaze/sys/procfs.h uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/sys/procfs.h
+--- uClibc-0.9.27/libc/sysdeps/linux/microblaze/sys/procfs.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/sys/procfs.h 2003-12-01 06:55:42.000000000 +0100
+@@ -0,0 +1,130 @@
++/* Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002 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. */
++
++#ifndef _SYS_PROCFS_H
++#define _SYS_PROCFS_H 1
++
++/* This is somewhat modelled after the file of the same name on SVR4
++ systems. It provides a definition of the core file format for ELF
++ used on Linux. It doesn't have anything to do with the /proc file
++ system, even though Linux has one.
++
++ Anyway, the whole purpose of this file is for GDB and GDB only.
++ Don't read too much into it. Don't use it for anything other than
++ GDB unless you know what you are doing. */
++
++#include <features.h>
++#include <sys/time.h>
++#include <sys/types.h>
++
++
++/* Type for a general-purpose register. */
++typedef unsigned long elf_greg_t;
++
++/* This is exactly the same as `struct pt_regs' in the kernel. */
++struct elf_gregset
++{
++ elf_greg_t gpr[32]; /* General purpose registers. */
++
++ elf_greg_t pc; /* program counter */
++ elf_greg_t psw; /* program status word */
++
++ elf_greg_t kernel_mode; /* 1 if in `kernel mode', 0 if user mode */
++ elf_greg_t single_step; /* 1 if in single step mode */
++};
++
++#define ELF_NGREG (sizeof (struct elf_gregset) / sizeof(elf_greg_t))
++typedef elf_greg_t elf_gregset_t[ELF_NGREG];
++
++/* Register set for the floating-point registers. */
++typedef void elf_fpregset_t;
++
++struct elf_siginfo
++{
++ int si_signo; /* signal number */
++ int si_code; /* extra code */
++ int si_errno; /* errno */
++};
++
++
++/*
++ * Definitions to generate Intel SVR4-like core files.
++ * These mostly have the same names as the SVR4 types with "elf_"
++ * tacked on the front to prevent clashes with linux definitions,
++ * and the typedef forms have been avoided. This is mostly like
++ * the SVR4 structure, but more Linuxy, with things that Linux does
++ * not support and which gdb doesn't really use excluded.
++ * Fields present but not used are marked with "XXX".
++ */
++struct elf_prstatus
++{
++ struct elf_siginfo pr_info; /* Info associated with signal */
++ short pr_cursig; /* Current signal */
++ unsigned long pr_sigpend; /* Set of pending signals */
++ unsigned long pr_sighold; /* Set of held signals */
++ __kernel_pid_t pr_pid;
++ __kernel_pid_t pr_ppid;
++ __kernel_pid_t pr_pgrp;
++ __kernel_pid_t pr_sid;
++ struct timeval pr_utime; /* User time */
++ struct timeval pr_stime; /* System time */
++ struct timeval pr_cutime; /* Cumulative user time */
++ struct timeval pr_cstime; /* Cumulative system time */
++ elf_gregset_t pr_reg; /* GP registers */
++ int pr_fpvalid; /* True if math co-processor being used. */
++};
++
++#define ELF_PRARGSZ (80) /* Number of chars for args */
++
++struct elf_prpsinfo
++{
++ char pr_state; /* numeric process state */
++ char pr_sname; /* char for pr_state */
++ char pr_zomb; /* zombie */
++ char pr_nice; /* nice val */
++ unsigned long pr_flag; /* flags */
++ __kernel_uid_t pr_uid;
++ __kernel_gid_t pr_gid;
++ __kernel_pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
++ /* Lots missing */
++ char pr_fname[16]; /* filename of executable */
++ char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
++};
++
++
++/* The rest of this file provides the types for emulation of the
++ Solaris <proc_service.h> interfaces that should be implemented by
++ users of libthread_db. */
++
++/* Addresses. */
++typedef void *psaddr_t;
++
++/* Register sets. Linux has different names. */
++typedef elf_gregset_t prgregset_t;
++typedef elf_fpregset_t prfpregset_t;
++
++/* We don't have any differences between processes and threads,
++ therefore have only one PID type. */
++typedef __kernel_pid_t lwpid_t;
++
++/* Process status and info. In the end we do provide typedefs for them. */
++typedef struct elf_prstatus prstatus_t;
++typedef struct elf_prpsinfo prpsinfo_t;
++
++
++#endif /* sys/procfs.h */
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/microblaze/sys/ptrace.h uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/sys/ptrace.h
+--- uClibc-0.9.27/libc/sysdeps/linux/microblaze/sys/ptrace.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/sys/ptrace.h 2003-12-01 06:55:42.000000000 +0100
+@@ -1,5 +1,5 @@
+ /* `ptrace' debugger support interface. Linux/microblaze version.
+- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
++ Copyright (C) 2001, 2002, 2003 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
+@@ -65,12 +65,16 @@
+ PTRACE_KILL = 8,
+ #define PT_KILL PTRACE_KILL
+
++ /* Single step the process. */
++ PTRACE_SINGLESTEP = 9,
++#define PT_STEP PTRACE_SINGLESTEP
++
+ /* Attach to a process that is already running. */
+- PTRACE_ATTACH = 0x10,
++ PTRACE_ATTACH = 16,
+ #define PT_ATTACH PTRACE_ATTACH
+
+ /* Detach from a process attached to with PTRACE_ATTACH. */
+- PTRACE_DETACH = 0x11,
++ PTRACE_DETACH = 17,
+ #define PT_DETACH PTRACE_DETACH
+
+ /* Continue and stop at the next (return from) syscall. */
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/microblaze/syscall.c uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/syscall.c
+--- uClibc-0.9.27/libc/sysdeps/linux/microblaze/syscall.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/syscall.c 2005-08-05 03:10:51.000000000 +0200
+@@ -26,26 +26,21 @@
+ off the stack even for (the majority of) system calls with fewer
+ arguments; hopefully this won't cause any problems. A1-A4 are in
+ registers, so they're OK. */
+- register arg_t a asm (SYSCALL_ARG0) = a1;
+- register arg_t b asm (SYSCALL_ARG1) = a2;
+- register arg_t c asm (SYSCALL_ARG2) = a3;
+- register arg_t d asm (SYSCALL_ARG3) = a4;
+- register arg_t e asm (SYSCALL_ARG4) = a5;
+- register arg_t f asm (SYSCALL_ARG5) = a6;
+- register unsigned long syscall asm (SYSCALL_NUM) = num;
+- register unsigned long ret asm (SYSCALL_RET);
+- unsigned long ret_sav;
++ register unsigned long ret;
+
+- *((unsigned long *)0xFFFF4004) = (unsigned int)('+');
+- asm ("brlid r17, 08x; nop;"
++ asm ( "addk r5, r0, %2 \n\t"
++ "addk r6, r0, %3 \n\t"
++ "addk r7, r0, %4 \n\t"
++ "addk r8, r0, %5 \n\t"
++ "addk r9, r0, %6 \n\t"
++ "addk r10,r0, %7 \n\t"
++ "addk r12,r0, %1 \n\t"
++ "brki r14, 0x08 \n\t"
++ "addk %0, r0, r3 \n\t"
+ : "=r" (ret)
+- : "r" (syscall), "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f)
+- : SYSCALL_CLOBBERS);
++ : "r" (syscall), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5),
++ "r" (a6)
++ : "r3", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "r14", "cc");
+
+- ret_sav=ret;
+- *((unsigned long *)0xFFFF4004) = (unsigned int)('-');
+-
+-
+-
+ __syscall_return (long, ret);
+ }
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/microblaze/vfork.S uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/vfork.S
+--- uClibc-0.9.27/libc/sysdeps/linux/microblaze/vfork.S 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/microblaze/vfork.S 2005-08-05 03:10:51.000000000 +0200
+@@ -29,15 +29,14 @@
+
+ C_ENTRY (__vfork):
+ addi r12, r0, SYS_vfork
+- bralid r17, 0x08;
+- nop
++ brki r14, 0x08;
+ addi r4, r3, 125 // minimum err value
+ blti r4, 1f // is r3 < -125?
+- rtsd r15, 8 // normal return
+- nop
++ bri 2f // normal return
+ 1: sub r3, r3, r0 // r3 = -r3
+ swi r3, r0, C_SYMBOL_NAME(errno);
+- rtsd r15, 8 // error return
++ // state restore etc
++2: rtsd r15, 8 // error return
+ nop
+ C_END(__vfork)
+
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/mips/bits/atomic.h uClibc-0.9.27-uc0/libc/sysdeps/linux/mips/bits/atomic.h
+--- uClibc-0.9.27/libc/sysdeps/linux/mips/bits/atomic.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/mips/bits/atomic.h 2006-01-16 07:46:31.000000000 +0100
+@@ -0,0 +1,303 @@
++/* Low-level functions for atomic operations. Mips version.
++ Copyright (C) 2005 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. */
++
++#ifndef _MIPS_BITS_ATOMIC_H
++#define _MIPS_BITS_ATOMIC_H 1
++
++#include <inttypes.h>
++#include <sgidefs.h>
++
++typedef int32_t atomic32_t;
++typedef uint32_t uatomic32_t;
++typedef int_fast32_t atomic_fast32_t;
++typedef uint_fast32_t uatomic_fast32_t;
++
++typedef int64_t atomic64_t;
++typedef uint64_t uatomic64_t;
++typedef int_fast64_t atomic_fast64_t;
++typedef uint_fast64_t uatomic_fast64_t;
++
++typedef intptr_t atomicptr_t;
++typedef uintptr_t uatomicptr_t;
++typedef intmax_t atomic_max_t;
++typedef uintmax_t uatomic_max_t;
++
++#if _MIPS_SIM == _ABIO32
++#define MIPS_PUSH_MIPS2 ".set mips2\n\t"
++#else
++#define MIPS_PUSH_MIPS2
++#endif
++
++/* See the comments in <sys/asm.h> about the use of the sync instruction. */
++#ifndef MIPS_SYNC
++# define MIPS_SYNC sync
++#endif
++
++#define MIPS_SYNC_STR_2(X) #X
++#define MIPS_SYNC_STR_1(X) MIPS_SYNC_STR_2(X)
++#define MIPS_SYNC_STR MIPS_SYNC_STR_1(MIPS_SYNC)
++
++/* Compare and exchange. For all of the "xxx" routines, we expect a
++ "__prev" and a "__cmp" variable to be provided by the enclosing scope,
++ in which values are returned. */
++
++#define __arch_compare_and_exchange_xxx_8_int(mem, newval, oldval, rel, acq) \
++ (abort (), __prev = __cmp = 0)
++
++#define __arch_compare_and_exchange_xxx_16_int(mem, newval, oldval, rel, acq) \
++ (abort (), __prev = __cmp = 0)
++
++#define __arch_compare_and_exchange_xxx_32_int(mem, newval, oldval, rel, acq) \
++ __asm__ __volatile__ ( \
++ ".set push\n\t" \
++ MIPS_PUSH_MIPS2 \
++ rel "\n" \
++ "1:\t" \
++ "ll %0,%4\n\t" \
++ "move %1,$0\n\t" \
++ "bne %0,%2,2f\n\t" \
++ "move %1,%3\n\t" \
++ "sc %1,%4\n\t" \
++ "beqz %1,1b\n" \
++ acq "\n\t" \
++ ".set pop\n" \
++ "2:\n\t" \
++ : "=&r" (__prev), "=&r" (__cmp) \
++ : "r" (oldval), "r" (newval), "m" (*mem) \
++ : "memory")
++
++#if _MIPS_SIM == _ABIO32
++/* We can't do an atomic 64-bit operation in O32. */
++#define __arch_compare_and_exchange_xxx_64_int(mem, newval, oldval, rel, acq) \
++ (abort (), __prev = __cmp = 0)
++#else
++#define __arch_compare_and_exchange_xxx_64_int(mem, newval, oldval, rel, acq) \
++ __asm__ __volatile__ ("\n" \
++ ".set push\n\t" \
++ MIPS_PUSH_MIPS2 \
++ rel "\n" \
++ "1:\t" \
++ "lld %0,%4\n\t" \
++ "move %1,$0\n\t" \
++ "bne %0,%2,2f\n\t" \
++ "move %1,%3\n\t" \
++ "scd %1,%4\n\t" \
++ "beqz %1,1b\n" \
++ acq "\n\t" \
++ ".set pop\n" \
++ "2:\n\t" \
++ : "=&r" (__prev), "=&r" (__cmp) \
++ : "r" (oldval), "r" (newval), "m" (*mem) \
++ : "memory")
++#endif
++
++/* For all "bool" routines, we return FALSE if exchange succesful. */
++
++#define __arch_compare_and_exchange_bool_8_int(mem, new, old, rel, acq) \
++({ typeof (*mem) __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_8_int(mem, new, old, rel, acq); \
++ !__cmp; })
++
++#define __arch_compare_and_exchange_bool_16_int(mem, new, old, rel, acq) \
++({ typeof (*mem) __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_16_int(mem, new, old, rel, acq); \
++ !__cmp; })
++
++#define __arch_compare_and_exchange_bool_32_int(mem, new, old, rel, acq) \
++({ typeof (*mem) __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_32_int(mem, new, old, rel, acq); \
++ !__cmp; })
++
++#define __arch_compare_and_exchange_bool_64_int(mem, new, old, rel, acq) \
++({ typeof (*mem) __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_64_int(mem, new, old, rel, acq); \
++ !__cmp; })
++
++/* For all "val" routines, return the old value whether exchange
++ successful or not. */
++
++#define __arch_compare_and_exchange_val_8_int(mem, new, old, rel, acq) \
++({ typeof (*mem) __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_8_int(mem, new, old, rel, acq); \
++ (typeof (*mem))__prev; })
++
++#define __arch_compare_and_exchange_val_16_int(mem, new, old, rel, acq) \
++({ typeof (*mem) __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_16_int(mem, new, old, rel, acq); \
++ (typeof (*mem))__prev; })
++
++#define __arch_compare_and_exchange_val_32_int(mem, new, old, rel, acq) \
++({ typeof (*mem) __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_32_int(mem, new, old, rel, acq); \
++ (typeof (*mem))__prev; })
++
++#define __arch_compare_and_exchange_val_64_int(mem, new, old, rel, acq) \
++({ typeof (*mem) __prev; int __cmp; \
++ __arch_compare_and_exchange_xxx_64_int(mem, new, old, rel, acq); \
++ (typeof (*mem))__prev; })
++
++/* Compare and exchange with "acquire" semantics, ie barrier after. */
++
++#define atomic_compare_and_exchange_bool_acq(mem, new, old) \
++ __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
++ mem, new, old, "", MIPS_SYNC_STR)
++
++#define atomic_compare_and_exchange_val_acq(mem, new, old) \
++ __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
++ mem, new, old, "", MIPS_SYNC_STR)
++
++/* Compare and exchange with "release" semantics, ie barrier before. */
++
++#define atomic_compare_and_exchange_bool_rel(mem, new, old) \
++ __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
++ mem, new, old, MIPS_SYNC_STR, "")
++
++#define atomic_compare_and_exchange_val_rel(mem, new, old) \
++ __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
++ mem, new, old, MIPS_SYNC_STR, "")
++
++
++
++/* Atomic exchange (without compare). */
++
++#define __arch_exchange_xxx_8_int(mem, newval, rel, acq) \
++ (abort (), 0)
++
++#define __arch_exchange_xxx_16_int(mem, newval, rel, acq) \
++ (abort (), 0)
++
++#define __arch_exchange_xxx_32_int(mem, newval, rel, acq) \
++({ typeof (*mem) __prev; int __cmp; \
++ __asm__ __volatile__ ("\n" \
++ ".set push\n\t" \
++ MIPS_PUSH_MIPS2 \
++ rel "\n" \
++ "1:\t" \
++ "ll %0,%3\n\t" \
++ "move %1,%2\n\t" \
++ "sc %1,%3\n\t" \
++ "beqz %1,1b\n" \
++ acq "\n\t" \
++ ".set pop\n" \
++ "2:\n\t" \
++ : "=&r" (__prev), "=&r" (__cmp) \
++ : "r" (newval), "m" (*mem) \
++ : "memory"); \
++ __prev; })
++
++#if _MIPS_SIM == _ABIO32
++/* We can't do an atomic 64-bit operation in O32. */
++#define __arch_exchange_xxx_64_int(mem, newval, rel, acq) \
++ (abort (), 0)
++#else
++#define __arch_exchange_xxx_64_int(mem, newval, rel, acq) \
++({ typeof (*mem) __prev; int __cmp; \
++ __asm__ __volatile__ ("\n" \
++ ".set push\n\t" \
++ MIPS_PUSH_MIPS2 \
++ rel "\n" \
++ "1:\n" \
++ "lld %0,%3\n\t" \
++ "move %1,%2\n\t" \
++ "scd %1,%3\n\t" \
++ "beqz %1,1b\n" \
++ acq "\n\t" \
++ ".set pop\n" \
++ "2:\n\t" \
++ : "=&r" (__prev), "=&r" (__cmp) \
++ : "r" (newval), "m" (*mem) \
++ : "memory"); \
++ __prev; })
++#endif
++
++#define atomic_exchange_acq(mem, value) \
++ __atomic_val_bysize (__arch_exchange_xxx, int, mem, value, "", MIPS_SYNC_STR)
++
++#define atomic_exchange_rel(mem, value) \
++ __atomic_val_bysize (__arch_exchange_xxx, int, mem, value, MIPS_SYNC_STR, "")
++
++
++/* Atomically add value and return the previous (unincremented) value. */
++
++#define __arch_exchange_and_add_8_int(mem, newval, rel, acq) \
++ (abort (), (typeof(*mem)) 0)
++
++#define __arch_exchange_and_add_16_int(mem, newval, rel, acq) \
++ (abort (), (typeof(*mem)) 0)
++
++#define __arch_exchange_and_add_32_int(mem, value, rel, acq) \
++({ typeof (*mem) __prev; int __cmp; \
++ __asm__ __volatile__ ("\n" \
++ ".set push\n\t" \
++ MIPS_PUSH_MIPS2 \
++ rel "\n" \
++ "1:\t" \
++ "ll %0,%3\n\t" \
++ "addu %1,%0,%2\n\t" \
++ "sc %1,%3\n\t" \
++ "beqz %1,1b\n" \
++ acq "\n\t" \
++ ".set pop\n" \
++ "2:\n\t" \
++ : "=&r" (__prev), "=&r" (__cmp) \
++ : "r" (value), "m" (*mem) \
++ : "memory"); \
++ __prev; })
++
++#if _MIPS_SIM == _ABIO32
++/* We can't do an atomic 64-bit operation in O32. */
++#define __arch_exchange_and_add_64_int(mem, value, rel, acq) \
++ (abort (), (typeof(*mem)) 0)
++#else
++#define __arch_exchange_and_add_64_int(mem, value, rel, acq) \
++({ typeof (*mem) __prev; int __cmp; \
++ __asm__ __volatile__ ( \
++ ".set push\n\t" \
++ MIPS_PUSH_MIPS2 \
++ rel "\n" \
++ "1:\t" \
++ "lld %0,%3\n\t" \
++ "daddu %1,%0,%2\n\t" \
++ "scd %1,%3\n\t" \
++ "beqz %1,1b\n" \
++ acq "\n\t" \
++ ".set pop\n" \
++ "2:\n\t" \
++ : "=&r" (__prev), "=&r" (__cmp) \
++ : "r" (value), "m" (*mem) \
++ : "memory"); \
++ __prev; })
++#endif
++
++/* ??? Barrier semantics for atomic_exchange_and_add appear to be
++ undefined. Use full barrier for now, as that's safe. */
++#define atomic_exchange_and_add(mem, value) \
++ __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \
++ MIPS_SYNC_STR, MIPS_SYNC_STR)
++
++/* TODO: More atomic operations could be implemented efficiently; only the
++ basic requirements are done. */
++
++#define atomic_full_barrier() \
++ __asm__ __volatile__ (".set push\n\t" \
++ MIPS_PUSH_MIPS2 \
++ MIPS_SYNC_STR "\n\t" \
++ ".set pop" : : : "memory")
++
++#endif /* bits/atomic.h */
+diff -urN uClibc-0.9.27/libc/sysdeps/linux/sh/bits/atomic.h uClibc-0.9.27-uc0/libc/sysdeps/linux/sh/bits/atomic.h
+--- uClibc-0.9.27/libc/sysdeps/linux/sh/bits/atomic.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libc/sysdeps/linux/sh/bits/atomic.h 2006-01-16 07:46:31.000000000 +0100
+@@ -0,0 +1,419 @@
++/* Atomic operations used inside libc. Linux/SH version.
++ Copyright (C) 2003 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 <stdint.h>
++
++
++typedef int8_t atomic8_t;
++typedef uint8_t uatomic8_t;
++typedef int_fast8_t atomic_fast8_t;
++typedef uint_fast8_t uatomic_fast8_t;
++
++typedef int16_t atomic16_t;
++typedef uint16_t uatomic16_t;
++typedef int_fast16_t atomic_fast16_t;
++typedef uint_fast16_t uatomic_fast16_t;
++
++typedef int32_t atomic32_t;
++typedef uint32_t uatomic32_t;
++typedef int_fast32_t atomic_fast32_t;
++typedef uint_fast32_t uatomic_fast32_t;
++
++typedef int64_t atomic64_t;
++typedef uint64_t uatomic64_t;
++typedef int_fast64_t atomic_fast64_t;
++typedef uint_fast64_t uatomic_fast64_t;
++
++typedef intptr_t atomicptr_t;
++typedef uintptr_t uatomicptr_t;
++typedef intmax_t atomic_max_t;
++typedef uintmax_t uatomic_max_t;
++
++/* SH kernel has implemented a gUSA ("g" User Space Atomicity) support
++ for the user space atomicity. The atomicity macros use this scheme.
++
++ Reference:
++ Niibe Yutaka, "gUSA: Simple and Efficient User Space Atomicity
++ Emulation with Little Kernel Modification", Linux Conference 2002,
++ Japan. http://lc.linux.or.jp/lc2002/papers/niibe0919h.pdf (in
++ Japanese).
++
++ B.N. Bershad, D. Redell, and J. Ellis, "Fast Mutual Exclusion for
++ Uniprocessors", Proceedings of the Fifth Architectural Support for
++ Programming Languages and Operating Systems (ASPLOS), pp. 223-233,
++ October 1992. http://www.cs.washington.edu/homes/bershad/Papers/Rcs.ps
++
++ SuperH ABI:
++ r15: -(size of atomic instruction sequence) < 0
++ r0: end point
++ r1: saved stack pointer
++*/
++
++#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
++ ({ __typeof (*(mem)) __result; \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ nop\n\
++ mov r15,r1\n\
++ mov #-8,r15\n\
++ 0: mov.b @%1,%0\n\
++ cmp/eq %0,%3\n\
++ bf 1f\n\
++ mov.b %2,@%1\n\
++ 1: mov r1,r15"\
++ : "=&r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
++ : "r0", "r1", "t", "memory"); \
++ __result; })
++
++#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
++ ({ __typeof (*(mem)) __result; \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ nop\n\
++ mov r15,r1\n\
++ mov #-8,r15\n\
++ 0: mov.w @%1,%0\n\
++ cmp/eq %0,%3\n\
++ bf 1f\n\
++ mov.w %2,@%1\n\
++ 1: mov r1,r15"\
++ : "=&r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
++ : "r0", "r1", "t", "memory"); \
++ __result; })
++
++#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
++ ({ __typeof (*(mem)) __result; \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ nop\n\
++ mov r15,r1\n\
++ mov #-8,r15\n\
++ 0: mov.l @%1,%0\n\
++ cmp/eq %0,%3\n\
++ bf 1f\n\
++ mov.l %2,@%1\n\
++ 1: mov r1,r15"\
++ : "=&r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
++ : "r0", "r1", "t", "memory"); \
++ __result; })
++
++/* XXX We do not really need 64-bit compare-and-exchange. At least
++ not in the moment. Using it would mean causing portability
++ problems since not many other 32-bit architectures have support for
++ such an operation. So don't define any code for now. */
++
++# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
++ (abort (), (__typeof (*mem)) 0)
++
++#define atomic_exchange_and_add(mem, value) \
++ ({ __typeof (*(mem)) __result, __tmp, __value = (value); \
++ if (sizeof (*(mem)) == 1) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.b @%2,%0\n\
++ add %0,%1\n\
++ mov.b %1,@%2\n\
++ 1: mov r1,r15"\
++ : "=&r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
++ : "r0", "r1", "memory"); \
++ else if (sizeof (*(mem)) == 2) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.w @%2,%0\n\
++ add %0,%1\n\
++ mov.w %1,@%2\n\
++ 1: mov r1,r15"\
++ : "=&r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
++ : "r0", "r1", "memory"); \
++ else if (sizeof (*(mem)) == 4) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.l @%2,%0\n\
++ add %0,%1\n\
++ mov.l %1,@%2\n\
++ 1: mov r1,r15"\
++ : "=&r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
++ : "r0", "r1", "memory"); \
++ else \
++ { \
++ __typeof (mem) memp = (mem); \
++ do \
++ __result = *memp; \
++ while (__arch_compare_and_exchange_val_64_acq \
++ (memp, __result + __value, __result) == __result); \
++ (void) __value; \
++ } \
++ __result; })
++
++#define atomic_add(mem, value) \
++ (void) ({ __typeof (*(mem)) __tmp, __value = (value); \
++ if (sizeof (*(mem)) == 1) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.b @%1,r2\n\
++ add r2,%0\n\
++ mov.b %0,@%1\n\
++ 1: mov r1,r15"\
++ : "=&r" (__tmp) : "r" (mem), "0" (__value) \
++ : "r0", "r1", "r2", "memory"); \
++ else if (sizeof (*(mem)) == 2) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.w @%1,r2\n\
++ add r2,%0\n\
++ mov.w %0,@%1\n\
++ 1: mov r1,r15"\
++ : "=&r" (__tmp) : "r" (mem), "0" (__value) \
++ : "r0", "r1", "r2", "memory"); \
++ else if (sizeof (*(mem)) == 4) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.l @%1,r2\n\
++ add r2,%0\n\
++ mov.l %0,@%1\n\
++ 1: mov r1,r15"\
++ : "=&r" (__tmp) : "r" (mem), "0" (__value) \
++ : "r0", "r1", "r2", "memory"); \
++ else \
++ { \
++ __typeof (*(mem)) oldval; \
++ __typeof (mem) memp = (mem); \
++ do \
++ oldval = *memp; \
++ while (__arch_compare_and_exchange_val_64_acq \
++ (memp, oldval + __value, oldval) == oldval); \
++ (void) __value; \
++ } \
++ })
++
++#define atomic_add_negative(mem, value) \
++ ({ unsigned char __result; \
++ __typeof (*(mem)) __tmp, __value = (value); \
++ if (sizeof (*(mem)) == 1) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.b @%2,r2\n\
++ add r2,%1\n\
++ mov.b %1,@%2\n\
++ 1: mov r1,r15\n\
++ shal %1\n\
++ movt %0"\
++ : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
++ : "r0", "r1", "r2", "t", "memory"); \
++ else if (sizeof (*(mem)) == 2) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.w @%2,r2\n\
++ add r2,%1\n\
++ mov.w %1,@%2\n\
++ 1: mov r1,r15\n\
++ shal %1\n\
++ movt %0"\
++ : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
++ : "r0", "r1", "r2", "t", "memory"); \
++ else if (sizeof (*(mem)) == 4) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.l @%2,r2\n\
++ add r2,%1\n\
++ mov.l %1,@%2\n\
++ 1: mov r1,r15\n\
++ shal %1\n\
++ movt %0"\
++ : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
++ : "r0", "r1", "r2", "t", "memory"); \
++ else \
++ abort (); \
++ __result; })
++
++#define atomic_add_zero(mem, value) \
++ ({ unsigned char __result; \
++ __typeof (*(mem)) __tmp, __value = (value); \
++ if (sizeof (*(mem)) == 1) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.b @%2,r2\n\
++ add r2,%1\n\
++ mov.b %1,@%2\n\
++ 1: mov r1,r15\n\
++ tst %1,%1\n\
++ movt %0"\
++ : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
++ : "r0", "r1", "r2", "t", "memory"); \
++ else if (sizeof (*(mem)) == 2) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.w @%2,r2\n\
++ add r2,%1\n\
++ mov.w %1,@%2\n\
++ 1: mov r1,r15\n\
++ tst %1,%1\n\
++ movt %0"\
++ : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
++ : "r0", "r1", "r2", "t", "memory"); \
++ else if (sizeof (*(mem)) == 4) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.l @%2,r2\n\
++ add r2,%1\n\
++ mov.l %1,@%2\n\
++ 1: mov r1,r15\n\
++ tst %1,%1\n\
++ movt %0"\
++ : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
++ : "r0", "r1", "r2", "t", "memory"); \
++ else \
++ abort (); \
++ __result; })
++
++#define atomic_increment_and_test(mem) atomic_add_zero((mem), 1)
++#define atomic_decrement_and_test(mem) atomic_add_zero((mem), -1)
++
++#define atomic_bit_set(mem, bit) \
++ (void) ({ unsigned int __mask = 1 << (bit); \
++ if (sizeof (*(mem)) == 1) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.b @%0,r2\n\
++ or %1,r2\n\
++ mov.b r2,@%0\n\
++ 1: mov r1,r15"\
++ : : "r" (mem), "r" (__mask) \
++ : "r0", "r1", "r2", "memory"); \
++ else if (sizeof (*(mem)) == 2) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.w @%0,r2\n\
++ or %1,r2\n\
++ mov.w r2,@%0\n\
++ 1: mov r1,r15"\
++ : : "r" (mem), "r" (__mask) \
++ : "r0", "r1", "r2", "memory"); \
++ else if (sizeof (*(mem)) == 4) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ mov r15,r1\n\
++ mov #-6,r15\n\
++ 0: mov.l @%0,r2\n\
++ or %1,r2\n\
++ mov.l r2,@%0\n\
++ 1: mov r1,r15"\
++ : : "r" (mem), "r" (__mask) \
++ : "r0", "r1", "r2", "memory"); \
++ else \
++ abort (); \
++ })
++
++#define atomic_bit_test_set(mem, bit) \
++ ({ unsigned int __mask = 1 << (bit); \
++ unsigned int __result = __mask; \
++ if (sizeof (*(mem)) == 1) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ nop\n\
++ mov r15,r1\n\
++ mov #-8,r15\n\
++ 0: mov.b @%2,r2\n\
++ or r2,%1\n\
++ and r2,%0\n\
++ mov.b %1,@%2\n\
++ 1: mov r1,r15"\
++ : "=&r" (__result), "=&r" (__mask) \
++ : "r" (mem), "0" (__result), "1" (__mask) \
++ : "r0", "r1", "r2", "memory"); \
++ else if (sizeof (*(mem)) == 2) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ nop\n\
++ mov r15,r1\n\
++ mov #-8,r15\n\
++ 0: mov.w @%2,r2\n\
++ or r2,%1\n\
++ and r2,%0\n\
++ mov.w %1,@%2\n\
++ 1: mov r1,r15"\
++ : "=&r" (__result), "=&r" (__mask) \
++ : "r" (mem), "0" (__result), "1" (__mask) \
++ : "r0", "r1", "r2", "memory"); \
++ else if (sizeof (*(mem)) == 4) \
++ __asm __volatile ("\
++ .align 2\n\
++ mova 1f,r0\n\
++ nop\n\
++ mov r15,r1\n\
++ mov #-8,r15\n\
++ 0: mov.l @%2,r2\n\
++ or r2,%1\n\
++ and r2,%0\n\
++ mov.l %1,@%2\n\
++ 1: mov r1,r15"\
++ : "=&r" (__result), "=&r" (__mask) \
++ : "r" (mem), "0" (__result), "1" (__mask) \
++ : "r0", "r1", "r2", "memory"); \
++ else \
++ abort (); \
++ __result; })
+diff -urN uClibc-0.9.27/libcrypt/md5.c uClibc-0.9.27-uc0/libcrypt/md5.c
+--- uClibc-0.9.27/libcrypt/md5.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libcrypt/md5.c 2003-07-14 17:11:41.000000000 +0200
+@@ -111,6 +111,11 @@
+ * a multiple of 4.
+ */
+
++static void __md5_Encode (unsigned char *output, u_int32_t *input,
++ unsigned int len);
++static void __md5_Decode (u_int32_t *output, const unsigned char *input,
++ unsigned int len);
++
+ static void
+ __md5_Encode (output, input, len)
+ unsigned char *output;
+diff -urN uClibc-0.9.27/libpthread/linuxthreads/internals.h uClibc-0.9.27-uc0/libpthread/linuxthreads/internals.h
+--- uClibc-0.9.27/libpthread/linuxthreads/internals.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libpthread/linuxthreads/internals.h 2005-09-16 08:11:17.000000000 +0200
+@@ -259,7 +259,10 @@
+ extern char *__pthread_initial_thread_bos;
+ #ifndef __ARCH_HAS_MMU__
+ extern char *__pthread_initial_thread_tos;
+-#define NOMMU_INITIAL_THREAD_BOUNDS(tos,bos) if ((tos)>=__pthread_initial_thread_bos && (bos)<=__pthread_initial_thread_tos) __pthread_initial_thread_bos = (tos)+1
++#define NOMMU_INITIAL_THREAD_BOUNDS(tos,bos) \
++ if ((tos)>=__pthread_initial_thread_bos \
++ && (bos)<__pthread_initial_thread_tos) \
++ __pthread_initial_thread_bos = (tos)+1
+ #else
+ #define NOMMU_INITIAL_THREAD_BOUNDS(tos,bos) /* empty */
+ #endif /* __ARCH_HAS_MMU__ */
+diff -urN uClibc-0.9.27/libpthread/linuxthreads/pthread.c uClibc-0.9.27-uc0/libpthread/linuxthreads/pthread.c
+--- uClibc-0.9.27/libpthread/linuxthreads/pthread.c 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libpthread/linuxthreads/pthread.c 2005-01-26 07:37:27.000000000 +0100
+@@ -33,7 +33,6 @@
+ #include "restart.h"
+ #include "debug.h" /* added to linuxthreads -StS */
+
+-
+ /* Mods for uClibc: Some includes */
+ #include <signal.h>
+ #include <sys/types.h>
+@@ -224,15 +223,8 @@
+ platform does not support any real-time signals we will define the
+ values to some unreasonable value which will signal failing of all
+ the functions below. */
+-#ifndef __NR_rt_sigaction
+-static int current_rtmin = -1;
+-static int current_rtmax = -1;
+-int __pthread_sig_restart = SIGUSR1;
+-int __pthread_sig_cancel = SIGUSR2;
+-int __pthread_sig_debug;
+-#else
+
+-#if __SIGRTMAX - __SIGRTMIN >= 3
++#if defined(__NR_rt_sigaction) && __SIGRTMAX - __SIGRTMIN >= 3
+ static int current_rtmin = __SIGRTMIN + 3;
+ static int current_rtmax = __SIGRTMAX;
+ int __pthread_sig_restart = __SIGRTMIN;
+@@ -250,7 +242,6 @@
+ void (*__pthread_restart)(pthread_descr) = __pthread_restart_old;
+ void (*__pthread_suspend)(pthread_descr) = __pthread_suspend_old;
+ int (*__pthread_timedsuspend)(pthread_descr, const struct timespec *) = __pthread_timedsuspend_old;
+-
+ #endif
+
+ /* Return number of available real-time signal with highest priority. */
+@@ -275,7 +266,6 @@
+ return -1;
+ return high ? current_rtmin++ : current_rtmax--;
+ }
+-#endif
+
+ /* Initialize the pthread library.
+ Initialization is split in two functions:
+@@ -889,7 +879,7 @@
+ struct timespec reltime;
+
+ /* Compute a time offset relative to now. */
+- __gettimeofday (&now, NULL);
++ gettimeofday (&now, NULL);
+ reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000;
+ reltime.tv_sec = abstime->tv_sec - now.tv_sec;
+ if (reltime.tv_nsec < 0) {
+diff -urN uClibc-0.9.27/libpthread/linuxthreads/restart.h uClibc-0.9.27-uc0/libpthread/linuxthreads/restart.h
+--- uClibc-0.9.27/libpthread/linuxthreads/restart.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/libpthread/linuxthreads/restart.h 2003-03-04 12:22:10.000000000 +0100
+@@ -15,6 +15,10 @@
+ #include <signal.h>
+ #include <sys/syscall.h>
+
++#ifdef arm
++#undef __NR_rt_sigaction
++#endif
++
+ /* Primitives for controlling thread execution */
+
+ static inline void restart(pthread_descr th)
+diff -urN uClibc-0.9.27/libpthread/linuxthreads/sysdeps/h8300/pt-machine.h uClibc-0.9.27-uc0/libpthread/linuxthreads/sysdeps/h8300/pt-machine.h
+--- uClibc-0.9.27/libpthread/linuxthreads/sysdeps/h8300/pt-machine.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libpthread/linuxthreads/sysdeps/h8300/pt-machine.h 2004-05-13 03:48:57.000000000 +0200
+@@ -0,0 +1,58 @@
++/* Machine-dependent pthreads configuration and inline functions.
++ m68k version.
++ Copyright (C) 1996, 1998, 2000, 2002 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Contributed by Richard Henderson <rth@tamu.edu>.
++
++ 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; see the file COPYING.LIB. If
++ not, write to the Free Software Foundation, Inc.,
++ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
++
++#ifndef _PT_MACHINE_H
++#define _PT_MACHINE_H 1
++
++#ifndef PT_EI
++# define PT_EI extern inline
++#endif
++
++extern long int testandset (int *spinlock);
++
++/* Spinlock implementation; required. */
++PT_EI long int
++testandset (int *spinlock)
++{
++ char ret;
++
++ __asm__ __volatile__(
++ "sub.w %0,%0\n\t"
++ "stc ccr,@-sp\n\t"
++ "orc #0x80,ccr\n\t"
++ "bld #0,@%2\n\t"
++ "bset #0,@%2\n\t"
++ "rotxl.w %0\n\t"
++ "ldc @+sp,ccr\n\t"
++ :"=r"(ret),"=m"(*spinlock)
++ :"g"(spinlock)
++ :"cc");
++
++ return ret;
++}
++
++
++/* Get some notion of the current stack. Need not be exactly the top
++ of the stack, just something somewhere in the current frame. */
++#define CURRENT_STACK_FRAME stack_pointer
++register char * stack_pointer __asm__ ("%sp");
++
++#endif /* pt-machine.h */
+diff -urN uClibc-0.9.27/libpthread/linuxthreads/sysdeps/h8300/sigcontextinfo.h uClibc-0.9.27-uc0/libpthread/linuxthreads/sysdeps/h8300/sigcontextinfo.h
+--- uClibc-0.9.27/libpthread/linuxthreads/sysdeps/h8300/sigcontextinfo.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libpthread/linuxthreads/sysdeps/h8300/sigcontextinfo.h 2004-05-13 03:48:57.000000000 +0200
+@@ -0,0 +1,26 @@
++/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>, 1998.
++
++ 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. */
++
++#define SIGCONTEXT int _code, struct sigcontext *
++#define SIGCONTEXT_EXTRA_ARGS _code,
++#define GET_PC(ctx) ((void *) (ctx)->sc_pc)
++#define GET_FRAME(ctx) ((void *) __builtin_frame_address (1))
++#define GET_STACK(ctx) ((void *) (ctx)->sc_usp)
++#define CALL_SIGHANDLER(handler, signo, ctx) \
++ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
+diff -urN uClibc-0.9.27/libpthread/linuxthreads/sysdeps/h8300/stackinfo.h uClibc-0.9.27-uc0/libpthread/linuxthreads/sysdeps/h8300/stackinfo.h
+--- uClibc-0.9.27/libpthread/linuxthreads/sysdeps/h8300/stackinfo.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libpthread/linuxthreads/sysdeps/h8300/stackinfo.h 2004-05-13 03:48:57.000000000 +0200
+@@ -0,0 +1,28 @@
++/* Copyright (C) 1999 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 file contains a bit of information about the stack allocation
++ of the processor. */
++
++#ifndef _STACKINFO_H
++#define _STACKINFO_H 1
++
++/* On m68k the stack grows down. */
++#define _STACK_GROWS_DOWN 1
++
++#endif /* stackinfo.h */
+diff -urN uClibc-0.9.27/libpthread/linuxthreads/sysdeps/microblaze/pt-machine.h uClibc-0.9.27-uc0/libpthread/linuxthreads/sysdeps/microblaze/pt-machine.h
+--- uClibc-0.9.27/libpthread/linuxthreads/sysdeps/microblaze/pt-machine.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libpthread/linuxthreads/sysdeps/microblaze/pt-machine.h 2005-08-05 03:10:51.000000000 +0200
+@@ -0,0 +1,105 @@
++/*
++ * sysdeps/microblaze/pt-machine.h -- microblaze-specific pthread definitions
++ *
++ * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
++ * Copyright (C) 2002 NEC Electronics Corporation
++ * Copyright (C) 2002 Miles Bader <miles@gnu.org>
++ *
++ * This file is subject to the terms and conditions of the GNU Lesser
++ * General Public License. See the file COPYING.LIB in the main
++ * directory of this archive for more details.
++ *
++ * Written by Miles Bader <miles@gnu.org>
++ */
++
++#ifndef PT_EI
++# define PT_EI extern inline
++#endif
++
++extern long int testandset (int *spinlock);
++extern int __compare_and_swap (long *ptr, long old, long new);
++
++/* Get some notion of the current stack. Need not be exactly the top
++ of the stack, just something somewhere in the current frame. */
++#define CURRENT_STACK_FRAME __stack_pointer
++register char *__stack_pointer __asm__ ("r1");
++
++#define HAS_COMPARE_AND_SWAP
++#define HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS
++#define IMPLEMENT_TAS_WITH_CAS
++
++/* Atomically: If *PTR == OLD, set *PTR to NEW and return true,
++ otherwise do nothing and return false. */
++PT_EI int __compare_and_swap (long *ptr, long old, long new)
++{
++ unsigned long psw;
++
++ /* disable interrupts */
++ /* This is ugly ugly ugly! */
++ __asm__ __volatile__ ("mfs %0, rmsr;"
++ "andi r3, %0, ~2;"
++ "mts rmsr, r3;"
++ : "=&r" (psw)
++ :
++ : "r3");
++
++ if (likely (*ptr == old))
++ {
++ *ptr = new;
++ __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw)); /* re-enable */
++ return 1;
++ }
++ else
++ {
++ __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw)); /* re-enable */
++ return 0;
++ }
++}
++
++/* like above's __compare_and_swap() but it first syncs the memory
++ (This is also the difference between both functions in e.g.
++ ../powerpc/pt-machine.h)
++ Doing this additional sync fixes a hang of __pthread_alt_unlock()
++ (Falk Brettschneider <fbrettschneider@baumeroptronic.de>) */
++PT_EI int
++__compare_and_swap_with_release_semantics (long *p,
++ long oldval, long newval)
++{
++ __asm__ __volatile__ ("" : : : "memory"); /*MEMORY_BARRIER ();*/
++ return __compare_and_swap (p, oldval, newval);
++}
++
++
++#ifndef IMPLEMENT_TAS_WITH_CAS
++/* Spinlock implementation; required. */
++PT_EI long int testandset (int *spinlock)
++{
++ char ret;
++ unsigned psw;
++
++ /* disable interrupts */
++ __asm__ __volatile__ ("mfs %0, rmsr;"
++ "andi r3, %0, ~2;"
++ "mts rmsr, r3;"
++ : "=&r" (psw)
++ :
++ : "r3");
++
++ if(*spinlock)
++ {
++ /* Enable ints */
++ __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw));
++ ret=1;
++ }
++ else
++ {
++ *spinlock=1;
++ /* Enable ints */
++ __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw));
++ ret=0;
++ }
++
++ return ret;
++}
++
++#endif
+diff -urN uClibc-0.9.27/libpthread/linuxthreads/sysdeps/microblaze/sigcontextinfo.h uClibc-0.9.27-uc0/libpthread/linuxthreads/sysdeps/microblaze/sigcontextinfo.h
+--- uClibc-0.9.27/libpthread/linuxthreads/sysdeps/microblaze/sigcontextinfo.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.27-uc0/libpthread/linuxthreads/sysdeps/microblaze/sigcontextinfo.h 2003-12-01 06:55:43.000000000 +0100
+@@ -0,0 +1,17 @@
++/*
++ * sysdeps/v850/sigcontextinfo.h -- v850-specific pthread signal definitions
++ *
++ * Copyright (C) 2002 NEC Electronics Corporation
++ * Copyright (C) 2002 Miles Bader <miles@gnu.org>
++ *
++ * This file is subject to the terms and conditions of the GNU Lesser
++ * General Public License. See the file COPYING.LIB in the main
++ * directory of this archive for more details.
++ *
++ * Written by Miles Bader <miles@gnu.org>
++ */
++
++#include <signal.h>
++
++#define SIGCONTEXT struct sigcontext *
++#define SIGCONTEXT_EXTRA_ARGS
+diff -urN uClibc-0.9.27/librt/kernel-posix-timers.h uClibc-0.9.27-uc0/librt/kernel-posix-timers.h
+--- uClibc-0.9.27/librt/kernel-posix-timers.h 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/librt/kernel-posix-timers.h 2005-07-08 00:55:16.000000000 +0200
+@@ -5,6 +5,7 @@
+ #include <setjmp.h>
+ #include <signal.h>
+ #include <sys/types.h>
++#include <pthread.h>
+
+ /* Type of timers in the kernel */
+ typedef int kernel_timer_t;
+diff -urN uClibc-0.9.27/Makefile uClibc-0.9.27-uc0/Makefile
+--- uClibc-0.9.27/Makefile 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/Makefile 2005-08-12 04:14:26.000000000 +0200
+@@ -40,7 +40,7 @@
+ # In this section, we need .config
+ -include .config.cmd
+
+-shared:
++shared: $(SHARED_TARGET)
+ ifeq ($(strip $(HAVE_SHARED)),y)
+ @$(MAKE) -C libc shared
+ @$(MAKE) -C ldso shared
+@@ -66,6 +66,8 @@
+ @echo Finally finished compiling...
+ @echo
+
++UCLIBC_VERSION := $(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL)
++
+ include/bits/uClibc_config.h: .config
+ @if [ ! -x ./extra/config/conf ] ; then \
+ $(MAKE) -C extra/config conf; \
+@@ -359,4 +361,49 @@
+
+ .PHONY: dummy subdirs release distclean clean config oldconfig menuconfig
+
++ifneq ($(SHARED_TARGET),)
++lib/main.o: $(ROOTDIR)/lib/libc/main.c
++ $(CC) $(CFLAGS) $(ARCH_CFLAGS) -c -o $@ $(ROOTDIR)/lib/libc/main.c
++
++bogus $(SHARED_TARGET): lib/libc.a lib/main.o Makefile
++ make -C $(ROOTDIR) relink
++ $(CC) -nostartfiles -o $(SHARED_TARGET) $(ARCH_CFLAGS) \
++ -mid-shared-library -mshared-library-id=0 \
++ -Wl,-elf2flt -nostdlib -Wl,-shared-lib-id,${LIBID} \
++ lib/main.o \
++ -Wl,--whole-archive,lib/libc.a,-lgcc,--no-whole-archive
++ $(OBJCOPY) -L _GLOBAL_OFFSET_TABLE_ -L main -L __main -L _start \
++ -L __uClibc_main -L __uClibc_start_main -L lib_main \
++ -L _exit_dummy_ref \
++ -L __do_global_dtors -L __do_global_ctors \
++ -L __CTOR_LIST__ -L __DTOR_LIST__ \
++ -L _current_shared_library_a5_offset_ \
++ $(SHARED_TARGET).gdb
++ $(LN) -sf $(SHARED_TARGET).gdb .
++endif
++
++#
++# Target for uClinux distro
++#
++.PHONY: romfs
++romfs:
++ [ -e $(ROMFSDIR)/lib ] || mkdir $(ROMFSDIR)/lib
++ if [ "$(SHARED_TARGET)" ]; then \
++ $(ROMFSINST) $(SHARED_TARGET) /lib/lib$(LIBID).so; \
++ fi
++ifeq ($(strip $(HAVE_SHARED)),y)
++ set -e; for i in lib/lib*-$(UCLIBC_VERSION).so lib/*.so.*; do \
++ if [ -L $$i ]; then \
++ $(ROMFSINST) -s `readlink $$i` /$$i; \
++ else \
++ $(ROMFSINST) -p 755 $$i /lib; \
++ fi; \
++ done
++ set -e; if [ -x lib/ld-uClibc-$(UCLIBC_VERSION).so ] ; then \
++ $(ROMFSINST) -p 755 lib/ld-uClibc-$(UCLIBC_VERSION).so /lib; \
++ $(ROMFSINST) -s \
++ /lib/ld-uClibc-$(UCLIBC_VERSION).so \
++ /lib/ld-linux.so.2; \
++ fi
++endif
+
+diff -urN uClibc-0.9.27/Rules.mak uClibc-0.9.27-uc0/Rules.mak
+--- uClibc-0.9.27/Rules.mak 2005-01-12 08:59:21.000000000 +0100
++++ uClibc-0.9.27-uc0/Rules.mak 2005-07-08 03:28:17.000000000 +0200
+@@ -218,7 +218,10 @@
+ # If -msoft-float isn't supported, we want an error anyway.
+ # Hmm... might need to revisit this for arm since it has 2 different
+ # soft float encodings.
++# msoft-float changes m68k target arch, do not add it
++ifneq ($(strip $(TARGET_ARCH)),m68k)
+ CPU_CFLAGS += -msoft-float
++endif
+ ifeq ($(strip $(TARGET_ARCH)),arm)
+ # No longer needed with current toolchains, but leave it here for now.
+ # If anyone is actually still using gcc 2.95 (say), they can uncomment it.
+@@ -251,7 +254,7 @@
+ LDFLAGS:= $(CPU_LDFLAGS-y) -shared --warn-common --warn-once -z combreloc
+ STRIPTOOL:= true -Since_we_are_debugging
+ else
+- LDFLAGS := $(CPU_LDFLAGS-y) -s -shared --warn-common --warn-once -z combreloc
++ LDFLAGS := $(CPU_LDFLAGS-y) -shared --warn-common --warn-once -z combreloc
+ endif
+
+ ifeq ($(UCLIBC_BUILD_RELRO),y)
+@@ -264,7 +267,7 @@
+
+ # Sigh, some stupid versions of gcc can't seem to cope with '-iwithprefix include'
+ #CFLAGS+=-iwithprefix include
+-CFLAGS+=-isystem $(shell $(CC) -print-file-name=include)
++CFLAGS+=-isystem $(shell $(CC) -print-file-name=include || echo)
+
+ ifneq ($(DOASSERTS),y)
+ CFLAGS += -DNDEBUG
+@@ -292,7 +295,7 @@
+ endif
+
+ LIBGCC_CFLAGS ?= $(CFLAGS) $(CPU_CFLAGS-y)
+-LIBGCC:=$(shell $(CC) $(LIBGCC_CFLAGS) -print-libgcc-file-name)
++LIBGCC:=$(shell $(CC) $(LIBGCC_CFLAGS) -print-libgcc-file-name || echo)
+ LIBGCC_DIR:=$(dir $(LIBGCC))
+
+ ########################################
+@@ -301,11 +304,13 @@
+ #
+
+ ifeq ($(CONFIG_BINFMT_SHARED_FLAT),y)
+- # For the shared version of this, we specify no stack and its library ID
+- FLTFLAGS += -s 0
+- LIBID=1
+- export LIBID FLTFLAGS
+- SHARED_TARGET = lib/libc
++ ifndef DISABLE_SHARED_LIBS
++ # For the shared version of this, we specify no stack and its library ID
++ FLTFLAGS += -s 0
++ LIBID=1
++ export LIBID FLTFLAGS
++ SHARED_TARGET = lib/libc
++ endif
+ endif
+
+ TARGET_ARCH:=$(strip $(subst ",, $(strip $(TARGET_ARCH))))