diff options
Diffstat (limited to 'usr.bin/file/readelf.c')
-rw-r--r-- | usr.bin/file/readelf.c | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/usr.bin/file/readelf.c b/usr.bin/file/readelf.c index a007cca..5674402 100644 --- a/usr.bin/file/readelf.c +++ b/usr.bin/file/readelf.c @@ -1,16 +1,23 @@ +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + #ifdef BUILTIN_ELF -#include <sys/types.h> -#include <string.h> -#include <stdio.h> #include <ctype.h> -#include <stdlib.h> -#include <unistd.h> +#include <err.h> #include <errno.h> +#include <string.h> +#include <unistd.h> #include "readelf.h" #include "file.h" +static void doshn __P((int, off_t, int, size_t, char *)); +static void dophn_exec __P((int, off_t, int, size_t, char *)); +static void dophn_core __P((int, off_t, int, size_t, char *)); + static void doshn(fd, off, num, size, buf) int fd; @@ -30,11 +37,11 @@ doshn(fd, off, num, size, buf) Elf32_Shdr *sh = (Elf32_Shdr *) buf; if (lseek(fd, off, SEEK_SET) == -1) - error("lseek failed (%s).\n", strerror(errno)); + err(1, "lseek failed"); for ( ; num; num--) { if (read(fd, buf, size) == -1) - error("read failed (%s).\n", strerror(errno)); + err(1, "read failed"); if (sh->sh_type == SHT_SYMTAB) { (void) printf (", not stripped"); return; @@ -60,11 +67,11 @@ dophn_exec(fd, off, num, size, buf) Elf32_Phdr *ph = (Elf32_Phdr *) buf; if (lseek(fd, off, SEEK_SET) == -1) - error("lseek failed (%s).\n", strerror(errno)); + err(1, "lseek failed"); for ( ; num; num--) { if (read(fd, buf, size) == -1) - error("read failed (%s).\n", strerror(errno)); + err(1, "read failed"); if (ph->p_type == PT_INTERP) { /* * Has an interpreter - must be a dynamically-linked @@ -78,6 +85,7 @@ dophn_exec(fd, off, num, size, buf) } size_t prpsoffsets[] = { + 8, /* FreeBSD */ 100, /* SunOS 5.x */ 32, /* Linux */ }; @@ -86,14 +94,15 @@ size_t prpsoffsets[] = { /* * Look through the program headers of an executable image, searching - * for a PT_NOTE section of type NT_PRPSINFO, with a name "CORE"; if one - * is found, try looking in various places in its contents for a 16-character - * string containing only printable characters - if found, that string - * should be the name of the program that dropped core. - * Note: right after that 16-character string is, at least in SunOS 5.x - * (and possibly other SVR4-flavored systems) and Linux, a longer string - * (80 characters, in 5.x, probably other SVR4-flavored systems, and Linux) - * containing the start of the command line for that program. + * for a PT_NOTE section of type NT_PRPSINFO, with a name "CORE" or + * "FreeBSD"; if one is found, try looking in various places in its + * contents for a 16-character string containing only printable + * characters - if found, that string should be the name of the program + * that dropped core. Note: right after that 16-character string is, + * at least in SunOS 5.x (and possibly other SVR4-flavored systems) and + * Linux, a longer string (80 characters, in 5.x, probably other + * SVR4-flavored systems, and Linux) containing the start of the + * command line for that program. */ static void dophn_core(fd, off, num, size, buf) @@ -121,17 +130,17 @@ dophn_core(fd, off, num, size, buf) for ( ; num; num--) { if (lseek(fd, off, SEEK_SET) == -1) - error("lseek failed (%s).\n", strerror(errno)); + err(1, "lseek failed"); if (read(fd, buf, size) == -1) - error("read failed (%s).\n", strerror(errno)); + err(1, "read failed"); off += size; if (ph->p_type != PT_NOTE) continue; if (lseek(fd, ph->p_offset, SEEK_SET) == -1) - error("lseek failed (%s).\n", strerror(errno)); + err(1, "lseek failed"); bufsize = read(fd, nbuf, BUFSIZ); if (bufsize == -1) - error("read failed (%s).\n", strerror(errno)); + err(1, "read failed"); offset = 0; for (;;) { if (offset >= bufsize) @@ -152,7 +161,8 @@ dophn_core(fd, off, num, size, buf) } /* - * Make sure this note has the name "CORE". + * Make sure this note has the name "CORE" or + * "FreeBSD". */ if (offset + nh->n_namesz >= bufsize) { /* @@ -160,8 +170,9 @@ dophn_core(fd, off, num, size, buf) */ break; } - if (nh->n_namesz != 5 - || strcmp(&nbuf[offset], "CORE") != 0) + if (nbuf[offset + nh->n_namesz - 1] != '\0' || + (strcmp(&nbuf[offset], "CORE") != 0 && + strcmp(&nbuf[offset], "FreeBSD") != 0)) continue; offset += nh->n_namesz; offset = ((offset + 3)/4)*4; |