ogcoff.pas 113 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133
  1. {
  2. Copyright (c) 1998-2006 by Peter Vreman
  3. Contains the binary coff/PE reader and writer
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit ogcoff;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. { common }
  22. cclasses,globtype,
  23. { target }
  24. systems,
  25. { assembler }
  26. cpuinfo,cpubase,aasmbase,assemble,link,
  27. { output }
  28. ogbase,
  29. owbase;
  30. const
  31. PE_DATADIR_ENTRIES = 16;
  32. type
  33. tcoffpedatadir = packed record
  34. vaddr : longword;
  35. size : longword;
  36. end;
  37. tcoffheader = packed record
  38. mach : word;
  39. nsects : word;
  40. time : longword;
  41. sympos : longword;
  42. syms : longword;
  43. opthdr : word;
  44. flag : word;
  45. end;
  46. tcoffpeoptheader = packed record
  47. Magic : word;
  48. MajorLinkerVersion : byte;
  49. MinorLinkerVersion : byte;
  50. tsize : longword;
  51. dsize : longword;
  52. bsize : longword;
  53. entry : longword;
  54. text_start : longword;
  55. {$ifndef cpu64bitaddr}
  56. data_start : longword;
  57. {$endif cpu64bitaddr}
  58. ImageBase : aword;
  59. SectionAlignment : longword;
  60. FileAlignment : longword;
  61. MajorOperatingSystemVersion : word;
  62. MinorOperatingSystemVersion : word;
  63. MajorImageVersion : word;
  64. MinorImageVersion : word;
  65. MajorSubsystemVersion : word;
  66. MinorSubsystemVersion : word;
  67. Win32Version : longword;
  68. SizeOfImage : longword;
  69. SizeOfHeaders : longword;
  70. CheckSum : longword;
  71. Subsystem : word;
  72. DllCharacteristics : word;
  73. SizeOfStackReserve : aword;
  74. SizeOfStackCommit : aword;
  75. SizeOfHeapReserve : aword;
  76. SizeOfHeapCommit : aword;
  77. LoaderFlags : longword; { This field is obsolete }
  78. NumberOfRvaAndSizes : longword;
  79. DataDirectory : array[0..PE_DATADIR_ENTRIES-1] of tcoffpedatadir;
  80. end;
  81. tcoffsechdr = packed record
  82. name : array[0..7] of char;
  83. vsize : longword;
  84. rvaofs : longword;
  85. datasize : longword;
  86. datapos : longword;
  87. relocpos : longword;
  88. lineno1 : longword;
  89. nrelocs : word;
  90. lineno2 : word;
  91. flags : longword;
  92. end;
  93. TCoffObjSection = class(TObjSection)
  94. private
  95. orgmempos,
  96. coffrelocs,
  97. coffrelocpos : aword;
  98. public
  99. constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);override;
  100. procedure writereloc_internal(aTarget:TObjSection;offset:aword;len:byte;reltype:TObjRelocationType);override;
  101. end;
  102. TCoffObjData = class(TObjData)
  103. private
  104. win32 : boolean;
  105. {$ifdef arm}
  106. eVCobj : boolean;
  107. {$endif arm}
  108. public
  109. constructor createcoff(const n:string;awin32:boolean;acObjSection:TObjSectionClass);
  110. procedure CreateDebugSections;override;
  111. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
  112. function sectiontype2options(atype:TAsmSectiontype):TObjSectionOptions;override;
  113. procedure writereloc(data:aint;len:aword;p:TObjSymbol;reloctype:TObjRelocationType);override;
  114. end;
  115. TDJCoffObjData = class(TCoffObjData)
  116. constructor create(const n:string);override;
  117. end;
  118. TPECoffObjData = class(TCoffObjData)
  119. constructor create(const n:string);override;
  120. end;
  121. TCoffObjOutput = class(tObjOutput)
  122. private
  123. win32 : boolean;
  124. symidx : longint;
  125. FCoffSyms,
  126. FCoffStrs : tdynamicarray;
  127. procedure write_symbol(const name:string;value:aword;section:smallint;typ,aux:byte);
  128. procedure section_write_symbol(p:TObject;arg:pointer);
  129. procedure section_write_relocs(p:TObject;arg:pointer);
  130. procedure create_symbols(data:TObjData);
  131. procedure section_set_reloc_datapos(p:TCoffObjSection;var datapos:aword);
  132. procedure section_write_header(p:TObject;arg:pointer);
  133. protected
  134. function writedata(data:TObjData):boolean;override;
  135. public
  136. constructor createcoff(AWriter:TObjectWriter;awin32:boolean);
  137. destructor destroy;override;
  138. end;
  139. TDJCoffObjOutput = class(TCoffObjOutput)
  140. constructor create(AWriter:TObjectWriter);override;
  141. end;
  142. TPECoffObjOutput = class(TCoffObjOutput)
  143. constructor create(AWriter:TObjectWriter);override;
  144. end;
  145. TCoffObjInput = class(tObjInput)
  146. private
  147. FCoffsyms : tdynamicarray;
  148. FCoffStrs : PChar;
  149. FCoffStrSize: longword;
  150. { Convert symidx -> TObjSymbol }
  151. FSymTbl : ^TObjSymbolArray;
  152. { Convert secidx -> TObjSection }
  153. FSecCount : smallint;
  154. FSecTbl : ^TObjSectionArray;
  155. win32 : boolean;
  156. function GetSection(secidx:longint):TObjSection;
  157. function Read_str(strpos:longword):string;
  158. procedure read_relocs(s:TCoffObjSection);
  159. procedure read_symbols(objdata:TObjData);
  160. procedure ObjSections_read_relocs(p:TObject;arg:pointer);
  161. public
  162. constructor createcoff(awin32:boolean);
  163. destructor destroy;override;
  164. function ReadObjData(AReader:TObjectreader;out objdata:TObjData):boolean;override;
  165. end;
  166. TDJCoffObjInput = class(TCoffObjInput)
  167. constructor create;override;
  168. end;
  169. TPECoffObjInput = class(TCoffObjInput)
  170. constructor create;override;
  171. end;
  172. TCoffexeoutput = class(texeoutput)
  173. private
  174. FCoffStrs : tdynamicarray;
  175. win32 : boolean;
  176. nsects : word;
  177. nsyms,
  178. sympos : aword;
  179. datapos_offset: longword;
  180. function totalheadersize:longword;
  181. procedure ExeSectionList_pass2_header(p:TObject;arg:pointer);
  182. procedure write_symbol(const name:string;value:aword;section:smallint;typ,aux:byte);
  183. procedure globalsyms_write_symbol(p:TObject;arg:pointer);
  184. procedure ExeSectionList_write_header(p:TObject;arg:pointer);
  185. protected
  186. function writedata:boolean;override;
  187. procedure Order_ObjSectionList(ObjSectionList : TFPObjectList;const aPattern:string);override;
  188. procedure DoRelocationFixup(objsec:TObjSection);override;
  189. public
  190. constructor createcoff(awin32:boolean);
  191. procedure MemPos_Header;override;
  192. procedure DataPos_Header;override;
  193. procedure DataPos_Symbols;override;
  194. end;
  195. TDJCoffexeoutput = class(TCoffexeoutput)
  196. constructor create;override;
  197. procedure MemPos_Header;override;
  198. end;
  199. TPECoffexeoutput = class(TCoffexeoutput)
  200. private
  201. FImports: TFPHashObjectList;
  202. textobjsection,
  203. idata2objsection,
  204. idata4objsection,
  205. idata5objsection,
  206. idata6objsection,
  207. idata7objsection : TObjSection;
  208. FRelocsGenerated : boolean;
  209. procedure GenerateRelocs;
  210. public
  211. constructor create;override;
  212. procedure MarkTargetSpecificSections(WorkList:TFPObjectList);override;
  213. procedure AfterUnusedSectionRemoval;override;
  214. procedure GenerateLibraryImports(ImportLibraryList:TFPHashObjectList);override;
  215. procedure MemPos_Start;override;
  216. procedure MemPos_ExeSection(const aname:string);override;
  217. end;
  218. TObjSymbolArray = array[0..high(word)] of TObjSymbol;
  219. TObjSectionArray = array[0..high(smallint)] of TObjSection;
  220. TDJCoffAssembler = class(tinternalassembler)
  221. constructor create(info: pasminfo; smart:boolean);override;
  222. end;
  223. TPECoffassembler = class(tinternalassembler)
  224. constructor create(info: pasminfo; smart:boolean);override;
  225. end;
  226. type
  227. Treaddllproc = procedure(const dllname,funcname:string) of object;
  228. const
  229. {$ifdef i386}
  230. COFF_MAGIC = $14c;
  231. COFF_OPT_MAGIC = $10b;
  232. TLSDIR_SIZE = $18;
  233. {$endif i386}
  234. {$ifdef arm}
  235. COFF_OPT_MAGIC = $10b;
  236. TLSDIR_SIZE = $18;
  237. function COFF_MAGIC: word;
  238. {$endif arm}
  239. {$ifdef x86_64}
  240. COFF_MAGIC = $8664;
  241. COFF_OPT_MAGIC = $20b;
  242. TLSDIR_SIZE = $28;
  243. {$endif x86_64}
  244. function ReadDLLImports(const dllname:string;readdllproc:Treaddllproc):boolean;
  245. implementation
  246. uses
  247. {$ifdef win32}
  248. Windows,
  249. {$endif win32}
  250. SysUtils,
  251. cutils,verbose,globals,
  252. fmodule,aasmtai,aasmdata,
  253. ogmap,
  254. owar,
  255. version
  256. ;
  257. const
  258. COFF_FLAG_NORELOCS = $0001;
  259. COFF_FLAG_EXE = $0002;
  260. COFF_FLAG_NOLINES = $0004;
  261. COFF_FLAG_NOLSYMS = $0008;
  262. COFF_FLAG_AR16WR = $0080; { 16bit little endian }
  263. COFF_FLAG_AR32WR = $0100; { 32bit little endian }
  264. COFF_FLAG_AR32W = $0200; { 32bit big endian }
  265. COFF_FLAG_DLL = $2000;
  266. COFF_SYM_GLOBAL = 2;
  267. COFF_SYM_LOCAL = 3;
  268. COFF_SYM_LABEL = 6;
  269. COFF_SYM_FUNCTION = 101;
  270. COFF_SYM_FILE = 103;
  271. COFF_SYM_SECTION = 104;
  272. COFF_STYP_REG = $0000; { "regular": allocated, relocated, loaded }
  273. COFF_STYP_DSECT = $0001; { "dummy": relocated only }
  274. COFF_STYP_NOLOAD = $0002; { "noload": allocated, relocated, not loaded }
  275. COFF_STYP_GROUP = $0004; { "grouped": formed of input sections }
  276. COFF_STYP_PAD = $0008;
  277. COFF_STYP_COPY = $0010;
  278. COFF_STYP_TEXT = $0020;
  279. COFF_STYP_DATA = $0040;
  280. COFF_STYP_BSS = $0080;
  281. COFF_STYP_INFO = $0200;
  282. COFF_STYP_OVER = $0400;
  283. COFF_STYP_LIB = $0800;
  284. PE_SUBSYSTEM_NATIVE = 1;
  285. PE_SUBSYSTEM_WINDOWS_GUI = 2;
  286. PE_SUBSYSTEM_WINDOWS_CUI = 3;
  287. PE_SUBSYSTEM_WINDOWS_CE_GUI = 9;
  288. PE_FILE_RELOCS_STRIPPED = $0001;
  289. PE_FILE_EXECUTABLE_IMAGE = $0002;
  290. PE_FILE_LINE_NUMS_STRIPPED = $0004;
  291. PE_FILE_LOCAL_SYMS_STRIPPED = $0008;
  292. PE_FILE_AGGRESSIVE_WS_TRIM = $0010;
  293. PE_FILE_LARGE_ADDRESS_AWARE = $0020;
  294. PE_FILE_16BIT_MACHINE = $0040;
  295. PE_FILE_BYTES_REVERSED_LO = $0080;
  296. PE_FILE_32BIT_MACHINE = $0100;
  297. PE_FILE_DEBUG_STRIPPED = $0200;
  298. PE_FILE_REMOVABLE_RUN_FROM_SWAP = $0400;
  299. PE_FILE_NET_RUN_FROM_SWAP = $0800;
  300. PE_FILE_SYSTEM = $1000;
  301. PE_FILE_DLL = $2000;
  302. PE_FILE_UP_SYSTEM_ONLY = $4000;
  303. PE_FILE_BYTES_REVERSED_HI = $8000;
  304. PE_SCN_CNT_CODE = $00000020; { Section contains code. }
  305. PE_SCN_CNT_INITIALIZED_DATA = $00000040; { Section contains initialized data. }
  306. PE_SCN_CNT_UNINITIALIZED_DATA = $00000080; { Section contains uninitialized data. }
  307. PE_SCN_LNK_OTHER = $00000100; { Reserved. }
  308. PE_SCN_LNK_INFO = $00000200; { Section contains comments or some other type of information. }
  309. PE_SCN_LNK_REMOVE = $00000800; { Section contents will not become part of image. }
  310. PE_SCN_LNK_COMDAT = $00001000; { Section contents comdat. }
  311. PE_SCN_MEM_FARDATA = $00008000;
  312. PE_SCN_MEM_PURGEABLE = $00020000;
  313. PE_SCN_MEM_16BIT = $00020000;
  314. PE_SCN_MEM_LOCKED = $00040000;
  315. PE_SCN_MEM_PRELOAD = $00080000;
  316. PE_SCN_ALIGN_MASK = $00f00000;
  317. PE_SCN_ALIGN_1BYTES = $00100000;
  318. PE_SCN_ALIGN_2BYTES = $00200000;
  319. PE_SCN_ALIGN_4BYTES = $00300000;
  320. PE_SCN_ALIGN_8BYTES = $00400000;
  321. PE_SCN_ALIGN_16BYTES = $00500000; { Default alignment if no others are specified. }
  322. PE_SCN_ALIGN_32BYTES = $00600000;
  323. PE_SCN_ALIGN_64BYTES = $00700000;
  324. PE_SCN_LNK_NRELOC_OVFL = $01000000; { Section contains extended relocations. }
  325. PE_SCN_MEM_NOT_CACHED = $04000000; { Section is not cachable. }
  326. PE_SCN_MEM_NOT_PAGED = $08000000; { Section is not pageable. }
  327. PE_SCN_MEM_SHARED = $10000000; { Section is shareable. }
  328. PE_SCN_MEM_DISCARDABLE = $02000000;
  329. PE_SCN_MEM_EXECUTE = $20000000;
  330. PE_SCN_MEM_READ = $40000000;
  331. PE_SCN_MEM_WRITE = $80000000;
  332. PE_DATADIR_EDATA = 0;
  333. PE_DATADIR_IDATA = 1;
  334. PE_DATADIR_RSRC = 2;
  335. PE_DATADIR_PDATA = 3;
  336. PE_DATADIR_SECURITY = 4;
  337. PE_DATADIR_RELOC = 5;
  338. PE_DATADIR_DEBUG = 6;
  339. PE_DATADIR_DESCRIPTION = 7;
  340. PE_DATADIR_SPECIAL = 8;
  341. PE_DATADIR_TLS = 9;
  342. PE_DATADIR_LOADCFG = 10;
  343. PE_DATADIR_BOUNDIMPORT = 11;
  344. PE_DATADIR_IMPORTADDRESSTABLE = 12;
  345. PE_DATADIR_DELAYIMPORT = 13;
  346. {$ifdef x86_64}
  347. IMAGE_REL_AMD64_ABSOLUTE = $0000; { Reference is absolute, no relocation is necessary }
  348. IMAGE_REL_AMD64_ADDR64 = $0001; { 64-bit address (VA). }
  349. IMAGE_REL_AMD64_ADDR32 = $0002; { 32-bit address (VA). }
  350. IMAGE_REL_AMD64_ADDR32NB = $0003; { 32-bit address w/o image base (RVA). }
  351. IMAGE_REL_AMD64_REL32 = $0004; { 32-bit relative address from byte following reloc }
  352. IMAGE_REL_AMD64_REL32_1 = $0005; { 32-bit relative address from byte distance 1 from reloc }
  353. IMAGE_REL_AMD64_REL32_2 = $0006; { 32-bit relative address from byte distance 2 from reloc }
  354. IMAGE_REL_AMD64_REL32_3 = $0007; { 32-bit relative address from byte distance 3 from reloc }
  355. IMAGE_REL_AMD64_REL32_4 = $0008; { 32-bit relative address from byte distance 4 from reloc }
  356. IMAGE_REL_AMD64_REL32_5 = $0009; { 32-bit relative address from byte distance 5 from reloc }
  357. IMAGE_REL_AMD64_SECTION = $000A; { Section index }
  358. IMAGE_REL_AMD64_SECREL = $000B; { 32 bit offset from base of section containing target }
  359. IMAGE_REL_AMD64_SECREL7 = $000C; { 7 bit unsigned offset from base of section containing target }
  360. IMAGE_REL_AMD64_TOKEN = $000D; { 32 bit metadata token }
  361. IMAGE_REL_AMD64_SREL32 = $000E; { 32 bit signed span-dependent value emitted into object }
  362. IMAGE_REL_AMD64_PAIR = $000F;
  363. IMAGE_REL_AMD64_SSPAN32 = $0010; { 32 bit signed span-dependent value applied at link time }
  364. { Direct 32 bit sign extended,
  365. win64 mingw GNU compiler
  366. also generates this type
  367. inside coff objects
  368. We assume they are equivalent to
  369. IMAGE_REL_AMD64_ADDR32 PM 2010-11-27 }
  370. R_X86_64_32S = $11;
  371. {$endif x86_64}
  372. {$ifdef arm}
  373. IMAGE_REL_ARM_ABSOLUTE = $0000; { No relocation required }
  374. IMAGE_REL_ARM_ADDR32 = $0001; { 32 bit address }
  375. IMAGE_REL_ARM_ADDR32NB = $0002; { 32 bit address w/o image base }
  376. IMAGE_REL_ARM_BRANCH24 = $0003; { 24 bit offset << 2 & sign ext. }
  377. IMAGE_REL_ARM_BRANCH11 = $0004; { Thumb: 2 11 bit offsets }
  378. IMAGE_REL_ARM_TOKEN = $0005; { clr token }
  379. IMAGE_REL_ARM_GPREL12 = $0006; { GP-relative addressing (ARM) }
  380. IMAGE_REL_ARM_GPREL7 = $0007; { GP-relative addressing (Thumb) }
  381. IMAGE_REL_ARM_BLX24 = $0008;
  382. IMAGE_REL_ARM_BLX11 = $0009;
  383. IMAGE_REL_ARM_SECTION = $000E; { Section table index }
  384. IMAGE_REL_ARM_SECREL = $000F; { Offset within section }
  385. IMAGE_REL_ARM_MOV32A = $0010; { 32-bit VA applied to MOVW+MOVT pair, added to existing imm (ARM) }
  386. IMAGE_REL_ARM_MOV32T = $0011; { 32-bit VA applied to MOVW+MOVT pair, added to existing imm (THUMB) }
  387. IMAGE_REL_ARM_BRANCH20T = $0012; { Thumb: 20 most significant bits of 32 bit B cond instruction }
  388. IMAGE_REL_ARM_BRANCH24T = $0014; { Thumb: 24 most significant bits of 32 bit B uncond instruction }
  389. IMAGE_REL_ARM_BLX23T = $0015; { 23 most significant bits of 32 bit BL/BLX instruction. Transformed to BLX if target is Thumb }
  390. {$endif arm}
  391. {$ifdef i386}
  392. IMAGE_REL_I386_DIR32 = 6;
  393. IMAGE_REL_I386_IMAGEBASE = 7;
  394. IMAGE_REL_I386_SECREL32 = 11;
  395. IMAGE_REL_I386_PCRLONG = 20;
  396. {$endif i386}
  397. { .reloc section fixup types }
  398. IMAGE_REL_BASED_HIGHLOW = 3; { Applies the delta to the 32-bit field at Offset. }
  399. IMAGE_REL_BASED_DIR64 = 10; { Applies the delta to the 64-bit field at Offset. }
  400. { values for coffsectionrec.select }
  401. IMAGE_COMDAT_SELECT_NODUPLICATES = 1;
  402. IMAGE_COMDAT_SELECT_ANY = 2;
  403. IMAGE_COMDAT_SELECT_SAME_SIZE = 3;
  404. IMAGE_COMDAT_SELECT_EXACT_MATCH = 4;
  405. IMAGE_COMDAT_SELECT_ASSOCIATIVE = 5;
  406. IMAGE_COMDAT_SELECT_LARGEST = 6;
  407. type
  408. coffdjoptheader=packed record
  409. magic : word;
  410. vstamp : word;
  411. tsize : longint;
  412. dsize : longint;
  413. bsize : longint;
  414. entry : longint;
  415. text_start : longint;
  416. data_start : longint;
  417. end;
  418. coffsectionrec=packed record
  419. len : longword;
  420. nrelocs : word;
  421. nlines : word;
  422. checksum: longword;
  423. assoc : word;
  424. select : byte;
  425. empty : array[0..2] of char;
  426. end;
  427. coffreloc=packed record
  428. address : longword;
  429. sym : longword;
  430. reloctype : word;
  431. end;
  432. coffsymbol=packed record
  433. name : array[0..3] of char; { real is [0..7], which overlaps the strpos ! }
  434. strpos : longword;
  435. value : longword;
  436. section : smallint;
  437. empty : word; { actually type, $20: function, 0: not a function }
  438. typ : byte;
  439. aux : byte;
  440. end;
  441. { This is defined in rtl/win/sysos.inc source }
  442. tlsdirectory=packed record
  443. data_start, data_end : PUInt;
  444. index_pointer, callbacks_pointer : PUInt;
  445. zero_fill_size : dword;
  446. flags : dword;
  447. end;
  448. const
  449. SymbolMaxGrow = 200*sizeof(coffsymbol);
  450. StrsMaxGrow = 8192;
  451. coffsecnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
  452. '.text','.data','.rdata','.rdata','.bss','.tls',
  453. '.pdata',{pdata}
  454. '.text', {stub}
  455. '.data',
  456. '.data',
  457. '.data',
  458. '.data',
  459. '.stab','.stabstr',
  460. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  461. '.eh_frame',
  462. '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
  463. '.fpc',
  464. '',
  465. '.init',
  466. '.fini',
  467. '.objc_class',
  468. '.objc_meta_class',
  469. '.objc_cat_cls_meth',
  470. '.objc_cat_inst_meth',
  471. '.objc_protocol',
  472. '.objc_string_object',
  473. '.objc_cls_meth',
  474. '.objc_inst_meth',
  475. '.objc_cls_refs',
  476. '.objc_message_refs',
  477. '.objc_symbols',
  478. '.objc_category',
  479. '.objc_class_vars',
  480. '.objc_instance_vars',
  481. '.objc_module_info',
  482. '.objc_class_names',
  483. '.objc_meth_var_types',
  484. '.objc_meth_var_names',
  485. '.objc_selector_strs',
  486. '.objc_protocol_ext',
  487. '.objc_class_ext',
  488. '.objc_property',
  489. '.objc_image_info',
  490. '.objc_cstring_object',
  491. '.objc_sel_fixup',
  492. '__DATA,__objc_data',
  493. '__DATA,__objc_const',
  494. '.objc_superrefs',
  495. '__DATA, __datacoal_nt,coalesced',
  496. '.objc_classlist',
  497. '.objc_nlclasslist',
  498. '.objc_catlist',
  499. '.obcj_nlcatlist',
  500. '.objc_protolist',
  501. '.stack',
  502. '.heap'
  503. );
  504. const go32v2stub : array[0..2047] of byte=(
  505. $4D,$5A,$00,$00,$04,$00,$00,$00,$20,$00,$27,$00,$FF,$FF,$00,
  506. $00,$60,$07,$00,$00,$54,$00,$00,$00,$00,$00,$00,$00,$0D,$0A,
  507. $73,$74,$75,$62,$2E,$68,$20,$67,$65,$6E,$65,$72,$61,$74,$65,
  508. $64,$20,$66,$72,$6F,$6D,$20,$73,$74,$75,$62,$2E,$61,$73,$6D,
  509. $20,$62,$79,$20,$64,$6A,$61,$73,$6D,$2C,$20,$6F,$6E,$20,$54,
  510. $68,$75,$20,$44,$65,$63,$20,$20,$39,$20,$31,$30,$3A,$35,$39,
  511. $3A,$33,$31,$20,$31,$39,$39,$39,$0D,$0A,$54,$68,$65,$20,$53,
  512. $54,$55,$42,$2E,$45,$58,$45,$20,$73,$74,$75,$62,$20,$6C,$6F,
  513. $61,$64,$65,$72,$20,$69,$73,$20,$43,$6F,$70,$79,$72,$69,$67,
  514. $68,$74,$20,$28,$43,$29,$20,$31,$39,$39,$33,$2D,$31,$39,$39,
  515. $35,$20,$44,$4A,$20,$44,$65,$6C,$6F,$72,$69,$65,$2E,$20,$0D,
  516. $0A,$50,$65,$72,$6D,$69,$73,$73,$69,$6F,$6E,$20,$67,$72,$61,
  517. $6E,$74,$65,$64,$20,$74,$6F,$20,$75,$73,$65,$20,$66,$6F,$72,
  518. $20,$61,$6E,$79,$20,$70,$75,$72,$70,$6F,$73,$65,$20,$70,$72,
  519. $6F,$76,$69,$64,$65,$64,$20,$74,$68,$69,$73,$20,$63,$6F,$70,
  520. $79,$72,$69,$67,$68,$74,$20,$0D,$0A,$72,$65,$6D,$61,$69,$6E,
  521. $73,$20,$70,$72,$65,$73,$65,$6E,$74,$20,$61,$6E,$64,$20,$75,
  522. $6E,$6D,$6F,$64,$69,$66,$69,$65,$64,$2E,$20,$0D,$0A,$54,$68,
  523. $69,$73,$20,$6F,$6E,$6C,$79,$20,$61,$70,$70,$6C,$69,$65,$73,
  524. $20,$74,$6F,$20,$74,$68,$65,$20,$73,$74,$75,$62,$2C,$20,$61,
  525. $6E,$64,$20,$6E,$6F,$74,$20,$6E,$65,$63,$65,$73,$73,$61,$72,
  526. $69,$6C,$79,$20,$74,$68,$65,$20,$77,$68,$6F,$6C,$65,$20,$70,
  527. $72,$6F,$67,$72,$61,$6D,$2E,$0A,$0D,$0A,$24,$49,$64,$3A,$20,
  528. $73,$74,$75,$62,$2E,$61,$73,$6D,$20,$62,$75,$69,$6C,$74,$20,
  529. $31,$32,$2F,$30,$39,$2F,$39,$39,$20,$31,$30,$3A,$35,$39,$3A,
  530. $33,$31,$20,$62,$79,$20,$64,$6A,$61,$73,$6D,$20,$24,$0A,$0D,
  531. $0A,$40,$28,$23,$29,$20,$73,$74,$75,$62,$2E,$61,$73,$6D,$20,
  532. $62,$75,$69,$6C,$74,$20,$31,$32,$2F,$30,$39,$2F,$39,$39,$20,
  533. $31,$30,$3A,$35,$39,$3A,$33,$31,$20,$62,$79,$20,$64,$6A,$61,
  534. $73,$6D,$0A,$0D,$0A,$1A,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  535. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  536. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  537. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  538. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  539. $00,$00,$67,$6F,$33,$32,$73,$74,$75,$62,$2C,$20,$76,$20,$32,
  540. $2E,$30,$32,$54,$00,$00,$00,$00,$00,$08,$00,$00,$00,$00,$00,
  541. $00,$00,$00,$00,$00,$40,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  542. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  543. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$43,$57,$53,$44,$50,
  544. $4D,$49,$2E,$45,$58,$45,$00,$00,$00,$00,$00,$0E,$1F,$8C,$1E,
  545. $24,$00,$8C,$06,$60,$07,$FC,$B4,$30,$CD,$21,$3C,$03,$73,$08,
  546. $B0,$6D,$BA,$A7,$05,$E9,$D4,$03,$A2,$69,$08,$BE,$20,$00,$8B,
  547. $04,$09,$C0,$75,$02,$B4,$FE,$BB,$70,$08,$39,$C3,$73,$02,$89,
  548. $C3,$89,$1C,$FE,$C7,$B9,$04,$FF,$D3,$EB,$B4,$4A,$CD,$21,$73,
  549. $08,$D3,$E3,$FE,$CF,$89,$1C,$EB,$D8,$26,$8E,$06,$2C,$00,$31,
  550. $FF,$30,$C0,$A9,$F2,$AE,$26,$81,$3D,$50,$41,$75,$15,$AF,$26,
  551. $81,$3D,$54,$48,$75,$0D,$AF,$26,$80,$3D,$3D,$75,$06,$47,$89,
  552. $3E,$8C,$04,$4F,$AE,$75,$DF,$AF,$B4,$3E,$BB,$13,$00,$CD,$21,
  553. $B4,$3E,$BB,$12,$00,$CD,$21,$06,$57,$31,$C9,$74,$12,$B0,$6E,
  554. $BA,$7E,$05,$E9,$5E,$03,$09,$C9,$75,$F4,$41,$E8,$A1,$03,$72,
  555. $EE,$B8,$87,$16,$CD,$2F,$09,$C0,$75,$ED,$80,$E3,$01,$74,$E8,
  556. $89,$3E,$00,$06,$8C,$06,$02,$06,$89,$36,$04,$06,$5F,$07,$E8,
  557. $D3,$02,$89,$3E,$2A,$00,$89,$36,$62,$07,$80,$3E,$2C,$00,$00,
  558. $74,$23,$B9,$08,$00,$BF,$2C,$00,$8A,$05,$47,$08,$C0,$74,$05,
  559. $88,$07,$43,$E2,$F4,$66,$C7,$07,$2E,$45,$58,$45,$83,$C3,$04,
  560. $C6,$07,$00,$89,$1E,$62,$07,$B8,$00,$3D,$BA,$64,$07,$CD,$21,
  561. $0F,$82,$B3,$02,$A3,$06,$06,$89,$C3,$B9,$06,$00,$BA,$B5,$07,
  562. $B4,$3F,$CD,$21,$31,$D2,$31,$C9,$A1,$B5,$07,$3D,$4C,$01,$74,
  563. $1B,$3D,$4D,$5A,$0F,$85,$98,$02,$8B,$16,$B9,$07,$C1,$E2,$09,
  564. $8B,$1E,$B7,$07,$09,$DB,$74,$05,$80,$EE,$02,$01,$DA,$89,$16,
  565. $BB,$07,$89,$0E,$BD,$07,$B8,$00,$42,$8B,$1E,$06,$06,$CD,$21,
  566. $B9,$A8,$00,$BA,$BF,$07,$B4,$3F,$CD,$21,$3D,$A8,$00,$75,$06,
  567. $81,$3E,$BF,$07,$4C,$01,$0F,$85,$61,$02,$66,$A1,$E3,$07,$66,
  568. $A3,$10,$06,$66,$8B,$0E,$BB,$07,$66,$A1,$03,$08,$66,$01,$C8,
  569. $66,$A3,$08,$06,$66,$A1,$2B,$08,$66,$01,$C8,$66,$A3,$0C,$06,
  570. $66,$8B,$1E,$4B,$08,$66,$A1,$4F,$08,$66,$01,$C3,$66,$B8,$01,
  571. $00,$01,$00,$66,$39,$C3,$73,$03,$66,$89,$C3,$66,$81,$C3,$FF,
  572. $FF,$00,$00,$31,$DB,$66,$89,$1E,$1C,$00,$E8,$F5,$02,$8B,$1E,
  573. $04,$06,$09,$DB,$74,$0A,$B4,$48,$CD,$21,$0F,$82,$15,$02,$8E,
  574. $C0,$E8,$08,$03,$B8,$01,$00,$FF,$1E,$00,$06,$0F,$82,$0F,$02,
  575. $8C,$06,$26,$00,$8C,$0E,$28,$00,$8C,$D8,$A3,$22,$00,$8E,$C0,
  576. $31,$C0,$B9,$01,$00,$CD,$31,$72,$07,$A3,$14,$06,$31,$C0,$CD,
  577. $31,$0F,$82,$F3,$01,$A3,$16,$06,$66,$8B,$0E,$1C,$00,$B8,$01,
  578. $05,$8B,$1E,$1E,$00,$CD,$31,$0F,$82,$E5,$01,$89,$1E,$1A,$06,
  579. $89,$0E,$18,$06,$89,$36,$1A,$00,$89,$3E,$18,$00,$B8,$07,$00,
  580. $8B,$1E,$14,$06,$8B,$0E,$1A,$06,$8B,$16,$18,$06,$CD,$31,$B8,
  581. $09,$00,$8C,$C9,$83,$E1,$03,$C1,$E1,$05,$51,$81,$C9,$9B,$C0,
  582. $CD,$31,$B8,$08,$00,$8B,$0E,$1E,$00,$49,$BA,$FF,$FF,$CD,$31,
  583. $B8,$07,$00,$8B,$1E,$16,$06,$8B,$0E,$1A,$06,$8B,$16,$18,$06,
  584. $CD,$31,$B8,$09,$00,$59,$81,$C9,$93,$C0,$CD,$31,$B8,$08,$00,
  585. $8B,$0E,$1E,$00,$49,$BA,$FF,$FF,$CD,$31,$B8,$00,$01,$BB,$00,
  586. $0F,$CD,$31,$73,$10,$3D,$08,$00,$0F,$85,$73,$01,$B8,$00,$01,
  587. $CD,$31,$0F,$82,$6A,$01,$A3,$1C,$06,$89,$16,$1E,$06,$C1,$E3,
  588. $04,$89,$1E,$20,$06,$66,$8B,$36,$08,$06,$66,$8B,$3E,$FB,$07,
  589. $66,$8B,$0E,$FF,$07,$E8,$49,$00,$66,$8B,$36,$0C,$06,$66,$8B,
  590. $3E,$23,$08,$66,$8B,$0E,$27,$08,$E8,$37,$00,$8E,$06,$16,$06,
  591. $66,$8B,$3E,$4B,$08,$66,$8B,$0E,$4F,$08,$66,$31,$C0,$66,$C1,
  592. $E9,$02,$67,$F3,$66,$AB,$B4,$3E,$8B,$1E,$06,$06,$CD,$21,$B8,
  593. $01,$01,$8B,$16,$1E,$06,$CD,$31,$1E,$0F,$A1,$8E,$1E,$16,$06,
  594. $66,$64,$FF,$2E,$10,$06,$66,$89,$F0,$66,$25,$FF,$01,$00,$00,
  595. $66,$01,$C1,$29,$C6,$66,$29,$C7,$66,$89,$0E,$26,$06,$66,$89,
  596. $3E,$22,$06,$E8,$0F,$01,$89,$36,$3E,$06,$66,$C1,$EE,$10,$89,
  597. $36,$42,$06,$8B,$1E,$06,$06,$89,$1E,$3A,$06,$C7,$06,$46,$06,
  598. $00,$42,$E8,$03,$01,$A1,$1C,$06,$A3,$4E,$06,$C7,$06,$3E,$06,
  599. $00,$00,$C6,$06,$47,$06,$3F,$A1,$28,$06,$09,$C0,$75,$09,$A1,
  600. $26,$06,$3B,$06,$20,$06,$76,$03,$A1,$20,$06,$A3,$42,$06,$E8,
  601. $D9,$00,$66,$31,$C9,$8B,$0E,$46,$06,$66,$8B,$3E,$22,$06,$66,
  602. $01,$0E,$22,$06,$66,$29,$0E,$26,$06,$66,$31,$F6,$C1,$E9,$02,
  603. $1E,$06,$8E,$06,$16,$06,$8E,$1E,$1E,$06,$67,$F3,$66,$A5,$07,
  604. $1F,$66,$03,$0E,$26,$06,$75,$AF,$C3,$3C,$3A,$74,$06,$3C,$2F,
  605. $74,$02,$3C,$5C,$C3,$BE,$64,$07,$89,$F3,$26,$8A,$05,$47,$88,
  606. $04,$38,$E0,$74,$0E,$08,$C0,$74,$0A,$46,$E8,$DE,$FF,$75,$EC,
  607. $89,$F3,$74,$E8,$C3,$B0,$66,$BA,$48,$05,$EB,$0C,$B0,$67,$BA,
  608. $55,$05,$EB,$05,$B0,$68,$BA,$5F,$05,$52,$8B,$1E,$62,$07,$C6,
  609. $07,$24,$BB,$64,$07,$EB,$28,$E8,$F5,$00,$B0,$69,$BA,$99,$05,
  610. $EB,$1A,$B0,$6A,$BA,$B2,$05,$EB,$13,$B0,$6B,$BA,$C4,$05,$EB,
  611. $0C,$B0,$6C,$BA,$D6,$05,$EB,$05,$B0,$69,$BA,$99,$05,$52,$BB,
  612. $3B,$05,$E8,$15,$00,$5B,$E8,$11,$00,$BB,$67,$04,$E8,$0B,$00,
  613. $B4,$4C,$CD,$21,$43,$50,$B4,$02,$CD,$21,$58,$8A,$17,$80,$FA,
  614. $24,$75,$F2,$C3,$0D,$0A,$24,$50,$51,$57,$31,$C0,$BF,$2A,$06,
  615. $B9,$19,$00,$F3,$AB,$5F,$59,$58,$C3,$B8,$00,$03,$BB,$21,$00,
  616. $31,$C9,$66,$BF,$2A,$06,$00,$00,$CD,$31,$C3,$00,$00,$30,$E4,
  617. $E8,$4E,$FF,$89,$DE,$8B,$3E,$8C,$04,$EB,$17,$B4,$3B,$E8,$41,
  618. $FF,$81,$FE,$64,$07,$74,$12,$8A,$44,$FF,$E8,$2A,$FF,$74,$04,
  619. $C6,$04,$5C,$46,$E8,$03,$00,$72,$E4,$C3,$E8,$34,$00,$BB,$44,
  620. $00,$8A,$07,$88,$04,$43,$46,$08,$C0,$75,$F6,$06,$57,$1E,$07,
  621. $E8,$9B,$FF,$BB,$2A,$06,$8C,$5F,$04,$89,$5F,$02,$BA,$64,$07,
  622. $B8,$00,$4B,$CD,$21,$5F,$07,$72,$09,$B4,$4D,$CD,$21,$2D,$00,
  623. $03,$F7,$D8,$EB,$28,$80,$3E,$69,$08,$05,$72,$20,$B8,$00,$58,
  624. $CD,$21,$A2,$67,$08,$B8,$02,$58,$CD,$21,$A2,$68,$08,$B8,$01,
  625. $58,$BB,$80,$00,$CD,$21,$B8,$03,$58,$BB,$01,$00,$CD,$21,$C3,
  626. $9C,$80,$3E,$69,$08,$05,$72,$1A,$50,$53,$B8,$03,$58,$8A,$1E,
  627. $68,$08,$30,$FF,$CD,$21,$B8,$01,$58,$8A,$1E,$67,$08,$30,$FF,
  628. $CD,$21,$5B,$58,$9D,$C3,$4C,$6F,$61,$64,$20,$65,$72,$72,$6F,
  629. $72,$3A,$20,$24,$3A,$20,$63,$61,$6E,$27,$74,$20,$6F,$70,$65,
  630. $6E,$24,$3A,$20,$6E,$6F,$74,$20,$45,$58,$45,$24,$3A,$20,$6E,
  631. $6F,$74,$20,$43,$4F,$46,$46,$20,$28,$43,$68,$65,$63,$6B,$20,
  632. $66,$6F,$72,$20,$76,$69,$72,$75,$73,$65,$73,$29,$24,$6E,$6F,
  633. $20,$44,$50,$4D,$49,$20,$2D,$20,$47,$65,$74,$20,$63,$73,$64,
  634. $70,$6D,$69,$2A,$62,$2E,$7A,$69,$70,$24,$6E,$6F,$20,$44,$4F,
  635. $53,$20,$6D,$65,$6D,$6F,$72,$79,$24,$6E,$65,$65,$64,$20,$44,
  636. $4F,$53,$20,$33,$24,$63,$61,$6E,$27,$74,$20,$73,$77,$69,$74,
  637. $63,$68,$20,$6D,$6F,$64,$65,$24,$6E,$6F,$20,$44,$50,$4D,$49,
  638. $20,$73,$65,$6C,$65,$63,$74,$6F,$72,$73,$24,$6E,$6F,$20,$44,
  639. $50,$4D,$49,$20,$6D,$65,$6D,$6F,$72,$79,$24,$90,$90,$90,$90,
  640. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  641. $90,$90,$90,$90,$90,$90,$90,$90);
  642. const win32stub : array[0..127] of byte=(
  643. $4D,$5A,$90,$00,$03,$00,$00,$00,$04,$00,$00,$00,$FF,$FF,$00,$00,
  644. $B8,$00,$00,$00,$00,$00,$00,$00,$40,$00,$00,$00,$00,$00,$00,$00,
  645. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  646. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$80,$00,$00,$00,
  647. $0E,$1F,$BA,$0E,$00,$B4,$09,$CD,$21,$B8,$01,$4C,$CD,$21,$54,$68,
  648. $69,$73,$20,$70,$72,$6F,$67,$72,$61,$6D,$20,$63,$61,$6E,$6E,$6F,
  649. $74,$20,$62,$65,$20,$72,$75,$6E,$20,$69,$6E,$20,$44,$4F,$53,$20,
  650. $6D,$6F,$64,$65,$2E,$0D,$0D,$0A,$24,$00,$00,$00,$00,$00,$00,$00);
  651. const pemagic : array[0..3] of byte = (
  652. $50,$45,$00,$00);
  653. {****************************************************************************
  654. Helpers
  655. ****************************************************************************}
  656. function djencodesechdrflags(aoptions:TObjSectionOptions):longword;
  657. begin
  658. if (oso_load in aoptions) then
  659. begin
  660. if oso_executable in aoptions then
  661. result:=COFF_STYP_TEXT
  662. else if not(oso_data in aoptions) then
  663. result:=COFF_STYP_BSS
  664. else
  665. result:=COFF_STYP_DATA;
  666. end
  667. else if oso_debug in aoptions then
  668. result:=COFF_STYP_INFO
  669. else
  670. result:=COFF_STYP_REG;
  671. end;
  672. function djdecodesechdrflags(const aname:string;flags:longword):TObjSectionOptions;
  673. begin
  674. result:=[];
  675. if flags and COFF_STYP_TEXT<>0 then
  676. result:=[oso_data,oso_load,oso_executable]
  677. else if flags and COFF_STYP_BSS<>0 then
  678. result:=[oso_load]
  679. else if flags and COFF_STYP_DATA<>0 then
  680. result:=[oso_data,oso_load]
  681. else if flags and COFF_STYP_INFO<>0 then
  682. result:=[oso_data,oso_debug]
  683. else
  684. result:=[oso_data]
  685. end;
  686. function peencodesechdrflags(aoptions:TObjSectionOptions;aalign:shortint):longword;
  687. begin
  688. if oso_executable in aoptions then
  689. result:=PE_SCN_CNT_CODE or PE_SCN_MEM_EXECUTE
  690. else
  691. begin
  692. if (oso_data in aoptions) then
  693. result:=PE_SCN_CNT_INITIALIZED_DATA
  694. else
  695. result:=PE_SCN_CNT_UNINITIALIZED_DATA;
  696. end;
  697. if oso_write in aoptions then
  698. result:=result or PE_SCN_MEM_WRITE or PE_SCN_MEM_READ
  699. else
  700. result:=result or PE_SCN_MEM_READ;
  701. if not (oso_load in aoptions) then
  702. result:=result or PE_SCN_MEM_DISCARDABLE;
  703. case aalign of
  704. 1 : result:=result or PE_SCN_ALIGN_1BYTES;
  705. 2 : result:=result or PE_SCN_ALIGN_2BYTES;
  706. 4 : result:=result or PE_SCN_ALIGN_4BYTES;
  707. 8 : result:=result or PE_SCN_ALIGN_8BYTES;
  708. 16 : result:=result or PE_SCN_ALIGN_16BYTES;
  709. 32 : result:=result or PE_SCN_ALIGN_32BYTES;
  710. 64 : result:=result or PE_SCN_ALIGN_64BYTES;
  711. else result:=result or PE_SCN_ALIGN_16BYTES;
  712. end;
  713. end;
  714. procedure pedecodesechdrflags(const aname:string;flags:longword;out aoptions:TObjSectionOptions;out aalign:shortint);
  715. var
  716. alignflag : longword;
  717. begin
  718. aoptions:=[];
  719. if flags and PE_SCN_CNT_CODE<>0 then
  720. include(aoptions,oso_executable);
  721. if flags and PE_SCN_MEM_DISCARDABLE<>0 then
  722. include(aoptions,oso_debug);
  723. if flags and PE_SCN_CNT_UNINITIALIZED_DATA=0 then
  724. include(aoptions,oso_data);
  725. if (flags and (PE_SCN_LNK_REMOVE or PE_SCN_MEM_DISCARDABLE)=0) then
  726. include(aoptions,oso_load);
  727. { read/write }
  728. if flags and PE_SCN_MEM_WRITE<>0 then
  729. include(aoptions,oso_write);
  730. { alignment }
  731. alignflag:=flags and PE_SCN_ALIGN_MASK;
  732. if alignflag=PE_SCN_ALIGN_64BYTES then
  733. aalign:=64
  734. else if alignflag=PE_SCN_ALIGN_32BYTES then
  735. aalign:=32
  736. else if alignflag=PE_SCN_ALIGN_16BYTES then
  737. aalign:=16
  738. else if alignflag=PE_SCN_ALIGN_8BYTES then
  739. aalign:=8
  740. else if alignflag=PE_SCN_ALIGN_4BYTES then
  741. aalign:=4
  742. else if alignflag=PE_SCN_ALIGN_2BYTES then
  743. aalign:=2
  744. else if alignflag=PE_SCN_ALIGN_1BYTES then
  745. aalign:=1
  746. else if alignflag=0 then
  747. aalign:=0
  748. else
  749. Internalerror(2009050401);
  750. end;
  751. {****************************************************************************
  752. TCoffObjSection
  753. ****************************************************************************}
  754. constructor TCoffObjSection.create(AList:TFPHashObjectList;const aname:string;aalign:shortint;aoptions:TObjSectionOptions);
  755. begin
  756. inherited create(AList,aname,aalign,aoptions);
  757. end;
  758. procedure TCoffObjSection.writereloc_internal(aTarget:TObjSection;offset:aword;len:byte;reltype:TObjRelocationType);
  759. begin
  760. AddSectionReloc(size,aTarget,reltype);
  761. write(offset,len);
  762. end;
  763. { We don't want overflow nor range checks here,
  764. wrapping is accepted in the address computation below }
  765. {$r-}
  766. {$q-}
  767. procedure TCoffExeOutput.DoRelocationFixup(objsec:TObjSection);
  768. var
  769. i,zero,address_size : longint;
  770. objreloc : TObjRelocation;
  771. address,
  772. relocval : aint;
  773. {$ifdef arm}
  774. addend : aint;
  775. {$endif arm}
  776. relocsec : TObjSection;
  777. {$ifdef cpu64bitaddr}
  778. s : string;
  779. {$endif cpu64bitaddr}
  780. data : TDynamicArray;
  781. begin
  782. data:=objsec.data;
  783. for i:=0 to objsec.ObjRelocations.Count-1 do
  784. begin
  785. objreloc:=TObjRelocation(objsec.ObjRelocations[i]);
  786. address_size:=4;
  787. case objreloc.typ of
  788. RELOC_NONE:
  789. continue;
  790. RELOC_ZERO:
  791. begin
  792. data.Seek(objreloc.dataoffset);
  793. zero:=0;
  794. data.Write(zero,4);
  795. continue;
  796. end;
  797. {$ifdef cpu64bitaddr}
  798. RELOC_ABSOLUTE:
  799. address_size:=8;
  800. {$endif cpu64bitaddr}
  801. end;
  802. address:=0;
  803. data.Seek(objreloc.dataoffset);
  804. data.Read(address,address_size);
  805. if assigned(objreloc.symbol) then
  806. begin
  807. relocsec:=objreloc.symbol.objsection;
  808. relocval:=objreloc.symbol.address;
  809. end
  810. else
  811. if assigned(objreloc.objsection) then
  812. begin
  813. relocsec:=objreloc.objsection;
  814. relocval:=objreloc.objsection.mempos
  815. end
  816. else
  817. internalerror(200205183);
  818. { Only debug sections are allowed to have relocs pointing to unused sections }
  819. if not relocsec.used and not (oso_debug in objsec.secoptions) then
  820. internalerror(200603061);
  821. if relocsec.used then
  822. case objreloc.typ of
  823. RELOC_RELATIVE :
  824. begin
  825. address:=address-objsec.mempos+relocval;
  826. if win32 then
  827. dec(address,objreloc.dataoffset+4);
  828. end;
  829. RELOC_RVA:
  830. begin
  831. { fixup address when the symbol was known in defined object }
  832. if (relocsec.objdata=objsec.objdata) then
  833. dec(address,TCoffObjSection(relocsec).orgmempos);
  834. {$ifdef arm}
  835. if (relocsec.objdata=objsec.objdata) and not TCoffObjData(objsec.objdata).eVCobj then
  836. inc(address, relocsec.MemPos)
  837. else
  838. {$endif arm}
  839. inc(address,relocval);
  840. end;
  841. RELOC_SECREL32 :
  842. begin
  843. { fixup address when the symbol was known in defined object }
  844. if (relocsec.objdata=objsec.objdata) then
  845. dec(address,relocsec.ExeSection.MemPos);
  846. inc(address,relocval);
  847. end;
  848. {$ifdef arm}
  849. RELOC_RELATIVE_24,
  850. RELOC_RELATIVE_CALL:
  851. begin
  852. addend:=sarlongint(((address and $ffffff) shl 8),6); // Sign-extend while shifting left twice
  853. relocval:=longint(relocval - objsec.mempos - objreloc.dataoffset + addend) shr 2;
  854. address:=(address and $ff000000) or (relocval and $ffffff);
  855. relocval:=relocval shr 24;
  856. if (relocval<>$3f) and (relocval<>0) then
  857. internalerror(200606085); { offset overflow }
  858. end;
  859. RELOC_RELATIVE_24_THUMB,
  860. RELOC_RELATIVE_CALL_THUMB:
  861. begin
  862. addend:=sarlongint(((address and $ffffff) shl 8),6); // Sign-extend while shifting left twice, the assembler never sets the H bit
  863. relocval:=longint(relocval - objsec.mempos - objreloc.dataoffset + addend) shr 1;
  864. address:=(address and $ff000000) or ((relocval shr 1) and $ffffff) or ((relocval and 1) shl 24);
  865. relocval:=relocval shr 25;
  866. if (relocval<>$3f) and (relocval<>0) then
  867. internalerror(200606085); { offset overflow }
  868. end;
  869. {$endif arm}
  870. {$ifdef x86_64}
  871. { 64 bit coff only }
  872. RELOC_RELATIVE_1:
  873. begin
  874. address:=address-objsec.mempos+relocval;
  875. dec(address,objreloc.dataoffset+5);
  876. end;
  877. RELOC_RELATIVE_2:
  878. begin
  879. address:=address-objsec.mempos+relocval;
  880. dec(address,objreloc.dataoffset+6);
  881. end;
  882. RELOC_RELATIVE_3:
  883. begin
  884. address:=address-objsec.mempos+relocval;
  885. dec(address,objreloc.dataoffset+7);
  886. end;
  887. RELOC_RELATIVE_4:
  888. begin
  889. address:=address-objsec.mempos+relocval;
  890. dec(address,objreloc.dataoffset+8);
  891. end;
  892. RELOC_RELATIVE_5:
  893. begin
  894. address:=address-objsec.mempos+relocval;
  895. dec(address,objreloc.dataoffset+9);
  896. end;
  897. RELOC_ABSOLUTE32,
  898. {$endif x86_64}
  899. RELOC_ABSOLUTE :
  900. begin
  901. if (not win32) and assigned(objreloc.symbol) and
  902. (objreloc.symbol.bind=AB_COMMON) then
  903. begin
  904. dec(address,objreloc.symbol.size);
  905. end
  906. else
  907. begin
  908. { fixup address when the symbol was known in defined object }
  909. if (relocsec.objdata=objsec.objdata) then
  910. dec(address,TCoffObjSection(relocsec).orgmempos);
  911. end;
  912. {$ifdef arm}
  913. if (relocsec.objdata=objsec.objdata) and not TCoffObjData(objsec.objdata).eVCobj then
  914. inc(address, relocsec.MemPos)
  915. else
  916. {$endif arm}
  917. inc(address,relocval);
  918. inc(address,imagebase);
  919. end;
  920. else
  921. internalerror(200604014);
  922. end
  923. else
  924. address:=0; { Relocation in debug section points to unused section, which is eliminated by linker }
  925. data.Seek(objreloc.dataoffset);
  926. data.Write(address,address_size);
  927. {$ifdef cpu64bitaddr}
  928. if (objreloc.typ = RELOC_ABSOLUTE32) and (objsec.name <> '.stab') then
  929. begin
  930. if assigned(objreloc.symbol) then
  931. s:=objreloc.symbol.Name
  932. else
  933. s:=objreloc.objsection.Name;
  934. Message2(link_w_32bit_absolute_reloc, objsec.ObjData.Name, s);
  935. end;
  936. {$endif cpu64bitaddr}
  937. end;
  938. end;
  939. {****************************************************************************
  940. TCoffObjData
  941. ****************************************************************************}
  942. constructor TCoffObjData.createcoff(const n:string;awin32:boolean;acObjSection:TObjSectionClass);
  943. begin
  944. inherited create(n);
  945. CObjSection:=ACObjSection;
  946. win32:=awin32;
  947. end;
  948. function TCoffObjData.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  949. var
  950. sep : string[3];
  951. secname : string;
  952. begin
  953. { section type user gives the user full controll on the section name }
  954. if atype=sec_user then
  955. result:=aname
  956. else
  957. begin
  958. { non-PECOFF targets lack rodata support }
  959. if (atype in [sec_rodata,sec_rodata_norel]) and
  960. not (target_info.system in systems_all_windows) then
  961. atype:=sec_data;
  962. secname:=coffsecnames[atype];
  963. if create_smartlink_sections and
  964. (aname<>'') then
  965. begin
  966. case aorder of
  967. secorder_begin :
  968. sep:='.b_';
  969. secorder_end :
  970. sep:='.z_';
  971. else
  972. sep:='.n_';
  973. end;
  974. result:=secname+sep+aname
  975. end
  976. else
  977. result:=secname;
  978. end;
  979. end;
  980. function TCoffObjData.sectiontype2options(aType:TAsmSectionType): TObjSectionOptions;
  981. begin
  982. if (aType in [sec_rodata,sec_rodata_norel]) then
  983. begin
  984. if (target_info.system in systems_all_windows) then
  985. aType:=sec_rodata_norel
  986. else
  987. aType:=sec_data;
  988. end;
  989. result:=inherited sectiontype2options(aType);
  990. end;
  991. procedure TCoffObjData.CreateDebugSections;
  992. begin
  993. if target_dbg.id=dbg_stabs then
  994. begin
  995. stabssec:=createsection(sec_stab);
  996. stabstrsec:=createsection(sec_stabstr);
  997. end;
  998. end;
  999. procedure TCoffObjData.writereloc(data:aint;len:aword;p:TObjSymbol;reloctype:TObjRelocationType);
  1000. var
  1001. curraddr,
  1002. symaddr : aword;
  1003. begin
  1004. if CurrObjSec=nil then
  1005. internalerror(200403072);
  1006. if assigned(p) then
  1007. begin
  1008. { current address }
  1009. curraddr:=CurrObjSec.mempos+CurrObjSec.Size;
  1010. { external/common symbols don't have a fixed memory position yet }
  1011. if (p.bind=AB_COMMON) then
  1012. begin
  1013. { For go32v2 we need to use the size as address }
  1014. if not win32 then
  1015. symaddr:=p.size
  1016. else
  1017. symaddr:=0;
  1018. end
  1019. else
  1020. symaddr:=p.address;
  1021. { no symbol relocation need inside a section }
  1022. if (p.objsection=CurrObjSec) and
  1023. (p.bind<>AB_COMMON) then
  1024. begin
  1025. case reloctype of
  1026. RELOC_ABSOLUTE :
  1027. begin
  1028. CurrObjSec.addsectionreloc(curraddr,CurrObjSec,RELOC_ABSOLUTE);
  1029. inc(data,symaddr);
  1030. end;
  1031. {$ifdef cpu64bitaddr}
  1032. RELOC_ABSOLUTE32 :
  1033. begin
  1034. CurrObjSec.addsectionreloc(curraddr,CurrObjSec,RELOC_ABSOLUTE32);
  1035. inc(data,symaddr);
  1036. end;
  1037. {$endif cpu64bitaddr}
  1038. RELOC_RELATIVE :
  1039. begin
  1040. //inc(data,symaddr-len-CurrObjSec.Size);
  1041. data:=data+symaddr-len-CurrObjSec.Size;
  1042. end;
  1043. {$ifdef ARM}
  1044. RELOC_RELATIVE_24,
  1045. RELOC_RELATIVE_CALL:
  1046. begin
  1047. data:=(data and $ff000000) or (((((data and $ffffff) shl 2)+(symaddr-CurrObjSec.Size)) shr 2) and $FFFFFF); // TODO: Check overflow
  1048. end;
  1049. {$endif ARM}
  1050. RELOC_RVA,
  1051. RELOC_SECREL32 :
  1052. begin
  1053. CurrObjSec.addsectionreloc(curraddr,CurrObjSec,reloctype);
  1054. inc(data,symaddr);
  1055. end;
  1056. else
  1057. internalerror(200604013);
  1058. end;
  1059. end
  1060. else
  1061. begin
  1062. if (p.objsection<>nil) and
  1063. (p.bind<>AB_COMMON) then
  1064. CurrObjSec.addsectionreloc(curraddr,p.objsection,reloctype)
  1065. else
  1066. CurrObjSec.addsymreloc(curraddr,p,reloctype);
  1067. if (not win32) or
  1068. (p.objsection<>nil) then
  1069. inc(data,symaddr);
  1070. if reloctype=RELOC_RELATIVE then
  1071. begin
  1072. if win32 then
  1073. dec(data,len-4)
  1074. else
  1075. dec(data,len+CurrObjSec.Size);
  1076. end;
  1077. end;
  1078. end
  1079. else
  1080. begin
  1081. if reloctype=RELOC_RVA then
  1082. internalerror(200603033);
  1083. end;
  1084. CurrObjSec.write(data,len);
  1085. end;
  1086. {****************************************************************************
  1087. TDJCoffObjData
  1088. ****************************************************************************}
  1089. constructor TDJCoffObjData.create(const n:string);
  1090. begin
  1091. inherited createcoff(n,false,TCoffObjSection);
  1092. end;
  1093. {****************************************************************************
  1094. TPECoffObjData
  1095. ****************************************************************************}
  1096. constructor TPECoffObjData.create(const n:string);
  1097. begin
  1098. inherited createcoff(n,true,TCoffObjSection);
  1099. end;
  1100. {****************************************************************************
  1101. TCoffObjOutput
  1102. ****************************************************************************}
  1103. constructor TCoffObjOutput.createcoff(AWriter:TObjectWriter;awin32:boolean);
  1104. begin
  1105. inherited create(AWriter);
  1106. win32:=awin32;
  1107. end;
  1108. destructor TCoffObjOutput.destroy;
  1109. begin
  1110. FCoffSyms.free;
  1111. FCoffStrs.free;
  1112. inherited destroy;
  1113. end;
  1114. procedure TCoffObjOutput.write_symbol(const name:string;value:aword;section:smallint;typ,aux:byte);
  1115. var
  1116. sym : coffsymbol;
  1117. begin
  1118. FillChar(sym,sizeof(sym),0);
  1119. { symbolname }
  1120. if length(name)>8 then
  1121. begin
  1122. sym.strpos:=FCoffStrs.size+4;
  1123. FCoffStrs.writestr(name);
  1124. FCoffStrs.writestr(#0);
  1125. end
  1126. else
  1127. move(name[1],sym.name,length(name));
  1128. sym.value:=value;
  1129. sym.section:=section;
  1130. sym.typ:=typ;
  1131. sym.aux:=aux;
  1132. inc(symidx);
  1133. FCoffSyms.write(sym,sizeof(sym));
  1134. end;
  1135. procedure TCoffObjOutput.section_write_symbol(p:TObject;arg:pointer);
  1136. var
  1137. secrec : coffsectionrec;
  1138. begin
  1139. with TCoffObjSection(p) do
  1140. begin
  1141. Inc(plongword(arg)^);
  1142. index:=plongword(arg)^;
  1143. secsymidx:=symidx;
  1144. { Both GNU and Microsoft toolchains write section symbols using
  1145. storage class 3 (STATIC).
  1146. No reason to use COFF_SYM_SECTION, it is silently converted to 3 by
  1147. PE binutils and causes warnings with DJGPP binutils. }
  1148. write_symbol(name,mempos,index,COFF_SYM_LOCAL,1);
  1149. { AUX }
  1150. fillchar(secrec,sizeof(secrec),0);
  1151. secrec.len:=Size;
  1152. if ObjRelocations.count<65535 then
  1153. secrec.nrelocs:=ObjRelocations.count
  1154. else
  1155. secrec.nrelocs:=65535;
  1156. inc(symidx);
  1157. FCoffSyms.write(secrec,sizeof(secrec));
  1158. end;
  1159. end;
  1160. procedure TCoffObjOutput.section_write_relocs(p:TObject;arg:pointer);
  1161. var
  1162. i : longint;
  1163. rel : coffreloc;
  1164. objreloc : TObjRelocation;
  1165. begin
  1166. if (TObjSection(p).ObjRelocations.Count>65535) then
  1167. begin
  1168. rel.address:=TObjSection(p).ObjRelocations.Count+1;
  1169. rel.sym:=0;
  1170. rel.reloctype:=0;
  1171. FWriter.Write(rel,sizeof(rel));
  1172. end;
  1173. for i:=0 to TObjSection(p).ObjRelocations.Count-1 do
  1174. begin
  1175. objreloc:=TObjRelocation(TObjSection(p).ObjRelocations[i]);
  1176. rel.address:=objreloc.dataoffset;
  1177. if assigned(objreloc.symbol) then
  1178. begin
  1179. if (objreloc.symbol.bind=AB_LOCAL) then
  1180. rel.sym:=objreloc.symbol.objsection.secsymidx
  1181. else
  1182. begin
  1183. if objreloc.symbol.symidx=-1 then
  1184. internalerror(200602233);
  1185. rel.sym:=objreloc.symbol.symidx;
  1186. end;
  1187. end
  1188. else
  1189. begin
  1190. if objreloc.objsection<>nil then
  1191. rel.sym:=objreloc.objsection.secsymidx
  1192. else
  1193. rel.sym:=0;
  1194. end;
  1195. case objreloc.typ of
  1196. {$ifdef arm}
  1197. RELOC_ABSOLUTE :
  1198. rel.reloctype:=IMAGE_REL_ARM_ADDR32;
  1199. { I've no idea if this is correct (FK):
  1200. RELOC_RELATIVE :
  1201. rel.reloctype:=IMAGE_REL_ARM_GPREL12;
  1202. }
  1203. RELOC_RVA :
  1204. rel.reloctype:=IMAGE_REL_ARM_ADDR32NB;
  1205. RELOC_SECREL32 :
  1206. rel.reloctype:=IMAGE_REL_ARM_SECREL;
  1207. RELOC_RELATIVE_24 :
  1208. rel.reloctype:=IMAGE_REL_ARM_BRANCH24;
  1209. RELOC_RELATIVE_CALL :
  1210. rel.reloctype:=IMAGE_REL_ARM_BLX24;
  1211. RELOC_RELATIVE_24_THUMB:
  1212. rel.reloctype:=IMAGE_REL_ARM_BLX23T;
  1213. {$endif arm}
  1214. {$ifdef i386}
  1215. RELOC_RELATIVE :
  1216. rel.reloctype:=IMAGE_REL_I386_PCRLONG;
  1217. RELOC_ABSOLUTE :
  1218. rel.reloctype:=IMAGE_REL_I386_DIR32;
  1219. RELOC_RVA :
  1220. rel.reloctype:=IMAGE_REL_I386_IMAGEBASE;
  1221. RELOC_SECREL32 :
  1222. rel.reloctype:=IMAGE_REL_I386_SECREL32;
  1223. {$endif i386}
  1224. {$ifdef x86_64}
  1225. RELOC_NONE :
  1226. rel.reloctype:=IMAGE_REL_AMD64_ABSOLUTE;
  1227. RELOC_RELATIVE :
  1228. rel.reloctype:=IMAGE_REL_AMD64_REL32;
  1229. RELOC_ABSOLUTE32 :
  1230. rel.reloctype:=IMAGE_REL_AMD64_ADDR32;
  1231. RELOC_ABSOLUTE :
  1232. rel.reloctype:=IMAGE_REL_AMD64_ADDR64;
  1233. RELOC_RVA :
  1234. rel.reloctype:=IMAGE_REL_AMD64_ADDR32NB;
  1235. RELOC_RELATIVE_1 :
  1236. rel.reloctype:=IMAGE_REL_AMD64_REL32_1;
  1237. RELOC_RELATIVE_2 :
  1238. rel.reloctype:=IMAGE_REL_AMD64_REL32_2;
  1239. RELOC_RELATIVE_3 :
  1240. rel.reloctype:=IMAGE_REL_AMD64_REL32_3;
  1241. RELOC_RELATIVE_4 :
  1242. rel.reloctype:=IMAGE_REL_AMD64_REL32_4;
  1243. RELOC_RELATIVE_5 :
  1244. rel.reloctype:=IMAGE_REL_AMD64_REL32_5;
  1245. RELOC_SECREL32 :
  1246. rel.reloctype:=IMAGE_REL_AMD64_SECREL;
  1247. {$endif x86_64}
  1248. else
  1249. internalerror(200905071);
  1250. end;
  1251. FWriter.write(rel,sizeof(rel));
  1252. end;
  1253. end;
  1254. procedure TCoffObjOutput.create_symbols(data:TObjData);
  1255. var
  1256. filename : string[18];
  1257. sectionval : word;
  1258. globalval : byte;
  1259. i : longint;
  1260. value : aword;
  1261. objsym : TObjSymbol;
  1262. secidx : longword;
  1263. begin
  1264. with TCoffObjData(data) do
  1265. begin
  1266. symidx:=0;
  1267. { The `.file' record, and the file name auxiliary record }
  1268. write_symbol('.file', 0, -2, COFF_SYM_FILE, 1);
  1269. fillchar(filename,sizeof(filename),0);
  1270. filename:=ExtractFileName(current_module.mainsource);
  1271. inc(symidx);
  1272. FCoffSyms.write(filename[1],sizeof(filename)-1);
  1273. { Sections }
  1274. secidx:=0;
  1275. ObjSectionList.ForEachCall(@section_write_symbol,@secidx);
  1276. { ObjSymbols }
  1277. for i:=0 to ObjSymbolList.Count-1 do
  1278. begin
  1279. objsym:=TObjSymbol(ObjSymbolList[i]);
  1280. if (objsym.bind=AB_LOCAL) then
  1281. continue;
  1282. case objsym.bind of
  1283. AB_GLOBAL :
  1284. begin
  1285. globalval:=COFF_SYM_GLOBAL;
  1286. sectionval:=objsym.objsection.index;
  1287. value:=objsym.address;
  1288. end;
  1289. AB_LOCAL :
  1290. begin
  1291. globalval:=COFF_SYM_LOCAL;
  1292. sectionval:=objsym.objsection.index;
  1293. value:=objsym.address;
  1294. end;
  1295. else
  1296. begin
  1297. globalval:=COFF_SYM_GLOBAL;
  1298. sectionval:=0;
  1299. value:=objsym.size;
  1300. end;
  1301. end;
  1302. { symbolname }
  1303. objsym.symidx:=symidx;
  1304. write_symbol(objsym.name,value,sectionval,globalval,0);
  1305. end;
  1306. end;
  1307. end;
  1308. procedure TCoffObjOutput.section_set_reloc_datapos(p:TCoffObjSection;var datapos:aword);
  1309. begin
  1310. p.coffrelocpos:=datapos;
  1311. inc(datapos,sizeof(coffreloc)*p.ObjRelocations.count);
  1312. if p.ObjRelocations.count>65535 then
  1313. begin
  1314. if win32 then
  1315. inc(datapos,sizeof(coffreloc))
  1316. else
  1317. Message1(asmw_f_too_many_relocations,p.fullname);
  1318. end;
  1319. end;
  1320. procedure TCoffObjOutput.section_write_header(p:TObject;arg:pointer);
  1321. var
  1322. sechdr : tcoffsechdr;
  1323. s : string;
  1324. strpos : aword;
  1325. begin
  1326. with TCoffObjSection(p) do
  1327. begin
  1328. fillchar(sechdr,sizeof(sechdr),0);
  1329. s:=name;
  1330. if length(s)>8 then
  1331. begin
  1332. strpos:=FCoffStrs.size+4;
  1333. FCoffStrs.writestr(s);
  1334. FCoffStrs.writestr(#0);
  1335. s:='/'+ToStr(strpos);
  1336. end;
  1337. move(s[1],sechdr.name,length(s));
  1338. if not win32 then
  1339. begin
  1340. sechdr.rvaofs:=mempos;
  1341. sechdr.vsize:=mempos;
  1342. end
  1343. else
  1344. begin
  1345. if not(oso_data in secoptions) then
  1346. sechdr.vsize:=Size;
  1347. end;
  1348. sechdr.DataSize:=size;
  1349. if (Size>0) and
  1350. (oso_data in secoptions) then
  1351. sechdr.datapos:=datapos;
  1352. if ObjRelocations.count<65535 then
  1353. sechdr.nrelocs:=ObjRelocations.count
  1354. else
  1355. sechdr.nrelocs:=65535;
  1356. sechdr.relocpos:=coffrelocpos;
  1357. if win32 then
  1358. begin
  1359. sechdr.flags:=peencodesechdrflags(secoptions,secalign);
  1360. if ObjRelocations.count>65535 then
  1361. sechdr.flags:=sechdr.flags or PE_SCN_LNK_NRELOC_OVFL;
  1362. end
  1363. else
  1364. sechdr.flags:=djencodesechdrflags(secoptions);
  1365. FWriter.write(sechdr,sizeof(sechdr));
  1366. end;
  1367. end;
  1368. function TCoffObjOutput.writedata(data:TObjData):boolean;
  1369. var
  1370. datapos,
  1371. sympos : aword;
  1372. i : longint;
  1373. header : tcoffheader;
  1374. begin
  1375. result:=false;
  1376. FCoffSyms:=TDynamicArray.Create(SymbolMaxGrow);
  1377. FCoffStrs:=TDynamicArray.Create(StrsMaxGrow);
  1378. with TCoffObjData(data) do
  1379. begin
  1380. { Create Symbol Table }
  1381. create_symbols(data);
  1382. { Calculate the filepositions }
  1383. datapos:=sizeof(tcoffheader)+sizeof(tcoffsechdr)*ObjSectionList.Count;
  1384. { Sections first }
  1385. layoutsections(datapos);
  1386. { relocs }
  1387. for i:=0 to ObjSectionList.Count-1 do
  1388. section_set_reloc_datapos(TCoffObjSection(ObjSectionList[i]),datapos);
  1389. { Symbols }
  1390. sympos:=datapos;
  1391. { Generate COFF header }
  1392. fillchar(header,sizeof(tcoffheader),0);
  1393. header.mach:=COFF_MAGIC;
  1394. header.nsects:=ObjSectionList.Count;
  1395. header.sympos:=sympos;
  1396. header.syms:=symidx;
  1397. if win32 then
  1398. begin
  1399. {$ifndef x86_64}
  1400. header.flag:=PE_FILE_32BIT_MACHINE or
  1401. PE_FILE_LINE_NUMS_STRIPPED or PE_FILE_LOCAL_SYMS_STRIPPED;
  1402. {$else x86_64}
  1403. header.flag:=PE_FILE_LINE_NUMS_STRIPPED or PE_FILE_LOCAL_SYMS_STRIPPED;
  1404. {$endif x86_64}
  1405. end
  1406. else
  1407. header.flag:=COFF_FLAG_AR32WR or COFF_FLAG_NOLINES or COFF_FLAG_NOLSYMS;
  1408. FWriter.write(header,sizeof(header));
  1409. { Section headers }
  1410. ObjSectionList.ForEachCall(@section_write_header,nil);
  1411. { ObjSections }
  1412. WriteSectionContent(data);
  1413. { Relocs }
  1414. ObjSectionList.ForEachCall(@section_write_relocs,nil);
  1415. { ObjSymbols }
  1416. if Sympos<>FWriter.ObjSize then
  1417. internalerror(200603051);
  1418. FWriter.writearray(FCoffSyms);
  1419. { Strings }
  1420. i:=FCoffStrs.size+4;
  1421. FWriter.write(i,4);
  1422. FWriter.writearray(FCoffStrs);
  1423. end;
  1424. FCoffStrs.Free;
  1425. FCoffStrs:=nil;
  1426. FCoffSyms.Free;
  1427. FCoffSyms:=nil;
  1428. end;
  1429. constructor TDJCoffObjOutput.create(AWriter:TObjectWriter);
  1430. begin
  1431. inherited createcoff(AWriter,false);
  1432. cobjdata:=TDJCoffObjData;
  1433. end;
  1434. constructor TPECoffObjOutput.create(AWriter:TObjectWriter);
  1435. begin
  1436. inherited createcoff(AWriter,true);
  1437. cobjdata:=TPECoffObjData;
  1438. end;
  1439. {****************************************************************************
  1440. TCoffObjInput
  1441. ****************************************************************************}
  1442. constructor TCoffObjInput.createcoff(awin32:boolean);
  1443. begin
  1444. inherited create;
  1445. win32:=awin32;
  1446. FSymTbl:=nil;
  1447. end;
  1448. destructor TCoffObjInput.destroy;
  1449. begin
  1450. FCoffSyms.free;
  1451. if assigned(FCoffStrs) then
  1452. freemem(FCoffStrs);
  1453. if assigned(FSymTbl) then
  1454. freemem(FSymTbl);
  1455. if assigned(FSecTbl) then
  1456. freemem(FSecTbl);
  1457. inherited destroy;
  1458. end;
  1459. function TCoffObjInput.GetSection(secidx:longint):TObjSection;
  1460. begin
  1461. result:=nil;
  1462. if (secidx<1) or (secidx>FSecCount) then
  1463. begin
  1464. InputError('Failed reading coff file, invalid section index');
  1465. exit;
  1466. end;
  1467. result:=FSecTbl^[secidx];
  1468. end;
  1469. function TCoffObjInput.Read_str(strpos:longword):string;
  1470. begin
  1471. if (FCoffStrs=nil) or (strpos>=FCoffStrSize) or (FCoffStrs[strpos]=#0) then
  1472. Internalerror(200205172);
  1473. result:=string(PChar(@FCoffStrs[strpos]));
  1474. end;
  1475. procedure TCoffObjInput.read_relocs(s:TCoffObjSection);
  1476. var
  1477. rel : coffreloc;
  1478. rel_type : TObjRelocationType;
  1479. i : longint;
  1480. p : TObjSymbol;
  1481. begin
  1482. if s.coffrelocs=high(aword) then
  1483. begin
  1484. { If number of relocations exceeds 65535, it is stored in address field
  1485. of the first record, and includes this first fake relocation. }
  1486. FReader.read(rel,sizeof(rel));
  1487. s.coffrelocs:=rel.address-1;
  1488. if s.coffrelocs<=65535 then
  1489. InternalError(2013012503);
  1490. end;
  1491. for i:=1 to s.coffrelocs do
  1492. begin
  1493. FReader.read(rel,sizeof(rel));
  1494. case rel.reloctype of
  1495. {$ifdef arm}
  1496. IMAGE_REL_ARM_ABSOLUTE:
  1497. rel_type:=RELOC_NONE;
  1498. IMAGE_REL_ARM_ADDR32:
  1499. rel_type:=RELOC_ABSOLUTE;
  1500. IMAGE_REL_ARM_ADDR32NB:
  1501. rel_type:=RELOC_RVA;
  1502. IMAGE_REL_ARM_BRANCH24:
  1503. rel_type:=RELOC_RELATIVE_24;
  1504. IMAGE_REL_ARM_BLX24:
  1505. rel_type:=RELOC_RELATIVE_CALL;
  1506. IMAGE_REL_ARM_SECREL:
  1507. rel_type:=RELOC_SECREL32;
  1508. IMAGE_REL_ARM_BLX23T:
  1509. rel_type:=RELOC_RELATIVE_24_THUMB;
  1510. {$endif arm}
  1511. {$ifdef i386}
  1512. IMAGE_REL_I386_PCRLONG :
  1513. rel_type:=RELOC_RELATIVE;
  1514. IMAGE_REL_I386_DIR32 :
  1515. rel_type:=RELOC_ABSOLUTE;
  1516. IMAGE_REL_I386_IMAGEBASE :
  1517. rel_type:=RELOC_RVA;
  1518. IMAGE_REL_I386_SECREL32 :
  1519. rel_type:=RELOC_SECREL32;
  1520. {$endif i386}
  1521. {$ifdef x86_64}
  1522. IMAGE_REL_AMD64_ABSOLUTE:
  1523. rel_type:=RELOC_NONE;
  1524. IMAGE_REL_AMD64_REL32:
  1525. rel_type:=RELOC_RELATIVE;
  1526. IMAGE_REL_AMD64_ADDR32,
  1527. R_X86_64_32S:
  1528. rel_type:=RELOC_ABSOLUTE32;
  1529. IMAGE_REL_AMD64_ADDR64:
  1530. rel_type:=RELOC_ABSOLUTE;
  1531. IMAGE_REL_AMD64_ADDR32NB:
  1532. rel_type:=RELOC_RVA;
  1533. IMAGE_REL_AMD64_REL32_1:
  1534. rel_type:=RELOC_RELATIVE_1;
  1535. IMAGE_REL_AMD64_REL32_2:
  1536. rel_type:=RELOC_RELATIVE_2;
  1537. IMAGE_REL_AMD64_REL32_3:
  1538. rel_type:=RELOC_RELATIVE_3;
  1539. IMAGE_REL_AMD64_REL32_4:
  1540. rel_type:=RELOC_RELATIVE_4;
  1541. IMAGE_REL_AMD64_REL32_5:
  1542. rel_type:=RELOC_RELATIVE_5;
  1543. IMAGE_REL_AMD64_SECREL:
  1544. rel_type:=RELOC_SECREL32;
  1545. {$endif x86_64}
  1546. else
  1547. begin
  1548. InputError('Failed reading coff file, illegal reloctype $'+system.hexstr(rel.reloctype,4));
  1549. exit;
  1550. end;
  1551. end;
  1552. p:=FSymTbl^[rel.sym];
  1553. if assigned(p) then
  1554. s.addsymreloc(rel.address-s.mempos,p,rel_type)
  1555. else
  1556. begin
  1557. InputError('Failed reading coff file, can''t resolve symbol of relocation');
  1558. exit;
  1559. end;
  1560. end;
  1561. end;
  1562. procedure TCoffObjInput.read_symbols(objdata:TObjData);
  1563. var
  1564. size,
  1565. address,
  1566. nsyms,
  1567. symidx : aint;
  1568. i : longint;
  1569. sym : coffsymbol;
  1570. objsym : TObjSymbol;
  1571. bind : Tasmsymbind;
  1572. strname : string;
  1573. auxrec : array[0..17] of byte;
  1574. objsec : TObjSection;
  1575. { keeps string manipulations out of main routine }
  1576. procedure UnsupportedSymbolType;
  1577. begin
  1578. Comment(V_Fatal,'Unsupported COFF symbol type '+tostr(sym.typ)+' at index '+tostr(symidx)+' while reading '+InputFileName);
  1579. end;
  1580. begin
  1581. with TCoffObjData(objdata) do
  1582. begin
  1583. nsyms:=FCoffSyms.Size div sizeof(CoffSymbol);
  1584. { Allocate memory for symidx -> TObjSymbol table }
  1585. FSymTbl:=AllocMem(nsyms*sizeof(TObjSymbol));
  1586. { Load the Symbols }
  1587. FCoffSyms.Seek(0);
  1588. symidx:=0;
  1589. while (symidx<nsyms) do
  1590. begin
  1591. FCoffSyms.Read(sym,sizeof(sym));
  1592. if plongint(@sym.name)^<>0 then
  1593. begin
  1594. move(sym.name,strname[1],8);
  1595. strname[9]:=#0;
  1596. strname[0]:=chr(strlen(@strname[1]));
  1597. if strname='' then
  1598. Internalerror(200205171);
  1599. end
  1600. else
  1601. strname:=Read_str(sym.strpos);
  1602. bind:=AB_EXTERNAL;
  1603. size:=0;
  1604. address:=0;
  1605. objsym:=nil;
  1606. objsec:=nil;
  1607. case sym.typ of
  1608. COFF_SYM_GLOBAL :
  1609. begin
  1610. if sym.section=0 then
  1611. begin
  1612. if sym.value=0 then
  1613. bind:=AB_EXTERNAL
  1614. else
  1615. begin
  1616. bind:=AB_COMMON;
  1617. size:=sym.value;
  1618. end;
  1619. end
  1620. else
  1621. begin
  1622. bind:=AB_GLOBAL;
  1623. objsec:=GetSection(sym.section);
  1624. if sym.value>=objsec.mempos then
  1625. address:=sym.value-objsec.mempos;
  1626. end;
  1627. objsym:=CreateSymbol(strname);
  1628. objsym.bind:=bind;
  1629. objsym.typ:=AT_FUNCTION;
  1630. objsym.objsection:=objsec;
  1631. objsym.offset:=address;
  1632. objsym.size:=size;
  1633. end;
  1634. COFF_SYM_LABEL,
  1635. COFF_SYM_LOCAL :
  1636. begin
  1637. { do not add constants (section=-1) }
  1638. if sym.section<>-1 then
  1639. begin
  1640. objsec:=GetSection(sym.section);
  1641. if sym.value>=objsec.mempos then
  1642. address:=sym.value-objsec.mempos;
  1643. objsym:=CreateSymbol(strname);
  1644. objsym.bind:=AB_LOCAL;
  1645. objsym.typ:=AT_FUNCTION;
  1646. objsym.objsection:=objsec;
  1647. objsym.offset:=address;
  1648. objsym.size:=size;
  1649. end;
  1650. end;
  1651. COFF_SYM_SECTION :
  1652. begin
  1653. { GetSection checks that index is in range }
  1654. objsec:=GetSection(sym.section);
  1655. if assigned(objsec) then
  1656. begin
  1657. if sym.value>=objsec.mempos then
  1658. address:=sym.value-objsec.mempos;
  1659. objsym:=CreateSymbol(strname);
  1660. objsym.bind:=AB_LOCAL;
  1661. objsym.typ:=AT_FUNCTION;
  1662. objsym.objsection:=objsec;
  1663. objsym.offset:=address;
  1664. objsym.size:=size;
  1665. end;
  1666. end;
  1667. COFF_SYM_FUNCTION,
  1668. COFF_SYM_FILE :
  1669. ;
  1670. else
  1671. UnsupportedSymbolType;
  1672. end;
  1673. FSymTbl^[symidx]:=objsym;
  1674. { read aux records }
  1675. for i:=1 to sym.aux do
  1676. begin
  1677. FCoffSyms.Read(auxrec,sizeof(auxrec));
  1678. inc(symidx);
  1679. end;
  1680. inc(symidx);
  1681. end;
  1682. end;
  1683. end;
  1684. procedure TCoffObjInput.ObjSections_read_relocs(p:TObject;arg:pointer);
  1685. begin
  1686. with TCoffObjSection(p) do
  1687. begin
  1688. { Skip debug sections }
  1689. if (oso_debug in secoptions) and
  1690. (cs_link_strip in current_settings.globalswitches) and
  1691. not(cs_link_separate_dbg_file in current_settings.globalswitches) then
  1692. exit;
  1693. if coffrelocs>0 then
  1694. begin
  1695. FReader.Seek(coffrelocpos);
  1696. read_relocs(TCoffObjSection(p));
  1697. end;
  1698. end;
  1699. end;
  1700. function TCoffObjInput.ReadObjData(AReader:TObjectreader;out objdata:TObjData):boolean;
  1701. var
  1702. secalign : shortint;
  1703. strpos,
  1704. i : longint;
  1705. code : longint;
  1706. objsec : TCoffObjSection;
  1707. secoptions : TObjSectionOptions;
  1708. header : tcoffheader;
  1709. sechdr : tcoffsechdr;
  1710. secname : string;
  1711. secnamebuf : array[0..15] of char;
  1712. begin
  1713. FReader:=AReader;
  1714. InputFileName:=AReader.FileName;
  1715. objdata:=CObjData.Create(InputFileName);
  1716. result:=false;
  1717. FCoffSyms:=TDynamicArray.Create(SymbolMaxGrow);
  1718. with TCoffObjData(objdata) do
  1719. begin
  1720. { Read COFF header }
  1721. if not AReader.read(header,sizeof(tcoffheader)) then
  1722. begin
  1723. InputError('Can''t read COFF Header');
  1724. exit;
  1725. end;
  1726. if header.mach<>COFF_MAGIC then
  1727. begin
  1728. InputError('Illegal COFF Magic');
  1729. exit;
  1730. end;
  1731. {$ifdef arm}
  1732. eVCobj:=header.flag=$100;
  1733. {$endif arm}
  1734. { ObjSymbols }
  1735. AReader.Seek(header.sympos);
  1736. if not AReader.ReadArray(FCoffSyms,header.syms*sizeof(CoffSymbol)) then
  1737. begin
  1738. InputError('Error reading coff symbol table');
  1739. exit;
  1740. end;
  1741. { Strings }
  1742. if not AReader.Read(FCoffStrSize,4) then
  1743. begin
  1744. InputError('Error reading COFF string table');
  1745. exit;
  1746. end;
  1747. if (FCoffStrSize>4) then
  1748. begin
  1749. { allocate an extra byte and null-terminate }
  1750. GetMem(FCoffStrs,FCoffStrSize+1);
  1751. FCoffStrs[FCoffStrSize]:=#0;
  1752. for i:=0 to 3 do
  1753. FCoffStrs[i]:=#0;
  1754. if not AReader.Read(FCoffStrs[4],FCoffStrSize-4) then
  1755. begin
  1756. InputError('Error reading COFF string table');
  1757. exit;
  1758. end;
  1759. end;
  1760. { Section headers }
  1761. { Allocate SecIdx -> TObjSection table, secidx is 1-based }
  1762. FSecCount:=header.nsects;
  1763. FSecTbl:=AllocMem((header.nsects+1)*sizeof(TObjSection));
  1764. AReader.Seek(sizeof(tcoffheader)+header.opthdr);
  1765. for i:=1 to header.nsects do
  1766. begin
  1767. if not AReader.read(sechdr,sizeof(sechdr)) then
  1768. begin
  1769. InputError('Error reading COFF Section Headers');
  1770. exit;
  1771. end;
  1772. move(sechdr.name,secnamebuf,8);
  1773. secnamebuf[8]:=#0;
  1774. secname:=strpas(secnamebuf);
  1775. if secname[1]='/' then
  1776. begin
  1777. Val(Copy(secname,2,8),strpos,code);
  1778. if code=0 then
  1779. secname:=Read_str(strpos)
  1780. else
  1781. begin
  1782. InputError('Error reading COFF Section Headers');
  1783. secname:='error';
  1784. end;
  1785. end;
  1786. if win32 then
  1787. pedecodesechdrflags(secname,sechdr.flags,secoptions,secalign)
  1788. else
  1789. begin
  1790. secoptions:=djdecodesechdrflags(secname,sechdr.flags);
  1791. secalign:=sizeof(pint);
  1792. end;
  1793. if (Length(secname)>3) and (secname[2] in ['e','f','i','p','r']) then
  1794. begin
  1795. if (Pos('.edata',secname)=1) or
  1796. (Pos('.rsrc',secname)=1) or
  1797. {$ifndef x86_64}
  1798. (Pos('.pdata',secname)=1) or
  1799. {$endif}
  1800. (Pos('.fpc',secname)=1) then
  1801. include(secoptions,oso_keep);
  1802. if (Pos('.idata',secname)=1) then
  1803. begin
  1804. { TODO: idata keep can maybe replaced with grouping of text and idata}
  1805. include(secoptions,oso_keep);
  1806. secname:=secname + '.' + ExtractFileName(InputFileName);
  1807. end;
  1808. end;
  1809. objsec:=TCoffObjSection(createsection(secname,secalign,secoptions,false));
  1810. FSecTbl^[i]:=objsec;
  1811. if not win32 then
  1812. objsec.mempos:=sechdr.rvaofs;
  1813. objsec.orgmempos:=sechdr.rvaofs;
  1814. objsec.coffrelocs:=sechdr.nrelocs;
  1815. if win32 then
  1816. begin
  1817. if (sechdr.flags and PE_SCN_LNK_NRELOC_OVFL)<>0 then
  1818. objsec.coffrelocs:=high(aword);
  1819. end;
  1820. objsec.coffrelocpos:=sechdr.relocpos;
  1821. objsec.datapos:=sechdr.datapos;
  1822. objsec.Size:=sechdr.dataSize;
  1823. end;
  1824. { Insert all ObjSymbols }
  1825. read_symbols(objdata);
  1826. { Section Data }
  1827. ReadSectionContent(objdata);
  1828. { Relocs }
  1829. ObjSectionList.ForEachCall(@objsections_read_relocs,nil);
  1830. end;
  1831. if assigned(FCoffStrs) then
  1832. freemem(FCoffStrs);
  1833. FCoffStrs:=nil;
  1834. FCoffSyms.Free;
  1835. FCoffSyms:=nil;
  1836. result:=true;
  1837. end;
  1838. constructor TDJCoffObjInput.create;
  1839. begin
  1840. inherited createcoff(false);
  1841. cobjdata:=TDJCoffObjData;
  1842. end;
  1843. constructor TPECoffObjInput.create;
  1844. begin
  1845. inherited createcoff(true);
  1846. cobjdata:=TPECoffObjData;
  1847. end;
  1848. {****************************************************************************
  1849. TCoffexeoutput
  1850. ****************************************************************************}
  1851. constructor TCoffexeoutput.createcoff(awin32:boolean);
  1852. begin
  1853. inherited create;
  1854. win32:=awin32;
  1855. if target_info.system in [system_x86_64_win64] then
  1856. MaxMemPos:=$FFFFFFFF
  1857. else
  1858. if target_info.system in systems_wince then
  1859. MaxMemPos:=$1FFFFFF
  1860. else
  1861. MaxMemPos:=$7FFFFFFF;
  1862. end;
  1863. procedure TCoffexeoutput.write_symbol(const name:string;value:aword;section:smallint;typ,aux:byte);
  1864. var
  1865. sym : coffsymbol;
  1866. begin
  1867. FillChar(sym,sizeof(sym),0);
  1868. if length(name)>8 then
  1869. begin
  1870. sym.strpos:=FCoffStrs.size+4;
  1871. FCoffStrs.writestr(name);
  1872. FCoffStrs.writestr(#0);
  1873. end
  1874. else
  1875. move(name[1],sym.name,length(name));
  1876. sym.value:=value;
  1877. sym.section:=section;
  1878. sym.typ:=typ;
  1879. sym.aux:=aux;
  1880. FWriter.write(sym,sizeof(sym));
  1881. end;
  1882. procedure TCoffexeoutput.globalsyms_write_symbol(p:TObject;arg:pointer);
  1883. var
  1884. secval,
  1885. value : aint;
  1886. globalval : byte;
  1887. exesec : TExeSection;
  1888. begin
  1889. if not assigned(texesymbol(p).objsymbol) then
  1890. internalerror(200603053);
  1891. with texesymbol(p).objsymbol do
  1892. begin
  1893. if assigned(objsection) then
  1894. exesec:=TExeSection(objsection.exesection)
  1895. else
  1896. exesec:=nil;
  1897. { There is no exesection defined for special internal symbols
  1898. like __image_base__ }
  1899. if assigned(exesec) then
  1900. begin
  1901. secval:=exesec.secsymidx;
  1902. if win32 then
  1903. value:=address-exesec.mempos
  1904. else
  1905. value:=address;
  1906. end
  1907. else
  1908. begin
  1909. secval:=-1;
  1910. value:=address;
  1911. end;
  1912. if bind=AB_LOCAL then
  1913. globalval:=COFF_SYM_LOCAL
  1914. else
  1915. globalval:=COFF_SYM_GLOBAL;
  1916. { reloctype address to the section in the executable }
  1917. write_symbol(name,value,secval,globalval,0);
  1918. end;
  1919. end;
  1920. procedure TCoffexeoutput.ExeSectionList_write_header(p:TObject;arg:pointer);
  1921. var
  1922. sechdr : tcoffsechdr;
  1923. s : string;
  1924. strpos : aword;
  1925. begin
  1926. with tExeSection(p) do
  1927. begin
  1928. fillchar(sechdr,sizeof(sechdr),0);
  1929. s:=name;
  1930. if length(s)>8 then
  1931. begin
  1932. strpos:=FCoffStrs.size+4;
  1933. FCoffStrs.writestr(s);
  1934. FCoffStrs.writestr(#0);
  1935. s:='/'+ToStr(strpos);
  1936. end;
  1937. move(s[1],sechdr.name,length(s));
  1938. if win32 then
  1939. begin
  1940. sechdr.rvaofs:=mempos;
  1941. sechdr.vsize:=Size;
  1942. { sechdr.dataSize is size of initialized data, rounded up to FileAlignment
  1943. (so it can be greater than VirtualSize). Must be zero for sections that
  1944. do not contain initialized data. }
  1945. if (oso_data in SecOptions) then
  1946. sechdr.datasize:=Align(Size,SectionDataAlign);
  1947. end
  1948. else
  1949. begin
  1950. if not (oso_debug in SecOptions) then
  1951. begin
  1952. sechdr.rvaofs:=mempos;
  1953. sechdr.vsize:=mempos;
  1954. end;
  1955. sechdr.datasize:=Size;
  1956. end;
  1957. if (Size>0) then
  1958. sechdr.datapos:=datapos-datapos_offset;
  1959. sechdr.nrelocs:=0;
  1960. sechdr.relocpos:=0;
  1961. if win32 then
  1962. begin
  1963. if (target_info.system in systems_nativent) and
  1964. (apptype = app_native) then
  1965. sechdr.flags:=peencodesechdrflags(SecOptions,SecAlign) or PE_SCN_MEM_NOT_PAGED
  1966. else
  1967. sechdr.flags:=peencodesechdrflags(SecOptions,SecAlign);
  1968. { some flags are invalid in executables, reset them }
  1969. sechdr.flags:=sechdr.flags and
  1970. not(PE_SCN_LNK_INFO or PE_SCN_LNK_REMOVE or
  1971. PE_SCN_LNK_COMDAT or PE_SCN_ALIGN_MASK);
  1972. end
  1973. else
  1974. sechdr.flags:=djencodesechdrflags(SecOptions);
  1975. FWriter.write(sechdr,sizeof(sechdr));
  1976. end;
  1977. end;
  1978. procedure TCoffexeoutput.ExeSectionList_pass2_header(p:TObject;arg:pointer);
  1979. begin
  1980. with TExeSection(p) do
  1981. begin
  1982. { The debuginfo sections should already be stripped }
  1983. { if (ExeWriteMode=ewm_exeonly) and
  1984. (oso_debug in SecOptions) then
  1985. internalerror(200801161); }
  1986. inc(plongint(arg)^);
  1987. secsymidx:=plongint(arg)^;
  1988. end;
  1989. end;
  1990. function tcoffexeoutput.totalheadersize:longword;
  1991. var
  1992. stubsize,
  1993. optheadersize : longword;
  1994. begin
  1995. if win32 then
  1996. begin
  1997. stubsize:=sizeof(win32stub)+sizeof(pemagic);
  1998. optheadersize:=sizeof(tcoffpeoptheader);
  1999. end
  2000. else
  2001. begin
  2002. stubsize:=sizeof(go32v2stub);
  2003. optheadersize:=sizeof(coffdjoptheader);
  2004. end;
  2005. result:=stubsize+sizeof(tcoffheader)+optheadersize;
  2006. end;
  2007. procedure tcoffexeoutput.MemPos_Header;
  2008. begin
  2009. { calculate start positions after the headers }
  2010. currmempos:=totalheadersize+sizeof(tcoffsechdr)*longword(ExeSectionList.Count-2);
  2011. end;
  2012. procedure tcoffexeoutput.DataPos_Header;
  2013. begin
  2014. { retrieve amount of sections }
  2015. nsects:=0;
  2016. ExeSectionList.ForEachCall(@ExeSectionList_pass2_header,@nsects);
  2017. { calculate start positions after the headers }
  2018. currdatapos:=totalheadersize+longword(nsects)*sizeof(tcoffsechdr);
  2019. end;
  2020. procedure tcoffexeoutput.DataPos_Symbols;
  2021. begin
  2022. inherited DataPos_Symbols;
  2023. { Calculating symbols position and size }
  2024. nsyms:=ExeSymbolList.Count;
  2025. sympos:=Align(CurrDataPos,SectionDataAlign);
  2026. inc(CurrDataPos,sizeof(coffsymbol)*nsyms);
  2027. end;
  2028. function TCoffexeoutput.writedata:boolean;
  2029. var
  2030. i : longword;
  2031. header : tcoffheader;
  2032. djoptheader : coffdjoptheader;
  2033. peoptheader : tcoffpeoptheader;
  2034. textExeSec,
  2035. dataExeSec,
  2036. bssExeSec,
  2037. idataExeSec : TExeSection;
  2038. hassymbols,
  2039. writeDbgStrings : boolean;
  2040. procedure UpdateDataDir(const secname:string;idx:longint);
  2041. var
  2042. exesec : TExeSection;
  2043. begin
  2044. exesec:=FindExeSection(secname);
  2045. if assigned(exesec) then
  2046. begin
  2047. peoptheader.DataDirectory[idx].vaddr:=exesec.mempos;
  2048. peoptheader.DataDirectory[idx].size:=exesec.Size;
  2049. end;
  2050. end;
  2051. procedure UpdateImports;
  2052. var
  2053. exesec: TExeSection;
  2054. objsec, iat_start, iat_end, ilt_start: TObjSection;
  2055. i: longint;
  2056. begin
  2057. exesec:=FindExeSection('.idata');
  2058. if exesec=nil then
  2059. exit;
  2060. iat_start:=nil;
  2061. iat_end:=nil;
  2062. ilt_start:=nil;
  2063. for i:=0 to exesec.ObjSectionList.Count-1 do
  2064. begin
  2065. objsec:=TObjSection(exesec.ObjSectionList[i]);
  2066. if (ilt_start=nil) and (Pos('.idata$4',objsec.Name)=1) then
  2067. ilt_start:=objsec;
  2068. if Pos('.idata$5',objsec.Name)=1 then
  2069. begin
  2070. if iat_start=nil then
  2071. iat_start:=objsec;
  2072. end
  2073. else
  2074. if Assigned(iat_start) then
  2075. begin
  2076. iat_end:=objsec;
  2077. Break;
  2078. end;
  2079. end;
  2080. peoptheader.DataDirectory[PE_DATADIR_IDATA].vaddr:=exesec.mempos;
  2081. if Assigned(ilt_start) then
  2082. peoptheader.DataDirectory[PE_DATADIR_IDATA].size:=ilt_start.mempos-exesec.mempos
  2083. else { should not happen }
  2084. peoptheader.DataDirectory[PE_DATADIR_IDATA].size:=exesec.Size;
  2085. if Assigned(iat_start) and Assigned(iat_end) then
  2086. begin
  2087. peoptheader.DataDirectory[PE_DATADIR_IMPORTADDRESSTABLE].vaddr:=iat_start.mempos;
  2088. peoptheader.DataDirectory[PE_DATADIR_IMPORTADDRESSTABLE].size:=iat_end.mempos-iat_start.mempos;
  2089. end;
  2090. end;
  2091. procedure UpdateTlsDataDir;
  2092. var
  2093. {callbacksection : TExeSection;}
  2094. tlsexesymbol: TExeSymbol;
  2095. tlssymbol: TObjSymbol;
  2096. callbackexesymbol: TExeSymbol;
  2097. //callbacksymbol: TObjSymbol;
  2098. begin
  2099. { according to GNU ld,
  2100. the callback routines should be placed into .CRT$XL*
  2101. sections, and the thread local variables in .tls
  2102. __tls_start__ and __tls_end__ symbols
  2103. should be used for the initialized part,
  2104. which we do not support yet. }
  2105. { For now, we only pass the address of the __tls_used
  2106. asm symbol into PE_DATADIR_TLS with the correct
  2107. size of this table (different for win32/win64 }
  2108. tlsexesymbol:=texesymbol(ExeSymbolList.Find(
  2109. target_info.Cprefix+'_tls_used'));
  2110. if assigned(tlsexesymbol) then
  2111. begin
  2112. tlssymbol:=tlsexesymbol.ObjSymbol;
  2113. peoptheader.DataDirectory[PE_DATADIR_TLS].vaddr:=tlssymbol.address;
  2114. { sizeof(TlsDirectory) is different on host and target when cross-compiling }
  2115. peoptheader.DataDirectory[PE_DATADIR_TLS].size:=TLSDIR_SIZE;
  2116. if IsSharedLibrary then
  2117. begin
  2118. { Here we should reset __FPC_tls_callbacks value to nil }
  2119. callbackexesymbol:=texesymbol(ExeSymbolList.Find(
  2120. '__FPC_tls_callbacks'));
  2121. if assigned (callbackexesymbol) then
  2122. begin
  2123. //callbacksymbol:=callbackexesymbol.ObjSymbol;
  2124. end;
  2125. end;
  2126. end;
  2127. end;
  2128. begin
  2129. result:=false;
  2130. FCoffStrs:=TDynamicArray.Create(StrsMaxGrow);
  2131. textExeSec:=FindExeSection('.text');
  2132. dataExeSec:=FindExeSection('.data');
  2133. bssExeSec:=FindExeSection('.bss');
  2134. if not assigned(TextExeSec) or
  2135. not assigned(DataExeSec) then
  2136. internalerror(200602231);
  2137. { do we need to write symbols? }
  2138. hassymbols:=(ExeWriteMode=ewm_dbgonly) or
  2139. (
  2140. (ExeWriteMode=ewm_exefull) and
  2141. not(cs_link_strip in current_settings.globalswitches)
  2142. );
  2143. writeDbgStrings:=hassymbols or ((ExeWriteMode=ewm_exeonly) and (cs_link_separate_dbg_file in current_settings.globalswitches));
  2144. { Stub }
  2145. if win32 then
  2146. begin
  2147. FWriter.write(win32stub,sizeof(win32stub));
  2148. FWriter.write(pemagic,sizeof(pemagic));
  2149. end
  2150. else
  2151. FWriter.write(go32v2stub,sizeof(go32v2stub));
  2152. { Initial header, will be updated later }
  2153. fillchar(header,sizeof(header),0);
  2154. header.mach:=COFF_MAGIC;
  2155. header.nsects:=nsects;
  2156. if writeDbgStrings then
  2157. header.sympos:=sympos-datapos_offset;
  2158. if hassymbols then
  2159. header.syms:=nsyms;
  2160. if win32 then
  2161. header.opthdr:=sizeof(tcoffpeoptheader)
  2162. else
  2163. header.opthdr:=sizeof(coffdjoptheader);
  2164. if win32 then
  2165. begin
  2166. header.flag:=PE_FILE_EXECUTABLE_IMAGE or PE_FILE_LINE_NUMS_STRIPPED;
  2167. if target_info.system in [system_x86_64_win64] then
  2168. header.flag:=header.flag or PE_FILE_LARGE_ADDRESS_AWARE
  2169. else
  2170. header.flag:=header.flag or PE_FILE_32BIT_MACHINE;
  2171. if IsSharedLibrary then
  2172. header.flag:=header.flag or PE_FILE_DLL;
  2173. if FindExeSection('.reloc')=nil then
  2174. header.flag:=header.flag or PE_FILE_RELOCS_STRIPPED;
  2175. if (FindExeSection('.stab')=nil) and
  2176. (FindExeSection('.debug_info')=nil) and
  2177. (FindExeSection('.gnu_debuglink')=nil) then
  2178. header.flag:=header.flag or PE_FILE_DEBUG_STRIPPED;
  2179. if not hassymbols then
  2180. header.flag:=header.flag or PE_FILE_LOCAL_SYMS_STRIPPED;
  2181. if SetPEFlagsSetExplicity then
  2182. header.flag:=header.flag or peflags;
  2183. end
  2184. else
  2185. header.flag:=COFF_FLAG_AR32WR or COFF_FLAG_EXE or COFF_FLAG_NORELOCS or COFF_FLAG_NOLINES;
  2186. FWriter.write(header,sizeof(header));
  2187. { Optional COFF Header }
  2188. if win32 then
  2189. begin
  2190. fillchar(peoptheader,sizeof(peoptheader),0);
  2191. peoptheader.magic:=COFF_OPT_MAGIC;
  2192. peoptheader.MajorLinkerVersion:=ord(version_nr)-ord('0');
  2193. peoptheader.MinorLinkerVersion:=(ord(release_nr)-ord('0'))*10 + (ord(patch_nr)-ord('0'));
  2194. peoptheader.tsize:=TextExeSec.Size;
  2195. peoptheader.dsize:=DataExeSec.Size;
  2196. if assigned(BSSExeSec) then
  2197. peoptheader.bsize:=BSSExeSec.Size;
  2198. peoptheader.text_start:=TextExeSec.mempos;
  2199. {$ifndef cpu64bitaddr}
  2200. peoptheader.data_start:=DataExeSec.mempos;
  2201. {$endif cpu64bitaddr}
  2202. peoptheader.entry:=EntrySym.Address;
  2203. peoptheader.ImageBase:=ImageBase;
  2204. peoptheader.SectionAlignment:=SectionMemAlign;
  2205. peoptheader.FileAlignment:=SectionDataAlign;
  2206. peoptheader.MajorOperatingSystemVersion:=4;
  2207. peoptheader.MinorOperatingSystemVersion:=0;
  2208. peoptheader.MajorImageVersion:=dllmajor;
  2209. peoptheader.MinorImageVersion:=dllminor;
  2210. if target_info.system in systems_wince then
  2211. peoptheader.MajorSubsystemVersion:=3
  2212. else
  2213. peoptheader.MajorSubsystemVersion:=4;
  2214. peoptheader.MinorSubsystemVersion:=0;
  2215. peoptheader.Win32Version:=0;
  2216. peoptheader.SizeOfImage:=Align(CurrMemPos,SectionMemAlign);
  2217. peoptheader.SizeOfHeaders:=textExeSec.DataPos;
  2218. peoptheader.CheckSum:=0;
  2219. if (target_info.system in systems_nativent) and (not IsSharedLibrary or (apptype = app_native)) then
  2220. { Although I did not really test this, it seems that Subsystem is
  2221. not checked in DLLs except for maybe drivers}
  2222. peoptheader.Subsystem:=PE_SUBSYSTEM_NATIVE
  2223. else
  2224. if target_info.system in systems_wince then
  2225. peoptheader.Subsystem:=PE_SUBSYSTEM_WINDOWS_CE_GUI
  2226. else
  2227. if apptype=app_gui then
  2228. peoptheader.Subsystem:=PE_SUBSYSTEM_WINDOWS_GUI
  2229. else
  2230. peoptheader.Subsystem:=PE_SUBSYSTEM_WINDOWS_CUI;
  2231. if SetPEOptFlagsSetExplicity then
  2232. peoptheader.DllCharacteristics:=peoptflags
  2233. else
  2234. peoptheader.DllCharacteristics:=0;
  2235. peoptheader.SizeOfStackReserve:=stacksize;
  2236. peoptheader.SizeOfStackCommit:=$1000;
  2237. if MinStackSizeSetExplicity then
  2238. peoptheader.SizeOfStackCommit:=minstacksize;
  2239. if MaxStackSizeSetExplicity then
  2240. peoptheader.SizeOfStackReserve:=maxstacksize;
  2241. peoptheader.SizeOfHeapReserve:=$100000;
  2242. peoptheader.SizeOfHeapCommit:=$1000;
  2243. peoptheader.NumberOfRvaAndSizes:=PE_DATADIR_ENTRIES;
  2244. UpdateImports;
  2245. UpdateTlsDataDir;
  2246. UpdateDataDir('.edata',PE_DATADIR_EDATA);
  2247. UpdateDataDir('.rsrc',PE_DATADIR_RSRC);
  2248. UpdateDataDir('.pdata',PE_DATADIR_PDATA);
  2249. UpdateDataDir('.reloc',PE_DATADIR_RELOC);
  2250. FWriter.write(peoptheader,sizeof(peoptheader));
  2251. end
  2252. else
  2253. begin
  2254. fillchar(djoptheader,sizeof(djoptheader),0);
  2255. djoptheader.magic:=COFF_OPT_MAGIC;
  2256. djoptheader.tsize:=TextExeSec.Size;
  2257. djoptheader.dsize:=DataExeSec.Size;
  2258. if assigned(BSSExeSec) then
  2259. djoptheader.bsize:=BSSExeSec.Size;
  2260. djoptheader.text_start:=TextExeSec.mempos;
  2261. djoptheader.data_start:=DataExeSec.mempos;
  2262. djoptheader.entry:=EntrySym.Address;
  2263. FWriter.write(djoptheader,sizeof(djoptheader));
  2264. end;
  2265. { For some unknown reason WM 6.1 requires .idata section to be read only.
  2266. Otherwise it refuses to load DLLs greater than 64KB.
  2267. Earlier versions of WinCE load DLLs regardless of .idata flags. }
  2268. if target_info.system in systems_wince then
  2269. begin
  2270. idataExeSec:=FindExeSection('.idata');
  2271. if idataExeSec<>nil then
  2272. idataExeSec.SecOptions:=idataExeSec.SecOptions - [oso_write];
  2273. end;
  2274. { Section headers }
  2275. ExeSectionList.ForEachCall(@ExeSectionList_write_header,nil);
  2276. { Section data }
  2277. WriteExeSectionContent;
  2278. { Align after the last section }
  2279. FWriter.Writezeros(Align(FWriter.Size,SectionDataAlign)-FWriter.Size);
  2280. { Optional Symbols }
  2281. if SymPos<>FWriter.Size then
  2282. internalerror(200602252);
  2283. if hassymbols then
  2284. ExeSymbolList.ForEachCall(@globalsyms_write_symbol,nil);
  2285. if writeDbgStrings then
  2286. begin
  2287. { Strings }
  2288. i:=FCoffStrs.size+4;
  2289. FWriter.write(i,4);
  2290. FWriter.writearray(FCoffStrs);
  2291. end;
  2292. { Release }
  2293. FCoffStrs.Free;
  2294. result:=true;
  2295. end;
  2296. function IdataObjSectionCompare(Item1, Item2: Pointer): Integer;
  2297. var
  2298. I1 : TObjSection absolute Item1;
  2299. I2 : TObjSection absolute Item2;
  2300. begin
  2301. Result:=CompareStr(I1.Name,I2.Name);
  2302. end;
  2303. procedure TCoffexeoutput.Order_ObjSectionList(ObjSectionList: TFPObjectList;const aPattern:string);
  2304. begin
  2305. { Sort sections having '$' in the name, that's how PECOFF documentation
  2306. tells to handle them. However, look for '$' in the pattern, not in section
  2307. names, because the latter often get superfluous '$' due to mangling. }
  2308. if Pos('$',aPattern)>0 then
  2309. ObjSectionList.Sort(@IdataObjSectionCompare);
  2310. end;
  2311. constructor TDJCoffexeoutput.create;
  2312. begin
  2313. inherited createcoff(false);
  2314. datapos_offset:=sizeof(go32v2stub);
  2315. CExeSection:=TExeSection;
  2316. CObjData:=TDJCoffObjData;
  2317. end;
  2318. procedure TDJCoffexeoutput.MemPos_Header;
  2319. begin
  2320. { Headers are not loaded, first 4K page is reserved }
  2321. CurrMemPos:=$1000;
  2322. end;
  2323. constructor TPECoffexeoutput.create;
  2324. begin
  2325. inherited createcoff(true);
  2326. CExeSection:=TExeSection;
  2327. CObjData:=TPECoffObjData;
  2328. end;
  2329. procedure TPECoffexeoutput.MarkTargetSpecificSections(WorkList:TFPObjectList);
  2330. var
  2331. exesec:TExeSection;
  2332. objsec,textsec:TObjSection;
  2333. objreloc:TObjRelocation;
  2334. i,j:longint;
  2335. begin
  2336. if target_info.system<>system_x86_64_win64 then
  2337. exit;
  2338. exesec:=FindExeSection('.pdata');
  2339. if exesec=nil then
  2340. exit;
  2341. for i:=0 to exesec.ObjSectionList.Count-1 do
  2342. begin
  2343. objsec:=TObjSection(exesec.ObjSectionList[i]);
  2344. if objsec.Used then
  2345. continue;
  2346. j:=0;
  2347. while j<objsec.ObjRelocations.Count do
  2348. begin
  2349. objreloc:=TObjRelocation(objsec.ObjRelocations[j]);
  2350. if objreloc.symbol=nil then
  2351. InternalError(2013041201);
  2352. textsec:=objreloc.symbol.objsection;
  2353. if textsec.used then
  2354. begin
  2355. WorkList.Add(objsec);
  2356. objsec.used:=true;
  2357. { The exact algorithm for non-smartlinked .pdata sections
  2358. is subject for refinement. Extreme cases are:
  2359. - several disjoint .pdata entries for a function, if function
  2360. is complex or if compiler splits it into chunks,
  2361. - single .pdata section referencing several .text sections,
  2362. may need to remove irrelevant parts like BFD does for
  2363. .eh_frame sections. }
  2364. break;
  2365. end;
  2366. inc(j,3);
  2367. end;
  2368. end;
  2369. end;
  2370. procedure TPECoffexeoutput.AfterUnusedSectionRemoval;
  2371. var
  2372. basedllname : string;
  2373. procedure StartImport(const dllname:string);
  2374. begin
  2375. if assigned(exemap) then
  2376. begin
  2377. exemap.Add('');
  2378. exemap.Add('Importing from DLL '+dllname);
  2379. end;
  2380. basedllname:=ExtractFileName(dllname);
  2381. { idata2 }
  2382. idata2objsection.writereloc_internal(idata4objsection,idata4objsection.size,sizeof(longint),RELOC_RVA);
  2383. idata2objsection.writezeros(2*sizeof(longint));
  2384. idata2objsection.writereloc_internal(idata7objsection,idata7objsection.size,sizeof(longint),RELOC_RVA);
  2385. idata2objsection.writereloc_internal(idata5objsection,idata5objsection.size,sizeof(longint),RELOC_RVA);
  2386. { idata7 }
  2387. idata7objsection.writestr(basedllname);
  2388. end;
  2389. procedure EndImport;
  2390. begin
  2391. { idata4 }
  2392. idata4objsection.writezeros(sizeof(longint));
  2393. if target_info.system=system_x86_64_win64 then
  2394. idata4objsection.writezeros(sizeof(longint));
  2395. { idata5 }
  2396. idata5objsection.writezeros(sizeof(longint));
  2397. if target_info.system=system_x86_64_win64 then
  2398. idata5objsection.writezeros(sizeof(longint));
  2399. end;
  2400. function AddImport(const afuncname,amangledname:string; AOrdNr:longint;isvar:boolean):TObjSymbol;
  2401. const
  2402. {$ifdef arm}
  2403. jmpopcode : array[0..7] of byte = (
  2404. $00,$c0,$9f,$e5, // ldr ip, [pc, #0]
  2405. $00,$f0,$9c,$e5 // ldr pc, [ip]
  2406. );
  2407. {$else arm}
  2408. jmpopcode : array[0..1] of byte = (
  2409. $ff,$25
  2410. );
  2411. {$endif arm}
  2412. nopopcodes : array[0..1] of byte = (
  2413. $90,$90
  2414. );
  2415. var
  2416. ordint: dword;
  2417. procedure WriteTableEntry(objsec:TObjSection);
  2418. begin
  2419. if AOrdNr <= 0 then
  2420. begin
  2421. objsec.writereloc_internal(idata6objsection,idata6objsection.size,sizeof(longint),RELOC_RVA);
  2422. if target_info.system=system_x86_64_win64 then
  2423. objsec.writezeros(sizeof(longint));
  2424. end
  2425. else
  2426. begin
  2427. { import by ordinal }
  2428. ordint:=AOrdNr;
  2429. if target_info.system=system_x86_64_win64 then
  2430. begin
  2431. objsec.write(ordint,sizeof(ordint));
  2432. ordint:=$80000000;
  2433. objsec.write(ordint,sizeof(ordint));
  2434. end
  2435. else
  2436. begin
  2437. ordint:=ordint or $80000000;
  2438. objsec.write(ordint,sizeof(ordint));
  2439. end;
  2440. end;
  2441. end;
  2442. begin
  2443. result:=nil;
  2444. if assigned(exemap) then
  2445. begin
  2446. if AOrdNr <= 0 then
  2447. exemap.Add(' Importing Function '+afuncname)
  2448. else
  2449. exemap.Add(' Importing Function '+afuncname+' (OrdNr='+tostr(AOrdNr)+')');
  2450. end;
  2451. { idata4, import lookup table }
  2452. WriteTableEntry(idata4objsection);
  2453. { idata5, import address table }
  2454. internalobjdata.SetSection(idata5objsection);
  2455. if isvar then
  2456. result:=internalobjdata.SymbolDefine(amangledname,AB_GLOBAL,AT_DATA)
  2457. else
  2458. begin
  2459. internalobjdata.SetSection(textobjsection);
  2460. textobjsection.writezeros(align_aword(textobjsection.size,16)-textobjsection.size);
  2461. result:=internalobjdata.SymbolDefine('_'+amangledname,AB_GLOBAL,AT_FUNCTION);
  2462. textobjsection.write(jmpopcode,sizeof(jmpopcode));
  2463. {$ifdef x86_64}
  2464. textobjsection.writereloc_internal(idata5objsection,idata5objsection.size,4,RELOC_RELATIVE);
  2465. {$else}
  2466. textobjsection.writereloc_internal(idata5objsection,idata5objsection.size,4,RELOC_ABSOLUTE32);
  2467. {$endif x86_64}
  2468. textobjsection.write(nopopcodes,align(textobjsection.size,sizeof(nopopcodes))-textobjsection.size);
  2469. end;
  2470. { idata5 section data }
  2471. WriteTableEntry(idata5objsection);
  2472. if (AOrdNr<=0) then
  2473. begin
  2474. { index hint, function name, null terminator and align }
  2475. ordint:=abs(AOrdNr);
  2476. idata6objsection.write(ordint,2);
  2477. idata6objsection.writestr(afuncname);
  2478. idata6objsection.writezeros(align(idata6objsection.size,2)-idata6objsection.size);
  2479. end;
  2480. end;
  2481. var
  2482. i,j : longint;
  2483. ImportLibrary : TImportLibrary;
  2484. ImportSymbol : TImportSymbol;
  2485. exesym : TExeSymbol;
  2486. newdll : boolean;
  2487. begin
  2488. for i:=0 to FImports.Count-1 do
  2489. begin
  2490. ImportLibrary:=TImportLibrary(FImports[i]);
  2491. newdll:=False;
  2492. for j:=0 to ImportLibrary.ImportSymbolList.Count-1 do
  2493. begin
  2494. ImportSymbol:=TImportSymbol(ImportLibrary.ImportSymbolList[j]);
  2495. exesym:=ImportSymbol.CachedExeSymbol;
  2496. if assigned(exesym) and
  2497. exesym.Used then
  2498. begin
  2499. if (not newdll) then
  2500. StartImport(ImportLibrary.Name);
  2501. newdll:=True;
  2502. exesym.objsymbol:=AddImport(ImportSymbol.Name,ImportSymbol.MangledName,ImportSymbol.OrdNr,ImportSymbol.IsVar);
  2503. end;
  2504. end;
  2505. if newdll then
  2506. EndImport;
  2507. end;
  2508. FixupSymbols;
  2509. end;
  2510. procedure TPECoffexeoutput.GenerateLibraryImports(ImportLibraryList:TFPHashObjectList);
  2511. var
  2512. i,j: longint;
  2513. ImportLibrary: TImportLibrary;
  2514. ImportSymbol: TImportSymbol;
  2515. exesym: TExeSymbol;
  2516. begin
  2517. { Here map import symbols to exe symbols and create necessary sections.
  2518. Actual import generation is done after unused sections (and symbols) are removed. }
  2519. FImports:=ImportLibraryList;
  2520. textobjsection:=internalObjData.CreateSection(sec_code);
  2521. textobjsection.SecOptions:=[oso_keep];
  2522. idata2objsection:=internalObjData.CreateSection(sec_idata2);
  2523. idata2objsection.SecOptions:=[oso_keep];
  2524. idata4objsection:=internalObjData.CreateSection(sec_idata4);
  2525. idata4objsection.SecOptions:=[oso_keep];
  2526. idata5objsection:=internalObjData.CreateSection(sec_idata5);
  2527. idata5objsection.SecOptions:=[oso_keep];
  2528. idata6objsection:=internalObjData.CreateSection(sec_idata6);
  2529. idata6objsection.SecOptions:=[oso_keep];
  2530. idata7objsection:=internalObjData.CreateSection(sec_idata7);
  2531. idata7objsection.SecOptions:=[oso_keep];
  2532. for i:=0 to ImportLibraryList.Count-1 do
  2533. begin
  2534. ImportLibrary:=TImportLibrary(ImportLibraryList[i]);
  2535. for j:=0 to ImportLibrary.ImportSymbolList.Count-1 do
  2536. begin
  2537. ImportSymbol:=TImportSymbol(ImportLibrary.ImportSymbolList[j]);
  2538. exesym:=TExeSymbol(ExeSymbolList.Find(ImportSymbol.MangledName));
  2539. if assigned(exesym) and
  2540. (exesym.State<>symstate_defined) then
  2541. begin
  2542. ImportSymbol.CachedExeSymbol:=exesym;
  2543. exesym.State:=symstate_defined;
  2544. end;
  2545. end;
  2546. end;
  2547. PackUnresolvedExeSymbols('after DLL imports');
  2548. end;
  2549. procedure TPECoffexeoutput.GenerateRelocs;
  2550. var
  2551. pgaddr, hdrpos : longword;
  2552. procedure FinishBlock;
  2553. var
  2554. p,len : longint;
  2555. begin
  2556. if hdrpos = longword(-1) then
  2557. exit;
  2558. p:=0;
  2559. internalobjdata.writebytes(p,align(internalobjdata.CurrObjSec.size,4)-internalobjdata.CurrObjSec.size);
  2560. p:=internalObjData.CurrObjSec.Data.Pos;
  2561. internalObjData.CurrObjSec.Data.seek(hdrpos+4);
  2562. len:=p-hdrpos;
  2563. internalObjData.CurrObjSec.Data.write(len,4);
  2564. internalObjData.CurrObjSec.Data.seek(p);
  2565. hdrpos:=longword(-1);
  2566. end;
  2567. var
  2568. exesec : TExeSection;
  2569. objsec : TObjSection;
  2570. objreloc : TObjRelocation;
  2571. i,j,k : longint;
  2572. offset : longword;
  2573. w: word;
  2574. begin
  2575. if not RelocSection or FRelocsGenerated then
  2576. exit;
  2577. exesec:=FindExeSection('.reloc');
  2578. if exesec=nil then
  2579. exit;
  2580. objsec:=internalObjData.createsection('.reloc',0,[oso_data,oso_keep]);
  2581. exesec.AddObjSection(objsec);
  2582. pgaddr:=longword(-1);
  2583. hdrpos:=longword(-1);
  2584. for i:=0 to ExeSectionList.Count-1 do
  2585. begin
  2586. exesec:=TExeSection(ExeSectionList[i]);
  2587. for j:=0 to exesec.ObjSectionList.count-1 do
  2588. begin
  2589. objsec:=TObjSection(exesec.ObjSectionList[j]);
  2590. { create relocs only for sections which are loaded in memory }
  2591. if not (oso_load in objsec.SecOptions) then
  2592. continue;
  2593. for k:=0 to objsec.ObjRelocations.Count-1 do
  2594. begin
  2595. objreloc:=TObjRelocation(objsec.ObjRelocations[k]);
  2596. if not (objreloc.typ in [{$ifdef cpu64bitaddr}RELOC_ABSOLUTE32,{$endif cpu64bitaddr}RELOC_ABSOLUTE]) then
  2597. continue;
  2598. offset:=objsec.MemPos+objreloc.dataoffset;
  2599. if (offset<pgaddr) and (pgaddr<>longword(-1)) then
  2600. Internalerror(2007062701);
  2601. if (offset-pgaddr>=4096) or (pgaddr=longword(-1)) then
  2602. begin
  2603. FinishBlock;
  2604. pgaddr:=(offset div 4096)*4096;
  2605. hdrpos:=internalObjData.CurrObjSec.Data.Pos;
  2606. internalObjData.writebytes(pgaddr,4);
  2607. { Reserving space for block size. The size will be written later in FinishBlock }
  2608. internalObjData.writebytes(k,4);
  2609. end;
  2610. {$ifdef cpu64bitaddr}
  2611. if objreloc.typ = RELOC_ABSOLUTE then
  2612. w:=IMAGE_REL_BASED_DIR64
  2613. else
  2614. {$endif cpu64bitaddr}
  2615. w:=IMAGE_REL_BASED_HIGHLOW;
  2616. w:=(w shl 12) or (offset-pgaddr);
  2617. internalObjData.writebytes(w,2);
  2618. end;
  2619. end;
  2620. end;
  2621. FinishBlock;
  2622. FRelocsGenerated:=true;
  2623. end;
  2624. procedure TPECoffexeoutput.MemPos_Start;
  2625. var
  2626. exesec : TExeSection;
  2627. begin
  2628. if RelocSection then
  2629. begin
  2630. exesec:=FindExeSection('.reloc');
  2631. if exesec=nil then
  2632. InternalError(2012072401);
  2633. exesec.Disabled:=false;
  2634. end;
  2635. inherited;
  2636. end;
  2637. procedure TPECoffexeoutput.MemPos_ExeSection(const aname:string);
  2638. begin
  2639. if aname='.reloc' then
  2640. GenerateRelocs;
  2641. inherited;
  2642. end;
  2643. {****************************************************************************
  2644. TDJCoffAssembler
  2645. ****************************************************************************}
  2646. constructor TDJCoffAssembler.Create(info: pasminfo; smart:boolean);
  2647. begin
  2648. inherited;
  2649. CObjOutput:=TDJCoffObjOutput;
  2650. CInternalAr:=tarobjectwriter;
  2651. end;
  2652. {****************************************************************************
  2653. TPECoffAssembler
  2654. ****************************************************************************}
  2655. constructor TPECoffAssembler.Create(info: pasminfo; smart:boolean);
  2656. begin
  2657. inherited;
  2658. CObjOutput:=TPECoffObjOutput;
  2659. CInternalAr:=tarobjectwriter;
  2660. end;
  2661. {*****************************************************************************
  2662. DLLReader
  2663. *****************************************************************************}
  2664. {$ifdef win32}
  2665. var
  2666. Wow64DisableWow64FsRedirection : function (var OldValue : pointer) : boolean;stdcall;
  2667. Wow64RevertWow64FsRedirection : function (OldValue : pointer) : boolean;stdcall;
  2668. {$endif win32}
  2669. function ReadDLLImports(const dllname:string;readdllproc:Treaddllproc):boolean;
  2670. type
  2671. TPECoffExpDir=packed record
  2672. flag,
  2673. stamp : cardinal;
  2674. Major,
  2675. Minor : word;
  2676. Name,
  2677. Base,
  2678. NumFuncs,
  2679. NumNames,
  2680. AddrFuncs,
  2681. AddrNames,
  2682. AddrOrds : cardinal;
  2683. end;
  2684. var
  2685. DLLReader : TObjectReader;
  2686. DosHeader : array[0..$7f] of byte;
  2687. PEMagic : array[0..3] of byte;
  2688. Header : TCoffHeader;
  2689. peheader : tcoffpeoptheader;
  2690. NameOfs,
  2691. newheaderofs : longword;
  2692. FuncName : string;
  2693. expdir : TPECoffExpDir;
  2694. i : longint;
  2695. found : boolean;
  2696. sechdr : tCoffSecHdr;
  2697. {$ifdef win32}
  2698. p : pointer;
  2699. {$endif win32}
  2700. begin
  2701. result:=false;
  2702. fillchar(sechdr,sizeof(sechdr),0);
  2703. {$ifdef win32}
  2704. if (target_info.system=system_x86_64_win64) and
  2705. assigned(Wow64DisableWow64FsRedirection) then
  2706. Wow64DisableWow64FsRedirection(p);
  2707. {$endif win32}
  2708. DLLReader:=TObjectReader.Create;
  2709. DLLReader.OpenFile(dllname);
  2710. {$ifdef win32}
  2711. if (target_info.system=system_x86_64_win64) and
  2712. assigned(Wow64RevertWow64FsRedirection) then
  2713. Wow64RevertWow64FsRedirection(p);
  2714. {$endif win32}
  2715. if not DLLReader.Read(DosHeader,sizeof(DosHeader)) or
  2716. (DosHeader[0]<>$4d) or (DosHeader[1]<>$5a) then
  2717. begin
  2718. Comment(V_Error,'Invalid DLL '+dllname+', Dos Header invalid');
  2719. exit;
  2720. end;
  2721. newheaderofs:=cardinal(DosHeader[$3c]) or (DosHeader[$3d] shl 8) or (DosHeader[$3e] shl 16) or (DosHeader[$3f] shl 24);
  2722. DLLReader.Seek(newheaderofs);
  2723. if not DLLReader.Read(PEMagic,sizeof(PEMagic)) or
  2724. (PEMagic[0]<>$50) or (PEMagic[1]<>$45) or (PEMagic[2]<>$00) or (PEMagic[3]<>$00) then
  2725. begin
  2726. Comment(V_Error,'Invalid DLL '+dllname+': invalid magic code');
  2727. exit;
  2728. end;
  2729. if not DLLReader.Read(Header,sizeof(TCoffHeader)) or
  2730. (Header.mach<>COFF_MAGIC) or
  2731. (Header.opthdr<>sizeof(tcoffpeoptheader)) then
  2732. begin
  2733. Comment(V_Error,'Invalid DLL '+dllname+', invalid header size');
  2734. exit;
  2735. end;
  2736. { Read optheader }
  2737. DLLreader.Read(peheader,sizeof(tcoffpeoptheader));
  2738. { Section headers }
  2739. found:=false;
  2740. for i:=1 to header.nsects do
  2741. begin
  2742. if not DLLreader.read(sechdr,sizeof(sechdr)) then
  2743. begin
  2744. Comment(V_Error,'Error reading coff file '+DLLName);
  2745. exit;
  2746. end;
  2747. if (sechdr.rvaofs<=peheader.DataDirectory[PE_DATADIR_EDATA].vaddr) and
  2748. (peheader.DataDirectory[PE_DATADIR_EDATA].vaddr<sechdr.rvaofs+sechdr.vsize) then
  2749. begin
  2750. found:=true;
  2751. break;
  2752. end;
  2753. end;
  2754. if not found then
  2755. begin
  2756. Comment(V_Warning,'DLL '+DLLName+' does not contain any exports');
  2757. exit;
  2758. end;
  2759. { Process edata }
  2760. DLLReader.Seek(sechdr.datapos+peheader.DataDirectory[PE_DATADIR_EDATA].vaddr-sechdr.rvaofs);
  2761. DLLReader.Read(expdir,sizeof(expdir));
  2762. for i:=0 to expdir.NumNames-1 do
  2763. begin
  2764. DLLReader.Seek(sechdr.datapos+expdir.AddrNames-sechdr.rvaofs+i*4);
  2765. DLLReader.Read(NameOfs,4);
  2766. Dec(NameOfs,sechdr.rvaofs);
  2767. if {(NameOfs<0) or}
  2768. (NameOfs>sechdr.vsize) then
  2769. begin
  2770. Comment(V_Error,'DLL does contains invalid exports');
  2771. break;
  2772. end;
  2773. { Read Function name from DLL, prepend _ and terminate with #0 }
  2774. DLLReader.Seek(sechdr.datapos+NameOfs);
  2775. DLLReader.Read((@FuncName[1])^,sizeof(FuncName)-3);
  2776. FuncName[sizeof(FuncName)-1]:=#0;
  2777. FuncName[0]:=chr(Strlen(@FuncName[1]));
  2778. readdllproc(DLLName,FuncName);
  2779. end;
  2780. DLLReader.Free;
  2781. end;
  2782. {$ifdef arm}
  2783. function COFF_MAGIC: word;
  2784. begin
  2785. if GenerateThumb2Code and (current_settings.cputype>=cpu_armv7) then
  2786. COFF_MAGIC:=$1c4 // IMAGE_FILE_MACHINE_ARMNT
  2787. else
  2788. COFF_MAGIC:=$1c0; // IMAGE_FILE_MACHINE_ARM
  2789. end;
  2790. {$endif arm}
  2791. {*****************************************************************************
  2792. Initialize
  2793. *****************************************************************************}
  2794. {$ifdef i386}
  2795. const
  2796. as_i386_coff_info : tasminfo =
  2797. (
  2798. id : as_i386_coff;
  2799. idtxt : 'COFF';
  2800. asmbin : '';
  2801. asmcmd : '';
  2802. supported_targets : [system_i386_go32v2];
  2803. flags : [af_outputbinary,af_smartlink_sections];
  2804. labelprefix : '.L';
  2805. comment : '';
  2806. dollarsign: '$';
  2807. );
  2808. as_i386_pecoff_info : tasminfo =
  2809. (
  2810. id : as_i386_pecoff;
  2811. idtxt : 'PECOFF';
  2812. asmbin : '';
  2813. asmcmd : '';
  2814. supported_targets : [system_i386_win32,system_i386_nativent];
  2815. flags : [af_outputbinary,af_smartlink_sections];
  2816. labelprefix : '.L';
  2817. comment : '';
  2818. dollarsign: '$';
  2819. );
  2820. as_i386_pecoffwdosx_info : tasminfo =
  2821. (
  2822. id : as_i386_pecoffwdosx;
  2823. idtxt : 'PEWDOSX';
  2824. asmbin : '';
  2825. asmcmd : '';
  2826. supported_targets : [system_i386_wdosx];
  2827. flags : [af_outputbinary];
  2828. labelprefix : '.L';
  2829. comment : '';
  2830. dollarsign: '$';
  2831. );
  2832. as_i386_pecoffwince_info : tasminfo =
  2833. (
  2834. id : as_i386_pecoffwince;
  2835. idtxt : 'PECOFFWINCE';
  2836. asmbin : '';
  2837. asmcmd : '';
  2838. supported_targets : [system_i386_wince];
  2839. flags : [af_outputbinary,af_smartlink_sections];
  2840. labelprefix : '.L';
  2841. comment : '';
  2842. dollarsign: '$';
  2843. );
  2844. {$endif i386}
  2845. {$ifdef x86_64}
  2846. const
  2847. as_x86_64_pecoff_info : tasminfo =
  2848. (
  2849. id : as_x86_64_pecoff;
  2850. idtxt : 'PECOFF';
  2851. asmbin : '';
  2852. asmcmd : '';
  2853. supported_targets : [system_x86_64_win64];
  2854. flags : [af_outputbinary,af_smartlink_sections];
  2855. labelprefix : '.L';
  2856. comment : '';
  2857. dollarsign: '$';
  2858. );
  2859. {$endif x86_64}
  2860. {$ifdef arm}
  2861. const
  2862. as_arm_pecoffwince_info : tasminfo =
  2863. (
  2864. id : as_arm_pecoffwince;
  2865. idtxt : 'PECOFFWINCE';
  2866. asmbin : '';
  2867. asmcmd : '';
  2868. supported_targets : [system_arm_wince];
  2869. flags : [af_outputbinary,af_smartlink_sections];
  2870. labelprefix : '.L';
  2871. comment : '';
  2872. dollarsign: '$';
  2873. );
  2874. {$endif arm}
  2875. {$ifdef win32}
  2876. procedure SetupProcVars;
  2877. var
  2878. hinstLib : THandle;
  2879. begin
  2880. Wow64DisableWow64FsRedirection:=nil;
  2881. Wow64RevertWow64FsRedirection:=nil;
  2882. hinstLib:=LoadLibrary('kernel32.dll');
  2883. if hinstLib<>0 then
  2884. begin
  2885. pointer(Wow64DisableWow64FsRedirection):=GetProcAddress(hinstLib,'Wow64DisableWow64FsRedirection');
  2886. pointer(Wow64RevertWow64FsRedirection):=GetProcAddress(hinstLib,'Wow64RevertWow64FsRedirection');
  2887. FreeLibrary(hinstLib);
  2888. end;
  2889. end;
  2890. {$endif win32}
  2891. initialization
  2892. {$ifdef i386}
  2893. RegisterAssembler(as_i386_coff_info,TDJCoffAssembler);
  2894. RegisterAssembler(as_i386_pecoff_info,TPECoffAssembler);
  2895. RegisterAssembler(as_i386_pecoffwdosx_info,TPECoffAssembler);
  2896. RegisterAssembler(as_i386_pecoffwince_info,TPECoffAssembler);
  2897. {$endif i386}
  2898. {$ifdef x86_64}
  2899. RegisterAssembler(as_x86_64_pecoff_info,TPECoffAssembler);
  2900. {$endif x86_64}
  2901. {$ifdef arm}
  2902. RegisterAssembler(as_arm_pecoffwince_info,TPECoffAssembler);
  2903. {$endif arm}
  2904. {$ifdef win32}
  2905. SetupProcVars;
  2906. {$endif win32}
  2907. end.