diff options
| author | John Baldwin <jhb@FreeBSD.org> | 2008-08-26 17:36:38 +0000 |
|---|---|---|
| committer | John Baldwin <jhb@FreeBSD.org> | 2008-08-26 17:36:38 +0000 |
| commit | a78d8a9fe1037c50d57c2676ed3759079364b447 (patch) | |
| tree | e4949ac1136e02e665ec03fe46c8bb00a3a16616 /usr.bin | |
| parent | 20cf32bae618c8f7982d5c1a8c5becfe14866497 (diff) | |
Notes
Diffstat (limited to 'usr.bin')
| -rw-r--r-- | usr.bin/ldd/Makefile | 2 | ||||
| -rw-r--r-- | usr.bin/ldd/ldd.1 | 6 | ||||
| -rw-r--r-- | usr.bin/ldd/ldd.c | 99 |
3 files changed, 67 insertions, 40 deletions
diff --git a/usr.bin/ldd/Makefile b/usr.bin/ldd/Makefile index bb04f4550e32..357f9f37c770 100644 --- a/usr.bin/ldd/Makefile +++ b/usr.bin/ldd/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -PROG= ldd +PROG?= ldd SRCS= ldd.c .if ${MACHINE_ARCH} == "i386" SRCS+= sods.c diff --git a/usr.bin/ldd/ldd.1 b/usr.bin/ldd/ldd.1 index 357bffec3f5b..9dd7902fae03 100644 --- a/usr.bin/ldd/ldd.1 +++ b/usr.bin/ldd/ldd.1 @@ -57,12 +57,6 @@ option displays a verbose listing of the dynamic linking headers encoded in the executable. See the source code and include files for the definitive meaning of all the fields. -.Sh BUGS -On 64 bit architectures, dlopen() cannot open 32 bit dynamic libraries, -so -.Nm -will show the error -.Qq "unsupported file layout" . .Sh SEE ALSO .Xr ld 1 , .Xr nm 1 , diff --git a/usr.bin/ldd/ldd.c b/usr.bin/ldd/ldd.c index a130521dc216..f83632ab08e6 100644 --- a/usr.bin/ldd/ldd.c +++ b/usr.bin/ldd/ldd.c @@ -44,10 +44,17 @@ __FBSDID("$FreeBSD$"); #include <fcntl.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #include "extern.h" +#ifdef COMPAT_32BIT +#define LD_ "LD_32_" +#else +#define LD_ "LD_" +#endif + /* * 32-bit ELF data structures can only be used if the system header[s] declare * them. There is no official macro for determining whether they are declared, @@ -66,30 +73,57 @@ static void usage(void); #define TYPE_ELF 2 /* Architecture default */ #if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED) #define TYPE_ELF32 3 /* Explicit 32 bits on architectures >32 bits */ -#endif -#define ENV_OBJECTS 0 -#define ENV_OBJECTS_FMT1 1 -#define ENV_OBJECTS_FMT2 2 -#define ENV_OBJECTS_PROGNAME 3 -#define ENV_OBJECTS_ALL 4 -#define ENV_LAST 5 +#define _PATH_LDD32 "/usr/bin/ldd32" -const char *envdef[ENV_LAST] = { - "LD_TRACE_LOADED_OBJECTS", - "LD_TRACE_LOADED_OBJECTS_FMT1", - "LD_TRACE_LOADED_OBJECTS_FMT2", - "LD_TRACE_LOADED_OBJECTS_PROGNAME", - "LD_TRACE_LOADED_OBJECTS_ALL", -}; -#if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED) -const char *env32[ENV_LAST] = { - "LD_32_TRACE_LOADED_OBJECTS", - "LD_32_TRACE_LOADED_OBJECTS_FMT1", - "LD_32_TRACE_LOADED_OBJECTS_FMT2", - "LD_32_TRACE_LOADED_OBJECTS_PROGNAME", - "LD_32_TRACE_LOADED_OBJECTS_ALL", -}; +static int +execldd32(char *file, char *fmt1, char *fmt2, int aflag, int vflag) +{ + char *argv[8]; + int i, rval, status; + + unsetenv(LD_ "TRACE_LOADED_OBJECTS"); + rval = 0; + i = 0; + argv[i++] = strdup(_PATH_LDD32); + if (aflag) + argv[i++] = strdup("-a"); + if (vflag) + argv[i++] = strdup("-v"); + if (fmt1 != NULL) { + argv[i++] = strdup("-f"); + argv[i++] = strdup(fmt1); + } + if (fmt2 != NULL) { + argv[i++] = strdup("-f"); + argv[i++] = strdup(fmt2); + } + argv[i++] = strdup(file); + argv[i++] = NULL; + + switch (fork()) { + case -1: + err(1, "fork"); + break; + case 0: + execv(_PATH_LDD32, argv); + warn("%s", _PATH_LDD32); + _exit(127); + break; + default: + if (wait(&status) < 0) + rval = 1; + else if (WIFSIGNALED(status)) + rval = 1; + else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) + rval = 1; + break; + } + while (i--) + free(argv[i]); + setenv(LD_ "TRACE_LOADED_OBJECTS", "yes", 1); + return (rval); +} #endif int @@ -144,7 +178,6 @@ main(int argc, char *argv[]) rval = 0; for (; argc > 0; argc--, argv++) { int fd, status, is_shlib, rv, type; - const char **env; if ((fd = open(*argv, O_RDONLY, 0)) < 0) { warn("%s", *argv); @@ -161,12 +194,11 @@ main(int argc, char *argv[]) switch (type) { case TYPE_ELF: case TYPE_AOUT: - env = envdef; break; #if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED) case TYPE_ELF32: - env = env32; - break; + rval |= execldd32(*argv, fmt1, fmt2, aflag, vflag); + continue; #endif case TYPE_UNKNOWN: default: @@ -178,15 +210,15 @@ main(int argc, char *argv[]) } /* ld.so magic */ - setenv(env[ENV_OBJECTS], "yes", 1); + setenv(LD_ "TRACE_LOADED_OBJECTS", "yes", 1); if (fmt1 != NULL) - setenv(env[ENV_OBJECTS_FMT1], fmt1, 1); + setenv(LD_ "TRACE_LOADED_OBJECTS_FMT1", fmt1, 1); if (fmt2 != NULL) - setenv(env[ENV_OBJECTS_FMT2], fmt2, 1); + setenv(LD_ "TRACE_LOADED_OBJECTS_FMT2", fmt2, 1); - setenv(env[ENV_OBJECTS_PROGNAME], *argv, 1); + setenv(LD_ "TRACE_LOADED_OBJECTS_PROGNAME", *argv, 1); if (aflag) - setenv(env[ENV_OBJECTS_ALL], "1", 1); + setenv(LD_ "TRACE_LOADED_OBJECTS_ALL", "1", 1); else if (fmt1 == NULL && fmt2 == NULL) /* Default formats */ printf("%s:\n", *argv); @@ -197,14 +229,15 @@ main(int argc, char *argv[]) err(1, "fork"); break; default: - if (wait(&status) <= 0) { + if (wait(&status) < 0) { warn("wait"); rval |= 1; } else if (WIFSIGNALED(status)) { fprintf(stderr, "%s: signal %d\n", *argv, WTERMSIG(status)); rval |= 1; - } else if (WIFEXITED(status) && WEXITSTATUS(status)) { + } else if (WIFEXITED(status) && + WEXITSTATUS(status) != 0) { fprintf(stderr, "%s: exit status %d\n", *argv, WEXITSTATUS(status)); rval |= 1; |
