diff options
| author | Chris Bieneman <beanz@apple.com> | 2016-06-27 19:53:53 +0000 |
|---|---|---|
| committer | Chris Bieneman <beanz@apple.com> | 2016-06-27 19:53:53 +0000 |
| commit | 8ff0c113575167809365d2de5f6a204ff9c9c2bb (patch) | |
| tree | bcfa2a036127dcd47a729941ec0389ec8022af0c /llvm/tools | |
| parent | f0fa61ffcfc8550f1b4282e456b3763d71b60c76 (diff) | |
| download | bcm5719-llvm-8ff0c113575167809365d2de5f6a204ff9c9c2bb.tar.gz bcm5719-llvm-8ff0c113575167809365d2de5f6a204ff9c9c2bb.zip | |
[yaml2obj] Remove --format option in favor of YAML tags
Summary:
Our YAML library's handling of tags isn't perfect, but it is good enough to get rid of the need for the --format argument to yaml2obj. This patch does exactly that.
Instead of requiring --format, it infers the format based on the tags found in the object file. The supported tags are:
!ELF
!COFF
!mach-o
!fat-mach-o
I have a corresponding patch that is quite large that fixes up all the in-tree test cases.
Reviewers: rafael, Bigcheese, compnerd, silvas
Subscribers: compnerd, llvm-commits
Differential Revision: http://reviews.llvm.org/D21711
llvm-svn: 273915
Diffstat (limited to 'llvm/tools')
| -rw-r--r-- | llvm/tools/obj2yaml/macho2yaml.cpp | 13 | ||||
| -rw-r--r-- | llvm/tools/yaml2obj/yaml2coff.cpp | 11 | ||||
| -rw-r--r-- | llvm/tools/yaml2obj/yaml2elf.cpp | 8 | ||||
| -rw-r--r-- | llvm/tools/yaml2obj/yaml2macho.cpp | 27 | ||||
| -rw-r--r-- | llvm/tools/yaml2obj/yaml2obj.cpp | 62 | ||||
| -rw-r--r-- | llvm/tools/yaml2obj/yaml2obj.h | 17 |
6 files changed, 55 insertions, 83 deletions
diff --git a/llvm/tools/obj2yaml/macho2yaml.cpp b/llvm/tools/obj2yaml/macho2yaml.cpp index 060a2b82726..c9a1385f173 100644 --- a/llvm/tools/obj2yaml/macho2yaml.cpp +++ b/llvm/tools/obj2yaml/macho2yaml.cpp @@ -10,7 +10,7 @@ #include "Error.h" #include "obj2yaml.h" #include "llvm/Object/MachOUniversal.h" -#include "llvm/ObjectYAML/MachOYAML.h" +#include "llvm/ObjectYAML/ObjectYAML.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/LEB128.h" @@ -467,15 +467,18 @@ Error macho2yaml(raw_ostream &Out, const object::MachOObjectFile &Obj) { if (!YAML) return YAML.takeError(); + yaml::YamlObjectFile YAMLFile; + YAMLFile.MachO = std::move(YAML.get()); + yaml::Output Yout(Out); - Yout << *(YAML.get()); + Yout << YAMLFile; return Error::success(); } Error macho2yaml(raw_ostream &Out, const object::MachOUniversalBinary &Obj) { - MachOYAML::MachFile YAMLFile; - YAMLFile.isFat = true; - MachOYAML::UniversalBinary &YAML = YAMLFile.FatFile; + yaml::YamlObjectFile YAMLFile; + YAMLFile.FatMachO.reset(new MachOYAML::UniversalBinary()); + MachOYAML::UniversalBinary &YAML = *YAMLFile.FatMachO; YAML.Header.magic = Obj.getMagic(); YAML.Header.nfat_arch = Obj.getNumberOfObjects(); diff --git a/llvm/tools/yaml2obj/yaml2coff.cpp b/llvm/tools/yaml2obj/yaml2coff.cpp index 1a1d07d7944..8f3f5217952 100644 --- a/llvm/tools/yaml2obj/yaml2coff.cpp +++ b/llvm/tools/yaml2obj/yaml2coff.cpp @@ -18,7 +18,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Object/COFF.h" -#include "llvm/ObjectYAML/COFFYAML.h" +#include "llvm/ObjectYAML/ObjectYAML.h" #include "llvm/Support/Endian.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" @@ -532,14 +532,7 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { return true; } -int yaml2coff(yaml::Input &YIn, raw_ostream &Out) { - COFFYAML::Object Doc; - YIn >> Doc; - if (YIn.error()) { - errs() << "yaml2obj: Failed to parse YAML file!\n"; - return 1; - } - +int yaml2coff(llvm::COFFYAML::Object &Doc, raw_ostream &Out) { COFFParser CP(Doc); if (!CP.parse()) { errs() << "yaml2obj: Failed to parse YAML file!\n"; diff --git a/llvm/tools/yaml2obj/yaml2elf.cpp b/llvm/tools/yaml2obj/yaml2elf.cpp index a2ae5e2e756..c98093431a7 100644 --- a/llvm/tools/yaml2obj/yaml2elf.cpp +++ b/llvm/tools/yaml2obj/yaml2elf.cpp @@ -558,13 +558,7 @@ static bool isLittleEndian(const ELFYAML::Object &Doc) { return Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); } -int yaml2elf(yaml::Input &YIn, raw_ostream &Out) { - ELFYAML::Object Doc; - YIn >> Doc; - if (YIn.error()) { - errs() << "yaml2obj: Failed to parse YAML file!\n"; - return 1; - } +int yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out) { using object::ELFType; typedef ELFType<support::little, true> LE64; typedef ELFType<support::big, true> BE64; diff --git a/llvm/tools/yaml2obj/yaml2macho.cpp b/llvm/tools/yaml2obj/yaml2macho.cpp index 3d8be965209..fb29e206be3 100644 --- a/llvm/tools/yaml2obj/yaml2macho.cpp +++ b/llvm/tools/yaml2obj/yaml2macho.cpp @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// #include "yaml2obj.h" -#include "llvm/ObjectYAML/MachOYAML.h" +#include "llvm/ObjectYAML/ObjectYAML.h" #include "llvm/Support/Error.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/MachO.h" @@ -426,8 +426,8 @@ Error MachOWriter::writeStringTable(raw_ostream &OS) { class UniversalWriter { public: - UniversalWriter(MachOYAML::MachFile &MachFile) - : MachFile(MachFile), fileStart(0) {} + UniversalWriter(yaml::YamlObjectFile &ObjectFile) + : ObjectFile(ObjectFile), fileStart(0) {} Error writeMachO(raw_ostream &OS); @@ -437,21 +437,21 @@ private: void ZeroToOffset(raw_ostream &OS, size_t offset); - MachOYAML::MachFile &MachFile; + yaml::YamlObjectFile &ObjectFile; uint64_t fileStart; }; Error UniversalWriter::writeMachO(raw_ostream &OS) { fileStart = OS.tell(); - if (!MachFile.isFat) { - MachOWriter Writer(MachFile.ThinFile); + if (ObjectFile.MachO) { + MachOWriter Writer(*ObjectFile.MachO); return Writer.writeMachO(OS); } if (auto Err = writeFatHeader(OS)) return Err; if (auto Err = writeFatArchs(OS)) return Err; - auto &FatFile = MachFile.FatFile; + 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); @@ -465,7 +465,7 @@ Error UniversalWriter::writeMachO(raw_ostream &OS) { } Error UniversalWriter::writeFatHeader(raw_ostream &OS) { - auto &FatFile = MachFile.FatFile; + auto &FatFile = *ObjectFile.FatMachO; MachO::fat_header header; header.magic = FatFile.Header.magic; header.nfat_arch = FatFile.Header.nfat_arch; @@ -509,7 +509,7 @@ void writeFatArch<MachO::fat_arch_64>(MachOYAML::FatArch &Arch, } Error UniversalWriter::writeFatArchs(raw_ostream &OS) { - auto &FatFile = MachFile.FatFile; + auto &FatFile = *ObjectFile.FatMachO; bool is64Bit = FatFile.Header.magic == MachO::FAT_MAGIC_64; for (auto Arch : FatFile.FatArchs) { if (is64Bit) @@ -529,14 +529,7 @@ void UniversalWriter::ZeroToOffset(raw_ostream &OS, size_t Offset) { } // end anonymous namespace -int yaml2macho(yaml::Input &YIn, raw_ostream &Out) { - MachOYAML::MachFile Doc; - YIn >> Doc; - if (YIn.error()) { - errs() << "yaml2obj: Failed to parse YAML file!\n"; - return 1; - } - +int yaml2macho(yaml::YamlObjectFile &Doc, raw_ostream &Out) { UniversalWriter Writer(Doc); if (auto Err = Writer.writeMachO(Out)) { errs() << toString(std::move(Err)); diff --git a/llvm/tools/yaml2obj/yaml2obj.cpp b/llvm/tools/yaml2obj/yaml2obj.cpp index a2a8e0b8b83..f746d84a389 100644 --- a/llvm/tools/yaml2obj/yaml2obj.cpp +++ b/llvm/tools/yaml2obj/yaml2obj.cpp @@ -16,6 +16,7 @@ #include "yaml2obj.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ObjectYAML/ObjectYAML.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/ManagedStatic.h" @@ -32,29 +33,6 @@ using namespace llvm; static cl::opt<std::string> Input(cl::Positional, cl::desc("<input>"), cl::init("-")); -// TODO: The "right" way to tell what kind of object file a given YAML file -// corresponds to is to look at YAML "tags" (e.g. `!Foo`). Then, different -// tags (`!ELF`, `!COFF`, etc.) would be used to discriminate between them. -// Interpreting the tags is needed eventually for when writing test cases, -// so that we can e.g. have `!Archive` contain a sequence of `!ELF`, and -// just Do The Right Thing. However, interpreting these tags and acting on -// them appropriately requires some work in the YAML parser and the YAMLIO -// library. -enum YAMLObjectFormat { - YOF_COFF, - YOF_ELF, - YOF_MACHO -}; - -cl::opt<YAMLObjectFormat> Format( - "format", - cl::desc("Interpret input as this type of object file"), - cl::values( - clEnumValN(YOF_COFF, "coff", "COFF object file format"), - clEnumValN(YOF_ELF, "elf", "ELF object file format"), - clEnumValN(YOF_MACHO, "macho", "Mach-O object file format"), - clEnumValEnd)); - cl::opt<unsigned> DocNum("docnum", cl::init(1), cl::desc("Read specified document from input (default = 1)")); @@ -62,14 +40,26 @@ DocNum("docnum", cl::init(1), static cl::opt<std::string> OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); -typedef int (*ConvertFuncPtr)(yaml::Input & YIn, raw_ostream &Out); - -static int convertYAML(yaml::Input &YIn, raw_ostream &Out, - ConvertFuncPtr Convert) { +static int convertYAML(yaml::Input &YIn, raw_ostream &Out) { unsigned CurDocNum = 0; do { - if (++CurDocNum == DocNum) - return Convert(YIn, Out); + if (++CurDocNum == DocNum) { + yaml::YamlObjectFile Doc; + YIn >> Doc; + if (YIn.error()) { + errs() << "yaml2obj: Failed to parse YAML file!\n"; + return 1; + } + + if (Doc.Elf) + return yaml2elf(*Doc.Elf, Out); + if (Doc.Coff) + return yaml2coff(*Doc.Coff, Out); + if (Doc.MachO || Doc.FatMachO) + return yaml2macho(Doc, Out); + errs() << "yaml2obj: Unknown document type!\n"; + return 1; + } } while (YIn.nextDocument()); errs() << "yaml2obj: Cannot find the " << DocNum @@ -99,21 +89,9 @@ int main(int argc, char **argv) { if (!Buf) return 1; - ConvertFuncPtr Convert = nullptr; - if (Format == YOF_COFF) - Convert = yaml2coff; - else if (Format == YOF_ELF) - Convert = yaml2elf; - else if (Format == YOF_MACHO) - Convert = yaml2macho; - else { - errs() << "Not yet implemented\n"; - return 1; - } - yaml::Input YIn(Buf.get()->getBuffer()); - int Res = convertYAML(YIn, Out->os(), Convert); + int Res = convertYAML(YIn, Out->os()); if (Res == 0) Out->keep(); diff --git a/llvm/tools/yaml2obj/yaml2obj.h b/llvm/tools/yaml2obj/yaml2obj.h index cd9845a7731..b5025e860bd 100644 --- a/llvm/tools/yaml2obj/yaml2obj.h +++ b/llvm/tools/yaml2obj/yaml2obj.h @@ -14,12 +14,23 @@ namespace llvm { class raw_ostream; + +namespace COFFYAML { +struct Object; +} + +namespace ELFYAML { +struct Object; +} + namespace yaml { class Input; +struct YamlObjectFile; } } -int yaml2coff(llvm::yaml::Input &YIn, llvm::raw_ostream &Out); -int yaml2elf(llvm::yaml::Input &YIn, llvm::raw_ostream &Out); -int yaml2macho(llvm::yaml::Input &YIn, llvm::raw_ostream &Out); + +int yaml2coff(llvm::COFFYAML::Object &Doc, llvm::raw_ostream &Out); +int yaml2elf(llvm::ELFYAML::Object &Doc, llvm::raw_ostream &Out); +int yaml2macho(llvm::yaml::YamlObjectFile &Doc, llvm::raw_ostream &Out); #endif |

