pmodules.pas 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296
  1. {
  2. Copyright (c) 1998-2008 by Florian Klaempfl
  3. Handles the parsing and loading of the modules (ppufiles)
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit pmodules;
  18. {$i fpcdefs.inc}
  19. interface
  20. procedure proc_unit;
  21. procedure proc_package;
  22. procedure proc_program(islibrary : boolean);
  23. implementation
  24. uses
  25. SysUtils,
  26. globtype,version,systems,tokens,
  27. cutils,cfileutl,cclasses,comphook,
  28. globals,verbose,fmodule,finput,fppu,
  29. symconst,symbase,symtype,symdef,symsym,symtable,
  30. wpoinfo,
  31. aasmtai,aasmdata,aasmcpu,aasmbase,
  32. cgbase,cgobj,
  33. nbas,ncgutil,
  34. link,assemble,import,export,gendef,ppu,comprsrc,dbgbase,
  35. cresstr,procinfo,
  36. pexports,
  37. wpobase,
  38. scanner,pbase,pexpr,psystem,psub,pdecsub,ptype
  39. ,cpuinfo
  40. {$ifdef i386}
  41. { fix me! }
  42. ,cpubase
  43. {$endif i386}
  44. ;
  45. procedure create_objectfile;
  46. var
  47. DLLScanner : TDLLScanner;
  48. s : string;
  49. KeepShared : TCmdStrList;
  50. begin
  51. { try to create import entries from system dlls }
  52. if (tf_has_dllscanner in target_info.flags) and
  53. (not current_module.linkOtherSharedLibs.Empty) then
  54. begin
  55. { Init DLLScanner }
  56. if assigned(CDLLScanner[target_info.system]) then
  57. DLLScanner:=CDLLScanner[target_info.system].Create
  58. else
  59. internalerror(200104121);
  60. KeepShared:=TCmdStrList.Create;
  61. { Walk all shared libs }
  62. While not current_module.linkOtherSharedLibs.Empty do
  63. begin
  64. S:=current_module.linkOtherSharedLibs.Getusemask(link_always);
  65. if not DLLScanner.scan(s) then
  66. KeepShared.Concat(s);
  67. end;
  68. DLLscanner.Free;
  69. { Recreate import section }
  70. if (target_info.system in [system_i386_win32,system_i386_wdosx]) then
  71. begin
  72. if assigned(current_asmdata.asmlists[al_imports]) then
  73. current_asmdata.asmlists[al_imports].clear
  74. else
  75. current_asmdata.asmlists[al_imports]:=TAsmList.Create;
  76. importlib.generatelib;
  77. end;
  78. { Readd the not processed files }
  79. while not KeepShared.Empty do
  80. begin
  81. s:=KeepShared.GetFirst;
  82. current_module.linkOtherSharedLibs.add(s,link_always);
  83. end;
  84. KeepShared.Free;
  85. end;
  86. { Start and end module debuginfo, at least required for stabs
  87. to insert n_sourcefile lines }
  88. if (cs_debuginfo in current_settings.moduleswitches) or
  89. (cs_use_lineinfo in current_settings.globalswitches) then
  90. current_debuginfo.insertmoduleinfo;
  91. { create the .s file and assemble it }
  92. GenerateAsm(false);
  93. { Also create a smartlinked version ? }
  94. if create_smartlink_library then
  95. begin
  96. GenerateAsm(true);
  97. if (af_needar in target_asm.flags) then
  98. Linker.MakeStaticLibrary;
  99. end;
  100. { resource files }
  101. CompileResourceFiles;
  102. end;
  103. procedure insertobjectfile;
  104. { Insert the used object file for this unit in the used list for this unit }
  105. begin
  106. current_module.linkunitofiles.add(current_module.objfilename^,link_static);
  107. current_module.flags:=current_module.flags or uf_static_linked;
  108. if create_smartlink_library then
  109. begin
  110. current_module.linkunitstaticlibs.add(current_module.staticlibfilename^,link_smart);
  111. current_module.flags:=current_module.flags or uf_smart_linked;
  112. end;
  113. end;
  114. procedure create_dwarf_frame;
  115. begin
  116. { Dwarf conflicts with smartlinking in separate .a files }
  117. if create_smartlink_library then
  118. exit;
  119. { Call frame information }
  120. { MWE: we write our own info, so dwarf asm support is not really needed }
  121. { if (af_supports_dwarf in target_asm.flags) and }
  122. { CFI is currently broken for Darwin }
  123. if not(target_info.system in systems_darwin) and
  124. (
  125. (tf_needs_dwarf_cfi in target_info.flags) or
  126. (paratargetdbg in [dbg_dwarf2, dbg_dwarf3])
  127. ) then
  128. begin
  129. current_asmdata.asmlists[al_dwarf_frame].Free;
  130. current_asmdata.asmlists[al_dwarf_frame] := TAsmList.create;
  131. current_asmdata.asmcfi.generate_code(current_asmdata.asmlists[al_dwarf_frame]);
  132. end;
  133. end;
  134. procedure InsertThreadvarTablesTable;
  135. var
  136. hp : tused_unit;
  137. ltvTables : TAsmList;
  138. count : longint;
  139. begin
  140. if (tf_section_threadvars in target_info.flags) then
  141. exit;
  142. ltvTables:=TAsmList.Create;
  143. count:=0;
  144. hp:=tused_unit(usedunits.first);
  145. while assigned(hp) do
  146. begin
  147. If (hp.u.flags and uf_threadvars)=uf_threadvars then
  148. begin
  149. ltvTables.concat(Tai_const.Createname(make_mangledname('THREADVARLIST',hp.u.globalsymtable,''),0));
  150. inc(count);
  151. end;
  152. hp:=tused_unit(hp.next);
  153. end;
  154. { Add program threadvars, if any }
  155. If (current_module.flags and uf_threadvars)=uf_threadvars then
  156. begin
  157. ltvTables.concat(Tai_const.Createname(make_mangledname('THREADVARLIST',current_module.localsymtable,''),0));
  158. inc(count);
  159. end;
  160. { Insert TableCount at start }
  161. ltvTables.insert(Tai_const.Create_32bit(count));
  162. { insert in data segment }
  163. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  164. new_section(current_asmdata.asmlists[al_globals],sec_data,'FPC_THREADVARTABLES',sizeof(pint));
  165. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('FPC_THREADVARTABLES',AT_DATA,0));
  166. current_asmdata.asmlists[al_globals].concatlist(ltvTables);
  167. current_asmdata.asmlists[al_globals].concat(Tai_symbol_end.Createname('FPC_THREADVARTABLES'));
  168. ltvTables.free;
  169. end;
  170. procedure AddToThreadvarList(p:TObject;arg:pointer);
  171. var
  172. ltvTable : TAsmList;
  173. begin
  174. ltvTable:=TAsmList(arg);
  175. if (tsym(p).typ=staticvarsym) and
  176. (vo_is_thread_var in tstaticvarsym(p).varoptions) then
  177. begin
  178. { address of threadvar }
  179. ltvTable.concat(tai_const.Createname(tstaticvarsym(p).mangledname,0));
  180. { size of threadvar }
  181. ltvTable.concat(tai_const.create_32bit(tstaticvarsym(p).getsize));
  182. end;
  183. end;
  184. procedure InsertThreadvars;
  185. var
  186. s : string;
  187. ltvTable : TAsmList;
  188. begin
  189. if (tf_section_threadvars in target_info.flags) then
  190. exit;
  191. ltvTable:=TAsmList.create;
  192. if assigned(current_module.globalsymtable) then
  193. current_module.globalsymtable.SymList.ForEachCall(@AddToThreadvarList,ltvTable);
  194. current_module.localsymtable.SymList.ForEachCall(@AddToThreadvarList,ltvTable);
  195. if ltvTable.first<>nil then
  196. begin
  197. s:=make_mangledname('THREADVARLIST',current_module.localsymtable,'');
  198. { end of the list marker }
  199. ltvTable.concat(tai_const.create_sym(nil));
  200. { add to datasegment }
  201. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  202. new_section(current_asmdata.asmlists[al_globals],sec_data,s,sizeof(pint));
  203. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global(s,AT_DATA,0));
  204. current_asmdata.asmlists[al_globals].concatlist(ltvTable);
  205. current_asmdata.asmlists[al_globals].concat(Tai_symbol_end.Createname(s));
  206. current_module.flags:=current_module.flags or uf_threadvars;
  207. end;
  208. ltvTable.Free;
  209. end;
  210. procedure MaybeGenerateObjectiveCImageInfo;
  211. begin
  212. if (m_objectivec1 in current_settings.modeswitches) then
  213. begin
  214. { first 4 bytes contain version information about this section (currently version 0),
  215. next 4 bytes contain flags (currently only regarding whether the code in the object
  216. file supports or requires garbage collection)
  217. }
  218. new_section(current_asmdata.asmlists[al_objc_data],sec_objc_image_info,'_OBJC_IMAGE_INFO',4);
  219. current_asmdata.asmlists[al_objc_data].concat(Tai_symbol.Createname(target_asm.labelprefix+'_OBJC_IMAGE_INFO',AT_LABEL,8));
  220. current_asmdata.asmlists[al_objc_data].concat(Tai_const.Create_64bit(0));
  221. end;
  222. end;
  223. Function CheckResourcesUsed : boolean;
  224. var
  225. hp : tused_unit;
  226. found : Boolean;
  227. begin
  228. CheckResourcesUsed:=tf_has_winlike_resources in target_info.flags;
  229. if not CheckResourcesUsed then exit;
  230. hp:=tused_unit(usedunits.first);
  231. found:=((current_module.flags and uf_has_resourcefiles)=uf_has_resourcefiles);
  232. If not found then
  233. While Assigned(hp) and not found do
  234. begin
  235. Found:=((hp.u.flags and uf_has_resourcefiles)=uf_has_resourcefiles);
  236. hp:=tused_unit(hp.next);
  237. end;
  238. CheckResourcesUsed:=found;
  239. end;
  240. Procedure InsertResourceInfo(ResourcesUsed : boolean);
  241. var
  242. ResourceInfo : TAsmList;
  243. begin
  244. if (target_res.id in [res_elf,res_macho]) then
  245. begin
  246. ResourceInfo:=TAsmList.Create;
  247. maybe_new_object_file(ResourceInfo);
  248. new_section(ResourceInfo,sec_data,'FPC_RESLOCATION',sizeof(aint));
  249. ResourceInfo.concat(Tai_symbol.Createname_global('FPC_RESLOCATION',AT_DATA,0));
  250. if ResourcesUsed then
  251. { Valid pointer to resource information }
  252. ResourceInfo.concat(Tai_const.Createname('FPC_RESSYMBOL',0))
  253. else
  254. { Nil pointer to resource information }
  255. {$IFDEF CPU32}
  256. ResourceInfo.Concat(Tai_const.Create_32bit(0));
  257. {$ELSE}
  258. ResourceInfo.Concat(Tai_const.Create_64bit(0));
  259. {$ENDIF}
  260. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  261. current_asmdata.asmlists[al_globals].concatlist(ResourceInfo);
  262. ResourceInfo.free;
  263. end;
  264. end;
  265. Procedure InsertResourceTablesTable;
  266. var
  267. hp : tmodule;
  268. ResourceStringTables : tasmlist;
  269. count : longint;
  270. begin
  271. ResourceStringTables:=tasmlist.Create;
  272. count:=0;
  273. hp:=tmodule(loaded_units.first);
  274. while assigned(hp) do
  275. begin
  276. If (hp.flags and uf_has_resourcestrings)=uf_has_resourcestrings then
  277. begin
  278. ResourceStringTables.concat(Tai_const.Createname(make_mangledname('RESSTR',hp.localsymtable,'START'),0));
  279. ResourceStringTables.concat(Tai_const.Createname(make_mangledname('RESSTR',hp.localsymtable,'END'),0));
  280. inc(count);
  281. end;
  282. hp:=tmodule(hp.next);
  283. end;
  284. { Insert TableCount at start }
  285. ResourceStringTables.insert(Tai_const.Create_pint(count));
  286. { Add to data segment }
  287. maybe_new_object_file(current_asmdata.AsmLists[al_globals]);
  288. new_section(current_asmdata.AsmLists[al_globals],sec_data,'FPC_RESOURCESTRINGTABLES',sizeof(pint));
  289. current_asmdata.AsmLists[al_globals].concat(Tai_symbol.Createname_global('FPC_RESOURCESTRINGTABLES',AT_DATA,0));
  290. current_asmdata.AsmLists[al_globals].concatlist(ResourceStringTables);
  291. current_asmdata.AsmLists[al_globals].concat(Tai_symbol_end.Createname('FPC_RESOURCESTRINGTABLES'));
  292. ResourceStringTables.free;
  293. end;
  294. procedure InsertInitFinalTable;
  295. var
  296. hp : tused_unit;
  297. unitinits : TAsmList;
  298. count : longint;
  299. begin
  300. unitinits:=TAsmList.Create;
  301. count:=0;
  302. hp:=tused_unit(usedunits.first);
  303. while assigned(hp) do
  304. begin
  305. { call the unit init code and make it external }
  306. if (hp.u.flags and (uf_init or uf_finalize))<>0 then
  307. begin
  308. if (hp.u.flags and uf_init)<>0 then
  309. unitinits.concat(Tai_const.Createname(make_mangledname('INIT$',hp.u.globalsymtable,''),0))
  310. else
  311. unitinits.concat(Tai_const.Create_sym(nil));
  312. if (hp.u.flags and uf_finalize)<>0 then
  313. unitinits.concat(Tai_const.Createname(make_mangledname('FINALIZE$',hp.u.globalsymtable,''),0))
  314. else
  315. unitinits.concat(Tai_const.Create_sym(nil));
  316. inc(count);
  317. end;
  318. hp:=tused_unit(hp.next);
  319. end;
  320. { Insert initialization/finalization of the program }
  321. if (current_module.flags and (uf_init or uf_finalize))<>0 then
  322. begin
  323. if (current_module.flags and uf_init)<>0 then
  324. unitinits.concat(Tai_const.Createname(make_mangledname('INIT$',current_module.localsymtable,''),0))
  325. else
  326. unitinits.concat(Tai_const.Create_sym(nil));
  327. if (current_module.flags and uf_finalize)<>0 then
  328. unitinits.concat(Tai_const.Createname(make_mangledname('FINALIZE$',current_module.localsymtable,''),0))
  329. else
  330. unitinits.concat(Tai_const.Create_sym(nil));
  331. inc(count);
  332. end;
  333. { Insert TableCount,InitCount at start }
  334. unitinits.insert(Tai_const.Create_32bit(0));
  335. unitinits.insert(Tai_const.Create_32bit(count));
  336. { Add to data segment }
  337. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  338. new_section(current_asmdata.asmlists[al_globals],sec_data,'INITFINAL',sizeof(pint));
  339. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('INITFINAL',AT_DATA,0));
  340. current_asmdata.asmlists[al_globals].concatlist(unitinits);
  341. current_asmdata.asmlists[al_globals].concat(Tai_symbol_end.Createname('INITFINAL'));
  342. unitinits.free;
  343. end;
  344. procedure insertmemorysizes;
  345. {$IFDEF POWERPC}
  346. var
  347. stkcookie: string;
  348. {$ENDIF POWERPC}
  349. begin
  350. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  351. { Insert Ident of the compiler in the .fpc.version section }
  352. current_asmdata.asmlists[al_globals].concat(Tai_section.create(sec_fpc,'version',0));
  353. current_asmdata.asmlists[al_globals].concat(Tai_align.Create(const_align(32)));
  354. current_asmdata.asmlists[al_globals].concat(Tai_string.Create('FPC '+full_version_string+
  355. ' ['+date_string+'] for '+target_cpu_string+' - '+target_info.shortname));
  356. if not(tf_no_generic_stackcheck in target_info.flags) then
  357. begin
  358. { stacksize can be specified and is now simulated }
  359. new_section(current_asmdata.asmlists[al_globals],sec_data,'__stklen', sizeof(pint));
  360. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('__stklen',AT_DATA,sizeof(pint)));
  361. current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(stacksize));
  362. end;
  363. {$IFDEF POWERPC}
  364. { AmigaOS4 "stack cookie" support }
  365. if ( target_info.system = system_powerpc_amiga ) then
  366. begin
  367. { this symbol is needed to ignite powerpc amigaos' }
  368. { stack allocation magic for us with the given stack size. }
  369. { note: won't work for m68k amigaos or morphos. (KB) }
  370. str(stacksize,stkcookie);
  371. stkcookie:='$STACK: '+stkcookie+#0;
  372. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  373. new_section(current_asmdata.asmlists[al_globals],sec_data,'__stack_cookie',length(stkcookie));
  374. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('__stack_cookie',AT_DATA,length(stkcookie)));
  375. current_asmdata.asmlists[al_globals].concat(Tai_string.Create(stkcookie));
  376. end;
  377. {$ENDIF POWERPC}
  378. { Initial heapsize }
  379. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  380. new_section(current_asmdata.asmlists[al_globals],sec_data,'__heapsize',sizeof(pint));
  381. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('__heapsize',AT_DATA,sizeof(pint)));
  382. current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(heapsize));
  383. { Initial heapsize }
  384. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  385. new_section(current_asmdata.asmlists[al_globals],sec_data,'__fpc_valgrind',sizeof(boolean));
  386. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('__fpc_valgrind',AT_DATA,sizeof(boolean)));
  387. current_asmdata.asmlists[al_globals].concat(Tai_const.create_8bit(byte(cs_gdb_valgrind in current_settings.globalswitches)));
  388. end;
  389. procedure AddUnit(const s:string);
  390. var
  391. hp : tppumodule;
  392. unitsym : tunitsym;
  393. begin
  394. { load unit }
  395. hp:=registerunit(current_module,s,'');
  396. hp.loadppu;
  397. hp.adddependency(current_module);
  398. { add to symtable stack }
  399. symtablestack.push(hp.globalsymtable);
  400. if (m_mac in current_settings.modeswitches) and
  401. assigned(hp.globalmacrosymtable) then
  402. macrosymtablestack.push(hp.globalmacrosymtable);
  403. { insert unitsym }
  404. unitsym:=tunitsym.create(s,hp);
  405. inc(unitsym.refs);
  406. current_module.localsymtable.insert(unitsym);
  407. { add to used units }
  408. current_module.addusedunit(hp,false,unitsym);
  409. end;
  410. procedure maybeloadvariantsunit;
  411. var
  412. hp : tmodule;
  413. begin
  414. { Do we need the variants unit? Skip this
  415. for VarUtils unit for bootstrapping }
  416. if (current_module.flags and uf_uses_variants=0) or
  417. (current_module.modulename^='VARUTILS') then
  418. exit;
  419. { Variants unit already loaded? }
  420. hp:=tmodule(loaded_units.first);
  421. while assigned(hp) do
  422. begin
  423. if hp.modulename^='VARIANTS' then
  424. exit;
  425. hp:=tmodule(hp.next);
  426. end;
  427. { Variants unit is not loaded yet, load it now }
  428. Message(parser_w_implicit_uses_of_variants_unit);
  429. AddUnit('variants');
  430. end;
  431. function MaybeRemoveResUnit : boolean;
  432. var
  433. resources_used : boolean;
  434. hp : tmodule;
  435. uu : tused_unit;
  436. unitname : shortstring;
  437. begin
  438. { We simply remove the unit from:
  439. - usedunit list, so that things like init/finalization table won't
  440. contain references to this unit
  441. - loaded_units list, so that the unit object file doesn't get linked
  442. with the executable. }
  443. { Note: on windows we always need resources! }
  444. resources_used:=(target_info.system in system_all_windows)
  445. or CheckResourcesUsed;
  446. if (not resources_used) and (tf_has_winlike_resources in target_info.flags) then
  447. begin
  448. { resources aren't used, so we don't need this unit }
  449. if target_res.id=res_ext then
  450. unitname:='FPEXTRES'
  451. else
  452. unitname:='FPINTRES';
  453. Message1(unit_u_unload_resunit,unitname);
  454. { find the module }
  455. hp:=tmodule(loaded_units.first);
  456. while assigned(hp) do
  457. begin
  458. if hp.is_unit and (hp.modulename^=unitname) then break;
  459. hp:=tmodule(hp.next);
  460. end;
  461. if not assigned(hp) then
  462. internalerror(200801071);
  463. { find its tused_unit in the global list }
  464. uu:=tused_unit(usedunits.first);
  465. while assigned(uu) do
  466. begin
  467. if uu.u=hp then break;
  468. uu:=tused_unit(uu.next);
  469. end;
  470. if not assigned(uu) then
  471. internalerror(200801072);
  472. { remove the tused_unit }
  473. usedunits.Remove(uu);
  474. uu.Free;
  475. { remove the module }
  476. loaded_units.Remove(hp);
  477. unloaded_units.Concat(hp);
  478. end;
  479. MaybeRemoveResUnit:=resources_used;
  480. end;
  481. procedure loaddefaultunits;
  482. begin
  483. { we are going to rebuild the symtablestack, clear it first }
  484. symtablestack.clear;
  485. macrosymtablestack.clear;
  486. { macro symtable }
  487. macrosymtablestack.push(initialmacrosymtable);
  488. { are we compiling the system unit? }
  489. if (cs_compilesystem in current_settings.moduleswitches) then
  490. begin
  491. systemunit:=tglobalsymtable(current_module.localsymtable);
  492. { create system defines }
  493. create_intern_symbols;
  494. create_intern_types;
  495. { Set the owner of errorsym and errortype to symtable to
  496. prevent crashes when accessing .owner }
  497. generrorsym.owner:=systemunit;
  498. generrordef.owner:=systemunit;
  499. exit;
  500. end;
  501. { insert the system unit, it is allways the first. Load also the
  502. internal types from the system unit }
  503. AddUnit('system');
  504. systemunit:=tglobalsymtable(symtablestack.top);
  505. load_intern_types;
  506. { Set the owner of errorsym and errortype to symtable to
  507. prevent crashes when accessing .owner }
  508. generrorsym.owner:=systemunit;
  509. generrordef.owner:=systemunit;
  510. { Units only required for main module }
  511. if not(current_module.is_unit) then
  512. begin
  513. { Heaptrc unit, load heaptrace before any other units especially objpas }
  514. if (cs_use_heaptrc in current_settings.globalswitches) then
  515. AddUnit('heaptrc');
  516. { Lineinfo unit }
  517. if (cs_use_lineinfo in current_settings.globalswitches) then begin
  518. if (paratargetdbg = dbg_stabs) then
  519. AddUnit('lineinfo')
  520. else
  521. AddUnit('lnfodwrf');
  522. end;
  523. { Valgrind requires c memory manager }
  524. if (cs_gdb_valgrind in current_settings.globalswitches) then
  525. AddUnit('cmem');
  526. {$ifdef cpufpemu}
  527. { Floating point emulation unit?
  528. softfpu must be in the system unit anyways (FK)
  529. if (cs_fp_emulation in current_settings.moduleswitches) and not(target_info.system in system_wince) then
  530. AddUnit('softfpu');
  531. }
  532. {$endif cpufpemu}
  533. { Which kind of resource support?
  534. Note: if resources aren't used this unit will be removed later,
  535. otherwise we need it here since it must be loaded quite early }
  536. if (tf_has_winlike_resources in target_info.flags) then
  537. if target_res.id=res_ext then
  538. AddUnit('fpextres')
  539. else
  540. AddUnit('fpintres');
  541. end;
  542. { Objpas unit? }
  543. if m_objpas in current_settings.modeswitches then
  544. AddUnit('objpas');
  545. { Macpas unit? }
  546. if m_mac in current_settings.modeswitches then
  547. AddUnit('macpas');
  548. { Objective-C 1.0 support unit? }
  549. if (m_objectivec1 in current_settings.modeswitches) then
  550. begin
  551. { interface to Objective-C run time }
  552. AddUnit('objc1');
  553. loadobjctypes;
  554. { NSObject }
  555. if not(current_module.is_unit) or
  556. (current_module.modulename^<>'OBJCBASE') then
  557. AddUnit('objcbase');
  558. end;
  559. { Profile unit? Needed for go32v2 only }
  560. if (cs_profile in current_settings.moduleswitches) and
  561. (target_info.system in [system_i386_go32v2,system_i386_watcom]) then
  562. AddUnit('profile');
  563. if (cs_load_fpcylix_unit in current_settings.globalswitches) then
  564. begin
  565. AddUnit('fpcylix');
  566. AddUnit('dynlibs');
  567. end;
  568. { CPU targets with microcontroller support can add a controller specific unit }
  569. {$if defined(ARM)}
  570. if (target_info.system in system_embedded) and (current_settings.controllertype<>ct_none) then
  571. AddUnit(controllerunitstr[current_settings.controllertype]);
  572. {$endif ARM}
  573. end;
  574. procedure loadautounits;
  575. var
  576. hs,s : string;
  577. begin
  578. hs:=autoloadunits;
  579. repeat
  580. s:=GetToken(hs,',');
  581. if s='' then
  582. break;
  583. AddUnit(s);
  584. until false;
  585. end;
  586. procedure loadunits;
  587. var
  588. s,sorg : TIDString;
  589. fn : string;
  590. pu : tused_unit;
  591. hp2 : tmodule;
  592. unitsym : tunitsym;
  593. begin
  594. consume(_USES);
  595. repeat
  596. s:=pattern;
  597. sorg:=orgpattern;
  598. consume(_ID);
  599. { support "<unit> in '<file>'" construct, but not for tp7 }
  600. fn:='';
  601. if not(m_tp7 in current_settings.modeswitches) and
  602. try_to_consume(_OP_IN) then
  603. fn:=FixFileName(get_stringconst);
  604. { Give a warning if lineinfo is loaded }
  605. if s='LINEINFO' then begin
  606. Message(parser_w_no_lineinfo_use_switch);
  607. if (paratargetdbg in [dbg_dwarf2, dbg_dwarf3]) then
  608. s := 'LNFODWRF';
  609. sorg := s;
  610. end;
  611. { Give a warning if objpas is loaded }
  612. if s='OBJPAS' then
  613. Message(parser_w_no_objpas_use_mode);
  614. { Using the unit itself is not possible }
  615. if (s<>current_module.modulename^) then
  616. begin
  617. { check if the unit is already used }
  618. hp2:=nil;
  619. pu:=tused_unit(current_module.used_units.first);
  620. while assigned(pu) do
  621. begin
  622. if (pu.u.modulename^=s) then
  623. begin
  624. hp2:=pu.u;
  625. break;
  626. end;
  627. pu:=tused_unit(pu.next);
  628. end;
  629. if not assigned(hp2) then
  630. hp2:=registerunit(current_module,sorg,fn)
  631. else
  632. Message1(sym_e_duplicate_id,s);
  633. { Create unitsym, we need to use the name as specified, we
  634. can not use the modulename because that can be different
  635. when -Un is used }
  636. unitsym:=tunitsym.create(sorg,nil);
  637. current_module.localsymtable.insert(unitsym);
  638. { the current module uses the unit hp2 }
  639. current_module.addusedunit(hp2,true,unitsym);
  640. end
  641. else
  642. Message1(sym_e_duplicate_id,s);
  643. if token=_COMMA then
  644. begin
  645. pattern:='';
  646. consume(_COMMA);
  647. end
  648. else
  649. break;
  650. until false;
  651. { Load the units }
  652. pu:=tused_unit(current_module.used_units.first);
  653. while assigned(pu) do
  654. begin
  655. { Only load the units that are in the current
  656. (interface/implementation) uses clause }
  657. if pu.in_uses and
  658. (pu.in_interface=current_module.in_interface) then
  659. begin
  660. tppumodule(pu.u).loadppu;
  661. { is our module compiled? then we can stop }
  662. if current_module.state=ms_compiled then
  663. exit;
  664. { add this unit to the dependencies }
  665. pu.u.adddependency(current_module);
  666. { save crc values }
  667. pu.checksum:=pu.u.crc;
  668. pu.interface_checksum:=pu.u.interface_crc;
  669. { connect unitsym to the module }
  670. pu.unitsym.module:=pu.u;
  671. { add to symtable stack }
  672. symtablestack.push(pu.u.globalsymtable);
  673. if (m_mac in current_settings.modeswitches) and
  674. assigned(pu.u.globalmacrosymtable) then
  675. macrosymtablestack.push(pu.u.globalmacrosymtable);
  676. end;
  677. pu:=tused_unit(pu.next);
  678. end;
  679. consume(_SEMICOLON);
  680. end;
  681. procedure reset_all_defs;
  682. procedure reset_used_unit_defs(hp:tmodule);
  683. var
  684. pu : tused_unit;
  685. begin
  686. pu:=tused_unit(hp.used_units.first);
  687. while assigned(pu) do
  688. begin
  689. if not pu.u.is_reset then
  690. begin
  691. { prevent infinte loop for circular dependencies }
  692. pu.u.is_reset:=true;
  693. if assigned(pu.u.globalsymtable) then
  694. begin
  695. tglobalsymtable(pu.u.globalsymtable).reset_all_defs;
  696. reset_used_unit_defs(pu.u);
  697. end;
  698. end;
  699. pu:=tused_unit(pu.next);
  700. end;
  701. end;
  702. var
  703. hp2 : tmodule;
  704. begin
  705. hp2:=tmodule(loaded_units.first);
  706. while assigned(hp2) do
  707. begin
  708. hp2.is_reset:=false;
  709. hp2:=tmodule(hp2.next);
  710. end;
  711. reset_used_unit_defs(current_module);
  712. end;
  713. procedure free_localsymtables(st:TSymtable);
  714. var
  715. i : longint;
  716. def : tstoreddef;
  717. pd : tprocdef;
  718. begin
  719. for i:=0 to st.DefList.Count-1 do
  720. begin
  721. def:=tstoreddef(st.DefList[i]);
  722. if def.typ=procdef then
  723. begin
  724. pd:=tprocdef(def);
  725. if assigned(pd.localst) and
  726. (pd.localst.symtabletype<>staticsymtable) and
  727. not(po_inline in pd.procoptions) then
  728. begin
  729. free_localsymtables(pd.localst);
  730. pd.localst.free;
  731. pd.localst:=nil;
  732. end;
  733. end;
  734. end;
  735. end;
  736. procedure parse_implementation_uses;
  737. begin
  738. if token=_USES then
  739. loadunits;
  740. end;
  741. procedure setupglobalswitches;
  742. begin
  743. if (cs_create_pic in current_settings.moduleswitches) then
  744. begin
  745. def_system_macro('FPC_PIC');
  746. def_system_macro('PIC');
  747. end;
  748. end;
  749. function create_main_proc(const name:string;potype:tproctypeoption;st:TSymtable):tcgprocinfo;
  750. var
  751. ps : tprocsym;
  752. pd : tprocdef;
  753. begin
  754. { there should be no current_procinfo available }
  755. if assigned(current_procinfo) then
  756. internalerror(200304275);
  757. {Generate a procsym for main}
  758. ps:=tprocsym.create('$'+name);
  759. { main are allways used }
  760. inc(ps.refs);
  761. st.insert(ps);
  762. pd:=tprocdef.create(main_program_level);
  763. include(pd.procoptions,po_global);
  764. pd.procsym:=ps;
  765. ps.ProcdefList.Add(pd);
  766. { set procdef options }
  767. pd.proctypeoption:=potype;
  768. pd.proccalloption:=pocall_default;
  769. include(pd.procoptions,po_hascallingconvention);
  770. pd.forwarddef:=false;
  771. pd.setmangledname(target_info.cprefix+name);
  772. pd.aliasnames.insert(pd.mangledname);
  773. handle_calling_convention(pd);
  774. { We don't need is a local symtable. Change it into the static
  775. symtable }
  776. pd.localst.free;
  777. pd.localst:=st;
  778. { set procinfo and current_procinfo.procdef }
  779. result:=tcgprocinfo(cprocinfo.create(nil));
  780. result.procdef:=pd;
  781. { main proc does always a call e.g. to init system unit }
  782. include(result.flags,pi_do_call);
  783. end;
  784. procedure release_main_proc(pi:tcgprocinfo);
  785. begin
  786. { remove localst as it was replaced by staticsymtable }
  787. pi.procdef.localst:=nil;
  788. { remove procinfo }
  789. current_module.procinfo:=nil;
  790. pi.free;
  791. pi:=nil;
  792. end;
  793. function gen_implicit_initfinal(flag:word;st:TSymtable):tcgprocinfo;
  794. begin
  795. { update module flags }
  796. current_module.flags:=current_module.flags or flag;
  797. { create procdef }
  798. case flag of
  799. uf_init :
  800. begin
  801. result:=create_main_proc(make_mangledname('',current_module.localsymtable,'init_implicit'),potype_unitinit,st);
  802. result.procdef.aliasnames.insert(make_mangledname('INIT$',current_module.localsymtable,''));
  803. end;
  804. uf_finalize :
  805. begin
  806. result:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize_implicit'),potype_unitfinalize,st);
  807. result.procdef.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
  808. if (not current_module.is_unit) then
  809. result.procdef.aliasnames.insert('PASCALFINALIZE');
  810. end;
  811. else
  812. internalerror(200304253);
  813. end;
  814. result.code:=cnothingnode.create;
  815. end;
  816. procedure copy_macro(p:TObject; arg:pointer);
  817. begin
  818. current_module.globalmacrosymtable.insert(tmacro(p).getcopy);
  819. end;
  820. procedure proc_unit;
  821. function is_assembler_generated:boolean;
  822. var
  823. hal : tasmlisttype;
  824. begin
  825. result:=false;
  826. if Errorcount=0 then
  827. begin
  828. for hal:=low(TasmlistType) to high(TasmlistType) do
  829. if not current_asmdata.asmlists[hal].empty then
  830. begin
  831. result:=true;
  832. exit;
  833. end;
  834. end;
  835. end;
  836. var
  837. main_file: tinputfile;
  838. {$ifdef EXTDEBUG}
  839. store_crc,
  840. {$endif EXTDEBUG}
  841. store_interface_crc : cardinal;
  842. s1,s2 : ^string; {Saves stack space}
  843. force_init_final : boolean;
  844. init_procinfo,
  845. finalize_procinfo : tcgprocinfo;
  846. unitname8 : string[8];
  847. ag: boolean;
  848. {$ifdef i386}
  849. gotvarsym : tstaticvarsym;
  850. {$endif i386}
  851. {$ifdef debug_devirt}
  852. i: longint;
  853. {$endif debug_devirt}
  854. begin
  855. init_procinfo:=nil;
  856. finalize_procinfo:=nil;
  857. if m_mac in current_settings.modeswitches then
  858. current_module.mode_switch_allowed:= false;
  859. consume(_UNIT);
  860. if compile_level=1 then
  861. Status.IsExe:=false;
  862. if token=_ID then
  863. begin
  864. { create filenames and unit name }
  865. main_file := current_scanner.inputfile;
  866. while assigned(main_file.next) do
  867. main_file := main_file.next;
  868. new(s1);
  869. s1^:=current_module.modulename^;
  870. current_module.SetFileName(main_file.path^+main_file.name^,true);
  871. current_module.SetModuleName(orgpattern);
  872. { check for system unit }
  873. new(s2);
  874. s2^:=upper(ChangeFileExt(ExtractFileName(main_file.name^),''));
  875. unitname8:=copy(current_module.modulename^,1,8);
  876. if (cs_check_unit_name in current_settings.globalswitches) and
  877. (
  878. not(
  879. (current_module.modulename^=s2^) or
  880. (
  881. (length(current_module.modulename^)>8) and
  882. (unitname8=s2^)
  883. )
  884. )
  885. or
  886. (
  887. (length(s1^)>8) and
  888. (s1^<>current_module.modulename^)
  889. )
  890. ) then
  891. Message1(unit_e_illegal_unit_name,current_module.realmodulename^);
  892. if (current_module.modulename^='SYSTEM') then
  893. include(current_settings.moduleswitches,cs_compilesystem);
  894. dispose(s2);
  895. dispose(s1);
  896. end;
  897. if (target_info.system in system_unit_program_exports) then
  898. exportlib.preparelib(current_module.realmodulename^);
  899. consume(_ID);
  900. consume(_SEMICOLON);
  901. consume(_INTERFACE);
  902. { global switches are read, so further changes aren't allowed }
  903. current_module.in_global:=false;
  904. { handle the global switches }
  905. setupglobalswitches;
  906. message1(unit_u_loading_interface_units,current_module.modulename^);
  907. { update status }
  908. status.currentmodule:=current_module.realmodulename^;
  909. { maybe turn off m_objpas if we are compiling objpas }
  910. if (current_module.modulename^='OBJPAS') then
  911. exclude(current_settings.modeswitches,m_objpas);
  912. { maybe turn off m_mac if we are compiling macpas }
  913. if (current_module.modulename^='MACPAS') then
  914. exclude(current_settings.modeswitches,m_mac);
  915. parse_only:=true;
  916. { generate now the global symboltable,
  917. define first as local to overcome dependency conflicts }
  918. current_module.localsymtable:=tglobalsymtable.create(current_module.modulename^,current_module.moduleid);
  919. { insert unitsym of this unit to prevent other units having
  920. the same name }
  921. current_module.localsymtable.insert(tunitsym.create(current_module.realmodulename^,current_module));
  922. { load default units, like the system unit }
  923. loaddefaultunits;
  924. { insert qualifier for the system unit (allows system.writeln) }
  925. if not(cs_compilesystem in current_settings.moduleswitches) and
  926. (token=_USES) then
  927. begin
  928. loadunits;
  929. { has it been compiled at a higher level ?}
  930. if current_module.state=ms_compiled then
  931. exit;
  932. end;
  933. { move the global symtable from the temporary local to global }
  934. current_module.globalsymtable:=current_module.localsymtable;
  935. current_module.localsymtable:=nil;
  936. reset_all_defs;
  937. { number all units, so we know if a unit is used by this unit or
  938. needs to be added implicitly }
  939. current_module.updatemaps;
  940. { create whole program optimisation information }
  941. current_module.wpoinfo:=tunitwpoinfo.create;
  942. { ... parse the declarations }
  943. Message1(parser_u_parsing_interface,current_module.realmodulename^);
  944. symtablestack.push(current_module.globalsymtable);
  945. read_interface_declarations;
  946. symtablestack.pop(current_module.globalsymtable);
  947. { Export macros defined in the interface for macpas. The macros
  948. are put in the globalmacrosymtable that will only be used by other
  949. units. The current unit continues to use the localmacrosymtable }
  950. if (m_mac in current_settings.modeswitches) then
  951. begin
  952. current_module.globalmacrosymtable:=tmacrosymtable.create(true);
  953. current_module.localmacrosymtable.SymList.ForEachCall(@copy_macro,nil);
  954. end;
  955. { leave when we got an error }
  956. if (Errorcount>0) and not status.skip_error then
  957. begin
  958. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  959. status.skip_error:=true;
  960. exit;
  961. end;
  962. { Our interface is compiled, generate CRC and switch to implementation }
  963. if not(cs_compilesystem in current_settings.moduleswitches) and
  964. (Errorcount=0) then
  965. tppumodule(current_module).getppucrc;
  966. current_module.in_interface:=false;
  967. current_module.interface_compiled:=true;
  968. { First reload all units depending on our interface, we need to do this
  969. in the implementation part to prevent erroneous circular references }
  970. reload_flagged_units;
  971. { Parse the implementation section }
  972. if (m_mac in current_settings.modeswitches) and try_to_consume(_END) then
  973. current_module.interface_only:=true
  974. else
  975. current_module.interface_only:=false;
  976. parse_only:=false;
  977. { create static symbol table }
  978. current_module.localsymtable:=tstaticsymtable.create(current_module.modulename^,current_module.moduleid);
  979. {$ifdef i386}
  980. if cs_create_pic in current_settings.moduleswitches then
  981. begin
  982. { insert symbol for got access in assembler code}
  983. gotvarsym:=tstaticvarsym.create('_GLOBAL_OFFSET_TABLE_',vs_value,voidpointertype,[vo_is_external]);
  984. gotvarsym.set_mangledname('_GLOBAL_OFFSET_TABLE_');
  985. current_module.localsymtable.insert(gotvarsym);
  986. { avoid unnecessary warnings }
  987. gotvarsym.varstate:=vs_read;
  988. gotvarsym.refs:=1;
  989. end;
  990. {$endif i386}
  991. if not current_module.interface_only then
  992. begin
  993. consume(_IMPLEMENTATION);
  994. Message1(unit_u_loading_implementation_units,current_module.modulename^);
  995. { Read the implementation units }
  996. parse_implementation_uses;
  997. end;
  998. if current_module.state=ms_compiled then
  999. exit;
  1000. { reset ranges/stabs in exported definitions }
  1001. reset_all_defs;
  1002. { All units are read, now give them a number }
  1003. current_module.updatemaps;
  1004. symtablestack.push(current_module.globalsymtable);
  1005. symtablestack.push(current_module.localsymtable);
  1006. if not current_module.interface_only then
  1007. begin
  1008. Message1(parser_u_parsing_implementation,current_module.modulename^);
  1009. if current_module.in_interface then
  1010. internalerror(200212285);
  1011. { Compile the unit }
  1012. init_procinfo:=create_main_proc(make_mangledname('',current_module.localsymtable,'init'),potype_unitinit,current_module.localsymtable);
  1013. init_procinfo.procdef.aliasnames.insert(make_mangledname('INIT$',current_module.localsymtable,''));
  1014. init_procinfo.parse_body;
  1015. { save file pos for debuginfo }
  1016. current_module.mainfilepos:=init_procinfo.entrypos;
  1017. end;
  1018. { Generate specializations of objectdefs methods }
  1019. generate_specialization_procs;
  1020. { if the unit contains ansi/widestrings, initialization and
  1021. finalization code must be forced }
  1022. force_init_final:=tglobalsymtable(current_module.globalsymtable).needs_init_final or
  1023. tstaticsymtable(current_module.localsymtable).needs_init_final;
  1024. { should we force unit initialization? }
  1025. { this is a hack, but how can it be done better ? }
  1026. if force_init_final and ((current_module.flags and uf_init)=0) then
  1027. begin
  1028. { first release the not used init procinfo }
  1029. if assigned(init_procinfo) then
  1030. release_main_proc(init_procinfo);
  1031. init_procinfo:=gen_implicit_initfinal(uf_init,current_module.localsymtable);
  1032. end;
  1033. { finalize? }
  1034. if not current_module.interface_only and (token=_FINALIZATION) then
  1035. begin
  1036. { set module options }
  1037. current_module.flags:=current_module.flags or uf_finalize;
  1038. { Compile the finalize }
  1039. finalize_procinfo:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize'),potype_unitfinalize,current_module.localsymtable);
  1040. finalize_procinfo.procdef.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
  1041. finalize_procinfo.parse_body;
  1042. end
  1043. else if force_init_final then
  1044. finalize_procinfo:=gen_implicit_initfinal(uf_finalize,current_module.localsymtable);
  1045. { Now both init and finalize bodies are read and it is known
  1046. which variables are used in both init and finalize we can now
  1047. generate the code. This is required to prevent putting a variable in
  1048. a register that is also used in the finalize body (PFV) }
  1049. if assigned(init_procinfo) then
  1050. begin
  1051. init_procinfo.generate_code;
  1052. init_procinfo.resetprocdef;
  1053. release_main_proc(init_procinfo);
  1054. end;
  1055. if assigned(finalize_procinfo) then
  1056. begin
  1057. finalize_procinfo.generate_code;
  1058. finalize_procinfo.resetprocdef;
  1059. release_main_proc(finalize_procinfo);
  1060. end;
  1061. symtablestack.pop(current_module.localsymtable);
  1062. symtablestack.pop(current_module.globalsymtable);
  1063. { the last char should always be a point }
  1064. consume(_POINT);
  1065. if (Errorcount=0) then
  1066. begin
  1067. { tests, if all (interface) forwards are resolved }
  1068. tstoredsymtable(current_module.globalsymtable).check_forwards;
  1069. { check if all private fields are used }
  1070. tstoredsymtable(current_module.globalsymtable).allprivatesused;
  1071. { test static symtable }
  1072. tstoredsymtable(current_module.localsymtable).allsymbolsused;
  1073. tstoredsymtable(current_module.localsymtable).allprivatesused;
  1074. tstoredsymtable(current_module.localsymtable).check_forwards;
  1075. tstoredsymtable(current_module.localsymtable).checklabels;
  1076. { used units }
  1077. current_module.allunitsused;
  1078. end;
  1079. { leave when we got an error }
  1080. if (Errorcount>0) and not status.skip_error then
  1081. begin
  1082. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1083. status.skip_error:=true;
  1084. exit;
  1085. end;
  1086. { if an Objective-C module, generate objc_image_info section }
  1087. MaybeGenerateObjectiveCImageInfo;
  1088. { do we need to add the variants unit? }
  1089. maybeloadvariantsunit;
  1090. { generate wrappers for interfaces }
  1091. gen_intf_wrappers(current_asmdata.asmlists[al_procedures],current_module.globalsymtable);
  1092. gen_intf_wrappers(current_asmdata.asmlists[al_procedures],current_module.localsymtable);
  1093. { generate pic helpers to load eip if necessary }
  1094. gen_pic_helpers(current_asmdata.asmlists[al_procedures]);
  1095. { generate rtti/init tables }
  1096. write_persistent_type_info(current_module.globalsymtable);
  1097. write_persistent_type_info(current_module.localsymtable);
  1098. { Tables }
  1099. insertThreadVars;
  1100. { Resource strings }
  1101. GenerateResourceStrings;
  1102. { generate debuginfo }
  1103. if (cs_debuginfo in current_settings.moduleswitches) then
  1104. current_debuginfo.inserttypeinfo;
  1105. { generate imports }
  1106. if current_module.ImportLibraryList.Count>0 then
  1107. importlib.generatelib;
  1108. { insert own objectfile, or say that it's in a library
  1109. (no check for an .o when loading) }
  1110. ag:=is_assembler_generated;
  1111. if ag then
  1112. insertobjectfile
  1113. else
  1114. begin
  1115. current_module.flags:=current_module.flags or uf_no_link;
  1116. current_module.flags:=current_module.flags and not (uf_has_stabs_debuginfo or uf_has_dwarf_debuginfo);
  1117. end;
  1118. if ag then
  1119. begin
  1120. { create callframe info }
  1121. create_dwarf_frame;
  1122. { assemble }
  1123. create_objectfile;
  1124. end;
  1125. { Write out the ppufile after the object file has been created }
  1126. store_interface_crc:=current_module.interface_crc;
  1127. {$ifdef EXTDEBUG}
  1128. store_crc:=current_module.crc;
  1129. {$endif EXTDEBUG}
  1130. if (Errorcount=0) then
  1131. tppumodule(current_module).writeppu;
  1132. if not(cs_compilesystem in current_settings.moduleswitches) then
  1133. if store_interface_crc<>current_module.interface_crc then
  1134. Message1(unit_u_interface_crc_changed,current_module.ppufilename^);
  1135. {$ifdef EXTDEBUG}
  1136. if not(cs_compilesystem in current_settings.moduleswitches) then
  1137. if (store_crc<>current_module.crc) and simplify_ppu then
  1138. Message1(unit_u_implementation_crc_changed,current_module.ppufilename^);
  1139. {$endif EXTDEBUG}
  1140. { release local symtables that are not needed anymore }
  1141. free_localsymtables(current_module.globalsymtable);
  1142. free_localsymtables(current_module.localsymtable);
  1143. { leave when we got an error }
  1144. if (Errorcount>0) and not status.skip_error then
  1145. begin
  1146. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1147. status.skip_error:=true;
  1148. exit;
  1149. end;
  1150. {$ifdef debug_devirt}
  1151. { print out all instantiated class/object types }
  1152. writeln('constructed object/class/classreftypes in ',current_module.realmodulename^);
  1153. for i := 0 to current_module.wpoinfo.createdobjtypes.count-1 do
  1154. begin
  1155. write(' ',tdef(current_module.wpoinfo.createdobjtypes[i]).GetTypeName);
  1156. case tdef(current_module.wpoinfo.createdobjtypes[i]).typ of
  1157. objectdef:
  1158. case tobjectdef(current_module.wpoinfo.createdobjtypes[i]).objecttype of
  1159. odt_object:
  1160. writeln(' (object)');
  1161. odt_class:
  1162. writeln(' (class)');
  1163. else
  1164. internalerror(2008101103);
  1165. end;
  1166. else
  1167. internalerror(2008101104);
  1168. end;
  1169. end;
  1170. for i := 0 to current_module.wpoinfo.createdclassrefobjtypes.count-1 do
  1171. begin
  1172. write(' Class Of ',tdef(current_module.wpoinfo.createdclassrefobjtypes[i]).GetTypeName);
  1173. case tdef(current_module.wpoinfo.createdclassrefobjtypes[i]).typ of
  1174. objectdef:
  1175. case tobjectdef(current_module.wpoinfo.createdclassrefobjtypes[i]).objecttype of
  1176. odt_class:
  1177. writeln(' (classrefdef)');
  1178. else
  1179. internalerror(2008101105);
  1180. end
  1181. else
  1182. internalerror(2008101102);
  1183. end;
  1184. end;
  1185. {$endif debug_devirt}
  1186. Message1(unit_u_finished_compiling,current_module.modulename^);
  1187. end;
  1188. procedure procexport(const s : string);
  1189. var
  1190. hp : texported_item;
  1191. begin
  1192. hp:=texported_item.create;
  1193. hp.name:=stringdup(s);
  1194. hp.options:=hp.options or eo_name;
  1195. exportlib.exportprocedure(hp);
  1196. end;
  1197. procedure varexport(const s : string);
  1198. var
  1199. hp : texported_item;
  1200. begin
  1201. hp:=texported_item.create;
  1202. hp.name:=stringdup(s);
  1203. hp.options:=hp.options or eo_name;
  1204. exportlib.exportvar(hp);
  1205. end;
  1206. procedure insert_export(sym : TObject;arg:pointer);
  1207. var
  1208. i : longint;
  1209. item : TCmdStrListItem;
  1210. begin
  1211. case TSym(sym).typ of
  1212. { ignore: }
  1213. unitsym,
  1214. syssym,
  1215. constsym,
  1216. enumsym,
  1217. typesym:
  1218. ;
  1219. procsym:
  1220. begin
  1221. for i:=0 to tprocsym(sym).ProcdefList.Count-1 do
  1222. begin
  1223. if not(tprocdef(tprocsym(sym).ProcdefList[i]).proccalloption in [pocall_internproc]) and
  1224. ((tprocdef(tprocsym(sym).ProcdefList[i]).procoptions*[po_external])=[]) and
  1225. ((tsymtable(arg).symtabletype=globalsymtable) or
  1226. ((tsymtable(arg).symtabletype=staticsymtable) and (po_public in tprocdef(tprocsym(sym).ProcdefList[i]).procoptions))
  1227. ) then
  1228. begin
  1229. procexport(tprocdef(tprocsym(sym).ProcdefList[i]).mangledname);
  1230. { walk through all aliases }
  1231. item:=TCmdStrListItem(tprocdef(tprocsym(sym).ProcdefList[i]).aliasnames.first);
  1232. while assigned(item) do
  1233. begin
  1234. { avoid duplicate entries, sometimes aliasnames contains the mangledname }
  1235. if item.str<>tprocdef(tprocsym(sym).ProcdefList[i]).mangledname then
  1236. procexport(item.str);
  1237. item:=TCmdStrListItem(item.next);
  1238. end;
  1239. end;
  1240. end;
  1241. end;
  1242. staticvarsym:
  1243. begin
  1244. varexport(tsym(sym).mangledname);
  1245. end;
  1246. else
  1247. begin
  1248. writeln('unknown: ',ord(TSym(sym).typ));
  1249. end;
  1250. end;
  1251. end;
  1252. Function RewritePPU(const PPUFn,PPLFn:String):Boolean;
  1253. Var
  1254. MakeStatic : Boolean;
  1255. Var
  1256. buffer : array[0..$1fff] of byte;
  1257. inppu,
  1258. outppu : tppufile;
  1259. b,
  1260. untilb : byte;
  1261. l,m : longint;
  1262. f : file;
  1263. ext,
  1264. s : string;
  1265. ppuversion : dword;
  1266. begin
  1267. Result:=false;
  1268. MakeStatic:=False;
  1269. inppu:=tppufile.create(PPUFn);
  1270. if not inppu.openfile then
  1271. begin
  1272. inppu.free;
  1273. Comment(V_Error,'Could not open : '+PPUFn);
  1274. Exit;
  1275. end;
  1276. { Check the ppufile }
  1277. if not inppu.CheckPPUId then
  1278. begin
  1279. inppu.free;
  1280. Comment(V_Error,'Not a PPU File : '+PPUFn);
  1281. Exit;
  1282. end;
  1283. ppuversion:=inppu.GetPPUVersion;
  1284. if ppuversion<CurrentPPUVersion then
  1285. begin
  1286. inppu.free;
  1287. Comment(V_Error,'Wrong PPU Version '+tostr(ppuversion)+' in '+PPUFn);
  1288. Exit;
  1289. end;
  1290. { No .o file generated for this ppu, just skip }
  1291. if (inppu.header.flags and uf_no_link)<>0 then
  1292. begin
  1293. inppu.free;
  1294. Result:=true;
  1295. Exit;
  1296. end;
  1297. { Already a lib? }
  1298. if (inppu.header.flags and uf_in_library)<>0 then
  1299. begin
  1300. inppu.free;
  1301. Comment(V_Error,'PPU is already in a library : '+PPUFn);
  1302. Exit;
  1303. end;
  1304. { We need a static linked unit }
  1305. if (inppu.header.flags and uf_static_linked)=0 then
  1306. begin
  1307. inppu.free;
  1308. Comment(V_Error,'PPU is not static linked : '+PPUFn);
  1309. Exit;
  1310. end;
  1311. { Check if shared is allowed }
  1312. if tsystem(inppu.header.target) in [system_i386_go32v2] then
  1313. begin
  1314. Comment(V_Error,'Shared library not supported for ppu target, switching to static library');
  1315. MakeStatic:=true;
  1316. end;
  1317. { Create the new ppu }
  1318. if PPUFn=PPLFn then
  1319. outppu:=tppufile.create('ppumove.$$$')
  1320. else
  1321. outppu:=tppufile.create(PPLFn);
  1322. outppu.createfile;
  1323. { Create new header, with the new flags }
  1324. outppu.header:=inppu.header;
  1325. outppu.header.flags:=outppu.header.flags or uf_in_library;
  1326. if MakeStatic then
  1327. outppu.header.flags:=outppu.header.flags or uf_static_linked
  1328. else
  1329. outppu.header.flags:=outppu.header.flags or uf_shared_linked;
  1330. { read until the object files are found }
  1331. untilb:=iblinkunitofiles;
  1332. repeat
  1333. b:=inppu.readentry;
  1334. if b in [ibendinterface,ibend] then
  1335. begin
  1336. inppu.free;
  1337. outppu.free;
  1338. Comment(V_Error,'No files to be linked found : '+PPUFn);
  1339. Exit;
  1340. end;
  1341. if b<>untilb then
  1342. begin
  1343. repeat
  1344. inppu.getdatabuf(buffer,sizeof(buffer),l);
  1345. outppu.putdata(buffer,l);
  1346. until l<sizeof(buffer);
  1347. outppu.writeentry(b);
  1348. end;
  1349. until (b=untilb);
  1350. { we have now reached the section for the files which need to be added,
  1351. now add them to the list }
  1352. case b of
  1353. iblinkunitofiles :
  1354. begin
  1355. { add all o files, and save the entry when not creating a static
  1356. library to keep staticlinking possible }
  1357. while not inppu.endofentry do
  1358. begin
  1359. s:=inppu.getstring;
  1360. m:=inppu.getlongint;
  1361. if not MakeStatic then
  1362. begin
  1363. outppu.putstring(s);
  1364. outppu.putlongint(m);
  1365. end;
  1366. current_module.linkotherofiles.add(s,link_always);;
  1367. end;
  1368. if not MakeStatic then
  1369. outppu.writeentry(b);
  1370. end;
  1371. { iblinkunitstaticlibs :
  1372. begin
  1373. AddToLinkFiles(ExtractLib(inppu.getstring));
  1374. if not inppu.endofentry then
  1375. begin
  1376. repeat
  1377. inppu.getdatabuf(buffer^,bufsize,l);
  1378. outppu.putdata(buffer^,l);
  1379. until l<bufsize;
  1380. outppu.writeentry(b);
  1381. end;
  1382. end; }
  1383. end;
  1384. { just add a new entry with the new lib }
  1385. if MakeStatic then
  1386. begin
  1387. outppu.putstring('imp'+current_module.realmodulename^);
  1388. outppu.putlongint(link_static);
  1389. outppu.writeentry(iblinkunitstaticlibs)
  1390. end
  1391. else
  1392. begin
  1393. outppu.putstring('imp'+current_module.realmodulename^);
  1394. outppu.putlongint(link_shared);
  1395. outppu.writeentry(iblinkunitsharedlibs);
  1396. end;
  1397. { read all entries until the end and write them also to the new ppu }
  1398. repeat
  1399. b:=inppu.readentry;
  1400. { don't write ibend, that's written automaticly }
  1401. if b<>ibend then
  1402. begin
  1403. if b=iblinkothersharedlibs then
  1404. begin
  1405. while not inppu.endofentry do
  1406. begin
  1407. s:=inppu.getstring;
  1408. m:=inppu.getlongint;
  1409. outppu.putstring(s);
  1410. outppu.putlongint(m);
  1411. { strip lib prefix }
  1412. if copy(s,1,3)='lib' then
  1413. delete(s,1,3);
  1414. ext:=ExtractFileExt(s);
  1415. if ext<>'' then
  1416. delete(s,length(s)-length(ext)+1,length(ext));
  1417. current_module.linkOtherSharedLibs.add(s,link_always);
  1418. end;
  1419. end
  1420. else
  1421. repeat
  1422. inppu.getdatabuf(buffer,sizeof(buffer),l);
  1423. outppu.putdata(buffer,l);
  1424. until l<sizeof(buffer);
  1425. outppu.writeentry(b);
  1426. end;
  1427. until b=ibend;
  1428. { write the last stuff and close }
  1429. outppu.flush;
  1430. outppu.writeheader;
  1431. outppu.free;
  1432. inppu.free;
  1433. { rename }
  1434. if PPUFn=PPLFn then
  1435. begin
  1436. {$I-}
  1437. assign(f,PPUFn);
  1438. erase(f);
  1439. assign(f,'ppumove.$$$');
  1440. rename(f,PPUFn);
  1441. {$I+}
  1442. if ioresult<>0 then;
  1443. end;
  1444. Result:=True;
  1445. end;
  1446. procedure createimportlibfromexports;
  1447. var
  1448. hp : texported_item;
  1449. begin
  1450. hp:=texported_item(current_module._exports.first);
  1451. while assigned(hp) do
  1452. begin
  1453. current_module.AddExternalImport(current_module.realmodulename^,hp.name^,hp.index,hp.is_var,false);
  1454. hp:=texported_item(hp.next);
  1455. end;
  1456. end;
  1457. procedure proc_package;
  1458. var
  1459. main_file : tinputfile;
  1460. hp,hp2 : tmodule;
  1461. {finalize_procinfo,
  1462. init_procinfo,
  1463. main_procinfo : tcgprocinfo;}
  1464. force_init_final : boolean;
  1465. uu : tused_unit;
  1466. begin
  1467. Status.IsPackage:=true;
  1468. Status.IsExe:=true;
  1469. parse_only:=false;
  1470. {main_procinfo:=nil;
  1471. init_procinfo:=nil;
  1472. finalize_procinfo:=nil;}
  1473. if not RelocSectionSetExplicitly then
  1474. RelocSection:=true;
  1475. { Relocation works only without stabs under Windows when }
  1476. { external linker (LD) is used. LD generates relocs for }
  1477. { stab sections which is not loaded in memory. It causes }
  1478. { AV error when DLL is loaded and relocation is needed. }
  1479. { Internal linker does not have this problem. }
  1480. if RelocSection and
  1481. (target_info.system in system_all_windows+[system_i386_wdosx]) and
  1482. (cs_link_extern in current_settings.globalswitches) then
  1483. begin
  1484. include(current_settings.globalswitches,cs_link_strip);
  1485. { Warning stabs info does not work with reloc section !! }
  1486. if (cs_debuginfo in current_settings.moduleswitches) and
  1487. (target_dbg.id=dbg_stabs) then
  1488. begin
  1489. Message1(parser_w_parser_reloc_no_debug,current_module.mainsource^);
  1490. Message(parser_w_parser_win32_debug_needs_WN);
  1491. exclude(current_settings.moduleswitches,cs_debuginfo);
  1492. end;
  1493. end;
  1494. { get correct output names }
  1495. main_file := current_scanner.inputfile;
  1496. while assigned(main_file.next) do
  1497. main_file := main_file.next;
  1498. current_module.SetFileName(main_file.path^+main_file.name^,true);
  1499. consume(_ID);
  1500. current_module.setmodulename(orgpattern);
  1501. current_module.ispackage:=true;
  1502. exportlib.preparelib(orgpattern);
  1503. if tf_library_needs_pic in target_info.flags then
  1504. include(current_settings.moduleswitches,cs_create_pic);
  1505. consume(_ID);
  1506. consume(_SEMICOLON);
  1507. { global switches are read, so further changes aren't allowed }
  1508. current_module.in_global:=false;
  1509. { setup things using the switches }
  1510. setupglobalswitches;
  1511. { set implementation flag }
  1512. current_module.in_interface:=false;
  1513. current_module.interface_compiled:=true;
  1514. { insert after the unit symbol tables the static symbol table }
  1515. { of the program }
  1516. current_module.localsymtable:=tstaticsymtable.create(current_module.modulename^,current_module.moduleid);
  1517. {Load the units used by the program we compile.}
  1518. if token=_REQUIRES then
  1519. begin
  1520. end;
  1521. {Load the units used by the program we compile.}
  1522. if (token=_ID) and (idtoken=_CONTAINS) then
  1523. begin
  1524. consume(_ID);
  1525. while true do
  1526. begin
  1527. if token=_ID then
  1528. AddUnit(pattern);
  1529. consume(_ID);
  1530. if token=_COMMA then
  1531. consume(_COMMA)
  1532. else break;
  1533. end;
  1534. consume(_SEMICOLON);
  1535. end;
  1536. { reset ranges/stabs in exported definitions }
  1537. reset_all_defs;
  1538. { All units are read, now give them a number }
  1539. current_module.updatemaps;
  1540. {Insert the name of the main program into the symbol table.}
  1541. if current_module.realmodulename^<>'' then
  1542. current_module.localsymtable.insert(tunitsym.create(current_module.realmodulename^,current_module));
  1543. Message1(parser_u_parsing_implementation,current_module.mainsource^);
  1544. symtablestack.push(current_module.localsymtable);
  1545. { create whole program optimisation information }
  1546. current_module.wpoinfo:=tunitwpoinfo.create;
  1547. { should we force unit initialization? }
  1548. force_init_final:=tstaticsymtable(current_module.localsymtable).needs_init_final;
  1549. if force_init_final then
  1550. {init_procinfo:=gen_implicit_initfinal(uf_init,current_module.localsymtable)};
  1551. { Add symbol to the exports section for win32 so smartlinking a
  1552. DLL will include the edata section }
  1553. if assigned(exportlib) and
  1554. (target_info.system in [system_i386_win32,system_i386_wdosx]) and
  1555. ((current_module.flags and uf_has_exports)<>0) then
  1556. current_asmdata.asmlists[al_procedures].concat(tai_const.createname(make_mangledname('EDATA',current_module.localsymtable,''),0));
  1557. { all labels must be defined before generating code }
  1558. if Errorcount=0 then
  1559. tstoredsymtable(current_module.localsymtable).checklabels;
  1560. symtablestack.pop(current_module.localsymtable);
  1561. { consume the last point }
  1562. consume(_END);
  1563. consume(_POINT);
  1564. if (Errorcount=0) then
  1565. begin
  1566. { test static symtable }
  1567. tstoredsymtable(current_module.localsymtable).allsymbolsused;
  1568. tstoredsymtable(current_module.localsymtable).allprivatesused;
  1569. tstoredsymtable(current_module.localsymtable).check_forwards;
  1570. current_module.allunitsused;
  1571. end;
  1572. new_section(current_asmdata.asmlists[al_globals],sec_data,'_FPCDummy',4);
  1573. current_asmdata.asmlists[al_globals].concat(tai_symbol.createname_global('_FPCDummy',AT_DATA,0));
  1574. current_asmdata.asmlists[al_globals].concat(tai_const.create_32bit(0));
  1575. new_section(current_asmdata.asmlists[al_procedures],sec_code,'',0);
  1576. current_asmdata.asmlists[al_procedures].concat(tai_symbol.createname_global('_DLLMainCRTStartup',AT_FUNCTION,0));
  1577. {$ifdef i386}
  1578. { fix me! }
  1579. current_asmdata.asmlists[al_procedures].concat(Taicpu.Op_const_reg(A_MOV,S_L,1,NR_EAX));
  1580. current_asmdata.asmlists[al_procedures].concat(Taicpu.Op_const(A_RET,S_W,12));
  1581. {$endif i386}
  1582. current_asmdata.asmlists[al_procedures].concat(tai_const.createname('_FPCDummy',0));
  1583. { leave when we got an error }
  1584. if (Errorcount>0) and not status.skip_error then
  1585. begin
  1586. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1587. status.skip_error:=true;
  1588. exit;
  1589. end;
  1590. { remove all unused units, this happends when units are removed
  1591. from the uses clause in the source and the ppu was already being loaded }
  1592. hp:=tmodule(loaded_units.first);
  1593. while assigned(hp) do
  1594. begin
  1595. hp2:=hp;
  1596. hp:=tmodule(hp.next);
  1597. if hp2.is_unit and
  1598. not assigned(hp2.globalsymtable) then
  1599. loaded_units.remove(hp2);
  1600. end;
  1601. { force exports }
  1602. uu:=tused_unit(usedunits.first);
  1603. while assigned(uu) do
  1604. begin
  1605. uu.u.globalsymtable.symlist.ForEachCall(@insert_export,uu.u.globalsymtable);
  1606. { check localsymtable for exports too to get public symbols }
  1607. uu.u.localsymtable.symlist.ForEachCall(@insert_export,uu.u.localsymtable);
  1608. { create special exports }
  1609. if (uu.u.flags and uf_init)<>0 then
  1610. procexport(make_mangledname('INIT$',uu.u.globalsymtable,''));
  1611. if (uu.u.flags and uf_finalize)<>0 then
  1612. procexport(make_mangledname('FINALIZE$',uu.u.globalsymtable,''));
  1613. if (uu.u.flags and uf_threadvars)=uf_threadvars then
  1614. varexport(make_mangledname('THREADVARLIST',uu.u.globalsymtable,''));
  1615. uu:=tused_unit(uu.next);
  1616. end;
  1617. {$ifdef arm}
  1618. { Insert .pdata section for arm-wince.
  1619. It is needed for exception handling. }
  1620. if target_info.system in [system_arm_wince] then
  1621. InsertPData;
  1622. {$endif arm}
  1623. { generate debuginfo }
  1624. if (cs_debuginfo in current_settings.moduleswitches) then
  1625. current_debuginfo.inserttypeinfo;
  1626. exportlib.generatelib;
  1627. { write all our exports to the import library,
  1628. needs to be done after exportlib.generatelib; }
  1629. createimportlibfromexports;
  1630. { generate imports }
  1631. if current_module.ImportLibraryList.Count>0 then
  1632. importlib.generatelib;
  1633. { Reference all DEBUGINFO sections from the main .fpc section }
  1634. if (cs_debuginfo in current_settings.moduleswitches) then
  1635. current_debuginfo.referencesections(current_asmdata.asmlists[al_procedures]);
  1636. { insert own objectfile }
  1637. insertobjectfile;
  1638. { assemble and link }
  1639. create_objectfile;
  1640. { We might need the symbols info if not using
  1641. the default do_extractsymbolinfo
  1642. which is a dummy function PM }
  1643. needsymbolinfo:=do_extractsymbolinfo<>@def_extractsymbolinfo;
  1644. { release all local symtables that are not needed anymore }
  1645. if (not needsymbolinfo) then
  1646. free_localsymtables(current_module.localsymtable);
  1647. { leave when we got an error }
  1648. if (Errorcount>0) and not status.skip_error then
  1649. begin
  1650. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1651. status.skip_error:=true;
  1652. exit;
  1653. end;
  1654. if (not current_module.is_unit) then
  1655. begin
  1656. { finally rewrite all units included into the package }
  1657. uu:=tused_unit(usedunits.first);
  1658. while assigned(uu) do
  1659. begin
  1660. RewritePPU(uu.u.ppufilename^,uu.u.ppufilename^);
  1661. uu:=tused_unit(uu.next);
  1662. end;
  1663. { create the executable when we are at level 1 }
  1664. if (compile_level=1) then
  1665. begin
  1666. { create global resource file by collecting all resource files }
  1667. CollectResourceFiles;
  1668. { write .def file }
  1669. if (cs_link_deffile in current_settings.globalswitches) then
  1670. deffile.writefile;
  1671. { insert all .o files from all loaded units and
  1672. unload the units, we don't need them anymore.
  1673. Keep the current_module because that is still needed }
  1674. hp:=tmodule(loaded_units.first);
  1675. while assigned(hp) do
  1676. begin
  1677. { the package itself contains no code so far }
  1678. linker.AddModuleFiles(hp);
  1679. hp2:=tmodule(hp.next);
  1680. if (hp<>current_module) and
  1681. (not needsymbolinfo) then
  1682. begin
  1683. loaded_units.remove(hp);
  1684. hp.free;
  1685. end;
  1686. hp:=hp2;
  1687. end;
  1688. linker.MakeSharedLibrary
  1689. end;
  1690. { Give Fatal with error count for linker errors }
  1691. if (Errorcount>0) and not status.skip_error then
  1692. begin
  1693. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1694. status.skip_error:=true;
  1695. end;
  1696. end;
  1697. end;
  1698. procedure proc_program(islibrary : boolean);
  1699. var
  1700. main_file : tinputfile;
  1701. hp,hp2 : tmodule;
  1702. finalize_procinfo,
  1703. init_procinfo,
  1704. main_procinfo : tcgprocinfo;
  1705. force_init_final : boolean;
  1706. resources_used : boolean;
  1707. begin
  1708. DLLsource:=islibrary;
  1709. Status.IsLibrary:=IsLibrary;
  1710. Status.IsPackage:=false;
  1711. Status.IsExe:=true;
  1712. parse_only:=false;
  1713. main_procinfo:=nil;
  1714. init_procinfo:=nil;
  1715. finalize_procinfo:=nil;
  1716. resources_used:=false;
  1717. { DLL defaults to create reloc info }
  1718. if islibrary then
  1719. begin
  1720. if not RelocSectionSetExplicitly then
  1721. RelocSection:=true;
  1722. end;
  1723. { Relocation works only without stabs under Windows when }
  1724. { external linker (LD) is used. LD generates relocs for }
  1725. { stab sections which is not loaded in memory. It causes }
  1726. { AV error when DLL is loaded and relocation is needed. }
  1727. { Internal linker does not have this problem. }
  1728. if RelocSection and
  1729. (target_info.system in system_all_windows+[system_i386_wdosx]) and
  1730. (cs_link_extern in current_settings.globalswitches) then
  1731. begin
  1732. include(current_settings.globalswitches,cs_link_strip);
  1733. { Warning stabs info does not work with reloc section !! }
  1734. if (cs_debuginfo in current_settings.moduleswitches) and
  1735. (target_dbg.id=dbg_stabs) then
  1736. begin
  1737. Message1(parser_w_parser_reloc_no_debug,current_module.mainsource^);
  1738. Message(parser_w_parser_win32_debug_needs_WN);
  1739. exclude(current_settings.moduleswitches,cs_debuginfo);
  1740. end;
  1741. end;
  1742. { get correct output names }
  1743. main_file := current_scanner.inputfile;
  1744. while assigned(main_file.next) do
  1745. main_file := main_file.next;
  1746. current_module.SetFileName(main_file.path^+main_file.name^,true);
  1747. if islibrary then
  1748. begin
  1749. consume(_LIBRARY);
  1750. current_module.setmodulename(orgpattern);
  1751. current_module.islibrary:=true;
  1752. exportlib.preparelib(orgpattern);
  1753. if tf_library_needs_pic in target_info.flags then
  1754. include(current_settings.moduleswitches,cs_create_pic);
  1755. consume(_ID);
  1756. consume(_SEMICOLON);
  1757. end
  1758. else
  1759. { is there an program head ? }
  1760. if token=_PROGRAM then
  1761. begin
  1762. consume(_PROGRAM);
  1763. current_module.setmodulename(orgpattern);
  1764. if (target_info.system in system_unit_program_exports) then
  1765. exportlib.preparelib(orgpattern);
  1766. consume(_ID);
  1767. if token=_LKLAMMER then
  1768. begin
  1769. consume(_LKLAMMER);
  1770. repeat
  1771. consume(_ID);
  1772. until not try_to_consume(_COMMA);
  1773. consume(_RKLAMMER);
  1774. end;
  1775. consume(_SEMICOLON);
  1776. end
  1777. else if (target_info.system in system_unit_program_exports) then
  1778. exportlib.preparelib(current_module.realmodulename^);
  1779. { global switches are read, so further changes aren't allowed }
  1780. current_module.in_global:=false;
  1781. { setup things using the switches }
  1782. setupglobalswitches;
  1783. { set implementation flag }
  1784. current_module.in_interface:=false;
  1785. current_module.interface_compiled:=true;
  1786. { insert after the unit symbol tables the static symbol table }
  1787. { of the program }
  1788. current_module.localsymtable:=tstaticsymtable.create(current_module.modulename^,current_module.moduleid);
  1789. { load standard units (system,objpas,profile unit) }
  1790. loaddefaultunits;
  1791. { Load units provided on the command line }
  1792. loadautounits;
  1793. {Load the units used by the program we compile.}
  1794. if token=_USES then
  1795. loadunits;
  1796. { reset ranges/stabs in exported definitions }
  1797. reset_all_defs;
  1798. { All units are read, now give them a number }
  1799. current_module.updatemaps;
  1800. {Insert the name of the main program into the symbol table.}
  1801. if current_module.realmodulename^<>'' then
  1802. current_module.localsymtable.insert(tunitsym.create(current_module.realmodulename^,current_module));
  1803. Message1(parser_u_parsing_implementation,current_module.mainsource^);
  1804. symtablestack.push(current_module.localsymtable);
  1805. { create whole program optimisation information }
  1806. current_module.wpoinfo:=tunitwpoinfo.create;
  1807. { The program intialization needs an alias, so it can be called
  1808. from the bootstrap code.}
  1809. if islibrary then
  1810. begin
  1811. main_procinfo:=create_main_proc(make_mangledname('',current_module.localsymtable,mainaliasname),potype_proginit,current_module.localsymtable);
  1812. { Win32 startup code needs a single name }
  1813. if not(target_info.system in systems_darwin) then
  1814. main_procinfo.procdef.aliasnames.insert('PASCALMAIN')
  1815. else
  1816. main_procinfo.procdef.aliasnames.insert(target_info.Cprefix+'PASCALMAIN')
  1817. end
  1818. else if (target_info.system in ([system_i386_netware,system_i386_netwlibc,system_powerpc_macos]+systems_darwin)) then
  1819. begin
  1820. main_procinfo:=create_main_proc('PASCALMAIN',potype_proginit,current_module.localsymtable);
  1821. end
  1822. else
  1823. begin
  1824. main_procinfo:=create_main_proc(mainaliasname,potype_proginit,current_module.localsymtable);
  1825. main_procinfo.procdef.aliasnames.insert('PASCALMAIN');
  1826. end;
  1827. main_procinfo.parse_body;
  1828. { save file pos for debuginfo }
  1829. current_module.mainfilepos:=main_procinfo.entrypos;
  1830. { Generate specializations of objectdefs methods }
  1831. generate_specialization_procs;
  1832. { should we force unit initialization? }
  1833. force_init_final:=tstaticsymtable(current_module.localsymtable).needs_init_final;
  1834. if force_init_final then
  1835. init_procinfo:=gen_implicit_initfinal(uf_init,current_module.localsymtable);
  1836. { Add symbol to the exports section for win32 so smartlinking a
  1837. DLL will include the edata section }
  1838. if assigned(exportlib) and
  1839. (target_info.system in [system_i386_win32,system_i386_wdosx]) and
  1840. ((current_module.flags and uf_has_exports)<>0) then
  1841. current_asmdata.asmlists[al_procedures].concat(tai_const.createname(make_mangledname('EDATA',current_module.localsymtable,''),0));
  1842. { finalize? }
  1843. if token=_FINALIZATION then
  1844. begin
  1845. { set module options }
  1846. current_module.flags:=current_module.flags or uf_finalize;
  1847. { Parse the finalize }
  1848. finalize_procinfo:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize'),potype_unitfinalize,current_module.localsymtable);
  1849. finalize_procinfo.procdef.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
  1850. finalize_procinfo.procdef.aliasnames.insert('PASCALFINALIZE');
  1851. finalize_procinfo.parse_body;
  1852. end
  1853. else
  1854. if force_init_final then
  1855. finalize_procinfo:=gen_implicit_initfinal(uf_finalize,current_module.localsymtable);
  1856. { the finalization routine of libraries is generic (and all libraries need to }
  1857. { be finalized, so they can finalize any units they use }
  1858. if (islibrary) then
  1859. exportlib.setfininame(current_asmdata.asmlists[al_procedures],'FPC_LIB_EXIT');
  1860. { all labels must be defined before generating code }
  1861. if Errorcount=0 then
  1862. tstoredsymtable(current_module.localsymtable).checklabels;
  1863. { See remark in unit init/final }
  1864. main_procinfo.generate_code;
  1865. main_procinfo.resetprocdef;
  1866. release_main_proc(main_procinfo);
  1867. if assigned(init_procinfo) then
  1868. begin
  1869. init_procinfo.generate_code;
  1870. init_procinfo.resetprocdef;
  1871. release_main_proc(init_procinfo);
  1872. end;
  1873. if assigned(finalize_procinfo) then
  1874. begin
  1875. finalize_procinfo.generate_code;
  1876. finalize_procinfo.resetprocdef;
  1877. release_main_proc(finalize_procinfo);
  1878. end;
  1879. symtablestack.pop(current_module.localsymtable);
  1880. { consume the last point }
  1881. consume(_POINT);
  1882. if (Errorcount=0) then
  1883. begin
  1884. { test static symtable }
  1885. tstoredsymtable(current_module.localsymtable).allsymbolsused;
  1886. tstoredsymtable(current_module.localsymtable).allprivatesused;
  1887. tstoredsymtable(current_module.localsymtable).check_forwards;
  1888. current_module.allunitsused;
  1889. end;
  1890. { leave when we got an error }
  1891. if (Errorcount>0) and not status.skip_error then
  1892. begin
  1893. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1894. status.skip_error:=true;
  1895. exit;
  1896. end;
  1897. { remove all unused units, this happens when units are removed
  1898. from the uses clause in the source and the ppu was already being loaded }
  1899. hp:=tmodule(loaded_units.first);
  1900. while assigned(hp) do
  1901. begin
  1902. hp2:=hp;
  1903. hp:=tmodule(hp.next);
  1904. if hp2.is_unit and
  1905. not assigned(hp2.globalsymtable) then
  1906. begin
  1907. loaded_units.remove(hp2);
  1908. unloaded_units.concat(hp2);
  1909. end;
  1910. end;
  1911. { if an Objective-C module, generate objc_image_info section }
  1912. MaybeGenerateObjectiveCImageInfo;
  1913. { do we need to add the variants unit? }
  1914. maybeloadvariantsunit;
  1915. { Now that everything has been compiled we know if we need resource
  1916. support. If not, remove the unit. }
  1917. resources_used:=MaybeRemoveResUnit;
  1918. linker.initsysinitunitname;
  1919. if target_info.system in system_internal_sysinit then
  1920. begin
  1921. { add start/halt unit }
  1922. AddUnit(linker.sysinitunit);
  1923. end;
  1924. {$ifdef arm}
  1925. { Insert .pdata section for arm-wince.
  1926. It is needed for exception handling. }
  1927. if target_info.system in [system_arm_wince] then
  1928. InsertPData;
  1929. {$endif arm}
  1930. InsertThreadvars;
  1931. { generate pic helpers to load eip if necessary }
  1932. gen_pic_helpers(current_asmdata.asmlists[al_procedures]);
  1933. { generate rtti/init tables }
  1934. write_persistent_type_info(current_module.localsymtable);
  1935. { generate wrappers for interfaces }
  1936. gen_intf_wrappers(current_asmdata.asmlists[al_procedures],current_module.localsymtable);
  1937. { generate imports }
  1938. if current_module.ImportLibraryList.Count>0 then
  1939. importlib.generatelib;
  1940. { generate debuginfo }
  1941. if (cs_debuginfo in current_settings.moduleswitches) then
  1942. current_debuginfo.inserttypeinfo;
  1943. if islibrary or (target_info.system in system_unit_program_exports) then
  1944. exportlib.generatelib;
  1945. { Reference all DEBUGINFO sections from the main .fpc section }
  1946. if (cs_debuginfo in current_settings.moduleswitches) then
  1947. current_debuginfo.referencesections(current_asmdata.asmlists[al_procedures]);
  1948. { Resource strings }
  1949. GenerateResourceStrings;
  1950. { insert Tables and StackLength }
  1951. insertinitfinaltable;
  1952. InsertThreadvarTablesTable;
  1953. InsertResourceTablesTable;
  1954. insertmemorysizes;
  1955. { Insert symbol to resource info }
  1956. InsertResourceInfo(resources_used);
  1957. { create callframe info }
  1958. create_dwarf_frame;
  1959. { insert own objectfile }
  1960. insertobjectfile;
  1961. { assemble and link }
  1962. create_objectfile;
  1963. { We might need the symbols info if not using
  1964. the default do_extractsymbolinfo
  1965. which is a dummy function PM }
  1966. needsymbolinfo:=
  1967. (do_extractsymbolinfo<>@def_extractsymbolinfo) or
  1968. ((current_settings.genwpoptimizerswitches*WPOptimizationsNeedingAllUnitInfo)<>[]);
  1969. { release all local symtables that are not needed anymore }
  1970. if (not needsymbolinfo) then
  1971. free_localsymtables(current_module.localsymtable);
  1972. { leave when we got an error }
  1973. if (Errorcount>0) and not status.skip_error then
  1974. begin
  1975. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1976. status.skip_error:=true;
  1977. exit;
  1978. end;
  1979. if (not current_module.is_unit) then
  1980. begin
  1981. { create the executable when we are at level 1 }
  1982. if (compile_level=1) then
  1983. begin
  1984. { create global resource file by collecting all resource files }
  1985. CollectResourceFiles;
  1986. { write .def file }
  1987. if (cs_link_deffile in current_settings.globalswitches) then
  1988. deffile.writefile;
  1989. { insert all .o files from all loaded units and
  1990. unload the units, we don't need them anymore.
  1991. Keep the current_module because that is still needed }
  1992. hp:=tmodule(loaded_units.first);
  1993. while assigned(hp) do
  1994. begin
  1995. linker.AddModuleFiles(hp);
  1996. hp2:=tmodule(hp.next);
  1997. if (hp<>current_module) and
  1998. (not needsymbolinfo) then
  1999. begin
  2000. loaded_units.remove(hp);
  2001. hp.free;
  2002. end;
  2003. hp:=hp2;
  2004. end;
  2005. { free also unneeded units we didn't free before }
  2006. if not needsymbolinfo then
  2007. unloaded_units.Clear;
  2008. { finally we can create a executable }
  2009. if DLLSource then
  2010. linker.MakeSharedLibrary
  2011. else
  2012. linker.MakeExecutable;
  2013. { collect all necessary information for whole-program optimization }
  2014. wpoinfomanager.extractwpoinfofromprogram;
  2015. end;
  2016. { Give Fatal with error count for linker errors }
  2017. if (Errorcount>0) and not status.skip_error then
  2018. begin
  2019. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  2020. status.skip_error:=true;
  2021. end;
  2022. end;
  2023. end;
  2024. end.