ogcoff.pas 63 KB

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