symppu.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  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(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.dataidx:=getlongint;
  147. end;
  148. function tcompilerppufile.getsymlist:tsymlist;
  149. var
  150. symderef : tderef;
  151. slt : tsltype;
  152. idx : longint;
  153. p : tsymlist;
  154. begin
  155. p:=tsymlist.create;
  156. getderef(p.procdefderef);
  157. repeat
  158. slt:=tsltype(getbyte);
  159. case slt of
  160. sl_none :
  161. break;
  162. sl_call,
  163. sl_load,
  164. sl_subscript :
  165. begin
  166. getderef(symderef);
  167. p.addsymderef(slt,symderef);
  168. end;
  169. sl_vec :
  170. begin
  171. idx:=getlongint;
  172. p.addconst(slt,idx);
  173. end;
  174. else
  175. internalerror(200110204);
  176. end;
  177. until false;
  178. getsymlist:=tsymlist(p);
  179. end;
  180. procedure tcompilerppufile.gettype(var t:ttype);
  181. begin
  182. getderef(t.deref);
  183. t.def:=nil;
  184. t.sym:=nil;
  185. end;
  186. function tcompilerppufile.getasmsymbol:tasmsymbol;
  187. begin
  188. getasmsymbol:=tasmsymbol(pointer(getlongint));
  189. end;
  190. procedure tcompilerppufile.putposinfo(const p:tfileposinfo);
  191. var
  192. oldcrc : boolean;
  193. info : byte;
  194. begin
  195. { posinfo is not relevant for changes in PPU }
  196. oldcrc:=do_crc;
  197. do_crc:=false;
  198. {
  199. info byte layout in bits:
  200. 0-1 - amount of bytes for fileindex
  201. 2-3 - amount of bytes for line
  202. 4-5 - amount of bytes for column
  203. }
  204. info:=0;
  205. { calculate info byte }
  206. if (p.fileindex>$ff) then
  207. begin
  208. if (p.fileindex<=$ffff) then
  209. info:=info or $1
  210. else
  211. if (p.fileindex<=$ffffff) then
  212. info:=info or $2
  213. else
  214. info:=info or $3;
  215. end;
  216. if (p.line>$ff) then
  217. begin
  218. if (p.line<=$ffff) then
  219. info:=info or $4
  220. else
  221. if (p.line<=$ffffff) then
  222. info:=info or $8
  223. else
  224. info:=info or $c;
  225. end;
  226. if (p.column>$ff) then
  227. begin
  228. if (p.column<=$ffff) then
  229. info:=info or $10
  230. else
  231. if (p.column<=$ffffff) then
  232. info:=info or $20
  233. else
  234. info:=info or $30;
  235. end;
  236. { write data }
  237. putbyte(info);
  238. case (info and $03) of
  239. 0 : putbyte(p.fileindex);
  240. 1 : putword(p.fileindex);
  241. 2 : begin
  242. putbyte(p.fileindex shr 16);
  243. putword(p.fileindex and $ffff);
  244. end;
  245. 3 : putlongint(p.fileindex);
  246. end;
  247. case ((info shr 2) and $03) of
  248. 0 : putbyte(p.line);
  249. 1 : putword(p.line);
  250. 2 : begin
  251. putbyte(p.line shr 16);
  252. putword(p.line and $ffff);
  253. end;
  254. 3 : putlongint(p.line);
  255. end;
  256. case ((info shr 4) and $03) of
  257. 0 : putbyte(p.column);
  258. 1 : putword(p.column);
  259. 2 : begin
  260. putbyte(p.column shr 16);
  261. putword(p.column and $ffff);
  262. end;
  263. 3 : putlongint(p.column);
  264. end;
  265. do_crc:=oldcrc;
  266. end;
  267. procedure tcompilerppufile.putguid(const g: tguid);
  268. begin
  269. putdata(g,sizeof(g));
  270. end;
  271. procedure tcompilerppufile.putexprint(v:tconstexprint);
  272. begin
  273. if sizeof(TConstExprInt)=8 then
  274. begin
  275. putlongint(longint(lo(v)));
  276. putlongint(longint(hi(v)));
  277. end
  278. else if sizeof(TConstExprInt)=4 then
  279. putlongint(longint(v))
  280. else
  281. internalerror(2002082601);
  282. end;
  283. procedure tcompilerppufile.PutPtrUInt(v:TConstPtrUInt);
  284. begin
  285. if sizeof(TConstPtrUInt)=8 then
  286. begin
  287. putlongint(longint(lo(v)));
  288. putlongint(longint(hi(v)));
  289. end
  290. else if sizeof(TConstPtrUInt)=4 then
  291. putlongint(longint(v))
  292. else
  293. internalerror(2002082601);
  294. end;
  295. procedure tcompilerppufile.putderef(const d:tderef);
  296. var
  297. oldcrc : boolean;
  298. begin
  299. oldcrc:=do_crc;
  300. do_crc:=false;
  301. putlongint(d.dataidx);
  302. do_crc:=oldcrc;
  303. end;
  304. procedure tcompilerppufile.putsymlist(p:tsymlist);
  305. var
  306. hp : psymlistitem;
  307. begin
  308. putderef(p.procdefderef);
  309. hp:=p.firstsym;
  310. while assigned(hp) do
  311. begin
  312. putbyte(byte(hp^.sltype));
  313. case hp^.sltype of
  314. sl_call,
  315. sl_load,
  316. sl_subscript :
  317. putderef(hp^.symderef);
  318. sl_vec :
  319. putlongint(hp^.value);
  320. else
  321. internalerror(200110205);
  322. end;
  323. hp:=hp^.next;
  324. end;
  325. putbyte(byte(sl_none));
  326. end;
  327. procedure tcompilerppufile.puttype(const t:ttype);
  328. begin
  329. putderef(t.deref);
  330. end;
  331. procedure tcompilerppufile.putasmsymbol(s:tasmsymbol);
  332. begin
  333. if assigned(s) then
  334. begin
  335. if s.ppuidx=-1 then
  336. begin
  337. inc(objectlibrary.asmsymbolppuidx);
  338. s.ppuidx:=objectlibrary.asmsymbolppuidx;
  339. end;
  340. putlongint(s.ppuidx);
  341. end
  342. else
  343. putlongint(0);
  344. end;
  345. end.
  346. {
  347. $Log$
  348. Revision 1.22 2003-10-23 14:44:07 peter
  349. * splitted buildderef and buildderefimpl to fix interface crc
  350. calculation
  351. Revision 1.21 2003/10/22 20:40:00 peter
  352. * write derefdata in a separate ppu entry
  353. Revision 1.20 2003/10/07 16:06:30 peter
  354. * tsymlist.def renamed to tsymlist.procdef
  355. * tsymlist.procdef is now only used to store the procdef
  356. Revision 1.19 2003/06/07 20:26:32 peter
  357. * re-resolving added instead of reloading from ppu
  358. * tderef object added to store deref info for resolving
  359. Revision 1.18 2002/12/21 13:07:34 peter
  360. * type redefine fix for tb0437
  361. Revision 1.17 2002/10/05 12:43:29 carl
  362. * fixes for Delphi 6 compilation
  363. (warning : Some features do not work under Delphi)
  364. Revision 1.16 2002/08/26 14:05:57 pierre
  365. * fixed compilation cycle with -Cr option by adding explicit
  366. longint typecast in PutPtrUInt and putexprint methods.
  367. + added checks for sizeof and internalerros if size is not handled.
  368. Revision 1.15 2002/08/18 20:06:26 peter
  369. * inlining is now also allowed in interface
  370. * renamed write/load to ppuwrite/ppuload
  371. * tnode storing in ppu
  372. * nld,ncon,nbas are already updated for storing in ppu
  373. Revision 1.14 2002/08/11 14:32:28 peter
  374. * renamed current_library to objectlibrary
  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. }