ogcoff.pas 62 KB

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