PEFBinaryFormat.pas 90 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602
  1. {
  2. File: CarbonCore/PEFBinaryFormat.h
  3. Contains: PEF Types and Macros
  4. The contents of this header file are deprecated.
  5. Copyright: © 1993-2011 by Apple Inc. All rights reserved.
  6. }
  7. {
  8. Modified for use with Free Pascal
  9. Version 308
  10. Please report any bugs to <[email protected]>
  11. }
  12. {$ifc not defined MACOSALLINCLUDE or not MACOSALLINCLUDE}
  13. {$mode macpas}
  14. {$modeswitch cblocks}
  15. {$packenum 1}
  16. {$macro on}
  17. {$inline on}
  18. {$calling mwpascal}
  19. {$IFNDEF FPC_DOTTEDUNITS}
  20. unit PEFBinaryFormat;
  21. {$ENDIF FPC_DOTTEDUNITS}
  22. interface
  23. {$setc UNIVERSAL_INTERFACES_VERSION := $0400}
  24. {$setc GAP_INTERFACES_VERSION := $0308}
  25. {$ifc not defined USE_CFSTR_CONSTANT_MACROS}
  26. {$setc USE_CFSTR_CONSTANT_MACROS := TRUE}
  27. {$endc}
  28. {$ifc defined CPUPOWERPC and defined CPUI386}
  29. {$error Conflicting initial definitions for CPUPOWERPC and CPUI386}
  30. {$endc}
  31. {$ifc defined FPC_BIG_ENDIAN and defined FPC_LITTLE_ENDIAN}
  32. {$error Conflicting initial definitions for FPC_BIG_ENDIAN and FPC_LITTLE_ENDIAN}
  33. {$endc}
  34. {$ifc not defined __ppc__ and defined CPUPOWERPC32}
  35. {$setc __ppc__ := 1}
  36. {$elsec}
  37. {$setc __ppc__ := 0}
  38. {$endc}
  39. {$ifc not defined __ppc64__ and defined CPUPOWERPC64}
  40. {$setc __ppc64__ := 1}
  41. {$elsec}
  42. {$setc __ppc64__ := 0}
  43. {$endc}
  44. {$ifc not defined __i386__ and defined CPUI386}
  45. {$setc __i386__ := 1}
  46. {$elsec}
  47. {$setc __i386__ := 0}
  48. {$endc}
  49. {$ifc not defined __x86_64__ and defined CPUX86_64}
  50. {$setc __x86_64__ := 1}
  51. {$elsec}
  52. {$setc __x86_64__ := 0}
  53. {$endc}
  54. {$ifc not defined __arm__ and defined CPUARM}
  55. {$setc __arm__ := 1}
  56. {$elsec}
  57. {$setc __arm__ := 0}
  58. {$endc}
  59. {$ifc not defined __arm64__ and defined CPUAARCH64}
  60. {$setc __arm64__ := 1}
  61. {$elsec}
  62. {$setc __arm64__ := 0}
  63. {$endc}
  64. {$ifc defined cpu64}
  65. {$setc __LP64__ := 1}
  66. {$elsec}
  67. {$setc __LP64__ := 0}
  68. {$endc}
  69. {$ifc defined __ppc__ and __ppc__ and defined __i386__ and __i386__}
  70. {$error Conflicting definitions for __ppc__ and __i386__}
  71. {$endc}
  72. {$ifc defined __ppc__ and __ppc__}
  73. {$setc TARGET_CPU_PPC := TRUE}
  74. {$setc TARGET_CPU_PPC64 := FALSE}
  75. {$setc TARGET_CPU_X86 := FALSE}
  76. {$setc TARGET_CPU_X86_64 := FALSE}
  77. {$setc TARGET_CPU_ARM := FALSE}
  78. {$setc TARGET_CPU_ARM64 := FALSE}
  79. {$setc TARGET_OS_MAC := TRUE}
  80. {$setc TARGET_OS_IPHONE := FALSE}
  81. {$setc TARGET_IPHONE_SIMULATOR := FALSE}
  82. {$setc TARGET_OS_EMBEDDED := FALSE}
  83. {$elifc defined __ppc64__ and __ppc64__}
  84. {$setc TARGET_CPU_PPC := FALSE}
  85. {$setc TARGET_CPU_PPC64 := TRUE}
  86. {$setc TARGET_CPU_X86 := FALSE}
  87. {$setc TARGET_CPU_X86_64 := FALSE}
  88. {$setc TARGET_CPU_ARM := FALSE}
  89. {$setc TARGET_CPU_ARM64 := FALSE}
  90. {$setc TARGET_OS_MAC := TRUE}
  91. {$setc TARGET_OS_IPHONE := FALSE}
  92. {$setc TARGET_IPHONE_SIMULATOR := FALSE}
  93. {$setc TARGET_OS_EMBEDDED := FALSE}
  94. {$elifc defined __i386__ and __i386__}
  95. {$setc TARGET_CPU_PPC := FALSE}
  96. {$setc TARGET_CPU_PPC64 := FALSE}
  97. {$setc TARGET_CPU_X86 := TRUE}
  98. {$setc TARGET_CPU_X86_64 := FALSE}
  99. {$setc TARGET_CPU_ARM := FALSE}
  100. {$setc TARGET_CPU_ARM64 := FALSE}
  101. {$ifc defined iphonesim}
  102. {$setc TARGET_OS_MAC := FALSE}
  103. {$setc TARGET_OS_IPHONE := TRUE}
  104. {$setc TARGET_IPHONE_SIMULATOR := TRUE}
  105. {$elsec}
  106. {$setc TARGET_OS_MAC := TRUE}
  107. {$setc TARGET_OS_IPHONE := FALSE}
  108. {$setc TARGET_IPHONE_SIMULATOR := FALSE}
  109. {$endc}
  110. {$setc TARGET_OS_EMBEDDED := FALSE}
  111. {$elifc defined __x86_64__ and __x86_64__}
  112. {$setc TARGET_CPU_PPC := FALSE}
  113. {$setc TARGET_CPU_PPC64 := FALSE}
  114. {$setc TARGET_CPU_X86 := FALSE}
  115. {$setc TARGET_CPU_X86_64 := TRUE}
  116. {$setc TARGET_CPU_ARM := FALSE}
  117. {$setc TARGET_CPU_ARM64 := FALSE}
  118. {$ifc defined iphonesim}
  119. {$setc TARGET_OS_MAC := FALSE}
  120. {$setc TARGET_OS_IPHONE := TRUE}
  121. {$setc TARGET_IPHONE_SIMULATOR := TRUE}
  122. {$elsec}
  123. {$setc TARGET_OS_MAC := TRUE}
  124. {$setc TARGET_OS_IPHONE := FALSE}
  125. {$setc TARGET_IPHONE_SIMULATOR := FALSE}
  126. {$endc}
  127. {$setc TARGET_OS_EMBEDDED := FALSE}
  128. {$elifc defined __arm__ and __arm__}
  129. {$setc TARGET_CPU_PPC := FALSE}
  130. {$setc TARGET_CPU_PPC64 := FALSE}
  131. {$setc TARGET_CPU_X86 := FALSE}
  132. {$setc TARGET_CPU_X86_64 := FALSE}
  133. {$setc TARGET_CPU_ARM := TRUE}
  134. {$setc TARGET_CPU_ARM64 := FALSE}
  135. {$setc TARGET_OS_MAC := FALSE}
  136. {$setc TARGET_OS_IPHONE := TRUE}
  137. {$setc TARGET_IPHONE_SIMULATOR := FALSE}
  138. {$setc TARGET_OS_EMBEDDED := TRUE}
  139. {$elifc defined __arm64__ and __arm64__}
  140. {$setc TARGET_CPU_PPC := FALSE}
  141. {$setc TARGET_CPU_PPC64 := FALSE}
  142. {$setc TARGET_CPU_X86 := FALSE}
  143. {$setc TARGET_CPU_X86_64 := FALSE}
  144. {$setc TARGET_CPU_ARM := FALSE}
  145. {$setc TARGET_CPU_ARM64 := TRUE}
  146. {$ifc defined ios}
  147. {$setc TARGET_OS_MAC := FALSE}
  148. {$setc TARGET_OS_IPHONE := TRUE}
  149. {$setc TARGET_OS_EMBEDDED := TRUE}
  150. {$elsec}
  151. {$setc TARGET_OS_MAC := TRUE}
  152. {$setc TARGET_OS_IPHONE := FALSE}
  153. {$setc TARGET_OS_EMBEDDED := FALSE}
  154. {$endc}
  155. {$setc TARGET_IPHONE_SIMULATOR := FALSE}
  156. {$elsec}
  157. {$error __ppc__ nor __ppc64__ nor __i386__ nor __x86_64__ nor __arm__ nor __arm64__ is defined.}
  158. {$endc}
  159. {$ifc defined __LP64__ and __LP64__ }
  160. {$setc TARGET_CPU_64 := TRUE}
  161. {$elsec}
  162. {$setc TARGET_CPU_64 := FALSE}
  163. {$endc}
  164. {$ifc defined FPC_BIG_ENDIAN}
  165. {$setc TARGET_RT_BIG_ENDIAN := TRUE}
  166. {$setc TARGET_RT_LITTLE_ENDIAN := FALSE}
  167. {$elifc defined FPC_LITTLE_ENDIAN}
  168. {$setc TARGET_RT_BIG_ENDIAN := FALSE}
  169. {$setc TARGET_RT_LITTLE_ENDIAN := TRUE}
  170. {$elsec}
  171. {$error Neither FPC_BIG_ENDIAN nor FPC_LITTLE_ENDIAN are defined.}
  172. {$endc}
  173. {$setc ACCESSOR_CALLS_ARE_FUNCTIONS := TRUE}
  174. {$setc CALL_NOT_IN_CARBON := FALSE}
  175. {$setc OLDROUTINENAMES := FALSE}
  176. {$setc OPAQUE_TOOLBOX_STRUCTS := TRUE}
  177. {$setc OPAQUE_UPP_TYPES := TRUE}
  178. {$setc OTCARBONAPPLICATION := TRUE}
  179. {$setc OTKERNEL := FALSE}
  180. {$setc PM_USE_SESSION_APIS := TRUE}
  181. {$setc TARGET_API_MAC_CARBON := TRUE}
  182. {$setc TARGET_API_MAC_OS8 := FALSE}
  183. {$setc TARGET_API_MAC_OSX := TRUE}
  184. {$setc TARGET_CARBON := TRUE}
  185. {$setc TARGET_CPU_68K := FALSE}
  186. {$setc TARGET_CPU_MIPS := FALSE}
  187. {$setc TARGET_CPU_SPARC := FALSE}
  188. {$setc TARGET_OS_UNIX := FALSE}
  189. {$setc TARGET_OS_WIN32 := FALSE}
  190. {$setc TARGET_RT_MAC_68881 := FALSE}
  191. {$setc TARGET_RT_MAC_CFM := FALSE}
  192. {$setc TARGET_RT_MAC_MACHO := TRUE}
  193. {$setc TYPED_FUNCTION_POINTERS := TRUE}
  194. {$setc TYPE_BOOL := FALSE}
  195. {$setc TYPE_EXTENDED := FALSE}
  196. {$setc TYPE_LONGLONG := TRUE}
  197. {$IFDEF FPC_DOTTEDUNITS}
  198. uses MacOsApi.MacTypes;
  199. {$ELSE FPC_DOTTEDUNITS}
  200. uses MacTypes;
  201. {$ENDIF FPC_DOTTEDUNITS}
  202. {$endc} {not MACOSALLINCLUDE}
  203. {$ifc TARGET_OS_MAC}
  204. {$ALIGN MAC68K}
  205. { -------------------------------------------------------------------------------------------- }
  206. { Almost all types are padded for natural alignment. However the PEFExportedSymbol type is }
  207. { 10 bytes long, containing two 32 bit fields and one 16 bit field. Arrays of it must be }
  208. { packed, so it requires "68K" alignment. Setting this globally to 68K should also help }
  209. { ensure consistent treatment across compilers. }
  210. { ======================================================================================== }
  211. { Overall Structure }
  212. { ================= }
  213. { -------------------------------------------------------------------------------------------- }
  214. { This header contains a complete set of types and macros for dealing with the PEF executable }
  215. { format. While some description is provided, this header is not meant as a primary source }
  216. { of documentation on PEF. An excellent specification of PEF can be found in the Macintosh }
  217. { Runtime Architectures book. This header is primarily a physical format description. Thus }
  218. { it depends on as few other headers as possible and structure fields have obvious sizes. }
  219. { The physical storage for a PEF executable is known as a "container". This refers to just }
  220. { the executable itself, not the file etc. E.g. if five DLLs are packaged in a single file's }
  221. { data fork, that one data fork has five containers within it. }
  222. { A PEF container consists of an overall header, followed by one or more section headers, }
  223. { followed by the section name table, followed by the contents for the sections. Some kinds }
  224. { of sections have specific internal representation. The "loader" section is the most common }
  225. { of these special sections. It contains information on the exports, imports, and runtime }
  226. { relocations required to prepare the executable. PEF containers are self contained, all }
  227. { portions are located via relative offsets. }
  228. { +-------------------------------+ }
  229. { | Container Header | 40 bytes }
  230. { +-------------------------------+ }
  231. { | Section 0 header | 28 bytes each }
  232. { |...............................| }
  233. { | - - - - | }
  234. { |...............................| }
  235. { | Section n-1 header | }
  236. { +-------------------------------+ }
  237. { | Section Name Table | }
  238. { +-------------------------------+ }
  239. { | Section x raw data | }
  240. { +-------------------------------+ }
  241. { | - - - - | }
  242. { +-------------------------------+ }
  243. { | Section y raw data | }
  244. { +-------------------------------+ }
  245. { The sections are implicitly numbered from 0 to n according to the order of their headers. }
  246. { The headers of the instantiated sections must precede those of the non-instantiated }
  247. { sections. The ordering of the raw data is independent of the section header ordering. }
  248. { Each section header contains the offset for that section's raw data. }
  249. { =========================================================================================== }
  250. { Container Header }
  251. { ================ }
  252. type
  253. PEFContainerHeaderPtr = ^PEFContainerHeader;
  254. PEFContainerHeader = record
  255. tag1: OSType; { Must contain 'Joy!'.}
  256. tag2: OSType; { Must contain 'peff'. (Yes, with two 'f's.)}
  257. architecture: OSType; { The ISA for code sections. Constants in CodeFragments.h.}
  258. formatVersion: UInt32; { The physical format version.}
  259. dateTimeStamp: UInt32; { Macintosh format creation/modification stamp.}
  260. oldDefVersion: UInt32; { Old definition version number for the code fragment.}
  261. oldImpVersion: UInt32; { Old implementation version number for the code fragment.}
  262. currentVersion: UInt32; { Current version number for the code fragment.}
  263. sectionCount: UInt16; { Total number of section headers that follow.}
  264. instSectionCount: UInt16; { Number of instantiated sections.}
  265. reservedA: UInt32; { Reserved, must be written as zero.}
  266. end;
  267. const
  268. kPEFTag1 = FourCharCode('Joy!'); { For non-Apple compilers: 0x4A6F7921.}
  269. kPEFTag2 = FourCharCode('peff'); { For non-Apple compilers: 0x70656666.}
  270. kPEFVersion = $00000001;
  271. const
  272. kPEFFirstSectionHeaderOffset = SizeOf(PEFContainerHeader);
  273. (*
  274. #define PEFFirstSectionNameOffset(container) \
  275. ( kPEFFirstSectionHeaderOffset + ((container)->sectionCount * sizeof ( PEFSectionHeader )) )
  276. *)
  277. { =========================================================================================== }
  278. { Section Headers }
  279. { =============== }
  280. type
  281. PEFSectionHeaderPtr = ^PEFSectionHeader;
  282. PEFSectionHeader = record
  283. nameOffset: SInt32; { Offset of name within the section name table, -1 => none.}
  284. defaultAddress: UInt32; { Default address, affects relocations.}
  285. totalLength: UInt32; { Fully expanded size in bytes of the section contents.}
  286. unpackedLength: UInt32; { Size in bytes of the "initialized" part of the contents.}
  287. containerLength: UInt32; { Size in bytes of the raw data in the container.}
  288. containerOffset: UInt32; { Offset of section's raw data.}
  289. sectionKind: UInt8; { Kind of section contents/usage.}
  290. shareKind: UInt8; { Sharing level, if a writeable section.}
  291. alignment: UInt8; { Preferred alignment, expressed as log 2.}
  292. reservedA: UInt8; { Reserved, must be zero.}
  293. end;
  294. const
  295. { Values for the sectionKind field.}
  296. { Section kind values for instantiated sections.}
  297. kPEFCodeSection = 0; { Code, presumed pure & position independent.}
  298. kPEFUnpackedDataSection = 1; { Unpacked writeable data.}
  299. kPEFPackedDataSection = 2; { Packed writeable data.}
  300. kPEFConstantSection = 3; { Read-only data.}
  301. kPEFExecDataSection = 6; { Intermixed code and writeable data.}
  302. { Section kind values for non-instantiated sections.}
  303. kPEFLoaderSection = 4; { Loader tables.}
  304. kPEFDebugSection = 5; { Reserved for future use.}
  305. kPEFExceptionSection = 7; { Reserved for future use.}
  306. kPEFTracebackSection = 8; { Reserved for future use.}
  307. const
  308. { Values for the shareKind field.}
  309. kPEFProcessShare = 1; { Shared within a single process.}
  310. kPEFGlobalShare = 4; { Shared across the entire system.}
  311. kPEFProtectedShare = 5; { Readable across the entire system, writeable only to privileged code.}
  312. { =========================================================================================== }
  313. { Packed Data Contents }
  314. { ==================== }
  315. { -------------------------------------------------------------------------------------------- }
  316. { The raw contents of a packed data section are a sequence of byte codes. The basic format }
  317. { has a 3 bit opcode followed by a 5 bit count. Additional bytes might be used to contain }
  318. { counts larger than 31, and to contain a second or third count. Further additional bytes }
  319. { contain actual data values to transfer. }
  320. { All counts are represented in a variable length manner. A zero in the initial 5 bit count }
  321. { indicates the actual value follows. In this case, and for the second and third counts, the }
  322. { count is represented as a variable length sequence of bytes. The bytes are stored in big }
  323. { endian manner, most significant part first. The high order bit is set in all but the last }
  324. { byte. The value is accumulated by shifting the current value up 7 bits and adding in the }
  325. { low order 7 bits of the next byte. }
  326. const
  327. { The packed data opcodes.}
  328. kPEFPkDataZero = 0; { Zero fill "count" bytes.}
  329. kPEFPkDataBlock = 1; { Block copy "count" bytes.}
  330. kPEFPkDataRepeat = 2; { Repeat "count" bytes "count2"+1 times.}
  331. kPEFPkDataRepeatBlock = 3; { Interleaved repeated and unique data.}
  332. kPEFPkDataRepeatZero = 4; { Interleaved zero and unique data.}
  333. const
  334. kPEFPkDataOpcodeShift = 5;
  335. kPEFPkDataCount5Mask = $1F;
  336. kPEFPkDataMaxCount5 = 31;
  337. kPEFPkDataVCountShift = 7;
  338. kPEFPkDataVCountMask = $7F;
  339. kPEFPkDataVCountEndMask = $80;
  340. (*
  341. #define PEFPkDataOpcode(byte) ( ((UInt8)(byte)) >> kPEFPkDataOpcodeShift )
  342. #define PEFPkDataCount5(byte) ( ((UInt8)(byte)) & kPEFPkDataCount5Mask )
  343. #define PEFPkDataComposeInstr(opcode,count5) \
  344. ( (((UInt8)(opcode)) << kPEFPkDataOpcodeShift) | ((UInt8)(count5)) )
  345. *)
  346. { -------------------------------------------------------------------------------------------- }
  347. { The following code snippet can be used to input a variable length count. }
  348. { count = 0; }
  349. { do ( }
  350. { byte = *bytePtr++; }
  351. { count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask); }
  352. { ) while ( (byte & kPEFPkDataVCountEndMask) != 0 ); }
  353. { The following code snippet can be used to output a variable length count to a byte array. }
  354. { This is more complex than the input code because the chunks are output in big endian order. }
  355. { Think about handling values like 0 or 0x030000. }
  356. { count = 1;. }
  357. { tempValue = value >> kPEFPkDataCountShift; }
  358. { while ( tempValue != 0 ) ( }
  359. { count += 1; }
  360. { tempValue = tempValue >> kPEFPkDataCountShift; }
  361. { ) }
  362. { bytePtr += count; }
  363. { tempPtr = bytePtr - 1; }
  364. { *tempPtr-- = value; // ! No need to mask, only the low order byte is stored. }
  365. { for ( count -= 1; count != 0; count -= 1 ) ( }
  366. { value = value >> kPEFPkDataCountShift; }
  367. { *tempPtr-- = value | kPEFPkDataCountEndMask; }
  368. { ) }
  369. { =========================================================================================== }
  370. { Loader Section }
  371. { ============== }
  372. { -------------------------------------------------------------------------------------------- }
  373. { The loader section contains information needed to prepare the code fragment for execution. }
  374. { This includes this fragment's exports, the import libraries and the imported symbols from }
  375. { each library, and the relocations for the writeable sections. }
  376. { +-----------------------------------+ <-- containerOffset --------+ }
  377. { | Loader Info Header | 56 bytes | }
  378. { |-----------------------------------| | }
  379. { | Imported Library 0 | 24 bytes each | }
  380. { |...................................| | }
  381. { | - - - | | }
  382. { |...................................| | }
  383. { | Imported Library l-1 | | }
  384. { |-----------------------------------| | }
  385. { | Imported Symbol 0 | 4 bytes each | }
  386. { |...................................| | }
  387. { | - - - | | }
  388. { |...................................| | }
  389. { | Imported Symbol i-1 | | }
  390. { |-----------------------------------| | }
  391. { | Relocation Header 0 | 12 bytes each | }
  392. { |...................................| | }
  393. { | - - - | | }
  394. { |...................................| | }
  395. { | Relocation Header r-1 | | }
  396. { |-----------------------------------| <-- + relocInstrOffset -----| }
  397. { | Relocation Instructions | | }
  398. { |-----------------------------------| <-- + loaderStringsOffset --| }
  399. { | Loader String Table | | }
  400. { |-----------------------------------| <-- + exportHashOffset -----+ }
  401. { | Export Hash Slot 0 | 4 bytes each }
  402. { |...................................| }
  403. { | - - - | }
  404. { |...................................| }
  405. { | Export Hash Slot h-1 | }
  406. { |-----------------------------------| }
  407. { | Export Symbol Key 0 | 4 bytes each }
  408. { |...................................| }
  409. { | - - - | }
  410. { |...................................| }
  411. { | Export Symbol Key e-1 | }
  412. { |-----------------------------------| }
  413. { | Export Symbol 0 | 10 bytes each }
  414. { |...................................| }
  415. { | - - - | }
  416. { |...................................| }
  417. { | Export Symbol e-1 | }
  418. { +-----------------------------------+ }
  419. type
  420. PEFLoaderInfoHeaderPtr = ^PEFLoaderInfoHeader;
  421. PEFLoaderInfoHeader = record
  422. mainSection: SInt32; { Section containing the main symbol, -1 => none.}
  423. mainOffset: UInt32; { Offset of main symbol.}
  424. initSection: SInt32; { Section containing the init routine's TVector, -1 => none.}
  425. initOffset: UInt32; { Offset of the init routine's TVector.}
  426. termSection: SInt32; { Section containing the term routine's TVector, -1 => none.}
  427. termOffset: UInt32; { Offset of the term routine's TVector.}
  428. importedLibraryCount: UInt32; { Number of imported libraries. ('l')}
  429. totalImportedSymbolCount: UInt32; { Total number of imported symbols. ('i')}
  430. relocSectionCount: UInt32; { Number of sections with relocations. ('r')}
  431. relocInstrOffset: UInt32; { Offset of the relocation instructions.}
  432. loaderStringsOffset: UInt32; { Offset of the loader string table.}
  433. exportHashOffset: UInt32; { Offset of the export hash table.}
  434. exportHashTablePower: UInt32; { Export hash table size as log 2. (Log2('h'))}
  435. exportedSymbolCount: UInt32; { Number of exported symbols. ('e')}
  436. end;
  437. { =========================================================================================== }
  438. { Imported Libraries }
  439. { ------------------ }
  440. type
  441. PEFImportedLibraryPtr = ^PEFImportedLibrary;
  442. PEFImportedLibrary = record
  443. nameOffset: UInt32; { Loader string table offset of library's name.}
  444. oldImpVersion: UInt32; { Oldest compatible implementation version.}
  445. currentVersion: UInt32; { Current version at build time.}
  446. importedSymbolCount: UInt32; { Imported symbol count for this library.}
  447. firstImportedSymbol: UInt32; { Index of first imported symbol from this library.}
  448. options: UInt8; { Option bits for this library.}
  449. reservedA: UInt8; { Reserved, must be zero.}
  450. reservedB: UInt16; { Reserved, must be zero.}
  451. end;
  452. const
  453. { Bits for the PEFImportedLibrary options field.}
  454. kPEFWeakImportLibMask = $40; { The imported library is allowed to be missing.}
  455. kPEFInitLibBeforeMask = $80; { The imported library must be initialized first.}
  456. { =========================================================================================== }
  457. { Imported Symbols }
  458. { ---------------- }
  459. { -------------------------------------------------------------------------------------------- }
  460. { The PEFImportedSymbol type has the following bit field layout. }
  461. { 3 }
  462. { 0 7 8 1 }
  463. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  464. { | symbol class | offset of symbol name in loader string table | }
  465. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  466. { |<-- 8 bits --->|<-- 24 bits ---------------------------------->| }
  467. type
  468. PEFImportedSymbolPtr = ^PEFImportedSymbol;
  469. PEFImportedSymbol = record
  470. classAndName: UInt32;
  471. end;
  472. const
  473. kPEFImpSymClassShift = 24;
  474. kPEFImpSymNameOffsetMask = $00FFFFFF;
  475. kPEFImpSymMaxNameOffset = $00FFFFFF; { 16,777,215}
  476. const
  477. { Imported and exported symbol classes.}
  478. kPEFCodeSymbol = $00;
  479. kPEFDataSymbol = $01;
  480. kPEFTVectorSymbol = $02;
  481. kPEFTOCSymbol = $03;
  482. kPEFGlueSymbol = $04;
  483. kPEFUndefinedSymbol = $0F;
  484. kPEFWeakImportSymMask = $80;
  485. { =========================================================================================== }
  486. { Exported Symbol Hash Table }
  487. { -------------------------- }
  488. { -------------------------------------------------------------------------------------------- }
  489. { Exported symbols are described in four parts, optimized for speed of lookup. These parts }
  490. { are the "export hash table", the "export key table", the "export symbol table", and the }
  491. { "export name table". Overall they contain a flattened representation of a fairly normal }
  492. { hashed symbol table. }
  493. { The export hash table is an array of small fixed size elements. The number of elements is }
  494. { a power of 2. A 32 bit hash word for a symbol is converted into an index into this array. }
  495. { Each hash slot contains a count of the number of exported symbols that map to this slot and }
  496. { the index of the first of those symbols in the key and symbol tables. Of course some hash }
  497. { slots will have a zero count. }
  498. { The key and symbol tables are also arrays of fixed size elements, one for each exported }
  499. { symbol. Their entries are grouped by hash slot, those elements mapping to the same hash }
  500. { slot are contiguous. The key table contains just the full 32 bit hash word for each }
  501. { exported symbol. The symbol table contains the offset of the symbol's name in the string }
  502. { table and other information about the exported symbol. }
  503. { To look up an export you take the hashword and compute the hash slot index. You then scan }
  504. { the indicated portion of the key table for matching hashwords. If a hashword matches, you }
  505. { look at the corresponding symbol table entry to find the full symbol name. If the names }
  506. { match the symbol is found. }
  507. { -------------------------------------------------------------------------------------------- }
  508. { The following function may be used to compute the hash table size. Signed values are used }
  509. { just to avoid potential code generation overhead for unsigned division. }
  510. { UInt8 PEFComputeHashTableExponent ( SInt32 exportCount ) }
  511. { ( }
  512. { SInt32 exponent; }
  513. { const SInt32 kExponentLimit = 16; // Arbitrary, but must not exceed 30. }
  514. { const SInt32 kAverageChainLimit = 10; // Arbitrary, for space/time tradeoff. }
  515. { for ( exponent = 0; exponent < kExponentLimit; exponent += 1 ) ( }
  516. { if ( (exportCount / (1 << exponent)) < kAverageChainLimit ) break; }
  517. { ) }
  518. { return exponent; }
  519. { ) // PEFComputeHashTableExponent () }
  520. { -------------------------------------------------------------------------------------------- }
  521. { The PEFExportedSymbolHashSlot type has the following bit field layout. }
  522. { 1 1 3 }
  523. { 0 3 4 1 }
  524. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  525. { | symbol count | index of first export key | }
  526. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  527. { |<-- 14 bits -------------->|<-- 18 bits ---------------------->| }
  528. type
  529. PEFExportedSymbolHashSlotPtr = ^PEFExportedSymbolHashSlot;
  530. PEFExportedSymbolHashSlot = record
  531. countAndStart: UInt32;
  532. end;
  533. const
  534. kPEFHashSlotSymCountShift = 18;
  535. kPEFHashSlotFirstKeyMask = $0003FFFF;
  536. kPEFHashSlotMaxSymbolCount = $00003FFF; { 16,383}
  537. kPEFHashSlotMaxKeyIndex = $0003FFFF; { 262,143}
  538. { =========================================================================================== }
  539. { Exported Symbol Hash Key }
  540. { ------------------------ }
  541. type
  542. PEFSplitHashWordPtr = ^PEFSplitHashWord;
  543. PEFSplitHashWord = record
  544. nameLength: UInt16;
  545. hashValue: UInt16;
  546. end;
  547. type
  548. PEFExportedSymbolKeyPtr = ^PEFExportedSymbolKey;
  549. PEFExportedSymbolKey = record
  550. case SInt16 of
  551. 0: (
  552. fullHashWord: UInt32;
  553. );
  554. 1: (
  555. splitHashWord: PEFSplitHashWord;
  556. );
  557. end;
  558. const
  559. kPEFHashLengthShift = 16;
  560. kPEFHashValueMask = $0000FFFF;
  561. kPEFHashMaxLength = $0000FFFF; { 65,535}
  562. { ---------------------------------------------------------------------------------------------------- }
  563. { The following function computes the full 32 bit hash word. }
  564. { UInt32 PEFComputeHashWord ( BytePtr nameText, // ! First "letter", not length byte. }
  565. { UInt32 nameLength ) // ! The text may be zero terminated. }
  566. { ( }
  567. { BytePtr charPtr = nameText; }
  568. { SInt32 hashValue = 0; // ! Signed to match old published algorithm. }
  569. { UInt32 length = 0; }
  570. { UInt32 limit; }
  571. { UInt32 result; }
  572. { UInt8 currChar; }
  573. { #define PseudoRotate(x) ( ( (x) << 1 ) - ( (x) >> 16 ) ) }
  574. { for ( limit = nameLength; limit > 0; limit -= 1 ) ( }
  575. { currChar = *charPtr++; }
  576. { if ( currChar == NULL ) break; }
  577. { length += 1; }
  578. { hashValue = PseudoRotate ( hashValue ) ^ currChar; }
  579. { ) }
  580. { result = (length << kPEFHashLengthShift) | }
  581. { ((UInt16) ((hashValue ^ (hashValue >> 16)) & kPEFHashValueMask)); }
  582. { return result; }
  583. { ) // PEFComputeHashWord () }
  584. { =========================================================================================== }
  585. { Exported Symbols }
  586. { ---------------- }
  587. type
  588. PEFExportedSymbolPtr = ^PEFExportedSymbol;
  589. PEFExportedSymbol = record
  590. { ! This structure is 10 bytes long and arrays are packed.}
  591. classAndName: UInt32; { A combination of class and name offset.}
  592. symbolValue: UInt32; { Typically the symbol's offset within a section.}
  593. sectionIndex: SInt16; { The index of the section, or pseudo-section, for the symbol.}
  594. end;
  595. { -------------------------------------------------------------------------------------------- }
  596. { The classAndName field of the PEFExportedSymbol type has the following bit field layout. }
  597. { 3 }
  598. { 0 7 8 1 }
  599. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  600. { | symbol class | offset of symbol name in loader string table | }
  601. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  602. { |<-- 8 bits --->|<-- 24 bits ---------------------------------->| }
  603. const
  604. kPEFExpSymClassShift = 24;
  605. kPEFExpSymNameOffsetMask = $00FFFFFF;
  606. kPEFExpSymMaxNameOffset = $00FFFFFF; { 16,777,215}
  607. (*
  608. #define PEFExportedSymbolClass(classAndName) ((UInt8) ((classAndName) >> kPEFExpSymClassShift))
  609. #define PEFExportedSymbolNameOffset(classAndName) ((classAndName) & kPEFExpSymNameOffsetMask)
  610. #define PEFComposeExportedSymbol(class,nameOffset) \
  611. ( ( ((UInt32)(class)) << kPEFExpSymClassShift ) | ( (UInt32)(nameOffset) ) )
  612. *)
  613. const
  614. { Negative section indices indicate pseudo-sections.}
  615. kPEFAbsoluteExport = -2; { The symbol value is an absolute address.}
  616. kPEFReexportedImport = -3; { The symbol value is the index of a reexported import.}
  617. { =========================================================================================== }
  618. { Loader Relocations }
  619. { ================== }
  620. { -------------------------------------------------------------------------------------------- }
  621. { The relocations for a section are defined by a sequence of instructions for an abstract }
  622. { machine that is specifically geared to performing relocations commonly needed for the "CFM" }
  623. { code generation model. These instructions occur in 16 bit chunks. Most instructions have }
  624. { just a single chunk. Instructions that are larger than 16 bits have an opcode and some of }
  625. { the operands in the first chunk, with other operands in following chunks. }
  626. { ! Note that the multi-chunk relocations have separate "Compose" macros for each chunk. The }
  627. { ! macros have the same basic name with a positional suffix of "_1st", "_2nd", etc. }
  628. type
  629. PEFRelocChunk = UInt16;
  630. PEFLoaderRelocationHeaderPtr = ^PEFLoaderRelocationHeader;
  631. PEFLoaderRelocationHeader = record
  632. sectionIndex: UInt16; { Index of the section to be fixed up.}
  633. reservedA: UInt16; { Reserved, must be zero.}
  634. relocCount: UInt32; { Number of 16 bit relocation chunks.}
  635. firstRelocOffset: UInt32; { Offset of first relocation instruction.}
  636. end;
  637. { -------------------------------------------------------------------------------------------- }
  638. { ! Note that the relocCount field is the number of 16 bit relocation chunks, i.e. 1/2 the }
  639. { ! total number of bytes of relocation instructions. While most relocation instructions are }
  640. { ! 16 bits long, some are longer so the number of complete relocation instructions may be }
  641. { ! less than the relocCount value. }
  642. { ------------------------------------------------------------------------------------ }
  643. { The PEFRelocField macro is a utility for extracting relocation instruction fields. }
  644. (*
  645. #define PEFRFShift(offset,length) (16 - ((offset) + (length)))
  646. #define PEFRFMask(length) ((1 << (length)) - 1)
  647. #define PEFRelocField(chunk,offset,length) \
  648. ( ( (chunk) >> (16 - ((offset) + (length))) ) & ((1 << (length)) - 1) )
  649. *)
  650. { =========================================================================================== }
  651. { Basic Relocation Opcodes }
  652. { ------------------------ }
  653. { -------------------------------------------------------------------------------------------- }
  654. { The number of opcode bits varies from 2 to 7. The enumeration and switch table given here }
  655. { are defined in terms of the most significant 7 bits of the first instruction chunk. An }
  656. { instruction is decoded by using the most significant 7 bits as an index into the opcode }
  657. { table, which in turn contains appropriately masked forms of the most significant 7 bits. }
  658. { The macro PEFRelocBasicOpcode assumes a declaration of the form. }
  659. { UInt8 kPEFRelocBasicOpcodes [kPEFRelocBasicOpcodeRange] = ( PEFMaskedBasicOpcodes ); }
  660. const
  661. kPEFRelocBasicOpcodeRange = 128;
  662. (*
  663. #define PEFRelocBasicOpcode(firstChunk) (kPEFRelocBasicOpcodes[(firstChunk)>>9])
  664. *)
  665. { -------------------------------------------------------------------------------------------- }
  666. { The relocation opcodes, clustered by major and minor groups. The instructions within a }
  667. { cluster all have the same bit field layout. The enumeration values use the high order 7 }
  668. { bits of the relocation instruction. Unused low order bits are set to zero. }
  669. const
  670. kPEFRelocBySectDWithSkip = $00; { Binary: 00x_xxxx}
  671. kPEFRelocBySectC = $20; { Binary: 010_0000, group is "RelocRun"}
  672. kPEFRelocBySectD = $21; { Binary: 010_0001}
  673. kPEFRelocTVector12 = $22; { Binary: 010_0010}
  674. kPEFRelocTVector8 = $23; { Binary: 010_0011}
  675. kPEFRelocVTable8 = $24; { Binary: 010_0100}
  676. kPEFRelocImportRun = $25; { Binary: 010_0101}
  677. kPEFRelocSmByImport = $30; { Binary: 011_0000, group is "RelocSmIndex"}
  678. kPEFRelocSmSetSectC = $31; { Binary: 011_0001}
  679. kPEFRelocSmSetSectD = $32; { Binary: 011_0010}
  680. kPEFRelocSmBySection = $33; { Binary: 011_0011}
  681. kPEFRelocIncrPosition = $40; { Binary: 100_0xxx}
  682. kPEFRelocSmRepeat = $48; { Binary: 100_1xxx}
  683. kPEFRelocSetPosition = $50; { Binary: 101_000x}
  684. kPEFRelocLgByImport = $52; { Binary: 101_001x}
  685. kPEFRelocLgRepeat = $58; { Binary: 101_100x}
  686. kPEFRelocLgSetOrBySection = $5A; { Binary: 101_101x}
  687. kPEFRelocUndefinedOpcode = $FF; { Used in masking table for all undefined values.}
  688. { ---------------------------------------------------------------------------- }
  689. { The RelocLgSetOrBySection instruction has an additional 4 bits of subopcode }
  690. { beyond the 7 used by the dispatch table. To be precise it has 6 plus 4 but }
  691. { the dispatch table ignores the 7th bit, so the subdispatch is on all 4 extra }
  692. { subopcode bits. }
  693. const
  694. kPEFRelocLgBySectionSubopcode = $00; { Binary: 0000}
  695. kPEFRelocLgSetSectCSubopcode = $01; { Binary: 0001}
  696. kPEFRelocLgSetSectDSubopcode = $02; { Binary: 0010}
  697. (*
  698. #define PEFRelocLgSetOrBySubopcode(chunk) (((chunk) >> 6) & 0x0F)
  699. *)
  700. { -------------------------------------------------------------------------------------------- }
  701. { The initial values for the opcode "masking" table. This has the enumeration values from }
  702. { above with appropriate replications for "don't care" bits. It is almost certainly shorter }
  703. { and faster to look up the masked value in a table than to use a branch tree. }
  704. (*
  705. #define PEFMaskedBasicOpcodes \
  706. \
  707. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, { 0x00 .. 0x03 } \
  708. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, { 0x04 .. 0x07 } \
  709. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, { 0x08 .. 0x0B } \
  710. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, { 0x0C .. 0x0F } \
  711. \
  712. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, { 0x10 .. 0x13 } \
  713. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, { 0x14 .. 0x17 } \
  714. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, { 0x18 .. 0x1B } \
  715. kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, { 0x1C .. 0x1F } \
  716. \
  717. kPEFRelocBySectC, kPEFRelocBySectD, kPEFRelocTVector12, kPEFRelocTVector8, { 0x20 .. 0x23 } \
  718. kPEFRelocVTable8, kPEFRelocImportRun, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x24 .. 0x27 } \
  719. \
  720. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x28 .. 0x2B } \
  721. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x2C .. 0x2F } \
  722. \
  723. kPEFRelocSmByImport, kPEFRelocSmSetSectC, kPEFRelocSmSetSectD, kPEFRelocSmBySection, { 0x30 .. 0x33 } \
  724. \
  725. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x34 .. 0x37 } \
  726. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x38 .. 0x3B } \
  727. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x3C .. 0x3F } \
  728. \
  729. kPEFRelocIncrPosition, kPEFRelocIncrPosition, kPEFRelocIncrPosition, kPEFRelocIncrPosition, { 0x40 .. 0x43 } \
  730. kPEFRelocIncrPosition, kPEFRelocIncrPosition, kPEFRelocIncrPosition, kPEFRelocIncrPosition, { 0x44 .. 0x47 } \
  731. \
  732. kPEFRelocSmRepeat, kPEFRelocSmRepeat, kPEFRelocSmRepeat, kPEFRelocSmRepeat, { 0x48 .. 0x4B } \
  733. kPEFRelocSmRepeat, kPEFRelocSmRepeat, kPEFRelocSmRepeat, kPEFRelocSmRepeat, { 0x4C .. 0x4F } \
  734. \
  735. kPEFRelocSetPosition, kPEFRelocSetPosition, kPEFRelocLgByImport, kPEFRelocLgByImport, { 0x50 .. 0x53 } \
  736. \
  737. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x54 .. 0x57 } \
  738. \
  739. kPEFRelocLgRepeat, kPEFRelocLgRepeat, kPEFRelocLgSetOrBySection, kPEFRelocLgSetOrBySection, { 0x58 .. 0x5B } \
  740. \
  741. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x5C .. 0x5F } \
  742. \
  743. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x60 .. 0x63 } \
  744. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x64 .. 0x67 } \
  745. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x68 .. 0x6B } \
  746. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x6C .. 0x6F } \
  747. \
  748. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x70 .. 0x73 } \
  749. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x74 .. 0x77 } \
  750. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, { 0x78 .. 0x7B } \
  751. kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode { 0x7C .. 0x7F }
  752. *)
  753. { =========================================================================================== }
  754. { RelocBySectDWithSkip Instruction (DDAT) }
  755. { --------------------------------------- }
  756. { -------------------------------------------------------------------------------------------- }
  757. { The "RelocBySectDWithSkip" (DDAT) instruction has the following bit field layout. }
  758. { 1 1 }
  759. { 0 1 2 9 0 5 }
  760. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  761. { |0 0| skip count | rel count | }
  762. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  763. { | 2 |<-- 8 bits --->|<-- 6 --->| }
  764. { ! Note that the stored skip count and reloc count are the actual values! }
  765. const
  766. kPEFRelocWithSkipMaxSkipCount = 255;
  767. kPEFRelocWithSkipMaxRelocCount = 63;
  768. (*
  769. #define PEFRelocWithSkipSkipCount(chunk) PEFRelocField ( (chunk), 2, 8 )
  770. #define PEFRelocWithSkipRelocCount(chunk) PEFRelocField ( (chunk), 10, 6 )
  771. #define PEFRelocComposeWithSkip(skipCount,relocCount) \
  772. ( 0x0000 | (((UInt16)(skipCount)) << 6) | ((UInt16)(relocCount)) )
  773. *)
  774. { =========================================================================================== }
  775. { RelocRun Group (CODE, DATA, DESC, DSC2, VTBL, SYMR) }
  776. { --------------------------------------------------- }
  777. { -------------------------------------------------------------------------------------------- }
  778. { The "RelocRun" group includes the "RelocBySectC" (CODE), "RelocBySectD" (DATA), }
  779. { "RelocTVector12" (DESC), "RelocTVector8" (DSC2), "RelocVTable8" (VTBL), and }
  780. { "RelocImportRun" (SYMR) instructions. This group has the following bit field layout. }
  781. { 1 }
  782. { 0 2 3 6 7 5 }
  783. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  784. { |0 1 0| subop.| run length | }
  785. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  786. { | 3 |<- 4 ->|<-- 9 bits ----->| }
  787. { ! Note that the stored run length is the actual value minus 1, but the macros deal with the }
  788. { ! actual value! }
  789. const
  790. kPEFRelocRunMaxRunLength = 512;
  791. (*
  792. #define PEFRelocRunSubopcode(chunk) PEFRelocField ( (chunk), 3, 4 )
  793. #define PEFRelocRunRunLength(chunk) (PEFRelocField ( (chunk), 7, 9 ) + 1)
  794. #define PEFRelocComposeRun(subopcode,runLength) \
  795. ( 0x4000 | (((UInt16)(subopcode)) << 9) | ((UInt16)((runLength)-1)) )
  796. #define PEFRelocComposeBySectC(runLength) PEFRelocComposeRun ( 0, (runLength) )
  797. #define PEFRelocComposeBySectD(runLength) PEFRelocComposeRun ( 1, (runLength) )
  798. #define PEFRelocComposeTVector12(runLength) PEFRelocComposeRun ( 2, (runLength) )
  799. #define PEFRelocComposeTVector8(runLength) PEFRelocComposeRun ( 3, (runLength) )
  800. #define PEFRelocComposeVTable8(runLength) PEFRelocComposeRun ( 4, (runLength) )
  801. #define PEFRelocComposeImportRun(runLength) PEFRelocComposeRun ( 5, (runLength) )
  802. *)
  803. { =========================================================================================== }
  804. { RelocSmIndex Group (SYMB, CDIS, DTIS, SECN) }
  805. { ------------------------------------------- }
  806. { -------------------------------------------------------------------------------------------- }
  807. { The "RelocSmIndex" group includes the "RelocSmByImport" (SYMB), "RelocSmSetSectC" (CDIS), }
  808. { "RelocSmSetSectD" (DTIS) and "RelocSmBySection" (SECN) instructions. This group has the }
  809. { following bit field layout. }
  810. { 1 }
  811. { 0 2 3 6 7 5 }
  812. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  813. { |0 1 1| subop.| index | }
  814. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  815. { | 3 |<- 4 ->|<-- 9 bits ----->| }
  816. { ! Note that the stored index is the actual value! }
  817. const
  818. kPEFRelocSmIndexMaxIndex = 511;
  819. (*
  820. #define PEFRelocSmIndexSubopcode(chunk) PEFRelocField ( (chunk), 3, 4 )
  821. #define PEFRelocSmIndexIndex(chunk) PEFRelocField ( (chunk), 7, 9 )
  822. #define PEFRelocComposeSmIndex(subopcode,index) \
  823. ( 0x6000 | (((UInt16)(subopcode)) << 9) | ((UInt16)(index)) )
  824. #define PEFRelocComposeSmByImport(index) PEFRelocComposeSmIndex ( 0, (index) )
  825. #define PEFRelocComposeSmSetSectC(index) PEFRelocComposeSmIndex ( 1, (index) )
  826. #define PEFRelocComposeSmSetSectD(index) PEFRelocComposeSmIndex ( 2, (index) )
  827. #define PEFRelocComposeSmBySection(index) PEFRelocComposeSmIndex ( 3, (index) )
  828. *)
  829. { =========================================================================================== }
  830. { RelocIncrPosition Instruction (DELT) }
  831. { ------------------------------------ }
  832. { -------------------------------------------------------------------------------------------- }
  833. { The "RelocIncrPosition" (DELT) instruction has the following bit field layout. }
  834. { 1 }
  835. { 0 3 4 5 }
  836. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  837. { |1 0 0 0| offset | }
  838. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  839. { |<- 4 ->|<-- 12 bits ---------->| }
  840. { ! Note that the stored offset is the actual value minus 1, but the macros deal with the }
  841. { ! actual value! }
  842. const
  843. kPEFRelocIncrPositionMaxOffset = 4096;
  844. (*
  845. #define PEFRelocIncrPositionOffset(chunk) (PEFRelocField ( (chunk), 4, 12 ) + 1)
  846. #define PEFRelocComposeIncrPosition(offset) \
  847. ( 0x8000 | ((UInt16)((offset)-1)) )
  848. *)
  849. { =========================================================================================== }
  850. { RelocSmRepeat Instruction (RPT) }
  851. { ------------------------------- }
  852. { -------------------------------------------------------------------------------------------- }
  853. { The "RelocSmRepeat" (RPT) instruction has the following bit field layout. }
  854. { 1 }
  855. { 0 3 4 7 8 5 }
  856. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  857. { |1 0 0 1| chnks | repeat count | }
  858. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  859. { |<- 4 ->|<- 4 ->|<-- 8 bits --->| }
  860. { ! Note that the stored chunk count and repeat count are the actual values minus 1, but the }
  861. { ! macros deal with the actual values! }
  862. const
  863. kPEFRelocSmRepeatMaxChunkCount = 16;
  864. kPEFRelocSmRepeatMaxRepeatCount = 256;
  865. (*
  866. #define PEFRelocSmRepeatChunkCount(chunk) (PEFRelocField ( (chunk), 4, 4 ) + 1)
  867. #define PEFRelocSmRepeatRepeatCount(chunk) (PEFRelocField ( (chunk), 8, 8 ) + 1)
  868. #define PEFRelocComposeSmRepeat(chunkCount,repeatCount) \
  869. ( 0x9000 | ((((UInt16)(chunkCount))-1) << 8) | (((UInt16)(repeatCount))-1) )
  870. *)
  871. { =========================================================================================== }
  872. { RelocSetPosition Instruction (LABS) }
  873. { ----------------------------------- }
  874. { -------------------------------------------------------------------------------------------- }
  875. { The "RelocSetPosition" (LABS) instruction has the following bit field layout. }
  876. { 1 1 }
  877. { 0 5 6 5 0 5 }
  878. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  879. { |1 0 1 0 0 0| offset (high) | | offset (low) | }
  880. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  881. { |<-- 6 ---->|<-- 10 bits ------>| |<-- 16 bits ------------------>| }
  882. { ! Note that the stored offset is the actual value! }
  883. const
  884. kPEFRelocSetPosMaxOffset = $03FFFFFF; { 67,108,863}
  885. (*
  886. #define PEFRelocSetPosOffsetHigh(chunk) PEFRelocField ( (chunk), 6, 10 )
  887. #define PEFRelocSetPosFullOffset(firstChunk,secondChunk) \
  888. ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  889. #define PEFRelocComposeSetPosition_1st(fullOffset) \
  890. ( 0xA000 | ((UInt16) (((UInt32)(fullOffset)) >> 16) ) )
  891. #define PEFRelocComposeSetPosition_2nd(fullOffset) \
  892. ( (UInt16) ((UInt32)(fullOffset) & 0xFFFF) )
  893. *)
  894. { =========================================================================================== }
  895. { RelocLgByImport Instruction (LSYM) }
  896. { ---------------------------------- }
  897. { -------------------------------------------------------------------------------------------- }
  898. { The "RelocLgByImport" (LSYM) instruction has the following bit field layout. }
  899. { 1 1 }
  900. { 0 5 6 5 0 5 }
  901. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  902. { |1 0 1 0 0 1| index (high) | | index (low) | }
  903. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  904. { |<-- 6 ---->|<-- 10 bits ------>| |<-- 16 bits ------------------>| }
  905. { ! Note that the stored offset is the actual value! }
  906. const
  907. kPEFRelocLgByImportMaxIndex = $03FFFFFF; { 67,108,863}
  908. (*
  909. #define PEFRelocLgByImportIndexHigh(chunk) PEFRelocField ( (chunk), 6, 10 )
  910. #define PEFRelocLgByImportFullIndex(firstChunk,secondChunk) \
  911. ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  912. #define PEFRelocComposeLgByImport_1st(fullIndex) \
  913. ( 0xA400 | ((UInt16) (((UInt32)(fullIndex)) >> 16) ) )
  914. #define PEFRelocComposeLgByImport_2nd(fullIndex) \
  915. ( (UInt16) ((UInt32)(fullIndex) & 0xFFFF) )
  916. *)
  917. { =========================================================================================== }
  918. { RelocLgRepeat Instruction (LRPT) }
  919. { -------------------------------- }
  920. { -------------------------------------------------------------------------------------------- }
  921. { The "RelocLgRepeat" (LRPT) instruction has the following bit field layout. }
  922. { 1 1 1 }
  923. { 0 5 6 9 0 5 0 5 }
  924. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  925. { |1 0 1 1 0 0| chnks | rpt (high)| | repeat count (low) | }
  926. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  927. { |<-- 6 --->|<- 4 ->|<-- 6 --->| |<-- 16 bits ------------------>| }
  928. { ! Note that the stored chunk count is the actual value minus 1, but the macros deal with }
  929. { ! the actual value! The stored repeat count is the actual value! }
  930. const
  931. kPEFRelocLgRepeatMaxChunkCount = 16;
  932. kPEFRelocLgRepeatMaxRepeatCount = $003FFFFF; { 4,194,303}
  933. (*
  934. #define PEFRelocLgRepeatChunkCount(chunk) (PEFRelocField ( (chunk), 6, 4 ) + 1)
  935. #define PEFRelocLgRepeatRepeatCountHigh(chunk) PEFRelocField ( (chunk), 10, 6 )
  936. #define PEFRelocLgRepeatFullRepeatCount(firstChunk,secondChunk) \
  937. ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  938. #define PEFRelocComposeLgRepeat_1st(chunkCount,fullRepeatCount) \
  939. ( 0xB000 | ((((UInt16)(chunkCount))-1) << 6) | ((UInt16) (((UInt32)(fullRepeatCount)) >>16 ) ) )
  940. #define PEFRelocComposeLgRepeat_2nd(chunkCount,fullRepeatCount) \
  941. ( (UInt16) ((UInt32)(fullRepeatCount) & 0xFFFF) )
  942. *)
  943. { =========================================================================================== }
  944. { RelocLgSetOrBySection Group (LSEC) }
  945. { ---------------------------------- }
  946. { -------------------------------------------------------------------------------------------- }
  947. { The "RelocLgSetOrBySection" (LSEC) instruction is a group including the "RelocLgBySection", }
  948. { "RelocLgSetSectC" and "RelocLgSetSectD" instructions. This group has the following bit }
  949. { field layout. }
  950. { 1 1 1 }
  951. { 0 5 6 9 0 5 0 5 }
  952. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  953. { |1 0 1 1 0 1| subop | idx (high)| | index (low) | }
  954. { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ }
  955. { |<-- 6 --->|<- 4 ->|<-- 6 --->| |<-- 16 bits ------------------>| }
  956. { ! Note that the stored index is the actual value! }
  957. const
  958. kPEFRelocLgSetOrBySectionMaxIndex = $003FFFFF; { 4,194,303}
  959. (*
  960. #define PEFRelocLgSetOrBySectionSubopcode(chunk) PEFRelocField ( (chunk), 6, 4 )
  961. #define PEFRelocLgSetOrBySectionIndexHigh(chunk) PEFRelocField ( (chunk), 10, 6 )
  962. #define PEFRelocLgSetOrBySectionFullIndex(firstChunk,secondChunk) \
  963. ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  964. #define PEFRelocComposeLgSetOrBySection_1st(subopcode,fullIndex) \
  965. ( 0xB400 | (((UInt16)(subopcode)) << 6) | ((UInt16) (((UInt32)(fullIndex)) >> 16) ) )
  966. #define PEFRelocComposeLgSetOrBySection_2nd(subopcode,fullIndex) \
  967. ( (UInt16) ((UInt32)(fullIndex) & 0xFFFF) )
  968. #define PEFRelocComposeLgBySection(fullIndex) PEFRelocComposeLgSetOrBySection ( 0x00, (fullIndex) )
  969. #define PEFRelocComposeLgSetSectC(fullIndex) PEFRelocComposeLgSetOrBySection ( 0x01, (fullIndex) )
  970. #define PEFRelocComposeLgSetSectD(fullIndex) PEFRelocComposeLgSetOrBySection ( 0x02, (fullIndex) )
  971. *)
  972. { ======================================================================================== }
  973. { ======================================================================================== }
  974. { ======================================================================================== }
  975. { Vector Library Declarations }
  976. { =========================== }
  977. { -------------------------------------------------------------------------------------------- }
  978. { Mac OS X has special "vector" and "bridge" libraries to allow CFM managed clients to import }
  979. { from the dyld managed implementation libraries. The vector libraries are typically embedded }
  980. { within their respective implementation libraries. Even if standalone, the vector libraries }
  981. { are themselves normal dyld managed libraries. The vector libraries contain an export symbol }
  982. { table and pointers to the actual implementations. For functions, these pointers serve as }
  983. { the PMacCG TVectors. Because the dyld libraries are not part of the CFM search, we need a }
  984. { separate library for CFM to find that then indicates where the vector library is. These are }
  985. { the bridge libraries. They are tiny, just the container header and container strings parts. }
  986. { Since the vector library is embedded in a Mach-O dylib, we use dyld services to obtain the }
  987. { base address for the main portion and the exported symbol portion. The binding pointers are }
  988. { found through offsets in the exported symbol records. }
  989. { +-----------------------------------+ <-- containerOrigin ------------+ }
  990. { | Container Header | 76 bytes | }
  991. { |-----------------------------------| <-- + containerStringsOffset ---| }
  992. { | Container Strings | | }
  993. { |-----------------------------------| <-- + exportHashOffset ---------+ }
  994. { | Export Hash Slot 0 | 4 bytes each | }
  995. { |...................................| | }
  996. { | - - - | | }
  997. { |...................................| | }
  998. { | Export Hash Slot h-1 | | }
  999. { |-----------------------------------| <-- + exportKeyOffset ----------+ }
  1000. { | Export Symbol Key 0 | 4 bytes each | }
  1001. { |...................................| Order must match the exported symbols | }
  1002. { | - - - | | }
  1003. { |...................................| | }
  1004. { | Export Symbol Key e-1 | | }
  1005. { |-----------------------------------| <-- + exportNamesOffset --------+ }
  1006. { | Export Names | | }
  1007. { |-----------------------------------| | }
  1008. { (Disjoint parts) | }
  1009. { |-----------------------------------| <-- + exportSymbolOffset -------+ }
  1010. { | Export Symbol 0 | 8 bytes each }
  1011. { |...................................| Order must match the export keys }
  1012. { | - - - | }
  1013. { |...................................| }
  1014. { | Export Symbol e-1 | }
  1015. { +-----------------------------------+ }
  1016. { (Disjoint parts) }
  1017. { |-----------------------------------| }
  1018. { | Binding Pointer 0 | 4 bytes each }
  1019. { |-----------------------------------| Possibly disjoint, order does not matter }
  1020. { | - - - | }
  1021. { |-----------------------------------| }
  1022. { | Binding Pointer e-1 | }
  1023. { +-----------------------------------+ }
  1024. type
  1025. XLibContainerHeaderPtr = ^XLibContainerHeader;
  1026. XLibContainerHeader = record
  1027. { Structural description fields:}
  1028. tag1: OSType; { Must contain 'ðMac'.}
  1029. tag2: OSType; { Must contain 'vLib' or 'bLib'.}
  1030. currentFormat: UInt32; { The version of XLib types used to create this container.}
  1031. containerStringsOffset: UInt32; { Container offset of the container string table.}
  1032. exportHashOffset: UInt32; { Offset of the export hash table.}
  1033. exportKeyOffset: UInt32; { Offset of the export key table.}
  1034. exportSymbolOffset: UInt32; { Offset of the export symbol table.}
  1035. exportNamesOffset: UInt32; { Offset of the export names.}
  1036. exportHashTablePower: UInt32; { Export hash table size as log 2. (Log2('h'))}
  1037. exportedSymbolCount: UInt32; { Number of exported symbols. ('e')}
  1038. { Fragment description fields:}
  1039. fragNameOffset: UInt32; { The offset of the fragment name in the container string table.}
  1040. fragNameLength: UInt32; { The length of the fragment name in the container string table.}
  1041. dylibPathOffset: UInt32; { The offset of the dyld "install name" in the container string table.}
  1042. dylibPathLength: UInt32; { The length of the dyld "install name" in the container string table.}
  1043. cpuFamily: OSType; { The ISA for code sections. Constants in CodeFragments.h.}
  1044. cpuModel: OSType; { Specific CPU model if applicable.}
  1045. dateTimeStamp: UInt32; { Mac format creation stamp.}
  1046. currentVersion: UInt32; { Current version number for the code fragment.}
  1047. oldDefVersion: UInt32; { Old definition version number for the code fragment.}
  1048. oldImpVersion: UInt32; { Old implementation version number for the code fragment.}
  1049. end;
  1050. const
  1051. kXLibTag1 = FourCharCode('ðMac'); { For non-Apple compilers: 0xF04D6163.}
  1052. kVLibTag2 = FourCharCode('VLib'); { For non-Apple compilers: 0x564C6962.}
  1053. kBLibTag2 = FourCharCode('BLib'); { For non-Apple compilers: 0x424C6962.}
  1054. kXLibVersion = $00000001;
  1055. type
  1056. XLibExportedSymbolHashSlot = PEFExportedSymbolHashSlot;
  1057. XLibExportedSymbolKey = PEFExportedSymbolKey;
  1058. XLibExportedSymbolPtr = ^XLibExportedSymbol;
  1059. XLibExportedSymbol = record
  1060. classAndName: UInt32; { A combination of class and name offset.}
  1061. bpOffset: UInt32; { Container offset of the export's dyld binding pointer.}
  1062. end;
  1063. { =========================================================================================== }
  1064. {$ifc not undefined IncludePEF2Declarations and IncludePEF2Declarations}
  1065. { ======================================================================================== }
  1066. { ======================================================================================== }
  1067. { ======================================================================================== }
  1068. { PEF2 Declarations }
  1069. { ================= }
  1070. { -------------------------------------------------------------------------------------------- }
  1071. { PEF2 is a follow-on to the original PEF, incorporating changes that would break backward }
  1072. { compatibility. The primary motivations for PEF2 are to incorporate new features cleanly, to }
  1073. { relax some physical limitations, and to provide a more explicit path for future growth. }
  1074. { PEF2 is very similar to PEF, it is possible for any PEF container to be mechanically }
  1075. { converted to PEF2. The converse is not necessarily true, containers that use new features }
  1076. { of PEF2 might not be convertable to PEF. }
  1077. { One difference from PEF is that PEF2 has no implicit ordering, e.g. the section headers do }
  1078. { not necessarily immediately follow the container header. Explicit offsets and lengths are }
  1079. { provided for all portions of the container so that tools can continue to parse PEF2 as new }
  1080. { versions of it are produced in the future. The following overall layout is suggested for }
  1081. { locality of reference in typical usage with a packed data image: }
  1082. { +-----------------------------------+ }
  1083. { | Container Header | }
  1084. { +-----------------------------------+ }
  1085. { | Section 0 header | }
  1086. { |...................................| }
  1087. { | - - - - | }
  1088. { |...................................| }
  1089. { | Section n-1 header | }
  1090. { +-----------------------------------+ }
  1091. { | Container String Table | }
  1092. { +-----------------------------------+ }
  1093. { | Loader section contents | }
  1094. { +-----------------------------------+ }
  1095. { | Packed data contents | }
  1096. { +-----------------------------------+ }
  1097. { | Code section contents | }
  1098. { +-----------------------------------+ }
  1099. { If unpacked data is used for prebinding with copy-on-write mapping, the unpacked data should }
  1100. { follow the code section. }
  1101. { Note that the rule regarding instantiated sections preceeding noninstantiated sections only }
  1102. { applies to the section headers, not the section contents. Thus it is perfectly fine for the }
  1103. { loader section contents to be first. }
  1104. { The container string table holds the name of the fragment and the names of the sections. }
  1105. { The first 4 bytes of the container string table must be zero and always present. An offset }
  1106. { of zero into the container string table is considered a null name. Actual names are stored }
  1107. { as a PEF-style 32 bit hashword followed by the text of the name. The encoding of the text }
  1108. { is given by the stringEncoding field of the container header. The hashword is computed from }
  1109. { the encoded name as a string of bytes. The length in the hashword is the number of bytes in }
  1110. { the encoded name, not the number of logical characters. }
  1111. { =========================================================================================== }
  1112. { Container Header }
  1113. { ================ }
  1114. type
  1115. PEF2ContainerHeaderPtr = ^PEF2ContainerHeader;
  1116. PEF2ContainerHeader = record
  1117. { Structural fields:}
  1118. tag1: OSType; { Must contain 'Joy!'.}
  1119. tag2: OSType; { Must contain 'PEF '.}
  1120. currentFormat: UInt32; { The version of PEF2 used to create this container.}
  1121. oldestFormat: UInt32; { Oldest compatible container handler.}
  1122. containerHeaderSize: UInt32; { The size of this header in bytes.}
  1123. containerLength: UInt32; { The total length of the container in bytes.}
  1124. checksum: UInt32; { A checksum for the entire container.}
  1125. sectionHeadersOffset: UInt32; { Container offset of the first section header.}
  1126. sectionHeaderSize: UInt32; { The size in bytes of each section header.}
  1127. totalSectionCount: UInt32; { Total number of section headers.}
  1128. instSectionCount: UInt32; { Number of instantiated sections.}
  1129. loaderSectionIndex: UInt32; { Index of the section containing runtime loader tables.}
  1130. containerStringsOffset: UInt32; { Container offset of the container string table.}
  1131. containerStringsLength: UInt32; { Length in bytes of the container string table.}
  1132. options: UInt32; { Array of 32 option bits.}
  1133. preferredAddress: UInt32; { Preferred container address, 0xFFFFFFFF indicates no preference.}
  1134. alignment: UInt8; { Required container alignment as LOG 2.}
  1135. stringEncoding: UInt8; { The encoding for all strings in the container.}
  1136. reservedA: UInt16; { Reserved, must be written as zero.}
  1137. reservedB: UInt32; { Reserved, must be written as zero.}
  1138. reservedC: UInt32; { Reserved, must be written as zero.}
  1139. { Fragment description fields:}
  1140. nameOffset: UInt32; { The offset of the name in the container string table.}
  1141. architecture: OSType; { The ISA for code sections. Constants in CodeFragments.h.}
  1142. dateTimeStamp: UInt32; { Macintosh format creation/modification stamp.}
  1143. currentVersion: UInt32; { Current version number for the code fragment.}
  1144. oldDefVersion: UInt32; { Old definition version number for the code fragment.}
  1145. oldImpVersion: UInt32; { Old implementation version number for the code fragment.}
  1146. reservedD: UInt32; { Reserved, must be written as zero.}
  1147. reservedE: UInt32; { Reserved, must be written as zero.}
  1148. end;
  1149. const
  1150. kPEF2Tag1 = kPEFTag1;
  1151. kPEF2Tag2 = FourCharCode('PEF '); { For non-Apple compilers: 0x50656620.}
  1152. kPEF2CurrentFormat = $00000002; { ! There is no version 0 or 1.}
  1153. kPEF2OldestHandler = $00000002;
  1154. const
  1155. { Values for the options field.}
  1156. kPEF2IsReexportLibraryMask = $00000001; { This fragment does nothing but reexport imports.}
  1157. kPEF2IsGlueLibraryMask = $00000002; { A special form of import library that provides a glue layer.}
  1158. const
  1159. { Values for the stringEncoding field.}
  1160. kPEF2StringsAreASCII = 0;
  1161. kPEF2StringsAreUnicode = 1;
  1162. { =========================================================================================== }
  1163. { Section Headers }
  1164. { =============== }
  1165. type
  1166. PEF2SectionHeaderPtr = ^PEF2SectionHeader;
  1167. PEF2SectionHeader = record
  1168. nameOffset: UInt32; { Offset of the name within the container string table.}
  1169. presumedAddress: UInt32; { Presumed address, affects relocations.}
  1170. totalLength: UInt32; { Fully expanded size in bytes of the section contents.}
  1171. unpackedLength: UInt32; { Size in bytes of the "initialized" part of the contents.}
  1172. containerLength: UInt32; { Size in bytes of the raw data in the container.}
  1173. containerOffset: UInt32; { Offset of section's raw data within the container.}
  1174. options: UInt32; { Array of 32 option bits.}
  1175. shareKind: UInt8; { Sharing level, if a writeable section.}
  1176. alignment: UInt8; { Required alignment, expressed as log 2.}
  1177. reservedA: UInt16; { Reserved, must be written as zero.}
  1178. reservedB: UInt32; { Reserved, must be written as zero.}
  1179. reservedC: UInt32; { Reserved, must be written as zero.}
  1180. end;
  1181. const
  1182. { Masks for instantiated section options.}
  1183. { Bits that define the preparation and usage of the section's contents.}
  1184. kPEF2SectionHasCodeMask = $00000001; { Affects cache flushing operations.}
  1185. kPEF2SectionIsWriteableMask = $00000002; { Affects MMU access.}
  1186. kPEF2SectionHasRelocationsMask = $00000004; { The section has runtime relocations.}
  1187. kPEF2SectionContentsArePackedMask = $00000100; { The raw data is compressed.}
  1188. kPEF2SectionNoZeroFillMask = $00000200; { "Uninit" part is not zero filled.}
  1189. kPEF2SectionResidentMask = $00000400; { The section should be RAM resident.}
  1190. { Bits that describe higher level semantics.}
  1191. kPEF2SectionFollowsPriorMask = $00010000; { Raw data is related to prior section.}
  1192. kPEF2SectionPrecedesNextMask = $00020000; { Raw data is related to next section.}
  1193. kPEF2SectionHasLoaderTablesMask = $01000000;
  1194. kPEF2SectionHasDebugTablesMask = $02000000;
  1195. kPEF2SectionHasExceptionTablesMask = $04000000;
  1196. kPEF2SectionHasTracebackTablesMask = $08000000;
  1197. const
  1198. { Values for the shareKind field.}
  1199. kPEF2PrivateShare = 0; { Shared only within a "private" closure.}
  1200. kPEF2ProcessShare = 1; { Shared within a single process.}
  1201. kPEF2GlobalShare = 4; { Shared across the entire system.}
  1202. kPEF2ProtectedShare = 5; { Readable across the entire system, writeable only to privileged code.}
  1203. { =========================================================================================== }
  1204. { Loader Section }
  1205. { ============== }
  1206. { -------------------------------------------------------------------------------------------- }
  1207. { The PEF2 loader section is very similar to that of PEF. The following overall layout is }
  1208. { not required, but suggested for typical locality of reference. The loader header contains }
  1209. { explicit offsets and sizes for each of the subsections. }
  1210. { +-----------------------------------+ }
  1211. { | Loader Info Header | }
  1212. { |-----------------------------------| }
  1213. { | Imported Library 0 | }
  1214. { |...................................| }
  1215. { | - - - | }
  1216. { |...................................| }
  1217. { | Imported Library l-1 | }
  1218. { |-----------------------------------| }
  1219. { | Imported Symbol 0 | }
  1220. { |...................................| }
  1221. { | - - - | }
  1222. { |...................................| }
  1223. { | Imported Symbol i-1 | }
  1224. { |-----------------------------------| }
  1225. { | Loader Name Table | }
  1226. { |-----------------------------------| }
  1227. { | Export Hash Slot 0 | }
  1228. { |...................................| }
  1229. { | - - - | }
  1230. { |...................................| }
  1231. { | Export Hash Slot h-1 | }
  1232. { |-----------------------------------| }
  1233. { | Exported Symbol Key 0 | }
  1234. { |...................................| }
  1235. { | - - - | }
  1236. { |...................................| }
  1237. { | Exported Symbol Key e-1 | }
  1238. { |-----------------------------------| }
  1239. { | Exported Symbol 0 | }
  1240. { |...................................| }
  1241. { | - - - | }
  1242. { |...................................| }
  1243. { | Exported Symbol e-1 | }
  1244. { |-----------------------------------| }
  1245. { | Relocation Header 0 | }
  1246. { |...................................| }
  1247. { | - - - | }
  1248. { |...................................| }
  1249. { | Relocation Header r-1 | }
  1250. { |-----------------------------------| }
  1251. { | Relocation Instructions | }
  1252. { +-----------------------------------+ }
  1253. type
  1254. PEF2LoaderInfoHeaderPtr = ^PEF2LoaderInfoHeader;
  1255. PEF2LoaderInfoHeader = record
  1256. headerSize: UInt32; { Size in bytes of the loader info header.}
  1257. options: UInt32; { An array of 32 option bits.}
  1258. mainSection: SInt32; { Section containing the main symbol, -1 => none.}
  1259. mainOffset: UInt32; { Offset of main symbol.}
  1260. initSection: SInt32; { Section containing the init routine's TVector, -1 => none.}
  1261. initOffset: UInt32; { Offset of the init routine's TVector.}
  1262. termSection: SInt32; { Section containing the term routine's TVector, -1 => none.}
  1263. termOffset: UInt32; { Offset of the term routine's TVector.}
  1264. notifySection: SInt32; { Section containing the notification routine's TVector, -1 => none.}
  1265. notifyOffset: UInt32; { Offset of the notification routine's TVector.}
  1266. importedLibrariesOffset: UInt32; { Offset of the imported library table.}
  1267. importedLibrarySize: UInt32; { The size in bytes of an imported library entry.}
  1268. importedLibraryCount: UInt32; { Number of imported libraries. ('l')}
  1269. importedSymbolsOffset: UInt32; { Offset of the imported symbol table.}
  1270. importedSymbolSize: UInt32; { The size in bytes of an imported symbol entry.}
  1271. totalImportedSymbolCount: UInt32; { Total number of imported symbols. ('s')}
  1272. loaderNamesOffset: UInt32; { Offset of the loader name table.}
  1273. loaderNamesLength: UInt32; { Total number of bytes in the loader name table.}
  1274. exportHashTableOffset: UInt32; { Offset of the export hash slot table.}
  1275. exportHashTablePower: UInt8; { Hash slot count as log 2.}
  1276. reservedA: UInt8; { Reserved, must be zero.}
  1277. reservedB: UInt16; { Reserved, must be zero.}
  1278. exportedKeysOffset: UInt32; { Offset of the exported symbol key table.}
  1279. exportedSymbolsOffset: UInt32; { Offset of the exported symbol table.}
  1280. exportedSymbolSize: UInt32; { The size in bytes of an exported symbol entry.}
  1281. exportedSymbolCount: UInt32; { Number of exported symbols. ('e')}
  1282. relocHeadersOffset: UInt32; { Offset of the relocation headers.}
  1283. relocHeaderCount: UInt32; { Number of sections with relocations.}
  1284. relocInstrOffset: UInt32; { Offset of the relocation instructions.}
  1285. relocInstrLength: UInt32; { Total number of bytes of relocation instructions.}
  1286. reservedC: UInt32; { Reserved, must be zero.}
  1287. reservedD: UInt32; { Reserved, must be zero.}
  1288. end;
  1289. const
  1290. { Masks for the option bits.}
  1291. kPEF2LdrInfoLargeImpSymMask = $00000001; { Selects large imported symbol entries.}
  1292. kPEF2LdrInfoLargeExpSymMask = $00000002; { Selects large exported symbol entries.}
  1293. kPEF2LdrInfoLargeExpHashMask = $00000004; { Selects large export hash table entries.}
  1294. { =========================================================================================== }
  1295. { Imports and Exports }
  1296. { ------------------- }
  1297. { -------------------------------------------------------------------------------------------- }
  1298. { Imports and exports in PEF2 have both small and large representations. The small form is }
  1299. { identical to original PEF. The large form removes count limitations by having full 32 bit }
  1300. { offsets. The import and export name tables have the same representation as the container }
  1301. { string table, four bytes of zero at the start followed by pairs of 32 bit hashwords and }
  1302. { the names in the appropriate encoding. }
  1303. type
  1304. PEF2ImportedLibraryPtr = ^PEF2ImportedLibrary;
  1305. PEF2ImportedLibrary = record
  1306. nameOffset: UInt32; { Imported name table offset of library's name.}
  1307. oldImpVersion: UInt32; { Oldest compatible implementation version.}
  1308. currentVersion: UInt32; { Current version at build time.}
  1309. importedSymbolCount: UInt32; { Imported symbol count for this library.}
  1310. firstImportedSymbol: UInt32; { Index of first imported symbol from this library.}
  1311. options: UInt32; { Option bits for this library.}
  1312. reservedA: UInt32; { Reserved, must be zero.}
  1313. end;
  1314. const
  1315. { Bits for the PEF2ImportedLibrary options field.}
  1316. kPEF2WeakImportLibMask = kPEFWeakImportLibMask; { The imported library is allowed to be missing.}
  1317. kPEF2InitLibBeforeMask = kPEFInitLibBeforeMask; { The imported library must be initialized first.}
  1318. type
  1319. PEF2SmImportedSymbol = PEFImportedSymbol;
  1320. // PEF2ComposeSmImportedSymbol = PEFComposeImportedSymbol;
  1321. type
  1322. PEF2LgImportedSymbolPtr = ^PEF2LgImportedSymbol;
  1323. PEF2LgImportedSymbol = record
  1324. symClass: UInt8;
  1325. flags: UInt8;
  1326. reservedA: UInt16;
  1327. nameOffset: UInt32;
  1328. versionPair: UInt32;
  1329. reservedB: UInt32;
  1330. end;
  1331. PEF2SmExportedSymbolHashSlot = PEFExportedSymbolHashSlot;
  1332. PEF2ExportedSymbolKey = PEFExportedSymbolKey;
  1333. PEF2SmExportedSymbol = PEFExportedSymbol;
  1334. // PEF2ComposeSmExportedSymbol = PEFComposeExportedSymbol;
  1335. type
  1336. PEF2LgExportedSymbolHashSlotPtr = ^PEF2LgExportedSymbolHashSlot;
  1337. PEF2LgExportedSymbolHashSlot = record
  1338. chainCount: UInt32;
  1339. chainOffset: UInt32;
  1340. end;
  1341. type
  1342. PEF2LgExportedSymbolPtr = ^PEF2LgExportedSymbol;
  1343. PEF2LgExportedSymbol = record
  1344. symClass: UInt8;
  1345. flags: UInt8;
  1346. reservedA: UInt16;
  1347. nameOffset: UInt32;
  1348. versionPair: UInt32;
  1349. sectionIndex: SInt32;
  1350. sectionOffset: UInt32;
  1351. reservedB: UInt32;
  1352. end;
  1353. { =========================================================================================== }
  1354. { Loader Relocations }
  1355. { ================== }
  1356. { -------------------------------------------------------------------------------------------- }
  1357. { The relocation header differs slightly in PEF2. The relocation instructions identical. }
  1358. type
  1359. PEF2LoaderRelocationHeaderPtr = ^PEF2LoaderRelocationHeader;
  1360. PEF2LoaderRelocationHeader = record
  1361. sectionIndex: UInt32; { Index of the section to be fixed up.}
  1362. relocLength: UInt32; { Number of bytes of relocation items.}
  1363. firstRelocOffset: UInt32; { Byte offset of first relocation instruction.}
  1364. reservedA: UInt32; { Reserved, must be zero.}
  1365. end;
  1366. { =========================================================================================== }
  1367. {$endc} {IncludePEF2Declarations}
  1368. {$endc} {TARGET_OS_MAC}
  1369. {$ifc not defined MACOSALLINCLUDE or not MACOSALLINCLUDE}
  1370. end.
  1371. {$endc} {not MACOSALLINCLUDE}