]> granicus.if.org Git - file/commitdiff
misc cleanups from NetBSD and addition of PT_NOTE field handling.
authorChristos Zoulas <christos@zoulas.com>
Thu, 16 May 2002 15:01:41 +0000 (15:01 +0000)
committerChristos Zoulas <christos@zoulas.com>
Thu, 16 May 2002 15:01:41 +0000 (15:01 +0000)
magic/Magdir/elf
src/names.h
src/readelf.c
src/readelf.h
src/softmagic.c

index 53a6bc96ef35faa4a367ef16909980e1a72a1480..70135e7f9d7970dc69ce83fc9585584c580f1943 100644 (file)
 # Core handling from Peter Tobias <tobias@server.et-inf.fho-emden.de>
 # corrections by Christian 'Dr. Disk' Hechelmann <drdisk@ds9.au.s.shuttle.de>
 >>16   leshort         4               core file
->>>(0x38+0xcc) string  >\0             of '%s'
->>>(0x38+0x10) lelong  >0              (signal %d),
+# Core file detection is not reliable.
+#>>>(0x38+0xcc) string >\0             of '%s'
+#>>>(0x38+0x10) lelong >0              (signal %d),
 >>16   leshort         &0xff00         processor-specific,
 >>18   leshort         0               no machine,
 >>18   leshort         1               AT&T WE32100 - invalid byte order,
 >>18   leshort         2               SPARC - invalid byte order,
 >>18   leshort         3               Intel 80386,
->>18   leshort         4               Motorola 68000 - invalid byte order,
+>>18   leshort         4               Motorola
+>>>36  lelong          &0x01000000     68000 - invalid byte order,
+>>>36  lelong          &0x00810000     CPU32 - invalid byte order,
+>>>36  lelong          0               68020 - invalid byte order,
 >>18   leshort         5               Motorola 88000 - invalid byte order,
 >>18   leshort         6               Intel 80486,
 >>18   leshort         7               Intel 80860,
 >>18   beshort         1               AT&T WE32100,
 >>18   beshort         2               SPARC,
 >>18   beshort         3               Intel 80386 - invalid byte order,
->>18   beshort         4               Motorola 68000,
+>>18   beshort         4               Motorola
+>>>36  belong          &0x01000000     68000,
+>>>36  belong          &0x00810000     CPU32,
+>>>36  belong          0               68020,
 >>18   beshort         5               Motorola 88000,
 >>18   beshort         6               Intel 80486 - invalid byte order,
 >>18   beshort         7               Intel 80860,
index 856632a9dc3ac1ea4ff6d9d111fa123c42cd5c90..ea4e85cc24dc51fbf4d0475a84039047164acb1d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Names.h - names and types used by ascmagic in file(1).
  * These tokens are here because they can appear anywhere in
- * the first HOWMANY bytes, while tokens in /etc/magic must
+ * the first HOWMANY bytes, while tokens in MAGIC must
  * appear at fixed offsets into the file. Don't make HOWMANY
  * too high unless you have a very fast CPU.
  *
@@ -10,7 +10,7 @@
  *
  * See LEGAL.NOTICE
  *
