summaryrefslogtreecommitdiffstats
path: root/toolchain/uClibc/uClibc-0.9.28-host-ldconfig.patch
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2007-01-25 20:27:27 +0000
committerEric Andersen <andersen@codepoet.org>2007-01-25 20:27:27 +0000
commitc78e178f37ee0c7405eb58730a4ebc0654e8b9b7 (patch)
treee24fd917c6200a30cc47b793bdff94a5140d17d1 /toolchain/uClibc/uClibc-0.9.28-host-ldconfig.patch
parentd8c52bc7401b0988be3ab670c8b0b1609e2c895f (diff)
downloadbuildroot-novena-c78e178f37ee0c7405eb58730a4ebc0654e8b9b7.tar.gz
buildroot-novena-c78e178f37ee0c7405eb58730a4ebc0654e8b9b7.zip
A patch set that should probably become uClibc-0.9.28.1
Diffstat (limited to 'toolchain/uClibc/uClibc-0.9.28-host-ldconfig.patch')
-rw-r--r--toolchain/uClibc/uClibc-0.9.28-host-ldconfig.patch635
1 files changed, 635 insertions, 0 deletions
diff --git a/toolchain/uClibc/uClibc-0.9.28-host-ldconfig.patch b/toolchain/uClibc/uClibc-0.9.28-host-ldconfig.patch
new file mode 100644
index 000000000..f55c3498a
--- /dev/null
+++ b/toolchain/uClibc/uClibc-0.9.28-host-ldconfig.patch
@@ -0,0 +1,635 @@
+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)