ogcoff.pas 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801
  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','.tbss',
  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. );
  513. begin
  514. { No support for named sections, because section names are limited to 8 chars }
  515. result:=secnames[atype];
  516. end;
  517. procedure tcoffobjectdata.writesymbol(p:tasmsymbol);
  518. begin
  519. if currsec=nil then
  520. internalerror(200403071);
  521. { already written ? }
  522. if p.indexnr<>-1 then
  523. exit;
  524. { calculate symbol index }
  525. if (p.currbind<>AB_LOCAL) then
  526. begin
  527. { insert the symbol in the local index, the indexarray
  528. will take care of the numbering }
  529. symbols.insert(p);
  530. end
  531. else
  532. p.indexnr:=-2; { local }
  533. end;
  534. procedure tcoffobjectdata.writereloc(data,len:aint;p:tasmsymbol;relative:TAsmRelocationType);
  535. var
  536. curraddr,
  537. symaddr : longint;
  538. begin
  539. if currsec=nil then
  540. internalerror(200403072);
  541. if assigned(p) then
  542. begin
  543. { current address }
  544. curraddr:=currsec.mempos+currsec.datasize;
  545. { external/common symbols don't have a fixed memory position yet }
  546. if (p.currbind=AB_COMMON) then
  547. begin
  548. { For go32v2 we need to use the size as address }
  549. if not win32 then
  550. symaddr:=p.size
  551. else
  552. symaddr:=0;
  553. end
  554. else
  555. begin
  556. symaddr:=p.address;
  557. if assigned(p.section) then
  558. inc(symaddr,p.section.mempos);
  559. end;
  560. { no symbol relocation need inside a section }
  561. if (p.section=currsec) and
  562. (p.currbind<>AB_COMMON) then
  563. begin
  564. case relative of
  565. RELOC_ABSOLUTE :
  566. begin
  567. currsec.addsectionreloc(curraddr,currsec,RELOC_ABSOLUTE);
  568. inc(data,symaddr);
  569. end;
  570. RELOC_RELATIVE :
  571. begin
  572. inc(data,symaddr-len-currsec.datasize);
  573. end;
  574. RELOC_RVA :
  575. begin
  576. currsec.addsectionreloc(curraddr,currsec,RELOC_RVA);
  577. inc(data,symaddr);
  578. end;
  579. end;
  580. end
  581. else
  582. begin
  583. writesymbol(p);
  584. if (p.section<>nil) and
  585. (p.currbind<>AB_COMMON) and
  586. (relative<>RELOC_RELATIVE) then
  587. currsec.addsectionreloc(curraddr,p.section,relative)
  588. else
  589. currsec.addsymreloc(curraddr,p,relative);
  590. if (not win32) or
  591. ((relative<>RELOC_RELATIVE) and (p.section<>nil)) then
  592. inc(data,symaddr);
  593. if relative=RELOC_RELATIVE then
  594. begin
  595. if win32 then
  596. dec(data,len-4)
  597. else
  598. dec(data,len+currsec.datasize);
  599. end;
  600. end;
  601. end;
  602. currsec.write(data,len);
  603. end;
  604. procedure tcoffobjectdata.writestabs(offset:aint;p:pchar;nidx,nother,line:longint;reloc : boolean);
  605. var
  606. stab : coffstab;
  607. curraddr : longint;
  608. begin
  609. { local var can be at offset -1 !! PM }
  610. if reloc then
  611. begin
  612. if (offset=-1) then
  613. begin
  614. if currsec=nil then
  615. offset:=0
  616. else
  617. offset:=currsec.datasize;
  618. end;
  619. if (currsec<>nil) then
  620. inc(offset,currsec.datapos);
  621. end;
  622. if assigned(p) and (p[0]<>#0) then
  623. begin
  624. stab.strpos:=stabstrsec.datasize;
  625. stabstrsec.write(p^,strlen(p)+1);
  626. end
  627. else
  628. stab.strpos:=0;
  629. stab.ntype:=nidx;
  630. stab.ndesc:=line;
  631. stab.nother:=nother;
  632. stab.nvalue:=offset;
  633. StabsSec.write(stab,sizeof(stab));
  634. { when the offset is not 0 then write a relocation, take also the
  635. hdrstab into account with the offset }
  636. if reloc then
  637. begin
  638. { current address }
  639. curraddr:=StabsSec.mempos+StabsSec.datasize;
  640. if DLLSource and RelocSection then
  641. { avoid relocation in the .stab section
  642. because it ends up in the .reloc section instead }
  643. StabsSec.addsectionreloc(curraddr-4,currsec,RELOC_RVA)
  644. else
  645. StabsSec.addsectionreloc(curraddr-4,currsec,RELOC_ABSOLUTE);
  646. end;
  647. end;
  648. procedure tcoffobjectdata.writesymstabs(offset:aint;p:pchar;ps:tasmsymbol;nidx,nother,line:longint;reloc:boolean);
  649. var
  650. stab : coffstab;
  651. curraddr : longint;
  652. begin
  653. { do not use the size stored in offset field
  654. this is DJGPP specific ! PM }
  655. if win32 then
  656. offset:=0;
  657. { local var can be at offset -1 !! PM }
  658. if reloc then
  659. begin
  660. if (offset=-1) then
  661. begin
  662. if currsec=nil then
  663. offset:=0
  664. else
  665. offset:=currsec.datasize;
  666. end;
  667. if (currsec<>nil) then
  668. inc(offset,currsec.mempos);
  669. end;
  670. if assigned(p) and (p[0]<>#0) then
  671. begin
  672. stab.strpos:=StabStrSec.datasize;
  673. StabStrSec.write(p^,strlen(p)+1);
  674. end
  675. else
  676. stab.strpos:=0;
  677. stab.ntype:=nidx;
  678. stab.ndesc:=line;
  679. stab.nother:=nother;
  680. stab.nvalue:=offset;
  681. StabsSec.write(stab,sizeof(stab));
  682. { when the offset is not 0 then write a relocation, take also the
  683. hdrstab into account with the offset }
  684. if reloc then
  685. begin
  686. { current address }
  687. curraddr:=StabsSec.mempos+StabsSec.datasize;
  688. if DLLSource and RelocSection then
  689. { avoid relocation in the .stab section
  690. because it ends up in the .reloc section instead }
  691. StabsSec.addsymreloc(curraddr-4,ps,RELOC_RVA)
  692. else
  693. StabsSec.addsymreloc(curraddr-4,ps,RELOC_ABSOLUTE);
  694. end;
  695. end;
  696. procedure tcoffobjectdata.section_mempos(p:tnamedindexitem;arg:pointer);
  697. begin
  698. tcoffobjectsection(p).memsize:=tcoffobjectsection(p).datasize;
  699. { memory position is in arg }
  700. if not win32 then
  701. begin
  702. tcoffobjectsection(p).mempos:=plongint(arg)^;
  703. inc(plongint(arg)^,align(tcoffobjectsection(p).memsize,tcoffobjectsection(p).addralign));
  704. end;
  705. end;
  706. procedure tcoffobjectdata.beforealloc;
  707. begin
  708. { create stabs sections if debugging }
  709. if (cs_debuginfo in aktmoduleswitches) then
  710. begin
  711. StabsSec.Alloc(sizeof(coffstab));
  712. StabStrSec.Alloc(length(SplitFileName(current_module.mainsource^))+2);
  713. end;
  714. end;
  715. procedure tcoffobjectdata.beforewrite;
  716. var
  717. s : string;
  718. begin
  719. { create stabs sections if debugging }
  720. if (cs_debuginfo in aktmoduleswitches) then
  721. begin
  722. writestabs(0,nil,0,0,0,false);
  723. { write zero pchar and name together (PM) }
  724. s:=#0+SplitFileName(current_module.mainsource^)+#0;
  725. stabstrsec.write(s[1],length(s));
  726. end;
  727. end;
  728. procedure tcoffobjectdata.afteralloc;
  729. var
  730. mempos : longint;
  731. begin
  732. { if debug then also count header stab }
  733. if (cs_debuginfo in aktmoduleswitches) then
  734. begin
  735. StabsSec.Alloc(sizeof(coffstab));
  736. StabStrSec.Alloc(length(SplitFileName(current_module.mainsource^))+2);
  737. end;
  738. { calc mempos }
  739. mempos:=0;
  740. sects.foreach(@section_mempos,@mempos);
  741. end;
  742. {****************************************************************************
  743. tdjcoffobjectdata
  744. ****************************************************************************}
  745. constructor tdjcoffobjectdata.create(const n:string);
  746. begin
  747. inherited createcoff(n,false,tdjcoffobjectsection);
  748. end;
  749. {****************************************************************************
  750. tpecoffobjectdata
  751. ****************************************************************************}
  752. constructor tpecoffobjectdata.create(const n:string);
  753. begin
  754. inherited createcoff(n,true,tpecoffobjectsection);
  755. end;
  756. {****************************************************************************
  757. tcoffobjectoutput
  758. ****************************************************************************}
  759. constructor tcoffobjectoutput.createdjgpp(smart:boolean);
  760. begin
  761. inherited create(smart);
  762. win32:=false;
  763. end;
  764. constructor tcoffobjectoutput.createwin32(smart:boolean);
  765. begin
  766. inherited create(smart);
  767. win32:=true;
  768. end;
  769. function tcoffobjectoutput.newobjectdata(const n:string):TAsmObjectData;
  770. begin
  771. if win32 then
  772. result:=tpecoffobjectdata.create(n)
  773. else
  774. result:=tdjcoffobjectdata.create(n);
  775. end;
  776. procedure tcoffobjectoutput.write_symbol(const name:string;value,section,typ,aux:longint);
  777. var
  778. sym : coffsymbol;
  779. begin
  780. FillChar(sym,sizeof(sym),0);
  781. { symbolname }
  782. if length(name)>8 then
  783. begin
  784. sym.strpos:=FCoffStrs.size+4;
  785. FCoffStrs.writestr(name);
  786. FCoffStrs.writestr(#0);
  787. end
  788. else
  789. move(name[1],sym.name,length(name));
  790. sym.value:=value;
  791. sym.section:=section;
  792. sym.typ:=typ;
  793. sym.aux:=aux;
  794. FWriter.write(sym,sizeof(sym));
  795. end;
  796. procedure tcoffobjectoutput.section_write_symbol(p:tnamedindexitem;arg:pointer);
  797. var
  798. secrec : coffsectionrec;
  799. begin
  800. write_symbol(tasmsection(p).name,tasmsection(p).mempos,tasmsection(p).secsymidx,3,1);
  801. fillchar(secrec,sizeof(secrec),0);
  802. secrec.len:=tasmsection(p).aligneddatasize;
  803. secrec.nrelocs:=tasmsection(p).relocations.count;
  804. FWriter.write(secrec,sizeof(secrec));
  805. end;
  806. procedure tcoffobjectoutput.section_write_relocs(p:tnamedindexitem;arg:pointer);
  807. var
  808. rel : coffreloc;
  809. r : TAsmRelocation;
  810. begin
  811. r:=TasmRelocation(tasmsection(p).relocations.first);
  812. while assigned(r) do
  813. begin
  814. rel.address:=r.address;
  815. if assigned(r.symbol) then
  816. begin
  817. if (r.symbol.currbind=AB_LOCAL) then
  818. rel.sym:=2*r.symbol.section.secsymidx
  819. else
  820. begin
  821. if r.symbol.indexnr=-1 then
  822. internalerror(4321);
  823. { indexnr starts with 1, coff starts with 0 }
  824. rel.sym:=r.symbol.indexnr+initsym-1;
  825. end;
  826. end
  827. else
  828. begin
  829. if r.section<>nil then
  830. rel.sym:=2*r.section.secsymidx
  831. else
  832. rel.sym:=0;
  833. end;
  834. case r.typ of
  835. RELOC_RELATIVE :
  836. rel.relative:=$14;
  837. RELOC_ABSOLUTE :
  838. rel.relative:=$6;
  839. RELOC_RVA :
  840. rel.relative:=$7;
  841. end;
  842. FWriter.write(rel,sizeof(rel));
  843. r:=TAsmRelocation(r.next);
  844. end;
  845. end;
  846. procedure tcoffobjectoutput.write_symbols(data:TAsmObjectData);
  847. var
  848. filename : string[18];
  849. value : longint;
  850. sectionval,
  851. globalval : byte;
  852. p : tasmsymbol;
  853. begin
  854. with tcoffobjectdata(data) do
  855. begin
  856. { The `.file' record, and the file name auxiliary record }
  857. write_symbol('.file', 0, -2, $67, 1);
  858. fillchar(filename,sizeof(filename),0);
  859. filename:=SplitFileName(current_module.mainsource^);
  860. FWriter.write(filename[1],sizeof(filename)-1);
  861. { The section records, with their auxiliaries, also store the
  862. symbol index }
  863. Sects.foreach(@section_write_symbol,nil);
  864. { The symbols used }
  865. p:=Tasmsymbol(symbols.First);
  866. while assigned(p) do
  867. begin
  868. if assigned(p.section) and
  869. (p.currbind<>AB_COMMON) then
  870. sectionval:=p.section.secsymidx
  871. else
  872. sectionval:=0;
  873. if p.currbind=AB_LOCAL then
  874. globalval:=3
  875. else
  876. globalval:=2;
  877. { if local of global then set the section value to the address
  878. of the symbol }
  879. if p.currbind in [AB_LOCAL,AB_GLOBAL] then
  880. value:=p.address+p.section.mempos
  881. else
  882. value:=p.size;
  883. { symbolname }
  884. write_symbol(p.name,value,sectionval,globalval,0);
  885. p:=tasmsymbol(p.indexnext);
  886. end;
  887. end;
  888. end;
  889. procedure tcoffobjectoutput.section_set_secsymidx(p:tnamedindexitem;arg:pointer);
  890. begin
  891. inc(plongint(arg)^);
  892. tasmsection(p).secsymidx:=plongint(arg)^;
  893. end;
  894. procedure tcoffobjectoutput.section_set_datapos(p:tnamedindexitem;arg:pointer);
  895. begin
  896. tasmsection(p).datapos:=plongint(arg)^;
  897. if not(aso_alloconly in tasmsection(p).secoptions) then
  898. inc(plongint(arg)^,tasmsection(p).aligneddatasize);
  899. end;
  900. procedure tcoffobjectoutput.section_set_reloc_datapos(p:tnamedindexitem;arg:pointer);
  901. begin
  902. TCoffObjectSection(p).coffrelocpos:=plongint(arg)^;
  903. inc(plongint(arg)^,sizeof(coffreloc)*tasmsection(p).relocations.count);
  904. end;
  905. procedure tcoffobjectoutput.section_write_header(p:tnamedindexitem;arg:pointer);
  906. var
  907. sechdr : coffsechdr;
  908. s : string;
  909. begin
  910. fillchar(sechdr,sizeof(sechdr),0);
  911. s:=tasmsection(p).name;
  912. { section names are limited to 8 chars }
  913. if length(s)>8 then
  914. internalerror(200403312);
  915. move(s[1],sechdr.name,length(s));
  916. if not win32 then
  917. begin
  918. sechdr.rvaofs:=tasmsection(p).mempos;
  919. sechdr.vsize:=tasmsection(p).mempos;
  920. end
  921. else
  922. begin
  923. if tasmsection(p).sectype=sec_bss then
  924. sechdr.vsize:=tasmsection(p).aligneddatasize;
  925. end;
  926. sechdr.datasize:=tasmsection(p).aligneddatasize;
  927. if (tasmsection(p).datasize>0) and
  928. not(aso_alloconly in tasmsection(p).secoptions) then
  929. sechdr.datapos:=tasmsection(p).datapos;
  930. sechdr.nrelocs:=tasmsection(p).relocations.count;
  931. sechdr.relocpos:=TCoffObjectSection(p).coffrelocpos;
  932. sechdr.flags:=TCoffObjectSection(p).flags;
  933. FWriter.write(sechdr,sizeof(sechdr));
  934. end;
  935. procedure tcoffobjectoutput.section_write_data(p:tnamedindexitem;arg:pointer);
  936. var
  937. hp : pdynamicblock;
  938. begin
  939. if (aso_alloconly in tasmsection(p).secoptions) then
  940. exit;
  941. if tasmsection(p).data=nil then
  942. internalerror(200403073);
  943. tasmsection(p).alignsection;
  944. hp:=tasmsection(p).data.firstblock;
  945. while assigned(hp) do
  946. begin
  947. FWriter.write(hp^.data,hp^.used);
  948. hp:=hp^.next;
  949. end;
  950. end;
  951. function tcoffobjectoutput.writedata(data:TAsmObjectData):boolean;
  952. var
  953. orgdatapos,
  954. datapos,
  955. nsects,
  956. sympos,i : longint;
  957. hstab : coffstab;
  958. gotreloc : boolean;
  959. header : coffheader;
  960. empty : array[0..15] of byte;
  961. hp : pdynamicblock;
  962. s : string;
  963. begin
  964. result:=false;
  965. FCoffStrs:=TDynamicArray.Create(strsresize);
  966. with tcoffobjectdata(data) do
  967. begin
  968. { calc amount of sections we have }
  969. fillchar(empty,sizeof(empty),0);
  970. nsects:=0;
  971. Sects.foreach(@section_set_secsymidx,@nsects);
  972. initsym:=2+nsects*2; { 2 for the file }
  973. { For the stab section we need an HdrSym which can now be
  974. calculated more easily }
  975. if StabsSec<>nil then
  976. begin
  977. { first stabs for main source }
  978. writestabs(0,nil,0,0,0,false);
  979. s:=#0+SplitFileName(current_module.mainsource^)+#0;
  980. stabstrsec.write(s[1],length(s));
  981. { header stab }
  982. hstab.strpos:=1;
  983. hstab.ntype:=0;
  984. hstab.nother:=0;
  985. hstab.ndesc:=(StabsSec.datasize div sizeof(coffstab))-1{+1 according to gas output PM};
  986. hstab.nvalue:=StabStrSec.datasize;
  987. StabsSec.data.seek(0);
  988. StabsSec.data.write(hstab,sizeof(hstab));
  989. end;
  990. { Calculate the filepositions }
  991. datapos:=sizeof(coffheader)+sizeof(coffsechdr)*nsects;
  992. { sections first }
  993. Sects.foreach(@section_set_datapos,@datapos);
  994. { relocs }
  995. orgdatapos:=datapos;
  996. Sects.foreach(@section_set_reloc_datapos,@datapos);
  997. gotreloc:=(orgdatapos<>datapos);
  998. { symbols }
  999. sympos:=datapos;
  1000. { COFF header }
  1001. fillchar(header,sizeof(coffheader),0);
  1002. header.mach:=$14c;
  1003. header.nsects:=nsects;
  1004. header.sympos:=sympos;
  1005. header.syms:=symbols.count+initsym;
  1006. header.flag:=COFF_FLAG_AR32WR or COFF_FLAG_NOLINES;
  1007. if not gotreloc then
  1008. header.flag:=header.flag or COFF_FLAG_NORELOCS;
  1009. FWriter.write(header,sizeof(header));
  1010. { Section headers }
  1011. Sects.foreach(@section_write_header,nil);
  1012. { Sections }
  1013. Sects.foreach(@section_write_data,nil);
  1014. { Relocs }
  1015. Sects.foreach(@section_write_relocs,nil);
  1016. { Symbols }
  1017. write_symbols(data);
  1018. { Strings }
  1019. i:=FCoffStrs.size+4;
  1020. FWriter.write(i,4);
  1021. hp:=FCoffStrs.firstblock;
  1022. while assigned(hp) do
  1023. begin
  1024. FWriter.write(hp^.data,hp^.used);
  1025. hp:=hp^.next;
  1026. end;
  1027. end;
  1028. FCoffStrs.Free;
  1029. end;
  1030. {****************************************************************************
  1031. tcoffexeoutput
  1032. ****************************************************************************}
  1033. constructor tcoffexeoutput.createdjgpp;
  1034. begin
  1035. inherited create;
  1036. win32:=false;
  1037. end;
  1038. constructor tcoffexeoutput.createwin32;
  1039. begin
  1040. inherited create;
  1041. win32:=true;
  1042. end;
  1043. function tcoffexeoutput.newobjectinput:tobjectinput;
  1044. begin
  1045. if win32 then
  1046. result:=tcoffobjectinput.createwin32
  1047. else
  1048. result:=tcoffobjectinput.createdjgpp;
  1049. end;
  1050. procedure tcoffexeoutput.write_symbol(const name:string;value,section,typ,aux:longint);
  1051. var
  1052. sym : coffsymbol;
  1053. begin
  1054. FillChar(sym,sizeof(sym),0);
  1055. if length(name)>8 then
  1056. begin
  1057. sym.strpos:=FCoffStrs.size+4;
  1058. FCoffStrs.writestr(name);
  1059. FCoffStrs.writestr(#0);
  1060. end
  1061. else
  1062. move(name[1],sym.name,length(name));
  1063. sym.value:=value;
  1064. sym.section:=section;
  1065. sym.typ:=typ;
  1066. sym.aux:=aux;
  1067. FWriter.write(sym,sizeof(sym));
  1068. end;
  1069. procedure tcoffexeoutput.write_symbols;
  1070. var
  1071. value,
  1072. sectionval,
  1073. globalval : byte;
  1074. objdata : TAsmObjectData;
  1075. p : tasmsymbol;
  1076. begin
  1077. {$ifdef internallinker}
  1078. objdata:=TAsmObjectData(objdatalist.first);
  1079. while assigned(objdata) do
  1080. begin
  1081. with tcoffobjectdata(objdata) do
  1082. begin
  1083. { The symbols used }
  1084. p:=Tasmsymbol(symbols.First);
  1085. while assigned(p) do
  1086. begin
  1087. if p.section=sec_common then
  1088. sectionval:=sections[sec_bss].secsymidx
  1089. else
  1090. sectionval:=sections[p.section.name].secsymidx;
  1091. if p.currbind=AB_LOCAL then
  1092. globalval:=3
  1093. else
  1094. globalval:=2;
  1095. { if local of global then set the section value to the address
  1096. of the symbol }
  1097. if p.currbind in [AB_LOCAL,AB_GLOBAL] then
  1098. value:=p.address
  1099. else
  1100. value:=p.size;
  1101. { symbolname }
  1102. s:=p.name;
  1103. if length(s)>8 then
  1104. begin
  1105. nameidx:=FCoffStrs.size+4;
  1106. FCoffStrs.writestr(s);
  1107. FCoffStrs.writestr(#0);
  1108. end
  1109. else
  1110. begin
  1111. nameidx:=-1;
  1112. namestr:=s;
  1113. end;
  1114. write_symbol(namestr,nameidx,value,sectionval,globalval,0);
  1115. p:=tasmsymbol(p.indexnext);
  1116. end;
  1117. end;
  1118. objdata:=TAsmObjectData(objdata.next);
  1119. end;
  1120. {$endif internallinker}
  1121. end;
  1122. procedure tcoffexeoutput.CalculateMemoryMap;
  1123. var
  1124. objdata : TAsmObjectData;
  1125. secsymidx,
  1126. mempos,
  1127. datapos : longint;
  1128. begin
  1129. {$ifdef internallinker}
  1130. { retrieve amount of sections }
  1131. nsects:=0;
  1132. secsymidx:=0;
  1133. for sec:=low(TSection) to high(TSection) do
  1134. begin
  1135. if sections[sec].available then
  1136. begin
  1137. inc(nsects);
  1138. inc(secsymidx);
  1139. sections[sec].secsymidx:=secsymidx;
  1140. end;
  1141. end;
  1142. { calculate start positions after the headers }
  1143. datapos:=sizeof(coffheader)+sizeof(coffoptheader)+sizeof(coffsechdr)*nsects;
  1144. mempos:=sizeof(coffheader)+sizeof(coffoptheader)+sizeof(coffsechdr)*nsects;
  1145. if not win32 then
  1146. inc(mempos,sizeof(go32v2stub)+$1000);
  1147. { add sections }
  1148. MapObjectdata(datapos,mempos);
  1149. { end symbol }
  1150. AddGlobalSym('_etext',sections[sec_code].mempos+sections[sec_code].memsize);
  1151. AddGlobalSym('_edata',sections[sec_data].mempos+sections[sec_data].memsize);
  1152. AddGlobalSym('end',mempos);
  1153. { symbols }
  1154. nsyms:=0;
  1155. sympos:=0;
  1156. if not(cs_link_strip in aktglobalswitches) then
  1157. begin
  1158. sympos:=datapos;
  1159. objdata:=TAsmObjectData(objdatalist.first);
  1160. while assigned(objdata) do
  1161. begin
  1162. inc(nsyms,objdata.symbols.count);
  1163. objdata:=TAsmObjectData(objdata.next);
  1164. end;
  1165. end;
  1166. {$endif internallinker}
  1167. end;
  1168. function tcoffexeoutput.writedata:boolean;
  1169. var
  1170. i : longint;
  1171. header : coffheader;
  1172. optheader : coffoptheader;
  1173. sechdr : coffsechdr;
  1174. hp : pdynamicblock;
  1175. objdata : TAsmObjectData;
  1176. hsym : tasmsymbol;
  1177. begin
  1178. result:=false;
  1179. {$ifdef internallinker}
  1180. FCoffSyms:=TDynamicArray.Create(symbolresize);
  1181. FCoffStrs:=TDynamicArray.Create(strsresize);
  1182. { Stub }
  1183. if not win32 then
  1184. FWriter.write(go32v2stub,sizeof(go32v2stub));
  1185. { COFF header }
  1186. fillchar(header,sizeof(header),0);
  1187. header.mach:=$14c;
  1188. header.nsects:=nsects;
  1189. header.sympos:=sympos;
  1190. header.syms:=nsyms;
  1191. header.opthdr:=sizeof(coffoptheader);
  1192. header.flag:=COFF_FLAG_AR32WR or COFF_FLAG_EXE or COFF_FLAG_NORELOCS or COFF_FLAG_NOLINES;
  1193. FWriter.write(header,sizeof(header));
  1194. { Optional COFF Header }
  1195. fillchar(optheader,sizeof(optheader),0);
  1196. optheader.magic:=$10b;
  1197. optheader.tsize:=sections[sec_code].memsize;
  1198. optheader.dsize:=sections[sec_data].memsize;
  1199. optheader.bsize:=sections[sec_bss].memsize;
  1200. hsym:=tasmsymbol(globalsyms.search('start'));
  1201. if not assigned(hsym) then
  1202. begin
  1203. Comment(V_Error,'Entrypoint "start" not defined');
  1204. exit;
  1205. end;
  1206. optheader.entry:=hsym.address;
  1207. optheader.text_start:=sections[sec_code].mempos;
  1208. optheader.data_start:=sections[sec_data].mempos;
  1209. FWriter.write(optheader,sizeof(optheader));
  1210. { Section headers }
  1211. for sec:=low(TSection) to high(TSection) do
  1212. if sections[sec].available then
  1213. begin
  1214. fillchar(sechdr,sizeof(sechdr),0);
  1215. move(target_asm.secnames[sec][1],sechdr.name,length(target_asm.secnames[sec]));
  1216. if not win32 then
  1217. begin
  1218. sechdr.rvaofs:=sections[sec].mempos;
  1219. sechdr.vsize:=sections[sec].mempos;
  1220. end
  1221. else
  1222. begin
  1223. if sec=sec_bss then
  1224. sechdr.vsize:=sections[sec].memsize;
  1225. end;
  1226. if sec=sec_bss then
  1227. sechdr.datasize:=sections[sec].memsize
  1228. else
  1229. begin
  1230. sechdr.datasize:=sections[sec].datasize;
  1231. sechdr.datapos:=sections[sec].datapos;
  1232. end;
  1233. sechdr.nrelocs:=0;
  1234. sechdr.relocpos:=0;
  1235. sechdr.flags:=sections[sec].flags;
  1236. FWriter.write(sechdr,sizeof(sechdr));
  1237. end;
  1238. { Sections }
  1239. for sec:=low(TSection) to high(TSection) do
  1240. if sections[sec].available then
  1241. begin
  1242. { update objectfiles }
  1243. objdata:=TAsmObjectData(objdatalist.first);
  1244. while assigned(objdata) do
  1245. begin
  1246. if assigned(objdata.sects[sec]) and
  1247. assigned(objdata.sects[sec].data) then
  1248. begin
  1249. FWriter.WriteZeros(objdata.sects[sec].dataalignbytes);
  1250. hp:=objdata.sects[sec].data.firstblock;
  1251. while assigned(hp) do
  1252. begin
  1253. FWriter.write(hp^.data,hp^.used);
  1254. hp:=hp^.next;
  1255. end;
  1256. end;
  1257. objdata:=TAsmObjectData(objdata.next);
  1258. end;
  1259. end;
  1260. { Optional symbols }
  1261. if not(cs_link_strip in aktglobalswitches) then
  1262. begin
  1263. { Symbols }
  1264. write_symbols;
  1265. { Strings }
  1266. i:=FCoffStrs.size+4;
  1267. FWriter.write(i,4);
  1268. hp:=FCoffStrs.firstblock;
  1269. while assigned(hp) do
  1270. begin
  1271. FWriter.write(hp^.data,hp^.used);
  1272. hp:=hp^.next;
  1273. end;
  1274. end;
  1275. { Release }
  1276. FCoffStrs.Free;
  1277. FCoffSyms.Free;
  1278. result:=true;
  1279. {$endif internallinker}
  1280. end;
  1281. procedure tcoffexeoutput.GenerateExecutable(const fn:string);
  1282. begin
  1283. AddGlobalSym('_etext',0);
  1284. AddGlobalSym('_edata',0);
  1285. AddGlobalSym('end',0);
  1286. if not CalculateSymbols then
  1287. exit;
  1288. CalculateMemoryMap;
  1289. FixupSymbols;
  1290. FixupRelocations;
  1291. writeexefile(fn);
  1292. end;
  1293. {****************************************************************************
  1294. tcoffobjectinput
  1295. ****************************************************************************}
  1296. constructor tcoffobjectinput.createdjgpp;
  1297. begin
  1298. inherited create;
  1299. win32:=false;
  1300. end;
  1301. constructor tcoffobjectinput.createwin32;
  1302. begin
  1303. inherited create;
  1304. win32:=true;
  1305. end;
  1306. function tcoffobjectinput.newobjectdata(const n:string):TAsmObjectData;
  1307. begin
  1308. if win32 then
  1309. result:=tpecoffobjectdata.create(n)
  1310. else
  1311. result:=tdjcoffobjectdata.create(n);
  1312. end;
  1313. procedure tcoffobjectinput.read_relocs(s:TCoffObjectSection);
  1314. var
  1315. rel : coffreloc;
  1316. rel_type : TAsmRelocationType;
  1317. i : longint;
  1318. p : tasmsymbol;
  1319. begin
  1320. for i:=1 to s.coffrelocs do
  1321. begin
  1322. FReader.read(rel,sizeof(rel));
  1323. case rel.relative of
  1324. $14 : rel_type:=RELOC_RELATIVE;
  1325. $06 : rel_type:=RELOC_ABSOLUTE;
  1326. $07 : rel_type:=RELOC_RVA;
  1327. else
  1328. begin
  1329. Comment(V_Error,'Error reading coff file');
  1330. exit;
  1331. end;
  1332. end;
  1333. p:=FSymTbl^[rel.sym].sym;
  1334. if assigned(p) then
  1335. begin
  1336. s.addsymsizereloc(rel.address-s.mempos,p,FSymTbl^[rel.sym].orgsize,rel_type);
  1337. end
  1338. else
  1339. begin
  1340. Comment(V_Error,'Error reading coff file');
  1341. exit;
  1342. end;
  1343. end;
  1344. end;
  1345. procedure tcoffobjectinput.handle_symbols(data:TAsmObjectData);
  1346. var
  1347. size,
  1348. address,
  1349. i,nsyms,
  1350. symidx : longint;
  1351. sym : coffsymbol;
  1352. strname : string;
  1353. p : tasmsymbol;
  1354. bind : Tasmsymbind;
  1355. auxrec : array[0..17] of byte;
  1356. begin
  1357. {$ifdef internallinker}
  1358. with tcoffobjectdata(data) do
  1359. begin
  1360. nsyms:=FCoffSyms.Size div sizeof(CoffSymbol);
  1361. { Allocate memory for symidx -> tasmsymbol table }
  1362. GetMem(FSymTbl,nsyms*sizeof(ttasmsymbolrec));
  1363. FillChar(FSymTbl^,nsyms*sizeof(ttasmsymbolrec),0);
  1364. { Loop all symbols }
  1365. FCoffSyms.Seek(0);
  1366. symidx:=0;
  1367. while (symidx<nsyms) do
  1368. begin
  1369. FCoffSyms.Read(sym,sizeof(sym));
  1370. if plongint(@sym.name)^<>0 then
  1371. begin
  1372. move(sym.name,strname[1],8);
  1373. strname[9]:=#0;
  1374. end
  1375. else
  1376. begin
  1377. FCoffStrs.Seek(sym.strpos-4);
  1378. FCoffStrs.Read(strname[1],255);
  1379. strname[255]:=#0;
  1380. end;
  1381. strname[0]:=chr(strlen(@strname[1]));
  1382. if strname='' then
  1383. Internalerror(200205172);
  1384. bind:=AB_EXTERNAL;
  1385. sec:=sec_none;
  1386. size:=0;
  1387. address:=0;
  1388. case sym.typ of
  1389. COFF_SYM_GLOBAL :
  1390. begin
  1391. if sym.section=0 then
  1392. begin
  1393. if sym.value=0 then
  1394. bind:=AB_EXTERNAL
  1395. else
  1396. begin
  1397. bind:=AB_COMMON;
  1398. size:=sym.value;
  1399. end;
  1400. end
  1401. else
  1402. begin
  1403. bind:=AB_GLOBAL;
  1404. sec:=Fidx2sec[sym.section];
  1405. if assigned(sects[sec]) then
  1406. begin
  1407. if sym.value>=sects[sec].mempos then
  1408. address:=sym.value-sects[sec].mempos
  1409. else
  1410. internalerror(432432432);
  1411. end
  1412. else
  1413. internalerror(34243214);
  1414. end;
  1415. p:=TAsmSymbol.Create(strname,bind,AT_FUNCTION);
  1416. p.SetAddress(0,sec,address,size);
  1417. p.objectdata:=data;
  1418. symbols.insert(p);
  1419. end;
  1420. COFF_SYM_LABEL,
  1421. COFF_SYM_LOCAL :
  1422. begin
  1423. { do not add constants (section=-1) }
  1424. if sym.section<>-1 then
  1425. begin
  1426. bind:=AB_LOCAL;
  1427. sec:=Fidx2sec[sym.section];
  1428. if assigned(sects[sec]) then
  1429. begin
  1430. if sym.value>=sects[sec].mempos then
  1431. address:=sym.value-sects[sec].mempos
  1432. else
  1433. internalerror(432432432);
  1434. end
  1435. else
  1436. internalerror(34243214);
  1437. p:=TAsmSymbol.Create(strname,bind,AT_FUNCTION);
  1438. p.SetAddress(0,sec,address,size);
  1439. p.objectdata:=data;
  1440. symbols.insert(p);
  1441. end;
  1442. end;
  1443. COFF_SYM_SECTION,
  1444. COFF_SYM_FUNCTION,
  1445. COFF_SYM_FILE :
  1446. ;
  1447. else
  1448. internalerror(4342343);
  1449. end;
  1450. FSymTbl^[symidx].sym:=p;
  1451. FSymTbl^[symidx].orgsize:=size;
  1452. { read aux records }
  1453. for i:=1 to sym.aux do
  1454. begin
  1455. FCoffSyms.Read(auxrec,sizeof(auxrec));
  1456. inc(symidx);
  1457. end;
  1458. inc(symidx);
  1459. end;
  1460. end;
  1461. {$endif internallinker}
  1462. end;
  1463. function tcoffobjectinput.readobjectdata(data:TAsmObjectData):boolean;
  1464. var
  1465. strsize,
  1466. i : longint;
  1467. header : coffheader;
  1468. sechdr : coffsechdr;
  1469. secname : array[0..15] of char;
  1470. begin
  1471. result:=false;
  1472. {$ifdef internallinker}
  1473. FCoffSyms:=TDynamicArray.Create(symbolresize);
  1474. FCoffStrs:=TDynamicArray.Create(strsresize);
  1475. with tcoffobjectdata(data) do
  1476. begin
  1477. FillChar(Fidx2sec,sizeof(Fidx2sec),0);
  1478. { Read COFF header }
  1479. if not reader.read(header,sizeof(coffheader)) then
  1480. begin
  1481. Comment(V_Error,'Error reading coff file');
  1482. exit;
  1483. end;
  1484. if header.mach<>$14c then
  1485. begin
  1486. Comment(V_Error,'Not a coff file');
  1487. exit;
  1488. end;
  1489. if header.nsects>255 then
  1490. begin
  1491. Comment(V_Error,'To many sections');
  1492. exit;
  1493. end;
  1494. { Section headers }
  1495. for i:=1 to header.nsects do
  1496. begin
  1497. if not reader.read(sechdr,sizeof(sechdr)) then
  1498. begin
  1499. Comment(V_Error,'Error reading coff file');
  1500. exit;
  1501. end;
  1502. move(sechdr.name,secname,8);
  1503. secname[8]:=#0;
  1504. sec:=str2sec(strpas(secname));
  1505. if sec<>sec_none then
  1506. begin
  1507. Fidx2sec[i]:=sec;
  1508. createsection(sec);
  1509. if not win32 then
  1510. sects[sec].mempos:=sechdr.rvaofs;
  1511. TCoffObjectSection(sects[sec]).coffrelocs:=sechdr.nrelocs;
  1512. TCoffObjectSection(sects[sec]).coffrelocpos:=sechdr.relocpos;
  1513. sects[sec].datapos:=sechdr.datapos;
  1514. sects[sec].datasize:=sechdr.datasize;
  1515. sects[sec].memsize:=sechdr.datasize;
  1516. TCoffObjectSection(sects[sec]).orgmempos:=sects[sec].mempos;
  1517. sects[sec].flags:=sechdr.flags;
  1518. end
  1519. else
  1520. Comment(V_Warning,'skipping unsupported section '+strpas(sechdr.name));
  1521. end;
  1522. { Symbols }
  1523. Reader.Seek(header.sympos);
  1524. if not Reader.ReadArray(FCoffSyms,header.syms*sizeof(CoffSymbol)) then
  1525. begin
  1526. Comment(V_Error,'Error reading coff file');
  1527. exit;
  1528. end;
  1529. { Strings }
  1530. if not Reader.Read(strsize,4) then
  1531. begin
  1532. Comment(V_Error,'Error reading coff file');
  1533. exit;
  1534. end;
  1535. if strsize<4 then
  1536. begin
  1537. Comment(V_Error,'Error reading coff file');
  1538. exit;
  1539. end;
  1540. if not Reader.ReadArray(FCoffStrs,Strsize-4) then
  1541. begin
  1542. Comment(V_Error,'Error reading coff file');
  1543. exit;
  1544. end;
  1545. { Insert all symbols }
  1546. handle_symbols(data);
  1547. { Sections }
  1548. for sec:=low(TSection) to high(TSection) do
  1549. if assigned(sects[sec]) and
  1550. (sec<>sec_bss) then
  1551. begin
  1552. Reader.Seek(sects[sec].datapos);
  1553. if not Reader.ReadArray(sects[sec].data,sects[sec].datasize) then
  1554. begin
  1555. Comment(V_Error,'Error reading coff file');
  1556. exit;
  1557. end;
  1558. end;
  1559. { Relocs }
  1560. for sec:=low(TSection) to high(TSection) do
  1561. if assigned(sects[sec]) and
  1562. (TCoffObjectSection(sects[sec]).coffrelocs>0) then
  1563. begin
  1564. Reader.Seek(TCoffObjectSection(sects[sec]).coffrelocpos);
  1565. read_relocs(TCoffObjectSection(sects[sec]));
  1566. end;
  1567. end;
  1568. FCoffStrs.Free;
  1569. FCoffSyms.Free;
  1570. result:=true;
  1571. {$endif internallinker}
  1572. end;
  1573. {****************************************************************************
  1574. TCoffAssembler
  1575. ****************************************************************************}
  1576. constructor TCoffAssembler.Create(smart:boolean);
  1577. begin
  1578. inherited Create(smart);
  1579. objectoutput:=tcoffobjectoutput.createdjgpp(smart);
  1580. end;
  1581. {****************************************************************************
  1582. TPECoffAssembler
  1583. ****************************************************************************}
  1584. constructor TPECoffAssembler.Create(smart:boolean);
  1585. begin
  1586. inherited Create(smart);
  1587. objectoutput:=tcoffobjectoutput.createwin32(smart);
  1588. end;
  1589. {****************************************************************************
  1590. TCoffLinker
  1591. ****************************************************************************}
  1592. constructor TCoffLinker.Create;
  1593. begin
  1594. inherited Create;
  1595. exeoutput:=tcoffexeoutput.createdjgpp;
  1596. end;
  1597. {*****************************************************************************
  1598. Initialize
  1599. *****************************************************************************}
  1600. const
  1601. as_i386_coff_info : tasminfo =
  1602. (
  1603. id : as_i386_coff;
  1604. idtxt : 'COFF';
  1605. asmbin : '';
  1606. asmcmd : '';
  1607. supported_target : system_i386_go32v2;
  1608. flags : [af_outputbinary];
  1609. labelprefix : '.L';
  1610. comment : '';
  1611. );
  1612. const
  1613. as_i386_pecoff_info : tasminfo =
  1614. (
  1615. id : as_i386_pecoff;
  1616. idtxt : 'PECOFF';
  1617. asmbin : '';
  1618. asmcmd : '';
  1619. supported_target : system_i386_win32;
  1620. flags : [af_outputbinary];
  1621. labelprefix : '.L';
  1622. comment : '';
  1623. );
  1624. as_i386_pecoffwdosx_info : tasminfo =
  1625. (
  1626. id : as_i386_pecoffwdosx;
  1627. idtxt : 'PEWDOSX';
  1628. asmbin : '';
  1629. asmcmd : '';
  1630. supported_target : system_i386_wdosx;
  1631. flags : [af_outputbinary];
  1632. labelprefix : '.L';
  1633. comment : '';
  1634. );
  1635. as_i386_pecoffwince_info : tasminfo =
  1636. (
  1637. id : as_i386_pecoffwince;
  1638. idtxt : 'PECOFFWINCE';
  1639. asmbin : '';
  1640. asmcmd : '';
  1641. supported_target : system_i386_wince;
  1642. flags : [af_outputbinary];
  1643. labelprefix : '.L';
  1644. comment : '';
  1645. );
  1646. initialization
  1647. RegisterAssembler(as_i386_coff_info,TCoffAssembler);
  1648. RegisterAssembler(as_i386_pecoff_info,TPECoffAssembler);
  1649. RegisterAssembler(as_i386_pecoffwdosx_info,TPECoffAssembler);
  1650. RegisterAssembler(as_i386_pecoffwince_info,TPECoffAssembler);
  1651. end.