Skip to content

Commit 04c5016

Browse files
author
George Rimar
committed
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@371865 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 3e78f24 commit 04c5016

21 files changed

+350
-345
lines changed

include/llvm/ObjectYAML/yaml2obj.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,22 @@ namespace yaml {
4444
class Input;
4545
struct YamlObjectFile;
4646

47-
bool yaml2coff(COFFYAML::Object &Doc, raw_ostream &Out);
48-
bool yaml2elf(ELFYAML::Object &Doc, raw_ostream &Out);
49-
bool yaml2macho(YamlObjectFile &Doc, raw_ostream &Out);
50-
bool yaml2minidump(MinidumpYAML::Object &Doc, raw_ostream &Out);
51-
bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out);
47+
using ErrorHandler = llvm::function_ref<void(const Twine &Msg)>;
5248

53-
Error convertYAML(Input &YIn, raw_ostream &Out, unsigned DocNum = 1);
49+
bool yaml2coff(COFFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH);
50+
bool yaml2elf(ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH);
51+
bool yaml2macho(YamlObjectFile &Doc, raw_ostream &Out, ErrorHandler EH);
52+
bool yaml2minidump(MinidumpYAML::Object &Doc, raw_ostream &Out,
53+
ErrorHandler EH);
54+
bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH);
55+
56+
bool convertYAML(Input &YIn, raw_ostream &Out, ErrorHandler ErrHandler,
57+
unsigned DocNum = 1);
5458

5559
/// Convenience function for tests.
56-
Expected<std::unique_ptr<object::ObjectFile>>
57-
yaml2ObjectFile(SmallVectorImpl<char> &Storage, StringRef Yaml);
60+
std::unique_ptr<object::ObjectFile>
61+
yaml2ObjectFile(SmallVectorImpl<char> &Storage, StringRef Yaml,
62+
ErrorHandler ErrHandler);
5863

5964
} // namespace yaml
6065
} // namespace llvm

