PEFBinaryFormat.pas 90 KB

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