diff options
author | George Rimar <grimar@accesssoftek.com> | 2018-03-21 08:34:55 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2018-03-21 08:34:55 +0000 |
commit | a48ab92bca4520d79a13c991e7896b74892d661d (patch) | |
tree | ae1e7a00b34659bd691689e76856caeb1d15b860 /tools/llvm-readobj | |
parent | 36dd4b436109c93fa6314579cd53ad13ba738f60 (diff) |
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@328078 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-readobj')
-rw-r--r-- | tools/llvm-readobj/ELFDumper.cpp | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 8d62864f05c..b41d431fdc7 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -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) @@ -3476,8 +3477,35 @@ static std::string getAMDGPUNoteTypeName(const uint32_t NT) { } 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'; } |