]> granicus.if.org Git - file/commitdiff
- add support for elf core files: find the program name under SVR4 [Ken Pizzini]
authorChristos Zoulas <christos@zoulas.com>
Wed, 15 Jan 1997 17:23:24 +0000 (17:23 +0000)
committerChristos Zoulas <christos@zoulas.com>
Wed, 15 Jan 1997 17:23:24 +0000 (17:23 +0000)
- print strings only up to the first carriage return [various]
- freebsd international ascii support [J Wunsch]
- magic fixes and additions [Guy Harris]
- 64 bit fixes [Larry Schwimmer]
- support for both utime and utimes, but don't restore file access times
  by default [various]
- \xXX only takes 2 hex digits, not 3.
- re-implement support for core files [Guy Harris]

13 files changed:
README
doc/file.man
src/Makefile
src/apprentice.c
src/ascmagic.c
src/file.c
src/file.h
src/is_tar.c
src/names.h
src/patchlevel.h
src/readelf.c
src/readelf.h
src/softmagic.c

diff --git a/README b/README
index 2ee8e6777a40dbc194bc319f7440ce032ba4c1be..f88f185f49c538e952b389037d1441d4855c663d 100644 (file)
--- a/README
+++ b/README
@@ -1,11 +1,9 @@
 ** README for file(1) Command **
