symppu.inc 18 KB

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