symppu.pas 13 KB

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