1b9ae52e3SPaul Richards /* 2b9ae52e3SPaul Richards * Copyright (c) 1993 Paul Kranenburg 3b9ae52e3SPaul Richards * All rights reserved. 4b9ae52e3SPaul Richards * 5b9ae52e3SPaul Richards * Redistribution and use in source and binary forms, with or without 6b9ae52e3SPaul Richards * modification, are permitted provided that the following conditions 7b9ae52e3SPaul Richards * are met: 8b9ae52e3SPaul Richards * 1. Redistributions of source code must retain the above copyright 9b9ae52e3SPaul Richards * notice, this list of conditions and the following disclaimer. 10b9ae52e3SPaul Richards * 2. Redistributions in binary form must reproduce the above copyright 11b9ae52e3SPaul Richards * notice, this list of conditions and the following disclaimer in the 12b9ae52e3SPaul Richards * documentation and/or other materials provided with the distribution. 13b9ae52e3SPaul Richards * 3. All advertising materials mentioning features or use of this software 14b9ae52e3SPaul Richards * must display the following acknowledgement: 15b9ae52e3SPaul Richards * This product includes software developed by Paul Kranenburg. 16b9ae52e3SPaul Richards * 4. The name of the author may not be used to endorse or promote products 1709e3d49dSJordan K. Hubbard * derived from this software without specific prior written permission 18b9ae52e3SPaul Richards * 19b9ae52e3SPaul Richards * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20b9ae52e3SPaul Richards * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21b9ae52e3SPaul Richards * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22b9ae52e3SPaul Richards * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23b9ae52e3SPaul Richards * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24b9ae52e3SPaul Richards * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25b9ae52e3SPaul Richards * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26b9ae52e3SPaul Richards * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27b9ae52e3SPaul Richards * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28b9ae52e3SPaul Richards * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29b9ae52e3SPaul Richards * 30d138df61SPeter Wemm * $Id: ldd.c,v 1.5 1994/12/23 22:31:31 nate Exp $ 31b9ae52e3SPaul Richards */ 32b9ae52e3SPaul Richards 33b9ae52e3SPaul Richards #include <sys/types.h> 34b9ae52e3SPaul Richards #include <sys/stat.h> 35b9ae52e3SPaul Richards #include <sys/file.h> 36b9ae52e3SPaul Richards #include <sys/time.h> 37b9ae52e3SPaul Richards #include <sys/resource.h> 38b9ae52e3SPaul Richards #include <sys/wait.h> 39b9ae52e3SPaul Richards #include <a.out.h> 40699e1b82SRich Murphey #include <err.h> 41699e1b82SRich Murphey #include <fcntl.h> 42699e1b82SRich Murphey #include <stdio.h> 43699e1b82SRich Murphey #include <stdlib.h> 44699e1b82SRich Murphey #include <string.h> 45699e1b82SRich Murphey #include <unistd.h> 46b9ae52e3SPaul Richards 47b9ae52e3SPaul Richards void 48b9ae52e3SPaul Richards usage() 49b9ae52e3SPaul Richards { 50699e1b82SRich Murphey extern char *__progname; 51699e1b82SRich Murphey 52699e1b82SRich Murphey fprintf(stderr, "Usage: %s <filename> ...\n", __progname); 53699e1b82SRich Murphey exit(1); 54b9ae52e3SPaul Richards } 55b9ae52e3SPaul Richards 56b9ae52e3SPaul Richards int 57b9ae52e3SPaul Richards main(argc, argv) 58b9ae52e3SPaul Richards int argc; 59b9ae52e3SPaul Richards char *argv[]; 60b9ae52e3SPaul Richards { 61d138df61SPeter Wemm char *fmt1 = NULL, *fmt2 = NULL; 62699e1b82SRich Murphey int rval; 63b9ae52e3SPaul Richards int c; 64b9ae52e3SPaul Richards 65d138df61SPeter Wemm while ((c = getopt(argc, argv, "f:")) != EOF) { 66b9ae52e3SPaul Richards switch (c) { 67d138df61SPeter Wemm case 'f': 68d138df61SPeter Wemm if (fmt1) { 69d138df61SPeter Wemm if (fmt2) 70d138df61SPeter Wemm errx(1, "Too many formats"); 71d138df61SPeter Wemm fmt2 = optarg; 72d138df61SPeter Wemm } else 73d138df61SPeter Wemm fmt1 = optarg; 74d138df61SPeter Wemm break; 75b9ae52e3SPaul Richards default: 76b9ae52e3SPaul Richards usage(); 77699e1b82SRich Murphey /*NOTREACHED*/ 78b9ae52e3SPaul Richards } 79b9ae52e3SPaul Richards } 80b9ae52e3SPaul Richards argc -= optind; 81b9ae52e3SPaul Richards argv += optind; 82b9ae52e3SPaul Richards 83b9ae52e3SPaul Richards if (argc <= 0) { 84b9ae52e3SPaul Richards usage(); 85699e1b82SRich Murphey /*NOTREACHED*/ 86b9ae52e3SPaul Richards } 87b9ae52e3SPaul Richards 88b9ae52e3SPaul Richards /* ld.so magic */ 89b9ae52e3SPaul Richards setenv("LD_TRACE_LOADED_OBJECTS", "", 1); 90d138df61SPeter Wemm if (fmt1) 91d138df61SPeter Wemm setenv("LD_TRACE_LOADED_OBJECTS_FMT1", fmt1, 1); 92d138df61SPeter Wemm if (fmt2) 93d138df61SPeter Wemm setenv("LD_TRACE_LOADED_OBJECTS_FMT2", fmt2, 1); 94b9ae52e3SPaul Richards 95699e1b82SRich Murphey rval = 0; 96b9ae52e3SPaul Richards while (argc--) { 97b9ae52e3SPaul Richards int fd; 98b9ae52e3SPaul Richards struct exec hdr; 99b9ae52e3SPaul Richards int status; 100b9ae52e3SPaul Richards 101b9ae52e3SPaul Richards if ((fd = open(*argv, O_RDONLY, 0)) < 0) { 102699e1b82SRich Murphey warn("%s", *argv); 103b9ae52e3SPaul Richards rval |= 1; 104b9ae52e3SPaul Richards argv++; 105b9ae52e3SPaul Richards continue; 106b9ae52e3SPaul Richards } 10761f9ce8dSNate Williams if (read(fd, &hdr, sizeof hdr) != sizeof hdr 10861f9ce8dSNate Williams || (N_GETFLAG(hdr) & EX_DPMASK) != EX_DYNAMIC 10961f9ce8dSNate Williams #if 1 /* Compatibility */ 11061f9ce8dSNate Williams || hdr.a_entry < __LDPGSZ 11161f9ce8dSNate Williams #endif 11261f9ce8dSNate Williams ) { 113699e1b82SRich Murphey 114699e1b82SRich Murphey warnx("%s: not a dynamic executable", *argv); 115b9ae52e3SPaul Richards (void)close(fd); 116b9ae52e3SPaul Richards rval |= 1; 117b9ae52e3SPaul Richards argv++; 118b9ae52e3SPaul Richards continue; 119b9ae52e3SPaul Richards } 120b9ae52e3SPaul Richards (void)close(fd); 121b9ae52e3SPaul Richards 122d138df61SPeter Wemm setenv("LD_TRACE_LOADED_OBJECTS_PROGNAME", *argv, 1); 123d138df61SPeter Wemm if (fmt1 == NULL && fmt2 == NULL) 124d138df61SPeter Wemm /* Default formats */ 125b9ae52e3SPaul Richards printf("%s:\n", *argv); 126d138df61SPeter Wemm 12709e3d49dSJordan K. Hubbard fflush(stdout); 128b9ae52e3SPaul Richards 129b9ae52e3SPaul Richards switch (fork()) { 130b9ae52e3SPaul Richards case -1: 131699e1b82SRich Murphey err(1, "fork"); 132b9ae52e3SPaul Richards break; 133b9ae52e3SPaul Richards default: 134699e1b82SRich Murphey if (wait(&status) <= 0) { 135699e1b82SRich Murphey warn("wait"); 136699e1b82SRich Murphey rval |= 1; 137699e1b82SRich Murphey } else if (WIFSIGNALED(status)) { 138b9ae52e3SPaul Richards fprintf(stderr, "%s: signal %d\n", 139b9ae52e3SPaul Richards *argv, WTERMSIG(status)); 140b9ae52e3SPaul Richards rval |= 1; 141b9ae52e3SPaul Richards } else if (WIFEXITED(status) && WEXITSTATUS(status)) { 142b9ae52e3SPaul Richards fprintf(stderr, "%s: exit status %d\n", 143b9ae52e3SPaul Richards *argv, WEXITSTATUS(status)); 144b9ae52e3SPaul Richards rval |= 1; 145b9ae52e3SPaul Richards } 146b9ae52e3SPaul Richards break; 147b9ae52e3SPaul Richards case 0: 148699e1b82SRich Murphey rval |= execl(*argv, *argv, NULL) != 0; 149b9ae52e3SPaul Richards perror(*argv); 150b9ae52e3SPaul Richards _exit(1); 151b9ae52e3SPaul Richards } 152b9ae52e3SPaul Richards argv++; 153b9ae52e3SPaul Richards } 154b9ae52e3SPaul Richards 155b9ae52e3SPaul Richards return rval; 156b9ae52e3SPaul Richards } 157