[yaml2obj/ObjectYAML] - Cleanup the error reporting API, add custom errors handlers.
This is a continuation of the YAML library error reporting
refactoring/improvement and the idea by itself was mentioned
in the following thread:
https://reviews.llvm.org/D67182?id=218714#inline-603404
This performs a cleanup of all object emitters in the library.
It allows using the custom one provided by the caller.
One of the nice things is that each tool can now print its tool name,
e.g: "yaml2obj: error: <text>"
Also, the code became a bit simpler.
Differential revision: https://reviews.llvm.org/D67445
llvm-svn: 371865
diff --git a/llvm/lib/ObjectYAML/COFFEmitter.cpp b/llvm/lib/ObjectYAML/COFFEmitter.cpp
index daa4f6d..efcdc51 100644
--- a/llvm/lib/ObjectYAML/COFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/COFFEmitter.cpp
@@ -34,8 +34,8 @@
/// 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 @@
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 @@
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 @@
std::string StringTable;
uint32_t SectionTableStart;
uint32_t SectionTableSize;
+
+ yaml::ErrorHandler ErrHandler;
};
enum { DOSStubSize = 128 };
@@ -592,24 +594,25 @@
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/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 6c64754..4584e3d 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -115,12 +115,13 @@
ELFYAML::Object &Doc;
bool HasError = false;
+ yaml::ErrorHandler ErrHandler;
+ void reportError(const Twine &Msg);
std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> 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 @@
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 <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); }
-template <class ELFT> ELFState<ELFT>::ELFState(ELFYAML::Object &D) : Doc(D) {
+template <class ELFT>
+ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)
+ : Doc(D), ErrHandler(EH) {
StringSet<> DocSections;
for (std::unique_ptr<ELFYAML::Section> &D : Doc.Sections)
if (!D->Name.empty())
@@ -592,7 +597,7 @@
}
template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) {
- WithColor::error() << Msg << "\n";
+ ErrHandler(Msg);
HasError = true;
}
@@ -983,8 +988,9 @@
}
template <class ELFT>
-bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc) {
- ELFState<ELFT> State(Doc);
+bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
+ yaml::ErrorHandler EH) {
+ ELFState<ELFT> 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 @@
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<object::ELF64LE>::writeELF(Out, Doc);
- return ELFState<object::ELF64BE>::writeELF(Out, Doc);
+ return ELFState<object::ELF64LE>::writeELF(Out, Doc, EH);
+ return ELFState<object::ELF64BE>::writeELF(Out, Doc, EH);
}
if (IsLE)
- return ELFState<object::ELF32LE>::writeELF(Out, Doc);
- return ELFState<object::ELF32BE>::writeELF(Out, Doc);
+ return ELFState<object::ELF32LE>::writeELF(Out, Doc, EH);
+ return ELFState<object::ELF32BE>::writeELF(Out, Doc, EH);
}
} // namespace yaml
diff --git a/llvm/lib/ObjectYAML/MachOEmitter.cpp b/llvm/lib/ObjectYAML/MachOEmitter.cpp
index 621b9b2..b56f811 100644
--- a/llvm/lib/ObjectYAML/MachOEmitter.cpp
+++ b/llvm/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 @@
memset(reinterpret_cast<void *>(&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<MachOYAML::BindOpcode> &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 @@
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 @@
auto header_size =
is64Bit ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header);
OS.write((const char *)&Header, header_size);
-
- return Error::success();
}
template <typename SectionType>
@@ -212,7 +205,7 @@
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 @@
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 @@
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 @@
}
// 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 @@
dumpExportEntry(OS, EE);
}
-Error MachOWriter::writeExportTrie(raw_ostream &OS) {
+void MachOWriter::writeExportTrie(raw_ostream &OS) {
dumpExportEntry(OS, Obj.LinkEdit.ExportTrie);
- return Error::success();
}
template <typename NListType>
@@ -397,8 +384,8 @@
OS.write(reinterpret_cast<const char *>(&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<uint64_t, writeHandler> writeOperation;
std::vector<writeOperation> WriteQueue;
@@ -435,57 +422,47 @@
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<char *>(&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<MachO::nlist_64>(NLE, OS, Obj.IsLittleEndian);
else
writeNListEntry<MachO::nlist>(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 @@
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 @@
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 @@
if (sys::IsLittleEndianHost)
swapStruct(header);
OS.write(reinterpret_cast<const char *>(&header), sizeof(MachO::fat_header));
- return Error::success();
}
template <typename FatArchType>
@@ -572,7 +548,7 @@
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 @@
else
writeFatArch<MachO::fat_arch>(Arch, OS);
}
-
- return Error::success();
}
void UniversalWriter::ZeroToOffset(raw_ostream &OS, size_t Offset) {
@@ -596,12 +570,9 @@
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/llvm/lib/ObjectYAML/MinidumpEmitter.cpp b/llvm/lib/ObjectYAML/MinidumpEmitter.cpp
index cc28f96..31a839e 100644
--- a/llvm/lib/ObjectYAML/MinidumpEmitter.cpp
+++ b/llvm/lib/ObjectYAML/MinidumpEmitter.cpp
@@ -198,7 +198,8 @@
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/llvm/lib/ObjectYAML/WasmEmitter.cpp b/llvm/lib/ObjectYAML/WasmEmitter.cpp
index 28d469c..e374764 100644
--- a/llvm/lib/ObjectYAML/WasmEmitter.cpp
+++ b/llvm/lib/ObjectYAML/WasmEmitter.cpp
@@ -25,39 +25,46 @@
/// 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 @@
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 @@
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 @@
}
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 @@
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 @@
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<WasmYAML::DylinkSection>(&Section)) {
- if (auto Err = writeSectionContent(OS, *S))
- return Err;
+ writeSectionContent(OS, *S);
} else if (auto S = dyn_cast<WasmYAML::NameSection>(&Section)) {
- if (auto Err = writeSectionContent(OS, *S))
- return Err;
+ writeSectionContent(OS, *S);
} else if (auto S = dyn_cast<WasmYAML::LinkingSection>(&Section)) {
- if (auto Err = writeSectionContent(OS, *S))
- return Err;
+ writeSectionContent(OS, *S);
} else if (auto S = dyn_cast<WasmYAML::ProducersSection>(&Section)) {
- if (auto Err = writeSectionContent(OS, *S))
- return Err;
+ writeSectionContent(OS, *S);
} else if (auto S = dyn_cast<WasmYAML::TargetFeaturesSection>(&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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
default:
llvm_unreachable("not yet implemented");
- return 1;
}
encodeULEB128(SectionIndex, OS);
@@ -560,7 +542,6 @@
encodeULEB128(Reloc.Addend, OS);
}
}
- return 0;
}
bool WasmWriter::writeWasm(raw_ostream &OS) {
@@ -575,58 +556,46 @@
if (auto S = dyn_cast<WasmYAML::CustomSection>(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<WasmYAML::CustomSection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else if (auto S = dyn_cast<WasmYAML::TypeSection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else if (auto S = dyn_cast<WasmYAML::ImportSection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else if (auto S = dyn_cast<WasmYAML::FunctionSection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else if (auto S = dyn_cast<WasmYAML::TableSection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else if (auto S = dyn_cast<WasmYAML::MemorySection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else if (auto S = dyn_cast<WasmYAML::GlobalSection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else if (auto S = dyn_cast<WasmYAML::EventSection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else if (auto S = dyn_cast<WasmYAML::ExportSection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else if (auto S = dyn_cast<WasmYAML::StartSection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else if (auto S = dyn_cast<WasmYAML::ElemSection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else if (auto S = dyn_cast<WasmYAML::CodeSection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else if (auto S = dyn_cast<WasmYAML::DataSection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else if (auto S = dyn_cast<WasmYAML::DataCountSection>(Sec.get())) {
- if (auto Err = writeSectionContent(StringStream, *S))
- return Err;
- } else {
- errs() << "Unknown section type: " << Sec->Type << "\n";
+ if (auto S = dyn_cast<WasmYAML::CustomSection>(Sec.get()))
+ writeSectionContent(StringStream, *S);
+ else if (auto S = dyn_cast<WasmYAML::TypeSection>(Sec.get()))
+ writeSectionContent(StringStream, *S);
+ else if (auto S = dyn_cast<WasmYAML::ImportSection>(Sec.get()))
+ writeSectionContent(StringStream, *S);
+ else if (auto S = dyn_cast<WasmYAML::FunctionSection>(Sec.get()))
+ writeSectionContent(StringStream, *S);
+ else if (auto S = dyn_cast<WasmYAML::TableSection>(Sec.get()))
+ writeSectionContent(StringStream, *S);
+ else if (auto S = dyn_cast<WasmYAML::MemorySection>(Sec.get()))
+ writeSectionContent(StringStream, *S);
+ else if (auto S = dyn_cast<WasmYAML::GlobalSection>(Sec.get()))
+ writeSectionContent(StringStream, *S);
+ else if (auto S = dyn_cast<WasmYAML::EventSection>(Sec.get()))
+ writeSectionContent(StringStream, *S);
+ else if (auto S = dyn_cast<WasmYAML::ExportSection>(Sec.get()))
+ writeSectionContent(StringStream, *S);
+ else if (auto S = dyn_cast<WasmYAML::StartSection>(Sec.get()))
+ writeSectionContent(StringStream, *S);
+ else if (auto S = dyn_cast<WasmYAML::ElemSection>(Sec.get()))
+ writeSectionContent(StringStream, *S);
+ else if (auto S = dyn_cast<WasmYAML::CodeSection>(Sec.get()))
+ writeSectionContent(StringStream, *S);
+ else if (auto S = dyn_cast<WasmYAML::DataSection>(Sec.get()))
+ writeSectionContent(StringStream, *S);
+ else if (auto S = dyn_cast<WasmYAML::DataCountSection>(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 @@
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/llvm/lib/ObjectYAML/yaml2obj.cpp b/llvm/lib/ObjectYAML/yaml2obj.cpp
index 8ca490b..c18fa5c 100644
--- a/llvm/lib/ObjectYAML/yaml2obj.cpp
+++ b/llvm/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<std::unique_ptr<object::ObjectFile>>
-yaml2ObjectFile(SmallVectorImpl<char> &Storage, StringRef Yaml) {
+std::unique_ptr<object::ObjectFile>
+yaml2ObjectFile(SmallVectorImpl<char> &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<std::unique_ptr<object::ObjectFile>> ObjOrErr =
+ object::ObjectFile::createObjectFile(
+ MemoryBufferRef(OS.str(), "YamlObject"));
+ if (ObjOrErr)
+ return std::move(*ObjOrErr);
+
+ ErrHandler(toString(ObjOrErr.takeError()));
+ return {};
}
} // namespace yaml