1 //===------ xcoff2yaml.cpp - XCOFF YAMLIO implementation --------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 #include "llvm/Object/XCOFFObjectFile.h"
11 #include "llvm/ObjectYAML/XCOFFYAML.h"
12 #include "llvm/Support/Errc.h"
13 #include "llvm/Support/YAMLTraits.h"
16 using namespace llvm::object
;
20 const object::XCOFFObjectFile
&Obj
;
21 XCOFFYAML::Object YAMLObj
;
25 template <typename Shdr
, typename Reloc
>
26 Error
dumpSections(ArrayRef
<Shdr
> Sections
);
29 XCOFFDumper(const object::XCOFFObjectFile
&obj
) : Obj(obj
) {}
31 XCOFFYAML::Object
&getYAMLObj() { return YAMLObj
; }
35 Error
XCOFFDumper::dump() {
37 if (Error E
= dumpSections())
42 void XCOFFDumper::dumpHeader() {
43 YAMLObj
.Header
.Magic
= Obj
.getMagic();
44 YAMLObj
.Header
.NumberOfSections
= Obj
.getNumberOfSections();
45 YAMLObj
.Header
.TimeStamp
= Obj
.getTimeStamp();
46 YAMLObj
.Header
.SymbolTableOffset
= Obj
.is64Bit()
47 ? Obj
.getSymbolTableOffset64()
48 : Obj
.getSymbolTableOffset32();
49 YAMLObj
.Header
.NumberOfSymTableEntries
=
50 Obj
.is64Bit() ? Obj
.getNumberOfSymbolTableEntries64()
51 : Obj
.getRawNumberOfSymbolTableEntries32();
52 YAMLObj
.Header
.AuxHeaderSize
= Obj
.getOptionalHeaderSize();
53 YAMLObj
.Header
.Flags
= Obj
.getFlags();
56 Error
XCOFFDumper::dumpSections() {
58 return dumpSections
<XCOFFSectionHeader64
, XCOFFRelocation64
>(
60 return dumpSections
<XCOFFSectionHeader32
, XCOFFRelocation32
>(
64 template <typename Shdr
, typename Reloc
>
65 Error
XCOFFDumper::dumpSections(ArrayRef
<Shdr
> Sections
) {
66 std::vector
<XCOFFYAML::Section
> &YamlSections
= YAMLObj
.Sections
;
67 for (const Shdr
&S
: Sections
) {
68 XCOFFYAML::Section YamlSec
;
69 YamlSec
.SectionName
= S
.getName();
70 YamlSec
.Address
= S
.PhysicalAddress
;
71 YamlSec
.Size
= S
.SectionSize
;
72 YamlSec
.NumberOfRelocations
= S
.NumberOfRelocations
;
73 YamlSec
.NumberOfLineNumbers
= S
.NumberOfLineNumbers
;
74 YamlSec
.FileOffsetToData
= S
.FileOffsetToRawData
;
75 YamlSec
.FileOffsetToRelocations
= S
.FileOffsetToRelocationInfo
;
76 YamlSec
.FileOffsetToLineNumbers
= S
.FileOffsetToLineNumberInfo
;
77 YamlSec
.Flags
= S
.Flags
;
80 if (S
.FileOffsetToRawData
) {
81 DataRefImpl SectionDRI
;
82 SectionDRI
.p
= reinterpret_cast<uintptr_t>(&S
);
83 Expected
<ArrayRef
<uint8_t>> SecDataRefOrErr
=
84 Obj
.getSectionContents(SectionDRI
);
86 return SecDataRefOrErr
.takeError();
87 YamlSec
.SectionData
= SecDataRefOrErr
.get();
91 if (S
.NumberOfRelocations
) {
92 auto RelRefOrErr
= Obj
.relocations
<Shdr
, Reloc
>(S
);
94 return RelRefOrErr
.takeError();
95 for (const Reloc
&R
: RelRefOrErr
.get()) {
96 XCOFFYAML::Relocation YamlRel
;
97 YamlRel
.Type
= R
.Type
;
98 YamlRel
.Info
= R
.Info
;
99 YamlRel
.SymbolIndex
= R
.SymbolIndex
;
100 YamlRel
.VirtualAddress
= R
.VirtualAddress
;
101 YamlSec
.Relocations
.push_back(YamlRel
);
104 YamlSections
.push_back(YamlSec
);
106 return Error::success();
109 Error
XCOFFDumper::dumpSymbols() {
110 std::vector
<XCOFFYAML::Symbol
> &Symbols
= YAMLObj
.Symbols
;
112 for (const SymbolRef
&S
: Obj
.symbols()) {
113 DataRefImpl SymbolDRI
= S
.getRawDataRefImpl();
114 const XCOFFSymbolRef SymbolEntRef
= Obj
.toSymbolRef(SymbolDRI
);
115 XCOFFYAML::Symbol Sym
;
117 Expected
<StringRef
> SymNameRefOrErr
= Obj
.getSymbolName(SymbolDRI
);
118 if (!SymNameRefOrErr
) {
119 return SymNameRefOrErr
.takeError();
121 Sym
.SymbolName
= SymNameRefOrErr
.get();
123 Sym
.Value
= SymbolEntRef
.getValue();
125 Expected
<StringRef
> SectionNameRefOrErr
=
126 Obj
.getSymbolSectionName(SymbolEntRef
);
127 if (!SectionNameRefOrErr
)
128 return SectionNameRefOrErr
.takeError();
130 Sym
.SectionName
= SectionNameRefOrErr
.get();
132 Sym
.Type
= SymbolEntRef
.getSymbolType();
133 Sym
.StorageClass
= SymbolEntRef
.getStorageClass();
134 Sym
.NumberOfAuxEntries
= SymbolEntRef
.getNumberOfAuxEntries();
136 Symbols
.push_back(std::move(Sym
));
139 return Error::success();
142 Error
xcoff2yaml(raw_ostream
&Out
, const object::XCOFFObjectFile
&Obj
) {
143 XCOFFDumper
Dumper(Obj
);
145 if (Error E
= Dumper
.dump())
148 yaml::Output
Yout(Out
);
149 Yout
<< Dumper
.getYAMLObj();
151 return Error::success();