From 84d18ae14eda81635e19c42495388d7f2c3b1fd0 Mon Sep 17 00:00:00 2001 From: Jake Ehrlich Date: Tue, 13 Nov 2018 01:10:35 +0000 Subject: [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 --- include/llvm/Object/ELFTypes.h | 11 +++--- test/tools/llvm-readobj/gnu-note-size.test | 32 ++++++++++++++++ tools/llvm-readobj/ELFDumper.cpp | 61 +++++++++++++++--------------- 3 files changed, 67 insertions(+), 37 deletions(-) create mode 100644 test/tools/llvm-readobj/gnu-note-size.test 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 getDesc() const { + ArrayRef getDesc() const { if (!Nhdr.n_descsz) - return ArrayRef(); - return ArrayRef( - reinterpret_cast( - reinterpret_cast(&Nhdr) + sizeof(Nhdr) + - alignTo::Align>(Nhdr.n_namesz)), + return ArrayRef(); + return ArrayRef( + reinterpret_cast(&Nhdr) + sizeof(Nhdr) + + alignTo::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: + +# 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: +# 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 static SmallVector -getGNUPropertyList(ArrayRef Words) { +getGNUPropertyList(ArrayRef Arr) { using Elf_Word = typename ELFT::Word; SmallVector Properties; - ArrayRef Arr(reinterpret_cast(Words.data()), - Words.size()); while (Arr.size() >= 8) { uint32_t Type = *reinterpret_cast(Arr.data()); uint32_t DataSize = *reinterpret_cast(Arr.data() + 4); @@ -3749,7 +3747,12 @@ struct GNUAbiTag { }; template -static GNUAbiTag getGNUAbiTag(ArrayRef Words) { +static GNUAbiTag getGNUAbiTag(ArrayRef Desc) { + typedef typename ELFT::Word Elf_Word; + + ArrayRef Words(reinterpret_cast(Desc.begin()), + reinterpret_cast(Desc.end())); + if (Words.size() < 4) return {"", "", /*IsValid=*/false}; @@ -3766,30 +3769,26 @@ static GNUAbiTag getGNUAbiTag(ArrayRef Words) { return {OSName, ABI.str(), /*IsValid=*/true}; } -template -static std::string getGNUBuildId(ArrayRef Words) { +static std::string getGNUBuildId(ArrayRef Desc) { std::string str; raw_string_ostream OS(str); - ArrayRef ID(reinterpret_cast(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 -static StringRef getGNUGoldVersion(ArrayRef Words) { - return StringRef(reinterpret_cast(Words.data()), Words.size()); +static StringRef getGNUGoldVersion(ArrayRef Desc) { + return StringRef(reinterpret_cast(Desc.data()), Desc.size()); } template static void printGNUNote(raw_ostream &OS, uint32_t NoteType, - ArrayRef Words) { + ArrayRef Desc) { switch (NoteType) { default: return; case ELF::NT_GNU_ABI_TAG: { - const GNUAbiTag &AbiTag = getGNUAbiTag(Words); + const GNUAbiTag &AbiTag = getGNUAbiTag(Desc); if (!AbiTag.IsValid) OS << " "; 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(Words); + OS << " Build ID: " << getGNUBuildId(Desc); break; } case ELF::NT_GNU_GOLD_VERSION: - OS << " Version: " << getGNUGoldVersion(Words); + OS << " Version: " << getGNUGoldVersion(Desc); break; case ELF::NT_GNU_PROPERTY_TYPE_0: OS << " Properties:"; - for (const auto &Property : getGNUPropertyList(Words)) + for (const auto &Property : getGNUPropertyList(Desc)) OS << " " << Property << "\n"; break; } @@ -3819,22 +3818,22 @@ struct AMDGPUNote { template static AMDGPUNote getAMDGPUNote(uint32_t NoteType, - ArrayRef Words) { + ArrayRef Desc) { switch (NoteType) { default: return {"", ""}; case ELF::NT_AMD_AMDGPU_HSA_METADATA: return {"HSA Metadata", - std::string(reinterpret_cast(Words.data()), - Words.size())}; + std::string(reinterpret_cast(Desc.data()), + Desc.size())}; case ELF::NT_AMD_AMDGPU_ISA: return {"ISA Version", - std::string(reinterpret_cast(Words.data()), - Words.size())}; + std::string(reinterpret_cast(Desc.data()), + Desc.size())}; case ELF::NT_AMD_AMDGPU_PAL_METADATA: const uint32_t *PALMetadataBegin = - reinterpret_cast(Words.data()); - const uint32_t *PALMetadataEnd = PALMetadataBegin + Words.size(); + reinterpret_cast(Desc.data()); + const uint32_t *PALMetadataEnd = PALMetadataBegin + Desc.size(); std::vector PALMetadata(PALMetadataBegin, PALMetadataEnd); std::string PALMetadataString; auto Error = AMDGPU::PALMD::toString(PALMetadata, PALMetadataString); @@ -3859,7 +3858,7 @@ void GNUStyle::printNotes(const ELFFile *Obj) { auto ProcessNote = [&](const Elf_Note &Note) { StringRef Name = Note.getName(); - ArrayRef Descriptor = Note.getDesc(); + ArrayRef Descriptor = Note.getDesc(); Elf_Word Type = Note.getType(); OS << " " << Name << std::string(22 - Name.size(), ' ') @@ -4481,13 +4480,13 @@ void LLVMStyle::printAddrsig(const ELFFile *Obj) { template static void printGNUNoteLLVMStyle(uint32_t NoteType, - ArrayRef Words, + ArrayRef Desc, ScopedPrinter &W) { switch (NoteType) { default: return; case ELF::NT_GNU_ABI_TAG: { - const GNUAbiTag &AbiTag = getGNUAbiTag(Words); + const GNUAbiTag &AbiTag = getGNUAbiTag(Desc); if (!AbiTag.IsValid) { W.printString("ABI", ""); } else { @@ -4497,15 +4496,15 @@ static void printGNUNoteLLVMStyle(uint32_t NoteType, break; } case ELF::NT_GNU_BUILD_ID: { - W.printString("Build ID", getGNUBuildId(Words)); + W.printString("Build ID", getGNUBuildId(Desc)); break; } case ELF::NT_GNU_GOLD_VERSION: - W.printString("Version", getGNUGoldVersion(Words)); + W.printString("Version", getGNUGoldVersion(Desc)); break; case ELF::NT_GNU_PROPERTY_TYPE_0: ListScope D(W, "Property"); - for (const auto &Property : getGNUPropertyList(Words)) + for (const auto &Property : getGNUPropertyList(Desc)) W.printString(Property); break; } @@ -4526,7 +4525,7 @@ void LLVMStyle::printNotes(const ELFFile *Obj) { auto ProcessNote = [&](const Elf_Note &Note) { DictScope D2(W, "Note"); StringRef Name = Note.getName(); - ArrayRef Descriptor = Note.getDesc(); + ArrayRef Descriptor = Note.getDesc(); Elf_Word Type = Note.getType(); W.printString("Owner", Name); -- cgit v1.2.3