symppu.inc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl, Pierre Muller
  4. Implementation of the reading of PPU Files for the symtable
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. const
  19. {$ifdef FPC}
  20. ppubufsize=32768;
  21. {$ELSE}
  22. {$IFDEF USEOVERLAY}
  23. ppubufsize=512;
  24. {$ELSE}
  25. ppubufsize=4096;
  26. {$ENDIF}
  27. {$ENDIF}
  28. {*****************************************************************************
  29. PPU Writing
  30. *****************************************************************************}
  31. procedure writebyte(b:byte);
  32. begin
  33. current_ppu^.putbyte(b);
  34. end;
  35. procedure writeword(w:word);
  36. begin
  37. current_ppu^.putword(w);
  38. end;
  39. procedure writelong(l:longint);
  40. begin
  41. current_ppu^.putlongint(l);
  42. end;
  43. procedure writereal(d:bestreal);
  44. begin
  45. current_ppu^.putreal(d);
  46. end;
  47. procedure writestring(const s:string);
  48. begin
  49. current_ppu^.putstring(s);
  50. end;
  51. procedure writenormalset(var s); {You cannot pass an array[0..31] of byte!}
  52. begin
  53. current_ppu^.putdata(s,sizeof(tnormalset));
  54. end;
  55. procedure writecontainer(var p:tstringcontainer;id:byte;hold,strippath:boolean);
  56. var
  57. hcontainer : tstringcontainer;
  58. s : string;
  59. begin
  60. if hold then
  61. hcontainer.init;
  62. while not p.empty do
  63. begin
  64. s:=p.get;
  65. if strippath then
  66. current_ppu^.putstring(SplitFileName(s))
  67. else
  68. current_ppu^.putstring(s);
  69. if hold then
  70. hcontainer.insert(s);
  71. end;
  72. current_ppu^.writeentry(id);
  73. if hold then
  74. p:=hcontainer;
  75. end;
  76. procedure writeposinfo(const p:tfileposinfo);
  77. begin
  78. current_ppu^.putword(p.fileindex);
  79. current_ppu^.putlongint(p.line);
  80. current_ppu^.putword(p.column);
  81. end;
  82. procedure writedefref(p : pdef);
  83. begin
  84. if p=nil then
  85. current_ppu^.putlongint($ffffffff)
  86. else
  87. begin
  88. if (p^.owner^.symtabletype in [recordsymtable,objectsymtable]) then
  89. current_ppu^.putword($ffff)
  90. else
  91. current_ppu^.putword(p^.owner^.unitid);
  92. current_ppu^.putword(p^.indexnb);
  93. end;
  94. end;
  95. procedure writesymref(p : psym);
  96. begin
  97. if p=nil then
  98. current_ppu^.putlongint($ffffffff)
  99. else
  100. begin
  101. if (p^.owner^.symtabletype in [recordsymtable,objectsymtable]) then
  102. current_ppu^.putword($ffff)
  103. else
  104. current_ppu^.putword(p^.owner^.unitid);
  105. current_ppu^.putword(p^.indexnb);
  106. end;
  107. end;
  108. procedure writesourcefiles;
  109. var
  110. hp : pinputfile;
  111. begin
  112. { second write the used source files }
  113. hp:=current_module^.sourcefiles^.files;
  114. while assigned(hp) do
  115. begin
  116. { only name and extension }
  117. current_ppu^.putstring(hp^.name^);
  118. hp:=hp^.ref_next;
  119. end;
  120. current_ppu^.writeentry(ibsourcefiles);
  121. end;
  122. procedure writeusedunit;
  123. var
  124. hp : pused_unit;
  125. begin
  126. numberunits;
  127. hp:=pused_unit(current_module^.used_units.first);
  128. while assigned(hp) do
  129. begin
  130. current_ppu^.putstring(hp^.name^);
  131. { the checksum should not affect the crc of this unit ! (PFV) }
  132. current_ppu^.do_crc:=false;
  133. current_ppu^.putlongint(hp^.checksum);
  134. current_ppu^.do_crc:=true;
  135. current_ppu^.putbyte(byte(hp^.in_interface));
  136. hp:=pused_unit(hp^.next);
  137. end;
  138. current_ppu^.writeentry(ibloadunit_int);
  139. end;
  140. procedure writeunitas(const s : string;unittable : punitsymtable);
  141. begin
  142. Message1(unit_u_ppu_write,s);
  143. { create unit flags }
  144. with Current_Module^ do
  145. begin
  146. if (cs_create_staticlib in aktmoduleswitches) or
  147. (cs_smartlink in aktmoduleswitches) then
  148. begin
  149. flags:=flags or uf_static_linked;
  150. if SplitName(ppufilename^)<>SplitName(staticlibfilename^) then
  151. flags:=flags or uf_in_library;
  152. end;
  153. if cs_create_sharedlib in aktmoduleswitches then
  154. begin
  155. flags:=flags or uf_shared_linked;
  156. if SplitName(ppufilename^)<>SplitName(sharedlibfilename^) then
  157. flags:=flags or uf_in_library;
  158. end;
  159. if cs_smartlink in aktmoduleswitches then
  160. flags:=flags or uf_smartlink;
  161. {$ifdef GDB}
  162. if cs_gdb_dbx in aktglobalswitches then
  163. flags:=flags or uf_has_dbx;
  164. {$endif GDB}
  165. if target_os.endian=endian_big then
  166. flags:=flags or uf_big_endian;
  167. {$ifdef UseBrowser}
  168. if cs_browser in aktmoduleswitches then
  169. flags:=flags or uf_has_browser;
  170. if cs_local_browser in aktmoduleswitches then
  171. flags:=flags or uf_local_browser;
  172. {$endif UseBrowser}
  173. end;
  174. { open ppufile }
  175. current_ppu:=new(pppufile,init(s));
  176. if not current_ppu^.create then
  177. Message(unit_f_ppu_cannot_write);
  178. current_ppu^.change_endian:=source_os.endian<>target_os.endian;
  179. { write symbols and definitions }
  180. unittable^.writeasunit;
  181. { flush to be sure }
  182. current_ppu^.flush;
  183. { create and write header }
  184. current_ppu^.header.size:=current_ppu^.size;
  185. current_ppu^.header.checksum:=current_ppu^.crc;
  186. current_ppu^.header.compiler:=wordversion;
  187. current_ppu^.header.cpu:=word(target_cpu);
  188. current_ppu^.header.target:=word(target_info.target);
  189. current_ppu^.header.flags:=current_module^.flags;
  190. current_ppu^.writeheader;
  191. { save crc in current_module also }
  192. current_module^.crc:=current_ppu^.crc;
  193. { close }
  194. current_ppu^.close;
  195. dispose(current_ppu,done);
  196. end;
  197. {*****************************************************************************
  198. PPU Reading
  199. *****************************************************************************}
  200. function readbyte:byte;
  201. begin
  202. readbyte:=current_ppu^.getbyte;
  203. if current_ppu^.error then
  204. Message(unit_f_ppu_read_error);
  205. end;
  206. function readword:word;
  207. begin
  208. readword:=current_ppu^.getword;
  209. if current_ppu^.error then
  210. Message(unit_f_ppu_read_error);
  211. end;
  212. function readlong:longint;
  213. begin
  214. readlong:=current_ppu^.getlongint;
  215. if current_ppu^.error then
  216. Message(unit_f_ppu_read_error);
  217. end;
  218. function readreal : bestreal;
  219. begin
  220. readreal:=current_ppu^.getreal;
  221. if current_ppu^.error then
  222. Message(unit_f_ppu_read_error);
  223. end;
  224. function readstring : string;
  225. begin
  226. readstring:=current_ppu^.getstring;
  227. if current_ppu^.error then
  228. Message(unit_f_ppu_read_error);
  229. end;
  230. procedure readnormalset(var s); {You cannot pass an array [0..31] of byte.}
  231. begin
  232. current_ppu^.getdata(s,sizeof(tnormalset));
  233. if current_ppu^.error then
  234. Message(unit_f_ppu_read_error);
  235. end;
  236. procedure readcontainer(var p:tstringcontainer);
  237. begin
  238. while not current_ppu^.endofentry do
  239. p.insert(current_ppu^.getstring);
  240. end;
  241. procedure readposinfo(var p:tfileposinfo);
  242. begin
  243. p.fileindex:=current_ppu^.getword;
  244. p.line:=current_ppu^.getlongint;
  245. p.column:=current_ppu^.getword;
  246. end;
  247. function readdefref : pdef;
  248. var
  249. hd : pdef;
  250. begin
  251. longint(hd):=current_ppu^.getword;
  252. longint(hd):=longint(hd) or (longint(current_ppu^.getword) shl 16);
  253. readdefref:=hd;
  254. end;
  255. function readsymref : psym;
  256. var
  257. hd : psym;
  258. begin
  259. longint(hd):=current_ppu^.getword;
  260. longint(hd):=longint(hd) or (longint(current_ppu^.getword) shl 16);
  261. readsymref:=hd;
  262. end;
  263. procedure readsourcefiles;
  264. var
  265. temp,hs : string;
  266. incfile_found : boolean;
  267. ppufiletime,
  268. source_time : longint;
  269. {$ifdef UseBrowser}
  270. hp : pinputfile;
  271. {$endif UseBrowser}
  272. begin
  273. ppufiletime:=getnamedfiletime(current_module^.ppufilename^);
  274. current_module^.sources_avail:=true;
  275. while not current_ppu^.endofentry do
  276. begin
  277. hs:=current_ppu^.getstring;
  278. temp:='';
  279. if (current_module^.flags and uf_in_library)<>0 then
  280. begin
  281. current_module^.sources_avail:=false;
  282. temp:=' library';
  283. end
  284. else if pos('Macro ',hs)=1 then
  285. begin
  286. { we don't want to find this file }
  287. { but there is a problem with file indexing !! }
  288. temp:='';
  289. end
  290. else
  291. begin
  292. { check the date of the source files }
  293. Source_Time:=GetNamedFileTime(current_module^.path^+hs);
  294. incfile_found:=false;
  295. if (Source_Time=-1) then
  296. begin
  297. temp:=search(hs,includesearchpath,incfile_found);
  298. if incfile_found then
  299. begin
  300. hs:=temp+hs;
  301. Source_Time:=GetNamedFileTime(hs);
  302. end
  303. end
  304. else
  305. hs:=current_module^.path^+hs;
  306. if Source_Time=-1 then
  307. begin
  308. current_module^.sources_avail:=false;
  309. temp:=' not found';
  310. end
  311. else
  312. begin
  313. { time newer? But only allow if the file is not searched
  314. in the include path (PFV), else you've problems with
  315. units which use the same includefile names }
  316. if incfile_found then
  317. temp:=' found'
  318. else
  319. begin
  320. temp:=' time '+filetimestring(source_time);
  321. if (source_time>ppufiletime) then
  322. begin
  323. current_module^.do_compile:=true;
  324. temp:=temp+' *'
  325. end;
  326. end;
  327. end;
  328. {$ifdef UseBrowser}
  329. new(hp,init(hs));
  330. { the indexing is wrong here PM }
  331. current_module^.sourcefiles^.register_file(hp);
  332. {$endif UseBrowser}
  333. end;
  334. Message1(unit_u_ppu_source,hs+temp);
  335. end;
  336. { main source is always the last }
  337. stringdispose(current_module^.mainsource);
  338. current_module^.mainsource:=stringdup(hs);
  339. { the indexing is corrected here PM }
  340. current_module^.sourcefiles^.inverse_register_indexes;
  341. { check if we want to rebuild every unit, only if the sources are
  342. available }
  343. if do_build and current_module^.sources_avail then
  344. current_module^.do_compile:=true;
  345. end;
  346. procedure readloadunit;
  347. var
  348. hs : string;
  349. checksum : longint;
  350. in_interface : boolean;
  351. begin
  352. while not current_ppu^.endofentry do
  353. begin
  354. hs:=current_ppu^.getstring;
  355. checksum:=current_ppu^.getlongint;
  356. in_interface:=(current_ppu^.getbyte<>0);
  357. current_module^.used_units.concat(new(pused_unit,init_to_load(hs,checksum,in_interface)));
  358. end;
  359. end;
  360. procedure load_interface;
  361. var
  362. b : byte;
  363. begin
  364. { read interface part }
  365. repeat
  366. b:=current_ppu^.readentry;
  367. case b of
  368. { ibinitunit : usedunits^.insert(readstring); }
  369. ibmodulename : begin
  370. stringdispose(current_module^.modulename);
  371. current_module^.modulename:=stringdup(current_ppu^.getstring);
  372. end;
  373. ibsourcefiles : readsourcefiles;
  374. ibloadunit_int : readloadunit;
  375. iblinksharedlibs : readcontainer(current_module^.LinkSharedLibs);
  376. iblinkstaticlibs : readcontainer(current_module^.LinkStaticLibs);
  377. iblinkofiles : readcontainer(current_module^.LinkOFiles);
  378. ibendinterface : break;
  379. else
  380. Message1(unit_f_ppu_invalid_entry,tostr(b));
  381. end;
  382. until false;
  383. end;
  384. {
  385. $Log$
  386. Revision 1.27 1998-12-08 10:18:14 peter
  387. + -gh for heaptrc unit
  388. Revision 1.26 1998/11/26 14:36:02 peter
  389. * set also library flag if smartlinking and outputname is different
  390. Revision 1.25 1998/10/26 09:35:47 peter
  391. * don't count includefiles which are found in the includepath for a
  392. recompile.
  393. Revision 1.24 1998/10/20 08:06:59 pierre
  394. * several memory corruptions due to double freemem solved
  395. => never use p^.loc.location:=p^.left^.loc.location;
  396. + finally I added now by default
  397. that ra386dir translates global and unit symbols
  398. + added a first field in tsymtable and
  399. a nextsym field in tsym
  400. (this allows to obtain ordered type info for
  401. records and objects in gdb !)
  402. Revision 1.23 1998/10/16 13:37:24 florian
  403. + switch -FD added to specify the path for utilities
  404. Revision 1.22 1998/10/14 13:38:24 peter
  405. * fixed path with staticlib/objects in ppufiles
  406. Revision 1.21 1998/10/14 10:45:10 pierre
  407. * ppu problems for m68k fixed (at least in cross compiling)
  408. * one last memory leak for sysamiga fixed
  409. * the amiga RTL compiles now completely !!
  410. Revision 1.20 1998/10/13 13:10:30 peter
  411. * new style for m68k/i386 infos and enums
  412. Revision 1.19 1998/10/08 23:29:07 peter
  413. * -vu shows unit info, -vt shows tried/used files
  414. Revision 1.18 1998/09/28 16:57:27 pierre
  415. * changed all length(p^.value_str^) into str_length(p)
  416. to get it work with and without ansistrings
  417. * changed sourcefiles field of tmodule to a pointer
  418. Revision 1.17 1998/09/22 17:13:53 pierre
  419. + browsing updated and developed
  420. records and objects fields are also stored
  421. Revision 1.16 1998/09/22 15:40:56 peter
  422. * some extra ifdef GDB
  423. Revision 1.15 1998/09/21 08:45:23 pierre
  424. + added vmt_offset in tobjectdef.write for fututre use
  425. (first steps to have objects without vmt if no virtual !!)
  426. + added fpu_used field for tabstractprocdef :
  427. sets this level to 2 if the functions return with value in FPU
  428. (is then set to correct value at parsing of implementation)
  429. THIS MIGHT refuse some code with FPU expression too complex
  430. that were accepted before and even in some cases
  431. that don't overflow in fact
  432. ( like if f : float; is a forward that finally in implementation
  433. only uses one fpu register !!)
  434. Nevertheless I think that it will improve security on
  435. FPU operations !!
  436. * most other changes only for UseBrowser code
  437. (added symtable references for record and objects)
  438. local switch for refs to args and local of each function
  439. (static symtable still missing)
  440. UseBrowser still not stable and probably broken by
  441. the definition hash array !!
  442. Revision 1.14 1998/09/01 07:54:24 pierre
  443. * UseBrowser a little updated (might still be buggy !!)
  444. * bug in psub.pas in function specifier removed
  445. * stdcall allowed in interface and in implementation
  446. (FPC will not yet complain if it is missing in either part
  447. because stdcall is only a dummy !!)
  448. Revision 1.13 1998/08/17 10:10:11 peter
  449. - removed OLDPPU
  450. Revision 1.12 1998/08/17 09:17:53 peter
  451. * static/shared linking updates
  452. Revision 1.11 1998/08/16 20:32:49 peter
  453. * crcs of used units are not important for the current crc, reduces the
  454. amount of recompiles
  455. Revision 1.10 1998/08/13 10:57:30 peter
  456. * constant sets are now written correctly to the ppufile
  457. Revision 1.9 1998/08/11 15:31:41 peter
  458. * write extended to ppu file
  459. * new version 0.99.7
  460. Revision 1.8 1998/08/10 14:50:29 peter
  461. + localswitches, moduleswitches, globalswitches splitting
  462. Revision 1.7 1998/07/14 14:47:07 peter
  463. * released NEWINPUT
  464. Revision 1.6 1998/07/07 11:20:14 peter
  465. + NEWINPUT for a better inputfile and scanner object
  466. Revision 1.5 1998/06/24 14:48:39 peter
  467. * ifdef newppu -> ifndef oldppu
  468. Revision 1.4 1998/06/16 08:56:32 peter
  469. + targetcpu
  470. * cleaner pmodules for newppu
  471. Revision 1.3 1998/06/13 00:10:17 peter
  472. * working browser and newppu
  473. * some small fixes against crashes which occured in bp7 (but not in
  474. fpc?!)
  475. Revision 1.2 1998/05/28 14:40:28 peter
  476. * fixes for newppu, remake3 works now with it
  477. Revision 1.1 1998/05/27 19:45:09 peter
  478. * symtable.pas splitted into includefiles
  479. * symtable adapted for $ifdef NEWPPU
  480. }