- * $Id: names.h,v 1.18 2000/08/05 17:36:49 christos Exp $
+ * $Id: names.h,v 1.19 2002/05/16 15:01:41 christos Exp $
  */
 
 /*
index ccce5992aa0ff0a1be6ef1518dfc42a6b77f4ddb..357c2eaab5154da090c0231b4770091ce88e8849 100644 (file)
@@ -14,7 +14,7 @@
 #include "readelf.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$Id: readelf.c,v 1.18 2001/10/20 17:44:53 christos Exp $")
+FILE_RCSID("@(#)$Id: readelf.c,v 1.19 2002/05/16 15:01:41 christos Exp $")
 #endif
 
 #ifdef ELFCORE
@@ -170,9 +170,14 @@ dophn_exec(class, swap, fd, off, num, size)
        size_t size;
 {
        Elf32_Phdr ph32;
+       Elf32_Nhdr *nh32;
        Elf64_Phdr ph64;
+       Elf64_Nhdr *nh64;
        char *linking_style = "statically";
        char *shared_libraries = "";
+       char nbuf[BUFSIZ];
+       int bufsize;
+       size_t offset, nameoffset;
 
        if (lseek(fd, off, SEEK_SET) == -1)
                error("lseek failed (%s).\n", strerror(errno));
@@ -188,6 +193,112 @@ dophn_exec(class, swap, fd, off, num, size)
                case PT_INTERP:
                        shared_libraries = " (uses shared libs)";
                        break;
+               case PT_NOTE:
+                       /*
+                        * This is a PT_NOTE section; loop through all the notes
+                        * in the section.
+                        */
+                       if (lseek(fd, (off_t) ph_offset, SEEK_SET) == -1)
+                               error("lseek failed (%s).\n", strerror(errno));
+                       bufsize = read(fd, nbuf, BUFSIZ);
+                       if (bufsize == -1)
+                               error(": " "read failed (%s).\n",
+                                   strerror(errno));
+                       offset = 0;
+                       for (;;) {
+                               if (offset >= bufsize)
+                                       break;
+                               if (class == ELFCLASS32)
+                                       nh32 = (Elf32_Nhdr *)&nbuf[offset];
+                               else
+                                       nh64 = (Elf64_Nhdr *)&nbuf[offset];
+                               offset += nh_size;
+       
+                               if (offset + nh_namesz >= bufsize) {
+                                       /*
+                                        * We're past the end of the buffer.
+                                        */
+                                       break;
+                               }
+
+                               nameoffset = offset;
+                               offset += nh_namesz;
+                               offset = ((offset + 3)/4)*4;
+
+                               if (offset + nh_descsz >= bufsize)
+                                       break;
+
+                               if (nh_namesz == 4 &&
+                                   strcmp(&nbuf[nameoffset], "GNU") == 0 &&
+                                   nh_type == NT_GNU_VERSION &&
+                                   nh_descsz == 16) {
+                                       uint32_t *desc =
+                                           (uint32_t *)&nbuf[offset];
+
+                                       printf(", for GNU/");
+                                       switch (getu32(swap, desc[0])) {
+                                       case GNU_OS_LINUX:
+                                               printf("Linux");
+                                               break;
+                                       case GNU_OS_HURD:
+                                               printf("Hurd");
+                                               break;
+                                       case GNU_OS_SOLARIS:
+                                               printf("Solaris");
+                                               break;
+                                       default:
+                                               printf("<unknown>");
+                                       }
+                                       printf(" %d.%d.%d",
+                                           getu32(swap, desc[1]),
+                                           getu32(swap, desc[2]),
+                                           getu32(swap, desc[3]));
+                               }
+
+                               if (nh_namesz == 7 &&
+                                   strcmp(&nbuf[nameoffset], "NetBSD") == 0 &&
+                                   nh_type == NT_NETBSD_VERSION &&
+                                   nh_descsz == 4) {
+                                       printf(", for NetBSD");
+                                       /*
+                                        * Version number is stuck at 199905,
+                                        * and hence is basically content-free.
+                                        */
+                               }
+
+                               if (nh_namesz == 8 &&
+                                   strcmp(&nbuf[nameoffset], "FreeBSD") == 0 &&
+                                   nh_type == NT_FREEBSD_VERSION &&
+                                   nh_descsz == 4) {
+                                       uint32_t desc = getu32(swap,
+                                           *(uint32_t *)&nbuf[offset]);
+                                       printf(", for FreeBSD");
+                                       /*
+                                        * Contents is __FreeBSD_version,
+                                        * whose relation to OS versions is
+                                        * defined by a huge table in the
+                                        * Porters' Handbook.  Happily, the
+                                        * first three digits are the version
+                                        * number, at least in versions of
+                                        * FreeBSD that use this note.
+                                        */
+
+                                       printf(" %d.%d", desc / 100000,
+                                           desc / 10000 % 10);
+                                       if (desc / 1000 % 10 > 0)
+                                               printf(".%d",
+                                                   desc / 1000 % 10);
+                               }
+
+                               if (nh_namesz == 8 &&
+                                   strcmp(&nbuf[nameoffset], "OpenBSD") == 0 &&
+                                   nh_type == NT_OPENBSD_VERSION &&
+                                   nh_descsz == 4) {
+                                       printf(", for OpenBSD");
+                                       /* Content of note is always 0 */
+                               }
+                       }
+                       break;
                }
        }
        printf(", %s linked%s", linking_style, shared_libraries);
@@ -230,6 +341,17 @@ size_t     prpsoffsets64[] = {
  * *do* have that binary, the debugger will probably tell you what
  * signal it was.)
  */
+
+#define        OS_STYLE_SVR4           0
+#define        OS_STYLE_FREEBSD        1
+#define        OS_STYLE_NETBSD         2
+
+static const char *os_style_names[] = {
+       "SVR4",
+       "FreeBSD",
+       "NetBSD",
+};
+
 static void
 dophn_core(class, swap, fd, off, num, size)
        int class;
@@ -248,7 +370,7 @@ dophn_core(class, swap, fd, off, num, size)
        int i, j;
        char nbuf[BUFSIZ];
        int bufsize;
