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()31 std::error_code XCOFFDumper::dump() {
32   dumpHeader();
33   return dumpSymbols();
34 }
35 
dumpHeader()36 void 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()53 std::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)85 std::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