summaryrefslogtreecommitdiff
path: root/tools/llvm-readobj
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2018-03-21 08:34:55 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2018-03-21 08:34:55 +0000
commita48ab92bca4520d79a13c991e7896b74892d661d (patch)
treeae1e7a00b34659bd691689e76856caeb1d15b860 /tools/llvm-readobj
parent36dd4b436109c93fa6314579cd53ad13ba738f60 (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.cpp53
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';
}