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 */ 30b9ae52e3SPaul Richards 31a53809fdSMark Murray #include <sys/cdefs.h> 32a53809fdSMark Murray __FBSDID("$FreeBSD$"); 333e762626SPhilippe Charnier 34b9ae52e3SPaul Richards #include <sys/wait.h> 35a53809fdSMark Murray 365e6220d9SDavid E. O'Brien #include <machine/elf.h> 37a53809fdSMark Murray 38a2cfdda8SMike Barcroft #include <arpa/inet.h> 39a53809fdSMark Murray 40b9ae52e3SPaul Richards #include <a.out.h> 41c6de4ce7SMaxim Sobolev #include <dlfcn.h> 42699e1b82SRich Murphey #include <err.h> 43fffd993dSEdwin Groothuis #include <errno.h> 44699e1b82SRich Murphey #include <fcntl.h> 45699e1b82SRich Murphey #include <stdio.h> 46699e1b82SRich Murphey #include <stdlib.h> 47699e1b82SRich Murphey #include <unistd.h> 48b9ae52e3SPaul Richards 49a53809fdSMark Murray #include "extern.h" 509731d137SPeter Wemm 518bd833ffSEdwin Groothuis /* 528bd833ffSEdwin Groothuis * Elf32_xhdr structures can only be used if sys/elf32.h is included, so 538bd833ffSEdwin Groothuis * check for the existence of one of the macros defined in sys/elf32.h. 548bd833ffSEdwin Groothuis * 558bd833ffSEdwin Groothuis * The presense of the ELF32_R_TYPE macro via machine/elf.h has been verified 568bd833ffSEdwin Groothuis * on amd64 6.3, ia64 7.0 and sparc64 7.0. The absence of the macro has been 578bd833ffSEdwin Groothuis * verified on alpha 6.2. 588bd833ffSEdwin Groothuis */ 598bd833ffSEdwin Groothuis #if defined(ELF32_R_TYPE) 608bd833ffSEdwin Groothuis #define ELF32_SUPPORTED 618bd833ffSEdwin Groothuis #endif 628bd833ffSEdwin Groothuis 63d3c1e14bSEdwin Groothuis static int is_executable(const char *fname, int fd, int *is_shlib, 64d3c1e14bSEdwin Groothuis int *type); 65d3c1e14bSEdwin Groothuis static void usage(void); 66a0d476a9SEdwin Groothuis 67d3c1e14bSEdwin Groothuis #define TYPE_UNKNOWN 0 68d3c1e14bSEdwin Groothuis #define TYPE_AOUT 1 69d3c1e14bSEdwin Groothuis #define TYPE_ELF 2 /* Architecture default */ 708bd833ffSEdwin Groothuis #if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED) 71fffd993dSEdwin Groothuis #define TYPE_ELF32 3 /* Explicit 32 bits on architectures >32 bits */ 72fffd993dSEdwin Groothuis #endif 73d3c1e14bSEdwin Groothuis 74d3c1e14bSEdwin Groothuis #define ENV_OBJECTS 0 75d3c1e14bSEdwin Groothuis #define ENV_OBJECTS_FMT1 1 76d3c1e14bSEdwin Groothuis #define ENV_OBJECTS_FMT2 2 77d3c1e14bSEdwin Groothuis #define ENV_OBJECTS_PROGNAME 3 78d3c1e14bSEdwin Groothuis #define ENV_OBJECTS_ALL 4 79d3c1e14bSEdwin Groothuis #define ENV_LAST 5 80d3c1e14bSEdwin Groothuis 81d3c1e14bSEdwin Groothuis const char *envdef[ENV_LAST] = { 82d3c1e14bSEdwin Groothuis "LD_TRACE_LOADED_OBJECTS", 83d3c1e14bSEdwin Groothuis "LD_TRACE_LOADED_OBJECTS_FMT1", 84d3c1e14bSEdwin Groothuis "LD_TRACE_LOADED_OBJECTS_FMT2", 85d3c1e14bSEdwin Groothuis "LD_TRACE_LOADED_OBJECTS_PROGNAME", 86d3c1e14bSEdwin Groothuis "LD_TRACE_LOADED_OBJECTS_ALL", 87d3c1e14bSEdwin Groothuis }; 888bd833ffSEdwin Groothuis #if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED) 89fffd993dSEdwin Groothuis const char *env32[ENV_LAST] = { 90fffd993dSEdwin Groothuis "LD_32_TRACE_LOADED_OBJECTS", 91fffd993dSEdwin Groothuis "LD_32_TRACE_LOADED_OBJECTS_FMT1", 92fffd993dSEdwin Groothuis "LD_32_TRACE_LOADED_OBJECTS_FMT2", 93fffd993dSEdwin Groothuis "LD_32_TRACE_LOADED_OBJECTS_PROGNAME", 94fffd993dSEdwin Groothuis "LD_32_TRACE_LOADED_OBJECTS_ALL", 95fffd993dSEdwin Groothuis }; 96fffd993dSEdwin Groothuis #endif 97b9ae52e3SPaul Richards 98b9ae52e3SPaul Richards int 99a53809fdSMark Murray main(int argc, char *argv[]) 100b9ae52e3SPaul Richards { 101a0d476a9SEdwin Groothuis char *fmt1, *fmt2; 102a0d476a9SEdwin Groothuis int rval, c, aflag, vflag; 103b9ae52e3SPaul Richards 10420249943SDavid E. O'Brien aflag = vflag = 0; 105a0d476a9SEdwin Groothuis fmt1 = fmt2 = NULL; 10620249943SDavid E. O'Brien 107a0d476a9SEdwin Groothuis while ((c = getopt(argc, argv, "af:v")) != -1) { 108b9ae52e3SPaul Richards switch (c) { 10920249943SDavid E. O'Brien case 'a': 11020249943SDavid E. O'Brien aflag++; 11120249943SDavid E. O'Brien break; 112d138df61SPeter Wemm case 'f': 113a0d476a9SEdwin Groothuis if (fmt1 != NULL) { 114a0d476a9SEdwin Groothuis if (fmt2 != NULL) 1153e762626SPhilippe Charnier errx(1, "too many formats"); 116d138df61SPeter Wemm fmt2 = optarg; 117d138df61SPeter Wemm } else 118d138df61SPeter Wemm fmt1 = optarg; 119d138df61SPeter Wemm break; 120a0d476a9SEdwin Groothuis case 'v': 121a0d476a9SEdwin Groothuis vflag++; 122a0d476a9SEdwin Groothuis break; 123b9ae52e3SPaul Richards default: 124b9ae52e3SPaul Richards usage(); 125699e1b82SRich Murphey /* NOTREACHED */ 126b9ae52e3SPaul Richards } 127b9ae52e3SPaul Richards } 128b9ae52e3SPaul Richards argc -= optind; 129b9ae52e3SPaul Richards argv += optind; 130b9ae52e3SPaul Richards 131a0d476a9SEdwin Groothuis if (vflag && fmt1 != NULL) 1329731d137SPeter Wemm errx(1, "-v may not be used with -f"); 1339731d137SPeter Wemm 134b9ae52e3SPaul Richards if (argc <= 0) { 135b9ae52e3SPaul Richards usage(); 136699e1b82SRich Murphey /* NOTREACHED */ 137b9ae52e3SPaul Richards } 138b9ae52e3SPaul Richards 13997db68b6SDoug Rabson #ifdef __i386__ 1409731d137SPeter Wemm if (vflag) { 1419731d137SPeter Wemm for (c = 0; c < argc; c++) 1429731d137SPeter Wemm dump_file(argv[c]); 1439731d137SPeter Wemm exit(error_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE); 1449731d137SPeter Wemm } 14597db68b6SDoug Rabson #endif 1469731d137SPeter Wemm 147699e1b82SRich Murphey rval = 0; 148e2daa140SJohn Polstra for (; argc > 0; argc--, argv++) { 149d3c1e14bSEdwin Groothuis int fd, status, is_shlib, rv, type; 150d3c1e14bSEdwin Groothuis const char **env; 151d3c1e14bSEdwin Groothuis 152b9ae52e3SPaul Richards if ((fd = open(*argv, O_RDONLY, 0)) < 0) { 153699e1b82SRich Murphey warn("%s", *argv); 154b9ae52e3SPaul Richards rval |= 1; 155b9ae52e3SPaul Richards continue; 156b9ae52e3SPaul Richards } 157d3c1e14bSEdwin Groothuis rv = is_executable(*argv, fd, &is_shlib, &type); 158a0d476a9SEdwin Groothuis close(fd); 159d3c1e14bSEdwin Groothuis if (rv == 0) { 160c474c6d3SDoug Rabson rval |= 1; 161c474c6d3SDoug Rabson continue; 162c474c6d3SDoug Rabson } 163c474c6d3SDoug Rabson 164fffd993dSEdwin Groothuis switch (type) { 165fffd993dSEdwin Groothuis case TYPE_ELF: 166fffd993dSEdwin Groothuis case TYPE_AOUT: 167fffd993dSEdwin Groothuis env = envdef; 168fffd993dSEdwin Groothuis break; 1698bd833ffSEdwin Groothuis #if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED) 170fffd993dSEdwin Groothuis case TYPE_ELF32: 171fffd993dSEdwin Groothuis env = env32; 172fffd993dSEdwin Groothuis break; 173fffd993dSEdwin Groothuis #endif 174fffd993dSEdwin Groothuis case TYPE_UNKNOWN: 175fffd993dSEdwin Groothuis default: 176fffd993dSEdwin Groothuis /* 177fffd993dSEdwin Groothuis * This shouldn't happen unless is_executable() 178fffd993dSEdwin Groothuis * is broken. 179fffd993dSEdwin Groothuis */ 180fffd993dSEdwin Groothuis errx(EDOOFUS, "unknown executable type"); 181fffd993dSEdwin Groothuis } 182fffd993dSEdwin Groothuis 183d3c1e14bSEdwin Groothuis /* ld.so magic */ 184d3c1e14bSEdwin Groothuis setenv(env[ENV_OBJECTS], "yes", 1); 185d3c1e14bSEdwin Groothuis if (fmt1 != NULL) 186d3c1e14bSEdwin Groothuis setenv(env[ENV_OBJECTS_FMT1], fmt1, 1); 187d3c1e14bSEdwin Groothuis if (fmt2 != NULL) 188d3c1e14bSEdwin Groothuis setenv(env[ENV_OBJECTS_FMT2], fmt2, 1); 189a0d476a9SEdwin Groothuis 190d3c1e14bSEdwin Groothuis setenv(env[ENV_OBJECTS_PROGNAME], *argv, 1); 191a0d476a9SEdwin Groothuis if (aflag) 192d3c1e14bSEdwin Groothuis setenv(env[ENV_OBJECTS_ALL], "1", 1); 19320249943SDavid E. O'Brien else if (fmt1 == NULL && fmt2 == NULL) 194d138df61SPeter Wemm /* Default formats */ 195b9ae52e3SPaul Richards printf("%s:\n", *argv); 19609e3d49dSJordan K. Hubbard fflush(stdout); 197b9ae52e3SPaul Richards 198b9ae52e3SPaul Richards switch (fork()) { 199b9ae52e3SPaul Richards case -1: 200699e1b82SRich Murphey err(1, "fork"); 201b9ae52e3SPaul Richards break; 202b9ae52e3SPaul Richards default: 203699e1b82SRich Murphey if (wait(&status) <= 0) { 204699e1b82SRich Murphey warn("wait"); 205699e1b82SRich Murphey rval |= 1; 206699e1b82SRich Murphey } else if (WIFSIGNALED(status)) { 207a0d476a9SEdwin Groothuis fprintf(stderr, "%s: signal %d\n", *argv, 208a0d476a9SEdwin Groothuis WTERMSIG(status)); 209b9ae52e3SPaul Richards rval |= 1; 210b9ae52e3SPaul Richards } else if (WIFEXITED(status) && WEXITSTATUS(status)) { 211a0d476a9SEdwin Groothuis fprintf(stderr, "%s: exit status %d\n", *argv, 212a0d476a9SEdwin Groothuis WEXITSTATUS(status)); 213b9ae52e3SPaul Richards rval |= 1; 214b9ae52e3SPaul Richards } 215b9ae52e3SPaul Richards break; 216b9ae52e3SPaul Richards case 0: 217d1cf9ea2SMaxim Sobolev if (is_shlib == 0) { 218fc41545eSMaxim Sobolev execl(*argv, *argv, (char *)NULL); 2193e762626SPhilippe Charnier warn("%s", *argv); 220d1cf9ea2SMaxim Sobolev } else { 221d1cf9ea2SMaxim Sobolev dlopen(*argv, RTLD_TRACE); 222d1cf9ea2SMaxim Sobolev warnx("%s: %s", *argv, dlerror()); 223c6de4ce7SMaxim Sobolev } 224b9ae52e3SPaul Richards _exit(1); 225b9ae52e3SPaul Richards } 226b9ae52e3SPaul Richards } 227b9ae52e3SPaul Richards 228b9ae52e3SPaul Richards return rval; 229b9ae52e3SPaul Richards } 230d3c1e14bSEdwin Groothuis 231d3c1e14bSEdwin Groothuis static void 232d3c1e14bSEdwin Groothuis usage(void) 233d3c1e14bSEdwin Groothuis { 234d3c1e14bSEdwin Groothuis 235d3c1e14bSEdwin Groothuis fprintf(stderr, "usage: ldd [-a] [-v] [-f format] program ...\n"); 236d3c1e14bSEdwin Groothuis exit(1); 237d3c1e14bSEdwin Groothuis } 238d3c1e14bSEdwin Groothuis 239d3c1e14bSEdwin Groothuis static int 240d3c1e14bSEdwin Groothuis is_executable(const char *fname, int fd, int *is_shlib, int *type) 241d3c1e14bSEdwin Groothuis { 242d3c1e14bSEdwin Groothuis union { 243d3c1e14bSEdwin Groothuis struct exec aout; 2448bd833ffSEdwin Groothuis #if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED) 245fffd993dSEdwin Groothuis Elf32_Ehdr elf32; 2468bd833ffSEdwin Groothuis #endif 247d3c1e14bSEdwin Groothuis Elf_Ehdr elf; 248d3c1e14bSEdwin Groothuis } hdr; 249d3c1e14bSEdwin Groothuis int n; 250d3c1e14bSEdwin Groothuis 251d3c1e14bSEdwin Groothuis *is_shlib = 0; 252d3c1e14bSEdwin Groothuis *type = TYPE_UNKNOWN; 253d3c1e14bSEdwin Groothuis 254d3c1e14bSEdwin Groothuis if ((n = read(fd, &hdr, sizeof(hdr))) == -1) { 255d3c1e14bSEdwin Groothuis warn("%s: can't read program header", fname); 256d3c1e14bSEdwin Groothuis return (0); 257d3c1e14bSEdwin Groothuis } 258d3c1e14bSEdwin Groothuis 259d3c1e14bSEdwin Groothuis if ((size_t)n >= sizeof(hdr.aout) && !N_BADMAG(hdr.aout)) { 260d3c1e14bSEdwin Groothuis /* a.out file */ 261d3c1e14bSEdwin Groothuis if ((N_GETFLAG(hdr.aout) & EX_DPMASK) != EX_DYNAMIC 262d3c1e14bSEdwin Groothuis #if 1 /* Compatibility */ 263d3c1e14bSEdwin Groothuis || hdr.aout.a_entry < __LDPGSZ 264d3c1e14bSEdwin Groothuis #endif 265d3c1e14bSEdwin Groothuis ) { 266d3c1e14bSEdwin Groothuis warnx("%s: not a dynamic executable", fname); 267d3c1e14bSEdwin Groothuis return (0); 268d3c1e14bSEdwin Groothuis } 269d3c1e14bSEdwin Groothuis *type = TYPE_AOUT; 270d3c1e14bSEdwin Groothuis return (1); 271d3c1e14bSEdwin Groothuis } 272d3c1e14bSEdwin Groothuis 2738bd833ffSEdwin Groothuis #if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED) 274fffd993dSEdwin Groothuis if ((size_t)n >= sizeof(hdr.elf32) && IS_ELF(hdr.elf32) && 275fffd993dSEdwin Groothuis hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) { 276fffd993dSEdwin Groothuis /* Handle 32 bit ELF objects */ 277fffd993dSEdwin Groothuis Elf32_Phdr phdr; 278fffd993dSEdwin Groothuis int dynamic, i; 279fffd993dSEdwin Groothuis 280fffd993dSEdwin Groothuis dynamic = 0; 281fffd993dSEdwin Groothuis *type = TYPE_ELF32; 282fffd993dSEdwin Groothuis 283fffd993dSEdwin Groothuis if (lseek(fd, hdr.elf32.e_phoff, SEEK_SET) == -1) { 284fffd993dSEdwin Groothuis warnx("%s: header too short", fname); 285fffd993dSEdwin Groothuis return (0); 286fffd993dSEdwin Groothuis } 287fffd993dSEdwin Groothuis for (i = 0; i < hdr.elf32.e_phnum; i++) { 288fffd993dSEdwin Groothuis if (read(fd, &phdr, hdr.elf32.e_phentsize) != 289fffd993dSEdwin Groothuis sizeof(phdr)) { 290fffd993dSEdwin Groothuis warnx("%s: can't read program header", fname); 291fffd993dSEdwin Groothuis return (0); 292fffd993dSEdwin Groothuis } 293fffd993dSEdwin Groothuis if (phdr.p_type == PT_DYNAMIC) { 294fffd993dSEdwin Groothuis dynamic = 1; 295fffd993dSEdwin Groothuis break; 296fffd993dSEdwin Groothuis } 297fffd993dSEdwin Groothuis } 298fffd993dSEdwin Groothuis 299fffd993dSEdwin Groothuis if (!dynamic) { 300fffd993dSEdwin Groothuis warnx("%s: not a dynamic ELF executable", fname); 301fffd993dSEdwin Groothuis return (0); 302fffd993dSEdwin Groothuis } 303fffd993dSEdwin Groothuis if (hdr.elf32.e_type == ET_DYN) { 304fffd993dSEdwin Groothuis if (hdr.elf32.e_ident[EI_OSABI] & ELFOSABI_FREEBSD) { 305fffd993dSEdwin Groothuis *is_shlib = 1; 306fffd993dSEdwin Groothuis return (1); 307fffd993dSEdwin Groothuis } 308fffd993dSEdwin Groothuis warnx("%s: not a FreeBSD ELF shared object", fname); 309fffd993dSEdwin Groothuis return (0); 310fffd993dSEdwin Groothuis } 311fffd993dSEdwin Groothuis 312fffd993dSEdwin Groothuis return (1); 313fffd993dSEdwin Groothuis } 314fffd993dSEdwin Groothuis #endif 315fffd993dSEdwin Groothuis 316d3c1e14bSEdwin Groothuis if ((size_t)n >= sizeof(hdr.elf) && IS_ELF(hdr.elf) && 317d3c1e14bSEdwin Groothuis hdr.elf.e_ident[EI_CLASS] == ELF_TARG_CLASS) { 318d3c1e14bSEdwin Groothuis /* Handle default ELF objects on this architecture */ 319d3c1e14bSEdwin Groothuis Elf_Phdr phdr; 320d3c1e14bSEdwin Groothuis int dynamic, i; 321d3c1e14bSEdwin Groothuis 322d3c1e14bSEdwin Groothuis dynamic = 0; 323d3c1e14bSEdwin Groothuis *type = TYPE_ELF; 324d3c1e14bSEdwin Groothuis 325d3c1e14bSEdwin Groothuis if (lseek(fd, hdr.elf.e_phoff, SEEK_SET) == -1) { 326d3c1e14bSEdwin Groothuis warnx("%s: header too short", fname); 327d3c1e14bSEdwin Groothuis return (0); 328d3c1e14bSEdwin Groothuis } 329d3c1e14bSEdwin Groothuis for (i = 0; i < hdr.elf.e_phnum; i++) { 330d3c1e14bSEdwin Groothuis if (read(fd, &phdr, hdr.elf.e_phentsize) 331d3c1e14bSEdwin Groothuis != sizeof(phdr)) { 332d3c1e14bSEdwin Groothuis warnx("%s: can't read program header", fname); 333d3c1e14bSEdwin Groothuis return (0); 334d3c1e14bSEdwin Groothuis } 335d3c1e14bSEdwin Groothuis if (phdr.p_type == PT_DYNAMIC) { 336d3c1e14bSEdwin Groothuis dynamic = 1; 337d3c1e14bSEdwin Groothuis break; 338d3c1e14bSEdwin Groothuis } 339d3c1e14bSEdwin Groothuis } 340d3c1e14bSEdwin Groothuis 341d3c1e14bSEdwin Groothuis if (!dynamic) { 342d3c1e14bSEdwin Groothuis warnx("%s: not a dynamic ELF executable", fname); 343d3c1e14bSEdwin Groothuis return (0); 344d3c1e14bSEdwin Groothuis } 345d3c1e14bSEdwin Groothuis if (hdr.elf.e_type == ET_DYN) { 346d3c1e14bSEdwin Groothuis if (hdr.elf.e_ident[EI_OSABI] & ELFOSABI_FREEBSD) { 347d3c1e14bSEdwin Groothuis *is_shlib = 1; 348d3c1e14bSEdwin Groothuis return (1); 349d3c1e14bSEdwin Groothuis } 350d3c1e14bSEdwin Groothuis warnx("%s: not a FreeBSD ELF shared object", fname); 351d3c1e14bSEdwin Groothuis return (0); 352d3c1e14bSEdwin Groothuis } 353d3c1e14bSEdwin Groothuis 354d3c1e14bSEdwin Groothuis return (1); 355d3c1e14bSEdwin Groothuis } 356d3c1e14bSEdwin Groothuis 357d3c1e14bSEdwin Groothuis warnx("%s: not a dynamic executable", fname); 358d3c1e14bSEdwin Groothuis return (0); 359d3c1e14bSEdwin Groothuis } 360