2
0

entfile.pas 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914
  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. { 21 } 32 {'xtensa'}
  150. );
  151. CpuAluBitSize : array[tsystemcpu] of longint =
  152. (
  153. { 0 } 32 {'none'},
  154. { 1 } 32 {'i386'},
  155. { 2 } 32 {'m68k'},
  156. { 3 } 32 {'alpha'},
  157. { 4 } 32 {'powerpc'},
  158. { 5 } 32 {'sparc'},
  159. { 6 } 32 {'vis'},
  160. { 7 } 64 {'ia64'},
  161. { 8 } 64 {'x86_64'},
  162. { 9 } 32 {'mipseb'},
  163. { 10 } 32 {'arm'},
  164. { 11 } 64 {'powerpc64'},
  165. { 12 } 8 {'avr'},
  166. { 13 } 32 {'mipsel'},
  167. { 14 } 64 {'jvm'},
  168. { 15 } 16 {'i8086'},
  169. { 16 } 64 {'aarch64'},
  170. { 17 } 64 {'wasm'},
  171. { 18 } 64 {'sparc64'},
  172. { 19 } 32 {'riscv32'},
  173. { 20 } 64 {'riscv64'},
  174. { 21 } 32 {'xtensa'}
  175. );
  176. {$endif generic_cpu}
  177. type
  178. { bestreal is defined based on the target architecture }
  179. entryreal=bestreal;
  180. { common part of the header for all kinds of entry files }
  181. tentryheader=record
  182. id : array[1..3] of char;
  183. ver : array[1..3] of char;
  184. compiler : word;
  185. cpu : word;
  186. target : word;
  187. flags : dword;
  188. size : dword; { size of the ppufile without header }
  189. end;
  190. pentryheader=^tentryheader;
  191. tentry=packed record
  192. size : longint;
  193. id : byte;
  194. nr : byte;
  195. end;
  196. tentryfile=class
  197. private
  198. function getposition:longint;
  199. procedure setposition(value:longint);
  200. protected
  201. buf : pchar;
  202. bufstart,
  203. bufsize,
  204. bufidx : integer;
  205. entrybufstart,
  206. entrystart,
  207. entryidx : integer;
  208. entry : tentry;
  209. closed,
  210. tempclosed : boolean;
  211. closepos : integer;
  212. protected
  213. f : TCStream;
  214. {$ifdef DEBUG_PPU}
  215. flog : text;
  216. flog_open : boolean;
  217. ppu_log_level : longint;
  218. ppu_log_idx : integer;
  219. {$endif}
  220. mode : byte; {0 - Closed, 1 - Reading, 2 - Writing}
  221. fisfile : boolean;
  222. fname : string;
  223. fsize : integer;
  224. procedure newheader;virtual;abstract;
  225. function readheader:longint;virtual;abstract;
  226. function outputallowed:boolean;virtual;
  227. procedure resetfile;virtual;abstract;
  228. function getheadersize:longint;virtual;abstract;
  229. function getheaderaddr:pentryheader;virtual;abstract;
  230. procedure RaiseAssertion(Code: Longint); virtual;
  231. public
  232. entrytyp : byte;
  233. size : integer;
  234. change_endian : boolean; { Used in ppudump util }
  235. {$ifdef generic_cpu}
  236. has_more,
  237. {$endif not generic_cpu}
  238. error : boolean;
  239. constructor create(const fn:string);
  240. destructor destroy;override;
  241. function getversion:integer;
  242. procedure flush; {$ifdef USEINLINE}inline;{$endif}
  243. procedure closefile;virtual;
  244. procedure newentry;
  245. property position:longint read getposition write setposition;
  246. { Warning: don't keep the stream open during a tempclose! }
  247. function substream(ofs,len:longint):TCStream;
  248. { Warning: don't use the put* or write* functions anymore when writing through this }
  249. property stream:TCStream read f;
  250. {$ifdef DEBUG_PPU}
  251. procedure ppu_log(st :string);virtual;
  252. procedure ppu_log_val(st :string);virtual;
  253. procedure inc_log_level;
  254. procedure dec_log_level;
  255. {$endif}
  256. {read}
  257. function openfile:boolean;
  258. function openstream(strm:TCStream):boolean;
  259. procedure reloadbuf;
  260. procedure readdata(out b;len:integer);
  261. procedure skipdata(len:integer);
  262. function readentry:byte;
  263. function EndOfEntry:boolean; {$ifdef USEINLINE}inline;{$endif}
  264. function entrysize:longint; {$ifdef USEINLINE}inline;{$endif}
  265. function entryleft:longint; {$ifdef USEINLINE}inline;{$endif}
  266. procedure getdatabuf(out b;len:integer;out res:integer);
  267. procedure getdata(out b;len:integer);
  268. function getbyte:byte;
  269. function getword:word;
  270. function getdword:dword;
  271. function getlongint:longint;
  272. function getint64:int64;
  273. function getqword:qword;
  274. function getaint:{$ifdef generic_cpu}int64{$else}aint{$ifdef USEINLINE}; inline{$endif}{$endif};
  275. function getasizeint:{$ifdef generic_cpu}int64{$else}asizeint{$ifdef USEINLINE}; inline{$endif}{$endif};
  276. function getpuint:{$ifdef generic_cpu}qword{$else}puint{$ifdef USEINLINE}; inline{$endif}{$endif};
  277. function getptruint:{$ifdef generic_cpu}qword{$else}TConstPtrUInt{$ifdef USEINLINE}; inline{$endif}{$endif};
  278. function getaword:{$ifdef generic_cpu}qword{$else}aword{$ifdef USEINLINE}; inline{$endif}{$endif};
  279. function getreal:entryreal;
  280. function getrealsize(sizeofreal : longint):entryreal;
  281. function getboolean:boolean; {$ifdef USEINLINE}inline;{$endif}
  282. function getstring:string;
  283. function getpshortstring:pshortstring;
  284. function getansistring:ansistring;
  285. procedure getset(out arr: array of byte);
  286. function skipuntilentry(untilb:byte):boolean;
  287. {write}
  288. function createfile:boolean;virtual;
  289. function createstream(strm:TCStream):boolean;
  290. procedure writeheader;virtual;abstract;
  291. procedure writebuf;
  292. procedure writedata(const b;len:integer);
  293. procedure writeentry(ibnr:byte);
  294. procedure putdata(const b;len:integer);virtual;
  295. procedure putbyte(b:byte); {$ifdef USEINLINE}inline;{$endif}
  296. procedure putword(w:word); {$ifdef USEINLINE}inline;{$endif}
  297. procedure putdword(w:dword); {$ifdef USEINLINE}inline;{$endif}
  298. procedure putlongint(l:longint); {$ifdef USEINLINE}inline;{$endif}
  299. procedure putint64(i:int64); {$ifdef USEINLINE}inline;{$endif}
  300. procedure putqword(q:qword); {$ifdef USEINLINE}inline;{$endif}
  301. procedure putaint(i:aint); {$ifdef USEINLINE}inline;{$endif}
  302. procedure putasizeint(i:asizeint); {$ifdef USEINLINE}inline;{$endif}
  303. procedure putpuint(i:puint); {$ifdef USEINLINE}inline;{$endif}
  304. procedure putptruint(v:TConstPtrUInt); {$ifdef USEINLINE}inline;{$endif}
  305. procedure putaword(i:aword); {$ifdef USEINLINE}inline;{$endif}
  306. procedure putreal(d:entryreal);
  307. procedure putboolean(b:boolean); {$ifdef USEINLINE}inline;{$endif}
  308. procedure putstring(const s:string); {$ifdef USEINLINE}inline;{$endif}
  309. procedure putansistring(const s:ansistring);
  310. procedure putset(const arr: array of byte);
  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. di : qword;{ integer of same size as double }
  1111. s : single;
  1112. si : dword; { integer of same size as single }
  1113. begin
  1114. if sizeofreal=sizeof(e) then
  1115. begin
  1116. {$ifdef DEBUG_PPU}
  1117. ppu_log('putreal,size='+tostr(sizeof(e)));
  1118. inc_log_level;
  1119. {$endif}
  1120. if entryidx+sizeof(e)>entry.size then
  1121. begin
  1122. error:=true;
  1123. result:=0;
  1124. exit;
  1125. end;
  1126. readdata(e,sizeof(e));
  1127. if change_endian then
  1128. result:=swapendian_entryreal(e)
  1129. else
  1130. result:=e;
  1131. inc(entryidx,sizeof(e));
  1132. {$ifdef DEBUG_PPU}
  1133. ppu_log_val(realtostr(result));
  1134. dec_log_level;
  1135. {$endif}
  1136. exit;
  1137. end;
  1138. if sizeofreal=sizeof(d) then
  1139. begin
  1140. {$ifdef DEBUG_PPU}
  1141. ppu_log('putreal,size='+tostr(sizeof(d)));
  1142. inc_log_level;
  1143. {$endif}
  1144. if entryidx+sizeof(d)>entry.size then
  1145. begin
  1146. error:=true;
  1147. result:=0;
  1148. exit;
  1149. end;
  1150. readdata(d,sizeof(d));
  1151. if change_endian then
  1152. begin
  1153. di:=swapendian(pqword(@d)^);
  1154. d:=pdouble(@di)^;
  1155. end;
  1156. result:=d;
  1157. inc(entryidx,sizeof(d));
  1158. result:=d;
  1159. {$ifdef DEBUG_PPU}
  1160. ppu_log_val(realtostr(result));
  1161. dec_log_level;
  1162. {$endif}
  1163. exit;
  1164. end;
  1165. if sizeofreal=sizeof(s) then
  1166. begin
  1167. {$ifdef DEBUG_PPU}
  1168. ppu_log('putreal,size='+tostr(sizeof(s)));
  1169. inc_log_level;
  1170. {$endif}
  1171. if entryidx+sizeof(s)>entry.size then
  1172. begin
  1173. error:=true;
  1174. result:=0;
  1175. exit;
  1176. end;
  1177. readdata(s,sizeof(s));
  1178. if change_endian then
  1179. begin
  1180. si:=swapendian(pdword(@s)^);
  1181. s:=psingle(@si)^;
  1182. end;
  1183. result:=s;
  1184. inc(entryidx,sizeof(s));
  1185. result:=s;
  1186. {$ifdef DEBUG_PPU}
  1187. ppu_log_val(realtostr(result));
  1188. dec_log_level;
  1189. {$endif}
  1190. exit;
  1191. end;
  1192. error:=true;
  1193. result:=0.0;
  1194. end;
  1195. function tentryfile.getreal:entryreal;
  1196. var
  1197. d : entryreal;
  1198. hd : double;
  1199. begin
  1200. if target_info.system=system_x86_64_win64 then
  1201. begin
  1202. hd:=getrealsize(sizeof(hd));
  1203. getreal:=hd;
  1204. end
  1205. else
  1206. begin
  1207. d:=getrealsize(sizeof(d));
  1208. getreal:=d;
  1209. end;
  1210. end;
  1211. function tentryfile.getboolean:boolean;
  1212. begin
  1213. {$ifdef DEBUG_PPU}
  1214. ppu_log('putboolean');
  1215. {$endif}
  1216. result:=boolean(getbyte);
  1217. end;
  1218. function tentryfile.getstring:string;
  1219. begin
  1220. result[0]:=chr(getbyte);
  1221. {$ifdef DEBUG_PPU}
  1222. ppu_log('putstring,size='+tostr(length(result)+1));
  1223. inc_log_level;
  1224. {$endif}
  1225. if entryidx+length(result)>entry.size then
  1226. begin
  1227. error:=true;
  1228. exit;
  1229. end;
  1230. ReadData(result[1],length(result));
  1231. {$ifdef DEBUG_PPU}
  1232. ppu_log_val(result);
  1233. dec_log_level;
  1234. {$endif}
  1235. inc(entryidx,length(result));
  1236. end;
  1237. function tentryfile.getpshortstring:pshortstring;
  1238. var
  1239. len: char;
  1240. begin
  1241. result:=nil;
  1242. len:=chr(getbyte);
  1243. {$ifdef DEBUG_PPU}
  1244. ppu_log('putstring,size='+tostr(ord(len)+1));
  1245. inc_log_level;
  1246. {$endif}
  1247. if entryidx+ord(len)>entry.size then
  1248. begin
  1249. error:=true;
  1250. exit;
  1251. end;
  1252. getmem(result,ord(len)+1);
  1253. result^[0]:=len;
  1254. ReadData(result^[1],ord(len));
  1255. inc(entryidx,ord(len));
  1256. {$ifdef DEBUG_PPU}
  1257. ppu_log_val(result^);
  1258. dec_log_level;
  1259. {$endif}
  1260. end;
  1261. function tentryfile.getansistring:ansistring;
  1262. var
  1263. len: longint;
  1264. begin
  1265. {$ifdef DEBUG_PPU}
  1266. ppu_log('putansistring');
  1267. inc_log_level;
  1268. {$endif}
  1269. len:=getlongint;
  1270. if entryidx+len>entry.size then
  1271. begin
  1272. error:=true;
  1273. result:='';
  1274. exit;
  1275. end;
  1276. setlength(result,len);
  1277. if len>0 then
  1278. getdata(result[1],len);
  1279. {$ifdef DEBUG_PPU}
  1280. ppu_log_val(result);
  1281. dec_log_level;
  1282. {$endif}
  1283. end;
  1284. procedure tentryfile.getset(out arr: array of byte);
  1285. var
  1286. i : longint;
  1287. begin
  1288. {$ifdef DEBUG_PPU}
  1289. ppu_log('putset');
  1290. inc_log_level;
  1291. {$endif}
  1292. getdata(arr,sizeof(arr));
  1293. if change_endian then
  1294. for i:=low(arr) to high(arr) do
  1295. arr[i]:=reverse_byte(arr[i]);
  1296. {$ifdef DEBUG_PPU}
  1297. for i:=0 to 3 do
  1298. ppu_log_val('byte['+tostr(i)+']=$'+hexstr(arr[i],2));
  1299. dec_log_level;
  1300. {$endif}
  1301. end;
  1302. function tentryfile.skipuntilentry(untilb:byte):boolean;
  1303. var
  1304. b : byte;
  1305. begin
  1306. {$ifdef DEBUG_PPU}
  1307. ppu_log('skipuntilentry '+tostr(untilb));
  1308. {$endif}
  1309. repeat
  1310. b:=readentry;
  1311. until (b in [ibend,iberror]) or ((b=untilb) and (entry.id=mainentryid));
  1312. skipuntilentry:=(b=untilb);
  1313. end;
  1314. {*****************************************************************************
  1315. tentryfile Writing
  1316. *****************************************************************************}
  1317. function tentryfile.createfile:boolean;
  1318. var
  1319. ok: boolean;
  1320. strm : TCStream;
  1321. begin
  1322. createfile:=false;
  1323. strm:=nil;
  1324. if outputallowed then
  1325. begin
  1326. {$ifdef MACOS}
  1327. {FPas is FreePascal's creator code on MacOS. See systems/mac_crea.txt}
  1328. SetDefaultMacOSCreator('FPas');
  1329. SetDefaultMacOSFiletype('FPPU');
  1330. {$endif}
  1331. ok:=false;
  1332. try
  1333. strm:=CFileStreamClass.Create(fname,fmCreate);
  1334. ok:=true;
  1335. except
  1336. end;
  1337. {$ifdef MACOS}
  1338. SetDefaultMacOSCreator('MPS ');
  1339. SetDefaultMacOSFiletype('TEXT');
  1340. {$endif}
  1341. if not ok then
  1342. exit;
  1343. end;
  1344. createfile:=createstream(strm);
  1345. fisfile:=result;
  1346. end;
  1347. function tentryfile.createstream(strm:TCStream):boolean;
  1348. begin
  1349. createstream:=false;
  1350. if outputallowed then
  1351. begin
  1352. f:=strm;
  1353. mode:=2;
  1354. {write header for sure}
  1355. f.Write(getheaderaddr^,getheadersize);
  1356. end;
  1357. bufsize:=entryfilebufsize;
  1358. bufstart:=getheadersize;
  1359. bufidx:=0;
  1360. {reset}
  1361. resetfile;
  1362. error:=false;
  1363. size:=0;
  1364. entrytyp:=mainentryid;
  1365. {$ifdef DEBUG_PPU}
  1366. {$push}
  1367. {$I-}
  1368. assign(flog,fname+'.debug-write-log');
  1369. rewrite(flog);
  1370. if InOutRes=0 then
  1371. flog_open:=true;
  1372. {$pop}
  1373. {$endif DEBUG_PPU}
  1374. {start}
  1375. newentry;
  1376. createstream:=true;
  1377. end;
  1378. procedure tentryfile.writebuf;
  1379. begin
  1380. if outputallowed and
  1381. (bufidx <> 0) then
  1382. f.Write(buf^,bufidx);
  1383. inc(bufstart,bufidx);
  1384. bufidx:=0;
  1385. end;
  1386. procedure tentryfile.writedata(const b;len:integer);
  1387. var
  1388. p : pchar;
  1389. left,
  1390. idx : integer;
  1391. {$ifdef DEBUG_PPU}
  1392. start_len : integer;
  1393. {$endif}
  1394. begin
  1395. if not outputallowed then
  1396. exit;
  1397. {$ifdef DEBUG_PPU}
  1398. start_len:=len;
  1399. {$endif}
  1400. p:=pchar(@b);
  1401. idx:=0;
  1402. while len>0 do
  1403. begin
  1404. left:=bufsize-bufidx;
  1405. if len>left then
  1406. begin
  1407. move(p[idx],buf[bufidx],left);
  1408. dec(len,left);
  1409. inc(idx,left);
  1410. inc(bufidx,left);
  1411. writebuf;
  1412. end
  1413. else
  1414. begin
  1415. move(p[idx],buf[bufidx],len);
  1416. inc(bufidx,len);
  1417. {$ifdef DEBUG_PPU}
  1418. len:=0;
  1419. {$else}
  1420. exit;
  1421. {$endif}
  1422. end;
  1423. end;
  1424. {$ifdef DEBUG_PPU}
  1425. if (start_len > 0) and (ppu_log_level <= 0) then
  1426. begin
  1427. ppu_log('writedata, length='+tostr(start_len)+' level='+tostr(ppu_log_level));
  1428. for idx:=0 to start_len-1 do
  1429. ppu_log_val('p['+tostr(idx)+']=$'+hexstr(byte(p[idx]),2));
  1430. end;
  1431. {$endif DEBUG_PPU}
  1432. end;
  1433. procedure tentryfile.newentry;
  1434. begin
  1435. with entry do
  1436. begin
  1437. id:=entrytyp;
  1438. nr:=ibend;
  1439. size:=0;
  1440. end;
  1441. {Reset Entry State}
  1442. entryidx:=0;
  1443. entrybufstart:=bufstart;
  1444. entrystart:=bufstart+bufidx;
  1445. {$ifdef DEBUG_PPU}
  1446. ppu_log('entrystart');
  1447. {$endif}
  1448. {Alloc in buffer}
  1449. writedata(entry,sizeof(tentry));
  1450. end;
  1451. procedure tentryfile.writeentry(ibnr:byte);
  1452. var
  1453. opos : integer;
  1454. begin
  1455. {create entry}
  1456. entry.id:=entrytyp;
  1457. entry.nr:=ibnr;
  1458. entry.size:=entryidx;
  1459. {it's already been sent to disk ?}
  1460. if entrybufstart<>bufstart then
  1461. begin
  1462. if outputallowed then
  1463. begin
  1464. {flush to be sure}
  1465. WriteBuf;
  1466. {write entry}
  1467. opos:=f.Position;
  1468. f.Position:=entrystart;
  1469. f.write(entry,sizeof(tentry));
  1470. f.Position:=opos;
  1471. end;
  1472. entrybufstart:=bufstart;
  1473. end
  1474. else
  1475. move(entry,buf[entrystart-bufstart],sizeof(entry));
  1476. {$ifdef DEBUG_PPU}
  1477. ppu_log('writeentry, id='+entryid_name(entry.id)+' nr='+entry_name(entry.nr)+' size='+tostr(entry.size));
  1478. {$endif}
  1479. {Add New Entry, which is ibend by default}
  1480. entrystart:=bufstart+bufidx; {next entry position}
  1481. newentry;
  1482. end;
  1483. procedure tentryfile.putdata(const b;len:integer);
  1484. begin
  1485. if outputallowed then
  1486. writedata(b,len);
  1487. inc(entryidx,len);
  1488. end;
  1489. procedure tentryfile.putbyte(b:byte);
  1490. begin
  1491. {$ifdef DEBUG_PPU}
  1492. ppu_log('putbyte');
  1493. inc_log_level;
  1494. ppu_log_val(tostr(b));
  1495. {$endif}
  1496. putdata(b,1);
  1497. {$ifdef DEBUG_PPU}
  1498. dec_log_level;
  1499. {$endif}
  1500. end;
  1501. procedure tentryfile.putword(w:word);
  1502. begin
  1503. {$ifdef DEBUG_PPU}
  1504. ppu_log('putword');
  1505. inc_log_level;
  1506. ppu_log_val(tostr(w));
  1507. {$endif}
  1508. putdata(w,2);
  1509. {$ifdef DEBUG_PPU}
  1510. dec_log_level;
  1511. {$endif}
  1512. end;
  1513. procedure tentryfile.putdword(w:dword);
  1514. begin
  1515. {$ifdef DEBUG_PPU}
  1516. ppu_log('putdword');
  1517. inc_log_level;
  1518. ppu_log_val(tostr(w));
  1519. {$endif}
  1520. putdata(w,4);
  1521. {$ifdef DEBUG_PPU}
  1522. dec_log_level;
  1523. {$endif}
  1524. end;
  1525. procedure tentryfile.putlongint(l:longint);
  1526. begin
  1527. {$ifdef DEBUG_PPU}
  1528. ppu_log('putlongint');
  1529. inc_log_level;
  1530. ppu_log_val(tostr(l));
  1531. {$endif}
  1532. putdata(l,4);
  1533. {$ifdef DEBUG_PPU}
  1534. dec_log_level;
  1535. {$endif}
  1536. end;
  1537. procedure tentryfile.putint64(i:int64);
  1538. begin
  1539. {$ifdef DEBUG_PPU}
  1540. ppu_log('putint64');
  1541. inc_log_level;
  1542. ppu_log_val(tostr(i));
  1543. {$endif}
  1544. putdata(i,8);
  1545. {$ifdef DEBUG_PPU}
  1546. dec_log_level;
  1547. {$endif}
  1548. end;
  1549. procedure tentryfile.putqword(q:qword);
  1550. begin
  1551. {$ifdef DEBUG_PPU}
  1552. ppu_log('putqword');
  1553. inc_log_level;
  1554. ppu_log_val(tostr(q));
  1555. {$endif}
  1556. putdata(q,sizeof(qword));
  1557. {$ifdef DEBUG_PPU}
  1558. dec_log_level;
  1559. {$endif}
  1560. end;
  1561. procedure tentryfile.putaint(i:aint);
  1562. begin
  1563. {$ifdef DEBUG_PPU}
  1564. ppu_log('putaint');
  1565. inc_log_level;
  1566. case sizeof(aint) of
  1567. 8: ppu_log('putint64');
  1568. 4: ppu_log('putlongint');
  1569. 2: ppu_log('putword');
  1570. 1: ppu_log('putbyte');
  1571. end;
  1572. ppu_log_val(tostr(i));
  1573. {$endif}
  1574. putdata(i,sizeof(aint));
  1575. {$ifdef DEBUG_PPU}
  1576. dec_log_level;
  1577. {$endif}
  1578. end;
  1579. procedure tentryfile.putasizeint(i: asizeint);
  1580. begin
  1581. {$ifdef DEBUG_PPU}
  1582. ppu_log('putasizeint');
  1583. inc_log_level;
  1584. case sizeof(asizeint) of
  1585. 8: ppu_log('putint64');
  1586. 4: ppu_log('putlongint');
  1587. 2: ppu_log('putword');
  1588. 1: ppu_log('putbyte');
  1589. end;
  1590. ppu_log_val(tostr(i));
  1591. {$endif}
  1592. putdata(i,sizeof(asizeint));
  1593. {$ifdef DEBUG_PPU}
  1594. dec_log_level;
  1595. {$endif}
  1596. end;
  1597. procedure tentryfile.putpuint(i : puint);
  1598. begin
  1599. {$ifdef DEBUG_PPU}
  1600. ppu_log('putpuint');
  1601. inc_log_level;
  1602. ppu_log_val(tostr(i));
  1603. {$endif}
  1604. putdata(i,sizeof(puint));
  1605. {$ifdef DEBUG_PPU}
  1606. dec_log_level;
  1607. {$endif}
  1608. end;
  1609. procedure tentryfile.putptruint(v:TConstPtrUInt);
  1610. begin
  1611. {$ifdef DEBUG_PPU}
  1612. ppu_log('putptruint');
  1613. inc_log_level;
  1614. {$endif}
  1615. {$if sizeof(TConstPtrUInt)=8}
  1616. putint64(int64(v));
  1617. {$else}
  1618. putlongint(longint(v));
  1619. {$endif}
  1620. {$ifdef DEBUG_PPU}
  1621. dec_log_level;
  1622. {$endif}
  1623. end;
  1624. procedure tentryfile.putaword(i:aword);
  1625. begin
  1626. {$ifdef DEBUG_PPU}
  1627. ppu_log('putaword');
  1628. inc_log_level;
  1629. ppu_log_val(tostr(i));
  1630. {$endif}
  1631. putdata(i,sizeof(aword));
  1632. {$ifdef DEBUG_PPU}
  1633. dec_log_level;
  1634. {$endif}
  1635. end;
  1636. procedure tentryfile.putreal(d:entryreal);
  1637. var
  1638. hd : double;
  1639. begin
  1640. if target_info.system=system_x86_64_win64 then
  1641. begin
  1642. {$ifdef DEBUG_PPU}
  1643. ppu_log('putreal,size='+tostr(sizeof(hd)));
  1644. inc_log_level;
  1645. ppu_log_val(realtostr(d));
  1646. {$endif}
  1647. hd:=d;
  1648. putdata(hd,sizeof(hd));
  1649. end
  1650. else
  1651. begin
  1652. {$ifdef DEBUG_PPU}
  1653. ppu_log('putreal,size='+tostr(sizeof(d)));
  1654. inc_log_level;
  1655. ppu_log_val(realtostr(d));
  1656. {$endif}
  1657. putdata(d,sizeof(entryreal));
  1658. end;
  1659. {$ifdef DEBUG_PPU}
  1660. dec_log_level;
  1661. {$endif}
  1662. end;
  1663. procedure tentryfile.putboolean(b:boolean);
  1664. begin
  1665. {$ifdef DEBUG_PPU}
  1666. ppu_log('putboolean');
  1667. inc_log_level;
  1668. {$endif}
  1669. putbyte(byte(b));
  1670. {$ifdef DEBUG_PPU}
  1671. dec_log_level;
  1672. {$endif}
  1673. end;
  1674. procedure tentryfile.putstring(const s:string);
  1675. begin
  1676. {$ifdef DEBUG_PPU}
  1677. { The reading method uses getbyte, so fake it here }
  1678. ppu_log('putbyte');
  1679. inc_log_level;
  1680. inc(bufidx);
  1681. ppu_log('putstring,size='+tostr(length(s)+1));
  1682. dec(bufidx);
  1683. ppu_log_val(s);
  1684. {$endif}
  1685. putdata(s,length(s)+1);
  1686. {$ifdef DEBUG_PPU}
  1687. dec_log_level;
  1688. {$endif}
  1689. end;
  1690. procedure tentryfile.putansistring(const s:ansistring);
  1691. var
  1692. len: longint;
  1693. begin
  1694. len:=length(s);
  1695. {$ifdef DEBUG_PPU}
  1696. ppu_log('putansistring');
  1697. inc_log_level;
  1698. ppu_log_val(s);
  1699. {$endif}
  1700. putlongint(len);
  1701. if len>0 then
  1702. putdata(s[1],len);
  1703. {$ifdef DEBUG_PPU}
  1704. dec_log_level;
  1705. {$endif}
  1706. end;
  1707. procedure tentryfile.putset(const arr: array of byte);
  1708. {$ifdef DEBUG_PPU}
  1709. var
  1710. i : byte;
  1711. {$endif}
  1712. begin
  1713. {$ifdef DEBUG_PPU}
  1714. ppu_log('putset');
  1715. inc_log_level;
  1716. {$endif}
  1717. putdata(arr,sizeof(arr));
  1718. {$ifdef DEBUG_PPU}
  1719. for i:=0 to 31 do
  1720. ppu_log_val('byte['+tostr(i)+']=$'+hexstr(arr[i],2));
  1721. dec_log_level;
  1722. {$endif}
  1723. end;
  1724. procedure tentryfile.tempclose;
  1725. begin
  1726. if not closed then
  1727. begin
  1728. closepos:=f.Position;
  1729. f.Free;
  1730. f:=nil;
  1731. closed:=true;
  1732. tempclosed:=true;
  1733. end;
  1734. end;
  1735. function tentryfile.tempopen:boolean;
  1736. begin
  1737. tempopen:=false;
  1738. if not closed or not tempclosed then
  1739. exit;
  1740. { MG: not sure, if this is correct
  1741. f.position:=0;
  1742. No, f was freed in tempclose above, we need to
  1743. recreate it. PM 2011/06/06 }
  1744. try
  1745. f:=CFileStreamClass.Create(fname,fmOpenRead);
  1746. except
  1747. exit;
  1748. end;
  1749. closed:=false;
  1750. tempclosed:=false;
  1751. { restore state }
  1752. f.Position:=closepos;
  1753. tempopen:=true;
  1754. end;
  1755. end.