t_win32.pas 62 KB

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