1ab2eb2bfSHubert Tong //===------ xcoff2yaml.cpp - XCOFF YAMLIO implementation --------*- C++ -*-===//
2ab2eb2bfSHubert Tong //
3ab2eb2bfSHubert Tong // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ab2eb2bfSHubert Tong // See https://llvm.org/LICENSE.txt for license information.
5ab2eb2bfSHubert Tong // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ab2eb2bfSHubert Tong //
7ab2eb2bfSHubert Tong //===----------------------------------------------------------------------===//
8ab2eb2bfSHubert Tong
9ab2eb2bfSHubert Tong #include "obj2yaml.h"
10ab2eb2bfSHubert Tong #include "llvm/Object/XCOFFObjectFile.h"
11ab2eb2bfSHubert Tong #include "llvm/ObjectYAML/XCOFFYAML.h"
12945df8bcSEsme-Yi #include "llvm/Support/Errc.h"
13ab2eb2bfSHubert Tong #include "llvm/Support/YAMLTraits.h"
14ab2eb2bfSHubert Tong
15ab2eb2bfSHubert Tong using namespace llvm;
16ab2eb2bfSHubert Tong using namespace llvm::object;
17ab2eb2bfSHubert Tong namespace {
18ab2eb2bfSHubert Tong
19ab2eb2bfSHubert Tong class XCOFFDumper {
20ab2eb2bfSHubert Tong const object::XCOFFObjectFile &Obj;
21ab2eb2bfSHubert Tong XCOFFYAML::Object YAMLObj;
22ab2eb2bfSHubert Tong void dumpHeader();
23945df8bcSEsme-Yi Error dumpSections();
24945df8bcSEsme-Yi Error dumpSymbols();
25945df8bcSEsme-Yi template <typename Shdr, typename Reloc>
26945df8bcSEsme-Yi Error dumpSections(ArrayRef<Shdr> Sections);
27ab2eb2bfSHubert Tong
28e4629371Sesmeyi // Dump auxiliary symbols.
29e4629371Sesmeyi Error dumpFileAuxSym(XCOFFYAML::Symbol &Sym,
30e4629371Sesmeyi const XCOFFSymbolRef &SymbolEntRef);
31e4629371Sesmeyi Error dumpStatAuxSym(XCOFFYAML::Symbol &Sym,
32e4629371Sesmeyi const XCOFFSymbolRef &SymbolEntRef);
33e4629371Sesmeyi Error dumpBlockAuxSym(XCOFFYAML::Symbol &Sym,
34e4629371Sesmeyi const XCOFFSymbolRef &SymbolEntRef);
35e4629371Sesmeyi Error dumpDwarfAuxSym(XCOFFYAML::Symbol &Sym,
36e4629371Sesmeyi const XCOFFSymbolRef &SymbolEntRef);
37e4629371Sesmeyi Error dumpAuxSyms(XCOFFYAML::Symbol &Sym, const XCOFFSymbolRef &SymbolEntRef);
38e4629371Sesmeyi void dumpFuncAuxSym(XCOFFYAML::Symbol &Sym, const uintptr_t AuxAddress);
39e4629371Sesmeyi void dumpExpAuxSym(XCOFFYAML::Symbol &Sym, const uintptr_t AuxAddress);
40a7f9e92dSstephenpeckham void dumpCsectAuxSym(XCOFFYAML::Symbol &Sym,
41e4629371Sesmeyi const object::XCOFFCsectAuxRef &AuxEntPtr);
42e4629371Sesmeyi
43ab2eb2bfSHubert Tong public:
XCOFFDumper(const object::XCOFFObjectFile & obj)449212206dSJason Liu XCOFFDumper(const object::XCOFFObjectFile &obj) : Obj(obj) {}
45945df8bcSEsme-Yi Error dump();
getYAMLObj()46ab2eb2bfSHubert Tong XCOFFYAML::Object &getYAMLObj() { return YAMLObj; }
47e4629371Sesmeyi
getAuxEntPtr(uintptr_t AuxAddress)48e4629371Sesmeyi template <typename T> const T *getAuxEntPtr(uintptr_t AuxAddress) {
49e4629371Sesmeyi Obj.checkSymbolEntryPointer(AuxAddress);
50e4629371Sesmeyi return reinterpret_cast<const T *>(AuxAddress);
51e4629371Sesmeyi }
52ab2eb2bfSHubert Tong };
53ab2eb2bfSHubert Tong } // namespace
54ab2eb2bfSHubert Tong
dump()55945df8bcSEsme-Yi Error XCOFFDumper::dump() {
56ab2eb2bfSHubert Tong dumpHeader();
57945df8bcSEsme-Yi if (Error E = dumpSections())
58945df8bcSEsme-Yi return E;
59837ae69fSSean Fertile return dumpSymbols();
60ab2eb2bfSHubert Tong }
61ab2eb2bfSHubert Tong
dumpHeader()62ab2eb2bfSHubert Tong void XCOFFDumper::dumpHeader() {
63837ae69fSSean Fertile YAMLObj.Header.Magic = Obj.getMagic();
64837ae69fSSean Fertile YAMLObj.Header.NumberOfSections = Obj.getNumberOfSections();
65837ae69fSSean Fertile YAMLObj.Header.TimeStamp = Obj.getTimeStamp();
66945df8bcSEsme-Yi YAMLObj.Header.SymbolTableOffset = Obj.is64Bit()
67945df8bcSEsme-Yi ? Obj.getSymbolTableOffset64()
68945df8bcSEsme-Yi : Obj.getSymbolTableOffset32();
69837ae69fSSean Fertile YAMLObj.Header.NumberOfSymTableEntries =
70945df8bcSEsme-Yi Obj.is64Bit() ? Obj.getNumberOfSymbolTableEntries64()
71945df8bcSEsme-Yi : Obj.getRawNumberOfSymbolTableEntries32();
72837ae69fSSean Fertile YAMLObj.Header.AuxHeaderSize = Obj.getOptionalHeaderSize();
73837ae69fSSean Fertile YAMLObj.Header.Flags = Obj.getFlags();
74ab2eb2bfSHubert Tong }
75ab2eb2bfSHubert Tong
dumpSections()76945df8bcSEsme-Yi Error XCOFFDumper::dumpSections() {
77945df8bcSEsme-Yi if (Obj.is64Bit())
78945df8bcSEsme-Yi return dumpSections<XCOFFSectionHeader64, XCOFFRelocation64>(
79945df8bcSEsme-Yi Obj.sections64());
80945df8bcSEsme-Yi return dumpSections<XCOFFSectionHeader32, XCOFFRelocation32>(
81945df8bcSEsme-Yi Obj.sections32());
82945df8bcSEsme-Yi }
83945df8bcSEsme-Yi
84945df8bcSEsme-Yi template <typename Shdr, typename Reloc>
dumpSections(ArrayRef<Shdr> Sections)85945df8bcSEsme-Yi Error XCOFFDumper::dumpSections(ArrayRef<Shdr> Sections) {
86945df8bcSEsme-Yi std::vector<XCOFFYAML::Section> &YamlSections = YAMLObj.Sections;
87945df8bcSEsme-Yi for (const Shdr &S : Sections) {
88945df8bcSEsme-Yi XCOFFYAML::Section YamlSec;
89945df8bcSEsme-Yi YamlSec.SectionName = S.getName();
90945df8bcSEsme-Yi YamlSec.Address = S.PhysicalAddress;
91945df8bcSEsme-Yi YamlSec.Size = S.SectionSize;
92945df8bcSEsme-Yi YamlSec.NumberOfRelocations = S.NumberOfRelocations;
93945df8bcSEsme-Yi YamlSec.NumberOfLineNumbers = S.NumberOfLineNumbers;
94945df8bcSEsme-Yi YamlSec.FileOffsetToData = S.FileOffsetToRawData;
95945df8bcSEsme-Yi YamlSec.FileOffsetToRelocations = S.FileOffsetToRelocationInfo;
96945df8bcSEsme-Yi YamlSec.FileOffsetToLineNumbers = S.FileOffsetToLineNumberInfo;
97945df8bcSEsme-Yi YamlSec.Flags = S.Flags;
98*26db8455Sstephenpeckham if (YamlSec.Flags & XCOFF::STYP_DWARF) {
99*26db8455Sstephenpeckham unsigned Mask = Obj.is64Bit()
100*26db8455Sstephenpeckham ? XCOFFSectionHeader64::SectionFlagsTypeMask
101*26db8455Sstephenpeckham : XCOFFSectionHeader32::SectionFlagsTypeMask;
102*26db8455Sstephenpeckham YamlSec.SectionSubtype =
103*26db8455Sstephenpeckham static_cast<XCOFF::DwarfSectionSubtypeFlags>(S.Flags & ~Mask);
104*26db8455Sstephenpeckham }
105945df8bcSEsme-Yi
106945df8bcSEsme-Yi // Dump section data.
107945df8bcSEsme-Yi if (S.FileOffsetToRawData) {
108945df8bcSEsme-Yi DataRefImpl SectionDRI;
109945df8bcSEsme-Yi SectionDRI.p = reinterpret_cast<uintptr_t>(&S);
110945df8bcSEsme-Yi Expected<ArrayRef<uint8_t>> SecDataRefOrErr =
111945df8bcSEsme-Yi Obj.getSectionContents(SectionDRI);
112945df8bcSEsme-Yi if (!SecDataRefOrErr)
113945df8bcSEsme-Yi return SecDataRefOrErr.takeError();
114945df8bcSEsme-Yi YamlSec.SectionData = SecDataRefOrErr.get();
115945df8bcSEsme-Yi }
116945df8bcSEsme-Yi
117945df8bcSEsme-Yi // Dump relocations.
118945df8bcSEsme-Yi if (S.NumberOfRelocations) {
119945df8bcSEsme-Yi auto RelRefOrErr = Obj.relocations<Shdr, Reloc>(S);
120945df8bcSEsme-Yi if (!RelRefOrErr)
121945df8bcSEsme-Yi return RelRefOrErr.takeError();
122945df8bcSEsme-Yi for (const Reloc &R : RelRefOrErr.get()) {
123945df8bcSEsme-Yi XCOFFYAML::Relocation YamlRel;
124945df8bcSEsme-Yi YamlRel.Type = R.Type;
125945df8bcSEsme-Yi YamlRel.Info = R.Info;
126945df8bcSEsme-Yi YamlRel.SymbolIndex = R.SymbolIndex;
127945df8bcSEsme-Yi YamlRel.VirtualAddress = R.VirtualAddress;
128945df8bcSEsme-Yi YamlSec.Relocations.push_back(YamlRel);
129945df8bcSEsme-Yi }
130945df8bcSEsme-Yi }
131945df8bcSEsme-Yi YamlSections.push_back(YamlSec);
132945df8bcSEsme-Yi }
133945df8bcSEsme-Yi return Error::success();
134945df8bcSEsme-Yi }
135945df8bcSEsme-Yi
dumpFileAuxSym(XCOFFYAML::Symbol & Sym,const XCOFFSymbolRef & SymbolEntRef)136e4629371Sesmeyi Error XCOFFDumper::dumpFileAuxSym(XCOFFYAML::Symbol &Sym,
137e4629371Sesmeyi const XCOFFSymbolRef &SymbolEntRef) {
138e4629371Sesmeyi for (uint8_t I = 1; I <= Sym.NumberOfAuxEntries; ++I) {
139e4629371Sesmeyi uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
140e4629371Sesmeyi SymbolEntRef.getEntryAddress(), I);
141e4629371Sesmeyi const XCOFFFileAuxEnt *FileAuxEntPtr =
142e4629371Sesmeyi getAuxEntPtr<XCOFFFileAuxEnt>(AuxAddress);
143e4629371Sesmeyi auto FileNameOrError = Obj.getCFileName(FileAuxEntPtr);
144e4629371Sesmeyi if (!FileNameOrError)
145e4629371Sesmeyi return FileNameOrError.takeError();
146e4629371Sesmeyi
147e4629371Sesmeyi XCOFFYAML::FileAuxEnt FileAuxSym;
148e4629371Sesmeyi FileAuxSym.FileNameOrString = FileNameOrError.get();
149e4629371Sesmeyi FileAuxSym.FileStringType = FileAuxEntPtr->Type;
150e4629371Sesmeyi Sym.AuxEntries.push_back(
151e4629371Sesmeyi std::make_unique<XCOFFYAML::FileAuxEnt>(FileAuxSym));
152e4629371Sesmeyi }
153e4629371Sesmeyi return Error::success();
154e4629371Sesmeyi }
155e4629371Sesmeyi
dumpStatAuxSym(XCOFFYAML::Symbol & Sym,const XCOFFSymbolRef & SymbolEntRef)156e4629371Sesmeyi Error XCOFFDumper::dumpStatAuxSym(XCOFFYAML::Symbol &Sym,
157e4629371Sesmeyi const XCOFFSymbolRef &SymbolEntRef) {
158e4629371Sesmeyi if (Sym.NumberOfAuxEntries != 1) {
159e4629371Sesmeyi uint32_t SymbolIndex = Obj.getSymbolIndex(SymbolEntRef.getEntryAddress());
160e4629371Sesmeyi return createError("failed to parse symbol \"" + Sym.SymbolName +
161e4629371Sesmeyi "\" with index of " + Twine(SymbolIndex) +
162e4629371Sesmeyi ": expected 1 aux symbol for C_STAT, while got " +
163e4629371Sesmeyi Twine(static_cast<uint32_t>(*Sym.NumberOfAuxEntries)));
164e4629371Sesmeyi }
165e4629371Sesmeyi
166e4629371Sesmeyi const XCOFFSectAuxEntForStat *AuxEntPtr =
167e4629371Sesmeyi getAuxEntPtr<XCOFFSectAuxEntForStat>(
168e4629371Sesmeyi XCOFFObjectFile::getAdvancedSymbolEntryAddress(
169e4629371Sesmeyi SymbolEntRef.getEntryAddress(), 1));
170e4629371Sesmeyi XCOFFYAML::SectAuxEntForStat StatAuxSym;
171e4629371Sesmeyi StatAuxSym.SectionLength = AuxEntPtr->SectionLength;
172e4629371Sesmeyi StatAuxSym.NumberOfLineNum = AuxEntPtr->NumberOfLineNum;
173e4629371Sesmeyi StatAuxSym.NumberOfRelocEnt = AuxEntPtr->NumberOfRelocEnt;
174e4629371Sesmeyi Sym.AuxEntries.push_back(
175e4629371Sesmeyi std::make_unique<XCOFFYAML::SectAuxEntForStat>(StatAuxSym));
176e4629371Sesmeyi return Error::success();
177e4629371Sesmeyi }
178e4629371Sesmeyi
dumpFuncAuxSym(XCOFFYAML::Symbol & Sym,const uintptr_t AuxAddress)179e4629371Sesmeyi void XCOFFDumper::dumpFuncAuxSym(XCOFFYAML::Symbol &Sym,
180e4629371Sesmeyi const uintptr_t AuxAddress) {
181e4629371Sesmeyi XCOFFYAML::FunctionAuxEnt FunAuxSym;
182e4629371Sesmeyi
183e4629371Sesmeyi if (Obj.is64Bit()) {
184e4629371Sesmeyi const XCOFFFunctionAuxEnt64 *AuxEntPtr =
185e4629371Sesmeyi getAuxEntPtr<XCOFFFunctionAuxEnt64>(AuxAddress);
186e4629371Sesmeyi FunAuxSym.PtrToLineNum = AuxEntPtr->PtrToLineNum;
187e4629371Sesmeyi FunAuxSym.SizeOfFunction = AuxEntPtr->SizeOfFunction;
188e4629371Sesmeyi FunAuxSym.SymIdxOfNextBeyond = AuxEntPtr->SymIdxOfNextBeyond;
189e4629371Sesmeyi } else {
190e4629371Sesmeyi const XCOFFFunctionAuxEnt32 *AuxEntPtr =
191e4629371Sesmeyi getAuxEntPtr<XCOFFFunctionAuxEnt32>(AuxAddress);
192e4629371Sesmeyi FunAuxSym.OffsetToExceptionTbl = AuxEntPtr->OffsetToExceptionTbl;
193e4629371Sesmeyi FunAuxSym.PtrToLineNum = AuxEntPtr->PtrToLineNum;
194e4629371Sesmeyi FunAuxSym.SizeOfFunction = AuxEntPtr->SizeOfFunction;
195e4629371Sesmeyi FunAuxSym.SymIdxOfNextBeyond = AuxEntPtr->SymIdxOfNextBeyond;
196e4629371Sesmeyi }
197e4629371Sesmeyi
198e4629371Sesmeyi Sym.AuxEntries.push_back(
199e4629371Sesmeyi std::make_unique<XCOFFYAML::FunctionAuxEnt>(FunAuxSym));
200e4629371Sesmeyi }
201e4629371Sesmeyi
dumpExpAuxSym(XCOFFYAML::Symbol & Sym,const uintptr_t AuxAddress)202e4629371Sesmeyi void XCOFFDumper::dumpExpAuxSym(XCOFFYAML::Symbol &Sym,
203e4629371Sesmeyi const uintptr_t AuxAddress) {
204e4629371Sesmeyi const XCOFFExceptionAuxEnt *AuxEntPtr =
205e4629371Sesmeyi getAuxEntPtr<XCOFFExceptionAuxEnt>(AuxAddress);
206e4629371Sesmeyi XCOFFYAML::ExcpetionAuxEnt ExceptAuxSym;
207e4629371Sesmeyi ExceptAuxSym.OffsetToExceptionTbl = AuxEntPtr->OffsetToExceptionTbl;
208e4629371Sesmeyi ExceptAuxSym.SizeOfFunction = AuxEntPtr->SizeOfFunction;
209e4629371Sesmeyi ExceptAuxSym.SymIdxOfNextBeyond = AuxEntPtr->SymIdxOfNextBeyond;
210e4629371Sesmeyi Sym.AuxEntries.push_back(
211e4629371Sesmeyi std::make_unique<XCOFFYAML::ExcpetionAuxEnt>(ExceptAuxSym));
212e4629371Sesmeyi }
213e4629371Sesmeyi
dumpCsectAuxSym(XCOFFYAML::Symbol & Sym,const object::XCOFFCsectAuxRef & AuxEntPtr)214a7f9e92dSstephenpeckham void XCOFFDumper::dumpCsectAuxSym(XCOFFYAML::Symbol &Sym,
215e4629371Sesmeyi const object::XCOFFCsectAuxRef &AuxEntPtr) {
216e4629371Sesmeyi XCOFFYAML::CsectAuxEnt CsectAuxSym;
217e4629371Sesmeyi CsectAuxSym.ParameterHashIndex = AuxEntPtr.getParameterHashIndex();
218e4629371Sesmeyi CsectAuxSym.TypeChkSectNum = AuxEntPtr.getTypeChkSectNum();
2195aeabf2dSstephenpeckham CsectAuxSym.SymbolAlignment = AuxEntPtr.getAlignmentLog2();
2205aeabf2dSstephenpeckham CsectAuxSym.SymbolType =
2215aeabf2dSstephenpeckham static_cast<XCOFF::SymbolType>(AuxEntPtr.getSymbolType());
222e4629371Sesmeyi CsectAuxSym.StorageMappingClass = AuxEntPtr.getStorageMappingClass();
223e4629371Sesmeyi
224e4629371Sesmeyi if (Obj.is64Bit()) {
225e4629371Sesmeyi CsectAuxSym.SectionOrLengthLo =
226e4629371Sesmeyi static_cast<uint32_t>(AuxEntPtr.getSectionOrLength64());
227e4629371Sesmeyi CsectAuxSym.SectionOrLengthHi =
228e4629371Sesmeyi static_cast<uint32_t>(AuxEntPtr.getSectionOrLength64() >> 32);
229e4629371Sesmeyi } else {
230e4629371Sesmeyi CsectAuxSym.SectionOrLength = AuxEntPtr.getSectionOrLength32();
231e4629371Sesmeyi CsectAuxSym.StabInfoIndex = AuxEntPtr.getStabInfoIndex32();
232e4629371Sesmeyi CsectAuxSym.StabSectNum = AuxEntPtr.getStabSectNum32();
233e4629371Sesmeyi }
234e4629371Sesmeyi
235e4629371Sesmeyi Sym.AuxEntries.push_back(
236e4629371Sesmeyi std::make_unique<XCOFFYAML::CsectAuxEnt>(CsectAuxSym));
237e4629371Sesmeyi }
238e4629371Sesmeyi
dumpAuxSyms(XCOFFYAML::Symbol & Sym,const XCOFFSymbolRef & SymbolEntRef)239e4629371Sesmeyi Error XCOFFDumper::dumpAuxSyms(XCOFFYAML::Symbol &Sym,
240e4629371Sesmeyi const XCOFFSymbolRef &SymbolEntRef) {
241e4629371Sesmeyi auto ErrOrCsectAuxRef = SymbolEntRef.getXCOFFCsectAuxRef();
242e4629371Sesmeyi if (!ErrOrCsectAuxRef)
243e4629371Sesmeyi return ErrOrCsectAuxRef.takeError();
244e4629371Sesmeyi XCOFFCsectAuxRef CsectAuxRef = ErrOrCsectAuxRef.get();
245e4629371Sesmeyi
246e4629371Sesmeyi for (uint8_t I = 1; I <= Sym.NumberOfAuxEntries; ++I) {
247e4629371Sesmeyi
248e4629371Sesmeyi if (I == Sym.NumberOfAuxEntries && !Obj.is64Bit()) {
249a7f9e92dSstephenpeckham dumpCsectAuxSym(Sym, CsectAuxRef);
250e4629371Sesmeyi return Error::success();
251e4629371Sesmeyi }
252e4629371Sesmeyi
253e4629371Sesmeyi uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
254e4629371Sesmeyi SymbolEntRef.getEntryAddress(), I);
255e4629371Sesmeyi
256e4629371Sesmeyi if (Obj.is64Bit()) {
257e4629371Sesmeyi XCOFF::SymbolAuxType Type = *Obj.getSymbolAuxType(AuxAddress);
258e4629371Sesmeyi if (Type == XCOFF::SymbolAuxType::AUX_CSECT)
259a7f9e92dSstephenpeckham dumpCsectAuxSym(Sym, CsectAuxRef);
260e4629371Sesmeyi else if (Type == XCOFF::SymbolAuxType::AUX_FCN)
261e4629371Sesmeyi dumpFuncAuxSym(Sym, AuxAddress);
262e4629371Sesmeyi else if (Type == XCOFF::SymbolAuxType::AUX_EXCEPT)
263e4629371Sesmeyi dumpExpAuxSym(Sym, AuxAddress);
264e4629371Sesmeyi else {
265e4629371Sesmeyi uint32_t SymbolIndex =
266e4629371Sesmeyi Obj.getSymbolIndex(SymbolEntRef.getEntryAddress());
267e4629371Sesmeyi return createError("failed to parse symbol \"" + Sym.SymbolName +
268e4629371Sesmeyi "\" with index of " + Twine(SymbolIndex) +
269e4629371Sesmeyi ": invalid auxiliary symbol type: " +
270e4629371Sesmeyi Twine(static_cast<uint32_t>(Type)));
271e4629371Sesmeyi }
272e4629371Sesmeyi
273e4629371Sesmeyi } else
274e4629371Sesmeyi dumpFuncAuxSym(Sym, AuxAddress);
275e4629371Sesmeyi }
276e4629371Sesmeyi
277e4629371Sesmeyi return Error::success();
278e4629371Sesmeyi }
279e4629371Sesmeyi
dumpBlockAuxSym(XCOFFYAML::Symbol & Sym,const XCOFFSymbolRef & SymbolEntRef)280e4629371Sesmeyi Error XCOFFDumper::dumpBlockAuxSym(XCOFFYAML::Symbol &Sym,
281e4629371Sesmeyi const XCOFFSymbolRef &SymbolEntRef) {
282e4629371Sesmeyi if (Sym.NumberOfAuxEntries != 1) {
283e4629371Sesmeyi uint32_t SymbolIndex = Obj.getSymbolIndex(SymbolEntRef.getEntryAddress());
284e4629371Sesmeyi return createError(
285e4629371Sesmeyi "failed to parse symbol \"" + Sym.SymbolName + "\" with index of " +
286e4629371Sesmeyi Twine(SymbolIndex) +
287e4629371Sesmeyi ": expected 1 aux symbol for C_BLOCK or C_FCN, while got " +
288e4629371Sesmeyi Twine(static_cast<uint32_t>(*Sym.NumberOfAuxEntries)));
289e4629371Sesmeyi }
290e4629371Sesmeyi
291e4629371Sesmeyi uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
292e4629371Sesmeyi SymbolEntRef.getEntryAddress(), 1);
293e4629371Sesmeyi XCOFFYAML::BlockAuxEnt BlockAuxSym;
294e4629371Sesmeyi
295e4629371Sesmeyi if (Obj.is64Bit()) {
296e4629371Sesmeyi const XCOFFBlockAuxEnt64 *AuxEntPtr =
297e4629371Sesmeyi getAuxEntPtr<XCOFFBlockAuxEnt64>(AuxAddress);
298e4629371Sesmeyi BlockAuxSym.LineNum = AuxEntPtr->LineNum;
299e4629371Sesmeyi } else {
300e4629371Sesmeyi const XCOFFBlockAuxEnt32 *AuxEntPtr =
301e4629371Sesmeyi getAuxEntPtr<XCOFFBlockAuxEnt32>(AuxAddress);
302e4629371Sesmeyi BlockAuxSym.LineNumLo = AuxEntPtr->LineNumLo;
303e4629371Sesmeyi BlockAuxSym.LineNumHi = AuxEntPtr->LineNumHi;
304e4629371Sesmeyi }
305e4629371Sesmeyi
306e4629371Sesmeyi Sym.AuxEntries.push_back(
307e4629371Sesmeyi std::make_unique<XCOFFYAML::BlockAuxEnt>(BlockAuxSym));
308e4629371Sesmeyi return Error::success();
309e4629371Sesmeyi }
310e4629371Sesmeyi
dumpDwarfAuxSym(XCOFFYAML::Symbol & Sym,const XCOFFSymbolRef & SymbolEntRef)311e4629371Sesmeyi Error XCOFFDumper::dumpDwarfAuxSym(XCOFFYAML::Symbol &Sym,
312e4629371Sesmeyi const XCOFFSymbolRef &SymbolEntRef) {
313e4629371Sesmeyi if (Sym.NumberOfAuxEntries != 1) {
314e4629371Sesmeyi uint32_t SymbolIndex = Obj.getSymbolIndex(SymbolEntRef.getEntryAddress());
315e4629371Sesmeyi return createError("failed to parse symbol \"" + Sym.SymbolName +
316e4629371Sesmeyi "\" with index of " + Twine(SymbolIndex) +
317e4629371Sesmeyi ": expected 1 aux symbol for C_DWARF, while got " +
318e4629371Sesmeyi Twine(static_cast<uint32_t>(*Sym.NumberOfAuxEntries)));
319e4629371Sesmeyi }
320e4629371Sesmeyi
321e4629371Sesmeyi uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
322e4629371Sesmeyi SymbolEntRef.getEntryAddress(), 1);
323e4629371Sesmeyi XCOFFYAML::SectAuxEntForDWARF DwarfAuxSym;
324e4629371Sesmeyi
325e4629371Sesmeyi if (Obj.is64Bit()) {
326e4629371Sesmeyi const XCOFFSectAuxEntForDWARF64 *AuxEntPtr =
327e4629371Sesmeyi getAuxEntPtr<XCOFFSectAuxEntForDWARF64>(AuxAddress);
328e4629371Sesmeyi DwarfAuxSym.LengthOfSectionPortion = AuxEntPtr->LengthOfSectionPortion;
329e4629371Sesmeyi DwarfAuxSym.NumberOfRelocEnt = AuxEntPtr->NumberOfRelocEnt;
330e4629371Sesmeyi } else {
331e4629371Sesmeyi const XCOFFSectAuxEntForDWARF32 *AuxEntPtr =
332e4629371Sesmeyi getAuxEntPtr<XCOFFSectAuxEntForDWARF32>(AuxAddress);
333e4629371Sesmeyi DwarfAuxSym.LengthOfSectionPortion = AuxEntPtr->LengthOfSectionPortion;
334e4629371Sesmeyi DwarfAuxSym.NumberOfRelocEnt = AuxEntPtr->NumberOfRelocEnt;
335e4629371Sesmeyi }
336e4629371Sesmeyi
337e4629371Sesmeyi Sym.AuxEntries.push_back(
338e4629371Sesmeyi std::make_unique<XCOFFYAML::SectAuxEntForDWARF>(DwarfAuxSym));
339e4629371Sesmeyi return Error::success();
340e4629371Sesmeyi }
341e4629371Sesmeyi
dumpSymbols()342945df8bcSEsme-Yi Error XCOFFDumper::dumpSymbols() {
3439212206dSJason Liu std::vector<XCOFFYAML::Symbol> &Symbols = YAMLObj.Symbols;
3449212206dSJason Liu
3459212206dSJason Liu for (const SymbolRef &S : Obj.symbols()) {
3469212206dSJason Liu DataRefImpl SymbolDRI = S.getRawDataRefImpl();
3478e84311aSjasonliu const XCOFFSymbolRef SymbolEntRef = Obj.toSymbolRef(SymbolDRI);
3489212206dSJason Liu XCOFFYAML::Symbol Sym;
3499212206dSJason Liu
3509212206dSJason Liu Expected<StringRef> SymNameRefOrErr = Obj.getSymbolName(SymbolDRI);
3519212206dSJason Liu if (!SymNameRefOrErr) {
352945df8bcSEsme-Yi return SymNameRefOrErr.takeError();
3539212206dSJason Liu }
3549212206dSJason Liu Sym.SymbolName = SymNameRefOrErr.get();
3559212206dSJason Liu
3568e84311aSjasonliu Sym.Value = SymbolEntRef.getValue();
3579212206dSJason Liu
3589212206dSJason Liu Expected<StringRef> SectionNameRefOrErr =
3598e84311aSjasonliu Obj.getSymbolSectionName(SymbolEntRef);
3609212206dSJason Liu if (!SectionNameRefOrErr)
361945df8bcSEsme-Yi return SectionNameRefOrErr.takeError();
3629212206dSJason Liu
3639212206dSJason Liu Sym.SectionName = SectionNameRefOrErr.get();
3649212206dSJason Liu
3658e84311aSjasonliu Sym.Type = SymbolEntRef.getSymbolType();
3668e84311aSjasonliu Sym.StorageClass = SymbolEntRef.getStorageClass();
3678e84311aSjasonliu Sym.NumberOfAuxEntries = SymbolEntRef.getNumberOfAuxEntries();
36881793640SEsme-Yi
369e4629371Sesmeyi if (Sym.NumberOfAuxEntries) {
370e4629371Sesmeyi switch (Sym.StorageClass) {
371e4629371Sesmeyi case XCOFF::C_FILE:
372e4629371Sesmeyi if (Error E = dumpFileAuxSym(Sym, SymbolEntRef))
373e4629371Sesmeyi return E;
374e4629371Sesmeyi break;
375e4629371Sesmeyi case XCOFF::C_STAT:
376e4629371Sesmeyi if (Error E = dumpStatAuxSym(Sym, SymbolEntRef))
377e4629371Sesmeyi return E;
378e4629371Sesmeyi break;
379e4629371Sesmeyi case XCOFF::C_EXT:
380e4629371Sesmeyi case XCOFF::C_WEAKEXT:
381e4629371Sesmeyi case XCOFF::C_HIDEXT:
382e4629371Sesmeyi if (Error E = dumpAuxSyms(Sym, SymbolEntRef))
383e4629371Sesmeyi return E;
384e4629371Sesmeyi break;
385e4629371Sesmeyi case XCOFF::C_BLOCK:
386e4629371Sesmeyi case XCOFF::C_FCN:
387e4629371Sesmeyi if (Error E = dumpBlockAuxSym(Sym, SymbolEntRef))
388e4629371Sesmeyi return E;
389e4629371Sesmeyi break;
390e4629371Sesmeyi case XCOFF::C_DWARF:
391e4629371Sesmeyi if (Error E = dumpDwarfAuxSym(Sym, SymbolEntRef))
392e4629371Sesmeyi return E;
393e4629371Sesmeyi break;
394e4629371Sesmeyi default:
395e4629371Sesmeyi break;
396e4629371Sesmeyi }
397e4629371Sesmeyi }
398e4629371Sesmeyi
39981793640SEsme-Yi Symbols.push_back(std::move(Sym));
4009212206dSJason Liu }
4019212206dSJason Liu
402945df8bcSEsme-Yi return Error::success();
4039212206dSJason Liu }
4049212206dSJason Liu
xcoff2yaml(raw_ostream & Out,const object::XCOFFObjectFile & Obj)405a00ff716SEsme-Yi Error xcoff2yaml(raw_ostream &Out, const object::XCOFFObjectFile &Obj) {
406ab2eb2bfSHubert Tong XCOFFDumper Dumper(Obj);
4079212206dSJason Liu
408945df8bcSEsme-Yi if (Error E = Dumper.dump())
409a00ff716SEsme-Yi return E;
4109212206dSJason Liu
411ab2eb2bfSHubert Tong yaml::Output Yout(Out);
412ab2eb2bfSHubert Tong Yout << Dumper.getYAMLObj();
413ab2eb2bfSHubert Tong
414a00ff716SEsme-Yi return Error::success();
415ab2eb2bfSHubert Tong }
416