symppu.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 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. unit symppu;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cclasses,
  23. globtype,globals,
  24. aasmbase,
  25. symbase,symtype,
  26. ppu;
  27. type
  28. tcompilerppufile=class(tppufile)
  29. public
  30. procedure checkerror;
  31. procedure getguid(var g: tguid);
  32. procedure getposinfo(var p:tfileposinfo);
  33. function getderef : pointer;
  34. function getsymlist:tsymlist;
  35. procedure gettype(var t:ttype);
  36. function getasmsymbol:tasmsymbol;
  37. procedure putguid(const g: tguid);
  38. procedure putposinfo(const p:tfileposinfo);
  39. procedure putderef(p : tsymtableentry);
  40. procedure putsymlist(p:tsymlist);
  41. procedure puttype(const t:ttype);
  42. procedure putasmsymbol(s:tasmsymbol);
  43. end;
  44. implementation
  45. uses
  46. symconst,
  47. verbose;
  48. {*****************************************************************************
  49. TCompilerPPUFile
  50. *****************************************************************************}
  51. procedure tcompilerppufile.checkerror;
  52. begin
  53. if error then
  54. Message(unit_f_ppu_read_error);
  55. end;
  56. procedure tcompilerppufile.getguid(var g: tguid);
  57. begin
  58. getdata(g,sizeof(g));
  59. end;
  60. procedure tcompilerppufile.getposinfo(var p:tfileposinfo);
  61. var
  62. info : byte;
  63. begin
  64. {
  65. info byte layout in bits:
  66. 0-1 - amount of bytes for fileindex
  67. 2-3 - amount of bytes for line
  68. 4-5 - amount of bytes for column
  69. }
  70. info:=getbyte;
  71. case (info and $03) of
  72. 0 : p.fileindex:=getbyte;
  73. 1 : p.fileindex:=getword;
  74. 2 : p.fileindex:=(getbyte shl 16) or getword;
  75. 3 : p.fileindex:=getlongint;
  76. end;
  77. case ((info shr 2) and $03) of
  78. 0 : p.line:=getbyte;
  79. 1 : p.line:=getword;
  80. 2 : p.line:=(getbyte shl 16) or getword;
  81. 3 : p.line:=getlongint;
  82. end;
  83. case ((info shr 4) and $03) of
  84. 0 : p.column:=getbyte;
  85. 1 : p.column:=getword;
  86. 2 : p.column:=(getbyte shl 16) or getword;
  87. 3 : p.column:=getlongint;
  88. end;
  89. end;
  90. function tcompilerppufile.getderef : pointer;
  91. var
  92. hp,p : tderef;
  93. b : tdereftype;
  94. begin
  95. p:=nil;
  96. repeat
  97. hp:=p;
  98. b:=tdereftype(getbyte);
  99. case b of
  100. derefnil :
  101. break;
  102. derefunit,
  103. derefaktrecordindex,
  104. derefaktlocal,
  105. derefaktstaticindex :
  106. begin
  107. p:=tderef.create(b,getword);
  108. p.next:=hp;
  109. break;
  110. end;
  111. derefindex,
  112. dereflocal,
  113. derefpara,
  114. derefrecord :
  115. begin
  116. p:=tderef.create(b,getword);
  117. p.next:=hp;
  118. end;
  119. end;
  120. until false;
  121. getderef:=p;
  122. end;
  123. function tcompilerppufile.getsymlist:tsymlist;
  124. var
  125. sym : tsym;
  126. slt : tsltype;
  127. idx : longint;
  128. p : tsymlist;
  129. begin
  130. p:=tsymlist.create;
  131. p.def:=tdef(getderef);
  132. repeat
  133. slt:=tsltype(getbyte);
  134. case slt of
  135. sl_none :
  136. break;
  137. sl_call,
  138. sl_load,
  139. sl_subscript :
  140. begin
  141. sym:=tsym(getderef);
  142. p.addsym(slt,sym);
  143. end;
  144. sl_vec :
  145. begin
  146. idx:=getlongint;
  147. p.addconst(slt,idx);
  148. end;
  149. else
  150. internalerror(200110204);
  151. end;
  152. until false;
  153. getsymlist:=tsymlist(p);
  154. end;
  155. procedure tcompilerppufile.gettype(var t:ttype);
  156. begin
  157. t.def:=tdef(getderef);
  158. t.sym:=tsym(getderef);
  159. end;
  160. function tcompilerppufile.getasmsymbol:tasmsymbol;
  161. begin
  162. getasmsymbol:=tasmsymbol(pointer(getlongint));
  163. end;
  164. procedure tcompilerppufile.putposinfo(const p:tfileposinfo);
  165. var
  166. oldcrc : boolean;
  167. info : byte;
  168. begin
  169. { posinfo is not relevant for changes in PPU }
  170. oldcrc:=do_crc;
  171. do_crc:=false;
  172. {
  173. info byte layout in bits:
  174. 0-1 - amount of bytes for fileindex
  175. 2-3 - amount of bytes for line
  176. 4-5 - amount of bytes for column
  177. }
  178. info:=0;
  179. { calculate info byte }
  180. if (p.fileindex>$ff) then
  181. begin
  182. if (p.fileindex<=$ffff) then
  183. info:=info or $1
  184. else
  185. if (p.fileindex<=$ffffff) then
  186. info:=info or $2
  187. else
  188. info:=info or $3;
  189. end;
  190. if (p.line>$ff) then
  191. begin
  192. if (p.line<=$ffff) then
  193. info:=info or $4
  194. else
  195. if (p.line<=$ffffff) then
  196. info:=info or $8
  197. else
  198. info:=info or $c;
  199. end;
  200. if (p.column>$ff) then
  201. begin
  202. if (p.column<=$ffff) then
  203. info:=info or $10
  204. else
  205. if (p.column<=$ffffff) then
  206. info:=info or $20
  207. else
  208. info:=info or $30;
  209. end;
  210. { write data }
  211. putbyte(info);
  212. case (info and $03) of
  213. 0 : putbyte(p.fileindex);
  214. 1 : putword(p.fileindex);
  215. 2 : begin
  216. putbyte(p.fileindex shr 16);
  217. putword(p.fileindex and $ffff);
  218. end;
  219. 3 : putlongint(p.fileindex);
  220. end;
  221. case ((info shr 2) and $03) of
  222. 0 : putbyte(p.line);
  223. 1 : putword(p.line);
  224. 2 : begin
  225. putbyte(p.line shr 16);
  226. putword(p.line and $ffff);
  227. end;
  228. 3 : putlongint(p.line);
  229. end;
  230. case ((info shr 4) and $03) of
  231. 0 : putbyte(p.column);
  232. 1 : putword(p.column);
  233. 2 : begin
  234. putbyte(p.column shr 16);
  235. putword(p.column and $ffff);
  236. end;
  237. 3 : putlongint(p.column);
  238. end;
  239. do_crc:=oldcrc;
  240. end;
  241. procedure tcompilerppufile.putguid(const g: tguid);
  242. begin
  243. putdata(g,sizeof(g));
  244. end;
  245. procedure tcompilerppufile.putderef(p : tsymtableentry);
  246. begin
  247. if p=nil then
  248. putbyte(ord(derefnil))
  249. else
  250. begin
  251. { Static symtable ? }
  252. if p.owner.symtabletype=staticsymtable then
  253. begin
  254. putbyte(ord(derefaktstaticindex));
  255. putword(p.indexnr);
  256. end
  257. { Local record/object symtable ? }
  258. else if (p.owner=aktrecordsymtable) then
  259. begin
  260. putbyte(ord(derefaktrecordindex));
  261. putword(p.indexnr);
  262. end
  263. { Local local/para symtable ? }
  264. else if (p.owner=aktlocalsymtable) then
  265. begin
  266. putbyte(ord(derefaktlocal));
  267. putword(p.indexnr);
  268. end
  269. else
  270. begin
  271. putbyte(ord(derefindex));
  272. putword(p.indexnr);
  273. { Current unit symtable ? }
  274. repeat
  275. if not assigned(p) then
  276. internalerror(556655);
  277. case p.owner.symtabletype of
  278. { when writing the pseudo PPU file
  279. to get CRC values the globalsymtable is not yet
  280. a unitsymtable PM }
  281. globalsymtable :
  282. begin
  283. { check if the unit is available in the uses
  284. clause, else it's an error }
  285. if p.owner.unitid=$ffff then
  286. internalerror(55665566);
  287. putbyte(ord(derefunit));
  288. putword(p.owner.unitid);
  289. break;
  290. end;
  291. staticsymtable :
  292. begin
  293. putbyte(ord(derefaktstaticindex));
  294. putword(p.indexnr);
  295. break;
  296. end;
  297. localsymtable :
  298. begin
  299. p:=p.owner.defowner;
  300. putbyte(ord(dereflocal));
  301. putword(p.indexnr);
  302. end;
  303. parasymtable :
  304. begin
  305. p:=p.owner.defowner;
  306. putbyte(ord(derefpara));
  307. putword(p.indexnr);
  308. end;
  309. objectsymtable,
  310. recordsymtable :
  311. begin
  312. p:=p.owner.defowner;
  313. putbyte(ord(derefrecord));
  314. putword(p.indexnr);
  315. end;
  316. else
  317. internalerror(556656);
  318. end;
  319. until false;
  320. end;
  321. end;
  322. end;
  323. procedure tcompilerppufile.putsymlist(p:tsymlist);
  324. var
  325. hp : psymlistitem;
  326. begin
  327. putderef(p.def);
  328. hp:=p.firstsym;
  329. while assigned(hp) do
  330. begin
  331. putbyte(byte(hp^.sltype));
  332. case hp^.sltype of
  333. sl_call,
  334. sl_load,
  335. sl_subscript :
  336. putderef(hp^.sym);
  337. sl_vec :
  338. putlongint(hp^.value);
  339. else
  340. internalerror(200110205);
  341. end;
  342. hp:=hp^.next;
  343. end;
  344. putbyte(byte(sl_none));
  345. end;
  346. procedure tcompilerppufile.puttype(const t:ttype);
  347. begin
  348. { Don't write symbol references for the current unit
  349. and for the system unit }
  350. if assigned(t.sym) and
  351. (t.sym.owner.unitid<>0) and
  352. (t.sym.owner.unitid<>1) then
  353. begin
  354. putderef(nil);
  355. putderef(t.sym);
  356. end
  357. else
  358. begin
  359. putderef(t.def);
  360. putderef(nil);
  361. end;
  362. end;
  363. procedure tcompilerppufile.putasmsymbol(s:tasmsymbol);
  364. begin
  365. if s.ppuidx=-1 then
  366. begin
  367. s.ppuidx:=objectlibrary.asmsymbolppuidx;
  368. inc(objectlibrary.asmsymbolppuidx);
  369. end;
  370. putlongint(s.ppuidx);
  371. end;
  372. end.
  373. {
  374. $Log$
  375. Revision 1.14 2002-08-11 14:32:28 peter
  376. * renamed current_library to objectlibrary
  377. Revision 1.13 2002/08/11 13:24:14 peter
  378. * saving of asmsymbols in ppu supported
  379. * asmsymbollist global is removed and moved into a new class
  380. tasmlibrarydata that will hold the info of a .a file which
  381. corresponds with a single module. Added librarydata to tmodule
  382. to keep the library info stored for the module. In the future the
  383. objectfiles will also be stored to the tasmlibrarydata class
  384. * all getlabel/newasmsymbol and friends are moved to the new class
  385. Revision 1.12 2002/05/18 13:34:18 peter
  386. * readded missing revisions
  387. Revision 1.11 2002/05/16 19:46:45 carl
  388. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  389. + try to fix temp allocation (still in ifdef)
  390. + generic constructor calls
  391. + start of tassembler / tmodulebase class cleanup
  392. Revision 1.9 2002/05/12 16:53:15 peter
  393. * moved entry and exitcode to ncgutil and cgobj
  394. * foreach gets extra argument for passing local data to the
  395. iterator function
  396. * -CR checks also class typecasts at runtime by changing them
  397. into as
  398. * fixed compiler to cycle with the -CR option
  399. * fixed stabs with elf writer, finally the global variables can
  400. be watched
  401. * removed a lot of routines from cga unit and replaced them by
  402. calls to cgobj
  403. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  404. u32bit then the other is typecasted also to u32bit without giving
  405. a rangecheck warning/error.
  406. * fixed pascal calling method with reversing also the high tree in
  407. the parast, detected by tcalcst3 test
  408. Revision 1.8 2002/04/19 15:40:40 peter
  409. * optimize tfileposinfo writing, this reduces the ppu size with 20%
  410. }