ppudump.pp 54 KB

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