entfile.pas 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953
  1. {
  2. Copyright (c) 1998-2013 by Free Pascal development team
  3. Routines to read/write entry based files (ppu, pcp)
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit entfile;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. systems,globtype,constexp,cstreams;
  22. const
  23. { buffer sizes }
  24. maxentrysize = 1024;
  25. // Unused, and wrong as there are entries that are larger then 1024 bytes
  26. entryfilebufsize = 16384;
  27. {ppu entries}
  28. mainentryid = 1;
  29. subentryid = 2;
  30. {special}
  31. iberror = 0;
  32. ibextraheader = 242;
  33. ibpputable = 243;
  34. ibstartrequireds = 244;
  35. ibendrequireds = 245;
  36. ibstartcontained = 246;
  37. ibendcontained = 247;
  38. ibstartdefs = 248;
  39. ibenddefs = 249;
  40. ibstartsyms = 250;
  41. ibendsyms = 251;
  42. ibendinterface = 252;
  43. ibendimplementation = 253;
  44. // ibendbrowser = 254;
  45. ibend = 255;
  46. {general}
  47. ibmodulename = 1;
  48. ibsourcefiles = 2;
  49. ibloadunit = 3;
  50. ibinitunit = 4;
  51. iblinkunitofiles = 5;
  52. iblinkunitstaticlibs = 6;
  53. iblinkunitsharedlibs = 7;
  54. iblinkotherofiles = 8;
  55. iblinkotherstaticlibs = 9;
  56. iblinkothersharedlibs = 10;
  57. ibImportSymbols = 11;
  58. ibsymref = 12;
  59. ibdefref = 13;
  60. ibfeatures = 14;
  61. {$IFDEF MACRO_DIFF_HINT}
  62. ibusedmacros = 16;
  63. {$ENDIF}
  64. ibderefdata = 17;
  65. ibexportedmacros = 18;
  66. ibderefmap = 19;
  67. {syms}
  68. ibtypesym = 20;
  69. ibprocsym = 21;
  70. ibstaticvarsym = 22;
  71. ibconstsym = 23;
  72. ibenumsym = 24;
  73. // ibtypedconstsym = 25;
  74. ibabsolutevarsym = 26;
  75. ibpropertysym = 27;
  76. ibfieldvarsym = 28;
  77. ibunitsym = 29;
  78. iblabelsym = 30;
  79. ibsyssym = 31;
  80. ibnamespacesym = 32;
  81. iblocalvarsym = 33;
  82. ibparavarsym = 34;
  83. ibmacrosym = 35;
  84. {definitions}
  85. iborddef = 40;
  86. ibpointerdef = 41;
  87. ibarraydef = 42;
  88. ibprocdef = 43;
  89. ibshortstringdef = 44;
  90. ibrecorddef = 45;
  91. ibfiledef = 46;
  92. ibformaldef = 47;
  93. ibobjectdef = 48;
  94. ibenumdef = 49;
  95. ibsetdef = 50;
  96. ibprocvardef = 51;
  97. ibfloatdef = 52;
  98. ibclassrefdef = 53;
  99. iblongstringdef = 54;
  100. ibansistringdef = 55;
  101. ibwidestringdef = 56;
  102. ibvariantdef = 57;
  103. ibundefineddef = 58;
  104. ibunicodestringdef = 59;
  105. {implementation/ObjData}
  106. ibnodetree = 80;
  107. ibasmsymbols = 81;
  108. ibresources = 82;
  109. ibcreatedobjtypes = 83;
  110. ibwpofile = 84;
  111. ibmoduleoptions = 85;
  112. ibunitimportsyms = 86;
  113. iborderedsymbols = 87;
  114. ibmainname = 90;
  115. ibsymtableoptions = 91;
  116. ibpackagefiles = 92;
  117. ibpackagename = 93;
  118. ibrecsymtableoptions = 94;
  119. { target-specific things }
  120. iblinkotherframeworks = 100;
  121. ibjvmnamespace = 101;
  122. {$ifdef generic_cpu}
  123. { We need to use the correct size of aint and pint for
  124. the target CPU }
  125. const
  126. CpuAddrBitSize : array[tsystemcpu] of longint =
  127. (
  128. { 0 } 32 {'none'},
  129. { 1 } 32 {'i386'},
  130. { 2 } 32 {'m68k'},
  131. { 3 } 32 {'alpha'},
  132. { 4 } 32 {'powerpc'},
  133. { 5 } 32 {'sparc'},
  134. { 6 } 32 {'vis'},
  135. { 7 } 64 {'ia64'},
  136. { 8 } 64 {'x86_64'},
  137. { 9 } 32 {'mipseb'},
  138. { 10 } 32 {'arm'},
  139. { 11 } 64 {'powerpc64'},
  140. { 12 } 16 {'avr'},
  141. { 13 } 32 {'mipsel'},
  142. { 14 } 32 {'jvm'},
  143. { 15 } 16 {'i8086'},
  144. { 16 } 64 {'aarch64'},
  145. { 17 } 32 {'wasm'},
  146. { 18 } 64 {'sparc64'},
  147. { 19 } 32 {'riscv32'},
  148. { 20 } 64 {'riscv64'}
  149. );
  150. CpuAluBitSize : array[tsystemcpu] of longint =
  151. (
  152. { 0 } 32 {'none'},
  153. { 1 } 32 {'i386'},
  154. { 2 } 32 {'m68k'},
  155. { 3 } 32 {'alpha'},
  156. { 4 } 32 {'powerpc'},
  157. { 5 } 32 {'sparc'},
  158. { 6 } 32 {'vis'},
  159. { 7 } 64 {'ia64'},
  160. { 8 } 64 {'x86_64'},
  161. { 9 } 32 {'mipseb'},
  162. { 10 } 32 {'arm'},
  163. { 11 } 64 {'powerpc64'},
  164. { 12 } 8 {'avr'},
  165. { 13 } 32 {'mipsel'},
  166. { 14 } 64 {'jvm'},
  167. { 15 } 16 {'i8086'},
  168. { 16 } 64 {'aarch64'},
  169. { 17 } 64 {'wasm'},
  170. { 18 } 64 {'sparc64'},
  171. { 19 } 32 {'riscv32'},
  172. { 20 } 64 {'riscv64'}
  173. );
  174. {$endif generic_cpu}
  175. type
  176. { bestreal is defined based on the target architecture }
  177. entryreal=bestreal;
  178. { common part of the header for all kinds of entry files }
  179. tentryheader=record
  180. id : array[1..3] of char;
  181. ver : array[1..3] of char;
  182. compiler : word;
  183. cpu : word;
  184. target : word;
  185. flags : dword;
  186. size : dword; { size of the ppufile without header }
  187. end;
  188. pentryheader=^tentryheader;
  189. tentry=packed record
  190. size : longint;
  191. id : byte;
  192. nr : byte;
  193. end;
  194. tentryfile=class
  195. private
  196. function getposition:longint;
  197. procedure setposition(value:longint);
  198. protected
  199. buf : pchar;
  200. bufstart,
  201. bufsize,
  202. bufidx : integer;
  203. entrybufstart,
  204. entrystart,
  205. entryidx : integer;
  206. entry : tentry;
  207. closed,
  208. tempclosed : boolean;
  209. closepos : integer;
  210. protected
  211. f : TCStream;
  212. {$ifdef DEBUG_PPU}
  213. flog : text;
  214. flog_open : boolean;
  215. ppu_log_level : longint;
  216. ppu_log_idx : integer;
  217. {$endif}
  218. mode : byte; {0 - Closed, 1 - Reading, 2 - Writing}
  219. fisfile : boolean;
  220. fname : string;
  221. fsize : integer;
  222. procedure newheader;virtual;abstract;
  223. function readheader:longint;virtual;abstract;
  224. function outputallowed:boolean;virtual;
  225. procedure resetfile;virtual;abstract;
  226. function getheadersize:longint;virtual;abstract;
  227. function getheaderaddr:pentryheader;virtual;abstract;
  228. procedure RaiseAssertion(Code: Longint); virtual;
  229. public
  230. entrytyp : byte;
  231. size : integer;
  232. change_endian : boolean; { Used in ppudump util }
  233. {$ifdef generic_cpu}
  234. has_more,
  235. {$endif not generic_cpu}
  236. error : boolean;
  237. constructor create(const fn:string);
  238. destructor destroy;override;
  239. function getversion:integer;
  240. procedure flush; {$ifdef USEINLINE}inline;{$endif}
  241. procedure closefile;virtual;
  242. procedure newentry;
  243. property position:longint read getposition write setposition;
  244. { Warning: don't keep the stream open during a tempclose! }
  245. function substream(ofs,len:longint):TCStream;
  246. { Warning: don't use the put* or write* functions anymore when writing through this }
  247. property stream:TCStream read f;
  248. {$ifdef DEBUG_PPU}
  249. procedure ppu_log(st :string);virtual;
  250. procedure ppu_log_val(st :string);virtual;
  251. procedure inc_log_level;
  252. procedure dec_log_level;
  253. {$endif}
  254. {read}
  255. function openfile:boolean;
  256. function openstream(strm:TCStream):boolean;
  257. procedure reloadbuf;
  258. procedure readdata(out b;len:integer);
  259. procedure skipdata(len:integer);
  260. function readentry:byte;
  261. function EndOfEntry:boolean; {$ifdef USEINLINE}inline;{$endif}
  262. function entrysize:longint; {$ifdef USEINLINE}inline;{$endif}
  263. function entryleft:longint; {$ifdef USEINLINE}inline;{$endif}
  264. procedure getdatabuf(out b;len:integer;out res:integer);
  265. procedure getdata(out b;len:integer);
  266. function getbyte:byte;
  267. function getword:word;
  268. function getdword:dword;
  269. function getlongint:longint;
  270. function getint64:int64;
  271. function getqword:qword;
  272. function getaint:{$ifdef generic_cpu}int64{$else}aint{$ifdef USEINLINE}; inline{$endif}{$endif};
  273. function getasizeint:{$ifdef generic_cpu}int64{$else}asizeint{$ifdef USEINLINE}; inline{$endif}{$endif};
  274. function getpuint:{$ifdef generic_cpu}qword{$else}puint{$ifdef USEINLINE}; inline{$endif}{$endif};
  275. function getptruint:{$ifdef generic_cpu}qword{$else}TConstPtrUInt{$ifdef USEINLINE}; inline{$endif}{$endif};
  276. function getaword:{$ifdef generic_cpu}qword{$else}aword{$ifdef USEINLINE}; inline{$endif}{$endif};
  277. function getreal:entryreal;
  278. function getrealsize(sizeofreal : longint):entryreal;
  279. function getboolean:boolean; {$ifdef USEINLINE}inline;{$endif}
  280. function getstring:string;
  281. function getpshortstring:pshortstring;
  282. function getansistring:ansistring;
  283. procedure getnormalset(out b);
  284. procedure getsmallset(out b);
  285. function skipuntilentry(untilb:byte):boolean;
  286. {write}
  287. function createfile:boolean;virtual;
  288. function createstream(strm:TCStream):boolean;
  289. procedure writeheader;virtual;abstract;
  290. procedure writebuf;
  291. procedure writedata(const b;len:integer);
  292. procedure writeentry(ibnr:byte);
  293. procedure putdata(const b;len:integer);virtual;
  294. procedure putbyte(b:byte); {$ifdef USEINLINE}inline;{$endif}
  295. procedure putword(w:word); {$ifdef USEINLINE}inline;{$endif}
  296. procedure putdword(w:dword); {$ifdef USEINLINE}inline;{$endif}
  297. procedure putlongint(l:longint); {$ifdef USEINLINE}inline;{$endif}
  298. procedure putint64(i:int64); {$ifdef USEINLINE}inline;{$endif}
  299. procedure putqword(q:qword); {$ifdef USEINLINE}inline;{$endif}
  300. procedure putaint(i:aint); {$ifdef USEINLINE}inline;{$endif}
  301. procedure putasizeint(i:asizeint); {$ifdef USEINLINE}inline;{$endif}
  302. procedure putpuint(i:puint); {$ifdef USEINLINE}inline;{$endif}
  303. procedure putptruint(v:TConstPtrUInt); {$ifdef USEINLINE}inline;{$endif}
  304. procedure putaword(i:aword); {$ifdef USEINLINE}inline;{$endif}
  305. procedure putreal(d:entryreal);
  306. procedure putboolean(b:boolean); {$ifdef USEINLINE}inline;{$endif}
  307. procedure putstring(const s:string); {$ifdef USEINLINE}inline;{$endif}
  308. procedure putansistring(const s:ansistring);
  309. procedure putnormalset(const b); {$ifdef USEINLINE}inline;{$endif}
  310. procedure putsmallset(const b); {$ifdef USEINLINE}inline;{$endif}
  311. procedure tempclose; // MG: not used, obsolete?
  312. function tempopen:boolean; // MG: not used, obsolete?
  313. end;
  314. implementation
  315. uses
  316. cutils;
  317. function swapendian_entryreal(d:entryreal):entryreal;
  318. type
  319. entryreal_bytes=array[0..sizeof(d)-1] of byte;
  320. var
  321. i:0..sizeof(d)-1;
  322. begin
  323. for i:=low(entryreal_bytes) to high(entryreal_bytes) do
  324. entryreal_bytes(result)[i]:=entryreal_bytes(d)[high(entryreal_bytes)-i];
  325. end;
  326. {*****************************************************************************
  327. tentryfile
  328. *****************************************************************************}
  329. function tentryfile.outputallowed: boolean;
  330. begin
  331. result:=true;
  332. end;
  333. constructor tentryfile.create(const fn:string);
  334. begin
  335. fname:=fn;
  336. fisfile:=false;
  337. change_endian:=false;
  338. mode:=0;
  339. newheader;
  340. error:=false;
  341. closed:=true;
  342. tempclosed:=false;
  343. getmem(buf,entryfilebufsize);
  344. {$ifdef DEBUG_PPU}
  345. assign(flog,fn+'.debug-log');
  346. flog_open:=false;
  347. {$endif DEBUG_PPU}
  348. end;
  349. destructor tentryfile.destroy;
  350. begin
  351. closefile;
  352. if assigned(buf) then
  353. freemem(buf,entryfilebufsize);
  354. end;
  355. {$ifdef DEBUG_PPU}
  356. function entryid_name(nr : byte) : string;
  357. begin
  358. case nr of
  359. {ppu entries}
  360. mainentryid: entryid_name:='main_entry_id';
  361. subentryid: entryid_name:='sub_entry_id';
  362. else
  363. entryid_name:='unknown entryid '+tostr(nr);
  364. end;
  365. end;
  366. function entry_name(nr : byte) : string;
  367. begin
  368. case nr of
  369. {special}
  370. iberror: entry_name:='iberror';
  371. ibextraheader: entry_name:='ibextraheader';
  372. ibpputable: entry_name:='ibpputable';
  373. ibstartrequireds: entry_name:='ibstartrequireds';
  374. ibendrequireds: entry_name:='ibendrequireds';
  375. ibstartcontained: entry_name:='ibstartcontained';
  376. ibendcontained: entry_name:='ibendcontained';
  377. ibstartdefs: entry_name:='ibstartdefs';
  378. ibenddefs: entry_name:='ibenddefs';
  379. ibstartsyms: entry_name:='ibstartsyms';
  380. ibendsyms: entry_name:='ibendsyms';
  381. ibendinterface: entry_name:='ibendinterface';
  382. ibendimplementation: entry_name:='ibendimplementation';
  383. // ibendbrowser: entry_name:='ibendbrowser';
  384. ibend: entry_name:='ibend';
  385. {general}
  386. ibmodulename: entry_name:='ibmodulename';
  387. ibsourcefiles: entry_name:='ibsourcefiles';
  388. ibloadunit: entry_name:='ibloadunit';
  389. ibinitunit: entry_name:='ibinitunit';
  390. iblinkunitofiles: entry_name:='iblinkunitofiles';
  391. iblinkunitstaticlibs: entry_name:='iblinkunitstaticlibs';
  392. iblinkunitsharedlibs: entry_name:='iblinkunitsharedlibs';
  393. iblinkotherofiles: entry_name:='iblinkotherofiles';
  394. iblinkotherstaticlibs: entry_name:='iblinkotherstaticlibs';
  395. iblinkothersharedlibs: entry_name:='iblinkothersharedlibs';
  396. ibImportSymbols: entry_name:='ibImportSymbols';
  397. ibsymref: entry_name:='ibsymref';
  398. ibdefref: entry_name:='ibdefref';
  399. ibfeatures: entry_name:='ibfeatures';
  400. {$IFDEF MACRO_DIFF_HINT}
  401. ibusedmacros: entry_name:='ibusedmacros';
  402. {$ENDIF}
  403. ibderefdata: entry_name:='ibderefdata';
  404. ibexportedmacros: entry_name:='ibexportedmacros';
  405. ibderefmap: entry_name:='ibderefmap';
  406. {syms}
  407. ibtypesym: entry_name:='ibtypesym';
  408. ibprocsym: entry_name:='ibprocsym';
  409. ibstaticvarsym: entry_name:='ibstaticvarsym';
  410. ibconstsym: entry_name:='ibconstsym';
  411. ibenumsym: entry_name:='ibenumsym';
  412. // ibtypedconstsym: entry_name:='ibtypedconstsym';
  413. ibabsolutevarsym: entry_name:='ibabsolutevarsym';
  414. ibpropertysym: entry_name:='ibpropertysym';
  415. ibfieldvarsym: entry_name:='ibfieldvarsym';
  416. ibunitsym: entry_name:='ibunitsym';
  417. iblabelsym: entry_name:='iblabelsym';
  418. ibsyssym: entry_name:='ibsyssym';
  419. ibnamespacesym: entry_name:='ibnamespacesym';
  420. iblocalvarsym: entry_name:='iblocalvarsym';
  421. ibparavarsym: entry_name:='ibparavarsym';
  422. ibmacrosym: entry_name:='ibmacrosym';
  423. {definitions}
  424. iborddef: entry_name:='iborddef';
  425. ibpointerdef: entry_name:='ibpointerdef';
  426. ibarraydef: entry_name:='ibarraydef';
  427. ibprocdef: entry_name:='ibprocdef';
  428. ibshortstringdef: entry_name:='ibshortstringdef';
  429. ibrecorddef: entry_name:='ibrecorddef';
  430. ibfiledef: entry_name:='ibfiledef';
  431. ibformaldef: entry_name:='ibformaldef';
  432. ibobjectdef: entry_name:='ibobjectdef';
  433. ibenumdef: entry_name:='ibenumdef';
  434. ibsetdef: entry_name:='ibsetdef';
  435. ibprocvardef: entry_name:='ibprocvardef';
  436. ibfloatdef: entry_name:='ibfloatdef';
  437. ibclassrefdef: entry_name:='ibclassrefdef';
  438. iblongstringdef: entry_name:='iblongstringdef';
  439. ibansistringdef: entry_name:='ibansistringdef';
  440. ibwidestringdef: entry_name:='ibwidestringdef';
  441. ibvariantdef: entry_name:='ibvariantdef';
  442. ibundefineddef: entry_name:='ibundefineddef';
  443. ibunicodestringdef: entry_name:='ibunicodestringdef';
  444. {implementation/ObjData}
  445. ibnodetree: entry_name:='ibnodetree';
  446. ibasmsymbols: entry_name:='ibasmsymbols';
  447. ibresources: entry_name:='ibresources';
  448. ibcreatedobjtypes: entry_name:='ibcreatedobjtypes';
  449. ibwpofile: entry_name:='ibwpofile';
  450. ibmoduleoptions: entry_name:='ibmoduleoptions';
  451. ibunitimportsyms: entry_name:='ibunitimportsyms';
  452. iborderedsymbols: entry_name:='iborderedsymbols';
  453. ibmainname: entry_name:='ibmainname';
  454. ibsymtableoptions: entry_name:='ibsymtableoptions';
  455. // ibrecsymtableoptions: entry_name:='ibrecsymtableoptions';
  456. ibpackagefiles: entry_name:='ibpackagefiles';
  457. ibpackagename: entry_name:='ibpackagename';
  458. { target-specific things }
  459. iblinkotherframeworks: entry_name:='iblinkotherframeworks';
  460. ibjvmnamespace: entry_name:='ibjvmnamespace';
  461. else
  462. entry_name:='unknown entry '+tostr(nr);
  463. end;
  464. end;
  465. procedure tentryfile.ppu_log(st :string);
  466. begin
  467. if flog_open then
  468. begin
  469. writeln(flog,bufstart+bufidx,': ',st);
  470. end;
  471. {$ifdef IN_PPUDUMP}
  472. writeln(bufstart+bufidx,': ',st);
  473. {$endif}
  474. end;
  475. procedure tentryfile.inc_log_level;
  476. begin
  477. inc(ppu_log_level);
  478. end;
  479. procedure tentryfile.ppu_log_val(st :string);
  480. begin
  481. if flog_open then
  482. begin
  483. writeln(flog,'(',ppu_log_level,') value: ',st);
  484. end;
  485. {$ifdef IN_PPUDUMP}
  486. writeln('(',ppu_log_level,') value: ',st);
  487. {$endif}
  488. end;
  489. procedure tentryfile.dec_log_level;
  490. begin
  491. dec(ppu_log_level);
  492. end;
  493. {$endif}
  494. function tentryfile.getversion:integer;
  495. var
  496. l : integer;
  497. code : integer;
  498. header : pentryheader;
  499. begin
  500. header:=getheaderaddr;
  501. Val(header^.ver[1]+header^.ver[2]+header^.ver[3],l,code);
  502. if code=0 then
  503. result:=l
  504. else
  505. result:=0;
  506. end;
  507. procedure tentryfile.flush;
  508. begin
  509. if mode=2 then
  510. writebuf;
  511. end;
  512. procedure tentryfile.RaiseAssertion(Code: Longint);
  513. begin
  514. { It's down to descendent classes to raise an internal error as desired. [Kit] }
  515. error := true;
  516. end;
  517. procedure tentryfile.closefile;
  518. begin
  519. if mode<>0 then
  520. begin
  521. flush;
  522. {$ifdef DEBUG_PPU}
  523. if (entry.nr<>0) and (mode=1) then
  524. ppu_log('writeentry, id='+entryid_name(entry.id)+' nr='+entry_name(entry.nr)+' size='+tostr(entry.size));
  525. {$endif}
  526. if fisfile then
  527. f.Free;
  528. mode:=0;
  529. closed:=true;
  530. {$ifdef DEBUG_PPU}
  531. if flog_open then
  532. close(flog);
  533. flog_open:=false;
  534. {$endif DEBUG_PPU}
  535. end;
  536. end;
  537. procedure tentryfile.setposition(value:longint);
  538. begin
  539. if assigned(f) then
  540. f.Position:=value
  541. else
  542. if tempclosed then
  543. closepos:=value;
  544. end;
  545. function tentryfile.getposition:longint;
  546. begin
  547. if assigned(f) then
  548. result:=f.Position
  549. else
  550. if tempclosed then
  551. result:=closepos
  552. else
  553. result:=0;
  554. end;
  555. function tentryfile.substream(ofs,len:longint):TCStream;
  556. begin
  557. result:=nil;
  558. if assigned(f) then
  559. result:=TCRangeStream.Create(f,ofs,len);
  560. end;
  561. {*****************************************************************************
  562. tentryfile Reading
  563. *****************************************************************************}
  564. function tentryfile.openfile:boolean;
  565. var
  566. strm : TCStream;
  567. begin
  568. openfile:=false;
  569. try
  570. strm:=CFileStreamClass.Create(fname,fmOpenRead)
  571. except
  572. exit;
  573. end;
  574. openfile:=openstream(strm);
  575. fisfile:=result;
  576. end;
  577. function tentryfile.openstream(strm:TCStream):boolean;
  578. var
  579. i : longint;
  580. begin
  581. openstream:=false;
  582. f:=strm;
  583. closed:=false;
  584. {$ifdef DEBUG_PPU}
  585. {$push}
  586. {$I-}
  587. assign(flog,fname+'.debug-read-log');
  588. rewrite(flog);
  589. if InOutRes=0 then
  590. flog_open:=true;
  591. {$pop}
  592. {$endif DEBUG_PPU}
  593. {read ppuheader}
  594. fsize:=f.Size;
  595. i:=readheader;
  596. if i<0 then
  597. exit;
  598. {reset buffer}
  599. bufstart:=i;
  600. bufsize:=0;
  601. bufidx:=0;
  602. mode:=1;
  603. FillChar(entry,sizeof(tentry),0);
  604. entryidx:=0;
  605. entrystart:=0;
  606. entrybufstart:=0;
  607. error:=false;
  608. openstream:=true;
  609. end;
  610. procedure tentryfile.reloadbuf;
  611. begin
  612. inc(bufstart,bufsize);
  613. bufsize:=f.Read(buf^,entryfilebufsize);
  614. bufidx:=0;
  615. end;
  616. procedure tentryfile.readdata(out b;len:integer);
  617. var
  618. p,pbuf : pchar;
  619. left : integer;
  620. {$ifdef DEBUG_PPU}
  621. i : integer;
  622. {$endif DEBUG_PPU}
  623. begin
  624. p:=pchar(@b);
  625. pbuf:=@buf[bufidx];
  626. {$ifdef DEBUG_PPU}
  627. if ppu_log_level <= 0 then
  628. begin
  629. ppu_log('writedata, length='+tostr(len)+' level='+tostr(ppu_log_level));
  630. for i:=0 to len-1 do
  631. ppu_log_val('p['+tostr(i)+']=$'+hexstr(byte(p[i]),2));
  632. end;
  633. {$endif DEBUG_PPU}
  634. repeat
  635. left:=bufsize-bufidx;
  636. if len<left then
  637. break;
  638. move(pbuf^,p^,left);
  639. dec(len,left);
  640. inc(p,left);
  641. reloadbuf;
  642. pbuf:=@buf[bufidx];
  643. if bufsize=0 then
  644. exit;
  645. until false;
  646. move(pbuf^,p^,len);
  647. inc(bufidx,len);
  648. end;
  649. procedure tentryfile.skipdata(len:integer);
  650. var
  651. left : integer;
  652. begin
  653. {$ifdef DEBUG_PPU}
  654. if len>0 then
  655. ppu_log('explicit skipdata '+tostr(len));
  656. {$endif}
  657. while len>0 do
  658. begin
  659. left:=bufsize-bufidx;
  660. if len>left then
  661. begin
  662. dec(len,left);
  663. reloadbuf;
  664. if bufsize=0 then
  665. exit;
  666. end
  667. else
  668. begin
  669. inc(bufidx,len);
  670. exit;
  671. end;
  672. end;
  673. end;
  674. function tentryfile.readentry:byte;
  675. begin
  676. if entryidx<entry.size then
  677. begin
  678. {$ifdef generic_cpu}
  679. has_more:=true;
  680. {$endif not generic_cpu}
  681. {$ifdef DEBUG_PPU}
  682. if entry.size-entryidx>0 then
  683. ppu_log('skipdata '+tostr(entry.size-entryidx));
  684. {$endif}
  685. skipdata(entry.size-entryidx);
  686. end;
  687. {$ifdef DEBUG_PPU}
  688. if entry.nr<>0 then
  689. ppu_log('writeentry, id='+entryid_name(entry.id)+' nr='+entry_name(entry.nr)+' size='+tostr(entry.size));
  690. ppu_log('entrystart');
  691. {$endif}
  692. readdata(entry,sizeof(tentry));
  693. if change_endian then
  694. entry.size:=swapendian(entry.size);
  695. entrystart:=bufstart+bufidx;
  696. entryidx:=0;
  697. {$ifdef generic_cpu}
  698. has_more:=false;
  699. {$endif not generic_cpu}
  700. if not(entry.id in [mainentryid,subentryid]) then
  701. begin
  702. readentry:=iberror;
  703. error:=true;
  704. exit;
  705. end;
  706. readentry:=entry.nr;
  707. end;
  708. function tentryfile.endofentry:boolean;
  709. begin
  710. {$ifdef generic_cpu}
  711. endofentry:=(entryidx=entry.size);
  712. {$else not generic_cpu}
  713. endofentry:=(entryidx>=entry.size);
  714. {$endif not generic_cpu}
  715. end;
  716. function tentryfile.entrysize:longint;
  717. begin
  718. entrysize:=entry.size;
  719. end;
  720. function tentryfile.entryleft:longint;
  721. begin
  722. entryleft:=entry.size-entryidx;
  723. end;
  724. procedure tentryfile.getdatabuf(out b;len:integer;out res:integer);
  725. begin
  726. if entryidx+len>entry.size then
  727. res:=entry.size-entryidx
  728. else
  729. res:=len;
  730. readdata(b,res);
  731. inc(entryidx,res);
  732. end;
  733. procedure tentryfile.getdata(out b;len:integer);
  734. begin
  735. if entryidx+len>entry.size then
  736. begin
  737. error:=true;
  738. exit;
  739. end;
  740. readdata(b,len);
  741. inc(entryidx,len);
  742. end;
  743. function tentryfile.getbyte:byte;
  744. begin
  745. if entryidx>=entry.size then
  746. begin
  747. error:=true;
  748. result:=0;
  749. exit;
  750. end;
  751. {$ifdef DEBUG_PPU}
  752. ppu_log('putbyte');
  753. inc_log_level;
  754. {$endif}
  755. if bufidx<bufsize then
  756. begin
  757. result:=pbyte(@buf[bufidx])^;
  758. inc(bufidx);
  759. end
  760. else
  761. readdata(result,1);
  762. {$ifdef DEBUG_PPU}
  763. ppu_log_val(tostr(result));
  764. dec_log_level;
  765. {$endif}
  766. inc(entryidx);
  767. end;
  768. function tentryfile.getword:word;
  769. begin
  770. if entryidx+2>entry.size then
  771. begin
  772. error:=true;
  773. result:=0;
  774. exit;
  775. end;
  776. {$ifdef DEBUG_PPU}
  777. ppu_log('putword');
  778. inc_log_level;
  779. {$endif}
  780. if bufsize-bufidx>=sizeof(word) then
  781. begin
  782. result:=Unaligned(pword(@buf[bufidx])^);
  783. inc(bufidx,sizeof(word));
  784. end
  785. else
  786. readdata(result,sizeof(word));
  787. if change_endian then
  788. result:=swapendian(result);
  789. {$ifdef DEBUG_PPU}
  790. ppu_log_val(tostr(result));
  791. dec_log_level;
  792. {$endif}
  793. inc(entryidx,2);
  794. end;
  795. function tentryfile.getlongint:longint;
  796. begin
  797. if entryidx+4>entry.size then
  798. begin
  799. error:=true;
  800. result:=0;
  801. exit;
  802. end;
  803. {$ifdef DEBUG_PPU}
  804. ppu_log('putlongint');
  805. inc_log_level;
  806. {$endif}
  807. if bufsize-bufidx>=sizeof(longint) then
  808. begin
  809. result:=Unaligned(plongint(@buf[bufidx])^);
  810. inc(bufidx,sizeof(longint));
  811. end
  812. else
  813. readdata(result,sizeof(longint));
  814. if change_endian then
  815. result:=swapendian(result);
  816. {$ifdef DEBUG_PPU}
  817. ppu_log_val(tostr(result));
  818. dec_log_level;
  819. {$endif}
  820. inc(entryidx,4);
  821. end;
  822. function tentryfile.getdword:dword;
  823. begin
  824. if entryidx+4>entry.size then
  825. begin
  826. error:=true;
  827. result:=0;
  828. exit;
  829. end;
  830. {$ifdef DEBUG_PPU}
  831. ppu_log('putdword');
  832. inc_log_level;
  833. {$endif}
  834. if bufsize-bufidx>=sizeof(dword) then
  835. begin
  836. result:=Unaligned(pdword(@buf[bufidx])^);
  837. inc(bufidx,sizeof(longint));
  838. end
  839. else
  840. readdata(result,sizeof(dword));
  841. if change_endian then
  842. result:=swapendian(result);
  843. {$ifdef DEBUG_PPU}
  844. ppu_log_val(tostr(result));
  845. dec_log_level;
  846. {$endif}
  847. inc(entryidx,4);
  848. end;
  849. function tentryfile.getint64:int64;
  850. begin
  851. if entryidx+8>entry.size then
  852. begin
  853. error:=true;
  854. result:=0;
  855. exit;
  856. end;
  857. {$ifdef DEBUG_PPU}
  858. ppu_log('putint64');
  859. inc_log_level;
  860. {$endif}
  861. if bufsize-bufidx>=sizeof(int64) then
  862. begin
  863. result:=Unaligned(pint64(@buf[bufidx])^);
  864. inc(bufidx,sizeof(int64));
  865. end
  866. else
  867. readdata(result,sizeof(int64));
  868. if change_endian then
  869. result:=swapendian(result);
  870. {$ifdef DEBUG_PPU}
  871. ppu_log_val(tostr(result));
  872. dec_log_level;
  873. {$endif}
  874. inc(entryidx,8);
  875. end;
  876. function tentryfile.getqword:qword;
  877. begin
  878. if entryidx+8>entry.size then
  879. begin
  880. error:=true;
  881. result:=0;
  882. exit;
  883. end;
  884. {$ifdef DEBUG_PPU}
  885. ppu_log('putqword');
  886. inc_log_level;
  887. {$endif}
  888. if bufsize-bufidx>=sizeof(qword) then
  889. begin
  890. result:=Unaligned(pqword(@buf[bufidx])^);
  891. inc(bufidx,sizeof(qword));
  892. end
  893. else
  894. readdata(result,sizeof(qword));
  895. if change_endian then
  896. result:=swapendian(result);
  897. {$ifdef DEBUG_PPU}
  898. ppu_log_val(tostr(result));
  899. dec_log_level;
  900. {$endif}
  901. inc(entryidx,8);
  902. end;
  903. function tentryfile.getaint:{$ifdef generic_cpu}int64{$else}aint{$endif};
  904. {$ifdef generic_cpu}
  905. var
  906. header : pentryheader;
  907. {$endif generic_cpu}
  908. begin
  909. {$ifdef DEBUG_PPU}
  910. ppu_log('putaint');
  911. inc_log_level;
  912. {$endif}
  913. {$ifdef generic_cpu}
  914. header:=getheaderaddr;
  915. if CpuAluBitSize[tsystemcpu(header^.cpu)]=64 then
  916. result:=getint64
  917. else if CpuAluBitSize[tsystemcpu(header^.cpu)]=32 then
  918. result:=getlongint
  919. else if CpuAluBitSize[tsystemcpu(header^.cpu)]=16 then
  920. result:=smallint(getword)
  921. else if CpuAluBitSize[tsystemcpu(header^.cpu)]=8 then
  922. result:=shortint(getbyte)
  923. else
  924. begin
  925. error:=true;
  926. result:=0;
  927. end;
  928. {$else not generic_cpu}
  929. case sizeof(aint) of
  930. 8: result:=getint64;
  931. 4: result:=getlongint;
  932. 2: result:=smallint(getword);
  933. 1: result:=shortint(getbyte);
  934. else
  935. begin
  936. RaiseAssertion(2019041801);
  937. result:=0;
  938. end;
  939. end;
  940. {$endif not generic_cpu}
  941. {$ifdef DEBUG_PPU}
  942. ppu_log_val(tostr(result));
  943. dec_log_level;
  944. {$endif}
  945. end;
  946. function tentryfile.getasizeint:{$ifdef generic_cpu}int64{$else}asizeint{$endif};
  947. {$ifdef generic_cpu}
  948. var
  949. header : pentryheader;
  950. {$endif generic_cpu}
  951. begin
  952. {$ifdef DEBUG_PPU}
  953. ppu_log('putasizeint');
  954. inc_log_level;
  955. {$endif}
  956. {$ifdef generic_cpu}
  957. header:=getheaderaddr;
  958. if CpuAddrBitSize[tsystemcpu(header^.cpu)]=64 then
  959. result:=getint64
  960. else if CpuAddrBitSize[tsystemcpu(header^.cpu)]=32 then
  961. result:=getlongint
  962. else if CpuAddrBitSize[tsystemcpu(header^.cpu)]=16 then
  963. begin
  964. { result:=smallint(getword);
  965. would have been logical, but it contradicts
  966. definition of asizeint in globtype unit,
  967. which uses 32-bit lngint type even for 16-bit
  968. address size, to be able to cope with
  969. I8086 seg:ofs huge addresses }
  970. result:=getlongint;
  971. end
  972. else
  973. begin
  974. error:=true;
  975. result:=0;
  976. end;
  977. {$else not generic_cpu}
  978. case sizeof(asizeint) of
  979. 8: result:=asizeint(getint64);
  980. 4: result:=asizeint(getlongint);
  981. 2: result:=asizeint(getword);
  982. 1: result:=asizeint(getbyte);
  983. else
  984. begin
  985. RaiseAssertion(2019041802);
  986. result:=0;
  987. end;
  988. end;
  989. {$endif not generic_cpu}
  990. {$ifdef DEBUG_PPU}
  991. ppu_log_val(tostr(result));
  992. dec_log_level;
  993. {$endif}
  994. end;
  995. function tentryfile.getpuint:{$ifdef generic_cpu}qword{$else}puint{$endif};
  996. {$ifdef generic_cpu}
  997. var
  998. header : pentryheader;
  999. {$endif generic_cpu}
  1000. begin
  1001. {$ifdef DEBUG_PPU}
  1002. ppu_log('putpuint');
  1003. inc_log_level;
  1004. {$endif}
  1005. {$ifdef generic_cpu}
  1006. header:=getheaderaddr;
  1007. if CpuAddrBitSize[tsystemcpu(header^.cpu)]=64 then
  1008. result:=getqword
  1009. else if CpuAddrBitSize[tsystemcpu(header^.cpu)]=32 then
  1010. result:=getdword
  1011. else if CpuAddrBitSize[tsystemcpu(header^.cpu)]=16 then
  1012. result:=getword
  1013. else
  1014. begin
  1015. error:=true;
  1016. result:=0;
  1017. end;
  1018. {$else not generic_cpu}
  1019. case sizeof(puint) of
  1020. 8: result:=getqword;
  1021. 4: result:=getdword;
  1022. 2: result:=getword;
  1023. 1: result:=getbyte;
  1024. else
  1025. begin
  1026. RaiseAssertion(2019041803);
  1027. result:=0;
  1028. end;
  1029. end;
  1030. {$endif not generic_cpu}
  1031. {$ifdef DEBUG_PPU}
  1032. ppu_log_val(tostr(result));
  1033. dec_log_level;
  1034. {$endif}
  1035. end;
  1036. function tentryfile.getptruint:{$ifdef generic_cpu}qword{$else}TConstPtrUInt{$endif};
  1037. {$ifdef generic_cpu}
  1038. var
  1039. header : pentryheader;
  1040. {$endif generic_cpu}
  1041. begin
  1042. {$ifdef DEBUG_PPU}
  1043. ppu_log('putptruint');
  1044. inc_log_level;
  1045. {$endif}
  1046. {$ifdef generic_cpu}
  1047. header:=getheaderaddr;
  1048. if CpuAddrBitSize[tsystemcpu(header^.cpu)]=64 then
  1049. result:=getqword
  1050. else result:=getdword;
  1051. {$else not generic_cpu}
  1052. {$if sizeof(TConstPtrUInt)=8}
  1053. result:=tconstptruint(getint64);
  1054. {$else}
  1055. result:=TConstPtrUInt(getlongint);
  1056. {$endif}
  1057. {$endif not generic_cpu}
  1058. {$ifdef DEBUG_PPU}
  1059. ppu_log_val(tostr(result));
  1060. dec_log_level;
  1061. {$endif}
  1062. end;
  1063. function tentryfile.getaword:{$ifdef generic_cpu}qword{$else}aword{$endif};
  1064. {$ifdef generic_cpu}
  1065. var
  1066. header : pentryheader;
  1067. {$endif generic_cpu}
  1068. begin
  1069. {$ifdef DEBUG_PPU}
  1070. ppu_log('putaword');
  1071. inc_log_level;
  1072. {$endif}
  1073. {$ifdef generic_cpu}
  1074. header:=getheaderaddr;
  1075. if CpuAluBitSize[tsystemcpu(header^.cpu)]=64 then
  1076. result:=getqword
  1077. else if CpuAluBitSize[tsystemcpu(header^.cpu)]=32 then
  1078. result:=getdword
  1079. else if CpuAluBitSize[tsystemcpu(header^.cpu)]=16 then
  1080. result:=getword
  1081. else if CpuAluBitSize[tsystemcpu(header^.cpu)]=8 then
  1082. result:=getbyte
  1083. else
  1084. begin
  1085. error:=true;
  1086. result:=0;
  1087. end;
  1088. {$else not generic_cpu}
  1089. case sizeof(aword) of
  1090. 8: result:=getqword;
  1091. 4: result:=getdword;
  1092. 2: result:=getword;
  1093. 1: result:=getbyte;
  1094. else
  1095. begin
  1096. RaiseAssertion(2019041804);
  1097. result:=0;
  1098. end;
  1099. end;
  1100. {$endif not generic_cpu}
  1101. {$ifdef DEBUG_PPU}
  1102. ppu_log_val(tostr(result));
  1103. dec_log_level;
  1104. {$endif}
  1105. end;
  1106. function tentryfile.getrealsize(sizeofreal : longint):entryreal;
  1107. var
  1108. e : entryreal;
  1109. d : double;
  1110. s : single;
  1111. begin
  1112. if sizeofreal=sizeof(e) then
  1113. begin
  1114. {$ifdef DEBUG_PPU}
  1115. ppu_log('putreal,size='+tostr(sizeof(e)));
  1116. inc_log_level;
  1117. {$endif}
  1118. if entryidx+sizeof(e)>entry.size then
  1119. begin
  1120. error:=true;
  1121. result:=0;
  1122. exit;
  1123. end;
  1124. readdata(e,sizeof(e));
  1125. if change_endian then
  1126. result:=swapendian_entryreal(e)
  1127. else
  1128. result:=e;
  1129. inc(entryidx,sizeof(e));
  1130. {$ifdef DEBUG_PPU}
  1131. ppu_log_val(realtostr(result));
  1132. dec_log_level;
  1133. {$endif}
  1134. exit;
  1135. end;
  1136. if sizeofreal=sizeof(d) then
  1137. begin
  1138. {$ifdef DEBUG_PPU}
  1139. ppu_log('putreal,size='+tostr(sizeof(d)));
  1140. inc_log_level;
  1141. {$endif}
  1142. if entryidx+sizeof(d)>entry.size then
  1143. begin
  1144. error:=true;
  1145. result:=0;
  1146. exit;
  1147. end;
  1148. readdata(d,sizeof(d));
  1149. if change_endian then
  1150. result:=swapendian(pqword(@d)^)
  1151. else
  1152. result:=d;
  1153. inc(entryidx,sizeof(d));
  1154. result:=d;
  1155. {$ifdef DEBUG_PPU}
  1156. ppu_log_val(realtostr(result));
  1157. dec_log_level;
  1158. {$endif}
  1159. exit;
  1160. end;
  1161. if sizeofreal=sizeof(s) then
  1162. begin
  1163. {$ifdef DEBUG_PPU}
  1164. ppu_log('putreal,size='+tostr(sizeof(s)));
  1165. inc_log_level;
  1166. {$endif}
  1167. if entryidx+sizeof(s)>entry.size then
  1168. begin
  1169. error:=true;
  1170. result:=0;
  1171. exit;
  1172. end;
  1173. readdata(s,sizeof(s));
  1174. if change_endian then
  1175. result:=swapendian(pdword(@s)^)
  1176. else
  1177. result:=s;
  1178. inc(entryidx,sizeof(s));
  1179. result:=s;
  1180. {$ifdef DEBUG_PPU}
  1181. ppu_log_val(realtostr(result));
  1182. dec_log_level;
  1183. {$endif}
  1184. exit;
  1185. end;
  1186. error:=true;
  1187. result:=0.0;
  1188. end;
  1189. function tentryfile.getreal:entryreal;
  1190. var
  1191. d : entryreal;
  1192. hd : double;
  1193. begin
  1194. if target_info.system=system_x86_64_win64 then
  1195. begin
  1196. hd:=getrealsize(sizeof(hd));
  1197. getreal:=hd;
  1198. end
  1199. else
  1200. begin
  1201. d:=getrealsize(sizeof(d));
  1202. getreal:=d;
  1203. end;
  1204. end;
  1205. function tentryfile.getboolean:boolean;
  1206. begin
  1207. {$ifdef DEBUG_PPU}
  1208. ppu_log('putboolean');
  1209. {$endif}
  1210. result:=boolean(getbyte);
  1211. end;
  1212. function tentryfile.getstring:string;
  1213. begin
  1214. result[0]:=chr(getbyte);
  1215. {$ifdef DEBUG_PPU}
  1216. ppu_log('putstring,size='+tostr(length(result)+1));
  1217. inc_log_level;
  1218. {$endif}
  1219. if entryidx+length(result)>entry.size then
  1220. begin
  1221. error:=true;
  1222. exit;
  1223. end;
  1224. ReadData(result[1],length(result));
  1225. {$ifdef DEBUG_PPU}
  1226. ppu_log_val(result);
  1227. dec_log_level;
  1228. {$endif}
  1229. inc(entryidx,length(result));
  1230. end;
  1231. function tentryfile.getpshortstring:pshortstring;
  1232. var
  1233. len: char;
  1234. begin
  1235. result:=nil;
  1236. len:=chr(getbyte);
  1237. {$ifdef DEBUG_PPU}
  1238. ppu_log('putstring,size='+tostr(ord(len)+1));
  1239. inc_log_level;
  1240. {$endif}
  1241. if entryidx+ord(len)>entry.size then
  1242. begin
  1243. error:=true;
  1244. exit;
  1245. end;
  1246. getmem(result,ord(len)+1);
  1247. result^[0]:=len;
  1248. ReadData(result^[1],ord(len));
  1249. inc(entryidx,ord(len));
  1250. {$ifdef DEBUG_PPU}
  1251. ppu_log_val(result^);
  1252. dec_log_level;
  1253. {$endif}
  1254. end;
  1255. function tentryfile.getansistring:ansistring;
  1256. var
  1257. len: longint;
  1258. begin
  1259. {$ifdef DEBUG_PPU}
  1260. ppu_log('putansistring');
  1261. inc_log_level;
  1262. {$endif}
  1263. len:=getlongint;
  1264. if entryidx+len>entry.size then
  1265. begin
  1266. error:=true;
  1267. result:='';
  1268. exit;
  1269. end;
  1270. setlength(result,len);
  1271. if len>0 then
  1272. getdata(result[1],len);
  1273. {$ifdef DEBUG_PPU}
  1274. ppu_log_val(result);
  1275. dec_log_level;
  1276. {$endif}
  1277. end;
  1278. procedure tentryfile.getsmallset(out b);
  1279. var
  1280. i : longint;
  1281. begin
  1282. {$ifdef DEBUG_PPU}
  1283. ppu_log('putsmallset');
  1284. inc_log_level;
  1285. { putsmallset uses putlongint, thus we need
  1286. to add a call to ppu_log('longint') to get the same output }
  1287. ppu_log('longint');
  1288. {$endif}
  1289. getdata(b,4);
  1290. if change_endian then
  1291. for i:=0 to 3 do
  1292. Pbyte(@b)[i]:=reverse_byte(Pbyte(@b)[i]);
  1293. {$ifdef DEBUG_PPU}
  1294. for i:=0 to 3 do
  1295. ppu_log_val('byte['+tostr(i)+']=$'+hexstr(pbyte(@b)[i],2));
  1296. dec_log_level;
  1297. {$endif}
  1298. end;
  1299. procedure tentryfile.getnormalset(out b);
  1300. var
  1301. i : longint;
  1302. begin
  1303. {$ifdef DEBUG_PPU}
  1304. ppu_log('putnormalset');
  1305. inc_log_level;
  1306. {$endif}
  1307. getdata(b,32);
  1308. if change_endian then
  1309. for i:=0 to 31 do
  1310. Pbyte(@b)[i]:=reverse_byte(Pbyte(@b)[i]);
  1311. {$ifdef DEBUG_PPU}
  1312. for i:=0 to 31 do
  1313. ppu_log_val('byte['+tostr(i)+']=$'+hexstr(pbyte(@b)[i],2));
  1314. dec_log_level;
  1315. {$endif}
  1316. end;
  1317. function tentryfile.skipuntilentry(untilb:byte):boolean;
  1318. var
  1319. b : byte;
  1320. begin
  1321. {$ifdef DEBUG_PPU}
  1322. ppu_log('skipuntilentry '+tostr(untilb));
  1323. {$endif}
  1324. repeat
  1325. b:=readentry;
  1326. until (b in [ibend,iberror]) or ((b=untilb) and (entry.id=mainentryid));
  1327. skipuntilentry:=(b=untilb);
  1328. end;
  1329. {*****************************************************************************
  1330. tentryfile Writing
  1331. *****************************************************************************}
  1332. function tentryfile.createfile:boolean;
  1333. var
  1334. ok: boolean;
  1335. strm : TCStream;
  1336. begin
  1337. createfile:=false;
  1338. strm:=nil;
  1339. if outputallowed then
  1340. begin
  1341. {$ifdef MACOS}
  1342. {FPas is FreePascal's creator code on MacOS. See systems/mac_crea.txt}
  1343. SetDefaultMacOSCreator('FPas');
  1344. SetDefaultMacOSFiletype('FPPU');
  1345. {$endif}
  1346. ok:=false;
  1347. try
  1348. strm:=CFileStreamClass.Create(fname,fmCreate);
  1349. ok:=true;
  1350. except
  1351. end;
  1352. {$ifdef MACOS}
  1353. SetDefaultMacOSCreator('MPS ');
  1354. SetDefaultMacOSFiletype('TEXT');
  1355. {$endif}
  1356. if not ok then
  1357. exit;
  1358. end;
  1359. createfile:=createstream(strm);
  1360. fisfile:=result;
  1361. end;
  1362. function tentryfile.createstream(strm:TCStream):boolean;
  1363. begin
  1364. createstream:=false;
  1365. if outputallowed then
  1366. begin
  1367. f:=strm;
  1368. mode:=2;
  1369. {write header for sure}
  1370. f.Write(getheaderaddr^,getheadersize);
  1371. end;
  1372. bufsize:=entryfilebufsize;
  1373. bufstart:=getheadersize;
  1374. bufidx:=0;
  1375. {reset}
  1376. resetfile;
  1377. error:=false;
  1378. size:=0;
  1379. entrytyp:=mainentryid;
  1380. {$ifdef DEBUG_PPU}
  1381. {$push}
  1382. {$I-}
  1383. assign(flog,fname+'.debug-write-log');
  1384. rewrite(flog);
  1385. if InOutRes=0 then
  1386. flog_open:=true;
  1387. {$pop}
  1388. {$endif DEBUG_PPU}
  1389. {start}
  1390. newentry;
  1391. createstream:=true;
  1392. end;
  1393. procedure tentryfile.writebuf;
  1394. begin
  1395. if outputallowed and
  1396. (bufidx <> 0) then
  1397. f.Write(buf^,bufidx);
  1398. inc(bufstart,bufidx);
  1399. bufidx:=0;
  1400. end;
  1401. procedure tentryfile.writedata(const b;len:integer);
  1402. var
  1403. p : pchar;
  1404. left,
  1405. idx : integer;
  1406. {$ifdef DEBUG_PPU}
  1407. start_len : integer;
  1408. {$endif}
  1409. begin
  1410. if not outputallowed then
  1411. exit;
  1412. {$ifdef DEBUG_PPU}
  1413. start_len:=len;
  1414. {$endif}
  1415. p:=pchar(@b);
  1416. idx:=0;
  1417. while len>0 do
  1418. begin
  1419. left:=bufsize-bufidx;
  1420. if len>left then
  1421. begin
  1422. move(p[idx],buf[bufidx],left);
  1423. dec(len,left);
  1424. inc(idx,left);
  1425. inc(bufidx,left);
  1426. writebuf;
  1427. end
  1428. else
  1429. begin
  1430. move(p[idx],buf[bufidx],len);
  1431. inc(bufidx,len);
  1432. {$ifdef DEBUG_PPU}
  1433. len:=0;
  1434. {$else}
  1435. exit;
  1436. {$endif}
  1437. end;
  1438. end;
  1439. {$ifdef DEBUG_PPU}
  1440. if (start_len > 0) and (ppu_log_level <= 0) then
  1441. begin
  1442. ppu_log('writedata, length='+tostr(start_len)+' level='+tostr(ppu_log_level));
  1443. for idx:=0 to start_len-1 do
  1444. ppu_log_val('p['+tostr(idx)+']=$'+hexstr(byte(p[idx]),2));
  1445. end;
  1446. {$endif DEBUG_PPU}
  1447. end;
  1448. procedure tentryfile.newentry;
  1449. begin
  1450. with entry do
  1451. begin
  1452. id:=entrytyp;
  1453. nr:=ibend;
  1454. size:=0;
  1455. end;
  1456. {Reset Entry State}
  1457. entryidx:=0;
  1458. entrybufstart:=bufstart;
  1459. entrystart:=bufstart+bufidx;
  1460. {$ifdef DEBUG_PPU}
  1461. ppu_log('entrystart');
  1462. {$endif}
  1463. {Alloc in buffer}
  1464. writedata(entry,sizeof(tentry));
  1465. end;
  1466. procedure tentryfile.writeentry(ibnr:byte);
  1467. var
  1468. opos : integer;
  1469. begin
  1470. {create entry}
  1471. entry.id:=entrytyp;
  1472. entry.nr:=ibnr;
  1473. entry.size:=entryidx;
  1474. {it's already been sent to disk ?}
  1475. if entrybufstart<>bufstart then
  1476. begin
  1477. if outputallowed then
  1478. begin
  1479. {flush to be sure}
  1480. WriteBuf;
  1481. {write entry}
  1482. opos:=f.Position;
  1483. f.Position:=entrystart;
  1484. f.write(entry,sizeof(tentry));
  1485. f.Position:=opos;
  1486. end;
  1487. entrybufstart:=bufstart;
  1488. end
  1489. else
  1490. move(entry,buf[entrystart-bufstart],sizeof(entry));
  1491. {$ifdef DEBUG_PPU}
  1492. ppu_log('writeentry, id='+entryid_name(entry.id)+' nr='+entry_name(entry.nr)+' size='+tostr(entry.size));
  1493. {$endif}
  1494. {Add New Entry, which is ibend by default}
  1495. entrystart:=bufstart+bufidx; {next entry position}
  1496. newentry;
  1497. end;
  1498. procedure tentryfile.putdata(const b;len:integer);
  1499. begin
  1500. if outputallowed then
  1501. writedata(b,len);
  1502. inc(entryidx,len);
  1503. end;
  1504. procedure tentryfile.putbyte(b:byte);
  1505. begin
  1506. {$ifdef DEBUG_PPU}
  1507. ppu_log('putbyte');
  1508. inc_log_level;
  1509. ppu_log_val(tostr(b));
  1510. {$endif}
  1511. putdata(b,1);
  1512. {$ifdef DEBUG_PPU}
  1513. dec_log_level;
  1514. {$endif}
  1515. end;
  1516. procedure tentryfile.putword(w:word);
  1517. begin
  1518. {$ifdef DEBUG_PPU}
  1519. ppu_log('putword');
  1520. inc_log_level;
  1521. ppu_log_val(tostr(w));
  1522. {$endif}
  1523. putdata(w,2);
  1524. {$ifdef DEBUG_PPU}
  1525. dec_log_level;
  1526. {$endif}
  1527. end;
  1528. procedure tentryfile.putdword(w:dword);
  1529. begin
  1530. {$ifdef DEBUG_PPU}
  1531. ppu_log('putdword');
  1532. inc_log_level;
  1533. ppu_log_val(tostr(w));
  1534. {$endif}
  1535. putdata(w,4);
  1536. {$ifdef DEBUG_PPU}
  1537. dec_log_level;
  1538. {$endif}
  1539. end;
  1540. procedure tentryfile.putlongint(l:longint);
  1541. begin
  1542. {$ifdef DEBUG_PPU}
  1543. ppu_log('putlongint');
  1544. inc_log_level;
  1545. ppu_log_val(tostr(l));
  1546. {$endif}
  1547. putdata(l,4);
  1548. {$ifdef DEBUG_PPU}
  1549. dec_log_level;
  1550. {$endif}
  1551. end;
  1552. procedure tentryfile.putint64(i:int64);
  1553. begin
  1554. {$ifdef DEBUG_PPU}
  1555. ppu_log('putint64');
  1556. inc_log_level;
  1557. ppu_log_val(tostr(i));
  1558. {$endif}
  1559. putdata(i,8);
  1560. {$ifdef DEBUG_PPU}
  1561. dec_log_level;
  1562. {$endif}
  1563. end;
  1564. procedure tentryfile.putqword(q:qword);
  1565. begin
  1566. {$ifdef DEBUG_PPU}
  1567. ppu_log('putqword');
  1568. inc_log_level;
  1569. ppu_log_val(tostr(q));
  1570. {$endif}
  1571. putdata(q,sizeof(qword));
  1572. {$ifdef DEBUG_PPU}
  1573. dec_log_level;
  1574. {$endif}
  1575. end;
  1576. procedure tentryfile.putaint(i:aint);
  1577. begin
  1578. {$ifdef DEBUG_PPU}
  1579. ppu_log('putaint');
  1580. inc_log_level;
  1581. case sizeof(aint) of
  1582. 8: ppu_log('putint64');
  1583. 4: ppu_log('putlongint');
  1584. 2: ppu_log('putword');
  1585. 1: ppu_log('putbyte');
  1586. end;
  1587. ppu_log_val(tostr(i));
  1588. {$endif}
  1589. putdata(i,sizeof(aint));
  1590. {$ifdef DEBUG_PPU}
  1591. dec_log_level;
  1592. {$endif}
  1593. end;
  1594. procedure tentryfile.putasizeint(i: asizeint);
  1595. begin
  1596. {$ifdef DEBUG_PPU}
  1597. ppu_log('putasizeint');
  1598. inc_log_level;
  1599. case sizeof(asizeint) of
  1600. 8: ppu_log('putint64');
  1601. 4: ppu_log('putlongint');
  1602. 2: ppu_log('putword');
  1603. 1: ppu_log('putbyte');
  1604. end;
  1605. ppu_log_val(tostr(i));
  1606. {$endif}
  1607. putdata(i,sizeof(asizeint));
  1608. {$ifdef DEBUG_PPU}
  1609. dec_log_level;
  1610. {$endif}
  1611. end;
  1612. procedure tentryfile.putpuint(i : puint);
  1613. begin
  1614. {$ifdef DEBUG_PPU}
  1615. ppu_log('putpuint');
  1616. inc_log_level;
  1617. ppu_log_val(tostr(i));
  1618. {$endif}
  1619. putdata(i,sizeof(puint));
  1620. {$ifdef DEBUG_PPU}
  1621. dec_log_level;
  1622. {$endif}
  1623. end;
  1624. procedure tentryfile.putptruint(v:TConstPtrUInt);
  1625. begin
  1626. {$ifdef DEBUG_PPU}
  1627. ppu_log('putptruint');
  1628. inc_log_level;
  1629. {$endif}
  1630. {$if sizeof(TConstPtrUInt)=8}
  1631. putint64(int64(v));
  1632. {$else}
  1633. putlongint(longint(v));
  1634. {$endif}
  1635. {$ifdef DEBUG_PPU}
  1636. dec_log_level;
  1637. {$endif}
  1638. end;
  1639. procedure tentryfile.putaword(i:aword);
  1640. begin
  1641. {$ifdef DEBUG_PPU}
  1642. ppu_log('putaword');
  1643. inc_log_level;
  1644. ppu_log_val(tostr(i));
  1645. {$endif}
  1646. putdata(i,sizeof(aword));
  1647. {$ifdef DEBUG_PPU}
  1648. dec_log_level;
  1649. {$endif}
  1650. end;
  1651. procedure tentryfile.putreal(d:entryreal);
  1652. var
  1653. hd : double;
  1654. begin
  1655. if target_info.system=system_x86_64_win64 then
  1656. begin
  1657. {$ifdef DEBUG_PPU}
  1658. ppu_log('putreal,size='+tostr(sizeof(hd)));
  1659. inc_log_level;
  1660. ppu_log_val(realtostr(d));
  1661. {$endif}
  1662. hd:=d;
  1663. putdata(hd,sizeof(hd));
  1664. end
  1665. else
  1666. begin
  1667. {$ifdef DEBUG_PPU}
  1668. ppu_log('putreal,size='+tostr(sizeof(d)));
  1669. inc_log_level;
  1670. ppu_log_val(realtostr(d));
  1671. {$endif}
  1672. putdata(d,sizeof(entryreal));
  1673. end;
  1674. {$ifdef DEBUG_PPU}
  1675. dec_log_level;
  1676. {$endif}
  1677. end;
  1678. procedure tentryfile.putboolean(b:boolean);
  1679. begin
  1680. {$ifdef DEBUG_PPU}
  1681. ppu_log('putboolean');
  1682. inc_log_level;
  1683. {$endif}
  1684. putbyte(byte(b));
  1685. {$ifdef DEBUG_PPU}
  1686. dec_log_level;
  1687. {$endif}
  1688. end;
  1689. procedure tentryfile.putstring(const s:string);
  1690. begin
  1691. {$ifdef DEBUG_PPU}
  1692. { The reading method uses getbyte, so fake it here }
  1693. ppu_log('putbyte');
  1694. inc_log_level;
  1695. inc(bufidx);
  1696. ppu_log('putstring,size='+tostr(length(s)+1));
  1697. dec(bufidx);
  1698. ppu_log_val(s);
  1699. {$endif}
  1700. putdata(s,length(s)+1);
  1701. {$ifdef DEBUG_PPU}
  1702. dec_log_level;
  1703. {$endif}
  1704. end;
  1705. procedure tentryfile.putansistring(const s:ansistring);
  1706. var
  1707. len: longint;
  1708. begin
  1709. len:=length(s);
  1710. {$ifdef DEBUG_PPU}
  1711. ppu_log('putansistring');
  1712. inc_log_level;
  1713. ppu_log_val(s);
  1714. {$endif}
  1715. putlongint(len);
  1716. if len>0 then
  1717. putdata(s[1],len);
  1718. {$ifdef DEBUG_PPU}
  1719. dec_log_level;
  1720. {$endif}
  1721. end;
  1722. procedure tentryfile.putsmallset(const b);
  1723. var
  1724. l : longint;
  1725. {$ifdef DEBUG_PPU}
  1726. i : byte;
  1727. {$endif}
  1728. begin
  1729. {$ifdef DEBUG_PPU}
  1730. ppu_log('putsmallset');
  1731. inc_log_level;
  1732. {$endif}
  1733. l:=longint(b);
  1734. putlongint(l);
  1735. {$ifdef DEBUG_PPU}
  1736. for i:=0 to 3 do
  1737. ppu_log_val('byte['+tostr(i)+']=$'+hexstr(pbyte(@b)[i],2));
  1738. dec_log_level;
  1739. {$endif}
  1740. end;
  1741. procedure tentryfile.putnormalset(const b);
  1742. {$ifdef DEBUG_PPU}
  1743. var
  1744. i : byte;
  1745. {$endif}
  1746. begin
  1747. {$ifdef DEBUG_PPU}
  1748. ppu_log('putnormalset');
  1749. inc_log_level;
  1750. {$endif}
  1751. putdata(b,32);
  1752. {$ifdef DEBUG_PPU}
  1753. for i:=0 to 31 do
  1754. ppu_log_val('byte['+tostr(i)+']=$'+hexstr(pbyte(@b)[i],2));
  1755. dec_log_level;
  1756. {$endif}
  1757. end;
  1758. procedure tentryfile.tempclose;
  1759. begin
  1760. if not closed then
  1761. begin
  1762. closepos:=f.Position;
  1763. f.Free;
  1764. f:=nil;
  1765. closed:=true;
  1766. tempclosed:=true;
  1767. end;
  1768. end;
  1769. function tentryfile.tempopen:boolean;
  1770. begin
  1771. tempopen:=false;
  1772. if not closed or not tempclosed then
  1773. exit;
  1774. { MG: not sure, if this is correct
  1775. f.position:=0;
  1776. No, f was freed in tempclose above, we need to
  1777. recreate it. PM 2011/06/06 }
  1778. try
  1779. f:=CFileStreamClass.Create(fname,fmOpenRead);
  1780. except
  1781. exit;
  1782. end;
  1783. closed:=false;
  1784. tempclosed:=false;
  1785. { restore state }
  1786. f.Position:=closepos;
  1787. tempopen:=true;
  1788. end;
  1789. end.