Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / tools / obj2yaml / xcoff2yaml.cpp
blob882c410496012a1de46b759e77b6ad6d52b379f8
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 //===----------------------------------------------------------------------===//
9 #include "obj2yaml.h"
10 #include "llvm/Object/XCOFFObjectFile.h"
11 #include "llvm/ObjectYAML/XCOFFYAML.h"
12 #include "llvm/Support/Errc.h"
13 #include "llvm/Support/YAMLTraits.h"
15 using namespace llvm;
16 using namespace llvm::object;
17 namespace {
19 class XCOFFDumper {
20 const object::XCOFFObjectFile &Obj;
21 XCOFFYAML::Object YAMLObj;
22 void dumpHeader();
23 Error dumpSections();
24 Error dumpSymbols();
25 template <typename Shdr, typename Reloc>
26 Error dumpSections(ArrayRef<Shdr> Sections);
28 public:
29 XCOFFDumper(const object::XCOFFObjectFile &obj) : Obj(obj) {}
30 Error dump();
31 XCOFFYAML::Object &getYAMLObj() { return YAMLObj; }
33 } // namespace
35 Error XCOFFDumper::dump() {
36 dumpHeader();
37 if (Error E = dumpSections())
38 return E;
39 return dumpSymbols();
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() {
57 if (Obj.is64Bit())
58 return dumpSections<XCOFFSectionHeader64, XCOFFRelocation64>(
59 Obj.sections64());
60 return dumpSections<XCOFFSectionHeader32, XCOFFRelocation32>(
61 Obj.sections32());
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;
79 // Dump section data.
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);
85 if (!SecDataRefOrErr)
86 return SecDataRefOrErr.takeError();
87 YamlSec.SectionData = SecDataRefOrErr.get();
90 // Dump relocations.
91 if (S.NumberOfRelocations) {
92 auto RelRefOrErr = Obj.relocations<Shdr, Reloc>(S);
93 if (!RelRefOrErr)
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())
146 return E;
148 yaml::Output Yout(Out);
149 Yout << Dumper.getYAMLObj();
151 return Error::success();