]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/Object/XCOFFObjectFile.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / Object / XCOFFObjectFile.h
1 //===- XCOFFObjectFile.h - XCOFF object file 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 the XCOFFObjectFile class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_OBJECT_XCOFFOBJECTFILE_H
14 #define LLVM_OBJECT_XCOFFOBJECTFILE_H
15
16 #include "llvm/BinaryFormat/XCOFF.h"
17 #include "llvm/Object/ObjectFile.h"
18
19 namespace llvm {
20 namespace object {
21
22 struct XCOFFFileHeader32 {
23   support::ubig16_t Magic;
24   support::ubig16_t NumberOfSections;
25
26   // Unix time value, value of 0 indicates no timestamp.
27   // Negative values are reserved.
28   support::big32_t TimeStamp;
29
30   support::ubig32_t SymbolTableOffset; // File offset to symbol table.
31   support::big32_t NumberOfSymTableEntries;
32   support::ubig16_t AuxHeaderSize;
33   support::ubig16_t Flags;
34 };
35
36 struct XCOFFFileHeader64 {
37   support::ubig16_t Magic;
38   support::ubig16_t NumberOfSections;
39
40   // Unix time value, value of 0 indicates no timestamp.
41   // Negative values are reserved.
42   support::big32_t TimeStamp;
43
44   support::ubig64_t SymbolTableOffset; // File offset to symbol table.
45   support::ubig16_t AuxHeaderSize;
46   support::ubig16_t Flags;
47   support::ubig32_t NumberOfSymTableEntries;
48 };
49
50 template <typename T> struct XCOFFSectionHeader {
51   // Least significant 3 bits are reserved.
52   static constexpr unsigned SectionFlagsReservedMask = 0x7;
53
54   // The low order 16 bits of section flags denotes the section type.
55   static constexpr unsigned SectionFlagsTypeMask = 0xffffu;
56
57 public:
58   StringRef getName() const;
59   uint16_t getSectionType() const;
60   bool isReservedSectionType() const;
61 };
62
63 // Explicit extern template declarations.
64 struct XCOFFSectionHeader32;
65 struct XCOFFSectionHeader64;
66 extern template struct XCOFFSectionHeader<XCOFFSectionHeader32>;
67 extern template struct XCOFFSectionHeader<XCOFFSectionHeader64>;
68
69 struct XCOFFSectionHeader32 : XCOFFSectionHeader<XCOFFSectionHeader32> {
70   char Name[XCOFF::NameSize];
71   support::ubig32_t PhysicalAddress;
72   support::ubig32_t VirtualAddress;
73   support::ubig32_t SectionSize;
74   support::ubig32_t FileOffsetToRawData;
75   support::ubig32_t FileOffsetToRelocationInfo;
76   support::ubig32_t FileOffsetToLineNumberInfo;
77   support::ubig16_t NumberOfRelocations;
78   support::ubig16_t NumberOfLineNumbers;
79   support::big32_t Flags;
80 };
81
82 struct XCOFFSectionHeader64 : XCOFFSectionHeader<XCOFFSectionHeader64> {
83   char Name[XCOFF::NameSize];
84   support::ubig64_t PhysicalAddress;
85   support::ubig64_t VirtualAddress;
86   support::ubig64_t SectionSize;
87   support::big64_t FileOffsetToRawData;
88   support::big64_t FileOffsetToRelocationInfo;
89   support::big64_t FileOffsetToLineNumberInfo;
90   support::ubig32_t NumberOfRelocations;
91   support::ubig32_t NumberOfLineNumbers;
92   support::big32_t Flags;
93   char Padding[4];
94 };
95
96 struct XCOFFSymbolEntry {
97   enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
98   typedef struct {
99     support::big32_t Magic; // Zero indicates name in string table.
100     support::ubig32_t Offset;
101   } NameInStrTblType;
102
103   typedef struct {
104     uint8_t LanguageId;
105     uint8_t CpuTypeId;
106   } CFileLanguageIdAndTypeIdType;
107
108   union {
109     char SymbolName[XCOFF::NameSize];
110     NameInStrTblType NameInStrTbl;
111   };
112
113   support::ubig32_t Value; // Symbol value; storage class-dependent.
114   support::big16_t SectionNumber;
115
116   union {
117     support::ubig16_t SymbolType;
118     CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
119   };
120
121   XCOFF::StorageClass StorageClass;
122   uint8_t NumberOfAuxEntries;
123 };
124
125 struct XCOFFStringTable {
126   uint32_t Size;
127   const char *Data;
128 };
129
130 struct XCOFFCsectAuxEnt32 {
131   support::ubig32_t
132       SectionOrLength; // If the symbol type is XTY_SD or XTY_CM, the csect
133                        // length.
134                        // If the symbol type is XTY_LD, the symbol table
135                        // index of the containing csect.
136                        // If the symbol type is XTY_ER, 0.
137   support::ubig32_t ParameterHashIndex;
138   support::ubig16_t TypeChkSectNum;
139   uint8_t SymbolAlignmentAndType;
140   XCOFF::StorageMappingClass StorageMappingClass;
141   support::ubig32_t StabInfoIndex;
142   support::ubig16_t StabSectNum;
143 };
144
145 struct XCOFFFileAuxEnt {
146   typedef struct {
147     support::big32_t Magic; // Zero indicates name in string table.
148     support::ubig32_t Offset;
149     char NamePad[XCOFF::FileNamePadSize];
150   } NameInStrTblType;
151   union {
152     char Name[XCOFF::NameSize + XCOFF::FileNamePadSize];
153     NameInStrTblType NameInStrTbl;
154   };
155   XCOFF::CFileStringType Type;
156   uint8_t ReservedZeros[2];
157   uint8_t AuxType; // 64-bit XCOFF file only.
158 };
159
160 struct XCOFFSectAuxEntForStat {
161   support::ubig32_t SectionLength;
162   support::ubig16_t NumberOfRelocEnt;
163   support::ubig16_t NumberOfLineNum;
164   uint8_t Pad[10];
165 };
166
167 struct XCOFFRelocation32 {
168   // Masks for packing/unpacking the r_rsize field of relocations.
169
170   // The msb is used to indicate if the bits being relocated are signed or
171   // unsigned.
172   static constexpr uint8_t XR_SIGN_INDICATOR_MASK = 0x80;
173
174   // The 2nd msb is used to indicate that the binder has replaced/modified the
175   // original instruction.
176   static constexpr uint8_t XR_FIXUP_INDICATOR_MASK = 0x40;
177
178   // The remaining bits specify the bit length of the relocatable reference
179   // minus one.
180   static constexpr uint8_t XR_BIASED_LENGTH_MASK = 0x3f;
181
182 public:
183   support::ubig32_t VirtualAddress;
184   support::ubig32_t SymbolIndex;
185
186   // Packed field, see XR_* masks for details of packing.
187   uint8_t Info;
188
189   XCOFF::RelocationType Type;
190
191 public:
192   bool isRelocationSigned() const;
193   bool isFixupIndicated() const;
194
195   // Returns the number of bits being relocated.
196   uint8_t getRelocatedLength() const;
197 };
198
199 class XCOFFObjectFile : public ObjectFile {
200 private:
201   const void *FileHeader = nullptr;
202   const void *SectionHeaderTable = nullptr;
203
204   const XCOFFSymbolEntry *SymbolTblPtr = nullptr;
205   XCOFFStringTable StringTable = {0, nullptr};
206
207   const XCOFFFileHeader32 *fileHeader32() const;
208   const XCOFFFileHeader64 *fileHeader64() const;
209
210   const XCOFFSectionHeader32 *sectionHeaderTable32() const;
211   const XCOFFSectionHeader64 *sectionHeaderTable64() const;
212
213   size_t getFileHeaderSize() const;
214   size_t getSectionHeaderSize() const;
215
216   const XCOFFSectionHeader32 *toSection32(DataRefImpl Ref) const;
217   const XCOFFSectionHeader64 *toSection64(DataRefImpl Ref) const;
218   uintptr_t getSectionHeaderTableAddress() const;
219   uintptr_t getEndOfSymbolTableAddress() const;
220
221   // This returns a pointer to the start of the storage for the name field of
222   // the 32-bit or 64-bit SectionHeader struct. This string is *not* necessarily
223   // null-terminated.
224   const char *getSectionNameInternal(DataRefImpl Sec) const;
225
226   // This function returns string table entry.
227   Expected<StringRef> getStringTableEntry(uint32_t Offset) const;
228
229   static bool isReservedSectionNumber(int16_t SectionNumber);
230
231   // Constructor and "create" factory function. The constructor is only a thin
232   // wrapper around the base constructor. The "create" function fills out the
233   // XCOFF-specific information and performs the error checking along the way.
234   XCOFFObjectFile(unsigned Type, MemoryBufferRef Object);
235   static Expected<std::unique_ptr<XCOFFObjectFile>> create(unsigned Type,
236                                                            MemoryBufferRef MBR);
237
238   // Helper for parsing the StringTable. Returns an 'Error' if parsing failed
239   // and an XCOFFStringTable if parsing succeeded.
240   static Expected<XCOFFStringTable> parseStringTable(const XCOFFObjectFile *Obj,
241                                                      uint64_t Offset);
242
243   // Make a friend so it can call the private 'create' function.
244   friend Expected<std::unique_ptr<ObjectFile>>
245   ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
246
247   void checkSectionAddress(uintptr_t Addr, uintptr_t TableAddr) const;
248
249 public:
250   // Interface inherited from base classes.
251   void moveSymbolNext(DataRefImpl &Symb) const override;
252   uint32_t getSymbolFlags(DataRefImpl Symb) const override;
253   basic_symbol_iterator symbol_begin() const override;
254   basic_symbol_iterator symbol_end() const override;
255
256   Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
257   Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
258   uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
259   uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
260   Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
261   Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
262
263   void moveSectionNext(DataRefImpl &Sec) const override;
264   Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
265   uint64_t getSectionAddress(DataRefImpl Sec) const override;
266   uint64_t getSectionIndex(DataRefImpl Sec) const override;
267   uint64_t getSectionSize(DataRefImpl Sec) const override;
268   Expected<ArrayRef<uint8_t>>
269   getSectionContents(DataRefImpl Sec) const override;
270   uint64_t getSectionAlignment(DataRefImpl Sec) const override;
271   bool isSectionCompressed(DataRefImpl Sec) const override;
272   bool isSectionText(DataRefImpl Sec) const override;
273   bool isSectionData(DataRefImpl Sec) const override;
274   bool isSectionBSS(DataRefImpl Sec) const override;
275
276   bool isSectionVirtual(DataRefImpl Sec) const override;
277   relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
278   relocation_iterator section_rel_end(DataRefImpl Sec) const override;
279
280   void moveRelocationNext(DataRefImpl &Rel) const override;
281   uint64_t getRelocationOffset(DataRefImpl Rel) const override;
282   symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
283   uint64_t getRelocationType(DataRefImpl Rel) const override;
284   void getRelocationTypeName(DataRefImpl Rel,
285                              SmallVectorImpl<char> &Result) const override;
286
287   section_iterator section_begin() const override;
288   section_iterator section_end() const override;
289   uint8_t getBytesInAddress() const override;
290   StringRef getFileFormatName() const override;
291   Triple::ArchType getArch() const override;
292   SubtargetFeatures getFeatures() const override;
293   Expected<uint64_t> getStartAddress() const override;
294   bool isRelocatableObject() const override;
295
296   // Below here is the non-inherited interface.
297   bool is64Bit() const;
298
299   const XCOFFSymbolEntry *getPointerToSymbolTable() const {
300     assert(!is64Bit() && "Symbol table handling not supported yet.");
301     return SymbolTblPtr;
302   }
303
304   Expected<StringRef>
305   getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const;
306
307   const XCOFFSymbolEntry *toSymbolEntry(DataRefImpl Ref) const;
308
309   // File header related interfaces.
310   uint16_t getMagic() const;
311   uint16_t getNumberOfSections() const;
312   int32_t getTimeStamp() const;
313
314   // Symbol table offset and entry count are handled differently between
315   // XCOFF32 and XCOFF64.
316   uint32_t getSymbolTableOffset32() const;
317   uint64_t getSymbolTableOffset64() const;
318
319   // Note that this value is signed and might return a negative value. Negative
320   // values are reserved for future use.
321   int32_t getRawNumberOfSymbolTableEntries32() const;
322
323   // The sanitized value appropriate to use as an index into the symbol table.
324   uint32_t getLogicalNumberOfSymbolTableEntries32() const;
325
326   uint32_t getNumberOfSymbolTableEntries64() const;
327   uint32_t getSymbolIndex(uintptr_t SymEntPtr) const;
328   Expected<StringRef> getSymbolNameByIndex(uint32_t SymbolTableIndex) const;
329
330   Expected<StringRef> getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const;
331   uint16_t getOptionalHeaderSize() const;
332   uint16_t getFlags() const;
333
334   // Section header table related interfaces.
335   ArrayRef<XCOFFSectionHeader32> sections32() const;
336   ArrayRef<XCOFFSectionHeader64> sections64() const;
337
338   int32_t getSectionFlags(DataRefImpl Sec) const;
339   Expected<DataRefImpl> getSectionByNum(int16_t Num) const;
340
341   void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const;
342
343   // Relocation-related interfaces.
344   Expected<uint32_t>
345   getLogicalNumberOfRelocationEntries(const XCOFFSectionHeader32 &Sec) const;
346
347   Expected<ArrayRef<XCOFFRelocation32>>
348   relocations(const XCOFFSectionHeader32 &) const;
349 }; // XCOFFObjectFile
350
351 class XCOFFSymbolRef {
352   const DataRefImpl SymEntDataRef;
353   const XCOFFObjectFile *const OwningObjectPtr;
354
355 public:
356   XCOFFSymbolRef(DataRefImpl SymEntDataRef,
357                  const XCOFFObjectFile *OwningObjectPtr)
358       : SymEntDataRef(SymEntDataRef), OwningObjectPtr(OwningObjectPtr){};
359
360   XCOFF::StorageClass getStorageClass() const;
361   uint8_t getNumberOfAuxEntries() const;
362   const XCOFFCsectAuxEnt32 *getXCOFFCsectAuxEnt32() const;
363   uint16_t getType() const;
364   int16_t getSectionNumber() const;
365
366   bool hasCsectAuxEnt() const;
367   bool isFunction() const;
368 };
369
370 } // namespace object
371 } // namespace llvm
372
373 #endif // LLVM_OBJECT_XCOFFOBJECTFILE_H