2
0

ogcoff.pas 61 KB

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