XCOFFObjectFile.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- XCOFFObjectFile.h - XCOFF object file implementation -----*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file declares the XCOFFObjectFile class.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_OBJECT_XCOFFOBJECTFILE_H
  18. #define LLVM_OBJECT_XCOFFOBJECTFILE_H
  19. #include "llvm/ADT/SmallString.h"
  20. #include "llvm/ADT/SmallVector.h"
  21. #include "llvm/BinaryFormat/XCOFF.h"
  22. #include "llvm/Object/ObjectFile.h"
  23. #include "llvm/Support/Endian.h"
  24. #include <limits>
  25. namespace llvm {
  26. namespace object {
  27. struct XCOFFFileHeader32 {
  28. support::ubig16_t Magic;
  29. support::ubig16_t NumberOfSections;
  30. // Unix time value, value of 0 indicates no timestamp.
  31. // Negative values are reserved.
  32. support::big32_t TimeStamp;
  33. support::ubig32_t SymbolTableOffset; // File offset to symbol table.
  34. support::big32_t NumberOfSymTableEntries;
  35. support::ubig16_t AuxHeaderSize;
  36. support::ubig16_t Flags;
  37. };
  38. struct XCOFFFileHeader64 {
  39. support::ubig16_t Magic;
  40. support::ubig16_t NumberOfSections;
  41. // Unix time value, value of 0 indicates no timestamp.
  42. // Negative values are reserved.
  43. 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;
  48. };
  49. template <typename T> struct XCOFFAuxiliaryHeader {
  50. static constexpr uint8_t AuxiHeaderFlagMask = 0xF0;
  51. static constexpr uint8_t AuxiHeaderTDataAlignmentMask = 0x0F;
  52. public:
  53. uint8_t getFlag() const {
  54. return static_cast<const T *>(this)->FlagAndTDataAlignment &
  55. AuxiHeaderFlagMask;
  56. }
  57. uint8_t getTDataAlignment() const {
  58. return static_cast<const T *>(this)->FlagAndTDataAlignment &
  59. AuxiHeaderTDataAlignmentMask;
  60. }
  61. };
  62. struct XCOFFAuxiliaryHeader32 : XCOFFAuxiliaryHeader<XCOFFAuxiliaryHeader32> {
  63. support::ubig16_t
  64. AuxMagic; ///< If the value of the o_vstamp field is greater than 1, the
  65. ///< o_mflags field is reserved for future use and it should
  66. ///< contain 0. Otherwise, this field is not used.
  67. support::ubig16_t
  68. Version; ///< The valid values are 1 and 2. When the o_vstamp field is 2
  69. ///< in an XCOFF32 file, the new interpretation of the n_type
  70. ///< field in the symbol table entry is used.
  71. support::ubig32_t TextSize;
  72. support::ubig32_t InitDataSize;
  73. support::ubig32_t BssDataSize;
  74. support::ubig32_t EntryPointAddr;
  75. support::ubig32_t TextStartAddr;
  76. support::ubig32_t DataStartAddr;
  77. support::ubig32_t TOCAnchorAddr;
  78. support::ubig16_t SecNumOfEntryPoint;
  79. support::ubig16_t SecNumOfText;
  80. support::ubig16_t SecNumOfData;
  81. support::ubig16_t SecNumOfTOC;
  82. support::ubig16_t SecNumOfLoader;
  83. support::ubig16_t SecNumOfBSS;
  84. support::ubig16_t MaxAlignOfText;
  85. support::ubig16_t MaxAlignOfData;
  86. support::ubig16_t ModuleType;
  87. uint8_t CpuFlag;
  88. uint8_t CpuType;
  89. support::ubig32_t MaxStackSize; ///< If the value is 0, the system default
  90. ///< maximum stack size is used.
  91. support::ubig32_t MaxDataSize; ///< If the value is 0, the system default
  92. ///< maximum data size is used.
  93. support::ubig32_t
  94. ReservedForDebugger; ///< This field should contain 0. When a loaded
  95. ///< program is being debugged, the memory image of
  96. ///< this field may be modified by a debugger to
  97. ///< insert a trap instruction.
  98. uint8_t TextPageSize; ///< Specifies the size of pages for the exec text. The
  99. ///< default value is 0 (system-selected page size).
  100. uint8_t DataPageSize; ///< Specifies the size of pages for the exec data. The
  101. ///< default value is 0 (system-selected page size).
  102. uint8_t StackPageSize; ///< Specifies the size of pages for the stack. The
  103. ///< default value is 0 (system-selected page size).
  104. uint8_t FlagAndTDataAlignment;
  105. support::ubig16_t SecNumOfTData;
  106. support::ubig16_t SecNumOfTBSS;
  107. };
  108. struct XCOFFAuxiliaryHeader64 : XCOFFAuxiliaryHeader<XCOFFAuxiliaryHeader32> {
  109. support::ubig16_t AuxMagic;
  110. support::ubig16_t Version;
  111. support::ubig32_t ReservedForDebugger;
  112. support::ubig64_t TextStartAddr;
  113. support::ubig64_t DataStartAddr;
  114. support::ubig64_t TOCAnchorAddr;
  115. support::ubig16_t SecNumOfEntryPoint;
  116. support::ubig16_t SecNumOfText;
  117. support::ubig16_t SecNumOfData;
  118. support::ubig16_t SecNumOfTOC;
  119. support::ubig16_t SecNumOfLoader;
  120. support::ubig16_t SecNumOfBSS;
  121. support::ubig16_t MaxAlignOfText;
  122. support::ubig16_t MaxAlignOfData;
  123. support::ubig16_t ModuleType;
  124. uint8_t CpuFlag;
  125. uint8_t CpuType;
  126. uint8_t TextPageSize;
  127. uint8_t DataPageSize;
  128. uint8_t StackPageSize;
  129. uint8_t FlagAndTDataAlignment;
  130. support::ubig64_t TextSize;
  131. support::ubig64_t InitDataSize;
  132. support::ubig64_t BssDataSize;
  133. support::ubig64_t EntryPointAddr;
  134. support::ubig64_t MaxStackSize;
  135. support::ubig64_t MaxDataSize;
  136. support::ubig16_t SecNumOfTData;
  137. support::ubig16_t SecNumOfTBSS;
  138. support::ubig16_t XCOFF64Flag;
  139. };
  140. template <typename T> struct XCOFFSectionHeader {
  141. // Least significant 3 bits are reserved.
  142. static constexpr unsigned SectionFlagsReservedMask = 0x7;
  143. // The low order 16 bits of section flags denotes the section type.
  144. static constexpr unsigned SectionFlagsTypeMask = 0xffffu;
  145. public:
  146. StringRef getName() const;
  147. uint16_t getSectionType() const;
  148. bool isReservedSectionType() const;
  149. };
  150. // Explicit extern template declarations.
  151. struct XCOFFSectionHeader32;
  152. struct XCOFFSectionHeader64;
  153. extern template struct XCOFFSectionHeader<XCOFFSectionHeader32>;
  154. extern template struct XCOFFSectionHeader<XCOFFSectionHeader64>;
  155. struct XCOFFSectionHeader32 : XCOFFSectionHeader<XCOFFSectionHeader32> {
  156. char Name[XCOFF::NameSize];
  157. support::ubig32_t PhysicalAddress;
  158. support::ubig32_t VirtualAddress;
  159. support::ubig32_t SectionSize;
  160. support::ubig32_t FileOffsetToRawData;
  161. support::ubig32_t FileOffsetToRelocationInfo;
  162. support::ubig32_t FileOffsetToLineNumberInfo;
  163. support::ubig16_t NumberOfRelocations;
  164. support::ubig16_t NumberOfLineNumbers;
  165. support::big32_t Flags;
  166. };
  167. struct XCOFFSectionHeader64 : XCOFFSectionHeader<XCOFFSectionHeader64> {
  168. char Name[XCOFF::NameSize];
  169. support::ubig64_t PhysicalAddress;
  170. support::ubig64_t VirtualAddress;
  171. support::ubig64_t SectionSize;
  172. support::big64_t FileOffsetToRawData;
  173. support::big64_t FileOffsetToRelocationInfo;
  174. support::big64_t FileOffsetToLineNumberInfo;
  175. support::ubig32_t NumberOfRelocations;
  176. support::ubig32_t NumberOfLineNumbers;
  177. support::big32_t Flags;
  178. char Padding[4];
  179. };
  180. struct LoaderSectionHeader32 {
  181. support::ubig32_t Version;
  182. support::ubig32_t NumberOfSymTabEnt;
  183. support::ubig32_t NumberOfRelTabEnt;
  184. support::ubig32_t LengthOfImpidStrTbl;
  185. support::ubig32_t NumberOfImpid;
  186. support::big32_t OffsetToImpid;
  187. support::ubig32_t LengthOfStrTbl;
  188. support::big32_t OffsetToStrTbl;
  189. };
  190. struct LoaderSectionHeader64 {
  191. support::ubig32_t Version;
  192. support::ubig32_t NumberOfSymTabEnt;
  193. support::ubig32_t NumberOfRelTabEnt;
  194. support::ubig32_t LengthOfImpidStrTbl;
  195. support::ubig32_t NumberOfImpid;
  196. support::ubig32_t LengthOfStrTbl;
  197. support::big64_t OffsetToImpid;
  198. support::big64_t OffsetToStrTbl;
  199. support::big64_t OffsetToSymTbl;
  200. char Padding[16];
  201. support::big32_t OffsetToRelEnt;
  202. };
  203. struct XCOFFStringTable {
  204. uint32_t Size;
  205. const char *Data;
  206. };
  207. struct XCOFFCsectAuxEnt32 {
  208. support::ubig32_t SectionOrLength;
  209. support::ubig32_t ParameterHashIndex;
  210. support::ubig16_t TypeChkSectNum;
  211. uint8_t SymbolAlignmentAndType;
  212. XCOFF::StorageMappingClass StorageMappingClass;
  213. support::ubig32_t StabInfoIndex;
  214. support::ubig16_t StabSectNum;
  215. };
  216. struct XCOFFCsectAuxEnt64 {
  217. support::ubig32_t SectionOrLengthLowByte;
  218. support::ubig32_t ParameterHashIndex;
  219. support::ubig16_t TypeChkSectNum;
  220. uint8_t SymbolAlignmentAndType;
  221. XCOFF::StorageMappingClass StorageMappingClass;
  222. support::ubig32_t SectionOrLengthHighByte;
  223. uint8_t Pad;
  224. XCOFF::SymbolAuxType AuxType;
  225. };
  226. class XCOFFCsectAuxRef {
  227. public:
  228. static constexpr uint8_t SymbolTypeMask = 0x07;
  229. static constexpr uint8_t SymbolAlignmentMask = 0xF8;
  230. static constexpr size_t SymbolAlignmentBitOffset = 3;
  231. XCOFFCsectAuxRef(const XCOFFCsectAuxEnt32 *Entry32) : Entry32(Entry32) {}
  232. XCOFFCsectAuxRef(const XCOFFCsectAuxEnt64 *Entry64) : Entry64(Entry64) {}
  233. // For getSectionOrLength(),
  234. // If the symbol type is XTY_SD or XTY_CM, the csect length.
  235. // If the symbol type is XTY_LD, the symbol table
  236. // index of the containing csect.
  237. // If the symbol type is XTY_ER, 0.
  238. uint64_t getSectionOrLength() const {
  239. return Entry32 ? getSectionOrLength32() : getSectionOrLength64();
  240. }
  241. uint32_t getSectionOrLength32() const {
  242. assert(Entry32 && "32-bit interface called on 64-bit object file.");
  243. return Entry32->SectionOrLength;
  244. }
  245. uint64_t getSectionOrLength64() const {
  246. assert(Entry64 && "64-bit interface called on 32-bit object file.");
  247. return (static_cast<uint64_t>(Entry64->SectionOrLengthHighByte) << 32) |
  248. Entry64->SectionOrLengthLowByte;
  249. }
  250. #define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X
  251. uint32_t getParameterHashIndex() const {
  252. return GETVALUE(ParameterHashIndex);
  253. }
  254. uint16_t getTypeChkSectNum() const { return GETVALUE(TypeChkSectNum); }
  255. XCOFF::StorageMappingClass getStorageMappingClass() const {
  256. return GETVALUE(StorageMappingClass);
  257. }
  258. uintptr_t getEntryAddress() const {
  259. return Entry32 ? reinterpret_cast<uintptr_t>(Entry32)
  260. : reinterpret_cast<uintptr_t>(Entry64);
  261. }
  262. uint16_t getAlignmentLog2() const {
  263. return (getSymbolAlignmentAndType() & SymbolAlignmentMask) >>
  264. SymbolAlignmentBitOffset;
  265. }
  266. uint8_t getSymbolType() const {
  267. return getSymbolAlignmentAndType() & SymbolTypeMask;
  268. }
  269. bool isLabel() const { return getSymbolType() == XCOFF::XTY_LD; }
  270. uint32_t getStabInfoIndex32() const {
  271. assert(Entry32 && "32-bit interface called on 64-bit object file.");
  272. return Entry32->StabInfoIndex;
  273. }
  274. uint16_t getStabSectNum32() const {
  275. assert(Entry32 && "32-bit interface called on 64-bit object file.");
  276. return Entry32->StabSectNum;
  277. }
  278. XCOFF::SymbolAuxType getAuxType64() const {
  279. assert(Entry64 && "64-bit interface called on 32-bit object file.");
  280. return Entry64->AuxType;
  281. }
  282. private:
  283. uint8_t getSymbolAlignmentAndType() const {
  284. return GETVALUE(SymbolAlignmentAndType);
  285. }
  286. #undef GETVALUE
  287. const XCOFFCsectAuxEnt32 *Entry32 = nullptr;
  288. const XCOFFCsectAuxEnt64 *Entry64 = nullptr;
  289. };
  290. struct XCOFFFileAuxEnt {
  291. typedef struct {
  292. support::big32_t Magic; // Zero indicates name in string table.
  293. support::ubig32_t Offset;
  294. char NamePad[XCOFF::FileNamePadSize];
  295. } NameInStrTblType;
  296. union {
  297. char Name[XCOFF::NameSize + XCOFF::FileNamePadSize];
  298. NameInStrTblType NameInStrTbl;
  299. };
  300. XCOFF::CFileStringType Type;
  301. uint8_t ReservedZeros[2];
  302. XCOFF::SymbolAuxType AuxType; // 64-bit XCOFF file only.
  303. };
  304. struct XCOFFSectAuxEntForStat {
  305. support::ubig32_t SectionLength;
  306. support::ubig16_t NumberOfRelocEnt;
  307. support::ubig16_t NumberOfLineNum;
  308. uint8_t Pad[10];
  309. }; // 32-bit XCOFF file only.
  310. struct XCOFFFunctionAuxEnt32 {
  311. support::ubig32_t OffsetToExceptionTbl;
  312. support::ubig32_t SizeOfFunction;
  313. support::ubig32_t PtrToLineNum;
  314. support::big32_t SymIdxOfNextBeyond;
  315. uint8_t Pad[2];
  316. };
  317. struct XCOFFFunctionAuxEnt64 {
  318. support::ubig64_t PtrToLineNum;
  319. support::ubig32_t SizeOfFunction;
  320. support::big32_t SymIdxOfNextBeyond;
  321. uint8_t Pad;
  322. XCOFF::SymbolAuxType AuxType; // Contains _AUX_FCN; Type of auxiliary entry
  323. };
  324. struct XCOFFExceptionAuxEnt {
  325. support::ubig64_t OffsetToExceptionTbl;
  326. support::ubig32_t SizeOfFunction;
  327. support::big32_t SymIdxOfNextBeyond;
  328. uint8_t Pad;
  329. XCOFF::SymbolAuxType AuxType; // Contains _AUX_EXCEPT; Type of auxiliary entry
  330. };
  331. struct XCOFFBlockAuxEnt32 {
  332. uint8_t ReservedZeros1[2];
  333. support::ubig16_t LineNumHi;
  334. support::ubig16_t LineNumLo;
  335. uint8_t ReservedZeros2[12];
  336. };
  337. struct XCOFFBlockAuxEnt64 {
  338. support::ubig32_t LineNum;
  339. uint8_t Pad[13];
  340. XCOFF::SymbolAuxType AuxType; // Contains _AUX_SYM; Type of auxiliary entry
  341. };
  342. struct XCOFFSectAuxEntForDWARF32 {
  343. support::ubig32_t LengthOfSectionPortion;
  344. uint8_t Pad1[4];
  345. support::ubig32_t NumberOfRelocEnt;
  346. uint8_t Pad2[6];
  347. };
  348. struct XCOFFSectAuxEntForDWARF64 {
  349. support::ubig64_t LengthOfSectionPortion;
  350. support::ubig64_t NumberOfRelocEnt;
  351. uint8_t Pad;
  352. XCOFF::SymbolAuxType AuxType; // Contains _AUX_SECT; Type of Auxillary entry
  353. };
  354. template <typename AddressType> struct XCOFFRelocation {
  355. // Masks for packing/unpacking the r_rsize field of relocations.
  356. // The msb is used to indicate if the bits being relocated are signed or
  357. // unsigned.
  358. static constexpr uint8_t XR_SIGN_INDICATOR_MASK = 0x80;
  359. // The 2nd msb is used to indicate that the binder has replaced/modified the
  360. // original instruction.
  361. static constexpr uint8_t XR_FIXUP_INDICATOR_MASK = 0x40;
  362. // The remaining bits specify the bit length of the relocatable reference
  363. // minus one.
  364. static constexpr uint8_t XR_BIASED_LENGTH_MASK = 0x3f;
  365. public:
  366. AddressType VirtualAddress;
  367. support::ubig32_t SymbolIndex;
  368. // Packed field, see XR_* masks for details of packing.
  369. uint8_t Info;
  370. XCOFF::RelocationType Type;
  371. public:
  372. bool isRelocationSigned() const;
  373. bool isFixupIndicated() const;
  374. // Returns the number of bits being relocated.
  375. uint8_t getRelocatedLength() const;
  376. };
  377. extern template struct XCOFFRelocation<llvm::support::ubig32_t>;
  378. extern template struct XCOFFRelocation<llvm::support::ubig64_t>;
  379. struct XCOFFRelocation32 : XCOFFRelocation<llvm::support::ubig32_t> {};
  380. struct XCOFFRelocation64 : XCOFFRelocation<llvm::support::ubig64_t> {};
  381. class XCOFFSymbolRef;
  382. class XCOFFObjectFile : public ObjectFile {
  383. private:
  384. const void *FileHeader = nullptr;
  385. const void *AuxiliaryHeader = nullptr;
  386. const void *SectionHeaderTable = nullptr;
  387. const void *SymbolTblPtr = nullptr;
  388. XCOFFStringTable StringTable = {0, nullptr};
  389. const XCOFFFileHeader32 *fileHeader32() const;
  390. const XCOFFFileHeader64 *fileHeader64() const;
  391. const XCOFFSectionHeader32 *sectionHeaderTable32() const;
  392. const XCOFFSectionHeader64 *sectionHeaderTable64() const;
  393. template <typename T> const T *sectionHeaderTable() const;
  394. size_t getFileHeaderSize() const;
  395. size_t getSectionHeaderSize() const;
  396. const XCOFFSectionHeader32 *toSection32(DataRefImpl Ref) const;
  397. const XCOFFSectionHeader64 *toSection64(DataRefImpl Ref) const;
  398. uintptr_t getSectionHeaderTableAddress() const;
  399. uintptr_t getEndOfSymbolTableAddress() const;
  400. Expected<uintptr_t> getLoaderSectionAddress() const;
  401. // This returns a pointer to the start of the storage for the name field of
  402. // the 32-bit or 64-bit SectionHeader struct. This string is *not* necessarily
  403. // null-terminated.
  404. const char *getSectionNameInternal(DataRefImpl Sec) const;
  405. static bool isReservedSectionNumber(int16_t SectionNumber);
  406. // Constructor and "create" factory function. The constructor is only a thin
  407. // wrapper around the base constructor. The "create" function fills out the
  408. // XCOFF-specific information and performs the error checking along the way.
  409. XCOFFObjectFile(unsigned Type, MemoryBufferRef Object);
  410. static Expected<std::unique_ptr<XCOFFObjectFile>> create(unsigned Type,
  411. MemoryBufferRef MBR);
  412. // Helper for parsing the StringTable. Returns an 'Error' if parsing failed
  413. // and an XCOFFStringTable if parsing succeeded.
  414. static Expected<XCOFFStringTable> parseStringTable(const XCOFFObjectFile *Obj,
  415. uint64_t Offset);
  416. // Make a friend so it can call the private 'create' function.
  417. friend Expected<std::unique_ptr<ObjectFile>>
  418. ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
  419. void checkSectionAddress(uintptr_t Addr, uintptr_t TableAddr) const;
  420. public:
  421. static constexpr uint64_t InvalidRelocOffset =
  422. std::numeric_limits<uint64_t>::max();
  423. // Interface inherited from base classes.
  424. void moveSymbolNext(DataRefImpl &Symb) const override;
  425. Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
  426. basic_symbol_iterator symbol_begin() const override;
  427. basic_symbol_iterator symbol_end() const override;
  428. Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
  429. Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
  430. uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
  431. uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
  432. uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
  433. Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
  434. Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
  435. void moveSectionNext(DataRefImpl &Sec) const override;
  436. Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
  437. uint64_t getSectionAddress(DataRefImpl Sec) const override;
  438. uint64_t getSectionIndex(DataRefImpl Sec) const override;
  439. uint64_t getSectionSize(DataRefImpl Sec) const override;
  440. Expected<ArrayRef<uint8_t>>
  441. getSectionContents(DataRefImpl Sec) const override;
  442. uint64_t getSectionAlignment(DataRefImpl Sec) const override;
  443. bool isSectionCompressed(DataRefImpl Sec) const override;
  444. bool isSectionText(DataRefImpl Sec) const override;
  445. bool isSectionData(DataRefImpl Sec) const override;
  446. bool isSectionBSS(DataRefImpl Sec) const override;
  447. bool isDebugSection(DataRefImpl Sec) const override;
  448. bool isSectionVirtual(DataRefImpl Sec) const override;
  449. relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
  450. relocation_iterator section_rel_end(DataRefImpl Sec) const override;
  451. void moveRelocationNext(DataRefImpl &Rel) const override;
  452. /// \returns the relocation offset with the base address of the containing
  453. /// section as zero, or InvalidRelocOffset on errors (such as a relocation
  454. /// that does not refer to an address in any section).
  455. uint64_t getRelocationOffset(DataRefImpl Rel) const override;
  456. symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
  457. uint64_t getRelocationType(DataRefImpl Rel) const override;
  458. void getRelocationTypeName(DataRefImpl Rel,
  459. SmallVectorImpl<char> &Result) const override;
  460. section_iterator section_begin() const override;
  461. section_iterator section_end() const override;
  462. uint8_t getBytesInAddress() const override;
  463. StringRef getFileFormatName() const override;
  464. Triple::ArchType getArch() const override;
  465. SubtargetFeatures getFeatures() const override;
  466. Expected<uint64_t> getStartAddress() const override;
  467. StringRef mapDebugSectionName(StringRef Name) const override;
  468. bool isRelocatableObject() const override;
  469. // Below here is the non-inherited interface.
  470. bool is64Bit() const;
  471. const XCOFFAuxiliaryHeader32 *auxiliaryHeader32() const;
  472. const XCOFFAuxiliaryHeader64 *auxiliaryHeader64() const;
  473. const void *getPointerToSymbolTable() const { return SymbolTblPtr; }
  474. Expected<StringRef> getSymbolSectionName(XCOFFSymbolRef Ref) const;
  475. unsigned getSymbolSectionID(SymbolRef Sym) const;
  476. XCOFFSymbolRef toSymbolRef(DataRefImpl Ref) const;
  477. // File header related interfaces.
  478. uint16_t getMagic() const;
  479. uint16_t getNumberOfSections() const;
  480. int32_t getTimeStamp() const;
  481. // Symbol table offset and entry count are handled differently between
  482. // XCOFF32 and XCOFF64.
  483. uint32_t getSymbolTableOffset32() const;
  484. uint64_t getSymbolTableOffset64() const;
  485. // Note that this value is signed and might return a negative value. Negative
  486. // values are reserved for future use.
  487. int32_t getRawNumberOfSymbolTableEntries32() const;
  488. // The sanitized value appropriate to use as an index into the symbol table.
  489. uint32_t getLogicalNumberOfSymbolTableEntries32() const;
  490. uint32_t getNumberOfSymbolTableEntries64() const;
  491. // Return getLogicalNumberOfSymbolTableEntries32 or
  492. // getNumberOfSymbolTableEntries64 depending on the object mode.
  493. uint32_t getNumberOfSymbolTableEntries() const;
  494. uint32_t getSymbolIndex(uintptr_t SymEntPtr) const;
  495. uint64_t getSymbolSize(DataRefImpl Symb) const;
  496. uintptr_t getSymbolByIndex(uint32_t Idx) const {
  497. return reinterpret_cast<uintptr_t>(SymbolTblPtr) +
  498. XCOFF::SymbolTableEntrySize * Idx;
  499. }
  500. uintptr_t getSymbolEntryAddressByIndex(uint32_t SymbolTableIndex) const;
  501. Expected<StringRef> getSymbolNameByIndex(uint32_t SymbolTableIndex) const;
  502. Expected<StringRef> getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const;
  503. uint16_t getOptionalHeaderSize() const;
  504. uint16_t getFlags() const;
  505. // Section header table related interfaces.
  506. ArrayRef<XCOFFSectionHeader32> sections32() const;
  507. ArrayRef<XCOFFSectionHeader64> sections64() const;
  508. int32_t getSectionFlags(DataRefImpl Sec) const;
  509. Expected<DataRefImpl> getSectionByNum(int16_t Num) const;
  510. void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const;
  511. // Relocation-related interfaces.
  512. template <typename T>
  513. Expected<uint32_t>
  514. getNumberOfRelocationEntries(const XCOFFSectionHeader<T> &Sec) const;
  515. template <typename Shdr, typename Reloc>
  516. Expected<ArrayRef<Reloc>> relocations(const Shdr &Sec) const;
  517. // Loader section related interfaces.
  518. Expected<StringRef> getImportFileTable() const;
  519. // This function returns string table entry.
  520. Expected<StringRef> getStringTableEntry(uint32_t Offset) const;
  521. // This function returns the string table.
  522. StringRef getStringTable() const;
  523. const XCOFF::SymbolAuxType *getSymbolAuxType(uintptr_t AuxEntryAddress) const;
  524. static uintptr_t getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,
  525. uint32_t Distance);
  526. static bool classof(const Binary *B) { return B->isXCOFF(); }
  527. }; // XCOFFObjectFile
  528. typedef struct {
  529. uint8_t LanguageId;
  530. uint8_t CpuTypeId;
  531. } CFileLanguageIdAndTypeIdType;
  532. struct XCOFFSymbolEntry32 {
  533. typedef struct {
  534. support::big32_t Magic; // Zero indicates name in string table.
  535. support::ubig32_t Offset;
  536. } NameInStrTblType;
  537. union {
  538. char SymbolName[XCOFF::NameSize];
  539. NameInStrTblType NameInStrTbl;
  540. };
  541. support::ubig32_t Value; // Symbol value; storage class-dependent.
  542. support::big16_t SectionNumber;
  543. union {
  544. support::ubig16_t SymbolType;
  545. CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
  546. };
  547. XCOFF::StorageClass StorageClass;
  548. uint8_t NumberOfAuxEntries;
  549. };
  550. struct XCOFFSymbolEntry64 {
  551. support::ubig64_t Value; // Symbol value; storage class-dependent.
  552. support::ubig32_t Offset;
  553. support::big16_t SectionNumber;
  554. union {
  555. support::ubig16_t SymbolType;
  556. CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
  557. };
  558. XCOFF::StorageClass StorageClass;
  559. uint8_t NumberOfAuxEntries;
  560. };
  561. class XCOFFSymbolRef {
  562. public:
  563. enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
  564. XCOFFSymbolRef(DataRefImpl SymEntDataRef,
  565. const XCOFFObjectFile *OwningObjectPtr)
  566. : OwningObjectPtr(OwningObjectPtr) {
  567. assert(OwningObjectPtr && "OwningObjectPtr cannot be nullptr!");
  568. assert(SymEntDataRef.p != 0 &&
  569. "Symbol table entry pointer cannot be nullptr!");
  570. if (OwningObjectPtr->is64Bit())
  571. Entry64 = reinterpret_cast<const XCOFFSymbolEntry64 *>(SymEntDataRef.p);
  572. else
  573. Entry32 = reinterpret_cast<const XCOFFSymbolEntry32 *>(SymEntDataRef.p);
  574. }
  575. uint64_t getValue() const { return Entry32 ? getValue32() : getValue64(); }
  576. uint32_t getValue32() const { return Entry32->Value; }
  577. uint64_t getValue64() const { return Entry64->Value; }
  578. #define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X
  579. int16_t getSectionNumber() const { return GETVALUE(SectionNumber); }
  580. uint16_t getSymbolType() const { return GETVALUE(SymbolType); }
  581. uint8_t getLanguageIdForCFile() const {
  582. assert(getStorageClass() == XCOFF::C_FILE &&
  583. "This interface is for C_FILE only.");
  584. return GETVALUE(CFileLanguageIdAndTypeId.LanguageId);
  585. }
  586. uint8_t getCPUTypeIddForCFile() const {
  587. assert(getStorageClass() == XCOFF::C_FILE &&
  588. "This interface is for C_FILE only.");
  589. return GETVALUE(CFileLanguageIdAndTypeId.CpuTypeId);
  590. }
  591. XCOFF::StorageClass getStorageClass() const { return GETVALUE(StorageClass); }
  592. uint8_t getNumberOfAuxEntries() const { return GETVALUE(NumberOfAuxEntries); }
  593. #undef GETVALUE
  594. uintptr_t getEntryAddress() const {
  595. return Entry32 ? reinterpret_cast<uintptr_t>(Entry32)
  596. : reinterpret_cast<uintptr_t>(Entry64);
  597. }
  598. Expected<StringRef> getName() const;
  599. bool isFunction() const;
  600. bool isCsectSymbol() const;
  601. Expected<XCOFFCsectAuxRef> getXCOFFCsectAuxRef() const;
  602. private:
  603. const XCOFFObjectFile *OwningObjectPtr;
  604. const XCOFFSymbolEntry32 *Entry32 = nullptr;
  605. const XCOFFSymbolEntry64 *Entry64 = nullptr;
  606. };
  607. class TBVectorExt {
  608. uint16_t Data;
  609. SmallString<32> VecParmsInfo;
  610. TBVectorExt(StringRef TBvectorStrRef, Error &Err);
  611. public:
  612. static Expected<TBVectorExt> create(StringRef TBvectorStrRef);
  613. uint8_t getNumberOfVRSaved() const;
  614. bool isVRSavedOnStack() const;
  615. bool hasVarArgs() const;
  616. uint8_t getNumberOfVectorParms() const;
  617. bool hasVMXInstruction() const;
  618. SmallString<32> getVectorParmsInfo() const { return VecParmsInfo; };
  619. };
  620. /// This class provides methods to extract traceback table data from a buffer.
  621. /// The various accessors may reference the buffer provided via the constructor.
  622. class XCOFFTracebackTable {
  623. const uint8_t *const TBPtr;
  624. Optional<SmallString<32>> ParmsType;
  625. Optional<uint32_t> TraceBackTableOffset;
  626. Optional<uint32_t> HandlerMask;
  627. Optional<uint32_t> NumOfCtlAnchors;
  628. Optional<SmallVector<uint32_t, 8>> ControlledStorageInfoDisp;
  629. Optional<StringRef> FunctionName;
  630. Optional<uint8_t> AllocaRegister;
  631. Optional<TBVectorExt> VecExt;
  632. Optional<uint8_t> ExtensionTable;
  633. XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size, Error &Err);
  634. public:
  635. /// Parse an XCOFF Traceback Table from \a Ptr with \a Size bytes.
  636. /// Returns an XCOFFTracebackTable upon successful parsing, otherwise an
  637. /// Error is returned.
  638. ///
  639. /// \param[in] Ptr
  640. /// A pointer that points just past the initial 4 bytes of zeros at the
  641. /// beginning of an XCOFF Traceback Table.
  642. ///
  643. /// \param[in, out] Size
  644. /// A pointer that points to the length of the XCOFF Traceback Table.
  645. /// If the XCOFF Traceback Table is not parsed successfully or there are
  646. /// extra bytes that are not recognized, \a Size will be updated to be the
  647. /// size up to the end of the last successfully parsed field of the table.
  648. static Expected<XCOFFTracebackTable> create(const uint8_t *Ptr,
  649. uint64_t &Size);
  650. uint8_t getVersion() const;
  651. uint8_t getLanguageID() const;
  652. bool isGlobalLinkage() const;
  653. bool isOutOfLineEpilogOrPrologue() const;
  654. bool hasTraceBackTableOffset() const;
  655. bool isInternalProcedure() const;
  656. bool hasControlledStorage() const;
  657. bool isTOCless() const;
  658. bool isFloatingPointPresent() const;
  659. bool isFloatingPointOperationLogOrAbortEnabled() const;
  660. bool isInterruptHandler() const;
  661. bool isFuncNamePresent() const;
  662. bool isAllocaUsed() const;
  663. uint8_t getOnConditionDirective() const;
  664. bool isCRSaved() const;
  665. bool isLRSaved() const;
  666. bool isBackChainStored() const;
  667. bool isFixup() const;
  668. uint8_t getNumOfFPRsSaved() const;
  669. bool hasVectorInfo() const;
  670. bool hasExtensionTable() const;
  671. uint8_t getNumOfGPRsSaved() const;
  672. uint8_t getNumberOfFixedParms() const;
  673. uint8_t getNumberOfFPParms() const;
  674. bool hasParmsOnStack() const;
  675. const Optional<SmallString<32>> &getParmsType() const { return ParmsType; }
  676. const Optional<uint32_t> &getTraceBackTableOffset() const {
  677. return TraceBackTableOffset;
  678. }
  679. const Optional<uint32_t> &getHandlerMask() const { return HandlerMask; }
  680. const Optional<uint32_t> &getNumOfCtlAnchors() { return NumOfCtlAnchors; }
  681. const Optional<SmallVector<uint32_t, 8>> &getControlledStorageInfoDisp() {
  682. return ControlledStorageInfoDisp;
  683. }
  684. const Optional<StringRef> &getFunctionName() const { return FunctionName; }
  685. const Optional<uint8_t> &getAllocaRegister() const { return AllocaRegister; }
  686. const Optional<TBVectorExt> &getVectorExt() const { return VecExt; }
  687. const Optional<uint8_t> &getExtensionTable() const { return ExtensionTable; }
  688. };
  689. bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes);
  690. } // namespace object
  691. } // namespace llvm
  692. #endif // LLVM_OBJECT_XCOFFOBJECTFILE_H
  693. #ifdef __GNUC__
  694. #pragma GCC diagnostic pop
  695. #endif