diff options
Diffstat (limited to 'toolchain')
39 files changed, 5191 insertions, 1 deletions
diff --git a/toolchain/uClibc/Config.in b/toolchain/uClibc/Config.in index 36bb8804e..67a835494 100644 --- a/toolchain/uClibc/Config.in +++ b/toolchain/uClibc/Config.in @@ -10,6 +10,9 @@ choice  	config UCLIBC_VERSION_0_9_32  		bool "uClibc 0.9.32-git" +	config UCLIBC_VERSION_0_9_33 +		bool "uClibc 0.9.33" +  endchoice diff --git a/toolchain/uClibc/Config.version b/toolchain/uClibc/Config.version index d122ccce3..9fa131a4f 100644 --- a/toolchain/uClibc/Config.version +++ b/toolchain/uClibc/Config.version @@ -2,6 +2,7 @@ config UCLIBC_VERSION  	string  	depends on USE_UCLIBC  	default "0.9.32"       if UCLIBC_VERSION_0_9_32 +	default "0.9.33"       if UCLIBC_VERSION_0_9_33  	default "0.9.32"  if !TOOLCHAINOPTS diff --git a/toolchain/uClibc/Makefile b/toolchain/uClibc/Makefile index 8c658448b..51c761a23 100644 --- a/toolchain/uClibc/Makefile +++ b/toolchain/uClibc/Makefile @@ -1,5 +1,5 @@  # -# Copyright (C) 2006-2011 OpenWrt.org +# Copyright (C) 2006-2012 OpenWrt.org  #  # This is free software, licensed under the GNU General Public License v2.  # See /LICENSE for more information. @@ -25,6 +25,7 @@ endif  PATCH_DIR:=./patches-$(PKG_VERSION)  CONFIG_DIR:=./config-$(PKG_VERSION) +PKG_MD5SUM_0.9.33 = cf9d25e4b3c87af1a99d33a6b959fbf1  PKG_MD5SUM=$(PKG_MD5SUM_$(PKG_VERSION))  HOST_BUILD_DIR:=$(BUILD_DIR_TOOLCHAIN)/$(PKG_NAME)-$(PKG_VERSION) diff --git a/toolchain/uClibc/config-0.9.33/arm b/toolchain/uClibc/config-0.9.33/arm new file mode 100644 index 000000000..b68617bb4 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/arm @@ -0,0 +1,7 @@ +ARCH_ANY_ENDIAN=y +ARCH_LITTLE_ENDIAN=y +ARCH_WANTS_LITTLE_ENDIAN=y +# COMPILE_IN_THUMB_MODE is not set +TARGET_ARCH="arm" +TARGET_arm=y +# USE_BX is not set diff --git a/toolchain/uClibc/config-0.9.33/armeb b/toolchain/uClibc/config-0.9.33/armeb new file mode 100644 index 000000000..d4932e864 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/armeb @@ -0,0 +1,7 @@ +ARCH_ANY_ENDIAN=y +ARCH_BIG_ENDIAN=y +ARCH_WANTS_BIG_ENDIAN=y +# COMPILE_IN_THUMB_MODE is not set +TARGET_ARCH="arm" +TARGET_arm=y +# USE_BX is not set diff --git a/toolchain/uClibc/config-0.9.33/avr32 b/toolchain/uClibc/config-0.9.33/avr32 new file mode 100644 index 000000000..729fbc9a3 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/avr32 @@ -0,0 +1,12 @@ +ARCH_BIG_ENDIAN=y +CONFIG_AVR32_AP7=y +FORCE_SHAREABLE_TEXT_SEGMENTS=y +LINKRELAX=y +LINUXTHREADS_OLD=y +TARGET_ARCH="avr32" +TARGET_avr32=y +UCLIBC_HAS_FPU=y +# UCLIBC_HAS_SCANF_GLIBC_A_FLAG is not set +# UCLIBC_HAS_STRING_ARCH_OPT is not set +# UCLIBC_HAS_THREADS_NATIVE is not set +UNIX98PTY_ONLY=y diff --git a/toolchain/uClibc/config-0.9.33/common b/toolchain/uClibc/config-0.9.33/common new file mode 100644 index 000000000..4b21713eb --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/common @@ -0,0 +1,211 @@ +# ARCH_ANY_ENDIAN is not set +ARCH_HAS_MMU=y +# ARCH_HAS_NO_LDSO is not set +# ARCH_HAS_NO_SHARED is not set +# ARCH_LITTLE_ENDIAN is not set +ARCH_USE_MMU=y +# ARCH_WANTS_BIG_ENDIAN is not set +# ARCH_WANTS_LITTLE_ENDIAN is not set +ASSUME_DEVPTS=y +# COMPAT_ATEXIT is not set +CROSS_COMPILER_PREFIX="" +DEVEL_PREFIX="/usr/" +# DOASSERTS is not set +# DODEBUG is not set +# DODEBUG_PT is not set +# DOMULTI is not set +DOPIC=y +DOSTRIP=y +DO_C99_MATH=y +# DO_XSI_MATH is not set +# EXTRA_WARNINGS is not set +FORCE_OPTIONS_FOR_ARCH=y +# FORCE_SHAREABLE_TEXT_SEGMENTS is not set +# HARDWIRED_ABSPATH is not set +# HAS_NO_THREADS is not set +HAVE_DOT_CONFIG=y +# HAVE_NO_PIC is not set +# HAVE_NO_SSP is not set +HAVE_SHARED=y +KERNEL_HEADERS="." +LDSO_BASE_FILENAME="ld.so" +LDSO_CACHE_SUPPORT=y +# LDSO_GNU_HASH_SUPPORT is not set +LDSO_LD_LIBRARY_PATH=y +LDSO_LDD_SUPPORT=y +# LDSO_NO_CLEANUP is not set +# LDSO_PRELINK_SUPPORT is not set +# LDSO_PRELOAD_FILE_SUPPORT is not set +# LDSO_PRELOAD_ENV_SUPPORT is not set +LDSO_RUNPATH=y +# LDSO_SEARCH_INTERP_PATH is not set +# LDSO_STANDALONE_SUPPORT is not set +# LINUXTHREADS_NEW is not set +# LINUXTHREADS_OLD is not set +# UCLIBC_HAS_BACKTRACE is not set +UCLIBC_HAS_THREADS_NATIVE=y +# MALLOC is not set +MALLOC_GLIBC_COMPAT=y +# MALLOC_SIMPLE is not set +MALLOC_STANDARD=y +MULTILIB_DIR="lib" +# PTHREADS_DEBUG_SUPPORT is not set +RUNTIME_PREFIX="/" +# SUPPORT_LD_DEBUG is not set +# SUPPORT_LD_DEBUG_EARLY is not set +TARGET_SUBARCH="" +# TARGET_alpha is not set +# TARGET_arm is not set +# TARGET_avr32 is not set +# TARGET_bfin is not set +# TARGET_c6x is not set +# TARGET_cris is not set +# TARGET_e1 is not set +# TARGET_frv is not set +# TARGET_h8300 is not set +# TARGET_hppa is not set +# TARGET_i386 is not set +# TARGET_i960 is not set +# TARGET_ia64 is not set +# TARGET_m68k is not set +# TARGET_microblaze is not set +# TARGET_mips is not set +# TARGET_nios is not set +# TARGET_nios2 is not set +# TARGET_powerpc is not set +# TARGET_sh is not set +# TARGET_sh64 is not set +# TARGET_sparc is not set +# TARGET_ubicom32 is not set +# TARGET_v850 is not set +# TARGET_vax is not set +# TARGET_x86_64 is not set +# TARGET_xtensa is not set +UCLIBC_BSD_SPECIFIC=y +UCLIBC_BUILD_NOEXECSTACK=y +# UCLIBC_BUILD_NOW is not set +# UCLIBC_BUILD_PIE is not set +UCLIBC_BUILD_RELRO=y +UCLIBC_CTOR_DTOR=y +UCLIBC_DYNAMIC_ATEXIT=y +UCLIBC_EXTRA_CFLAGS="" +UCLIBC_GRP_BUFFER_SIZE=256 +UCLIBC_HAS_ADVANCED_REALTIME=y +# UCLIBC_HAS_ARC4RANDOM is not set +UCLIBC_HAS_BSD_ERR=y +UCLIBC_HAS_BSD_RES_CLOSE=y +# UCLIBC_HAS_COMPAT_RES_STATE is not set +UCLIBC_HAS_CRYPT=y +UCLIBC_HAS_CRYPT_IMPL=y +UCLIBC_HAS_CTYPE_CHECKED=y +# UCLIBC_HAS_CTYPE_ENFORCED is not set +UCLIBC_HAS_CTYPE_SIGNED=y +UCLIBC_HAS_CTYPE_TABLES=y +# UCLIBC_HAS_CTYPE_UNSAFE is not set +UCLIBC_HAS_EPOLL=y +UCLIBC_HAS_ERRNO_MESSAGES=y +# UCLIBC_HAS_EXTRA_COMPAT_RES_STATE is not set +# UCLIBC_HAS_FENV is not set +UCLIBC_HAS_FLOATS=y +UCLIBC_HAS_FNMATCH=y +UCLIBC_HAS_FNMATCH_OLD=y +# UCLIBC_HAS_FOPEN_CLOSEEXEC_MODE is not set +UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE=y +# UCLIBC_HAS_FOPEN_LARGEFILE_MODE is not set +# UCLIBC_HAS_FPU is not set +UCLIBC_HAS_FTS=y +UCLIBC_HAS_FTW=y +# UCLIBC_HAS_FULL_RPC is not set +UCLIBC_HAS_GETPT=y +UCLIBC_HAS_GLIBC_CUSTOM_PRINTF=y +UCLIBC_HAS_GLIBC_CUSTOM_STREAMS=y +# UCLIB_HAS_GLIBC_DIGIT_GROUPING is not set +UCLIBC_HAS_GLOB=y +UCLIBC_HAS_GNU_ERROR=y +UCLIBC_HAS_GNU_GETOPT=y +UCLIBC_HAS_GNU_GETSUBOPT=y +UCLIBC_HAS_GNU_GLOB=y +UCLIBC_HAS_HEXADECIMAL_FLOATS=y +UCLIBC_HAS_IPV4=y +UCLIBC_HAS_IPV6=y +UCLIBC_HAS_LFS=y +UCLIBC_HAS_LIBNSL_STUB=y +UCLIBC_HAS_LIBRESOLV_STUB=y +UCLIBC_HAS_LIBUTIL=y +# UCLIBC_HAS_LOCALE is not set +UCLIBC_HAS_LONG_DOUBLE_MATH=y +UCLIBC_HAS_NETWORK_SUPPORT=y +UCLIBC_HAS_NFTW=y +# UCLIBC_HAS_OBSOLETE_BSD_SIGNAL is not set +# UCLIBC_HAS_OBSOLETE_SYSV_SIGNAL is not set +UCLIBC_HAS_PRINTF_M_SPEC=y +# UCLIBC_HAS_PROFILING is not set +UCLIBC_HAS_PROGRAM_INVOCATION_NAME=y +UCLIBC_HAS_PTY=y +UCLIBC_HAS_REALTIME=y +# UCLIBC_HAS_REENTRANT_RPC is not set +UCLIBC_HAS_REGEX=y +UCLIBC_HAS_REGEX_OLD=y +UCLIBC_HAS_RESOLVER_SUPPORT=y +# UCLIBC_HAS_RPC is not set +UCLIBC_HAS_SCANF_GLIBC_A_FLAG=y +UCLIBC_HAS_SHA256_CRYPT_IMPL=y +UCLIBC_HAS_SHA512_CRYPT_IMPL=y +UCLIBC_HAS_SHADOW=y +UCLIBC_HAS_SIGNUM_MESSAGES=y +UCLIBC_HAS_SOCKET=y +UCLIBC_HAS_SOFT_FLOAT=y +# UCLIBC_HAS_SSP is not set +UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION=y +# UCLIBC_HAS_STDIO_BUFSIZ_1024 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_2048 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_256 is not set +UCLIBC_HAS_STDIO_BUFSIZ_4096=y +# UCLIBC_HAS_STDIO_BUFSIZ_512 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_8192 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_NONE is not set +# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_4 is not set +# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_8 is not set +UCLIBC_HAS_STDIO_BUILTIN_BUFFER_NONE=y +UCLIBC_HAS_STDIO_GETC_MACRO=y +UCLIBC_HAS_STDIO_PUTC_MACRO=y +# UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT is not set +UCLIBC_HAS_STRING_ARCH_OPT=y +UCLIBC_HAS_STRING_GENERIC_OPT=y +# UCLIBC_HAS_STUBS is not set +UCLIBC_HAS_SYSLOG=y +# UCLIBC_HAS_SYS_ERRLIST is not set +# UCLIBC_HAS_SYS_SIGLIST is not set +UCLIBC_HAS_THREADS=y +UCLIBC_HAS_TM_EXTENSIONS=y +UCLIBC_HAS_TZ_CACHING=y +UCLIBC_HAS_TZ_FILE=y +UCLIBC_HAS_TZ_FILE_READ_MANY=y +# UCLIBC_HAS_UTMPX is not set +UCLIBC_HAS_WCHAR=y +UCLIBC_HAS_WORDEXP=y +# UCLIBC_HAS_XATTR is not set +# UCLIBC_HAS_XLOCALE is not set +UCLIBC_HAS___PROGNAME=y +# UCLIBC_LINUX_MODULE_24 is not set +UCLIBC_LINUX_MODULE_26=y +UCLIBC_LINUX_SPECIFIC=y +# UCLIBC_MALLOC_DEBUGGING is not set +# UCLIBC_MJN3_ONLY is not set +# UCLIBC_NTP_LEGACY is not set +# USE_OLD_VFPRINTF is not set +UCLIBC_PRINTF_SCANF_POSITIONAL_ARGS=9 +UCLIBC_PWD_BUFFER_SIZE=256 +# UCLIBC_STATIC_LDCONFIG is not set +# UCLIBC_STRICT_HEADERS is not set +UCLIBC_SUPPORT_AI_ADDRCONFIG=y +UCLIBC_SUSV3_LEGACY=y +UCLIBC_SUSV3_LEGACY_MACROS=y +UCLIBC_SUSV4_LEGACY=y +# UCLIBC_SV4_DEPRECATED is not set +UCLIBC_TZ_FILE_PATH="/etc/TZ" +# UCLIBC_FALLBACK_TO_ETC_LOCALTIME is not set +UCLIBC_USE_NETLINK=y +# UNIX98PTY_ONLY is not set +USE_BX=y +WARNINGS="-Wall" diff --git a/toolchain/uClibc/config-0.9.33/cris b/toolchain/uClibc/config-0.9.33/cris new file mode 100644 index 000000000..4164484aa --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/cris @@ -0,0 +1,8 @@ +ARCH_LITTLE_ENDIAN=y +CONFIG_CRIS=y +# CONFIG_CRISV32 is not set +LINUXTHREADS_OLD=y +TARGET_ARCH="cris" +TARGET_cris=y +UCLIBC_HAS_FPU=y +# UCLIBC_HAS_THREADS_NATIVE is not set diff --git a/toolchain/uClibc/config-0.9.33/debug b/toolchain/uClibc/config-0.9.33/debug new file mode 100644 index 000000000..b366e66e3 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/debug @@ -0,0 +1,6 @@ +DODEBUG=y +DODEBUG_PT=y +PTHREADS_DEBUG_SUPPORT=y +SUPPORT_LD_DEBUG=y +SUPPORT_LD_DEBUG_EARLY=y +UCLIBC_MALLOC_DEBUGGING=y diff --git a/toolchain/uClibc/config-0.9.33/i386 b/toolchain/uClibc/config-0.9.33/i386 new file mode 100644 index 000000000..5ef264c27 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/i386 @@ -0,0 +1,21 @@ +ARCH_LITTLE_ENDIAN=y +# CONFIG_386 is not set +CONFIG_486=y +# CONFIG_586 is not set +# CONFIG_586MMX is not set +# CONFIG_686 is not set +# CONFIG_CRUSOE is not set +# CONFIG_CYRIXIII is not set +# CONFIG_ELAN is not set +# CONFIG_GENERIC_386 is not set +# CONFIG_K6 is not set +# CONFIG_K7 is not set +# CONFIG_NEHEMIAH is not set +# CONFIG_PENTIUM4 is not set +# CONFIG_PENTIUMII is not set +# CONFIG_PENTIUMIII is not set +# CONFIG_WINCHIP2 is not set +# CONFIG_WINCHIPC6 is not set +TARGET_ARCH="i386" +TARGET_i386=y +UCLIBC_HAS_FPU=y diff --git a/toolchain/uClibc/config-0.9.33/i686 b/toolchain/uClibc/config-0.9.33/i686 new file mode 100644 index 000000000..ba615f6b8 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/i686 @@ -0,0 +1,21 @@ +ARCH_LITTLE_ENDIAN=y +# CONFIG_386 is not set +# CONFIG_486 is not set +# CONFIG_586 is not set +# CONFIG_586MMX is not set +CONFIG_686=y +# CONFIG_CRUSOE is not set +# CONFIG_CYRIXIII is not set +# CONFIG_ELAN is not set +# CONFIG_GENERIC_386 is not set +# CONFIG_K6 is not set +# CONFIG_K7 is not set +# CONFIG_NEHEMIAH is not set +# CONFIG_PENTIUM4 is not set +# CONFIG_PENTIUMII is not set +# CONFIG_PENTIUMIII is not set +# CONFIG_WINCHIP2 is not set +# CONFIG_WINCHIPC6 is not set +TARGET_ARCH="i386" +TARGET_i386=y +UCLIBC_HAS_FPU=y diff --git a/toolchain/uClibc/config-0.9.33/m68k b/toolchain/uClibc/config-0.9.33/m68k new file mode 100644 index 000000000..14ce5aef7 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/m68k @@ -0,0 +1,6 @@ +ARCH_BIG_ENDIAN=y +LINUXTHREADS_OLD=y +TARGET_ARCH="m68k" +TARGET_SUBARCH="" +TARGET_m68k=y +# UCLIBC_HAS_THREADS_NATIVE is not set diff --git a/toolchain/uClibc/config-0.9.33/mips b/toolchain/uClibc/config-0.9.33/mips new file mode 100644 index 000000000..7398c6692 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/mips @@ -0,0 +1,17 @@ +ARCH_ANY_ENDIAN=y +ARCH_BIG_ENDIAN=y +ARCH_CFLAGS="-mno-split-addresses" +ARCH_WANTS_BIG_ENDIAN=y +# CONFIG_MIPS_ISA_1 is not set +# CONFIG_MIPS_ISA_2 is not set +# CONFIG_MIPS_ISA_3 is not set +# CONFIG_MIPS_ISA_4 is not set +CONFIG_MIPS_ISA_MIPS32=y +# CONFIG_MIPS_ISA_MIPS32R2 is not set +# CONFIG_MIPS_ISA_MIPS64 is not set +# CONFIG_MIPS_N32_ABI is not set +# CONFIG_MIPS_N64_ABI is not set +CONFIG_MIPS_O32_ABI=y +TARGET_ARCH="mips" +TARGET_mips=y +UCLIBC_HAS_FPU=y diff --git a/toolchain/uClibc/config-0.9.33/mips64 b/toolchain/uClibc/config-0.9.33/mips64 new file mode 100644 index 000000000..fa5bee3aa --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/mips64 @@ -0,0 +1,17 @@ +ARCH_ANY_ENDIAN=y +ARCH_BIG_ENDIAN=y +ARCH_CFLAGS="-mno-split-addresses" +ARCH_WANTS_BIG_ENDIAN=y +# CONFIG_MIPS_ISA_1 is not set +# CONFIG_MIPS_ISA_2 is not set +# CONFIG_MIPS_ISA_3 is not set +# CONFIG_MIPS_ISA_4 is not set +# CONFIG_MIPS_ISA_MIPS32 is not set +# CONFIG_MIPS_ISA_MIPS32R2 is not set +CONFIG_MIPS_ISA_MIPS64=y +# CONFIG_MIPS_N32_ABI is not set +CONFIG_MIPS_N64_ABI=y +# CONFIG_MIPS_O32_ABI is not set +TARGET_ARCH="mips" +TARGET_mips=y +UCLIBC_HAS_FPU=y diff --git a/toolchain/uClibc/config-0.9.33/mips64el b/toolchain/uClibc/config-0.9.33/mips64el new file mode 100644 index 000000000..1ca764f6e --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/mips64el @@ -0,0 +1,17 @@ +ARCH_ANY_ENDIAN=y +ARCH_CFLAGS="-mno-split-addresses" +ARCH_LITTLE_ENDIAN=y +ARCH_WANTS_LITTLE_ENDIAN=y +# CONFIG_MIPS_ISA_1 is not set +# CONFIG_MIPS_ISA_2 is not set +# CONFIG_MIPS_ISA_3 is not set +# CONFIG_MIPS_ISA_4 is not set +# CONFIG_MIPS_ISA_MIPS32 is not set +# CONFIG_MIPS_ISA_MIPS32R2 is not set +CONFIG_MIPS_ISA_MIPS64=y +# CONFIG_MIPS_N32_ABI is not set +CONFIG_MIPS_N64_ABI=y +# CONFIG_MIPS_O32_ABI is not set +TARGET_ARCH="mips" +TARGET_mips=y +UCLIBC_HAS_FPU=y diff --git a/toolchain/uClibc/config-0.9.33/mipsel b/toolchain/uClibc/config-0.9.33/mipsel new file mode 100644 index 000000000..7648f396b --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/mipsel @@ -0,0 +1,17 @@ +ARCH_ANY_ENDIAN=y +ARCH_CFLAGS="-mno-split-addresses" +ARCH_LITTLE_ENDIAN=y +ARCH_WANTS_LITTLE_ENDIAN=y +# CONFIG_MIPS_ISA_1 is not set +# CONFIG_MIPS_ISA_2 is not set +# CONFIG_MIPS_ISA_3 is not set +# CONFIG_MIPS_ISA_4 is not set +CONFIG_MIPS_ISA_MIPS32=y +# CONFIG_MIPS_ISA_MIPS32R2 is not set +# CONFIG_MIPS_ISA_MIPS64 is not set +# CONFIG_MIPS_N32_ABI is not set +# CONFIG_MIPS_N64_ABI is not set +CONFIG_MIPS_O32_ABI=y +TARGET_ARCH="mips" +TARGET_mips=y +UCLIBC_HAS_FPU=y diff --git a/toolchain/uClibc/config-0.9.33/mipsel.cobalt b/toolchain/uClibc/config-0.9.33/mipsel.cobalt new file mode 100644 index 000000000..323b0aa52 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/mipsel.cobalt @@ -0,0 +1,17 @@ +ARCH_ANY_ENDIAN=y +ARCH_CFLAGS="-mno-split-addresses" +ARCH_LITTLE_ENDIAN=y +ARCH_WANTS_LITTLE_ENDIAN=y +# CONFIG_MIPS_ISA_1 is not set +# CONFIG_MIPS_ISA_2 is not set +CONFIG_MIPS_ISA_3=y +# CONFIG_MIPS_ISA_4 is not set +# CONFIG_MIPS_ISA_MIPS32 is not set +# CONFIG_MIPS_ISA_MIPS32R2 is not set +# CONFIG_MIPS_ISA_MIPS64 is not set +# CONFIG_MIPS_N32_ABI is not set +# CONFIG_MIPS_N64_ABI is not set +CONFIG_MIPS_O32_ABI=y +TARGET_ARCH="mips" +TARGET_mips=y +UCLIBC_HAS_FPU=y diff --git a/toolchain/uClibc/config-0.9.33/powerpc b/toolchain/uClibc/config-0.9.33/powerpc new file mode 100644 index 000000000..5b1292d12 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/powerpc @@ -0,0 +1,6 @@ +ARCH_BIG_ENDIAN=y +CONFIG_CLASSIC=y +# CONFIG_E500 is not set +TARGET_ARCH="powerpc" +TARGET_SUBARCH="classic" +TARGET_powerpc=y diff --git a/toolchain/uClibc/config-0.9.33/powerpc.e500 b/toolchain/uClibc/config-0.9.33/powerpc.e500 new file mode 100644 index 000000000..a835c3d5e --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/powerpc.e500 @@ -0,0 +1,6 @@ +ARCH_BIG_ENDIAN=y +# CONFIG_CLASSIC is not set +CONFIG_E500=y +TARGET_ARCH="powerpc" +TARGET_SUBARCH="classic" +TARGET_powerpc=y diff --git a/toolchain/uClibc/config-0.9.33/sparc b/toolchain/uClibc/config-0.9.33/sparc new file mode 100644 index 000000000..e1596c410 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/sparc @@ -0,0 +1,8 @@ +ARCH_BIG_ENDIAN=y +# CONFIG_SPARC_V7 is not set +# CONFIG_SPARC_V8 is not set +CONFIG_SPARC_V9=y +# CONFIG_SPARC_V9B is not set +TARGET_ARCH="sparc" +TARGET_sparc=y +UCLIBC_HAS_LONG_DOUBLE_MATH=y diff --git a/toolchain/uClibc/config-0.9.33/sparc.leon b/toolchain/uClibc/config-0.9.33/sparc.leon new file mode 100644 index 000000000..eb725ac05 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/sparc.leon @@ -0,0 +1,8 @@ +ARCH_BIG_ENDIAN=y +# CONFIG_SPARC_V7 is not set +CONFIG_SPARC_V8=y +# CONFIG_SPARC_V9 is not set +# CONFIG_SPARC_V9B is not set +TARGET_ARCH="sparc" +TARGET_sparc=y +UCLIBC_HAS_LONG_DOUBLE_MATH=y diff --git a/toolchain/uClibc/config-0.9.33/ubicom32 b/toolchain/uClibc/config-0.9.33/ubicom32 new file mode 100644 index 000000000..6277fc380 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/ubicom32 @@ -0,0 +1,36 @@ +ARCH_BIG_ENDIAN=y +ARCH_HAS_NO_MMU=y +COMPAT_ATEXIT=y +# CONFIG_UC_UBICOM32_V3 is not set +CONFIG_UC_UBICOM32_V4=y +# DOSTRIP is not set +EXCLUDE_BRK=y +FORCE_SHAREABLE_TEXT_SEGMENTS=y +LDSO_PRELOAD_FILE_SUPPORT=y +LINUXTHREADS_OLD=y +MALLOC=y +# MALLOC_STANDARD is not set +PTHREADS_DEBUG_SUPPORT=y +SUPPORT_LD_DEBUG=y +TARGET_ARCH="ubicom32" +TARGET_ubicom32=y +# UCLIBC_FORMAT_ELF is not set +UCLIBC_FORMAT_FDPIC_ELF=y +# UCLIBC_FORMAT_FLAT is not set +# UCLIBC_FORMAT_FLAT_SEP_DATA is not set +# UCLIBC_FORMAT_SHARED_FLAT is not set +UCLIBC_HAS_FOPEN_LARGEFILE_MODE=y +UCLIBC_HAS_FPU=y +# UCLIBC_HAS_GETPT is not set +UCLIBC_HAS_OBSOLETE_BSD_SIGNAL=y +UCLIBC_HAS_OBSOLETE_SYSV_SIGNAL=y +UCLIBC_HAS_PROFILING=y +UCLIBC_HAS_REENTRANT_RPC=y +UCLIBC_HAS_STUBS=y +# UCLIBC_HAS_THREADS_NATIVE is not set +UCLIBC_HAS_XATTR=y +UCLIBC_NTP_LEGACY=y +UCLIBC_STATIC_LDCONFIG=y +UCLIBC_SV4_DEPRECATED=y +UCLIBC_UCLINUX_BROKEN_MUNMAP=y +UNIX98PTY_ONLY=y diff --git a/toolchain/uClibc/config-0.9.33/x86_64 b/toolchain/uClibc/config-0.9.33/x86_64 new file mode 100644 index 000000000..92f0e6569 --- /dev/null +++ b/toolchain/uClibc/config-0.9.33/x86_64 @@ -0,0 +1,6 @@ +ARCH_LITTLE_ENDIAN=y +# LINUXTHREADS_NEW is not set +TARGET_ARCH="x86_64" +TARGET_x86_64=y +UCLIBC_BSD_SPECIFIC=y  +UCLIBC_HAS_FPU=y diff --git a/toolchain/uClibc/patches-0.9.33/110-compat_macros.patch b/toolchain/uClibc/patches-0.9.33/110-compat_macros.patch new file mode 100644 index 000000000..a7538b16f --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/110-compat_macros.patch @@ -0,0 +1,51 @@ +--- a/include/string.h ++++ b/include/string.h +@@ -355,18 +355,40 @@ extern char *index (__const char *__s, i + /* Find the last occurrence of C in S (same as strrchr).  */ + extern char *rindex (__const char *__s, int __c) +      __THROW __attribute_pure__ __nonnull ((1)); +-# else +-#  ifdef __UCLIBC_SUSV3_LEGACY_MACROS__ ++# elif defined(__UCLIBC_SUSV3_LEGACY_MACROS__) && !defined(_STRINGS_H) + /* bcopy/bzero/bcmp/index/rindex are marked LEGACY in SuSv3. +  * They are replaced as proposed by SuSv3. Don't sync this part +  * with glibc and keep it in sync with strings.h.  */ +  +-#  define bcopy(src,dest,n) (memmove((dest), (src), (n)), (void) 0) +-#  define bzero(s,n) (memset((s), '\0', (n)), (void) 0) +-#  define bcmp(s1,s2,n) memcmp((s1), (s2), (size_t)(n)) +-#  define index(s,c) strchr((s), (c)) +-#  define rindex(s,c) strrchr((s), (c)) +-#  endif ++/* Copy N bytes of SRC to DEST (like memmove, but args reversed).  */ ++static __inline__ void bcopy (__const void *__src, void *__dest, size_t __n) ++{ ++	memmove(__dest, __src, __n); ++} ++ ++/* Set N bytes of S to 0.  */ ++static __inline__ void bzero (void *__s, size_t __n) ++{ ++	memset(__s, 0, __n); ++} ++ ++/* Compare N bytes of S1 and S2 (same as memcmp).  */ ++static __inline__ int bcmp (__const void *__s1, __const void *__s2, size_t __n) ++{ ++	return memcmp(__s1, __s2, __n); ++} ++ ++/* Find the first occurrence of C in S (same as strchr).  */ ++static __inline__ char *index (__const char *__s, int __c) ++{ ++	return strchr(__s, __c); ++} ++ ++/* Find the last occurrence of C in S (same as strrchr).  */ ++static __inline__ char *rindex (__const char *__s, int __c) ++{ ++	return strrchr(__s, __c); ++} + # endif +  + /* Return the position of the first bit set in I, or 0 if none are set. diff --git a/toolchain/uClibc/patches-0.9.33/120-adjtimex.patch b/toolchain/uClibc/patches-0.9.33/120-adjtimex.patch new file mode 100644 index 000000000..dcf9c9b5a --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/120-adjtimex.patch @@ -0,0 +1,14 @@ +--- a/include/sys/timex.h ++++ b/include/sys/timex.h +@@ -116,9 +116,8 @@ struct timex +  + __BEGIN_DECLS +  +-#if 0 +-extern int __adjtimex (struct timex *__ntx) __THROW; +-#endif ++#undef __adjtimex ++#define __adjtimex adjtimex + extern int adjtimex (struct timex *__ntx) __THROW; + libc_hidden_proto(adjtimex) +  diff --git a/toolchain/uClibc/patches-0.9.33/131-inet-fix-__read_etc_hosts_r-segfault.patch b/toolchain/uClibc/patches-0.9.33/131-inet-fix-__read_etc_hosts_r-segfault.patch new file mode 100644 index 000000000..74b685763 --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/131-inet-fix-__read_etc_hosts_r-segfault.patch @@ -0,0 +1,10 @@ +--- a/libc/inet/resolv.c ++++ b/libc/inet/resolv.c +@@ -1634,6 +1634,7 @@ int attribute_hidden __read_etc_hosts_r( + 	 * struct in[6]_addr + 	 * char line_buffer[BUFSZ+]; + 	 */ ++	memset(buf, 0, buflen); + 	parser->data = buf; + 	parser->data_len = aliaslen; + 	parser->line_len = buflen - aliaslen; diff --git a/toolchain/uClibc/patches-0.9.33/140-avr32_atomic_fix.patch b/toolchain/uClibc/patches-0.9.33/140-avr32_atomic_fix.patch new file mode 100644 index 000000000..5e5460a3d --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/140-avr32_atomic_fix.patch @@ -0,0 +1,10 @@ +--- a/libc/sysdeps/linux/avr32/bits/atomic.h ++++ b/libc/sysdeps/linux/avr32/bits/atomic.h +@@ -28,6 +28,7 @@ typedef uintmax_t uatomic_max_t; +  + #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval)	\ + 	({								\ ++		__uint32_t __result;					\ + 		__typeof__(*(mem)) __prev;				\ + 		__asm__ __volatile__(					\ + 			"/* __arch_compare_and_exchange_val_32_acq */\n" \ diff --git a/toolchain/uClibc/patches-0.9.33/160-mips_signalfd_sfd_nonblock.patch b/toolchain/uClibc/patches-0.9.33/160-mips_signalfd_sfd_nonblock.patch new file mode 100644 index 000000000..6d94d3226 --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/160-mips_signalfd_sfd_nonblock.patch @@ -0,0 +1,27 @@ +From f87898ca4a7d4b7171779c06ff1f4848efeee431 Mon Sep 17 00:00:00 2001 +From: Khem Raj <raj.khem@gmail.com> +Date: Thu, 30 Jun 2011 07:32:11 +0000 +Subject: mips/signalfd.h: SFD_NONBLOCK for mips is 0200 unlike 04000 commonly + +Exposed by udev 171 which uses signalfd + +Signed-off-by: Khem Raj <raj.khem@gmail.com> +--- +--- a/include/sys/signalfd.h ++++ b/include/sys/signalfd.h +@@ -73,6 +73,15 @@ enum + # define SFD_NONBLOCK SFD_NONBLOCK +   }; +  ++#elif defined __mips__ ++enum ++  { ++    SFD_CLOEXEC = 02000000, ++# define SFD_CLOEXEC SFD_CLOEXEC ++    SFD_NONBLOCK = 0200 ++# define SFD_NONBLOCK SFD_NONBLOCK ++  }; ++ + #else + enum +   { diff --git a/toolchain/uClibc/patches-0.9.33/170-math_finite.patch b/toolchain/uClibc/patches-0.9.33/170-math_finite.patch new file mode 100644 index 000000000..b0ae3337b --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/170-math_finite.patch @@ -0,0 +1,23 @@ +--- a/include/math.h ++++ b/include/math.h +@@ -195,7 +195,7 @@ extern int signgam; +  +  + /* ISO C99 defines some generic macros which work on any data type.  */ +-#ifdef __USE_ISOC99 ++#if defined(__USE_ISOC99) || defined(__USE_BSD) +  + /* Get the architecture specific values describing the floating-point +    evaluation.  The following symbols will get defined: +@@ -315,6 +315,11 @@ enum +  + #endif /* Use ISO C99.  */ +  ++/* BSD compat */ ++#define finite(x) __finite(x) ++#define finitef(x) __finitef(x) ++#define finitel(x) __finitel(x) ++ + #ifdef	__USE_MISC + /* Support for various different standard error handling behaviors.  */ + typedef enum diff --git a/toolchain/uClibc/patches-0.9.33/180-pthread_cleanup_fix.patch b/toolchain/uClibc/patches-0.9.33/180-pthread_cleanup_fix.patch new file mode 100644 index 000000000..ae3601879 --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/180-pthread_cleanup_fix.patch @@ -0,0 +1,45 @@ +--- a/libpthread/nptl/cleanup_defer_compat.c ++++ b/libpthread/nptl/cleanup_defer_compat.c +@@ -22,7 +22,7 @@ +  + void + attribute_protected +-_pthread_cleanup_push_defer ( ++__pthread_cleanup_push_defer ( +      struct _pthread_cleanup_buffer *buffer, +      void (*routine) (void *), +      void *arg) +@@ -57,12 +57,12 @@ _pthread_cleanup_push_defer ( +  +   THREAD_SETMEM (self, cleanup, buffer); + } +-strong_alias (_pthread_cleanup_push_defer, __pthread_cleanup_push_defer) ++strong_alias (__pthread_cleanup_push_defer, _pthread_cleanup_push_defer) +  +  + void + attribute_protected +-_pthread_cleanup_pop_restore ( ++__pthread_cleanup_pop_restore ( +      struct _pthread_cleanup_buffer *buffer, +      int execute) + { +@@ -97,4 +97,4 @@ _pthread_cleanup_pop_restore ( +   if (execute) +     buffer->__routine (buffer->__arg); + } +-strong_alias (_pthread_cleanup_pop_restore, __pthread_cleanup_pop_restore) ++strong_alias (__pthread_cleanup_pop_restore, _pthread_cleanup_pop_restore) +--- a/libpthread/nptl/init.c ++++ b/libpthread/nptl/init.c +@@ -112,8 +112,8 @@ static const struct pthread_functions pt +     .ptr___pthread_key_create = __pthread_key_create_internal, +     .ptr___pthread_getspecific = __pthread_getspecific_internal, +     .ptr___pthread_setspecific = __pthread_setspecific_internal, +-    .ptr__pthread_cleanup_push_defer = _pthread_cleanup_push_defer, +-    .ptr__pthread_cleanup_pop_restore = _pthread_cleanup_pop_restore, ++    .ptr__pthread_cleanup_push_defer = __pthread_cleanup_push_defer, ++    .ptr__pthread_cleanup_pop_restore = __pthread_cleanup_pop_restore, +     .ptr_nthreads = &__nptl_nthreads, +     .ptr___pthread_unwind = &__pthread_unwind, +     .ptr__nptl_deallocate_tsd = __nptl_deallocate_tsd, diff --git a/toolchain/uClibc/patches-0.9.33/190-nptl_use_arch_default_stack_limit.patch b/toolchain/uClibc/patches-0.9.33/190-nptl_use_arch_default_stack_limit.patch new file mode 100644 index 000000000..b7f5c82e0 --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/190-nptl_use_arch_default_stack_limit.patch @@ -0,0 +1,13 @@ +--- a/libpthread/nptl/init.c ++++ b/libpthread/nptl/init.c +@@ -402,6 +402,10 @@ __pthread_initialize_minimal_internal (v +        Use the minimal size acceptable.  */ +     limit.rlim_cur = PTHREAD_STACK_MIN; +  ++  /* Do not exceed architecture specific default */ ++  if (limit.rlim_cur > ARCH_STACK_DEFAULT_SIZE) ++    limit.rlim_cur = ARCH_STACK_DEFAULT_SIZE; ++ +   /* Make sure it meets the minimum size that allocate_stack +      (allocatestack.c) will demand, which depends on the page size.  */ +   const uintptr_t pagesz = sysconf (_SC_PAGESIZE); diff --git a/toolchain/uClibc/patches-0.9.33/200-no_forced_unwind.patch b/toolchain/uClibc/patches-0.9.33/200-no_forced_unwind.patch new file mode 100644 index 000000000..d6869e2de --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/200-no_forced_unwind.patch @@ -0,0 +1,10 @@ +--- a/Rules.mak ++++ b/Rules.mak +@@ -707,7 +707,6 @@ endif + ifeq ($(UCLIBC_HAS_THREADS),y) + ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y) + 	PTNAME := nptl +-	CFLAGS += -DHAVE_FORCED_UNWIND + else + ifeq ($(LINUXTHREADS_OLD),y) + 	PTNAME := linuxthreads.old diff --git a/toolchain/uClibc/patches-0.9.33/350-use-fputs_unlocked.patch b/toolchain/uClibc/patches-0.9.33/350-use-fputs_unlocked.patch new file mode 100644 index 000000000..58b03ec7d --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/350-use-fputs_unlocked.patch @@ -0,0 +1,19 @@ +commit 3e3ae40f053b22fbb9bef50067d6edad4c358c4c +Author: Mirko Vogt <dev@nanl.de> +Date:   Tue May 24 14:36:42 2011 +0200 + +    use 'fputws_unlocked(S,F)' instead of 'fputws(S,F)' +     +    this eliminates a source of reproduceable freezes + +--- a/libc/stdio/_vfprintf.c ++++ b/libc/stdio/_vfprintf.c +@@ -1229,7 +1229,7 @@ static size_t _fp_out_narrow(FILE *fp, i + #define STRLEN  wcslen + #define _PPFS_init _ppwfs_init + /* Pulls in fseek: */ +-#define OUTPUT(F,S)			fputws(S,F) ++#define OUTPUT(F,S)			fputws_unlocked(S,F) + /* TODO: #define OUTPUT(F,S)		_wstdio_fwrite((S),wcslen(S),(F)) */ + #define _outnwcs(stream, wstring, len)	_wstdio_fwrite((const wchar_t *)(wstring), len, stream) + #define FP_OUT _fp_out_wide diff --git a/toolchain/uClibc/patches-0.9.33/410-llvm_workaround.patch b/toolchain/uClibc/patches-0.9.33/410-llvm_workaround.patch new file mode 100644 index 000000000..7ae394325 --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/410-llvm_workaround.patch @@ -0,0 +1,11 @@ +--- a/libc/stdio/_stdio.c ++++ b/libc/stdio/_stdio.c +@@ -124,7 +124,7 @@ static FILE _stdio_streams[] = { + 							 __FLAG_NBF|__FLAG_WRITEONLY, \ + 							 2, \ + 							 NULL, \ +-							 NULL, \ ++							 0, \ + 							 0 ) + }; +  diff --git a/toolchain/uClibc/patches-0.9.33/450-powerpc_copysignl.patch b/toolchain/uClibc/patches-0.9.33/450-powerpc_copysignl.patch new file mode 100644 index 000000000..ad8d6824b --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/450-powerpc_copysignl.patch @@ -0,0 +1,103 @@ +--- a/libc/sysdeps/linux/powerpc/Makefile.arch ++++ b/libc/sysdeps/linux/powerpc/Makefile.arch +@@ -5,7 +5,7 @@ + # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + # +  +-CSRC := __syscall_error.c pread_write.c ioctl.c ++CSRC := __syscall_error.c pread_write.c ioctl.c copysignl.c +  + ifeq ($(UCLIBC_HAS_ADVANCED_REALTIME),y) + CSRC += posix_fadvise.c posix_fadvise64.c +--- /dev/null ++++ b/libc/sysdeps/linux/powerpc/copysignl.c +@@ -0,0 +1,89 @@ ++/* s_copysignl.c -- long double version of s_copysign.c. ++ * Conversion to long double by Ulrich Drepper, ++ * Cygnus Support, drepper@cygnus.com. ++ */ ++ ++/* ++ * ==================================================== ++ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. ++ * ++ * Developed at SunPro, a Sun Microsystems, Inc. business. ++ * Permission to use, copy, modify, and distribute this ++ * software is freely granted, provided that this notice ++ * is preserved. ++ * ==================================================== ++ */ ++ ++/* ++ * copysignl(long double x, long double y) ++ * copysignl(x,y) returns a value with the magnitude of x and ++ * with the sign bit of y. ++ */ ++ ++#include <endian.h> ++#include <stdint.h> ++ ++#if __FLOAT_WORD_ORDER == BIG_ENDIAN ++ ++typedef union ++{ ++  long double value; ++  struct ++  { ++    int sign_exponent:16; ++    unsigned int empty:16; ++    uint32_t msw; ++    uint32_t lsw; ++  } parts; ++} ieee_long_double_shape_type; ++ ++#endif ++ ++#if __FLOAT_WORD_ORDER == LITTLE_ENDIAN ++ ++typedef union ++{ ++  long double value; ++  struct ++  { ++    uint32_t lsw; ++    uint32_t msw; ++    int sign_exponent:16; ++    unsigned int empty:16; ++  } parts; ++} ieee_long_double_shape_type; ++ ++#endif ++ ++/* Get int from the exponent of a long double.  */ ++ ++#define GET_LDOUBLE_EXP(exp,d)					\ ++do {								\ ++  ieee_long_double_shape_type ge_u;				\ ++  ge_u.value = (d);						\ ++  (exp) = ge_u.parts.sign_exponent;				\ ++} while (0) ++ ++/* Set exponent of a long double from an int.  */ ++ ++#define SET_LDOUBLE_EXP(d,exp)					\ ++do {								\ ++  ieee_long_double_shape_type se_u;				\ ++  se_u.value = (d);						\ ++  se_u.parts.sign_exponent = (exp);				\ ++  (d) = se_u.value;						\ ++} while (0) ++ ++long double copysignl(long double x, long double y); ++libc_hidden_proto(copysignl); ++ ++long double copysignl(long double x, long double y) ++{ ++	uint32_t es1,es2; ++	GET_LDOUBLE_EXP(es1,x); ++	GET_LDOUBLE_EXP(es2,y); ++	SET_LDOUBLE_EXP(x,(es1&0x7fff)|(es2&0x8000)); ++        return x; ++} ++ ++libc_hidden_def(copysignl); diff --git a/toolchain/uClibc/patches-0.9.33/480-powerpc_rel24_support.patch b/toolchain/uClibc/patches-0.9.33/480-powerpc_rel24_support.patch new file mode 100644 index 000000000..19c2b2c8a --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/480-powerpc_rel24_support.patch @@ -0,0 +1,26 @@ +--- a/ldso/ldso/powerpc/elfinterp.c ++++ b/ldso/ldso/powerpc/elfinterp.c +@@ -297,22 +297,17 @@ _dl_do_reloc (struct elf_resolve *tpnt,s + 		break; + #endif + 	case R_PPC_REL24: +-#if 0 + 		{ + 			Elf32_Sword delta = finaladdr - (Elf32_Word)reloc_addr; + 			if (unlikely(delta<<6>>6 != delta)) { + 				_dl_dprintf(2, "%s: symbol '%s' R_PPC_REL24 is out of range.\n\t" + 						"Compile shared libraries with -fPIC!\n", + 						_dl_progname, symname); +-				_dl_exit(1); ++				return -1; + 			} + 			*reloc_addr = (*reloc_addr & 0xfc000003) | (delta & 0x3fffffc); + 			break; + 		} +-#else +-		_dl_dprintf(2,"R_PPC_REL24: Compile shared libraries with -fPIC!\n"); +-		return -1; +-#endif + 	case R_PPC_NONE: + 		goto out_nocode; /* No code code modified */ + 	default: diff --git a/toolchain/uClibc/patches-0.9.33/600-ubicom32-uClibc.patch b/toolchain/uClibc/patches-0.9.33/600-ubicom32-uClibc.patch new file mode 100644 index 000000000..6e8fc8a89 --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/600-ubicom32-uClibc.patch @@ -0,0 +1,4305 @@ +--- a/Rules.mak ++++ b/Rules.mak +@@ -524,6 +524,17 @@ ifeq ($(TARGET_ARCH),i960) +       SYMBOL_PREFIX=_ + endif +  ++ifeq ($(TARGET_ARCH),ubicom32) ++	OPTIMIZATION+=-fstrict-aliasing ++	CPU_CFLAGS-$(CONFIG_UBICOM32_V3)+=-march=ubicom32v3 ++	CPU_CFLAGS-$(CONFIG_UBICOM32_V4)+=-march=ubicom32v4 ++ifeq ($(UCLIBC_FORMAT_FDPIC_ELF),y) ++	CPU_CFLAGS-y:=-mfdpic ++	CPU_LDFLAGS-y += -Wl,-melf32ubicom32fdpic ++endif ++ ++endif ++ + ifeq ($(TARGET_ARCH),v850) +       SYMBOL_PREFIX=_ + endif +--- a/extra/Configs/Config.in ++++ b/extra/Configs/Config.in +@@ -102,6 +102,9 @@ config TARGET_sh64 + config TARGET_sparc + 	bool "sparc" +  ++config TARGET_ubicom32 ++	bool "ubicom32" ++ + config TARGET_v850 + 	bool "v850 (BROKEN)" +  +@@ -206,6 +209,10 @@ if TARGET_sparc + source "extra/Configs/Config.sparc" + endif +  ++if TARGET_ubicom32 ++source "extra/Configs/Config.ubicom32" ++endif ++ + if TARGET_v850 + source "extra/Configs/Config.v850" + endif +--- a/extra/Configs/Config.in.arch ++++ b/extra/Configs/Config.in.arch +@@ -152,7 +152,7 @@ config UCLIBC_HAS_SOFT_FLOAT + config DO_C99_MATH + 	bool "Enable full C99 math library support" + 	depends on UCLIBC_HAS_FLOATS +-	default n ++	default y + 	help + 	  If you want the uClibc math library to contain the full set C99 + 	  math library features, then answer Y.  If you leave this set to +--- /dev/null ++++ b/extra/Configs/Config.ubicom32 +@@ -0,0 +1,44 @@ ++# ++# For a description of the syntax of this configuration file, ++# see extra/config/Kconfig-language.txt ++# ++ ++config TARGET_ARCH ++	string ++	default "ubicom32" ++ ++config FORCE_OPTIONS_FOR_ARCH ++	bool ++	default y ++	select ARCH_BIG_ENDIAN ++	select ARCH_HAS_NO_MMU ++ ++choice ++	prompt "Target Processor Architecture" ++	default CONFIG_UC_UBICOM32_V3 ++	help ++	  This selects the instruction set architecture of your Ubicom32 CPU. This ++	  information is used for optimizing purposes. To build a library that ++	  will run on any Ubicom32 CPU, you can specify "v3" here. ++	  If you pick anything other than "v3," there is no ++	  guarantee that uClibc will even run on anything other than the ++	  selected processor type. ++ ++	  You should probably select the Ubicom32 ISA that best matches the ++	  CPU you will be using on your device. uClibc will be tuned ++	  for that architecture. ++ ++	  If you don't know what to do, choose "v3" ++ ++config CONFIG_UC_UBICOM32_V3 ++	bool "ISA v3" ++ ++config CONFIG_UC_UBICOM32_V4 ++	bool "ISA v4" ++endchoice ++ ++config ARCH_CFLAGS ++	string ++ ++config CROSS ++	string +--- a/include/elf.h ++++ b/include/elf.h +@@ -338,6 +338,8 @@ typedef struct +  + #define EM_XSTORMY16		0xad45 +  ++#define EM_UBICOM32 	        0xde3d	/* Ubicom32; no ABI */ ++ + /* FRV magic number - no EABI available??.  */ + #define EM_CYGNUS_FRV	0x5441 +  +@@ -3141,6 +3143,55 @@ typedef Elf32_Addr Elf32_Conflict; + #define R_MICROBLAZE_COPY 21  /* runtime copy */ + #define R_MICROBLAZE_NUM 22 +  ++/* Ubicom32 ELF relocation types */ ++#define R_UBICOM32_NONE               0 ++#define R_UBICOM32_16                         1 ++#define R_UBICOM32_32                         2 ++#define R_UBICOM32_LO16               3 ++#define R_UBICOM32_HI16               4 ++#define R_UBICOM32_21_PCREL           5 ++#define R_UBICOM32_24_PCREL           6 ++#define R_UBICOM32_HI24               7 ++#define R_UBICOM32_LO7_S              8 ++#define R_UBICOM32_LO7_2_S            9 ++#define R_UBICOM32_LO7_4_S            10 ++#define R_UBICOM32_LO7_D              11 ++#define R_UBICOM32_LO7_2_D            12 ++#define R_UBICOM32_LO7_4_D            13 ++#define R_UBICOM32_32_HARVARD                 14 ++#define R_UBICOM32_LO7_CALLI          15 ++#define R_UBICOM32_LO16_CALLI                 16 ++#define R_UBICOM32_GOT_HI24           17 ++#define R_UBICOM32_GOT_LO7_S          18 ++#define R_UBICOM32_GOT_LO7_2_S                19 ++#define R_UBICOM32_GOT_LO7_4_S                20 ++#define R_UBICOM32_GOT_LO7_D          21 ++#define R_UBICOM32_GOT_LO7_2_D                22 ++#define R_UBICOM32_GOT_LO7_4_D                23 ++#define R_UBICOM32_FUNCDESC_GOT_HI24  24 ++#define R_UBICOM32_FUNCDESC_GOT_LO7_S 25 ++#define R_UBICOM32_FUNCDESC_GOT_LO7_2_S 26 ++#define R_UBICOM32_FUNCDESC_GOT_LO7_4_S 27 ++#define R_UBICOM32_FUNCDESC_GOT_LO7_D 28 ++#define R_UBICOM32_FUNCDESC_GOT_LO7_2_D 29 ++#define R_UBICOM32_FUNCDESC_GOT_LO7_4_D 30 ++#define R_UBICOM32_GOT_LO7_CALLI      31 ++#define R_UBICOM32_FUNCDESC_GOT_LO7_CALLI 32 ++#define R_UBICOM32_FUNCDESC_VALUE     33 ++#define R_UBICOM32_FUNCDESC           34 ++#define R_UBICOM32_GOTOFFSET_LO               35 ++#define R_UBICOM32_GOTOFFSET_HI               36 ++#define R_UBICOM32_FUNCDESC_GOTOFFSET_LO 37 ++#define R_UBICOM32_FUNCDESC_GOTOFFSET_HI 38 ++#define R_UBICOM32_GNU_VTINHERIT      200 ++#define R_UBICOM32_GNU_VTENTRY                201 ++ ++/* Ubicom32 Flags. */ ++#define EF_UBICOM32_V3                0x00000001      /* -fmarch=ubicom32v3 */ ++#define EF_UBICOM32_V4                0x00000002      /* -fmarch=ubicom32v4 */ ++#define EF_UBICOM32_PIC               0x80000000      /* -fpic */ ++#define EF_UBICOM32_FDPIC             0x40000000      /* -mfdpic */ ++ + #ifdef	__cplusplus + } + #endif +--- a/include/features.h ++++ b/include/features.h +@@ -448,4 +448,10 @@ uClibc was built without large file supp + # include <libc-internal.h> + #endif +  ++#ifndef libc_hidden_proto ++#define libc_hidden_proto(name, attrs...) ++#endif ++#ifndef libm_hidden_proto ++#define libm_hidden_proto(name, attrs...) ++#endif + #endif	/* features.h  */ +--- /dev/null ++++ b/ldso/ldso/ubicom32/dl-debug.h +@@ -0,0 +1,72 @@ ++/* vi: set sw=4 ts=4: */ ++/* Ubicom32 ELF shared library loader suppport ++ * ++ * Copyright (c) 2009		Ubicom Inc. ++ * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, ++ *                              David Engel, Hongjiu Lu and Mitch D'Souza ++ * Copyright (C) 2001-2004 Erik Andersen ++ * ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ *    notice, this list of conditions and the following disclaimer. ++ * 2. The name of the above contributors may not be ++ *    used to endorse or promote products derived from this software ++ *    without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ */ ++ ++static const char *_dl_reltypes_tab[] = ++{ ++	"R_UBICOM32_NONE", /* 0 */ ++	"R_UBICOM32_16", ++	"R_UBICOM32_32", ++	"R_UBICOM32_LO16", ++	"R_UBICOM32_HI16", ++	"R_UBICOM32_21_PCREL", /* 5 */ ++	"R_UBICOM32_24_PCREL", ++	"R_UBICOM32_HI24", ++	"R_UBICOM32_LO7_S", ++	"R_UBICOM32_LO7_2_S", ++	"R_UBICOM32_LO7_4_S", /* 10 */ ++	"R_UBICOM32_LO7_D", ++	"R_UBICOM32_LO7_2_D", ++	"R_UBICOM32_LO7_4_D", ++	"R_UBICOM32_32_HARVARD", ++	"R_UBICOM32_LO7_CALLI", /* 15 */ ++	"R_UBICOM32_LO16_CALLI", ++	"R_UBICOM32_GOT_HI24", ++	"R_UBICOM32_GOT_LO7_S", ++	"R_UBICOM32_GOT_LO7_2_S" ++	"R_UBICOM32_GOT_LO7_4_S", /* 20 */ ++	"R_UBICOM32_GOT_LO7_D", ++	"R_UBICOM32_GOT_LO7_2_D", ++	"R_UBICOM32_GOT_LO7_4_D", ++	"R_UBICOM32_FUNCDESC_GOT_HI24	24", ++	"R_UBICOM32_FUNCDESC_GOT_LO7_S", /* 25 */ ++	"R_UBICOM32_FUNCDESC_GOT_LO7_2_S", ++	"R_UBICOM32_FUNCDESC_GOT_LO7_4_S", ++	"R_UBICOM32_FUNCDESC_GOT_LO7_D", ++	"R_UBICOM32_FUNCDESC_GOT_LO7_2_D", ++	"R_UBICOM32_FUNCDESC_GOT_LO7_4_D", /* 30 */ ++	"R_UBICOM32_GOT_LO7_CALLI", ++	"R_UBICOM32_FUNCDESC_VALUE", ++	"R_UBICOM32_FUNCDESC", ++#if 1 ++	[200] "R_UBICOM32_GNU_VTINHERIT" , "R_UBICOM32_GNU_VTENTRY" ++#endif ++}; +--- /dev/null ++++ b/ldso/ldso/ubicom32/dl-inlines.h +@@ -0,0 +1,582 @@ ++     /* Copyright (C) 2003, 2004 Red Hat, Inc. ++	Contributed by Alexandre Oliva <aoliva@redhat.com> ++ ++This file is part of uClibc. ++ ++uClibc 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. ++ ++uClibc 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 Lesser General Public ++License along with uClibc; see the file COPYING.LIB.  If not, write to ++the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, ++USA.  */ ++ ++//#include <bfin_sram.h> ++#define SRAM_TEST(x) 0 ++#ifndef _dl_assert ++# define _dl_assert(expr) ++#endif ++ ++/* Initialize a DL_LOADADDR_TYPE given a got pointer and a complete ++   load map.  */ ++static __always_inline void ++__dl_init_loadaddr_map (struct elf32_fdpic_loadaddr *loadaddr, Elf32_Addr dl_boot_got_pointer, ++			struct elf32_fdpic_loadmap *map) ++{ ++  if (map->version != 0) ++    { ++      SEND_EARLY_STDERR ("Invalid loadmap version number\n"); ++      _dl_exit(-1); ++    } ++  if (map->nsegs == 0) ++    { ++      SEND_EARLY_STDERR ("Invalid segment count in loadmap\n"); ++      _dl_exit(-1); ++    } ++  loadaddr->got_value = (void*)dl_boot_got_pointer; ++  loadaddr->map = map; ++} ++ ++/* Figure out how many LOAD segments there are in the given headers, ++   and allocate a block for the load map big enough for them. ++   got_value will be properly initialized later on, with INIT_GOT.  */ ++static __always_inline int ++__dl_init_loadaddr (struct elf32_fdpic_loadaddr *loadaddr, Elf32_Phdr *ppnt, ++		    int pcnt) ++{ ++  int count = 0, i; ++  size_t size; ++ ++  for (i = 0; i < pcnt; i++) ++    if (ppnt[i].p_type == PT_LOAD) ++      count++; ++ ++  loadaddr->got_value = 0; ++ ++  size = sizeof (struct elf32_fdpic_loadmap) ++    + sizeof (struct elf32_fdpic_loadseg) * count; ++  loadaddr->map = _dl_malloc (size); ++  if (! loadaddr->map) ++    _dl_exit (-1); ++ ++  loadaddr->map->version = 0; ++  loadaddr->map->nsegs = 0; ++ ++  return count; ++} ++ ++#if defined (__SUPPORT_LD_DEBUG__) ++extern char *_dl_debug; ++extern int _dl_debug_file; ++#endif ++ ++/* Incrementally initialize a load map.  */ ++static __always_inline void ++__dl_init_loadaddr_hdr (struct elf32_fdpic_loadaddr loadaddr, void *addr, ++			Elf32_Phdr *phdr, int maxsegs) ++{ ++  struct elf32_fdpic_loadseg *segdata; ++ ++  if (loadaddr.map->nsegs == maxsegs) ++    _dl_exit (-1); ++ ++  segdata = &loadaddr.map->segs[loadaddr.map->nsegs++]; ++  segdata->addr = (Elf32_Addr) addr; ++  segdata->p_vaddr = phdr->p_vaddr; ++  segdata->p_memsz = phdr->p_memsz; ++ ++#if defined (__SUPPORT_LD_DEBUG__) ++  { ++    if (_dl_debug) ++      _dl_dprintf(_dl_debug_file, "%i: mapped %x at %x, size %x\n", ++		  loadaddr.map->nsegs-1, ++		  segdata->p_vaddr, segdata->addr, segdata->p_memsz); ++  } ++#endif ++} ++ ++static __always_inline void __dl_loadaddr_unmap ++(struct elf32_fdpic_loadaddr loadaddr, struct funcdesc_ht *funcdesc_ht); ++ ++/* Figure out whether the given address is in one of the mapped ++   segments.  */ ++static __always_inline int ++__dl_addr_in_loadaddr (void *p, struct elf32_fdpic_loadaddr loadaddr) ++{ ++  struct elf32_fdpic_loadmap *map = loadaddr.map; ++  int c; ++ ++  for (c = 0; c < map->nsegs; c++) ++    if ((void*)map->segs[c].addr <= p ++	&& (char*)p < (char*)map->segs[c].addr + map->segs[c].p_memsz) ++      return 1; ++ ++  return 0; ++} ++ ++static __always_inline void * _dl_funcdesc_for (void *entry_point, void *got_value); ++ ++/* The hashcode handling code below is heavily inspired in libiberty's ++   hashtab code, but with most adaptation points and support for ++   deleting elements removed. ++ ++   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ++   Contributed by Vladimir Makarov (vmakarov@cygnus.com).  */ ++ ++static __always_inline unsigned long ++higher_prime_number (unsigned long n) ++{ ++  /* These are primes that are near, but slightly smaller than, a ++     power of two.  */ ++  static const unsigned long primes[] = { ++    (unsigned long) 7, ++    (unsigned long) 13, ++    (unsigned long) 31, ++    (unsigned long) 61, ++    (unsigned long) 127, ++    (unsigned long) 251, ++    (unsigned long) 509, ++    (unsigned long) 1021, ++    (unsigned long) 2039, ++    (unsigned long) 4093, ++    (unsigned long) 8191, ++    (unsigned long) 16381, ++    (unsigned long) 32749, ++    (unsigned long) 65521, ++    (unsigned long) 131071, ++    (unsigned long) 262139, ++    (unsigned long) 524287, ++    (unsigned long) 1048573, ++    (unsigned long) 2097143, ++    (unsigned long) 4194301, ++    (unsigned long) 8388593, ++    (unsigned long) 16777213, ++    (unsigned long) 33554393, ++    (unsigned long) 67108859, ++    (unsigned long) 134217689, ++    (unsigned long) 268435399, ++    (unsigned long) 536870909, ++    (unsigned long) 1073741789, ++    (unsigned long) 2147483647, ++					/* 4294967291L */ ++    ((unsigned long) 2147483647) + ((unsigned long) 2147483644), ++  }; ++ ++  const unsigned long *low = &primes[0]; ++  const unsigned long *high = &primes[sizeof(primes) / sizeof(primes[0])]; ++ ++  while (low != high) ++    { ++      const unsigned long *mid = low + (high - low) / 2; ++      if (n > *mid) ++	low = mid + 1; ++      else ++	high = mid; ++    } ++ ++#if 0 ++  /* If we've run out of primes, abort.  */ ++  if (n > *low) ++    { ++      fprintf (stderr, "Cannot find prime bigger than %lu\n", n); ++      abort (); ++    } ++#endif ++ ++  return *low; ++} ++ ++struct funcdesc_ht ++{ ++  /* Table itself.  */ ++  struct funcdesc_value **entries; ++ ++  /* Current size (in entries) of the hash table */ ++  size_t size; ++ ++  /* Current number of elements.  */ ++  size_t n_elements; ++}; ++ ++static __always_inline int ++hash_pointer (const void *p) ++{ ++  return (int) ((long)p >> 3); ++} ++ ++static __always_inline struct funcdesc_ht * ++htab_create (void) ++{ ++  struct funcdesc_ht *ht = _dl_malloc (sizeof (struct funcdesc_ht)); ++ ++  if (! ht) ++    return NULL; ++  ht->size = 3; ++  ht->entries = _dl_malloc (sizeof (struct funcdesc_ht_value *) * ht->size); ++  if (! ht->entries) ++    return NULL; ++ ++  ht->n_elements = 0; ++ ++  _dl_memset (ht->entries, 0, sizeof (struct funcdesc_ht_value *) * ht->size); ++ ++  return ht; ++} ++ ++/* This is only called from _dl_loadaddr_unmap, so it's safe to call ++   _dl_free().  See the discussion below.  */ ++static __always_inline void ++htab_delete (struct funcdesc_ht *htab) ++{ ++  int i; ++ ++  for (i = htab->size - 1; i >= 0; i--) ++    if (htab->entries[i]) ++      _dl_free (htab->entries[i]); ++ ++  _dl_free (htab->entries); ++  _dl_free (htab); ++} ++ ++/* Similar to htab_find_slot, but without several unwanted side effects: ++    - Does not call htab->eq_f when it finds an existing entry. ++    - Does not change the count of elements/searches/collisions in the ++      hash table. ++   This function also assumes there are no deleted entries in the table. ++   HASH is the hash value for the element to be inserted.  */ ++ ++static __always_inline struct funcdesc_value ** ++find_empty_slot_for_expand (struct funcdesc_ht *htab, int hash) ++{ ++  size_t size = htab->size; ++  unsigned int index = hash % size; ++  struct funcdesc_value **slot = htab->entries + index; ++  int hash2; ++ ++  if (! *slot) ++    return slot; ++ ++  hash2 = 1 + hash % (size - 2); ++  for (;;) ++    { ++      index += hash2; ++      if (index >= size) ++	index -= size; ++ ++      slot = htab->entries + index; ++      if (! *slot) ++	return slot; ++    } ++} ++ ++/* The following function changes size of memory allocated for the ++   entries and repeatedly inserts the table elements.  The occupancy ++   of the table after the call will be about 50%.  Naturally the hash ++   table must already exist.  Remember also that the place of the ++   table entries is changed.  If memory allocation failures are allowed, ++   this function will return zero, indicating that the table could not be ++   expanded.  If all goes well, it will return a non-zero value.  */ ++ ++static __always_inline int ++htab_expand (struct funcdesc_ht *htab) ++{ ++  struct funcdesc_value **oentries; ++  struct funcdesc_value **olimit; ++  struct funcdesc_value **p; ++  struct funcdesc_value **nentries; ++  size_t nsize; ++ ++  oentries = htab->entries; ++  olimit = oentries + htab->size; ++ ++  /* Resize only when table after removal of unused elements is either ++     too full or too empty.  */ ++  if (htab->n_elements * 2 > htab->size) ++    nsize = higher_prime_number (htab->n_elements * 2); ++  else ++    nsize = htab->size; ++ ++  nentries = _dl_malloc (sizeof (struct funcdesc_value *) * nsize); ++  _dl_memset (nentries, 0, sizeof (struct funcdesc_value *) * nsize); ++  if (nentries == NULL) ++    return 0; ++  htab->entries = nentries; ++  htab->size = nsize; ++ ++  p = oentries; ++  do ++    { ++      if (*p) ++	*find_empty_slot_for_expand (htab, hash_pointer ((*p)->entry_point)) ++	  = *p; ++ ++      p++; ++    } ++  while (p < olimit); ++ ++#if 0 /* We can't tell whether this was allocated by the _dl_malloc() ++	 built into ld.so or malloc() in the main executable or libc, ++	 and calling free() for something that wasn't malloc()ed could ++	 do Very Bad Things (TM).  Take the conservative approach ++	 here, potentially wasting as much memory as actually used by ++	 the hash table, even if multiple growths occur.  That's not ++	 so bad as to require some overengineered solution that would ++	 enable us to keep track of how it was allocated. */ ++  _dl_free (oentries); ++#endif ++  return 1; ++} ++ ++/* This function searches for a hash table slot containing an entry ++   equal to the given element.  To delete an entry, call this with ++   INSERT = 0, then call htab_clear_slot on the slot returned (possibly ++   after doing some checks).  To insert an entry, call this with ++   INSERT = 1, then write the value you want into the returned slot. ++   When inserting an entry, NULL may be returned if memory allocation ++   fails.  */ ++ ++static __always_inline struct funcdesc_value ** ++htab_find_slot (struct funcdesc_ht *htab, void *ptr, int insert) ++{ ++  unsigned int index; ++  int hash, hash2; ++  size_t size; ++  struct funcdesc_value **entry; ++ ++  if (htab->size * 3 <= htab->n_elements * 4 ++      && htab_expand (htab) == 0) ++    return NULL; ++ ++  hash = hash_pointer (ptr); ++ ++  size = htab->size; ++  index = hash % size; ++ ++  entry = &htab->entries[index]; ++  if (!*entry) ++    goto empty_entry; ++  else if ((*entry)->entry_point == ptr) ++    return entry; ++ ++  hash2 = 1 + hash % (size - 2); ++  for (;;) ++    { ++      index += hash2; ++      if (index >= size) ++	index -= size; ++ ++      entry = &htab->entries[index]; ++      if (!*entry) ++	goto empty_entry; ++      else if ((*entry)->entry_point == ptr) ++	return entry; ++    } ++ ++ empty_entry: ++  if (!insert) ++    return NULL; ++ ++  htab->n_elements++; ++  return entry; ++} ++ ++void * ++_dl_funcdesc_for (void *entry_point, void *got_value) ++{ ++  struct elf_resolve *tpnt = ((void**)got_value)[2]; ++  struct funcdesc_ht *ht = tpnt->funcdesc_ht; ++  struct funcdesc_value **entry; ++ ++  _dl_assert (got_value == tpnt->loadaddr.got_value); ++ ++  if (! ht) ++    { ++      ht = htab_create (); ++      if (! ht) ++	return (void*)-1; ++      tpnt->funcdesc_ht = ht; ++    } ++ ++  entry = htab_find_slot (ht, entry_point, 1); ++  if (*entry) ++    { ++      _dl_assert ((*entry)->entry_point == entry_point); ++      return _dl_stabilize_funcdesc (*entry); ++    } ++ ++  *entry = _dl_malloc (sizeof (struct funcdesc_value)); ++  (*entry)->entry_point = entry_point; ++  (*entry)->got_value = got_value; ++ ++  return _dl_stabilize_funcdesc (*entry); ++} ++ ++static __always_inline void const * ++_dl_lookup_address (void const *address) ++{ ++  struct elf_resolve *rpnt; ++  struct funcdesc_value const *fd; ++ ++  /* Make sure we don't make assumptions about its alignment.  */ ++  __asm__ ("" : "+r" (address)); ++ ++  if ((Elf32_Addr)address & 7) ++    /* It's not a function descriptor.  */ ++    return address; ++ ++  fd = (struct funcdesc_value const *)address; ++ ++  for (rpnt = _dl_loaded_modules; rpnt; rpnt = rpnt->next) ++    { ++      if (! rpnt->funcdesc_ht) ++	continue; ++ ++      if (fd->got_value != rpnt->loadaddr.got_value) ++	continue; ++ ++      address = htab_find_slot (rpnt->funcdesc_ht, (void*)fd->entry_point, 0); ++ ++      if (address && *(struct funcdesc_value *const*)address == fd) ++	{ ++	  address = (*(struct funcdesc_value *const*)address)->entry_point; ++	  break; ++	} ++      else ++	address = fd; ++    } ++ ++  return address; ++} ++ ++void ++__dl_loadaddr_unmap (struct elf32_fdpic_loadaddr loadaddr, ++		     struct funcdesc_ht *funcdesc_ht) ++{ ++  int i; ++ ++  for (i = 0; i < loadaddr.map->nsegs; i++) ++    { ++      struct elf32_fdpic_loadseg *segdata; ++      ssize_t offs; ++      segdata = loadaddr.map->segs + i; ++ ++#if 0 /* SRAM */ ++      /* FIXME: ++	A more cleaner way is to add type for struct elf32_fdpic_loadseg, ++	and release the memory according to the type. ++	Currently, we hardcode the memory address of L1 SRAM.  */ ++      if ((segdata->addr & 0xff800000) == 0xff800000) ++       { ++	 _dl_sram_free ((void *)segdata->addr); ++	 continue; ++       } ++#endif ++      offs = (segdata->p_vaddr & ADDR_ALIGN); ++      _dl_munmap ((void*)segdata->addr - offs, ++		  segdata->p_memsz + offs); ++    } ++  /* _dl_unmap is only called for dlopen()ed libraries, for which ++     calling free() is safe, or before we've completed the initial ++     relocation, in which case calling free() is probably pointless, ++     but still safe.  */ ++  _dl_free (loadaddr.map); ++  if (funcdesc_ht) ++    htab_delete (funcdesc_ht); ++} ++ ++#if 0 /* XXX TODO will look at enabling this if we decide to add support for OCM ++       * code/data */ ++// OLD BLACKFIN CODE ++static __always_inline int ++__dl_is_special_segment (Elf32_Ehdr *epnt, ++			 Elf32_Phdr *ppnt) ++{ ++  if (ppnt->p_type != PT_LOAD) ++    return 0; ++ ++  if ((epnt->e_flags & EF_BFIN_CODE_IN_L1) ++      && !(ppnt->p_flags & PF_W) ++      && (ppnt->p_flags & PF_X)) ++    return 1; ++ ++  if ((epnt->e_flags & EF_BFIN_DATA_IN_L1) ++      && (ppnt->p_flags & PF_W) ++      && !(ppnt->p_flags & PF_X)) ++    return 1; ++ ++  /* 0xff700000, 0xff800000, 0xff900000 and 0xffa00000 are also used in ++     GNU ld and linux kernel. They need to be keep synchronized.  */ ++  if (ppnt->p_vaddr == 0xff700000 ++      || ppnt->p_vaddr == 0xff800000 ++      || ppnt->p_vaddr == 0xff900000 ++      || ppnt->p_vaddr == 0xffa00000) ++    return 1; ++ ++  return 0; ++} ++ ++static __always_inline char * ++__dl_map_segment (Elf32_Ehdr *epnt, ++		  Elf32_Phdr *ppnt, ++		  int infile, ++		  int flags) ++{ ++  char *status, *tryaddr, *l1addr; ++  size_t size; ++ ++ ++  if (((epnt->e_flags & EF_BFIN_CODE_IN_L1) || ppnt->p_vaddr == 0xffa00000) ++      && !(ppnt->p_flags & PF_W) ++      && (ppnt->p_flags & PF_X)) { ++    status = (char *) _dl_mmap ++      (tryaddr = 0, ++       size = (ppnt->p_vaddr & ADDR_ALIGN) + ppnt->p_filesz, ++       LXFLAGS(ppnt->p_flags), ++       flags | MAP_EXECUTABLE | MAP_DENYWRITE, ++       infile, ppnt->p_offset & OFFS_ALIGN); ++    if (_dl_mmap_check_error(status) ++	|| (tryaddr && tryaddr != status)) ++      return NULL; ++    l1addr = (char *) _dl_sram_alloc (ppnt->p_filesz, L1_INST_SRAM); ++    if (l1addr != NULL) ++      _dl_dma_memcpy (l1addr, status + (ppnt->p_vaddr & ADDR_ALIGN), ppnt->p_filesz); ++    _dl_munmap (status, size); ++    if (l1addr == NULL) ++      _dl_dprintf(2, "%s:%i: L1 allocation failed\n", _dl_progname, __LINE__); ++    return l1addr; ++  } ++ ++  if (((epnt->e_flags & EF_BFIN_DATA_IN_L1) ++       || ppnt->p_vaddr == 0xff700000 ++       || ppnt->p_vaddr == 0xff800000 ++       || ppnt->p_vaddr == 0xff900000) ++      && (ppnt->p_flags & PF_W) ++      && !(ppnt->p_flags & PF_X)) { ++    if (ppnt->p_vaddr == 0xff800000) ++      l1addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_A_SRAM); ++    else if (ppnt->p_vaddr == 0xff900000) ++      l1addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_B_SRAM); ++    else ++      l1addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_SRAM); ++    if (l1addr == NULL) { ++      _dl_dprintf(2, "%s:%i: L1 allocation failed\n", _dl_progname, __LINE__); ++    } else { ++      if (_DL_PREAD (infile, l1addr, ppnt->p_filesz, ppnt->p_offset) != ppnt->p_filesz) { ++	_dl_sram_free (l1addr); ++	return NULL; ++      } ++      if (ppnt->p_filesz < ppnt->p_memsz) ++       _dl_memset (l1addr + ppnt->p_filesz, 0, ppnt->p_memsz - ppnt->p_filesz); ++    } ++    return l1addr; ++  } ++  return 0; ++} ++#endif +--- /dev/null ++++ b/ldso/ldso/ubicom32/dl-startup.h +@@ -0,0 +1,232 @@ ++/* ++  Copyright (C) 2009 Ubicom, Inc. ++  Copyright (C) 2003 Red Hat, Inc. ++  Contributed by Alexandre Oliva <aoliva@redhat.com> ++ ++This file is part of uClibc. ++ ++uClibc 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. ++ ++uClibc 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 Lesser General Public ++License along with uClibc; see the file COPYING.LIB.  If not, write to ++the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, ++USA.  */ ++ ++/* Any assembly language/system dependent hacks needed to setup ++ * boot1.c so it will work as expected and cope with whatever platform ++ * specific wierdness is needed for this architecture. ++ ++ * We override the default _dl_boot function, and replace it with a ++ * bit of asm.  Then call the real _dl_boot function, which is now ++ * named _dl_boot2.  */ ++ ++/* At program start-up, p0 contains a pointer to a ++   elf32_fdpic_loadmap that describes how the executable was loaded ++   into memory.  p1 contains a pointer to the interpreter (our!) ++   loadmap, if there is an interpreter, or 0 if we're being run as an ++   executable.  p2 holds a pointer to the interpreter's dynamic ++   section, if there is an interpreter, or to the executable's dynamic ++   section, otherwise.  If the executable is not dynamic, gr18 is 0. ++ ++   We rely on the fact that the linker adds a pointer to the ++   _GLOBAL_OFFSET_TABLE_ as the last ROFIXUP entry, and that ++   __self_reloc returns the relocated pointer to us, so that we can ++   use this value to initialize the PIC register.  */ ++ ++ ++/* ++ *  _dl_boot is the entry point for ldso. ++ * ++ * The kernel leaves the main apps args on the stack (positive offsets), and ++ * communicates the load maps as follows ++ * ++ * - d1 is set to the exec_map_addr (struct elf32_fdpic_loadmap *), which is the ++ *   current state of the mapped application. ++ * ++ * - d2 is set to interp_map_addr (struct elf32_fdpic_loadmap *), which is use ++ *    by ldso to relocate itself. ++ * ++ * - d3 is dynamic_addr which as far as I can tell is the stack pointer. ++ * ++ * - a1 is set to zero and will later be initialised to ldso _dl_fini funcdesc ++ */ ++ ++__asm__( ++	"	.text							\n\t" ++	"	.global	_start						\n\t" ++	"	.type	_start,@function				\n\t" ++	"_start:\n\t" ++	/* ++	 * Jump to .Lcall storing the location .Lcall in a5 ++	 */ ++	"	call	a5, .Lcall					\n\t" ++	".Lcall:							\n\t" ++	/* ++	 * Reserve and Push inputs to stack. ++	 * 32 byte  stack layout as follows ++	 * offset	0  exec_map_addr ++	 *		4  interp_map_addr ++	 *		8  dynamic_addr ++	 *		12 not used ++	 *		16 dl_main_funcdesc structure for _dl_boot ++	 *		   (12 bytes sizeof funcdesc_value) ++	 *		28 reserved ++	 *		32  start of &original stack ++	 */ ++	"	pdec	sp, 32(sp); reserve stack space			\n\t" ++	"	move.4	0(sp), d1 ; exec_map_addr			\n\t" ++	"	move.4	4(sp), d2 ; interp_map_addr			\n\t" ++	"	move.4	8(sp), d3; dynamic_addr				\n\t" ++ ++	/* ++	 * Load linker version of .Lcall in to d0 ++	 */ ++	"	moveai	a3, #%hi(.Lcall)				\n\t" ++	"	lea.1	d0, %lo(.Lcall)(a3)				\n\t" ++ ++	/* ++	 * Determine the offset from loaded .Lcall and put it in d0. ++	 */ ++	"	sub.4 d0, a5, d0					\n\t" ++ ++	/* ++	 * Load linker version of __ROFIXUP_LIST__ and __ROFIXUP_END__ in to d1 ++	 * and d2. ++	 */ ++	"	moveai	a3, #%hi(__ROFIXUP_LIST__)			\n\t" ++	"	lea.1	d1, %lo(__ROFIXUP_LIST__)(a3)			\n\t" ++	"	moveai	a3, #%hi(__ROFIXUP_END__)			\n\t" ++	"	lea.1	d2, %lo(__ROFIXUP_END__)(a3)			\n\t" ++	/* ++	 * Use offset determined above to find the loaded versions. ++	 */ ++	"	add.4	d1, d1, d0					\n\t" ++	"	add.4	d2, d2, d0					\n\t" ++ ++	/* ++	 * Load interp_map_addr into d0, if interp_map_addr is null use ++	 * exec_map_addr. ++	 */ ++	"	move.4	d0, 4(sp) ; load interp_map_addr	       	\n\t" ++	"	cmpi	d0, #0						\n\t" ++	"	jmpne.f	1f						\n\t" ++	"	move.4	d0, 0(sp) ; load exec_map_addr			\n\t" ++ ++	/* ++	 * call __self_reloc(map, void ***p, void ***e) ++	 * it returns the the GOT in d0. ++	 */ ++	"1:	call	a5, __self_reloc ; returns a0 in d0		\n\t" ++	"	move.4	a0, d0 ; set GOT				\n\t" ++	"	move.4	a2, d0 ; save GOT				\n\t" ++ ++	/* ++	 * now setup to call ++	 * _dl_start (Elf32_Addr dl_boot_got_pointer,		(d0) ++	 *	struct elf32_fdpic_loadmap *dl_boot_progmap,	(d1) ++	 *	struct elf32_fdpic_loadmap *dl_boot_ldsomap,	(d2) ++	 *	Elf32_Dyn *dl_boot_ldso_dyn_pointer,		(d3) ++	 *	struct funcdesc_value *dl_main_funcdesc,	(d4) ++	 *	unsigned long args				(d5) ++	 * ++	 * NOTE: for dl_main_funcdesc we reserved space on the stack for this ++	 * structure. ++	 */ ++	"	move.4	d1, 0(sp)	; d1 = exec_map_addr		\n\t" ++	"	move.4	d2, 4(sp)	; d2 = interp_map_addr		\n\t" ++	"	move.4	d3, 8(sp)	; d3 = dynamic_addr		\n\t" ++	"	lea.1	d4, 16(sp)	; d4 = &dl_main_funcdesc	\n\t" ++	"	lea.1	d5, 32(sp)	; d5 = original stack ptr (args)\n\t" ++	"	call	a5, _dl_start					\n\t" ++ ++	/* ++	 * Setup to call the main entry point, starting with passing our FINI ++	 * ptr() to the user in a1 (remember we saved the got in a2) ++	 */ ++	"	movei	d15, #%got_funcdesc_lo(_dl_fini)		\n\t" ++	"	move.4	a1, (a2, d15)					\n\t" ++ ++	/* ++	 * restore the load map from the kernel. ++	 */ ++	"	move.4	d1, 0(sp)	; restore exec_map_addr		\n\t" ++	"	move.4	d2, 4(sp)	; restore interp_map_addr	\n\t" ++	"	move.4	d3, 8(sp)	; restore dynamic_addr		\n\t" ++ ++	/* ++	 * _dl_start returned the main apps entry point in dl_main_funcdesc, ++	 * load that information now. ++	 */ ++	"	move.4	a5, 16(sp) ; a5 = dl_main_funcdesc.entry_point	\n\t" ++	"	move.4	a0, 20(sp) ; a0 = dl_main_funcdesc.got_value	\n\t" ++	"	lea.1	sp, 32(sp); restore original stack ptr (args)	\n\t" ++	"	calli	a5, 0(a5)					\n\t" ++	"	bkpt	-1; should never get here			\n\t" ++	"	.size	_start, . - _start				\n\t" ++); ++ ++#undef DL_START ++#define DL_START(X)   \ ++static void  __attribute__ ((used)) \ ++_dl_start (Elf32_Addr dl_boot_got_pointer, \ ++	   struct elf32_fdpic_loadmap *dl_boot_progmap, \ ++	   struct elf32_fdpic_loadmap *dl_boot_ldsomap, \ ++	   Elf32_Dyn *dl_boot_ldso_dyn_pointer, \ ++	   struct funcdesc_value *dl_main_funcdesc, \ ++	   X) ++ ++struct elf32_fdpic_loadmap; ++ ++/* ++ * Get a pointer to the argv array.  On many platforms this can be just ++ * the address if the first argument, on other platforms we need to ++ * do something a little more subtle here. ++ */ ++#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS) + 1) ++ ++/* ++ * Here is a macro to perform a relocation.  This is only used when ++ * bootstrapping the dynamic loader.  RELP is the relocation that we ++ * are performing, REL is the pointer to the address we are relocating. ++ * SYMBOL is the symbol involved in the relocation, and LOAD is the ++ * load address. ++ */ ++#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ ++	switch(ELF32_R_TYPE((RELP)->r_info)){				\ ++	case R_UBICOM32_32:						\ ++	  *(REL) += (SYMBOL);						\ ++	  break;							\ ++	case R_UBICOM32_FUNCDESC_VALUE:					\ ++	  {								\ ++	    struct funcdesc_value fv = {				\ ++	      (void*)((SYMBOL) + *(REL)),				\ ++	      (LOAD).got_value						\ ++	    };								\ ++	    *(struct funcdesc_value volatile *)(REL) = fv;		\ ++	    break;							\ ++	  }								\ ++	default:							\ ++	  _dl_exit(1);							\ ++	} ++ ++/* ++ * Transfer control to the user's application, once the dynamic loader ++ * is done.  We return the address of the function's entry point to ++ * _dl_boot, see boot1_arch.h. ++ */ ++#define START()	do {							\ ++  struct elf_resolve *exec_mod = _dl_loaded_modules;			\ ++  dl_main_funcdesc->entry_point = _dl_elf_main;				\ ++  while (exec_mod->libtype != elf_executable)				\ ++    exec_mod = exec_mod->next;						\ ++  dl_main_funcdesc->got_value = exec_mod->loadaddr.got_value;		\ ++  return;								\ ++} while (0) +--- /dev/null ++++ b/ldso/ldso/ubicom32/dl-syscalls.h +@@ -0,0 +1,206 @@ ++/* Copyright (C) 2003, 2004 Red Hat, Inc. ++   Contributed by Alexandre Oliva <aoliva@redhat.com> ++ ++This file is part of uClibc. ++ ++uClibc 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. ++ ++uClibc 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 Lesser General Public ++License along with uClibc; see the file COPYING.LIB.  If not, write to ++the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, ++USA.  */ ++ ++/* We can't use the real errno in ldso, since it has not yet ++ * been dynamicly linked in yet. */ ++#include "sys/syscall.h" ++extern int _dl_errno; ++#undef __set_errno ++#define __set_errno(X) {(_dl_errno) = (X);} ++#include <sys/mman.h> ++ ++/* The code below is extracted from libc/sysdeps/linux/frv/_mmap.c */ ++ ++#if defined(DYNAMIC_LOADER_IN_SIMULATOR) && DYNAMIC_LOADER_IN_SIMULATOR ++#define __NR___syscall_mmap2	    __NR_mmap2 ++static __inline__ _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, ++	size_t, len, int, prot, int, flags, int, fd, off_t, offset); ++ ++/* Make sure we don't get another definition of _dl_mmap from the ++   machine-independent code.  */ ++#undef __NR_mmap ++#undef __NR_mmap2 ++ ++/* This is always 12, even on architectures where PAGE_SHIFT != 12.  */ ++# ifndef MMAP2_PAGE_SHIFT ++#  define MMAP2_PAGE_SHIFT 12 ++# endif ++ ++#include <bits/uClibc_page.h> /* for PAGE_SIZE */ ++static __always_inline void *_dl_memset(void*,int,size_t); ++static __always_inline ssize_t _dl_pread(int fd, void *buf, size_t count, off_t offset); ++ ++static __ptr_t ++_dl_mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset) ++{ ++  size_t plen = (len + PAGE_SIZE - 1) & -PAGE_SIZE; ++ ++/* This is a hack to enable the dynamic loader to run within a ++   simulator that doesn't support mmap, with a number of very ugly ++   tricks.  Also, it's not as useful as it sounds, since only dynamic ++   executables without DT_NEEDED dependencies can be run.  AFAIK, they ++   can only be created with -pie.  This trick suffices to enable the ++   dynamic loader to obtain a blank page that it maps early in the ++   bootstrap. */ ++  if ((flags & MAP_FIXED) == 0) ++    { ++      void *_dl_mmap_base = 0; ++      __ptr_t *ret = 0; ++ ++      if (! _dl_mmap_base) ++	{ ++	  void *stack; ++	  __asm__ ("mov sp, %0" : "=r" (stack)); ++	  _dl_mmap_base = (void *)(((long)stack + 2 * PAGE_SIZE) & -PAGE_SIZE); ++	retry: ++	  if (((void **)_dl_mmap_base)[0] == _dl_mmap_base ++	      && ((void **)_dl_mmap_base)[1023] == _dl_mmap_base ++	      && (((void **)_dl_mmap_base)[177] ++		  == ((void **)_dl_mmap_base)[771])) ++	    { ++	      while (((void**)_dl_mmap_base)[177]) ++		{ ++		  _dl_mmap_base = ((void**)_dl_mmap_base)[177]; ++		  if (!(((void **)_dl_mmap_base)[0] == _dl_mmap_base ++			&& ((void **)_dl_mmap_base)[1023] == _dl_mmap_base ++			&& (((void **)_dl_mmap_base)[177] ++			    == ((void**)_dl_mmap_base)[771]))) ++		    ((void(*)())0)(); ++		} ++	    } ++	  else ++	    { ++	      int i; ++	      for (i = 0; i < (int)PAGE_SIZE; i++) ++		if (*(char*)(_dl_mmap_base + i)) ++		  break; ++	      if (i != PAGE_SIZE) ++		{ ++		  _dl_mmap_base = (void*)((long)_dl_mmap_base + PAGE_SIZE); ++		  goto retry; ++		} ++	      ((void**)_dl_mmap_base)[-1] = ++		((void**)_dl_mmap_base)[0] = ++		((void**)_dl_mmap_base)[1023] = ++		_dl_mmap_base; ++	    } ++	} ++ ++      if (_dl_mmap_base) ++	{ ++	  if (!(((void **)_dl_mmap_base)[0] == _dl_mmap_base ++		&& ((void **)_dl_mmap_base)[1023] == _dl_mmap_base ++		&& (((void **)_dl_mmap_base)[177] ++		    == ((void**)_dl_mmap_base)[771]))) ++	    ((void(*)())0)(); ++	  ret = (__ptr_t)((char*)_dl_mmap_base + PAGE_SIZE); ++	  _dl_mmap_base = ++	    ((void**)_dl_mmap_base)[177] = ++	    ((void**)_dl_mmap_base)[771] = ++	    (char*)_dl_mmap_base + plen + PAGE_SIZE; ++	  ((void**)_dl_mmap_base)[0] = ++	    ((void**)_dl_mmap_base)[1023] = ++	    _dl_mmap_base; ++	} ++ ++      if ((flags & MAP_ANONYMOUS) != 0) ++	{ ++	  _dl_memset (ret, 0, plen); ++	  return ret; ++	} ++ ++      flags |= MAP_FIXED; ++      addr = ret; ++    } ++    if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1)) { ++#if 0 ++	__set_errno (EINVAL); ++#endif ++	return MAP_FAILED; ++    } ++    if ((flags & MAP_FIXED) != 0) ++      { ++	if (_dl_pread(fd, addr, len, offset) != (ssize_t)len) ++	  return (void*)MAP_FAILED; ++	if (plen != len) ++	  _dl_memset (addr + len, 0, plen - len); ++	return addr; ++      } ++    return(__syscall_mmap2(addr, len, prot, flags, fd, (off_t) (offset >> MMAP2_PAGE_SHIFT))); ++} ++#endif ++ ++#ifdef __NR_pread64 ++#ifdef DYNAMIC_LOADER_IN_SIMULATOR ++#include <unistd.h> ++ ++#define __NR___syscall_lseek __NR_lseek ++static __always_inline unsigned long _dl_read(int fd, const void *buf, unsigned long count); ++ ++static __always_inline _syscall3(__off_t, __syscall_lseek, int, fd, __off_t, offset, ++			int, whence); ++static __always_inline ssize_t ++_dl_pread(int fd, void *buf, size_t count, off_t offset) ++{ ++  __off_t orig = __syscall_lseek (fd, 0, SEEK_CUR); ++  ssize_t ret; ++ ++  if (orig == -1) ++    return -1; ++ ++  if (__syscall_lseek (fd, offset, SEEK_SET) != offset) ++    return -1; ++ ++  ret = _dl_read (fd, buf, count); ++ ++  if (__syscall_lseek (fd, orig, SEEK_SET) != orig) ++    ((void(*)())0)(); ++ ++  return ret; ++} ++#else ++#define __NR___syscall_pread __NR_pread64 ++static __always_inline _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf, ++			size_t, count, off_t, offset_hi, off_t, offset_lo); ++ ++static __always_inline ssize_t ++_dl_pread(int fd, void *buf, size_t count, off_t offset) ++{ ++  return(__syscall_pread(fd,buf,count,__LONG_LONG_PAIR (offset >> 31, offset))); ++} ++#endif ++#endif ++ ++#ifdef __NR_sram_alloc ++#define __NR__dl_sram_alloc __NR_sram_alloc ++static __always_inline _syscall2(__ptr_t, _dl_sram_alloc, ++			size_t, len, unsigned long, flags); ++#endif ++ ++#ifdef __NR_sram_free ++#define __NR__dl_sram_free __NR_sram_free ++static __always_inline _syscall1(int, _dl_sram_free, __ptr_t, addr); ++#endif ++ ++#ifdef __NR_dma_memcpy ++#define __NR__dl_dma_memcpy __NR_dma_memcpy ++static __always_inline _syscall3(__ptr_t, _dl_dma_memcpy, ++			__ptr_t, dest, __ptr_t, src, size_t, len); ++#endif +--- /dev/null ++++ b/ldso/ldso/ubicom32/dl-sysdep.h +@@ -0,0 +1,243 @@ ++     /* Copyright (C) 2003, 2004 Red Hat, Inc. ++	Contributed by Alexandre Oliva <aoliva@redhat.com> ++	Based on ../i386/dl-sysdep.h ++ ++This file is part of uClibc. ++ ++uClibc 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. ++ ++uClibc 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 Lesser General Public ++License along with uClibc; see the file COPYING.LIB.  If not, write to ++the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, ++USA.  */ ++ ++/* ++ * Various assembly language/system dependent  hacks that are required ++ * so that we can minimize the amount of platform specific code. ++ */ ++ ++/* ++ * Define this if the system uses RELOCA. ++ */ ++#undef ELF_USES_RELOCA ++ ++/* JMPREL relocs are inside the DT_RELA table.  */ ++#define ELF_MACHINE_PLTREL_OVERLAP ++ ++#define DL_NO_COPY_RELOCS ++ ++#define HAVE_DL_INLINES_H ++ ++/* ++ * Initialization sequence for a GOT.  Copy the resolver function ++ * descriptor and the pointer to the elf_resolve/link_map data ++ * structure.  Initialize the got_value in the module while at that. ++ */ ++#define INIT_GOT(GOT_BASE,MODULE) \ ++{				\ ++  (MODULE)->loadaddr.got_value = (GOT_BASE); \ ++  GOT_BASE[0] = ((unsigned long *)&_dl_linux_resolve)[0]; \ ++  GOT_BASE[1] = ((unsigned long *)&_dl_linux_resolve)[1]; \ ++  GOT_BASE[2] = (unsigned long) MODULE; \ ++} ++ ++/* Here we define the magic numbers that this dynamic loader should accept */ ++#define MAGIC1 EM_UBICOM32 ++#undef  MAGIC2 ++ ++/* Used for error messages */ ++#define ELF_TARGET "UBICOM32" ++ ++struct elf_resolve; ++ ++struct funcdesc_value ++{ ++  void *entry_point; ++  void *got_value; ++/*int  relocation; not sure if this required, but it does exist */ ++}; ++ ++extern int _dl_linux_resolve(void) __attribute__((__visibility__("hidden"))); ++extern struct funcdesc_value volatile *__attribute__((__visibility__("hidden"))) ++	_dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry); ++ ++/* 4KiB page alignment.  Should perhaps be made dynamic using ++   getpagesize(), based on AT_PAGESZ from auxvt?  */ ++#define PAGE_ALIGN 0xfffff000 ++#define ADDR_ALIGN 0xfff ++#define OFFS_ALIGN 0x7ffff000 ++ ++struct funcdesc_ht; ++ ++/* ++ * This asm does a quick relcation of string S (which is stored in the text ++ * section as thats all we can use ++ */ ++#undef SEND_EARLY_STDERR ++#define SEND_EARLY_STDERR(S)						\ ++do {									\ ++	static const char __attribute__((section(".text"))) __s[] = (S); \ ++	const char *__p, *__scratch;					\ ++	__asm__ (							\ ++	"	call a3, 1f;				\n\t"		\ ++	"1:	movei	%0, #%%got_lo(1b)		\n\t"		\ ++	"	move.4	%0, (%3, %0)			\n\t"		\ ++	"	sub.4	%1, a3, %0;			\n\t"		\ ++	"	add.4	%1, %1, %2;			\n\t"		\ ++	: "=&d" (__scratch), "=&d" (__p)				\ ++	: "d" (__s), "a" (dl_boot_got_pointer)				\ ++	: "a3", "a4", "d15");						\ ++	SEND_STDERR (__p);						\ ++	{	int __t;						\ ++		for (__t = 0; __t < 0x100000; __t++) __asm__ __volatile__ (""); } \ ++} while (0) ++ ++#define DL_LOADADDR_TYPE struct elf32_fdpic_loadaddr ++ ++#define DL_RELOC_ADDR(LOADADDR, ADDR) \ ++    ((ElfW(Addr))__reloc_pointer ((void*)(ADDR), (LOADADDR).map)) ++ ++#define DL_ADDR_TO_FUNC_PTR(ADDR, LOADADDR) \ ++  ((void(*)(void)) _dl_funcdesc_for ((void*)(ADDR), (LOADADDR).got_value)) ++ ++#define _dl_stabilize_funcdesc(val) \ ++  ({ __asm__ ("" : "+m" (*(val))); (val); }) ++ ++#define DL_CALL_FUNC_AT_ADDR(ADDR, LOADADDR, SIGNATURE, ...) \ ++  ({ struct funcdesc_value fd = { (void*)(ADDR), (LOADADDR).got_value }; \ ++     void (*pf)(void) = (void*) _dl_stabilize_funcdesc (&fd); \ ++     (* SIGNATURE pf)(__VA_ARGS__); }) ++ ++#define DL_INIT_LOADADDR_BOOT(LOADADDR, BASEADDR) \ ++  (__dl_init_loadaddr_map (&(LOADADDR), dl_boot_got_pointer, \ ++			   dl_boot_ldsomap ?: dl_boot_progmap)) ++ ++#define DL_INIT_LOADADDR_PROG(LOADADDR, BASEADDR) \ ++  (__dl_init_loadaddr_map (&(LOADADDR), 0, dl_boot_progmap)) ++ ++#define DL_INIT_LOADADDR_EXTRA_DECLS \ ++  int dl_init_loadaddr_load_count; ++#define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \ ++  (dl_init_loadaddr_load_count = \ ++     __dl_init_loadaddr (&(LOADADDR), (PHDR), (PHDRCNT))) ++#define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \ ++  (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \ ++			   dl_init_loadaddr_load_count)) ++#define DL_LOADADDR_UNMAP(LOADADDR, LEN) \ ++  (__dl_loadaddr_unmap ((LOADADDR), (NULL))) ++#define DL_LIB_UNMAP(LIB, LEN) \ ++  (__dl_loadaddr_unmap ((LIB)->loadaddr, (LIB)->funcdesc_ht)) ++#define DL_LOADADDR_BASE(LOADADDR) \ ++  ((LOADADDR).got_value) ++ ++/* This is called from dladdr(), such that we map a function ++   descriptor's address to the function's entry point before trying to ++   find in which library it's defined.  */ ++#define DL_LOOKUP_ADDRESS(ADDRESS) (_dl_lookup_address (ADDRESS)) ++ ++#define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \ ++  (! (TFROM) && __dl_addr_in_loadaddr ((void*)(ADDR), (TPNT)->loadaddr)) ++ ++/* ++ * Compute the GOT address.  On several platforms, we use assembly ++ * here.  on FR-V FDPIC, there's no way to compute the GOT address, ++ * since the offset between text and data is not fixed, so we arrange ++ * for the assembly _dl_boot to pass this value as an argument to ++ * _dl_boot.  */ ++#define DL_BOOT_COMPUTE_GOT(got) ((got) = dl_boot_got_pointer) ++ ++#define DL_BOOT_COMPUTE_DYN(dpnt, got, load_addr) \ ++  ((dpnt) = dl_boot_ldso_dyn_pointer) ++ ++/* We only support loading FDPIC independently-relocatable shared ++   libraries.  It probably wouldn't be too hard to support loading ++   shared libraries that require relocation by the same amount, but we ++   don't know that they exist or would be useful, and the dynamic ++   loader code could leak the whole-library map unless we keeping a ++   bit more state for DL_LOADADDR_UNMAP and DL_LIB_UNMAP, so let's ++   keep things simple for now.  */ ++#define DL_CHECK_LIB_TYPE(epnt, piclib, _dl_progname, libname) \ ++do \ ++{ \ ++  if (((epnt)->e_flags & EF_UBICOM32_FDPIC) && ! ((epnt)->e_flags & EF_UBICOM32_PIC)) \ ++    (piclib) = 2; \ ++  else \ ++    { \ ++      _dl_internal_error_number = LD_ERROR_NOTDYN; \ ++      _dl_dprintf(2, "%s: '%s' is not an FDPIC shared library" \ ++		  "\n", (_dl_progname), (libname)); \ ++      _dl_close(infile); \ ++      return NULL; \ ++    } \ ++\ ++} \ ++while (0) ++ ++/* We want want to apply all relocations in the interpreter during ++   bootstrap.  Because of this, we have to skip the interpreter ++   relocations in _dl_parse_relocation_information(), see ++   elfinterp.c.  */ ++#define DL_SKIP_BOOTSTRAP_RELOC(SYMTAB, INDEX, STRTAB) 0 ++ ++#ifdef __NR_pread64 ++#define _DL_PREAD(FD, BUF, SIZE, OFFSET) \ ++  (_dl_pread((FD), (BUF), (SIZE), (OFFSET))) ++#endif ++ ++/* We want to return to dlsym() a function descriptor if the symbol ++   turns out to be a function.  */ ++#define DL_FIND_HASH_VALUE(TPNT, TYPE_CLASS, SYM) \ ++  (((TYPE_CLASS) & ELF_RTYPE_CLASS_DLSYM) \ ++   && ELF32_ST_TYPE((SYM)->st_info) == STT_FUNC \ ++   ? _dl_funcdesc_for ((void *)DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value), \ ++		       (TPNT)->loadaddr.got_value)			     \ ++   : DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value)) ++ ++#if 0 /* XXX TODO will look at enabling this if we decide to add support for OCM ++       * code/data */ ++ ++#define DL_IS_SPECIAL_SEGMENT(EPNT, PPNT) \ ++  __dl_is_special_segment(EPNT, PPNT) ++#define DL_MAP_SEGMENT(EPNT, PPNT, INFILE, FLAGS) \ ++  __dl_map_segment (EPNT, PPNT, INFILE, FLAGS) ++ ++#endif ++ ++ ++#define DL_GET_READY_TO_RUN_EXTRA_PARMS \ ++    , struct elf32_fdpic_loadmap *dl_boot_progmap, Elf32_Addr dl_boot_got_pointer ++#define DL_GET_READY_TO_RUN_EXTRA_ARGS \ ++    , dl_boot_progmap, dl_boot_got_pointer ++ ++ ++#ifdef __USE_GNU ++# include <link.h> ++#else ++# define __USE_GNU ++# include <link.h> ++# undef __USE_GNU ++#endif ++ ++#include <elf.h> ++static __inline__ void ++elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr, ++		      Elf32_Word relative_count) ++{ ++#if 0 ++	 Elf32_Rel * rpnt = (void *) rel_addr; ++	--rpnt; ++	do { ++		Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset); ++ ++		*reloc_addr = DL_RELOC_ADDR (load_off, *reloc_addr); ++	} while (--relative_count); ++#endif ++} +--- /dev/null ++++ b/ldso/ldso/ubicom32/elfinterp.c +@@ -0,0 +1,366 @@ ++/* Blackfin ELF shared library loader suppport ++   Copyright (C) 2003, 2004 Red Hat, Inc. ++   Contributed by Alexandre Oliva <aoliva@redhat.com> ++   Lots of code copied from ../i386/elfinterp.c, so: ++   Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, ++				David Engel, Hongjiu Lu and Mitch D'Souza ++   Copyright (C) 2001-2002, Erik Andersen ++   All rights reserved. ++ ++This file is part of uClibc. ++ ++uClibc 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. ++ ++uClibc 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 Lesser General Public ++License along with uClibc; see the file COPYING.LIB.  If not, write to ++the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, ++USA.  */ ++ ++#include <sys/cdefs.h>	    /* __attribute_used__ */ ++ ++/* Program to load an ELF binary on a linux system, and run it. ++   References to symbols in sharable libraries can be resolved by either ++   an ELF sharable library or a linux style of shared library. */ ++ ++/* Disclaimer:  I have never seen any AT&T source code for SVr4, nor have ++   I ever taken any courses on internals.  This program was developed using ++   information available through the book "UNIX SYSTEM V RELEASE 4, ++   Programmers guide: Ansi C and Programming Support Tools", which did ++   a more than adequate job of explaining everything required to get this ++   working. */ ++extern int _dl_ubicom32_resolve_pending(void) __attribute__((__visibility__("hidden"))); ++ ++struct funcdesc_value volatile *__attribute__((__visibility__("hidden"))) ++_dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) ++{ ++	int reloc_type; ++	ELF_RELOC *this_reloc; ++	char *strtab; ++	ElfW(Sym) *symtab; ++	int symtab_index; ++	char *rel_addr; ++	struct elf_resolve *new_tpnt; ++	char *new_addr; ++	struct funcdesc_value funcval; ++	struct funcdesc_value volatile *got_entry; ++	char *symname; ++ ++	rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL]; ++ ++	this_reloc = (ELF_RELOC *)(intptr_t)(rel_addr + reloc_entry); ++	reloc_type = ELF_R_TYPE(this_reloc->r_info); ++	symtab_index = ELF_R_SYM(this_reloc->r_info); ++ ++	symtab = (Elf32_Sym *) tpnt->dynamic_info[DT_SYMTAB]; ++	strtab = (char *) tpnt->dynamic_info[DT_STRTAB]; ++	symname= strtab + symtab[symtab_index].st_name; ++ ++	if (reloc_type != R_UBICOM32_FUNCDESC_VALUE) { ++		_dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n", ++			    _dl_progname); ++		_dl_exit(1); ++	} ++ ++	/* Address of GOT entry fix up */ ++	got_entry = (struct funcdesc_value *) DL_RELOC_ADDR(tpnt->loadaddr, this_reloc->r_offset); ++ ++	/* Get the address to be used to fill in the GOT entry.  */ ++	new_addr = _dl_lookup_hash(symname, tpnt->symbol_scope, NULL, 0, &new_tpnt); ++	if (!new_addr) { ++		new_addr = _dl_lookup_hash(symname, NULL, NULL, 0, &new_tpnt); ++		if (!new_addr) { ++			_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", ++				    _dl_progname, symname); ++			_dl_exit(1); ++		} ++	} ++ ++	funcval.entry_point = new_addr; ++	funcval.got_value = new_tpnt->loadaddr.got_value; ++ ++#if defined (__SUPPORT_LD_DEBUG__) ++	if (_dl_debug_bindings) { ++		_dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname); ++		if (_dl_debug_detail) ++			_dl_dprintf(_dl_debug_file, ++				    "\n\tpatched (%x,%x) ==> (%x,%x) @ %x\n", ++				    got_entry->entry_point, got_entry->got_value, ++				    funcval.entry_point, funcval.got_value, ++				    got_entry); ++	} ++	if (1 || !_dl_debug_nofixups) { ++		got_entry->entry_point = ((unsigned long *)&_dl_ubicom32_resolve_pending)[0]; ++		got_entry->got_value = funcval.got_value; ++		got_entry->entry_point = funcval.entry_point; ++	} ++#else ++	/* ++	 * initially set the entry point to resolve pending before starting ++	 * the update. This has the effect of putting all other requests in a ++	 * holding pattern until the resolution is completed. ++	 */ ++	got_entry->entry_point = ((unsigned long *)&_dl_ubicom32_resolve_pending)[0]; ++	got_entry->got_value = funcval.got_value; ++	got_entry->entry_point = funcval.entry_point; ++#endif ++ ++	return got_entry; ++} ++ ++static int ++_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, ++	  unsigned long rel_addr, unsigned long rel_size, ++	  int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope, ++			    ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)) ++{ ++	unsigned int i; ++	char *strtab; ++	ElfW(Sym) *symtab; ++	ELF_RELOC *rpnt; ++	int symtab_index; ++ ++	/* Now parse the relocation information */ ++	rpnt = (ELF_RELOC *) rel_addr; ++	rel_size = rel_size / sizeof(ELF_RELOC); ++ ++	symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB]; ++	strtab = (char *) tpnt->dynamic_info[DT_STRTAB]; ++ ++	for (i = 0; i < rel_size; i++, rpnt++) { ++		int res; ++ ++		symtab_index = ELF_R_SYM(rpnt->r_info); ++		debug_sym(symtab,strtab,symtab_index); ++		debug_reloc(symtab,strtab,rpnt); ++ ++		res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab); ++ ++		if (res==0) continue; ++ ++		_dl_dprintf(2, "\n%s: ",_dl_progname); ++ ++		if (symtab_index) ++			_dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name); ++ ++		if (res <0) { ++			int reloc_type = ELF_R_TYPE(rpnt->r_info); ++#if defined (__SUPPORT_LD_DEBUG__) ++			_dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type)); ++#else ++			_dl_dprintf(2, "can't handle reloc type %x\n", reloc_type); ++#endif ++			_dl_exit(-res); ++		} else if (res >0) { ++			_dl_dprintf(2, "can't resolve symbol\n"); ++			return res; ++		} ++	  } ++	  return 0; ++} ++ ++static int ++_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, ++	      ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) ++{ ++	int reloc_type; ++	int symtab_index; ++	char *symname; ++	unsigned long reloc_value = 0, *reloc_addr; ++	struct { unsigned long v; } __attribute__((__packed__)) ++					    *reloc_addr_packed; ++	unsigned long symbol_addr; ++	struct elf_resolve *symbol_tpnt; ++	struct funcdesc_value funcval; ++#if defined (__SUPPORT_LD_DEBUG__) ++	unsigned long old_val; ++#endif ++ ++	reloc_addr   = (unsigned long *) DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_offset); ++	__asm__ ("" : "=r" (reloc_addr_packed) : "0" (reloc_addr)); ++	reloc_type   = ELF_R_TYPE(rpnt->r_info); ++	symtab_index = ELF_R_SYM(rpnt->r_info); ++	symbol_addr  = 0; ++	symname      = strtab + symtab[symtab_index].st_name; ++ ++	if (ELF_ST_BIND (symtab[symtab_index].st_info) == STB_LOCAL) { ++		symbol_addr = (unsigned long) DL_RELOC_ADDR(tpnt->loadaddr, symtab[symtab_index].st_value); ++		symbol_tpnt = tpnt; ++	} else { ++ ++		symbol_addr = (unsigned long) ++		  _dl_lookup_hash(symname, scope, NULL, 0, &symbol_tpnt); ++ ++		/* ++		 * We want to allow undefined references to weak symbols - this might ++		 * have been intentional.  We should not be linking local symbols ++		 * here, so all bases should be covered. ++		 */ ++ ++		if (!symbol_addr && ELF_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) { ++			_dl_dprintf (2, "%s: can't resolve symbol '%s'\n", ++				     _dl_progname, strtab + symtab[symtab_index].st_name); ++			_dl_exit (1); ++		} ++	} ++ ++#if defined (__SUPPORT_LD_DEBUG__) ++	if (_dl_debug_reloc && _dl_debug_detail) ++	  { ++	    if ((long)reloc_addr_packed & 3) ++	      old_val = reloc_addr_packed->v; ++	    else ++	      old_val = *reloc_addr; ++	  } ++	else ++	  old_val = 0; ++#endif ++	switch (reloc_type) { ++	case R_UBICOM32_NONE: ++		break; ++	case R_UBICOM32_32: ++		if ((long)reloc_addr_packed & 3) ++			reloc_value = reloc_addr_packed->v += symbol_addr; ++		else ++			reloc_value = *reloc_addr += symbol_addr; ++		break; ++	case R_UBICOM32_FUNCDESC_VALUE: ++		funcval.entry_point = (void*)symbol_addr; ++		/* The addend of FUNCDESC_VALUE ++		   relocations referencing global ++		   symbols must be ignored, because it ++		   may hold the address of a lazy PLT ++		   entry.  */ ++		if (ELF_ST_BIND(symtab[symtab_index].st_info) == STB_LOCAL) ++			funcval.entry_point += *reloc_addr; ++		reloc_value = (unsigned long)funcval.entry_point; ++		if (symbol_addr) ++			funcval.got_value ++				= symbol_tpnt->loadaddr.got_value; ++		else ++			funcval.got_value = 0; ++ ++/// XXX this is my best guess as to what I should be doing, but I'm ++/// putting a break-point here so I can inspect the first time this is ++/// used. ++		__asm__ ( ++		"	move.4 4(%0), 4(%1)		\n\t" ++		"	move.4 0(%0), 0(%1)		\n\t" /* Must to entry_point last */ ++			: ++			: "a" (reloc_addr), "a" (&funcval) ++			: "memory" ); ++		break; ++	case R_UBICOM32_FUNCDESC: ++		if ((long)reloc_addr_packed & 3) ++			reloc_value = reloc_addr_packed->v; ++		else ++			reloc_value = *reloc_addr; ++		if (symbol_addr) ++			reloc_value = (unsigned long)_dl_funcdesc_for ++				((char *)symbol_addr + reloc_value, ++				 symbol_tpnt->loadaddr.got_value); ++		else ++			reloc_value = 0; ++		if ((long)reloc_addr_packed & 3) ++			reloc_addr_packed->v = reloc_value; ++		else ++			*reloc_addr = reloc_value; ++		break; ++	default: ++		return -1; ++	} ++#if defined (__SUPPORT_LD_DEBUG__) ++	if (_dl_debug_reloc && _dl_debug_detail) { ++		_dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, reloc_value, reloc_addr); ++		switch (reloc_type) { ++		case R_UBICOM32_FUNCDESC_VALUE: ++			_dl_dprintf(_dl_debug_file, " got %x", ((struct funcdesc_value *)reloc_value)->got_value); ++			break; ++		case R_UBICOM32_FUNCDESC: ++			if (! reloc_value) ++				break; ++			_dl_dprintf(_dl_debug_file, " funcdesc (%x,%x)", ++				    ((struct funcdesc_value *)reloc_value)->entry_point, ++				    ((struct funcdesc_value *)reloc_value)->got_value); ++			break; ++		} ++	} ++#endif ++ ++	return 0; ++} ++ ++static int ++_dl_do_lazy_reloc (struct elf_resolve *tpnt, ++		   struct dyn_elf *scope __attribute__((unused)), ++		   ELF_RELOC *rpnt, ElfW(Sym) *symtab __attribute__((unused)), ++		   char *strtab __attribute__((unused))) ++{ ++	int reloc_type; ++	struct funcdesc_value volatile *reloc_addr; ++	struct funcdesc_value funcval; ++#if defined (__SUPPORT_LD_DEBUG__) ++	unsigned long old_val; ++#endif ++ ++	reloc_addr = (struct funcdesc_value *) DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_offset); ++	reloc_type = ELF_R_TYPE(rpnt->r_info); ++ ++#if defined (__SUPPORT_LD_DEBUG__) ++	old_val = (unsigned long)reloc_addr->entry_point; ++#endif ++		switch (reloc_type) { ++			case R_UBICOM32_NONE: ++				break; ++			case R_UBICOM32_FUNCDESC_VALUE: ++				funcval = *reloc_addr; ++				funcval.entry_point = (void*)DL_RELOC_ADDR(tpnt->loadaddr, funcval.entry_point); ++				funcval.got_value = tpnt->loadaddr.got_value; ++				*reloc_addr = funcval; ++				break; ++			default: ++				return -1; ++		} ++#if defined (__SUPPORT_LD_DEBUG__) ++	if (_dl_debug_reloc && _dl_debug_detail) ++		_dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, reloc_addr->entry_point, reloc_addr); ++#endif ++	return 0; ++ ++} ++ ++void ++_dl_parse_lazy_relocation_information ++(struct dyn_elf *rpnt, unsigned long rel_addr, unsigned long rel_size) ++{ ++  _dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc); ++} ++ ++int ++_dl_parse_relocation_information ++(struct dyn_elf *rpnt, unsigned long rel_addr, unsigned long rel_size) ++{ ++  return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc); ++} ++ ++#if 0 ++/* We don't have copy relocs.  */ ++int ++_dl_parse_copy_information ++(struct dyn_elf *rpnt __attribute__((unused)), ++ unsigned long rel_addr __attribute__((unused)), ++ unsigned long rel_size __attribute__((unused))) ++{ ++  return 0; ++} ++#endif ++#ifndef IS_IN_libdl ++# include "../../libc/sysdeps/linux/ubicom32/crtreloc.c" ++#endif +--- /dev/null ++++ b/ldso/ldso/ubicom32/resolve.S +@@ -0,0 +1,161 @@ ++     /* Copyright (C) 2003 Red Hat, Inc. ++	Contributed by Alexandre Oliva <aoliva@redhat.com> ++ ++	Copyright (C) 2009 Ubicom Inc. ++	Ported to Ubicom32 by Ubicom Inc. ++ ++This file is part of uClibc. ++ ++uClibc 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. ++ ++uClibc 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 Lesser General Public ++License along with uClibc; see the file COPYING.LIB.  If not, write to ++the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, ++USA.  */ ++ ++ ++/* ++ * The function below is tail-called by resolver stubs when a lazily-bound * ++ * function is called.  It must preserve all registers that could * be used to ++ * pass arguments to the actual function. ++ * ++ * On entry to the function d0-d13 contain parameters to the actual function of ++ * interest ++ * ++ * a5 contains the return address ++ * a0 is pointing to the GOT table for the original function ++ *  (a0) _dl_linux_resolve ++ * 4(a0) GOT for _dl_linux_resolve ++ * 8(a0) is pointer to "structure elf_resolve" of the module where the call ++ *	originated from ++ * ++ * a3 is pointing to the function descriptor in the GOT table, and 8(a3) the ++ * resolver lookup information. ++ * ++ * _dl_linux_resolve calls _dl_linux_resolver passing it pointer to ++ * struct elf_resolve and the relocation entry. ++ * ++ * _dl_linux_resolver() figures out where the jump symbol is _really_ supposed ++ * to have jumped to and returns that to us. Once we have that, we prepare to ++ * tail-call the actual function, clean up after ourselves, restoring the ++ * original arguments, then jump to the fixed up address. ++ */ ++ ++#if 0 ++	/* ++	 * Here is what the linker will use for the PLT. ++	 */ ++sample_PLT_functionX:	/* (at entry a0 contains GOT for this library)  */ ++	movei	d15, # -%lo(got_funcdescX) ; load offset for GOT ++	lea.4	a3, (a0, d15)	; a4 is now the function descriptor ++	move.4	a4, 0(a3)	; get entry_point ++	move.4	a0, 4(a3)	; set new GOT ++ ++	/* ++	 * jump to resovled function OR PLT_trampoline Nat had some code here ++	 * that uses the stack instead of a3 to reduces hazards. ++	 */ ++	calli	a4, 0(a4) ++ ++ ++sample_PLT_trampoline: ++	/* ++	 * find the old got by undoing what was done above. An alternative ++	 * could have been to ‘save’ the old got in say d14 but that would add 1 ++	 * instruction to every PLT and there is only 1 PLT trampoline per library. ++	 */ ++	ret	(a0)		; jump to _dl_linux_resolve ++#endif ++ ++	.text ++	.p2align 4 ++ ++	.hidden	_dl_linux_resolve ++	.global	_dl_linux_resolve ++	.type	_dl_linux_resolve,@function ++_dl_linux_resolve: ++	/* Preserve arguments and return address  */ ++	move.4	-4(sp)++, d0 ++	move.4	-4(sp)++, d1 ++	move.4	-4(sp)++, d2 ++	move.4	-4(sp)++, d3 ++	move.4	-4(sp)++, d4 ++	move.4	-4(sp)++, d5 ++	move.4	-4(sp)++, d6 ++	move.4	-4(sp)++, d7 ++	move.4	-4(sp)++, d8 ++	move.4	-4(sp)++, d9 ++	move.4	-4(sp)++, d10 ++	move.4	-4(sp)++, d11 ++	move.4	-4(sp)++, d12 ++	move.4	-4(sp)++, d13 ++	move.4	-4(sp)++, a5 ++ ++	/* Prepare to call _dl_linux_resolver.  */ ++	move.4 d0, 8(a0)	; reference to elf_resolve ++	/* Not aligned for space reasons.  */ ++	move.4 d1, mac_hi 	; reference to GOT table entry which ++				; contains the relocation information. ++ ++	move.4 a0, 4(a0) ; switch to GOT for _dl_linux_resolve ++	call	a5, _dl_linux_resolver; ++ ++	/* Move aside return value that contains the FUNCDESC_VALUE.  */ ++	;P3 = R0; ++	move.4 a3, d0; ++ ++	/* Restore arguments.  */ ++	move.4	a5, (sp)4++ ++	move.4	d13, (sp)4++ ++	move.4	d12, (sp)4++ ++	move.4	d11, (sp)4++ ++	move.4	d10, (sp)4++ ++	move.4	d9, (sp)4++ ++	move.4	d8, (sp)4++ ++	move.4	d7, (sp)4++ ++	move.4	d6, (sp)4++ ++	move.4	d5, (sp)4++ ++	move.4	d4, (sp)4++ ++	move.4	d3, (sp)4++ ++	move.4	d2, (sp)4++ ++	move.4	d1, (sp)4++ ++	move.4	d0, (sp)4++ ++ ++	/* Now jump to the actual function.  */ ++	/* a3 contains func_desc resolution */ ++	move.4 a4, 0(a3)	; address of function X ++	move.4 a0, 4(a3)	; switch to GOT for function X ++	calli  a4, 0(a4)	; call through a4, a5 remains ++ ++	.size	_dl_linux_resolve, . - _dl_linux_resolve ++ ++	.hidden	_dl_ubicom32_resolve_pending ++	.global	_dl_ubicom32_resolve_pending ++	.type	_dl_ubicom32_resolve_pending,@function ++ ++_dl_ubicom32_resolve_pending: ++	/* ++	 * A special function that is used to ensure thread saftly when the fd ++	 * for a particular resolution is being updated. ++	 * ++	 * At entry, a3 must point to the FD.  While the FD is being updated the ++	 * entry_point will continue to point to _dl_ubicom32_resolve_pending so ++	 * we will effectively spin until the resolver update is complete. ++	 */ ++ ++	move.4	a4, 0(a3)	; get entry_point ++	move.4	a0, 4(a3)	; set new GOT ++ ++	/* ++	 * jump to resovled function or back to _dl_ubicom32_resolve_pending. ++	 */ ++	calli	a4, 0(a4) ++	.size	_dl_ubicom32_resolve_pending, . - _dl_ubicom32_resolve_pending +--- a/libc/misc/Makefile.in ++++ b/libc/misc/Makefile.in +@@ -12,7 +12,9 @@ include $(top_srcdir)libc/misc/assert/Ma + include $(top_srcdir)libc/misc/ctype/Makefile.in + include $(top_srcdir)libc/misc/dirent/Makefile.in + include $(top_srcdir)libc/misc/error/Makefile.in ++ifneq ($(ARCH_HAS_NO_LDSO),y) + include $(top_srcdir)libc/misc/elf/Makefile.in ++endif + include $(top_srcdir)libc/misc/file/Makefile.in + include $(top_srcdir)libc/misc/fnmatch/Makefile.in + include $(top_srcdir)libc/misc/ftw/Makefile.in +--- a/libc/misc/elf/dl-iterate-phdr.c ++++ b/libc/misc/elf/dl-iterate-phdr.c +@@ -14,7 +14,7 @@ +  + #include <link.h> + #include <ldso.h> +- ++#include <memory.h> + /* we want this in libc but nowhere else */ + #ifdef __USE_GNU +  +--- a/libc/stdlib/malloc/malloc.c ++++ b/libc/stdlib/malloc/malloc.c +@@ -23,7 +23,7 @@ +  + /* The malloc heap.  We provide a bit of initial static space so that +    programs can do a little mallocing without mmaping in more space.  */ +-HEAP_DECLARE_STATIC_FREE_AREA (initial_fa, 256); ++HEAP_DECLARE_STATIC_FREE_AREA (initial_fa, 32768); + struct heap_free_area *__malloc_heap = HEAP_INIT_WITH_FA (initial_fa); + #ifdef HEAP_USE_LOCKING + malloc_mutex_t __malloc_heap_lock = PTHREAD_MUTEX_INITIALIZER; +--- /dev/null ++++ b/libc/string/ubicom32/Makefile +@@ -0,0 +1,13 @@ ++# Makefile for uClibc ++# ++# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> ++# ++# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. ++# ++ ++top_srcdir:=../../../ ++top_builddir:=../../../ ++all: objs ++include $(top_builddir)Rules.mak ++include ../Makefile.in ++include $(top_srcdir)Makerules +--- /dev/null ++++ b/libc/string/ubicom32/memcpy.c +@@ -0,0 +1,152 @@ ++/* Copy memory to memory until the specified number of bytes ++   has been copied.  Overlap is NOT handled correctly. ++   Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc. ++   This file is part of the GNU C Library. ++   Contributed by Torbjorn Granlund (tege@sics.se). ++ ++   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 <string.h> ++ ++typedef unsigned long addr_t; ++ ++libc_hidden_proto(memcpy) ++ ++void *memcpy (void *dest, const void *src, size_t n) ++{ ++	void *dest_ret = dest; ++	void *aligned_start; ++ ++	if (likely((((addr_t)dest ^ (addr_t)src) & 3) == 0) && likely(n > 6)) { ++		size_t m; ++		n -= (4 - (addr_t)dest) & 0x03; ++		m = n >> 2; ++		__asm__ volatile ( ++		"	call		%4, 99f			\n\t"	// load %4 with address of 99 ++		"99:	movei		d15, #%%lo(1f-99b)	\n\t"	// load d15 with offset to 1 from 99 ++		"	add.4		%4, %4, d15		\n\t"	// add difference ++ ++		"	sub.4		d15, #0, %2		\n\t"	// set up for jump table ++		"	and.4		d15, #(32-1), d15	\n\t"	// d15 = (-m) & (32 - 1) ++		"	lea.4		%4, (%4,d15)		\n\t" ++ ++		"	bfextu		d15, %0, #2		\n\t"	// d15 = (dest & 3) ++		"	jmpne.w.f	100f			\n\t" ++		"	calli		%4, 0(%4)		\n\t"	// 4-byte alignment ++ ++		"100:	cmpi		d15, #2			\n\t" ++		"	jmpne.s.f	101f			\n\t" ++		"	move.2		(%0)2++, (%1)2++	\n\t" ++		"	calli		%4, 0(%4)		\n\t"	// 2-byte alignment ++ ++		"101:	move.1		(%0)1++, (%1)1++	\n\t" ++		"	jmpgt.s.f	102f			\n\t"	// 3-byte alignment ++		"	move.2		(%0)2++, (%1)2++	\n\t"	// 1-byte alignment ++		"102:	calli		%4, 0(%4)		\n\t" ++ ++		"200:	cmpi		%3, #2			\n\t" ++		"	jmplt.s.f	201f			\n\t" ++		"	move.2		(%0)2++, (%1)2++	\n\t" ++		"	jmpeq.s.t	2f			\n\t" ++		"201:	move.1		(%0)1++, (%1)1++	\n\t" ++		"	jmpt.w.t	2f			\n\t" ++ ++		"1:	.rept		25			\n\t" ++		"	movea		(%0)4++, (%1)4++	\n\t" ++		"	.endr					\n\t" ++		"	.rept		7			\n\t" ++		"	move.4		(%0)4++, (%1)4++	\n\t" ++		"	.endr					\n\t" ++		"	add.4		%2, #-32, %2		\n\t" ++		"	jmpgt.w.f	1b			\n\t" ++ ++		"	and.4		%3, #3, %3		\n\t"	// check n ++		"	jmpne.w.f	200b			\n\t" ++		"2:						\n\t" ++			: "+a"(dest), "+a"(src), "+d"(m), "+d"(n), "=a"(aligned_start) ++			: ++			: "d15", "memory", "cc" ++		); ++ ++		return dest_ret; ++	} ++ ++	if (likely((((addr_t)dest ^ (addr_t)src) & 1) == 0) && likely(n > 2)) { ++		size_t m; ++		n -= (addr_t)dest & 0x01; ++		m = n >> 1; ++		__asm__ volatile ( ++		"	call		%4, 99f			\n\t"	// load %4 with address of 99 ++		"99:	movei		d15, #%%lo(1f-99b)	\n\t"	// load d15 with offset to 1 from 99 ++		"	add.4		%4, %4, d15		\n\t"	// add difference ++ ++		"	sub.4		d15, #0, %2		\n\t"	// set up for jump table ++		"	and.4		d15, #(32-1), d15	\n\t"	// d15 = (-m) & (32 - 1) ++		"	lea.4		%4, (%4,d15)		\n\t" ++ ++		"	btst		%0, #0			\n\t"	// check bit 0 ++		"	jmpne.w.f	100f			\n\t" ++		"	calli		%4, 0(%4)		\n\t"	// 4-byte alignment ++ ++		"100:	move.1		(%0)1++, (%1)1++	\n\t" ++		"	calli		%4, 0(%4)		\n\t" ++ ++		"200:	move.1		(%0)1++, (%1)1++	\n\t" ++		"	jmpt.w.t	2f			\n\t" ++ ++		"1:	.rept		32			\n\t" ++		"	move.2		(%0)2++, (%1)2++	\n\t" ++		"	.endr					\n\t" ++		"	add.4		%2, #-32, %2		\n\t" ++		"	jmpgt.w.f	1b			\n\t" ++ ++		"	and.4		%3, #1, %3		\n\t"	// check n ++		"	jmpne.w.f	200b			\n\t" ++		"2:						\n\t" ++ ++			: "+a"(dest), "+a"(src), "+d"(m), "+d"(n), "=a"(aligned_start) ++			: ++			: "d15", "memory", "cc" ++		); ++		return dest_ret; ++	} ++ ++	__asm__ volatile ( ++	"	call		%3, 99f			\n\t"	// load %3 with address of 99 ++	"99:	movei		d15, #%%lo(1f-99b)	\n\t"	// load d15 with offset to 1 from 99 ++	"	add.4		%3, %3, d15		\n\t"	// add difference ++ ++	"	sub.4		d15, #0, %2		\n\t" ++	"	jmpeq.w.f	2f			\n\t" ++	"	and.4		d15, #(16-1), d15	\n\t"	// d15 = (-n) & (16 - 1) ++	"	lea.4		%3, (%3,d15)		\n\t" ++	"	calli		%3, 0(%3)		\n\t" ++ ++	"1:	.rept		16			\n\t" ++	"	move.1		(%0)1++, (%1)1++	\n\t" ++	"	.endr					\n\t" ++	"	add.4		%2, #-16, %2		\n\t" ++	"	jmpgt.w.f	1b			\n\t" ++	"2:						\n\t" ++ ++		: "+a"(dest), "+a"(src), "+d"(n), "=a"(aligned_start) ++		: ++		: "d15", "memory", "cc" ++	); ++ ++	return dest_ret; ++} ++libc_hidden_def(memcpy) +--- /dev/null ++++ b/libc/string/ubicom32/memset.c +@@ -0,0 +1,107 @@ ++/* Copyright (C) 1991, 1997, 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 <string.h> ++ ++typedef unsigned long addr_t; ++ ++libc_hidden_proto(memset) ++void *memset (void *s, int c, size_t n) ++{ ++	void *s_ret = s; ++	void *aligned_start; ++	if (likely(n > 6)) { ++		size_t m; ++		n -= (4 - (addr_t)s) & 0x03; ++		m = n >> 2; ++		__asm__ volatile ( ++		"	call		%4, 99f			\n\t"	// load %4 with address of 99 ++		"99:	movei		d15, #%%lo(1f-99b)	\n\t"	// load d15 with offset to 1 from 99 ++		"	add.4		%4, %4, d15		\n\t"	// add difference ++ ++		"	sub.4		d15, #0, %2		\n\t"	// set up for jump table ++		"	and.4		d15, #(32-1), d15	\n\t"	// d15 = (-m) & (32 - 1) ++		"	shmrg.1		%1, %1, %1		\n\t" ++		"	shmrg.2		%1, %1, %1		\n\t"	// %1 = (c<<24)|(c<<16)|(c<<8)|c ++		"	lea.4		%4, (%4,d15)		\n\t" ++ ++		"	bfextu		d15, %0, #2		\n\t"	// d15 = (s & 3) ++		"	jmpne.w.f	100f			\n\t" ++		"	calli		%4, 0(%4)		\n\t"	// 4-byte alignment ++ ++		"100:	cmpi		d15, #2			\n\t" ++		"	jmpne.s.f	101f			\n\t" ++		"	move.2		(%0)2++, %1		\n\t" ++		"	calli		%4, 0(%4)		\n\t"	// 2-byte alignment ++ ++		"101:	move.1		(%0)1++, %1		\n\t" ++		"	jmpgt.s.f	102f			\n\t"	// 3-byte alignment ++		"	move.2		(%0)2++, %1		\n\t"	// 1-byte alignment ++		"102:	calli		%4, 0(%4)		\n\t" ++ ++		"200:	cmpi		%3, #2			\n\t" ++		"	jmplt.s.f	201f			\n\t" ++		"	move.2		(%0)2++, %1		\n\t" ++		"	jmpeq.s.t	2f			\n\t" ++		"201:	move.1		(%0)1++, %1		\n\t" ++		"	jmpt.w.t	2f			\n\t" ++ ++		"1:	.rept		25			\n\t" ++		"	movea		(%0)4++, %1		\n\t" ++		"	.endr					\n\t" ++		"	.rept		7			\n\t" ++		"	move.4		(%0)4++, %1		\n\t" ++		"	.endr					\n\t" ++		"	add.4		%2, #-32, %2		\n\t" ++		"	jmpgt.w.f	1b			\n\t" ++ ++		"	and.4		%3, #3, %3		\n\t"	// test bit 1 of n ++		"	jmpne.w.f	200b			\n\t" ++		"2:						\n\t" ++			: "+a"(s), "+d"(c), "+d"(m), "+d"(n), "=a"(aligned_start) ++			: ++			: "d15", "memory", "cc" ++		); ++ ++		return s_ret; ++	} ++ ++	__asm__ volatile ( ++	"	call		%3, 99f			\n\t"	// load %3 with address of 99 ++	"99:	movei		d15, #%%lo(1f-99b)	\n\t"	// load d15 with offset to 1 from 99 ++	"	add.4		%3, %3, d15		\n\t"	// add difference ++ ++	"	sub.4		d15, #0, %2		\n\t" ++	"	jmpeq.w.f	2f			\n\t" ++	"	and.4		d15, #(8-1), d15	\n\t"	// d15 = (-%2) & (16 - 1) ++	"	lea.4		%3, (%3,d15)		\n\t" ++	"	calli		%3, 0(%3)		\n\t" ++ ++	"1:	.rept		8			\n\t" ++	"	move.1		(%0)1++, %1		\n\t" ++	"	.endr					\n\t" ++	"2:						\n\t" ++ ++		: "+a"(s), "+d"(c), "+d"(n), "=a"(aligned_start) ++		: ++		: "d15", "memory", "cc" ++	); ++ ++	return s_ret; ++} ++libc_hidden_def(memset) +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/Makefile +@@ -0,0 +1,13 @@ ++# Makefile for uClibc ++# ++# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> ++# ++# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. ++# ++ ++top_srcdir=../../../../ ++top_builddir=../../../../ ++all: objs ++include $(top_builddir)Rules.mak ++include Makefile.arch ++include $(top_srcdir)Makerules +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/Makefile.arch +@@ -0,0 +1,28 @@ ++# Makefile for uClibc ++# ++# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> ++# ++# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. ++# ++ ++#CSRC := \ ++#	brk.c \ ++#	crtbegin.c \ ++#	crtend.c ++# ++#SSRC := \ ++#	__longjmp.S \ ++#	bsd-_setjmp.S \ ++#	bsd-setjmp.S \ ++#	setjmp.S \ ++#	clone.S \ ++#	vfork.S ++ ++CSRC := \ ++	syscall.c __syscall_error.c ++ ++SSRC := \ ++	clone.S setjmp.S vfork.S ++ ++ARCH_CFLAGS := $(CPU_CFLAGS-y) ++include $(top_srcdir)libc/sysdeps/linux/Makefile.commonarch +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/__syscall_error.c +@@ -0,0 +1,11 @@ ++#include <errno.h> ++#include <features.h> ++ ++/* This routine is jumped to by some of the syscall handlers, to stash ++ * an error number into errno.  */ ++int __syscall_error(int err_no) attribute_hidden; ++int __syscall_error(int err_no) ++{ ++	__set_errno(err_no); ++	return -1; ++} +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/bits/elf-fdpic.h +@@ -0,0 +1,115 @@ ++/* Copyright 2003, 2004 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 ++Library 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., 675 Mass Ave, ++Cambridge, MA 02139, USA.  */ ++ ++#ifndef _BITS_ELF_FDPIC_H ++#define _BITS_ELF_FDPIC_H ++ ++/* These data structures are described in the FDPIC ABI extension. ++   The kernel passes a process a memory map, such that for every LOAD ++   segment there is an elf32_fdpic_loadseg entry.  A pointer to an ++   elf32_fdpic_loadmap is passed in d8 at start-up, and a pointer to ++   an additional such map is passed in d9 for the interpreter, when ++   there is one.  */ ++ ++#include <elf.h> ++ ++/* This data structure represents a PT_LOAD segment.  */ ++struct elf32_fdpic_loadseg ++{ ++  /* Core address to which the segment is mapped.  */ ++  Elf32_Addr addr; ++  /* VMA recorded in the program header.  */ ++  Elf32_Addr p_vaddr; ++  /* Size of this segment in memory.  */ ++  Elf32_Word p_memsz; ++}; ++ ++struct elf32_fdpic_loadmap { ++  /* Protocol version number, must be zero.  */ ++  Elf32_Half version; ++  /* Number of segments in this map.  */ ++  Elf32_Half nsegs; ++  /* The actual memory map.  */ ++  struct elf32_fdpic_loadseg segs[/*nsegs*/]; ++}; ++ ++struct elf32_fdpic_loadaddr { ++  struct elf32_fdpic_loadmap *map; ++  void *got_value; ++}; ++ ++/* Map a pointer's VMA to its corresponding address according to the ++   load map.  */ ++static __always_inline void * ++__reloc_pointer (void *p, ++		 const struct elf32_fdpic_loadmap *map) ++{ ++  int c; ++ ++#if 0 ++  if (map->version != 0) ++    /* Crash.  */ ++    ((void(*)())0)(); ++#endif ++ ++  /* No special provision is made for NULL.  We don't want NULL ++     addresses to go through relocation, so they shouldn't be in ++     .rofixup sections, and, if they're present in dynamic ++     relocations, they shall be mapped to the NULL address without ++     undergoing relocations.  */ ++ ++  for (c = 0; ++       /* Take advantage of the fact that the loadmap is ordered by ++	  virtual addresses.  In general there will only be 2 entries, ++	  so it's not profitable to do a binary search.  */ ++       c < map->nsegs && p >= (void*)map->segs[c].p_vaddr; ++       c++) ++    { ++      /* This should be computed as part of the pointer comparison ++	 above, but we want to use the carry in the comparison, so we ++	 can't convert it to an integer type beforehand.  */ ++      unsigned long offset = p - (void*)map->segs[c].p_vaddr; ++      /* We only check for one-past-the-end for the last segment, ++	 assumed to be the data segment, because other cases are ++	 ambiguous in the absence of padding between segments, and ++	 rofixup already serves as padding between text and data. ++	 Unfortunately, unless we special-case the last segment, we ++	 fail to relocate the _end symbol.  */ ++      if (offset < map->segs[c].p_memsz ++	  || (offset == map->segs[c].p_memsz && c + 1 == map->nsegs)) ++	return (char*)map->segs[c].addr + offset; ++    } ++ ++  /* We might want to crash instead.  */ ++  return (void*)-1; ++} ++ ++# define __RELOC_POINTER(ptr, loadaddr) \ ++  (__reloc_pointer ((void*)(ptr), \ ++		    (loadaddr).map)) ++ ++#endif /* _BITS_ELF_FDPIC_H */ +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/bits/endian.h +@@ -0,0 +1,7 @@ ++/* Ubicom32 is big-endian.  */ ++ ++#ifndef _ENDIAN_H ++# error "Never use <bits/endian.h> directly; include <endian.h> instead." ++#endif ++ ++#define __BYTE_ORDER __BIG_ENDIAN +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/bits/fcntl.h +@@ -0,0 +1,226 @@ ++/* O_*, F_*, FD_* bit values for Linux. ++   Copyright (C) 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. ++ ++   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	_FCNTL_H ++# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead." ++#endif ++ ++ ++#include <sys/types.h> ++#ifdef __USE_GNU ++# include <bits/uio.h> ++#endif ++ ++/* open/fcntl - O_SYNC is only implemented on blocks devices and on files ++   located on an ext2 file system */ ++#define O_ACCMODE	   0003 ++#define O_RDONLY	     00 ++#define O_WRONLY	     01 ++#define O_RDWR		     02 ++#define O_CREAT		   0100	/* not fcntl */ ++#define O_EXCL		   0200	/* not fcntl */ ++#define O_NOCTTY	   0400	/* not fcntl */ ++#define O_TRUNC		  01000	/* not fcntl */ ++#define O_APPEND	  02000 ++#define O_NONBLOCK	  04000 ++#define O_NDELAY	O_NONBLOCK ++#define O_SYNC		 010000 ++#define O_FSYNC		 O_SYNC ++#define O_ASYNC		 020000 ++ ++#ifdef __USE_GNU ++# define O_DIRECTORY    040000 /* Must be a directory.	 */ ++# define O_NOFOLLOW    0100000 /* Do not follow links.	 */ ++# define O_DIRECT      0200000 /* Direct disk access.	*/ ++# define O_NOATIME    01000000 /* Do not set atime.  */ ++# define O_CLOEXEC    02000000 /* set close_on_exec */ ++# define O_STREAMING  04000000 /* streaming access */ ++#endif ++ ++/* For now Linux has synchronisity options for data and read operations. ++   We define the symbols here but let them do the same as O_SYNC since ++   this is a superset.	*/ ++#if defined __USE_POSIX199309 || defined __USE_UNIX98 ++# define O_DSYNC	O_SYNC	/* Synchronize data.  */ ++# define O_RSYNC	O_SYNC	/* Synchronize read operations.	 */ ++#endif ++ ++#ifdef __USE_LARGEFILE64 ++# define O_LARGEFILE	0400000 ++#endif ++ ++/* Values for the second argument to `fcntl'.  */ ++#define F_DUPFD		0	/* Duplicate file descriptor.  */ ++#define F_GETFD		1	/* Get file descriptor flags.  */ ++#define F_SETFD		2	/* Set file descriptor flags.  */ ++#define F_GETFL		3	/* Get file status flags.  */ ++#define F_SETFL		4	/* Set file status flags.  */ ++#ifndef __USE_FILE_OFFSET64 ++# define F_GETLK	5	/* Get record locking info.  */ ++# define F_SETLK	6	/* Set record locking info (non-blocking).  */ ++# define F_SETLKW	7	/* Set record locking info (blocking).	*/ ++#else ++# define F_GETLK	F_GETLK64  /* Get record locking info.	*/ ++# define F_SETLK	F_SETLK64  /* Set record locking info (non-blocking).*/ ++# define F_SETLKW	F_SETLKW64 /* Set record locking info (blocking).  */ ++#endif ++#define F_GETLK64	12	/* Get record locking info.  */ ++#define F_SETLK64	13	/* Set record locking info (non-blocking).  */ ++#define F_SETLKW64	14	/* Set record locking info (blocking).	*/ ++ ++#if defined __USE_BSD || defined __USE_XOPEN2K ++# define F_SETOWN	8	/* Get owner of socket (receiver of SIGIO).  */ ++# define F_GETOWN	9	/* Set owner of socket (receiver of SIGIO).  */ ++#endif ++ ++#ifdef __USE_GNU ++# define F_SETSIG	10	/* Set number of signal to be sent.  */ ++# define F_GETSIG	11	/* Get number of signal to be sent.  */ ++#endif ++ ++#ifdef __USE_GNU ++# define F_SETLEASE	1024	/* Set a lease.	 */ ++# define F_GETLEASE	1025	/* Enquire what lease is active.  */ ++# define F_NOTIFY	1026	/* Request notfications on a directory.	 */ ++#endif ++ ++/* For F_[GET|SET]FL.  */ ++#define FD_CLOEXEC	1	/* actually anything with low bit set goes */ ++ ++/* For posix fcntl() and `l_type' field of a `struct flock' for lockf().  */ ++#define F_RDLCK		0	/* Read lock.  */ ++#define F_WRLCK		1	/* Write lock.	*/ ++#define F_UNLCK		2	/* Remove lock.	 */ ++ ++/* For old implementation of bsd flock().  */ ++#define F_EXLCK		4	/* or 3 */ ++#define F_SHLCK		8	/* or 4 */ ++ ++#ifdef __USE_BSD ++/* Operations for bsd flock(), also used by the kernel implementation.	*/ ++# define LOCK_SH	1	/* shared lock */ ++# define LOCK_EX	2	/* exclusive lock */ ++# define LOCK_NB	4	/* or'd with one of the above to prevent ++				   blocking */ ++# define LOCK_UN	8	/* remove lock */ ++#endif ++ ++#ifdef __USE_GNU ++# define LOCK_MAND	32	/* This is a mandatory flock:	*/ ++# define LOCK_READ	64	/* ... which allows concurrent read operations.	 */ ++# define LOCK_WRITE	128	/* ... which allows concurrent write operations.  */ ++# define LOCK_RW	192	/* ... Which allows concurrent read & write operations.	 */ ++#endif ++ ++#ifdef __USE_GNU ++/* Types of directory notifications that may be requested with F_NOTIFY.  */ ++# define DN_ACCESS	0x00000001	/* File accessed.  */ ++# define DN_MODIFY	0x00000002	/* File modified.  */ ++# define DN_CREATE	0x00000004	/* File created.  */ ++# define DN_DELETE	0x00000008	/* File removed.  */ ++# define DN_RENAME	0x00000010	/* File renamed.  */ ++# define DN_ATTRIB	0x00000020	/* File changed attibutes.  */ ++# define DN_MULTISHOT	0x80000000	/* Don't remove notifier.  */ ++#endif ++ ++struct flock ++  { ++    short int l_type;	/* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.	*/ ++    short int l_whence;	/* Where `l_start' is relative to (like `lseek').  */ ++#ifndef __USE_FILE_OFFSET64 ++    __off_t l_start;	/* Offset where the lock begins.  */ ++    __off_t l_len;	/* Size of the locked area; zero means until EOF.  */ ++#else ++    __off64_t l_start;	/* Offset where the lock begins.  */ ++    __off64_t l_len;	/* Size of the locked area; zero means until EOF.  */ ++#endif ++    __pid_t l_pid;	/* Process holding the lock.  */ ++  }; ++ ++#ifdef __USE_LARGEFILE64 ++struct flock64 ++  { ++    short int l_type;	/* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.	*/ ++    short int l_whence;	/* Where `l_start' is relative to (like `lseek').  */ ++    __off64_t l_start;	/* Offset where the lock begins.  */ ++    __off64_t l_len;	/* Size of the locked area; zero means until EOF.  */ ++    __pid_t l_pid;	/* Process holding the lock.  */ ++  }; ++#endif ++ ++/* Define some more compatibility macros to be backward compatible with ++   BSD systems which did not managed to hide these kernel macros.  */ ++#ifdef	__USE_BSD ++# define FAPPEND	O_APPEND ++# define FFSYNC		O_FSYNC ++# define FASYNC		O_ASYNC ++# define FNONBLOCK	O_NONBLOCK ++# define FNDELAY	O_NDELAY ++#endif /* Use BSD.  */ ++ ++/* Advise to `posix_fadvise'.  */ ++#ifdef __USE_XOPEN2K ++# define POSIX_FADV_NORMAL	0 /* No further special treatment.  */ ++# define POSIX_FADV_RANDOM	1 /* Expect random page references.  */ ++# define POSIX_FADV_SEQUENTIAL	2 /* Expect sequential page references.	 */ ++# define POSIX_FADV_WILLNEED	3 /* Will need these pages.  */ ++# define POSIX_FADV_DONTNEED	4 /* Don't need these pages.  */ ++# define POSIX_FADV_NOREUSE	5 /* Data will be accessed once.  */ ++#endif ++ ++#ifdef __USE_GNU ++# define SYNC_FILE_RANGE_WAIT_BEFORE	1 /* Wait upon writeout of all pages ++					     in the range before performing the ++					     write.  */ ++# define SYNC_FILE_RANGE_WRITE		2 /* Initiate writeout of all those ++					     dirty pages in the range which are ++					     not presently under writeback.  */ ++# define SYNC_FILE_RANGE_WAIT_AFTER	4 /* Wait upon writeout of all pages in ++					     the range after performing the ++					     write.  */ ++#endif ++ ++__BEGIN_DECLS ++ ++#ifdef __USE_GNU ++ ++/* Provide kernel hint to read ahead.  */ ++extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count) ++    __THROW; ++ ++/* Selective file content synch'ing.  */ ++extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to, ++			    unsigned int __flags); ++ ++/* Splice address range into a pipe.  */ ++extern ssize_t vmsplice (int __fdout, const struct iovec *__iov, ++			 size_t __count, unsigned int __flags); ++ ++/* Splice two files together.  */ ++extern ssize_t splice (int __fdin, __off64_t *__offin, int __fdout, ++		       __off64_t *__offout, size_t __len, ++		       unsigned int __flags); ++ ++/* In-kernel implementation of tee for pipe buffers.  */ ++extern ssize_t tee (int __fdin, int __fdout, size_t __len, ++		    unsigned int __flags); ++ ++#endif ++ ++__END_DECLS +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/bits/kernel_stat.h +@@ -0,0 +1,55 @@ ++#ifndef _BITS_STAT_STRUCT_H ++#define _BITS_STAT_STRUCT_H ++ ++#ifndef _LIBC ++#error bits/kernel_stat.h is for internal uClibc use only! ++#endif ++ ++/* This file provides whatever this particular arch's kernel thinks ++ * struct kernel_stat should look like...  It turns out each arch has a ++ * different opinion on the subject... */ ++ ++struct kernel_stat { ++	unsigned short st_dev; ++	unsigned short __pad1; ++	unsigned long st_ino; ++	unsigned short st_mode; ++	unsigned short st_nlink; ++	unsigned short st_uid; ++	unsigned short st_gid; ++	unsigned short st_rdev; ++	unsigned short __pad2; ++	unsigned long  st_size; ++	unsigned long  st_blksize; ++	unsigned long  st_blocks; ++	struct timespec st_atim; ++	struct timespec st_mtim; ++	struct timespec st_ctim; ++	unsigned long  __unused4; ++	unsigned long  __unused5; ++}; ++ ++struct kernel_stat64 { ++	unsigned char	__pad0[6]; ++	unsigned short	st_dev; ++	unsigned char	__pad1[4]; ++#define _HAVE_STAT64___ST_INO ++	unsigned long	__st_ino; ++	unsigned int	st_mode; ++	unsigned int	st_nlink; ++	unsigned long	st_uid; ++	unsigned long	st_gid; ++	unsigned char	__pad2[6]; ++	unsigned short	st_rdev; ++	unsigned char	__pad3[4]; ++	long long	st_size; ++	unsigned long	st_blksize; ++	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */ ++	unsigned long	__pad4;		/* future possible st_blocks high bits */ ++	struct timespec	st_atim; ++	struct timespec	st_mtim; ++	struct timespec	st_ctim; ++	unsigned long long	st_ino; ++}; ++ ++#endif	/*  _BITS_STAT_STRUCT_H */ +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/bits/kernel_types.h +@@ -0,0 +1,44 @@ ++/* Note that we use the exact same include guard #define names ++ * as asm/posix_types.h.  This will avoid gratuitous conflicts ++ * with the posix_types.h kernel header, and will ensure that ++ * our private content, and not the kernel header, will win. ++ *  -Erik ++ */ ++#ifndef __ARCH_UBICOM32_POSIX_TYPES_H ++#define __ARCH_UBICOM32_POSIX_TYPES_H ++ ++typedef unsigned long	__kernel_dev_t; ++typedef unsigned long	__kernel_ino_t; ++typedef unsigned short	__kernel_mode_t; ++typedef unsigned short	__kernel_nlink_t; ++typedef long		__kernel_off_t; ++typedef int		__kernel_pid_t; ++typedef unsigned short	__kernel_ipc_pid_t; ++typedef unsigned short	__kernel_uid_t; ++typedef unsigned short	__kernel_gid_t; ++typedef unsigned int	__kernel_size_t; ++typedef int		__kernel_ssize_t; ++typedef int		__kernel_ptrdiff_t; ++typedef long		__kernel_time_t; ++typedef long		__kernel_suseconds_t; ++typedef long		__kernel_clock_t; ++typedef int		__kernel_daddr_t; ++typedef char *		__kernel_caddr_t; ++typedef unsigned short	__kernel_uid16_t; ++typedef unsigned short	__kernel_gid16_t; ++typedef unsigned int	__kernel_uid32_t; ++typedef unsigned int	__kernel_gid32_t; ++typedef unsigned short	__kernel_old_uid_t; ++typedef unsigned short	__kernel_old_gid_t; ++typedef unsigned short	__kernel_old_dev_t; ++typedef long long	__kernel_loff_t; ++ ++typedef struct { ++#ifdef __USE_ALL ++	int val[2]; ++#else ++	int __val[2]; ++#endif ++} __kernel_fsid_t; ++ ++#endif /* __ARCH_UBICOM32_POSIX_TYPES_H */ +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/bits/mman.h +@@ -0,0 +1,103 @@ ++/* Definitions for POSIX memory map interface.  Linux/m68k version. ++   Copyright (C) 1997, 2000, 2003, 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 _SYS_MMAN_H ++# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead." ++#endif ++ ++/* The following definitions basically come from the kernel headers. ++   But the kernel header is not namespace clean.  */ ++ ++ ++/* Protections are chosen from these bits, OR'd together.  The ++   implementation does not necessarily support PROT_EXEC or PROT_WRITE ++   without PROT_READ.  The only guarantees are that no writing will be ++   allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */ ++ ++#define PROT_READ	0x1		/* Page can be read.  */ ++#define PROT_WRITE	0x2		/* Page can be written.  */ ++#define PROT_EXEC	0x4		/* Page can be executed.  */ ++#define PROT_NONE	0x0		/* Page can not be accessed.  */ ++#define PROT_GROWSDOWN	0x01000000	/* Extend change to start of ++					   growsdown vma (mprotect only).  */ ++#define PROT_GROWSUP	0x02000000	/* Extend change to start of ++					   growsup vma (mprotect only).  */ ++ ++/* Sharing types (must choose one and only one of these).  */ ++#define MAP_SHARED	0x01		/* Share changes.  */ ++#define MAP_PRIVATE	0x02		/* Changes are private.  */ ++#ifdef __USE_MISC ++# define MAP_TYPE	0x0f		/* Mask for type of mapping.  */ ++#endif ++ ++/* Other flags.  */ ++#define MAP_FIXED	0x10		/* Interpret addr exactly.  */ ++#ifdef __USE_MISC ++# define MAP_FILE	0 ++# define MAP_ANONYMOUS	0x20		/* Don't use a file.  */ ++# define MAP_ANON	MAP_ANONYMOUS ++#endif ++ ++/* These are Linux-specific.  */ ++#ifdef __USE_MISC ++# define MAP_GROWSDOWN     0x0000100 /* Stack-like segment.  */ ++# define MAP_DENYWRITE     0x0000800 /* ETXTBSY */ ++# define MAP_EXECUTABLE    0x0001000 /* Mark it as an executable.  */ ++# define MAP_LOCKED        0x0002000 /* Lock the mapping.  */ ++# define MAP_NORESERVE     0x0004000 /* Don't check for reservations.  */ ++# define MAP_POPULATE      0x0008000 /* Populate (prefault) pagetables.  */ ++# define MAP_NONBLOCK      0x0010000 /* Do not block on IO.  */ ++# define MAP_UNINITIALIZE  0x4000000 /* For anonymous mmap, memory could be uninitialized. */ ++#endif ++ ++/* Flags to `msync'.  */ ++#define MS_ASYNC	1		/* Sync memory asynchronously.  */ ++#define MS_SYNC		4		/* Synchronous memory sync.  */ ++#define MS_INVALIDATE	2		/* Invalidate the caches.  */ ++ ++/* Flags for `mlockall'.  */ ++#define MCL_CURRENT	1		/* Lock all currently mapped pages.  */ ++#define MCL_FUTURE	2		/* Lock all additions to address ++					   space.  */ ++ ++/* Flags for `mremap'.  */ ++#ifdef __USE_GNU ++# define MREMAP_MAYMOVE	1 ++# define MREMAP_FIXED	2 ++#endif ++ ++/* Advice to `madvise'.  */ ++#ifdef __USE_BSD ++# define MADV_NORMAL	 0	/* No further special treatment.  */ ++# define MADV_RANDOM	 1	/* Expect random page references.  */ ++# define MADV_SEQUENTIAL 2	/* Expect sequential page references.  */ ++# define MADV_WILLNEED	 3	/* Will need these pages.  */ ++# define MADV_DONTNEED	 4	/* Don't need these pages.  */ ++# define MADV_DONTFORK	 10	/* Do not inherit across fork.  */ ++# define MADV_DOFORK	 11	/* Do inherit across fork.  */ ++#endif ++ ++/* The POSIX people had to invent similar names for the same things.  */ ++#ifdef __USE_XOPEN2K ++# define POSIX_MADV_NORMAL	0 /* No further special treatment.  */ ++# define POSIX_MADV_RANDOM	1 /* Expect random page references.  */ ++# define POSIX_MADV_SEQUENTIAL	2 /* Expect sequential page references.  */ ++# define POSIX_MADV_WILLNEED	3 /* Will need these pages.  */ ++# define POSIX_MADV_DONTNEED	4 /* Don't need these pages.  */ ++#endif +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/bits/setjmp.h +@@ -0,0 +1,52 @@ ++/* Define the machine-dependent type `jmp_buf'.  Ubicom32 version. ++   Copyright (C) 1992,93,95,97,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. ++ ++   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_SETJMP_H ++#define _BITS_SETJMP_H	1 ++ ++#if !defined _SETJMP_H && !defined _PTHREAD_H ++# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead." ++#endif ++ ++#ifndef	_ASM ++/* ++ * This is the structure where we are going to save D10-D13, A0, A1, A2, A5, A6 and SP(A7). ++ * A5 is the return address. Call to setjmp will save these. Call to longjmp will return ++ * Control to the address in A5. ++ */ ++typedef struct setjmp_save_struct { ++	unsigned long  d10;		/* D10 */ ++	unsigned long  d11;		/* D11 */ ++	unsigned long  d12;		/* D12 */ ++	unsigned long  d13;		/* D13 */ ++	unsigned long  a1;		/* A1  */ ++	unsigned long  a2;		/* A2  */ ++	unsigned long  a5;		/* A5 return address. */ ++	unsigned long  a6;		/* A6 */ ++	unsigned long  sp;		/* A7 stack pointer. */ ++} __jmp_buf[1]; ++ ++#endif ++ ++/* Test if longjmp to JMPBUF would unwind the frame ++   containing a local variable at ADDRESS.  */ ++#define _JMPBUF_UNWINDS(jmpbuf, address) \ ++  ((void *) (address) < (void*)(jmpbuf)->sp) ++ ++#endif	/* bits/setjmp.h */ +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/bits/stackinfo.h +@@ -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 Ubicom32 the stack grows down.  */ ++#define _STACK_GROWS_DOWN	1 ++ ++#endif	/* stackinfo.h */ +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/bits/syscalls.h +@@ -0,0 +1,81 @@ ++#ifndef _BITS_SYSCALLS_H ++#define _BITS_SYSCALLS_H ++#ifndef _SYSCALL_H ++# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead." ++#endif ++ ++/* m68k headers does stupid stuff with __NR_iopl / __NR_vm86: ++ * #define __NR_iopl   not supported ++ * #define __NR_vm86   not supported ++ */ ++#undef __NR_iopl ++#undef __NR_vm86 ++ ++#ifndef __ASSEMBLER__ ++ ++#include <errno.h> ++ ++/* Linux takes system call arguments in registers: ++ ++	syscall number	%d8 ++	arg 1		%d0 ++	arg 2		%d1 ++	arg 3		%d2 ++	arg 4		%d3 ++	arg 5		%d4 ++	arg 6		%d5 ++*/ ++ ++#define __loadargs_0(name, dummy)					      \ ++	d8 = (long int)name ++ ++#define __loadargs_1(name, __arg1)					\ ++	__loadargs_0(name, 0);						\ ++	d0_retval = (long int) __arg1 ++ ++#define __loadargs_2(name, __arg1, __arg2)    \ ++	__loadargs_1(name, __arg1);			   \ ++	d1 = (long int) __arg2 ++ ++#define __loadargs_3(name, __arg1, __arg2, __arg3) \ ++	__loadargs_2(name, __arg1, __arg2); \ ++	d2 = (long int) __arg3 ++ ++#define __loadargs_4(name, __arg1, __arg2, __arg3, __arg4)	\ ++	__loadargs_3(name, __arg1, __arg2, __arg3); \ ++	d3 = (long int)__arg4 ++ ++#define __loadargs_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \ ++	__loadargs_4(name, __arg1, __arg2, __arg3, __arg4); \ ++	d4 = (long int)__arg5 ++ ++#define __loadargs_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \ ++	__loadargs_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \ ++	d5 = (long int)__arg6 ++ ++#define INTERNAL_SYSCALL_NCS(name, err, nr, args...)			\ ++({									\ ++	register long int d0_retval  __asm__ ("d0");			\ ++	register long int d1  __asm__ ("d1");				\ ++	register long int d2  __asm__ ("d2");				\ ++	register long int d3  __asm__ ("d3");				\ ++	register long int d4  __asm__ ("d4");				\ ++	register long int d5  __asm__ ("d5");				\ ++	register long int d8  __asm__ ("d8");				\ ++	__loadargs_##nr (name, args);					\ ++	__asm__ __volatile__ (						\ ++	"	moveai a5, #%%hi(0x40400000)\n\t"			\ ++	"	calli a5, 16(a5)\n\t"					\ ++		: "+r" (d0_retval), "+r" (d1), "+r" (d2), "+r" (d3),	\ ++		  "+r" (d4), "+r" (d5),  "+r" (d8) :			\ ++		: "cc", "memory",					\ ++		  "acc0_lo", "acc0_hi", "acc1_lo", "acc1_hi",		\ ++		  "source3",						\ ++		  "a0", "a3", "a4", "a5",				\ ++		  "d6", "d7", "d9", "d14", "d15"			\ ++	);								\ ++	d0_retval;							\ ++}) ++ ++#endif /* __ASSEMBLER__ */ ++#endif /* _BITS_SYSCALLS_H */ +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/bits/uClibc_arch_features.h +@@ -0,0 +1,45 @@ ++/* ++ * Track misc arch-specific features that aren't config options ++ */ ++ ++#ifndef _BITS_UCLIBC_ARCH_FEATURES_H ++#define _BITS_UCLIBC_ARCH_FEATURES_H ++ ++/* instruction used when calling abort() to kill yourself */ ++/*#define __UCLIBC_ABORT_INSTRUCTION__ "asm instruction"*/ ++#undef __UCLIBC_ABORT_INSTRUCTION__ ++ ++/* can your target use syscall6() for mmap ? */ ++#undef __UCLIBC_MMAP_HAS_6_ARGS__ ++ ++/* does your target use syscall4() for truncate64 ? (32bit arches only) */ ++#undef __UCLIBC_TRUNCATE64_HAS_4_ARGS__ ++ ++/* does your target have a broken create_module() ? */ ++#undef __UCLIBC_BROKEN_CREATE_MODULE__ ++ ++/* does your target have to worry about older [gs]etrlimit() ? */ ++#undef __UCLIBC_HANDLE_OLDER_RLIMIT__ ++ ++/* does your target prefix all symbols with an _ ? */ ++#define __UCLIBC_NO_UNDERSCORES__ ++ ++/* does your target have an asm .set ? */ ++#define __UCLIBC_HAVE_ASM_SET_DIRECTIVE__ ++ ++/* define if target doesn't like .global */ ++#undef __UCLIBC_ASM_GLOBAL_DIRECTIVE__ ++ ++/* define if target supports .weak */ ++#define __UCLIBC_HAVE_ASM_WEAK_DIRECTIVE__ ++ ++/* define if target supports .weakext */ ++#undef __UCLIBC_HAVE_ASM_WEAKEXT_DIRECTIVE__ ++ ++/* needed probably only for ppc64 */ ++#undef __UCLIBC_HAVE_ASM_GLOBAL_DOT_NAME__ ++ ++/* define if target supports IEEE signed zero floats */ ++#define __UCLIBC_HAVE_SIGNED_ZERO__ ++ ++#endif /* _BITS_UCLIBC_ARCH_FEATURES_H */ +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/bits/wordsize.h +@@ -0,0 +1,19 @@ ++/* 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.  */ ++ ++#define __WORDSIZE	32 +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/clone.S +@@ -0,0 +1,71 @@ ++#include <sys/syscall.h> ++ ++	.global __syscall_error ++ ++/* int _clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */ ++	.text ++	.type   clone,@function ++	.global clone ++clone: ++	/* Sanity check arguments.  */ ++	sub.4	#0, #0, d0	/* Test if fn is zero. */ ++	jmpeq.f 1f		/* arg bad */ ++	sub.4	#0, #0, d1	/* Test if child_stack is zero. */ ++	jmpeq.f	1f		/* arg bad */ ++ ++	/* Set up child_stack frame.. arg and fn */ ++	move.4	a3, d1 ++	move.4	-4(a3)++, d3	/* push 'arg' to child stack */ ++	move.4	-4(a3)++, d0	/* push fn to child stack, this will become a5 ++				 * on new child */ ++	move.4	d1, a3 ++	move.4	-4(sp)++, a5	/* push a5 to our stack */ ++ ++	/* ++	 * The syscall clone is clone(int flags, void *child_stack) so we set ++	 * that up now ++	 */ ++	move.4	d0, d2		/* Move flags to d0 */ ++ ++	/* Do Clone syscall */ ++	movei	d8, #__NR_clone ++	moveai	a5, #%hi(0x40400000) ++	calli	a5, 0x10(a5) ++	move.4	a5, (sp)4++	/* pop a5 from stack */ ++ ++	/* Clone Complete */ ++	cmpi	d0, #0		/* Test if d0 is less than zero. If it is we ++				 * return the error */ ++	jmplt.f	2f		/* If return is less than we had an error */ ++	jmpeq.f	3f		/* If return is 0 we are in the clone, jump to ++				 * thread start */ ++	ret	a5		/* d0 is pid */ ++ ++	/* Invalid Value */ ++1:	movei   d0, #-22	/* EINVAL */ ++ ++	/* Call syscall Error */ ++2:	sub.4	d0, #0, d0	/* d0 = -d0 */ ++#if defined(__UBICOM32_FDPIC__) ++	call	a3, __syscall_error ++#else ++	moveai	a3, #%hi(__syscall_error) ++	calli	a3, %lo(__syscall_error)(a3) ++#endif ++	/* Child Thread Start */ ++3: ++#if defined(__UBICOM32_FDPIC__) ++	/* a5 actually contains a function descriptor for fdpic */ ++	move.4	a0, 4(a5)	/* set GOT for this function */ ++	move.4	a5, 0(a5)	/* get address of entry point */ ++#endif ++	move.4	d0, (sp)4++	/* pop 'arg' to stack */ ++	calli	a5, 0(a5) ++	movei	d8, #__NR_exit ++	moveai	a3, #%hi(0x40400000) ++	calli	a3, 0x10(a3) ++ ++	.size clone, . - clone ++	.global __GI_clone ++	.hidden __GI_clone ++	.set __GI_clone,clone +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/crt1.S +@@ -0,0 +1,179 @@ ++/* Startup code compliant to the ELF m68k ABI. ++   Copyright (C) 1996, 1997, 1998, 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. ++ ++   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.) ++ ++   Note that people who make modified versions of this file are not ++   obligated to grant this special exception for their modified ++   versions; it is their choice whether to do so. The GNU Lesser ++   General Public License gives permission to release a modified ++   version without this exception; this exception also makes it ++   possible to release a modified version which carries forward this ++   exception. ++ ++   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 <features.h> ++ ++/* This is the canonical entry point, usually the first thing in the text ++   segment.  The SVR4/m68k ABI says that when the entry point runs, ++   most registers' values are unspecified, except for: ++ ++   %a1		Contains a function pointer to be registered with `atexit'. ++		This is how the dynamic linker arranges to have DT_FINI ++		functions called for shared libraries that have been loaded ++		before this code runs. ++ ++   %sp		The stack contains the arguments and environment: ++		0(%sp)			argc ++		4(%sp)			argv[0] ++		... ++		(4*argc)(%sp)		NULL ++		(4*(argc+1))(%sp)	envp[0] ++		... ++					NULL ++ ++   The uclinux conventions are different.  %a1 is not defined on entry ++   and the stack is laid out as follows: ++ ++		0(%sp)			argc ++		4(%sp)			argv ++		8(%sp)			envp ++*/ ++ ++ ++	.text ++	.type   main,@function ++	.type	_init,%function ++	.type	_fini,%function ++#ifndef __UCLIBC_CTOR_DTOR__ ++	.weak	_init ++	.weak	_fini ++#endif ++	.globl	_start ++	.global __uClibc_main; ++	.type	__uClibc_main,@function; ++	.type	_start,@function ++_start: ++ ++#if defined(__UBICOM32_FDPIC__) && !defined(L_Scrt1) ++	/* P0 contains a pointer to the program's load map.  */ ++	call	a3, .Lcall; ++.Lcall: ++	move.4	d0, d1 ; load exec_map_addr ++	moveai	a4, #%hi(.Lcall) ++	lea.1	d15, %lo(.Lcall)(a4) ++	sub.4	d15, a3, d15	;  difference between .Lcall and actual address of .Lcall ++	moveai	a3, #%hi(__ROFIXUP_LIST__) ++	lea.1	d1, %lo(__ROFIXUP_LIST__)(a3) ++	moveai	a3, #%hi(__ROFIXUP_END__) ++	lea.1	d2, %lo(__ROFIXUP_END__)(a3) ++	add.4	d1, d1, d15 ++	add.4	d2, d2, d15 ++	call	a5, __self_reloc	; returns GOT in d0 ++	move.4	a0, d0	; set GOT ++#endif ++ ++/* ++	all this is setup to make the following call. ++ ++	void __uClibc_main( ++		d0 - int (*main)(int, char **, char **), ++		d1 - int argc, (d1) ++		d2 - char **argv, ++		d3 - void (*app_init)(void), ++		d4 - void (*app_fini)(void), ++		d5 - void (*rtld_fini)(void), ++		d6 - void *stack_end ++	); ++ */ ++ ++	/* ++	 * Load pointer to main into d0 ++	 */ ++#ifdef __UBICOM32_FDPIC__ ++	movei	d0, #%got_funcdesc_lo(main) ++	move.4	d0, (a0, d0) ++#else ++	moveai	a3, #%hi(main) ++	lea.1	d0, %lo(main)(a3) ++#endif ++ ++	/* ++	 * Grab the environment stuff from stack and set up d1, d2 with it. ++	 */ ++	move.4	d1, (sp) ++#ifdef __UBICOM32_FDPIC__ ++	/* For FDPIC the calling convention is different than flat */ ++	lea.1	d2, 4(sp) ++#else ++	move.4	d2, 4(sp) ++#endif ++ ++#ifdef __UCLIBC_CTOR_DTOR__ ++	/* ++	 * Load pointer to _init into d3 ++	 */ ++#ifdef __UBICOM32_FDPIC__ ++	movei	d3, #%got_funcdesc_lo(_init) ++	move.4	d3, (a0, d3) ++#else ++	moveai	a3, #%hi(_init) ++	lea.1	d3, %lo(_init)(a3) ++#endif ++ ++	/* ++	 * Load pointer to _fini into d4 ++	 */ ++#ifdef __UBICOM32_FDPIC__ ++	movei	d4, #%got_funcdesc_lo(_fini) ++	move.4	d4, (a0, d4) ++#else ++	moveai	a3, #%hi(_fini) ++	lea.1	d4, %lo(_fini)(a3) ++#endif ++ ++#else /* !__UCLIBC_CTOR_DTOR__ */ ++	move.4	d3, #0		; _init ++	move.4	d4, #0		; _fini ++#endif ++ ++#ifdef __UBICOM32_FDPIC__ ++	move.4	d5, a1		; ldso _fini funcdesc (see dl-startup.h) ++#else ++	movei	d5, #0		; rtld_fini (not used) ++#endif ++ ++	move.4	d6, sp		; Stack End. ++ ++	/* Call the user's main function, and exit with its value.  But ++	   let the libc call main.  */ ++#ifdef __UBICOM32_FDPIC__ ++	call	a5, __uClibc_main ++#else ++	moveai	a5, #%hi(__uClibc_main) ++	calli	a5, %lo(__uClibc_main)(a5) ++#endif ++ ++	bkpt #-1		; Crash if somehow `exit' does return. +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/crti.S +@@ -0,0 +1,54 @@ ++/* Specialized code needed to support construction and destruction of ++   file-scope objects in C++ and Java code, and to support exception handling. ++   Copyright (C) 1999 Free Software Foundation, Inc. ++   Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca). ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2, or (at your option) ++any later version. ++ ++GCC 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 General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING.  If not, write to ++the Free Software Foundation, 59 Temple Place - Suite 330, ++Boston, MA 02111-1307, USA.  */ ++ ++/* As a special exception, if you link this library with files ++   compiled with GCC to produce an executable, this does not cause ++   the resulting executable to be covered by the GNU General Public License. ++   This exception does not however invalidate any other reasons why ++   the executable file might be covered by the GNU General Public License.  */ ++ ++/* ++ * This file just supplies function prologues for the .init and .fini ++ * sections.  It is linked in before crtbegin.o. ++ */ ++	.file   "crti.o" ++	.ident  "GNU C crti.o" ++ ++	.section .init ++	.align	2 ++	.globl	_init ++	.type	_init, @function ++_init: ++	move.4 -4(sp)++, a5 ++#ifdef __UBICOM32_FDPIC__ ++	move.4 -4(sp)++, a0 ++#endif ++ ++	.section .fini ++	.align	2 ++	.globl	_fini ++	.type	_fini, @function ++_fini: ++	move.4 -4(sp)++, a5 ++#ifdef __UBICOM32_FDPIC__ ++	move.4 -4(sp)++, a0 ++#endif +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/crtn.S +@@ -0,0 +1,47 @@ ++/* Specialized code needed to support construction and destruction of ++   file-scope objects in C++ and Java code, and to support exception handling. ++   Copyright (C) 1999 Free Software Foundation, Inc. ++   Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca). ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2, or (at your option) ++any later version. ++ ++GCC 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 General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING.  If not, write to ++the Free Software Foundation, 59 Temple Place - Suite 330, ++Boston, MA 02111-1307, USA.  */ ++ ++/* As a special exception, if you link this library with files ++   compiled with GCC to produce an executable, this does not cause ++   the resulting executable to be covered by the GNU General Public License. ++   This exception does not however invalidate any other reasons why ++   the executable file might be covered by the GNU General Public License.  */ ++ ++/* ++ * This file supplies function epilogues for the .init and .fini sections. ++ * It is linked in after all other files. ++ */ ++ ++	.file   "crtn.o" ++	.ident  "GNU C crtn.o" ++ ++	.section .init ++#ifdef __UBICOM32_FDPIC__ ++	move.4	a0, (sp)4++ ++#endif ++	ret	(sp)4++ ++ ++	.section .fini ++#ifdef __UBICOM32_FDPIC__ ++	move.4	a0, (sp)4++ ++#endif ++	ret	(sp)4++ +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/crtreloc.c +@@ -0,0 +1,145 @@ ++/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. ++   written by Alexandre Oliva <aoliva@redhat.com> ++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 ++Library 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., 675 Mass Ave, ++Cambridge, MA 02139, USA.  */ ++ ++#ifdef __UBICOM32_FDPIC__ ++ ++#include <sys/types.h> ++#include <link.h> ++ ++/* This file is to be compiled into crt object files, to enable ++   executables to easily self-relocate.  */ ++ ++union word { ++    char c[4]; ++    void *v; ++}; ++ ++/* Compute the runtime address of pointer in the range [p,e), and then ++   map the pointer pointed by it.  */ ++static __always_inline void *** ++reloc_range_indirect (void ***p, void ***e, ++		      const struct elf32_fdpic_loadmap *map) ++{ ++  while (p < e) ++    { ++      if (*p != (void **)-1) ++	{ ++	  void *ptr = __reloc_pointer (*p, map); ++	  if (ptr != (void *)-1) ++	    { ++	      void *pt; ++	      if ((long)ptr & 3) ++		{ ++		  unsigned char *c = ptr; ++		  int i; ++		  unsigned long v = 0; ++		  for (i = 0; i < 4; i++) ++		    v |= c[i] << 8 * i; ++		  pt = (void *)v; ++		} ++	      else ++		pt = *(void**)ptr; ++	      pt = __reloc_pointer (pt, map); ++	      if ((long)ptr & 3) ++		{ ++		  unsigned char *c = ptr; ++		  int i; ++		  unsigned long v = (unsigned long)pt; ++		  for (i = 0; i < 4; i++, v >>= 8) ++		    c[i] = v; ++		} ++	      else ++		*(void**)ptr = pt; ++	    } ++	} ++      p++; ++    } ++  return p; ++} ++ ++/* Call __reloc_range_indirect for the given range except for the last ++   entry, whose contents are only relocated.  It's expected to hold ++   the GOT value.  */ ++void* attribute_hidden ++__self_reloc (const struct elf32_fdpic_loadmap *map, ++	      void ***p, void ***e) ++{ ++  p = reloc_range_indirect (p, e-1, map); ++ ++  if (p >= e) ++    return (void*)-1; ++ ++  return __reloc_pointer (*p, map); ++} ++ ++#if 0 ++/* These are other functions that might be useful, but that we don't ++   need.  */ ++ ++/* Remap pointers in [p,e).  */ ++static __always_inline void** ++reloc_range (void **p, void **e, ++	     const struct elf32_fdpic_loadmap *map) ++{ ++  while (p < e) ++    { ++      *p = __reloc_pointer (*p, map); ++      p++; ++    } ++  return p; ++} ++ ++/* Remap p, adjust e by the same offset, then map the pointers in the ++   range determined by them.  */ ++void attribute_hidden ++__reloc_range (const struct elf32_fdpic_loadmap *map, ++	       void **p, void **e) ++{ ++  void **old = p; ++ ++  p = __reloc_pointer (p, map); ++  e += p - old; ++  reloc_range (p, e, map); ++} ++ ++/* Remap p, adjust e by the same offset, then map pointers referenced ++   by the (unadjusted) pointers in the range.  Return the relocated ++   value of the last pointer in the range.  */ ++void* attribute_hidden ++__reloc_range_indirect (const struct elf32_fdpic_loadmap *map, ++			void ***p, void ***e) ++{ ++  void ***old = p; ++ ++  p = __reloc_pointer (p, map); ++  e += p - old; ++  return reloc_range_indirect (p, e, map); ++} ++#endif ++ ++#endif /* __UBICOM32_FDPIC__ */ +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/setjmp.S +@@ -0,0 +1,72 @@ ++/* Setjmp for Ubicom32 */ ++	.text ++	.global _setjmp ++	.type   _setjmp,@function ++_setjmp: ++	movea	a3, d0		; A3 now holds the jmp buf that was passed in. ++	move.4	(a3)4++, d10 ++	move.4	(a3)4++, d11 ++	move.4	(a3)4++, d12 ++	move.4	(a3)4++, d13 ++	move.4  (a3)4++, a1 ++	move.4  (a3)4++, a2 ++	move.4  (a3)4++, a5 ++	move.4  (a3)4++, a6 ++	move.4  (a3)4++, a7 ++	move.4	d0, #0 ++ ++	calli	a5, 0(a5) ++	.size _setjmp, . - _setjmp ++ ++/* ++ * __sigsetjmp for Ubicom32 ++ *     d0 holds sigjmp_buf and d1 holds the savemask. We will save the frame and then just call __sigjmp_save to do the mask save. ++ */ ++	.global __sigsetjmp ++	.type   __sigsetjmp,@function ++__sigsetjmp: ++	movea	a3, d0		; A3 now holds the jmp buf that was passed in. ++	move.4	(a3)4++, d10 ++	move.4	(a3)4++, d11 ++	move.4	(a3)4++, d12 ++	move.4	(a3)4++, d13 ++	move.4  (a3)4++, a1 ++	move.4  (a3)4++, a2 ++	move.4  (a3)4++, a5 ++	move.4  (a3)4++, a6 ++	move.4  (a3)4++, a7 ++ ++	;; The frame has been saved. Call _sigjmp_save to get sigmask saved. a5 still has the return address and it will go back to that. ++#if defined(__UBICOM32_FDPIC__) ++	call	a3, __sigjmp_save ++#else ++	moveai	a3, #%hi(__sigjmp_save) ++	calli	a3, %lo(__sigjmp_save)(a3) ++#endif ++	.size __sigjmp_save, . - __sigjmp_save ++ ++	.global	__longjmp ++	.type   __longjmp,@function ++__longjmp: ++	movea	a3, d0		; A3 now holds the jmp buf that was passed in. ++	move.4  d10, (a3)4++ ++	move.4  d11, (a3)4++ ++	move.4  d12, (a3)4++ ++	move.4  d13, (a3)4++ ++	move.4  a1 , (a3)4++ ++	move.4  a2 , (a3)4++ ++	move.4  a5 , (a3)4++ ++	move.4  a6 , (a3)4++ ++	move.4  a7 , (a3)4++ ++ ++	sub.4	#0, #0, d1	; Test if d1 is zero. If it is we have to return 1 other wise return content of d1 ++	jmpeq.t	2f ++	move.4	d0, d1		; d1 is non zero load it into d0 ++	jmpt.t	3f ++ ++2:	move.4	d0, #1 ++3:	calli	a5, 0(a5) ++	.size __longjmp, . - __longjmp ++	.global __GI___longjmp ++	.hidden __GI___longjmp ++	.set __GI___longjmp,__longjmp +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/sys/procfs.h +@@ -0,0 +1,122 @@ ++/* Copyright (C) 1996, 1997, 1999, 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. ++ ++   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 somehow modelled after the file of the same name on SysVr4 ++   systems.  It provides a definition of the core file format for ELF ++   used on Linux.  */ ++ ++#include <features.h> ++#include <signal.h> ++#include <sys/time.h> ++#include <sys/types.h> ++#include <sys/ucontext.h> ++#include <bits/wordsize.h> ++ ++__BEGIN_DECLS ++ ++#define ELF_NGREG		38 ++ ++typedef struct ++  { ++    union ++      { ++	unsigned long	pr_regs[32]; ++	double		pr_dregs[16]; ++      }			pr_fr; ++    unsigned long	__unused; ++    unsigned long	pr_fsr; ++    unsigned char	pr_qcnt; ++    unsigned char	pr_q_entrysize; ++    unsigned char	pr_en; ++    unsigned int	pr_q[64]; ++  } elf_fpregset_t; ++ ++typedef unsigned long elf_greg_t; ++typedef elf_greg_t elf_gregset_t[ELF_NGREG]; ++ ++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 int pr_cursig;		/* Current signal.  */ ++    unsigned long int pr_sigpend;	/* Set of pending signals.  */ ++    unsigned long int pr_sighold;	/* Set of held signals.  */ ++    __pid_t pr_pid; ++    __pid_t pr_ppid; ++    __pid_t pr_pgrp; ++    __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 copro 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 int pr_flag;		/* Flags.  */ ++    unsigned short int pr_uid; ++    unsigned short int pr_gid; ++    int 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.  */ ++  }; ++ ++/* 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 __pid_t lwpid_t; ++ ++ ++typedef struct elf_prstatus prstatus_t; ++typedef struct elf_prpsinfo prpsinfo_t; ++ ++__END_DECLS ++ ++#endif	/* sys/procfs.h */ +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/sys/ucontext.h +@@ -0,0 +1,104 @@ ++/* Copyright (C) 1998, 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.  */ ++ ++#ifndef _SYS_UCONTEXT_H ++#define _SYS_UCONTEXT_H	1 ++ ++#include <features.h> ++#include <signal.h> ++/* ++ * Location of the users' stored registers relative to R0. ++ * Usage is as an index into a gregset_t array or as u.u_ar0[XX]. ++ */ ++#define REG_PSR (0) ++#define REG_PC  (1) ++#define REG_SPARE   (2) ++#define REG_WVALID  (3) ++#define REG_G1  (4) ++#define REG_G2  (5) ++#define REG_G3  (6) ++#define REG_G4  (7) ++#define REG_G5  (8) ++#define REG_G6  (9) ++#define REG_G7  (10) ++#define REG_O0  (11) ++#define REG_O1  (12) ++#define REG_O2  (13) ++#define REG_O3  (14) ++#define REG_O4  (15) ++#define REG_O5  (16) ++#define REG_O6  (17) ++#define REG_O7  (18) ++#define REG_GLOBALS (19) ++ ++/* ++ * A gregset_t is defined as an array type for compatibility with the reference ++ * source. This is important due to differences in the way the C language ++ * treats arrays and structures as parameters. ++ * ++ * Note that NGREG is really (sizeof (struct regs) / sizeof (greg_t)), ++ * but that the ABI defines it absolutely to be 21 (resp. 19). ++ */ ++ ++#define NGREG   20 ++typedef int greg_t; ++ ++typedef greg_t  gregset_t[NGREG]; ++ ++/* ++ * The following structures define how a register window can appear on the ++ * stack. This structure is available (when required) through the `gwins' ++ * field of an mcontext (nested within ucontext). NIOS_MAXWINDOW is the ++ * maximum number of outstanding register windows defined in the NIOS ++ * architecture (*not* implementation). ++ */ ++#define NIOS_MAXREGWINDOW	31	/* max windows in NIOS arch. */ ++struct  rwindow ++  { ++    greg_t rw_local[8];			/* locals */ ++    greg_t rw_in[8];			/* ins */ ++  }; ++ ++#define rw_fp   rw_in[6]		/* frame pointer */ ++#define rw_rtn  rw_in[7]		/* return address */ ++ ++typedef struct gwindows ++  { ++    int            wbcnt; ++    int           *spbuf[NIOS_MAXREGWINDOW]; ++    struct rwindow wbuf[NIOS_MAXREGWINDOW]; ++  } gwindows_t; ++ ++typedef struct ++  { ++    gregset_t   gregs;		/* general register set */ ++    gwindows_t  *gwins;		/* POSSIBLE pointer to register windows */ ++  } mcontext_t; ++ ++ ++/* Userlevel context.  */ ++typedef struct ucontext ++  { ++    unsigned long   uc_flags; ++    struct ucontext *uc_link; ++    __sigset_t	    uc_sigmask; ++    stack_t         uc_stack; ++    mcontext_t      uc_mcontext; ++  } ucontext_t; ++ ++#endif /* sys/ucontext.h */ +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/syscall.c +@@ -0,0 +1,32 @@ ++/* vi: set sw=4 ts=4: */ ++/* syscall for ubicom32/uClibc ++ * ++ * Copyright (C) 2008 by Ubicom Inc. ++ * Copyright (C) 2002 by Erik Andersen <andersen@uclibc.org> ++ * ++ * 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> ++ ++extern long syscall(long sysnum, long a, long b, long c, long d, long e, long f); ++long syscall(long sysnum, long a, long b, long c, long d, long e, long f) ++{ ++	int __NR_syscall_number = sysnum; ++	return (long) INLINE_SYSCALL(syscall_number, 6, a, b, c, d, e, f); ++} +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/vfork.S +@@ -0,0 +1,35 @@ ++#include <sys/syscall.h> ++ ++	.text ++	.type   vfork,@function ++	.global vfork ++vfork: ++	move.4	-4(sp)++, a5	; Save return address on the stack. ++	movei	d8, #__NR_vfork ++	moveai	a3, #%hi(0x40400000) ++	calli	a5, 0x10(a3) ++ ++	/* ++	 * You get here only if the syscall bombed. If things had worked out the ++	 * parent and child would have both returned to the instruction after ++	 * the vfork call. ++	 */ ++	move.4	a5, (sp)4++	; Pop the return address off the stack. ++	movei	d1, #-125 ++	sub.4	#0, d0, d1 ++	jmplt.t	1f ++ ++	;; We have an error. ++	sub.4	d0, #0, d0	; d0 = -res. Call __set_errno with that. ++#if defined(__UBICOM32_FDPIC__) ++	call	a3, __syscall_error ++#else ++	moveai	a3, #%hi(__syscall_error) ++	calli	a3, %lo(__syscall_error)(a3)	; __syscall_error will return -1 and not come back here. ++#endif ++1: ++	calli	a5, 0(a5) ++	.size vfork, . - vfork ++	.global __GI_vfork ++	.hidden __GI_vfork ++	.set __GI_vfork,vfork +--- a/libpthread/linuxthreads.old/pthread.c ++++ b/libpthread/linuxthreads.old/pthread.c +@@ -391,6 +391,10 @@ void __pthread_initialize_minimal(void) + #endif +  +     __libc_multiple_threads_ptr = __libc_pthread_init (ptr_pthread_functions); ++#ifndef __ARCH_USE_MMU__ ++    __pthread_initial_thread_tos = ++      (char *)(((long)CURRENT_STACK_FRAME + getpagesize()) & ~(getpagesize() - 1)); ++#endif /* __ARCH_USE_MMU__ */ + } +  +  +@@ -467,7 +471,8 @@ static void pthread_initialize(void) +    * for a few more details. +    */ +   __pthread_initial_thread_mid = CURRENT_STACK_FRAME; +-  __pthread_initial_thread_tos = (char *) -1; ++  if (__pthread_initial_thread_tos == NULL) ++    __pthread_initial_thread_tos = (char *) -1; +   __pthread_initial_thread_bos = (char *) 1; /* set it non-zero so we know we have been here */ +   PDEBUG("initial thread stack bounds: bos=%p, tos=%p\n", + 	 __pthread_initial_thread_bos, __pthread_initial_thread_tos); +--- /dev/null ++++ b/libpthread/linuxthreads.old/sysdeps/ubicom32/pt-machine.h +@@ -0,0 +1,68 @@ ++/* Machine-dependent pthreads configuration and inline functions. ++ ++   Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004 ++   Free Software Foundation, Inc. ++   This file is part of the GNU C Library. ++   Contributed by Ralf Baechle <ralf@gnu.org>. ++   Based on the Alpha version 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 ++ ++#include <features.h> ++ ++/* ++ * XXX try to make this inline ++ */ ++extern long int testandset (int *spinlock); ++ ++#ifndef PT_EI ++#define PT_EI ++#else ++/* Spinlock implementation; required.  */ ++ ++/* ++ * testandset() is the basis for the pthread spin lock. ++ * ++ * This implementation only requires that we 'set' the state of *spinlock. As ++ * bset is allows us to atomically 'testandset' a single bit define our 'set' is ++ * such that we will set bit 0 (ignoring all other bits, which should also be ++ * zero). ++ * Return value of 1 implies that the bit was already set and is still ++ * set. ++ * Return value of 0 implies that the bit was not previously set but it ++ * now is. ++ */ ++long int ++testandset (int *spinlock) ++{ ++	int ret; ++	__asm__ volatile ( ++		"	move.4	%0, #0		\n\t" /* Assume that the bit is not currently set */ ++		"	bset	%1, %1, #0	\n\t" /* Attempt to 'set' bit 0 */ ++		"	jmpeq.t	1f		\n\t" ++		"	move.4	%0, #1		\n\t" /* Bit was already set, so return 1 */ ++		" 1:				\n\t" ++		: "=r"(ret), "+U4"(*spinlock) ++		: ++		: "memory", "cc" ++		); ++	return ret; ++} ++#endif ++#endif /* pt-machine.h */ +--- /dev/null ++++ b/libpthread/linuxthreads.old/sysdeps/ubicom32/tls.h +@@ -0,0 +1,26 @@ ++/* Definitions for thread-local data handling.  linuxthreads/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 _TLS_H ++#define _TLS_H ++#ifdef HAVE_TLS_SUPPORT ++#warning no tls support ++#undef USE_TLS ++#endif ++#endif	/* tls.h */ +--- /dev/null ++++ b/libc/sysdeps/linux/ubicom32/sys/user.h +@@ -0,0 +1,40 @@ ++/* Copyright (C) 1998 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_USER_H ++#define _SYS_USER_H 1 ++ ++#include <features.h> ++ ++#include <asm/ptrace.h> ++ ++struct user { ++	struct pt_regs	regs;			/* entire machine state */ ++	size_t		u_tsize;		/* text size (pages) */ ++	size_t		u_dsize;		/* data size (pages) */ ++	size_t		u_ssize;		/* stack size (pages) */ ++	unsigned long	start_code;		/* text starting address */ ++	unsigned long	start_data;		/* data starting address */ ++	unsigned long	start_stack;		/* stack starting address */ ++	long int	signal;			/* signal causing core dump */ ++	struct regs *	u_ar0;			/* help gdb find registers */ ++	unsigned long	magic;			/* identifies a core file */ ++	char		u_comm[32];		/* user command name */ ++}; ++ ++#endif /* _SYS_USER_H */ diff --git a/toolchain/uClibc/patches-0.9.33/601-ubicom32_uClibc_fixes.patch b/toolchain/uClibc/patches-0.9.33/601-ubicom32_uClibc_fixes.patch new file mode 100644 index 000000000..d2bfdc72b --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/601-ubicom32_uClibc_fixes.patch @@ -0,0 +1,32 @@ +--- a/ldso/include/dl-elf.h ++++ b/ldso/include/dl-elf.h +@@ -45,6 +45,10 @@ extern int _dl_linux_resolve(void); + extern int _dl_fixup(struct dyn_elf *rpnt, struct r_scope_elem *scope, int flag); + extern void _dl_protect_relro (struct elf_resolve *l); +  ++#ifndef DL_LOADADDR_ISSET(_loadaddr) ++#define DL_LOADADDR_ISSET(_loadaddr) ((_loadaddr) != 0) ++#endif ++ + /* +  * Bitsize related settings for things ElfW() +  * does not handle already +@@ -206,7 +210,7 @@ unsigned int __dl_parse_dynamic_info(Elf + 	   we'd have to walk all the loadsegs to find out if it was + 	   actually unnecessary, so skip this optimization.  */ + #if !defined __FDPIC__ && !defined __DSBT__ +-	if (load_off != 0) ++	if (DL_LOADADDR_ISSET(load_off)) + #endif + 	{ + 		ADJUST_DYN_INFO(DT_HASH, load_off); +--- a/ldso/ldso/ubicom32/dl-sysdep.h ++++ b/ldso/ldso/ubicom32/dl-sysdep.h +@@ -101,6 +101,7 @@ do {									\ + } while (0) +  + #define DL_LOADADDR_TYPE struct elf32_fdpic_loadaddr ++#define DL_LOADADDR_ISSET(_loadaddr) ((_loadaddr).map != NULL) +  + #define DL_RELOC_ADDR(LOADADDR, ADDR) \ +     ((ElfW(Addr))__reloc_pointer ((void*)(ADDR), (LOADADDR).map)) diff --git a/toolchain/uClibc/patches-0.9.33/960-remove_eabi_oabi_selection.patch b/toolchain/uClibc/patches-0.9.33/960-remove_eabi_oabi_selection.patch new file mode 100644 index 000000000..19ac24695 --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33/960-remove_eabi_oabi_selection.patch @@ -0,0 +1,32 @@ +Rely on the compiler to be properly setup for the default ABI. + +When installing-headers, there are two cases: +- NPTL: no issue, a cross-compiler is already expected +- LinuxThreads: no issue, EABI/OABI has no impact on installed headers. + +Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr> +Cc: Khem Raj <raj.khem@gmail.com> +Cc: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> +Cc: Carmelo AMOROSO <carmelo.amoroso@st.com> +--- + +--- a/extra/Configs/Config.arm ++++ b/extra/Configs/Config.arm +@@ -12,17 +12,6 @@ config FORCE_OPTIONS_FOR_ARCH + 	default y + 	select ARCH_ANY_ENDIAN +  +-config CONFIG_ARM_EABI +-	bool "Build for EABI" +-	help +-	  If you say 'y' here, functions and constants required by the +-	  ARM EABI will be built into the library.  You should say 'y' +-	  if your compiler uses the ARM EABI, in which case you will also +-	  need a kernel supporting the EABI system call interface. +- +-	  If you say 'n' here, then the library will be built for the +-	  old Linux ABI. +- + config COMPILE_IN_THUMB_MODE + 	bool "Build using Thumb mode" + 	select USE_BX  | 
