forked from OSchip/llvm-project
[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 llvm-svn: 328078
This commit is contained in:
parent
f1fc25eb74
commit
6a14c02431
|
@ -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.
|
||||
|
|
|
@ -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:
|
|
@ -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:
|
|
@ -3412,6 +3412,7 @@ static std::string getGNUNoteTypeName(const uint32_t NT) {
|
|||
{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)
|
||||
|
@ -3475,9 +3476,36 @@ static std::string getAMDGPUNoteTypeName(const uint32_t NT) {
|
|||
return OS.str();
|
||||
}
|
||||
|
||||
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, uint32_t NoteType,
|
|||
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';
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue