summaryrefslogtreecommitdiffstats
path: root/usr.bin/file/readelf.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/file/readelf.c')
-rw-r--r--usr.bin/file/readelf.c59
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;
OpenPOWER on IntegriCloud