1 //===------ xcoff2yaml.cpp - XCOFF YAMLIO implementation --------*- C++ -*-===// 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 "obj2yaml.h" 10 #include "llvm/Object/XCOFFObjectFile.h" 11 #include "llvm/ObjectYAML/XCOFFYAML.h" 12 #include "llvm/Support/YAMLTraits.h" 13 14 using namespace llvm; 15 using namespace llvm::object; 16 namespace { 17 18 class XCOFFDumper { 19 const object::XCOFFObjectFile &Obj; 20 XCOFFYAML::Object YAMLObj; 21 void dumpHeader(); 22 std::error_code dumpSymbols(); 23 24 public: XCOFFDumper(const object::XCOFFObjectFile & obj)25 XCOFFDumper(const object::XCOFFObjectFile &obj) : Obj(obj) {} 26 std::error_code dump(); getYAMLObj()27 XCOFFYAML::Object &getYAMLObj() { return YAMLObj; } 28 }; 29 } // namespace 30 dump()31std::error_code XCOFFDumper::dump() { 32 dumpHeader(); 33 return dumpSymbols(); 34 } 35 dumpHeader()36void XCOFFDumper::dumpHeader() { 37 38 YAMLObj.Header.Magic = Obj.getMagic(); 39 YAMLObj.Header.NumberOfSections = Obj.getNumberOfSections(); 40 YAMLObj.Header.TimeStamp = Obj.getTimeStamp(); 41 42 // TODO FIXME only dump 32 bit header for now. 43 if (Obj.is64Bit()) 44 report_fatal_error("64-bit XCOFF files not supported yet."); 45 YAMLObj.Header.SymbolTableOffset = Obj.getSymbolTableOffset32(); 46 47 YAMLObj.Header.NumberOfSymTableEntries = 48 Obj.getRawNumberOfSymbolTableEntries32(); 49 YAMLObj.Header.AuxHeaderSize = Obj.getOptionalHeaderSize(); 50 YAMLObj.Header.Flags = Obj.getFlags(); 51 } 52 dumpSymbols()53std::error_code XCOFFDumper::dumpSymbols() { 54 std::vector<XCOFFYAML::Symbol> &Symbols = YAMLObj.Symbols; 55 56 for (const SymbolRef &S : Obj.symbols()) { 57 DataRefImpl SymbolDRI = S.getRawDataRefImpl(); 58 const XCOFFSymbolEntry *SymbolEntPtr = Obj.toSymbolEntry(SymbolDRI); 59 XCOFFYAML::Symbol Sym; 60 61 Expected<StringRef> SymNameRefOrErr = Obj.getSymbolName(SymbolDRI); 62 if (!SymNameRefOrErr) { 63 return errorToErrorCode(SymNameRefOrErr.takeError()); 64 } 65 Sym.SymbolName = SymNameRefOrErr.get(); 66 67 Sym.Value = SymbolEntPtr->Value; 68 69 Expected<StringRef> SectionNameRefOrErr = 70 Obj.getSymbolSectionName(SymbolEntPtr); 71 if (!SectionNameRefOrErr) 72 return errorToErrorCode(SectionNameRefOrErr.takeError()); 73 74 Sym.SectionName = SectionNameRefOrErr.get(); 75 76 Sym.Type = SymbolEntPtr->SymbolType; 77 Sym.StorageClass = SymbolEntPtr->StorageClass; 78 Sym.NumberOfAuxEntries = SymbolEntPtr->NumberOfAuxEntries; 79 Symbols.push_back(Sym); 80 } 81 82 return std::error_code(); 83 } 84 xcoff2yaml(raw_ostream & Out,const object::XCOFFObjectFile & Obj)85std::error_code xcoff2yaml(raw_ostream &Out, 86 const object::XCOFFObjectFile &Obj) { 87 XCOFFDumper Dumper(Obj); 88 89 if (std::error_code EC = Dumper.dump()) 90 return EC; 91 92 yaml::Output Yout(Out); 93 Yout << Dumper.getYAMLObj(); 94 95 return std::error_code(); 96 } 97