xref: /freebsd-src/contrib/llvm-project/llvm/include/llvm/Object/XCOFFObjectFile.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- XCOFFObjectFile.h - XCOFF object file implementation -----*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file declares the XCOFFObjectFile class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_OBJECT_XCOFFOBJECTFILE_H
140b57cec5SDimitry Andric #define LLVM_OBJECT_XCOFFOBJECTFILE_H
150b57cec5SDimitry Andric 
16e8d8bef9SDimitry Andric #include "llvm/ADT/SmallString.h"
17e8d8bef9SDimitry Andric #include "llvm/ADT/SmallVector.h"
185f757f3fSDimitry Andric #include "llvm/ADT/iterator_range.h"
190b57cec5SDimitry Andric #include "llvm/BinaryFormat/XCOFF.h"
200b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h"
215ffd83dbSDimitry Andric #include "llvm/Support/Endian.h"
225ffd83dbSDimitry Andric #include <limits>
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric namespace llvm {
250b57cec5SDimitry Andric namespace object {
260b57cec5SDimitry Andric 
275f757f3fSDimitry Andric class xcoff_symbol_iterator;
285f757f3fSDimitry Andric 
290b57cec5SDimitry Andric struct XCOFFFileHeader32 {
300b57cec5SDimitry Andric   support::ubig16_t Magic;
310b57cec5SDimitry Andric   support::ubig16_t NumberOfSections;
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric   // Unix time value, value of 0 indicates no timestamp.
340b57cec5SDimitry Andric   // Negative values are reserved.
350b57cec5SDimitry Andric   support::big32_t TimeStamp;
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric   support::ubig32_t SymbolTableOffset; // File offset to symbol table.
380b57cec5SDimitry Andric   support::big32_t NumberOfSymTableEntries;
390b57cec5SDimitry Andric   support::ubig16_t AuxHeaderSize;
400b57cec5SDimitry Andric   support::ubig16_t Flags;
410b57cec5SDimitry Andric };
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric struct XCOFFFileHeader64 {
440b57cec5SDimitry Andric   support::ubig16_t Magic;
450b57cec5SDimitry Andric   support::ubig16_t NumberOfSections;
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric   // Unix time value, value of 0 indicates no timestamp.
480b57cec5SDimitry Andric   // Negative values are reserved.
490b57cec5SDimitry Andric   support::big32_t TimeStamp;
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   support::ubig64_t SymbolTableOffset; // File offset to symbol table.
520b57cec5SDimitry Andric   support::ubig16_t AuxHeaderSize;
530b57cec5SDimitry Andric   support::ubig16_t Flags;
540b57cec5SDimitry Andric   support::ubig32_t NumberOfSymTableEntries;
550b57cec5SDimitry Andric };
560b57cec5SDimitry Andric 
57349cc55cSDimitry Andric template <typename T> struct XCOFFAuxiliaryHeader {
58349cc55cSDimitry Andric   static constexpr uint8_t AuxiHeaderFlagMask = 0xF0;
59349cc55cSDimitry Andric   static constexpr uint8_t AuxiHeaderTDataAlignmentMask = 0x0F;
60349cc55cSDimitry Andric 
61349cc55cSDimitry Andric public:
62349cc55cSDimitry Andric   uint8_t getFlag() const {
63349cc55cSDimitry Andric     return static_cast<const T *>(this)->FlagAndTDataAlignment &
64349cc55cSDimitry Andric            AuxiHeaderFlagMask;
65349cc55cSDimitry Andric   }
6681ad6265SDimitry Andric 
67349cc55cSDimitry Andric   uint8_t getTDataAlignment() const {
68349cc55cSDimitry Andric     return static_cast<const T *>(this)->FlagAndTDataAlignment &
69349cc55cSDimitry Andric            AuxiHeaderTDataAlignmentMask;
70349cc55cSDimitry Andric   }
7181ad6265SDimitry Andric 
7281ad6265SDimitry Andric   uint16_t getVersion() const { return static_cast<const T *>(this)->Version; }
73*0fca6ea1SDimitry Andric   uint64_t getEntryPointAddr() const {
74*0fca6ea1SDimitry Andric     return static_cast<const T *>(this)->EntryPointAddr;
75*0fca6ea1SDimitry Andric   }
76349cc55cSDimitry Andric };
77349cc55cSDimitry Andric 
78349cc55cSDimitry Andric struct XCOFFAuxiliaryHeader32 : XCOFFAuxiliaryHeader<XCOFFAuxiliaryHeader32> {
79349cc55cSDimitry Andric   support::ubig16_t
80349cc55cSDimitry Andric       AuxMagic; ///< If the value of the o_vstamp field is greater than 1, the
81349cc55cSDimitry Andric                 ///< o_mflags field is reserved for future use and it should
82349cc55cSDimitry Andric                 ///< contain 0. Otherwise, this field is not used.
83349cc55cSDimitry Andric   support::ubig16_t
84349cc55cSDimitry Andric       Version; ///< The valid values are 1 and 2. When the o_vstamp field is 2
85349cc55cSDimitry Andric                ///< in an XCOFF32 file, the new interpretation of the n_type
86349cc55cSDimitry Andric                ///< field in the symbol table entry is used.
87349cc55cSDimitry Andric   support::ubig32_t TextSize;
88349cc55cSDimitry Andric   support::ubig32_t InitDataSize;
89349cc55cSDimitry Andric   support::ubig32_t BssDataSize;
90349cc55cSDimitry Andric   support::ubig32_t EntryPointAddr;
91349cc55cSDimitry Andric   support::ubig32_t TextStartAddr;
92349cc55cSDimitry Andric   support::ubig32_t DataStartAddr;
93349cc55cSDimitry Andric   support::ubig32_t TOCAnchorAddr;
94349cc55cSDimitry Andric   support::ubig16_t SecNumOfEntryPoint;
95349cc55cSDimitry Andric   support::ubig16_t SecNumOfText;
96349cc55cSDimitry Andric   support::ubig16_t SecNumOfData;
97349cc55cSDimitry Andric   support::ubig16_t SecNumOfTOC;
98349cc55cSDimitry Andric   support::ubig16_t SecNumOfLoader;
99349cc55cSDimitry Andric   support::ubig16_t SecNumOfBSS;
100349cc55cSDimitry Andric   support::ubig16_t MaxAlignOfText;
101349cc55cSDimitry Andric   support::ubig16_t MaxAlignOfData;
102349cc55cSDimitry Andric   support::ubig16_t ModuleType;
103349cc55cSDimitry Andric   uint8_t CpuFlag;
104349cc55cSDimitry Andric   uint8_t CpuType;
105349cc55cSDimitry Andric   support::ubig32_t MaxStackSize; ///< If the value is 0, the system default
106349cc55cSDimitry Andric                                   ///< maximum stack size is used.
107349cc55cSDimitry Andric   support::ubig32_t MaxDataSize;  ///< If the value is 0, the system default
108349cc55cSDimitry Andric                                   ///< maximum data size is used.
109349cc55cSDimitry Andric   support::ubig32_t
110349cc55cSDimitry Andric       ReservedForDebugger; ///< This field should contain 0. When a loaded
111349cc55cSDimitry Andric                            ///< program is being debugged, the memory image of
112349cc55cSDimitry Andric                            ///< this field may be modified by a debugger to
113349cc55cSDimitry Andric                            ///< insert a trap instruction.
114349cc55cSDimitry Andric   uint8_t TextPageSize;  ///< Specifies the size of pages for the exec text. The
115349cc55cSDimitry Andric                          ///< default value is 0 (system-selected page size).
116349cc55cSDimitry Andric   uint8_t DataPageSize;  ///< Specifies the size of pages for the exec data. The
117349cc55cSDimitry Andric                          ///< default value is 0 (system-selected page size).
118349cc55cSDimitry Andric   uint8_t StackPageSize; ///< Specifies the size of pages for the stack. The
119349cc55cSDimitry Andric                          ///< default value is 0 (system-selected page size).
120349cc55cSDimitry Andric   uint8_t FlagAndTDataAlignment;
121349cc55cSDimitry Andric   support::ubig16_t SecNumOfTData;
122349cc55cSDimitry Andric   support::ubig16_t SecNumOfTBSS;
123349cc55cSDimitry Andric };
124349cc55cSDimitry Andric 
12581ad6265SDimitry Andric struct XCOFFAuxiliaryHeader64 : XCOFFAuxiliaryHeader<XCOFFAuxiliaryHeader64> {
126349cc55cSDimitry Andric   support::ubig16_t AuxMagic;
127349cc55cSDimitry Andric   support::ubig16_t Version;
128349cc55cSDimitry Andric   support::ubig32_t ReservedForDebugger;
129349cc55cSDimitry Andric   support::ubig64_t TextStartAddr;
130349cc55cSDimitry Andric   support::ubig64_t DataStartAddr;
131349cc55cSDimitry Andric   support::ubig64_t TOCAnchorAddr;
132349cc55cSDimitry Andric   support::ubig16_t SecNumOfEntryPoint;
133349cc55cSDimitry Andric   support::ubig16_t SecNumOfText;
134349cc55cSDimitry Andric   support::ubig16_t SecNumOfData;
135349cc55cSDimitry Andric   support::ubig16_t SecNumOfTOC;
136349cc55cSDimitry Andric   support::ubig16_t SecNumOfLoader;
137349cc55cSDimitry Andric   support::ubig16_t SecNumOfBSS;
138349cc55cSDimitry Andric   support::ubig16_t MaxAlignOfText;
139349cc55cSDimitry Andric   support::ubig16_t MaxAlignOfData;
140349cc55cSDimitry Andric   support::ubig16_t ModuleType;
141349cc55cSDimitry Andric   uint8_t CpuFlag;
142349cc55cSDimitry Andric   uint8_t CpuType;
143349cc55cSDimitry Andric   uint8_t TextPageSize;
144349cc55cSDimitry Andric   uint8_t DataPageSize;
145349cc55cSDimitry Andric   uint8_t StackPageSize;
146349cc55cSDimitry Andric   uint8_t FlagAndTDataAlignment;
147349cc55cSDimitry Andric   support::ubig64_t TextSize;
148349cc55cSDimitry Andric   support::ubig64_t InitDataSize;
149349cc55cSDimitry Andric   support::ubig64_t BssDataSize;
150349cc55cSDimitry Andric   support::ubig64_t EntryPointAddr;
151349cc55cSDimitry Andric   support::ubig64_t MaxStackSize;
152349cc55cSDimitry Andric   support::ubig64_t MaxDataSize;
153349cc55cSDimitry Andric   support::ubig16_t SecNumOfTData;
154349cc55cSDimitry Andric   support::ubig16_t SecNumOfTBSS;
155349cc55cSDimitry Andric   support::ubig16_t XCOFF64Flag;
156349cc55cSDimitry Andric };
157349cc55cSDimitry Andric 
158480093f4SDimitry Andric template <typename T> struct XCOFFSectionHeader {
159*0fca6ea1SDimitry Andric   // The section flags definitions are the same in both 32- and 64-bit objects.
160480093f4SDimitry Andric   //  Least significant 3 bits are reserved.
161480093f4SDimitry Andric   static constexpr unsigned SectionFlagsReservedMask = 0x7;
162480093f4SDimitry Andric 
163480093f4SDimitry Andric   // The low order 16 bits of section flags denotes the section type.
164*0fca6ea1SDimitry Andric   // The high order 16 bits of section flags denotes the section subtype.
165*0fca6ea1SDimitry Andric   // For now, this is only used for DWARF sections.
166480093f4SDimitry Andric   static constexpr unsigned SectionFlagsTypeMask = 0xffffu;
167480093f4SDimitry Andric 
168480093f4SDimitry Andric public:
169480093f4SDimitry Andric   StringRef getName() const;
170480093f4SDimitry Andric   uint16_t getSectionType() const;
171*0fca6ea1SDimitry Andric   uint32_t getSectionSubtype() const;
172480093f4SDimitry Andric   bool isReservedSectionType() const;
173480093f4SDimitry Andric };
174480093f4SDimitry Andric 
175480093f4SDimitry Andric // Explicit extern template declarations.
176480093f4SDimitry Andric struct XCOFFSectionHeader32;
177480093f4SDimitry Andric struct XCOFFSectionHeader64;
178480093f4SDimitry Andric extern template struct XCOFFSectionHeader<XCOFFSectionHeader32>;
179480093f4SDimitry Andric extern template struct XCOFFSectionHeader<XCOFFSectionHeader64>;
180480093f4SDimitry Andric 
181480093f4SDimitry Andric struct XCOFFSectionHeader32 : XCOFFSectionHeader<XCOFFSectionHeader32> {
1828bcb0991SDimitry Andric   char Name[XCOFF::NameSize];
1830b57cec5SDimitry Andric   support::ubig32_t PhysicalAddress;
1840b57cec5SDimitry Andric   support::ubig32_t VirtualAddress;
1850b57cec5SDimitry Andric   support::ubig32_t SectionSize;
1860b57cec5SDimitry Andric   support::ubig32_t FileOffsetToRawData;
1870b57cec5SDimitry Andric   support::ubig32_t FileOffsetToRelocationInfo;
1880b57cec5SDimitry Andric   support::ubig32_t FileOffsetToLineNumberInfo;
1890b57cec5SDimitry Andric   support::ubig16_t NumberOfRelocations;
1900b57cec5SDimitry Andric   support::ubig16_t NumberOfLineNumbers;
1910b57cec5SDimitry Andric   support::big32_t Flags;
1920b57cec5SDimitry Andric };
1930b57cec5SDimitry Andric 
194480093f4SDimitry Andric struct XCOFFSectionHeader64 : XCOFFSectionHeader<XCOFFSectionHeader64> {
1958bcb0991SDimitry Andric   char Name[XCOFF::NameSize];
1960b57cec5SDimitry Andric   support::ubig64_t PhysicalAddress;
1970b57cec5SDimitry Andric   support::ubig64_t VirtualAddress;
1980b57cec5SDimitry Andric   support::ubig64_t SectionSize;
1990b57cec5SDimitry Andric   support::big64_t FileOffsetToRawData;
2000b57cec5SDimitry Andric   support::big64_t FileOffsetToRelocationInfo;
2010b57cec5SDimitry Andric   support::big64_t FileOffsetToLineNumberInfo;
2020b57cec5SDimitry Andric   support::ubig32_t NumberOfRelocations;
2030b57cec5SDimitry Andric   support::ubig32_t NumberOfLineNumbers;
2040b57cec5SDimitry Andric   support::big32_t Flags;
2050b57cec5SDimitry Andric   char Padding[4];
2060b57cec5SDimitry Andric };
2070b57cec5SDimitry Andric 
208bdd1243dSDimitry Andric struct LoaderSectionHeader32;
209bdd1243dSDimitry Andric struct LoaderSectionHeader64;
210bdd1243dSDimitry Andric struct LoaderSectionSymbolEntry32 {
211bdd1243dSDimitry Andric   struct NameOffsetInStrTbl {
212bdd1243dSDimitry Andric     support::big32_t IsNameInStrTbl; // Zero indicates name in string table.
213bdd1243dSDimitry Andric     support::ubig32_t Offset;
214bdd1243dSDimitry Andric   };
215bdd1243dSDimitry Andric 
216bdd1243dSDimitry Andric   char SymbolName[XCOFF::NameSize];
217bdd1243dSDimitry Andric   support::ubig32_t Value; // The virtual address of the symbol.
218bdd1243dSDimitry Andric   support::big16_t SectionNumber;
219bdd1243dSDimitry Andric   uint8_t SymbolType;
220bdd1243dSDimitry Andric   XCOFF::StorageClass StorageClass;
221bdd1243dSDimitry Andric   support::ubig32_t ImportFileID;
222bdd1243dSDimitry Andric   support::ubig32_t ParameterTypeCheck;
223bdd1243dSDimitry Andric 
224bdd1243dSDimitry Andric   Expected<StringRef>
225bdd1243dSDimitry Andric   getSymbolName(const LoaderSectionHeader32 *LoaderSecHeader) const;
226bdd1243dSDimitry Andric };
227bdd1243dSDimitry Andric 
228bdd1243dSDimitry Andric struct LoaderSectionSymbolEntry64 {
229bdd1243dSDimitry Andric   support::ubig64_t Value; // The virtual address of the symbol.
230bdd1243dSDimitry Andric   support::ubig32_t Offset;
231bdd1243dSDimitry Andric   support::big16_t SectionNumber;
232bdd1243dSDimitry Andric   uint8_t SymbolType;
233bdd1243dSDimitry Andric   XCOFF::StorageClass StorageClass;
234bdd1243dSDimitry Andric   support::ubig32_t ImportFileID;
235bdd1243dSDimitry Andric   support::ubig32_t ParameterTypeCheck;
236bdd1243dSDimitry Andric 
237bdd1243dSDimitry Andric   Expected<StringRef>
238bdd1243dSDimitry Andric   getSymbolName(const LoaderSectionHeader64 *LoaderSecHeader) const;
239bdd1243dSDimitry Andric };
240bdd1243dSDimitry Andric 
241bdd1243dSDimitry Andric struct LoaderSectionRelocationEntry32 {
242bdd1243dSDimitry Andric   support::ubig32_t VirtualAddr;
243bdd1243dSDimitry Andric   support::big32_t SymbolIndex;
244bdd1243dSDimitry Andric   support::ubig16_t Type;
245bdd1243dSDimitry Andric   support::big16_t SectionNum;
246bdd1243dSDimitry Andric };
247bdd1243dSDimitry Andric 
248bdd1243dSDimitry Andric struct LoaderSectionRelocationEntry64 {
249bdd1243dSDimitry Andric   support::ubig64_t VirtualAddr;
250bdd1243dSDimitry Andric   support::ubig16_t Type;
251bdd1243dSDimitry Andric   support::big16_t SectionNum;
252bdd1243dSDimitry Andric   support::big32_t SymbolIndex;
253bdd1243dSDimitry Andric };
254bdd1243dSDimitry Andric 
255349cc55cSDimitry Andric struct LoaderSectionHeader32 {
256349cc55cSDimitry Andric   support::ubig32_t Version;
257349cc55cSDimitry Andric   support::ubig32_t NumberOfSymTabEnt;
258349cc55cSDimitry Andric   support::ubig32_t NumberOfRelTabEnt;
259349cc55cSDimitry Andric   support::ubig32_t LengthOfImpidStrTbl;
260349cc55cSDimitry Andric   support::ubig32_t NumberOfImpid;
261349cc55cSDimitry Andric   support::big32_t OffsetToImpid;
262349cc55cSDimitry Andric   support::ubig32_t LengthOfStrTbl;
263349cc55cSDimitry Andric   support::big32_t OffsetToStrTbl;
264bdd1243dSDimitry Andric 
265bdd1243dSDimitry Andric   uint64_t getOffsetToSymTbl() const {
266bdd1243dSDimitry Andric     return NumberOfSymTabEnt == 0 ? 0 : sizeof(LoaderSectionHeader32);
267bdd1243dSDimitry Andric   }
268bdd1243dSDimitry Andric 
269bdd1243dSDimitry Andric   uint64_t getOffsetToRelEnt() const {
270bdd1243dSDimitry Andric     // Relocation table is after Symbol table.
271bdd1243dSDimitry Andric     return NumberOfRelTabEnt == 0
272bdd1243dSDimitry Andric                ? 0
273bdd1243dSDimitry Andric                : sizeof(LoaderSectionHeader32) +
274bdd1243dSDimitry Andric                      sizeof(LoaderSectionSymbolEntry32) * NumberOfSymTabEnt;
275bdd1243dSDimitry Andric   }
276349cc55cSDimitry Andric };
277349cc55cSDimitry Andric 
278349cc55cSDimitry Andric struct LoaderSectionHeader64 {
279349cc55cSDimitry Andric   support::ubig32_t Version;
280349cc55cSDimitry Andric   support::ubig32_t NumberOfSymTabEnt;
281349cc55cSDimitry Andric   support::ubig32_t NumberOfRelTabEnt;
282349cc55cSDimitry Andric   support::ubig32_t LengthOfImpidStrTbl;
283349cc55cSDimitry Andric   support::ubig32_t NumberOfImpid;
284349cc55cSDimitry Andric   support::ubig32_t LengthOfStrTbl;
285349cc55cSDimitry Andric   support::big64_t OffsetToImpid;
286349cc55cSDimitry Andric   support::big64_t OffsetToStrTbl;
287349cc55cSDimitry Andric   support::big64_t OffsetToSymTbl;
288bdd1243dSDimitry Andric   support::big64_t OffsetToRelEnt;
289bdd1243dSDimitry Andric 
290bdd1243dSDimitry Andric   uint64_t getOffsetToSymTbl() const { return OffsetToSymTbl; }
291bdd1243dSDimitry Andric   uint64_t getOffsetToRelEnt() const { return OffsetToRelEnt; }
292349cc55cSDimitry Andric };
293349cc55cSDimitry Andric 
294bdd1243dSDimitry Andric template <typename AddressType> struct ExceptionSectionEntry {
295bdd1243dSDimitry Andric   union {
296bdd1243dSDimitry Andric     support::ubig32_t SymbolIdx;
297bdd1243dSDimitry Andric     AddressType TrapInstAddr;
298bdd1243dSDimitry Andric   };
299bdd1243dSDimitry Andric   uint8_t LangId;
300bdd1243dSDimitry Andric   uint8_t Reason;
301bdd1243dSDimitry Andric 
302bdd1243dSDimitry Andric   uint32_t getSymbolIndex() const {
303bdd1243dSDimitry Andric     assert(Reason == 0 && "Get symbol table index of the function only when "
304bdd1243dSDimitry Andric                           "the e_reason field is 0.");
305bdd1243dSDimitry Andric     return SymbolIdx;
306bdd1243dSDimitry Andric   }
307bdd1243dSDimitry Andric 
308bdd1243dSDimitry Andric   uint64_t getTrapInstAddr() const {
309bdd1243dSDimitry Andric     assert(Reason != 0 && "Zero is not a valid trap exception reason code.");
310bdd1243dSDimitry Andric     return TrapInstAddr;
311bdd1243dSDimitry Andric   }
312bdd1243dSDimitry Andric   uint8_t getLangID() const { return LangId; }
313bdd1243dSDimitry Andric   uint8_t getReason() const { return Reason; }
314bdd1243dSDimitry Andric };
315bdd1243dSDimitry Andric 
316bdd1243dSDimitry Andric typedef ExceptionSectionEntry<support::ubig32_t> ExceptionSectionEntry32;
317bdd1243dSDimitry Andric typedef ExceptionSectionEntry<support::ubig64_t> ExceptionSectionEntry64;
318bdd1243dSDimitry Andric 
319bdd1243dSDimitry Andric // Explicit extern template declarations.
320bdd1243dSDimitry Andric extern template struct ExceptionSectionEntry<support::ubig32_t>;
321bdd1243dSDimitry Andric extern template struct ExceptionSectionEntry<support::ubig64_t>;
322bdd1243dSDimitry Andric 
3230b57cec5SDimitry Andric struct XCOFFStringTable {
3240b57cec5SDimitry Andric   uint32_t Size;
3250b57cec5SDimitry Andric   const char *Data;
3260b57cec5SDimitry Andric };
3270b57cec5SDimitry Andric 
3288bcb0991SDimitry Andric struct XCOFFCsectAuxEnt32 {
329fe6060f1SDimitry Andric   support::ubig32_t SectionOrLength;
3308bcb0991SDimitry Andric   support::ubig32_t ParameterHashIndex;
3318bcb0991SDimitry Andric   support::ubig16_t TypeChkSectNum;
3328bcb0991SDimitry Andric   uint8_t SymbolAlignmentAndType;
3338bcb0991SDimitry Andric   XCOFF::StorageMappingClass StorageMappingClass;
3348bcb0991SDimitry Andric   support::ubig32_t StabInfoIndex;
3358bcb0991SDimitry Andric   support::ubig16_t StabSectNum;
336fe6060f1SDimitry Andric };
337fe6060f1SDimitry Andric 
338fe6060f1SDimitry Andric struct XCOFFCsectAuxEnt64 {
339fe6060f1SDimitry Andric   support::ubig32_t SectionOrLengthLowByte;
340fe6060f1SDimitry Andric   support::ubig32_t ParameterHashIndex;
341fe6060f1SDimitry Andric   support::ubig16_t TypeChkSectNum;
342fe6060f1SDimitry Andric   uint8_t SymbolAlignmentAndType;
343fe6060f1SDimitry Andric   XCOFF::StorageMappingClass StorageMappingClass;
344fe6060f1SDimitry Andric   support::ubig32_t SectionOrLengthHighByte;
345fe6060f1SDimitry Andric   uint8_t Pad;
346fe6060f1SDimitry Andric   XCOFF::SymbolAuxType AuxType;
347fe6060f1SDimitry Andric };
348fe6060f1SDimitry Andric 
349fe6060f1SDimitry Andric class XCOFFCsectAuxRef {
350fe6060f1SDimitry Andric public:
351fe6060f1SDimitry Andric   static constexpr uint8_t SymbolTypeMask = 0x07;
352fe6060f1SDimitry Andric   static constexpr uint8_t SymbolAlignmentMask = 0xF8;
353fe6060f1SDimitry Andric   static constexpr size_t SymbolAlignmentBitOffset = 3;
354fe6060f1SDimitry Andric 
355fe6060f1SDimitry Andric   XCOFFCsectAuxRef(const XCOFFCsectAuxEnt32 *Entry32) : Entry32(Entry32) {}
356fe6060f1SDimitry Andric   XCOFFCsectAuxRef(const XCOFFCsectAuxEnt64 *Entry64) : Entry64(Entry64) {}
357fe6060f1SDimitry Andric 
358fe6060f1SDimitry Andric   // For getSectionOrLength(),
359fe6060f1SDimitry Andric   // If the symbol type is XTY_SD or XTY_CM, the csect length.
360fe6060f1SDimitry Andric   // If the symbol type is XTY_LD, the symbol table
361fe6060f1SDimitry Andric   // index of the containing csect.
362fe6060f1SDimitry Andric   // If the symbol type is XTY_ER, 0.
363fe6060f1SDimitry Andric   uint64_t getSectionOrLength() const {
364fe6060f1SDimitry Andric     return Entry32 ? getSectionOrLength32() : getSectionOrLength64();
365fe6060f1SDimitry Andric   }
366fe6060f1SDimitry Andric 
367fe6060f1SDimitry Andric   uint32_t getSectionOrLength32() const {
368fe6060f1SDimitry Andric     assert(Entry32 && "32-bit interface called on 64-bit object file.");
369fe6060f1SDimitry Andric     return Entry32->SectionOrLength;
370fe6060f1SDimitry Andric   }
371fe6060f1SDimitry Andric 
372fe6060f1SDimitry Andric   uint64_t getSectionOrLength64() const {
373fe6060f1SDimitry Andric     assert(Entry64 && "64-bit interface called on 32-bit object file.");
374fe6060f1SDimitry Andric     return (static_cast<uint64_t>(Entry64->SectionOrLengthHighByte) << 32) |
375fe6060f1SDimitry Andric            Entry64->SectionOrLengthLowByte;
376fe6060f1SDimitry Andric   }
377fe6060f1SDimitry Andric 
378fe6060f1SDimitry Andric #define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X
379fe6060f1SDimitry Andric 
380fe6060f1SDimitry Andric   uint32_t getParameterHashIndex() const {
381fe6060f1SDimitry Andric     return GETVALUE(ParameterHashIndex);
382fe6060f1SDimitry Andric   }
383fe6060f1SDimitry Andric 
384fe6060f1SDimitry Andric   uint16_t getTypeChkSectNum() const { return GETVALUE(TypeChkSectNum); }
385fe6060f1SDimitry Andric 
386fe6060f1SDimitry Andric   XCOFF::StorageMappingClass getStorageMappingClass() const {
387fe6060f1SDimitry Andric     return GETVALUE(StorageMappingClass);
388fe6060f1SDimitry Andric   }
389fe6060f1SDimitry Andric 
390fe6060f1SDimitry Andric   uintptr_t getEntryAddress() const {
391fe6060f1SDimitry Andric     return Entry32 ? reinterpret_cast<uintptr_t>(Entry32)
392fe6060f1SDimitry Andric                    : reinterpret_cast<uintptr_t>(Entry64);
393fe6060f1SDimitry Andric   }
3945ffd83dbSDimitry Andric 
3955ffd83dbSDimitry Andric   uint16_t getAlignmentLog2() const {
396fe6060f1SDimitry Andric     return (getSymbolAlignmentAndType() & SymbolAlignmentMask) >>
3975ffd83dbSDimitry Andric            SymbolAlignmentBitOffset;
3985ffd83dbSDimitry Andric   }
3995ffd83dbSDimitry Andric 
4005ffd83dbSDimitry Andric   uint8_t getSymbolType() const {
401fe6060f1SDimitry Andric     return getSymbolAlignmentAndType() & SymbolTypeMask;
4025ffd83dbSDimitry Andric   }
4035ffd83dbSDimitry Andric 
4045ffd83dbSDimitry Andric   bool isLabel() const { return getSymbolType() == XCOFF::XTY_LD; }
405fe6060f1SDimitry Andric 
406fe6060f1SDimitry Andric   uint32_t getStabInfoIndex32() const {
407fe6060f1SDimitry Andric     assert(Entry32 && "32-bit interface called on 64-bit object file.");
408fe6060f1SDimitry Andric     return Entry32->StabInfoIndex;
409fe6060f1SDimitry Andric   }
410fe6060f1SDimitry Andric 
411fe6060f1SDimitry Andric   uint16_t getStabSectNum32() const {
412fe6060f1SDimitry Andric     assert(Entry32 && "32-bit interface called on 64-bit object file.");
413fe6060f1SDimitry Andric     return Entry32->StabSectNum;
414fe6060f1SDimitry Andric   }
415fe6060f1SDimitry Andric 
416fe6060f1SDimitry Andric   XCOFF::SymbolAuxType getAuxType64() const {
417fe6060f1SDimitry Andric     assert(Entry64 && "64-bit interface called on 32-bit object file.");
418fe6060f1SDimitry Andric     return Entry64->AuxType;
419fe6060f1SDimitry Andric   }
420fe6060f1SDimitry Andric 
421fe6060f1SDimitry Andric   uint8_t getSymbolAlignmentAndType() const {
422fe6060f1SDimitry Andric     return GETVALUE(SymbolAlignmentAndType);
423fe6060f1SDimitry Andric   }
424fe6060f1SDimitry Andric 
425fe6060f1SDimitry Andric #undef GETVALUE
426fe6060f1SDimitry Andric 
4275f757f3fSDimitry Andric private:
428fe6060f1SDimitry Andric   const XCOFFCsectAuxEnt32 *Entry32 = nullptr;
429fe6060f1SDimitry Andric   const XCOFFCsectAuxEnt64 *Entry64 = nullptr;
4308bcb0991SDimitry Andric };
4318bcb0991SDimitry Andric 
4328bcb0991SDimitry Andric struct XCOFFFileAuxEnt {
4338bcb0991SDimitry Andric   typedef struct {
4348bcb0991SDimitry Andric     support::big32_t Magic; // Zero indicates name in string table.
4358bcb0991SDimitry Andric     support::ubig32_t Offset;
4368bcb0991SDimitry Andric     char NamePad[XCOFF::FileNamePadSize];
4378bcb0991SDimitry Andric   } NameInStrTblType;
4388bcb0991SDimitry Andric   union {
4398bcb0991SDimitry Andric     char Name[XCOFF::NameSize + XCOFF::FileNamePadSize];
4408bcb0991SDimitry Andric     NameInStrTblType NameInStrTbl;
4418bcb0991SDimitry Andric   };
4428bcb0991SDimitry Andric   XCOFF::CFileStringType Type;
4438bcb0991SDimitry Andric   uint8_t ReservedZeros[2];
444fe6060f1SDimitry Andric   XCOFF::SymbolAuxType AuxType; // 64-bit XCOFF file only.
4458bcb0991SDimitry Andric };
4468bcb0991SDimitry Andric 
4478bcb0991SDimitry Andric struct XCOFFSectAuxEntForStat {
4488bcb0991SDimitry Andric   support::ubig32_t SectionLength;
4498bcb0991SDimitry Andric   support::ubig16_t NumberOfRelocEnt;
4508bcb0991SDimitry Andric   support::ubig16_t NumberOfLineNum;
4518bcb0991SDimitry Andric   uint8_t Pad[10];
452fe6060f1SDimitry Andric }; // 32-bit XCOFF file only.
4538bcb0991SDimitry Andric 
45404eeddc0SDimitry Andric struct XCOFFFunctionAuxEnt32 {
45504eeddc0SDimitry Andric   support::ubig32_t OffsetToExceptionTbl;
45604eeddc0SDimitry Andric   support::ubig32_t SizeOfFunction;
45704eeddc0SDimitry Andric   support::ubig32_t PtrToLineNum;
45804eeddc0SDimitry Andric   support::big32_t SymIdxOfNextBeyond;
45904eeddc0SDimitry Andric   uint8_t Pad[2];
46004eeddc0SDimitry Andric };
46104eeddc0SDimitry Andric 
46204eeddc0SDimitry Andric struct XCOFFFunctionAuxEnt64 {
46304eeddc0SDimitry Andric   support::ubig64_t PtrToLineNum;
46404eeddc0SDimitry Andric   support::ubig32_t SizeOfFunction;
46504eeddc0SDimitry Andric   support::big32_t SymIdxOfNextBeyond;
46604eeddc0SDimitry Andric   uint8_t Pad;
46704eeddc0SDimitry Andric   XCOFF::SymbolAuxType AuxType; // Contains _AUX_FCN; Type of auxiliary entry
46804eeddc0SDimitry Andric };
46904eeddc0SDimitry Andric 
47004eeddc0SDimitry Andric struct XCOFFExceptionAuxEnt {
47104eeddc0SDimitry Andric   support::ubig64_t OffsetToExceptionTbl;
47204eeddc0SDimitry Andric   support::ubig32_t SizeOfFunction;
47304eeddc0SDimitry Andric   support::big32_t SymIdxOfNextBeyond;
47404eeddc0SDimitry Andric   uint8_t Pad;
47504eeddc0SDimitry Andric   XCOFF::SymbolAuxType AuxType; // Contains _AUX_EXCEPT; Type of auxiliary entry
47604eeddc0SDimitry Andric };
47704eeddc0SDimitry Andric 
47804eeddc0SDimitry Andric struct XCOFFBlockAuxEnt32 {
47904eeddc0SDimitry Andric   uint8_t ReservedZeros1[2];
48004eeddc0SDimitry Andric   support::ubig16_t LineNumHi;
48104eeddc0SDimitry Andric   support::ubig16_t LineNumLo;
48204eeddc0SDimitry Andric   uint8_t ReservedZeros2[12];
48304eeddc0SDimitry Andric };
48404eeddc0SDimitry Andric 
48504eeddc0SDimitry Andric struct XCOFFBlockAuxEnt64 {
48604eeddc0SDimitry Andric   support::ubig32_t LineNum;
48704eeddc0SDimitry Andric   uint8_t Pad[13];
48804eeddc0SDimitry Andric   XCOFF::SymbolAuxType AuxType; // Contains _AUX_SYM; Type of auxiliary entry
48904eeddc0SDimitry Andric };
49004eeddc0SDimitry Andric 
49104eeddc0SDimitry Andric struct XCOFFSectAuxEntForDWARF32 {
49204eeddc0SDimitry Andric   support::ubig32_t LengthOfSectionPortion;
49304eeddc0SDimitry Andric   uint8_t Pad1[4];
49404eeddc0SDimitry Andric   support::ubig32_t NumberOfRelocEnt;
49504eeddc0SDimitry Andric   uint8_t Pad2[6];
49604eeddc0SDimitry Andric };
49704eeddc0SDimitry Andric 
49804eeddc0SDimitry Andric struct XCOFFSectAuxEntForDWARF64 {
49904eeddc0SDimitry Andric   support::ubig64_t LengthOfSectionPortion;
50004eeddc0SDimitry Andric   support::ubig64_t NumberOfRelocEnt;
50104eeddc0SDimitry Andric   uint8_t Pad;
50204eeddc0SDimitry Andric   XCOFF::SymbolAuxType AuxType; // Contains _AUX_SECT; Type of Auxillary entry
50304eeddc0SDimitry Andric };
50404eeddc0SDimitry Andric 
505349cc55cSDimitry Andric template <typename AddressType> struct XCOFFRelocation {
5068bcb0991SDimitry Andric public:
507349cc55cSDimitry Andric   AddressType VirtualAddress;
5088bcb0991SDimitry Andric   support::ubig32_t SymbolIndex;
5098bcb0991SDimitry Andric 
5108bcb0991SDimitry Andric   // Packed field, see XR_* masks for details of packing.
5118bcb0991SDimitry Andric   uint8_t Info;
5128bcb0991SDimitry Andric 
5138bcb0991SDimitry Andric   XCOFF::RelocationType Type;
5148bcb0991SDimitry Andric 
5158bcb0991SDimitry Andric public:
5168bcb0991SDimitry Andric   bool isRelocationSigned() const;
5178bcb0991SDimitry Andric   bool isFixupIndicated() const;
5188bcb0991SDimitry Andric 
5198bcb0991SDimitry Andric   // Returns the number of bits being relocated.
5208bcb0991SDimitry Andric   uint8_t getRelocatedLength() const;
5218bcb0991SDimitry Andric };
5228bcb0991SDimitry Andric 
523349cc55cSDimitry Andric extern template struct XCOFFRelocation<llvm::support::ubig32_t>;
524349cc55cSDimitry Andric extern template struct XCOFFRelocation<llvm::support::ubig64_t>;
525349cc55cSDimitry Andric 
526349cc55cSDimitry Andric struct XCOFFRelocation32 : XCOFFRelocation<llvm::support::ubig32_t> {};
527349cc55cSDimitry Andric struct XCOFFRelocation64 : XCOFFRelocation<llvm::support::ubig64_t> {};
528349cc55cSDimitry Andric 
529fe6060f1SDimitry Andric class XCOFFSymbolRef;
530fe6060f1SDimitry Andric 
5310b57cec5SDimitry Andric class XCOFFObjectFile : public ObjectFile {
5320b57cec5SDimitry Andric private:
5330b57cec5SDimitry Andric   const void *FileHeader = nullptr;
534349cc55cSDimitry Andric   const void *AuxiliaryHeader = nullptr;
5350b57cec5SDimitry Andric   const void *SectionHeaderTable = nullptr;
5360b57cec5SDimitry Andric 
537fe6060f1SDimitry Andric   const void *SymbolTblPtr = nullptr;
5380b57cec5SDimitry Andric   XCOFFStringTable StringTable = {0, nullptr};
5390b57cec5SDimitry Andric 
5400b57cec5SDimitry Andric   const XCOFFSectionHeader32 *sectionHeaderTable32() const;
5410b57cec5SDimitry Andric   const XCOFFSectionHeader64 *sectionHeaderTable64() const;
542349cc55cSDimitry Andric   template <typename T> const T *sectionHeaderTable() const;
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric   size_t getFileHeaderSize() const;
5450b57cec5SDimitry Andric   size_t getSectionHeaderSize() const;
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric   const XCOFFSectionHeader32 *toSection32(DataRefImpl Ref) const;
5480b57cec5SDimitry Andric   const XCOFFSectionHeader64 *toSection64(DataRefImpl Ref) const;
5490b57cec5SDimitry Andric   uintptr_t getSectionHeaderTableAddress() const;
5508bcb0991SDimitry Andric   uintptr_t getEndOfSymbolTableAddress() const;
551bdd1243dSDimitry Andric 
552bdd1243dSDimitry Andric   DataRefImpl getSectionByType(XCOFF::SectionTypeFlags SectType) const;
553bdd1243dSDimitry Andric   uint64_t getSectionFileOffsetToRawData(DataRefImpl Sec) const;
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric   // This returns a pointer to the start of the storage for the name field of
5560b57cec5SDimitry Andric   // the 32-bit or 64-bit SectionHeader struct. This string is *not* necessarily
5570b57cec5SDimitry Andric   // null-terminated.
5580b57cec5SDimitry Andric   const char *getSectionNameInternal(DataRefImpl Sec) const;
5590b57cec5SDimitry Andric 
5600b57cec5SDimitry Andric   static bool isReservedSectionNumber(int16_t SectionNumber);
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric   // Constructor and "create" factory function. The constructor is only a thin
5630b57cec5SDimitry Andric   // wrapper around the base constructor. The "create" function fills out the
5640b57cec5SDimitry Andric   // XCOFF-specific information and performs the error checking along the way.
5650b57cec5SDimitry Andric   XCOFFObjectFile(unsigned Type, MemoryBufferRef Object);
5660b57cec5SDimitry Andric   static Expected<std::unique_ptr<XCOFFObjectFile>> create(unsigned Type,
5670b57cec5SDimitry Andric                                                            MemoryBufferRef MBR);
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric   // Helper for parsing the StringTable. Returns an 'Error' if parsing failed
5700b57cec5SDimitry Andric   // and an XCOFFStringTable if parsing succeeded.
5710b57cec5SDimitry Andric   static Expected<XCOFFStringTable> parseStringTable(const XCOFFObjectFile *Obj,
5720b57cec5SDimitry Andric                                                      uint64_t Offset);
5730b57cec5SDimitry Andric 
5740b57cec5SDimitry Andric   // Make a friend so it can call the private 'create' function.
5750b57cec5SDimitry Andric   friend Expected<std::unique_ptr<ObjectFile>>
5760b57cec5SDimitry Andric   ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
5770b57cec5SDimitry Andric 
5788bcb0991SDimitry Andric   void checkSectionAddress(uintptr_t Addr, uintptr_t TableAddr) const;
5798bcb0991SDimitry Andric 
5800b57cec5SDimitry Andric public:
5815ffd83dbSDimitry Andric   static constexpr uint64_t InvalidRelocOffset =
5825ffd83dbSDimitry Andric       std::numeric_limits<uint64_t>::max();
5835ffd83dbSDimitry Andric 
5840b57cec5SDimitry Andric   // Interface inherited from base classes.
5850b57cec5SDimitry Andric   void moveSymbolNext(DataRefImpl &Symb) const override;
5865ffd83dbSDimitry Andric   Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
5870b57cec5SDimitry Andric   basic_symbol_iterator symbol_begin() const override;
5880b57cec5SDimitry Andric   basic_symbol_iterator symbol_end() const override;
5895f757f3fSDimitry Andric 
5905f757f3fSDimitry Andric   using xcoff_symbol_iterator_range = iterator_range<xcoff_symbol_iterator>;
5915f757f3fSDimitry Andric   xcoff_symbol_iterator_range symbols() const;
5925f757f3fSDimitry Andric 
59306c3fb27SDimitry Andric   bool is64Bit() const override;
5940b57cec5SDimitry Andric   Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
5950b57cec5SDimitry Andric   Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
5960b57cec5SDimitry Andric   uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
597349cc55cSDimitry Andric   uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
5980b57cec5SDimitry Andric   uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
5990b57cec5SDimitry Andric   Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
6000b57cec5SDimitry Andric   Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
6010b57cec5SDimitry Andric 
6020b57cec5SDimitry Andric   void moveSectionNext(DataRefImpl &Sec) const override;
6030b57cec5SDimitry Andric   Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
6040b57cec5SDimitry Andric   uint64_t getSectionAddress(DataRefImpl Sec) const override;
6050b57cec5SDimitry Andric   uint64_t getSectionIndex(DataRefImpl Sec) const override;
6060b57cec5SDimitry Andric   uint64_t getSectionSize(DataRefImpl Sec) const override;
6070b57cec5SDimitry Andric   Expected<ArrayRef<uint8_t>>
6080b57cec5SDimitry Andric   getSectionContents(DataRefImpl Sec) const override;
6090b57cec5SDimitry Andric   uint64_t getSectionAlignment(DataRefImpl Sec) const override;
6100b57cec5SDimitry Andric   bool isSectionCompressed(DataRefImpl Sec) const override;
6110b57cec5SDimitry Andric   bool isSectionText(DataRefImpl Sec) const override;
6120b57cec5SDimitry Andric   bool isSectionData(DataRefImpl Sec) const override;
6130b57cec5SDimitry Andric   bool isSectionBSS(DataRefImpl Sec) const override;
614fe6060f1SDimitry Andric   bool isDebugSection(DataRefImpl Sec) const override;
6150b57cec5SDimitry Andric 
6160b57cec5SDimitry Andric   bool isSectionVirtual(DataRefImpl Sec) const override;
6170b57cec5SDimitry Andric   relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
6180b57cec5SDimitry Andric   relocation_iterator section_rel_end(DataRefImpl Sec) const override;
6190b57cec5SDimitry Andric 
6200b57cec5SDimitry Andric   void moveRelocationNext(DataRefImpl &Rel) const override;
6215ffd83dbSDimitry Andric 
6225ffd83dbSDimitry Andric   /// \returns the relocation offset with the base address of the containing
6235ffd83dbSDimitry Andric   /// section as zero, or InvalidRelocOffset on errors (such as a relocation
6245ffd83dbSDimitry Andric   /// that does not refer to an address in any section).
6250b57cec5SDimitry Andric   uint64_t getRelocationOffset(DataRefImpl Rel) const override;
6260b57cec5SDimitry Andric   symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
6270b57cec5SDimitry Andric   uint64_t getRelocationType(DataRefImpl Rel) const override;
6280b57cec5SDimitry Andric   void getRelocationTypeName(DataRefImpl Rel,
6290b57cec5SDimitry Andric                              SmallVectorImpl<char> &Result) const override;
6300b57cec5SDimitry Andric 
6310b57cec5SDimitry Andric   section_iterator section_begin() const override;
6320b57cec5SDimitry Andric   section_iterator section_end() const override;
6330b57cec5SDimitry Andric   uint8_t getBytesInAddress() const override;
6340b57cec5SDimitry Andric   StringRef getFileFormatName() const override;
6350b57cec5SDimitry Andric   Triple::ArchType getArch() const override;
636bdd1243dSDimitry Andric   Expected<SubtargetFeatures> getFeatures() const override;
6370b57cec5SDimitry Andric   Expected<uint64_t> getStartAddress() const override;
638fe6060f1SDimitry Andric   StringRef mapDebugSectionName(StringRef Name) const override;
6390b57cec5SDimitry Andric   bool isRelocatableObject() const override;
6400b57cec5SDimitry Andric 
6410b57cec5SDimitry Andric   // Below here is the non-inherited interface.
64206c3fb27SDimitry Andric 
64381ad6265SDimitry Andric   Expected<StringRef> getRawData(const char *Start, uint64_t Size,
64481ad6265SDimitry Andric                                  StringRef Name) const;
6450b57cec5SDimitry Andric 
646349cc55cSDimitry Andric   const XCOFFAuxiliaryHeader32 *auxiliaryHeader32() const;
647349cc55cSDimitry Andric   const XCOFFAuxiliaryHeader64 *auxiliaryHeader64() const;
648349cc55cSDimitry Andric 
649fe6060f1SDimitry Andric   const void *getPointerToSymbolTable() const { return SymbolTblPtr; }
6500b57cec5SDimitry Andric 
651fe6060f1SDimitry Andric   Expected<StringRef> getSymbolSectionName(XCOFFSymbolRef Ref) const;
652fe6060f1SDimitry Andric   unsigned getSymbolSectionID(SymbolRef Sym) const;
653fe6060f1SDimitry Andric   XCOFFSymbolRef toSymbolRef(DataRefImpl Ref) const;
6540b57cec5SDimitry Andric 
6550b57cec5SDimitry Andric   // File header related interfaces.
65681ad6265SDimitry Andric   const XCOFFFileHeader32 *fileHeader32() const;
65781ad6265SDimitry Andric   const XCOFFFileHeader64 *fileHeader64() const;
6580b57cec5SDimitry Andric   uint16_t getMagic() const;
6590b57cec5SDimitry Andric   uint16_t getNumberOfSections() const;
6600b57cec5SDimitry Andric   int32_t getTimeStamp() const;
6610b57cec5SDimitry Andric 
6620b57cec5SDimitry Andric   // Symbol table offset and entry count are handled differently between
6630b57cec5SDimitry Andric   // XCOFF32 and XCOFF64.
6640b57cec5SDimitry Andric   uint32_t getSymbolTableOffset32() const;
6650b57cec5SDimitry Andric   uint64_t getSymbolTableOffset64() const;
6660b57cec5SDimitry Andric 
6670b57cec5SDimitry Andric   // Note that this value is signed and might return a negative value. Negative
6680b57cec5SDimitry Andric   // values are reserved for future use.
6690b57cec5SDimitry Andric   int32_t getRawNumberOfSymbolTableEntries32() const;
6700b57cec5SDimitry Andric 
6710b57cec5SDimitry Andric   // The sanitized value appropriate to use as an index into the symbol table.
6720b57cec5SDimitry Andric   uint32_t getLogicalNumberOfSymbolTableEntries32() const;
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric   uint32_t getNumberOfSymbolTableEntries64() const;
675fe6060f1SDimitry Andric 
676fe6060f1SDimitry Andric   // Return getLogicalNumberOfSymbolTableEntries32 or
677fe6060f1SDimitry Andric   // getNumberOfSymbolTableEntries64 depending on the object mode.
678fe6060f1SDimitry Andric   uint32_t getNumberOfSymbolTableEntries() const;
679fe6060f1SDimitry Andric 
6808bcb0991SDimitry Andric   uint32_t getSymbolIndex(uintptr_t SymEntPtr) const;
681349cc55cSDimitry Andric   uint64_t getSymbolSize(DataRefImpl Symb) const;
682349cc55cSDimitry Andric   uintptr_t getSymbolByIndex(uint32_t Idx) const {
683349cc55cSDimitry Andric     return reinterpret_cast<uintptr_t>(SymbolTblPtr) +
684349cc55cSDimitry Andric            XCOFF::SymbolTableEntrySize * Idx;
685349cc55cSDimitry Andric   }
686fe6060f1SDimitry Andric   uintptr_t getSymbolEntryAddressByIndex(uint32_t SymbolTableIndex) const;
6878bcb0991SDimitry Andric   Expected<StringRef> getSymbolNameByIndex(uint32_t SymbolTableIndex) const;
6880b57cec5SDimitry Andric 
6898bcb0991SDimitry Andric   Expected<StringRef> getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const;
6900b57cec5SDimitry Andric   uint16_t getOptionalHeaderSize() const;
6910b57cec5SDimitry Andric   uint16_t getFlags() const;
6920b57cec5SDimitry Andric 
6930b57cec5SDimitry Andric   // Section header table related interfaces.
6940b57cec5SDimitry Andric   ArrayRef<XCOFFSectionHeader32> sections32() const;
6950b57cec5SDimitry Andric   ArrayRef<XCOFFSectionHeader64> sections64() const;
6968bcb0991SDimitry Andric 
6978bcb0991SDimitry Andric   int32_t getSectionFlags(DataRefImpl Sec) const;
6988bcb0991SDimitry Andric   Expected<DataRefImpl> getSectionByNum(int16_t Num) const;
6998bcb0991SDimitry Andric 
700bdd1243dSDimitry Andric   Expected<uintptr_t>
701bdd1243dSDimitry Andric   getSectionFileOffsetToRawData(XCOFF::SectionTypeFlags SectType) const;
702bdd1243dSDimitry Andric 
7038bcb0991SDimitry Andric   void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const;
7048bcb0991SDimitry Andric 
7058bcb0991SDimitry Andric   // Relocation-related interfaces.
706349cc55cSDimitry Andric   template <typename T>
7078bcb0991SDimitry Andric   Expected<uint32_t>
708349cc55cSDimitry Andric   getNumberOfRelocationEntries(const XCOFFSectionHeader<T> &Sec) const;
7098bcb0991SDimitry Andric 
710349cc55cSDimitry Andric   template <typename Shdr, typename Reloc>
711349cc55cSDimitry Andric   Expected<ArrayRef<Reloc>> relocations(const Shdr &Sec) const;
712349cc55cSDimitry Andric 
713349cc55cSDimitry Andric   // Loader section related interfaces.
714349cc55cSDimitry Andric   Expected<StringRef> getImportFileTable() const;
715e8d8bef9SDimitry Andric 
716bdd1243dSDimitry Andric   // Exception-related interface.
717bdd1243dSDimitry Andric   template <typename ExceptEnt>
718bdd1243dSDimitry Andric   Expected<ArrayRef<ExceptEnt>> getExceptionEntries() const;
719bdd1243dSDimitry Andric 
720fe6060f1SDimitry Andric   // This function returns string table entry.
721fe6060f1SDimitry Andric   Expected<StringRef> getStringTableEntry(uint32_t Offset) const;
722fe6060f1SDimitry Andric 
723fe6060f1SDimitry Andric   // This function returns the string table.
724fe6060f1SDimitry Andric   StringRef getStringTable() const;
725fe6060f1SDimitry Andric 
726fe6060f1SDimitry Andric   const XCOFF::SymbolAuxType *getSymbolAuxType(uintptr_t AuxEntryAddress) const;
727fe6060f1SDimitry Andric 
728fe6060f1SDimitry Andric   static uintptr_t getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,
729fe6060f1SDimitry Andric                                                  uint32_t Distance);
730fe6060f1SDimitry Andric 
731e8d8bef9SDimitry Andric   static bool classof(const Binary *B) { return B->isXCOFF(); }
73206c3fb27SDimitry Andric 
73306c3fb27SDimitry Andric   std::optional<StringRef> tryGetCPUName() const override;
7340b57cec5SDimitry Andric }; // XCOFFObjectFile
7350b57cec5SDimitry Andric 
736fe6060f1SDimitry Andric typedef struct {
737fe6060f1SDimitry Andric   uint8_t LanguageId;
738fe6060f1SDimitry Andric   uint8_t CpuTypeId;
739fe6060f1SDimitry Andric } CFileLanguageIdAndTypeIdType;
7408bcb0991SDimitry Andric 
741fe6060f1SDimitry Andric struct XCOFFSymbolEntry32 {
742fe6060f1SDimitry Andric   typedef struct {
743fe6060f1SDimitry Andric     support::big32_t Magic; // Zero indicates name in string table.
744fe6060f1SDimitry Andric     support::ubig32_t Offset;
745fe6060f1SDimitry Andric   } NameInStrTblType;
746fe6060f1SDimitry Andric 
747fe6060f1SDimitry Andric   union {
748fe6060f1SDimitry Andric     char SymbolName[XCOFF::NameSize];
749fe6060f1SDimitry Andric     NameInStrTblType NameInStrTbl;
750fe6060f1SDimitry Andric   };
751fe6060f1SDimitry Andric 
752fe6060f1SDimitry Andric   support::ubig32_t Value; // Symbol value; storage class-dependent.
753fe6060f1SDimitry Andric   support::big16_t SectionNumber;
754fe6060f1SDimitry Andric 
755fe6060f1SDimitry Andric   union {
756fe6060f1SDimitry Andric     support::ubig16_t SymbolType;
757fe6060f1SDimitry Andric     CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
758fe6060f1SDimitry Andric   };
759fe6060f1SDimitry Andric 
760fe6060f1SDimitry Andric   XCOFF::StorageClass StorageClass;
761fe6060f1SDimitry Andric   uint8_t NumberOfAuxEntries;
762fe6060f1SDimitry Andric };
763fe6060f1SDimitry Andric 
764fe6060f1SDimitry Andric struct XCOFFSymbolEntry64 {
765fe6060f1SDimitry Andric   support::ubig64_t Value; // Symbol value; storage class-dependent.
766fe6060f1SDimitry Andric   support::ubig32_t Offset;
767fe6060f1SDimitry Andric   support::big16_t SectionNumber;
768fe6060f1SDimitry Andric 
769fe6060f1SDimitry Andric   union {
770fe6060f1SDimitry Andric     support::ubig16_t SymbolType;
771fe6060f1SDimitry Andric     CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
772fe6060f1SDimitry Andric   };
773fe6060f1SDimitry Andric 
774fe6060f1SDimitry Andric   XCOFF::StorageClass StorageClass;
775fe6060f1SDimitry Andric   uint8_t NumberOfAuxEntries;
776fe6060f1SDimitry Andric };
777fe6060f1SDimitry Andric 
7785f757f3fSDimitry Andric class XCOFFSymbolRef : public SymbolRef {
7798bcb0991SDimitry Andric public:
780fe6060f1SDimitry Andric   enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
781fe6060f1SDimitry Andric 
7828bcb0991SDimitry Andric   XCOFFSymbolRef(DataRefImpl SymEntDataRef,
7838bcb0991SDimitry Andric                  const XCOFFObjectFile *OwningObjectPtr)
7845f757f3fSDimitry Andric       : SymbolRef(SymEntDataRef, OwningObjectPtr) {
785fe6060f1SDimitry Andric     assert(OwningObjectPtr && "OwningObjectPtr cannot be nullptr!");
786fe6060f1SDimitry Andric     assert(SymEntDataRef.p != 0 &&
787fe6060f1SDimitry Andric            "Symbol table entry pointer cannot be nullptr!");
788fe6060f1SDimitry Andric   }
7898bcb0991SDimitry Andric 
7905f757f3fSDimitry Andric   const XCOFFSymbolEntry32 *getSymbol32() const {
7915f757f3fSDimitry Andric     return reinterpret_cast<const XCOFFSymbolEntry32 *>(getRawDataRefImpl().p);
7925f757f3fSDimitry Andric   }
79381ad6265SDimitry Andric 
7945f757f3fSDimitry Andric   const XCOFFSymbolEntry64 *getSymbol64() const {
7955f757f3fSDimitry Andric     return reinterpret_cast<const XCOFFSymbolEntry64 *>(getRawDataRefImpl().p);
7965f757f3fSDimitry Andric   }
797fe6060f1SDimitry Andric 
7985f757f3fSDimitry Andric   uint64_t getValue() const {
7995f757f3fSDimitry Andric     return getObject()->is64Bit() ? getValue64() : getValue32();
8005f757f3fSDimitry Andric   }
801fe6060f1SDimitry Andric 
8025f757f3fSDimitry Andric   uint32_t getValue32() const {
8035f757f3fSDimitry Andric     return reinterpret_cast<const XCOFFSymbolEntry32 *>(getRawDataRefImpl().p)
8045f757f3fSDimitry Andric         ->Value;
8055f757f3fSDimitry Andric   }
806fe6060f1SDimitry Andric 
8075f757f3fSDimitry Andric   uint64_t getValue64() const {
8085f757f3fSDimitry Andric     return reinterpret_cast<const XCOFFSymbolEntry64 *>(getRawDataRefImpl().p)
8095f757f3fSDimitry Andric         ->Value;
8105f757f3fSDimitry Andric   }
8115f757f3fSDimitry Andric 
8125f757f3fSDimitry Andric   uint64_t getSize() const {
8135f757f3fSDimitry Andric     return getObject()->getSymbolSize(getRawDataRefImpl());
8145f757f3fSDimitry Andric   }
8155f757f3fSDimitry Andric 
8165f757f3fSDimitry Andric #define GETVALUE(X)                                                            \
8175f757f3fSDimitry Andric   getObject()->is64Bit()                                                       \
8185f757f3fSDimitry Andric       ? reinterpret_cast<const XCOFFSymbolEntry64 *>(getRawDataRefImpl().p)->X \
8195f757f3fSDimitry Andric       : reinterpret_cast<const XCOFFSymbolEntry32 *>(getRawDataRefImpl().p)->X
820fe6060f1SDimitry Andric 
821fe6060f1SDimitry Andric   int16_t getSectionNumber() const { return GETVALUE(SectionNumber); }
822fe6060f1SDimitry Andric 
823fe6060f1SDimitry Andric   uint16_t getSymbolType() const { return GETVALUE(SymbolType); }
824fe6060f1SDimitry Andric 
825fe6060f1SDimitry Andric   uint8_t getLanguageIdForCFile() const {
826fe6060f1SDimitry Andric     assert(getStorageClass() == XCOFF::C_FILE &&
827fe6060f1SDimitry Andric            "This interface is for C_FILE only.");
828fe6060f1SDimitry Andric     return GETVALUE(CFileLanguageIdAndTypeId.LanguageId);
829fe6060f1SDimitry Andric   }
830fe6060f1SDimitry Andric 
831fe6060f1SDimitry Andric   uint8_t getCPUTypeIddForCFile() const {
832fe6060f1SDimitry Andric     assert(getStorageClass() == XCOFF::C_FILE &&
833fe6060f1SDimitry Andric            "This interface is for C_FILE only.");
834fe6060f1SDimitry Andric     return GETVALUE(CFileLanguageIdAndTypeId.CpuTypeId);
835fe6060f1SDimitry Andric   }
836fe6060f1SDimitry Andric 
837fe6060f1SDimitry Andric   XCOFF::StorageClass getStorageClass() const { return GETVALUE(StorageClass); }
838fe6060f1SDimitry Andric 
839fe6060f1SDimitry Andric   uint8_t getNumberOfAuxEntries() const { return GETVALUE(NumberOfAuxEntries); }
840fe6060f1SDimitry Andric 
841fe6060f1SDimitry Andric #undef GETVALUE
842fe6060f1SDimitry Andric 
843fe6060f1SDimitry Andric   uintptr_t getEntryAddress() const {
8445f757f3fSDimitry Andric     return getRawDataRefImpl().p;
845fe6060f1SDimitry Andric   }
846fe6060f1SDimitry Andric 
847fe6060f1SDimitry Andric   Expected<StringRef> getName() const;
8485f757f3fSDimitry Andric   Expected<bool> isFunction() const;
849fe6060f1SDimitry Andric   bool isCsectSymbol() const;
850fe6060f1SDimitry Andric   Expected<XCOFFCsectAuxRef> getXCOFFCsectAuxRef() const;
851fe6060f1SDimitry Andric 
852fe6060f1SDimitry Andric private:
8535f757f3fSDimitry Andric   const XCOFFObjectFile *getObject() const {
8545f757f3fSDimitry Andric     return cast<XCOFFObjectFile>(BasicSymbolRef::getObject());
8555f757f3fSDimitry Andric   }
8565f757f3fSDimitry Andric };
8575f757f3fSDimitry Andric 
8585f757f3fSDimitry Andric class xcoff_symbol_iterator : public symbol_iterator {
8595f757f3fSDimitry Andric public:
8605f757f3fSDimitry Andric   xcoff_symbol_iterator(const basic_symbol_iterator &B)
8615f757f3fSDimitry Andric       : symbol_iterator(B) {}
8625f757f3fSDimitry Andric 
8635f757f3fSDimitry Andric   xcoff_symbol_iterator(const XCOFFSymbolRef *Symbol)
8645f757f3fSDimitry Andric       : symbol_iterator(*Symbol) {}
8655f757f3fSDimitry Andric 
8665f757f3fSDimitry Andric   const XCOFFSymbolRef *operator->() const {
8675f757f3fSDimitry Andric     return static_cast<const XCOFFSymbolRef *>(symbol_iterator::operator->());
8685f757f3fSDimitry Andric   }
8695f757f3fSDimitry Andric 
8705f757f3fSDimitry Andric   const XCOFFSymbolRef &operator*() const {
8715f757f3fSDimitry Andric     return static_cast<const XCOFFSymbolRef &>(symbol_iterator::operator*());
8725f757f3fSDimitry Andric   }
8738bcb0991SDimitry Andric };
8748bcb0991SDimitry Andric 
875e8d8bef9SDimitry Andric class TBVectorExt {
876e8d8bef9SDimitry Andric   uint16_t Data;
877fe6060f1SDimitry Andric   SmallString<32> VecParmsInfo;
878e8d8bef9SDimitry Andric 
879fe6060f1SDimitry Andric   TBVectorExt(StringRef TBvectorStrRef, Error &Err);
880e8d8bef9SDimitry Andric 
881e8d8bef9SDimitry Andric public:
882fe6060f1SDimitry Andric   static Expected<TBVectorExt> create(StringRef TBvectorStrRef);
883e8d8bef9SDimitry Andric   uint8_t getNumberOfVRSaved() const;
884e8d8bef9SDimitry Andric   bool isVRSavedOnStack() const;
885e8d8bef9SDimitry Andric   bool hasVarArgs() const;
886e8d8bef9SDimitry Andric   uint8_t getNumberOfVectorParms() const;
887e8d8bef9SDimitry Andric   bool hasVMXInstruction() const;
888fe6060f1SDimitry Andric   SmallString<32> getVectorParmsInfo() const { return VecParmsInfo; };
889e8d8bef9SDimitry Andric };
890e8d8bef9SDimitry Andric 
891e8d8bef9SDimitry Andric /// This class provides methods to extract traceback table data from a buffer.
892e8d8bef9SDimitry Andric /// The various accessors may reference the buffer provided via the constructor.
893e8d8bef9SDimitry Andric 
894e8d8bef9SDimitry Andric class XCOFFTracebackTable {
895e8d8bef9SDimitry Andric   const uint8_t *const TBPtr;
89606c3fb27SDimitry Andric   bool Is64BitObj;
897bdd1243dSDimitry Andric   std::optional<SmallString<32>> ParmsType;
898bdd1243dSDimitry Andric   std::optional<uint32_t> TraceBackTableOffset;
899bdd1243dSDimitry Andric   std::optional<uint32_t> HandlerMask;
900bdd1243dSDimitry Andric   std::optional<uint32_t> NumOfCtlAnchors;
901bdd1243dSDimitry Andric   std::optional<SmallVector<uint32_t, 8>> ControlledStorageInfoDisp;
902bdd1243dSDimitry Andric   std::optional<StringRef> FunctionName;
903bdd1243dSDimitry Andric   std::optional<uint8_t> AllocaRegister;
904bdd1243dSDimitry Andric   std::optional<TBVectorExt> VecExt;
905bdd1243dSDimitry Andric   std::optional<uint8_t> ExtensionTable;
90606c3fb27SDimitry Andric   std::optional<uint64_t> EhInfoDisp;
907e8d8bef9SDimitry Andric 
90806c3fb27SDimitry Andric   XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size, Error &Err,
90906c3fb27SDimitry Andric                       bool Is64Bit = false);
910349cc55cSDimitry Andric 
911e8d8bef9SDimitry Andric public:
912e8d8bef9SDimitry Andric   /// Parse an XCOFF Traceback Table from \a Ptr with \a Size bytes.
913e8d8bef9SDimitry Andric   /// Returns an XCOFFTracebackTable upon successful parsing, otherwise an
914e8d8bef9SDimitry Andric   /// Error is returned.
915e8d8bef9SDimitry Andric   ///
916e8d8bef9SDimitry Andric   /// \param[in] Ptr
917e8d8bef9SDimitry Andric   ///   A pointer that points just past the initial 4 bytes of zeros at the
918e8d8bef9SDimitry Andric   ///   beginning of an XCOFF Traceback Table.
919e8d8bef9SDimitry Andric   ///
920e8d8bef9SDimitry Andric   /// \param[in, out] Size
921e8d8bef9SDimitry Andric   ///    A pointer that points to the length of the XCOFF Traceback Table.
922e8d8bef9SDimitry Andric   ///    If the XCOFF Traceback Table is not parsed successfully or there are
923e8d8bef9SDimitry Andric   ///    extra bytes that are not recognized, \a Size will be updated to be the
924e8d8bef9SDimitry Andric   ///    size up to the end of the last successfully parsed field of the table.
92506c3fb27SDimitry Andric   static Expected<XCOFFTracebackTable>
92606c3fb27SDimitry Andric   create(const uint8_t *Ptr, uint64_t &Size, bool Is64Bits = false);
927e8d8bef9SDimitry Andric   uint8_t getVersion() const;
928e8d8bef9SDimitry Andric   uint8_t getLanguageID() const;
929e8d8bef9SDimitry Andric 
930e8d8bef9SDimitry Andric   bool isGlobalLinkage() const;
931e8d8bef9SDimitry Andric   bool isOutOfLineEpilogOrPrologue() const;
932e8d8bef9SDimitry Andric   bool hasTraceBackTableOffset() const;
933e8d8bef9SDimitry Andric   bool isInternalProcedure() const;
934e8d8bef9SDimitry Andric   bool hasControlledStorage() const;
935e8d8bef9SDimitry Andric   bool isTOCless() const;
936e8d8bef9SDimitry Andric   bool isFloatingPointPresent() const;
937e8d8bef9SDimitry Andric   bool isFloatingPointOperationLogOrAbortEnabled() const;
938e8d8bef9SDimitry Andric 
939e8d8bef9SDimitry Andric   bool isInterruptHandler() const;
940e8d8bef9SDimitry Andric   bool isFuncNamePresent() const;
941e8d8bef9SDimitry Andric   bool isAllocaUsed() const;
942e8d8bef9SDimitry Andric   uint8_t getOnConditionDirective() const;
943e8d8bef9SDimitry Andric   bool isCRSaved() const;
944e8d8bef9SDimitry Andric   bool isLRSaved() const;
945e8d8bef9SDimitry Andric 
946e8d8bef9SDimitry Andric   bool isBackChainStored() const;
947e8d8bef9SDimitry Andric   bool isFixup() const;
948e8d8bef9SDimitry Andric   uint8_t getNumOfFPRsSaved() const;
949e8d8bef9SDimitry Andric 
950e8d8bef9SDimitry Andric   bool hasVectorInfo() const;
951e8d8bef9SDimitry Andric   bool hasExtensionTable() const;
952e8d8bef9SDimitry Andric   uint8_t getNumOfGPRsSaved() const;
953e8d8bef9SDimitry Andric 
954e8d8bef9SDimitry Andric   uint8_t getNumberOfFixedParms() const;
955e8d8bef9SDimitry Andric 
956e8d8bef9SDimitry Andric   uint8_t getNumberOfFPParms() const;
957e8d8bef9SDimitry Andric   bool hasParmsOnStack() const;
958e8d8bef9SDimitry Andric 
959bdd1243dSDimitry Andric   const std::optional<SmallString<32>> &getParmsType() const {
960bdd1243dSDimitry Andric     return ParmsType;
961bdd1243dSDimitry Andric   }
962bdd1243dSDimitry Andric   const std::optional<uint32_t> &getTraceBackTableOffset() const {
963e8d8bef9SDimitry Andric     return TraceBackTableOffset;
964e8d8bef9SDimitry Andric   }
965bdd1243dSDimitry Andric   const std::optional<uint32_t> &getHandlerMask() const { return HandlerMask; }
966bdd1243dSDimitry Andric   const std::optional<uint32_t> &getNumOfCtlAnchors() {
967bdd1243dSDimitry Andric     return NumOfCtlAnchors;
968bdd1243dSDimitry Andric   }
969bdd1243dSDimitry Andric   const std::optional<SmallVector<uint32_t, 8>> &
970bdd1243dSDimitry Andric   getControlledStorageInfoDisp() {
971e8d8bef9SDimitry Andric     return ControlledStorageInfoDisp;
972e8d8bef9SDimitry Andric   }
973bdd1243dSDimitry Andric   const std::optional<StringRef> &getFunctionName() const {
974bdd1243dSDimitry Andric     return FunctionName;
975bdd1243dSDimitry Andric   }
976bdd1243dSDimitry Andric   const std::optional<uint8_t> &getAllocaRegister() const {
977bdd1243dSDimitry Andric     return AllocaRegister;
978bdd1243dSDimitry Andric   }
979bdd1243dSDimitry Andric   const std::optional<TBVectorExt> &getVectorExt() const { return VecExt; }
980bdd1243dSDimitry Andric   const std::optional<uint8_t> &getExtensionTable() const {
981bdd1243dSDimitry Andric     return ExtensionTable;
982bdd1243dSDimitry Andric   }
98306c3fb27SDimitry Andric   const std::optional<uint64_t> &getEhInfoDisp() const { return EhInfoDisp; }
984e8d8bef9SDimitry Andric };
985e8d8bef9SDimitry Andric 
986e8d8bef9SDimitry Andric bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes);
9870b57cec5SDimitry Andric } // namespace object
9880b57cec5SDimitry Andric } // namespace llvm
9890b57cec5SDimitry Andric 
9900b57cec5SDimitry Andric #endif // LLVM_OBJECT_XCOFFOBJECTFILE_H
991