diff options
Diffstat (limited to 'toolchain/uClibc')
-rw-r--r-- | toolchain/uClibc/uClibc-0.9.28-100-fix_includes.patch | 327 | ||||
-rw-r--r-- | toolchain/uClibc/uClibc-0.9.28-200-host-ldconfig.patch | 635 | ||||
-rw-r--r-- | toolchain/uClibc/uClibc-0.9.28-300-ldso.patch | 5190 | ||||
-rw-r--r-- | toolchain/uClibc/uClibc-0.9.28-400-math-endianness.patch | 247 | ||||
-rw-r--r-- | toolchain/uClibc/uClibc-0.9.28-500-mutex-cancel.patch | 8631 | ||||
-rw-r--r-- | toolchain/uClibc/uClibc-0.9.28-600-new_dst_rules.patch | 101 | ||||
-rw-r--r-- | toolchain/uClibc/uClibc-0.9.28-700-rm-whitespace.patch | 86 | ||||
-rw-r--r-- | toolchain/uClibc/uClibc-0.9.28-800-avr32-1.patch | 4433 |
8 files changed, 0 insertions, 19650 deletions
diff --git a/toolchain/uClibc/uClibc-0.9.28-100-fix_includes.patch b/toolchain/uClibc/uClibc-0.9.28-100-fix_includes.patch deleted file mode 100644 index 52c89678e..000000000 --- a/toolchain/uClibc/uClibc-0.9.28-100-fix_includes.patch +++ /dev/null @@ -1,327 +0,0 @@ ---- uClibc-0.9.28/Makefile.orig 2006-12-11 21:06:42.000000000 -0700 -+++ uClibc-0.9.28/Makefile 2006-12-11 21:06:53.000000000 -0700 -@@ -158,7 +158,7 @@ - $(INSTALL) -d $(PREFIX)$(DEVEL_PREFIX)lib - $(INSTALL) -d $(PREFIX)$(DEVEL_PREFIX)include - -$(INSTALL) -m 644 lib/*.[ao] $(PREFIX)$(DEVEL_PREFIX)lib/ -- if [ "$(KERNEL_SOURCE)" == "$(DEVEL_PREFIX)" ] ; then \ -+ if [ "$(KERNEL_SOURCE)" = "$(DEVEL_PREFIX)" ] ; then \ - extra_exclude="--exclude include/linux --exclude include/asm'*'" ; \ - else \ - extra_exclude="" ; \ ---- uClibc-0.9.28/extra/scripts/fix_includes.sh.orig 2006-12-13 05:44:21.000000000 -0700 -+++ uClibc-0.9.28/extra/scripts/fix_includes.sh 2006-12-13 05:44:35.000000000 -0700 -@@ -1,183 +1,155 @@ - #!/bin/sh --# Copyright (C) 2003 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 -- --usage () { -- echo "" -- echo "usage: "`basename $0`" -k KERNEL_SOURCE_DIRECTORY -t TARGET_ARCH" -- echo "" -- echo "This utility scans the KERNEL_SOURCE_DIRECTORY directory and" -- echo "checks that it contains well formed kernel headers suitable" -- echo "for inclusion as the include/linux/ directory provided by" -- echo "uClibc." -- echo "" -- echo "If the specified kernel headers are present and already" -- echo "configured for the architecture specified by TARGET_ARCH," -- echo "they will be used as-is." -- echo "" -- echo "If the specified kernel headers are missing entirely, this" -- echo "script will return an error." -- echo "" -- echo "If the specified kernel headers are present, but are either" -- echo "not yet configured or are configured for an architecture" -- echo "different than that specified by TARGET_ARCH, this script" -- echo "will attempt to 'fix' the kernel headers and make them" -- echo "suitable for use by uClibc. This fixing process may fail." -- echo "It is therefore best to always provide kernel headers that" -- echo "are already configured for the selected architecture." -- echo "" -- echo "Most Linux distributions provide 'kernel-headers' packages" -- echo "that are suitable for use by uClibc." -- echo "" -- echo "" -- exit 1; -+# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> -+# -+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. -+# -+ -+usage() { -+ echo "" -+ echo "usage: "`basename $0`" -k KERNEL_SOURCE_DIRECTORY -t TARGET_ARCH" -+ echo "" -+ echo "This utility scans the KERNEL_SOURCE_DIRECTORY directory and" -+ echo "checks that it contains well formed kernel headers suitable" -+ echo "for inclusion as the include/linux/ directory provided by" -+ echo "uClibc." -+ echo "" -+ echo "If the specified kernel headers are present and already" -+ echo "configured for the architecture specified by TARGET_ARCH," -+ echo "they will be used as-is." -+ echo "" -+ echo "If the specified kernel headers are missing entirely, this" -+ echo "script will return an error." -+ echo "" -+ echo "If the specified kernel headers are present, but are either" -+ echo "not yet configured or are configured for an architecture" -+ echo "different than that specified by TARGET_ARCH, this script" -+ echo "will attempt to 'fix' the kernel headers and make them" -+ echo "suitable for use by uClibc. This fixing process may fail." -+ echo "It is therefore best to always provide kernel headers that" -+ echo "are already configured for the selected architecture." -+ echo "" -+ echo "Most Linux distributions provide 'kernel-headers' packages" -+ echo "that are suitable for use by uClibc." -+ echo "" -+ echo "" -+ exit 1 - } - --HAS_MMU="y"; -+ -+# -+# Parse our arguments -+# -+HAS_MMU="y" - while [ -n "$1" ]; do -- case $1 in -- -k ) shift; if [ -n "$1" ]; then KERNEL_SOURCE=$1; shift; else usage; fi; ;; -- -t ) shift; if [ -n "$1" ]; then TARGET_ARCH=$1; shift; else usage; fi; ;; -- -n ) shift; HAS_MMU="n"; ;; -- -* ) usage; ;; -- * ) usage; ;; -- esac; --done; -+ case $1 in -+ -k ) shift; if [ -n "$1" ]; then KERNEL_SOURCE=$1; shift; else usage; fi; ;; -+ -t ) shift; if [ -n "$1" ]; then TARGET_ARCH=$1; shift; else usage; fi; ;; -+ -n ) shift; HAS_MMU="n"; ;; -+ -* ) usage; ;; -+ * ) usage; ;; -+ esac -+done - --if [ ! -f "$KERNEL_SOURCE/Makefile" -a ! -f "$KERNEL_SOURCE/include/linux/version.h" ]; then -- echo ""; -- echo ""; -- echo "The file $KERNEL_SOURCE/Makefile or $KERNEL_SOURCE/include/linux/version.h is missing!"; -- echo "Perhaps your kernel source is broken?" -- echo ""; -- echo ""; -- exit 1; --fi; - --if [ ! -d "$KERNEL_SOURCE" ]; then -- echo ""; -- echo ""; -- echo "$KERNEL_SOURCE is not a directory"; -- echo ""; -- echo ""; -- exit 1; --fi; -- --if [ -f "$KERNEL_SOURCE/Makefile" ] ; then --# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION --eval `sed -n -e 's/^\([A-Z]*\) = \([0-9]*\)$/\1=\2/p' -e 's/^\([A-Z]*\) = \(-[-a-z0-9]*\)$/\1=\2/p' $KERNEL_SOURCE/Makefile` --else --ver=`grep UTS_RELEASE $KERNEL_SOURCE/include/linux/version.h | cut -d '"' -f 2` --VERSION=`echo "$ver" | cut -d '.' -f 1` --PATCHLEVEL=`echo "$ver" | cut -d '.' -f 2` --if echo "$ver" | grep -q '-' ; then --SUBLEVEL=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.//" | cut -d '-' -f 1` --EXTRAVERSION=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}-//"` --else --SUBLEVEL=`echo "$ver" | cut -d '.' -f 3` --#EXTRAVERSION= --fi -+# -+# Perform some sanity checks on our kernel sources -+# -+if [ ! -f "$KERNEL_SOURCE/Makefile" -a ! -f "$KERNEL_SOURCE/include/linux/version.h" ]; then -+ echo "" -+ echo "" -+ echo "The file $KERNEL_SOURCE/Makefile or $KERNEL_SOURCE/include/linux/version.h is missing!" -+ echo "Perhaps your kernel source is broken?" -+ echo "" -+ echo "" -+ exit 1 - fi --if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ] --then -- echo "Unable to determine version for kernel headers" -- echo -e "\tprovided in directory $KERNEL_SOURCE" -- exit 1 -+if [ ! -d "$KERNEL_SOURCE" ]; then -+ echo "" -+ echo "" -+ echo "$KERNEL_SOURCE is not a directory" -+ echo "" -+ echo "" -+ exit 1 - fi - --if [ "$MAKE_IS_SILENT" != "y" ]; then --echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION}" --echo -e "\n" --echo "Using kernel headers from $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} for architecture '$TARGET_ARCH'" --echo -e "\tprovided in directory $KERNEL_SOURCE" --echo -e "\n" --fi - -+# - # Create a symlink to include/asm -- -+# - rm -f include/asm* - if [ ! -d "$KERNEL_SOURCE/include/asm" ]; then -- echo ""; -- echo ""; -- echo "The symlink $KERNEL_SOURCE/include/asm is missing\!"; -- echo "Perhaps you forgot to configure your kernel source?"; -- echo "You really should configure your kernel source tree so I"; -- echo "do not have to try and guess about this sort of thing."; -- echo "" -- echo "Attempting to guess a usable value...."; -- echo "" -- echo ""; -- sleep 1; -- -- if [ "$TARGET_ARCH" = "powerpc" ];then -- set -x; -- ln -fs $KERNEL_SOURCE/include/asm-ppc include/asm; -- set +x; -- elif [ "$TARGET_ARCH" = "mips" ];then -- set -x; -- ln -fs $KERNEL_SOURCE/include/asm-mips include/asm; -- set +x; -- elif [ "$TARGET_ARCH" = "arm" ];then -- set -x; -- ln -fs $KERNEL_SOURCE/include/asm-arm include/asm; -- set +x; -- if [ ! -L $KERNEL_SOURCE/include/asm-arm/proc ] ; then -- if [ ! -L proc ] ; then -- (cd include/asm; -- ln -fs proc-armv proc; -- ln -fs arch-ebsa285 arch); -- fi -+ echo "" -+ echo "" -+ echo "The symlink $KERNEL_SOURCE/include/asm is missing\!" -+ echo "Perhaps you forgot to configure your kernel source?" -+ echo "You really should configure your kernel source tree so I" -+ echo "do not have to try and guess about this sort of thing." -+ echo "" -+ echo "Attempting to guess a usable value...." -+ echo "" -+ echo "" -+ sleep 1 -+ -+ if [ "$TARGET_ARCH" = "powerpc" ]; then -+ set -x -+ ln -fs $KERNEL_SOURCE/include/asm-ppc include/asm -+ set +x -+ elif [ "$TARGET_ARCH" = "mips" ]; then -+ set -x -+ ln -fs $KERNEL_SOURCE/include/asm-mips include/asm -+ set +x -+ elif [ "$TARGET_ARCH" = "arm" ]; then -+ set -x -+ ln -fs $KERNEL_SOURCE/include/asm-arm include/asm -+ set +x -+ if [ ! -L $KERNEL_SOURCE/include/asm-arm/proc ]; then -+ if [ ! -L proc ]; then -+ ( -+ cd include/asm -+ ln -fs proc-armv proc -+ ln -fs arch-ebsa285 arch -+ ) -+ fi -+ fi -+ elif [ "$TARGET_ARCH" = "cris" ]; then -+ set -x -+ ln -fs $KERNEL_SOURCE/include/asm-cris include/asm -+ set +x -+ elif [ "$HAS_MMU" != "y" ]; then -+ if [ -d $KERNEL_SOURCE/include/asm-${TARGET_ARCH}nommu ]; then -+ set -x -+ ln -fs $KERNEL_SOURCE/include/asm-${TARGET_ARCH}nommu include/asm -+ set +x -+ else -+ set -x -+ ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm -+ set +x -+ fi -+ else -+ set -x -+ ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm -+ set +x - fi; -- elif [ "$TARGET_ARCH" = "cris" ]; then -- set -x; -- ln -fs $KERNEL_SOURCE/include/asm-cris include/asm; -- set +x; -- elif [ "$HAS_MMU" != "y" ]; then -- if [ -d $KERNEL_SOURCE/include/asm-${TARGET_ARCH}nommu ] ; then -- set -x; -- ln -fs $KERNEL_SOURCE/include/asm-${TARGET_ARCH}nommu include/asm; -- set +x; -- else -- set -x; -- ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm; -- set +x; -- fi; -- else -- set -x; -- ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm; -- set +x; -- fi; - else --# No guessing required..... --ln -fs $KERNEL_SOURCE/include/asm include/asm --if [ -e $KERNEL_SOURCE/include/asm-$TARGET_ARCH ] ; then --ln -fs $KERNEL_SOURCE/include/asm-$TARGET_ARCH include/asm-$TARGET_ARCH -+ # No guessing required..... -+ for x in $KERNEL_SOURCE/include/asm* ; do -+ ln -fs ${x} include/ -+ done - fi --fi; - - -+# - # Annoyingly, 2.6.x kernel headers also need an include/asm-generic/ directory --if [ $VERSION -eq 2 ] && [ $PATCHLEVEL -ge 6 ] ; then -- ln -fs $KERNEL_SOURCE/include/asm-generic include/asm-generic --fi; -+# -+if [ -e $KERNEL_SOURCE/include/asm-generic ]; then -+ rm -f include/asm-generic -+ ln -fs $KERNEL_SOURCE/include/asm-generic include/asm-generic -+fi - - -+# - # Create the include/linux symlink. -+# - rm -f include/linux - ln -fs $KERNEL_SOURCE/include/linux include/linux -- diff --git a/toolchain/uClibc/uClibc-0.9.28-200-host-ldconfig.patch b/toolchain/uClibc/uClibc-0.9.28-200-host-ldconfig.patch deleted file mode 100644 index f55c3498a..000000000 --- a/toolchain/uClibc/uClibc-0.9.28-200-host-ldconfig.patch +++ /dev/null @@ -1,635 +0,0 @@ -This patch supports cross-development for embedded systems by allowing the -host version of ldconfig (ldconfig.host) to build ld.so.cache for the target. -Changes include: - 1) LDSO_CACHE_SUPPORT is defined for the host build. - 2) A little-endian host can create a big-endian ld.so.cache, and vice versa. - 3) Can use -r option without chroot(), so no need to run as superuser. - -Dan Howell <dahowell@directv.com> - -diff -urN uClibc-orig/utils/chroot_realpath.c uClibc-20050502/utils/chroot_realpath.c ---- uClibc-orig/utils/chroot_realpath.c 1969-12-31 16:00:00.000000000 -0800 -+++ uClibc-20050502/utils/chroot_realpath.c 2005-09-12 18:30:29.000000000 -0700 -@@ -0,0 +1,163 @@ -+/* -+ * chroot_realpath.c -- reslove pathname as if inside chroot -+ * Based on realpath.c Copyright (C) 1993 Rick Sladkey <jrs@world.std.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Library Public License as published by -+ * the Free Software Foundation; either version 2, 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 Public License for more details. -+ * -+ * 2005/09/12: Dan Howell (modified from realpath.c to emulate chroot) -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include <config.h> -+#endif -+ -+#include <sys/types.h> -+#include <unistd.h> -+#include <stdio.h> -+#include <string.h> -+#include <strings.h> -+#include <limits.h> /* for PATH_MAX */ -+#include <sys/param.h> /* for MAXPATHLEN */ -+#include <errno.h> -+#ifndef __set_errno -+#define __set_errno(val) ((errno) = (val)) -+#endif -+ -+#include <sys/stat.h> /* for S_IFLNK */ -+ -+#ifndef PATH_MAX -+#define PATH_MAX _POSIX_PATH_MAX -+#endif -+ -+#define MAX_READLINKS 32 -+ -+char *chroot_realpath(const char *chroot, const char *path, char resolved_path[]) -+{ -+ char copy_path[PATH_MAX]; -+ char link_path[PATH_MAX]; -+ char got_path[PATH_MAX]; -+ char *got_path_root = got_path; -+ char *new_path = got_path; -+ char *max_path; -+ int readlinks = 0; -+ int n; -+ int chroot_len; -+ -+ /* Trivial case. */ -+ if (chroot == NULL || *chroot == '\0' || -+ (*chroot == '/' && chroot[1] == '\0')) { -+ strcpy(resolved_path, path); -+ return resolved_path; -+ } -+ -+ chroot_len = strlen(chroot); -+ -+ if (chroot_len + strlen(path) >= PATH_MAX - 3) { -+ __set_errno(ENAMETOOLONG); -+ return NULL; -+ } -+ -+ /* Make a copy of the source path since we may need to modify it. */ -+ strcpy(copy_path, path); -+ path = copy_path; -+ max_path = copy_path + PATH_MAX - chroot_len - 3; -+ -+ /* Start with the chroot path. */ -+ strcpy(new_path, chroot); -+ new_path += chroot_len; -+ while (*new_path == '/' && new_path > got_path) -+ new_path--; -+ got_path_root = new_path; -+ *new_path++ = '/'; -+ -+ /* Expand each slash-separated pathname component. */ -+ while (*path != '\0') { -+ /* Ignore stray "/". */ -+ if (*path == '/') { -+ path++; -+ continue; -+ } -+ if (*path == '.') { -+ /* Ignore ".". */ -+ if (path[1] == '\0' || path[1] == '/') { -+ path++; -+ continue; -+ } -+ if (path[1] == '.') { -+ if (path[2] == '\0' || path[2] == '/') { -+ path += 2; -+ /* Ignore ".." at root. */ -+ if (new_path == got_path_root + 1) -+ continue; -+ /* Handle ".." by backing up. */ -+ while ((--new_path)[-1] != '/'); -+ continue; -+ } -+ } -+ } -+ /* Safely copy the next pathname component. */ -+ while (*path != '\0' && *path != '/') { -+ if (path > max_path) { -+ __set_errno(ENAMETOOLONG); -+ return NULL; -+ } -+ *new_path++ = *path++; -+ } -+ if (*path == '\0') -+ /* Don't follow symlink for last pathname component. */ -+ break; -+#ifdef S_IFLNK -+ /* Protect against infinite loops. */ -+ if (readlinks++ > MAX_READLINKS) { -+ __set_errno(ELOOP); -+ return NULL; -+ } -+ /* See if latest pathname component is a symlink. */ -+ *new_path = '\0'; -+ n = readlink(got_path, link_path, PATH_MAX - 1); -+ if (n < 0) { -+ /* EINVAL means the file exists but isn't a symlink. */ -+ if (errno != EINVAL) { -+ /* Make sure it's null terminated. */ -+ *new_path = '\0'; -+ strcpy(resolved_path, got_path); -+ return NULL; -+ } -+ } else { -+ /* Note: readlink doesn't add the null byte. */ -+ link_path[n] = '\0'; -+ if (*link_path == '/') -+ /* Start over for an absolute symlink. */ -+ new_path = got_path_root; -+ else -+ /* Otherwise back up over this component. */ -+ while (*(--new_path) != '/'); -+ /* Safe sex check. */ -+ if (strlen(path) + n >= PATH_MAX - 2) { -+ __set_errno(ENAMETOOLONG); -+ return NULL; -+ } -+ /* Insert symlink contents into path. */ -+ strcat(link_path, path); -+ strcpy(copy_path, link_path); -+ path = copy_path; -+ } -+#endif /* S_IFLNK */ -+ *new_path++ = '/'; -+ } -+ /* Delete trailing slash but don't whomp a lone slash. */ -+ if (new_path != got_path + 1 && new_path[-1] == '/') -+ new_path--; -+ /* Make sure it's null terminated. */ -+ *new_path = '\0'; -+ strcpy(resolved_path, got_path); -+ return resolved_path; -+} -diff -urN uClibc-orig/utils/ldconfig.c uClibc-20050502/utils/ldconfig.c ---- uClibc-orig/utils/ldconfig.c 2005-05-01 23:10:12.000000000 -0700 -+++ uClibc-20050502/utils/ldconfig.c 2005-09-16 19:26:33.000000000 -0700 -@@ -22,6 +22,8 @@ - * - * This program may be used for any purpose as long as this - * copyright notice is kept. -+ * -+ * 2005/09/16: Dan Howell (modified for cross-development) - */ - - #include <stdio.h> -@@ -37,6 +39,7 @@ - #include <errno.h> - #include <sys/stat.h> - #include <sys/mman.h> -+#include "bswap.h" - #include "dl-defs.h" - - #define BUFFER_SIZE 4096 -@@ -56,6 +59,7 @@ - #if !defined (N_MAGIC) - #define N_MAGIC(exec) ((exec).a_info & 0xffff) - #endif -+#define N_MAGIC_SWAP(exec) (bswap_32((exec).a_info) & 0xffff) - /* Code indicating object file or impure executable. */ - #define OMAGIC 0407 - /* Code indicating pure executable. */ -@@ -97,6 +101,8 @@ - char *conffile = LDSO_CONF; /* default conf file */ - char *cachefile = LDSO_CACHE; /* default cache file */ - #endif -+char *chroot_dir = NULL; -+int byteswap = 0; - - struct needed_tab - { -@@ -117,6 +123,8 @@ - { NULL, LIB_ELF } - }; - -+extern char *chroot_realpath(const char *chroot, const char *path, char resolved_path[]); -+ - - /* These two are used internally -- you shouldn't need to use them */ - static void verror_msg(const char *s, va_list p) -@@ -242,6 +250,8 @@ - ElfW(Ehdr) *elf_hdr; - struct stat statbuf; - char buff[BUFFER_SIZE]; -+ char real[BUFFER_SIZE]; -+ static int byteswapflag = -1; /* start with byte-order unknown */ - - /* see if name is of the form *.so* */ - if (name[strlen(name)-1] != '~' && (cp = strstr(name, ".so"))) -@@ -256,8 +266,12 @@ - sprintf(buff, "%s%s%s", dir, (*dir && strcmp(dir, "/")) ? - "/" : "", name); - -+ /* get real path in case of chroot */ -+ if (!chroot_realpath(chroot_dir, buff, real)) -+ warn("can't resolve %s in chroot %s", buff, chroot_dir); -+ - /* first, make sure it's a regular file */ -- if (lstat(buff, &statbuf)) -+ if (lstat(real, &statbuf)) - warn("skipping %s", buff); - else if (!S_ISREG(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) - warnx("%s is not a regular file or symlink, skipping", buff); -@@ -267,14 +281,15 @@ - *islink = S_ISLNK(statbuf.st_mode); - - /* then try opening it */ -- if (!(file = fopen(buff, "rb"))) -+ if (!(file = fopen(real, "rb"))) - warn("skipping %s", buff); - else - { - /* now make sure it's a shared library */ - if (fread(&exec, sizeof exec, 1, file) < 1) - warnx("can't read header from %s, skipping", buff); -- else if (N_MAGIC(exec) != ZMAGIC && N_MAGIC(exec) != QMAGIC) -+ else if (N_MAGIC(exec) != ZMAGIC && N_MAGIC(exec) != QMAGIC && -+ N_MAGIC_SWAP(exec) != ZMAGIC && N_MAGIC_SWAP(exec) != QMAGIC) - { - elf_hdr = (ElfW(Ehdr) *) &exec; - if (elf_hdr->e_ident[0] != 0x7f || -@@ -294,6 +309,9 @@ - *type = LIB_ELF; - good = readsoname(buff, file, expected_type, type, - elf_hdr->e_ident[EI_CLASS]); -+ if (byteswapflag == -1) -+ /* byte-order detected */ -+ byteswapflag = byteswap; - if (good == NULL || *islink) - { - if (good != NULL) -@@ -313,6 +331,12 @@ - } - else - { -+ /* Determine byte-order */ -+ byteswap = (N_MAGIC(exec) == ZMAGIC || N_MAGIC(exec) == QMAGIC) ? 0 : 1; -+ if (byteswapflag == -1) -+ /* byte-order detected */ -+ byteswapflag = byteswap; -+ - if (*islink) - good = xstrdup(name); - else -@@ -330,6 +354,14 @@ - *type = LIB_DLL; - } - fclose(file); -+ -+ if (byteswapflag >= 0 && byteswap != byteswapflag) -+ { -+ byteswapflag = -2; -+ warnx("mixed byte-order detected, using host byte-order..."); -+ } -+ if (byteswapflag == -2) -+ byteswap = 0; - } - } - } -@@ -343,18 +375,24 @@ - int change = 1; - char libname[BUFFER_SIZE]; - char linkname[BUFFER_SIZE]; -+ char reallibname[BUFFER_SIZE]; -+ char reallinkname[BUFFER_SIZE]; - struct stat libstat; - struct stat linkstat; - - /* construct the full path names */ - sprintf(libname, "%s/%s", dir, file); - sprintf(linkname, "%s/%s", dir, so); -+ if (!chroot_realpath(chroot_dir, libname, reallibname)) -+ warn("can't resolve %s in chroot %s", libname, chroot_dir); -+ if (!chroot_realpath(chroot_dir, linkname, reallinkname)) -+ warn("can't resolve %s in chroot %s", linkname, chroot_dir); - - /* see if a link already exists */ -- if (!stat(linkname, &linkstat)) -+ if (!stat(reallinkname, &linkstat)) - { - /* now see if it's the one we want */ -- if (stat(libname, &libstat)) -+ if (stat(reallibname, &libstat)) - warn("can't stat %s", libname); - else if (libstat.st_dev == linkstat.st_dev && - libstat.st_ino == linkstat.st_ino) -@@ -364,14 +402,14 @@ - /* then update the link, if required */ - if (change > 0 && !nolinks) - { -- if (!lstat(linkname, &linkstat)) -+ if (!lstat(reallinkname, &linkstat)) - { - if (!S_ISLNK(linkstat.st_mode)) - { - warnx("%s is not a symlink", linkname); - change = -1; - } -- else if (remove(linkname)) -+ else if (remove(reallinkname)) - { - warn("can't unlink %s", linkname); - change = -1; -@@ -379,7 +417,7 @@ - } - if (change > 0) - { -- if (symlink(file, linkname)) -+ if (symlink(file, reallinkname)) - { - warn("can't link %s to %s", linkname, file); - change = -1; -@@ -441,6 +479,7 @@ - char *so, *path, *path_n; - struct lib *lp, *libs = NULL; - int i, libtype, islink, expected_type = LIB_ANY; -+ char realname[BUFFER_SIZE]; - - /* We need a writable copy of this string */ - path = strdup(rawname); -@@ -500,8 +539,12 @@ - if (verbose > 0) - printf("%s:\n", name); - -+ /* get real path in case of chroot */ -+ if (!chroot_realpath(chroot_dir, name, realname)) -+ warn("can't resolve %s in chroot %s", name, chroot_dir); -+ - /* if we can't open it, we can't do anything */ -- if ((dir = opendir(name)) == NULL) -+ if ((dir = opendir(realname)) == NULL) - { - warn("skipping %s", name); - free(path); -@@ -596,8 +639,12 @@ - char *res = NULL, *cp; - FILE *file; - struct stat stat; -+ char realconffile[BUFFER_SIZE]; -+ -+ if (!chroot_realpath(chroot_dir, conffile, realconffile)) -+ return NULL; - -- if ((file = fopen(conffile, "r")) != NULL) -+ if ((file = fopen(realconffile, "r")) != NULL) - { - fstat(fileno(file), &stat); - res = xmalloc(stat.st_size + 1); -@@ -678,22 +725,38 @@ - { - int cachefd; - int stroffset = 0; -+ char realcachefile[BUFFER_SIZE]; - char tempfile[BUFFER_SIZE]; -+ header_t swap_magic; -+ header_t *magic_ptr; -+ libentry_t swap_lib; -+ libentry_t *lib_ptr; - liblist_t *cur_lib; - - if (!magic.nlibs) - return; - -- sprintf(tempfile, "%s~", cachefile); -+ if (!chroot_realpath(chroot_dir, cachefile, realcachefile)) -+ err(EXIT_FATAL,"can't resolve %s in chroot %s (%s)", -+ cachefile, chroot_dir, strerror(errno)); -+ -+ sprintf(tempfile, "%s~", realcachefile); - - if (unlink(tempfile) && errno != ENOENT) -- err(EXIT_FATAL,"can't unlink %s (%s)", tempfile, strerror(errno)); -+ err(EXIT_FATAL,"can't unlink %s~ (%s)", cachefile, strerror(errno)); - - if ((cachefd = creat(tempfile, 0644)) < 0) -- err(EXIT_FATAL,"can't create %s (%s)", tempfile, strerror(errno)); -+ err(EXIT_FATAL,"can't create %s~ (%s)", cachefile, strerror(errno)); - -- if (write(cachefd, &magic, sizeof (header_t)) != sizeof (header_t)) -- err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno)); -+ if (byteswap) { -+ swap_magic = magic; -+ swap_magic.nlibs = bswap_32(swap_magic.nlibs); -+ magic_ptr = &swap_magic; -+ } else { -+ magic_ptr = &magic; -+ } -+ if (write(cachefd, magic_ptr, sizeof (header_t)) != sizeof (header_t)) -+ err(EXIT_FATAL,"can't write %s~ (%s)", cachefile, strerror(errno)); - - for (cur_lib = lib_head; cur_lib != NULL; cur_lib = cur_lib->next) - { -@@ -701,29 +764,37 @@ - stroffset += strlen(cur_lib->soname) + 1; - cur_lib->liboffset = stroffset; - stroffset += strlen(cur_lib->libname) + 1; -- if (write(cachefd, cur_lib, sizeof (libentry_t)) != -- sizeof (libentry_t)) -- err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno)); -+ if (byteswap) { -+ swap_lib.flags = bswap_32(cur_lib->flags); -+ swap_lib.sooffset = bswap_32(cur_lib->sooffset); -+ swap_lib.liboffset = bswap_32(cur_lib->liboffset); -+ lib_ptr = &swap_lib; -+ } else { -+ lib_ptr = (libentry_t *)cur_lib; -+ } -+ if (write(cachefd, lib_ptr, sizeof (libentry_t)) != -+ sizeof (libentry_t)) -+ err(EXIT_FATAL,"can't write %s~ (%s)", cachefile, strerror(errno)); - } - - for (cur_lib = lib_head; cur_lib != NULL; cur_lib = cur_lib->next) - { - if (write(cachefd, cur_lib->soname, strlen(cur_lib->soname) + 1) - != strlen(cur_lib->soname) + 1) -- err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno)); -+ err(EXIT_FATAL,"can't write %s~ (%s)", cachefile, strerror(errno)); - if (write(cachefd, cur_lib->libname, strlen(cur_lib->libname) + 1) - != strlen(cur_lib->libname) + 1) -- err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno)); -+ err(EXIT_FATAL,"can't write %s~ (%s)", cachefile, strerror(errno)); - } - - if (close(cachefd)) -- err(EXIT_FATAL,"can't close %s (%s)", tempfile, strerror(errno)); -+ err(EXIT_FATAL,"can't close %s~ (%s)", cachefile, strerror(errno)); - - if (chmod(tempfile, 0644)) -- err(EXIT_FATAL,"can't chmod %s (%s)", tempfile, strerror(errno)); -+ err(EXIT_FATAL,"can't chmod %s~ (%s)", cachefile, strerror(errno)); - -- if (rename(tempfile, cachefile)) -- err(EXIT_FATAL,"can't rename %s (%s)", tempfile, strerror(errno)); -+ if (rename(tempfile, realcachefile)) -+ err(EXIT_FATAL,"can't rename %s~ (%s)", cachefile, strerror(errno)); - } - - void cache_print(void) -@@ -734,8 +805,13 @@ - char *strs; - header_t *header; - libentry_t *libent; -+ char realcachefile[BUFFER_SIZE]; -+ -+ if (!chroot_realpath(chroot_dir, cachefile, realcachefile)) -+ err(EXIT_FATAL,"can't resolve %s in chroot %s (%s)", -+ cachefile, chroot_dir, strerror(errno)); - -- if (stat(cachefile, &st) || (fd = open(cachefile, O_RDONLY))<0) -+ if (stat(realcachefile, &st) || (fd = open(realcachefile, O_RDONLY))<0) - err(EXIT_FATAL,"can't read %s (%s)", cachefile, strerror(errno)); - if ((c = mmap(0,st.st_size, PROT_READ, MAP_SHARED ,fd, 0)) == (caddr_t)-1) - err(EXIT_FATAL,"can't map %s (%s)", cachefile, strerror(errno)); -@@ -828,7 +904,6 @@ - int nodefault = 0; - char *cp, *dir, *so; - int libtype, islink; -- char *chroot_dir = NULL; - int printcache = 0; - #ifdef __LDSO_CACHE_SUPPORT__ - char *extpath; -@@ -891,10 +966,16 @@ - } - - if (chroot_dir && *chroot_dir) { -- if (chroot(chroot_dir) < 0) -- err(EXIT_FATAL,"couldn't chroot to %s (%s)", chroot_dir, strerror(errno)); -- if (chdir("/") < 0) -- err(EXIT_FATAL,"couldn't chdir to / (%s)", strerror(errno)); -+ if (chroot(chroot_dir) < 0) { -+ if (chdir(chroot_dir) < 0) -+ err(EXIT_FATAL,"couldn't chroot to %s (%s)", chroot_dir, strerror(errno)); -+ } -+ else -+ { -+ if (chdir("/") < 0) -+ err(EXIT_FATAL,"couldn't chdir to / (%s)", strerror(errno)); -+ chroot_dir = NULL; -+ } - } - - /* allow me to introduce myself, hi, my name is ... */ -diff -urN uClibc-orig/utils/Makefile uClibc-20050502/utils/Makefile ---- uClibc-orig/utils/Makefile 2005-05-01 23:10:12.000000000 -0700 -+++ uClibc-20050502/utils/Makefile 2005-09-16 19:28:55.000000000 -0700 -@@ -29,6 +29,12 @@ - TARGET_ICONV = - endif - -+ifeq ($(strip $(LDSO_CACHE_SUPPORT)),y) -+HOST_LDSO_CACHE_FLAG = -D__LDSO_CACHE_SUPPORT__=1 -+else -+HOST_LDSO_CACHE_FLAG = -+endif -+ - # NOTE: We build the utils AFTER we have a uClibc-targeted toolchain. - - ifeq ($(strip $(HAVE_SHARED)),y) -@@ -51,7 +57,7 @@ - else - LDCONFIG_CFLAGS := $(PIEFLAG) $(LDPIEFLAG) - endif --ldconfig: ldconfig.c -+ldconfig: ldconfig.c chroot_realpath.c - $(CC) $(CFLAGS) $(LDCONFIG_CFLAGS) \ - -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \ - -DUCLIBC_LDSO=$(UCLIBC_LDSO) -I. -I../ldso/include \ -@@ -79,13 +85,13 @@ - - ldd.host: ldd.c - $(HOSTCC) $(HOSTCFLAGS) -Wl,-s \ -- -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \ -+ -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" $(HOST_LDSO_CACHE_FLAG) \ - -DUCLIBC_LDSO=$(UCLIBC_LDSO) -I. -I../ldso/include \ - $^ -o $@ - --ldconfig.host: ldconfig.c -+ldconfig.host: ldconfig.c chroot_realpath.c - $(HOSTCC) $(HOSTCFLAGS) -Wl,-s \ -- -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \ -+ -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" $(HOST_LDSO_CACHE_FLAG) \ - -DUCLIBC_LDSO=$(UCLIBC_LDSO) -I. -I../ldso/include \ - $^ -o $@ - -diff -urN uClibc-orig/utils/readsoname2.c uClibc-20050502/utils/readsoname2.c ---- uClibc-orig/utils/readsoname2.c 2005-05-01 23:10:12.000000000 -0700 -+++ uClibc-20050502/utils/readsoname2.c 2005-09-16 17:48:59.000000000 -0700 -@@ -26,7 +26,7 @@ - - if (fstat(fileno(infile), &st)) - return NULL; -- header = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fileno(infile), 0); -+ header = mmap(0, st.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(infile), 0); - if (header == (caddr_t)-1) - return NULL; - -@@ -34,6 +34,19 @@ - if ((char *)(epnt+1) > (char *)(header + st.st_size)) - goto skip; - -+#if __BYTE_ORDER == __LITTLE_ENDIAN -+ byteswap = (epnt->e_ident[5] == ELFDATA2MSB) ? 1 : 0; -+#elif __BYTE_ORDER == __BIG_ENDIAN -+ byteswap = (epnt->e_ident[5] == ELFDATA2LSB) ? 1 : 0; -+#else -+#error Unknown host byte order! -+#endif -+ /* Be very lazy, and only byteswap the stuff we use */ -+ if (byteswap==1) { -+ epnt->e_phoff=bswap_32(epnt->e_phoff); -+ epnt->e_phnum=bswap_16(epnt->e_phnum); -+ } -+ - ppnt = (ElfW(Phdr) *)&header[epnt->e_phoff]; - if ((char *)ppnt < (char *)header || - (char *)(ppnt+epnt->e_phnum) > (char *)(header + st.st_size)) -@@ -41,6 +54,14 @@ - - for(i = 0; i < epnt->e_phnum; i++) - { -+ /* Be very lazy, and only byteswap the stuff we use */ -+ if (byteswap==1) { -+ ppnt->p_type=bswap_32(ppnt->p_type); -+ ppnt->p_vaddr=bswap_32(ppnt->p_vaddr); -+ ppnt->p_offset=bswap_32(ppnt->p_offset); -+ ppnt->p_filesz=bswap_32(ppnt->p_filesz); -+ } -+ - if (loadaddr == -1 && ppnt->p_type == PT_LOAD) - loadaddr = (ppnt->p_vaddr & ~(page_size-1)) - - (ppnt->p_offset & ~(page_size-1)); -@@ -58,11 +79,20 @@ - (char *)(dpnt+dynamic_size) > (char *)(header + st.st_size)) - goto skip; - -+ if (byteswap==1) { -+ dpnt->d_tag=bswap_32(dpnt->d_tag); -+ dpnt->d_un.d_val=bswap_32(dpnt->d_un.d_val); -+ } -+ - while (dpnt->d_tag != DT_NULL) - { - if (dpnt->d_tag == DT_STRTAB) - strtab_val = dpnt->d_un.d_val; - dpnt++; -+ if (byteswap==1) { -+ dpnt->d_tag=bswap_32(dpnt->d_tag); -+ dpnt->d_un.d_val=bswap_32(dpnt->d_un.d_val); -+ } - }; - - if (!strtab_val) diff --git a/toolchain/uClibc/uClibc-0.9.28-300-ldso.patch b/toolchain/uClibc/uClibc-0.9.28-300-ldso.patch deleted file mode 100644 index 4081fc7d1..000000000 --- a/toolchain/uClibc/uClibc-0.9.28-300-ldso.patch +++ /dev/null @@ -1,5190 +0,0 @@ -diff -urN uClibc-0.9.28.orig/include/elf.h uClibc-0.9.28/include/elf.h ---- uClibc-0.9.28.orig/include/elf.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/include/elf.h 2006-04-28 00:14:35.000000000 -0600 -@@ -142,6 +142,7 @@ - #define ELFOSABI_HPUX 1 /* HP-UX */ - #define ELFOSABI_NETBSD 2 /* NetBSD. */ - #define ELFOSABI_LINUX 3 /* Linux. */ -+#define ELFOSABI_HURD 4 /* GNU/Hurd */ - #define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ - #define ELFOSABI_AIX 7 /* IBM AIX. */ - #define ELFOSABI_IRIX 8 /* SGI Irix. */ -@@ -149,6 +150,9 @@ - #define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ - #define ELFOSABI_MODESTO 11 /* Novell Modesto. */ - #define ELFOSABI_OPENBSD 12 /* OpenBSD. */ -+#define ELFOSABI_OPENVMS 13 /* OpenVMS */ -+#define ELFOSABI_NSK 14 /* Hewlett-Packard Non-Stop Kernel */ -+#define ELFOSABI_AROS 15 /* Amiga Research OS */ - #define ELFOSABI_ARM 97 /* ARM */ - #define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ - -@@ -177,6 +181,7 @@ - #define EM_386 3 /* Intel 80386 */ - #define EM_68K 4 /* Motorola m68k family */ - #define EM_88K 5 /* Motorola m88k family */ -+#define EM_486 6 /* Intel 80486 *//* Reserved for future use */ - #define EM_860 7 /* Intel 80860 */ - #define EM_MIPS 8 /* MIPS R3000 big-endian */ - #define EM_S370 9 /* IBM System/370 */ -@@ -193,7 +198,8 @@ - #define EM_V800 36 /* NEC V800 series */ - #define EM_FR20 37 /* Fujitsu FR20 */ - #define EM_RH32 38 /* TRW RH-32 */ --#define EM_RCE 39 /* Motorola RCE */ -+#define EM_MCORE 39 /* Motorola M*Core */ /* May also be taken by Fujitsu MMA */ -+#define EM_RCE 39 /* Old name for MCore */ - #define EM_ARM 40 /* ARM */ - #define EM_FAKE_ALPHA 41 /* Digital Alpha */ - #define EM_SH 42 /* Renesas SH */ -@@ -248,18 +254,105 @@ - #define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ - #define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ - #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ -+#define EM_IP2K 101 /* Ubicom IP2022 micro controller */ -+#define EM_CR 103 /* National Semiconductor CompactRISC */ -+#define EM_MSP430 105 /* TI msp430 micro controller */ -+#define EM_BLACKFIN 106 /* Analog Devices Blackfin */ -+#define EM_ALTERA_NIOS2 113 /* Altera Nios II soft-core processor */ -+#define EM_CRX 114 /* National Semiconductor CRX */ - #define EM_NUM 95 - --/* If it is necessary to assign new unofficial EM_* values, please -- pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the -- chances of collision with official or non-GNU unofficial values. */ -+/* If it is necessary to assign new unofficial EM_* values, please pick large -+ random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision -+ with official or non-GNU unofficial values. - --/* Fujitsu FR-V. */ -+ NOTE: Do not just increment the most recent number by one. -+ Somebody else somewhere will do exactly the same thing, and you -+ will have a collision. Instead, pick a random number. -+ -+ Normally, each entity or maintainer responsible for a machine with an -+ unofficial e_machine number should eventually ask registry@caldera.com for -+ an officially blessed number to be added to the list above. */ -+ -+/* picoJava */ -+#define EM_PJ_OLD 99 -+ -+/* Cygnus PowerPC ELF backend. Written in the absence of an ABI. */ -+#define EM_CYGNUS_POWERPC 0x9025 -+ -+/* Old version of Sparc v9, from before the ABI; this should be -+ removed shortly. */ -+#define EM_OLD_SPARCV9 11 -+ -+/* Old version of PowerPC, this should be removed shortly. */ -+#define EM_PPC_OLD 17 -+ -+/* (Deprecated) Temporary number for the OpenRISC processor. */ -+#define EM_OR32 0x8472 -+ -+/* Renesas M32C and M16C. */ -+#define EM_M32C 0xFEB0 -+ -+/* Cygnus M32R ELF backend. Written in the absence of an ABI. */ -+#define EM_CYGNUS_M32R 0x9041 -+ -+/* old S/390 backend magic number. Written in the absence of an ABI. */ -+#define EM_S390_OLD 0xa390 -+ -+/* D10V backend magic number. Written in the absence of an ABI. */ -+#define EM_CYGNUS_D10V 0x7650 -+ -+/* D30V backend magic number. Written in the absence of an ABI. */ -+#define EM_CYGNUS_D30V 0x7676 -+ -+/* V850 backend magic number. Written in the absense of an ABI. */ -+#define EM_CYGNUS_V850 0x9080 -+ -+/* mn10200 and mn10300 backend magic numbers. -+ Written in the absense of an ABI. */ -+#define EM_CYGNUS_MN10200 0xdead -+#define EM_CYGNUS_MN10300 0xbeef -+ -+/* FR30 magic number - no EABI available. */ -+#define EM_CYGNUS_FR30 0x3330 -+ -+/* AVR magic number -+ Written in the absense of an ABI. */ -+#define EM_AVR_OLD 0x1057 -+ -+/* OpenRISC magic number -+ Written in the absense of an ABI. */ -+#define EM_OPENRISC_OLD 0x3426 -+ -+/* DLX magic number -+ Written in the absense of an ABI. */ -+#define EM_DLX 0x5aa5 -+ -+#define EM_XSTORMY16 0xad45 -+ -+/* FRV magic number - no EABI available??. */ - #define EM_CYGNUS_FRV 0x5441 - -+/* Ubicom IP2xxx; no ABI */ -+#define EM_IP2K_OLD 0x8217 -+ -+#define EM_MT 0x2530 /* Morpho MT; no ABI */ -+ -+/* MSP430 magic number -+ Written in the absense everything. */ -+#define EM_MSP430_OLD 0x1059 -+ -+/* Vitesse IQ2000. */ -+#define EM_IQ2000 0xFEBA -+ -+/* Old, unofficial value for Xtensa. */ -+#define EM_XTENSA_OLD 0xabc7 -+ -+/* Alpha backend magic number. Written in the absence of an ABI. */ - #define EM_ALPHA 0x9026 --#define EM_NIOS32 0xfebb /* Altera Nios 32 */ --#define EM_ALTERA_NIOS2 0x9ee5 /* Altera Nios II */ -+ -+/* NIOS magic number - no EABI available. */ -+#define EM_NIOS32 0xFEBB - - /* V850 backend magic number. Written in the absense of an ABI. */ - #define EM_CYGNUS_V850 0x9080 -@@ -2498,6 +2591,12 @@ - #define R_390_NUM 61 - - -+/* CRIS flags. */ -+#define EF_CRIS_VARIANT_MASK 0x0000000e -+#define EF_CRIS_VARIANT_ANY_V0_V10 0x00000000 -+#define EF_CRIS_VARIANT_V32 0x00000002 -+#define EF_CRIS_VARIANT_COMMON_V10_V32 0x00000004 -+ - /* CRIS relocations. */ - #define R_CRIS_NONE 0 - #define R_CRIS_8 1 -@@ -2688,6 +2787,7 @@ - #define R_V850_NUM 25 - - -+/* Renesas H8/300 Relocations */ - #define R_H8_NONE 0 - #define R_H8_DIR32 1 - #define R_H8_DIR32_28 2 -@@ -2731,8 +2831,7 @@ - #define R_H8_DIR32A16 63 - #define R_H8_ABS32 65 - #define R_H8_ABS32A16 127 -- --/* Altera NIOS specific definitions. */ -+#define R_H8_NUM 128 - - /* NIOS relocations. */ - #define R_NIOS_NONE 0 -diff -urN uClibc-0.9.28.orig/include/errno.h uClibc-0.9.28/include/errno.h ---- uClibc-0.9.28.orig/include/errno.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/include/errno.h 2006-04-28 00:14:35.000000000 -0600 -@@ -43,9 +43,11 @@ - variable. This redeclaration using the macro still works, but it - will be a function declaration without a prototype and may trigger - a -Wstrict-prototypes warning. */ -+#ifndef __ASSEMBLER__ - #ifndef errno - extern int errno; - #endif -+#endif - - #if 0 /*def __USE_GNU uClibc note: not supported */ - -diff -urN uClibc-0.9.28.orig/ldso/Makefile uClibc-0.9.28/ldso/Makefile ---- uClibc-0.9.28.orig/ldso/Makefile 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/Makefile 2006-04-28 00:14:35.000000000 -0600 -@@ -37,15 +37,12 @@ - - LN_HEADERS := $(patsubst %, include/%, elf.h) - LN_ARCH_HEADERS := $(patsubst %, include/%, dl-startup.h dl-syscalls.h dl-sysdep.h dl-debug.h) --HEADERS := $(LN_HEADERS) $(LN_ARCH_HEADERS) include/dl-progname.h -+HEADERS := $(LN_HEADERS) $(LN_ARCH_HEADERS) - headers: $(HEADERS) - $(LN_HEADERS): - $(LN) -fs $(TOPDIR)../$@ $@ - $(LN_ARCH_HEADERS): - $(LN) -fs ../ldso/$(TARGET_ARCH)/$(patsubst include/%,%,$@) $@ --include/dl-progname.h: -- echo '#include "$(TARGET_ARCH)/elfinterp.c"' \ -- > include/dl-progname.h - - clean: - set -e ; for d in $(DIRS) ; do $(MAKE) -C $$d $@ ; done -diff -urN uClibc-0.9.28.orig/ldso/include/dl-defs.h uClibc-0.9.28/ldso/include/dl-defs.h ---- uClibc-0.9.28.orig/ldso/include/dl-defs.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/include/dl-defs.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,6 +1,29 @@ -+/* vi: set sw=4 ts=4: */ -+/* -+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org> -+ * -+ * GNU Lesser General Public License version 2.1 or later. -+ */ -+ - #ifndef _LD_DEFS_H - #define _LD_DEFS_H - -+#define FLAG_ANY -1 -+#define FLAG_TYPE_MASK 0x00ff -+#define FLAG_LIBC4 0x0000 -+#define FLAG_ELF 0x0001 -+#define FLAG_ELF_LIBC5 0x0002 -+#define FLAG_ELF_LIBC6 0x0003 -+#define FLAG_ELF_UCLIBC 0x0004 -+#define FLAG_REQUIRED_MASK 0xff00 -+#define FLAG_SPARC_LIB64 0x0100 -+#define FLAG_IA64_LIB64 0x0200 -+#define FLAG_X8664_LIB64 0x0300 -+#define FLAG_S390_LIB64 0x0400 -+#define FLAG_POWERPC_LIB64 0x0500 -+#define FLAG_MIPS64_LIBN32 0x0600 -+#define FLAG_MIPS64_LIBN64 0x0700 -+ - #define LIB_ANY -1 - #define LIB_DLL 0 - #define LIB_ELF 1 -diff -urN uClibc-0.9.28.orig/ldso/include/dl-elf.h uClibc-0.9.28/ldso/include/dl-elf.h ---- uClibc-0.9.28.orig/ldso/include/dl-elf.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/include/dl-elf.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,3 +1,10 @@ -+/* vi: set sw=4 ts=4: */ -+/* -+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org> -+ * -+ * GNU Lesser General Public License version 2.1 or later. -+ */ -+ - #ifndef LINUXELF_H - #define LINUXELF_H - -diff -urN uClibc-0.9.28.orig/ldso/include/dl-hash.h uClibc-0.9.28/ldso/include/dl-hash.h ---- uClibc-0.9.28.orig/ldso/include/dl-hash.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/include/dl-hash.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,3 +1,10 @@ -+/* vi: set sw=4 ts=4: */ -+/* -+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org> -+ * -+ * GNU Lesser General Public License version 2.1 or later. -+ */ -+ - #ifndef _LD_HASH_H_ - #define _LD_HASH_H_ - -@@ -32,15 +39,15 @@ - unsigned short usage_count; - unsigned short int init_flag; - unsigned long rtld_flags; /* RTLD_GLOBAL, RTLD_NOW etc. */ -- Elf32_Word nbucket; -- Elf32_Word *elf_buckets; -+ Elf_Symndx nbucket; -+ Elf_Symndx *elf_buckets; - struct init_fini_list *init_fini; - struct init_fini_list *rtld_local; /* keep tack of RTLD_LOCAL libs in same group */ - /* - * These are only used with ELF style shared libraries - */ -- Elf32_Word nchain; -- Elf32_Word *chains; -+ Elf_Symndx nchain; -+ Elf_Symndx *chains; - unsigned long dynamic_info[DYNAMIC_SIZE]; - - unsigned long n_phent; -@@ -49,6 +56,9 @@ - ElfW(Addr) relro_addr; - size_t relro_size; - -+ dev_t st_dev; /* device */ -+ ino_t st_ino; /* inode */ -+ - #ifdef __powerpc__ - /* this is used to store the address of relocation data words, so - * we don't have to calculate it every time, which requires a divide */ -@@ -66,7 +76,6 @@ - extern struct elf_resolve * _dl_loaded_modules; - extern struct dyn_elf * _dl_handles; - --extern struct elf_resolve * _dl_check_hashed_files(const char * libname); - extern struct elf_resolve * _dl_add_elf_hash_table(const char * libname, - char * loadaddr, unsigned long * dynamic_info, - unsigned long dynamic_addr, unsigned long dynamic_size); -diff -urN uClibc-0.9.28.orig/ldso/include/dl-string.h uClibc-0.9.28/ldso/include/dl-string.h ---- uClibc-0.9.28.orig/ldso/include/dl-string.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/include/dl-string.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,9 +1,24 @@ -+/* vi: set sw=4 ts=4: */ -+/* -+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org> -+ * -+ * GNU Lesser General Public License version 2.1 or later. -+ */ -+ - #ifndef _LINUX_STRING_H_ - #define _LINUX_STRING_H_ - --#include <dl-sysdep.h> // for do_rem -+#include <dl-sysdep.h> /* for do_rem */ - #include <features.h> - -+/* provide some sane defaults */ -+#ifndef do_rem -+# define do_rem(result, n, base) ((result) = (n) % (base)) -+#endif -+#ifndef do_div_10 -+# define do_div_10(result, remain) ((result) /= 10) -+#endif -+ - static size_t _dl_strlen(const char * str); - static char *_dl_strcat(char *dst, const char *src); - static char * _dl_strcpy(char * dst,const char *src); -@@ -26,8 +41,8 @@ - static __always_inline size_t _dl_strlen(const char * str) - { - register const char *ptr = (char *) str-1; -- -- while (*++ptr); -+ while (*++ptr) -+ ;/* empty */ - return (ptr - str); - } - -@@ -49,7 +64,8 @@ - register char *ptr = dst; - - dst--;src--; -- while ((*++dst = *++src) != 0); -+ while ((*++dst = *++src) != 0) -+ ;/* empty */ - - return ptr; - } -@@ -63,8 +79,7 @@ - c2 = (unsigned char) *++s2; - if (c1 == '\0') - return c1 - c2; -- } -- while (c1 == c2); -+ } while (c1 == c2); - - return c1 - c2; - } -@@ -98,43 +113,41 @@ - return 0; - } - --static inline char * _dl_strrchr(const char *str, int c) -+static __always_inline char * _dl_strrchr(const char *str, int c) - { -- register char *prev = 0; -- register char *ptr = (char *) str-1; -+ register char *prev = 0; -+ register char *ptr = (char *) str-1; - -- while (*++ptr != '\0') { -- if (*ptr == c) -- prev = ptr; -- } -- if (c == '\0') -- return(ptr); -- return(prev); -+ while (*++ptr != '\0') { -+ if (*ptr == c) -+ prev = ptr; -+ } -+ if (c == '\0') -+ return(ptr); -+ return(prev); - } - --static inline char * _dl_strstr(const char *s1, const char *s2) -+static __always_inline char * _dl_strstr(const char *s1, const char *s2) - { -- register const char *s = s1; -- register const char *p = s2; -+ register const char *s = s1; -+ register const char *p = s2; - -- do { -- if (!*p) { -- return (char *) s1;; -- } -- if (*p == *s) { -- ++p; -- ++s; -- } else { -- p = s2; -- if (!*s) { -- return NULL; -- } -- s = ++s1; -- } -- } while (1); -+ do { -+ if (!*p) -+ return (char *) s1;; -+ if (*p == *s) { -+ ++p; -+ ++s; -+ } else { -+ p = s2; -+ if (!*s) -+ return NULL; -+ s = ++s1; -+ } -+ } while (1); - } - --static inline void * _dl_memcpy(void * dst, const void * src, size_t len) -+static __always_inline void * _dl_memcpy(void * dst, const void * src, size_t len) - { - register char *a = dst-1; - register const char *b = src-1; -@@ -163,27 +176,28 @@ - /* Will generate smaller and faster code due to loop unrolling.*/ - static __always_inline void * _dl_memset(void *to, int c, size_t n) - { -- unsigned long chunks; -- unsigned long *tmp_to; -+ unsigned long chunks; -+ unsigned long *tmp_to; - unsigned char *tmp_char; - -- chunks = n / 4; -- tmp_to = to + n; -- c = c << 8 | c; -- c = c << 16 | c; -- if (!chunks) -- goto lessthan4; -- do { -- *--tmp_to = c; -- } while (--chunks); -- lessthan4: -- n = n % 4; -- if (!n ) return to; -- tmp_char = (unsigned char *)tmp_to; -- do { -- *--tmp_char = c; -- } while (--n); -- return to; -+ chunks = n / 4; -+ tmp_to = to + n; -+ c = c << 8 | c; -+ c = c << 16 | c; -+ if (!chunks) -+ goto lessthan4; -+ do { -+ *--tmp_to = c; -+ } while (--chunks); -+lessthan4: -+ n = n % 4; -+ if (!n) -+ return to; -+ tmp_char = (unsigned char *)tmp_to; -+ do { -+ *--tmp_char = c; -+ } while (--n); -+ return to; - } - #else - static __always_inline void * _dl_memset(void * str,int c,size_t len) -@@ -225,10 +239,10 @@ - char *p = &local[22]; - *--p = '\0'; - do { -- char temp; -- do_rem(temp, i, 10); -- *--p = '0' + temp; -- i /= 10; -+ char temp; -+ do_rem(temp, i, 10); -+ *--p = '0' + temp; -+ do_div_10(i, temp); - } while (i > 0); - return p; - } -@@ -242,9 +256,9 @@ - do { - char temp = i & 0xf; - if (temp <= 0x09) -- *--p = '0' + temp; -+ *--p = '0' + temp; - else -- *--p = 'a' - 0x0a + temp; -+ *--p = 'a' - 0x0a + temp; - i >>= 4; - } while (i > 0); - *--p = 'x'; -@@ -270,8 +284,8 @@ - - /* On some arches constant strings are referenced through the GOT. - * This requires that load_addr must already be defined... */ --#if defined(mc68000) || defined(__arm__) || defined(__mips__) \ -- || defined(__sh__) || defined(__powerpc__) -+#if defined(mc68000) || defined(__arm__) || defined(__thumb__) || \ -+ defined(__mips__) || defined(__sh__) || defined(__powerpc__) - # define CONSTANT_STRING_GOT_FIXUP(X) \ - if ((X) < (const char *) load_addr) (X) += load_addr - # define NO_EARLY_SEND_STDERR -@@ -318,7 +332,7 @@ - do { \ - do_rem(v, (X), 10); \ - *--tmp2 = '0' + v; \ -- (X) /= 10; \ -+ do_div_10((X), v); \ - } while ((X) > 0); \ - _dl_write(2, tmp2, tmp1 - tmp2 + sizeof(tmp) - 1); \ - } -diff -urN uClibc-0.9.28.orig/ldso/include/dl-syscall.h uClibc-0.9.28/ldso/include/dl-syscall.h ---- uClibc-0.9.28.orig/ldso/include/dl-syscall.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/include/dl-syscall.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,3 +1,10 @@ -+/* vi: set sw=4 ts=4: */ -+/* -+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org> -+ * -+ * GNU Lesser General Public License version 2.1 or later. -+ */ -+ - #ifndef _LD_SYSCALL_H_ - #define _LD_SYSCALL_H_ - -@@ -12,9 +19,8 @@ - #include <bits/kernel_stat.h> - #include <bits/kernel_types.h> - -- - /* _dl_open() parameters */ --#define O_RDONLY 0x0000 -+#define O_RDONLY 00 - #define O_WRONLY 01 - #define O_RDWR 02 - #define O_CREAT 0100 -@@ -39,18 +45,6 @@ - #define S_IWRITE 0200 /* Write by owner. */ - #define S_IEXEC 0100 /* Execute by owner. */ - --/* Stuff for _dl_mmap */ --#if 0 --#define MAP_FAILED ((void *) -1) --#define _dl_mmap_check_error(X) (((void *)X) == MAP_FAILED) --#else --#ifndef _dl_MAX_ERRNO --#define _dl_MAX_ERRNO 4096 --#endif --#define _dl_mmap_check_error(__res) \ -- (((long)__res) < 0 && ((long)__res) >= -_dl_MAX_ERRNO) --#endif -- - - - /* Here are the definitions for some syscalls that are used -@@ -66,54 +60,125 @@ - static inline _syscall1(int, _dl_close, int, fd); - - #define __NR__dl_open __NR_open --static inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode); -+static inline _syscall3(int, _dl_open, const char *, fn, int, flags, -+ __kernel_mode_t, mode); - - #define __NR__dl_write __NR_write - static inline _syscall3(unsigned long, _dl_write, int, fd, -- const void *, buf, unsigned long, count); -+ const void *, buf, unsigned long, count); - - #define __NR__dl_read __NR_read - static inline _syscall3(unsigned long, _dl_read, int, fd, -- const void *, buf, unsigned long, count); -+ const void *, buf, unsigned long, count); - - #define __NR__dl_mprotect __NR_mprotect --static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot); -+static inline _syscall3(int, _dl_mprotect, const void *, addr, -+ unsigned long, len, int, prot); - - #define __NR__dl_stat __NR_stat --static inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf); -+static inline _syscall2(int, _dl_stat, const char *, file_name, -+ struct stat *, buf); -+ -+#define __NR__dl_fstat __NR_fstat -+static inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf); - - #define __NR__dl_munmap __NR_munmap - static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length); - -+#ifdef __NR_getxuid -+# define __NR_getuid __NR_getxuid -+#endif - #define __NR__dl_getuid __NR_getuid - static inline _syscall0(uid_t, _dl_getuid); - -+#ifndef __NR_geteuid -+# define __NR_geteuid __NR_getuid -+#endif - #define __NR__dl_geteuid __NR_geteuid - static inline _syscall0(uid_t, _dl_geteuid); - -+#ifdef __NR_getxgid -+# define __NR_getgid __NR_getxgid -+#endif - #define __NR__dl_getgid __NR_getgid - static inline _syscall0(gid_t, _dl_getgid); - -+#ifndef __NR_getegid -+# define __NR_getegid __NR_getgid -+#endif - #define __NR__dl_getegid __NR_getegid - static inline _syscall0(gid_t, _dl_getegid); - -+#ifdef __NR_getxpid -+# define __NR_getpid __NR_getxpid -+#endif - #define __NR__dl_getpid __NR_getpid - static inline _syscall0(gid_t, _dl_getpid); - - #define __NR__dl_readlink __NR_readlink --static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz); -+static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, -+ size_t, bufsiz); - --#ifdef __NR_mmap --#ifdef MMAP_HAS_6_ARGS --#define __NR__dl_mmap __NR_mmap --static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length, -- int, prot, int, flags, int, fd, off_t, offset); -+#ifdef __UCLIBC_HAS_SSP__ -+# include <sys/time.h> -+# define __NR__dl_gettimeofday __NR_gettimeofday -+static inline _syscall2(int, _dl_gettimeofday, struct timeval *, tv, -+# ifdef __USE_BSD -+ struct timezone *, tz); -+# else -+ void *, tz); -+# endif -+#endif -+ -+ -+/* handle all the fun mmap intricacies */ -+#if (defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap)) || !defined(__NR_mmap2) -+# define _dl_MAX_ERRNO 4096 -+# define _dl_mmap_check_error(__res) \ -+ (((long)__res) < 0 && ((long)__res) >= -_dl_MAX_ERRNO) - #else --#define __NR__dl_mmap_real __NR_mmap --static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer); -+# define MAP_FAILED ((void *) -1) -+# define _dl_mmap_check_error(X) (((void *)X) == MAP_FAILED) -+#endif -+ -+/* first try mmap(), syscall6() style */ -+#if defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap) -+ -+# define __NR__dl_mmap __NR_mmap -+static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length, -+ int, prot, int, flags, int, fd, off_t, offset); -+ -+/* then try mmap2() */ -+#elif defined(__NR_mmap2) -+ -+# 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); -+ -+/* Some architectures always use 12 as page shift for mmap2() eventhough the -+ * real PAGE_SHIFT != 12. Other architectures use the same value as -+ * PAGE_SHIFT... -+ */ -+#ifndef MMAP2_PAGE_SHIFT -+# define MMAP2_PAGE_SHIFT 12 -+#endif - - static inline void * _dl_mmap(void * addr, unsigned long size, int prot, -- int flags, int fd, unsigned long offset) -+ int flags, int fd, unsigned long offset) -+{ -+ if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1)) -+ return MAP_FAILED; -+ return __syscall_mmap2(addr, size, prot, flags, -+ fd, (off_t) (offset >> MMAP2_PAGE_SHIFT)); -+} -+ -+/* finally, fall back to mmap(), syscall1() style */ -+#elif defined(__NR_mmap) -+ -+# define __NR__dl_mmap_real __NR_mmap -+static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer); -+static inline void * _dl_mmap(void * addr, unsigned long size, int prot, -+ int flags, int fd, unsigned long offset) - { - unsigned long buffer[6]; - -@@ -125,24 +190,9 @@ - buffer[5] = (unsigned long) offset; - return (void *) _dl_mmap_real(buffer); - } --#endif --#elif defined __NR_mmap2 --#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); --/*always 12, even on architectures where PAGE_SHIFT != 12 */ --#define MMAP2_PAGE_SHIFT 12 --static inline void * _dl_mmap(void * addr, unsigned long size, int prot, -- int flags, int fd, unsigned long offset) --{ -- if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1)) -- return MAP_FAILED; -- return(__syscall_mmap2(addr, size, prot, flags, -- fd, (off_t) (offset >> MMAP2_PAGE_SHIFT))); --} -+ - #else --#error "Your architecture doesn't seem to provide mmap() !?" -+# error "Your architecture doesn't seem to provide mmap() !?" - #endif - - #endif /* _LD_SYSCALL_H_ */ -- -diff -urN uClibc-0.9.28.orig/ldso/include/dlfcn.h uClibc-0.9.28/ldso/include/dlfcn.h ---- uClibc-0.9.28.orig/ldso/include/dlfcn.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/include/dlfcn.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,3 +1,10 @@ -+/* vi: set sw=4 ts=4: */ -+/* -+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org> -+ * -+ * GNU Lesser General Public License version 2.1 or later. -+ */ -+ - /* User functions for run-time dynamic loading. libdl version */ - #ifndef _DLFCN_H - #define _DLFCN_H 1 -diff -urN uClibc-0.9.28.orig/ldso/include/ldso.h uClibc-0.9.28/ldso/include/ldso.h ---- uClibc-0.9.28.orig/ldso/include/ldso.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/include/ldso.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,3 +1,10 @@ -+/* vi: set sw=4 ts=4: */ -+/* -+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org> -+ * -+ * GNU Lesser General Public License version 2.1 or later. -+ */ -+ - #ifndef _LDSO_H_ - #define _LDSO_H_ - -@@ -20,13 +27,15 @@ - /* Pull in compiler and arch stuff */ - #include <stdlib.h> - #include <stdarg.h> -+#include <bits/wordsize.h> - /* Pull in the arch specific type information */ - #include <sys/types.h> -+/* Pull in the arch specific page size */ -+#include <bits/uClibc_page.h> -+#define attribute_unused __attribute__ ((unused)) - /* Pull in the ldso syscalls and string functions */ - #include <dl-syscall.h> - #include <dl-string.h> --/* Pull in the arch specific page size */ --#include <bits/uClibc_page.h> - /* Now the ldso specific headers */ - #include <dl-elf.h> - #include <dl-hash.h> -diff -urN uClibc-0.9.28.orig/ldso/include/unsecvars.h uClibc-0.9.28/ldso/include/unsecvars.h ---- uClibc-0.9.28.orig/ldso/include/unsecvars.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/include/unsecvars.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,3 +1,10 @@ -+/* vi: set sw=4 ts=4: */ -+/* -+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org> -+ * -+ * GNU Lesser General Public License version 2.1 or later. -+ */ -+ - /* - * Environment variable to be removed for SUID programs. The names are all - * stuffed in a single string which means they have to be terminated with a -@@ -5,22 +12,21 @@ - */ - - #define UNSECURE_ENVVARS \ -- "LD_AOUT_PRELOAD\0" \ -- "LD_AOUT_LIBRARY_PATH\0" \ - "LD_PRELOAD\0" \ - "LD_LIBRARY_PATH\0" \ - "LD_DEBUG\0" \ - "LD_DEBUG_OUTPUT\0" \ - "LD_TRACE_LOADED_OBJECTS\0" \ -- "HOSTALIASES\0" \ -- "LOCALDOMAIN\0" \ -- "RES_OPTIONS\0" \ - "TMPDIR\0" - - /* -+ * LD_TRACE_LOADED_OBJECTS is not in glibc-2.3.5's unsecvars.h -+ * though used by ldd -+ * - * These environment variables are defined by glibc but ignored in - * uClibc, but may very well have an equivalent in uClibc. - * -- * MALLOC_TRACE, RESOLV_HOST_CONF, TZDIR, GCONV_PATH, LD_USE_LOAD_BIAS, -- * LD_PROFILE, LD_ORIGIN_PATH, LOCPATH, NLSPATH -+ * LD_ORIGIN_PATH, LD_PROFILE, LD_USE_LOAD_BIAS, LD_DYNAMIC_WEAK, LD_SHOW_AUXV, -+ * GCONV_PATH, GETCONF_DIR, HOSTALIASES, LOCALDOMAIN, LOCPATH, MALLOC_TRACE, -+ * NLSPATH, RESOLV_HOST_CONF, RES_OPTIONS, TZDIR - */ -diff -urN uClibc-0.9.28.orig/ldso/ldso/Makefile uClibc-0.9.28/ldso/ldso/Makefile ---- uClibc-0.9.28.orig/ldso/ldso/Makefile 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/Makefile 2006-04-28 00:14:35.000000000 -0600 -@@ -42,7 +42,9 @@ - endif - XXFLAGS+= -DUCLIBC_LDSO=\"$(UCLIBC_LDSO)\" $(XARCH_CFLAGS) $(CPU_CFLAGS) $(PICFLAG) \ - -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \ -- -fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)ldso/include -I. -I$(TOPDIR)include -+ -fno-builtin -nostdinc -D_LIBC \ -+ -DLDSO_ELFINTERP=\"$(TARGET_ARCH)/elfinterp.c\" \ -+ -I$(TOPDIR)ldso/ldso/$(TARGET_ARCH) -I$(TOPDIR)ldso/include -I$(TOPDIR)ldso/ldso -I$(TOPDIR)include - - # BEWARE!!! At least mips* will die if -O0 is used!!! - XXFLAGS:=$(XXFLAGS:-O0=-O1) -diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/dl-startup.h uClibc-0.9.28/ldso/ldso/arm/dl-startup.h ---- uClibc-0.9.28.orig/ldso/ldso/arm/dl-startup.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/arm/dl-startup.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,10 +1,15 @@ - /* vi: set sw=4 ts=4: */ - /* - * Architecture specific code used by dl-startup.c -- * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org> -+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> -+ * -+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - */ - --asm( -+#include <features.h> -+ -+#if !defined(__thumb__) -+__asm__( - " .text\n" - " .globl _start\n" - " .type _start,%function\n" -@@ -40,7 +45,78 @@ - " ldr r0, .L_FINI_PROC\n" - " ldr r0, [sl, r0]\n" - " @ jump to the user_s entry point\n" -+#if defined(__USE_BX__) -+ " bx r6\n" -+#else -+ " mov pc, r6\n" -+#endif -+ ".L_GET_GOT:\n" -+ " .word _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n" -+ ".L_SKIP_ARGS:\n" -+ " .word _dl_skip_args(GOTOFF)\n" -+ ".L_FINI_PROC:\n" -+ " .word _dl_fini(GOT)\n" -+ "\n\n" -+ " .size _start,.-_start\n" -+ ".previous\n" -+); -+#else -+__asm__( -+ " .text\n" -+ " .arm\n" -+ " .globl _start\n" -+ " .type _start,%function\n" -+ "_start:\n" -+ " @ dumb: can't persuade the linker to make the start address\n" -+ " @ odd, so use an arm function and change to thumb (_dl_start\n" -+ " @ is thumb)\n" -+ " adr r0, __dl_thumb_start+1\n" -+ " bx r0\n" -+ "\n\n" -+ " .thumb\n" -+ " .globl __dl_thumb_start\n" -+ " .thumb_func\n" -+ " .type __dl_thumb_start,%function\n" -+ "__dl_thumb_start:\n" -+ " @ at start time, all the args are on the stack\n" -+ " mov r0, sp\n" -+ " bl _dl_start\n" -+ " @ returns user entry point in r0\n" -+ " mov r6, r0\n" -+ " @ we are PIC code, so get global offset table\n" -+ " ldr r7, .L_GET_GOT\n" -+ ".L_GOT_GOT:\n" -+ " add r7, pc\n" -+ " @ See if we were run as a command with the executable file\n" -+ " @ name as an extra leading argument.\n" -+ " ldr r4, .L_SKIP_ARGS\n" -+ " ldr r4, [r7, r4]\n" -+ " @ get the original arg count\n" -+ " ldr r1, [sp]\n" -+ " @ subtract _dl_skip_args from it\n" -+ " sub r1, r1, r4\n" -+ " @ adjust the stack pointer to skip them\n" -+ " lsl r4, r4, #2\n" -+ " add sp, r4\n" -+ " @ get the argv address\n" -+ " add r2, sp, #4\n" -+ " @ store the new argc in the new stack location\n" -+ " str r1, [sp]\n" -+ " @ compute envp\n" -+ " lsl r3, r1, #2\n" -+ " add r3, r3, r2\n" -+ " add r3, #4\n" -+ "\n\n" -+ " @ load the finalizer function\n" -+ " ldr r0, .L_FINI_PROC\n" -+ " ldr r0, [r7, r0]\n" -+ " @ jump to the user_s entry point\n" -+#if defined(__USE_BX__) -+ " bx r6\n" -+#else - " mov pc, r6\n" -+#endif -+ "\n\n" - ".L_GET_GOT:\n" - " .word _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n" - ".L_SKIP_ARGS:\n" -@@ -51,6 +127,7 @@ - " .size _start,.-_start\n" - ".previous\n" - ); -+#endif - - - /* Get a pointer to the argv array. On many platforms this can be just -@@ -115,9 +192,3 @@ - _dl_exit(1); - } - } -- -- --/* Transfer control to the user's application, once the dynamic loader is -- * done. This routine has to exit the current function, then call the -- * _dl_elf_main function. */ --#define START() return _dl_elf_main; -diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/dl-syscalls.h uClibc-0.9.28/ldso/ldso/arm/dl-syscalls.h ---- uClibc-0.9.28.orig/ldso/ldso/arm/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/arm/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,6 +1,7 @@ - /* 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/syscall.h" - -diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/dl-sysdep.h uClibc-0.9.28/ldso/ldso/arm/dl-sysdep.h ---- uClibc-0.9.28.orig/ldso/ldso/arm/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/arm/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600 -@@ -43,6 +43,7 @@ - return m; - } - #define do_rem(result, n, base) ((result) = arm_modulus(n, base)) -+#define do_div_10(result, remain) ((result) = (((result) - (remain)) / 2) * -(-1ul / 5ul)) - - /* Here we define the magic numbers that this dynamic loader should accept */ - #define MAGIC1 EM_ARM -@@ -85,7 +86,25 @@ - extern void __dl_start asm ("_dl_start"); - Elf32_Addr got_addr = (Elf32_Addr) &__dl_start; - Elf32_Addr pcrel_addr; -+#if !defined __thumb__ - asm ("adr %0, _dl_start" : "=r" (pcrel_addr)); -+#else -+ int tmp; -+ /* The above adr will not work on thumb because it -+ * is negative. The only safe way is to temporarily -+ * swap to arm. -+ */ -+ asm( ".align 2\n" -+ " bx pc\n" -+ " nop \n" -+ " .arm \n" -+ " adr %0, _dl_start\n" -+ " .align 2\n" -+ " orr %1, pc, #1\n" -+ " bx %1\n" -+ " .force_thumb\n" -+ : "=r" (pcrel_addr), "=&r" (tmp)); -+#endif - return pcrel_addr - got_addr; - } - -diff -urN uClibc-0.9.28.orig/ldso/ldso/arm/elfinterp.c uClibc-0.9.28/ldso/ldso/arm/elfinterp.c ---- uClibc-0.9.28.orig/ldso/ldso/arm/elfinterp.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/arm/elfinterp.c 2006-04-28 00:14:35.000000000 -0600 -@@ -38,6 +38,8 @@ - a more than adequate job of explaining everything required to get this - working. */ - -+#include "ldso.h" -+ - extern int _dl_linux_resolve(void); - - unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) -@@ -63,7 +65,6 @@ - strtab = (char *) tpnt->dynamic_info[DT_STRTAB]; - symname = strtab + symtab[symtab_index].st_name; - -- - if (unlikely(reloc_type != R_ARM_JUMP_SLOT)) { - _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n", - _dl_progname); -diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/dl-startup.h uClibc-0.9.28/ldso/ldso/cris/dl-startup.h ---- uClibc-0.9.28.orig/ldso/ldso/cris/dl-startup.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/cris/dl-startup.h 2006-04-28 00:14:35.000000000 -0600 -@@ -4,22 +4,43 @@ - - /* This code fixes the stack pointer so that the dynamic linker - * can find argc, argv and auxvt (Auxillary Vector Table). */ -+#ifdef __arch_v32 -+ -+asm("" \ -+" .text\n" \ -+" .globl _start\n" \ -+" .type _start,@function\n" \ -+"_start:\n" \ -+" move.d $sp,$r10\n" \ -+" lapc _dl_start,$r9\n" \ -+" jsr $r9\n" \ -+" nop\n" \ -+" moveq 0,$r8\n" \ -+" jump $r10\n" \ -+" move $r8,$srp\n" \ -+" .size _start,.-_start\n" \ -+" .previous\n" \ -+); -+ -+#else -+ - asm("" \ - " .text\n" \ - " .globl _start\n" \ - " .type _start,@function\n" \ - "_start:\n" \ --" move.d $sp,$r10\n" \ --" move.d $pc,$r9\n" \ --" add.d _dl_start - ., $r9\n" \ --" jsr $r9\n" \ --" moveq 0,$r8\n" \ --" move $r8,$srp\n" \ --" jump $r10\n" \ -+" move.d $sp,$r10\n" \ -+" move.d $pc,$r9\n" \ -+" add.d _dl_start - ., $r9\n" \ -+" jsr $r9\n" \ -+" moveq 0,$r8\n" \ -+" move $r8,$srp\n" \ -+" jump $r10\n" \ - " .size _start,.-_start\n" \ - " .previous\n" \ - ); - -+#endif /* __arch_v32 */ - - /* 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 -@@ -58,8 +79,3 @@ - break; - } - } -- --/* Transfer control to the user's application, once the dynamic loader is -- * done. This routine has to exit the current function, then call the -- * _dl_elf_main function. */ --#define START() return _dl_elf_main -diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/dl-syscalls.h uClibc-0.9.28/ldso/ldso/cris/dl-syscalls.h ---- uClibc-0.9.28.orig/ldso/ldso/cris/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/cris/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,5 +1,6 @@ - /* 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/syscall.h" -diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/dl-sysdep.h uClibc-0.9.28/ldso/ldso/cris/dl-sysdep.h ---- uClibc-0.9.28.orig/ldso/ldso/cris/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/cris/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600 -@@ -18,8 +18,6 @@ - struct elf_resolve; - extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry); - --#define do_rem(result, n, base) ((result) = (n) % (base)) -- - /* 8192 bytes alignment */ - #define PAGE_ALIGN 0xffffe000 - #define ADDR_ALIGN 0x1fff -@@ -68,8 +66,32 @@ - { - Elf32_Addr gotaddr_diff; - -+#ifdef __arch_v32 -+ extern char ___CRISv32_dummy[] __asm__ ("_dl_start"); -+ -+ __asm__ ("addo.w _dl_start:GOT16,$r0,$acr\n\t" -+ "lapc _dl_start,%0\n\t" -+ "sub.d [$acr],%0" -+ /* For v32, we need to force GCC to have R0 loaded with -+ _GLOBAL_OFFSET_TABLE_ at this point, which might not -+ otherwise have happened in the caller. (For v10, it's -+ loaded for non-global variables too, so we don't need -+ anything special there.) We accomplish this by faking the -+ address of a global variable (as seen by GCC) as input to -+ the asm; that address calculation goes through the GOT. -+ Use of this function happens before we've filled in the -+ GOT, so the address itself will not be correctly -+ calculated, therefore we don't use any symbol whose -+ address may be re-used later on. Let's just reuse the -+ _dl_start symbol, faking it as a global by renaming it as -+ another variable through an asm. */ -+ : "=r" (gotaddr_diff) -+ : "g" (___CRISv32_dummy) -+ : "acr"); -+#else - __asm__ ("sub.d [$r0+_dl_start:GOT16],$r0,%0\n\t" - "add.d _dl_start:GOTOFF,%0" : "=r" (gotaddr_diff)); -+#endif - return gotaddr_diff; - } - -diff -urN uClibc-0.9.28.orig/ldso/ldso/cris/resolve.S uClibc-0.9.28/ldso/ldso/cris/resolve.S ---- uClibc-0.9.28.orig/ldso/ldso/cris/resolve.S 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/cris/resolve.S 2006-04-28 00:14:35.000000000 -0600 -@@ -17,33 +17,73 @@ - .globl _dl_linux_resolve - .type _dl_linux_resolve,@function - -+#ifdef __arch_v32 -+ -+_dl_linux_resolve: -+ subq 4,$sp -+ move.d $r0,[$sp] -+ subq 4,$sp -+ move.d $r13,[$sp] -+ subq 4,$sp -+ move.d $r12,[$sp] -+ subq 4,$sp -+ move.d $r11,[$sp] -+ subq 4,$sp -+ addoq 5*4,$sp,$acr -+ move.d $r10,[$sp] -+ subq 4,$sp -+ move $mof,$r10 -+ move.d $r9,[$sp] -+ subq 4,$sp -+ move.d [$acr],$r11 -+ move $srp,[$sp] -+ lapc _GLOBAL_OFFSET_TABLE_,$r0 -+ move.d _dl_linux_resolver:PLTG,$r9 -+ add.d $r0,$r9 -+ jsr $r9 -+ nop -+ move.d $r10,$acr -+ move [$sp+],$srp -+ move.d [$sp+],$r9 -+ move.d [$sp+],$r10 -+ move.d [$sp+],$r11 -+ move.d [$sp+],$r12 -+ move.d [$sp+],$r13 -+ move.d [$sp+],$r0 -+ jump $acr -+ addq 4,$sp -+ -+#else -+ - _dl_linux_resolve: -- push $r13 -- push $r12 -- push $r11 -- push $r10 -- push $r9 -- push $r0 -- push $srp -- move.d [$sp+7*4],$r11 -- move $mof,$r10 -+ push $r13 -+ push $r12 -+ push $r11 -+ push $r10 -+ push $r9 -+ push $r0 -+ push $srp -+ move.d [$sp+7*4],$r11 -+ move $mof,$r10 - #ifdef __PIC__ -- move.d $pc,$r0 -- sub.d .:GOTOFF,$r0 -- move.d _dl_linux_resolver:PLTG,$r9 -- add.d $r0,$r9 -- jsr $r9 -+ move.d $pc,$r0 -+ sub.d .:GOTOFF,$r0 -+ move.d _dl_linux_resolver:PLTG,$r9 -+ add.d $r0,$r9 -+ jsr $r9 - #else -- jsr _dl_linux_resolver -+ jsr _dl_linux_resolver - #endif -- move.d $r10,[$sp+7*4] -- pop $srp -- pop $r0 -- pop $r9 -- pop $r10 -- pop $r11 -- pop $r12 -- pop $r13 -- jump [$sp+] -+ move.d $r10,[$sp+7*4] -+ pop $srp -+ pop $r0 -+ pop $r9 -+ pop $r10 -+ pop $r11 -+ pop $r12 -+ pop $r13 -+ jump [$sp+] -+ -+#endif /* __arch_v32 */ - - .size _dl_linux_resolve, . - _dl_linux_resolve -diff -urN uClibc-0.9.28.orig/ldso/ldso/dl-elf.c uClibc-0.9.28/ldso/ldso/dl-elf.c ---- uClibc-0.9.28.orig/ldso/ldso/dl-elf.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/dl-elf.c 2006-05-02 13:50:58.000000000 -0600 -@@ -3,7 +3,7 @@ - * This file contains the helper routines to load an ELF shared - * library into memory and add the symbol table info to the chain. - * -- * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org> -+ * Copyright (C) 2000-2006 by Erik Andersen <andersen@codepoet.org> - * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, - * David Engel, Hongjiu Lu and Mitch D'Souza - * -@@ -60,8 +60,8 @@ - _dl_cache_addr = (caddr_t) _dl_mmap(0, _dl_cache_size, PROT_READ, MAP_SHARED, fd, 0); - _dl_close(fd); - if (_dl_mmap_check_error(_dl_cache_addr)) { -- _dl_dprintf(2, "%s: can't map cache '%s'\n", -- _dl_progname, LDSO_CACHE); -+ _dl_dprintf(2, "%s:%i: can't map '%s'\n", -+ _dl_progname, __LINE__, LDSO_CACHE); - return -1; - } - -@@ -115,7 +115,7 @@ - #endif - - --void -+void - _dl_protect_relro (struct elf_resolve *l) - { - ElfW(Addr) start = ((l->loadaddr + l->relro_addr) -@@ -136,27 +136,41 @@ - search_for_named_library(const char *name, int secure, const char *path_list, - struct dyn_elf **rpnt) - { -- char *path, *path_n; -- char mylibname[2050]; -+ char *path, *path_n, *mylibname; - struct elf_resolve *tpnt; -- int done = 0; -+ int done; - - if (path_list==NULL) - return NULL; - -- /* We need a writable copy of this string */ -- path = _dl_strdup(path_list); -- if (!path) { -+ /* We need a writable copy of this string, but we don't -+ * need this allocated permanently since we don't want -+ * to leak memory, so use alloca to put path on the stack */ -+ done = _dl_strlen(path_list); -+ path = alloca(done + 1); -+ -+ /* another bit of local storage */ -+ mylibname = alloca(2050); -+ -+ /* gcc inlines alloca using a single instruction adjusting -+ * the stack pointer and no stack overflow check and thus -+ * no NULL error return. No point leaving in dead code... */ -+#if 0 -+ if (!path || !mylibname) { - _dl_dprintf(2, "Out of memory!\n"); - _dl_exit(0); - } -+#endif -+ -+ _dl_memcpy(path, path_list, done+1); - - /* Unlike ldd.c, don't bother to eliminate double //s */ - - /* Replace colons with zeros in path_list */ - /* : at the beginning or end of path maps to CWD */ - /* :: anywhere maps CWD */ -- /* "" maps to CWD */ -+ /* "" maps to CWD */ -+ done = 0; - path_n = path; - do { - if (*path == 0) { -@@ -180,71 +194,6 @@ - return NULL; - } - --/* Check if the named library is already loaded... */ --struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname, -- int trace_loaded_objects) --{ -- const char *pnt, *pnt1; -- struct elf_resolve *tpnt1; -- const char *libname, *libname2; -- static const char libc[] = "libc.so."; -- static const char aborted_wrong_lib[] = "%s: aborted attempt to load %s!\n"; -- -- pnt = libname = full_libname; -- -- _dl_if_debug_dprint("Checking if '%s' is already loaded\n", full_libname); -- /* quick hack to ensure mylibname buffer doesn't overflow. don't -- allow full_libname or any directory to be longer than 1024. */ -- if (_dl_strlen(full_libname) > 1024) -- return NULL; -- -- /* Skip over any initial initial './' and '/' stuff to -- * get the short form libname with no path garbage */ -- pnt1 = _dl_strrchr(pnt, '/'); -- if (pnt1) { -- libname = pnt1 + 1; -- } -- -- /* Make sure they are not trying to load the wrong C library! -- * This sometimes happens esp with shared libraries when the -- * library path is somehow wrong! */ --#define isdigit(c) (c >= '0' && c <= '9') -- if ((_dl_strncmp(libname, libc, 8) == 0) && _dl_strlen(libname) >=8 && -- isdigit(libname[8])) -- { -- /* Abort attempts to load glibc, libc5, etc */ -- if ( libname[8]!='0') { -- if (!trace_loaded_objects) { -- _dl_dprintf(2, aborted_wrong_lib, libname, _dl_progname); -- _dl_exit(1); -- } -- return NULL; -- } -- } -- -- /* Critical step! Weed out duplicates early to avoid -- * function aliasing, which wastes memory, and causes -- * really bad things to happen with weaks and globals. */ -- for (tpnt1 = _dl_loaded_modules; tpnt1; tpnt1 = tpnt1->next) { -- -- /* Skip over any initial initial './' and '/' stuff to -- * get the short form libname with no path garbage */ -- libname2 = tpnt1->libname; -- pnt1 = _dl_strrchr(libname2, '/'); -- if (pnt1) { -- libname2 = pnt1 + 1; -- } -- -- if (_dl_strcmp(libname2, libname) == 0) { -- /* Well, that was certainly easy */ -- return tpnt1; -- } -- } -- -- return NULL; --} -- -- - /* Used to return error codes back to dlopen et. al. */ - unsigned long _dl_error_number; - unsigned long _dl_internal_error_number; -@@ -271,14 +220,6 @@ - libname = pnt + 1; - } - -- /* Critical step! Weed out duplicates early to avoid -- * function aliasing, which wastes memory, and causes -- * really bad things to happen with weaks and globals. */ -- if ((tpnt1=_dl_check_if_named_library_is_loaded(libname, trace_loaded_objects))!=NULL) { -- tpnt1->usage_count++; -- return tpnt1; -- } -- - _dl_if_debug_dprint("\tfind library='%s'; searching\n", libname); - /* If the filename has any '/', try it straight and leave it at that. - For IBCS2 compatibility under linux, we substitute the string -@@ -290,7 +231,6 @@ - if (tpnt1) { - return tpnt1; - } -- //goto goof; - } - - /* -@@ -411,56 +351,45 @@ - int i, flags, piclib, infile; - ElfW(Addr) relro_addr = 0; - size_t relro_size = 0; -- -- /* If this file is already loaded, skip this step */ -- tpnt = _dl_check_hashed_files(libname); -- if (tpnt) { -- if (*rpnt) { -- (*rpnt)->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf)); -- _dl_memset((*rpnt)->next, 0, sizeof(struct dyn_elf)); -- (*rpnt)->next->prev = (*rpnt); -- *rpnt = (*rpnt)->next; -- (*rpnt)->dyn = tpnt; -- tpnt->symbol_scope = _dl_symbol_tables; -- } -- tpnt->usage_count++; -- tpnt->libtype = elf_lib; -- _dl_if_debug_dprint("file='%s'; already loaded\n", libname); -- return tpnt; -- } -- -- /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD), -- we don't load the library if it isn't setuid. */ -- -- if (secure) { -- struct stat st; -- -- if (_dl_stat(libname, &st) || !(st.st_mode & S_ISUID)) -- return NULL; -- } -+ struct stat st; - - libaddr = 0; - infile = _dl_open(libname, O_RDONLY, 0); - if (infile < 0) { --#if 0 -- /* -- * NO! When we open shared libraries we may search several paths. -- * it is inappropriate to generate an error here. -- */ -- _dl_dprintf(2, "%s: can't open '%s'\n", _dl_progname, libname); --#endif - _dl_internal_error_number = LD_ERROR_NOFILE; - return NULL; - } - -+ if (_dl_fstat(infile, &st) < 0) { -+ _dl_internal_error_number = LD_ERROR_NOFILE; -+ _dl_close(infile); -+ return NULL; -+ } -+ /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD), -+ we don't load the library if it isn't setuid. */ -+ if (secure) -+ if (!(st.st_mode & S_ISUID)) { -+ _dl_close(infile); -+ return NULL; -+ } -+ -+ /* Check if file is already loaded */ -+ for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) { -+ if(tpnt->st_dev == st.st_dev && tpnt->st_ino == st.st_ino) { -+ /* Already loaded */ -+ tpnt->usage_count++; -+ _dl_close(infile); -+ return tpnt; -+ } -+ } - header = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (_dl_mmap_check_error(header)) { -- _dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname); -+ _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname); - _dl_internal_error_number = LD_ERROR_MMAP_FAILED; - _dl_close(infile); - return NULL; -- }; -+ } - - _dl_read(infile, header, _dl_pagesize); - epnt = (ElfW(Ehdr) *) (intptr_t) header; -@@ -475,7 +404,7 @@ - _dl_close(infile); - _dl_munmap(header, _dl_pagesize); - return NULL; -- }; -+ } - - if ((epnt->e_type != ET_DYN) || (epnt->e_machine != MAGIC1 - #ifdef MAGIC2 -@@ -490,7 +419,7 @@ - _dl_close(infile); - _dl_munmap(header, _dl_pagesize); - return NULL; -- }; -+ } - - ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff]; - -@@ -502,7 +431,7 @@ - _dl_dprintf(2, "%s: '%s' has more than one dynamic section\n", - _dl_progname, libname); - dynamic_addr = ppnt->p_vaddr; -- }; -+ } - - if (ppnt->p_type == PT_LOAD) { - /* See if this is a PIC library. */ -@@ -518,7 +447,7 @@ - } - } - ppnt++; -- }; -+ } - - maxvma = (maxvma + ADDR_ALIGN) & ~ADDR_ALIGN; - minvma = minvma & ~0xffffU; -@@ -530,12 +459,12 @@ - status = (char *) _dl_mmap((char *) (piclib ? 0 : minvma), - maxvma - minvma, PROT_NONE, flags | MAP_ANONYMOUS, -1, 0); - if (_dl_mmap_check_error(status)) { -- _dl_dprintf(2, "%s: can't map %s\n", _dl_progname, libname); -+ _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname); - _dl_internal_error_number = LD_ERROR_MMAP_FAILED; - _dl_close(infile); - _dl_munmap(header, _dl_pagesize); - return NULL; -- }; -+ } - libaddr = (unsigned long) status; - flags |= MAP_FIXED; - -@@ -567,14 +496,14 @@ - ppnt->p_offset & OFFS_ALIGN); - - if (_dl_mmap_check_error(status)) { -- _dl_dprintf(2, "%s: can't map '%s'\n", -- _dl_progname, libname); -+ _dl_dprintf(2, "%s:%i: can't map '%s'\n", -+ _dl_progname, __LINE__, libname); - _dl_internal_error_number = LD_ERROR_MMAP_FAILED; - _dl_munmap((char *) libaddr, maxvma - minvma); - _dl_close(infile); - _dl_munmap(header, _dl_pagesize); - return NULL; -- }; -+ } - - /* Pad the last page with zeroes. */ - cpnt = (char *) (status + (ppnt->p_vaddr & ADDR_ALIGN) + -@@ -601,21 +530,21 @@ - ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags, - infile, ppnt->p_offset & OFFS_ALIGN); - if (_dl_mmap_check_error(status)) { -- _dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname); -+ _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname); - _dl_internal_error_number = LD_ERROR_MMAP_FAILED; - _dl_munmap((char *) libaddr, maxvma - minvma); - _dl_close(infile); - _dl_munmap(header, _dl_pagesize); - return NULL; -- }; -+ } - - /* if(libaddr == 0 && piclib) { - libaddr = (unsigned long) status; - flags |= MAP_FIXED; -- }; */ -- }; -+ } */ -+ } - ppnt++; -- }; -+ } - _dl_close(infile); - - /* For a non-PIC library, the addresses are all absolute */ -@@ -665,6 +594,8 @@ - dynamic_addr, 0); - tpnt->relro_addr = relro_addr; - tpnt->relro_size = relro_size; -+ tpnt->st_dev = st.st_dev; -+ tpnt->st_ino = st.st_ino; - tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff); - tpnt->n_phent = epnt->e_phnum; - -@@ -693,7 +624,7 @@ - if (lpnt) { - lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT]); - INIT_GOT(lpnt, tpnt); -- }; -+ } - - _dl_if_debug_dprint("\n\tfile='%s'; generating link map\n", libname); - _dl_if_debug_dprint("\t\tdynamic: %x base: %x\n", dynamic_addr, libaddr); -@@ -714,10 +645,12 @@ - ElfW(Addr) reloc_addr; - - if (rpnt->next) -- goof += _dl_fixup(rpnt->next, now_flag); -+ goof = _dl_fixup(rpnt->next, now_flag); -+ if (goof) -+ return goof; - tpnt = rpnt->dyn; - -- if(!(tpnt->init_flag & RELOCS_DONE)) -+ if(!(tpnt->init_flag & RELOCS_DONE)) - _dl_if_debug_dprint("relocation processing: %s\n", tpnt->libname); - - if (unlikely(tpnt->dynamic_info[UNSUPPORTED_RELOC_TYPE])) { -@@ -735,7 +668,6 @@ - #endif - if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR] && - !(tpnt->init_flag & RELOCS_DONE)) { -- tpnt->init_flag |= RELOCS_DONE; - reloc_addr = tpnt->dynamic_info[DT_RELOC_TABLE_ADDR]; - relative_count = tpnt->dynamic_info[DT_RELCONT_IDX]; - if (relative_count) { /* Optimize the XX_RELATIVE relocations if possible */ -@@ -746,14 +678,14 @@ - goof += _dl_parse_relocation_information(rpnt, - reloc_addr, - reloc_size); -+ tpnt->init_flag |= RELOCS_DONE; - } - if (tpnt->dynamic_info[DT_BIND_NOW]) - now_flag = RTLD_NOW; - if (tpnt->dynamic_info[DT_JMPREL] && - (!(tpnt->init_flag & JMP_RELOCS_DONE) || - (now_flag && !(tpnt->rtld_flags & now_flag)))) { -- tpnt->rtld_flags |= now_flag; -- tpnt->init_flag |= JMP_RELOCS_DONE; -+ tpnt->rtld_flags |= now_flag; - if (!(tpnt->rtld_flags & RTLD_NOW)) { - _dl_parse_lazy_relocation_information(rpnt, - tpnt->dynamic_info[DT_JMPREL], -@@ -763,6 +695,7 @@ - tpnt->dynamic_info[DT_JMPREL], - tpnt->dynamic_info[DT_PLTRELSZ]); - } -+ tpnt->init_flag |= JMP_RELOCS_DONE; - } - return goof; - } -@@ -770,11 +703,18 @@ - /* Minimal printf which handles only %s, %d, and %x */ - void _dl_dprintf(int fd, const char *fmt, ...) - { -- long num; -+#if __WORDSIZE > 32 -+ long int num; -+#else -+ int num; -+#endif - va_list args; - char *start, *ptr, *string; - static char *buf; - -+ if (!fmt) -+ return; -+ - buf = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (_dl_mmap_check_error(buf)) { -@@ -784,9 +724,6 @@ - - start = ptr = buf; - -- if (!fmt) -- return; -- - if (_dl_strlen(fmt) >= (_dl_pagesize - 1)) { - _dl_write(fd, "overflow\n", 11); - _dl_exit(20); -@@ -818,8 +755,11 @@ - case 'd': - { - char tmp[22]; -- num = va_arg(args, long); -- -+#if __WORDSIZE > 32 -+ num = va_arg(args, long int); -+#else -+ num = va_arg(args, int); -+#endif - string = _dl_simple_ltoa(tmp, num); - _dl_write(fd, string, _dl_strlen(string)); - break; -@@ -828,8 +768,11 @@ - case 'X': - { - char tmp[22]; -- num = va_arg(args, long); -- -+#if __WORDSIZE > 32 -+ num = va_arg(args, long int); -+#else -+ num = va_arg(args, int); -+#endif - string = _dl_simple_ltoahex(tmp, num); - _dl_write(fd, string, _dl_strlen(string)); - break; -@@ -864,8 +807,10 @@ - { - __dl_parse_dynamic_info(dpnt, dynamic_info, debug_addr, load_off); - } -+ -+/* we want this in ldso.so and libdl.a but nowhere else */ - #ifdef __USE_GNU --#if ! defined LIBDL || (! defined PIC && ! defined __PIC__) -+#if ! defined SHARED || (! defined PIC && ! defined __PIC__) - int - __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, size_t size, void *data), void *data) - { -@@ -884,6 +829,6 @@ - } - return ret; - } --strong_alias(__dl_iterate_phdr, dl_iterate_phdr); -+strong_alias(__dl_iterate_phdr, dl_iterate_phdr) - #endif - #endif -diff -urN uClibc-0.9.28.orig/ldso/ldso/dl-hash.c uClibc-0.9.28/ldso/ldso/dl-hash.c ---- uClibc-0.9.28.orig/ldso/ldso/dl-hash.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/dl-hash.c 2006-04-28 00:14:35.000000000 -0600 -@@ -57,7 +57,7 @@ - /* This is the hash function that is used by the ELF linker to generate the - * hash table that each executable and library is required to have. We need - * it to decode the hash table. */ --static inline Elf32_Word _dl_elf_hash(const char *name) -+static inline Elf_Symndx _dl_elf_hash(const char *name) - { - unsigned long hash=0; - unsigned long tmp; -@@ -77,21 +77,6 @@ - return hash; - } - --/* Check to see if a library has already been added to the hash chain. */ --struct elf_resolve *_dl_check_hashed_files(const char *libname) --{ -- struct elf_resolve *tpnt; -- int len = _dl_strlen(libname); -- -- for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) { -- if (_dl_strncmp(tpnt->libname, libname, len) == 0 && -- (tpnt->libname[len] == '\0' || tpnt->libname[len] == '.')) -- return tpnt; -- } -- -- return NULL; --} -- - /* - * We call this function when we have just read an ELF library or executable. - * We add the relevant info to the symbol chain, so that we can resolve all -@@ -99,9 +84,10 @@ - */ - struct elf_resolve *_dl_add_elf_hash_table(const char *libname, - char *loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr, -+ //attribute_unused - unsigned long dynamic_size) - { -- Elf32_Word *hash_addr; -+ Elf_Symndx *hash_addr; - struct elf_resolve *tpnt; - int i; - -@@ -125,7 +111,7 @@ - tpnt->libtype = loaded_file; - - if (dynamic_info[DT_HASH] != 0) { -- hash_addr = (Elf32_Word*)dynamic_info[DT_HASH]; -+ hash_addr = (Elf_Symndx*)dynamic_info[DT_HASH]; - tpnt->nbucket = *hash_addr++; - tpnt->nchain = *hash_addr++; - tpnt->elf_buckets = hash_addr; -diff -urN uClibc-0.9.28.orig/ldso/ldso/dl-startup.c uClibc-0.9.28/ldso/ldso/dl-startup.c ---- uClibc-0.9.28.orig/ldso/ldso/dl-startup.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/dl-startup.c 2006-04-28 00:14:35.000000000 -0600 -@@ -98,7 +98,7 @@ - int (*_dl_elf_main) (int, char **, char **); - - static void* __rtld_stack_end; /* Points to argc on stack, e.g *((long *)__rtld_stackend) == argc */ --strong_alias(__rtld_stack_end, __libc_stack_end); /* Exported version of __rtld_stack_end */ -+strong_alias(__rtld_stack_end, __libc_stack_end) /* Exported version of __rtld_stack_end */ - - /* When we enter this piece of code, the program stack looks like this: - argc argument counter (integer) -@@ -307,5 +307,11 @@ - SEND_STDERR_DEBUG("transfering control to application @ "); - _dl_elf_main = (int (*)(int, char **, char **)) auxvt[AT_ENTRY].a_un.a_val; - SEND_ADDRESS_STDERR_DEBUG(_dl_elf_main, 1); -+ -+#ifndef START -+ return _dl_elf_main; -+#else -+#warning You need to update your arch ldso code - START(); -+#endif - } -diff -urN uClibc-0.9.28.orig/ldso/ldso/frv/dl-syscalls.h uClibc-0.9.28/ldso/ldso/frv/dl-syscalls.h ---- uClibc-0.9.28.orig/ldso/ldso/frv/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/frv/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600 -@@ -20,9 +20,10 @@ - - /* 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/syscall.h" - #include <sys/mman.h> - - /* The code below is extracted from libc/sysdeps/linux/frv/_mmap.c */ -diff -urN uClibc-0.9.28.orig/ldso/ldso/frv/dl-sysdep.h uClibc-0.9.28/ldso/ldso/frv/dl-sysdep.h ---- uClibc-0.9.28.orig/ldso/ldso/frv/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/frv/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600 -@@ -65,8 +65,6 @@ - - extern int _dl_linux_resolve(void) __attribute__((__visibility__("hidden"))); - --#define do_rem(result, n, base) ((result) = (n) % (base)) -- - /* 16KiB page alignment. Should perhaps be made dynamic using - getpagesize(), based on AT_PAGESZ from auxvt? */ - #define PAGE_ALIGN 0xffffc000 -diff -urN uClibc-0.9.28.orig/ldso/ldso/frv/elfinterp.c uClibc-0.9.28/ldso/ldso/frv/elfinterp.c ---- uClibc-0.9.28.orig/ldso/ldso/frv/elfinterp.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/frv/elfinterp.c 2006-04-28 00:14:35.000000000 -0600 -@@ -24,7 +24,7 @@ - the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, - USA. */ - --#include <sys/cdefs.h> /* __attribute_used__ */ -+#include <features.h> - - /* Program to load an ELF binary on a linux system, and run it. - References to symbols in sharable libraries can be resolved by either -@@ -37,7 +37,7 @@ - a more than adequate job of explaining everything required to get this - working. */ - --struct funcdesc_value volatile *__attribute__((__visibility__("hidden"))) -+struct funcdesc_value volatile attribute_hidden * - _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) - { - int reloc_type; -diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/dl-startup.h uClibc-0.9.28/ldso/ldso/i386/dl-startup.h ---- uClibc-0.9.28.orig/ldso/ldso/i386/dl-startup.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/i386/dl-startup.h 2006-04-28 00:14:35.000000000 -0600 -@@ -3,7 +3,7 @@ - * Architecture specific code used by dl-startup.c - * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org> - */ --asm( -+__asm__ ( - " .text\n" - " .align 16\n" - " .globl _start\n" -@@ -41,9 +41,9 @@ - #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) & ARGS)+1) - - /* Handle relocation of the symbols in the dynamic loader. */ --static inline -+static __always_inline - void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr, -- unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab) -+ unsigned long symbol_addr, unsigned long load_addr, attribute_unused Elf32_Sym *symtab) - { - switch (ELF32_R_TYPE(rpnt->r_info)) - { -@@ -64,8 +64,3 @@ - _dl_exit(1); - } - } -- --/* Transfer control to the user's application, once the dynamic loader is -- * done. This routine has to exit the current function, then call the -- * _dl_elf_main function. */ --#define START() return _dl_elf_main -diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/dl-syscalls.h uClibc-0.9.28/ldso/ldso/i386/dl-syscalls.h ---- uClibc-0.9.28.orig/ldso/ldso/i386/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/i386/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,5 +1,6 @@ - /* 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/syscall.h" -diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/dl-sysdep.h uClibc-0.9.28/ldso/ldso/i386/dl-sysdep.h ---- uClibc-0.9.28.orig/ldso/ldso/i386/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/i386/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600 -@@ -25,8 +25,6 @@ - struct elf_resolve; - extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - --#define do_rem(result, n, base) ((result) = (n) % (base)) -- - /* 4096 bytes alignment */ - #define PAGE_ALIGN 0xfffff000 - #define ADDR_ALIGN 0xfff -@@ -44,16 +42,18 @@ - /* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. This must be inlined in a function which - uses global data. */ --static inline Elf32_Addr __attribute__ ((unused)) -+static inline Elf32_Addr elf_machine_dynamic (void) attribute_unused; -+static inline Elf32_Addr - elf_machine_dynamic (void) - { -- register Elf32_Addr *got asm ("%ebx"); -+ register Elf32_Addr *got __asm__ ("%ebx"); - return *got; - } - - - /* Return the run-time load address of the shared object. */ --static inline Elf32_Addr __attribute__ ((unused)) -+static inline Elf32_Addr elf_machine_load_address (void) attribute_unused; -+static inline Elf32_Addr - elf_machine_load_address (void) - { - /* It doesn't matter what variable this is, the reference never makes -@@ -61,7 +61,7 @@ - via the GOT to make sure the compiler initialized %ebx in time. */ - extern int _dl_errno; - Elf32_Addr addr; -- asm ("leal _dl_start@GOTOFF(%%ebx), %0\n" -+ __asm__ ("leal _dl_start@GOTOFF(%%ebx), %0\n" - "subl _dl_start@GOT(%%ebx), %0" - : "=r" (addr) : "m" (_dl_errno) : "cc"); - return addr; -diff -urN uClibc-0.9.28.orig/ldso/ldso/i386/elfinterp.c uClibc-0.9.28/ldso/ldso/i386/elfinterp.c ---- uClibc-0.9.28.orig/ldso/ldso/i386/elfinterp.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/i386/elfinterp.c 2006-04-28 00:14:35.000000000 -0600 -@@ -67,12 +67,6 @@ - strtab = (char *)tpnt->dynamic_info[DT_STRTAB]; - symname = strtab + symtab[symtab_index].st_name; - -- if (unlikely(reloc_type != R_386_JMP_SLOT)) { -- _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n", -- _dl_progname); -- _dl_exit(1); -- } -- - /* Address of the jump instruction to fix up. */ - instr_addr = ((unsigned long)this_reloc->r_offset + - (unsigned long)tpnt->loadaddr); -@@ -81,7 +75,7 @@ - /* Get the address of the GOT entry. */ - new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT); - if (unlikely(!new_addr)) { -- _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname); -+ _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname); - _dl_exit(1); - } - -@@ -147,15 +141,15 @@ - int reloc_type = ELF32_R_TYPE(rpnt->r_info); - - #if defined (__SUPPORT_LD_DEBUG__) -- _dl_dprintf(2, "can't handle reloc type %s\n", -- _dl_reltypes(reloc_type)); -+ _dl_dprintf(2, "can't handle reloc type '%s' in lib '%s'\n", -+ _dl_reltypes(reloc_type), tpnt->libname); - #else -- _dl_dprintf(2, "can't handle reloc type %x\n", -- reloc_type); -+ _dl_dprintf(2, "can't handle reloc type %x in lib '%s'\n", -+ reloc_type, tpnt->libname); - #endif -- _dl_exit(-res); -+ return res; - } else if (unlikely(res > 0)) { -- _dl_dprintf(2, "can't resolve symbol\n"); -+ _dl_dprintf(2, "can't resolve symbol in lib '%s'.\n", tpnt->libname); - return res; - } - } -@@ -191,10 +185,8 @@ - * might have been intentional. We should not be linking local - * symbols here, so all bases should be covered. - */ -- if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) { -- _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); -- _dl_exit(1); -- }; -+ if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) -+ return 1; - } - - #if defined (__SUPPORT_LD_DEBUG__) -@@ -233,7 +225,7 @@ - } - break; - default: -- return -1; /* Calls _dl_exit(1). */ -+ return -1; - } - - #if defined (__SUPPORT_LD_DEBUG__) -@@ -273,7 +265,7 @@ - *reloc_addr += (unsigned long)tpnt->loadaddr; - break; - default: -- return -1; /* Calls _dl_exit(1). */ -+ return -1; - } - - #if defined (__SUPPORT_LD_DEBUG__) -diff -urN uClibc-0.9.28.orig/ldso/ldso/ldso.c uClibc-0.9.28/ldso/ldso/ldso.c ---- uClibc-0.9.28.orig/ldso/ldso/ldso.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/ldso.c 2006-05-02 13:55:54.000000000 -0600 -@@ -39,7 +39,7 @@ - #define ALLOW_ZERO_PLTGOT - - /* Pull in the value of _dl_progname */ --#include "dl-progname.h" -+#include LDSO_ELFINTERP - - /* Global variables used within the shared library loader */ - char *_dl_library_path = 0; /* Where we look for libraries */ -@@ -74,7 +74,8 @@ - * can set an internal breakpoint on it, so that we are notified when the - * address mapping is changed in some way. - */ --void _dl_debug_state(void) -+void _dl_debug_state(void); -+void _dl_debug_state() - { - } - -@@ -82,9 +83,78 @@ - static unsigned char *_dl_mmap_zero = 0; /* Also used by _dl_malloc */ - - static struct elf_resolve **init_fini_list; --static int nlist; /* # items in init_fini_list */ -+static unsigned int nlist; /* # items in init_fini_list */ - extern void _start(void); - -+#ifdef __UCLIBC_HAS_SSP__ -+#ifndef __UCLIBC_HAS_SSP_COMPAT__ -+#define __UCLIBC_HAS_SSP_COMPAT__ 1 -+#endif -+# include <dl-osinfo.h> -+uintptr_t stack_chk_guard; -+# ifndef THREAD_SET_STACK_GUARD -+/* Only exported for architectures that don't store the stack guard canary -+ * in local thread area. */ -+uintptr_t __stack_chk_guard attribute_relro; -+# ifdef __UCLIBC_HAS_SSP_COMPAT__ -+strong_alias(__stack_chk_guard,__guard) -+# endif -+# elif __UCLIBC_HAS_SSP_COMPAT__ -+uintptr_t __guard attribute_relro; -+# endif -+#endif -+ -+static void _dl_run_array_forward(unsigned long array, unsigned long size, -+ ElfW(Addr) loadaddr) -+{ -+ if (array != 0) { -+ unsigned int j; -+ unsigned int jm; -+ ElfW(Addr) *addrs; -+ jm = size / sizeof (ElfW(Addr)); -+ addrs = (ElfW(Addr) *) (array + loadaddr); -+ for (j = 0; j < jm; ++j) { -+ void (*dl_elf_func) (void); -+ dl_elf_func = (void (*)(void)) (intptr_t) addrs[j]; -+ (*dl_elf_func) (); -+ } -+ } -+} -+ -+void _dl_run_init_array(struct elf_resolve *tpnt); -+void _dl_run_init_array(struct elf_resolve *tpnt) -+{ -+ _dl_run_array_forward(tpnt->dynamic_info[DT_INIT_ARRAY], -+ tpnt->dynamic_info[DT_INIT_ARRAYSZ], -+ tpnt->loadaddr); -+} -+ -+void _dl_app_init_array(void); -+void _dl_app_init_array(void) -+{ -+ _dl_run_init_array(_dl_loaded_modules); -+} -+ -+void _dl_run_fini_array(struct elf_resolve *tpnt); -+void _dl_run_fini_array(struct elf_resolve *tpnt) -+{ -+ if (tpnt->dynamic_info[DT_FINI_ARRAY]) { -+ ElfW(Addr) *array = (ElfW(Addr) *) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI_ARRAY]); -+ unsigned int i = (tpnt->dynamic_info[DT_FINI_ARRAYSZ] / sizeof(ElfW(Addr))); -+ while (i-- > 0) { -+ void (*dl_elf_func) (void); -+ dl_elf_func = (void (*)(void)) (intptr_t) array[i]; -+ (*dl_elf_func) (); -+ } -+ } -+} -+ -+void _dl_app_fini_array(void); -+void _dl_app_fini_array(void) -+{ -+ _dl_run_fini_array(_dl_loaded_modules); -+} -+ - static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void) - { - int i; -@@ -95,6 +165,7 @@ - if (tpnt->init_flag & FINI_FUNCS_CALLED) - continue; - tpnt->init_flag |= FINI_FUNCS_CALLED; -+ _dl_run_fini_array(tpnt); - if (tpnt->dynamic_info[DT_FINI]) { - void (*dl_elf_func) (void); - -@@ -112,7 +183,8 @@ - ElfW(Phdr) *ppnt; - ElfW(Dyn) *dpnt; - char *lpntstr; -- int i, goof = 0, unlazy = 0, trace_loaded_objects = 0; -+ unsigned int i; -+ int unlazy = 0, trace_loaded_objects = 0; - struct dyn_elf *rpnt; - struct elf_resolve *tcurr; - struct elf_resolve *tpnt1; -@@ -128,6 +200,7 @@ - * setup so we can use _dl_dprintf() to print debug noise - * instead of the SEND_STDERR macros used in dl-startup.c */ - -+ _dl_memset(app_tpnt, 0x00, sizeof(*app_tpnt)); - - /* Store the page size for later use */ - _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE; -@@ -168,8 +241,8 @@ - * Note that for SUID programs we ignore the settings in - * LD_LIBRARY_PATH. - */ -- if ((auxvt[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) || -- (auxvt[AT_UID].a_un.a_val != -1 && -+ if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) || -+ (auxvt[AT_UID].a_un.a_val != (size_t)-1 && - auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val && - auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) { - _dl_secure = 0; -@@ -196,6 +269,20 @@ - unlazy = RTLD_NOW; - } - -+ /* sjhill: your TLS init should go before this */ -+#ifdef __UCLIBC_HAS_SSP__ -+ /* Set up the stack checker's canary. */ -+ stack_chk_guard = _dl_setup_stack_chk_guard (); -+# ifdef THREAD_SET_STACK_GUARD -+ THREAD_SET_STACK_GUARD (stack_chk_guard); -+# ifdef __UCLIBC_HAS_SSP_COMPAT__ -+ __guard = stack_chk_guard; -+# endif -+# else -+ __stack_chk_guard = stack_chk_guard; -+# endif -+#endif -+ - /* At this point we are now free to examine the user application, - * and figure out which libraries are supposed to be called. Until - * we have this list, we will not be completely ready for dynamic -@@ -206,12 +293,12 @@ - * different from what the ELF header says for ET_DYN/PIE executables. - */ - { -- int i; -- ElfW(Phdr) *ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val; -+ unsigned int idx; -+ ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val; - -- for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) -- if (ppnt->p_type == PT_PHDR) { -- app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - ppnt->p_vaddr); -+ for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++) -+ if (phdr->p_type == PT_PHDR) { -+ app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr); - break; - } - -@@ -459,8 +546,8 @@ - PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - _dl_close(fd); - if (preload == (caddr_t) -1) { -- _dl_dprintf(_dl_debug_file, "%s: can't map file '%s'\n", -- _dl_progname, LDSO_PRELOAD); -+ _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n", -+ _dl_progname, __LINE__, LDSO_PRELOAD); - break; - } - -@@ -528,15 +615,15 @@ - - nlist = 0; - for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) { -- ElfW(Dyn) *dpnt; -+ ElfW(Dyn) *this_dpnt; - - nlist++; -- for (dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) { -- if (dpnt->d_tag == DT_NEEDED) { -+ for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) { -+ if (this_dpnt->d_tag == DT_NEEDED) { - char *name; - struct init_fini_list *tmp; - -- lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + dpnt->d_un.d_val); -+ lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val); - name = _dl_get_last_path_component(lpntstr); - if (_dl_strcmp(name, UCLIBC_LDSO) == 0) - continue; -@@ -633,7 +720,7 @@ - ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val; - ElfW(Phdr) *myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff); - int j; -- -+ - tpnt = _dl_add_elf_hash_table(tpnt->libname, (char *)load_addr, - tpnt->dynamic_info, - (unsigned long)tpnt->dynamic_addr, -@@ -703,16 +790,14 @@ - * order so that COPY directives work correctly. - */ - if (_dl_symbol_tables) -- goof += _dl_fixup(_dl_symbol_tables, unlazy); -+ if (_dl_fixup(_dl_symbol_tables, unlazy)) -+ _dl_exit(-1); - - for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) { - if (tpnt->relro_size) - _dl_protect_relro (tpnt); - } - -- -- -- - /* OK, at this point things are pretty much ready to run. Now we need - * to touch up a few items that are required, and then we can let the - * user application have at it. Note that the dynamic linker itself -@@ -746,6 +831,14 @@ - /* Notify the debugger we have added some objects. */ - _dl_debug_addr->r_state = RT_ADD; - _dl_debug_state(); -+ -+ /* Run pre-initialization functions for the executable. */ -+ _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY], -+ _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ], -+ _dl_loaded_modules->loadaddr); -+ -+ /* Run initialization functions for loaded objects. For the -+ main executable, they will be run from __uClibc_main. */ - for (i = nlist; i; --i) { - tpnt = init_fini_list[i-1]; - tpnt->init_fini = NULL; /* Clear, since alloca was used */ -@@ -762,17 +855,9 @@ - - (*dl_elf_func) (); - } -- } --#ifdef _DL_FINI_CRT_COMPAT -- /* arches that have moved their ldso FINI handling should skip this part */ -- { -- int (*_dl_atexit) (void *) = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", -- _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT); - -- if (_dl_atexit) -- (*_dl_atexit) (_dl_fini); -+ _dl_run_init_array(tpnt); - } --#endif - - /* Find the real malloc function and make ldso functions use that from now on */ - _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash("malloc", -diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/dl-startup.h uClibc-0.9.28/ldso/ldso/m68k/dl-startup.h ---- uClibc-0.9.28.orig/ldso/ldso/m68k/dl-startup.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/m68k/dl-startup.h 2006-04-28 00:14:35.000000000 -0600 -@@ -4,23 +4,48 @@ - * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org> - */ - --asm( -- " .text\n" -- " .globl _start\n" -- " .type _start,@function\n" -- "_start:\n" -- " .set _start,_dl_start\n" -- " .size _start,.-_start\n" -- " .previous\n" --); -+asm ("\ -+ .text\n\ -+ .globl _start\n\ -+ .type _start,@function\n\ -+_start:\n\ -+ move.l %sp, -(%sp)\n\ -+ jbsr _dl_start\n\ -+ addq.l #4, %sp\n\ -+ /* FALLTHRU */\n\ -+\n\ -+ .globl _dl_start_user\n\ -+.type _dl_start_user,@function\n\ -+_dl_start_user:\n\ -+ # Save the user entry point address in %a4.\n\ -+ move.l %d0, %a4\n\ -+ # See if we were run as a command with the executable file\n\ -+ # name as an extra leading argument.\n\ -+ move.l _dl_skip_args(%pc), %d0\n\ -+ # Pop the original argument count\n\ -+ move.l (%sp)+, %d1\n\ -+ # Subtract _dl_skip_args from it.\n\ -+ sub.l %d0, %d1\n\ -+ # Adjust the stack pointer to skip _dl_skip_args words.\n\ -+ lea (%sp, %d0*4), %sp\n\ -+ # Push back the modified argument count.\n\ -+ move.l %d1, -(%sp)\n\ -+ # Pass our finalizer function to the user in %a1.\n\ -+ lea _dl_fini(%pc), %a1\n\ -+ # Initialize %fp with the stack pointer.\n\ -+ move.l %sp, %fp\n\ -+ # Jump to the user's entry point.\n\ -+ jmp (%a4)\n\ -+ .size _dl_start_user, . - _dl_start_user\n\ -+ .previous"); - - /* 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 int *) & ARGS) -+#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS) + 1) - - /* Handle relocation of the symbols in the dynamic loader. */ --static inline -+static __always_inline - void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr, - unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab) - { -@@ -59,12 +84,3 @@ - _dl_exit (1); - } - } -- --/* Transfer control to the user's application, once the dynamic loader is -- * done. This routine has to exit the current function, then call the -- * _dl_elf_main function. */ --#define START() \ -- __asm__ volatile ( \ -- "unlk %%a6\n\t" \ -- "jmp %0@" \ -- : : "a" (_dl_elf_main)); -diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/dl-syscalls.h uClibc-0.9.28/ldso/ldso/m68k/dl-syscalls.h ---- uClibc-0.9.28.orig/ldso/ldso/m68k/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/m68k/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,5 +1,6 @@ - /* 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/syscall.h" -diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/dl-sysdep.h uClibc-0.9.28/ldso/ldso/m68k/dl-sysdep.h ---- uClibc-0.9.28.orig/ldso/ldso/m68k/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/m68k/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600 -@@ -25,10 +25,6 @@ - struct elf_resolve; - extern unsigned int _dl_linux_resolver (struct elf_resolve *, int); - --/* Define this because we do not want to call .udiv in the library. -- Not needed for m68k. */ --#define do_rem(result, n, base) ((result) = (n) % (base)) -- - /* 4096 bytes alignment */ - #define PAGE_ALIGN 0xfffff000 - #define ADDR_ALIGN 0xfff -diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/elfinterp.c uClibc-0.9.28/ldso/ldso/m68k/elfinterp.c ---- uClibc-0.9.28.orig/ldso/ldso/m68k/elfinterp.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/m68k/elfinterp.c 2006-04-28 00:14:35.000000000 -0600 -@@ -40,6 +40,8 @@ - a more than adequate job of explaining everything required to get this - working. */ - -+#include "ldso.h" -+ - extern int _dl_linux_resolve(void); - - unsigned int -@@ -48,20 +50,20 @@ - int reloc_type; - ELF_RELOC *this_reloc; - char *strtab; -- Elf32_Sym *symtab; -+ ElfW(Sym) *symtab; - int symtab_index; -- ELF_RELOC *rel_addr; -+ char *rel_addr; - char *new_addr; - char **got_addr; -- unsigned int instr_addr; -+ ElfW(Addr) instr_addr; - char *symname; - -- rel_addr = (ELF_RELOC *)tpnt->dynamic_info[DT_JMPREL]; -- this_reloc = (ELF_RELOC *)(intptr_t)(rel_addr + reloc_entry); -- reloc_type = ELF32_R_TYPE(this_reloc->r_info); -- symtab_index = ELF32_R_SYM(this_reloc->r_info); -+ rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL]; -+ this_reloc = (ELF_RELOC *)(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 *)(intptr_t)tpnt->dynamic_info[DT_SYMTAB]; -+ symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB]; - strtab = (char *)tpnt->dynamic_info[DT_STRTAB]; - symname = strtab + symtab[symtab_index].st_name; - -@@ -72,7 +74,7 @@ - } - - /* Address of the jump instruction to fix up. */ -- instr_addr = ((int)this_reloc->r_offset + (int)tpnt->loadaddr); -+ instr_addr = (this_reloc->r_offset + tpnt->loadaddr); - got_addr = (char **)instr_addr; - - /* Get the address of the GOT entry. */ -@@ -88,159 +90,237 @@ - _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname); - if (_dl_debug_detail) - _dl_dprintf(_dl_debug_file, -- "\n\tpatched: %x ==> %x @ %x", -+ "\tpatched: %x ==> %x @ %x\n", - *got_addr, new_addr, got_addr); - } - } -- if (!_dl_debug_nofixups) { -- *got_addr = new_addr; -- } --#else -- *got_addr = new_addr; -+ if (!_dl_debug_nofixups) - #endif -+ *got_addr = new_addr; - -- return (unsigned int)new_addr; -+ return (unsigned int)new_addr; - } - --void --_dl_parse_lazy_relocation_information(struct dyn_elf *arg_rpnt, -- unsigned long rel_addr, unsigned long rel_size) -+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)) - { -- int i; -+ unsigned int i; - char *strtab; -- int reloc_type; -+ ElfW(Sym) *symtab; -+ ELF_RELOC *rpnt; - int symtab_index; -- Elf32_Sym *symtab; -- Elf32_Rela *rpnt; -- unsigned int *reloc_addr; -- struct elf_resolve *tpnt = arg_rpnt->dyn; -- -- /* Now parse the relocation information. */ -- rpnt = (Elf32_Rela *)rel_addr; -- rel_size = rel_size / sizeof (Elf32_Rela); - -- symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB]; -+ /* Parse the relocation information. */ -+ rpnt = (ELF_RELOC *)rel_addr; -+ 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++) { -- reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset); -- reloc_type = ELF32_R_TYPE (rpnt->r_info); -- symtab_index = ELF32_R_SYM (rpnt->r_info); -+ int res; - -- switch (reloc_type) -- { -- case R_68K_NONE: -- break; -- case R_68K_JMP_SLOT: -- *reloc_addr += (unsigned int) tpnt->loadaddr; -- break; -- default: -- _dl_dprintf (2, "%s: (LAZY) can't handle reloc type ", _dl_progname); -+ 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 (unlikely(res < 0)) { -+ int reloc_type = ELF_R_TYPE(rpnt->r_info); -+ -+ _dl_dprintf(2, "can't handle reloc type " - #if defined (__SUPPORT_LD_DEBUG__) -- _dl_dprintf (2, "%s ", _dl_reltypes_tab[reloc_type]); -+ "%s\n", _dl_reltypes(reloc_type)); -+#else -+ "%x\n", reloc_type); - #endif -- if (symtab_index) -- _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name); -- _dl_dprintf (2, "\n"); -- _dl_exit (1); -+ _dl_exit(-res); -+ } else if (unlikely(res > 0)) { -+ _dl_dprintf(2, "can't resolve symbol\n"); -+ return res; - } - } -+ -+ return 0; - } - --int --_dl_parse_relocation_information(struct dyn_elf *arg_rpnt, -- unsigned long rel_addr, unsigned long rel_size) -+static int -+_dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, -+ ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) - { -- int i; -- char *strtab; - int reloc_type; -- int goof = 0; -- Elf32_Sym *symtab; -- Elf32_Rela *rpnt; -- unsigned int *reloc_addr; -- unsigned int symbol_addr; - int symtab_index; -- struct elf_resolve *tpnt = arg_rpnt->dyn; -- /* Now parse the relocation information */ -+ char *symname; -+ ElfW(Sym) *sym; -+ ElfW(Addr) *reloc_addr; -+ ElfW(Addr) symbol_addr; -+#if defined (__SUPPORT_LD_DEBUG__) -+ ElfW(Addr) old_val; -+#endif - -- rpnt = (Elf32_Rela *)rel_addr; -- rel_size = rel_size / sizeof (Elf32_Rela); -+ reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset); -+ reloc_type = ELF_R_TYPE(rpnt->r_info); -+ symtab_index = ELF_R_SYM(rpnt->r_info); -+ sym = &symtab[symtab_index]; -+ symbol_addr = 0; -+ symname = strtab + sym->st_name; -+ -+ if (symtab_index) { -+ symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt, -+ elf_machine_type_class(reloc_type)); -+ /* -+ * 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 (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) { -+ _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); -+ _dl_exit(1); -+ }; -+ } - -- symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB]; -- strtab = (char *)tpnt->dynamic_info[DT_STRTAB]; -+#if defined (__SUPPORT_LD_DEBUG__) -+ old_val = *reloc_addr; -+#endif - -- for (i = 0; i < rel_size; i++, rpnt++) { -- reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset); -- reloc_type = ELF32_R_TYPE (rpnt->r_info); -- symtab_index = ELF32_R_SYM (rpnt->r_info); -- symbol_addr = 0; -- if (symtab_index) { -- symbol_addr = (unsigned int) -- _dl_find_hash (strtab + symtab[symtab_index].st_name, -- tpnt->symbol_scope, tpnt, -- elf_machine_type_class(reloc_type)); -- -- /* 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 -- && ELF32_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); -- } -- } -- switch (reloc_type) -- { -- case R_68K_NONE: -- break; -- case R_68K_8: -- *(char *) reloc_addr = symbol_addr + rpnt->r_addend; -- break; -- case R_68K_16: -- *(short *) reloc_addr = symbol_addr + rpnt->r_addend; -- break; -- case R_68K_32: -- *reloc_addr = symbol_addr + rpnt->r_addend; -- break; -- case R_68K_PC8: -- *(char *) reloc_addr = (symbol_addr + rpnt->r_addend -- - (unsigned int) reloc_addr); -- break; -- case R_68K_PC16: -- *(short *) reloc_addr = (symbol_addr + rpnt->r_addend -- - (unsigned int) reloc_addr); -- break; -- case R_68K_PC32: -- *reloc_addr = (symbol_addr + rpnt->r_addend -- - (unsigned int) reloc_addr); -- break; -- case R_68K_GLOB_DAT: -- case R_68K_JMP_SLOT: -- *reloc_addr = symbol_addr; -- break; -- case R_68K_RELATIVE: -- *reloc_addr = ((unsigned int) tpnt->loadaddr -- /* Compatibility kludge. */ -- + (rpnt->r_addend ? : *reloc_addr)); -- break; -- case R_68K_COPY: -+ switch (reloc_type) { -+ case R_68K_NONE: -+ break; -+ case R_68K_8: -+ *(char *) reloc_addr = symbol_addr + rpnt->r_addend; -+ break; -+ case R_68K_16: -+ *(short *) reloc_addr = symbol_addr + rpnt->r_addend; -+ break; -+ case R_68K_32: -+ *reloc_addr = symbol_addr + rpnt->r_addend; -+ break; -+ case R_68K_PC8: -+ *(char *) reloc_addr = (symbol_addr + rpnt->r_addend -+ - (unsigned int) reloc_addr); -+ break; -+ case R_68K_PC16: -+ *(short *) reloc_addr = (symbol_addr + rpnt->r_addend -+ - (unsigned int) reloc_addr); -+ break; -+ case R_68K_PC32: -+ *reloc_addr = (symbol_addr + rpnt->r_addend -+ - (unsigned int) reloc_addr); -+ break; -+ case R_68K_GLOB_DAT: -+ case R_68K_JMP_SLOT: -+ *reloc_addr = symbol_addr + rpnt->r_addend; -+ break; -+ /* handled by elf_machine_relative() -+ case R_68K_RELATIVE: -+ *reloc_addr = ((unsigned int) tpnt->loadaddr -+ / * Compatibility kludge. * / -+ + (rpnt->r_addend ? : *reloc_addr)); -+ */ -+ break; -+ case R_68K_COPY: -+ if (symbol_addr) { -+#if defined (__SUPPORT_LD_DEBUG__) -+ if (_dl_debug_move) -+ _dl_dprintf(_dl_debug_file, -+ "\t%s move %d bytes from %x to %x\n", -+ symname, sym->st_size, -+ symbol_addr, reloc_addr); -+#endif - _dl_memcpy ((void *) reloc_addr, - (void *) symbol_addr, -- symtab[symtab_index].st_size); -- break; -- default: -- _dl_dprintf (2, "%s: can't handle reloc type ", _dl_progname); --#if defined (__SUPPORT_LD_DEBUG__) -- _dl_dprintf (2, "%s ", _dl_reltypes_tab[reloc_type]); --#endif -- if (symtab_index) -- _dl_dprintf (2, "'%s'", strtab + symtab[symtab_index].st_name); -- _dl_dprintf (2, "\n"); -- _dl_exit (1); -- } -+ sym->st_size); -+ } else -+ _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n"); -+ break; -+ -+ default: -+ return -1; /* Calls _dl_exit(1). */ -+ } -+ -+#if defined (__SUPPORT_LD_DEBUG__) -+ if (_dl_debug_reloc && _dl_debug_detail) -+ _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n", -+ old_val, *reloc_addr, reloc_addr); -+#endif -+ -+ return 0; -+} -+ -+#undef LAZY_RELOC_WORKS -+#ifdef LAZY_RELOC_WORKS -+static int -+_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, -+ ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) -+{ -+ int reloc_type; -+ int symtab_index; -+ ElfW(Addr) *reloc_addr; -+#if defined (__SUPPORT_LD_DEBUG__) -+ ElfW(Addr) old_val; -+#endif -+ -+ (void)scope; -+ symtab_index = ELF_R_SYM(rpnt->r_info); -+ (void)strtab; -+ -+ reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset); -+ reloc_type = ELF_R_TYPE(rpnt->r_info); -+ -+#if defined (__SUPPORT_LD_DEBUG__) -+ old_val = *reloc_addr; -+#endif -+ -+ switch (reloc_type) { -+ case R_68K_NONE: -+ break; -+ case R_68K_JMP_SLOT: -+ *reloc_addr += (unsigned int) tpnt->loadaddr; -+ break; -+ default: -+ _dl_exit(1); - } -- return goof; -+ -+#if defined (__SUPPORT_LD_DEBUG__) -+ if (_dl_debug_reloc && _dl_debug_detail) -+ _dl_dprintf(_dl_debug_file, "\tpatched_lazy: %x ==> %x @ %x\n", -+ old_val, *reloc_addr, reloc_addr); -+#endif -+ -+ return 0; -+} -+#endif -+ -+void -+_dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, -+ unsigned long rel_addr, -+ unsigned long rel_size) -+{ -+#ifdef LAZY_RELOC_WORKS -+ (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc); -+#else -+ _dl_parse_relocation_information(rpnt, rel_addr, rel_size); -+#endif -+} -+ -+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); - } -diff -urN uClibc-0.9.28.orig/ldso/ldso/m68k/resolve.S uClibc-0.9.28/ldso/ldso/m68k/resolve.S ---- uClibc-0.9.28.orig/ldso/ldso/m68k/resolve.S 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/m68k/resolve.S 2006-04-28 00:14:35.000000000 -0600 -@@ -8,14 +8,16 @@ - .globl _dl_linux_resolve - .type _dl_linux_resolve,@function - _dl_linux_resolve: -- moveml %a0/%a1,%sp@- --#ifdef __PIC__ -- bsrl _dl_linux_resolver@PLTPC --#else -- jbsr _dl_linux_resolver --#endif -- moveml %sp@+,%a0/%a1 -- addql #8,%sp -- jmp @(%d0) --.LFE2: -- .size _dl_linux_resolve,.LFE2-_dl_linux_resolve -+ # Save %a0 (struct return address) and %a1. -+ move.l %a0, -(%sp) -+ move.l %a1, -(%sp) -+ # Call the real address resolver. -+ jbsr _dl_linux_resolver -+ # Restore register %a0 and %a1. -+ move.l (%sp)+, %a1 -+ move.l (%sp)+, %a0 -+ # Pop parameters -+ addq.l #8, %sp -+ # Call real function. -+ jmp (%d0) -+.size _dl_linux_resolve,.-_dl_linux_resolve -diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/dl-startup.h uClibc-0.9.28/ldso/ldso/mips/dl-startup.h ---- uClibc-0.9.28.orig/ldso/ldso/mips/dl-startup.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/mips/dl-startup.h 2006-04-28 00:14:35.000000000 -0600 -@@ -136,13 +136,3 @@ - SEND_STDERR("Aiieeee!"); \ - _dl_exit(1); \ - } -- -- --/* -- * Transfer control to the user's application, once the dynamic loader -- * is done. This routine has to exit the current function, then -- * call the _dl_elf_main function. For MIPS, we do it in assembly -- * because the stack doesn't get properly restored otherwise. Got look -- * at boot1_arch.h -- */ --#define START() return _dl_elf_main -diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/dl-syscalls.h uClibc-0.9.28/ldso/ldso/mips/dl-syscalls.h ---- uClibc-0.9.28.orig/ldso/ldso/mips/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/mips/dl-syscalls.h 2006-05-02 13:39:25.000000000 -0600 -@@ -1,7 +1,8 @@ - /* We can't use the real errno in ldso, since it has not yet - * been dynamicly linked in yet. */ -+#define __UCLIBC_MMAP_HAS_6_ARGS__ -+ -+#include "sys/syscall.h" - extern int _dl_errno; -+#undef __set_errno - #define __set_errno(X) {(_dl_errno) = (X);} --#include "sys/syscall.h" -- --#define MMAP_HAS_6_ARGS -diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/dl-sysdep.h uClibc-0.9.28/ldso/ldso/mips/dl-sysdep.h ---- uClibc-0.9.28.orig/ldso/ldso/mips/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/mips/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600 -@@ -30,7 +30,7 @@ - /* Initialization sequence for the application/library GOT. */ - #define INIT_GOT(GOT_BASE,MODULE) \ - do { \ -- unsigned long i; \ -+ unsigned long idx; \ - \ - /* Check if this is the dynamic linker itself */ \ - if (MODULE->libtype == program_interpreter) \ -@@ -41,9 +41,9 @@ - GOT_BASE[1] = (unsigned long) MODULE; \ - \ - /* Add load address displacement to all local GOT entries */ \ -- i = 2; \ -- while (i < MODULE->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]) \ -- GOT_BASE[i++] += (unsigned long) MODULE->loadaddr; \ -+ idx = 2; \ -+ while (idx < MODULE->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]) \ -+ GOT_BASE[idx++] += (unsigned long) MODULE->loadaddr; \ - \ - } while (0) - -@@ -63,8 +63,6 @@ - struct elf_resolve; - void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy); - --#define do_rem(result, n, base) ((result) = (n) % (base)) -- - /* 4096 bytes alignment */ - #define PAGE_ALIGN 0xfffff000 - #define ADDR_ALIGN 0xfff -diff -urN uClibc-0.9.28.orig/ldso/ldso/mips/elfinterp.c uClibc-0.9.28/ldso/ldso/mips/elfinterp.c ---- uClibc-0.9.28.orig/ldso/ldso/mips/elfinterp.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/mips/elfinterp.c 2006-04-28 00:14:35.000000000 -0600 -@@ -27,6 +27,8 @@ - * SUCH DAMAGE. - */ - -+#include "ldso.h" -+ - extern int _dl_runtime_resolve(void); - - #define OFFSET_GP_GOT 0x7ff0 -@@ -146,7 +148,6 @@ - break; - default: - { -- int reloc_type = ELF32_R_TYPE(rpnt->r_info); - _dl_dprintf(2, "\n%s: ",_dl_progname); - - if (symtab_index) -diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-startup.h uClibc-0.9.28/ldso/ldso/powerpc/dl-startup.h ---- uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-startup.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/powerpc/dl-startup.h 2006-04-28 00:14:35.000000000 -0600 -@@ -42,8 +42,10 @@ - " bne 2b\n" - " addi 6,6,4\n" - #endif -- /* Pass a termination function pointer (in this case _dl_fini) in r7. */ -- " lwz 7,_dl_fini@got(31)\n" -+ /* Pass a termination function pointer (in this case _dl_fini) in r3. */ -+ /* Paulus promized he would keep r3 zero in the exec ABI. */ -+ " lwz 3,_dl_fini@got(31)\n" -+ " mr 7,3\n" /* Pass _dl_fini in r7 to maintain compat */ - " bctr\n" /* Jump to entry point */ - " .size _start,.-_start\n" - " .previous\n" -@@ -78,9 +80,3 @@ - _dl_exit(100+ELF32_R_TYPE((RELP)->r_info));\ - } \ - } --/* -- * Transfer control to the user's application, once the dynamic loader -- * is done. This routine has to exit the current function, then -- * call the _dl_elf_main function. -- */ --#define START() return _dl_elf_main -diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-syscalls.h uClibc-0.9.28/ldso/ldso/powerpc/dl-syscalls.h ---- uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/powerpc/dl-syscalls.h 2006-05-02 13:39:14.000000000 -0600 -@@ -1,251 +1,8 @@ --/* -- * This file contains the system call macros and syscall -- * numbers used by the shared library loader. -- */ -- --#define MMAP_HAS_6_ARGS -- --#define __NR_exit 1 --#define __NR_read 3 --#define __NR_write 4 --#define __NR_open 5 --#define __NR_close 6 --#define __NR_getpid 20 --#define __NR_getuid 24 --#define __NR_geteuid 49 --#define __NR_getgid 47 --#define __NR_getegid 50 --#define __NR_readlink 85 --#define __NR_mmap 90 --#define __NR_munmap 91 --#define __NR_stat 106 --#define __NR_mprotect 125 -- -- - /* We can't use the real errno in ldso, since it has not yet - * been dynamicly linked in yet. */ --extern int _dl_errno; -- --/* Here are the macros which define how this platform makes -- * system calls. This particular variant does _not_ set -- * errno (note how it is disabled in __syscall_return) since -- * these will get called before the errno symbol is dynamicly -- * linked. */ -- --#undef __syscall_return --#define __syscall_return(type) \ -- return (__sc_err & 0x10000000 ? _dl_errno = __sc_ret, __sc_ret = -1 : 0), \ -- (type) __sc_ret -- --#undef __syscall_clobbers --#define __syscall_clobbers \ -- "r9", "r10", "r11", "r12" -- //"r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" -- --#undef _syscall0 --#define _syscall0(type,name) \ --type name(void) \ --{ \ -- unsigned long __sc_ret, __sc_err; \ -- { \ -- register unsigned long __sc_0 __asm__ ("r0"); \ -- register unsigned long __sc_3 __asm__ ("r3"); \ -- \ -- __sc_0 = __NR_##name; \ -- __asm__ __volatile__ \ -- ("sc \n\t" \ -- "mfcr %1 " \ -- : "=&r" (__sc_3), "=&r" (__sc_0) \ -- : "0" (__sc_3), "1" (__sc_0) \ -- : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \ -- __sc_ret = __sc_3; \ -- __sc_err = __sc_0; \ -- } \ -- __syscall_return (type); \ --} -- --#undef _syscall1 --#define _syscall1(type,name,type1,arg1) \ --type name(type1 arg1) \ --{ \ -- unsigned long __sc_ret, __sc_err; \ -- { \ -- register unsigned long __sc_0 __asm__ ("r0"); \ -- register unsigned long __sc_3 __asm__ ("r3"); \ -- \ -- __sc_3 = (unsigned long) (arg1); \ -- __sc_0 = __NR_##name; \ -- __asm__ __volatile__ \ -- ("sc \n\t" \ -- "mfcr %1 " \ -- : "=&r" (__sc_3), "=&r" (__sc_0) \ -- : "0" (__sc_3), "1" (__sc_0) \ -- : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \ -- __sc_ret = __sc_3; \ -- __sc_err = __sc_0; \ -- } \ -- __syscall_return (type); \ --} -- --#undef _syscall2 --#define _syscall2(type,name,type1,arg1,type2,arg2) \ --type name(type1 arg1, type2 arg2) \ --{ \ -- unsigned long __sc_ret, __sc_err; \ -- { \ -- register unsigned long __sc_0 __asm__ ("r0"); \ -- register unsigned long __sc_3 __asm__ ("r3"); \ -- register unsigned long __sc_4 __asm__ ("r4"); \ -- \ -- __sc_3 = (unsigned long) (arg1); \ -- __sc_4 = (unsigned long) (arg2); \ -- __sc_0 = __NR_##name; \ -- __asm__ __volatile__ \ -- ("sc \n\t" \ -- "mfcr %1 " \ -- : "=&r" (__sc_3), "=&r" (__sc_0) \ -- : "0" (__sc_3), "1" (__sc_0), \ -- "r" (__sc_4) \ -- : "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \ -- __sc_ret = __sc_3; \ -- __sc_err = __sc_0; \ -- } \ -- __syscall_return (type); \ --} -- --#undef _syscall3 --#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ --type name(type1 arg1, type2 arg2, type3 arg3) \ --{ \ -- unsigned long __sc_ret, __sc_err; \ -- { \ -- register unsigned long __sc_0 __asm__ ("r0"); \ -- register unsigned long __sc_3 __asm__ ("r3"); \ -- register unsigned long __sc_4 __asm__ ("r4"); \ -- register unsigned long __sc_5 __asm__ ("r5"); \ -- \ -- __sc_3 = (unsigned long) (arg1); \ -- __sc_4 = (unsigned long) (arg2); \ -- __sc_5 = (unsigned long) (arg3); \ -- __sc_0 = __NR_##name; \ -- __asm__ __volatile__ \ -- ("sc \n\t" \ -- "mfcr %1 " \ -- : "=&r" (__sc_3), "=&r" (__sc_0) \ -- : "0" (__sc_3), "1" (__sc_0), \ -- "r" (__sc_4), \ -- "r" (__sc_5) \ -- : "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); \ -- __sc_ret = __sc_3; \ -- __sc_err = __sc_0; \ -- } \ -- __syscall_return (type); \ --} -- --#undef _syscall4 --#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ --type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ --{ \ -- unsigned long __sc_ret, __sc_err; \ -- { \ -- register unsigned long __sc_0 __asm__ ("r0"); \ -- register unsigned long __sc_3 __asm__ ("r3"); \ -- register unsigned long __sc_4 __asm__ ("r4"); \ -- register unsigned long __sc_5 __asm__ ("r5"); \ -- register unsigned long __sc_6 __asm__ ("r6"); \ -- \ -- __sc_3 = (unsigned long) (arg1); \ -- __sc_4 = (unsigned long) (arg2); \ -- __sc_5 = (unsigned long) (arg3); \ -- __sc_6 = (unsigned long) (arg4); \ -- __sc_0 = __NR_##name; \ -- __asm__ __volatile__ \ -- ("sc \n\t" \ -- "mfcr %1 " \ -- : "=&r" (__sc_3), "=&r" (__sc_0) \ -- : "0" (__sc_3), "1" (__sc_0), \ -- "r" (__sc_4), \ -- "r" (__sc_5), \ -- "r" (__sc_6) \ -- : "r7", "r8", "r9", "r10", "r11", "r12" ); \ -- __sc_ret = __sc_3; \ -- __sc_err = __sc_0; \ -- } \ -- __syscall_return (type); \ --} -- --#undef _syscall5 --#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ --type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ --{ \ -- unsigned long __sc_ret, __sc_err; \ -- { \ -- register unsigned long __sc_0 __asm__ ("r0"); \ -- register unsigned long __sc_3 __asm__ ("r3"); \ -- register unsigned long __sc_4 __asm__ ("r4"); \ -- register unsigned long __sc_5 __asm__ ("r5"); \ -- register unsigned long __sc_6 __asm__ ("r6"); \ -- register unsigned long __sc_7 __asm__ ("r7"); \ -- \ -- __sc_3 = (unsigned long) (arg1); \ -- __sc_4 = (unsigned long) (arg2); \ -- __sc_5 = (unsigned long) (arg3); \ -- __sc_6 = (unsigned long) (arg4); \ -- __sc_7 = (unsigned long) (arg5); \ -- __sc_0 = __NR_##name; \ -- __asm__ __volatile__ \ -- ("sc \n\t" \ -- "mfcr %1 " \ -- : "=&r" (__sc_3), "=&r" (__sc_0) \ -- : "0" (__sc_3), "1" (__sc_0), \ -- "r" (__sc_4), \ -- "r" (__sc_5), \ -- "r" (__sc_6), \ -- "r" (__sc_7) \ -- : "r8", "r9", "r10", "r11", "r12" ); \ -- __sc_ret = __sc_3; \ -- __sc_err = __sc_0; \ -- } \ -- __syscall_return (type); \ --} -- -- --#undef _syscall6 --#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ --type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ --{ \ -- unsigned long __sc_ret, __sc_err; \ -- { \ -- register unsigned long __sc_0 __asm__ ("r0"); \ -- register unsigned long __sc_3 __asm__ ("r3"); \ -- register unsigned long __sc_4 __asm__ ("r4"); \ -- register unsigned long __sc_5 __asm__ ("r5"); \ -- register unsigned long __sc_6 __asm__ ("r6"); \ -- register unsigned long __sc_7 __asm__ ("r7"); \ -- register unsigned long __sc_8 __asm__ ("r8"); \ -- \ -- __sc_3 = (unsigned long) (arg1); \ -- __sc_4 = (unsigned long) (arg2); \ -- __sc_5 = (unsigned long) (arg3); \ -- __sc_6 = (unsigned long) (arg4); \ -- __sc_7 = (unsigned long) (arg5); \ -- __sc_8 = (unsigned long) (arg6); \ -- __sc_0 = __NR_##name; \ -- __asm__ __volatile__ \ -- ("sc \n\t" \ -- "mfcr %1 " \ -- : "=&r" (__sc_3), "=&r" (__sc_0) \ -- : "0" (__sc_3), "1" (__sc_0), \ -- "r" (__sc_4), \ -- "r" (__sc_5), \ -- "r" (__sc_6), \ -- "r" (__sc_7), \ -- "r" (__sc_8) \ -- : "r9", "r10", "r11", "r12" ); \ -- __sc_ret = __sc_3; \ -- __sc_err = __sc_0; \ -- } \ -- __syscall_return (type); \ --} -- -+#define __UCLIBC_MMAP_HAS_6_ARGS__ - -+#include "sys/syscall.h" -+extern int _dl_errno; -+#undef __set_errno -+#define __set_errno(X) {(_dl_errno) = (X);} -diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-sysdep.h uClibc-0.9.28/ldso/ldso/powerpc/dl-sysdep.h ---- uClibc-0.9.28.orig/ldso/ldso/powerpc/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/powerpc/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600 -@@ -67,9 +67,6 @@ - extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt); - -- --#define do_rem(result, n, base) ((result) = (n) % (base)) -- - /* 4096 bytes alignment */ - #define PAGE_ALIGN 0xfffff000 - #define ADDR_ALIGN 0xfff -diff -urN uClibc-0.9.28.orig/ldso/ldso/powerpc/elfinterp.c uClibc-0.9.28/ldso/ldso/powerpc/elfinterp.c ---- uClibc-0.9.28.orig/ldso/ldso/powerpc/elfinterp.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/powerpc/elfinterp.c 2006-04-28 00:14:35.000000000 -0600 -@@ -29,6 +29,8 @@ - * SUCH DAMAGE. - */ - -+#include "ldso.h" -+ - extern int _dl_linux_resolve(void); - - void _dl_init_got(unsigned long *plt,struct elf_resolve *tpnt) -@@ -138,7 +140,7 @@ - finaladdr = (Elf32_Addr) _dl_find_hash(symname, - tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT); - if (unlikely(!finaladdr)) { -- _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); -+ _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname); - _dl_exit(1); - }; - finaladdr += this_reloc->r_addend; -@@ -379,15 +381,15 @@ - { - int reloc_type = ELF32_R_TYPE(rpnt->r_info); - #if defined (__SUPPORT_LD_DEBUG__) -- _dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type)); -+ _dl_dprintf(2, "can't handle reloc type '%s' in lib '%s'\n", _dl_reltypes(reloc_type), tpnt->libname); - #else -- _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type); -+ _dl_dprintf(2, "can't handle reloc type %x in lib '%s'\n", reloc_type, tpnt->libname); - #endif -- _dl_exit(-res); -+ return res; - } - if (unlikely(res >0)) - { -- _dl_dprintf(2, "can't resolve symbol\n"); -+ _dl_dprintf(2, "can't resolve symbol in lib '%s'.\n", tpnt->libname); - return res; - } - } -diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/dl-startup.h uClibc-0.9.28/ldso/ldso/sh/dl-startup.h ---- uClibc-0.9.28.orig/ldso/ldso/sh/dl-startup.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/sh/dl-startup.h 2006-04-28 00:14:35.000000000 -0600 -@@ -55,11 +55,3 @@ - default: \ - _dl_exit(1); \ - } -- -- --/* -- * Transfer control to the user's application, once the dynamic loader -- * is done. This routine has to exit the current function, then -- * call the _dl_elf_main function. -- */ --#define START() return _dl_elf_main; -diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/dl-syscalls.h uClibc-0.9.28/ldso/ldso/sh/dl-syscalls.h ---- uClibc-0.9.28.orig/ldso/ldso/sh/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/sh/dl-syscalls.h 2006-05-02 13:39:28.000000000 -0600 -@@ -1,7 +1,8 @@ - /* We can't use the real errno in ldso, since it has not yet - * been dynamicly linked in yet. */ -+#define __UCLIBC_MMAP_HAS_6_ARGS__ -+ -+#include "sys/syscall.h" - extern int _dl_errno; -+#undef __set_errno - #define __set_errno(X) {(_dl_errno) = (X);} --#include "sys/syscall.h" -- --#define MMAP_HAS_6_ARGS -diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/dl-sysdep.h uClibc-0.9.28/ldso/ldso/sh/dl-sysdep.h ---- uClibc-0.9.28.orig/ldso/ldso/sh/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/sh/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600 -@@ -25,7 +25,7 @@ - struct elf_resolve; - extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - --static __inline__ unsigned int -+static inline unsigned int - _dl_urem(unsigned int n, unsigned int base) - { - int res; -@@ -104,7 +104,7 @@ - elf_machine_dynamic (void) - { - register Elf32_Addr *got; -- asm ("mov r12,%0" :"=r" (got)); -+ __asm__ ("mov r12,%0" :"=r" (got)); - return *got; - } - -@@ -113,7 +113,7 @@ - elf_machine_load_address (void) - { - Elf32_Addr addr; -- asm ("mov.l 1f,r0\n\ -+ __asm__ ("mov.l 1f,r0\n\ - mov.l 3f,r2\n\ - add r12,r2\n\ - mov.l @(r0,r12),r0\n\ -diff -urN uClibc-0.9.28.orig/ldso/ldso/sh/elfinterp.c uClibc-0.9.28/ldso/ldso/sh/elfinterp.c ---- uClibc-0.9.28.orig/ldso/ldso/sh/elfinterp.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/sh/elfinterp.c 2006-04-28 00:14:35.000000000 -0600 -@@ -39,6 +39,8 @@ - a more than adequate job of explaining everything required to get this - working. */ - -+#include "ldso.h" -+ - extern int _dl_linux_resolve(void); - - unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) -diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/dl-startup.h uClibc-0.9.28/ldso/ldso/sh64/dl-startup.h ---- uClibc-0.9.28.orig/ldso/ldso/sh64/dl-startup.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/sh64/dl-startup.h 2006-04-28 00:14:35.000000000 -0600 -@@ -115,12 +115,3 @@ - default: \ - _dl_exit(1); \ - } -- --/* -- * Transfer control to the user's application, once the dynamic loader -- * is done. This routine has to exit the current function, then -- * call the _dl_elf_main function. -- */ -- --#define START() return _dl_elf_main; -- -diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/dl-syscalls.h uClibc-0.9.28/ldso/ldso/sh64/dl-syscalls.h ---- uClibc-0.9.28.orig/ldso/ldso/sh64/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/sh64/dl-syscalls.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,8 +1,9 @@ - /* 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/syscall.h" - - #undef __syscall_return - #define __syscall_return(type, res) \ -diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/dl-sysdep.h uClibc-0.9.28/ldso/ldso/sh64/dl-sysdep.h ---- uClibc-0.9.28.orig/ldso/ldso/sh64/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/sh64/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600 -@@ -25,8 +25,6 @@ - struct elf_resolve; - extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - --#define do_rem(result, n, base) ((result) = (n) % (base)) -- - /* 4096 bytes alignment */ - #define PAGE_ALIGN 0xfffff000 - #define ADDR_ALIGN 0xfff -diff -urN uClibc-0.9.28.orig/ldso/ldso/sh64/elfinterp.c uClibc-0.9.28/ldso/ldso/sh64/elfinterp.c ---- uClibc-0.9.28.orig/ldso/ldso/sh64/elfinterp.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/sh64/elfinterp.c 2006-04-28 00:14:35.000000000 -0600 -@@ -41,6 +41,8 @@ - a more than adequate job of explaining everything required to get this - working. */ - -+#include "ldso.h" -+ - extern int _dl_linux_resolve(void); - - unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) -diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/dl-startup.h uClibc-0.9.28/ldso/ldso/sparc/dl-startup.h ---- uClibc-0.9.28.orig/ldso/ldso/sparc/dl-startup.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/sparc/dl-startup.h 2006-04-28 00:14:35.000000000 -0600 -@@ -3,15 +3,46 @@ - * needed for this architecture. See arm/boot1_arch.h for an example of what - * can be done. - */ --asm( -- " .text\n" -- " .global _start\n" -- " .type _start,%function\n" -- "_start:\n" -- " .set _start,_dl_start\n" -- " .size _start,.-_start\n" -- " .previous\n" --); -+ -+asm ("\ -+ .text\n\ -+ .global _start\n\ -+ .type _start,%function\n\ -+ .align 32\n\ -+_start:\n\ -+ /* Allocate space for functions to drop their arguments. */\n\ -+ sub %sp, 6*4, %sp\n\ -+ /* Pass pointer to argument block to _dl_start. */\n\ -+ call _dl_start\n\ -+ add %sp, 22*4, %o0\n\ -+ /* FALTHRU */\n\ -+ .globl _dl_start_user\n\ -+ .type _dl_start_user, @function\n\ -+_dl_start_user:\n\ -+ /* Load the PIC register. */\n\ -+1: call 2f\n\ -+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\ -+2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\ -+ add %l7, %o7, %l7\n\ -+ /* Save the user entry point address in %l0 */\n\ -+ mov %o0, %l0\n\ -+ /* See if we were run as a command with the executable file name as an\n\ -+ extra leading argument. If so, adjust the contents of the stack. */\n\ -+ sethi %hi(_dl_skip_args), %g2\n\ -+ or %g2, %lo(_dl_skip_args), %g2\n\ -+ ld [%l7+%g2], %i0\n\ -+ ld [%i0], %i0\n\ -+ tst %i0\n\ -+ /* Pass our finalizer function to the user in %g1. */\n\ -+ sethi %hi(_dl_fini), %g1\n\ -+ or %g1, %lo(_dl_fini), %g1\n\ -+ ld [%l7+%g1], %g1\n\ -+ /* Jump to the user's entry point and deallocate the extra stack we got. */\n\ -+ jmp %l0\n\ -+ add %sp, 6*4, %sp\n\ -+ .size _dl_start_user, . - _dl_start_user\n\ -+ .previous\n\ -+"); - - /* - * Get a pointer to the argv array. On many platforms this can be just -@@ -19,17 +50,15 @@ - * do something a little more subtle here. We assume that argc is stored - * at the word just below the argvp that we return here. - */ --#define GET_ARGV(ARGVP, ARGS) __asm__("\tadd %%fp,68,%0\n" : "=r" (ARGVP)); -+#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. - */ - #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ -- switch(ELF32_R_TYPE((RELP)->r_info)) { \ -+switch(ELF_R_TYPE((RELP)->r_info)) { \ - case R_SPARC_32: \ -- *REL = SYMBOL + (RELP)->r_addend; \ -- break; \ - case R_SPARC_GLOB_DAT: \ - *REL = SYMBOL + (RELP)->r_addend; \ - break; \ -@@ -38,7 +67,6 @@ - REL[2] = 0x81c06000 | (SYMBOL & 0x3ff); \ - break; \ - case R_SPARC_NONE: \ -- break; \ - case R_SPARC_WDISP30: \ - break; \ - case R_SPARC_RELATIVE: \ -@@ -46,18 +74,4 @@ - break; \ - default: \ - _dl_exit(1); \ -- } -- --/* -- * Transfer control to the user's application, once the dynamic loader -- * is done. The crt calls atexit with $g1 if not null, so we need to -- * ensure that it contains NULL. -- */ -- --#define START() \ -- __asm__ volatile ( \ -- "add %%g0,%%g0,%%g1\n\t" \ -- "jmpl %0, %%o7\n\t" \ -- "restore %%g0,%%g0,%%g0\n\t" \ -- : /*"=r" (status) */ : \ -- "r" (_dl_elf_main): "g1", "o0", "o1") -+} -diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/dl-syscalls.h uClibc-0.9.28/ldso/ldso/sparc/dl-syscalls.h ---- uClibc-0.9.28.orig/ldso/ldso/sparc/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/sparc/dl-syscalls.h 2006-05-02 13:39:21.000000000 -0600 -@@ -1,187 +1,8 @@ --/* -- * This file contains the system call macros and syscall -- * numbers used by the shared library loader. -- * -- * NOTE: This should be integrated/moved to -- * sysdeps/linux/sparc/bits/syscalls.h at some point ... -- */ -- --#define MMAP_HAS_6_ARGS -- --#define __NR_exit 1 --#define __NR_read 3 --#define __NR_write 4 --#define __NR_open 5 --#define __NR_close 6 --#define __NR_getpid 20 --#define __NR_getuid 24 --#define __NR_getgid 47 --#define __NR_geteuid 49 --#define __NR_getegid 50 --#define __NR_readlink 58 --#define __NR_mmap 71 --#define __NR_munmap 73 --#define __NR_stat 38 --#define __NR_mprotect 74 -- - /* We can't use the real errno in ldso, since it has not yet - * been dynamicly linked in yet. */ -+#define __UCLIBC_MMAP_HAS_6_ARGS__ -+ -+#include "sys/syscall.h" - extern int _dl_errno; -+#undef __set_errno - #define __set_errno(X) {(_dl_errno) = (X);} -- --/* Here are the macros which define how this platform makes -- * system calls. This particular variant does _not_ set -- * errno (note how _dl_errno is used in __syscall_return) since -- * these will get called before the errno symbol is dynamicly -- * linked. */ -- --#define __syscall_return(type, res) \ --do { \ -- if (res < -255 || res >= 0) \ -- return (type) res; \ -- __set_errno(-res); \ -- res = -1; \ -- return (type) res; \ --} while (0) -- --#define _syscall0(type,name) \ --type name(void) \ --{ \ -- long __res; \ -- register long __g1 __asm__ ("g1") = __NR_##name; \ -- __asm__ __volatile__ ( \ -- "t 0x10\n\t" \ -- "bcc 1f\n\t" \ -- "mov %%o0, %0\n\t" \ -- "sub %%g0, %%o0, %0\n\t" \ -- "1:\n\t" \ -- : "=r" (__res)\ -- : "r" (__g1) \ -- : "o0", "cc"); \ -- __syscall_return(type, __res); \ --} -- --#define _syscall1(type,name,type1,arg1) \ --type name(type1 arg1) \ --{ \ -- long __res; \ -- register long __g1 __asm__ ("g1") = __NR_##name; \ -- register long __o0 __asm__ ("o0") = (long)(arg1); \ -- __asm__ __volatile__ ( \ -- "t 0x10\n\t" \ -- "bcc 1f\n\t" \ -- "mov %%o0, %0\n\t" \ -- "sub %%g0, %%o0, %0\n\t" \ -- "1:\n\t" \ -- : "=r" (__res), "=&r" (__o0) \ -- : "1" (__o0), "r" (__g1) \ -- : "cc"); \ -- __syscall_return(type, __res); \ --} -- --#define _syscall2(type,name,type1,arg1,type2,arg2) \ --type name(type1 arg1,type2 arg2) \ --{ \ -- long __res; \ -- register long __g1 __asm__ ("g1") = __NR_##name; \ -- register long __o0 __asm__ ("o0") = (long)(arg1); \ -- register long __o1 __asm__ ("o1") = (long)(arg2); \ -- __asm__ __volatile__ ( \ -- "t 0x10\n\t" \ -- "bcc 1f\n\t" \ -- "mov %%o0, %0\n\t" \ -- "sub %%g0, %%o0, %0\n\t" \ -- "1:\n\t" \ -- : "=r" (__res), "=&r" (__o0) \ -- : "1" (__o0), "r" (__o1), "r" (__g1) \ -- : "cc"); \ -- __syscall_return(type, __res); \ --} -- --#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ --type name(type1 arg1,type2 arg2,type3 arg3) \ --{ \ -- long __res; \ -- register long __g1 __asm__ ("g1") = __NR_##name; \ -- register long __o0 __asm__ ("o0") = (long)(arg1); \ -- register long __o1 __asm__ ("o1") = (long)(arg2); \ -- register long __o2 __asm__ ("o2") = (long)(arg3); \ -- __asm__ __volatile__ ( \ -- "t 0x10\n\t" \ -- "bcc 1f\n\t" \ -- "mov %%o0, %0\n\t" \ -- "sub %%g0, %%o0, %0\n\t" \ -- "1:\n\t" \ -- : "=r" (__res), "=&r" (__o0) \ -- : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \ -- : "cc"); \ -- __syscall_return(type, __res); \ --} -- --#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ --type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ --{ \ -- long __res; \ -- register long __g1 __asm__ ("g1") = __NR_##name; \ -- register long __o0 __asm__ ("o0") = (long)(arg1); \ -- register long __o1 __asm__ ("o1") = (long)(arg2); \ -- register long __o2 __asm__ ("o2") = (long)(arg3); \ -- register long __o3 __asm__ ("o3") = (long)(arg4); \ -- __asm__ __volatile__ ( \ -- "t 0x10\n\t" \ -- "bcc 1f\n\t" \ -- "mov %%o0, %0\n\t" \ -- "sub %%g0, %%o0, %0\n\t" \ -- "1:\n\t" \ -- : "=r" (__res), "=&r" (__o0) \ -- : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \ -- : "cc"); \ -- __syscall_return(type, __res); \ --} -- --#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -- type5,arg5) \ --type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ --{ \ -- long __res; \ -- register long __g1 __asm__ ("g1") = __NR_##name; \ -- register long __o0 __asm__ ("o0") = (long)(arg1); \ -- register long __o1 __asm__ ("o1") = (long)(arg2); \ -- register long __o2 __asm__ ("o2") = (long)(arg3); \ -- register long __o3 __asm__ ("o3") = (long)(arg4); \ -- register long __o4 __asm__ ("o4") = (long)(arg5); \ -- __asm__ __volatile__ ( \ -- "t 0x10\n\t" \ -- "bcc 1f\n\t" \ -- "mov %%o0, %0\n\t" \ -- "sub %%g0, %%o0, %0\n\t" \ -- "1:\n\t" \ -- : "=r" (__res), "=&r" (__o0) \ -- : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \ -- : "cc"); \ -- __syscall_return(type, __res); \ --} -- --#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -- type5,arg5,type6,arg6) \ --type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ --{ \ -- long __res; \ -- register long __g1 __asm__ ("g1") = __NR_##name; \ -- register long __o0 __asm__ ("o0") = (long)(arg1); \ -- register long __o1 __asm__ ("o1") = (long)(arg2); \ -- register long __o2 __asm__ ("o2") = (long)(arg3); \ -- register long __o3 __asm__ ("o3") = (long)(arg4); \ -- register long __o4 __asm__ ("o4") = (long)(arg5); \ -- register long __o5 __asm__ ("o5") = (long)(arg6); \ -- __asm__ __volatile__ ( \ -- "t 0x10\n\t" \ -- "bcc 1f\n\t" \ -- "mov %%o0, %0\n\t" \ -- "sub %%g0, %%o0, %0\n\t" \ -- "1:\n\t" \ -- : "=r" (__res), "=&r" (__o0) \ -- : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__o5), "r" (__g1) \ -- : "cc"); \ -- __syscall_return(type, __res); \ --} -diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/dl-sysdep.h uClibc-0.9.28/ldso/ldso/sparc/dl-sysdep.h ---- uClibc-0.9.28.orig/ldso/ldso/sparc/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/sparc/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600 -@@ -1,9 +1,9 @@ -- -+/* vi: set sw=4 ts=4: */ - /* - * Various assmbly language/system dependent hacks that are required - * so that we can minimize the amount of platform specific code. -+ * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org> - */ --#define LINUXBIN - - /* Define this if the system uses RELOCA. */ - #define ELF_USES_RELOCA -@@ -31,19 +31,14 @@ - #undef MAGIC2 - - /* Used for error messages */ --#define ELF_TARGET "Sparc" -+#define ELF_TARGET "sparc" - --#ifndef COMPILE_ASM --extern unsigned int _dl_linux_resolver(unsigned int reloc_entry, -- unsigned int * i); --#endif -+struct elf_resolve; -+unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - - /* - * Define this if you want a dynamic loader that works on Solaris. - */ --#ifndef __linux__ --#define SOLARIS_COMPATIBLE --#endif - - #ifndef COMPILE_ASM - /* Cheap modulo implementation, taken from arm/ld_sysdep.h. */ -@@ -87,13 +82,6 @@ - #define do_rem(result, n, base) ((result) = sparc_mod(n, base)) - #endif - --/* -- * dbx wants the binder to have a specific name. Mustn't disappoint it. -- */ --#ifdef SOLARIS_COMPATIBLE --#define _dl_linux_resolve _elf_rtbndr --#endif -- - /* 4096 bytes alignment */ - /* ...but 8192 is required for mmap() on sparc64 kernel */ - #define PAGE_ALIGN 0xffffe000 -@@ -160,7 +148,7 @@ - elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, - Elf32_Word relative_count) - { -- Elf32_Rela * rpnt = (void *)rel_addr; -+ Elf32_Rela * rpnt = (void *)rel_addr; - --rpnt; - do { - Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset); -diff -urN uClibc-0.9.28.orig/ldso/ldso/sparc/elfinterp.c uClibc-0.9.28/ldso/ldso/sparc/elfinterp.c ---- uClibc-0.9.28.orig/ldso/ldso/sparc/elfinterp.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/sparc/elfinterp.c 2006-04-28 00:14:35.000000000 -0600 -@@ -33,236 +33,340 @@ - 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. */ -+ 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. */ -+ -+/* Some SPARC opcodes we need to use for self-modifying code. */ -+#define OPCODE_NOP 0x01000000 /* nop */ -+#define OPCODE_CALL 0x40000000 /* call ?; add PC-rel word address */ -+#define OPCODE_SETHI_G1 0x03000000 /* sethi ?, %g1; add value>>10 */ -+#define OPCODE_JMP_G1 0x81c06000 /* jmp %g1+?; add lo 10 bits of value */ -+#define OPCODE_SAVE_SP 0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */ -+#define OPCODE_BA 0x30800000 /* b,a ?; add PC-rel word address */ - - extern int _dl_linux_resolve(void); - --unsigned int _dl_linux_resolver(unsigned int reloc_entry, unsigned int * plt) -+unsigned long -+_dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) - { -- int reloc_type; -- Elf32_Rela * this_reloc; -- char * strtab; -- Elf32_Sym * symtab; -- Elf32_Rela * rel_addr; -- struct elf_resolve * tpnt; -- int symtab_index; -- char * new_addr; -- char ** got_addr; -- unsigned int instr_addr; -- tpnt = (struct elf_resolve *) plt[2]; -- -- rel_addr = (Elf32_Rela *)tpnt->dynamic_info[DT_JMPREL]; -- -- /* -- * Generate the correct relocation index into the .rela.plt section. -- */ -- reloc_entry = (reloc_entry >> 10) - 0xc; -- -- this_reloc = (Elf32_Rela *) ((char *) rel_addr + reloc_entry); -- -- reloc_type = ELF32_R_TYPE(this_reloc->r_info); -- symtab_index = ELF32_R_SYM(this_reloc->r_info); -- -- symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB]; -- strtab = (char *)tpnt->dynamic_info[DT_STRTAB]; -- --#ifdef __SUPPORT_LD_DEBUG__ -- if (_dl_debug_symbols) { -- _dl_dprintf(2, "tpnt = %x\n", tpnt); -- _dl_dprintf(2, "reloc = %x\n", this_reloc); -- _dl_dprintf(2, "symtab = %x\n", symtab); -- _dl_dprintf(2, "strtab = %x\n", strtab); -- } --#endif -- -- -- if (unlikely(reloc_type != R_SPARC_JMP_SLOT)) { -- _dl_dprintf(2, "%s: incorrect relocation type in jump relocations (%d)\n", -- _dl_progname, reloc_type); -- _dl_exit(30); -- }; -- -- /* Address of jump instruction to fix up */ -- instr_addr = ((int)this_reloc->r_offset + (int)tpnt->loadaddr); -- got_addr = (char **) instr_addr; -- --#ifdef __SUPPORT_LD_DEBUG__ -- if (_dl_debug_symbols) { -- _dl_dprintf(2, "symtab_index %x\n", symtab_index); -- -- _dl_dprintf(2, "Resolving symbol %s\n", -- strtab + symtab[symtab_index].st_name); -- } --#endif -- -- /* Get the address of the GOT entry */ -- new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, -- tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT); -- if(unlikely(!new_addr)) { -- _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", -- _dl_progname, strtab + symtab[symtab_index].st_name); -- _dl_exit(31); -- }; -+ int reloc_type; -+ ELF_RELOC *this_reloc; -+ char *strtab; -+ ElfW(Sym) *symtab; -+ int symtab_index; -+ char *rel_addr; -+ char *new_addr; -+ char **got_addr; -+ ElfW(Addr) instr_addr; -+ char *symname; -+ -+ rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL]; -+ /* -+ * Generate the correct relocation index into the .rela.plt section. -+ */ -+ reloc_entry = (reloc_entry >> 10) - 0xc; -+ -+ this_reloc = (ELF_RELOC *)(rel_addr + reloc_entry); -+ reloc_type = ELF_R_TYPE(this_reloc->r_info); -+ symtab_index = ELF_R_SYM(this_reloc->r_info); -+ -+ symtab = (ElfW(Sym) *)tpnt->dynamic_info[DT_SYMTAB]; -+ strtab = (char *)tpnt->dynamic_info[DT_STRTAB]; -+ symname = strtab + symtab[symtab_index].st_name; -+ -+ if (unlikely(reloc_type != R_SPARC_JMP_SLOT)) { -+ _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n", -+ _dl_progname); -+ _dl_exit(1); -+ } -+ -+ /* Address of the jump instruction to fix up. */ -+ instr_addr = (this_reloc->r_offset + tpnt->loadaddr); -+ got_addr = (char **)instr_addr; -+ -+ /* Get the address of the GOT entry */ -+ new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT); -+ if (unlikely(!new_addr)) { -+ _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname); -+ _dl_exit(1); -+ } - - #if defined (__SUPPORT_LD_DEBUG__) -- if ((unsigned long) got_addr < 0x40000000) -- { -- if (_dl_debug_bindings) -- { -- _dl_dprintf(_dl_debug_file, "\nresolve function: %s", -- strtab + symtab[symtab_index].st_name); -- if(_dl_debug_detail) _dl_dprintf(_dl_debug_file, -- "\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr); -+ if ((unsigned long)got_addr < 0x40000000) { -+ if (_dl_debug_bindings) { -+ _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname); -+ if (_dl_debug_detail) -+ _dl_dprintf(_dl_debug_file, -+ "\tpatched: %x ==> %x @ %x\n", -+ *got_addr, new_addr, got_addr); - } - } -- if (!_dl_debug_nofixups) { -+ if (!_dl_debug_nofixups) -+#endif -+ { - got_addr[1] = (char *) (0x03000000 | (((unsigned int) new_addr >> 10) & 0x3fffff)); - got_addr[2] = (char *) (0x81c06000 | ((unsigned int) new_addr & 0x3ff)); - } -+ -+ return (unsigned long)new_addr; -+} -+ -+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; -+ -+ /* Parse the relocation information. */ -+ rpnt = (ELF_RELOC *)rel_addr; -+ 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 (unlikely(res < 0)) { -+ int reloc_type = ELF_R_TYPE(rpnt->r_info); -+ -+ _dl_dprintf(2, "can't handle reloc type " -+#if defined (__SUPPORT_LD_DEBUG__) -+ "%s\n", _dl_reltypes(reloc_type)); - #else -- got_addr[1] = (char *) (0x03000000 | (((unsigned int) new_addr >> 10) & 0x3fffff)); -- got_addr[2] = (char *) (0x81c06000 | ((unsigned int) new_addr & 0x3ff)); -+ "%x\n", reloc_type); - #endif -+ _dl_exit(-res); -+ } else if (unlikely(res > 0)) { -+ _dl_dprintf(2, "can't resolve symbol\n"); -+ return res; -+ } -+ } -+ -+ return 0; -+} - -- _dl_dprintf(2, "Address = %x\n",new_addr); -- _dl_exit(32); -+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; -+ ElfW(Sym) *sym; -+ ElfW(Addr) *reloc_addr; -+ ElfW(Addr) symbol_addr; -+#if defined (__SUPPORT_LD_DEBUG__) -+ ElfW(Addr) old_val; -+#endif -+ -+ reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset); -+ reloc_type = ELF_R_TYPE(rpnt->r_info); -+ symtab_index = ELF_R_SYM(rpnt->r_info); -+ sym = &symtab[symtab_index]; -+ symbol_addr = 0; -+ symname = strtab + sym->st_name; -+ -+ if (symtab_index) { -+ symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt, -+ elf_machine_type_class(reloc_type)); -+ /* -+ * 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 (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) { -+ _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); -+ _dl_exit(1); -+ } -+ } -+ -+#if defined (__SUPPORT_LD_DEBUG__) -+ old_val = *reloc_addr; -+#endif - -- return (unsigned int) new_addr; -+ symbol_addr += rpnt->r_addend; /* Assume copy relocs have zero addend. */ -+ -+ switch (reloc_type) { -+ case R_SPARC_NONE: -+ break; -+ -+#if 0 /* these dont really seem to be useful */ -+ case R_SPARC_8: -+ *(char *) reloc_addr = symbol_addr; -+ break; -+ case R_SPARC_16: -+ *(short *) reloc_addr = symbol_addr; -+ break; -+ case R_SPARC_DISP8: -+ *(char *) reloc_addr = (symbol_addr) - (Elf32_Addr) reloc_addr; -+ break; -+ case R_SPARC_DISP16: -+ *(short *) reloc_addr = (symbol_addr) - (Elf32_Addr) reloc_addr; -+ break; -+#endif -+ -+ case R_SPARC_DISP32: -+ *reloc_addr = symbol_addr - (unsigned int) reloc_addr; -+ break; -+ -+ case R_SPARC_LO10: -+ if (!symbol_addr) -+ symbol_addr = tpnt->loadaddr + rpnt->r_addend; -+ else -+ symbol_addr += rpnt->r_addend; -+ *reloc_addr = (*reloc_addr & ~0x3ff)|(symbol_addr & 0x3ff); -+ break; -+ -+ case R_SPARC_GLOB_DAT: -+ case R_SPARC_32: -+ *reloc_addr = symbol_addr; -+ break; -+ -+ case R_SPARC_JMP_SLOT: -+/* -+value = symbol_addr; -+value += reloc->r_addend; -+disp = value - reloc_addr; -+reloc_addr[1] = OPCODE_JMP_G1 | (value & 0x3ff); -+reloc_addr[0] = OPCODE_SETHI_G1 | (value >> 10); -+ reloc_addr[1] = OPCODE_JMP_G1 | ((symbol_addr-(Elf32_Addr)reloc_addr) & 0x3ff); -+ reloc_addr[0] = OPCODE_SETHI_G1 | ((symbol_addr-(Elf32_Addr)reloc_addr) >> 10); -+*/ -+ reloc_addr[1] = 0x03000000 | ((symbol_addr >> 10) & 0x3fffff); -+ reloc_addr[2] = 0x81c06000 | (symbol_addr & 0x3ff); -+ break; -+ -+ case R_SPARC_RELATIVE: -+ *reloc_addr += tpnt->loadaddr + rpnt->r_addend; -+ break; -+ -+ case R_SPARC_WDISP30: -+ *reloc_addr = (*reloc_addr & 0xc0000000)| -+ ((symbol_addr - (unsigned int) reloc_addr) >> 2); -+ break; -+ -+ case R_SPARC_HI22: -+ if (!symbol_addr) -+ symbol_addr = tpnt->loadaddr + rpnt->r_addend; -+ else -+ symbol_addr += rpnt->r_addend; -+ *reloc_addr = (*reloc_addr & 0xffc00000) | (symbol_addr >> 10); -+ break; -+ -+ case R_SPARC_COPY: -+ if (symbol_addr) { -+#if defined (__SUPPORT_LD_DEBUG__) -+ if (_dl_debug_move) -+ _dl_dprintf(_dl_debug_file, -+ "\t%s move %d bytes from %x to %x\n", -+ symname, sym->st_size, -+ symbol_addr, reloc_addr); -+#endif -+ -+ _dl_memcpy((char *)reloc_addr, -+ (char *)symbol_addr, -+ sym->st_size); -+ } else -+ _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n"); -+ break; -+ default: -+ return -1; /* Calls _dl_exit(1). */ -+ } -+ -+#if defined (__SUPPORT_LD_DEBUG__) -+ if (_dl_debug_reloc && _dl_debug_detail) -+ _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n", -+ old_val, *reloc_addr, reloc_addr); -+#endif -+ -+ return 0; -+} -+ -+#undef __SPARC_LAZY_RELOC_WORKS -+#ifdef __SPARC_LAZY_RELOC_WORKS -+static int -+_dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, -+ ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) -+{ -+ int reloc_type; -+ int symtab_index; -+ ElfW(Addr) *reloc_addr; -+#if defined (__SUPPORT_LD_DEBUG__) -+ ElfW(Addr) old_val; -+#endif -+ -+ (void)scope; -+ symtab_index = ELF_R_SYM(rpnt->r_info); -+ (void)strtab; -+ -+ reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset); -+ reloc_type = ELF_R_TYPE(rpnt->r_info); -+ -+#if defined (__SUPPORT_LD_DEBUG__) -+ old_val = *reloc_addr; -+#endif -+ -+ switch (reloc_type) { -+ case R_SPARC_NONE: -+ break; -+ case R_SPARC_JMP_SLOT: -+ break; -+ default: -+ _dl_exit(1); -+ } -+ -+#if defined (__SUPPORT_LD_DEBUG__) -+ if (_dl_debug_reloc && _dl_debug_detail) -+ _dl_dprintf(_dl_debug_file, "\tpatched_lazy: %x ==> %x @ %x\n", -+ old_val, *reloc_addr, reloc_addr); -+#endif -+ -+ return 0; - } -+#endif - --void _dl_parse_lazy_relocation_information(struct dyn_elf *arg_rpnt, -- unsigned long rel_addr, unsigned long rel_size) --{ -- int i; -- char * strtab; -- int reloc_type; -- int symtab_index; -- Elf32_Sym * symtab; -- Elf32_Rela * rpnt; -- unsigned int * reloc_addr; -- struct elf_resolve * tpnt = arg_rpnt->dyn; -- -- /* Now parse the relocation information */ -- rpnt = (Elf32_Rela *)rel_addr; -- -- symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB]; -- strtab = ( char *)tpnt->dynamic_info[DT_STRTAB]; -- -- for(i=0; i< rel_size; i += sizeof(Elf32_Rela), rpnt++){ -- reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset); -- reloc_type = ELF32_R_TYPE(rpnt->r_info); -- symtab_index = ELF32_R_SYM(rpnt->r_info); -- -- switch(reloc_type){ -- case R_SPARC_NONE: -- break; -- case R_SPARC_JMP_SLOT: -- break; -- default: -- _dl_dprintf(2, "%s: (LAZY) can't handle reloc type ", _dl_progname); --#if defined (__SUPPORT_LD_DEBUG__) -- _dl_dprintf(2, "%s ", _dl_reltypes_tab[reloc_type]); --#endif -- if(symtab_index) _dl_dprintf(2, "'%s'\n", -- strtab + symtab[symtab_index].st_name); -- _dl_exit(33); -- }; -- }; --} -- --int _dl_parse_relocation_information(struct dyn_elf *arg_rpnt, -- unsigned long rel_addr, unsigned long rel_size) --{ -- int i; -- char * strtab; -- int reloc_type; -- int goof = 0; -- Elf32_Sym * symtab; -- Elf32_Rela * rpnt; -- unsigned int * reloc_addr; -- unsigned int symbol_addr; -- int symtab_index; -- struct elf_resolve * tpnt = arg_rpnt->dyn; -- /* Now parse the relocation information */ -- -- rpnt = (Elf32_Rela *)rel_addr; -- -- symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB]; -- strtab = ( char *)tpnt->dynamic_info[DT_STRTAB]; -- -- for(i=0; i< rel_size; i+= sizeof(Elf32_Rela), rpnt++){ -- reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset); -- reloc_type = ELF32_R_TYPE(rpnt->r_info); -- symtab_index = ELF32_R_SYM(rpnt->r_info); -- symbol_addr = 0; -- -- if(symtab_index) { -- -- symbol_addr = (unsigned int) -- _dl_find_hash(strtab + symtab[symtab_index].st_name, -- tpnt->symbol_scope, tpnt, elf_machine_type_class(reloc_type)); -- -- if(!symbol_addr && -- ELF32_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); -- }; -- }; -- switch(reloc_type){ -- case R_SPARC_NONE: -- break; -- case R_SPARC_32: -- *reloc_addr = symbol_addr + rpnt->r_addend; -- break; -- case R_SPARC_DISP32: -- *reloc_addr = symbol_addr + rpnt->r_addend - (unsigned int) reloc_addr; -- break; -- case R_SPARC_GLOB_DAT: -- *reloc_addr = symbol_addr + rpnt->r_addend; -- break; -- case R_SPARC_JMP_SLOT: -- reloc_addr[1] = 0x03000000 | ((symbol_addr >> 10) & 0x3fffff); -- reloc_addr[2] = 0x81c06000 | (symbol_addr & 0x3ff); -- break; -- case R_SPARC_RELATIVE: -- *reloc_addr += (unsigned int) tpnt->loadaddr + rpnt->r_addend; -- break; -- case R_SPARC_HI22: -- if (!symbol_addr) -- symbol_addr = tpnt->loadaddr + rpnt->r_addend; -- else -- symbol_addr += rpnt->r_addend; -- *reloc_addr = (*reloc_addr & 0xffc00000)|(symbol_addr >> 10); -- break; -- case R_SPARC_LO10: -- if (!symbol_addr) -- symbol_addr = tpnt->loadaddr + rpnt->r_addend; -- else -- symbol_addr += rpnt->r_addend; -- *reloc_addr = (*reloc_addr & ~0x3ff)|(symbol_addr & 0x3ff); -- break; -- case R_SPARC_WDISP30: -- *reloc_addr = (*reloc_addr & 0xc0000000)| -- ((symbol_addr - (unsigned int) reloc_addr) >> 2); -- break; -- case R_SPARC_COPY: -- _dl_memcpy((void *) reloc_addr, (void *) symbol_addr, symtab[symtab_index].st_size); -- break; -- default: -- _dl_dprintf(2, "%s: can't handle reloc type ", _dl_progname); --#if defined (__SUPPORT_LD_DEBUG__) -- _dl_dprintf(2, "%s ", _dl_reltypes_tab[reloc_type]); --#endif -- if (symtab_index) -- _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name); -- _dl_exit(34); -- }; -+void -+_dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, -+ unsigned long rel_addr, -+ unsigned long rel_size) -+{ -+#ifdef __SPARC_LAZY_RELOC_WORKS -+ (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc); -+#else -+ _dl_parse_relocation_information(rpnt, rel_addr, rel_size); -+#endif -+} - -- }; -- return goof; -+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); - } -diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-debug.h uClibc-0.9.28/ldso/ldso/x86_64/dl-debug.h ---- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-debug.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/x86_64/dl-debug.h 2006-04-28 00:14:35.000000000 -0600 -@@ -30,7 +30,10 @@ - */ - - static const char *_dl_reltypes_tab[] = { -- [0] "R_X86_64_NONE", "R_X86_64_64", "R_X86_64_PC32", "R_X86_64_GOT32", -- [4] "R_X86_64_PLT32", "R_X86_64_COPY", "R_X86_64_GLOB_DAT", "R_X86_64_JUMP_SLOT", -- [8] "R_X86_64_RELATIVE", "R_X86_64_GOTPCREL", "R_X86_64_32" -+ [ 0] "R_X86_64_NONE", "R_X86_64_64", "R_X86_64_PC32", "R_X86_64_GOT32", -+ [ 4] "R_X86_64_PLT32", "R_X86_64_COPY", "R_X86_64_GLOB_DAT", "R_X86_64_JUMP_SLOT", -+ [ 8] "R_X86_64_RELATIVE", "R_X86_64_GOTPCREL", "R_X86_64_32", "R_X86_64_32S", -+ [12] "R_X86_64_16", "R_X86_64_PC16", "R_X86_64_8", "R_X86_64_PC8", -+ [16] "R_X86_64_DTPMOD64", "R_X86_64_DTPOFF64", "R_X86_64_TPOFF64", "R_X86_64_TLSGD", -+ [20] "R_X86_64_TLSLD", "R_X86_64_DTPOFF32", "R_X86_64_GOTTPOFF", "R_X86_64_TPOFF32" - }; -diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-startup.h uClibc-0.9.28/ldso/ldso/x86_64/dl-startup.h ---- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-startup.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/x86_64/dl-startup.h 2006-04-28 00:14:35.000000000 -0600 -@@ -6,7 +6,7 @@ - * - * Parts taken from glibc/sysdeps/x86_64/dl-machine.h - */ --asm( -+__asm__ ( - " .text\n" - " .align 16\n" - " .global _start\n" -@@ -42,10 +42,10 @@ - - /* Handle relocation of the symbols in the dynamic loader. */ - static __always_inline --void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr, -- unsigned long symbol_addr, unsigned long load_addr, Elf64_Sym *sym) -+void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, ElfW(Addr) *reloc_addr, -+ ElfW(Addr) symbol_addr, ElfW(Addr) load_addr, ElfW(Sym) *sym) - { -- switch (ELF64_R_TYPE(rpnt->r_info)) { -+ switch (ELF_R_TYPE(rpnt->r_info)) { - case R_X86_64_GLOB_DAT: - case R_X86_64_JUMP_SLOT: - *reloc_addr = symbol_addr + rpnt->r_addend; -@@ -63,8 +63,3 @@ - _dl_exit(1); - } - } -- --/* Transfer control to the user's application, once the dynamic loader is -- * done. This routine has to exit the current function, then call the -- * _dl_elf_main function. */ --#define START() return _dl_elf_main -diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-syscalls.h uClibc-0.9.28/ldso/ldso/x86_64/dl-syscalls.h ---- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-syscalls.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/x86_64/dl-syscalls.h 2006-05-02 13:39:17.000000000 -0600 -@@ -1,7 +1,8 @@ - /* We can't use the real errno in ldso, since it has not yet - * been dynamicly linked in yet. */ -+#define __UCLIBC_MMAP_HAS_6_ARGS__ -+ -+#include "sys/syscall.h" - extern int _dl_errno; -+#undef __set_errno - #define __set_errno(X) {(_dl_errno) = (X);} --#include "sys/syscall.h" -- --#define MMAP_HAS_6_ARGS -diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-sysdep.h uClibc-0.9.28/ldso/ldso/x86_64/dl-sysdep.h ---- uClibc-0.9.28.orig/ldso/ldso/x86_64/dl-sysdep.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/x86_64/dl-sysdep.h 2006-04-28 00:14:35.000000000 -0600 -@@ -41,8 +41,6 @@ - struct elf_resolve; - extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - --#define do_rem(result, n, base) ((result) = (n) % (base)) -- - /* 4096 bytes alignment */ - #define PAGE_ALIGN 0xfffff000 - #define ADDR_ALIGN 0xfff -@@ -90,7 +88,7 @@ - and compare it with the current value that we can get via - an RIP relative addressing mode. */ - -- asm ("movq 1f(%%rip), %1\n" -+ __asm__ ("movq 1f(%%rip), %1\n" - "0:\tleaq _dl_start(%%rip), %0\n\t" - "subq %1, %0\n\t" - ".section\t.data\n" -diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/elfinterp.c uClibc-0.9.28/ldso/ldso/x86_64/elfinterp.c ---- uClibc-0.9.28.orig/ldso/ldso/x86_64/elfinterp.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/ldso/x86_64/elfinterp.c 2006-04-28 00:14:35.000000000 -0600 -@@ -165,6 +165,7 @@ - int reloc_type; - int symtab_index; - char *symname; -+ ElfW(Sym) *sym; - ElfW(Addr) *reloc_addr; - ElfW(Addr) symbol_addr; - #if defined (__SUPPORT_LD_DEBUG__) -@@ -174,8 +175,9 @@ - reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset); - reloc_type = ELF_R_TYPE(rpnt->r_info); - symtab_index = ELF_R_SYM(rpnt->r_info); -+ sym = &symtab[symtab_index]; - symbol_addr = 0; -- symname = strtab + symtab[symtab_index].st_name; -+ symname = strtab + sym->st_name; - - if (symtab_index) { - symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt, -@@ -185,7 +187,7 @@ - * might have been intentional. We should not be linking local - * symbols here, so all bases should be covered. - */ -- if (unlikely(!symbol_addr && ELF_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) { -+ if (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) { - _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); - _dl_exit(1); - }; -@@ -209,7 +211,7 @@ - - case R_X86_64_GLOB_DAT: - case R_X86_64_JUMP_SLOT: -- *reloc_addr = symbol_addr; -+ *reloc_addr = symbol_addr + rpnt->r_addend; - break; - - /* handled by elf_machine_relative() -@@ -217,33 +219,33 @@ - *reloc_addr = map->l_addr + rpnt->r_addend; - break; - */ --#if 0 - case R_X86_64_DTPMOD64: -+ *reloc_addr = 1; - break; - case R_X86_64_DTPOFF64: -- *reloc_addr = symbol_addr + rpnt->r_addend; -+ *reloc_addr = sym->st_value + rpnt->r_addend; - break; - case R_X86_64_TPOFF64: -- *reloc_addr = symbol_addr + rpnt->r_addend; -+ *reloc_addr = sym->st_value + rpnt->r_addend - symbol_addr; - break; - case R_X86_64_32: -- *reloc_addr = symbol_addr + rpnt->r_addend; -+ *(unsigned int *) reloc_addr = symbol_addr + rpnt->r_addend; -+ /* XXX: should check for overflow eh ? */ - break; - --#endif - case R_X86_64_COPY: - if (symbol_addr) { - #if defined (__SUPPORT_LD_DEBUG__) - if (_dl_debug_move) - _dl_dprintf(_dl_debug_file, - "\t%s move %d bytes from %x to %x\n", -- symname, symtab[symtab_index].st_size, -+ symname, sym->st_size, - symbol_addr, reloc_addr); - #endif - - _dl_memcpy((char *)reloc_addr, - (char *)symbol_addr, -- symtab[symtab_index].st_size); -+ sym->st_size); - } else - _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n"); - break; -@@ -261,7 +263,6 @@ - return 0; - } - --#if 0 - static int - _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope, - ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) -@@ -288,7 +289,7 @@ - case R_X86_64_NONE: - break; - case R_X86_64_JUMP_SLOT: -- *reloc_addr = tpnt->loadaddr + symtab[symtab_index].st_value; -+ *reloc_addr += (unsigned long)tpnt->loadaddr; - break; - default: - _dl_exit(1); -@@ -302,17 +303,13 @@ - - return 0; - } --#endif - - void - _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, - unsigned long rel_addr, - unsigned long rel_size) - { -- _dl_parse_relocation_information(rpnt, rel_addr, rel_size); --/* jump slot isnt working - (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc); --*/ - } - - int -diff -urN uClibc-0.9.28.orig/ldso/ldso/x86_64/resolve.S uClibc-0.9.28/ldso/ldso/x86_64/resolve.S ---- uClibc-0.9.28.orig/ldso/ldso/x86_64/resolve.S 1969-12-31 17:00:00.000000000 -0700 -+++ uClibc-0.9.28/ldso/ldso/x86_64/resolve.S 2006-04-28 00:14:35.000000000 -0600 -@@ -0,0 +1,63 @@ -+/* -+ * This function is _not_ called directly. It is jumped to (so no return -+ * address is on the stack) when attempting to use a symbol that has not yet -+ * been resolved. The first time a jump symbol (such as a function call inside -+ * a shared library) is used (before it gets resolved) it will jump here to -+ * _dl_linux_resolve. When we get called the stack looks like this: -+ * reloc_entry -+ * tpnt -+ * -+ * This function saves all the registers, puts a copy of reloc_entry and tpnt -+ * on the stack (as function arguments) then make the function call -+ * _dl_linux_resolver(tpnt, reloc_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 overwrite tpnt with this fixed up -+ * address. We then clean up after ourselves, put all the registers back how we -+ * found them, then we jump to where the fixed up address, which is where the -+ * jump symbol that got us here really wanted to jump to in the first place. -+ * found them, then we jump to the fixed up address, which is where the jump -+ * symbol that got us here really wanted to jump to in the first place. -+ * -Erik Andersen -+ */ -+ -+/* more info taken from glibc/sysdeps/x86_64/dl-trampoline.S */ -+ -+.text -+ -+.global _dl_linux_resolve -+.type _dl_linux_resolve,%function -+.align 16 -+ -+_dl_linux_resolve: -+ subq $56,%rsp -+ /* Preserve registers otherwise clobbered. */ -+ movq %rax, (%rsp) -+ movq %rcx, 8(%rsp) -+ movq %rdx, 16(%rsp) -+ movq %rsi, 24(%rsp) -+ movq %rdi, 32(%rsp) -+ movq %r8, 40(%rsp) -+ movq %r9, 48(%rsp) -+ -+ movq 64(%rsp), %rsi /* Copy args pushed by PLT in register. */ -+ movq %rsi, %r11 /* Multiply by 24 */ -+ addq %r11, %rsi -+ addq %r11, %rsi -+ shlq $3, %rsi -+ movq 56(%rsp), %rdi /* %rdi: link_map, %rsi: reloc_offset */ -+ call _dl_linux_resolver /* Call resolver. */ -+ movq %rax, %r11 /* Save return value */ -+ -+ /* Get register content back. */ -+ movq 48(%rsp), %r9 -+ movq 40(%rsp), %r8 -+ movq 32(%rsp), %rdi -+ movq 24(%rsp), %rsi -+ movq 16(%rsp), %rdx -+ movq 8(%rsp), %rcx -+ movq (%rsp), %rax -+ -+ addq $72, %rsp /* Adjust stack(PLT did 2 pushes) */ -+ jmp *%r11 /* Jump to function address. */ -+ -+.size _dl_linux_resolve,.-_dl_linux_resolve -diff -urN uClibc-0.9.28.orig/ldso/libdl/Makefile uClibc-0.9.28/ldso/libdl/Makefile ---- uClibc-0.9.28.orig/ldso/libdl/Makefile 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/libdl/Makefile 2006-04-28 00:14:35.000000000 -0600 -@@ -29,12 +29,14 @@ - endif - XXFLAGS+= $(XARCH_CFLAGS) $(CPU_CFLAGS) \ - -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \ -- -fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)ldso/include -I$(TOPDIR)ldso/ldso -I. -I$(TOPDIR)include -+ -fno-builtin -nostdinc -D_LIBC \ -+ -DLDSO_ELFINTERP=\"$(TARGET_ARCH)/elfinterp.c\" \ -+ -I$(TOPDIR)ldso/ldso/$(TARGET_ARCH) -I$(TOPDIR)ldso/include -I$(TOPDIR)ldso/ldso -I$(TOPDIR)include - - XXFLAGS+=-isystem $(shell $(CC) -print-file-name=include) - XXFLAGS_NOPIC:=$(XXFLAGS) - ifeq ($(DOPIC),y) -- XXFLAGS += $(PICFLAG) -D__LIBDL_SHARED__ -+ XXFLAGS += $(PICFLAG) -DSHARED - endif - ifeq ($(strip $(SUPPORT_LD_DEBUG)),y) - XXFLAGS+=-D__SUPPORT_LD_DEBUG__ -diff -urN uClibc-0.9.28.orig/ldso/libdl/libdl.c uClibc-0.9.28/ldso/libdl/libdl.c ---- uClibc-0.9.28.orig/ldso/libdl/libdl.c 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/ldso/libdl/libdl.c 2006-04-28 00:14:35.000000000 -0600 -@@ -3,7 +3,7 @@ - * Program to load an ELF binary on a linux system, and run it - * after resolving ELF shared library symbols - * -- * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org> -+ * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org> - * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, - * David Engel, Hongjiu Lu and Mitch D'Souza - * -@@ -30,12 +30,12 @@ - */ - - --#define _GNU_SOURCE -+#define _GNU_SOURCE - #include <ldso.h> - #include <stdio.h> - - --#if defined (__LIBDL_SHARED__) -+#ifdef SHARED - - /* When libdl is loaded as a shared library, we need to load in - * and use a pile of symbols from ldso... */ -@@ -52,6 +51,8 @@ - extern struct r_debug *_dl_debug_addr; - extern unsigned long _dl_error_number; - extern void *(*_dl_malloc_function)(size_t); -+extern void _dl_run_init_array(struct elf_resolve *); -+extern void _dl_run_fini_array(struct elf_resolve *); - #ifdef __LDSO_CACHE_SUPPORT__ - int _dl_map_cache(void); - int _dl_unmap_cache(void); -@@ -64,7 +65,7 @@ - #endif - - --#else /* __LIBDL_SHARED__ */ -+#else /* SHARED */ - - /* When libdl is linked as a static library, we need to replace all - * the symbols that otherwise would have been loaded in from ldso... */ -@@ -81,11 +82,11 @@ - struct r_debug *_dl_debug_addr = NULL; - #define _dl_malloc malloc - #include "../ldso/dl-debug.c" --#include "dl-progname.h" -+#include LDSO_ELFINTERP - #include "../ldso/dl-hash.c" - #define _dl_trace_loaded_objects 0 - #include "../ldso/dl-elf.c" --#endif /* __LIBDL_SHARED__ */ -+#endif /* SHARED */ - - #ifdef __SUPPORT_LD_DEBUG__ - # define _dl_if_debug_print(fmt, args...) \ -@@ -126,7 +127,8 @@ - "Unable to resolve symbol" - }; - --void __attribute__ ((destructor)) dl_cleanup(void) -+void dl_cleanup(void) __attribute__ ((destructor)); -+void dl_cleanup(void) - { - struct dyn_elf *d; - for (d = _dl_handles; d; d = d->next_handle) { -@@ -138,13 +140,12 @@ - { - struct elf_resolve *tpnt, *tfrom; - struct dyn_elf *dyn_chain, *rpnt = NULL, *dyn_ptr, *relro_ptr, *handle; -- struct dyn_elf *dpnt; - ElfW(Addr) from; - struct elf_resolve *tpnt1; - void (*dl_brk) (void); - int now_flag; - struct init_fini_list *tmp, *runp, *runp2, *dep_list; -- int nlist, i; -+ unsigned int nlist, i; - struct elf_resolve **init_fini_list; - - /* A bit of sanity checking... */ -@@ -169,12 +170,15 @@ - * the application. Thus this may go away at some time - * in the future. - */ -- tfrom = NULL; -- for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) { -- tpnt = dpnt->dyn; -- if (tpnt->loadaddr < from -- && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr)) -- tfrom = tpnt; -+ { -+ struct dyn_elf *dpnt; -+ tfrom = NULL; -+ for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) { -+ tpnt = dpnt->dyn; -+ if (tpnt->loadaddr < from -+ && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr)) -+ tfrom = tpnt; -+ } - } - for(rpnt = _dl_symbol_tables; rpnt && rpnt->next; rpnt=rpnt->next); - -@@ -233,11 +237,8 @@ - runp->tpnt->init_fini = NULL; /* clear any previous dependcies */ - for (dpnt = (ElfW(Dyn) *) runp->tpnt->dynamic_addr; dpnt->d_tag; dpnt++) { - if (dpnt->d_tag == DT_NEEDED) { -- char *name; -- - lpntstr = (char*) (runp->tpnt->dynamic_info[DT_STRTAB] + - dpnt->d_un.d_val); -- name = _dl_get_last_path_component(lpntstr); - _dl_if_debug_print("Trying to load '%s', needed by '%s'\n", - lpntstr, runp->tpnt->libname); - tpnt1 = _dl_load_shared_library(0, &rpnt, runp->tpnt, lpntstr, 0); -@@ -297,14 +298,14 @@ - } - /* Sort the INIT/FINI list in dependency order. */ - for (runp2 = dep_list; runp2; runp2 = runp2->next) { -- int j, k; -+ unsigned int j, k; - for (j = 0; init_fini_list[j] != runp2->tpnt; ++j) - /* Empty */; - for (k = j + 1; k < nlist; ++k) { -- struct init_fini_list *runp = init_fini_list[k]->init_fini; -+ struct init_fini_list *ele = init_fini_list[k]->init_fini; - -- for (; runp; runp = runp->next) { -- if (runp->tpnt == runp2->tpnt) { -+ for (; ele; ele = ele->next) { -+ if (ele->tpnt == runp2->tpnt) { - struct elf_resolve *here = init_fini_list[k]; - _dl_if_debug_print("Move %s from pos %d to %d in INIT/FINI list.\n", here->libname, k, j); - for (i = (k - j); i; --i) -@@ -367,7 +368,7 @@ - } - } - --#if defined (__LIBDL_SHARED__) -+#ifdef SHARED - /* Run the ctors and setup the dtors */ - for (i = nlist; i; --i) { - tpnt = init_fini_list[i-1]; -@@ -384,8 +385,11 @@ - (*dl_elf_func) (); - } - } -+ -+ _dl_run_init_array(tpnt); - } --#endif -+#endif /* SHARED */ -+ - _dl_unmap_cache(); - return (void *) dyn_chain; - -@@ -450,9 +454,16 @@ - return ret; - } - -+#if 0 -+void *dlvsym(void *vhandle, const char *name, const char *version) -+{ -+ return dlsym(vhandle, name); -+} -+#endif -+ - static int do_dlclose(void *vhandle, int need_fini) - { -- struct dyn_elf *rpnt, *rpnt1; -+ struct dyn_elf *rpnt, *rpnt1, *rpnt1_tmp; - struct init_fini_list *runp, *tmp; - ElfW(Phdr) *ppnt; - struct elf_resolve *tpnt, *run_tpnt; -@@ -460,7 +471,7 @@ - void (*dl_brk) (void); - struct dyn_elf *handle; - unsigned int end; -- int i = 0, j; -+ unsigned int i, j; - - handle = (struct dyn_elf *) vhandle; - if (handle == _dl_symbol_tables) -@@ -491,13 +502,21 @@ - for (j = 0; j < handle->init_fini.nlist; ++j) { - tpnt = handle->init_fini.init_fini[j]; - if (--tpnt->usage_count == 0) { -- if (tpnt->dynamic_info[DT_FINI] && need_fini && -+ if ((tpnt->dynamic_info[DT_FINI] -+ || tpnt->dynamic_info[DT_FINI_ARRAY]) -+ && need_fini && - !(tpnt->init_flag & FINI_FUNCS_CALLED)) { - tpnt->init_flag |= FINI_FUNCS_CALLED; -- dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]); -- _dl_if_debug_print("running dtors for library %s at '%p'\n", -- tpnt->libname, dl_elf_fini); -- (*dl_elf_fini) (); -+#ifdef SHARED -+ _dl_run_fini_array(tpnt); -+#endif -+ -+ if (tpnt->dynamic_info[DT_FINI]) { -+ dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]); -+ _dl_if_debug_print("running dtors for library %s at '%p'\n", -+ tpnt->libname, dl_elf_fini); -+ (*dl_elf_fini) (); -+ } - } - - _dl_if_debug_print("unmapping: %s\n", tpnt->libname); -@@ -541,8 +560,9 @@ - for (rpnt1 = _dl_symbol_tables; rpnt1->next; rpnt1 = rpnt1->next) { - if (rpnt1->next->dyn == tpnt) { - _dl_if_debug_print("removing symbol_tables: %s\n", tpnt->libname); -+ rpnt1_tmp = rpnt1->next->next; - free(rpnt1->next); -- rpnt1->next = rpnt1->next->next; -+ rpnt1->next = rpnt1_tmp; - if (rpnt1->next) - rpnt1->next->prev = rpnt1; - break; -@@ -588,8 +608,9 @@ - } - - /* -- * Dump information to stderrr about the current loaded modules -+ * Dump information to stderr about the current loaded modules - */ -+#if 1 - static char *type[] = { "Lib", "Exe", "Int", "Mod" }; - - int dlinfo(void) -@@ -660,16 +681,14 @@ - { - char *strtab; - ElfW(Sym) *symtab; -- int hn, si; -- int sf; -- int sn = 0; -+ unsigned int hn, si, sn, sf; - ElfW(Addr) sa; - - sa = 0; - symtab = (ElfW(Sym) *) (pelf->dynamic_info[DT_SYMTAB]); - strtab = (char *) (pelf->dynamic_info[DT_STRTAB]); - -- sf = 0; -+ sf = sn = 0; - for (hn = 0; hn < pelf->nbucket; hn++) { - for (si = pelf->elf_buckets[hn]; si; si = pelf->chains[si]) { - ElfW(Addr) symbol_addr; -@@ -696,3 +715,4 @@ - return 1; - } - } -+#endif -diff -urN uClibc-0.9.28.orig/libc/sysdeps/linux/i386/bits/syscalls.h uClibc-0.9.28/libc/sysdeps/linux/i386/bits/syscalls.h ---- uClibc-0.9.28.orig/libc/sysdeps/linux/i386/bits/syscalls.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/libc/sysdeps/linux/i386/bits/syscalls.h 2006-04-28 00:14:35.000000000 -0600 -@@ -4,17 +4,15 @@ - # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead." - #endif - -+#include <errno.h> -+ - /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel - * header files. It also defines the traditional `SYS_<name>' macros for older - * programs. */ - #include <bits/sysnum.h> - --#ifndef __set_errno --# define __set_errno(val) (*__errno_location ()) = (val) --#endif -- - /* -- Some of the sneaky macros in the code were taken from -+ Some of the sneaky macros in the code were taken from - glibc-2.2.5/sysdeps/unix/sysv/linux/i386/sysdep.h - */ - -@@ -22,7 +20,8 @@ - - /* We need some help from the assembler to generate optimal code. We - define some macros here which later will be used. */ --asm (".L__X'%ebx = 1\n\t" -+ -+__asm__ (".L__X'%ebx = 1\n\t" - ".L__X'%ecx = 2\n\t" - ".L__X'%edx = 2\n\t" - ".L__X'%eax = 3\n\t" -@@ -56,7 +55,6 @@ - ".endif\n\t" - ".endm\n\t"); - -- - #undef _syscall0 - #define _syscall0(type,name) \ - type name(void) \ -@@ -90,7 +88,7 @@ - type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ - { \ - return (type) (INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4)); \ --} -+} - - #undef _syscall5 - #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -@@ -100,10 +98,18 @@ - return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \ - } - -+#undef _syscall6 -+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5,type6,arg6) \ -+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6) \ -+{ \ -+return (type) (INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6)); \ -+} -+ - #define INLINE_SYSCALL(name, nr, args...) \ - ({ \ - unsigned int resultvar; \ -- asm volatile ( \ -+ __asm__ __volatile__ ( \ - LOADARGS_##nr \ - "movl %1, %%eax\n\t" \ - "int $0x80\n\t" \ -@@ -125,6 +131,7 @@ - #define LOADARGS_3 LOADARGS_1 - #define LOADARGS_4 LOADARGS_1 - #define LOADARGS_5 LOADARGS_1 -+#define LOADARGS_6 LOADARGS_1 "push %%ebp ; movl %7, %%ebp\n\t" - - #define RESTOREARGS_0 - #define RESTOREARGS_1 \ -@@ -133,6 +140,7 @@ - #define RESTOREARGS_3 RESTOREARGS_1 - #define RESTOREARGS_4 RESTOREARGS_1 - #define RESTOREARGS_5 RESTOREARGS_1 -+#define RESTOREARGS_6 "pop %%ebp\n\t" RESTOREARGS_1 - - #define ASMFMT_0() - #define ASMFMT_1(arg1) \ -@@ -145,7 +153,8 @@ - , "aD" (arg1), "c" (arg2), "d" (arg3), "S" (arg4) - #define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \ - , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5) -- -+#define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \ -+ , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6) - - #endif /* __ASSEMBLER__ */ - #endif /* _BITS_SYSCALLS_H */ -diff -urN uClibc-0.9.28.orig/libc/sysdeps/linux/powerpc/bits/syscalls.h uClibc-0.9.28/libc/sysdeps/linux/powerpc/bits/syscalls.h ---- uClibc-0.9.28.orig/libc/sysdeps/linux/powerpc/bits/syscalls.h 2006-05-02 10:47:27.000000000 -0600 -+++ uClibc-0.9.28/libc/sysdeps/linux/powerpc/bits/syscalls.h 2006-04-28 00:14:35.000000000 -0600 -@@ -5,67 +5,164 @@ - # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead." - #endif - -+#include <errno.h> -+ - /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel - * header files. It also defines the traditional `SYS_<name>' macros for older - * programs. */ - #include <bits/sysnum.h> - -- --#define __STRINGIFY(s) __STRINGIFY2 (s) --#define __STRINGIFY2(s) #s -- --#undef JUMPTARGET --#ifdef __PIC__ --#define __MAKE_SYSCALL __STRINGIFY(__uClibc_syscall@plt) -+/* Define a macro which expands inline into the wrapper code for a system -+ call. This use is for internal calls that do not need to handle errors -+ normally. It will never touch errno. -+ On powerpc a system call basically clobbers the same registers like a -+ function call, with the exception of LR (which is needed for the -+ "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal -+ an error return status). */ -+ -+# undef INLINE_SYSCALL -+#if 1 -+# define INLINE_SYSCALL(name, nr, args...) \ -+ ({ \ -+ INTERNAL_SYSCALL_DECL (sc_err); \ -+ long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \ -+ if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \ -+ { \ -+ __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \ -+ sc_ret = -1L; \ -+ } \ -+ sc_ret; \ -+ }) - #else --#define __MAKE_SYSCALL __STRINGIFY(__uClibc_syscall) -+# define INLINE_SYSCALL(name, nr, args...) \ -+ ({ \ -+ INTERNAL_SYSCALL_DECL (sc_err); \ -+ long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \ -+ if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \ -+ { \ -+ sc_ret = __syscall_error(INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));\ -+ } \ -+ sc_ret; \ -+ }) - #endif - --#define unified_syscall_body(name) \ -- __asm__ ( \ -- ".section \".text\"\n\t" \ -- ".align 2\n\t" \ -- ".globl " __STRINGIFY(name) "\n\t" \ -- ".type " __STRINGIFY(name) ",@function\n\t" \ -- #name":\tli 0," __STRINGIFY(__NR_##name) "\n\t" \ -- "b " __MAKE_SYSCALL "\n\t" \ -- ".size\t" __STRINGIFY(name) ",.""-" __STRINGIFY(name) "\n" \ -- ) -+/* Define a macro which expands inline into the wrapper code for a system -+ call. This use is for internal calls that do not need to handle errors -+ normally. It will never touch errno. -+ On powerpc a system call basically clobbers the same registers like a -+ function call, with the exception of LR (which is needed for the -+ "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal -+ an error return status). */ -+ -+# undef INTERNAL_SYSCALL_DECL -+# define INTERNAL_SYSCALL_DECL(err) long int err -+ -+# undef INTERNAL_SYSCALL -+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ -+ ({ \ -+ register long int r0 __asm__ ("r0"); \ -+ register long int r3 __asm__ ("r3"); \ -+ register long int r4 __asm__ ("r4"); \ -+ register long int r5 __asm__ ("r5"); \ -+ register long int r6 __asm__ ("r6"); \ -+ register long int r7 __asm__ ("r7"); \ -+ register long int r8 __asm__ ("r8"); \ -+ register long int r9 __asm__ ("r9"); \ -+ register long int r10 __asm__ ("r10"); \ -+ register long int r11 __asm__ ("r11"); \ -+ register long int r12 __asm__ ("r12"); \ -+ LOADARGS_##nr(name, args); \ -+ __asm__ __volatile__ \ -+ ("sc \n\t" \ -+ "mfcr %0" \ -+ : "=&r" (r0), \ -+ "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \ -+ "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \ -+ : ASM_INPUT_##nr \ -+ : "cr0", "ctr", "memory"); \ -+ err = r0; \ -+ (int) r3; \ -+ }) -+# define INTERNAL_SYSCALL(name, err, nr, args...) \ -+ INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args) -+ -+# undef INTERNAL_SYSCALL_ERROR_P -+# define INTERNAL_SYSCALL_ERROR_P(val, err) \ -+ ((void) (val), __builtin_expect ((err) & (1 << 28), 0)) -+ -+# undef INTERNAL_SYSCALL_ERRNO -+# define INTERNAL_SYSCALL_ERRNO(val, err) (val) -+ -+# define LOADARGS_0(name, dummy) \ -+ r0 = (long int)name -+# define LOADARGS_1(name, __arg1) \ -+ LOADARGS_0(name, 0); \ -+ r3 = (long int)__arg1 -+# define LOADARGS_2(name, __arg1, __arg2) \ -+ LOADARGS_1(name, __arg1); \ -+ r4 = (long int)__arg2 -+# define LOADARGS_3(name, __arg1, __arg2, __arg3) \ -+ LOADARGS_2(name, __arg1, __arg2); \ -+ r5 = (long int)__arg3 -+# define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \ -+ LOADARGS_3(name, __arg1, __arg2, __arg3); \ -+ r6 = (long int)__arg4 -+# define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \ -+ LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \ -+ r7 = (long int)__arg5 -+# define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \ -+ LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \ -+ r8 = (long int)__arg6 -+ -+# define ASM_INPUT_0 "0" (r0) -+# define ASM_INPUT_1 ASM_INPUT_0, "1" (r3) -+# define ASM_INPUT_2 ASM_INPUT_1, "2" (r4) -+# define ASM_INPUT_3 ASM_INPUT_2, "3" (r5) -+# define ASM_INPUT_4 ASM_INPUT_3, "4" (r6) -+# define ASM_INPUT_5 ASM_INPUT_4, "5" (r7) -+# define ASM_INPUT_6 ASM_INPUT_5, "6" (r8) - - #undef _syscall0 --#define _syscall0(type,name) \ --type name(void); \ --unified_syscall_body(name) -+#define _syscall0(type,name) \ -+type name(void){ \ -+ return (type) INLINE_SYSCALL(name, 0); \ -+} - - #undef _syscall1 - #define _syscall1(type,name,type1,arg1) \ --type name(type1 arg1); \ --unified_syscall_body(name) -+type name(type1 arg1){ \ -+ return (type) INLINE_SYSCALL(name, 1, arg1); \ -+} - - #undef _syscall2 - #define _syscall2(type,name,type1,arg1,type2,arg2) \ --type name(type1 arg1, type2 arg2); \ --unified_syscall_body(name) -+type name(type1 arg1, type2 arg2){ \ -+ return (type) INLINE_SYSCALL(name, 2, arg1, arg2); \ -+} - - #undef _syscall3 - #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ --type name(type1 arg1, type2 arg2, type3 arg3); \ --unified_syscall_body(name) -+type name(type1 arg1, type2 arg2, type3 arg3){ \ -+ return (type) INLINE_SYSCALL(name, 3, arg1, arg2, arg3); \ -+} - - #undef _syscall4 - #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ --type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4); \ --unified_syscall_body(name) -+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4){ \ -+ return (type) INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4); \ -+} - - #undef _syscall5 - #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ --type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5); \ --unified_syscall_body(name) -+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5){ \ -+ return (type) INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5); \ -+} - - #undef _syscall6 - #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ --type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6); \ --unified_syscall_body(name) -+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6){ \ -+ return (type) INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6); \ -+} - - #endif /* _BITS_SYSCALLS_H */ - diff --git a/toolchain/uClibc/uClibc-0.9.28-400-math-endianness.patch b/toolchain/uClibc/uClibc-0.9.28-400-math-endianness.patch deleted file mode 100644 index 015f79568..000000000 --- a/toolchain/uClibc/uClibc-0.9.28-400-math-endianness.patch +++ /dev/null @@ -1,247 +0,0 @@ -Index: uclibc/libm/fp_private.h -=================================================================== ---- uclibc/libm/fp_private.h (revision 12879) -+++ uclibc/libm/fp_private.h (working copy) -@@ -70,10 +70,11 @@ - *******************************************************************************/ - - #include <stdint.h> -+#include <endian.h> - - typedef struct /* Hex representation of a double. */ - { --#if defined(__BIG_ENDIAN__) -+#if (__BYTE_ORDER == __BIG_ENDIAN) - uint32_t high; - uint32_t low; - #else -Index: uclibc/libm/powerpc/s_ceil.c -=================================================================== ---- uclibc/libm/powerpc/s_ceil.c (revision 12879) -+++ uclibc/libm/powerpc/s_ceil.c (working copy) -@@ -21,13 +21,15 @@ - * * - *******************************************************************************/ - -+#include <endian.h> -+ - static const double twoTo52 = 4503599627370496.0; - static const unsigned long signMask = 0x80000000ul; - - typedef union - { - struct { --#if defined(__BIG_ENDIAN__) -+#if (__BYTE_ORDER == __BIG_ENDIAN) - unsigned long int hi; - unsigned long int lo; - #else -Index: uclibc/libm/powerpc/s_ldexp.c -=================================================================== ---- uclibc/libm/powerpc/s_ldexp.c (revision 12879) -+++ uclibc/libm/powerpc/s_ldexp.c (working copy) -@@ -21,11 +21,12 @@ - - #include <limits.h> - #include <math.h> -+#include <endian.h> - - typedef union - { - struct { --#if defined(__BIG_ENDIAN__) -+#if (__BYTE_ORDER == __BIG_ENDIAN) - unsigned long int hi; - unsigned long int lo; - #else -Index: uclibc/libm/powerpc/s_rint.c -=================================================================== ---- uclibc/libm/powerpc/s_rint.c (revision 12879) -+++ uclibc/libm/powerpc/s_rint.c (working copy) -@@ -46,13 +46,14 @@ - - #include <limits.h> - #include <math.h> -+#include <endian.h> - - #define SET_INVALID 0x01000000UL - - typedef union - { - struct { --#if defined(__BIG_ENDIAN__) -+#if (__BYTE_ORDER == __BIG_ENDIAN) - unsigned long int hi; - unsigned long int lo; - #else -Index: uclibc/libm/powerpc/s_floor.c -=================================================================== ---- uclibc/libm/powerpc/s_floor.c (revision 12879) -+++ uclibc/libm/powerpc/s_floor.c (working copy) -@@ -21,13 +21,15 @@ - * * - *******************************************************************************/ - -+#include <endian.h> -+ - static const double twoTo52 = 4503599627370496.0; - static const unsigned long signMask = 0x80000000ul; - - typedef union - { - struct { --#if defined(__BIG_ENDIAN__) -+#if (__BYTE_ORDER == __BIG_ENDIAN) - unsigned long int hi; - unsigned long int lo; - #else -Index: uclibc/libm/powerpc/s_logb.c -=================================================================== ---- uclibc/libm/powerpc/s_logb.c (revision 12879) -+++ uclibc/libm/powerpc/s_logb.c (working copy) -@@ -32,10 +32,12 @@ - * Standard 754. * - *******************************************************************************/ - -+#include <endian.h> -+ - typedef union - { - struct { --#if defined(__BIG_ENDIAN__) -+#if (__BYTE_ORDER == __BIG_ENDIAN) - unsigned long int hi; - unsigned long int lo; - #else -Index: uclibc/libm/powerpc/s_frexp.c -=================================================================== ---- uclibc/libm/powerpc/s_frexp.c (revision 12879) -+++ uclibc/libm/powerpc/s_frexp.c (working copy) -@@ -21,13 +21,14 @@ - - #include <limits.h> - #include <math.h> -+#include <endian.h> - - static const double two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ - - typedef union - { - struct { --#if defined(__BIG_ENDIAN__) -+#if (__BYTE_ORDER == __BIG_ENDIAN) - unsigned long int hi; - unsigned long int lo; - #else -Index: uclibc/libm/powerpc/s_modf.c -=================================================================== ---- uclibc/libm/powerpc/s_modf.c (revision 12879) -+++ uclibc/libm/powerpc/s_modf.c (working copy) -@@ -45,13 +45,14 @@ - - #include <limits.h> - #include <math.h> -+#include <endian.h> - - #define SET_INVALID 0x01000000UL - - typedef union - { - struct { --#if defined(__BIG_ENDIAN__) -+#if (__BYTE_ORDER == __BIG_ENDIAN) - unsigned long int hi; - unsigned long int lo; - #else -Index: uclibc/libm/powerpc/w_scalb.c -=================================================================== ---- uclibc/libm/powerpc/w_scalb.c (revision 12879) -+++ uclibc/libm/powerpc/w_scalb.c (working copy) -@@ -19,10 +19,12 @@ - ** - ***********************************************************************/ - -+#include <endian.h> -+ - typedef union - { - struct { --#if defined(__BIG_ENDIAN__) -+#if (__BYTE_ORDER == __BIG_ENDIAN) - unsigned long int hi; - unsigned long int lo; - #else -Index: uclibc/libc/string/sh64/strcpy.S -=================================================================== ---- uclibc/libc/string/sh64/strcpy.S (revision 12879) -+++ uclibc/libc/string/sh64/strcpy.S (working copy) -@@ -6,7 +6,9 @@ - ! - ! SH5 code Copyright 2002 SuperH Ltd. - --#ifdef __LITTLE_ENDIAN__ -+#include <endian.h> -+ -+#if __BYTE_ORDER == __LITTLE_ENDIAN - #define SHHI shlld - #define SHLO shlrd - #else -@@ -67,7 +69,7 @@ - add r5, r63, r4 - addi r0, 8, r0 - shortstring: --#ifndef __LITTLE_ENDIAN__ -+#if __BYTE_ORDER != __LITTLE_ENDIAN - pta/l shortstring2,tr1 - byterev r4,r4 - #endif -Index: uclibc/libc/string/sh64/memset.S -=================================================================== ---- uclibc/libc/string/sh64/memset.S (revision 12879) -+++ uclibc/libc/string/sh64/memset.S (working copy) -@@ -9,7 +9,9 @@ - ! Copyright 2002 SuperH Ltd. - ! - --#ifdef __LITTLE_ENDIAN__ -+#include <endian.h> -+ -+#if __BYTE_ORDER == __LITTLE_ENDIAN - #define SHHI shlld - #define SHLO shlrd - #else -Index: uclibc/libc/sysdeps/linux/sh/bits/kernel_stat.h -=================================================================== ---- uclibc/libc/sysdeps/linux/sh/bits/kernel_stat.h (revision 12879) -+++ uclibc/libc/sysdeps/linux/sh/bits/kernel_stat.h (working copy) -@@ -30,10 +30,10 @@ - }; - - struct kernel_stat64 { --#if defined(__BIG_ENDIAN__) -+#if (__BYTE_ORDER == __BIG_ENDIAN) - unsigned char __pad0b[6]; - unsigned short st_dev; --#elif defined(__LITTLE_ENDIAN__) -+#elif (__BYTE_ORDER == __LITTLE_ENDIAN) - unsigned short st_dev; - unsigned char __pad0b[6]; - #else -@@ -48,7 +48,7 @@ - unsigned long st_uid; - unsigned long st_gid; - --#if defined(__BIG_ENDIAN__) -+#if (__BYTE_ORDER == __BIG_ENDIAN) - unsigned char __pad3b[6]; - unsigned short st_rdev; - #else /* Must be little */ -@@ -60,7 +60,7 @@ - long long st_size; - unsigned long st_blksize; - --#if defined(__BIG_ENDIAN__) -+#if (__BYTE_ORDER == __BIG_ENDIAN) - unsigned long __pad4; /* Future possible st_blocks hi bits */ - unsigned long st_blocks; /* Number 512-byte blocks allocated. */ - #else /* Must be little */ diff --git a/toolchain/uClibc/uClibc-0.9.28-500-mutex-cancel.patch b/toolchain/uClibc/uClibc-0.9.28-500-mutex-cancel.patch deleted file mode 100644 index 5e56a7397..000000000 --- a/toolchain/uClibc/uClibc-0.9.28-500-mutex-cancel.patch +++ /dev/null @@ -1,8631 +0,0 @@ -diff --git a/include/printf.h b/include/printf.h -index 340b6cb..2dea58f 100644 ---- a/include/printf.h -+++ b/include/printf.h -@@ -75,6 +75,7 @@ struct printf_info - unsigned int is_short:1; /* h flag. */ - unsigned int is_long:1; /* l flag. */ - unsigned int is_long_double:1;/* L flag. */ -+ unsigned int __padding:20;/* non-gnu -- total of 32 bits on 32bit arch */ - - #elif __BYTE_ORDER == __BIG_ENDIAN - -diff --git a/include/pthread.h b/include/pthread.h -index 8c01172..cee112b 100644 ---- a/include/pthread.h -+++ b/include/pthread.h -@@ -644,7 +644,8 @@ extern void _pthread_cleanup_pop (struct - /* Install a cleanup handler as pthread_cleanup_push does, but also - saves the current cancellation type and set it to deferred cancellation. */ - --#ifdef __USE_GNU -+/* #ifdef __USE_GNU */ -+#if defined(__USE_GNU) || defined(_LIBC) - # define pthread_cleanup_push_defer_np(routine,arg) \ - { struct _pthread_cleanup_buffer _buffer; \ - _pthread_cleanup_push_defer (&_buffer, (routine), (arg)); -diff --git a/libc/inet/getnetent.c b/libc/inet/getnetent.c -index 181c5ad..659bf5d 100644 ---- a/libc/inet/getnetent.c -+++ b/libc/inet/getnetent.c -@@ -22,18 +22,9 @@ - #include <netdb.h> - #include <arpa/inet.h> - -+#include <bits/uClibc_mutex.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -- -- -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - #define MAXALIASES 35 - static const char NETDB[] = _PATH_NETWORKS; -@@ -46,25 +37,25 @@ int _net_stayopen; - - void setnetent(int f) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (netf == NULL) -- netf = fopen(NETDB, "r" ); -+ netf = fopen(NETDB, "r" ); - else -- rewind(netf); -+ rewind(netf); - _net_stayopen |= f; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return; - } - - void endnetent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (netf) { -- fclose(netf); -- netf = NULL; -+ fclose(netf); -+ netf = NULL; - } - _net_stayopen = 0; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - static char * any(register char *cp, char *match) -@@ -72,10 +63,10 @@ static char * any(register char *cp, cha - register char *mp, c; - - while ((c = *cp)) { -- for (mp = match; *mp; mp++) -- if (*mp == c) -- return (cp); -- cp++; -+ for (mp = match; *mp; mp++) -+ if (*mp == c) -+ return (cp); -+ cp++; - } - return ((char *)0); - } -@@ -84,59 +75,62 @@ struct netent * getnetent(void) - { - char *p; - register char *cp, **q; -+ struct netent *rv = NULL; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (netf == NULL && (netf = fopen(NETDB, "r" )) == NULL) { -- UNLOCK; -- return (NULL); -+ goto DONE; - } --again: -+ again: - - if (!line) { -- line = malloc(BUFSIZ + 1); -- if (!line) -- abort(); -+ line = malloc(BUFSIZ + 1); -+ if (!line) -+ abort(); - } - - p = fgets(line, BUFSIZ, netf); - if (p == NULL) { -- UNLOCK; -- return (NULL); -+ goto DONE; - } - if (*p == '#') -- goto again; -+ goto again; - cp = any(p, "#\n"); - if (cp == NULL) -- goto again; -+ goto again; - *cp = '\0'; - net.n_name = p; - cp = any(p, " \t"); - if (cp == NULL) -- goto again; -+ goto again; - *cp++ = '\0'; - while (*cp == ' ' || *cp == '\t') -- cp++; -+ cp++; - p = any(cp, " \t"); - if (p != NULL) -- *p++ = '\0'; -+ *p++ = '\0'; - net.n_net = inet_network(cp); - net.n_addrtype = AF_INET; - q = net.n_aliases = net_aliases; - if (p != NULL) -- cp = p; -+ cp = p; - while (cp && *cp) { -- if (*cp == ' ' || *cp == '\t') { -- cp++; -- continue; -- } -- if (q < &net_aliases[MAXALIASES - 1]) -- *q++ = cp; -- cp = any(cp, " \t"); -- if (cp != NULL) -- *cp++ = '\0'; -+ if (*cp == ' ' || *cp == '\t') { -+ cp++; -+ continue; -+ } -+ if (q < &net_aliases[MAXALIASES - 1]) -+ *q++ = cp; -+ cp = any(cp, " \t"); -+ if (cp != NULL) -+ *cp++ = '\0'; - } - *q = NULL; -- UNLOCK; -- return (&net); -+ -+ rv = &net; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); -+ return rv; - } - -diff --git a/libc/inet/getproto.c b/libc/inet/getproto.c -index c9f35f1..3665d89 100644 ---- a/libc/inet/getproto.c -+++ b/libc/inet/getproto.c -@@ -62,17 +62,9 @@ - #include <string.h> - #include <errno.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -- -+#include <bits/uClibc_mutex.h> - -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - #define MAXALIASES 35 - #define SBUFSIZE (BUFSIZ + 1 + (sizeof(char *) * MAXALIASES)) -@@ -85,109 +77,114 @@ static int proto_stayopen; - static void __initbuf(void) - { - if (!static_aliases) { -- static_aliases = malloc(SBUFSIZE); -- if (!static_aliases) -- abort(); -+ static_aliases = malloc(SBUFSIZE); -+ if (!static_aliases) -+ abort(); - } - } - - void setprotoent(int f) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (protof == NULL) -- protof = fopen(_PATH_PROTOCOLS, "r" ); -+ protof = fopen(_PATH_PROTOCOLS, "r" ); - else -- rewind(protof); -+ rewind(protof); - proto_stayopen |= f; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - void endprotoent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (protof) { -- fclose(protof); -- protof = NULL; -+ fclose(protof); -+ protof = NULL; - } - proto_stayopen = 0; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - int getprotoent_r(struct protoent *result_buf, -- char *buf, size_t buflen, -- struct protoent **result) -+ char *buf, size_t buflen, -+ struct protoent **result) - { - char *p; - register char *cp, **q; - char **proto_aliases; - char *line; -+ int rv; - - *result = NULL; - - if (buflen < sizeof(*proto_aliases)*MAXALIASES) { -- errno=ERANGE; -- return errno; -+ errno=ERANGE; -+ return errno; - } -- LOCK; -+ -+ __UCLIBC_MUTEX_LOCK(mylock); - proto_aliases=(char **)buf; - buf+=sizeof(*proto_aliases)*MAXALIASES; - buflen-=sizeof(*proto_aliases)*MAXALIASES; - - if (buflen < BUFSIZ+1) { -- UNLOCK; -- errno=ERANGE; -- return errno; -+ errno=rv=ERANGE; -+ goto DONE; - } - line=buf; - buf+=BUFSIZ+1; - buflen-=BUFSIZ+1; - - if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL) { -- UNLOCK; -- return errno; -+ rv=errno; -+ goto DONE; - } --again: -+ again: - if ((p = fgets(line, BUFSIZ, protof)) == NULL) { -- UNLOCK; -- return TRY_AGAIN; -+ rv=TRY_AGAIN; -+ goto DONE; - } - - if (*p == '#') -- goto again; -+ goto again; - cp = strpbrk(p, "#\n"); - if (cp == NULL) -- goto again; -+ goto again; - *cp = '\0'; - result_buf->p_name = p; - cp = strpbrk(p, " \t"); - if (cp == NULL) -- goto again; -+ goto again; - *cp++ = '\0'; - while (*cp == ' ' || *cp == '\t') -- cp++; -+ cp++; - p = strpbrk(cp, " \t"); - if (p != NULL) -- *p++ = '\0'; -+ *p++ = '\0'; - result_buf->p_proto = atoi(cp); - q = result_buf->p_aliases = proto_aliases; - if (p != NULL) { -- cp = p; -- while (cp && *cp) { -- if (*cp == ' ' || *cp == '\t') { -- cp++; -- continue; -- } -- if (q < &proto_aliases[MAXALIASES - 1]) -- *q++ = cp; -- cp = strpbrk(cp, " \t"); -- if (cp != NULL) -- *cp++ = '\0'; -- } -+ cp = p; -+ while (cp && *cp) { -+ if (*cp == ' ' || *cp == '\t') { -+ cp++; -+ continue; -+ } -+ if (q < &proto_aliases[MAXALIASES - 1]) -+ *q++ = cp; -+ cp = strpbrk(cp, " \t"); -+ if (cp != NULL) -+ *cp++ = '\0'; -+ } - } - *q = NULL; - *result=result_buf; -- UNLOCK; -- return 0; -+ -+ rv = 0; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); -+ return rv; - } - - struct protoent * getprotoent(void) -@@ -201,26 +198,26 @@ struct protoent * getprotoent(void) - - - int getprotobyname_r(const char *name, -- struct protoent *result_buf, -- char *buf, size_t buflen, -- struct protoent **result) -+ struct protoent *result_buf, -+ char *buf, size_t buflen, -+ struct protoent **result) - { - register char **cp; - int ret; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - setprotoent(proto_stayopen); - while (!(ret=getprotoent_r(result_buf, buf, buflen, result))) { -- if (strcmp(result_buf->p_name, name) == 0) -- break; -- for (cp = result_buf->p_aliases; *cp != 0; cp++) -- if (strcmp(*cp, name) == 0) -- goto found; -+ if (strcmp(result_buf->p_name, name) == 0) -+ break; -+ for (cp = result_buf->p_aliases; *cp != 0; cp++) -+ if (strcmp(*cp, name) == 0) -+ goto found; - } --found: -+ found: - if (!proto_stayopen) -- endprotoent(); -- UNLOCK; -+ endprotoent(); -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return *result?0:ret; - } - -@@ -236,20 +233,20 @@ struct protoent * getprotobyname(const c - - - int getprotobynumber_r (int proto_num, -- struct protoent *result_buf, -- char *buf, size_t buflen, -- struct protoent **result) -+ struct protoent *result_buf, -+ char *buf, size_t buflen, -+ struct protoent **result) - { - int ret; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - setprotoent(proto_stayopen); - while (!(ret=getprotoent_r(result_buf, buf, buflen, result))) -- if (result_buf->p_proto == proto_num) -- break; -+ if (result_buf->p_proto == proto_num) -+ break; - if (!proto_stayopen) -- endprotoent(); -- UNLOCK; -+ endprotoent(); -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return *result?0:ret; - } - -diff --git a/libc/inet/getservice.c b/libc/inet/getservice.c -index cbe5c50..b666057 100644 ---- a/libc/inet/getservice.c -+++ b/libc/inet/getservice.c -@@ -65,20 +65,9 @@ - #include <arpa/inet.h> - #include <errno.h> - -+#include <bits/uClibc_mutex.h> - -- --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -- -- -- -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - #define MAXALIASES 35 - #define SBUFSIZE (BUFSIZ + 1 + (sizeof(char *) * MAXALIASES)) -@@ -91,32 +80,32 @@ static int serv_stayopen; - static void __initbuf(void) - { - if (!servbuf) { -- servbuf = malloc(SBUFSIZE); -- if (!servbuf) -- abort(); -+ servbuf = malloc(SBUFSIZE); -+ if (!servbuf) -+ abort(); - } - } - - void setservent(int f) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (servf == NULL) -- servf = fopen(_PATH_SERVICES, "r" ); -+ servf = fopen(_PATH_SERVICES, "r" ); - else -- rewind(servf); -+ rewind(servf); - serv_stayopen |= f; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - void endservent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (servf) { -- fclose(servf); -- servf = NULL; -+ fclose(servf); -+ servf = NULL; - } - serv_stayopen = 0; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - struct servent * getservent(void) -@@ -149,127 +138,129 @@ struct servent * getservbyport(int port, - } - - int getservent_r(struct servent * result_buf, -- char * buf, size_t buflen, -- struct servent ** result) -+ char * buf, size_t buflen, -+ struct servent ** result) - { - char *p; - register char *cp, **q; - char **serv_aliases; - char *line; -+ int rv; - - *result=NULL; - - if (buflen < sizeof(*serv_aliases)*MAXALIASES) { -- errno=ERANGE; -- return errno; -+ errno=ERANGE; -+ return errno; - } -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - serv_aliases=(char **)buf; - buf+=sizeof(*serv_aliases)*MAXALIASES; - buflen-=sizeof(*serv_aliases)*MAXALIASES; - - if (buflen < BUFSIZ+1) { -- UNLOCK; -- errno=ERANGE; -- return errno; -+ errno=rv=ERANGE; -+ goto DONE; - } - line=buf; - buf+=BUFSIZ+1; - buflen-=BUFSIZ+1; - - if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) { -- UNLOCK; -- errno=EIO; -- return errno; -+ errno=rv=EIO; -+ goto DONE; - } --again: -+ again: - if ((p = fgets(line, BUFSIZ, servf)) == NULL) { -- UNLOCK; -- errno=EIO; -- return errno; -+ errno=rv=EIO; -+ goto DONE; - } - if (*p == '#') -- goto again; -+ goto again; - cp = strpbrk(p, "#\n"); - if (cp == NULL) -- goto again; -+ goto again; - *cp = '\0'; - result_buf->s_name = p; - p = strpbrk(p, " \t"); - if (p == NULL) -- goto again; -+ goto again; - *p++ = '\0'; - while (*p == ' ' || *p == '\t') -- p++; -+ p++; - cp = strpbrk(p, ",/"); - if (cp == NULL) -- goto again; -+ goto again; - *cp++ = '\0'; - result_buf->s_port = htons((u_short)atoi(p)); - result_buf->s_proto = cp; - q = result_buf->s_aliases = serv_aliases; - cp = strpbrk(cp, " \t"); - if (cp != NULL) -- *cp++ = '\0'; -+ *cp++ = '\0'; - while (cp && *cp) { -- if (*cp == ' ' || *cp == '\t') { -- cp++; -- continue; -- } -- if (q < &serv_aliases[MAXALIASES - 1]) -- *q++ = cp; -- cp = strpbrk(cp, " \t"); -- if (cp != NULL) -- *cp++ = '\0'; -+ if (*cp == ' ' || *cp == '\t') { -+ cp++; -+ continue; -+ } -+ if (q < &serv_aliases[MAXALIASES - 1]) -+ *q++ = cp; -+ cp = strpbrk(cp, " \t"); -+ if (cp != NULL) -+ *cp++ = '\0'; - } - *q = NULL; - *result=result_buf; -- UNLOCK; -- return 0; -+ -+ rv = 0; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); -+ return rv; - } - - int getservbyname_r(const char *name, const char *proto, -- struct servent * result_buf, char * buf, size_t buflen, -- struct servent ** result) -+ struct servent * result_buf, char * buf, size_t buflen, -+ struct servent ** result) - { - register char **cp; - int ret; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - setservent(serv_stayopen); - while (!(ret=getservent_r(result_buf, buf, buflen, result))) { -- if (strcmp(name, result_buf->s_name) == 0) -- goto gotname; -- for (cp = result_buf->s_aliases; *cp; cp++) -- if (strcmp(name, *cp) == 0) -- goto gotname; -- continue; --gotname: -- if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0) -- break; -+ if (strcmp(name, result_buf->s_name) == 0) -+ goto gotname; -+ for (cp = result_buf->s_aliases; *cp; cp++) -+ if (strcmp(name, *cp) == 0) -+ goto gotname; -+ continue; -+ gotname: -+ if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0) -+ break; - } - if (!serv_stayopen) -- endservent(); -- UNLOCK; -+ endservent(); -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return *result?0:ret; - } - - int getservbyport_r(int port, const char *proto, -- struct servent * result_buf, char * buf, -- size_t buflen, struct servent ** result) -+ struct servent * result_buf, char * buf, -+ size_t buflen, struct servent ** result) - { - int ret; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - setservent(serv_stayopen); - while (!(ret=getservent_r(result_buf, buf, buflen, result))) { -- if (result_buf->s_port != port) -- continue; -- if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0) -- break; -+ if (result_buf->s_port != port) -+ continue; -+ if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0) -+ break; - } - if (!serv_stayopen) -- endservent(); -- UNLOCK; -+ endservent(); -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return *result?0:ret; - } -diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c -index 27b60ef..0f583ab 100644 ---- a/libc/inet/resolv.c -+++ b/libc/inet/resolv.c -@@ -7,7 +7,7 @@ - * 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. --*/ -+ */ - - /* - * Portions Copyright (c) 1985, 1993 -@@ -153,6 +153,11 @@ - #include <sys/utsname.h> - #include <sys/un.h> - -+#include <bits/uClibc_mutex.h> -+ -+__UCLIBC_MUTEX_EXTERN(__resolv_lock); -+ -+ - #define MAX_RECURSE 5 - #define REPLY_TIMEOUT 10 - #define MAX_RETRIES 3 -@@ -180,18 +185,6 @@ extern char * __nameserver[MAX_SERVERS]; - extern int __searchdomains; - extern char * __searchdomain[MAX_SEARCH]; - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --extern pthread_mutex_t __resolv_lock; --# define BIGLOCK __pthread_mutex_lock(&__resolv_lock) --# define BIGUNLOCK __pthread_mutex_unlock(&__resolv_lock); --#else --# define BIGLOCK --# define BIGUNLOCK --#endif -- -- -- - /* Structs */ - struct resolv_header { - int id; -@@ -229,49 +222,49 @@ enum etc_hosts_action { - - /* function prototypes */ - extern int __get_hosts_byname_r(const char * name, int type, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop); -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop); - extern int __get_hosts_byaddr_r(const char * addr, int len, int type, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop); -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop); - extern void __open_etc_hosts(FILE **fp); - extern int __read_etc_hosts_r(FILE *fp, const char * name, int type, -- enum etc_hosts_action action, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop); -+ enum etc_hosts_action action, -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop); - extern int __dns_lookup(const char * name, int type, int nscount, -- char ** nsip, unsigned char ** outpacket, struct resolv_answer * a); -+ char ** nsip, unsigned char ** outpacket, struct resolv_answer * a); - - extern int __encode_dotted(const char * dotted, unsigned char * dest, int maxlen); - extern int __decode_dotted(const unsigned char * message, int offset, -- char * dest, int maxlen); -+ char * dest, int maxlen); - extern int __length_dotted(const unsigned char * message, int offset); - extern int __encode_header(struct resolv_header * h, unsigned char * dest, int maxlen); - extern int __decode_header(unsigned char * data, struct resolv_header * h); - extern int __encode_question(struct resolv_question * q, -- unsigned char * dest, int maxlen); -+ unsigned char * dest, int maxlen); - extern int __decode_question(unsigned char * message, int offset, -- struct resolv_question * q); -+ struct resolv_question * q); - extern int __encode_answer(struct resolv_answer * a, -- unsigned char * dest, int maxlen); -+ unsigned char * dest, int maxlen); - extern int __decode_answer(unsigned char * message, int offset, -- struct resolv_answer * a); -+ struct resolv_answer * a); - extern int __length_question(unsigned char * message, int offset); - extern int __open_nameservers(void); - extern void __close_nameservers(void); - extern int __dn_expand(const u_char *, const u_char *, const u_char *, -- char *, int); -+ char *, int); - extern int __ns_name_uncompress(const u_char *, const u_char *, -- const u_char *, char *, size_t); -+ const u_char *, char *, size_t); - extern int __ns_name_ntop(const u_char *, char *, size_t); - extern int __ns_name_unpack(const u_char *, const u_char *, const u_char *, -- u_char *, size_t); -+ u_char *, size_t); - - - #ifdef L_encodeh -@@ -361,7 +354,7 @@ int __encode_dotted(const char *dotted, - This routine understands compressed data. */ - - int __decode_dotted(const unsigned char *data, int offset, -- char *dest, int maxlen) -+ char *dest, int maxlen) - { - int l; - int measure = 1; -@@ -435,7 +428,7 @@ int __length_dotted(const unsigned char - - #ifdef L_encodeq - int __encode_question(struct resolv_question *q, -- unsigned char *dest, int maxlen) -+ unsigned char *dest, int maxlen) - { - int i; - -@@ -460,7 +453,7 @@ int __encode_question(struct resolv_ques - - #ifdef L_decodeq - int __decode_question(unsigned char *message, int offset, -- struct resolv_question *q) -+ struct resolv_question *q) - { - char temp[256]; - int i; -@@ -525,7 +518,7 @@ int __encode_answer(struct resolv_answer - - #ifdef L_decodea - int __decode_answer(unsigned char *message, int offset, -- struct resolv_answer *a) -+ struct resolv_answer *a) - { - char temp[256]; - int i; -@@ -557,11 +550,11 @@ int __decode_answer(unsigned char *messa - - #ifdef L_encodep - int __encode_packet(struct resolv_header *h, -- struct resolv_question **q, -- struct resolv_answer **an, -- struct resolv_answer **ns, -- struct resolv_answer **ar, -- unsigned char *dest, int maxlen) -+ struct resolv_question **q, -+ struct resolv_answer **an, -+ struct resolv_answer **ns, -+ struct resolv_answer **ar, -+ unsigned char *dest, int maxlen) - { - int i, total = 0; - int j; -@@ -621,7 +614,7 @@ int __decode_packet(unsigned char *data, - - #ifdef L_formquery - int __form_query(int id, const char *name, int type, unsigned char *packet, -- int maxlen) -+ int maxlen) - { - struct resolv_header h; - struct resolv_question q; -@@ -649,14 +642,7 @@ int __form_query(int id, const char *nam - - #ifdef L_dnslookup - --#ifdef __UCLIBC_HAS_THREADS__ --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - /* Just for the record, having to lock __dns_lookup() just for these two globals - * is pretty lame. I think these two variables can probably be de-global-ized, -@@ -665,7 +651,7 @@ static pthread_mutex_t mylock = PTHREAD_ - static int ns=0, id=1; - - int __dns_lookup(const char *name, int type, int nscount, char **nsip, -- unsigned char **outpacket, struct resolv_answer *a) -+ unsigned char **outpacket, struct resolv_answer *a) - { - int i, j, len, fd, pos, rc; - struct timeval tv; -@@ -693,10 +679,10 @@ int __dns_lookup(const char *name, int t - DPRINTF("Looking up type %d answer for '%s'\n", type, name); - - /* Mess with globals while under lock */ -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - local_ns = ns % nscount; - local_id = id; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - while (retries < MAX_RETRIES) { - if (fd != -1) -@@ -722,13 +708,13 @@ int __dns_lookup(const char *name, int t - - strncpy(lookup,name,MAXDNAME); - if (variant >= 0) { -- BIGLOCK; -- if (variant < __searchdomains) { -- strncat(lookup,".", MAXDNAME); -- strncat(lookup,__searchdomain[variant], MAXDNAME); -- } -- BIGUNLOCK; -- } -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); -+ if (variant < __searchdomains) { -+ strncat(lookup,".", MAXDNAME); -+ strncat(lookup,__searchdomain[variant], MAXDNAME); -+ } -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); -+ } - DPRINTF("lookup name: %s\n", lookup); - q.dotted = (char *)lookup; - q.qtype = type; -@@ -750,7 +736,7 @@ int __dns_lookup(const char *name, int t - fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - #endif - if (fd < 0) { -- retries++; -+ retries++; - continue; - } - -@@ -772,11 +758,11 @@ int __dns_lookup(const char *name, int t - #endif - if (rc < 0) { - if (errno == ENETUNREACH) { -- /* routing error, presume not transient */ -- goto tryall; -+ /* routing error, presume not transient */ -+ goto tryall; - } else -- /* retry */ -- retries++; -+ /* retry */ -+ retries++; - continue; - } - -@@ -838,55 +824,55 @@ int __dns_lookup(const char *name, int t - - first_answer = 1; - for (j=0;j<h.ancount;j++,pos += i) -- { -- i = __decode_answer(packet, pos, &ma); -+ { -+ i = __decode_answer(packet, pos, &ma); - -- if (i<0) { -- DPRINTF("failed decode %d\n", i); -- goto again; -- } -+ if (i<0) { -+ DPRINTF("failed decode %d\n", i); -+ goto again; -+ } - -- if ( first_answer ) -- { -- ma.buf = a->buf; -- ma.buflen = a->buflen; -- ma.add_count = a->add_count; -- memcpy(a, &ma, sizeof(ma)); -- if (a->atype != T_SIG && (0 == a->buf || (type != T_A && type != T_AAAA))) -- { -- break; -- } -- if (a->atype != type) -- { -- free(a->dotted); -- continue; -- } -- a->add_count = h.ancount - j - 1; -- if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen) -- { -- break; -- } -- a->add_count = 0; -- first_answer = 0; -- } -- else -- { -- free(ma.dotted); -- if (ma.atype != type) -- { -- continue; -- } -- if (a->rdlength != ma.rdlength) -- { -- free(a->dotted); -- DPRINTF("Answer address len(%u) differs from original(%u)\n", -- ma.rdlength, a->rdlength); -- goto again; -+ if ( first_answer ) -+ { -+ ma.buf = a->buf; -+ ma.buflen = a->buflen; -+ ma.add_count = a->add_count; -+ memcpy(a, &ma, sizeof(ma)); -+ if (a->atype != T_SIG && (0 == a->buf || (type != T_A && type != T_AAAA))) -+ { -+ break; -+ } -+ if (a->atype != type) -+ { -+ free(a->dotted); -+ continue; -+ } -+ a->add_count = h.ancount - j - 1; -+ if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen) -+ { -+ break; -+ } -+ a->add_count = 0; -+ first_answer = 0; -+ } -+ else -+ { -+ free(ma.dotted); -+ if (ma.atype != type) -+ { -+ continue; -+ } -+ if (a->rdlength != ma.rdlength) -+ { -+ free(a->dotted); -+ DPRINTF("Answer address len(%u) differs from original(%u)\n", -+ ma.rdlength, a->rdlength); -+ goto again; -+ } -+ memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, ma.rdlength); -+ ++a->add_count; -+ } - } -- memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, ma.rdlength); -- ++a->add_count; -- } -- } - - DPRINTF("Answer name = |%s|\n", a->dotted); - DPRINTF("Answer type = |%d|\n", a->atype); -@@ -900,48 +886,48 @@ int __dns_lookup(const char *name, int t - free(lookup); - - /* Mess with globals while under lock */ -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - ns = local_ns; - id = local_id; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - return (len); /* success! */ - -- tryall: -+ tryall: - /* if there are other nameservers, give them a go, - otherwise return with error */ - { - variant = -1; -- local_ns = (local_ns + 1) % nscount; -- if (local_ns == 0) -- retries++; -+ local_ns = (local_ns + 1) % nscount; -+ if (local_ns == 0) -+ retries++; - -- continue; -+ continue; - } - -- again: -+ again: - /* if there are searchdomains, try them or fallback as passed */ - { - int sdomains; -- BIGLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); - sdomains=__searchdomains; -- BIGUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - - if (variant < sdomains - 1) { -- /* next search */ -- variant++; -+ /* next search */ -+ variant++; - } else { -- /* next server, first search */ -- local_ns = (local_ns + 1) % nscount; -- if (local_ns == 0) -- retries++; -+ /* next server, first search */ -+ local_ns = (local_ns + 1) % nscount; -+ if (local_ns == 0) -+ retries++; - -- variant = -1; -+ variant = -1; - } - } - } - --fail: -+ fail: - if (fd != -1) - close(fd); - if (lookup) -@@ -951,10 +937,10 @@ fail: - h_errno = NETDB_INTERNAL; - /* Mess with globals while under lock */ - if (local_ns != -1) { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - ns = local_ns; - id = local_id; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - return -1; - } -@@ -966,9 +952,8 @@ int __nameservers; - char * __nameserver[MAX_SERVERS]; - int __searchdomains; - char * __searchdomain[MAX_SEARCH]; --#ifdef __UCLIBC_HAS_THREADS__ --pthread_mutex_t __resolv_lock = PTHREAD_MUTEX_INITIALIZER; --#endif -+ -+__UCLIBC_MUTEX_INIT(__resolv_lock, PTHREAD_MUTEX_INITIALIZER); - - /* - * we currently read formats not quite the same as that on normal -@@ -982,60 +967,63 @@ int __open_nameservers() - #define RESOLV_ARGS 5 - char szBuffer[128], *p, *argv[RESOLV_ARGS]; - int argc; -+ int rv = 0; - -- BIGLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); - if (__nameservers > 0) { -- BIGUNLOCK; -- return 0; -+ goto DONE; - } - - if ((fp = fopen("/etc/resolv.conf", "r")) || -- (fp = fopen("/etc/config/resolv.conf", "r"))) -- { -- -- while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) { -+ (fp = fopen("/etc/config/resolv.conf", "r"))) -+ { - -- for (p = szBuffer; *p && isspace(*p); p++) -- /* skip white space */; -- if (*p == '\0' || *p == '\n' || *p == '#') /* skip comments etc */ -- continue; -- argc = 0; -- while (*p && argc < RESOLV_ARGS) { -- argv[argc++] = p; -- while (*p && !isspace(*p) && *p != '\n') -- p++; -- while (*p && (isspace(*p) || *p == '\n')) /* remove spaces */ -- *p++ = '\0'; -- } -+ while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) { - -- if (strcmp(argv[0], "nameserver") == 0) { -- for (i = 1; i < argc && __nameservers < MAX_SERVERS; i++) { -- __nameserver[__nameservers++] = strdup(argv[i]); -- DPRINTF("adding nameserver %s\n", argv[i]); -+ for (p = szBuffer; *p && isspace(*p); p++) -+ /* skip white space */; -+ if (*p == '\0' || *p == '\n' || *p == '#') /* skip comments etc */ -+ continue; -+ argc = 0; -+ while (*p && argc < RESOLV_ARGS) { -+ argv[argc++] = p; -+ while (*p && !isspace(*p) && *p != '\n') -+ p++; -+ while (*p && (isspace(*p) || *p == '\n')) /* remove spaces */ -+ *p++ = '\0'; - } -- } - -- /* domain and search are mutually exclusive, the last one wins */ -- if (strcmp(argv[0],"domain")==0 || strcmp(argv[0],"search")==0) { -- while (__searchdomains > 0) { -- free(__searchdomain[--__searchdomains]); -- __searchdomain[__searchdomains] = NULL; -+ if (strcmp(argv[0], "nameserver") == 0) { -+ for (i = 1; i < argc && __nameservers < MAX_SERVERS; i++) { -+ __nameserver[__nameservers++] = strdup(argv[i]); -+ DPRINTF("adding nameserver %s\n", argv[i]); -+ } - } -- for (i=1; i < argc && __searchdomains < MAX_SEARCH; i++) { -- __searchdomain[__searchdomains++] = strdup(argv[i]); -- DPRINTF("adding search %s\n", argv[i]); -+ -+ /* domain and search are mutually exclusive, the last one wins */ -+ if (strcmp(argv[0],"domain")==0 || strcmp(argv[0],"search")==0) { -+ while (__searchdomains > 0) { -+ free(__searchdomain[--__searchdomains]); -+ __searchdomain[__searchdomains] = NULL; -+ } -+ for (i=1; i < argc && __searchdomains < MAX_SEARCH; i++) { -+ __searchdomain[__searchdomains++] = strdup(argv[i]); -+ DPRINTF("adding search %s\n", argv[i]); -+ } - } - } -+ fclose(fp); -+ DPRINTF("nameservers = %d\n", __nameservers); -+ goto DONE; - } -- fclose(fp); -- DPRINTF("nameservers = %d\n", __nameservers); -- BIGUNLOCK; -- return 0; -- } - DPRINTF("failed to open %s\n", "resolv.conf"); - h_errno = NO_RECOVERY; -- BIGUNLOCK; -- return -1; -+ -+ rv = -1; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); -+ return rv; - } - #endif - -@@ -1044,7 +1032,7 @@ int __open_nameservers() - - void __close_nameservers(void) - { -- BIGLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); - while (__nameservers > 0) { - free(__nameserver[--__nameservers]); - __nameserver[__nameservers] = NULL; -@@ -1053,7 +1041,7 @@ void __close_nameservers(void) - free(__searchdomain[--__searchdomains]); - __searchdomain[__searchdomains] = NULL; - } -- BIGUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - } - #endif - -@@ -1063,8 +1051,8 @@ struct hostent *gethostbyname(const char - { - static struct hostent h; - static char buf[sizeof(struct in_addr) + -- sizeof(struct in_addr *)*2 + -- sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */]; -+ sizeof(struct in_addr *)*2 + -+ sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */]; - struct hostent *hp; - - gethostbyname_r(name, &h, buf, sizeof(buf), &hp, &h_errno); -@@ -1082,8 +1070,8 @@ struct hostent *gethostbyname2(const cha - #else /* __UCLIBC_HAS_IPV6__ */ - static struct hostent h; - static char buf[sizeof(struct in6_addr) + -- sizeof(struct in6_addr *)*2 + -- sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */]; -+ sizeof(struct in6_addr *)*2 + -+ sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */]; - struct hostent *hp; - - gethostbyname2_r(name, family, &h, buf, sizeof(buf), &hp, &h_errno); -@@ -1119,7 +1107,7 @@ int res_init(void) - /** rp->rhook = NULL; **/ - /** rp->_u._ext.nsinit = 0; **/ - -- BIGLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); - if(__searchdomains) { - int i; - for(i=0; i<__searchdomains; i++) { -@@ -1139,7 +1127,7 @@ int res_init(void) - } - } - rp->nscount = __nameservers; -- BIGUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - - return(0); - } -@@ -1175,10 +1163,10 @@ int res_query(const char *dname, int cla - - memset((char *) &a, '\0', sizeof(a)); - -- BIGLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); - __nameserversXX=__nameservers; - __nameserverXX=__nameserver; -- BIGUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - i = __dns_lookup(dname, type, __nameserversXX, __nameserverXX, &packet, &a); - - if (i < 0) { -@@ -1207,10 +1195,10 @@ int res_query(const char *dname, int cla - * is detected. Error code, if any, is left in h_errno. - */ - int res_search(name, class, type, answer, anslen) -- const char *name; /* domain name */ -- int class, type; /* class and type of query */ -- u_char *answer; /* buffer to put answer */ -- int anslen; /* size of answer */ -+ const char *name; /* domain name */ -+ int class, type; /* class and type of query */ -+ u_char *answer; /* buffer to put answer */ -+ int anslen; /* size of answer */ - { - const char *cp, * const *domain; - HEADER *hp = (HEADER *)(void *)answer; -@@ -1256,11 +1244,11 @@ int res_search(name, class, type, answer - int done = 0; - - for (domain = (const char * const *)_res.dnsrch; -- *domain && !done; -- domain++) { -+ *domain && !done; -+ domain++) { - - ret = res_querydomain(name, *domain, class, type, -- answer, anslen); -+ answer, anslen); - if (ret > 0) - return (ret); - -@@ -1283,22 +1271,22 @@ int res_search(name, class, type, answer - } - - switch (h_errno) { -- case NO_DATA: -- got_nodata++; -- /* FALLTHROUGH */ -- case HOST_NOT_FOUND: -- /* keep trying */ -- break; -- case TRY_AGAIN: -- if (hp->rcode == SERVFAIL) { -- /* try next search element, if any */ -- got_servfail++; -+ case NO_DATA: -+ got_nodata++; -+ /* FALLTHROUGH */ -+ case HOST_NOT_FOUND: -+ /* keep trying */ - break; -- } -- /* FALLTHROUGH */ -- default: -- /* anything else implies that we're done */ -- done++; -+ case TRY_AGAIN: -+ if (hp->rcode == SERVFAIL) { -+ /* try next search element, if any */ -+ got_servfail++; -+ break; -+ } -+ /* FALLTHROUGH */ -+ default: -+ /* anything else implies that we're done */ -+ done++; - } - /* - * if we got here for some reason other than DNSRCH, -@@ -1342,10 +1330,10 @@ int res_search(name, class, type, answer - * removing a trailing dot from name if domain is NULL. - */ - int res_querydomain(name, domain, class, type, answer, anslen) -- const char *name, *domain; -- int class, type; /* class and type of query */ -- u_char *answer; /* buffer to put answer */ -- int anslen; /* size of answer */ -+ const char *name, *domain; -+ int class, type; /* class and type of query */ -+ u_char *answer; /* buffer to put answer */ -+ int anslen; /* size of answer */ - { - char nbuf[MAXDNAME]; - const char *longname = nbuf; -@@ -1359,7 +1347,7 @@ int res_querydomain(name, domain, class, - #ifdef DEBUG - if (_res.options & RES_DEBUG) - printf(";; res_querydomain(%s, %s, %d, %d)\n", -- name, domain?domain:"<Nil>", class, type); -+ name, domain?domain:"<Nil>", class, type); - #endif - if (domain == NULL) { - /* -@@ -1400,11 +1388,11 @@ struct hostent *gethostbyaddr (const voi - static struct hostent h; - static char buf[ - #ifndef __UCLIBC_HAS_IPV6__ -- sizeof(struct in_addr) + sizeof(struct in_addr *)*2 + -+ sizeof(struct in_addr) + sizeof(struct in_addr *)*2 + - #else -- sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 + -+ sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 + - #endif /* __UCLIBC_HAS_IPV6__ */ -- sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */]; -+ sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */]; - struct hostent *hp; - - gethostbyaddr_r(addr, len, type, &h, buf, sizeof(buf), &hp, &h_errno); -@@ -1425,11 +1413,11 @@ void __open_etc_hosts(FILE **fp) - } - - int __read_etc_hosts_r(FILE * fp, const char * name, int type, -- enum etc_hosts_action action, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop) -+ enum etc_hosts_action action, -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop) - { - struct in_addr *in=NULL; - struct in_addr **addr_list=NULL; -@@ -1576,56 +1564,49 @@ int __read_etc_hosts_r(FILE * fp, const - - #ifdef L_gethostent - --#ifdef __UCLIBC_HAS_THREADS__ --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - static int __stay_open; - static FILE * __gethostent_fp; - - void endhostent (void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - __stay_open = 0; - if (__gethostent_fp) { -- fclose(__gethostent_fp); -+ fclose(__gethostent_fp); - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - void sethostent (int stay_open) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - __stay_open = stay_open; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen, -- struct hostent **result, int *h_errnop) -+ struct hostent **result, int *h_errnop) - { -- int ret; -+ int ret = 0; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (__gethostent_fp == NULL) { -- __open_etc_hosts(&__gethostent_fp); -- if (__gethostent_fp == NULL) { -- UNLOCK; -- *result=NULL; -- return 0; -- } -+ __open_etc_hosts(&__gethostent_fp); -+ if (__gethostent_fp == NULL) { -+ *result=NULL; -+ goto DONE; -+ } - } - - ret = __read_etc_hosts_r(__gethostent_fp, NULL, AF_INET, GETHOSTENT, -- result_buf, buf, buflen, result, h_errnop); -+ result_buf, buf, buflen, result, h_errnop); - if (__stay_open==0) { -- fclose(__gethostent_fp); -+ fclose(__gethostent_fp); - } -- UNLOCK; -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return(ret); - } - -@@ -1634,17 +1615,17 @@ struct hostent *gethostent (void) - static struct hostent h; - static char buf[ - #ifndef __UCLIBC_HAS_IPV6__ -- sizeof(struct in_addr) + sizeof(struct in_addr *)*2 + -+ sizeof(struct in_addr) + sizeof(struct in_addr *)*2 + - #else -- sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 + -+ sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 + - #endif /* __UCLIBC_HAS_IPV6__ */ -- sizeof(char *)*(ALIAS_DIM) + -- 80/*namebuffer*/ + 2/* margin */]; -+ sizeof(char *)*(ALIAS_DIM) + -+ 80/*namebuffer*/ + 2/* margin */]; - struct hostent *host; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - gethostent_r(&h, buf, sizeof(buf), &host, &h_errno); -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return(host); - } - #endif -@@ -1652,23 +1633,23 @@ struct hostent *gethostent (void) - #ifdef L_get_hosts_byname_r - - int __get_hosts_byname_r(const char * name, int type, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop) -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop) - { - return(__read_etc_hosts_r(NULL, name, type, GET_HOSTS_BYNAME, -- result_buf, buf, buflen, result, h_errnop)); -+ result_buf, buf, buflen, result, h_errnop)); - } - #endif - - #ifdef L_get_hosts_byaddr_r - - int __get_hosts_byaddr_r(const char * addr, int len, int type, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop) -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop) - { - #ifndef __UCLIBC_HAS_IPV6__ - char ipaddr[INET_ADDRSTRLEN]; -@@ -1677,24 +1658,24 @@ int __get_hosts_byaddr_r(const char * ad - #endif /* __UCLIBC_HAS_IPV6__ */ - - switch (type) { -- case AF_INET: -- if (len != sizeof(struct in_addr)) -- return 0; -- break; -+ case AF_INET: -+ if (len != sizeof(struct in_addr)) -+ return 0; -+ break; - #ifdef __UCLIBC_HAS_IPV6__ -- case AF_INET6: -- if (len != sizeof(struct in6_addr)) -- return 0; -- break; -+ case AF_INET6: -+ if (len != sizeof(struct in6_addr)) -+ return 0; -+ break; - #endif /* __UCLIBC_HAS_IPV6__ */ -- default: -- return 0; -+ default: -+ return 0; - } - - inet_ntop(type, addr, ipaddr, sizeof(ipaddr)); - - return(__read_etc_hosts_r(NULL, ipaddr, type, GET_HOSTS_BYADDR, -- result_buf, buf, buflen, result, h_errnop)); -+ result_buf, buf, buflen, result, h_errnop)); - } - #endif - -@@ -1705,8 +1686,8 @@ int __get_hosts_byaddr_r(const char * ad - #endif /* min */ - - int getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host, -- socklen_t hostlen, char *serv, socklen_t servlen, -- unsigned int flags) -+ socklen_t hostlen, char *serv, socklen_t servlen, -+ unsigned int flags) - { - int serrno = errno; - int ok = 0; -@@ -1720,167 +1701,167 @@ int getnameinfo (const struct sockaddr * - return EAI_FAMILY; - - switch (sa->sa_family) { -- case AF_LOCAL: -- break; -- case AF_INET: -- if (addrlen < sizeof (struct sockaddr_in)) -- return EAI_FAMILY; -- break; -+ case AF_LOCAL: -+ break; -+ case AF_INET: -+ if (addrlen < sizeof (struct sockaddr_in)) -+ return EAI_FAMILY; -+ break; - #ifdef __UCLIBC_HAS_IPV6__ -- case AF_INET6: -- if (addrlen < sizeof (struct sockaddr_in6)) -- return EAI_FAMILY; -- break; -+ case AF_INET6: -+ if (addrlen < sizeof (struct sockaddr_in6)) -+ return EAI_FAMILY; -+ break; - #endif /* __UCLIBC_HAS_IPV6__ */ -- default: -- return EAI_FAMILY; -+ default: -+ return EAI_FAMILY; - } - - if (host != NULL && hostlen > 0) - switch (sa->sa_family) { -- case AF_INET: -+ case AF_INET: - #ifdef __UCLIBC_HAS_IPV6__ -- case AF_INET6: -+ case AF_INET6: - #endif /* __UCLIBC_HAS_IPV6__ */ -- if (!(flags & NI_NUMERICHOST)) { -+ if (!(flags & NI_NUMERICHOST)) { - #ifdef __UCLIBC_HAS_IPV6__ -- if (sa->sa_family == AF_INET6) -- h = gethostbyaddr ((const void *) -- &(((const struct sockaddr_in6 *) sa)->sin6_addr), -- sizeof(struct in6_addr), AF_INET6); -- else --#endif /* __UCLIBC_HAS_IPV6__ */ -- h = gethostbyaddr ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr), -- sizeof(struct in_addr), AF_INET); -- -- if (h) { -- char *c; -- if ((flags & NI_NOFQDN) -- && (getdomainname (domain, sizeof(domain)) == 0) -- && (c = strstr (h->h_name, domain)) -- && (c != h->h_name) && (*(--c) == '.')) { -- strncpy (host, h->h_name, -- min(hostlen, (size_t) (c - h->h_name))); -- host[min(hostlen - 1, (size_t) (c - h->h_name))] = '\0'; -- ok = 1; -- } else { -- strncpy (host, h->h_name, hostlen); -- ok = 1; -+ if (sa->sa_family == AF_INET6) -+ h = gethostbyaddr ((const void *) -+ &(((const struct sockaddr_in6 *) sa)->sin6_addr), -+ sizeof(struct in6_addr), AF_INET6); -+ else -+#endif /* __UCLIBC_HAS_IPV6__ */ -+ h = gethostbyaddr ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr), -+ sizeof(struct in_addr), AF_INET); -+ -+ if (h) { -+ char *c; -+ if ((flags & NI_NOFQDN) -+ && (getdomainname (domain, sizeof(domain)) == 0) -+ && (c = strstr (h->h_name, domain)) -+ && (c != h->h_name) && (*(--c) == '.')) { -+ strncpy (host, h->h_name, -+ min(hostlen, (size_t) (c - h->h_name))); -+ host[min(hostlen - 1, (size_t) (c - h->h_name))] = '\0'; -+ ok = 1; -+ } else { -+ strncpy (host, h->h_name, hostlen); -+ ok = 1; -+ } - } -- } -- } -+ } - -- if (!ok) { -- if (flags & NI_NAMEREQD) { -- errno = serrno; -- return EAI_NONAME; -- } else { -- const char *c; -+ if (!ok) { -+ if (flags & NI_NAMEREQD) { -+ errno = serrno; -+ return EAI_NONAME; -+ } else { -+ const char *c; - #ifdef __UCLIBC_HAS_IPV6__ -- if (sa->sa_family == AF_INET6) { -- const struct sockaddr_in6 *sin6p; -+ if (sa->sa_family == AF_INET6) { -+ const struct sockaddr_in6 *sin6p; - -- sin6p = (const struct sockaddr_in6 *) sa; -+ sin6p = (const struct sockaddr_in6 *) sa; - -- c = inet_ntop (AF_INET6, -- (const void *) &sin6p->sin6_addr, host, hostlen); -+ c = inet_ntop (AF_INET6, -+ (const void *) &sin6p->sin6_addr, host, hostlen); - #if 0 -- /* Does scope id need to be supported? */ -- uint32_t scopeid; -- scopeid = sin6p->sin6_scope_id; -- if (scopeid != 0) { -- /* Buffer is >= IFNAMSIZ+1. */ -- char scopebuf[IFNAMSIZ + 1]; -- char *scopeptr; -- int ni_numericscope = 0; -- size_t real_hostlen = __strnlen (host, hostlen); -- size_t scopelen = 0; -- -- scopebuf[0] = SCOPE_DELIMITER; -- scopebuf[1] = '\0'; -- scopeptr = &scopebuf[1]; -- -- if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr) -- || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr)) { -- if (if_indextoname (scopeid, scopeptr) == NULL) -+ /* Does scope id need to be supported? */ -+ uint32_t scopeid; -+ scopeid = sin6p->sin6_scope_id; -+ if (scopeid != 0) { -+ /* Buffer is >= IFNAMSIZ+1. */ -+ char scopebuf[IFNAMSIZ + 1]; -+ char *scopeptr; -+ int ni_numericscope = 0; -+ size_t real_hostlen = __strnlen (host, hostlen); -+ size_t scopelen = 0; -+ -+ scopebuf[0] = SCOPE_DELIMITER; -+ scopebuf[1] = '\0'; -+ scopeptr = &scopebuf[1]; -+ -+ if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr) -+ || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr)) { -+ if (if_indextoname (scopeid, scopeptr) == NULL) -+ ++ni_numericscope; -+ else -+ scopelen = strlen (scopebuf); -+ } else { - ++ni_numericscope; -- else -- scopelen = strlen (scopebuf); -- } else { -- ++ni_numericscope; -- } -+ } - -- if (ni_numericscope) -- scopelen = 1 + snprintf (scopeptr, -- (scopebuf -- + sizeof scopebuf -- - scopeptr), -- "%u", scopeid); -- -- if (real_hostlen + scopelen + 1 > hostlen) -- return EAI_SYSTEM; -- memcpy (host + real_hostlen, scopebuf, scopelen + 1); -- } -+ if (ni_numericscope) -+ scopelen = 1 + snprintf (scopeptr, -+ (scopebuf -+ + sizeof scopebuf -+ - scopeptr), -+ "%u", scopeid); -+ -+ if (real_hostlen + scopelen + 1 > hostlen) -+ return EAI_SYSTEM; -+ memcpy (host + real_hostlen, scopebuf, scopelen + 1); -+ } - #endif -- } else -+ } else - #endif /* __UCLIBC_HAS_IPV6__ */ -- c = inet_ntop (AF_INET, (const void *) -- &(((const struct sockaddr_in *) sa)->sin_addr), -- host, hostlen); -- -- if (c == NULL) { -- errno = serrno; -- return EAI_SYSTEM; -+ c = inet_ntop (AF_INET, (const void *) -+ &(((const struct sockaddr_in *) sa)->sin_addr), -+ host, hostlen); -+ -+ if (c == NULL) { -+ errno = serrno; -+ return EAI_SYSTEM; -+ } - } -+ ok = 1; - } -- ok = 1; -- } -- break; -- -- case AF_LOCAL: -- if (!(flags & NI_NUMERICHOST)) { -- struct utsname utsname; -+ break; - -- if (!uname (&utsname)) { -- strncpy (host, utsname.nodename, hostlen); -- break; -+ case AF_LOCAL: -+ if (!(flags & NI_NUMERICHOST)) { -+ struct utsname utsname; -+ -+ if (!uname (&utsname)) { -+ strncpy (host, utsname.nodename, hostlen); -+ break; -+ }; - }; -- }; - -- if (flags & NI_NAMEREQD) { -- errno = serrno; -- return EAI_NONAME; -- } -+ if (flags & NI_NAMEREQD) { -+ errno = serrno; -+ return EAI_NONAME; -+ } - -- strncpy (host, "localhost", hostlen); -- break; -+ strncpy (host, "localhost", hostlen); -+ break; - -- default: -- return EAI_FAMILY; -- } -+ default: -+ return EAI_FAMILY; -+ } - - if (serv && (servlen > 0)) { - switch (sa->sa_family) { -- case AF_INET: -+ case AF_INET: - #ifdef __UCLIBC_HAS_IPV6__ -- case AF_INET6: -+ case AF_INET6: - #endif /* __UCLIBC_HAS_IPV6__ */ -- if (!(flags & NI_NUMERICSERV)) { -- struct servent *s; -- s = getservbyport (((const struct sockaddr_in *) sa)->sin_port, -- ((flags & NI_DGRAM) ? "udp" : "tcp")); -- if (s) { -- strncpy (serv, s->s_name, servlen); -- break; -+ if (!(flags & NI_NUMERICSERV)) { -+ struct servent *s; -+ s = getservbyport (((const struct sockaddr_in *) sa)->sin_port, -+ ((flags & NI_DGRAM) ? "udp" : "tcp")); -+ if (s) { -+ strncpy (serv, s->s_name, servlen); -+ break; -+ } - } -- } -- snprintf (serv, servlen, "%d", -- ntohs (((const struct sockaddr_in *) sa)->sin_port)); -- break; -+ snprintf (serv, servlen, "%d", -+ ntohs (((const struct sockaddr_in *) sa)->sin_port)); -+ break; - -- case AF_LOCAL: -- strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen); -- break; -+ case AF_LOCAL: -+ strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen); -+ break; - } - } - if (host && (hostlen > 0)) -@@ -1896,10 +1877,10 @@ int getnameinfo (const struct sockaddr * - #ifdef L_gethostbyname_r - - int gethostbyname_r(const char * name, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop) -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop) - { - struct in_addr *in; - struct in_addr **addr_list; -@@ -1921,7 +1902,7 @@ int gethostbyname_r(const char * name, - __set_errno(0); /* to check for missing /etc/hosts. */ - - if ((i=__get_hosts_byname_r(name, AF_INET, result_buf, -- buf, buflen, result, h_errnop))==0) -+ buf, buflen, result, h_errnop))==0) - return i; - switch (*h_errnop) { - case HOST_NOT_FOUND: -@@ -1983,60 +1964,60 @@ int gethostbyname_r(const char * name, - - for (;;) { - -- BIGLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); - __nameserversXX=__nameservers; - __nameserverXX=__nameserver; -- BIGUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - a.buf = buf; - a.buflen = buflen; - a.add_count = 0; - i = __dns_lookup(name, T_A, __nameserversXX, __nameserverXX, &packet, &a); - - if (i < 0) { -- *h_errnop = HOST_NOT_FOUND; -- DPRINTF("__dns_lookup\n"); -- return TRY_AGAIN; -+ *h_errnop = HOST_NOT_FOUND; -+ DPRINTF("__dns_lookup\n"); -+ return TRY_AGAIN; - } - - if ((a.rdlength + sizeof(struct in_addr*)) * a.add_count + 256 > buflen) -- { -- free(a.dotted); -- free(packet); -- *h_errnop = NETDB_INTERNAL; -- DPRINTF("buffer too small for all addresses\n"); -- return ERANGE; -- } -+ { -+ free(a.dotted); -+ free(packet); -+ *h_errnop = NETDB_INTERNAL; -+ DPRINTF("buffer too small for all addresses\n"); -+ return ERANGE; -+ } - else if(a.add_count > 0) -- { -- memmove(buf - sizeof(struct in_addr*)*2, buf, a.add_count * a.rdlength); -- addr_list = (struct in_addr**)(buf + a.add_count * a.rdlength); -- addr_list[0] = in; -- for (i = a.add_count-1; i>=0; --i) -- addr_list[i+1] = (struct in_addr*)(buf - sizeof(struct in_addr*)*2 + a.rdlength * i); -- addr_list[a.add_count + 1] = 0; -- buflen -= (((char*)&(addr_list[a.add_count + 2])) - buf); -- buf = (char*)&addr_list[a.add_count + 2]; -- } -+ { -+ memmove(buf - sizeof(struct in_addr*)*2, buf, a.add_count * a.rdlength); -+ addr_list = (struct in_addr**)(buf + a.add_count * a.rdlength); -+ addr_list[0] = in; -+ for (i = a.add_count-1; i>=0; --i) -+ addr_list[i+1] = (struct in_addr*)(buf - sizeof(struct in_addr*)*2 + a.rdlength * i); -+ addr_list[a.add_count + 1] = 0; -+ buflen -= (((char*)&(addr_list[a.add_count + 2])) - buf); -+ buf = (char*)&addr_list[a.add_count + 2]; -+ } - - strncpy(buf, a.dotted, buflen); - free(a.dotted); - - if (a.atype == T_A) { /* ADDRESS */ -- memcpy(in, a.rdata, sizeof(*in)); -- result_buf->h_name = buf; -- result_buf->h_addrtype = AF_INET; -- result_buf->h_length = sizeof(*in); -- result_buf->h_addr_list = (char **) addr_list; -+ memcpy(in, a.rdata, sizeof(*in)); -+ result_buf->h_name = buf; -+ result_buf->h_addrtype = AF_INET; -+ result_buf->h_length = sizeof(*in); -+ result_buf->h_addr_list = (char **) addr_list; - #ifdef __UCLIBC_MJN3_ONLY__ - #warning TODO -- generate the full list - #endif -- result_buf->h_aliases = alias; /* TODO: generate the full list */ -- free(packet); -- break; -+ result_buf->h_aliases = alias; /* TODO: generate the full list */ -+ free(packet); -+ break; - } else { -- free(packet); -- *h_errnop=HOST_NOT_FOUND; -- return TRY_AGAIN; -+ free(packet); -+ *h_errnop=HOST_NOT_FOUND; -+ return TRY_AGAIN; - } - } - -@@ -2049,14 +2030,14 @@ int gethostbyname_r(const char * name, - #ifdef L_gethostbyname2_r - - int gethostbyname2_r(const char *name, int family, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop) -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop) - { - #ifndef __UCLIBC_HAS_IPV6__ - return family == (AF_INET)? gethostbyname_r(name, result_buf, -- buf, buflen, result, h_errnop) : HOST_NOT_FOUND; -+ buf, buflen, result, h_errnop) : HOST_NOT_FOUND; - #else /* __UCLIBC_HAS_IPV6__ */ - struct in6_addr *in; - struct in6_addr **addr_list; -@@ -2084,7 +2065,7 @@ int gethostbyname2_r(const char *name, i - __set_errno(0); /* to check for missing /etc/hosts. */ - - if ((i=__get_hosts_byname_r(name, AF_INET, result_buf, -- buf, buflen, result, h_errnop))==0) -+ buf, buflen, result, h_errnop))==0) - return i; - switch (*h_errnop) { - case HOST_NOT_FOUND: -@@ -2137,10 +2118,10 @@ int gethostbyname2_r(const char *name, i - memset((char *) &a, '\0', sizeof(a)); - - for (;;) { -- BIGLOCK; -- __nameserversXX=__nameservers; -- __nameserverXX=__nameserver; -- BIGUNLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); -+ __nameserversXX=__nameservers; -+ __nameserverXX=__nameserver; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - - i = __dns_lookup(buf, T_AAAA, __nameserversXX, __nameserverXX, &packet, &a); - -@@ -2190,10 +2171,10 @@ int gethostbyname2_r(const char *name, i - - #ifdef L_gethostbyaddr_r - int gethostbyaddr_r (const void *addr, socklen_t len, int type, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop) -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop) - - { - struct in_addr *in; -@@ -2234,7 +2215,7 @@ int gethostbyaddr_r (const void *addr, s - - /* do /etc/hosts first */ - if ((i=__get_hosts_byaddr_r(addr, len, type, result_buf, -- buf, buflen, result, h_errnop))==0) -+ buf, buflen, result, h_errnop))==0) - return i; - switch (*h_errnop) { - case HOST_NOT_FOUND: -@@ -2294,7 +2275,7 @@ int gethostbyaddr_r (const void *addr, s - addr_list[0] = in; - - sprintf(buf, "%u.%u.%u.%u.in-addr.arpa", -- tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]); -+ tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]); - #ifdef __UCLIBC_HAS_IPV6__ - } else { - memcpy(in6->s6_addr, addr, len); -@@ -2304,7 +2285,7 @@ int gethostbyaddr_r (const void *addr, s - - for (i = len - 1; i >= 0; i--) { - qp += sprintf(qp, "%x.%x.", in6->s6_addr[i] & 0xf, -- (in6->s6_addr[i] >> 4) & 0xf); -+ (in6->s6_addr[i] >> 4) & 0xf); - } - strcpy(qp, "ip6.int"); - #endif /* __UCLIBC_HAS_IPV6__ */ -@@ -2314,10 +2295,10 @@ int gethostbyaddr_r (const void *addr, s - - for (;;) { - -- BIGLOCK; -- __nameserversXX=__nameservers; -- __nameserverXX=__nameserver; -- BIGUNLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); -+ __nameserversXX=__nameservers; -+ __nameserverXX=__nameserver; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - i = __dns_lookup(buf, T_PTR, __nameserversXX, __nameserverXX, &packet, &a); - - if (i < 0) { -@@ -2381,7 +2362,7 @@ int gethostbyaddr_r (const void *addr, s - * Return size of compressed name or -1 if there was an error. - */ - int __dn_expand(const u_char *msg, const u_char *eom, const u_char *src, -- char *dst, int dstsiz) -+ char *dst, int dstsiz) - { - int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz); - -@@ -2401,7 +2382,7 @@ int __dn_expand(const u_char *msg, const - */ - static int printable(int ch) - { -- return (ch > 0x20 && ch < 0x7f); -+ return (ch > 0x20 && ch < 0x7f); - } - - /* -@@ -2413,18 +2394,18 @@ static int printable(int ch) - */ - static int special(int ch) - { -- switch (ch) { -+ switch (ch) { - case 0x22: /* '"' */ - case 0x2E: /* '.' */ - case 0x3B: /* ';' */ - case 0x5C: /* '\\' */ -- /* Special modifiers in zone files. */ -+ /* Special modifiers in zone files. */ - case 0x40: /* '@' */ - case 0x24: /* '$' */ -- return (1); -+ return (1); - default: -- return (0); -- } -+ return (0); -+ } - } - - /* -@@ -2436,7 +2417,7 @@ static int special(int ch) - * Root domain returns as "." not "". - */ - int __ns_name_uncompress(const u_char *msg, const u_char *eom, -- const u_char *src, char *dst, size_t dstsiz) -+ const u_char *src, char *dst, size_t dstsiz) - { - u_char tmp[NS_MAXCDNAME]; - int n; -@@ -2525,7 +2506,7 @@ int __ns_name_ntop(const u_char *src, ch - return (-1); - } - *dn++ = '\0'; -- return (dn - dst); -+ return (dn - dst); - } - - /* -@@ -2535,7 +2516,7 @@ int __ns_name_ntop(const u_char *src, ch - * -1 if it fails, or consumed octets if it succeeds. - */ - int __ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, -- u_char *dst, size_t dstsiz) -+ u_char *dst, size_t dstsiz) - { - const u_char *srcp, *dstlim; - u_char *dstp; -@@ -2554,46 +2535,46 @@ int __ns_name_unpack(const u_char *msg, - while ((n = *srcp++) != 0) { - /* Check for indirection. */ - switch (n & NS_CMPRSFLGS) { -- case 0: -- /* Limit checks. */ -- if (dstp + n + 1 >= dstlim || srcp + n >= eom) { -- __set_errno (EMSGSIZE); -- return (-1); -- } -- checked += n + 1; -- *dstp++ = n; -- memcpy(dstp, srcp, n); -- dstp += n; -- srcp += n; -- break; -+ case 0: -+ /* Limit checks. */ -+ if (dstp + n + 1 >= dstlim || srcp + n >= eom) { -+ __set_errno (EMSGSIZE); -+ return (-1); -+ } -+ checked += n + 1; -+ *dstp++ = n; -+ memcpy(dstp, srcp, n); -+ dstp += n; -+ srcp += n; -+ break; - -- case NS_CMPRSFLGS: -- if (srcp >= eom) { -- __set_errno (EMSGSIZE); -- return (-1); -- } -- if (len < 0) -- len = srcp - src + 1; -- srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff)); -- if (srcp < msg || srcp >= eom) { /* Out of range. */ -- __set_errno (EMSGSIZE); -- return (-1); -- } -- checked += 2; -- /* -- * Check for loops in the compressed name; -- * if we've looked at the whole message, -- * there must be a loop. -- */ -- if (checked >= eom - msg) { -- __set_errno (EMSGSIZE); -- return (-1); -- } -- break; -+ case NS_CMPRSFLGS: -+ if (srcp >= eom) { -+ __set_errno (EMSGSIZE); -+ return (-1); -+ } -+ if (len < 0) -+ len = srcp - src + 1; -+ srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff)); -+ if (srcp < msg || srcp >= eom) { /* Out of range. */ -+ __set_errno (EMSGSIZE); -+ return (-1); -+ } -+ checked += 2; -+ /* -+ * Check for loops in the compressed name; -+ * if we've looked at the whole message, -+ * there must be a loop. -+ */ -+ if (checked >= eom - msg) { -+ __set_errno (EMSGSIZE); -+ return (-1); -+ } -+ break; - -- default: -- __set_errno (EMSGSIZE); -- return (-1); /* flag error */ -+ default: -+ __set_errno (EMSGSIZE); -+ return (-1); /* flag error */ - } - } - *dstp = '\0'; -diff --git a/libc/inet/rpc/create_xid.c b/libc/inet/rpc/create_xid.c -index cbb961e..c86cbb4 100644 ---- a/libc/inet/rpc/create_xid.c -+++ b/libc/inet/rpc/create_xid.c -@@ -27,15 +27,7 @@ - - /* The RPC code is not threadsafe, but new code should be threadsafe. */ - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t createxid_lock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&createxid_lock) --# define UNLOCK __pthread_mutex_unlock(&createxid_lock); --#else --# define LOCK --# define UNLOCK --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - static int is_initialized; - static struct drand48_data __rpc_lrand48_data; -@@ -43,22 +35,22 @@ static struct drand48_data __rpc_lrand48 - unsigned long - _create_xid (void) - { -- unsigned long res; -+ unsigned long res; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - -- if (!is_initialized) -- { -- struct timeval now; -+ if (!is_initialized) -+ { -+ struct timeval now; - -- gettimeofday (&now, (struct timezone *) 0); -- srand48_r (now.tv_sec ^ now.tv_usec, &__rpc_lrand48_data); -- is_initialized = 1; -- } -+ gettimeofday (&now, (struct timezone *) 0); -+ srand48_r (now.tv_sec ^ now.tv_usec, &__rpc_lrand48_data); -+ is_initialized = 1; -+ } - -- lrand48_r (&__rpc_lrand48_data, &res); -+ lrand48_r (&__rpc_lrand48_data, &res); - -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - -- return res; -+ return res; - } -diff --git a/libc/misc/dirent/closedir.c b/libc/misc/dirent/closedir.c -index 068e2d3..56adb23 100644 ---- a/libc/misc/dirent/closedir.c -+++ b/libc/misc/dirent/closedir.c -@@ -4,7 +4,6 @@ - #include <unistd.h> - #include "dirstream.h" - -- - int closedir(DIR * dir) - { - int fd; -@@ -19,14 +18,10 @@ int closedir(DIR * dir) - __set_errno(EBADF); - return -1; - } --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - fd = dir->dd_fd; - dir->dd_fd = -1; --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); - free(dir->dd_buf); - free(dir); - return close(fd); -diff --git a/libc/misc/dirent/dirstream.h b/libc/misc/dirent/dirstream.h -index 2dd0264..bd721c5 100644 ---- a/libc/misc/dirent/dirstream.h -+++ b/libc/misc/dirent/dirstream.h -@@ -26,9 +26,8 @@ Cambridge, MA 02139, USA. */ - - #include <features.h> - #include <sys/types.h> --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --#endif -+ -+#include <bits/uClibc_mutex.h> - - /* For now, syscall readdir () only supports one entry at a time. It - * will be changed in the future. -@@ -63,11 +62,7 @@ struct __dirstream { - size_t dd_max; - - /* lock */ --#ifdef __UCLIBC_HAS_THREADS__ -- pthread_mutex_t dd_lock; --#else -- void *dd_lock; --#endif -+ __UCLIBC_MUTEX(dd_lock); - }; /* stream data from opendir() */ - - -diff --git a/libc/misc/dirent/readdir.c b/libc/misc/dirent/readdir.c -index 1f196e1..c55317a 100644 ---- a/libc/misc/dirent/readdir.c -+++ b/libc/misc/dirent/readdir.c -@@ -5,7 +5,6 @@ - #include <dirent.h> - #include "dirstream.h" - -- - struct dirent *readdir(DIR * dir) - { - ssize_t bytes; -@@ -16,9 +15,7 @@ struct dirent *readdir(DIR * dir) - return NULL; - } - --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - - do { - if (dir->dd_size <= dir->dd_nextloc) { -@@ -44,8 +41,6 @@ struct dirent *readdir(DIR * dir) - } while (de->d_ino == 0); - - all_done: --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); - return de; - } -diff --git a/libc/misc/dirent/readdir64.c b/libc/misc/dirent/readdir64.c -index f798c6f..6da3b0d 100644 ---- a/libc/misc/dirent/readdir64.c -+++ b/libc/misc/dirent/readdir64.c -@@ -20,7 +20,6 @@ - #include <dirent.h> - #include "dirstream.h" - -- - struct dirent64 *readdir64(DIR * dir) - { - ssize_t bytes; -@@ -31,9 +30,7 @@ struct dirent64 *readdir64(DIR * dir) - return NULL; - } - --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - - do { - if (dir->dd_size <= dir->dd_nextloc) { -@@ -59,9 +56,7 @@ struct dirent64 *readdir64(DIR * dir) - } while (de->d_ino == 0); - - all_done: --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); - - return de; - } -diff --git a/libc/misc/dirent/readdir64_r.c b/libc/misc/dirent/readdir64_r.c -index da3564e..cc96eff 100644 ---- a/libc/misc/dirent/readdir64_r.c -+++ b/libc/misc/dirent/readdir64_r.c -@@ -19,7 +19,6 @@ - #include <dirent.h> - #include "dirstream.h" - -- - int readdir64_r(DIR *dir, struct dirent64 *entry, struct dirent64 **result) - { - int ret; -@@ -32,21 +31,19 @@ int readdir64_r(DIR *dir, struct dirent6 - } - de = NULL; - --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - - do { - if (dir->dd_size <= dir->dd_nextloc) { -- /* read dir->dd_max bytes of directory entries. */ -- bytes = __getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max); -- if (bytes <= 0) { -- *result = NULL; -- ret = errno; -- goto all_done; -- } -- dir->dd_size = bytes; -- dir->dd_nextloc = 0; -+ /* read dir->dd_max bytes of directory entries. */ -+ bytes = __getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max); -+ if (bytes <= 0) { -+ *result = NULL; -+ ret = errno; -+ goto all_done; -+ } -+ dir->dd_size = bytes; -+ dir->dd_nextloc = 0; - } - - de = (struct dirent64 *) (((char *) dir->dd_buf) + dir->dd_nextloc); -@@ -66,12 +63,10 @@ int readdir64_r(DIR *dir, struct dirent6 - } - ret = 0; - --all_done: -+ all_done: - --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -- return((de != NULL)? 0 : ret); -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); -+ return((de != NULL)? 0 : ret); - } - #endif /* __UCLIBC_HAS_LFS__ */ - -diff --git a/libc/misc/dirent/readdir_r.c b/libc/misc/dirent/readdir_r.c -index 245dcbd..aeccdd8 100644 ---- a/libc/misc/dirent/readdir_r.c -+++ b/libc/misc/dirent/readdir_r.c -@@ -5,7 +5,6 @@ - #include <dirent.h> - #include "dirstream.h" - -- - int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) - { - int ret; -@@ -18,21 +17,19 @@ int readdir_r(DIR *dir, struct dirent *e - } - de = NULL; - --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - - do { - if (dir->dd_size <= dir->dd_nextloc) { -- /* read dir->dd_max bytes of directory entries. */ -- bytes = __getdents(dir->dd_fd, dir->dd_buf, dir->dd_max); -- if (bytes <= 0) { -- *result = NULL; -- ret = errno; -- goto all_done; -- } -- dir->dd_size = bytes; -- dir->dd_nextloc = 0; -+ /* read dir->dd_max bytes of directory entries. */ -+ bytes = __getdents(dir->dd_fd, dir->dd_buf, dir->dd_max); -+ if (bytes <= 0) { -+ *result = NULL; -+ ret = errno; -+ goto all_done; -+ } -+ dir->dd_size = bytes; -+ dir->dd_nextloc = 0; - } - - de = (struct dirent *) (((char *) dir->dd_buf) + dir->dd_nextloc); -@@ -52,10 +49,8 @@ int readdir_r(DIR *dir, struct dirent *e - } - ret = 0; - --all_done: -+ all_done: - --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -- return((de != NULL)? 0 : ret); -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); -+ return((de != NULL)? 0 : ret); - } -diff --git a/libc/misc/dirent/rewinddir.c b/libc/misc/dirent/rewinddir.c -index 60ef71d..fe8fc2a 100644 ---- a/libc/misc/dirent/rewinddir.c -+++ b/libc/misc/dirent/rewinddir.c -@@ -3,7 +3,6 @@ - #include <unistd.h> - #include "dirstream.h" - -- - /* rewinddir() just does an lseek(fd,0,0) - see close for comments */ - void rewinddir(DIR * dir) - { -@@ -11,12 +10,8 @@ void rewinddir(DIR * dir) - __set_errno(EBADF); - return; - } --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - lseek(dir->dd_fd, 0, SEEK_SET); - dir->dd_nextoff = dir->dd_nextloc = dir->dd_size = 0; --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); - } -diff --git a/libc/misc/dirent/seekdir.c b/libc/misc/dirent/seekdir.c -index 139f1e1..6d6f5f0 100644 ---- a/libc/misc/dirent/seekdir.c -+++ b/libc/misc/dirent/seekdir.c -@@ -3,19 +3,14 @@ - #include <unistd.h> - #include "dirstream.h" - -- - void seekdir(DIR * dir, long int offset) - { - if (!dir) { - __set_errno(EBADF); - return; - } --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - dir->dd_nextoff = lseek(dir->dd_fd, offset, SEEK_SET); - dir->dd_size = dir->dd_nextloc = 0; --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); - } -diff --git a/libc/misc/mntent/mntent.c b/libc/misc/mntent/mntent.c -index d98a687..af6d848 100644 ---- a/libc/misc/mntent/mntent.c -+++ b/libc/misc/mntent/mntent.c -@@ -3,15 +3,9 @@ - #include <string.h> - #include <mntent.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -+#include <bits/uClibc_mutex.h> -+ -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - /* Reentrant version of getmntent. */ - struct mntent *getmntent_r (FILE *filep, -@@ -67,7 +61,7 @@ struct mntent *getmntent(FILE * filep) - struct mntent *tmp; - static char *buff = NULL; - static struct mntent mnt; -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - if (!buff) { - buff = malloc(BUFSIZ); -@@ -76,7 +70,7 @@ struct mntent *getmntent(FILE * filep) - } - - tmp = getmntent_r(filep, &mnt, buff, BUFSIZ); -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return(tmp); - } - -diff --git a/libc/misc/pthread/weaks.c b/libc/misc/pthread/weaks.c -index 89c2611..c27bd10 100644 ---- a/libc/misc/pthread/weaks.c -+++ b/libc/misc/pthread/weaks.c -@@ -21,6 +21,7 @@ - #include <limits.h> - #include <stdlib.h> - -+static void __pthread_return_void __P ((void)); - static int __pthread_return_0 __P ((void)); - static int __pthread_return_1 __P ((void)); - -@@ -104,8 +105,17 @@ weak_alias (__pthread_return_0, __pthrea - weak_alias (__pthread_return_0, __pthread_mutex_trylock) - weak_alias (__pthread_return_0, __pthread_mutex_unlock) - -+weak_alias (__pthread_return_void, _pthread_cleanup_push_defer) -+weak_alias (__pthread_return_void, _pthread_cleanup_pop_restore) -+ - /**********************************************************************/ - -+static void -+__pthread_return_void (void) -+{ -+ return; -+} -+ - static int - __pthread_return_0 (void) - { -diff --git a/libc/misc/syslog/syslog.c b/libc/misc/syslog/syslog.c -index 2b478e1..9e9ddbf 100644 ---- a/libc/misc/syslog/syslog.c -+++ b/libc/misc/syslog/syslog.c -@@ -80,17 +80,9 @@ - #include <ctype.h> - #include <signal.h> - -+#include <bits/uClibc_mutex.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -- -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - static int LogFile = -1; /* fd for log */ - static int connected; /* have done connect */ -@@ -110,26 +102,26 @@ int setlogmask(int pmask); - static void - closelog_intern(int to_default) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (LogFile != -1) { - (void) close(LogFile); - } - LogFile = -1; - connected = 0; - if (to_default) -- { -- LogStat = 0; -- LogTag = "syslog"; -- LogFacility = LOG_USER; -- LogMask = 0xff; -- } -- UNLOCK; -+ { -+ LogStat = 0; -+ LogTag = "syslog"; -+ LogFacility = LOG_USER; -+ LogMask = 0xff; -+ } -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - static void - sigpipe_handler (int sig) - { -- closelog_intern (0); -+ closelog_intern (0); - } - - /* -@@ -165,7 +157,7 @@ vsyslog( int pri, const char *fmt, va_li - - saved_errno = errno; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - /* See if we should just throw out this message. */ - if (!(LogMask & LOG_MASK(LOG_PRI(pri))) || (pri &~ (LOG_PRIMASK|LOG_FACMASK))) -@@ -208,7 +200,7 @@ vsyslog( int pri, const char *fmt, va_li - if (p >= end || p < head_end) { /* Returned -1 in case of error... */ - static const char truncate_msg[12] = "[truncated] "; - memmove(head_end + sizeof(truncate_msg), head_end, -- end - head_end - sizeof(truncate_msg)); -+ end - head_end - sizeof(truncate_msg)); - memcpy(head_end, truncate_msg, sizeof(truncate_msg)); - if (p < head_end) { - while (p < end && *p) { -@@ -261,11 +253,11 @@ vsyslog( int pri, const char *fmt, va_li - (void)close(fd); - } - --getout: -- UNLOCK; -+ getout: -+ __UCLIBC_MUTEX_UNLOCK(mylock); - if (sigpipe == 0) - sigaction (SIGPIPE, &oldaction, -- (struct sigaction *) NULL); -+ (struct sigaction *) NULL); - } - - /* -@@ -276,48 +268,48 @@ openlog( const char *ident, int logstat, - { - int logType = SOCK_DGRAM; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - if (ident != NULL) -- LogTag = ident; -+ LogTag = ident; - LogStat = logstat; - if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) -- LogFacility = logfac; -+ LogFacility = logfac; - if (LogFile == -1) { -- SyslogAddr.sa_family = AF_UNIX; -- (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, -- sizeof(SyslogAddr.sa_data)); --retry: -- if (LogStat & LOG_NDELAY) { -- if ((LogFile = socket(AF_UNIX, logType, 0)) == -1){ -- UNLOCK; -- return; -- } -- /* fcntl(LogFile, F_SETFD, 1); */ -- } -+ SyslogAddr.sa_family = AF_UNIX; -+ (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, -+ sizeof(SyslogAddr.sa_data)); -+ retry: -+ if (LogStat & LOG_NDELAY) { -+ if ((LogFile = socket(AF_UNIX, logType, 0)) == -1){ -+ goto DONE; -+ } -+ /* fcntl(LogFile, F_SETFD, 1); */ -+ } - } - - if (LogFile != -1 && !connected) { -- if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr) - -- sizeof(SyslogAddr.sa_data) + strlen(SyslogAddr.sa_data)) != -1) -- { -- connected = 1; -- } else if (logType == SOCK_DGRAM) { -- logType = SOCK_STREAM; -- if (LogFile != -1) { -- close(LogFile); -- LogFile = -1; -- } -- goto retry; -- } else { -- if (LogFile != -1) { -- close(LogFile); -- LogFile = -1; -- } -- } -+ if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr) - -+ sizeof(SyslogAddr.sa_data) + strlen(SyslogAddr.sa_data)) != -1) -+ { -+ connected = 1; -+ } else if (logType == SOCK_DGRAM) { -+ logType = SOCK_STREAM; -+ if (LogFile != -1) { -+ close(LogFile); -+ LogFile = -1; -+ } -+ goto retry; -+ } else { -+ if (LogFile != -1) { -+ close(LogFile); -+ LogFile = -1; -+ } -+ } - } - -- UNLOCK; -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - /* -@@ -335,10 +327,10 @@ int setlogmask(int pmask) - int omask; - - omask = LogMask; -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (pmask != 0) -- LogMask = pmask; -- UNLOCK; -+ LogMask = pmask; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return (omask); - } - -diff --git a/libc/misc/time/time.c b/libc/misc/time/time.c -index f43bb8a..6165a52 100644 ---- a/libc/misc/time/time.c -+++ b/libc/misc/time/time.c -@@ -143,6 +143,8 @@ - #include <locale.h> - #include <bits/uClibc_uintmaxtostr.h> - -+#include <bits/uClibc_mutex.h> -+ - #ifdef __UCLIBC_HAS_XLOCALE__ - #include <xlocale.h> - #endif -@@ -191,21 +193,7 @@ typedef struct { - char tzname[TZNAME_MAX+1]; - } rule_struct; - --#ifdef __UCLIBC_HAS_THREADS__ -- --#include <pthread.h> -- --extern pthread_mutex_t _time_tzlock; -- --#define TZLOCK __pthread_mutex_lock(&_time_tzlock) --#define TZUNLOCK __pthread_mutex_unlock(&_time_tzlock) -- --#else -- --#define TZLOCK ((void) 0) --#define TZUNLOCK ((void) 0) -- --#endif -+__UCLIBC_MUTEX_EXTERN(_time_tzlock); - - extern rule_struct _time_tzinfo[2]; - -@@ -542,13 +530,13 @@ struct tm *localtime(const time_t *timer - struct tm *localtime_r(register const time_t *__restrict timer, - register struct tm *__restrict result) - { -- TZLOCK; -+ __UCLIBC_MUTEX_LOCK(_time_tzlock); - - tzset(); - - __time_localtime_tzi(timer, result, _time_tzinfo); - -- TZUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(_time_tzlock); - - return result; - } -@@ -1037,7 +1025,7 @@ size_t __XL(strftime)(char *__restrict s - goto LOOP; - } - -- o = spec + 26; /* set to "????" */ -+ o = ((const char *) spec) + 26; /* set to "????" */ - if ((code & MASK_SPEC) == CALC_SPEC) { - - if (*p == 's') { -@@ -1073,17 +1061,15 @@ size_t __XL(strftime)(char *__restrict s - - #ifdef __UCLIBC_HAS_TM_EXTENSIONS__ - --#define RSP_TZUNLOCK ((void) 0) - #define RSP_TZNAME timeptr->tm_zone - #define RSP_GMT_OFFSET (-timeptr->tm_gmtoff) - - #else - --#define RSP_TZUNLOCK TZUNLOCK - #define RSP_TZNAME rsp->tzname - #define RSP_GMT_OFFSET rsp->gmt_offset - -- TZLOCK; -+ __UCLIBC_MUTEX_LOCK(_time_tzlock); - - rsp = _time_tzinfo; - if (timeptr->tm_isdst > 0) { -@@ -1114,15 +1100,17 @@ size_t __XL(strftime)(char *__restrict s - } - #endif - o_count = SIZE_MAX; -- RSP_TZUNLOCK; -+/* RSP_TZUNLOCK; */ -+#ifdef __UCLIBC_HAS_TM_EXTENSIONS__ - goto OUTPUT; -+#endif - } else { /* z */ - *s = '+'; - if ((tzo = -RSP_GMT_OFFSET) < 0) { - tzo = -tzo; - *s = '-'; - } -- RSP_TZUNLOCK; -+/* RSP_TZUNLOCK; */ - ++s; - --count; - -@@ -1131,7 +1119,13 @@ size_t __XL(strftime)(char *__restrict s - - i = 16 + 6; /* 0-fill, width = 4 */ - } -- -+#ifdef __UCLIBC_HAS_TM_EXTENSIONS__ -+#else -+ __UCLIBC_MUTEX_UNLOCK(_time_tzlock); -+ if (*p == 'Z') { -+ goto OUTPUT; -+ } -+#endif - } else { - /* TODO: don't need year for U, W */ - for (i=0 ; i < 3 ; i++) { -@@ -1664,9 +1658,7 @@ int daylight = 0; - long timezone = 0; - char *tzname[2] = { (char *) UTC, (char *) (UTC-1) }; - --#ifdef __UCLIBC_HAS_THREADS__ --pthread_mutex_t _time_tzlock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --#endif -+__UCLIBC_MUTEX_INIT(_time_tzlock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - rule_struct _time_tzinfo[2]; - -@@ -1796,7 +1788,7 @@ void tzset(void) - static char oldval[TZ_BUFLEN]; /* BSS-zero'd. */ - #endif /* __UCLIBC_HAS_TZ_CACHING__ */ - -- TZLOCK; -+ __UCLIBC_MUTEX_LOCK(_time_tzlock); - - e = getenv(TZ); /* TZ env var always takes precedence. */ - -@@ -1962,10 +1954,10 @@ void tzset(void) - daylight = !!_time_tzinfo[1].tzname[0]; - timezone = _time_tzinfo[0].gmt_offset; - --#if defined(__UCLIBC_HAS_TZ_FILE__) -+#if defined(__UCLIBC_HAS_TZ_FILE__) || defined(__UCLIBC_HAS_TZ_CACHING__) - FAST_DONE: - #endif -- TZUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(_time_tzlock); - } - - #endif -@@ -2167,13 +2159,13 @@ time_t _time_mktime(struct tm *timeptr, - { - time_t t; - -- TZLOCK; -+ __UCLIBC_MUTEX_LOCK(_time_tzlock); - - tzset(); - - t = _time_mktime_tzi(timeptr, store_on_success, _time_tzinfo); - -- TZUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(_time_tzlock); - - return t; - } -diff --git a/libc/misc/ttyent/getttyent.c b/libc/misc/ttyent/getttyent.c -index 6e2fbd2..c85c73a 100644 ---- a/libc/misc/ttyent/getttyent.c -+++ b/libc/misc/ttyent/getttyent.c -@@ -35,9 +35,6 @@ - #include <ctype.h> - #include <string.h> - #include <stdlib.h> --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --#endif - - static char zapchar; - static FILE *tf; -@@ -50,8 +47,8 @@ struct ttyent * getttynam(const char *tt - - setttyent(); - while ((t = getttyent())) -- if (!strcmp(tty, t->ty_name)) -- break; -+ if (!strcmp(tty, t->ty_name)) -+ break; - endttyent(); - return (t); - } -@@ -67,27 +64,27 @@ static char * skip(register char *p) - register int c, q; - - for (q = 0, t = p; (c = *p) != '\0'; p++) { -- if (c == '"') { -- q ^= QUOTED; /* obscure, but nice */ -- continue; -- } -- if (q == QUOTED && *p == '\\' && *(p+1) == '"') -- p++; -- *t++ = *p; -- if (q == QUOTED) -- continue; -- if (c == '#') { -- zapchar = c; -- *p = 0; -- break; -- } -- if (c == '\t' || c == ' ' || c == '\n') { -- zapchar = c; -- *p++ = 0; -- while ((c = *p) == '\t' || c == ' ' || c == '\n') -- p++; -- break; -- } -+ if (c == '"') { -+ q ^= QUOTED; /* obscure, but nice */ -+ continue; -+ } -+ if (q == QUOTED && *p == '\\' && *(p+1) == '"') -+ p++; -+ *t++ = *p; -+ if (q == QUOTED) -+ continue; -+ if (c == '#') { -+ zapchar = c; -+ *p = 0; -+ break; -+ } -+ if (c == '\t' || c == ' ' || c == '\n') { -+ zapchar = c; -+ *p++ = 0; -+ while ((c = *p) == '\t' || c == ' ' || c == '\n') -+ p++; -+ break; -+ } - } - *--t = '\0'; - return (p); -@@ -104,46 +101,46 @@ struct ttyent * getttyent(void) - register int c; - register char *p; - static char *line = NULL; -+ struct ttyent *retval = NULL; - - if (!tf && !setttyent()) -- return (NULL); -+ return (NULL); - - if (!line) { -- line = malloc(BUFSIZ); -+ line = malloc(BUFSIZ); - if (!line) - abort(); - } - -- __STDIO_ALWAYS_THREADLOCK(tf); -+ __STDIO_ALWAYS_THREADLOCK(tf); - - for (;;) { -- if (!fgets_unlocked(p = line, BUFSIZ, tf)) { -- __STDIO_ALWAYS_THREADUNLOCK(tf); -- return (NULL); -- } -- /* skip lines that are too big */ -- if (!index(p, '\n')) { -- while ((c = getc_unlocked(tf)) != '\n' && c != EOF) -- ; -- continue; -- } -- while (isspace(*p)) -- ++p; -- if (*p && *p != '#') -- break; -+ if (!fgets_unlocked(p = line, BUFSIZ, tf)) { -+ goto DONE; -+ } -+ /* skip lines that are too big */ -+ if (!index(p, '\n')) { -+ while ((c = getc_unlocked(tf)) != '\n' && c != EOF) -+ ; -+ continue; -+ } -+ while (isspace(*p)) -+ ++p; -+ if (*p && *p != '#') -+ break; - } - - zapchar = 0; - tty.ty_name = p; - p = skip(p); - if (!*(tty.ty_getty = p)) -- tty.ty_getty = tty.ty_type = NULL; -+ tty.ty_getty = tty.ty_type = NULL; - else { -- p = skip(p); -- if (!*(tty.ty_type = p)) -- tty.ty_type = NULL; -- else -- p = skip(p); -+ p = skip(p); -+ if (!*(tty.ty_type = p)) -+ tty.ty_type = NULL; -+ else -+ p = skip(p); - } - tty.ty_status = 0; - tty.ty_window = NULL; -@@ -151,43 +148,45 @@ struct ttyent * getttyent(void) - #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace(p[sizeof(e) - 1]) - #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '=' - for (; *p; p = skip(p)) { -- if (scmp(_TTYS_OFF)) -- tty.ty_status &= ~TTY_ON; -- else if (scmp(_TTYS_ON)) -- tty.ty_status |= TTY_ON; -- else if (scmp(_TTYS_SECURE)) -- tty.ty_status |= TTY_SECURE; -- else if (vcmp(_TTYS_WINDOW)) -- tty.ty_window = value(p); -- else -- break; -+ if (scmp(_TTYS_OFF)) -+ tty.ty_status &= ~TTY_ON; -+ else if (scmp(_TTYS_ON)) -+ tty.ty_status |= TTY_ON; -+ else if (scmp(_TTYS_SECURE)) -+ tty.ty_status |= TTY_SECURE; -+ else if (vcmp(_TTYS_WINDOW)) -+ tty.ty_window = value(p); -+ else -+ break; - } -- /* We can release the lock only here since `zapchar' is global. */ -- __STDIO_ALWAYS_THREADUNLOCK(tf); - - if (zapchar == '#' || *p == '#') -- while ((c = *++p) == ' ' || c == '\t') -- ; -+ while ((c = *++p) == ' ' || c == '\t') -+ ; - tty.ty_comment = p; - if (*p == 0) -- tty.ty_comment = 0; -+ tty.ty_comment = 0; - if ((p = index(p, '\n'))) -- *p = '\0'; -- return (&tty); -+ *p = '\0'; -+ retval = &tty; -+ -+ DONE: -+ __STDIO_ALWAYS_THREADUNLOCK(tf); -+ return retval; - } - - int setttyent(void) - { - - if (tf) { -- rewind(tf); -- return (1); -+ rewind(tf); -+ return (1); - } else if ((tf = fopen(_PATH_TTYS, "r"))) { -- /* We do the locking ourselves. */ -+ /* We do the locking ourselves. */ - #ifdef __UCLIBC_HAS_THREADS__ -- __fsetlocking (tf, FSETLOCKING_BYCALLER); -+ __fsetlocking (tf, FSETLOCKING_BYCALLER); - #endif -- return (1); -+ return (1); - } - return (0); - } -@@ -197,9 +196,9 @@ int endttyent(void) - int rval; - - if (tf) { -- rval = !(fclose(tf) == EOF); -- tf = NULL; -- return (rval); -+ rval = !(fclose(tf) == EOF); -+ tf = NULL; -+ return (rval); - } - return (1); - } -diff --git a/libc/misc/utmp/utent.c b/libc/misc/utmp/utent.c -index c1d8d6f..0fc6df4 100644 ---- a/libc/misc/utmp/utent.c -+++ b/libc/misc/utmp/utent.c -@@ -20,19 +20,9 @@ - #include <string.h> - #include <utmp.h> - -+#include <bits/uClibc_mutex.h> - -- --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t utmplock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&utmplock) --# define UNLOCK __pthread_mutex_unlock(&utmplock) --#else --# define LOCK --# define UNLOCK --#endif -- -- -+__UCLIBC_MUTEX_STATIC(utmplock, PTHREAD_MUTEX_INITIALIZER); - - /* Some global crap */ - static int static_fd = -1; -@@ -46,19 +36,19 @@ static struct utmp *__getutent(int utmp_ - - { - if (utmp_fd == -1) { -- setutent(); -+ setutent(); - } - if (utmp_fd == -1) { -- return NULL; -+ return NULL; - } - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(utmplock); - if (read(utmp_fd, (char *) &static_utmp, sizeof(struct utmp)) != sizeof(struct utmp)) -- { -- return NULL; -- } -+ { -+ return NULL; -+ } - -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(utmplock); - return &static_utmp; - } - -@@ -66,39 +56,39 @@ void setutent(void) - { - int ret; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(utmplock); - if (static_fd == -1) { -- if ((static_fd = open(static_ut_name, O_RDWR)) < 0) { -- if ((static_fd = open(static_ut_name, O_RDONLY)) < 0) { -- goto bummer; -- } -- } -- /* Make sure the file will be closed on exec() */ -- ret = fcntl(static_fd, F_GETFD, 0); -- if (ret >= 0) { -- ret = fcntl(static_fd, F_GETFD, 0); -- } -- if (ret < 0) { --bummer: -- UNLOCK; -- static_fd = -1; -- close(static_fd); -- return; -- } -+ if ((static_fd = open(static_ut_name, O_RDWR)) < 0) { -+ if ((static_fd = open(static_ut_name, O_RDONLY)) < 0) { -+ goto bummer; -+ } -+ } -+ /* Make sure the file will be closed on exec() */ -+ ret = fcntl(static_fd, F_GETFD, 0); -+ if (ret >= 0) { -+ ret = fcntl(static_fd, F_GETFD, 0); -+ } -+ if (ret < 0) { -+ bummer: -+ close(static_fd); -+ static_fd = -1; -+ goto DONE; -+ } - } - lseek(static_fd, 0, SEEK_SET); -- UNLOCK; -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(utmplock); - return; - } - - void endutent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(utmplock); - if (static_fd != -1) { -- close(static_fd); -+ close(static_fd); - } - static_fd = -1; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(utmplock); - } - - /* Locking is done in __getutent */ -@@ -113,22 +103,22 @@ struct utmp *getutid (const struct utmp - struct utmp *lutmp; - - while ((lutmp = __getutent(static_fd)) != NULL) { -- if ( (utmp_entry->ut_type == RUN_LVL || -- utmp_entry->ut_type == BOOT_TIME || -- utmp_entry->ut_type == NEW_TIME || -- utmp_entry->ut_type == OLD_TIME) && -- lutmp->ut_type == utmp_entry->ut_type) -- { -- return lutmp; -- } -- if ( (utmp_entry->ut_type == INIT_PROCESS || -- utmp_entry->ut_type == DEAD_PROCESS || -- utmp_entry->ut_type == LOGIN_PROCESS || -- utmp_entry->ut_type == USER_PROCESS) && -- !strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id))) -- { -- return lutmp; -- } -+ if ( (utmp_entry->ut_type == RUN_LVL || -+ utmp_entry->ut_type == BOOT_TIME || -+ utmp_entry->ut_type == NEW_TIME || -+ utmp_entry->ut_type == OLD_TIME) && -+ lutmp->ut_type == utmp_entry->ut_type) -+ { -+ return lutmp; -+ } -+ if ( (utmp_entry->ut_type == INIT_PROCESS || -+ utmp_entry->ut_type == DEAD_PROCESS || -+ utmp_entry->ut_type == LOGIN_PROCESS || -+ utmp_entry->ut_type == USER_PROCESS) && -+ !strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id))) -+ { -+ return lutmp; -+ } - } - - return NULL; -@@ -140,11 +130,11 @@ struct utmp *getutline(const struct utmp - struct utmp *lutmp; - - while ((lutmp = __getutent(static_fd)) != NULL) { -- if ((lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) && -- !strcmp(lutmp->ut_line, utmp_entry->ut_line)) -- { -- return lutmp; -- } -+ if ((lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) && -+ !strcmp(lutmp->ut_line, utmp_entry->ut_line)) -+ { -+ return lutmp; -+ } - } - - return NULL; -@@ -152,42 +142,42 @@ struct utmp *getutline(const struct utmp - - struct utmp *pututline (const struct utmp *utmp_entry) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(utmplock); - /* Ignore the return value. That way, if they've already positioned - the file pointer where they want it, everything will work out. */ - lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR); - - if (getutid(utmp_entry) != NULL) { -- lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR); -- if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp)) -- return NULL; -+ lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR); -+ if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp)) -+ return NULL; - } else { -- lseek(static_fd, (off_t) 0, SEEK_END); -- if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp)) -- return NULL; -+ lseek(static_fd, (off_t) 0, SEEK_END); -+ if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp)) -+ return NULL; - } - -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(utmplock); - return (struct utmp *)utmp_entry; - } - - int utmpname (const char *new_ut_name) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(utmplock); - if (new_ut_name != NULL) { -- if (static_ut_name != default_file_name) -- free((char *)static_ut_name); -- static_ut_name = strdup(new_ut_name); -- if (static_ut_name == NULL) { -- /* We should probably whine about out-of-memory -- * errors here... Instead just reset to the default */ -- static_ut_name = default_file_name; -- } -+ if (static_ut_name != default_file_name) -+ free((char *)static_ut_name); -+ static_ut_name = strdup(new_ut_name); -+ if (static_ut_name == NULL) { -+ /* We should probably whine about out-of-memory -+ * errors here... Instead just reset to the default */ -+ static_ut_name = default_file_name; -+ } - } - - if (static_fd != -1) -- close(static_fd); -- UNLOCK; -+ close(static_fd); -+ __UCLIBC_MUTEX_UNLOCK(utmplock); - return 0; - } - -diff --git a/libc/misc/wchar/wstdio.c b/libc/misc/wchar/wstdio.c -index b49494f..408c57a 100644 ---- a/libc/misc/wchar/wstdio.c -+++ b/libc/misc/wchar/wstdio.c -@@ -82,9 +82,6 @@ strong_alias(NAME,NAME##_unlocked) \ - void NAME PARAMS - #endif - --#define __STDIO_THREADLOCK_OPENLIST --#define __STDIO_THREADUNLOCK_OPENLIST -- - #else /* __UCLIBC_HAS_THREADS__ */ - - #include <pthread.h> -@@ -112,15 +109,6 @@ void NAME PARAMS \ - } \ - void NAME##_unlocked PARAMS - --#define __STDIO_THREADLOCK_OPENLIST \ -- __pthread_mutex_lock(&_stdio_openlist_lock) -- --#define __STDIO_THREADUNLOCK_OPENLIST \ -- __pthread_mutex_unlock(&_stdio_openlist_lock) -- --#define __STDIO_THREADTRYLOCK_OPENLIST \ -- __pthread_mutex_trylock(&_stdio_openlist_lock) -- - #endif /* __UCLIBC_HAS_THREADS__ */ - - #ifndef __STDIO_BUFFERS -diff --git a/libc/pwd_grp/lckpwdf.c b/libc/pwd_grp/lckpwdf.c -index 6b9c251..063fed4 100644 ---- a/libc/pwd_grp/lckpwdf.c -+++ b/libc/pwd_grp/lckpwdf.c -@@ -27,15 +27,9 @@ - #include <sys/file.h> - #include <paths.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -+#include <bits/uClibc_mutex.h> -+ -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - /* How long to wait for getting the lock before returning with an - error. */ -@@ -57,18 +51,18 @@ int lckpwdf (void) - struct sigaction new_act; /* New signal action. */ - struct flock fl; /* Information struct for locking. */ - int result; -+ int rv = -1; - - if (lock_fd != -1) - /* Still locked by own process. */ - return -1; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - lock_fd = open (_PATH_PASSWD, O_WRONLY); - if (lock_fd == -1) { - /* Cannot create lock file. */ -- UNLOCK; -- return -1; -+ goto DONE; - } - - /* Make sure file gets correctly closed when process finished. */ -@@ -77,16 +71,14 @@ int lckpwdf (void) - /* Cannot get file flags. */ - close(lock_fd); - lock_fd = -1; -- UNLOCK; -- return -1; -+ goto DONE; - } - flags |= FD_CLOEXEC; /* Close on exit. */ - if (fcntl (lock_fd, F_SETFD, flags) < 0) { - /* Cannot set new flags. */ - close(lock_fd); - lock_fd = -1; -- UNLOCK; -- return -1; -+ goto DONE; - } - - /* Now we have to get exclusive write access. Since multiple -@@ -107,8 +99,7 @@ int lckpwdf (void) - /* Cannot install signal handler. */ - close(lock_fd); - lock_fd = -1; -- UNLOCK; -- return -1; -+ goto DONE; - } - - /* Now make sure the alarm signal is not blocked. */ -@@ -118,8 +109,7 @@ int lckpwdf (void) - sigaction (SIGALRM, &saved_act, NULL); - close(lock_fd); - lock_fd = -1; -- UNLOCK; -- return -1; -+ goto DONE; - } - - /* Start timer. If we cannot get the lock in the specified time we -@@ -146,12 +136,14 @@ int lckpwdf (void) - if (result < 0) { - close(lock_fd); - lock_fd = -1; -- UNLOCK; -- return -1; -+ goto DONE; - } - -- UNLOCK; -- return 0; -+ rv = 0; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); -+ return rv; - } - - -@@ -164,11 +156,11 @@ int ulckpwdf (void) - result = -1; - } - else { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - result = close (lock_fd); - /* Mark descriptor as unused. */ - lock_fd = -1; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - return result; -diff --git a/libc/pwd_grp/pwd_grp.c b/libc/pwd_grp/pwd_grp.c -index 91c0d83..a302c7c 100644 ---- a/libc/pwd_grp/pwd_grp.c -+++ b/libc/pwd_grp/pwd_grp.c -@@ -42,9 +42,8 @@ - #include <pwd.h> - #include <grp.h> - #include <shadow.h> --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --#endif -+ -+#include <bits/uClibc_mutex.h> - - /**********************************************************************/ - /* Sizes for staticly allocated buffers. */ -@@ -445,34 +444,27 @@ int getpw(uid_t uid, char *buf) - /**********************************************************************/ - #ifdef L_getpwent_r - --#ifdef __UCLIBC_HAS_THREADS__ --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK ((void) 0) --# define UNLOCK ((void) 0) --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - static FILE *pwf /*= NULL*/; - - void setpwent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (pwf) { - rewind(pwf); - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - void endpwent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (pwf) { - fclose(pwf); - pwf = NULL; - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - -@@ -482,7 +474,7 @@ int getpwent_r(struct passwd *__restrict - { - int rv; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - *result = NULL; /* In case of error... */ - -@@ -500,7 +492,7 @@ int getpwent_r(struct passwd *__restrict - } - - ERR: -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - return rv; - } -@@ -509,34 +501,27 @@ int getpwent_r(struct passwd *__restrict - /**********************************************************************/ - #ifdef L_getgrent_r - --#ifdef __UCLIBC_HAS_THREADS__ --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK ((void) 0) --# define UNLOCK ((void) 0) --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - static FILE *grf /*= NULL*/; - - void setgrent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (grf) { - rewind(grf); - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - void endgrent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (grf) { - fclose(grf); - grf = NULL; - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - int getgrent_r(struct group *__restrict resultbuf, -@@ -545,7 +530,7 @@ int getgrent_r(struct group *__restrict - { - int rv; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - *result = NULL; /* In case of error... */ - -@@ -563,7 +548,7 @@ int getgrent_r(struct group *__restrict - } - - ERR: -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - return rv; - } -@@ -572,34 +557,27 @@ int getgrent_r(struct group *__restrict - /**********************************************************************/ - #ifdef L_getspent_r - --#ifdef __UCLIBC_HAS_THREADS__ --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK ((void) 0) --# define UNLOCK ((void) 0) --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - static FILE *spf /*= NULL*/; - - void setspent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (spf) { - rewind(spf); - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - void endspent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (spf) { - fclose(spf); - spf = NULL; - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - int getspent_r(struct spwd *resultbuf, char *buffer, -@@ -607,7 +585,7 @@ int getspent_r(struct spwd *resultbuf, c - { - int rv; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - *result = NULL; /* In case of error... */ - -@@ -625,7 +603,7 @@ int getspent_r(struct spwd *resultbuf, c - } - - ERR: -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - return rv; - } -diff --git a/libc/stdio/_READ.c b/libc/stdio/_READ.c -index 7d3c38c..fe1bc91 100644 ---- a/libc/stdio/_READ.c -+++ b/libc/stdio/_READ.c -@@ -41,7 +41,7 @@ size_t __stdio_READ(register FILE *strea - #warning EINTR? - #endif - /* RETRY: */ -- if ((rv = __READ(stream, buf, bufsize)) <= 0) { -+ if ((rv = __READ(stream, (char *) buf, bufsize)) <= 0) { - if (rv == 0) { - __STDIO_STREAM_SET_EOF(stream); - } else { -diff --git a/libc/stdio/_WRITE.c b/libc/stdio/_WRITE.c -index d300d39..4131eb7 100644 ---- a/libc/stdio/_WRITE.c -+++ b/libc/stdio/_WRITE.c -@@ -47,7 +47,7 @@ size_t __stdio_WRITE(register FILE *stre - return bufsize; - } - stodo = (todo <= SSIZE_MAX) ? todo : SSIZE_MAX; -- if ((rv = __WRITE(stream, buf, stodo)) >= 0) { -+ if ((rv = __WRITE(stream, (char *) buf, stodo)) >= 0) { - #ifdef __UCLIBC_MJN3_ONLY__ - #warning TODO: Make custom stream write return check optional. - #endif -diff --git a/libc/stdio/_fopen.c b/libc/stdio/_fopen.c -index f7f5bb6..4984f11 100644 ---- a/libc/stdio/_fopen.c -+++ b/libc/stdio/_fopen.c -@@ -194,10 +194,23 @@ FILE *_stdio_fopen(intptr_t fname_or_mod - #endif - - #ifdef __STDIO_HAS_OPENLIST -- __STDIO_THREADLOCK_OPENLIST; -- stream->__nextopen = _stdio_openlist; /* New files are inserted at */ -- _stdio_openlist = stream; /* the head of the list. */ -- __STDIO_THREADUNLOCK_OPENLIST; -+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS) -+ if (!(stream->__modeflags & __FLAG_FREEFILE)) -+ { -+ /* An freopen call so the file was never removed from the list. */ -+ } -+ else -+#endif -+ { -+ /* We have to lock the del mutex in case another thread wants to fclose() -+ * the last file. */ -+ __STDIO_THREADLOCK_OPENLIST_DEL; -+ __STDIO_THREADLOCK_OPENLIST_ADD; -+ stream->__nextopen = _stdio_openlist; /* New files are inserted at */ -+ _stdio_openlist = stream; /* the head of the list. */ -+ __STDIO_THREADUNLOCK_OPENLIST_ADD; -+ __STDIO_THREADUNLOCK_OPENLIST_DEL; -+ } - #endif - - __STDIO_STREAM_VALIDATE(stream); -diff --git a/libc/stdio/_stdio.c b/libc/stdio/_stdio.c -index 4aae3c4..9cfe02c 100644 ---- a/libc/stdio/_stdio.c -+++ b/libc/stdio/_stdio.c -@@ -151,8 +151,12 @@ FILE *__stdout = _stdio_streams + 1; /* - FILE *_stdio_openlist = _stdio_streams; - - # ifdef __UCLIBC_HAS_THREADS__ --pthread_mutex_t _stdio_openlist_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --int _stdio_openlist_delflag = 0; -+__UCLIBC_MUTEX_INIT(_stdio_openlist_add_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); -+#ifdef __STDIO_BUFFERS -+__UCLIBC_MUTEX_INIT(_stdio_openlist_del_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); -+volatile int _stdio_openlist_use_count = 0; -+int _stdio_openlist_del_count = 0; -+#endif - # endif - - #endif -@@ -162,10 +166,10 @@ int _stdio_openlist_delflag = 0; - /* 2 if threading not initialized and 0 otherwise; */ - int _stdio_user_locking = 2; - --void __stdio_init_mutex(pthread_mutex_t *m) -+void __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m) - { -- static const pthread_mutex_t __stdio_mutex_initializer -- = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -+ const __UCLIBC_MUTEX_STATIC(__stdio_mutex_initializer, -+ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - memcpy(m, &__stdio_mutex_initializer, sizeof(__stdio_mutex_initializer)); - } -@@ -184,7 +188,11 @@ void _stdio_term(void) - * locked, then I suppose there is a chance that a pointer in the - * chain might be corrupt due to a partial store. - */ -- __stdio_init_mutex(&_stdio_openlist_lock); -+ __stdio_init_mutex(&_stdio_openlist_add_lock); -+#warning check -+#ifdef __STDIO_BUFFERS -+ __stdio_init_mutex(&_stdio_openlist_del_lock); -+#endif - - /* Next we need to worry about the streams themselves. If a stream - * is currently locked, then it may be in an invalid state. So we -@@ -192,7 +200,7 @@ void _stdio_term(void) - * Then we reinitialize the locks. - */ - for (ptr = _stdio_openlist ; ptr ; ptr = ptr->__nextopen ) { -- if (__STDIO_ALWAYS_THREADTRYLOCK(ptr)) { -+ if (__STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(ptr)) { - /* The stream is already locked, so we don't want to touch it. - * However, if we have custom streams, we can't just close it - * or leave it locked since a custom stream may be stacked -@@ -258,10 +266,6 @@ void _stdio_init(void) - #error Assumption violated about __MASK_READING and __FLAG_UNGOT - #endif - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --#endif -- - #ifndef NDEBUG - - void _stdio_validate_FILE(const FILE *stream) -diff --git a/libc/stdio/_stdio.h b/libc/stdio/_stdio.h -index e3c2c58..decf57d 100644 ---- a/libc/stdio/_stdio.h -+++ b/libc/stdio/_stdio.h -@@ -22,23 +22,57 @@ - #include <wchar.h> - #endif - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> -+#include <bits/uClibc_mutex.h> - --#define __STDIO_THREADLOCK_OPENLIST \ -- __pthread_mutex_lock(&_stdio_openlist_lock) -+#define __STDIO_THREADLOCK_OPENLIST_ADD \ -+ __UCLIBC_MUTEX_LOCK(_stdio_openlist_add_lock) - --#define __STDIO_THREADUNLOCK_OPENLIST \ -- __pthread_mutex_unlock(&_stdio_openlist_lock) -+#define __STDIO_THREADUNLOCK_OPENLIST_ADD \ -+ __UCLIBC_MUTEX_UNLOCK(_stdio_openlist_add_lock) - --#define __STDIO_THREADTRYLOCK_OPENLIST \ -- __pthread_mutex_trylock(&_stdio_openlist_lock) -+#ifdef __STDIO_BUFFERS - --#else -+#define __STDIO_THREADLOCK_OPENLIST_DEL \ -+ __UCLIBC_MUTEX_LOCK(_stdio_openlist_del_lock) -+ -+#define __STDIO_THREADUNLOCK_OPENLIST_DEL \ -+ __UCLIBC_MUTEX_UNLOCK(_stdio_openlist_del_lock) - --#define __STDIO_THREADLOCK_OPENLIST ((void)0) --#define __STDIO_THREADUNLOCK_OPENLIST ((void)0) -+#define __STDIO_OPENLIST_INC_USE \ -+do { \ -+ __STDIO_THREADLOCK_OPENLIST_DEL; \ -+ ++_stdio_openlist_use_count; \ -+ __STDIO_THREADUNLOCK_OPENLIST_DEL; \ -+} while (0) -+ -+extern void _stdio_openlist_dec_use(void); -+ -+#define __STDIO_OPENLIST_DEC_USE \ -+ _stdio_openlist_dec_use() -+ -+#define __STDIO_OPENLIST_INC_DEL_CNT \ -+do { \ -+ __STDIO_THREADLOCK_OPENLIST_DEL; \ -+ ++_stdio_openlist_del_count; \ -+ __STDIO_THREADUNLOCK_OPENLIST_DEL; \ -+} while (0) -+ -+#define __STDIO_OPENLIST_DEC_DEL_CNT \ -+do { \ -+ __STDIO_THREADLOCK_OPENLIST_DEL; \ -+ --_stdio_openlist_del_count; \ -+ __STDIO_THREADUNLOCK_OPENLIST_DEL; \ -+} while (0) -+ -+#endif /* __STDIO_BUFFERS */ - -+#ifndef __STDIO_THREADLOCK_OPENLIST_DEL -+#define __STDIO_THREADLOCK_OPENLIST_DEL ((void)0) -+#define __STDIO_THREADUNLOCK_OPENLIST_DEL ((void)0) -+#define __STDIO_OPENLIST_INC_USE ((void)0) -+#define __STDIO_OPENLIST_DEC_USE ((void)0) -+#define __STDIO_OPENLIST_INC_DEL_CNT ((void)0) -+#define __STDIO_OPENLIST_DEC_DEL_CNT ((void)0) - #endif - - #define __UNDEFINED_OR_NONPORTABLE ((void)0) -diff --git a/libc/stdio/fclose.c b/libc/stdio/fclose.c -index 4df2e42..dfababc 100644 ---- a/libc/stdio/fclose.c -+++ b/libc/stdio/fclose.c -@@ -12,30 +12,34 @@ int fclose(register FILE *stream) - int rv = 0; - __STDIO_AUTO_THREADLOCK_VAR; - -- /* First, remove the file from the open file list. */ --#ifdef __STDIO_HAS_OPENLIST -- { -- register FILE *ptr; -- -- __STDIO_THREADLOCK_OPENLIST; -- if ((ptr = _stdio_openlist) == stream) { -- _stdio_openlist = stream->__nextopen; -- } else { -- while (ptr) { -- if (ptr->__nextopen == stream) { -- ptr->__nextopen = stream->__nextopen; -- break; -- } -- ptr = ptr->__nextopen; -- } -- } -- __STDIO_THREADUNLOCK_OPENLIST; -- -- if (!ptr) { /* Did not find stream in the open file list! */ -- return EOF; -- } -- } --#endif -+#warning dead code... but may want to simply check and not remove -+/* #ifdef __STDIO_HAS_OPENLIST */ -+/* #if !defined(__UCLIBC_HAS_THREADS__) || !defined(__STDIO_BUFFERS) */ -+/* /\* First, remove the file from the open file list. *\/ */ -+/* { */ -+/* register FILE *ptr; */ -+ -+/* __STDIO_THREADLOCK_OPENLIST; */ -+/* if ((ptr = _stdio_openlist) == stream) { */ -+/* #warning does a mod!!! */ -+/* _stdio_openlist = stream->__nextopen; */ -+/* } else { */ -+/* while (ptr) { */ -+/* if (ptr->__nextopen == stream) { */ -+/* ptr->__nextopen = stream->__nextopen; */ -+/* break; */ -+/* } */ -+/* ptr = ptr->__nextopen; */ -+/* } */ -+/* } */ -+/* __STDIO_THREADUNLOCK_OPENLIST; */ -+ -+/* if (!ptr) { /\* Did not find stream in the open file list! *\/ */ -+/* return EOF; */ -+/* } */ -+/* } */ -+/* #endif */ -+/* #endif */ - - __STDIO_AUTO_THREADLOCK(stream); - -@@ -80,7 +84,15 @@ int fclose(register FILE *stream) - __STDIO_AUTO_THREADUNLOCK(stream); - - __STDIO_STREAM_FREE_BUFFER(stream); -+#warning... inefficient - locks and unlocks twice and walks whole list -+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS) -+ /* inefficient - locks/unlocks twice and walks whole list */ -+ __STDIO_OPENLIST_INC_USE; -+ __STDIO_OPENLIST_INC_DEL_CNT; -+ __STDIO_OPENLIST_DEC_USE; /* This with free the file if necessary. */ -+#else - __STDIO_STREAM_FREE_FILE(stream); -+#endif - - return rv; - } -diff --git a/libc/stdio/fcloseall.c b/libc/stdio/fcloseall.c -index dbb6000..f62281a 100644 ---- a/libc/stdio/fcloseall.c -+++ b/libc/stdio/fcloseall.c -@@ -19,14 +19,34 @@ int fcloseall (void) - #ifdef __STDIO_HAS_OPENLIST - - int retval = 0; -+ FILE *f; - -- __STDIO_THREADLOCK_OPENLIST; -- while (_stdio_openlist) { -- if (fclose(_stdio_openlist)) { -+#warning remove dead code -+/* __STDIO_THREADLOCK_OPENLIST; */ -+/* while (_stdio_openlist) { */ -+/* if (fclose(_stdio_openlist)) { */ -+/* retval = EOF; */ -+/* } */ -+/* } */ -+/* __STDIO_THREADUNLOCK_OPENLIST; */ -+ -+ __STDIO_OPENLIST_INC_USE; -+ -+#warning should probably have a get_head() operation -+ __STDIO_THREADLOCK_OPENLIST_ADD; -+ f = _stdio_openlist; -+ __STDIO_THREADUNLOCK_OPENLIST_ADD; -+ -+ while (f) { -+#warning should probably have a get_next() operation -+ FILE *n = f->__nextopen; -+ if (fclose(f)) { - retval = EOF; - } -+ f = n; - } -- __STDIO_THREADUNLOCK_OPENLIST; -+ -+ __STDIO_OPENLIST_DEC_USE; - - return retval; - -diff --git a/libc/stdio/fflush.c b/libc/stdio/fflush.c -index 6baa0ec..66b65cd 100644 ---- a/libc/stdio/fflush.c -+++ b/libc/stdio/fflush.c -@@ -20,23 +20,50 @@ weak_alias(__fflush_unlocked,fflush_unlo - weak_alias(__fflush_unlocked,fflush); - #endif - --#ifdef __UCLIBC_HAS_THREADS__ - /* Even if the stream is set to user-locking, we still need to lock - * when all (lbf) writing streams are flushed. */ --#define MY_STDIO_THREADLOCK(STREAM) \ -- if (_stdio_user_locking != 2) { \ -- __STDIO_ALWAYS_THREADLOCK(STREAM); \ -- } - --#define MY_STDIO_THREADUNLOCK(STREAM) \ -- if (_stdio_user_locking != 2) { \ -- __STDIO_ALWAYS_THREADUNLOCK(STREAM); \ -- } --#else --#define MY_STDIO_THREADLOCK(STREAM) ((void)0) --#define MY_STDIO_THREADUNLOCK(STREAM) ((void)0) --#endif -+#define __MY_STDIO_THREADLOCK(__stream) \ -+ __UCLIBC_MUTEX_CONDITIONAL_LOCK((__stream)->__lock, \ -+ (_stdio_user_locking != 2)) -+ -+#define __MY_STDIO_THREADUNLOCK(__stream) \ -+ __UCLIBC_MUTEX_CONDITIONAL_UNLOCK((__stream)->__lock, \ -+ (_stdio_user_locking != 2)) - -+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS) -+void _stdio_openlist_dec_use(void) -+{ -+ __STDIO_THREADLOCK_OPENLIST_DEL; -+ if ((_stdio_openlist_use_count == 1) && (_stdio_openlist_del_count > 0)) { -+ FILE *p = NULL; -+ FILE *n; -+ FILE *stream; -+ -+ __STDIO_THREADLOCK_OPENLIST_ADD; -+ for (stream = _stdio_openlist; stream; stream = n) { -+#warning walk the list and clear out all fclosed()d files -+ n = stream->__nextopen; -+#warning fix for nonatomic -+ if ((stream->__modeflags & (__FLAG_READONLY|__FLAG_WRITEONLY)) -+ == (__FLAG_READONLY|__FLAG_WRITEONLY) -+ ) { /* The file was closed so remove from the list. */ -+ if (!p) { -+ _stdio_openlist = n; -+ } else { -+ p->__nextopen = n; -+ } -+ __STDIO_STREAM_FREE_FILE(stream); -+ } else { -+ p = stream; -+ } -+ } -+ __STDIO_THREADUNLOCK_OPENLIST_DEL; -+ } -+ --_stdio_openlist_use_count; -+ __STDIO_THREADUNLOCK_OPENLIST_DEL; -+} -+#endif - - int __fflush_unlocked(register FILE *stream) - { -@@ -60,23 +87,39 @@ int __fflush_unlocked(register FILE *str - } - - if (!stream) { /* Flush all (lbf) writing streams. */ -- __STDIO_THREADLOCK_OPENLIST; -- for (stream = _stdio_openlist; stream ; stream = stream->__nextopen) { -- MY_STDIO_THREADLOCK(stream); -- if (!(((stream->__modeflags | bufmask) -- ^ (__FLAG_WRITING|__FLAG_LBF) -- ) & (__FLAG_WRITING|__MASK_BUFMODE)) -- ) { -- if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) { -- __STDIO_STREAM_DISABLE_PUTC(stream); -- __STDIO_STREAM_CLEAR_WRITING(stream); -- } else { -- retval = EOF; -+ -+ __STDIO_OPENLIST_INC_USE; -+ -+ __STDIO_THREADLOCK_OPENLIST_ADD; -+ stream = _stdio_openlist; -+ __STDIO_THREADUNLOCK_OPENLIST_ADD; -+ -+ while(stream) { -+ /* We only care about currently writing streams and do not want to -+ * block trying to obtain mutexes on non-writing streams. */ -+#warning fix for nonatomic -+#warning unnecessary check if no threads -+ if (__STDIO_STREAM_IS_WRITING(stream)) { /* ONLY IF ATOMIC!!! */ -+ __MY_STDIO_THREADLOCK(stream); -+ /* Need to check again once we have the lock. */ -+ if (!(((stream->__modeflags | bufmask) -+ ^ (__FLAG_WRITING|__FLAG_LBF) -+ ) & (__FLAG_WRITING|__MASK_BUFMODE)) -+ ) { -+ if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) { -+ __STDIO_STREAM_DISABLE_PUTC(stream); -+ __STDIO_STREAM_CLEAR_WRITING(stream); -+ } else { -+ retval = EOF; -+ } - } -+ __MY_STDIO_THREADUNLOCK(stream); - } -- MY_STDIO_THREADUNLOCK(stream); -+ stream = stream->__nextopen; - } -- __STDIO_THREADUNLOCK_OPENLIST; -+ -+ __STDIO_OPENLIST_DEC_USE; -+ - } else if (__STDIO_STREAM_IS_WRITING(stream)) { - if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) { - __STDIO_STREAM_DISABLE_PUTC(stream); -diff --git a/libc/stdio/flockfile.c b/libc/stdio/flockfile.c -index 0dcc7c2..3fad711 100644 ---- a/libc/stdio/flockfile.c -+++ b/libc/stdio/flockfile.c -@@ -11,6 +11,6 @@ void flockfile(FILE *stream) - { - __STDIO_STREAM_VALIDATE(stream); - -- __STDIO_ALWAYS_THREADLOCK(stream); -+ __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(stream); - } - -diff --git a/libc/stdio/freopen.c b/libc/stdio/freopen.c -index 0eccaac..36b8488 100644 ---- a/libc/stdio/freopen.c -+++ b/libc/stdio/freopen.c -@@ -42,6 +42,8 @@ FILE *freopen(const char * __restrict fi - - __STDIO_STREAM_VALIDATE(stream); - -+ __STDIO_OPENLIST_INC_USE; /* Do not remove the file from the list. */ -+ - /* First, flush and close, but don't deallocate, the stream. */ - /* This also removes the stream for the open file list. */ - dynmode = (stream->__modeflags & (__FLAG_FREEBUF|__FLAG_FREEFILE)); -@@ -57,9 +59,16 @@ FILE *freopen(const char * __restrict fi - - fp = _stdio_fopen(((intptr_t) filename), mode, stream, FILEDES_ARG); - -+#warning if fp is NULL, then we do not free file (but beware stdin,stdout,stderr) -+ if (fp) { -+ __STDIO_OPENLIST_DEC_DEL_CNT; -+ } -+ - /* Reset the allocation flags. */ - stream->__modeflags |= dynmode; - -+ __STDIO_OPENLIST_DEC_USE; -+ - __STDIO_AUTO_THREADUNLOCK(stream); - - return fp; -diff --git a/libc/stdio/ftello.c b/libc/stdio/ftello.c -index 7092f34..69385ce 100644 ---- a/libc/stdio/ftello.c -+++ b/libc/stdio/ftello.c -@@ -48,7 +48,10 @@ OFFSET_TYPE FTELL(register FILE *stream) - - __STDIO_STREAM_VALIDATE(stream); - -- if ((__SEEK(stream, &pos, SEEK_CUR) < 0) -+ if ((__SEEK(stream, &pos, -+ ((__STDIO_STREAM_IS_WRITING(stream) -+ && (stream->__modeflags & __FLAG_APPEND)) -+ ? SEEK_END : SEEK_CUR)) < 0) - || (__stdio_adjust_position(stream, &pos) < 0)) { - pos = -1; - } -diff --git a/libc/stdio/ftrylockfile.c b/libc/stdio/ftrylockfile.c -index d85b8ff..0d2e156 100644 ---- a/libc/stdio/ftrylockfile.c -+++ b/libc/stdio/ftrylockfile.c -@@ -15,5 +15,5 @@ int ftrylockfile(FILE *stream) - { - __STDIO_STREAM_VALIDATE(stream); - -- return __STDIO_ALWAYS_THREADTRYLOCK(stream); -+ return __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(stream); - } -diff --git a/libc/stdio/funlockfile.c b/libc/stdio/funlockfile.c -index 048c093..2ddf097 100644 ---- a/libc/stdio/funlockfile.c -+++ b/libc/stdio/funlockfile.c -@@ -11,5 +11,5 @@ void funlockfile(FILE *stream) - { - __STDIO_STREAM_VALIDATE(stream); - -- __STDIO_ALWAYS_THREADUNLOCK(stream); -+ __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(stream); - } -diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c -index c7887ad..ab8d296 100644 ---- a/libc/stdio/popen.c -+++ b/libc/stdio/popen.c -@@ -14,6 +14,7 @@ - * Fix failure exit code for failed execve(). - */ - -+#warning hmm... susv3 says "Pipe streams are byte-oriented." - - #include <stdio.h> - #include <stdlib.h> -@@ -21,6 +22,8 @@ - #include <unistd.h> - #include <sys/wait.h> - -+#include <bits/uClibc_mutex.h> -+ - /* uClinux-2.0 has vfork, but Linux 2.0 doesn't */ - #include <sys/syscall.h> - #if ! defined __NR_vfork -@@ -29,19 +32,11 @@ - # define VFORK_UNLOCK ((void) 0) - #endif - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK ((void) 0) --# define UNLOCK ((void) 0) --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - #ifndef VFORK_LOCK --# define VFORK_LOCK LOCK --# define VFORK_UNLOCK UNLOCK -+# define VFORK_LOCK __UCLIBC_MUTEX_LOCK(mylock) -+# define VFORK_UNLOCK __UCLIBC_MUTEX_UNLOCK(mylock) - #endif - - struct popen_list_item { -@@ -118,10 +113,10 @@ FILE *popen(const char *command, const c - if (pid > 0) { /* Parent of vfork... */ - pi->pid = pid; - pi->f = fp; -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - pi->next = popen_list; - popen_list = pi; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - return fp; - } -@@ -136,6 +131,8 @@ FILE *popen(const char *command, const c - return NULL; - } - -+#warning is pclose correct wrt the new mutex semantics? -+ - int pclose(FILE *stream) - { - struct popen_list_item *p; -@@ -144,7 +141,7 @@ int pclose(FILE *stream) - - /* First, find the list entry corresponding to stream and remove it - * from the list. Set p to the list item (NULL if not found). */ -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if ((p = popen_list) != NULL) { - if (p->f == stream) { - popen_list = p->next; -@@ -163,7 +160,7 @@ int pclose(FILE *stream) - } while (1); - } - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - if (p) { - pid = p->pid; /* Save the pid we need */ -diff --git a/libc/stdio/setvbuf.c b/libc/stdio/setvbuf.c -index 3fe62c6..6d53ab1 100644 ---- a/libc/stdio/setvbuf.c -+++ b/libc/stdio/setvbuf.c -@@ -75,8 +75,8 @@ int setvbuf(register FILE * __restrict s - } - - stream->__modeflags |= alloc_flag; -- stream->__bufstart = buf; -- stream->__bufend = buf + size; -+ stream->__bufstart = (unsigned char *) buf; -+ stream->__bufend = (unsigned char *) buf + size; - __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream); - __STDIO_STREAM_DISABLE_GETC(stream); - __STDIO_STREAM_DISABLE_PUTC(stream); -diff --git a/libc/stdio/vasprintf.c b/libc/stdio/vasprintf.c -index 688ab7c..6d7664d 100644 ---- a/libc/stdio/vasprintf.c -+++ b/libc/stdio/vasprintf.c -@@ -63,6 +63,8 @@ int vasprintf(char **__restrict buf, con - free(*buf); - *buf = NULL; - } -+ } else { -+ rv = -1; - } - } - -diff --git a/libc/stdio/vdprintf.c b/libc/stdio/vdprintf.c -index de8362c..7cb707f 100644 ---- a/libc/stdio/vdprintf.c -+++ b/libc/stdio/vdprintf.c -@@ -15,8 +15,8 @@ int vdprintf(int filedes, const char * _ - #ifdef __STDIO_BUFFERS - char buf[64]; /* TODO: provide _optional_ buffering? */ - -- f.__bufend = buf + sizeof(buf); -- f.__bufstart = buf; -+ f.__bufend = (unsigned char *) buf + sizeof(buf); -+ f.__bufstart = (unsigned char *) buf; - __STDIO_STREAM_DISABLE_GETC(&f); - __STDIO_STREAM_DISABLE_PUTC(&f); - __STDIO_STREAM_INIT_BUFREAD_BUFPOS(&f); -diff --git a/libc/stdio/vfprintf.c b/libc/stdio/vfprintf.c -index 10114f0..9214e3b 100644 ---- a/libc/stdio/vfprintf.c -+++ b/libc/stdio/vfprintf.c -@@ -569,7 +569,7 @@ int _ppfs_init(register ppfs_t *ppfs, co - ppfs->fmtpos = fmt0; /* rewind */ - } - --#ifdef NL_MAX_ARG -+#ifdef NL_ARGMAX - /* If we have positional args, make sure we know all the types. */ - { - register int *p = ppfs->argtype; -@@ -581,7 +581,7 @@ int _ppfs_init(register ppfs_t *ppfs, co - ++p; - } - } --#endif /* NL_MAX_ARG */ -+#endif /* NL_ARGMAX */ - - return 0; - } -@@ -1214,7 +1214,7 @@ static size_t _fp_out_narrow(FILE *fp, i - } - len = buflen; - } -- return r + OUTNSTR(fp, (const char *) buf, len); -+ return r + OUTNSTR(fp, (const unsigned char *) buf, len); - } - - #endif /* __STDIO_PRINTF_FLOAT */ -diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c -index 77c2cdc..9f69918 100644 ---- a/libc/stdlib/abort.c -+++ b/libc/stdlib/abort.c -@@ -70,16 +70,9 @@ extern void _exit __P((int __status)) __ - static int been_there_done_that = 0; - - /* Be prepared in case multiple threads try to abort() */ --#ifdef __UCLIBC_HAS_THREADS__ --# include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock) --#else --# define LOCK --# define UNLOCK --#endif -+#include <bits/uClibc_mutex.h> - -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - /* Cause an abnormal program termination with core-dump */ - void abort(void) -@@ -87,7 +80,7 @@ void abort(void) - sigset_t sigset; - - /* Make sure we acquire the lock before proceeding */ -- LOCK; -+ __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock); - - /* Unmask SIGABRT to be sure we can get it */ - if (__sigemptyset(&sigset) == 0 && __sigaddset(&sigset, SIGABRT) == 0) { -@@ -110,9 +103,9 @@ void abort(void) - #endif - - abort_it: -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(mylock); - raise(SIGABRT); -- LOCK; -+ __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock); - } - - /* Still here? Try to remove any signal handlers */ -diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c -index 280f42c..b028068 100644 ---- a/libc/stdlib/atexit.c -+++ b/libc/stdlib/atexit.c -@@ -40,17 +40,9 @@ - #include <stdlib.h> - #include <errno.h> - -+#include <bits/uClibc_mutex.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --extern pthread_mutex_t mylock; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -- -+__UCLIBC_MUTEX_EXTERN(__atexit_lock); - - typedef void (*aefuncp) (void); /* atexit function pointer */ - typedef void (*oefuncp) (int, void *); /* on_exit function pointer */ -@@ -90,8 +82,9 @@ extern struct exit_function __exit_funct - int atexit(aefuncp func) - { - struct exit_function *efp; -+ int rv = -1; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(__atexit_lock); - if (func) { - #ifdef __UCLIBC_DYNAMIC_ATEXIT__ - /* If we are out of function table slots, make some more */ -@@ -99,18 +92,16 @@ int atexit(aefuncp func) - efp=realloc(__exit_function_table, - (__exit_slots+20)*sizeof(struct exit_function)); - if (efp==NULL) { -- UNLOCK; - __set_errno(ENOMEM); -- return -1; -+ goto DONE; - } - __exit_function_table = efp; - __exit_slots+=20; - } - #else - if (__exit_count >= __UCLIBC_MAX_ATEXIT) { -- UNLOCK; - __set_errno(ENOMEM); -- return -1; -+ goto DONE; - } - #endif - __exit_cleanup = __exit_handler; /* enable cleanup */ -@@ -118,8 +109,12 @@ int atexit(aefuncp func) - efp->type = ef_atexit; - efp->funcs.atexit = func; - } -- UNLOCK; -- return 0; -+ -+ rv = 0; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(__atexit_lock); -+ return rv; - } - #endif - -@@ -133,8 +128,9 @@ int atexit(aefuncp func) - int on_exit(oefuncp func, void *arg) - { - struct exit_function *efp; -+ int rv = -1; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(__atexit_lock); - if (func) { - #ifdef __UCLIBC_DYNAMIC_ATEXIT__ - /* If we are out of function table slots, make some more */ -@@ -142,18 +138,16 @@ int on_exit(oefuncp func, void *arg) - efp=realloc(__exit_function_table, - (__exit_slots+20)*sizeof(struct exit_function)); - if (efp==NULL) { -- UNLOCK; - __set_errno(ENOMEM); -- return -1; -+ goto DONE; - } - __exit_function_table=efp; - __exit_slots+=20; - } - #else - if (__exit_count >= __UCLIBC_MAX_ATEXIT) { -- UNLOCK; - __set_errno(ENOMEM); -- return -1; -+ goto DONE; - } - #endif - -@@ -163,8 +157,12 @@ int on_exit(oefuncp func, void *arg) - efp->funcs.on_exit.func = func; - efp->funcs.on_exit.arg = arg; - } -- UNLOCK; -- return 0; -+ -+ rv = 0; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(__atexit_lock); -+ return rv; - } - #endif - -@@ -214,9 +212,8 @@ void __exit_handler(int status) - #ifdef L_exit - extern void weak_function _stdio_term(void); - void (*__exit_cleanup) (int) = 0; --#ifdef __UCLIBC_HAS_THREADS__ --pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --#endif -+ -+__UCLIBC_MUTEX_INIT(__atexit_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - #ifdef __UCLIBC_CTOR_DTOR__ - extern void (*__app_fini)(void); -@@ -229,11 +226,11 @@ extern void (*__rtld_fini)(void); - void exit(int rv) - { - /* Perform exit-specific cleanup (atexit and on_exit) */ -- LOCK; -+ __UCLIBC_MUTEX_LOCK(__atexit_lock); - if (__exit_cleanup) { - __exit_cleanup(rv); - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(__atexit_lock); - - #ifdef __UCLIBC_CTOR_DTOR__ - if (__app_fini != NULL) -diff --git a/libc/stdlib/malloc-simple/alloc.c b/libc/stdlib/malloc-simple/alloc.c -index ed14c37..519a875 100644 ---- a/libc/stdlib/malloc-simple/alloc.c -+++ b/libc/stdlib/malloc-simple/alloc.c -@@ -108,15 +108,14 @@ void free(void *ptr) - #endif - - #ifdef L_memalign --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --# define LOCK __pthread_mutex_lock(&__malloc_lock) --# define UNLOCK __pthread_mutex_unlock(&__malloc_lock); --#else --# define LOCK --# define UNLOCK --#endif -+ -+#include <bits/uClibc_mutex.h> -+ -+__UCLIBC_MUTEX_EXTERN(__malloc_lock); -+ -+#define __MALLOC_LOCK __UCLIBC_MUTEX_LOCK(__malloc_lock) -+#define __MALLOC_UNLOCK __UCLIBC_MUTEX_UNLOCK(__malloc_lock) -+ - - /* List of blocks allocated with memalign or valloc */ - struct alignlist -@@ -135,7 +134,7 @@ int __libc_free_aligned(void *ptr) - if (ptr == NULL) - return 0; - -- LOCK; -+ __MALLOC_LOCK; - for (l = _aligned_blocks; l != NULL; l = l->next) { - if (l->aligned == ptr) { - /* Mark the block as free */ -@@ -146,7 +145,7 @@ int __libc_free_aligned(void *ptr) - return 1; - } - } -- UNLOCK; -+ __MALLOC_UNLOCK; - return 0; - } - void * memalign (size_t alignment, size_t size) -@@ -159,10 +158,10 @@ void * memalign (size_t alignment, size_ - return NULL; - - adj = (unsigned long int) ((unsigned long int) ((char *) result - -- (char *) NULL)) % alignment; -+ (char *) NULL)) % alignment; - if (adj != 0) { - struct alignlist *l; -- LOCK; -+ __MALLOC_LOCK; - for (l = _aligned_blocks; l != NULL; l = l->next) - if (l->aligned == NULL) - /* This slot is free. Use it. */ -@@ -171,15 +170,16 @@ void * memalign (size_t alignment, size_ - l = (struct alignlist *) malloc (sizeof (struct alignlist)); - if (l == NULL) { - free(result); -- UNLOCK; -- return NULL; -+ result = NULL; -+ goto DONE; - } - l->next = _aligned_blocks; - _aligned_blocks = l; - } - l->exact = result; - result = l->aligned = (char *) result + alignment - adj; -- UNLOCK; -+ DONE: -+ __MALLOC_UNLOCK; - } - - return result; -diff --git a/libc/stdlib/malloc-standard/calloc.c b/libc/stdlib/malloc-standard/calloc.c -index a67dad7..4277954 100644 ---- a/libc/stdlib/malloc-standard/calloc.c -+++ b/libc/stdlib/malloc-standard/calloc.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -31,63 +31,63 @@ void* calloc(size_t n_elements, size_t e - * to fall through and call malloc(0) */ - size = n_elements * elem_size; - if (n_elements && elem_size != (size / n_elements)) { -- __set_errno(ENOMEM); -- return NULL; -+ __set_errno(ENOMEM); -+ return NULL; - } - -- LOCK; -+ __MALLOC_LOCK; - mem = malloc(size); - if (mem != 0) { -- p = mem2chunk(mem); -+ p = mem2chunk(mem); - -- if (!chunk_is_mmapped(p)) -- { -- /* -- Unroll clear of <= 36 bytes (72 if 8byte sizes) -- We know that contents have an odd number of -- size_t-sized words; minimally 3. -- */ -- -- d = (size_t*)mem; -- clearsize = chunksize(p) - (sizeof(size_t)); -- nclears = clearsize / sizeof(size_t); -- assert(nclears >= 3); -- -- if (nclears > 9) -- memset(d, 0, clearsize); -- -- else { -- *(d+0) = 0; -- *(d+1) = 0; -- *(d+2) = 0; -- if (nclears > 4) { -- *(d+3) = 0; -- *(d+4) = 0; -- if (nclears > 6) { -- *(d+5) = 0; -- *(d+6) = 0; -- if (nclears > 8) { -- *(d+7) = 0; -- *(d+8) = 0; -+ if (!chunk_is_mmapped(p)) -+ { -+ /* -+ Unroll clear of <= 36 bytes (72 if 8byte sizes) -+ We know that contents have an odd number of -+ size_t-sized words; minimally 3. -+ */ -+ -+ d = (size_t*)mem; -+ clearsize = chunksize(p) - (sizeof(size_t)); -+ nclears = clearsize / sizeof(size_t); -+ assert(nclears >= 3); -+ -+ if (nclears > 9) -+ memset(d, 0, clearsize); -+ -+ else { -+ *(d+0) = 0; -+ *(d+1) = 0; -+ *(d+2) = 0; -+ if (nclears > 4) { -+ *(d+3) = 0; -+ *(d+4) = 0; -+ if (nclears > 6) { -+ *(d+5) = 0; -+ *(d+6) = 0; -+ if (nclears > 8) { -+ *(d+7) = 0; -+ *(d+8) = 0; -+ } -+ } -+ } -+ } - } -- } -- } -- } -- } - #if 0 -- else -- { -- /* Standard unix mmap using /dev/zero clears memory so calloc -- * doesn't need to actually zero anything.... -- */ -- d = (size_t*)mem; -- /* Note the additional (sizeof(size_t)) */ -- clearsize = chunksize(p) - 2*(sizeof(size_t)); -- memset(d, 0, clearsize); -- } -+ else -+ { -+ /* Standard unix mmap using /dev/zero clears memory so calloc -+ * doesn't need to actually zero anything.... -+ */ -+ d = (size_t*)mem; -+ /* Note the additional (sizeof(size_t)) */ -+ clearsize = chunksize(p) - 2*(sizeof(size_t)); -+ memset(d, 0, clearsize); -+ } - #endif - } -- UNLOCK; -+ __MALLOC_UNLOCK; - return mem; - } - -diff --git a/libc/stdlib/malloc-standard/free.c b/libc/stdlib/malloc-standard/free.c -index 94e1d65..4e08ef7 100644 ---- a/libc/stdlib/malloc-standard/free.c -+++ b/libc/stdlib/malloc-standard/free.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -42,71 +42,71 @@ static int __malloc_trim(size_t pad, mst - - if (extra > 0) { - -- /* -- Only proceed if end of memory is where we last set it. -- This avoids problems if there were foreign sbrk calls. -- */ -- current_brk = (char*)(MORECORE(0)); -- if (current_brk == (char*)(av->top) + top_size) { -- -- /* -- Attempt to release memory. We ignore MORECORE return value, -- and instead call again to find out where new end of memory is. -- This avoids problems if first call releases less than we asked, -- of if failure somehow altered brk value. (We could still -- encounter problems if it altered brk in some very bad way, -- but the only thing we can do is adjust anyway, which will cause -- some downstream failure.) -- */ -- -- MORECORE(-extra); -- new_brk = (char*)(MORECORE(0)); -- -- if (new_brk != (char*)MORECORE_FAILURE) { -- released = (long)(current_brk - new_brk); -- -- if (released != 0) { -- /* Success. Adjust top. */ -- av->sbrked_mem -= released; -- set_head(av->top, (top_size - released) | PREV_INUSE); -- check_malloc_state(); -- return 1; -+ /* -+ Only proceed if end of memory is where we last set it. -+ This avoids problems if there were foreign sbrk calls. -+ */ -+ current_brk = (char*)(MORECORE(0)); -+ if (current_brk == (char*)(av->top) + top_size) { -+ -+ /* -+ Attempt to release memory. We ignore MORECORE return value, -+ and instead call again to find out where new end of memory is. -+ This avoids problems if first call releases less than we asked, -+ of if failure somehow altered brk value. (We could still -+ encounter problems if it altered brk in some very bad way, -+ but the only thing we can do is adjust anyway, which will cause -+ some downstream failure.) -+ */ -+ -+ MORECORE(-extra); -+ new_brk = (char*)(MORECORE(0)); -+ -+ if (new_brk != (char*)MORECORE_FAILURE) { -+ released = (long)(current_brk - new_brk); -+ -+ if (released != 0) { -+ /* Success. Adjust top. */ -+ av->sbrked_mem -= released; -+ set_head(av->top, (top_size - released) | PREV_INUSE); -+ check_malloc_state(); -+ return 1; -+ } -+ } - } -- } -- } - } - return 0; - } - - /* ------------------------- malloc_trim ------------------------- -- malloc_trim(size_t pad); -+ malloc_trim(size_t pad); - -- If possible, gives memory back to the system (via negative -- arguments to sbrk) if there is unused memory at the `high' end of -- the malloc pool. You can call this after freeing large blocks of -- memory to potentially reduce the system-level memory requirements -- of a program. However, it cannot guarantee to reduce memory. Under -- some allocation patterns, some large free blocks of memory will be -- locked between two used chunks, so they cannot be given back to -- the system. -- -- The `pad' argument to malloc_trim represents the amount of free -- trailing space to leave untrimmed. If this argument is zero, -- only the minimum amount of memory to maintain internal data -- structures will be left (one page or less). Non-zero arguments -- can be supplied to maintain enough trailing space to service -- future expected allocations without having to re-obtain memory -- from the system. -- -- Malloc_trim returns 1 if it actually released any memory, else 0. -- On systems that do not support "negative sbrks", it will always -- return 0. -+ If possible, gives memory back to the system (via negative -+ arguments to sbrk) if there is unused memory at the `high' end of -+ the malloc pool. You can call this after freeing large blocks of -+ memory to potentially reduce the system-level memory requirements -+ of a program. However, it cannot guarantee to reduce memory. Under -+ some allocation patterns, some large free blocks of memory will be -+ locked between two used chunks, so they cannot be given back to -+ the system. -+ -+ The `pad' argument to malloc_trim represents the amount of free -+ trailing space to leave untrimmed. If this argument is zero, -+ only the minimum amount of memory to maintain internal data -+ structures will be left (one page or less). Non-zero arguments -+ can be supplied to maintain enough trailing space to service -+ future expected allocations without having to re-obtain memory -+ from the system. -+ -+ Malloc_trim returns 1 if it actually released any memory, else 0. -+ On systems that do not support "negative sbrks", it will always -+ return 0. - */ - int malloc_trim(size_t pad) - { -- mstate av = get_malloc_state(); -- __malloc_consolidate(av); -- return __malloc_trim(pad, av); -+ mstate av = get_malloc_state(); -+ __malloc_consolidate(av); -+ return __malloc_trim(pad, av); - } - - /* -@@ -125,8 +125,8 @@ static void malloc_init_state(mstate av) - - /* Establish circular links for normal bins */ - for (i = 1; i < NBINS; ++i) { -- bin = bin_at(av,i); -- bin->fd = bin->bk = bin; -+ bin = bin_at(av,i); -+ bin->fd = bin->bk = bin; - } - - av->top_pad = DEFAULT_TOP_PAD; -@@ -157,15 +157,15 @@ static void malloc_init_state(mstate av) - - /* ------------------------- __malloc_consolidate ------------------------- - -- __malloc_consolidate is a specialized version of free() that tears -- down chunks held in fastbins. Free itself cannot be used for this -- purpose since, among other things, it might place chunks back onto -- fastbins. So, instead, we need to use a minor variant of the same -- code. -- -- Also, because this routine needs to be called the first time through -- malloc anyway, it turns out to be the perfect place to trigger -- initialization code. -+__malloc_consolidate is a specialized version of free() that tears -+down chunks held in fastbins. Free itself cannot be used for this -+purpose since, among other things, it might place chunks back onto -+fastbins. So, instead, we need to use a minor variant of the same -+code. -+ -+Also, because this routine needs to be called the first time through -+malloc anyway, it turns out to be the perfect place to trigger -+initialization code. - */ - void __malloc_consolidate(mstate av) - { -@@ -186,78 +186,78 @@ void __malloc_consolidate(mstate av) - mchunkptr fwd; - - /* -- If max_fast is 0, we know that av hasn't -- yet been initialized, in which case do so below -- */ -+ If max_fast is 0, we know that av hasn't -+ yet been initialized, in which case do so below -+ */ - - if (av->max_fast != 0) { -- clear_fastchunks(av); -+ clear_fastchunks(av); - -- unsorted_bin = unsorted_chunks(av); -+ unsorted_bin = unsorted_chunks(av); - -- /* -- Remove each chunk from fast bin and consolidate it, placing it -- then in unsorted bin. Among other reasons for doing this, -- placing in unsorted bin avoids needing to calculate actual bins -- until malloc is sure that chunks aren't immediately going to be -- reused anyway. -- */ -- -- maxfb = &(av->fastbins[fastbin_index(av->max_fast)]); -- fb = &(av->fastbins[0]); -- do { -- if ( (p = *fb) != 0) { -- *fb = 0; -+ /* -+ Remove each chunk from fast bin and consolidate it, placing it -+ then in unsorted bin. Among other reasons for doing this, -+ placing in unsorted bin avoids needing to calculate actual bins -+ until malloc is sure that chunks aren't immediately going to be -+ reused anyway. -+ */ - -+ maxfb = &(av->fastbins[fastbin_index(av->max_fast)]); -+ fb = &(av->fastbins[0]); - do { -- check_inuse_chunk(p); -- nextp = p->fd; -+ if ( (p = *fb) != 0) { -+ *fb = 0; - -- /* Slightly streamlined version of consolidation code in free() */ -- size = p->size & ~PREV_INUSE; -- nextchunk = chunk_at_offset(p, size); -- nextsize = chunksize(nextchunk); -+ do { -+ check_inuse_chunk(p); -+ nextp = p->fd; -+ -+ /* Slightly streamlined version of consolidation code in free() */ -+ size = p->size & ~PREV_INUSE; -+ nextchunk = chunk_at_offset(p, size); -+ nextsize = chunksize(nextchunk); -+ -+ if (!prev_inuse(p)) { -+ prevsize = p->prev_size; -+ size += prevsize; -+ p = chunk_at_offset(p, -((long) prevsize)); -+ unlink(p, bck, fwd); -+ } -+ -+ if (nextchunk != av->top) { -+ nextinuse = inuse_bit_at_offset(nextchunk, nextsize); -+ set_head(nextchunk, nextsize); -+ -+ if (!nextinuse) { -+ size += nextsize; -+ unlink(nextchunk, bck, fwd); -+ } -+ -+ first_unsorted = unsorted_bin->fd; -+ unsorted_bin->fd = p; -+ first_unsorted->bk = p; -+ -+ set_head(p, size | PREV_INUSE); -+ p->bk = unsorted_bin; -+ p->fd = first_unsorted; -+ set_foot(p, size); -+ } -+ -+ else { -+ size += nextsize; -+ set_head(p, size | PREV_INUSE); -+ av->top = p; -+ } - -- if (!prev_inuse(p)) { -- prevsize = p->prev_size; -- size += prevsize; -- p = chunk_at_offset(p, -((long) prevsize)); -- unlink(p, bck, fwd); -- } -+ } while ( (p = nextp) != 0); - -- if (nextchunk != av->top) { -- nextinuse = inuse_bit_at_offset(nextchunk, nextsize); -- set_head(nextchunk, nextsize); -- -- if (!nextinuse) { -- size += nextsize; -- unlink(nextchunk, bck, fwd); - } -- -- first_unsorted = unsorted_bin->fd; -- unsorted_bin->fd = p; -- first_unsorted->bk = p; -- -- set_head(p, size | PREV_INUSE); -- p->bk = unsorted_bin; -- p->fd = first_unsorted; -- set_foot(p, size); -- } -- -- else { -- size += nextsize; -- set_head(p, size | PREV_INUSE); -- av->top = p; -- } -- -- } while ( (p = nextp) != 0); -- -- } -- } while (fb++ != maxfb); -+ } while (fb++ != maxfb); - } - else { -- malloc_init_state(av); -- check_malloc_state(); -+ malloc_init_state(av); -+ check_malloc_state(); - } - } - -@@ -279,9 +279,9 @@ void free(void* mem) - - /* free(0) has no effect */ - if (mem == NULL) -- return; -+ return; - -- LOCK; -+ __MALLOC_LOCK; - av = get_malloc_state(); - p = mem2chunk(mem); - size = chunksize(p); -@@ -289,9 +289,9 @@ void free(void* mem) - check_inuse_chunk(p); - - /* -- If eligible, place chunk on a fastbin so it can be found -- and used quickly in malloc. -- */ -+ If eligible, place chunk on a fastbin so it can be found -+ and used quickly in malloc. -+ */ - - if ((unsigned long)(size) <= (unsigned long)(av->max_fast) - -@@ -300,114 +300,114 @@ void free(void* mem) - bordering top into fastbins */ - && (chunk_at_offset(p, size) != av->top) - #endif -- ) { -+ ) { - -- set_fastchunks(av); -- fb = &(av->fastbins[fastbin_index(size)]); -- p->fd = *fb; -- *fb = p; -+ set_fastchunks(av); -+ fb = &(av->fastbins[fastbin_index(size)]); -+ p->fd = *fb; -+ *fb = p; - } - - /* -- Consolidate other non-mmapped chunks as they arrive. -- */ -+ Consolidate other non-mmapped chunks as they arrive. -+ */ - - else if (!chunk_is_mmapped(p)) { -- set_anychunks(av); -+ set_anychunks(av); -+ -+ nextchunk = chunk_at_offset(p, size); -+ nextsize = chunksize(nextchunk); -+ -+ /* consolidate backward */ -+ if (!prev_inuse(p)) { -+ prevsize = p->prev_size; -+ size += prevsize; -+ p = chunk_at_offset(p, -((long) prevsize)); -+ unlink(p, bck, fwd); -+ } -+ -+ if (nextchunk != av->top) { -+ /* get and clear inuse bit */ -+ nextinuse = inuse_bit_at_offset(nextchunk, nextsize); -+ set_head(nextchunk, nextsize); -+ -+ /* consolidate forward */ -+ if (!nextinuse) { -+ unlink(nextchunk, bck, fwd); -+ size += nextsize; -+ } -+ -+ /* -+ Place the chunk in unsorted chunk list. Chunks are -+ not placed into regular bins until after they have -+ been given one chance to be used in malloc. -+ */ -+ -+ bck = unsorted_chunks(av); -+ fwd = bck->fd; -+ p->bk = bck; -+ p->fd = fwd; -+ bck->fd = p; -+ fwd->bk = p; - -- nextchunk = chunk_at_offset(p, size); -- nextsize = chunksize(nextchunk); -+ set_head(p, size | PREV_INUSE); -+ set_foot(p, size); -+ -+ check_free_chunk(p); -+ } -+ -+ /* -+ If the chunk borders the current high end of memory, -+ consolidate into top -+ */ - -- /* consolidate backward */ -- if (!prev_inuse(p)) { -- prevsize = p->prev_size; -- size += prevsize; -- p = chunk_at_offset(p, -((long) prevsize)); -- unlink(p, bck, fwd); -- } -- -- if (nextchunk != av->top) { -- /* get and clear inuse bit */ -- nextinuse = inuse_bit_at_offset(nextchunk, nextsize); -- set_head(nextchunk, nextsize); -- -- /* consolidate forward */ -- if (!nextinuse) { -- unlink(nextchunk, bck, fwd); -- size += nextsize; -- } -- -- /* -- Place the chunk in unsorted chunk list. Chunks are -- not placed into regular bins until after they have -- been given one chance to be used in malloc. -- */ -- -- bck = unsorted_chunks(av); -- fwd = bck->fd; -- p->bk = bck; -- p->fd = fwd; -- bck->fd = p; -- fwd->bk = p; -- -- set_head(p, size | PREV_INUSE); -- set_foot(p, size); -- -- check_free_chunk(p); -- } -- -- /* -- If the chunk borders the current high end of memory, -- consolidate into top -- */ -- -- else { -- size += nextsize; -- set_head(p, size | PREV_INUSE); -- av->top = p; -- check_chunk(p); -- } -- -- /* -- If freeing a large space, consolidate possibly-surrounding -- chunks. Then, if the total unused topmost memory exceeds trim -- threshold, ask malloc_trim to reduce top. -- -- Unless max_fast is 0, we don't know if there are fastbins -- bordering top, so we cannot tell for sure whether threshold -- has been reached unless fastbins are consolidated. But we -- don't want to consolidate on each free. As a compromise, -- consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD -- is reached. -- */ -- -- if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) { -- if (have_fastchunks(av)) -- __malloc_consolidate(av); -- -- if ((unsigned long)(chunksize(av->top)) >= -- (unsigned long)(av->trim_threshold)) -- __malloc_trim(av->top_pad, av); -- } -+ else { -+ size += nextsize; -+ set_head(p, size | PREV_INUSE); -+ av->top = p; -+ check_chunk(p); -+ } -+ -+ /* -+ If freeing a large space, consolidate possibly-surrounding -+ chunks. Then, if the total unused topmost memory exceeds trim -+ threshold, ask malloc_trim to reduce top. -+ -+ Unless max_fast is 0, we don't know if there are fastbins -+ bordering top, so we cannot tell for sure whether threshold -+ has been reached unless fastbins are consolidated. But we -+ don't want to consolidate on each free. As a compromise, -+ consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD -+ is reached. -+ */ -+ -+ if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) { -+ if (have_fastchunks(av)) -+ __malloc_consolidate(av); -+ -+ if ((unsigned long)(chunksize(av->top)) >= -+ (unsigned long)(av->trim_threshold)) -+ __malloc_trim(av->top_pad, av); -+ } - - } - /* -- If the chunk was allocated via mmap, release via munmap() -- Note that if HAVE_MMAP is false but chunk_is_mmapped is -- true, then user must have overwritten memory. There's nothing -- we can do to catch this error unless DEBUG is set, in which case -- check_inuse_chunk (above) will have triggered error. -- */ -+ If the chunk was allocated via mmap, release via munmap() -+ Note that if HAVE_MMAP is false but chunk_is_mmapped is -+ true, then user must have overwritten memory. There's nothing -+ we can do to catch this error unless DEBUG is set, in which case -+ check_inuse_chunk (above) will have triggered error. -+ */ - - else { -- int ret; -- size_t offset = p->prev_size; -- av->n_mmaps--; -- av->mmapped_mem -= (size + offset); -- ret = munmap((char*)p - offset, size + offset); -- /* munmap returns non-zero on failure */ -- assert(ret == 0); -+ int ret; -+ size_t offset = p->prev_size; -+ av->n_mmaps--; -+ av->mmapped_mem -= (size + offset); -+ ret = munmap((char*)p - offset, size + offset); -+ /* munmap returns non-zero on failure */ -+ assert(ret == 0); - } -- UNLOCK; -+ __MALLOC_UNLOCK; - } - -diff --git a/libc/stdlib/malloc-standard/mallinfo.c b/libc/stdlib/malloc-standard/mallinfo.c -index 51ac423..1e0875c 100644 ---- a/libc/stdlib/malloc-standard/mallinfo.c -+++ b/libc/stdlib/malloc-standard/mallinfo.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -30,11 +30,11 @@ struct mallinfo mallinfo(void) - int nblocks; - int nfastblocks; - -- LOCK; -+ __MALLOC_LOCK; - av = get_malloc_state(); - /* Ensure initialization */ - if (av->top == 0) { -- __malloc_consolidate(av); -+ __malloc_consolidate(av); - } - - check_malloc_state(); -@@ -48,21 +48,21 @@ struct mallinfo mallinfo(void) - fastavail = 0; - - for (i = 0; i < NFASTBINS; ++i) { -- for (p = av->fastbins[i]; p != 0; p = p->fd) { -- ++nfastblocks; -- fastavail += chunksize(p); -- } -+ for (p = av->fastbins[i]; p != 0; p = p->fd) { -+ ++nfastblocks; -+ fastavail += chunksize(p); -+ } - } - - avail += fastavail; - - /* traverse regular bins */ - for (i = 1; i < NBINS; ++i) { -- b = bin_at(av, i); -- for (p = last(b); p != b; p = p->bk) { -- ++nblocks; -- avail += chunksize(p); -- } -+ b = bin_at(av, i); -+ for (p = last(b); p != b; p = p->bk) { -+ ++nblocks; -+ avail += chunksize(p); -+ } - } - - mi.smblks = nfastblocks; -@@ -75,7 +75,7 @@ struct mallinfo mallinfo(void) - mi.fsmblks = fastavail; - mi.keepcost = chunksize(av->top); - mi.usmblks = av->max_total_mem; -- UNLOCK; -+ __MALLOC_UNLOCK; - return mi; - } - -@@ -84,23 +84,40 @@ void malloc_stats(FILE *file) - struct mallinfo mi; - - if (file==NULL) { -- file = stderr; -+ file = stderr; - } - - mi = mallinfo(); -- fprintf(file, "total bytes allocated = %10u\n", (unsigned int)(mi.arena + mi.hblkhd)); -- fprintf(file, "total bytes in use bytes = %10u\n", (unsigned int)(mi.uordblks + mi.hblkhd)); -- fprintf(file, "total non-mmapped bytes allocated = %10d\n", mi.arena); -- fprintf(file, "number of mmapped regions = %10d\n", mi.hblks); -- fprintf(file, "total allocated mmap space = %10d\n", mi.hblkhd); -- fprintf(file, "total allocated sbrk space = %10d\n", mi.uordblks); -+ fprintf(file, -+ "total bytes allocated = %10u\n" -+ "total bytes in use bytes = %10u\n" -+ "total non-mmapped bytes allocated = %10d\n" -+ "number of mmapped regions = %10d\n" -+ "total allocated mmap space = %10d\n" -+ "total allocated sbrk space = %10d\n" - #if 0 -- fprintf(file, "number of free chunks = %10d\n", mi.ordblks); -- fprintf(file, "number of fastbin blocks = %10d\n", mi.smblks); -- fprintf(file, "space in freed fastbin blocks = %10d\n", mi.fsmblks); -+ "number of free chunks = %10d\n" -+ "number of fastbin blocks = %10d\n" -+ "space in freed fastbin blocks = %10d\n" - #endif -- fprintf(file, "maximum total allocated space = %10d\n", mi.usmblks); -- fprintf(file, "total free space = %10d\n", mi.fordblks); -- fprintf(file, "memory releasable via malloc_trim = %10d\n", mi.keepcost); -+ "maximum total allocated space = %10d\n" -+ "total free space = %10d\n" -+ "memory releasable via malloc_trim = %10d\n", -+ -+ (unsigned int)(mi.arena + mi.hblkhd), -+ (unsigned int)(mi.uordblks + mi.hblkhd), -+ mi.arena, -+ mi.hblks, -+ mi.hblkhd, -+ mi.uordblks, -+#if 0 -+ mi.ordblks, -+ mi.smblks, -+ mi.fsmblks, -+#endif -+ mi.usmblks, -+ mi.fordblks, -+ mi.keepcost -+ ); - } - -diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c -index 7025e83..60494a0 100644 ---- a/libc/stdlib/malloc-standard/malloc.c -+++ b/libc/stdlib/malloc-standard/malloc.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -17,17 +17,14 @@ - #define _GNU_SOURCE - #include "malloc.h" - -- --#ifdef __UCLIBC_HAS_THREADS__ --pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --#endif -+__UCLIBC_MUTEX_INIT(__malloc_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - /* -- There is exactly one instance of this struct in this malloc. -- If you are adapting this malloc in a way that does NOT use a static -- malloc_state, you MUST explicitly zero-fill it before using. This -- malloc relies on the property that malloc_state is initialized to -- all zeroes (as is true of C statics). -+ There is exactly one instance of this struct in this malloc. -+ If you are adapting this malloc in a way that does NOT use a static -+ malloc_state, you MUST explicitly zero-fill it before using. This -+ malloc relies on the property that malloc_state is initialized to -+ all zeroes (as is true of C statics). - */ - struct malloc_state __malloc_state; /* never directly referenced */ - -@@ -77,30 +74,30 @@ void __do_check_chunk(mchunkptr p) - - if (!chunk_is_mmapped(p)) { - -- /* Has legal address ... */ -- if (p != av->top) { -- if (contiguous(av)) { -- assert(((char*)p) >= min_address); -- assert(((char*)p + sz) <= ((char*)(av->top))); -- } -- } -- else { -- /* top size is always at least MINSIZE */ -- assert((unsigned long)(sz) >= MINSIZE); -- /* top predecessor always marked inuse */ -- assert(prev_inuse(p)); -- } -+ /* Has legal address ... */ -+ if (p != av->top) { -+ if (contiguous(av)) { -+ assert(((char*)p) >= min_address); -+ assert(((char*)p + sz) <= ((char*)(av->top))); -+ } -+ } -+ else { -+ /* top size is always at least MINSIZE */ -+ assert((unsigned long)(sz) >= MINSIZE); -+ /* top predecessor always marked inuse */ -+ assert(prev_inuse(p)); -+ } - - } - else { -- /* address is outside main heap */ -- if (contiguous(av) && av->top != initial_top(av)) { -- assert(((char*)p) < min_address || ((char*)p) > max_address); -- } -- /* chunk is page-aligned */ -- assert(((p->prev_size + sz) & (av->pagesize-1)) == 0); -- /* mem is aligned */ -- assert(aligned_OK(chunk2mem(p))); -+ /* address is outside main heap */ -+ if (contiguous(av) && av->top != initial_top(av)) { -+ assert(((char*)p) < min_address || ((char*)p) > max_address); -+ } -+ /* chunk is page-aligned */ -+ assert(((p->prev_size + sz) & (av->pagesize-1)) == 0); -+ /* mem is aligned */ -+ assert(aligned_OK(chunk2mem(p))); - } - } - -@@ -121,21 +118,21 @@ void __do_check_free_chunk(mchunkptr p) - - /* Unless a special marker, must have OK fields */ - if ((unsigned long)(sz) >= MINSIZE) -- { -- assert((sz & MALLOC_ALIGN_MASK) == 0); -- assert(aligned_OK(chunk2mem(p))); -- /* ... matching footer field */ -- assert(next->prev_size == sz); -- /* ... and is fully consolidated */ -- assert(prev_inuse(p)); -- assert (next == av->top || inuse(next)); -- -- /* ... and has minimally sane links */ -- assert(p->fd->bk == p); -- assert(p->bk->fd == p); -- } -+ { -+ assert((sz & MALLOC_ALIGN_MASK) == 0); -+ assert(aligned_OK(chunk2mem(p))); -+ /* ... matching footer field */ -+ assert(next->prev_size == sz); -+ /* ... and is fully consolidated */ -+ assert(prev_inuse(p)); -+ assert (next == av->top || inuse(next)); -+ -+ /* ... and has minimally sane links */ -+ assert(p->fd->bk == p); -+ assert(p->bk->fd == p); -+ } - else /* markers are always of size (sizeof(size_t)) */ -- assert(sz == (sizeof(size_t))); -+ assert(sz == (sizeof(size_t))); - } - - /* Properties of inuse chunks */ -@@ -146,7 +143,7 @@ void __do_check_inuse_chunk(mchunkptr p) - __do_check_chunk(p); - - if (chunk_is_mmapped(p)) -- return; /* mmapped chunks have no next/prev */ -+ return; /* mmapped chunks have no next/prev */ - - /* Check whether it claims to be in use ... */ - assert(inuse(p)); -@@ -156,20 +153,20 @@ void __do_check_inuse_chunk(mchunkptr p) - /* ... and is surrounded by OK chunks. - Since more things can be checked with free chunks than inuse ones, - if an inuse chunk borders them and debug is on, it's worth doing them. -- */ -+ */ - if (!prev_inuse(p)) { -- /* Note that we cannot even look at prev unless it is not inuse */ -- mchunkptr prv = prev_chunk(p); -- assert(next_chunk(prv) == p); -- __do_check_free_chunk(prv); -+ /* Note that we cannot even look at prev unless it is not inuse */ -+ mchunkptr prv = prev_chunk(p); -+ assert(next_chunk(prv) == p); -+ __do_check_free_chunk(prv); - } - - if (next == av->top) { -- assert(prev_inuse(next)); -- assert(chunksize(next) >= MINSIZE); -+ assert(prev_inuse(next)); -+ assert(chunksize(next) >= MINSIZE); - } - else if (!inuse(next)) -- __do_check_free_chunk(next); -+ __do_check_free_chunk(next); - } - - /* Properties of chunks recycled from fastbins */ -@@ -198,14 +195,14 @@ void __do_check_malloced_chunk(mchunkptr - __do_check_remalloced_chunk(p, s); - - /* -- ... plus, must obey implementation invariant that prev_inuse is -- always true of any allocated chunk; i.e., that each allocated -- chunk borders either a previously allocated and still in-use -- chunk, or the base of its memory arena. This is ensured -- by making all allocations from the the `lowest' part of any found -- chunk. This does not necessarily hold however for chunks -- recycled via fastbins. -- */ -+ ... plus, must obey implementation invariant that prev_inuse is -+ always true of any allocated chunk; i.e., that each allocated -+ chunk borders either a previously allocated and still in-use -+ chunk, or the base of its memory arena. This is ensured -+ by making all allocations from the the `lowest' part of any found -+ chunk. This does not necessarily hold however for chunks -+ recycled via fastbins. -+ */ - - assert(prev_inuse(p)); - } -@@ -243,7 +240,7 @@ void __do_check_malloc_state(void) - - /* cannot run remaining checks until fully initialized */ - if (av->top == 0 || av->top == initial_top(av)) -- return; -+ return; - - /* pagesize is a power of 2 */ - assert((av->pagesize & (av->pagesize-1)) == 0); -@@ -256,64 +253,64 @@ void __do_check_malloc_state(void) - max_fast_bin = fastbin_index(av->max_fast); - - for (i = 0; i < NFASTBINS; ++i) { -- p = av->fastbins[i]; -+ p = av->fastbins[i]; - -- /* all bins past max_fast are empty */ -- if (i > max_fast_bin) -- assert(p == 0); -- -- while (p != 0) { -- /* each chunk claims to be inuse */ -- __do_check_inuse_chunk(p); -- total += chunksize(p); -- /* chunk belongs in this bin */ -- assert(fastbin_index(chunksize(p)) == i); -- p = p->fd; -- } -+ /* all bins past max_fast are empty */ -+ if (i > max_fast_bin) -+ assert(p == 0); -+ -+ while (p != 0) { -+ /* each chunk claims to be inuse */ -+ __do_check_inuse_chunk(p); -+ total += chunksize(p); -+ /* chunk belongs in this bin */ -+ assert(fastbin_index(chunksize(p)) == i); -+ p = p->fd; -+ } - } - - if (total != 0) -- assert(have_fastchunks(av)); -+ assert(have_fastchunks(av)); - else if (!have_fastchunks(av)) -- assert(total == 0); -+ assert(total == 0); - - /* check normal bins */ - for (i = 1; i < NBINS; ++i) { -- b = bin_at(av,i); -+ b = bin_at(av,i); - -- /* binmap is accurate (except for bin 1 == unsorted_chunks) */ -- if (i >= 2) { -- binbit = get_binmap(av,i); -- empty = last(b) == b; -- if (!binbit) -- assert(empty); -- else if (!empty) -- assert(binbit); -- } -- -- for (p = last(b); p != b; p = p->bk) { -- /* each chunk claims to be free */ -- __do_check_free_chunk(p); -- size = chunksize(p); -- total += size; -- if (i >= 2) { -- /* chunk belongs in bin */ -- idx = bin_index(size); -- assert(idx == i); -- /* lists are sorted */ -- if ((unsigned long) size >= (unsigned long)(FIRST_SORTED_BIN_SIZE)) { -- assert(p->bk == b || -- (unsigned long)chunksize(p->bk) >= -- (unsigned long)chunksize(p)); -- } -- } -- /* chunk is followed by a legal chain of inuse chunks */ -- for (q = next_chunk(p); -- (q != av->top && inuse(q) && -- (unsigned long)(chunksize(q)) >= MINSIZE); -- q = next_chunk(q)) -- __do_check_inuse_chunk(q); -- } -+ /* binmap is accurate (except for bin 1 == unsorted_chunks) */ -+ if (i >= 2) { -+ binbit = get_binmap(av,i); -+ empty = last(b) == b; -+ if (!binbit) -+ assert(empty); -+ else if (!empty) -+ assert(binbit); -+ } -+ -+ for (p = last(b); p != b; p = p->bk) { -+ /* each chunk claims to be free */ -+ __do_check_free_chunk(p); -+ size = chunksize(p); -+ total += size; -+ if (i >= 2) { -+ /* chunk belongs in bin */ -+ idx = bin_index(size); -+ assert(idx == i); -+ /* lists are sorted */ -+ if ((unsigned long) size >= (unsigned long)(FIRST_SORTED_BIN_SIZE)) { -+ assert(p->bk == b || -+ (unsigned long)chunksize(p->bk) >= -+ (unsigned long)chunksize(p)); -+ } -+ } -+ /* chunk is followed by a legal chain of inuse chunks */ -+ for (q = next_chunk(p); -+ (q != av->top && inuse(q) && -+ (unsigned long)(chunksize(q)) >= MINSIZE); -+ q = next_chunk(q)) -+ __do_check_inuse_chunk(q); -+ } - } - - /* top chunk is OK */ -@@ -326,13 +323,13 @@ void __do_check_malloc_state(void) - assert(av->n_mmaps <= av->max_n_mmaps); - - assert((unsigned long)(av->sbrked_mem) <= -- (unsigned long)(av->max_sbrked_mem)); -+ (unsigned long)(av->max_sbrked_mem)); - - assert((unsigned long)(av->mmapped_mem) <= -- (unsigned long)(av->max_mmapped_mem)); -+ (unsigned long)(av->max_mmapped_mem)); - - assert((unsigned long)(av->max_total_mem) >= -- (unsigned long)(av->mmapped_mem) + (unsigned long)(av->sbrked_mem)); -+ (unsigned long)(av->mmapped_mem) + (unsigned long)(av->sbrked_mem)); - } - #endif - -@@ -370,84 +367,84 @@ static void* __malloc_alloc(size_t nb, m - size_t pagemask = av->pagesize - 1; - - /* -- If there is space available in fastbins, consolidate and retry -- malloc from scratch rather than getting memory from system. This -- can occur only if nb is in smallbin range so we didn't consolidate -- upon entry to malloc. It is much easier to handle this case here -- than in malloc proper. -- */ -+ If there is space available in fastbins, consolidate and retry -+ malloc from scratch rather than getting memory from system. This -+ can occur only if nb is in smallbin range so we didn't consolidate -+ upon entry to malloc. It is much easier to handle this case here -+ than in malloc proper. -+ */ - - if (have_fastchunks(av)) { -- assert(in_smallbin_range(nb)); -- __malloc_consolidate(av); -- return malloc(nb - MALLOC_ALIGN_MASK); -+ assert(in_smallbin_range(nb)); -+ __malloc_consolidate(av); -+ return malloc(nb - MALLOC_ALIGN_MASK); - } - - - /* -- If have mmap, and the request size meets the mmap threshold, and -- the system supports mmap, and there are few enough currently -- allocated mmapped regions, try to directly map this request -- rather than expanding top. -- */ -+ If have mmap, and the request size meets the mmap threshold, and -+ the system supports mmap, and there are few enough currently -+ allocated mmapped regions, try to directly map this request -+ rather than expanding top. -+ */ - - if ((unsigned long)(nb) >= (unsigned long)(av->mmap_threshold) && - (av->n_mmaps < av->n_mmaps_max)) { - -- char* mm; /* return value from mmap call*/ -- -- /* -- Round up size to nearest page. For mmapped chunks, the overhead -- is one (sizeof(size_t)) unit larger than for normal chunks, because there -- is no following chunk whose prev_size field could be used. -- */ -- size = (nb + (sizeof(size_t)) + MALLOC_ALIGN_MASK + pagemask) & ~pagemask; -- -- /* Don't try if size wraps around 0 */ -- if ((unsigned long)(size) > (unsigned long)(nb)) { -- -- mm = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE)); -- -- if (mm != (char*)(MORECORE_FAILURE)) { -+ char* mm; /* return value from mmap call*/ - - /* -- The offset to the start of the mmapped region is stored -- in the prev_size field of the chunk. This allows us to adjust -- returned start address to meet alignment requirements here -- and in memalign(), and still be able to compute proper -- address argument for later munmap in free() and realloc(). -- */ -- -- front_misalign = (size_t)chunk2mem(mm) & MALLOC_ALIGN_MASK; -- if (front_misalign > 0) { -- correction = MALLOC_ALIGNMENT - front_misalign; -- p = (mchunkptr)(mm + correction); -- p->prev_size = correction; -- set_head(p, (size - correction) |IS_MMAPPED); -- } -- else { -- p = (mchunkptr)mm; -- p->prev_size = 0; -- set_head(p, size|IS_MMAPPED); -- } -+ Round up size to nearest page. For mmapped chunks, the overhead -+ is one (sizeof(size_t)) unit larger than for normal chunks, because there -+ is no following chunk whose prev_size field could be used. -+ */ -+ size = (nb + (sizeof(size_t)) + MALLOC_ALIGN_MASK + pagemask) & ~pagemask; -+ -+ /* Don't try if size wraps around 0 */ -+ if ((unsigned long)(size) > (unsigned long)(nb)) { -+ -+ mm = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE)); -+ -+ if (mm != (char*)(MORECORE_FAILURE)) { -+ -+ /* -+ The offset to the start of the mmapped region is stored -+ in the prev_size field of the chunk. This allows us to adjust -+ returned start address to meet alignment requirements here -+ and in memalign(), and still be able to compute proper -+ address argument for later munmap in free() and realloc(). -+ */ -+ -+ front_misalign = (size_t)chunk2mem(mm) & MALLOC_ALIGN_MASK; -+ if (front_misalign > 0) { -+ correction = MALLOC_ALIGNMENT - front_misalign; -+ p = (mchunkptr)(mm + correction); -+ p->prev_size = correction; -+ set_head(p, (size - correction) |IS_MMAPPED); -+ } -+ else { -+ p = (mchunkptr)mm; -+ p->prev_size = 0; -+ set_head(p, size|IS_MMAPPED); -+ } -+ -+ /* update statistics */ -+ -+ if (++av->n_mmaps > av->max_n_mmaps) -+ av->max_n_mmaps = av->n_mmaps; -+ -+ sum = av->mmapped_mem += size; -+ if (sum > (unsigned long)(av->max_mmapped_mem)) -+ av->max_mmapped_mem = sum; -+ sum += av->sbrked_mem; -+ if (sum > (unsigned long)(av->max_total_mem)) -+ av->max_total_mem = sum; - -- /* update statistics */ -+ check_chunk(p); - -- if (++av->n_mmaps > av->max_n_mmaps) -- av->max_n_mmaps = av->n_mmaps; -- -- sum = av->mmapped_mem += size; -- if (sum > (unsigned long)(av->max_mmapped_mem)) -- av->max_mmapped_mem = sum; -- sum += av->sbrked_mem; -- if (sum > (unsigned long)(av->max_total_mem)) -- av->max_total_mem = sum; -- -- check_chunk(p); -- -- return chunk2mem(p); -- } -- } -+ return chunk2mem(p); -+ } -+ } - } - - /* Record incoming configuration of top */ -@@ -462,8 +459,8 @@ static void* __malloc_alloc(size_t nb, m - * be at least MINSIZE and to have prev_inuse set. */ - - assert((old_top == initial_top(av) && old_size == 0) || -- ((unsigned long) (old_size) >= MINSIZE && -- prev_inuse(old_top))); -+ ((unsigned long) (old_size) >= MINSIZE && -+ prev_inuse(old_top))); - - /* Precondition: not enough current space to satisfy nb request */ - assert((unsigned long)(old_size) < (unsigned long)(nb + MINSIZE)); -@@ -477,272 +474,272 @@ static void* __malloc_alloc(size_t nb, m - size = nb + av->top_pad + MINSIZE; - - /* -- If contiguous, we can subtract out existing space that we hope to -- combine with new space. We add it back later only if -- we don't actually get contiguous space. -- */ -+ If contiguous, we can subtract out existing space that we hope to -+ combine with new space. We add it back later only if -+ we don't actually get contiguous space. -+ */ - - if (contiguous(av)) -- size -= old_size; -+ size -= old_size; - - /* -- Round to a multiple of page size. -- If MORECORE is not contiguous, this ensures that we only call it -- with whole-page arguments. And if MORECORE is contiguous and -- this is not first time through, this preserves page-alignment of -- previous calls. Otherwise, we correct to page-align below. -- */ -+ Round to a multiple of page size. -+ If MORECORE is not contiguous, this ensures that we only call it -+ with whole-page arguments. And if MORECORE is contiguous and -+ this is not first time through, this preserves page-alignment of -+ previous calls. Otherwise, we correct to page-align below. -+ */ - - size = (size + pagemask) & ~pagemask; - - /* -- Don't try to call MORECORE if argument is so big as to appear -- negative. Note that since mmap takes size_t arg, it may succeed -- below even if we cannot call MORECORE. -- */ -+ Don't try to call MORECORE if argument is so big as to appear -+ negative. Note that since mmap takes size_t arg, it may succeed -+ below even if we cannot call MORECORE. -+ */ - - if (size > 0) -- brk = (char*)(MORECORE(size)); -+ brk = (char*)(MORECORE(size)); - - /* -- If have mmap, try using it as a backup when MORECORE fails or -- cannot be used. This is worth doing on systems that have "holes" in -- address space, so sbrk cannot extend to give contiguous space, but -- space is available elsewhere. Note that we ignore mmap max count -- and threshold limits, since the space will not be used as a -- segregated mmap region. -- */ -+ If have mmap, try using it as a backup when MORECORE fails or -+ cannot be used. This is worth doing on systems that have "holes" in -+ address space, so sbrk cannot extend to give contiguous space, but -+ space is available elsewhere. Note that we ignore mmap max count -+ and threshold limits, since the space will not be used as a -+ segregated mmap region. -+ */ - - if (brk == (char*)(MORECORE_FAILURE)) { - -- /* Cannot merge with old top, so add its size back in */ -- if (contiguous(av)) -- size = (size + old_size + pagemask) & ~pagemask; -- -- /* If we are relying on mmap as backup, then use larger units */ -- if ((unsigned long)(size) < (unsigned long)(MMAP_AS_MORECORE_SIZE)) -- size = MMAP_AS_MORECORE_SIZE; -- -- /* Don't try if size wraps around 0 */ -- if ((unsigned long)(size) > (unsigned long)(nb)) { -- -- brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE)); -- -- if (brk != (char*)(MORECORE_FAILURE)) { -- -- /* We do not need, and cannot use, another sbrk call to find end */ -- snd_brk = brk + size; -- -- /* Record that we no longer have a contiguous sbrk region. -- After the first time mmap is used as backup, we do not -- ever rely on contiguous space since this could incorrectly -- bridge regions. -- */ -- set_noncontiguous(av); -- } -- } -+ /* Cannot merge with old top, so add its size back in */ -+ if (contiguous(av)) -+ size = (size + old_size + pagemask) & ~pagemask; -+ -+ /* If we are relying on mmap as backup, then use larger units */ -+ if ((unsigned long)(size) < (unsigned long)(MMAP_AS_MORECORE_SIZE)) -+ size = MMAP_AS_MORECORE_SIZE; -+ -+ /* Don't try if size wraps around 0 */ -+ if ((unsigned long)(size) > (unsigned long)(nb)) { -+ -+ brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE)); -+ -+ if (brk != (char*)(MORECORE_FAILURE)) { -+ -+ /* We do not need, and cannot use, another sbrk call to find end */ -+ snd_brk = brk + size; -+ -+ /* Record that we no longer have a contiguous sbrk region. -+ After the first time mmap is used as backup, we do not -+ ever rely on contiguous space since this could incorrectly -+ bridge regions. -+ */ -+ set_noncontiguous(av); -+ } -+ } - } - - if (brk != (char*)(MORECORE_FAILURE)) { -- av->sbrked_mem += size; -+ av->sbrked_mem += size; - -- /* -- If MORECORE extends previous space, we can likewise extend top size. -- */ -- -- if (brk == old_end && snd_brk == (char*)(MORECORE_FAILURE)) { -- set_head(old_top, (size + old_size) | PREV_INUSE); -- } -- -- /* -- Otherwise, make adjustments: -- -- * If the first time through or noncontiguous, we need to call sbrk -- just to find out where the end of memory lies. -- -- * We need to ensure that all returned chunks from malloc will meet -- MALLOC_ALIGNMENT -- -- * If there was an intervening foreign sbrk, we need to adjust sbrk -- request size to account for fact that we will not be able to -- combine new space with existing space in old_top. -- -- * Almost all systems internally allocate whole pages at a time, in -- which case we might as well use the whole last page of request. -- So we allocate enough more memory to hit a page boundary now, -- which in turn causes future contiguous calls to page-align. -- */ -- -- else { -- front_misalign = 0; -- end_misalign = 0; -- correction = 0; -- aligned_brk = brk; -- -- /* -- If MORECORE returns an address lower than we have seen before, -- we know it isn't really contiguous. This and some subsequent -- checks help cope with non-conforming MORECORE functions and -- the presence of "foreign" calls to MORECORE from outside of -- malloc or by other threads. We cannot guarantee to detect -- these in all cases, but cope with the ones we do detect. -- */ -- if (contiguous(av) && old_size != 0 && brk < old_end) { -- set_noncontiguous(av); -- } -- -- /* handle contiguous cases */ -- if (contiguous(av)) { -- -- /* We can tolerate forward non-contiguities here (usually due -- to foreign calls) but treat them as part of our space for -- stats reporting. */ -- if (old_size != 0) -- av->sbrked_mem += brk - old_end; -- -- /* Guarantee alignment of first new chunk made from this space */ -- -- front_misalign = (size_t)chunk2mem(brk) & MALLOC_ALIGN_MASK; -- if (front_misalign > 0) { -- -- /* -- Skip over some bytes to arrive at an aligned position. -- We don't need to specially mark these wasted front bytes. -- They will never be accessed anyway because -- prev_inuse of av->top (and any chunk created from its start) -- is always true after initialization. -- */ -+ /* -+ If MORECORE extends previous space, we can likewise extend top size. -+ */ - -- correction = MALLOC_ALIGNMENT - front_misalign; -- aligned_brk += correction; -+ if (brk == old_end && snd_brk == (char*)(MORECORE_FAILURE)) { -+ set_head(old_top, (size + old_size) | PREV_INUSE); - } - - /* -- If this isn't adjacent to existing space, then we will not -- be able to merge with old_top space, so must add to 2nd request. -- */ -- -- correction += old_size; -- -- /* Extend the end address to hit a page boundary */ -- end_misalign = (size_t)(brk + size + correction); -- correction += ((end_misalign + pagemask) & ~pagemask) - end_misalign; -- -- assert(correction >= 0); -- snd_brk = (char*)(MORECORE(correction)); -- -- if (snd_brk == (char*)(MORECORE_FAILURE)) { -- /* -- If can't allocate correction, try to at least find out current -- brk. It might be enough to proceed without failing. -- */ -- correction = 0; -- snd_brk = (char*)(MORECORE(0)); -- } -- else if (snd_brk < brk) { -- /* -- If the second call gives noncontiguous space even though -- it says it won't, the only course of action is to ignore -- results of second call, and conservatively estimate where -- the first call left us. Also set noncontiguous, so this -- won't happen again, leaving at most one hole. -- -- Note that this check is intrinsically incomplete. Because -- MORECORE is allowed to give more space than we ask for, -- there is no reliable way to detect a noncontiguity -- producing a forward gap for the second call. -- */ -- snd_brk = brk + size; -- correction = 0; -- set_noncontiguous(av); -- } -- -- } -- -- /* handle non-contiguous cases */ -- else { -- /* MORECORE/mmap must correctly align */ -- assert(aligned_OK(chunk2mem(brk))); -- -- /* Find out current end of memory */ -- if (snd_brk == (char*)(MORECORE_FAILURE)) { -- snd_brk = (char*)(MORECORE(0)); -- av->sbrked_mem += snd_brk - brk - size; -- } -- } -- -- /* Adjust top based on results of second sbrk */ -- if (snd_brk != (char*)(MORECORE_FAILURE)) { -- av->top = (mchunkptr)aligned_brk; -- set_head(av->top, (snd_brk - aligned_brk + correction) | PREV_INUSE); -- av->sbrked_mem += correction; -+ Otherwise, make adjustments: - -- /* -- If not the first time through, we either have a -- gap due to foreign sbrk or a non-contiguous region. Insert a -- double fencepost at old_top to prevent consolidation with space -- we don't own. These fenceposts are artificial chunks that are -- marked as inuse and are in any case too small to use. We need -- two to make sizes and alignments work out. -- */ -- -- if (old_size != 0) { -- /* Shrink old_top to insert fenceposts, keeping size a -- multiple of MALLOC_ALIGNMENT. We know there is at least -- enough space in old_top to do this. -- */ -- old_size = (old_size - 3*(sizeof(size_t))) & ~MALLOC_ALIGN_MASK; -- set_head(old_top, old_size | PREV_INUSE); -- -- /* -- Note that the following assignments completely overwrite -- old_top when old_size was previously MINSIZE. This is -- intentional. We need the fencepost, even if old_top otherwise gets -- lost. -- */ -- chunk_at_offset(old_top, old_size )->size = -- (sizeof(size_t))|PREV_INUSE; -- -- chunk_at_offset(old_top, old_size + (sizeof(size_t)))->size = -- (sizeof(size_t))|PREV_INUSE; -- -- /* If possible, release the rest, suppressing trimming. */ -- if (old_size >= MINSIZE) { -- size_t tt = av->trim_threshold; -- av->trim_threshold = (size_t)(-1); -- free(chunk2mem(old_top)); -- av->trim_threshold = tt; -- } -- } -- } -- } -- -- /* Update statistics */ -- sum = av->sbrked_mem; -- if (sum > (unsigned long)(av->max_sbrked_mem)) -- av->max_sbrked_mem = sum; -- -- sum += av->mmapped_mem; -- if (sum > (unsigned long)(av->max_total_mem)) -- av->max_total_mem = sum; -- -- check_malloc_state(); -- -- /* finally, do the allocation */ -- -- p = av->top; -- size = chunksize(p); -- -- /* check that one of the above allocation paths succeeded */ -- if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) { -- remainder_size = size - nb; -- remainder = chunk_at_offset(p, nb); -- av->top = remainder; -- set_head(p, nb | PREV_INUSE); -- set_head(remainder, remainder_size | PREV_INUSE); -- check_malloced_chunk(p, nb); -- return chunk2mem(p); -- } -+ * If the first time through or noncontiguous, we need to call sbrk -+ just to find out where the end of memory lies. -+ -+ * We need to ensure that all returned chunks from malloc will meet -+ MALLOC_ALIGNMENT -+ -+ * If there was an intervening foreign sbrk, we need to adjust sbrk -+ request size to account for fact that we will not be able to -+ combine new space with existing space in old_top. -+ -+ * Almost all systems internally allocate whole pages at a time, in -+ which case we might as well use the whole last page of request. -+ So we allocate enough more memory to hit a page boundary now, -+ which in turn causes future contiguous calls to page-align. -+ */ -+ -+ else { -+ front_misalign = 0; -+ end_misalign = 0; -+ correction = 0; -+ aligned_brk = brk; -+ -+ /* -+ If MORECORE returns an address lower than we have seen before, -+ we know it isn't really contiguous. This and some subsequent -+ checks help cope with non-conforming MORECORE functions and -+ the presence of "foreign" calls to MORECORE from outside of -+ malloc or by other threads. We cannot guarantee to detect -+ these in all cases, but cope with the ones we do detect. -+ */ -+ if (contiguous(av) && old_size != 0 && brk < old_end) { -+ set_noncontiguous(av); -+ } -+ -+ /* handle contiguous cases */ -+ if (contiguous(av)) { -+ -+ /* We can tolerate forward non-contiguities here (usually due -+ to foreign calls) but treat them as part of our space for -+ stats reporting. */ -+ if (old_size != 0) -+ av->sbrked_mem += brk - old_end; -+ -+ /* Guarantee alignment of first new chunk made from this space */ -+ -+ front_misalign = (size_t)chunk2mem(brk) & MALLOC_ALIGN_MASK; -+ if (front_misalign > 0) { -+ -+ /* -+ Skip over some bytes to arrive at an aligned position. -+ We don't need to specially mark these wasted front bytes. -+ They will never be accessed anyway because -+ prev_inuse of av->top (and any chunk created from its start) -+ is always true after initialization. -+ */ -+ -+ correction = MALLOC_ALIGNMENT - front_misalign; -+ aligned_brk += correction; -+ } -+ -+ /* -+ If this isn't adjacent to existing space, then we will not -+ be able to merge with old_top space, so must add to 2nd request. -+ */ -+ -+ correction += old_size; -+ -+ /* Extend the end address to hit a page boundary */ -+ end_misalign = (size_t)(brk + size + correction); -+ correction += ((end_misalign + pagemask) & ~pagemask) - end_misalign; -+ -+ assert(correction >= 0); -+ snd_brk = (char*)(MORECORE(correction)); -+ -+ if (snd_brk == (char*)(MORECORE_FAILURE)) { -+ /* -+ If can't allocate correction, try to at least find out current -+ brk. It might be enough to proceed without failing. -+ */ -+ correction = 0; -+ snd_brk = (char*)(MORECORE(0)); -+ } -+ else if (snd_brk < brk) { -+ /* -+ If the second call gives noncontiguous space even though -+ it says it won't, the only course of action is to ignore -+ results of second call, and conservatively estimate where -+ the first call left us. Also set noncontiguous, so this -+ won't happen again, leaving at most one hole. -+ -+ Note that this check is intrinsically incomplete. Because -+ MORECORE is allowed to give more space than we ask for, -+ there is no reliable way to detect a noncontiguity -+ producing a forward gap for the second call. -+ */ -+ snd_brk = brk + size; -+ correction = 0; -+ set_noncontiguous(av); -+ } -+ -+ } -+ -+ /* handle non-contiguous cases */ -+ else { -+ /* MORECORE/mmap must correctly align */ -+ assert(aligned_OK(chunk2mem(brk))); -+ -+ /* Find out current end of memory */ -+ if (snd_brk == (char*)(MORECORE_FAILURE)) { -+ snd_brk = (char*)(MORECORE(0)); -+ av->sbrked_mem += snd_brk - brk - size; -+ } -+ } -+ -+ /* Adjust top based on results of second sbrk */ -+ if (snd_brk != (char*)(MORECORE_FAILURE)) { -+ av->top = (mchunkptr)aligned_brk; -+ set_head(av->top, (snd_brk - aligned_brk + correction) | PREV_INUSE); -+ av->sbrked_mem += correction; -+ -+ /* -+ If not the first time through, we either have a -+ gap due to foreign sbrk or a non-contiguous region. Insert a -+ double fencepost at old_top to prevent consolidation with space -+ we don't own. These fenceposts are artificial chunks that are -+ marked as inuse and are in any case too small to use. We need -+ two to make sizes and alignments work out. -+ */ -+ -+ if (old_size != 0) { -+ /* Shrink old_top to insert fenceposts, keeping size a -+ multiple of MALLOC_ALIGNMENT. We know there is at least -+ enough space in old_top to do this. -+ */ -+ old_size = (old_size - 3*(sizeof(size_t))) & ~MALLOC_ALIGN_MASK; -+ set_head(old_top, old_size | PREV_INUSE); -+ -+ /* -+ Note that the following assignments completely overwrite -+ old_top when old_size was previously MINSIZE. This is -+ intentional. We need the fencepost, even if old_top otherwise gets -+ lost. -+ */ -+ chunk_at_offset(old_top, old_size )->size = -+ (sizeof(size_t))|PREV_INUSE; -+ -+ chunk_at_offset(old_top, old_size + (sizeof(size_t)))->size = -+ (sizeof(size_t))|PREV_INUSE; -+ -+ /* If possible, release the rest, suppressing trimming. */ -+ if (old_size >= MINSIZE) { -+ size_t tt = av->trim_threshold; -+ av->trim_threshold = (size_t)(-1); -+ free(chunk2mem(old_top)); -+ av->trim_threshold = tt; -+ } -+ } -+ } -+ } -+ -+ /* Update statistics */ -+ sum = av->sbrked_mem; -+ if (sum > (unsigned long)(av->max_sbrked_mem)) -+ av->max_sbrked_mem = sum; -+ -+ sum += av->mmapped_mem; -+ if (sum > (unsigned long)(av->max_total_mem)) -+ av->max_total_mem = sum; -+ -+ check_malloc_state(); -+ -+ /* finally, do the allocation */ -+ -+ p = av->top; -+ size = chunksize(p); -+ -+ /* check that one of the above allocation paths succeeded */ -+ if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) { -+ remainder_size = size - nb; -+ remainder = chunk_at_offset(p, nb); -+ av->top = remainder; -+ set_head(p, nb | PREV_INUSE); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ check_malloced_chunk(p, nb); -+ return chunk2mem(p); -+ } - - } - -@@ -767,25 +764,25 @@ static int __malloc_largebin_index(unsig - #if defined(__GNUC__) && defined(i386) - - __asm__("bsrl %1,%0\n\t" -- : "=r" (m) -- : "g" (x)); -+ : "=r" (m) -+ : "g" (x)); - - #else - { -- /* -- Based on branch-free nlz algorithm in chapter 5 of Henry -- S. Warren Jr's book "Hacker's Delight". -- */ -- -- unsigned int n = ((x - 0x100) >> 16) & 8; -- x <<= n; -- m = ((x - 0x1000) >> 16) & 4; -- n += m; -- x <<= m; -- m = ((x - 0x4000) >> 16) & 2; -- n += m; -- x = (x << m) >> 14; -- m = 13 - n + (x & ~(x>>1)); -+ /* -+ Based on branch-free nlz algorithm in chapter 5 of Henry -+ S. Warren Jr's book "Hacker's Delight". -+ */ -+ -+ unsigned int n = ((x - 0x100) >> 16) & 8; -+ x <<= n; -+ m = ((x - 0x1000) >> 16) & 4; -+ n += m; -+ x <<= m; -+ m = ((x - 0x4000) >> 16) & 2; -+ n += m; -+ x = (x << m) >> 14; -+ m = 13 - n + (x & ~(x>>1)); - } - #endif - -@@ -826,69 +823,70 @@ void* malloc(size_t bytes) - mchunkptr fwd; /* misc temp for linking */ - mchunkptr bck; /* misc temp for linking */ - void * sysmem; -+ void * retval; - - #if !defined(__MALLOC_GLIBC_COMPAT__) - if (!bytes) return NULL; - #endif - -- LOCK; -+ __MALLOC_LOCK; - av = get_malloc_state(); - /* -- Convert request size to internal form by adding (sizeof(size_t)) bytes -- overhead plus possibly more to obtain necessary alignment and/or -- to obtain a size of at least MINSIZE, the smallest allocatable -- size. Also, checked_request2size traps (returning 0) request sizes -- that are so large that they wrap around zero when padded and -- aligned. -- */ -+ Convert request size to internal form by adding (sizeof(size_t)) bytes -+ overhead plus possibly more to obtain necessary alignment and/or -+ to obtain a size of at least MINSIZE, the smallest allocatable -+ size. Also, checked_request2size traps (returning 0) request sizes -+ that are so large that they wrap around zero when padded and -+ aligned. -+ */ - - checked_request2size(bytes, nb); - - /* -- Bypass search if no frees yet -- */ -+ Bypass search if no frees yet -+ */ - if (!have_anychunks(av)) { -- if (av->max_fast == 0) /* initialization check */ -- __malloc_consolidate(av); -- goto use_top; -+ if (av->max_fast == 0) /* initialization check */ -+ __malloc_consolidate(av); -+ goto use_top; - } - - /* -- If the size qualifies as a fastbin, first check corresponding bin. -- */ -+ If the size qualifies as a fastbin, first check corresponding bin. -+ */ - - if ((unsigned long)(nb) <= (unsigned long)(av->max_fast)) { -- fb = &(av->fastbins[(fastbin_index(nb))]); -- if ( (victim = *fb) != 0) { -- *fb = victim->fd; -- check_remalloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -+ fb = &(av->fastbins[(fastbin_index(nb))]); -+ if ( (victim = *fb) != 0) { -+ *fb = victim->fd; -+ check_remalloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } - } - - /* -- If a small request, check regular bin. Since these "smallbins" -- hold one size each, no searching within bins is necessary. -- (For a large request, we need to wait until unsorted chunks are -- processed to find best fit. But for small ones, fits are exact -- anyway, so we can check now, which is faster.) -- */ -+ If a small request, check regular bin. Since these "smallbins" -+ hold one size each, no searching within bins is necessary. -+ (For a large request, we need to wait until unsorted chunks are -+ processed to find best fit. But for small ones, fits are exact -+ anyway, so we can check now, which is faster.) -+ */ - - if (in_smallbin_range(nb)) { -- idx = smallbin_index(nb); -- bin = bin_at(av,idx); -+ idx = smallbin_index(nb); -+ bin = bin_at(av,idx); - -- if ( (victim = last(bin)) != bin) { -- bck = victim->bk; -- set_inuse_bit_at_offset(victim, nb); -- bin->bk = bck; -- bck->fd = bin; -- -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -+ if ( (victim = last(bin)) != bin) { -+ bck = victim->bk; -+ set_inuse_bit_at_offset(victim, nb); -+ bin->bk = bck; -+ bck->fd = bin; -+ -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } - } - - /* If this is a large request, consolidate fastbins before continuing. -@@ -899,154 +897,154 @@ void* malloc(size_t bytes) - large requests, but less often mixtures, so consolidation is not - invoked all that often in most programs. And the programs that - it is called frequently in otherwise tend to fragment. -- */ -+ */ - - else { -- idx = __malloc_largebin_index(nb); -- if (have_fastchunks(av)) -- __malloc_consolidate(av); -+ idx = __malloc_largebin_index(nb); -+ if (have_fastchunks(av)) -+ __malloc_consolidate(av); - } - - /* -- Process recently freed or remaindered chunks, taking one only if -- it is exact fit, or, if this a small request, the chunk is remainder from -- the most recent non-exact fit. Place other traversed chunks in -- bins. Note that this step is the only place in any routine where -- chunks are placed in bins. -- */ -+ Process recently freed or remaindered chunks, taking one only if -+ it is exact fit, or, if this a small request, the chunk is remainder from -+ the most recent non-exact fit. Place other traversed chunks in -+ bins. Note that this step is the only place in any routine where -+ chunks are placed in bins. -+ */ - - while ( (victim = unsorted_chunks(av)->bk) != unsorted_chunks(av)) { -- bck = victim->bk; -- size = chunksize(victim); -+ bck = victim->bk; -+ size = chunksize(victim); -+ -+ /* If a small request, try to use last remainder if it is the -+ only chunk in unsorted bin. This helps promote locality for -+ runs of consecutive small requests. This is the only -+ exception to best-fit, and applies only when there is -+ no exact fit for a small chunk. -+ */ -+ -+ if (in_smallbin_range(nb) && -+ bck == unsorted_chunks(av) && -+ victim == av->last_remainder && -+ (unsigned long)(size) > (unsigned long)(nb + MINSIZE)) { -+ -+ /* split and reattach remainder */ -+ remainder_size = size - nb; -+ remainder = chunk_at_offset(victim, nb); -+ unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; -+ av->last_remainder = remainder; -+ remainder->bk = remainder->fd = unsorted_chunks(av); -+ -+ set_head(victim, nb | PREV_INUSE); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ set_foot(remainder, remainder_size); -+ -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } -+ -+ /* remove from unsorted list */ -+ unsorted_chunks(av)->bk = bck; -+ bck->fd = unsorted_chunks(av); -+ -+ /* Take now instead of binning if exact fit */ -+ -+ if (size == nb) { -+ set_inuse_bit_at_offset(victim, size); -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } -+ -+ /* place chunk in bin */ - -- /* If a small request, try to use last remainder if it is the -- only chunk in unsorted bin. This helps promote locality for -- runs of consecutive small requests. This is the only -- exception to best-fit, and applies only when there is -- no exact fit for a small chunk. -- */ -- -- if (in_smallbin_range(nb) && -- bck == unsorted_chunks(av) && -- victim == av->last_remainder && -- (unsigned long)(size) > (unsigned long)(nb + MINSIZE)) { -- -- /* split and reattach remainder */ -- remainder_size = size - nb; -- remainder = chunk_at_offset(victim, nb); -- unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; -- av->last_remainder = remainder; -- remainder->bk = remainder->fd = unsorted_chunks(av); -- -- set_head(victim, nb | PREV_INUSE); -- set_head(remainder, remainder_size | PREV_INUSE); -- set_foot(remainder, remainder_size); -- -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -- -- /* remove from unsorted list */ -- unsorted_chunks(av)->bk = bck; -- bck->fd = unsorted_chunks(av); -- -- /* Take now instead of binning if exact fit */ -- -- if (size == nb) { -- set_inuse_bit_at_offset(victim, size); -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -- -- /* place chunk in bin */ -- -- if (in_smallbin_range(size)) { -- victim_index = smallbin_index(size); -- bck = bin_at(av, victim_index); -- fwd = bck->fd; -- } -- else { -- victim_index = __malloc_largebin_index(size); -- bck = bin_at(av, victim_index); -- fwd = bck->fd; -- -- if (fwd != bck) { -- /* if smaller than smallest, place first */ -- if ((unsigned long)(size) < (unsigned long)(bck->bk->size)) { -- fwd = bck; -- bck = bck->bk; -- } -- else if ((unsigned long)(size) >= -- (unsigned long)(FIRST_SORTED_BIN_SIZE)) { -- -- /* maintain large bins in sorted order */ -- size |= PREV_INUSE; /* Or with inuse bit to speed comparisons */ -- while ((unsigned long)(size) < (unsigned long)(fwd->size)) -- fwd = fwd->fd; -- bck = fwd->bk; -- } -- } -- } -- -- mark_bin(av, victim_index); -- victim->bk = bck; -- victim->fd = fwd; -- fwd->bk = victim; -- bck->fd = victim; -+ if (in_smallbin_range(size)) { -+ victim_index = smallbin_index(size); -+ bck = bin_at(av, victim_index); -+ fwd = bck->fd; -+ } -+ else { -+ victim_index = __malloc_largebin_index(size); -+ bck = bin_at(av, victim_index); -+ fwd = bck->fd; -+ -+ if (fwd != bck) { -+ /* if smaller than smallest, place first */ -+ if ((unsigned long)(size) < (unsigned long)(bck->bk->size)) { -+ fwd = bck; -+ bck = bck->bk; -+ } -+ else if ((unsigned long)(size) >= -+ (unsigned long)(FIRST_SORTED_BIN_SIZE)) { -+ -+ /* maintain large bins in sorted order */ -+ size |= PREV_INUSE; /* Or with inuse bit to speed comparisons */ -+ while ((unsigned long)(size) < (unsigned long)(fwd->size)) -+ fwd = fwd->fd; -+ bck = fwd->bk; -+ } -+ } -+ } -+ -+ mark_bin(av, victim_index); -+ victim->bk = bck; -+ victim->fd = fwd; -+ fwd->bk = victim; -+ bck->fd = victim; - } - - /* -- If a large request, scan through the chunks of current bin to -- find one that fits. (This will be the smallest that fits unless -- FIRST_SORTED_BIN_SIZE has been changed from default.) This is -- the only step where an unbounded number of chunks might be -- scanned without doing anything useful with them. However the -- lists tend to be short. -- */ -+ If a large request, scan through the chunks of current bin to -+ find one that fits. (This will be the smallest that fits unless -+ FIRST_SORTED_BIN_SIZE has been changed from default.) This is -+ the only step where an unbounded number of chunks might be -+ scanned without doing anything useful with them. However the -+ lists tend to be short. -+ */ - - if (!in_smallbin_range(nb)) { -- bin = bin_at(av, idx); -- -- for (victim = last(bin); victim != bin; victim = victim->bk) { -- size = chunksize(victim); -+ bin = bin_at(av, idx); - -- if ((unsigned long)(size) >= (unsigned long)(nb)) { -- remainder_size = size - nb; -- unlink(victim, bck, fwd); -+ for (victim = last(bin); victim != bin; victim = victim->bk) { -+ size = chunksize(victim); - -- /* Exhaust */ -- if (remainder_size < MINSIZE) { -- set_inuse_bit_at_offset(victim, size); -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -- /* Split */ -- else { -- remainder = chunk_at_offset(victim, nb); -- unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; -- remainder->bk = remainder->fd = unsorted_chunks(av); -- set_head(victim, nb | PREV_INUSE); -- set_head(remainder, remainder_size | PREV_INUSE); -- set_foot(remainder, remainder_size); -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -+ if ((unsigned long)(size) >= (unsigned long)(nb)) { -+ remainder_size = size - nb; -+ unlink(victim, bck, fwd); -+ -+ /* Exhaust */ -+ if (remainder_size < MINSIZE) { -+ set_inuse_bit_at_offset(victim, size); -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } -+ /* Split */ -+ else { -+ remainder = chunk_at_offset(victim, nb); -+ unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; -+ remainder->bk = remainder->fd = unsorted_chunks(av); -+ set_head(victim, nb | PREV_INUSE); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ set_foot(remainder, remainder_size); -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } -+ } - } -- } -- } - } - - /* -- Search for a chunk by scanning bins, starting with next largest -- bin. This search is strictly by best-fit; i.e., the smallest -- (with ties going to approximately the least recently used) chunk -- that fits is selected. -+ Search for a chunk by scanning bins, starting with next largest -+ bin. This search is strictly by best-fit; i.e., the smallest -+ (with ties going to approximately the least recently used) chunk -+ that fits is selected. - -- The bitmap avoids needing to check that most blocks are nonempty. -- */ -+ The bitmap avoids needing to check that most blocks are nonempty. -+ */ - - ++idx; - bin = bin_at(av,idx); -@@ -1056,109 +1054,111 @@ void* malloc(size_t bytes) - - for (;;) { - -- /* Skip rest of block if there are no more set bits in this block. */ -- if (bit > map || bit == 0) { -- do { -- if (++block >= BINMAPSIZE) /* out of bins */ -- goto use_top; -- } while ( (map = av->binmap[block]) == 0); -- -- bin = bin_at(av, (block << BINMAPSHIFT)); -- bit = 1; -- } -- -- /* Advance to bin with set bit. There must be one. */ -- while ((bit & map) == 0) { -- bin = next_bin(bin); -- bit <<= 1; -- assert(bit != 0); -- } -- -- /* Inspect the bin. It is likely to be non-empty */ -- victim = last(bin); -- -- /* If a false alarm (empty bin), clear the bit. */ -- if (victim == bin) { -- av->binmap[block] = map &= ~bit; /* Write through */ -- bin = next_bin(bin); -- bit <<= 1; -- } -- -- else { -- size = chunksize(victim); -- -- /* We know the first chunk in this bin is big enough to use. */ -- assert((unsigned long)(size) >= (unsigned long)(nb)); -- -- remainder_size = size - nb; -- -- /* unlink */ -- bck = victim->bk; -- bin->bk = bck; -- bck->fd = bin; -- -- /* Exhaust */ -- if (remainder_size < MINSIZE) { -- set_inuse_bit_at_offset(victim, size); -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -+ /* Skip rest of block if there are no more set bits in this block. */ -+ if (bit > map || bit == 0) { -+ do { -+ if (++block >= BINMAPSIZE) /* out of bins */ -+ goto use_top; -+ } while ( (map = av->binmap[block]) == 0); - -- /* Split */ -- else { -- remainder = chunk_at_offset(victim, nb); -+ bin = bin_at(av, (block << BINMAPSHIFT)); -+ bit = 1; -+ } - -- unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; -- remainder->bk = remainder->fd = unsorted_chunks(av); -- /* advertise as last remainder */ -- if (in_smallbin_range(nb)) -- av->last_remainder = remainder; -+ /* Advance to bin with set bit. There must be one. */ -+ while ((bit & map) == 0) { -+ bin = next_bin(bin); -+ bit <<= 1; -+ assert(bit != 0); -+ } - -- set_head(victim, nb | PREV_INUSE); -- set_head(remainder, remainder_size | PREV_INUSE); -- set_foot(remainder, remainder_size); -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -- } -+ /* Inspect the bin. It is likely to be non-empty */ -+ victim = last(bin); -+ -+ /* If a false alarm (empty bin), clear the bit. */ -+ if (victim == bin) { -+ av->binmap[block] = map &= ~bit; /* Write through */ -+ bin = next_bin(bin); -+ bit <<= 1; -+ } -+ -+ else { -+ size = chunksize(victim); -+ -+ /* We know the first chunk in this bin is big enough to use. */ -+ assert((unsigned long)(size) >= (unsigned long)(nb)); -+ -+ remainder_size = size - nb; -+ -+ /* unlink */ -+ bck = victim->bk; -+ bin->bk = bck; -+ bck->fd = bin; -+ -+ /* Exhaust */ -+ if (remainder_size < MINSIZE) { -+ set_inuse_bit_at_offset(victim, size); -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } -+ -+ /* Split */ -+ else { -+ remainder = chunk_at_offset(victim, nb); -+ -+ unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; -+ remainder->bk = remainder->fd = unsorted_chunks(av); -+ /* advertise as last remainder */ -+ if (in_smallbin_range(nb)) -+ av->last_remainder = remainder; -+ -+ set_head(victim, nb | PREV_INUSE); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ set_foot(remainder, remainder_size); -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } -+ } - } - --use_top: -+ use_top: - /* -- If large enough, split off the chunk bordering the end of memory -- (held in av->top). Note that this is in accord with the best-fit -- search rule. In effect, av->top is treated as larger (and thus -- less well fitting) than any other available chunk since it can -- be extended to be as large as necessary (up to system -- limitations). -- -- We require that av->top always exists (i.e., has size >= -- MINSIZE) after initialization, so if it would otherwise be -- exhuasted by current request, it is replenished. (The main -- reason for ensuring it exists is that we may need MINSIZE space -- to put in fenceposts in sysmalloc.) -- */ -+ If large enough, split off the chunk bordering the end of memory -+ (held in av->top). Note that this is in accord with the best-fit -+ search rule. In effect, av->top is treated as larger (and thus -+ less well fitting) than any other available chunk since it can -+ be extended to be as large as necessary (up to system -+ limitations). -+ -+ We require that av->top always exists (i.e., has size >= -+ MINSIZE) after initialization, so if it would otherwise be -+ exhuasted by current request, it is replenished. (The main -+ reason for ensuring it exists is that we may need MINSIZE space -+ to put in fenceposts in sysmalloc.) -+ */ - - victim = av->top; - size = chunksize(victim); - - if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) { -- remainder_size = size - nb; -- remainder = chunk_at_offset(victim, nb); -- av->top = remainder; -- set_head(victim, nb | PREV_INUSE); -- set_head(remainder, remainder_size | PREV_INUSE); -- -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -+ remainder_size = size - nb; -+ remainder = chunk_at_offset(victim, nb); -+ av->top = remainder; -+ set_head(victim, nb | PREV_INUSE); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; - } - - /* If no space in top, relay to handle system-dependent cases */ - sysmem = __malloc_alloc(nb, av); -- UNLOCK; -- return sysmem; -+ retval = sysmem; -+ DONE: -+ __MALLOC_UNLOCK; -+ return retval; - } - -diff --git a/libc/stdlib/malloc-standard/malloc.h b/libc/stdlib/malloc-standard/malloc.h -index fbc1492..14a0dd9 100644 ---- a/libc/stdlib/malloc-standard/malloc.h -+++ b/libc/stdlib/malloc-standard/malloc.h -@@ -22,16 +22,12 @@ - #include <malloc.h> - #include <stdlib.h> - -+#include <bits/uClibc_mutex.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --extern pthread_mutex_t __malloc_lock; --# define LOCK __pthread_mutex_lock(&__malloc_lock) --# define UNLOCK __pthread_mutex_unlock(&__malloc_lock); --#else --# define LOCK --# define UNLOCK --#endif -+__UCLIBC_MUTEX_EXTERN(__malloc_lock); -+ -+#define __MALLOC_LOCK __UCLIBC_MUTEX_LOCK(__malloc_lock) -+#define __MALLOC_UNLOCK __UCLIBC_MUTEX_UNLOCK(__malloc_lock) - - - -diff --git a/libc/stdlib/malloc-standard/mallopt.c b/libc/stdlib/malloc-standard/mallopt.c -index e287920..41aa614 100644 ---- a/libc/stdlib/malloc-standard/mallopt.c -+++ b/libc/stdlib/malloc-standard/mallopt.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -25,40 +25,40 @@ int mallopt(int param_number, int value) - - ret = 0; - -- LOCK; -+ __MALLOC_LOCK; - av = get_malloc_state(); - /* Ensure initialization/consolidation */ - __malloc_consolidate(av); - - switch(param_number) { -- case M_MXFAST: -- if (value >= 0 && value <= MAX_FAST_SIZE) { -- set_max_fast(av, value); -- ret = 1; -- } -- break; -- -- case M_TRIM_THRESHOLD: -- av->trim_threshold = value; -- ret = 1; -- break; -- -- case M_TOP_PAD: -- av->top_pad = value; -- ret = 1; -- break; -- -- case M_MMAP_THRESHOLD: -- av->mmap_threshold = value; -- ret = 1; -- break; -- -- case M_MMAP_MAX: -- av->n_mmaps_max = value; -- ret = 1; -- break; -+ case M_MXFAST: -+ if (value >= 0 && value <= MAX_FAST_SIZE) { -+ set_max_fast(av, value); -+ ret = 1; -+ } -+ break; -+ -+ case M_TRIM_THRESHOLD: -+ av->trim_threshold = value; -+ ret = 1; -+ break; -+ -+ case M_TOP_PAD: -+ av->top_pad = value; -+ ret = 1; -+ break; -+ -+ case M_MMAP_THRESHOLD: -+ av->mmap_threshold = value; -+ ret = 1; -+ break; -+ -+ case M_MMAP_MAX: -+ av->n_mmaps_max = value; -+ ret = 1; -+ break; - } -- UNLOCK; -+ __MALLOC_UNLOCK; - return ret; - } - -diff --git a/libc/stdlib/malloc-standard/memalign.c b/libc/stdlib/malloc-standard/memalign.c -index bd95362..e78d752 100644 ---- a/libc/stdlib/malloc-standard/memalign.c -+++ b/libc/stdlib/malloc-standard/memalign.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -35,6 +35,7 @@ void* memalign(size_t alignment, size_t - mchunkptr remainder; /* spare room at end to split off */ - unsigned long remainder_size; /* its size */ - size_t size; -+ void *retval; - - /* If need less alignment than we give anyway, just relay to malloc */ - -@@ -46,12 +47,12 @@ void* memalign(size_t alignment, size_t - - /* Make sure alignment is power of 2 (in case MINSIZE is not). */ - if ((alignment & (alignment - 1)) != 0) { -- size_t a = MALLOC_ALIGNMENT * 2; -- while ((unsigned long)a < (unsigned long)alignment) a <<= 1; -- alignment = a; -+ size_t a = MALLOC_ALIGNMENT * 2; -+ while ((unsigned long)a < (unsigned long)alignment) a <<= 1; -+ alignment = a; - } - -- LOCK; -+ __MALLOC_LOCK; - checked_request2size(bytes, nb); - - /* Strategy: find a spot within that chunk that meets the alignment -@@ -63,64 +64,67 @@ void* memalign(size_t alignment, size_t - m = (char*)(malloc(nb + alignment + MINSIZE)); - - if (m == 0) { -- UNLOCK; -- return 0; /* propagate failure */ -+ retval = 0; /* propagate failure */ -+ goto DONE; - } - - p = mem2chunk(m); - - if ((((unsigned long)(m)) % alignment) != 0) { /* misaligned */ - -- /* -- Find an aligned spot inside chunk. Since we need to give back -- leading space in a chunk of at least MINSIZE, if the first -- calculation places us at a spot with less than MINSIZE leader, -- we can move to the next aligned spot -- we've allocated enough -- total room so that this is always possible. -- */ -- -- brk = (char*)mem2chunk((unsigned long)(((unsigned long)(m + alignment - 1)) & -- -((signed long) alignment))); -- if ((unsigned long)(brk - (char*)(p)) < MINSIZE) -- brk += alignment; -- -- newp = (mchunkptr)brk; -- leadsize = brk - (char*)(p); -- newsize = chunksize(p) - leadsize; -- -- /* For mmapped chunks, just adjust offset */ -- if (chunk_is_mmapped(p)) { -- newp->prev_size = p->prev_size + leadsize; -- set_head(newp, newsize|IS_MMAPPED); -- UNLOCK; -- return chunk2mem(newp); -- } -- -- /* Otherwise, give back leader, use the rest */ -- set_head(newp, newsize | PREV_INUSE); -- set_inuse_bit_at_offset(newp, newsize); -- set_head_size(p, leadsize); -- free(chunk2mem(p)); -- p = newp; -+ /* -+ Find an aligned spot inside chunk. Since we need to give back -+ leading space in a chunk of at least MINSIZE, if the first -+ calculation places us at a spot with less than MINSIZE leader, -+ we can move to the next aligned spot -- we've allocated enough -+ total room so that this is always possible. -+ */ -+ -+ brk = (char*)mem2chunk((unsigned long)(((unsigned long)(m + alignment - 1)) & -+ -((signed long) alignment))); -+ if ((unsigned long)(brk - (char*)(p)) < MINSIZE) -+ brk += alignment; -+ -+ newp = (mchunkptr)brk; -+ leadsize = brk - (char*)(p); -+ newsize = chunksize(p) - leadsize; -+ -+ /* For mmapped chunks, just adjust offset */ -+ if (chunk_is_mmapped(p)) { -+ newp->prev_size = p->prev_size + leadsize; -+ set_head(newp, newsize|IS_MMAPPED); -+ retval = chunk2mem(newp); -+ goto DONE; -+ } -+ -+ /* Otherwise, give back leader, use the rest */ -+ set_head(newp, newsize | PREV_INUSE); -+ set_inuse_bit_at_offset(newp, newsize); -+ set_head_size(p, leadsize); -+ free(chunk2mem(p)); -+ p = newp; - -- assert (newsize >= nb && -- (((unsigned long)(chunk2mem(p))) % alignment) == 0); -+ assert (newsize >= nb && -+ (((unsigned long)(chunk2mem(p))) % alignment) == 0); - } - - /* Also give back spare room at the end */ - if (!chunk_is_mmapped(p)) { -- size = chunksize(p); -- if ((unsigned long)(size) > (unsigned long)(nb + MINSIZE)) { -- remainder_size = size - nb; -- remainder = chunk_at_offset(p, nb); -- set_head(remainder, remainder_size | PREV_INUSE); -- set_head_size(p, nb); -- free(chunk2mem(remainder)); -- } -+ size = chunksize(p); -+ if ((unsigned long)(size) > (unsigned long)(nb + MINSIZE)) { -+ remainder_size = size - nb; -+ remainder = chunk_at_offset(p, nb); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ set_head_size(p, nb); -+ free(chunk2mem(remainder)); -+ } - } - - check_inuse_chunk(p); -- UNLOCK; -- return chunk2mem(p); -+ retval = chunk2mem(p); -+ -+ DONE: -+ __MALLOC_UNLOCK; -+ return retval; - } - -diff --git a/libc/stdlib/malloc-standard/realloc.c b/libc/stdlib/malloc-standard/realloc.c -index 1950130..9ca4b26 100644 ---- a/libc/stdlib/malloc-standard/realloc.c -+++ b/libc/stdlib/malloc-standard/realloc.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -23,14 +23,14 @@ void* realloc(void* oldmem, size_t bytes - { - mstate av; - -- size_t nb; /* padded request size */ -+ size_t nb; /* padded request size */ - - mchunkptr oldp; /* chunk corresponding to oldmem */ -- size_t oldsize; /* its size */ -+ size_t oldsize; /* its size */ - - mchunkptr newp; /* chunk to return */ -- size_t newsize; /* its size */ -- void* newmem; /* corresponding user mem */ -+ size_t newsize; /* its size */ -+ void* newmem; /* corresponding user mem */ - - mchunkptr next; /* next contiguous chunk after oldp */ - -@@ -40,21 +40,23 @@ void* realloc(void* oldmem, size_t bytes - mchunkptr bck; /* misc temp for linking */ - mchunkptr fwd; /* misc temp for linking */ - -- unsigned long copysize; /* bytes to copy */ -+ unsigned long copysize; /* bytes to copy */ - unsigned int ncopies; /* size_t words to copy */ -- size_t* s; /* copy source */ -- size_t* d; /* copy destination */ -+ size_t* s; /* copy source */ -+ size_t* d; /* copy destination */ -+ -+ void *retval; - - - /* Check for special cases. */ - if (! oldmem) -- return malloc(bytes); -+ return malloc(bytes); - if (! bytes) { -- free (oldmem); -- return malloc(bytes); -+ free (oldmem); -+ return malloc(bytes); - } - -- LOCK; -+ __MALLOC_LOCK; - av = get_malloc_state(); - checked_request2size(bytes, nb); - -@@ -65,173 +67,176 @@ void* realloc(void* oldmem, size_t bytes - - if (!chunk_is_mmapped(oldp)) { - -- if ((unsigned long)(oldsize) >= (unsigned long)(nb)) { -- /* already big enough; split below */ -- newp = oldp; -- newsize = oldsize; -- } -- -- else { -- next = chunk_at_offset(oldp, oldsize); -- -- /* Try to expand forward into top */ -- if (next == av->top && -- (unsigned long)(newsize = oldsize + chunksize(next)) >= -- (unsigned long)(nb + MINSIZE)) { -- set_head_size(oldp, nb); -- av->top = chunk_at_offset(oldp, nb); -- set_head(av->top, (newsize - nb) | PREV_INUSE); -- UNLOCK; -- return chunk2mem(oldp); -- } -- -- /* Try to expand forward into next chunk; split off remainder below */ -- else if (next != av->top && -- !inuse(next) && -- (unsigned long)(newsize = oldsize + chunksize(next)) >= -- (unsigned long)(nb)) { -- newp = oldp; -- unlink(next, bck, fwd); -- } -- -- /* allocate, copy, free */ -- else { -- newmem = malloc(nb - MALLOC_ALIGN_MASK); -- if (newmem == 0) { -- UNLOCK; -- return 0; /* propagate failure */ -- } -- -- newp = mem2chunk(newmem); -- newsize = chunksize(newp); -- -- /* -- Avoid copy if newp is next chunk after oldp. -- */ -- if (newp == next) { -- newsize += oldsize; -- newp = oldp; -+ if ((unsigned long)(oldsize) >= (unsigned long)(nb)) { -+ /* already big enough; split below */ -+ newp = oldp; -+ newsize = oldsize; - } -+ - else { -- /* -- Unroll copy of <= 36 bytes (72 if 8byte sizes) -- We know that contents have an odd number of -- size_t-sized words; minimally 3. -- */ -- -- copysize = oldsize - (sizeof(size_t)); -- s = (size_t*)(oldmem); -- d = (size_t*)(newmem); -- ncopies = copysize / sizeof(size_t); -- assert(ncopies >= 3); -- -- if (ncopies > 9) -- memcpy(d, s, copysize); -- -- else { -- *(d+0) = *(s+0); -- *(d+1) = *(s+1); -- *(d+2) = *(s+2); -- if (ncopies > 4) { -- *(d+3) = *(s+3); -- *(d+4) = *(s+4); -- if (ncopies > 6) { -- *(d+5) = *(s+5); -- *(d+6) = *(s+6); -- if (ncopies > 8) { -- *(d+7) = *(s+7); -- *(d+8) = *(s+8); -+ next = chunk_at_offset(oldp, oldsize); -+ -+ /* Try to expand forward into top */ -+ if (next == av->top && -+ (unsigned long)(newsize = oldsize + chunksize(next)) >= -+ (unsigned long)(nb + MINSIZE)) { -+ set_head_size(oldp, nb); -+ av->top = chunk_at_offset(oldp, nb); -+ set_head(av->top, (newsize - nb) | PREV_INUSE); -+ retval = chunk2mem(oldp); -+ goto DONE; -+ } -+ -+ /* Try to expand forward into next chunk; split off remainder below */ -+ else if (next != av->top && -+ !inuse(next) && -+ (unsigned long)(newsize = oldsize + chunksize(next)) >= -+ (unsigned long)(nb)) { -+ newp = oldp; -+ unlink(next, bck, fwd); -+ } -+ -+ /* allocate, copy, free */ -+ else { -+ newmem = malloc(nb - MALLOC_ALIGN_MASK); -+ if (newmem == 0) { -+ retval = 0; /* propagate failure */ -+ goto DONE; -+ } -+ -+ newp = mem2chunk(newmem); -+ newsize = chunksize(newp); -+ -+ /* -+ Avoid copy if newp is next chunk after oldp. -+ */ -+ if (newp == next) { -+ newsize += oldsize; -+ newp = oldp; -+ } -+ else { -+ /* -+ Unroll copy of <= 36 bytes (72 if 8byte sizes) -+ We know that contents have an odd number of -+ size_t-sized words; minimally 3. -+ */ -+ -+ copysize = oldsize - (sizeof(size_t)); -+ s = (size_t*)(oldmem); -+ d = (size_t*)(newmem); -+ ncopies = copysize / sizeof(size_t); -+ assert(ncopies >= 3); -+ -+ if (ncopies > 9) -+ memcpy(d, s, copysize); -+ -+ else { -+ *(d+0) = *(s+0); -+ *(d+1) = *(s+1); -+ *(d+2) = *(s+2); -+ if (ncopies > 4) { -+ *(d+3) = *(s+3); -+ *(d+4) = *(s+4); -+ if (ncopies > 6) { -+ *(d+5) = *(s+5); -+ *(d+6) = *(s+6); -+ if (ncopies > 8) { -+ *(d+7) = *(s+7); -+ *(d+8) = *(s+8); -+ } -+ } -+ } -+ } -+ -+ free(oldmem); -+ check_inuse_chunk(newp); -+ retval = chunk2mem(newp); -+ goto DONE; - } -- } - } -- } -+ } -+ -+ /* If possible, free extra space in old or extended chunk */ -+ -+ assert((unsigned long)(newsize) >= (unsigned long)(nb)); -+ -+ remainder_size = newsize - nb; - -- free(oldmem); -- check_inuse_chunk(newp); -- UNLOCK; -- return chunk2mem(newp); -- } -- } -- } -- -- /* If possible, free extra space in old or extended chunk */ -- -- assert((unsigned long)(newsize) >= (unsigned long)(nb)); -- -- remainder_size = newsize - nb; -- -- if (remainder_size < MINSIZE) { /* not enough extra to split off */ -- set_head_size(newp, newsize); -- set_inuse_bit_at_offset(newp, newsize); -- } -- else { /* split remainder */ -- remainder = chunk_at_offset(newp, nb); -- set_head_size(newp, nb); -- set_head(remainder, remainder_size | PREV_INUSE); -- /* Mark remainder as inuse so free() won't complain */ -- set_inuse_bit_at_offset(remainder, remainder_size); -- free(chunk2mem(remainder)); -- } -- -- check_inuse_chunk(newp); -- UNLOCK; -- return chunk2mem(newp); -+ if (remainder_size < MINSIZE) { /* not enough extra to split off */ -+ set_head_size(newp, newsize); -+ set_inuse_bit_at_offset(newp, newsize); -+ } -+ else { /* split remainder */ -+ remainder = chunk_at_offset(newp, nb); -+ set_head_size(newp, nb); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ /* Mark remainder as inuse so free() won't complain */ -+ set_inuse_bit_at_offset(remainder, remainder_size); -+ free(chunk2mem(remainder)); -+ } -+ -+ check_inuse_chunk(newp); -+ retval = chunk2mem(newp); -+ goto DONE; - } - - /* -- Handle mmap cases -- */ -+ Handle mmap cases -+ */ - - else { -- size_t offset = oldp->prev_size; -- size_t pagemask = av->pagesize - 1; -- char *cp; -- unsigned long sum; -- -- /* Note the extra (sizeof(size_t)) overhead */ -- newsize = (nb + offset + (sizeof(size_t)) + pagemask) & ~pagemask; -- -- /* don't need to remap if still within same page */ -- if (oldsize == newsize - offset) { -- UNLOCK; -- return oldmem; -- } -- -- cp = (char*)mremap((char*)oldp - offset, oldsize + offset, newsize, 1); -- -- if (cp != (char*)MORECORE_FAILURE) { -- -- newp = (mchunkptr)(cp + offset); -- set_head(newp, (newsize - offset)|IS_MMAPPED); -- -- assert(aligned_OK(chunk2mem(newp))); -- assert((newp->prev_size == offset)); -- -- /* update statistics */ -- sum = av->mmapped_mem += newsize - oldsize; -- if (sum > (unsigned long)(av->max_mmapped_mem)) -- av->max_mmapped_mem = sum; -- sum += av->sbrked_mem; -- if (sum > (unsigned long)(av->max_total_mem)) -- av->max_total_mem = sum; -- -- UNLOCK; -- return chunk2mem(newp); -- } -- -- /* Note the extra (sizeof(size_t)) overhead. */ -- if ((unsigned long)(oldsize) >= (unsigned long)(nb + (sizeof(size_t)))) -- newmem = oldmem; /* do nothing */ -- else { -- /* Must alloc, copy, free. */ -- newmem = malloc(nb - MALLOC_ALIGN_MASK); -- if (newmem != 0) { -- memcpy(newmem, oldmem, oldsize - 2*(sizeof(size_t))); -- free(oldmem); -- } -- } -- UNLOCK; -- return newmem; -+ size_t offset = oldp->prev_size; -+ size_t pagemask = av->pagesize - 1; -+ char *cp; -+ unsigned long sum; -+ -+ /* Note the extra (sizeof(size_t)) overhead */ -+ newsize = (nb + offset + (sizeof(size_t)) + pagemask) & ~pagemask; -+ -+ /* don't need to remap if still within same page */ -+ if (oldsize == newsize - offset) { -+ retval = oldmem; -+ goto DONE; -+ } -+ -+ cp = (char*)mremap((char*)oldp - offset, oldsize + offset, newsize, 1); -+ -+ if (cp != (char*)MORECORE_FAILURE) { -+ -+ newp = (mchunkptr)(cp + offset); -+ set_head(newp, (newsize - offset)|IS_MMAPPED); -+ -+ assert(aligned_OK(chunk2mem(newp))); -+ assert((newp->prev_size == offset)); -+ -+ /* update statistics */ -+ sum = av->mmapped_mem += newsize - oldsize; -+ if (sum > (unsigned long)(av->max_mmapped_mem)) -+ av->max_mmapped_mem = sum; -+ sum += av->sbrked_mem; -+ if (sum > (unsigned long)(av->max_total_mem)) -+ av->max_total_mem = sum; -+ -+ retval = chunk2mem(newp); -+ goto DONE; -+ } -+ -+ /* Note the extra (sizeof(size_t)) overhead. */ -+ if ((unsigned long)(oldsize) >= (unsigned long)(nb + (sizeof(size_t)))) -+ newmem = oldmem; /* do nothing */ -+ else { -+ /* Must alloc, copy, free. */ -+ newmem = malloc(nb - MALLOC_ALIGN_MASK); -+ if (newmem != 0) { -+ memcpy(newmem, oldmem, oldsize - 2*(sizeof(size_t))); -+ free(oldmem); -+ } -+ } -+ retval = newmem; - } -+ -+ DONE: -+ __MALLOC_UNLOCK; -+ return retval; - } - -diff --git a/libc/stdlib/random.c b/libc/stdlib/random.c -index b0a00e1..1bd63bc 100644 ---- a/libc/stdlib/random.c -+++ b/libc/stdlib/random.c -@@ -27,16 +27,14 @@ - #include <limits.h> - #include <stddef.h> - #include <stdlib.h> --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> -+ - /* POSIX.1c requires that there is mutual exclusion for the `rand' and - `srand' functions to prevent concurrent calls from modifying common - data. */ --static pthread_mutex_t lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --#else --#define __pthread_mutex_lock(x) --#define __pthread_mutex_unlock(x) --#endif -+ -+#include <bits/uClibc_mutex.h> -+ -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - /* An improved random number generation package. In addition to the standard - rand()/srand() like interface, this package also has a special state info -@@ -184,9 +182,9 @@ static struct random_data unsafe_state = - for default usage relies on values produced by this routine. */ - void srandom (unsigned int x) - { -- __pthread_mutex_lock(&lock); -+ __UCLIBC_MUTEX_LOCK(mylock); - srandom_r (x, &unsafe_state); -- __pthread_mutex_unlock(&lock); -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - weak_alias (srandom, srand) - -@@ -205,10 +203,10 @@ char * initstate (unsigned int seed, cha - { - int32_t *ostate; - -- __pthread_mutex_lock(&lock); -+ __UCLIBC_MUTEX_LOCK(mylock); - ostate = &unsafe_state.state[-1]; - initstate_r (seed, arg_state, n, &unsafe_state); -- __pthread_mutex_unlock(&lock); -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return (char *) ostate; - } - -@@ -224,11 +222,11 @@ char * setstate (char *arg_state) - { - int32_t *ostate; - -- __pthread_mutex_lock(&lock); -+ __UCLIBC_MUTEX_LOCK(mylock); - ostate = &unsafe_state.state[-1]; - if (setstate_r (arg_state, &unsafe_state) < 0) - ostate = NULL; -- __pthread_mutex_unlock(&lock); -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return (char *) ostate; - } - -@@ -247,9 +245,9 @@ long int random () - { - int32_t retval; - -- __pthread_mutex_lock(&lock); -+ __UCLIBC_MUTEX_LOCK(mylock); - random_r (&unsafe_state, &retval); -- __pthread_mutex_unlock(&lock); -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return retval; - } - -diff --git a/libc/stdlib/setenv.c b/libc/stdlib/setenv.c -index d0cfe52..2d899cc 100644 ---- a/libc/stdlib/setenv.c -+++ b/libc/stdlib/setenv.c -@@ -17,7 +17,7 @@ - 02111-1307 USA. - - modified for uClibc by Erik Andersen <andersen@codepoet.org> -- */ -+*/ - - #define _GNU_SOURCE - #include <features.h> -@@ -26,16 +26,9 @@ - #include <string.h> - #include <unistd.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -+#include <bits/uClibc_mutex.h> - -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - /* If this variable is not a null pointer we allocated the current - environment. */ -@@ -49,14 +42,15 @@ static char **last_environ; - to reuse values once generated for a `setenv' call since we can never - free the strings. */ - int __add_to_environ (const char *name, const char *value, -- const char *combined, int replace) -+ const char *combined, int replace) - { - register char **ep; - register size_t size; - const size_t namelen = strlen (name); - const size_t vallen = value != NULL ? strlen (value) + 1 : 0; -+ int rv = -1; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - /* We have to get the pointer now that we have the lock and not earlier - since another thread might have created a new environment. */ -@@ -64,72 +58,72 @@ int __add_to_environ (const char *name, - - size = 0; - if (ep != NULL) { -- for (; *ep != NULL; ++ep) { -- if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') -- break; -- else -- ++size; -- } -+ for (; *ep != NULL; ++ep) { -+ if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') -+ break; -+ else -+ ++size; -+ } - } - - if (ep == NULL || *ep == NULL) { -- char **new_environ; -+ char **new_environ; - -- /* We allocated this space; we can extend it. */ -- new_environ = (char **) realloc (last_environ, -- (size + 2) * sizeof (char *)); -- if (new_environ == NULL) { -- UNLOCK; -- return -1; -- } -- -- /* If the whole entry is given add it. */ -- if (combined != NULL) { -- /* We must not add the string to the search tree since it belongs -- to the user. */ -- new_environ[size] = (char *) combined; -- } else { -- /* See whether the value is already known. */ -- new_environ[size] = (char *) malloc (namelen + 1 + vallen); -- if (new_environ[size] == NULL) { -- __set_errno (ENOMEM); -- UNLOCK; -- return -1; -- } -- -- memcpy (new_environ[size], name, namelen); -- new_environ[size][namelen] = '='; -- memcpy (&new_environ[size][namelen + 1], value, vallen); -- } -- -- if (__environ != last_environ) { -- memcpy ((char *) new_environ, (char *) __environ, -- size * sizeof (char *)); -- } -+ /* We allocated this space; we can extend it. */ -+ new_environ = (char **) realloc (last_environ, -+ (size + 2) * sizeof (char *)); -+ if (new_environ == NULL) { -+ goto DONE; -+ } -+ -+ /* If the whole entry is given add it. */ -+ if (combined != NULL) { -+ /* We must not add the string to the search tree since it belongs -+ to the user. */ -+ new_environ[size] = (char *) combined; -+ } else { -+ /* See whether the value is already known. */ -+ new_environ[size] = (char *) malloc (namelen + 1 + vallen); -+ if (new_environ[size] == NULL) { -+ __set_errno (ENOMEM); -+ goto DONE; -+ } -+ -+ memcpy (new_environ[size], name, namelen); -+ new_environ[size][namelen] = '='; -+ memcpy (&new_environ[size][namelen + 1], value, vallen); -+ } -+ -+ if (__environ != last_environ) { -+ memcpy ((char *) new_environ, (char *) __environ, -+ size * sizeof (char *)); -+ } - -- new_environ[size + 1] = NULL; -- last_environ = __environ = new_environ; -+ new_environ[size + 1] = NULL; -+ last_environ = __environ = new_environ; - } else if (replace) { -- char *np; -+ char *np; - -- /* Use the user string if given. */ -- if (combined != NULL) { -- np = (char *) combined; -- } else { -- np = malloc (namelen + 1 + vallen); -- if (np == NULL) { -- UNLOCK; -- return -1; -- } -- memcpy (np, name, namelen); -- np[namelen] = '='; -- memcpy (&np[namelen + 1], value, vallen); -- } -- *ep = np; -- } -- -- UNLOCK; -- return 0; -+ /* Use the user string if given. */ -+ if (combined != NULL) { -+ np = (char *) combined; -+ } else { -+ np = malloc (namelen + 1 + vallen); -+ if (np == NULL) { -+ goto DONE; -+ } -+ memcpy (np, name, namelen); -+ np[namelen] = '='; -+ memcpy (&np[namelen + 1], value, vallen); -+ } -+ *ep = np; -+ } -+ -+ rv = 0; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); -+ return rv; - } - - int setenv (const char *name, const char *value, int replace) -@@ -143,26 +137,26 @@ int unsetenv (const char *name) - char **ep; - - if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) { -- __set_errno (EINVAL); -- return -1; -+ __set_errno (EINVAL); -+ return -1; - } - - len = strlen (name); -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - ep = __environ; - while (*ep != NULL) { -- if (!strncmp (*ep, name, len) && (*ep)[len] == '=') { -- /* Found it. Remove this pointer by moving later ones back. */ -- char **dp = ep; -- do { -- dp[0] = dp[1]; -- } while (*dp++); -- /* Continue the loop in case NAME appears again. */ -- } else { -- ++ep; -- } -+ if (!strncmp (*ep, name, len) && (*ep)[len] == '=') { -+ /* Found it. Remove this pointer by moving later ones back. */ -+ char **dp = ep; -+ do { -+ dp[0] = dp[1]; -+ } while (*dp++); -+ /* Continue the loop in case NAME appears again. */ -+ } else { -+ ++ep; -+ } - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return 0; - } - -@@ -171,15 +165,15 @@ int unsetenv (const char *name) - for Fortran 77) requires this function. */ - int clearenv (void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (__environ == last_environ && __environ != NULL) { -- /* We allocated this environment so we can free it. */ -- free (__environ); -- last_environ = NULL; -+ /* We allocated this environment so we can free it. */ -+ free (__environ); -+ last_environ = NULL; - } - /* Clear the environment pointer removes the whole environment. */ - __environ = NULL; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return 0; - } - -@@ -190,10 +184,10 @@ int putenv (char *string) - const char *const name_end = strchr (string, '='); - - if (name_end != NULL) { -- char *name = strndup(string, name_end - string); -- result = __add_to_environ (name, NULL, string, 1); -- free(name); -- return(result); -+ char *name = strndup(string, name_end - string); -+ result = __add_to_environ (name, NULL, string, 1); -+ free(name); -+ return(result); - } - unsetenv (string); - return 0; -diff --git a/libc/sysdeps/linux/common/bits/uClibc_stdio.h b/libc/sysdeps/linux/common/bits/uClibc_stdio.h -index 40cd5fe..3c6911e 100644 ---- a/libc/sysdeps/linux/common/bits/uClibc_stdio.h -+++ b/libc/sysdeps/linux/common/bits/uClibc_stdio.h -@@ -116,9 +116,7 @@ - #endif - - /**********************************************************************/ --#ifdef __UCLIBC_HAS_THREADS__ --/* Need this for pthread_mutex_t. */ --#include <bits/pthreadtypes.h> -+#include <bits/uClibc_mutex.h> - - /* user_locking - * 0 : do auto locking/unlocking -@@ -132,43 +130,37 @@ - * This way, we avoid calling the weak lock/unlock functions. - */ - --#define __STDIO_AUTO_THREADLOCK_VAR int __infunc_user_locking -- --#define __STDIO_AUTO_THREADLOCK(__stream) \ -- if ((__infunc_user_locking = (__stream)->__user_locking) == 0) { \ -- __pthread_mutex_lock(&(__stream)->__lock); \ -- } -- --#define __STDIO_AUTO_THREADUNLOCK(__stream) \ -- if (__infunc_user_locking == 0) { \ -- __pthread_mutex_unlock(&(__stream)->__lock); \ -- } -+#define __STDIO_AUTO_THREADLOCK_VAR \ -+ __UCLIBC_MUTEX_AUTO_LOCK_VAR(__infunc_user_locking) - --#define __STDIO_SET_USER_LOCKING(__stream) ((__stream)->__user_locking = 1) -+#define __STDIO_AUTO_THREADLOCK(__stream) \ -+ __UCLIBC_MUTEX_AUTO_LOCK((__stream)->__lock, __infunc_user_locking, \ -+ (__stream)->__user_locking) - --#define __STDIO_ALWAYS_THREADLOCK(__stream) \ -- __pthread_mutex_lock(&(__stream)->__lock) -+#define __STDIO_AUTO_THREADUNLOCK(__stream) \ -+ __UCLIBC_MUTEX_AUTO_UNLOCK((__stream)->__lock, __infunc_user_locking) - --#define __STDIO_ALWAYS_THREADTRYLOCK(__stream) \ -- __pthread_mutex_trylock(&(__stream)->__lock) -+#define __STDIO_ALWAYS_THREADLOCK(__stream) \ -+ __UCLIBC_MUTEX_LOCK((__stream)->__lock) - --#define __STDIO_ALWAYS_THREADUNLOCK(__stream) \ -- __pthread_mutex_unlock(&(__stream)->__lock) -+#define __STDIO_ALWAYS_THREADUNLOCK(__stream) \ -+ __UCLIBC_MUTEX_UNLOCK((__stream)->__lock) - --#else /* __UCLIBC_HAS_THREADS__ */ -+#define __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(__stream) \ -+ __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE((__stream)->__lock) - --#define __STDIO_AUTO_THREADLOCK_VAR ((void)0) -+#define __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(__stream) \ -+ __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE((__stream)->__lock) - --#define __STDIO_AUTO_THREADLOCK(__stream) ((void)0) --#define __STDIO_AUTO_THREADUNLOCK(__stream) ((void)0) -+#define __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(__stream) \ -+ __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE((__stream)->__lock) - -+#ifdef __UCLIBC_HAS_THREADS__ -+#define __STDIO_SET_USER_LOCKING(__stream) ((__stream)->__user_locking = 1) -+#else - #define __STDIO_SET_USER_LOCKING(__stream) ((void)0) -+#endif - --#define __STDIO_ALWAYS_THREADLOCK(__stream) ((void)0) --#define __STDIO_ALWAYS_THREADTRYLOCK(__stream) (0) /* Always succeed. */ --#define __STDIO_ALWAYS_THREADUNLOCK(__stream) ((void)0) -- --#endif /* __UCLIBC_HAS_THREADS__ */ - /**********************************************************************/ - - #define __STDIO_IOFBF 0 /* Fully buffered. */ -@@ -283,7 +275,7 @@ struct __STDIO_FILE_STRUCT { - #endif - #ifdef __UCLIBC_HAS_THREADS__ - int __user_locking; -- pthread_mutex_t __lock; -+ __UCLIBC_MUTEX(__lock); - #endif - /* Everything after this is unimplemented... and may be trashed. */ - #if __STDIO_BUILTIN_BUF_SIZE > 0 -@@ -358,10 +350,14 @@ extern void _stdio_term(void); - extern struct __STDIO_FILE_STRUCT *_stdio_openlist; - - #ifdef __UCLIBC_HAS_THREADS__ --extern pthread_mutex_t _stdio_openlist_lock; --extern int _stdio_openlist_delflag; -+__UCLIBC_MUTEX_EXTERN(_stdio_openlist_add_lock); -+#ifdef __STDIO_BUFFERS -+__UCLIBC_MUTEX_EXTERN(_stdio_openlist_del_lock); -+extern volatile int _stdio_openlist_use_count; /* _stdio_openlist_del_lock */ -+extern int _stdio_openlist_del_count; /* _stdio_openlist_del_lock */ -+#endif - extern int _stdio_user_locking; --extern void __stdio_init_mutex(pthread_mutex_t *m); -+extern void __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m); - #endif - - #endif -diff --git a/libc/sysdeps/linux/common/getdents.c b/libc/sysdeps/linux/common/getdents.c -index ab6a276..23463e5 100644 ---- a/libc/sysdeps/linux/common/getdents.c -+++ b/libc/sysdeps/linux/common/getdents.c -@@ -30,8 +30,6 @@ - #include <sys/syscall.h> - - --#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -- - struct kernel_dirent - { - long d_ino; -diff --git a/libc/sysdeps/linux/common/sigprocmask.c b/libc/sysdeps/linux/common/sigprocmask.c -index 70ff366..565318d 100644 ---- a/libc/sysdeps/linux/common/sigprocmask.c -+++ b/libc/sysdeps/linux/common/sigprocmask.c -@@ -23,6 +23,8 @@ int sigprocmask(int how, const sigset_t - if (set && - #if (SIG_BLOCK == 0) && (SIG_UNBLOCK == 1) && (SIG_SETMASK == 2) - (((unsigned int) how) > 2) -+#elif (SIG_BLOCK == 1) && (SIG_UNBLOCK == 2) && (SIG_SETMASK == 3) -+ (((unsigned int)(how-1)) > 2) - #else - #warning "compile time assumption violated.. slow path..." - ((how != SIG_BLOCK) && (how != SIG_UNBLOCK) -@@ -48,6 +50,8 @@ int sigprocmask(int how, const sigset_t - if (set && - #if (SIG_BLOCK == 0) && (SIG_UNBLOCK == 1) && (SIG_SETMASK == 2) - (((unsigned int) how) > 2) -+#elif (SIG_BLOCK == 1) && (SIG_UNBLOCK == 2) && (SIG_SETMASK == 3) -+ (((unsigned int)(how-1)) > 2) - #else - #warning "compile time assumption violated.. slow path..." - ((how != SIG_BLOCK) && (how != SIG_UNBLOCK) -diff --git a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h -index b6f52cc..317e5b3 100644 ---- a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h -+++ b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h -@@ -38,3 +38,6 @@ struct kernel_sigaction { - void (*sa_restorer)(void); - int s_resv[1]; /* reserved */ - }; -+ -+extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *__unbounded, -+ struct kernel_sigaction *__unbounded, size_t); -diff --git a/libc/sysdeps/linux/mips/pipe.S b/libc/sysdeps/linux/mips/pipe.S -index c3afae5..cd88074 100644 ---- a/libc/sysdeps/linux/mips/pipe.S -+++ b/libc/sysdeps/linux/mips/pipe.S -@@ -7,25 +7,36 @@ - #include <asm/unistd.h> - #include <asm/regdef.h> - -- .globl pipe -- .ent pipe, 0 -+ .globl pipe -+ .ent pipe, 0 - pipe: -- addiu sp,sp,-24 -- sw a0,16(sp) -- li v0,__NR_pipe -- syscall -- beqz a3, 1f -- la t3, errno -- sw v0, (t3) -- li v0, -1 -- b 2f -+ .frame sp, 24, sp -+#ifdef __PIC__ -+ .set noreorder -+ .cpload $25 -+ .set reorder -+ addiu sp,sp,-24 -+ .cprestore 16 -+#else -+ addiu sp,sp,-24 -+#endif -+ sw a0,16(sp) -+ li v0,__NR_pipe -+ syscall -+ beqz a3, 1f -+#ifdef __PIC__ -+ la t0, __syscall_error -+ jr t9 -+#else -+ j __syscall_error -+#endif - 1: -- lw a0, 16(sp) -- sw v0, 0(a0) -- sw v1, 4(a0) -- li v0, 0 -+ lw a0, 16(sp) -+ sw v0, 0(a0) -+ sw v1, 4(a0) -+ li v0, 0 - 2: -- addiu sp,sp,24 -- j ra -- .end pipe -- .size pipe,.-pipe -+ addiu sp,sp,24 -+ j ra -+ .end pipe -+ .size pipe,.-pipe -diff --git a/libcrypt/des.c b/libcrypt/des.c -index 3b49a7a..f7a6be1 100644 ---- a/libcrypt/des.c -+++ b/libcrypt/des.c -@@ -504,7 +504,7 @@ do_des( u_int32_t l_in, u_int32_t r_in, - kl = kl1; - kr = kr1; - round = 16; -- while (round--) { -+ do { - /* - * Expand R to 48 bits (simulate the E-box). - */ -@@ -540,7 +540,7 @@ do_des( u_int32_t l_in, u_int32_t r_in, - f ^= l; - l = r; - r = f; -- } -+ } while (--round); - r = l; - l = f; - } -diff --git a/libpthread/linuxthreads/ptfork.c b/libpthread/linuxthreads/ptfork.c -index eb544f3..cfec2b7 100644 ---- a/libpthread/linuxthreads/ptfork.c -+++ b/libpthread/linuxthreads/ptfork.c -@@ -26,6 +26,15 @@ - #include "pthread.h" - #include "internals.h" - -+#warning hack alert... should be sufficent for system(), but what about other libc mutexes? -+#include <bits/uClibc_mutex.h> -+ -+__UCLIBC_MUTEX_EXTERN(__malloc_lock); -+ -+#define __MALLOC_LOCK __UCLIBC_MUTEX_LOCK(__malloc_lock) -+#define __MALLOC_UNLOCK __UCLIBC_MUTEX_UNLOCK(__malloc_lock) -+#warning hack alert block end -+ - struct handler_list { - void (*handler)(void); - struct handler_list * next; -@@ -91,9 +100,18 @@ pid_t __fork(void) - parent = pthread_atfork_parent; - pthread_mutex_unlock(&pthread_atfork_lock); - pthread_call_handlers(prepare); -+ -+#warning hack alert -+ __MALLOC_LOCK; -+ - pid = __libc_fork(); -+ -+#warning hack alert -+ __MALLOC_UNLOCK; -+ - if (pid == 0) { - __pthread_reset_main_thread(); -+#warning need to reconsider __fresetlockfiles! - __fresetlockfiles(); - pthread_call_handlers(child); - } else { -diff -urN -x .git uClibc-0.9.28/libc/sysdeps/linux/common/bits/uClibc_mutex.h uClibc-mjn3/libc/sysdeps/linux/common/bits/uClibc_mutex.h ---- uClibc-0.9.28/libc/sysdeps/linux/common/bits/uClibc_mutex.h 1969-12-31 17:00:00.000000000 -0700 -+++ uClibc-mjn3/libc/sysdeps/linux/common/bits/uClibc_mutex.h 2006-03-08 11:21:58.000000000 -0700 -@@ -0,0 +1,87 @@ -+/* Copyright (C) 2006 Manuel Novoa III <mjn3@codepoet.org> -+ * -+ * GNU Library General Public License (LGPL) version 2 or later. -+ * -+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. -+ */ -+ -+#ifndef _UCLIBC_MUTEX_H -+#define _UCLIBC_MUTEX_H -+ -+#include <features.h> -+ -+#ifdef __UCLIBC_HAS_THREADS__ -+ -+#include <pthread.h> -+ -+#define __UCLIBC_MUTEX_TYPE pthread_mutex_t -+ -+#define __UCLIBC_MUTEX(M) pthread_mutex_t M -+#define __UCLIBC_MUTEX_INIT(M,I) pthread_mutex_t M = I -+#define __UCLIBC_MUTEX_STATIC(M,I) static pthread_mutex_t M = I -+#define __UCLIBC_MUTEX_EXTERN(M) extern pthread_mutex_t M -+ -+#define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M) \ -+ __pthread_mutex_lock(&(M)) -+ -+#define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M) \ -+ __pthread_mutex_unlock(&(M)) -+ -+#define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) \ -+ __pthread_mutex_trylock(&(M)) -+ -+#define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C) \ -+ do { \ -+ struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer; \ -+ if (C) { \ -+ _pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer, \ -+ __pthread_mutex_unlock, \ -+ &(M)); \ -+ __pthread_mutex_lock(&(M)); \ -+ } \ -+ ((void)0) -+ -+#define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C) \ -+ if (C) { \ -+ _pthread_cleanup_pop_restore(&__infunc_pthread_cleanup_buffer,1);\ -+ } \ -+ } while (0) -+ -+#define __UCLIBC_MUTEX_AUTO_LOCK_VAR(A) int A -+ -+#define __UCLIBC_MUTEX_AUTO_LOCK(M,A,V) \ -+ __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,((A=(V)) == 0)) -+ -+#define __UCLIBC_MUTEX_AUTO_UNLOCK(M,A) \ -+ __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,(A == 0)) -+ -+#define __UCLIBC_MUTEX_LOCK(M) \ -+ __UCLIBC_MUTEX_CONDITIONAL_LOCK(M, 1) -+ -+#define __UCLIBC_MUTEX_UNLOCK(M) \ -+ __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M, 1) -+ -+#else -+ -+#define __UCLIBC_MUTEX(M) void *__UCLIBC_MUTEX_DUMMY_ ## M -+#define __UCLIBC_MUTEX_INIT(M,I) extern void *__UCLIBC_MUTEX_DUMMY_ ## M -+#define __UCLIBC_MUTEX_STATIC(M) extern void *__UCLIBC_MUTEX_DUMMY_ ## M -+#define __UCLIBC_MUTEX_EXTERN(M) extern void *__UCLIBC_MUTEX_DUMMY_ ## M -+ -+#define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M) ((void)0) -+#define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M) ((void)0) -+#define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) (0) /* Always succeed? */ -+ -+#define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C) ((void)0) -+#define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C) ((void)0) -+ -+#define __UCLIBC_MUTEX_AUTO_LOCK_VAR(A) ((void)0) -+#define __UCLIBC_MUTEX_AUTO_LOCK(M,A,V) ((void)0) -+#define __UCLIBC_MUTEX_AUTO_UNLOCK(M,A) ((void)0) -+ -+#define __UCLIBC_MUTEX_LOCK(M) ((void)0) -+#define __UCLIBC_MUTEX_UNLOCK(M) ((void)0) -+ -+#endif -+ -+#endif /* _UCLIBC_MUTEX_H */ -diff -urN -x .git uClibc-0.9.28/libc/sysdeps/linux/mips/pipe.c uClibc-mjn3/libc/sysdeps/linux/mips/pipe.c ---- uClibc-0.9.28/libc/sysdeps/linux/mips/pipe.c 2005-08-17 16:49:44.000000000 -0600 -+++ uClibc-mjn3/libc/sysdeps/linux/mips/pipe.c 1969-12-31 17:00:00.000000000 -0700 -@@ -1,23 +0,0 @@ --/* pipe system call for Linux/MIPS */ -- --/*see uClibc's sh/pipe.c and glibc-2.2.4's mips/pipe.S */ -- --#include <errno.h> --#include <unistd.h> --#include <syscall.h> -- --int pipe(int *fd) --{ -- register long int res __asm__ ("$2"); // v0 -- register long int res2 __asm__ ("$3"); // v1 -- -- asm ("move\t$4,%2\n\t" // $4 = a0 -- "syscall" /* Perform the system call. */ -- : "=r" (res) -- : "0" (__NR_pipe), "r" (fd) -- : "$4", "$7"); -- -- fd[0] = res; -- fd[1] = res2; -- return(0); --} diff --git a/toolchain/uClibc/uClibc-0.9.28-600-new_dst_rules.patch b/toolchain/uClibc/uClibc-0.9.28-600-new_dst_rules.patch deleted file mode 100644 index 8b1a5a9ac..000000000 --- a/toolchain/uClibc/uClibc-0.9.28-600-new_dst_rules.patch +++ /dev/null @@ -1,101 +0,0 @@ ---- uClibc/libc/misc/time/time.c (revision 16488) -+++ uClibc/libc/misc/time/time.c (working copy) -@@ -157,6 +157,22 @@ - #define TZNAME_MAX _POSIX_TZNAME_MAX - #endif - -+#if defined (L_tzset) || defined (L_localtime_r) || defined(L_strftime) || \ -+ defined(L__time_mktime) || defined(L__time_mktime_tzi) || \ -+ ((defined(L_strftime) || defined(L_strftime_l)) && \ -+ defined(__UCLIBC_HAS_XLOCALE__)) -+ -+void _time_tzset (int); -+ -+#ifndef L__time_mktime -+ -+ /* Jan 1, 2007 Z - tm = 0,0,0,1,0,107,1,0,0 */ -+ -+const static time_t new_rule_starts = 1167609600; -+ -+#endif -+#endif -+ - /**********************************************************************/ - /* The era code is currently unfinished. */ - /* #define ENABLE_ERA_CODE */ -@@ -532,7 +548,7 @@ - { - __UCLIBC_MUTEX_LOCK(_time_tzlock); - -- tzset(); -+ _time_tzset(*timer < new_rule_starts); - - __time_localtime_tzi(timer, result, _time_tzinfo); - -@@ -956,7 +972,8 @@ - unsigned char mod; - unsigned char code; - -- tzset(); /* We'll, let's get this out of the way. */ -+ /* We'll, let's get this out of the way. */ -+ _time_tzset(_time_mktime((struct tm *) timeptr, 0) < new_rule_starts); - - lvl = 0; - p = format; -@@ -1644,7 +1661,9 @@ - 6, 0, 0, /* Note: overloaded for non-M non-J case... */ - 0, 1, 0, /* J */ - ',', 'M', '4', '.', '1', '.', '0', -- ',', 'M', '1', '0', '.', '5', '.', '0', 0 -+ ',', 'M', '1', '0', '.', '5', '.', '0', 0, -+ ',', 'M', '3', '.', '2', '.', '0', -+ ',', 'M', '1', '1', '.', '1', '.', '0', 0 - }; - - #define TZ vals -@@ -1652,6 +1671,7 @@ - #define RANGE (vals + 7) - #define RULE (vals + 11 - 1) - #define DEFAULT_RULES (vals + 22) -+#define DEFAULT_2007_RULES (vals + 38) - - /* Initialize to UTC. */ - int daylight = 0; -@@ -1774,6 +1794,11 @@ - - void tzset(void) - { -+ _time_tzset((time(NULL)) < new_rule_starts); -+} -+ -+void _time_tzset(int use_old_rules) -+{ - register const char *e; - register char *s; - long off; -@@ -1896,7 +1921,15 @@ - } else { /* OK, we have dst, so get some rules. */ - count = 0; - if (!*e) { /* No rules so default to US rules. */ -- e = DEFAULT_RULES; -+ e = use_old_rules ? DEFAULT_RULES : DEFAULT_2007_RULES; -+#ifdef DEBUG_TZSET -+ if (e == DEFAULT_RULES) -+ printf("tzset: Using old rules.\n"); -+ else if (e == DEFAULT_2007_RULES) -+ printf("tzset: Using new rules\n"); -+ else -+ printf("tzset: Using undefined rules\n"); -+#endif /* DEBUG_TZSET */ - } - - do { -@@ -2230,6 +2263,8 @@ - --d; - } - -+ _time_tzset (x.tm_year < 2007); /* tm_year was expanded above */ -+ - #ifdef __BCC__ - d = p[5] - 1; - days = -719163L + ((long)d)*365 + ((d/4) - (d/100) + (d/400) + p[3] + p[7]); diff --git a/toolchain/uClibc/uClibc-0.9.28-700-rm-whitespace.patch b/toolchain/uClibc/uClibc-0.9.28-700-rm-whitespace.patch deleted file mode 100644 index 6004f91e3..000000000 --- a/toolchain/uClibc/uClibc-0.9.28-700-rm-whitespace.patch +++ /dev/null @@ -1,86 +0,0 @@ -diff -urN uClibc-0.9.29-0rig/include/assert.h uClibc-0.9.29/include/assert.h ---- uClibc-0.9.29-0rig/include/assert.h 2005-11-03 23:42:46.000000000 +0100 -+++ uClibc-0.9.29/include/assert.h 2007-08-13 19:10:57.000000000 +0200 -@@ -31,7 +31,7 @@ - #define _ASSERT_H 1 - #include <features.h> - --#if defined __cplusplus && __GNUC_PREREQ (2,95) -+#if defined __cplusplus && __GNUC_PREREQ(2,95) - # define __ASSERT_VOID_CAST static_cast<void> - #else - # define __ASSERT_VOID_CAST (void) -@@ -59,13 +59,17 @@ - (__ASSERT_VOID_CAST ((expr) ? 0 : \ - (__assert (__STRING(expr), __FILE__, __LINE__, \ - __ASSERT_FUNCTION), 0))) -- -+ -+/* Define some temporaries to workaround tinyx makedepend bug */ -+#define __GNUC_PREREQ_2_6 __GNUC_PREREQ(2, 6) -+#define __GNUC_PREREQ_2_4 __GNUC_PREREQ(2, 4) - /* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__' - which contains the name of the function currently being defined. - This is broken in G++ before version 2.6. - C9x has a similar variable called __func__, but prefer the GCC one since - it demangles C++ function names. */ --# if defined __cplusplus ? __GNUC_PREREQ (2, 6) : __GNUC_PREREQ (2, 4) -+ -+# if defined __cplusplus ? __GNUC_PREREQ_2_6 : __GNUC_PREREQ_2_4 - # define __ASSERT_FUNCTION __PRETTY_FUNCTION__ - # else - # if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L -diff -urN uClibc-0.9.29-0rig/include/complex.h uClibc-0.9.29/include/complex.h ---- uClibc-0.9.29-0rig/include/complex.h 2002-05-09 10:15:21.000000000 +0200 -+++ uClibc-0.9.29/include/complex.h 2007-08-13 17:55:29.000000000 +0200 -@@ -33,7 +33,7 @@ - /* We might need to add support for more compilers here. But since ISO - C99 is out hopefully all maintained compilers will soon provide the data - types `float complex' and `double complex'. */ --#if __GNUC_PREREQ (2, 7) && !__GNUC_PREREQ (2, 97) -+#if __GNUC_PREREQ(2, 7) && !__GNUC_PREREQ(2, 97) - # define _Complex __complex__ - #endif - -diff -urN uClibc-0.9.29-0rig/include/features.h uClibc-0.9.29/include/features.h ---- uClibc-0.9.29-0rig/include/features.h 2006-11-29 22:10:04.000000000 +0100 -+++ uClibc-0.9.29/include/features.h 2007-08-13 17:55:51.000000000 +0200 -@@ -143,7 +143,7 @@ - - /* Convenience macros to test the versions of glibc and gcc. - Use them like this: -- #if __GNUC_PREREQ (2,8) -+ #if __GNUC_PREREQ(2,8) - ... code requiring gcc 2.8 or later ... - #endif - Note - they won't work for gcc1 or glibc1, since the _MINOR macros -@@ -297,7 +297,7 @@ - /* uClibc does not support _FORTIFY_SOURCE */ - #undef _FORTIFY_SOURCE - #if defined _FORTIFY_SOURCE && _FORTIFY_SOURCE > 0 \ -- && __GNUC_PREREQ (4, 1) && defined __OPTIMIZE__ && __OPTIMIZE__ > 0 -+ && __GNUC_PREREQ(4, 1) && defined __OPTIMIZE__ && __OPTIMIZE__ > 0 - # if _FORTIFY_SOURCE > 1 - # define __USE_FORTIFY_LEVEL 2 - # else -@@ -366,7 +366,7 @@ - #endif /* !ASSEMBLER */ - - /* Decide whether we can define 'extern inline' functions in headers. */ --#if __GNUC_PREREQ (2, 7) && defined __OPTIMIZE__ \ -+#if __GNUC_PREREQ(2, 7) && defined __OPTIMIZE__ \ - && !defined __OPTIMIZE_SIZE__ && !defined __NO_INLINE__ - # define __USE_EXTERN_INLINES 1 - #endif -diff -urN uClibc-0.9.29-0rig/include/tgmath.h uClibc-0.9.29/include/tgmath.h ---- uClibc-0.9.29-0rig/include/tgmath.h 2002-05-09 10:15:21.000000000 +0200 -+++ uClibc-0.9.29/include/tgmath.h 2007-08-13 17:56:17.000000000 +0200 -@@ -34,7 +34,7 @@ - do not try this for now and instead concentrate only on GNU CC. Once - we have more information support for other compilers might follow. */ - --#if __GNUC_PREREQ (2, 7) -+#if __GNUC_PREREQ(2, 7) - - # ifdef __NO_LONG_DOUBLE_MATH - # define __tgml(fct) fct diff --git a/toolchain/uClibc/uClibc-0.9.28-800-avr32-1.patch b/toolchain/uClibc/uClibc-0.9.28-800-avr32-1.patch deleted file mode 100644 index 14c3b38ff..000000000 --- a/toolchain/uClibc/uClibc-0.9.28-800-avr32-1.patch +++ /dev/null @@ -1,4433 +0,0 @@ -Index: uclibc/Makefile -=================================================================== -RCS file: /disk1/ic_group/design/I9980/REPOSITORY/I7413/source/uclibc/Makefile,v -retrieving revision 1.1.1.3 -diff -u -r1.1.1.3 Makefile ---- uclibc/Makefile 31 Aug 2005 13:08:25 -0000 1.1.1.3 -+++ uclibc/Makefile 7 Dec 2005 06:38:39 -0000 -@@ -163,7 +163,7 @@ - else \ - extra_exclude="" ; \ - fi ; \ -- tar -chf - include --exclude .svn --exclude CVS $$extra_exclude \ -+ tar -chf - --exclude .svn --exclude CVS $$extra_exclude include \ - | tar -xf - -C $(PREFIX)$(DEVEL_PREFIX) - ifneq ($(strip $(UCLIBC_HAS_FLOATS)),y) - # Remove floating point related headers since float support is disabled. ---- a/extra/scripts/fix_includes.sh 2005-08-18 00:49:41.000000000 +0200 -+++ b/extra/scripts/fix_includes.sh 2006-09-27 13:23:12.000000000 +0200 -@@ -78,36 +78,6 @@ if [ ! -d "$KERNEL_SOURCE" ]; then - exit 1; - fi; - --if [ -f "$KERNEL_SOURCE/Makefile" ] ; then --# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION --eval `sed -n -e 's/^\([A-Z]*\) = \([0-9]*\)$/\1=\2/p' -e 's/^\([A-Z]*\) = \(-[-a-z0-9]*\)$/\1=\2/p' $KERNEL_SOURCE/Makefile` --else --ver=`grep UTS_RELEASE $KERNEL_SOURCE/include/linux/version.h | cut -d '"' -f 2` --VERSION=`echo "$ver" | cut -d '.' -f 1` --PATCHLEVEL=`echo "$ver" | cut -d '.' -f 2` --if echo "$ver" | grep -q '-' ; then --SUBLEVEL=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.//" | cut -d '-' -f 1` --EXTRAVERSION=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}-//"` --else --SUBLEVEL=`echo "$ver" | cut -d '.' -f 3` --#EXTRAVERSION= --fi --fi --if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ] --then -- echo "Unable to determine version for kernel headers" -- echo -e "\tprovided in directory $KERNEL_SOURCE" -- exit 1 --fi -- --if [ "$MAKE_IS_SILENT" != "y" ]; then --echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION}" --echo -e "\n" --echo "Using kernel headers from $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} for architecture '$TARGET_ARCH'" --echo -e "\tprovided in directory $KERNEL_SOURCE" --echo -e "\n" --fi -- - # Create a symlink to include/asm - - rm -f include/asm* -@@ -172,7 +142,7 @@ fi; - - - # Annoyingly, 2.6.x kernel headers also need an include/asm-generic/ directory --if [ $VERSION -eq 2 ] && [ $PATCHLEVEL -ge 6 ] ; then -+if [ -d $KERNEL_SOURCE/include/asm-generic ] ; then - ln -fs $KERNEL_SOURCE/include/asm-generic include/asm-generic - fi; - -From 7b2f125425cf777e7937b533217588e27952b87d Mon Sep 17 00:00:00 2001 -From: Haavard Skinnemoen <hskinnemoen@atmel.com> -Date: Mon, 7 Aug 2006 11:12:50 +0200 -Subject: [PATCH] Let optimized stringops override default ones - -The default, slow stringops must be archived _before_ the optimized -stringops if there is to be any point doing the optimizations in the -first place. ---- - libc/Makefile | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/libc/Makefile b/libc/Makefile -index 31e4bab..687eac5 100644 ---- a/libc/Makefile -+++ b/libc/Makefile -@@ -59,7 +59,7 @@ # will evaluate to no files :(. - $(AR) dN 2 $(LIBNAME) $$objs && \ - $(AR) dN 2 $(LIBNAME) $$objs - @for objfile in obj.signal \ -- obj.string.generic obj.string.$(TARGET_ARCH) obj.string \ -+ obj.string obj.string.generic obj.string.$(TARGET_ARCH) \ - obj.sysdeps.common obj.sysdeps.$(TARGET_ARCH) ; do \ - if [ -e $$objfile ] ; then \ - if [ "$(MAKE_IS_SILENT)" = "n" ] ; then \ --- -1.4.1.1 - -Subject: [PATCH] Fix getrusage argument type - -The first argument to getrusage is of type __rusage_who_t, not int. -This patch fixes that. ---- - - libc/sysdeps/linux/common/getrusage.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -Index: uClibc-0.9.28/libc/sysdeps/linux/common/getrusage.c -=================================================================== ---- uClibc-0.9.28.orig/libc/sysdeps/linux/common/getrusage.c 2006-02-07 17:18:22.000000000 +0100 -+++ uClibc-0.9.28/libc/sysdeps/linux/common/getrusage.c 2006-02-07 17:18:31.000000000 +0100 -@@ -10,4 +10,4 @@ - #include "syscalls.h" - #include <unistd.h> - #include <wait.h> --_syscall2(int, getrusage, int, who, struct rusage *, usage); -+_syscall2(int, getrusage, __rusage_who_t, who, struct rusage *, usage); -Subject: [PATCH] Fix __libc_fcntl64 prototype in __syscall_fcntl.c - -__libc_fcntl64 is a varargs function and should be declared as such. -Otherwise, the gcc compiler for AVR32, and perhaps other architectures, -will use the wrong calling convention. - ---- - - libc/sysdeps/linux/common/__syscall_fcntl.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -Index: uClibc-0.9.28/libc/sysdeps/linux/common/__syscall_fcntl.c -=================================================================== ---- uClibc-0.9.28.orig/libc/sysdeps/linux/common/__syscall_fcntl.c 2006-02-07 16:48:32.000000000 +0100 -+++ uClibc-0.9.28/libc/sysdeps/linux/common/__syscall_fcntl.c 2006-02-07 17:19:09.000000000 +0100 -@@ -12,7 +12,7 @@ - #include <fcntl.h> - - #if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64 --extern int __libc_fcntl64(int fd, int cmd, long arg); -+extern int __libc_fcntl64(int fd, int cmd, ...); - #endif - - #define __NR___syscall_fcntl __NR_fcntl -From nobody Mon Sep 17 00:00:00 2001 -From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com> -Date: Fri Apr 7 17:10:32 2006 +0200 -Subject: [PATCH] Fix broken __libc_open declaration in open64.c - -__libc_open is a vararg function and should therefore be declared as -such. Fixes bug #4190. - ---- - - libc/sysdeps/linux/common/open64.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -70f2c81903327a8a346e370830932b80045ab04e -diff --git a/libc/sysdeps/linux/common/open64.c b/libc/sysdeps/linux/common/open64.c -index 543aa13..d9a27a7 100644 ---- a/libc/sysdeps/linux/common/open64.c -+++ b/libc/sysdeps/linux/common/open64.c -@@ -26,7 +26,7 @@ - #endif - - #ifdef __UCLIBC_HAS_LFS__ --extern int __libc_open (__const char *file, int oflag, mode_t mode); -+extern int __libc_open (__const char *file, int oflag, ...); - - /* Open FILE with access OFLAG. If OFLAG includes O_CREAT, - a third argument is the file protection. */ --- -1.2.4 - -Subject: [PATCH] AVR32 Architecture support - -Add support for the AVR32 architecture in the core libc and build system. -This also adds AVR32-ELF definitions to elf.h - ---- - - Rules.mak | 4 - extra/Configs/Config.avr32 | 38 +++++ - extra/Configs/Config.in | 7 + - include/elf.h | 51 +++++++ - libc/sysdeps/linux/avr32/Makefile | 93 +++++++++++++ - libc/sysdeps/linux/avr32/__longjmp.S | 17 ++ - libc/sysdeps/linux/avr32/_mmap.c | 33 ++++ - libc/sysdeps/linux/avr32/bits/atomicity.h | 86 ++++++++++++ - libc/sysdeps/linux/avr32/bits/byteswap.h | 80 +++++++++++ - libc/sysdeps/linux/avr32/bits/endian.h | 7 + - libc/sysdeps/linux/avr32/bits/fcntl.h | 167 +++++++++++++++++++++++++ - libc/sysdeps/linux/avr32/bits/kernel_stat.h | 63 +++++++++ - libc/sysdeps/linux/avr32/bits/kernel_types.h | 56 ++++++++ - libc/sysdeps/linux/avr32/bits/machine-gmon.h | 69 ++++++++++ - libc/sysdeps/linux/avr32/bits/mman.h | 95 ++++++++++++++ - libc/sysdeps/linux/avr32/bits/profil-counter.h | 26 +++ - libc/sysdeps/linux/avr32/bits/setjmp.h | 21 +++ - libc/sysdeps/linux/avr32/bits/syscalls.h | 143 +++++++++++++++++++++ - libc/sysdeps/linux/avr32/bits/wordsize.h | 1 - libc/sysdeps/linux/avr32/brk.c | 23 +++ - libc/sysdeps/linux/avr32/bsd-_setjmp.S | 12 + - libc/sysdeps/linux/avr32/bsd-setjmp.S | 12 + - libc/sysdeps/linux/avr32/clone.c | 37 +++++ - libc/sysdeps/linux/avr32/crt1.S | 93 +++++++++++++ - libc/sysdeps/linux/avr32/crti.S | 17 ++ - libc/sysdeps/linux/avr32/crtn.S | 14 ++ - libc/sysdeps/linux/avr32/mmap.c | 31 ++++ - libc/sysdeps/linux/avr32/setjmp.S | 43 ++++++ - libc/sysdeps/linux/avr32/sigaction.c | 49 +++++++ - libc/sysdeps/linux/avr32/sigrestorer.S | 11 + - libc/sysdeps/linux/avr32/sys/elf.h | 26 +++ - libc/sysdeps/linux/avr32/sys/io.h | 48 +++++++ - libc/sysdeps/linux/avr32/sys/procfs.h | 123 ++++++++++++++++++ - libc/sysdeps/linux/avr32/sys/ucontext.h | 94 ++++++++++++++ - libc/sysdeps/linux/avr32/sys/user.h | 46 ++++++ - libc/sysdeps/linux/avr32/syscall.S | 81 ++++++++++++ - libc/sysdeps/linux/avr32/vfork.S | 55 ++++++++ - 37 files changed, 1872 insertions(+) - -Index: uClibc-0.9.28/extra/Configs/Config.avr32 -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/extra/Configs/Config.avr32 2006-05-05 09:27:17.000000000 +0200 -@@ -0,0 +1,38 @@ -+# -+# For a description of the syntax of this configuration file, -+# see extra/config/Kconfig-language.txt -+# -+ -+config HAVE_ELF -+ bool -+ default y -+ -+config TARGET_ARCH -+ default "avr32" -+ -+config ARCH_CFLAGS -+ string -+ -+config ARCH_LDFLAGS -+ string -+ -+config LIBGCC_CFLAGS -+ string -+ -+config ARCH_SUPPORTS_BIG_ENDIAN -+ bool -+ default y -+ -+config UCLIBC_COMPLETELY_PIC -+ select FORCE_SHAREABLE_TEXT_SEGMENTS -+ bool -+ default y -+ -+choice -+ prompt "Target CPU Type" -+ default CONFIG_AP7000 -+ -+config CONFIG_AP7000 -+ bool "AP7000" -+ -+endchoice -Index: uClibc-0.9.28/extra/Configs/Config.in -=================================================================== ---- uClibc-0.9.28.orig/extra/Configs/Config.in 2006-04-19 12:47:48.000000000 +0200 -+++ uClibc-0.9.28/extra/Configs/Config.in 2006-04-19 12:48:33.000000000 +0200 -@@ -16,6 +16,9 @@ config TARGET_alpha - config TARGET_arm - bool "arm" - -+config TARGET_avr32 -+ bool "avr32" -+ - config TARGET_bfin - bool "bfin" - -@@ -83,6 +86,10 @@ if TARGET_arm - source "extra/Configs/Config.arm" - endif - -+if TARGET_avr32 -+source "extra/Configs/Config.avr32" -+endif -+ - if TARGET_bfin - source "extra/Configs/Config.bfin" - endif -Index: uClibc-0.9.28/include/elf.h -=================================================================== ---- uClibc-0.9.28.orig/include/elf.h 2006-04-19 12:47:48.000000000 +0200 -+++ uClibc-0.9.28/include/elf.h 2006-05-05 09:28:38.000000000 +0200 -@@ -261,6 +261,8 @@ typedef struct - #define EM_NIOS32 0xfebb /* Altera Nios 32 */ - #define EM_ALTERA_NIOS2 0x9ee5 /* Altera Nios II */ - -+#define EM_AVR32 0x18ad -+ - /* V850 backend magic number. Written in the absense of an ABI. */ - #define EM_CYGNUS_V850 0x9080 - -@@ -2687,6 +2689,55 @@ typedef Elf32_Addr Elf32_Conflict; - /* Keep this the last entry. */ - #define R_V850_NUM 25 - -+/* Atmel AVR32 relocations. */ -+#define R_AVR32_NONE 0 -+#define R_AVR32_32 1 -+#define R_AVR32_16 2 -+#define R_AVR32_8 3 -+#define R_AVR32_32_PCREL 4 -+#define R_AVR32_16_PCREL 5 -+#define R_AVR32_8_PCREL 6 -+#define R_AVR32_DIFF32 7 -+#define R_AVR32_DIFF16 8 -+#define R_AVR32_DIFF8 9 -+#define R_AVR32_GOT32 10 -+#define R_AVR32_GOT16 11 -+#define R_AVR32_GOT8 12 -+#define R_AVR32_21S 13 -+#define R_AVR32_16U 14 -+#define R_AVR32_16S 15 -+#define R_AVR32_8S 16 -+#define R_AVR32_8S_EXT 17 -+#define R_AVR32_22H_PCREL 18 -+#define R_AVR32_18W_PCREL 19 -+#define R_AVR32_16B_PCREL 20 -+#define R_AVR32_16N_PCREL 21 -+#define R_AVR32_14UW_PCREL 22 -+#define R_AVR32_11H_PCREL 23 -+#define R_AVR32_10UW_PCREL 24 -+#define R_AVR32_9H_PCREL 25 -+#define R_AVR32_9UW_PCREL 26 -+#define R_AVR32_HI16 27 -+#define R_AVR32_LO16 28 -+#define R_AVR32_GOTPC 29 -+#define R_AVR32_GOTCALL 30 -+#define R_AVR32_LDA_GOT 31 -+#define R_AVR32_GOT21S 32 -+#define R_AVR32_GOT18SW 33 -+#define R_AVR32_GOT16S 34 -+#define R_AVR32_GOT7UW 35 -+#define R_AVR32_32_CPENT 36 -+#define R_AVR32_CPCALL 37 -+#define R_AVR32_16_CP 38 -+#define R_AVR32_9W_CP 39 -+#define R_AVR32_RELATIVE 40 -+#define R_AVR32_GLOB_DAT 41 -+#define R_AVR32_JMP_SLOT 42 -+#define R_AVR32_ALIGN 43 -+#define R_AVR32_NUM 44 -+ -+/* AVR32 dynamic tags */ -+#define DT_AVR32_GOTSZ 0x70000001 /* Total size of GOT in bytes */ - - #define R_H8_NONE 0 - #define R_H8_DIR32 1 -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/Makefile -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/Makefile 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,93 @@ -+# Makefile for uClibc -+# -+# Copyright (C) 2000-2003 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 -+ -+TOPDIR=../../../../ -+include $(TOPDIR)Rules.mak -+ASFLAGS=$(CFLAGS) -+ -+CRT_SRC = crt1.S -+CRT_OBJ = crt1.o -+SCRT_OBJ = $(patsubst %,S%, $(CRT_OBJ)) -+CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o -+ -+SSRC=__longjmp.S setjmp.S bsd-setjmp.S vfork.S \ -+ bsd-_setjmp.S sigrestorer.S syscall.S -+SOBJS=$(patsubst %.S,%.o, $(SSRC)) -+ -+CSRC=clone.c brk.c sigaction.c mmap.c -+COBJS=$(patsubst %.c,%.o, $(CSRC)) -+ -+OBJS=$(SOBJS) $(COBJS) -+ -+OBJ_LIST=../../../obj.sysdeps.$(TARGET_ARCH) -+ -+all: $(OBJ_LIST) -+ -+$(OBJ_LIST): $(OBJS) $(CRT_OBJ) $(SCRT_OBJ) $(CTOR_TARGETS) -+ echo $(patsubst %, sysdeps/linux/$(TARGET_ARCH)/%, $(OBJS)) > $(OBJ_LIST) -+ $(INSTALL) -d $(TOPDIR)lib/ -+ cp $(CRT_OBJ) $(SCRT_OBJ) $(TOPDIR)lib/ -+ -+$(CRT_OBJ): $(CRT_SRC) -+ $(CC) $(ASFLAGS) -DL_$* $< -c -o $*.o -+ $(STRIPTOOL) -x -R .note -R .comment $*.o -+ -+$(SCRT_OBJ): $(CRT_SRC) -+ $(CC) $(ASFLAGS) $(PIEFLAG) -DL_$* $< -c -o $*.o -+ $(STRIPTOOL) -x -R .note -R .comment $*.o -+ -+$(SOBJS): %.o : %.S -+ $(CC) $(ASFLAGS) -c $< -o $@ -+ $(STRIPTOOL) -x -R .note -R .comment $*.o -+ -+$(COBJS): %.o : %.c -+ $(CC) $(CFLAGS) -c $< -o $@ -+ $(STRIPTOOL) -x -R .note -R .comment $*.o -+ -+ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y) -+crti.o: crti.S -+ $(CC) $(ASFLAGS) -c crti.S -o crti.o -+ -+$(TOPDIR)lib/crti.o: crti.o -+ $(INSTALL) -d $(TOPDIR)lib/ -+ cp crti.o $(TOPDIR)lib/ -+ -+crtn.o: crtn.S -+ $(CC) $(ASFLAGS) -c crtn.S -o crtn.o -+ -+$(TOPDIR)lib/crtn.o: crtn.o -+ $(INSTALL) -d $(TOPDIR)lib/ -+ cp crtn.o $(TOPDIR)lib/ -+else -+$(TOPDIR)lib/crti.o: -+ $(INSTALL) -d $(TOPDIR)lib/ -+ $(AR) $(ARFLAGS) $(TOPDIR)lib/crti.o -+$(TOPDIR)lib/crtn.o: -+ $(INSTALL) -d $(TOPDIR)lib/ -+ $(AR) $(ARFLAGS) $(TOPDIR)lib/crtn.o -+endif -+ -+ -+headers: -+# $(LN) -fs ../libc/sysdeps/linux/avr32/fpu_control.h $(TOPDIR)/include/ -+ -+clean: -+ $(RM) *.[oa] *~ core -+ $(RM) bits/sysnum.h -+ $(RM) gmon-start.S -+ -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/__longjmp.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/__longjmp.S 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,17 @@ -+/* longjmp for AVR32 -+ * -+ * Copyright (C) 2004 Atmel Norway AS -+ */ -+ -+ .global __longjmp -+ .type __longjmp,"function" -+ .align 1 -+__longjmp: -+ ldm r12++, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr -+ mov r12, r11 /* get the return value right */ -+ mustr r8 /* restore status register (lower half) */ -+ cp r12, 0 /* can't return zero */ -+ frs -+ moveq r12, 1 -+ mov pc,lr -+ .size __longjmp, . - __longjmp -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/_mmap.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/_mmap.c 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,33 @@ -+/* Copyright (C) 2005 Atmel Norway -+ -+ 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 -+ -+ Derived in part from the Linux-8086 C library, the GNU C Library, and several -+ other sundry sources. Files within this library are copyright by their -+ respective copyright holders. -+ */ -+ -+#include <errno.h> -+#include <sys/mman.h> -+#include <sys/syscall.h> -+ -+#define __NR_mmap2 __NR_mmap -+ -+static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot, int, flags, int, fd, __off_t, pgoff); -+ -+__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset) -+{ -+ return mmap2(addr, len, prot, flags, fd, offset >> 12); -+} -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/atomicity.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/atomicity.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,86 @@ -+/* Low-level functions for atomic operations. AVR32 version. -+ Copyright (C) 1997, 1998, 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 _ATOMICITY_H -+#define _ATOMICITY_H 1 -+ -+#include <inttypes.h> -+ -+static inline int -+__attribute__((unused)) -+exchange_and_add (volatile uint32_t *mem, int val) -+{ -+ int tmp, result; -+ -+ __asm__ __volatile__( -+ "/* Inline exchange and add */\n" -+ "1: ssrf 5\n" -+ " ld.w %0, %3\n" -+ " add %1, %0, %4\n" -+ " stcond %2, %1\n" -+ " brne 1b" -+ : "=&r"(result), "=&r"(tmp), "=m"(*mem) -+ : "m"(*mem), "r"(val) -+ : "cc", "memory"); -+ -+ return result; -+} -+ -+static inline void -+__attribute__((unused)) -+atomic_add (volatile uin32_t *mem, int val) -+{ -+ int result; -+ -+ __asm__ __volatile__( -+ "/* Inline atomic add */\n" -+ "1: ssrf 5\n" -+ " ld.w %0, %2\n" -+ " add %0, %3\n" -+ " stcond %2, %0\n" -+ " brne 1b" -+ : "=&r"(result), "=m"(*mem) -+ : "m"(*mem), "r"(val) -+ : "cc", "memory"); -+} -+ -+static inline int -+__attribute__((unused)) -+compare_and_swap(volatile long int *p, long int oldval, long int newval) -+{ -+ long int result, tmp; -+ -+ __asm__ __volatile__( -+ "/* Inline compare and swap */\n" -+ "1: ssrf 5\n" -+ " ld.w %1, %3\n" -+ " cp.w %1, %5\n" -+ " sreq %0\n" -+ " brne 2f\n" -+ " stcond %2, %4\n" -+ " brne 1b\n" -+ "2:" -+ : "=&r"(result), "=&r"(tmp), "=m"(*p) -+ : "m"(*p), "r"(newval), "r"(oldval) -+ : "cc", "memory"); -+ -+ return result; -+} -+ -+#endif /* atomicity.h */ -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/byteswap.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/byteswap.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,80 @@ -+/* Macros to swap the order of bytes in integer values. -+ Copyright (C) 2005 Atmel Norway. -+ -+ 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. */ -+ -+#if !defined _BYTESWAP_H && !defined _NETINET_IN_H -+# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead." -+#endif -+ -+#ifndef _BITS_BYTESWAP_H -+#define _BITS_BYTESWAP_H 1 -+ -+/* Swap bytes in 16 bit value. */ -+#if defined __GNUC__ -+# define __bswap_16(x) (__extension__ __builtin_bswap_16(x)) -+#else -+/* This is better than nothing. */ -+static __inline unsigned short int -+__bswap_16 (unsigned short int __bsx) -+{ -+ return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8)); -+} -+#endif -+ -+/* Swap bytes in 32 bit value. */ -+#if defined __GNUC__ -+# define __bswap_32(x) (__extension__ __builtin_bswap_32(x)) -+#else -+static __inline unsigned int -+__bswap_32 (unsigned int __bsx) -+{ -+ return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) | -+ (((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24)); -+} -+#endif -+ -+#if defined __GNUC__ -+/* Swap bytes in 64 bit value. */ -+# define __bswap_constant_64(x) \ -+ ((((x) & 0xff00000000000000ull) >> 56) \ -+ | (((x) & 0x00ff000000000000ull) >> 40) \ -+ | (((x) & 0x0000ff0000000000ull) >> 24) \ -+ | (((x) & 0x000000ff00000000ull) >> 8) \ -+ | (((x) & 0x00000000ff000000ull) << 8) \ -+ | (((x) & 0x0000000000ff0000ull) << 24) \ -+ | (((x) & 0x000000000000ff00ull) << 40) \ -+ | (((x) & 0x00000000000000ffull) << 56)) -+ -+# define __bswap_64(x) \ -+ (__extension__ \ -+ ({ \ -+ union { \ -+ __extension__ unsigned long long int __ll; \ -+ unsigned int __l[2]; \ -+ } __w, __r; \ -+ if (__builtin_constant_p(x)) \ -+ __r.__ll = __bswap_constant_64(x); \ -+ else { \ -+ __w.__ll = (x); \ -+ __r.__l[0] = __bswap_32(__w.__l[1]); \ -+ __r.__l[1] = __bswap_32(__w.__l[0]); \ -+ } \ -+ __r.__ll; \ -+ })) -+#endif -+ -+#endif /* _BITS_BYTESWAP_H */ -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/endian.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/endian.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,7 @@ -+/* AVR32 is big-endian */ -+ -+#ifndef _ENDIAN_H -+# error "Never use <bits/endian.h> directly; include <endian.h> instead." -+#endif -+ -+#define __BYTE_ORDER __BIG_ENDIAN -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/fcntl.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/fcntl.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,167 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway AS -+ * -+ * This file is part of the Linux kernel -+ */ -+#ifndef _FCNTL_H -+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead." -+#endif -+ -+#include <sys/types.h> -+ -+/* 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_ASYNC 020000 -+ -+#ifdef __USE_GNU -+# define O_DIRECTORY 040000 /* must be a directory */ -+# define O_NOFOLLOW 0100000 /* don't follow links */ -+# define O_DIRECT 0200000 /* direct disk access */ -+#endif -+ -+#ifdef __USE_LARGEFILE64 -+# define O_LARGEFILE 0400000 -+#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 -+ -+#define F_DUPFD 0 /* dup */ -+#define F_GETFD 1 /* get close_on_exec */ -+#define F_SETFD 2 /* set/clear close_on_exec */ -+#define F_GETFL 3 /* get file->f_flags */ -+#define F_SETFL 4 /* set file->f_flags */ -+ -+#ifndef __USE_FILE_OFFSET64 -+# define F_GETLK 5 -+# define F_SETLK 6 -+# define F_SETLKW 7 -+#else -+# define F_GETLK F_GETLK64 -+# define F_SETLK F_SETLK64 -+# define F_SETLKW F_SETLKW64 -+#endif -+#define F_GETLK64 12 /* using 'struct flock64' */ -+#define F_SETLK64 13 -+#define F_SETLKW64 14 -+ -+#if defined __USE_BSD || defined __USE_XOPEN2K -+# define F_SETOWN 8 /* for sockets. */ -+# define F_GETOWN 9 /* for sockets. */ -+#endif -+ -+#ifdef __USE_GNU -+# define F_SETSIG 10 /* for sockets. */ -+# define F_GETSIG 11 /* for sockets. */ -+#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 lockf() */ -+#define F_RDLCK 0 -+#define F_WRLCK 1 -+#define F_UNLCK 2 -+ -+/* for old implementation of bsd flock () */ -+#define F_EXLCK 4 /* or 3 */ -+#define F_SHLCK 8 /* or 4 */ -+ -+/* for leases */ -+#define F_INPROGRESS 16 -+ -+#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 ops */ -+#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 l_type; -+ short l_whence; -+#ifndef __USE_FILE_OFFSET64 -+ __off_t l_start; -+ __off_t l_len; -+#else -+ __off64_t l_start; -+ __off64_t l_len; -+#endif -+ __pid_t l_pid; -+}; -+ -+#ifdef __USE_LARGEFILE64 -+struct flock64 { -+ short l_type; -+ short l_whence; -+ __off64_t l_start; -+ __off64_t l_len; -+ __pid_t l_pid; -+}; -+#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 -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_stat.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_stat.h 2006-05-05 09:28:32.000000000 +0200 -@@ -0,0 +1,63 @@ -+#ifndef _BITS_STAT_STRUCT_H -+#define _BITS_STAT_STRUCT_H -+ -+/* -+ * This file provides struct stat, taken from kernel 2.6.4 -+ * (include/asm-avr32/stat.h revision 1.1). -+ */ -+ -+struct kernel_stat { -+ unsigned long st_dev; -+ unsigned long st_ino; -+ unsigned short st_mode; -+ unsigned short st_nlink; -+ unsigned short st_uid; -+ unsigned short st_gid; -+ unsigned long st_rdev; -+ unsigned long st_size; -+ unsigned long st_blksize; -+ unsigned long st_blocks; -+ unsigned long st_atime; -+ unsigned long st_atime_nsec; -+ unsigned long st_mtime; -+ unsigned long st_mtime_nsec; -+ unsigned long st_ctime; -+ unsigned long st_ctime_nsec; -+ unsigned long __unused4; -+ unsigned long __unused5; -+}; -+ -+#define STAT_HAVE_NSEC 1 -+ -+struct kernel_stat64 { -+ unsigned long long st_dev; -+ -+ unsigned long long st_ino; -+ unsigned int st_mode; -+ unsigned int st_nlink; -+ -+ unsigned long st_uid; -+ unsigned long st_gid; -+ -+ unsigned long long st_rdev; -+ -+ long long st_size; -+ unsigned long __pad1; -+ unsigned long st_blksize; -+ -+ unsigned long long st_blocks; -+ -+ unsigned long st_atime; -+ unsigned long st_atime_nsec; -+ -+ unsigned long st_mtime; -+ unsigned long st_mtime_nsec; -+ -+ unsigned long st_ctime; -+ unsigned long st_ctime_nsec; -+ -+ unsigned long __unused1; -+ unsigned long __unused2; -+}; -+ -+#endif /* _BITS_STAT_STRUCT_H */ -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_types.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_types.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,56 @@ -+/* 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 __ASM_AVR32_POSIX_TYPES_H -+#define __ASM_AVR32_POSIX_TYPES_H -+ -+/* -+ * This file is generally used by user-level software, so you need to -+ * be a little careful about namespace pollution etc. Also, we cannot -+ * assume GCC is being used. -+ */ -+ -+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 int __kernel_uid_t; -+typedef unsigned int __kernel_gid_t; -+typedef unsigned long __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_timer_t; -+typedef int __kernel_clockid_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; -+ -+#ifdef __GNUC__ -+typedef long long __kernel_loff_t; -+#endif -+ -+typedef struct { -+#if defined(__USE_ALL) -+ int val[2]; -+#else -+ int __val[2]; -+#endif -+} __kernel_fsid_t; -+ -+#endif /* __ASM_AVR32_POSIX_TYPES_H */ -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/machine-gmon.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/machine-gmon.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,69 @@ -+/* Machine-dependent definitions for profiling support. AVR32 version. -+ Copyright (C) 1996, 1997, 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. */ -+ -+#define mcount_internal __mcount_internal -+ -+#define _MCOUNT_DECL(frompc, selfpc) \ -+static void __attribute((used)) mcount_internal(unsigned long frompc, unsigned long selfpc) -+ -+/* -+ * This mcount implementation expects to get called after the prologue -+ * has been run. It also expects that r7 contains a valid frame -+ * pointer. -+ * -+ * When profiling, the compiler should generate something like this at -+ * each function entry: -+ * -+ * pushm r0-r7,lr // lr mandatory, others optional -+ * mov r7, sp -+ * // rest of prologue goes here -+ * mcall pc[.LC1 - .] -+ * // rest of function goes here -+ * .LC1: -+ * .long mcount -+ * -+ * or for PIC: -+ * -+ * pushm r0-r7,lr -+ * mov r7, sp -+ * // rest of prologue goes here -+ * lddpc r0, .LC1 -+ * .L1: rsub r0, pc -+ * mcall r0[mcount@GOT] -+ * // rest of function goes here -+ * .LC1: -+ * .long .L1 - _GLOBAL_OFFSET_TABLE_ -+ * -+ * This way, when mcount() is called, r7 points to the calling -+ * function's return address. It is guaranteed that calling mcount -+ * will clobber no registers except LR, which is unavoidable. -+ */ -+#define MCOUNT asm( \ -+ " .align 4\n" \ -+ " .global _mcount\n" \ -+ " .type _mcount,@function\n" \ -+ "_mcount:\n" \ -+ " pushm r8-r12,lr\n" \ -+ " mov r11, lr\n" \ -+ " ld.w r12, r7[0]\n" \ -+ " rcall __mcount_internal\n" \ -+ " popm r8-r12,pc\n" \ -+ " .size _mcount, . - _mcount\n" \ -+ " .weak mcount\n" \ -+ " mcount = _mcount"); -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/mman.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/mman.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,95 @@ -+/* Definitions for POSIX memory map interface. Linux/AVR32 version. -+ Copyright (C) 1997, 2000 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ 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 include this file directly. Use <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. */ -+ -+/* 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 0x0100 /* Stack-like segment. */ -+# define MAP_DENYWRITE 0x0800 /* ETXTBSY */ -+# define MAP_EXECUTABLE 0x1000 /* Mark it as an executable. */ -+# define MAP_LOCKED 0x2000 /* Lock the mapping. */ -+# define MAP_NORESERVE 0x4000 /* Don't check for reservations. */ -+# define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ -+# define MAP_NONBLOCK 0x10000 /* do not block on IO */ -+#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 -+#endif -+ -+/* Advise 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. */ -+#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 -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/profil-counter.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/profil-counter.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,26 @@ -+/* Low-level statistical profiling support function. Linux/AVR32 version. -+ Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include <signal.h> -+ -+void -+profil_counter(int signo, siginfo_t *si, struct sigcontext *sc) -+{ -+ profil_count((void *)sc->pc); -+} -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/setjmp.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/setjmp.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,21 @@ -+/* -+ * Copyright (C) 2004-2005 Atmel Norway -+ */ -+#ifndef _SETJMP_H -+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead." -+#endif -+ -+#ifndef _ASM -+/* -+ * The jump buffer contains r0-r7, sr, sp and lr. Other registers are -+ * not saved. -+ */ -+typedef int __jmp_buf[11]; -+#endif -+ -+#define __JMP_BUF_SP 4 -+ -+/* Test if longjmp to JMPBUF would unwind the frame containing a local -+ variable at ADDRESS. */ -+#define _JMPBUF_UNWINDS(jmpbuf, address) \ -+ ((void *)(address) < (void *)(jmpbuf[__JMP_BUF_SP])) -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/syscalls.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/syscalls.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,143 @@ -+#ifndef _SYSCALL_H -+# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead." -+#endif -+ -+/* -+ * This includes the `__NR_<name>' syscall numbers taken from the -+ * Linux kernel header files. It also defines the traditional -+ * `SYS_<name>' macros for older programs. -+ */ -+#include <bits/sysnum.h> -+ -+#ifndef __set_errno -+# define __set_errno(val) (*__errno_location()) = (val) -+#endif -+#ifndef SYS_ify -+# define SYS_ify(syscall_name) (__NR_##syscall_name) -+#endif -+ -+#ifndef __ASSEMBLER__ -+ -+#undef _syscall0 -+#define _syscall0(type,name) \ -+ type name(void) \ -+ { \ -+ return (type)(INLINE_SYSCALL(name, 0)); \ -+ } -+ -+#undef _syscall1 -+#define _syscall1(type,name,type1,arg1) \ -+ type name(type1 arg1) \ -+ { \ -+ return (type)(INLINE_SYSCALL(name, 1, arg1)); \ -+ } -+ -+#undef _syscall2 -+#define _syscall2(type,name,type1,arg1,type2,arg2) \ -+ type name(type1 arg1, type2 arg2) \ -+ { \ -+ return (type)(INLINE_SYSCALL(name, 2, arg1, arg2)); \ -+ } -+ -+#undef _syscall3 -+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -+ type name(type1 arg1, type2 arg2, type3 arg3) \ -+ { \ -+ return (type)(INLINE_SYSCALL(name, 3, arg1, \ -+ arg2, arg3)); \ -+ } -+ -+#undef _syscall4 -+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3, \ -+ type4,arg4) \ -+ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -+ { \ -+ return (type)(INLINE_SYSCALL(name, 4, arg1, arg2, \ -+ arg3, arg4)); \ -+ } -+ -+#undef _syscall5 -+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3, \ -+ type4,arg4,type5,arg5) \ -+ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5) \ -+ { \ -+ return (type)(INLINE_SYSCALL(name, 5, arg1, arg2, \ -+ arg3, arg4, arg5)); \ -+ } -+ -+#undef _syscall6 -+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3, \ -+ type4,arg4,type5,arg5,type6,arg6) \ -+ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5, type6 arg6) \ -+ { \ -+ return (type)(INLINE_SYSCALL(name, 6, arg1, arg2, arg3, \ -+ arg4, arg5, arg6)); \ -+ } -+ -+#undef unlikely -+#define unlikely(x) __builtin_expect((x), 0) -+ -+#undef INLINE_SYSCALL -+#define INLINE_SYSCALL(name, nr, args...) \ -+ ({ \ -+ unsigned _sys_result = INTERNAL_SYSCALL(name, , nr, args); \ -+ if (unlikely(INTERNAL_SYSCALL_ERROR_P(_sys_result, ))) { \ -+ __set_errno(INTERNAL_SYSCALL_ERRNO(_sys_result, )); \ -+ _sys_result = (unsigned int) -1; \ -+ } \ -+ (int) _sys_result; \ -+ }) -+ -+#undef INTERNAL_SYSCALL_DECL -+#define INTERNAL_SYSCALL_DECL(err) do { } while(0) -+ -+#undef INTERNAL_SYSCALL -+#define INTERNAL_SYSCALL(name, err, nr, args...) \ -+ ({ \ -+ register int _a1 asm ("r12"); \ -+ register int _scno asm("r8") = SYS_ify(name); \ -+ LOAD_ARGS_##nr (args); \ -+ asm volatile ("scall /* syscall " #name " */" \ -+ : "=r" (_a1) \ -+ : "r"(_scno) ASM_ARGS_##nr \ -+ : "lr", "cc", "memory"); \ -+ _a1; \ -+ }) -+ -+#undef INTERNAL_SYSCALL_ERROR_P -+#define INTERNAL_SYSCALL_ERROR_P(val, err) \ -+ ((unsigned int)(val) >= 0xfffff001U) -+ -+#undef INTERNAL_SYSCALL_ERRNO -+#define INTERNAL_SYSCALL_ERRNO(val, errr) (-(val)) -+ -+#define LOAD_ARGS_0() do { } while(0) -+#define ASM_ARGS_0 -+#define LOAD_ARGS_1(a1) \ -+ _a1 = (int) (a1); \ -+ LOAD_ARGS_0() -+#define ASM_ARGS_1 ASM_ARGS_0, "r"(_a1) -+#define LOAD_ARGS_2(a1, a2) \ -+ register int _a2 asm("r11") = (int)(a2); \ -+ LOAD_ARGS_1(a1) -+#define ASM_ARGS_2 ASM_ARGS_1, "r"(_a2) -+#define LOAD_ARGS_3(a1, a2, a3) \ -+ register int _a3 asm("r10") = (int)(a3); \ -+ LOAD_ARGS_2(a1, a2) -+#define ASM_ARGS_3 ASM_ARGS_2, "r"(_a3) -+#define LOAD_ARGS_4(a1, a2, a3, a4) \ -+ register int _a4 asm("r9") = (int)(a4); \ -+ LOAD_ARGS_3(a1, a2, a3) -+#define ASM_ARGS_4 ASM_ARGS_3, "r"(_a4) -+#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \ -+ register int _a5 asm("r5") = (int)(a5); \ -+ LOAD_ARGS_4(a1, a2, a3, a4) -+#define ASM_ARGS_5 ASM_ARGS_4, "r"(_a5) -+#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \ -+ register int _a6 asm("r3") = (int)(a6); \ -+ LOAD_ARGS_5(a1, a2, a3, a4, a5) -+#define ASM_ARGS_6 ASM_ARGS_5, "r"(_a6) -+ -+#endif /* __ASSEMBLER__ */ -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/wordsize.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/wordsize.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1 @@ -+#define __WORDSIZE 32 -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/brk.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/brk.c 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,23 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway AS -+ */ -+#include <errno.h> -+#include <sys/syscall.h> -+ -+void *__curbrk = 0; -+ -+int brk (void *addr) -+{ -+ void *newbrk; -+ -+ newbrk = INLINE_SYSCALL(brk, 1, addr); -+ -+ __curbrk = newbrk; -+ -+ if (newbrk < addr) { -+ __set_errno (ENOMEM); -+ return -1; -+ } -+ -+ return 0; -+} -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-_setjmp.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-_setjmp.S 2006-05-05 09:26:42.000000000 +0200 -@@ -0,0 +1,12 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway AS -+ */ -+ -+ /* This just does a tail-call to __sigsetjmp(env, 0) */ -+ .global _setjmp -+ .type _setjmp,"function" -+ .align 1 -+_setjmp: -+ mov r11, 0 -+ bral __sigsetjmp_internal -+ .size _setjmp, . - _setjmp -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-setjmp.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-setjmp.S 2006-05-05 09:26:42.000000000 +0200 -@@ -0,0 +1,12 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway AS -+ */ -+ -+ /* This just does a tail-call to __sigsetjmp(env, 1) */ -+ .global setjmp -+ .type setjmp,"function" -+ .align 1 -+setjmp: -+ mov r11, 1 -+ bral __sigsetjmp_internal -+ .size setjmp, . - setjmp -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/clone.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/clone.c 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,37 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway AS -+ */ -+#include <errno.h> -+#include <sys/syscall.h> -+#include <unistd.h> -+ -+/* -+ * I don't know if we can be absolutely certain that the fn and arg -+ * parameters are preserved when returning as the child. If the -+ * compiler stores them in registers (r0-r7), they should be. -+ */ -+int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) -+{ -+ register int (*_fn)(void *arg) = fn; -+ register void *_arg = arg; -+ int err; -+ -+ /* Sanity check the arguments */ -+ err = -EINVAL; -+ if (!fn) -+ goto syscall_error; -+ if (!child_stack) -+ goto syscall_error; -+ -+ err = INLINE_SYSCALL(clone, 2, flags, child_stack); -+ if (err < 0) -+ goto syscall_error; -+ else if (err != 0) -+ return err; -+ -+ _exit(_fn(_arg)); -+ -+syscall_error: -+ __set_errno (-err); -+ return -1; -+} -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/crt1.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/crt1.S 2006-05-05 09:28:23.000000000 +0200 -@@ -0,0 +1,93 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway AS -+ * -+ * When we enter _start, the stack looks like this: -+ * argc argument counter -+ * argv[0] pointer to program name -+ * argv[1..argc-1] pointers to program args -+ * NULL -+ * env[0..N] pointers to environment variables -+ * NULL -+ * -+ * r12 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. -+ * -+ * We're going to call the following function: -+ * __uClibc_main(int (*main)(int, char **, char **), int argc, -+ * char **argv, void (*app_init)(void), void (*app_fini)(void), -+ * void (*rtld_fini)(void), void *stack_end) -+ * -+ * So we need to set up things as follows: -+ * r12 = address of main -+ * r11 = argc -+ * r10 = &argv[0] -+ * r9 = address of _init -+ * r8 = address of _fini -+ * sp[0] = whatever we got passed in r12 -+ */ -+ -+#include <features.h> -+ -+ .text -+ .global _start -+ .type _start, @function -+_start: -+ /* Clear the frame pointer and link register since this is the outermost frame. */ -+ mov r7, 0 -+ mov lr, 0 -+ -+ ld.w r11, sp++ /* argc */ -+ mov r10, sp /* &argv[0] */ -+ -+ st.w --sp, r10 /* stack_end */ -+ st.w --sp, r12 /* rtld_fini */ -+ -+#ifdef __PIC__ -+ lddpc r6, .L_GOT -+.L_RGOT: -+ rsub r6, pc -+ lda.w r9, _init -+ lda.w r8, _fini -+ lda.w r12, main -+ -+ /* Ok, now run uClibc's main() -- should not return */ -+ call __uClibc_main -+ -+ .align 2 -+.L_GOT: -+ .long .L_RGOT - _GLOBAL_OFFSET_TABLE_ -+#else -+ lddpc r9, __init_addr /* app_init */ -+ lddpc r8, __fini_addr /* app_fini */ -+ lddpc r12, __main_addr /* main */ -+ -+ /* Ok, now run uClibc's main() -- should not return */ -+ lddpc pc, ___uClibc_main_addr -+ -+ .align 2 -+__init_addr: -+ .long _init -+__fini_addr: -+ .long _fini -+__main_addr: -+ .long main -+___uClibc_main_addr: -+ .long __uClibc_main -+#endif -+ .size _start, . - _start -+ -+ /* -+ * The LSB says we need this. -+ */ -+ .section ".note.ABI-tag", "a" -+ .align 4 -+ .long 2f - 1f /* namesz */ -+ .long 4f - 3f /* descsz */ -+ .long 1 /* type */ -+1: .asciz "GNU" /* name */ -+2: .align 4 -+3: .long 0 /* Linux executable */ -+ .long 2,6,0 /* Earliest compatible kernel */ -+4: .align 4 -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/crti.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/crti.S 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,17 @@ -+ -+ .section .init -+ .align 2 -+ .global _init -+ .type _init, @function -+_init: -+ /* Use a four-byte instruction to avoid NOPs */ -+ stm --sp, r0-r7,lr -+ .align 2 -+ -+ .section .fini -+ .align 2 -+ .global _fini -+ .type _fini, @function -+_fini: -+ stm --sp, r0-r7,lr -+ .align 2 -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/crtn.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/crtn.S 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,14 @@ -+ -+ .section .init -+ .align 2 -+ .global _init -+ .type _init, @function -+ ldm sp++, r0-r7,pc -+ .size _init, . - _init -+ -+ .section .fini -+ .align 2 -+ .global _fini -+ .type _fini, @function -+ ldm sp++, r0-r7,pc -+ .size _fini, . - _fini -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/mmap.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/mmap.c 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,31 @@ -+/* Copyright (C) 2005 Atmel Norway -+ -+ 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 -+ -+ Derived in part from the Linux-8086 C library, the GNU C Library, and several -+ other sundry sources. Files within this library are copyright by their -+ respective copyright holders. -+ */ -+ -+#include <errno.h> -+#include <sys/mman.h> -+#include <sys/syscall.h> -+ -+static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot, int, flags, int, fd, __off_t, pgoff); -+ -+__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset) -+{ -+ return mmap2(addr, len, prot, flags, fd, offset >> 12); -+} -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/setjmp.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/setjmp.S 2006-05-05 09:28:28.000000000 +0200 -@@ -0,0 +1,43 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway AS -+ */ -+#define _SETJMP_H -+#define _ASM -+#include <bits/setjmp.h> -+ -+ .text -+ -+ .global __sigsetjmp -+ .type __sigsetjmp,"function" -+ -+ /* Create a global, hidden symbol for use by setjmp() and _setjmp(). -+ If it's not hidden, the linker will complain about a relative -+ jump to a dynamic symbol when building a shared library. -+ -+ Also, if a user overrides the __sigsetjmp function, he might not -+ expect the setjmp() and _setjmp() function to effectively be -+ overridden as well. */ -+ .global __sigsetjmp_internal -+ .hidden __sigsetjmp_internal -+ .type __sigsetjmp_internal,"function" -+ .align 1 -+__sigsetjmp: -+__sigsetjmp_internal: -+ mustr r8 -+ stm r12, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr -+ -+ /* Make a tail call to __sigjmp_save; it takes the same args. */ -+#ifdef __PIC__ -+ mov r9, r6 -+ lddpc r6, .LG -+.L1: rsub r6, pc -+ ld.w r8, r6[__sigjmp_save@got] -+ mov r6, r9 -+ mov pc, r8 -+ -+ .align 2 -+.LG: .long .L1 - _GLOBAL_OFFSET_TABLE_ -+#else -+ rjmp __sigjmp_save -+#endif -+ .size __sigsetjmp, . - __sigsetjmp -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sigaction.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sigaction.c 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway AS -+ */ -+#include <errno.h> -+#include <signal.h> -+#include <string.h> -+#include <sys/syscall.h> -+#include <bits/kernel_sigaction.h> -+ -+#define SA_RESTORER 0x04000000 -+extern void __default_rt_sa_restorer(void); -+ -+/* -+ * If act is not NULL, change the action for sig to *act. -+ * If oact is not NULL, put the old action for sig in *oact. -+ */ -+int __libc_sigaction(int signum, const struct sigaction *act, -+ struct sigaction *oldact) -+{ -+ struct kernel_sigaction kact, koact; -+ int result; -+ -+ if (act) { -+ kact.k_sa_handler = act->sa_handler; -+ memcpy(&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask)); -+ kact.sa_flags = act->sa_flags; -+ if (kact.sa_flags & (SA_RESTORER | SA_ONSTACK)) -+ kact.sa_restorer = act->sa_restorer; -+ else -+ kact.sa_restorer = __default_rt_sa_restorer; -+ kact.sa_flags |= SA_RESTORER; -+ } -+ -+ result = __syscall_rt_sigaction(signum, act ? __ptrvalue(&kact) : NULL, -+ oldact ? __ptrvalue(&koact) : NULL, -+ _NSIG / 8); -+ -+ if (oldact && result >= 0) { -+ oldact->sa_handler = koact.k_sa_handler; -+ memcpy(&oldact->sa_mask, &koact.sa_mask, -+ sizeof(oldact->sa_mask)); -+ oldact->sa_flags = koact.sa_flags; -+ oldact->sa_restorer = koact.sa_restorer; -+ } -+ -+ return result; -+} -+ -+weak_alias(__libc_sigaction, sigaction) -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sigrestorer.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sigrestorer.S 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,11 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway AS -+ */ -+#include <sys/syscall.h> -+ -+ .global __default_rt_sa_restorer -+ .type __default_rt_sa_restorer,"function" -+ .align 1 -+__default_rt_sa_restorer: -+ mov r8, __NR_rt_sigreturn -+ scall -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/elf.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/elf.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,26 @@ -+/* Copyright (C) 1996, 1997, 1999, 2001 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_ELF_H -+#define _SYS_ELF_H 1 -+ -+#warning "This header is obsolete; use <sys/procfs.h> instead." -+ -+#include <sys/procfs.h> -+ -+#endif /* sys/elf.h */ -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/io.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/io.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,48 @@ -+/* Copyright (C) 1996, 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_IO_H -+ -+#define _SYS_IO_H 1 -+#include <features.h> -+ -+__BEGIN_DECLS -+ -+/* If TURN_ON is TRUE, request for permission to do direct i/o on the -+ port numbers in the range [FROM,FROM+NUM-1]. Otherwise, turn I/O -+ permission off for that range. This call requires root privileges. */ -+extern int ioperm (unsigned long int __from, unsigned long int __num, -+ int __turn_on) __THROW; -+ -+/* Set the I/O privilege level to LEVEL. If LEVEL is nonzero, -+ permission to access any I/O port is granted. This call requires -+ root privileges. */ -+extern int iopl (int __level) __THROW; -+ -+/* The functions that actually perform reads and writes. */ -+extern unsigned char inb (unsigned long int port) __THROW; -+extern unsigned short int inw (unsigned long int port) __THROW; -+extern unsigned long int inl (unsigned long int port) __THROW; -+ -+extern void outb (unsigned char value, unsigned long int port) __THROW; -+extern void outw (unsigned short value, unsigned long int port) __THROW; -+extern void outl (unsigned long value, unsigned long int port) __THROW; -+ -+__END_DECLS -+ -+#endif /* _SYS_IO_H */ -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/procfs.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/procfs.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,123 @@ -+/* Copyright (C) 1996, 1997, 1999, 2001 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#ifndef _SYS_PROCFS_H -+#define _SYS_PROCFS_H 1 -+ -+/* This is somewhat modelled after the file of the same name on SVR4 -+ systems. It provides a definition of the core file format for ELF -+ used on Linux. It doesn't have anything to do with the /proc file -+ system, even though Linux has one. -+ -+ Anyway, the whole purpose of this file is for GDB and GDB only. -+ Don't read too much into it. Don't use it for anything other than -+ GDB unless you know what you are doing. */ -+ -+#include <features.h> -+#include <sys/time.h> -+#include <sys/types.h> -+#include <sys/user.h> -+ -+__BEGIN_DECLS -+ -+/* Type for a general-purpose register. */ -+typedef unsigned long elf_greg_t; -+ -+/* And the whole bunch of them. We could have used `struct -+ user_regs' directly in the typedef, but tradition says that -+ the register set is an array, which does have some peculiar -+ semantics, so leave it that way. */ -+#define ELF_NGREG (sizeof (struct user_regs) / sizeof(elf_greg_t)) -+typedef elf_greg_t elf_gregset_t[ELF_NGREG]; -+ -+/* Register set for the floating-point registers. */ -+typedef struct user_fpregs elf_fpregset_t; -+ -+/* Signal info. */ -+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. */ -+ -+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. */ -+ }; -+ -+/* The rest of this file provides the types for emulation of the -+ Solaris <proc_service.h> interfaces that should be implemented by -+ users of libthread_db. */ -+ -+/* Addresses. */ -+typedef void *psaddr_t; -+ -+/* Register sets. Linux has different names. */ -+typedef elf_gregset_t prgregset_t; -+typedef elf_fpregset_t prfpregset_t; -+ -+/* We don't have any differences between processes and threads, -+ therefore have only one PID type. */ -+typedef __pid_t lwpid_t; -+ -+/* Process status and info. In the end we do provide typedefs for them. */ -+typedef struct elf_prstatus prstatus_t; -+typedef struct elf_prpsinfo prpsinfo_t; -+ -+__END_DECLS -+ -+#endif /* sys/procfs.h */ -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/ucontext.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/ucontext.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,94 @@ -+/* Copyright (C) 1998, 1999, 2001 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. */ -+ -+/* Linux/AVR32 ABI compliant context switching support. */ -+ -+#ifndef _SYS_UCONTEXT_H -+#define _SYS_UCONTEXT_H 1 -+ -+#include <features.h> -+#include <signal.h> -+#include <sys/procfs.h> -+#include <bits/sigcontext.h> -+ -+typedef int greg_t; -+ -+/* Number of general registers. */ -+#define NGREG 16 -+ -+/* Container for all general registers. */ -+typedef elf_gregset_t gregset_t; -+ -+/* Number of each register is the `gregset_t' array. */ -+enum -+{ -+ R0 = 0, -+#define R0 R0 -+ R1 = 1, -+#define R1 R1 -+ R2 = 2, -+#define R2 R2 -+ R3 = 3, -+#define R3 R3 -+ R4 = 4, -+#define R4 R4 -+ R5 = 5, -+#define R5 R5 -+ R6 = 6, -+#define R6 R6 -+ R7 = 7, -+#define R7 R7 -+ R8 = 8, -+#define R8 R8 -+ R9 = 9, -+#define R9 R9 -+ R10 = 10, -+#define R10 R10 -+ R11 = 11, -+#define R11 R11 -+ R12 = 12, -+#define R12 R12 -+ R13 = 13, -+#define R13 R13 -+ R14 = 14, -+#define R14 R14 -+ R15 = 15 -+#define R15 R15 -+}; -+ -+/* Structure to describe FPU registers. */ -+typedef elf_fpregset_t fpregset_t; -+ -+/* Context to describe whole processor state. */ -+typedef struct -+ { -+ gregset_t gregs; -+ fpregset_t fpregs; -+ } mcontext_t; -+ -+/* Userlevel context. */ -+typedef struct ucontext -+{ -+ unsigned long uc_flags; -+ struct ucontext *uc_link; -+ stack_t uc_stack; -+ struct sigcontext uc_mcontext; -+ sigset_t uc_sigmask; /* mask last for extensibility */ -+} ucontext_t; -+ -+#endif /* sys/ucontext.h */ -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/user.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/user.h 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,46 @@ -+#ifndef _SYS_USER_H -+#define _SYS_USER_H -+ -+struct user_fpregs -+{ -+ -+}; -+ -+struct user_regs -+{ -+ unsigned long sr; -+ unsigned long pc; -+ unsigned long lr; -+ unsigned long sp; -+ unsigned long r12; -+ unsigned long r11; -+ unsigned long r10; -+ unsigned long r9; -+ unsigned long r8; -+ unsigned long r7; -+ unsigned long r6; -+ unsigned long r5; -+ unsigned long r4; -+ unsigned long r3; -+ unsigned long r2; -+ unsigned long r1; -+ unsigned long r0; -+ unsigned long r12_orig; -+}; -+ -+struct user -+{ -+ struct user_regs regs; /* general registers */ -+ 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 user_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 */ -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/syscall.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/syscall.S 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,81 @@ -+/* -+ * syscall for AVR32/uClibc -+ * -+ * Copyright (C) 2004 Atmel Norway -+ * -+ * 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> -+ -+ .text -+ -+ /* -+ * long int syscall(long int sysno, ...) -+ */ -+ .global syscall -+ .type syscall, @function -+ .align 2 -+syscall: -+ stm --sp, r3,r5,lr -+ sub lr, sp, -12 -+ mov r8, r12 -+ ldm lr, r3,r5,r9-r12 -+ scall -+ cp.w r12, -4095 -+ brlo .Ldone -+ -+#ifdef __PIC__ -+ lddpc r5, .Lgot -+.Lgotcalc: -+ rsub r5, pc -+# ifdef __UCLIBC_HAS_THREADS__ -+ mov r3, r12 -+ mcall r5[__errno_location@got] -+ st.w r12[0], r3 -+# else -+ ld.w r3, r5[errno@got] -+ st.w r3[0], r12 -+# endif -+#else -+# ifdef __UCLIBC_HAS_THREADS__ -+ mov r3, r12 -+ mcall .Lerrno_location -+ st.w r12[0], r3 -+# else -+ lddpc r3, .Lerrno -+ st.w r3[0], r12 -+# endif -+#endif -+ mov r12, -1 -+ -+.Ldone: -+ ldm sp++, r3,r5,pc -+ -+ .align 2 -+#ifdef __PIC__ -+.Lgot: -+ .long .Lgotcalc - _GLOBAL_OFFSET_TABLE_ -+#else -+# ifdef __UCLIBC_HAS_THREADS__ -+.Lerrno_location: -+ .long __errno_location -+# else -+.Lerrno: -+ .long errno -+# endif -+#endif -+ -+ -+ .size syscall, . - syscall -Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/vfork.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libc/sysdeps/linux/avr32/vfork.S 2006-04-19 12:48:33.000000000 +0200 -@@ -0,0 +1,55 @@ -+ /* -+ * vfork for uClibc -+ * -+ * Copyright (C) 2005 Atmel Norway -+ */ -+ -+ /* -+ * Clone the process without copying the address space. The -+ * calling process is suspended until the child either exits -+ * or calls execve. -+ * -+ * This all means that we cannot rely on the stack to store -+ * away registers, since they will be overwritten by the child -+ * as soon as it makes another function call (e.g. execve()). -+ * Fortunately, the Linux kernel preserves LR across system calls. -+ */ -+#include <features.h> -+#include <sys/syscall.h> -+ -+ .global __vfork -+ .type __vfork,@function -+ .align 1 -+__vfork: -+ mov r8, __NR_vfork -+ scall -+ cp.w r12, -4096 -+ retls r12 -+ -+ /* vfork failed, so we may use the stack freely */ -+ pushm r4-r7,lr -+#ifdef __PIC__ -+ lddpc r6, .L_GOT -+ rsub r4, r12, 0 -+.L_RGOT: -+ rsub r6, pc -+ mcall r6[__errno_location@got] -+#else -+ rsub r4, r12, 0 -+ mcall .L__errno_location -+#endif -+ st.w r12[0], r4 -+ popm r4-r7,pc,r12=-1 -+ -+ .align 2 -+#ifdef __PIC__ -+.L_GOT: -+ .long .L_RGOT - _GLOBAL_OFFSET_TABLE_ -+#else -+.L__errno_location: -+ .long __errno_location -+#endif -+ .size __vfork, . - __vfork -+ -+ .weak vfork -+ vfork = __vfork -Index: uClibc-0.9.28/Rules.mak -=================================================================== ---- uClibc-0.9.28.orig/Rules.mak 2006-05-05 09:26:01.000000000 +0200 -+++ uClibc-0.9.28/Rules.mak 2006-05-05 09:27:17.000000000 +0200 -@@ -231,6 +231,10 @@ ifeq ($(strip $(TARGET_ARCH)),frv) - UCLIBC_LDSO=ld.so.1 - endif - -+ifeq ($(strip $(TARGET_ARCH)),avr32) -+ CPU_CFLAGS-$(CONFIG_AP7000) += -mcpu=ap7000 -+endif -+ - # Keep the check_gcc from being needlessly executed - ifndef PIEFLAG - ifneq ($(UCLIBC_BUILD_PIE),y) -From nobody Mon Sep 17 00:00:00 2001 -Subject: [PATCH] Make linkrelax configurable -From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com> -Date: 1133951618 +0100 - -Add a linkrelax option to the configure system which will give -appropriate options to the compiler, assembler and linker to enable -link-time optimizations. - ---- - - Rules.mak | 2 ++ - extra/Configs/Config.avr32 | 4 ++++ - 2 files changed, 6 insertions(+) - -Index: uClibc-0.9.28/Rules.mak -=================================================================== ---- uClibc-0.9.28.orig/Rules.mak 2006-02-08 17:58:53.000000000 +0100 -+++ uClibc-0.9.28/Rules.mak 2006-02-08 17:59:07.000000000 +0100 -@@ -233,6 +233,8 @@ endif - - ifeq ($(strip $(TARGET_ARCH)),avr32) - CPU_CFLAGS-$(CONFIG_AP7000) += -mcpu=ap7000 -+ CPU_CFLAGS-$(LINKRELAX) += -masm-addr-pseudos -Wa,--pic,--linkrelax -+ CPU_LDFLAGS-$(LINKRELAX) += --relax - endif - - # Keep the check_gcc from being needlessly executed -Index: uClibc-0.9.28/extra/Configs/Config.avr32 -=================================================================== ---- uClibc-0.9.28.orig/extra/Configs/Config.avr32 2006-02-08 17:58:53.000000000 +0100 -+++ uClibc-0.9.28/extra/Configs/Config.avr32 2006-02-08 17:59:07.000000000 +0100 -@@ -36,3 +36,7 @@ config CONFIG_AP7000 - bool "AP7000" - - endchoice -+ -+config LINKRELAX -+ bool "Enable linker optimizations" -+ default n -Subject: [PATCH] AVR32-optimized string operations - -Add hand-optimized AVR32-specific string operations. Some of them -need a bit more testing, though. - ---- - - libc/string/avr32/Makefile | 40 +++++++++++ - libc/string/avr32/bcopy.S | 15 ++++ - libc/string/avr32/bzero.S | 12 +++ - libc/string/avr32/memchr.S | 62 +++++++++++++++++ - libc/string/avr32/memcmp.S | 50 +++++++++++++ - libc/string/avr32/memcpy.S | 110 ++++++++++++++++++++++++++++++ - libc/string/avr32/memmove.S | 114 +++++++++++++++++++++++++++++++ - libc/string/avr32/memset.S | 60 ++++++++++++++++ - libc/string/avr32/strcat.S | 95 ++++++++++++++++++++++++++ - libc/string/avr32/strcmp.S | 80 ++++++++++++++++++++++ - libc/string/avr32/strcpy.S | 63 +++++++++++++++++ - libc/string/avr32/stringtest.c | 144 ++++++++++++++++++++++++++++++++++++++++ - libc/string/avr32/strlen.S | 52 ++++++++++++++ - libc/string/avr32/strncpy.S | 77 +++++++++++++++++++++ - libc/string/avr32/test_memcpy.c | 66 ++++++++++++++++++ - 15 files changed, 1040 insertions(+) - -Index: uClibc-0.9.28-avr32/libc/string/avr32/bcopy.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/bcopy.S 2006-10-19 15:05:52.000000000 +0200 -@@ -0,0 +1,15 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway -+ */ -+ -+ .text -+ .global bcopy -+ .type bcopy, @function -+ .align 1 -+bcopy: -+ /* Swap the first two arguments */ -+ eor r11, r12 -+ eor r12, r11 -+ eor r11, r12 -+ rjmp __memmove -+ .size bcopy, . - bcopy -Index: uClibc-0.9.28-avr32/libc/string/avr32/bzero.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/bzero.S 2006-10-19 15:05:52.000000000 +0200 -@@ -0,0 +1,12 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway -+ */ -+ -+ .text -+ .global bzero -+ .type bzero, @function -+ .align 1 -+bzero: -+ mov r10, r11 -+ mov r11, 0 -+ rjmp __memset -Index: uClibc-0.9.28-avr32/libc/string/avr32/Makefile -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/Makefile 2006-10-19 15:05:52.000000000 +0200 -@@ -0,0 +1,40 @@ -+# Makefile for uClibc -+# -+# Copyright (C) 2000-2003 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 -+ -+TOPDIR=../../../ -+include $(TOPDIR)Rules.mak -+ -+SSRC := bcopy.S bzero.S memcmp.S memcpy.S memmove.S -+SSRC += memset.S strcmp.S strlen.S -+# memchr.S, strcat.S, strcpy.S, strncpy.S is broken -+SOBJS := $(patsubst %.S,%.o, $(SSRC)) -+OBJS := $(SOBJS) -+ -+OBJ_LIST:= ../../obj.string.$(TARGET_ARCH) -+ -+all: $(OBJ_LIST) -+ -+$(OBJ_LIST): $(OBJS) -+ echo $(addprefix string/$(TARGET_ARCH)/, $(OBJS)) > $@ -+ -+$(SOBJS): %.o: %.S -+ $(CC) $(ASFLAGS) -c $< -o $@ -+ $(STRIPTOOL) -x -R .note -R .comment $@ -+ -+clean: -+ $(RM) *.[oa] *~ core -Index: uClibc-0.9.28-avr32/libc/string/avr32/memchr.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/memchr.S 2006-10-19 15:05:52.000000000 +0200 -@@ -0,0 +1,62 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway -+ */ -+ -+#define str r12 -+#define chr r11 -+#define len r10 -+ -+ .text -+ .global memchr -+ .type memchr, @function -+memchr: -+ or chr, chr, chr << 8 -+ or chr, chr, chr << 16 -+ -+ mov r9, str -+ andl r9, 3, COH -+ brne .Lunaligned_str -+ -+1: sub len, 4 -+ brlt 2f -+ ld.w r8, str++ -+ psub.b r9, r8, r11 -+ tnbz r9 -+ brne 1b -+ -+ sub str, 4 -+ bfextu r9, r8, 24, 8 -+ cp.b r9, r11 -+ reteq str -+ sub str, -1 -+ bfextu r9, r8, 16, 8 -+ cp.b r9, r11 -+ reteq str -+ sub str, -1 -+ bfextu r9, r8, 8, 8 -+ cp.b r9, r11 -+ reteq str -+ sub str, -1 -+ retal str -+ -+2: sub len, -4 -+ reteq 0 -+ -+3: ld.ub r8, str++ -+ cp.w r8, 0 -+ reteq str -+ sub len, 1 -+ brne 3b -+ -+ retal 0 -+ -+.Lunaligned_str: -+1: sub len, 1 -+ retlt 0 -+ ld.ub r8, str++ -+ cp.b r8, r11 -+ reteq str -+ sub r9, 1 -+ brge 1b -+ -+ rjmp .Laligned_search -Index: uClibc-0.9.28-avr32/libc/string/avr32/memcmp.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/memcmp.S 2006-10-20 10:42:09.000000000 +0200 -@@ -0,0 +1,50 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway. -+ */ -+ -+#define s1 r12 -+#define s2 r11 -+#define len r10 -+ -+ .text -+ .global memcmp -+ .type memcmp, @function -+ .align 1 -+memcmp: -+ sub len, 4 -+ brlt .Lless_than_4 -+ -+1: ld.w r8, s1++ -+ ld.w r9, s2++ -+ cp.w r8, r9 -+ brne .Lfound_word -+ sub len, 4 -+ brge 1b -+ -+.Lless_than_4: -+ sub len, -4 -+ reteq 0 -+ -+1: ld.ub r8, s1++ -+ ld.ub r9, s2++ -+ sub r8, r9 -+ retne r8 -+ sub len, 1 -+ brgt 1b -+ -+ retal 0 -+ -+.Lfound_word: -+ psub.b r9, r8, r9 -+ bfextu r8, r9, 24, 8 -+ retne r8 -+ bfextu r8, r9, 16, 8 -+ retne r8 -+ bfextu r8, r9, 8, 8 -+ retne r8 -+ retal r9 -+ -+ .size memcmp, . - memcmp -+ -+ .weak bcmp -+ bcmp = memcmp -Index: uClibc-0.9.28-avr32/libc/string/avr32/memcpy.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/memcpy.S 2006-10-19 15:05:52.000000000 +0200 -@@ -0,0 +1,110 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway -+ */ -+ -+/* Don't use r12 as dst since we must return it unmodified */ -+#define dst r9 -+#define src r11 -+#define len r10 -+ -+ .text -+ .global memcpy -+ .type memcpy, @function -+ -+ .global __memcpy -+ .hidden __memcpy -+ .type __memcpy, @function -+memcpy: -+__memcpy: -+ pref src[0] -+ mov dst, r12 -+ -+ /* If we have less than 32 bytes, don't do anything fancy */ -+ cp.w len, 32 -+ brge .Lmore_than_31 -+ -+ sub len, 1 -+ retlt r12 -+1: ld.ub r8, src++ -+ st.b dst++, r8 -+ sub len, 1 -+ brge 1b -+ retal r12 -+ -+.Lmore_than_31: -+ pushm r0-r7, lr -+ -+ /* Check alignment */ -+ mov r8, src -+ andl r8, 31, COH -+ brne .Lunaligned_src -+ mov r8, dst -+ andl r8, 3, COH -+ brne .Lunaligned_dst -+ -+.Laligned_copy: -+ sub len, 32 -+ brlt .Lless_than_32 -+ -+1: /* Copy 32 bytes at a time */ -+ ldm src, r0-r7 -+ sub src, -32 -+ stm dst, r0-r7 -+ sub dst, -32 -+ sub len, 32 -+ brge 1b -+ -+.Lless_than_32: -+ /* Copy 16 more bytes if possible */ -+ sub len, -16 -+ brlt .Lless_than_16 -+ ldm src, r0-r3 -+ sub src, -16 -+ sub len, 16 -+ stm dst, r0-r3 -+ sub dst, -16 -+ -+.Lless_than_16: -+ /* Do the remaining as byte copies */ -+ neg len -+ add pc, pc, len << 2 -+ .rept 15 -+ ld.ub r0, src++ -+ st.b dst++, r0 -+ .endr -+ -+ popm r0-r7, pc -+ -+.Lunaligned_src: -+ /* Make src cacheline-aligned. r8 = (src & 31) */ -+ rsub r8, r8, 32 -+ sub len, r8 -+1: ld.ub r0, src++ -+ st.b dst++, r0 -+ sub r8, 1 -+ brne 1b -+ -+ /* If dst is word-aligned, we're ready to go */ -+ pref src[0] -+ mov r8, 3 -+ tst dst, r8 -+ breq .Laligned_copy -+ -+.Lunaligned_dst: -+ /* src is aligned, but dst is not. Expect bad performance */ -+ sub len, 4 -+ brlt 2f -+1: ld.w r0, src++ -+ st.w dst++, r0 -+ sub len, 4 -+ brge 1b -+ -+2: neg len -+ add pc, pc, len << 2 -+ .rept 3 -+ ld.ub r0, src++ -+ st.b dst++, r0 -+ .endr -+ -+ popm r0-r7, pc -+ .size memcpy, . - memcpy -Index: uClibc-0.9.28-avr32/libc/string/avr32/memmove.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/memmove.S 2006-10-19 15:05:52.000000000 +0200 -@@ -0,0 +1,114 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway -+ */ -+ -+#define dst r12 -+#define src r11 -+#define len r10 -+ -+ .text -+ .global memmove -+ .type memmove, @function -+ -+ .global __memmove -+ .hidden __memmove -+ .type __memmove, @function -+memmove: -+__memmove: -+ cp.w src, dst -+ brge __memcpy -+ -+ add dst, len -+ add src, len -+ pref src[-1] -+ -+ /* -+ * The rest is basically the same as in memcpy.S except that -+ * the direction is reversed. -+ */ -+ cp.w len, 32 -+ brge .Lmore_than_31 -+ -+ sub len, 1 -+ retlt r12 -+1: ld.ub r8, --src -+ st.b --dst, r8 -+ sub len, 1 -+ brge 1b -+ retal r12 -+ -+.Lmore_than_31: -+ pushm r0-r7, lr -+ -+ /* Check alignment */ -+ mov r8, src -+ andl r8, 31, COH -+ brne .Lunaligned_src -+ mov r8, r12 -+ andl r8, 3, COH -+ brne .Lunaligned_dst -+ -+.Laligned_copy: -+ sub len, 32 -+ brlt .Lless_than_32 -+ -+1: /* Copy 32 bytes at a time */ -+ sub src, 32 -+ ldm src, r0-r7 -+ sub dst, 32 -+ sub len, 32 -+ stm dst, r0-r7 -+ brge 1b -+ -+.Lless_than_32: -+ /* Copy 16 more bytes if possible */ -+ sub len, -16 -+ brlt .Lless_than_16 -+ sub src, 16 -+ ldm src, r0-r3 -+ sub dst, 16 -+ sub len, 16 -+ stm dst, r0-r3 -+ -+.Lless_than_16: -+ /* Do the remaining as byte copies */ -+ sub len, -16 -+ breq 2f -+1: ld.ub r0, --src -+ st.b --dst, r0 -+ sub len, 1 -+ brne 1b -+ -+2: popm r0-r7, pc -+ -+.Lunaligned_src: -+ /* Make src cacheline-aligned. r8 = (src & 31) */ -+ sub len, r8 -+1: ld.ub r0, --src -+ st.b --dst, r0 -+ sub r8, 1 -+ brne 1b -+ -+ /* If dst is word-aligned, we're ready to go */ -+ pref src[-4] -+ mov r8, 3 -+ tst dst, r8 -+ breq .Laligned_copy -+ -+.Lunaligned_dst: -+ /* src is aligned, but dst is not. Expect bad performance */ -+ sub len, 4 -+ brlt 2f -+1: ld.w r0, --src -+ st.w --dst, r0 -+ sub len, 4 -+ brge 1b -+ -+2: neg len -+ add pc, pc, len << 2 -+ .rept 3 -+ ld.ub r0, --src -+ st.b --dst, r0 -+ .endr -+ -+ popm r0-r7, pc -Index: uClibc-0.9.28-avr32/libc/string/avr32/memset.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/memset.S 2006-10-20 10:42:15.000000000 +0200 -@@ -0,0 +1,60 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway. -+ */ -+ -+#define s r12 -+#define c r11 -+#define n r10 -+ -+ .text -+ .global memset -+ .type memset, @function -+ -+ .global __memset -+ .hidden __memset -+ .type __memset, @function -+ -+ .align 1 -+memset: -+__memset: -+ cp.w n, 32 -+ mov r9, s -+ brge .Llarge_memset -+ -+ sub n, 1 -+ retlt s -+1: st.b s++, c -+ sub n, 1 -+ brge 1b -+ -+ retal r9 -+ -+.Llarge_memset: -+ mov r8, r11 -+ mov r11, 3 -+ bfins r8, r8, 8, 8 -+ bfins r8, r8, 16, 16 -+ tst s, r11 -+ breq 2f -+ -+1: st.b s++, r8 -+ sub n, 1 -+ tst s, r11 -+ brne 1b -+ -+2: mov r11, r9 -+ mov r9, r8 -+ sub n, 8 -+ -+3: st.d s++, r8 -+ sub n, 8 -+ brge 3b -+ -+ /* If we are done, n == -8 and we'll skip all st.b insns below */ -+ neg n -+ lsl n, 1 -+ add pc, n -+ .rept 7 -+ st.b s++, r8 -+ .endr -+ retal r11 -Index: uClibc-0.9.28-avr32/libc/string/avr32/strcat.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/strcat.S 2006-10-19 15:05:52.000000000 +0200 -@@ -0,0 +1,95 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway -+ */ -+ -+#define s1 r9 -+#define s2 r11 -+ -+ .text -+ .global strcat -+ .type strcat, @function -+ .align 1 -+strcat: -+ mov s1, r12 -+ -+ /* Make sure s1 is word-aligned */ -+ mov r10, s1 -+ andl r10, 3, COH -+ breq 2f -+ -+ add pc, pc, r10 << 3 -+ sub r0, r0, 0 /* 4-byte nop */ -+ ld.ub r8, s1++ -+ sub r8, r8, 0 -+ breq 2f -+ ld.ub r8, s1++ -+ sub r8, r8, 0 -+ breq 3f -+ ld.ub r8, s1++ -+ sub r8, r8, 0 -+ breq 4f -+ -+ /* Find the end of the first string */ -+5: ld.w r8, s1++ -+ tnbz r8 -+ brne 5b -+ -+ sub s1, 4 -+ -+ bfextu r10, r8, 24, 8 -+ cp.w r10, 0 -+ breq 1f -+ sub s1, -1 -+ bfextu r10, r8, 16, 8 -+ cp.w r10, 0 -+ breq 2f -+ sub s1, -1 -+ bfextu r10, r8, 8, 8 -+ cp.w r10, 0 -+ breq 3f -+ sub s1, -1 -+ rjmp 4f -+ -+ /* Now, append s2 */ -+1: ld.ub r8, s2++ -+ st.b s1++, r8 -+ cp.w r8, 0 -+ reteq r12 -+2: ld.ub r8, s2++ -+ st.b s1++, r8 -+ cp.w r8, 0 -+ reteq r12 -+3: ld.ub r8, s2++ -+ st.b s1++, r8 -+ cp.w r8, 0 -+ reteq r12 -+4: ld.ub r8, s2++ -+ st.b s1++, r8 -+ cp.w r8, 0 -+ reteq r12 -+ -+ /* Copy one word at a time */ -+ ld.w r8, s2++ -+ tnbz r8 -+ breq 2f -+1: st.w r8, s2++ -+ ld.w r8, s2++ -+ tnbz r8 -+ brne 1b -+ -+ /* Copy the remaining bytes */ -+ bfextu r10, r8, 24, 8 -+ st.b s1++, r10 -+ cp.w r10, 0 -+ reteq r12 -+ bfextu r10, r8, 16, 8 -+ st.b s1++, r10 -+ cp.w r10, 0 -+ reteq r12 -+ bfextu r10, r8, 8, 8 -+ st.b s1++, r10 -+ cp.w r10, 0 -+ reteq r12 -+ st.b s1++, r8 -+ retal r12 -+ .size strcat, . - strcat -Index: uClibc-0.9.28-avr32/libc/string/avr32/strcmp.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/strcmp.S 2006-10-19 15:05:52.000000000 +0200 -@@ -0,0 +1,80 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway. -+ */ -+ -+#define s1 r12 -+#define s2 r11 -+#define len r10 -+ -+ .text -+ .global strcmp -+ .type strcmp, @function -+ .align 1 -+strcmp: -+ mov r8, 3 -+ tst s1, r8 -+ brne .Lunaligned_s1 -+ tst s2, r8 -+ brne .Lunaligned_s2 -+ -+1: ld.w r8, s1++ -+ ld.w r9, s2++ -+ cp.w r8, r9 -+ brne 2f -+ tnbz r8 -+ brne 1b -+ retal 0 -+ -+2: bfextu r12, r8, 24, 8 -+ bfextu r11, r9, 24, 8 -+ sub r12, r11 -+ retne r12 -+ cp.w r11, 0 -+ reteq 0 -+ bfextu r12, r8, 16, 8 -+ bfextu r11, r9, 16, 8 -+ sub r12, r11 -+ retne r12 -+ cp.w r11, 0 -+ reteq 0 -+ bfextu r12, r8, 8, 8 -+ bfextu r11, r9, 8, 8 -+ sub r12, r11 -+ retne r12 -+ cp.w r11, 0 -+ reteq 0 -+ bfextu r12, r8, 0, 8 -+ bfextu r11, r9, 0, 8 -+ sub r12, r11 -+ retal r12 -+ -+.Lunaligned_s1: -+3: tst s1, r8 -+ breq 4f -+ ld.ub r10, s1++ -+ ld.ub r9, s2++ -+ sub r10, r9 -+ retne r10 -+ cp.w r9, 0 -+ brne 3b -+ retal r10 -+ -+4: tst s2, r8 -+ breq 1b -+ -+.Lunaligned_s2: -+ /* -+ * s1 and s2 can't both be aligned, and unaligned word loads -+ * can trigger spurious exceptions if we cross a page boundary. -+ * Do it the slow way... -+ */ -+1: ld.ub r8, s1++ -+ ld.ub r9, s2++ -+ sub r8, r9 -+ retne r8 -+ cp.w r9, 0 -+ brne 1b -+ retal 0 -+ -+ .weak strcoll -+ strcoll = strcmp -Index: uClibc-0.9.28-avr32/libc/string/avr32/strcpy.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/strcpy.S 2006-10-19 15:05:52.000000000 +0200 -@@ -0,0 +1,63 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway -+ * -+ * To reduce the size, this one might simply call strncpy with len = -1. -+ */ -+ -+#define dst r9 -+#define src r11 -+ -+ .text -+ .global strcpy -+ .type strcpy, @function -+strcpy: -+ mov dst, r12 -+ -+ pref src[0] -+ -+ /* -+ * Check alignment. If src is aligned but dst isn't, we can't -+ * do much about it... -+ */ -+ mov r8, src -+ andl r8, 3 COH -+ brne .Lunaligned_src -+ -+.Laligned_copy: -+1: ld.w r8, src++ -+ tnbz r8 -+ breq 2f -+ st.w dst++, r8 -+ rjmp 1b -+ -+2: /* -+ * Ok, r8 now contains the terminating '\0'. Copy the -+ * remaining bytes individually. -+ */ -+ bfextu r10, r8, 24, 8 -+ st.b dst++, r10 -+ cp.w r10, 0 -+ reteq r12 -+ bfextu r10, r8, 16, 8 -+ st.b dst++, r10 -+ cp.w r10, 0 -+ reteq r12 -+ bfextu r10, r8, 8, 8 -+ st.b dst++, r10 -+ cp.w r10, 0 -+ reteq r12 -+ st.b dst++, r8 -+ retal r12 -+ -+.Lunaligned_src: -+ /* Copy bytes until we're aligned */ -+ rsub r8, r8, 4 -+ add pc, pc, r8 << 3 -+ nop -+ nop -+ ld.ub r10, src++ -+ st.b dst++, r10 -+ cp.w r10, 0 -+ reteq r12 -+ -+ rjmp .Laligned_copy -Index: uClibc-0.9.28-avr32/libc/string/avr32/stringtest.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/stringtest.c 2006-10-19 15:05:52.000000000 +0200 -@@ -0,0 +1,144 @@ -+ -+#include <stdio.h> -+#include <string.h> -+#include <time.h> -+#include <sys/mman.h> -+ -+#define BUF_SIZE (8 * 1024) -+ -+static char *buf1; -+static char *buf1_ref; -+static char *buf2; -+ -+extern void *optimized_memcpy(void *dest, void *src, size_t len); -+extern void *optimized_memmove(void *dest, void *src, size_t len); -+extern char *optimized_strcpy(char *dest, char *src); -+extern char *optimized_strncpy(char *dest, char *src, size_t len); -+ -+void dump_mismatch(char *buf, char *ref, size_t len) -+{ -+ int i, j; -+ -+ for (i = 0; i < len; i += 16) { -+ if (memcmp(buf + i, ref + i, 16) == 0) -+ continue; -+ -+ printf("%4x buf:", i); -+ for (j = i; j < (i + 16); j++) -+ printf(" %02x", buf[j]); -+ printf("\n ref:"); -+ for (j = i; j < (i + 16); j++) -+ printf(" %02x", ref[j]); -+ printf("\n"); -+ } -+} -+ -+static void test_memcpy(int src_offset, int dst_offset, int len) -+{ -+ clock_t start, old, new; -+ int i; -+ -+ memset(buf1, 0x55, BUF_SIZE); -+ memset(buf1_ref, 0x55, BUF_SIZE); -+ memset(buf2, 0xaa, BUF_SIZE); -+ -+ printf("Testing memcpy with offsets %d => %d and len %d...", -+ src_offset, dst_offset, len); -+ -+ start = clock(); -+ for (i = 0; i < 8192; i++) -+ optimized_memcpy(buf1 + dst_offset, buf2 + src_offset, len); -+ new = clock() - start; -+ start = clock(); -+ for ( i = 0; i < 8192; i++) -+ memcpy(buf1_ref + dst_offset, buf2 + src_offset, len); -+ old = clock() - start; -+ -+ if (memcmp(buf1, buf1_ref, BUF_SIZE) == 0) -+ printf("OK\n"); -+ else { -+ printf("FAILED\n"); -+ dump_mismatch(buf1, buf1_ref, BUF_SIZE); -+ } -+ printf("CPU time used: %d vs. %d\n", new, old); -+} -+ -+static void test_memmove(int src_offset, int dst_offset, int len) -+{ -+ clock_t start, old, new; -+ -+ memset(buf1, 0x55, BUF_SIZE); -+ memset(buf1_ref, 0x55, BUF_SIZE); -+ memset(buf2, 0xaa, BUF_SIZE); -+ -+ printf("Testing memmove with offsets %d => %d and len %d...", -+ src_offset, dst_offset, len); -+ -+ start = clock(); -+ optimized_memmove(buf1 + dst_offset, buf2 + src_offset, len); -+ new = clock() - start; -+ start = clock(); -+ memmove(buf1_ref + dst_offset, buf2 + src_offset, len); -+ old = clock() - start; -+ -+ if (memcmp(buf1, buf1_ref, BUF_SIZE) == 0) -+ printf("OK\n"); -+ else { -+ printf("FAILED\n"); -+ dump_mismatch(buf1, buf1_ref, BUF_SIZE); -+ } -+ printf("CPU time used: %d vs. %d\n", new, old); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ buf2 = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE, -+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); -+ if (buf2 == MAP_FAILED) { -+ perror("Failed to allocate memory for buf2"); -+ return 1; -+ } -+ buf1 = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE, -+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); -+ if (buf1 == MAP_FAILED) { -+ perror("Failed to allocate memory for buf1"); -+ return 1; -+ } -+ buf1_ref = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE, -+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); -+ if (buf1_ref == MAP_FAILED) { -+ perror("Failed to allocate memory for buf1_ref"); -+ return 1; -+ } -+ printf("\n === MEMCPY ===\n\n"); -+ -+ test_memcpy(0, 0, BUF_SIZE - 32); -+ test_memcpy(0, 0, 1); -+ test_memcpy(0, 0, 31); -+ test_memcpy(0, 0, 32); -+ test_memcpy(0, 0, 127); -+ test_memcpy(0, 0, 128); -+ test_memcpy(4, 4, BUF_SIZE - 32 - 4); -+ test_memcpy(1, 1, BUF_SIZE - 32 - 1); -+ test_memcpy(1, 1, 126); -+ test_memcpy(0, 3, 128); -+ test_memcpy(1, 4, 128); -+ test_memcpy(0, 0, 0); -+ -+ printf("\n === MEMMOVE ===\n\n"); -+ -+ test_memmove(0, 0, BUF_SIZE - 32); -+ test_memmove(0, 0, 1); -+ test_memmove(0, 0, 31); -+ test_memmove(0, 0, 32); -+ test_memmove(0, 0, BUF_SIZE - 33); -+ test_memmove(0, 0, 128); -+ test_memmove(4, 4, BUF_SIZE - 32 - 4); -+ test_memmove(1, 1, BUF_SIZE - 32 - 1); -+ test_memmove(1, 1, BUF_SIZE - 130); -+ test_memmove(0, 3, BUF_SIZE - 128); -+ test_memmove(1, 4, BUF_SIZE - 128); -+ test_memmove(0, 0, 0); -+ -+ return 0; -+} -Index: uClibc-0.9.28-avr32/libc/string/avr32/strlen.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/strlen.S 2006-10-19 15:05:52.000000000 +0200 -@@ -0,0 +1,52 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway -+ */ -+ -+#define str r12 -+ -+ .text -+ .global strlen -+ .type strlen, @function -+strlen: -+ mov r11, r12 -+ -+ mov r9, str -+ andl r9, 3, COH -+ brne .Lunaligned_str -+ -+1: ld.w r8, str++ -+ tnbz r8 -+ brne 1b -+ -+ sub r12, r11 -+ bfextu r9, r8, 24, 8 -+ cp.w r9, 0 -+ subeq r12, 4 -+ reteq r12 -+ bfextu r9, r8, 16, 8 -+ cp.w r9, 0 -+ subeq r12, 3 -+ reteq r12 -+ bfextu r9, r8, 8, 8 -+ cp.w r9, 0 -+ subeq r12, 2 -+ reteq r12 -+ sub r12, 1 -+ retal r12 -+ -+.Lunaligned_str: -+ add pc, pc, r9 << 3 -+ sub r0, r0, 0 /* 4-byte nop */ -+ ld.ub r8, str++ -+ sub r8, r8, 0 -+ breq 1f -+ ld.ub r8, str++ -+ sub r8, r8, 0 -+ breq 1f -+ ld.ub r8, str++ -+ sub r8, r8, 0 -+ brne 1b -+ -+1: sub r12, 1 -+ sub r12, r11 -+ retal r12 -Index: uClibc-0.9.28-avr32/libc/string/avr32/strncpy.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/strncpy.S 2006-10-19 15:05:52.000000000 +0200 -@@ -0,0 +1,77 @@ -+/* -+ * Copyright (C) 2004 Atmel Norway -+ */ -+ -+#define dst r9 -+#define src r11 -+ -+ .text -+ .global strcpy -+ .type strncpy, @function -+strncpy: -+ mov dst, r12 -+ -+ pref src[0] -+ mov dst, r12 -+ -+ /* -+ * Check alignment. If src is aligned but dst isn't, we can't -+ * do much about it... -+ */ -+ mov r8, src -+ andl r8, 3 COH -+ brne .Lunaligned_src -+ -+.Laligned_copy: -+ sub r10, 4 -+ brlt 3f -+1: ld.w r8, src++ -+ tnbz r8 -+ breq 2f -+ st.w dst++, r8 -+ sub r10, 4 -+ brne 1b -+ -+3: sub r10, -4 -+ reteq r12 -+ -+ /* This is safe as long as src is word-aligned and r10 > 0 */ -+ ld.w r8, src++ -+ -+2: /* -+ * Ok, r8 now contains the terminating '\0'. Copy the -+ * remaining bytes individually. -+ */ -+ bfextu r11, r8, 24, 8 -+ st.b dst++, r11 -+ cp.w r11, 0 -+ reteq r12 -+ sub r10, 1 -+ reteq r12 -+ bfextu r11, r8, 16, 8 -+ st.b dst++, r11 -+ cp.w r11, 0 -+ reteq r12 -+ sub r10, 1 -+ reteq r12 -+ bfextu r11, r8, 8, 8 -+ st.b dst++, r11 -+ cp.w r11, 0 -+ reteq r12 -+ sub r10, 1 -+ reteq r12 -+ st.b dst++, r8 -+ retal r12 -+ -+.Lunaligned_src: -+ /* Copy bytes until we're aligned */ -+ min r8, r8, r10 -+ sub r10, r8 -+ sub r8, 1 -+ retlt r12 -+1: ld.ub r10, src++ -+ st.b dst++, r10 -+ sub r8, 1 -+ brge 1b -+ -+ rjmp .Laligned_copy -Index: uClibc-0.9.28-avr32/libc/string/avr32/test_memcpy.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28-avr32/libc/string/avr32/test_memcpy.c 2006-10-19 15:05:52.000000000 +0200 -@@ -0,0 +1,66 @@ -+ -+#include <stdio.h> -+#include <string.h> -+ -+#define BUF_SIZE 32768 -+ -+static char buf1[BUF_SIZE] __attribute__((aligned(32))); -+static char buf1_ref[BUF_SIZE] __attribute__((aligned(32))); -+static char buf2[BUF_SIZE] __attribute__((aligned(32))); -+ -+extern void *new_memcpy(void *dest, void *src, size_t len); -+ -+void dump_mismatch(char *buf, char *ref, size_t len) -+{ -+ int i, j; -+ -+ for (i = 0; i < len; i += 16) { -+ if (memcmp(buf + i, ref + i, 16) == 0) -+ continue; -+ -+ printf("% 4x buf:", i); -+ for (j = i; j < (i + 16); j++) -+ printf(" %02x", buf[j]); -+ printf("\n ref:"); -+ for (j = i; j < (i + 16); j++) -+ printf(" %02x", ref[j]); -+ printf("\n"); -+ } -+} -+ -+void test(int src_offset, int dst_offset, int len) -+{ -+ memset(buf1, 0x55, sizeof(buf1)); -+ memset(buf1_ref, 0x55, sizeof(buf1_ref)); -+ memset(buf2, 0xaa, sizeof(buf2)); -+ -+ printf("Testing with offsets %d => %d and len %d...", -+ src_offset, dst_offset, len); -+ -+ new_memcpy(buf1 + dst_offset, buf2 + src_offset, len); -+ memcpy(buf1_ref + dst_offset, buf2 + src_offset, len); -+ -+ if (memcmp(buf1, buf1_ref, sizeof(buf1)) == 0) -+ printf("OK\n"); -+ else { -+ printf("FAILED\n"); -+ dump_mismatch(buf1, buf1_ref, sizeof(buf1)); -+ } -+} -+ -+int main(int argc, char *argv[]) -+{ -+ test(0, 0, BUF_SIZE); -+ test(0, 0, 1); -+ test(0, 0, 31); -+ test(0, 0, 32); -+ test(0, 0, 127); -+ test(0, 0, 128); -+ test(4, 4, BUF_SIZE - 4); -+ test(1, 1, BUF_SIZE - 1); -+ test(1, 1, 126); -+ test(0, 3, 128); -+ test(1, 4, 128); -+ -+ return 0; -+} -Subject: [PATCH] Don't include create_module() for AVR32 - -The create_module() system call is obsolete in Linux 2.6, so the -AVR32 kernel doesn't even have it. - -Come to think about it, this should be completely unnecessary as the -create_module function is only a stub when __NR_create_module is -undefined. ---- - - libc/sysdeps/linux/common/create_module.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -Index: uClibc-0.9.28/libc/sysdeps/linux/common/create_module.c -=================================================================== ---- uClibc-0.9.28.orig/libc/sysdeps/linux/common/create_module.c 2006-02-07 16:48:38.000000000 +0100 -+++ uClibc-0.9.28/libc/sysdeps/linux/common/create_module.c 2006-02-07 17:17:14.000000000 +0100 -@@ -61,7 +61,8 @@ unsigned long create_module(const char * - { - return __create_module(name, size, 0, 0); - } --#else -+/* create_module is obsolete in Linux 2.6, so AVR32 doesn't have it */ -+#elif !defined(__avr32__) - /* Sparc, MIPS, etc don't mistake return values for errors. */ - _syscall2(unsigned long, create_module, const char *, name, size_t, size); - #endif -Subject: [PATCH] ldso: Always inline _dl_memcpy() - -On some gcc versions, inline is merely a hint. AVR32 depends on this -function actually getting inlined, so we need to use __always_inline -instead of just inline. - ---- - - ldso/include/dl-string.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -Index: uClibc-0.9.28/ldso/include/dl-string.h -=================================================================== ---- uClibc-0.9.28.orig/ldso/include/dl-string.h 2006-02-07 17:01:28.000000000 +0100 -+++ uClibc-0.9.28/ldso/include/dl-string.h 2006-02-07 17:03:02.000000000 +0100 -@@ -134,7 +134,7 @@ static inline char * _dl_strstr(const ch - } while (1); - } - --static inline void * _dl_memcpy(void * dst, const void * src, size_t len) -+static __always_inline void * _dl_memcpy(void * dst, const void * src, size_t len) - { - register char *a = dst-1; - register const char *b = src-1; -Subject: [PATCH] ldso: Define MAP_FAILED for _dl_mmap() - -When using mmap2() to emulate mmap(), _dl_mmap() uses MAP_FAILED to -indicate failure. MAP_FAILED is not defined anywhere, so this patch -defines it. - ---- - - ldso/include/dl-syscall.h | 1 + - 1 file changed, 1 insertion(+) - -Index: uClibc-0.9.28/ldso/include/dl-syscall.h -=================================================================== ---- uClibc-0.9.28.orig/ldso/include/dl-syscall.h 2006-02-07 16:49:27.000000000 +0100 -+++ uClibc-0.9.28/ldso/include/dl-syscall.h 2006-02-07 17:07:06.000000000 +0100 -@@ -132,6 +132,7 @@ static inline _syscall6(__ptr_t, __sysca - size_t, len, int, prot, int, flags, int, fd, off_t, offset); - /*always 12, even on architectures where PAGE_SHIFT != 12 */ - #define MMAP2_PAGE_SHIFT 12 -+#define MAP_FAILED ((void *) -1) - static inline void * _dl_mmap(void * addr, unsigned long size, int prot, - int flags, int fd, unsigned long offset) - { -Subject: [PATCH] ldso: Always inline system calls - -Some versions of gcc consider inline merely a hint. AVR32 depends on -the system calls actually being inlined, so we need to use -__always_inline instead of just inline. - ---- - - ldso/include/dl-syscall.h | 38 +++++++++++++++++++------------------- - 1 file changed, 19 insertions(+), 19 deletions(-) - -Index: uClibc-0.9.28/ldso/include/dl-syscall.h -=================================================================== ---- uClibc-0.9.28.orig/ldso/include/dl-syscall.h 2006-02-07 17:07:06.000000000 +0100 -+++ uClibc-0.9.28/ldso/include/dl-syscall.h 2006-02-07 17:08:47.000000000 +0100 -@@ -60,59 +60,59 @@ - dynamic linking at all, so we cannot return any error codes. - We just punt if there is an error. */ - #define __NR__dl_exit __NR_exit --static inline _syscall1(void, _dl_exit, int, status); -+static __always_inline _syscall1(void, _dl_exit, int, status); - - #define __NR__dl_close __NR_close --static inline _syscall1(int, _dl_close, int, fd); -+static __always_inline _syscall1(int, _dl_close, int, fd); - - #define __NR__dl_open __NR_open --static inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode); -+static __always_inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode); - - #define __NR__dl_write __NR_write --static inline _syscall3(unsigned long, _dl_write, int, fd, -+static __always_inline _syscall3(unsigned long, _dl_write, int, fd, - const void *, buf, unsigned long, count); - - #define __NR__dl_read __NR_read --static inline _syscall3(unsigned long, _dl_read, int, fd, -+static __always_inline _syscall3(unsigned long, _dl_read, int, fd, - const void *, buf, unsigned long, count); - - #define __NR__dl_mprotect __NR_mprotect --static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot); -+static __always_inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot); - - #define __NR__dl_stat __NR_stat --static inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf); -+static __always_inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf); - - #define __NR__dl_munmap __NR_munmap --static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length); -+static __always_inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length); - - #define __NR__dl_getuid __NR_getuid --static inline _syscall0(uid_t, _dl_getuid); -+static __always_inline _syscall0(uid_t, _dl_getuid); - - #define __NR__dl_geteuid __NR_geteuid --static inline _syscall0(uid_t, _dl_geteuid); -+static __always_inline _syscall0(uid_t, _dl_geteuid); - - #define __NR__dl_getgid __NR_getgid --static inline _syscall0(gid_t, _dl_getgid); -+static __always_inline _syscall0(gid_t, _dl_getgid); - - #define __NR__dl_getegid __NR_getegid --static inline _syscall0(gid_t, _dl_getegid); -+static __always_inline _syscall0(gid_t, _dl_getegid); - - #define __NR__dl_getpid __NR_getpid --static inline _syscall0(gid_t, _dl_getpid); -+static __always_inline _syscall0(gid_t, _dl_getpid); - - #define __NR__dl_readlink __NR_readlink --static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz); -+static __always_inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz); - - #ifdef __NR_mmap - #ifdef MMAP_HAS_6_ARGS - #define __NR__dl_mmap __NR_mmap --static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length, -+static __always_inline _syscall6(void *, _dl_mmap, void *, start, size_t, length, - int, prot, int, flags, int, fd, off_t, offset); - #else - #define __NR__dl_mmap_real __NR_mmap --static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer); -+static __always_inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer); - --static inline void * _dl_mmap(void * addr, unsigned long size, int prot, -+static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot, - int flags, int fd, unsigned long offset) - { - unsigned long buffer[6]; -@@ -128,12 +128,12 @@ static inline void * _dl_mmap(void * add - #endif - #elif defined __NR_mmap2 - #define __NR___syscall_mmap2 __NR_mmap2 --static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, -+static __always_inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, - size_t, len, int, prot, int, flags, int, fd, off_t, offset); - /*always 12, even on architectures where PAGE_SHIFT != 12 */ - #define MMAP2_PAGE_SHIFT 12 - #define MAP_FAILED ((void *) -1) --static inline void * _dl_mmap(void * addr, unsigned long size, int prot, -+static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot, - int flags, int fd, unsigned long offset) - { - if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1)) -Subject: [PATCH] ldso: AVR32 support - -This implements the AVR32-specific parts of the dynamic linker. - ---- - - ldso/ldso/avr32/dl-debug.h | 45 +++++++++ - ldso/ldso/avr32/dl-startup.h | 110 ++++++++++++++++++++++++ - ldso/ldso/avr32/dl-syscalls.h | 5 + - ldso/ldso/avr32/dl-sysdep.h | 103 ++++++++++++++++++++++ - ldso/ldso/avr32/elfinterp.c | 191 ++++++++++++++++++++++++++++++++++++++++++ - ldso/ldso/avr32/resolve.S | 28 ++++++ - 6 files changed, 482 insertions(+) - -Index: uClibc-0.9.28/ldso/ldso/avr32/dl-debug.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/ldso/ldso/avr32/dl-debug.h 2006-05-05 09:30:43.000000000 +0200 -@@ -0,0 +1,45 @@ -+/* -+ * AVR32 ELF shared libary loader support -+ * -+ * Copyright (C) 2005 Atmel Norway -+ * 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_AVR32_NONE", -+ "R_AVR32_32", "R_AVR32_16", "R_AVR32_8", -+ "R_AVR32_32_PCREL", "R_AVR32_16_PCREL", "R_AVR32_8_PCREL", -+ "R_AVR32_DIFF32", "R_AVR32_DIFF16", "R_AVR32_DIFF8", -+ "R_AVR32_GOT32", "R_AVR32_GOT16", "R_AVR32_GOT8", -+ "R_AVR32_21S", "R_AVR32_16U", "R_AVR32_16S", "R_AVR32_8S", "R_AVR32_8S_EXT", -+ "R_AVR32_22H_PCREL", "R_AVR32_18W_PCREL", "R_AVR32_16B_PCREL", -+ "R_AVR32_16N_PCREL", "R_AVR32_14UW_PCREL", "R_AVR32_11H_PCREL", -+ "R_AVR32_10UW_PCREL", "R_AVR32_9H_PCREL", "R_AVR32_9UW_PCREL", -+ "R_AVR32_HI16", "R_AVR32_LO16", -+ "R_AVR32_GOTPC", "R_AVR32_GOTCALL", "R_AVR32_LDA_GOT", -+ "R_AVR32_GOT21S", "R_AVR32_GOT18SW", "R_AVR32_GOT16S", "R_AVR32_GOT7UW", -+ "R_AVR32_32_CPENT", "R_AVR32_CPCALL", "R_AVR32_16_CP", "R_AVR32_9W_CP", -+ "R_AVR32_RELATIVE", "R_AVR32_GLOB_DAT", "R_AVR32_JMP_SLOT", -+ "R_AVR32_ALIGN", -+}; -Index: uClibc-0.9.28/ldso/ldso/avr32/dl-startup.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/ldso/ldso/avr32/dl-startup.h 2006-05-05 09:29:45.000000000 +0200 -@@ -0,0 +1,110 @@ -+/* vi: set sw=4 ts=4: */ -+/* -+ * Architecture specific code used by dl-startup.c -+ * Copyright (C) 2005 Atmel Norway -+ */ -+ -+/* This is the library loader's main entry point. Let _dl_boot2 do its -+ * initializations and jump to the application's entry point -+ * afterwards. */ -+asm( " .text\n" -+ " .global _start\n" -+ " .type _start,@function\n" -+ "_start:\n" -+ /* All arguments are on the stack initially */ -+ " mov r12, sp\n" -+ " rcall _dl_start\n" -+ /* Returns user entry point in r12. Save it. */ -+ " mov r0, r12\n" -+ /* We're PIC, so get the Global Offset Table */ -+ " lddpc r6, .L_GOT\n" -+ ".L_RGOT:\n" -+ " rsub r6, pc\n" -+ /* Adjust argc and argv according to _dl_skip_args */ -+ " ld.w r1, r6[_dl_skip_args@got]\n" -+ " ld.w r1, r1[0]\n" -+ " ld.w r2, sp++\n" -+ " sub r2, r1\n" -+ " add sp, sp, r1 << 2\n" -+ " st.w --sp, r2\n" -+ /* Load the finalizer function */ -+ " ld.w r12, r6[_dl_fini@got]\n" -+ /* Jump to the user's entry point */ -+ " mov pc, r0\n\n" -+ -+ " .align 2\n" -+ ".L_GOT:" -+ " .long .L_RGOT - _GLOBAL_OFFSET_TABLE_\n" -+ " .size _start, . - _start\n" -+ " .previous\n"); -+ -+/* 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) -+ -+ -+/* We can't call functions before the GOT has been initialized */ -+#define NO_FUNCS_BEFORE_BOOTSTRAP -+ -+/* -+ * Relocate the GOT during dynamic loader bootstrap. This will add -+ * the load address to all entries in the GOT, which is necessary -+ * because the linker doesn't generate R_AVR32_RELATIVE relocs for the -+ * GOT. -+ */ -+static __always_inline -+void PERFORM_BOOTSTRAP_GOT(struct elf_resolve *tpnt) -+{ -+ Elf32_Addr i, nr_got; -+ register Elf32_Addr *__r6 __asm__("r6"); -+ Elf32_Addr *got = __r6; -+ -+ nr_got = tpnt->dynamic_info[DT_AVR32_GOTSZ_IDX] / sizeof(*got); -+ for (i = 2; i < nr_got; i++) -+ got[i] += tpnt->loadaddr; -+} -+ -+#define PERFORM_BOOTSTRAP_GOT(tpnt) PERFORM_BOOTSTRAP_GOT(tpnt) -+ -+/* Handle relocation of the symbols in the dynamic loader. */ -+static __always_inline -+void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr, -+ unsigned long symbol_addr, -+ unsigned long load_addr, Elf32_Sym *symtab) -+{ -+ switch(ELF32_R_TYPE(rpnt->r_info)) { -+ case R_AVR32_NONE: -+ break; -+ case R_AVR32_GLOB_DAT: -+ case R_AVR32_JMP_SLOT: -+ *reloc_addr = symbol_addr; -+ break; -+ case R_AVR32_RELATIVE: -+ SEND_STDERR_DEBUG("Applying RELATIVE relocation: "); -+ SEND_ADDRESS_STDERR_DEBUG(load_addr, 0); -+ SEND_STDERR_DEBUG(" + "); -+ SEND_ADDRESS_STDERR_DEBUG(rpnt->r_addend, 1); -+ *reloc_addr = load_addr + rpnt->r_addend; -+ break; -+ default: -+ SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc_type "); -+ SEND_NUMBER_STDERR(ELF32_R_TYPE(rpnt->r_info), 1); -+ SEND_STDERR("REL, SYMBOL, LOAD: "); -+ SEND_ADDRESS_STDERR(reloc_addr, 0); -+ SEND_STDERR(", "); -+ SEND_ADDRESS_STDERR(symbol_addr, 0); -+ SEND_STDERR(", "); -+ SEND_ADDRESS_STDERR(load_addr, 1); -+ _dl_exit(1); -+ } -+} -+ -+/* Transfer control to the user's application, once the dynamic loader -+ * is done. This routine has to exit the current function, then call -+ * the _dl_elf_main function. -+ * -+ * Since our _dl_boot will simply call whatever is returned by -+ * _dl_boot2, we can just return the address we're supposed to -+ * call. */ -+#define START() return _dl_elf_main; -Index: uClibc-0.9.28/ldso/ldso/avr32/dl-syscalls.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/ldso/ldso/avr32/dl-syscalls.h 2006-05-05 09:29:25.000000000 +0200 -@@ -0,0 +1,5 @@ -+/* We can't use the real errno in ldso, since it has not yet -+ * been dynamicly linked in yet. */ -+extern int _dl_errno; -+#define __set_errno(X) {(_dl_errno) = (X);} -+#include "sys/syscall.h" -Index: uClibc-0.9.28/ldso/ldso/avr32/dl-sysdep.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/ldso/ldso/avr32/dl-sysdep.h 2006-05-05 09:30:43.000000000 +0200 -@@ -0,0 +1,103 @@ -+/* vi: set sw=4 ts=4: */ -+/* -+ * Various assembly language/system dependent hacks that are required -+ * so that we can minimize the amount of platform specific code. -+ * Copyright (C) 2004-2005 Atmel Norway -+ */ -+ -+/* Define this if the system uses RELOCA. */ -+#define ELF_USES_RELOCA -+ -+#include <elf.h> -+ -+#define ARCH_NUM 1 -+#define DT_AVR32_GOTSZ_IDX (DT_NUM + OS_NUM) -+ -+#define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr) \ -+ do { \ -+ if (dpnt->d_tag == DT_AVR32_GOTSZ) \ -+ dynamic[DT_AVR32_GOTSZ_IDX] = dpnt->d_un.d_val; \ -+ } while (0) -+ -+/* Initialization sequence for the application/library GOT. */ -+#define INIT_GOT(GOT_BASE,MODULE) \ -+ do { \ -+ unsigned long i, nr_got; \ -+ \ -+ GOT_BASE[0] = (unsigned long) _dl_linux_resolve; \ -+ GOT_BASE[1] = (unsigned long) MODULE; \ -+ \ -+ /* Add load address displacement to all GOT entries */ \ -+ nr_got = MODULE->dynamic_info[DT_AVR32_GOTSZ_IDX] / 4; \ -+ for (i = 2; i < nr_got; i++) \ -+ GOT_BASE[i] += (unsigned long)MODULE->loadaddr; \ -+ } while (0) -+ -+#define do_rem(result, n, base) ((result) = (n) % (base)) -+ -+/* Here we define the magic numbers that this dynamic loader should accept */ -+#define MAGIC1 EM_AVR32 -+#undef MAGIC2 -+ -+/* Used for error messages */ -+#define ELF_TARGET "AVR32" -+ -+unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got); -+ -+/* 4096 bytes alignment */ -+#define PAGE_ALIGN 0xfffff000 -+#define ADDR_ALIGN 0xfff -+#define OFFS_ALIGN 0x7ffff000 -+ -+#define elf_machine_type_class(type) \ -+ ((type == R_AVR32_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) -+ -+/* AVR32 doesn't need any COPY relocs */ -+#define DL_NO_COPY_RELOCS -+ -+/* Return the link-time address of _DYNAMIC. Conveniently, this is the -+ first element of the GOT. This must be inlined in a function which -+ uses global data. */ -+static inline Elf32_Addr -+elf_machine_dynamic (void) -+{ -+ register Elf32_Addr *got asm ("r6"); -+ return *got; -+} -+ -+/* Return the run-time load address of the shared object. */ -+static inline Elf32_Addr -+elf_machine_load_address (void) -+{ -+ extern void __dl_start asm("_dl_start"); -+ Elf32_Addr got_addr = (Elf32_Addr) &__dl_start; -+ Elf32_Addr pcrel_addr; -+ -+ asm (" lddpc %0, 2f\n" -+ "1: add %0, pc\n" -+ " rjmp 3f\n" -+ " .align 2\n" -+ "2: .long _dl_start - 1b\n" -+ "3:\n" -+ : "=r"(pcrel_addr) : : "cc"); -+ -+ return pcrel_addr - got_addr; -+} -+ -+/* -+ * Perform any RELATIVE relocations specified by DT_RELCOUNT. -+ * Currently, we don't use that tag, but we might in the future as -+ * this would reduce the startup time somewhat (although probably not by much). -+ */ -+static inline void -+elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, -+ Elf32_Word relative_count) -+{ -+ Elf32_Rela *rpnt = (void *)rel_addr; -+ -+ do { -+ Elf32_Addr *reloc_addr; -+ reloc_addr = (void *)(load_off + (rpnt++)->r_offset); -+ *reloc_addr = load_off + rpnt->r_addend; -+ } while (--relative_count); -+} -Index: uClibc-0.9.28/ldso/ldso/avr32/elfinterp.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/ldso/ldso/avr32/elfinterp.c 2006-05-05 09:30:43.000000000 +0200 -@@ -0,0 +1,191 @@ -+/* -+ * AVR32 ELF shared library loader suppport -+ * -+ * Copyright (C) 2004-2006 Atmel Corporation -+ * -+ * 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. -+ */ -+ -+unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got) -+{ -+ struct elf_resolve *tpnt = (struct elf_resolve *)got[1]; -+ Elf32_Sym *sym; -+ unsigned long local_gotno; -+ unsigned long gotsym; -+ unsigned long new_addr; -+ char *strtab, *symname; -+ unsigned long *entry; -+ unsigned long sym_index = got_offset / 4; -+ -+#if 0 -+ local_gotno = tpnt->dynamic_info[DT_AVR32_LOCAL_GOTNO]; -+ gotsym = tpnt->dynamic_info[DT_AVR32_GOTSYM]; -+ -+ sym = ((Elf32_Sym *)(tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr)) -+ + sym_index; -+ strtab = (char *)(tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); -+ symname = strtab + sym->st_name; -+ -+#if 0 -+ new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name, -+ tpnt->symbol_scope, tpnt, -+ resolver); -+#endif -+ -+ entry = (unsigned long *)(got + local_gotno + sym_index - gotsym); -+ *entry = new_addr; -+#endif -+ -+ return new_addr; -+} -+ -+static int -+_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, -+ unsigned long rel_addr, unsigned long rel_size, -+ int (*reloc_func)(struct elf_resolve *tpnt, struct dyn_elf *scope, -+ Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab)) -+{ -+ Elf32_Sym *symtab; -+ Elf32_Rela *rpnt; -+ char *strtab; -+ int i; -+ -+ rpnt = (Elf32_Rela *)rel_addr; -+ rel_size /= sizeof(Elf32_Rela); -+ symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB]; -+ strtab = (char *)tpnt->dynamic_info[DT_STRTAB]; -+ -+ for (i = 0; i < rel_size; i++, rpnt++) { -+ int symtab_index, res; -+ -+ symtab_index = ELF32_R_SYM(rpnt->r_info); -+ -+ debug_sym(symtab, strtab, symtab_index); -+ debug_reloc(symtab, strtab, rpnt); -+ -+ res = reloc_func(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 = ELF32_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 { -+ _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, -+ Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab) -+{ -+ int reloc_type; -+ int symtab_index; -+ char *symname; -+ unsigned long *reloc_addr; -+ unsigned long symbol_addr; -+#if defined(__SUPPORT_LD_DEBUG__) -+ unsigned long old_val; -+#endif -+ -+ reloc_addr = (unsigned long *)(tpnt->loadaddr + rpnt->r_offset); -+ reloc_type = ELF32_R_TYPE(rpnt->r_info); -+ symtab_index = ELF32_R_SYM(rpnt->r_info); -+ symbol_addr = 0; -+ symname = strtab + symtab[symtab_index].st_name; -+ -+ if (symtab_index) { -+ symbol_addr = (unsigned long) -+ _dl_find_hash(strtab + symtab[symtab_index].st_name, -+ tpnt->symbol_scope, tpnt, -+ elf_machine_type_class(reloc_type)); -+ -+ /* Allow undefined references to weak symbols */ -+ if (!symbol_addr && -+ ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) { -+ _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", -+ _dl_progname, symname); -+ return 0; -+ } -+ } -+ -+#if defined(__SUPPORT_LD_DEBUG__) -+ old_val = *reloc_addr; -+#endif -+ switch (reloc_type) { -+ case R_AVR32_NONE: -+ break; -+ case R_AVR32_GLOB_DAT: -+ case R_AVR32_JMP_SLOT: -+ *reloc_addr = symbol_addr + rpnt->r_addend; -+ break; -+ case R_AVR32_RELATIVE: -+ *reloc_addr = (unsigned long)tpnt->loadaddr -+ + rpnt->r_addend; -+ 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\n", -+ old_val, *reloc_addr); -+#endif -+ -+ return 0; -+} -+ -+void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, -+ unsigned long rel_addr, -+ unsigned long rel_size) -+{ -+ /* TODO: Might want to support this in order to get faster -+ * startup times... */ -+} -+ -+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); -+} -Index: uClibc-0.9.28/ldso/ldso/avr32/resolve.S -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/ldso/ldso/avr32/resolve.S 2006-05-05 09:29:25.000000000 +0200 -@@ -0,0 +1,28 @@ -+/* -+ * Linux dynamic resolving code for AVR32. Fixes up the GOT entry as -+ * indicated in register r12 and jumps to the resolved address. -+ * -+ * This file is subject to the terms and conditions of the GNU Lesser General -+ * Public License. See the file "COPYING.LIB" in the main directory of this -+ * archive for more details. -+ * -+ * Copyright (C) 2004 Atmel Norway -+ */ -+ -+#define ip r5 -+ -+ .text -+ .global _dl_linux_resolve -+ .type _dl_linux_resolve,@function -+_dl_linux_resolve: -+ /* The PLT code pushed r8 for us. It contains the address of this -+ function's GOT entry, that is entry 0. ip contains the address -+ of the GOT entry of the function we wanted to call. */ -+ stm --sp, r9-r12, lr -+ mov r11, r8 -+ sub r12, ip, r8 -+ rcall _dl_linux_resolver -+ mov ip, r12 -+ popm r8-r12,lr -+ mov pc, ip -+ .size _dl_linux_resolve, . - _dl_linux_resolve -Subject: [PATCH] ldso: AVR32 needs CONSTANT_STRING_GOT_FIXUP - -Add AVR32 to the list of architectures needing CONSTANT_STRING_GOT_FIXUP. - ---- - - ldso/include/dl-string.h | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -Index: uClibc-0.9.28/ldso/include/dl-string.h -=================================================================== ---- uClibc-0.9.28.orig/ldso/include/dl-string.h 2006-02-07 16:58:58.000000000 +0100 -+++ uClibc-0.9.28/ldso/include/dl-string.h 2006-02-07 16:59:28.000000000 +0100 -@@ -271,7 +271,8 @@ static __always_inline char * _dl_simple - /* On some arches constant strings are referenced through the GOT. - * This requires that load_addr must already be defined... */ - #if defined(mc68000) || defined(__arm__) || defined(__mips__) \ -- || defined(__sh__) || defined(__powerpc__) -+ || defined(__sh__) || defined(__powerpc__) \ -+ || defined(__avr32__) - # define CONSTANT_STRING_GOT_FIXUP(X) \ - if ((X) < (const char *) load_addr) (X) += load_addr - # define NO_EARLY_SEND_STDERR -Subject: [PATCH] ldso: AVR32 startup hack - -AVR32 needs to do both PERFORM_BOOTSTRAP_GOT and a full relocation of -the GOT. I don't quite remember why, but I think it's because some GOT -entries just need the load address added to them, while the rest need -the full relocation code. - -This patch should be revisited to figure out whether we're processing -relocations against undefined symbols and whether that's something we -should be doing... - ---- - - ldso/ldso/dl-startup.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -Index: uClibc-0.9.28/ldso/ldso/dl-startup.c -=================================================================== ---- uClibc-0.9.28.orig/ldso/ldso/dl-startup.c 2006-02-07 16:49:27.000000000 +0100 -+++ uClibc-0.9.28/ldso/ldso/dl-startup.c 2006-02-07 17:12:09.000000000 +0100 -@@ -217,7 +217,9 @@ static void * __attribute_used__ _dl_sta - /* some arches (like MIPS) we have to tweak the GOT before relocations */ - PERFORM_BOOTSTRAP_GOT(tpnt); - --#else -+#endif -+ -+#if !defined(PERFORM_BOOTSTRAP_GOT) || defined(__avr32__) - - /* OK, now do the relocations. We do not do a lazy binding here, so - that once we are done, we have considerably more flexibility. */ -@@ -259,7 +261,7 @@ static void * __attribute_used__ _dl_sta - rel_addr += relative_count * sizeof(ELF_RELOC);; - } - -- rpnt = (ELF_RELOC *) (rel_addr + load_addr); -+ rpnt = (ELF_RELOC *) (rel_addr /* + load_addr */); - for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) { - reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset); - symtab_index = ELF_R_SYM(rpnt->r_info); -Subject: [PATCH] ldd: AVR32 support - -Add AVR32-specific definitions to ldd. - ---- - - utils/ldd.c | 5 +++++ - 1 file changed, 5 insertions(+) - -Index: uClibc-0.9.28/utils/ldd.c -=================================================================== ---- uClibc-0.9.28.orig/utils/ldd.c 2006-02-07 16:48:02.000000000 +0100 -+++ uClibc-0.9.28/utils/ldd.c 2006-02-07 17:13:00.000000000 +0100 -@@ -56,6 +56,11 @@ - #define ELFCLASSM ELFCLASS32 - #endif - -+#if defined(__avr32__) -+#define MATCH_MACHINE(x) (x == EM_AVR32) -+#define ELFCLASSM ELFCLASS32 -+#endif -+ - #if defined(__s390__) - #define MATCH_MACHINE(x) (x == EM_S390) - #define ELFCLASSM ELFCLASS32 -Subject: [PATCH] libpthread: AVR32 support - -Implement pt-machine.h for AVR32. ---- - - libpthread/linuxthreads/sysdeps/avr32/pt-machine.h | 92 +++++++++++++++++++++ - 1 file changed, 92 insertions(+) - -Index: uClibc-0.9.28/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ uClibc-0.9.28/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h 2006-02-07 17:14:47.000000000 +0100 -@@ -0,0 +1,92 @@ -+/* Machine-dependent pthreads configuration and inline functions. -+ -+ Copyright (C) 2005 Atmel Norway -+ 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; 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> -+ -+static inline int -+_test_and_set (int *p, int v) __THROW -+{ -+ int result; -+ -+ __asm__ __volatile__( -+ "/* Inline test and set */\n" -+ "1: ssrf 5\n" -+ " ld.w %0, %2\n" -+ " tst %0, %3\n" -+ " breq 2f\n" -+ " stcond %1, %3\n" -+ " brne 1b\n" -+ "2:" -+ : "=&r"(result), "=m"(*p) -+ : "m"(*p), "r"(v) -+ : "memory", "cc"); -+ -+ return result; -+} -+ -+#ifndef PT_EI -+# define PT_EI extern inline -+#endif -+ -+extern long int testandset (int *spinlock); -+extern int __compare_and_swap (long int *p, long int oldval, long int newval); -+ -+/* Spinlock implementation; required. */ -+PT_EI long int -+testandset (int *spinlock) -+{ -+ return _test_and_set(spinlock, 1); -+} -+ -+ -+/* Get some notion of the current stack. Need not be exactly the top -+ of the stack, just something somewhere in the current frame. */ -+#define CURRENT_STACK_FRAME stack_pointer -+register char * stack_pointer __asm__ ("sp"); -+ -+/* Compare-and-swap for semaphores. */ -+ -+#define HAS_COMPARE_AND_SWAP -+PT_EI int -+__compare_and_swap(long int *p, long int oldval, long int newval) -+{ -+ long int result, tmp; -+ -+ __asm__ __volatile__( -+ "/* Inline compare and swap */\n" -+ "1: ssrf 5\n" -+ " ld.w %1, %3\n" -+ " cp.w %1, %5\n" -+ " sreq %0\n" -+ " brne 2f\n" -+ " stcond %2, %4\n" -+ " brne 1b\n" -+ "2:" -+ : "=&r"(result), "=&r"(tmp), "=m"(*p) -+ : "m"(*p), "r"(newval), "r"(oldval) -+ : "cc", "memory"); -+ -+ return result; -+} -+ -+#endif /* pt-machine.h */ ---- - libc/sysdeps/linux/avr32/bits/fcntl.h | 33 +++++++++++++++++---------------- - 1 file changed, 17 insertions(+), 16 deletions(-) - -Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/fcntl.h -=================================================================== ---- uClibc-0.9.28-avr32.orig/libc/sysdeps/linux/avr32/bits/fcntl.h 2006-11-23 17:38:30.000000000 +0100 -+++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/fcntl.h 2006-11-23 17:52:15.000000000 +0100 -@@ -11,28 +11,29 @@ - - /* 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_ACCMODE 00000003 -+#define O_RDONLY 00000000 -+#define O_WRONLY 00000001 -+#define O_RDWR 00000002 -+#define O_CREAT 00000100 /* not fcntl */ -+#define O_EXCL 00000200 /* not fcntl */ -+#define O_NOCTTY 00000400 /* not fcntl */ -+#define O_TRUNC 00001000 /* not fcntl */ -+#define O_APPEND 00002000 -+#define O_NONBLOCK 00004000 - #define O_NDELAY O_NONBLOCK --#define O_SYNC 010000 --#define O_ASYNC 020000 -+#define O_SYNC 00010000 -+#define O_ASYNC 00020000 - - #ifdef __USE_GNU --# define O_DIRECTORY 040000 /* must be a directory */ --# define O_NOFOLLOW 0100000 /* don't follow links */ --# define O_DIRECT 0200000 /* direct disk access */ -+# define O_DIRECT 00040000 /* must be a directory */ -+# define O_DIRECTORY 00200000 /* direct disk access */ -+# define O_NOFOLLOW 00400000 /* don't follow links */ -+# define O_NOATIME 01000000 /* don't set atime */ - #endif - - #ifdef __USE_LARGEFILE64 --# define O_LARGEFILE 0400000 -+# define O_LARGEFILE 00100000 - #endif - - /* For now Linux has synchronisity options for data and read operations. |