ogcoff.pas 60 KB

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