[llvm-branch-commits] [llvm] 9c89dcf - [yaml2obj, obj2yaml] - Implement section header table as a special Chunk.
Author: Georgii Rymar Date: 2021-01-25T13:08:08+03:00 New Revision: 9c89dcf80736a7c0710dc4c237ec35f0687e1efd URL: https://github.com/llvm/llvm-project/commit/9c89dcf80736a7c0710dc4c237ec35f0687e1efd DIFF: https://github.com/llvm/llvm-project/commit/9c89dcf80736a7c0710dc4c237ec35f0687e1efd.diff LOG: [yaml2obj, obj2yaml] - Implement section header table as a special Chunk. This was discussed in D93678 thread. Currently we have one special chunk - Fill. This patch re implements the "SectionHeaderTable" key to become a special chunk too. With that we are able to place the section header table at any location, just like we place sections. Differential revision: https://reviews.llvm.org/D95140 Added: Modified: llvm/include/llvm/ObjectYAML/ELFYAML.h llvm/lib/ObjectYAML/ELFEmitter.cpp llvm/lib/ObjectYAML/ELFYAML.cpp llvm/test/Object/obj2yaml.test llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test llvm/test/tools/llvm-readobj/ELF/dynamic-reloc-no-section-headers.test llvm/test/tools/llvm-readobj/ELF/file-headers.test llvm/test/tools/llvm-readobj/ELF/hash-table.test llvm/test/tools/llvm-readobj/ELF/malformed-pt-dynamic.test llvm/test/tools/llvm-readobj/ELF/symtab-shndx.test llvm/test/tools/obj2yaml/ELF/offset.yaml llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml llvm/test/tools/yaml2obj/ELF/section-headers.yaml llvm/test/tools/yaml2obj/ELF/verdef-section.yaml llvm/test/tools/yaml2obj/ELF/verneed-section.yaml llvm/test/tools/yaml2obj/ELF/versym-section.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index 98ba8cda372b..cae3b435f3b0 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -128,12 +128,6 @@ struct SectionHeader { StringRef Name; }; -struct SectionHeaderTable { - Optional> Sections; - Optional> Excluded; - Optional NoHeaders; -}; - struct Symbol { StringRef Name; ELF_STT Type; @@ -196,18 +190,26 @@ struct Chunk { ARMIndexTable, MipsABIFlags, Addrsig, -Fill, LinkerOptions, DependentLibraries, CallGraphProfile, -BBAddrMap +BBAddrMap, + +// Special chunks. +SpecialChunksStart, +Fill = SpecialChunksStart, +SectionHeaderTable, }; ChunkKind Kind; StringRef Name; Optional Offset; - Chunk(ChunkKind K) : Kind(K) {} + // Usually chunks are not created implicitly, but rather loaded from YAML. + // This flag is used to signal whether this is the case or not. + bool IsImplicit; + + Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {} virtual ~Chunk(); }; @@ -222,17 +224,14 @@ struct Section : public Chunk { Optional Content; Optional Size; - // Usually sections are not created implicitly, but loaded from YAML. - // When they are, this flag is used to signal about that. - bool IsImplicit; - // Holds the original section index. unsigned OriginalSecNdx; - Section(ChunkKind Kind, bool IsImplicit = false) - : Chunk(Kind), IsImplicit(IsImplicit) {} + Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {} - static bool classof(const Chunk *S) { return S->Kind != ChunkKind::Fill; } + static bool classof(const Chunk *S) { +return S->Kind < ChunkKind::SpecialChunksStart; + } // Some derived sections might have their own special entries. This method // returns a vector of pairs. It is used for section @@ -276,11 +275,34 @@ struct Fill : Chunk { Optional Pattern; llvm::yaml::Hex64 Size; - Fill() : Chunk(ChunkKind::Fill) {} + Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {} static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; } }; +struct SectionHeaderTable : Chunk { + SectionHeaderTable(bool IsImplicit) + : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {} + + static bool classof(const Chunk *S) { +return S->Kind == ChunkKind::SectionHeaderTable; + } + + Optional> Sections; + Optional> Excluded; + Optional NoHeaders; + + size_t getNumHeaders(size_t SectionsNum) const { +if (IsImplicit) + return SectionsNum; +if (NoHeaders) + return (*NoHeaders) ? 0 : SectionsNum; +return (Sections ? Sections->size() : 0) + /*Null section*/ 1; + } + + static constexpr StringRef TypeStr = "SectionHeaderTable"; +}; + struct BBAddrMapSection : Section { Optional> Entries; @@ -665,7 +687,6 @@ struct ProgramHeader { struct Object { FileHeader Header; - Optional SectionHeaders; std::vector ProgramHeaders; // An object might contain output section descriptions as well as @@ -688,6 +709,13 @@ struct Object { return Ret; } + const SectionHeaderTable &getSectionHeaderTable() const { +for (const std::unique_ptr &C : Chunks) + i
[llvm-branch-commits] [llvm] 19245b7 - [ObjectYAML] - An attempt to fix BB after commit of D95140.
Author: Georgii Rymar Date: 2021-01-25T13:26:06+03:00 New Revision: 19245b781576f36b85201b94a7c4a54c8f5dead3 URL: https://github.com/llvm/llvm-project/commit/19245b781576f36b85201b94a7c4a54c8f5dead3 DIFF: https://github.com/llvm/llvm-project/commit/19245b781576f36b85201b94a7c4a54c8f5dead3.diff LOG: [ObjectYAML] - An attempt to fix BB after commit of D95140. D95140 introduced `static constexpr StringRef TypeStr = "SectionHeaderTable";` member of `SectionHeaderTable` with in-class initialized. BB reports the link error: /usr/bin/ld: lib/libLLVMObjectYAML.a(ELFYAML.cpp.o): in function `llvm::yaml::MappingTraits > >::mapping(llvm::yaml::IO&, std::unique_ptr >&)': ELFYAML.cpp:(.text._ZN4llvm4yaml13MappingTraitsISt10unique_ptrINS_7ELFYAML5ChunkESt14default_deleteIS4_EEE7mappingERNS0_2IOERS7_+0x58): undefined reference to `llvm::ELFYAML::SectionHeaderTable::TypeStr' /usr/bin/ld: ELFYAML.cpp:(.text._ZN4llvm4yaml13MappingTraitsISt10unique_ptrINS_7ELFYAML5ChunkESt14default_deleteIS4_EEE7mappingERNS0_2IOERS7_+0x353):undefined reference to `llvm::ELFYAML::SectionHeaderTable::TypeStr' /usr/bin/ld: ELFYAML.cpp:(.text._ZN4llvm4yaml13MappingTraitsISt10unique_ptrINS_7ELFYAML5ChunkESt14default_deleteIS4_EEE7mappingERNS0_2IOERS7_+0x6e5): undefined reference to `llvm::ELFYAML::SectionHeaderTable::TypeStr' This patch adds a definition to cpp file, I guess it should fix the issue. Added: Modified: llvm/lib/ObjectYAML/ELFYAML.cpp Removed: diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index b81d9a81758a..05d30577812b 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -33,6 +33,8 @@ unsigned Object::getMachine() const { return *Header.Machine; return llvm::ELF::EM_NONE; } + +constexpr StringRef SectionHeaderTable::TypeStr; } // namespace ELFYAML namespace yaml { ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 141906f - [llvm-readelf/obj] - Add support of multiple SHT_SYMTAB_SHNDX sections.
Author: Georgii Rymar Date: 2021-01-13T11:36:43+03:00 New Revision: 141906fa149ffaa37bb5b65e9890ab1f0f3effd5 URL: https://github.com/llvm/llvm-project/commit/141906fa149ffaa37bb5b65e9890ab1f0f3effd5 DIFF: https://github.com/llvm/llvm-project/commit/141906fa149ffaa37bb5b65e9890ab1f0f3effd5.diff LOG: [llvm-readelf/obj] - Add support of multiple SHT_SYMTAB_SHNDX sections. Currently we don't support multiple SHT_SYMTAB_SHNDX sections and the DT_SYMTAB_SHNDX tag currently. This patch implements it and fixes the https://bugs.llvm.org/show_bug.cgi?id=43991. I had to introduce the `struct DataRegion` to ELF.h, it is used to represent a region that might have no known size. It is needed, because we don't know the size of the extended section indices table when it is located via DT_SYMTAB_SHNDX. In this case we still want to validate that we don't read past the end of the file. Differential revision: https://reviews.llvm.org/D92923 Added: llvm/test/tools/llvm-readobj/ELF/symtab-shndx.test Modified: llvm/include/llvm/Object/ELF.h llvm/test/Object/invalid.test llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test llvm/test/tools/llvm-readobj/ELF/mips-got.test llvm/test/tools/llvm-readobj/ELF/mips-plt.test llvm/test/tools/llvm-readobj/ELF/section-symbols.test llvm/test/tools/llvm-readobj/ELF/symbol-shndx.test llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml llvm/test/tools/yaml2obj/ELF/sht-symtab-shndx.yaml llvm/tools/llvm-readobj/ELFDumper.cpp llvm/unittests/Object/ELFTest.cpp Removed: diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h index bd224ada7783..86359ff44d56 100644 --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/include/llvm/Object/ELF.h @@ -57,6 +57,36 @@ enum PPCInstrMasks : uint64_t { template class ELFFile; +template struct DataRegion { + // This constructor is used when we know the start and the size of a data + // region. We assume that Arr does not go past the end of the file. + DataRegion(ArrayRef Arr) : First(Arr.data()), Size(Arr.size()) {} + + // Sometimes we only know the start of a data region. We still don't want to + // read past the end of the file, so we provide the end of a buffer. + DataRegion(const T *Data, const uint8_t *BufferEnd) + : First(Data), BufEnd(BufferEnd) {} + + Expected operator[](uint64_t N) { +assert(Size || BufEnd); +if (Size) { + if (N >= *Size) +return createError( +"the index is greater than or equal to the number of entries (" + +Twine(*Size) + ")"); +} else { + const uint8_t *EntryStart = (const uint8_t *)First + N * sizeof(T); + if (EntryStart + sizeof(T) > BufEnd) +return createError("can't read past the end of the file"); +} +return *(First + N); + } + + const T *First; + Optional Size = None; + const uint8_t *BufEnd = nullptr; +}; + template std::string getSecIndexForError(const ELFFile &Obj, const typename ELFT::Shdr &Sec) { @@ -99,6 +129,7 @@ class ELFFile { using WarningHandler = llvm::function_ref; const uint8_t *base() const { return Buf.bytes_begin(); } + const uint8_t *end() const { return base() + getBufSize(); } size_t getBufSize() const { return Buf.size(); } @@ -274,13 +305,13 @@ class ELFFile { Elf_Shdr_Range Sections, WarningHandler WarnHandler = &defaultWarningHandler) const; Expected getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms, - ArrayRef ShndxTable) const; + DataRegion ShndxTable) const; Expected getSection(const Elf_Sym &Sym, const Elf_Shdr *SymTab, -ArrayRef ShndxTable) const; +DataRegion ShndxTable) const; Expected getSection(const Elf_Sym &Sym, Elf_Sym_Range Symtab, -ArrayRef ShndxTable) const; +DataRegion ShndxTable) const; Expected getSection(uint32_t Index) const; Expected getSymbol(const Elf_Shdr *Sec, @@ -313,22 +344,25 @@ getSection(typename ELFT::ShdrRange Sections, uint32_t Index) { template inline Expected getExtendedSymbolTableIndex(const typename ELFT::Sym &Sym, unsigned SymIndex, -ArrayRef ShndxTable) { +DataRegion ShndxTable) { assert(Sym.st_shndx == ELF::SHN_XINDEX); - if (SymIndex >= ShndxTable.size()) + if (!ShndxTable.First) return createError( -"extended symbol index (" + Twine(SymIndex) + -") is past the end of the SHT_SYMTAB_SHNDX section of size " + -Twine(ShndxTable.size())); +"found an extended sym
[llvm-branch-commits] [llvm] 6d3098e - [obj2yaml, yaml2obj] - Refine how we set/dump the sh_entsize field.
Author: Georgii Rymar Date: 2021-01-13T11:52:40+03:00 New Revision: 6d3098e7ff968ad7d3033d7751af05a1fcd2ed9b URL: https://github.com/llvm/llvm-project/commit/6d3098e7ff968ad7d3033d7751af05a1fcd2ed9b DIFF: https://github.com/llvm/llvm-project/commit/6d3098e7ff968ad7d3033d7751af05a1fcd2ed9b.diff LOG: [obj2yaml,yaml2obj] - Refine how we set/dump the sh_entsize field. This reuses the code from yaml2obj (moves it to ELFYAML.h). With it we can set the `sh_entsize` in a single place in `obj2yaml`. Note that it also fixes a bug of `yaml2obj`: we do not set the `sh_entsize` field for the `SHT_ARM_EXIDX` section properly. Differential revision: https://reviews.llvm.org/D93858 Added: Modified: llvm/include/llvm/ObjectYAML/ELFYAML.h llvm/lib/ObjectYAML/ELFEmitter.cpp llvm/test/Object/obj2yaml.test llvm/test/tools/obj2yaml/ELF/call-graph-profile-section.yaml llvm/test/tools/obj2yaml/ELF/mips-abi-flags.yaml llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml llvm/test/tools/obj2yaml/ELF/versym-section.yaml llvm/test/tools/yaml2obj/ELF/arm-exidx-section.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index a838b69273ce..a289aab05b2c 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -16,6 +16,8 @@ #define LLVM_OBJECTYAML_ELFYAML_H #include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/Object/ELFTypes.h" #include "llvm/ObjectYAML/DWARFYAML.h" #include "llvm/ObjectYAML/YAML.h" #include "llvm/Support/YAMLTraits.h" @@ -69,6 +71,38 @@ LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA) LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString) LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt) +template +unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType, + StringRef SecName) { + if (EMachine == ELF::EM_MIPS && SecType == ELF::SHT_MIPS_ABIFLAGS) +return sizeof(object::Elf_Mips_ABIFlags); + + switch (SecType) { + case ELF::SHT_GROUP: +return sizeof(typename ELFT::Word); + case ELF::SHT_REL: +return sizeof(typename ELFT::Rel); + case ELF::SHT_RELA: +return sizeof(typename ELFT::Rela); + case ELF::SHT_RELR: +return sizeof(typename ELFT::Relr); + case ELF::SHT_DYNAMIC: +return sizeof(typename ELFT::Dyn); + case ELF::SHT_HASH: +return sizeof(typename ELFT::Word); + case ELF::SHT_SYMTAB_SHNDX: +return sizeof(typename ELFT::Word); + case ELF::SHT_GNU_versym: +return sizeof(typename ELFT::Half); + case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: +return sizeof(object::Elf_CGProfile_Impl); + default: +if (SecName == ".debug_str") + return 1; +return 0; + } +} + // For now, hardcode 64 bits everywhere that 32 or 64 would be needed // since 64-bit can hold 32-bit values too. struct FileHeader { diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index 181b130de621..ba0525c4a675 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -704,6 +704,12 @@ void ELFState::initSectionHeaders(std::vector &SHeaders, if (Sec->Link) SHeader.sh_link = toSectionIndex(*Sec->Link, Sec->Name); +if (Sec->EntSize) + SHeader.sh_entsize = *Sec->EntSize; +else + SHeader.sh_entsize = ELFYAML::getDefaultShEntSize( + Doc.Header.Machine.getValueOr(ELF::EM_NONE), Sec->Type, Sec->Name); + if (IsFirstUndefSection) { if (auto RawSec = dyn_cast(Sec)) { // We do not write any content for special SHN_UNDEF section. @@ -712,8 +718,6 @@ void ELFState::initSectionHeaders(std::vector &SHeaders, if (RawSec->Info) SHeader.sh_info = *RawSec->Info; } - if (Sec->EntSize) -SHeader.sh_entsize = *Sec->EntSize; LocationCounter += SHeader.sh_size; overrideFields(Sec, SHeader); @@ -1161,9 +1165,6 @@ template void ELFState::writeSectionContent( Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section, ContiguousBlobAccumulator &CBA) { - if (Section.EntSize) -SHeader.sh_entsize = *Section.EntSize; - if (Section.Info) SHeader.sh_info = *Section.Info; } @@ -1182,12 +1183,6 @@ void ELFState::writeSectionContent( Section.Type == llvm::ELF::SHT_RELA) && "Section type is not SHT_REL nor SHT_RELA"); - bool IsRela = Section.Type == llvm::ELF::SHT_RELA; - if (Section.EntSize) -SHeader.sh_entsize = *Section.EntSize; - else -SHeader.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); - // For relocation section set link to .symtab by default. unsigned Link = 0; if (!Section.Link && !ExcludedSectionHeaders.count(".symtab") && @@ -1200,6 +1195,7 @@ void ELFState::writeSectionContent( if (!Section.Relocations) return; + co
[llvm-branch-commits] [llvm] 1185d3f - [llvm-readobj] - Fix the compilation with GCC < 7.0.
Author: Georgii Rymar Date: 2021-01-15T11:58:04+03:00 New Revision: 1185d3f43d2186fa9291fe7779abf48d9b962ef4 URL: https://github.com/llvm/llvm-project/commit/1185d3f43d2186fa9291fe7779abf48d9b962ef4 DIFF: https://github.com/llvm/llvm-project/commit/1185d3f43d2186fa9291fe7779abf48d9b962ef4.diff LOG: [llvm-readobj] - Fix the compilation with GCC < 7.0. This addressed post commit comments for D93900. GCC had an issue and requires placing a specialization of `printUnwindInfo` to a namespace to compile: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480 Added: Modified: llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index e03a3d1edc7e..9351338590ae 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -2536,6 +2536,8 @@ template void ELFDumper::printUnwindInfo() { Ctx.printUnwindInformation(); } +// The namespace is needed to fix the compilation with GCC older than 7.0+. +namespace { template <> void ELFDumper::printUnwindInfo() { if (Obj.getHeader().e_machine == EM_ARM) { ARM::EHABI::PrinterContext Ctx(W, Obj, ObjF.getFileName(), @@ -2545,6 +2547,7 @@ template <> void ELFDumper::printUnwindInfo() { DwarfCFIEH::PrinterContext Ctx(W, ObjF); Ctx.printUnwindInformation(); } +} // namespace template void ELFDumper::printNeededLibraries() { ListScope D(W, "NeededLibraries"); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] bfb8f45 - [llvm-nm] - Move MachO specific logic out from the dumpSymbolNamesFromObject(). NFC.
Author: Georgii Rymar Date: 2021-01-15T12:18:37+03:00 New Revision: bfb8f45ef3f46102d290f11039faa82456c920ae URL: https://github.com/llvm/llvm-project/commit/bfb8f45ef3f46102d290f11039faa82456c920ae DIFF: https://github.com/llvm/llvm-project/commit/bfb8f45ef3f46102d290f11039faa82456c920ae.diff LOG: [llvm-nm] - Move MachO specific logic out from the dumpSymbolNamesFromObject(). NFC. `dumpSymbolNamesFromObject` is the method that dumps symbol names. It has 563 lines, mostly because of huge piece of MachO specific code. In this patch I move it to separate helper method. The new size of `dumpSymbolNamesFromObject` is 93 lines. With it it becomes much easier to maintain it. I had to change the type of 2 name fields to `std::string`, because MachO logic uses temporarily buffer strings (e.g `ExportsNameBuffer`, `BindsNameBuffer` etc): ``` std::string ExportsNameBuffer; raw_string_ostream EOS(ExportsNameBuffer); ``` these buffers were moved to `dumpSymbolsFromDLInfoMachO` by this patch and invalidated after return. Technically, before this patch we had a situation when local pointers (symbol names) were assigned to members of global static `SymbolList`, what is dirty by itself. Differential revision: https://reviews.llvm.org/D94667 Added: Modified: llvm/tools/llvm-nm/llvm-nm.cpp Removed: diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp index bbbf90db26f5..130201aac9dd 100644 --- a/llvm/tools/llvm-nm/llvm-nm.cpp +++ b/llvm/tools/llvm-nm/llvm-nm.cpp @@ -295,7 +295,7 @@ struct NMSymbol { uint64_t Address; uint64_t Size; char TypeChar; - StringRef Name; + std::string Name; StringRef SectionName; StringRef TypeName; BasicSymbolRef Sym; @@ -309,7 +309,7 @@ struct NMSymbol { uint8_t NType; uint8_t NSect; uint16_t NDesc; - StringRef IndirectName; + std::string IndirectName; }; } // anonymous namespace @@ -815,7 +815,7 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, for (const NMSymbol &S : SymbolList) { uint32_t SymFlags; -std::string Name = S.Name.str(); +std::string Name = S.Name; MachOObjectFile *MachO = dyn_cast(&Obj); if (Demangle) { if (Optional Opt = demangle(S.Name, MachO)) @@ -1219,6 +1219,473 @@ static unsigned getNsectInMachO(MachOObjectFile &Obj, BasicSymbolRef Sym) { return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0; } +static void dumpSymbolsFromDLInfoMachO(MachOObjectFile &MachO) { + size_t I = SymbolList.size(); + std::string ExportsNameBuffer; + raw_string_ostream EOS(ExportsNameBuffer); + std::string BindsNameBuffer; + raw_string_ostream BOS(BindsNameBuffer); + std::string LazysNameBuffer; + raw_string_ostream LOS(LazysNameBuffer); + std::string WeaksNameBuffer; + raw_string_ostream WOS(WeaksNameBuffer); + std::string FunctionStartsNameBuffer; + raw_string_ostream FOS(FunctionStartsNameBuffer); + + MachO::mach_header H; + MachO::mach_header_64 H_64; + uint32_t HFlags = 0; + if (MachO.is64Bit()) { +H_64 = MachO.MachOObjectFile::getHeader64(); +HFlags = H_64.flags; + } else { +H = MachO.MachOObjectFile::getHeader(); +HFlags = H.flags; + } + uint64_t BaseSegmentAddress = 0; + for (const auto &Command : MachO.load_commands()) { +if (Command.C.cmd == MachO::LC_SEGMENT) { + MachO::segment_command Seg = MachO.getSegmentLoadCommand(Command); + if (Seg.fileoff == 0 && Seg.filesize != 0) { +BaseSegmentAddress = Seg.vmaddr; +break; + } +} else if (Command.C.cmd == MachO::LC_SEGMENT_64) { + MachO::segment_command_64 Seg = MachO.getSegment64LoadCommand(Command); + if (Seg.fileoff == 0 && Seg.filesize != 0) { +BaseSegmentAddress = Seg.vmaddr; +break; + } +} + } + if (DyldInfoOnly || AddDyldInfo || + HFlags & MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO) { +unsigned ExportsAdded = 0; +Error Err = Error::success(); +for (const llvm::object::ExportEntry &Entry : MachO.exports(Err)) { + bool found = false; + bool ReExport = false; + if (!DyldInfoOnly) { +for (const NMSymbol &S : SymbolList) + if (S.Address == Entry.address() + BaseSegmentAddress && + S.Name == Entry.name()) { +found = true; +break; + } + } + if (!found) { +NMSymbol S = {}; +S.Address = Entry.address() + BaseSegmentAddress; +S.Size = 0; +S.TypeChar = '\0'; +S.Name = Entry.name().str(); +// There is no symbol in the nlist symbol table for this so we set +// Sym effectivly to null and the rest of code in here must test for +// it and not do things like Sym.getFlags() for it. +S.Sym = BasicSymbolRef(); +S.SymFlags = SymbolRef::SF_Global; +S.Section = SectionRef(); +S.NType = 0; +S.
[llvm-branch-commits] [llvm] 021ea78 - [llvm-nm] - Simplify the code in dumpSymbolNamesFromObject. NFC.
Author: Georgii Rymar Date: 2021-01-15T12:29:49+03:00 New Revision: 021ea78a97ed8f4796d92a61cdf62284def36f1e URL: https://github.com/llvm/llvm-project/commit/021ea78a97ed8f4796d92a61cdf62284def36f1e DIFF: https://github.com/llvm/llvm-project/commit/021ea78a97ed8f4796d92a61cdf62284def36f1e.diff LOG: [llvm-nm] - Simplify the code in dumpSymbolNamesFromObject. NFC. It is possible to simplify the logic that extracts symbol names. D94667 made the `NMSymbol::Name` to be `std::string`, what allowed this simplification. Differential revision: https://reviews.llvm.org/D94669 Added: Modified: llvm/tools/llvm-nm/llvm-nm.cpp Removed: diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp index 130201aac9dd..ccb54c3576fe 100644 --- a/llvm/tools/llvm-nm/llvm-nm.cpp +++ b/llvm/tools/llvm-nm/llvm-nm.cpp @@ -1698,8 +1698,7 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, } Symbols = E->getDynamicSymbolIterators(); } - std::string NameBuffer; - raw_string_ostream OS(NameBuffer); + // If a "-s segname sectname" option was specified and this is a Mach-O // file get the section number for that section in this object file. unsigned int Nsect = 0; @@ -1742,6 +1741,8 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, } S.TypeName = getNMTypeName(Obj, Sym); S.TypeChar = getNMSectionTagAndName(Obj, Sym, S.SectionName); + + raw_string_ostream OS(S.Name); if (Error E = Sym.printName(OS)) { if (MachO) { OS << "bad string index"; @@ -1749,20 +1750,11 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, } else error(std::move(E), Obj.getFileName()); } - OS << '\0'; S.Sym = Sym; SymbolList.push_back(S); } } - OS.flush(); - const char *P = NameBuffer.c_str(); - unsigned I; - for (I = 0; I < SymbolList.size(); ++I) { -SymbolList[I].Name = P; -P += strlen(P) + 1; - } - // If this is a Mach-O file where the nlist symbol table is out of sync // with the dyld export trie then look through exports and fake up symbols // for the ones that are missing (also done with the -add-dyldinfo flag). ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] d9afe85 - [yaml2obj/obj2yaml] - Refine handling of SHT_GNU_verdef sections.
Author: Georgii Rymar Date: 2021-01-15T12:40:42+03:00 New Revision: d9afe8588e49f1a2779ab1fe7ff2ec39e8d080fd URL: https://github.com/llvm/llvm-project/commit/d9afe8588e49f1a2779ab1fe7ff2ec39e8d080fd DIFF: https://github.com/llvm/llvm-project/commit/d9afe8588e49f1a2779ab1fe7ff2ec39e8d080fd.diff LOG: [yaml2obj/obj2yaml] - Refine handling of SHT_GNU_verdef sections. This patch: 1) Makes `Version`, `Flags`, `VersionNdx` and `Hash` fields to be `Optional<>`. 2) Disallows dumping version definitions that have `vd_version != 1`. `vd_version` identifies the version of the structure itself. (https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html, https://docs.oracle.com/cd/E19683-01/816-/chapter6-80869/index.html) 3) Stops dumping default values for `Version`, `Flags`, `VersionNdx` and `Hash` fields. 4) Refines testing. Differential revision: https://reviews.llvm.org/D94659 Added: Modified: llvm/include/llvm/ObjectYAML/ELFYAML.h llvm/lib/ObjectYAML/ELFEmitter.cpp llvm/lib/ObjectYAML/ELFYAML.cpp llvm/test/tools/obj2yaml/ELF/verdef-section.yaml llvm/test/tools/yaml2obj/ELF/verdef-section.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index a289aab05b2c..c9e90527380e 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -522,10 +522,10 @@ struct SymverSection : Section { }; struct VerdefEntry { - uint16_t Version; - uint16_t Flags; - uint16_t VersionNdx; - uint32_t Hash; + Optional Version; + Optional Flags; + Optional VersionNdx; + Optional Hash; std::vector VerNames; }; diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index ba0525c4a675..d4d61b22f1e1 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -1456,10 +1456,10 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::VerdefEntry &E = (*Section.Entries)[I]; Elf_Verdef VerDef; -VerDef.vd_version = E.Version; -VerDef.vd_flags = E.Flags; -VerDef.vd_ndx = E.VersionNdx; -VerDef.vd_hash = E.Hash; +VerDef.vd_version = E.Version.getValueOr(1); +VerDef.vd_flags = E.Flags.getValueOr(0); +VerDef.vd_ndx = E.VersionNdx.getValueOr(0); +VerDef.vd_hash = E.Hash.getValueOr(0); VerDef.vd_aux = sizeof(Elf_Verdef); VerDef.vd_cnt = E.VerNames.size(); if (I == Section.Entries->size() - 1) diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 3a280b06336d..20b52723b1e8 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1584,10 +1584,10 @@ void MappingTraits::mapping(IO &IO, ELFYAML::VerdefEntry &E) { assert(IO.getContext() && "The IO context is not initialized"); - IO.mapRequired("Version", E.Version); - IO.mapRequired("Flags", E.Flags); - IO.mapRequired("VersionNdx", E.VersionNdx); - IO.mapRequired("Hash", E.Hash); + IO.mapOptional("Version", E.Version); + IO.mapOptional("Flags", E.Flags); + IO.mapOptional("VersionNdx", E.VersionNdx); + IO.mapOptional("Hash", E.Hash); IO.mapRequired("Names", E.VerNames); } diff --git a/llvm/test/tools/obj2yaml/ELF/verdef-section.yaml b/llvm/test/tools/obj2yaml/ELF/verdef-section.yaml index 762b797ceb2b..cd6981c25df1 100644 --- a/llvm/test/tools/obj2yaml/ELF/verdef-section.yaml +++ b/llvm/test/tools/obj2yaml/ELF/verdef-section.yaml @@ -1,42 +1,37 @@ +## Check how we dump SHT_GNU_verdef sections. + # RUN: yaml2obj %s -o %t # RUN: obj2yaml %t | FileCheck %s -## Check we are able to yamalize SHT_GNU_verdef section. - -# CHECK: - Name:.gnu.version_d -# CHECK-NEXT: Type:SHT_GNU_verdef -# CHECK-NEXT: Flags: [ SHF_ALLOC ] -# CHECK-NEXT: Address: 0x230 -# CHECK-NEXT: Link:.dynstr -# CHECK-NEXT: AddressAlign:0x4 -# CHECK-NEXT: Info:0x4 -# CHECK-NEXT: Entries: -# CHECK-NEXT: - Version: 1 -# CHECK-NEXT: Flags: 1 -# CHECK-NEXT: VersionNdx: 1 -# CHECK-NEXT: Hash:170240160 -# CHECK-NEXT: Names: -# CHECK-NEXT: - dso.so.0 -# CHECK-NEXT: - Version: 1 -# CHECK-NEXT: Flags: 2 -# CHECK-NEXT: VersionNdx: 2 -# CHECK-NEXT: Hash:108387921 -# CHECK-NEXT: Names: -# CHECK-NEXT: - VERSION_1 -# CHECK-NEXT: - Version: 1 -# CHECK-NEXT: Flags: 3 -# CHECK-NEXT: VersionNdx: 3 -# CHECK-NEXT: Hash:108387922 -# CHECK-NEXT: Names: -# CHECK-NEXT: - VERSION_2 -# CHECK-NEXT: - VERSION_3 +# CHECK:
[llvm-branch-commits] [llvm] 45ef053 - [llvm-readobj][test] - Remove excessive YAML fields from tests.
Author: Georgii Rymar Date: 2021-01-15T12:46:39+03:00 New Revision: 45ef053bd70952d35e9bea58fc4af11d6e507ce2 URL: https://github.com/llvm/llvm-project/commit/45ef053bd70952d35e9bea58fc4af11d6e507ce2 DIFF: https://github.com/llvm/llvm-project/commit/45ef053bd70952d35e9bea58fc4af11d6e507ce2.diff LOG: [llvm-readobj][test] - Remove excessive YAML fields from tests. This removes excessive YAML keys from `SHT_GNU_verdef` sections. Those keys are set by default. Differential revision: https://reviews.llvm.org/D94660 Added: Modified: llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test llvm/test/tools/llvm-readobj/ELF/versioninfo.test Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test index d8ad0200316e..edb12d861862 100644 --- a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test +++ b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test @@ -308,16 +308,10 @@ Sections: AddressAlign: 0x4 Info: 0x2 Entries: - - Version:1 -Flags: 0 -VersionNdx: 2 -Hash: 0 + - VersionNdx: 2 Names: - Default - - Version:1 -Flags: 0 -VersionNdx: 3 -Hash: 0 + - VersionNdx: 3 Names: - NonDefault DynamicSymbols: diff --git a/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test b/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test index aa9b7b86e227..e7c93efed1a5 100644 --- a/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test +++ b/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test @@ -107,11 +107,7 @@ Sections: Link:.dynstr Info:0x1 Entries: - - Version:1 -Flags: 0 -VersionNdx: 0 -Hash: 0 -Names: + - Names: - FOO ShSize: 1 DynamicSymbols: @@ -137,11 +133,7 @@ Sections: Link:.dynstr Info:0x1 Entries: - - Version:1 -Flags: 0 -VersionNdx: 0 -Hash: 0 -Names: + - Names: - FOO ShSize: 21 DynamicSymbols: @@ -181,11 +173,7 @@ Sections: Link:.strtab Info:0x1 Entries: - - Version:1 -Flags: 0 -VersionNdx: 0 -Hash: 0 -Names: + - Names: - FOO - Name: .strtab Type: SHT_STRTAB @@ -213,11 +201,7 @@ Sections: Link: .dynstr Info: 0x1 Entries: - - Version:1 -Flags: 0 -VersionNdx: 0 -Hash: 0 -Names: + - Names: - FOO DynamicSymbols: - Name: foo @@ -266,10 +250,7 @@ Sections: Link: .dynstr Info: 0x1 Entries: - - Version:0xfefe -Flags: 0 -VersionNdx: 0 -Hash: 0 + - Version: 0xfefe Names: [] DynamicSymbols: - Name: foo diff --git a/llvm/test/tools/llvm-readobj/ELF/versioninfo.test b/llvm/test/tools/llvm-readobj/ELF/versioninfo.test index 071ad9a1a28f..38f1c6a02973 100644 --- a/llvm/test/tools/llvm-readobj/ELF/versioninfo.test +++ b/llvm/test/tools/llvm-readobj/ELF/versioninfo.test @@ -27,38 +27,23 @@ Sections: AddressAlign: 0x0004 Info: 0x0006 Entries: - - Version:1 -Flags: 0 -VersionNdx: 0 -Hash: 0 -Names: + - Names: - VERSION1 - - Version:1 -Flags: 1 -VersionNdx: 0 -Hash: 0 + - Flags: 1 Names: - VERSION1 - - Version:1 -Flags: 2 -VersionNdx: 0 -Hash: 0 + - Flags: 2 Names: - VERSION1 - - Version:1 -Flags: 4 -VersionNdx: 0 -Hash: 0 + - Flags: 4 Names: - VERSION1 - - Version:1 -Flags: 7 + - Flags: 7 VersionNdx: 2 Hash: 175630257 Names: - VERSION1 - - Version:1 -Flags: 8 + - Flags: 8 VersionNdx: 3 Hash: 175630258 Names: ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] b9ce772 - [Object, llvm-readelf] - Move the API for retrieving symbol versions to ELF.h
Author: Georgii Rymar Date: 2021-01-18T12:50:29+03:00 New Revision: b9ce772b8fb5d02afd026c9b029f5d53d1ea9591 URL: https://github.com/llvm/llvm-project/commit/b9ce772b8fb5d02afd026c9b029f5d53d1ea9591 DIFF: https://github.com/llvm/llvm-project/commit/b9ce772b8fb5d02afd026c9b029f5d53d1ea9591.diff LOG: [Object, llvm-readelf] - Move the API for retrieving symbol versions to ELF.h `ELFDumper.cpp` implements the functionality that allows to get symbol versions. It is used for dumping versioned symbols. This helps to implement https://bugs.llvm.org/show_bug.cgi?id=48670 ("make llvm-nm -D print version names"): we can move out and reuse the code from `ELFDumper.cpp`. This is what this patch do: it moves the related functionality to `ELFFile`. Differential revision: https://reviews.llvm.org/D94771 Added: Modified: llvm/include/llvm/Object/ELF.h llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h index 86359ff44d562..7ed124012a05d 100644 --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/include/llvm/Object/ELF.h @@ -30,6 +30,43 @@ namespace llvm { namespace object { +struct VerdAux { + unsigned Offset; + std::string Name; +}; + +struct VerDef { + unsigned Offset; + unsigned Version; + unsigned Flags; + unsigned Ndx; + unsigned Cnt; + unsigned Hash; + std::string Name; + std::vector AuxV; +}; + +struct VernAux { + unsigned Hash; + unsigned Flags; + unsigned Other; + unsigned Offset; + std::string Name; +}; + +struct VerNeed { + unsigned Version; + unsigned Cnt; + unsigned Offset; + std::string File; + std::vector AuxV; +}; + +struct VersionEntry { + std::string Name; + bool IsVerDef; +}; + StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type); uint32_t getELFRelativeRelocationType(uint32_t Machine); StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type); @@ -101,6 +138,16 @@ std::string getSecIndexForError(const ELFFile &Obj, return "[unknown index]"; } +template +static std::string describe(const ELFFile &Obj, +const typename ELFT::Shdr &Sec) { + unsigned SecNdx = &Sec - &cantFail(Obj.sections()).front(); + return (object::getELFSectionTypeName(Obj.getHeader().e_machine, +Sec.sh_type) + + " section with index " + Twine(SecNdx)) + .str(); +} + template std::string getPhdrIndexForError(const ELFFile &Obj, const typename ELFT::Phdr &Phdr) { @@ -148,12 +195,22 @@ class ELFFile { template Expected getEntry(const Elf_Shdr &Section, uint32_t Entry) const; + Expected> + getVersionDefinitions(const Elf_Shdr &Sec) const; + Expected> getVersionDependencies( + const Elf_Shdr &Sec, + WarningHandler WarnHandler = &defaultWarningHandler) const; + Expected getSymbolVersionByIndex( + uint32_t SymbolVersionIndex, bool &IsDefault, + SmallVector, 0> &VersionMap) const; + Expected getStringTable(const Elf_Shdr &Section, WarningHandler WarnHandler = &defaultWarningHandler) const; Expected getStringTableForSymtab(const Elf_Shdr &Section) const; Expected getStringTableForSymtab(const Elf_Shdr &Section, Elf_Shdr_Range Sections) const; + Expected getLinkAsStrtab(const typename ELFT::Shdr &Sec) const; Expected> getSHNDXTable(const Elf_Shdr &Section) const; Expected> getSHNDXTable(const Elf_Shdr &Section, @@ -171,6 +228,9 @@ class ELFFile { Expected getRelocationSymbol(const Elf_Rel &Rel, const Elf_Shdr *SymTab) const; + Expected, 0>> + loadVersionMap(const Elf_Shdr *VerNeedSec, const Elf_Shdr *VerDefSec) const; + static Expected create(StringRef Object); bool isLE() const { @@ -518,6 +578,43 @@ uint32_t ELFFile::getRelativeRelocationType() const { return getELFRelativeRelocationType(getHeader().e_machine); } +template +Expected, 0>> +ELFFile::loadVersionMap(const Elf_Shdr *VerNeedSec, + const Elf_Shdr *VerDefSec) const { + SmallVector, 0> VersionMap; + + // The first two version indexes are reserved. + // Index 0 is VER_NDX_LOCAL, index 1 is VER_NDX_GLOBAL. + VersionMap.push_back(VersionEntry()); + VersionMap.push_back(VersionEntry()); + + auto InsertEntry = [&](unsigned N, StringRef Version, bool IsVerdef) { +if (N >= VersionMap.size()) + VersionMap.resize(N + 1); +VersionMap[N] = {std::string(Version), IsVerdef}; + }; + + if (VerDefSec) { +Expected> Defs = getVersionDefinitions(*VerDefSec); +if (!Defs) + return Defs.takeError(); +for (const VerDef &Def : *Defs) + InsertEntry(Def.Ndx & ELF::VERSYM_VERSION, Def
[llvm-branch-commits] [llvm] 51f4958 - [yaml2obj/obj2yaml] - Improve dumping/creating of ELF versioning sections.
Author: Georgii Rymar Date: 2021-01-21T10:36:48+03:00 New Revision: 51f4958057d6c246e85c3fbc65353bc0d7c1049b URL: https://github.com/llvm/llvm-project/commit/51f4958057d6c246e85c3fbc65353bc0d7c1049b DIFF: https://github.com/llvm/llvm-project/commit/51f4958057d6c246e85c3fbc65353bc0d7c1049b.diff LOG: [yaml2obj/obj2yaml] - Improve dumping/creating of ELF versioning sections. This makes the following improvements. For `SHT_GNU_versym`: * yaml2obj: set `sh_link` to index of `.dynsym` section automatically. For `SHT_GNU_verdef`: * yaml2obj: set `sh_link` to index of `.dynstr` section automatically. * yaml2obj: set `sh_info` field automatically. * obj2yaml: don't dump the `Info` field when its value matches the number of version definitions. For `SHT_GNU_verneed`: * yaml2obj: set `sh_link` to index of `.dynstr` section automatically. * yaml2obj: set `sh_info` field automatically. * obj2yaml: don't dump the `Info` field when its value matches the number of version dependencies. Also, simplifies few test cases. Differential revision: https://reviews.llvm.org/D94956 Added: Modified: lld/test/ELF/invalid/verneed-shared.test llvm/include/llvm/ObjectYAML/ELFYAML.h llvm/lib/ObjectYAML/ELFEmitter.cpp llvm/lib/ObjectYAML/ELFYAML.cpp llvm/test/Object/invalid.test llvm/test/tools/llvm-objdump/ELF/verdef.test llvm/test/tools/llvm-objdump/ELF/verneed.test llvm/test/tools/llvm-readobj/ELF/all.test llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test llvm/test/tools/llvm-readobj/ELF/hidden-versym.test llvm/test/tools/llvm-readobj/ELF/merged.test llvm/test/tools/llvm-readobj/ELF/reloc-symbol-with-versioning.test llvm/test/tools/llvm-readobj/ELF/section-types.test llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test llvm/test/tools/llvm-readobj/ELF/verneed-flags.yaml llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test llvm/test/tools/llvm-readobj/ELF/versioninfo.test llvm/test/tools/llvm-readobj/ELF/versym-invalid.test llvm/test/tools/obj2yaml/ELF/verdef-section.yaml llvm/test/tools/obj2yaml/ELF/verneed-section.yaml llvm/test/tools/yaml2obj/ELF/override-shname.yaml llvm/test/tools/yaml2obj/ELF/override-shoffset.yaml llvm/test/tools/yaml2obj/ELF/override-shsize.yaml llvm/test/tools/yaml2obj/ELF/override-shtype.yaml llvm/test/tools/yaml2obj/ELF/verdef-section.yaml llvm/test/tools/yaml2obj/ELF/verneed-section.yaml llvm/test/tools/yaml2obj/ELF/versym-section.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/lld/test/ELF/invalid/verneed-shared.test b/lld/test/ELF/invalid/verneed-shared.test index 916b8c1a5d95..2e2ff494fb58 100644 --- a/lld/test/ELF/invalid/verneed-shared.test +++ b/lld/test/ELF/invalid/verneed-shared.test @@ -14,10 +14,9 @@ FileHeader: Type:ET_DYN Machine: EM_X86_64 Sections: - - Name: .gnu.version_r -Type: SHT_GNU_verneed -Flags: [ SHF_ALLOC ] -Info: 1 + - Name: .gnu.version_r +Type: SHT_GNU_verneed +Flags:[ SHF_ALLOC ] ShOffset: 0x ## A Verneed entry is misaligned (not a multiple of 4). This may happen @@ -37,8 +36,6 @@ Sections: - Name: .gnu.version_r Type: SHT_GNU_verneed Flags: [ SHF_ALLOC ] -Info: 1 -Link: .dynstr Dependencies: - Version: 1 File:foo @@ -65,7 +62,6 @@ Sections: Type: SHT_GNU_verneed Flags: [ SHF_ALLOC ] Info: 1 -Link: .dynstr Content: "[[VERNEED]]" DynamicSymbols: - Name: foo diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index c9e90527380e..98ba8cda372b 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -427,7 +427,7 @@ struct VerneedEntry { struct VerneedSection : Section { Optional> VerneedV; - llvm::yaml::Hex64 Info; + Optional Info; VerneedSection() : Section(ChunkKind::Verneed) {} @@ -531,8 +531,7 @@ struct VerdefEntry { struct VerdefSection : Section { Optional> Entries; - - llvm::yaml::Hex64 Info; + Optional Info; VerdefSection() : Section(ChunkKind::Verdef) {} diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index d4d61b22f1e1..752a037d61b1 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -1288,6 +1288,11 @@ template void ELFState::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::SymverSection &Section, ContiguousBlobAccumulator &CBA) { + unsigned Link = 0; + if (!Section.Link && !ExcludedSectionHeaders.count(".dynsym") && + SN2I.lookup(".dynsym", Link)) +SHeader.sh_link = Link; + if (!Section.Entries) return; @@ -1446,7 +1451,16 @@ template void ELFState::writeSectionContent(Elf_Shdr &SHeade
[llvm-branch-commits] [llvm] dd5c982 - [llvm-nm][ELF] - Make -D display symbol versions.
Author: Georgii Rymar Date: 2021-01-21T11:23:45+03:00 New Revision: dd5c98280473a7f74c5e5a715839e4938b46a69c URL: https://github.com/llvm/llvm-project/commit/dd5c98280473a7f74c5e5a715839e4938b46a69c DIFF: https://github.com/llvm/llvm-project/commit/dd5c98280473a7f74c5e5a715839e4938b46a69c.diff LOG: [llvm-nm][ELF] - Make -D display symbol versions. This fixes https://bugs.llvm.org/show_bug.cgi?id=48670. Since binutils 2.35, nm -D displays symbol versions by default. This patch teaches llvm-nm to do the same. Differential revision: https://reviews.llvm.org/D94907 Added: Modified: llvm/test/tools/llvm-nm/dynamic.test llvm/tools/llvm-nm/llvm-nm.cpp Removed: diff --git a/llvm/test/tools/llvm-nm/dynamic.test b/llvm/test/tools/llvm-nm/dynamic.test index 7c7ec8241ec7..9d91aacb5717 100644 --- a/llvm/test/tools/llvm-nm/dynamic.test +++ b/llvm/test/tools/llvm-nm/dynamic.test @@ -60,3 +60,106 @@ Sections: - Name: .dynsym Type: SHT_DYNSYM Size: 0 + +## Check we print symbol versions, when they are available. + +# RUN: yaml2obj --docnum=4 %s -o %t4.o +# RUN: llvm-nm --dynamic %t4.o 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t4.o --check-prefix=VERSIONED-SYMS + +# VERSIONED-SYMS: U globalversym +# VERSIONED-SYMS-NEXT: U localversym +# VERSIONED-SYMS-NEXT: U version2sym@v2 +# VERSIONED-SYMS-NEXT: U version3sym@v3hidden +# VERSIONED-SYMS-NEXT: U version4sym@v4 +# VERSIONED-SYMS-NEXT: U version5sym@v5hidden + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN +Sections: + - Name:.gnu.version +Type:SHT_GNU_versym +Flags: [ SHF_ALLOC ] +## 0x8000 is a special VERSYM_HIDDEN bit. +Entries: [ 0, 0, 1, [[VERSYMENTRY=2]], 0x8003, 4, 0x8005 ] +ShSize: [[VERSYMSIZE=]] + - Name: .gnu.version_d +Type: SHT_GNU_verdef +Flags:[ SHF_ALLOC ] +Link: .dynstr +AddressAlign: 0x4 +Info: 0x2 +ShOffset: [[VERDEFOFFSET=]] +Entries: + - VersionNdx: 2 +Names: + - v2 + - VersionNdx: 3 +Names: + - v3hidden + - Name: .gnu.version_r +Type: SHT_GNU_verneed +Flags: [ SHF_ALLOC ] +Link: .dynstr +Info: 0x2 +Dependencies: + - Version: 1 +File:file1.so +Entries: + - Name: v4 +Hash: 0 +Flags: 0 +Other: 4 + - Version: 1 +File:file2.0 +Entries: + - Name: v5hidden +Hash: 0 +Flags: 0 +Other: 5 +DynamicSymbols: + - Name: localversym + - Name: globalversym + - Name: version2sym + - Name: version3sym + - Name: version4sym + - Name: version5sym + +## In the following cases we check we report warnings when unable to read symbol version. +## Check that we still print unversioned symbol names. + +## Case 1: check we report a warning when unable to read symbol versions +## from a broken SHT_GNU_verdef section. In this case its sh_offset +## field has a too large value that goes past the EOF. + +# RUN: yaml2obj --docnum=4 -DVERDEFOFFSET=0x %s -o %t4-broken-verdef.o +# RUN: llvm-nm --dynamic %t4-broken-verdef.o 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t4-broken-verdef.o --check-prefixes=VERSION-ERR,VERSION-ERR1 + +# VERSION-ERR1: warning: unable to read symbol versions: cannot read content of SHT_GNU_verdef section with index 2: section [index 2] has a sh_offset (0x) + sh_size (0x38) that is greater than the file size (0x438) +# VERSION-ERR2: warning: unable to read symbol versions: unable to read an entry with index 1 from SHT_GNU_versym section with index 1: section [index 1] has an invalid sh_size (255) which is not a multiple of its sh_entsize (2) +# VERSION-ERR3: warning: unable to read symbol versions: unable to get a version for entry 3 of SHT_GNU_versym section with index 1: SHT_GNU_versym section refers to a version index 255 which is missing + +# VERSION-ERR-NEXT: U globalversym{{$}} +# VERSION-ERR-NEXT: U localversym{{$}} +# VERSION-ERR-NEXT: U version2sym{{$}} +# VERSION-ERR-NEXT: U version3sym{{$}} +# VERSION-ERR-NEXT: U version4sym{{$}} +# VERSION-ERR-NEXT: U version5sym{{$}} + +## Case 2: check we report a warning when we are unable to read a SHT_GNU_versym section entry. +## In this case, the section has a size that is not a multiple of its sh_entsize. + +# RUN: yaml2obj --docnum=4 -DVERSYMSIZE=0xff %s -o %t4-broken-versym.o +# RUN: llvm-nm --dynamic %t4-broken-versym.o 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t4-broken-versym.o --check-prefixes=VERSION-ERR,VERSION-ERR2 + +## Case 3: check we report a warning when we are unable to get a vesrion for a SHT_GNU_versym section entry. +## In this case the SHT_GNU_versym section refers to a version index 255 which is missing. + +# RUN: yaml2obj --docnum=4 -DVERSYMENTRY=0xff %s -o %t4-broken-index.o +# RUN: llvm-n
[llvm-branch-commits] [lld] ed146d6 - [LLD][ELF] - Use LLVM_ELF_IMPORT_TYPES_ELFT instead of multiple types definitions. NFCI.
Author: Georgii Rymar Date: 2020-12-29T10:50:07+03:00 New Revision: ed146d6291ce510ef954d350e2ca5a107890c2d2 URL: https://github.com/llvm/llvm-project/commit/ed146d6291ce510ef954d350e2ca5a107890c2d2 DIFF: https://github.com/llvm/llvm-project/commit/ed146d6291ce510ef954d350e2ca5a107890c2d2.diff LOG: [LLD][ELF] - Use LLVM_ELF_IMPORT_TYPES_ELFT instead of multiple types definitions. NFCI. We can reduce the number of "using" declarations. `LLVM_ELF_IMPORT_TYPES_ELFT` was extended in D93801. Differential revision: https://reviews.llvm.org/D93856 Added: Modified: lld/ELF/InputFiles.h lld/ELF/SyntheticSections.h lld/ELF/Writer.cpp Removed: diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 7ffe4c29cb87..cdd6b5c2ce99 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -189,12 +189,7 @@ class ELFFileBase : public InputFile { // .o file. template class ObjFile : public ELFFileBase { - using Elf_Rel = typename ELFT::Rel; - using Elf_Rela = typename ELFT::Rela; - using Elf_Sym = typename ELFT::Sym; - using Elf_Shdr = typename ELFT::Shdr; - using Elf_Word = typename ELFT::Word; - using Elf_CGProfile = typename ELFT::CGProfile; + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) public: static bool classof(const InputFile *f) { return f->kind() == ObjKind; } diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 8943596179c1..c20386cc20da 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -461,12 +461,7 @@ class DynamicReloc { }; template class DynamicSection final : public SyntheticSection { - using Elf_Dyn = typename ELFT::Dyn; - using Elf_Rel = typename ELFT::Rel; - using Elf_Rela = typename ELFT::Rela; - using Elf_Relr = typename ELFT::Relr; - using Elf_Shdr = typename ELFT::Shdr; - using Elf_Sym = typename ELFT::Sym; + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) // finalizeContents() fills this vector with the section contents. std::vector>> entries; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 98139b56b29b..0397dae8f891 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -45,10 +45,9 @@ namespace { // The writer writes a SymbolTable result to a file. template class Writer { public: + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) + Writer() : buffer(errorHandler().outputBuffer) {} - using Elf_Shdr = typename ELFT::Shdr; - using Elf_Ehdr = typename ELFT::Ehdr; - using Elf_Phdr = typename ELFT::Phdr; void run(); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] c74751d - [obj2yaml] - Fix the crash in getUniquedSectionName().
Author: Georgii Rymar Date: 2021-01-11T15:04:00+03:00 New Revision: c74751d4b5bd8e6753ba8dbc5baa88d7c8929c5c URL: https://github.com/llvm/llvm-project/commit/c74751d4b5bd8e6753ba8dbc5baa88d7c8929c5c DIFF: https://github.com/llvm/llvm-project/commit/c74751d4b5bd8e6753ba8dbc5baa88d7c8929c5c.diff LOG: [obj2yaml] - Fix the crash in getUniquedSectionName(). `getUniquedSectionName(const Elf_Shdr *Sec)` assumes that `Sec` is not `nullptr`. I've found one place in `getUniquedSymbolName` where it is not true (because of that we crash when trying to dump unnamed null section symbols). Patch fixes the crash and changes the signature of the `getUniquedSectionName` section to accept a reference. Differential revision: https://reviews.llvm.org/D93754 Added: Modified: llvm/test/tools/obj2yaml/ELF/symbol.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/test/tools/obj2yaml/ELF/symbol.yaml b/llvm/test/tools/obj2yaml/ELF/symbol.yaml index 3684d4f70c6c..3afe2d13d162 100644 --- a/llvm/test/tools/obj2yaml/ELF/symbol.yaml +++ b/llvm/test/tools/obj2yaml/ELF/symbol.yaml @@ -25,3 +25,44 @@ Symbols: - Name: bar Size: 0x1 Value: 0x1 + +## Check how we dump unnamed section symbols. +## Check we are able to handle the section symbol for the null section. +## Document we name them with a section name they describe. + +# RUN: yaml2obj --docnum=2 %s -o %t2 +# RUN: obj2yaml %t2 | FileCheck %s --check-prefix=SECTION-SYM + +# SECTION-SYM: --- !ELF +# SECTION-SYM-NEXT: FileHeader: +# SECTION-SYM-NEXT: Class: ELFCLASS64 +# SECTION-SYM-NEXT: Data: ELFDATA2LSB +# SECTION-SYM-NEXT: Type: ET_REL +# SECTION-SYM-NEXT: Sections: +# SECTION-SYM-NEXT: - Name: .section +# SECTION-SYM-NEXT: Type: SHT_PROGBITS +# SECTION-SYM-NEXT: Symbols: +# SECTION-SYM-NEXT: - Type: STT_SECTION +# SECTION-SYM-NEXT: - Name:.section +# SECTION-SYM-NEXT: Type:STT_SECTION +# SECTION-SYM-NEXT: Section: .section +# SECTION-SYM-NEXT: - Name:.section +# SECTION-SYM-NEXT: Type:STT_SECTION +# SECTION-SYM-NEXT: Section: .section +# SECTION-SYM-NEXT: ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL +Sections: + - Name: .section +Type: SHT_PROGBITS +Symbols: + - Type: STT_SECTION +Index: 0 + - Type: STT_SECTION +Index: 1 + - Type: STT_SECTION +Index: 1 diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index da32eaba5a69..dacbaaf482c0 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -37,7 +37,7 @@ class ELFDumper { BumpPtrAllocator StringAllocator; - Expected getUniquedSectionName(const Elf_Shdr *Sec); + Expected getUniquedSectionName(const Elf_Shdr &Sec); Expected getUniquedSymbolName(const Elf_Sym *Sym, StringRef StrTable, const Elf_Shdr *SymTab); @@ -115,13 +115,12 @@ ELFDumper::ELFDumper(const object::ELFFile &O, template Expected -ELFDumper::getUniquedSectionName(const Elf_Shdr *Sec) { - unsigned SecIndex = Sec - &Sections[0]; - assert(&Sections[SecIndex] == Sec); +ELFDumper::getUniquedSectionName(const Elf_Shdr &Sec) { + unsigned SecIndex = &Sec - &Sections[0]; if (!SectionNames[SecIndex].empty()) return SectionNames[SecIndex]; - auto NameOrErr = Obj.getSectionName(*Sec); + auto NameOrErr = Obj.getSectionName(Sec); if (!NameOrErr) return NameOrErr; StringRef Name = *NameOrErr; @@ -150,10 +149,12 @@ ELFDumper::getUniquedSymbolName(const Elf_Sym *Sym, StringRef StrTable, return SymbolNameOrErr; StringRef Name = *SymbolNameOrErr; if (Name.empty() && Sym->getType() == ELF::STT_SECTION) { -auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab)); +Expected ShdrOrErr = +Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab)); if (!ShdrOrErr) return ShdrOrErr.takeError(); -return getUniquedSectionName(*ShdrOrErr); +// The null section has no name. +return (*ShdrOrErr == nullptr) ? "" : getUniquedSectionName(**ShdrOrErr); } // Symbols in .symtab can have duplicate names. For example, it is a common @@ -678,7 +679,7 @@ Error ELFDumper::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab, if (!Shdr) return Error::success(); - auto NameOrErr = getUniquedSectionName(Shdr); + auto NameOrErr = getUniquedSectionName(*Shdr); if (!NameOrErr) return NameOrErr.takeError(); S.Section = NameOrErr.get(); @@ -755,7 +756,7 @@ Error ELFDumper::dumpCommonSection(const Elf_Shdr *Shdr, S.OriginalSecNdx = Shdr - &Sections[0]; - auto NameOrErr = getUniquedSectionName(Shdr); + Expected NameOrErr = getUniquedSectionName(*Shdr); if (!NameOrErr) return NameOrErr.takeError(); S.Name = NameOrErr.get(); @@ -764,14 +765,14 @@ Er
[llvm-branch-commits] [llvm] a6db7cf - [llvm-readelf/obj] - Index phdrs and relocations from 0 when reporting warnings.
Author: Georgii Rymar Date: 2021-01-11T15:13:54+03:00 New Revision: a6db7cf1ce7f3523adb132819c1697a572bdcfde URL: https://github.com/llvm/llvm-project/commit/a6db7cf1ce7f3523adb132819c1697a572bdcfde DIFF: https://github.com/llvm/llvm-project/commit/a6db7cf1ce7f3523adb132819c1697a572bdcfde.diff LOG: [llvm-readelf/obj] - Index phdrs and relocations from 0 when reporting warnings. As was mentioned in comments here: https://reviews.llvm.org/D92636#inline-864967 we are not consistent and sometimes index things from 0, but sometimes from 1 in warnings. This patch fixes 2 places: messages reported for program headers and messages reported for relocations. Differential revision: https://reviews.llvm.org/D93805 Added: Modified: llvm/test/tools/llvm-readobj/ELF/gnu-notes.test llvm/test/tools/llvm-readobj/ELF/note-core-ntfile-bad.test llvm/test/tools/llvm-readobj/ELF/relocation-errors.test llvm/test/tools/llvm-readobj/ELF/relocations.test llvm/test/tools/llvm-readobj/ELF/stack-sizes.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test b/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test index 4a5cb1a38473..83b5be8ac57d 100644 --- a/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test +++ b/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test @@ -172,7 +172,7 @@ Sections: # ERR3-GNU: Displaying notes found at file offset 0x with length 0x: # ERR3-GNU-NEXT: OwnerData sizeDescription -# ERR3-GNU-NEXT: warning: '[[FILE]]': unable to read notes from the PT_NOTE segment with index 1: invalid offset (0x) or size (0x0) +# ERR3-GNU-NEXT: warning: '[[FILE]]': unable to read notes from the PT_NOTE segment with index 0: invalid offset (0x) or size (0x0) # ERR3-GNU-NOT: {{.}} # ERR3-LLVM: Notes [ @@ -180,7 +180,7 @@ Sections: # ERR3-LLVM-NEXT: Name: # ERR3-LLVM-NEXT: Offset: 0x # ERR3-LLVM-NEXT: Size: 0x0 -# ERR3-LLVM-NEXT: warning: '[[FILE]]': unable to read notes from the PT_NOTE segment with index 1: invalid offset (0x) or size (0x0) +# ERR3-LLVM-NEXT: warning: '[[FILE]]': unable to read notes from the PT_NOTE segment with index 0: invalid offset (0x) or size (0x0) # ERR3-LLVM-NEXT: } # ERR3-LLVM-NEXT: ] @@ -203,7 +203,7 @@ ProgramHeaders: # ERR4-GNU: Displaying notes found at file offset 0x with length 0x: # ERR4-GNU-NEXT: OwnerData sizeDescription -# ERR4-GNU-NEXT: warning: '[[FILE]]': unable to read notes from the PT_NOTE segment with index 1: invalid offset (0x0) or size (0x) +# ERR4-GNU-NEXT: warning: '[[FILE]]': unable to read notes from the PT_NOTE segment with index 0: invalid offset (0x0) or size (0x) # ERR4-GNU-NOT: {{.}} # ERR4-LLVM: Notes [ @@ -211,7 +211,7 @@ ProgramHeaders: # ERR4-LLVM-NEXT: Name: # ERR4-LLVM-NEXT: Offset: 0x0 # ERR4-LLVM-NEXT: Size: 0x -# ERR4-LLVM-NEXT: warning: '[[FILE]]': unable to read notes from the PT_NOTE segment with index 1: invalid offset (0x0) or size (0x) +# ERR4-LLVM-NEXT: warning: '[[FILE]]': unable to read notes from the PT_NOTE segment with index 0: invalid offset (0x0) or size (0x) # ERR4-LLVM-NEXT: } # ERR4-LLVM-NEXT: ] diff --git a/llvm/test/tools/llvm-readobj/ELF/note-core-ntfile-bad.test b/llvm/test/tools/llvm-readobj/ELF/note-core-ntfile-bad.test index 5a497c23a795..92553aa05596 100644 --- a/llvm/test/tools/llvm-readobj/ELF/note-core-ntfile-bad.test +++ b/llvm/test/tools/llvm-readobj/ELF/note-core-ntfile-bad.test @@ -11,7 +11,7 @@ # RUN: llvm-readelf -n %t1.o 2>&1 | FileCheck -DFILE=%t1.o %s --check-prefix=ERR-HEADER-SHORT # RUN: llvm-readobj -n %t1.o 2>&1 | FileCheck -DFILE=%t1.o %s --check-prefix=ERR-HEADER-SHORT -# ERR-HEADER-SHORT: warning: '[[FILE]]': unable to read note with index 0 from the PT_NOTE segment with index 1: the note of size 0x8 is too short, expected at least 0x10 +# ERR-HEADER-SHORT: warning: '[[FILE]]': unable to read note with index 0 from the PT_NOTE segment with index 0: the note of size 0x8 is too short, expected at least 0x10 # .section ".note.foo", "a" # .align 4 @@ -42,7 +42,7 @@ ProgramHeaders: # RUN: llvm-readelf -n %t2.o 2>&1 | FileCheck -DFILE=%t2.o %s --check-prefix=ERR-NULL-TERM # RUN: llvm-readobj -n %t2.o 2>&1 | FileCheck -DFILE=%t2.o %s --check-prefix=ERR-NULL-TERM -# ERR-NULL-TERM: warning: '[[FILE]]': unable to read note with index 0 from the PT_NOTE segment with index 1: the note is not NUL terminated +# ERR-NULL-TERM: warning: '[[FILE]]': unable to read note with index 0 from the PT_NOTE segment with index 0: the note is not NUL terminated # .section ".note.foo", "a" # .align 4 @@ -78,7 +78,7 @@ ProgramHeaders: # RUN: llvm-readelf -n %t3.o 2>&1 | FileCheck -DFILE=
[llvm-branch-commits] [llvm] a5b484c - [obj2yaml][test] - Improve and fix section-group.yaml test.
Author: Georgii Rymar Date: 2021-01-11T15:24:21+03:00 New Revision: a5b484c4d41a7452b590a2c1c98dc31f43d3dc1a URL: https://github.com/llvm/llvm-project/commit/a5b484c4d41a7452b590a2c1c98dc31f43d3dc1a DIFF: https://github.com/llvm/llvm-project/commit/a5b484c4d41a7452b590a2c1c98dc31f43d3dc1a.diff LOG: [obj2yaml][test] - Improve and fix section-group.yaml test. It has multiple issues fixed by this patch: 1) It shouldn't test how llvm-readelf/yaml2obj works. 2) It should use "-NEXT" prefix for check lines. 3) It can use YAML macros, that allows to use a single YAML. 4) It should probably test the case when a group member is a null section. Differential revision: https://reviews.llvm.org/D93753 Added: Modified: llvm/test/tools/obj2yaml/ELF/section-group.yaml Removed: diff --git a/llvm/test/tools/obj2yaml/ELF/section-group.yaml b/llvm/test/tools/obj2yaml/ELF/section-group.yaml index aba787ff59ac..33044ceeb36c 100644 --- a/llvm/test/tools/obj2yaml/ELF/section-group.yaml +++ b/llvm/test/tools/obj2yaml/ELF/section-group.yaml @@ -1,30 +1,17 @@ ## Checks that the tool is able to read section groups from ELF. -# RUN: yaml2obj --docnum=1 %s -o %t1.o -# RUN: llvm-readobj --elf-section-groups %t1.o | FileCheck %s -check-prefix=OBJ -# RUN: obj2yaml %t1.o | FileCheck %s --check-prefix YAML - -# OBJ: Groups { -# OBJ-NEXT: Group { -# OBJ-NEXT: Name: .group -# OBJ-NEXT: Index: 1 -# OBJ-NEXT: Link: 3 -# OBJ-NEXT: Info: 1 -# OBJ-NEXT: Type: COMDAT (0x1) -# OBJ-NEXT: Signature: signature -# OBJ-NEXT: Section(s) in group [ -# OBJ-NEXT: .rodata (2) -# OBJ-NEXT: ] -# OBJ-NEXT: } -# OBJ-NEXT: } - -# YAML: - Name: .group -# YAML: Type: SHT_GROUP -# YAML: Link: .symtab -# YAML: Info: signature -# YAML: Members: -# YAML: - SectionOrType: GRP_COMDAT -# YAML: - SectionOrType: .rodata +# RUN: yaml2obj %s -o %t1.o +# RUN: obj2yaml %t1.o | FileCheck %s -DSEC=.rodata + +# CHECK: - Name:.group +# CHECK-NEXT: Type:SHT_GROUP +# CHECK-NEXT: Link:.symtab +# CHECK-NEXT: EntSize: 0x4 +# CHECK-NEXT: Info:signature +# CHECK-NEXT: Members: +# CHECK-NEXT: - SectionOrType: GRP_COMDAT +# CHECK-NEXT: - SectionOrType: [[SEC]] +# CHECK-NEXT: - Name: --- !ELF FileHeader: @@ -35,10 +22,10 @@ Sections: - Name: .group Type: SHT_GROUP Link: .symtab -Info: signature +Info: [[INFO=signature]] Members: - SectionOrType: GRP_COMDAT - - SectionOrType: .rodata + - SectionOrType: [[SEC=.rodata]] - Name: .rodata Type: SHT_PROGBITS Symbols: @@ -46,24 +33,16 @@ Symbols: Type:STT_OBJECT Section: .rodata +## Check we are able to dump members of the SHT_GROUP section even when +## one of them has section index 0. + +# RUN: yaml2obj -DSEC=0 %s -o %tnull.o +# RUN: obj2yaml %tnull.o | FileCheck %s -DSEC="''" + ## Check obj2yaml report an error when sh_info field of ## group section contains invalid (too large) signature symbol index. -# RUN: yaml2obj --docnum=2 %s -o %t2.o -# RUN: not obj2yaml %t2.o 2>&1 | FileCheck %s --check-prefix ERR - !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL -Sections: - - Name: .group -Type: SHT_GROUP -Link: .symtab -Info: 0xFF -Members: - - SectionOrType: GRP_COMDAT -Symbols: [] +# RUN: yaml2obj -DINFO=0xFF %s -o %t2.o +# RUN: not obj2yaml %t2.o 2>&1 | FileCheck %s -DFILE=%t2.o --check-prefix=ERR -# ERR: Error reading file: {{.*}}2.o: unable to get symbol from section [index 2]: invalid symbol index (255) +# ERR: Error reading file: [[FILE]]: unable to get symbol from section [index 3]: invalid symbol index (255) ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 9ec72cf - [llvm-readef/obj] - Change the design structure of ELF dumper. NFCI.
Author: Georgii Rymar Date: 2021-01-12T12:36:17+03:00 New Revision: 9ec72cfc61ad5d87bb9e719b8b01f56e4da88a5b URL: https://github.com/llvm/llvm-project/commit/9ec72cfc61ad5d87bb9e719b8b01f56e4da88a5b DIFF: https://github.com/llvm/llvm-project/commit/9ec72cfc61ad5d87bb9e719b8b01f56e4da88a5b.diff LOG: [llvm-readef/obj] - Change the design structure of ELF dumper. NFCI. This is a refactoring for design of stuff in `ELFDumper.cpp`. The current design of ELF dumper is far from ideal. Currently most overridden functions (inherited from `ObjDumper`) in `ELFDumper` just forward to the functions of `ELFDumperStyle` (which can be either `GNUStyle` or `LLVMStyle`). A concrete implementation may be in any of `ELFDumper`/`DumperStyle`/`GNUStyle`/`LLVMStyle`. This patch reorganizes the classes by introducing `GNUStyleELFDumper`/`LLVMStyleELFDumper` which inherit from `ELFDumper`. The implementations are moved: `DumperStyle` -> `ELFDumper` `GNUStyle` -> `GNUStyleELFDumper` `LLVMStyle` -> `LLVMStyleELFDumper` With that we can avoid having a lot of redirection calls and helper methods. The number of code lines changes from 7142 to 6922 (reduced by ~3%) and the code overall looks cleaner. Differential revision: https://reviews.llvm.org/D93900 Added: Modified: llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index ca8f84728496..a09ee6d630d7 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -82,8 +82,6 @@ using namespace ELF; namespace { -template class DumpStyle; - template struct RelSymbol { RelSymbol(const typename ELFT::Sym *S, StringRef N) : Sym(S), Name(N.str()) {} @@ -232,50 +230,120 @@ template class Relocation { Optional Addend; }; +template class MipsGOTParser; + template class ELFDumper : public ObjDumper { + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) + public: ELFDumper(const object::ELFObjectFile &ObjF, ScopedPrinter &Writer); - void printFileHeaders() override; - void printSectionHeaders() override; - void printRelocations() override; - void printDependentLibs() override; - void printDynamicRelocations() override; - void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) override; - void printHashSymbols() override; - void printSectionDetails() override; void printUnwindInfo() override; - - void printDynamicTable() override; void printNeededLibraries() override; - void printProgramHeaders(bool PrintProgramHeaders, - cl::boolOrDefault PrintSectionMapping) override; void printHashTable() override; void printGnuHashTable() override; void printLoadName() override; void printVersionInfo() override; - void printGroupSections() override; - void printArchSpecificInfo() override; - void printStackMap() const override; - void printHashHistograms() override; + const object::ELFObjectFile &getElfObject() const { return ObjF; }; - void printCGProfile() override; - void printAddrsig() override; + std::string describe(const Elf_Shdr &Sec) const; - void printNotes() override; + unsigned getHashTableEntSize() const { +// EM_S390 and ELF::EM_ALPHA platforms use 8-bytes entries in SHT_HASH +// sections. This violates the ELF specification. +if (Obj.getHeader().e_machine == ELF::EM_S390 || +Obj.getHeader().e_machine == ELF::EM_ALPHA) + return 8; +return 4; + } - void printELFLinkerOptions() override; - void printStackSizes() override; + Elf_Dyn_Range dynamic_table() const { +// A valid .dynamic section contains an array of entries terminated +// with a DT_NULL entry. However, sometimes the section content may +// continue past the DT_NULL entry, so to dump the section correctly, +// we first find the end of the entries by iterating over them. +Elf_Dyn_Range Table = DynamicTable.getAsArrayRef(); - const object::ELFObjectFile &getElfObject() const { return ObjF; }; +size_t Size = 0; +while (Size < Table.size()) + if (Table[Size++].getTag() == DT_NULL) +break; -private: - std::unique_ptr> ELFDumperStyle; +return Table.slice(0, Size); + } - LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) + Elf_Sym_Range dynamic_symbols() const { +if (!DynSymRegion) + return Elf_Sym_Range(); +return DynSymRegion->getAsArrayRef(); + } + + const Elf_Shdr *findSectionByName(StringRef Name) const; + + StringRef getDynamicStringTable() const { return DynamicStringTable; } + +protected: + virtual void printVersionSymbolSection(const Elf_Shdr *Sec) = 0; + virtual void printVersionDefinitionSection(const Elf_Shdr *Sec) = 0; + virtual void printVersionDependencySection(const Elf_Shdr *Sec) = 0; + + void + printDependentLibsHelper(function_ref OnSectionStart, + function_ref OnLibEntry);
[llvm-branch-commits] [llvm] 1e11402 - [llvm-readobj] - Add 'override' to fix build bots.
Author: Georgii Rymar Date: 2021-01-12T13:01:15+03:00 New Revision: 1e11402aa8e25d88c095a1c70fc87d2d9775186b URL: https://github.com/llvm/llvm-project/commit/1e11402aa8e25d88c095a1c70fc87d2d9775186b DIFF: https://github.com/llvm/llvm-project/commit/1e11402aa8e25d88c095a1c70fc87d2d9775186b.diff LOG: [llvm-readobj] - Add 'override' to fix build bots. This should fix bots after landing D93900. An example of error is: /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/llvm/tools/llvm-readobj/ELFDumper.cpp:883:8: warning: 'printSectionMapping' overrides a member function but is not marked 'override' [-Winconsistent-missing-override] void printSectionMapping() {} Added: Modified: llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index a09ee6d630d7..44608b8c9a06 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -831,8 +831,8 @@ template class GNUELFDumper : public ELFDumper { std::string getSymbolSectionNdx(const Elf_Sym &Symbol, unsigned SymIndex) const; - void printProgramHeaders(); - void printSectionMapping(); + void printProgramHeaders() override; + void printSectionMapping() override; void printGNUVersionSectionProlog(const typename ELFT::Shdr &Sec, const Twine &Label, unsigned EntriesNum); @@ -879,8 +879,8 @@ template class LLVMELFDumper : public ELFDumper { void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, Optional StrTable, bool IsDynamic, bool /*NonVisibilityBitsUsed*/) const override; - void printProgramHeaders(); - void printSectionMapping() {} + void printProgramHeaders() override; + void printSectionMapping() override {} void printStackSizeEntry(uint64_t Size, StringRef FuncName) override; void printMipsGOT(const MipsGOTParser &Parser) override; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] cc91efd - [llvm-readobj] - An attempt to fix BB.
Author: Georgii Rymar Date: 2021-01-12T13:09:49+03:00 New Revision: cc91efdabee05f749cb42e45aef1b45431844ade URL: https://github.com/llvm/llvm-project/commit/cc91efdabee05f749cb42e45aef1b45431844ade DIFF: https://github.com/llvm/llvm-project/commit/cc91efdabee05f749cb42e45aef1b45431844ade.diff LOG: [llvm-readobj] - An attempt to fix BB. This adds the `template` keyword for 'getAsArrayRef' calls. An example of error: /b/1/openmp-gcc-x86_64-linux-debian/llvm.src/llvm/tools/llvm-readobj/ELFDumper.cpp:4491:50: error: use 'template' keyword to treat 'getAsArrayRef' as a dependent template name for (const Elf_Rel &Rel : this->DynRelRegion.getAsArrayRef()) Added: Modified: llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 44608b8c9a06..d18e1d416278 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -265,7 +265,7 @@ template class ELFDumper : public ObjDumper { // with a DT_NULL entry. However, sometimes the section content may // continue past the DT_NULL entry, so to dump the section correctly, // we first find the end of the entries by iterating over them. -Elf_Dyn_Range Table = DynamicTable.getAsArrayRef(); +Elf_Dyn_Range Table = DynamicTable.template getAsArrayRef(); size_t Size = 0; while (Size < Table.size()) @@ -278,7 +278,7 @@ template class ELFDumper : public ObjDumper { Elf_Sym_Range dynamic_symbols() const { if (!DynSymRegion) return Elf_Sym_Range(); -return DynSymRegion->getAsArrayRef(); +return DynSymRegion->template getAsArrayRef(); } const Elf_Shdr *findSectionByName(StringRef Name) const; @@ -1828,7 +1828,7 @@ void ELFDumper::loadDynamicTable() { sizeof(Elf_Dyn))); FromPhdr.SizePrintName = "PT_DYNAMIC size"; FromPhdr.EntSizePrintName = ""; -IsPhdrTableValid = !FromPhdr.getAsArrayRef().empty(); +IsPhdrTableValid = !FromPhdr.template getAsArrayRef().empty(); } // Locate the dynamic table described in a section header. @@ -1844,7 +1844,7 @@ void ELFDumper::loadDynamicTable() { FromSec = *RegOrErr; FromSec.Context = describe(*DynamicSec); FromSec.EntSizePrintName = ""; - IsSecTableValid = !FromSec.getAsArrayRef().empty(); + IsSecTableValid = !FromSec.template getAsArrayRef().empty(); } else { reportUniqueWarning("unable to read the dynamic table from " + describe(*DynamicSec) + ": " + @@ -2584,7 +2584,7 @@ getGnuHashTableChains(Optional DynSymRegion, return createError("no dynamic symbol table found"); ArrayRef DynSymTable = - DynSymRegion->getAsArrayRef(); + DynSymRegion->template getAsArrayRef(); size_t NumSyms = DynSymTable.size(); if (!NumSyms) return createError("the dynamic symbol table is empty"); @@ -4480,21 +4480,24 @@ void ELFDumper::printRelocationsHelper(const Elf_Shdr &Sec) { template void ELFDumper::printDynamicRelocationsHelper() { const bool IsMips64EL = this->Obj.isMips64EL(); - if ( this->DynRelaRegion.Size > 0) { -printDynamicRelocHeader(ELF::SHT_RELA, "RELA", this->DynRelaRegion); -for (const Elf_Rela &Rela : this->DynRelaRegion.getAsArrayRef()) + if (this->DynRelaRegion.Size > 0) { +printDynamicRelocHeader(ELF::SHT_RELA, "RELA", this->DynRelaRegion); +for (const Elf_Rela &Rela : + this->DynRelaRegion.template getAsArrayRef()) printDynamicReloc(Relocation(Rela, IsMips64EL)); } if (this->DynRelRegion.Size > 0) { printDynamicRelocHeader(ELF::SHT_REL, "REL", this->DynRelRegion); -for (const Elf_Rel &Rel : this->DynRelRegion.getAsArrayRef()) +for (const Elf_Rel &Rel : + this->DynRelRegion.template getAsArrayRef()) printDynamicReloc(Relocation(Rel, IsMips64EL)); } if (this->DynRelrRegion.Size > 0) { printDynamicRelocHeader(ELF::SHT_REL, "RELR", this->DynRelrRegion); -Elf_Relr_Range Relrs = this->DynRelrRegion.getAsArrayRef(); +Elf_Relr_Range Relrs = +this->DynRelrRegion.template getAsArrayRef(); for (const Elf_Rel &Rel : Obj.decode_relrs(Relrs)) printDynamicReloc(Relocation(Rel, IsMips64EL)); } @@ -4503,11 +4506,12 @@ template void ELFDumper::printDynamicRelocationsHelper() { if (this->DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) { printDynamicRelocHeader(ELF::SHT_RELA, "PLT", this->DynPLTRelRegion); for (const Elf_Rela &Rela : - this->DynPLTRelRegion.getAsArrayRef()) + this->DynPLTRelRegion.template getAsArrayRef()) printDynamicReloc(Relocation(Rela, IsMips64EL)); } else { printDynamicRelocHeader(ELF::SHT_REL, "PLT", this->DynPLTRelRegion); - for (const Elf_Rel &Rel : this->DynPLTRelRegion.getAsArrayRef()) + for
[llvm-branch-commits] [llvm] 891b487 - [llvm-readobj] - One more attempt to fix BB.
Author: Georgii Rymar Date: 2021-01-12T13:17:59+03:00 New Revision: 891b4873c129e27755e90a9b8954b9f0d0e7c5a4 URL: https://github.com/llvm/llvm-project/commit/891b4873c129e27755e90a9b8954b9f0d0e7c5a4 DIFF: https://github.com/llvm/llvm-project/commit/891b4873c129e27755e90a9b8954b9f0d0e7c5a4.diff LOG: [llvm-readobj] - One more attempt to fix BB. Add `this->` for `W`, which is the member of `ObjDumper` An example of error: readobj/ELFDumper.cpp:738:13: error: use of undeclared identifier 'W' assert(&W.getOStream() == &llvm::fouts()); Added: Modified: llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index d18e1d416278..5e27a14d0475 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -735,7 +735,7 @@ template class GNUELFDumper : public ELFDumper { GNUELFDumper(const object::ELFObjectFile &ObjF, ScopedPrinter &Writer) : ELFDumper(ObjF, Writer), OS(static_cast(Writer.getOStream())) { -assert(&W.getOStream() == &llvm::fouts()); +assert(&this->W.getOStream() == &llvm::fouts()); } void printFileHeaders() override; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 60df7c0 - [obj2yaml, yaml2obj] - Fix issues with creating/dumping group sections.
Author: Georgii Rymar Date: 2021-01-12T14:07:42+03:00 New Revision: 60df7c08b1f4447309c0c07fec1c8bc7267562fc URL: https://github.com/llvm/llvm-project/commit/60df7c08b1f4447309c0c07fec1c8bc7267562fc DIFF: https://github.com/llvm/llvm-project/commit/60df7c08b1f4447309c0c07fec1c8bc7267562fc.diff LOG: [obj2yaml,yaml2obj] - Fix issues with creating/dumping group sections. We have the following issues related to group sections: 1) yaml2obj is unable to set the custom `sh_entsize` value, because the `EntSize` key is currently ignored. 2) obj2yaml is unable to dump the group section which `sh_entsize != 4`. 3) obj2yaml always dumps the "EntSize" for group sections, though usually we are trying to omit dumping default values when dumping keys. I.e. we should not print the "EntSize" key when `sh_entsize` == 4. This patch fixes (1),(3) and adds the test case to document the behavior of (2). Differential revision: https://reviews.llvm.org/D93854 Added: Modified: llvm/lib/ObjectYAML/ELFEmitter.cpp llvm/test/tools/obj2yaml/ELF/section-group.yaml llvm/test/tools/yaml2obj/ELF/group.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index 010a881379f3..181b130de621 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -1275,7 +1275,10 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, SN2I.lookup(".symtab", Link)) SHeader.sh_link = Link; - SHeader.sh_entsize = 4; + if (Section.EntSize) +SHeader.sh_entsize = *Section.EntSize; + else +SHeader.sh_entsize = sizeof(typename ELFT::Word); if (Section.Signature) SHeader.sh_info = diff --git a/llvm/test/tools/obj2yaml/ELF/section-group.yaml b/llvm/test/tools/obj2yaml/ELF/section-group.yaml index 33044ceeb36c..bdd65908992d 100644 --- a/llvm/test/tools/obj2yaml/ELF/section-group.yaml +++ b/llvm/test/tools/obj2yaml/ELF/section-group.yaml @@ -1,13 +1,15 @@ ## Checks that the tool is able to read section groups from ELF. +## Check how groups sections are dumped. +## Check we don't dump the "EntSize" key when sh_entsize == 4. + # RUN: yaml2obj %s -o %t1.o # RUN: obj2yaml %t1.o | FileCheck %s -DSEC=.rodata -# CHECK: - Name:.group -# CHECK-NEXT: Type:SHT_GROUP -# CHECK-NEXT: Link:.symtab -# CHECK-NEXT: EntSize: 0x4 -# CHECK-NEXT: Info:signature +# CHECK: - Name: .group +# CHECK-NEXT: Type: SHT_GROUP +# CHECK-NEXT: Link: .symtab +# CHECK-NEXT: Info: signature # CHECK-NEXT: Members: # CHECK-NEXT: - SectionOrType: GRP_COMDAT # CHECK-NEXT: - SectionOrType: [[SEC]] @@ -19,10 +21,11 @@ FileHeader: Data: ELFDATA2LSB Type: ET_REL Sections: - - Name: .group -Type: SHT_GROUP -Link: .symtab -Info: [[INFO=signature]] + - Name:.group +Type:SHT_GROUP +Link:.symtab +Info:[[INFO=signature]] +EntSize: [[ENTSIZE=]] Members: - SectionOrType: GRP_COMDAT - SectionOrType: [[SEC=.rodata]] @@ -33,6 +36,14 @@ Symbols: Type:STT_OBJECT Section: .rodata +## Document that yaml2obj can't dump the SHT_GROUP section when its sh_entsize != 4. + +# RUN: yaml2obj %s -DENTSIZE=0xfe -o %t1.entsize.o +# RUN: not obj2yaml %t1.entsize.o 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t1.entsize.o --check-prefix=ENTSIZE + +# ENTSIZE: Error reading file: [[FILE]]: section [index 1] has invalid sh_entsize: expected 4, but got 254 + ## Check we are able to dump members of the SHT_GROUP section even when ## one of them has section index 0. diff --git a/llvm/test/tools/yaml2obj/ELF/group.yaml b/llvm/test/tools/yaml2obj/ELF/group.yaml index 56794d9f14d7..1f061ade5769 100644 --- a/llvm/test/tools/yaml2obj/ELF/group.yaml +++ b/llvm/test/tools/yaml2obj/ELF/group.yaml @@ -19,6 +19,7 @@ Sections: Type:SHT_GROUP Link:0x1 Info:0x2 +EntSize: [[ENTSIZE=]] Size:[[SIZE=]] Content: [[CONTENT=]] Members: [[MEMBERS=]] @@ -68,10 +69,19 @@ Sections: # MEMBERS-ERR: error: "Members" cannot be used with "Content" or "Size" ## Check we create an empty section when none of "Size", "Content" or "Members" are specified. +## Check that the default value of sh_entsize is 4. # RUN: yaml2obj %s -o %t.empty.o # RUN: llvm-readelf --sections --section-data %t.empty.o | \ # RUN: FileCheck %s --check-prefix=EMPTY-SEC -# EMPTY-SEC: [Nr] Name Type Address OffSize -# EMPTY-SEC: [ 1] .group GROUP 40 00 +# EMPTY-SEC: [Nr] Name Type Address OffSize ES Flg +# EMPTY-SEC: [ 1] .group GROUP 40 00 04 1 + +## Check that we are able to set an arbitrary entry size for the group section. + +# RUN: yaml2obj %s -DENTSIZE=0xFE -o %t.entsize.o +# RUN: llvm-readelf --sections %t.entsize.o | FileChec
[llvm-branch-commits] [llvm] c15a57c - [obj2yaml] - Don't crash when an object has an empty symbol table.
Author: Georgii Rymar Date: 2021-01-12T14:08:59+03:00 New Revision: c15a57cc1a86bfb72f4fa0e7d265494babc3b412 URL: https://github.com/llvm/llvm-project/commit/c15a57cc1a86bfb72f4fa0e7d265494babc3b412 DIFF: https://github.com/llvm/llvm-project/commit/c15a57cc1a86bfb72f4fa0e7d265494babc3b412.diff LOG: [obj2yaml] - Don't crash when an object has an empty symbol table. Currently we crash when we have an object with SHT_SYMTAB/SHT_DYNSYM sections of size 0. With this patch instead of the crash we start to dump them properly. Differential revision: https://reviews.llvm.org/D93697 Added: Modified: llvm/test/tools/obj2yaml/ELF/no-symtab.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/test/tools/obj2yaml/ELF/no-symtab.yaml b/llvm/test/tools/obj2yaml/ELF/no-symtab.yaml index 8f9fb8285645..132ddfbbc321 100644 --- a/llvm/test/tools/obj2yaml/ELF/no-symtab.yaml +++ b/llvm/test/tools/obj2yaml/ELF/no-symtab.yaml @@ -37,3 +37,37 @@ FileHeader: Data: ELFDATA2LSB Type: ET_DYN Symbols: [] + +## A symbol table without the null entry is non-conforming. +## Check we don't print "Symbols" and "DynamicSymbols" keys in this case. + +# RUN: yaml2obj --docnum=3 %s -o %t3 +# RUN: obj2yaml %t3 | FileCheck %s --check-prefix=EMPTY + +# EMPTY: Sections: +# EMPTY-NEXT: - Name:.symtab +# EMPTY-NEXT: Type:SHT_SYMTAB +# EMPTY-NEXT: Link:.strtab +## TODO: we shouldn't dump the default "EntSize" value. +# EMPTY-NEXT: EntSize: 0x18 +# EMPTY-NEXT: Size:0x0 +# EMPTY-NEXT: - Name:.dynsym +# EMPTY-NEXT: Type:SHT_DYNSYM +# EMPTY-NEXT: Flags: [ SHF_ALLOC ] +## TODO: we shouldn't dump the default "EntSize" value. +# EMPTY-NEXT: EntSize: 0x18 +# EMPTY-NEXT: Size:0x0 +# EMPTY-NEXT: ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN +Sections: + - Name: .symtab +Type: SHT_SYMTAB +Size: 0 + - Name: .dynsym +Type: SHT_DYNSYM +Size: 0 diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index f29b1ebca7de..89bbee49657a 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -55,7 +55,7 @@ class ELFDumper { dumpDWARFSections(std::vector> &Sections); Error dumpSymbols(const Elf_Shdr *Symtab, -std::vector &Symbols); +Optional> &Symbols); Error dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab, StringRef StrTable, ELFYAML::Symbol &S); Expected>> dumpSections(); @@ -219,9 +219,12 @@ bool ELFDumper::shouldPrintSection(const ELFYAML::Section &S, // Generally we are trying to reduce noise in the YAML output. Because // of that we do not print non-allocatable versions of such sections and // assume they are placed at the end. + // We also dump symbol tables when the Size field is set. It happens when they + // are empty, which should not normally happen. if (S.Type == ELF::SHT_STRTAB || S.Type == ELF::SHT_SYMTAB || - S.Type == ELF::SHT_DYNSYM) -return S.Flags.getValueOr(ELFYAML::ELF_SHF(0)) & ELF::SHF_ALLOC; + S.Type == ELF::SHT_DYNSYM) { +return S.Size || S.Flags.getValueOr(ELFYAML::ELF_SHF(0)) & ELF::SHF_ALLOC; + } return true; } @@ -325,17 +328,13 @@ template Expected ELFDumper::dump() { } } - if (SymTab) { -Y->Symbols.emplace(); -if (Error E = dumpSymbols(SymTab, *Y->Symbols)) + if (SymTab) +if (Error E = dumpSymbols(SymTab, Y->Symbols)) return std::move(E); - } - if (DynSymTab) { -Y->DynamicSymbols.emplace(); -if (Error E = dumpSymbols(DynSymTab, *Y->DynamicSymbols)) + if (DynSymTab) +if (Error E = dumpSymbols(DynSymTab, Y->DynamicSymbols)) return std::move(E); - } // We dump all sections first. It is simple and allows us to verify that all // sections are valid and also to generalize the code. But we are not going to @@ -516,6 +515,13 @@ ELFDumper::dumpPlaceholderSection(const Elf_Shdr *Shdr) { auto S = std::make_unique(); if (Error E = dumpCommonSection(Shdr, *S.get())) return std::move(E); + + // Normally symbol tables should not be empty. We dump the "Size" + // key when they are. + if ((Shdr->sh_type == ELF::SHT_SYMTAB || Shdr->sh_type == ELF::SHT_DYNSYM) && + !Shdr->sh_size) +S->Size.emplace(); + return S.release(); } @@ -621,30 +627,33 @@ ELFDumper::dumpSections() { } template -Error ELFDumper::dumpSymbols(const Elf_Shdr *Symtab, - std::vector &Symbols) { +Error ELFDumper::dumpSymbols( +const Elf_Shdr *Symtab, Optional> &Symbols) { if (!Symtab) return Error::success(); - auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab); - if (!StrTableOrErr) -return StrTableOrErr.takeError(); - StringRef StrTable = *StrTableOrErr; - auto SymtabOrErr = Obj.symbols(Symtab
[llvm-branch-commits] [llvm] 83aea14 - [llvm-readelf] - Don't print OS/Processor specific prefix for known ELF file types.
Author: Georgii Rymar Date: 2020-12-15T10:56:25+03:00 New Revision: 83aea14ed6118c810e4ed2966bc34db9b42cb049 URL: https://github.com/llvm/llvm-project/commit/83aea14ed6118c810e4ed2966bc34db9b42cb049 DIFF: https://github.com/llvm/llvm-project/commit/83aea14ed6118c810e4ed2966bc34db9b42cb049.diff LOG: [llvm-readelf] - Don't print OS/Processor specific prefix for known ELF file types. This is a change suggested in post commit comments for D93096 (https://reviews.llvm.org/D93096#2451796). Imagine we want to add a custom OS specific ELF file type. For that we can update the `ElfObjectFileType` array: ``` static const EnumEntry ElfObjectFileType[] = { ... {"Core", "CORE (Core file)", ELF::ET_CORE}, {"MyType", "MyType (my description)", 0xfe01}, }; ``` The current code then might print: ``` OS Specific: (MyType (my description)) ``` Though instead we probably would like to see a nicer output, e.g: ``` Type: MyType (my description) ``` To achieve that we can reorder the code slightly. It is impossible to add a test I think, because we have no custom values in the `ElfObjectFileType` array in LLVM. Differential revision: https://reviews.llvm.org/D93217 Added: Modified: llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 27222c5639e6..c9ca2215d2c6 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -3528,16 +3528,17 @@ template void GNUStyle::printFileHeaders() { "ABI Version:", std::to_string(e.e_ident[ELF::EI_ABIVERSION])); Str = printEnum(e.e_type, makeArrayRef(ElfObjectFileType)); - if (e.e_type >= ET_LOPROC) { -Str = "Processor Specific: (" + Str + ")"; - } else if (e.e_type >= ET_LOOS) { -Str = "OS Specific: (" + Str + ")"; - } else if (makeArrayRef(ElfObjectFileType).end() == - llvm::find_if(ElfObjectFileType, - [&](const EnumEntry &E) { - return E.Value == e.e_type; - })) -Str = ": " + Str; + if (makeArrayRef(ElfObjectFileType).end() == + llvm::find_if(ElfObjectFileType, [&](const EnumEntry &E) { +return E.Value == e.e_type; + })) { +if (e.e_type >= ET_LOPROC) + Str = "Processor Specific: (" + Str + ")"; +else if (e.e_type >= ET_LOOS) + Str = "OS Specific: (" + Str + ")"; +else + Str = ": " + Str; + } printFields(OS, "Type:", Str); Str = printEnum(e.e_machine, makeArrayRef(ElfMachineType)); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 78aea98 - [llvm-readelf/obj] - Handle out-of-order PT_LOADs better.
Author: Georgii Rymar Date: 2020-12-16T12:59:32+03:00 New Revision: 78aea98308a85c061a87952e9842bf1e6fe097d5 URL: https://github.com/llvm/llvm-project/commit/78aea98308a85c061a87952e9842bf1e6fe097d5 DIFF: https://github.com/llvm/llvm-project/commit/78aea98308a85c061a87952e9842bf1e6fe097d5.diff LOG: [llvm-readelf/obj] - Handle out-of-order PT_LOADs better. This is https://bugs.llvm.org/show_bug.cgi?id=45698. Specification says that "Loadable segment entries in the program header table appear in ascending order, sorted on the p_vaddr member." Our `toMappedAddr()` relies on this condition. This patch adds a warning when the sorting order of loadable segments is wrong. In this case we force segments sorting and that allows `toMappedAddr()` to work as expected. Differential revision: https://reviews.llvm.org/D92641 Added: Modified: llvm/include/llvm/Object/ELF.h llvm/lib/Object/ELF.cpp llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test llvm/tools/llvm-readobj/ELFDumper.cpp llvm/unittests/Object/ELFObjectFileTest.cpp Removed: diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h index d47c8f7809fe..efe518f93192 100644 --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/include/llvm/Object/ELF.h @@ -183,7 +183,9 @@ class ELFFile { Expected dynamicEntries() const; - Expected toMappedAddr(uint64_t VAddr) const; + Expected + toMappedAddr(uint64_t VAddr, + WarningHandler WarnHandler = &defaultWarningHandler) const; Expected symbols(const Elf_Shdr *Sec) const { if (!Sec) diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp index 116856a4260b..28a69143c1b2 100644 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -566,7 +566,8 @@ Expected ELFFile::dynamicEntries() const { } template -Expected ELFFile::toMappedAddr(uint64_t VAddr) const { +Expected +ELFFile::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const { auto ProgramHeadersOrError = program_headers(); if (!ProgramHeadersOrError) return ProgramHeadersOrError.takeError(); @@ -577,6 +578,17 @@ Expected ELFFile::toMappedAddr(uint64_t VAddr) const { if (Phdr.p_type == ELF::PT_LOAD) LoadSegments.push_back(const_cast(&Phdr)); + auto SortPred = [](const Elf_Phdr_Impl *A, + const Elf_Phdr_Impl *B) { +return A->p_vaddr < B->p_vaddr; + }; + if (!llvm::is_sorted(LoadSegments, SortPred)) { +if (Error E = +WarnHandler("loadable segments are unsorted by virtual address")) + return std::move(E); +llvm::stable_sort(LoadSegments, SortPred); + } + const Elf_Phdr *const *I = std::upper_bound(LoadSegments.begin(), LoadSegments.end(), VAddr, [](uint64_t VAddr, const Elf_Phdr_Impl *Phdr) { diff --git a/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test b/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test index 6bcf890949c8..d160ea87208c 100644 --- a/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test +++ b/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test @@ -414,3 +414,58 @@ ProgramHeaders: # PAST-THE-EOF-NEXT: {{[(]?}}RPATH{{[)]?}} Library rpath: [] # PAST-THE-EOF-NEXT: {{[(]?}}RUNPATH{{[)]?}} Library runpath: [] # PAST-THE-EOF-NEXT: {{[(]?}}NULL{{[)]?}} 0x0 + +## Check that we report a warning when we try to map an address, but loadable +## segments appear unsorted by the p_vaddr member. In this case we are still +## able to map an address. + +# RUN: yaml2obj %s --docnum=7 -o %t10 +# RUN: llvm-readobj --dynamic-table %t10 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t10 --implicit-check-not=warning: --check-prefixes=OUT-OF-ORDER,OUT-OF-ORDER-LLVM +# RUN: llvm-readelf --dynamic-table %t10 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t10 --implicit-check-not=warning: --check-prefixes=OUT-OF-ORDER,OUT-OF-ORDER-GNU + +# OUT-OF-ORDER: warning: '[[FILE]]': loadable segments are unsorted by virtual address + +# OUT-OF-ORDER-LLVM: DynamicSection [ (2 entries) +# OUT-OF-ORDER-LLVM-NEXT: TagType Name/Value +# OUT-OF-ORDER-LLVM-NEXT: 0x0005 STRTAB 0x1000 +# OUT-OF-ORDER-LLVM-NEXT: 0x NULL 0x0 +# OUT-OF-ORDER-LLVM-NEXT: ] + +# OUT-OF-ORDER-GNU: Dynamic section at offset 0xe9 contains 2 entries: +# OUT-OF-ORDER-GNU-NEXT: TagType Name/Value +# OUT-OF-ORDER-GNU-NEXT: 0x0005 (STRTAB) 0x1000 +# OUT-OF-ORDER-GNU-NEXT: 0x (NULL) 0x0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC +Sections: + - Name:.dynstr +Type:SHT_STRTAB +Address: 0x1000 + - Name:.dynamic +Type:SHT_DYNAMIC +Address: 0x1010 +Entries: + - Tag: DT_STRTAB +Value: 0x1000 + - Tag: DT_NULL +Value: 0 +Symbols: [] +ProgramHeaders: + - Type:
[llvm-branch-commits] [llvm] 407d420 - [lib/Object] - Make ELFObjectFile::getSymbol() return Expected<>.
Author: Georgii Rymar Date: 2020-12-16T13:14:23+03:00 New Revision: 407d42002904ce541f732ce4300913ef57cff232 URL: https://github.com/llvm/llvm-project/commit/407d42002904ce541f732ce4300913ef57cff232 DIFF: https://github.com/llvm/llvm-project/commit/407d42002904ce541f732ce4300913ef57cff232.diff LOG: [lib/Object] - Make ELFObjectFile::getSymbol() return Expected<>. This was requested in comments for D93209: https://reviews.llvm.org/D93209#inline-871192 D93209 fixes an issue with `ELFFile::getEntry`, after what `getSymbol` starts calling `report_fatal_error` for previously missed invalid cases. This patch makes it return `Expected<>` and updates callers. For few of them I had to add new `report_fatal_error` calls. But I see no way to avoid it currently. The change would affects too many places, e.g: `getSymbolBinding` and other methods are used from `ELFSymbolRef` which is used in too many places across LLVM. Differential revision: https://reviews.llvm.org/D93297 Added: Modified: llvm/include/llvm/Object/ELFObjectFile.h llvm/tools/llvm-objdump/ELFDump.cpp llvm/tools/llvm-objdump/llvm-objdump.cpp llvm/unittests/Object/ELFObjectFileTest.cpp Removed: diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index ae4521624077..ca4363572d90 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -408,11 +408,8 @@ template class ELFObjectFile : public ELFObjectFileBase { const Elf_Rel *getRel(DataRefImpl Rel) const; const Elf_Rela *getRela(DataRefImpl Rela) const; - const Elf_Sym *getSymbol(DataRefImpl Sym) const { -auto Ret = EF.template getEntry(Sym.d.a, Sym.d.b); -if (!Ret) - report_fatal_error(errorToErrorCode(Ret.takeError()).message()); -return *Ret; + Expected getSymbol(DataRefImpl Sym) const { +return EF.template getEntry(Sym.d.a, Sym.d.b); } /// Get the relocation section that contains \a Rel. @@ -499,7 +496,9 @@ template Error ELFObjectFile::initContent() { template Expected ELFObjectFile::getSymbolName(DataRefImpl Sym) const { - const Elf_Sym *ESym = getSymbol(Sym); + Expected SymOrErr = getSymbol(Sym); + if (!SymOrErr) +return SymOrErr.takeError(); auto SymTabOrErr = EF.getSection(Sym.d.a); if (!SymTabOrErr) return SymTabOrErr.takeError(); @@ -511,12 +510,12 @@ Expected ELFObjectFile::getSymbolName(DataRefImpl Sym) const { auto SymStrTabOrErr = EF.getStringTable(*StringTableSec); if (!SymStrTabOrErr) return SymStrTabOrErr.takeError(); - Expected Name = ESym->getName(*SymStrTabOrErr); + Expected Name = (*SymOrErr)->getName(*SymStrTabOrErr); if (Name && !Name->empty()) return Name; // If the symbol name is empty use the section name. - if (ESym->getType() == ELF::STT_SECTION) { + if ((*SymOrErr)->getType() == ELF::STT_SECTION) { if (Expected SecOrErr = getSymbolSection(Sym)) { consumeError(Name.takeError()); return (*SecOrErr)->getName(); @@ -542,15 +541,18 @@ uint64_t ELFObjectFile::getSectionOffset(DataRefImpl Sec) const { template uint64_t ELFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const { - const Elf_Sym *ESym = getSymbol(Symb); - uint64_t Ret = ESym->st_value; - if (ESym->st_shndx == ELF::SHN_ABS) + Expected SymOrErr = getSymbol(Symb); + if (!SymOrErr) +report_fatal_error(SymOrErr.takeError()); + + uint64_t Ret = (*SymOrErr)->st_value; + if ((*SymOrErr)->st_shndx == ELF::SHN_ABS) return Ret; const Elf_Ehdr &Header = EF.getHeader(); // Clear the ARM/Thumb or microMIPS indicator flag. if ((Header.e_machine == ELF::EM_ARM || Header.e_machine == ELF::EM_MIPS) && - ESym->getType() == ELF::STT_FUNC) + (*SymOrErr)->getType() == ELF::STT_FUNC) Ret &= ~1; return Ret; @@ -565,8 +567,11 @@ ELFObjectFile::getSymbolAddress(DataRefImpl Symb) const { return SymbolValueOrErr.takeError(); uint64_t Result = *SymbolValueOrErr; - const Elf_Sym *ESym = getSymbol(Symb); - switch (ESym->st_shndx) { + Expected SymOrErr = getSymbol(Symb); + if (!SymOrErr) +return SymOrErr.takeError(); + + switch ((*SymOrErr)->st_shndx) { case ELF::SHN_COMMON: case ELF::SHN_UNDEF: case ELF::SHN_ABS: @@ -589,7 +594,7 @@ ELFObjectFile::getSymbolAddress(DataRefImpl Symb) const { } Expected SectionOrErr = -EF.getSection(*ESym, *SymTabOrErr, ShndxTable); +EF.getSection(**SymOrErr, *SymTabOrErr, ShndxTable); if (!SectionOrErr) return SectionOrErr.takeError(); const Elf_Shdr *Section = *SectionOrErr; @@ -602,9 +607,11 @@ ELFObjectFile::getSymbolAddress(DataRefImpl Symb) const { template uint32_t ELFObjectFile::getSymbolAlignment(DataRefImpl Symb) const { - const Elf_Sym *Sym = getSymbol(Symb); - if (Sym->st_shndx == ELF::SHN_COMMON) -return Sym->st_value; + Expected SymOrErr = get
[llvm-branch-commits] [llvm] 8c2cf89 - [yaml2obj/obj2yaml] - Make Value/Size fields of Symbol optional.
Author: Georgii Rymar Date: 2020-12-16T13:49:57+03:00 New Revision: 8c2cf89834c3496be343525b9f9c6aecc9182117 URL: https://github.com/llvm/llvm-project/commit/8c2cf89834c3496be343525b9f9c6aecc9182117 DIFF: https://github.com/llvm/llvm-project/commit/8c2cf89834c3496be343525b9f9c6aecc9182117.diff LOG: [yaml2obj/obj2yaml] - Make Value/Size fields of Symbol optional. When a field is optional we can use the `=` syntax in macros. This patch makes `Value`/`Size` fields of `Symbol` optional and adds test cases for them. Differential revision: https://reviews.llvm.org/D93010 Added: llvm/test/tools/obj2yaml/ELF/symbol.yaml llvm/test/tools/yaml2obj/ELF/symbol-size.yaml llvm/test/tools/yaml2obj/ELF/symbol-value.yaml Modified: llvm/include/llvm/ObjectYAML/ELFYAML.h llvm/lib/ObjectYAML/ELFEmitter.cpp llvm/lib/ObjectYAML/ELFYAML.cpp llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index 8de2e17303782..a838b69273ceb 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -106,8 +106,8 @@ struct Symbol { Optional Section; Optional Index; ELF_STB Binding; - llvm::yaml::Hex64 Value; - llvm::yaml::Hex64 Size; + Optional Value; + Optional Size; Optional Other; Optional StName; diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index ee6149fe02bd8..51efc00f52d4d 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -837,9 +837,9 @@ ELFState::toELFSymbols(ArrayRef Symbols, else if (Sym.Index) Symbol.st_shndx = *Sym.Index; -Symbol.st_value = Sym.Value; +Symbol.st_value = Sym.Value.getValueOr(yaml::Hex64(0)); Symbol.st_other = Sym.Other ? *Sym.Other : 0; -Symbol.st_size = Sym.Size; +Symbol.st_size = Sym.Size.getValueOr(yaml::Hex64(0)); } return Ret; diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index d7de5462ed254..52a4a3a2d80b0 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1089,8 +1089,8 @@ void MappingTraits::mapping(IO &IO, ELFYAML::Symbol &Symbol) { IO.mapOptional("Section", Symbol.Section); IO.mapOptional("Index", Symbol.Index); IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0)); - IO.mapOptional("Value", Symbol.Value, Hex64(0)); - IO.mapOptional("Size", Symbol.Size, Hex64(0)); + IO.mapOptional("Value", Symbol.Value); + IO.mapOptional("Size", Symbol.Size); // Symbol's Other field is a bit special. It is usually a field that // represents st_other and holds the symbol visibility. However, on some diff --git a/llvm/test/tools/obj2yaml/ELF/symbol.yaml b/llvm/test/tools/obj2yaml/ELF/symbol.yaml new file mode 100644 index 0..3684d4f70c6cd --- /dev/null +++ b/llvm/test/tools/obj2yaml/ELF/symbol.yaml @@ -0,0 +1,27 @@ +## This is a test case to check how obj2yaml dumps symbols. + +## Check that we only dump Size and Value keys when +## their values are not 0. + +# RUN: yaml2obj %s -o %t1 +# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=FIELDS-DEF + +# FIELDS-DEF: Symbols: +# FIELDS-DEF-NEXT: - Name: foo +# FIELDS-DEF-NEXT: - Name: bar +# FIELDS-DEF-NEXT: Value: 0x1 +# FIELDS-DEF-NEXT: Size: 0x1 +# FIELDS-DEF-NEXT: ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL +Symbols: + - Name: foo +Size: 0x0 +Value: 0x0 + - Name: bar +Size: 0x1 +Value: 0x1 diff --git a/llvm/test/tools/yaml2obj/ELF/symbol-size.yaml b/llvm/test/tools/yaml2obj/ELF/symbol-size.yaml new file mode 100644 index 0..ba3b40928f357 --- /dev/null +++ b/llvm/test/tools/yaml2obj/ELF/symbol-size.yaml @@ -0,0 +1,33 @@ +## Check we can set diff erent sizes for symbols. + +# RUN: yaml2obj %s -o %t +# RUN: llvm-readelf --symbols %t | FileCheck %s + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL +Symbols: +## No "Size" key was set. Check the behaviour is the +## same as if it was set to 0. + - Name: aaa +# CHECK:Num: Value Size {{.*}} Name +# CHECK: 1: [[#]] 0{{.*}} aaa +## The "Size" key is explicitly set to 0x0. + - Name: bbb +Size: 0x0 +## Check we can use the "=" syntax. +# CHECK-NEXT: 2: [[#]] 0{{.*}} bbb + - Name: ccc +Size: [[ESIZE=]] +# CHECK-NEXT: 3: [[#]] 0{{.*}} ccc +## "Size" is explicitly set to an arbitrary value. +## Here we use UINT64_MAX to check this boundary case. + - Name: ddd +Size: 0x +# CHECK-NEXT: 4: [[#]] -1 {{.*}} ddd +## The same as the previous case, but using decimal values. + - Name: eee +Size: 18446744073709551615 +# CHECK-NEXT: 5: [[#]] -1 {{.*}} eee diff --git a/llvm/test/tools/yaml2obj/ELF/symbol-value.yaml b/llvm/test/tools/ya
[llvm-branch-commits] [lld] 8590b5c - [libObject, llvm-readobj] - Reimplement `ELFFile::getEntry`.
Author: Georgii Rymar Date: 2020-12-18T16:52:27+03:00 New Revision: 8590b5ccd568764287ec5ed28567d0284ab9dbdb URL: https://github.com/llvm/llvm-project/commit/8590b5ccd568764287ec5ed28567d0284ab9dbdb DIFF: https://github.com/llvm/llvm-project/commit/8590b5ccd568764287ec5ed28567d0284ab9dbdb.diff LOG: [libObject, llvm-readobj] - Reimplement `ELFFile::getEntry`. Currently, `ELFFile::getEntry` does not check an index of an entry. Because of that the code might read past the end of the symbol table silently. I've added a test to `llvm-readobj\ELF\relocations.test` to demonstrate the possible issue. Also, I've added a unit test for this method. After this change, `getEntry` stops reporting the section index and reuses the `getSectionContentsAsArray` method, which already has all the validation needed. Our related warnings now provide more and better context sometimes. Differential revision: https://reviews.llvm.org/D93209 Added: Modified: lld/test/ELF/invalid/dynamic-section-broken.test llvm/include/llvm/Object/ELF.h llvm/test/Object/invalid.test llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test llvm/test/tools/llvm-readobj/ELF/reloc-symbol-with-versioning.test llvm/test/tools/llvm-readobj/ELF/relocation-errors.test llvm/test/tools/llvm-readobj/ELF/relocations.test llvm/test/tools/llvm-readobj/ELF/relr-relocs.test llvm/test/tools/llvm-readobj/ELF/stack-sizes.test llvm/test/tools/llvm-readobj/ELF/symbols.test llvm/test/tools/llvm-readobj/ELF/versym-invalid.test llvm/test/tools/obj2yaml/ELF/dynamic-section.yaml llvm/test/tools/obj2yaml/ELF/rel-rela-section.yaml llvm/test/tools/yaml2obj/ELF/sht-symtab-shndx.yaml llvm/tools/llvm-readobj/ELFDumper.cpp llvm/unittests/Object/ELFObjectFileTest.cpp Removed: diff --git a/lld/test/ELF/invalid/dynamic-section-broken.test b/lld/test/ELF/invalid/dynamic-section-broken.test index 31317f632487..62f311470a2e 100644 --- a/lld/test/ELF/invalid/dynamic-section-broken.test +++ b/lld/test/ELF/invalid/dynamic-section-broken.test @@ -1,7 +1,7 @@ ## .dynamic section has invalid sh_entsize, check we report it. # RUN: yaml2obj --docnum=1 %s -o %t.so # RUN: not ld.lld %t.so -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1 -# ERR1: error: {{.*}}.so: section [index 1] has an invalid sh_entsize: 291 +# ERR1: error: {{.*}}.so: section [index 1] has invalid sh_entsize: expected 16, but got 291 --- !ELF FileHeader: diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h index efe518f93192..25f2df47781b 100644 --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/include/llvm/Object/ELF.h @@ -412,7 +412,8 @@ Expected> ELFFile::getSectionContentsAsArray(const Elf_Shdr &Sec) const { if (Sec.sh_entsize != sizeof(T) && sizeof(T) != 1) return createError("section " + getSecIndexForError(*this, Sec) + - " has an invalid sh_entsize: " + Twine(Sec.sh_entsize)); + " has invalid sh_entsize: expected " + Twine(sizeof(T)) + + ", but got " + Twine(Sec.sh_entsize)); uintX_t Offset = Sec.sh_offset; uintX_t Size = Sec.sh_size; @@ -618,17 +619,17 @@ template template Expected ELFFile::getEntry(const Elf_Shdr &Section, uint32_t Entry) const { - if (sizeof(T) != Section.sh_entsize) -return createError("section " + getSecIndexForError(*this, Section) + - " has invalid sh_entsize: expected " + Twine(sizeof(T)) + - ", but got " + Twine(Section.sh_entsize)); - uint64_t Pos = Section.sh_offset + (uint64_t)Entry * sizeof(T); - if (Pos + sizeof(T) > Buf.size()) -return createError("unable to access section " + - getSecIndexForError(*this, Section) + " data at 0x" + - Twine::utohexstr(Pos) + - ": offset goes past the end of file"); - return reinterpret_cast(base() + Pos); + Expected> EntriesOrErr = getSectionContentsAsArray(Section); + if (!EntriesOrErr) +return EntriesOrErr.takeError(); + + ArrayRef Arr = *EntriesOrErr; + if (Entry >= Arr.size()) +return createError("can't read an entry at 0x" + + Twine::utohexstr(Entry * sizeof(T)) + + ": it goes past the end of the section (0x" + + Twine::utohexstr(Section.sh_size) + ")"); + return &Arr[Entry]; } template diff --git a/llvm/test/Object/invalid.test b/llvm/test/Object/invalid.test index 57fb006351eb..95b677fae293 100644 --- a/llvm/test/Object/invalid.test +++ b/llvm/test/Object/invalid.test @@ -118,7 +118,7 @@ Symbols: # RUN: yaml2obj %s --docnum=6 -o %t6 # RUN: llvm-readobj --symbols %t6 2>&1 | FileCheck -DFILE=%t6 --check-prefix=INVALID-SYM-SIZE %s -# INVALID-SYM-SIZE: warning: '[[FILE]]': unable to read symbols from the SHT
[llvm-branch-commits] [llvm] bdef1f8 - [llvm-readobj] - Dump the ELF file type better.
Author: Georgii Rymar Date: 2020-12-23T11:13:19+03:00 New Revision: bdef1f87aba656a64b34f76d2a6613b6e9299a03 URL: https://github.com/llvm/llvm-project/commit/bdef1f87aba656a64b34f76d2a6613b6e9299a03 DIFF: https://github.com/llvm/llvm-project/commit/bdef1f87aba656a64b34f76d2a6613b6e9299a03.diff LOG: [llvm-readobj] - Dump the ELF file type better. Currently llvm-readelf might print "OS Specific/Processor Specific/" hint when dumping the ELF file type. The patch teaches llvm-readobj to do the same. This fixes https://bugs.llvm.org/show_bug.cgi?id=40868 I am removing `Object/elf-unknown-type.test` test because it is not in the right place, it is outdated and very limited. The `readobj/ELF/file-types.test` checks the functionality much better. Differential revision: https://reviews.llvm.org/D93689 Added: Modified: llvm/test/tools/llvm-readobj/ELF/file-types.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: llvm/test/Object/elf-unknown-type.test diff --git a/llvm/test/Object/elf-unknown-type.test b/llvm/test/Object/elf-unknown-type.test deleted file mode 100644 index 508e831ae90e.. --- a/llvm/test/Object/elf-unknown-type.test +++ /dev/null @@ -1,10 +0,0 @@ -# RUN: yaml2obj %s | llvm-readobj --file-headers - | FileCheck %s - -!ELF -FileHeader: !FileHeader - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: 42 - Machine: EM_X86_64 - -# CHECK: Type: 0x2A diff --git a/llvm/test/tools/llvm-readobj/ELF/file-types.test b/llvm/test/tools/llvm-readobj/ELF/file-types.test index 767ce4d646ff..f06f302b8642 100644 --- a/llvm/test/tools/llvm-readobj/ELF/file-types.test +++ b/llvm/test/tools/llvm-readobj/ELF/file-types.test @@ -62,7 +62,7 @@ FileHeader: # RUN: llvm-readelf -h %t.unknown | FileCheck %s --match-full-lines --check-prefix GNU-UNNKNOWN # LLVM-UNNKNOWN: ElfHeader { -# LLVM-UNNKNOWN: Type: 0xFDFF +# LLVM-UNNKNOWN: Type: Unknown (0xFDFF) # GNU-UNNKNOWN: ELF Header: # GNU-UNNKNOWN: Type: : fdff @@ -72,7 +72,7 @@ FileHeader: # RUN: llvm-readelf -h %t6 | FileCheck %s --match-full-lines --check-prefix GNU-LOOS # LLVM-LOOS: ElfHeader { -# LLVM-LOOS: Type: 0xFE00 +# LLVM-LOOS: Type: OS Specific (0xFE00) # GNU-LOOS: ELF Header: # GNU-LOOS: Type: OS Specific: (fe00) @@ -82,7 +82,7 @@ FileHeader: # RUN: llvm-readelf -h %t7 | FileCheck %s --match-full-lines --check-prefix GNU-HIOS # LLVM-HIOS: ElfHeader { -# LLVM-HIOS: Type: 0xFEFF +# LLVM-HIOS: Type: OS Specific (0xFEFF) # GNU-HIOS: ELF Header: # GNU-HIOS: Type: OS Specific: (feff) @@ -92,7 +92,7 @@ FileHeader: # RUN: llvm-readelf -h %t8 | FileCheck %s --match-full-lines --check-prefix GNU-LOPROC # LLVM-LOPROC: ElfHeader { -# LLVM-LOPROC: Type: 0xFF00 +# LLVM-LOPROC: Type: Processor Specific (0xFF00) # GNU-LOPROC: ELF Header: # GNU-LOPROC: Type: Processor Specific: (ff00) @@ -102,7 +102,7 @@ FileHeader: # RUN: llvm-readelf -h %t9 | FileCheck %s --match-full-lines --check-prefix GNU-HIPROC # LLVM-HIPROC: ElfHeader { -# LLVM-HIPROC: Type: 0x +# LLVM-HIPROC: Type: Processor Specific (0x) # GNU-HIPROC: ELF Header: # GNU-HIPROC: Type: Processor Specific: () diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index a82494ad1b4d..00f8c3fcefac 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -3515,6 +3515,15 @@ static std::string getSectionHeaderTableIndexString(const ELFFile &Obj, to_string((*ArrOrErr)[0].sh_link) + ")"; } +static const EnumEntry *getObjectFileEnumEntry(unsigned Type) { + auto It = llvm::find_if(ElfObjectFileType, [&](const EnumEntry &E) { +return E.Value == Type; + }); + if (It != makeArrayRef(ElfObjectFileType).end()) +return It; + return nullptr; +} + template void GNUStyle::printFileHeaders() { const Elf_Ehdr &e = this->Obj.getHeader(); OS << "ELF Header:\n"; @@ -3539,17 +3548,15 @@ template void GNUStyle::printFileHeaders() { printFields(OS, "ABI Version:", std::to_string(e.e_ident[ELF::EI_ABIVERSION])); - Str = printEnum(e.e_type, makeArrayRef(ElfObjectFileType)); - if (makeArrayRef(ElfObjectFileType).end() == - llvm::find_if(ElfObjectFileType, [&](const EnumEntry &E) { -return E.Value == e.e_type; - })) { + if (const EnumEntry *E = getObjectFileEnumEntry(e.e_type)) { +Str = E->AltName.str(); + } else { if (e.e_type >= ET_LOPROC) - Str = "Processor Specific: (" + Str + ")"; + Str = "Processor Specific: (" + to_hexString(e.e_type, false) + ")"; else if (e.e_type >= ET_LOOS) - Str = "OS Specific: (" + Str + ")"; + Str = "OS Specific: (" + to_hexString(e.e_type, false) + ")"; else - Str = ": " + Str; + Str = ": " + to_hexString(e.e_type, false); } printFields(OS, "Type:", Str); @@ -6343,7 +6350,19 @@ template void LLVMSt
[llvm-branch-commits] [llvm] b8cb180 - [obj2yaml] - Dump the content of a broken GNU hash table properly.
Author: Georgii Rymar Date: 2020-12-24T11:16:31+03:00 New Revision: b8cb1802a8a2037bd893e038b4eafa61bd5c279e URL: https://github.com/llvm/llvm-project/commit/b8cb1802a8a2037bd893e038b4eafa61bd5c279e DIFF: https://github.com/llvm/llvm-project/commit/b8cb1802a8a2037bd893e038b4eafa61bd5c279e.diff LOG: [obj2yaml] - Dump the content of a broken GNU hash table properly. When something is wrong with the GNU hash table header we dump its context as a raw data. Currently we have the calculation overflow issue and it is possible to bypass the validation we have (and crash). The patch fixes it. Differential revision: https://reviews.llvm.org/D93760 Added: Modified: llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml b/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml index 7dd0a7c870ea..00861c013100 100644 --- a/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml +++ b/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml @@ -54,9 +54,12 @@ Sections: # INVALID-NEXT: - Name:.gnu.hash.broken.maskwords # INVALID-NEXT: Type:SHT_GNU_HASH # INVALID-NEXT: Content: '0100' -# INVALID-NEXT: - Name:.gnu.hash.broken.nbuckets +# INVALID-NEXT: - Name:.gnu.hash.broken.nbuckets.a # INVALID-NEXT: Type:SHT_GNU_HASH # INVALID-NEXT: Content: '0100' +# INVALID-NEXT: - Name:.gnu.hash.broken.nbuckets.b +# INVALID-NEXT: Type:SHT_GNU_HASH +# INVALID-NEXT: Content: 0100{{$}} # INVALID-NEXT: - Name:.gnu.hash.hashvalues.ok # INVALID-NEXT: Type:SHT_GNU_HASH # INVALID-NEXT: Header: @@ -108,9 +111,9 @@ Sections: BloomFilter: [] HashBuckets: [] HashValues: [] -## Case 4: NBuckets field is broken, it says that the number of entries +## Case 4(a): NBuckets field is broken, it says that the number of entries ## in the hash buckets is 1, but it is empty. - - Name: .gnu.hash.broken.nbuckets + - Name: .gnu.hash.broken.nbuckets.a Type: SHT_GNU_HASH Header: SymNdx: 0x0 @@ -120,6 +123,18 @@ Sections: BloomFilter: [] HashBuckets: [] HashValues: [] +## Case 4(b): NBuckets = 0x is incorrect. The result will cause 32-bit +## unsigned overflows if we keep intermediate expressions uint32_t. + - Name: .gnu.hash.broken.nbuckets.b +Type: SHT_GNU_HASH +Header: + SymNdx: 0x0 + Shift2: 0x0 + MaskWords: 0x1 + NBuckets: 0x +BloomFilter: [] +HashBuckets: [] +HashValues: [] ## Case 5: Check that we use the various properties to dump the data when it ## has a size that is a multiple of 4, but fallback to dumping the whole section ## using the "Content" property otherwise. diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 1f9ff88f042a..2b54acd99f9e 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -1271,9 +1271,9 @@ ELFDumper::dumpGnuHashSection(const Elf_Shdr *Shdr) { ELFYAML::GnuHashHeader Header; DataExtractor::Cursor Cur(0); - uint32_t NBuckets = Data.getU32(Cur); + uint64_t NBuckets = Data.getU32(Cur); Header.SymNdx = Data.getU32(Cur); - uint32_t MaskWords = Data.getU32(Cur); + uint64_t MaskWords = Data.getU32(Cur); Header.Shift2 = Data.getU32(Cur); // Set just the raw binary content if we were unable to read the header ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 438bc15 - [libObject] - Add more ELF types to LLVM_ELF_IMPORT_TYPES_ELFT define (ELFTypes.h).
Author: Georgii Rymar Date: 2020-12-25T11:39:05+03:00 New Revision: 438bc157a47a03d36d81977a3ee9974cd021a885 URL: https://github.com/llvm/llvm-project/commit/438bc157a47a03d36d81977a3ee9974cd021a885 DIFF: https://github.com/llvm/llvm-project/commit/438bc157a47a03d36d81977a3ee9974cd021a885.diff LOG: [libObject] - Add more ELF types to LLVM_ELF_IMPORT_TYPES_ELFT define (ELFTypes.h). This allows to get rid of lots for typedefs/usings from many places. Differential revision: https://reviews.llvm.org/D93801 Added: Modified: llvm/include/llvm/Object/ELF.h llvm/include/llvm/Object/ELFObjectFile.h llvm/include/llvm/Object/ELFTypes.h llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp llvm/lib/ObjectYAML/ELFEmitter.cpp llvm/tools/llvm-readobj/ELFDumper.cpp llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h index a5233bd3ac10..bd224ada7783 100644 --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/include/llvm/Object/ELF.h @@ -90,32 +90,6 @@ template class ELFFile { public: LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) - using uintX_t = typename ELFT::uint; - using Elf_Ehdr = typename ELFT::Ehdr; - using Elf_Shdr = typename ELFT::Shdr; - using Elf_Sym = typename ELFT::Sym; - using Elf_Dyn = typename ELFT::Dyn; - using Elf_Phdr = typename ELFT::Phdr; - using Elf_Rel = typename ELFT::Rel; - using Elf_Rela = typename ELFT::Rela; - using Elf_Relr = typename ELFT::Relr; - using Elf_Verdef = typename ELFT::Verdef; - using Elf_Verdaux = typename ELFT::Verdaux; - using Elf_Verneed = typename ELFT::Verneed; - using Elf_Vernaux = typename ELFT::Vernaux; - using Elf_Versym = typename ELFT::Versym; - using Elf_Hash = typename ELFT::Hash; - using Elf_GnuHash = typename ELFT::GnuHash; - using Elf_Nhdr = typename ELFT::Nhdr; - using Elf_Note = typename ELFT::Note; - using Elf_Note_Iterator = typename ELFT::NoteIterator; - using Elf_Dyn_Range = typename ELFT::DynRange; - using Elf_Shdr_Range = typename ELFT::ShdrRange; - using Elf_Sym_Range = typename ELFT::SymRange; - using Elf_Rel_Range = typename ELFT::RelRange; - using Elf_Rela_Range = typename ELFT::RelaRange; - using Elf_Relr_Range = typename ELFT::RelrRange; - using Elf_Phdr_Range = typename ELFT::PhdrRange; // This is a callback that can be passed to a number of functions. // It can be used to ignore non-critical errors (warnings), which is diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index ca4363572d90..33b4c28db951 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -233,15 +233,6 @@ template class ELFObjectFile : public ELFObjectFileBase { public: LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) - using uintX_t = typename ELFT::uint; - - using Elf_Sym = typename ELFT::Sym; - using Elf_Shdr = typename ELFT::Shdr; - using Elf_Ehdr = typename ELFT::Ehdr; - using Elf_Rel = typename ELFT::Rel; - using Elf_Rela = typename ELFT::Rela; - using Elf_Dyn = typename ELFT::Dyn; - SectionRef toSectionRef(const Elf_Shdr *Sec) const { return SectionRef(toDRI(Sec), this); } diff --git a/llvm/include/llvm/Object/ELFTypes.h b/llvm/include/llvm/Object/ELFTypes.h index 5e85e6cc4653..f64e7c06e03b 100644 --- a/llvm/include/llvm/Object/ELFTypes.h +++ b/llvm/include/llvm/Object/ELFTypes.h @@ -107,7 +107,34 @@ using ELF64BE = ELFType; using Elf_Word = typename ELFT::Word; \ using Elf_Sword = typename ELFT::Sword; \ using Elf_Xword = typename ELFT::Xword; \ - using Elf_Sxword = typename ELFT::Sxword; + using Elf_Sxword = typename ELFT::Sxword; \ + using uintX_t = typename ELFT::uint; \ + using Elf_Ehdr = typename ELFT::Ehdr; \ + using Elf_Shdr = typename ELFT::Shdr; \ + using Elf_Sym = typename ELFT::Sym; \ + using Elf_Dyn = typename ELFT::Dyn; \ + using Elf_Phdr = typename ELFT::Phdr; \ + using Elf_Rel = typename ELFT::Rel; \ + using Elf_Rela = typename ELFT::Rela; \ + using Elf_Relr = typename ELFT::Relr; \ + using Elf_Verdef = typename ELFT::Verdef; \ + using Elf_Verdaux = typename ELFT::Verdaux; \ + using Elf_Verneed = typename ELFT::Verneed; \ + using Elf_Vernaux = typename ELFT::Vernaux;
[llvm-branch-commits] [llvm] 177779e - [llvm-readelf/obj] - Improve the warning reported when unable to read the stack size.
Author: Georgii Rymar Date: 2020-12-25T11:40:35+03:00 New Revision: 19e8dd9f7d20b96d4711a81d65ab7d480bb5 URL: https://github.com/llvm/llvm-project/commit/19e8dd9f7d20b96d4711a81d65ab7d480bb5 DIFF: https://github.com/llvm/llvm-project/commit/19e8dd9f7d20b96d4711a81d65ab7d480bb5.diff LOG: [llvm-readelf/obj] - Improve the warning reported when unable to read the stack size. It was discussed in D92545 that we might want to improve messages reported when something is wrong with the stack size section. This patch does it. Differential revision: https://reviews.llvm.org/D93802 Added: Modified: llvm/test/tools/llvm-readobj/ELF/stack-sizes.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test b/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test index 9d0c0b532e5e..8a8e481d8ff3 100644 --- a/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test +++ b/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test @@ -442,11 +442,13 @@ Symbols: ## ends in a byte with the high bit set. # RUN: yaml2obj --docnum=6 %s -o %t06 -# RUN: llvm-readelf --stack-sizes %t06 2>&1 | FileCheck %s --check-prefix=BADSIZE -DFILE=%t06 -# RUN: llvm-readobj --stack-sizes %t06 2>&1 | FileCheck %s --check-prefix=BADSIZE -DFILE=%t06 +# RUN: llvm-readelf --stack-sizes %t06 2>&1 | \ +# RUN: FileCheck %s --check-prefix=BADSIZE -DFILE=%t06 --implicit-check-not=warning: +# RUN: llvm-readobj --stack-sizes %t06 2>&1 | \ +# RUN: FileCheck %s --check-prefix=BADSIZE -DFILE=%t06 --implicit-check-not=warning: -# BADSIZE: warning: '[[FILE]]': could not extract a valid stack size from SHT_PROGBITS section with index 2 -# BADSIZE: warning: '[[FILE]]': could not extract a valid stack size from SHT_PROGBITS section with index 3 +# BADSIZE: warning: '[[FILE]]': could not extract a valid stack size from SHT_PROGBITS section with index 2: unable to decode LEB128 at offset 0x0008: malformed uleb128, extends past end +# BADSIZE: warning: '[[FILE]]': could not extract a valid stack size from SHT_PROGBITS section with index 3: unable to decode LEB128 at offset 0x0008: malformed uleb128, extends past end --- !ELF FileHeader: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index fe2aad166250..8fbef39c5a25 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -759,7 +759,7 @@ template class DumpStyle { virtual void printStackSizes() = 0; void printNonRelocatableStackSizes(std::function PrintHeader); void printRelocatableStackSizes(std::function PrintHeader); - void printFunctionStackSize(uint64_t SymValue, + bool printFunctionStackSize(uint64_t SymValue, Optional FunctionSec, const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset); @@ -5833,7 +5833,7 @@ template void GNUStyle::printDependentLibs() { } template -void DumpStyle::printFunctionStackSize( +bool DumpStyle::printFunctionStackSize( uint64_t SymValue, Optional FunctionSec, const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) { uint32_t FuncSymIndex = 0; @@ -5893,16 +5893,16 @@ void DumpStyle::printFunctionStackSize( // Extract the size. The expectation is that Offset is pointing to the right // place, i.e. past the function address. - uint64_t PrevOffset = *Offset; - uint64_t StackSize = Data.getULEB128(Offset); - // getULEB128() does not advance Offset if it is not able to extract a valid - // integer. - if (*Offset == PrevOffset) { + Error Err = Error::success(); + uint64_t StackSize = Data.getULEB128(Offset, &Err); + if (Err) { reportUniqueWarning("could not extract a valid stack size from " + -describe(Obj, StackSizeSec)); -return; +describe(Obj, StackSizeSec) + ": " + +toString(std::move(Err))); +return false; } printStackSizeEntry(StackSize, FuncName); + return true; } template @@ -5991,8 +5991,9 @@ void DumpStyle::printNonRelocatableStackSizes( break; } uint64_t SymValue = Data.getAddress(&Offset); - printFunctionStackSize(SymValue, /*FunctionSec=*/None, Sec, Data, - &Offset); + if (!printFunctionStackSize(SymValue, /*FunctionSec=*/None, Sec, Data, + &Offset)) +break; } } } ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 893c84d - [obj2yaml] - Dump the content of a broken hash table properly.
Author: Georgii Rymar Date: 2020-12-25T11:51:28+03:00 New Revision: 893c84d71c4ad223ae495d66a0c733a91c72e7bf URL: https://github.com/llvm/llvm-project/commit/893c84d71c4ad223ae495d66a0c733a91c72e7bf DIFF: https://github.com/llvm/llvm-project/commit/893c84d71c4ad223ae495d66a0c733a91c72e7bf.diff LOG: [obj2yaml] - Dump the content of a broken hash table properly. This is similar to D93760. When something is wrong with the hash table header we dump its context as a raw data. Currently we have the calculation overflow issue and it is possible to bypass the validation we have (and crash). The patch fixes it. Differential revision: https://reviews.llvm.org/D93799 Added: Modified: llvm/test/tools/obj2yaml/ELF/hash-section.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/test/tools/obj2yaml/ELF/hash-section.yaml b/llvm/test/tools/obj2yaml/ELF/hash-section.yaml index 389b4bbb6972..57d823b3a0be 100644 --- a/llvm/test/tools/obj2yaml/ELF/hash-section.yaml +++ b/llvm/test/tools/obj2yaml/ELF/hash-section.yaml @@ -49,6 +49,13 @@ Sections: # CONTENT-NEXT: - Name:.oversized # CONTENT-NEXT: Type:SHT_HASH # CONTENT-NEXT: Content: '01000200030004' +# CONTENT-NEXT: - Name:.overflow1 +# CONTENT-NEXT: Type:SHT_HASH +# CONTENT-NEXT: Content: 0100{{$}} +# CONTENT-NEXT: - Name:.overflow2 +# CONTENT-NEXT: Type:SHT_HASH +# CONTENT-NEXT: Content: 0100{{$}} +# CONTENT-NEXT: ... --- !ELF FileHeader: @@ -74,6 +81,20 @@ Sections: - Name:.oversized Type:SHT_HASH Content: '01000200030004' +## Case 5, 6: NChain/NBucket are incorrect and causing 32-bit +##unsigned overflows of intermediate expressions. + - Name:.overflow1 +Type:SHT_HASH +Bucket: [ ] +Chain: [ ] +NBucket: 0x1 +NChain: 0x + - Name:.overflow2 +Type:SHT_HASH +Bucket: [ ] +Chain: [ ] +NBucket: 0x +NChain: 0x1 ## Check how we dump the "EntSize" field. When the sh_entsize is 4, ## we don't print it, because it is the default value for the SHT_HASH section. diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 50c3e90eb667..da32eaba5a69 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -1224,8 +1224,8 @@ ELFDumper::dumpHashSection(const Elf_Shdr *Shdr) { DataExtractor::Cursor Cur(0); DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0); - uint32_t NBucket = Data.getU32(Cur); - uint32_t NChain = Data.getU32(Cur); + uint64_t NBucket = Data.getU32(Cur); + uint64_t NChain = Data.getU32(Cur); if (Content.size() != (2 + NBucket + NChain) * 4) { S->Content = yaml::BinaryRef(Content); if (Cur) ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 2584e1e - [llvm-readobj] - Don't crash when relocation table goes past the EOF.
Author: Georgii Rymar Date: 2020-11-23T10:31:04+03:00 New Revision: 2584e1e324c97eeeacc1e421e5f3191a708c3d2d URL: https://github.com/llvm/llvm-project/commit/2584e1e324c97eeeacc1e421e5f3191a708c3d2d DIFF: https://github.com/llvm/llvm-project/commit/2584e1e324c97eeeacc1e421e5f3191a708c3d2d.diff LOG: [llvm-readobj] - Don't crash when relocation table goes past the EOF. It is possible to trigger reading past the EOF by breaking fields like DT_PLTRELSZ, DT_RELSZ or DT_RELASZ This patch adds a validation in `DynRegionInfo` helper class. Differential revision: https://reviews.llvm.org/D91787 Added: Modified: llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test b/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test index bd7916a91fc1..741eaec90d13 100644 --- a/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test +++ b/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test @@ -49,11 +49,16 @@ ProgramHeaders: LastSec: .dynamic ## Show we print a warning for an invalid relocation table size stored in a DT_RELASZ entry. -# RUN: yaml2obj --docnum=2 -DRELTYPE=RELA -DTAG1=DT_RELASZ -DTAG1VAL=0xFF -DTAG2=DT_RELAENT %s -o %t2 -# RUN: llvm-readobj --dyn-relocations %t2 2>&1 | FileCheck %s -DFILE=%t2 --check-prefix=INVALID-DT-RELASZ -# RUN: llvm-readelf --dyn-relocations %t2 2>&1 | FileCheck %s -DFILE=%t2 --check-prefix=INVALID-DT-RELASZ -# INVALID-DT-RELASZ: warning: '[[FILE]]': invalid DT_RELASZ value (0xff) or DT_RELAENT value (0x18) +## Case A: the size of a single relocation entry is 0x18. In this case 0xFF % 0x18 != 0 and we report a warning + +# RUN: yaml2obj --docnum=2 -DRELTYPE=RELA -DTAG1=DT_RELASZ -DTAG1VAL=0xFF -DTAG2=DT_RELAENT %s -o %t2a +# RUN: llvm-readobj --dyn-relocations %t2a 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t2a --check-prefix=INVALID-DT-RELASZ1 --implicit-check-not=warning: +# RUN: llvm-readelf --dyn-relocations %t2a 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t2a --check-prefix=INVALID-DT-RELASZ1 --implicit-check-not=warning: + +# INVALID-DT-RELASZ1: warning: '[[FILE]]': invalid DT_RELASZ value (0xff) or DT_RELAENT value (0x18) --- !ELF FileHeader: @@ -80,19 +85,42 @@ ProgramHeaders: FirstSec: .relx.dyn LastSec: .dynamic +## Case B: the DT_RELASZ has value of 0x251, what is too large, because the relocation table goes past the EOF. + +# RUN: yaml2obj --docnum=2 -DRELTYPE=RELA -DTAG1=DT_RELASZ -DTAG1VAL=0x251 -DTAG2=DT_RELAENT %s -o %t2b +# RUN: llvm-readobj --dyn-relocations %t2b 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t2b --check-prefix=INVALID-DT-RELASZ2 --implicit-check-not=warning: +# RUN: llvm-readelf --dyn-relocations %t2b 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t2b --check-prefix=INVALID-DT-RELASZ2 --implicit-check-not=warning: + +# INVALID-DT-RELASZ2: warning: '[[FILE]]': unable to read data at 0x78 of size 0x251 (DT_RELASZ value): it goes past the end of the file of size 0x2c8 + ## Show we print a warning for an invalid relocation table entry size stored in a DT_RELAENT entry. # RUN: yaml2obj --docnum=2 -DRELTYPE=RELA -DTAG1=DT_RELASZ -DTAG2=DT_RELAENT -DTAG2VAL=0xFF %s -o %t3 -# RUN: llvm-readobj --dyn-relocations %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=INVALID-DT-RELAENT -# RUN: llvm-readelf --dyn-relocations %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=INVALID-DT-RELAENT +# RUN: llvm-readobj --dyn-relocations %t3 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t3 --check-prefix=INVALID-DT-RELAENT --implicit-check-not=warning: +# RUN: llvm-readelf --dyn-relocations %t3 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t3 --check-prefix=INVALID-DT-RELAENT --implicit-check-not=warning: ## INVALID-DT-RELAENT: warning: '[[FILE]]': invalid DT_RELASZ value (0x18) or DT_RELAENT value (0xff) ## Show we print a warning for an invalid relocation table size stored in a DT_RELSZ entry. -# RUN: yaml2obj --docnum=2 -DRELTYPE=REL -DTAG1=DT_RELSZ -DTAG1VAL=0xFF -DTAG2=DT_RELENT %s -o %t4 -# RUN: llvm-readobj --dyn-relocations %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=INVALID-DT-RELSZ -# RUN: llvm-readelf --dyn-relocations %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=INVALID-DT-RELSZ -## INVALID-DT-RELSZ: warning: '[[FILE]]': invalid DT_RELSZ value (0xff) or DT_RELENT value (0x18) +## Case A: the size of a single relocation entry is 0x18. In this case 0xFF % 0x18 != 0 and we report a warning. + +# RUN: yaml2obj --docnum=2 -DRELTYPE=REL -DTAG1=DT_RELSZ -DTAG1VAL=0xFF -DTAG2=DT_RELENT %s -o %t4a +# RUN: llvm-readobj --dyn-relocations %t4a 2>&1 | FileCheck %s -DFILE=%t4a --check-prefix=INVALID-DT-RELSZ1 +# RUN: llvm-readelf --dyn-relocations %t4a 2>&1 | FileCheck %s -DFILE=%t4a --check-prefix=INVALID-DT-RELSZ1 + +## INVALID-DT-RELSZ1: warning: '[[FILE]]': invalid DT_RELSZ value
[llvm-branch-commits] [llvm] 4dcdf0d - [llvm-readobj] - Stop using `unwrapOrError` in `DumpStyle::getGroups()`
Author: Georgii Rymar Date: 2020-11-23T12:48:33+03:00 New Revision: 4dcdf0df31259c1c02a1f7bbaa7ae45ca6c814dc URL: https://github.com/llvm/llvm-project/commit/4dcdf0df31259c1c02a1f7bbaa7ae45ca6c814dc DIFF: https://github.com/llvm/llvm-project/commit/4dcdf0df31259c1c02a1f7bbaa7ae45ca6c814dc.diff LOG: [llvm-readobj] - Stop using `unwrapOrError` in `DumpStyle::getGroups()` With this we are able to diagnose possible issues much better and don't exit on an error. Differential revision: https://reviews.llvm.org/D91867 Added: Modified: llvm/test/tools/llvm-readobj/ELF/groups.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/groups.test b/llvm/test/tools/llvm-readobj/ELF/groups.test index a5f4338729d0..00696470e078 100644 --- a/llvm/test/tools/llvm-readobj/ELF/groups.test +++ b/llvm/test/tools/llvm-readobj/ELF/groups.test @@ -48,28 +48,32 @@ FileHeader: Sections: - Name: .group Type: SHT_GROUP -Link: .symtab +Link: [[SYMTAB1=.symtab]] Info: foo Members: - SectionOrType: GRP_COMDAT - SectionOrType: .text.foo - - SectionOrType: .rela.text.foo + - SectionOrType: [[MEMBER1=.rela.text.foo]] +ShSize: [[SECSIZE1=]] +ShName: [[GROUP1SHNAME=]] - Name: .group1 Type: SHT_GROUP -Link: .symtab +Link: [[SYMTAB2=.symtab]] Info: bar Members: - SectionOrType: GRP_COMDAT - - SectionOrType: [[TEXTBARNAME=.text.bar]] + - SectionOrType: [[MEMBER2=.text.bar]] - SectionOrType: .rela.text.bar +ShSize: [[SECSIZE2=]] - Name: .text.foo Type: SHT_PROGBITS - Name: .rela.text.foo Type: SHT_RELA Link: .symtab Info: .text.foo - - Name: .text.bar -Type: SHT_PROGBITS + - Name: .text.bar +Type: SHT_PROGBITS +ShName: [[TEXTBARSHNAME=]] - Name: .rela.text.bar Type: SHT_RELA Link: .symtab @@ -86,7 +90,7 @@ Symbols: ## Check that we report a warning and continue dumping when a section is included ## in two group sections at the same time. -# RUN: yaml2obj %s -DTEXTBARNAME=.text.foo -o %t.dup.o +# RUN: yaml2obj %s -DMEMBER2=.text.foo -o %t.dup.o # RUN: llvm-readobj --elf-section-groups %t.dup.o 2>&1 | FileCheck %s -DFILE=%t.dup.o --check-prefix=DUP-LLVM # RUN: llvm-readelf --elf-section-groups %t.dup.o 2>&1 | FileCheck %s -DFILE=%t.dup.o --check-prefix=DUP-GNU @@ -127,6 +131,11 @@ Symbols: # DUP-GNU-NEXT:[3] .text.foo # DUP-GNU-NEXT:[6] .rela.text.bar +## Check what we do when we are unable to dump the signature symbol name. +## In this case the index of the string table section, linked to the symbol table used by a group section, +## is broken (section does not exist). +## Check we report a warning in this case. Check we don't print the same warning message twice. + # RUN: yaml2obj %s -DSYMTABLINK=0xFF -o %t.symtab.o # RUN: llvm-readobj --elf-section-groups %t.symtab.o 2>&1 | \ # RUN: FileCheck -DFILE=%t.symtab.o %s --check-prefix=SYMTAB-LLVM --implicit-check-not=warning: @@ -172,3 +181,201 @@ Symbols: # SYMTAB-GNU-NEXT: [Index]Name # SYMTAB-GNU-NEXT: [5] .text.bar # SYMTAB-GNU-NEXT: [6] .rela.text.bar + +## This tests the behavior for two more cases when we are unable to dump the signature symbol name. +## In the first case we link the group section to the section with index 255, which does not exist. +## We check that a warning is reported when we are unable to locate the symbol table. +## In the second case we link the SHT_GROUP section to itself. This documents that we don't check the +## type of the linked section (we assume it is the symbol table) and checks that we report a warning +## when we are unable to read a signature symbol. + +# RUN: yaml2obj %s -DSYMTAB1=0xFF -DSYMTAB2=0x1 -o %t.symtab2.o +# RUN: llvm-readobj --elf-section-groups %t.symtab2.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.symtab2.o %s --check-prefix=SIGNATURE-LLVM --implicit-check-not=warning: +# RUN: llvm-readelf --elf-section-groups %t.symtab2.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.symtab2.o %s --check-prefix=SIGNATURE-GNU --implicit-check-not=warning: + +# SIGNATURE: Groups { +# SIGNATURE-LLVM: warning: '[[FILE]]': unable to get the symbol table for SHT_GROUP section with index 1: invalid section index: 255 +# SIGNATURE-LLVM: warning: '[[FILE]]': unable to get the signature symbol for SHT_GROUP section with index 2: section [index 1] has invalid sh_entsize: expected 24, but got 4 +# SIGNATURE-LLVM: Group { +# SIGNATURE-LLVM: Name: .group (16) +# SIGNATURE-LLVM: Index: 1 +# SIGNATURE-LLVM: Link: 255 +# SIGNATURE-LLVM: Info: 1 +# SIGNATURE-LLVM: Type: COMDAT (0x1) +# SIGNATURE-LLVM: Signature: +# SIGNATURE-LLVM: Section(s) in group [ +# SIGNATURE-LLVM: .text.foo (3) +# SIGNATURE-LLVM: .rela.text.foo (4) +# SIGNAT
[llvm-branch-commits] [llvm] 76a626b - [llvm-readelf/obj] - Fix the possible crash when dumping group sections.
Author: Georgii Rymar Date: 2020-11-23T13:05:12+03:00 New Revision: 76a626b2061bc8a33656a49ebcabbfa75c317d4c URL: https://github.com/llvm/llvm-project/commit/76a626b2061bc8a33656a49ebcabbfa75c317d4c DIFF: https://github.com/llvm/llvm-project/commit/76a626b2061bc8a33656a49ebcabbfa75c317d4c.diff LOG: [llvm-readelf/obj] - Fix the possible crash when dumping group sections. It is possible to trigger a crash/misbehavior when the st_name field of the signature symbol goes past the end of the string table. This patch fixes it. Differential revision: https://reviews.llvm.org/D91943 Added: Modified: llvm/test/tools/llvm-readobj/ELF/groups.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/groups.test b/llvm/test/tools/llvm-readobj/ELF/groups.test index 00696470e078..afdc63e9dc0b 100644 --- a/llvm/test/tools/llvm-readobj/ELF/groups.test +++ b/llvm/test/tools/llvm-readobj/ELF/groups.test @@ -81,11 +81,16 @@ Sections: - Name: .symtab Type: SHT_SYMTAB Link: [[SYMTABLINK=.strtab]] + - Name:.strtab +Type:SHT_STRTAB +Content: [[STRTABCONTENT=]] Symbols: - Name:foo Section: .text.foo +StName: [[SYM1STNAME=]] - Name:bar Section: .text.bar +StName: [[SYM2STNAME=]] ## Check that we report a warning and continue dumping when a section is included ## in two group sections at the same time. @@ -379,3 +384,37 @@ Symbols: # MEMBER-GNU-NEXT: [Index]Name # MEMBER-GNU-NEXT: [ 255] # MEMBER-GNU-NEXT: [6] .rela.text.bar + +## Check warnings that are reported when the st_name field of the signature symbol goes past the end of the string table. + +## We set the content of the string table to '0061626300' ('\0abc\0') to fixup the size of the string table. +## This makes it easier to test the boundary conditions. +# RUN: yaml2obj %s -DSTRTABCONTENT="0061626300" -DSYM1STNAME=4 -DSYM2STNAME=5 -o %t.signame.o +# RUN: llvm-readobj --elf-section-groups %t.signame.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.signame.o %s --check-prefixes=SIGNAME1-WARN,SIGNAME1-LLVM --implicit-check-not=warning: +# RUN: llvm-readelf --elf-section-groups %t.signame.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.signame.o %s --check-prefixes=SIGNAME1-WARN,SIGNAME1-GNU --implicit-check-not=warning: + +# SIGNAME1-WARN: warning: '[[FILE]]': unable to get the name of the symbol with index 2: st_name (0x5) is past the end of the string table of size 0x5 + +# SIGNAME1-LLVM: Signature: {{$}} +# SIGNAME1-LLVM: Signature: + +# SIGNAME1-GNU: COMDAT group section [1] `.group' [] contains 2 sections: +# SIGNAME1-GNU: COMDAT group section [2] `.group1' [] contains 2 sections: + +## Chech we report a warning when the string table that contains the signature symbol name is not null-terminated. + +# RUN: yaml2obj %s -DSTRTABCONTENT="0061626361" -DSYM1STNAME=4 -DSYM2STNAME=5 -o %t.signame2.o +# RUN: llvm-readobj --elf-section-groups %t.signame2.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.signame2.o %s --check-prefixes=SIGNAME2-WARN,SIGNAME2-LLVM --implicit-check-not=warning: +# RUN: llvm-readelf --elf-section-groups %t.signame2.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t.signame2.o %s --check-prefixes=SIGNAME2-WARN,SIGNAME2-GNU --implicit-check-not=warning: + +# SIGNAME2-WARN: warning: '[[FILE]]': unable to get the string table for SHT_SYMTAB section with index 7: SHT_STRTAB string table section [index 8] is non-null terminated + +# SIGNAME2-LLVM: Signature: +# SIGNAME2-LLVM: Signature: + +# SIGNAME2-GNU: COMDAT group section [1] `.group' [] contains 2 sections: +# SIGNAME2-GNU: COMDAT group section [2] `.group1' [] contains 2 sections: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 3e54c3599428..c5eb2d628b0b 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -3595,7 +3595,7 @@ static StringRef tryGetSectionName(const ELFFile &Obj, } template std::vector DumpStyle::getGroups() { - auto GetSignature = [&](const Elf_Sym &Sym, + auto GetSignature = [&](const Elf_Sym &Sym, unsigned SymNdx, const Elf_Shdr &Symtab) -> StringRef { Expected StrTableOrErr = Obj.getStringTableForSymtab(Symtab); if (!StrTableOrErr) { @@ -3605,8 +3605,16 @@ template std::vector DumpStyle::getGroups() { return ""; } -// TODO: this might lead to a crash or produce a wrong result, when the -// st_name goes past the end of the string table. +StringRef Strings = *StrTableOrErr; +if (Sym.st_name >= Strings.size()) { + reportUniqueWarning(createError( + "unable to get the name of the symbol with index " + Twine(SymNdx) + + ": st_name (0x" + Twine::utohexstr(Sym.st_name) + + ") is past the end of the string table of size 0x" + +
[llvm-branch-commits] [llvm] 2745d9c - [llvm-readobj][test] - Simplify the gnu-notes.test
Author: Georgii Rymar Date: 2020-11-23T16:26:02+03:00 New Revision: 2745d9c586d1fea438f5542dfd0718feefd14ad9 URL: https://github.com/llvm/llvm-project/commit/2745d9c586d1fea438f5542dfd0718feefd14ad9 DIFF: https://github.com/llvm/llvm-project/commit/2745d9c586d1fea438f5542dfd0718feefd14ad9.diff LOG: [llvm-readobj][test] - Simplify the gnu-notes.test This test contains YAMLs that can be merged with use of macros. This opens road for adding more test cases. Differential revision: https://reviews.llvm.org/D91953 Added: Modified: llvm/test/tools/llvm-readobj/ELF/gnu-notes.test Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test b/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test index efc7f6e57094..04430577daaf 100644 --- a/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test +++ b/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test @@ -112,7 +112,7 @@ ProgramHeaders: ## Test tools report an error if a note section has an invalid offset ## that goes past the end of file. -# RUN: yaml2obj --docnum=2 %s -o %t2.so +# RUN: yaml2obj --docnum=2 -DSHOFFSET=0x %s -o %t2.so # RUN: not llvm-readelf --notes %t2.so 2>&1 | FileCheck -DFILE=%t2.so %s --check-prefix=ERR1 # RUN: not llvm-readobj --notes %t2.so 2>&1 | FileCheck -DFILE=%t2.so %s --check-prefix=ERR1 @@ -127,32 +127,22 @@ Sections: - Name: .note Type: SHT_NOTE Notes:[] -ShOffset: 0x +ShOffset: [[SHOFFSET=]] +ShSize: [[SHSIZE=]] ## Test tools report an error if a note section has invalid size ## that goes past the end of file. -# RUN: yaml2obj --docnum=3 %s -o %t3.so +# RUN: yaml2obj --docnum=2 -DSHSIZE=0x %s -o %t3.so # RUN: not llvm-readelf --notes %t3.so 2>&1 | FileCheck -DFILE=%t3.so %s --check-prefix=ERR2 # RUN: not llvm-readobj --notes %t3.so 2>&1 | FileCheck -DFILE=%t3.so %s --check-prefix=ERR2 # ERR2: error: '[[FILE]]': SHT_NOTE section [index 1] has invalid offset (0x40) or size (0x) !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_EXEC -Sections: - - Name: .note -Type: SHT_NOTE -ShSize: 0x -Notes: [] - ## Test tools report an error if a note program header has an invalid offset that ## goes past the end of file. -# RUN: yaml2obj --docnum=4 %s -o %t4.so +# RUN: yaml2obj --docnum=3 -DPHOFFSET=0x %s -o %t4.so # RUN: not llvm-readelf --notes %t4.so 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefix=ERR3 # RUN: not llvm-readobj --notes %t4.so 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefix=ERR3 @@ -164,32 +154,18 @@ FileHeader: Data: ELFDATA2LSB Type: ET_CORE ProgramHeaders: - - Type: PT_NOTE -Offset: 0x + - Type: PT_NOTE +Offset: [[PHOFFSET=]] +FileSize: [[PHFILESIZE=]] ## Test tools report an error if a note program header has an invalid size that ## goes past the end of file. -# RUN: yaml2obj --docnum=5 %s -o %t5.so +# RUN: yaml2obj --docnum=3 -DPHFILESIZE=0x %s -o %t5.so # RUN: not llvm-readelf --notes %t5.so 2>&1 | FileCheck -DFILE=%t5.so %s --check-prefix=ERR4 # RUN: not llvm-readobj --notes %t5.so 2>&1 | FileCheck -DFILE=%t5.so %s --check-prefix=ERR4 -# ERR4: error: '[[FILE]]': PT_NOTE header has invalid offset (0x78) or size (0x) - !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_CORE -Sections: - - Name: .note -Type: SHT_NOTE -Notes: [] -ProgramHeaders: - - Type: PT_NOTE -FileSize: 0x -FirstSec: .note -LastSec: .note +# ERR4: error: '[[FILE]]': PT_NOTE header has invalid offset (0x0) or size (0x) ## Check we report a warning when we are unable to locate the PT_NOTE ## segment because of broken program headers. ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] ec0b927 - [llvm-readelf/obj] - Deduplicate the logic that prints notes. NFCI.
Author: Georgii Rymar Date: 2020-11-25T11:04:13+03:00 New Revision: ec0b927e4aa863dd610b97f3d6e996ca05475846 URL: https://github.com/llvm/llvm-project/commit/ec0b927e4aa863dd610b97f3d6e996ca05475846 DIFF: https://github.com/llvm/llvm-project/commit/ec0b927e4aa863dd610b97f3d6e996ca05475846.diff LOG: [llvm-readelf/obj] - Deduplicate the logic that prints notes. NFCI. We have a similar logic for LLVM/GNU styles that can be deduplicated. This will allow to replace `reportError` calls with `reportUniqueWarning` calls in a single place. Differential revision: https://reviews.llvm.org/D92018 Added: Modified: llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index d1a5aa7e0e5d..3676ee9724d3 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -5541,6 +5541,54 @@ const StringRef getNoteTypeName(const typename ELFT::Note &Note, return FindNote(GenericNoteTypes); } +template +static void printNotesHelper( +const ELFDumper &Dumper, +llvm::function_ref, typename ELFT::Off, +typename ELFT::Addr)> +StartNotesFn, +llvm::function_ref ProcessNoteFn, +llvm::function_ref FinishNotesFn = []() {}) { + const ELFFile &Obj = *Dumper.getElfObject().getELFFile(); + + ArrayRef Sections = cantFail(Obj.sections()); + if (Obj.getHeader().e_type != ELF::ET_CORE && !Sections.empty()) { +for (const typename ELFT::Shdr &S : Sections) { + if (S.sh_type != SHT_NOTE) +continue; + StartNotesFn(expectedToOptional(Obj.getSectionName(S)), S.sh_offset, + S.sh_size); + Error Err = Error::success(); + for (const typename ELFT::Note &Note : Obj.notes(S, Err)) +ProcessNoteFn(Note); + if (Err) +reportError(std::move(Err), Dumper.getElfObject().getFileName()); + FinishNotesFn(); +} +return; + } + + Expected> PhdrsOrErr = Obj.program_headers(); + if (!PhdrsOrErr) { +Dumper.reportUniqueWarning(createError( +"unable to read program headers to locate the PT_NOTE segment: " + +toString(PhdrsOrErr.takeError(; +return; + } + + for (const typename ELFT::Phdr &P : *PhdrsOrErr) { +if (P.p_type != PT_NOTE) + continue; +StartNotesFn(/*SecName=*/None, P.p_offset, P.p_filesz); +Error Err = Error::success(); +for (const typename ELFT::Note Note : Obj.notes(P, Err)) + ProcessNoteFn(Note); +if (Err) + reportError(std::move(Err), Dumper.getElfObject().getFileName()); +FinishNotesFn(); + } +} + template void GNUStyle::printNotes() { auto PrintHeader = [&](Optional SecName, const typename ELFT::Off Offset, @@ -5603,39 +5651,7 @@ template void GNUStyle::printNotes() { } }; - ArrayRef Sections = cantFail(this->Obj.sections()); - if (this->Obj.getHeader().e_type != ELF::ET_CORE && !Sections.empty()) { -for (const Elf_Shdr &S : Sections) { - if (S.sh_type != SHT_NOTE) -continue; - PrintHeader(expectedToOptional(this->Obj.getSectionName(S)), S.sh_offset, - S.sh_size); - Error Err = Error::success(); - for (const Elf_Note Note : this->Obj.notes(S, Err)) -ProcessNote(Note); - if (Err) -reportError(std::move(Err), this->FileName); -} - } else { -Expected> PhdrsOrErr = this->Obj.program_headers(); -if (!PhdrsOrErr) { - this->reportUniqueWarning(createError( - "unable to read program headers to locate the PT_NOTE segment: " + - toString(PhdrsOrErr.takeError(; - return; -} - -for (const Elf_Phdr &P : *PhdrsOrErr) { - if (P.p_type != PT_NOTE) -continue; - PrintHeader(/*SecName=*/None, P.p_offset, P.p_filesz); - Error Err = Error::success(); - for (const Elf_Note Note : this->Obj.notes(P, Err)) -ProcessNote(Note); - if (Err) -reportError(std::move(Err), this->FileName); -} - } + printNotesHelper(this->dumper(), PrintHeader, ProcessNote); } template void GNUStyle::printELFLinkerOptions() { @@ -6828,14 +6844,18 @@ static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) { template void LLVMStyle::printNotes() { ListScope L(W, "Notes"); - auto PrintHeader = [&](Optional SecName, - const typename ELFT::Off Offset, - const typename ELFT::Addr Size) { + std::unique_ptr NoteScope; + auto StartNotes = [&](Optional SecName, +const typename ELFT::Off Offset, +const typename ELFT::Addr Size) { +NoteScope = std::make_unique(W, "NoteSection"); W.printString("Name", SecName ? *SecName : ""); W.printHex("Offset", Offset); W.printHex("Size", Size); }; + auto EndNotes = [&] { N
[llvm-branch-commits] [llvm] ae7ac2d - [llvm-readobj] - An attempt to fix BB after D92018.
Author: Georgii Rymar Date: 2020-11-25T11:38:58+03:00 New Revision: ae7ac2d6654a18bd90db08a882c6ba91afee6ed9 URL: https://github.com/llvm/llvm-project/commit/ae7ac2d6654a18bd90db08a882c6ba91afee6ed9 DIFF: https://github.com/llvm/llvm-project/commit/ae7ac2d6654a18bd90db08a882c6ba91afee6ed9.diff LOG: [llvm-readobj] - An attempt to fix BB after D92018. AVR and PPC64 bots reports link errors: (http://lab.llvm.org:8011/#/builders/112/builds/1522) (http://lab.llvm.org:8011/#/builders/52/builds/1764) /tmp/cclOvLx0.s: Assembler messages: /tmp/cclOvLx0.s:9223: Error: symbol `_ZN4llvm12function_refIFvvEE11callback_fnIUlvE2_EEvl' is already defined /tmp/cclOvLx0.s:9227: Error: symbol `.L._ZN4llvm12function_refIFvvEE11callback_fnIUlvE2_EEvl' is already defined /tmp/cclOvLx0.s:10272: Error: symbol `_ZN4llvm12function_refIFvvEE11callback_fnIUlvE2_EEvl' is already defined /tmp/cclOvLx0.s:10276: Error: symbol `.L._ZN4llvm12function_refIFvvEE11callback_fnIUlvE2_EEvl' is already defined /tmp/cclOvLx0.s:10285: Error: symbol `_ZN4llvm12function_refIFvvEE11callback_fnIUlvE2_EEvl' is already defined /tmp/cclOvLx0.s:10289: Error: symbol `.L._ZN4llvm12function_refIFvvEE11callback_fnIUlvE2_EEvl' is already defined /tmp/ccFJYr6I.s: Assembler messages: /tmp/ccFJYr6I.s:6284: Error: symbol `_ZN4llvm12function_refIFvvEE11callback_fnIUlvE2_EEvl' is already defined /tmp/ccFJYr6I.s:7053: Error: symbol `_ZN4llvm12function_refIFvvEE11callback_fnIUlvE2_EEvl' is already defined /tmp/ccFJYr6I.s:7093: Error: symbol `_ZN4llvm12function_refIFvvEE11callback_fnIUlvE2_EEvl' is already defined I *guess* the reason might be the default lambda argument. I've removed it. Added: Modified: llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 3676ee9724d3..c5f506bb21f8 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -5548,7 +5548,7 @@ static void printNotesHelper( typename ELFT::Addr)> StartNotesFn, llvm::function_ref ProcessNoteFn, -llvm::function_ref FinishNotesFn = []() {}) { +llvm::function_ref FinishNotesFn) { const ELFFile &Obj = *Dumper.getElfObject().getELFFile(); ArrayRef Sections = cantFail(Obj.sections()); @@ -5651,7 +5651,7 @@ template void GNUStyle::printNotes() { } }; - printNotesHelper(this->dumper(), PrintHeader, ProcessNote); + printNotesHelper(this->dumper(), PrintHeader, ProcessNote, []() {}); } template void GNUStyle::printELFLinkerOptions() { ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 5edb90c - [obj2yaml] - Dump section offsets in some cases.
Author: Georgii Rymar Date: 2020-11-25T12:41:01+03:00 New Revision: 5edb90c927131b9153da98634241ef74419a3b4d URL: https://github.com/llvm/llvm-project/commit/5edb90c927131b9153da98634241ef74419a3b4d DIFF: https://github.com/llvm/llvm-project/commit/5edb90c927131b9153da98634241ef74419a3b4d.diff LOG: [obj2yaml] - Dump section offsets in some cases. Currently we never dump the `sh_offset` key. Though it sometimes an important information. To reduce the noise this patch implements the following logic: 1) The "Offset" key for the first section is always emitted. 2) If we can derive the offset for a next section naturally, then the "Offset" key is omitted. By "naturally" I mean that section[X] offset is expected to be: ``` offsetOf(section[X]) == alignTo(section[X - 1].sh_offset + section[X - 1].sh_size, section[X].sh_addralign) ``` So, when it has the expected value, we omit it from the output. Differential revision: https://reviews.llvm.org/D91152 Added: llvm/test/tools/obj2yaml/ELF/offset.yaml Modified: llvm/include/llvm/ObjectYAML/ELFYAML.h llvm/lib/ObjectYAML/ELFEmitter.cpp llvm/test/Object/obj2yaml.test llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index 058d78d4f4fd..9015fb680b60 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -658,6 +658,9 @@ struct Object { unsigned getMachine() const; }; +bool shouldAllocateFileSpace(ArrayRef Phdrs, + const NoBitsSection &S); + } // end namespace ELFYAML } // end namespace llvm diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index b31b7681adad..b8386bd46be2 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -1135,8 +1135,8 @@ void ELFState::setProgramHeaderLayout(std::vector &PHeaders, } } -static bool shouldAllocateFileSpace(ArrayRef Phdrs, -const ELFYAML::NoBitsSection &S) { +bool llvm::ELFYAML::shouldAllocateFileSpace( +ArrayRef Phdrs, const ELFYAML::NoBitsSection &S) { for (const ELFYAML::ProgramHeader &PH : Phdrs) { auto It = llvm::find_if( PH.Chunks, [&](ELFYAML::Chunk *C) { return C->Name == S.Name; }); diff --git a/llvm/test/Object/obj2yaml.test b/llvm/test/Object/obj2yaml.test index ea6194dee9a6..840440406456 100644 --- a/llvm/test/Object/obj2yaml.test +++ b/llvm/test/Object/obj2yaml.test @@ -362,6 +362,7 @@ # ELF-MIPSEL-NEXT: Type:SHT_REL # ELF-MIPSEL-NEXT: Link:.symtab # ELF-MIPSEL-NEXT: AddressAlign:0x4 +# ELF-MIPSEL-NEXT: Offset: 0x434 # ELF-MIPSEL-NEXT: Info:.text # ELF-MIPSEL-NEXT: Relocations: # ELF-MIPSEL-NEXT: - Symbol: _gp_disp @@ -385,6 +386,7 @@ # ELF-MIPSEL-NEXT: Type:SHT_PROGBITS # ELF-MIPSEL-NEXT: Flags: [ SHF_WRITE, SHF_ALLOC ] # ELF-MIPSEL-NEXT: AddressAlign:0x4 +# ELF-MIPSEL-NEXT: Offset: 0x80 # ELF-MIPSEL-NEXT: - Name:.bss # ELF-MIPSEL-NEXT: Type:SHT_NOBITS # ELF-MIPSEL-NEXT: Flags: [ SHF_WRITE, SHF_ALLOC ] @@ -482,6 +484,7 @@ # ELF-MIPS64EL-NEXT: Type:SHT_RELA # ELF-MIPS64EL-NEXT: Link:.symtab # ELF-MIPS64EL-NEXT: AddressAlign:0x8 +# ELF-MIPS64EL-NEXT: Offset: 0x410 # ELF-MIPS64EL-NEXT: Info:.data # ELF-MIPS64EL-NEXT: Relocations: # ELF-MIPS64EL-NEXT: - Symbol: zed @@ -490,6 +493,7 @@ # ELF-MIPS64EL-NEXT: Type:SHT_NOBITS # ELF-MIPS64EL-NEXT: Flags: [ SHF_WRITE, SHF_ALLOC ] # ELF-MIPS64EL-NEXT: AddressAlign:0x10 +# ELF-MIPS64EL-NEXT: Offset: 0x50 # ELF-MIPS64EL-NEXT: - Name:.MIPS.options # ELF-MIPS64EL-NEXT: Type:SHT_MIPS_OPTIONS # ELF-MIPS64EL-NEXT: Flags: [ SHF_ALLOC, SHF_MIPS_NOSTRIP ] diff --git a/llvm/test/tools/obj2yaml/ELF/offset.yaml b/llvm/test/tools/obj2yaml/ELF/offset.yaml new file mode 100644 index ..417c92aed1f8 --- /dev/null +++ b/llvm/test/tools/obj2yaml/ELF/offset.yaml @@ -0,0 +1,260 @@ +## Check how the "Offset" field is dumped by obj2yaml. +## For each section we calulate the expected offset. +## When it does not match the actual offset, we emit the "Offset" key. + +# RUN: yaml2obj %s -o %t1.o +# RUN: obj2yaml %t1.o | FileCheck %s --check-prefix=BASIC + +# BASIC: --- !ELF +# BASIC-NEXT: FileHeader: +# BASIC-NEXT: Class: ELFCLASS64 +# BASIC-NEXT: Data: ELFDATA2LSB +# BASIC-NEXT: Type: ET_REL +# BASIC-NEXT: Sections: +# BASIC-NEXT: - Name: .foo1 +# BASIC-NEXT: Type: SHT_PROGBITS +# BASIC-NEXT: Content: '00' +# BASIC-NEXT: - Name:
[llvm-branch-commits] [llvm] fee910e - [libObject, llvm-readelf] - Stop describing a section/segment in `notes_begin()`.
Author: Georgii Rymar Date: 2020-11-25T12:51:40+03:00 New Revision: fee910e522c997d7606f31148e01bcf67f3f94d1 URL: https://github.com/llvm/llvm-project/commit/fee910e522c997d7606f31148e01bcf67f3f94d1 DIFF: https://github.com/llvm/llvm-project/commit/fee910e522c997d7606f31148e01bcf67f3f94d1.diff LOG: [libObject,llvm-readelf] - Stop describing a section/segment in `notes_begin()`. `notes_begin()` is used for iterating over notes. This API in some cases might print section type and index. At the same time during iterating, the `Elf_Note_Iterator` might omit it as it doesn't have this info. Because of above we might have the redundant duplication of information in warnings: (See D92021). ``` warning: '[[FILE]]': unable to read notes from the SHT_NOTE section with index 1: SHT_NOTE section [index 1] has invalid offset (0x40) or size (0x) ``` This change stops reporting section index/type in Object/ELF.h/notes_begin(). (FTR, this was introduced by me for llvm-readobj in D64470). Instead we can describe sections/program headers on the caller side. Differential revision: https://reviews.llvm.org/D92081 Added: Modified: llvm/include/llvm/Object/ELF.h llvm/test/tools/llvm-readobj/ELF/gnu-notes.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h index 7ebe6869c7b5..d47c8f7809fe 100644 --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/include/llvm/Object/ELF.h @@ -238,9 +238,9 @@ class ELFFile { assert(Phdr.p_type == ELF::PT_NOTE && "Phdr is not of type PT_NOTE"); ErrorAsOutParameter ErrAsOutParam(&Err); if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) { - Err = createError("PT_NOTE header has invalid offset (0x" + -Twine::utohexstr(Phdr.p_offset) + ") or size (0x" + -Twine::utohexstr(Phdr.p_filesz) + ")"); + Err = + createError("invalid offset (0x" + Twine::utohexstr(Phdr.p_offset) + + ") or size (0x" + Twine::utohexstr(Phdr.p_filesz) + ")"); return Elf_Note_Iterator(Err); } return Elf_Note_Iterator(base() + Phdr.p_offset, Phdr.p_filesz, Err); @@ -257,10 +257,9 @@ class ELFFile { assert(Shdr.sh_type == ELF::SHT_NOTE && "Shdr is not of type SHT_NOTE"); ErrorAsOutParameter ErrAsOutParam(&Err); if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) { - Err = createError("SHT_NOTE section " + getSecIndexForError(*this, Shdr) + -" has invalid offset (0x" + -Twine::utohexstr(Shdr.sh_offset) + ") or size (0x" + -Twine::utohexstr(Shdr.sh_size) + ")"); + Err = + createError("invalid offset (0x" + Twine::utohexstr(Shdr.sh_offset) + + ") or size (0x" + Twine::utohexstr(Shdr.sh_size) + ")"); return Elf_Note_Iterator(Err); } return Elf_Note_Iterator(base() + Shdr.sh_offset, Shdr.sh_size, Err); diff --git a/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test b/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test index 04430577daaf..530a4a87293b 100644 --- a/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test +++ b/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test @@ -116,7 +116,7 @@ ProgramHeaders: # RUN: not llvm-readelf --notes %t2.so 2>&1 | FileCheck -DFILE=%t2.so %s --check-prefix=ERR1 # RUN: not llvm-readobj --notes %t2.so 2>&1 | FileCheck -DFILE=%t2.so %s --check-prefix=ERR1 -# ERR1: error: '[[FILE]]': SHT_NOTE section [index 1] has invalid offset (0x) or size (0x0) +# ERR1: error: '[[FILE]]': unable to read notes from the SHT_NOTE section with index 1: invalid offset (0x) or size (0x0) --- !ELF FileHeader: @@ -137,7 +137,7 @@ Sections: # RUN: not llvm-readelf --notes %t3.so 2>&1 | FileCheck -DFILE=%t3.so %s --check-prefix=ERR2 # RUN: not llvm-readobj --notes %t3.so 2>&1 | FileCheck -DFILE=%t3.so %s --check-prefix=ERR2 -# ERR2: error: '[[FILE]]': SHT_NOTE section [index 1] has invalid offset (0x40) or size (0x) +# ERR2: error: '[[FILE]]': unable to read notes from the SHT_NOTE section with index 1: invalid offset (0x40) or size (0x) ## Test tools report an error if a note program header has an invalid offset that ## goes past the end of file. @@ -146,7 +146,7 @@ Sections: # RUN: not llvm-readelf --notes %t4.so 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefix=ERR3 # RUN: not llvm-readobj --notes %t4.so 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefix=ERR3 -# ERR3: error: '[[FILE]]': PT_NOTE header has invalid offset (0x) or size (0x0) +# ERR3: error: '[[FILE]]': unable to read notes from the PT_NOTE segment: invalid offset (0x) or size (0x0) --- !ELF FileHeader: @@ -165,7 +165,7 @@ ProgramHeaders: # RUN: not llvm-readelf --notes %t5.so 2>&1 | FileCheck -DFILE=%t5.so %s --check-prefix=ERR4
[llvm-branch-commits] [llvm] ce322fb - [llvm-readelf/obj] - Stop using `reportError` when dumping notes.
Author: Georgii Rymar Date: 2020-11-25T15:22:56+03:00 New Revision: ce322fb0b8973134f9e0f8f38e99f7051d24acb8 URL: https://github.com/llvm/llvm-project/commit/ce322fb0b8973134f9e0f8f38e99f7051d24acb8 DIFF: https://github.com/llvm/llvm-project/commit/ce322fb0b8973134f9e0f8f38e99f7051d24acb8.diff LOG: [llvm-readelf/obj] - Stop using `reportError` when dumping notes. This starts using `reportUniqueWarnings` instead of `reportError` in the code that is responsible for dumping notes. Differential revision: https://reviews.llvm.org/D92021 Added: Modified: llvm/test/tools/llvm-readobj/ELF/gnu-notes.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test b/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test index 530a4a87293b..4a5cb1a38473 100644 --- a/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test +++ b/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test @@ -113,10 +113,22 @@ ProgramHeaders: ## that goes past the end of file. # RUN: yaml2obj --docnum=2 -DSHOFFSET=0x %s -o %t2.so -# RUN: not llvm-readelf --notes %t2.so 2>&1 | FileCheck -DFILE=%t2.so %s --check-prefix=ERR1 -# RUN: not llvm-readobj --notes %t2.so 2>&1 | FileCheck -DFILE=%t2.so %s --check-prefix=ERR1 - -# ERR1: error: '[[FILE]]': unable to read notes from the SHT_NOTE section with index 1: invalid offset (0x) or size (0x0) +# RUN: llvm-readelf --notes %t2.so 2>&1 | FileCheck -DFILE=%t2.so %s --check-prefix=ERR1-GNU +# RUN: llvm-readobj --notes %t2.so 2>&1 | FileCheck -DFILE=%t2.so %s --check-prefix=ERR1-LLVM + +# ERR1-GNU: Displaying notes found in: .note +# ERR1-GNU-NEXT: OwnerData sizeDescription +# ERR1-GNU-NEXT: warning: '[[FILE]]': unable to read notes from the SHT_NOTE section with index 1: invalid offset (0x) or size (0x0) +# ERR1-GNU-NOT: {{.}} + +# ERR1-LLVM: Notes [ +# ERR1-LLVM-NEXT: NoteSection { +# ERR1-LLVM-NEXT: Name: .note +# ERR1-LLVM-NEXT: Offset: 0x +# ERR1-LLVM-NEXT: Size: 0x0 +# ERR1-LLVM-NEXT: warning: '[[FILE]]': unable to read notes from the SHT_NOTE section with index 1: invalid offset (0x) or size (0x0) +# ERR1-LLVM-NEXT: } +# ERR1-LLVM-NEXT: ] --- !ELF FileHeader: @@ -134,19 +146,43 @@ Sections: ## that goes past the end of file. # RUN: yaml2obj --docnum=2 -DSHSIZE=0x %s -o %t3.so -# RUN: not llvm-readelf --notes %t3.so 2>&1 | FileCheck -DFILE=%t3.so %s --check-prefix=ERR2 -# RUN: not llvm-readobj --notes %t3.so 2>&1 | FileCheck -DFILE=%t3.so %s --check-prefix=ERR2 - -# ERR2: error: '[[FILE]]': unable to read notes from the SHT_NOTE section with index 1: invalid offset (0x40) or size (0x) +# RUN: llvm-readelf --notes %t3.so 2>&1 | FileCheck -DFILE=%t3.so %s --check-prefix=ERR2-GNU +# RUN: llvm-readobj --notes %t3.so 2>&1 | FileCheck -DFILE=%t3.so %s --check-prefix=ERR2-LLVM + +# ERR2-GNU: Displaying notes found in: .note +# ERR2-GNU-NEXT: OwnerData sizeDescription +# ERR2-GNU-NEXT: warning: '[[FILE]]': unable to read notes from the SHT_NOTE section with index 1: invalid offset (0x40) or size (0x) +# ERR2-GNU-NOT: {{.}} + +# ERR2-LLVM: Notes [ +# ERR2-LLVM-NEXT: NoteSection { +# ERR2-LLVM-NEXT: Name: .note +# ERR2-LLVM-NEXT: Offset: 0x40 +# ERR2-LLVM-NEXT: Size: 0x +# ERR2-LLVM-NEXT: warning: '[[FILE]]': unable to read notes from the SHT_NOTE section with index 1: invalid offset (0x40) or size (0x) +# ERR2-LLVM-NEXT: } +# ERR2-LLVM-NEXT: ] ## Test tools report an error if a note program header has an invalid offset that ## goes past the end of file. # RUN: yaml2obj --docnum=3 -DPHOFFSET=0x %s -o %t4.so -# RUN: not llvm-readelf --notes %t4.so 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefix=ERR3 -# RUN: not llvm-readobj --notes %t4.so 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefix=ERR3 - -# ERR3: error: '[[FILE]]': unable to read notes from the PT_NOTE segment: invalid offset (0x) or size (0x0) +# RUN: llvm-readelf --notes %t4.so 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefix=ERR3-GNU +# RUN: llvm-readobj --notes %t4.so 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefix=ERR3-LLVM + +# ERR3-GNU: Displaying notes found at file offset 0x with length 0x: +# ERR3-GNU-NEXT: OwnerData sizeDescription +# ERR3-GNU-NEXT: warning: '[[FILE]]': unable to read notes from the PT_NOTE segment with index 1: invalid offset (0x) or size (0x0) +# ERR3-GNU-NOT: {{.}} + +# ERR3-LLVM: Notes [ +# ERR3-LLVM-NEXT: NoteSection { +# ERR3-LLVM-NEXT: Name: +# ERR3-LLVM-NEXT: Offset: 0x +# ERR3-LLVM-NEXT: Size: 0x0 +# ERR3-LLVM-NEXT: warning: '[[FILE]]': unable to read notes from the PT_NOTE segment with index 1: invalid offset (0x) or size (0x0) +# ERR3-LLVM-NE
[llvm-branch-commits] [llvm] c3673ea - [llvm-readobj] - Fix a warning.
Author: Georgii Rymar Date: 2020-11-26T10:24:24+03:00 New Revision: c3673ea65df576535c85397dfe36624bd09fe47b URL: https://github.com/llvm/llvm-project/commit/c3673ea65df576535c85397dfe36624bd09fe47b DIFF: https://github.com/llvm/llvm-project/commit/c3673ea65df576535c85397dfe36624bd09fe47b.diff LOG: [llvm-readobj] - Fix a warning. This addresses post review comment for D92018. The warning was: ``` error: loop variable 'Note' is always a copy because the range of type 'iterator_range >::Elf_Note_Iterator>' (aka 'iterator_range > >') does not return a reference [-Werror,-Wrange-loop-analysis] for (const typename ELFT::Note &Note : Obj.notes(S, Err)) ``` Added: Modified: llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 2fac1c970fb3..656b9924ece0 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -5559,7 +5559,7 @@ static void printNotesHelper( StartNotesFn(expectedToOptional(Obj.getSectionName(S)), S.sh_offset, S.sh_size); Error Err = Error::success(); - for (const typename ELFT::Note &Note : Obj.notes(S, Err)) + for (const typename ELFT::Note Note : Obj.notes(S, Err)) ProcessNoteFn(Note); if (Err) Dumper.reportUniqueWarning( ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 54ec9bb - [llvm-readelf/obj] - Report a warning when the value of the DT_PLTREL dynamic tag is invalid.
Author: Georgii Rymar Date: 2020-11-26T13:15:59+03:00 New Revision: 54ec9bb5510de301d05e8b34bb8c2484e8c95eaa URL: https://github.com/llvm/llvm-project/commit/54ec9bb5510de301d05e8b34bb8c2484e8c95eaa DIFF: https://github.com/llvm/llvm-project/commit/54ec9bb5510de301d05e8b34bb8c2484e8c95eaa.diff LOG: [llvm-readelf/obj] - Report a warning when the value of the DT_PLTREL dynamic tag is invalid. We report an error for unknown `DT_PLTREL` values. This switches the error to warning. Differential revision: https://reviews.llvm.org/D92087 Added: Modified: llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test llvm/test/tools/llvm-readobj/ELF/dynamic-reloc.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test b/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test index 741eaec90d13..8793a3e9980c 100644 --- a/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test +++ b/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test @@ -163,7 +163,7 @@ ProgramHeaders: # RUN: llvm-readelf --dyn-relocations %t10a 2>&1 | \ # RUN: FileCheck %s -DFILE=%t10a --check-prefix=INVALID-DT-PLTRELSZ1 --implicit-check-not=warning: -# INVALID-DT-PLTRELSZ1: warning: '[[FILE]]': invalid DT_PLTRELSZ value (0xff){{$}} +# INVALID-DT-PLTRELSZ1: warning: '[[FILE]]': invalid DT_PLTRELSZ value (0xff) or PLTREL entry size (0x18){{$}} --- !ELF FileHeader: diff --git a/llvm/test/tools/llvm-readobj/ELF/dynamic-reloc.test b/llvm/test/tools/llvm-readobj/ELF/dynamic-reloc.test index 221e0b80058e..bed9985cdc68 100644 --- a/llvm/test/tools/llvm-readobj/ELF/dynamic-reloc.test +++ b/llvm/test/tools/llvm-readobj/ELF/dynamic-reloc.test @@ -128,3 +128,38 @@ ProgramHeaders: - Type: PT_LOAD FirstSec: .rela.dyn LastSec: .dynamic + +## Check we report a warning when the value of the DT_PLTREL dynamic tag is invalid. +## We currently accept DT_RELA(7) and DT_REL(17) values. This test case uses 0xff. + +# RUN: yaml2obj --docnum=2 %s -DDTPLTREL=0xFF -o %t3 +# RUN: llvm-readobj --dyn-relocations %t3 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t3 --implicit-check-not=warning: --check-prefix=PLTRELUNKNOWN-LLVM +# RUN: llvm-readelf --dyn-relocations %t3 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t3 --implicit-check-not=warning: --check-prefix=PLTRELUNKNOWN-GNU + +# PLTRELUNKNOWN-LLVM: warning: '[[FILE]]': unknown DT_PLTREL value of 255 +# PLTRELUNKNOWN-LLVM: Dynamic Relocations { +# PLTRELUNKNOWN-LLVM-NEXT: 0x1 R_X86_64_NONE foo 0x0 +# PLTRELUNKNOWN-LLVM-NEXT: 0x2 R_X86_64_NONE foo 0x0 +# PLTRELUNKNOWN-LLVM-NEXT: 0x4 R_X86_64_RELATIVE - 0x0 +# PLTRELUNKNOWN-LLVM-NEXT: warning: '[[FILE]]': invalid DT_PLTRELSZ value (0x10) or PLTREL entry size (0x0) +# PLTRELUNKNOWN-LLVM-NEXT: } + +# PLTRELUNKNOWN-GNU:warning: '[[FILE]]': unknown DT_PLTREL value of 255 +# PLTRELUNKNOWN-GNU-EMPTY: +# PLTRELUNKNOWN-GNU-NEXT: 'RELA' relocation section at offset 0x78 contains 24 bytes: +# PLTRELUNKNOWN-GNU-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend +# PLTRELUNKNOWN-GNU-NEXT: 0001 0001 R_X86_64_NONE foo + 0 +# PLTRELUNKNOWN-GNU-EMPTY: +# PLTRELUNKNOWN-GNU-NEXT: 'REL' relocation section at offset 0x90 contains 16 bytes: +# PLTRELUNKNOWN-GNU-NEXT: Offset Info Type Symbol's Value Symbol's Name +# PLTRELUNKNOWN-GNU-NEXT: 0002 0001 R_X86_64_NONE foo +# PLTRELUNKNOWN-GNU-EMPTY: +# PLTRELUNKNOWN-GNU-NEXT: 'RELR' relocation section at offset 0xa0 contains 8 bytes: +# PLTRELUNKNOWN-GNU-NEXT: Offset Info Type Symbol's Value Symbol's Name +# PLTRELUNKNOWN-GNU-NEXT: 0004 0008 R_X86_64_RELATIVE +# PLTRELUNKNOWN-GNU-EMPTY: +# PLTRELUNKNOWN-GNU-NEXT: 'PLT' relocation section at offset 0xa8 contains 16 bytes: +# PLTRELUNKNOWN-GNU-NEXT: Offset Info Type Symbol's Value Symbol's Name +# PLTRELUNKNOWN-GNU-NEXT: warning: '[[FILE]]': invalid DT_PLTRELSZ value (0x10) or PLTREL entry size (0x0) diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 656b9924ece0..c546be25a951 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -2204,10 +2204,9 @@ void ELFDumper::parseDynamicTable() { else if (Dyn.getVal() == DT_RELA) DynPLTRelRegion.EntSize = sizeof(Elf_Rela); else -reportError(createError(Twine("unknown DT_PLTREL value of ") + -Twine((uint64_t)Dyn.getVal())), -ObjF.getFileName()); - DynPLTRelRegion.EntSizePrintName = ""; +reportUniq
[llvm-branch-commits] [llvm] 3d811c5 - [llvm-readelf/obj] - Stop calling `reportError` in `printArchSpecificInfo()`.
Author: Georgii Rymar Date: 2020-11-27T10:27:00+03:00 New Revision: 3d811c57aa1a26fb2ba737dfc6f922fd98c96622 URL: https://github.com/llvm/llvm-project/commit/3d811c57aa1a26fb2ba737dfc6f922fd98c96622 DIFF: https://github.com/llvm/llvm-project/commit/3d811c57aa1a26fb2ba737dfc6f922fd98c96622.diff LOG: [llvm-readelf/obj] - Stop calling `reportError` in `printArchSpecificInfo()`. This is related to MIPS. Currently we might report an error and exit, though there is no problem to report a warning and try to continue dumping an object. The code uses `MipsGOTParser Parser`, which is isolated in this method. Differential revision: https://reviews.llvm.org/D92090 Added: Modified: llvm/test/tools/llvm-readobj/ELF/mips-got.test llvm/test/tools/llvm-readobj/ELF/mips-plt.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/mips-got.test b/llvm/test/tools/llvm-readobj/ELF/mips-got.test index 1615ce0b0e1b..01bff1b914f8 100644 --- a/llvm/test/tools/llvm-readobj/ELF/mips-got.test +++ b/llvm/test/tools/llvm-readobj/ELF/mips-got.test @@ -368,19 +368,13 @@ DynamicSymbols: [] ## Check we report errors when dynamic tags, needed for dumping GOT, are missing. # RUN: yaml2obj --docnum=4 -DTAG1=DT_MIPS_LOCAL_GOTNO -DTAG2=DT_MIPS_GOTSYM %s -o %t.err1.o -# RUN: not llvm-readobj -A %t.err1.o 2>&1 | FileCheck %s -DFILE=%t.err1.o -check-prefix ERR1 - -# ERR1: error: '[[FILE]]': cannot find PLTGOT dynamic tag +# RUN: llvm-readobj -A %t.err1.o 2>&1 | FileCheck %s -DFILE=%t.err1.o -check-prefixes=NO-OUTPUT,ERR1 # RUN: yaml2obj --docnum=4 -DTAG1=DT_PLTGOT -DTAG2=DT_MIPS_GOTSYM %s -o %t.err2.o -# RUN: not llvm-readobj -A %t.err2.o 2>&1 | FileCheck %s -DFILE=%t.err2.o -check-prefix ERR2 - -# ERR2: error: '[[FILE]]': cannot find MIPS_LOCAL_GOTNO dynamic tag +# RUN: llvm-readobj -A %t.err2.o 2>&1 | FileCheck %s -DFILE=%t.err2.o -check-prefixes=NO-OUTPUT,ERR2 # RUN: yaml2obj --docnum=4 -DTAG1=DT_PLTGOT -DTAG2=DT_MIPS_LOCAL_GOTNO %s -o %t.err3.o -# RUN: not llvm-readobj -A %t.err3.o 2>&1 | FileCheck %s -DFILE=%t.err3.o -check-prefix ERR3 - -# ERR3: error: '[[FILE]]': cannot find MIPS_GOTSYM dynamic tag +# RUN: llvm-readobj -A %t.err3.o 2>&1 | FileCheck %s -DFILE=%t.err3.o -check-prefixes=NO-OUTPUT,ERR3 --- !ELF FileHeader: @@ -401,14 +395,10 @@ Sections: DynamicSymbols: [] # RUN: yaml2obj --docnum=5 -DVAL1=0x %s -o %t.err4.o -# RUN: not llvm-readobj -A %t.err4.o 2>&1 | FileCheck %s -DFILE=%t.err4.o -check-prefix=ERR4 - -# ERR4: error: '[[FILE]]': DT_MIPS_GOTSYM value (65535) exceeds the number of dynamic symbols (1) +# RUN: llvm-readobj -A %t.err4.o 2>&1 | FileCheck %s -DFILE=%t.err4.o -check-prefixes=NO-OUTPUT,ERR4 # RUN: yaml2obj --docnum=5 -DVAL2=0x %s -o %t.err5.o -# RUN: not llvm-readobj -A %t.err5.o 2>&1 | FileCheck %s -DFILE=%t.err5.o -check-prefix=ERR5 - -# ERR5: error: '[[FILE]]': there is no non-empty GOT section at 0x +# RUN: llvm-readobj -A %t.err5.o 2>&1 | FileCheck %s -DFILE=%t.err5.o -check-prefixes=NO-OUTPUT,ERR5 --- !ELF FileHeader: @@ -428,6 +418,20 @@ Sections: Value: [[VAL2=0]] DynamicSymbols: [] +# NO-OUTPUT: LoadName: +# NO-OUTPUT-NEXT: There is no .MIPS.abiflags section in the file. +# NO-OUTPUT-NEXT: There is no .MIPS.options section in the file. +# NO-OUTPUT-NEXT: There is no .reginfo section in the file. + +# ERR1-NEXT: warning: '[[FILE]]': cannot find PLTGOT dynamic tag +# ERR2-NEXT: warning: '[[FILE]]': cannot find MIPS_LOCAL_GOTNO dynamic tag +# ERR3-NEXT: warning: '[[FILE]]': cannot find MIPS_GOTSYM dynamic tag +# ERR4-NEXT: warning: '[[FILE]]': DT_MIPS_GOTSYM value (65535) exceeds the number of dynamic symbols (1) +# ERR5-NEXT: warning: '[[FILE]]': there is no non-empty GOT section at 0x + +# NO-OUTPUT-EMPTY: +# NO-OUTPUT-NOT: {{.}} + ## Check that we do not report a warning about the .got section when we are able to locate it by name. # RUN: yaml2obj --docnum=6 -DNAME=0x %s -o %t.err6.o # RUN: llvm-readobj -A %t.err6.o 2>&1 | \ diff --git a/llvm/test/tools/llvm-readobj/ELF/mips-plt.test b/llvm/test/tools/llvm-readobj/ELF/mips-plt.test index 3f57a39988e8..607388cb852b 100644 --- a/llvm/test/tools/llvm-readobj/ELF/mips-plt.test +++ b/llvm/test/tools/llvm-readobj/ELF/mips-plt.test @@ -89,14 +89,10 @@ DynamicSymbols: ## Check we report errors when dynamic tags, needed for dumping PLT, are missing. # RUN: yaml2obj --docnum=2 -DTAG=DT_MIPS_PLTGOT %s -o %t.err1.o -# RUN: not llvm-readobj -A %t.err1.o 2>&1 | FileCheck %s -DFILE=%t.err1.o --check-prefix=ERR1 - -# ERR1: error: '[[FILE]]': cannot find JMPREL dynamic tag +# RUN: llvm-readobj -A %t.err1.o 2>&1 | FileCheck %s -DFILE=%t.err1.o --check-prefixes=NO-OUTPUT,ERR1 # RUN: yaml2obj --docnum=2 -DTAG=DT_JMPREL %s -o %t.err2.o -# RUN: not llvm-readobj -A %t.err2.o 2>&1 | FileCheck %s -DFILE=%t.err2.o --check-prefix=ER
[llvm-branch-commits] [llvm] c2090ff - [obj2yaml] - Don't assert when trying to calculate the expected section offset.
Author: Georgii Rymar Date: 2020-11-27T15:38:22+03:00 New Revision: c2090ff5942269c391c549f432258e4fd2fa12cb URL: https://github.com/llvm/llvm-project/commit/c2090ff5942269c391c549f432258e4fd2fa12cb DIFF: https://github.com/llvm/llvm-project/commit/c2090ff5942269c391c549f432258e4fd2fa12cb.diff LOG: [obj2yaml] - Don't assert when trying to calculate the expected section offset. The following line asserts when `sh_addralign > MAX_UINT32 && (uint32_t)sh_addralign == 0`: ``` ExpectedOffset = alignTo(ExpectedOffset, SecHdr.sh_addralign ? SecHdr.sh_addralign : 1); ``` it happens because `sh_addralign` is truncated to 32-bit value, but `alignTo` doesn't accept `Align == 0`. We should change `1` to `1uLL`. Differential revision: https://reviews.llvm.org/D92163 Added: Modified: llvm/test/tools/obj2yaml/ELF/offset.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/test/tools/obj2yaml/ELF/offset.yaml b/llvm/test/tools/obj2yaml/ELF/offset.yaml index 417c92aed1f8..2dc04b617417 100644 --- a/llvm/test/tools/obj2yaml/ELF/offset.yaml +++ b/llvm/test/tools/obj2yaml/ELF/offset.yaml @@ -32,6 +32,10 @@ # BASIC-NEXT: Type: SHT_PROGBITS # BASIC-NEXT: AddressAlign: 0x10 # BASIC-NEXT: Offset: 0x200 +# BASIC-NEXT: - Name: .bar4 +# BASIC-NEXT: Type: SHT_PROGBITS +# BASIC-NEXT: AddressAlign: 0x1 +# BASIC-NEXT: Offset: 0x210 --- !ELF FileHeader: @@ -81,6 +85,12 @@ Sections: Type: SHT_PROGBITS AddressAlign: 0x10 Offset: 0x200 +## A case where AddressAlign > MAX_UINT32 and (uint32_t)AddressAlign == 0. +## Check we dump an offset in this case properly. + - Name: .bar4 +Type: SHT_PROGBITS +AddressAlign: 0x1 +Offset: 0x210 ## Show we dump the "Offset" key for the first section when ## it has an unexpected file offset. diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 3aa74bab0c18..4d8d471817ac 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -248,8 +248,8 @@ static void dumpSectionOffsets(const typename ELFT::Ehdr &Header, ELFYAML::Section &Sec = *cast(C.get()); const typename ELFT::Shdr &SecHdr = S[Sec.OriginalSecNdx]; -ExpectedOffset = -alignTo(ExpectedOffset, SecHdr.sh_addralign ? SecHdr.sh_addralign : 1); +ExpectedOffset = alignTo(ExpectedOffset, + SecHdr.sh_addralign ? SecHdr.sh_addralign : 1uLL); // We only set the "Offset" field when it can't be naturally derived // from the offset and size of the previous section. This reduces ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] ee9ffc7 - [obj2yaml] - Dump the `EShNum` key in some cases.
Author: Georgii Rymar Date: 2020-11-27T15:56:10+03:00 New Revision: ee9ffc73452a0b500db18d422562918d389b1d14 URL: https://github.com/llvm/llvm-project/commit/ee9ffc73452a0b500db18d422562918d389b1d14 DIFF: https://github.com/llvm/llvm-project/commit/ee9ffc73452a0b500db18d422562918d389b1d14.diff LOG: [obj2yaml] - Dump the `EShNum` key in some cases. This patch starts emitting the `EShNum` key, when the `e_shnum = 0` and the section header table exists. `e_shnum` might be 0, when the the number of entries in the section header table is larger than or equal to SHN_LORESERVE (0xff00). In this case the real number of entries in the section header table is held in the `sh_size` member of the initial entry in section header table. Currently, obj2yaml crashes when an object has `e_shoff != 0` and the `sh_size` member of the initial entry in section header table is `0`. This patch fixes it. Differential revision: https://reviews.llvm.org/D92098 Added: llvm/test/tools/obj2yaml/ELF/eshnum.yaml Modified: llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/test/tools/obj2yaml/ELF/eshnum.yaml b/llvm/test/tools/obj2yaml/ELF/eshnum.yaml new file mode 100644 index ..35c7cfddf58c --- /dev/null +++ b/llvm/test/tools/obj2yaml/ELF/eshnum.yaml @@ -0,0 +1,67 @@ +## Test cases related to the value of the e_shnum field of the ELF header live here. + +## Normally an object that does not have sections has e_shnum == 0. +## Also, e_shnum might be 0, when the the number of entries in the section +## header table is larger than or equal to SHN_LORESERVE (0xff00). In this case +## the real number of entries in the section header table is held in the sh_size +## member of the initial entry in the section header table. + +## In the test case below we have an object that has e_shnum = 0 and the real +## number of sections is written to the sh_size member of the initial entry in +## the section header table. Check that we emit the `EShNum` key properly. + +# RUN: yaml2obj %s -o %t1 +# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=PRESERVE + +# PRESERVE: --- !ELF +# PRESERVE-NEXT: FileHeader: +# PRESERVE-NEXT: Class: ELFCLASS64 +# PRESERVE-NEXT: Data: ELFDATA2LSB +# PRESERVE-NEXT: Type: ET_REL +# PRESERVE-NEXT: EShNum: 0x0 +# PRESERVE-NEXT: Sections: +# PRESERVE-NEXT: - Type: SHT_NULL +# PRESERVE-NEXT: Size: 0x3 +# PRESERVE-NEXT: ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + EShNum: 0x0 + EShOff: [[ESHOFF=]] +Sections: + - Type: SHT_NULL +## 3 sections total: SHT_NULL + 2 implicit sections: .strtab and .shstrtab. + Size: [[SIZE=0x3]] + +## In the test case below we have an object with a non-zero section header table +## file offset and an initial entry in the section header table with sh_size of 0. +## Here we check that we are able to dump such objects properly. + +# RUN: yaml2obj %s -DSIZE=0x0 -o %t2 +# RUN: obj2yaml %t2 | FileCheck %s --check-prefix=NO-SECTIONS + +# NO-SECTIONS: --- !ELF +# NO-SECTIONS-NEXT: FileHeader: +# NO-SECTIONS-NEXT: Class: ELFCLASS64 +# NO-SECTIONS-NEXT: Data: ELFDATA2LSB +# NO-SECTIONS-NEXT: Type: ET_REL +# NO-SECTIONS-NEXT: EShNum: 0x0 +## Note: yaml2obj will create the SHT_NULL section with sh_size = 0 implicitly. +# NO-SECTIONS-NEXT: ... + +## In the test case below we have an object without a section header table and e_shnum == 0. +## Document how we dump it. +## FIXME: we should emit the `SectionHeaderTable` key with `NoHeaders=true` for this case. + +# RUN: yaml2obj %s -DESHOFF=0x0 -o %t3 +# RUN: obj2yaml %t3 | FileCheck %s --check-prefix=NO-HEADERS + +# NO-HEADERS: --- !ELF +# NO-HEADERS-NEXT: FileHeader: +# NO-HEADERS-NEXT: Class: ELFCLASS64 +# NO-HEADERS-NEXT: Data: ELFDATA2LSB +# NO-HEADERS-NEXT: Type: ET_REL +# NO-HEADERS-NEXT: ... diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 4d8d471817ac..ea2f2911712b 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -237,6 +237,9 @@ static void dumpSectionOffsets(const typename ELFT::Ehdr &Header, ArrayRef Phdrs, std::vector> &V, ArrayRef S) { + if (V.empty()) +return; + uint64_t ExpectedOffset; if (Header.e_phoff > 0) ExpectedOffset = Header.e_phoff + Header.e_phentsize * Header.e_phnum; @@ -289,6 +292,14 @@ template Expected ELFDumper::dump() { Sections = *SectionsOrErr; SectionNames.resize(Sections.size()); + // Normally an object that does not have sections has e_shnum == 0. + // Also, e_shnum might be 0, when the the number of entries in the section + // header table is larger than or equal to SHN_LORESERVE (0xff00). In this + // case the real number of entries is held in the sh_size member of the + // initial en
[llvm-branch-commits] [llvm] 31eeac9 - [llvm-readelf/obj] - Move unique warning handling logic to the `ObjDumper`.
Author: Georgii Rymar Date: 2020-12-01T10:53:00+03:00 New Revision: 31eeac915a0a25c2690b956931c77684bc34da0b URL: https://github.com/llvm/llvm-project/commit/31eeac915a0a25c2690b956931c77684bc34da0b DIFF: https://github.com/llvm/llvm-project/commit/31eeac915a0a25c2690b956931c77684bc34da0b.diff LOG: [llvm-readelf/obj] - Move unique warning handling logic to the `ObjDumper`. This moves the `reportUniqueWarning` method to the base class. My motivation is the following: I've experimented with replacing `reportWarning` calls with `reportUniqueWarning` in ELF dumper. I've found that for example for removing them from `DynRegionInfo` helper class, it is worth to pass a dumper instance to it (to be able to call dumper()->reportUniqueWarning()). The problem was that `ELFDumper` is a template class. I had to make `DynRegionInfo` to be templated and do lots of minor changes everywhere what did not look reasonable/nice. At the same time I guess one day other dumpers like COFF/MachO/Wasm etc might want to start using `reportUniqueWarning` API too. Then it looks reasonable to move the logic to the base class. With that the problem of passing the dumper instance will be gone. Differential revision: https://reviews.llvm.org/D92218 Added: Modified: llvm/tools/llvm-readobj/COFFDumper.cpp llvm/tools/llvm-readobj/ELFDumper.cpp llvm/tools/llvm-readobj/MachODumper.cpp llvm/tools/llvm-readobj/ObjDumper.cpp llvm/tools/llvm-readobj/ObjDumper.h llvm/tools/llvm-readobj/WasmDumper.cpp llvm/tools/llvm-readobj/XCOFFDumper.cpp Removed: diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index b1ac1d9d0f39..144ecf56d50a 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -77,7 +77,8 @@ class COFFDumper : public ObjDumper { public: friend class COFFObjectDumpDelegate; COFFDumper(const llvm::object::COFFObjectFile *Obj, ScopedPrinter &Writer) - : ObjDumper(Writer), Obj(Obj), Writer(Writer), Types(100) {} + : ObjDumper(Writer, Obj->getFileName()), Obj(Obj), Writer(Writer), +Types(100) {} void printFileHeaders() override; void printSectionHeaders() override; diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 890bb2a21e82..f89d88724a9a 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -64,7 +64,6 @@ #include #include #include -#include #include using namespace llvm; @@ -355,8 +354,6 @@ template class ELFDumper : public ObjDumper { }; mutable SmallVector, 16> VersionMap; - std::unordered_set Warnings; - std::string describe(const Elf_Shdr &Sec) const; public: @@ -435,9 +432,6 @@ template class ELFDumper : public ObjDumper { Expected> getRelocationTarget(const Relocation &R, const Elf_Shdr *SymTab) const; - - std::function WarningHandler; - void reportUniqueWarning(Error Err) const; }; template @@ -956,14 +950,6 @@ template class GNUStyle : public DumpStyle { const Twine &Label, unsigned EntriesNum); }; -template -void ELFDumper::reportUniqueWarning(Error Err) const { - handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) { -cantFail(WarningHandler(EI.message()), - "WarningHandler should always return ErrorSuccess"); - }); -} - template void DumpStyle::reportUniqueWarning(Error Err) const { this->dumper().reportUniqueWarning(std::move(Err)); @@ -2020,16 +2006,9 @@ void ELFDumper::loadDynamicTable() { template ELFDumper::ELFDumper(const object::ELFObjectFile &O, ScopedPrinter &Writer) -: ObjDumper(Writer), ObjF(O), Obj(*O.getELFFile()), DynRelRegion(O), - DynRelaRegion(O), DynRelrRegion(O), DynPLTRelRegion(O), DynamicTable(O) { - // Dumper reports all non-critical errors as warnings. - // It does not print the same warning more than once. - WarningHandler = [this](const Twine &Msg) { -if (Warnings.insert(Msg.str()).second) - reportWarning(createError(Msg), ObjF.getFileName()); -return Error::success(); - }; - +: ObjDumper(Writer, O.getFileName()), ObjF(O), Obj(*O.getELFFile()), + DynRelRegion(O), DynRelaRegion(O), DynRelrRegion(O), DynPLTRelRegion(O), + DynamicTable(O) { if (opts::Output == opts::GNU) ELFDumperStyle.reset(new GNUStyle(Writer, *this)); else diff --git a/llvm/tools/llvm-readobj/MachODumper.cpp b/llvm/tools/llvm-readobj/MachODumper.cpp index 5c4960804e8f..c13b1f3bf2a0 100644 --- a/llvm/tools/llvm-readobj/MachODumper.cpp +++ b/llvm/tools/llvm-readobj/MachODumper.cpp @@ -27,7 +27,7 @@ namespace { class MachODumper : public ObjDumper { public: MachODumper(const MachOObjectFile *Obj, ScopedPrinter &Writer) - : ObjDumper(W
[llvm-branch-commits] [llvm] 8748106 - [llvm-readelf] - Switch to using from `reportWarning` to `reportUniqueWarning` in `DynRegionInfo`.
Author: Georgii Rymar Date: 2020-12-01T11:09:30+03:00 New Revision: 87481068fddf29e913b129b9c962ba761ae478c8 URL: https://github.com/llvm/llvm-project/commit/87481068fddf29e913b129b9c962ba761ae478c8 DIFF: https://github.com/llvm/llvm-project/commit/87481068fddf29e913b129b9c962ba761ae478c8.diff LOG: [llvm-readelf] - Switch to using from `reportWarning` to `reportUniqueWarning` in `DynRegionInfo`. This is a part of the plan we had previously to convert all calls to `reportUniqueWarning` and then rename it to just `reportWarning`. I was a bit unsure about this particular change at first, because it doesn't add a new functionality: seems it is impossible to trigger a warning duplication currently. At the same time I find the idea of the plan mentioned very reasonable. And with that we will be sure that `DynRegionInfo` can't report duplicate warnings, what looks like a nice feature for possible refactorings and further tool development. Differential revision: https://reviews.llvm.org/D92224 Added: Modified: llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index f89d88724a9a..d4f716ac97ad 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -125,9 +125,11 @@ template struct RelSymbol { /// the size, entity size and virtual address are diff erent entries in arbitrary /// order (DT_REL, DT_RELSZ, DT_RELENT for example). struct DynRegionInfo { - DynRegionInfo(const Binary &Owner) : Obj(&Owner) {} - DynRegionInfo(const Binary &Owner, const uint8_t *A, uint64_t S, uint64_t ES) - : Addr(A), Size(S), EntSize(ES), Obj(&Owner) {} + DynRegionInfo(const Binary &Owner, const ObjDumper &D) + : Obj(&Owner), Dumper(&D) {} + DynRegionInfo(const Binary &Owner, const ObjDumper &D, const uint8_t *A, +uint64_t S, uint64_t ES) + : Addr(A), Size(S), EntSize(ES), Obj(&Owner), Dumper(&D) {} /// Address in current address space. const uint8_t *Addr = nullptr; @@ -138,6 +140,8 @@ struct DynRegionInfo { /// Owner object. Used for error reporting. const Binary *Obj; + /// Dumper used for error reporting. + const ObjDumper *Dumper; /// Error prefix. Used for error reporting to provide more information. std::string Context; /// Region size name. Used for error reporting. @@ -156,13 +160,11 @@ struct DynRegionInfo { const uint64_t ObjSize = Obj->getMemoryBufferRef().getBufferSize(); if (Size > ObjSize - Offset) { - reportWarning( - createError("unable to read data at 0x" + Twine::utohexstr(Offset) + - " of size 0x" + Twine::utohexstr(Size) + " (" + - SizePrintName + - "): it goes past the end of the file of size 0x" + - Twine::utohexstr(ObjSize)), - Obj->getFileName()); + Dumper->reportUniqueWarning(createError( + "unable to read data at 0x" + Twine::utohexstr(Offset) + + " of size 0x" + Twine::utohexstr(Size) + " (" + SizePrintName + + "): it goes past the end of the file of size 0x" + + Twine::utohexstr(ObjSize))); return {Start, Start}; } @@ -180,7 +182,7 @@ struct DynRegionInfo { (" or " + EntSizePrintName + " (0x" + Twine::utohexstr(EntSize) + ")") .str(); -reportWarning(createError(Msg.c_str()), Obj->getFileName()); +Dumper->reportUniqueWarning(createError(Msg.c_str())); return {Start, Start}; } }; @@ -311,7 +313,7 @@ template class ELFDumper : public ObjDumper { ") + size (0x" + Twine::utohexstr(Size) + ") is greater than the file size (0x" + Twine::utohexstr(Obj.getBufSize()) + ")"); -return DynRegionInfo(ObjF, Obj.base() + Offset, Size, EntSize); +return DynRegionInfo(ObjF, *this, Obj.base() + Offset, Size, EntSize); } void printAttributes(); @@ -1928,7 +1930,7 @@ void ELFDumper::loadDynamicTable() { if (!DynamicPhdr && !DynamicSec) return; - DynRegionInfo FromPhdr(ObjF); + DynRegionInfo FromPhdr(ObjF, *this); bool IsPhdrTableValid = false; if (DynamicPhdr) { // Use cantFail(), because p_offset/p_filesz fields of a PT_DYNAMIC are @@ -1944,7 +1946,7 @@ void ELFDumper::loadDynamicTable() { // Ignore sh_entsize and use the expected value for entry size explicitly. // This allows us to dump dynamic sections with a broken sh_entsize // field. - DynRegionInfo FromSec(ObjF); + DynRegionInfo FromSec(ObjF, *this); bool IsSecTableValid = false; if (DynamicSec) { Expected RegOrErr = @@ -2007,8 +2009,8 @@ template ELFDumper::ELFDumper(const object::ELFObjectFile &O, ScopedPrinter &Writer) : ObjDumper(Writer, O.getFileName()), ObjF(O), Obj(*O.ge
llvm-branch-commits@lists.llvm.org
Author: Georgii Rymar Date: 2020-12-01T12:36:44+03:00 New Revision: 82d9fb0ac19e6909a957d346a815d993774b2e98 URL: https://github.com/llvm/llvm-project/commit/82d9fb0ac19e6909a957d346a815d993774b2e98 DIFF: https://github.com/llvm/llvm-project/commit/82d9fb0ac19e6909a957d346a815d993774b2e98.diff LOG: [llvm-readobj] - Introduce `ObjDumper::reportUniqueWarning(const Twine &Msg)`. This introduces the overload for `reportUniqueWarning` which allows to avoid using `createError` in many places. Differential revision: https://reviews.llvm.org/D92371 Added: Modified: llvm/tools/llvm-readobj/ELFDumper.cpp llvm/tools/llvm-readobj/ObjDumper.cpp llvm/tools/llvm-readobj/ObjDumper.h Removed: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index d4f716ac97ad..2167fc3e3dff 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -160,11 +160,11 @@ struct DynRegionInfo { const uint64_t ObjSize = Obj->getMemoryBufferRef().getBufferSize(); if (Size > ObjSize - Offset) { - Dumper->reportUniqueWarning(createError( + Dumper->reportUniqueWarning( "unable to read data at 0x" + Twine::utohexstr(Offset) + " of size 0x" + Twine::utohexstr(Size) + " (" + SizePrintName + "): it goes past the end of the file of size 0x" + - Twine::utohexstr(ObjSize))); + Twine::utohexstr(ObjSize)); return {Start, Start}; } @@ -182,7 +182,7 @@ struct DynRegionInfo { (" or " + EntSizePrintName + " (0x" + Twine::utohexstr(EntSize) + ")") .str(); -Dumper->reportUniqueWarning(createError(Msg.c_str())); +Dumper->reportUniqueWarning(Msg); return {Start, Start}; } }; @@ -522,12 +522,12 @@ ELFDumper::getVersionTable(const Elf_Shdr &Sec, ArrayRef *SymTab, } if (SymTabOrErr->first.size() != VersionsOrErr->size()) -reportUniqueWarning( -createError(describe(Sec) + ": the number of entries (" + -Twine(VersionsOrErr->size()) + -") does not match the number of symbols (" + -Twine(SymTabOrErr->first.size()) + -") in the symbol table with index " + Twine(Sec.sh_link))); +reportUniqueWarning(describe(Sec) + ": the number of entries (" + +Twine(VersionsOrErr->size()) + +") does not match the number of symbols (" + +Twine(SymTabOrErr->first.size()) + +") in the symbol table with index " + +Twine(Sec.sh_link)); if (SymTab) std::tie(*SymTab, *StrTab) = *SymTabOrErr; @@ -717,16 +717,16 @@ void ELFDumper::printSymbolsHelper(bool IsDynamic) const { Obj.getStringTableForSymtab(*DotSymtabSec)) StrTable = *StrTableOrErr; else - reportUniqueWarning(createError( + reportUniqueWarning( "unable to get the string table for the SHT_SYMTAB section: " + - toString(StrTableOrErr.takeError(; + toString(StrTableOrErr.takeError())); if (Expected SymsOrErr = Obj.symbols(DotSymtabSec)) Syms = *SymsOrErr; else reportUniqueWarning( - createError("unable to read symbols from the SHT_SYMTAB section: " + - toString(SymsOrErr.takeError(; + "unable to read symbols from the SHT_SYMTAB section: " + + toString(SymsOrErr.takeError())); Entries = DotSymtabSec->getEntityCount(); } if (Syms.begin() == Syms.end()) @@ -800,6 +800,7 @@ template class DumpStyle { virtual void printMipsABIFlags() = 0; const ELFDumper &dumper() const { return Dumper; } void reportUniqueWarning(Error Err) const; + void reportUniqueWarning(const Twine &Msg) const; protected: std::vector getGroups(); @@ -957,6 +958,11 @@ void DumpStyle::reportUniqueWarning(Error Err) const { this->dumper().reportUniqueWarning(std::move(Err)); } +template +void DumpStyle::reportUniqueWarning(const Twine &Msg) const { + this->dumper().reportUniqueWarning(Msg); +} + template class LLVMStyle : public DumpStyle { public: TYPEDEF_ELF_TYPES(ELFT) @@ -1136,9 +1142,8 @@ static std::string maybeDemangle(StringRef Name) { template std::string ELFDumper::getStaticSymbolName(uint32_t Index) const { auto Warn = [&](Error E) -> std::string { -this->reportUniqueWarning( -createError("unable to read the name of symbol with index " + -Twine(Index) + ": " + toString(std::move(E; +this->reportUniqueWarning("unable to read the name of symbol with index " + + Twine(Index) + ": " + toString(std::move(E))); return ""; }; @@ -1877,9 +1882,9 @@ ELFDumper::findDynamic() { break; } } else { -this->reportUniqueWarning(createError
[llvm-branch-commits] [llvm] ade2fbb - [llvm-readobj][test] - Merge 2 test cases together.
Author: Georgii Rymar Date: 2020-12-01T12:51:07+03:00 New Revision: ade2fbbfb09c03ed665271247542774ecd540344 URL: https://github.com/llvm/llvm-project/commit/ade2fbbfb09c03ed665271247542774ecd540344 DIFF: https://github.com/llvm/llvm-project/commit/ade2fbbfb09c03ed665271247542774ecd540344.diff LOG: [llvm-readobj][test] - Merge 2 test cases together. This merges `invalid-attr-section-size.test` and `invalid-attr-version.test` into `invalid-attributes-sec.test`. This allows to have a single place where other related test cases can be added. Differential revision: https://reviews.llvm.org/D92316 Added: llvm/test/tools/llvm-readobj/ELF/RISCV/attributes-invalid.test Modified: Removed: llvm/test/tools/llvm-readobj/ELF/RISCV/invalid-attr-section-size.test llvm/test/tools/llvm-readobj/ELF/RISCV/invalid-attr-version.test diff --git a/llvm/test/tools/llvm-readobj/ELF/RISCV/attributes-invalid.test b/llvm/test/tools/llvm-readobj/ELF/RISCV/attributes-invalid.test new file mode 100644 index ..547ed93bcd10 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/RISCV/attributes-invalid.test @@ -0,0 +1,32 @@ +## Check how we dump invalid SHT_RISCV_ATTRIBUTES sections. + +## This test case is used to ensure llvm-readobj checks the version of +## attribute sections correctly. The only supported format is 'A' (41), +## here we use 'B' (42). + +# RUN: yaml2obj %s -D BITS=32 -DCONTENT=42 -o %t1.32.o +# RUN: llvm-readobj -A %t1.32.o 2>&1 | FileCheck -DFILE=%t1 %s --check-prefix=ERR-FORMAT +# RUN: yaml2obj %s -D BITS=64 -DCONTENT=42 -o %t1.64.o +# RUN: llvm-readobj -A %t1.64.o 2>&1 | FileCheck -DFILE=%t1 %s --check-prefix=ERR-FORMAT + +# ERR-FORMAT: warning: '[[FILE]].{{32|64}}.o': unrecognised FormatVersion: 0x42 + +--- !ELF +FileHeader: + Class: ELFCLASS[[BITS=64]] + Data:ELFDATA2LSB + Type:ET_REL + Machine: EM_RISCV +Sections: + - Name:.riscv.attributes +Type:SHT_RISCV_ATTRIBUTES +Content: [[CONTENT]] + +## Check we report a warning when we are unable to parse the attribute section data. + +# RUN: yaml2obj %s -D BITS=32 -DCONTENT=41 -o %t2.32.o +# RUN: llvm-readobj -A %t2.32.o 2>&1 | FileCheck -DFILE=%t2 %s --check-prefix=ERR-LENGTH +# RUN: yaml2obj %s -D BITS=64 -DCONTENT=41 -o %t2.64.o +# RUN: llvm-readobj -A %t2.64.o 2>&1 | FileCheck -DFILE=%t2 %s --check-prefix=ERR-LENGTH + +# ERR-LENGTH: warning: '[[FILE]].{{32|64}}.o': invalid section length 0 at offset 0x1 diff --git a/llvm/test/tools/llvm-readobj/ELF/RISCV/invalid-attr-section-size.test b/llvm/test/tools/llvm-readobj/ELF/RISCV/invalid-attr-section-size.test deleted file mode 100644 index 524134e1579b.. --- a/llvm/test/tools/llvm-readobj/ELF/RISCV/invalid-attr-section-size.test +++ /dev/null @@ -1,20 +0,0 @@ -## This test case is used to ensure the error code is caught by llvm-readobj. - -# RUN: yaml2obj %s -D BITS=32 -o %t.32.o -# RUN: llvm-readobj -A %t.32.o 2>&1 | FileCheck -DFILE=%t %s -# RUN: yaml2obj %s -D BITS=64 -o %t.64.o -# RUN: llvm-readobj -A %t.64.o 2>&1 | FileCheck -DFILE=%t %s - -# CHECK: warning: '[[FILE]].{{32|64}}.o': invalid section length 0 at offset 0x1 - !ELF -FileHeader: - Class: ELFCLASS[[BITS]] - Data:ELFDATA2LSB - Type:ET_REL - Machine: EM_RISCV -Sections: - - Name:.riscv.attributes -Type:SHT_RISCV_ATTRIBUTES -## Version: 'A'(0x41), section length: 0 -Content: 41 diff --git a/llvm/test/tools/llvm-readobj/ELF/RISCV/invalid-attr-version.test b/llvm/test/tools/llvm-readobj/ELF/RISCV/invalid-attr-version.test deleted file mode 100644 index 9a4d81bcc4f1.. --- a/llvm/test/tools/llvm-readobj/ELF/RISCV/invalid-attr-version.test +++ /dev/null @@ -1,21 +0,0 @@ -## This test case is used to ensure llvm-readobj checks the version of -## attribute sections correctly. - -# RUN: yaml2obj %s -D BITS=32 -o %t.32.o -# RUN: llvm-readobj -A %t.32.o 2>&1 | FileCheck -DFILE=%t %s -# RUN: yaml2obj %s -D BITS=64 -o %t.64.o -# RUN: llvm-readobj -A %t.64.o 2>&1 | FileCheck -DFILE=%t %s - -# CHECK: warning: '[[FILE]].{{32|64}}.o': unrecognised FormatVersion: 0x42 - !ELF -FileHeader: - Class: ELFCLASS[[BITS]] - Data:ELFDATA2LSB - Type:ET_REL - Machine: EM_RISCV -Sections: - - Name:.riscv.attributes -Type:SHT_RISCV_ATTRIBUTES -## Version: 'B' -Content: 42 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] ea8c8a5 - [obj2yaml] - Teach tool to emit the "SectionHeaderTable" key and sort sections by file offset.
Author: Georgii Rymar Date: 2020-12-01T12:59:15+03:00 New Revision: ea8c8a50976fd5b9ca9799414bd3c412fce37f03 URL: https://github.com/llvm/llvm-project/commit/ea8c8a50976fd5b9ca9799414bd3c412fce37f03 DIFF: https://github.com/llvm/llvm-project/commit/ea8c8a50976fd5b9ca9799414bd3c412fce37f03.diff LOG: [obj2yaml] - Teach tool to emit the "SectionHeaderTable" key and sort sections by file offset. Currently when we dump sections, we dump them in the order, which is specified in the sections header table. With that the order in the output might not match the order in the file. This patch starts sorting them by by file offsets when dumping. When the order in the section header table doesn't match the order in the file, we should emit the "SectionHeaderTable" key. This patch does it. Differential revision: https://reviews.llvm.org/D91249 Added: Modified: llvm/lib/ObjectYAML/ELFYAML.cpp llvm/test/Object/X86/obj2yaml-dup-section-name.s llvm/test/Object/obj2yaml.test llvm/test/tools/obj2yaml/ELF/offset.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 5c60705e291e..92b9c284e064 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1648,12 +1648,12 @@ void MappingTraits::mapping(IO &IO, ELFYAML::Object &Object) { IO.setContext(&Object); IO.mapTag("!ELF", true); IO.mapRequired("FileHeader", Object.Header); - IO.mapOptional("SectionHeaderTable", Object.SectionHeaders); IO.mapOptional("ProgramHeaders", Object.ProgramHeaders); IO.mapOptional("Sections", Object.Chunks); IO.mapOptional("Symbols", Object.Symbols); IO.mapOptional("DynamicSymbols", Object.DynamicSymbols); IO.mapOptional("DWARF", Object.DWARF); + IO.mapOptional("SectionHeaderTable", Object.SectionHeaders); if (Object.DWARF) { Object.DWARF->IsLittleEndian = Object.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); diff --git a/llvm/test/Object/X86/obj2yaml-dup-section-name.s b/llvm/test/Object/X86/obj2yaml-dup-section-name.s index 17fc7a4d9003..9c0a2bef6ac6 100644 --- a/llvm/test/Object/X86/obj2yaml-dup-section-name.s +++ b/llvm/test/Object/X86/obj2yaml-dup-section-name.s @@ -2,18 +2,18 @@ # RUN: obj2yaml %t.o | FileCheck %s # CHECK: Sections: +# CHECK: - Name:.text.foo{{$}} +# CHECK: - Name:'.text.foo (1)' # CHECK: - Name:.group{{$}} # CHECK: Members: # CHECK: - SectionOrType: .text.foo{{$}} # CHECK: - SectionOrType: .rela.text.foo{{$}} -# CHECK: - Name:.text.foo{{$}} -# CHECK: - Name:.rela.text.foo{{$}} -# CHECK: Info:.text.foo{{$}} # CHECK: - Name:'.group (1)' # CHECK: Members: # CHECK: - SectionOrType: '.text.foo (1)' # CHECK: - SectionOrType: '.rela.text.foo (1)' -# CHECK: - Name:'.text.foo (1)' +# CHECK: - Name:.rela.text.foo{{$}} +# CHECK: Info:.text.foo{{$}} # CHECK: - Name:'.rela.text.foo (1)' # CHECK: Info:'.text.foo (1)' # CHECK: Symbols: diff --git a/llvm/test/Object/obj2yaml.test b/llvm/test/Object/obj2yaml.test index 840440406456..ea538a16782c 100644 --- a/llvm/test/Object/obj2yaml.test +++ b/llvm/test/Object/obj2yaml.test @@ -358,35 +358,10 @@ # ELF-MIPSEL-NEXT: Flags: [ SHF_ALLOC, SHF_EXECINSTR ] # ELF-MIPSEL-NEXT: AddressAlign:0x4 # ELF-MIPSEL-NEXT: Content: 023C4224E8FFBD271400BFAF1000B0AF21805900018E2424198E09F8200321E2198E09F8200321E202241000B08F1400BF8F0800E0031800BD27 -# ELF-MIPSEL-NEXT: - Name:.rel.text -# ELF-MIPSEL-NEXT: Type:SHT_REL -# ELF-MIPSEL-NEXT: Link:.symtab -# ELF-MIPSEL-NEXT: AddressAlign:0x4 -# ELF-MIPSEL-NEXT: Offset: 0x434 -# ELF-MIPSEL-NEXT: Info:.text -# ELF-MIPSEL-NEXT: Relocations: -# ELF-MIPSEL-NEXT: - Symbol: _gp_disp -# ELF-MIPSEL-NEXT: Type:R_MIPS_HI16 -# ELF-MIPSEL-NEXT: - Offset: 0x4 -# ELF-MIPSEL-NEXT: Symbol: _gp_disp -# ELF-MIPSEL-NEXT: Type:R_MIPS_LO16 -# ELF-MIPSEL-NEXT: - Offset: 0x18 -# ELF-MIPSEL-NEXT: Symbol: '$.str' -# ELF-MIPSEL-NEXT: Type:R_MIPS_GOT16 -# ELF-MIPSEL-NEXT: - Offset: 0x1C -# ELF-MIPSEL-NEXT: Symbol: '$.str' -# ELF-MIPSEL-NEXT: Type:R_MIPS_LO16 -# ELF-MIPSEL-NEXT: - Offset: 0x20 -# ELF-MIPSEL-NEXT: Symbol: puts -# ELF-MIPSEL-NEXT: Type:R_MIPS_CALL16 -# ELF-MIPSEL-NEXT: - Offset: 0x2C -# ELF-MIPSEL-NEXT: Symbol: SomeOtherFunction -# ELF-MIPSEL-NEXT: Type:R_MIPS_CA
[llvm-branch-commits] [lld] 3f5dc57 - [LLD][ELF] - Don't keep empty output sections which have explicit program headers.
Author: Georgii Rymar Date: 2020-12-02T11:19:21+03:00 New Revision: 3f5dc57fd18106766f45216b5ddd4648d2fb4629 URL: https://github.com/llvm/llvm-project/commit/3f5dc57fd18106766f45216b5ddd4648d2fb4629 DIFF: https://github.com/llvm/llvm-project/commit/3f5dc57fd18106766f45216b5ddd4648d2fb4629.diff LOG: [LLD][ELF] - Don't keep empty output sections which have explicit program headers. This reverts a side effect introduced in the code cleanup patch D43571: LLD started to emit empty output sections that are explicitly assigned to a segment. This patch fixes the issue by removing the !sec.phdrs.empty() special case from isDiscardable. As compensation, we add an early phdrs propagation step (see the inline comment). This is similar to one that we do in adjustSectionsAfterSorting. Differential revision: https://reviews.llvm.org/D92301 Added: Modified: lld/ELF/LinkerScript.cpp lld/test/ELF/linkerscript/empty-relaplt-dyntags.test lld/test/ELF/linkerscript/implicit-program-header.test lld/test/ELF/linkerscript/orphan-phdrs.s Removed: diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 5bb977d6882b..201f1e48f1fb 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -987,11 +987,6 @@ static bool isDiscardable(OutputSection &sec) { if (sec.name == "/DISCARD/") return true; - // We do not remove empty sections that are explicitly - // assigned to any segment. - if (!sec.phdrs.empty()) -return false; - // We do not want to remove OutputSections with expressions that reference // symbols even if the OutputSection is empty. We want to ensure that the // expressions can be evaluated and report an error if they cannot. @@ -1017,6 +1012,18 @@ static bool isDiscardable(OutputSection &sec) { return true; } +static void maybePropagatePhdrs(OutputSection &sec, +std::vector &phdrs) { + if (sec.phdrs.empty()) { +// To match the bfd linker script behaviour, only propagate program +// headers to sections that are allocated. +if (sec.flags & SHF_ALLOC) + sec.phdrs = phdrs; + } else { +phdrs = sec.phdrs; + } +} + void LinkerScript::adjustSectionsBeforeSorting() { // If the output section contains only symbol assignments, create a // corresponding output section. The issue is what to do with linker script @@ -1040,6 +1047,7 @@ void LinkerScript::adjustSectionsBeforeSorting() { // the previous sections. Only a few flags are needed to keep the impact low. uint64_t flags = SHF_ALLOC; + std::vector defPhdrs; for (BaseCommand *&cmd : sectionCommands) { auto *sec = dyn_cast(cmd); if (!sec) @@ -1062,6 +1070,18 @@ void LinkerScript::adjustSectionsBeforeSorting() { sec->flags = flags & ((sec->nonAlloc ? 0 : (uint64_t)SHF_ALLOC) | SHF_WRITE | SHF_EXECINSTR); +// The code below may remove empty output sections. We should save the +// specified program headers (if exist) and propagate them to subsequent +// sections which do not specify program headers. +// An example of such a linker script is: +// SECTIONS { .empty : { *(.empty) } :rw +//.foo : { *(.foo) } } +// Note: at this point the order of output sections has not been finalized, +// because orphans have not been inserted into their expected positions. We +// will handle them in adjustSectionsAfterSorting(). +if (sec->sectionIndex != UINT32_MAX) + maybePropagatePhdrs(*sec, defPhdrs); + if (isEmpty && isDiscardable(*sec)) { sec->markDead(); cmd = nullptr; @@ -1106,20 +1126,9 @@ void LinkerScript::adjustSectionsAfterSorting() { // Walk the commands and propagate the program headers to commands that don't // explicitly specify them. - for (BaseCommand *base : sectionCommands) { -auto *sec = dyn_cast(base); -if (!sec) - continue; - -if (sec->phdrs.empty()) { - // To match the bfd linker script behaviour, only propagate program - // headers to sections that are allocated. - if (sec->flags & SHF_ALLOC) -sec->phdrs = defPhdrs; -} else { - defPhdrs = sec->phdrs; -} - } + for (BaseCommand *base : sectionCommands) +if (auto *sec = dyn_cast(base)) + maybePropagatePhdrs(*sec, defPhdrs); } static uint64_t computeBase(uint64_t min, bool allocateHeaders) { diff --git a/lld/test/ELF/linkerscript/empty-relaplt-dyntags.test b/lld/test/ELF/linkerscript/empty-relaplt-dyntags.test index 3836dfb02d02..83bb9f15451f 100644 --- a/lld/test/ELF/linkerscript/empty-relaplt-dyntags.test +++ b/lld/test/ELF/linkerscript/empty-relaplt-dyntags.test @@ -3,31 +3,11 @@ # RUN: ld.lld -shared %t.o -T %s -o %t # RUN: llvm-readobj --dynamic-table --sections %t | FileCheck %s -## In spite of .rela.plt is empty, it might have been preserved because it is -## mentioned
[llvm-branch-commits] [llvm] 01e4920 - [llvm-readelf/obj] - Refine the error message about the broken string table.
Author: Georgii Rymar Date: 2020-12-02T12:06:16+03:00 New Revision: 01e49204b82057f356ad3fe0cabba139635ac733 URL: https://github.com/llvm/llvm-project/commit/01e49204b82057f356ad3fe0cabba139635ac733 DIFF: https://github.com/llvm/llvm-project/commit/01e49204b82057f356ad3fe0cabba139635ac733.diff LOG: [llvm-readelf/obj] - Refine the error message about the broken string table. This: 1) Changes `reportWarning` to `reportUniqueWarning` (no-op here). 2) Adds more context to the message. 3) Merges `broken-dynsym-link.test` into `dyn-symbols.test`, adds more testing. Differential revision: https://reviews.llvm.org/D92380 Added: Modified: llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: llvm/test/tools/llvm-readobj/ELF/broken-dynsym-link.test diff --git a/llvm/test/tools/llvm-readobj/ELF/broken-dynsym-link.test b/llvm/test/tools/llvm-readobj/ELF/broken-dynsym-link.test deleted file mode 100644 index 179aff1d5652.. --- a/llvm/test/tools/llvm-readobj/ELF/broken-dynsym-link.test +++ /dev/null @@ -1,57 +0,0 @@ -## Test that we are able to dump section headers even if the -## .dynsym section's sh_link field is broken. - -## Case 1: sh_link is set to 0. -# RUN: yaml2obj --docnum=1 -DLINK=0 %s -o %t1 -# RUN: llvm-readobj -S %t1 2>&1 | FileCheck %s -DFILE=%t1 --check-prefixes=LLVM,ERR -# RUN: llvm-readelf -S %t1 2>&1 | FileCheck %s -DFILE=%t1 --check-prefixes=GNU,ERR - -# ERR: warning: '[[FILE]]': invalid sh_type for string table section [index 0]: expected SHT_STRTAB, but got SHT_NULL - -# LLVM: Name: .dynsym -# LLVM-NEXT: Type: SHT_DYNSYM -# LLVM-NEXT: Flags [ -# LLVM-NEXT:SHF_ALLOC -# LLVM-NEXT: ] -# LLVM-NEXT: Address: 0x0 -# LLVM-NEXT: Offset: 0x40 -# LLVM-NEXT: Size: 24 -# LLVM-NEXT: Link: 0 - -# GNU: Section Headers: -# GNU-NEXT: [Nr] NameType Address OffSize ES Flg Lk -# GNU-NEXT: [ 0] NULL 00 00 00 0 0 -# GNU-NEXT: [ 1] .dynsym DYNSYM 40 18 18 A 0 - !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_DYN -Sections: - - Name: .dynsym -Type: SHT_DYNSYM -Link: [[LINK]] - -## Case 2: sh_link is set to 255, which is larger than the number of the sections. -# RUN: yaml2obj --docnum=1 -DLINK=255 %s -o %t2 - -# RUN: llvm-readobj -S %t2 2>&1 | FileCheck -DFILE=%t2 %s --check-prefixes=LLVM2,ERR2 -# RUN: llvm-readelf -S %t2 2>&1 | FileCheck -DFILE=%t2 %s --check-prefixes=GNU2,ERR2 - -# ERR2: warning: '[[FILE]]': invalid section index: 255 - -# LLVM2: Name: .dynsym -# LLVM2-NEXT: Type: SHT_DYNSYM -# LLVM2-NEXT: Flags [ -# LLVM2-NEXT:SHF_ALLOC -# LLVM2-NEXT: ] -# LLVM2-NEXT: Address: 0x0 -# LLVM2-NEXT: Offset: 0x40 -# LLVM2-NEXT: Size: 24 -# LLVM2-NEXT: Link: 255 - -# GNU2: Section Headers: -# GNU2-NEXT: [Nr] NameType Address OffSize ES Flg Lk -# GNU2-NEXT: [ 0] NULL 00 00 00 0 0 -# GNU2-NEXT: [ 1] .dynsym DYNSYM 40 18 18 A 255 diff --git a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test index 0ccb24a2f4bd..eb976f673b93 100644 --- a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test +++ b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test @@ -610,6 +610,7 @@ Sections: - Name: .dynsym Type: SHT_DYNSYM EntSize: [[ENTSIZE=]] +Link: [[LINK=]] ShOffset: [[OFFSET=]] ShSize: [[SIZE=]] DynamicSymbols: @@ -642,3 +643,65 @@ DynamicSymbols: # SIZE-BROKEN-LLVM: DynamicSymbols [ # SIZE-BROKEN-LLVM-NEXT: ] + +## d) check we report a warning when the sh_link field of the SHT_DYNSYM section +##is not a valid section index or is not an index of a valid string table. +# RUN: yaml2obj --docnum=14 %s -DLINK=0x -o %t16.link +# RUN: llvm-readobj %t16.link --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link \ +# RUN: --check-prefixes=LINK-BROKEN1,LINK-BROKEN-LLVM --implicit-check-not=warning: +# RUN: llvm-readelf %t16.link --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link \ +# RUN: --check-prefixes=LINK-BROKEN1,LINK-BROKEN-GNU --implicit-check-not=warning: + +## Also test that we are able to dump section headers even if the .dynsym section's sh_link field is broken. +# RUN: llvm-readobj %t16.link --section-headers --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link \ +# RUN: --check-prefixes=LINK-BROKEN1,LINK-SEC-HDRS-LLVM,LINK-BROKEN-LLVM --implicit-check-not=warning: +# RUN: llvm-readelf %t16.link --section-headers --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link \ +# RUN: --check-prefixes=LINK-BROKEN1,LINK-SEC-HDRS-GNU,LINK-BROKEN-GNU + +# RUN: yaml2obj --docnum=14 %s -DLINK=0x0 -o %t16.link.0 +# RUN: llvm-readobj %t16.link.0 --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link.0 \ +#
[llvm-branch-commits] [llvm] 21b6c04 - [llvm-readelf/obj] - Report unique warnings in `parseDynamicTable`.
Author: Georgii Rymar Date: 2020-12-02T12:52:42+03:00 New Revision: 21b6c04e3a02d67cebb3e3bc3d43d3e9311ea915 URL: https://github.com/llvm/llvm-project/commit/21b6c04e3a02d67cebb3e3bc3d43d3e9311ea915 DIFF: https://github.com/llvm/llvm-project/commit/21b6c04e3a02d67cebb3e3bc3d43d3e9311ea915.diff LOG: [llvm-readelf/obj] - Report unique warnings in `parseDynamicTable`. This makes the warnings reported to be unique and adds test cases. Differential revision: https://reviews.llvm.org/D92382 Added: Modified: llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test index eb976f673b93..43ca57a80b61 100644 --- a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test +++ b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test @@ -451,11 +451,15 @@ DynamicSymbols: [] ## c) In the case when the DT_SYMENT tag is present, we report when it's value does not match the # value of the symbol size for the platform. # RUN: yaml2obj %s -D BITS=32 --docnum=12 -o %t12 -# RUN: llvm-readobj --dyn-symbols %t12 2>&1 | FileCheck %s -DFILE=%t12 --check-prefix=DYNSYM-SIZE-INVALID3 -# RUN: llvm-readelf --dyn-symbols %t12 2>&1 | FileCheck %s -DFILE=%t12 --check-prefix=DYNSYM-SIZE-INVALID3 +# RUN: llvm-readobj --dyn-symbols %t12 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t12 --implicit-check-not=warning: --check-prefix=DYNSYM-SIZE-INVALID3 +# RUN: llvm-readelf --dyn-symbols %t12 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t12 --implicit-check-not=warning: --check-prefix=DYNSYM-SIZE-INVALID3 # RUN: yaml2obj %s -D BITS=64 --docnum=12 -o %t13 -# RUN: llvm-readobj --dyn-symbols %t13 2>&1 | FileCheck %s -DFILE=%t13 --check-prefix=DYNSYM-SIZE-INVALID4 -# RUN: llvm-readelf --dyn-symbols %t13 2>&1 | FileCheck %s -DFILE=%t13 --check-prefix=DYNSYM-SIZE-INVALID4 +# RUN: llvm-readobj --dyn-symbols %t13 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t13 --implicit-check-not=warning: --check-prefix=DYNSYM-SIZE-INVALID4 +# RUN: llvm-readelf --dyn-symbols %t13 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t13 --implicit-check-not=warning: --check-prefix=DYNSYM-SIZE-INVALID4 # DYNSYM-SIZE-INVALID3: warning: '[[FILE]]': DT_SYMENT value of 0x123 is not the size of a symbol (0x10){{$}} # DYNSYM-SIZE-INVALID4: warning: '[[FILE]]': DT_SYMENT value of 0x123 is not the size of a symbol (0x18){{$}} @@ -502,6 +506,8 @@ Sections: - Name:.dynamic Type:SHT_DYNAMIC Entries: + - Tag: DT_SYMENT +Value: 0x123 - Tag: DT_SYMENT Value: 0x123 - Tag: DT_NULL diff --git a/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test b/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test index 48ab1d914c3b..bb12ce80d9e2 100644 --- a/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test +++ b/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test @@ -215,6 +215,9 @@ Sections: Type:SHT_DYNAMIC Address: 0x1000 Entries: +## Two DT_STRTAB entries are needed to check that we don't report it twice. + - Tag: DT_STRTAB +Value: 0x200 - Tag: DT_STRTAB Value: 0x200 - Tag: DT_STRSZ diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index be018e18a912..8a774da52772 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -2090,11 +2090,9 @@ void ELFDumper::parseDynamicTable() { auto toMappedAddr = [&](uint64_t Tag, uint64_t VAddr) -> const uint8_t * { auto MappedAddrOrError = Obj.toMappedAddr(VAddr); if (!MappedAddrOrError) { - Error Err = - createError("Unable to parse DT_" + Obj.getDynamicTagAsString(Tag) + - ": " + llvm::toString(MappedAddrOrError.takeError())); - - reportWarning(std::move(Err), ObjF.getFileName()); + this->reportUniqueWarning("Unable to parse DT_" + +Obj.getDynamicTagAsString(Tag) + ": " + +llvm::toString(MappedAddrOrError.takeError())); return nullptr; } return MappedAddrOrError.get(); @@ -2134,11 +2132,10 @@ void ELFDumper::parseDynamicTable() { case ELF::DT_SYMENT: { uint64_t Val = Dyn.getVal(); if (Val != sizeof(Elf_Sym)) -reportWarning(createError("DT_SYMENT value of 0x" + +this->reportUniqueWarning("DT_SYMENT value of 0x" + Twine::utohexstr(Val) + " is not the size of a symbol (0x" + - Twine::utohexstr(sizeof(Elf_Sym)) + ")"), - ObjF.getFileName()); + Twine::utohexstr(sizeof(Elf_Sym)) + ")"); break;
[llvm-branch-commits] [llvm] 1daace3 - [llvm-readelf/obj] - Lowercase the warning message reported.
Author: Georgii Rymar Date: 2020-12-02T13:09:47+03:00 New Revision: 1daace3fbb307d09ef8445bede5559143da1712d URL: https://github.com/llvm/llvm-project/commit/1daace3fbb307d09ef8445bede5559143da1712d DIFF: https://github.com/llvm/llvm-project/commit/1daace3fbb307d09ef8445bede5559143da1712d.diff LOG: [llvm-readelf/obj] - Lowercase the warning message reported. Our warnings/errors reported are using lowercase normally. This addresses one of review comments from D92382. Added: Modified: llvm/test/Object/invalid.test llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test llvm/test/tools/llvm-readobj/ELF/loadname.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/Object/invalid.test b/llvm/test/Object/invalid.test index 74ad8fcc9c72..57fb006351eb 100644 --- a/llvm/test/Object/invalid.test +++ b/llvm/test/Object/invalid.test @@ -437,7 +437,7 @@ DynamicSymbols: # RUN: yaml2obj %s --docnum=20 -o %t20 # RUN: llvm-readobj --dynamic-table %t20 2>&1 | FileCheck -DFILE=%t20 --check-prefix=INVALID-DTSTRTAB %s -# INVALID-DTSTRTAB: warning: '[[FILE]]': Unable to parse DT_STRTAB: virtual address is not in any segment: 0x +# INVALID-DTSTRTAB: warning: '[[FILE]]': unable to parse DT_STRTAB: virtual address is not in any segment: 0x --- !ELF FileHeader: diff --git a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test index 43ca57a80b61..4b4a4bed4c8b 100644 --- a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test +++ b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test @@ -90,7 +90,7 @@ ProgramHeaders: # RUN: llvm-readelf %t2.so --dyn-symbols 2>&1 | \ # RUN: FileCheck %s -DFILE=%t2.so --implicit-check-not=warning: -DNAME=.dynsym --check-prefix=NOPHDRS-GNU -# NOPHDRS-LLVM: warning: '[[FILE]]': Unable to parse DT_SYMTAB: virtual address is not in any segment: 0x1234 +# NOPHDRS-LLVM: warning: '[[FILE]]': unable to parse DT_SYMTAB: virtual address is not in any segment: 0x1234 # NOPHDRS-LLVM: DynamicSymbols [ # NOPHDRS-LLVM-NEXT: Symbol { # NOPHDRS-LLVM-NEXT: Name: (0) @@ -112,7 +112,7 @@ ProgramHeaders: # NOPHDRS-LLVM-NEXT: } # NOPHDRS-LLVM-NEXT: ] -# NOPHDRS-GNU: warning: '[[FILE]]': Unable to parse DT_SYMTAB: virtual address is not in any segment: 0x1234 +# NOPHDRS-GNU: warning: '[[FILE]]': unable to parse DT_SYMTAB: virtual address is not in any segment: 0x1234 # NOPHDRS-NAMEWARN: warning: '[[FILE]]': unable to get the name of SHT_DYNSYM section with index 2: a section [index 2] has an invalid sh_name (0x) offset which goes past the end of the section name string table # NOPHDRS-GNU: Symbol table '[[NAME]]' contains 2 entries: # NOPHDRS-GNU-NEXT: Num:Value Size TypeBind Vis Ndx Name @@ -153,7 +153,7 @@ DynamicSymbols: # RUN: llvm-readobj %t3.so --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t3.so --check-prefixes=NOSHT-DYNSYM,NOSHT-DYNSYM-LLVM # RUN: llvm-readelf %t3.so --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t3.so --check-prefix=NOSHT-DYNSYM -# NOSHT-DYNSYM: warning: '[[FILE]]': Unable to parse DT_SYMTAB: virtual address is not in any segment: 0x0 +# NOSHT-DYNSYM: warning: '[[FILE]]': unable to parse DT_SYMTAB: virtual address is not in any segment: 0x0 # NOSHT-DYNSYM-LLVM: DynamicSymbols [ # NOSHT-DYNSYM-LLVM-NEXT: ] @@ -181,7 +181,7 @@ DynamicSymbols: # RUN: llvm-readobj %t4.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefixes=BROKEN-DTSYMTAB,BROKEN-DTSYMTAB-LLVM # RUN: llvm-readelf %t4.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefixes=BROKEN-DTSYMTAB,BROKEN-DTSYMTAB-GNU -# BROKEN-DTSYMTAB: warning: '[[FILE]]': Unable to parse DT_SYMTAB: virtual address is not in any segment: 0x1234 +# BROKEN-DTSYMTAB: warning: '[[FILE]]': unable to parse DT_SYMTAB: virtual address is not in any segment: 0x1234 # BROKEN-DTSYMTAB-LLVM: Name: foo # BROKEN-DTSYMTAB-GNU: 1: 0 NOTYPE LOCAL DEFAULT UND foo diff --git a/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test b/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test index bb12ce80d9e2..6bcf890949c8 100644 --- a/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test +++ b/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test @@ -187,7 +187,7 @@ ProgramHeaders: # RUN: FileCheck -DFILE=%t.bad-strtab %s --implicit-check-not=warning: --check-prefix=BAD-STRTAB-ERR # RUN: llvm-readelf --dynamic-table %t.bad-strtab 2>&1 >/dev/null | \ # RUN: FileCheck -DFILE=%t.bad-strtab %s --implicit-check-not=warning: --check-prefix=BAD-STRTAB-ERR -# BAD-STRTAB-ERR:warning: '[[FILE]]': Unable to parse DT_STRTAB: virtual address is no
[llvm-branch-commits] [llvm] 137a25f - [llvm-readobj, libSupport] - Refine the implementation of the code that dumps build attributes.
Author: Georgii Rymar Date: 2020-12-02T13:51:32+03:00 New Revision: 137a25f04a515e5ea8f24c897e34b4cd236239a8 URL: https://github.com/llvm/llvm-project/commit/137a25f04a515e5ea8f24c897e34b4cd236239a8 DIFF: https://github.com/llvm/llvm-project/commit/137a25f04a515e5ea8f24c897e34b4cd236239a8.diff LOG: [llvm-readobj, libSupport] - Refine the implementation of the code that dumps build attributes. This implementation of `ELFDumper::printAttributes()` in llvm-readobj has issues: 1) It crashes when the content of the attribute section is empty. 2) It uses `unwrapOrError` and `reportWarning` calls, though ideally we want to use `reportUniqueWarning`. 3) It contains a TODO about redundant format version check. `lib/Support/ELFAttributeParser.cpp` uses a hardcoded constant instead of the named constant. This patch fixes all these issues. Differential revision: https://reviews.llvm.org/D92318 Added: Modified: llvm/lib/Support/ELFAttributeParser.cpp llvm/test/tools/llvm-readobj/ELF/RISCV/attributes-invalid.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/lib/Support/ELFAttributeParser.cpp b/llvm/lib/Support/ELFAttributeParser.cpp index df955cdf5d30..2a30794bc1e9 100644 --- a/llvm/lib/Support/ELFAttributeParser.cpp +++ b/llvm/lib/Support/ELFAttributeParser.cpp @@ -200,7 +200,7 @@ Error ELFAttributeParser::parse(ArrayRef section, // Unrecognized format-version. uint8_t formatVersion = de.getU8(cursor); - if (formatVersion != 'A') + if (formatVersion != ELFAttrs::Format_Version) return createStringError(errc::invalid_argument, "unrecognized format-version: 0x" + utohexstr(formatVersion)); diff --git a/llvm/test/tools/llvm-readobj/ELF/RISCV/attributes-invalid.test b/llvm/test/tools/llvm-readobj/ELF/RISCV/attributes-invalid.test index 547ed93bcd10..882bbb53b577 100644 --- a/llvm/test/tools/llvm-readobj/ELF/RISCV/attributes-invalid.test +++ b/llvm/test/tools/llvm-readobj/ELF/RISCV/attributes-invalid.test @@ -5,11 +5,16 @@ ## here we use 'B' (42). # RUN: yaml2obj %s -D BITS=32 -DCONTENT=42 -o %t1.32.o -# RUN: llvm-readobj -A %t1.32.o 2>&1 | FileCheck -DFILE=%t1 %s --check-prefix=ERR-FORMAT +# RUN: llvm-readobj -A %t1.32.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t1 %s --implicit-check-not=warning: --check-prefix=ERR-FORMAT # RUN: yaml2obj %s -D BITS=64 -DCONTENT=42 -o %t1.64.o -# RUN: llvm-readobj -A %t1.64.o 2>&1 | FileCheck -DFILE=%t1 %s --check-prefix=ERR-FORMAT +# RUN: llvm-readobj -A %t1.64.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t1 %s --implicit-check-not=warning: --check-prefix=ERR-FORMAT -# ERR-FORMAT: warning: '[[FILE]].{{32|64}}.o': unrecognised FormatVersion: 0x42 +# ERR-FORMAT: BuildAttributes { +# ERR-FORMAT-NEXT: FormatVersion: 0x42 +# ERR-FORMAT-NEXT: warning: '[[FILE]].{{32|64}}.o': unable to dump attributes from the SHT_RISCV_ATTRIBUTES section with index 1: unrecognized format-version: 0x42 +# ERR-FORMAT-NEXT: } --- !ELF FileHeader: @@ -18,15 +23,54 @@ FileHeader: Type:ET_REL Machine: EM_RISCV Sections: - - Name:.riscv.attributes -Type:SHT_RISCV_ATTRIBUTES -Content: [[CONTENT]] + - Name: .riscv.attributes +Type: SHT_RISCV_ATTRIBUTES +Content: [[CONTENT]] +ShOffset: [[SHOFFSET=]] ## Check we report a warning when we are unable to parse the attribute section data. +## FIXME: this test case documents that we don't close the "Section X" clause of +##the output properly when a warning is reported by the attributes parser. # RUN: yaml2obj %s -D BITS=32 -DCONTENT=41 -o %t2.32.o -# RUN: llvm-readobj -A %t2.32.o 2>&1 | FileCheck -DFILE=%t2 %s --check-prefix=ERR-LENGTH +# RUN: llvm-readobj -A %t2.32.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t2 %s --implicit-check-not=warning: --check-prefix=ERR-LENGTH # RUN: yaml2obj %s -D BITS=64 -DCONTENT=41 -o %t2.64.o -# RUN: llvm-readobj -A %t2.64.o 2>&1 | FileCheck -DFILE=%t2 %s --check-prefix=ERR-LENGTH +# RUN: llvm-readobj -A %t2.64.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t2 %s --implicit-check-not=warning: --check-prefix=ERR-LENGTH -# ERR-LENGTH: warning: '[[FILE]].{{32|64}}.o': invalid section length 0 at offset 0x1 +# ERR-LENGTH: BuildAttributes { +# ERR-LENGTH-NEXT: FormatVersion: 0x41 +# ERR-LENGTH-NEXT: Section 1 { +# ERR-LENGTH-NEXT: warning: '[[FILE]].{{32|64}}.o': unable to dump attributes from the SHT_RISCV_ATTRIBUTES section with index 1: invalid section length 0 at offset 0x1 +# ERR-LENGTH-NEXT: } +# ERR-LENGTH-NOT: {{.}} + +## Check that we don't report a warning when the SHT_RISCV_ATTRIBUTES section contains the +## valid format version byte and no other data. + +# RUN: yaml2obj %s -DCONTENT=41 -o %t3.o +# RUN: llvm-readobj -A %t3.o 2>&1 | \ +# RUN: FileCheck %s --implicit-check-not=warning: --check-prefix=NO-CONTEN
[llvm-branch-commits] [llvm] 351f736 - [llvm-readelf] - Report unique warnings when dumping hash symbols/histogram.
Author: Georgii Rymar Date: 2020-12-03T14:05:04+03:00 New Revision: 351f736368842cb7e961791fb7e3a3065a260c51 URL: https://github.com/llvm/llvm-project/commit/351f736368842cb7e961791fb7e3a3065a260c51 DIFF: https://github.com/llvm/llvm-project/commit/351f736368842cb7e961791fb7e3a3065a260c51.diff LOG: [llvm-readelf] - Report unique warnings when dumping hash symbols/histogram. This converts 2 more places to use `reportUniqueWarning` and adds tests. Differential revision: https://reviews.llvm.org/D92551 Added: Modified: llvm/test/tools/llvm-readobj/ELF/hash-histogram.test llvm/test/tools/llvm-readobj/ELF/hash-symbols.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/hash-histogram.test b/llvm/test/tools/llvm-readobj/ELF/hash-histogram.test index cc187f477aa0..f4db2d8ad7d7 100644 --- a/llvm/test/tools/llvm-readobj/ELF/hash-histogram.test +++ b/llvm/test/tools/llvm-readobj/ELF/hash-histogram.test @@ -71,13 +71,14 @@ ProgramHeaders: ## the bucket array pointing to a cycle. # RUN: yaml2obj --docnum=2 %s -o %t2.o -# RUN: llvm-readelf --elf-hash-histogram 2>&1 %t2.o | FileCheck -DFILE=%t2.o %s --check-prefix=BROKEN +# RUN: llvm-readelf --elf-hash-histogram 2>&1 %t2.o | \ +# RUN: FileCheck -DFILE=%t2.o %s --check-prefix=BROKEN --implicit-check-not=warning: # BROKEN: warning: '[[FILE]]': .hash section is invalid: bucket 1: a cycle was detected in the linked chain -# BROKEN: Histogram for bucket list length (total of 1 buckets) +# BROKEN: Histogram for bucket list length (total of 2 buckets) # BROKEN-NEXT: Length Number % of total Coverage # BROKEN-NEXT: 0 0 ( 0.0%) 0.0% -# BROKEN-NEXT: 1 1 (100.0%) 100.0% +# BROKEN-NEXT: 1 2 (100.0%) 100.0% --- !ELF FileHeader: @@ -88,7 +89,7 @@ Sections: - Name: .hash Type: SHT_HASH Link: .dynsym -Bucket: [ 1 ] +Bucket: [ 1, 1 ] Chain: [ 0, 1 ] - Name: .dynamic Type: SHT_DYNAMIC diff --git a/llvm/test/tools/llvm-readobj/ELF/hash-symbols.test b/llvm/test/tools/llvm-readobj/ELF/hash-symbols.test index 49db87e04ddb..e0ee9cec893a 100644 --- a/llvm/test/tools/llvm-readobj/ELF/hash-symbols.test +++ b/llvm/test/tools/llvm-readobj/ELF/hash-symbols.test @@ -328,12 +328,15 @@ ProgramHeaders: ## the bucket array pointing to a cycle. # RUN: yaml2obj --docnum=5 %s -o %t5.so -# RUN: llvm-readelf --hash-symbols %t5.so 2>&1 | FileCheck %s -DFILE=%t5.so --check-prefix=BROKEN +# RUN: llvm-readelf --hash-symbols %t5.so 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t5.so --check-prefix=BROKEN --implicit-check-not=warning: # BROKEN: Symbol table of .hash for image: # BROKEN-NEXT: Num Buc:Value Size Type Bind Vis Ndx Name # BROKEN-NEXT:1 0: 0 NOTYPE LOCAL DEFAULT UND aaa # BROKEN: warning: '[[FILE]]': .hash section is invalid: bucket 1: a cycle was detected in the linked chain +# BROKEN-NEXT:1 1: 0 NOTYPE LOCAL DEFAULT UND aaa +# BROKEN-NOT: {{.}} --- !ELF FileHeader: @@ -344,7 +347,7 @@ Sections: - Name:.hash Type:SHT_HASH Link:.dynsym -Bucket: [ 1 ] +Bucket: [ 1, 1 ] Chain: [ 1, 1 ] - Name: .dynamic Type: SHT_DYNAMIC @@ -355,8 +358,7 @@ Sections: - Tag: DT_HASH Value: 0x0 DynamicSymbols: - - Name:aaa - - Name:bbb + - Name: aaa ProgramHeaders: - Type: PT_LOAD FirstSec: .hash diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 646616f6649d..ebcad74808ab 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -4124,10 +4124,9 @@ void GNUStyle::printHashTableSymbols(const Elf_Hash &SysVHash) { break; if (Visited[Ch]) { -reportWarning(createError(".hash section is invalid: bucket " + +this->reportUniqueWarning(".hash section is invalid: bucket " + Twine(Ch) + - ": a cycle was detected in the linked chain"), - this->FileName); + ": a cycle was detected in the linked chain"); break; } @@ -4868,10 +4867,9 @@ void GNUStyle::printHashHistogram(const Elf_Hash &HashTable) { if (C == ELF::STN_UNDEF) break; if (Visited[C]) { -reportWarning(createError(".hash section is invalid: bucket " + +this->reportUniqueWarning(".hash section is invalid: bucket " + Twine(C) + - ": a cycle was detected in the linked chain"), - this->FileName); + ": a cycle was detected in the linked chain"); break; } Visit
[llvm-branch-commits] [llvm] 50de7d5 - [llvm-readelf/obj] - Report unique warnings in getSymbolForReloc() helper.
Author: Georgii Rymar Date: 2020-12-03T14:13:26+03:00 New Revision: 50de7d55044a32f65e78b00cea836f0907041b21 URL: https://github.com/llvm/llvm-project/commit/50de7d55044a32f65e78b00cea836f0907041b21 DIFF: https://github.com/llvm/llvm-project/commit/50de7d55044a32f65e78b00cea836f0907041b21.diff LOG: [llvm-readelf/obj] - Report unique warnings in getSymbolForReloc() helper. Use `reportUniqueWarning` instead of `reportWarning` and refine the interface of the helper. Differential revision: https://reviews.llvm.org/D92556 Added: Modified: llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test b/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test index 8793a3e9980c..0513b0913266 100644 --- a/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test +++ b/llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test @@ -260,18 +260,22 @@ ProgramHeaders: ## Show we print a warning when the symbol index of a dynamic relocation is too ## large (goes past the end of the dynamic symbol table). # RUN: yaml2obj --docnum=5 %s -o %t12 -# RUN: llvm-readobj --dyn-relocations %t12 2>&1 | FileCheck %s -DFILE=%t12 --check-prefix=LLVM-INVALID-DYNSYM -# RUN: llvm-readelf --dyn-relocations %t12 2>&1 | FileCheck %s -DFILE=%t12 --check-prefix=GNU-INVALID-DYNSYM +# RUN: llvm-readobj --dyn-relocations %t12 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t12 --implicit-check-not=warning: --check-prefix=LLVM-INVALID-DYNSYM +# RUN: llvm-readelf --dyn-relocations %t12 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t12 --implicit-check-not=warning: --check-prefix=GNU-INVALID-DYNSYM # LLVM-INVALID-DYNSYM: Dynamic Relocations { # LLVM-INVALID-DYNSYM-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 2: index is greater than or equal to the number of dynamic symbols (2) # LLVM-INVALID-DYNSYM-NEXT: 0x0 R_X86_64_NONE 0x0 +# LLVM-INVALID-DYNSYM-NEXT: 0x0 R_X86_64_NONE 0x0 # LLVM-INVALID-DYNSYM-NEXT: } -# GNU-INVALID-DYNSYM: 'RELA' relocation section at offset 0x78 contains 24 bytes: +# GNU-INVALID-DYNSYM: 'RELA' relocation section at offset 0x78 contains 48 bytes: # GNU-INVALID-DYNSYM-NEXT: OffsetInfo Type Symbol's Value Symbol's Name + Addend # GNU-INVALID-DYNSYM-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 2: index is greater than or equal to the number of dynamic symbols (2) # GNU-INVALID-DYNSYM-NEXT: 0002 R_X86_64_NONE + 0 +# GNU-INVALID-DYNSYM-NEXT: 0002 R_X86_64_NONE + 0 --- !ELF FileHeader: @@ -285,13 +289,15 @@ Sections: Relocations: - Type: R_X86_64_NONE Symbol: 0x2 + - Type: R_X86_64_NONE +Symbol: 0x2 - Name: .dynamic Type: SHT_DYNAMIC Entries: - Tag: DT_RELA Value: 0x0 - Tag: DT_RELASZ -Value: 0x18 +Value: 0x30 - Tag: DT_RELAENT Value: 0x18 - Tag: DT_NULL diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index ebcad74808ab..13d053179356 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -4554,16 +4554,14 @@ template void GNUStyle::printSectionMapping() { namespace { template -RelSymbol getSymbolForReloc(const ELFFile &Obj, StringRef FileName, - const ELFDumper &Dumper, +RelSymbol getSymbolForReloc(const ELFDumper &Dumper, const Relocation &Reloc) { using Elf_Sym = typename ELFT::Sym; auto WarnAndReturn = [&](const Elf_Sym *Sym, const Twine &Reason) -> RelSymbol { -reportWarning( -createError("unable to get name of the dynamic symbol with index " + -Twine(Reloc.Symbol) + ": " + Reason), -FileName); +Dumper.reportUniqueWarning( +"unable to get name of the dynamic symbol with index " + +Twine(Reloc.Symbol) + ": " + Reason); return {Sym, ""}; }; @@ -4581,6 +4579,7 @@ RelSymbol getSymbolForReloc(const ELFFile &Obj, StringRef FileName, "index is greater than or equal to the number of dynamic symbols (" + Twine(Symbols.size()) + ")"); + const ELFFile &Obj = *Dumper.getElfObject().getELFFile(); const uint64_t FileSize = Obj.getBufSize(); const uint64_t SymOffset = ((const uint8_t *)FirstSym - Obj.base()) + (uint64_t)Reloc.Symbol * sizeof(Elf_Sym); @@ -4600,8 +4599,7 @@ RelSymbol getSymbolForReloc(const ELFFile &Obj, StringRef FileName, template void GNUStyle::printDynamicReloc(const Relocation &R) { - printRelRelaRel
[llvm-branch-commits] [llvm] 5c650d3 - [llvm-readobj] - Report unique warnings in printProgramHeaders.
Author: Georgii Rymar Date: 2020-12-04T13:35:44+03:00 New Revision: 5c650d3d9b03a59fa547a0414fbd3a6942c25395 URL: https://github.com/llvm/llvm-project/commit/5c650d3d9b03a59fa547a0414fbd3a6942c25395 DIFF: https://github.com/llvm/llvm-project/commit/5c650d3d9b03a59fa547a0414fbd3a6942c25395.diff LOG: [llvm-readobj] - Report unique warnings in printProgramHeaders. This converts `reportWarning` -> `reportUniqueWarning` Differential revision: https://reviews.llvm.org/D92568 Added: Modified: llvm/test/tools/llvm-readobj/ELF/program-headers.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/program-headers.test b/llvm/test/tools/llvm-readobj/ELF/program-headers.test index d876a239ba68..3a0fb1e462d3 100644 --- a/llvm/test/tools/llvm-readobj/ELF/program-headers.test +++ b/llvm/test/tools/llvm-readobj/ELF/program-headers.test @@ -607,16 +607,16 @@ ProgramHeaders: ## Show the size of the output produced. It is used in the YAML below. # RUN: wc -c < %t.err | FileCheck %s --check-prefix=SIZE -# SIZE: 560 +# SIZE: 616 ## Write the additional 'C', '\0, 'C' bytes to the end. # RUN: echo -n -e "C\x00C" >> %t.err # RUN: llvm-readelf --program-headers %t.err 2>&1 | \ -# RUN: FileCheck %s -DFILE=%t.err --check-prefix=ERROR-INTERP +# RUN: FileCheck %s -DFILE=%t.err --check-prefix=ERROR-INTERP --implicit-check-not=warning: # ERROR-INTERP: Type Offset -# ERROR-INTERP-NEXT: INTERP 0x000[[#%x,OFFSET:0x230]] +# ERROR-INTERP-NEXT: INTERP 0x000[[#%x,OFFSET:0x268]] # ERROR-INTERP-NEXT: [Requesting program interpreter: C] # ERROR-INTERP-NEXT: INTERP 0x000[[#OFFSET + 1]] # ERROR-INTERP-NEXT: [Requesting program interpreter: ] @@ -626,6 +626,7 @@ ProgramHeaders: # ERROR-INTERP-NEXT: warning: '[[FILE]]': unable to read program interpreter name at offset 0x[[#OFFSET+3]]: it goes past the end of the file (0x[[#OFFSET + 3]]) # ERROR-INTERP-NEXT: INTERP 0xaabbccddeeff1122 # ERROR-INTERP-NEXT: warning: '[[FILE]]': unable to read program interpreter name at offset 0xaabbccddeeff1122: it goes past the end of the file (0x[[#OFFSET + 3]]) +# ERROR-INTERP-NEXT: INTERP 0xaabbccddeeff1122 --- !ELF FileHeader: @@ -635,21 +636,25 @@ FileHeader: ProgramHeaders: ## Case 1: the offset points to the first additional byte. - Type: PT_INTERP -Offset: 560 +Offset: 616 ## Case 1: the offset points to the second additional byte, ## which is a null byte. - Type: PT_INTERP -Offset: 561 +Offset: 617 ## Case 3: the offset points to the third additional ## byte, which is the last byte in the file. - Type: PT_INTERP -Offset: 562 +Offset: 618 ## Case 4: the offset goes 1 byte past the end of the file. - Type: PT_INTERP -Offset: 563 +Offset: 619 ## Case 5: an arbitrary large offset that goes past the end of the file. - Type: PT_INTERP Offset: 0xAABBCCDDEEFF1122 +## Case 6: the same as case 5. Used to demonstrate that we don't report +## the same warning twice. + - Type: PT_INTERP +Offset: 0xAABBCCDDEEFF1122 ## Check we report a warning when we are unable to read program headers. ## Case A: the e_phentsize field is invalid. diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 13d053179356..e682581684e9 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -4473,10 +4473,9 @@ template void GNUStyle::printProgramHeaders() { if (Phdr.p_type == ELF::PT_INTERP) { OS << "\n"; auto ReportBadInterp = [&](const Twine &Msg) { -reportWarning( -createError("unable to read program interpreter name at offset 0x" + -Twine::utohexstr(Phdr.p_offset) + ": " + Msg), -this->FileName); +this->reportUniqueWarning( +"unable to read program interpreter name at offset 0x" + +Twine::utohexstr(Phdr.p_offset) + ": " + Msg); }; if (Phdr.p_offset >= this->Obj.getBufSize()) { ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 7ac0644 - [yaml2obj, obj2yaml] - Make Symbol::Section field optional.
Author: Georgii Rymar Date: 2020-12-04T13:45:47+03:00 New Revision: 7ac06444b8baead56301562fbfecbcedbdf30ecd URL: https://github.com/llvm/llvm-project/commit/7ac06444b8baead56301562fbfecbcedbdf30ecd DIFF: https://github.com/llvm/llvm-project/commit/7ac06444b8baead56301562fbfecbcedbdf30ecd.diff LOG: [yaml2obj,obj2yaml] - Make Symbol::Section field optional. This is similar to what we did earlier for fields of the Section class. When a field is optional we can use the = syntax in macros. This was splitted from D92478. Differential revision: https://reviews.llvm.org/D92565 Added: Modified: llvm/include/llvm/ObjectYAML/ELFYAML.h llvm/lib/ObjectYAML/ELFEmitter.cpp llvm/lib/ObjectYAML/ELFYAML.cpp llvm/test/tools/yaml2obj/ELF/dynamic-symbols.yaml Removed: diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index 9015fb680b60..8de2e1730378 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -103,7 +103,7 @@ struct SectionHeaderTable { struct Symbol { StringRef Name; ELF_STT Type; - StringRef Section; + Optional Section; Optional Index; ELF_STB Binding; llvm::yaml::Hex64 Value; diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index b8386bd46be2..ee6149fe02bd 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -832,8 +832,8 @@ ELFState::toELFSymbols(ArrayRef Symbols, Symbol.st_name = Strtab.getOffset(ELFYAML::dropUniqueSuffix(Sym.Name)); Symbol.setBindingAndType(Sym.Binding, Sym.Type); -if (!Sym.Section.empty()) - Symbol.st_shndx = toSectionIndex(Sym.Section, "", Sym.Name); +if (Sym.Section) + Symbol.st_shndx = toSectionIndex(*Sym.Section, "", Sym.Name); else if (Sym.Index) Symbol.st_shndx = *Sym.Index; diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 92b9c284e064..d7de5462ed25 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1086,7 +1086,7 @@ void MappingTraits::mapping(IO &IO, ELFYAML::Symbol &Symbol) { IO.mapOptional("Name", Symbol.Name, StringRef()); IO.mapOptional("StName", Symbol.StName); IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0)); - IO.mapOptional("Section", Symbol.Section, StringRef()); + IO.mapOptional("Section", Symbol.Section); IO.mapOptional("Index", Symbol.Index); IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0)); IO.mapOptional("Value", Symbol.Value, Hex64(0)); @@ -1104,7 +1104,7 @@ void MappingTraits::mapping(IO &IO, ELFYAML::Symbol &Symbol) { std::string MappingTraits::validate(IO &IO, ELFYAML::Symbol &Symbol) { - if (Symbol.Index && Symbol.Section.data()) + if (Symbol.Index && Symbol.Section) return "Index and Section cannot both be specified for Symbol"; return ""; } diff --git a/llvm/test/tools/yaml2obj/ELF/dynamic-symbols.yaml b/llvm/test/tools/yaml2obj/ELF/dynamic-symbols.yaml index 89b420104330..ca27db4afe03 100644 --- a/llvm/test/tools/yaml2obj/ELF/dynamic-symbols.yaml +++ b/llvm/test/tools/yaml2obj/ELF/dynamic-symbols.yaml @@ -42,7 +42,7 @@ DynamicSymbols: ## Check we can use numeric values to refer to sections. -# RUN: yaml2obj --docnum=2 %s -o %t2 +# RUN: yaml2obj --docnum=2 -DSEC=0xff %s -o %t2 # RUN: llvm-readobj --dyn-symbols %t2 2>&1 | FileCheck -DFILE=%t2 %s --check-prefix=NUM # NUM: Name: foo @@ -53,11 +53,15 @@ DynamicSymbols: # NUM: Section: # NUM-SAME: .dynsym (0x2) -# NUM: Name: zed +# NUM: Name: zed1 # NUM: warning: '[[FILE]]': invalid section index: 255 # NUM: Section: # NUM-SAME: (0xFF) +# NUM: Name: zed2 +# NUM: Section: +# NUM-SAME: Undefined (0x0) + --- !ELF FileHeader: Class: ELFCLASS64 @@ -67,12 +71,27 @@ Sections: - Name: .data Type: SHT_PROGBITS DynamicSymbols: - - Name: foo + - Name:foo Section: 1 - - Name: bar + - Name:bar Section: 2 - - Name: zed -Section: 0xff + - Name:zed1 +Section: [[SEC=]] +## The case when no "Section" key is set. + - Name: zed2 + +## Check that by default no section is set. + +# RUN: yaml2obj --docnum=2 %s -o %t2.none +# RUN: llvm-readobj --dyn-symbols %t2.none 2>&1 | \ +# RUN: FileCheck -DFILE=%t2.none %s --check-prefix=NONE + +# NONE: Name: zed1 +# NONE: Section: +# NONE-SAME: Undefined (0x0) +# NONE: Name: zed2 +# NONE: Section: +# NONE-SAME: Undefined (0x0) ## Check we report errors when unknown sections are referenced by dynamic symbols. @@ -80,6 +99,7 @@ DynamicSymbols: # ERR: error: unknown section referenced: '.sec1' by YAML symbol 'foo' # ERR: error: unknown section referenced: '.sec2' by YAML symbol 'bar' +# ERR: error: unknown section referenced: '' by YA
[llvm-branch-commits] [llvm] ffbce65 - [lib/Object, tools] - Make ELFObjectFile::getELFFile return reference.
Author: Georgii Rymar Date: 2020-12-04T16:02:29+03:00 New Revision: ffbce65f95eea7db1ca151d38b3391b2a4f3da81 URL: https://github.com/llvm/llvm-project/commit/ffbce65f95eea7db1ca151d38b3391b2a4f3da81 DIFF: https://github.com/llvm/llvm-project/commit/ffbce65f95eea7db1ca151d38b3391b2a4f3da81.diff LOG: [lib/Object, tools] - Make ELFObjectFile::getELFFile return reference. We always have an object, so we don't have to return a pointer. Differential revision: https://reviews.llvm.org/D92560 Added: Modified: llvm/include/llvm/Object/ELFObjectFile.h llvm/lib/DebugInfo/Symbolize/Symbolize.cpp llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp llvm/lib/InterfaceStub/ELFObjHandler.cpp llvm/lib/XRay/InstrumentationMap.cpp llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp llvm/tools/llvm-objcopy/ELF/Object.h llvm/tools/llvm-objdump/ELFDump.cpp llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h llvm/tools/llvm-readobj/ELFDumper.cpp llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 3a4937235d5b..a75aba86f9d4 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -441,7 +441,7 @@ template class ELFObjectFile : public ELFObjectFileBase { unsigned getPlatformFlags() const override { return EF.getHeader().e_flags; } - const ELFFile *getELFFile() const { return &EF; } + const ELFFile &getELFFile() const { return EF; } bool isDyldType() const { return isDyldELFObject; } static bool classof(const Binary *v) { diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 3eb84a141b81..5a98ce0753b6 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -287,10 +287,8 @@ bool darwinDsymMatchesBinary(const MachOObjectFile *DbgObj, } template -Optional> getBuildID(const ELFFile *Obj) { - if (!Obj) -return {}; - auto PhdrsOrErr = Obj->program_headers(); +Optional> getBuildID(const ELFFile &Obj) { + auto PhdrsOrErr = Obj.program_headers(); if (!PhdrsOrErr) { consumeError(PhdrsOrErr.takeError()); return {}; @@ -299,7 +297,7 @@ Optional> getBuildID(const ELFFile *Obj) { if (P.p_type != ELF::PT_NOTE) continue; Error Err = Error::success(); -for (auto N : Obj->notes(P, Err)) +for (auto N : Obj.notes(P, Err)) if (N.getType() == ELF::NT_GNU_BUILD_ID && N.getName() == ELF::ELF_NOTE_GNU) return N.getDesc(); consumeError(std::move(Err)); diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp index 49933fc14d52..a0f944db7943 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp @@ -626,7 +626,7 @@ class ELFJITLinker_x86_64 : public JITLinker { auto &ELFObjFile = cast>(**ELFObj); std::string fileName(ELFObj->get()->getFileName()); return ELFLinkGraphBuilder_x86_64(std::move(fileName), - *ELFObjFile.getELFFile()) + ELFObjFile.getELFFile()) .buildGraph(); } diff --git a/llvm/lib/InterfaceStub/ELFObjHandler.cpp b/llvm/lib/InterfaceStub/ELFObjHandler.cpp index ba583b79571e..e50ebd7b8ba1 100644 --- a/llvm/lib/InterfaceStub/ELFObjHandler.cpp +++ b/llvm/lib/InterfaceStub/ELFObjHandler.cpp @@ -585,15 +585,15 @@ buildStub(const ELFObjectFile &ElfObj) { using Elf_Sym_Range = typename ELFT::SymRange; using Elf_Sym = typename ELFT::Sym; std::unique_ptr DestStub = std::make_unique(); - const ELFFile *ElfFile = ElfObj.getELFFile(); + const ELFFile &ElfFile = ElfObj.getELFFile(); // Fetch .dynamic table. - Expected DynTable = ElfFile->dynamicEntries(); + Expected DynTable = ElfFile.dynamicEntries(); if (!DynTable) { return DynTable.takeError(); } // Fetch program headers. - Expected PHdrs = ElfFile->program_headers(); + Expected PHdrs = ElfFile.program_headers(); if (!PHdrs) { return PHdrs.takeError(); } @@ -604,8 +604,7 @@ buildStub(const ELFObjectFile &ElfObj) { return std::move(Err); // Get pointer to in-memory location of .dynstr section. - Expected DynStrPtr = - ElfFile->toMappedAddr(DynEnt.StrTabAddr); + Expected DynStrPtr = ElfFile.toMappedAddr(DynEnt.StrTabAddr); if (!DynStrPtr) return appendToError(DynStrPtr.takeError(), "when locating .dynstr section contents"); @@ -614,7 +613,7 @@ buildStub(const ELFObjectFile &ElfObj) { DynEnt.StrSize); // Populate Arch from ELF header. - DestStub->Arch = ElfFile->getHeader().e_machine; + DestStub->Arch = ElfFile.getHeader().e_machine; // Populate SoName fr
[llvm-branch-commits] [llvm] 44794cd - [llvm-profgen] - Fix compilation issue after ELFFile interface update.
Author: Georgii Rymar Date: 2020-12-04T16:09:25+03:00 New Revision: 44794cde188fea364e0868f427ae824ad8b32f9c URL: https://github.com/llvm/llvm-project/commit/44794cde188fea364e0868f427ae824ad8b32f9c DIFF: https://github.com/llvm/llvm-project/commit/44794cde188fea364e0868f427ae824ad8b32f9c.diff LOG: [llvm-profgen] - Fix compilation issue after ELFFile interface update. `D92560` changed `ELFObjectFile::getELFFile` to return reference. Added: Modified: llvm/tools/llvm-profgen/ProfiledBinary.cpp Removed: diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.cpp b/llvm/tools/llvm-profgen/ProfiledBinary.cpp index 7ea17c2ea9a7..7cc318ccffa6 100644 --- a/llvm/tools/llvm-profgen/ProfiledBinary.cpp +++ b/llvm/tools/llvm-profgen/ProfiledBinary.cpp @@ -43,12 +43,12 @@ static const Target *getTarget(const ObjectFile *Obj) { } template -static uint64_t getELFImageLMAForSec(const ELFFile *Obj, +static uint64_t getELFImageLMAForSec(const ELFFile &Obj, const object::ELFSectionRef &Sec, StringRef FileName) { // Search for a PT_LOAD segment containing the requested section. Return this // segment's p_addr as the image load address for the section. - const auto &PhdrRange = unwrapOrError(Obj->program_headers(), FileName); + const auto &PhdrRange = unwrapOrError(Obj.program_headers(), FileName); for (const typename ELFT::Phdr &Phdr : PhdrRange) if ((Phdr.p_type == ELF::PT_LOAD) && (Phdr.p_vaddr <= Sec.getAddress()) && (Phdr.p_vaddr + Phdr.p_memsz > Sec.getAddress())) ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 347ea1a - [llvm-readobj/elf] - Refine the implementation of "printFunctionStackSize".
Author: Georgii Rymar Date: 2020-12-07T14:57:44+03:00 New Revision: 347ea1af348e7b48341be4d85b10a7076483f59c URL: https://github.com/llvm/llvm-project/commit/347ea1af348e7b48341be4d85b10a7076483f59c DIFF: https://github.com/llvm/llvm-project/commit/347ea1af348e7b48341be4d85b10a7076483f59c.diff LOG: [llvm-readobj/elf] - Refine the implementation of "printFunctionStackSize". This rewrites the logic to get rid of "ELFSymbolRef" API where possible. This allowed to handle possible errors better, improve warnings reported and add new ones. Also 'reportWarning' was replaced with 'reportUniqueWarning' Differential revision: https://reviews.llvm.org/D92545 Added: Modified: llvm/include/llvm/Object/ELFObjectFile.h llvm/test/tools/llvm-readobj/ELF/stack-sizes.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index a75aba86f9d4..ae4521624077 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -246,6 +246,10 @@ template class ELFObjectFile : public ELFObjectFileBase { return SectionRef(toDRI(Sec), this); } + ELFSymbolRef toSymbolRef(const Elf_Shdr *SymTable, unsigned SymbolNum) const { +return ELFSymbolRef({toDRI(SymTable, SymbolNum), this}); + } + bool IsContentValid() const { return ContentValid; } private: diff --git a/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test b/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test index 01bdb7231567..35c400d69e76 100644 --- a/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test +++ b/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test @@ -74,10 +74,14 @@ Sections: - Offset: 0 Symbol: separate_text_section_baz Type: R_X86_64_64 + - Name: .symtab +Type: SHT_SYMTAB +ShOffset: [[SYMTABOFFSET=]] Symbols: - Name:separate_text_section_baz -Section: .text.baz +Section: [[SEC1=.text.baz]] Type:STT_FUNC +Index: [[SEC1INDEX=]] - Name:.text Section: .text Type:STT_SECTION @@ -91,6 +95,86 @@ Symbols: Type:STT_FUNC Binding: STB_GLOBAL +## Check that we report a warning when we are unable to read +## the symbol table when dumping stack sizes. + +# RUN: yaml2obj --docnum=1 %s -DSYMTABOFFSET=0x -o %t01.broken.symtab +# RUN: llvm-readelf --stack-sizes %t01.broken.symtab 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t01.broken.symtab --check-prefix=SYMTAB-GNU --implicit-check-not=warning: +# RUN: llvm-readobj --stack-sizes %t01.broken.symtab 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t01.broken.symtab --check-prefix=SYMTAB-LLVM --implicit-check-not=warning: + +# SYMTAB-GNU: Stack Sizes: +# SYMTAB-GNU-NEXT: Size Function +# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 5: unable to access section [index 7] data at 0xef36: offset goes past the end of file +# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to read the symbol table: section [index 7] has a sh_offset (0x) + sh_size (0x78) that is greater than the file size (0x450) +# SYMTAB-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 3 +# SYMTAB-GNU-NEXT:16 ? +# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 5: unable to access section [index 7] data at 0xef1e: offset goes past the end of file +# SYMTAB-GNU-NEXT:32 ? +# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 6: unable to access section [index 7] data at 0xef06: offset goes past the end of file +# SYMTAB-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 4 +# SYMTAB-GNU-NEXT: 8 ? + +# SYMTAB-LLVM: StackSizes [ +# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 5: unable to access section [index 7] data at 0xef36: offset goes past the end of file +# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to read the symbol table: section [index 7] has a sh_offset (0x) + sh_size (0x78) that is greater than the file size (0x450) +# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 3 +# SYMTAB-LLVM-NEXT: Entry { +# SYMTAB-LLVM-NEXT: Function: ? +# SYMTAB-LLVM-NEXT: Size: 0x10 +# SYMTAB-LLVM-NEXT: } +# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 5: unable to access section [index 7] data at
[llvm-branch-commits] [llvm] abae3c1 - [obj2yaml] - Support dumping objects that have multiple SHT_SYMTAB_SHNDX sections.
Author: Georgii Rymar Date: 2020-12-09T12:14:58+03:00 New Revision: abae3c11969defb6537dff99806668eacb6f0057 URL: https://github.com/llvm/llvm-project/commit/abae3c11969defb6537dff99806668eacb6f0057 DIFF: https://github.com/llvm/llvm-project/commit/abae3c11969defb6537dff99806668eacb6f0057.diff LOG: [obj2yaml] - Support dumping objects that have multiple SHT_SYMTAB_SHNDX sections. It is allowed to have multiple `SHT_SYMTAB_SHNDX` sections, though we currently don't implement it. The current implementation assumes that there is a maximum of one SHT_SYMTAB_SHNDX section and that it is always linked with .symtab section. This patch drops this limitations. Differential revision: https://reviews.llvm.org/D92644 Added: Modified: llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml b/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml index 2b337538acba..1c1e95e5bacb 100644 --- a/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml +++ b/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml @@ -94,7 +94,7 @@ Symbols: # RUN: yaml2obj --docnum=4 %s -o %t4 # RUN: not obj2yaml %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=CASE4 -## CASE4: Error reading file: [[FILE]]: SHT_SYMTAB_SHNDX has 3 entries, but the symbol table associated has 2 +## CASE4: Error reading file: [[FILE]]: unable to read extended section indexes: SHT_SYMTAB_SHNDX has 3 entries, but the symbol table associated has 2 --- !ELF FileHeader: @@ -113,12 +113,14 @@ Symbols: Index: SHN_XINDEX ## ELF gABI allows having multiple SHT_SYMTAB_SHNDX sections. -## We only support having one associated with .symtab now. +## Only one is allowed to be linked with a corresponding symbol table section though. +## Check we report an error when multiple SHT_SYMTAB_SHNDX sections are linked +## to the same symbol table. # RUN: yaml2obj --docnum=5 %s -o %t5 # RUN: not obj2yaml %t5 2>&1 | FileCheck %s -DFILE=%t5 --check-prefix=CASE5 -# CASE5: Error reading file: [[FILE]]: multiple SHT_SYMTAB_SHNDX sections are not supported +# CASE5: Error reading file: [[FILE]]: multiple SHT_SYMTAB_SHNDX sections are linked to the same symbol table with index 5 --- !ELF FileHeader: @@ -128,14 +130,41 @@ FileHeader: Sections: - Name:.symtab_shndx1 Type:SHT_SYMTAB_SHNDX -Entries: [ 0 ] +Entries: [ 0, 1 ] EntSize: 4 Link:.symtab - Name:.symtab_shndx2 Type:SHT_SYMTAB_SHNDX -Entries: [ 0 ] -Link:.symtab -Symbols: [] +Entries: [ 0, 2 ] +Link:[[LINK=.symtab]] +Symbols: + - Type: STT_SECTION +Index: SHN_XINDEX +DynamicSymbols: + - Type: STT_SECTION +Index: SHN_XINDEX + +## Check it is possible to dump an object that has multiple SHT_SYMTAB_SHNDX sections. +## Check that yaml2obj can dump the object and dynamic symbols properly when +## the SHT_SYMTAB_SHNDX section is associated with a SHT_DYNSYM section. + +# RUN: yaml2obj --docnum=5 -DLINK=.dynsym %s -o %t5.multiple +# RUN: obj2yaml %t5.multiple | FileCheck %s --check-prefix=MULTIPLE-SYMTAB + +# MULTIPLE-SYMTAB: - Name: .symtab_shndx1 +# MULTIPLE-SYMTAB-NEXT: Type: SHT_SYMTAB_SHNDX +# MULTIPLE-SYMTAB-NEXT: Link: .symtab +# MULTIPLE-SYMTAB: - Name: .symtab_shndx2 +# MULTIPLE-SYMTAB-NEXT: Type: SHT_SYMTAB_SHNDX +# MULTIPLE-SYMTAB-NEXT: Link: .dynsym +# MULTIPLE-SYMTAB: Symbols: +# MULTIPLE-SYMTAB-NEXT: - Name: .symtab_shndx1 +# MULTIPLE-SYMTAB-NEXT: Type: STT_SECTION +# MULTIPLE-SYMTAB-NEXT: Index: SHN_XINDEX +# MULTIPLE-SYMTAB-NEXT: DynamicSymbols: +# MULTIPLE-SYMTAB-NEXT: - Name: .symtab_shndx2 +# MULTIPLE-SYMTAB-NEXT: Type: STT_SECTION +# MULTIPLE-SYMTAB-NEXT: Index: SHN_XINDEX ## Check that yaml2obj can't dump the object if SHT_SYMTAB_SHNDX is ## not associated with a SHT_SYMTAB section (this case is illegal). @@ -143,7 +172,7 @@ Symbols: [] # RUN: yaml2obj --docnum=6 %s -o %t6 # RUN: not obj2yaml %t6 2>&1 | FileCheck %s -DFILE=%t6 --check-prefix=CASE6 -# CASE6: Error reading file: [[FILE]]: only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported +# CASE6: Error reading file: [[FILE]]: unable to read extended section indexes: SHT_SYMTAB_SHNDX section is linked with SHT_PROGBITS section (expected SHT_SYMTAB/SHT_DYNSYM) --- !ELF FileHeader: @@ -157,25 +186,3 @@ Sections: Link:.foo - Name:.foo Type:SHT_PROGBITS - -## Check that yaml2obj can't dump the object if SHT_SYMTAB_SHNDX is -## associated with a SHT_DYNSYM section (not implemented yet). - -# RUN: yaml2obj --docnum=7 %s -o %t7 -# RUN: not obj2yaml %t7 2>&1 | FileCheck %s -DFILE=%t7 --check-prefix=CASE7 - -# CASE7: Error reading file: [[FILE]]: only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported - !ELF -FileHeader: - Class: ELFCLASS64 - Da
[llvm-branch-commits] [llvm] bdfafc4 - [llvm-readelf/obj] - Improve diagnostics when printing NT_FILE notes.
Author: Georgii Rymar Date: 2020-12-09T12:31:46+03:00 New Revision: bdfafc4613bd2ff933c846708f4726128fb4b1ce URL: https://github.com/llvm/llvm-project/commit/bdfafc4613bd2ff933c846708f4726128fb4b1ce DIFF: https://github.com/llvm/llvm-project/commit/bdfafc4613bd2ff933c846708f4726128fb4b1ce.diff LOG: [llvm-readelf/obj] - Improve diagnostics when printing NT_FILE notes. This changes the `printNotesHelper` to report warnings on its side when there are errors when dumping notes. With that we can provide more content when reporting warnings about broken notes. Differential revision: https://reviews.llvm.org/D92636 Added: Modified: llvm/test/tools/llvm-readobj/ELF/note-core-ntfile-bad.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: diff --git a/llvm/test/tools/llvm-readobj/ELF/note-core-ntfile-bad.test b/llvm/test/tools/llvm-readobj/ELF/note-core-ntfile-bad.test index ca3033c7248a..5a497c23a795 100644 --- a/llvm/test/tools/llvm-readobj/ELF/note-core-ntfile-bad.test +++ b/llvm/test/tools/llvm-readobj/ELF/note-core-ntfile-bad.test @@ -9,7 +9,9 @@ # RUN: yaml2obj --docnum=1 %s -o %t1.o # RUN: llvm-readelf -n %t1.o 2>&1 | FileCheck -DFILE=%t1.o %s --check-prefix=ERR-HEADER-SHORT -# ERR-HEADER-SHORT: warning: '[[FILE]]': malformed note: header too short +# RUN: llvm-readobj -n %t1.o 2>&1 | FileCheck -DFILE=%t1.o %s --check-prefix=ERR-HEADER-SHORT + +# ERR-HEADER-SHORT: warning: '[[FILE]]': unable to read note with index 0 from the PT_NOTE segment with index 1: the note of size 0x8 is too short, expected at least 0x10 # .section ".note.foo", "a" # .align 4 @@ -38,7 +40,9 @@ ProgramHeaders: # RUN: yaml2obj --docnum=2 %s -o %t2.o # RUN: llvm-readelf -n %t2.o 2>&1 | FileCheck -DFILE=%t2.o %s --check-prefix=ERR-NULL-TERM -# ERR-NULL-TERM: warning: '[[FILE]]': malformed note: not NUL terminated +# RUN: llvm-readobj -n %t2.o 2>&1 | FileCheck -DFILE=%t2.o %s --check-prefix=ERR-NULL-TERM + +# ERR-NULL-TERM: warning: '[[FILE]]': unable to read note with index 0 from the PT_NOTE segment with index 1: the note is not NUL terminated # .section ".note.foo", "a" # .align 4 @@ -72,7 +76,9 @@ ProgramHeaders: # RUN: yaml2obj --docnum=3 %s -o %t3.o # RUN: llvm-readelf -n %t3.o 2>&1 | FileCheck -DFILE=%t3.o %s --check-prefix=ERR-FILE-COUNT -# ERR-FILE-COUNT: warning: '[[FILE]]': malformed note: too short for number of files +# RUN: llvm-readobj -n %t3.o 2>&1 | FileCheck -DFILE=%t3.o %s --check-prefix=ERR-FILE-COUNT + +# ERR-FILE-COUNT: warning: '[[FILE]]': unable to read note with index 0 from the PT_NOTE segment with index 1: unable to read file mappings (found 2): the note of size 0x2c is too short # .section ".note.foo", "a" # .align 4 @@ -106,7 +112,9 @@ ProgramHeaders: # RUN: yaml2obj --docnum=4 %s -o %t4.o # RUN: llvm-readelf -n %t4.o 2>&1 | FileCheck -DFILE=%t4.o %s --check-prefix=ERR-FILE-END-EARLY -# ERR-FILE-END-EARLY: warning: '[[FILE]]': malformed note: too few filenames +# RUN: llvm-readobj -n %t4.o 2>&1 | FileCheck -DFILE=%t4.o %s --check-prefix=ERR-FILE-END-EARLY + +# ERR-FILE-END-EARLY: warning: '[[FILE]]': unable to read note with index 0 from the PT_NOTE segment with index 1: unable to read the file name for the mapping with index 2: the note of size 0x44 is truncated # .section ".note.foo", "a" # .align 4 diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 2a286cb0b50d..279e406397d5 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -5333,19 +5333,20 @@ static Expected readCoreNote(DataExtractor Desc) { const int Bytes = Desc.getAddressSize(); if (!Desc.isValidOffsetForAddress(2)) -return createStringError(object_error::parse_failed, - "malformed note: header too short"); +return createError("the note of size 0x" + Twine::utohexstr(Desc.size()) + + " is too short, expected at least 0x" + + Twine::utohexstr(Bytes * 2)); if (Desc.getData().back() != 0) -return createStringError(object_error::parse_failed, - "malformed note: not NUL terminated"); +return createError("the note is not NUL terminated"); uint64_t DescOffset = 0; uint64_t FileCount = Desc.getAddress(&DescOffset); Ret.PageSize = Desc.getAddress(&DescOffset); if (!Desc.isValidOffsetForAddress(3 * FileCount * Bytes)) -return createStringError(object_error::parse_failed, - "malformed note: too short for number of files"); +return createError("unable to read file mappings (found " + + Twine(FileCount) + "): the note of size 0x" + + Twine::utohexstr(Desc.size()) + " is too short"); uint64_t FilenamesOffset = 0; DataExtractor Filenames( @@ -5353,10 +5354,1
[llvm-branch-commits] [llvm] 4e2e785 - [llvm-readelf] - Improve ELF type field dumping.
Author: Georgii Rymar Date: 2020-12-14T11:24:08+03:00 New Revision: 4e2e785ddd35c421a4df9453f17b8317d6b62b2c URL: https://github.com/llvm/llvm-project/commit/4e2e785ddd35c421a4df9453f17b8317d6b62b2c DIFF: https://github.com/llvm/llvm-project/commit/4e2e785ddd35c421a4df9453f17b8317d6b62b2c.diff LOG: [llvm-readelf] - Improve ELF type field dumping. This is related to https://bugs.llvm.org/show_bug.cgi?id=40868. Currently we don't print `OS Specific`/``Processor Specific`/`` prefixes when dumping the ELF file type. This is not consistent with GNU readelf. The patch fixes it. Also, this patch removes the `types.test`, because we already have `file-types.test`, which tests more cases and this patch revealed that we have such a duplicate. Differential revision: https://reviews.llvm.org/D93096 Added: Modified: llvm/include/llvm/BinaryFormat/ELF.h llvm/test/tools/llvm-readobj/ELF/file-types.test llvm/tools/llvm-readobj/ELFDumper.cpp Removed: llvm/test/tools/llvm-readobj/ELF/types.test diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index d49760c5d4c1..1552303b610c 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -107,13 +107,17 @@ struct Elf64_Ehdr { unsigned char getDataEncoding() const { return e_ident[EI_DATA]; } }; -// File types +// File types. +// See current registered ELF types at: +//http://www.sco.com/developers/gabi/latest/ch4.eheader.html enum { ET_NONE = 0,// No file type ET_REL = 1, // Relocatable file ET_EXEC = 2,// Executable file ET_DYN = 3, // Shared object file ET_CORE = 4,// Core file + ET_LOOS = 0xfe00, // Beginning of operating system-specific codes + ET_HIOS = 0xfeff, // Operating system-specific ET_LOPROC = 0xff00, // Beginning of processor-specific codes ET_HIPROC = 0x // Processor-specific }; diff --git a/llvm/test/tools/llvm-readobj/ELF/file-types.test b/llvm/test/tools/llvm-readobj/ELF/file-types.test index 8c8dc43d6bcc..767ce4d646ff 100644 --- a/llvm/test/tools/llvm-readobj/ELF/file-types.test +++ b/llvm/test/tools/llvm-readobj/ELF/file-types.test @@ -56,6 +56,17 @@ FileHeader: # GNU-CORE: ELF Header: # GNU-CORE: Type: CORE (Core file) +## Test what we dump for an arbitrary unknown ELF type. +# RUN: yaml2obj %s -DTYPE=0xFDFF -o %t.unknown +# RUN: llvm-readobj -h %t.unknown | FileCheck %s --match-full-lines --check-prefix LLVM-UNNKNOWN +# RUN: llvm-readelf -h %t.unknown | FileCheck %s --match-full-lines --check-prefix GNU-UNNKNOWN + +# LLVM-UNNKNOWN: ElfHeader { +# LLVM-UNNKNOWN: Type: 0xFDFF + +# GNU-UNNKNOWN: ELF Header: +# GNU-UNNKNOWN: Type: : fdff + # RUN: yaml2obj %s -DTYPE=0xfe00 -o %t6 # RUN: llvm-readobj -h %t6 | FileCheck %s --match-full-lines --check-prefix LLVM-LOOS # RUN: llvm-readelf -h %t6 | FileCheck %s --match-full-lines --check-prefix GNU-LOOS @@ -64,7 +75,7 @@ FileHeader: # LLVM-LOOS: Type: 0xFE00 # GNU-LOOS: ELF Header: -# GNU-LOOS: Type: fe00 +# GNU-LOOS: Type: OS Specific: (fe00) # RUN: yaml2obj %s -DTYPE=0xfeff -o %t7 # RUN: llvm-readobj -h %t7 | FileCheck %s --match-full-lines --check-prefix LLVM-HIOS @@ -74,7 +85,7 @@ FileHeader: # LLVM-HIOS: Type: 0xFEFF # GNU-HIOS: ELF Header: -# GNU-HIOS: Type: feff +# GNU-HIOS: Type: OS Specific: (feff) # RUN: yaml2obj %s -DTYPE=0xff00 -o %t8 # RUN: llvm-readobj -h %t8 | FileCheck %s --match-full-lines --check-prefix LLVM-LOPROC @@ -84,7 +95,7 @@ FileHeader: # LLVM-LOPROC: Type: 0xFF00 # GNU-LOPROC: ELF Header: -# GNU-LOPROC: Type: ff00 +# GNU-LOPROC: Type: Processor Specific: (ff00) # RUN: yaml2obj %s -DTYPE=0x -o %t9 # RUN: llvm-readobj -h %t9 | FileCheck %s --match-full-lines --check-prefix LLVM-HIPROC @@ -94,4 +105,4 @@ FileHeader: # LLVM-HIPROC: Type: 0x # GNU-HIPROC: ELF Header: -# GNU-HIPROC: Type: +# GNU-HIPROC: Type: Processor Specific: () diff --git a/llvm/test/tools/llvm-readobj/ELF/types.test b/llvm/test/tools/llvm-readobj/ELF/types.test deleted file mode 100644 index ffc3ec34aea4.. --- a/llvm/test/tools/llvm-readobj/ELF/types.test +++ /dev/null @@ -1,65 +0,0 @@ -# Show that llvm-readobj can handle all standard ELF types. -# RUN: yaml2obj %s -DTYPE=ET_NONE -o %t.none -# RUN: llvm-readobj --file-headers %t.none | FileCheck %s --check-prefix=LLVM-NONE -# RUN: llvm-readelf --file-headers %t.none | FileCheck %s --check-prefix=GNU-NONE - -# LLVM-NONE: Type: None (0x0) -# GNU-NONE: Type: NONE (none) - !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: [[TYPE]] - -# RUN: yaml2obj %s -DTYPE=ET_REL -o %t.rel -# RUN: llvm-readobj --file-headers %t.rel | FileCheck %s --check-prefix=LLVM-REL -# RUN: llvm-readelf --file-headers %t.rel | FileCheck %s --check-prefix=GNU-REL - -# LLVM-REL: Type: Relocatable