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