xref: /freebsd-src/contrib/llvm-project/llvm/lib/ObjectYAML/yaml2obj.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
18bcb0991SDimitry Andric //===-- yaml2obj.cpp ------------------------------------------------------===//
28bcb0991SDimitry Andric //
38bcb0991SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48bcb0991SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
58bcb0991SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68bcb0991SDimitry Andric //
78bcb0991SDimitry Andric //===----------------------------------------------------------------------===//
88bcb0991SDimitry Andric 
98bcb0991SDimitry Andric #include "llvm/ObjectYAML/yaml2obj.h"
108bcb0991SDimitry Andric #include "llvm/ADT/StringExtras.h"
118bcb0991SDimitry Andric #include "llvm/ADT/Twine.h"
128bcb0991SDimitry Andric #include "llvm/Object/ObjectFile.h"
138bcb0991SDimitry Andric #include "llvm/ObjectYAML/ObjectYAML.h"
148bcb0991SDimitry Andric #include "llvm/Support/Errc.h"
158bcb0991SDimitry Andric #include "llvm/Support/WithColor.h"
168bcb0991SDimitry Andric #include "llvm/Support/YAMLTraits.h"
178bcb0991SDimitry Andric 
188bcb0991SDimitry Andric namespace llvm {
198bcb0991SDimitry Andric namespace yaml {
208bcb0991SDimitry Andric 
218bcb0991SDimitry Andric bool convertYAML(yaml::Input &YIn, raw_ostream &Out, ErrorHandler ErrHandler,
225ffd83dbSDimitry Andric                  unsigned DocNum, uint64_t MaxSize) {
238bcb0991SDimitry Andric   unsigned CurDocNum = 0;
248bcb0991SDimitry Andric   do {
258bcb0991SDimitry Andric     if (++CurDocNum != DocNum)
268bcb0991SDimitry Andric       continue;
278bcb0991SDimitry Andric 
288bcb0991SDimitry Andric     yaml::YamlObjectFile Doc;
298bcb0991SDimitry Andric     YIn >> Doc;
308bcb0991SDimitry Andric     if (std::error_code EC = YIn.error()) {
318bcb0991SDimitry Andric       ErrHandler("failed to parse YAML input: " + EC.message());
328bcb0991SDimitry Andric       return false;
338bcb0991SDimitry Andric     }
348bcb0991SDimitry Andric 
35e8d8bef9SDimitry Andric     if (Doc.Arch)
36e8d8bef9SDimitry Andric       return yaml2archive(*Doc.Arch, Out, ErrHandler);
378bcb0991SDimitry Andric     if (Doc.Elf)
385ffd83dbSDimitry Andric       return yaml2elf(*Doc.Elf, Out, ErrHandler, MaxSize);
398bcb0991SDimitry Andric     if (Doc.Coff)
408bcb0991SDimitry Andric       return yaml2coff(*Doc.Coff, Out, ErrHandler);
418bcb0991SDimitry Andric     if (Doc.MachO || Doc.FatMachO)
428bcb0991SDimitry Andric       return yaml2macho(Doc, Out, ErrHandler);
438bcb0991SDimitry Andric     if (Doc.Minidump)
448bcb0991SDimitry Andric       return yaml2minidump(*Doc.Minidump, Out, ErrHandler);
458bcb0991SDimitry Andric     if (Doc.Wasm)
468bcb0991SDimitry Andric       return yaml2wasm(*Doc.Wasm, Out, ErrHandler);
47*fe6060f1SDimitry Andric     if (Doc.Xcoff)
48*fe6060f1SDimitry Andric       return yaml2xcoff(*Doc.Xcoff, Out, ErrHandler);
498bcb0991SDimitry Andric 
508bcb0991SDimitry Andric     ErrHandler("unknown document type");
518bcb0991SDimitry Andric     return false;
528bcb0991SDimitry Andric 
538bcb0991SDimitry Andric   } while (YIn.nextDocument());
548bcb0991SDimitry Andric 
558bcb0991SDimitry Andric   ErrHandler("cannot find the " + Twine(DocNum) +
568bcb0991SDimitry Andric              getOrdinalSuffix(DocNum).data() + " document");
578bcb0991SDimitry Andric   return false;
588bcb0991SDimitry Andric }
598bcb0991SDimitry Andric 
608bcb0991SDimitry Andric std::unique_ptr<object::ObjectFile>
618bcb0991SDimitry Andric yaml2ObjectFile(SmallVectorImpl<char> &Storage, StringRef Yaml,
628bcb0991SDimitry Andric                 ErrorHandler ErrHandler) {
638bcb0991SDimitry Andric   Storage.clear();
648bcb0991SDimitry Andric   raw_svector_ostream OS(Storage);
658bcb0991SDimitry Andric 
668bcb0991SDimitry Andric   yaml::Input YIn(Yaml);
678bcb0991SDimitry Andric   if (!convertYAML(YIn, OS, ErrHandler))
688bcb0991SDimitry Andric     return {};
698bcb0991SDimitry Andric 
708bcb0991SDimitry Andric   Expected<std::unique_ptr<object::ObjectFile>> ObjOrErr =
718bcb0991SDimitry Andric       object::ObjectFile::createObjectFile(
728bcb0991SDimitry Andric           MemoryBufferRef(OS.str(), "YamlObject"));
738bcb0991SDimitry Andric   if (ObjOrErr)
748bcb0991SDimitry Andric     return std::move(*ObjOrErr);
758bcb0991SDimitry Andric 
768bcb0991SDimitry Andric   ErrHandler(toString(ObjOrErr.takeError()));
778bcb0991SDimitry Andric   return {};
788bcb0991SDimitry Andric }
798bcb0991SDimitry Andric 
808bcb0991SDimitry Andric } // namespace yaml
818bcb0991SDimitry Andric } // namespace llvm
82