ppudump.pp 115 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869
  1. {
  2. Copyright (c) 1998-2013 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. {$i fpcdefs.inc}
  18. {$H+}
  19. {$define IN_PPUDUMP}
  20. uses
  21. { do NOT add symconst or globtype to make merging easier }
  22. { do include symconst and globtype now before splitting 2.5 PM 2011-06-15 }
  23. SysUtils,
  24. constexp,
  25. symconst,
  26. ppu,
  27. systems,
  28. globals,
  29. globtype,
  30. widestr,
  31. tokens,
  32. version,
  33. ppuout,
  34. ppujson,
  35. ppuxml;
  36. const
  37. Title = 'PPU-Analyser';
  38. Copyright = 'Copyright (c) 1998-2013 by the Free Pascal Development Team';
  39. { verbosity }
  40. v_none = $0;
  41. v_header = $1;
  42. v_defs = $2;
  43. v_syms = $4;
  44. v_interface = $8;
  45. v_implementation = $10;
  46. // v_browser = $20;
  47. v_all = $ff;
  48. { not needed anymore $i systems.inc }
  49. { List of all supported cpus }
  50. const
  51. CpuTxt : array[tsystemcpu] of string[9]=
  52. (
  53. { 0 } 'none',
  54. { 1 } 'i386',
  55. { 2 } 'm68k',
  56. { 3 } 'alpha',
  57. { 4 } 'powerpc',
  58. { 5 } 'sparc',
  59. { 6 } 'vis',
  60. { 7 } 'ia64',
  61. { 8 } 'x86_64',
  62. { 9 } 'mipseb',
  63. { 10 } 'arm',
  64. { 11 } 'powerpc64',
  65. { 12 } 'avr',
  66. { 13 } 'mipsel',
  67. { 14 } 'jvm',
  68. { 15 } 'i8086',
  69. { 16 } 'aarch64'
  70. );
  71. { List of all supported system-cpu couples }
  72. const
  73. Targets : array[tsystem] of string[18]=(
  74. { 0 } 'none',
  75. { 1 } 'GO32V1 (obsolete)',
  76. { 2 } 'GO32V2',
  77. { 3 } 'Linux-i386',
  78. { 4 } 'OS/2',
  79. { 5 } 'Win32',
  80. { 6 } 'FreeBSD-i386',
  81. { 7 } 'Amiga',
  82. { 8 } 'Atari',
  83. { 9 } 'MacOS-m68k',
  84. { 10 } 'Linux-m68k',
  85. { 11 } 'PalmOS-m68k',
  86. { 12 } 'Linux-alpha',
  87. { 13 } 'Linux-ppc',
  88. { 14 } 'MacOS-ppc',
  89. { 15 } 'Solaris-i386',
  90. { 16 } 'BeOS-i386',
  91. { 17 } 'NetBSD-i386',
  92. { 18 } 'NetBSD-m68k',
  93. { 19 } 'Netware-i386-clib',
  94. { 20 } 'Qnx-i386',
  95. { 21 } 'WDOSX-i386',
  96. { 22 } 'Solaris-sparc',
  97. { 23 } 'Linux-sparc',
  98. { 24 } 'OpenBSD-i386',
  99. { 25 } 'OpenBSD-m68k',
  100. { 26 } 'Linux-x86-64',
  101. { 27 } 'MacOSX-ppc',
  102. { 28 } 'OS/2 via EMX',
  103. { 29 } 'NetBSD-powerpc',
  104. { 30 } 'OpenBSD-powerpc',
  105. { 31 } 'Linux-arm',
  106. { 32 } 'Watcom-i386',
  107. { 33 } 'MorphOS-powerpc',
  108. { 34 } 'FreeBSD-x86-64',
  109. { 35 } 'Netware-i386-libc',
  110. { 36 } 'Amiga-PowerPC',
  111. { 37 } 'Win64-x64',
  112. { 38 } 'WinCE-ARM',
  113. { 39 } 'Win64-iA64',
  114. { 40 } 'WinCE-i386',
  115. { 41 } 'Linux-x64',
  116. { 42 } 'GBA-arm',
  117. { 43 } 'Linux-powerpc64',
  118. { 44 } 'Darwin-i386',
  119. { 45 } 'PalmOS-arm',
  120. { 46 } 'MacOSX-powerpc64',
  121. { 47 } 'NDS-arm',
  122. { 48 } 'Embedded-i386',
  123. { 49 } 'Embedded-m68k',
  124. { 50 } 'Embedded-alpha',
  125. { 51 } 'Embedded-powerpc',
  126. { 52 } 'Embedded-sparc',
  127. { 53 } 'Embedded-vm',
  128. { 54 } 'Embedded-iA64',
  129. { 55 } 'Embedded-x64',
  130. { 56 } 'Embedded-mips',
  131. { 57 } 'Embedded-arm',
  132. { 58 } 'Embedded-powerpc64',
  133. { 59 } 'Symbian-i386',
  134. { 60 } 'Symbian-arm',
  135. { 61 } 'MacOSX-x64',
  136. { 62 } 'Embedded-avr',
  137. { 63 } 'Haiku-i386',
  138. { 64 } 'Darwin-ARM',
  139. { 65 } 'Solaris-x86-64',
  140. { 66 } 'Linux-MIPS',
  141. { 67 } 'Linux-MIPSel',
  142. { 68 } 'NativeNT-i386',
  143. { 69 } 'iPhoneSim-i386',
  144. { 70 } 'Wii-powerpc',
  145. { 71 } 'OpenBSD-x86-64',
  146. { 72 } 'NetBSD-x86-64',
  147. { 73 } 'AIX-powerpc',
  148. { 74 } 'AIX-powerpc64',
  149. { 75 } 'Java-JVM',
  150. { 76 } 'Android-JVM',
  151. { 77 } 'Android-arm',
  152. { 78 } 'Android-i386',
  153. { 79 } 'MSDOS-i8086',
  154. { 80 } 'Android-MIPSel',
  155. { 81 } 'Embedded-mipseb',
  156. { 82 } 'Embedded-mipsel',
  157. { 83 } 'AROS-i386',
  158. { 84 } 'AROS-x86-64',
  159. { 85 } 'DragonFly-x86-64',
  160. { 85 } 'Darwin-AArch64'
  161. );
  162. const
  163. { in widestr, we have the following definition
  164. type
  165. tcompilerwidechar = word;
  166. thus widecharsize seems to always be 2 bytes }
  167. widecharsize : longint = 2;
  168. cpu : tsystemcpu = cpu_no;
  169. { This type is defined in scanner.pas unit }
  170. type
  171. tspecialgenerictoken = (
  172. ST_LOADSETTINGS,
  173. ST_LINE,
  174. ST_COLUMN,
  175. ST_FILEINDEX,
  176. ST_LOADMESSAGES);
  177. var
  178. ppufile : tppufile;
  179. ppuversion : dword;
  180. space : string;
  181. verbose : longint;
  182. derefdata : pbyte;
  183. derefdatalen : longint;
  184. pout: TPpuOutput;
  185. nostdout: boolean;
  186. UnitList: TPpuContainerDef;
  187. CurUnit: TPpuUnitDef;
  188. SkipVersionCheck: boolean;
  189. {****************************************************************************
  190. Helper Routines
  191. ****************************************************************************}
  192. {****************************************************************************
  193. Routine to read 80-bit reals
  194. ****************************************************************************
  195. }
  196. type
  197. TSplit80bitReal = packed record
  198. case byte of
  199. 0: (bytes: Array[0..9] of byte);
  200. 1: (words: Array[0..4] of word);
  201. 2: (cards: Array[0..1] of cardinal; w: word);
  202. end;
  203. const
  204. maxDigits = 17;
  205. function Real80bitToStr(var e : TSplit80bitReal) : string;
  206. var
  207. Temp : string;
  208. new : TSplit80bitReal;
  209. fraczero, expmaximal, sign, outside_double : boolean;
  210. exp : smallint;
  211. ext : extended;
  212. d : double;
  213. i : longint;
  214. mantval : qword;
  215. begin
  216. if ppufile.change_endian then
  217. begin
  218. for i:=0 to 9 do
  219. new.bytes[i]:=e.bytes[9-i];
  220. e:=new;
  221. end;
  222. if sizeof(ext)=10 then
  223. begin
  224. ext:=pextended(@e)^;
  225. str(ext,result);
  226. exit;
  227. end;
  228. { extended, format (MSB): 1 Sign bit, 15 bit exponent, 64 bit mantissa }
  229. sign := (e.w and $8000) <> 0;
  230. expMaximal := (e.w and $7fff) = 32767;
  231. exp:=(e.w and $7fff) - 16383 - 63;
  232. fraczero := (e.cards[0] = 0) and
  233. ((e.cards[1] and $7fffffff) = 0);
  234. mantval := qword(e.cards[0]) or (qword(e.cards[1]) shl 32);
  235. if expMaximal then
  236. if fraczero then
  237. if sign then
  238. temp := '-Inf'
  239. else temp := '+Inf'
  240. else temp := 'Nan'
  241. else
  242. begin
  243. d:=double(mantval);
  244. if sign then
  245. d:=-d;
  246. outside_double:=false;
  247. Try
  248. if exp > 0 then
  249. begin
  250. for i:=1 to exp do
  251. d:=d *2.0;
  252. end
  253. else if exp < 0 then
  254. begin
  255. for i:=1 to -exp do
  256. d:=d /2.0;
  257. end;
  258. Except
  259. outside_double:=true;
  260. end;
  261. if (mantval<>0) and (d=0.0) then
  262. outside_double:=true;
  263. if outside_double then
  264. Temp:='Extended value outside double bound'
  265. else
  266. system.str(d,temp);
  267. end;
  268. result:=temp;
  269. end;
  270. const has_errors : boolean = false;
  271. has_warnings : boolean = false;
  272. has_more_infos : boolean = false;
  273. procedure SetHasErrors;
  274. begin
  275. has_errors:=true;
  276. end;
  277. Procedure WriteError(const S : string);
  278. Begin
  279. system.Writeln(StdErr, S);
  280. SetHasErrors;
  281. End;
  282. Procedure WriteWarning(const S : string);
  283. var
  284. ss: string;
  285. Begin
  286. ss:='!! Warning: ' + S;
  287. if nostdout then
  288. system.Writeln(StdErr, ss)
  289. else
  290. system.Writeln(ss);
  291. has_warnings:=true;
  292. End;
  293. procedure Write(const s: string);
  294. begin
  295. if nostdout then exit;
  296. system.write(s);
  297. end;
  298. procedure Write(const params: array of const);
  299. var
  300. i: integer;
  301. { Last vtType define in rtl/inc/objpash.inc }
  302. const
  303. max_vttype = vtUnicodeString;
  304. begin
  305. if nostdout then exit;
  306. for i:=Low(params) to High(params) do
  307. { All vtType in
  308. vtInteger = 0;
  309. vtBoolean = 1;
  310. vtChar = 2;
  311. vtExtended = 3;
  312. vtString = 4;
  313. vtPointer = 5;
  314. vtPChar = 6;
  315. vtObject = 7;
  316. vtClass = 8;
  317. vtWideChar = 9;
  318. vtPWideChar = 10;
  319. vtAnsiString32 = 11; called vtAnsiString in objpas unit
  320. vtCurrency = 12;
  321. vtVariant = 13;
  322. vtInterface = 14;
  323. vtWideString = 15;
  324. vtInt64 = 16;
  325. vtQWord = 17;
  326. vtUnicodeString = 18;
  327. // vtAnsiString16 = 19; not yet used
  328. // vtAnsiString64 = 20; not yet used
  329. }
  330. with TVarRec(params[i]) do
  331. case VType of
  332. vtInteger: system.write(VInteger);
  333. vtBoolean: system.write(VBoolean);
  334. vtChar: system.write(VChar);
  335. vtExtended: system.write(VExtended^);
  336. vtString: system.write(VString^);
  337. vtPointer:
  338. begin
  339. { Not sure the display will be correct
  340. if sizeof pointer is not native }
  341. WriteWarning('Pointer constant');
  342. end;
  343. vtPChar: system.write(VPChar);
  344. vtObject:
  345. begin
  346. { Not sure the display will be correct
  347. if sizeof pointer is not native }
  348. WriteWarning('Object constant');
  349. end;
  350. vtClass:
  351. begin
  352. { Not sure the display will be correct
  353. if sizeof pointer is not native }
  354. WriteWarning('Class constant');
  355. end;
  356. vtWideChar: system.write(VWideChar);
  357. vtPWideChar:
  358. begin
  359. WriteWarning('PWideChar constant');
  360. end;
  361. vtAnsiString: system.write(ansistring(VAnsiString));
  362. vtCurrency : system.write(VCurrency^);
  363. vtVariant :
  364. begin
  365. { Not sure the display will be correct
  366. if sizeof pointer is not native }
  367. WriteWarning('Variant constant');
  368. end;
  369. vtInterface :
  370. begin
  371. { Not sure the display will be correct
  372. if sizeof pointer is not native }
  373. WriteWarning('Interface constant');
  374. end;
  375. vtWideString : system.write(widestring(VWideString));
  376. vtInt64: system.write(VInt64^);
  377. vtQWord: system.write(VQWord^);
  378. vtUnicodeString : system.write(unicodestring(VUnicodeString));
  379. else
  380. begin
  381. system.writeln;
  382. system.writeln('Unsupported var type: ', VType);
  383. Halt(10);
  384. end;
  385. end;
  386. end;
  387. procedure Writeln(const s: string = '');
  388. begin
  389. if nostdout then exit;
  390. system.writeln(s);
  391. end;
  392. procedure Writeln(const params: array of const);
  393. begin
  394. if nostdout then exit;
  395. Write(params);
  396. system.writeln;
  397. end;
  398. Procedure HasMoreInfos;
  399. begin
  400. Writeln('!! Entry has more information stored');
  401. has_more_infos:=true;
  402. end;
  403. function Unknown(const st : string; val :longint) : string;
  404. Begin
  405. Unknown:='<!! Unknown'+st+' value '+tostr(val)+'>';
  406. SetHasErrors;
  407. end;
  408. function ToStr(w:longint):String;
  409. begin
  410. Str(w,ToStr);
  411. end;
  412. Function Target2Str(w:longint):string;
  413. begin
  414. if w<=ord(high(tsystem)) then
  415. Target2Str:=Targets[tsystem(w)]
  416. else
  417. Target2Str:=Unknown('target',w);
  418. end;
  419. Function Cpu2Str(w:longint):string;
  420. begin
  421. if w<=ord(high(tsystemcpu)) then
  422. begin
  423. cpu:=tsystemcpu(w);
  424. Cpu2Str:=CpuTxt[cpu];
  425. end
  426. else
  427. Cpu2Str:=Unknown('cpu',w);
  428. end;
  429. Function Varspez2Str(w:longint):string;
  430. const
  431. { in symconst unit
  432. tvarspez = (vs_value,vs_const,vs_var,vs_out,vs_constref); }
  433. varspezstr : array[tvarspez] of string[8]=('Value','Const','Var','Out','ConstRef','Final');
  434. begin
  435. if w<=ord(high(varspezstr)) then
  436. Varspez2Str:=varspezstr[tvarspez(w)]
  437. else
  438. Varspez2Str:=Unknown('varspez',w);
  439. end;
  440. Function VarRegable2Str(w:longint):string;
  441. { tvarregable type is defined in symconst unit }
  442. const
  443. varregableStr : array[tvarregable] of string[6]=('None','IntReg','FPUReg','MMReg','Addr');
  444. begin
  445. if w<=ord(high(varregablestr)) then
  446. Varregable2Str:=varregablestr[tvarregable(w)]
  447. else
  448. Varregable2Str:=Unknown('regable',w);
  449. end;
  450. Function Visibility2Str(w:longint):string;
  451. const
  452. { tvisibility type is defined in symconst unit }
  453. visibilityName : array[tvisibility] of string[16] = (
  454. 'hidden','strict private','private','strict protected','protected',
  455. 'public','published','<none>'
  456. );
  457. begin
  458. if w<=ord(high(visibilityName)) then
  459. result:=visibilityName[tvisibility(w)]
  460. else
  461. result:=Unknown('visibility',w);
  462. end;
  463. Function IntfEntryType2Str(w:longint):string;
  464. const
  465. { tinterfaceentrytype type is defined in symconst unit }
  466. Name : array[tinterfaceentrytype] of string = (
  467. 'standard','virtual method result','static method result','field value','virtual method class',
  468. 'static method class','field value class'
  469. );
  470. begin
  471. if w<=ord(high(Name)) then
  472. result:=Name[tinterfaceentrytype(w)]
  473. else
  474. result:=Unknown('entry type',w);
  475. end;
  476. Function Synthetic2Str(w: byte): string;
  477. const
  478. syntheticName : array[tsynthetickind] of string[length('jvm procvar intf constructor')] = (
  479. '<none>','anon inherited','jvm clone','record deep copy',
  480. 'record initilializer', 'empty routine', 'typed const initializer',
  481. 'callthough', 'callthrough if not abstract', 'jvm enum values',
  482. 'jvm enum valueof', 'jvm enum class constructor',
  483. 'jvm enum jumps constructor', 'jvm enum fpcordinal',
  484. 'jvm enum fpcvalueof', 'jvm enum long2set',
  485. 'jvm enum bitset2set', 'jvm enum set2set',
  486. 'jvm procvar invoke', 'jvm procvar intf constructor',
  487. 'jvm virtual class method', 'jvm field getter', 'jvm field setter', 'block invoke');
  488. begin
  489. if w<=ord(high(syntheticName)) then
  490. result:=syntheticName[tsynthetickind(w)]
  491. else
  492. result:=Unknown('synthetickind',w);
  493. end;
  494. function PPUFlags2Str(flags:longint):string;
  495. type
  496. tflagopt=record
  497. mask : longint;
  498. str : string[30];
  499. end;
  500. const
  501. flagopts=28;
  502. flagopt : array[1..flagopts] of tflagopt=(
  503. (mask: $1 ;str:'init'),
  504. (mask: $2 ;str:'final'),
  505. (mask: $4 ;str:'big_endian'),
  506. (mask: $8 ;str:'dbx'),
  507. // (mask: $10 ;str:'browser'),
  508. (mask: $20 ;str:'in_library'),
  509. (mask: $40 ;str:'smart_linked'),
  510. (mask: $80 ;str:'static_linked'),
  511. (mask: $100 ;str:'shared_linked'),
  512. // (mask: $200 ;str:'local_browser'),
  513. (mask: $400 ;str:'no_link'),
  514. (mask: $800 ;str:'has_resources'),
  515. (mask: $1000 ;str:'little_endian'),
  516. (mask: $2000 ;str:'release'),
  517. (mask: $4000 ;str:'local_threadvars'),
  518. (mask: $8000 ;str:'fpu_emulation_on'),
  519. (mask: $210000 ;str:'has_debug_info'),
  520. (mask: $10000 ;str:'stabs_debug_info'),
  521. (mask: $200000 ;str:'dwarf_debug_info'),
  522. (mask: $20000 ;str:'local_symtable'),
  523. (mask: $40000 ;str:'uses_variants'),
  524. (mask: $80000 ;str:'has_resourcefiles'),
  525. (mask: $100000 ;str:'has_exports'),
  526. (mask: $400000 ;str:'has_wideinits'),
  527. (mask: $800000 ;str:'has_classinits'),
  528. (mask: $1000000 ;str:'has_resstrinits'),
  529. (mask: $2000000 ;str:'i8086_far_code'),
  530. (mask: $4000000 ;str:'i8086_far_data'),
  531. (mask: $8000000 ;str:'i8086_huge_data'),
  532. (mask: $10000000;str:'i8086_cs_equals_ds')
  533. );
  534. var
  535. i,ntflags : longint;
  536. first : boolean;
  537. s : string;
  538. begin
  539. s:='';
  540. if flags<>0 then
  541. begin
  542. ntflags:=flags;
  543. first:=true;
  544. for i:=1to flagopts do
  545. if (flags and flagopt[i].mask)<>0 then
  546. begin
  547. if first then
  548. first:=false
  549. else
  550. s:=s+', ';
  551. s:=s+flagopt[i].str;
  552. ntflags:=ntflags and (not flagopt[i].mask);
  553. end;
  554. end
  555. else
  556. s:='none';
  557. if ntflags<>0 then
  558. begin
  559. s:=s+' unknown '+hexstr(ntflags,8);
  560. SetHasErrors;
  561. end;
  562. PPUFlags2Str:=s;
  563. end;
  564. Function L0(l:longint):string;
  565. {
  566. return the string of value l, if l<10 then insert a zero, so
  567. the string is always at least 2 chars '01','02',etc
  568. }
  569. var
  570. s : string;
  571. begin
  572. Str(l,s);
  573. if l<10 then
  574. s:='0'+s;
  575. L0:=s;
  576. end;
  577. function filetimestring( t : longint) : string;
  578. {
  579. convert dos datetime t to a string YY/MM/DD HH:MM:SS
  580. }
  581. var
  582. DT : TDateTime;
  583. hsec : word;
  584. Year,Month,Day: Word;
  585. hour,min,sec : word;
  586. begin
  587. if t=-1 then
  588. begin
  589. Result := 'Not Found';
  590. SetHasErrors;
  591. exit;
  592. end;
  593. DT := FileDateToDateTime(t);
  594. DecodeTime(DT,hour,min,sec,hsec);
  595. DecodeDate(DT,year,month,day);
  596. Result := L0(Year)+'/'+L0(Month)+'/'+L0(Day)+' '+L0(Hour)+':'+L0(min)+':'+L0(sec);
  597. end;
  598. {****************************************************************************
  599. Read Routines
  600. ****************************************************************************}
  601. procedure readrecsymtableoptions;
  602. var
  603. usefieldalignment : shortint;
  604. begin
  605. if ppufile.readentry<>ibrecsymtableoptions then
  606. begin
  607. SetHasErrors;
  608. exit;
  609. end;
  610. writeln([space,' recordalignment: ',shortint(ppufile.getbyte)]);
  611. usefieldalignment:=shortint(ppufile.getbyte);
  612. writeln([space,' usefieldalignment: ',usefieldalignment]);
  613. if (usefieldalignment=C_alignment) then
  614. writeln([space,' fieldalignment: ',shortint(ppufile.getbyte)]);
  615. end;
  616. procedure readsymtableoptions(const s: string);
  617. type
  618. tsymtblopt=record
  619. mask : tsymtableoption;
  620. str : string[30];
  621. end;
  622. const
  623. symtblopts=ord(high(tsymtableoption)) + 1;
  624. symtblopt : array[1..symtblopts] of tsymtblopt=(
  625. (mask:sto_has_helper; str:'Has helper'),
  626. (mask:sto_has_generic; str:'Has generic'),
  627. (mask:sto_has_operator; str:'Has operator'),
  628. (mask:sto_needs_init_final;str:'Needs init final table')
  629. );
  630. var
  631. options : tsymtableoptions;
  632. first : boolean;
  633. i : integer;
  634. begin
  635. if ppufile.readentry<>ibsymtableoptions then
  636. begin
  637. SetHasErrors;
  638. exit;
  639. end;
  640. ppufile.getsmallset(options);
  641. if space<>'' then
  642. writeln([space,'------ ',s,' ------']);
  643. write([space,'Symtable options: ']);
  644. if options<>[] then
  645. begin
  646. first:=true;
  647. for i:=1 to symtblopts do
  648. if (symtblopt[i].mask in options) then
  649. begin
  650. if first then
  651. first:=false
  652. else
  653. write(', ');
  654. write(symtblopt[i].str);
  655. end;
  656. end
  657. else
  658. write('none');
  659. writeln;
  660. end;
  661. procedure readdefinitions(const s:string; ParentDef: TPpuContainerDef); forward;
  662. procedure readsymbols(const s:string; ParentDef: TPpuContainerDef = nil); forward;
  663. procedure readsymtable(const s: string; ParentDef: TPpuContainerDef = nil);
  664. begin
  665. readsymtableoptions(s);
  666. readdefinitions(s, ParentDef);
  667. readsymbols(s, ParentDef);
  668. end;
  669. Procedure ReadLinkContainer(const prefix:string);
  670. {
  671. Read a serie of strings and write to the screen starting every line
  672. with prefix
  673. }
  674. function maskstr(m:longint):string;
  675. { link options are in globtype unit
  676. const
  677. link_none = $0;
  678. link_always = $1;
  679. link_static = $2;
  680. link_smart = $4;
  681. link_shared = $8; }
  682. var
  683. s : string;
  684. begin
  685. s:='';
  686. if (m and link_always)<>0 then
  687. s:=s+'always ';
  688. if (m and link_static)<>0 then
  689. s:=s+'static ';
  690. if (m and link_smart)<>0 then
  691. s:=s+'smart ';
  692. if (m and link_shared)<>0 then
  693. s:=s+'shared ';
  694. maskstr:=s;
  695. end;
  696. var
  697. s : string;
  698. m : longint;
  699. begin
  700. while not ppufile.endofentry do
  701. begin
  702. s:=ppufile.getstring;
  703. m:=ppufile.getlongint;
  704. WriteLn([prefix,s,' (',maskstr(m),')']);
  705. end;
  706. end;
  707. Procedure ReadContainer(const prefix:string);
  708. {
  709. Read a serie of strings and write to the screen starting every line
  710. with prefix
  711. }
  712. begin
  713. while not ppufile.endofentry do
  714. WriteLn([prefix,ppufile.getstring]);
  715. end;
  716. procedure ReadLoadUnit;
  717. var
  718. ucrc,uintfcrc, indcrc : cardinal;
  719. un: TPpuUnitDef;
  720. begin
  721. while not ppufile.EndOfEntry do
  722. begin
  723. un:=TPpuUnitDef.Create(CurUnit.UsedUnits);
  724. un.Name:=ppufile.getstring;
  725. write(['Uses unit: ',un.Name]);
  726. ucrc:=cardinal(ppufile.getlongint);
  727. uintfcrc:=cardinal(ppufile.getlongint);
  728. indcrc:=cardinal(ppufile.getlongint);
  729. writeln([' (Crc: ',hexstr(ucrc,8),', IntfcCrc: ',hexstr(uintfcrc,8),', IndCrc: ',hexstr(indcrc,8),')']);
  730. un.Crc:=ucrc;
  731. un.IntfCrc:=uintfcrc;
  732. end;
  733. end;
  734. Procedure ReadDerefmap;
  735. var
  736. i,mapsize : longint;
  737. s: string;
  738. begin
  739. mapsize:=ppufile.getlongint;
  740. writeln(['DerefMapsize: ',mapsize]);
  741. SetLength(CurUnit.RefUnits, mapsize);
  742. for i:=0 to mapsize-1 do
  743. begin
  744. s:=ppufile.getstring;
  745. writeln(['DerefMap[',i,'] = ',s]);
  746. CurUnit.RefUnits[i]:=LowerCase(s);
  747. end;
  748. end;
  749. Procedure ReadImportSymbols;
  750. var
  751. extlibname : string;
  752. j,
  753. extsymcnt : longint;
  754. extsymname : string;
  755. extsymmangledname : string;
  756. extsymordnr : longint;
  757. extsymisvar : boolean;
  758. begin
  759. while not ppufile.endofentry do
  760. begin
  761. extlibname:=ppufile.getstring;
  762. extsymcnt:=ppufile.getlongint;
  763. writeln(['External Library: ',extlibname,' (',extsymcnt,' imports)']);
  764. for j:=0 to extsymcnt-1 do
  765. begin
  766. extsymname:=ppufile.getstring;
  767. if ppuversion>130 then
  768. extsymmangledname:=ppufile.getstring
  769. else
  770. extsymmangledname:=extsymname;
  771. extsymordnr:=ppufile.getlongint;
  772. extsymisvar:=ppufile.getbyte<>0;
  773. writeln([' ',extsymname,' as ',extsymmangledname,
  774. '(OrdNr: ',extsymordnr,' IsVar: ',extsymisvar,')']);
  775. end;
  776. end;
  777. end;
  778. Procedure ReadDerefdata;
  779. begin
  780. derefdatalen:=ppufile.entrysize;
  781. if derefdatalen=0 then
  782. begin
  783. WriteError('!! Error: derefdatalen=0');
  784. exit;
  785. end;
  786. Writeln(['Derefdata length: ',derefdatalen]);
  787. derefdata:=allocmem(derefdatalen);
  788. ppufile.getdata(derefdata^,derefdatalen);
  789. end;
  790. Procedure FreeDerefdata;
  791. begin
  792. if assigned(derefdata) then
  793. begin
  794. FreeMem(derefdata);
  795. derefdata:=nil;
  796. derefdatalen:=0;
  797. end;
  798. end;
  799. Procedure ReadWpoFileInfo;
  800. begin
  801. Writeln(['Compiled with input whole-program optimisation from ',ppufile.getstring,' ',filetimestring(ppufile.getlongint)]);
  802. end;
  803. Procedure ReadAsmSymbols;
  804. type
  805. { Copied from aasmbase.pas }
  806. TAsmsymbind=(
  807. AB_NONE,AB_EXTERNAL,AB_COMMON,AB_LOCAL,AB_GLOBAL,AB_WEAK_EXTERNAL,
  808. { global in the current program/library, but not visible outside it }
  809. AB_PRIVATE_EXTERN,AB_LAZY,AB_IMPORT);
  810. TAsmsymtype=(
  811. AT_NONE,AT_FUNCTION,AT_DATA,AT_SECTION,AT_LABEL,
  812. {
  813. the address of this code label is taken somewhere in the code
  814. so it must be taken care of it when creating pic
  815. }
  816. AT_ADDR
  817. );
  818. var
  819. s,
  820. bindstr,
  821. typestr : string;
  822. i : longint;
  823. begin
  824. writeln([space,'Number of AsmSymbols: ',ppufile.getlongint]);
  825. i:=0;
  826. while (not ppufile.endofentry) and (not ppufile.error) do
  827. begin
  828. s:=ppufile.getstring;
  829. case tasmsymbind(ppufile.getbyte) of
  830. AB_EXTERNAL :
  831. bindstr:='External';
  832. AB_COMMON :
  833. bindstr:='Common';
  834. AB_LOCAL :
  835. bindstr:='Local';
  836. AB_GLOBAL :
  837. bindstr:='Global';
  838. AB_WEAK_EXTERNAL :
  839. bindstr:='Weak external';
  840. AB_PRIVATE_EXTERN :
  841. bindstr:='Private extern';
  842. AB_LAZY :
  843. bindstr:='Lazy';
  844. AB_IMPORT :
  845. bindstr:='Import';
  846. else
  847. begin
  848. bindstr:='<Error !!>';
  849. SetHasErrors;
  850. end;
  851. end;
  852. case tasmsymtype(ppufile.getbyte) of
  853. AT_FUNCTION :
  854. typestr:='Function';
  855. AT_DATA :
  856. typestr:='Data';
  857. AT_SECTION :
  858. typestr:='Section';
  859. AT_LABEL :
  860. typestr:='Label';
  861. AT_ADDR :
  862. typestr:='Label (with address taken)';
  863. else
  864. begin
  865. typestr:='<Error !!>';
  866. SetHasErrors;
  867. end;
  868. end;
  869. Writeln([space,' ',i,' : ',s,' [',bindstr,',',typestr,']']);
  870. inc(i);
  871. end;
  872. end;
  873. function getexprint:Tconstexprint;
  874. begin
  875. getexprint.overflow:=false;
  876. getexprint.signed:=boolean(ppufile.getbyte);
  877. getexprint.svalue:=ppufile.getint64;
  878. end;
  879. Procedure ReadPosInfo(Def: TPpuDef = nil);
  880. var
  881. info : byte;
  882. fileindex,line,column : longint;
  883. begin
  884. with ppufile do
  885. begin
  886. {
  887. info byte layout in bits:
  888. 0-1 - amount of bytes for fileindex
  889. 2-3 - amount of bytes for line
  890. 4-5 - amount of bytes for column
  891. }
  892. info:=getbyte;
  893. case (info and $03) of
  894. 0 : fileindex:=getbyte;
  895. 1 : fileindex:=getword;
  896. 2 : fileindex:=(getbyte shl 16) or getword;
  897. 3 : fileindex:=getlongint;
  898. end;
  899. case ((info shr 2) and $03) of
  900. 0 : line:=getbyte;
  901. 1 : line:=getword;
  902. 2 : line:=(getbyte shl 16) or getword;
  903. 3 : line:=getlongint;
  904. end;
  905. case ((info shr 4) and $03) of
  906. 0 : column:=getbyte;
  907. 1 : column:=getword;
  908. 2 : column:=(getbyte shl 16) or getword;
  909. 3 : column:=getlongint;
  910. end;
  911. Writeln([fileindex,' (',line,',',column,')']);
  912. if Def <> nil then
  913. begin
  914. Def.FilePos.FileIndex:=fileindex - 1;
  915. Def.FilePos.Line:=line;
  916. Def.FilePos.Col:=column;
  917. end;
  918. end;
  919. end;
  920. procedure readderef(const derefspace: string; Ref: TPpuRef = nil);
  921. var
  922. b : tdereftype;
  923. first : boolean;
  924. idx : longint;
  925. i,n : byte;
  926. pdata : pbyte;
  927. begin
  928. if not assigned(derefdata) then
  929. exit;
  930. first:=true;
  931. idx:=ppufile.getlongint;
  932. if idx = -1 then
  933. begin
  934. writeln('Nil');
  935. exit;
  936. end;
  937. if (idx>derefdatalen) then
  938. begin
  939. WriteError('!! Error: Deref idx '+IntToStr(idx)+' > '+IntToStr(derefdatalen));
  940. exit;
  941. end;
  942. write([derefspace,'(',idx,') ']);
  943. pdata:=@derefdata[idx];
  944. i:=0;
  945. n:=pdata[i];
  946. inc(i);
  947. if n<1 then
  948. begin
  949. WriteError('!! Error: Deref len < 1');
  950. exit;
  951. end;
  952. while (i<=n) do
  953. begin
  954. if not first then
  955. write(', ')
  956. else
  957. first:=false;
  958. b:=tdereftype(pdata[i]);
  959. inc(i);
  960. case b of
  961. deref_nil :
  962. write('Nil');
  963. deref_symid :
  964. begin
  965. idx:=pdata[i] shl 24 or pdata[i+1] shl 16 or pdata[i+2] shl 8 or pdata[i+3];
  966. inc(i,4);
  967. write(['SymId ',idx]);
  968. if Ref <> nil then
  969. Ref.Id:=idx;
  970. end;
  971. deref_defid :
  972. begin
  973. idx:=pdata[i] shl 24 or pdata[i+1] shl 16 or pdata[i+2] shl 8 or pdata[i+3];
  974. inc(i,4);
  975. write(['DefId ',idx]);
  976. if Ref <> nil then
  977. Ref.Id:=idx;
  978. end;
  979. deref_unit :
  980. begin
  981. idx:=pdata[i] shl 8 or pdata[i+1];
  982. inc(i,2);
  983. write(['Unit ',idx]);
  984. if Ref <> nil then
  985. Ref.UnitIndex:=idx;
  986. end;
  987. else
  988. begin
  989. WriteError('!! unsupported dereftyp: '+IntToStr(ord(b)));
  990. break;
  991. end;
  992. end;
  993. end;
  994. writeln;
  995. end;
  996. procedure readpropaccesslist(const s:string; Ref: TPpuRef = nil);
  997. { type tsltype is in symconst unit }
  998. const
  999. slstr : array[tsltype] of string[12] = (
  1000. '',
  1001. 'load',
  1002. 'call',
  1003. 'subscript',
  1004. 'vec',
  1005. 'typeconv',
  1006. 'absolutetype'
  1007. );
  1008. var
  1009. sl : tsltype;
  1010. begin
  1011. readderef('',Ref);
  1012. repeat
  1013. sl:=tsltype(ppufile.getbyte);
  1014. if sl=sl_none then
  1015. break;
  1016. write([s,'(',slstr[sl],') ']);
  1017. case sl of
  1018. sl_call,
  1019. sl_load,
  1020. sl_subscript :
  1021. if (Ref <> nil) and (Ref.IsNull) then
  1022. begin
  1023. readderef('',Ref);
  1024. Ref.IsSymId:=True;
  1025. end
  1026. else
  1027. readderef('');
  1028. sl_absolutetype,
  1029. sl_typeconv :
  1030. readderef('');
  1031. sl_vec :
  1032. begin
  1033. writeln([ppufile.getlongint]);
  1034. readderef('');
  1035. end;
  1036. end;
  1037. until false;
  1038. end;
  1039. (*
  1040. talignmentinfo = packed record
  1041. procalign,
  1042. loopalign,
  1043. jumpalign,
  1044. constalignmin,
  1045. constalignmax,
  1046. varalignmin,
  1047. varalignmax,
  1048. localalignmin,
  1049. localalignmax,
  1050. recordalignmin,
  1051. recordalignmax,
  1052. maxCrecordalign : longint;
  1053. end;
  1054. tsettings = packed record
  1055. alignment : talignmentinfo;
  1056. globalswitches : tglobalswitches;
  1057. moduleswitches : tmoduleswitches;
  1058. localswitches : tlocalswitches;
  1059. modeswitches : tmodeswitches;
  1060. optimizerswitches : toptimizerswitches;
  1061. { generate information necessary to perform these wpo's during a subsequent compilation }
  1062. genwpoptimizerswitches: twpoptimizerswitches;
  1063. { perform these wpo's using information generated during a previous compilation }
  1064. dowpoptimizerswitches: twpoptimizerswitches;
  1065. debugswitches : tdebugswitches;
  1066. { 0: old behaviour for sets <=256 elements
  1067. >0: round to this size }
  1068. setalloc,
  1069. packenum : shortint;
  1070. packrecords : shortint;
  1071. maxfpuregisters : shortint;
  1072. cputype,
  1073. optimizecputype : tcputype;
  1074. fputype : tfputype;
  1075. asmmode : tasmmode;
  1076. interfacetype : tinterfacetypes;
  1077. defproccall : tproccalloption;
  1078. sourcecodepage : tcodepagestring;
  1079. minfpconstprec : tfloattype;
  1080. disabledircache : boolean;
  1081. { CPU targets with microcontroller support can add a controller specific unit }
  1082. controllertype : tcontrollertype;
  1083. { WARNING: this pointer cannot be written as such in record token }
  1084. pmessage : pmessagestaterecord;
  1085. end;
  1086. *)
  1087. procedure readprocinfooptions(space : string);
  1088. (*
  1089. tprocinfoflag=(
  1090. { procedure has at least one assembler block }
  1091. pi_has_assembler_block,
  1092. { procedure does a call }
  1093. pi_do_call,
  1094. { procedure has a try statement = no register optimization }
  1095. pi_uses_exceptions,
  1096. { procedure is declared as @var(assembler), don't optimize}
  1097. pi_is_assembler,
  1098. { procedure contains data which needs to be finalized }
  1099. pi_needs_implicit_finally,
  1100. { procedure has the implicit try..finally generated }
  1101. pi_has_implicit_finally,
  1102. { procedure uses fpu}
  1103. pi_uses_fpu,
  1104. { procedure uses GOT for PIC code }
  1105. pi_needs_got,
  1106. { references var/proc/type/const in static symtable,
  1107. i.e. not allowed for inlining from other units }
  1108. pi_uses_static_symtable,
  1109. { set if the procedure has to push parameters onto the stack }
  1110. pi_has_stackparameter,
  1111. { set if the procedure has at least one label }
  1112. pi_has_label,
  1113. { calls itself recursive }
  1114. pi_is_recursive,
  1115. { stack frame optimization not possible (only on x86 probably) }
  1116. pi_needs_stackframe,
  1117. { set if the procedure has at least one register saved on the stack }
  1118. pi_has_saved_regs,
  1119. { dfa was generated for this proc }
  1120. pi_dfaavailable,
  1121. { subroutine contains interprocedural used labels }
  1122. pi_has_interproclabel,
  1123. { subroutine contains interprocedural gotos }
  1124. pi_has_global_goto
  1125. ); *)
  1126. type
  1127. tprocinfoopt=record
  1128. mask : tprocinfoflag;
  1129. str : string[81];
  1130. end;
  1131. const
  1132. procinfoopts=ord(high(tprocinfoflag)) - ord(low(tprocinfoflag));
  1133. procinfoopt : array[0..procinfoopts] of tprocinfoopt=(
  1134. (mask:pi_has_assembler_block;
  1135. str:' has at least one assembler block'),
  1136. (mask:pi_do_call;
  1137. str:' does a call'),
  1138. (mask:pi_uses_exceptions;
  1139. str:' has a try statement = no register optimization '),
  1140. (mask:pi_is_assembler;
  1141. str:' is declared as @var(assembler), don''t optimize'),
  1142. (mask:pi_needs_implicit_finally;
  1143. str:' contains data which needs to be finalized '),
  1144. (mask:pi_has_implicit_finally;
  1145. str:' has the implicit try..finally generated '),
  1146. (mask:pi_uses_fpu;
  1147. str:' uses fpu'),
  1148. (mask:pi_needs_got;
  1149. str:' uses GOT for PIC code '),
  1150. (mask:pi_uses_static_symtable;
  1151. str:' references var/proc/type/const in static symtable'),
  1152. (mask:pi_has_stackparameter;
  1153. str:' set if the procedure has to push parameters onto the stack '),
  1154. (mask:pi_has_label;
  1155. str:' set if the procedure has at least one label '),
  1156. (mask:pi_is_recursive;
  1157. str:' calls itself recursive '),
  1158. (mask:pi_needs_stackframe;
  1159. str:' stack frame optimization not possible (only on x86 probably) '),
  1160. (mask:pi_has_saved_regs;
  1161. str:' set if the procedure has at least one register saved on the stack '),
  1162. (mask:pi_dfaavailable;
  1163. str:' dfa was generated for this proc '),
  1164. (mask:pi_has_interproclabel;
  1165. str:' subroutine contains interprocedural used labels '),
  1166. (mask:pi_has_unwind_info;
  1167. str:' unwinding info was generated for this proc '),
  1168. (mask:pi_has_global_goto;
  1169. str:' subroutine contains interprocedural goto '),
  1170. (mask:pi_has_inherited;
  1171. str:' subroutine contains inherited call '),
  1172. (mask:pi_has_nested_exit;
  1173. str:' subroutine contains a nested subroutine which calls the exit of the current one '),
  1174. (mask:pi_has_stack_allocs;
  1175. str:' allocates memory on stack, so stack may be unbalanced on exit '),
  1176. (mask:pi_estimatestacksize;
  1177. str:' stack size is estimated before subroutine is compiled '),
  1178. (mask:pi_calls_c_varargs;
  1179. str:' calls function with C-style varargs ')
  1180. );
  1181. var
  1182. procinfooptions : tprocinfoflags;
  1183. i : longint;
  1184. first : boolean;
  1185. begin
  1186. ppufile.getsmallset(procinfooptions);
  1187. if procinfooptions<>[] then
  1188. begin
  1189. first:=true;
  1190. for i:=0 to procinfoopts do
  1191. if (procinfoopt[i].mask in procinfooptions) then
  1192. begin
  1193. if first then
  1194. first:=false
  1195. else
  1196. write(', ');
  1197. write(procinfoopt[i].str);
  1198. end;
  1199. end;
  1200. writeln;
  1201. end;
  1202. procedure readsymoptions(space : string; Def: TPpuDef = nil);
  1203. type
  1204. tsymopt=record
  1205. mask : tsymoption;
  1206. str : string[30];
  1207. end;
  1208. const
  1209. symopts=ord(high(tsymoption)) - ord(low(tsymoption));
  1210. { sp_none = 0 corresponds to nothing }
  1211. symopt : array[1..symopts] of tsymopt=(
  1212. (mask:sp_static; str:'Static'),
  1213. (mask:sp_hint_deprecated; str:'Hint Deprecated'),
  1214. (mask:sp_hint_platform; str:'Hint Platform'),
  1215. (mask:sp_hint_library; str:'Hint Library'),
  1216. (mask:sp_hint_unimplemented; str:'Hint Unimplemented'),
  1217. (mask:sp_hint_experimental; str:'Hint Experimental'),
  1218. (mask:sp_has_overloaded; str:'Has overloaded'),
  1219. (mask:sp_internal; str:'Internal'),
  1220. (mask:sp_implicitrename; str:'Implicit Rename'),
  1221. (mask:sp_generic_para; str:'Generic Parameter'),
  1222. (mask:sp_has_deprecated_msg; str:'Has Deprecated Message'),
  1223. (mask:sp_generic_dummy; str:'Generic Dummy'),
  1224. (mask:sp_explicitrename; str:'Explicit Rename')
  1225. );
  1226. var
  1227. symoptions : tsymoptions;
  1228. i : longint;
  1229. first : boolean;
  1230. begin
  1231. ppufile.getsmallset(symoptions);
  1232. if symoptions<>[] then
  1233. begin
  1234. if Def <> nil then
  1235. if sp_internal in symoptions then
  1236. Def.Visibility:=dvHidden;
  1237. first:=true;
  1238. for i:=1to symopts do
  1239. if (symopt[i].mask in symoptions) then
  1240. begin
  1241. if first then
  1242. first:=false
  1243. else
  1244. write(', ');
  1245. write(symopt[i].str);
  1246. end;
  1247. end;
  1248. writeln;
  1249. if sp_has_deprecated_msg in symoptions then
  1250. writeln([space,'Deprecated : ', ppufile.getstring]);
  1251. end;
  1252. procedure readvisibility(Def: TPpuDef = nil);
  1253. var
  1254. i: byte;
  1255. begin
  1256. i:=ppufile.getbyte;
  1257. if Def <> nil then
  1258. case tvisibility(i) of
  1259. vis_public: Def.Visibility:=dvPublic;
  1260. vis_published: Def.Visibility:=dvPublished;
  1261. vis_protected, vis_strictprotected: Def.Visibility:=dvProtected;
  1262. else Def.Visibility:=dvPrivate;
  1263. end;
  1264. writeln(Visibility2Str(i));
  1265. end;
  1266. procedure readcommonsym(const s:string; Def: TPpuDef = nil);
  1267. var
  1268. i: integer;
  1269. n: string;
  1270. begin
  1271. i:=ppufile.getlongint;
  1272. if Def <> nil then
  1273. Def.SetSymId(i);
  1274. writeln([space,'** Symbol Id ',i,' **']);
  1275. n:=ppufile.getstring;
  1276. if Def <> nil then
  1277. Def.Name:=n;
  1278. writeln([space,s,n]);
  1279. write ([space,' File Pos : ']);
  1280. readposinfo(Def);
  1281. write ([space,' Visibility : ']);
  1282. readvisibility(Def);
  1283. write ([space,' SymOptions : ']);
  1284. readsymoptions(space+' ',Def);
  1285. end;
  1286. var
  1287. { needed during tobjectdef parsing... }
  1288. current_defoptions : tdefoptions;
  1289. current_objectoptions : tobjectoptions;
  1290. procedure readcommondef(const s:string; out defoptions: tdefoptions; Def: TPpuDef = nil);
  1291. type
  1292. tdefopt=record
  1293. mask : tdefoption;
  1294. str : string[30];
  1295. end;
  1296. tdefstateinfo=record
  1297. mask : tdefstate;
  1298. str : string[30];
  1299. end;
  1300. tgenconstrflag=record
  1301. mask : tgenericconstraintflag;
  1302. str : string[30];
  1303. end;
  1304. ptoken=^ttoken;
  1305. pmsgstate =^tmsgstate;
  1306. const
  1307. defopt : array[1..ord(high(tdefoption))] of tdefopt=(
  1308. (mask:df_unique; str:'Unique Type'),
  1309. (mask:df_generic; str:'Generic'),
  1310. (mask:df_specialization; str:'Specialization'),
  1311. (mask:df_copied_def; str:'Copied Typedef'),
  1312. (mask:df_genconstraint; str:'Generic Constraint')
  1313. );
  1314. defstate : array[1..ord(high(tdefstate))] of tdefstateinfo=(
  1315. (mask:ds_vmt_written; str:'VMT Written'),
  1316. (mask:ds_rtti_table_used; str:'RTTITable Used'),
  1317. (mask:ds_init_table_used; str:'InitTable Used'),
  1318. (mask:ds_rtti_table_written; str:'RTTITable Written'),
  1319. (mask:ds_init_table_written; str:'InitTable Written'),
  1320. (mask:ds_dwarf_dbg_info_used; str:'Dwarf DbgInfo Used'),
  1321. (mask:ds_dwarf_dbg_info_written;str:'Dwarf DbgInfo Written')
  1322. );
  1323. genconstrflag : array[1..ord(high(tgenericconstraintflag))] of tgenconstrflag=(
  1324. (mask:gcf_constructor; str:'Constructor'),
  1325. (mask:gcf_class; str:'Class'),
  1326. (mask:gcf_record; str:'Record')
  1327. );
  1328. var
  1329. defstates : tdefstates;
  1330. i, nb{, msgvalue}, mesgnb : longint;
  1331. first : boolean;
  1332. copy_size, min_size, tokenbufsize : longint;
  1333. tokenbuf : pbyte;
  1334. // idtoken,
  1335. token : ttoken;
  1336. // state : tmsgstate;
  1337. new_settings : Tsettings;
  1338. len : sizeint;
  1339. wstring : widestring;
  1340. astring : ansistring;
  1341. genconstr : tgenericconstraintflags;
  1342. function readtoken: ttoken;
  1343. var
  1344. b,b2 : byte;
  1345. begin
  1346. b:=tokenbuf[i];
  1347. inc(i);
  1348. if (b and $80)<>0 then
  1349. begin
  1350. b2:=tokenbuf[i];
  1351. inc(i);
  1352. result:=ttoken(((b and $7f) shl 8) or b2);
  1353. end
  1354. else
  1355. result:=ttoken(b);
  1356. end;
  1357. function gettokenbufdword : dword;
  1358. var
  1359. var32 : dword;
  1360. begin
  1361. var32:=pdword(@tokenbuf[i])^;
  1362. inc(i,sizeof(dword));
  1363. if ppufile.change_endian then
  1364. var32:=swapendian(var32);
  1365. result:=var32;
  1366. end;
  1367. function gettokenbufword : word;
  1368. var
  1369. var16 : word;
  1370. begin
  1371. var16:=pword(@tokenbuf[i])^;
  1372. inc(i,sizeof(word));
  1373. if ppufile.change_endian then
  1374. var16:=swapendian(var16);
  1375. result:=var16;
  1376. end;
  1377. function gettokenbufsizeint : int64;
  1378. var
  1379. var64 : int64;
  1380. var32 : longint;
  1381. var16 : smallint;
  1382. begin
  1383. if CpuAddrBitSize[cpu]=64 then
  1384. begin
  1385. var64:=pint64(@tokenbuf[i])^;
  1386. inc(i,sizeof(int64));
  1387. if ppufile.change_endian then
  1388. var64:=swapendian(var64);
  1389. result:=var64;
  1390. end
  1391. else if CpuAddrBitSize[cpu]=32 then
  1392. begin
  1393. var32:=plongint(@tokenbuf[i])^;
  1394. inc(i,sizeof(longint));
  1395. if ppufile.change_endian then
  1396. var32:=swapendian(var32);
  1397. result:=var32;
  1398. end
  1399. else if CpuAddrBitSize[cpu]=16 then
  1400. begin
  1401. var16:=psmallint(@tokenbuf[i])^;
  1402. inc(i,sizeof(smallint));
  1403. if ppufile.change_endian then
  1404. var16:=swapendian(var16);
  1405. result:=var16;
  1406. end
  1407. else
  1408. begin
  1409. WriteError('Wrong CpuAddrBitSize');
  1410. result:=0;
  1411. end;
  1412. end;
  1413. begin
  1414. i:=ppufile.getlongint;
  1415. if Def <> nil then
  1416. Def.Id:=i;
  1417. writeln([space,'** Definition Id ',i,' **']);
  1418. writeln([space,s]);
  1419. write ([space,' Type symbol : ']);
  1420. if Def <> nil then
  1421. readderef('', Def.Ref)
  1422. else
  1423. readderef('');
  1424. write ([space,' DefOptions : ']);
  1425. ppufile.getsmallset(defoptions);
  1426. if defoptions<>[] then
  1427. begin
  1428. first:=true;
  1429. for i:=1to high(defopt) do
  1430. if (defopt[i].mask in defoptions) then
  1431. begin
  1432. if first then
  1433. first:=false
  1434. else
  1435. write(', ');
  1436. write(defopt[i].str);
  1437. end;
  1438. end;
  1439. writeln;
  1440. write ([space,' DefStates : ']);
  1441. ppufile.getsmallset(defstates);
  1442. if defstates<>[] then
  1443. begin
  1444. first:=true;
  1445. for i:=1 to high(defstate) do
  1446. if (defstate[i].mask in defstates) then
  1447. begin
  1448. if first then
  1449. first:=false
  1450. else
  1451. write(', ');
  1452. write(defstate[i].str);
  1453. end;
  1454. end;
  1455. writeln;
  1456. if df_genconstraint in defoptions then
  1457. begin
  1458. ppufile.getsmallset(genconstr);
  1459. write ([space,' GenConstraints : ']);
  1460. if genconstr<>[] then
  1461. begin
  1462. first:=true;
  1463. for i:=1 to high(genconstrflag) do
  1464. if (genconstrflag[i].mask in genconstr) then
  1465. begin
  1466. if first then
  1467. first:=false
  1468. else
  1469. write(', ');
  1470. write(genconstrflag[i].str);
  1471. end;
  1472. end;
  1473. writeln;
  1474. len:=ppufile.getasizeint;
  1475. if len>0 then
  1476. begin
  1477. space:=' '+space;
  1478. writeln([space,'------ constraint defs begin ------']);
  1479. for i:=0 to len-1 do
  1480. begin
  1481. writeln([space,'------ constraint def ',i,' ------']);
  1482. readderef(space);
  1483. end;
  1484. writeln([space,'------ constraint defs end ------']);
  1485. delete(space,1,4);
  1486. end;
  1487. end;
  1488. if [df_generic,df_specialization]*defoptions<>[] then
  1489. begin
  1490. nb:=ppufile.getlongint;
  1491. writeln([space,'has ',nb,' parameters']);
  1492. if nb>0 then
  1493. begin
  1494. for i:=0 to nb-1 do
  1495. begin
  1496. writeln([space,'parameter ',i,': ',ppufile.getstring]);
  1497. readderef(space);
  1498. end;
  1499. end;
  1500. end;
  1501. if df_generic in defoptions then
  1502. begin
  1503. tokenbufsize:=ppufile.getlongint;
  1504. writeln([space,' Tokenbuffer size : ',tokenbufsize]);
  1505. tokenbuf:=allocmem(tokenbufsize);
  1506. ppufile.getdata(tokenbuf^,tokenbufsize);
  1507. i:=0;
  1508. write([space,' Tokens: ']);
  1509. while i<tokenbufsize do
  1510. begin
  1511. token:=readtoken;
  1512. if token<>_GENERICSPECIALTOKEN then
  1513. begin
  1514. if token <= high(ttoken) then
  1515. write(arraytokeninfo[token].str)
  1516. else
  1517. begin
  1518. HasMoreInfos;
  1519. write('Error in Token List');
  1520. break;
  1521. end;
  1522. {idtoken:=}readtoken;
  1523. end;
  1524. case token of
  1525. _CWCHAR,
  1526. _CWSTRING :
  1527. begin
  1528. len:=gettokenbufsizeint;
  1529. setlength(wstring,len);
  1530. move(tokenbuf[i],wstring[1],len*2);
  1531. write([' ',wstring]);
  1532. inc(i,len*2);
  1533. end;
  1534. _CSTRING:
  1535. begin
  1536. len:=gettokenbufsizeint;
  1537. setlength(astring,len);
  1538. move(tokenbuf[i],astring[1],len);
  1539. write([' ',astring]);
  1540. inc(i,len);
  1541. end;
  1542. _CCHAR,
  1543. _INTCONST,
  1544. _REALNUMBER :
  1545. begin
  1546. write([' ',pshortstring(@tokenbuf[i])^]);
  1547. inc(i,tokenbuf[i]+1);
  1548. end;
  1549. _ID :
  1550. begin
  1551. write([' ',pshortstring(@tokenbuf[i])^]);
  1552. inc(i,tokenbuf[i]+1);
  1553. end;
  1554. _GENERICSPECIALTOKEN:
  1555. begin
  1556. { Short version of column change,
  1557. byte or $80 used }
  1558. if (tokenbuf[i] and $80)<>0 then
  1559. begin
  1560. write(['Col: ',tokenbuf[i] and $7f]);
  1561. inc(i);
  1562. end
  1563. else
  1564. case tspecialgenerictoken(tokenbuf[i]) of
  1565. ST_LOADSETTINGS:
  1566. begin
  1567. inc(i);
  1568. write('Settings');
  1569. { This does not load pmessage pointer }
  1570. new_settings.pmessage:=nil;
  1571. { TSettings size depends in target...
  1572. We first read the size of the copied part }
  1573. { Still not cross endian ready :( }
  1574. copy_size:=gettokenbufsizeint;
  1575. if copy_size < sizeof(tsettings)-sizeof(pointer) then
  1576. min_size:=copy_size
  1577. else
  1578. min_size:= sizeof(tsettings)-sizeof(pointer);
  1579. move(tokenbuf[i],new_settings, min_size);
  1580. inc(i,copy_size);
  1581. end;
  1582. ST_LOADMESSAGES:
  1583. begin
  1584. inc(i);
  1585. write('Messages:');
  1586. mesgnb:=tokenbuf[i];
  1587. inc(i);
  1588. for nb:=1 to mesgnb do
  1589. begin
  1590. {msgvalue:=}gettokenbufsizeint;
  1591. inc(i,sizeof(sizeint));
  1592. //state:=tmsgstate(gettokenbufsizeint);
  1593. end;
  1594. end;
  1595. ST_LINE:
  1596. begin
  1597. inc(i);
  1598. write(['Line: ',gettokenbufdword]);
  1599. end;
  1600. ST_COLUMN:
  1601. begin
  1602. inc(i);
  1603. write(['Col: ',gettokenbufword]);
  1604. end;
  1605. ST_FILEINDEX:
  1606. begin
  1607. inc(i);
  1608. write(['File: ',gettokenbufword]);
  1609. end;
  1610. end;
  1611. end;
  1612. end;
  1613. if i<tokenbufsize then
  1614. write(',');
  1615. end;
  1616. writeln;
  1617. freemem(tokenbuf);
  1618. end;
  1619. if df_specialization in defoptions then
  1620. begin
  1621. write ([space,' Orig. GenericDef : ']);
  1622. readderef('');
  1623. end;
  1624. current_defoptions:=defoptions;
  1625. end;
  1626. { Read abstract procdef and return if inline procdef }
  1627. { type tproccalloption is in globtype unit }
  1628. { type tproctypeoption is in globtype unit }
  1629. { type tprocoption is in globtype unit }
  1630. procedure read_abstract_proc_def(var proccalloption:tproccalloption;var procoptions:tprocoptions; ProcDef: TPpuProcDef);
  1631. type
  1632. tproccallopt=record
  1633. mask : tproccalloption;
  1634. str : string[30];
  1635. end;
  1636. tproctypeopt=record
  1637. mask : tproctypeoption;
  1638. str : string[30];
  1639. end;
  1640. tprocopt=record
  1641. mask : tprocoption;
  1642. str : string[31];
  1643. end;
  1644. const
  1645. {proccalloptionStr is also in globtype unit }
  1646. proctypeopt : array[1..ord(high(tproctypeoption))] of tproctypeopt=(
  1647. (mask:potype_proginit; str:'ProgInit'),
  1648. (mask:potype_unitinit; str:'UnitInit'),
  1649. (mask:potype_unitfinalize; str:'UnitFinalize'),
  1650. (mask:potype_constructor; str:'Constructor'),
  1651. (mask:potype_destructor; str:'Destructor'),
  1652. (mask:potype_operator; str:'Operator'),
  1653. (mask:potype_procedure; str:'Procedure'),
  1654. (mask:potype_function; str:'Function'),
  1655. (mask:potype_class_constructor; str:'Class Constructor'),
  1656. (mask:potype_class_destructor; str:'Class Destructor'),
  1657. { Dispinterface property accessors }
  1658. (mask:potype_propgetter; str:'Property Getter'),
  1659. (mask:potype_propsetter; str:'Property Setter'),
  1660. (mask:potype_exceptfilter; str:'SEH filter')
  1661. );
  1662. procopt : array[1..ord(high(tprocoption))] of tprocopt=(
  1663. (mask:po_classmethod; str:'ClassMethod'),
  1664. (mask:po_virtualmethod; str:'VirtualMethod'),
  1665. (mask:po_abstractmethod; str:'AbstractMethod'),
  1666. (mask:po_finalmethod; str:'FinalMethod'),
  1667. (mask:po_staticmethod; str:'StaticMethod'),
  1668. (mask:po_overridingmethod;str:'OverridingMethod'),
  1669. (mask:po_methodpointer; str:'MethodPointer'),
  1670. (mask:po_interrupt; str:'Interrupt'),
  1671. (mask:po_iocheck; str:'IOCheck'),
  1672. (mask:po_assembler; str:'Assembler'),
  1673. (mask:po_msgstr; str:'MsgStr'),
  1674. (mask:po_msgint; str:'MsgInt'),
  1675. (mask:po_exports; str:'Exports'),
  1676. (mask:po_external; str:'External'),
  1677. (mask:po_overload; str:'Overload'),
  1678. (mask:po_varargs; str:'VarArgs'),
  1679. (mask:po_internconst; str:'InternConst'),
  1680. (mask:po_addressonly; str:'AddressOnly'),
  1681. (mask:po_public; str:'Public'),
  1682. (mask:po_hascallingconvention;str:'HasCallingConvention'),
  1683. (mask:po_reintroduce; str:'ReIntroduce'),
  1684. (mask:po_explicitparaloc; str:'ExplicitParaloc'),
  1685. (mask:po_nostackframe; str:'NoStackFrame'),
  1686. (mask:po_has_mangledname; str:'HasMangledName'),
  1687. (mask:po_has_public_name; str:'HasPublicName'),
  1688. (mask:po_forward; str:'Forward'),
  1689. (mask:po_global; str:'Global'),
  1690. (mask:po_syscall_legacy; str:'SyscallLegacy'),
  1691. (mask:po_syscall_sysv; str:'SyscallSysV'),
  1692. (mask:po_syscall_basesysv;str:'SyscallBaseSysV'),
  1693. (mask:po_syscall_sysvbase;str:'SyscallSysVBase'),
  1694. (mask:po_syscall_r12base; str:'SyscallR12Base'),
  1695. (mask:po_syscall_has_libsym; str:'Has LibSym'),
  1696. (mask:po_inline; str:'Inline'),
  1697. (mask:po_compilerproc; str:'CompilerProc'),
  1698. (mask:po_has_importdll; str:'HasImportDLL'),
  1699. (mask:po_has_importname; str:'HasImportName'),
  1700. (mask:po_kylixlocal; str:'KylixLocal'),
  1701. (mask:po_dispid; str:'DispId'),
  1702. (mask:po_weakexternal; str:'WeakExternal'),
  1703. (mask:po_objc; str:'ObjC'),
  1704. (mask:po_enumerator_movenext; str:'EnumeratorMoveNext'),
  1705. (mask:po_optional; str: 'Optional'),
  1706. (mask:po_delphi_nested_cc;str: 'Delphi-style nested frameptr'),
  1707. (mask:po_java_nonvirtual; str: 'Java non-virtual method'),
  1708. (mask:po_ignore_for_overload_resolution;str: 'Ignored for overload resolution'),
  1709. (mask:po_rtlproc; str: 'RTL procedure'),
  1710. (mask:po_auto_raised_visibility; str: 'Visibility raised by compiler'),
  1711. (mask:po_far; str: 'Far'),
  1712. (mask:po_noreturn; str: 'No return'),
  1713. (mask:po_is_function_ref; str: 'Function reference'),
  1714. (mask:po_is_block; str: 'C "Block"')
  1715. );
  1716. var
  1717. proctypeoption : tproctypeoption;
  1718. i : longint;
  1719. first : boolean;
  1720. tempbuf : array[0..255] of byte;
  1721. begin
  1722. write([space,' Return type : ']);
  1723. readderef('', ProcDef.ReturnType);
  1724. proctypeoption:=tproctypeoption(ppufile.getbyte);
  1725. case proctypeoption of
  1726. potype_function: Include(ProcDef.Options, poFunction);
  1727. potype_procedure: Include(ProcDef.Options, poProcedure);
  1728. potype_constructor: Include(ProcDef.Options, poConstructor);
  1729. potype_destructor: Include(ProcDef.Options, poDestructor);
  1730. potype_operator: Include(ProcDef.Options, poOperator);
  1731. end;
  1732. write([space,' TypeOption : ']);
  1733. first:=true;
  1734. for i:=1 to high(proctypeopt) do
  1735. if (proctypeopt[i].mask=proctypeoption) then
  1736. begin
  1737. if first then
  1738. first:=false
  1739. else
  1740. write(', ');
  1741. write(proctypeopt[i].str);
  1742. end;
  1743. writeln;
  1744. proccalloption:=tproccalloption(ppufile.getbyte);
  1745. writeln([space,' CallOption : ',proccalloptionStr[proccalloption]]);
  1746. ppufile.getnormalset(procoptions);
  1747. if procoptions<>[] then
  1748. begin
  1749. if po_classmethod in procoptions then Include(ProcDef.Options, poClassMethod);
  1750. if po_virtualmethod in procoptions then Include(ProcDef.Options, poVirtual);
  1751. if po_abstractmethod in procoptions then Include(ProcDef.Options, poAbstract);
  1752. if po_overridingmethod in procoptions then Include(ProcDef.Options, poOverriding);
  1753. if po_overload in procoptions then Include(ProcDef.Options, poOverload);
  1754. if po_inline in procoptions then Include(ProcDef.Options, poInline);
  1755. if (po_methodpointer in procoptions) and (ProcDef.DefType = dtProcType) then
  1756. TPpuProcTypeDef(ProcDef).MethodPtr:=True;
  1757. write([space,' Options : ']);
  1758. first:=true;
  1759. for i:=1 to high(procopt) do
  1760. if (procopt[i].mask in procoptions) then
  1761. begin
  1762. if first then
  1763. first:=false
  1764. else
  1765. write(', ');
  1766. write(procopt[i].str);
  1767. end;
  1768. writeln;
  1769. end;
  1770. if (po_explicitparaloc in procoptions) then
  1771. begin
  1772. i:=ppufile.getbyte;
  1773. ppufile.getdata(tempbuf,i);
  1774. end;
  1775. if po_syscall_has_libsym in procoptions then
  1776. readderef(space);
  1777. end;
  1778. { type tvaroption is in unit symconst }
  1779. { register variable }
  1780. { type tvarregable is in unit symconst }
  1781. procedure readabstractvarsym(const s:string;var varoptions:tvaroptions; VarDef: TPpuVarDef = nil);
  1782. type
  1783. tvaropt=record
  1784. mask : tvaroption;
  1785. str : string[30];
  1786. end;
  1787. const
  1788. varopt : array[1..ord(high(tvaroption))] of tvaropt=(
  1789. (mask:vo_is_external; str:'External'),
  1790. (mask:vo_is_dll_var; str:'DLLVar'),
  1791. (mask:vo_is_thread_var; str:'ThreadVar'),
  1792. (mask:vo_has_local_copy; str:'HasLocalCopy'),
  1793. (mask:vo_is_const; str:'Constant'),
  1794. (mask:vo_is_public; str:'Public'),
  1795. (mask:vo_is_high_para; str:'HighValue'),
  1796. (mask:vo_is_funcret; str:'Funcret'),
  1797. (mask:vo_is_self; str:'Self'),
  1798. (mask:vo_is_vmt; str:'VMT'),
  1799. (mask:vo_is_result; str:'Result'),
  1800. (mask:vo_is_parentfp; str:'ParentFP'),
  1801. (mask:vo_is_loop_counter; str:'LoopCounter'),
  1802. (mask:vo_is_hidden_para; str:'Hidden'),
  1803. (mask:vo_has_explicit_paraloc;str:'ExplicitParaloc'),
  1804. (mask:vo_is_syscall_lib; str:'SysCallLib'),
  1805. (mask:vo_has_mangledname; str:'HasMangledName'),
  1806. (mask:vo_is_typed_const; str:'TypedConst'),
  1807. (mask:vo_is_range_check; str:'RangeCheckSwitch'),
  1808. (mask:vo_is_overflow_check; str:'OverflowCheckSwitch'),
  1809. (mask:vo_is_typinfo_para; str:'TypeInfo'),
  1810. (mask:vo_is_msgsel;str:'MsgSel'),
  1811. (mask:vo_is_weak_external;str:'WeakExternal'),
  1812. (mask:vo_is_first_field;str:'IsFirstField'),
  1813. (mask:vo_volatile; str:'Volatile'),
  1814. (mask:vo_has_section; str:'HasSection'),
  1815. (mask:vo_force_finalize; str:'ForceFinalize'),
  1816. (mask:vo_is_default_var; str:'DefaultIntrinsicVar')
  1817. );
  1818. var
  1819. i : longint;
  1820. first : boolean;
  1821. begin
  1822. readcommonsym(s, VarDef);
  1823. i:=ppufile.getbyte;
  1824. if (VarDef <> nil) and (VarDef.DefType = dtParam) then
  1825. with TPpuParamDef(VarDef) do
  1826. case tvarspez(i) of
  1827. vs_value: Spez:=psValue;
  1828. vs_var: Spez:=psVar;
  1829. vs_out: Spez:=psOut;
  1830. vs_const: Spez:=psConst;
  1831. vs_constref: Spez:=psConstRef;
  1832. end;
  1833. writeln([space,' Spez : ',Varspez2Str(i)]);
  1834. writeln([space,' Regable : ',Varregable2Str(ppufile.getbyte)]);
  1835. writeln([space,' Addr Taken : ',(ppufile.getbyte<>0)]);
  1836. write ([space,' Var Type : ']);
  1837. if VarDef <> nil then
  1838. readderef('',VarDef.VarType)
  1839. else
  1840. readderef('');
  1841. ppufile.getsmallset(varoptions);
  1842. if varoptions<>[] then
  1843. begin
  1844. if (VarDef <> nil) and (VarDef.DefType = dtParam) and (vo_is_hidden_para in varoptions) then
  1845. TPpuParamDef(VarDef).Spez:=psHidden;
  1846. write([space,' Options : ']);
  1847. first:=true;
  1848. for i:=1 to high(varopt) do
  1849. if (varopt[i].mask in varoptions) then
  1850. begin
  1851. if first then
  1852. first:=false
  1853. else
  1854. write(', ');
  1855. write(varopt[i].str);
  1856. end;
  1857. writeln;
  1858. end;
  1859. end;
  1860. procedure readobjectdefoptions(ObjDef: TPpuObjectDef = nil);
  1861. type
  1862. tsymopt=record
  1863. mask : tobjectoption;
  1864. str : string[30];
  1865. end;
  1866. const
  1867. symopt : array[1..ord(high(tobjectoption))] of tsymopt=(
  1868. (mask:oo_is_forward; str:'IsForward'),
  1869. (mask:oo_is_abstract; str:'IsAbstract'),
  1870. (mask:oo_is_sealed; str:'IsSealed'),
  1871. (mask:oo_has_virtual; str:'HasVirtual'),
  1872. (mask:oo_has_private; str:'HasPrivate'),
  1873. (mask:oo_has_protected; str:'HasProtected'),
  1874. (mask:oo_has_strictprivate; str:'HasStrictPrivate'),
  1875. (mask:oo_has_strictprotected;str:'HasStrictProtected'),
  1876. (mask:oo_has_constructor; str:'HasConstructor'),
  1877. (mask:oo_has_destructor; str:'HasDestructor'),
  1878. (mask:oo_has_vmt; str:'HasVMT'),
  1879. (mask:oo_has_msgstr; str:'HasMsgStr'),
  1880. (mask:oo_has_msgint; str:'HasMsgInt'),
  1881. (mask:oo_can_have_published; str:'CanHavePublished'),
  1882. (mask:oo_has_default_property;str:'HasDefaultProperty'),
  1883. (mask:oo_has_valid_guid; str:'HasValidGUID'),
  1884. (mask:oo_has_enumerator_movenext; str:'HasEnumeratorMoveNext'),
  1885. (mask:oo_has_enumerator_current; str:'HasEnumeratorCurrent'),
  1886. (mask:oo_is_external; str:'External'),
  1887. (mask:oo_is_formal; str:'Formal'),
  1888. (mask:oo_is_classhelper; str:'Class Helper/Category'),
  1889. (mask:oo_has_class_constructor; str:'HasClassConstructor'),
  1890. (mask:oo_has_class_destructor; str:'HasClassDestructor'),
  1891. (mask:oo_is_enum_class; str:'JvmEnumClass'),
  1892. (mask:oo_has_new_destructor; str:'HasNewDestructor')
  1893. );
  1894. var
  1895. i : longint;
  1896. first : boolean;
  1897. begin
  1898. ppufile.getsmallset(current_objectoptions);
  1899. if current_objectoptions<>[] then
  1900. begin
  1901. if ObjDef <> nil then
  1902. begin
  1903. if oo_is_abstract in current_objectoptions then
  1904. Include(ObjDef.Options, ooIsAbstract);
  1905. end;
  1906. first:=true;
  1907. for i:=1 to high(symopt) do
  1908. if (symopt[i].mask in current_objectoptions) then
  1909. begin
  1910. if first then
  1911. first:=false
  1912. else
  1913. write(', ');
  1914. write(symopt[i].str);
  1915. end;
  1916. end;
  1917. writeln;
  1918. end;
  1919. procedure readprocimploptions(const space: string; out implprocoptions: timplprocoptions);
  1920. type
  1921. tpiopt=record
  1922. mask : timplprocoption;
  1923. str : string[30];
  1924. end;
  1925. const
  1926. piopt : array[low(timplprocoption)..high(timplprocoption)] of tpiopt=(
  1927. (mask:pio_empty; str:'IsEmpty'),
  1928. (mask:pio_has_inlininginfo; str:'HasInliningInfo')
  1929. );
  1930. var
  1931. i: timplprocoption;
  1932. first: boolean;
  1933. begin
  1934. ppufile.getsmallset(implprocoptions);
  1935. if implprocoptions<>[] then
  1936. begin
  1937. first:=true;
  1938. write([space,' Options : ']);
  1939. for i:=low(piopt) to high(piopt) do
  1940. begin
  1941. if i in implprocoptions then
  1942. begin
  1943. if first then
  1944. first:=false
  1945. else
  1946. write(', ');
  1947. write(piopt[i].str);
  1948. end;
  1949. end;
  1950. writeln;
  1951. end;
  1952. end;
  1953. procedure readarraydefoptions(ArrayDef: TPpuArrayDef);
  1954. { type tarraydefoption is in unit symconst }
  1955. const
  1956. symopt : array[tarraydefoption] of string = (
  1957. { ado_IsConvertedPointer } 'ConvertedPointer',
  1958. { ado_IsDynamicArray } 'IsDynamicArray',
  1959. { ado_IsVariant } 'IsVariant',
  1960. { ado_IsConstructor } 'IsConstructor',
  1961. { ado_IsArrayOfConst } 'ArrayOfConst',
  1962. { ado_IsConstString } 'ConstString',
  1963. { ado_IsBitPacked } 'BitPacked'
  1964. );
  1965. var
  1966. symoptions: tarraydefoptions;
  1967. i: tarraydefoption;
  1968. first: boolean;
  1969. begin
  1970. ppufile.getsmallset(symoptions);
  1971. if symoptions<>[] then
  1972. begin
  1973. if ado_IsDynamicArray in symoptions then Include(ArrayDef.Options, aoDynamic);
  1974. first:=true;
  1975. for i:=Low(symopt) to high(symopt) do
  1976. if (i in symoptions) then
  1977. begin
  1978. if first then
  1979. first:=false
  1980. else
  1981. write(', ');
  1982. write(symopt[i]);
  1983. end;
  1984. end;
  1985. writeln;
  1986. end;
  1987. (* options for properties
  1988. tpropertyoption=(ppo_none,
  1989. ppo_indexed,
  1990. ppo_defaultproperty,
  1991. ppo_stored,
  1992. ppo_hasparameters,
  1993. ppo_implements,
  1994. ppo_enumerator_current,
  1995. ppo_overrides,
  1996. ppo_dispid_write { no longer used }
  1997. );
  1998. tpropertyoptions=set of tpropertyoption;
  1999. *)
  2000. function readpropertyoptions:tpropertyoptions;
  2001. { type tarraydefoption is in unit symconst }
  2002. type
  2003. tpropopt=record
  2004. mask : tpropertyoption;
  2005. str : string[30];
  2006. end;
  2007. const
  2008. symopt : array[1..ord(high(tpropertyoption))] of tpropopt=(
  2009. (mask:ppo_indexed;str:'indexed'),
  2010. (mask:ppo_defaultproperty;str:'default'),
  2011. (mask:ppo_stored;str:'stored'),
  2012. (mask:ppo_hasparameters;str:'has parameters'),
  2013. (mask:ppo_implements;str:'implements'),
  2014. (mask:ppo_enumerator_current;str:'enumerator current'),
  2015. (mask:ppo_overrides;str:'overrides'),
  2016. (mask:ppo_dispid_write;str:'dispid write') { no longer used }
  2017. );
  2018. var
  2019. i : longint;
  2020. first : boolean;
  2021. begin
  2022. ppufile.getsmallset(result);
  2023. if result<>[] then
  2024. begin
  2025. first:=true;
  2026. for i:=1 to high(symopt) do
  2027. if (symopt[i].mask in result) then
  2028. begin
  2029. if first then
  2030. first:=false
  2031. else
  2032. write(', ');
  2033. write(symopt[i].str);
  2034. end;
  2035. end;
  2036. writeln;
  2037. end;
  2038. procedure readnodetree;
  2039. var
  2040. l : longint;
  2041. p : pointer;
  2042. begin
  2043. with ppufile do
  2044. begin
  2045. if space<>'' then
  2046. Writeln([space,'------ nodetree ------']);
  2047. if readentry=ibnodetree then
  2048. begin
  2049. l:=entrysize;
  2050. Writeln([space,'Tree size : ',l]);
  2051. { Read data to prevent error that entry is not completly read }
  2052. getmem(p,l);
  2053. getdata(p^,l);
  2054. freemem(p);
  2055. end
  2056. else
  2057. begin
  2058. WriteError('!! ibnodetree not found');
  2059. end;
  2060. end;
  2061. end;
  2062. procedure ReadCreatedObjTypes;
  2063. var
  2064. i,j,
  2065. len,
  2066. bssize: longint;
  2067. bs: pbyte;
  2068. begin
  2069. if ppufile.readentry<>ibcreatedobjtypes then
  2070. begin
  2071. WriteError('!! ibcreatedobjtypes entry not found');
  2072. ppufile.skipdata(ppufile.entrysize);
  2073. exit
  2074. end;
  2075. writeln;
  2076. writeln([space,'WPO info']);
  2077. writeln([space,'--------']);
  2078. len:=ppufile.getlongint;
  2079. writeln([space,'** Instantiated Object/Class types: ',len,' **']);
  2080. space:=space+' ';
  2081. for i:=0 to len-1 do
  2082. readderef(space);
  2083. setlength(space,length(space)-2);
  2084. len:=ppufile.getlongint;
  2085. writeln([space,'** Instantiated ClassRef types: ',len,' **']);
  2086. space:=space+' ';
  2087. for i:=0 to len-1 do
  2088. readderef(space);
  2089. setlength(space,length(space)-2);
  2090. len:=ppufile.getlongint;
  2091. writeln([space,'** Possibly instantiated ClassRef types : ',len,' **']);
  2092. space:=space+' ';
  2093. for i:=0 to len-1 do
  2094. readderef(space);
  2095. setlength(space,length(space)-2);
  2096. len:=ppufile.getlongint;
  2097. writeln([space,'** Class types with called virtual methods info : ',len,' **']);
  2098. space:=space+' ';
  2099. for i:=0 to len-1 do
  2100. begin
  2101. write([space,'Class def : ']);
  2102. readderef('');
  2103. write([space+' ','Called vmtentries : ']);
  2104. bssize:=ppufile.getlongint;
  2105. getmem(bs,bssize);
  2106. ppufile.readdata(bs^,bssize);
  2107. for j:=0 to bssize*8-1 do
  2108. if (((bs+j shr 3)^ shr (j and 7)) and 1) <> 0 then
  2109. write([j,', ']);
  2110. writeln;
  2111. freemem(bs);
  2112. end;
  2113. setlength(space,length(space)-2);
  2114. end;
  2115. {****************************************************************************
  2116. Read Symbols Part
  2117. ****************************************************************************}
  2118. procedure readsymbols(const s:string; ParentDef: TPpuContainerDef = nil);
  2119. function _finddef(symdef: TPpuDef): TPpuDef;
  2120. begin
  2121. Result:=nil;
  2122. if symdef.Ref.IsCurUnit then
  2123. begin;
  2124. Result:=CurUnit.FindById(symdef.Ref.Id);
  2125. if (Result <> nil) and (Result.Ref.Id = symdef.Id) then
  2126. begin
  2127. Result.Name:=symdef.Name;
  2128. Result.FilePos:=symdef.FilePos;
  2129. end
  2130. else
  2131. Result:=nil;
  2132. end;
  2133. end;
  2134. type
  2135. pguid = ^tguid;
  2136. tguid = packed record
  2137. D1: LongWord;
  2138. D2: Word;
  2139. D3: Word;
  2140. D4: array[0..7] of Byte;
  2141. end;
  2142. var
  2143. b : byte;
  2144. pc : pchar;
  2145. ch : dword;
  2146. startnewline : boolean;
  2147. i,j,len : longint;
  2148. prettyname, ss : ansistring;
  2149. ws: widestring;
  2150. guid : tguid;
  2151. realvalue : ppureal;
  2152. doublevalue : double;
  2153. singlevalue : single;
  2154. extended : TSplit80bitReal;
  2155. tempbuf : array[0..127] of char;
  2156. pw : pcompilerwidestring;
  2157. varoptions : tvaroptions;
  2158. propoptions : tpropertyoptions;
  2159. iexp: Tconstexprint;
  2160. def: TPpuDef;
  2161. constdef: TPpuConstDef absolute def;
  2162. begin
  2163. with ppufile do
  2164. begin
  2165. if space<>'' then
  2166. Writeln([space,'------ ',s,' ------']);
  2167. if readentry=ibstartsyms then
  2168. begin
  2169. Writeln([space,'Symtable datasize : ',getlongint]);
  2170. Writeln([space,'Symtable alignment: ',getlongint]);
  2171. end
  2172. else
  2173. Writeln('!! ibstartsym not found');
  2174. repeat
  2175. def:=nil;
  2176. b:=readentry;
  2177. case b of
  2178. ibunitsym :
  2179. readcommonsym('Unit symbol ');
  2180. ibnamespacesym :
  2181. begin
  2182. readcommonsym('NameSpace symbol ');
  2183. write([space,' Hidden Unit : ']);
  2184. readderef('');
  2185. end;
  2186. iblabelsym :
  2187. readcommonsym('Label symbol ');
  2188. ibtypesym :
  2189. begin
  2190. def:=TPpuTypeRef.Create(nil);
  2191. readcommonsym('Type symbol ',def);
  2192. write([space,' Result Type : ']);
  2193. readderef('', def.Ref);
  2194. if _finddef(def) = nil then
  2195. def.Parent:=ParentDef;
  2196. prettyname:=getansistring;
  2197. if prettyname<>'' then
  2198. begin
  2199. write([space,' Pretty Name : ']);
  2200. Writeln(prettyname);
  2201. end;
  2202. end;
  2203. ibprocsym :
  2204. begin
  2205. def:=TPpuDef.Create(nil);
  2206. readcommonsym('Procedure symbol ', def);
  2207. len:=ppufile.getword;
  2208. for i:=1 to len do
  2209. begin
  2210. write([space,' Definition : ']);
  2211. readderef('', def.Ref);
  2212. _finddef(def);
  2213. end;
  2214. end;
  2215. ibconstsym :
  2216. begin
  2217. constdef:=TPpuConstDef.Create(ParentDef);
  2218. readcommonsym('Constant symbol ',constdef);
  2219. b:=getbyte;
  2220. case tconsttyp(b) of
  2221. constord :
  2222. begin
  2223. write ([space,' OrdinalType : ']);
  2224. readderef('',constdef.TypeRef);
  2225. iexp:=getexprint;
  2226. constdef.ConstType:=ctInt;
  2227. constdef.VInt:=iexp.svalue;
  2228. writeln([space,' Value : ',constexp.tostr(iexp)]);
  2229. end;
  2230. constpointer :
  2231. begin
  2232. write ([space,' PointerType : ']);
  2233. readderef('',constdef.TypeRef);
  2234. constdef.ConstType:=ctInt;
  2235. constdef.VInt:=getaint;
  2236. writeln([space,' Value : ',constdef.VInt])
  2237. end;
  2238. conststring,
  2239. constresourcestring :
  2240. begin
  2241. len:=getlongint;
  2242. getmem(pc,len+1);
  2243. getdata(pc^,len);
  2244. (pc+len)^:= #0;
  2245. writeln([space,' Length : ',len]);
  2246. writeln([space,' Value : "',pc,'"']);
  2247. constdef.ConstType:=ctStr;
  2248. SetString(constdef.VStr, pc, len);
  2249. constdef.VStr:=UTF8Encode(constdef.VStr);
  2250. freemem(pc,len+1);
  2251. end;
  2252. constreal :
  2253. begin
  2254. constdef.ConstType:=ctFloat;
  2255. write ([space,' RealType : ']);
  2256. readderef('',constdef.TypeRef);
  2257. write([space,' Value : ']);
  2258. if entryleft=sizeof(ppureal) then
  2259. begin
  2260. realvalue:=getrealsize(sizeof(ppureal));
  2261. constdef.VFloat:=realvalue;
  2262. writeln([realvalue]);
  2263. end
  2264. else if entryleft=sizeof(double) then
  2265. begin
  2266. doublevalue:=getrealsize(sizeof(double));
  2267. constdef.VFloat:=doublevalue;
  2268. writeln([doublevalue]);
  2269. end
  2270. else if entryleft=sizeof(single) then
  2271. begin
  2272. singlevalue:=getrealsize(sizeof(single));
  2273. constdef.VFloat:=singlevalue;
  2274. writeln([singlevalue]);
  2275. end
  2276. else if entryleft=10 then
  2277. begin
  2278. getdata(extended,entryleft);
  2279. ss:=Real80bitToStr(extended);
  2280. constdef.VFloat:=StrToFloat(ss);
  2281. writeln(ss);
  2282. end
  2283. else
  2284. begin
  2285. realvalue:=0.0;
  2286. WriteError('Error reading real value');
  2287. end;
  2288. end;
  2289. constset :
  2290. begin
  2291. constdef.ConstType:=ctSet;
  2292. write ([space,' Set Type : ']);
  2293. readderef('',constdef.TypeRef);
  2294. for i:=1to 4 do
  2295. begin
  2296. write ([space,' Value : ']);
  2297. for j:=1to 8 do
  2298. begin
  2299. if j>1 then
  2300. write(',');
  2301. b:=getbyte;
  2302. write(hexstr(b,2));
  2303. constdef.VSet[i*j-1]:=b;
  2304. end;
  2305. writeln;
  2306. end;
  2307. end;
  2308. constnil:
  2309. begin
  2310. writeln([space,' NIL pointer.']);
  2311. constdef.ConstType:=ctPtr;
  2312. constdef.VInt:=0;
  2313. end;
  2314. constwstring :
  2315. begin
  2316. initwidestring(pw);
  2317. setlengthwidestring(pw,getlongint);
  2318. if widecharsize=2 then
  2319. { don't use getdata, because the compilerwidechars may have to
  2320. be byteswapped
  2321. }
  2322. begin
  2323. for i:=0 to pw^.len-1 do
  2324. pw^.data[i]:=ppufile.getword;
  2325. SetString(ws, PWideChar(pw^.data), pw^.len);
  2326. constdef.VStr:=UTF8Encode(ws);
  2327. constdef.ConstType:=ctStr;
  2328. end
  2329. else if widecharsize=4 then
  2330. begin
  2331. for i:=0 to pw^.len-1 do
  2332. pw^.data[i]:=cardinal(ppufile.getlongint);
  2333. end
  2334. else
  2335. begin
  2336. WriteError('Unsupported tcompilerwidechar size');
  2337. end;
  2338. Write([space,'Wide string type']);
  2339. startnewline:=true;
  2340. for i:=0 to pw^.len-1 do
  2341. begin
  2342. if startnewline then
  2343. begin
  2344. writeln;
  2345. write(space);
  2346. startnewline:=false;
  2347. end;
  2348. ch:=pw^.data[i];
  2349. if widecharsize=2 then
  2350. write(hexstr(ch,4))
  2351. else
  2352. write(hexstr(ch,8));
  2353. if ((i + 1) mod 8)= 0 then
  2354. startnewline:=true
  2355. else
  2356. if i <> pw^.len-1 then
  2357. write(', ');
  2358. end;
  2359. donewidestring(pw);
  2360. Writeln;
  2361. end;
  2362. constguid:
  2363. begin
  2364. getdata(guid,sizeof(guid));
  2365. write ([space,' IID String: {',hexstr(guid.d1,8),'-',hexstr(guid.d2,4),'-',hexstr(guid.d3,4),'-']);
  2366. for i:=0 to 7 do
  2367. begin
  2368. write(hexstr(guid.d4[i],2));
  2369. if i=1 then write('-');
  2370. end;
  2371. writeln('}');
  2372. end
  2373. else
  2374. Writeln (['!! Invalid unit format : Invalid const type encountered: ',b]);
  2375. end;
  2376. end;
  2377. ibabsolutevarsym :
  2378. begin
  2379. def:=TPpuVarDef.Create(ParentDef);
  2380. readabstractvarsym('Absolute variable symbol ',varoptions,TPpuVarDef(def));
  2381. Write ([space,' Relocated to ']);
  2382. b:=getbyte;
  2383. case absolutetyp(b) of
  2384. tovar :
  2385. readpropaccesslist(space+' Sym : ');
  2386. toasm :
  2387. Writeln(['Assembler name : ',getstring]);
  2388. toaddr :
  2389. begin
  2390. Write(['Address : ',getaword]);
  2391. if tsystemcpu(ppufile.header.cpu)=cpu_i386 then
  2392. Write([' (Far: ',getbyte<>0,')']);
  2393. if tsystemcpu(ppufile.header.cpu)=cpu_i8086 then
  2394. if getbyte<>0 then
  2395. Write([' (Far: TRUE, Segment=',getaword,')'])
  2396. else
  2397. Write([' (Far: FALSE)']);
  2398. Writeln;
  2399. end;
  2400. else
  2401. Writeln (['!! Invalid unit format : Invalid absolute type encountered: ',b]);
  2402. end;
  2403. end;
  2404. ibfieldvarsym :
  2405. begin
  2406. def:=TPpuFieldDef.Create(ParentDef);
  2407. readabstractvarsym('Field Variable symbol ',varoptions,TPpuVarDef(def));
  2408. writeln([space,' Address : ',getaint]);
  2409. end;
  2410. ibstaticvarsym :
  2411. begin
  2412. def:=TPpuVarDef.Create(ParentDef);
  2413. readabstractvarsym('Global Variable symbol ',varoptions,TPpuVarDef(def));
  2414. write ([space,' DefaultConst : ']);
  2415. readderef('');
  2416. if (vo_has_mangledname in varoptions) then
  2417. {$ifdef symansistr}
  2418. writeln([space,' Mangledname : ',getansistring]);
  2419. {$else symansistr}
  2420. writeln([space,' Mangledname : ',getstring]);
  2421. {$endif symansistr}
  2422. if vo_has_section in varoptions then
  2423. writeln(['Section name:',ppufile.getansistring]);
  2424. write ([space,' FieldVarSymDeref: ']);
  2425. readderef('');
  2426. end;
  2427. iblocalvarsym :
  2428. begin
  2429. readabstractvarsym('Local Variable symbol ',varoptions);
  2430. write ([space,' DefaultConst : ']);
  2431. readderef('');
  2432. end;
  2433. ibparavarsym :
  2434. begin
  2435. def:=TPpuParamDef.Create(ParentDef);
  2436. readabstractvarsym('Parameter Variable symbol ',varoptions,TPpuVarDef(def));
  2437. write ([space,' DefaultConst : ']);
  2438. readderef('',TPpuParamDef(def).DefaultValue);
  2439. writeln([space,' ParaNr : ',getword]);
  2440. writeln([space,' Univ : ',boolean(getbyte)]);
  2441. writeln([space,' VarState : ',getbyte]);
  2442. writeln([space,' Refs : ',getbyte]);
  2443. if (vo_has_explicit_paraloc in varoptions) then
  2444. begin
  2445. i:=getbyte;
  2446. getdata(tempbuf,i);
  2447. end;
  2448. end;
  2449. ibenumsym :
  2450. begin
  2451. def:=TPpuConstDef.Create(nil);
  2452. readcommonsym('Enumeration symbol ',def);
  2453. write ([space,' Definition : ']);
  2454. readderef('');
  2455. TPpuConstDef(def).ConstType:=ctInt;
  2456. TPpuConstDef(def).VInt:=getlongint;
  2457. writeln([space,' Value : ',TPpuConstDef(def).VInt]);
  2458. if (ParentDef <> nil) and (ParentDef.DefType = dtEnum) then
  2459. def.Parent:=ParentDef;
  2460. end;
  2461. ibsyssym :
  2462. begin
  2463. readcommonsym('Internal system symbol ');
  2464. writeln([space,' Internal Nr : ',getlongint]);
  2465. end;
  2466. ibmacrosym :
  2467. begin
  2468. readcommonsym('Macro symbol ');
  2469. writeln([space,' Defined: ',boolean(getbyte)]);
  2470. writeln([space,' Compiler var: ',boolean(getbyte)]);
  2471. len:=getlongint;
  2472. writeln([space,' Value length: ',len]);
  2473. if len > 0 then
  2474. begin
  2475. getmem(pc,len+1);
  2476. getdata(pc^,len);
  2477. (pc+len)^:= #0;
  2478. writeln([space,' Value: "',pc,'"']);
  2479. freemem(pc,len+1);
  2480. end;
  2481. end;
  2482. ibpropertysym :
  2483. begin
  2484. def:=TPpuPropDef.Create(ParentDef);
  2485. readcommonsym('Property ',def);
  2486. propoptions:=readpropertyoptions;
  2487. if ppo_overrides in propoptions then
  2488. begin
  2489. write ([space,' OverrideProp : ']);
  2490. readderef('');
  2491. end;
  2492. if ppo_defaultproperty in propoptions then
  2493. Include(TPpuPropDef(def).Options, poDefault);
  2494. write ([space,' Prop Type : ']);
  2495. readderef('',TPpuPropDef(def).PropType);
  2496. writeln([space,' Index : ',getlongint]);
  2497. writeln([space,' Default : ',getlongint]);
  2498. write ([space,' Index Type : ']);
  2499. readderef('');
  2500. { palt_none }
  2501. readpropaccesslist('');
  2502. write ([space,' Readaccess : ']);
  2503. readpropaccesslist(space+' Sym: ',TPpuPropDef(def).Getter);
  2504. write ([space,' Writeaccess : ']);
  2505. readpropaccesslist(space+' Sym: ',TPpuPropDef(def).Setter);
  2506. write ([space,' Storedaccess : ']);
  2507. readpropaccesslist(space+' Sym: ');
  2508. if [ppo_hasparameters,ppo_overrides]*propoptions=[ppo_hasparameters] then
  2509. begin
  2510. space:=' '+space;
  2511. readsymtable('parast',TPpuPropDef(def));
  2512. delete(space,1,4);
  2513. end;
  2514. end;
  2515. iberror :
  2516. begin
  2517. WriteError('!! Error in PPU');
  2518. exit;
  2519. end;
  2520. ibendsyms :
  2521. break;
  2522. else
  2523. begin
  2524. WriteError('!! Skipping unsupported PPU Entry in Symbols: '+IntToStr(b));
  2525. end;
  2526. end;
  2527. if (def <> nil) and (def.Parent = nil) then
  2528. def.Free;
  2529. if not EndOfEntry then
  2530. HasMoreInfos;
  2531. until false;
  2532. end;
  2533. end;
  2534. {****************************************************************************
  2535. Read defintions Part
  2536. ****************************************************************************}
  2537. procedure readdefinitions(const s:string; ParentDef: TPpuContainerDef);
  2538. { type tordtype is in symconst unit }
  2539. {
  2540. uvoid,
  2541. u8bit,u16bit,u32bit,u64bit,
  2542. s8bit,s16bit,s32bit,s64bit,
  2543. bool8bit,bool16bit,bool32bit,bool64bit,
  2544. uchar,uwidechar,scurrency
  2545. ); }
  2546. { type tobjecttyp is in symconst unit }
  2547. { type tvarianttype is in symconst unit }
  2548. var
  2549. b : byte;
  2550. l,j : longint;
  2551. calloption : tproccalloption;
  2552. procoptions : tprocoptions;
  2553. implprocoptions: timplprocoptions;
  2554. defoptions: tdefoptions;
  2555. iexpr: Tconstexprint;
  2556. def: TPpuDef;
  2557. objdef: TPpuObjectDef absolute def;
  2558. arrdef: TPpuArrayDef absolute def;
  2559. enumdef: TPpuEnumDef absolute def;
  2560. setdef: TPpuSetDef absolute def;
  2561. orddef: TPpuOrdDef absolute def;
  2562. floatdef: TPpuFloatDef absolute def;
  2563. strdef: TPpuStringDef absolute def;
  2564. filedef: TPpuFileDef absolute def;
  2565. begin
  2566. with ppufile do
  2567. begin
  2568. if space<>'' then
  2569. Writeln([space,'------ ',s,' ------']);
  2570. if readentry<>ibstartdefs then
  2571. Writeln('!! ibstartdefs not found');
  2572. repeat
  2573. def:=nil;
  2574. b:=readentry;
  2575. case b of
  2576. ibpointerdef :
  2577. begin
  2578. def:=TPpuPointerDef.Create(ParentDef);
  2579. readcommondef('Pointer definition',defoptions,def);
  2580. write ([space,' Pointed Type : ']);
  2581. readderef('',TPpuPointerDef(def).Ptr);
  2582. writeln([space,' Has Pointer Math : ',(getbyte<>0)]);
  2583. if tsystemcpu(ppufile.header.cpu) in [cpu_i8086,cpu_i386,cpu_x86_64] then
  2584. begin
  2585. write([space,' X86 Pointer Type : ']);
  2586. b:=getbyte;
  2587. case tx86pointertyp(b) of
  2588. x86pt_near: writeln('Near');
  2589. x86pt_near_cs: writeln('Near ''CS''');
  2590. x86pt_near_ds: writeln('Near ''DS''');
  2591. x86pt_near_ss: writeln('Near ''SS''');
  2592. x86pt_near_es: writeln('Near ''ES''');
  2593. x86pt_near_fs: writeln('Near ''FS''');
  2594. x86pt_near_gs: writeln('Near ''GS''');
  2595. x86pt_far: writeln('Far');
  2596. x86pt_huge: writeln('Huge');
  2597. else
  2598. WriteWarning('Invalid x86 pointer type: ' + IntToStr(b));
  2599. end;
  2600. end;
  2601. end;
  2602. iborddef :
  2603. begin
  2604. orddef:=TPpuOrdDef.Create(ParentDef);
  2605. readcommondef('Ordinal definition',defoptions,orddef);
  2606. write ([space,' Base type : ']);
  2607. b:=getbyte;
  2608. case tordtype(b) of
  2609. uvoid:
  2610. begin
  2611. writeln('uvoid');
  2612. orddef.OrdType:=otVoid;
  2613. end;
  2614. u8bit:
  2615. begin
  2616. writeln('u8bit');
  2617. orddef.OrdType:=otUInt;
  2618. orddef.Size:=1;
  2619. end;
  2620. u16bit:
  2621. begin
  2622. writeln('u16bit');
  2623. orddef.OrdType:=otUInt;
  2624. orddef.Size:=2;
  2625. end;
  2626. u32bit:
  2627. begin
  2628. writeln('u32bit');
  2629. orddef.OrdType:=otUInt;
  2630. orddef.Size:=4;
  2631. end;
  2632. u64bit:
  2633. begin
  2634. writeln('u64bit');
  2635. orddef.OrdType:=otUInt;
  2636. orddef.Size:=8;
  2637. end;
  2638. s8bit:
  2639. begin
  2640. writeln('s8bit');
  2641. orddef.OrdType:=otSInt;
  2642. orddef.Size:=1;
  2643. end;
  2644. s16bit:
  2645. begin
  2646. writeln('s16bit');
  2647. orddef.OrdType:=otSInt;
  2648. orddef.Size:=2;
  2649. end;
  2650. s32bit:
  2651. begin
  2652. writeln('s32bit');
  2653. orddef.OrdType:=otSInt;
  2654. orddef.Size:=4;
  2655. end;
  2656. s64bit:
  2657. begin
  2658. writeln('s64bit');
  2659. orddef.OrdType:=otSInt;
  2660. orddef.Size:=8;
  2661. end;
  2662. pasbool8:
  2663. begin
  2664. writeln('pasbool8');
  2665. orddef.OrdType:=otPasBool;
  2666. orddef.Size:=1;
  2667. end;
  2668. pasbool16:
  2669. begin
  2670. writeln('pasbool16');
  2671. orddef.OrdType:=otPasBool;
  2672. orddef.Size:=2;
  2673. end;
  2674. pasbool32:
  2675. begin
  2676. writeln('pasbool32');
  2677. orddef.OrdType:=otPasBool;
  2678. orddef.Size:=4;
  2679. end;
  2680. pasbool64:
  2681. begin
  2682. writeln('pasbool64');
  2683. orddef.OrdType:=otPasBool;
  2684. orddef.Size:=8;
  2685. end;
  2686. bool8bit:
  2687. begin
  2688. writeln('bool8bit');
  2689. orddef.OrdType:=otBool;
  2690. orddef.Size:=1;
  2691. end;
  2692. bool16bit:
  2693. begin
  2694. writeln('bool16bit');
  2695. orddef.OrdType:=otBool;
  2696. orddef.Size:=2;
  2697. end;
  2698. bool32bit:
  2699. begin
  2700. writeln('bool32bit');
  2701. orddef.OrdType:=otBool;
  2702. orddef.Size:=4;
  2703. end;
  2704. bool64bit:
  2705. begin
  2706. writeln('bool64bit');
  2707. orddef.OrdType:=otBool;
  2708. orddef.Size:=8;
  2709. end;
  2710. uchar:
  2711. begin
  2712. writeln('uchar');
  2713. orddef.OrdType:=otChar;
  2714. orddef.Size:=1;
  2715. end;
  2716. uwidechar:
  2717. begin
  2718. writeln('uwidechar');
  2719. orddef.OrdType:=otChar;
  2720. orddef.Size:=2;
  2721. end;
  2722. scurrency:
  2723. begin
  2724. writeln('scurrency');
  2725. orddef.OrdType:=otCurrency;
  2726. orddef.Size:=8;
  2727. end;
  2728. else
  2729. WriteWarning('Invalid base type: ' + IntToStr(b));
  2730. end;
  2731. iexpr:=getexprint;
  2732. orddef.RangeLow:=iexpr.svalue;
  2733. write([space,' Range : ',constexp.tostr(iexpr)]);
  2734. iexpr:=getexprint;
  2735. orddef.RangeHigh:=iexpr.svalue;
  2736. writeln([' to ',constexp.tostr(iexpr)]);
  2737. end;
  2738. ibfloatdef :
  2739. begin
  2740. floatdef:=TPpuFloatDef.Create(ParentDef);
  2741. readcommondef('Float definition',defoptions,floatdef);
  2742. write ([space,' Float type : ']);
  2743. b:=getbyte;
  2744. case b of
  2745. ftSingle:
  2746. begin
  2747. writeln('Single');
  2748. floatdef.FloatType:=pftSingle;
  2749. end;
  2750. ftDouble:
  2751. begin
  2752. writeln('Double');
  2753. floatdef.FloatType:=pftDouble;
  2754. end;
  2755. ftExtended:
  2756. begin
  2757. writeln('Extended');
  2758. floatdef.FloatType:=pftExtended;
  2759. end;
  2760. ftComp:
  2761. begin
  2762. writeln('Comp');
  2763. floatdef.FloatType:=pftComp;
  2764. end;
  2765. ftCurr:
  2766. begin
  2767. writeln('Currency');
  2768. floatdef.FloatType:=pftCurrency;
  2769. end;
  2770. ftFloat128:
  2771. begin
  2772. writeln('Float128');
  2773. floatdef.FloatType:=pftFloat128;
  2774. end;
  2775. else
  2776. WriteWarning('Invalid float type: ' + IntToStr(b));
  2777. end;
  2778. end;
  2779. ibarraydef :
  2780. begin
  2781. arrdef:=TPpuArrayDef.Create(ParentDef);
  2782. readcommondef('Array definition',defoptions,arrdef);
  2783. write ([space,' Element type : ']);
  2784. readderef('',arrdef.ElType);
  2785. write ([space,' Range Type : ']);
  2786. readderef('',arrdef.RangeType);
  2787. arrdef.RangeLow:=getasizeint;
  2788. arrdef.RangeHigh:=getasizeint;
  2789. writeln([space,' Range : ',arrdef.RangeLow,' to ',arrdef.RangeHigh]);
  2790. write ([space,' Options : ']);
  2791. readarraydefoptions(arrdef);
  2792. if tsystemcpu(ppufile.header.cpu)=cpu_i8086 then
  2793. writeln([space,' Huge : ',(getbyte<>0)]);
  2794. readsymtable('symbols', arrdef);
  2795. end;
  2796. ibprocdef :
  2797. begin
  2798. def:=TPpuProcDef.Create(ParentDef);
  2799. readcommondef('Procedure definition',defoptions,def);
  2800. read_abstract_proc_def(calloption,procoptions,TPpuProcDef(def));
  2801. if (po_has_mangledname in procoptions) then
  2802. {$ifdef symansistr}
  2803. writeln([space,' Mangled name : ',getansistring]);
  2804. {$else symansistr}
  2805. writeln([space,' Mangled name : ',getstring]);
  2806. {$endif symansistr}
  2807. writeln([space,' Number : ',getword]);
  2808. writeln([space,' Level : ',getbyte]);
  2809. write ([space,' Class : ']);
  2810. readderef('');
  2811. write ([space,' Procsym : ']);
  2812. readderef('', def.Ref);
  2813. write ([space,' File Pos : ']);
  2814. readposinfo(def);
  2815. write ([space,' Visibility : ']);
  2816. readvisibility(def);
  2817. write ([space,' SymOptions : ']);
  2818. readsymoptions(space+' ');
  2819. writeln ([space,' Synthetic kind : ',Synthetic2Str(ppufile.getbyte)]);
  2820. if tsystemcpu(ppufile.header.cpu)=cpu_powerpc then
  2821. begin
  2822. { library symbol for AmigaOS/MorphOS }
  2823. write ([space,' Library symbol : ']);
  2824. readderef('');
  2825. end;
  2826. if (po_has_importdll in procoptions) then
  2827. writeln([space,' Import DLL : ',getstring]);
  2828. if (po_has_importname in procoptions) then
  2829. writeln([space,' Import Name : ',getstring]);
  2830. writeln([space,' Import Nr : ',getword]);
  2831. if (po_msgint in procoptions) then
  2832. writeln([space,' MsgInt : ',getlongint]);
  2833. if (po_msgstr in procoptions) then
  2834. writeln([space,' MsgStr : ',getstring]);
  2835. if (po_dispid in procoptions) then
  2836. writeln([space,' DispID: ',ppufile.getlongint]);
  2837. readprocimploptions(space,implprocoptions);
  2838. if (pio_has_inlininginfo in implprocoptions) then
  2839. begin
  2840. write ([space,' FuncretSym : ']);
  2841. readderef('');
  2842. readprocinfooptions(space);
  2843. end;
  2844. b:=ppufile.getbyte;
  2845. if b<>0 then
  2846. begin
  2847. write ([space,' Alias names : ']);
  2848. for j:=1 to b do
  2849. begin
  2850. write(ppufile.getstring);
  2851. if j<b then
  2852. write(', ');
  2853. end;
  2854. writeln;
  2855. end;
  2856. if not EndOfEntry then
  2857. HasMoreInfos;
  2858. space:=' '+space;
  2859. { parast }
  2860. readsymtable('parast', TPpuProcDef(def));
  2861. { localst }
  2862. if (pio_has_inlininginfo in implprocoptions) then
  2863. readsymtable('localst');
  2864. if (pio_has_inlininginfo in implprocoptions) then
  2865. readnodetree;
  2866. delete(space,1,4);
  2867. end;
  2868. ibprocvardef :
  2869. begin
  2870. def:=TPpuProcTypeDef.Create(ParentDef);
  2871. readcommondef('Procedural type (ProcVar) definition',defoptions,def);
  2872. read_abstract_proc_def(calloption,procoptions, TPpuProcDef(def));
  2873. writeln([space,' Symtable level :',ppufile.getbyte]);
  2874. if not EndOfEntry then
  2875. HasMoreInfos;
  2876. space:=' '+space;
  2877. { parast }
  2878. readsymtable('parast',TPpuProcDef(def));
  2879. delete(space,1,4);
  2880. end;
  2881. ibshortstringdef :
  2882. begin
  2883. strdef:=TPpuStringDef.Create(ParentDef);
  2884. strdef.StrType:=stShort;
  2885. readcommondef('ShortString definition',defoptions,strdef);
  2886. strdef.Len:=getbyte;
  2887. writeln([space,' Length : ',strdef.Len]);
  2888. end;
  2889. ibwidestringdef :
  2890. begin
  2891. strdef:=TPpuStringDef.Create(ParentDef);
  2892. strdef.StrType:=stWide;
  2893. readcommondef('WideString definition',defoptions,strdef);
  2894. strdef.Len:=getaint;
  2895. writeln([space,' Length : ',strdef.Len]);
  2896. end;
  2897. ibunicodestringdef :
  2898. begin
  2899. strdef:=TPpuStringDef.Create(ParentDef);
  2900. strdef.StrType:=stUnicode;
  2901. readcommondef('UnicodeString definition',defoptions,strdef);
  2902. strdef.Len:=getaint;
  2903. writeln([space,' Length : ',strdef.Len]);
  2904. writeln([space,' Encoding : ',getword]);
  2905. end;
  2906. ibansistringdef :
  2907. begin
  2908. strdef:=TPpuStringDef.Create(ParentDef);
  2909. strdef.StrType:=stAnsi;
  2910. readcommondef('AnsiString definition',defoptions,strdef);
  2911. strdef.Len:=getaint;
  2912. writeln([space,' Length : ',strdef.Len]);
  2913. writeln([space,' Encoding : ',getword]);
  2914. end;
  2915. iblongstringdef :
  2916. begin
  2917. strdef:=TPpuStringDef.Create(ParentDef);
  2918. strdef.StrType:=stLong;
  2919. readcommondef('Longstring definition',defoptions,strdef);
  2920. strdef.Len:=getaint;
  2921. writeln([space,' Length : ',strdef.Len]);
  2922. end;
  2923. ibrecorddef :
  2924. begin
  2925. objdef:=TPpuRecordDef.Create(ParentDef);
  2926. readcommondef('Record definition',defoptions, objdef);
  2927. def.Name:=getstring;
  2928. writeln([space,' Name of Record : ',objdef.Name]);
  2929. writeln([space,' Import lib/pkg : ',getstring]);
  2930. write ([space,' Options : ']);
  2931. readobjectdefoptions(objdef);
  2932. if (df_copied_def in defoptions) then
  2933. begin
  2934. Include(TPpuRecordDef(def).Options, ooCopied);
  2935. write([space,' Copied from : ']);
  2936. readderef('',objdef.Ancestor);
  2937. end
  2938. else
  2939. begin
  2940. writeln([space,' FieldAlign : ',shortint(getbyte)]);
  2941. writeln([space,' RecordAlign : ',shortint(getbyte)]);
  2942. writeln([space,' PadAlign : ',shortint(getbyte)]);
  2943. writeln([space,'UseFieldAlignment : ',shortint(getbyte)]);
  2944. objdef.Size:=getasizeint;
  2945. writeln([space,' DataSize : ',objdef.Size]);
  2946. writeln([space,' PaddingSize : ',getword]);
  2947. end;
  2948. if not EndOfEntry then
  2949. HasMoreInfos;
  2950. {read the record definitions and symbols}
  2951. if not(df_copied_def in current_defoptions) then
  2952. begin
  2953. space:=' '+space;
  2954. readrecsymtableoptions;
  2955. readsymtable('fields',TPpuRecordDef(def));
  2956. Delete(space,1,4);
  2957. end;
  2958. end;
  2959. ibobjectdef :
  2960. begin
  2961. objdef:=TPpuObjectDef.Create(ParentDef);
  2962. readcommondef('Object/Class definition',defoptions,objdef);
  2963. objdef.Name:=getstring;
  2964. writeln([space,' Name of Class : ',objdef.Name]);
  2965. writeln([space,' Import lib/pkg : ',getstring]);
  2966. write ([space,' Options : ']);
  2967. readobjectdefoptions(objdef);
  2968. b:=getbyte;
  2969. write ([space,' Type : ']);
  2970. case tobjecttyp(b) of
  2971. odt_class : writeln('class');
  2972. odt_object : writeln('object');
  2973. odt_interfacecom : writeln('interfacecom');
  2974. odt_interfacecorba : writeln('interfacecorba');
  2975. odt_cppclass : writeln('cppclass');
  2976. odt_dispinterface : writeln('dispinterface');
  2977. odt_objcclass : writeln('objcclass');
  2978. odt_objcprotocol : writeln('objcprotocol');
  2979. odt_helper : writeln('helper');
  2980. odt_objccategory : writeln('objccategory');
  2981. odt_javaclass : writeln('Java class');
  2982. odt_interfacejava : writeln('Java interface');
  2983. else WriteWarning('Invalid object type: ' + IntToStr(b));
  2984. end;
  2985. case tobjecttyp(b) of
  2986. odt_class, odt_cppclass, odt_objcclass, odt_javaclass:
  2987. objdef.ObjType:=otClass;
  2988. odt_object:
  2989. objdef.ObjType:=otObject;
  2990. odt_interfacecom, odt_interfacecorba, odt_interfacejava, odt_dispinterface:
  2991. objdef.ObjType:=otInterface;
  2992. odt_helper:
  2993. objdef.ObjType:=otHelper;
  2994. end;
  2995. writeln([space,' External name : ',getstring]);
  2996. objdef.Size:=getasizeint;
  2997. writeln([space,' DataSize : ',objdef.Size]);
  2998. writeln([space,' PaddingSize : ',getword]);
  2999. writeln([space,' FieldAlign : ',shortint(getbyte)]);
  3000. writeln([space,' RecordAlign : ',shortint(getbyte)]);
  3001. writeln([space,' Vmt offset : ',getlongint]);
  3002. write ([space, ' Ancestor Class : ']);
  3003. readderef('',objdef.Ancestor);
  3004. if tobjecttyp(b) in [odt_interfacecom,odt_interfacecorba,odt_dispinterface] then
  3005. begin
  3006. { IIDGUID }
  3007. for j:=1to 16 do
  3008. getbyte;
  3009. objdef.IID:=getstring;
  3010. writeln([space,' IID String : ',objdef.IID]);
  3011. end;
  3012. writeln([space,' Abstract methods : ',getlongint]);
  3013. if (tobjecttyp(b)=odt_helper) or
  3014. (oo_is_classhelper in current_objectoptions) then
  3015. begin
  3016. write([space,' Helper parent : ']);
  3017. readderef('',objdef.HelperParent);
  3018. end;
  3019. l:=getlongint;
  3020. writeln([space,' VMT entries: ',l]);
  3021. for j:=1 to l do
  3022. begin
  3023. write([space,' ']);
  3024. readderef('');
  3025. write([space,' Visibility: ']);
  3026. readvisibility;
  3027. end;
  3028. if tobjecttyp(b) in [odt_class,odt_objcclass,odt_objcprotocol,odt_javaclass,odt_interfacejava] then
  3029. begin
  3030. l:=getlongint;
  3031. writeln([space,' Impl Intf Count : ',l]);
  3032. for j:=1 to l do
  3033. begin
  3034. write ([space,' - Definition : ']);
  3035. readderef('');
  3036. write ([space,' - Getter Def : ']);
  3037. readderef('');
  3038. writeln([space,' IOffset : ',getlongint]);
  3039. writeln([space,' Entry type : ',IntfEntryType2Str(getbyte)]);
  3040. end;
  3041. end;
  3042. if df_copied_def in current_defoptions then
  3043. begin
  3044. Include(objdef.Options, ooCopied);
  3045. writeln(' Copy of def: ');
  3046. readderef('',objdef.Ancestor);
  3047. end;
  3048. if not EndOfEntry then
  3049. HasMoreInfos;
  3050. if not(df_copied_def in current_defoptions) then
  3051. begin
  3052. {read the record definitions and symbols}
  3053. space:=' '+space;
  3054. readrecsymtableoptions;
  3055. readsymtable('fields',objdef);
  3056. Delete(space,1,4);
  3057. end;
  3058. end;
  3059. ibfiledef :
  3060. begin
  3061. filedef:=TPpuFileDef.Create(ParentDef);
  3062. ReadCommonDef('File definition',defoptions,filedef);
  3063. write ([space,' Type : ']);
  3064. case getbyte of
  3065. 0 : begin
  3066. writeln('Text');
  3067. filedef.FileType:=ftText;
  3068. end;
  3069. 1 : begin
  3070. writeln('Typed');
  3071. filedef.FileType:=ftTyped;
  3072. write ([space,' File of Type : ']);
  3073. readderef('',filedef.TypeRef);
  3074. end;
  3075. 2 : begin
  3076. writeln('Untyped');
  3077. filedef.FileType:=ftUntyped;
  3078. end;
  3079. end;
  3080. end;
  3081. ibformaldef :
  3082. begin
  3083. def:=TPpuFormalDef.Create(ParentDef);
  3084. readcommondef('Generic definition (void-typ)',defoptions,def);
  3085. TPpuFormalDef(def).IsTyped:=(getbyte<>0);
  3086. writeln([space,' Is Typed : ',TPpuFormalDef(def).IsTyped]);
  3087. end;
  3088. ibundefineddef :
  3089. begin
  3090. def:=TPpuUndefinedDef.Create(ParentDef);
  3091. readcommondef('Undefined definition (generic parameter)',defoptions,def);
  3092. end;
  3093. ibenumdef :
  3094. begin
  3095. enumdef:=TPpuEnumDef.Create(ParentDef);
  3096. readcommondef('Enumeration type definition',defoptions,enumdef);
  3097. enumdef.ElLow:=getaint;
  3098. writeln([space,' Smallest element : ',enumdef.ElLow]);
  3099. enumdef.ElHigh:=getaint;
  3100. writeln([space,' Largest element : ',enumdef.ElHigh]);
  3101. enumdef.Size:=byte(getaint);
  3102. writeln([space,' Size : ',enumdef.Size]);
  3103. {$ifdef jvm}
  3104. write([space,' Class def : ']);
  3105. readderef('');
  3106. {$endif}
  3107. if df_copied_def in defoptions then
  3108. begin
  3109. write([space,'Base enumeration type : ']);
  3110. readderef('',enumdef.CopyFrom);
  3111. end
  3112. else
  3113. begin
  3114. space:=' '+space;
  3115. readsymtable('elements',enumdef);
  3116. delete(space,1,4);
  3117. end;
  3118. end;
  3119. ibclassrefdef :
  3120. begin
  3121. def:=TPpuClassRefDef.Create(ParentDef);
  3122. readcommondef('Class reference definition',defoptions,def);
  3123. write ([space,' Pointed Type : ']);
  3124. readderef('',TPpuClassRefDef(def).ClassRef);
  3125. end;
  3126. ibsetdef :
  3127. begin
  3128. setdef:=TPpuSetDef.Create(ParentDef);
  3129. readcommondef('Set definition',defoptions,setdef);
  3130. write ([space,' Element type : ']);
  3131. readderef('',setdef.ElType);
  3132. setdef.Size:=getaint;
  3133. writeln([space,' Size : ',setdef.Size]);
  3134. setdef.SetBase:=getaint;
  3135. writeln([space,' Set Base : ',setdef.SetBase]);
  3136. setdef.SetMax:=getaint;
  3137. writeln([space,' Set Max : ',setdef.SetMax]);
  3138. end;
  3139. ibvariantdef :
  3140. begin
  3141. def:=TPpuVariantDef.Create(ParentDef);
  3142. readcommondef('Variant definition',defoptions,def);
  3143. write ([space,' Varianttype : ']);
  3144. b:=getbyte;
  3145. case tvarianttype(b) of
  3146. vt_normalvariant :
  3147. writeln('Normal');
  3148. vt_olevariant :
  3149. begin
  3150. TPpuVariantDef(def).IsOLE:=True;
  3151. writeln('OLE');
  3152. end
  3153. else
  3154. WriteWarning('Invalid varianttype: ' + IntToStr(b));
  3155. end;
  3156. end;
  3157. iberror :
  3158. begin
  3159. WriteError('!! Error in PPU');
  3160. exit;
  3161. end;
  3162. ibenddefs :
  3163. break;
  3164. else
  3165. begin
  3166. WriteError('!! Skipping unsupported PPU Entry in definitions: '+IntToStr(b));
  3167. end;
  3168. end;
  3169. if (def <> nil) and (def.Parent = nil) then
  3170. def.Free;
  3171. if not EndOfEntry then
  3172. HasMoreInfos;
  3173. until false;
  3174. end;
  3175. end;
  3176. procedure readmoduleoptions(space : string);
  3177. type
  3178. { tmoduleoption type is in unit fmodule }
  3179. tmoduleoption = (mo_none,
  3180. mo_hint_deprecated,
  3181. mo_hint_platform,
  3182. mo_hint_library,
  3183. mo_hint_unimplemented,
  3184. mo_hint_experimental,
  3185. mo_has_deprecated_msg
  3186. );
  3187. tmoduleoptions = set of tmoduleoption;
  3188. tmoduleopt=record
  3189. mask : tmoduleoption;
  3190. str : string[30];
  3191. end;
  3192. const
  3193. moduleopts=ord(high(tmoduleoption));
  3194. moduleopt : array[1..moduleopts] of tmoduleopt=(
  3195. (mask:mo_hint_deprecated; str:'Hint Deprecated'),
  3196. (mask:mo_hint_platform; str:'Hint Platform'),
  3197. (mask:mo_hint_library; str:'Hint Library'),
  3198. (mask:mo_hint_unimplemented; str:'Hint Unimplemented'),
  3199. (mask:mo_hint_experimental; str:'Hint Experimental'),
  3200. (mask:mo_has_deprecated_msg; str:'Has Deprecated Message')
  3201. );
  3202. var
  3203. moduleoptions : tmoduleoptions;
  3204. i : longint;
  3205. first : boolean;
  3206. begin
  3207. ppufile.getsmallset(moduleoptions);
  3208. if moduleoptions<>[] then
  3209. begin
  3210. first:=true;
  3211. for i:=1to moduleopts do
  3212. if (moduleopt[i].mask in moduleoptions) then
  3213. begin
  3214. if first then
  3215. first:=false
  3216. else
  3217. write(', ');
  3218. write(moduleopt[i].str);
  3219. end;
  3220. end;
  3221. writeln;
  3222. if mo_has_deprecated_msg in moduleoptions then
  3223. writeln([space,'Deprecated : ', ppufile.getstring]);
  3224. end;
  3225. {****************************************************************************
  3226. Read General Part
  3227. ****************************************************************************}
  3228. procedure readinterface;
  3229. var
  3230. b : byte;
  3231. sourcenumber, i : longint;
  3232. begin
  3233. with ppufile do
  3234. begin
  3235. repeat
  3236. b:=readentry;
  3237. case b of
  3238. ibmodulename :
  3239. begin
  3240. CurUnit.Name:=getstring;
  3241. Writeln(['Module Name: ',CurUnit.Name]);
  3242. end;
  3243. ibmoduleoptions:
  3244. readmoduleoptions(' ');
  3245. ibsourcefiles :
  3246. begin
  3247. sourcenumber:=1;
  3248. while not EndOfEntry do
  3249. begin
  3250. with TPpuSrcFile.Create(CurUnit.SourceFiles) do begin
  3251. Name:=getstring;
  3252. i:=getlongint;
  3253. if i >= 0 then
  3254. FileTime:=FileDateToDateTime(i);
  3255. Writeln(['Source file ',sourcenumber,' : ',Name,' ',filetimestring(i)]);
  3256. end;
  3257. inc(sourcenumber);
  3258. end;
  3259. end;
  3260. {$IFDEF MACRO_DIFF_HINT}
  3261. ibusedmacros :
  3262. begin
  3263. while not EndOfEntry do
  3264. begin
  3265. Write('Conditional ',getstring);
  3266. b:=getbyte;
  3267. if boolean(b)=true then
  3268. write(' defined at startup')
  3269. else
  3270. write(' not defined at startup');
  3271. b:=getbyte;
  3272. if boolean(b)=true then
  3273. writeln(' was used')
  3274. else
  3275. writeln;
  3276. end;
  3277. end;
  3278. {$ENDIF}
  3279. ibloadunit :
  3280. ReadLoadUnit;
  3281. iblinkunitofiles :
  3282. ReadLinkContainer('Link unit object file: ');
  3283. iblinkunitstaticlibs :
  3284. ReadLinkContainer('Link unit static lib: ');
  3285. iblinkunitsharedlibs :
  3286. ReadLinkContainer('Link unit shared lib: ');
  3287. iblinkotherofiles :
  3288. ReadLinkContainer('Link other object file: ');
  3289. iblinkotherstaticlibs :
  3290. ReadLinkContainer('Link other static lib: ');
  3291. iblinkothersharedlibs :
  3292. ReadLinkContainer('Link other shared lib: ');
  3293. iblinkotherframeworks:
  3294. ReadLinkContainer('Link framework: ');
  3295. ibmainname:
  3296. Writeln(['Specified main program symbol name: ',getstring]);
  3297. ibImportSymbols :
  3298. ReadImportSymbols;
  3299. ibderefdata :
  3300. ReadDerefData;
  3301. ibderefmap :
  3302. ReadDerefMap;
  3303. ibwpofile :
  3304. ReadWpoFileInfo;
  3305. ibresources :
  3306. ReadLinkContainer('Resource file: ');
  3307. iberror :
  3308. begin
  3309. WriteError('Error in PPU');
  3310. exit;
  3311. end;
  3312. ibendinterface :
  3313. break;
  3314. else
  3315. begin
  3316. WriteError('!! Skipping unsupported PPU Entry in General Part: '+IntToStr(b));
  3317. end;
  3318. end;
  3319. until false;
  3320. end;
  3321. end;
  3322. {****************************************************************************
  3323. Read Implementation Part
  3324. ****************************************************************************}
  3325. procedure readimplementation;
  3326. var
  3327. b : byte;
  3328. begin
  3329. with ppufile do
  3330. begin
  3331. repeat
  3332. b:=readentry;
  3333. case b of
  3334. ibasmsymbols :
  3335. ReadAsmSymbols;
  3336. ibloadunit :
  3337. ReadLoadUnit;
  3338. iberror :
  3339. begin
  3340. WriteError('Error in PPU');
  3341. exit;
  3342. end;
  3343. ibendimplementation :
  3344. break;
  3345. else
  3346. begin
  3347. WriteError('!! Skipping unsupported PPU Entry in Implementation: '+IntToStr(b));
  3348. end;
  3349. end;
  3350. until false;
  3351. end;
  3352. end;
  3353. procedure dofile (filename : string);
  3354. begin
  3355. { reset }
  3356. space:='';
  3357. { fix filename }
  3358. if pos('.',filename)=0 then
  3359. filename:=filename+'.ppu';
  3360. ppufile:=tppufile.create(filename);
  3361. if not ppufile.openfile then
  3362. begin
  3363. WriteError('IO-Error when opening : '+filename+', Skipping');
  3364. exit;
  3365. end;
  3366. { PPU File is open, check for PPU Id }
  3367. if not ppufile.CheckPPUID then
  3368. begin
  3369. WriteError(Filename+' : Not a valid PPU file, Skipping');
  3370. exit;
  3371. end;
  3372. { Check PPU Version }
  3373. ppuversion:=ppufile.GetPPUVersion;
  3374. Writeln(['Analyzing ',filename,' (v',PPUVersion,')']);
  3375. if PPUVersion<16 then
  3376. begin
  3377. WriteError(Filename+' : Old PPU Formats (<v16) are not supported, Skipping');
  3378. exit;
  3379. end;
  3380. if not SkipVersionCheck and (PPUVersion <> CurrentPPUVersion) then
  3381. begin
  3382. WriteError(Format('Unsupported PPU version %d. Expecting PPU version %d.', [PPUVersion, CurrentPPUVersion]));
  3383. exit;
  3384. end;
  3385. CurUnit:=TPpuUnitDef.Create(UnitList);
  3386. CurUnit.Version:=ppuversion;
  3387. { Write PPU Header Information }
  3388. if (verbose and v_header)<>0 then
  3389. begin
  3390. Writeln;
  3391. Writeln('Header');
  3392. Writeln('-------');
  3393. with ppufile.header do
  3394. begin
  3395. Writeln(['Compiler version : ',ppufile.header.compiler shr 14,'.',
  3396. (ppufile.header.compiler shr 7) and $7f,'.',
  3397. ppufile.header.compiler and $7f]);
  3398. WriteLn(['Target processor : ',Cpu2Str(cpu)]);
  3399. WriteLn(['Target operating system : ',Target2Str(target)]);
  3400. Writeln(['Unit flags : ',PPUFlags2Str(flags)]);
  3401. Writeln(['FileSize (w/o header) : ',size]);
  3402. Writeln(['Checksum : ',hexstr(checksum,8)]);
  3403. Writeln(['Interface Checksum : ',hexstr(interface_checksum,8)]);
  3404. Writeln(['Indirect Checksum : ',hexstr(indirect_checksum,8)]);
  3405. Writeln(['Definitions stored : ',tostr(deflistsize)]);
  3406. Writeln(['Symbols stored : ',tostr(symlistsize)]);
  3407. end;
  3408. end;
  3409. with ppufile.header do
  3410. begin
  3411. CurUnit.Crc:=checksum;
  3412. CurUnit.IntfCrc:=interface_checksum;
  3413. CurUnit.TargetCPU:=Cpu2Str(cpu);
  3414. CurUnit.TargetOS:=Target2Str(target);
  3415. end;
  3416. {read the general stuff}
  3417. if (verbose and v_interface)<>0 then
  3418. begin
  3419. Writeln;
  3420. Writeln('Interface section');
  3421. Writeln('------------------');
  3422. readinterface;
  3423. end
  3424. else
  3425. ppufile.skipuntilentry(ibendinterface);
  3426. Writeln;
  3427. Writeln('Interface symtable');
  3428. Writeln('----------------------');
  3429. readsymtableoptions('interface');
  3430. {read the definitions}
  3431. if (verbose and v_defs)<>0 then
  3432. begin
  3433. Writeln;
  3434. Writeln('Interface definitions');
  3435. Writeln('----------------------');
  3436. readdefinitions('interface', CurUnit);
  3437. end
  3438. else
  3439. ppufile.skipuntilentry(ibenddefs);
  3440. {read the symbols}
  3441. if (verbose and v_syms)<>0 then
  3442. begin
  3443. Writeln;
  3444. Writeln('Interface Symbols');
  3445. Writeln('------------------');
  3446. readsymbols('interface',CurUnit);
  3447. end
  3448. else
  3449. ppufile.skipuntilentry(ibendsyms);
  3450. {read the macro symbols}
  3451. if (verbose and v_syms)<>0 then
  3452. begin
  3453. Writeln;
  3454. Writeln('Interface Macro Symbols');
  3455. Writeln('-----------------------');
  3456. end;
  3457. if ppufile.readentry<>ibexportedmacros then
  3458. begin
  3459. WriteError('!! Error in PPU');
  3460. exit;
  3461. end;
  3462. if boolean(ppufile.getbyte) then
  3463. begin
  3464. readsymtableoptions('interface macro');
  3465. {skip the definition section for macros (since they are never used) }
  3466. ppufile.skipuntilentry(ibenddefs);
  3467. {read the macro symbols}
  3468. if (verbose and v_syms)<>0 then
  3469. readsymbols('interface macro')
  3470. else
  3471. ppufile.skipuntilentry(ibendsyms);
  3472. end
  3473. else
  3474. Writeln('(no exported macros)');
  3475. {read the implementation stuff}
  3476. if (verbose and v_implementation)<>0 then
  3477. begin
  3478. Writeln;
  3479. Writeln('Implementation section');
  3480. Writeln('-----------------------');
  3481. readimplementation;
  3482. end
  3483. else
  3484. ppufile.skipuntilentry(ibendimplementation);
  3485. {read the static symtable}
  3486. Writeln;
  3487. Writeln('Implementation symtable');
  3488. Writeln('----------------------');
  3489. readsymtableoptions('implementation');
  3490. if (ppufile.header.flags and uf_local_symtable)<>0 then
  3491. begin
  3492. if (verbose and v_defs)<>0 then
  3493. begin
  3494. Writeln;
  3495. Writeln('Static definitions');
  3496. Writeln('----------------------');
  3497. readdefinitions('implementation', nil);
  3498. end
  3499. else
  3500. ppufile.skipuntilentry(ibenddefs);
  3501. {read the symbols}
  3502. if (verbose and v_syms)<>0 then
  3503. begin
  3504. Writeln;
  3505. Writeln('Static Symbols');
  3506. Writeln('------------------');
  3507. readsymbols('implementation');
  3508. end
  3509. else
  3510. ppufile.skipuntilentry(ibendsyms);
  3511. end;
  3512. ReadCreatedObjTypes;
  3513. FreeDerefdata;
  3514. {shutdown ppufile}
  3515. ppufile.closefile;
  3516. ppufile.free;
  3517. Writeln;
  3518. end;
  3519. procedure WriteLogo;
  3520. begin
  3521. writeln(Title+' Version '+version_string);
  3522. writeln(Copyright);
  3523. writeln;
  3524. end;
  3525. procedure help;
  3526. begin
  3527. WriteLogo;
  3528. writeln('usage: ppudump [options] <filename1> <filename2>...');
  3529. writeln;
  3530. writeln('[options] can be:');
  3531. writeln(' -F<format> Set output format to <format>');
  3532. writeln(' t - text format (default)');
  3533. writeln(' j - JSON format');
  3534. writeln(' x - XML format');
  3535. writeln(' -M Exit with ExitCode=2 if more information is available');
  3536. writeln(' -S Skip PPU version check. May lead to reading errors');
  3537. writeln(' -V<verbose> Set verbosity to <verbose>');
  3538. writeln(' H - Show header info');
  3539. writeln(' I - Show interface');
  3540. writeln(' M - Show implementation');
  3541. writeln(' S - Show interface symbols');
  3542. writeln(' D - Show interface definitions');
  3543. writeln(' A - Show all');
  3544. writeln(' -h, -? This helpscreen');
  3545. halt;
  3546. end;
  3547. var
  3548. startpara,
  3549. nrfile,i : longint;
  3550. para : string;
  3551. const
  3552. error_on_more : boolean = false;
  3553. begin
  3554. if paramcount<1 then
  3555. help;
  3556. { turn verbose on by default }
  3557. verbose:=v_all;
  3558. { read options }
  3559. startpara:=1;
  3560. while copy(paramstr(startpara),1,1)='-' do
  3561. begin
  3562. para:=paramstr(startpara);
  3563. case upcase(para[2]) of
  3564. 'F' : begin
  3565. FreeAndNil(pout);
  3566. if Length(para) > 2 then
  3567. case upcase(para[3]) of
  3568. 'T':
  3569. nostdout:=False;
  3570. 'J':
  3571. begin
  3572. nostdout:=True;
  3573. pout:=TPpuJsonOutput.Create(Output);
  3574. end;
  3575. 'X':
  3576. begin
  3577. nostdout:=True;
  3578. pout:=TPpuXmlOutput.Create(Output);
  3579. end;
  3580. else
  3581. begin
  3582. WriteError('Invalid output format: ' + para[3]);
  3583. Halt(1);
  3584. end;
  3585. end;
  3586. end;
  3587. 'M' : error_on_more:=true;
  3588. 'S' : SkipVersionCheck:=True;
  3589. 'V' : begin
  3590. verbose:=0;
  3591. for i:=3 to length(para) do
  3592. case upcase(para[i]) of
  3593. 'H' : verbose:=verbose or v_header;
  3594. 'I' : verbose:=verbose or v_interface;
  3595. 'M' : verbose:=verbose or v_implementation;
  3596. 'D' : verbose:=verbose or v_defs;
  3597. 'S' : verbose:=verbose or v_syms;
  3598. 'A' : verbose:=verbose or v_all;
  3599. end;
  3600. end;
  3601. 'H' : help;
  3602. '?' : help;
  3603. else
  3604. begin
  3605. WriteError('Invalid option: ' + para);
  3606. Halt(1);
  3607. end;
  3608. end;
  3609. inc(startpara);
  3610. end;
  3611. if not nostdout then
  3612. WriteLogo;
  3613. UnitList:=TPpuContainerDef.Create(nil);
  3614. try
  3615. UnitList.ItemsName:='';
  3616. { process files }
  3617. for nrfile:=startpara to paramcount do
  3618. dofile (paramstr(nrfile));
  3619. if not has_errors and (pout <> nil) then
  3620. begin
  3621. pout.Init;
  3622. UnitList.Write(pout);
  3623. pout.Done;
  3624. end;
  3625. finally
  3626. UnitList.Free;
  3627. pout.Free;
  3628. end;
  3629. if has_errors then
  3630. Halt(1);
  3631. if error_on_more and
  3632. (has_more_infos or has_warnings) then
  3633. Halt(2);
  3634. end.