lib/ObjectYAML/COFFEmitter.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ namespace {
3434
/// This parses a yaml stream that represents a COFF object file.
3535
/// See docs/yaml2obj for the yaml scheema.
3636
struct COFFParser {
37-
COFFParser(COFFYAML::Object &Obj)
38-
: Obj(Obj), SectionTableStart(0), SectionTableSize(0) {
37+
COFFParser(COFFYAML::Object &Obj, yaml::ErrorHandler EH)
38+
: Obj(Obj), SectionTableStart(0), SectionTableSize(0), ErrHandler(EH) {
3939
// A COFF string table always starts with a 4 byte size field. Offsets into
4040
// it include this size, so allocate it now.
4141
StringTable.append(4, char(0));
@@ -81,7 +81,7 @@ struct COFFParser {
8181
unsigned Index = getStringIndex(Name);
8282
std::string str = utostr(Index);
8383
if (str.size() > 7) {
84-
errs() << "String table got too large\n";
84+
ErrHandler("string table got too large");
8585
return false;
8686
}
8787
Sec.Header.Name[0] = '/';
@@ -90,11 +90,11 @@ struct COFFParser {
9090

9191
if (Sec.Alignment) {
9292
if (Sec.Alignment > 8192) {
93-
errs() << "Section alignment is too large\n";
93+
ErrHandler("section alignment is too large");
9494
return false;
9595
}
9696
if (!isPowerOf2_32(Sec.Alignment)) {
97-
errs() << "Section alignment is not a power of 2\n";
97+
ErrHandler("section alignment is not a power of 2");
9898
return false;
9999
}
100100
Sec.Header.Characteristics |= (Log2_32(Sec.Alignment) + 1) << 20;
@@ -155,6 +155,8 @@ struct COFFParser {
155155
std::string StringTable;
156156
uint32_t SectionTableStart;
157157
uint32_t SectionTableSize;
158+
159+
yaml::ErrorHandler ErrHandler;
158160
};
159161

160162
enum { DOSStubSize = 128 };
@@ -592,24 +594,25 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
592594
namespace llvm {
593595
namespace yaml {
594596

595-
bool yaml2coff(llvm::COFFYAML::Object &Doc, raw_ostream &Out) {
596-
COFFParser CP(Doc);
597+
bool yaml2coff(llvm::COFFYAML::Object &Doc, raw_ostream &Out,
598+
ErrorHandler ErrHandler) {
599+
COFFParser CP(Doc, ErrHandler);
597600
if (!CP.parse()) {
598-
errs() << "yaml2obj: Failed to parse YAML file!\n";
601+
ErrHandler("failed to parse YAML file");
599602
return false;
600603
}
601604

602605
if (!layoutOptionalHeader(CP)) {
603-
errs() << "yaml2obj: Failed to layout optional header for COFF file!\n";
606+
ErrHandler("failed to layout optional header for COFF file");
604607
return false;
605608
}
606609

607610
if (!layoutCOFF(CP)) {
608-
errs() << "yaml2obj: Failed to layout COFF file!\n";
611+
ErrHandler("failed to layout COFF file");
609612
return false;
610613
}
611614
if (!writeCOFF(CP, Out)) {
612-
errs() << "yaml2obj: Failed to write COFF file!\n";
615+
ErrHandler("failed to write COFF file");
613616
return false;
614617
}
615618
return true;

lib/ObjectYAML/ELFEmitter.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,13 @@ template <class ELFT> class ELFState {
115115
ELFYAML::Object &Doc;
116116

117117
bool HasError = false;
118+
yaml::ErrorHandler ErrHandler;
119+
void reportError(const Twine &Msg);
118120

119121
std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,
120122
const StringTableBuilder &Strtab);
121123
unsigned toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym = "");
122124
unsigned toSymbolIndex(StringRef S, StringRef LocSec, bool IsDynamic);
123-
void reportError(const Twine &Msg);
124125

125126
void buildSectionIndex();
126127
void buildSymbolIndexes();
@@ -166,9 +167,11 @@ template <class ELFT> class ELFState {
166167
void writeSectionContent(Elf_Shdr &SHeader,
167168
const ELFYAML::DynamicSection &Section,
168169
ContiguousBlobAccumulator &CBA);
169-
ELFState(ELFYAML::Object &D);
170+
ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH);
171+
170172
public:
171-
static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc);
173+
static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
174+
yaml::ErrorHandler EH);
172175
};
173176
} // end anonymous namespace
174177

@@ -182,7 +185,9 @@ template <class T> static void writeArrayData(raw_ostream &OS, ArrayRef<T> A) {
182185

183186
template <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); }
184187

185-
template <class ELFT> ELFState<ELFT>::ELFState(ELFYAML::Object &D) : Doc(D) {
188+
template <class ELFT>
189+
ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)
190+
: Doc(D), ErrHandler(EH) {
186191
StringSet<> DocSections;
187192
for (std::unique_ptr<ELFYAML::Section> &D : Doc.Sections)
188193
if (!D->Name.empty())
@@ -592,7 +597,7 @@ void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
592597
}
593598

594599
template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) {
595-
WithColor::error() << Msg << "\n";
600+
ErrHandler(Msg);
596601
HasError = true;
597602
}
598603

@@ -983,8 +988,9 @@ template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
983988
}
984989

985990
template <class ELFT>
986-
bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc) {
987-
ELFState<ELFT> State(Doc);
991+
bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
992+
yaml::ErrorHandler EH) {
993+
ELFState<ELFT> State(Doc, EH);
988994

989995
// Finalize .strtab and .dynstr sections. We do that early because want to
990996
// finalize the string table builders before writing the content of the
@@ -1022,17 +1028,17 @@ bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc) {
10221028
namespace llvm {
10231029
namespace yaml {
10241030

1025-
bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out) {
1031+
bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH) {
10261032
bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
10271033
bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);
10281034
if (Is64Bit) {
10291035
if (IsLE)
1030-
return ELFState<object::ELF64LE>::writeELF(Out, Doc);
1031-
return ELFState<object::ELF64BE>::writeELF(Out, Doc);
1036+
return ELFState<object::ELF64LE>::writeELF(Out, Doc, EH);
1037+
return ELFState<object::ELF64BE>::writeELF(Out, Doc, EH);
10321038
}
10331039
if (IsLE)
1034-
return ELFState<object::ELF32LE>::writeELF(Out, Doc);
1035-
return ELFState<object::ELF32BE>::writeELF(Out, Doc);
1040+
return ELFState<object::ELF32LE>::writeELF(Out, Doc, EH);
1041+
return ELFState<object::ELF32BE>::writeELF(Out, Doc, EH);
10361042
}
10371043

10381044
} // namespace yaml

0 commit comments

Comments
 (0)