-@(#) $Id: README,v 1.20 1993/09/23 21:47:01 christos Exp $
+@(#) $Id: README,v 1.21 1997/01/15 17:23:24 christos Exp $
 
 This is Release 3.x of Ian Darwin's (copyright but distributable)
-file(1) command.  Release 3.x is scheduled for inclusion in the
-4.4 BSD (Berkeley Software Distribution) of UNIX-like
-software, and is the standard "file" command for Linux, 386bsd,
-and other systems. (See "patchlevel.h" for the exact release number).
+file(1) command. This version is the standard "file" command for Linux,
+*BSD, and other systems. (See "patchlevel.h" for the exact release number).
 
 UNIX is a trademark of UNIX System Laboratories.
 
@@ -58,15 +56,29 @@ magic.4 - man page for the magic file, courtesy Guy Harris.
 file.c - main program
 file.h - header file
 fsmagic.c - first set of tests the program runs, based on filesystem info
-is_tar.c - knows about tarchives (courtesy John Gilmore).
+is_tar.c, tar.h - knows about tarchives (courtesy John Gilmore).
 magdir - directory of /etc/magic pieces
        magdir/Makefile - ADJUST THIS FOR YOUR CONFIGURATION
 names.h - header file for ascmagic.c
 softmagic.c - 2nd set of tests, based on /etc/magic
-strtok.c, getopt.c - in case you them (courtesy of Henry Spencer).
-strtol.c, strchr.c - in case you need them - public domain.
-tst - simple test suite, built from tst/Makefile
+readelf.[ch] - Standalone elf parsing code.
+compress.c - on-the-fly decompression.
+internat.c - recognize international `text' files.
+print.c - print results, errors, warnings.
 
+If your gzip sometimes fails to decompress things complaining about a short
+file, apply this patch [which is going to be in the next version of gzip]:
+*** -   Tue Oct 29 02:06:35 1996
+--- util.c      Sun Jul 21 21:51:38 1996
+*** 106,111 ****
+--- 108,114 ----
+  
+      if (insize == 0) {
+        if (eof_ok) return EOF;
++       flush_window();
+        read_error();
+      }
+      bytes_in += (ulg)insize;
 
 E-mail: christos@deshaw.com, moraes@deshaw.com
 
index 32a1c391bdb8ea3198a63a9a03d4859c0c9398d3..9c5cfb0fe3be9537808d727a02ed5b02f60a6db6 100644 (file)
@@ -1,5 +1,5 @@
 .TH FILE __CSECTION__ "Copyright but distributable"
-.\" $Id: file.man,v 1.27 1996/06/22 22:05:07 christos Exp $
+.\" $Id: file.man,v 1.28 1997/01/15 17:23:24 christos Exp $
 .SH NAME
 file
 \- determine file type
@@ -248,7 +248,7 @@ the process running
 .RE
 .PP
 Changes by Ian Darwin and various authors including
-Christos Zoulas (christos@ee.cornell.edu), 1990-1992.
+Christos Zoulas (christos@deshaw.com), 1990-1992.
 .SH LEGAL NOTICE
 Copyright (c) Ian F. Darwin, Toronto, Canada,
 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993.
@@ -360,6 +360,6 @@ This manual page, and particularly this section, is too long.
 .SH AVAILABILITY
 You can obtain the original author's latest version by anonymous FTP
 on
-.B tesla.ee.cornell.edu
+.B ftp.deshaw.com
 in the directory
-.I /pub/file-X.YY.tar.gz
+.I /pub/file/file-X.YY.tar.gz
index 40007c154573b9750e731cd40604b53bd5b88068..fde51c975a7f6bb8c8194ac9ea9de63da9866ed9 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for file(1) cmd. 
 # Copyright (c) Ian F. Darwin 86/09/01 - see LEGAL.NOTICE.
-# @(#)$Id: Makefile,v 1.54 1996/12/16 03:33:34 christos Exp $
+# @(#)$Id: Makefile,v 1.55 1997/01/15 17:23:24 christos Exp $
 #
 # This software is not subject to any license of the American Telephone
 # and Telegraph Company or of the Regents of the University of California.
@@ -21,7 +21,7 @@
 #    ever read sources, credits must appear in the documentation.
 #
 # 4. This notice may not be removed or altered.
-VERSION        = 3.21
+VERSION        = 3.22
 SHELL  = /bin/sh
 #MAGIC = /etc/magic
 MAGIC  = /usr/local/etc/magic
@@ -70,10 +70,10 @@ LOCALOBJS = # localsrc/getopt.o localsrc/strtol.o \
 LOCALINC = # localinc/*.h localinc/sys/*.h
 
 SRCS = file.c apprentice.c fsmagic.c softmagic.c ascmagic.c \
-       compress.c is_tar.c readelf.c international.c \
+       compress.c is_tar.c readelf.c internat.c \
        print.c $(LOCALSRCS) $(LOCALINC)
 OBJS = file.o apprentice.o fsmagic.o softmagic.o ascmagic.o \
-       compress.o is_tar.o readelf.o international.o \
+       compress.o is_tar.o readelf.o internat.o \
        print.o $(LOCALOBJS)
 
 ALLSRC = LEGAL.NOTICE README MAINT PORTING $(SRCS) *.h \
index 6bdfffef8ccc61af09d913736a6f0360521e15a1..7d8d9e2e8acd31b4e9d95b94c3403e23aefbdc63 100644 (file)
@@ -34,7 +34,7 @@
 
 #ifndef        lint
 static char *moduleid = 
-       "@(#)$Id: apprentice.c,v 1.24 1996/06/22 22:04:22 christos Exp $";
+       "@(#)$Id: apprentice.c,v 1.25 1997/01/15 17:23:24 christos Exp $";
 #endif /* lint */
 
 #define        EATAB {while (isascii((unsigned char) *l) && \
@@ -133,10 +133,10 @@ int check;                        /* non-zero? checking-only run. */
 /*
  * extend the sign bit if the comparison is to be signed
  */
-unsigned long
+uint32
 signextend(m, v)
 struct magic *m;
-unsigned long v;
+uint32 v;
 {
        if (!(m->flag & UNSIGNED))
                switch(m->type) {
@@ -159,7 +159,7 @@ unsigned long v;
                case LONG:
                case BELONG:
                case LELONG:
-                       v = (long) v;
+                       v = (int32) v;
                        break;
                case STRING:
                        break;
@@ -495,21 +495,16 @@ int       plen, *slen;
                                *p++ = (char)val;
                                break;
 
-                       /* \x and up to 3 hex digits */
+                       /* \x and up to 2 hex digits */
                        case 'x':
                                val = 'x';      /* Default if no digits */
                                c = hextoint(*s++);     /* Get next char */
                                if (c >= 0) {
                                        val = c;
                                        c = hextoint(*s++);
-                                       if (c >= 0) {
+                                       if (c >= 0)
                                                val = (val << 4) + c;
-                                               c = hextoint(*s++);
-                                               if (c >= 0) {
-                                                       val = (val << 4) + c;
-                                               } else
-                                                       --s;
-                                       } else
+                                       else
                                                --s;
                                } else
                                        --s;
index 600d468b7da706cf32d2f66a20ef812e9d5820bc..7ba9ae1c98919f6bd0dfe1a7851a3e7a70527fa2 100644 (file)
@@ -36,7 +36,7 @@
 
 #ifndef        lint
 static char *moduleid = 
-       "@(#)$Id: ascmagic.c,v 1.20 1995/05/20 22:09:21 christos Exp $";
+       "@(#)$Id: ascmagic.c,v 1.21 1997/01/15 17:23:24 christos Exp $";
 #endif /* lint */
 
                        /* an optimisation over plain strcmp() */
@@ -88,6 +88,13 @@ int nbytes;  /* size actually read */
                return 1;
        }
 
+
+       /* Make sure we are dealing with ascii text before looking for tokens */
+       for (i = 0; i < nbytes; i++) {
+               if (!isascii(buf[i]))
+                       return 0;       /* not all ASCII */
+       }
+
        /* look for tokens from names.h - this is expensive! */
        /* make a copy of the buffer here because strtok() will destroy it */
        s = (unsigned char*) memcpy(nbuf, buf, nbytes);
@@ -106,12 +113,6 @@ int nbytes;        /* size actually read */
                }
        }
 
-
-       for (i = 0; i < nbytes; i++) {
-               if (!isascii(buf[i]))
-                       return 0;       /* not all ASCII */
-       }
-
        /* all else fails, but it is ASCII... */
        ckfputs("ASCII text", stdout);
        if (has_escapes) {
index 3b6b1ca94d48c9cde8127fe9b8fa385f1c64fe32..22a3c442372caafba13f37f92004e10d50c90866 100644 (file)
@@ -26,7 +26,7 @@
  */
 #ifndef        lint
 static char *moduleid = 
-       "@(#)$Id: file.c,v 1.36 1996/10/05 18:13:57 christos Exp $";
+       "@(#)$Id: file.c,v 1.37 1997/01/15 17:23:24 christos Exp $";
 #endif /* lint */
 
 #include <stdio.h>
@@ -37,9 +37,13 @@ static char *moduleid =
 #include <sys/stat.h>
 #include <fcntl.h>     /* for open() */
 #if (__COHERENT__ >= 0x420)
-#include <sys/utime.h>
+# include <sys/utime.h>
 #else
-#include <utime.h>
+# ifdef USE_UTIMES
+#  include <sys/time.h>
+# else
+#  include <utime.h>
+# endif
 #endif
 #include <unistd.h>    /* for read() */
 
@@ -281,7 +285,6 @@ int wid;
        int     fd = 0;
        static  const char stdname[] = "standard input";
        unsigned char   buf[HOWMANY+1]; /* one extra for terminating '\0' */
-       struct utimbuf  utbuf;
        struct stat     sb;
        int nbytes = 0; /* number of bytes read from a datafile */
        char match = '\0';
@@ -340,12 +343,24 @@ int wid;
 #endif
 
        if (inname != stdname) {
+#ifdef RESTORE_TIME
                /*
                 * Try to restore access, modification times if read it.
                 */
+# ifdef USE_UTIMES
+               struct timeval  utsbuf[2];
+               utsbuf[0].tv_sec = sb.st_atime;
+               utsbuf[1].tv_sec = sb.st_mtime;
+
+               (void) utimes(inname, utsbuf); /* don't care if loses */
+# else
+               struct utimbuf  utbuf;
+
                utbuf.actime = sb.st_atime;
                utbuf.modtime = sb.st_mtime;
                (void) utime(inname, &utbuf); /* don't care if loses */
+# endif
+#endif
                (void) close(fd);
        }
        (void) putchar('\n');
@@ -369,6 +384,10 @@ int nb, zflag;
        if (ascmagic(buf, nb))
                return 'a';
 
+       /* see if it's international language text */
+       if (internatmagic(buf, nb))
+               return 'i';
+
        /* abandon hope, all ye who remain here */
        ckfputs("data", stdout);
                return '\0';
index 3c4363cc03e6b148d8e380e8ac569440b3b55f49..513ffd66d58a8a3cef6bac4501f34e0915b4f08b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * file.h - definitions for file(1) program
- * @(#)$Id: file.h,v 1.23 1996/06/22 22:04:22 christos Exp $
+ * @(#)$Id: file.h,v 1.24 1997/01/15 17:23:24 christos Exp $
  *
  * Copyright (c) Ian F. Darwin, 1987.
  * Written by Ian F. Darwin.
  * 4. This notice may not be removed or altered.
  */
 
+#ifndef __file_h__
+#define __file_h__
+
+typedef int int32;
+typedef unsigned int uint32;
+
 #ifndef HOWMANY
 # define HOWMANY 8192          /* how much of the file to look at */
 #endif
@@ -41,9 +47,9 @@ struct magic {
        short cont_level;       /* level of ">" */
        struct {
                char type;      /* byte short long */
-               long offset;    /* offset from indirection */
+               int32 offset;   /* offset from indirection */
        } in;
-       long offset;            /* offset to magic number */
+       int32 offset;           /* offset to magic number */
        unsigned char reln;     /* relation (0=eq, '>'=gt, etc) */
        char type;              /* int, short, long or string. */
        char vallen;            /* length of string value, if any */
@@ -61,12 +67,12 @@ struct magic {
        union VALUETYPE {
                unsigned char b;
                unsigned short h;
-               unsigned long l;
+               uint32 l;
                char s[MAXstring];
                unsigned char hs[2];    /* 2 bytes of a fixed-endian "short" */
                unsigned char hl[4];    /* 2 bytes of a fixed-endian "long" */
        } value;                /* either number or string */
-       unsigned long mask;     /* mask before comparison with value */
+       uint32 mask;    /* mask before comparison with value */
        char nospflag;          /* supress space character */
        char desc[MAXDESC];     /* description */
 };
@@ -98,7 +104,7 @@ extern int   softmagic               __P((unsigned char *, int));
 extern int   tryit             __P((unsigned char *, int, int));
 extern int   zmagic            __P((unsigned char *, int));
 extern void  ckfprintf         __P((FILE *, const char *, ...));
-extern unsigned long signextend        __P((struct magic *, unsigned long));
+extern uint32 signextend       __P((struct magic *, unsigned int32));
 
 
 
@@ -119,7 +125,16 @@ extern int lflag;          /* follow symbolic links?               */
 extern int optind;             /* From getopt(3)                       */
 extern char *optarg;
 
-#if !defined(__STDC__) || defined(sun) || defined(__sun__) || defined(__convex__)
+#if defined(sun) || defined(__sun__) || defined (__sun)
+# if defined(__svr4) || defined (__SVR4) || defined(__svr4__)
+#  define SOLARIS
+# else
+#  define SUNOS
+# endif
+#endif
+
+
+#if !defined(__STDC__) || defined(SUNOS) || defined(__convex__)
 extern int sys_nerr;
 extern char *sys_errlist[];
 #define strerror(e) \
@@ -130,3 +145,5 @@ extern char *sys_errlist[];
 #ifndef MAXPATHLEN
 #define        MAXPATHLEN      512
 #endif
+
+#endif /* __file_h__ */
index 5b036be1af8d088545737143acd01f04dbc7fd8c..865410417539a17213651864fa03543787a50243 100644 (file)
@@ -5,7 +5,7 @@
  * Pubic Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu).
  *
  * @(#)list.c 1.18 9/23/86 Public Domain - gnu
- * $Id: is_tar.c,v 1.8 1993/09/16 21:09:35 christos Exp $
+ * $Id: is_tar.c,v 1.9 1997/01/15 17:23:24 christos Exp $
  *
  * Comments changed and some code/comments reformatted
  * for file command by Ian Darwin.
@@ -19,9 +19,9 @@
 #define        isodigit(c)     ( ((c) >= '0') && ((c) <= '7') )
 
 #if    defined(__STDC__) || defined(__cplusplus)
-static long from_oct(int, char*);      /* Decode octal number */
+static int from_oct(int, char*);       /* Decode octal number */
 #else
-static long from_oct();
+static int from_oct();
 #endif
 
 /*
@@ -37,7 +37,7 @@ int nbytes;
 {
        register union record *header = (union record *)buf;
        register int    i;
-       register long   sum, recsum;
+       register int    sum, recsum;
        register char   *p;
 
        if (nbytes < sizeof(union record))
@@ -75,12 +75,12 @@ int nbytes;
  *
  * Result is -1 if the field is invalid (all blank, or nonoctal).
  */
-static long
+static int
 from_oct(digs, where)
        register int    digs;
        register char   *where;
 {
-       register long   value;
+       register int    value;
 
        while (isspace(*where)) {               /* Skip spaces */
                where++;
index 86633dd0d07589670123d2d094fb818bc210d360..54d1cbb125135a54f1ecfaee725eaebea4d8d364 100644 (file)
  *
  * See LEGAL.NOTICE
  *
- * $Id: names.h,v 1.12 1995/04/28 17:29:13 christos Exp $
+ * $Id: names.h,v 1.13 1997/01/15 17:23:24 christos Exp $
  */
 
 /* these types are used to index the table 'types': keep em in sync! */
 #define L_C    0               /* first and foremost on UNIX */
-#define        L_FORT  1               /* the oldest one */
-#define L_MAKE 2               /* Makefiles */
-#define L_PLI  3               /* PL/1 */
-#define L_MACH 4               /* some kinda assembler */
-#define L_ENG  5               /* English */
-#define        L_PAS   6               /* Pascal */
-#define        L_MAIL  7               /* Electronic mail */
-#define        L_NEWS  8               /* Usenet Netnews */
+#define L_CC   1               /* Bjarne's postincrement */
+#define        L_FORT  2               /* the oldest one */
+#define L_MAKE 3               /* Makefiles */
+#define L_PLI  4               /* PL/1 */
+#define L_MACH 5               /* some kinda assembler */
+#define L_ENG  6               /* English */
+#define        L_PAS   7               /* Pascal */
+#define        L_MAIL  8               /* Electronic mail */
+#define        L_NEWS  9               /* Usenet Netnews */
 
 static char *types[] = {
        "C program text",
+       "C++ program text",
        "FORTRAN program text",
        "make commands text" ,
        "PL/1 program text",
@@ -43,6 +45,12 @@ static struct names {
 } names[] = {
        /* These must be sorted by eye for optimal hit rate */
        /* Add to this list only after substantial meditation */
+       {"//",          L_CC},
+       {"template",    L_CC},
+       {"virtual",     L_CC},
+       {"class",       L_CC},
+       {"public:",     L_CC},
+       {"private:",    L_CC},
        {"/*",          L_C},   /* must precede "The", "the", etc. */
        {"#include",    L_C},
        {"char",        L_C},
index 10708c5cb1bd92179bb2df9a88c508f131272206..387ac2ca029a47ea1614186f82eeb2b8c0e04c64 100644 (file)
@@ -1,11 +1,22 @@
 #define        FILE_VERSION_MAJOR      3
-#define        patchlevel              21
+#define        patchlevel              22
 
 /*
  * Patchlevel file for Ian Darwin's MAGIC command.
- * $Id: patchlevel.h,v 1.21 1996/10/05 18:15:29 christos Exp $
+ * $Id: patchlevel.h,v 1.22 1997/01/15 17:23:24 christos Exp $
  *
  * $Log: patchlevel.h,v $
+ * Revision 1.22  1997/01/15 17:23:24  christos
+ * - add support for elf core files: find the program name under SVR4 [Ken Pizzini]
+ * - print strings only up to the first carriage return [various]
+ * - freebsd international ascii support [J Wunsch]
+ * - magic fixes and additions [Guy Harris]
+ * - 64 bit fixes [Larry Schwimmer]
+ * - support for both utime and utimes, but don't restore file access times
+ *   by default [various]
+ * - \xXX only takes 2 hex digits, not 3.
+ * - re-implement support for core files [Guy Harris]
+ *
  * Revision 1.21  1996/10/05 18:15:29  christos
  * Segregate elf stuff and conditionally enable it with -DBUILTIN_ELF
  * More magic fixes
index dc4a3ac01e1bb7fd699748984e1ae93378589414..6f6f3b40f42886c522118d61e7d43f37b70c2146 100644 (file)
@@ -1,13 +1,11 @@
 
 #ifdef BUILTIN_ELF
+#include <sys/types.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
-#ifdef __SVR4
-#include <sys/procfs.h>
-#endif
 
 #include "readelf.h"
 #include "file.h"
@@ -20,7 +18,14 @@ doshn(fd, off, num, size, buf)
        size_t size;
        char *buf;
 {
-       /* This works for both 32 and 64 bit elf formats */
+       /*
+        * This works for both 32-bit and 64-bit ELF formats,
+        * because it looks only at the "sh_type" field, which is
+        * always 32 bits, and is preceded only by the "sh_name"
+        * field which is also always 32 bits, and because it uses
+        * the shdr size from the ELF header rather than using
+        * the size of an "Elf32_Shdr".
+        */
        Elf32_Shdr *sh = (Elf32_Shdr *) buf;
 
        if (lseek(fd, off, SEEK_SET) == -1)
@@ -29,17 +34,21 @@ doshn(fd, off, num, size, buf)
        for ( ; num; num--) {
                if (read(fd, buf, size) == -1)
                        error("read failed (%s).\n", strerror(errno));
-               if (sh->sh_type == SHT_SYMTAB)
+               if (sh->sh_type == SHT_SYMTAB) {
+                       (void) printf (", not stripped");
                        return;
+               }
        }
        (void) printf (", stripped");
 }
 
 /*
- * From: Ken Pizzini <ken@spry.com>
+ * Look through the program headers of an executable image, searching
+ * for a PT_INTERP section; if one is found, it's dynamically linked,
+ * otherwise it's statically linked.
  */
 static void
-dophn(fd, off, num, size, buf)
+dophn_exec(fd, off, num, size, buf)
        int fd;
        off_t off;
        int num;
@@ -47,48 +56,168 @@ dophn(fd, off, num, size, buf)
        char *buf;
 {
        /* I am not sure if this works for 64 bit elf formats */
-       Elf32_Phdr ph;
-       Elf32_Nhdr nh;
-       off_t off_sv;
-       off_t fname_off;
+       Elf32_Phdr *ph = (Elf32_Phdr *) buf;
 
        if (lseek(fd, off, SEEK_SET) == -1)
                error("lseek failed (%s).\n", strerror(errno));
 
+       for ( ; num; num--) {
+               if (read(fd, buf, size) == -1)
+                       error("read failed (%s).\n", strerror(errno));
+               if (ph->p_type == PT_INTERP) {
+                       /*
+                        * Has an interpreter - must be a dynamically-linked
+                        * executable.
+                        */
+                       printf(", dynamically linked");
+                       return;
+               }
+       }
+       printf(", statically linked");
+}
+
+size_t prpsoffsets[] = {
+       100,            /* SunOS 5.x */
+       32,             /* Linux */
+};
+
+#define        NOFFSETS        (sizeof prpsoffsets / sizeof prpsoffsets[0])
+
+/*
+ * 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.
+ */
+static void
+dophn_core(fd, off, num, size, buf)
+       int fd;
+       off_t off;
+       int num;
+       size_t size;
+       char *buf;
+{
+       /*
+        * This doesn't work for 64-bit ELF, as the "p_offset" field is
+        * 64 bits in 64-bit ELF.
+        */
+       /*
+        * This doesn't work for 64-bit ELF, as the "p_offset" field is
+        * 64 bits in 64-bit ELF.
+        */
+       Elf32_Phdr *ph = (Elf32_Phdr *) buf;
+       Elf32_Nhdr *nh;
+       size_t offset, noffset, reloffset;
+       unsigned char c;
+       int i, j;
+       char nbuf[BUFSIZ];
+       int bufsize;
+
        for ( ; num; num--) {
-               if (read(fd, &ph, sizeof ph) != sizeof ph)
+               if (lseek(fd, off, SEEK_SET) == -1)
+                       error("lseek failed (%s).\n", strerror(errno));
+               if (read(fd, buf, size) == -1)
                        error("read failed (%s).\n", strerror(errno));
-               if (ph.p_type != PT_NOTE)
+               off += size;
+               if (ph->p_type != PT_NOTE)
                        continue;
-               off_sv = lseek(fd, ph.p_offset, SEEK_SET);
-               if (off_sv == -1)
+               if (lseek(fd, ph->p_offset, SEEK_SET) == -1)
                        error("lseek failed (%s).\n", strerror(errno));
-               if (read(fd, &nh, sizeof nh) != sizeof nh)
+               bufsize = read(fd, nbuf, BUFSIZ);
+               if (bufsize == -1)
                        error("read failed (%s).\n", strerror(errno));
-               if (nh.n_type != NT_PRPSINFO) {
-                       if (lseek(fd, off_sv, SEEK_SET) == -1)
-                               error("lseek failed (%s).\n", strerror(errno));
-                       continue;
-               }
+               offset = 0;
+               for (;;) {
+                       if (offset >= bufsize)
+                               break;
+                       nh = (Elf32_Nhdr *)&nbuf[offset];
+                       offset += sizeof *nh;
 
-#ifdef __SVR4
+                       /*
+                        * If this note isn't an NT_PRPSINFO note, it's
+                        * not what we're looking for.
+                        */
+                       if (nh->n_type != NT_PRPSINFO) {
+                               offset += nh->n_namesz;
+                               offset = ((offset + 3)/4)*4;
+                               offset += nh->n_descsz;
+                               offset = ((offset + 3)/4)*4;
+                               continue;
+                       }
 
-#define ALIGN(n)       (((n)+3) & ~3)  /* round up to nearest multiple of 4 */
-#define offsetof(a, b) (int) &((a *) 0)->b
+                       /*
+                        * Make sure this note has the name "CORE".
+                        */
+                       if (offset + nh->n_namesz >= bufsize) {
+                               /*
+                                * We're past the end of the buffer.
+                                */
+                               break;
+                       }
+                       if (nh->n_namesz != 5
+                           || strcmp(&nbuf[offset], "CORE") != 0)
+                               continue;
+                       offset += nh->n_namesz;
+                       offset = ((offset + 3)/4)*4;
 
-               fname_off = offsetof(struct prpsinfo, pr_fname) +
-                       ALIGN(nh.n_namesz);
-               if (lseek(fd, fname_off, SEEK_CUR) == -1)
-                       error("lseek failed (%s).\n", strerror(errno));
-               if (read(fd, buf, size) == -1)
-                       error("read failed (%s).\n", strerror(errno));
-               (void) printf ("; from `%s'", buf);
-#endif
-               return;
+                       /*
+                        * Extract the program name.  We assume it to be
+                        * 16 characters (that's what it is in SunOS 5.x
+                        * and Linux).
+                        *
+                        * Unfortunately, it's at a different offset in
+                        * SunOS 5.x and Linux, so try multiple offsets.
+                        * If the characters aren't all printable, reject
+                        * it.
+                        */
+                       for (i = 0; i < NOFFSETS; i++) {
+                               reloffset = prpsoffsets[i];
+                               noffset = offset + reloffset;
+                               for (j = 0; j < 16;
+                                   j++, noffset++, reloffset++) {
+                                       /*
+                                        * Make sure we're not past the end
+                                        * of the buffer; if we are, just
+                                        * give up.
+                                        */
+                                       if (noffset >= bufsize)
+                                               return;
+
+                                       /*
+                                        * Make sure we're not past the
+                                        * end of the contents; if we
+                                        * are, this obviously isn't
+                                        * the right offset.
+                                        */
+                                       if (reloffset >= nh->n_descsz)
+                                               goto tryanother;
+
+                                       c = nbuf[noffset];
+                                       if (c != '\0' && !isprint(c))
+                                               goto tryanother;
+                               }
+
+                               /*
+                                * Well, that worked.
+                                */
+                               printf(", from '%.16s'",
+                                   &nbuf[offset + prpsoffsets[i]]);
+                               return;
+
+                       tryanother:
+                               ;
+                       }
+                       offset += nh->n_descsz;
+                       offset = ((offset + 3)/4)*4;
+               }
        }
 }
 
