diff --git a/include/llvm/ObjectYAML/yaml2obj.h b/include/llvm/ObjectYAML/yaml2obj.h index 54c39ef055d..386551337d8 100644 --- a/include/llvm/ObjectYAML/yaml2obj.h +++ b/include/llvm/ObjectYAML/yaml2obj.h @@ -44,17 +44,22 @@ namespace yaml { class Input; struct YamlObjectFile; -bool yaml2coff(COFFYAML::Object &Doc, raw_ostream &Out); -bool yaml2elf(ELFYAML::Object &Doc, raw_ostream &Out); -bool yaml2macho(YamlObjectFile &Doc, raw_ostream &Out); -bool yaml2minidump(MinidumpYAML::Object &Doc, raw_ostream &Out); -bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out); +using ErrorHandler = llvm::function_ref; -Error convertYAML(Input &YIn, raw_ostream &Out, unsigned DocNum = 1); +bool yaml2coff(COFFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH); +bool yaml2elf(ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH); +bool yaml2macho(YamlObjectFile &Doc, raw_ostream &Out, ErrorHandler EH); +bool yaml2minidump(MinidumpYAML::Object &Doc, raw_ostream &Out, + ErrorHandler EH); +bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH); + +bool convertYAML(Input &YIn, raw_ostream &Out, ErrorHandler ErrHandler, + unsigned DocNum = 1); /// Convenience function for tests. -Expected> -yaml2ObjectFile(SmallVectorImpl &Storage, StringRef Yaml); +std::unique_ptr +yaml2ObjectFile(SmallVectorImpl &Storage, StringRef Yaml, + ErrorHandler ErrHandler); } // namespace yaml } // namespace llvm diff --git a/lib/ObjectYAML/COFFEmitter.cpp b/lib/ObjectYAML/COFFEmitter.cpp index daa4f6d83db..efcdc51e167 100644 --- a/lib/ObjectYAML/COFFEmitter.cpp +++ b/lib/ObjectYAML/COFFEmitter.cpp @@ -34,8 +34,8 @@ namespace { /// This parses a yaml stream that represents a COFF object file. /// See docs/yaml2obj for the yaml scheema. struct COFFParser { - COFFParser(COFFYAML::Object &Obj) - : Obj(Obj), SectionTableStart(0), SectionTableSize(0) { + COFFParser(COFFYAML::Object &Obj, yaml::ErrorHandler EH) + : Obj(Obj), SectionTableStart(0), SectionTableSize(0), ErrHandler(EH) { // A COFF string table always starts with a 4 byte size field. Offsets into // it include this size, so allocate it now. StringTable.append(4, char(0)); @@ -81,7 +81,7 @@ struct COFFParser { unsigned Index = getStringIndex(Name); std::string str = utostr(Index); if (str.size() > 7) { - errs() << "String table got too large\n"; + ErrHandler("string table got too large"); return false; } Sec.Header.Name[0] = '/'; @@ -90,11 +90,11 @@ struct COFFParser { if (Sec.Alignment) { if (Sec.Alignment > 8192) { - errs() << "Section alignment is too large\n"; + ErrHandler("section alignment is too large"); return false; } if (!isPowerOf2_32(Sec.Alignment)) { - errs() << "Section alignment is not a power of 2\n"; + ErrHandler("section alignment is not a power of 2"); return false; } Sec.Header.Characteristics |= (Log2_32(Sec.Alignment) + 1) << 20; @@ -155,6 +155,8 @@ struct COFFParser { std::string StringTable; uint32_t SectionTableStart; uint32_t SectionTableSize; + + yaml::ErrorHandler ErrHandler; }; enum { DOSStubSize = 128 }; @@ -592,24 +594,25 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { namespace llvm { namespace yaml { -bool yaml2coff(llvm::COFFYAML::Object &Doc, raw_ostream &Out) { - COFFParser CP(Doc); +bool yaml2coff(llvm::COFFYAML::Object &Doc, raw_ostream &Out, + ErrorHandler ErrHandler) { + COFFParser CP(Doc, ErrHandler); if (!CP.parse()) { - errs() << "yaml2obj: Failed to parse YAML file!\n"; + ErrHandler("failed to parse YAML file"); return false; } if (!layoutOptionalHeader(CP)) { - errs() << "yaml2obj: Failed to layout optional header for COFF file!\n"; + ErrHandler("failed to layout optional header for COFF file"); return false; } if (!layoutCOFF(CP)) { - errs() << "yaml2obj: Failed to layout COFF file!\n"; + ErrHandler("failed to layout COFF file"); return false; } if (!writeCOFF(CP, Out)) { - errs() << "yaml2obj: Failed to write COFF file!\n"; + ErrHandler("failed to write COFF file"); return false; } return true; diff --git a/lib/ObjectYAML/ELFEmitter.cpp b/lib/ObjectYAML/ELFEmitter.cpp index 6c64754f49b..4584e3d73bd 100644 --- a/lib/ObjectYAML/ELFEmitter.cpp +++ b/lib/ObjectYAML/ELFEmitter.cpp @@ -115,12 +115,13 @@ template class ELFState { ELFYAML::Object &Doc; bool HasError = false; + yaml::ErrorHandler ErrHandler; + void reportError(const Twine &Msg); std::vector toELFSymbols(ArrayRef Symbols, const StringTableBuilder &Strtab); unsigned toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym = ""); unsigned toSymbolIndex(StringRef S, StringRef LocSec, bool IsDynamic); - void reportError(const Twine &Msg); void buildSectionIndex(); void buildSymbolIndexes(); @@ -166,9 +167,11 @@ template class ELFState { void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::DynamicSection &Section, ContiguousBlobAccumulator &CBA); - ELFState(ELFYAML::Object &D); + ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH); + public: - static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc); + static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc, + yaml::ErrorHandler EH); }; } // end anonymous namespace @@ -182,7 +185,9 @@ template static void writeArrayData(raw_ostream &OS, ArrayRef 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, yaml::ErrorHandler EH) + : Doc(D), ErrHandler(EH) { StringSet<> DocSections; for (std::unique_ptr &D : Doc.Sections) if (!D->Name.empty()) @@ -592,7 +597,7 @@ void ELFState::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, } template void ELFState::reportError(const Twine &Msg) { - WithColor::error() << Msg << "\n"; + ErrHandler(Msg); HasError = true; } @@ -983,8 +988,9 @@ template void ELFState::finalizeStrings() { } template -bool ELFState::writeELF(raw_ostream &OS, ELFYAML::Object &Doc) { - ELFState State(Doc); +bool ELFState::writeELF(raw_ostream &OS, ELFYAML::Object &Doc, + yaml::ErrorHandler EH) { + ELFState State(Doc, EH); // Finalize .strtab and .dynstr sections. We do that early because want to // finalize the string table builders before writing the content of the @@ -1022,17 +1028,17 @@ bool ELFState::writeELF(raw_ostream &OS, ELFYAML::Object &Doc) { namespace llvm { namespace yaml { -bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out) { +bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH) { bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64); if (Is64Bit) { if (IsLE) - return ELFState::writeELF(Out, Doc); - return ELFState::writeELF(Out, Doc); + return ELFState::writeELF(Out, Doc, EH); + return ELFState::writeELF(Out, Doc, EH); } if (IsLE) - return ELFState::writeELF(Out, Doc); - return ELFState::writeELF(Out, Doc); + return ELFState::writeELF(Out, Doc, EH); + return ELFState::writeELF(Out, Doc, EH); } } // namespace yaml diff --git a/lib/ObjectYAML/MachOEmitter.cpp b/lib/ObjectYAML/MachOEmitter.cpp index 621b9b2617d..b56f811ce67 100644 --- a/lib/ObjectYAML/MachOEmitter.cpp +++ b/lib/ObjectYAML/MachOEmitter.cpp @@ -15,7 +15,6 @@ #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" #include "llvm/Support/raw_ostream.h" @@ -34,24 +33,24 @@ public: memset(reinterpret_cast(&Header), 0, sizeof(MachO::mach_header_64)); } - Error writeMachO(raw_ostream &OS); + void writeMachO(raw_ostream &OS); private: - Error writeHeader(raw_ostream &OS); - Error writeLoadCommands(raw_ostream &OS); - Error writeSectionData(raw_ostream &OS); - Error writeLinkEditData(raw_ostream &OS); + void writeHeader(raw_ostream &OS); + void writeLoadCommands(raw_ostream &OS); + void writeSectionData(raw_ostream &OS); + void writeLinkEditData(raw_ostream &OS); void writeBindOpcodes(raw_ostream &OS, std::vector &BindOpcodes); // LinkEdit writers - Error writeRebaseOpcodes(raw_ostream &OS); - Error writeBasicBindOpcodes(raw_ostream &OS); - Error writeWeakBindOpcodes(raw_ostream &OS); - Error writeLazyBindOpcodes(raw_ostream &OS); - Error writeNameList(raw_ostream &OS); - Error writeStringTable(raw_ostream &OS); - Error writeExportTrie(raw_ostream &OS); + void writeRebaseOpcodes(raw_ostream &OS); + void writeBasicBindOpcodes(raw_ostream &OS); + void writeWeakBindOpcodes(raw_ostream &OS); + void writeLazyBindOpcodes(raw_ostream &OS); + void writeNameList(raw_ostream &OS); + void writeStringTable(raw_ostream &OS); + void writeExportTrie(raw_ostream &OS); void dumpExportEntry(raw_ostream &OS, MachOYAML::ExportEntry &Entry); void ZeroToOffset(raw_ostream &OS, size_t offset); @@ -63,18 +62,14 @@ private: MachO::mach_header_64 Header; }; -Error MachOWriter::writeMachO(raw_ostream &OS) { +void MachOWriter::writeMachO(raw_ostream &OS) { fileStart = OS.tell(); - if (auto Err = writeHeader(OS)) - return Err; - if (auto Err = writeLoadCommands(OS)) - return Err; - if (auto Err = writeSectionData(OS)) - return Err; - return Error::success(); + writeHeader(OS); + writeLoadCommands(OS); + writeSectionData(OS); } -Error MachOWriter::writeHeader(raw_ostream &OS) { +void MachOWriter::writeHeader(raw_ostream &OS) { Header.magic = Obj.Header.magic; Header.cputype = Obj.Header.cputype; Header.cpusubtype = Obj.Header.cpusubtype; @@ -90,8 +85,6 @@ Error MachOWriter::writeHeader(raw_ostream &OS) { auto header_size = is64Bit ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header); OS.write((const char *)&Header, header_size); - - return Error::success(); } template @@ -212,7 +205,7 @@ void MachOWriter::ZeroToOffset(raw_ostream &OS, size_t Offset) { ZeroFillBytes(OS, Offset - currOffset); } -Error MachOWriter::writeLoadCommands(raw_ostream &OS) { +void MachOWriter::writeLoadCommands(raw_ostream &OS) { for (auto &LC : Obj.LoadCommands) { size_t BytesWritten = 0; llvm::MachO::macho_load_command Data = LC.Data; @@ -259,10 +252,9 @@ Error MachOWriter::writeLoadCommands(raw_ostream &OS) { ZeroFillBytes(OS, BytesRemaining); } } - return Error::success(); } -Error MachOWriter::writeSectionData(raw_ostream &OS) { +void MachOWriter::writeSectionData(raw_ostream &OS) { bool FoundLinkEditSeg = false; for (auto &LC : Obj.LoadCommands) { switch (LC.Data.load_command_data.cmd) { @@ -273,8 +265,7 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) { if (0 == strncmp(&LC.Data.segment_command_data.segname[0], "__LINKEDIT", 16)) { FoundLinkEditSeg = true; - if (auto Err = writeLinkEditData(OS)) - return Err; + writeLinkEditData(OS); } for (auto &Sec : LC.Sections) { ZeroToOffset(OS, Sec.offset); @@ -326,11 +317,8 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) { } // Old PPC Object Files didn't have __LINKEDIT segments, the data was just // stuck at the end of the file. - if (!FoundLinkEditSeg) { - if (auto Err = writeLinkEditData(OS)) - return Err; - } - return Error::success(); + if (!FoundLinkEditSeg) + writeLinkEditData(OS); } void MachOWriter::writeBindOpcodes( @@ -377,9 +365,8 @@ void MachOWriter::dumpExportEntry(raw_ostream &OS, dumpExportEntry(OS, EE); } -Error MachOWriter::writeExportTrie(raw_ostream &OS) { +void MachOWriter::writeExportTrie(raw_ostream &OS) { dumpExportEntry(OS, Obj.LinkEdit.ExportTrie); - return Error::success(); } template @@ -397,8 +384,8 @@ void writeNListEntry(MachOYAML::NListEntry &NLE, raw_ostream &OS, OS.write(reinterpret_cast(&ListEntry), sizeof(NListType)); } -Error MachOWriter::writeLinkEditData(raw_ostream &OS) { - typedef Error (MachOWriter::*writeHandler)(raw_ostream &); +void MachOWriter::writeLinkEditData(raw_ostream &OS) { + typedef void (MachOWriter::*writeHandler)(raw_ostream &); typedef std::pair writeOperation; std::vector WriteQueue; @@ -435,57 +422,47 @@ Error MachOWriter::writeLinkEditData(raw_ostream &OS) { for (auto writeOp : WriteQueue) { ZeroToOffset(OS, writeOp.first); - if (auto Err = (this->*writeOp.second)(OS)) - return Err; + (this->*writeOp.second)(OS); } - - return Error::success(); } -Error MachOWriter::writeRebaseOpcodes(raw_ostream &OS) { +void MachOWriter::writeRebaseOpcodes(raw_ostream &OS) { MachOYAML::LinkEditData &LinkEdit = Obj.LinkEdit; for (auto Opcode : LinkEdit.RebaseOpcodes) { uint8_t OpByte = Opcode.Opcode | Opcode.Imm; OS.write(reinterpret_cast(&OpByte), 1); - for (auto Data : Opcode.ExtraData) { + for (auto Data : Opcode.ExtraData) encodeULEB128(Data, OS); - } } - return Error::success(); } -Error MachOWriter::writeBasicBindOpcodes(raw_ostream &OS) { +void MachOWriter::writeBasicBindOpcodes(raw_ostream &OS) { writeBindOpcodes(OS, Obj.LinkEdit.BindOpcodes); - return Error::success(); } -Error MachOWriter::writeWeakBindOpcodes(raw_ostream &OS) { +void MachOWriter::writeWeakBindOpcodes(raw_ostream &OS) { writeBindOpcodes(OS, Obj.LinkEdit.WeakBindOpcodes); - return Error::success(); } -Error MachOWriter::writeLazyBindOpcodes(raw_ostream &OS) { +void MachOWriter::writeLazyBindOpcodes(raw_ostream &OS) { writeBindOpcodes(OS, Obj.LinkEdit.LazyBindOpcodes); - return Error::success(); } -Error MachOWriter::writeNameList(raw_ostream &OS) { +void MachOWriter::writeNameList(raw_ostream &OS) { for (auto NLE : Obj.LinkEdit.NameList) { if (is64Bit) writeNListEntry(NLE, OS, Obj.IsLittleEndian); else writeNListEntry(NLE, OS, Obj.IsLittleEndian); } - return Error::success(); } -Error MachOWriter::writeStringTable(raw_ostream &OS) { +void MachOWriter::writeStringTable(raw_ostream &OS) { for (auto Str : Obj.LinkEdit.StringTable) { OS.write(Str.data(), Str.size()); OS.write('\0'); } - return Error::success(); } class UniversalWriter { @@ -493,11 +470,11 @@ public: UniversalWriter(yaml::YamlObjectFile &ObjectFile) : ObjectFile(ObjectFile), fileStart(0) {} - Error writeMachO(raw_ostream &OS); + void writeMachO(raw_ostream &OS); private: - Error writeFatHeader(raw_ostream &OS); - Error writeFatArchs(raw_ostream &OS); + void writeFatHeader(raw_ostream &OS); + void writeFatArchs(raw_ostream &OS); void ZeroToOffset(raw_ostream &OS, size_t offset); @@ -505,30 +482,30 @@ private: uint64_t fileStart; }; -Error UniversalWriter::writeMachO(raw_ostream &OS) { +void UniversalWriter::writeMachO(raw_ostream &OS) { fileStart = OS.tell(); if (ObjectFile.MachO) { MachOWriter Writer(*ObjectFile.MachO); - return Writer.writeMachO(OS); + Writer.writeMachO(OS); + return; } - if (auto Err = writeFatHeader(OS)) - return Err; - if (auto Err = writeFatArchs(OS)) - return Err; + + writeFatHeader(OS); + writeFatArchs(OS); + auto &FatFile = *ObjectFile.FatMachO; assert(FatFile.FatArchs.size() == FatFile.Slices.size()); for (size_t i = 0; i < FatFile.Slices.size(); i++) { ZeroToOffset(OS, FatFile.FatArchs[i].offset); MachOWriter Writer(FatFile.Slices[i]); - if (auto Err = Writer.writeMachO(OS)) - return Err; + Writer.writeMachO(OS); + auto SliceEnd = FatFile.FatArchs[i].offset + FatFile.FatArchs[i].size; ZeroToOffset(OS, SliceEnd); } - return Error::success(); } -Error UniversalWriter::writeFatHeader(raw_ostream &OS) { +void UniversalWriter::writeFatHeader(raw_ostream &OS) { auto &FatFile = *ObjectFile.FatMachO; MachO::fat_header header; header.magic = FatFile.Header.magic; @@ -536,7 +513,6 @@ Error UniversalWriter::writeFatHeader(raw_ostream &OS) { if (sys::IsLittleEndianHost) swapStruct(header); OS.write(reinterpret_cast(&header), sizeof(MachO::fat_header)); - return Error::success(); } template @@ -572,7 +548,7 @@ void writeFatArch(MachOYAML::FatArch &Arch, sizeof(MachO::fat_arch_64)); } -Error UniversalWriter::writeFatArchs(raw_ostream &OS) { +void UniversalWriter::writeFatArchs(raw_ostream &OS) { auto &FatFile = *ObjectFile.FatMachO; bool is64Bit = FatFile.Header.magic == MachO::FAT_MAGIC_64; for (auto Arch : FatFile.FatArchs) { @@ -581,8 +557,6 @@ Error UniversalWriter::writeFatArchs(raw_ostream &OS) { else writeFatArch(Arch, OS); } - - return Error::success(); } void UniversalWriter::ZeroToOffset(raw_ostream &OS, size_t Offset) { @@ -596,12 +570,9 @@ void UniversalWriter::ZeroToOffset(raw_ostream &OS, size_t Offset) { namespace llvm { namespace yaml { -bool yaml2macho(YamlObjectFile &Doc, raw_ostream &Out) { +bool yaml2macho(YamlObjectFile &Doc, raw_ostream &Out, ErrorHandler /*EH*/) { UniversalWriter Writer(Doc); - if (auto Err = Writer.writeMachO(Out)) { - errs() << toString(std::move(Err)); - return false; - } + Writer.writeMachO(Out); return true; } diff --git a/lib/ObjectYAML/MinidumpEmitter.cpp b/lib/ObjectYAML/MinidumpEmitter.cpp index cc28f96a44a..31a839e524c 100644 --- a/lib/ObjectYAML/MinidumpEmitter.cpp +++ b/lib/ObjectYAML/MinidumpEmitter.cpp @@ -198,7 +198,8 @@ static Directory layout(BlobAllocator &File, Stream &S) { namespace llvm { namespace yaml { -bool yaml2minidump(MinidumpYAML::Object &Obj, raw_ostream &Out) { +bool yaml2minidump(MinidumpYAML::Object &Obj, raw_ostream &Out, + ErrorHandler /*EH*/) { BlobAllocator File; File.allocateObject(Obj.Header); diff --git a/lib/ObjectYAML/WasmEmitter.cpp b/lib/ObjectYAML/WasmEmitter.cpp index 28d469ccb97..e374764bf13 100644 --- a/lib/ObjectYAML/WasmEmitter.cpp +++ b/lib/ObjectYAML/WasmEmitter.cpp @@ -25,39 +25,46 @@ namespace { /// See docs/yaml2obj for the yaml scheema. class WasmWriter { public: - WasmWriter(WasmYAML::Object &Obj) : Obj(Obj) {} + WasmWriter(WasmYAML::Object &Obj, yaml::ErrorHandler EH) + : Obj(Obj), ErrHandler(EH) {} bool writeWasm(raw_ostream &OS); private: - int writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec, - uint32_t SectionIndex); + void writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec, + uint32_t SectionIndex); - int writeSectionContent(raw_ostream &OS, WasmYAML::CustomSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::TypeSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::ImportSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::FunctionSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::TableSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::MemorySection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::GlobalSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::EventSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::ExportSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::StartSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::ElemSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::CodeSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::DataSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::DataCountSection &Section); + void writeInitExpr(raw_ostream &OS, const wasm::WasmInitExpr &InitExpr); + + void writeSectionContent(raw_ostream &OS, WasmYAML::CustomSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::TypeSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::ImportSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::FunctionSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::TableSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::MemorySection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::GlobalSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::EventSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::ExportSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::StartSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::ElemSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::CodeSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::DataSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::DataCountSection &Section); // Custom section types - int writeSectionContent(raw_ostream &OS, WasmYAML::DylinkSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section); - int writeSectionContent(raw_ostream &OS, WasmYAML::ProducersSection &Section); - int writeSectionContent(raw_ostream &OS, + void writeSectionContent(raw_ostream &OS, WasmYAML::DylinkSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::ProducersSection &Section); + void writeSectionContent(raw_ostream &OS, WasmYAML::TargetFeaturesSection &Section); WasmYAML::Object &Obj; uint32_t NumImportedFunctions = 0; uint32_t NumImportedGlobals = 0; uint32_t NumImportedEvents = 0; + + bool HasError = false; + yaml::ErrorHandler ErrHandler; + void reportError(const Twine &Msg); }; class SubSectionWriter { @@ -115,7 +122,13 @@ static int writeLimits(const WasmYAML::Limits &Lim, raw_ostream &OS) { return 0; } -static int writeInitExpr(const wasm::WasmInitExpr &InitExpr, raw_ostream &OS) { +void WasmWriter::reportError(const Twine &Msg) { + ErrHandler(Msg); + HasError = true; +} + +void WasmWriter::writeInitExpr(raw_ostream &OS, + const wasm::WasmInitExpr &InitExpr) { writeUint8(OS, InitExpr.Opcode); switch (InitExpr.Opcode) { case wasm::WASM_OPCODE_I32_CONST: @@ -134,29 +147,26 @@ static int writeInitExpr(const wasm::WasmInitExpr &InitExpr, raw_ostream &OS) { encodeULEB128(InitExpr.Value.Global, OS); break; default: - errs() << "Unknown opcode in init_expr: " << InitExpr.Opcode << "\n"; - return 1; + reportError("unknown opcode in init_expr: " + Twine(InitExpr.Opcode)); + return; } writeUint8(OS, wasm::WASM_OPCODE_END); - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::DylinkSection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::DylinkSection &Section) { writeStringRef(Section.Name, OS); encodeULEB128(Section.MemorySize, OS); encodeULEB128(Section.MemoryAlignment, OS); encodeULEB128(Section.TableSize, OS); encodeULEB128(Section.TableAlignment, OS); encodeULEB128(Section.Needed.size(), OS); - for (StringRef Needed : Section.Needed) { + for (StringRef Needed : Section.Needed) writeStringRef(Needed, OS); - } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::LinkingSection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::LinkingSection &Section) { writeStringRef(Section.Name, OS); encodeULEB128(Section.Version, OS); @@ -240,12 +250,10 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, } SubSection.done(); } - - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::NameSection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::NameSection &Section) { writeStringRef(Section.Name, OS); if (Section.FunctionNames.size()) { writeUint8(OS, wasm::WASM_NAMES_FUNCTION); @@ -260,16 +268,15 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, SubSection.done(); } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::ProducersSection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::ProducersSection &Section) { writeStringRef(Section.Name, OS); int Fields = int(!Section.Languages.empty()) + int(!Section.Tools.empty()) + int(!Section.SDKs.empty()); if (Fields == 0) - return 0; + return; encodeULEB128(Fields, OS); for (auto &Field : {std::make_pair(StringRef("language"), &Section.Languages), std::make_pair(StringRef("processed-by"), &Section.Tools), @@ -283,52 +290,44 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, writeStringRef(Entry.Version, OS); } } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::TargetFeaturesSection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::TargetFeaturesSection &Section) { writeStringRef(Section.Name, OS); encodeULEB128(Section.Features.size(), OS); for (auto &E : Section.Features) { writeUint8(OS, E.Prefix); writeStringRef(E.Name, OS); } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::CustomSection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::CustomSection &Section) { if (auto S = dyn_cast(&Section)) { - if (auto Err = writeSectionContent(OS, *S)) - return Err; + writeSectionContent(OS, *S); } else if (auto S = dyn_cast(&Section)) { - if (auto Err = writeSectionContent(OS, *S)) - return Err; + writeSectionContent(OS, *S); } else if (auto S = dyn_cast(&Section)) { - if (auto Err = writeSectionContent(OS, *S)) - return Err; + writeSectionContent(OS, *S); } else if (auto S = dyn_cast(&Section)) { - if (auto Err = writeSectionContent(OS, *S)) - return Err; + writeSectionContent(OS, *S); } else if (auto S = dyn_cast(&Section)) { - if (auto Err = writeSectionContent(OS, *S)) - return Err; + writeSectionContent(OS, *S); } else { writeStringRef(Section.Name, OS); Section.Payload.writeAsBinary(OS); } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, +void WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::TypeSection &Section) { encodeULEB128(Section.Signatures.size(), OS); uint32_t ExpectedIndex = 0; for (const WasmYAML::Signature &Sig : Section.Signatures) { if (Sig.Index != ExpectedIndex) { - errs() << "Unexpected type index: " << Sig.Index << "\n"; - return 1; + reportError("unexpected type index: " + Twine(Sig.Index)); + return; } ++ExpectedIndex; writeUint8(OS, Sig.Form); @@ -342,10 +341,9 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, writeUint8(OS, Sig.ReturnType); } } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, +void WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::ImportSection &Section) { encodeULEB128(Section.Imports.size(), OS); for (const WasmYAML::Import &Import : Section.Imports) { @@ -375,23 +373,20 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, writeLimits(Import.TableImport.TableLimits, OS); break; default: - errs() << "Unknown import type: " << Import.Kind << "\n"; - return 1; + reportError("unknown import type: " +Twine(Import.Kind)); + return; } } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::FunctionSection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::FunctionSection &Section) { encodeULEB128(Section.FunctionTypes.size(), OS); - for (uint32_t FuncType : Section.FunctionTypes) { + for (uint32_t FuncType : Section.FunctionTypes) encodeULEB128(FuncType, OS); - } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, +void WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::ExportSection &Section) { encodeULEB128(Section.Exports.size(), OS); for (const WasmYAML::Export &Export : Section.Exports) { @@ -399,83 +394,74 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, writeUint8(OS, Export.Kind); encodeULEB128(Export.Index, OS); } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::StartSection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::StartSection &Section) { encodeULEB128(Section.StartFunction, OS); - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::TableSection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::TableSection &Section) { encodeULEB128(Section.Tables.size(), OS); for (auto &Table : Section.Tables) { writeUint8(OS, Table.ElemType); writeLimits(Table.TableLimits, OS); } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::MemorySection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::MemorySection &Section) { encodeULEB128(Section.Memories.size(), OS); - for (const WasmYAML::Limits &Mem : Section.Memories) { + for (const WasmYAML::Limits &Mem : Section.Memories) writeLimits(Mem, OS); - } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::GlobalSection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::GlobalSection &Section) { encodeULEB128(Section.Globals.size(), OS); uint32_t ExpectedIndex = NumImportedGlobals; for (auto &Global : Section.Globals) { if (Global.Index != ExpectedIndex) { - errs() << "Unexpected global index: " << Global.Index << "\n"; - return 1; + reportError("unexpected global index: " + Twine(Global.Index)); + return; } ++ExpectedIndex; writeUint8(OS, Global.Type); writeUint8(OS, Global.Mutable); - writeInitExpr(Global.InitExpr, OS); + writeInitExpr(OS, Global.InitExpr); } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, +void WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::EventSection &Section) { encodeULEB128(Section.Events.size(), OS); uint32_t ExpectedIndex = NumImportedEvents; for (auto &Event : Section.Events) { if (Event.Index != ExpectedIndex) { - errs() << "Unexpected event index: " << Event.Index << "\n"; - return 1; + reportError("unexpected event index: " + Twine(Event.Index)); + return; } ++ExpectedIndex; encodeULEB128(Event.Attribute, OS); encodeULEB128(Event.SigIndex, OS); } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::ElemSection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::ElemSection &Section) { encodeULEB128(Section.Segments.size(), OS); for (auto &Segment : Section.Segments) { encodeULEB128(Segment.TableIndex, OS); - writeInitExpr(Segment.Offset, OS); + writeInitExpr(OS, Segment.Offset); encodeULEB128(Segment.Functions.size(), OS); - for (auto &Function : Segment.Functions) { + for (auto &Function : Segment.Functions) encodeULEB128(Function, OS); - } } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, +void WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::CodeSection &Section) { encodeULEB128(Section.Functions.size(), OS); uint32_t ExpectedIndex = NumImportedFunctions; @@ -483,8 +469,8 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, std::string OutString; raw_string_ostream StringStream(OutString); if (Func.Index != ExpectedIndex) { - errs() << "Unexpected function index: " << Func.Index << "\n"; - return 1; + reportError("unexpected function index: " + Twine(Func.Index)); + return; } ++ExpectedIndex; @@ -501,31 +487,28 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, encodeULEB128(OutString.size(), OS); OS << OutString; } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::DataSection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::DataSection &Section) { encodeULEB128(Section.Segments.size(), OS); for (auto &Segment : Section.Segments) { encodeULEB128(Segment.InitFlags, OS); if (Segment.InitFlags & wasm::WASM_SEGMENT_HAS_MEMINDEX) encodeULEB128(Segment.MemoryIndex, OS); if ((Segment.InitFlags & wasm::WASM_SEGMENT_IS_PASSIVE) == 0) - writeInitExpr(Segment.Offset, OS); + writeInitExpr(OS, Segment.Offset); encodeULEB128(Segment.Content.binary_size(), OS); Segment.Content.writeAsBinary(OS); } - return 0; } -int WasmWriter::writeSectionContent(raw_ostream &OS, - WasmYAML::DataCountSection &Section) { +void WasmWriter::writeSectionContent(raw_ostream &OS, + WasmYAML::DataCountSection &Section) { encodeULEB128(Section.Count, OS); - return 0; } -int WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec, +void WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec, uint32_t SectionIndex) { switch (Sec.Type) { case wasm::WASM_SEC_CODE: @@ -541,7 +524,6 @@ int WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec, } default: llvm_unreachable("not yet implemented"); - return 1; } encodeULEB128(SectionIndex, OS); @@ -560,7 +542,6 @@ int WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec, encodeULEB128(Reloc.Addend, OS); } } - return 0; } bool WasmWriter::writeWasm(raw_ostream &OS) { @@ -575,58 +556,46 @@ bool WasmWriter::writeWasm(raw_ostream &OS) { if (auto S = dyn_cast(Sec.get())) SecName = S->Name; if (!Checker.isValidSectionOrder(Sec->Type, SecName)) { - errs() << "Out of order section type: " << Sec->Type << "\n"; + reportError("out of order section type: " + Twine(Sec->Type)); return false; } encodeULEB128(Sec->Type, OS); std::string OutString; raw_string_ostream StringStream(OutString); - if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else if (auto S = dyn_cast(Sec.get())) { - if (auto Err = writeSectionContent(StringStream, *S)) - return Err; - } else { - errs() << "Unknown section type: " << Sec->Type << "\n"; + if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else if (auto S = dyn_cast(Sec.get())) + writeSectionContent(StringStream, *S); + else + reportError("unknown section type: " + Twine(Sec->Type)); + + if (HasError) return false; - } + StringStream.flush(); // Write the section size followed by the content @@ -658,8 +627,8 @@ bool WasmWriter::writeWasm(raw_ostream &OS) { namespace llvm { namespace yaml { -bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out) { - WasmWriter Writer(Doc); +bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH) { + WasmWriter Writer(Doc, EH); return Writer.writeWasm(Out); } diff --git a/lib/ObjectYAML/yaml2obj.cpp b/lib/ObjectYAML/yaml2obj.cpp index 8ca490bf9ca..c18fa5cfdb5 100644 --- a/lib/ObjectYAML/yaml2obj.cpp +++ b/lib/ObjectYAML/yaml2obj.cpp @@ -8,59 +8,69 @@ #include "llvm/ObjectYAML/yaml2obj.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Twine.h" #include "llvm/Object/ObjectFile.h" #include "llvm/ObjectYAML/ObjectYAML.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/WithColor.h" #include "llvm/Support/YAMLTraits.h" namespace llvm { namespace yaml { -Error convertYAML(yaml::Input &YIn, raw_ostream &Out, unsigned DocNum) { - auto BoolToErr = [](bool Ret) -> Error { - if (!Ret) - return createStringError(errc::invalid_argument, "yaml2obj failed"); - return Error::success(); - }; - +bool convertYAML(yaml::Input &YIn, raw_ostream &Out, ErrorHandler ErrHandler, + unsigned DocNum) { 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 BoolToErr(yaml2elf(*Doc.Elf, Out)); - if (Doc.Coff) - return BoolToErr(yaml2coff(*Doc.Coff, Out)); - if (Doc.MachO || Doc.FatMachO) - return BoolToErr(yaml2macho(Doc, Out)); - if (Doc.Minidump) - return BoolToErr(yaml2minidump(*Doc.Minidump, Out)); - if (Doc.Wasm) - return BoolToErr(yaml2wasm(*Doc.Wasm, Out)); - return createStringError(errc::invalid_argument, - "Unknown document type!"); + if (++CurDocNum != DocNum) + continue; + + yaml::YamlObjectFile Doc; + YIn >> Doc; + if (std::error_code EC = YIn.error()) { + ErrHandler("failed to parse YAML input: " + EC.message()); + return false; } + + if (Doc.Elf) + return yaml2elf(*Doc.Elf, Out, ErrHandler); + if (Doc.Coff) + return yaml2coff(*Doc.Coff, Out, ErrHandler); + if (Doc.MachO || Doc.FatMachO) + return yaml2macho(Doc, Out, ErrHandler); + if (Doc.Minidump) + return yaml2minidump(*Doc.Minidump, Out, ErrHandler); + if (Doc.Wasm) + return yaml2wasm(*Doc.Wasm, Out, ErrHandler); + + ErrHandler("unknown document type"); + return false; + } while (YIn.nextDocument()); - return createStringError(errc::invalid_argument, - "Cannot find the %u%s document", DocNum, - getOrdinalSuffix(DocNum).data()); + ErrHandler("cannot find the " + Twine(DocNum) + + getOrdinalSuffix(DocNum).data() + " document"); + return false; } -Expected> -yaml2ObjectFile(SmallVectorImpl &Storage, StringRef Yaml) { +std::unique_ptr +yaml2ObjectFile(SmallVectorImpl &Storage, StringRef Yaml, + ErrorHandler ErrHandler) { Storage.clear(); raw_svector_ostream OS(Storage); yaml::Input YIn(Yaml); - if (Error E = convertYAML(YIn, OS)) - return std::move(E); + if (!convertYAML(YIn, OS, ErrHandler)) + return {}; - return object::ObjectFile::createObjectFile( - MemoryBufferRef(OS.str(), "YamlObject")); + Expected> ObjOrErr = + object::ObjectFile::createObjectFile( + MemoryBufferRef(OS.str(), "YamlObject")); + if (ObjOrErr) + return std::move(*ObjOrErr); + + ErrHandler(toString(ObjOrErr.takeError())); + return {}; } } // namespace yaml diff --git a/test/ObjectYAML/wasm/invalid_section_order.yaml b/test/ObjectYAML/wasm/invalid_section_order.yaml index 52ad1361962..4e3581ec5eb 100644 --- a/test/ObjectYAML/wasm/invalid_section_order.yaml +++ b/test/ObjectYAML/wasm/invalid_section_order.yaml @@ -14,7 +14,7 @@ Sections: - Index: 0 Locals: [] Body: 0B - # CHECK: Out of order section type: 3 + # CHECK: yaml2obj: error: out of order section type: 3 - Type: FUNCTION FunctionTypes: [ 0 ] ... diff --git a/test/tools/yaml2obj/coff-invalid-alignment.test b/test/tools/yaml2obj/coff-invalid-alignment.test index fd9e0b04f27..3a3d8a84ad1 100644 --- a/test/tools/yaml2obj/coff-invalid-alignment.test +++ b/test/tools/yaml2obj/coff-invalid-alignment.test @@ -1,6 +1,6 @@ # RUN: not yaml2obj %s 2>&1 | FileCheck %s -## CHECK: Section alignment is too large +## CHECK: error: section alignment is too large --- !COFF header: diff --git a/test/tools/yaml2obj/dynsymtab-implicit-sections-size-content.yaml b/test/tools/yaml2obj/dynsymtab-implicit-sections-size-content.yaml index 948d3250556..bd3d1629534 100644 --- a/test/tools/yaml2obj/dynsymtab-implicit-sections-size-content.yaml +++ b/test/tools/yaml2obj/dynsymtab-implicit-sections-size-content.yaml @@ -31,8 +31,7 @@ DynamicSymbols: # RUN: not yaml2obj --docnum=2 %s 2>&1 | FileCheck %s --implicit-check-not=error --check-prefix=CASE2 -# CASE2: error: cannot specify both `Size` and `DynamicSymbols` for symbol table section '.dynsym' -# CASE2: error: yaml2obj failed +# CASE2: yaml2obj: error: cannot specify both `Size` and `DynamicSymbols` for symbol table section '.dynsym' --- !ELF FileHeader: @@ -55,8 +54,7 @@ DynamicSymbols: # RUN: not yaml2obj --docnum=3 %s 2>&1 | FileCheck %s --implicit-check-not=error --check-prefix=CASE3 -# CASE3: error: cannot specify both `Content` and `DynamicSymbols` for symbol table section '.dynsym' -# CASE3: error: yaml2obj failed +# CASE3: yaml2obj: error: cannot specify both `Content` and `DynamicSymbols` for symbol table section '.dynsym' --- !ELF FileHeader: diff --git a/test/tools/yaml2obj/empty-or-invalid-doc.yaml b/test/tools/yaml2obj/empty-or-invalid-doc.yaml index 9f451cab5a5..31a0973209f 100644 --- a/test/tools/yaml2obj/empty-or-invalid-doc.yaml +++ b/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: error: Unknown document type! +# CHECK: yaml2obj: error: unknown document type # RUN: echo -e -n "\xff" | not yaml2obj 2>&1 | FileCheck %s --check-prefix=INVALID -# INVALID: error: Failed to parse YAML input! +# INVALID: yaml2obj: error: failed to parse YAML input diff --git a/test/tools/yaml2obj/invalid-docnum.test b/test/tools/yaml2obj/invalid-docnum.test index 0a533468eda..e25a033b638 100644 --- a/test/tools/yaml2obj/invalid-docnum.test +++ b/test/tools/yaml2obj/invalid-docnum.test @@ -2,10 +2,10 @@ ## greater than the number of YAML inputs in the file. # RUN: not yaml2obj %s --docnum=3 2>&1 | FileCheck %s -# CHECK: error: Cannot find the 3rd document +# CHECK: yaml2obj: error: cannot find the 3rd document # RUN: not yaml2obj %s --docnum=76768677 2>&1 | FileCheck %s --check-prefix=TWO -# TWO: error: Cannot find the 76768677th document +# TWO: yaml2obj: error: cannot find the 76768677th document --- !ELF FileHeader: diff --git a/test/tools/yaml2obj/invalid_output_file.test b/test/tools/yaml2obj/invalid_output_file.test index 3045a0b21f5..1124b49d18c 100644 --- a/test/tools/yaml2obj/invalid_output_file.test +++ b/test/tools/yaml2obj/invalid_output_file.test @@ -1,4 +1,4 @@ # RUN: not yaml2obj -o %p/path/does/not/exist 2>&1 | FileCheck %s # Don't check the OS-dependent message "No such file or directory". -# CHECK: yaml2obj: Error opening '{{.*}}/path/does/not/exist': {{.*}} +# CHECK: yaml2obj: error: failed to open '{{.*}}/path/does/not/exist': {{.*}} diff --git a/test/tools/yaml2obj/missing_document_tag.yaml b/test/tools/yaml2obj/missing_document_tag.yaml index 09cdc4bff65..fd6c42114be 100644 --- a/test/tools/yaml2obj/missing_document_tag.yaml +++ b/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: error: Failed to parse YAML input! +# CHECK: error: failed to parse YAML input diff --git a/test/tools/yaml2obj/multi-doc.test b/test/tools/yaml2obj/multi-doc.test index 0b794e10067..327d625bfb3 100644 --- a/test/tools/yaml2obj/multi-doc.test +++ b/test/tools/yaml2obj/multi-doc.test @@ -16,7 +16,7 @@ # DOC2: Name: _sym2 # DOC3: Name: _sym3 # DOC4: Name: _sym4 -# DOC5: error: Cannot find the 5th document +# DOC5: error: cannot find the 5th document --- !ELF FileHeader: !FileHeader diff --git a/test/tools/yaml2obj/reloc-sec-info.yaml b/test/tools/yaml2obj/reloc-sec-info.yaml index c20536b47dd..801fe02e05f 100644 --- a/test/tools/yaml2obj/reloc-sec-info.yaml +++ b/test/tools/yaml2obj/reloc-sec-info.yaml @@ -30,7 +30,6 @@ Sections: # ERR: error: unknown section referenced: '.unknown1' by YAML section '.foo' # ERR: error: unknown section referenced: '.unknown2' by YAML section '.bar' -# ERR: error: yaml2obj failed --- !ELF FileHeader: diff --git a/test/tools/yaml2obj/section-size-content.yaml b/test/tools/yaml2obj/section-size-content.yaml index bc7a1a05c59..16b4b37dd42 100644 --- a/test/tools/yaml2obj/section-size-content.yaml +++ b/test/tools/yaml2obj/section-size-content.yaml @@ -175,4 +175,4 @@ Sections: # ERR2: error: Section size must be greater than or equal to the content size # ERR2-NEXT: - Name: .data # ERR2-NEXT: ^ -# ERR2-NEXT: error: Failed to parse YAML input! +# ERR2-NEXT: error: failed to parse YAML input diff --git a/tools/llvm-ifs/llvm-ifs.cpp b/tools/llvm-ifs/llvm-ifs.cpp index 17463578275..9d6d8d9ec4c 100644 --- a/tools/llvm-ifs/llvm-ifs.cpp +++ b/tools/llvm-ifs/llvm-ifs.cpp @@ -376,12 +376,10 @@ int writeElfStub(const llvm::Triple &T, const std::set &Symbols, }); yaml::Input YIn(YamlStr); - if (Error E = convertYAML(YIn, Out)) { - logAllUnhandledErrors(std::move(E), WithColor::error(errs(), "llvm-ifs")); - return 1; - } - - return 0; + auto ErrHandler = [](const Twine &Msg) { + WithColor::error(errs(), "llvm-ifs") << Msg << "\n"; + }; + return convertYAML(YIn, Out, ErrHandler) ? 0 : 1; } int writeIfso(const IFSStub &Stub, bool IsWriteIfs, raw_ostream &Out) { diff --git a/tools/yaml2obj/yaml2obj.cpp b/tools/yaml2obj/yaml2obj.cpp index 76e6663c095..66e0da69881 100644 --- a/tools/yaml2obj/yaml2obj.cpp +++ b/tools/yaml2obj/yaml2obj.cpp @@ -38,11 +38,6 @@ DocNum("docnum", cl::init(1), static cl::opt OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); -LLVM_ATTRIBUTE_NORETURN static void error(Twine Message) { - errs() << Message << "\n"; - exit(1); -} - int main(int argc, char **argv) { InitLLVM X(argc, argv); cl::ParseCommandLineOptions(argc, argv); @@ -50,11 +45,17 @@ int main(int argc, char **argv) { if (OutputFilename.empty()) OutputFilename = "-"; + auto ErrHandler = [](const Twine &Msg) { + WithColor::error(errs(), "yaml2obj") << Msg << "\n"; + }; + std::error_code EC; std::unique_ptr Out( new ToolOutputFile(OutputFilename, EC, sys::fs::OF_None)); - if (EC) - error("yaml2obj: Error opening '" + OutputFilename + "': " + EC.message()); + if (EC) { + ErrHandler("failed to open '" + OutputFilename + "': " + EC.message()); + return 1; + } ErrorOr> Buf = MemoryBuffer::getFileOrSTDIN(Input); @@ -62,10 +63,8 @@ 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])); + if (!convertYAML(YIn, Out->os(), ErrHandler, DocNum)) return 1; - } Out->keep(); Out->os().flush(); diff --git a/unittests/ObjectYAML/MinidumpYAMLTest.cpp b/unittests/ObjectYAML/MinidumpYAMLTest.cpp index 6df9536e9d3..576d8a09dfd 100644 --- a/unittests/ObjectYAML/MinidumpYAMLTest.cpp +++ b/unittests/ObjectYAML/MinidumpYAMLTest.cpp @@ -20,8 +20,9 @@ toBinary(SmallVectorImpl &Storage, StringRef Yaml) { Storage.clear(); raw_svector_ostream OS(Storage); yaml::Input YIn(Yaml); - if (Error E = yaml::convertYAML(YIn, OS)) - return std::move(E); + if (!yaml::convertYAML(YIn, OS, [](const Twine &Msg) {})) + return createStringError(std::errc::invalid_argument, + "unable to convert YAML"); return object::MinidumpFile::create(MemoryBufferRef(OS.str(), "Binary")); } diff --git a/unittests/ObjectYAML/YAML2ObjTest.cpp b/unittests/ObjectYAML/YAML2ObjTest.cpp index 0a383881687..8fafca4f908 100644 --- a/unittests/ObjectYAML/YAML2ObjTest.cpp +++ b/unittests/ObjectYAML/YAML2ObjTest.cpp @@ -10,6 +10,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h" +#include "llvm/Support/YAMLTraits.h" #include "llvm/Testing/Support/Error.h" #include "gtest/gtest.h" @@ -18,19 +19,63 @@ using namespace object; using namespace yaml; TEST(yaml2ObjectFile, ELF) { + bool ErrorReported = false; + auto ErrHandler = [&](const Twine &Msg) { ErrorReported = true; }; + SmallString<0> Storage; - Expected> ErrOrObj = yaml2ObjectFile(Storage, R"( + std::unique_ptr Obj = yaml2ObjectFile(Storage, R"( --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_REL - Machine: EM_X86_64)"); + Machine: EM_X86_64)", ErrHandler); - ASSERT_THAT_EXPECTED(ErrOrObj, Succeeded()); - - std::unique_ptr ObjFile = std::move(ErrOrObj.get()); - - ASSERT_TRUE(ObjFile->isELF()); - ASSERT_TRUE(ObjFile->isRelocatableObject()); + ASSERT_FALSE(ErrorReported); + ASSERT_TRUE(Obj); + ASSERT_TRUE(Obj->isELF()); + ASSERT_TRUE(Obj->isRelocatableObject()); +} + +TEST(yaml2ObjectFile, Errors) { + std::vector Errors; + auto ErrHandler = [&](const Twine &Msg) { + Errors.push_back("ObjectYAML: " + Msg.str()); + }; + + SmallString<0> Storage; + StringRef Yaml = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Symbols: + - Name: foo + - Name: foo + - Name: foo +)"; + + // 1. Test yaml2ObjectFile(). + + std::unique_ptr Obj = yaml2ObjectFile(Storage, Yaml, ErrHandler); + + ASSERT_FALSE(Obj); + ASSERT_TRUE(Errors.size() == 2); + ASSERT_TRUE(Errors[0] == "ObjectYAML: repeated symbol name: 'foo'"); + ASSERT_TRUE(Errors[1] == Errors[0]); + + // 2. Test convertYAML(). + + Errors.clear(); + Storage.clear(); + raw_svector_ostream OS(Storage); + + yaml::Input YIn(Yaml); + bool Res = convertYAML(YIn, OS, ErrHandler); + ASSERT_FALSE(Res); + ASSERT_TRUE(Errors.size() == 2); + ASSERT_TRUE(Errors[0] == "ObjectYAML: repeated symbol name: 'foo'"); + ASSERT_TRUE(Errors[1] == Errors[0]); }