diff options
author | Eric Andersen <andersen@codepoet.org> | 2007-01-25 20:27:27 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2007-01-25 20:27:27 +0000 |
commit | c78e178f37ee0c7405eb58730a4ebc0654e8b9b7 (patch) | |
tree | e24fd917c6200a30cc47b793bdff94a5140d17d1 /toolchain/uClibc/uClibc-0.9.28-host-ldconfig.patch | |
parent | d8c52bc7401b0988be3ab670c8b0b1609e2c895f (diff) | |
download | buildroot-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.patch | 635 |
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) |