[llvm] r328078 - [llvm-readobj] - Teach llvm-readobj to dump .note.gnu.property sections.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 21 01:34:55 PDT 2018


Author: grimar
Date: Wed Mar 21 01:34:55 2018
New Revision: 328078

URL: http://llvm.org/viewvc/llvm-project?rev=328078&view=rev
Log:
[llvm-readobj] - Teach llvm-readobj to dump .note.gnu.property sections.

NT_GNU_PROPERTY_TYPE_0 is a recently added type of .note.gnu.property
section specified in Linux Extensions to gABI.
(https://github.com/hjl-tools/linux-abi/wiki/Linux-Extensions-to-gABI)

Patch teach tool to print such notes properly.

Differential revision: https://reviews.llvm.org/D44469

Added:
    llvm/trunk/test/tools/llvm-readobj/note-gnu-property.s
    llvm/trunk/test/tools/llvm-readobj/note-gnu-property2.s
Modified:
    llvm/trunk/include/llvm/BinaryFormat/ELF.h
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp

Modified: llvm/trunk/include/llvm/BinaryFormat/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/ELF.h?rev=328078&r1=328077&r2=328078&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/ELF.h (original)
+++ llvm/trunk/include/llvm/BinaryFormat/ELF.h Wed Mar 21 01:34:55 2018
@@ -1440,6 +1440,13 @@ enum {
   NT_GNU_HWCAP = 2,
   NT_GNU_BUILD_ID = 3,
   NT_GNU_GOLD_VERSION = 4,
+  NT_GNU_PROPERTY_TYPE_0 = 5,
+};
+
+// Property types used in GNU_PROPERTY_TYPE_0 notes.
+enum {
+  GNU_PROPERTY_STACK_SIZE = 1,
+  GNU_PROPERTY_NO_COPY_ON_PROTECTED = 2,
 };
 
 // AMDGPU specific notes.

Added: llvm/trunk/test/tools/llvm-readobj/note-gnu-property.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/note-gnu-property.s?rev=328078&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/note-gnu-property.s (added)
+++ llvm/trunk/test/tools/llvm-readobj/note-gnu-property.s Wed Mar 21 01:34:55 2018
@@ -0,0 +1,68 @@
+// REQUIRES: x86-registered-target
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t
+// RUN: llvm-readobj -elf-output-style GNU --notes %t | FileCheck %s
+
+// CHECK:      Displaying notes found at file offset 0x00000040 with length 0x00000070:
+// CHECK-NEXT:   Owner                 Data size       Description
+// CHECK-NEXT:   GNU                   0x00000060      NT_GNU_PROPERTY_TYPE_0 (property note)
+// CHECK-NEXT:     Properties:  stack size: 0x100
+// CHECK-NEXT:     stack size: 0x100
+// CHECK-NEXT:     no copy on protected
+// CHECK-NEXT:     <application-specific type 0xfefefefe>
+// CHECK-NEXT:     stack size: <corrupt length: 0x0>
+// CHECK-NEXT:     stack size: <corrupt length: 0x4> 
+// CHECK-NEXT:     no copy on protected <corrupt length: 0x1>
+// CHECK-NEXT:     <corrupt type (0x2) datasz: 0x1>
+
+.section ".note.gnu.property", "a"
+.align 4 
+  .long 4           /* Name length is always 4 ("GNU") */
+  .long end - begin /* Data length */
+  .long 5           /* Type: NT_GNU_PROPERTY_TYPE_0 */
+  .asciz "GNU"      /* Name */
+  .p2align 3
+begin:
+  .long 1           /* Type: GNU_PROPERTY_STACK_SIZE */
+  .long 8           /* Data size */
+  .quad 0x100       /* Data (stack size) */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+  
+  /* Test we handle alignment properly */
+  .long 1           /* Type: GNU_PROPERTY_STACK_SIZE */
+  .long 8           /* Data size */
+  .long 0x100       /* Data (stack size) */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+  
+  .long 2           /* Type: GNU_PROPERTY_NO_COPY_ON_PROTECTED */
+  .long 0           /* Data size */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+  
+  /* All notes below are broken. Test we are able to report them. */
+  
+  /* Broken note type */
+  .long 0xfefefefe  /* Invalid type for testing */
+  .long 0           /* Data size */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+  
+  /* GNU_PROPERTY_STACK_SIZE with zero stack size */
+  .long 1           /* Type: GNU_PROPERTY_STACK_SIZE */
+  .long 0           /* Data size */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+  
+  /* GNU_PROPERTY_STACK_SIZE with data size 4 (should be 8) */
+  .long 1           /* Type: GNU_PROPERTY_STACK_SIZE */
+  .long 4           /* Data size */
+  .long 0x100       /* Data (stack size) */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+  
+  /* GNU_PROPERTY_NO_COPY_ON_PROTECTED with pr_datasz and some data */
+  .long 2           /* Type: GNU_PROPERTY_NO_COPY_ON_PROTECTED */
+  .long 1           /* Data size (corrupted) */
+  .byte 1           /* Data */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+  
+  /* GNU_PROPERTY_NO_COPY_ON_PROTECTED with pr_datasz and without data */
+  .long 2           /* Type: GNU_PROPERTY_NO_COPY_ON_PROTECTED */
+  .long 1           /* Data size (corrupted) */
+  .p2align 3        /* Align to 8 byte for 64 bit */
+end:

Added: llvm/trunk/test/tools/llvm-readobj/note-gnu-property2.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/note-gnu-property2.s?rev=328078&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/note-gnu-property2.s (added)
+++ llvm/trunk/test/tools/llvm-readobj/note-gnu-property2.s Wed Mar 21 01:34:55 2018
@@ -0,0 +1,22 @@
+// REQUIRES: x86-registered-target
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t
+// RUN: llvm-readobj -elf-output-style GNU --notes %t | FileCheck %s
+
+// CHECK:      Displaying notes found at file offset 0x00000040 with length 0x00000014:
+// CHECK-NEXT:   Owner                 Data size       Description
+// CHECK-NEXT:   GNU                   0x00000004      NT_GNU_PROPERTY_TYPE_0 (property note)
+// CHECK-NEXT:     Properties:
+// CHECK-NEXT:     <corrupted GNU_PROPERTY_TYPE_0>
+
+// Section below is broken, check we report that.
+
+.section ".note.gnu.property", "a"
+.align 4 
+  .long 4           /* Name length is always 4 ("GNU") */
+  .long end - begin /* Data length */
+  .long 5           /* Type: NT_GNU_PROPERTY_TYPE_0 */
+  .asciz "GNU"      /* Name */
+  .p2align 3
+begin:
+  .long 1           /* Type: GNU_PROPERTY_STACK_SIZE */
+end:

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=328078&r1=328077&r2=328078&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Wed Mar 21 01:34:55 2018
@@ -3412,6 +3412,7 @@ static std::string getGNUNoteTypeName(co
       {ELF::NT_GNU_HWCAP, "NT_GNU_HWCAP (DSO-supplied software HWCAP info)"},
       {ELF::NT_GNU_BUILD_ID, "NT_GNU_BUILD_ID (unique build ID bitstring)"},
       {ELF::NT_GNU_GOLD_VERSION, "NT_GNU_GOLD_VERSION (gold version)"},
+      {ELF::NT_GNU_PROPERTY_TYPE_0, "NT_GNU_PROPERTY_TYPE_0 (property note)"},
   };
 
   for (const auto &Note : Notes)
@@ -3476,8 +3477,35 @@ static std::string getAMDGPUNoteTypeName
 }
 
 template <typename ELFT>
