From fc21bb661f5177eaec4d756b904167be4f0e7dfb Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Tue, 6 Aug 2019 13:39:50 +0000 Subject: [PATCH] Revert "[yaml2obj] Move core yaml2obj code into lib and include for use in unit tests" This reverts commit r368021, it broke tests. llvm-svn: 368035 --- llvm/lib/ObjectYAML/CMakeLists.txt | 9 --- llvm/lib/ObjectYAML/LLVMBuild.txt | 2 +- llvm/lib/ObjectYAML/yaml2obj.cpp | 68 ----------------- llvm/test/tools/yaml2obj/empty-or-invalid-doc.yaml | 4 +- llvm/test/tools/yaml2obj/invalid-docnum.test | 22 ------ llvm/test/tools/yaml2obj/missing_document_tag.yaml | 2 +- llvm/tools/yaml2obj/CMakeLists.txt | 8 ++ .../yaml2obj/yaml2coff.cpp} | 85 +++++++++++----------- .../ELFEmitter.cpp => tools/yaml2obj/yaml2elf.cpp} | 60 ++++++++------- .../yaml2obj/yaml2macho.cpp} | 16 ++-- .../yaml2obj/yaml2minidump.cpp} | 8 +- llvm/tools/yaml2obj/yaml2obj.cpp | 39 ++++++++-- .../llvm/ObjectYAML => tools/yaml2obj}/yaml2obj.h | 31 ++------ .../yaml2obj/yaml2wasm.cpp} | 48 +++++------- llvm/unittests/ObjectYAML/CMakeLists.txt | 1 - llvm/unittests/ObjectYAML/YAML2ObjTest.cpp | 36 --------- 16 files changed, 149 insertions(+), 290 deletions(-) delete mode 100644 llvm/lib/ObjectYAML/yaml2obj.cpp delete mode 100644 llvm/test/tools/yaml2obj/invalid-docnum.test rename llvm/{lib/ObjectYAML/COFFEmitter.cpp => tools/yaml2obj/yaml2coff.cpp} (92%) rename llvm/{lib/ObjectYAML/ELFEmitter.cpp => tools/yaml2obj/yaml2elf.cpp} (97%) rename llvm/{lib/ObjectYAML/MachOEmitter.cpp => tools/yaml2obj/yaml2macho.cpp} (98%) rename llvm/{lib/ObjectYAML/MinidumpEmitter.cpp => tools/yaml2obj/yaml2minidump.cpp} (83%) rename llvm/{include/llvm/ObjectYAML => tools/yaml2obj}/yaml2obj.h (52%) rename llvm/{lib/ObjectYAML/WasmEmitter.cpp => tools/yaml2obj/yaml2wasm.cpp} (99%) delete mode 100644 llvm/unittests/ObjectYAML/YAML2ObjTest.cpp diff --git a/llvm/lib/ObjectYAML/CMakeLists.txt b/llvm/lib/ObjectYAML/CMakeLists.txt index 434da71..8943aab 100644 --- a/llvm/lib/ObjectYAML/CMakeLists.txt +++ b/llvm/lib/ObjectYAML/CMakeLists.txt @@ -3,24 +3,15 @@ add_llvm_library(LLVMObjectYAML CodeViewYAMLSymbols.cpp CodeViewYAMLTypeHashing.cpp CodeViewYAMLTypes.cpp - COFFEmitter.cpp COFFYAML.cpp DWARFEmitter.cpp DWARFVisitor.cpp DWARFYAML.cpp - ELFEmitter.cpp ELFYAML.cpp - MachOEmitter.cpp MachOYAML.cpp ObjectYAML.cpp - MinidumpEmitter.cpp MinidumpYAML.cpp - WasmEmitter.cpp WasmYAML.cpp XCOFFYAML.cpp YAML.cpp - yaml2obj.cpp - - ADDITIONAL_HEADER_DIRS - ${LLVM_MAIN_INCLUDE_DIR}/llvm/ObjectYAML ) diff --git a/llvm/lib/ObjectYAML/LLVMBuild.txt b/llvm/lib/ObjectYAML/LLVMBuild.txt index de43aaf..c921236 100644 --- a/llvm/lib/ObjectYAML/LLVMBuild.txt +++ b/llvm/lib/ObjectYAML/LLVMBuild.txt @@ -10,4 +10,4 @@ type = Library name = ObjectYAML parent = Libraries -required_libraries = Object Support DebugInfoCodeView MC +required_libraries = Object Support DebugInfoCodeView diff --git a/llvm/lib/ObjectYAML/yaml2obj.cpp b/llvm/lib/ObjectYAML/yaml2obj.cpp deleted file mode 100644 index f9bcba6..0000000 --- a/llvm/lib/ObjectYAML/yaml2obj.cpp +++ /dev/null @@ -1,68 +0,0 @@ -//===-- yaml2obj.cpp ------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/ObjectYAML/yaml2obj.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/ObjectYAML/ObjectYAML.h" -#include "llvm/Support/Errc.h" -#include "llvm/Support/YAMLTraits.h" - -namespace llvm { -namespace yaml { - -Error convertYAML(yaml::Input &YIn, raw_ostream &Out, unsigned DocNum) { - // TODO: make yaml2* functions return Error instead of int. - auto IntToErr = [](int Ret) -> Error { - if (Ret) - return createStringError(errc::invalid_argument, "yaml2obj failed"); - return Error::success(); - }; - - unsigned CurDocNum = 0; - do { - if (++CurDocNum == DocNum) { - yaml::YamlObjectFile Doc; - YIn >> Doc; - if (std::error_code EC = YIn.error()) - return createStringError(EC, "Failed to parse YAML input!"); - if (Doc.Elf) - return IntToErr(yaml2elf(*Doc.Elf, Out)); - if (Doc.Coff) - return IntToErr(yaml2coff(*Doc.Coff, Out)); - if (Doc.MachO || Doc.FatMachO) - return IntToErr(yaml2macho(Doc, Out)); - if (Doc.Minidump) - return IntToErr(yaml2minidump(*Doc.Minidump, Out)); - if (Doc.Wasm) - return IntToErr(yaml2wasm(*Doc.Wasm, Out)); - return createStringError(errc::invalid_argument, - "Unknown document type!"); - } - } while (YIn.nextDocument()); - - return createStringError(errc::invalid_argument, - "Cannot find the %u%s document", DocNum, - getOrdinalSuffix(DocNum).data()); -} - -Expected> -yaml2ObjectFile(SmallVectorImpl &Storage, StringRef Yaml) { - Storage.clear(); - raw_svector_ostream OS(Storage); - - yaml::Input YIn(Yaml); - if (Error E = convertYAML(YIn, OS)) - return std::move(E); - - return object::ObjectFile::createObjectFile( - MemoryBufferRef(OS.str(), "YamlObject")); -} - -} // namespace yaml -} // namespace llvm diff --git a/llvm/test/tools/yaml2obj/empty-or-invalid-doc.yaml b/llvm/test/tools/yaml2obj/empty-or-invalid-doc.yaml index de79f41..450f2f7 100644 --- a/llvm/test/tools/yaml2obj/empty-or-invalid-doc.yaml +++ b/llvm/test/tools/yaml2obj/empty-or-invalid-doc.yaml @@ -2,7 +2,7 @@ # RUN: echo -n "" | not yaml2obj 2>&1 | FileCheck %s # RUN: echo " " | not yaml2obj 2>&1 | FileCheck %s # RUN: echo " " | not yaml2obj 2>&1 | FileCheck %s -# CHECK: yaml2obj: error: Unknown document type! +# CHECK: yaml2obj: Unknown document type! # RUN: echo -e -n "\xff" | not yaml2obj 2>&1 | FileCheck %s --check-prefix=INVALID -# INVALID: yaml2obj: error: Failed to parse YAML input! +# INVALID: yaml2obj: Failed to parse YAML file! diff --git a/llvm/test/tools/yaml2obj/invalid-docnum.test b/llvm/test/tools/yaml2obj/invalid-docnum.test deleted file mode 100644 index 0f79602..0000000 --- a/llvm/test/tools/yaml2obj/invalid-docnum.test +++ /dev/null @@ -1,22 +0,0 @@ -## Test that an error is reported when a docnum is specified, which is -## greater than the number of YAML inputs in the file. - -# RUN: not yaml2obj %s --docnum=3 2>&1 | FileCheck %s -# CHECK: yaml2obj: error: Cannot find the 3rd document - -# RUN: not yaml2obj %s --docnum=76768677 2>&1 | FileCheck %s --check-prefix=TWO -# TWO: yaml2obj: error: Cannot find the 76768677th document - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_DYN - Machine: EM_X86_64 - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_DYN - Machine: EM_X86_64 diff --git a/llvm/test/tools/yaml2obj/missing_document_tag.yaml b/llvm/test/tools/yaml2obj/missing_document_tag.yaml index d41e799..8cfd9a1 100644 --- a/llvm/test/tools/yaml2obj/missing_document_tag.yaml +++ b/llvm/test/tools/yaml2obj/missing_document_tag.yaml @@ -6,4 +6,4 @@ DummyData: ... # CHECK: YAML:4:1: error: YAML Object File missing document type tag! -# CHECK: yaml2obj: error: Failed to parse YAML input! +# CHECK: yaml2obj: Failed to parse YAML file! diff --git a/llvm/tools/yaml2obj/CMakeLists.txt b/llvm/tools/yaml2obj/CMakeLists.txt index 0cbc8e0..1c61fb7 100644 --- a/llvm/tools/yaml2obj/CMakeLists.txt +++ b/llvm/tools/yaml2obj/CMakeLists.txt @@ -1,8 +1,16 @@ set(LLVM_LINK_COMPONENTS + DebugInfoCodeView + MC + Object ObjectYAML Support ) add_llvm_tool(yaml2obj yaml2obj.cpp + yaml2coff.cpp + yaml2elf.cpp + yaml2macho.cpp + yaml2minidump.cpp + yaml2wasm.cpp ) diff --git a/llvm/lib/ObjectYAML/COFFEmitter.cpp b/llvm/tools/yaml2obj/yaml2coff.cpp similarity index 92% rename from llvm/lib/ObjectYAML/COFFEmitter.cpp rename to llvm/tools/yaml2obj/yaml2coff.cpp index d94cdbf..3afbd58 100644 --- a/llvm/lib/ObjectYAML/COFFEmitter.cpp +++ b/llvm/tools/yaml2obj/yaml2coff.cpp @@ -11,6 +11,7 @@ /// //===----------------------------------------------------------------------===// +#include "yaml2obj.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" @@ -19,7 +20,6 @@ #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" #include "llvm/Object/COFF.h" #include "llvm/ObjectYAML/ObjectYAML.h" -#include "llvm/ObjectYAML/yaml2obj.h" #include "llvm/Support/Endian.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" @@ -29,8 +29,6 @@ using namespace llvm; -namespace { - /// This parses a yaml stream that represents a COFF object file. /// See docs/yaml2obj for the yaml scheema. struct COFFParser { @@ -66,8 +64,7 @@ struct COFFParser { bool parseSections() { for (std::vector::iterator i = Obj.Sections.begin(), - e = Obj.Sections.end(); - i != e; ++i) { + e = Obj.Sections.end(); i != e; ++i) { COFFYAML::Section &Sec = *i; // If the name is less than 8 bytes, store it in place, otherwise @@ -105,8 +102,7 @@ struct COFFParser { bool parseSymbols() { for (std::vector::iterator i = Obj.Symbols.begin(), - e = Obj.Symbols.end(); - i != e; ++i) { + e = Obj.Symbols.end(); i != e; ++i) { COFFYAML::Symbol &Sym = *i; // If the name is less than 8 bytes, store it in place, otherwise @@ -117,8 +113,8 @@ struct COFFParser { } else { // Add string to the string table and format the index for output. unsigned Index = getStringIndex(Name); - *reinterpret_cast(Sym.Header.Name + 4) = - Index; + *reinterpret_cast( + Sym.Header.Name + 4) = Index; } Sym.Header.Type = Sym.SimpleType; @@ -157,10 +153,6 @@ struct COFFParser { uint32_t SectionTableSize; }; -enum { DOSStubSize = 128 }; - -} // end anonymous namespace - // Take a CP and assign addresses and sizes to everything. Returns false if the // layout is not valid to do. static bool layoutOptionalHeader(COFFParser &CP) { @@ -174,6 +166,10 @@ static bool layoutOptionalHeader(COFFParser &CP) { return true; } +namespace { +enum { DOSStubSize = 128 }; +} + static yaml::BinaryRef toDebugS(ArrayRef Subsections, const codeview::StringsAndChecksums &SC, BumpPtrAllocator &Allocator) { @@ -275,7 +271,7 @@ static bool layoutCOFF(COFFParser &CP) { uint32_t NumberOfSymbols = 0; for (std::vector::iterator i = CP.Obj.Symbols.begin(), e = CP.Obj.Symbols.end(); - i != e; ++i) { + i != e; ++i) { uint32_t NumberOfAuxSymbols = 0; if (i->FunctionDefinition) NumberOfAuxSymbols += 1; @@ -302,23 +298,24 @@ static bool layoutCOFF(COFFParser &CP) { else CP.Obj.Header.PointerToSymbolTable = 0; - *reinterpret_cast(&CP.StringTable[0]) = - CP.StringTable.size(); + *reinterpret_cast(&CP.StringTable[0]) + = CP.StringTable.size(); return true; } -template struct binary_le_impl { +template +struct binary_le_impl { value_type Value; binary_le_impl(value_type V) : Value(V) {} }; template -raw_ostream &operator<<(raw_ostream &OS, - const binary_le_impl &BLE) { +raw_ostream &operator <<( raw_ostream &OS + , const binary_le_impl &BLE) { char Buffer[sizeof(BLE.Value)]; support::endian::write( - Buffer, BLE.Value); + Buffer, BLE.Value); OS.write(Buffer, sizeof(BLE.Value)); return OS; } @@ -338,13 +335,13 @@ raw_ostream &operator<<(raw_ostream &OS, const zeros_impl &) { return OS; } -template zeros_impl zeros(const T &) { +template +zeros_impl zeros(const T &) { return zeros_impl(); } template -static uint32_t initializeOptionalHeader(COFFParser &CP, uint16_t Magic, - T Header) { +static uint32_t initializeOptionalHeader(COFFParser &CP, uint16_t Magic, T Header) { memset(Header, 0, sizeof(*Header)); Header->Magic = Magic; Header->SectionAlignment = CP.Obj.OptionalHeader->Header.SectionAlignment; @@ -379,8 +376,10 @@ static uint32_t initializeOptionalHeader(COFFParser &CP, uint16_t Magic, CP.Obj.OptionalHeader->Header.MajorOperatingSystemVersion; Header->MinorOperatingSystemVersion = CP.Obj.OptionalHeader->Header.MinorOperatingSystemVersion; - Header->MajorImageVersion = CP.Obj.OptionalHeader->Header.MajorImageVersion; - Header->MinorImageVersion = CP.Obj.OptionalHeader->Header.MinorImageVersion; + Header->MajorImageVersion = + CP.Obj.OptionalHeader->Header.MajorImageVersion; + Header->MinorImageVersion = + CP.Obj.OptionalHeader->Header.MinorImageVersion; Header->MajorSubsystemVersion = CP.Obj.OptionalHeader->Header.MajorSubsystemVersion; Header->MinorSubsystemVersion = @@ -424,13 +423,15 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { if (CP.useBigObj()) { OS << binary_le(static_cast(COFF::IMAGE_FILE_MACHINE_UNKNOWN)) << binary_le(static_cast(0xffff)) - << binary_le( - static_cast(COFF::BigObjHeader::MinBigObjectVersion)) + << binary_le(static_cast(COFF::BigObjHeader::MinBigObjectVersion)) << binary_le(CP.Obj.Header.Machine) << binary_le(CP.Obj.Header.TimeDateStamp); OS.write(COFF::BigObjMagic, sizeof(COFF::BigObjMagic)); - OS << zeros(uint32_t(0)) << zeros(uint32_t(0)) << zeros(uint32_t(0)) - << zeros(uint32_t(0)) << binary_le(CP.Obj.Header.NumberOfSections) + OS << zeros(uint32_t(0)) + << zeros(uint32_t(0)) + << zeros(uint32_t(0)) + << zeros(uint32_t(0)) + << binary_le(CP.Obj.Header.NumberOfSections) << binary_le(CP.Obj.Header.PointerToSymbolTable) << binary_le(CP.Obj.Header.NumberOfSymbols); } else { @@ -449,8 +450,7 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { OS.write(reinterpret_cast(&PEH), sizeof(PEH)); } else { object::pe32_header PEH; - uint32_t BaseOfData = - initializeOptionalHeader(CP, COFF::PE32Header::PE32, &PEH); + uint32_t BaseOfData = initializeOptionalHeader(CP, COFF::PE32Header::PE32, &PEH); PEH.BaseOfData = BaseOfData; OS.write(reinterpret_cast(&PEH), sizeof(PEH)); } @@ -472,7 +472,7 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { // Output section table. for (std::vector::iterator i = CP.Obj.Sections.begin(), e = CP.Obj.Sections.end(); - i != e; ++i) { + i != e; ++i) { OS.write(i->Header.Name, COFF::NameSize); OS << binary_le(i->Header.VirtualSize) << binary_le(i->Header.VirtualAddress) @@ -514,7 +514,8 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { } else { SymbolTableIndex = SymbolTableIndexMap[R.SymbolName]; } - OS << binary_le(R.VirtualAddress) << binary_le(SymbolTableIndex) + OS << binary_le(R.VirtualAddress) + << binary_le(SymbolTableIndex) << binary_le(R.Type); } } @@ -523,14 +524,15 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { for (std::vector::const_iterator i = CP.Obj.Symbols.begin(), e = CP.Obj.Symbols.end(); - i != e; ++i) { + i != e; ++i) { OS.write(i->Header.Name, COFF::NameSize); OS << binary_le(i->Header.Value); if (CP.useBigObj()) - OS << binary_le(i->Header.SectionNumber); + OS << binary_le(i->Header.SectionNumber); else - OS << binary_le(static_cast(i->Header.SectionNumber)); - OS << binary_le(i->Header.Type) << binary_le(i->Header.StorageClass) + OS << binary_le(static_cast(i->Header.SectionNumber)); + OS << binary_le(i->Header.Type) + << binary_le(i->Header.StorageClass) << binary_le(i->Header.NumberOfAuxSymbols); if (i->FunctionDefinition) { @@ -576,7 +578,8 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { OS.write_zeros(CP.getSymbolSize() - COFF::Symbol16Size); } if (i->CLRToken) { - OS << binary_le(i->CLRToken->AuxType) << zeros(i->CLRToken->unused1) + OS << binary_le(i->CLRToken->AuxType) + << zeros(i->CLRToken->unused1) << binary_le(i->CLRToken->SymbolTableIndex) << zeros(i->CLRToken->unused2); OS.write_zeros(CP.getSymbolSize() - COFF::Symbol16Size); @@ -589,9 +592,6 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { return true; } -namespace llvm { -namespace yaml { - int yaml2coff(llvm::COFFYAML::Object &Doc, raw_ostream &Out) { COFFParser CP(Doc); if (!CP.parse()) { @@ -614,6 +614,3 @@ int yaml2coff(llvm::COFFYAML::Object &Doc, raw_ostream &Out) { } return 0; } - -} // namespace yaml -} // namespace llvm diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/tools/yaml2obj/yaml2elf.cpp similarity index 97% rename from llvm/lib/ObjectYAML/ELFEmitter.cpp rename to llvm/tools/yaml2obj/yaml2elf.cpp index 370d620..bcb390b 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/tools/yaml2obj/yaml2elf.cpp @@ -11,13 +11,13 @@ /// //===----------------------------------------------------------------------===// +#include "yaml2obj.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringSet.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/StringTableBuilder.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/ObjectYAML/ELFYAML.h" -#include "llvm/ObjectYAML/yaml2obj.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Support/EndianStream.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/WithColor.h" @@ -55,9 +55,11 @@ public: } void writeBlobToStream(raw_ostream &Out) { Out << OS.str(); } }; +} // end anonymous namespace // Used to keep track of section and symbol names, so that in the YAML file // sections and symbols can be referenced by name instead of by index. +namespace { class NameToIdxMap { StringMap Map; @@ -84,11 +86,29 @@ public: } unsigned size() const { return Map.size(); } }; +} // end anonymous namespace + +template +static size_t arrayDataSize(ArrayRef A) { + return A.size() * sizeof(T); +} +template +static void writeArrayData(raw_ostream &OS, ArrayRef A) { + OS.write((const char *)A.data(), arrayDataSize(A)); +} + +template +static void zero(T &Obj) { + memset(&Obj, 0, sizeof(Obj)); +} + +namespace { /// "Single point of truth" for the ELF file construction. /// TODO: This class still has a ways to go before it is truly a "single /// point of truth". -template class ELFState { +template +class ELFState { typedef typename ELFT::Ehdr Elf_Ehdr; typedef typename ELFT::Phdr Elf_Phdr; typedef typename ELFT::Shdr Elf_Shdr; @@ -165,17 +185,8 @@ private: }; } // end anonymous namespace -template static size_t arrayDataSize(ArrayRef A) { - return A.size() * sizeof(T); -} - -template static void writeArrayData(raw_ostream &OS, ArrayRef A) { - OS.write((const char *)A.data(), arrayDataSize(A)); -} - -template static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); } - -template ELFState::ELFState(ELFYAML::Object &D) : Doc(D) { +template +ELFState::ELFState(ELFYAML::Object &D) : Doc(D) { StringSet<> DocSections; for (std::unique_ptr &D : Doc.Sections) if (!D->Name.empty()) @@ -186,7 +197,7 @@ template ELFState::ELFState(ELFYAML::Object &D) : Doc(D) { Doc.Sections.insert( Doc.Sections.begin(), llvm::make_unique( - ELFYAML::Section::SectionKind::RawContent, /*IsImplicit=*/true)); + ELFYAML::Section::SectionKind::RawContent, /*IsImplicit=*/true)); std::vector ImplicitSections = {".symtab", ".strtab", ".shstrtab"}; if (!Doc.DynamicSymbols.empty()) @@ -205,7 +216,8 @@ template ELFState::ELFState(ELFYAML::Object &D) : Doc(D) { } } -template void ELFState::initELFHeader(Elf_Ehdr &Header) { +template +void ELFState::initELFHeader(Elf_Ehdr &Header) { using namespace llvm::ELF; zero(Header); Header.e_ident[EI_MAG0] = 0x7f; @@ -688,9 +700,10 @@ static bool isMips64EL(const ELFYAML::Object &Doc) { } template -bool ELFState::writeSectionContent( - Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section, - ContiguousBlobAccumulator &CBA) { +bool +ELFState::writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::RelocationSection &Section, + ContiguousBlobAccumulator &CBA) { assert((Section.Type == llvm::ELF::SHT_REL || Section.Type == llvm::ELF::SHT_RELA) && "Section type is not SHT_REL nor SHT_RELA"); @@ -936,8 +949,7 @@ bool ELFState::writeSectionContent(Elf_Shdr &SHeader, else SHeader.sh_entsize = sizeof(Elf_Dyn); - raw_ostream &OS = - CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); + raw_ostream &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); for (const ELFYAML::DynamicEntry &DE : Section.Entries) { support::endian::write(OS, DE.Tag, ELFT::TargetEndianness); support::endian::write(OS, DE.Val, ELFT::TargetEndianness); @@ -1063,9 +1075,6 @@ int ELFState::writeELF(raw_ostream &OS, ELFYAML::Object &Doc) { return 0; } -namespace llvm { -namespace yaml { - int yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out) { bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64); @@ -1078,6 +1087,3 @@ int yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out) { return ELFState::writeELF(Out, Doc); return ELFState::writeELF(Out, Doc); } - -} // namespace yaml -} // namespace llvm diff --git a/llvm/lib/ObjectYAML/MachOEmitter.cpp b/llvm/tools/yaml2obj/yaml2macho.cpp similarity index 98% rename from llvm/lib/ObjectYAML/MachOEmitter.cpp rename to llvm/tools/yaml2obj/yaml2macho.cpp index e7789d0..9dcc7d1 100644 --- a/llvm/lib/ObjectYAML/MachOEmitter.cpp +++ b/llvm/tools/yaml2obj/yaml2macho.cpp @@ -11,10 +11,10 @@ /// //===----------------------------------------------------------------------===// +#include "yaml2obj.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/ObjectYAML/DWARFEmitter.h" #include "llvm/ObjectYAML/ObjectYAML.h" -#include "llvm/ObjectYAML/yaml2obj.h" #include "llvm/Support/Error.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/YAMLTraits.h" @@ -263,7 +263,8 @@ Error MachOWriter::writeLoadCommands(raw_ostream &OS) { } static bool isVirtualSection(uint8_t type) { - return (type == MachO::S_ZEROFILL || type == MachO::S_GB_ZEROFILL || + return (type == MachO::S_ZEROFILL || + type == MachO::S_GB_ZEROFILL || type == MachO::S_THREAD_LOCAL_ZEROFILL); } @@ -275,8 +276,7 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) { case MachO::LC_SEGMENT_64: uint64_t segOff = is64Bit ? LC.Data.segment_command_64_data.fileoff : LC.Data.segment_command_data.fileoff; - if (0 == - strncmp(&LC.Data.segment_command_data.segname[0], "__LINKEDIT", 16)) { + if (0 == strncmp(&LC.Data.segment_command_data.segname[0], "__LINKEDIT", 16)) { FoundLinkEditSeg = true; if (auto Err = writeLinkEditData(OS)) return Err; @@ -592,10 +592,7 @@ void UniversalWriter::ZeroToOffset(raw_ostream &OS, size_t Offset) { } // end anonymous namespace -namespace llvm { -namespace yaml { - -int yaml2macho(YamlObjectFile &Doc, raw_ostream &Out) { +int yaml2macho(yaml::YamlObjectFile &Doc, raw_ostream &Out) { UniversalWriter Writer(Doc); if (auto Err = Writer.writeMachO(Out)) { errs() << toString(std::move(Err)); @@ -603,6 +600,3 @@ int yaml2macho(YamlObjectFile &Doc, raw_ostream &Out) { } return 0; } - -} // namespace yaml -} // namespace llvm diff --git a/llvm/lib/ObjectYAML/MinidumpEmitter.cpp b/llvm/tools/yaml2obj/yaml2minidump.cpp similarity index 83% rename from llvm/lib/ObjectYAML/MinidumpEmitter.cpp rename to llvm/tools/yaml2obj/yaml2minidump.cpp index 3e3a254..a9a2947 100644 --- a/llvm/lib/ObjectYAML/MinidumpEmitter.cpp +++ b/llvm/tools/yaml2obj/yaml2minidump.cpp @@ -6,19 +6,13 @@ // //===----------------------------------------------------------------------===// +#include "yaml2obj.h" #include "llvm/ObjectYAML/MinidumpYAML.h" -#include "llvm/ObjectYAML/yaml2obj.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; -namespace llvm { -namespace yaml { - int yaml2minidump(MinidumpYAML::Object &Doc, raw_ostream &Out) { writeAsBinary(Doc, Out); return 0; } - -} // namespace yaml -} // namespace llvm diff --git a/llvm/tools/yaml2obj/yaml2obj.cpp b/llvm/tools/yaml2obj/yaml2obj.cpp index 76e6663..533c8ea 100644 --- a/llvm/tools/yaml2obj/yaml2obj.cpp +++ b/llvm/tools/yaml2obj/yaml2obj.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ObjectYAML/yaml2obj.h" +#include "yaml2obj.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ObjectYAML/ObjectYAML.h" #include "llvm/Support/CommandLine.h" @@ -21,7 +21,6 @@ #include "llvm/Support/InitLLVM.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/ToolOutputFile.h" -#include "llvm/Support/WithColor.h" #include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" #include @@ -43,6 +42,32 @@ LLVM_ATTRIBUTE_NORETURN static void error(Twine Message) { exit(1); } +static int convertYAML(yaml::Input &YIn, raw_ostream &Out) { + unsigned CurDocNum = 0; + do { + if (++CurDocNum == DocNum) { + yaml::YamlObjectFile Doc; + YIn >> Doc; + if (YIn.error()) + error("yaml2obj: Failed to parse YAML file!"); + if (Doc.Elf) + return yaml2elf(*Doc.Elf, Out); + if (Doc.Coff) + return yaml2coff(*Doc.Coff, Out); + if (Doc.MachO || Doc.FatMachO) + return yaml2macho(Doc, Out); + if (Doc.Minidump) + return yaml2minidump(*Doc.Minidump, Out); + if (Doc.Wasm) + return yaml2wasm(*Doc.Wasm, Out); + error("yaml2obj: Unknown document type!"); + } + } while (YIn.nextDocument()); + + error("yaml2obj: Cannot find the " + Twine(DocNum) + + llvm::getOrdinalSuffix(DocNum) + " document"); +} + int main(int argc, char **argv) { InitLLVM X(argc, argv); cl::ParseCommandLineOptions(argc, argv); @@ -62,12 +87,10 @@ int main(int argc, char **argv) { return 1; yaml::Input YIn(Buf.get()->getBuffer()); - if (Error E = convertYAML(YIn, Out->os(), DocNum)) { - logAllUnhandledErrors(std::move(E), WithColor::error(errs(), argv[0])); - return 1; - } + int Res = convertYAML(YIn, Out->os()); + if (Res == 0) + Out->keep(); - Out->keep(); Out->os().flush(); - return 0; + return Res; } diff --git a/llvm/include/llvm/ObjectYAML/yaml2obj.h b/llvm/tools/yaml2obj/yaml2obj.h similarity index 52% rename from llvm/include/llvm/ObjectYAML/yaml2obj.h rename to llvm/tools/yaml2obj/yaml2obj.h index d8d8dad..60c2987 100644 --- a/llvm/include/llvm/ObjectYAML/yaml2obj.h +++ b/llvm/tools/yaml2obj/yaml2obj.h @@ -11,18 +11,8 @@ #ifndef LLVM_TOOLS_YAML2OBJ_YAML2OBJ_H #define LLVM_TOOLS_YAML2OBJ_YAML2OBJ_H -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Error.h" -#include - namespace llvm { class raw_ostream; -template class SmallVectorImpl; -template class Expected; - -namespace object { -class ObjectFile; -} namespace COFFYAML { struct Object; @@ -43,20 +33,13 @@ struct Object; namespace yaml { class Input; struct YamlObjectFile; +} +} -int yaml2coff(COFFYAML::Object &Doc, raw_ostream &Out); -int yaml2elf(ELFYAML::Object &Doc, raw_ostream &Out); -int yaml2macho(YamlObjectFile &Doc, raw_ostream &Out); -int yaml2minidump(MinidumpYAML::Object &Doc, raw_ostream &Out); -int yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out); - -Error convertYAML(Input &YIn, raw_ostream &Out, unsigned DocNum = 1); - -/// Convenience function for tests. -Expected> -yaml2ObjectFile(SmallVectorImpl &Storage, StringRef Yaml); - -} // namespace yaml -} // namespace llvm +int yaml2coff(llvm::COFFYAML::Object &Doc, llvm::raw_ostream &Out); +int yaml2elf(llvm::ELFYAML::Object &Doc, llvm::raw_ostream &Out); +int yaml2macho(llvm::yaml::YamlObjectFile &Doc, llvm::raw_ostream &Out); +int yaml2minidump(llvm::MinidumpYAML::Object &Doc, llvm::raw_ostream &Out); +int yaml2wasm(llvm::WasmYAML::Object &Doc, llvm::raw_ostream &Out); #endif diff --git a/llvm/lib/ObjectYAML/WasmEmitter.cpp b/llvm/tools/yaml2obj/yaml2wasm.cpp similarity index 99% rename from llvm/lib/ObjectYAML/WasmEmitter.cpp rename to llvm/tools/yaml2obj/yaml2wasm.cpp index 5769d7b..758c498 100644 --- a/llvm/lib/ObjectYAML/WasmEmitter.cpp +++ b/llvm/tools/yaml2obj/yaml2wasm.cpp @@ -14,13 +14,11 @@ #include "llvm/Object/Wasm.h" #include "llvm/ObjectYAML/ObjectYAML.h" -#include "llvm/ObjectYAML/yaml2obj.h" #include "llvm/Support/Endian.h" #include "llvm/Support/LEB128.h" using namespace llvm; -namespace { /// This parses a yaml stream that represents a Wasm object file. /// See docs/yaml2obj for the yaml scheema. class WasmWriter { @@ -60,26 +58,6 @@ private: uint32_t NumImportedEvents = 0; }; -class SubSectionWriter { - raw_ostream &OS; - std::string OutString; - raw_string_ostream StringStream; - -public: - SubSectionWriter(raw_ostream &OS) : OS(OS), StringStream(OutString) {} - - void done() { - StringStream.flush(); - encodeULEB128(OutString.size(), OS); - OS << OutString; - OutString.clear(); - } - - raw_ostream &getStream() { return StringStream; } -}; - -} // end anonymous namespace - static int writeUint64(raw_ostream &OS, uint64_t Value) { char Data[sizeof(Value)]; support::endian::write64le(Data, Value); @@ -141,6 +119,24 @@ static int writeInitExpr(const wasm::WasmInitExpr &InitExpr, raw_ostream &OS) { return 0; } +class SubSectionWriter { + raw_ostream &OS; + std::string OutString; + raw_string_ostream StringStream; + +public: + SubSectionWriter(raw_ostream &OS) : OS(OS), StringStream(OutString) {} + + void done() { + StringStream.flush(); + encodeULEB128(OutString.size(), OS); + OS << OutString; + OutString.clear(); + } + + raw_ostream &getStream() { return StringStream; } +}; + int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::DylinkSection &Section) { writeStringRef(Section.Name, OS); @@ -655,14 +651,8 @@ int WasmWriter::writeWasm(raw_ostream &OS) { return 0; } -namespace llvm { -namespace yaml { - -int yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out) { +int yaml2wasm(llvm::WasmYAML::Object &Doc, raw_ostream &Out) { WasmWriter Writer(Doc); return Writer.writeWasm(Out); } - -} // namespace yaml -} // namespace llvm diff --git a/llvm/unittests/ObjectYAML/CMakeLists.txt b/llvm/unittests/ObjectYAML/CMakeLists.txt index 45e9c67..7fcc974 100644 --- a/llvm/unittests/ObjectYAML/CMakeLists.txt +++ b/llvm/unittests/ObjectYAML/CMakeLists.txt @@ -5,7 +5,6 @@ set(LLVM_LINK_COMPONENTS add_llvm_unittest(ObjectYAMLTests MinidumpYAMLTest.cpp - YAML2ObjTest.cpp YAMLTest.cpp ) diff --git a/llvm/unittests/ObjectYAML/YAML2ObjTest.cpp b/llvm/unittests/ObjectYAML/YAML2ObjTest.cpp deleted file mode 100644 index 0a38388..0000000 --- a/llvm/unittests/ObjectYAML/YAML2ObjTest.cpp +++ /dev/null @@ -1,36 +0,0 @@ -//===- YAML2ObjTest.cpp --------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/ObjectYAML/yaml2obj.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/Support/Error.h" -#include "llvm/Testing/Support/Error.h" -#include "gtest/gtest.h" - -using namespace llvm; -using namespace object; -using namespace yaml; - -TEST(yaml2ObjectFile, ELF) { - SmallString<0> Storage; - Expected> ErrOrObj = yaml2ObjectFile(Storage, R"( ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64)"); - - ASSERT_THAT_EXPECTED(ErrOrObj, Succeeded()); - - std::unique_ptr ObjFile = std::move(ErrOrObj.get()); - - ASSERT_TRUE(ObjFile->isELF()); - ASSERT_TRUE(ObjFile->isRelocatableObject()); -} -- 2.7.4