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<void(const Twine &Msg)>;
-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<std::unique_ptr<object::ObjectFile>>
-yaml2ObjectFile(SmallVectorImpl<char> &Storage, StringRef Yaml);
+std::unique_ptr<object::ObjectFile>
+yaml2ObjectFile(SmallVectorImpl<char> &Storage, StringRef Yaml,
+ ErrorHandler ErrHandler);
} // namespace yaml
} // namespace llvm
/// 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));
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] = '/';
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;
std::string StringTable;
uint32_t SectionTableStart;
uint32_t SectionTableSize;
+
+ yaml::ErrorHandler ErrHandler;
};
enum { DOSStubSize = 128 };
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;
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();
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
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())
}
template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) {
- WithColor::error() << Msg << "\n";
+ ErrHandler(Msg);
HasError = true;
}
}
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
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
#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"
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);
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;
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>
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;
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) {
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);
}
// 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(
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>
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;
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 {
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);
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;
if (sys::IsLittleEndianHost)
swapStruct(header);
OS.write(reinterpret_cast<const char *>(&header), sizeof(MachO::fat_header));
- return Error::success();
}
template <typename FatArchType>
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) {
else
writeFatArch<MachO::fat_arch>(Arch, OS);
}
-
- return Error::success();
}
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;
}
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);
/// 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);
-
- 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 writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec,
+ uint32_t SectionIndex);
+
+ 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 {
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:
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);
}
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);
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),
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);
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) {
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) {
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;
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;
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:
}
default:
llvm_unreachable("not yet implemented");
- return 1;
}
encodeULEB128(SectionIndex, OS);
encodeULEB128(Reloc.Addend, OS);
}
}
- return 0;
}
bool WasmWriter::writeWasm(raw_ostream &OS) {
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
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);
}
#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 {};
+
+ Expected<std::unique_ptr<object::ObjectFile>> ObjOrErr =
+ object::ObjectFile::createObjectFile(
+ MemoryBufferRef(OS.str(), "YamlObject"));
+ if (ObjOrErr)
+ return std::move(*ObjOrErr);
- return object::ObjectFile::createObjectFile(
- MemoryBufferRef(OS.str(), "YamlObject"));
+ ErrHandler(toString(ObjOrErr.takeError()));
+ return {};
}
} // namespace yaml
- 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 ]
...
# RUN: not yaml2obj %s 2>&1 | FileCheck %s
-## CHECK: Section alignment is too large
+## CHECK: error: section alignment is too large
--- !COFF
header:
# 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:
# 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:
# 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
## 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:
# 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': {{.*}}
...
# 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
# 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
# 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:
# 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
});
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) {
static cl::opt<std::string> 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);
if (OutputFilename.empty())
OutputFilename = "-";
+ auto ErrHandler = [](const Twine &Msg) {
+ WithColor::error(errs(), "yaml2obj") << Msg << "\n";
+ };
+
std::error_code EC;
std::unique_ptr<ToolOutputFile> 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<std::unique_ptr<MemoryBuffer>> Buf =
MemoryBuffer::getFileOrSTDIN(Input);
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();
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"));
}
#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"
using namespace yaml;
TEST(yaml2ObjectFile, ELF) {
+ bool ErrorReported = false;
+ auto ErrHandler = [&](const Twine &Msg) { ErrorReported = true; };
+
+ SmallString<0> Storage;
+ std::unique_ptr<ObjectFile> Obj = yaml2ObjectFile(Storage, R"(
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64)", ErrHandler);
+
+ ASSERT_FALSE(ErrorReported);
+ ASSERT_TRUE(Obj);
+ ASSERT_TRUE(Obj->isELF());
+ ASSERT_TRUE(Obj->isRelocatableObject());
+}
+
+TEST(yaml2ObjectFile, Errors) {
+ std::vector<std::string> Errors;
+ auto ErrHandler = [&](const Twine &Msg) {
+ Errors.push_back("ObjectYAML: " + Msg.str());
+ };
+
SmallString<0> Storage;
- Expected<std::unique_ptr<ObjectFile>> ErrOrObj = yaml2ObjectFile(Storage, R"(
+ StringRef Yaml = R"(
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
- Machine: EM_X86_64)");
+ Machine: EM_X86_64
+Symbols:
+ - Name: foo
+ - Name: foo
+ - Name: foo
+)";
+
+ // 1. Test yaml2ObjectFile().
+
+ std::unique_ptr<ObjectFile> 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]);
- ASSERT_THAT_EXPECTED(ErrOrObj, Succeeded());
+ // 2. Test convertYAML().
- std::unique_ptr<ObjectFile> ObjFile = std::move(ErrOrObj.get());
+ Errors.clear();
+ Storage.clear();
+ raw_svector_ostream OS(Storage);
- ASSERT_TRUE(ObjFile->isELF());
- ASSERT_TRUE(ObjFile->isRelocatableObject());
+ 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]);
}