1 //===-- yaml2obj.cpp ------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/ObjectYAML/yaml2obj.h"
10 #include "llvm/ADT/StringExtras.h"
11 #include "llvm/Object/ObjectFile.h"
12 #include "llvm/ObjectYAML/ObjectYAML.h"
13 #include "llvm/Support/Errc.h"
14 #include "llvm/Support/YAMLTraits.h"
15 
16 namespace llvm {
17 namespace yaml {
18 
19 Error convertYAML(yaml::Input &YIn, raw_ostream &Out, unsigned DocNum) {
20   auto BoolToErr = [](bool Ret) -> Error {
21     if (!Ret)
22       return createStringError(errc::invalid_argument, "yaml2obj failed");
23     return Error::success();
24   };
25 
26   unsigned CurDocNum = 0;
27   do {
28     if (++CurDocNum == DocNum) {
29       yaml::YamlObjectFile Doc;
30       YIn >> Doc;
31       if (std::error_code EC = YIn.error())
32         return createStringError(EC, "Failed to parse YAML input!");
33       if (Doc.Elf)
34         return BoolToErr(yaml2elf(*Doc.Elf, Out));
35       if (Doc.Coff)
36         return BoolToErr(yaml2coff(*Doc.Coff, Out));
37       if (Doc.MachO || Doc.FatMachO)
38         return BoolToErr(yaml2macho(Doc, Out));
39       if (Doc.Minidump)
40         return BoolToErr(yaml2minidump(*Doc.Minidump, Out));
41       if (Doc.Wasm)
42         return BoolToErr(yaml2wasm(*Doc.Wasm, Out));
43       return createStringError(errc::invalid_argument,
44                                "Unknown document type!");
45     }
46   } while (YIn.nextDocument());
47 
48   return createStringError(errc::invalid_argument,
49                            "Cannot find the %u%s document", DocNum,
50                            getOrdinalSuffix(DocNum).data());
51 }
52 
53 Expected<std::unique_ptr<object::ObjectFile>>
54 yaml2ObjectFile(SmallVectorImpl<char> &Storage, StringRef Yaml) {
55   Storage.clear();
56   raw_svector_ostream OS(Storage);
57 
58   yaml::Input YIn(Yaml);
59   if (Error E = convertYAML(YIn, OS))
60     return std::move(E);
61 
62   return object::ObjectFile::createObjectFile(
63       MemoryBufferRef(OS.str(), "YamlObject"));
64 }
65 
66 } // namespace yaml
67 } // namespace llvm
68