1 //===- XCOFFObjectFile.h - XCOFF object file 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 declares the XCOFFObjectFile class.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_OBJECT_XCOFFOBJECTFILE_H
14 #define LLVM_OBJECT_XCOFFOBJECTFILE_H
16 #include "llvm/BinaryFormat/XCOFF.h"
17 #include "llvm/Object/ObjectFile.h"
22 struct XCOFFFileHeader32 {
23 support::ubig16_t Magic;
24 support::ubig16_t NumberOfSections;
26 // Unix time value, value of 0 indicates no timestamp.
27 // Negative values are reserved.
28 support::big32_t TimeStamp;
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;
36 struct XCOFFFileHeader64 {
37 support::ubig16_t Magic;
38 support::ubig16_t NumberOfSections;
40 // Unix time value, value of 0 indicates no timestamp.
41 // Negative values are reserved.
42 support::big32_t TimeStamp;
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;
50 template <typename T> struct XCOFFSectionHeader {
51 // Least significant 3 bits are reserved.
52 static constexpr unsigned SectionFlagsReservedMask = 0x7;
54 // The low order 16 bits of section flags denotes the section type.
55 static constexpr unsigned SectionFlagsTypeMask = 0xffffu;
58 StringRef getName() const;
59 uint16_t getSectionType() const;
60 bool isReservedSectionType() const;
63 // Explicit extern template declarations.
64 struct XCOFFSectionHeader32;
65 struct XCOFFSectionHeader64;
66 extern template struct XCOFFSectionHeader<XCOFFSectionHeader32>;
67 extern template struct XCOFFSectionHeader<XCOFFSectionHeader64>;
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;
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;
96 struct XCOFFSymbolEntry {
97 enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
99 support::big32_t Magic; // Zero indicates name in string table.
100 support::ubig32_t Offset;
106 } CFileLanguageIdAndTypeIdType;
109 char SymbolName[XCOFF::NameSize];
110 NameInStrTblType NameInStrTbl;
113 support::ubig32_t Value; // Symbol value; storage class-dependent.
114 support::big16_t SectionNumber;
117 support::ubig16_t SymbolType;
118 CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
121 XCOFF::StorageClass StorageClass;
122 uint8_t NumberOfAuxEntries;
125 struct XCOFFStringTable {
130 struct XCOFFCsectAuxEnt32 {
132 SectionOrLength; // If the symbol type is XTY_SD or XTY_CM, the csect
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;
145 struct XCOFFFileAuxEnt {
147 support::big32_t Magic; // Zero indicates name in string table.
148 support::ubig32_t Offset;
149 char NamePad[XCOFF::FileNamePadSize];
152 char Name[XCOFF::NameSize + XCOFF::FileNamePadSize];
153 NameInStrTblType NameInStrTbl;
155 XCOFF::CFileStringType Type;
156 uint8_t ReservedZeros[2];
157 uint8_t AuxType; // 64-bit XCOFF file only.
160 struct XCOFFSectAuxEntForStat {
161 support::ubig32_t SectionLength;
162 support::ubig16_t NumberOfRelocEnt;
163 support::ubig16_t NumberOfLineNum;
167 struct XCOFFRelocation32 {
168 // Masks for packing/unpacking the r_rsize field of relocations.
170 // The msb is used to indicate if the bits being relocated are signed or
172 static constexpr uint8_t XR_SIGN_INDICATOR_MASK = 0x80;
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;
178 // The remaining bits specify the bit length of the relocatable reference
180 static constexpr uint8_t XR_BIASED_LENGTH_MASK = 0x3f;
183 support::ubig32_t VirtualAddress;
184 support::ubig32_t SymbolIndex;
186 // Packed field, see XR_* masks for details of packing.
189 XCOFF::RelocationType Type;
192 bool isRelocationSigned() const;
193 bool isFixupIndicated() const;
195 // Returns the number of bits being relocated.
196 uint8_t getRelocatedLength() const;
199 class XCOFFObjectFile : public ObjectFile {
201 const void *FileHeader = nullptr;
202 const void *SectionHeaderTable = nullptr;
204 const XCOFFSymbolEntry *SymbolTblPtr = nullptr;
205 XCOFFStringTable StringTable = {0, nullptr};
207 const XCOFFFileHeader32 *fileHeader32() const;
208 const XCOFFFileHeader64 *fileHeader64() const;
210 const XCOFFSectionHeader32 *sectionHeaderTable32() const;
211 const XCOFFSectionHeader64 *sectionHeaderTable64() const;
213 size_t getFileHeaderSize() const;
214 size_t getSectionHeaderSize() const;
216 const XCOFFSectionHeader32 *toSection32(DataRefImpl Ref) const;
217 const XCOFFSectionHeader64 *toSection64(DataRefImpl Ref) const;
218 uintptr_t getSectionHeaderTableAddress() const;
219 uintptr_t getEndOfSymbolTableAddress() const;
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
224 const char *getSectionNameInternal(DataRefImpl Sec) const;
226 // This function returns string table entry.
227 Expected<StringRef> getStringTableEntry(uint32_t Offset) const;
229 static bool isReservedSectionNumber(int16_t SectionNumber);
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);
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,
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);
247 void checkSectionAddress(uintptr_t Addr, uintptr_t TableAddr) const;
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;
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;
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;
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;
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;
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;
296 // Below here is the non-inherited interface.
297 bool is64Bit() const;
299 const XCOFFSymbolEntry *getPointerToSymbolTable() const {
300 assert(!is64Bit() && "Symbol table handling not supported yet.");
305 getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const;
307 const XCOFFSymbolEntry *toSymbolEntry(DataRefImpl Ref) const;
309 // File header related interfaces.
310 uint16_t getMagic() const;
311 uint16_t getNumberOfSections() const;
312 int32_t getTimeStamp() const;
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;
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;
323 // The sanitized value appropriate to use as an index into the symbol table.
324 uint32_t getLogicalNumberOfSymbolTableEntries32() const;
326 uint32_t getNumberOfSymbolTableEntries64() const;
327 uint32_t getSymbolIndex(uintptr_t SymEntPtr) const;
328 Expected<StringRef> getSymbolNameByIndex(uint32_t SymbolTableIndex) const;
330 Expected<StringRef> getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const;
331 uint16_t getOptionalHeaderSize() const;
332 uint16_t getFlags() const;
334 // Section header table related interfaces.
335 ArrayRef<XCOFFSectionHeader32> sections32() const;
336 ArrayRef<XCOFFSectionHeader64> sections64() const;
338 int32_t getSectionFlags(DataRefImpl Sec) const;
339 Expected<DataRefImpl> getSectionByNum(int16_t Num) const;
341 void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const;
343 // Relocation-related interfaces.
345 getLogicalNumberOfRelocationEntries(const XCOFFSectionHeader32 &Sec) const;
347 Expected<ArrayRef<XCOFFRelocation32>>
348 relocations(const XCOFFSectionHeader32 &) const;
349 }; // XCOFFObjectFile
351 class XCOFFSymbolRef {
352 const DataRefImpl SymEntDataRef;
353 const XCOFFObjectFile *const OwningObjectPtr;
356 XCOFFSymbolRef(DataRefImpl SymEntDataRef,
357 const XCOFFObjectFile *OwningObjectPtr)
358 : SymEntDataRef(SymEntDataRef), OwningObjectPtr(OwningObjectPtr){};
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;
366 bool hasCsectAuxEnt() const;
367 bool isFunction() const;
370 } // namespace object
373 #endif // LLVM_OBJECT_XCOFFOBJECTFILE_H