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