-       int is_freebsd;
+       int os_style = -1;
 
        /*
         * Loop through all the program headers.
@@ -283,7 +405,7 @@ dophn_core(class, swap, fd, off, num, size)
 
                        /*
                         * Check whether this note has the name "CORE" or
-                        * "FreeBSD".
+                        * "FreeBSD", or "NetBSD-CORE".
                         */
                        if (offset + nh_namesz >= bufsize) {
                                /*
@@ -310,17 +432,50 @@ dophn_core(class, swap, fd, off, num, size)
                         * doesn't include the terminating null in the
                         * name....
                         */
-                       if ((nh_namesz == 4 &&
-                             strncmp(&nbuf[nameoffset], "CORE", 4) == 0) ||
-                           (nh_namesz == 5 &&
-                             strcmp(&nbuf[nameoffset], "CORE") == 0))
-                               is_freebsd = 0;
-                       else if ((nh_namesz == 8 &&
-                             strcmp(&nbuf[nameoffset], "FreeBSD") == 0))
-                               is_freebsd = 1;
-                       else
-                               continue;
-                       if (nh_type == NT_PRPSINFO) {
+                       if (os_style == -1) {
+                               if ((nh_namesz == 4 &&
+                                    strncmp(&nbuf[nameoffset],
+                                           "CORE", 4) == 0) ||
+                                   (nh_namesz == 5 &&
+                                    strcmp(&nbuf[nameoffset],
+                                           "CORE") == 0)) {
+                                       os_style = OS_STYLE_SVR4;
+                               } else
+                               if ((nh_namesz == 8 &&
+                                    strcmp(&nbuf[nameoffset],
+                                           "FreeBSD") == 0)) {
+                                       os_style = OS_STYLE_FREEBSD;
+                               } else
+                               if ((nh_namesz >= 11 &&
+                                    strncmp(&nbuf[nameoffset],
+                                            "NetBSD-CORE", 11) == 0)) {
+                                       os_style = OS_STYLE_NETBSD;
+                               } else
+                                       continue;
+                               printf(", %s-style", os_style_names[os_style]);
+                       }
+
+                       if (os_style == OS_STYLE_NETBSD &&
+                           nh_type == NT_NETBSD_CORE_PROCINFO) {
+                               uint32_t signo;
+
+                               /*
+                                * Extract the program name.  It is at
+                                * offset 0x7c, and is up to 32-bytes,
+                                * including the terminating NUL.
+                                */
+                               printf(", from '%.31s'", &nbuf[offset + 0x7c]);
+                               
+                               /*
+                                * Extract the signal number.  It is at
+                                * offset 0x08.
+                                */
+                               memcpy(&signo, &nbuf[offset + 0x08],
+                                   sizeof(signo));
+                               printf(" (signal %u)", getu32(swap, signo));
+                       } else
+                       if (os_style != OS_STYLE_NETBSD &&
+                           nh_type == NT_PRPSINFO) {
                                /*
                                 * Extract the program name.  We assume
                                 * it to be 16 characters (that's what it
index d0ae3337394bccb179ee68dd95f53386dc128869..21d64362de7f12f88e9718a0efe3f02a86dc8057 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * readelf.h 
- * @(#)$Id: readelf.h,v 1.7 1999/02/14 17:16:11 christos Exp $
+ * @(#)$Id: readelf.h,v 1.8 2002/05/16 15:01:41 christos Exp $
  *
  * Provide elf data structures for non-elf machines, allowing file
  * non-elf hosts to determine if an elf binary is stripped.
@@ -166,6 +166,8 @@ typedef struct {
 #define NT_PRPSINFO    3
 #define NT_TASKSTRUCT  4
 
+#define        NT_NETBSD_CORE_PROCINFO         1
+
 /* Note header in a PT_NOTE section */
 typedef struct elf_note {
     Elf32_Word n_namesz;       /* Name size */
@@ -186,4 +188,18 @@ typedef struct {
 #define        NT_PLATFORM     5
 #define        NT_AUXV         6
 
+/* Note types used in executables */
+/* NetBSD executables (name = "NetBSD") */
+#define NT_NETBSD_VERSION      1
+#define NT_NETBSD_EMULATION    2
+#define NT_FREEBSD_VERSION     1
+#define NT_OPENBSD_VERSION     1
+/* GNU executables (name = "GNU") */
+#define NT_GNU_VERSION         1
+
+/* GNU OS tags */
+#define GNU_OS_LINUX   0
+#define GNU_OS_HURD    1
+#define GNU_OS_SOLARIS 2
+
 #endif
index fc9161543225c0d0738be3cd8e828b6b876c57f2..904360e2d1586bd007731c2f22c28877ed6fb933 100644 (file)
@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$Id: softmagic.c,v 1.46 2001/07/23 00:02:32 christos Exp $")
+FILE_RCSID("@(#)$Id: softmagic.c,v 1.47 2002/05/16 15:01:41 christos Exp $")
 #endif /* lint */
 
 static int match       __P((struct magic *, uint32, unsigned char *, int));
@@ -50,7 +50,7 @@ extern int kflag;
 
 /*
  * softmagic - lookup one file in database 
- * (already read from /etc/magic by apprentice.c).
+ * (already read from MAGIC by apprentice.c).
  * Passed the name and FILE * of one file to be typed.
  */
 /*ARGSUSED1*/          /* nbytes passed for regularity, maybe need later */