PEFBinaryFormat.h
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:69k
源码类别:

多媒体编程

开发平台:

Visual C++

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