t_win32.pas 62 KB

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