]> granicus.if.org Git - file/commitdiff
- split netbsd and freebsd version printing into separate functions
authorChristos Zoulas <christos@zoulas.com>
Tue, 5 Nov 2013 15:44:01 +0000 (15:44 +0000)
committerChristos Zoulas <christos@zoulas.com>
Tue, 5 Nov 2013 15:44:01 +0000 (15:44 +0000)
- don't let the NetBSD pax note end the search for notes
- add 2 more NetBSD notes

src/readelf.c
src/readelf.h

index ebaf09366587c1616c8f453b6b619d81d5f64682..2bb32aa8bb7895d12a30ed3c0aabc6b409c0200c 100644 (file)
@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: readelf.c,v 1.97 2013/03/06 03:35:30 christos Exp $")
+FILE_RCSID("@(#)$File: readelf.c,v 1.98 2013/09/20 00:39:43 christos Exp $")
 #endif
 
 #ifdef BUILTIN_ELF
@@ -344,6 +344,126 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
 }
 #endif
 
+static void
+do_note_netbsd_version(struct magic_set *ms, int swap, void *v)
+{
+       uint32_t desc;
+       (void)memcpy(&desc, v, sizeof(desc));
+       desc = elf_getu32(swap, desc);
+
+       if (file_printf(ms, ", for NetBSD") == -1)
+               return;
+       /*
+        * The version number used to be stuck as 199905, and was thus
+        * basically content-free.  Newer versions of NetBSD have fixed
+        * this and now use the encoding of __NetBSD_Version__:
+        *
+        *      MMmmrrpp00
+        *
+        * M = major version
+        * m = minor version
+        * r = release ["",A-Z,Z[A-Z] but numeric]
+        * p = patchlevel
+        */
+       if (desc > 100000000U) {
+               uint32_t ver_patch = (desc / 100) % 100;
+               uint32_t ver_rel = (desc / 10000) % 100;
+               uint32_t ver_min = (desc / 1000000) % 100;
+               uint32_t ver_maj = desc / 100000000;
+
+               if (file_printf(ms, " %u.%u", ver_maj, ver_min) == -1)
+                       return;
+               if (ver_rel == 0 && ver_patch != 0) {
+                       if (file_printf(ms, ".%u", ver_patch) == -1)
+                               return;
+               } else if (ver_rel != 0) {
+                       while (ver_rel > 26) {
+                               if (file_printf(ms, "Z") == -1)
+                                       return;
+                               ver_rel -= 26;
+                       }
+                       if (file_printf(ms, "%c", 'A' + ver_rel - 1)
+                           == -1)
+                               return;
+               }
+       }
+}
+
+static void
+do_note_freebsd_version(struct magic_set *ms, int swap, void *v)
+{
+       uint32_t desc;
+
+       (void)memcpy(&desc, v, sizeof(desc));
+       desc = elf_getu32(swap, desc);
+       if (file_printf(ms, ", for FreeBSD") == -1)
+               return;
+
+       /*
+        * Contents is __FreeBSD_version, whose relation to OS
+        * versions is defined by a huge table in the Porter's
+        * Handbook.  This is the general scheme:
+        * 
+        * Releases:
+        *      Mmp000 (before 4.10)
+        *      Mmi0p0 (before 5.0)
+        *      Mmm0p0
+        * 
+        * Development branches:
+        *      Mmpxxx (before 4.6)
+        *      Mmp1xx (before 4.10)
+        *      Mmi1xx (before 5.0)
+        *      M000xx (pre-M.0)
+        *      Mmm1xx
+        * 
+        * M = major version
+        * m = minor version
+        * i = minor version increment (491000 -> 4.10)
+        * p = patchlevel
+        * x = revision
+        * 
+        * The first release of FreeBSD to use ELF by default
+        * was version 3.0.
+        */
+       if (desc == 460002) {
+               if (file_printf(ms, " 4.6.2") == -1)
+                       return;
+       } else if (desc < 460100) {
+               if (file_printf(ms, " %d.%d", desc / 100000,
+                   desc / 10000 % 10) == -1)
+                       return;
+               if (desc / 1000 % 10 > 0)
+                       if (file_printf(ms, ".%d", desc / 1000 % 10) == -1)
+                               return;
+               if ((desc % 1000 > 0) || (desc % 100000 == 0))
+                       if (file_printf(ms, " (%d)", desc) == -1)
+                               return;
+       } else if (desc < 500000) {
+               if (file_printf(ms, " %d.%d", desc / 100000,
+                   desc / 10000 % 10 + desc / 1000 % 10) == -1)
+                       return;
+               if (desc / 100 % 10 > 0) {
+                       if (file_printf(ms, " (%d)", desc) == -1)
+                               return;
+               } else if (desc / 10 % 10 > 0) {
+                       if (file_printf(ms, ".%d", desc / 10 % 10) == -1)
+                               return;
+               }
+       } else {
+               if (file_printf(ms, " %d.%d", desc / 100000,
+                   desc / 1000 % 100) == -1)
+                       return;
+               if ((desc / 100 % 10 > 0) ||
+                   (desc % 100000 / 100 == 0)) {
+                       if (file_printf(ms, " (%d)", desc) == -1)
+                               return;
+               } else if (desc / 10 % 10 > 0) {
+                       if (file_printf(ms, ".%d", desc / 10 % 10) == -1)
+                               return;
+               }
+       }
+}
+
 private size_t
 donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
     int clazz, int swap, size_t align, int *flags)
