diff options
author | Jake Ehrlich <jakehehrlich@google.com> | 2018-11-13 01:10:35 +0000 |
---|---|---|
committer | Jake Ehrlich <jakehehrlich@google.com> | 2018-11-13 01:10:35 +0000 |
commit | 84d18ae14eda81635e19c42495388d7f2c3b1fd0 (patch) | |
tree | 1b037ceec31839a47cc3cff4afe7b7e5ef69d5bb | |
parent | 7b60928bd7de2c0f32b98c71ad6f567276b5c301 (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.h | 11 | ||||
-rw-r--r-- | test/tools/llvm-readobj/gnu-note-size.test | 32 | ||||
-rw-r--r-- | tools/llvm-readobj/ELFDumper.cpp | 61 |
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); |