-
 void
 tryelf(fd, buf, nbytes)
        int fd;
@@ -96,8 +225,8 @@ tryelf(fd, buf, nbytes)
        int nbytes;
 {
        union {
-               long l;
-               char c[sizeof (long)];
+               int32 l;
+               char c[sizeof (int32)];
        } u;
 
        /*
@@ -119,21 +248,27 @@ tryelf(fd, buf, nbytes)
 
                u.l = 1;
                (void) memcpy(&elfhdr, buf, sizeof elfhdr);
-
-               if (elfhdr.e_type == ET_CORE) 
-                       dophn(fd, elfhdr.e_phoff, elfhdr.e_phnum, 
-                             elfhdr.e_phentsize, buf);
-               else 
-               {
-                       /*
-                        * If the system byteorder does not equal the
-                        * object byteorder then don't test.
-                        */
-                       if ((u.c[sizeof(long) - 1] + 1) == elfhdr.e_ident[5])
+               /*
+                * If the system byteorder does not equal the
+                * object byteorder then don't test.
+                * XXX - we could conceivably fix up the "dophn_XXX()" and
+                * "doshn()" routines to extract stuff in the right
+                * byte order....
+                */
+               if ((u.c[sizeof(long) - 1] + 1) == elfhdr.e_ident[5]) {
+                       if (elfhdr.e_type == ET_CORE) 
+                               dophn_core(fd, elfhdr.e_phoff, elfhdr.e_phnum, 
+                                     elfhdr.e_phentsize, buf);
+                       else {
+                               if (elfhdr.e_type == ET_EXEC) {
+                                       dophn_exec(fd, elfhdr.e_phoff,
+                                           elfhdr.e_phnum, 
+                                             elfhdr.e_phentsize, buf);
+                               }
                                doshn(fd, elfhdr.e_shoff, elfhdr.e_shnum,
                                      elfhdr.e_shentsize, buf);
+                       }
                }
-
                return;
        }
 