+static void printGNUProperty(raw_ostream &OS, uint32_t Type, uint32_t DataSize,
+                             ArrayRef<uint8_t> Data) {
+  switch (Type) {
+  default:
+    OS << format("    <application-specific type 0x%x>\n", Type);
+    return;
+  case GNU_PROPERTY_STACK_SIZE: {
+    OS << "    stack size: ";
+    if (DataSize == sizeof(typename ELFT::uint))
+      OS << format("0x%x\n",
+                   (uint64_t)(*(const typename ELFT::Addr *)Data.data()));
+    else
+      OS << format("<corrupt length: 0x%x>\n", DataSize);
+    break;
+  }
+  case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
+    OS << "    no copy on protected";
+    if (DataSize)
+      OS << format(" <corrupt length: 0x%x>", DataSize);
+    OS << "\n";
+    break;
+  }
+}
+
+template <typename ELFT>
 static void printGNUNote(raw_ostream &OS, uint32_t NoteType,
                          ArrayRef<typename ELFT::Word> Words, size_t Size) {
+  using Elf_Word = typename ELFT::Word;
+
   switch (NoteType) {
   default:
     return;
@@ -3509,8 +3537,31 @@ static void printGNUNote(raw_ostream &OS
     OS << "    Version: "
        << StringRef(reinterpret_cast<const char *>(Words.data()), Size);
     break;
-  }
+  case ELF::NT_GNU_PROPERTY_TYPE_0:
+    OS << "    Properties:";
 
+    ArrayRef<uint8_t> Arr(reinterpret_cast<const uint8_t *>(Words.data()),
+                          Size);
+    while (Arr.size() >= 8) {
+      uint32_t Type = *reinterpret_cast<const Elf_Word *>(Arr.data());
+      uint32_t DataSize = *reinterpret_cast<const Elf_Word *>(Arr.data() + 4);
+      Arr = Arr.drop_front(8);
+
+      // Take padding size into account if present.
+      uint64_t PaddedSize = alignTo(DataSize, sizeof(typename ELFT::uint));
+      if (Arr.size() < PaddedSize) {
+        OS << format("    <corrupt type (0x%x) datasz: 0x%x>\n", Type,
+                     DataSize);
+        break;
+      }
+      printGNUProperty<ELFT>(OS, Type, DataSize, Arr.take_front(PaddedSize));
+      Arr = Arr.drop_front(PaddedSize);
+    }
+
+    if (!Arr.empty())
+      OS << "    <corrupted GNU_PROPERTY_TYPE_0>";
+    break;
+  }
   OS << '\n';
 }
 




More information about the llvm-commits mailing list