t_win32.pas 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Peter Vreman
  4. This unit implements support import,export,link routines
  5. for the (i386) Win32 target
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. unit t_win32;
  20. {$i fpcdefs.inc}
  21. interface
  22. uses
  23. {$ifdef Delphi}
  24. dmisc,
  25. sysutils,
  26. {$else Delphi}
  27. dos,
  28. {$endif Delphi}
  29. cutils,cclasses,
  30. aasmbase,aasmtai,aasmcpu,fmodule,globtype,globals,systems,verbose,
  31. symconst,symdef,symsym,
  32. script,gendef,
  33. cpubase,
  34. {$ifdef GDB}
  35. gdb,
  36. {$endif}
  37. import,export,link,cgobj,i_win32;
  38. const
  39. MAX_DEFAULT_EXTENSIONS = 3;
  40. type
  41. tStr4=array[1..MAX_DEFAULT_EXTENSIONS]of string[4];
  42. pStr4=^tStr4;
  43. twin32imported_item = class(timported_item)
  44. procdef : tprocdef;
  45. end;
  46. timportlibwin32=class(timportlib)
  47. private
  48. procedure win32importproc(aprocdef:tprocdef;const func,module : string;index : longint;const name : string);
  49. procedure importvariable_str(const s:string;const name,module:string);
  50. procedure importprocedure_str(const func,module:string;index:longint;const name:string);
  51. public
  52. procedure GetDefExt(var N:longint;var P:pStr4);virtual;
  53. procedure preparelib(const s:string);override;
  54. procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
  55. procedure importvariable(vs:tvarsym;const name,module:string);override;
  56. procedure generatelib;override;
  57. procedure generatenasmlib;virtual;
  58. procedure generatesmartlib;override;
  59. end;
  60. texportlibwin32=class(texportlib)
  61. st : string;
  62. last_index : longint;
  63. procedure preparelib(const s:string);override;
  64. procedure exportprocedure(hp : texported_item);override;
  65. procedure exportvar(hp : texported_item);override;
  66. procedure generatelib;override;
  67. procedure generatenasmlib;virtual;
  68. end;
  69. tlinkerwin32=class(texternallinker)
  70. private
  71. Function WriteResponseFile(isdll:boolean) : Boolean;
  72. Function PostProcessExecutable(const fn:string;isdll:boolean) : Boolean;
  73. public
  74. Constructor Create;override;
  75. Procedure SetDefaultInfo;override;
  76. function MakeExecutable:boolean;override;
  77. function MakeSharedLibrary:boolean;override;
  78. end;
  79. tDLLScannerWin32=class(tDLLScanner)
  80. private
  81. cstring : array[0..127]of char;
  82. function DOSstubOK(var x:cardinal):boolean;
  83. function FindDLL(const s:string;var founddll:string):boolean;
  84. function ExtractDllName(Const Name : string) : string;
  85. public
  86. procedure GetDefExt(var N:longint;var P:pStr4);virtual;
  87. function isSuitableFileType(x:cardinal):longbool;override;
  88. function GetEdata(HeaderEntry:cardinal):longbool;override;
  89. function Scan(const binname:string):longbool;override;
  90. end;
  91. implementation
  92. function DllName(Const Name : string;NdefExt:longint;DefExt:pStr4) : string;
  93. var n : string;
  94. i:longint;
  95. begin
  96. n:=Upper(SplitExtension(Name));
  97. for i:=1 to NdefExt do
  98. if n=DefExt^[i]then
  99. begin
  100. DllName:=Name;
  101. exit;
  102. end
  103. else
  104. DllName:=Name+target_info.sharedlibext;
  105. end;
  106. const
  107. DefaultDLLExtensions:array[1..MAX_DEFAULT_EXTENSIONS]of string[4]=('.DLL','.DRV','.EXE');
  108. {*****************************************************************************
  109. TIMPORTLIBWIN32
  110. *****************************************************************************}
  111. procedure timportlibwin32.GetDefExt(var N:longint;var P:pStr4);
  112. begin
  113. N:=sizeof(DefaultDLLExtensions)div sizeof(DefaultDLLExtensions[1]);
  114. pointer(P):=@DefaultDLLExtensions;
  115. end;
  116. procedure timportlibwin32.preparelib(const s : string);
  117. begin
  118. if not(assigned(importssection)) then
  119. importssection:=TAAsmoutput.create;
  120. end;
  121. procedure timportlibwin32.win32importproc(aprocdef:tprocdef;const func,module : string;index : longint;const name : string);
  122. var
  123. hp1 : timportlist;
  124. hp2 : twin32imported_item;
  125. hs : string;
  126. PP : pStr4;
  127. NN : longint;
  128. begin
  129. { force the current mangledname }
  130. if assigned(aprocdef) then
  131. aprocdef.has_mangledname:=true;
  132. { append extension if required }
  133. GetDefExt(NN,PP);
  134. hs:=DllName(module,NN,PP);
  135. { search for the module }
  136. hp1:=timportlist(current_module.imports.first);
  137. while assigned(hp1) do
  138. begin
  139. if hs=hp1.dllname^ then
  140. break;
  141. hp1:=timportlist(hp1.next);
  142. end;
  143. { generate a new item ? }
  144. if not(assigned(hp1)) then
  145. begin
  146. hp1:=timportlist.create(hs);
  147. current_module.imports.concat(hp1);
  148. end;
  149. { search for reuse of old import item }
  150. hp2:=twin32imported_item(hp1.imported_items.first);
  151. while assigned(hp2) do
  152. begin
  153. if hp2.func^=func then
  154. break;
  155. hp2:=twin32imported_item(hp2.next);
  156. end;
  157. if not assigned(hp2) then
  158. begin
  159. hp2:=twin32imported_item.create(func,name,index);
  160. hp2.procdef:=aprocdef;
  161. hp1.imported_items.concat(hp2);
  162. end;
  163. end;
  164. procedure timportlibwin32.importprocedure(aprocdef:tprocdef;const module : string;index : longint;const name : string);
  165. begin
  166. win32importproc(aprocdef,aprocdef.mangledname,module,index,name);
  167. end;
  168. procedure timportlibwin32.importprocedure_str(const func,module : string;index : longint;const name : string);
  169. begin
  170. win32importproc(nil,func,module,index,name);
  171. end;
  172. procedure timportlibwin32.importvariable(vs:tvarsym;const name,module:string);
  173. begin
  174. importvariable_str(vs.mangledname,name,module);
  175. end;
  176. procedure timportlibwin32.importvariable_str(const s:string;const name,module:string);
  177. var
  178. hp1 : timportlist;
  179. hp2 : twin32imported_item;
  180. hs : string;
  181. NN : longint;
  182. PP : pStr4;
  183. begin
  184. GetDefExt(NN,PP);
  185. hs:=DllName(module,NN,PP);
  186. { search for the module }
  187. hp1:=timportlist(current_module.imports.first);
  188. while assigned(hp1) do
  189. begin
  190. if hs=hp1.dllname^ then
  191. break;
  192. hp1:=timportlist(hp1.next);
  193. end;
  194. { generate a new item ? }
  195. if not(assigned(hp1)) then
  196. begin
  197. hp1:=timportlist.create(hs);
  198. current_module.imports.concat(hp1);
  199. end;
  200. hp2:=twin32imported_item.create_var(s,name);
  201. hp2.procdef:=nil;
  202. hp1.imported_items.concat(hp2);
  203. end;
  204. procedure timportlibwin32.generatenasmlib;
  205. var
  206. hp1 : timportlist;
  207. hp2 : twin32imported_item;
  208. p : pchar;
  209. begin
  210. importssection.concat(tai_section.create(sec_code));
  211. hp1:=timportlist(current_module.imports.first);
  212. while assigned(hp1) do
  213. begin
  214. hp2:=twin32imported_item(hp1.imported_items.first);
  215. while assigned(hp2) do
  216. begin
  217. if (aktoutputformat in [as_i386_tasm,as_i386_masm]) then
  218. p:=strpnew(#9+'EXTRN '+hp2.func^)
  219. else
  220. p:=strpnew(#9+'EXTERN '+hp2.func^);
  221. importssection.concat(tai_direct.create(p));
  222. p:=strpnew(#9+'import '+hp2.func^+' '+hp1.dllname^+' '+hp2.name^);
  223. importssection.concat(tai_direct.create(p));
  224. hp2:=twin32imported_item(hp2.next);
  225. end;
  226. hp1:=timportlist(hp1.next);
  227. end;
  228. end;
  229. procedure timportlibwin32.generatesmartlib;
  230. var
  231. hp1 : timportlist;
  232. {$ifdef GDB}
  233. importname : string;
  234. mangledstring : string;
  235. suffix : integer;
  236. {$endif GDB}
  237. hp2 : twin32imported_item;
  238. lhead,lname,lcode,
  239. lidata4,lidata5 : tasmlabel;
  240. href : treference;
  241. begin
  242. if (aktoutputformat in [as_i386_masm,as_i386_tasm,as_i386_nasmwin32]) then
  243. begin
  244. generatenasmlib;
  245. exit;
  246. end;
  247. hp1:=timportlist(current_module.imports.first);
  248. while assigned(hp1) do
  249. begin
  250. { Get labels for the sections }
  251. objectlibrary.getdatalabel(lhead);
  252. objectlibrary.getdatalabel(lname);
  253. objectlibrary.getaddrlabel(lidata4);
  254. objectlibrary.getaddrlabel(lidata5);
  255. { create header for this importmodule }
  256. importsSection.concat(Tai_cut.Create_begin);
  257. importsSection.concat(Tai_section.Create(sec_idata2));
  258. importsSection.concat(Tai_label.Create(lhead));
  259. { pointer to procedure names }
  260. importsSection.concat(Tai_const_symbol.Create_rva(lidata4));
  261. { two empty entries follow }
  262. importsSection.concat(Tai_const.Create_32bit(0));
  263. importsSection.concat(Tai_const.Create_32bit(0));
  264. { pointer to dll name }
  265. importsSection.concat(Tai_const_symbol.Create_rva(lname));
  266. { pointer to fixups }
  267. importsSection.concat(Tai_const_symbol.Create_rva(lidata5));
  268. { first write the name references }
  269. importsSection.concat(Tai_section.Create(sec_idata4));
  270. importsSection.concat(Tai_const.Create_32bit(0));
  271. importsSection.concat(Tai_label.Create(lidata4));
  272. { then the addresses and create also the indirect jump }
  273. importsSection.concat(Tai_section.Create(sec_idata5));
  274. importsSection.concat(Tai_const.Create_32bit(0));
  275. importsSection.concat(Tai_label.Create(lidata5));
  276. { create procedures }
  277. hp2:=twin32imported_item(hp1.imported_items.first);
  278. while assigned(hp2) do
  279. begin
  280. { insert cuts }
  281. importsSection.concat(Tai_cut.Create);
  282. { create indirect jump }
  283. if not hp2.is_var then
  284. begin
  285. objectlibrary.getlabel(lcode);
  286. reference_reset_symbol(href,lcode,0);
  287. { place jump in codesegment, insert a code section in the
  288. imporTSection to reduce the amount of .s files (PFV) }
  289. importsSection.concat(Tai_section.Create(sec_code));
  290. {$IfDef GDB}
  291. if (cs_debuginfo in aktmoduleswitches) then
  292. importsSection.concat(Tai_stab_function_name.Create(nil));
  293. {$EndIf GDB}
  294. importsSection.concat(Tai_symbol.Createname_global(hp2.func^,0));
  295. importsSection.concat(Taicpu.Op_ref(A_JMP,S_NO,href));
  296. importsSection.concat(Tai_align.Create_op(4,$90));
  297. {$IfDef GDB}
  298. if (cs_debuginfo in aktmoduleswitches) and assigned(hp2.procdef) then
  299. begin
  300. mangledstring:=hp2.procdef.mangledname;
  301. hp2.procdef.setmangledname(hp2.func^);
  302. hp2.procdef.concatstabto(importssection);
  303. hp2.procdef.setmangledname(mangledstring);
  304. end;
  305. {$EndIf GDB}
  306. end;
  307. { create head link }
  308. importsSection.concat(Tai_section.Create(sec_idata7));
  309. importsSection.concat(Tai_const_symbol.Create_rva(lhead));
  310. { fixup }
  311. objectlibrary.getlabel(tasmlabel(hp2.lab));
  312. importsSection.concat(Tai_section.Create(sec_idata4));
  313. importsSection.concat(Tai_const_symbol.Create_rva(hp2.lab));
  314. { add jump field to imporTSection }
  315. importsSection.concat(Tai_section.Create(sec_idata5));
  316. if hp2.is_var then
  317. importsSection.concat(Tai_symbol.Createname_global(hp2.func^,0))
  318. else
  319. importsSection.concat(Tai_label.Create(lcode));
  320. {$ifdef GDB}
  321. if (cs_debuginfo in aktmoduleswitches) then
  322. begin
  323. if assigned(hp2.name) then
  324. begin
  325. importname:='__imp_'+hp2.name^;
  326. suffix:=0;
  327. while assigned(objectlibrary.getasmsymbol(importname)) do
  328. begin
  329. inc(suffix);
  330. importname:='__imp_'+hp2.name^+'_'+tostr(suffix);
  331. end;
  332. importssection.concat(tai_symbol.createname(importname,4));
  333. end
  334. else
  335. begin
  336. importname:='__imp_by_ordinal'+tostr(hp2.ordnr);
  337. suffix:=0;
  338. while assigned(objectlibrary.getasmsymbol(importname)) do
  339. begin
  340. inc(suffix);
  341. importname:='__imp_by_ordinal'+tostr(hp2.ordnr)+'_'+tostr(suffix);
  342. end;
  343. importssection.concat(tai_symbol.createname(importname,4));
  344. end;
  345. end;
  346. {$endif GDB}
  347. if hp2.name^<>'' then
  348. importsSection.concat(Tai_const_symbol.Create_rva(hp2.lab))
  349. else
  350. importsSection.concat(Tai_const.Create_32bit(cardinal($80000000) or cardinal(hp2.ordnr)));
  351. { finally the import information }
  352. importsSection.concat(Tai_section.Create(sec_idata6));
  353. importsSection.concat(Tai_label.Create(hp2.lab));
  354. importsSection.concat(Tai_const.Create_16bit(hp2.ordnr));
  355. importsSection.concat(Tai_string.Create(hp2.name^+#0));
  356. importsSection.concat(Tai_align.Create_op(2,0));
  357. hp2:=twin32imported_item(hp2.next);
  358. end;
  359. { write final section }
  360. importsSection.concat(Tai_cut.Create_end);
  361. { end of name references }
  362. importsSection.concat(Tai_section.Create(sec_idata4));
  363. importsSection.concat(Tai_const.Create_32bit(0));
  364. { end if addresses }
  365. importsSection.concat(Tai_section.Create(sec_idata5));
  366. importsSection.concat(Tai_const.Create_32bit(0));
  367. { dllname }
  368. importsSection.concat(Tai_section.Create(sec_idata7));
  369. importsSection.concat(Tai_label.Create(lname));
  370. importsSection.concat(Tai_string.Create(hp1.dllname^+#0));
  371. hp1:=timportlist(hp1.next);
  372. end;
  373. end;
  374. procedure timportlibwin32.generatelib;
  375. var
  376. hp1 : timportlist;
  377. hp2 : twin32imported_item;
  378. l1,l2,l3,l4 : tasmlabel;
  379. {$ifdef GDB}
  380. importname : string;
  381. mangledstring : string;
  382. suffix : integer;
  383. {$endif GDB}
  384. href : treference;
  385. begin
  386. if (aktoutputformat in [as_i386_masm,as_i386_tasm,as_i386_nasmwin32]) then
  387. begin
  388. generatenasmlib;
  389. exit;
  390. end;
  391. hp1:=timportlist(current_module.imports.first);
  392. while assigned(hp1) do
  393. begin
  394. { align codesegment for the jumps }
  395. importsSection.concat(Tai_section.Create(sec_code));
  396. importsSection.concat(Tai_align.Create_op(4,$90));
  397. { Get labels for the sections }
  398. objectlibrary.getlabel(l1);
  399. objectlibrary.getlabel(l2);
  400. objectlibrary.getlabel(l3);
  401. importsSection.concat(Tai_section.Create(sec_idata2));
  402. { pointer to procedure names }
  403. importsSection.concat(Tai_const_symbol.Create_rva(l2));
  404. { two empty entries follow }
  405. importsSection.concat(Tai_const.Create_32bit(0));
  406. importsSection.concat(Tai_const.Create_32bit(0));
  407. { pointer to dll name }
  408. importsSection.concat(Tai_const_symbol.Create_rva(l1));
  409. { pointer to fixups }
  410. importsSection.concat(Tai_const_symbol.Create_rva(l3));
  411. { only create one section for each else it will
  412. create a lot of idata* }
  413. { first write the name references }
  414. importsSection.concat(Tai_section.Create(sec_idata4));
  415. importsSection.concat(Tai_label.Create(l2));
  416. hp2:=twin32imported_item(hp1.imported_items.first);
  417. while assigned(hp2) do
  418. begin
  419. objectlibrary.getlabel(tasmlabel(hp2.lab));
  420. if hp2.name^<>'' then
  421. importsSection.concat(Tai_const_symbol.Create_rva(hp2.lab))
  422. else
  423. importsSection.concat(Tai_const.Create_32bit(cardinal($80000000) or cardinal(hp2.ordnr)));
  424. hp2:=twin32imported_item(hp2.next);
  425. end;
  426. { finalize the names ... }
  427. importsSection.concat(Tai_const.Create_32bit(0));
  428. { then the addresses and create also the indirect jump }
  429. importsSection.concat(Tai_section.Create(sec_idata5));
  430. importsSection.concat(Tai_label.Create(l3));
  431. hp2:=twin32imported_item(hp1.imported_items.first);
  432. while assigned(hp2) do
  433. begin
  434. if not hp2.is_var then
  435. begin
  436. objectlibrary.getlabel(l4);
  437. { create indirect jump }
  438. reference_reset_symbol(href,l4,0);
  439. { place jump in codesegment }
  440. importsSection.concat(Tai_section.Create(sec_code));
  441. {$IfDef GDB}
  442. if (cs_debuginfo in aktmoduleswitches) then
  443. importssection.concat(tai_stab_function_name.create(nil));
  444. {$EndIf GDB}
  445. importsSection.concat(Tai_symbol.Createname_global(hp2.func^,0));
  446. importsSection.concat(Taicpu.Op_ref(A_JMP,S_NO,href));
  447. importsSection.concat(Tai_align.Create_op(4,$90));
  448. {$IfDef GDB}
  449. if (cs_debuginfo in aktmoduleswitches) and assigned(hp2.procdef) then
  450. begin
  451. mangledstring:=hp2.procdef.mangledname;
  452. hp2.procdef.setmangledname(hp2.func^);
  453. hp2.procdef.concatstabto(importssection);
  454. hp2.procdef.setmangledname(mangledstring);
  455. end;
  456. {$EndIf GDB}
  457. { add jump field to imporTSection }
  458. importsSection.concat(Tai_section.Create(sec_idata5));
  459. {$ifdef GDB}
  460. if (cs_debuginfo in aktmoduleswitches) then
  461. begin
  462. if assigned(hp2.name) then
  463. begin
  464. importname:='__imp_'+hp2.name^;
  465. suffix:=0;
  466. while assigned(objectlibrary.getasmsymbol(importname)) do
  467. begin
  468. inc(suffix);
  469. importname:='__imp_'+hp2.name^+'_'+tostr(suffix);
  470. end;
  471. importssection.concat(tai_symbol.createname(importname,4));
  472. end
  473. else
  474. begin
  475. importname:='__imp_by_ordinal'+tostr(hp2.ordnr);
  476. suffix:=0;
  477. while assigned(objectlibrary.getasmsymbol(importname)) do
  478. begin
  479. inc(suffix);
  480. importname:='__imp_by_ordinal'+tostr(hp2.ordnr)+'_'+tostr(suffix);
  481. end;
  482. importssection.concat(tai_symbol.createname(importname,4));
  483. end;
  484. end;
  485. {$endif GDB}
  486. importsSection.concat(Tai_label.Create(l4));
  487. end
  488. else
  489. begin
  490. importsSection.concat(Tai_symbol.Createname_global(hp2.func^,0));
  491. end;
  492. importsSection.concat(Tai_const_symbol.Create_rva(hp2.lab));
  493. hp2:=twin32imported_item(hp2.next);
  494. end;
  495. { finalize the addresses }
  496. importsSection.concat(Tai_const.Create_32bit(0));
  497. { finally the import information }
  498. importsSection.concat(Tai_section.Create(sec_idata6));
  499. hp2:=twin32imported_item(hp1.imported_items.first);
  500. while assigned(hp2) do
  501. begin
  502. importsSection.concat(Tai_label.Create(hp2.lab));
  503. { the ordinal number }
  504. importsSection.concat(Tai_const.Create_16bit(hp2.ordnr));
  505. importsSection.concat(Tai_string.Create(hp2.name^+#0));
  506. importsSection.concat(Tai_align.Create_op(2,0));
  507. hp2:=twin32imported_item(hp2.next);
  508. end;
  509. { create import dll name }
  510. importsSection.concat(Tai_section.Create(sec_idata7));
  511. importsSection.concat(Tai_label.Create(l1));
  512. importsSection.concat(Tai_string.Create(hp1.dllname^+#0));
  513. hp1:=timportlist(hp1.next);
  514. end;
  515. end;
  516. {*****************************************************************************
  517. TEXPORTLIBWIN32
  518. *****************************************************************************}
  519. procedure texportlibwin32.preparelib(const s:string);
  520. begin
  521. if not(assigned(exportssection)) then
  522. exportssection:=TAAsmoutput.create;
  523. last_index:=0;
  524. objectlibrary.getdatalabel(edatalabel);
  525. end;
  526. procedure texportlibwin32.exportvar(hp : texported_item);
  527. begin
  528. { same code used !! PM }
  529. exportprocedure(hp);
  530. end;
  531. procedure texportlibwin32.exportprocedure(hp : texported_item);
  532. { must be ordered at least for win32 !! }
  533. var
  534. hp2 : texported_item;
  535. begin
  536. { first test the index value }
  537. if (hp.options and eo_index)<>0 then
  538. begin
  539. if (hp.index<=0) or (hp.index>$ffff) then
  540. begin
  541. message1(parser_e_export_invalid_index,tostr(hp.index));
  542. exit;
  543. end;
  544. if (hp.index<=last_index) then
  545. begin
  546. message1(parser_e_export_ordinal_double,tostr(hp.index));
  547. { disregard index value }
  548. inc(last_index);
  549. hp.index:=last_index;
  550. exit;
  551. end
  552. else
  553. begin
  554. last_index:=hp.index;
  555. end;
  556. end
  557. else
  558. begin
  559. inc(last_index);
  560. hp.index:=last_index;
  561. end;
  562. { now place in correct order }
  563. hp2:=texported_item(current_module._exports.first);
  564. while assigned(hp2) and
  565. (hp.name^>hp2.name^) do
  566. hp2:=texported_item(hp2.next);
  567. { insert hp there !! }
  568. if hp2=nil then
  569. current_module._exports.concat(hp)
  570. else
  571. begin
  572. if hp2.name^=hp.name^ then
  573. begin
  574. { this is not allowed !! }
  575. message1(parser_e_export_name_double,hp.name^);
  576. exit;
  577. end;
  578. current_module._exports.insertbefore(hp,hp2);
  579. end;
  580. { if hp2=texported_item(current_module._exports.first) then
  581. current_module._exports.concat(hp)
  582. else if assigned(hp2) then
  583. begin
  584. hp.next:=hp2;
  585. hp.previous:=hp2.previous;
  586. if assigned(hp2.previous) then
  587. hp2.previous.next:=hp;
  588. hp2.previous:=hp;
  589. end
  590. else
  591. current_module._exports.concat(hp);}
  592. end;
  593. procedure texportlibwin32.generatelib;
  594. var
  595. ordinal_base,ordinal_max,ordinal_min : longint;
  596. current_index : longint;
  597. entries,named_entries : longint;
  598. name_label,dll_name_label,export_address_table : tasmlabel;
  599. export_name_table_pointers,export_ordinal_table : tasmlabel;
  600. hp,hp2 : texported_item;
  601. temtexport : TLinkedList;
  602. address_table,name_table_pointers,
  603. name_table,ordinal_table : TAAsmoutput;
  604. begin
  605. if (aktoutputformat in [as_i386_masm,as_i386_tasm,as_i386_nasmwin32]) then
  606. begin
  607. generatenasmlib;
  608. exit;
  609. end;
  610. hp:=texported_item(current_module._exports.first);
  611. if not assigned(hp) then
  612. exit;
  613. ordinal_max:=0;
  614. ordinal_min:=$7FFFFFFF;
  615. entries:=0;
  616. named_entries:=0;
  617. objectlibrary.getlabel(dll_name_label);
  618. objectlibrary.getlabel(export_address_table);
  619. objectlibrary.getlabel(export_name_table_pointers);
  620. objectlibrary.getlabel(export_ordinal_table);
  621. { count entries }
  622. while assigned(hp) do
  623. begin
  624. inc(entries);
  625. if (hp.index>ordinal_max) then
  626. ordinal_max:=hp.index;
  627. if (hp.index>0) and (hp.index<ordinal_min) then
  628. ordinal_min:=hp.index;
  629. if assigned(hp.name) then
  630. inc(named_entries);
  631. hp:=texported_item(hp.next);
  632. end;
  633. { no support for higher ordinal base yet !! }
  634. ordinal_base:=1;
  635. current_index:=ordinal_base;
  636. { we must also count the holes !! }
  637. entries:=ordinal_max-ordinal_base+1;
  638. exportsSection.concat(Tai_section.Create(sec_edata));
  639. { create label to reference from main so smartlink will include
  640. the .edata section }
  641. exportsSection.concat(Tai_symbol.Create_global(edatalabel,0));
  642. { export flags }
  643. exportsSection.concat(Tai_const.Create_32bit(0));
  644. { date/time stamp }
  645. exportsSection.concat(Tai_const.Create_32bit(0));
  646. { major version }
  647. exportsSection.concat(Tai_const.Create_16bit(0));
  648. { minor version }
  649. exportsSection.concat(Tai_const.Create_16bit(0));
  650. { pointer to dll name }
  651. exportsSection.concat(Tai_const_symbol.Create_rva(dll_name_label));
  652. { ordinal base normally set to 1 }
  653. exportsSection.concat(Tai_const.Create_32bit(ordinal_base));
  654. { number of entries }
  655. exportsSection.concat(Tai_const.Create_32bit(entries));
  656. { number of named entries }
  657. exportsSection.concat(Tai_const.Create_32bit(named_entries));
  658. { address of export address table }
  659. exportsSection.concat(Tai_const_symbol.Create_rva(export_address_table));
  660. { address of name pointer pointers }
  661. exportsSection.concat(Tai_const_symbol.Create_rva(export_name_table_pointers));
  662. { address of ordinal number pointers }
  663. exportsSection.concat(Tai_const_symbol.Create_rva(export_ordinal_table));
  664. { the name }
  665. exportsSection.concat(Tai_label.Create(dll_name_label));
  666. if st='' then
  667. exportsSection.concat(Tai_string.Create(current_module.modulename^+target_info.sharedlibext+#0))
  668. else
  669. exportsSection.concat(Tai_string.Create(st+target_info.sharedlibext+#0));
  670. { export address table }
  671. address_table:=TAAsmoutput.create;
  672. address_table.concat(Tai_align.Create_op(4,0));
  673. address_table.concat(Tai_label.Create(export_address_table));
  674. name_table_pointers:=TAAsmoutput.create;
  675. name_table_pointers.concat(Tai_align.Create_op(4,0));
  676. name_table_pointers.concat(Tai_label.Create(export_name_table_pointers));
  677. ordinal_table:=TAAsmoutput.create;
  678. ordinal_table.concat(Tai_align.Create_op(4,0));
  679. ordinal_table.concat(Tai_label.Create(export_ordinal_table));
  680. name_table:=TAAsmoutput.Create;
  681. name_table.concat(Tai_align.Create_op(4,0));
  682. { write each address }
  683. hp:=texported_item(current_module._exports.first);
  684. while assigned(hp) do
  685. begin
  686. if (hp.options and eo_name)<>0 then
  687. begin
  688. objectlibrary.getlabel(name_label);
  689. name_table_pointers.concat(Tai_const_symbol.Create_rva(name_label));
  690. ordinal_table.concat(Tai_const.Create_16bit(hp.index-ordinal_base));
  691. name_table.concat(Tai_align.Create_op(2,0));
  692. name_table.concat(Tai_label.Create(name_label));
  693. name_table.concat(Tai_string.Create(hp.name^+#0));
  694. end;
  695. hp:=texported_item(hp.next);
  696. end;
  697. { order in increasing ordinal values }
  698. { into temtexport list }
  699. temtexport:=TLinkedList.Create;
  700. hp:=texported_item(current_module._exports.first);
  701. while assigned(hp) do
  702. begin
  703. current_module._exports.remove(hp);
  704. hp2:=texported_item(temtexport.first);
  705. while assigned(hp2) and (hp.index>hp2.index) do
  706. hp2:=texported_item(hp2.next);
  707. if hp2=nil then
  708. temtexport.concat(hp)
  709. else
  710. temtexport.insertbefore(hp,hp2);
  711. { if hp2=texported_item(temtexport.first) then
  712. temtexport.insert(hp)
  713. else
  714. begin
  715. if assigned(hp2) then
  716. begin
  717. hp.next:=hp2;
  718. hp.previous:=hp2.previous;
  719. hp2.previous:=hp;
  720. if assigned(hp.previous) then
  721. hp.previous.next:=hp;
  722. end
  723. else
  724. temtexport.concat(hp);
  725. end;}
  726. hp:=texported_item(current_module._exports.first);;
  727. end;
  728. { write the export adress table }
  729. current_index:=ordinal_base;
  730. hp:=texported_item(temtexport.first);
  731. while assigned(hp) do
  732. begin
  733. { fill missing values }
  734. while current_index<hp.index do
  735. begin
  736. address_table.concat(Tai_const.Create_32bit(0));
  737. inc(current_index);
  738. end;
  739. case hp.sym.typ of
  740. varsym :
  741. address_table.concat(Tai_const_symbol.Createname_rva(tvarsym(hp.sym).mangledname));
  742. typedconstsym :
  743. address_table.concat(Tai_const_symbol.Createname_rva(ttypedconstsym(hp.sym).mangledname));
  744. procsym :
  745. address_table.concat(Tai_const_symbol.Createname_rva(tprocsym(hp.sym).first_procdef.mangledname));
  746. end;
  747. inc(current_index);
  748. hp:=texported_item(hp.next);
  749. end;
  750. exportsSection.concatlist(address_table);
  751. exportsSection.concatlist(name_table_pointers);
  752. exportsSection.concatlist(ordinal_table);
  753. exportsSection.concatlist(name_table);
  754. address_table.Free;
  755. name_table_pointers.free;
  756. ordinal_table.free;
  757. name_table.free;
  758. temtexport.free;
  759. end;
  760. procedure texportlibwin32.generatenasmlib;
  761. var
  762. hp : texported_item;
  763. p : pchar;
  764. s : string;
  765. begin
  766. exportssection.concat(tai_section.create(sec_code));
  767. hp:=texported_item(current_module._exports.first);
  768. while assigned(hp) do
  769. begin
  770. case hp.sym.typ of
  771. varsym :
  772. s:=tvarsym(hp.sym).mangledname;
  773. typedconstsym :
  774. s:=ttypedconstsym(hp.sym).mangledname;
  775. procsym :
  776. s:=tprocsym(hp.sym).first_procdef.mangledname;
  777. else
  778. s:='';
  779. end;
  780. p:=strpnew(#9+'export '+s+' '+hp.name^+' '+tostr(hp.index));
  781. exportssection.concat(tai_direct.create(p));
  782. hp:=texported_item(hp.next);
  783. end;
  784. end;
  785. {****************************************************************************
  786. TLINKERWIN32
  787. ****************************************************************************}
  788. Constructor TLinkerWin32.Create;
  789. begin
  790. Inherited Create;
  791. { allow duplicated libs (PM) }
  792. SharedLibFiles.doubles:=true;
  793. StaticLibFiles.doubles:=true;
  794. If not ForceDeffileForExport then
  795. UseDeffileForExport:=false;
  796. end;
  797. Procedure TLinkerWin32.SetDefaultInfo;
  798. begin
  799. with Info do
  800. begin
  801. ExeCmd[1]:='ld $OPT $STRIP $APPTYPE $IMAGEBASE $RELOC -o $EXE $RES';
  802. DllCmd[1]:='ld $OPT $STRIP --dll $APPTYPE $IMAGEBASE $RELOC -o $EXE $RES';
  803. if RelocSection or UseDeffileForExport then
  804. begin
  805. { ExeCmd[2]:='dlltool --as $ASBIN --dllname $EXE --output-exp exp.$$$ $RELOC $DEF';
  806. use short forms to avoid 128 char limitation problem }
  807. ExeCmd[2]:='dlltool -S $ASBIN -D $EXE -e exp.$$$ $RELOC $DEF';
  808. ExeCmd[3]:='ld $OPT $STRIP $APPTYPE $IMAGEBASE -o $EXE $RES exp.$$$';
  809. { DllCmd[2]:='dlltool --as $ASBIN --dllname $EXE --output-exp exp.$$$ $RELOC $DEF'; }
  810. DllCmd[2]:='dlltool -S $ASBIN -D $EXE -e exp.$$$ $RELOC $DEF';
  811. DllCmd[3]:='ld $OPT $STRIP --dll $APPTYPE $IMAGEBASE -o $EXE $RES exp.$$$';
  812. end;
  813. end;
  814. end;
  815. Function TLinkerWin32.WriteResponseFile(isdll:boolean) : Boolean;
  816. Var
  817. linkres : TLinkRes;
  818. HPath : TStringListItem;
  819. s,s2 : string;
  820. i : integer;
  821. linklibc : boolean;
  822. begin
  823. WriteResponseFile:=False;
  824. linklibc:=false;
  825. { Open link.res file }
  826. LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
  827. { Write path to search libraries }
  828. HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
  829. while assigned(HPath) do
  830. begin
  831. LinkRes.Add('SEARCH_DIR('+MaybeQuoted(HPath.Str)+')');
  832. HPath:=TStringListItem(HPath.Next);
  833. end;
  834. HPath:=TStringListItem(LibrarySearchPath.First);
  835. while assigned(HPath) do
  836. begin
  837. LinkRes.Add('SEARCH_DIR('+MaybeQuoted(HPath.Str)+')');
  838. HPath:=TStringListItem(HPath.Next);
  839. end;
  840. { add objectfiles, start with prt0 always }
  841. { profiling of shared libraries is currently not supported }
  842. LinkRes.Add('INPUT(');
  843. if isdll then
  844. LinkRes.AddFileName(MaybeQuoted(FindObjectFile('wdllprt0','',false)))
  845. else
  846. if (cs_profile in aktmoduleswitches) then
  847. LinkRes.AddFileName(MaybeQuoted(FindObjectFile('gprt0','',false)))
  848. else
  849. LinkRes.AddFileName(MaybeQuoted(FindObjectFile('wprt0','',false)));
  850. while not ObjectFiles.Empty do
  851. begin
  852. s:=ObjectFiles.GetFirst;
  853. if s<>'' then
  854. LinkRes.AddFileName(MaybeQuoted(s));
  855. end;
  856. LinkRes.Add(')');
  857. { Write staticlibraries }
  858. if (not StaticLibFiles.Empty) or (cs_profile in aktmoduleswitches) then
  859. begin
  860. LinkRes.Add('GROUP(');
  861. if (cs_profile in aktmoduleswitches) then
  862. begin
  863. LinkRes.Add('-lgcc');
  864. LinkRes.Add('-lmoldname');
  865. LinkRes.Add('-lmsvcrt');
  866. LinkRes.Add('-lgmon');
  867. LinkRes.Add('-lkernel32');
  868. end;
  869. While not StaticLibFiles.Empty do
  870. begin
  871. S:=StaticLibFiles.GetFirst;
  872. LinkRes.AddFileName(MaybeQuoted(s));
  873. end;
  874. LinkRes.Add(')');
  875. end;
  876. { Write sharedlibraries }
  877. if not SharedLibFiles.Empty then
  878. begin
  879. LinkRes.Add('INPUT(') ;
  880. While not SharedLibFiles.Empty do
  881. begin
  882. S:=SharedLibFiles.GetFirst;
  883. if FindLibraryFile(s,target_info.staticClibprefix,target_info.staticClibext,s2) then
  884. begin
  885. LinkRes.Add(MaybeQuoted(s2));
  886. continue;
  887. end;
  888. if pos(target_info.sharedlibprefix,s)=1 then
  889. s:=copy(s,length(target_info.sharedlibprefix)+1,255);
  890. if s<>'c' then
  891. begin
  892. i:=Pos(target_info.sharedlibext,S);
  893. if i>0 then
  894. Delete(S,i,255);
  895. LinkRes.Add('-l'+s);
  896. end
  897. else
  898. begin
  899. LinkRes.Add('-l'+s);
  900. linklibc:=true;
  901. end;
  902. end;
  903. { be sure that libc is the last lib }
  904. if linklibc then
  905. LinkRes.Add('-lc');
  906. LinkRes.Add(')');
  907. end;
  908. { Write and Close response }
  909. linkres.writetodisk;
  910. LinkRes.Free;
  911. WriteResponseFile:=True;
  912. end;
  913. function TLinkerWin32.MakeExecutable:boolean;
  914. var
  915. binstr,
  916. cmdstr : string;
  917. success : boolean;
  918. i : longint;
  919. AsBinStr : string[80];
  920. StripStr,
  921. RelocStr,
  922. AppTypeStr,
  923. ImageBaseStr : string[40];
  924. begin
  925. if not(cs_link_extern in aktglobalswitches) then
  926. Message1(exec_i_linking,current_module.exefilename^);
  927. { Create some replacements }
  928. RelocStr:='';
  929. AppTypeStr:='';
  930. ImageBaseStr:='';
  931. StripStr:='';
  932. AsBinStr:=FindUtil(utilsprefix+'as');
  933. if RelocSection then
  934. { Using short form to avoid problems with 128 char limitation under Dos. }
  935. RelocStr:='--base-file base.$$$';
  936. if apptype=app_gui then
  937. AppTypeStr:='--subsystem windows';
  938. if assigned(DLLImageBase) then
  939. ImageBaseStr:='--image-base=0x'+DLLImageBase^;
  940. if (cs_link_strip in aktglobalswitches) then
  941. StripStr:='-s';
  942. { Write used files and libraries }
  943. WriteResponseFile(false);
  944. { Call linker }
  945. success:=false;
  946. for i:=1 to 3 do
  947. begin
  948. SplitBinCmd(Info.ExeCmd[i],binstr,cmdstr);
  949. if binstr<>'' then
  950. begin
  951. Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
  952. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  953. Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
  954. Replace(cmdstr,'$APPTYPE',AppTypeStr);
  955. Replace(cmdstr,'$ASBIN',AsbinStr);
  956. Replace(cmdstr,'$RELOC',RelocStr);
  957. Replace(cmdstr,'$IMAGEBASE',ImageBaseStr);
  958. Replace(cmdstr,'$STRIP',StripStr);
  959. if not DefFile.Empty {and UseDefFileForExport} then
  960. begin
  961. DefFile.WriteFile;
  962. Replace(cmdstr,'$DEF','-d '+maybequoted(deffile.fname));
  963. end
  964. else
  965. Replace(cmdstr,'$DEF','');
  966. success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,(i=1),false);
  967. if not success then
  968. break;
  969. end;
  970. end;
  971. { Post process }
  972. if success then
  973. success:=PostProcessExecutable(current_module.exefilename^,false);
  974. { Remove ReponseFile }
  975. if (success) and not(cs_link_extern in aktglobalswitches) then
  976. begin
  977. RemoveFile(outputexedir+Info.ResName);
  978. RemoveFile('base.$$$');
  979. RemoveFile('exp.$$$');
  980. RemoveFile('deffile.$$$');
  981. end;
  982. MakeExecutable:=success; { otherwise a recursive call to link method }
  983. end;
  984. Function TLinkerWin32.MakeSharedLibrary:boolean;
  985. var
  986. binstr,
  987. cmdstr : string;
  988. success : boolean;
  989. i : longint;
  990. AsBinStr : string[80];
  991. StripStr,
  992. RelocStr,
  993. AppTypeStr,
  994. ImageBaseStr : string[40];
  995. begin
  996. MakeSharedLibrary:=false;
  997. if not(cs_link_extern in aktglobalswitches) then
  998. Message1(exec_i_linking,current_module.sharedlibfilename^);
  999. { Create some replacements }
  1000. RelocStr:='';
  1001. AppTypeStr:='';
  1002. ImageBaseStr:='';
  1003. StripStr:='';
  1004. AsBinStr:=FindUtil(utilsprefix+'as');
  1005. if RelocSection then
  1006. { Using short form to avoid problems with 128 char limitation under Dos. }
  1007. RelocStr:='-b base.$$$';
  1008. if apptype=app_gui then
  1009. AppTypeStr:='--subsystem windows';
  1010. if assigned(DLLImageBase) then
  1011. ImageBaseStr:='--image-base=0x'+DLLImageBase^;
  1012. if (cs_link_strip in aktglobalswitches) then
  1013. StripStr:='-s';
  1014. { Write used files and libraries }
  1015. WriteResponseFile(true);
  1016. { Call linker }
  1017. success:=false;
  1018. for i:=1 to 3 do
  1019. begin
  1020. SplitBinCmd(Info.DllCmd[i],binstr,cmdstr);
  1021. if binstr<>'' then
  1022. begin
  1023. Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename^));
  1024. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  1025. Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
  1026. Replace(cmdstr,'$APPTYPE',AppTypeStr);
  1027. Replace(cmdstr,'$ASBIN',AsbinStr);
  1028. Replace(cmdstr,'$RELOC',RelocStr);
  1029. Replace(cmdstr,'$IMAGEBASE',ImageBaseStr);
  1030. Replace(cmdstr,'$STRIP',StripStr);
  1031. if not DefFile.Empty {and UseDefFileForExport} then
  1032. begin
  1033. DefFile.WriteFile;
  1034. Replace(cmdstr,'$DEF','-d '+maybequoted(deffile.fname));
  1035. end
  1036. else
  1037. Replace(cmdstr,'$DEF','');
  1038. success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,(i=1),false);
  1039. if not success then
  1040. break;
  1041. end;
  1042. end;
  1043. { Post process }
  1044. if success then
  1045. success:=PostProcessExecutable(current_module.sharedlibfilename^,true);
  1046. { Remove ReponseFile }
  1047. if (success) and not(cs_link_extern in aktglobalswitches) then
  1048. begin
  1049. RemoveFile(outputexedir+Info.ResName);
  1050. RemoveFile('base.$$$');
  1051. RemoveFile('exp.$$$');
  1052. end;
  1053. MakeSharedLibrary:=success; { otherwise a recursive call to link method }
  1054. end;
  1055. function tlinkerwin32.postprocessexecutable(const fn : string;isdll:boolean):boolean;
  1056. type
  1057. tdosheader = packed record
  1058. e_magic : word;
  1059. e_cblp : word;
  1060. e_cp : word;
  1061. e_crlc : word;
  1062. e_cparhdr : word;
  1063. e_minalloc : word;
  1064. e_maxalloc : word;
  1065. e_ss : word;
  1066. e_sp : word;
  1067. e_csum : word;
  1068. e_ip : word;
  1069. e_cs : word;
  1070. e_lfarlc : word;
  1071. e_ovno : word;
  1072. e_res : array[0..3] of word;
  1073. e_oemid : word;
  1074. e_oeminfo : word;
  1075. e_res2 : array[0..9] of word;
  1076. e_lfanew : longint;
  1077. end;
  1078. tpeheader = packed record
  1079. PEMagic : array[0..3] of char;
  1080. Machine : word;
  1081. NumberOfSections : word;
  1082. TimeDateStamp : longint;
  1083. PointerToSymbolTable : longint;
  1084. NumberOfSymbols : longint;
  1085. SizeOfOptionalHeader : word;
  1086. Characteristics : word;
  1087. Magic : word;
  1088. MajorLinkerVersion : byte;
  1089. MinorLinkerVersion : byte;
  1090. SizeOfCode : longint;
  1091. SizeOfInitializedData : longint;
  1092. SizeOfUninitializedData : longint;
  1093. AddressOfEntryPoint : longint;
  1094. BaseOfCode : longint;
  1095. BaseOfData : longint;
  1096. ImageBase : longint;
  1097. SectionAlignment : longint;
  1098. FileAlignment : longint;
  1099. MajorOperatingSystemVersion : word;
  1100. MinorOperatingSystemVersion : word;
  1101. MajorImageVersion : word;
  1102. MinorImageVersion : word;
  1103. MajorSubsystemVersion : word;
  1104. MinorSubsystemVersion : word;
  1105. Reserved1 : longint;
  1106. SizeOfImage : longint;
  1107. SizeOfHeaders : longint;
  1108. CheckSum : longint;
  1109. Subsystem : word;
  1110. DllCharacteristics : word;
  1111. SizeOfStackReserve : longint;
  1112. SizeOfStackCommit : longint;
  1113. SizeOfHeapReserve : longint;
  1114. SizeOfHeapCommit : longint;
  1115. LoaderFlags : longint;
  1116. NumberOfRvaAndSizes : longint;
  1117. DataDirectory : array[1..$80] of byte;
  1118. end;
  1119. tcoffsechdr=packed record
  1120. name : array[0..7] of char;
  1121. vsize : longint;
  1122. rvaofs : longint;
  1123. datalen : longint;
  1124. datapos : longint;
  1125. relocpos : longint;
  1126. lineno1 : longint;
  1127. nrelocs : word;
  1128. lineno2 : word;
  1129. flags : longint;
  1130. end;
  1131. psecfill=^TSecfill;
  1132. TSecfill=record
  1133. fillpos,
  1134. fillsize : longint;
  1135. next : psecfill;
  1136. end;
  1137. var
  1138. f : file;
  1139. cmdstr : string;
  1140. dosheader : tdosheader;
  1141. peheader : tpeheader;
  1142. firstsecpos,
  1143. maxfillsize,
  1144. l,peheaderpos : longint;
  1145. coffsec : tcoffsechdr;
  1146. secroot,hsecroot : psecfill;
  1147. zerobuf : pointer;
  1148. begin
  1149. postprocessexecutable:=false;
  1150. { when -s is used or it's a dll then quit }
  1151. if (cs_link_extern in aktglobalswitches) then
  1152. begin
  1153. case apptype of
  1154. app_gui :
  1155. cmdstr:='--subsystem gui';
  1156. app_cui :
  1157. cmdstr:='--subsystem console';
  1158. end;
  1159. if dllversion<>'' then
  1160. cmdstr:=cmdstr+' --version '+dllversion;
  1161. cmdstr:=cmdstr+' --input '+maybequoted(fn);
  1162. cmdstr:=cmdstr+' --stack '+tostr(stacksize);
  1163. DoExec(FindUtil(utilsprefix+'postw32'),cmdstr,false,false);
  1164. postprocessexecutable:=true;
  1165. exit;
  1166. end;
  1167. { open file }
  1168. assign(f,fn);
  1169. {$I-}
  1170. reset(f,1);
  1171. if ioresult<>0 then
  1172. Message1(execinfo_f_cant_open_executable,fn);
  1173. { read headers }
  1174. blockread(f,dosheader,sizeof(tdosheader));
  1175. peheaderpos:=dosheader.e_lfanew;
  1176. seek(f,peheaderpos);
  1177. blockread(f,peheader,sizeof(tpeheader));
  1178. { write info }
  1179. Message1(execinfo_x_codesize,tostr(peheader.SizeOfCode));
  1180. Message1(execinfo_x_initdatasize,tostr(peheader.SizeOfInitializedData));
  1181. Message1(execinfo_x_uninitdatasize,tostr(peheader.SizeOfUninitializedData));
  1182. { change stack size (PM) }
  1183. { I am not sure that the default value is adequate !! }
  1184. peheader.SizeOfStackReserve:=stacksize;
  1185. { change the header }
  1186. { sub system }
  1187. { gui=2 }
  1188. { cui=3 }
  1189. case apptype of
  1190. app_gui :
  1191. peheader.Subsystem:=2;
  1192. app_cui :
  1193. peheader.Subsystem:=3;
  1194. end;
  1195. if dllversion<>'' then
  1196. begin
  1197. peheader.MajorImageVersion:=dllmajor;
  1198. peheader.MinorImageVersion:=dllminor;
  1199. end;
  1200. { reset timestamp }
  1201. peheader.TimeDateStamp:=0;
  1202. { write header back }
  1203. seek(f,peheaderpos);
  1204. blockwrite(f,peheader,sizeof(tpeheader));
  1205. if ioresult<>0 then
  1206. Message1(execinfo_f_cant_process_executable,fn);
  1207. seek(f,peheaderpos);
  1208. blockread(f,peheader,sizeof(tpeheader));
  1209. { write the value after the change }
  1210. Message1(execinfo_x_stackreserve,tostr(peheader.SizeOfStackReserve));
  1211. Message1(execinfo_x_stackcommit,tostr(peheader.SizeOfStackCommit));
  1212. { read section info }
  1213. maxfillsize:=0;
  1214. firstsecpos:=0;
  1215. secroot:=nil;
  1216. for l:=1 to peheader.NumberOfSections do
  1217. begin
  1218. blockread(f,coffsec,sizeof(tcoffsechdr));
  1219. if coffsec.datapos>0 then
  1220. begin
  1221. if secroot=nil then
  1222. firstsecpos:=coffsec.datapos;
  1223. new(hsecroot);
  1224. hsecroot^.fillpos:=coffsec.datapos+coffsec.vsize;
  1225. hsecroot^.fillsize:=coffsec.datalen-coffsec.vsize;
  1226. hsecroot^.next:=secroot;
  1227. secroot:=hsecroot;
  1228. if secroot^.fillsize>maxfillsize then
  1229. maxfillsize:=secroot^.fillsize;
  1230. end;
  1231. end;
  1232. if firstsecpos>0 then
  1233. begin
  1234. l:=firstsecpos-filepos(f);
  1235. if l>maxfillsize then
  1236. maxfillsize:=l;
  1237. end
  1238. else
  1239. l:=0;
  1240. { get zero buffer }
  1241. getmem(zerobuf,maxfillsize);
  1242. fillchar(zerobuf^,maxfillsize,0);
  1243. { zero from sectioninfo until first section }
  1244. blockwrite(f,zerobuf^,l);
  1245. { zero section alignments }
  1246. while assigned(secroot) do
  1247. begin
  1248. seek(f,secroot^.fillpos);
  1249. blockwrite(f,zerobuf^,secroot^.fillsize);
  1250. hsecroot:=secroot;
  1251. secroot:=secroot^.next;
  1252. dispose(hsecroot);
  1253. end;
  1254. freemem(zerobuf,maxfillsize);
  1255. close(f);
  1256. {$I+}
  1257. if ioresult<>0 then;
  1258. postprocessexecutable:=true;
  1259. end;
  1260. {****************************************************************************
  1261. TDLLScannerWin32
  1262. ****************************************************************************}
  1263. procedure tDLLScannerWin32.GetDefExt(var N:longint;var P:pStr4);
  1264. begin
  1265. N:=sizeof(DefaultDLLExtensions)div sizeof(DefaultDLLExtensions[1]);
  1266. pointer(P):=@DefaultDLLExtensions;
  1267. end;
  1268. function tDLLScannerWin32.DOSstubOK(var x:cardinal):boolean;
  1269. begin
  1270. blockread(f,TheWord,2,loaded);
  1271. if loaded<>2 then
  1272. DOSstubOK:=false
  1273. else
  1274. begin
  1275. DOSstubOK:=(TheWord='MZ');
  1276. seek(f,$3C);
  1277. blockread(f,x,4,loaded);
  1278. if(loaded<>4)or(longint(x)>filesize(f))then
  1279. DOSstubOK:=false;
  1280. end;
  1281. end;
  1282. function TDLLScannerWin32.FindDLL(const s:string;var founddll:string):boolean;
  1283. var
  1284. sysdir : string;
  1285. Found : boolean;
  1286. begin
  1287. Found:=false;
  1288. { Look for DLL in:
  1289. 1. Current dir
  1290. 2. Library Path
  1291. 3. windir,windir/system,windir/system32 }
  1292. Found:=FindFile(s,'.'+source_info.DirSep,founddll);
  1293. if (not found) then
  1294. Found:=librarysearchpath.FindFile(s,founddll);
  1295. if (not found) then
  1296. begin
  1297. sysdir:=FixPath(GetEnv('windir'),false);
  1298. Found:=FindFile(s,sysdir+';'+sysdir+'system'+source_info.DirSep+';'+sysdir+'system32'+source_info.DirSep,founddll);
  1299. end;
  1300. if (not found) then
  1301. begin
  1302. message1(exec_w_libfile_not_found,s);
  1303. FoundDll:=s;
  1304. end;
  1305. FindDll:=Found;
  1306. end;
  1307. function tDLLScannerWin32.ExtractDllName(Const Name : string) : string;
  1308. var n : string;
  1309. begin
  1310. n:=Upper(SplitExtension(Name));
  1311. if (n='.DLL') or (n='.DRV') or (n='.EXE') then
  1312. ExtractDllName:=Name
  1313. else
  1314. ExtractDllName:=Name+target_info.sharedlibext;
  1315. end;
  1316. function tDLLScannerWin32.isSuitableFileType(x:cardinal):longbool;
  1317. begin
  1318. seek(f,x);
  1319. blockread(f,TheWord,2,loaded);
  1320. isSuitableFileType:=(loaded=2)and(TheWord='PE');
  1321. end;
  1322. function tDLLScannerWin32.GetEdata(HeaderEntry:cardinal):longbool;
  1323. type
  1324. TObjInfo=packed record
  1325. ObjName:array[0..7]of char;
  1326. VirtSize,
  1327. VirtAddr,
  1328. RawSize,
  1329. RawOffset,
  1330. Reloc,
  1331. LineNum:cardinal;
  1332. RelCount,
  1333. LineCount:word;
  1334. flags:cardinal;
  1335. end;
  1336. var
  1337. i:cardinal;
  1338. ObjOfs:cardinal;
  1339. Obj:TObjInfo;
  1340. APE_obj,APE_Optsize:word;
  1341. ExportRVA:cardinal;
  1342. delta:cardinal;
  1343. const
  1344. IMAGE_SCN_CNT_CODE=$00000020;
  1345. var
  1346. _d:dirstr;
  1347. _n:namestr;
  1348. _e:extstr;
  1349. function isUsedFunction(name:pchar):longbool;
  1350. var
  1351. hp:tExternalsItem;
  1352. begin
  1353. isUsedFunction:=false;
  1354. hp:=tExternalsItem(current_module.Externals.first);
  1355. while assigned(hp)do
  1356. begin
  1357. if(assigned(hp.data))and(not hp.found)then
  1358. if hp.data^=StrPas(name)then
  1359. begin
  1360. isUsedFunction:=true;
  1361. hp.found:=true;
  1362. exit;
  1363. end;
  1364. hp:=tExternalsItem(hp.next);
  1365. end;
  1366. end;
  1367. procedure Store(index:cardinal;name:pchar;isData:longbool);
  1368. begin
  1369. if not isUsedFunction(name)then
  1370. exit;
  1371. if not(current_module.uses_imports) then
  1372. begin
  1373. current_module.uses_imports:=true;
  1374. importlib.preparelib(current_module.modulename^);
  1375. end;
  1376. if IsData then
  1377. timportlibwin32(importlib).importvariable_str(name,_n,name)
  1378. else
  1379. timportlibwin32(importlib).importprocedure_str(name,_n,index,name);
  1380. end;
  1381. procedure ProcessEdata;
  1382. type
  1383. a8=array[0..7]of char;
  1384. function GetSectionName(rva:cardinal;var Flags:cardinal):a8;
  1385. var
  1386. i:cardinal;
  1387. LocObjOfs:cardinal;
  1388. LocObj:TObjInfo;
  1389. begin
  1390. GetSectionName:='';
  1391. Flags:=0;
  1392. LocObjOfs:=APE_OptSize+HeaderOffset+24;
  1393. for i:=1 to APE_obj do
  1394. begin
  1395. seek(f,LocObjOfs);
  1396. blockread(f,LocObj,sizeof(LocObj));
  1397. if(rva>=LocObj.VirtAddr)and(rva<=LocObj.VirtAddr+LocObj.RawSize)then
  1398. begin
  1399. GetSectionName:=a8(LocObj.ObjName);
  1400. Flags:=LocObj.flags;
  1401. end;
  1402. end;
  1403. end;
  1404. var
  1405. j,Fl:cardinal;
  1406. ulongval,procEntry:cardinal;
  1407. Ordinal:word;
  1408. isData:longbool;
  1409. ExpDir:packed record
  1410. flag,
  1411. stamp:cardinal;
  1412. Major,
  1413. Minor:word;
  1414. Name,
  1415. Base,
  1416. NumFuncs,
  1417. NumNames,
  1418. AddrFuncs,
  1419. AddrNames,
  1420. AddrOrds:cardinal;
  1421. end;
  1422. begin
  1423. with Obj do
  1424. begin
  1425. seek(f,RawOffset+delta);
  1426. blockread(f,ExpDir,sizeof(ExpDir));
  1427. fsplit(impname,_d,_n,_e);
  1428. for j:=0 to pred(ExpDir.NumNames)do
  1429. begin
  1430. { Don't know why but this gives serious problems with overflow checking on }
  1431. {$IFOPT Q+}
  1432. {$DEFINE OVERFLOW_CHECK_WAS_ON}
  1433. {$ENDIF}
  1434. {$Q-}
  1435. seek(f,RawOffset-VirtAddr+ExpDir.AddrOrds+j*2);
  1436. blockread(f,Ordinal,2);
  1437. seek(f,RawOffset-VirtAddr+ExpDir.AddrFuncs+cardinal(Ordinal)*4);
  1438. blockread(f,ProcEntry,4);
  1439. seek(f,RawOffset-VirtAddr+ExpDir.AddrNames+j*4);
  1440. blockread(f,ulongval,4);
  1441. seek(f,RawOffset-VirtAddr+ulongval);
  1442. blockread(f,cstring,sizeof(cstring));
  1443. isData:=GetSectionName(procentry,Fl)='';
  1444. {$IFDEF OVERFLOW_CHECK_WAS_ON}
  1445. {$Q+}
  1446. {$ENDIF}
  1447. if not isData then
  1448. isData:=Fl and IMAGE_SCN_CNT_CODE<>IMAGE_SCN_CNT_CODE;
  1449. Store(succ(Ordinal),cstring,isData);
  1450. end;
  1451. end;
  1452. end;
  1453. begin
  1454. GetEdata:=false;
  1455. seek(f,HeaderEntry+120);
  1456. blockread(f,ExportRVA,4);
  1457. seek(f,HeaderEntry+6);
  1458. blockread(f,APE_Obj,2);
  1459. seek(f,HeaderEntry+20);
  1460. blockread(f,APE_OptSize,2);
  1461. ObjOfs:=APE_OptSize+HeaderOffset+24;
  1462. for i:=1 to APE_obj do
  1463. begin
  1464. seek(f,ObjOfs);
  1465. blockread(f,Obj,sizeof(Obj));
  1466. inc(ObjOfs,sizeof(Obj));
  1467. with Obj do
  1468. if(VirtAddr<=ExportRva)and(ExportRva<VirtAddr+VirtSize)then
  1469. begin
  1470. delta:=ExportRva-VirtAddr;
  1471. ProcessEdata;
  1472. GetEdata:=true;
  1473. end;
  1474. end;
  1475. end;
  1476. function tDLLScannerWin32.scan(const binname:string):longbool;
  1477. var
  1478. OldFileMode:longint;
  1479. foundimp : string;
  1480. NN:longint;PP:pStr4;
  1481. begin
  1482. Scan:=false;
  1483. { is there already an import library the we will use that one }
  1484. if FindLibraryFile(binname,target_info.staticClibprefix,target_info.staticClibext,foundimp) then
  1485. exit;
  1486. { check if we can find the dll }
  1487. GetDefExt(NN,PP);
  1488. if not FindDll(DLLName(binname,NN,PP),impname) then
  1489. exit;
  1490. { read the dll file }
  1491. assign(f,impname);
  1492. OldFileMode:=filemode;
  1493. filemode:=0;
  1494. reset(f,1);
  1495. filemode:=OldFileMode;
  1496. if not DOSstubOK(HeaderOffset)then
  1497. scan:=false
  1498. else if not isSuitableFileType(HeaderOffset)then
  1499. scan:=false
  1500. else
  1501. scan:=GetEdata(HeaderOffset);
  1502. close(f);
  1503. end;
  1504. {*****************************************************************************
  1505. Initialize
  1506. *****************************************************************************}
  1507. initialization
  1508. {$ifdef i386}
  1509. RegisterExternalLinker(system_i386_win32_info,TLinkerWin32);
  1510. RegisterImport(system_i386_win32,TImportLibWin32);
  1511. RegisterExport(system_i386_win32,TExportLibWin32);
  1512. RegisterDLLScanner(system_i386_win32,TDLLScannerWin32);
  1513. RegisterRes(res_gnu_windres_info);
  1514. RegisterTarget(system_i386_win32_info);
  1515. {$endif i386}
  1516. end.
  1517. {
  1518. $Log$
  1519. Revision 1.26 2004-01-09 13:36:26 daniel
  1520. * Export table generation fixed according to instructions from Pierre
  1521. Revision 1.25 2003/12/09 19:54:59 marco
  1522. * base-file instead of base_file
  1523. Revision 1.24 2003/12/08 22:37:04 peter
  1524. * base_file instead of b
  1525. Revision 1.23 2003/10/10 17:48:14 peter
  1526. * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
  1527. * tregisteralloctor renamed to trgobj
  1528. * removed rgobj from a lot of units
  1529. * moved location_* and reference_* to cgobj
  1530. * first things for mmx register allocation
  1531. Revision 1.22 2003/10/09 16:14:49 peter
  1532. * fix check for generatenasmlib
  1533. Revision 1.21 2003/10/03 14:16:48 marco
  1534. * -XP<prefix> support
  1535. Revision 1.20 2003/10/02 21:17:08 peter
  1536. * use as,ld,ar instead of asw,ldw,arw for win32
  1537. Revision 1.19 2003/09/30 20:10:12 peter
  1538. * smartlink fix for dlls from Pavel
  1539. Revision 1.18 2003/08/21 14:47:41 peter
  1540. * remove convert_registers
  1541. Revision 1.17 2003/08/20 20:50:18 daniel
  1542. * convert_registers call removed from t_win32.pas
  1543. Revision 1.16 2003/05/13 15:15:25 peter
  1544. * fixed import crash with explicit provided name
  1545. Revision 1.15 2003/04/27 09:14:48 florian
  1546. * aprocdef instead of aktprocdef must be used
  1547. Revision 1.14 2003/04/27 07:29:52 peter
  1548. * aktprocdef cleanup, aktprocdef is now always nil when parsing
  1549. a new procdef declaration
  1550. * aktprocsym removed
  1551. * lexlevel removed, use symtable.symtablelevel instead
  1552. * implicit init/final code uses the normal genentry/genexit
  1553. * funcret state checking updated for new funcret handling
  1554. Revision 1.13 2003/04/26 09:16:08 peter
  1555. * .o files belonging to the unit are first searched in the same dir
  1556. as the .ppu
  1557. Revision 1.12 2003/04/12 15:43:40 peter
  1558. * convert registers for importssection
  1559. Revision 1.11 2003/01/06 20:19:52 peter
  1560. * use findutil
  1561. Revision 1.10 2003/01/05 13:36:53 florian
  1562. * x86-64 compiles
  1563. + very basic support for float128 type (x86-64 only)
  1564. Revision 1.9 2002/12/24 15:55:51 peter
  1565. * Use maybequote instead of getshortname
  1566. Revision 1.8 2002/12/01 18:57:34 carl
  1567. * disable overflow checking in some parts to avoid problems
  1568. Revision 1.7 2002/11/30 18:45:28 carl
  1569. + profiling support for Win32
  1570. Revision 1.6 2002/11/16 18:40:38 carl
  1571. - remove my last stupid commit (Thanks, Peter!)
  1572. Revision 1.5 2002/11/16 14:46:50 carl
  1573. * don't add debug information in not in debug mode
  1574. Revision 1.4 2002/11/15 01:59:02 peter
  1575. * merged changes from 1.0.7 up to 04-11
  1576. - -V option for generating bug report tracing
  1577. - more tracing for option parsing
  1578. - errors for cdecl and high()
  1579. - win32 import stabs
  1580. - win32 records<=8 are returned in eax:edx (turned off by default)
  1581. - heaptrc update
  1582. - more info for temp management in .s file with EXTDEBUG
  1583. Revision 1.3 2002/10/05 12:43:29 carl
  1584. * fixes for Delphi 6 compilation
  1585. (warning : Some features do not work under Delphi)
  1586. Revision 1.2 2002/09/09 17:34:17 peter
  1587. * tdicationary.replace added to replace and item in a dictionary. This
  1588. is only allowed for the same name
  1589. * varsyms are inserted in symtable before the types are parsed. This
  1590. fixes the long standing "var longint : longint" bug
  1591. - consume_idlist and idstringlist removed. The loops are inserted
  1592. at the callers place and uses the symtable for duplicate id checking
  1593. Revision 1.1 2002/09/06 15:03:50 carl
  1594. * moved files to systems directory
  1595. Revision 1.40 2002/09/03 16:26:29 daniel
  1596. * Make Tprocdef.defs protected
  1597. Revision 1.39 2002/08/12 15:08:44 carl
  1598. + stab register indexes for powerpc (moved from gdb to cpubase)
  1599. + tprocessor enumeration moved to cpuinfo
  1600. + linker in target_info is now a class
  1601. * many many updates for m68k (will soon start to compile)
  1602. - removed some ifdef or correct them for correct cpu
  1603. Revision 1.38 2002/08/11 14:32:32 peter
  1604. * renamed current_library to objectlibrary
  1605. Revision 1.37 2002/08/11 13:24:20 peter
  1606. * saving of asmsymbols in ppu supported
  1607. * asmsymbollist global is removed and moved into a new class
  1608. tasmlibrarydata that will hold the info of a .a file which
  1609. corresponds with a single module. Added librarydata to tmodule
  1610. to keep the library info stored for the module. In the future the
  1611. objectfiles will also be stored to the tasmlibrarydata class
  1612. * all getlabel/newasmsymbol and friends are moved to the new class
  1613. Revision 1.36 2002/07/26 21:15:46 florian
  1614. * rewrote the system handling
  1615. Revision 1.35 2002/07/01 18:46:35 peter
  1616. * internal linker
  1617. * reorganized aasm layer
  1618. Revision 1.34 2002/05/18 13:34:27 peter
  1619. * readded missing revisions
  1620. Revision 1.33 2002/05/16 19:46:53 carl
  1621. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1622. + try to fix temp allocation (still in ifdef)
  1623. + generic constructor calls
  1624. + start of tassembler / tmodulebase class cleanup
  1625. Revision 1.31 2002/04/22 18:19:22 carl
  1626. - remove use_bound_instruction field
  1627. Revision 1.30 2002/04/21 15:43:58 carl
  1628. * change stack size to 256K
  1629. Revision 1.29 2002/04/20 21:43:18 carl
  1630. * fix stack size for some targets
  1631. + add offset to parameters from frame pointer info.
  1632. - remove some unused stuff
  1633. Revision 1.28 2002/04/15 19:16:57 carl
  1634. - remove size_of_pointer field
  1635. Revision 1.27 2002/04/05 17:49:09 carl
  1636. * fix compilation problems
  1637. * fix range check error
  1638. Revision 1.26 2002/04/04 19:06:14 peter
  1639. * removed unused units
  1640. * use tlocation.size in cg.a_*loc*() routines
  1641. Revision 1.25 2002/04/04 18:25:30 carl
  1642. + added wdosx patch from Pavel
  1643. Revision 1.24 2002/04/02 17:11:39 peter
  1644. * tlocation,treference update
  1645. * LOC_CONSTANT added for better constant handling
  1646. * secondadd splitted in multiple routines
  1647. * location_force_reg added for loading a location to a register
  1648. of a specified size
  1649. * secondassignment parses now first the right and then the left node
  1650. (this is compatible with Kylix). This saves a lot of push/pop especially
  1651. with string operations
  1652. * adapted some routines to use the new cg methods
  1653. Revision 1.23 2002/01/29 21:27:34 peter
  1654. * default alignment changed to 4 bytes for locals and static const,var
  1655. Revision 1.22 2002/01/19 11:53:07 peter
  1656. * fixed managledname
  1657. }