diff options
| author | Eric Andersen <andersen@codepoet.org> | 2005-09-30 21:30:57 +0000 | 
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2005-09-30 21:30:57 +0000 | 
| commit | d5b26eae203eb12832b378149dd09c849c0be4bc (patch) | |
| tree | 5fdb4d6d11ec9b3e6d26cd900557d42fde44433a | |
| parent | 948d4fc01692997f98184b232e89fdcce1b1e24d (diff) | |
Allow ldconfig.host to build ld.so.cache for target, regardless of
the target system's byteorder
| -rw-r--r-- | utils/Makefile | 12 | ||||
| -rw-r--r-- | utils/chroot_realpath.c | 163 | ||||
| -rw-r--r-- | utils/ldconfig.c | 143 | ||||
| -rw-r--r-- | utils/readsoname2.c | 32 | 
4 files changed, 315 insertions, 35 deletions
| diff --git a/utils/Makefile b/utils/Makefile index 640bedfb7..f35b94eac 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -31,6 +31,12 @@ else  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) @@ -84,13 +90,13 @@ endif  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 --git a/utils/chroot_realpath.c b/utils/chroot_realpath.c new file mode 100644 index 000000000..43ce9a528 --- /dev/null +++ b/utils/chroot_realpath.c @@ -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 --git a/utils/ldconfig.c b/utils/ldconfig.c index 202a58dd6..85ce015d5 100644 --- a/utils/ldconfig.c +++ b/utils/ldconfig.c @@ -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 @@ struct exec  #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 @@ void cache_dolib(const char *dir, const char *so, int libtype);  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 @@ struct needed_tab needed_tab[] = {    { 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 @@ char *is_shlib(const char *dir, const char *name, int *type,      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 @@ char *is_shlib(const char *dir, const char *name, int *type,  	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 @@ char *is_shlib(const char *dir, const char *name, int *type,  	    *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 @@ char *is_shlib(const char *dir, const char *name, int *type,  			*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 @@ char *is_shlib(const char *dir, const char *name, int *type,  		}  		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 @@ char *is_shlib(const char *dir, const char *name, int *type,  		    *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 @@ void link_shlib(const char *dir, const char *file, const char *so)      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 @@ void link_shlib(const char *dir, const char *file, const char *so)      /* 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 @@ void link_shlib(const char *dir, const char *file, const char *so)  	}  	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 @@ void scan_dir(const char *rawname)      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 @@ void scan_dir(const char *rawname)      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 *get_extpath(void)      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 @@ void cache_write(void)  {      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)); - -    if (write(cachefd, &magic, sizeof (header_t)) != sizeof (header_t)) -	err(EXIT_FATAL,"can't write %s (%s)", tempfile, strerror(errno)); +	err(EXIT_FATAL,"can't create %s~ (%s)", cachefile, 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 @@ void cache_write(void)  	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 @@ void cache_print(void)      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 main(int argc, char **argv)      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 @@ int main(int argc, char **argv)  	}      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 --git a/utils/readsoname2.c b/utils/readsoname2.c index 1bf47b7c6..9452c0c4d 100644 --- a/utils/readsoname2.c +++ b/utils/readsoname2.c @@ -26,7 +26,7 @@ char *readsonameXX(char *name, FILE *infile, int expected_type, int *type)    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 @@ char *readsonameXX(char *name, FILE *infile, int expected_type, int *type)    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 @@ char *readsonameXX(char *name, FILE *infile, int expected_type, int *type)    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 *readsonameXX(char *name, FILE *infile, int expected_type, int *type)        (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) | 
