]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Recognize NT_VERSION notes.
authorMark Wielaard <mark@klomp.org>
Sun, 11 Nov 2018 22:50:41 +0000 (23:50 +0100)
committerMark Wielaard <mark@klomp.org>
Tue, 13 Nov 2018 12:40:00 +0000 (13:40 +0100)
NT_VERSION notes are emitted by the gas .version directive.
They have an empty description and (ab)use the owner name to store the
version data string.

Signed-off-by: Mark Wielaard <mark@klomp.org>
libebl/ChangeLog
libebl/eblobjnote.c
libebl/eblobjnotetypename.c
libebl/libebl.h
src/ChangeLog
src/elflint.c
src/readelf.c
tests/ChangeLog
tests/run-readelf-n.sh

index 120c84c06e6c48c2c40a9ef191ad4df7df060eca..076596f09f59253b07dc9b6e4d1cd7f8ce49aff0 100644 (file)
@@ -1,3 +1,12 @@
+2018-11-11  Mark Wielaard  <mark@klomp.org>
+
+       * eblobjnote.c (ebl_object_note): Recognize NT_VERSION with zero
+       descriptor. Add explicit "GNU" name check.
+       * eblobjnotetypename.c (ebl_object_note_type_name): Add extra
+       argument descsz. Recognize NT_VERSION using descsz. With "GNU"
+       name it is  NT_GNU_ABI_TAG.
+       * libebl.h (ebl_object_note_type_name): Add extra argument descsz.
+
 2018-10-18  Mark Wielaard  <mark@klomp.org>
 
        * eblobjnote.c (ebl_object_note): Handle NT_GNU_PROPERTY_TYPE_0.
index 57e9f52f45b16bf7c2ed066d0bae76af9a95e5f6..8fda7d992d3df1576f3cc6764bbe2e388611e028 100644 (file)
@@ -135,6 +135,14 @@ ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
          return;
        }
 
+      /* NT_VERSION doesn't have any info.  All data is in the name.  */
+      if (descsz == 0 && type == NT_VERSION)
+       return;
+
+      /* Everything else should have the "GNU" owner name.  */
+      if (strcmp ("GNU", name) != 0)
+       return;
+
       switch (type)
        {
        case NT_GNU_BUILD_ID:
@@ -337,7 +345,7 @@ ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
          break;
 
        case NT_GNU_ABI_TAG:
-         if (strcmp (name, "GNU") == 0 && descsz >= 8 && descsz % 4 == 0)
+         if (descsz >= 8 && descsz % 4 == 0)
            {
              Elf_Data in =
                {
index af23caea8274fb1a259c3d64b6c34963f8813a8f..8cdd78199ef103132f2c97aff8de3003c7a37dc1 100644 (file)
@@ -39,6 +39,7 @@
 
 const char *
 ebl_object_note_type_name (Ebl *ebl, const char *name, uint32_t type,
+                          GElf_Word descsz,
                           char *buf, size_t len)
 {
   const char *res = ebl->object_note_type_name (name, type, buf, len);
@@ -80,14 +81,19 @@ ebl_object_note_type_name (Ebl *ebl, const char *name, uint32_t type,
 
       if (strcmp (name, "GNU") != 0)
        {
+         /* NT_VERSION is special, all data is in the name.  */
+         if (descsz == 0 && type == NT_VERSION)
+           return "VERSION";
+
          snprintf (buf, len, "%s: %" PRIu32, gettext ("<unknown>"), type);
          return buf;
        }
 
+      /* And finally all the "GNU" note types.  */
       static const char *knowntypes[] =
        {
 #define KNOWNSTYPE(name) [NT_##name] = #name
-         KNOWNSTYPE (VERSION),
+         KNOWNSTYPE (GNU_ABI_TAG),
          KNOWNSTYPE (GNU_HWCAP),
          KNOWNSTYPE (GNU_BUILD_ID),
          KNOWNSTYPE (GNU_GOLD_VERSION),
index a34fe48ddc4a305a6dc970c204c1e114b3106689..583065475073bb68a139171407061018bc9b1f9a 100644 (file)
@@ -175,8 +175,8 @@ extern const char *ebl_core_note_type_name (Ebl *ebl, uint32_t type, char *buf,
 
 /* Return name of the note section type for an object file.  */
 extern const char *ebl_object_note_type_name (Ebl *ebl, const char *name,
-                                             uint32_t type, char *buf,
-                                             size_t len);
+                                             uint32_t type, GElf_Word descsz,
+                                             char *buf, size_t len);
 
 /* Print information about object note if available.  */
 extern void ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
index f1a35798027765e351e4ff47cd1f2ff101195f73..0ed86bbfc428e177d5ce7406a1fd12e8691d6307 100644 (file)
@@ -1,3 +1,10 @@
+2018-11-11  Mark Wielaard  <mark@klomp.org>
+
+       * readelf.c (handle_notes_data): Pass n_descsz to
+       ebl_object_note_type_name.
+       * elflint.c (check_note_data): Recognize NT_VERSION, add owner
+       name to unknown note error.
+
 2018-10-20  Mark Wielaard  <mark@klomp.org>
 
        * readelf.c (process_elf_file): Use dwelf_elf_begin to open pure_elf.
index fa3af4c56fd6f331500294d04570b1b0a9f302b6..dff74eee8ecc4c10c93c2eb17a6b7b08ace1c86e 100644 (file)
@@ -1,5 +1,5 @@
 /* Pedantic checking of ELF files compliance with gABI/psABI spec.
-   Copyright (C) 2001-2015, 2017 Red Hat, Inc.
+   Copyright (C) 2001-2015, 2017, 2018 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2001.
 
@@ -4332,7 +4332,17 @@ section [%2d] '%s': unknown core file note type %" PRIu32
          case NT_GNU_BUILD_ID:
          case NT_GNU_GOLD_VERSION:
          case NT_GNU_PROPERTY_TYPE_0:
-           break;
+           if (nhdr.n_namesz == sizeof ELF_NOTE_GNU
+               && strcmp (data->d_buf + name_offset, ELF_NOTE_GNU) == 0)
+             break;
+           else
+             {
+               /* NT_VERSION is 1, same as NT_GNU_ABI_TAG.  It has no
+                  descriptor and (ab)uses the name as version string.  */
+               if (nhdr.n_descsz == 0 && nhdr.n_type == NT_VERSION)
+                 break;
+             }
+             goto unknown_note;
 
          case 0:
            /* Linux vDSOs use a type 0 note for the kernel version word.  */
@@ -4341,16 +4351,21 @@ section [%2d] '%s': unknown core file note type %" PRIu32
              break;
            FALLTHROUGH;
          default:
+           {
+           unknown_note:
            if (shndx == 0)
              ERROR (gettext ("\
-phdr[%d]: unknown object file note type %" PRIu32 " at offset %zu\n"),
-                    phndx, (uint32_t) nhdr.n_type, offset);
+phdr[%d]: unknown object file note type %" PRIu32 " with owner name '%s' at offset %zu\n"),
+                    phndx, (uint32_t) nhdr.n_type,
+                    (char *) data->d_buf + name_offset, offset);
            else
              ERROR (gettext ("\
 section [%2d] '%s': unknown object file note type %" PRIu32
-                             " at offset %zu\n"),
+                             " with owner name '%s' at offset %zu\n"),
                     shndx, section_name (ebl, shndx),
-                    (uint32_t) nhdr.n_type, offset);
+                    (uint32_t) nhdr.n_type,
+                    (char *) data->d_buf + name_offset, offset);
+           }
          }
     }
 