@@ -146,20 +281,32 @@ tryelf(fd, buf, nbytes)
                u.l = 1;
                (void) memcpy(&elfhdr, buf, sizeof elfhdr);
 
-               if (elfhdr.e_type == ET_CORE) 
-                       dophn(fd, elfhdr.e_phoff, elfhdr.e_phnum, 
-                             elfhdr.e_phentsize, buf);
-               else
-               {
-                       /*
-                        * If the system byteorder does not equal the
-                        * object byteorder then don't test.
-                        */
-                       if ((u.c[sizeof(long) - 1] + 1) == elfhdr.e_ident[5])
+               /*
+                * If the system byteorder does not equal the
+                * object byteorder then don't test.
+                * XXX - we could conceivably fix up the "dophn_XXX()" and
+                * "doshn()" routines to extract stuff in the right
+                * byte order....
+                */
+               if ((u.c[sizeof(long) - 1] + 1) == elfhdr.e_ident[5]) {
+#ifdef notyet
+                       if (elfhdr.e_type == ET_CORE) 
+                               dophn_core(fd, elfhdr.e_phoff, elfhdr.e_phnum, 
+                                     elfhdr.e_phentsize, buf);
+                       else
+#endif
+                       {
+#ifdef notyet
+                               if (elfhdr.e_type == ET_EXEC) {
+                                       dophn_exec(fd, elfhdr.e_phoff,
+                                           elfhdr.e_phnum, 
+                                             elfhdr.e_phentsize, buf);
+                               }
+#endif
                                doshn(fd, elfhdr.e_shoff, elfhdr.e_shnum,
                                      elfhdr.e_shentsize, buf);
+                       }
                }
-
                return;
        }
 }
