blob: 949daffa9e8c3c7209cb1e6573f9b84c2deb6018 [file] [log] [blame]
Michael J. Spencera915f242012-08-02 19:16:56 +00001//===- yaml2obj - Convert YAML to a binary object file --------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This program takes a YAML description of an object file and outputs the
11// binary equivalent.
12//
13// This is used for writing tests that require binary files.
14//
15//===----------------------------------------------------------------------===//
16
Sean Silva6ed30e02013-06-05 19:56:47 +000017#include "yaml2obj.h"
Simon Atanasyandf96c562014-05-31 04:51:07 +000018#include "llvm/ADT/StringExtras.h"
Chris Bieneman9cf90e62016-06-27 19:53:53 +000019#include "llvm/ObjectYAML/ObjectYAML.h"
Michael J. Spencera915f242012-08-02 19:16:56 +000020#include "llvm/Support/CommandLine.h"
Simon Atanasyan926273d2014-05-15 16:14:02 +000021#include "llvm/Support/FileSystem.h"
Rui Ueyama0b9d56a2018-04-13 18:26:06 +000022#include "llvm/Support/InitLLVM.h"
Michael J. Spencera915f242012-08-02 19:16:56 +000023#include "llvm/Support/MemoryBuffer.h"
Simon Atanasyan926273d2014-05-15 16:14:02 +000024#include "llvm/Support/ToolOutputFile.h"
Simon Atanasyandf96c562014-05-31 04:51:07 +000025#include "llvm/Support/YAMLTraits.h"
Rafael Espindolad5132f92014-06-12 17:38:55 +000026#include "llvm/Support/raw_ostream.h"
27#include <system_error>
Michael J. Spencera915f242012-08-02 19:16:56 +000028
29using namespace llvm;
30
31static cl::opt<std::string>
32 Input(cl::Positional, cl::desc("<input>"), cl::init("-"));
33
Simon Atanasyandf96c562014-05-31 04:51:07 +000034cl::opt<unsigned>
35DocNum("docnum", cl::init(1),
36 cl::desc("Read specified document from input (default = 1)"));
37
Simon Atanasyan926273d2014-05-15 16:14:02 +000038static cl::opt<std::string> OutputFilename("o", cl::desc("Output filename"),
39 cl::value_desc("filename"));
Sean Silvadb9dc532013-06-05 18:51:34 +000040
Davide Italiano6bc97db2017-04-05 15:18:16 +000041LLVM_ATTRIBUTE_NORETURN static void error(Twine Message) {
42 errs() << Message << "\n";
43 exit(1);
44}
45
Chris Bieneman9cf90e62016-06-27 19:53:53 +000046static int convertYAML(yaml::Input &YIn, raw_ostream &Out) {
Simon Atanasyandf96c562014-05-31 04:51:07 +000047 unsigned CurDocNum = 0;
48 do {
Chris Bieneman9cf90e62016-06-27 19:53:53 +000049 if (++CurDocNum == DocNum) {
50 yaml::YamlObjectFile Doc;
51 YIn >> Doc;
Davide Italiano6bc97db2017-04-05 15:18:16 +000052 if (YIn.error())
53 error("yaml2obj: Failed to parse YAML file!");
Chris Bieneman9cf90e62016-06-27 19:53:53 +000054 if (Doc.Elf)
55 return yaml2elf(*Doc.Elf, Out);
56 if (Doc.Coff)
57 return yaml2coff(*Doc.Coff, Out);
58 if (Doc.MachO || Doc.FatMachO)
59 return yaml2macho(Doc, Out);
Derek Schuff349a48f2017-03-30 19:44:09 +000060 if (Doc.Wasm)
61 return yaml2wasm(*Doc.Wasm, Out);
Davide Italiano6bc97db2017-04-05 15:18:16 +000062 error("yaml2obj: Unknown document type!");
Chris Bieneman9cf90e62016-06-27 19:53:53 +000063 }
Simon Atanasyandf96c562014-05-31 04:51:07 +000064 } while (YIn.nextDocument());
65
Benjamin Kramerca5092a2017-12-28 16:58:54 +000066 error("yaml2obj: Cannot find the " + Twine(DocNum) +
Davide Italiano6bc97db2017-04-05 15:18:16 +000067 llvm::getOrdinalSuffix(DocNum) + " document");
Simon Atanasyandf96c562014-05-31 04:51:07 +000068}
69
Sean Silvadb9dc532013-06-05 18:51:34 +000070int main(int argc, char **argv) {
Rui Ueyama0b9d56a2018-04-13 18:26:06 +000071 InitLLVM X(argc, argv);
Sean Silvadb9dc532013-06-05 18:51:34 +000072 cl::ParseCommandLineOptions(argc, argv);
Sean Silvadb9dc532013-06-05 18:51:34 +000073
Simon Atanasyan926273d2014-05-15 16:14:02 +000074 if (OutputFilename.empty())
75 OutputFilename = "-";
76
Rafael Espindola8c968622014-08-25 18:16:47 +000077 std::error_code EC;
Reid Kleckner97ca9642017-09-23 01:03:17 +000078 std::unique_ptr<ToolOutputFile> Out(
79 new ToolOutputFile(OutputFilename, EC, sys::fs::F_None));
Davide Italiano6bc97db2017-04-05 15:18:16 +000080 if (EC)
81 error("yaml2obj: Error opening '" + OutputFilename + "': " + EC.message());
Simon Atanasyan926273d2014-05-15 16:14:02 +000082
Rafael Espindola7cba2a92014-07-06 17:43:13 +000083 ErrorOr<std::unique_ptr<MemoryBuffer>> Buf =
84 MemoryBuffer::getFileOrSTDIN(Input);
85 if (!Buf)
Sean Silvadb9dc532013-06-05 18:51:34 +000086 return 1;
Simon Atanasyan926273d2014-05-15 16:14:02 +000087
Rafael Espindola7cba2a92014-07-06 17:43:13 +000088 yaml::Input YIn(Buf.get()->getBuffer());
Simon Atanasyandf96c562014-05-31 04:51:07 +000089
Chris Bieneman9cf90e62016-06-27 19:53:53 +000090 int Res = convertYAML(YIn, Out->os());
Simon Atanasyan926273d2014-05-15 16:14:02 +000091 if (Res == 0)
92 Out->keep();
93
Zachary Turnerae75a982017-06-15 23:44:19 +000094 Out->os().flush();
Simon Atanasyan926273d2014-05-15 16:14:02 +000095 return Res;
Michael J. Spencera915f242012-08-02 19:16:56 +000096}