ppudump.pp 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330
  1. {
  2. Copyright (c) 1998-2002 by the FPC Development Team
  3. Dumps the contents of a FPC unit file (PPU File)
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************}
  16. program ppudump;
  17. {$mode objfpc}
  18. {$H+}
  19. uses
  20. SysUtils,
  21. ppu,
  22. globals,
  23. tokens;
  24. const
  25. Version = 'Version 2.2.0';
  26. Title = 'PPU-Analyser';
  27. Copyright = 'Copyright (c) 1998-2007 by the Free Pascal Development Team';
  28. { verbosity }
  29. v_none = $0;
  30. v_header = $1;
  31. v_defs = $2;
  32. v_syms = $4;
  33. v_interface = $8;
  34. v_implementation = $10;
  35. // v_browser = $20;
  36. v_all = $ff;
  37. type
  38. tprocinfoflag=(
  39. {# procedure uses asm }
  40. pi_uses_asm,
  41. {# procedure does a call }
  42. pi_do_call,
  43. {# procedure has a try statement = no register optimization }
  44. pi_uses_exceptions,
  45. {# procedure is declared as @var(assembler), don't optimize}
  46. pi_is_assembler,
  47. {# procedure contains data which needs to be finalized }
  48. pi_needs_implicit_finally
  49. );
  50. tprocinfoflags=set of tprocinfoflag;
  51. { copied from scanner.pas }
  52. tspecialgenerictoken = (ST_LOADSETTINGS,ST_LINE,ST_COLUMN,ST_FILEINDEX);
  53. { Copied from systems.pas }
  54. tsystemcpu=
  55. (
  56. cpu_no, { 0 }
  57. cpu_i386, { 1 }
  58. cpu_m68k, { 2 }
  59. cpu_alpha, { 3 }
  60. cpu_powerpc, { 4 }
  61. cpu_sparc, { 5 }
  62. cpu_vm, { 6 }
  63. cpu_iA64, { 7 }
  64. cpu_x86_64, { 8 }
  65. cpu_mips, { 9 }
  66. cpu_arm { 10 }
  67. );
  68. var
  69. ppufile : tppufile;
  70. space : string;
  71. verbose : longint;
  72. derefdata : pbyte;
  73. derefdatalen : longint;
  74. {****************************************************************************
  75. Helper Routines
  76. ****************************************************************************}
  77. const has_errors : boolean = false;
  78. Procedure Error(const S : string);
  79. Begin
  80. Writeln(S);
  81. has_errors:=true;
  82. End;
  83. function ToStr(w:longint):String;
  84. begin
  85. Str(w,ToStr);
  86. end;
  87. Function Target2Str(w:longint):string;
  88. type
  89. { taken from systems.pas }
  90. ttarget =
  91. (
  92. target_none, { 0 }
  93. target_i386_GO32V1, { 1 }
  94. target_i386_GO32V2, { 2 }
  95. target_i386_linux, { 3 }
  96. target_i386_OS2, { 4 }
  97. target_i386_Win32, { 5 }
  98. target_i386_freebsd, { 6 }
  99. target_m68k_Amiga, { 7 }
  100. target_m68k_Atari, { 8 }
  101. target_m68k_Mac, { 9 }
  102. target_m68k_linux, { 10 }
  103. target_m68k_PalmOS, { 11 }
  104. target_alpha_linux, { 12 }
  105. target_powerpc_linux, { 13 }
  106. target_powerpc_macos, { 14 }
  107. target_i386_sunos, { 15 }
  108. target_i386_beos, { 16 }
  109. target_i386_netbsd, { 17 }
  110. target_m68k_netbsd, { 18 }
  111. target_i386_Netware, { 19 }
  112. target_i386_qnx, { 20 }
  113. target_i386_wdosx, { 21 }
  114. target_sparc_sunos, { 22 }
  115. target_sparc_linux, { 23 }
  116. target_i386_openbsd, { 24 }
  117. target_m68k_openbsd, { 25 }
  118. system_x86_64_linux, { 26 }
  119. system_powerpc_macosx, { 27 }
  120. target_i386_emx, { 28 }
  121. target_powerpc_netbsd, { 29 }
  122. target_powerpc_openbsd, { 30 }
  123. target_arm_linux, { 31 }
  124. target_i386_watcom, { 32 }
  125. target_powerpc_MorphOS, { 33 }
  126. target_x86_64_freebsd, { 34 }
  127. target_i386_netwlibc, { 35 }
  128. system_powerpc_Amiga, { 36 }
  129. system_x86_64_win64, { 37 }
  130. system_arm_wince, { 38 }
  131. system_ia64_win64, { 39 }
  132. system_i386_wince, { 40 }
  133. system_x86_6432_linux, { 41 }
  134. system_arm_gba { 42 }
  135. );
  136. const
  137. Targets : array[ttarget] of string[17]=(
  138. { 0 } 'none',
  139. { 1 } 'GO32V1',
  140. { 2 } 'GO32V2',
  141. { 3 } 'Linux-i386',
  142. { 4 } 'OS/2',
  143. { 5 } 'Win32',
  144. { 6 } 'FreeBSD-i386',
  145. { 7 } 'Amiga',
  146. { 8 } 'Atari',
  147. { 9 } 'MacOS-m68k',
  148. { 10 } 'Linux-m68k',
  149. { 11 } 'PalmOS-m68k',
  150. { 12 } 'Linux-alpha',
  151. { 13 } 'Linux-ppc',
  152. { 14 } 'MacOS-ppc',
  153. { 15 } 'Solaris-i386',
  154. { 16 } 'BeOS-i386',
  155. { 17 } 'NetBSD-i386',
  156. { 18 } 'NetBSD-m68k',
  157. { 19 } 'Netware-i386-clib',
  158. { 20 } 'Qnx-i386',
  159. { 21 } 'WDOSX-i386',
  160. { 22 } 'Solaris-sparc',
  161. { 23 } 'Linux-sparc',
  162. { 24 } 'OpenBSD-i386',
  163. { 25 } 'OpenBSD-m68k',
  164. { 26 } 'Linux-x86-64',
  165. { 27 } 'MacOSX-ppc',
  166. { 28 } 'OS/2 via EMX',
  167. { 29 } 'NetBSD-powerpc',
  168. { 30 } 'OpenBSD-powerpc',
  169. { 31 } 'Linux-arm',
  170. { 32 } 'Watcom-i386',
  171. { 33 } 'MorphOS-powerpc',
  172. { 34 } 'FreeBSD-x86-64',
  173. { 35 } 'Netware-i386-libc',
  174. { 36 } 'Amiga-PowerPC',
  175. { 37 } 'Win64-x64',
  176. { 38 } 'WinCE-ARM',
  177. { 39 } 'Win64-iA64',
  178. { 40 } 'WinCE-i386',
  179. { 41 } 'Linux-x64',
  180. { 42 } 'GBA-ARM'
  181. );
  182. begin
  183. if w<=ord(high(ttarget)) then
  184. Target2Str:=Targets[ttarget(w)]
  185. else
  186. Target2Str:='<!! Unknown target value '+tostr(w)+'>';
  187. end;
  188. Function Cpu2Str(w:longint):string;
  189. const
  190. CpuTxt : array[tsystemcpu] of string[8]=
  191. ('none','i386','m68k','alpha','powerpc','sparc','vis','ia64','x86_64','mips','arm');
  192. begin
  193. if w<=ord(high(tsystemcpu)) then
  194. Cpu2Str:=CpuTxt[tsystemcpu(w)]
  195. else
  196. Cpu2Str:='<!! Unknown cpu value '+tostr(w)+'>';
  197. end;
  198. Function Varspez2Str(w:longint):string;
  199. const
  200. varspezstr : array[0..4] of string[6]=('Value','Const','Var','Out','Hidden');
  201. begin
  202. if w<=ord(high(varspezstr)) then
  203. Varspez2Str:=varspezstr[w]
  204. else
  205. Varspez2Str:='<!! Unknown varspez value '+tostr(w)+'>';
  206. end;
  207. Function VarRegable2Str(w:longint):string;
  208. const
  209. varregableStr : array[0..4] of string[6]=('None','IntReg','FPUReg','MMReg','Addr');
  210. begin
  211. if w<=ord(high(varregablestr)) then
  212. Varregable2Str:=varregablestr[w]
  213. else
  214. Varregable2Str:='<!! Unknown regable value '+tostr(w)+'>';
  215. end;
  216. function PPUFlags2Str(flags:longint):string;
  217. type
  218. tflagopt=record
  219. mask : longint;
  220. str : string[30];
  221. end;
  222. const
  223. flagopts=17;
  224. flagopt : array[1..flagopts] of tflagopt=(
  225. (mask: $1 ;str:'init'),
  226. (mask: $2 ;str:'final'),
  227. (mask: $4 ;str:'big_endian'),
  228. (mask: $8 ;str:'dbx'),
  229. // (mask: $10 ;str:'browser'),
  230. (mask: $20 ;str:'in_library'),
  231. (mask: $40 ;str:'smart_linked'),
  232. (mask: $80 ;str:'static_linked'),
  233. (mask: $100 ;str:'shared_linked'),
  234. // (mask: $200 ;str:'local_browser'),
  235. (mask: $400 ;str:'no_link'),
  236. (mask: $800 ;str:'has_resources'),
  237. (mask: $1000 ;str:'little_endian'),
  238. (mask: $2000 ;str:'release'),
  239. (mask: $4000 ;str:'local_threadvars'),
  240. (mask: $8000 ;str:'fpu_emulation_on'),
  241. (mask: $10000 ;str:'has_debug_info'),
  242. (mask: $20000 ;str:'local_symtable'),
  243. (mask: $40000 ;str:'uses_variants')
  244. );
  245. var
  246. i : longint;
  247. first : boolean;
  248. s : string;
  249. begin
  250. s:='';
  251. if flags<>0 then
  252. begin
  253. first:=true;
  254. for i:=1to flagopts do
  255. if (flags and flagopt[i].mask)<>0 then
  256. begin
  257. if first then
  258. first:=false
  259. else
  260. s:=s+', ';
  261. s:=s+flagopt[i].str;
  262. end;
  263. end
  264. else
  265. s:='none';
  266. PPUFlags2Str:=s;
  267. end;
  268. const
  269. HexTbl : array[0..15] of char='0123456789ABCDEF';
  270. function HexB(b:byte):shortstring;
  271. begin
  272. HexB[0]:=#2;
  273. HexB[1]:=HexTbl[b shr 4];
  274. HexB[2]:=HexTbl[b and $f];
  275. end;
  276. function hexstr(val : cardinal;cnt : byte) : shortstring;
  277. const
  278. HexTbl : array[0..15] of char='0123456789ABCDEF';
  279. var
  280. i : longint;
  281. begin
  282. hexstr[0]:=char(cnt);
  283. for i:=cnt downto 1 do
  284. begin
  285. hexstr[i]:=hextbl[val and $f];
  286. val:=val shr 4;
  287. end;
  288. end;
  289. Function L0(l:longint):string;
  290. {
  291. return the string of value l, if l<10 then insert a zero, so
  292. the string is always at least 2 chars '01','02',etc
  293. }
  294. var
  295. s : string;
  296. begin
  297. Str(l,s);
  298. if l<10 then
  299. s:='0'+s;
  300. L0:=s;
  301. end;
  302. function filetimestring( t : longint) : string;
  303. {
  304. convert dos datetime t to a string YY/MM/DD HH:MM:SS
  305. }
  306. var
  307. DT : TDateTime;
  308. hsec : word;
  309. Year,Month,Day: Word;
  310. hour,min,sec : word;
  311. begin
  312. if t=-1 then
  313. begin
  314. Result := 'Not Found';
  315. exit;
  316. end;
  317. DT := FileDateToDateTime(t);
  318. DecodeTime(DT,hour,min,sec,hsec);
  319. DecodeDate(DT,year,month,day);
  320. Result := L0(Year)+'/'+L0(Month)+'/'+L0(Day)+' '+L0(Hour)+':'+L0(min)+':'+L0(sec);
  321. end;
  322. {****************************************************************************
  323. Read Routines
  324. ****************************************************************************}
  325. Procedure ReadLinkContainer(const prefix:string);
  326. {
  327. Read a serie of strings and write to the screen starting every line
  328. with prefix
  329. }
  330. function maskstr(m:longint):string;
  331. const
  332. { link options }
  333. link_none = $0;
  334. link_always = $1;
  335. link_static = $2;
  336. link_smart = $4;
  337. link_shared = $8;
  338. var
  339. s : string;
  340. begin
  341. s:='';
  342. if (m and link_always)<>0 then
  343. s:=s+'always ';
  344. if (m and link_static)<>0 then
  345. s:=s+'static ';
  346. if (m and link_smart)<>0 then
  347. s:=s+'smart ';
  348. if (m and link_shared)<>0 then
  349. s:=s+'shared ';
  350. maskstr:=s;
  351. end;
  352. var
  353. s : string;
  354. m : longint;
  355. begin
  356. while not ppufile.endofentry do
  357. begin
  358. s:=ppufile.getstring;
  359. m:=ppufile.getlongint;
  360. WriteLn(prefix,s,' (',maskstr(m),')');
  361. end;
  362. end;
  363. Procedure ReadContainer(const prefix:string);
  364. {
  365. Read a serie of strings and write to the screen starting every line
  366. with prefix
  367. }
  368. begin
  369. while not ppufile.endofentry do
  370. WriteLn(prefix,ppufile.getstring);
  371. end;
  372. procedure ReadLoadUnit;
  373. var
  374. ucrc,uintfcrc : cardinal;
  375. begin
  376. while not ppufile.EndOfEntry do
  377. begin
  378. write('Uses unit: ',ppufile.getstring);
  379. ucrc:=cardinal(ppufile.getlongint);
  380. uintfcrc:=cardinal(ppufile.getlongint);
  381. writeln(' (Crc: ',hexstr(ucrc,8),', IntfcCrc: ',hexstr(uintfcrc,8),')');
  382. end;
  383. end;
  384. Procedure ReadDerefmap;
  385. var
  386. i,mapsize : longint;
  387. begin
  388. mapsize:=ppufile.getlongint;
  389. writeln('DerefMapsize: ',mapsize);
  390. for i:=0 to mapsize-1 do
  391. writeln('DerefMap[',i,'] = ',ppufile.getstring);
  392. end;
  393. Procedure ReadImportSymbols;
  394. var
  395. extlibname : string;
  396. j,
  397. extsymcnt : longint;
  398. extsymname : string;
  399. extsymordnr : longint;
  400. extsymisvar : boolean;
  401. begin
  402. while not ppufile.endofentry do
  403. begin
  404. extlibname:=ppufile.getstring;
  405. extsymcnt:=ppufile.getlongint;
  406. writeln('External Library: ',extlibname,' (',extsymcnt,' imports)');
  407. for j:=0 to extsymcnt-1 do
  408. begin
  409. extsymname:=ppufile.getstring;
  410. extsymordnr:=ppufile.getlongint;
  411. extsymisvar:=ppufile.getbyte<>0;
  412. writeln(' ',extsymname,' (OrdNr: ',extsymordnr,' IsVar: ',extsymisvar,')');
  413. end;
  414. end;
  415. end;
  416. Procedure ReadDerefdata;
  417. begin
  418. derefdatalen:=ppufile.entrysize;
  419. if derefdatalen=0 then
  420. begin
  421. writeln('!! Error: derefdatalen=0');
  422. exit;
  423. end;
  424. Writeln('Derefdata length: ',derefdatalen);
  425. derefdata:=allocmem(derefdatalen);
  426. ppufile.getdata(derefdata^,derefdatalen);
  427. end;
  428. Procedure ReadAsmSymbols;
  429. type
  430. { Copied from aasmbase.pas }
  431. TAsmsymbind=(AB_NONE,AB_EXTERNAL,AB_COMMON,AB_LOCAL,AB_GLOBAL);
  432. TAsmsymtype=(AT_NONE,AT_FUNCTION,AT_DATA,AT_SECTION,AT_LABEL);
  433. var
  434. s,
  435. bindstr,
  436. typestr : string;
  437. i : longint;
  438. begin
  439. writeln(space,'Number of AsmSymbols: ',ppufile.getlongint);
  440. i:=0;
  441. while (not ppufile.endofentry) and (not ppufile.error) do
  442. begin
  443. s:=ppufile.getstring;
  444. case tasmsymbind(ppufile.getbyte) of
  445. AB_EXTERNAL :
  446. bindstr:='External';
  447. AB_COMMON :
  448. bindstr:='Common';
  449. AB_LOCAL :
  450. bindstr:='Local';
  451. AB_GLOBAL :
  452. bindstr:='Global';
  453. else
  454. bindstr:='<Error !!>'
  455. end;
  456. case tasmsymtype(ppufile.getbyte) of
  457. AT_FUNCTION :
  458. typestr:='Function';
  459. AT_DATA :
  460. typestr:='Data';
  461. AT_SECTION :
  462. typestr:='Section';
  463. AT_LABEL :
  464. typestr:='Label';
  465. else
  466. typestr:='<Error !!>'
  467. end;
  468. Writeln(space,' ',i,' : ',s,' [',bindstr,',',typestr,']');
  469. inc(i);
  470. end;
  471. end;
  472. Procedure ReadPosInfo;
  473. var
  474. info : byte;
  475. fileindex,line,column : longint;
  476. begin
  477. with ppufile do
  478. begin
  479. {
  480. info byte layout in bits:
  481. 0-1 - amount of bytes for fileindex
  482. 2-3 - amount of bytes for line
  483. 4-5 - amount of bytes for column
  484. }
  485. info:=getbyte;
  486. case (info and $03) of
  487. 0 : fileindex:=getbyte;
  488. 1 : fileindex:=getword;
  489. 2 : fileindex:=(getbyte shl 16) or getword;
  490. 3 : fileindex:=getlongint;
  491. end;
  492. case ((info shr 2) and $03) of
  493. 0 : line:=getbyte;
  494. 1 : line:=getword;
  495. 2 : line:=(getbyte shl 16) or getword;
  496. 3 : line:=getlongint;
  497. end;
  498. case ((info shr 4) and $03) of
  499. 0 : column:=getbyte;
  500. 1 : column:=getword;
  501. 2 : column:=(getbyte shl 16) or getword;
  502. 3 : column:=getlongint;
  503. end;
  504. Writeln(fileindex,' (',line,',',column,')');
  505. end;
  506. end;
  507. procedure readderef;
  508. type
  509. tdereftype = (deref_nil,
  510. deref_unit,
  511. deref_symid,
  512. deref_defid
  513. );
  514. var
  515. b : tdereftype;
  516. first : boolean;
  517. idx : longint;
  518. i,n : byte;
  519. pdata : pbyte;
  520. begin
  521. if not assigned(derefdata) then
  522. exit;
  523. first:=true;
  524. idx:=ppufile.getlongint;
  525. if (idx>derefdatalen) then
  526. begin
  527. writeln('!! Error: Deref idx ',idx,' > ',derefdatalen);
  528. exit;
  529. end;
  530. write('(',idx,') ');
  531. pdata:=@derefdata[idx];
  532. i:=0;
  533. n:=pdata[i];
  534. inc(i);
  535. if n<1 then
  536. begin
  537. writeln('!! Error: Deref len < 1');
  538. exit;
  539. end;
  540. while (i<=n) do
  541. begin
  542. if not first then
  543. write(', ')
  544. else
  545. first:=false;
  546. b:=tdereftype(pdata[i]);
  547. inc(i);
  548. case b of
  549. deref_nil :
  550. write('Nil');
  551. deref_symid :
  552. begin
  553. idx:=pdata[i] shl 24 or pdata[i+1] shl 16 or pdata[i+2] shl 8 or pdata[i+3];
  554. inc(i,4);
  555. write('SymId ',idx);
  556. end;
  557. deref_defid :
  558. begin
  559. idx:=pdata[i] shl 24 or pdata[i+1] shl 16 or pdata[i+2] shl 8 or pdata[i+3];
  560. inc(i,4);
  561. write('DefId ',idx);
  562. end;
  563. deref_unit :
  564. begin
  565. idx:=pdata[i] shl 8 or pdata[i+1];
  566. inc(i,2);
  567. write('Unit ',idx);
  568. end;
  569. else
  570. begin
  571. writeln('!! unsupported dereftyp: ',ord(b));
  572. break;
  573. end;
  574. end;
  575. end;
  576. writeln;
  577. end;
  578. procedure readpropaccesslist(const s:string);
  579. type
  580. tsltype = (sl_none,
  581. sl_load,
  582. sl_call,
  583. sl_subscript,
  584. sl_vec,
  585. sl_typeconv,
  586. sl_absolutetype
  587. );
  588. const
  589. slstr : array[tsltype] of string[12] = ('',
  590. 'load',
  591. 'call',
  592. 'subscript',
  593. 'vec',
  594. 'typeconv',
  595. 'absolutetype'
  596. );
  597. var
  598. sl : tsltype;
  599. begin
  600. readderef;
  601. repeat
  602. sl:=tsltype(ppufile.getbyte);
  603. if sl=sl_none then
  604. break;
  605. write(s,'(',slstr[sl],') ');
  606. case sl of
  607. sl_call,
  608. sl_load,
  609. sl_subscript :
  610. readderef;
  611. sl_absolutetype,
  612. sl_typeconv :
  613. readderef;
  614. sl_vec :
  615. begin
  616. writeln(ppufile.getlongint);
  617. readderef;
  618. end;
  619. end;
  620. until false;
  621. end;
  622. procedure readsymoptions;
  623. type
  624. tsymoption=(sp_none,
  625. sp_public,
  626. sp_private,
  627. sp_published,
  628. sp_protected,
  629. sp_static,
  630. sp_hint_deprecated,
  631. sp_hint_platform,
  632. sp_hint_library,
  633. sp_hint_unimplemented,
  634. sp_has_overloaded,
  635. sp_internal { internal symbol, not reported as unused }
  636. );
  637. tsymoptions=set of tsymoption;
  638. tsymopt=record
  639. mask : tsymoption;
  640. str : string[30];
  641. end;
  642. const
  643. symopts=11;
  644. symopt : array[1..symopts] of tsymopt=(
  645. (mask:sp_public; str:'Public'),
  646. (mask:sp_private; str:'Private'),
  647. (mask:sp_published; str:'Published'),
  648. (mask:sp_protected; str:'Protected'),
  649. (mask:sp_static; str:'Static'),
  650. (mask:sp_hint_deprecated;str:'Hint Deprecated'),
  651. (mask:sp_hint_deprecated;str:'Hint Platform'),
  652. (mask:sp_hint_deprecated;str:'Hint Library'),
  653. (mask:sp_hint_deprecated;str:'Hint Unimplemented'),
  654. (mask:sp_has_overloaded; str:'Has overloaded'),
  655. (mask:sp_internal; str:'Internal')
  656. );
  657. var
  658. symoptions : tsymoptions;
  659. i : longint;
  660. first : boolean;
  661. begin
  662. ppufile.getsmallset(symoptions);
  663. if symoptions<>[] then
  664. begin
  665. first:=true;
  666. for i:=1to symopts do
  667. if (symopt[i].mask in symoptions) then
  668. begin
  669. if first then
  670. first:=false
  671. else
  672. write(', ');
  673. write(symopt[i].str);
  674. end;
  675. end;
  676. writeln;
  677. end;
  678. procedure readcommonsym(const s:string);
  679. begin
  680. writeln(space,'** Symbol Id ',ppufile.getlongint,' **');
  681. writeln(space,s,ppufile.getstring);
  682. write(space,' File Pos : ');
  683. readposinfo;
  684. write(space,' SymOptions : ');
  685. readsymoptions;
  686. end;
  687. procedure readcommondef(const s:string);
  688. type
  689. { flags for a definition }
  690. tdefoption=(df_none,
  691. { type is unique, i.e. declared with type = type <tdef>; }
  692. df_unique,
  693. { type is a generic }
  694. df_generic,
  695. { type is a specialization of a generic type }
  696. df_specialization
  697. );
  698. tdefoptions=set of tdefoption;
  699. tdefstate=(ds_none,
  700. ds_vmt_written,
  701. ds_rtti_table_used,
  702. ds_init_table_used,
  703. ds_rtti_table_written,
  704. ds_init_table_written,
  705. ds_dwarf_dbg_info_used,
  706. ds_dwarf_dbg_info_written
  707. );
  708. tdefstates=set of tdefstate;
  709. tdefopt=record
  710. mask : tdefoption;
  711. str : string[30];
  712. end;
  713. tdefstateinfo=record
  714. mask : tdefstate;
  715. str : string[30];
  716. end;
  717. const
  718. defopts=3;
  719. defopt : array[1..defopts] of tdefopt=(
  720. (mask:df_unique; str:'Unique Type'),
  721. (mask:df_generic; str:'Generic'),
  722. (mask:df_specialization; str:'Specialization')
  723. );
  724. defstateinfos=7;
  725. defstate : array[1..defstateinfos] of tdefstateinfo=(
  726. (mask:ds_init_table_used; str:'InitTable Used'),
  727. (mask:ds_rtti_table_used; str:'RTTITable Used'),
  728. (mask:ds_init_table_written; str:'InitTable Written'),
  729. (mask:ds_rtti_table_written; str:'RTTITable Written'),
  730. (mask:ds_dwarf_dbg_info_used; str:'Dwarf DbgInfo Used'),
  731. (mask:ds_dwarf_dbg_info_written;str:'Dwarf DbgInfo Written'),
  732. (mask:ds_vmt_written; str:'VMT Written')
  733. );
  734. var
  735. defoptions : tdefoptions;
  736. i : longint;
  737. first : boolean;
  738. tokenbufsize : longint;
  739. tokenbuf : pbyte;
  740. begin
  741. writeln(space,'** Definition Id ',ppufile.getlongint,' **');
  742. writeln(space,s);
  743. write (space,' Type symbol : ');
  744. readderef;
  745. write (space,' DefOptions : ');
  746. ppufile.getsmallset(defoptions);
  747. if defoptions<>[] then
  748. begin
  749. first:=true;
  750. for i:=1to defopts do
  751. if (defopt[i].mask in defoptions) then
  752. begin
  753. if first then
  754. first:=false
  755. else
  756. write(', ');
  757. write(defopt[i].str);
  758. end;
  759. end;
  760. writeln;
  761. if df_unique in defoptions then
  762. writeln (space,' Unique type symbol');
  763. if df_generic in defoptions then
  764. begin
  765. tokenbufsize:=ppufile.getlongint;
  766. writeln(space,' Tokenbuffer size : ',tokenbufsize);
  767. tokenbuf:=allocmem(tokenbufsize);
  768. ppufile.getdata(tokenbuf^,tokenbufsize);
  769. i:=0;
  770. write(space,' Tokens: ');
  771. while i<tokenbufsize do
  772. begin
  773. if ttoken(tokenbuf[i])<>_GENERICSPECIALTOKEN then
  774. write(arraytokeninfo[ttoken(tokenbuf[i])].str);
  775. case ttoken(tokenbuf[i]) of
  776. _CWCHAR,
  777. _CWSTRING :
  778. begin
  779. inc(i);
  780. {
  781. replaytokenbuf.read(wlen,sizeof(SizeInt));
  782. setlengthwidestring(patternw,wlen);
  783. replaytokenbuf.read(patternw^.data^,patternw^.len*sizeof(tcompilerwidechar));
  784. pattern:='';
  785. }
  786. end;
  787. _CCHAR,
  788. _CSTRING,
  789. _INTCONST,
  790. _REALNUMBER :
  791. begin
  792. inc(i);
  793. {
  794. replaytokenbuf.read(pattern[0],1);
  795. replaytokenbuf.read(pattern[1],length(pattern));
  796. orgpattern:='';
  797. }
  798. end;
  799. _ID :
  800. begin
  801. inc(i);
  802. inc(i);
  803. write(' ',pshortstring(@tokenbuf[i])^);
  804. inc(i,tokenbuf[i]+1);
  805. {
  806. replaytokenbuf.read(orgpattern[0],1);
  807. replaytokenbuf.read(orgpattern[1],length(orgpattern));
  808. pattern:=upper(orgpattern);
  809. }
  810. end;
  811. _GENERICSPECIALTOKEN:
  812. begin
  813. inc(i);
  814. case tspecialgenerictoken(tokenbuf[i]) of
  815. ST_LOADSETTINGS:
  816. begin
  817. inc(i);
  818. write('Settings');
  819. inc(i,sizeof(tsettings));
  820. end;
  821. ST_LINE:
  822. begin
  823. inc(i);
  824. write('Line: ',pdword(@tokenbuf[i])^);
  825. inc(i,4);
  826. end;
  827. ST_COLUMN:
  828. begin
  829. inc(i);
  830. write('Col: ',pword(@tokenbuf[i])^);
  831. inc(i,2);
  832. end;
  833. ST_FILEINDEX:
  834. begin
  835. inc(i);
  836. write('File: ',pword(@tokenbuf[i])^);
  837. inc(i,2);
  838. end;
  839. end;
  840. {
  841. replaytokenbuf.read(specialtoken,1);
  842. case specialtoken of
  843. ST_LOADSETTINGS:
  844. begin
  845. replaytokenbuf.read(current_settings,sizeof(current_settings));
  846. end
  847. else
  848. internalerror(2006103010);
  849. end;
  850. continue;
  851. }
  852. end;
  853. else
  854. inc(i);
  855. end;
  856. if i<tokenbufsize then
  857. write(',');
  858. end;
  859. writeln;
  860. freemem(tokenbuf);
  861. end;
  862. if df_specialization in defoptions then
  863. begin
  864. write (space,' Orig. GenericDef : ');
  865. readderef;
  866. end;
  867. end;
  868. { Read abstract procdef and return if inline procdef }
  869. type
  870. tproccalloption=(pocall_none,
  871. { procedure uses C styled calling }
  872. pocall_cdecl,
  873. { C++ calling conventions }
  874. pocall_cppdecl,
  875. { Far16 for OS/2 }
  876. pocall_far16,
  877. { Old style FPC default calling }
  878. pocall_oldfpccall,
  879. { Procedure has compiler magic}
  880. pocall_internproc,
  881. { procedure is a system call, applies e.g. to MorphOS and PalmOS }
  882. pocall_syscall,
  883. { pascal standard left to right }
  884. pocall_pascal,
  885. { procedure uses register (fastcall) calling }
  886. pocall_register,
  887. { safe call calling conventions }
  888. pocall_safecall,
  889. { procedure uses stdcall call }
  890. pocall_stdcall,
  891. { Special calling convention for cpus without a floating point
  892. unit. Floating point numbers are passed in integer registers
  893. instead of floating point registers. Depending on the other
  894. available calling conventions available for the cpu
  895. this replaces either pocall_fastcall or pocall_stdcall.
  896. }
  897. pocall_softfloat,
  898. { Metrowerks Pascal. Special case on Mac OS (X): passes all }
  899. { constant records by reference. }
  900. pocall_mwpascal
  901. );
  902. tproccalloptions=set of tproccalloption;
  903. tproctypeoption=(potype_none,
  904. potype_proginit, { Program initialization }
  905. potype_unitinit, { unit initialization }
  906. potype_unitfinalize, { unit finalization }
  907. potype_constructor, { Procedure is a constructor }
  908. potype_destructor, { Procedure is a destructor }
  909. potype_operator, { Procedure defines an operator }
  910. potype_procedure,
  911. potype_function
  912. );
  913. tproctypeoptions=set of tproctypeoption;
  914. tprocoption=(po_none,
  915. po_classmethod, { class method }
  916. po_virtualmethod, { Procedure is a virtual method }
  917. po_abstractmethod, { Procedure is an abstract method }
  918. po_staticmethod, { static method }
  919. po_overridingmethod, { method with override directive }
  920. po_methodpointer, { method pointer, only in procvardef, also used for 'with object do' }
  921. po_interrupt, { Procedure is an interrupt handler }
  922. po_iocheck, { IO checking should be done after a call to the procedure }
  923. po_assembler, { Procedure is written in assembler }
  924. po_msgstr, { method for string message handling }
  925. po_msgint, { method for int message handling }
  926. po_exports, { Procedure has export directive (needed for OS/2) }
  927. po_external, { Procedure is external (in other object or lib)}
  928. po_overload, { procedure is declared with overload directive }
  929. po_varargs, { printf like arguments }
  930. po_internconst, { procedure has constant evaluator intern }
  931. { flag that only the address of a method is returned and not a full methodpointer }
  932. po_addressonly,
  933. { procedure is exported }
  934. po_public,
  935. { calling convention is specified explicitly }
  936. po_hascallingconvention,
  937. { reintroduce flag }
  938. po_reintroduce,
  939. { location of parameters is given explicitly as it is necessary for some syscall
  940. conventions like that one of MorphOS }
  941. po_explicitparaloc,
  942. { no stackframe will be generated, used by lowlevel assembler like get_frame }
  943. po_nostackframe,
  944. po_has_mangledname,
  945. po_has_public_name,
  946. po_forward,
  947. po_global,
  948. po_has_inlininginfo,
  949. { The different kind of syscalls on MorphOS }
  950. po_syscall_legacy,
  951. po_syscall_sysv,
  952. po_syscall_basesysv,
  953. po_syscall_sysvbase,
  954. po_syscall_r12base,
  955. po_local,
  956. { Procedure can be inlined }
  957. po_inline,
  958. { Procedure is used for internal compiler calls }
  959. po_compilerproc,
  960. { importing }
  961. po_has_importdll,
  962. po_has_importname,
  963. po_kylixlocal
  964. );
  965. tprocoptions=set of tprocoption;
  966. procedure read_abstract_proc_def(var proccalloption:tproccalloption;var procoptions:tprocoptions);
  967. type
  968. tproccallopt=record
  969. mask : tproccalloption;
  970. str : string[30];
  971. end;
  972. tproctypeopt=record
  973. mask : tproctypeoption;
  974. str : string[30];
  975. end;
  976. tprocopt=record
  977. mask : tprocoption;
  978. str : string[30];
  979. end;
  980. const
  981. proccalloptionStr : array[tproccalloption] of string[14]=('',
  982. 'CDecl',
  983. 'CPPDecl',
  984. 'Far16',
  985. 'OldFPCCall',
  986. 'InternProc',
  987. 'SysCall',
  988. 'Pascal',
  989. 'Register',
  990. 'SafeCall',
  991. 'StdCall',
  992. 'SoftFloat',
  993. 'MWPascal'
  994. );
  995. proctypeopts=8;
  996. proctypeopt : array[1..proctypeopts] of tproctypeopt=(
  997. (mask:potype_proginit; str:'ProgInit'),
  998. (mask:potype_unitinit; str:'UnitInit'),
  999. (mask:potype_unitfinalize;str:'UnitFinalize'),
  1000. (mask:potype_constructor; str:'Constructor'),
  1001. (mask:potype_destructor; str:'Destructor'),
  1002. (mask:potype_operator; str:'Operator'),
  1003. (mask:potype_function; str:'Function'),
  1004. (mask:potype_procedure; str:'Procedure')
  1005. );
  1006. procopts=38;
  1007. procopt : array[1..procopts] of tprocopt=(
  1008. (mask:po_classmethod; str:'ClassMethod'),
  1009. (mask:po_virtualmethod; str:'VirtualMethod'),
  1010. (mask:po_abstractmethod; str:'AbstractMethod'),
  1011. (mask:po_staticmethod; str:'StaticMethod'),
  1012. (mask:po_overridingmethod;str:'OverridingMethod'),
  1013. (mask:po_methodpointer; str:'MethodPointer'),
  1014. (mask:po_interrupt; str:'Interrupt'),
  1015. (mask:po_iocheck; str:'IOCheck'),
  1016. (mask:po_assembler; str:'Assembler'),
  1017. (mask:po_msgstr; str:'MsgStr'),
  1018. (mask:po_msgint; str:'MsgInt'),
  1019. (mask:po_exports; str:'Exports'),
  1020. (mask:po_external; str:'External'),
  1021. (mask:po_overload; str:'Overload'),
  1022. (mask:po_varargs; str:'VarArgs'),
  1023. (mask:po_internconst; str:'InternConst'),
  1024. (mask:po_addressonly; str:'AddressOnly'),
  1025. (mask:po_public; str:'Public'),
  1026. (mask:po_hascallingconvention;str:'HasCallingConvention'),
  1027. (mask:po_reintroduce; str:'ReIntroduce'),
  1028. (mask:po_explicitparaloc; str:'ExplicitParaloc'),
  1029. (mask:po_nostackframe; str:'NoStackFrame'),
  1030. (mask:po_has_mangledname; str:'HasMangledName'),
  1031. (mask:po_has_public_name; str:'HasPublicName'),
  1032. (mask:po_forward; str:'Forward'),
  1033. (mask:po_global; str:'Global'),
  1034. (mask:po_has_inlininginfo;str:'HasInliningInfo'),
  1035. (mask:po_syscall_legacy; str:'SyscallLegacy'),
  1036. (mask:po_syscall_sysv; str:'SyscallSysV'),
  1037. (mask:po_syscall_basesysv;str:'SyscallBaseSysV'),
  1038. (mask:po_syscall_sysvbase;str:'SyscallSysVBase'),
  1039. (mask:po_syscall_r12base; str:'SyscallR12Base'),
  1040. (mask:po_local; str:'Local'),
  1041. (mask:po_inline; str:'Inline'),
  1042. (mask:po_compilerproc; str:'CompilerProc'),
  1043. (mask:po_has_importdll; str:'HasImportDLL'),
  1044. (mask:po_has_importname; str:'HasImportName'),
  1045. (mask:po_kylixlocal; str:'KylixLocal')
  1046. );
  1047. var
  1048. proctypeoption : tproctypeoption;
  1049. i : longint;
  1050. first : boolean;
  1051. tempbuf : array[0..255] of byte;
  1052. begin
  1053. write(space,' Return type : ');
  1054. readderef;
  1055. writeln(space,' Fpu used : ',ppufile.getbyte);
  1056. proctypeoption:=tproctypeoption(ppufile.getbyte);
  1057. write(space,' TypeOption : ');
  1058. first:=true;
  1059. for i:=1 to proctypeopts do
  1060. if (proctypeopt[i].mask=proctypeoption) then
  1061. begin
  1062. if first then
  1063. first:=false
  1064. else
  1065. write(', ');
  1066. write(proctypeopt[i].str);
  1067. end;
  1068. writeln;
  1069. proccalloption:=tproccalloption(ppufile.getbyte);
  1070. writeln(space,' CallOption : ',proccalloptionStr[proccalloption]);
  1071. ppufile.getnormalset(procoptions);
  1072. if procoptions<>[] then
  1073. begin
  1074. write(space,' Options : ');
  1075. first:=true;
  1076. for i:=1to procopts do
  1077. if (procopt[i].mask in procoptions) then
  1078. begin
  1079. if first then
  1080. first:=false
  1081. else
  1082. write(', ');
  1083. write(procopt[i].str);
  1084. end;
  1085. writeln;
  1086. end;
  1087. if (po_explicitparaloc in procoptions) then
  1088. begin
  1089. i:=ppufile.getbyte;
  1090. ppufile.getdata(tempbuf,i);
  1091. end;
  1092. end;
  1093. type
  1094. { options for variables }
  1095. tvaroption=(vo_none,
  1096. vo_is_external,
  1097. vo_is_dll_var,
  1098. vo_is_thread_var,
  1099. vo_has_local_copy,
  1100. vo_is_const, { variable is declared as const (parameter) and can't be written to }
  1101. vo_is_public,
  1102. vo_is_high_para,
  1103. vo_is_funcret,
  1104. vo_is_self,
  1105. vo_is_vmt,
  1106. vo_is_result, { special result variable }
  1107. vo_is_parentfp,
  1108. vo_is_loop_counter, { used to detect assignments to loop counter }
  1109. vo_is_hidden_para,
  1110. vo_has_explicit_paraloc,
  1111. vo_is_syscall_lib,
  1112. vo_has_mangledname,
  1113. vo_is_typed_const
  1114. );
  1115. tvaroptions=set of tvaroption;
  1116. { register variable }
  1117. tvarregable=(vr_none,
  1118. vr_intreg,
  1119. vr_fpureg,
  1120. vr_mmreg,
  1121. vr_addr
  1122. );
  1123. procedure readabstractvarsym(const s:string;var varoptions:tvaroptions);
  1124. type
  1125. tvaropt=record
  1126. mask : tvaroption;
  1127. str : string[30];
  1128. end;
  1129. const
  1130. varopts=18;
  1131. varopt : array[1..varopts] of tvaropt=(
  1132. (mask:vo_is_external; str:'External'),
  1133. (mask:vo_is_dll_var; str:'DLLVar'),
  1134. (mask:vo_is_thread_var; str:'ThreadVar'),
  1135. (mask:vo_has_local_copy; str:'HasLocalCopy'),
  1136. (mask:vo_is_const; str:'Constant'),
  1137. (mask:vo_is_public; str:'Public'),
  1138. (mask:vo_is_high_para; str:'HighValue'),
  1139. (mask:vo_is_funcret; str:'Funcret'),
  1140. (mask:vo_is_self; str:'Self'),
  1141. (mask:vo_is_vmt; str:'VMT'),
  1142. (mask:vo_is_result; str:'Result'),
  1143. (mask:vo_is_parentfp; str:'ParentFP'),
  1144. (mask:vo_is_loop_counter; str:'LoopCounter'),
  1145. (mask:vo_is_hidden_para; str:'Hidden'),
  1146. (mask:vo_has_explicit_paraloc;str:'ExplicitParaloc'),
  1147. (mask:vo_is_syscall_lib; str:'SysCallLib'),
  1148. (mask:vo_has_mangledname; str:'HasMangledName'),
  1149. (mask:vo_is_typed_const; str:'TypedConst')
  1150. );
  1151. var
  1152. i : longint;
  1153. first : boolean;
  1154. begin
  1155. readcommonsym(s);
  1156. writeln(space,' Spez : ',Varspez2Str(ppufile.getbyte));
  1157. writeln(space,' Regable : ',Varregable2Str(ppufile.getbyte));
  1158. write (space,' Var Type : ');
  1159. readderef;
  1160. ppufile.getsmallset(varoptions);
  1161. if varoptions<>[] then
  1162. begin
  1163. write(space,' Options : ');
  1164. first:=true;
  1165. for i:=1to varopts do
  1166. if (varopt[i].mask in varoptions) then
  1167. begin
  1168. if first then
  1169. first:=false
  1170. else
  1171. write(', ');
  1172. write(varopt[i].str);
  1173. end;
  1174. writeln;
  1175. end;
  1176. end;
  1177. procedure readobjectdefoptions;
  1178. type
  1179. tobjectoption=(oo_none,
  1180. oo_is_forward, { the class is only a forward declared yet }
  1181. oo_has_virtual, { the object/class has virtual methods }
  1182. oo_has_private,
  1183. oo_has_protected,
  1184. oo_has_strictprivate,
  1185. oo_has_strictprotected,
  1186. oo_has_constructor, { the object/class has a constructor }
  1187. oo_has_destructor, { the object/class has a destructor }
  1188. oo_has_vmt, { the object/class has a vmt }
  1189. oo_has_msgstr,
  1190. oo_has_msgint,
  1191. oo_can_have_published,{ the class has rtti, i.e. you can publish properties }
  1192. oo_has_default_property,
  1193. oo_vmt_written
  1194. );
  1195. tobjectoptions=set of tobjectoption;
  1196. tsymopt=record
  1197. mask : tobjectoption;
  1198. str : string[30];
  1199. end;
  1200. const
  1201. symopts=14;
  1202. symopt : array[1..symopts] of tsymopt=(
  1203. (mask:oo_has_virtual; str:'IsForward'),
  1204. (mask:oo_has_virtual; str:'HasVirtual'),
  1205. (mask:oo_has_private; str:'HasPrivate'),
  1206. (mask:oo_has_protected; str:'HasProtected'),
  1207. (mask:oo_has_strictprivate; str:'HasStrictPrivate'),
  1208. (mask:oo_has_strictprotected;str:'HasStrictProtected'),
  1209. (mask:oo_has_constructor; str:'HasConstructor'),
  1210. (mask:oo_has_destructor; str:'HasDestructor'),
  1211. (mask:oo_has_vmt; str:'HasVMT'),
  1212. (mask:oo_has_msgstr; str:'HasMsgStr'),
  1213. (mask:oo_has_msgint; str:'HasMsgInt'),
  1214. (mask:oo_can_have_published; str:'CanHavePublished'),
  1215. (mask:oo_has_default_property;str:'HasDefaultProperty'),
  1216. (mask:oo_vmt_written; str:'VMTWritten')
  1217. );
  1218. var
  1219. symoptions : tobjectoptions;
  1220. i : longint;
  1221. first : boolean;
  1222. begin
  1223. ppufile.getsmallset(symoptions);
  1224. if symoptions<>[] then
  1225. begin
  1226. first:=true;
  1227. for i:=1to symopts do
  1228. if (symopt[i].mask in symoptions) then
  1229. begin
  1230. if first then
  1231. first:=false
  1232. else
  1233. write(', ');
  1234. write(symopt[i].str);
  1235. end;
  1236. end;
  1237. writeln;
  1238. end;
  1239. procedure readarraydefoptions;
  1240. type
  1241. tarraydefoption=(ado_none,
  1242. ado_IsConvertedPointer,
  1243. ado_IsDynamicArray,
  1244. ado_IsVariant,
  1245. ado_IsConstructor,
  1246. ado_IsArrayOfConst,
  1247. ado_IsConstString
  1248. );
  1249. tarraydefoptions=set of tarraydefoption;
  1250. tsymopt=record
  1251. mask : tarraydefoption;
  1252. str : string[30];
  1253. end;
  1254. const
  1255. symopts=6;
  1256. symopt : array[1..symopts] of tsymopt=(
  1257. (mask:ado_IsConvertedPointer;str:'ConvertedPointer'),
  1258. (mask:ado_IsDynamicArray; str:'IsDynamicArray'),
  1259. (mask:ado_IsVariant; str:'IsVariant'),
  1260. (mask:ado_IsConstructor; str:'IsConstructor'),
  1261. (mask:ado_IsArrayOfConst; str:'ArrayOfConst'),
  1262. (mask:ado_IsConstString; str:'ConstString')
  1263. );
  1264. var
  1265. symoptions : tarraydefoptions;
  1266. i : longint;
  1267. first : boolean;
  1268. begin
  1269. ppufile.getsmallset(symoptions);
  1270. if symoptions<>[] then
  1271. begin
  1272. first:=true;
  1273. for i:=1to symopts do
  1274. if (symopt[i].mask in symoptions) then
  1275. begin
  1276. if first then
  1277. first:=false
  1278. else
  1279. write(', ');
  1280. write(symopt[i].str);
  1281. end;
  1282. end;
  1283. writeln;
  1284. end;
  1285. procedure readnodetree;
  1286. var
  1287. l : longint;
  1288. p : pointer;
  1289. begin
  1290. with ppufile do
  1291. begin
  1292. if space<>'' then
  1293. Writeln(space,'------ nodetree ------');
  1294. if readentry=ibnodetree then
  1295. begin
  1296. l:=entrysize;
  1297. Writeln(space,'Tree size : ',l);
  1298. { Read data to prevent error that entry is not completly read }
  1299. getmem(p,l);
  1300. getdata(p^,l);
  1301. freemem(p);
  1302. end
  1303. else
  1304. begin
  1305. Writeln('!! ibnodetree not found');
  1306. end;
  1307. end;
  1308. end;
  1309. {****************************************************************************
  1310. Read Symbols Part
  1311. ****************************************************************************}
  1312. procedure readsymbols(const s:string);
  1313. type
  1314. pguid = ^tguid;
  1315. tguid = packed record
  1316. D1: LongWord;
  1317. D2: Word;
  1318. D3: Word;
  1319. D4: array[0..7] of Byte;
  1320. end;
  1321. absolutetyp = (tovar,toasm,toaddr);
  1322. tconsttyp = (constnone,
  1323. constord,conststring,constreal,
  1324. constset,constpointer,constnil,
  1325. constresourcestring,constwstring,constguid
  1326. );
  1327. var
  1328. b : byte;
  1329. pc : pchar;
  1330. i,j,len : longint;
  1331. guid : tguid;
  1332. tempbuf : array[0..127] of char;
  1333. varoptions : tvaroptions;
  1334. begin
  1335. with ppufile do
  1336. begin
  1337. if space<>'' then
  1338. Writeln(space,'------ ',s,' ------');
  1339. if readentry=ibstartsyms then
  1340. begin
  1341. Writeln(space,'Symtable datasize : ',getlongint);
  1342. Writeln(space,'Symtable alignment: ',getlongint);
  1343. end
  1344. else
  1345. Writeln('!! ibstartsym not found');
  1346. repeat
  1347. b:=readentry;
  1348. case b of
  1349. ibunitsym :
  1350. readcommonsym('Unit symbol ');
  1351. iblabelsym :
  1352. readcommonsym('Label symbol ');
  1353. ibtypesym :
  1354. begin
  1355. readcommonsym('Type symbol ');
  1356. write(space,' Result Type : ');
  1357. readderef;
  1358. end;
  1359. ibprocsym :
  1360. begin
  1361. readcommonsym('Procedure symbol ');
  1362. len:=ppufile.getword;
  1363. for i:=1 to len do
  1364. begin
  1365. write(space,' Definition : ');
  1366. readderef;
  1367. end;
  1368. end;
  1369. ibconstsym :
  1370. begin
  1371. readcommonsym('Constant symbol ');
  1372. b:=getbyte;
  1373. case tconsttyp(b) of
  1374. constord :
  1375. begin
  1376. write (space,' OrdinalType : ');
  1377. readderef;
  1378. writeln(space,' Value : ',getint64);
  1379. end;
  1380. constpointer :
  1381. begin
  1382. write (space,' PointerType : ');
  1383. readderef;
  1384. writeln(space,' Value : ',getlongint)
  1385. end;
  1386. conststring,
  1387. constresourcestring :
  1388. begin
  1389. len:=getlongint;
  1390. getmem(pc,len+1);
  1391. getdata(pc^,len);
  1392. (pc+len)^:= #0;
  1393. writeln(space,' Length : ',len);
  1394. writeln(space,' Value : "',pc,'"');
  1395. freemem(pc,len+1);
  1396. end;
  1397. constreal :
  1398. writeln(space,' Value : ',getreal);
  1399. constset :
  1400. begin
  1401. write (space,' Set Type : ');
  1402. readderef;
  1403. for i:=1to 4 do
  1404. begin
  1405. write (space,' Value : ');
  1406. for j:=1to 8 do
  1407. begin
  1408. if j>1 then
  1409. write(',');
  1410. write(hexb(getbyte));
  1411. end;
  1412. writeln;
  1413. end;
  1414. end;
  1415. constwstring:
  1416. begin
  1417. end;
  1418. constguid:
  1419. begin
  1420. getdata(guid,sizeof(guid));
  1421. write (space,' IID String: {',hexstr(guid.d1,8),'-',hexstr(guid.d2,4),'-',hexstr(guid.d3,4),'-');
  1422. for i:=0 to 7 do
  1423. begin
  1424. write(hexstr(guid.d4[i],2));
  1425. if i=1 then write('-');
  1426. end;
  1427. writeln('}');
  1428. end
  1429. else
  1430. Writeln ('!! Invalid unit format : Invalid const type encountered: ',b);
  1431. end;
  1432. end;
  1433. ibabsolutevarsym :
  1434. begin
  1435. readabstractvarsym('Absolute variable symbol ',varoptions);
  1436. Write (space,' Relocated to ');
  1437. b:=getbyte;
  1438. case absolutetyp(b) of
  1439. tovar :
  1440. readpropaccesslist(space+' Sym : ');
  1441. toasm :
  1442. Writeln('Assembler name : ',getstring);
  1443. toaddr :
  1444. begin
  1445. Write('Address : ',getlongint);
  1446. if tsystemcpu(ppufile.header.cpu)=cpu_i386 then
  1447. WriteLn(' (Far: ',getbyte<>0,')');
  1448. end;
  1449. else
  1450. Writeln ('!! Invalid unit format : Invalid absolute type encountered: ',b);
  1451. end;
  1452. end;
  1453. ibfieldvarsym :
  1454. begin
  1455. readabstractvarsym('Field Variable symbol ',varoptions);
  1456. writeln(space,' Address : ',getaint);
  1457. end;
  1458. ibstaticvarsym :
  1459. begin
  1460. readabstractvarsym('Global Variable symbol ',varoptions);
  1461. write (space,' DefaultConst : ');
  1462. readderef;
  1463. if (vo_has_mangledname in varoptions) then
  1464. writeln(space,' Mangledname : ',getstring);
  1465. end;
  1466. iblocalvarsym :
  1467. begin
  1468. readabstractvarsym('Local Variable symbol ',varoptions);
  1469. write (space,' DefaultConst : ');
  1470. readderef;
  1471. end;
  1472. ibparavarsym :
  1473. begin
  1474. readabstractvarsym('Parameter Variable symbol ',varoptions);
  1475. write (space,' DefaultConst : ');
  1476. readderef;
  1477. writeln(space,' ParaNr : ',getword);
  1478. writeln(space,' VarState : ',getbyte);
  1479. if (vo_has_explicit_paraloc in varoptions) then
  1480. begin
  1481. i:=getbyte;
  1482. getdata(tempbuf,i);
  1483. end;
  1484. end;
  1485. ibenumsym :
  1486. begin
  1487. readcommonsym('Enumeration symbol ');
  1488. write (space,' Definition : ');
  1489. readderef;
  1490. writeln(space,' Value : ',getlongint);
  1491. end;
  1492. ibsyssym :
  1493. begin
  1494. readcommonsym('Internal system symbol ');
  1495. writeln(space,' Internal Nr : ',getlongint);
  1496. end;
  1497. ibmacrosym :
  1498. begin
  1499. readcommonsym('Macro symbol ');
  1500. writeln(space,' Name: ',getstring);
  1501. writeln(space,' Defined: ',getbyte);
  1502. writeln(space,' Compiler var: ',getbyte);
  1503. len:=getlongint;
  1504. writeln(space,' Value length: ',len);
  1505. if len > 0 then
  1506. begin
  1507. getmem(pc,len+1);
  1508. getdata(pc^,len);
  1509. (pc+len)^:= #0;
  1510. writeln(space,' Value: "',pc,'"');
  1511. freemem(pc,len+1);
  1512. end;
  1513. end;
  1514. ibpropertysym :
  1515. begin
  1516. readcommonsym('Property ');
  1517. i:=getlongint;
  1518. writeln(space,' PropOptions : ',i);
  1519. write (space,' OverrideProp : ');
  1520. readderef;
  1521. write (space,' Prop Type : ');
  1522. readderef;
  1523. writeln(space,' Index : ',getlongint);
  1524. writeln(space,' Default : ',getlongint);
  1525. write (space,' Index Type : ');
  1526. readderef;
  1527. write (space,' Readaccess : ');
  1528. readpropaccesslist(space+' Sym: ');
  1529. write (space,' Writeaccess : ');
  1530. readpropaccesslist(space+' Sym: ');
  1531. write (space,' Storedaccess : ');
  1532. readpropaccesslist(space+' Sym: ');
  1533. end;
  1534. iberror :
  1535. begin
  1536. Writeln('!! Error in PPU');
  1537. exit;
  1538. end;
  1539. ibendsyms :
  1540. break;
  1541. else
  1542. WriteLn('!! Skipping unsupported PPU Entry in Symbols: ',b);
  1543. end;
  1544. if not EndOfEntry then
  1545. Writeln('!! Entry has more information stored');
  1546. until false;
  1547. end;
  1548. end;
  1549. {****************************************************************************
  1550. Read defintions Part
  1551. ****************************************************************************}
  1552. procedure readdefinitions(const s:string);
  1553. type
  1554. tsettype = (normset,smallset,varset);
  1555. tordtype = (
  1556. uvoid,
  1557. u8bit,u16bit,u32bit,u64bit,
  1558. s8bit,s16bit,s32bit,s64bit,
  1559. bool8bit,bool16bit,bool32bit,bool64bit,
  1560. uchar,uwidechar,scurrency
  1561. );
  1562. tobjecttyp = (odt_none,
  1563. odt_class,
  1564. odt_object,
  1565. odt_interfacecom,
  1566. odt_interfacecorba,
  1567. odt_cppclass,
  1568. odt_dispinterface
  1569. );
  1570. tvarianttype = (
  1571. vt_normalvariant,vt_olevariant
  1572. );
  1573. var
  1574. b : byte;
  1575. l,j : longint;
  1576. calloption : tproccalloption;
  1577. procoptions : tprocoptions;
  1578. procinfooptions : tprocinfoflag;
  1579. begin
  1580. with ppufile do
  1581. begin
  1582. if space<>'' then
  1583. Writeln(space,'------ ',s,' ------');
  1584. if readentry<>ibstartdefs then
  1585. Writeln('!! ibstartdefs not found');
  1586. repeat
  1587. b:=readentry;
  1588. case b of
  1589. ibpointerdef :
  1590. begin
  1591. readcommondef('Pointer definition');
  1592. write (space,' Pointed Type : ');
  1593. readderef;
  1594. writeln(space,' Is Far : ',(getbyte<>0));
  1595. end;
  1596. iborddef :
  1597. begin
  1598. readcommondef('Ordinal definition');
  1599. write (space,' Base type : ');
  1600. b:=getbyte;
  1601. case tordtype(b) of
  1602. uvoid : writeln('uvoid');
  1603. u8bit : writeln('u8bit');
  1604. u16bit : writeln('u16bit');
  1605. u32bit : writeln('s32bit');
  1606. u64bit : writeln('u64bit');
  1607. s8bit : writeln('s8bit');
  1608. s16bit : writeln('s16bit');
  1609. s32bit : writeln('s32bit');
  1610. s64bit : writeln('s64bit');
  1611. bool8bit : writeln('bool8bit');
  1612. bool16bit : writeln('bool16bit');
  1613. bool32bit : writeln('bool32bit');
  1614. bool64bit : writeln('bool64bit');
  1615. uchar : writeln('uchar');
  1616. uwidechar : writeln('uwidechar');
  1617. scurrency : writeln('ucurrency');
  1618. else writeln('!! Warning: Invalid base type ',b);
  1619. end;
  1620. writeln(space,' Range : ',getint64,' to ',getint64);
  1621. end;
  1622. ibfloatdef :
  1623. begin
  1624. readcommondef('Float definition');
  1625. writeln(space,' Float type : ',getbyte);
  1626. end;
  1627. ibarraydef :
  1628. begin
  1629. readcommondef('Array definition');
  1630. write (space,' Element type : ');
  1631. readderef;
  1632. write (space,' Range Type : ');
  1633. readderef;
  1634. writeln(space,' Range : ',getaint,' to ',getaint);
  1635. write (space,' Options : ');
  1636. readarraydefoptions;
  1637. end;
  1638. ibprocdef :
  1639. begin
  1640. readcommondef('Procedure definition');
  1641. read_abstract_proc_def(calloption,procoptions);
  1642. if (po_has_mangledname in procoptions) then
  1643. writeln(space,' Mangled name : ',getstring);
  1644. writeln(space,' Number : ',getword);
  1645. writeln(space,' Level : ',getbyte);
  1646. write (space,' Class : ');
  1647. readderef;
  1648. write (space,' Procsym : ');
  1649. readderef;
  1650. write (space,' File Pos : ');
  1651. readposinfo;
  1652. write (space,' SymOptions : ');
  1653. readsymoptions;
  1654. if tsystemcpu(ppufile.header.cpu)=cpu_powerpc then
  1655. begin
  1656. { library symbol for AmigaOS/MorphOS }
  1657. write (space,' Library symbol : ');
  1658. readderef;
  1659. end;
  1660. if (po_has_importdll in procoptions) then
  1661. writeln(space,' Import DLL : ',getstring);
  1662. if (po_has_importname in procoptions) then
  1663. writeln(space,' Import Name : ',getstring);
  1664. writeln(space,' Import Nr : ',getword);
  1665. if (po_msgint in procoptions) then
  1666. writeln(space,' MsgInt : ',getlongint);
  1667. if (po_msgstr in procoptions) then
  1668. writeln(space,' MsgStr : ',getstring);
  1669. if (po_has_inlininginfo in procoptions) then
  1670. begin
  1671. write (space,' FuncretSym : ');
  1672. readderef;
  1673. ppufile.getsmallset(procinfooptions);
  1674. writeln(space,' ProcInfoOptions : ',dword(procinfooptions));
  1675. end;
  1676. if not EndOfEntry then
  1677. Writeln('!! Entry has more information stored');
  1678. space:=' '+space;
  1679. { parast }
  1680. readdefinitions('parast');
  1681. readsymbols('parast');
  1682. { localst }
  1683. if (po_has_inlininginfo in procoptions) then
  1684. begin
  1685. readdefinitions('localst');
  1686. readsymbols('localst');
  1687. end;
  1688. if (po_has_inlininginfo in procoptions) then
  1689. readnodetree;
  1690. delete(space,1,4);
  1691. end;
  1692. ibprocvardef :
  1693. begin
  1694. readcommondef('Procedural type (ProcVar) definition');
  1695. read_abstract_proc_def(calloption,procoptions);
  1696. if not EndOfEntry then
  1697. Writeln('!! Entry has more information stored');
  1698. space:=' '+space;
  1699. { parast }
  1700. readdefinitions('parast');
  1701. readsymbols('parast');
  1702. delete(space,1,4);
  1703. end;
  1704. ibshortstringdef :
  1705. begin
  1706. readcommondef('ShortString definition');
  1707. writeln(space,' Length : ',getbyte);
  1708. end;
  1709. ibwidestringdef :
  1710. begin
  1711. readcommondef('WideString definition');
  1712. writeln(space,' Length : ',getlongint);
  1713. end;
  1714. ibansistringdef :
  1715. begin
  1716. readcommondef('AnsiString definition');
  1717. writeln(space,' Length : ',getlongint);
  1718. end;
  1719. iblongstringdef :
  1720. begin
  1721. readcommondef('Longstring definition');
  1722. writeln(space,' Length : ',getlongint);
  1723. end;
  1724. ibrecorddef :
  1725. begin
  1726. readcommondef('Record definition');
  1727. writeln(space,' FieldAlign : ',getbyte);
  1728. writeln(space,' RecordAlign : ',getbyte);
  1729. writeln(space,' PadAlign : ',getbyte);
  1730. writeln(space,'UseFieldAlignment : ',getbyte);
  1731. writeln(space,' DataSize : ',getaint);
  1732. if not EndOfEntry then
  1733. Writeln('!! Entry has more information stored');
  1734. {read the record definitions and symbols}
  1735. space:=' '+space;
  1736. readdefinitions('fields');
  1737. readsymbols('fields');
  1738. Delete(space,1,4);
  1739. end;
  1740. ibobjectdef :
  1741. begin
  1742. readcommondef('Object/Class definition');
  1743. b:=getbyte;
  1744. write (space,' Type : ');
  1745. case tobjecttyp(b) of
  1746. odt_class : writeln('class');
  1747. odt_object : writeln('object');
  1748. odt_interfacecom : writeln('interfacecom');
  1749. odt_interfacecorba : writeln('interfacecorba');
  1750. odt_cppclass : writeln('cppclass');
  1751. else writeln('!! Warning: Invalid object type ',b);
  1752. end;
  1753. writeln(space,' Name of Class : ',getstring);
  1754. writeln(space,' DataSize : ',getaint);
  1755. writeln(space,' FieldAlign : ',getbyte);
  1756. writeln(space,' RecordAlign : ',getbyte);
  1757. writeln(space,' Vmt offset : ',getlongint);
  1758. write (space, ' Ancestor Class : ');
  1759. readderef;
  1760. write (space,' Options : ');
  1761. readobjectdefoptions;
  1762. if tobjecttyp(b) in [odt_interfacecom,odt_interfacecorba,odt_dispinterface] then
  1763. begin
  1764. { IIDGUID }
  1765. for j:=1to 16 do
  1766. getbyte;
  1767. writeln(space,' IID String : ',getstring);
  1768. writeln(space,' Last VTable idx : ',getlongint);
  1769. end;
  1770. if tobjecttyp(b) in [odt_class,odt_interfacecorba] then
  1771. begin
  1772. l:=getlongint;
  1773. writeln(space,' Impl Intf Count : ',l);
  1774. for j:=1 to l do
  1775. begin
  1776. write (space,' - Definition : ');
  1777. readderef;
  1778. writeln(space,' IOffset : ',getlongint);
  1779. end;
  1780. end;
  1781. if not EndOfEntry then
  1782. Writeln('!! Entry has more information stored');
  1783. {read the record definitions and symbols}
  1784. space:=' '+space;
  1785. readdefinitions('fields');
  1786. readsymbols('fields');
  1787. Delete(space,1,4);
  1788. end;
  1789. ibfiledef :
  1790. begin
  1791. ReadCommonDef('File definition');
  1792. write (space,' Type : ');
  1793. case getbyte of
  1794. 0 : writeln('Text');
  1795. 1 : begin
  1796. writeln('Typed');
  1797. write (space,' File of Type : ');
  1798. readderef;
  1799. end;
  1800. 2 : writeln('Untyped');
  1801. end;
  1802. end;
  1803. ibformaldef :
  1804. readcommondef('Generic definition (void-typ)');
  1805. ibundefineddef :
  1806. readcommondef('Undefined definition (generic parameter)');
  1807. ibenumdef :
  1808. begin
  1809. readcommondef('Enumeration type definition');
  1810. write(space,'Base enumeration type : ');
  1811. readderef;
  1812. writeln(space,' Smallest element : ',getaint);
  1813. writeln(space,' Largest element : ',getaint);
  1814. writeln(space,' Size : ',getaint);
  1815. end;
  1816. ibclassrefdef :
  1817. begin
  1818. readcommondef('Class reference definition');
  1819. write (space,' Pointed Type : ');
  1820. readderef;
  1821. end;
  1822. ibsetdef :
  1823. begin
  1824. readcommondef('Set definition');
  1825. write (space,' Element type : ');
  1826. readderef;
  1827. b:=getbyte;
  1828. // skip savesize
  1829. getaint;
  1830. case tsettype(b) of
  1831. smallset : write(space,' SmallSet');
  1832. normset : write(space,' NormalSet');
  1833. varset : write(space,' VarSet');
  1834. else writeln('!! Warning: Invalid set type ',b);
  1835. end;
  1836. // set base
  1837. l:=getaint;
  1838. // set max
  1839. j:=getaint;
  1840. writeln(' with ',j-l,' elements');
  1841. end;
  1842. ibvariantdef :
  1843. begin
  1844. readcommondef('Variant definition');
  1845. write (space,' Varianttype : ');
  1846. b:=getbyte;
  1847. case tvarianttype(b) of
  1848. vt_normalvariant :
  1849. writeln('Normal');
  1850. vt_olevariant :
  1851. writeln('OLE');
  1852. else
  1853. writeln('!! Warning: Invalid varianttype ',b);
  1854. end;
  1855. end;
  1856. iberror :
  1857. begin
  1858. Writeln('!! Error in PPU');
  1859. exit;
  1860. end;
  1861. ibenddefs :
  1862. break;
  1863. else
  1864. WriteLn('!! Skipping unsupported PPU Entry in definitions: ',b);
  1865. end;
  1866. if not EndOfEntry then
  1867. Writeln('!! Entry has more information stored');
  1868. until false;
  1869. end;
  1870. end;
  1871. {****************************************************************************
  1872. Read General Part
  1873. ****************************************************************************}
  1874. procedure readinterface;
  1875. var
  1876. b : byte;
  1877. sourcenumber : longint;
  1878. begin
  1879. with ppufile do
  1880. begin
  1881. repeat
  1882. b:=readentry;
  1883. case b of
  1884. ibmodulename :
  1885. Writeln('Module Name: ',getstring);
  1886. ibsourcefiles :
  1887. begin
  1888. sourcenumber:=1;
  1889. while not EndOfEntry do
  1890. begin
  1891. Writeln('Source file ',sourcenumber,' : ',getstring,' ',filetimestring(getlongint));
  1892. inc(sourcenumber);
  1893. end;
  1894. end;
  1895. {$IFDEF MACRO_DIFF_HINT}
  1896. ibusedmacros :
  1897. begin
  1898. while not EndOfEntry do
  1899. begin
  1900. Write('Conditional ',getstring);
  1901. b:=getbyte;
  1902. if boolean(b)=true then
  1903. write(' defined at startup')
  1904. else
  1905. write(' not defined at startup');
  1906. b:=getbyte;
  1907. if boolean(b)=true then
  1908. writeln(' was used')
  1909. else
  1910. writeln;
  1911. end;
  1912. end;
  1913. {$ENDIF}
  1914. ibloadunit :
  1915. ReadLoadUnit;
  1916. iblinkunitofiles :
  1917. ReadLinkContainer('Link unit object file: ');
  1918. iblinkunitstaticlibs :
  1919. ReadLinkContainer('Link unit static lib: ');
  1920. iblinkunitsharedlibs :
  1921. ReadLinkContainer('Link unit shared lib: ');
  1922. iblinkotherofiles :
  1923. ReadLinkContainer('Link other object file: ');
  1924. iblinkotherstaticlibs :
  1925. ReadLinkContainer('Link other static lib: ');
  1926. iblinkothersharedlibs :
  1927. ReadLinkContainer('Link other shared lib: ');
  1928. ibImportSymbols :
  1929. ReadImportSymbols;
  1930. ibderefdata :
  1931. ReadDerefData;
  1932. ibderefmap :
  1933. ReadDerefMap;
  1934. iberror :
  1935. begin
  1936. Writeln('Error in PPU');
  1937. exit;
  1938. end;
  1939. ibendinterface :
  1940. break;
  1941. else
  1942. WriteLn('!! Skipping unsupported PPU Entry in General Part: ',b);
  1943. end;
  1944. until false;
  1945. end;
  1946. end;
  1947. {****************************************************************************
  1948. Read Implementation Part
  1949. ****************************************************************************}
  1950. procedure readimplementation;
  1951. var
  1952. b : byte;
  1953. begin
  1954. with ppufile do
  1955. begin
  1956. repeat
  1957. b:=readentry;
  1958. case b of
  1959. ibasmsymbols :
  1960. ReadAsmSymbols;
  1961. ibloadunit :
  1962. ReadLoadUnit;
  1963. iberror :
  1964. begin
  1965. Writeln('Error in PPU');
  1966. exit;
  1967. end;
  1968. ibendimplementation :
  1969. break;
  1970. else
  1971. WriteLn('!! Skipping unsupported PPU Entry in Implementation: ',b);
  1972. end;
  1973. until false;
  1974. end;
  1975. end;
  1976. procedure dofile (filename : string);
  1977. begin
  1978. { reset }
  1979. space:='';
  1980. { fix filename }
  1981. if pos('.',filename)=0 then
  1982. filename:=filename+'.ppu';
  1983. ppufile:=tppufile.create(filename);
  1984. if not ppufile.openfile then
  1985. begin
  1986. writeln ('IO-Error when opening : ',filename,', Skipping');
  1987. exit;
  1988. end;
  1989. { PPU File is open, check for PPU Id }
  1990. if not ppufile.CheckPPUID then
  1991. begin
  1992. writeln(Filename,' : Not a valid PPU file, Skipping');
  1993. exit;
  1994. end;
  1995. { Check PPU Version }
  1996. Writeln('Analyzing ',filename,' (v',ppufile.GetPPUVersion,')');
  1997. if ppufile.GetPPUVersion<16 then
  1998. begin
  1999. writeln(Filename,' : Old PPU Formats (<v16) are not supported, Skipping');
  2000. exit;
  2001. end;
  2002. { Write PPU Header Information }
  2003. if (verbose and v_header)<>0 then
  2004. begin
  2005. Writeln;
  2006. Writeln('Header');
  2007. Writeln('-------');
  2008. with ppufile.header do
  2009. begin
  2010. Writeln('Compiler version : ',ppufile.header.compiler shr 14,'.',
  2011. (ppufile.header.compiler shr 7) and $7f,'.',
  2012. ppufile.header.compiler and $7f);
  2013. WriteLn('Target processor : ',Cpu2Str(cpu));
  2014. WriteLn('Target operating system : ',Target2Str(target));
  2015. Writeln('Unit flags : ',PPUFlags2Str(flags));
  2016. Writeln('FileSize (w/o header) : ',size);
  2017. Writeln('Checksum : ',hexstr(checksum,8));
  2018. Writeln('Interface Checksum : ',hexstr(interface_checksum,8));
  2019. Writeln('Definitions stored : ',tostr(deflistsize));
  2020. Writeln('Symbols stored : ',tostr(symlistsize));
  2021. end;
  2022. end;
  2023. {read the general stuff}
  2024. if (verbose and v_interface)<>0 then
  2025. begin
  2026. Writeln;
  2027. Writeln('Interface section');
  2028. Writeln('------------------');
  2029. readinterface;
  2030. end
  2031. else
  2032. ppufile.skipuntilentry(ibendinterface);
  2033. {read the definitions}
  2034. if (verbose and v_defs)<>0 then
  2035. begin
  2036. Writeln;
  2037. Writeln('Interface definitions');
  2038. Writeln('----------------------');
  2039. readdefinitions('interface');
  2040. end
  2041. else
  2042. ppufile.skipuntilentry(ibenddefs);
  2043. {read the symbols}
  2044. if (verbose and v_syms)<>0 then
  2045. begin
  2046. Writeln;
  2047. Writeln('Interface Symbols');
  2048. Writeln('------------------');
  2049. readsymbols('interface');
  2050. end
  2051. else
  2052. ppufile.skipuntilentry(ibendsyms);
  2053. {read the macro symbols}
  2054. if (verbose and v_syms)<>0 then
  2055. begin
  2056. Writeln;
  2057. Writeln('Interface Macro Symbols');
  2058. Writeln('-----------------------');
  2059. end;
  2060. if ppufile.readentry<>ibexportedmacros then
  2061. begin
  2062. Writeln('!! Error in PPU');
  2063. exit;
  2064. end;
  2065. if boolean(ppufile.getbyte) then
  2066. begin
  2067. {skip the definition section for macros (since they are never used) }
  2068. ppufile.skipuntilentry(ibenddefs);
  2069. {read the macro symbols}
  2070. if (verbose and v_syms)<>0 then
  2071. readsymbols('interface macro')
  2072. else
  2073. ppufile.skipuntilentry(ibendsyms);
  2074. end
  2075. else
  2076. Writeln('(no exported macros)');
  2077. {read the implementation stuff}
  2078. if (verbose and v_implementation)<>0 then
  2079. begin
  2080. Writeln;
  2081. Writeln('Implementation section');
  2082. Writeln('-----------------------');
  2083. readimplementation;
  2084. end
  2085. else
  2086. ppufile.skipuntilentry(ibendimplementation);
  2087. {read the static symtable}
  2088. if (ppufile.header.flags and uf_local_symtable)<>0 then
  2089. begin
  2090. if (verbose and v_defs)<>0 then
  2091. begin
  2092. Writeln;
  2093. Writeln('Static definitions');
  2094. Writeln('----------------------');
  2095. readdefinitions('implementation');
  2096. end
  2097. else
  2098. ppufile.skipuntilentry(ibenddefs);
  2099. {read the symbols}
  2100. if (verbose and v_syms)<>0 then
  2101. begin
  2102. Writeln;
  2103. Writeln('Static Symbols');
  2104. Writeln('------------------');
  2105. readsymbols('implementation');
  2106. end
  2107. else
  2108. ppufile.skipuntilentry(ibendsyms);
  2109. end;
  2110. {shutdown ppufile}
  2111. ppufile.closefile;
  2112. ppufile.free;
  2113. Writeln;
  2114. end;
  2115. procedure help;
  2116. begin
  2117. writeln('usage: ppudump [options] <filename1> <filename2>...');
  2118. writeln;
  2119. writeln('[options] can be:');
  2120. writeln(' -V<verbose> Set verbosity to <verbose>');
  2121. writeln(' H - Show header info');
  2122. writeln(' I - Show interface');
  2123. writeln(' M - Show implementation');
  2124. writeln(' S - Show interface symbols');
  2125. writeln(' D - Show interface definitions');
  2126. // writeln(' B - Show browser info');
  2127. writeln(' A - Show all');
  2128. writeln(' -h, -? This helpscreen');
  2129. halt;
  2130. end;
  2131. var
  2132. startpara,
  2133. nrfile,i : longint;
  2134. para : string;
  2135. begin
  2136. writeln(Title+' '+Version);
  2137. writeln(Copyright);
  2138. writeln;
  2139. if paramcount<1 then
  2140. begin
  2141. writeln('usage: dumpppu [options] <filename1> <filename2>...');
  2142. halt(1);
  2143. end;
  2144. { turn verbose on by default }
  2145. verbose:=v_all;
  2146. { read options }
  2147. startpara:=1;
  2148. while copy(paramstr(startpara),1,1)='-' do
  2149. begin
  2150. para:=paramstr(startpara);
  2151. case upcase(para[2]) of
  2152. 'V' : begin
  2153. verbose:=0;
  2154. for i:=3 to length(para) do
  2155. case upcase(para[i]) of
  2156. 'H' : verbose:=verbose or v_header;
  2157. 'I' : verbose:=verbose or v_interface;
  2158. 'M' : verbose:=verbose or v_implementation;
  2159. 'D' : verbose:=verbose or v_defs;
  2160. 'S' : verbose:=verbose or v_syms;
  2161. 'A' : verbose:=verbose or v_all;
  2162. end;
  2163. end;
  2164. 'H' : help;
  2165. '?' : help;
  2166. end;
  2167. inc(startpara);
  2168. end;
  2169. { process files }
  2170. for nrfile:=startpara to paramcount do
  2171. dofile (paramstr(nrfile));
  2172. if has_errors then
  2173. Halt(1);
  2174. end.