4.4BSD/usr/src/contrib/sun.sharedlib/bin/ldd.c
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify this source code without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* THIS PROGRAM CONTAINS SOURCE CODE COPYRIGHTED BY SUN MICROSYSTEMS, INC.
* SUN MICROSYSTEMS, INC., MAKES NO REPRESENTATIONS ABOUT THE SUITABLITY
* OF SUCH SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT
* EXPRESS OR IMPLIED WARRANTY OF ANY KIND. SUN MICROSYSTEMS, INC. DISCLAIMS
* ALL WARRANTIES WITH REGARD TO SUCH SOURCE CODE, INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN
* NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT,
* INCIDENTAL, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM USE OF SUCH SOURCE CODE, REGARDLESS OF THE THEORY OF LIABILITY.
*
* This source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS
* SOURCE CODE OR ANY PART THEREOF.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/* @(#)ldd.c 1.6 91/04/07 SMI */
/* Copyright (c) 1991 by Sun Microsystems, Inc. */
/*
* List Dynamic Dependencies
*/
#include <sys/types.h>
#include <stdio.h>
#include <a.out.h>
#include <link.h>
#include <sys/wait.h>
#include <sys/file.h>
char *nargv[] = {0, 0}; /* dummy argument vector */
char *malloc(); /* malloc return value */
main(argc, argv, envp)
int argc; /* count of arguments */
char *argv[]; /* argument values */
char *envp[]; /* array of environment strings */
{
unsigned int i, j; /* general temporaries */
int fd; /* file descriptor on targets */
int pid; /* child process id */
char **nenvp; /* new environment */
struct exec exec; /* template for inspecting target */
union wait status; /* dummy for wait() */
struct exec a;
/*
* Initial sanity check.
*/
if (argc <= 1) {
(void) fprintf(stderr, "Usage: ldd file ... \n");
exit(1);
}
(void) setlinebuf(stdout);
(void) setlinebuf(stderr);
/*
* Add an environment variable. Count the number of existing
* ones, and then allocate up a new vector of environment strings
* and add ours to it.
*/
for (i = 0; envp[i]; i++)
;
if ((nenvp = (char **)malloc((i + 2) * sizeof (char *))) == NULL) {
perror("ldd: out of memory for environment");
exit(1);
}
nenvp[0] = "LD_TRACE_LOADED_OBJECTS=placeholder";
for (j = 0; j < (i + 1); j++)
nenvp[j + 1] = envp[j];
/*
* For each argument, examine it and determine if it is an
* executable with a __DYNAMIC structure and an entry point.
* If it is, simply execute it and let the dynamic linker
* report its status.
*/
for (i = 1; i < argc; i++) {
if ((fd = open(argv[i], O_RDONLY)) == -1) {
fprintf(stderr, "ldd: %s unreadable: ", argv[1]);
perror("");
continue;
}
j = read(fd, (char *)&exec, sizeof (struct exec));
(void) close(fd);
if (j != sizeof (struct exec)) {
(void) fprintf(stderr, "ldd: %s: not an executable\n",
argv[i]);
continue;
}
if (N_BADMAG(exec)) {
(void) fprintf(stderr, "ldd: %s: not an executable\n",
argv[i]);
continue;
}
if (!exec.a_dynamic) {
(void) printf("%s: statically linked\n", argv[i]);
continue;
}
if (exec.a_entry == 0) {
(void) fprintf("%s: not an executable\n", argv[i]);
continue;
}
if ((pid = fork()) == 0) {
if (argc > 2)
(void) printf("%s:\n", argv[i]);
execve(argv[i], nargv, nenvp);
(void) fprintf(stderr,
"ldd: %s execution failed: ", argv[i]);
perror("");
continue;
} else
if (pid != -1) {
while (wait(&status) != pid)
;
if (status.w_T.w_Termsig)
(void) fprintf(stderr,
"ldd: %s execution failed due to signal %d %s\n",
argv[i],
status.w_T.w_Termsig,
status.w_T.w_Coredump ?
"(core dumped)" : "");
else if (status.w_T.w_Retcode)
(void) printf(stderr,
"ldd: %s execution failed: exit status %d\n",
argv[i],
status.w_T.w_Retcode);
} else
perror("ldd: fork() failed");
}
exit(0);
/*NOTREACHED*/
}