1 //===-- XCOFFYAML.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 //===----------------------------------------------------------------------===//
9 // This file defines classes for handling the YAML representation of XCOFF.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/ObjectYAML/XCOFFYAML.h"
14 #include "llvm/BinaryFormat/XCOFF.h"
20 Object::Object() { memset(&Header
, 0, sizeof(Header
)); }
22 AuxSymbolEnt::~AuxSymbolEnt() = default;
24 } // namespace XCOFFYAML
28 void ScalarBitSetTraits
<XCOFF::SectionTypeFlags
>::bitset(
29 IO
&IO
, XCOFF::SectionTypeFlags
&Value
) {
30 #define ECase(X) IO.bitSetCase(Value, #X, XCOFF::X)
47 void ScalarEnumerationTraits
<XCOFF::DwarfSectionSubtypeFlags
>::enumeration(
48 IO
&IO
, XCOFF::DwarfSectionSubtypeFlags
&Value
) {
49 #define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
50 ECase(SSUBTYP_DWINFO
);
51 ECase(SSUBTYP_DWLINE
);
52 ECase(SSUBTYP_DWPBNMS
);
53 ECase(SSUBTYP_DWPBTYP
);
54 ECase(SSUBTYP_DWARNGE
);
55 ECase(SSUBTYP_DWABREV
);
57 ECase(SSUBTYP_DWRNGES
);
59 ECase(SSUBTYP_DWFRAME
);
62 IO
.enumFallback
<Hex32
>(Value
);
65 void ScalarEnumerationTraits
<XCOFF::StorageClass
>::enumeration(
66 IO
&IO
, XCOFF::StorageClass
&Value
) {
67 #define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
121 void ScalarEnumerationTraits
<XCOFF::StorageMappingClass
>::enumeration(
122 IO
&IO
, XCOFF::StorageMappingClass
&Value
) {
123 #define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
148 void ScalarEnumerationTraits
<XCOFF::SymbolType
>::enumeration(
149 IO
&IO
, XCOFF::SymbolType
&Value
) {
150 #define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
156 IO
.enumFallback
<Hex8
>(Value
);
159 void ScalarEnumerationTraits
<XCOFFYAML::AuxSymbolType
>::enumeration(
160 IO
&IO
, XCOFFYAML::AuxSymbolType
&Type
) {
161 #define ECase(X) IO.enumCase(Type, #X, XCOFFYAML::X)
172 void ScalarEnumerationTraits
<XCOFF::CFileStringType
>::enumeration(
173 IO
&IO
, XCOFF::CFileStringType
&Type
) {
174 #define ECase(X) IO.enumCase(Type, #X, XCOFF::X)
182 struct NSectionFlags
{
183 NSectionFlags(IO
&) : Flags(XCOFF::SectionTypeFlags(0)) {}
184 NSectionFlags(IO
&, uint32_t C
) : Flags(XCOFF::SectionTypeFlags(C
)) {}
186 uint32_t denormalize(IO
&) { return Flags
; }
188 XCOFF::SectionTypeFlags Flags
;
191 void MappingTraits
<XCOFFYAML::FileHeader
>::mapping(
192 IO
&IO
, XCOFFYAML::FileHeader
&FileHdr
) {
193 IO
.mapOptional("MagicNumber", FileHdr
.Magic
);
194 IO
.mapOptional("NumberOfSections", FileHdr
.NumberOfSections
);
195 IO
.mapOptional("CreationTime", FileHdr
.TimeStamp
);
196 IO
.mapOptional("OffsetToSymbolTable", FileHdr
.SymbolTableOffset
);
197 IO
.mapOptional("EntriesInSymbolTable", FileHdr
.NumberOfSymTableEntries
);
198 IO
.mapOptional("AuxiliaryHeaderSize", FileHdr
.AuxHeaderSize
);
199 IO
.mapOptional("Flags", FileHdr
.Flags
);
202 void MappingTraits
<XCOFFYAML::AuxiliaryHeader
>::mapping(
203 IO
&IO
, XCOFFYAML::AuxiliaryHeader
&AuxHdr
) {
204 IO
.mapOptional("Magic", AuxHdr
.Magic
);
205 IO
.mapOptional("Version", AuxHdr
.Version
);
206 IO
.mapOptional("TextStartAddr", AuxHdr
.TextStartAddr
);
207 IO
.mapOptional("DataStartAddr", AuxHdr
.DataStartAddr
);
208 IO
.mapOptional("TOCAnchorAddr", AuxHdr
.TOCAnchorAddr
);
209 IO
.mapOptional("TextSectionSize", AuxHdr
.TextSize
);
210 IO
.mapOptional("DataSectionSize", AuxHdr
.InitDataSize
);
211 IO
.mapOptional("BssSectionSize", AuxHdr
.BssDataSize
);
212 IO
.mapOptional("SecNumOfEntryPoint", AuxHdr
.SecNumOfEntryPoint
);
213 IO
.mapOptional("SecNumOfText", AuxHdr
.SecNumOfText
);
214 IO
.mapOptional("SecNumOfData", AuxHdr
.SecNumOfData
);
215 IO
.mapOptional("SecNumOfTOC", AuxHdr
.SecNumOfTOC
);
216 IO
.mapOptional("SecNumOfLoader", AuxHdr
.SecNumOfLoader
);
217 IO
.mapOptional("SecNumOfBSS", AuxHdr
.SecNumOfBSS
);
218 IO
.mapOptional("MaxAlignOfText", AuxHdr
.MaxAlignOfText
);
219 IO
.mapOptional("MaxAlignOfData", AuxHdr
.MaxAlignOfData
);
220 IO
.mapOptional("ModuleType", AuxHdr
.CpuFlag
);
221 IO
.mapOptional("TextPageSize", AuxHdr
.TextPageSize
);
222 IO
.mapOptional("DataPageSize", AuxHdr
.DataPageSize
);
223 IO
.mapOptional("StackPageSize", AuxHdr
.StackPageSize
);
224 IO
.mapOptional("FlagAndTDataAlignment", AuxHdr
.FlagAndTDataAlignment
);
225 IO
.mapOptional("EntryPointAddr", AuxHdr
.EntryPointAddr
);
226 IO
.mapOptional("MaxStackSize", AuxHdr
.MaxStackSize
);
227 IO
.mapOptional("MaxDataSize", AuxHdr
.MaxDataSize
);
228 IO
.mapOptional("SecNumOfTData", AuxHdr
.SecNumOfTData
);
229 IO
.mapOptional("SecNumOfTBSS", AuxHdr
.SecNumOfTBSS
);
230 IO
.mapOptional("Flag", AuxHdr
.Flag
);
233 void MappingTraits
<XCOFFYAML::Relocation
>::mapping(IO
&IO
,
234 XCOFFYAML::Relocation
&R
) {
235 IO
.mapOptional("Address", R
.VirtualAddress
);
236 IO
.mapOptional("Symbol", R
.SymbolIndex
);
237 IO
.mapOptional("Info", R
.Info
);
238 IO
.mapOptional("Type", R
.Type
);
241 void MappingTraits
<XCOFFYAML::Section
>::mapping(IO
&IO
,
242 XCOFFYAML::Section
&Sec
) {
243 MappingNormalization
<NSectionFlags
, uint32_t> NC(IO
, Sec
.Flags
);
244 IO
.mapOptional("Name", Sec
.SectionName
);
245 IO
.mapOptional("Address", Sec
.Address
);
246 IO
.mapOptional("Size", Sec
.Size
);
247 IO
.mapOptional("FileOffsetToData", Sec
.FileOffsetToData
);
248 IO
.mapOptional("FileOffsetToRelocations", Sec
.FileOffsetToRelocations
);
249 IO
.mapOptional("FileOffsetToLineNumbers", Sec
.FileOffsetToLineNumbers
);
250 IO
.mapOptional("NumberOfRelocations", Sec
.NumberOfRelocations
);
251 IO
.mapOptional("NumberOfLineNumbers", Sec
.NumberOfLineNumbers
);
252 IO
.mapOptional("Flags", NC
->Flags
);
253 IO
.mapOptional("DWARFSectionSubtype", Sec
.SectionSubtype
);
254 IO
.mapOptional("SectionData", Sec
.SectionData
);
255 IO
.mapOptional("Relocations", Sec
.Relocations
);
258 static void auxSymMapping(IO
&IO
, XCOFFYAML::CsectAuxEnt
&AuxSym
, bool Is64
) {
259 IO
.mapOptional("ParameterHashIndex", AuxSym
.ParameterHashIndex
);
260 IO
.mapOptional("TypeChkSectNum", AuxSym
.TypeChkSectNum
);
261 IO
.mapOptional("SymbolAlignmentAndType", AuxSym
.SymbolAlignmentAndType
);
262 IO
.mapOptional("SymbolType", AuxSym
.SymbolType
);
263 IO
.mapOptional("SymbolAlignment", AuxSym
.SymbolAlignment
);
264 IO
.mapOptional("StorageMappingClass", AuxSym
.StorageMappingClass
);
266 IO
.mapOptional("SectionOrLengthLo", AuxSym
.SectionOrLengthLo
);
267 IO
.mapOptional("SectionOrLengthHi", AuxSym
.SectionOrLengthHi
);
269 IO
.mapOptional("SectionOrLength", AuxSym
.SectionOrLength
);
270 IO
.mapOptional("StabInfoIndex", AuxSym
.StabInfoIndex
);
271 IO
.mapOptional("StabSectNum", AuxSym
.StabSectNum
);
275 static void auxSymMapping(IO
&IO
, XCOFFYAML::FileAuxEnt
&AuxSym
) {
276 IO
.mapOptional("FileNameOrString", AuxSym
.FileNameOrString
);
277 IO
.mapOptional("FileStringType", AuxSym
.FileStringType
);
280 static void auxSymMapping(IO
&IO
, XCOFFYAML::BlockAuxEnt
&AuxSym
, bool Is64
) {
282 IO
.mapOptional("LineNum", AuxSym
.LineNum
);
284 IO
.mapOptional("LineNumHi", AuxSym
.LineNumHi
);
285 IO
.mapOptional("LineNumLo", AuxSym
.LineNumLo
);
289 static void auxSymMapping(IO
&IO
, XCOFFYAML::FunctionAuxEnt
&AuxSym
,
292 IO
.mapOptional("OffsetToExceptionTbl", AuxSym
.OffsetToExceptionTbl
);
293 IO
.mapOptional("SizeOfFunction", AuxSym
.SizeOfFunction
);
294 IO
.mapOptional("SymIdxOfNextBeyond", AuxSym
.SymIdxOfNextBeyond
);
295 IO
.mapOptional("PtrToLineNum", AuxSym
.PtrToLineNum
);
298 static void auxSymMapping(IO
&IO
, XCOFFYAML::ExcpetionAuxEnt
&AuxSym
) {
299 IO
.mapOptional("OffsetToExceptionTbl", AuxSym
.OffsetToExceptionTbl
);
300 IO
.mapOptional("SizeOfFunction", AuxSym
.SizeOfFunction
);
301 IO
.mapOptional("SymIdxOfNextBeyond", AuxSym
.SymIdxOfNextBeyond
);
304 static void auxSymMapping(IO
&IO
, XCOFFYAML::SectAuxEntForDWARF
&AuxSym
) {
305 IO
.mapOptional("LengthOfSectionPortion", AuxSym
.LengthOfSectionPortion
);
306 IO
.mapOptional("NumberOfRelocEnt", AuxSym
.NumberOfRelocEnt
);
309 static void auxSymMapping(IO
&IO
, XCOFFYAML::SectAuxEntForStat
&AuxSym
) {
310 IO
.mapOptional("SectionLength", AuxSym
.SectionLength
);
311 IO
.mapOptional("NumberOfRelocEnt", AuxSym
.NumberOfRelocEnt
);
312 IO
.mapOptional("NumberOfLineNum", AuxSym
.NumberOfLineNum
);
315 template <typename AuxEntT
>
316 static void ResetAuxSym(IO
&IO
,
317 std::unique_ptr
<XCOFFYAML::AuxSymbolEnt
> &AuxSym
) {
318 if (!IO
.outputting())
319 AuxSym
.reset(new AuxEntT
);
322 void MappingTraits
<std::unique_ptr
<XCOFFYAML::AuxSymbolEnt
>>::mapping(
323 IO
&IO
, std::unique_ptr
<XCOFFYAML::AuxSymbolEnt
> &AuxSym
) {
325 static_cast<XCOFFYAML::Object
*>(IO
.getContext())->Header
.Magic
==
326 (llvm::yaml::Hex16
)XCOFF::XCOFF64
;
328 XCOFFYAML::AuxSymbolType AuxType
;
330 AuxType
= AuxSym
.get()->Type
;
331 IO
.mapRequired("Type", AuxType
);
333 case XCOFFYAML::AUX_EXCEPT
:
335 IO
.setError("an auxiliary symbol of type AUX_EXCEPT cannot be defined in "
339 ResetAuxSym
<XCOFFYAML::ExcpetionAuxEnt
>(IO
, AuxSym
);
340 auxSymMapping(IO
, *cast
<XCOFFYAML::ExcpetionAuxEnt
>(AuxSym
.get()));
342 case XCOFFYAML::AUX_FCN
:
343 ResetAuxSym
<XCOFFYAML::FunctionAuxEnt
>(IO
, AuxSym
);
344 auxSymMapping(IO
, *cast
<XCOFFYAML::FunctionAuxEnt
>(AuxSym
.get()), Is64
);
346 case XCOFFYAML::AUX_SYM
:
347 ResetAuxSym
<XCOFFYAML::BlockAuxEnt
>(IO
, AuxSym
);
348 auxSymMapping(IO
, *cast
<XCOFFYAML::BlockAuxEnt
>(AuxSym
.get()), Is64
);
350 case XCOFFYAML::AUX_FILE
:
351 ResetAuxSym
<XCOFFYAML::FileAuxEnt
>(IO
, AuxSym
);
352 auxSymMapping(IO
, *cast
<XCOFFYAML::FileAuxEnt
>(AuxSym
.get()));
354 case XCOFFYAML::AUX_CSECT
:
355 ResetAuxSym
<XCOFFYAML::CsectAuxEnt
>(IO
, AuxSym
);
356 auxSymMapping(IO
, *cast
<XCOFFYAML::CsectAuxEnt
>(AuxSym
.get()), Is64
);
358 case XCOFFYAML::AUX_SECT
:
359 ResetAuxSym
<XCOFFYAML::SectAuxEntForDWARF
>(IO
, AuxSym
);
360 auxSymMapping(IO
, *cast
<XCOFFYAML::SectAuxEntForDWARF
>(AuxSym
.get()));
362 case XCOFFYAML::AUX_STAT
:
365 "an auxiliary symbol of type AUX_STAT cannot be defined in XCOFF64");
368 ResetAuxSym
<XCOFFYAML::SectAuxEntForStat
>(IO
, AuxSym
);
369 auxSymMapping(IO
, *cast
<XCOFFYAML::SectAuxEntForStat
>(AuxSym
.get()));
374 void MappingTraits
<XCOFFYAML::Symbol
>::mapping(IO
&IO
, XCOFFYAML::Symbol
&S
) {
375 IO
.mapOptional("Name", S
.SymbolName
);
376 IO
.mapOptional("Value", S
.Value
);
377 IO
.mapOptional("Section", S
.SectionName
);
378 IO
.mapOptional("SectionIndex", S
.SectionIndex
);
379 IO
.mapOptional("Type", S
.Type
);
380 IO
.mapOptional("StorageClass", S
.StorageClass
);
381 IO
.mapOptional("NumberOfAuxEntries", S
.NumberOfAuxEntries
);
382 IO
.mapOptional("AuxEntries", S
.AuxEntries
);
385 void MappingTraits
<XCOFFYAML::StringTable
>::mapping(
386 IO
&IO
, XCOFFYAML::StringTable
&Str
) {
387 IO
.mapOptional("ContentSize", Str
.ContentSize
);
388 IO
.mapOptional("Length", Str
.Length
);
389 IO
.mapOptional("Strings", Str
.Strings
);
390 IO
.mapOptional("RawContent", Str
.RawContent
);
393 void MappingTraits
<XCOFFYAML::Object
>::mapping(IO
&IO
, XCOFFYAML::Object
&Obj
) {
395 IO
.mapTag("!XCOFF", true);
396 IO
.mapRequired("FileHeader", Obj
.Header
);
397 IO
.mapOptional("AuxiliaryHeader", Obj
.AuxHeader
);
398 IO
.mapOptional("Sections", Obj
.Sections
);
399 IO
.mapOptional("Symbols", Obj
.Symbols
);
400 IO
.mapOptional("StringTable", Obj
.StrTbl
);
401 IO
.setContext(nullptr);