aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Ehrlich <jakehehrlich@google.com>2018-11-13 01:10:35 +0000
committerJake Ehrlich <jakehehrlich@google.com>2018-11-13 01:10:35 +0000
commit84d18ae14eda81635e19c42495388d7f2c3b1fd0 (patch)
tree1b037ceec31839a47cc3cff4afe7b7e5ef69d5bb
parent7b60928bd7de2c0f32b98c71ad6f567276b5c301 (diff)
[libObject] Fix getDesc for Elf_Note_Impl
This change fixes a bug in Elf_Note_Impl in which Elf_Word was used where uint8_t should have been used. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346724 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Object/ELFTypes.h11
-rw-r--r--test/tools/llvm-readobj/gnu-note-size.test32
-rw-r--r--tools/llvm-readobj/ELFDumper.cpp61
3 files changed, 67 insertions, 37 deletions
diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h
index fb386120e34..fafdcd7bdae 100644
--- a/include/llvm/Object/ELFTypes.h
+++ b/include/llvm/Object/ELFTypes.h
@@ -605,13 +605,12 @@ public:
}
/// Get the note's descriptor.
- ArrayRef<Elf_Word> getDesc() const {
+ ArrayRef<uint8_t> getDesc() const {
if (!Nhdr.n_descsz)
- return ArrayRef<Elf_Word>();
- return ArrayRef<Elf_Word>(
- reinterpret_cast<const Elf_Word *>(
- reinterpret_cast<const uint8_t *>(&Nhdr) + sizeof(Nhdr) +
- alignTo<Elf_Nhdr_Impl<ELFT>::Align>(Nhdr.n_namesz)),
+ return ArrayRef<uint8_t>();
+ return ArrayRef<uint8_t>(
+ reinterpret_cast<const uint8_t *>(&Nhdr) + sizeof(Nhdr) +
+ alignTo<Elf_Nhdr_Impl<ELFT>::Align>(Nhdr.n_namesz),
Nhdr.n_descsz);
}
diff --git a/test/tools/llvm-readobj/gnu-note-size.test b/test/tools/llvm-readobj/gnu-note-size.test
new file mode 100644
index 00000000000..4a160d13a5c
--- /dev/null
+++ b/test/tools/llvm-readobj/gnu-note-size.test
@@ -0,0 +1,32 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-readobj -elf-output-style GNU --notes %t | FileCheck %s --check-prefix=GNU
+# RUN: llvm-readobj -elf-output-style LLVM --notes %t | FileCheck %s --check-prefix=LLVM
+
+# GNU: Owner Data size Description
+# GNU-NEXT: GNU 0x00000004 NT_GNU_ABI_TAG (ABI version tag)
+# GNU-NEXT: <corrupt GNU_ABI_TAG>
+
+# LLVM: Notes [
+# LLVM-NEXT: NoteSection {
+# LLVM-NEXT: Offset:
+# LLVM-NEXT: Size: 0x14
+# LLVM-NEXT: Note {
+# LLVM-NEXT: Owner: GNU
+# LLVM-NEXT: Data size: 0x4
+# LLVM-NEXT: Type: NT_GNU_ABI_TAG (ABI version tag)
+# LLVM-NEXT: ABI: <corrupt GNU_ABI_TAG>
+# LLVM-NEXT: }
+# LLVM-NEXT: }
+# LLVM-NEXT: ]
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .note.ABI-tag
+ Type: SHT_NOTE
+ AddressAlign: 0x0000000000000004
+ Content: 040000000400000001000000474E550000000000
diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp
index 16a0f0d2e31..ea0bb736fa0 100644
--- a/tools/llvm-readobj/ELFDumper.cpp
+++ b/tools/llvm-readobj/ELFDumper.cpp
@@ -3711,12 +3711,10 @@ static std::string getGNUProperty(uint32_t Type, uint32_t DataSize,
template <typename ELFT>
static SmallVector<std::string, 4>
-getGNUPropertyList(ArrayRef<typename ELFT::Word> Words) {
+getGNUPropertyList(ArrayRef<uint8_t> Arr) {
using Elf_Word = typename ELFT::Word;
SmallVector<std::string, 4> Properties;
- ArrayRef<uint8_t> Arr(reinterpret_cast<const uint8_t *>(Words.data()),
- Words.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);
@@ -3749,7 +3747,12 @@ struct GNUAbiTag {
};
template <typename ELFT>
-static GNUAbiTag getGNUAbiTag(ArrayRef<typename ELFT::Word> Words) {
+static GNUAbiTag getGNUAbiTag(ArrayRef<uint8_t> Desc) {
+ typedef typename ELFT::Word Elf_Word;
+
+ ArrayRef<Elf_Word> Words(reinterpret_cast<const Elf_Word*>(Desc.begin()),
+ reinterpret_cast<const Elf_Word*>(Desc.end()));
+
if (Words.size() < 4)
return {"", "", /*IsValid=*/false};
@@ -3766,30 +3769,26 @@ static GNUAbiTag getGNUAbiTag(ArrayRef<typename ELFT::Word> Words) {
return {OSName, ABI.str(), /*IsValid=*/true};
}
-template <typename ELFT>
-static std::string getGNUBuildId(ArrayRef<typename ELFT::Word> Words) {
+static std::string getGNUBuildId(ArrayRef<uint8_t> Desc) {
std::string str;
raw_string_ostream OS(str);
- ArrayRef<uint8_t> ID(reinterpret_cast<const uint8_t *>(Words.data()),
- Words.size());
- for (const auto &B : ID)
+ for (const auto &B : Desc)
OS << format_hex_no_prefix(B, 2);
return OS.str();
}
-template <typename ELFT>
-static StringRef getGNUGoldVersion(ArrayRef<typename ELFT::Word> Words) {
- return StringRef(reinterpret_cast<const char *>(Words.data()), Words.size());
+static StringRef getGNUGoldVersion(ArrayRef<uint8_t> Desc) {
+ return StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
}
template <typename ELFT>
static void printGNUNote(raw_ostream &OS, uint32_t NoteType,
- ArrayRef<typename ELFT::Word> Words) {
+ ArrayRef<uint8_t> Desc) {
switch (NoteType) {
default:
return;
case ELF::NT_GNU_ABI_TAG: {
- const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Words);
+ const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);
if (!AbiTag.IsValid)
OS << " <corrupt GNU_ABI_TAG>";
else
@@ -3797,15 +3796,15 @@ static void printGNUNote(raw_ostream &OS, uint32_t NoteType,
break;
}
case ELF::NT_GNU_BUILD_ID: {
- OS << " Build ID: " << getGNUBuildId<ELFT>(Words);
+ OS << " Build ID: " << getGNUBuildId(Desc);
break;
}
case ELF::NT_GNU_GOLD_VERSION:
- OS << " Version: " << getGNUGoldVersion<ELFT>(Words);
+ OS << " Version: " << getGNUGoldVersion(Desc);
break;
case ELF::NT_GNU_PROPERTY_TYPE_0:
OS << " Properties:";
- for (const auto &Property : getGNUPropertyList<ELFT>(Words))
+ for (const auto &Property : getGNUPropertyList<ELFT>(Desc))
OS << " " << Property << "\n";
break;
}
@@ -3819,22 +3818,22 @@ struct AMDGPUNote {
template <typename ELFT>
static AMDGPUNote getAMDGPUNote(uint32_t NoteType,
- ArrayRef<typename ELFT::Word> Words) {
+ ArrayRef<uint8_t> Desc) {
switch (NoteType) {
default:
return {"", ""};
case ELF::NT_AMD_AMDGPU_HSA_METADATA:
return {"HSA Metadata",
- std::string(reinterpret_cast<const char *>(Words.data()),
- Words.size())};
+ std::string(reinterpret_cast<const char *>(Desc.data()),
+ Desc.size())};
case ELF::NT_AMD_AMDGPU_ISA:
return {"ISA Version",
- std::string(reinterpret_cast<const char *>(Words.data()),
- Words.size())};
+ std::string(reinterpret_cast<const char *>(Desc.data()),
+ Desc.size())};
case ELF::NT_AMD_AMDGPU_PAL_METADATA:
const uint32_t *PALMetadataBegin =
- reinterpret_cast<const uint32_t *>(Words.data());
- const uint32_t *PALMetadataEnd = PALMetadataBegin + Words.size();
+ reinterpret_cast<const uint32_t *>(Desc.data());
+ const uint32_t *PALMetadataEnd = PALMetadataBegin + Desc.size();
std::vector<uint32_t> PALMetadata(PALMetadataBegin, PALMetadataEnd);
std::string PALMetadataString;
auto Error = AMDGPU::PALMD::toString(PALMetadata, PALMetadataString);
@@ -3859,7 +3858,7 @@ void GNUStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
auto ProcessNote = [&](const Elf_Note &Note) {
StringRef Name = Note.getName();
- ArrayRef<Elf_Word> Descriptor = Note.getDesc();
+ ArrayRef<uint8_t> Descriptor = Note.getDesc();
Elf_Word Type = Note.getType();
OS << " " << Name << std::string(22 - Name.size(), ' ')
@@ -4481,13 +4480,13 @@ void LLVMStyle<ELFT>::printAddrsig(const ELFFile<ELFT> *Obj) {
template <typename ELFT>
static void printGNUNoteLLVMStyle(uint32_t NoteType,
- ArrayRef<typename ELFT::Word> Words,
+ ArrayRef<uint8_t> Desc,
ScopedPrinter &W) {
switch (NoteType) {
default:
return;
case ELF::NT_GNU_ABI_TAG: {
- const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Words);
+ const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);
if (!AbiTag.IsValid) {
W.printString("ABI", "<corrupt GNU_ABI_TAG>");
} else {
@@ -4497,15 +4496,15 @@ static void printGNUNoteLLVMStyle(uint32_t NoteType,
break;
}
case ELF::NT_GNU_BUILD_ID: {
- W.printString("Build ID", getGNUBuildId<ELFT>(Words));
+ W.printString("Build ID", getGNUBuildId(Desc));
break;
}
case ELF::NT_GNU_GOLD_VERSION:
- W.printString("Version", getGNUGoldVersion<ELFT>(Words));
+ W.printString("Version", getGNUGoldVersion(Desc));
break;
case ELF::NT_GNU_PROPERTY_TYPE_0:
ListScope D(W, "Property");
- for (const auto &Property : getGNUPropertyList<ELFT>(Words))
+ for (const auto &Property : getGNUPropertyList<ELFT>(Desc))
W.printString(Property);
break;
}
@@ -4526,7 +4525,7 @@ void LLVMStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
auto ProcessNote = [&](const Elf_Note &Note) {
DictScope D2(W, "Note");
StringRef Name = Note.getName();
- ArrayRef<Elf_Word> Descriptor = Note.getDesc();
+ ArrayRef<uint8_t> Descriptor = Note.getDesc();
Elf_Word Type = Note.getType();
W.printString("Owner", Name);