Annotation of src/usr.bin/file/readelf.c, Revision 1.5
1.5 ! ian 1: /*
! 2: * ELF routines for the file command.
! 3: *
! 4: * Copyright (c) Ian F. Darwin 1986-1995.
! 5: * Software written by Ian F. Darwin and others;
! 6: * maintained 1995-present by Christos Zoulas and others.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice immediately at the beginning of the file, without modification,
! 13: * this list of conditions, and the following disclaimer.
! 14: * 2. Redistributions in binary form must reproduce the above copyright
! 15: * notice, this list of conditions and the following disclaimer in the
! 16: * documentation and/or other materials provided with the distribution.
! 17: * 3. All advertising materials mentioning features or use of this software
! 18: * must display the following acknowledgement:
! 19: * This product includes software developed by Ian F. Darwin and others.
! 20: * 4. The name of the author may not be used to endorse or promote products
! 21: * derived from this software without specific prior written permission.
! 22: *
! 23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
! 24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 26: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
! 27: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 33: * SUCH DAMAGE.
! 34: */
! 35:
1.4 ian 36: #include "file.h"
1.1 millert 37:
38: #ifdef BUILTIN_ELF
39: #include <string.h>
40: #include <ctype.h>
41: #include <stdlib.h>
1.4 ian 42: #ifdef HAVE_UNISTD_H
1.1 millert 43: #include <unistd.h>
1.4 ian 44: #endif
1.1 millert 45:
46: #include "readelf.h"
1.4 ian 47:
48: #ifndef lint
1.5 ! ian 49: static char *RCSID = "@(#)$Id: readelf.c,v 1.4 2003/03/03 22:24:08 ian Exp $";
1.4 ian 50: #endif
51:
52: #ifdef ELFCORE
53: static void dophn_core(int, int, int, off_t, int, size_t);
54: #endif
55: static void dophn_exec(int, int, int, off_t, int, size_t);
56: static void doshn(int, int, int, off_t, int, size_t);
57:
58: static uint16_t getu16(int, uint16_t);
59: static uint32_t getu32(int, uint32_t);
60: static uint64_t getu64(int, uint64_t);
61:
62: static uint16_t
63: getu16(int swap, uint16_t value)
64: {
65: union {
66: uint16_t ui;
67: char c[2];
68: } retval, tmpval;
69:
70: if (swap) {
71: tmpval.ui = value;
72:
73: retval.c[0] = tmpval.c[1];
74: retval.c[1] = tmpval.c[0];
75:
76: return retval.ui;
77: } else
78: return value;
79: }
80:
81: static uint32_t
82: getu32(int swap, uint32_t value)
83: {
84: union {
85: uint32_t ui;
86: char c[4];
87: } retval, tmpval;
88:
89: if (swap) {
90: tmpval.ui = value;
91:
92: retval.c[0] = tmpval.c[3];
93: retval.c[1] = tmpval.c[2];
94: retval.c[2] = tmpval.c[1];
95: retval.c[3] = tmpval.c[0];
96:
97: return retval.ui;
98: } else
99: return value;
100: }
101:
102: static uint64_t
103: getu64(int swap, uint64_t value)
104: {
105: union {
106: uint64_t ui;
107: char c[8];
108: } retval, tmpval;
109:
110: if (swap) {
111: tmpval.ui = value;
112:
113: retval.c[0] = tmpval.c[7];
114: retval.c[1] = tmpval.c[6];
115: retval.c[2] = tmpval.c[5];
116: retval.c[3] = tmpval.c[4];
117: retval.c[4] = tmpval.c[3];
118: retval.c[5] = tmpval.c[2];
119: retval.c[6] = tmpval.c[1];
120: retval.c[7] = tmpval.c[0];
121:
122: return retval.ui;
123: } else
124: return value;
125: }
126:
127: #define sh_addr (class == ELFCLASS32 \
128: ? (void *) &sh32 \
129: : (void *) &sh64)
130: #define sh_size (class == ELFCLASS32 \
131: ? sizeof sh32 \
132: : sizeof sh64)
133: #define shs_type (class == ELFCLASS32 \
134: ? getu32(swap, sh32.sh_type) \
135: : getu32(swap, sh64.sh_type))
136: #define ph_addr (class == ELFCLASS32 \
137: ? (void *) &ph32 \
138: : (void *) &ph64)
139: #define ph_size (class == ELFCLASS32 \
140: ? sizeof ph32 \
141: : sizeof ph64)
142: #define ph_type (class == ELFCLASS32 \
143: ? getu32(swap, ph32.p_type) \
144: : getu32(swap, ph64.p_type))
145: #define ph_offset (class == ELFCLASS32 \
146: ? getu32(swap, ph32.p_offset) \
147: : getu64(swap, ph64.p_offset))
148: #define ph_align (class == ELFCLASS32 \
149: ? (ph32.p_align ? getu32(swap, ph32.p_align) : 4) \
150: : (ph64.p_align ? getu64(swap, ph64.p_align) : 4))
151: #define nh_size (class == ELFCLASS32 \
152: ? sizeof *nh32 \
153: : sizeof *nh64)
154: #define nh_type (class == ELFCLASS32 \
155: ? getu32(swap, nh32->n_type) \
156: : getu32(swap, nh64->n_type))
157: #define nh_namesz (class == ELFCLASS32 \
158: ? getu32(swap, nh32->n_namesz) \
159: : getu32(swap, nh64->n_namesz))
160: #define nh_descsz (class == ELFCLASS32 \
161: ? getu32(swap, nh32->n_descsz) \
162: : getu32(swap, nh64->n_descsz))
163: #define prpsoffsets(i) (class == ELFCLASS32 \
164: ? prpsoffsets32[i] \
165: : prpsoffsets64[i])
1.1 millert 166:
167: static void
1.4 ian 168: doshn(int class, int swap, int fd, off_t off, int num, size_t size)
1.1 millert 169: {
1.4 ian 170: Elf32_Shdr sh32;
171: Elf64_Shdr sh64;
172:
173: if (size != sh_size)
174: error("corrupted section header size.\n");
1.1 millert 175:
176: if (lseek(fd, off, SEEK_SET) == -1)
1.4 ian 177: error("lseek failed (%s).\n", strerror(errno));
1.1 millert 178:
179: for ( ; num; num--) {
1.4 ian 180: if (read(fd, sh_addr, sh_size) == -1)
181: error("read failed (%s).\n", strerror(errno));
182: if (shs_type == SHT_SYMTAB /* || shs_type == SHT_DYNSYM */) {
1.1 millert 183: (void) printf (", not stripped");
184: return;
185: }
186: }
187: (void) printf (", stripped");
188: }
189:
190: /*
191: * Look through the program headers of an executable image, searching
192: * for a PT_INTERP section; if one is found, it's dynamically linked,
193: * otherwise it's statically linked.
194: */
195: static void
1.4 ian 196: dophn_exec(int class, int swap, int fd, off_t off, int num, size_t size)
1.1 millert 197: {
1.4 ian 198: Elf32_Phdr ph32;
199: Elf32_Nhdr *nh32 = NULL;
200: Elf64_Phdr ph64;
201: Elf64_Nhdr *nh64 = NULL;
202: char *linking_style = "statically";
203: char *shared_libraries = "";
204: char nbuf[BUFSIZ];
205: int bufsize;
206: size_t offset, nameoffset;
207: off_t savedoffset;
1.1 millert 208:
1.4 ian 209: if (size != ph_size)
210: error("corrupted program header size.\n");
1.1 millert 211: if (lseek(fd, off, SEEK_SET) == -1)
1.4 ian 212: error("lseek failed (%s).\n", strerror(errno));
1.1 millert 213:
214: for ( ; num; num--) {
1.4 ian 215: if (read(fd, ph_addr, ph_size) == -1)
216: error("read failed (%s).\n", strerror(errno));
217: if ((savedoffset = lseek(fd, 0, SEEK_CUR)) == -1)
218: error("lseek failed (%s).\n", strerror(errno));
219:
220: switch (ph_type) {
221: case PT_DYNAMIC:
222: linking_style = "dynamically";
223: break;
224: case PT_INTERP:
225: shared_libraries = " (uses shared libs)";
226: break;
227: case PT_NOTE:
1.1 millert 228: /*
1.4 ian 229: * This is a PT_NOTE section; loop through all the notes
230: * in the section.
1.1 millert 231: */
1.4 ian 232: if (lseek(fd, (off_t) ph_offset, SEEK_SET) == -1)
233: error("lseek failed (%s).\n", strerror(errno));
234: bufsize = read(fd, nbuf, sizeof(nbuf));
235: if (bufsize == -1)
236: error(": " "read failed (%s).\n",
237: strerror(errno));
238: offset = 0;
239: for (;;) {
240: if (offset >= bufsize)
241: break;
242: if (class == ELFCLASS32)
243: nh32 = (Elf32_Nhdr *)&nbuf[offset];
244: else
245: nh64 = (Elf64_Nhdr *)&nbuf[offset];
246: offset += nh_size;
247:
248: if (offset + nh_namesz >= bufsize) {
249: /*
250: * We're past the end of the buffer.
251: */
252: break;
253: }
254:
255: nameoffset = offset;
256: offset += nh_namesz;
257: offset = ((offset+ph_align-1)/ph_align)*ph_align;
258:
259: if ((nh_namesz == 0) && (nh_descsz == 0)) {
260: /*
261: * We're out of note headers.
262: */
263: break;
264: }
265:
266: if (offset + nh_descsz >= bufsize)
267: break;
268:
269: if (nh_namesz == 4 &&
270: strcmp(&nbuf[nameoffset], "GNU") == 0 &&
271: nh_type == NT_GNU_VERSION &&
272: nh_descsz == 16) {
273: uint32_t *desc =
274: (uint32_t *)&nbuf[offset];
275:
276: printf(", for GNU/");
277: switch (getu32(swap, desc[0])) {
278: case GNU_OS_LINUX:
279: printf("Linux");
280: break;
281: case GNU_OS_HURD:
282: printf("Hurd");
283: break;
284: case GNU_OS_SOLARIS:
285: printf("Solaris");
286: break;
287: default:
288: printf("<unknown>");
289: }
290: printf(" %d.%d.%d",
291: getu32(swap, desc[1]),
292: getu32(swap, desc[2]),
293: getu32(swap, desc[3]));
294: }
295:
296: if (nh_namesz == 7 &&
297: strcmp(&nbuf[nameoffset], "NetBSD") == 0 &&
298: nh_type == NT_NETBSD_VERSION &&
299: nh_descsz == 4) {
300: printf(", for NetBSD");
301: /*
302: * Version number is stuck at 199905,
303: * and hence is basically content-free.
304: */
305: }
306:
307: if (nh_namesz == 8 &&
308: strcmp(&nbuf[nameoffset], "FreeBSD") == 0 &&
309: nh_type == NT_FREEBSD_VERSION &&
310: nh_descsz == 4) {
311: uint32_t desc = getu32(swap,
312: *(uint32_t *)&nbuf[offset]);
313: printf(", for FreeBSD");
314: /*
315: * Contents is __FreeBSD_version,
316: * whose relation to OS versions is
317: * defined by a huge table in the
318: * Porters' Handbook. Happily, the
319: * first three digits are the version
320: * number, at least in versions of
321: * FreeBSD that use this note.
322: */
323:
324: printf(" %d.%d", desc / 100000,
325: desc / 10000 % 10);
326: if (desc / 1000 % 10 > 0)
327: printf(".%d",
328: desc / 1000 % 10);
329: }
330:
331: if (nh_namesz == 8 &&
332: strcmp(&nbuf[nameoffset], "OpenBSD") == 0 &&
333: nh_type == NT_OPENBSD_VERSION &&
334: nh_descsz == 4) {
335: printf(", for OpenBSD");
336: /* Content of note is always 0 */
337: }
338: }
339: if ((lseek(fd, savedoffset + offset, SEEK_SET)) == -1)
340: error("lseek failed (%s).\n", strerror(errno));
341: break;
1.1 millert 342: }
343: }
1.4 ian 344: printf(", %s linked%s", linking_style, shared_libraries);
1.1 millert 345: }
346:
1.4 ian 347: #ifdef ELFCORE
348: size_t prpsoffsets32[] = {
349: 8, /* FreeBSD */
350: 28, /* Linux 2.0.36 */
351: 32, /* Linux (I forget which kernel version) */
352: 84, /* SunOS 5.x */
353: };
354:
355: size_t prpsoffsets64[] = {
356: 120, /* SunOS 5.x, 64-bit */
1.1 millert 357: };
358:
1.4 ian 359: #define NOFFSETS32 (sizeof prpsoffsets32 / sizeof prpsoffsets32[0])
360: #define NOFFSETS64 (sizeof prpsoffsets64 / sizeof prpsoffsets64[0])
361:
362: #define NOFFSETS (class == ELFCLASS32 ? NOFFSETS32 : NOFFSETS64)
1.1 millert 363:
364: /*
365: * Look through the program headers of an executable image, searching
1.4 ian 366: * for a PT_NOTE section of type NT_PRPSINFO, with a name "CORE" or
367: * "FreeBSD"; if one is found, try looking in various places in its
368: * contents for a 16-character string containing only printable
369: * characters - if found, that string should be the name of the program
370: * that dropped core. Note: right after that 16-character string is,
371: * at least in SunOS 5.x (and possibly other SVR4-flavored systems) and
372: * Linux, a longer string (80 characters, in 5.x, probably other
373: * SVR4-flavored systems, and Linux) containing the start of the
374: * command line for that program.
375: *
376: * The signal number probably appears in a section of type NT_PRSTATUS,
377: * but that's also rather OS-dependent, in ways that are harder to
378: * dissect with heuristics, so I'm not bothering with the signal number.
379: * (I suppose the signal number could be of interest in situations where
380: * you don't have the binary of the program that dropped core; if you
381: * *do* have that binary, the debugger will probably tell you what
382: * signal it was.)
1.1 millert 383: */
1.4 ian 384:
385: #define OS_STYLE_SVR4 0
386: #define OS_STYLE_FREEBSD 1
387: #define OS_STYLE_NETBSD 2
388:
389: static const char *os_style_names[] = {
390: "SVR4",
391: "FreeBSD",
392: "NetBSD",
393: };
394:
1.1 millert 395: static void
1.4 ian 396: dophn_core(int class, int swap, int fd, off_t off, int num, size_t size)
1.1 millert 397: {
1.4 ian 398: Elf32_Phdr ph32;
399: Elf32_Nhdr *nh32 = NULL;
400: Elf64_Phdr ph64;
401: Elf64_Nhdr *nh64 = NULL;
402: size_t offset, nameoffset, noffset, reloffset;
1.1 millert 403: unsigned char c;
404: int i, j;
405: char nbuf[BUFSIZ];
406: int bufsize;
1.4 ian 407: int os_style = -1;
1.1 millert 408:
1.4 ian 409: if (size != ph_size)
410: error("corrupted program header size.\n");
411: /*
412: * Loop through all the program headers.
413: */
1.1 millert 414: for ( ; num; num--) {
415: if (lseek(fd, off, SEEK_SET) == -1)
1.4 ian 416: error("lseek failed (%s).\n", strerror(errno));
417: if (read(fd, ph_addr, ph_size) == -1)
418: error("read failed (%s).\n", strerror(errno));
1.1 millert 419: off += size;
1.4 ian 420: if (ph_type != PT_NOTE)
1.1 millert 421: continue;
1.4 ian 422:
423: /*
424: * This is a PT_NOTE section; loop through all the notes
425: * in the section.
426: */
427: if (lseek(fd, (off_t) ph_offset, SEEK_SET) == -1)
428: error("lseek failed (%s).\n", strerror(errno));
1.1 millert 429: bufsize = read(fd, nbuf, BUFSIZ);
430: if (bufsize == -1)
1.4 ian 431: error(": " "read failed (%s).\n", strerror(errno));
1.1 millert 432: offset = 0;
433: for (;;) {
434: if (offset >= bufsize)
435: break;
1.4 ian 436: if (class == ELFCLASS32)
437: nh32 = (Elf32_Nhdr *)&nbuf[offset];
438: else
439: nh64 = (Elf64_Nhdr *)&nbuf[offset];
440: offset += nh_size;
1.1 millert 441:
442: /*
1.4 ian 443: * Check whether this note has the name "CORE" or
444: * "FreeBSD", or "NetBSD-CORE".
1.1 millert 445: */
1.4 ian 446: if (offset + nh_namesz >= bufsize) {
1.1 millert 447: /*
448: * We're past the end of the buffer.
449: */
450: break;
451: }
1.4 ian 452:
453: nameoffset = offset;
454: offset += nh_namesz;
1.1 millert 455: offset = ((offset + 3)/4)*4;
456:
457: /*
1.4 ian 458: * Sigh. The 2.0.36 kernel in Debian 2.1, at
459: * least, doesn't correctly implement name
460: * sections, in core dumps, as specified by
461: * the "Program Linking" section of "UNIX(R) System
462: * V Release 4 Programmer's Guide: ANSI C and
463: * Programming Support Tools", because my copy
464: * clearly says "The first 'namesz' bytes in 'name'
465: * contain a *null-terminated* [emphasis mine]
466: * character representation of the entry's owner
467: * or originator", but the 2.0.36 kernel code
468: * doesn't include the terminating null in the
469: * name....
1.1 millert 470: */
1.4 ian 471: if (os_style == -1) {
472: if ((nh_namesz == 4 &&
473: strncmp(&nbuf[nameoffset],
474: "CORE", 4) == 0) ||
475: (nh_namesz == 5 &&
476: strcmp(&nbuf[nameoffset],
477: "CORE") == 0)) {
478: os_style = OS_STYLE_SVR4;
479: } else
480: if ((nh_namesz == 8 &&
481: strcmp(&nbuf[nameoffset],
482: "FreeBSD") == 0)) {
483: os_style = OS_STYLE_FREEBSD;
484: } else
485: if ((nh_namesz >= 11 &&
486: strncmp(&nbuf[nameoffset],
487: "NetBSD-CORE", 11) == 0)) {
488: os_style = OS_STYLE_NETBSD;
489: } else
490: continue;
491: printf(", %s-style", os_style_names[os_style]);
492: }
493:
494: if (os_style == OS_STYLE_NETBSD &&
495: nh_type == NT_NETBSD_CORE_PROCINFO) {
496: uint32_t signo;
497:
498: /*
499: * Extract the program name. It is at
500: * offset 0x7c, and is up to 32-bytes,
501: * including the terminating NUL.
502: */
503: printf(", from '%.31s'", &nbuf[offset + 0x7c]);
504:
505: /*
506: * Extract the signal number. It is at
507: * offset 0x08.
508: */
509: memcpy(&signo, &nbuf[offset + 0x08],
510: sizeof(signo));
511: printf(" (signal %u)", getu32(swap, signo));
512: } else
513: if (os_style != OS_STYLE_NETBSD &&
514: nh_type == NT_PRPSINFO) {
515: /*
516: * Extract the program name. We assume
517: * it to be 16 characters (that's what it
518: * is in SunOS 5.x and Linux).
519: *
520: * Unfortunately, it's at a different offset
521: * in varous OSes, so try multiple offsets.
522: * If the characters aren't all printable,
523: * reject it.
524: */
525: for (i = 0; i < NOFFSETS; i++) {
526: reloffset = prpsoffsets(i);
527: noffset = offset + reloffset;
528: for (j = 0; j < 16;
529: j++, noffset++, reloffset++) {
530: /*
531: * Make sure we're not past
532: * the end of the buffer; if
533: * we are, just give up.
534: */
535: if (noffset >= bufsize)
536: goto tryanother;
537:
538: /*
539: * Make sure we're not past
540: * the end of the contents;
541: * if we are, this obviously
542: * isn't the right offset.
543: */
544: if (reloffset >= nh_descsz)
545: goto tryanother;
546:
547: c = nbuf[noffset];
548: if (c == '\0') {
549: /*
550: * A '\0' at the
551: * beginning is
552: * obviously wrong.
553: * Any other '\0'
554: * means we're done.
555: */
556: if (j == 0)
557: goto tryanother;
558: else
559: break;
560: } else {
561: /*
562: * A nonprintable
563: * character is also
564: * wrong.
565: */
566: #define isquote(c) (strchr("'\"`", (c)) != NULL)
567: if (!isprint(c) ||
568: isquote(c))
569: goto tryanother;
570: }
571: }
1.1 millert 572:
573: /*
1.4 ian 574: * Well, that worked.
1.1 millert 575: */
1.4 ian 576: printf(", from '%.16s'",
577: &nbuf[offset + prpsoffsets(i)]);
578: break;
1.1 millert 579:
1.4 ian 580: tryanother:
581: ;
1.1 millert 582: }
1.4 ian 583: break;
1.1 millert 584: }
1.4 ian 585: offset += nh_descsz;
1.1 millert 586: offset = ((offset + 3)/4)*4;
587: }
588: }
589: }
1.4 ian 590: #endif
1.1 millert 591:
592: void
1.4 ian 593: tryelf(int fd, unsigned char *buf, int nbytes)
1.1 millert 594: {
595: union {
1.3 itojun 596: int32_t l;
597: char c[sizeof (int32_t)];
1.1 millert 598: } u;
1.4 ian 599: int class;
600: int swap;
601:
602: /*
603: * If we can't seek, it must be a pipe, socket or fifo.
604: */
605: if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
606: fd = pipe2file(fd, buf, nbytes);
1.1 millert 607:
608: /*
609: * ELF executables have multiple section headers in arbitrary
610: * file locations and thus file(1) cannot determine it from easily.
611: * Instead we traverse thru all section headers until a symbol table
612: * one is found or else the binary is stripped.
613: */
1.4 ian 614: if (buf[EI_MAG0] != ELFMAG0
615: || (buf[EI_MAG1] != ELFMAG1 && buf[EI_MAG1] != OLFMAG1)
1.1 millert 616: || buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3)
617: return;
618:
619:
1.4 ian 620: class = buf[4];
621:
622: if (class == ELFCLASS32) {
1.1 millert 623: Elf32_Ehdr elfhdr;
624: if (nbytes <= sizeof (Elf32_Ehdr))
625: return;
626:
627:
628: u.l = 1;
629: (void) memcpy(&elfhdr, buf, sizeof elfhdr);
1.4 ian 630: swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[5];
631:
632: if (getu16(swap, elfhdr.e_type) == ET_CORE)
633: #ifdef ELFCORE
634: dophn_core(class, swap,
635: fd,
636: getu32(swap, elfhdr.e_phoff),
637: getu16(swap, elfhdr.e_phnum),
638: getu16(swap, elfhdr.e_phentsize));
639: #else
640: ;
641: #endif
642: else {
643: if (getu16(swap, elfhdr.e_type) == ET_EXEC) {
644: dophn_exec(class, swap,
645: fd,
646: getu32(swap, elfhdr.e_phoff),
647: getu16(swap, elfhdr.e_phnum),
648: getu16(swap, elfhdr.e_phentsize));
1.1 millert 649: }
1.4 ian 650: doshn(class, swap,
651: fd,
652: getu32(swap, elfhdr.e_shoff),
653: getu16(swap, elfhdr.e_shnum),
654: getu16(swap, elfhdr.e_shentsize));
1.1 millert 655: }
656: return;
657: }
658:
1.4 ian 659: if (class == ELFCLASS64) {
1.1 millert 660: Elf64_Ehdr elfhdr;
661: if (nbytes <= sizeof (Elf64_Ehdr))
662: return;
663:
664:
665: u.l = 1;
666: (void) memcpy(&elfhdr, buf, sizeof elfhdr);
1.4 ian 667: swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[5];
1.1 millert 668:
1.4 ian 669: if (getu16(swap, elfhdr.e_type) == ET_CORE)
670: #ifdef ELFCORE
671: dophn_core(class, swap,
672: fd,
673: #ifdef USE_ARRAY_FOR_64BIT_TYPES
674: getu32(swap, elfhdr.e_phoff[1]),
675: #else
676: getu64(swap, elfhdr.e_phoff),
677: #endif
678: getu16(swap, elfhdr.e_phnum),
679: getu16(swap, elfhdr.e_phentsize));
680: #else
681: ;
1.1 millert 682: #endif
1.4 ian 683: else
684: {
685: if (getu16(swap, elfhdr.e_type) == ET_EXEC) {
686: dophn_exec(class, swap,
687: fd,
688: #ifdef USE_ARRAY_FOR_64BIT_TYPES
689: getu32(swap, elfhdr.e_phoff[1]),
690: #else
691: getu64(swap, elfhdr.e_phoff),
1.1 millert 692: #endif
1.4 ian 693: getu16(swap, elfhdr.e_phnum),
694: getu16(swap, elfhdr.e_phentsize));
1.1 millert 695: }
1.4 ian 696: doshn(class, swap,
697: fd,
698: #ifdef USE_ARRAY_FOR_64BIT_TYPES
699: getu32(swap, elfhdr.e_shoff[1]),
700: #else
701: getu64(swap, elfhdr.e_shoff),
702: #endif
703: getu16(swap, elfhdr.e_shnum),
704: getu16(swap, elfhdr.e_shentsize));
1.1 millert 705: }
706: return;
707: }
708: }
709: #endif