95a93d
commit 7a3f6fe60b8519b5372f5a5521ccbac59411f33f
95a93d
Author: Mark Wielaard <mark@klomp.org>
95a93d
Date:   Sun Nov 11 23:50:41 2018 +0100
95a93d
95a93d
    Recognize NT_VERSION notes.
95a93d
    
95a93d
    NT_VERSION notes are emitted by the gas .version directive.
95a93d
    They have an empty description and (ab)use the owner name to store the
95a93d
    version data string.
95a93d
    
95a93d
    Signed-off-by: Mark Wielaard <mark@klomp.org>
95a93d
95a93d
diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c
95a93d
index 57e9f52..8fda7d9 100644
95a93d
--- a/libebl/eblobjnote.c
95a93d
+++ b/libebl/eblobjnote.c
95a93d
@@ -135,6 +135,14 @@ ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
95a93d
 	  return;
95a93d
 	}
95a93d
 
95a93d
+      /* NT_VERSION doesn't have any info.  All data is in the name.  */
95a93d
+      if (descsz == 0 && type == NT_VERSION)
95a93d
+	return;
95a93d
+
95a93d
+      /* Everything else should have the "GNU" owner name.  */
95a93d
+      if (strcmp ("GNU", name) != 0)
95a93d
+	return;
95a93d
+
95a93d
       switch (type)
