xref: /freebsd-src/contrib/llvm-project/llvm/lib/ObjectYAML/yaml2obj.cpp (revision 8bcb0991864975618c09697b1aca10683346d9f0)
1*8bcb0991SDimitry Andric //===-- yaml2obj.cpp ------------------------------------------------------===//
2*8bcb0991SDimitry Andric //
3*8bcb0991SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*8bcb0991SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*8bcb0991SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*8bcb0991SDimitry Andric //
7*8bcb0991SDimitry Andric //===----------------------------------------------------------------------===//
8*8bcb0991SDimitry Andric 
9*8bcb0991SDimitry Andric #include "llvm/ObjectYAML/yaml2obj.h"
10*8bcb0991SDimitry Andric #include "llvm/ADT/StringExtras.h"
11*8bcb0991SDimitry Andric #include "llvm/ADT/Twine.h"
12*8bcb0991SDimitry Andric #include "llvm/Object/ObjectFile.h"
13*8bcb0991SDimitry Andric #include "llvm/ObjectYAML/ObjectYAML.h"
14*8bcb0991SDimitry Andric #include "llvm/Support/Errc.h"
15*8bcb0991SDimitry Andric #include "llvm/Support/WithColor.h"
16*8bcb0991SDimitry Andric #include "llvm/Support/YAMLTraits.h"
17*8bcb0991SDimitry Andric 
18*8bcb0991SDimitry Andric namespace llvm {
19*8bcb0991SDimitry Andric namespace yaml {
20*8bcb0991SDimitry Andric 
21*8bcb0991SDimitry Andric bool convertYAML(yaml::Input &YIn, raw_ostream &Out, ErrorHandler ErrHandler,
22*8bcb0991SDimitry Andric                  unsigned DocNum) {
23*8bcb0991SDimitry Andric   unsigned CurDocNum = 0;
24*8bcb0991SDimitry Andric   do {
25*8bcb0991SDimitry Andric     if (++CurDocNum != DocNum)
26*8bcb0991SDimitry Andric       continue;
27*8bcb0991SDimitry Andric 
28*8bcb0991SDimitry Andric     yaml::YamlObjectFile Doc;
29*8bcb0991SDimitry Andric     YIn >> Doc;
30*8bcb0991SDimitry Andric     if (std::error_code EC = YIn.error()) {
31*8bcb0991SDimitry Andric       ErrHandler("failed to parse YAML input: " + EC.message());
32*8bcb0991SDimitry Andric       return false;
33*8bcb0991SDimitry Andric     }
34*8bcb0991SDimitry Andric 
35*8bcb0991SDimitry Andric     if (Doc.Elf)
36*8bcb0991SDimitry Andric       return yaml2elf(*Doc.Elf, Out, ErrHandler);
37*8bcb0991SDimitry Andric     if (Doc.Coff)
38*8bcb0991SDimitry Andric       return yaml2coff(*Doc.Coff, Out, ErrHandler);
39*8bcb0991SDimitry Andric     if (Doc.MachO || Doc.FatMachO)
40*8bcb0991SDimitry Andric       return yaml2macho(Doc, Out, ErrHandler);
41*8bcb0991SDimitry Andric     if (Doc.Minidump)
42*8bcb0991SDimitry Andric       return yaml2minidump(*Doc.Minidump, Out, ErrHandler);
43*8bcb0991SDimitry Andric     if (Doc.Wasm)
44*8bcb0991SDimitry Andric       return yaml2wasm(*Doc.Wasm, Out, ErrHandler);
45*8bcb0991SDimitry Andric 
46*8bcb0991SDimitry Andric     ErrHandler("unknown document type");
47*8bcb0991SDimitry Andric     return false;
48*8bcb0991SDimitry Andric 
49*8bcb0991SDimitry Andric   } while (YIn.nextDocument());
50*8bcb0991SDimitry Andric 
51*8bcb0991SDimitry Andric   ErrHandler("cannot find the " + Twine(DocNum) +
52*8bcb0991SDimitry Andric              getOrdinalSuffix(DocNum).data() + " document");
53*8bcb0991SDimitry Andric   return false;
54*8bcb0991SDimitry Andric }
55*8bcb0991SDimitry Andric 
56*8bcb0991SDimitry Andric std::unique_ptr<object::ObjectFile>
57*8bcb0991SDimitry Andric yaml2ObjectFile(SmallVectorImpl<char> &Storage, StringRef Yaml,
58*8bcb0991SDimitry Andric                 ErrorHandler ErrHandler) {
59*8bcb0991SDimitry Andric   Storage.clear();
60*8bcb0991SDimitry Andric   raw_svector_ostream OS(Storage);
61*8bcb0991SDimitry Andric 
62*8bcb0991SDimitry Andric   yaml::Input YIn(Yaml);
63*8bcb0991SDimitry Andric   if (!convertYAML(YIn, OS, ErrHandler))
64*8bcb0991SDimitry Andric     return {};
65*8bcb0991SDimitry Andric 
66*8bcb0991SDimitry Andric   Expected<std::unique_ptr<object::ObjectFile>> ObjOrErr =
67*8bcb0991SDimitry Andric       object::ObjectFile::createObjectFile(
68*8bcb0991SDimitry Andric           MemoryBufferRef(OS.str(), "YamlObject"));
69*8bcb0991SDimitry Andric   if (ObjOrErr)
70*8bcb0991SDimitry Andric     return std::move(*ObjOrErr);
71*8bcb0991SDimitry Andric 
72*8bcb0991SDimitry Andric   ErrHandler(toString(ObjOrErr.takeError()));
73*8bcb0991SDimitry Andric   return {};
74*8bcb0991SDimitry Andric }
75*8bcb0991SDimitry Andric 
76*8bcb0991SDimitry Andric } // namespace yaml
77*8bcb0991SDimitry Andric } // namespace llvm
78