symppu.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  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:=current_library.asmsymbolppuidx;
  368. inc(current_library.asmsymbolppuidx);
  369. end;
  370. putlongint(s.ppuidx);
  371. end;
  372. end.
  373. {
  374. $Log$
  375. Revision 1.13 2002-08-11 13:24:14 peter
  376. * saving of asmsymbols in ppu supported
  377. * asmsymbollist global is removed and moved into a new class
  378. tasmlibrarydata that will hold the info of a .a file which
  379. corresponds with a single module. Added librarydata to tmodule
  380. to keep the library info stored for the module. In the future the
  381. objectfiles will also be stored to the tasmlibrarydata class
  382. * all getlabel/newasmsymbol and friends are moved to the new class
  383. Revision 1.12 2002/05/18 13:34:18 peter
  384. * readded missing revisions
  385. Revision 1.11 2002/05/16 19:46:45 carl
  386. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  387. + try to fix temp allocation (still in ifdef)
  388. + generic constructor calls
  389. + start of tassembler / tmodulebase class cleanup
  390. Revision 1.9 2002/05/12 16:53:15 peter
  391. * moved entry and exitcode to ncgutil and cgobj
  392. * foreach gets extra argument for passing local data to the
  393. iterator function
  394. * -CR checks also class typecasts at runtime by changing them
  395. into as
  396. * fixed compiler to cycle with the -CR option
  397. * fixed stabs with elf writer, finally the global variables can
  398. be watched
  399. * removed a lot of routines from cga unit and replaced them by
  400. calls to cgobj
  401. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  402. u32bit then the other is typecasted also to u32bit without giving
  403. a rangecheck warning/error.
  404. * fixed pascal calling method with reversing also the high tree in
  405. the parast, detected by tcalcst3 test
  406. Revision 1.8 2002/04/19 15:40:40 peter
  407. * optimize tfileposinfo writing, this reduces the ppu size with 20%
  408. }