symppu.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  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.defderef);
  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.def,p.defderef);
  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.19 2003-06-07 20:26:32 peter
  362. * re-resolving added instead of reloading from ppu
  363. * tderef object added to store deref info for resolving
  364. Revision 1.18 2002/12/21 13:07:34 peter
  365. * type redefine fix for tb0437
  366. Revision 1.17 2002/10/05 12:43:29 carl
  367. * fixes for Delphi 6 compilation
  368. (warning : Some features do not work under Delphi)
  369. Revision 1.16 2002/08/26 14:05:57 pierre
  370. * fixed compilation cycle with -Cr option by adding explicit
  371. longint typecast in PutPtrUInt and putexprint methods.
  372. + added checks for sizeof and internalerros if size is not handled.
  373. Revision 1.15 2002/08/18 20:06:26 peter
  374. * inlining is now also allowed in interface
  375. * renamed write/load to ppuwrite/ppuload
  376. * tnode storing in ppu
  377. * nld,ncon,nbas are already updated for storing in ppu
  378. Revision 1.14 2002/08/11 14:32:28 peter
  379. * renamed current_library to objectlibrary
  380. Revision 1.13 2002/08/11 13:24:14 peter
  381. * saving of asmsymbols in ppu supported
  382. * asmsymbollist global is removed and moved into a new class
  383. tasmlibrarydata that will hold the info of a .a file which
  384. corresponds with a single module. Added librarydata to tmodule
  385. to keep the library info stored for the module. In the future the
  386. objectfiles will also be stored to the tasmlibrarydata class
  387. * all getlabel/newasmsymbol and friends are moved to the new class
  388. Revision 1.12 2002/05/18 13:34:18 peter
  389. * readded missing revisions
  390. Revision 1.11 2002/05/16 19:46:45 carl
  391. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  392. + try to fix temp allocation (still in ifdef)
  393. + generic constructor calls
  394. + start of tassembler / tmodulebase class cleanup
  395. Revision 1.9 2002/05/12 16:53:15 peter
  396. * moved entry and exitcode to ncgutil and cgobj
  397. * foreach gets extra argument for passing local data to the
  398. iterator function
  399. * -CR checks also class typecasts at runtime by changing them
  400. into as
  401. * fixed compiler to cycle with the -CR option
  402. * fixed stabs with elf writer, finally the global variables can
  403. be watched
  404. * removed a lot of routines from cga unit and replaced them by
  405. calls to cgobj
  406. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  407. u32bit then the other is typecasted also to u32bit without giving
  408. a rangecheck warning/error.
  409. * fixed pascal calling method with reversing also the high tree in
  410. the parast, detected by tcalcst3 test
  411. Revision 1.8 2002/04/19 15:40:40 peter
  412. * optimize tfileposinfo writing, this reduces the ppu size with 20%
  413. }