ogcoff.pas 61 KB

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