t_win32.pas 59 KB

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