Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1111 lines
66 KiB

  1. /*
  2. File: PEFBinaryFormat.h
  3. Contains: PEF Types and Macros
  4. Version: QuickTime 7.3
  5. Copyright: (c) 2007 (c) 1993-2001 by Apple Computer, Inc., all rights reserved.
  6. Bugs?: For bug reports, consult the following page on
  7. the World Wide Web:
  8. http://developer.apple.com/bugreporter/
  9. */
  10. #ifndef __PEFBINARYFORMAT__
  11. #define __PEFBINARYFORMAT__
  12. #ifndef __MACTYPES__
  13. #include <MacTypes.h>
  14. #endif
  15. #if PRAGMA_ONCE
  16. #pragma once
  17. #endif
  18. #if PRAGMA_IMPORT
  19. #pragma import on
  20. #endif
  21. #if PRAGMA_STRUCT_ALIGN
  22. #pragma options align=mac68k
  23. #elif PRAGMA_STRUCT_PACKPUSH
  24. #pragma pack(push, 2)
  25. #elif PRAGMA_STRUCT_PACK
  26. #pragma pack(2)
  27. #endif
  28. /* -------------------------------------------------------------------------------------------- */
  29. /* Almost all types are padded for natural alignment. However the PEFExportedSymbol type is */
  30. /* 10 bytes long, containing two 32 bit fields and one 16 bit field. Arrays of it must be */
  31. /* packed, so it requires "68K" alignment. Setting this globally to 68K should also help */
  32. /* ensure consistent treatment across compilers. */
  33. /* ======================================================================================== */
  34. /* Overall Structure */
  35. /* ================= */
  36. /* -------------------------------------------------------------------------------------------- */
  37. /* This header contains a complete set of types and macros for dealing with the PEF executable */
  38. /* format. While some description is provided, this header is not meant as a primary source */
  39. /* of documentation on PEF. An excellent specification of PEF can be found in the Macintosh */
  40. /* Runtime Architectures book. This header is primarily a physical format description. Thus */
  41. /* it depends on as few other headers as possible and structure fields have obvious sizes. */
  42. /* */
  43. /* The physical storage for a PEF executable is known as a "container". This refers to just */
  44. /* the executable itself, not the file etc. E.g. if five DLLs are packaged in a single file's */
  45. /* data fork, that one data fork has five containers within it. */
  46. /* */
  47. /* A PEF container consists of an overall header, followed by one or more section headers, */
  48. /* followed by the section name table, followed by the contents for the sections. Some kinds */
  49. /* of sections have specific internal representation. The "loader" section is the most common */
  50. /* of these special sections. It contains information on the exports, imports, and runtime */
  51. /* relocations required to prepare the executable. PEF containers are self contained, all */
  52. /* portions are located via relative offsets. */
  53. /* */
  54. /* */
  55. /* +-------------------------------+ */
  56. /* | Container Header | 40 bytes */
  57. /* +-------------------------------+ */
  58. /* | Section 0 header | 28 bytes each */
  59. /* |...............................| */
  60. /* | - - - - | */
  61. /* |...............................| */
  62. /* | Section n-1 header | */
  63. /* +-------------------------------+ */
  64. /* | Section Name Table | */
  65. /* +-------------------------------+ */
  66. /* | Section x raw data | */
  67. /* +-------------------------------+ */
  68. /* | - - - - | */
  69. /* +-------------------------------+ */
  70. /* | Section y raw data | */
  71. /* +-------------------------------+ */
  72. /* */
  73. /* */
  74. /* The sections are implicitly numbered from 0 to n according to the order of their headers. */
  75. /* The headers of the instantiated sections must precede those of the non-instantiated */
  76. /* sections. The ordering of the raw data is independent of the section header ordering. */
  77. /* Each section header contains the offset for that section's raw data. */
  78. /* =========================================================================================== */
  79. /* Container Header */
  80. /* ================ */
  81. struct PEFContainerHeader {
  82. OSType tag1; /* Must contain 'Joy!'.*/
  83. OSType tag2; /* Must contain 'peff'. (Yes, with two 'f's.)*/
  84. OSType architecture; /* The ISA for code sections. Constants in CodeFragments.h.*/
  85. UInt32 formatVersion; /* The physical format version.*/
  86. UInt32 dateTimeStamp; /* Macintosh format creation/modification stamp.*/
  87. UInt32 oldDefVersion; /* Old definition version number for the code fragment.*/
  88. UInt32 oldImpVersion; /* Old implementation version number for the code fragment.*/
  89. UInt32 currentVersion; /* Current version number for the code fragment.*/
  90. UInt16 sectionCount; /* Total number of section headers that follow.*/
  91. UInt16 instSectionCount; /* Number of instantiated sections.*/
  92. UInt32 reservedA; /* Reserved, must be written as zero.*/
  93. };
  94. typedef struct PEFContainerHeader PEFContainerHeader;
  95. enum {
  96. kPEFTag1 = FOUR_CHAR_CODE('Joy!'), /* For non-Apple compilers: 0x4A6F7921.*/
  97. kPEFTag2 = FOUR_CHAR_CODE('peff'), /* For non-Apple compilers: 0x70656666.*/
  98. kPEFVersion = 0x00000001
  99. };
  100. enum {
  101. kPEFFirstSectionHeaderOffset = sizeof(PEFContainerHeader)
  102. };
  103. #define PEFFirstSectionNameOffset(container) \
  104. ( kPEFFirstSectionHeaderOffset + ((container)->sectionCount * sizeof ( PEFSectionHeader )) )
  105. /* =========================================================================================== */
  106. /* Section Headers */
  107. /* =============== */
  108. struct PEFSectionHeader {
  109. SInt32 nameOffset; /* Offset of name within the section name table, -1 => none.*/
  110. UInt32 defaultAddress; /* Default address, affects relocations.*/
  111. UInt32 totalLength; /* Fully expanded size in bytes of the section contents.*/
  112. UInt32 unpackedLength; /* Size in bytes of the "initialized" part of the contents.*/
  113. UInt32 containerLength; /* Size in bytes of the raw data in the container.*/
  114. UInt32 containerOffset; /* Offset of section's raw data.*/
  115. UInt8 sectionKind; /* Kind of section contents/usage.*/
  116. UInt8 shareKind; /* Sharing level, if a writeable section.*/
  117. UInt8 alignment; /* Preferred alignment, expressed as log 2.*/
  118. UInt8 reservedA; /* Reserved, must be zero.*/
  119. };
  120. typedef struct PEFSectionHeader PEFSectionHeader;
  121. enum {
  122. /* Values for the sectionKind field.*/
  123. /* Section kind values for instantiated sections.*/
  124. kPEFCodeSection = 0, /* Code, presumed pure & position independent.*/
  125. kPEFUnpackedDataSection = 1, /* Unpacked writeable data.*/
  126. kPEFPackedDataSection = 2, /* Packed writeable data.*/
  127. kPEFConstantSection = 3, /* Read-only data.*/
  128. kPEFExecDataSection = 6, /* Intermixed code and writeable data.*/
  129. /* Section kind values for non-instantiated sections.*/
  130. kPEFLoaderSection = 4, /* Loader tables.*/
  131. kPEFDebugSection = 5, /* Reserved for future use.*/
  132. kPEFExceptionSection = 7, /* Reserved for future use.*/
  133. kPEFTracebackSection = 8 /* Reserved for future use.*/
  134. };
  135. enum {
  136. /* Values for the shareKind field.*/
  137. kPEFProcessShare = 1, /* Shared within a single process.*/
  138. kPEFGlobalShare = 4, /* Shared across the entire system.*/
  139. kPEFProtectedShare = 5 /* Readable across the entire system, writeable only to privileged code.*/
  140. };
  141. /* =========================================================================================== */
  142. /* Packed Data Contents */
  143. /* ==================== */
  144. /* -------------------------------------------------------------------------------------------- */
  145. /* The raw contents of a packed data section are a sequence of byte codes. The basic format */
  146. /* has a 3 bit opcode followed by a 5 bit count. Additional bytes might be used to contain */
  147. /* counts larger than 31, and to contain a second or third count. Further additional bytes */
  148. /* contain actual data values to transfer. */
  149. /* */
  150. /* All counts are represented in a variable length manner. A zero in the initial 5 bit count */
  151. /* indicates the actual value follows. In this case, and for the second and third counts, the */
  152. /* count is represented as a variable length sequence of bytes. The bytes are stored in big */
  153. /* endian manner, most significant part first. The high order bit is set in all but the last */
  154. /* byte. The value is accumulated by shifting the current value up 7 bits and adding in the */
  155. /* low order 7 bits of the next byte. */
  156. enum {
  157. /* The packed data opcodes.*/
  158. kPEFPkDataZero = 0, /* Zero fill "count" bytes.*/
  159. kPEFPkDataBlock = 1, /* Block copy "count" bytes.*/
  160. kPEFPkDataRepeat = 2, /* Repeat "count" bytes "count2"+1 times.*/
  161. kPEFPkDataRepeatBlock = 3, /* Interleaved repeated and unique data.*/
  162. kPEFPkDataRepeatZero = 4 /* Interleaved zero and unique data.*/
  163. };
  164. enum {
  165. kPEFPkDataOpcodeShift = 5,
  166. kPEFPkDataCount5Mask = 0x1F,
  167. kPEFPkDataMaxCount5 = 31,
  168. kPEFPkDataVCountShift = 7,
  169. kPEFPkDataVCountMask = 0x7F,
  170. kPEFPkDataVCountEndMask = 0x80
  171. };
  172. #define PEFPkDataOpcode(byte) ( ((UInt8)(byte)) >> kPEFPkDataOpcodeShift )
  173. #define PEFPkDataCount5(byte) ( ((UInt8)(byte)) & kPEFPkDataCount5Mask )
  174. #define PEFPkDataComposeInstr(opcode,count5) \
  175. ( (((UInt8)(opcode)) << kPEFPkDataOpcodeShift) | ((UInt8)(count5)) )
  176. /* -------------------------------------------------------------------------------------------- */
  177. /* The following code snippet can be used to input a variable length count. */
  178. /* */
  179. /* count = 0; */
  180. /* do { */
  181. /* byte = *bytePtr++; */
  182. /* count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask); */
  183. /* } while ( (byte & kPEFPkDataVCountEndMask) != 0 ); */
  184. /* */
  185. /* The following code snippet can be used to output a variable length count to a byte array. */
  186. /* This is more complex than the input code because the chunks are output in big endian order. */
  187. /* Think about handling values like 0 or 0x030000. */
  188. /* */
  189. /* count = 1;. */
  190. /* tempValue = value >> kPEFPkDataCountShift; */
  191. /* while ( tempValue != 0 ) { */
  192. /* count += 1; */
  193. /* tempValue = tempValue >> kPEFPkDataCountShift; */
  194. /* } */
  195. /* */
  196. /* bytePtr += count; */
  197. /* tempPtr = bytePtr - 1; */
  198. /* *tempPtr-- = value; // ! No need to mask, only the low order byte is stored. */
  199. /* for ( count -= 1; count != 0; count -= 1 ) { */
  200. /* value = value >> kPEFPkDataCountShift; */
  201. /* *tempPtr-- = value | kPEFPkDataCountEndMask; */
  202. /* } */
  203. /* =========================================================================================== */
  204. /* Loader Section */
  205. /* ============== */
  206. /* -------------------------------------------------------------------------------------------- */
  207. /* The loader section contains information needed to prepare the code fragment for execution. */
  208. /* This includes this fragment's exports, the import libraries and the imported symbols from */
  209. /* each library, and the relocations for the writeable sections. */
  210. /* */
  211. /* +-----------------------------------+ <-- containerOffset --------+ */
  212. /* | Loader Info Header | 56 bytes | */
  213. /* |-----------------------------------| | */
  214. /* | Imported Library 0 | 24 bytes each | */
  215. /* |...................................| | */
  216. /* | - - - | | */
  217. /* |...................................| | */
  218. /* | Imported Library l-1 | | */
  219. /* |-----------------------------------| | */
  220. /* | Imported Symbol 0 | 4 bytes each | */
  221. /* |...................................| | */
  222. /* | - - - | | */
  223. /* |...................................| | */
  224. /* | Imported Symbol i-1 | | */
  225. /* |-----------------------------------| | */
  226. /* | Relocation Header 0 | 12 bytes each | */
  227. /* |...................................| | */
  228. /* | - - - | | */
  229. /* |...................................| | */
  230. /* | Relocation Header r-1 | | */
  231. /* |-----------------------------------| <-- + relocInstrOffset -----| */
  232. /* | Relocation Instructions | | */
  233. /* |-----------------------------------| <-- + loaderStringsOffset --| */
  234. /* | Loader String Table | | */
  235. /* |-----------------------------------| <-- + exportHashOffset -----+ */
  236. /* | Export Hash Slot 0 | 4 bytes each */
  237. /* |...................................| */
  238. /* | - - - | */
  239. /* |...................................| */
  240. /* | Export Hash Slot h-1 | */
  241. /* |-----------------------------------| */
  242. /* | Export Symbol Key 0 | 4 bytes each */
  243. /* |...................................| */
  244. /* | - - - | */
  245. /* |...................................| */
  246. /* | Export Symbol Key e-1 | */
  247. /* |-----------------------------------| */
  248. /* | Export Symbol 0 | 10 bytes each */
  249. /* |...................................| */
  250. /* | - - - | */
  251. /* |...................................| */
  252. /* | Export Symbol e-1 | */
  253. /* +-----------------------------------+ */
  254. struct PEFLoaderInfoHeader {
  255. SInt32 mainSection; /* Section containing the main symbol, -1 => none.*/
  256. UInt32 mainOffset; /* Offset of main symbol.*/
  257. SInt32 initSection; /* Section containing the init routine's TVector, -1 => none.*/
  258. UInt32 initOffset; /* Offset of the init routine's TVector.*/
  259. SInt32 termSection; /* Section containing the term routine's TVector, -1 => none.*/
  260. UInt32 termOffset; /* Offset of the term routine's TVector.*/
  261. UInt32 importedLibraryCount; /* Number of imported libraries. ('l')*/
  262. UInt32 totalImportedSymbolCount; /* Total number of imported symbols. ('i')*/
  263. UInt32 relocSectionCount; /* Number of sections with relocations. ('r')*/
  264. UInt32 relocInstrOffset; /* Offset of the relocation instructions.*/
  265. UInt32 loaderStringsOffset; /* Offset of the loader string table.*/
  266. UInt32 exportHashOffset; /* Offset of the export hash table.*/
  267. UInt32 exportHashTablePower; /* Export hash table size as log 2. (Log2('h'))*/
  268. UInt32 exportedSymbolCount; /* Number of exported symbols. ('e')*/
  269. };
  270. typedef struct PEFLoaderInfoHeader PEFLoaderInfoHeader;
  271. /* =========================================================================================== */
  272. /* Imported Libraries */
  273. /* ------------------ */
  274. struct PEFImportedLibrary {
  275. UInt32 nameOffset; /* Loader string table offset of library's name.*/
  276. UInt32 oldImpVersion; /* Oldest compatible implementation version.*/
  277. UInt32 currentVersion; /* Current version at build time.*/
  278. UInt32 importedSymbolCount; /* Imported symbol count for this library.*/
  279. UInt32 firstImportedSymbol; /* Index of first imported symbol from this library.*/
  280. UInt8 options; /* Option bits for this library.*/
  281. UInt8 reservedA; /* Reserved, must be zero.*/
  282. UInt16 reservedB; /* Reserved, must be zero.*/
  283. };
  284. typedef struct PEFImportedLibrary PEFImportedLibrary;
  285. enum {
  286. /* Bits for the PEFImportedLibrary options field.*/
  287. kPEFWeakImportLibMask = 0x40, /* The imported library is allowed to be missing.*/
  288. kPEFInitLibBeforeMask = 0x80 /* The imported library must be initialized first.*/
  289. };
  290. /* =========================================================================================== */
  291. /* Imported Symbols */
  292. /* ---------------- */
  293. /* -------------------------------------------------------------------------------------------- */
  294. /* The PEFImportedSymbol type has the following bit field layout. */
  295. /* */
  296. /* 3 */
  297. /* 0 7 8 1 */
  298. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  299. /* | symbol class | offset of symbol name in loader string table | */
  300. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  301. /* |<-- 8 bits --->|<-- 24 bits ---------------------------------->| */
  302. struct PEFImportedSymbol {
  303. UInt32 classAndName;
  304. };
  305. typedef struct PEFImportedSymbol PEFImportedSymbol;
  306. enum {
  307. kPEFImpSymClassShift = 24,
  308. kPEFImpSymNameOffsetMask = 0x00FFFFFF,
  309. kPEFImpSymMaxNameOffset = 0x00FFFFFF /* 16,777,215*/
  310. };
  311. #define PEFImportedSymbolClass(classAndName) ((UInt8) ((classAndName) >> kPEFImpSymClassShift))
  312. #define PEFImportedSymbolNameOffset(classAndName) ((classAndName) & kPEFImpSymNameOffsetMask)
  313. #define PEFComposeImportedSymbol(class,nameOffset) \
  314. ( ( ((UInt32)(class)) << kPEFImpSymClassShift ) | ( (UInt32)(nameOffset) ) )
  315. enum {
  316. /* Imported and exported symbol classes.*/
  317. kPEFCodeSymbol = 0x00,
  318. kPEFDataSymbol = 0x01,
  319. kPEFTVectorSymbol = 0x02,
  320. kPEFTOCSymbol = 0x03,
  321. kPEFGlueSymbol = 0x04,
  322. kPEFUndefinedSymbol = 0x0F,
  323. kPEFWeakImportSymMask = 0x80
  324. };
  325. /* =========================================================================================== */
  326. /* Exported Symbol Hash Table */
  327. /* -------------------------- */
  328. /* -------------------------------------------------------------------------------------------- */
  329. /* Exported symbols are described in four parts, optimized for speed of lookup. These parts */
  330. /* are the "export hash table", the "export key table", the "export symbol table", and the */
  331. /* "export name table". Overall they contain a flattened representation of a fairly normal */
  332. /* hashed symbol table. */
  333. /* */
  334. /* The export hash table is an array of small fixed size elements. The number of elements is */
  335. /* a power of 2. A 32 bit hash word for a symbol is converted into an index into this array. */
  336. /* Each hash slot contains a count of the number of exported symbols that map to this slot and */
  337. /* the index of the first of those symbols in the key and symbol tables. Of course some hash */
  338. /* slots will have a zero count. */
  339. /* */
  340. /* The key and symbol tables are also arrays of fixed size elements, one for each exported */
  341. /* symbol. Their entries are grouped by hash slot, those elements mapping to the same hash */
  342. /* slot are contiguous. The key table contains just the full 32 bit hash word for each */
  343. /* exported symbol. The symbol table contains the offset of the symbol's name in the string */
  344. /* table and other information about the exported symbol. */
  345. /* */
  346. /* To look up an export you take the hashword and compute the hash slot index. You then scan */
  347. /* the indicated portion of the key table for matching hashwords. If a hashword matches, you */
  348. /* look at the corresponding symbol table entry to find the full symbol name. If the names */
  349. /* match the symbol is found. */
  350. /* -------------------------------------------------------------------------------------------- */
  351. /* The following function may be used to compute the hash table size. Signed values are used */
  352. /* just to avoid potential code generation overhead for unsigned division. */
  353. /* */
  354. /* UInt8 PEFComputeHashTableExponent ( SInt32 exportCount ) */
  355. /* { */
  356. /* SInt32 exponent; */
  357. /* */
  358. /* const SInt32 kExponentLimit = 16; // Arbitrary, but must not exceed 30. */
  359. /* const SInt32 kAverageChainLimit = 10; // Arbitrary, for space/time tradeoff. */
  360. /* */
  361. /* for ( exponent = 0; exponent < kExponentLimit; exponent += 1 ) { */
  362. /* if ( (exportCount / (1 << exponent)) < kAverageChainLimit ) break; */
  363. /* } */
  364. /* */
  365. /* return exponent; */
  366. /* */
  367. /* } // PEFComputeHashTableExponent () */
  368. /* -------------------------------------------------------------------------------------------- */
  369. /* The PEFExportedSymbolHashSlot type has the following bit field layout. */
  370. /* */
  371. /* 1 1 3 */
  372. /* 0 3 4 1 */
  373. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  374. /* | symbol count | index of first export key | */
  375. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  376. /* |<-- 14 bits -------------->|<-- 18 bits ---------------------->| */
  377. struct PEFExportedSymbolHashSlot {
  378. UInt32 countAndStart;
  379. };
  380. typedef struct PEFExportedSymbolHashSlot PEFExportedSymbolHashSlot;
  381. enum {
  382. kPEFHashSlotSymCountShift = 18,
  383. kPEFHashSlotFirstKeyMask = 0x0003FFFF,
  384. kPEFHashSlotMaxSymbolCount = 0x00003FFF, /* 16,383*/
  385. kPEFHashSlotMaxKeyIndex = 0x0003FFFF /* 262,143*/
  386. };
  387. #define PEFHashTableIndex(fullHashWord,hashTablePower) \
  388. ( ( (fullHashWord) ^ ((fullHashWord) >> (hashTablePower)) ) & ((1 << (hashTablePower)) - 1) )
  389. #define PEFHashSlotSymbolCount(countAndStart) ((UInt32) ((countAndStart) >> kPEFHashSlotSymCountShift))
  390. #define PEFHashSlotFirstKey(countAndStart) ((countAndStart) & kPEFHashSlotFirstKeyMask)
  391. #define PEFComposeExportedSymbolHashSlot(symbolCount,firstKey) \
  392. ( ( ((UInt32)(symbolCount)) << kPEFHashSlotSymCountShift ) | ( (UInt32)(firstKey) ) )
  393. /* =========================================================================================== */
  394. /* Exported Symbol Hash Key */
  395. /* ------------------------ */
  396. struct PEFSplitHashWord {
  397. UInt16 nameLength;
  398. UInt16 hashValue;
  399. };
  400. typedef struct PEFSplitHashWord PEFSplitHashWord;
  401. struct PEFExportedSymbolKey {
  402. union {
  403. UInt32 fullHashWord;
  404. PEFSplitHashWord splitHashWord;
  405. } u;
  406. };
  407. typedef struct PEFExportedSymbolKey PEFExportedSymbolKey;
  408. enum {
  409. kPEFHashLengthShift = 16,
  410. kPEFHashValueMask = 0x0000FFFF,
  411. kPEFHashMaxLength = 0x0000FFFF /* 65,535*/
  412. };
  413. #define PEFHashNameLength(fullHashWord) ((UInt32) ((fullHashWord) >> kPEFHashLengthShift))
  414. #define PEFHashValue(fullHashWord) ((fullHashWord) & kPEFHashValueMask)
  415. #define PEFComposeFullHashWord(nameLength,hashValue) \
  416. ( ( ((UInt32)(nameLength)) << kPEFHashLengthShift ) | ( (UInt32)(hashValue) ) )
  417. /* ---------------------------------------------------------------------------------------------------- */
  418. /* The following function computes the full 32 bit hash word. */
  419. /* */
  420. /* UInt32 PEFComputeHashWord ( BytePtr nameText, // ! First "letter", not length byte. */
  421. /* UInt32 nameLength ) // ! The text may be zero terminated. */
  422. /* { */
  423. /* BytePtr charPtr = nameText; */
  424. /* SInt32 hashValue = 0; // ! Signed to match old published algorithm. */
  425. /* UInt32 length = 0; */
  426. /* UInt32 limit; */
  427. /* UInt32 result; */
  428. /* UInt8 currChar; */
  429. /* */
  430. /* #define PseudoRotate(x) ( ( (x) << 1 ) - ( (x) >> 16 ) ) */
  431. /* */
  432. /* for ( limit = nameLength; limit > 0; limit -= 1 ) { */
  433. /* currChar = *charPtr++; */
  434. /* if ( currChar == NULL ) break; */
  435. /* length += 1; */
  436. /* hashValue = PseudoRotate ( hashValue ) ^ currChar; */
  437. /* } */
  438. /* */
  439. /* result = (length << kPEFHashLengthShift) | */
  440. /* ((UInt16) ((hashValue ^ (hashValue >> 16)) & kPEFHashValueMask)); */
  441. /* */
  442. /* return result; */
  443. /* */
  444. /* } // PEFComputeHashWord () */
  445. /* =========================================================================================== */
  446. /* Exported Symbols */
  447. /* ---------------- */
  448. struct PEFExportedSymbol { /* ! This structure is 10 bytes long and arrays are packed.*/
  449. UInt32 classAndName; /* A combination of class and name offset.*/
  450. UInt32 symbolValue; /* Typically the symbol's offset within a section.*/
  451. SInt16 sectionIndex; /* The index of the section, or pseudo-section, for the symbol.*/
  452. };
  453. typedef struct PEFExportedSymbol PEFExportedSymbol;
  454. /* -------------------------------------------------------------------------------------------- */
  455. /* The classAndName field of the PEFExportedSymbol type has the following bit field layout. */
  456. /* */
  457. /* 3 */
  458. /* 0 7 8 1 */
  459. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  460. /* | symbol class | offset of symbol name in loader string table | */
  461. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  462. /* |<-- 8 bits --->|<-- 24 bits ---------------------------------->| */
  463. enum {
  464. kPEFExpSymClassShift = 24,
  465. kPEFExpSymNameOffsetMask = 0x00FFFFFF,
  466. kPEFExpSymMaxNameOffset = 0x00FFFFFF /* 16,777,215*/
  467. };
  468. #define PEFExportedSymbolClass(classAndName) ((UInt8) ((classAndName) >> kPEFExpSymClassShift))
  469. #define PEFExportedSymbolNameOffset(classAndName) ((classAndName) & kPEFExpSymNameOffsetMask)
  470. #define PEFComposeExportedSymbol(class,nameOffset) \
  471. ( ( ((UInt32)(class)) << kPEFExpSymClassShift ) | ( (UInt32)(nameOffset) ) )
  472. enum {
  473. /* Negative section indices indicate pseudo-sections.*/
  474. kPEFAbsoluteExport = -2, /* The symbol value is an absolute address.*/
  475. kPEFReexportedImport = -3 /* The symbol value is the index of a reexported import.*/
  476. };
  477. /* =========================================================================================== */
  478. /* Loader Relocations */
  479. /* ================== */
  480. /* -------------------------------------------------------------------------------------------- */
  481. /* The relocations for a section are defined by a sequence of instructions for an abstract */
  482. /* machine that is specifically geared to performing relocations commonly needed for the "CFM" */
  483. /* code generation model. These instructions occur in 16 bit chunks. Most instructions have */
  484. /* just a single chunk. Instructions that are larger than 16 bits have an opcode and some of */
  485. /* the operands in the first chunk, with other operands in following chunks. */
  486. /* */
  487. /* ! Note that the multi-chunk relocations have separate "Compose" macros for each chunk. The */
  488. /* ! macros have the same basic name with a positional suffix of "_1st", "_2nd", etc. */
  489. typedef UInt16 PEFRelocChunk;
  490. struct PEFLoaderRelocationHeader {
  491. UInt16 sectionIndex; /* Index of the section to be fixed up.*/
  492. UInt16 reservedA; /* Reserved, must be zero.*/
  493. UInt32 relocCount; /* Number of 16 bit relocation chunks.*/
  494. UInt32 firstRelocOffset; /* Offset of first relocation instruction.*/
  495. };
  496. typedef struct PEFLoaderRelocationHeader PEFLoaderRelocationHeader;
  497. /* -------------------------------------------------------------------------------------------- */
  498. /* ! Note that the relocCount field is the number of 16 bit relocation chunks, i.e. 1/2 the */
  499. /* ! total number of bytes of relocation instructions. While most relocation instructions are */
  500. /* ! 16 bits long, some are longer so the number of complete relocation instructions may be */
  501. /* ! less than the relocCount value. */
  502. /* ------------------------------------------------------------------------------------ */
  503. /* The PEFRelocField macro is a utility for extracting relocation instruction fields. */
  504. #define PEFRFShift(offset,length) (16 - ((offset) + (length)))
  505. #define PEFRFMask(length) ((1 << (length)) - 1)
  506. #define PEFRelocField(chunk,offset,length) \
  507. ( ( (chunk) >> (16 - ((offset) + (length))) ) & ((1 << (length)) - 1) )
  508. /* =========================================================================================== */
  509. /* Basic Relocation Opcodes */
  510. /* ------------------------ */
  511. /* -------------------------------------------------------------------------------------------- */
  512. /* The number of opcode bits varies from 2 to 7. The enumeration and switch table given here */
  513. /* are defined in terms of the most significant 7 bits of the first instruction chunk. An */
  514. /* instruction is decoded by using the most significant 7 bits as an index into the opcode */
  515. /* table, which in turn contains appropriately masked forms of the most significant 7 bits. */
  516. /* The macro PEFRelocBasicOpcode assumes a declaration of the form. */
  517. /* */
  518. /* UInt8 kPEFRelocBasicOpcodes [kPEFRelocBasicOpcodeRange] = { PEFMaskedBasicOpcodes }; */
  519. enum {
  520. kPEFRelocBasicOpcodeRange = 128
  521. };
  522. #define PEFRelocBasicOpcode(firstChunk) (kPEFRelocBasicOpcodes[(firstChunk)>>9])
  523. /* -------------------------------------------------------------------------------------------- */
  524. /* The relocation opcodes, clustered by major and minor groups. The instructions within a */
  525. /* cluster all have the same bit field layout. The enumeration values use the high order 7 */
  526. /* bits of the relocation instruction. Unused low order bits are set to zero. */
  527. enum {
  528. kPEFRelocBySectDWithSkip = 0x00, /* Binary: 00x_xxxx*/
  529. kPEFRelocBySectC = 0x20, /* Binary: 010_0000, group is "RelocRun"*/
  530. kPEFRelocBySectD = 0x21, /* Binary: 010_0001*/
  531. kPEFRelocTVector12 = 0x22, /* Binary: 010_0010*/
  532. kPEFRelocTVector8 = 0x23, /* Binary: 010_0011*/
  533. kPEFRelocVTable8 = 0x24, /* Binary: 010_0100*/
  534. kPEFRelocImportRun = 0x25, /* Binary: 010_0101*/
  535. kPEFRelocSmByImport = 0x30, /* Binary: 011_0000, group is "RelocSmIndex"*/
  536. kPEFRelocSmSetSectC = 0x31, /* Binary: 011_0001*/
  537. kPEFRelocSmSetSectD = 0x32, /* Binary: 011_0010*/
  538. kPEFRelocSmBySection = 0x33, /* Binary: 011_0011*/
  539. kPEFRelocIncrPosition = 0x40, /* Binary: 100_0xxx*/
  540. kPEFRelocSmRepeat = 0x48, /* Binary: 100_1xxx*/
  541. kPEFRelocSetPosition = 0x50, /* Binary: 101_000x*/
  542. kPEFRelocLgByImport = 0x52, /* Binary: 101_001x*/
  543. kPEFRelocLgRepeat = 0x58, /* Binary: 101_100x*/
  544. kPEFRelocLgSetOrBySection = 0x5A, /* Binary: 101_101x*/
  545. kPEFRelocUndefinedOpcode = 0xFF /* Used in masking table for all undefined values.*/
  546. };
  547. /* ---------------------------------------------------------------------------- */
  548. /* The RelocLgSetOrBySection instruction has an additional 4 bits of subopcode */
  549. /* beyond the 7 used by the dispatch table. To be precise it has 6 plus 4 but */
  550. /* the dispatch table ignores the 7th bit, so the subdispatch is on all 4 extra */
  551. /* subopcode bits. */
  552. enum {
  553. kPEFRelocLgBySectionSubopcode = 0x00, /* Binary: 0000*/
  554. kPEFRelocLgSetSectCSubopcode = 0x01, /* Binary: 0001*/
  555. kPEFRelocLgSetSectDSubopcode = 0x02 /* Binary: 0010*/
  556. };
  557. #define PEFRelocLgSetOrBySubopcode(chunk) (((chunk) >> 6) & 0x0F)
  558. /* -------------------------------------------------------------------------------------------- */
  559. /* The initial values for the opcode "masking" table. This has the enumeration values from */
  560. /* above with appropriate replications for "don't care" bits. It is almost certainly shorter */
  561. /* and faster to look up the masked value in a table than to use a branch tree. */
  562. #define PEFMaskedBasicOpcodes \
  563. \
  564. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x00 .. 0x03 */ \
  565. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x04 .. 0x07 */ \
  566. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x08 .. 0x0B */ \
  567. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x0C .. 0x0F */ \
  568. \
  569. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x10 .. 0x13 */ \
  570. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x14 .. 0x17 */ \
  571. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x18 .. 0x1B */ \
  572. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x1C .. 0x1F */ \
  573. \
  574. kPEFRelocBySectC, kPEFRelocBySectD, kPEFRelocTVector12, kPEFRelocTVector8, /* 0x20 .. 0x23 */ \
  575. kPEFRelocVTable8, kPEFRelocImportRun, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x24 .. 0x27 */ \
  576. \
  577. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x28 .. 0x2B */ \
  578. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x2C .. 0x2F */ \
  579. \
  580. kPEFRelocSmByImport, kPEFRelocSmSetSectC, kPEFRelocSmSetSectD, kPEFRelocSmBySection, /* 0x30 .. 0x33 */ \
  581. \
  582. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x34 .. 0x37 */ \
  583. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x38 .. 0x3B */ \
  584. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x3C .. 0x3F */ \
  585. \
  586. kPEFRelocIncrPosition, kPEFRelocIncrPosition, kPEFRelocIncrPosition, kPEFRelocIncrPosition, /* 0x40 .. 0x43 */ \
  587. kPEFRelocIncrPosition, kPEFRelocIncrPosition, kPEFRelocIncrPosition, kPEFRelocIncrPosition, /* 0x44 .. 0x47 */ \
  588. \
  589. kPEFRelocSmRepeat, kPEFRelocSmRepeat, kPEFRelocSmRepeat, kPEFRelocSmRepeat, /* 0x48 .. 0x4B */ \
  590. kPEFRelocSmRepeat, kPEFRelocSmRepeat, kPEFRelocSmRepeat, kPEFRelocSmRepeat, /* 0x4C .. 0x4F */ \
  591. \
  592. kPEFRelocSetPosition, kPEFRelocSetPosition, kPEFRelocLgByImport, kPEFRelocLgByImport, /* 0x50 .. 0x53 */ \
  593. \
  594. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x54 .. 0x57 */ \
  595. \
  596. kPEFRelocLgRepeat, kPEFRelocLgRepeat, kPEFRelocLgSetOrBySection, kPEFRelocLgSetOrBySection, /* 0x58 .. 0x5B */ \
  597. \
  598. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x5C .. 0x5F */ \
  599. \
  600. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x60 .. 0x63 */ \
  601. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x64 .. 0x67 */ \
  602. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x68 .. 0x6B */ \
  603. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x6C .. 0x6F */ \
  604. \
  605. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x70 .. 0x73 */ \
  606. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x74 .. 0x77 */ \
  607. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x78 .. 0x7B */ \
  608. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode /* 0x7C .. 0x7F */
  609. /* =========================================================================================== */
  610. /* RelocBySectDWithSkip Instruction (DDAT) */
  611. /* --------------------------------------- */
  612. /* -------------------------------------------------------------------------------------------- */
  613. /* The "RelocBySectDWithSkip" (DDAT) instruction has the following bit field layout. */
  614. /* */
  615. /* 1 1 */
  616. /* 0 1 2 9 0 5 */
  617. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  618. /* |0 0| skip count | rel count | */
  619. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  620. /* | 2 |<-- 8 bits --->|<-- 6 --->| */
  621. /* */
  622. /* ! Note that the stored skip count and reloc count are the actual values! */
  623. enum {
  624. kPEFRelocWithSkipMaxSkipCount = 255,
  625. kPEFRelocWithSkipMaxRelocCount = 63
  626. };
  627. #define PEFRelocWithSkipSkipCount(chunk) PEFRelocField ( (chunk), 2, 8 )
  628. #define PEFRelocWithSkipRelocCount(chunk) PEFRelocField ( (chunk), 10, 6 )
  629. #define PEFRelocComposeWithSkip(skipCount,relocCount) \
  630. ( 0x0000 | (((UInt16)(skipCount)) << 6) | ((UInt16)(relocCount)) )
  631. /* =========================================================================================== */
  632. /* RelocRun Group (CODE, DATA, DESC, DSC2, VTBL, SYMR) */
  633. /* --------------------------------------------------- */
  634. /* -------------------------------------------------------------------------------------------- */
  635. /* The "RelocRun" group includes the "RelocBySectC" (CODE), "RelocBySectD" (DATA), */
  636. /* "RelocTVector12" (DESC), "RelocTVector8" (DSC2), "RelocVTable8" (VTBL), and */
  637. /* "RelocImportRun" (SYMR) instructions. This group has the following bit field layout. */
  638. /* */
  639. /* 1 */
  640. /* 0 2 3 6 7 5 */
  641. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  642. /* |0 1 0| subop.| run length | */
  643. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  644. /* | 3 |<- 4 ->|<-- 9 bits ----->| */
  645. /* */
  646. /* ! Note that the stored run length is the actual value minus 1, but the macros deal with the */
  647. /* ! actual value! */
  648. enum {
  649. kPEFRelocRunMaxRunLength = 512
  650. };
  651. #define PEFRelocRunSubopcode(chunk) PEFRelocField ( (chunk), 3, 4 )
  652. #define PEFRelocRunRunLength(chunk) (PEFRelocField ( (chunk), 7, 9 ) + 1)
  653. #define PEFRelocComposeRun(subopcode,runLength) \
  654. ( 0x4000 | (((UInt16)(subopcode)) << 9) | ((UInt16)((runLength)-1)) )
  655. #define PEFRelocComposeBySectC(runLength) PEFRelocComposeRun ( 0, (runLength) )
  656. #define PEFRelocComposeBySectD(runLength) PEFRelocComposeRun ( 1, (runLength) )
  657. #define PEFRelocComposeTVector12(runLength) PEFRelocComposeRun ( 2, (runLength) )
  658. #define PEFRelocComposeTVector8(runLength) PEFRelocComposeRun ( 3, (runLength) )
  659. #define PEFRelocComposeVTable8(runLength) PEFRelocComposeRun ( 4, (runLength) )
  660. #define PEFRelocComposeImportRun(runLength) PEFRelocComposeRun ( 5, (runLength) )
  661. /* =========================================================================================== */
  662. /* RelocSmIndex Group (SYMB, CDIS, DTIS, SECN) */
  663. /* ------------------------------------------- */
  664. /* -------------------------------------------------------------------------------------------- */
  665. /* The "RelocSmIndex" group includes the "RelocSmByImport" (SYMB), "RelocSmSetSectC" (CDIS), */
  666. /* "RelocSmSetSectD" (DTIS) and "RelocSmBySection" (SECN) instructions. This group has the */
  667. /* following bit field layout. */
  668. /* */
  669. /* 1 */
  670. /* 0 2 3 6 7 5 */
  671. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  672. /* |0 1 1| subop.| index | */
  673. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  674. /* | 3 |<- 4 ->|<-- 9 bits ----->| */
  675. /* */
  676. /* ! Note that the stored index is the actual value! */
  677. enum {
  678. kPEFRelocSmIndexMaxIndex = 511
  679. };
  680. #define PEFRelocSmIndexSubopcode(chunk) PEFRelocField ( (chunk), 3, 4 )
  681. #define PEFRelocSmIndexIndex(chunk) PEFRelocField ( (chunk), 7, 9 )
  682. #define PEFRelocComposeSmIndex(subopcode,index) \
  683. ( 0x6000 | (((UInt16)(subopcode)) << 9) | ((UInt16)(index)) )
  684. #define PEFRelocComposeSmByImport(index) PEFRelocComposeSmIndex ( 0, (index) )
  685. #define PEFRelocComposeSmSetSectC(index) PEFRelocComposeSmIndex ( 1, (index) )
  686. #define PEFRelocComposeSmSetSectD(index) PEFRelocComposeSmIndex ( 2, (index) )
  687. #define PEFRelocComposeSmBySection(index) PEFRelocComposeSmIndex ( 3, (index) )
  688. /* =========================================================================================== */
  689. /* RelocIncrPosition Instruction (DELT) */
  690. /* ------------------------------------ */
  691. /* -------------------------------------------------------------------------------------------- */
  692. /* The "RelocIncrPosition" (DELT) instruction has the following bit field layout. */
  693. /* */
  694. /* 1 */
  695. /* 0 3 4 5 */
  696. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  697. /* |1 0 0 0| offset | */
  698. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  699. /* |<- 4 ->|<-- 12 bits ---------->| */
  700. /* */
  701. /* ! Note that the stored offset is the actual value minus 1, but the macros deal with the */
  702. /* ! actual value! */
  703. enum {
  704. kPEFRelocIncrPositionMaxOffset = 4096
  705. };
  706. #define PEFRelocIncrPositionOffset(chunk) (PEFRelocField ( (chunk), 4, 12 ) + 1)
  707. #define PEFRelocComposeIncrPosition(offset) \
  708. ( 0x8000 | ((UInt16)((offset)-1)) )
  709. /* =========================================================================================== */
  710. /* RelocSmRepeat Instruction (RPT) */
  711. /* ------------------------------- */
  712. /* -------------------------------------------------------------------------------------------- */
  713. /* The "RelocSmRepeat" (RPT) instruction has the following bit field layout. */
  714. /* */
  715. /* 1 */
  716. /* 0 3 4 7 8 5 */
  717. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  718. /* |1 0 0 1| chnks | repeat count | */
  719. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  720. /* |<- 4 ->|<- 4 ->|<-- 8 bits --->| */
  721. /* */
  722. /* ! Note that the stored chunk count and repeat count are the actual values minus 1, but the */
  723. /* ! macros deal with the actual values! */
  724. enum {
  725. kPEFRelocSmRepeatMaxChunkCount = 16,
  726. kPEFRelocSmRepeatMaxRepeatCount = 256
  727. };
  728. #define PEFRelocSmRepeatChunkCount(chunk) (PEFRelocField ( (chunk), 4, 4 ) + 1)
  729. #define PEFRelocSmRepeatRepeatCount(chunk) (PEFRelocField ( (chunk), 8, 8 ) + 1)
  730. #define PEFRelocComposeSmRepeat(chunkCount,repeatCount) \
  731. ( 0x9000 | ((((UInt16)(chunkCount))-1) << 8) | (((UInt16)(repeatCount))-1) )
  732. /* =========================================================================================== */
  733. /* RelocSetPosition Instruction (LABS) */
  734. /* ----------------------------------- */
  735. /* -------------------------------------------------------------------------------------------- */
  736. /* The "RelocSetPosition" (LABS) instruction has the following bit field layout. */
  737. /* */
  738. /* 1 1 */
  739. /* 0 5 6 5 0 5 */
  740. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  741. /* |1 0 1 0 0 0| offset (high) | | offset (low) | */
  742. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  743. /* |<-- 6 ---->|<-- 10 bits ------>| |<-- 16 bits ------------------>| */
  744. /* */
  745. /* ! Note that the stored offset is the actual value! */
  746. enum {
  747. kPEFRelocSetPosMaxOffset = 0x03FFFFFF /* 67,108,863*/
  748. };
  749. #define PEFRelocSetPosOffsetHigh(chunk) PEFRelocField ( (chunk), 6, 10 )
  750. #define PEFRelocSetPosFullOffset(firstChunk,secondChunk) \
  751. ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  752. #define PEFRelocComposeSetPosition_1st(fullOffset) \
  753. ( 0xA000 | ((UInt16) (((UInt32)(fullOffset)) >> 16) ) )
  754. #define PEFRelocComposeSetPosition_2nd(fullOffset) \
  755. ( (UInt16) ((UInt32)(fullOffset) & 0xFFFF) )
  756. /* =========================================================================================== */
  757. /* RelocLgByImport Instruction (LSYM) */
  758. /* ---------------------------------- */
  759. /* -------------------------------------------------------------------------------------------- */
  760. /* The "RelocLgByImport" (LSYM) instruction has the following bit field layout. */
  761. /* */
  762. /* 1 1 */
  763. /* 0 5 6 5 0 5 */
  764. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  765. /* |1 0 1 0 0 1| index (high) | | index (low) | */
  766. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  767. /* |<-- 6 ---->|<-- 10 bits ------>| |<-- 16 bits ------------------>| */
  768. /* */
  769. /* ! Note that the stored offset is the actual value! */
  770. enum {
  771. kPEFRelocLgByImportMaxIndex = 0x03FFFFFF /* 67,108,863*/
  772. };
  773. #define PEFRelocLgByImportIndexHigh(chunk) PEFRelocField ( (chunk), 6, 10 )
  774. #define PEFRelocLgByImportFullIndex(firstChunk,secondChunk) \
  775. ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  776. #define PEFRelocComposeLgByImport_1st(fullIndex) \
  777. ( 0xA400 | ((UInt16) (((UInt32)(fullIndex)) >> 16) ) )
  778. #define PEFRelocComposeLgByImport_2nd(fullIndex) \
  779. ( (UInt16) ((UInt32)(fullIndex) & 0xFFFF) )
  780. /* =========================================================================================== */
  781. /* RelocLgRepeat Instruction (LRPT) */
  782. /* -------------------------------- */
  783. /* -------------------------------------------------------------------------------------------- */
  784. /* The "RelocLgRepeat" (LRPT) instruction has the following bit field layout. */
  785. /* */
  786. /* 1 1 1 */
  787. /* 0 5 6 9 0 5 0 5 */
  788. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  789. /* |1 0 1 1 0 0| chnks | rpt (high)| | repeat count (low) | */
  790. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  791. /* |<-- 6 --->|<- 4 ->|<-- 6 --->| |<-- 16 bits ------------------>| */
  792. /* */
  793. /* ! Note that the stored chunk count is the actual value minus 1, but the macros deal with */
  794. /* ! the actual value! The stored repeat count is the actual value! */
  795. enum {
  796. kPEFRelocLgRepeatMaxChunkCount = 16,
  797. kPEFRelocLgRepeatMaxRepeatCount = 0x003FFFFF /* 4,194,303*/
  798. };
  799. #define PEFRelocLgRepeatChunkCount(chunk) (PEFRelocField ( (chunk), 6, 4 ) + 1)
  800. #define PEFRelocLgRepeatRepeatCountHigh(chunk) PEFRelocField ( (chunk), 10, 6 )
  801. #define PEFRelocLgRepeatFullRepeatCount(firstChunk,secondChunk) \
  802. ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  803. #define PEFRelocComposeLgRepeat_1st(chunkCount,fullRepeatCount) \
  804. ( 0xB000 | ((((UInt16)(chunkCount))-1) << 6) | ((UInt16) (((UInt32)(fullRepeatCount)) >>16 ) ) )
  805. #define PEFRelocComposeLgRepeat_2nd(chunkCount,fullRepeatCount) \
  806. ( (UInt16) ((UInt32)(fullRepeatCount) & 0xFFFF) )
  807. /* =========================================================================================== */
  808. /* RelocLgSetOrBySection Group (LSEC) */
  809. /* ---------------------------------- */
  810. /* -------------------------------------------------------------------------------------------- */
  811. /* The "RelocLgSetOrBySection" (LSEC) instruction is a group including the "RelocLgBySection", */
  812. /* "RelocLgSetSectC" and "RelocLgSetSectD" instructions. This group has the following bit */
  813. /* field layout. */
  814. /* */
  815. /* 1 1 1 */
  816. /* 0 5 6 9 0 5 0 5 */
  817. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  818. /* |1 0 1 1 0 1| subop | idx (high)| | index (low) | */
  819. /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
  820. /* |<-- 6 --->|<- 4 ->|<-- 6 --->| |<-- 16 bits ------------------>| */
  821. /* */
  822. /* ! Note that the stored index is the actual value! */
  823. enum {
  824. kPEFRelocLgSetOrBySectionMaxIndex = 0x003FFFFF /* 4,194,303*/
  825. };
  826. #define PEFRelocLgSetOrBySectionSubopcode(chunk) PEFRelocField ( (chunk), 6, 4 )
  827. #define PEFRelocLgSetOrBySectionIndexHigh(chunk) PEFRelocField ( (chunk), 10, 6 )
  828. #define PEFRelocLgSetOrBySectionFullIndex(firstChunk,secondChunk) \
  829. ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  830. #define PEFRelocComposeLgSetOrBySection_1st(subopcode,fullIndex) \
  831. ( 0xB400 | (((UInt16)(subopcode)) << 6) | ((UInt16) (((UInt32)(fullIndex)) >> 16) ) )
  832. #define PEFRelocComposeLgSetOrBySection_2nd(subopcode,fullIndex) \
  833. ( (UInt16) ((UInt32)(fullIndex) & 0xFFFF) )
  834. #define PEFRelocComposeLgBySection(fullIndex) PEFRelocComposeLgSetOrBySection ( 0x00, (fullIndex) )
  835. #define PEFRelocComposeLgSetSectC(fullIndex) PEFRelocComposeLgSetOrBySection ( 0x01, (fullIndex) )
  836. #define PEFRelocComposeLgSetSectD(fullIndex) PEFRelocComposeLgSetOrBySection ( 0x02, (fullIndex) )
  837. #if PRAGMA_STRUCT_ALIGN
  838. #pragma options align=reset
  839. #elif PRAGMA_STRUCT_PACKPUSH
  840. #pragma pack(pop)
  841. #elif PRAGMA_STRUCT_PACK
  842. #pragma pack()
  843. #endif
  844. #ifdef PRAGMA_IMPORT_OFF
  845. #pragma import off
  846. #elif PRAGMA_IMPORT
  847. #pragma import reset
  848. #endif
  849. #endif /* __PEFBINARYFORMAT__ */