t_win32.pas 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788
  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. end;
  581. procedure texportlibwin32.generatelib;
  582. var
  583. ordinal_base,ordinal_max,ordinal_min : longint;
  584. current_index : longint;
  585. entries,named_entries : longint;
  586. name_label,dll_name_label,export_address_table : tasmlabel;
  587. export_name_table_pointers,export_ordinal_table : tasmlabel;
  588. hp,hp2 : texported_item;
  589. temtexport : TLinkedList;
  590. address_table,name_table_pointers,
  591. name_table,ordinal_table : TAAsmoutput;
  592. begin
  593. if (aktoutputformat in [as_i386_masm,as_i386_tasm,as_i386_nasmwin32]) then
  594. begin
  595. generatenasmlib;
  596. exit;
  597. end;
  598. hp:=texported_item(current_module._exports.first);
  599. if not assigned(hp) then
  600. exit;
  601. ordinal_max:=0;
  602. ordinal_min:=$7FFFFFFF;
  603. entries:=0;
  604. named_entries:=0;
  605. objectlibrary.getlabel(dll_name_label);
  606. objectlibrary.getlabel(export_address_table);
  607. objectlibrary.getlabel(export_name_table_pointers);
  608. objectlibrary.getlabel(export_ordinal_table);
  609. { count entries }
  610. while assigned(hp) do
  611. begin
  612. inc(entries);
  613. if (hp.index>ordinal_max) then
  614. ordinal_max:=hp.index;
  615. if (hp.index>0) and (hp.index<ordinal_min) then
  616. ordinal_min:=hp.index;
  617. if assigned(hp.name) then
  618. inc(named_entries);
  619. hp:=texported_item(hp.next);
  620. end;
  621. { no support for higher ordinal base yet !! }
  622. ordinal_base:=1;
  623. current_index:=ordinal_base;
  624. { we must also count the holes !! }
  625. entries:=ordinal_max-ordinal_base+1;
  626. exportsSection.concat(Tai_section.Create(sec_edata));
  627. { create label to reference from main so smartlink will include
  628. the .edata section }
  629. exportsSection.concat(Tai_symbol.Create_global(edatalabel,0));
  630. { export flags }
  631. exportsSection.concat(Tai_const.Create_32bit(0));
  632. { date/time stamp }
  633. exportsSection.concat(Tai_const.Create_32bit(0));
  634. { major version }
  635. exportsSection.concat(Tai_const.Create_16bit(0));
  636. { minor version }
  637. exportsSection.concat(Tai_const.Create_16bit(0));
  638. { pointer to dll name }
  639. exportsSection.concat(Tai_const_symbol.Create_rva(dll_name_label));
  640. { ordinal base normally set to 1 }
  641. exportsSection.concat(Tai_const.Create_32bit(ordinal_base));
  642. { number of entries }
  643. exportsSection.concat(Tai_const.Create_32bit(entries));
  644. { number of named entries }
  645. exportsSection.concat(Tai_const.Create_32bit(named_entries));
  646. { address of export address table }
  647. exportsSection.concat(Tai_const_symbol.Create_rva(export_address_table));
  648. { address of name pointer pointers }
  649. exportsSection.concat(Tai_const_symbol.Create_rva(export_name_table_pointers));
  650. { address of ordinal number pointers }
  651. exportsSection.concat(Tai_const_symbol.Create_rva(export_ordinal_table));
  652. { the name }
  653. exportsSection.concat(Tai_label.Create(dll_name_label));
  654. if st='' then
  655. exportsSection.concat(Tai_string.Create(current_module.modulename^+target_info.sharedlibext+#0))
  656. else
  657. exportsSection.concat(Tai_string.Create(st+target_info.sharedlibext+#0));
  658. { export address table }
  659. address_table:=TAAsmoutput.create;
  660. address_table.concat(Tai_align.Create_op(4,0));
  661. address_table.concat(Tai_label.Create(export_address_table));
  662. name_table_pointers:=TAAsmoutput.create;
  663. name_table_pointers.concat(Tai_align.Create_op(4,0));
  664. name_table_pointers.concat(Tai_label.Create(export_name_table_pointers));
  665. ordinal_table:=TAAsmoutput.create;
  666. ordinal_table.concat(Tai_align.Create_op(4,0));
  667. ordinal_table.concat(Tai_label.Create(export_ordinal_table));
  668. name_table:=TAAsmoutput.Create;
  669. name_table.concat(Tai_align.Create_op(4,0));
  670. { write each address }
  671. hp:=texported_item(current_module._exports.first);
  672. while assigned(hp) do
  673. begin
  674. if (hp.options and eo_name)<>0 then
  675. begin
  676. objectlibrary.getlabel(name_label);
  677. name_table_pointers.concat(Tai_const_symbol.Create_rva(name_label));
  678. ordinal_table.concat(Tai_const.Create_16bit(hp.index-ordinal_base));
  679. name_table.concat(Tai_align.Create_op(2,0));
  680. name_table.concat(Tai_label.Create(name_label));
  681. name_table.concat(Tai_string.Create(hp.name^+#0));
  682. end;
  683. hp:=texported_item(hp.next);
  684. end;
  685. { order in increasing ordinal values }
  686. { into temtexport list }
  687. temtexport:=TLinkedList.Create;
  688. hp:=texported_item(current_module._exports.first);
  689. while assigned(hp) do
  690. begin
  691. current_module._exports.remove(hp);
  692. hp2:=texported_item(temtexport.first);
  693. while assigned(hp2) and (hp.index>hp2.index) do
  694. hp2:=texported_item(hp2.next);
  695. if hp2=nil then
  696. temtexport.concat(hp)
  697. else
  698. temtexport.insertbefore(hp,hp2);
  699. hp:=texported_item(current_module._exports.first);;
  700. end;
  701. { write the export adress table }
  702. current_index:=ordinal_base;
  703. hp:=texported_item(temtexport.first);
  704. while assigned(hp) do
  705. begin
  706. { fill missing values }
  707. while current_index<hp.index do
  708. begin
  709. address_table.concat(Tai_const.Create_32bit(0));
  710. inc(current_index);
  711. end;
  712. case hp.sym.typ of
  713. varsym :
  714. address_table.concat(Tai_const_symbol.Createname_rva(tvarsym(hp.sym).mangledname));
  715. typedconstsym :
  716. address_table.concat(Tai_const_symbol.Createname_rva(ttypedconstsym(hp.sym).mangledname));
  717. procsym :
  718. address_table.concat(Tai_const_symbol.Createname_rva(tprocsym(hp.sym).first_procdef.mangledname));
  719. end;
  720. inc(current_index);
  721. hp:=texported_item(hp.next);
  722. end;
  723. exportsSection.concatlist(address_table);
  724. exportsSection.concatlist(name_table_pointers);
  725. exportsSection.concatlist(ordinal_table);
  726. exportsSection.concatlist(name_table);
  727. address_table.Free;
  728. name_table_pointers.free;
  729. ordinal_table.free;
  730. name_table.free;
  731. temtexport.free;
  732. end;
  733. procedure texportlibwin32.generatenasmlib;
  734. var
  735. hp : texported_item;
  736. p : pchar;
  737. s : string;
  738. begin
  739. exportssection.concat(tai_section.create(sec_code));
  740. hp:=texported_item(current_module._exports.first);
  741. while assigned(hp) do
  742. begin
  743. case hp.sym.typ of
  744. varsym :
  745. s:=tvarsym(hp.sym).mangledname;
  746. typedconstsym :
  747. s:=ttypedconstsym(hp.sym).mangledname;
  748. procsym :
  749. s:=tprocsym(hp.sym).first_procdef.mangledname;
  750. else
  751. s:='';
  752. end;
  753. p:=strpnew(#9+'export '+s+' '+hp.name^+' '+tostr(hp.index));
  754. exportssection.concat(tai_direct.create(p));
  755. hp:=texported_item(hp.next);
  756. end;
  757. end;
  758. {****************************************************************************
  759. TLINKERWIN32
  760. ****************************************************************************}
  761. Constructor TLinkerWin32.Create;
  762. begin
  763. Inherited Create;
  764. { allow duplicated libs (PM) }
  765. SharedLibFiles.doubles:=true;
  766. StaticLibFiles.doubles:=true;
  767. If not ForceDeffileForExport then
  768. UseDeffileForExport:=false;
  769. end;
  770. Procedure TLinkerWin32.SetDefaultInfo;
  771. begin
  772. with Info do
  773. begin
  774. ExeCmd[1]:='ld $OPT $STRIP $APPTYPE $IMAGEBASE $RELOC -o $EXE $RES';
  775. DllCmd[1]:='ld $OPT $STRIP --dll $APPTYPE $IMAGEBASE $RELOC -o $EXE $RES';
  776. if RelocSection or UseDeffileForExport then
  777. begin
  778. { ExeCmd[2]:='dlltool --as $ASBIN --dllname $EXE --output-exp exp.$$$ $RELOC $DEF';
  779. use short forms to avoid 128 char limitation problem }
  780. ExeCmd[2]:='dlltool -S $ASBIN -D $EXE -e exp.$$$ $RELOC $DEF';
  781. ExeCmd[3]:='ld $OPT $STRIP $APPTYPE $IMAGEBASE -o $EXE $RES exp.$$$';
  782. { DllCmd[2]:='dlltool --as $ASBIN --dllname $EXE --output-exp exp.$$$ $RELOC $DEF'; }
  783. DllCmd[2]:='dlltool -S $ASBIN -D $EXE -e exp.$$$ $RELOC $DEF';
  784. DllCmd[3]:='ld $OPT $STRIP --dll $APPTYPE $IMAGEBASE -o $EXE $RES exp.$$$';
  785. end;
  786. end;
  787. end;
  788. Function TLinkerWin32.WriteResponseFile(isdll:boolean) : Boolean;
  789. Var
  790. linkres : TLinkRes;
  791. HPath : TStringListItem;
  792. s,s2 : string;
  793. i : integer;
  794. linklibc : boolean;
  795. begin
  796. WriteResponseFile:=False;
  797. linklibc:=false;
  798. { Open link.res file }
  799. LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
  800. { Write path to search libraries }
  801. HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
  802. while assigned(HPath) do
  803. begin
  804. LinkRes.Add('SEARCH_DIR('+MaybeQuoted(HPath.Str)+')');
  805. HPath:=TStringListItem(HPath.Next);
  806. end;
  807. HPath:=TStringListItem(LibrarySearchPath.First);
  808. while assigned(HPath) do
  809. begin
  810. LinkRes.Add('SEARCH_DIR('+MaybeQuoted(HPath.Str)+')');
  811. HPath:=TStringListItem(HPath.Next);
  812. end;
  813. { add objectfiles, start with prt0 always }
  814. { profiling of shared libraries is currently not supported }
  815. LinkRes.Add('INPUT(');
  816. if isdll then
  817. LinkRes.AddFileName(MaybeQuoted(FindObjectFile('wdllprt0','',false)))
  818. else
  819. if (cs_profile in aktmoduleswitches) then
  820. LinkRes.AddFileName(MaybeQuoted(FindObjectFile('gprt0','',false)))
  821. else
  822. LinkRes.AddFileName(MaybeQuoted(FindObjectFile('wprt0','',false)));
  823. while not ObjectFiles.Empty do
  824. begin
  825. s:=ObjectFiles.GetFirst;
  826. if s<>'' then
  827. LinkRes.AddFileName(MaybeQuoted(s));
  828. end;
  829. LinkRes.Add(')');
  830. { Write staticlibraries }
  831. if (not StaticLibFiles.Empty) or (cs_profile in aktmoduleswitches) then
  832. begin
  833. LinkRes.Add('GROUP(');
  834. if (cs_profile in aktmoduleswitches) then
  835. begin
  836. LinkRes.Add('-lgcc');
  837. LinkRes.Add('-lmoldname');
  838. LinkRes.Add('-lmsvcrt');
  839. LinkRes.Add('-lgmon');
  840. LinkRes.Add('-lkernel32');
  841. end;
  842. While not StaticLibFiles.Empty do
  843. begin
  844. S:=StaticLibFiles.GetFirst;
  845. LinkRes.AddFileName(MaybeQuoted(s));
  846. end;
  847. LinkRes.Add(')');
  848. end;
  849. { Write sharedlibraries }
  850. if not SharedLibFiles.Empty then
  851. begin
  852. LinkRes.Add('INPUT(') ;
  853. While not SharedLibFiles.Empty do
  854. begin
  855. S:=SharedLibFiles.GetFirst;
  856. if FindLibraryFile(s,target_info.staticClibprefix,target_info.staticClibext,s2) then
  857. begin
  858. LinkRes.Add(MaybeQuoted(s2));
  859. continue;
  860. end;
  861. if pos(target_info.sharedlibprefix,s)=1 then
  862. s:=copy(s,length(target_info.sharedlibprefix)+1,255);
  863. if s<>'c' then
  864. begin
  865. i:=Pos(target_info.sharedlibext,S);
  866. if i>0 then
  867. Delete(S,i,255);
  868. LinkRes.Add('-l'+s);
  869. end
  870. else
  871. begin
  872. LinkRes.Add('-l'+s);
  873. linklibc:=true;
  874. end;
  875. end;
  876. { be sure that libc is the last lib }
  877. if linklibc then
  878. LinkRes.Add('-lc');
  879. LinkRes.Add(')');
  880. end;
  881. { Write and Close response }
  882. linkres.writetodisk;
  883. LinkRes.Free;
  884. WriteResponseFile:=True;
  885. end;
  886. function TLinkerWin32.MakeExecutable:boolean;
  887. var
  888. binstr,
  889. cmdstr : string;
  890. success : boolean;
  891. i : longint;
  892. AsBinStr : string[80];
  893. StripStr,
  894. RelocStr,
  895. AppTypeStr,
  896. ImageBaseStr : string[40];
  897. begin
  898. if not(cs_link_extern in aktglobalswitches) then
  899. Message1(exec_i_linking,current_module.exefilename^);
  900. { Create some replacements }
  901. RelocStr:='';
  902. AppTypeStr:='';
  903. ImageBaseStr:='';
  904. StripStr:='';
  905. AsBinStr:=FindUtil(utilsprefix+'as');
  906. if RelocSection then
  907. { Using short form to avoid problems with 128 char limitation under Dos. }
  908. RelocStr:='--base-file base.$$$';
  909. if apptype=app_gui then
  910. AppTypeStr:='--subsystem windows';
  911. if assigned(DLLImageBase) then
  912. ImageBaseStr:='--image-base=0x'+DLLImageBase^;
  913. if (cs_link_strip in aktglobalswitches) then
  914. StripStr:='-s';
  915. { Write used files and libraries }
  916. WriteResponseFile(false);
  917. { Call linker }
  918. success:=false;
  919. for i:=1 to 3 do
  920. begin
  921. SplitBinCmd(Info.ExeCmd[i],binstr,cmdstr);
  922. if binstr<>'' then
  923. begin
  924. Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
  925. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  926. Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
  927. Replace(cmdstr,'$APPTYPE',AppTypeStr);
  928. Replace(cmdstr,'$ASBIN',AsbinStr);
  929. Replace(cmdstr,'$RELOC',RelocStr);
  930. Replace(cmdstr,'$IMAGEBASE',ImageBaseStr);
  931. Replace(cmdstr,'$STRIP',StripStr);
  932. if not DefFile.Empty {and UseDefFileForExport} then
  933. begin
  934. DefFile.WriteFile;
  935. Replace(cmdstr,'$DEF','-d '+maybequoted(deffile.fname));
  936. end
  937. else
  938. Replace(cmdstr,'$DEF','');
  939. success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,(i=1),false);
  940. if not success then
  941. break;
  942. end;
  943. end;
  944. { Post process }
  945. if success then
  946. success:=PostProcessExecutable(current_module.exefilename^,false);
  947. { Remove ReponseFile }
  948. if (success) and not(cs_link_extern in aktglobalswitches) then
  949. begin
  950. RemoveFile(outputexedir+Info.ResName);
  951. RemoveFile('base.$$$');
  952. RemoveFile('exp.$$$');
  953. RemoveFile('deffile.$$$');
  954. end;
  955. MakeExecutable:=success; { otherwise a recursive call to link method }
  956. end;
  957. Function TLinkerWin32.MakeSharedLibrary:boolean;
  958. var
  959. binstr,
  960. cmdstr : string;
  961. success : boolean;
  962. i : longint;
  963. AsBinStr : string[80];
  964. StripStr,
  965. RelocStr,
  966. AppTypeStr,
  967. ImageBaseStr : string[40];
  968. begin
  969. MakeSharedLibrary:=false;
  970. if not(cs_link_extern in aktglobalswitches) then
  971. Message1(exec_i_linking,current_module.sharedlibfilename^);
  972. { Create some replacements }
  973. RelocStr:='';
  974. AppTypeStr:='';
  975. ImageBaseStr:='';
  976. StripStr:='';
  977. AsBinStr:=FindUtil(utilsprefix+'as');
  978. if RelocSection then
  979. { Using short form to avoid problems with 128 char limitation under Dos. }
  980. RelocStr:='-b base.$$$';
  981. if apptype=app_gui then
  982. AppTypeStr:='--subsystem windows';
  983. if assigned(DLLImageBase) then
  984. ImageBaseStr:='--image-base=0x'+DLLImageBase^;
  985. if (cs_link_strip in aktglobalswitches) then
  986. StripStr:='-s';
  987. { Write used files and libraries }
  988. WriteResponseFile(true);
  989. { Call linker }
  990. success:=false;
  991. for i:=1 to 3 do
  992. begin
  993. SplitBinCmd(Info.DllCmd[i],binstr,cmdstr);
  994. if binstr<>'' then
  995. begin
  996. Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename^));
  997. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  998. Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
  999. Replace(cmdstr,'$APPTYPE',AppTypeStr);
  1000. Replace(cmdstr,'$ASBIN',AsbinStr);
  1001. Replace(cmdstr,'$RELOC',RelocStr);
  1002. Replace(cmdstr,'$IMAGEBASE',ImageBaseStr);
  1003. Replace(cmdstr,'$STRIP',StripStr);
  1004. if not DefFile.Empty {and UseDefFileForExport} then
  1005. begin
  1006. DefFile.WriteFile;
  1007. Replace(cmdstr,'$DEF','-d '+maybequoted(deffile.fname));
  1008. end
  1009. else
  1010. Replace(cmdstr,'$DEF','');
  1011. success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,(i=1),false);
  1012. if not success then
  1013. break;
  1014. end;
  1015. end;
  1016. { Post process }
  1017. if success then
  1018. success:=PostProcessExecutable(current_module.sharedlibfilename^,true);
  1019. { Remove ReponseFile }
  1020. if (success) and not(cs_link_extern in aktglobalswitches) then
  1021. begin
  1022. RemoveFile(outputexedir+Info.ResName);
  1023. RemoveFile('base.$$$');
  1024. RemoveFile('exp.$$$');
  1025. end;
  1026. MakeSharedLibrary:=success; { otherwise a recursive call to link method }
  1027. end;
  1028. function tlinkerwin32.postprocessexecutable(const fn : string;isdll:boolean):boolean;
  1029. type
  1030. tdosheader = packed record
  1031. e_magic : word;
  1032. e_cblp : word;
  1033. e_cp : word;
  1034. e_crlc : word;
  1035. e_cparhdr : word;
  1036. e_minalloc : word;
  1037. e_maxalloc : word;
  1038. e_ss : word;
  1039. e_sp : word;
  1040. e_csum : word;
  1041. e_ip : word;
  1042. e_cs : word;
  1043. e_lfarlc : word;
  1044. e_ovno : word;
  1045. e_res : array[0..3] of word;
  1046. e_oemid : word;
  1047. e_oeminfo : word;
  1048. e_res2 : array[0..9] of word;
  1049. e_lfanew : longint;
  1050. end;
  1051. tpeheader = packed record
  1052. PEMagic : array[0..3] of char;
  1053. Machine : word;
  1054. NumberOfSections : word;
  1055. TimeDateStamp : longint;
  1056. PointerToSymbolTable : longint;
  1057. NumberOfSymbols : longint;
  1058. SizeOfOptionalHeader : word;
  1059. Characteristics : word;
  1060. Magic : word;
  1061. MajorLinkerVersion : byte;
  1062. MinorLinkerVersion : byte;
  1063. SizeOfCode : longint;
  1064. SizeOfInitializedData : longint;
  1065. SizeOfUninitializedData : longint;
  1066. AddressOfEntryPoint : longint;
  1067. BaseOfCode : longint;
  1068. BaseOfData : longint;
  1069. ImageBase : longint;
  1070. SectionAlignment : longint;
  1071. FileAlignment : longint;
  1072. MajorOperatingSystemVersion : word;
  1073. MinorOperatingSystemVersion : word;
  1074. MajorImageVersion : word;
  1075. MinorImageVersion : word;
  1076. MajorSubsystemVersion : word;
  1077. MinorSubsystemVersion : word;
  1078. Reserved1 : longint;
  1079. SizeOfImage : longint;
  1080. SizeOfHeaders : longint;
  1081. CheckSum : longint;
  1082. Subsystem : word;
  1083. DllCharacteristics : word;
  1084. SizeOfStackReserve : longint;
  1085. SizeOfStackCommit : longint;
  1086. SizeOfHeapReserve : longint;
  1087. SizeOfHeapCommit : longint;
  1088. LoaderFlags : longint;
  1089. NumberOfRvaAndSizes : longint;
  1090. DataDirectory : array[1..$80] of byte;
  1091. end;
  1092. tcoffsechdr=packed record
  1093. name : array[0..7] of char;
  1094. vsize : longint;
  1095. rvaofs : longint;
  1096. datalen : longint;
  1097. datapos : longint;
  1098. relocpos : longint;
  1099. lineno1 : longint;
  1100. nrelocs : word;
  1101. lineno2 : word;
  1102. flags : longint;
  1103. end;
  1104. psecfill=^TSecfill;
  1105. TSecfill=record
  1106. fillpos,
  1107. fillsize : longint;
  1108. next : psecfill;
  1109. end;
  1110. var
  1111. f : file;
  1112. cmdstr : string;
  1113. dosheader : tdosheader;
  1114. peheader : tpeheader;
  1115. firstsecpos,
  1116. maxfillsize,
  1117. l,peheaderpos : longint;
  1118. coffsec : tcoffsechdr;
  1119. secroot,hsecroot : psecfill;
  1120. zerobuf : pointer;
  1121. begin
  1122. postprocessexecutable:=false;
  1123. { when -s is used or it's a dll then quit }
  1124. if (cs_link_extern in aktglobalswitches) then
  1125. begin
  1126. case apptype of
  1127. app_gui :
  1128. cmdstr:='--subsystem gui';
  1129. app_cui :
  1130. cmdstr:='--subsystem console';
  1131. end;
  1132. if dllversion<>'' then
  1133. cmdstr:=cmdstr+' --version '+dllversion;
  1134. cmdstr:=cmdstr+' --input '+maybequoted(fn);
  1135. cmdstr:=cmdstr+' --stack '+tostr(stacksize);
  1136. DoExec(FindUtil(utilsprefix+'postw32'),cmdstr,false,false);
  1137. postprocessexecutable:=true;
  1138. exit;
  1139. end;
  1140. { open file }
  1141. assign(f,fn);
  1142. {$I-}
  1143. reset(f,1);
  1144. if ioresult<>0 then
  1145. Message1(execinfo_f_cant_open_executable,fn);
  1146. { read headers }
  1147. blockread(f,dosheader,sizeof(tdosheader));
  1148. peheaderpos:=dosheader.e_lfanew;
  1149. seek(f,peheaderpos);
  1150. blockread(f,peheader,sizeof(tpeheader));
  1151. { write info }
  1152. Message1(execinfo_x_codesize,tostr(peheader.SizeOfCode));
  1153. Message1(execinfo_x_initdatasize,tostr(peheader.SizeOfInitializedData));
  1154. Message1(execinfo_x_uninitdatasize,tostr(peheader.SizeOfUninitializedData));
  1155. { change stack size (PM) }
  1156. { I am not sure that the default value is adequate !! }
  1157. peheader.SizeOfStackReserve:=stacksize;
  1158. { change the header }
  1159. { sub system }
  1160. { gui=2 }
  1161. { cui=3 }
  1162. case apptype of
  1163. app_gui :
  1164. peheader.Subsystem:=2;
  1165. app_cui :
  1166. peheader.Subsystem:=3;
  1167. end;
  1168. if dllversion<>'' then
  1169. begin
  1170. peheader.MajorImageVersion:=dllmajor;
  1171. peheader.MinorImageVersion:=dllminor;
  1172. end;
  1173. { reset timestamp }
  1174. peheader.TimeDateStamp:=0;
  1175. { write header back }
  1176. seek(f,peheaderpos);
  1177. blockwrite(f,peheader,sizeof(tpeheader));
  1178. if ioresult<>0 then
  1179. Message1(execinfo_f_cant_process_executable,fn);
  1180. seek(f,peheaderpos);
  1181. blockread(f,peheader,sizeof(tpeheader));
  1182. { write the value after the change }
  1183. Message1(execinfo_x_stackreserve,tostr(peheader.SizeOfStackReserve));
  1184. Message1(execinfo_x_stackcommit,tostr(peheader.SizeOfStackCommit));
  1185. { read section info }
  1186. maxfillsize:=0;
  1187. firstsecpos:=0;
  1188. secroot:=nil;
  1189. for l:=1 to peheader.NumberOfSections do
  1190. begin
  1191. blockread(f,coffsec,sizeof(tcoffsechdr));
  1192. if coffsec.datapos>0 then
  1193. begin
  1194. if secroot=nil then
  1195. firstsecpos:=coffsec.datapos;
  1196. new(hsecroot);
  1197. hsecroot^.fillpos:=coffsec.datapos+coffsec.vsize;
  1198. hsecroot^.fillsize:=coffsec.datalen-coffsec.vsize;
  1199. hsecroot^.next:=secroot;
  1200. secroot:=hsecroot;
  1201. if secroot^.fillsize>maxfillsize then
  1202. maxfillsize:=secroot^.fillsize;
  1203. end;
  1204. end;
  1205. if firstsecpos>0 then
  1206. begin
  1207. l:=firstsecpos-filepos(f);
  1208. if l>maxfillsize then
  1209. maxfillsize:=l;
  1210. end
  1211. else
  1212. l:=0;
  1213. { get zero buffer }
  1214. getmem(zerobuf,maxfillsize);
  1215. fillchar(zerobuf^,maxfillsize,0);
  1216. { zero from sectioninfo until first section }
  1217. blockwrite(f,zerobuf^,l);
  1218. { zero section alignments }
  1219. while assigned(secroot) do
  1220. begin
  1221. seek(f,secroot^.fillpos);
  1222. blockwrite(f,zerobuf^,secroot^.fillsize);
  1223. hsecroot:=secroot;
  1224. secroot:=secroot^.next;
  1225. dispose(hsecroot);
  1226. end;
  1227. freemem(zerobuf,maxfillsize);
  1228. close(f);
  1229. {$I+}
  1230. if ioresult<>0 then;
  1231. postprocessexecutable:=true;
  1232. end;
  1233. {****************************************************************************
  1234. TDLLScannerWin32
  1235. ****************************************************************************}
  1236. procedure tDLLScannerWin32.GetDefExt(var N:longint;var P:pStr4);
  1237. begin
  1238. N:=sizeof(DefaultDLLExtensions)div sizeof(DefaultDLLExtensions[1]);
  1239. pointer(P):=@DefaultDLLExtensions;
  1240. end;
  1241. function tDLLScannerWin32.DOSstubOK(var x:cardinal):boolean;
  1242. begin
  1243. blockread(f,TheWord,2,loaded);
  1244. if loaded<>2 then
  1245. DOSstubOK:=false
  1246. else
  1247. begin
  1248. DOSstubOK:=(TheWord='MZ');
  1249. seek(f,$3C);
  1250. blockread(f,x,4,loaded);
  1251. if(loaded<>4)or(longint(x)>filesize(f))then
  1252. DOSstubOK:=false;
  1253. end;
  1254. end;
  1255. function TDLLScannerWin32.FindDLL(const s:string;var founddll:string):boolean;
  1256. var
  1257. sysdir : string;
  1258. Found : boolean;
  1259. begin
  1260. Found:=false;
  1261. { Look for DLL in:
  1262. 1. Current dir
  1263. 2. Library Path
  1264. 3. windir,windir/system,windir/system32 }
  1265. Found:=FindFile(s,'.'+source_info.DirSep,founddll);
  1266. if (not found) then
  1267. Found:=librarysearchpath.FindFile(s,founddll);
  1268. if (not found) then
  1269. begin
  1270. sysdir:=FixPath(GetEnv('windir'),false);
  1271. Found:=FindFile(s,sysdir+';'+sysdir+'system'+source_info.DirSep+';'+sysdir+'system32'+source_info.DirSep,founddll);
  1272. end;
  1273. if (not found) then
  1274. begin
  1275. message1(exec_w_libfile_not_found,s);
  1276. FoundDll:=s;
  1277. end;
  1278. FindDll:=Found;
  1279. end;
  1280. function tDLLScannerWin32.ExtractDllName(Const Name : string) : string;
  1281. var n : string;
  1282. begin
  1283. n:=Upper(SplitExtension(Name));
  1284. if (n='.DLL') or (n='.DRV') or (n='.EXE') then
  1285. ExtractDllName:=Name
  1286. else
  1287. ExtractDllName:=Name+target_info.sharedlibext;
  1288. end;
  1289. function tDLLScannerWin32.isSuitableFileType(x:cardinal):longbool;
  1290. begin
  1291. seek(f,x);
  1292. blockread(f,TheWord,2,loaded);
  1293. isSuitableFileType:=(loaded=2)and(TheWord='PE');
  1294. end;
  1295. function tDLLScannerWin32.GetEdata(HeaderEntry:cardinal):longbool;
  1296. type
  1297. TObjInfo=packed record
  1298. ObjName:array[0..7]of char;
  1299. VirtSize,
  1300. VirtAddr,
  1301. RawSize,
  1302. RawOffset,
  1303. Reloc,
  1304. LineNum:cardinal;
  1305. RelCount,
  1306. LineCount:word;
  1307. flags:cardinal;
  1308. end;
  1309. var
  1310. i:cardinal;
  1311. ObjOfs:cardinal;
  1312. Obj:TObjInfo;
  1313. APE_obj,APE_Optsize:word;
  1314. ExportRVA:cardinal;
  1315. delta:cardinal;
  1316. const
  1317. IMAGE_SCN_CNT_CODE=$00000020;
  1318. var
  1319. _d:dirstr;
  1320. _n:namestr;
  1321. _e:extstr;
  1322. function isUsedFunction(name:pchar):longbool;
  1323. var
  1324. hp:tExternalsItem;
  1325. begin
  1326. isUsedFunction:=false;
  1327. hp:=tExternalsItem(current_module.Externals.first);
  1328. while assigned(hp)do
  1329. begin
  1330. if(assigned(hp.data))and(not hp.found)then
  1331. if hp.data^=StrPas(name)then
  1332. begin
  1333. isUsedFunction:=true;
  1334. hp.found:=true;
  1335. exit;
  1336. end;
  1337. hp:=tExternalsItem(hp.next);
  1338. end;
  1339. end;
  1340. procedure Store(index:cardinal;name:pchar;isData:longbool);
  1341. begin
  1342. if not isUsedFunction(name)then
  1343. exit;
  1344. if not(current_module.uses_imports) then
  1345. begin
  1346. current_module.uses_imports:=true;
  1347. importlib.preparelib(current_module.modulename^);
  1348. end;
  1349. if IsData then
  1350. timportlibwin32(importlib).importvariable_str(name,_n,name)
  1351. else
  1352. timportlibwin32(importlib).importprocedure_str(name,_n,index,name);
  1353. end;
  1354. procedure ProcessEdata;
  1355. type
  1356. a8=array[0..7]of char;
  1357. function GetSectionName(rva:cardinal;var Flags:cardinal):a8;
  1358. var
  1359. i:cardinal;
  1360. LocObjOfs:cardinal;
  1361. LocObj:TObjInfo;
  1362. begin
  1363. GetSectionName:='';
  1364. Flags:=0;
  1365. LocObjOfs:=APE_OptSize+HeaderOffset+24;
  1366. for i:=1 to APE_obj do
  1367. begin
  1368. seek(f,LocObjOfs);
  1369. blockread(f,LocObj,sizeof(LocObj));
  1370. if(rva>=LocObj.VirtAddr)and(rva<=LocObj.VirtAddr+LocObj.RawSize)then
  1371. begin
  1372. GetSectionName:=a8(LocObj.ObjName);
  1373. Flags:=LocObj.flags;
  1374. end;
  1375. end;
  1376. end;
  1377. var
  1378. j,Fl:cardinal;
  1379. ulongval,procEntry:cardinal;
  1380. Ordinal:word;
  1381. isData:longbool;
  1382. ExpDir:packed record
  1383. flag,
  1384. stamp:cardinal;
  1385. Major,
  1386. Minor:word;
  1387. Name,
  1388. Base,
  1389. NumFuncs,
  1390. NumNames,
  1391. AddrFuncs,
  1392. AddrNames,
  1393. AddrOrds:cardinal;
  1394. end;
  1395. begin
  1396. with Obj do
  1397. begin
  1398. seek(f,RawOffset+delta);
  1399. blockread(f,ExpDir,sizeof(ExpDir));
  1400. fsplit(impname,_d,_n,_e);
  1401. for j:=0 to pred(ExpDir.NumNames)do
  1402. begin
  1403. { Don't know why but this gives serious problems with overflow checking on }
  1404. {$IFOPT Q+}
  1405. {$DEFINE OVERFLOW_CHECK_WAS_ON}
  1406. {$ENDIF}
  1407. {$Q-}
  1408. seek(f,RawOffset-VirtAddr+ExpDir.AddrOrds+j*2);
  1409. blockread(f,Ordinal,2);
  1410. seek(f,RawOffset-VirtAddr+ExpDir.AddrFuncs+cardinal(Ordinal)*4);
  1411. blockread(f,ProcEntry,4);
  1412. seek(f,RawOffset-VirtAddr+ExpDir.AddrNames+j*4);
  1413. blockread(f,ulongval,4);
  1414. seek(f,RawOffset-VirtAddr+ulongval);
  1415. blockread(f,cstring,sizeof(cstring));
  1416. isData:=GetSectionName(procentry,Fl)='';
  1417. {$IFDEF OVERFLOW_CHECK_WAS_ON}
  1418. {$Q+}
  1419. {$ENDIF}
  1420. if not isData then
  1421. isData:=Fl and IMAGE_SCN_CNT_CODE<>IMAGE_SCN_CNT_CODE;
  1422. Store(succ(Ordinal),cstring,isData);
  1423. end;
  1424. end;
  1425. end;
  1426. begin
  1427. GetEdata:=false;
  1428. seek(f,HeaderEntry+120);
  1429. blockread(f,ExportRVA,4);
  1430. seek(f,HeaderEntry+6);
  1431. blockread(f,APE_Obj,2);
  1432. seek(f,HeaderEntry+20);
  1433. blockread(f,APE_OptSize,2);
  1434. ObjOfs:=APE_OptSize+HeaderOffset+24;
  1435. for i:=1 to APE_obj do
  1436. begin
  1437. seek(f,ObjOfs);
  1438. blockread(f,Obj,sizeof(Obj));
  1439. inc(ObjOfs,sizeof(Obj));
  1440. with Obj do
  1441. if(VirtAddr<=ExportRva)and(ExportRva<VirtAddr+VirtSize)then
  1442. begin
  1443. delta:=ExportRva-VirtAddr;
  1444. ProcessEdata;
  1445. GetEdata:=true;
  1446. end;
  1447. end;
  1448. end;
  1449. function tDLLScannerWin32.scan(const binname:string):longbool;
  1450. var
  1451. OldFileMode:longint;
  1452. foundimp : string;
  1453. NN:longint;PP:pStr4;
  1454. begin
  1455. Scan:=false;
  1456. { is there already an import library the we will use that one }
  1457. if FindLibraryFile(binname,target_info.staticClibprefix,target_info.staticClibext,foundimp) then
  1458. exit;
  1459. { check if we can find the dll }
  1460. GetDefExt(NN,PP);
  1461. if not FindDll(DLLName(binname,NN,PP),impname) then
  1462. exit;
  1463. { read the dll file }
  1464. assign(f,impname);
  1465. OldFileMode:=filemode;
  1466. filemode:=0;
  1467. reset(f,1);
  1468. filemode:=OldFileMode;
  1469. if not DOSstubOK(HeaderOffset)then
  1470. scan:=false
  1471. else if not isSuitableFileType(HeaderOffset)then
  1472. scan:=false
  1473. else
  1474. scan:=GetEdata(HeaderOffset);
  1475. close(f);
  1476. end;
  1477. {*****************************************************************************
  1478. Initialize
  1479. *****************************************************************************}
  1480. initialization
  1481. {$ifdef i386}
  1482. RegisterExternalLinker(system_i386_win32_info,TLinkerWin32);
  1483. RegisterImport(system_i386_win32,TImportLibWin32);
  1484. RegisterExport(system_i386_win32,TExportLibWin32);
  1485. RegisterDLLScanner(system_i386_win32,TDLLScannerWin32);
  1486. RegisterRes(res_gnu_windres_info);
  1487. RegisterTarget(system_i386_win32_info);
  1488. {$endif i386}
  1489. end.
  1490. {
  1491. $Log$
  1492. Revision 1.27 2004-01-09 13:37:17 daniel
  1493. * Commented out code removed
  1494. Revision 1.25 2003/12/09 19:54:59 marco
  1495. * base-file instead of base_file
  1496. Revision 1.24 2003/12/08 22:37:04 peter
  1497. * base_file instead of b
  1498. Revision 1.23 2003/10/10 17:48:14 peter
  1499. * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
  1500. * tregisteralloctor renamed to trgobj
  1501. * removed rgobj from a lot of units
  1502. * moved location_* and reference_* to cgobj
  1503. * first things for mmx register allocation
  1504. Revision 1.22 2003/10/09 16:14:49 peter
  1505. * fix check for generatenasmlib
  1506. Revision 1.21 2003/10/03 14:16:48 marco
  1507. * -XP<prefix> support
  1508. Revision 1.20 2003/10/02 21:17:08 peter
  1509. * use as,ld,ar instead of asw,ldw,arw for win32
  1510. Revision 1.19 2003/09/30 20:10:12 peter
  1511. * smartlink fix for dlls from Pavel
  1512. Revision 1.18 2003/08/21 14:47:41 peter
  1513. * remove convert_registers
  1514. Revision 1.17 2003/08/20 20:50:18 daniel
  1515. * convert_registers call removed from t_win32.pas
  1516. Revision 1.16 2003/05/13 15:15:25 peter
  1517. * fixed import crash with explicit provided name
  1518. Revision 1.15 2003/04/27 09:14:48 florian
  1519. * aprocdef instead of aktprocdef must be used
  1520. Revision 1.14 2003/04/27 07:29:52 peter
  1521. * aktprocdef cleanup, aktprocdef is now always nil when parsing
  1522. a new procdef declaration
  1523. * aktprocsym removed
  1524. * lexlevel removed, use symtable.symtablelevel instead
  1525. * implicit init/final code uses the normal genentry/genexit
  1526. * funcret state checking updated for new funcret handling
  1527. Revision 1.13 2003/04/26 09:16:08 peter
  1528. * .o files belonging to the unit are first searched in the same dir
  1529. as the .ppu
  1530. Revision 1.12 2003/04/12 15:43:40 peter
  1531. * convert registers for importssection
  1532. Revision 1.11 2003/01/06 20:19:52 peter
  1533. * use findutil
  1534. Revision 1.10 2003/01/05 13:36:53 florian
  1535. * x86-64 compiles
  1536. + very basic support for float128 type (x86-64 only)
  1537. Revision 1.9 2002/12/24 15:55:51 peter
  1538. * Use maybequote instead of getshortname
  1539. Revision 1.8 2002/12/01 18:57:34 carl
  1540. * disable overflow checking in some parts to avoid problems
  1541. Revision 1.7 2002/11/30 18:45:28 carl
  1542. + profiling support for Win32
  1543. Revision 1.6 2002/11/16 18:40:38 carl
  1544. - remove my last stupid commit (Thanks, Peter!)
  1545. Revision 1.5 2002/11/16 14:46:50 carl
  1546. * don't add debug information in not in debug mode
  1547. Revision 1.4 2002/11/15 01:59:02 peter
  1548. * merged changes from 1.0.7 up to 04-11
  1549. - -V option for generating bug report tracing
  1550. - more tracing for option parsing
  1551. - errors for cdecl and high()
  1552. - win32 import stabs
  1553. - win32 records<=8 are returned in eax:edx (turned off by default)
  1554. - heaptrc update
  1555. - more info for temp management in .s file with EXTDEBUG
  1556. Revision 1.3 2002/10/05 12:43:29 carl
  1557. * fixes for Delphi 6 compilation
  1558. (warning : Some features do not work under Delphi)
  1559. Revision 1.2 2002/09/09 17:34:17 peter
  1560. * tdicationary.replace added to replace and item in a dictionary. This
  1561. is only allowed for the same name
  1562. * varsyms are inserted in symtable before the types are parsed. This
  1563. fixes the long standing "var longint : longint" bug
  1564. - consume_idlist and idstringlist removed. The loops are inserted
  1565. at the callers place and uses the symtable for duplicate id checking
  1566. Revision 1.1 2002/09/06 15:03:50 carl
  1567. * moved files to systems directory
  1568. Revision 1.40 2002/09/03 16:26:29 daniel
  1569. * Make Tprocdef.defs protected
  1570. Revision 1.39 2002/08/12 15:08:44 carl
  1571. + stab register indexes for powerpc (moved from gdb to cpubase)
  1572. + tprocessor enumeration moved to cpuinfo
  1573. + linker in target_info is now a class
  1574. * many many updates for m68k (will soon start to compile)
  1575. - removed some ifdef or correct them for correct cpu
  1576. Revision 1.38 2002/08/11 14:32:32 peter
  1577. * renamed current_library to objectlibrary
  1578. Revision 1.37 2002/08/11 13:24:20 peter
  1579. * saving of asmsymbols in ppu supported
  1580. * asmsymbollist global is removed and moved into a new class
  1581. tasmlibrarydata that will hold the info of a .a file which
  1582. corresponds with a single module. Added librarydata to tmodule
  1583. to keep the library info stored for the module. In the future the
  1584. objectfiles will also be stored to the tasmlibrarydata class
  1585. * all getlabel/newasmsymbol and friends are moved to the new class
  1586. Revision 1.36 2002/07/26 21:15:46 florian
  1587. * rewrote the system handling
  1588. Revision 1.35 2002/07/01 18:46:35 peter
  1589. * internal linker
  1590. * reorganized aasm layer
  1591. Revision 1.34 2002/05/18 13:34:27 peter
  1592. * readded missing revisions
  1593. Revision 1.33 2002/05/16 19:46:53 carl
  1594. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1595. + try to fix temp allocation (still in ifdef)
  1596. + generic constructor calls
  1597. + start of tassembler / tmodulebase class cleanup
  1598. Revision 1.31 2002/04/22 18:19:22 carl
  1599. - remove use_bound_instruction field
  1600. Revision 1.30 2002/04/21 15:43:58 carl
  1601. * change stack size to 256K
  1602. Revision 1.29 2002/04/20 21:43:18 carl
  1603. * fix stack size for some targets
  1604. + add offset to parameters from frame pointer info.
  1605. - remove some unused stuff
  1606. Revision 1.28 2002/04/15 19:16:57 carl
  1607. - remove size_of_pointer field
  1608. Revision 1.27 2002/04/05 17:49:09 carl
  1609. * fix compilation problems
  1610. * fix range check error
  1611. Revision 1.26 2002/04/04 19:06:14 peter
  1612. * removed unused units
  1613. * use tlocation.size in cg.a_*loc*() routines
  1614. Revision 1.25 2002/04/04 18:25:30 carl
  1615. + added wdosx patch from Pavel
  1616. Revision 1.24 2002/04/02 17:11:39 peter
  1617. * tlocation,treference update
  1618. * LOC_CONSTANT added for better constant handling
  1619. * secondadd splitted in multiple routines
  1620. * location_force_reg added for loading a location to a register
  1621. of a specified size
  1622. * secondassignment parses now first the right and then the left node
  1623. (this is compatible with Kylix). This saves a lot of push/pop especially
  1624. with string operations
  1625. * adapted some routines to use the new cg methods
  1626. Revision 1.23 2002/01/29 21:27:34 peter
  1627. * default alignment changed to 4 bytes for locals and static const,var
  1628. Revision 1.22 2002/01/19 11:53:07 peter
  1629. * fixed managledname
  1630. }