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   // TODO: make yaml2* functions return Error instead of int.
21   auto IntToErr = [](int Ret) -> Error {
22     if (Ret)
23       return createStringError(errc::invalid_argument, "yaml2obj failed");
24     return Error::success();
25   };
26 
27   unsigned CurDocNum = 0;
28   do {
29     if (++CurDocNum == DocNum) {
30       yaml::YamlObjectFile Doc;
31       YIn >> Doc;
32       if (std::error_code EC = YIn.error())
33         return createStringError(EC, "Failed to parse YAML input!");
34       if (Doc.Elf)
35         return IntToErr(yaml2elf(*Doc.Elf, Out));
36       if (Doc.Coff)
37         return IntToErr(yaml2coff(*Doc.Coff, Out));
38       if (Doc.MachO || Doc.FatMachO)
39         return IntToErr(yaml2macho(Doc, Out));
40       if (Doc.Minidump)
41         return IntToErr(yaml2minidump(*Doc.Minidump, Out));
42       if (Doc.Wasm)
43         return IntToErr(yaml2wasm(*Doc.Wasm, Out));
44       return createStringError(errc::invalid_argument,
45                                "Unknown document type!");
46     }
47   } while (YIn.nextDocument());
48 
49   return createStringError(errc::invalid_argument,
50                            "Cannot find the %u%s document", DocNum,
51                            getOrdinalSuffix(DocNum).data());
52 }
53 
54 Expected<std::unique_ptr<object::ObjectFile>>
55 yaml2ObjectFile(SmallVectorImpl<char> &Storage, StringRef Yaml) {
56   Storage.clear();
57   raw_svector_ostream OS(Storage);
58 
59   yaml::Input YIn(Yaml);
60   if (Error E = convertYAML(YIn, OS))
61     return std::move(E);
62 
63   return object::ObjectFile::createObjectFile(
64       MemoryBufferRef(OS.str(), "YamlObject"));
65 }
66 
67 } // namespace yaml
68 } // namespace llvm
69