summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2008-08-26 17:36:38 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2008-08-26 17:36:38 +0000
commita78d8a9fe1037c50d57c2676ed3759079364b447 (patch)
treee4949ac1136e02e665ec03fe46c8bb00a3a16616 /usr.bin
parent20cf32bae618c8f7982d5c1a8c5becfe14866497 (diff)
Notes
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ldd/Makefile2
-rw-r--r--usr.bin/ldd/ldd.16
-rw-r--r--usr.bin/ldd/ldd.c99
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;