1 //===----- XCOFFYAML.h - 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 // This file declares classes for handling the YAML representation of XCOFF.
10 //
11 //===----------------------------------------------------------------------===//
12 #ifndef LLVM_OBJECTYAML_XCOFFYAML_H
13 #define LLVM_OBJECTYAML_XCOFFYAML_H
14
15 #include "llvm/BinaryFormat/XCOFF.h"
16 #include "llvm/ObjectYAML/YAML.h"
17 #include <optional>
18 #include <vector>
19
20 namespace llvm {
21 namespace XCOFFYAML {
22
23 struct FileHeader {
24 llvm::yaml::Hex16 Magic;
25 uint16_t NumberOfSections;
26 int32_t TimeStamp;
27 llvm::yaml::Hex64 SymbolTableOffset;
28 int32_t NumberOfSymTableEntries;
29 uint16_t AuxHeaderSize;
30 llvm::yaml::Hex16 Flags;
31 };
32
33 struct AuxiliaryHeader {
34 std::optional<llvm::yaml::Hex16> Magic;
35 std::optional<llvm::yaml::Hex16> Version;
36 std::optional<llvm::yaml::Hex64> TextStartAddr;
37 std::optional<llvm::yaml::Hex64> DataStartAddr;
38 std::optional<llvm::yaml::Hex64> TOCAnchorAddr;
39 std::optional<uint16_t> SecNumOfEntryPoint;
40 std::optional<uint16_t> SecNumOfText;
41 std::optional<uint16_t> SecNumOfData;
42 std::optional<uint16_t> SecNumOfTOC;
43 std::optional<uint16_t> SecNumOfLoader;
44 std::optional<uint16_t> SecNumOfBSS;
45 std::optional<llvm::yaml::Hex16> MaxAlignOfText;
46 std::optional<llvm::yaml::Hex16> MaxAlignOfData;
47 std::optional<llvm::yaml::Hex16> ModuleType;
48 std::optional<llvm::yaml::Hex8> CpuFlag;
49 std::optional<llvm::yaml::Hex8> CpuType;
50 std::optional<llvm::yaml::Hex8> TextPageSize;
51 std::optional<llvm::yaml::Hex8> DataPageSize;
52 std::optional<llvm::yaml::Hex8> StackPageSize;
53 std::optional<llvm::yaml::Hex8> FlagAndTDataAlignment;
54 std::optional<llvm::yaml::Hex64> TextSize;
55 std::optional<llvm::yaml::Hex64> InitDataSize;
56 std::optional<llvm::yaml::Hex64> BssDataSize;
57 std::optional<llvm::yaml::Hex64> EntryPointAddr;
58 std::optional<llvm::yaml::Hex64> MaxStackSize;
59 std::optional<llvm::yaml::Hex64> MaxDataSize;
60 std::optional<uint16_t> SecNumOfTData;
61 std::optional<uint16_t> SecNumOfTBSS;
62 std::optional<llvm::yaml::Hex16> Flag;
63 };
64
65 struct Relocation {
66 llvm::yaml::Hex64 VirtualAddress;
67 llvm::yaml::Hex64 SymbolIndex;
68 llvm::yaml::Hex8 Info;
69 llvm::yaml::Hex8 Type;
70 };
71
72 struct Section {
73 StringRef SectionName;
74 llvm::yaml::Hex64 Address;
75 llvm::yaml::Hex64 Size;
76 llvm::yaml::Hex64 FileOffsetToData;
77 llvm::yaml::Hex64 FileOffsetToRelocations;
78 llvm::yaml::Hex64 FileOffsetToLineNumbers; // Line number pointer. Not supported yet.
79 llvm::yaml::Hex16 NumberOfRelocations;
80 llvm::yaml::Hex16 NumberOfLineNumbers; // Line number counts. Not supported yet.
81 uint32_t Flags;
82 std::optional<XCOFF::DwarfSectionSubtypeFlags> SectionSubtype;
83 yaml::BinaryRef SectionData;
84 std::vector<Relocation> Relocations;
85 };
86
87 enum AuxSymbolType : uint8_t {
88 AUX_EXCEPT = 255,
89 AUX_FCN = 254,
90 AUX_SYM = 253,
91 AUX_FILE = 252,
92 AUX_CSECT = 251,
93 AUX_SECT = 250,
94 AUX_STAT = 249
95 };
96
97 struct AuxSymbolEnt {
98 AuxSymbolType Type;
99
AuxSymbolEntAuxSymbolEnt100 explicit AuxSymbolEnt(AuxSymbolType T) : Type(T) {}
101 virtual ~AuxSymbolEnt();
102 };
103
104 struct FileAuxEnt : AuxSymbolEnt {
105 std::optional<StringRef> FileNameOrString;
106 std::optional<XCOFF::CFileStringType> FileStringType;
107
FileAuxEntFileAuxEnt108 FileAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_FILE) {}
classofFileAuxEnt109 static bool classof(const AuxSymbolEnt *S) {
110 return S->Type == AuxSymbolType::AUX_FILE;
111 }
112 };
113
114 struct CsectAuxEnt : AuxSymbolEnt {
115 // Only for XCOFF32.
116 std::optional<uint32_t> SectionOrLength;
117 std::optional<uint32_t> StabInfoIndex;
118 std::optional<uint16_t> StabSectNum;
119 // Only for XCOFF64.
120 std::optional<uint32_t> SectionOrLengthLo;
121 std::optional<uint32_t> SectionOrLengthHi;
122 // Common fields for both XCOFF32 and XCOFF64.
123 std::optional<uint32_t> ParameterHashIndex;
124 std::optional<uint16_t> TypeChkSectNum;
125 std::optional<XCOFF::SymbolType> SymbolType;
126 std::optional<uint8_t> SymbolAlignment;
127 // The two previous values can be encoded as a single value.
128 std::optional<uint8_t> SymbolAlignmentAndType;
129 std::optional<XCOFF::StorageMappingClass> StorageMappingClass;
130
CsectAuxEntCsectAuxEnt131 CsectAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_CSECT) {}
classofCsectAuxEnt132 static bool classof(const AuxSymbolEnt *S) {
133 return S->Type == AuxSymbolType::AUX_CSECT;
134 }
135 };
136
137 struct FunctionAuxEnt : AuxSymbolEnt {
138 std::optional<uint32_t> OffsetToExceptionTbl; // Only for XCOFF32.
139 std::optional<uint64_t> PtrToLineNum;
140 std::optional<uint32_t> SizeOfFunction;
141 std::optional<int32_t> SymIdxOfNextBeyond;
142
FunctionAuxEntFunctionAuxEnt143 FunctionAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_FCN) {}
classofFunctionAuxEnt144 static bool classof(const AuxSymbolEnt *S) {
145 return S->Type == AuxSymbolType::AUX_FCN;
146 }
147 };
148
149 struct ExcpetionAuxEnt : AuxSymbolEnt {
150 std::optional<uint64_t> OffsetToExceptionTbl;
151 std::optional<uint32_t> SizeOfFunction;
152 std::optional<int32_t> SymIdxOfNextBeyond;
153
ExcpetionAuxEntExcpetionAuxEnt154 ExcpetionAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_EXCEPT) {}
classofExcpetionAuxEnt155 static bool classof(const AuxSymbolEnt *S) {
156 return S->Type == AuxSymbolType::AUX_EXCEPT;
157 }
158 }; // Only for XCOFF64.
159
160 struct BlockAuxEnt : AuxSymbolEnt {
161 // Only for XCOFF32.
162 std::optional<uint16_t> LineNumHi;
163 std::optional<uint16_t> LineNumLo;
164 // Only for XCOFF64.
165 std::optional<uint32_t> LineNum;
166
BlockAuxEntBlockAuxEnt167 BlockAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_SYM) {}
classofBlockAuxEnt168 static bool classof(const AuxSymbolEnt *S) {
169 return S->Type == AuxSymbolType::AUX_SYM;
170 }
171 };
172
173 struct SectAuxEntForDWARF : AuxSymbolEnt {
174 std::optional<uint32_t> LengthOfSectionPortion;
175 std::optional<uint32_t> NumberOfRelocEnt;
176
SectAuxEntForDWARFSectAuxEntForDWARF177 SectAuxEntForDWARF() : AuxSymbolEnt(AuxSymbolType::AUX_SECT) {}
classofSectAuxEntForDWARF178 static bool classof(const AuxSymbolEnt *S) {
179 return S->Type == AuxSymbolType::AUX_SECT;
180 }
181 };
182
183 struct SectAuxEntForStat : AuxSymbolEnt {
184 std::optional<uint32_t> SectionLength;
185 std::optional<uint16_t> NumberOfRelocEnt;
186 std::optional<uint16_t> NumberOfLineNum;
187
SectAuxEntForStatSectAuxEntForStat188 SectAuxEntForStat() : AuxSymbolEnt(AuxSymbolType::AUX_STAT) {}
classofSectAuxEntForStat189 static bool classof(const AuxSymbolEnt *S) {
190 return S->Type == AuxSymbolType::AUX_STAT;
191 }
192 }; // Only for XCOFF32.
193
194 struct Symbol {
195 StringRef SymbolName;
196 llvm::yaml::Hex64 Value; // Symbol value; storage class-dependent.
197 std::optional<StringRef> SectionName;
198 std::optional<uint16_t> SectionIndex;
199 llvm::yaml::Hex16 Type;
200 XCOFF::StorageClass StorageClass;
201 std::optional<uint8_t> NumberOfAuxEntries;
202 std::vector<std::unique_ptr<AuxSymbolEnt>> AuxEntries;
203 };
204
205 struct StringTable {
206 std::optional<uint32_t> ContentSize; // The total size of the string table.
207 std::optional<uint32_t> Length; // The value of the length field for the first
208 // 4 bytes of the table.
209 std::optional<std::vector<StringRef>> Strings;
210 std::optional<yaml::BinaryRef> RawContent;
211 };
212
213 struct Object {
214 FileHeader Header;
215 std::optional<AuxiliaryHeader> AuxHeader;
216 std::vector<Section> Sections;
217 std::vector<Symbol> Symbols;
218 StringTable StrTbl;
219 Object();
220 };
221 } // namespace XCOFFYAML
222 } // namespace llvm
223
224 LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Symbol)
LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Relocation)225 LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Relocation)
226 LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Section)
227 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::XCOFFYAML::AuxSymbolEnt>)
228
229 namespace llvm {
230 namespace yaml {
231
232 template <> struct ScalarBitSetTraits<XCOFF::SectionTypeFlags> {
233 static void bitset(IO &IO, XCOFF::SectionTypeFlags &Value);
234 };
235
236 template <> struct ScalarEnumerationTraits<XCOFF::DwarfSectionSubtypeFlags> {
237 static void enumeration(IO &IO, XCOFF::DwarfSectionSubtypeFlags &Value);
238 };
239
240 template <> struct ScalarEnumerationTraits<XCOFF::StorageClass> {
241 static void enumeration(IO &IO, XCOFF::StorageClass &Value);
242 };
243
244 template <> struct ScalarEnumerationTraits<XCOFF::StorageMappingClass> {
245 static void enumeration(IO &IO, XCOFF::StorageMappingClass &Value);
246 };
247
248 template <> struct ScalarEnumerationTraits<XCOFF::SymbolType> {
249 static void enumeration(IO &IO, XCOFF::SymbolType &Value);
250 };
251
252 template <> struct ScalarEnumerationTraits<XCOFF::CFileStringType> {
253 static void enumeration(IO &IO, XCOFF::CFileStringType &Type);
254 };
255
256 template <> struct ScalarEnumerationTraits<XCOFFYAML::AuxSymbolType> {
257 static void enumeration(IO &IO, XCOFFYAML::AuxSymbolType &Type);
258 };
259
260 template <> struct MappingTraits<XCOFFYAML::FileHeader> {
261 static void mapping(IO &IO, XCOFFYAML::FileHeader &H);
262 };
263
264 template <> struct MappingTraits<XCOFFYAML::AuxiliaryHeader> {
265 static void mapping(IO &IO, XCOFFYAML::AuxiliaryHeader &AuxHdr);
266 };
267
268 template <> struct MappingTraits<std::unique_ptr<XCOFFYAML::AuxSymbolEnt>> {
269 static void mapping(IO &IO, std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym);
270 };
271
272 template <> struct MappingTraits<XCOFFYAML::Symbol> {
273 static void mapping(IO &IO, XCOFFYAML::Symbol &S);
274 };
275
276 template <> struct MappingTraits<XCOFFYAML::Relocation> {
277 static void mapping(IO &IO, XCOFFYAML::Relocation &R);
278 };
279
280 template <> struct MappingTraits<XCOFFYAML::Section> {
281 static void mapping(IO &IO, XCOFFYAML::Section &Sec);
282 };
283
284 template <> struct MappingTraits<XCOFFYAML::StringTable> {
285 static void mapping(IO &IO, XCOFFYAML::StringTable &Str);
286 };
287
288 template <> struct MappingTraits<XCOFFYAML::Object> {
289 static void mapping(IO &IO, XCOFFYAML::Object &Obj);
290 };
291
292 } // namespace yaml
293 } // namespace llvm
294
295 #endif // LLVM_OBJECTYAML_XCOFFYAML_H
296