diff options
Diffstat (limited to 'contrib/file/readelf.c')
-rw-r--r-- | contrib/file/readelf.c | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/contrib/file/readelf.c b/contrib/file/readelf.c index dd9004b..3c7472b 100644 --- a/contrib/file/readelf.c +++ b/contrib/file/readelf.c @@ -37,7 +37,7 @@ #include "readelf.h" #ifndef lint -FILE_RCSID("@(#)$File: readelf.c,v 1.63 2007/01/16 14:56:45 ljt Exp $") +FILE_RCSID("@(#)$File: readelf.c,v 1.68 2007/12/27 16:13:26 christos Exp $") #endif #ifdef ELFCORE @@ -191,15 +191,15 @@ getu64(int swap, uint64_t value) #ifdef ELFCORE size_t prpsoffsets32[] = { 8, /* FreeBSD */ - 28, /* Linux 2.0.36 (short name) */ 44, /* Linux (path name) */ + 28, /* Linux 2.0.36 (short name) */ 84, /* SunOS 5.x */ }; size_t prpsoffsets64[] = { 16, /* FreeBSD, 64-bit */ - 40, /* Linux (tested on core from 2.4.x, short name) */ 56, /* Linux (path name) */ + 40, /* Linux (tested on core from 2.4.x, short name) */ 120, /* SunOS 5.x, 64-bit */ }; @@ -241,6 +241,7 @@ private const char *os_style_names[] = { #define FLAGS_DID_CORE 1 #define FLAGS_DID_NOTE 2 +#define FLAGS_DID_CORE_STYLE 4 private int dophn_core(struct magic_set *ms, int class, int swap, int fd, off_t off, @@ -587,10 +588,11 @@ core: if ((*flags & FLAGS_DID_CORE) != 0) return size; - if (os_style != -1) { + if (os_style != -1 && (*flags & FLAGS_DID_CORE_STYLE) == 0) { if (file_printf(ms, ", %s-style", os_style_names[os_style]) == -1) return size; + *flags |= FLAGS_DID_CORE_STYLE; } switch (os_style) { @@ -615,6 +617,7 @@ core: if (file_printf(ms, " (signal %u)", getu32(swap, signo)) == -1) return size; + *flags |= FLAGS_DID_CORE; return size; } break; @@ -629,11 +632,12 @@ core: * is in SunOS 5.x and Linux). * * Unfortunately, it's at a different offset - * in varous OSes, so try multiple offsets. + * in various OSes, so try multiple offsets. * If the characters aren't all printable, * reject it. */ for (i = 0; i < NOFFSETS; i++) { + unsigned char *cname, *cp; size_t reloffset = prpsoffsets(i); size_t noffset = doff + reloffset; for (j = 0; j < 16; j++, noffset++, @@ -681,9 +685,16 @@ core: /* * Well, that worked. */ - if (file_printf(ms, ", from '%.16s'", - &nbuf[doff + prpsoffsets(i)]) == -1) + cname = (unsigned char *) + &nbuf[doff + prpsoffsets(i)]; + for (cp = cname; *cp && isprint(*cp); cp++) + continue; + if (cp > cname) + cp--; + if (file_printf(ms, ", from '%.*s'", + (int)(cp - cname), cname) == -1) return size; + *flags |= FLAGS_DID_CORE; return size; tryanother: @@ -693,7 +704,6 @@ core: break; } #endif - *flags |= FLAGS_DID_CORE; return offset; } @@ -884,6 +894,8 @@ dophn_exec(struct magic_set *ms, int class, int swap, int fd, off_t off, return -1; } break; + default: + break; } } if (file_printf(ms, ", %s linked%s", linking_style, shared_libraries) @@ -935,6 +947,8 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf, if (class == ELFCLASS32) { Elf32_Ehdr elfhdr; + uint16_t type; + if (nbytes <= sizeof (Elf32_Ehdr)) return 0; @@ -943,33 +957,36 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf, (void) memcpy(&elfhdr, buf, sizeof elfhdr); swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA]; - if (getu16(swap, elfhdr.e_type) == ET_CORE) { + type = getu16(swap, elfhdr.e_type); + switch (type) { #ifdef ELFCORE + case ET_CORE: if (dophn_core(ms, class, swap, fd, (off_t)getu32(swap, elfhdr.e_phoff), getu16(swap, elfhdr.e_phnum), (size_t)getu16(swap, elfhdr.e_phentsize), fsize, &flags) == -1) return -1; -#else - ; + break; #endif - } else { - if (getu16(swap, elfhdr.e_type) == ET_EXEC) { - if (dophn_exec(ms, class, swap, - fd, (off_t)getu32(swap, elfhdr.e_phoff), - getu16(swap, elfhdr.e_phnum), - (size_t)getu16(swap, elfhdr.e_phentsize), - fsize, &flags) - == -1) - return -1; - } + case ET_EXEC: + case ET_DYN: + if (dophn_exec(ms, class, swap, + fd, (off_t)getu32(swap, elfhdr.e_phoff), + getu16(swap, elfhdr.e_phnum), + (size_t)getu16(swap, elfhdr.e_phentsize), + fsize, &flags) == -1) + return -1; if (doshn(ms, class, swap, fd, (off_t)getu32(swap, elfhdr.e_shoff), getu16(swap, elfhdr.e_shnum), (size_t)getu16(swap, elfhdr.e_shentsize), &flags) == -1) return -1; + break; + + default: + break; } return 1; } |