1*8bd8dd16SAdrian Prantl //===------ utils/obj2yaml.cpp - obj2yaml conversion tool -----------------===// 287a02909SRafael Espindola // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 687a02909SRafael Espindola // 787a02909SRafael Espindola //===----------------------------------------------------------------------===// 887a02909SRafael Espindola 987a02909SRafael Espindola #include "obj2yaml.h" 1047369e19SGeorgii Rymar #include "llvm/BinaryFormat/Magic.h" 1187a02909SRafael Espindola #include "llvm/Object/Archive.h" 1287a02909SRafael Espindola #include "llvm/Object/COFF.h" 133cee663eSPavel Labath #include "llvm/Object/Minidump.h" 1487a02909SRafael Espindola #include "llvm/Support/CommandLine.h" 15357dc1edSGeorgii Rymar #include "llvm/Support/Errc.h" 16197194b6SRui Ueyama #include "llvm/Support/InitLLVM.h" 1787a02909SRafael Espindola 1818192896SChandler Carruth using namespace llvm; 19ba592977SSimon Atanasyan using namespace llvm::object; 2018192896SChandler Carruth 21*8bd8dd16SAdrian Prantl static cl::opt<std::string> 22*8bd8dd16SAdrian Prantl InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-")); 23*8bd8dd16SAdrian Prantl static cl::bits<RawSegments> RawSegment( 24*8bd8dd16SAdrian Prantl "raw-segment", 25*8bd8dd16SAdrian Prantl cl::desc("Mach-O: dump the raw contents of the listed segments instead of " 26*8bd8dd16SAdrian Prantl "parsing them:"), 27*8bd8dd16SAdrian Prantl cl::values(clEnumVal(data, "__DATA"), clEnumVal(linkedit, "__LINKEDIT"))); 28*8bd8dd16SAdrian Prantl 29224816baSGeorge Rimar static Error dumpObject(const ObjectFile &Obj) { 30ba592977SSimon Atanasyan if (Obj.isCOFF()) 31224816baSGeorge Rimar return errorCodeToError(coff2yaml(outs(), cast<COFFObjectFile>(Obj))); 32ab2eb2bfSHubert Tong 33ab2eb2bfSHubert Tong if (Obj.isXCOFF()) 34a00ff716SEsme-Yi return xcoff2yaml(outs(), cast<XCOFFObjectFile>(Obj)); 35ab2eb2bfSHubert Tong 36ae6bb33aSSimon Atanasyan if (Obj.isELF()) 37ae6bb33aSSimon Atanasyan return elf2yaml(outs(), Obj); 38309246e4SGeorge Rimar 39224816baSGeorge Rimar if (Obj.isWasm()) 40224816baSGeorge Rimar return errorCodeToError(wasm2yaml(outs(), cast<WasmObjectFile>(Obj))); 41224816baSGeorge Rimar 42357dc1edSGeorgii Rymar llvm_unreachable("unexpected object file format"); 4318192896SChandler Carruth } 4487a02909SRafael Espindola 4520c7d432SSam Clegg static Error dumpInput(StringRef File) { 4647369e19SGeorgii Rymar ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 47c83cd8feSAbhina Sreeskantharajan MemoryBuffer::getFileOrSTDIN(File, /*IsText=*/false, 4847369e19SGeorgii Rymar /*RequiresNullTerminator=*/false); 4947369e19SGeorgii Rymar if (std::error_code EC = FileOrErr.getError()) 5047369e19SGeorgii Rymar return errorCodeToError(EC); 5147369e19SGeorgii Rymar std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get(); 5247369e19SGeorgii Rymar MemoryBufferRef MemBuf = Buffer->getMemBufferRef(); 5347369e19SGeorgii Rymar if (file_magic::archive == identify_magic(MemBuf.getBuffer())) 5447369e19SGeorgii Rymar return archive2yaml(outs(), MemBuf); 55ba592977SSimon Atanasyan 5647369e19SGeorgii Rymar Expected<std::unique_ptr<Binary>> BinOrErr = 5747369e19SGeorgii Rymar createBinary(MemBuf, /*Context=*/nullptr); 5847369e19SGeorgii Rymar if (!BinOrErr) 5947369e19SGeorgii Rymar return BinOrErr.takeError(); 6047369e19SGeorgii Rymar 6147369e19SGeorgii Rymar Binary &Binary = *BinOrErr->get(); 6293e71193SChris Bieneman // Universal MachO is not a subclass of ObjectFile, so it needs to be handled 6393e71193SChris Bieneman // here with the other binary types. 6493e71193SChris Bieneman if (Binary.isMachO() || Binary.isMachOUniversalBinary()) 65*8bd8dd16SAdrian Prantl return macho2yaml(outs(), Binary, RawSegment.getBits()); 663f6481d0SRafael Espindola if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary)) 67224816baSGeorge Rimar return dumpObject(*Obj); 683cee663eSPavel Labath if (MinidumpFile *Minidump = dyn_cast<MinidumpFile>(&Binary)) 693cee663eSPavel Labath return minidump2yaml(outs(), *Minidump); 70ba592977SSimon Atanasyan 7120c7d432SSam Clegg return Error::success(); 7220c7d432SSam Clegg } 7320c7d432SSam Clegg 7420c7d432SSam Clegg static void reportError(StringRef Input, Error Err) { 7520c7d432SSam Clegg if (Input == "-") 7620c7d432SSam Clegg Input = "<stdin>"; 7720c7d432SSam Clegg std::string ErrMsg; 7820c7d432SSam Clegg raw_string_ostream OS(ErrMsg); 7945eb84f3SJonas Devlieghere logAllUnhandledErrors(std::move(Err), OS); 8020c7d432SSam Clegg OS.flush(); 8120c7d432SSam Clegg errs() << "Error reading file: " << Input << ": " << ErrMsg; 8220c7d432SSam Clegg errs().flush(); 83ba592977SSimon Atanasyan } 8487a02909SRafael Espindola 8587a02909SRafael Espindola int main(int argc, char *argv[]) { 86197194b6SRui Ueyama InitLLVM X(argc, argv); 8787a02909SRafael Espindola cl::ParseCommandLineOptions(argc, argv); 8887a02909SRafael Espindola 8920c7d432SSam Clegg if (Error Err = dumpInput(InputFilename)) { 9020c7d432SSam Clegg reportError(InputFilename, std::move(Err)); 91ba592977SSimon Atanasyan return 1; 9287a02909SRafael Espindola } 9387a02909SRafael Espindola 9487a02909SRafael Espindola return 0; 9587a02909SRafael Espindola } 96