ogcoff.pas 60 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768
  1. {
  2. Copyright (c) 1998-2002 by Peter Vreman and Pierre Muller
  3. Contains the binary coff reader and writer
  4. * This code was inspired by the NASM sources
  5. The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  6. Julian Hall. All rights reserved.
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. ****************************************************************************
  19. }
  20. unit ogcoff;
  21. {$i fpcdefs.inc}
  22. interface
  23. uses
  24. { common }
  25. cclasses,globtype,
  26. { target }
  27. systems,
  28. { assembler }
  29. cpuinfo,cpubase,aasmbase,assemble,link,
  30. { output }
  31. ogbase,ogmap;
  32. type
  33. TCoffObjectSection = class(TAsmSection)
  34. private
  35. orgmempos,
  36. coffrelocs,
  37. coffrelocpos : longint;
  38. public
  39. flags : cardinal;
  40. constructor create(const Aname:string;Atype:TAsmSectionType;Aalign:longint;Aoptions:TAsmSectionOptions);override;
  41. procedure addsymsizereloc(ofs:longint;p:tasmsymbol;size:longint;relative:TAsmRelocationType);
  42. procedure fixuprelocs;override;
  43. end;
  44. TDjCoffObjectSection = class(TCoffObjectSection)
  45. constructor create(const Aname:string;Atype:TAsmSectionType;Aalign:longint;Aoptions:TAsmSectionOptions);override;
  46. end;
  47. TPECoffObjectSection = class(TCoffObjectSection)
  48. constructor create(const Aname:string;Atype:TAsmSectionType;Aalign:longint;Aoptions:TAsmSectionOptions);override;
  49. end;
  50. tcoffobjectdata = class(TAsmObjectData)
  51. private
  52. win32 : boolean;
  53. procedure section_mempos(p:tnamedindexitem;arg:pointer);
  54. public
  55. constructor createcoff(const n:string;awin32:boolean;acasmsection:TAsmSectionClass);
  56. destructor destroy;override;
  57. function sectionname(atype:tasmsectiontype;const aname:string):string;override;
  58. procedure writereloc(data,len:aint;p:tasmsymbol;relative:TAsmRelocationType);override;
  59. procedure writesymbol(p:tasmsymbol);override;
  60. procedure writestab(offset:aint;ps:tasmsymbol;nidx,nother,line:longint;p:pchar);override;
  61. procedure beforealloc;override;
  62. procedure beforewrite;override;
  63. procedure afteralloc;override;
  64. end;
  65. tdjcoffobjectdata = class(TCoffObjectData)
  66. constructor create(const n:string);override;
  67. end;
  68. tpecoffobjectdata = class(TCoffObjectData)
  69. constructor create(const n:string);override;
  70. end;
  71. tcoffobjectoutput = class(tobjectoutput)
  72. private
  73. win32 : boolean;
  74. initsym : longint;
  75. FCoffStrs : tdynamicarray;
  76. procedure write_symbol(const name:string;value,section,typ,aux:longint);
  77. procedure section_write_symbol(p:tnamedindexitem;arg:pointer);
  78. procedure section_write_relocs(p:tnamedindexitem;arg:pointer);
  79. procedure write_symbols(data:TAsmObjectData);
  80. procedure section_set_secsymidx(p:tnamedindexitem;arg:pointer);
  81. procedure section_set_datapos(p:tnamedindexitem;arg:pointer);
  82. procedure section_set_reloc_datapos(p:tnamedindexitem;arg:pointer);
  83. procedure section_write_header(p:tnamedindexitem;arg:pointer);
  84. procedure section_write_data(p:tnamedindexitem;arg:pointer);
  85. protected
  86. function writedata(data:TAsmObjectData):boolean;override;
  87. public
  88. constructor createdjgpp(smart:boolean);
  89. constructor createwin32(smart:boolean);
  90. function newobjectdata(const n:string):TAsmObjectData;override;
  91. end;
  92. tcoffexeoutput = class(texeoutput)
  93. private
  94. FCoffsyms,
  95. FCoffStrs : tdynamicarray;
  96. win32 : boolean;
  97. nsects,
  98. nsyms,
  99. sympos : longint;
  100. procedure write_symbol(const name:string;value,section,typ,aux:longint);
  101. procedure write_symbols;
  102. protected
  103. function writedata:boolean;override;
  104. public
  105. constructor createdjgpp;
  106. constructor createwin32;
  107. function newobjectinput:tobjectinput;override;
  108. procedure CalculateMemoryMap;override;
  109. procedure GenerateExecutable(const fn:string);override;
  110. end;
  111. ttasmsymbolrec = record
  112. sym : tasmsymbol;
  113. orgsize : longint;
  114. end;
  115. ttasmsymbolarray = array[0..high(word)] of ttasmsymbolrec;
  116. tcoffobjectinput = class(tobjectinput)
  117. private
  118. Fidx2sec : array[0..255] of TAsmSection;
  119. FCoffsyms,
  120. FCoffStrs : tdynamicarray;
  121. FSymTbl : ^ttasmsymbolarray;
  122. win32 : boolean;
  123. procedure read_relocs(s:TCoffObjectSection);
  124. procedure handle_symbols(data:TAsmObjectData);
  125. protected
  126. function readobjectdata(data:TAsmObjectData):boolean;override;
  127. public
  128. constructor createdjgpp;
  129. constructor createwin32;
  130. function newobjectdata(const n:string):TAsmObjectData;override;
  131. end;
  132. tcoffassembler = class(tinternalassembler)
  133. constructor create(smart:boolean);override;
  134. end;
  135. tpecoffassembler = class(tinternalassembler)
  136. constructor create(smart:boolean);override;
  137. end;
  138. tcofflinker = class(tinternallinker)
  139. constructor create;override;
  140. end;
  141. implementation
  142. uses
  143. strings,
  144. cutils,verbose,
  145. globals,fmodule;
  146. const
  147. COFF_FLAG_NORELOCS = $0001;
  148. COFF_FLAG_EXE = $0002;
  149. COFF_FLAG_NOLINES = $0004;
  150. COFF_FLAG_NOLSYMS = $0008;
  151. COFF_FLAG_AR16WR = $0080; { 16bit little endian }
  152. COFF_FLAG_AR32WR = $0100; { 32bit little endian }
  153. COFF_FLAG_AR32W = $0200; { 32bit big endian }
  154. COFF_FLAG_DLL = $2000;
  155. COFF_SYM_GLOBAL = 2;
  156. COFF_SYM_LOCAL = 3;
  157. COFF_SYM_LABEL = 6;
  158. COFF_SYM_FUNCTION = 101;
  159. COFF_SYM_FILE = 103;
  160. COFF_SYM_SECTION = 104;
  161. type
  162. { Structures which are written directly to the output file }
  163. coffheader=packed record
  164. mach : word;
  165. nsects : word;
  166. time : longint;
  167. sympos : longint;
  168. syms : longint;
  169. opthdr : word;
  170. flag : word;
  171. end;
  172. coffoptheader=packed record
  173. magic : word;
  174. vstamp : word;
  175. tsize : longint;
  176. dsize : longint;
  177. bsize : longint;
  178. entry : longint;
  179. text_start : longint;
  180. data_start : longint;
  181. end;
  182. coffsechdr=packed record
  183. name : array[0..7] of char;
  184. vsize : longint;
  185. rvaofs : longint;
  186. datasize : longint;
  187. datapos : longint;
  188. relocpos : longint;
  189. lineno1 : longint;
  190. nrelocs : word;
  191. lineno2 : word;
  192. flags : cardinal;
  193. end;
  194. coffsectionrec=packed record
  195. len : longint;
  196. nrelocs : word;
  197. empty : array[0..11] of char;
  198. end;
  199. coffreloc=packed record
  200. address : longint;
  201. sym : longint;
  202. relative : word;
  203. end;
  204. coffsymbol=packed record
  205. name : array[0..3] of char; { real is [0..7], which overlaps the strpos ! }
  206. strpos : longint;
  207. value : longint;
  208. section : smallint;
  209. empty : smallint;
  210. typ : byte;
  211. aux : byte;
  212. end;
  213. coffstab=packed record
  214. strpos : longint;
  215. ntype : byte;
  216. nother : byte;
  217. ndesc : word;
  218. nvalue : longint;
  219. end;
  220. const
  221. symbolresize = 200*sizeof(coffsymbol);
  222. strsresize = 8192;
  223. const go32v2stub : array[0..2047] of byte=(
  224. $4D,$5A,$00,$00,$04,$00,$00,$00,$20,$00,$27,$00,$FF,$FF,$00,
  225. $00,$60,$07,$00,$00,$54,$00,$00,$00,$00,$00,$00,$00,$0D,$0A,
  226. $73,$74,$75,$62,$2E,$68,$20,$67,$65,$6E,$65,$72,$61,$74,$65,
  227. $64,$20,$66,$72,$6F,$6D,$20,$73,$74,$75,$62,$2E,$61,$73,$6D,
  228. $20,$62,$79,$20,$64,$6A,$61,$73,$6D,$2C,$20,$6F,$6E,$20,$54,
  229. $68,$75,$20,$44,$65,$63,$20,$20,$39,$20,$31,$30,$3A,$35,$39,
  230. $3A,$33,$31,$20,$31,$39,$39,$39,$0D,$0A,$54,$68,$65,$20,$53,
  231. $54,$55,$42,$2E,$45,$58,$45,$20,$73,$74,$75,$62,$20,$6C,$6F,
  232. $61,$64,$65,$72,$20,$69,$73,$20,$43,$6F,$70,$79,$72,$69,$67,
  233. $68,$74,$20,$28,$43,$29,$20,$31,$39,$39,$33,$2D,$31,$39,$39,
  234. $35,$20,$44,$4A,$20,$44,$65,$6C,$6F,$72,$69,$65,$2E,$20,$0D,
  235. $0A,$50,$65,$72,$6D,$69,$73,$73,$69,$6F,$6E,$20,$67,$72,$61,
  236. $6E,$74,$65,$64,$20,$74,$6F,$20,$75,$73,$65,$20,$66,$6F,$72,
  237. $20,$61,$6E,$79,$20,$70,$75,$72,$70,$6F,$73,$65,$20,$70,$72,
  238. $6F,$76,$69,$64,$65,$64,$20,$74,$68,$69,$73,$20,$63,$6F,$70,
  239. $79,$72,$69,$67,$68,$74,$20,$0D,$0A,$72,$65,$6D,$61,$69,$6E,
  240. $73,$20,$70,$72,$65,$73,$65,$6E,$74,$20,$61,$6E,$64,$20,$75,
  241. $6E,$6D,$6F,$64,$69,$66,$69,$65,$64,$2E,$20,$0D,$0A,$54,$68,
  242. $69,$73,$20,$6F,$6E,$6C,$79,$20,$61,$70,$70,$6C,$69,$65,$73,
  243. $20,$74,$6F,$20,$74,$68,$65,$20,$73,$74,$75,$62,$2C,$20,$61,
  244. $6E,$64,$20,$6E,$6F,$74,$20,$6E,$65,$63,$65,$73,$73,$61,$72,
  245. $69,$6C,$79,$20,$74,$68,$65,$20,$77,$68,$6F,$6C,$65,$20,$70,
  246. $72,$6F,$67,$72,$61,$6D,$2E,$0A,$0D,$0A,$24,$49,$64,$3A,$20,
  247. $73,$74,$75,$62,$2E,$61,$73,$6D,$20,$62,$75,$69,$6C,$74,$20,
  248. $31,$32,$2F,$30,$39,$2F,$39,$39,$20,$31,$30,$3A,$35,$39,$3A,
  249. $33,$31,$20,$62,$79,$20,$64,$6A,$61,$73,$6D,$20,$24,$0A,$0D,
  250. $0A,$40,$28,$23,$29,$20,$73,$74,$75,$62,$2E,$61,$73,$6D,$20,
  251. $62,$75,$69,$6C,$74,$20,$31,$32,$2F,$30,$39,$2F,$39,$39,$20,
  252. $31,$30,$3A,$35,$39,$3A,$33,$31,$20,$62,$79,$20,$64,$6A,$61,
  253. $73,$6D,$0A,$0D,$0A,$1A,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  254. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  255. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  256. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  257. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  258. $00,$00,$67,$6F,$33,$32,$73,$74,$75,$62,$2C,$20,$76,$20,$32,
  259. $2E,$30,$32,$54,$00,$00,$00,$00,$00,$08,$00,$00,$00,$00,$00,
  260. $00,$00,$00,$00,$00,$40,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  261. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  262. $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$43,$57,$53,$44,$50,
  263. $4D,$49,$2E,$45,$58,$45,$00,$00,$00,$00,$00,$0E,$1F,$8C,$1E,
  264. $24,$00,$8C,$06,$60,$07,$FC,$B4,$30,$CD,$21,$3C,$03,$73,$08,
  265. $B0,$6D,$BA,$A7,$05,$E9,$D4,$03,$A2,$69,$08,$BE,$20,$00,$8B,
  266. $04,$09,$C0,$75,$02,$B4,$FE,$BB,$70,$08,$39,$C3,$73,$02,$89,
  267. $C3,$89,$1C,$FE,$C7,$B9,$04,$FF,$D3,$EB,$B4,$4A,$CD,$21,$73,
  268. $08,$D3,$E3,$FE,$CF,$89,$1C,$EB,$D8,$26,$8E,$06,$2C,$00,$31,
  269. $FF,$30,$C0,$A9,$F2,$AE,$26,$81,$3D,$50,$41,$75,$15,$AF,$26,
  270. $81,$3D,$54,$48,$75,$0D,$AF,$26,$80,$3D,$3D,$75,$06,$47,$89,
  271. $3E,$8C,$04,$4F,$AE,$75,$DF,$AF,$B4,$3E,$BB,$13,$00,$CD,$21,
  272. $B4,$3E,$BB,$12,$00,$CD,$21,$06,$57,$31,$C9,$74,$12,$B0,$6E,
  273. $BA,$7E,$05,$E9,$5E,$03,$09,$C9,$75,$F4,$41,$E8,$A1,$03,$72,
  274. $EE,$B8,$87,$16,$CD,$2F,$09,$C0,$75,$ED,$80,$E3,$01,$74,$E8,
  275. $89,$3E,$00,$06,$8C,$06,$02,$06,$89,$36,$04,$06,$5F,$07,$E8,
  276. $D3,$02,$89,$3E,$2A,$00,$89,$36,$62,$07,$80,$3E,$2C,$00,$00,
  277. $74,$23,$B9,$08,$00,$BF,$2C,$00,$8A,$05,$47,$08,$C0,$74,$05,
  278. $88,$07,$43,$E2,$F4,$66,$C7,$07,$2E,$45,$58,$45,$83,$C3,$04,
  279. $C6,$07,$00,$89,$1E,$62,$07,$B8,$00,$3D,$BA,$64,$07,$CD,$21,
  280. $0F,$82,$B3,$02,$A3,$06,$06,$89,$C3,$B9,$06,$00,$BA,$B5,$07,
  281. $B4,$3F,$CD,$21,$31,$D2,$31,$C9,$A1,$B5,$07,$3D,$4C,$01,$74,
  282. $1B,$3D,$4D,$5A,$0F,$85,$98,$02,$8B,$16,$B9,$07,$C1,$E2,$09,
  283. $8B,$1E,$B7,$07,$09,$DB,$74,$05,$80,$EE,$02,$01,$DA,$89,$16,
  284. $BB,$07,$89,$0E,$BD,$07,$B8,$00,$42,$8B,$1E,$06,$06,$CD,$21,
  285. $B9,$A8,$00,$BA,$BF,$07,$B4,$3F,$CD,$21,$3D,$A8,$00,$75,$06,
  286. $81,$3E,$BF,$07,$4C,$01,$0F,$85,$61,$02,$66,$A1,$E3,$07,$66,
  287. $A3,$10,$06,$66,$8B,$0E,$BB,$07,$66,$A1,$03,$08,$66,$01,$C8,
  288. $66,$A3,$08,$06,$66,$A1,$2B,$08,$66,$01,$C8,$66,$A3,$0C,$06,
  289. $66,$8B,$1E,$4B,$08,$66,$A1,$4F,$08,$66,$01,$C3,$66,$B8,$01,
  290. $00,$01,$00,$66,$39,$C3,$73,$03,$66,$89,$C3,$66,$81,$C3,$FF,
  291. $FF,$00,$00,$31,$DB,$66,$89,$1E,$1C,$00,$E8,$F5,$02,$8B,$1E,
  292. $04,$06,$09,$DB,$74,$0A,$B4,$48,$CD,$21,$0F,$82,$15,$02,$8E,
  293. $C0,$E8,$08,$03,$B8,$01,$00,$FF,$1E,$00,$06,$0F,$82,$0F,$02,
  294. $8C,$06,$26,$00,$8C,$0E,$28,$00,$8C,$D8,$A3,$22,$00,$8E,$C0,
  295. $31,$C0,$B9,$01,$00,$CD,$31,$72,$07,$A3,$14,$06,$31,$C0,$CD,
  296. $31,$0F,$82,$F3,$01,$A3,$16,$06,$66,$8B,$0E,$1C,$00,$B8,$01,
  297. $05,$8B,$1E,$1E,$00,$CD,$31,$0F,$82,$E5,$01,$89,$1E,$1A,$06,
  298. $89,$0E,$18,$06,$89,$36,$1A,$00,$89,$3E,$18,$00,$B8,$07,$00,
  299. $8B,$1E,$14,$06,$8B,$0E,$1A,$06,$8B,$16,$18,$06,$CD,$31,$B8,
  300. $09,$00,$8C,$C9,$83,$E1,$03,$C1,$E1,$05,$51,$81,$C9,$9B,$C0,
  301. $CD,$31,$B8,$08,$00,$8B,$0E,$1E,$00,$49,$BA,$FF,$FF,$CD,$31,
  302. $B8,$07,$00,$8B,$1E,$16,$06,$8B,$0E,$1A,$06,$8B,$16,$18,$06,
  303. $CD,$31,$B8,$09,$00,$59,$81,$C9,$93,$C0,$CD,$31,$B8,$08,$00,
  304. $8B,$0E,$1E,$00,$49,$BA,$FF,$FF,$CD,$31,$B8,$00,$01,$BB,$00,
  305. $0F,$CD,$31,$73,$10,$3D,$08,$00,$0F,$85,$73,$01,$B8,$00,$01,
  306. $CD,$31,$0F,$82,$6A,$01,$A3,$1C,$06,$89,$16,$1E,$06,$C1,$E3,
  307. $04,$89,$1E,$20,$06,$66,$8B,$36,$08,$06,$66,$8B,$3E,$FB,$07,
  308. $66,$8B,$0E,$FF,$07,$E8,$49,$00,$66,$8B,$36,$0C,$06,$66,$8B,
  309. $3E,$23,$08,$66,$8B,$0E,$27,$08,$E8,$37,$00,$8E,$06,$16,$06,
  310. $66,$8B,$3E,$4B,$08,$66,$8B,$0E,$4F,$08,$66,$31,$C0,$66,$C1,
  311. $E9,$02,$67,$F3,$66,$AB,$B4,$3E,$8B,$1E,$06,$06,$CD,$21,$B8,
  312. $01,$01,$8B,$16,$1E,$06,$CD,$31,$1E,$0F,$A1,$8E,$1E,$16,$06,
  313. $66,$64,$FF,$2E,$10,$06,$66,$89,$F0,$66,$25,$FF,$01,$00,$00,
  314. $66,$01,$C1,$29,$C6,$66,$29,$C7,$66,$89,$0E,$26,$06,$66,$89,
  315. $3E,$22,$06,$E8,$0F,$01,$89,$36,$3E,$06,$66,$C1,$EE,$10,$89,
  316. $36,$42,$06,$8B,$1E,$06,$06,$89,$1E,$3A,$06,$C7,$06,$46,$06,
  317. $00,$42,$E8,$03,$01,$A1,$1C,$06,$A3,$4E,$06,$C7,$06,$3E,$06,
  318. $00,$00,$C6,$06,$47,$06,$3F,$A1,$28,$06,$09,$C0,$75,$09,$A1,
  319. $26,$06,$3B,$06,$20,$06,$76,$03,$A1,$20,$06,$A3,$42,$06,$E8,
  320. $D9,$00,$66,$31,$C9,$8B,$0E,$46,$06,$66,$8B,$3E,$22,$06,$66,
  321. $01,$0E,$22,$06,$66,$29,$0E,$26,$06,$66,$31,$F6,$C1,$E9,$02,
  322. $1E,$06,$8E,$06,$16,$06,$8E,$1E,$1E,$06,$67,$F3,$66,$A5,$07,
  323. $1F,$66,$03,$0E,$26,$06,$75,$AF,$C3,$3C,$3A,$74,$06,$3C,$2F,
  324. $74,$02,$3C,$5C,$C3,$BE,$64,$07,$89,$F3,$26,$8A,$05,$47,$88,
  325. $04,$38,$E0,$74,$0E,$08,$C0,$74,$0A,$46,$E8,$DE,$FF,$75,$EC,
  326. $89,$F3,$74,$E8,$C3,$B0,$66,$BA,$48,$05,$EB,$0C,$B0,$67,$BA,
  327. $55,$05,$EB,$05,$B0,$68,$BA,$5F,$05,$52,$8B,$1E,$62,$07,$C6,
  328. $07,$24,$BB,$64,$07,$EB,$28,$E8,$F5,$00,$B0,$69,$BA,$99,$05,
  329. $EB,$1A,$B0,$6A,$BA,$B2,$05,$EB,$13,$B0,$6B,$BA,$C4,$05,$EB,
  330. $0C,$B0,$6C,$BA,$D6,$05,$EB,$05,$B0,$69,$BA,$99,$05,$52,$BB,
  331. $3B,$05,$E8,$15,$00,$5B,$E8,$11,$00,$BB,$67,$04,$E8,$0B,$00,
  332. $B4,$4C,$CD,$21,$43,$50,$B4,$02,$CD,$21,$58,$8A,$17,$80,$FA,
  333. $24,$75,$F2,$C3,$0D,$0A,$24,$50,$51,$57,$31,$C0,$BF,$2A,$06,
  334. $B9,$19,$00,$F3,$AB,$5F,$59,$58,$C3,$B8,$00,$03,$BB,$21,$00,
  335. $31,$C9,$66,$BF,$2A,$06,$00,$00,$CD,$31,$C3,$00,$00,$30,$E4,
  336. $E8,$4E,$FF,$89,$DE,$8B,$3E,$8C,$04,$EB,$17,$B4,$3B,$E8,$41,
  337. $FF,$81,$FE,$64,$07,$74,$12,$8A,$44,$FF,$E8,$2A,$FF,$74,$04,
  338. $C6,$04,$5C,$46,$E8,$03,$00,$72,$E4,$C3,$E8,$34,$00,$BB,$44,
  339. $00,$8A,$07,$88,$04,$43,$46,$08,$C0,$75,$F6,$06,$57,$1E,$07,
  340. $E8,$9B,$FF,$BB,$2A,$06,$8C,$5F,$04,$89,$5F,$02,$BA,$64,$07,
  341. $B8,$00,$4B,$CD,$21,$5F,$07,$72,$09,$B4,$4D,$CD,$21,$2D,$00,
  342. $03,$F7,$D8,$EB,$28,$80,$3E,$69,$08,$05,$72,$20,$B8,$00,$58,
  343. $CD,$21,$A2,$67,$08,$B8,$02,$58,$CD,$21,$A2,$68,$08,$B8,$01,
  344. $58,$BB,$80,$00,$CD,$21,$B8,$03,$58,$BB,$01,$00,$CD,$21,$C3,
  345. $9C,$80,$3E,$69,$08,$05,$72,$1A,$50,$53,$B8,$03,$58,$8A,$1E,
  346. $68,$08,$30,$FF,$CD,$21,$B8,$01,$58,$8A,$1E,$67,$08,$30,$FF,
  347. $CD,$21,$5B,$58,$9D,$C3,$4C,$6F,$61,$64,$20,$65,$72,$72,$6F,
  348. $72,$3A,$20,$24,$3A,$20,$63,$61,$6E,$27,$74,$20,$6F,$70,$65,
  349. $6E,$24,$3A,$20,$6E,$6F,$74,$20,$45,$58,$45,$24,$3A,$20,$6E,
  350. $6F,$74,$20,$43,$4F,$46,$46,$20,$28,$43,$68,$65,$63,$6B,$20,
  351. $66,$6F,$72,$20,$76,$69,$72,$75,$73,$65,$73,$29,$24,$6E,$6F,
  352. $20,$44,$50,$4D,$49,$20,$2D,$20,$47,$65,$74,$20,$63,$73,$64,
  353. $70,$6D,$69,$2A,$62,$2E,$7A,$69,$70,$24,$6E,$6F,$20,$44,$4F,
  354. $53,$20,$6D,$65,$6D,$6F,$72,$79,$24,$6E,$65,$65,$64,$20,$44,
  355. $4F,$53,$20,$33,$24,$63,$61,$6E,$27,$74,$20,$73,$77,$69,$74,
  356. $63,$68,$20,$6D,$6F,$64,$65,$24,$6E,$6F,$20,$44,$50,$4D,$49,
  357. $20,$73,$65,$6C,$65,$63,$74,$6F,$72,$73,$24,$6E,$6F,$20,$44,
  358. $50,$4D,$49,$20,$6D,$65,$6D,$6F,$72,$79,$24,$90,$90,$90,$90,
  359. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  360. $90,$90,$90,$90,$90,$90,$90,$90);
  361. {****************************************************************************
  362. TCoffObjectSection
  363. ****************************************************************************}
  364. constructor tcoffobjectsection.create(const aname:string;atype:tasmsectiontype;aalign:longint;aoptions:TAsmSectionOptions);
  365. begin
  366. inherited create(aname,atype,aalign,aoptions);
  367. Flags:=0;
  368. end;
  369. procedure TCoffObjectSection.addsymsizereloc(ofs:longint;p:tasmsymbol;size:longint;relative:TAsmRelocationType);
  370. begin
  371. relocations.concat(tasmrelocation.createsymbolsize(ofs,p,size,relative));
  372. end;
  373. procedure TCoffObjectSection.fixuprelocs;
  374. var
  375. r : TAsmRelocation;
  376. address,
  377. relocval : longint;
  378. begin
  379. r:=TAsmRelocation(relocations.first);
  380. if assigned(r) and
  381. (not assigned(data)) then
  382. internalerror(200205183);
  383. while assigned(r) do
  384. begin
  385. if assigned(r.symbol) then
  386. relocval:=r.symbol.address
  387. else
  388. internalerror(200205183);
  389. data.Seek(r.address);
  390. data.Read(address,4);
  391. case r.typ of
  392. RELOC_RELATIVE :
  393. begin
  394. dec(address,mempos);
  395. inc(address,relocval);
  396. end;
  397. RELOC_RVA,
  398. RELOC_ABSOLUTE :
  399. begin
  400. if r.symbol.section.sectype=sec_common then
  401. dec(address,r.orgsize)
  402. else
  403. begin
  404. { fixup address when the symbol was known in defined object }
  405. if (r.symbol.section<>nil) and
  406. (r.symbol.owner=owner) then
  407. dec(address,TCoffObjectSection(r.symbol.section).orgmempos);
  408. end;
  409. inc(address,relocval);
  410. end;
  411. end;
  412. data.Seek(r.address);
  413. data.Write(address,4);
  414. { goto next reloc }
  415. r:=TAsmRelocation(r.next);
  416. end;
  417. end;
  418. {****************************************************************************
  419. TDjCoffObjectSection
  420. ****************************************************************************}
  421. constructor tdjcoffobjectsection.create(const aname:string;atype:tasmsectiontype;aalign:longint;aoptions:TAsmSectionOptions);
  422. begin
  423. inherited create(aname,atype,aalign,aoptions);
  424. case atype of
  425. sec_code :
  426. begin
  427. Flags:=$20;
  428. addralign:=16;
  429. end;
  430. sec_data :
  431. begin
  432. Flags:=$40;
  433. addralign:=16;
  434. end;
  435. sec_bss :
  436. begin
  437. Flags:=$80;
  438. addralign:=16;
  439. end;
  440. end;
  441. end;
  442. {****************************************************************************
  443. TPECoffObjectSection
  444. ****************************************************************************}
  445. constructor tpecoffobjectsection.create(const aname:string;atype:tasmsectiontype;aalign:longint;aoptions:TAsmSectionOptions);
  446. begin
  447. inherited create(aname,atype,aalign,aoptions);
  448. case atype of
  449. sec_code :
  450. begin
  451. Flags:=$60000020;
  452. addralign:=16;
  453. end;
  454. sec_data :
  455. begin
  456. Flags:=$c0300040;
  457. addralign:=16;
  458. end;
  459. sec_bss :
  460. begin
  461. Flags:=$c0300080;
  462. addralign:=16;
  463. end;
  464. sec_idata2,
  465. sec_idata4,
  466. sec_idata5,
  467. sec_idata6,
  468. sec_idata7 :
  469. begin
  470. Flags:=$40000000;
  471. end;
  472. sec_edata :
  473. begin
  474. Flags:=$c0300040;
  475. end;
  476. end;
  477. end;
  478. {****************************************************************************
  479. tcoffobjectdata
  480. ****************************************************************************}
  481. constructor tcoffobjectdata.createcoff(const n:string;awin32:boolean;acasmsection:TAsmSectionClass);
  482. begin
  483. inherited create(n);
  484. CAsmSection:=ACAsmSection;
  485. win32:=awin32;
  486. { we need at least the following 3 sections }
  487. createsection(sec_code,'',0,[]);
  488. createsection(sec_data,'',0,[]);
  489. createsection(sec_bss,'',0,[]);
  490. if (cs_use_lineinfo in aktglobalswitches) or
  491. (cs_debuginfo in aktmoduleswitches) then
  492. begin
  493. stabssec:=createsection(sec_stab,'',0,[]);
  494. stabstrsec:=createsection(sec_stabstr,'',0,[]);
  495. end;
  496. end;
  497. destructor tcoffobjectdata.destroy;
  498. begin
  499. inherited destroy;
  500. end;
  501. function TCoffObjectData.sectionname(atype:tasmsectiontype;const aname:string):string;
  502. const
  503. secnames : array[tasmsectiontype] of string[16] = ('',
  504. '.text','.data','.data','.bss','.tls',
  505. 'common',
  506. '.note',
  507. '.text',
  508. '.stab','.stabstr',
  509. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  510. '.eh_frame',
  511. '.debug_frame',
  512. '.fpc',
  513. ''
  514. );
  515. begin
  516. { No support for named sections, because section names are limited to 8 chars }
  517. result:=secnames[atype];
  518. end;
  519. procedure tcoffobjectdata.writesymbol(p:tasmsymbol);
  520. begin
  521. if currsec=nil then
  522. internalerror(200403071);
  523. { already written ? }
  524. if p.indexnr<>-1 then
  525. exit;
  526. { calculate symbol index }
  527. if (p.currbind<>AB_LOCAL) then
  528. begin
  529. { insert the symbol in the local index, the indexarray
  530. will take care of the numbering }
  531. symbols.insert(p);
  532. end
  533. else
  534. p.indexnr:=-2; { local }
  535. end;
  536. procedure tcoffobjectdata.writereloc(data,len:aint;p:tasmsymbol;relative:TAsmRelocationType);
  537. var
  538. curraddr,
  539. symaddr : longint;
  540. begin
  541. if currsec=nil then
  542. internalerror(200403072);
  543. if assigned(p) then
  544. begin
  545. { current address }
  546. curraddr:=currsec.mempos+currsec.datasize;
  547. { external/common symbols don't have a fixed memory position yet }
  548. if (p.currbind=AB_COMMON) then
  549. begin
  550. { For go32v2 we need to use the size as address }
  551. if not win32 then
  552. symaddr:=p.size
  553. else
  554. symaddr:=0;
  555. end
  556. else
  557. begin
  558. symaddr:=p.address;
  559. if assigned(p.section) then
  560. inc(symaddr,p.section.mempos);
  561. end;
  562. { no symbol relocation need inside a section }
  563. if (p.section=currsec) and
  564. (p.currbind<>AB_COMMON) then
  565. begin
  566. case relative of
  567. RELOC_ABSOLUTE :
  568. begin
  569. currsec.addsectionreloc(curraddr,currsec,RELOC_ABSOLUTE);
  570. inc(data,symaddr);
  571. end;
  572. RELOC_RELATIVE :
  573. begin
  574. inc(data,symaddr-len-currsec.datasize);
  575. end;
  576. RELOC_RVA :
  577. begin
  578. currsec.addsectionreloc(curraddr,currsec,RELOC_RVA);
  579. inc(data,symaddr);
  580. end;
  581. end;
  582. end
  583. else
  584. begin
  585. writesymbol(p);
  586. if (p.section<>nil) and
  587. (p.currbind<>AB_COMMON) and
  588. (relative<>RELOC_RELATIVE) then
  589. currsec.addsectionreloc(curraddr,p.section,relative)
  590. else
  591. currsec.addsymreloc(curraddr,p,relative);
  592. if (not win32) or
  593. ((relative<>RELOC_RELATIVE) and (p.section<>nil)) then
  594. inc(data,symaddr);
  595. if relative=RELOC_RELATIVE then
  596. begin
  597. if win32 then
  598. dec(data,len-4)
  599. else
  600. dec(data,len+currsec.datasize);
  601. end;
  602. end;
  603. end;
  604. currsec.write(data,len);
  605. end;
  606. procedure tcoffobjectdata.writestab(offset:aint;ps:tasmsymbol;nidx,nother,line:longint;p:pchar);
  607. var
  608. stab : coffstab;
  609. curraddr : longint;
  610. begin
  611. { Win32 does not need an offset if a symbol relocation is used }
  612. if win32 and
  613. assigned(ps) and
  614. (ps.currbind<>AB_LOCAL) then
  615. offset:=0;
  616. if assigned(p) and (p[0]<>#0) then
  617. begin
  618. stab.strpos:=StabStrSec.datasize;
  619. StabStrSec.write(p^,strlen(p)+1);
  620. end
  621. else
  622. stab.strpos:=0;
  623. stab.ntype:=nidx;
  624. stab.ndesc:=line;
  625. stab.nother:=nother;
  626. stab.nvalue:=offset;
  627. StabsSec.write(stab,sizeof(stab));
  628. if assigned(ps) then
  629. begin
  630. writesymbol(ps);
  631. { current address }
  632. curraddr:=StabsSec.mempos+StabsSec.datasize;
  633. if DLLSource and RelocSection then
  634. { avoid relocation in the .stab section
  635. because it ends up in the .reloc section instead }
  636. StabsSec.addsymreloc(curraddr-4,ps,RELOC_RVA)
  637. else
  638. StabsSec.addsymreloc(curraddr-4,ps,RELOC_ABSOLUTE);
  639. end;
  640. end;
  641. procedure tcoffobjectdata.section_mempos(p:tnamedindexitem;arg:pointer);
  642. begin
  643. tcoffobjectsection(p).memsize:=tcoffobjectsection(p).datasize;
  644. { memory position is in arg }
  645. if not win32 then
  646. begin
  647. tcoffobjectsection(p).mempos:=plongint(arg)^;
  648. inc(plongint(arg)^,align(tcoffobjectsection(p).memsize,tcoffobjectsection(p).addralign));
  649. end;
  650. end;
  651. procedure tcoffobjectdata.beforealloc;
  652. begin
  653. { create stabs sections if debugging }
  654. if (cs_debuginfo in aktmoduleswitches) then
  655. begin
  656. StabsSec.Alloc(sizeof(coffstab));
  657. StabStrSec.Alloc(length(SplitFileName(current_module.mainsource^))+2);
  658. end;
  659. end;
  660. procedure tcoffobjectdata.beforewrite;
  661. var
  662. s : string;
  663. begin
  664. { create stabs sections if debugging }
  665. if (cs_debuginfo in aktmoduleswitches) then
  666. begin
  667. writestab(0,nil,0,0,0,nil);
  668. { write zero pchar and name together (PM) }
  669. s:=#0+SplitFileName(current_module.mainsource^)+#0;
  670. stabstrsec.write(s[1],length(s));
  671. end;
  672. end;
  673. procedure tcoffobjectdata.afteralloc;
  674. var
  675. mempos : longint;
  676. begin
  677. { if debug then also count header stab }
  678. if (cs_debuginfo in aktmoduleswitches) then
  679. begin
  680. StabsSec.Alloc(sizeof(coffstab));
  681. StabStrSec.Alloc(length(SplitFileName(current_module.mainsource^))+2);
  682. end;
  683. { calc mempos }
  684. mempos:=0;
  685. sects.foreach(@section_mempos,@mempos);
  686. end;
  687. {****************************************************************************
  688. tdjcoffobjectdata
  689. ****************************************************************************}
  690. constructor tdjcoffobjectdata.create(const n:string);
  691. begin
  692. inherited createcoff(n,false,tdjcoffobjectsection);
  693. end;
  694. {****************************************************************************
  695. tpecoffobjectdata
  696. ****************************************************************************}
  697. constructor tpecoffobjectdata.create(const n:string);
  698. begin
  699. inherited createcoff(n,true,tpecoffobjectsection);
  700. end;
  701. {****************************************************************************
  702. tcoffobjectoutput
  703. ****************************************************************************}
  704. constructor tcoffobjectoutput.createdjgpp(smart:boolean);
  705. begin
  706. inherited create(smart);
  707. win32:=false;
  708. end;
  709. constructor tcoffobjectoutput.createwin32(smart:boolean);
  710. begin
  711. inherited create(smart);
  712. win32:=true;
  713. end;
  714. function tcoffobjectoutput.newobjectdata(const n:string):TAsmObjectData;
  715. begin
  716. if win32 then
  717. result:=tpecoffobjectdata.create(n)
  718. else
  719. result:=tdjcoffobjectdata.create(n);
  720. end;
  721. procedure tcoffobjectoutput.write_symbol(const name:string;value,section,typ,aux:longint);
  722. var
  723. sym : coffsymbol;
  724. begin
  725. FillChar(sym,sizeof(sym),0);
  726. { symbolname }
  727. if length(name)>8 then
  728. begin
  729. sym.strpos:=FCoffStrs.size+4;
  730. FCoffStrs.writestr(name);
  731. FCoffStrs.writestr(#0);
  732. end
  733. else
  734. move(name[1],sym.name,length(name));
  735. sym.value:=value;
  736. sym.section:=section;
  737. sym.typ:=typ;
  738. sym.aux:=aux;
  739. FWriter.write(sym,sizeof(sym));
  740. end;
  741. procedure tcoffobjectoutput.section_write_symbol(p:tnamedindexitem;arg:pointer);
  742. var
  743. secrec : coffsectionrec;
  744. begin
  745. write_symbol(tasmsection(p).name,tasmsection(p).mempos,tasmsection(p).secsymidx,3,1);
  746. fillchar(secrec,sizeof(secrec),0);
  747. secrec.len:=tasmsection(p).aligneddatasize;
  748. secrec.nrelocs:=tasmsection(p).relocations.count;
  749. FWriter.write(secrec,sizeof(secrec));
  750. end;
  751. procedure tcoffobjectoutput.section_write_relocs(p:tnamedindexitem;arg:pointer);
  752. var
  753. rel : coffreloc;
  754. r : TAsmRelocation;
  755. begin
  756. r:=TasmRelocation(tasmsection(p).relocations.first);
  757. while assigned(r) do
  758. begin
  759. rel.address:=r.address;
  760. if assigned(r.symbol) then
  761. begin
  762. if (r.symbol.currbind=AB_LOCAL) then
  763. rel.sym:=2*r.symbol.section.secsymidx
  764. else
  765. begin
  766. if r.symbol.indexnr=-1 then
  767. internalerror(4321);
  768. { indexnr starts with 1, coff starts with 0 }
  769. rel.sym:=r.symbol.indexnr+initsym-1;
  770. end;
  771. end
  772. else
  773. begin
  774. if r.section<>nil then
  775. rel.sym:=2*r.section.secsymidx
  776. else
  777. rel.sym:=0;
  778. end;
  779. case r.typ of
  780. RELOC_RELATIVE :
  781. rel.relative:=$14;
  782. RELOC_ABSOLUTE :
  783. rel.relative:=$6;
  784. RELOC_RVA :
  785. rel.relative:=$7;
  786. end;
  787. FWriter.write(rel,sizeof(rel));
  788. r:=TAsmRelocation(r.next);
  789. end;
  790. end;
  791. procedure tcoffobjectoutput.write_symbols(data:TAsmObjectData);
  792. var
  793. filename : string[18];
  794. value : longint;
  795. sectionval,
  796. globalval : byte;
  797. p : tasmsymbol;
  798. begin
  799. with tcoffobjectdata(data) do
  800. begin
  801. { The `.file' record, and the file name auxiliary record }
  802. write_symbol('.file', 0, -2, $67, 1);
  803. fillchar(filename,sizeof(filename),0);
  804. filename:=SplitFileName(current_module.mainsource^);
  805. FWriter.write(filename[1],sizeof(filename)-1);
  806. { The section records, with their auxiliaries, also store the
  807. symbol index }
  808. Sects.foreach(@section_write_symbol,nil);
  809. { The symbols used }
  810. p:=Tasmsymbol(symbols.First);
  811. while assigned(p) do
  812. begin
  813. if assigned(p.section) and
  814. (p.currbind<>AB_COMMON) then
  815. sectionval:=p.section.secsymidx
  816. else
  817. sectionval:=0;
  818. if p.currbind=AB_LOCAL then
  819. globalval:=3
  820. else
  821. globalval:=2;
  822. { if local of global then set the section value to the address
  823. of the symbol }
  824. if p.currbind in [AB_LOCAL,AB_GLOBAL] then
  825. value:=p.address+p.section.mempos
  826. else
  827. value:=p.size;
  828. { symbolname }
  829. write_symbol(p.name,value,sectionval,globalval,0);
  830. p:=tasmsymbol(p.indexnext);
  831. end;
  832. end;
  833. end;
  834. procedure tcoffobjectoutput.section_set_secsymidx(p:tnamedindexitem;arg:pointer);
  835. begin
  836. inc(plongint(arg)^);
  837. tasmsection(p).secsymidx:=plongint(arg)^;
  838. end;
  839. procedure tcoffobjectoutput.section_set_datapos(p:tnamedindexitem;arg:pointer);
  840. begin
  841. tasmsection(p).datapos:=plongint(arg)^;
  842. if not(aso_alloconly in tasmsection(p).secoptions) then
  843. inc(plongint(arg)^,tasmsection(p).aligneddatasize);
  844. end;
  845. procedure tcoffobjectoutput.section_set_reloc_datapos(p:tnamedindexitem;arg:pointer);
  846. begin
  847. TCoffObjectSection(p).coffrelocpos:=plongint(arg)^;
  848. inc(plongint(arg)^,sizeof(coffreloc)*tasmsection(p).relocations.count);
  849. end;
  850. procedure tcoffobjectoutput.section_write_header(p:tnamedindexitem;arg:pointer);
  851. var
  852. sechdr : coffsechdr;
  853. s : string;
  854. begin
  855. fillchar(sechdr,sizeof(sechdr),0);
  856. s:=tasmsection(p).name;
  857. { section names are limited to 8 chars }
  858. if length(s)>8 then
  859. internalerror(200403312);
  860. move(s[1],sechdr.name,length(s));
  861. if not win32 then
  862. begin
  863. sechdr.rvaofs:=tasmsection(p).mempos;
  864. sechdr.vsize:=tasmsection(p).mempos;
  865. end
  866. else
  867. begin
  868. if tasmsection(p).sectype=sec_bss then
  869. sechdr.vsize:=tasmsection(p).aligneddatasize;
  870. end;
  871. sechdr.datasize:=tasmsection(p).aligneddatasize;
  872. if (tasmsection(p).datasize>0) and
  873. not(aso_alloconly in tasmsection(p).secoptions) then
  874. sechdr.datapos:=tasmsection(p).datapos;
  875. sechdr.nrelocs:=tasmsection(p).relocations.count;
  876. sechdr.relocpos:=TCoffObjectSection(p).coffrelocpos;
  877. sechdr.flags:=TCoffObjectSection(p).flags;
  878. FWriter.write(sechdr,sizeof(sechdr));
  879. end;
  880. procedure tcoffobjectoutput.section_write_data(p:tnamedindexitem;arg:pointer);
  881. var
  882. hp : pdynamicblock;
  883. begin
  884. if (aso_alloconly in tasmsection(p).secoptions) then
  885. exit;
  886. if tasmsection(p).data=nil then
  887. internalerror(200403073);
  888. tasmsection(p).alignsection;
  889. hp:=tasmsection(p).data.firstblock;
  890. while assigned(hp) do
  891. begin
  892. FWriter.write(hp^.data,hp^.used);
  893. hp:=hp^.next;
  894. end;
  895. end;
  896. function tcoffobjectoutput.writedata(data:TAsmObjectData):boolean;
  897. var
  898. orgdatapos,
  899. datapos,
  900. nsects,
  901. sympos,i : longint;
  902. hstab : coffstab;
  903. gotreloc : boolean;
  904. header : coffheader;
  905. empty : array[0..15] of byte;
  906. hp : pdynamicblock;
  907. s : string;
  908. begin
  909. result:=false;
  910. FCoffStrs:=TDynamicArray.Create(strsresize);
  911. with tcoffobjectdata(data) do
  912. begin
  913. { calc amount of sections we have }
  914. fillchar(empty,sizeof(empty),0);
  915. nsects:=0;
  916. Sects.foreach(@section_set_secsymidx,@nsects);
  917. initsym:=2+nsects*2; { 2 for the file }
  918. { For the stab section we need an HdrSym which can now be
  919. calculated more easily }
  920. if StabsSec<>nil then
  921. begin
  922. { header stab }
  923. s:=#0+SplitFileName(current_module.mainsource^)+#0;
  924. stabstrsec.write(s[1],length(s));
  925. hstab.strpos:=1;
  926. hstab.ntype:=0;
  927. hstab.nother:=0;
  928. hstab.ndesc:=(StabsSec.datasize div sizeof(coffstab))-1{+1 according to gas output PM};
  929. hstab.nvalue:=StabStrSec.datasize;
  930. StabsSec.data.seek(0);
  931. StabsSec.data.write(hstab,sizeof(hstab));
  932. end;
  933. { Calculate the filepositions }
  934. datapos:=sizeof(coffheader)+sizeof(coffsechdr)*nsects;
  935. { sections first }
  936. Sects.foreach(@section_set_datapos,@datapos);
  937. { relocs }
  938. orgdatapos:=datapos;
  939. Sects.foreach(@section_set_reloc_datapos,@datapos);
  940. gotreloc:=(orgdatapos<>datapos);
  941. { symbols }
  942. sympos:=datapos;
  943. { COFF header }
  944. fillchar(header,sizeof(coffheader),0);
  945. {$ifdef i386}
  946. header.mach:=$14c;
  947. {$endif i386}
  948. {$ifdef arm}
  949. header.mach:=$1c0;
  950. {$endif arm}
  951. header.nsects:=nsects;
  952. header.sympos:=sympos;
  953. header.syms:=symbols.count+initsym;
  954. header.flag:=COFF_FLAG_AR32WR or COFF_FLAG_NOLINES;
  955. if not gotreloc then
  956. header.flag:=header.flag or COFF_FLAG_NORELOCS;
  957. FWriter.write(header,sizeof(header));
  958. { Section headers }
  959. Sects.foreach(@section_write_header,nil);
  960. { Sections }
  961. Sects.foreach(@section_write_data,nil);
  962. { Relocs }
  963. Sects.foreach(@section_write_relocs,nil);
  964. { Symbols }
  965. write_symbols(data);
  966. { Strings }
  967. i:=FCoffStrs.size+4;
  968. FWriter.write(i,4);
  969. hp:=FCoffStrs.firstblock;
  970. while assigned(hp) do
  971. begin
  972. FWriter.write(hp^.data,hp^.used);
  973. hp:=hp^.next;
  974. end;
  975. end;
  976. FCoffStrs.Free;
  977. end;
  978. {****************************************************************************
  979. tcoffexeoutput
  980. ****************************************************************************}
  981. constructor tcoffexeoutput.createdjgpp;
  982. begin
  983. inherited create;
  984. win32:=false;
  985. end;
  986. constructor tcoffexeoutput.createwin32;
  987. begin
  988. inherited create;
  989. win32:=true;
  990. end;
  991. function tcoffexeoutput.newobjectinput:tobjectinput;
  992. begin
  993. if win32 then
  994. result:=tcoffobjectinput.createwin32
  995. else
  996. result:=tcoffobjectinput.createdjgpp;
  997. end;
  998. procedure tcoffexeoutput.write_symbol(const name:string;value,section,typ,aux:longint);
  999. var
  1000. sym : coffsymbol;
  1001. begin
  1002. FillChar(sym,sizeof(sym),0);
  1003. if length(name)>8 then
  1004. begin
  1005. sym.strpos:=FCoffStrs.size+4;
  1006. FCoffStrs.writestr(name);
  1007. FCoffStrs.writestr(#0);
  1008. end
  1009. else
  1010. move(name[1],sym.name,length(name));
  1011. sym.value:=value;
  1012. sym.section:=section;
  1013. sym.typ:=typ;
  1014. sym.aux:=aux;
  1015. FWriter.write(sym,sizeof(sym));
  1016. end;
  1017. procedure tcoffexeoutput.write_symbols;
  1018. var
  1019. value,
  1020. sectionval,
  1021. globalval : byte;
  1022. objdata : TAsmObjectData;
  1023. p : tasmsymbol;
  1024. begin
  1025. {$ifdef internallinker}
  1026. objdata:=TAsmObjectData(objdatalist.first);
  1027. while assigned(objdata) do
  1028. begin
  1029. with tcoffobjectdata(objdata) do
  1030. begin
  1031. { The symbols used }
  1032. p:=Tasmsymbol(symbols.First);
  1033. while assigned(p) do
  1034. begin
  1035. if p.section=sec_common then
  1036. sectionval:=sections[sec_bss].secsymidx
  1037. else
  1038. sectionval:=sections[p.section.name].secsymidx;
  1039. if p.currbind=AB_LOCAL then
  1040. globalval:=3
  1041. else
  1042. globalval:=2;
  1043. { if local of global then set the section value to the address
  1044. of the symbol }
  1045. if p.currbind in [AB_LOCAL,AB_GLOBAL] then
  1046. value:=p.address
  1047. else
  1048. value:=p.size;
  1049. { symbolname }
  1050. s:=p.name;
  1051. if length(s)>8 then
  1052. begin
  1053. nameidx:=FCoffStrs.size+4;
  1054. FCoffStrs.writestr(s);
  1055. FCoffStrs.writestr(#0);
  1056. end
  1057. else
  1058. begin
  1059. nameidx:=-1;
  1060. namestr:=s;
  1061. end;
  1062. write_symbol(namestr,nameidx,value,sectionval,globalval,0);
  1063. p:=tasmsymbol(p.indexnext);
  1064. end;
  1065. end;
  1066. objdata:=TAsmObjectData(objdata.next);
  1067. end;
  1068. {$endif internallinker}
  1069. end;
  1070. procedure tcoffexeoutput.CalculateMemoryMap;
  1071. var
  1072. objdata : TAsmObjectData;
  1073. secsymidx,
  1074. mempos,
  1075. datapos : longint;
  1076. begin
  1077. {$ifdef internallinker}
  1078. { retrieve amount of sections }
  1079. nsects:=0;
  1080. secsymidx:=0;
  1081. for sec:=low(TSection) to high(TSection) do
  1082. begin
  1083. if sections[sec].available then
  1084. begin
  1085. inc(nsects);
  1086. inc(secsymidx);
  1087. sections[sec].secsymidx:=secsymidx;
  1088. end;
  1089. end;
  1090. { calculate start positions after the headers }
  1091. datapos:=sizeof(coffheader)+sizeof(coffoptheader)+sizeof(coffsechdr)*nsects;
  1092. mempos:=sizeof(coffheader)+sizeof(coffoptheader)+sizeof(coffsechdr)*nsects;
  1093. if not win32 then
  1094. inc(mempos,sizeof(go32v2stub)+$1000);
  1095. { add sections }
  1096. MapObjectdata(datapos,mempos);
  1097. { end symbol }
  1098. AddGlobalSym('_etext',sections[sec_code].mempos+sections[sec_code].memsize);
  1099. AddGlobalSym('_edata',sections[sec_data].mempos+sections[sec_data].memsize);
  1100. AddGlobalSym('end',mempos);
  1101. { symbols }
  1102. nsyms:=0;
  1103. sympos:=0;
  1104. if not(cs_link_strip in aktglobalswitches) then
  1105. begin
  1106. sympos:=datapos;
  1107. objdata:=TAsmObjectData(objdatalist.first);
  1108. while assigned(objdata) do
  1109. begin
  1110. inc(nsyms,objdata.symbols.count);
  1111. objdata:=TAsmObjectData(objdata.next);
  1112. end;
  1113. end;
  1114. {$endif internallinker}
  1115. end;
  1116. function tcoffexeoutput.writedata:boolean;
  1117. var
  1118. i : longint;
  1119. header : coffheader;
  1120. optheader : coffoptheader;
  1121. sechdr : coffsechdr;
  1122. hp : pdynamicblock;
  1123. objdata : TAsmObjectData;
  1124. hsym : tasmsymbol;
  1125. begin
  1126. result:=false;
  1127. {$ifdef internallinker}
  1128. FCoffSyms:=TDynamicArray.Create(symbolresize);
  1129. FCoffStrs:=TDynamicArray.Create(strsresize);
  1130. { Stub }
  1131. if not win32 then
  1132. FWriter.write(go32v2stub,sizeof(go32v2stub));
  1133. { COFF header }
  1134. fillchar(header,sizeof(header),0);
  1135. header.mach:=$14c;
  1136. header.nsects:=nsects;
  1137. header.sympos:=sympos;
  1138. header.syms:=nsyms;
  1139. header.opthdr:=sizeof(coffoptheader);
  1140. header.flag:=COFF_FLAG_AR32WR or COFF_FLAG_EXE or COFF_FLAG_NORELOCS or COFF_FLAG_NOLINES;
  1141. FWriter.write(header,sizeof(header));
  1142. { Optional COFF Header }
  1143. fillchar(optheader,sizeof(optheader),0);
  1144. optheader.magic:=$10b;
  1145. optheader.tsize:=sections[sec_code].memsize;
  1146. optheader.dsize:=sections[sec_data].memsize;
  1147. optheader.bsize:=sections[sec_bss].memsize;
  1148. hsym:=tasmsymbol(globalsyms.search('start'));
  1149. if not assigned(hsym) then
  1150. begin
  1151. Comment(V_Error,'Entrypoint "start" not defined');
  1152. exit;
  1153. end;
  1154. optheader.entry:=hsym.address;
  1155. optheader.text_start:=sections[sec_code].mempos;
  1156. optheader.data_start:=sections[sec_data].mempos;
  1157. FWriter.write(optheader,sizeof(optheader));
  1158. { Section headers }
  1159. for sec:=low(TSection) to high(TSection) do
  1160. if sections[sec].available then
  1161. begin
  1162. fillchar(sechdr,sizeof(sechdr),0);
  1163. move(target_asm.secnames[sec][1],sechdr.name,length(target_asm.secnames[sec]));
  1164. if not win32 then
  1165. begin
  1166. sechdr.rvaofs:=sections[sec].mempos;
  1167. sechdr.vsize:=sections[sec].mempos;
  1168. end
  1169. else
  1170. begin
  1171. if sec=sec_bss then
  1172. sechdr.vsize:=sections[sec].memsize;
  1173. end;
  1174. if sec=sec_bss then
  1175. sechdr.datasize:=sections[sec].memsize
  1176. else
  1177. begin
  1178. sechdr.datasize:=sections[sec].datasize;
  1179. sechdr.datapos:=sections[sec].datapos;
  1180. end;
  1181. sechdr.nrelocs:=0;
  1182. sechdr.relocpos:=0;
  1183. sechdr.flags:=sections[sec].flags;
  1184. FWriter.write(sechdr,sizeof(sechdr));
  1185. end;
  1186. { Sections }
  1187. for sec:=low(TSection) to high(TSection) do
  1188. if sections[sec].available then
  1189. begin
  1190. { update objectfiles }
  1191. objdata:=TAsmObjectData(objdatalist.first);
  1192. while assigned(objdata) do
  1193. begin
  1194. if assigned(objdata.sects[sec]) and
  1195. assigned(objdata.sects[sec].data) then
  1196. begin
  1197. FWriter.WriteZeros(objdata.sects[sec].dataalignbytes);
  1198. hp:=objdata.sects[sec].data.firstblock;
  1199. while assigned(hp) do
  1200. begin
  1201. FWriter.write(hp^.data,hp^.used);
  1202. hp:=hp^.next;
  1203. end;
  1204. end;
  1205. objdata:=TAsmObjectData(objdata.next);
  1206. end;
  1207. end;
  1208. { Optional symbols }
  1209. if not(cs_link_strip in aktglobalswitches) then
  1210. begin
  1211. { Symbols }
  1212. write_symbols;
  1213. { Strings }
  1214. i:=FCoffStrs.size+4;
  1215. FWriter.write(i,4);
  1216. hp:=FCoffStrs.firstblock;
  1217. while assigned(hp) do
  1218. begin
  1219. FWriter.write(hp^.data,hp^.used);
  1220. hp:=hp^.next;
  1221. end;
  1222. end;
  1223. { Release }
  1224. FCoffStrs.Free;
  1225. FCoffSyms.Free;
  1226. result:=true;
  1227. {$endif internallinker}
  1228. end;
  1229. procedure tcoffexeoutput.GenerateExecutable(const fn:string);
  1230. begin
  1231. AddGlobalSym('_etext',0);
  1232. AddGlobalSym('_edata',0);
  1233. AddGlobalSym('end',0);
  1234. if not CalculateSymbols then
  1235. exit;
  1236. CalculateMemoryMap;
  1237. FixupSymbols;
  1238. FixupRelocations;
  1239. writeexefile(fn);
  1240. end;
  1241. {****************************************************************************
  1242. tcoffobjectinput
  1243. ****************************************************************************}
  1244. constructor tcoffobjectinput.createdjgpp;
  1245. begin
  1246. inherited create;
  1247. win32:=false;
  1248. end;
  1249. constructor tcoffobjectinput.createwin32;
  1250. begin
  1251. inherited create;
  1252. win32:=true;
  1253. end;
  1254. function tcoffobjectinput.newobjectdata(const n:string):TAsmObjectData;
  1255. begin
  1256. if win32 then
  1257. result:=tpecoffobjectdata.create(n)
  1258. else
  1259. result:=tdjcoffobjectdata.create(n);
  1260. end;
  1261. procedure tcoffobjectinput.read_relocs(s:TCoffObjectSection);
  1262. var
  1263. rel : coffreloc;
  1264. rel_type : TAsmRelocationType;
  1265. i : longint;
  1266. p : tasmsymbol;
  1267. begin
  1268. for i:=1 to s.coffrelocs do
  1269. begin
  1270. FReader.read(rel,sizeof(rel));
  1271. case rel.relative of
  1272. $14 : rel_type:=RELOC_RELATIVE;
  1273. $06 : rel_type:=RELOC_ABSOLUTE;
  1274. $07 : rel_type:=RELOC_RVA;
  1275. else
  1276. begin
  1277. Comment(V_Error,'Error reading coff file');
  1278. exit;
  1279. end;
  1280. end;
  1281. p:=FSymTbl^[rel.sym].sym;
  1282. if assigned(p) then
  1283. begin
  1284. s.addsymsizereloc(rel.address-s.mempos,p,FSymTbl^[rel.sym].orgsize,rel_type);
  1285. end
  1286. else
  1287. begin
  1288. Comment(V_Error,'Error reading coff file');
  1289. exit;
  1290. end;
  1291. end;
  1292. end;
  1293. procedure tcoffobjectinput.handle_symbols(data:TAsmObjectData);
  1294. var
  1295. size,
  1296. address,
  1297. i,nsyms,
  1298. symidx : longint;
  1299. sym : coffsymbol;
  1300. strname : string;
  1301. p : tasmsymbol;
  1302. bind : Tasmsymbind;
  1303. auxrec : array[0..17] of byte;
  1304. begin
  1305. {$ifdef internallinker}
  1306. with tcoffobjectdata(data) do
  1307. begin
  1308. nsyms:=FCoffSyms.Size div sizeof(CoffSymbol);
  1309. { Allocate memory for symidx -> tasmsymbol table }
  1310. GetMem(FSymTbl,nsyms*sizeof(ttasmsymbolrec));
  1311. FillChar(FSymTbl^,nsyms*sizeof(ttasmsymbolrec),0);
  1312. { Loop all symbols }
  1313. FCoffSyms.Seek(0);
  1314. symidx:=0;
  1315. while (symidx<nsyms) do
  1316. begin
  1317. FCoffSyms.Read(sym,sizeof(sym));
  1318. if plongint(@sym.name)^<>0 then
  1319. begin
  1320. move(sym.name,strname[1],8);
  1321. strname[9]:=#0;
  1322. end
  1323. else
  1324. begin
  1325. FCoffStrs.Seek(sym.strpos-4);
  1326. FCoffStrs.Read(strname[1],255);
  1327. strname[255]:=#0;
  1328. end;
  1329. strname[0]:=chr(strlen(@strname[1]));
  1330. if strname='' then
  1331. Internalerror(200205172);
  1332. bind:=AB_EXTERNAL;
  1333. sec:=sec_none;
  1334. size:=0;
  1335. address:=0;
  1336. case sym.typ of
  1337. COFF_SYM_GLOBAL :
  1338. begin
  1339. if sym.section=0 then
  1340. begin
  1341. if sym.value=0 then
  1342. bind:=AB_EXTERNAL
  1343. else
  1344. begin
  1345. bind:=AB_COMMON;
  1346. size:=sym.value;
  1347. end;
  1348. end
  1349. else
  1350. begin
  1351. bind:=AB_GLOBAL;
  1352. sec:=Fidx2sec[sym.section];
  1353. if assigned(sects[sec]) then
  1354. begin
  1355. if sym.value>=sects[sec].mempos then
  1356. address:=sym.value-sects[sec].mempos
  1357. else
  1358. internalerror(432432432);
  1359. end
  1360. else
  1361. internalerror(34243214);
  1362. end;
  1363. p:=TAsmSymbol.Create(strname,bind,AT_FUNCTION);
  1364. p.SetAddress(0,sec,address,size);
  1365. p.objectdata:=data;
  1366. symbols.insert(p);
  1367. end;
  1368. COFF_SYM_LABEL,
  1369. COFF_SYM_LOCAL :
  1370. begin
  1371. { do not add constants (section=-1) }
  1372. if sym.section<>-1 then
  1373. begin
  1374. bind:=AB_LOCAL;
  1375. sec:=Fidx2sec[sym.section];
  1376. if assigned(sects[sec]) then
  1377. begin
  1378. if sym.value>=sects[sec].mempos then
  1379. address:=sym.value-sects[sec].mempos
  1380. else
  1381. internalerror(432432432);
  1382. end
  1383. else
  1384. internalerror(34243214);
  1385. p:=TAsmSymbol.Create(strname,bind,AT_FUNCTION);
  1386. p.SetAddress(0,sec,address,size);
  1387. p.objectdata:=data;
  1388. symbols.insert(p);
  1389. end;
  1390. end;
  1391. COFF_SYM_SECTION,
  1392. COFF_SYM_FUNCTION,
  1393. COFF_SYM_FILE :
  1394. ;
  1395. else
  1396. internalerror(4342343);
  1397. end;
  1398. FSymTbl^[symidx].sym:=p;
  1399. FSymTbl^[symidx].orgsize:=size;
  1400. { read aux records }
  1401. for i:=1 to sym.aux do
  1402. begin
  1403. FCoffSyms.Read(auxrec,sizeof(auxrec));
  1404. inc(symidx);
  1405. end;
  1406. inc(symidx);
  1407. end;
  1408. end;
  1409. {$endif internallinker}
  1410. end;
  1411. function tcoffobjectinput.readobjectdata(data:TAsmObjectData):boolean;
  1412. var
  1413. strsize,
  1414. i : longint;
  1415. header : coffheader;
  1416. sechdr : coffsechdr;
  1417. secname : array[0..15] of char;
  1418. begin
  1419. result:=false;
  1420. {$ifdef internallinker}
  1421. FCoffSyms:=TDynamicArray.Create(symbolresize);
  1422. FCoffStrs:=TDynamicArray.Create(strsresize);
  1423. with tcoffobjectdata(data) do
  1424. begin
  1425. FillChar(Fidx2sec,sizeof(Fidx2sec),0);
  1426. { Read COFF header }
  1427. if not reader.read(header,sizeof(coffheader)) then
  1428. begin
  1429. Comment(V_Error,'Error reading coff file');
  1430. exit;
  1431. end;
  1432. {$ifdef i386}
  1433. if header.mach<>$14c then
  1434. {$endif i386}
  1435. {$ifdef arm}
  1436. if header.mach<>$1c0 then
  1437. {$endif arm}
  1438. begin
  1439. Comment(V_Error,'Not a coff file');
  1440. exit;
  1441. end;
  1442. if header.nsects>255 then
  1443. begin
  1444. Comment(V_Error,'To many sections');
  1445. exit;
  1446. end;
  1447. { Section headers }
  1448. for i:=1 to header.nsects do
  1449. begin
  1450. if not reader.read(sechdr,sizeof(sechdr)) then
  1451. begin
  1452. Comment(V_Error,'Error reading coff file');
  1453. exit;
  1454. end;
  1455. move(sechdr.name,secname,8);
  1456. secname[8]:=#0;
  1457. sec:=str2sec(strpas(secname));
  1458. if sec<>sec_none then
  1459. begin
  1460. Fidx2sec[i]:=sec;
  1461. createsection(sec);
  1462. if not win32 then
  1463. sects[sec].mempos:=sechdr.rvaofs;
  1464. TCoffObjectSection(sects[sec]).coffrelocs:=sechdr.nrelocs;
  1465. TCoffObjectSection(sects[sec]).coffrelocpos:=sechdr.relocpos;
  1466. sects[sec].datapos:=sechdr.datapos;
  1467. sects[sec].datasize:=sechdr.datasize;
  1468. sects[sec].memsize:=sechdr.datasize;
  1469. TCoffObjectSection(sects[sec]).orgmempos:=sects[sec].mempos;
  1470. sects[sec].flags:=sechdr.flags;
  1471. end
  1472. else
  1473. Comment(V_Warning,'skipping unsupported section '+strpas(sechdr.name));
  1474. end;
  1475. { Symbols }
  1476. Reader.Seek(header.sympos);
  1477. if not Reader.ReadArray(FCoffSyms,header.syms*sizeof(CoffSymbol)) then
  1478. begin
  1479. Comment(V_Error,'Error reading coff file');
  1480. exit;
  1481. end;
  1482. { Strings }
  1483. if not Reader.Read(strsize,4) then
  1484. begin
  1485. Comment(V_Error,'Error reading coff file');
  1486. exit;
  1487. end;
  1488. if strsize<4 then
  1489. begin
  1490. Comment(V_Error,'Error reading coff file');
  1491. exit;
  1492. end;
  1493. if not Reader.ReadArray(FCoffStrs,Strsize-4) then
  1494. begin
  1495. Comment(V_Error,'Error reading coff file');
  1496. exit;
  1497. end;
  1498. { Insert all symbols }
  1499. handle_symbols(data);
  1500. { Sections }
  1501. for sec:=low(TSection) to high(TSection) do
  1502. if assigned(sects[sec]) and
  1503. (sec<>sec_bss) then
  1504. begin
  1505. Reader.Seek(sects[sec].datapos);
  1506. if not Reader.ReadArray(sects[sec].data,sects[sec].datasize) then
  1507. begin
  1508. Comment(V_Error,'Error reading coff file');
  1509. exit;
  1510. end;
  1511. end;
  1512. { Relocs }
  1513. for sec:=low(TSection) to high(TSection) do
  1514. if assigned(sects[sec]) and
  1515. (TCoffObjectSection(sects[sec]).coffrelocs>0) then
  1516. begin
  1517. Reader.Seek(TCoffObjectSection(sects[sec]).coffrelocpos);
  1518. read_relocs(TCoffObjectSection(sects[sec]));
  1519. end;
  1520. end;
  1521. FCoffStrs.Free;
  1522. FCoffSyms.Free;
  1523. result:=true;
  1524. {$endif internallinker}
  1525. end;
  1526. {****************************************************************************
  1527. TCoffAssembler
  1528. ****************************************************************************}
  1529. constructor TCoffAssembler.Create(smart:boolean);
  1530. begin
  1531. inherited Create(smart);
  1532. objectoutput:=tcoffobjectoutput.createdjgpp(smart);
  1533. end;
  1534. {****************************************************************************
  1535. TPECoffAssembler
  1536. ****************************************************************************}
  1537. constructor TPECoffAssembler.Create(smart:boolean);
  1538. begin
  1539. inherited Create(smart);
  1540. objectoutput:=tcoffobjectoutput.createwin32(smart);
  1541. end;
  1542. {****************************************************************************
  1543. TCoffLinker
  1544. ****************************************************************************}
  1545. constructor TCoffLinker.Create;
  1546. begin
  1547. inherited Create;
  1548. exeoutput:=tcoffexeoutput.createdjgpp;
  1549. end;
  1550. {*****************************************************************************
  1551. Initialize
  1552. *****************************************************************************}
  1553. const
  1554. as_i386_coff_info : tasminfo =
  1555. (
  1556. id : as_i386_coff;
  1557. idtxt : 'COFF';
  1558. asmbin : '';
  1559. asmcmd : '';
  1560. supported_target : system_i386_go32v2;
  1561. flags : [af_outputbinary];
  1562. labelprefix : '.L';
  1563. comment : '';
  1564. );
  1565. as_i386_pecoff_info : tasminfo =
  1566. (
  1567. id : as_i386_pecoff;
  1568. idtxt : 'PECOFF';
  1569. asmbin : '';
  1570. asmcmd : '';
  1571. supported_target : system_i386_win32;
  1572. flags : [af_outputbinary];
  1573. labelprefix : '.L';
  1574. comment : '';
  1575. );
  1576. as_i386_pecoffwdosx_info : tasminfo =
  1577. (
  1578. id : as_i386_pecoffwdosx;
  1579. idtxt : 'PEWDOSX';
  1580. asmbin : '';
  1581. asmcmd : '';
  1582. supported_target : system_i386_wdosx;
  1583. flags : [af_outputbinary];
  1584. labelprefix : '.L';
  1585. comment : '';
  1586. );
  1587. as_i386_pecoffwince_info : tasminfo =
  1588. (
  1589. id : as_i386_pecoffwince;
  1590. idtxt : 'PECOFFWINCE';
  1591. asmbin : '';
  1592. asmcmd : '';
  1593. supported_target : system_i386_wince;
  1594. flags : [af_outputbinary];
  1595. labelprefix : '.L';
  1596. comment : '';
  1597. );
  1598. as_arm_pecoffwince_info : tasminfo =
  1599. (
  1600. id : as_arm_pecoffwince;
  1601. idtxt : 'PECOFFWINCE';
  1602. asmbin : '';
  1603. asmcmd : '';
  1604. supported_target : system_arm_wince;
  1605. flags : [af_outputbinary];
  1606. labelprefix : '.L';
  1607. comment : '';
  1608. );
  1609. initialization
  1610. {$ifdef i386}
  1611. RegisterAssembler(as_i386_coff_info,TCoffAssembler);
  1612. RegisterAssembler(as_i386_pecoff_info,TPECoffAssembler);
  1613. RegisterAssembler(as_i386_pecoffwdosx_info,TPECoffAssembler);
  1614. RegisterAssembler(as_i386_pecoffwince_info,TPECoffAssembler);
  1615. {$endif i386}
  1616. {$ifdef arm}
  1617. RegisterAssembler(as_arm_pecoffwince_info,TPECoffAssembler);
  1618. {$endif arm}
  1619. end.