ppudump.pp 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by the FPC Development Team
  4. Dumps the contents of a FPC unit file (PPU File)
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************}
  17. {$ifdef TP}
  18. {$N+,E+}
  19. {$endif}
  20. program pppdump;
  21. uses
  22. ppu;
  23. const
  24. Version = 'Version 1.10';
  25. Title = 'PPU-Analyser';
  26. Copyright = 'Copyright (c) 1998-2002 by the Free Pascal Development Team';
  27. { verbosity }
  28. v_none = $0;
  29. v_header = $1;
  30. v_defs = $2;
  31. v_syms = $4;
  32. v_interface = $8;
  33. v_implementation = $10;
  34. v_browser = $20;
  35. v_all = $ff;
  36. type
  37. { Copied from systems.pas }
  38. ttargetcpu=
  39. (
  40. no_cpu, { 0 }
  41. i386, { 1 }
  42. m68k, { 2 }
  43. alpha, { 3 }
  44. powerpc, { 4 }
  45. sparc, { 5 }
  46. vm { 6 }
  47. );
  48. var
  49. ppufile : tppufile;
  50. space : string;
  51. read_member : boolean;
  52. unitindex : longint;
  53. verbose : longint;
  54. {****************************************************************************
  55. Helper Routines
  56. ****************************************************************************}
  57. const has_errors : boolean = false;
  58. Procedure Error(const S : string);
  59. Begin
  60. Writeln(S);
  61. has_errors:=true;
  62. End;
  63. Function Target2Str(w:longint):string;
  64. type
  65. { taken from systems.pas }
  66. ttarget =
  67. (
  68. target_none, { 0 }
  69. target_i386_GO32V1, { 1 }
  70. target_i386_GO32V2, { 2 }
  71. target_i386_linux, { 3 }
  72. target_i386_OS2, { 4 }
  73. target_i386_Win32, { 5 }
  74. target_i386_freebsd, { 6 }
  75. target_m68k_Amiga, { 7 }
  76. target_m68k_Atari, { 8 }
  77. target_m68k_Mac, { 9 }
  78. target_m68k_linux, { 10 }
  79. target_m68k_PalmOS, { 11 }
  80. target_alpha_linux, { 12 }
  81. target_powerpc_linux, { 13 }
  82. target_powerpc_macos, { 14 }
  83. target_i386_sunos, { 15 }
  84. target_i386_beos, { 16 }
  85. target_i386_netbsd, { 17 }
  86. target_m68k_netbsd, { 18 }
  87. target_i386_Netware, { 19 }
  88. target_i386_qnx, { 20 }
  89. target_i386_wdosx, { 21 }
  90. target_sparc_sunos, { 22 }
  91. target_sparc_linux { 23 }
  92. );
  93. const
  94. Targets : array[ttarget] of string[16]=(
  95. { 0 } 'none',
  96. { 1 } 'GO32V1',
  97. { 2 } 'GO32V2',
  98. { 3 } 'Linux-i386',
  99. { 4 } 'OS/2',
  100. { 5 } 'Win32',
  101. { 6 } 'FreeBSD-i386',
  102. { 7 } 'Amiga',
  103. { 8 } 'Atari',
  104. { 9 } 'MacOS-m68k',
  105. { 10 } 'Linux-m68k',
  106. { 11 } 'PalmOS-m68k',
  107. { 12 } 'Linux-alpha',
  108. { 13 } 'Linux-ppc',
  109. { 14 } 'MacOS-ppc',
  110. { 15 } 'Solaris-i386',
  111. { 16 } 'BeOS-i386',
  112. { 17 } 'NetBSD-i386',
  113. { 18 } 'NetBSD-m68k',
  114. { 19 } 'Netware',
  115. { 20 } 'Qnx-i386',
  116. { 21 } 'WDOSX-i386',
  117. { 22 } 'Solaris-sparc',
  118. { 23 } 'Linux-sparc'
  119. );
  120. begin
  121. if w<=ord(high(ttarget)) then
  122. Target2Str:=Targets[ttarget(w)]
  123. else
  124. Target2Str:='<Unknown>';
  125. end;
  126. Function Cpu2Str(w:longint):string;
  127. const
  128. CpuTxt : array[ttargetcpu] of string[7]=
  129. ('none','i386','m68k','alpha','powerpc','sparc','vis');
  130. begin
  131. if w<=ord(high(ttargetcpu)) then
  132. Cpu2Str:=CpuTxt[ttargetcpu(w)]
  133. else
  134. Cpu2Str:='<Unknown>';
  135. end;
  136. function PPUFlags2Str(flags:longint):string;
  137. type
  138. tflagopt=record
  139. mask : longint;
  140. str : string[30];
  141. end;
  142. const
  143. flagopts=15;
  144. flagopt : array[1..flagopts] of tflagopt=(
  145. (mask: $1 ;str:'init'),
  146. (mask: $2 ;str:'final'),
  147. (mask: $4 ;str:'big_endian'),
  148. (mask: $8 ;str:'dbx'),
  149. (mask: $10 ;str:'browser'),
  150. (mask: $20 ;str:'in_library'),
  151. (mask: $40 ;str:'smart_linked'),
  152. (mask: $80 ;str:'static_linked'),
  153. (mask: $100 ;str:'shared_linked'),
  154. (mask: $200 ;str:'local_browser'),
  155. (mask: $400 ;str:'no_link'),
  156. (mask: $800 ;str:'has_resources'),
  157. (mask: $1000 ;str:'little_endian'),
  158. (mask: $2000 ;str:'release'),
  159. (mask: $4000 ;str:'local_threadvars')
  160. );
  161. var
  162. i : longint;
  163. first : boolean;
  164. s : string;
  165. begin
  166. s:='';
  167. if flags<>0 then
  168. begin
  169. first:=true;
  170. for i:=1to flagopts do
  171. if (flags and flagopt[i].mask)<>0 then
  172. begin
  173. if first then
  174. first:=false
  175. else
  176. s:=s+', ';
  177. s:=s+flagopt[i].str;
  178. end;
  179. end
  180. else
  181. s:='none';
  182. PPUFlags2Str:=s;
  183. end;
  184. const
  185. HexTbl : array[0..15] of char='0123456789ABCDEF';
  186. function HexB(b:byte):string;
  187. begin
  188. HexB[0]:=#2;
  189. HexB[1]:=HexTbl[b shr 4];
  190. HexB[2]:=HexTbl[b and $f];
  191. end;
  192. function hexstr(val : cardinal;cnt : byte) : string;
  193. const
  194. HexTbl : array[0..15] of char='0123456789ABCDEF';
  195. var
  196. i : longint;
  197. begin
  198. hexstr[0]:=char(cnt);
  199. for i:=cnt downto 1 do
  200. begin
  201. hexstr[i]:=hextbl[val and $f];
  202. val:=val shr 4;
  203. end;
  204. end;
  205. {****************************************************************************
  206. Read Routines
  207. ****************************************************************************}
  208. function getint64:int64;
  209. var
  210. l1,l2 : longint;
  211. begin
  212. l1:=ppufile.getlongint;
  213. l2:=ppufile.getlongint;
  214. getint64:=(int64(l2) shl 32) or qword(l1);
  215. end;
  216. Procedure ReadLinkContainer(const prefix:string);
  217. {
  218. Read a serie of strings and write to the screen starting every line
  219. with prefix
  220. }
  221. function maskstr(m:longint):string;
  222. const
  223. { link options }
  224. link_none = $0;
  225. link_allways = $1;
  226. link_static = $2;
  227. link_smart = $4;
  228. link_shared = $8;
  229. var
  230. s : string;
  231. begin
  232. s:='';
  233. if (m and link_allways)<>0 then
  234. s:=s+'always ';
  235. if (m and link_static)<>0 then
  236. s:=s+'static ';
  237. if (m and link_smart)<>0 then
  238. s:=s+'smart ';
  239. if (m and link_shared)<>0 then
  240. s:=s+'shared ';
  241. maskstr:=s;
  242. end;
  243. var
  244. s : string;
  245. m : longint;
  246. begin
  247. while not ppufile.endofentry do
  248. begin
  249. s:=ppufile.getstring;
  250. m:=ppufile.getlongint;
  251. WriteLn(prefix,s,' (',maskstr(m),')');
  252. end;
  253. end;
  254. Procedure ReadContainer(const prefix:string);
  255. {
  256. Read a serie of strings and write to the screen starting every line
  257. with prefix
  258. }
  259. begin
  260. while not ppufile.endofentry do
  261. WriteLn(prefix,ppufile.getstring);
  262. end;
  263. Procedure ReadRef;
  264. begin
  265. if (verbose and v_browser)=0 then
  266. exit;
  267. while (not ppufile.endofentry) and (not ppufile.error) do
  268. Writeln(space,' - Refered : ',ppufile.getword,', (',ppufile.getlongint,',',ppufile.getword,')');
  269. end;
  270. Procedure ReadPosInfo;
  271. var
  272. info : byte;
  273. fileindex,line,column : longint;
  274. begin
  275. with ppufile do
  276. begin
  277. {
  278. info byte layout in bits:
  279. 0-1 - amount of bytes for fileindex
  280. 2-3 - amount of bytes for line
  281. 4-5 - amount of bytes for column
  282. }
  283. info:=getbyte;
  284. case (info and $03) of
  285. 0 : fileindex:=getbyte;
  286. 1 : fileindex:=getword;
  287. 2 : fileindex:=(getbyte shl 16) or getword;
  288. 3 : fileindex:=getlongint;
  289. end;
  290. case ((info shr 2) and $03) of
  291. 0 : line:=getbyte;
  292. 1 : line:=getword;
  293. 2 : line:=(getbyte shl 16) or getword;
  294. 3 : line:=getlongint;
  295. end;
  296. case ((info shr 4) and $03) of
  297. 0 : column:=getbyte;
  298. 1 : column:=getword;
  299. 2 : column:=(getbyte shl 16) or getword;
  300. 3 : column:=getlongint;
  301. end;
  302. Writeln(fileindex,' (',line,',',column,')');
  303. end;
  304. end;
  305. function readderef(const s:string;skipnil:boolean):boolean;
  306. type
  307. tdereftype = (derefnil,derefaktrecordindex,derefaktstaticindex,
  308. derefunit,derefrecord,derefindex,
  309. dereflocal,derefpara,derefaktlocalindex);
  310. var
  311. b : tdereftype;
  312. begin
  313. readderef:=true;
  314. repeat
  315. b:=tdereftype(ppufile.getbyte);
  316. case b of
  317. derefnil :
  318. begin
  319. if not skipnil then
  320. writeln('nil');
  321. readderef:=false;
  322. break;
  323. end;
  324. derefaktrecordindex :
  325. begin
  326. writeln('AktRecord ',s,' ',ppufile.getword);
  327. break;
  328. end;
  329. derefaktstaticindex :
  330. begin
  331. writeln('AktStatic ',s,' ',ppufile.getword);
  332. break;
  333. end;
  334. derefaktlocalindex :
  335. begin
  336. writeln('AktLocal ',s,' ',ppufile.getword);
  337. break;
  338. end;
  339. derefunit :
  340. begin
  341. writeln('Unit ',ppufile.getword);
  342. break;
  343. end;
  344. derefrecord :
  345. begin
  346. write('RecordDef ',ppufile.getword,', ');
  347. end;
  348. derefpara :
  349. begin
  350. write('Parameter of procdef ',ppufile.getword,', ');
  351. end;
  352. dereflocal :
  353. begin
  354. write('Local of procdef ',ppufile.getword,', ');
  355. end;
  356. derefindex :
  357. begin
  358. write(s,' ',ppufile.getword,', ');
  359. end;
  360. else
  361. begin
  362. writeln('!! unsupported dereftyp: ',ord(b));
  363. break;
  364. end;
  365. end;
  366. until false;
  367. end;
  368. function readdefref:boolean;
  369. begin
  370. readdefref:=readderef('Definition',false);
  371. end;
  372. function readsymref:boolean;
  373. begin
  374. readsymref:=readderef('Symbol',false);
  375. end;
  376. procedure readtype;
  377. var
  378. b1,b2 : boolean;
  379. begin
  380. b1:=readderef('Definition',true);
  381. b2:=readderef('Symbol',true);
  382. if not(b1 or b2) then
  383. Writeln('nil')
  384. else
  385. if (b1 and b2) then
  386. Writeln('!! Type has both definition and symbol stored');
  387. end;
  388. procedure readsymlist(const s:string);
  389. type
  390. tsltype = (sl_none,
  391. sl_load,
  392. sl_call,
  393. sl_subscript,
  394. sl_vec
  395. );
  396. const
  397. slstr : array[tsltype] of string[9] = ('',
  398. 'load',
  399. 'call',
  400. 'subscript',
  401. 'vec'
  402. );
  403. var
  404. sl : tsltype;
  405. begin
  406. readdefref;
  407. repeat
  408. sl:=tsltype(ppufile.getbyte);
  409. if sl=sl_none then
  410. break;
  411. write(s,'(',slstr[sl],') ');
  412. case sl of
  413. sl_call,
  414. sl_load,
  415. sl_subscript :
  416. readsymref;
  417. sl_vec :
  418. writeln(ppufile.getlongint);
  419. end;
  420. until false;
  421. end;
  422. { Read abstract procdef and return if inline procdef }
  423. type
  424. tproccalloption=(pocall_none,
  425. pocall_cdecl, { procedure uses C styled calling }
  426. pocall_cppdecl, { C++ calling conventions }
  427. pocall_compilerproc, { Procedure is used for internal compiler calls }
  428. pocall_far16, { Far16 for OS/2 }
  429. pocall_fpccall, { FPC default calling }
  430. pocall_inline, { Procedure is an assembler macro }
  431. pocall_internconst, { procedure has constant evaluator intern }
  432. pocall_internproc, { Procedure has compiler magic}
  433. pocall_palmossyscall, { procedure is a PalmOS system call }
  434. pocall_pascal, { pascal standard left to right }
  435. pocall_register, { procedure uses register (fastcall) calling }
  436. pocall_safecall, { safe call calling conventions }
  437. pocall_stdcall, { procedure uses stdcall call }
  438. pocall_system { system call }
  439. );
  440. tproccalloptions=set of tproccalloption;
  441. tproctypeoption=(potype_none,
  442. potype_proginit, { Program initialization }
  443. potype_unitinit, { unit initialization }
  444. potype_unitfinalize, { unit finalization }
  445. potype_constructor, { Procedure is a constructor }
  446. potype_destructor, { Procedure is a destructor }
  447. potype_operator { Procedure defines an operator }
  448. );
  449. tproctypeoptions=set of tproctypeoption;
  450. tprocoption=(po_none,
  451. po_classmethod, { class method }
  452. po_virtualmethod, { Procedure is a virtual method }
  453. po_abstractmethod, { Procedure is an abstract method }
  454. po_staticmethod, { static method }
  455. po_overridingmethod, { method with override directive }
  456. po_methodpointer, { method pointer, only in procvardef, also used for 'with object do' }
  457. po_containsself, { self is passed explicit to the compiler }
  458. po_interrupt, { Procedure is an interrupt handler }
  459. po_iocheck, { IO checking should be done after a call to the procedure }
  460. po_assembler, { Procedure is written in assembler }
  461. po_msgstr, { method for string message handling }
  462. po_msgint, { method for int message handling }
  463. po_exports, { Procedure has export directive (needed for OS/2) }
  464. po_external, { Procedure is external (in other object or lib)}
  465. po_savestdregs, { save std regs cdecl and stdcall need that ! }
  466. po_saveregisters, { save all registers }
  467. po_overload, { procedure is declared with overload directive }
  468. po_varargs { printf like arguments }
  469. );
  470. tprocoptions=set of tprocoption;
  471. function read_abstract_proc_def:tproccalloption;
  472. type
  473. tproccallopt=record
  474. mask : tproccalloption;
  475. str : string[30];
  476. end;
  477. tproctypeopt=record
  478. mask : tproctypeoption;
  479. str : string[30];
  480. end;
  481. tprocopt=record
  482. mask : tprocoption;
  483. str : string[30];
  484. end;
  485. const
  486. proccalloptionStr : array[tproccalloption] of string[14]=('',
  487. 'CDecl',
  488. 'CPPDecl',
  489. 'CompilerProc',
  490. 'Far16',
  491. 'FPCCall',
  492. 'Inline',
  493. 'InternConst',
  494. 'InternProc',
  495. 'PalmOSSysCall',
  496. 'Pascal',
  497. 'Register',
  498. 'SafeCall',
  499. 'StdCall',
  500. 'System'
  501. );
  502. proctypeopts=6;
  503. proctypeopt : array[1..proctypeopts] of tproctypeopt=(
  504. (mask:potype_proginit; str:'ProgInit'),
  505. (mask:potype_unitinit; str:'UnitInit'),
  506. (mask:potype_unitfinalize;str:'UnitFinalize'),
  507. (mask:potype_constructor; str:'Constructor'),
  508. (mask:potype_destructor; str:'Destructor'),
  509. (mask:potype_operator; str:'Operator')
  510. );
  511. procopts=18;
  512. procopt : array[1..procopts] of tprocopt=(
  513. (mask:po_classmethod; str:'ClassMethod'),
  514. (mask:po_virtualmethod; str:'VirtualMethod'),
  515. (mask:po_abstractmethod; str:'AbstractMethod'),
  516. (mask:po_staticmethod; str:'StaticMethod'),
  517. (mask:po_overridingmethod;str:'OverridingMethod'),
  518. (mask:po_methodpointer; str:'MethodPointer'),
  519. (mask:po_containsself; str:'ContainsSelf'),
  520. (mask:po_interrupt; str:'Interrupt'),
  521. (mask:po_iocheck; str:'IOCheck'),
  522. (mask:po_assembler; str:'Assembler'),
  523. (mask:po_msgstr; str:'MsgStr'),
  524. (mask:po_msgint; str:'MsgInt'),
  525. (mask:po_exports; str:'Exports'),
  526. (mask:po_external; str:'External'),
  527. (mask:po_savestdregs; str:'SaveStdRegs'),
  528. (mask:po_saveregisters; str:'SaveRegisters'),
  529. (mask:po_overload; str:'Overload'),
  530. (mask:po_varargs; str:'VarArgs')
  531. );
  532. tvarspez : array[0..3] of string[5]=('Value','Const','Var ','Out ');
  533. var
  534. proctypeoption : tproctypeoption;
  535. proccalloption : tproccalloption;
  536. procoptions : tprocoptions;
  537. i,params : longint;
  538. first : boolean;
  539. begin
  540. write(space,' Return type : ');
  541. readtype;
  542. writeln(space,' Fpu used : ',ppufile.getbyte);
  543. proctypeoption:=tproctypeoption(ppufile.getbyte);
  544. if proctypeoption<>potype_none then
  545. begin
  546. write(space,' TypeOption : ');
  547. first:=true;
  548. for i:=1to proctypeopts do
  549. if (proctypeopt[i].mask=proctypeoption) then
  550. begin
  551. if first then
  552. first:=false
  553. else
  554. write(', ');
  555. write(proctypeopt[i].str);
  556. end;
  557. writeln;
  558. end;
  559. proccalloption:=tproccalloption(ppufile.getbyte);
  560. read_abstract_proc_def:=proccalloption;
  561. writeln(space,' CallOption : ',proccalloptionStr[proccalloption]);
  562. ppufile.getsmallset(procoptions);
  563. if procoptions<>[] then
  564. begin
  565. write(space,' Options : ');
  566. first:=true;
  567. for i:=1to procopts do
  568. if (procopt[i].mask in procoptions) then
  569. begin
  570. if first then
  571. first:=false
  572. else
  573. write(', ');
  574. write(procopt[i].str);
  575. end;
  576. writeln;
  577. end;
  578. params:=ppufile.getword;
  579. writeln(space,' Nr of parameters : ',params);
  580. if params>0 then
  581. begin
  582. repeat
  583. write(space,' - ',tvarspez[ppufile.getbyte],' : ');
  584. readtype;
  585. write(space,' Default : ');
  586. readsymref;
  587. write(space,' Symbol : ');
  588. readsymref;
  589. dec(params);
  590. until params=0;
  591. end;
  592. end;
  593. procedure readcommonsym(const s:string);
  594. type
  595. tsymoption=(sp_none,
  596. sp_public,
  597. sp_private,
  598. sp_published,
  599. sp_protected,
  600. sp_forwarddef,
  601. sp_static,
  602. sp_primary_typesym { this is for typesym, to know who is the primary symbol of a def }
  603. );
  604. tsymoptions=set of tsymoption;
  605. tsymopt=record
  606. mask : tsymoption;
  607. str : string[30];
  608. end;
  609. const
  610. symopts=7;
  611. symopt : array[1..symopts] of tsymopt=(
  612. (mask:sp_public; str:'Public'),
  613. (mask:sp_private; str:'Private'),
  614. (mask:sp_published; str:'Published'),
  615. (mask:sp_protected; str:'Protected'),
  616. (mask:sp_forwarddef; str:'ForwardDef'),
  617. (mask:sp_static; str:'Static'),
  618. (mask:sp_primary_typesym;str:'PrimaryTypeSym')
  619. );
  620. var
  621. symoptions : tsymoptions;
  622. i : longint;
  623. first : boolean;
  624. begin
  625. writeln(space,'** Symbol Nr. ',ppufile.getword,' **');
  626. writeln(space,s,ppufile.getstring);
  627. ppufile.getsmallset(symoptions);
  628. if symoptions<>[] then
  629. begin
  630. write(space,' File Pos: ');
  631. readposinfo;
  632. write(space,' SymOptions: ');
  633. first:=true;
  634. for i:=1to symopts do
  635. if (symopt[i].mask in symoptions) then
  636. begin
  637. if first then
  638. first:=false
  639. else
  640. write(', ');
  641. write(symopt[i].str);
  642. end;
  643. writeln;
  644. end;
  645. end;
  646. procedure readcommondef(const s:string);
  647. type
  648. tdefoption=(df_none,
  649. df_has_inittable, { init data has been generated }
  650. df_has_rttitable { rtti data has been generated }
  651. );
  652. tdefoptions=set of tdefoption;
  653. var
  654. defopts : tdefoptions;
  655. begin
  656. writeln(space,'** Definition Nr. ',ppufile.getword,' **');
  657. writeln(space,s);
  658. write (space,' Type symbol : ');
  659. readsymref;
  660. ppufile.getsmallset(defopts);
  661. if df_has_rttitable in defopts then
  662. begin
  663. write (space,' RTTI symbol : ');
  664. readsymref;
  665. end;
  666. if df_has_inittable in defopts then
  667. begin
  668. write (space,' Init symbol : ');
  669. readsymref;
  670. end;
  671. end;
  672. {****************************************************************************
  673. Read Symbols Part
  674. ****************************************************************************}
  675. procedure readsymbols;
  676. Const
  677. vo_is_C_var = 2;
  678. Type
  679. absolutetyp = (tovar,toasm,toaddr);
  680. tconsttyp = (constnone,
  681. constord,conststring,constreal,constbool,
  682. constint,constchar,constset,constpointer,constnil,
  683. constresourcestring
  684. );
  685. var
  686. b : byte;
  687. pc : pchar;
  688. totalsyms,
  689. symcnt,
  690. i,j,len : longint;
  691. begin
  692. symcnt:=1;
  693. with ppufile do
  694. begin
  695. if space<>'' then
  696. Writeln(space,'-----------------------------');
  697. if readentry=ibstartsyms then
  698. begin
  699. totalsyms:=getlongint;
  700. Writeln(space,'Number of symbols : ',totalsyms);
  701. Writeln(space,'Symtable datasize : ',getlongint);
  702. Writeln(space,'Symtable alignment: ',getlongint);
  703. end
  704. else
  705. begin
  706. totalsyms:=-1;
  707. Writeln('!! ibstartsym not found');
  708. end;
  709. repeat
  710. b:=readentry;
  711. if not (b in [iberror,ibendsyms]) then
  712. inc(symcnt);
  713. case b of
  714. ibunitsym :
  715. readcommonsym('Unit symbol ');
  716. iblabelsym :
  717. readcommonsym('Label symbol ');
  718. ibtypesym :
  719. begin
  720. readcommonsym('Type symbol ');
  721. write(space,' Result Type: ');
  722. readtype;
  723. end;
  724. ibprocsym :
  725. begin
  726. readcommonsym('Procedure symbol ');
  727. repeat
  728. write(space,' Definition: ');
  729. until not readdefref;
  730. end;
  731. ibconstsym :
  732. begin
  733. readcommonsym('Constant symbol ');
  734. b:=getbyte;
  735. case tconsttyp(b) of
  736. constord :
  737. begin
  738. write (space,'OrdinalType: ');
  739. readtype;
  740. writeln (space,' Value: ',getlongint)
  741. end;
  742. constpointer :
  743. begin
  744. write (space,' Pointer Type: ');
  745. readtype;
  746. writeln (space,' Value: ',getlongint)
  747. end;
  748. conststring,
  749. constresourcestring :
  750. begin
  751. len:=getlongint;
  752. getmem(pc,len+1);
  753. getdata(pc^,len);
  754. writeln(space,' Length: ',len);
  755. writeln(space,' Value: "',pc,'"');
  756. freemem(pc,len+1);
  757. if tconsttyp(b)=constresourcestring then
  758. writeln(space,' Index: ',getlongint);
  759. end;
  760. constreal :
  761. writeln(space,' Value: ',getreal);
  762. constbool :
  763. if getlongint<>0 then
  764. writeln (space,' Value : True')
  765. else
  766. writeln (space,' Value: False');
  767. constint :
  768. writeln(space,' Value: ',getint64);
  769. constchar :
  770. writeln(space,' Value: "'+chr(getlongint)+'"');
  771. constset :
  772. begin
  773. write (space,' Set Type: ');
  774. readtype;
  775. for i:=1to 4 do
  776. begin
  777. write (space,' Value: ');
  778. for j:=1to 8 do
  779. begin
  780. if j>1 then
  781. write(',');
  782. write(hexb(getbyte));
  783. end;
  784. writeln;
  785. end;
  786. end;
  787. else
  788. Writeln ('!! Invalid unit format : Invalid const type encountered: ',b);
  789. end;
  790. end;
  791. ibvarsym :
  792. begin
  793. readcommonsym('Variable symbol ');
  794. writeln(space,' Type: ',getbyte);
  795. if read_member then
  796. writeln(space,' Address: ',getlongint);
  797. write (space,' Var Type: ');
  798. readtype;
  799. i:=getlongint;
  800. writeln(space,' Options: ',i);
  801. if (i and vo_is_C_var)<>0 then
  802. writeln(space,' Mangledname: ',getstring);
  803. end;
  804. ibenumsym :
  805. begin
  806. readcommonsym('Enumeration symbol ');
  807. write (space,' Definition: ');
  808. readdefref;
  809. writeln(space,' Value: ',getlongint);
  810. end;
  811. ibsyssym :
  812. begin
  813. readcommonsym('Internal system symbol ');
  814. writeln(space,' Internal Nr: ',getlongint);
  815. end;
  816. ibrttisym :
  817. begin
  818. readcommonsym('RTTI symbol ');
  819. writeln(space,' RTTI Type: ',getbyte);
  820. end;
  821. ibtypedconstsym :
  822. begin
  823. readcommonsym('Typed constant ');
  824. write (space,' Constant Type: ');
  825. readtype;
  826. writeln(space,' Label: ',getstring);
  827. writeln(space,' ReallyConst: ',(getbyte<>0));
  828. end;
  829. ibabsolutesym :
  830. begin
  831. readcommonsym('Absolute variable symbol ');
  832. writeln(space,' Type: ',getbyte);
  833. if read_member then
  834. writeln(space,' Address: ',getlongint);
  835. write (space,' Var Type: ');
  836. readtype;
  837. writeln(space,' Options: ',getlongint);
  838. Write (space,' Relocated to ');
  839. b:=getbyte;
  840. case absolutetyp(b) of
  841. tovar :
  842. Writeln('Name : ',getstring);
  843. toasm :
  844. Writeln('Assembler name : ',getstring);
  845. toaddr :
  846. begin
  847. Write('Address : ',getlongint);
  848. WriteLn(' (Far: ',getbyte<>0,')');
  849. end;
  850. else
  851. Writeln ('!! Invalid unit format : Invalid absolute type encountered: ',b);
  852. end;
  853. end;
  854. ibpropertysym :
  855. begin
  856. readcommonsym('Property ');
  857. i:=getlongint;
  858. writeln(space,' PropOptions: ',i);
  859. if (i and 32)>0 then
  860. begin
  861. write (space,'OverrideProp: ');
  862. readsymref;
  863. end
  864. else
  865. begin
  866. write (space,' Prop Type: ');
  867. readtype;
  868. writeln(space,' Index: ',getlongint);
  869. writeln(space,' Default: ',getlongint);
  870. write (space,' Index Type: ');
  871. readtype;
  872. write (space,' Readaccess: ');
  873. readsymlist(space+' Sym: ');
  874. write (space,' Writeaccess: ');
  875. readsymlist(space+' Sym: ');
  876. write (space,'Storedaccess: ');
  877. readsymlist(space+' Sym: ');
  878. end;
  879. end;
  880. ibfuncretsym :
  881. begin
  882. readcommonsym('Func return value ');
  883. write (space,' Return Type: ');
  884. readtype;
  885. writeln(space,' Address: ',getlongint);
  886. end;
  887. iberror :
  888. begin
  889. Writeln('!! Error in PPU');
  890. exit;
  891. end;
  892. ibendsyms :
  893. break;
  894. else
  895. WriteLn('!! Skipping unsupported PPU Entry in Symbols: ',b);
  896. end;
  897. if not EndOfEntry then
  898. Writeln('!! Entry has more information stored');
  899. until false;
  900. if (totalsyms<>-1) and (symcnt-1<>totalsyms) then
  901. Writeln('!! Only read ',symcnt-1,' of ',totalsyms,' symbols');
  902. end;
  903. end;
  904. {****************************************************************************
  905. Read defintions Part
  906. ****************************************************************************}
  907. procedure getusedregisters_i386;
  908. type
  909. tregister = (R_NO,
  910. R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
  911. R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
  912. R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_BH,R_DH,
  913. R_CS,R_DS,R_ES,R_SS,R_FS,R_GS,
  914. R_ST,R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7,
  915. R_DR0,R_DR1,R_DR2,R_DR3,R_DR6,R_DR7,
  916. R_CR0,R_CR2,R_CR3,R_CR4,
  917. R_TR3,R_TR4,R_TR5,R_TR6,R_TR7,
  918. R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7,
  919. R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7
  920. );
  921. tregisterset = set of tregister;
  922. reg2strtable = array[tregister] of string[6];
  923. const
  924. std_reg2str : reg2strtable = ('',
  925. 'eax','ecx','edx','ebx','esp','ebp','esi','edi',
  926. 'ax','cx','dx','bx','sp','bp','si','di',
  927. 'al','cl','dl','bl','ah','ch','bh','dh',
  928. 'cs','ds','es','ss','fs','gs',
  929. 'st','st(0)','st(1)','st(2)','st(3)','st(4)','st(5)','st(6)','st(7)',
  930. 'dr0','dr1','dr2','dr3','dr6','dr7',
  931. 'cr0','cr2','cr3','cr4',
  932. 'tr3','tr4','tr5','tr6','tr7',
  933. 'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
  934. 'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
  935. );
  936. firstsaveintreg = R_EAX;
  937. lastsaveintreg = R_EBX;
  938. firstsavefpureg = R_NO;
  939. lastsavefpureg = R_NO;
  940. firstsavemmreg = R_MM0;
  941. lastsavemmreg = R_MM7;
  942. var
  943. regs: tregisterset;
  944. r: tregister;
  945. first: boolean;
  946. begin
  947. first := true;
  948. ppufile.getnormalset(regs);
  949. for r := firstsaveintreg to lastsaveintreg do
  950. if r in regs then
  951. begin
  952. if not first then
  953. write(', ')
  954. else
  955. first := false;
  956. write(std_reg2str[r])
  957. end;
  958. if (firstsavefpureg <> R_NO) then
  959. for r := firstsavefpureg to lastsavefpureg do
  960. if r in regs then
  961. begin
  962. if not first then
  963. write(', ')
  964. else
  965. first := false;
  966. write(std_reg2str[r])
  967. end;
  968. if (firstsavemmreg <> R_NO) then
  969. for r := firstsavemmreg to lastsavemmreg do
  970. if r in regs then
  971. begin
  972. if not first then
  973. write(', ')
  974. else
  975. first := false;
  976. write(std_reg2str[r])
  977. end;
  978. writeln;
  979. end;
  980. procedure readdefinitions(start_read : boolean);
  981. type
  982. tsettype = (normset,smallset,varset);
  983. tbasetype = (
  984. uvoid,
  985. u8bit,u16bit,u32bit,u64bit,
  986. s8bit,s16bit,s32bit,s64bit,
  987. bool8bit,bool16bit,bool32bit,
  988. uchar,uwidechar
  989. );
  990. tobjectdeftype = (odt_none,
  991. odt_class,
  992. odt_object,
  993. odt_interfacecom,
  994. odt_interfacecorba,
  995. odt_cppclass
  996. );
  997. var
  998. b : byte;
  999. oldread_member : boolean;
  1000. totaldefs,l,j,
  1001. defcnt : longint;
  1002. calloption : tproccalloption;
  1003. regs : set of char;
  1004. begin
  1005. defcnt:=0;
  1006. with ppufile do
  1007. begin
  1008. if space<>'' then
  1009. Writeln(space,'-----------------------------');
  1010. if not start_read then
  1011. if readentry=ibstartdefs then
  1012. begin
  1013. totaldefs:=getlongint;
  1014. Writeln(space,'Number of definitions: ',totaldefs);
  1015. end
  1016. else
  1017. begin
  1018. totaldefs:=-1;
  1019. Writeln('!! ibstartdef not found');
  1020. end;
  1021. repeat
  1022. b:=readentry;
  1023. if not (b in [iberror,ibenddefs]) then
  1024. inc(defcnt);
  1025. case b of
  1026. ibpointerdef :
  1027. begin
  1028. readcommondef('Pointer definition');
  1029. write (space,' Pointed Type : ');
  1030. readtype;
  1031. writeln(space,' Is Far : ',(getbyte<>0));
  1032. end;
  1033. iborddef :
  1034. begin
  1035. readcommondef('Ordinal definition');
  1036. write (space,' Base type : ');
  1037. b:=getbyte;
  1038. case tbasetype(b) of
  1039. uvoid : writeln('uvoid');
  1040. u8bit : writeln('u8bit');
  1041. u16bit : writeln('u16bit');
  1042. u32bit : writeln('s32bit');
  1043. u64bit : writeln('u64bit');
  1044. s8bit : writeln('s8bit');
  1045. s16bit : writeln('s16bit');
  1046. s32bit : writeln('s32bit');
  1047. s64bit : writeln('s64bit');
  1048. bool8bit : writeln('bool8bit');
  1049. bool16bit : writeln('bool16bit');
  1050. bool32bit : writeln('bool32bit');
  1051. uchar : writeln('uchar');
  1052. uwidechar : writeln('uwidechar');
  1053. else writeln('!! Warning: Invalid base type ',b);
  1054. end;
  1055. writeln(space,' Range : ',getint64,' to ',getint64);
  1056. end;
  1057. ibfloatdef :
  1058. begin
  1059. readcommondef('Float definition');
  1060. writeln(space,' Float type : ',getbyte);
  1061. end;
  1062. ibarraydef :
  1063. begin
  1064. readcommondef('Array definition');
  1065. write (space,' Element type : ');
  1066. readtype;
  1067. write (space,' Range Type : ');
  1068. readtype;
  1069. writeln(space,' Range : ',getlongint,' to ',getlongint);
  1070. writeln(space,' Is Constructor : ',(getbyte<>0));
  1071. writeln(space,' Is Dynamic : ',(getbyte<>0));
  1072. end;
  1073. ibprocdef :
  1074. begin
  1075. readcommondef('Procedure definition');
  1076. calloption:=read_abstract_proc_def;
  1077. write (space,' Used Registers : ');
  1078. case ttargetcpu(header.cpu) of
  1079. i386 :
  1080. getusedregisters_i386
  1081. else
  1082. begin
  1083. getnormalset(regs);
  1084. writeln('<not yet implemented>');
  1085. end;
  1086. end;
  1087. if (getbyte<>0) then
  1088. writeln(space,' Mangled name : ',getstring);
  1089. writeln(space,' Overload Number : ',getword);
  1090. writeln(space,' Number : ',getword);
  1091. write (space,' Class : ');
  1092. readdefref;
  1093. write (space,' Procsym : ');
  1094. readsymref;
  1095. write (space,' File Pos : ');
  1096. readposinfo;
  1097. if (calloption=pocall_inline) then
  1098. begin
  1099. write (space,' FuncretSym : ');
  1100. readdefref;
  1101. end;
  1102. space:=' '+space;
  1103. { parast }
  1104. readdefinitions(false);
  1105. readsymbols;
  1106. { localst }
  1107. if (calloption=pocall_inline) or
  1108. ((ppufile.header.flags and uf_local_browser) <> 0) then
  1109. begin
  1110. readdefinitions(false);
  1111. readsymbols;
  1112. end;
  1113. delete(space,1,4);
  1114. end;
  1115. ibprocvardef :
  1116. begin
  1117. readcommondef('Procedural type (ProcVar) definition');
  1118. read_abstract_proc_def;
  1119. end;
  1120. ibshortstringdef :
  1121. begin
  1122. readcommondef('ShortString definition');
  1123. writeln(space,' Length : ',getbyte);
  1124. end;
  1125. ibwidestringdef :
  1126. begin
  1127. readcommondef('WideString definition');
  1128. writeln(space,' Length : ',getlongint);
  1129. end;
  1130. ibansistringdef :
  1131. begin
  1132. readcommondef('AnsiString definition');
  1133. writeln(space,' Length : ',getlongint);
  1134. end;
  1135. iblongstringdef :
  1136. begin
  1137. readcommondef('Longstring definition');
  1138. writeln(space,' Length : ',getlongint);
  1139. end;
  1140. ibrecorddef :
  1141. begin
  1142. readcommondef('Record definition');
  1143. writeln(space,' Size : ',getlongint);
  1144. {read the record definitions and symbols}
  1145. space:=' '+space;
  1146. oldread_member:=read_member;
  1147. read_member:=true;
  1148. readdefinitions(false);
  1149. readsymbols;
  1150. read_member:=oldread_member;
  1151. Delete(space,1,4);
  1152. end;
  1153. ibobjectdef :
  1154. begin
  1155. readcommondef('Object/Class definition');
  1156. b:=getbyte;
  1157. write (space,' Type : ');
  1158. case tobjectdeftype(b) of
  1159. odt_class : writeln('class');
  1160. odt_object : writeln('object');
  1161. odt_interfacecom : writeln('interfacecom');
  1162. odt_interfacecorba : writeln('interfacecorba');
  1163. odt_cppclass : writeln('cppclass');
  1164. else writeln('!! Warning: Invalid object type ',b);
  1165. end;
  1166. writeln(space,' Size : ',getlongint);
  1167. writeln(space,' Vmt offset : ',getlongint);
  1168. writeln(space,' Name of Class : ',getstring);
  1169. write(space, ' Ancestor Class : ');
  1170. readdefref;
  1171. writeln(space,' Options : ',getlongint);
  1172. if tobjectdeftype(b) in [odt_interfacecom,odt_interfacecorba] then
  1173. begin
  1174. writeln(space,' GUID Valid : ',(getbyte<>0));
  1175. { IIDGUID }
  1176. for j:=1to 16 do
  1177. getbyte;
  1178. writeln(space,' IID String : ',getstring);
  1179. writeln(space,' Last VTable idx : ',getlongint);
  1180. end;
  1181. if tobjectdeftype(b) in [odt_class,odt_interfacecorba] then
  1182. begin
  1183. l:=getlongint;
  1184. writeln(space,' Impl Intf Count : ',l);
  1185. for j:=1 to l do
  1186. begin
  1187. write (space,' - Definition : ');
  1188. readdefref;
  1189. writeln(space,' IOffset : ',getlongint);
  1190. end;
  1191. end;
  1192. {read the record definitions and symbols}
  1193. space:=' '+space;
  1194. oldread_member:=read_member;
  1195. read_member:=true;
  1196. readdefinitions(false);
  1197. readsymbols;
  1198. read_member:=oldread_member;
  1199. Delete(space,1,4);
  1200. end;
  1201. ibfiledef :
  1202. begin
  1203. ReadCommonDef('File definition');
  1204. write (space,' Type : ');
  1205. case getbyte of
  1206. 0 : writeln('Text');
  1207. 1 : begin
  1208. writeln('Typed');
  1209. write (space,' File of Type : ');
  1210. Readtype;
  1211. end;
  1212. 2 : writeln('Untyped');
  1213. end;
  1214. end;
  1215. ibformaldef :
  1216. readcommondef('Generic Definition (void-typ)');
  1217. ibenumdef :
  1218. begin
  1219. readcommondef('Enumeration type definition');
  1220. write(space,'Base enumeration type : ');
  1221. readdefref;
  1222. writeln(space,' Smallest element : ',getlongint);
  1223. writeln(space,' Largest element : ',getlongint);
  1224. writeln(space,' Size : ',getlongint);
  1225. end;
  1226. ibclassrefdef :
  1227. begin
  1228. readcommondef('Class reference definition');
  1229. write (space,' Pointed Type : ');
  1230. readtype;
  1231. end;
  1232. ibsetdef :
  1233. begin
  1234. readcommondef('Set definition');
  1235. write (space,' Element type : ');
  1236. readtype;
  1237. b:=getbyte;
  1238. case tsettype(b) of
  1239. smallset : writeln(space,' Set with 32 Elements');
  1240. normset : writeln(space,' Set with 256 Elements');
  1241. varset : writeln(space,' Set with ',getlongint,' Elements');
  1242. else writeln('!! Warning: Invalid set type ',b);
  1243. end;
  1244. end;
  1245. ibvariantdef :
  1246. begin
  1247. readcommondef('Variant definition');
  1248. end;
  1249. iberror :
  1250. begin
  1251. Writeln('!! Error in PPU');
  1252. exit;
  1253. end;
  1254. ibenddefs :
  1255. break;
  1256. else
  1257. WriteLn('!! Skipping unsupported PPU Entry in definitions: ',b);
  1258. end;
  1259. if not EndOfEntry then
  1260. Writeln('!! Entry has more information stored');
  1261. until false;
  1262. if (totaldefs<>-1) and (defcnt<>totaldefs) then
  1263. Writeln('!! Only read ',defcnt,' of ',totaldefs,' definitions');
  1264. end;
  1265. end;
  1266. {****************************************************************************
  1267. Read General Part
  1268. ****************************************************************************}
  1269. procedure readinterface;
  1270. var
  1271. b : byte;
  1272. sourcenumber,
  1273. unitnumber : word;
  1274. ucrc,uintfcrc : longint;
  1275. begin
  1276. with ppufile do
  1277. begin
  1278. repeat
  1279. b:=readentry;
  1280. case b of
  1281. ibmodulename :
  1282. Writeln('Module Name: ',getstring);
  1283. ibsourcefiles :
  1284. begin
  1285. sourcenumber:=1;
  1286. while not EndOfEntry do
  1287. begin
  1288. Writeln('Source file ',sourcenumber,' : ',getstring);
  1289. inc(sourcenumber);
  1290. end;
  1291. end;
  1292. ibusedmacros :
  1293. begin
  1294. while not EndOfEntry do
  1295. begin
  1296. Write('Conditional ',getstring);
  1297. b:=getbyte;
  1298. if boolean(b)=true then
  1299. write(' defined at startup')
  1300. else
  1301. write(' not defined at startup');
  1302. b:=getbyte;
  1303. if boolean(b)=true then
  1304. writeln(' was used')
  1305. else
  1306. writeln;
  1307. end;
  1308. end;
  1309. ibloadunit :
  1310. begin
  1311. unitnumber:=1;
  1312. while not EndOfEntry do
  1313. begin
  1314. write('Uses unit: ',getstring,' (Number: ',unitnumber,')');
  1315. ucrc:=getlongint;
  1316. uintfcrc:=getlongint;
  1317. write(' (Crc: ',hexstr(ucrc,8),', IntfcCrc: ',hexstr(uintfcrc,8),')');
  1318. if getbyte<>0 then
  1319. writeln(' (interface)')
  1320. else
  1321. writeln(' (implementation)');
  1322. inc(unitnumber);
  1323. end;
  1324. end;
  1325. iblinkunitofiles :
  1326. ReadLinkContainer('Link unit object file: ');
  1327. iblinkunitstaticlibs :
  1328. ReadLinkContainer('Link unit static lib: ');
  1329. iblinkunitsharedlibs :
  1330. ReadLinkContainer('Link unit shared lib: ');
  1331. iblinkotherofiles :
  1332. ReadLinkContainer('Link other object file: ');
  1333. iblinkotherstaticlibs :
  1334. ReadLinkContainer('Link other static lib: ');
  1335. iblinkothersharedlibs :
  1336. ReadLinkContainer('Link other shared lib: ');
  1337. iberror :
  1338. begin
  1339. Writeln('Error in PPU');
  1340. exit;
  1341. end;
  1342. ibendinterface :
  1343. break;
  1344. else
  1345. WriteLn('!! Skipping unsupported PPU Entry in General Part: ',b);
  1346. end;
  1347. until false;
  1348. end;
  1349. end;
  1350. {****************************************************************************
  1351. Read Implementation Part
  1352. ****************************************************************************}
  1353. procedure readimplementation;
  1354. var
  1355. b : byte;
  1356. begin
  1357. with ppufile do
  1358. begin
  1359. repeat
  1360. b:=readentry;
  1361. case b of
  1362. iberror :
  1363. begin
  1364. Writeln('Error in PPU');
  1365. exit;
  1366. end;
  1367. ibendimplementation :
  1368. break;
  1369. else
  1370. WriteLn('!! Skipping unsupported PPU Entry in Implementation: ',b);
  1371. end;
  1372. until false;
  1373. end;
  1374. end;
  1375. {****************************************************************************
  1376. Read Browser Part
  1377. ****************************************************************************}
  1378. procedure readbrowser;
  1379. var
  1380. b : byte;
  1381. const indent : string = '';
  1382. begin
  1383. Writeln(indent,'Start of symtable browser');
  1384. indent:=indent+'**';
  1385. with ppufile do
  1386. begin
  1387. repeat
  1388. b:=readentry;
  1389. case b of
  1390. ibbeginsymtablebrowser :
  1391. begin
  1392. { here we must read object and record symtables !! }
  1393. indent:=indent+' ';
  1394. Writeln(indent,'Record/Object symtable');
  1395. readbrowser;
  1396. Indent:=Copy(Indent,1,Length(Indent)-2);
  1397. end;
  1398. ibsymref :
  1399. begin
  1400. readsymref;
  1401. readref;
  1402. end;
  1403. ibdefref :
  1404. begin
  1405. readdefref;
  1406. readref;
  1407. if ((ppufile.header.flags and uf_local_browser)<>0) and
  1408. (UnitIndex=0) then
  1409. begin
  1410. { parast and localst }
  1411. indent:=indent+' ';
  1412. b:=ppufile.readentry;
  1413. if b=ibbeginsymtablebrowser then
  1414. readbrowser;
  1415. b:=ppufile.readentry;
  1416. if b=ibbeginsymtablebrowser then
  1417. readbrowser;
  1418. Indent:=Copy(Indent,1,Length(Indent)-2);
  1419. end;
  1420. end;
  1421. iberror :
  1422. begin
  1423. Writeln('Error in PPU');
  1424. exit;
  1425. end;
  1426. ibendsymtablebrowser :
  1427. break;
  1428. else
  1429. begin
  1430. WriteLn('!! Skipping unsupported PPU Entry in Browser: ',b);
  1431. Halt;
  1432. end;
  1433. end;
  1434. until false;
  1435. end;
  1436. Indent:=Copy(Indent,1,Length(Indent)-2);
  1437. Writeln(Indent,'End of symtable browser');
  1438. end;
  1439. procedure dofile (filename : string);
  1440. var
  1441. b : byte;
  1442. begin
  1443. { reset }
  1444. space:='';
  1445. { fix filename }
  1446. if pos('.',filename)=0 then
  1447. filename:=filename+'.ppu';
  1448. ppufile:=tppufile.create(filename);
  1449. if not ppufile.openfile then
  1450. begin
  1451. writeln ('IO-Error when opening : ',filename,', Skipping');
  1452. exit;
  1453. end;
  1454. { PPU File is open, check for PPU Id }
  1455. if not ppufile.CheckPPUID then
  1456. begin
  1457. writeln(Filename,' : Not a valid PPU file, Skipping');
  1458. exit;
  1459. end;
  1460. { Check PPU Version }
  1461. Writeln('Analyzing ',filename,' (v',ppufile.GetPPUVersion,')');
  1462. if ppufile.GetPPUVersion<16 then
  1463. begin
  1464. writeln(Filename,' : Old PPU Formats (<v16) are not supported, Skipping');
  1465. exit;
  1466. end;
  1467. { Write PPU Header Information }
  1468. if (verbose and v_header)<>0 then
  1469. begin
  1470. Writeln;
  1471. Writeln('Header');
  1472. Writeln('-------');
  1473. with ppufile.header do
  1474. begin
  1475. Writeln('Compiler version : ',hi(ppufile.header.compiler and $ff),'.',lo(ppufile.header.compiler));
  1476. WriteLn('Target processor : ',Cpu2Str(cpu));
  1477. WriteLn('Target operating system : ',Target2Str(target));
  1478. Writeln('Unit flags : ',PPUFlags2Str(flags));
  1479. Writeln('FileSize (w/o header) : ',size);
  1480. Writeln('Checksum : ',hexstr(checksum,8));
  1481. Writeln('Interface Checksum : ',hexstr(interface_checksum,8));
  1482. end;
  1483. end;
  1484. {read the general stuff}
  1485. if (verbose and v_interface)<>0 then
  1486. begin
  1487. Writeln;
  1488. Writeln('Interface section');
  1489. Writeln('------------------');
  1490. readinterface;
  1491. end
  1492. else
  1493. ppufile.skipuntilentry(ibendinterface);
  1494. {read the definitions}
  1495. if (verbose and v_defs)<>0 then
  1496. begin
  1497. Writeln;
  1498. Writeln('Interface definitions');
  1499. Writeln('----------------------');
  1500. readdefinitions(false);
  1501. end
  1502. else
  1503. ppufile.skipuntilentry(ibenddefs);
  1504. {read the symbols}
  1505. if (verbose and v_syms)<>0 then
  1506. begin
  1507. Writeln;
  1508. Writeln('Interface Symbols');
  1509. Writeln('------------------');
  1510. readsymbols;
  1511. end
  1512. else
  1513. ppufile.skipuntilentry(ibendsyms);
  1514. {read the implementation stuff}
  1515. { Not used at the moment (PFV)
  1516. if (verbose and v_implementation)<>0 then
  1517. begin
  1518. Writeln;
  1519. Writeln('Implementation section');
  1520. Writeln('-----------------------');
  1521. readimplementation;
  1522. end
  1523. else}
  1524. ppufile.skipuntilentry(ibendimplementation);
  1525. {read the static browser units stuff}
  1526. if (ppufile.header.flags and uf_local_browser)<>0 then
  1527. begin
  1528. if (verbose and v_defs)<>0 then
  1529. begin
  1530. Writeln;
  1531. Writeln('Static definitions');
  1532. Writeln('----------------------');
  1533. readdefinitions(false);
  1534. end
  1535. else
  1536. ppufile.skipuntilentry(ibenddefs);
  1537. {read the symbols}
  1538. if (verbose and v_syms)<>0 then
  1539. begin
  1540. Writeln;
  1541. Writeln('Static Symbols');
  1542. Writeln('------------------');
  1543. readsymbols;
  1544. end;
  1545. end;
  1546. {read the browser units stuff}
  1547. if (ppufile.header.flags and uf_has_browser)<>0 then
  1548. begin
  1549. if (verbose and v_browser)<>0 then
  1550. begin
  1551. Writeln;
  1552. Writeln('Browser section');
  1553. Writeln('---------------');
  1554. UnitIndex:=0;
  1555. repeat
  1556. b:=ppufile.readentry;
  1557. if b = ibendbrowser then break;
  1558. if b=ibbeginsymtablebrowser then
  1559. begin
  1560. Writeln('Unit ',UnitIndex);
  1561. readbrowser;
  1562. Inc(UnitIndex);
  1563. end
  1564. else
  1565. Writeln('Wrong end browser entry ',b,' should be ',ibendbrowser);
  1566. until false;
  1567. end;
  1568. end;
  1569. {read the static browser units stuff}
  1570. if (ppufile.header.flags and uf_local_browser)<>0 then
  1571. begin
  1572. if (verbose and v_browser)<>0 then
  1573. begin
  1574. Writeln;
  1575. Writeln('Static browser section');
  1576. Writeln('---------------');
  1577. UnitIndex:=0;
  1578. b:=ppufile.readentry;
  1579. if b=ibbeginsymtablebrowser then
  1580. readbrowser
  1581. else
  1582. Writeln('Wrong end browser entry ',b,' should be ',ibendbrowser);
  1583. end;
  1584. end;
  1585. {shutdown ppufile}
  1586. ppufile.closefile;
  1587. ppufile.free;
  1588. Writeln;
  1589. end;
  1590. procedure help;
  1591. begin
  1592. writeln('usage: ppudump [options] <filename1> <filename2>...');
  1593. writeln;
  1594. writeln('[options] can be:');
  1595. writeln(' -V<verbose> Set verbosity to <verbose>');
  1596. writeln(' H - Show header info');
  1597. writeln(' I - Show interface');
  1598. writeln(' M - Show implementation');
  1599. writeln(' S - Show interface symbols');
  1600. writeln(' D - Show interface definitions');
  1601. writeln(' B - Show browser info');
  1602. writeln(' A - Show all');
  1603. writeln(' -? This helpscreen');
  1604. halt;
  1605. end;
  1606. var
  1607. startpara,
  1608. nrfile,i : longint;
  1609. para : string;
  1610. begin
  1611. writeln(Title+' '+Version);
  1612. writeln(Copyright);
  1613. writeln;
  1614. if paramcount<1 then
  1615. begin
  1616. writeln('usage: dumpppu [options] <filename1> <filename2>...');
  1617. halt(1);
  1618. end;
  1619. { turn verbose on by default }
  1620. verbose:=v_all;
  1621. { read options }
  1622. startpara:=1;
  1623. while copy(paramstr(startpara),1,1)='-' do
  1624. begin
  1625. para:=paramstr(startpara);
  1626. case upcase(para[2]) of
  1627. 'V' : begin
  1628. verbose:=0;
  1629. for i:=3to length(para) do
  1630. case upcase(para[i]) of
  1631. 'H' : verbose:=verbose or v_header;
  1632. 'I' : verbose:=verbose or v_interface;
  1633. 'M' : verbose:=verbose or v_implementation;
  1634. 'D' : verbose:=verbose or v_defs;
  1635. 'S' : verbose:=verbose or v_syms;
  1636. 'B' : verbose:=verbose or v_browser;
  1637. 'A' : verbose:=verbose or v_all;
  1638. end;
  1639. end;
  1640. '?' : help;
  1641. end;
  1642. inc(startpara);
  1643. end;
  1644. { process files }
  1645. for nrfile:=startpara to paramcount do
  1646. dofile (paramstr(nrfile));
  1647. if has_errors then
  1648. Halt(1);
  1649. end.
  1650. {
  1651. $Log$
  1652. Revision 1.25 2002-05-18 13:34:27 peter
  1653. * readded missing revisions
  1654. Revision 1.24 2002/05/16 19:46:54 carl
  1655. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1656. + try to fix temp allocation (still in ifdef)
  1657. + generic constructor calls
  1658. + start of tassembler / tmodulebase class cleanup
  1659. Revision 1.22 2002/05/12 16:53:18 peter
  1660. * moved entry and exitcode to ncgutil and cgobj
  1661. * foreach gets extra argument for passing local data to the
  1662. iterator function
  1663. * -CR checks also class typecasts at runtime by changing them
  1664. into as
  1665. * fixed compiler to cycle with the -CR option
  1666. * fixed stabs with elf writer, finally the global variables can
  1667. be watched
  1668. * removed a lot of routines from cga unit and replaced them by
  1669. calls to cgobj
  1670. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1671. u32bit then the other is typecasted also to u32bit without giving
  1672. a rangecheck warning/error.
  1673. * fixed pascal calling method with reversing also the high tree in
  1674. the parast, detected by tcalcst3 test
  1675. Revision 1.21 2002/04/23 13:12:58 peter
  1676. * updated for posinfo change
  1677. * updated for mangledname change
  1678. * include i386 registers, removed reference to cpubase unit that would
  1679. make ppudump dependent on the source processor
  1680. Revision 1.20 2002/04/15 19:15:09 carl
  1681. + write std_reg2str instead of gas registers
  1682. Revision 1.19 2002/04/14 17:02:19 carl
  1683. + att_reg2str -> gas_reg2str
  1684. Revision 1.18 2002/04/07 10:23:36 carl
  1685. + added vm / sparc targets
  1686. Revision 1.17 2002/04/04 19:06:14 peter
  1687. * removed unused units
  1688. * use tlocation.size in cg.a_*loc*() routines
  1689. Revision 1.16 2002/04/04 18:50:27 carl
  1690. + added wdosx support (patch from Pavel)
  1691. Revision 1.15 2002/03/31 20:26:42 jonas
  1692. + a_loadfpu_* and a_loadmm_* methods in tcg
  1693. * register allocation is now handled by a class and is mostly processor
  1694. independent (+rgobj.pas and i386/rgcpu.pas)
  1695. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  1696. * some small improvements and fixes to the optimizer
  1697. * some register allocation fixes
  1698. * some fpuvaroffset fixes in the unary minus node
  1699. * push/popusedregisters is now called rg.save/restoreusedregisters and
  1700. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  1701. also better optimizable)
  1702. * fixed and optimized register saving/restoring for new/dispose nodes
  1703. * LOC_FPU locations now also require their "register" field to be set to
  1704. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  1705. - list field removed of the tnode class because it's not used currently
  1706. and can cause hard-to-find bugs
  1707. Revision 1.14 2002/03/28 20:48:52 carl
  1708. - remove go32v1 support
  1709. Revision 1.13 2002/03/28 16:44:59 armin
  1710. + new flag if unit has local threadvars
  1711. Revision 1.12 2002/03/01 14:08:47 peter
  1712. * parasym added
  1713. Revision 1.11 2002/01/06 12:08:16 peter
  1714. * removed uauto from orddef, use new range_to_basetype generating
  1715. the correct ordinal type for a range
  1716. }