ppudump.pp 56 KB

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