Deleted Added
full compact
ldd.c (256281) ldd.c (291268)
1/*
2 * Copyright (c) 1993 Paul Kranenburg
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Paul Kranenburg.
16 * 4. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
1/*
2 * Copyright (c) 1993 Paul Kranenburg
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Paul Kranenburg.
16 * 4. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: stable/10/usr.bin/ldd/ldd.c 254018 2013-08-07 00:28:17Z markj $");
32__FBSDID("$FreeBSD: stable/10/usr.bin/ldd/ldd.c 291268 2015-11-24 23:04:03Z jkim $");
33
34#include <sys/wait.h>
35
36#include <machine/elf.h>
37
38#include <arpa/inet.h>
39
40#include <a.out.h>
41#include <dlfcn.h>
42#include <err.h>
43#include <errno.h>
44#include <fcntl.h>
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48#include <unistd.h>
49
50#include "extern.h"
51
52/*
53 * 32-bit ELF data structures can only be used if the system header[s] declare
54 * them. There is no official macro for determining whether they are declared,
55 * so check for the existence of one of the 32-macros defined in elf(5).
56 */
57#ifdef ELF32_R_TYPE
58#define ELF32_SUPPORTED
59#endif
60
61#define LDD_SETENV(name, value, overwrite) do { \
62 setenv("LD_" name, value, overwrite); \
63 setenv("LD_32_" name, value, overwrite); \
64} while (0)
65
66#define LDD_UNSETENV(name) do { \
67 unsetenv("LD_" name); \
68 unsetenv("LD_32_" name); \
69} while (0)
70
71static int is_executable(const char *fname, int fd, int *is_shlib,
72 int *type);
73static void usage(void);
74
75#define TYPE_UNKNOWN 0
76#define TYPE_AOUT 1
77#define TYPE_ELF 2 /* Architecture default */
78#if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED)
79#define TYPE_ELF32 3 /* Explicit 32 bits on architectures >32 bits */
80
81#define _PATH_LDD32 "/usr/bin/ldd32"
82
83static int
84execldd32(char *file, char *fmt1, char *fmt2, int aflag, int vflag)
85{
86 char *argv[8];
87 int i, rval, status;
88
89 LDD_UNSETENV("TRACE_LOADED_OBJECTS");
90 rval = 0;
91 i = 0;
92 argv[i++] = strdup(_PATH_LDD32);
93 if (aflag)
94 argv[i++] = strdup("-a");
95 if (vflag)
96 argv[i++] = strdup("-v");
97 if (fmt1 != NULL) {
98 argv[i++] = strdup("-f");
99 argv[i++] = strdup(fmt1);
100 }
101 if (fmt2 != NULL) {
102 argv[i++] = strdup("-f");
103 argv[i++] = strdup(fmt2);
104 }
105 argv[i++] = strdup(file);
106 argv[i++] = NULL;
107
108 switch (fork()) {
109 case -1:
110 err(1, "fork");
111 break;
112 case 0:
113 execv(_PATH_LDD32, argv);
114 warn("%s", _PATH_LDD32);
115 _exit(127);
116 break;
117 default:
118 if (wait(&status) < 0)
119 rval = 1;
120 else if (WIFSIGNALED(status))
121 rval = 1;
122 else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
123 rval = 1;
124 break;
125 }
126 while (i--)
127 free(argv[i]);
128 LDD_SETENV("TRACE_LOADED_OBJECTS", "yes", 1);
129 return (rval);
130}
131#endif
132
133int
134main(int argc, char *argv[])
135{
136 char *fmt1, *fmt2;
137 int rval, c, aflag, vflag;
138
139 aflag = vflag = 0;
140 fmt1 = fmt2 = NULL;
141
142 while ((c = getopt(argc, argv, "af:v")) != -1) {
143 switch (c) {
144 case 'a':
145 aflag++;
146 break;
147 case 'f':
148 if (fmt1 != NULL) {
149 if (fmt2 != NULL)
150 errx(1, "too many formats");
151 fmt2 = optarg;
152 } else
153 fmt1 = optarg;
154 break;
155 case 'v':
156 vflag++;
157 break;
158 default:
159 usage();
160 /* NOTREACHED */
161 }
162 }
163 argc -= optind;
164 argv += optind;
165
166 if (vflag && fmt1 != NULL)
167 errx(1, "-v may not be used with -f");
168
169 if (argc <= 0) {
170 usage();
171 /* NOTREACHED */
172 }
173
174#ifdef __i386__
175 if (vflag) {
176 for (c = 0; c < argc; c++)
177 dump_file(argv[c]);
178 exit(error_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
179 }
180#endif
181
182 rval = 0;
183 for (; argc > 0; argc--, argv++) {
184 int fd, status, is_shlib, rv, type;
185
186 if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
187 warn("%s", *argv);
188 rval |= 1;
189 continue;
190 }
191 rv = is_executable(*argv, fd, &is_shlib, &type);
192 close(fd);
193 if (rv == 0) {
194 rval |= 1;
195 continue;
196 }
197
198 switch (type) {
199 case TYPE_ELF:
200 case TYPE_AOUT:
201 break;
202#if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED)
203 case TYPE_ELF32:
204 rval |= execldd32(*argv, fmt1, fmt2, aflag, vflag);
205 continue;
206#endif
207 case TYPE_UNKNOWN:
208 default:
209 /*
210 * This shouldn't happen unless is_executable()
211 * is broken.
212 */
213 errx(EDOOFUS, "unknown executable type");
214 }
215
216 /* ld.so magic */
217 LDD_SETENV("TRACE_LOADED_OBJECTS", "yes", 1);
218 if (fmt1 != NULL)
219 LDD_SETENV("TRACE_LOADED_OBJECTS_FMT1", fmt1, 1);
220 if (fmt2 != NULL)
221 LDD_SETENV("TRACE_LOADED_OBJECTS_FMT2", fmt2, 1);
222
223 LDD_SETENV("TRACE_LOADED_OBJECTS_PROGNAME", *argv, 1);
224 if (aflag)
225 LDD_SETENV("TRACE_LOADED_OBJECTS_ALL", "1", 1);
226 else if (fmt1 == NULL && fmt2 == NULL)
227 /* Default formats */
228 printf("%s:\n", *argv);
229 fflush(stdout);
230
231 switch (fork()) {
232 case -1:
233 err(1, "fork");
234 break;
235 default:
236 if (wait(&status) < 0) {
237 warn("wait");
238 rval |= 1;
239 } else if (WIFSIGNALED(status)) {
240 fprintf(stderr, "%s: signal %d\n", *argv,
241 WTERMSIG(status));
242 rval |= 1;
243 } else if (WIFEXITED(status) &&
244 WEXITSTATUS(status) != 0) {
245 fprintf(stderr, "%s: exit status %d\n", *argv,
246 WEXITSTATUS(status));
247 rval |= 1;
248 }
249 break;
250 case 0:
251 if (is_shlib == 0) {
252 execl(*argv, *argv, (char *)NULL);
253 warn("%s", *argv);
254 } else {
255 dlopen(*argv, RTLD_TRACE);
256 warnx("%s: %s", *argv, dlerror());
257 }
258 _exit(1);
259 }
260 }
261
262 return rval;
263}
264
265static void
266usage(void)
267{
268
269 fprintf(stderr, "usage: ldd [-a] [-v] [-f format] program ...\n");
270 exit(1);
271}
272
273static int
274is_executable(const char *fname, int fd, int *is_shlib, int *type)
275{
276 union {
277 struct exec aout;
278#if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED)
279 Elf32_Ehdr elf32;
280#endif
281 Elf_Ehdr elf;
282 } hdr;
283 int n;
284
285 *is_shlib = 0;
286 *type = TYPE_UNKNOWN;
287
288 if ((n = read(fd, &hdr, sizeof(hdr))) == -1) {
289 warn("%s: can't read program header", fname);
290 return (0);
291 }
292
293 if ((size_t)n >= sizeof(hdr.aout) && !N_BADMAG(hdr.aout)) {
294 /* a.out file */
295 if ((N_GETFLAG(hdr.aout) & EX_DPMASK) != EX_DYNAMIC
296#if 1 /* Compatibility */
297 || hdr.aout.a_entry < __LDPGSZ
298#endif
299 ) {
300 warnx("%s: not a dynamic executable", fname);
301 return (0);
302 }
303 *type = TYPE_AOUT;
304 return (1);
305 }
306
307#if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED)
308 if ((size_t)n >= sizeof(hdr.elf32) && IS_ELF(hdr.elf32) &&
309 hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) {
310 /* Handle 32 bit ELF objects */
311 Elf32_Phdr phdr;
312 int dynamic, i;
313
314 dynamic = 0;
315 *type = TYPE_ELF32;
316
317 if (lseek(fd, hdr.elf32.e_phoff, SEEK_SET) == -1) {
318 warnx("%s: header too short", fname);
319 return (0);
320 }
321 for (i = 0; i < hdr.elf32.e_phnum; i++) {
322 if (read(fd, &phdr, hdr.elf32.e_phentsize) !=
323 sizeof(phdr)) {
324 warnx("%s: can't read program header", fname);
325 return (0);
326 }
327 if (phdr.p_type == PT_DYNAMIC) {
328 dynamic = 1;
329 break;
330 }
331 }
332
333 if (!dynamic) {
334 warnx("%s: not a dynamic ELF executable", fname);
335 return (0);
336 }
337 if (hdr.elf32.e_type == ET_DYN) {
338 if (hdr.elf32.e_ident[EI_OSABI] == ELFOSABI_FREEBSD) {
339 *is_shlib = 1;
340 return (1);
341 }
342 warnx("%s: not a FreeBSD ELF shared object", fname);
343 return (0);
344 }
345
346 return (1);
347 }
348#endif
349
350 if ((size_t)n >= sizeof(hdr.elf) && IS_ELF(hdr.elf) &&
351 hdr.elf.e_ident[EI_CLASS] == ELF_TARG_CLASS) {
352 /* Handle default ELF objects on this architecture */
353 Elf_Phdr phdr;
354 int dynamic, i;
355
356 dynamic = 0;
357 *type = TYPE_ELF;
358
359 if (lseek(fd, hdr.elf.e_phoff, SEEK_SET) == -1) {
360 warnx("%s: header too short", fname);
361 return (0);
362 }
363 for (i = 0; i < hdr.elf.e_phnum; i++) {
364 if (read(fd, &phdr, hdr.elf.e_phentsize)
365 != sizeof(phdr)) {
366 warnx("%s: can't read program header", fname);
367 return (0);
368 }
369 if (phdr.p_type == PT_DYNAMIC) {
370 dynamic = 1;
371 break;
372 }
373 }
374
375 if (!dynamic) {
376 warnx("%s: not a dynamic ELF executable", fname);
377 return (0);
378 }
379 if (hdr.elf.e_type == ET_DYN) {
33
34#include <sys/wait.h>
35
36#include <machine/elf.h>
37
38#include <arpa/inet.h>
39
40#include <a.out.h>
41#include <dlfcn.h>
42#include <err.h>
43#include <errno.h>
44#include <fcntl.h>
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48#include <unistd.h>
49
50#include "extern.h"
51
52/*
53 * 32-bit ELF data structures can only be used if the system header[s] declare
54 * them. There is no official macro for determining whether they are declared,
55 * so check for the existence of one of the 32-macros defined in elf(5).
56 */
57#ifdef ELF32_R_TYPE
58#define ELF32_SUPPORTED
59#endif
60
61#define LDD_SETENV(name, value, overwrite) do { \
62 setenv("LD_" name, value, overwrite); \
63 setenv("LD_32_" name, value, overwrite); \
64} while (0)
65
66#define LDD_UNSETENV(name) do { \
67 unsetenv("LD_" name); \
68 unsetenv("LD_32_" name); \
69} while (0)
70
71static int is_executable(const char *fname, int fd, int *is_shlib,
72 int *type);
73static void usage(void);
74
75#define TYPE_UNKNOWN 0
76#define TYPE_AOUT 1
77#define TYPE_ELF 2 /* Architecture default */
78#if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED)
79#define TYPE_ELF32 3 /* Explicit 32 bits on architectures >32 bits */
80
81#define _PATH_LDD32 "/usr/bin/ldd32"
82
83static int
84execldd32(char *file, char *fmt1, char *fmt2, int aflag, int vflag)
85{
86 char *argv[8];
87 int i, rval, status;
88
89 LDD_UNSETENV("TRACE_LOADED_OBJECTS");
90 rval = 0;
91 i = 0;
92 argv[i++] = strdup(_PATH_LDD32);
93 if (aflag)
94 argv[i++] = strdup("-a");
95 if (vflag)
96 argv[i++] = strdup("-v");
97 if (fmt1 != NULL) {
98 argv[i++] = strdup("-f");
99 argv[i++] = strdup(fmt1);
100 }
101 if (fmt2 != NULL) {
102 argv[i++] = strdup("-f");
103 argv[i++] = strdup(fmt2);
104 }
105 argv[i++] = strdup(file);
106 argv[i++] = NULL;
107
108 switch (fork()) {
109 case -1:
110 err(1, "fork");
111 break;
112 case 0:
113 execv(_PATH_LDD32, argv);
114 warn("%s", _PATH_LDD32);
115 _exit(127);
116 break;
117 default:
118 if (wait(&status) < 0)
119 rval = 1;
120 else if (WIFSIGNALED(status))
121 rval = 1;
122 else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
123 rval = 1;
124 break;
125 }
126 while (i--)
127 free(argv[i]);
128 LDD_SETENV("TRACE_LOADED_OBJECTS", "yes", 1);
129 return (rval);
130}
131#endif
132
133int
134main(int argc, char *argv[])
135{
136 char *fmt1, *fmt2;
137 int rval, c, aflag, vflag;
138
139 aflag = vflag = 0;
140 fmt1 = fmt2 = NULL;
141
142 while ((c = getopt(argc, argv, "af:v")) != -1) {
143 switch (c) {
144 case 'a':
145 aflag++;
146 break;
147 case 'f':
148 if (fmt1 != NULL) {
149 if (fmt2 != NULL)
150 errx(1, "too many formats");
151 fmt2 = optarg;
152 } else
153 fmt1 = optarg;
154 break;
155 case 'v':
156 vflag++;
157 break;
158 default:
159 usage();
160 /* NOTREACHED */
161 }
162 }
163 argc -= optind;
164 argv += optind;
165
166 if (vflag && fmt1 != NULL)
167 errx(1, "-v may not be used with -f");
168
169 if (argc <= 0) {
170 usage();
171 /* NOTREACHED */
172 }
173
174#ifdef __i386__
175 if (vflag) {
176 for (c = 0; c < argc; c++)
177 dump_file(argv[c]);
178 exit(error_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
179 }
180#endif
181
182 rval = 0;
183 for (; argc > 0; argc--, argv++) {
184 int fd, status, is_shlib, rv, type;
185
186 if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
187 warn("%s", *argv);
188 rval |= 1;
189 continue;
190 }
191 rv = is_executable(*argv, fd, &is_shlib, &type);
192 close(fd);
193 if (rv == 0) {
194 rval |= 1;
195 continue;
196 }
197
198 switch (type) {
199 case TYPE_ELF:
200 case TYPE_AOUT:
201 break;
202#if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED)
203 case TYPE_ELF32:
204 rval |= execldd32(*argv, fmt1, fmt2, aflag, vflag);
205 continue;
206#endif
207 case TYPE_UNKNOWN:
208 default:
209 /*
210 * This shouldn't happen unless is_executable()
211 * is broken.
212 */
213 errx(EDOOFUS, "unknown executable type");
214 }
215
216 /* ld.so magic */
217 LDD_SETENV("TRACE_LOADED_OBJECTS", "yes", 1);
218 if (fmt1 != NULL)
219 LDD_SETENV("TRACE_LOADED_OBJECTS_FMT1", fmt1, 1);
220 if (fmt2 != NULL)
221 LDD_SETENV("TRACE_LOADED_OBJECTS_FMT2", fmt2, 1);
222
223 LDD_SETENV("TRACE_LOADED_OBJECTS_PROGNAME", *argv, 1);
224 if (aflag)
225 LDD_SETENV("TRACE_LOADED_OBJECTS_ALL", "1", 1);
226 else if (fmt1 == NULL && fmt2 == NULL)
227 /* Default formats */
228 printf("%s:\n", *argv);
229 fflush(stdout);
230
231 switch (fork()) {
232 case -1:
233 err(1, "fork");
234 break;
235 default:
236 if (wait(&status) < 0) {
237 warn("wait");
238 rval |= 1;
239 } else if (WIFSIGNALED(status)) {
240 fprintf(stderr, "%s: signal %d\n", *argv,
241 WTERMSIG(status));
242 rval |= 1;
243 } else if (WIFEXITED(status) &&
244 WEXITSTATUS(status) != 0) {
245 fprintf(stderr, "%s: exit status %d\n", *argv,
246 WEXITSTATUS(status));
247 rval |= 1;
248 }
249 break;
250 case 0:
251 if (is_shlib == 0) {
252 execl(*argv, *argv, (char *)NULL);
253 warn("%s", *argv);
254 } else {
255 dlopen(*argv, RTLD_TRACE);
256 warnx("%s: %s", *argv, dlerror());
257 }
258 _exit(1);
259 }
260 }
261
262 return rval;
263}
264
265static void
266usage(void)
267{
268
269 fprintf(stderr, "usage: ldd [-a] [-v] [-f format] program ...\n");
270 exit(1);
271}
272
273static int
274is_executable(const char *fname, int fd, int *is_shlib, int *type)
275{
276 union {
277 struct exec aout;
278#if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED)
279 Elf32_Ehdr elf32;
280#endif
281 Elf_Ehdr elf;
282 } hdr;
283 int n;
284
285 *is_shlib = 0;
286 *type = TYPE_UNKNOWN;
287
288 if ((n = read(fd, &hdr, sizeof(hdr))) == -1) {
289 warn("%s: can't read program header", fname);
290 return (0);
291 }
292
293 if ((size_t)n >= sizeof(hdr.aout) && !N_BADMAG(hdr.aout)) {
294 /* a.out file */
295 if ((N_GETFLAG(hdr.aout) & EX_DPMASK) != EX_DYNAMIC
296#if 1 /* Compatibility */
297 || hdr.aout.a_entry < __LDPGSZ
298#endif
299 ) {
300 warnx("%s: not a dynamic executable", fname);
301 return (0);
302 }
303 *type = TYPE_AOUT;
304 return (1);
305 }
306
307#if __ELF_WORD_SIZE > 32 && defined(ELF32_SUPPORTED)
308 if ((size_t)n >= sizeof(hdr.elf32) && IS_ELF(hdr.elf32) &&
309 hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) {
310 /* Handle 32 bit ELF objects */
311 Elf32_Phdr phdr;
312 int dynamic, i;
313
314 dynamic = 0;
315 *type = TYPE_ELF32;
316
317 if (lseek(fd, hdr.elf32.e_phoff, SEEK_SET) == -1) {
318 warnx("%s: header too short", fname);
319 return (0);
320 }
321 for (i = 0; i < hdr.elf32.e_phnum; i++) {
322 if (read(fd, &phdr, hdr.elf32.e_phentsize) !=
323 sizeof(phdr)) {
324 warnx("%s: can't read program header", fname);
325 return (0);
326 }
327 if (phdr.p_type == PT_DYNAMIC) {
328 dynamic = 1;
329 break;
330 }
331 }
332
333 if (!dynamic) {
334 warnx("%s: not a dynamic ELF executable", fname);
335 return (0);
336 }
337 if (hdr.elf32.e_type == ET_DYN) {
338 if (hdr.elf32.e_ident[EI_OSABI] == ELFOSABI_FREEBSD) {
339 *is_shlib = 1;
340 return (1);
341 }
342 warnx("%s: not a FreeBSD ELF shared object", fname);
343 return (0);
344 }
345
346 return (1);
347 }
348#endif
349
350 if ((size_t)n >= sizeof(hdr.elf) && IS_ELF(hdr.elf) &&
351 hdr.elf.e_ident[EI_CLASS] == ELF_TARG_CLASS) {
352 /* Handle default ELF objects on this architecture */
353 Elf_Phdr phdr;
354 int dynamic, i;
355
356 dynamic = 0;
357 *type = TYPE_ELF;
358
359 if (lseek(fd, hdr.elf.e_phoff, SEEK_SET) == -1) {
360 warnx("%s: header too short", fname);
361 return (0);
362 }
363 for (i = 0; i < hdr.elf.e_phnum; i++) {
364 if (read(fd, &phdr, hdr.elf.e_phentsize)
365 != sizeof(phdr)) {
366 warnx("%s: can't read program header", fname);
367 return (0);
368 }
369 if (phdr.p_type == PT_DYNAMIC) {
370 dynamic = 1;
371 break;
372 }
373 }
374
375 if (!dynamic) {
376 warnx("%s: not a dynamic ELF executable", fname);
377 return (0);
378 }
379 if (hdr.elf.e_type == ET_DYN) {
380 if (hdr.elf.e_ident[EI_OSABI] == ELFOSABI_FREEBSD) {
380 switch (hdr.elf.e_ident[EI_OSABI]) {
381 case ELFOSABI_FREEBSD:
381 *is_shlib = 1;
382 return (1);
382 *is_shlib = 1;
383 return (1);
384#ifdef __ARM_EABI__
385 case ELFOSABI_NONE:
386 if (hdr.elf.e_machine != EM_ARM)
387 break;
388 if (((hdr.elf.e_flags & 0xff000000) >> 24) < 4)
389 break;
390 *is_shlib = 1;
391 return (1);
392#endif
383 }
384 warnx("%s: not a FreeBSD ELF shared object", fname);
385 return (0);
386 }
387
388 return (1);
389 }
390
391 warnx("%s: not a dynamic executable", fname);
392 return (0);
393}
393 }
394 warnx("%s: not a FreeBSD ELF shared object", fname);
395 return (0);
396 }
397
398 return (1);
399 }
400
401 warnx("%s: not a dynamic executable", fname);
402 return (0);
403}