ppudump.pp 55 KB

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