index c6c3fb323c0bc8064d54c9d47d8420f871650ef8..659e34fb5434d55f4c229e4b1694ec1713e4c35e 100644 (file)
@@ -12201,6 +12201,7 @@ handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
              ? ebl_core_note_type_name (ebl, nhdr.n_type,
                                         buf, sizeof (buf))
              : ebl_object_note_type_name (ebl, name, nhdr.n_type,
+                                          nhdr.n_descsz,
                                           buf2, sizeof (buf2)));
 
       /* Filter out invalid entries.  */
index 92dfb95d7000a6eeb66b2580644dec1e06b1b21d..d92b8e3ac6b1eed759dcb05ee68feeaf1edc3c37 100644 (file)
@@ -1,3 +1,8 @@
+2018-11-11  Mark Wielaard  <mark@klomp.org>
+
+       * run-readelf-n.sh: Fix NT_GNU_ABI_TAG type. Add testfile11 test
+       for NT_VERSION.
+
 2018-11-04  Mark Wielaard  <mark@klomp.org>
 
        * testfile-bpf-reloc.expect.bz2: Update with new expected jump
index 3ae7cf02f06c5dfe89321ab4ce739526aea4ed92..7e2a845e61a291e744554afd86de63959d14aca9 100755 (executable)
@@ -48,8 +48,25 @@ Note segment of 32 bytes at offset 0x300:
 
 Note segment of 68 bytes at offset 0x320:
   Owner          Data size  Type
-  GNU                   16  VERSION
+  GNU                   16  GNU_ABI_TAG
     OS: Linux, ABI: 3.2.0
   GNU                   20  GNU_BUILD_ID
     Build ID: 83cb2229fabd2065d1361f5b46424cd75270f94b
 EOF
+
+# NT_VERSION note type clashes with "GNU" owner type NT_GNU_ABI_TAG.
+# Uses owner name (with zero desc) for version string.
+testfiles testfile11
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile11 << EOF
+
+Note section [ 2] '.note.ABI-tag' of 32 bytes at offset 0x128:
+  Owner          Data size  Type
+  GNU                   16  GNU_ABI_TAG
+    OS: Linux, ABI: 2.2.5
+
+Note section [35] '.note' of 60 bytes at offset 0x13364:
+  Owner          Data size  Type
+  01.01                  0  VERSION
+  01.01                  0  VERSION
+  01.01                  0  VERSION
+EOF