index 15fb8573a152a853a34bdc04d2c639f5817b7d22..c4b42d7eb13fc1fa4d0ec3f9759b75e1ff33e6d7 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * readelf.h 
- * @(#)$Id: readelf.h,v 1.3 1996/10/25 18:11:51 christos Exp $
+ * @(#)$Id: readelf.h,v 1.4 1997/01/15 17:23:24 christos Exp $
  *
  * Provide elf data structures for non-elf machines, allowing file
  * non-elf hosts to determine if an elf binary is stripped.
@@ -59,6 +59,7 @@ typedef struct {
 } Elf64_Ehdr;
 
 /* e_type */
+#define ET_EXEC                2
 #define ET_CORE                4
 
 /* sh_type */
@@ -137,11 +138,17 @@ typedef struct {
     Elf64_Off  sh_entsize;
 } Elf64_Shdr;
 
-
-typedef struct {
-    Elf32_Word n_namesz;
-    Elf32_Word n_descsz;
-    Elf32_Word n_type;
+/* Notes used in ET_CORE */
+#define NT_PRSTATUS    1
+#define NT_PRFPREG     2
+#define NT_PRPSINFO    3
+#define NT_TASKSTRUCT  4
+
+/* Note header in a PT_NOTE section */
+typedef struct elf_note {
+  Elf32_Word   n_namesz;       /* Name size */
+  Elf32_Word   n_descsz;       /* Content size */
+  Elf32_Word   n_type;         /* Content type */
 } Elf32_Nhdr;
 
 typedef struct {
index d3eac07b54428f019669510e3efe948f078c49de..e79a17307d588045b65a63275d7aed382686f07e 100644 (file)
 
 #ifndef        lint
 static char *moduleid = 
-       "@(#)$Id: softmagic.c,v 1.32 1996/10/25 19:50:35 christos Exp $";
+       "@(#)$Id: softmagic.c,v 1.33 1997/01/15 17:23:24 christos Exp $";
 #endif /* lint */
 
 static int match       __P((unsigned char *, int));
 static int mget                __P((union VALUETYPE *,
                             unsigned char *, struct magic *, int));
 static int mcheck      __P((union VALUETYPE *, struct magic *));
-static long mprint     __P((union VALUETYPE *, struct magic *));
-static void mdebug     __P((long, char *, int));
+static int32 mprint    __P((union VALUETYPE *, struct magic *));
+static void mdebug     __P((int32, char *, int));
 static int mconvert    __P((union VALUETYPE *, struct magic *));
 
 /*
@@ -99,12 +99,12 @@ int nbytes;
        int cont_level = 0;
        int need_separator = 0;
        union VALUETYPE p;
-       static long *tmpoff = NULL;
+       static int32 *tmpoff = NULL;
        static size_t tmplen = 0;
-       long oldoff = 0;
+       int32 oldoff = 0;
 
        if (tmpoff == NULL)
-               if ((tmpoff = (long *) malloc(tmplen = 20)) == NULL)
+               if ((tmpoff = (int32 *) malloc(tmplen = 20)) == NULL)
                        error("out of memory\n");
 
        for (magindex = 0; magindex < nmagic; magindex++) {
@@ -130,7 +130,7 @@ int nbytes;
                        need_separator = 1;
                /* and any continuations that match */
                if (++cont_level >= tmplen)
-                       if ((tmpoff = (long *) realloc(tmpoff,
+                       if ((tmpoff = (int32 *) realloc(tmpoff,
                                                       tmplen += 20)) == NULL)
                                error("out of memory\n");
                while (magic[magindex+1].cont_level != 0 && 
@@ -175,7 +175,7 @@ int nbytes;
                                         */
                                        if (++cont_level >= tmplen)
                                                if ((tmpoff = 
-                                                   (long *) realloc(tmpoff,
+                                                   (int32 *) realloc(tmpoff,
                                                    tmplen += 20)) == NULL)
                                                        error("out of memory\n");
                                }
@@ -189,14 +189,14 @@ int nbytes;
        return 0;                       /* no match at all */
 }
 
-static long
+static int32
 mprint(p, m)
 union VALUETYPE *p;
 struct magic *m;
 {
        char *pp, *rt;
-       unsigned long v;
-       long t=0 ;
+       uint32 v;
+       int32 t=0 ;
 
 
        switch (m->type) {
@@ -221,8 +221,8 @@ struct magic *m;
        case LELONG:
                v = p->l;
                v = signextend(m, v) & m->mask;
-               (void) printf(m->desc, (unsigned long) v);
-               t = m->offset + sizeof(long);
+               (void) printf(m->desc, (uint32) v);
+               t = m->offset + sizeof(int32);
                break;
 
        case STRING:
@@ -231,6 +231,11 @@ struct magic *m;
                        t = m->offset + strlen(m->value.s);
                }
                else {
+                       if (*m->value.s == '\0') {
+                               char *cp = strchr(p->s,'\n');
+                               if (cp)
+                                       *cp = '\0';
+                       }
                        (void) printf(m->desc, p->s);
                        t = m->offset + strlen(p->s);
                }
@@ -282,7 +287,7 @@ struct magic *m;
                return 1;
        case BELONG:
        case BEDATE:
-               p->l = (long)
+               p->l = (int32)
                    ((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3]));
                return 1;
        case LESHORT:
@@ -290,7 +295,7 @@ struct magic *m;
                return 1;
        case LELONG:
        case LEDATE:
-               p->l = (long)
+               p->l = (int32)
                    ((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0]));
                return 1;
        default:
@@ -302,7 +307,7 @@ struct magic *m;
 
 static void
 mdebug(offset, str, len)
-long offset;
+int32 offset;
 char *str;
 int len;
 {
@@ -319,7 +324,7 @@ unsigned char       *s;
 struct magic *m;
 int nbytes;
 {
-       long offset = m->offset;
+       int32 offset = m->offset;
 
        if (offset + sizeof(union VALUETYPE) <= nbytes)
                memcpy(p, s + offset, sizeof(union VALUETYPE));
@@ -328,7 +333,7 @@ int nbytes;
                 * the usefulness of padding with zeroes eludes me, it
                 * might even cause problems
                 */
-               long have = nbytes - offset;
+               int32 have = nbytes - offset;
                memset(p, 0, sizeof(union VALUETYPE));
                if (have > 0)
                        memcpy(p, s + offset, have);
@@ -378,8 +383,8 @@ mcheck(p, m)
 union VALUETYPE* p;
 struct magic *m;
 {
-       register unsigned long l = m->value.l;
-       register unsigned long v;
+       register uint32 l = m->value.l;
+       register uint32 v;
        int matched;
 
        if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) {
@@ -462,7 +467,7 @@ struct magic *m;
                                               v, l, matched);
                }
                else {
-                       matched = (long) v > (long) l;
+                       matched = (int32) v > (int32) l;
                        if (debug)
                                (void) fprintf(stderr, "%ld > %ld = %d\n",
                                               v, l, matched);
@@ -477,7 +482,7 @@ struct magic *m;
                                               v, l, matched);
                }
                else {
-                       matched = (long) v < (long) l;
+                       matched = (int32) v < (int32) l;
                        if (debug)
                                (void) fprintf(stderr, "%ld < %ld = %d\n",
                                               v, l, matched);