File indexing completed on 2026-05-10 08:44:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_OBJECT_XCOFFOBJECTFILE_H
0014 #define LLVM_OBJECT_XCOFFOBJECTFILE_H
0015
0016 #include "llvm/ADT/SmallString.h"
0017 #include "llvm/ADT/SmallVector.h"
0018 #include "llvm/ADT/iterator_range.h"
0019 #include "llvm/BinaryFormat/XCOFF.h"
0020 #include "llvm/Object/ObjectFile.h"
0021 #include "llvm/Support/Compiler.h"
0022 #include "llvm/Support/Endian.h"
0023 #include <limits>
0024
0025 namespace llvm {
0026 namespace object {
0027
0028 class xcoff_symbol_iterator;
0029
0030 struct XCOFFFileHeader32 {
0031 support::ubig16_t Magic;
0032 support::ubig16_t NumberOfSections;
0033
0034
0035
0036 support::big32_t TimeStamp;
0037
0038 support::ubig32_t SymbolTableOffset;
0039 support::big32_t NumberOfSymTableEntries;
0040 support::ubig16_t AuxHeaderSize;
0041 support::ubig16_t Flags;
0042 };
0043
0044 struct XCOFFFileHeader64 {
0045 support::ubig16_t Magic;
0046 support::ubig16_t NumberOfSections;
0047
0048
0049
0050 support::big32_t TimeStamp;
0051
0052 support::ubig64_t SymbolTableOffset;
0053 support::ubig16_t AuxHeaderSize;
0054 support::ubig16_t Flags;
0055 support::ubig32_t NumberOfSymTableEntries;
0056 };
0057
0058 template <typename T> struct XCOFFAuxiliaryHeader {
0059 static constexpr uint8_t AuxiHeaderFlagMask = 0xF0;
0060 static constexpr uint8_t AuxiHeaderTDataAlignmentMask = 0x0F;
0061
0062 public:
0063 uint8_t getFlag() const {
0064 return static_cast<const T *>(this)->FlagAndTDataAlignment &
0065 AuxiHeaderFlagMask;
0066 }
0067
0068 uint8_t getTDataAlignment() const {
0069 return static_cast<const T *>(this)->FlagAndTDataAlignment &
0070 AuxiHeaderTDataAlignmentMask;
0071 }
0072
0073 uint16_t getVersion() const { return static_cast<const T *>(this)->Version; }
0074 uint64_t getEntryPointAddr() const {
0075 return static_cast<const T *>(this)->EntryPointAddr;
0076 }
0077 };
0078
0079 struct XCOFFAuxiliaryHeader32 : XCOFFAuxiliaryHeader<XCOFFAuxiliaryHeader32> {
0080 support::ubig16_t
0081 AuxMagic;
0082
0083
0084 support::ubig16_t
0085 Version;
0086
0087
0088 support::ubig32_t TextSize;
0089 support::ubig32_t InitDataSize;
0090 support::ubig32_t BssDataSize;
0091 support::ubig32_t EntryPointAddr;
0092 support::ubig32_t TextStartAddr;
0093 support::ubig32_t DataStartAddr;
0094 support::ubig32_t TOCAnchorAddr;
0095 support::ubig16_t SecNumOfEntryPoint;
0096 support::ubig16_t SecNumOfText;
0097 support::ubig16_t SecNumOfData;
0098 support::ubig16_t SecNumOfTOC;
0099 support::ubig16_t SecNumOfLoader;
0100 support::ubig16_t SecNumOfBSS;
0101 support::ubig16_t MaxAlignOfText;
0102 support::ubig16_t MaxAlignOfData;
0103 support::ubig16_t ModuleType;
0104 uint8_t CpuFlag;
0105 uint8_t CpuType;
0106 support::ubig32_t MaxStackSize;
0107
0108 support::ubig32_t MaxDataSize;
0109
0110 support::ubig32_t
0111 ReservedForDebugger;
0112
0113
0114
0115 uint8_t TextPageSize;
0116
0117 uint8_t DataPageSize;
0118
0119 uint8_t StackPageSize;
0120
0121 uint8_t FlagAndTDataAlignment;
0122 support::ubig16_t SecNumOfTData;
0123 support::ubig16_t SecNumOfTBSS;
0124 };
0125
0126 struct XCOFFAuxiliaryHeader64 : XCOFFAuxiliaryHeader<XCOFFAuxiliaryHeader64> {
0127 support::ubig16_t AuxMagic;
0128 support::ubig16_t Version;
0129 support::ubig32_t ReservedForDebugger;
0130 support::ubig64_t TextStartAddr;
0131 support::ubig64_t DataStartAddr;
0132 support::ubig64_t TOCAnchorAddr;
0133 support::ubig16_t SecNumOfEntryPoint;
0134 support::ubig16_t SecNumOfText;
0135 support::ubig16_t SecNumOfData;
0136 support::ubig16_t SecNumOfTOC;
0137 support::ubig16_t SecNumOfLoader;
0138 support::ubig16_t SecNumOfBSS;
0139 support::ubig16_t MaxAlignOfText;
0140 support::ubig16_t MaxAlignOfData;
0141 support::ubig16_t ModuleType;
0142 uint8_t CpuFlag;
0143 uint8_t CpuType;
0144 uint8_t TextPageSize;
0145 uint8_t DataPageSize;
0146 uint8_t StackPageSize;
0147 uint8_t FlagAndTDataAlignment;
0148 support::ubig64_t TextSize;
0149 support::ubig64_t InitDataSize;
0150 support::ubig64_t BssDataSize;
0151 support::ubig64_t EntryPointAddr;
0152 support::ubig64_t MaxStackSize;
0153 support::ubig64_t MaxDataSize;
0154 support::ubig16_t SecNumOfTData;
0155 support::ubig16_t SecNumOfTBSS;
0156 support::ubig16_t XCOFF64Flag;
0157 };
0158
0159 template <typename T> struct XCOFFSectionHeader {
0160
0161
0162 static constexpr unsigned SectionFlagsReservedMask = 0x7;
0163
0164
0165
0166
0167 static constexpr unsigned SectionFlagsTypeMask = 0xffffu;
0168
0169 public:
0170 StringRef getName() const;
0171 uint16_t getSectionType() const;
0172 uint32_t getSectionSubtype() const;
0173 bool isReservedSectionType() const;
0174 };
0175
0176
0177 struct XCOFFSectionHeader32;
0178 struct XCOFFSectionHeader64;
0179 extern template struct XCOFFSectionHeader<XCOFFSectionHeader32>;
0180 extern template struct XCOFFSectionHeader<XCOFFSectionHeader64>;
0181
0182 struct XCOFFSectionHeader32 : XCOFFSectionHeader<XCOFFSectionHeader32> {
0183 char Name[XCOFF::NameSize];
0184 support::ubig32_t PhysicalAddress;
0185 support::ubig32_t VirtualAddress;
0186 support::ubig32_t SectionSize;
0187 support::ubig32_t FileOffsetToRawData;
0188 support::ubig32_t FileOffsetToRelocationInfo;
0189 support::ubig32_t FileOffsetToLineNumberInfo;
0190 support::ubig16_t NumberOfRelocations;
0191 support::ubig16_t NumberOfLineNumbers;
0192 support::big32_t Flags;
0193 };
0194
0195 struct XCOFFSectionHeader64 : XCOFFSectionHeader<XCOFFSectionHeader64> {
0196 char Name[XCOFF::NameSize];
0197 support::ubig64_t PhysicalAddress;
0198 support::ubig64_t VirtualAddress;
0199 support::ubig64_t SectionSize;
0200 support::big64_t FileOffsetToRawData;
0201 support::big64_t FileOffsetToRelocationInfo;
0202 support::big64_t FileOffsetToLineNumberInfo;
0203 support::ubig32_t NumberOfRelocations;
0204 support::ubig32_t NumberOfLineNumbers;
0205 support::big32_t Flags;
0206 char Padding[4];
0207 };
0208
0209 struct LoaderSectionHeader32;
0210 struct LoaderSectionHeader64;
0211 struct LoaderSectionSymbolEntry32 {
0212 struct NameOffsetInStrTbl {
0213 support::big32_t IsNameInStrTbl;
0214 support::ubig32_t Offset;
0215 };
0216
0217 char SymbolName[XCOFF::NameSize];
0218 support::ubig32_t Value;
0219 support::big16_t SectionNumber;
0220 uint8_t SymbolType;
0221 XCOFF::StorageClass StorageClass;
0222 support::ubig32_t ImportFileID;
0223 support::ubig32_t ParameterTypeCheck;
0224
0225 Expected<StringRef>
0226 getSymbolName(const LoaderSectionHeader32 *LoaderSecHeader) const;
0227 };
0228
0229 struct LoaderSectionSymbolEntry64 {
0230 support::ubig64_t Value;
0231 support::ubig32_t Offset;
0232 support::big16_t SectionNumber;
0233 uint8_t SymbolType;
0234 XCOFF::StorageClass StorageClass;
0235 support::ubig32_t ImportFileID;
0236 support::ubig32_t ParameterTypeCheck;
0237
0238 Expected<StringRef>
0239 getSymbolName(const LoaderSectionHeader64 *LoaderSecHeader) const;
0240 };
0241
0242 struct LoaderSectionRelocationEntry32 {
0243 support::ubig32_t VirtualAddr;
0244 support::big32_t SymbolIndex;
0245 support::ubig16_t Type;
0246 support::big16_t SectionNum;
0247 };
0248
0249 struct LoaderSectionRelocationEntry64 {
0250 support::ubig64_t VirtualAddr;
0251 support::ubig16_t Type;
0252 support::big16_t SectionNum;
0253 support::big32_t SymbolIndex;
0254 };
0255
0256 struct LoaderSectionHeader32 {
0257 support::ubig32_t Version;
0258 support::ubig32_t NumberOfSymTabEnt;
0259 support::ubig32_t NumberOfRelTabEnt;
0260 support::ubig32_t LengthOfImpidStrTbl;
0261 support::ubig32_t NumberOfImpid;
0262 support::big32_t OffsetToImpid;
0263 support::ubig32_t LengthOfStrTbl;
0264 support::big32_t OffsetToStrTbl;
0265
0266 uint64_t getOffsetToSymTbl() const {
0267 return NumberOfSymTabEnt == 0 ? 0 : sizeof(LoaderSectionHeader32);
0268 }
0269
0270 uint64_t getOffsetToRelEnt() const {
0271
0272 return NumberOfRelTabEnt == 0
0273 ? 0
0274 : sizeof(LoaderSectionHeader32) +
0275 sizeof(LoaderSectionSymbolEntry32) * NumberOfSymTabEnt;
0276 }
0277 };
0278
0279 struct LoaderSectionHeader64 {
0280 support::ubig32_t Version;
0281 support::ubig32_t NumberOfSymTabEnt;
0282 support::ubig32_t NumberOfRelTabEnt;
0283 support::ubig32_t LengthOfImpidStrTbl;
0284 support::ubig32_t NumberOfImpid;
0285 support::ubig32_t LengthOfStrTbl;
0286 support::big64_t OffsetToImpid;
0287 support::big64_t OffsetToStrTbl;
0288 support::big64_t OffsetToSymTbl;
0289 support::big64_t OffsetToRelEnt;
0290
0291 uint64_t getOffsetToSymTbl() const { return OffsetToSymTbl; }
0292 uint64_t getOffsetToRelEnt() const { return OffsetToRelEnt; }
0293 };
0294
0295 template <typename AddressType> struct ExceptionSectionEntry {
0296 union {
0297 support::ubig32_t SymbolIdx;
0298 AddressType TrapInstAddr;
0299 };
0300 uint8_t LangId;
0301 uint8_t Reason;
0302
0303 uint32_t getSymbolIndex() const {
0304 assert(Reason == 0 && "Get symbol table index of the function only when "
0305 "the e_reason field is 0.");
0306 return SymbolIdx;
0307 }
0308
0309 uint64_t getTrapInstAddr() const {
0310 assert(Reason != 0 && "Zero is not a valid trap exception reason code.");
0311 return TrapInstAddr;
0312 }
0313 uint8_t getLangID() const { return LangId; }
0314 uint8_t getReason() const { return Reason; }
0315 };
0316
0317 typedef ExceptionSectionEntry<support::ubig32_t> ExceptionSectionEntry32;
0318 typedef ExceptionSectionEntry<support::ubig64_t> ExceptionSectionEntry64;
0319
0320
0321 extern template struct ExceptionSectionEntry<support::ubig32_t>;
0322 extern template struct ExceptionSectionEntry<support::ubig64_t>;
0323
0324 struct XCOFFStringTable {
0325 uint32_t Size;
0326 const char *Data;
0327 };
0328
0329 struct XCOFFCsectAuxEnt32 {
0330 support::ubig32_t SectionOrLength;
0331 support::ubig32_t ParameterHashIndex;
0332 support::ubig16_t TypeChkSectNum;
0333 uint8_t SymbolAlignmentAndType;
0334 XCOFF::StorageMappingClass StorageMappingClass;
0335 support::ubig32_t StabInfoIndex;
0336 support::ubig16_t StabSectNum;
0337 };
0338
0339 struct XCOFFCsectAuxEnt64 {
0340 support::ubig32_t SectionOrLengthLowByte;
0341 support::ubig32_t ParameterHashIndex;
0342 support::ubig16_t TypeChkSectNum;
0343 uint8_t SymbolAlignmentAndType;
0344 XCOFF::StorageMappingClass StorageMappingClass;
0345 support::ubig32_t SectionOrLengthHighByte;
0346 uint8_t Pad;
0347 XCOFF::SymbolAuxType AuxType;
0348 };
0349
0350 class XCOFFCsectAuxRef {
0351 public:
0352 static constexpr uint8_t SymbolTypeMask = 0x07;
0353 static constexpr uint8_t SymbolAlignmentMask = 0xF8;
0354 static constexpr size_t SymbolAlignmentBitOffset = 3;
0355
0356 XCOFFCsectAuxRef(const XCOFFCsectAuxEnt32 *Entry32) : Entry32(Entry32) {}
0357 XCOFFCsectAuxRef(const XCOFFCsectAuxEnt64 *Entry64) : Entry64(Entry64) {}
0358
0359
0360
0361
0362
0363
0364 uint64_t getSectionOrLength() const {
0365 return Entry32 ? getSectionOrLength32() : getSectionOrLength64();
0366 }
0367
0368 uint32_t getSectionOrLength32() const {
0369 assert(Entry32 && "32-bit interface called on 64-bit object file.");
0370 return Entry32->SectionOrLength;
0371 }
0372
0373 uint64_t getSectionOrLength64() const {
0374 assert(Entry64 && "64-bit interface called on 32-bit object file.");
0375 return (static_cast<uint64_t>(Entry64->SectionOrLengthHighByte) << 32) |
0376 Entry64->SectionOrLengthLowByte;
0377 }
0378
0379 #define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X
0380
0381 uint32_t getParameterHashIndex() const {
0382 return GETVALUE(ParameterHashIndex);
0383 }
0384
0385 uint16_t getTypeChkSectNum() const { return GETVALUE(TypeChkSectNum); }
0386
0387 XCOFF::StorageMappingClass getStorageMappingClass() const {
0388 return GETVALUE(StorageMappingClass);
0389 }
0390
0391 uintptr_t getEntryAddress() const {
0392 return Entry32 ? reinterpret_cast<uintptr_t>(Entry32)
0393 : reinterpret_cast<uintptr_t>(Entry64);
0394 }
0395
0396 uint16_t getAlignmentLog2() const {
0397 return (getSymbolAlignmentAndType() & SymbolAlignmentMask) >>
0398 SymbolAlignmentBitOffset;
0399 }
0400
0401 uint8_t getSymbolType() const {
0402 return getSymbolAlignmentAndType() & SymbolTypeMask;
0403 }
0404
0405 bool isLabel() const { return getSymbolType() == XCOFF::XTY_LD; }
0406
0407 uint32_t getStabInfoIndex32() const {
0408 assert(Entry32 && "32-bit interface called on 64-bit object file.");
0409 return Entry32->StabInfoIndex;
0410 }
0411
0412 uint16_t getStabSectNum32() const {
0413 assert(Entry32 && "32-bit interface called on 64-bit object file.");
0414 return Entry32->StabSectNum;
0415 }
0416
0417 XCOFF::SymbolAuxType getAuxType64() const {
0418 assert(Entry64 && "64-bit interface called on 32-bit object file.");
0419 return Entry64->AuxType;
0420 }
0421
0422 uint8_t getSymbolAlignmentAndType() const {
0423 return GETVALUE(SymbolAlignmentAndType);
0424 }
0425
0426 #undef GETVALUE
0427
0428 private:
0429 const XCOFFCsectAuxEnt32 *Entry32 = nullptr;
0430 const XCOFFCsectAuxEnt64 *Entry64 = nullptr;
0431 };
0432
0433 struct XCOFFFileAuxEnt {
0434 typedef struct {
0435 support::big32_t Magic;
0436 support::ubig32_t Offset;
0437 char NamePad[XCOFF::FileNamePadSize];
0438 } NameInStrTblType;
0439 union {
0440 char Name[XCOFF::NameSize + XCOFF::FileNamePadSize];
0441 NameInStrTblType NameInStrTbl;
0442 };
0443 XCOFF::CFileStringType Type;
0444 uint8_t ReservedZeros[2];
0445 XCOFF::SymbolAuxType AuxType;
0446 };
0447
0448 struct XCOFFSectAuxEntForStat {
0449 support::ubig32_t SectionLength;
0450 support::ubig16_t NumberOfRelocEnt;
0451 support::ubig16_t NumberOfLineNum;
0452 uint8_t Pad[10];
0453 };
0454
0455 struct XCOFFFunctionAuxEnt32 {
0456 support::ubig32_t OffsetToExceptionTbl;
0457 support::ubig32_t SizeOfFunction;
0458 support::ubig32_t PtrToLineNum;
0459 support::big32_t SymIdxOfNextBeyond;
0460 uint8_t Pad[2];
0461 };
0462
0463 struct XCOFFFunctionAuxEnt64 {
0464 support::ubig64_t PtrToLineNum;
0465 support::ubig32_t SizeOfFunction;
0466 support::big32_t SymIdxOfNextBeyond;
0467 uint8_t Pad;
0468 XCOFF::SymbolAuxType AuxType;
0469 };
0470
0471 struct XCOFFExceptionAuxEnt {
0472 support::ubig64_t OffsetToExceptionTbl;
0473 support::ubig32_t SizeOfFunction;
0474 support::big32_t SymIdxOfNextBeyond;
0475 uint8_t Pad;
0476 XCOFF::SymbolAuxType AuxType;
0477 };
0478
0479 struct XCOFFBlockAuxEnt32 {
0480 uint8_t ReservedZeros1[2];
0481 support::ubig16_t LineNumHi;
0482 support::ubig16_t LineNumLo;
0483 uint8_t ReservedZeros2[12];
0484 };
0485
0486 struct XCOFFBlockAuxEnt64 {
0487 support::ubig32_t LineNum;
0488 uint8_t Pad[13];
0489 XCOFF::SymbolAuxType AuxType;
0490 };
0491
0492 struct XCOFFSectAuxEntForDWARF32 {
0493 support::ubig32_t LengthOfSectionPortion;
0494 uint8_t Pad1[4];
0495 support::ubig32_t NumberOfRelocEnt;
0496 uint8_t Pad2[6];
0497 };
0498
0499 struct XCOFFSectAuxEntForDWARF64 {
0500 support::ubig64_t LengthOfSectionPortion;
0501 support::ubig64_t NumberOfRelocEnt;
0502 uint8_t Pad;
0503 XCOFF::SymbolAuxType AuxType;
0504 };
0505
0506 template <typename AddressType> struct XCOFFRelocation {
0507 public:
0508 AddressType VirtualAddress;
0509 support::ubig32_t SymbolIndex;
0510
0511
0512 uint8_t Info;
0513
0514 XCOFF::RelocationType Type;
0515
0516 public:
0517 bool isRelocationSigned() const;
0518 bool isFixupIndicated() const;
0519
0520
0521 uint8_t getRelocatedLength() const;
0522 };
0523
0524 extern template struct XCOFFRelocation<llvm::support::ubig32_t>;
0525 extern template struct XCOFFRelocation<llvm::support::ubig64_t>;
0526
0527 struct XCOFFRelocation32 : XCOFFRelocation<llvm::support::ubig32_t> {};
0528 struct XCOFFRelocation64 : XCOFFRelocation<llvm::support::ubig64_t> {};
0529
0530 class XCOFFSymbolRef;
0531
0532 class XCOFFObjectFile : public ObjectFile {
0533 private:
0534 const void *FileHeader = nullptr;
0535 const void *AuxiliaryHeader = nullptr;
0536 const void *SectionHeaderTable = nullptr;
0537
0538 const void *SymbolTblPtr = nullptr;
0539 XCOFFStringTable StringTable = {0, nullptr};
0540
0541 const XCOFFSectionHeader32 *sectionHeaderTable32() const;
0542 const XCOFFSectionHeader64 *sectionHeaderTable64() const;
0543 template <typename T> const T *sectionHeaderTable() const;
0544
0545 size_t getFileHeaderSize() const;
0546 size_t getSectionHeaderSize() const;
0547
0548 const XCOFFSectionHeader32 *toSection32(DataRefImpl Ref) const;
0549 const XCOFFSectionHeader64 *toSection64(DataRefImpl Ref) const;
0550 uintptr_t getSectionHeaderTableAddress() const;
0551 uintptr_t getEndOfSymbolTableAddress() const;
0552
0553 DataRefImpl getSectionByType(XCOFF::SectionTypeFlags SectType) const;
0554 uint64_t getSectionFileOffsetToRawData(DataRefImpl Sec) const;
0555
0556
0557
0558
0559 const char *getSectionNameInternal(DataRefImpl Sec) const;
0560
0561 static bool isReservedSectionNumber(int16_t SectionNumber);
0562
0563
0564
0565
0566 XCOFFObjectFile(unsigned Type, MemoryBufferRef Object);
0567 static Expected<std::unique_ptr<XCOFFObjectFile>> create(unsigned Type,
0568 MemoryBufferRef MBR);
0569
0570
0571
0572 static Expected<XCOFFStringTable> parseStringTable(const XCOFFObjectFile *Obj,
0573 uint64_t Offset);
0574
0575
0576 friend Expected<std::unique_ptr<ObjectFile>>
0577 ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
0578
0579 void checkSectionAddress(uintptr_t Addr, uintptr_t TableAddr) const;
0580
0581 public:
0582 static constexpr uint64_t InvalidRelocOffset =
0583 std::numeric_limits<uint64_t>::max();
0584
0585
0586 void moveSymbolNext(DataRefImpl &Symb) const override;
0587 Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
0588 basic_symbol_iterator symbol_begin() const override;
0589 basic_symbol_iterator symbol_end() const override;
0590
0591 using xcoff_symbol_iterator_range = iterator_range<xcoff_symbol_iterator>;
0592 xcoff_symbol_iterator_range symbols() const;
0593
0594 bool is64Bit() const override;
0595 Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
0596 Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
0597 uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
0598 uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
0599 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
0600 Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
0601 Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
0602
0603 void moveSectionNext(DataRefImpl &Sec) const override;
0604 Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
0605 uint64_t getSectionAddress(DataRefImpl Sec) const override;
0606 uint64_t getSectionIndex(DataRefImpl Sec) const override;
0607 uint64_t getSectionSize(DataRefImpl Sec) const override;
0608 Expected<ArrayRef<uint8_t>>
0609 getSectionContents(DataRefImpl Sec) const override;
0610 uint64_t getSectionAlignment(DataRefImpl Sec) const override;
0611 bool isSectionCompressed(DataRefImpl Sec) const override;
0612 bool isSectionText(DataRefImpl Sec) const override;
0613 bool isSectionData(DataRefImpl Sec) const override;
0614 bool isSectionBSS(DataRefImpl Sec) const override;
0615 bool isDebugSection(DataRefImpl Sec) const override;
0616
0617 bool isSectionVirtual(DataRefImpl Sec) const override;
0618 relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
0619 relocation_iterator section_rel_end(DataRefImpl Sec) const override;
0620
0621 void moveRelocationNext(DataRefImpl &Rel) const override;
0622
0623
0624
0625
0626 uint64_t getRelocationOffset(DataRefImpl Rel) const override;
0627 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
0628 uint64_t getRelocationType(DataRefImpl Rel) const override;
0629 void getRelocationTypeName(DataRefImpl Rel,
0630 SmallVectorImpl<char> &Result) const override;
0631
0632 section_iterator section_begin() const override;
0633 section_iterator section_end() const override;
0634 uint8_t getBytesInAddress() const override;
0635 StringRef getFileFormatName() const override;
0636 Triple::ArchType getArch() const override;
0637 Expected<SubtargetFeatures> getFeatures() const override;
0638 Expected<uint64_t> getStartAddress() const override;
0639 StringRef mapDebugSectionName(StringRef Name) const override;
0640 bool isRelocatableObject() const override;
0641
0642
0643
0644 Expected<StringRef> getRawData(const char *Start, uint64_t Size,
0645 StringRef Name) const;
0646
0647 const XCOFFAuxiliaryHeader32 *auxiliaryHeader32() const;
0648 const XCOFFAuxiliaryHeader64 *auxiliaryHeader64() const;
0649
0650 const void *getPointerToSymbolTable() const { return SymbolTblPtr; }
0651
0652 Expected<StringRef> getSymbolSectionName(XCOFFSymbolRef Ref) const;
0653 unsigned getSymbolSectionID(SymbolRef Sym) const;
0654 XCOFFSymbolRef toSymbolRef(DataRefImpl Ref) const;
0655
0656
0657 const XCOFFFileHeader32 *fileHeader32() const;
0658 const XCOFFFileHeader64 *fileHeader64() const;
0659 uint16_t getMagic() const;
0660 uint16_t getNumberOfSections() const;
0661 int32_t getTimeStamp() const;
0662
0663
0664
0665 uint32_t getSymbolTableOffset32() const;
0666 uint64_t getSymbolTableOffset64() const;
0667
0668
0669
0670 int32_t getRawNumberOfSymbolTableEntries32() const;
0671
0672
0673 uint32_t getLogicalNumberOfSymbolTableEntries32() const;
0674
0675 uint32_t getNumberOfSymbolTableEntries64() const;
0676
0677
0678
0679 uint32_t getNumberOfSymbolTableEntries() const;
0680
0681 uint32_t getSymbolIndex(uintptr_t SymEntPtr) const;
0682 uint64_t getSymbolSize(DataRefImpl Symb) const;
0683 uintptr_t getSymbolByIndex(uint32_t Idx) const {
0684 return reinterpret_cast<uintptr_t>(SymbolTblPtr) +
0685 XCOFF::SymbolTableEntrySize * Idx;
0686 }
0687 uintptr_t getSymbolEntryAddressByIndex(uint32_t SymbolTableIndex) const;
0688 Expected<StringRef> getSymbolNameByIndex(uint32_t SymbolTableIndex) const;
0689
0690 Expected<StringRef> getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const;
0691 uint16_t getOptionalHeaderSize() const;
0692 uint16_t getFlags() const;
0693
0694
0695 ArrayRef<XCOFFSectionHeader32> sections32() const;
0696 ArrayRef<XCOFFSectionHeader64> sections64() const;
0697
0698 int32_t getSectionFlags(DataRefImpl Sec) const;
0699 Expected<DataRefImpl> getSectionByNum(int16_t Num) const;
0700
0701 Expected<uintptr_t>
0702 getSectionFileOffsetToRawData(XCOFF::SectionTypeFlags SectType) const;
0703
0704 void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const;
0705
0706
0707 template <typename T>
0708 Expected<uint32_t>
0709 getNumberOfRelocationEntries(const XCOFFSectionHeader<T> &Sec) const;
0710
0711 template <typename Shdr, typename Reloc>
0712 Expected<ArrayRef<Reloc>> relocations(const Shdr &Sec) const;
0713
0714
0715 Expected<StringRef> getImportFileTable() const;
0716
0717
0718 template <typename ExceptEnt>
0719 Expected<ArrayRef<ExceptEnt>> getExceptionEntries() const;
0720
0721
0722 Expected<StringRef> getStringTableEntry(uint32_t Offset) const;
0723
0724
0725 StringRef getStringTable() const;
0726
0727 const XCOFF::SymbolAuxType *getSymbolAuxType(uintptr_t AuxEntryAddress) const;
0728
0729 static uintptr_t getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,
0730 uint32_t Distance);
0731
0732 static bool classof(const Binary *B) { return B->isXCOFF(); }
0733
0734 std::optional<StringRef> tryGetCPUName() const override;
0735 };
0736
0737 typedef struct {
0738 uint8_t LanguageId;
0739 uint8_t CpuTypeId;
0740 } CFileLanguageIdAndTypeIdType;
0741
0742 struct XCOFFSymbolEntry32 {
0743 typedef struct {
0744 support::big32_t Magic;
0745 support::ubig32_t Offset;
0746 } NameInStrTblType;
0747
0748 union {
0749 char SymbolName[XCOFF::NameSize];
0750 NameInStrTblType NameInStrTbl;
0751 };
0752
0753 support::ubig32_t Value;
0754 support::big16_t SectionNumber;
0755
0756 union {
0757 support::ubig16_t SymbolType;
0758 CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
0759 };
0760
0761 XCOFF::StorageClass StorageClass;
0762 uint8_t NumberOfAuxEntries;
0763 };
0764
0765 struct XCOFFSymbolEntry64 {
0766 support::ubig64_t Value;
0767 support::ubig32_t Offset;
0768 support::big16_t SectionNumber;
0769
0770 union {
0771 support::ubig16_t SymbolType;
0772 CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
0773 };
0774
0775 XCOFF::StorageClass StorageClass;
0776 uint8_t NumberOfAuxEntries;
0777 };
0778
0779 extern template LLVM_TEMPLATE_ABI Expected<ArrayRef<XCOFFRelocation32>>
0780 XCOFFObjectFile::relocations<XCOFFSectionHeader32, XCOFFRelocation32>(
0781 const XCOFFSectionHeader32 &Sec) const;
0782 extern template LLVM_TEMPLATE_ABI Expected<ArrayRef<XCOFFRelocation64>>
0783 XCOFFObjectFile::relocations<XCOFFSectionHeader64, XCOFFRelocation64>(
0784 const XCOFFSectionHeader64 &Sec) const;
0785
0786 class XCOFFSymbolRef : public SymbolRef {
0787 public:
0788 enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
0789
0790 XCOFFSymbolRef(DataRefImpl SymEntDataRef,
0791 const XCOFFObjectFile *OwningObjectPtr)
0792 : SymbolRef(SymEntDataRef, OwningObjectPtr) {
0793 assert(OwningObjectPtr && "OwningObjectPtr cannot be nullptr!");
0794 assert(SymEntDataRef.p != 0 &&
0795 "Symbol table entry pointer cannot be nullptr!");
0796 }
0797
0798 const XCOFFSymbolEntry32 *getSymbol32() const {
0799 return reinterpret_cast<const XCOFFSymbolEntry32 *>(getRawDataRefImpl().p);
0800 }
0801
0802 const XCOFFSymbolEntry64 *getSymbol64() const {
0803 return reinterpret_cast<const XCOFFSymbolEntry64 *>(getRawDataRefImpl().p);
0804 }
0805
0806 uint64_t getValue() const {
0807 return getObject()->is64Bit() ? getValue64() : getValue32();
0808 }
0809
0810 uint32_t getValue32() const {
0811 return reinterpret_cast<const XCOFFSymbolEntry32 *>(getRawDataRefImpl().p)
0812 ->Value;
0813 }
0814
0815 uint64_t getValue64() const {
0816 return reinterpret_cast<const XCOFFSymbolEntry64 *>(getRawDataRefImpl().p)
0817 ->Value;
0818 }
0819
0820 uint64_t getSize() const {
0821 return getObject()->getSymbolSize(getRawDataRefImpl());
0822 }
0823
0824 #define GETVALUE(X) \
0825 getObject()->is64Bit() \
0826 ? reinterpret_cast<const XCOFFSymbolEntry64 *>(getRawDataRefImpl().p)->X \
0827 : reinterpret_cast<const XCOFFSymbolEntry32 *>(getRawDataRefImpl().p)->X
0828
0829 int16_t getSectionNumber() const { return GETVALUE(SectionNumber); }
0830
0831 uint16_t getSymbolType() const { return GETVALUE(SymbolType); }
0832
0833 uint8_t getLanguageIdForCFile() const {
0834 assert(getStorageClass() == XCOFF::C_FILE &&
0835 "This interface is for C_FILE only.");
0836 return GETVALUE(CFileLanguageIdAndTypeId.LanguageId);
0837 }
0838
0839 uint8_t getCPUTypeIddForCFile() const {
0840 assert(getStorageClass() == XCOFF::C_FILE &&
0841 "This interface is for C_FILE only.");
0842 return GETVALUE(CFileLanguageIdAndTypeId.CpuTypeId);
0843 }
0844
0845 XCOFF::StorageClass getStorageClass() const { return GETVALUE(StorageClass); }
0846
0847 uint8_t getNumberOfAuxEntries() const { return GETVALUE(NumberOfAuxEntries); }
0848
0849 #undef GETVALUE
0850
0851 uintptr_t getEntryAddress() const {
0852 return getRawDataRefImpl().p;
0853 }
0854
0855 Expected<StringRef> getName() const;
0856 Expected<bool> isFunction() const;
0857 bool isCsectSymbol() const;
0858 Expected<XCOFFCsectAuxRef> getXCOFFCsectAuxRef() const;
0859
0860 private:
0861 const XCOFFObjectFile *getObject() const {
0862 return cast<XCOFFObjectFile>(BasicSymbolRef::getObject());
0863 }
0864 };
0865
0866 class xcoff_symbol_iterator : public symbol_iterator {
0867 public:
0868 xcoff_symbol_iterator(const basic_symbol_iterator &B)
0869 : symbol_iterator(B) {}
0870
0871 xcoff_symbol_iterator(const XCOFFSymbolRef *Symbol)
0872 : symbol_iterator(*Symbol) {}
0873
0874 const XCOFFSymbolRef *operator->() const {
0875 return static_cast<const XCOFFSymbolRef *>(symbol_iterator::operator->());
0876 }
0877
0878 const XCOFFSymbolRef &operator*() const {
0879 return static_cast<const XCOFFSymbolRef &>(symbol_iterator::operator*());
0880 }
0881 };
0882
0883 class TBVectorExt {
0884 uint16_t Data;
0885 SmallString<32> VecParmsInfo;
0886
0887 TBVectorExt(StringRef TBvectorStrRef, Error &Err);
0888
0889 public:
0890 static Expected<TBVectorExt> create(StringRef TBvectorStrRef);
0891 uint8_t getNumberOfVRSaved() const;
0892 bool isVRSavedOnStack() const;
0893 bool hasVarArgs() const;
0894 uint8_t getNumberOfVectorParms() const;
0895 bool hasVMXInstruction() const;
0896 SmallString<32> getVectorParmsInfo() const { return VecParmsInfo; };
0897 };
0898
0899
0900
0901
0902 class XCOFFTracebackTable {
0903 const uint8_t *const TBPtr;
0904 bool Is64BitObj;
0905 std::optional<SmallString<32>> ParmsType;
0906 std::optional<uint32_t> TraceBackTableOffset;
0907 std::optional<uint32_t> HandlerMask;
0908 std::optional<uint32_t> NumOfCtlAnchors;
0909 std::optional<SmallVector<uint32_t, 8>> ControlledStorageInfoDisp;
0910 std::optional<StringRef> FunctionName;
0911 std::optional<uint8_t> AllocaRegister;
0912 std::optional<TBVectorExt> VecExt;
0913 std::optional<uint8_t> ExtensionTable;
0914 std::optional<uint64_t> EhInfoDisp;
0915
0916 XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size, Error &Err,
0917 bool Is64Bit = false);
0918
0919 public:
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933 static Expected<XCOFFTracebackTable>
0934 create(const uint8_t *Ptr, uint64_t &Size, bool Is64Bits = false);
0935 uint8_t getVersion() const;
0936 uint8_t getLanguageID() const;
0937
0938 bool isGlobalLinkage() const;
0939 bool isOutOfLineEpilogOrPrologue() const;
0940 bool hasTraceBackTableOffset() const;
0941 bool isInternalProcedure() const;
0942 bool hasControlledStorage() const;
0943 bool isTOCless() const;
0944 bool isFloatingPointPresent() const;
0945 bool isFloatingPointOperationLogOrAbortEnabled() const;
0946
0947 bool isInterruptHandler() const;
0948 bool isFuncNamePresent() const;
0949 bool isAllocaUsed() const;
0950 uint8_t getOnConditionDirective() const;
0951 bool isCRSaved() const;
0952 bool isLRSaved() const;
0953
0954 bool isBackChainStored() const;
0955 bool isFixup() const;
0956 uint8_t getNumOfFPRsSaved() const;
0957
0958 bool hasVectorInfo() const;
0959 bool hasExtensionTable() const;
0960 uint8_t getNumOfGPRsSaved() const;
0961
0962 uint8_t getNumberOfFixedParms() const;
0963
0964 uint8_t getNumberOfFPParms() const;
0965 bool hasParmsOnStack() const;
0966
0967 const std::optional<SmallString<32>> &getParmsType() const {
0968 return ParmsType;
0969 }
0970 const std::optional<uint32_t> &getTraceBackTableOffset() const {
0971 return TraceBackTableOffset;
0972 }
0973 const std::optional<uint32_t> &getHandlerMask() const { return HandlerMask; }
0974 const std::optional<uint32_t> &getNumOfCtlAnchors() {
0975 return NumOfCtlAnchors;
0976 }
0977 const std::optional<SmallVector<uint32_t, 8>> &
0978 getControlledStorageInfoDisp() {
0979 return ControlledStorageInfoDisp;
0980 }
0981 const std::optional<StringRef> &getFunctionName() const {
0982 return FunctionName;
0983 }
0984 const std::optional<uint8_t> &getAllocaRegister() const {
0985 return AllocaRegister;
0986 }
0987 const std::optional<TBVectorExt> &getVectorExt() const { return VecExt; }
0988 const std::optional<uint8_t> &getExtensionTable() const {
0989 return ExtensionTable;
0990 }
0991 const std::optional<uint64_t> &getEhInfoDisp() const { return EhInfoDisp; }
0992 };
0993
0994 bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes);
0995 }
0996 }
0997
0998 #endif