PEFBinaryFormat.pas 90 KB

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