ogcoff.pas 114 KB

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