95a93d
 	{
95a93d
 	case NT_GNU_BUILD_ID:
95a93d
@@ -337,7 +345,7 @@ ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
95a93d
 	  break;
95a93d
 
95a93d
 	case NT_GNU_ABI_TAG:
95a93d
-	  if (strcmp (name, "GNU") == 0 && descsz >= 8 && descsz % 4 == 0)
95a93d
+	  if (descsz >= 8 && descsz % 4 == 0)
95a93d
 	    {
95a93d
 	      Elf_Data in =
95a93d
 		{
95a93d
diff --git a/libebl/eblobjnotetypename.c b/libebl/eblobjnotetypename.c
95a93d
index af23cae..8cdd781 100644
95a93d
--- a/libebl/eblobjnotetypename.c
95a93d
+++ b/libebl/eblobjnotetypename.c
95a93d
@@ -39,6 +39,7 @@
95a93d
 
95a93d
 const char *
95a93d
 ebl_object_note_type_name (Ebl *ebl, const char *name, uint32_t type,
95a93d
+			   GElf_Word descsz,
95a93d
 			   char *buf, size_t len)
95a93d
 {
95a93d
   const char *res = ebl->object_note_type_name (name, type, buf, len);
95a93d
@@ -80,14 +81,19 @@ ebl_object_note_type_name (Ebl *ebl, const char *name, uint32_t type,
95a93d
 
95a93d
       if (strcmp (name, "GNU") != 0)
95a93d
 	{
95a93d
+	  /* NT_VERSION is special, all data is in the name.  */
95a93d
+	  if (descsz == 0 && type == NT_VERSION)
95a93d
+	    return "VERSION";
95a93d
+
95a93d
 	  snprintf (buf, len, "%s: %" PRIu32, gettext ("<unknown>"), type);
95a93d
 	  return buf;
95a93d
 	}
95a93d
 
95a93d
+      /* And finally all the "GNU" note types.  */
95a93d
       static const char *knowntypes[] =
95a93d
 	{
95a93d
 #define KNOWNSTYPE(name) [NT_##name] = #name
95a93d
-	  KNOWNSTYPE (VERSION),
95a93d
+	  KNOWNSTYPE (GNU_ABI_TAG),
95a93d
 	  KNOWNSTYPE (GNU_HWCAP),
95a93d
 	  KNOWNSTYPE (GNU_BUILD_ID),
95a93d
 	  KNOWNSTYPE (GNU_GOLD_VERSION),
95a93d
diff --git a/libebl/libebl.h b/libebl/libebl.h
95a93d
index a34fe48..5830654 100644
95a93d
--- a/libebl/libebl.h
95a93d
+++ b/libebl/libebl.h
95a93d
@@ -175,8 +175,8 @@ extern const char *ebl_core_note_type_name (Ebl *ebl, uint32_t type, char *buf,
95a93d
 
95a93d
 /* Return name of the note section type for an object file.  */
95a93d
 extern const char *ebl_object_note_type_name (Ebl *ebl, const char *name,
95a93d
-					      uint32_t type, char *buf,
95a93d
-					      size_t len);
95a93d
+					      uint32_t type, GElf_Word descsz,
95a93d
+					      char *buf, size_t len);
95a93d
 
95a93d
 /* Print information about object note if available.  */
95a93d
 extern void ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
95a93d
diff --git a/src/elflint.c b/src/elflint.c
95a93d
index fa3af4c..dff74ee 100644
95a93d
--- a/src/elflint.c
95a93d
+++ b/src/elflint.c
95a93d
@@ -1,5 +1,5 @@
95a93d
 /* Pedantic checking of ELF files compliance with gABI/psABI spec.
95a93d
-   Copyright (C) 2001-2015, 2017 Red Hat, Inc.
95a93d
+   Copyright (C) 2001-2015, 2017, 2018 Red Hat, Inc.
95a93d
    This file is part of elfutils.
95a93d
    Written by Ulrich Drepper <drepper@redhat.com>, 2001.
95a93d
 
95a93d
@@ -4332,7 +4332,17 @@ section [%2d] '%s': unknown core file note type %" PRIu32
95a93d
 	  case NT_GNU_BUILD_ID:
95a93d
 	  case NT_GNU_GOLD_VERSION:
95a93d
 	  case NT_GNU_PROPERTY_TYPE_0:
95a93d
-	    break;
95a93d
+	    if (nhdr.n_namesz == sizeof ELF_NOTE_GNU
95a93d
+		&& strcmp (data->d_buf + name_offset, ELF_NOTE_GNU) == 0)
95a93d
+	      break;
95a93d
+	    else
95a93d
+	      {
95a93d
+		/* NT_VERSION is 1, same as NT_GNU_ABI_TAG.  It has no
95a93d
+		   descriptor and (ab)uses the name as version string.  */
95a93d
+		if (nhdr.n_descsz == 0 && nhdr.n_type == NT_VERSION)
95a93d
+		  break;
95a93d
+	      }
95a93d
+	      goto unknown_note;
95a93d
 
95a93d
 	  case 0:
95a93d
 	    /* Linux vDSOs use a type 0 note for the kernel version word.  */
95a93d
@@ -4341,16 +4351,21 @@ section [%2d] '%s': unknown core file note type %" PRIu32
95a93d
 	      break;
95a93d
 	    FALLTHROUGH;
95a93d
 	  default:
95a93d
+	    {
95a93d
+	    unknown_note:
95a93d
 	    if (shndx == 0)
95a93d
 	      ERROR (gettext ("\
95a93d
-phdr[%d]: unknown object file note type %" PRIu32 " at offset %zu\n"),
95a93d
-		     phndx, (uint32_t) nhdr.n_type, offset);
95a93d
+phdr[%d]: unknown object file note type %" PRIu32 " with owner name '%s' at offset %zu\n"),
95a93d
+		     phndx, (uint32_t) nhdr.n_type,
95a93d
+		     (char *) data->d_buf + name_offset, offset);
95a93d
 	    else
95a93d
 	      ERROR (gettext ("\
95a93d
 section [%2d] '%s': unknown object file note type %" PRIu32
95a93d
-			      " at offset %zu\n"),
95a93d
+			      " with owner name '%s' at offset %zu\n"),
95a93d
 		     shndx, section_name (ebl, shndx),
95a93d
-		     (uint32_t) nhdr.n_type, offset);
95a93d
+		     (uint32_t) nhdr.n_type,
95a93d
+		     (char *) data->d_buf + name_offset, offset);
95a93d
+	    }
95a93d
 	  }
95a93d
     }
95a93d
 
95a93d
diff --git a/src/readelf.c b/src/readelf.c
95a93d
index c6c3fb3..659e34f 100644
95a93d
--- a/src/readelf.c
95a93d
+++ b/src/readelf.c
95a93d
@@ -12201,6 +12201,7 @@ handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
95a93d
 	      ? ebl_core_note_type_name (ebl, nhdr.n_type,
95a93d
 					 buf, sizeof (buf))
95a93d
 	      : ebl_object_note_type_name (ebl, name, nhdr.n_type,
95a93d
+					   nhdr.n_descsz,
95a93d
 					   buf2, sizeof (buf2)));
95a93d
 
95a93d
       /* Filter out invalid entries.  */