00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "file.h"
00028
00029 #ifdef BUILTIN_ELF
00030 #include <string.h>
00031 #include <ctype.h>
00032 #include <stdlib.h>
00033 #ifdef HAVE_UNISTD_H
00034 #include <unistd.h>
00035 #endif
00036
00037 #include "readelf.h"
00038
00039 #ifndef lint
00040 FILE_RCSID("@(#)$Id: readelf.c,v 1.47 2005/06/25 15:52:14 christos Exp $")
00041 #endif
00042
00043 #ifdef ELFCORE
00044 private int dophn_core(struct magic_set *ms, int class, int swap, int fd, off_t off, int num, size_t size)
00045 ;
00046 #endif
00047 private int dophn_exec(struct magic_set *ms, int class, int swap, int fd, off_t off, int num, size_t size)
00048 ;
00049 private int doshn(struct magic_set *ms, int class, int swap, int fd, off_t off, int num, size_t size)
00050 ;
00051 private size_t donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size, int class,
00052 int swap, size_t align)
00053 ;
00054
00055 #define ELF_ALIGN(a) ((((a) + align - 1) / align) * align)
00056
00057 private uint16_t getu16(int swap, uint16_t value)
00058 ;
00059 private uint32_t getu32(int swap, uint32_t value)
00060 ;
00061 private uint64_t getu64(int swap, uint64_t value)
00062 ;
00063
00064 private uint16_t
00065 getu16(int swap, uint16_t value)
00066 {
00067 union {
00068 uint16_t ui;
00069 char c[2];
00070 } retval, tmpval;
00071
00072 if (swap) {
00073 tmpval.ui = value;
00074
00075 retval.c[0] = tmpval.c[1];
00076 retval.c[1] = tmpval.c[0];
00077
00078 return retval.ui;
00079 } else
00080 return value;
00081 }
00082
00083 private uint32_t
00084 getu32(int swap, uint32_t value)
00085 {
00086 union {
00087 uint32_t ui;
00088 char c[4];
00089 } retval, tmpval;
00090
00091 if (swap) {
00092 tmpval.ui = value;
00093
00094 retval.c[0] = tmpval.c[3];
00095 retval.c[1] = tmpval.c[2];
00096 retval.c[2] = tmpval.c[1];
00097 retval.c[3] = tmpval.c[0];
00098
00099 return retval.ui;
00100 } else
00101 return value;
00102 }
00103
00104 private uint64_t
00105 getu64(int swap, uint64_t value)
00106 {
00107 union {
00108 uint64_t ui;
00109 char c[8];
00110 } retval, tmpval;
00111
00112 if (swap) {
00113 tmpval.ui = value;
00114
00115 retval.c[0] = tmpval.c[7];
00116 retval.c[1] = tmpval.c[6];
00117 retval.c[2] = tmpval.c[5];
00118 retval.c[3] = tmpval.c[4];
00119 retval.c[4] = tmpval.c[3];
00120 retval.c[5] = tmpval.c[2];
00121 retval.c[6] = tmpval.c[1];
00122 retval.c[7] = tmpval.c[0];
00123
00124 return retval.ui;
00125 } else
00126 return value;
00127 }
00128
00129 #define sh_addr (class == ELFCLASS32 \
00130 ? (void *) &sh32 \
00131 : (void *) &sh64)
00132 #define sh_size (class == ELFCLASS32 \
00133 ? sizeof sh32 \
00134 : sizeof sh64)
00135 #define shs_type (class == ELFCLASS32 \
00136 ? getu32(swap, sh32.sh_type) \
00137 : getu32(swap, sh64.sh_type))
00138 #define ph_addr (class == ELFCLASS32 \
00139 ? (void *) &ph32 \
00140 : (void *) &ph64)
00141 #define ph_size (class == ELFCLASS32 \
00142 ? sizeof ph32 \
00143 : sizeof ph64)
00144 #define ph_type (class == ELFCLASS32 \
00145 ? getu32(swap, ph32.p_type) \
00146 : getu32(swap, ph64.p_type))
00147 #define ph_offset (class == ELFCLASS32 \
00148 ? getu32(swap, ph32.p_offset) \
00149 : getu64(swap, ph64.p_offset))
00150 #define ph_align (size_t)((class == ELFCLASS32 \
00151 ? (off_t) (ph32.p_align ? \
00152 getu32(swap, ph32.p_align) : 4) \
00153 : (off_t) (ph64.p_align ? \
00154 getu64(swap, ph64.p_align) : 4)))
00155 #define ph_filesz (size_t)((class == ELFCLASS32 \
00156 ? getu32(swap, ph32.p_filesz) \
00157 : getu64(swap, ph64.p_filesz)))
00158 #define ph_memsz (size_t)((class == ELFCLASS32 \
00159 ? getu32(swap, ph32.p_memsz) \
00160 : getu64(swap, ph64.p_memsz)))
00161 #define nh_size (class == ELFCLASS32 \
00162 ? sizeof nh32 \
00163 : sizeof nh64)
00164 #define nh_type (class == ELFCLASS32 \
00165 ? getu32(swap, nh32.n_type) \
00166 : getu32(swap, nh64.n_type))
00167 #define nh_namesz (class == ELFCLASS32 \
00168 ? getu32(swap, nh32.n_namesz) \
00169 : getu32(swap, nh64.n_namesz))
00170 #define nh_descsz (class == ELFCLASS32 \
00171 ? getu32(swap, nh32.n_descsz) \
00172 : getu32(swap, nh64.n_descsz))
00173 #define prpsoffsets(i) (class == ELFCLASS32 \
00174 ? prpsoffsets32[i] \
00175 : prpsoffsets64[i])
00176
00177 #ifdef ELFCORE
00178
00179 size_t prpsoffsets32[] = {
00180 8,
00181 28,
00182 32,
00183 84,
00184 };
00185
00186
00187 size_t prpsoffsets64[] = {
00188 40,
00189 120,
00190 };
00191
00192 #define NOFFSETS32 (sizeof prpsoffsets32 / sizeof prpsoffsets32[0])
00193 #define NOFFSETS64 (sizeof prpsoffsets64 / sizeof prpsoffsets64[0])
00194
00195 #define NOFFSETS (class == ELFCLASS32 ? NOFFSETS32 : NOFFSETS64)
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 #define OS_STYLE_SVR4 0
00219 #define OS_STYLE_FREEBSD 1
00220 #define OS_STYLE_NETBSD 2
00221
00222
00223 private const char *os_style_names[] = {
00224 "SVR4",
00225 "FreeBSD",
00226 "NetBSD",
00227 };
00228
00229 private int
00230 dophn_core(struct magic_set *ms, int class, int swap, int fd, off_t off,
00231 int num, size_t size)
00232 {
00233 Elf32_Phdr ph32;
00234 Elf64_Phdr ph64;
00235 size_t offset;
00236 unsigned char nbuf[BUFSIZ];
00237 ssize_t bufsize;
00238
00239 if (size != ph_size) {
00240 if (file_printf(ms, ", corrupted program header size") == -1)
00241 return -1;
00242 return 0;
00243 }
00244
00245
00246
00247 for ( ; num; num--) {
00248 if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
00249 file_badseek(ms);
00250 return -1;
00251 }
00252 if (read(fd, ph_addr, ph_size) == -1) {
00253 file_badread(ms);
00254 return -1;
00255 }
00256 off += size;
00257 if (ph_type != PT_NOTE)
00258 continue;
00259
00260
00261
00262
00263
00264 if (lseek(fd, (off_t) ph_offset, SEEK_SET) == (off_t)-1) {
00265 file_badseek(ms);
00266 return -1;
00267 }
00268 bufsize = read(fd, nbuf,
00269 ((ph_filesz < sizeof(nbuf)) ? ph_filesz : sizeof(nbuf)));
00270 if (bufsize == -1) {
00271 file_badread(ms);
00272 return -1;
00273 }
00274 offset = 0;
00275 for (;;) {
00276 if (offset >= (size_t)bufsize)
00277 break;
00278 offset = donote(ms, nbuf, offset, (size_t)bufsize,
00279 class, swap, 4);
00280 if (offset == 0)
00281 break;
00282
00283 }
00284 }
00285 return 0;
00286 }
00287 #endif
00288
00289 private size_t
00290 donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size,
00291 int class, int swap, size_t align)
00292 {
00293 Elf32_Nhdr nh32;
00294 Elf64_Nhdr nh64;
00295 size_t noff, doff;
00296 #ifdef ELFCORE
00297 int os_style = -1;
00298 #endif
00299 uint32_t namesz, descsz;
00300
00301 if (class == ELFCLASS32)
00302 memcpy(&nh32, &nbuf[offset], sizeof(nh32));
00303 else
00304 memcpy(&nh64, &nbuf[offset], sizeof(nh64));
00305 offset += nh_size;
00306
00307 namesz = nh_namesz;
00308 descsz = nh_descsz;
00309 if ((namesz == 0) && (descsz == 0)) {
00310
00311
00312
00313 return offset;
00314 }
00315
00316 if (namesz & 0x80000000) {
00317 (void)file_printf(ms, ", bad note name size 0x%lx",
00318 (unsigned long)namesz);
00319 return offset;
00320 }
00321
00322 if (descsz & 0x80000000) {
00323 (void)file_printf(ms, ", bad note description size 0x%lx",
00324 (unsigned long)descsz);
00325 return offset;
00326 }
00327
00328
00329 noff = offset;
00330 doff = ELF_ALIGN(offset + namesz);
00331
00332 if (offset + namesz > size) {
00333
00334
00335
00336 return doff;
00337 }
00338
00339 offset = ELF_ALIGN(doff + descsz);
00340 if (doff + descsz > size) {
00341 return offset;
00342 }
00343
00344 if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
00345 nh_type == NT_GNU_VERSION && descsz == 16) {
00346 uint32_t desc[4];
00347 (void)memcpy(desc, &nbuf[doff], sizeof(desc));
00348
00349 if (file_printf(ms, ", for GNU/") == -1)
00350 return size;
00351 switch (getu32(swap, desc[0])) {
00352 case GNU_OS_LINUX:
00353 if (file_printf(ms, "Linux") == -1)
00354 return size;
00355 break;
00356 case GNU_OS_HURD:
00357 if (file_printf(ms, "Hurd") == -1)
00358 return size;
00359 break;
00360 case GNU_OS_SOLARIS:
00361 if (file_printf(ms, "Solaris") == -1)
00362 return size;
00363 break;
00364 default:
00365 if (file_printf(ms, "<unknown>") == -1)
00366 return size;
00367 }
00368 if (file_printf(ms, " %d.%d.%d", getu32(swap, desc[1]),
00369 getu32(swap, desc[2]), getu32(swap, desc[3])) == -1)
00370 return size;
00371 return size;
00372 }
00373
00374 if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0 &&
00375 nh_type == NT_NETBSD_VERSION && descsz == 4) {
00376 uint32_t desc;
00377 (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
00378 desc = getu32(swap, desc);
00379
00380 if (file_printf(ms, ", for NetBSD") == -1)
00381 return size;
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 if (desc > 100000000U) {
00395 u_int ver_patch = (desc / 100) % 100;
00396 u_int ver_rel = (desc / 10000) % 100;
00397 u_int ver_min = (desc / 1000000) % 100;
00398 u_int ver_maj = desc / 100000000;
00399
00400 if (file_printf(ms, " %u.%u", ver_maj, ver_min) == -1)
00401 return size;
00402 if (ver_rel == 0 && ver_patch != 0) {
00403 if (file_printf(ms, ".%u", ver_patch) == -1)
00404 return size;
00405 } else if (ver_rel != 0) {
00406 while (ver_rel > 26) {
00407 file_printf(ms, "Z");
00408 ver_rel -= 26;
00409 }
00410 file_printf(ms, "%c", 'A' + ver_rel - 1);
00411 }
00412 }
00413 return size;
00414 }
00415
00416 if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0 &&
00417 nh_type == NT_FREEBSD_VERSION && descsz == 4) {
00418 uint32_t desc;
00419 (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
00420 desc = getu32(swap, desc);
00421 if (file_printf(ms, ", for FreeBSD") == -1)
00422 return size;
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 if (desc == 460002) {
00451 if (file_printf(ms, " 4.6.2") == -1)
00452 return size;
00453 } else if (desc < 460100) {
00454 if (file_printf(ms, " %d.%d", desc / 100000,
00455 desc / 10000 % 10) == -1)
00456 return size;
00457 if (desc / 1000 % 10 > 0)
00458 if (file_printf(ms, ".%d", desc / 1000 % 10)
00459 == -1)
00460 return size;
00461 if ((desc % 1000 > 0) || (desc % 100000 == 0))
00462 if (file_printf(ms, " (%d)", desc) == -1)
00463 return size;
00464 } else if (desc < 500000) {
00465 if (file_printf(ms, " %d.%d", desc / 100000,
00466 desc / 10000 % 10 + desc / 1000 % 10) == -1)
00467 return size;
00468 if (desc / 100 % 10 > 0) {
00469 if (file_printf(ms, " (%d)", desc) == -1)
00470 return size;
00471 } else if (desc / 10 % 10 > 0) {
00472 if (file_printf(ms, ".%d", desc / 10 % 10)
00473 == -1)
00474 return size;
00475 }
00476 } else {
00477 if (file_printf(ms, " %d.%d", desc / 100000,
00478 desc / 1000 % 100) == -1)
00479 return size;
00480 if ((desc / 100 % 10 > 0) ||
00481 (desc % 100000 / 100 == 0)) {
00482 if (file_printf(ms, " (%d)", desc) == -1)
00483 return size;
00484 } else if (desc / 10 % 10 > 0) {
00485 if (file_printf(ms, ".%d", desc / 10 % 10)
00486 == -1)
00487 return size;
00488 }
00489 }
00490 return size;
00491 }
00492
00493 if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
00494 nh_type == NT_OPENBSD_VERSION && descsz == 4) {
00495 if (file_printf(ms, ", for OpenBSD") == -1)
00496 return size;
00497
00498 return size;
00499 }
00500
00501 if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 &&
00502 nh_type == NT_DRAGONFLY_VERSION && descsz == 4) {
00503 uint32_t desc;
00504 if (file_printf(ms, ", for DragonFly") == -1)
00505 return size;
00506 (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
00507 desc = getu32(swap, desc);
00508 if (file_printf(ms, " %d.%d.%d", desc / 100000,
00509 desc / 10000 % 10, desc % 10000) == -1)
00510 return size;
00511 return size;
00512 }
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 if ((namesz == 4 && strncmp((char *)&nbuf[noff], "CORE", 4) == 0) ||
00529 (namesz == 5 && strcmp((char *)&nbuf[noff], "CORE") == 0)) {
00530 os_style = OS_STYLE_SVR4;
00531 }
00532
00533 if ((namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0)) {
00534 os_style = OS_STYLE_FREEBSD;
00535 }
00536
00537 if ((namesz >= 11 && strncmp((char *)&nbuf[noff], "NetBSD-CORE", 11)
00538 == 0)) {
00539 os_style = OS_STYLE_NETBSD;
00540 }
00541
00542 #ifdef ELFCORE
00543 if (os_style != -1)
00544 if (file_printf(ms, ", %s-style", os_style_names[os_style]) == -1)
00545 return size;
00546
00547 if (os_style == OS_STYLE_NETBSD && nh_type == NT_NETBSD_CORE_PROCINFO) {
00548 uint32_t signo;
00549
00550
00551
00552
00553
00554 if (file_printf(ms, ", from '%.31s'", &nbuf[doff + 0x7c]) == -1)
00555 return size;
00556
00557
00558
00559
00560
00561 memcpy(&signo, &nbuf[doff + 0x08],
00562 sizeof(signo));
00563 if (file_printf(ms, " (signal %u)", getu32(swap, signo)) == -1)
00564 return size;
00565 return size;
00566 } else if (os_style != OS_STYLE_NETBSD && nh_type == NT_PRPSINFO) {
00567 size_t i, j;
00568 unsigned char c;
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 for (i = 0; i < NOFFSETS; i++) {
00580 size_t reloffset = prpsoffsets(i);
00581 size_t noffset = doff + reloffset;
00582 for (j = 0; j < 16; j++, noffset++, reloffset++) {
00583
00584
00585
00586
00587
00588 if (noffset >= size)
00589 goto tryanother;
00590
00591
00592
00593
00594
00595
00596
00597 if (reloffset >= descsz)
00598 goto tryanother;
00599
00600 c = nbuf[noffset];
00601 if (c == '\0') {
00602
00603
00604
00605
00606
00607
00608
00609 if (j == 0)
00610 goto tryanother;
00611 else
00612 break;
00613 } else {
00614
00615
00616
00617
00618
00619 #define isquote(c) (strchr("'\"`", (c)) != NULL)
00620 if (!isprint(c) || isquote(c))
00621 goto tryanother;
00622 }
00623 }
00624
00625
00626
00627
00628 if (file_printf(ms, ", from '%.16s'",
00629 &nbuf[doff + prpsoffsets(i)]) == -1)
00630 return size;
00631 return size;
00632
00633 tryanother:
00634 ;
00635 }
00636 return offset;
00637 }
00638 #endif
00639 return offset;
00640 }
00641
00642 private int
00643 doshn(struct magic_set *ms, int class, int swap, int fd, off_t off, int num,
00644 size_t size)
00645 {
00646 Elf32_Shdr sh32;
00647 Elf64_Shdr sh64;
00648
00649 if (size != sh_size) {
00650 if (file_printf(ms, ", corrupted section header size") == -1)
00651 return -1;
00652 return 0;
00653 }
00654
00655 if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
00656 file_badseek(ms);
00657 return -1;
00658 }
00659
00660 for ( ; num; num--) {
00661 if (read(fd, sh_addr, sh_size) == -1) {
00662 file_badread(ms);
00663 return -1;
00664 }
00665 if (shs_type == SHT_SYMTAB ) {
00666 if (file_printf(ms, ", not stripped") == -1)
00667 return -1;
00668 return 0;
00669 }
00670 }
00671 if (file_printf(ms, ", stripped") == -1)
00672 return -1;
00673 return 0;
00674 }
00675
00676
00677
00678
00679
00680
00681 private int
00682 dophn_exec(struct magic_set *ms, int class, int swap, int fd, off_t off,
00683 int num, size_t size)
00684 {
00685 Elf32_Phdr ph32;
00686 Elf64_Phdr ph64;
00687 const char *linking_style = "statically";
00688 const char *shared_libraries = "";
00689 unsigned char nbuf[BUFSIZ];
00690 int bufsize;
00691 size_t offset, align;
00692 off_t savedoffset;
00693
00694 if (size != ph_size) {
00695 if (file_printf(ms, ", corrupted program header size") == -1)
00696 return -1;
00697 return 0;
00698 }
00699 if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
00700 file_badseek(ms);
00701 return -1;
00702 }
00703
00704 for ( ; num; num--) {
00705 if (read(fd, ph_addr, ph_size) == -1) {
00706 file_badread(ms);
00707 return -1;
00708 }
00709 if ((savedoffset = lseek(fd, (off_t)0, SEEK_CUR)) == (off_t)-1) {
00710 file_badseek(ms);
00711 return -1;
00712 }
00713
00714 switch (ph_type) {
00715 case PT_DYNAMIC:
00716 linking_style = "dynamically";
00717 break;
00718 case PT_INTERP:
00719 shared_libraries = " (uses shared libs)";
00720 break;
00721 case PT_NOTE:
00722 if ((align = ph_align) & 0x80000000) {
00723 if (file_printf(ms,
00724 ", invalid note alignment 0x%lx",
00725 (unsigned long)align) == -1)
00726 return -1;
00727 align = 4;
00728 }
00729
00730
00731
00732
00733 if (lseek(fd, (off_t) ph_offset, SEEK_SET)
00734 == (off_t)-1) {
00735 file_badseek(ms);
00736 return -1;
00737 }
00738 bufsize = read(fd, nbuf, ((ph_filesz < sizeof(nbuf)) ?
00739 ph_filesz : sizeof(nbuf)));
00740 if (bufsize == -1) {
00741 file_badread(ms);
00742 return -1;
00743 }
00744 offset = 0;
00745 for (;;) {
00746 if (offset >= (size_t)bufsize)
00747 break;
00748 offset = donote(ms, nbuf, offset,
00749 (size_t)bufsize, class, swap, align);
00750 if (offset == 0)
00751 break;
00752 }
00753 if (lseek(fd, savedoffset, SEEK_SET) == (off_t)-1) {
00754 file_badseek(ms);
00755 return -1;
00756 }
00757 break;
00758 }
00759 }
00760 if (file_printf(ms, ", %s linked%s", linking_style, shared_libraries)
00761 == -1)
00762 return -1;
00763 return 0;
00764 }
00765
00766
00767 protected int
00768 file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf,
00769 size_t nbytes)
00770 {
00771 union {
00772 int32_t l;
00773 char c[sizeof (int32_t)];
00774 } u;
00775 int class;
00776 int swap;
00777
00778
00779
00780
00781 if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
00782 fd = file_pipe2file(ms, fd, buf, nbytes);
00783
00784
00785
00786
00787
00788
00789
00790 if (buf[EI_MAG0] != ELFMAG0
00791 || (buf[EI_MAG1] != ELFMAG1 && buf[EI_MAG1] != OLFMAG1)
00792 || buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3)
00793 return 0;
00794
00795
00796 class = buf[4];
00797
00798 if (class == ELFCLASS32) {
00799 Elf32_Ehdr elfhdr;
00800 if (nbytes <= sizeof (Elf32_Ehdr))
00801 return 0;
00802
00803
00804 u.l = 1;
00805 (void) memcpy(&elfhdr, buf, sizeof elfhdr);
00806 swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[5];
00807
00808 if (getu16(swap, elfhdr.e_type) == ET_CORE) {
00809 #ifdef ELFCORE
00810 if (dophn_core(ms, class, swap, fd,
00811 (off_t)getu32(swap, elfhdr.e_phoff),
00812 getu16(swap, elfhdr.e_phnum),
00813 (size_t)getu16(swap, elfhdr.e_phentsize)) == -1)
00814 return -1;
00815 #else
00816 ;
00817 #endif
00818 } else {
00819 if (getu16(swap, elfhdr.e_type) == ET_EXEC) {
00820 if (dophn_exec(ms, class, swap,
00821 fd, (off_t)getu32(swap, elfhdr.e_phoff),
00822 getu16(swap, elfhdr.e_phnum),
00823 (size_t)getu16(swap, elfhdr.e_phentsize))
00824 == -1)
00825 return -1;
00826 }
00827 if (doshn(ms, class, swap, fd,
00828 (off_t)getu32(swap, elfhdr.e_shoff),
00829 getu16(swap, elfhdr.e_shnum),
00830 (size_t)getu16(swap, elfhdr.e_shentsize)) == -1)
00831 return -1;
00832 }
00833 return 1;
00834 }
00835
00836 if (class == ELFCLASS64) {
00837 Elf64_Ehdr elfhdr;
00838 if (nbytes <= sizeof (Elf64_Ehdr))
00839 return 0;
00840
00841
00842 u.l = 1;
00843 (void) memcpy(&elfhdr, buf, sizeof elfhdr);
00844 swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[5];
00845
00846 if (getu16(swap, elfhdr.e_type) == ET_CORE) {
00847 #ifdef ELFCORE
00848 if (dophn_core(ms, class, swap, fd,
00849 #ifdef USE_ARRAY_FOR_64BIT_TYPES
00850 (off_t)getu32(swap, elfhdr.e_phoff[1]),
00851 #else
00852 (off_t)getu64(swap, elfhdr.e_phoff),
00853 #endif
00854 getu16(swap, elfhdr.e_phnum),
00855 (size_t)getu16(swap, elfhdr.e_phentsize)) == -1)
00856 return -1;
00857 #else
00858 ;
00859 #endif
00860 } else {
00861 if (getu16(swap, elfhdr.e_type) == ET_EXEC) {
00862 if (dophn_exec(ms, class, swap, fd,
00863 #ifdef USE_ARRAY_FOR_64BIT_TYPES
00864 (off_t)getu32(swap, elfhdr.e_phoff[1]),
00865 #else
00866 (off_t)getu64(swap, elfhdr.e_phoff),
00867 #endif
00868 getu16(swap, elfhdr.e_phnum),
00869 (size_t)getu16(swap, elfhdr.e_phentsize))
00870 == -1)
00871 return -1;
00872 }
00873 if (doshn(ms, class, swap, fd,
00874 #ifdef USE_ARRAY_FOR_64BIT_TYPES
00875 (off_t)getu32(swap, elfhdr.e_shoff[1]),
00876 #else
00877 (off_t)getu64(swap, elfhdr.e_shoff),
00878 #endif
00879 getu16(swap, elfhdr.e_shnum),
00880 (size_t)getu16(swap, elfhdr.e_shentsize)) == -1)
00881 return -1;
00882 }
00883 return 1;
00884 }
00885 return 0;
00886 }
00887 #endif