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 struct XCOFFSectionHeader32
{
51 char Name
[XCOFF::NameSize
];
52 support::ubig32_t PhysicalAddress
;
53 support::ubig32_t VirtualAddress
;
54 support::ubig32_t SectionSize
;
55 support::ubig32_t FileOffsetToRawData
;
56 support::ubig32_t FileOffsetToRelocationInfo
;
57 support::ubig32_t FileOffsetToLineNumberInfo
;
58 support::ubig16_t NumberOfRelocations
;
59 support::ubig16_t NumberOfLineNumbers
;
60 support::big32_t Flags
;
62 StringRef
getName() const;
65 struct XCOFFSectionHeader64
{
66 char Name
[XCOFF::NameSize
];
67 support::ubig64_t PhysicalAddress
;
68 support::ubig64_t VirtualAddress
;
69 support::ubig64_t SectionSize
;
70 support::big64_t FileOffsetToRawData
;
71 support::big64_t FileOffsetToRelocationInfo
;
72 support::big64_t FileOffsetToLineNumberInfo
;
73 support::ubig32_t NumberOfRelocations
;
74 support::ubig32_t NumberOfLineNumbers
;
75 support::big32_t Flags
;
78 StringRef
getName() const;
81 struct XCOFFSymbolEntry
{
82 enum { NAME_IN_STR_TBL_MAGIC
= 0x0 };
84 support::big32_t Magic
; // Zero indicates name in string table.
85 support::ubig32_t Offset
;
91 } CFileLanguageIdAndTypeIdType
;
94 char SymbolName
[XCOFF::NameSize
];
95 NameInStrTblType NameInStrTbl
;
98 support::ubig32_t Value
; // Symbol value; storage class-dependent.
99 support::big16_t SectionNumber
;
102 support::ubig16_t SymbolType
;
103 CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId
;
106 XCOFF::StorageClass StorageClass
;
107 uint8_t NumberOfAuxEntries
;
110 struct XCOFFStringTable
{
115 struct XCOFFCsectAuxEnt32
{
117 SectionOrLength
; // If the symbol type is XTY_SD or XTY_CM, the csect
119 // If the symbol type is XTY_LD, the symbol table
120 // index of the containing csect.
121 // If the symbol type is XTY_ER, 0.
122 support::ubig32_t ParameterHashIndex
;
123 support::ubig16_t TypeChkSectNum
;
124 uint8_t SymbolAlignmentAndType
;
125 XCOFF::StorageMappingClass StorageMappingClass
;
126 support::ubig32_t StabInfoIndex
;
127 support::ubig16_t StabSectNum
;
130 struct XCOFFFileAuxEnt
{
132 support::big32_t Magic
; // Zero indicates name in string table.
133 support::ubig32_t Offset
;
134 char NamePad
[XCOFF::FileNamePadSize
];
137 char Name
[XCOFF::NameSize
+ XCOFF::FileNamePadSize
];
138 NameInStrTblType NameInStrTbl
;
140 XCOFF::CFileStringType Type
;
141 uint8_t ReservedZeros
[2];
142 uint8_t AuxType
; // 64-bit XCOFF file only.
145 struct XCOFFSectAuxEntForStat
{
146 support::ubig32_t SectionLength
;
147 support::ubig16_t NumberOfRelocEnt
;
148 support::ubig16_t NumberOfLineNum
;
152 struct XCOFFRelocation32
{
153 // Masks for packing/unpacking the r_rsize field of relocations.
155 // The msb is used to indicate if the bits being relocated are signed or
157 static constexpr uint8_t XR_SIGN_INDICATOR_MASK
= 0x80;
159 // The 2nd msb is used to indicate that the binder has replaced/modified the
160 // original instruction.
161 static constexpr uint8_t XR_FIXUP_INDICATOR_MASK
= 0x40;
163 // The remaining bits specify the bit length of the relocatable reference
165 static constexpr uint8_t XR_BIASED_LENGTH_MASK
= 0x3f;
168 support::ubig32_t VirtualAddress
;
169 support::ubig32_t SymbolIndex
;
171 // Packed field, see XR_* masks for details of packing.
174 XCOFF::RelocationType Type
;
177 bool isRelocationSigned() const;
178 bool isFixupIndicated() const;
180 // Returns the number of bits being relocated.
181 uint8_t getRelocatedLength() const;
184 class XCOFFObjectFile
: public ObjectFile
{
186 const void *FileHeader
= nullptr;
187 const void *SectionHeaderTable
= nullptr;
189 const XCOFFSymbolEntry
*SymbolTblPtr
= nullptr;
190 XCOFFStringTable StringTable
= {0, nullptr};
192 const XCOFFFileHeader32
*fileHeader32() const;
193 const XCOFFFileHeader64
*fileHeader64() const;
195 const XCOFFSectionHeader32
*sectionHeaderTable32() const;
196 const XCOFFSectionHeader64
*sectionHeaderTable64() const;
198 size_t getFileHeaderSize() const;
199 size_t getSectionHeaderSize() const;
201 const XCOFFSectionHeader32
*toSection32(DataRefImpl Ref
) const;
202 const XCOFFSectionHeader64
*toSection64(DataRefImpl Ref
) const;
203 uintptr_t getSectionHeaderTableAddress() const;
204 uintptr_t getEndOfSymbolTableAddress() const;
206 // This returns a pointer to the start of the storage for the name field of
207 // the 32-bit or 64-bit SectionHeader struct. This string is *not* necessarily
209 const char *getSectionNameInternal(DataRefImpl Sec
) const;
211 // This function returns string table entry.
212 Expected
<StringRef
> getStringTableEntry(uint32_t Offset
) const;
214 static bool isReservedSectionNumber(int16_t SectionNumber
);
216 // Constructor and "create" factory function. The constructor is only a thin
217 // wrapper around the base constructor. The "create" function fills out the
218 // XCOFF-specific information and performs the error checking along the way.
219 XCOFFObjectFile(unsigned Type
, MemoryBufferRef Object
);
220 static Expected
<std::unique_ptr
<XCOFFObjectFile
>> create(unsigned Type
,
221 MemoryBufferRef MBR
);
223 // Helper for parsing the StringTable. Returns an 'Error' if parsing failed
224 // and an XCOFFStringTable if parsing succeeded.
225 static Expected
<XCOFFStringTable
> parseStringTable(const XCOFFObjectFile
*Obj
,
228 // Make a friend so it can call the private 'create' function.
229 friend Expected
<std::unique_ptr
<ObjectFile
>>
230 ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object
, unsigned FileType
);
232 void checkSectionAddress(uintptr_t Addr
, uintptr_t TableAddr
) const;
235 // Interface inherited from base classes.
236 void moveSymbolNext(DataRefImpl
&Symb
) const override
;
237 uint32_t getSymbolFlags(DataRefImpl Symb
) const override
;
238 basic_symbol_iterator
symbol_begin() const override
;
239 basic_symbol_iterator
symbol_end() const override
;
241 Expected
<StringRef
> getSymbolName(DataRefImpl Symb
) const override
;
242 Expected
<uint64_t> getSymbolAddress(DataRefImpl Symb
) const override
;
243 uint64_t getSymbolValueImpl(DataRefImpl Symb
) const override
;
244 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb
) const override
;
245 Expected
<SymbolRef::Type
> getSymbolType(DataRefImpl Symb
) const override
;
246 Expected
<section_iterator
> getSymbolSection(DataRefImpl Symb
) const override
;
248 void moveSectionNext(DataRefImpl
&Sec
) const override
;
249 Expected
<StringRef
> getSectionName(DataRefImpl Sec
) const override
;
250 uint64_t getSectionAddress(DataRefImpl Sec
) const override
;
251 uint64_t getSectionIndex(DataRefImpl Sec
) const override
;
252 uint64_t getSectionSize(DataRefImpl Sec
) const override
;
253 Expected
<ArrayRef
<uint8_t>>
254 getSectionContents(DataRefImpl Sec
) const override
;
255 uint64_t getSectionAlignment(DataRefImpl Sec
) const override
;
256 bool isSectionCompressed(DataRefImpl Sec
) const override
;
257 bool isSectionText(DataRefImpl Sec
) const override
;
258 bool isSectionData(DataRefImpl Sec
) const override
;
259 bool isSectionBSS(DataRefImpl Sec
) const override
;
261 bool isSectionVirtual(DataRefImpl Sec
) const override
;
262 relocation_iterator
section_rel_begin(DataRefImpl Sec
) const override
;
263 relocation_iterator
section_rel_end(DataRefImpl Sec
) const override
;
265 void moveRelocationNext(DataRefImpl
&Rel
) const override
;
266 uint64_t getRelocationOffset(DataRefImpl Rel
) const override
;
267 symbol_iterator
getRelocationSymbol(DataRefImpl Rel
) const override
;
268 uint64_t getRelocationType(DataRefImpl Rel
) const override
;
269 void getRelocationTypeName(DataRefImpl Rel
,
270 SmallVectorImpl
<char> &Result
) const override
;
272 section_iterator
section_begin() const override
;
273 section_iterator
section_end() const override
;
274 uint8_t getBytesInAddress() const override
;
275 StringRef
getFileFormatName() const override
;
276 Triple::ArchType
getArch() const override
;
277 SubtargetFeatures
getFeatures() const override
;
278 Expected
<uint64_t> getStartAddress() const override
;
279 bool isRelocatableObject() const override
;
281 // Below here is the non-inherited interface.
282 bool is64Bit() const;
284 const XCOFFSymbolEntry
*getPointerToSymbolTable() const {
285 assert(!is64Bit() && "Symbol table handling not supported yet.");
290 getSymbolSectionName(const XCOFFSymbolEntry
*SymEntPtr
) const;
292 const XCOFFSymbolEntry
*toSymbolEntry(DataRefImpl Ref
) const;
294 // File header related interfaces.
295 uint16_t getMagic() const;
296 uint16_t getNumberOfSections() const;
297 int32_t getTimeStamp() const;
299 // Symbol table offset and entry count are handled differently between
300 // XCOFF32 and XCOFF64.
301 uint32_t getSymbolTableOffset32() const;
302 uint64_t getSymbolTableOffset64() const;
304 // Note that this value is signed and might return a negative value. Negative
305 // values are reserved for future use.
306 int32_t getRawNumberOfSymbolTableEntries32() const;
308 // The sanitized value appropriate to use as an index into the symbol table.
309 uint32_t getLogicalNumberOfSymbolTableEntries32() const;
311 uint32_t getNumberOfSymbolTableEntries64() const;
312 uint32_t getSymbolIndex(uintptr_t SymEntPtr
) const;
313 Expected
<StringRef
> getSymbolNameByIndex(uint32_t SymbolTableIndex
) const;
315 Expected
<StringRef
> getCFileName(const XCOFFFileAuxEnt
*CFileEntPtr
) const;
316 uint16_t getOptionalHeaderSize() const;
317 uint16_t getFlags() const;
319 // Section header table related interfaces.
320 ArrayRef
<XCOFFSectionHeader32
> sections32() const;
321 ArrayRef
<XCOFFSectionHeader64
> sections64() const;
323 int32_t getSectionFlags(DataRefImpl Sec
) const;
324 Expected
<DataRefImpl
> getSectionByNum(int16_t Num
) const;
326 void checkSymbolEntryPointer(uintptr_t SymbolEntPtr
) const;
328 // Relocation-related interfaces.
330 getLogicalNumberOfRelocationEntries(const XCOFFSectionHeader32
&Sec
) const;
332 Expected
<ArrayRef
<XCOFFRelocation32
>>
333 relocations(const XCOFFSectionHeader32
&) const;
334 }; // XCOFFObjectFile
336 class XCOFFSymbolRef
{
337 const DataRefImpl SymEntDataRef
;
338 const XCOFFObjectFile
*const OwningObjectPtr
;
341 XCOFFSymbolRef(DataRefImpl SymEntDataRef
,
342 const XCOFFObjectFile
*OwningObjectPtr
)
343 : SymEntDataRef(SymEntDataRef
), OwningObjectPtr(OwningObjectPtr
){};
345 XCOFF::StorageClass
getStorageClass() const;
346 uint8_t getNumberOfAuxEntries() const;
347 const XCOFFCsectAuxEnt32
*getXCOFFCsectAuxEnt32() const;
348 uint16_t getType() const;
349 int16_t getSectionNumber() const;
351 bool hasCsectAuxEnt() const;
352 bool isFunction() const;
355 } // namespace object
358 #endif // LLVM_OBJECT_XCOFFOBJECTFILE_H