ogcoff.pas 61 KB

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