symppu.inc 19 KB

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