Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 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/ADT/SmallString.h" |
||
| 17 | #include "llvm/ADT/SmallVector.h" |
||
| 18 | #include "llvm/BinaryFormat/XCOFF.h" |
||
| 19 | #include "llvm/Object/ObjectFile.h" |
||
| 20 | #include "llvm/Support/Endian.h" |
||
| 21 | #include <limits> |
||
| 22 | |||
| 23 | namespace llvm { |
||
| 24 | namespace object { |
||
| 25 | |||
| 26 | struct XCOFFFileHeader32 { |
||
| 27 | support::ubig16_t Magic; |
||
| 28 | support::ubig16_t NumberOfSections; |
||
| 29 | |||
| 30 | // Unix time value, value of 0 indicates no timestamp. |
||
| 31 | // Negative values are reserved. |
||
| 32 | support::big32_t TimeStamp; |
||
| 33 | |||
| 34 | support::ubig32_t SymbolTableOffset; // File offset to symbol table. |
||
| 35 | support::big32_t NumberOfSymTableEntries; |
||
| 36 | support::ubig16_t AuxHeaderSize; |
||
| 37 | support::ubig16_t Flags; |
||
| 38 | }; |
||
| 39 | |||
| 40 | struct XCOFFFileHeader64 { |
||
| 41 | support::ubig16_t Magic; |
||
| 42 | support::ubig16_t NumberOfSections; |
||
| 43 | |||
| 44 | // Unix time value, value of 0 indicates no timestamp. |
||
| 45 | // Negative values are reserved. |
||
| 46 | support::big32_t TimeStamp; |
||
| 47 | |||
| 48 | support::ubig64_t SymbolTableOffset; // File offset to symbol table. |
||
| 49 | support::ubig16_t AuxHeaderSize; |
||
| 50 | support::ubig16_t Flags; |
||
| 51 | support::ubig32_t NumberOfSymTableEntries; |
||
| 52 | }; |
||
| 53 | |||
| 54 | template <typename T> struct XCOFFAuxiliaryHeader { |
||
| 55 | static constexpr uint8_t AuxiHeaderFlagMask = 0xF0; |
||
| 56 | static constexpr uint8_t AuxiHeaderTDataAlignmentMask = 0x0F; |
||
| 57 | |||
| 58 | public: |
||
| 59 | uint8_t getFlag() const { |
||
| 60 | return static_cast<const T *>(this)->FlagAndTDataAlignment & |
||
| 61 | AuxiHeaderFlagMask; |
||
| 62 | } |
||
| 63 | |||
| 64 | uint8_t getTDataAlignment() const { |
||
| 65 | return static_cast<const T *>(this)->FlagAndTDataAlignment & |
||
| 66 | AuxiHeaderTDataAlignmentMask; |
||
| 67 | } |
||
| 68 | |||
| 69 | uint16_t getVersion() const { return static_cast<const T *>(this)->Version; } |
||
| 70 | }; |
||
| 71 | |||
| 72 | struct XCOFFAuxiliaryHeader32 : XCOFFAuxiliaryHeader<XCOFFAuxiliaryHeader32> { |
||
| 73 | support::ubig16_t |
||
| 74 | AuxMagic; ///< If the value of the o_vstamp field is greater than 1, the |
||
| 75 | ///< o_mflags field is reserved for future use and it should |
||
| 76 | ///< contain 0. Otherwise, this field is not used. |
||
| 77 | support::ubig16_t |
||
| 78 | Version; ///< The valid values are 1 and 2. When the o_vstamp field is 2 |
||
| 79 | ///< in an XCOFF32 file, the new interpretation of the n_type |
||
| 80 | ///< field in the symbol table entry is used. |
||
| 81 | support::ubig32_t TextSize; |
||
| 82 | support::ubig32_t InitDataSize; |
||
| 83 | support::ubig32_t BssDataSize; |
||
| 84 | support::ubig32_t EntryPointAddr; |
||
| 85 | support::ubig32_t TextStartAddr; |
||
| 86 | support::ubig32_t DataStartAddr; |
||
| 87 | support::ubig32_t TOCAnchorAddr; |
||
| 88 | support::ubig16_t SecNumOfEntryPoint; |
||
| 89 | support::ubig16_t SecNumOfText; |
||
| 90 | support::ubig16_t SecNumOfData; |
||
| 91 | support::ubig16_t SecNumOfTOC; |
||
| 92 | support::ubig16_t SecNumOfLoader; |
||
| 93 | support::ubig16_t SecNumOfBSS; |
||
| 94 | support::ubig16_t MaxAlignOfText; |
||
| 95 | support::ubig16_t MaxAlignOfData; |
||
| 96 | support::ubig16_t ModuleType; |
||
| 97 | uint8_t CpuFlag; |
||
| 98 | uint8_t CpuType; |
||
| 99 | support::ubig32_t MaxStackSize; ///< If the value is 0, the system default |
||
| 100 | ///< maximum stack size is used. |
||
| 101 | support::ubig32_t MaxDataSize; ///< If the value is 0, the system default |
||
| 102 | ///< maximum data size is used. |
||
| 103 | support::ubig32_t |
||
| 104 | ReservedForDebugger; ///< This field should contain 0. When a loaded |
||
| 105 | ///< program is being debugged, the memory image of |
||
| 106 | ///< this field may be modified by a debugger to |
||
| 107 | ///< insert a trap instruction. |
||
| 108 | uint8_t TextPageSize; ///< Specifies the size of pages for the exec text. The |
||
| 109 | ///< default value is 0 (system-selected page size). |
||
| 110 | uint8_t DataPageSize; ///< Specifies the size of pages for the exec data. The |
||
| 111 | ///< default value is 0 (system-selected page size). |
||
| 112 | uint8_t StackPageSize; ///< Specifies the size of pages for the stack. The |
||
| 113 | ///< default value is 0 (system-selected page size). |
||
| 114 | uint8_t FlagAndTDataAlignment; |
||
| 115 | support::ubig16_t SecNumOfTData; |
||
| 116 | support::ubig16_t SecNumOfTBSS; |
||
| 117 | }; |
||
| 118 | |||
| 119 | struct XCOFFAuxiliaryHeader64 : XCOFFAuxiliaryHeader<XCOFFAuxiliaryHeader64> { |
||
| 120 | support::ubig16_t AuxMagic; |
||
| 121 | support::ubig16_t Version; |
||
| 122 | support::ubig32_t ReservedForDebugger; |
||
| 123 | support::ubig64_t TextStartAddr; |
||
| 124 | support::ubig64_t DataStartAddr; |
||
| 125 | support::ubig64_t TOCAnchorAddr; |
||
| 126 | support::ubig16_t SecNumOfEntryPoint; |
||
| 127 | support::ubig16_t SecNumOfText; |
||
| 128 | support::ubig16_t SecNumOfData; |
||
| 129 | support::ubig16_t SecNumOfTOC; |
||
| 130 | support::ubig16_t SecNumOfLoader; |
||
| 131 | support::ubig16_t SecNumOfBSS; |
||
| 132 | support::ubig16_t MaxAlignOfText; |
||
| 133 | support::ubig16_t MaxAlignOfData; |
||
| 134 | support::ubig16_t ModuleType; |
||
| 135 | uint8_t CpuFlag; |
||
| 136 | uint8_t CpuType; |
||
| 137 | uint8_t TextPageSize; |
||
| 138 | uint8_t DataPageSize; |
||
| 139 | uint8_t StackPageSize; |
||
| 140 | uint8_t FlagAndTDataAlignment; |
||
| 141 | support::ubig64_t TextSize; |
||
| 142 | support::ubig64_t InitDataSize; |
||
| 143 | support::ubig64_t BssDataSize; |
||
| 144 | support::ubig64_t EntryPointAddr; |
||
| 145 | support::ubig64_t MaxStackSize; |
||
| 146 | support::ubig64_t MaxDataSize; |
||
| 147 | support::ubig16_t SecNumOfTData; |
||
| 148 | support::ubig16_t SecNumOfTBSS; |
||
| 149 | support::ubig16_t XCOFF64Flag; |
||
| 150 | }; |
||
| 151 | |||
| 152 | template <typename T> struct XCOFFSectionHeader { |
||
| 153 | // Least significant 3 bits are reserved. |
||
| 154 | static constexpr unsigned SectionFlagsReservedMask = 0x7; |
||
| 155 | |||
| 156 | // The low order 16 bits of section flags denotes the section type. |
||
| 157 | static constexpr unsigned SectionFlagsTypeMask = 0xffffu; |
||
| 158 | |||
| 159 | public: |
||
| 160 | StringRef getName() const; |
||
| 161 | uint16_t getSectionType() const; |
||
| 162 | bool isReservedSectionType() const; |
||
| 163 | }; |
||
| 164 | |||
| 165 | // Explicit extern template declarations. |
||
| 166 | struct XCOFFSectionHeader32; |
||
| 167 | struct XCOFFSectionHeader64; |
||
| 168 | extern template struct XCOFFSectionHeader<XCOFFSectionHeader32>; |
||
| 169 | extern template struct XCOFFSectionHeader<XCOFFSectionHeader64>; |
||
| 170 | |||
| 171 | struct XCOFFSectionHeader32 : XCOFFSectionHeader<XCOFFSectionHeader32> { |
||
| 172 | char Name[XCOFF::NameSize]; |
||
| 173 | support::ubig32_t PhysicalAddress; |
||
| 174 | support::ubig32_t VirtualAddress; |
||
| 175 | support::ubig32_t SectionSize; |
||
| 176 | support::ubig32_t FileOffsetToRawData; |
||
| 177 | support::ubig32_t FileOffsetToRelocationInfo; |
||
| 178 | support::ubig32_t FileOffsetToLineNumberInfo; |
||
| 179 | support::ubig16_t NumberOfRelocations; |
||
| 180 | support::ubig16_t NumberOfLineNumbers; |
||
| 181 | support::big32_t Flags; |
||
| 182 | }; |
||
| 183 | |||
| 184 | struct XCOFFSectionHeader64 : XCOFFSectionHeader<XCOFFSectionHeader64> { |
||
| 185 | char Name[XCOFF::NameSize]; |
||
| 186 | support::ubig64_t PhysicalAddress; |
||
| 187 | support::ubig64_t VirtualAddress; |
||
| 188 | support::ubig64_t SectionSize; |
||
| 189 | support::big64_t FileOffsetToRawData; |
||
| 190 | support::big64_t FileOffsetToRelocationInfo; |
||
| 191 | support::big64_t FileOffsetToLineNumberInfo; |
||
| 192 | support::ubig32_t NumberOfRelocations; |
||
| 193 | support::ubig32_t NumberOfLineNumbers; |
||
| 194 | support::big32_t Flags; |
||
| 195 | char Padding[4]; |
||
| 196 | }; |
||
| 197 | |||
| 198 | struct LoaderSectionHeader32; |
||
| 199 | struct LoaderSectionHeader64; |
||
| 200 | struct LoaderSectionSymbolEntry32 { |
||
| 201 | struct NameOffsetInStrTbl { |
||
| 202 | support::big32_t IsNameInStrTbl; // Zero indicates name in string table. |
||
| 203 | support::ubig32_t Offset; |
||
| 204 | }; |
||
| 205 | |||
| 206 | char SymbolName[XCOFF::NameSize]; |
||
| 207 | support::ubig32_t Value; // The virtual address of the symbol. |
||
| 208 | support::big16_t SectionNumber; |
||
| 209 | uint8_t SymbolType; |
||
| 210 | XCOFF::StorageClass StorageClass; |
||
| 211 | support::ubig32_t ImportFileID; |
||
| 212 | support::ubig32_t ParameterTypeCheck; |
||
| 213 | |||
| 214 | Expected<StringRef> |
||
| 215 | getSymbolName(const LoaderSectionHeader32 *LoaderSecHeader) const; |
||
| 216 | }; |
||
| 217 | |||
| 218 | struct LoaderSectionSymbolEntry64 { |
||
| 219 | support::ubig64_t Value; // The virtual address of the symbol. |
||
| 220 | support::ubig32_t Offset; |
||
| 221 | support::big16_t SectionNumber; |
||
| 222 | uint8_t SymbolType; |
||
| 223 | XCOFF::StorageClass StorageClass; |
||
| 224 | support::ubig32_t ImportFileID; |
||
| 225 | support::ubig32_t ParameterTypeCheck; |
||
| 226 | |||
| 227 | Expected<StringRef> |
||
| 228 | getSymbolName(const LoaderSectionHeader64 *LoaderSecHeader) const; |
||
| 229 | }; |
||
| 230 | |||
| 231 | struct LoaderSectionRelocationEntry32 { |
||
| 232 | support::ubig32_t VirtualAddr; |
||
| 233 | support::big32_t SymbolIndex; |
||
| 234 | support::ubig16_t Type; |
||
| 235 | support::big16_t SectionNum; |
||
| 236 | }; |
||
| 237 | |||
| 238 | struct LoaderSectionRelocationEntry64 { |
||
| 239 | support::ubig64_t VirtualAddr; |
||
| 240 | support::ubig16_t Type; |
||
| 241 | support::big16_t SectionNum; |
||
| 242 | support::big32_t SymbolIndex; |
||
| 243 | }; |
||
| 244 | |||
| 245 | struct LoaderSectionHeader32 { |
||
| 246 | support::ubig32_t Version; |
||
| 247 | support::ubig32_t NumberOfSymTabEnt; |
||
| 248 | support::ubig32_t NumberOfRelTabEnt; |
||
| 249 | support::ubig32_t LengthOfImpidStrTbl; |
||
| 250 | support::ubig32_t NumberOfImpid; |
||
| 251 | support::big32_t OffsetToImpid; |
||
| 252 | support::ubig32_t LengthOfStrTbl; |
||
| 253 | support::big32_t OffsetToStrTbl; |
||
| 254 | |||
| 255 | uint64_t getOffsetToSymTbl() const { |
||
| 256 | return NumberOfSymTabEnt == 0 ? 0 : sizeof(LoaderSectionHeader32); |
||
| 257 | } |
||
| 258 | |||
| 259 | uint64_t getOffsetToRelEnt() const { |
||
| 260 | // Relocation table is after Symbol table. |
||
| 261 | return NumberOfRelTabEnt == 0 |
||
| 262 | ? 0 |
||
| 263 | : sizeof(LoaderSectionHeader32) + |
||
| 264 | sizeof(LoaderSectionSymbolEntry32) * NumberOfSymTabEnt; |
||
| 265 | } |
||
| 266 | }; |
||
| 267 | |||
| 268 | struct LoaderSectionHeader64 { |
||
| 269 | support::ubig32_t Version; |
||
| 270 | support::ubig32_t NumberOfSymTabEnt; |
||
| 271 | support::ubig32_t NumberOfRelTabEnt; |
||
| 272 | support::ubig32_t LengthOfImpidStrTbl; |
||
| 273 | support::ubig32_t NumberOfImpid; |
||
| 274 | support::ubig32_t LengthOfStrTbl; |
||
| 275 | support::big64_t OffsetToImpid; |
||
| 276 | support::big64_t OffsetToStrTbl; |
||
| 277 | support::big64_t OffsetToSymTbl; |
||
| 278 | support::big64_t OffsetToRelEnt; |
||
| 279 | |||
| 280 | uint64_t getOffsetToSymTbl() const { return OffsetToSymTbl; } |
||
| 281 | uint64_t getOffsetToRelEnt() const { return OffsetToRelEnt; } |
||
| 282 | }; |
||
| 283 | |||
| 284 | template <typename AddressType> struct ExceptionSectionEntry { |
||
| 285 | union { |
||
| 286 | support::ubig32_t SymbolIdx; |
||
| 287 | AddressType TrapInstAddr; |
||
| 288 | }; |
||
| 289 | uint8_t LangId; |
||
| 290 | uint8_t Reason; |
||
| 291 | |||
| 292 | uint32_t getSymbolIndex() const { |
||
| 293 | assert(Reason == 0 && "Get symbol table index of the function only when " |
||
| 294 | "the e_reason field is 0."); |
||
| 295 | return SymbolIdx; |
||
| 296 | } |
||
| 297 | |||
| 298 | uint64_t getTrapInstAddr() const { |
||
| 299 | assert(Reason != 0 && "Zero is not a valid trap exception reason code."); |
||
| 300 | return TrapInstAddr; |
||
| 301 | } |
||
| 302 | uint8_t getLangID() const { return LangId; } |
||
| 303 | uint8_t getReason() const { return Reason; } |
||
| 304 | }; |
||
| 305 | |||
| 306 | typedef ExceptionSectionEntry<support::ubig32_t> ExceptionSectionEntry32; |
||
| 307 | typedef ExceptionSectionEntry<support::ubig64_t> ExceptionSectionEntry64; |
||
| 308 | |||
| 309 | // Explicit extern template declarations. |
||
| 310 | extern template struct ExceptionSectionEntry<support::ubig32_t>; |
||
| 311 | extern template struct ExceptionSectionEntry<support::ubig64_t>; |
||
| 312 | |||
| 313 | struct XCOFFStringTable { |
||
| 314 | uint32_t Size; |
||
| 315 | const char *Data; |
||
| 316 | }; |
||
| 317 | |||
| 318 | struct XCOFFCsectAuxEnt32 { |
||
| 319 | support::ubig32_t SectionOrLength; |
||
| 320 | support::ubig32_t ParameterHashIndex; |
||
| 321 | support::ubig16_t TypeChkSectNum; |
||
| 322 | uint8_t SymbolAlignmentAndType; |
||
| 323 | XCOFF::StorageMappingClass StorageMappingClass; |
||
| 324 | support::ubig32_t StabInfoIndex; |
||
| 325 | support::ubig16_t StabSectNum; |
||
| 326 | }; |
||
| 327 | |||
| 328 | struct XCOFFCsectAuxEnt64 { |
||
| 329 | support::ubig32_t SectionOrLengthLowByte; |
||
| 330 | support::ubig32_t ParameterHashIndex; |
||
| 331 | support::ubig16_t TypeChkSectNum; |
||
| 332 | uint8_t SymbolAlignmentAndType; |
||
| 333 | XCOFF::StorageMappingClass StorageMappingClass; |
||
| 334 | support::ubig32_t SectionOrLengthHighByte; |
||
| 335 | uint8_t Pad; |
||
| 336 | XCOFF::SymbolAuxType AuxType; |
||
| 337 | }; |
||
| 338 | |||
| 339 | class XCOFFCsectAuxRef { |
||
| 340 | public: |
||
| 341 | static constexpr uint8_t SymbolTypeMask = 0x07; |
||
| 342 | static constexpr uint8_t SymbolAlignmentMask = 0xF8; |
||
| 343 | static constexpr size_t SymbolAlignmentBitOffset = 3; |
||
| 344 | |||
| 345 | XCOFFCsectAuxRef(const XCOFFCsectAuxEnt32 *Entry32) : Entry32(Entry32) {} |
||
| 346 | XCOFFCsectAuxRef(const XCOFFCsectAuxEnt64 *Entry64) : Entry64(Entry64) {} |
||
| 347 | |||
| 348 | // For getSectionOrLength(), |
||
| 349 | // If the symbol type is XTY_SD or XTY_CM, the csect length. |
||
| 350 | // If the symbol type is XTY_LD, the symbol table |
||
| 351 | // index of the containing csect. |
||
| 352 | // If the symbol type is XTY_ER, 0. |
||
| 353 | uint64_t getSectionOrLength() const { |
||
| 354 | return Entry32 ? getSectionOrLength32() : getSectionOrLength64(); |
||
| 355 | } |
||
| 356 | |||
| 357 | uint32_t getSectionOrLength32() const { |
||
| 358 | assert(Entry32 && "32-bit interface called on 64-bit object file."); |
||
| 359 | return Entry32->SectionOrLength; |
||
| 360 | } |
||
| 361 | |||
| 362 | uint64_t getSectionOrLength64() const { |
||
| 363 | assert(Entry64 && "64-bit interface called on 32-bit object file."); |
||
| 364 | return (static_cast<uint64_t>(Entry64->SectionOrLengthHighByte) << 32) | |
||
| 365 | Entry64->SectionOrLengthLowByte; |
||
| 366 | } |
||
| 367 | |||
| 368 | #define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X |
||
| 369 | |||
| 370 | uint32_t getParameterHashIndex() const { |
||
| 371 | return GETVALUE(ParameterHashIndex); |
||
| 372 | } |
||
| 373 | |||
| 374 | uint16_t getTypeChkSectNum() const { return GETVALUE(TypeChkSectNum); } |
||
| 375 | |||
| 376 | XCOFF::StorageMappingClass getStorageMappingClass() const { |
||
| 377 | return GETVALUE(StorageMappingClass); |
||
| 378 | } |
||
| 379 | |||
| 380 | uintptr_t getEntryAddress() const { |
||
| 381 | return Entry32 ? reinterpret_cast<uintptr_t>(Entry32) |
||
| 382 | : reinterpret_cast<uintptr_t>(Entry64); |
||
| 383 | } |
||
| 384 | |||
| 385 | uint16_t getAlignmentLog2() const { |
||
| 386 | return (getSymbolAlignmentAndType() & SymbolAlignmentMask) >> |
||
| 387 | SymbolAlignmentBitOffset; |
||
| 388 | } |
||
| 389 | |||
| 390 | uint8_t getSymbolType() const { |
||
| 391 | return getSymbolAlignmentAndType() & SymbolTypeMask; |
||
| 392 | } |
||
| 393 | |||
| 394 | bool isLabel() const { return getSymbolType() == XCOFF::XTY_LD; } |
||
| 395 | |||
| 396 | uint32_t getStabInfoIndex32() const { |
||
| 397 | assert(Entry32 && "32-bit interface called on 64-bit object file."); |
||
| 398 | return Entry32->StabInfoIndex; |
||
| 399 | } |
||
| 400 | |||
| 401 | uint16_t getStabSectNum32() const { |
||
| 402 | assert(Entry32 && "32-bit interface called on 64-bit object file."); |
||
| 403 | return Entry32->StabSectNum; |
||
| 404 | } |
||
| 405 | |||
| 406 | XCOFF::SymbolAuxType getAuxType64() const { |
||
| 407 | assert(Entry64 && "64-bit interface called on 32-bit object file."); |
||
| 408 | return Entry64->AuxType; |
||
| 409 | } |
||
| 410 | |||
| 411 | private: |
||
| 412 | uint8_t getSymbolAlignmentAndType() const { |
||
| 413 | return GETVALUE(SymbolAlignmentAndType); |
||
| 414 | } |
||
| 415 | |||
| 416 | #undef GETVALUE |
||
| 417 | |||
| 418 | const XCOFFCsectAuxEnt32 *Entry32 = nullptr; |
||
| 419 | const XCOFFCsectAuxEnt64 *Entry64 = nullptr; |
||
| 420 | }; |
||
| 421 | |||
| 422 | struct XCOFFFileAuxEnt { |
||
| 423 | typedef struct { |
||
| 424 | support::big32_t Magic; // Zero indicates name in string table. |
||
| 425 | support::ubig32_t Offset; |
||
| 426 | char NamePad[XCOFF::FileNamePadSize]; |
||
| 427 | } NameInStrTblType; |
||
| 428 | union { |
||
| 429 | char Name[XCOFF::NameSize + XCOFF::FileNamePadSize]; |
||
| 430 | NameInStrTblType NameInStrTbl; |
||
| 431 | }; |
||
| 432 | XCOFF::CFileStringType Type; |
||
| 433 | uint8_t ReservedZeros[2]; |
||
| 434 | XCOFF::SymbolAuxType AuxType; // 64-bit XCOFF file only. |
||
| 435 | }; |
||
| 436 | |||
| 437 | struct XCOFFSectAuxEntForStat { |
||
| 438 | support::ubig32_t SectionLength; |
||
| 439 | support::ubig16_t NumberOfRelocEnt; |
||
| 440 | support::ubig16_t NumberOfLineNum; |
||
| 441 | uint8_t Pad[10]; |
||
| 442 | }; // 32-bit XCOFF file only. |
||
| 443 | |||
| 444 | struct XCOFFFunctionAuxEnt32 { |
||
| 445 | support::ubig32_t OffsetToExceptionTbl; |
||
| 446 | support::ubig32_t SizeOfFunction; |
||
| 447 | support::ubig32_t PtrToLineNum; |
||
| 448 | support::big32_t SymIdxOfNextBeyond; |
||
| 449 | uint8_t Pad[2]; |
||
| 450 | }; |
||
| 451 | |||
| 452 | struct XCOFFFunctionAuxEnt64 { |
||
| 453 | support::ubig64_t PtrToLineNum; |
||
| 454 | support::ubig32_t SizeOfFunction; |
||
| 455 | support::big32_t SymIdxOfNextBeyond; |
||
| 456 | uint8_t Pad; |
||
| 457 | XCOFF::SymbolAuxType AuxType; // Contains _AUX_FCN; Type of auxiliary entry |
||
| 458 | }; |
||
| 459 | |||
| 460 | struct XCOFFExceptionAuxEnt { |
||
| 461 | support::ubig64_t OffsetToExceptionTbl; |
||
| 462 | support::ubig32_t SizeOfFunction; |
||
| 463 | support::big32_t SymIdxOfNextBeyond; |
||
| 464 | uint8_t Pad; |
||
| 465 | XCOFF::SymbolAuxType AuxType; // Contains _AUX_EXCEPT; Type of auxiliary entry |
||
| 466 | }; |
||
| 467 | |||
| 468 | struct XCOFFBlockAuxEnt32 { |
||
| 469 | uint8_t ReservedZeros1[2]; |
||
| 470 | support::ubig16_t LineNumHi; |
||
| 471 | support::ubig16_t LineNumLo; |
||
| 472 | uint8_t ReservedZeros2[12]; |
||
| 473 | }; |
||
| 474 | |||
| 475 | struct XCOFFBlockAuxEnt64 { |
||
| 476 | support::ubig32_t LineNum; |
||
| 477 | uint8_t Pad[13]; |
||
| 478 | XCOFF::SymbolAuxType AuxType; // Contains _AUX_SYM; Type of auxiliary entry |
||
| 479 | }; |
||
| 480 | |||
| 481 | struct XCOFFSectAuxEntForDWARF32 { |
||
| 482 | support::ubig32_t LengthOfSectionPortion; |
||
| 483 | uint8_t Pad1[4]; |
||
| 484 | support::ubig32_t NumberOfRelocEnt; |
||
| 485 | uint8_t Pad2[6]; |
||
| 486 | }; |
||
| 487 | |||
| 488 | struct XCOFFSectAuxEntForDWARF64 { |
||
| 489 | support::ubig64_t LengthOfSectionPortion; |
||
| 490 | support::ubig64_t NumberOfRelocEnt; |
||
| 491 | uint8_t Pad; |
||
| 492 | XCOFF::SymbolAuxType AuxType; // Contains _AUX_SECT; Type of Auxillary entry |
||
| 493 | }; |
||
| 494 | |||
| 495 | template <typename AddressType> struct XCOFFRelocation { |
||
| 496 | public: |
||
| 497 | AddressType VirtualAddress; |
||
| 498 | support::ubig32_t SymbolIndex; |
||
| 499 | |||
| 500 | // Packed field, see XR_* masks for details of packing. |
||
| 501 | uint8_t Info; |
||
| 502 | |||
| 503 | XCOFF::RelocationType Type; |
||
| 504 | |||
| 505 | public: |
||
| 506 | bool isRelocationSigned() const; |
||
| 507 | bool isFixupIndicated() const; |
||
| 508 | |||
| 509 | // Returns the number of bits being relocated. |
||
| 510 | uint8_t getRelocatedLength() const; |
||
| 511 | }; |
||
| 512 | |||
| 513 | extern template struct XCOFFRelocation<llvm::support::ubig32_t>; |
||
| 514 | extern template struct XCOFFRelocation<llvm::support::ubig64_t>; |
||
| 515 | |||
| 516 | struct XCOFFRelocation32 : XCOFFRelocation<llvm::support::ubig32_t> {}; |
||
| 517 | struct XCOFFRelocation64 : XCOFFRelocation<llvm::support::ubig64_t> {}; |
||
| 518 | |||
| 519 | class XCOFFSymbolRef; |
||
| 520 | |||
| 521 | class XCOFFObjectFile : public ObjectFile { |
||
| 522 | private: |
||
| 523 | const void *FileHeader = nullptr; |
||
| 524 | const void *AuxiliaryHeader = nullptr; |
||
| 525 | const void *SectionHeaderTable = nullptr; |
||
| 526 | |||
| 527 | const void *SymbolTblPtr = nullptr; |
||
| 528 | XCOFFStringTable StringTable = {0, nullptr}; |
||
| 529 | |||
| 530 | const XCOFFSectionHeader32 *sectionHeaderTable32() const; |
||
| 531 | const XCOFFSectionHeader64 *sectionHeaderTable64() const; |
||
| 532 | template <typename T> const T *sectionHeaderTable() const; |
||
| 533 | |||
| 534 | size_t getFileHeaderSize() const; |
||
| 535 | size_t getSectionHeaderSize() const; |
||
| 536 | |||
| 537 | const XCOFFSectionHeader32 *toSection32(DataRefImpl Ref) const; |
||
| 538 | const XCOFFSectionHeader64 *toSection64(DataRefImpl Ref) const; |
||
| 539 | uintptr_t getSectionHeaderTableAddress() const; |
||
| 540 | uintptr_t getEndOfSymbolTableAddress() const; |
||
| 541 | |||
| 542 | DataRefImpl getSectionByType(XCOFF::SectionTypeFlags SectType) const; |
||
| 543 | uint64_t getSectionFileOffsetToRawData(DataRefImpl Sec) const; |
||
| 544 | |||
| 545 | // This returns a pointer to the start of the storage for the name field of |
||
| 546 | // the 32-bit or 64-bit SectionHeader struct. This string is *not* necessarily |
||
| 547 | // null-terminated. |
||
| 548 | const char *getSectionNameInternal(DataRefImpl Sec) const; |
||
| 549 | |||
| 550 | static bool isReservedSectionNumber(int16_t SectionNumber); |
||
| 551 | |||
| 552 | // Constructor and "create" factory function. The constructor is only a thin |
||
| 553 | // wrapper around the base constructor. The "create" function fills out the |
||
| 554 | // XCOFF-specific information and performs the error checking along the way. |
||
| 555 | XCOFFObjectFile(unsigned Type, MemoryBufferRef Object); |
||
| 556 | static Expected<std::unique_ptr<XCOFFObjectFile>> create(unsigned Type, |
||
| 557 | MemoryBufferRef MBR); |
||
| 558 | |||
| 559 | // Helper for parsing the StringTable. Returns an 'Error' if parsing failed |
||
| 560 | // and an XCOFFStringTable if parsing succeeded. |
||
| 561 | static Expected<XCOFFStringTable> parseStringTable(const XCOFFObjectFile *Obj, |
||
| 562 | uint64_t Offset); |
||
| 563 | |||
| 564 | // Make a friend so it can call the private 'create' function. |
||
| 565 | friend Expected<std::unique_ptr<ObjectFile>> |
||
| 566 | ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType); |
||
| 567 | |||
| 568 | void checkSectionAddress(uintptr_t Addr, uintptr_t TableAddr) const; |
||
| 569 | |||
| 570 | public: |
||
| 571 | static constexpr uint64_t InvalidRelocOffset = |
||
| 572 | std::numeric_limits<uint64_t>::max(); |
||
| 573 | |||
| 574 | // Interface inherited from base classes. |
||
| 575 | void moveSymbolNext(DataRefImpl &Symb) const override; |
||
| 576 | Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override; |
||
| 577 | basic_symbol_iterator symbol_begin() const override; |
||
| 578 | basic_symbol_iterator symbol_end() const override; |
||
| 579 | |||
| 580 | Expected<StringRef> getSymbolName(DataRefImpl Symb) const override; |
||
| 581 | Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override; |
||
| 582 | uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; |
||
| 583 | uint32_t getSymbolAlignment(DataRefImpl Symb) const override; |
||
| 584 | uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; |
||
| 585 | Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override; |
||
| 586 | Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override; |
||
| 587 | |||
| 588 | void moveSectionNext(DataRefImpl &Sec) const override; |
||
| 589 | Expected<StringRef> getSectionName(DataRefImpl Sec) const override; |
||
| 590 | uint64_t getSectionAddress(DataRefImpl Sec) const override; |
||
| 591 | uint64_t getSectionIndex(DataRefImpl Sec) const override; |
||
| 592 | uint64_t getSectionSize(DataRefImpl Sec) const override; |
||
| 593 | Expected<ArrayRef<uint8_t>> |
||
| 594 | getSectionContents(DataRefImpl Sec) const override; |
||
| 595 | uint64_t getSectionAlignment(DataRefImpl Sec) const override; |
||
| 596 | bool isSectionCompressed(DataRefImpl Sec) const override; |
||
| 597 | bool isSectionText(DataRefImpl Sec) const override; |
||
| 598 | bool isSectionData(DataRefImpl Sec) const override; |
||
| 599 | bool isSectionBSS(DataRefImpl Sec) const override; |
||
| 600 | bool isDebugSection(DataRefImpl Sec) const override; |
||
| 601 | |||
| 602 | bool isSectionVirtual(DataRefImpl Sec) const override; |
||
| 603 | relocation_iterator section_rel_begin(DataRefImpl Sec) const override; |
||
| 604 | relocation_iterator section_rel_end(DataRefImpl Sec) const override; |
||
| 605 | |||
| 606 | void moveRelocationNext(DataRefImpl &Rel) const override; |
||
| 607 | |||
| 608 | /// \returns the relocation offset with the base address of the containing |
||
| 609 | /// section as zero, or InvalidRelocOffset on errors (such as a relocation |
||
| 610 | /// that does not refer to an address in any section). |
||
| 611 | uint64_t getRelocationOffset(DataRefImpl Rel) const override; |
||
| 612 | symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; |
||
| 613 | uint64_t getRelocationType(DataRefImpl Rel) const override; |
||
| 614 | void getRelocationTypeName(DataRefImpl Rel, |
||
| 615 | SmallVectorImpl<char> &Result) const override; |
||
| 616 | |||
| 617 | section_iterator section_begin() const override; |
||
| 618 | section_iterator section_end() const override; |
||
| 619 | uint8_t getBytesInAddress() const override; |
||
| 620 | StringRef getFileFormatName() const override; |
||
| 621 | Triple::ArchType getArch() const override; |
||
| 622 | Expected<SubtargetFeatures> getFeatures() const override; |
||
| 623 | Expected<uint64_t> getStartAddress() const override; |
||
| 624 | StringRef mapDebugSectionName(StringRef Name) const override; |
||
| 625 | bool isRelocatableObject() const override; |
||
| 626 | |||
| 627 | // Below here is the non-inherited interface. |
||
| 628 | bool is64Bit() const; |
||
| 629 | Expected<StringRef> getRawData(const char *Start, uint64_t Size, |
||
| 630 | StringRef Name) const; |
||
| 631 | |||
| 632 | const XCOFFAuxiliaryHeader32 *auxiliaryHeader32() const; |
||
| 633 | const XCOFFAuxiliaryHeader64 *auxiliaryHeader64() const; |
||
| 634 | |||
| 635 | const void *getPointerToSymbolTable() const { return SymbolTblPtr; } |
||
| 636 | |||
| 637 | Expected<StringRef> getSymbolSectionName(XCOFFSymbolRef Ref) const; |
||
| 638 | unsigned getSymbolSectionID(SymbolRef Sym) const; |
||
| 639 | XCOFFSymbolRef toSymbolRef(DataRefImpl Ref) const; |
||
| 640 | |||
| 641 | // File header related interfaces. |
||
| 642 | const XCOFFFileHeader32 *fileHeader32() const; |
||
| 643 | const XCOFFFileHeader64 *fileHeader64() const; |
||
| 644 | uint16_t getMagic() const; |
||
| 645 | uint16_t getNumberOfSections() const; |
||
| 646 | int32_t getTimeStamp() const; |
||
| 647 | |||
| 648 | // Symbol table offset and entry count are handled differently between |
||
| 649 | // XCOFF32 and XCOFF64. |
||
| 650 | uint32_t getSymbolTableOffset32() const; |
||
| 651 | uint64_t getSymbolTableOffset64() const; |
||
| 652 | |||
| 653 | // Note that this value is signed and might return a negative value. Negative |
||
| 654 | // values are reserved for future use. |
||
| 655 | int32_t getRawNumberOfSymbolTableEntries32() const; |
||
| 656 | |||
| 657 | // The sanitized value appropriate to use as an index into the symbol table. |
||
| 658 | uint32_t getLogicalNumberOfSymbolTableEntries32() const; |
||
| 659 | |||
| 660 | uint32_t getNumberOfSymbolTableEntries64() const; |
||
| 661 | |||
| 662 | // Return getLogicalNumberOfSymbolTableEntries32 or |
||
| 663 | // getNumberOfSymbolTableEntries64 depending on the object mode. |
||
| 664 | uint32_t getNumberOfSymbolTableEntries() const; |
||
| 665 | |||
| 666 | uint32_t getSymbolIndex(uintptr_t SymEntPtr) const; |
||
| 667 | uint64_t getSymbolSize(DataRefImpl Symb) const; |
||
| 668 | uintptr_t getSymbolByIndex(uint32_t Idx) const { |
||
| 669 | return reinterpret_cast<uintptr_t>(SymbolTblPtr) + |
||
| 670 | XCOFF::SymbolTableEntrySize * Idx; |
||
| 671 | } |
||
| 672 | uintptr_t getSymbolEntryAddressByIndex(uint32_t SymbolTableIndex) const; |
||
| 673 | Expected<StringRef> getSymbolNameByIndex(uint32_t SymbolTableIndex) const; |
||
| 674 | |||
| 675 | Expected<StringRef> getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const; |
||
| 676 | uint16_t getOptionalHeaderSize() const; |
||
| 677 | uint16_t getFlags() const; |
||
| 678 | |||
| 679 | // Section header table related interfaces. |
||
| 680 | ArrayRef<XCOFFSectionHeader32> sections32() const; |
||
| 681 | ArrayRef<XCOFFSectionHeader64> sections64() const; |
||
| 682 | |||
| 683 | int32_t getSectionFlags(DataRefImpl Sec) const; |
||
| 684 | Expected<DataRefImpl> getSectionByNum(int16_t Num) const; |
||
| 685 | |||
| 686 | Expected<uintptr_t> |
||
| 687 | getSectionFileOffsetToRawData(XCOFF::SectionTypeFlags SectType) const; |
||
| 688 | |||
| 689 | void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const; |
||
| 690 | |||
| 691 | // Relocation-related interfaces. |
||
| 692 | template <typename T> |
||
| 693 | Expected<uint32_t> |
||
| 694 | getNumberOfRelocationEntries(const XCOFFSectionHeader<T> &Sec) const; |
||
| 695 | |||
| 696 | template <typename Shdr, typename Reloc> |
||
| 697 | Expected<ArrayRef<Reloc>> relocations(const Shdr &Sec) const; |
||
| 698 | |||
| 699 | // Loader section related interfaces. |
||
| 700 | Expected<StringRef> getImportFileTable() const; |
||
| 701 | |||
| 702 | // Exception-related interface. |
||
| 703 | template <typename ExceptEnt> |
||
| 704 | Expected<ArrayRef<ExceptEnt>> getExceptionEntries() const; |
||
| 705 | |||
| 706 | // This function returns string table entry. |
||
| 707 | Expected<StringRef> getStringTableEntry(uint32_t Offset) const; |
||
| 708 | |||
| 709 | // This function returns the string table. |
||
| 710 | StringRef getStringTable() const; |
||
| 711 | |||
| 712 | const XCOFF::SymbolAuxType *getSymbolAuxType(uintptr_t AuxEntryAddress) const; |
||
| 713 | |||
| 714 | static uintptr_t getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress, |
||
| 715 | uint32_t Distance); |
||
| 716 | |||
| 717 | static bool classof(const Binary *B) { return B->isXCOFF(); } |
||
| 718 | }; // XCOFFObjectFile |
||
| 719 | |||
| 720 | typedef struct { |
||
| 721 | uint8_t LanguageId; |
||
| 722 | uint8_t CpuTypeId; |
||
| 723 | } CFileLanguageIdAndTypeIdType; |
||
| 724 | |||
| 725 | struct XCOFFSymbolEntry32 { |
||
| 726 | typedef struct { |
||
| 727 | support::big32_t Magic; // Zero indicates name in string table. |
||
| 728 | support::ubig32_t Offset; |
||
| 729 | } NameInStrTblType; |
||
| 730 | |||
| 731 | union { |
||
| 732 | char SymbolName[XCOFF::NameSize]; |
||
| 733 | NameInStrTblType NameInStrTbl; |
||
| 734 | }; |
||
| 735 | |||
| 736 | support::ubig32_t Value; // Symbol value; storage class-dependent. |
||
| 737 | support::big16_t SectionNumber; |
||
| 738 | |||
| 739 | union { |
||
| 740 | support::ubig16_t SymbolType; |
||
| 741 | CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId; |
||
| 742 | }; |
||
| 743 | |||
| 744 | XCOFF::StorageClass StorageClass; |
||
| 745 | uint8_t NumberOfAuxEntries; |
||
| 746 | }; |
||
| 747 | |||
| 748 | struct XCOFFSymbolEntry64 { |
||
| 749 | support::ubig64_t Value; // Symbol value; storage class-dependent. |
||
| 750 | support::ubig32_t Offset; |
||
| 751 | support::big16_t SectionNumber; |
||
| 752 | |||
| 753 | union { |
||
| 754 | support::ubig16_t SymbolType; |
||
| 755 | CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId; |
||
| 756 | }; |
||
| 757 | |||
| 758 | XCOFF::StorageClass StorageClass; |
||
| 759 | uint8_t NumberOfAuxEntries; |
||
| 760 | }; |
||
| 761 | |||
| 762 | class XCOFFSymbolRef { |
||
| 763 | public: |
||
| 764 | enum { NAME_IN_STR_TBL_MAGIC = 0x0 }; |
||
| 765 | |||
| 766 | XCOFFSymbolRef(DataRefImpl SymEntDataRef, |
||
| 767 | const XCOFFObjectFile *OwningObjectPtr) |
||
| 768 | : OwningObjectPtr(OwningObjectPtr) { |
||
| 769 | assert(OwningObjectPtr && "OwningObjectPtr cannot be nullptr!"); |
||
| 770 | assert(SymEntDataRef.p != 0 && |
||
| 771 | "Symbol table entry pointer cannot be nullptr!"); |
||
| 772 | |||
| 773 | if (OwningObjectPtr->is64Bit()) |
||
| 774 | Entry64 = reinterpret_cast<const XCOFFSymbolEntry64 *>(SymEntDataRef.p); |
||
| 775 | else |
||
| 776 | Entry32 = reinterpret_cast<const XCOFFSymbolEntry32 *>(SymEntDataRef.p); |
||
| 777 | } |
||
| 778 | |||
| 779 | const XCOFFSymbolEntry32 *getSymbol32() { return Entry32; } |
||
| 780 | const XCOFFSymbolEntry64 *getSymbol64() { return Entry64; } |
||
| 781 | |||
| 782 | uint64_t getValue() const { return Entry32 ? getValue32() : getValue64(); } |
||
| 783 | |||
| 784 | uint32_t getValue32() const { return Entry32->Value; } |
||
| 785 | |||
| 786 | uint64_t getValue64() const { return Entry64->Value; } |
||
| 787 | |||
| 788 | #define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X |
||
| 789 | |||
| 790 | int16_t getSectionNumber() const { return GETVALUE(SectionNumber); } |
||
| 791 | |||
| 792 | uint16_t getSymbolType() const { return GETVALUE(SymbolType); } |
||
| 793 | |||
| 794 | uint8_t getLanguageIdForCFile() const { |
||
| 795 | assert(getStorageClass() == XCOFF::C_FILE && |
||
| 796 | "This interface is for C_FILE only."); |
||
| 797 | return GETVALUE(CFileLanguageIdAndTypeId.LanguageId); |
||
| 798 | } |
||
| 799 | |||
| 800 | uint8_t getCPUTypeIddForCFile() const { |
||
| 801 | assert(getStorageClass() == XCOFF::C_FILE && |
||
| 802 | "This interface is for C_FILE only."); |
||
| 803 | return GETVALUE(CFileLanguageIdAndTypeId.CpuTypeId); |
||
| 804 | } |
||
| 805 | |||
| 806 | XCOFF::StorageClass getStorageClass() const { return GETVALUE(StorageClass); } |
||
| 807 | |||
| 808 | uint8_t getNumberOfAuxEntries() const { return GETVALUE(NumberOfAuxEntries); } |
||
| 809 | |||
| 810 | #undef GETVALUE |
||
| 811 | |||
| 812 | uintptr_t getEntryAddress() const { |
||
| 813 | return Entry32 ? reinterpret_cast<uintptr_t>(Entry32) |
||
| 814 | : reinterpret_cast<uintptr_t>(Entry64); |
||
| 815 | } |
||
| 816 | |||
| 817 | Expected<StringRef> getName() const; |
||
| 818 | bool isFunction() const; |
||
| 819 | bool isCsectSymbol() const; |
||
| 820 | Expected<XCOFFCsectAuxRef> getXCOFFCsectAuxRef() const; |
||
| 821 | |||
| 822 | private: |
||
| 823 | const XCOFFObjectFile *OwningObjectPtr; |
||
| 824 | const XCOFFSymbolEntry32 *Entry32 = nullptr; |
||
| 825 | const XCOFFSymbolEntry64 *Entry64 = nullptr; |
||
| 826 | }; |
||
| 827 | |||
| 828 | class TBVectorExt { |
||
| 829 | uint16_t Data; |
||
| 830 | SmallString<32> VecParmsInfo; |
||
| 831 | |||
| 832 | TBVectorExt(StringRef TBvectorStrRef, Error &Err); |
||
| 833 | |||
| 834 | public: |
||
| 835 | static Expected<TBVectorExt> create(StringRef TBvectorStrRef); |
||
| 836 | uint8_t getNumberOfVRSaved() const; |
||
| 837 | bool isVRSavedOnStack() const; |
||
| 838 | bool hasVarArgs() const; |
||
| 839 | uint8_t getNumberOfVectorParms() const; |
||
| 840 | bool hasVMXInstruction() const; |
||
| 841 | SmallString<32> getVectorParmsInfo() const { return VecParmsInfo; }; |
||
| 842 | }; |
||
| 843 | |||
| 844 | /// This class provides methods to extract traceback table data from a buffer. |
||
| 845 | /// The various accessors may reference the buffer provided via the constructor. |
||
| 846 | |||
| 847 | class XCOFFTracebackTable { |
||
| 848 | const uint8_t *const TBPtr; |
||
| 849 | std::optional<SmallString<32>> ParmsType; |
||
| 850 | std::optional<uint32_t> TraceBackTableOffset; |
||
| 851 | std::optional<uint32_t> HandlerMask; |
||
| 852 | std::optional<uint32_t> NumOfCtlAnchors; |
||
| 853 | std::optional<SmallVector<uint32_t, 8>> ControlledStorageInfoDisp; |
||
| 854 | std::optional<StringRef> FunctionName; |
||
| 855 | std::optional<uint8_t> AllocaRegister; |
||
| 856 | std::optional<TBVectorExt> VecExt; |
||
| 857 | std::optional<uint8_t> ExtensionTable; |
||
| 858 | |||
| 859 | XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size, Error &Err); |
||
| 860 | |||
| 861 | public: |
||
| 862 | /// Parse an XCOFF Traceback Table from \a Ptr with \a Size bytes. |
||
| 863 | /// Returns an XCOFFTracebackTable upon successful parsing, otherwise an |
||
| 864 | /// Error is returned. |
||
| 865 | /// |
||
| 866 | /// \param[in] Ptr |
||
| 867 | /// A pointer that points just past the initial 4 bytes of zeros at the |
||
| 868 | /// beginning of an XCOFF Traceback Table. |
||
| 869 | /// |
||
| 870 | /// \param[in, out] Size |
||
| 871 | /// A pointer that points to the length of the XCOFF Traceback Table. |
||
| 872 | /// If the XCOFF Traceback Table is not parsed successfully or there are |
||
| 873 | /// extra bytes that are not recognized, \a Size will be updated to be the |
||
| 874 | /// size up to the end of the last successfully parsed field of the table. |
||
| 875 | static Expected<XCOFFTracebackTable> create(const uint8_t *Ptr, |
||
| 876 | uint64_t &Size); |
||
| 877 | uint8_t getVersion() const; |
||
| 878 | uint8_t getLanguageID() const; |
||
| 879 | |||
| 880 | bool isGlobalLinkage() const; |
||
| 881 | bool isOutOfLineEpilogOrPrologue() const; |
||
| 882 | bool hasTraceBackTableOffset() const; |
||
| 883 | bool isInternalProcedure() const; |
||
| 884 | bool hasControlledStorage() const; |
||
| 885 | bool isTOCless() const; |
||
| 886 | bool isFloatingPointPresent() const; |
||
| 887 | bool isFloatingPointOperationLogOrAbortEnabled() const; |
||
| 888 | |||
| 889 | bool isInterruptHandler() const; |
||
| 890 | bool isFuncNamePresent() const; |
||
| 891 | bool isAllocaUsed() const; |
||
| 892 | uint8_t getOnConditionDirective() const; |
||
| 893 | bool isCRSaved() const; |
||
| 894 | bool isLRSaved() const; |
||
| 895 | |||
| 896 | bool isBackChainStored() const; |
||
| 897 | bool isFixup() const; |
||
| 898 | uint8_t getNumOfFPRsSaved() const; |
||
| 899 | |||
| 900 | bool hasVectorInfo() const; |
||
| 901 | bool hasExtensionTable() const; |
||
| 902 | uint8_t getNumOfGPRsSaved() const; |
||
| 903 | |||
| 904 | uint8_t getNumberOfFixedParms() const; |
||
| 905 | |||
| 906 | uint8_t getNumberOfFPParms() const; |
||
| 907 | bool hasParmsOnStack() const; |
||
| 908 | |||
| 909 | const std::optional<SmallString<32>> &getParmsType() const { |
||
| 910 | return ParmsType; |
||
| 911 | } |
||
| 912 | const std::optional<uint32_t> &getTraceBackTableOffset() const { |
||
| 913 | return TraceBackTableOffset; |
||
| 914 | } |
||
| 915 | const std::optional<uint32_t> &getHandlerMask() const { return HandlerMask; } |
||
| 916 | const std::optional<uint32_t> &getNumOfCtlAnchors() { |
||
| 917 | return NumOfCtlAnchors; |
||
| 918 | } |
||
| 919 | const std::optional<SmallVector<uint32_t, 8>> & |
||
| 920 | getControlledStorageInfoDisp() { |
||
| 921 | return ControlledStorageInfoDisp; |
||
| 922 | } |
||
| 923 | const std::optional<StringRef> &getFunctionName() const { |
||
| 924 | return FunctionName; |
||
| 925 | } |
||
| 926 | const std::optional<uint8_t> &getAllocaRegister() const { |
||
| 927 | return AllocaRegister; |
||
| 928 | } |
||
| 929 | const std::optional<TBVectorExt> &getVectorExt() const { return VecExt; } |
||
| 930 | const std::optional<uint8_t> &getExtensionTable() const { |
||
| 931 | return ExtensionTable; |
||
| 932 | } |
||
| 933 | }; |
||
| 934 | |||
| 935 | bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes); |
||
| 936 | } // namespace object |
||
| 937 | } // namespace llvm |
||
| 938 | |||
| 939 | #endif // LLVM_OBJECT_XCOFFOBJECTFILE_H |