@@ -488,131 +608,41 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
                            pax[i]) == -1)
                                return size;
                }
-               *flags |= FLAGS_DID_BUILD_ID;
        }
 
-       if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0 &&
-           xnh_type == NT_NETBSD_VERSION && descsz == 4) {
-               uint32_t desc;
-               (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
-               desc = elf_getu32(swap, desc);
-
-               if (file_printf(ms, ", for NetBSD") == -1)
-                       return size;
-               /*
-                * The version number used to be stuck as 199905, and was thus
-                * basically content-free.  Newer versions of NetBSD have fixed
-                * this and now use the encoding of __NetBSD_Version__:
-                *
-                *      MMmmrrpp00
-                *
-                * M = major version
-                * m = minor version
-                * r = release ["",A-Z,Z[A-Z] but numeric]
-                * p = patchlevel
-                */
-               if (desc > 100000000U) {
-                       uint32_t ver_patch = (desc / 100) % 100;
-                       uint32_t ver_rel = (desc / 10000) % 100;
-                       uint32_t ver_min = (desc / 1000000) % 100;
-                       uint32_t ver_maj = desc / 100000000;
-
-                       if (file_printf(ms, " %u.%u", ver_maj, ver_min) == -1)
+       if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
+               switch (xnh_type) {
+               case NT_NETBSD_VERSION:
+                       if (descsz == 4) {
+                               do_note_netbsd_version(ms, swap, &nbuf[doff]);
+                               *flags |= FLAGS_DID_NOTE;
                                return size;
-                       if (ver_rel == 0 && ver_patch != 0) {
-                               if (file_printf(ms, ".%u", ver_patch) == -1)
-                                       return size;
-                       } else if (ver_rel != 0) {
-                               while (ver_rel > 26) {
-                                       if (file_printf(ms, "Z") == -1)
-                                               return size;
-                                       ver_rel -= 26;
-                               }
-                               if (file_printf(ms, "%c", 'A' + ver_rel - 1)
-                                   == -1)
-                                       return size;
                        }
+                       break;
+               case NT_NETBSD_MARCH:
+                       if (file_printf(ms, ", compiled for: %.*s", (int)descsz,
+                           (const char *)&nbuf[doff]) == -1)
+                               return size;
+                       break;
+               case NT_NETBSD_CMODEL:
+                       if (file_printf(ms, ", compiler model: %.*s",
+                           (int)descsz, (const char *)&nbuf[doff]) == -1)
+                               return size;
+                       break;
+               default:
+                       if (file_printf(ms, ", note=%u", xnh_type) == -1)
+                               return size;
+                       break;
                }
-               *flags |= FLAGS_DID_NOTE;
                return size;
        }
 
-       if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0 &&
-           xnh_type == NT_FREEBSD_VERSION && descsz == 4) {
-               uint32_t desc;
-               (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
-               desc = elf_getu32(swap, desc);
-               if (file_printf(ms, ", for FreeBSD") == -1)
+       if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) {
+               if (xnh_type == NT_FREEBSD_VERSION && descsz == 4) {
+                       do_note_freebsd_version(ms, swap, &nbuf[doff]);
+                       *flags |= FLAGS_DID_NOTE;
                        return size;
-
-               /*
-                * Contents is __FreeBSD_version, whose relation to OS
-                * versions is defined by a huge table in the Porter's
-                * Handbook.  This is the general scheme:
-                * 
-                * Releases:
-                *      Mmp000 (before 4.10)
-                *      Mmi0p0 (before 5.0)
-                *      Mmm0p0
-                * 
-                * Development branches:
-                *      Mmpxxx (before 4.6)
-                *      Mmp1xx (before 4.10)
-                *      Mmi1xx (before 5.0)
-                *      M000xx (pre-M.0)
-                *      Mmm1xx
-                * 
-                * M = major version
-                * m = minor version
-                * i = minor version increment (491000 -> 4.10)
-                * p = patchlevel
-                * x = revision
-                * 
-                * The first release of FreeBSD to use ELF by default
-                * was version 3.0.
-                */
-               if (desc == 460002) {
-                       if (file_printf(ms, " 4.6.2") == -1)
-                               return size;
-               } else if (desc < 460100) {
-                       if (file_printf(ms, " %d.%d", desc / 100000,
-                           desc / 10000 % 10) == -1)
-                               return size;
-                       if (desc / 1000 % 10 > 0)
-                               if (file_printf(ms, ".%d", desc / 1000 % 10)
-                                   == -1)
-                                       return size;
-                       if ((desc % 1000 > 0) || (desc % 100000 == 0))
-                               if (file_printf(ms, " (%d)", desc) == -1)
-                                       return size;
-               } else if (desc < 500000) {
-                       if (file_printf(ms, " %d.%d", desc / 100000,
-                           desc / 10000 % 10 + desc / 1000 % 10) == -1)
-                               return size;
-                       if (desc / 100 % 10 > 0) {
-                               if (file_printf(ms, " (%d)", desc) == -1)
-                                       return size;
-                       } else if (desc / 10 % 10 > 0) {
-                               if (file_printf(ms, ".%d", desc / 10 % 10)
-                                   == -1)
-                                       return size;
-                       }
-               } else {
-                       if (file_printf(ms, " %d.%d", desc / 100000,
-                           desc / 1000 % 100) == -1)
-                               return size;
-                       if ((desc / 100 % 10 > 0) ||
-                           (desc % 100000 / 100 == 0)) {
-                               if (file_printf(ms, " (%d)", desc) == -1)
-                                       return size;
-                       } else if (desc / 10 % 10 > 0) {
-                               if (file_printf(ms, ".%d", desc / 10 % 10)
-                                   == -1)
-                                       return size;
-                       }
                }
-               *flags |= FLAGS_DID_NOTE;
-               return size;
        }
 
        if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
index 10a9e63605212e0b18b4cad2ccfd6e4bb3bae68a..732b20c88e728761ba19ee2d8c75d619420c4fc1 100644 (file)
@@ -272,6 +272,29 @@ typedef struct {
 #define NT_NETBSD_PAX_ASLR             0x10    /* Force enable ASLR */
 #define NT_NETBSD_PAX_NOASLR           0x20    /* Force disable ASLR */
 
+/*
+ * NetBSD-specific note type: MACHINE_ARCH.
+ * There should be 1 NOTE per executable.
+ * name:       NetBSD\0
+ * namesz:     7
+ * desc:       string
+ * descsz:     variable
+ */
+#define NT_NETBSD_MARCH                5
+
+/*
+ * NetBSD-specific note type: COMPILER MODEL.
+ * There should be 1 NOTE per executable.
+ * name:       NetBSD\0
+ * namesz:     7
+ * desc:       string
+ * descsz:     variable
+ */
+#define NT_NETBSD_CMODEL       6
+
+#if !defined(ELFSIZE) && defined(ARCH_ELFSIZE)
+#define ELFSIZE ARCH_ELFSIZE
+#endif
 /* SunOS 5.x hardware/software capabilities */
 typedef struct {
        Elf32_Word      c_tag;