From a8e6ca86f617e62420a6c2db2d58fea9fafbf019 Mon Sep 17 00:00:00 2001 From: ghidra_red Date: Thu, 27 Aug 2026 17:50:22 +0000 Subject: [PATCH] GP-6993: Add help docs for DebuggerVariableViewerPlugin --- Ghidra/Debug/Debugger/certification.manifest | 3 + .../src/main/help/help/TOC_Source.xml | 4 + .../DebuggerVariableViewerPlugin.html | 135 ++++++++++ .../images/DebuggerVariableViewerPlugin.png | Bin 0 -> 18194 bytes ...DebuggerVariableViewerPluginRightClick.png | Bin 0 -> 26683 bytes .../DebuggerVariableViewerProvider.java | 23 +- ...buggerVariableViewerPluginScreenShots.java | 251 ++++++++++++++++++ 7 files changed, 406 insertions(+), 10 deletions(-) create mode 100644 Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerVariableViewerPlugin/DebuggerVariableViewerPlugin.html create mode 100644 Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerVariableViewerPlugin/images/DebuggerVariableViewerPlugin.png create mode 100644 Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerVariableViewerPlugin/images/DebuggerVariableViewerPluginRightClick.png create mode 100644 Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/variable/DebuggerVariableViewerPluginScreenShots.java diff --git a/Ghidra/Debug/Debugger/certification.manifest b/Ghidra/Debug/Debugger/certification.manifest index e90f410858..4d989a1b13 100644 --- a/Ghidra/Debug/Debugger/certification.manifest +++ b/Ghidra/Debug/Debugger/certification.manifest @@ -68,6 +68,9 @@ src/main/help/help/topics/DebuggerTraceManagerServicePlugin/DebuggerTraceManager src/main/help/help/topics/DebuggerTraceViewDiffPlugin/DebuggerTraceViewDiffPlugin.html||GHIDRA||||END| src/main/help/help/topics/DebuggerTraceViewDiffPlugin/images/DebuggerTimeSelectionDialog.png||GHIDRA||||END| src/main/help/help/topics/DebuggerTraceViewDiffPlugin/images/DebuggerTraceViewDiffPlugin.png||GHIDRA||||END| +src/main/help/help/topics/DebuggerVariableViewerPlugin/DebuggerVariableViewerPlugin.html||GHIDRA||||END| +src/main/help/help/topics/DebuggerVariableViewerPlugin/images/DebuggerVariableViewerPlugin.png||GHIDRA||||END| +src/main/help/help/topics/DebuggerVariableViewerPlugin/images/DebuggerVariableViewerPluginRightClick.png||GHIDRA||||END| src/main/help/help/topics/DebuggerWatchesPlugin/DebuggerWatchesPlugin.html||GHIDRA||||END| src/main/help/help/topics/DebuggerWatchesPlugin/images/DebuggerWatchesPlugin.png||GHIDRA||||END| src/main/help/help/topics/DynamicStaticSynchronizationPlugin/DynamicStaticSynchronizationPlugin.html||GHIDRA||||END| diff --git a/Ghidra/Debug/Debugger/src/main/help/help/TOC_Source.xml b/Ghidra/Debug/Debugger/src/main/help/help/TOC_Source.xml index ff425d4024..e3ed917984 100644 --- a/Ghidra/Debug/Debugger/src/main/help/help/TOC_Source.xml +++ b/Ghidra/Debug/Debugger/src/main/help/help/TOC_Source.xml @@ -130,6 +130,10 @@ + + diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerVariableViewerPlugin/DebuggerVariableViewerPlugin.html b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerVariableViewerPlugin/DebuggerVariableViewerPlugin.html new file mode 100644 index 0000000000..377cc5f9c5 --- /dev/null +++ b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerVariableViewerPlugin/DebuggerVariableViewerPlugin.html @@ -0,0 +1,135 @@ + + + + + + + Debugger: Variable Viewer + + + + + +

Debugger: Variable Viewer

+ +
+ +
+ +

The Variable Viewer displays a table of local variables for the function at the current + program counter, evaluated against the current thread's machine state at the current snapshot. + Variables are gathered from two sources: the Static Listing and the Decompiler.

+ +

The variable viewer uses colors to hint about changes and freshness of displayed values. By + default, changed values are displayed in red, and stale values are displayed in dark gray. A + stale value is one whose backing register or memory location has not been recorded in + the current snap.

+ +

Table Columns

+ +

The table displays and allows modification of each variable. It has the following + columns:

+ + + +

Actions

+ +

The variable viewer provides the following actions:

+ +

Enable Edits

+ +

This toggle enables writes to the machine state. To modify a variable's symbol, value, type, + or representation, this toggle must be enabled. It is available only when there is an active + trace. Edits are directed according to the Control and Machine State + Plugin.

+ +

Show/Hide + Variables

+ +

This action controls which source of variables is displayed in the table. The three choices + are:

+ + + +

Right Click Actions

+ +
+ +
+ + + +

Sub Menu Options

+ +

Both actions share the same sub options of which listing window to show the result in:

+ + + + diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerVariableViewerPlugin/images/DebuggerVariableViewerPlugin.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerVariableViewerPlugin/images/DebuggerVariableViewerPlugin.png new file mode 100644 index 0000000000000000000000000000000000000000..894120f4911a532e22fa6bc76a9c866c2069794c GIT binary patch literal 18194 zcmeIaXH=70*DlP~ZP`@aN=FcpA_z#A5>P{v-g`i#cY)9X1h)z(y?274_g)i1+#tQz z(Ajhdy@XCUH~ZPo`=0k3;~VGvI=`MD3>Yc*T5GPk=A73xuf;bFH3bS%22v6d5{kEq zvRWi0zZ?QT33qP;uSDQor$|WTC*I1w*6}voO21RDEk`8cApVA4H$$RIixGK6*$kgI@eH50QjTv=)v!YJ52zq! z4qs>PX?;5mHh8OE6FeSX6FjNPLSB;!M&kSZ9dl2qhfjHdH~;3obm} zrAP>#f)EtOXDIfe>WasrJ=zoUY+FrH+b(H&Zd$R?N3UWvkKPSy9u4epU%4WfiI&x% z-?akOuLiPu<)^SI;T7#EkrnMZ{cYpe0NjI&$Qn*CtWXYta26j!*opV8Pv|Xfim!*d z9{DL!W9eM@{gU&p6ieEtLRm3~qrdu!XX`f+!SRzS6gj;4c}_Ra9f9{uwr256b|#?I>LQ=$V5guC15QCAo5WxSLXvqn*nWRl#etiU zX2)_>st)U|R`>0#w8k8aH12P3c_Oy}I$ zWq0~&L=o_0hbyvzt?vy-z2AMtoOfC5Wh@c?j6+`FRpUE$28brAg2mm_F}sr+=dT$m ze!wpv=?Z-1d~CEvI87hCC=BUw1p&1^ugu7<2rafz#I*5N&MwkO66iDXnjX+h^|KOE z>wgwth3&pk+_n2_iT$X1Dd(s=PKtumZg(U{^l3J7I6<5u6_Gd38lF_qBj0D>%x1$^ zr^yEC^ih$pW2LCd2Z*MbpnM?ApMBarHvTD!hRUUNQ*T( zi6BH?g++VYPilRueG`HIdL0%;eyJXCrfop9=&a`CIPH^UF-{irC{az_DOQM_Jz5CO zm{4HxcQ{z-4SkzRxz*Xg@gNA1)jS{oC4U5_3PE=N-0I|P;m$9h9eX+lM<>VgT}H?A zUws3e*^>DZPhH;Jo*PXOV`1L^lSb5GtT<_Pvw+mMv><<+{*2RqW$K`Wv-KzE(3;Oi ziQcNAz}_v@Do*Y-@jNgv(g}2N>v+#?qsxNgpBwTVx@AlST=B5& zII{Q+@Qg_AILKVQ7;L(Nr+`l0Q5!e7{r4(-^0*2-=ZI~5U zYx{t};bS^fk1>ah1wUyjjDrH>I8o@?LQ%7c@WoHinvqxhiG+!~`>`2yKcY%q`m|O0 z$}ivlpqK7^8$IAf809av>7Nzw+5Gl9JXSC)yD{$i>GI;>d8()rX0%{_0pDb}X3^=i>5DhFHR@A?N@y`sTlqRxPy(l03NW77FSy zI7RboZ;C*!enOf-2j#{pt-8PL!&bGrIS)ga=INEL9hzdr1GBIf%td9ln>tYJ3Ndv%Wia!jFSn^ zvs`7c!y~i=+zT{5^BX5NqOvfxsvoegPk>&R=pBpl^eC*l}*hz{4P#1Ao)yA_aNw~tW@Az0+E>`)V}CJ^D8=zkX@5Zt-{XbkrU$th2vNr^iHT*~H_I z`*v%j=fgj>k>r=3>fo-J`PHT#;|c$%V76(KgVxd8t=R-&`)$~HeShNz1CDX`g{~wh z-2JdSqd$aVs`wyjS<{Y#chZ*k_VcjRygrDvAvg4ozaC+0S2U(Br(8T=r#0;B%sRZ@ zPqf?kvvh=5y5x;qbiFEc*$?B?Au1diNvg&Cawy=v-F&9?_&D>3)@aQdoo>5KA6(0+%F z=VG{v@eJzpcmR~+*4No5vH^m=1-GZm^SfV(ZHkMvrSX#y>K%wLhg%&)>d&KoPjbw@ z*bD5;o9I6%nHxC)FL;UdY}_xKX>3U-nOmurdg`j$+sIsD)(NcSK!3-m<>)M6^Mas< zoOtOl%Rh4WlE{F1HMsG#dk3WfM<8+Af@IgR4N4BmBcBl>bj&t%d_ivH3dD2!yY!|~ zRg9G=7zL85fg}`wzE)g%aL74hmzixjZws2M+JU; ze2t#EuMN4IsX^W6QdY{^MvS zFAf!lBbYKH!f2CU9F{em_1TZCnVZ4Io1HWraL(13B+8EZIL(olyd0S@Hb_X<~HOdD%<9nC{6 zSzy@`VFvi2a|*(WL<>+G_u!9{EO4U?_?3)6*raKS4ml{^&(d=tnV$o7%R;Frem1&j zEFh(PXp+MC_of#ENeHJ_rZ; z)(4cbNibz>v0;_@QIC+*RuH2p6m%%!F!pmv-+)~L_oPAFB%ArluThy_h`WV zRsL{o5!eE}%&N{lE(AJX;+V)xgcgSmhxlJP{OqRs$LSNvL5Kw)MkTKFr8`7Q8?`XQ z@-_2=rFktQBxlBiU4EJN!0A$g#%hOh%<5v;%}A5|vZD4PyF-w9U|-9%{I#FqRxhq= zp?-ES|J`Iks9p1yZ+dmk4;;qJll_k--g$-M^i5AiE&p-}ByV)>`0LKZ021uf5yjfq zlgI~Qh;2vYKVCJ`Fkchr{nrN|aU))r;?sz${6=Smf-IE%CI&xb#E z-3RwS))_f`C7w&wB?$WGO*&W*GBfv1mw>-U!ulU>DlBnUupa|LZNfO zs96_|&iKmb+y4wqFLD^qqd%$4kFm^4_e=p2EYb5~uYKzBc+N%0rVrZgp`WT-q<4y- zem^)4~0Db^{_YO=W<3e_3W=@OjD?oI;MCDA1y zV^rttbcgA~N2kf^&VY_S>2t^P&8q&3|DF)lXzy}&qU30q*_@j6>Cy*-$y%q>t7qbJ zwOyJWVa)IobA4wRK>Jw$*Dz0K_wWIl6p zNLG*PuomwML%{F_`Sn)a2@TA-eEaU{j&W9vg5(Uq7=M1ggYL?`Ex^p;f2cW9-k$C? zyS@-`z9oixjBxK0_Z&A5ZYa{Y{NeZ1UKo3Z=fPQk7QV6-0~=II3smb?k_SCPTR(16 zK{3A&NS{n#eCtN@HCxm`1Rcqvaf_Kdels38!#d}gW;@UA>GdFk_>~T}$m(Ebm~CX~ zUqhO}{w{x}lC}lx6dB@xD@{-L7&F`sh}Z8;5!q^Ebb(qGR&GsH<#}vRPn4qY+>%RC z;LQ-8(y!b$pw&|JcI82zWIv_!$-6}7wE^V(;*-&S?nk#1BivMi@UdNjzmFykMBUA;F(V`l>19c->f+(td4pthvjv@mt*e)(&)g(G|)(5kKQ}fCUDl#|zw6C9I z15Bz<4l%m{nRc8(i7@4nrIcZb5=?4(?H4;@$;do(Q_dUFt|4_Pu)3ZLX6IC0=5h(2 zKS>s@BWF5JBX{a!S;cf|U2WOJhxbD!pXtIlkEAmEaqFV-jl9MoM`e^=tgs?5|%Z)%I{EmjD% z2)1&BDW#P1{Ai1jvWN-8;}x%OsqO{@ZobHl%BYH>q4mp<#R$nhU7{i%=1|M`l7O4J zx^-IY);d5qbr62TM*D`=KSh78-25~DGK=h(z^>7Bvf6b=BY49Iwao>fRI(%1ncAIZEW@dSeQq+n6cc^(s=_cf7&@!Bw1OnZul z#Kl${G=)lFF&*q_^wj5zAZfdyr~1EK@`R7_j0Df$FZ(F$m^lxnUOCxYgp}bCzT2+g z)+d^?(Lts2mO0;;^k%gM4K>-iwK&SeA$y0z>c(4>H7)B4@%l^WG^h}D>$S6e-`k1# zQrf4*q+pJ2ffzmrYTWGVOkXTBt008(k;Ios_9BbsEBI)+z3l|s(14KUoEEFG75&>M zV18SSZYolcR!$erJn>usOK;~5SuR+A8Ledalt=wOzv}hzKkI(M4ESv0iDTU#1yLSg z+>2;0LS|PsD+`rK5^6tebMR|XS(Ai)K9}h)c9h_jEc~A^+q?MvZho&T&Mspx2cp8R zUN*cTz`$O;!%{B%xiZBSlgEhWwh{!hGf`y|Jlx7tW*Jm!&UO`r=6l>YUm&}j+-0Ln zCukTEo&SfXc{)1^7zSS9p=Qcnb$dD3 zlCDPM4K48Zc`C?!QN_qc;k@7Ja$<{}srUS?M6WVajN_l5Zt3NzJxb&l8W+YD`+z8{ z99-i_6+=5ol_j|CxvieX$>$a|Y%2nLDG1hI{3||O`c8Zi%?r8G6xHP_ZvE0UNq&)O z-#0)i)`cRokGHYk-{wS|&g}^GOD%>uF8uuFTru=OUFyClGbK)SQI0G~}=rt1&WVTSF@-YB-TidOPzbKt3bE!rhGnE6sQ z%jYTV>f3_0-OUFeu?K)jMo;XVHH*IJ+CiyH*)OAcK8X|;IPu_rTkkF&O~JF;IYj9h zZjkC2=T$!uijlpQ{gOUDOrb^5UWIK{OazBSa`T=@EXQe24}4uotB#S30ixzedL5r= z_1#`$4`VtYHEKUoMz+$QHQOt{d%D-flZ@ODx3{f^oOIU3 zQx+BiM18Jyok6*nt2g~@hK~-gW+F5|!uQBXg(*(vd`INltUXD;b_v4-W*|Jl33>-@ zvtw@q+an$^#>-oxFQh6BBlgH4wBZcD49R6G!2hQO>N_M`+5e{n+;2Ixro1r!BqQNu znUx9iF2aeN-4h0$@;a|R-YOH8+8b2<;$fYeio7ddzX?zGLYJx2n$gI2o(UCa*G_A> z(a}?@M94}c<*yUZ+rMj1cL{1@c>8WY4KWty$ao(?KQ7;ni}h+U*{m1 z1Q&~?zpXUXB*3fr9)ATA%V#xLo^Dw}?MuceF6ZT>umuxDgI+>wJf>?v#4MZoYl_Se z6H3oZzSN-a*NMV>qbQ_#x60+2k!Ea(+cYDWnpLvdzXsJ7&wcY>^R!x%`{nV7G_Uzv5+#XX~YG&VNrD^Xfi2DqM9;#=i)^8>u3Ce}(`ifM~sQYOI zCxr8wRLt_BFS?Qz3vyp`QA1ppM@6BBvd33Znh#9IGjd-rNPD{JF_=H}v#R1dH7gq0 zaIu~lUo`_ON zx3FY*=m^X-XWvNhFaqL>s&^>kpP!uK9t`Octt2z8}hYKUR?anhRm%Khq~-8|_NUGfP%B zT|eX8R1@caWW`83)-k|aH^Z!JRy688X9_1!7^AJ~$cpBr&Zh(9MZ$E8aFzO|MNH0j zZTL;?#Nrw|$B)v{KL#FmzY9DANh?tCK4>f@))32Nw52!FqzSzKwDsO7^;e=bYI zvc=y#Gfaa?3bKnR!gR(Zb8oBB=9y-#y>*ak4AN{D{(U*XpCGl}P-ddympxLo-@cqu zX|?76pIKfpA}AXu>$!xSs)V5bHHo)Dri+&-0UwCpx|K7pHa9SV6o4$2%X-5IE96L1 zLjAq9cqbgO{IyORHh8yVCK#(mxmy;$n|e#qgl(}6C2rA&c&J*<~sRnn(F zS=6h7abIS!r^*B~w!5gQaLLQDW1=le4splgArUDrXZoZz9BuB>nm}ErncunUif(9e zm$CbRw~5eY9;uZsiTH!J?5f!>4m0luMYtK+Z;pD)wiW#GEe)JlZL7BOy={B?pwFu% zakfGhl&)^{(uKUDn4gmPqdLKb6EmA#68Yd!edQ-@)S=a_2ay(=U*PzJ2z2s)$y$Exp zOBHsQZ|)u=GDK{My!&d*wFLAK+v%NGgNXWz`Ujt3&cB#0oq7-1H0?Bl8asmbG*Fo zJr9pZ$=fJKCHWGl3cG4l4*#l`jAz~b#k|R2id59?&ERcJOZ(`_Gqv?YximDiCNuz} zqsk@w6w$Dm5S4(bdwdE>Y`6_v(=w$C4738HmLtw_rzx zlJn(F-@OtsGTh;?*LRqqQ63vJGTdVmfk z3lbh1)b1);{(h^N$@y{`>O#)hT>ti@YJ^t7FuXIrnrFU0fLOKh+Zq3-dvCr4B59*n zcp(-ZjKZ!IX{DZ{?wT%BlFTlBS|GPecy&P2;aXPYZ;bVaOG5qVdCki*5RS-d`{hC_ z(!}G%pi|P~XnR$kI4-5e@ew6$u3CF6AK%EqaX$symwnnG(_gj93|m(EF}pDo%;K{m znMNgNBURKbb_*hKqmE^#)o)<{EIBGIOe|#;;k_3s)*h&leLI|P6`vqxv!UO3mQTHo zK+@K#v3(ihB*)x++A?}!vBZ=>BO6MF;?3&ExNWFs90Ls!1m{7`Jk zuc9gWDt_n76LvP-ntE^_=zYZ7J-kKs|MsZt(F}Vj5zYc+tLL1TCnjr^c;NO@HM4DJ zebw}X7-7&PkLI3UnJ%ZjW?G&;4|W-TC{Lz;;RB?sV;O^4LS;?4-CkjM-!w+f@glTrT%euVhBMtS1amlto7qKSZAAR0 zAL72l>Llg3l7&@>;}6u))I+FajNUWfW6DT<7B&h9x8pw#C8@q5o})w%6ZUOUeECa!@H_g)cCK*llI=yP!KR;!CM)lTX*6|*D2F60o_huZ`0 zR;s*~uDhTUv5zYXr8V_NLVUMsL_Igh^A`aks3w4Tkg=VV_dxCCpSQ{B?!~JCJi+K} zz?DDxV!wOF#~&#CiBIpn1F}sY=y*Ec&(xnVn!gx5;Cw6f4gJ}uzM0blPBrM2deVzO z123N{XOWs_%KkQ0@0vxXj*yzrZJUFi^KwHf{bWUlzXCwA!94)Lra*u4h}aTkrFA*I zzlbvnsOjcI_W)e*Mst--zvsNuRBhn!;m+J#0>IT$hWc(dwA1jL0)@%#lQCnL8d0ao z@xFA)tccgUot}`G*LgR#^md<>BO{qXlK?R{pZ_wjJ&gVVWnPN)>HhNlXFc24D|o7q zjoQmJd+7MRo?QncpCscxn?Myvc5f=F72Pt2X{K??=#VDMYf! z3=7vuYYsV9WDn1v=FuBxPc-@6gF017dP0Q_inwMIwq`Msc};W-mjkD_!*!(V0NTm8 zKr6?DU%~I7SIiUOKBgibNjBRF3qso;c^LqezSC%-?idn$2My3>E$xd)VHWraQf87+ zJ>sojsMFaM&yy(Bk_vpNiY4G;kcHyb(LXB*D3<2Qklry?_yXo9Hpc+ikD4n>V(%8>s zng)Bt{TY}bS|RY#cAR)c+_~EPM8;QslS=A^R9ME>{pIfVLzHl_&!8M_1KI8H-)#+a z!MUGrQ-mn#Gc}wngw9MmzgF}DQIG=p-d=1Jao6K(b%d<@NpyD6%%=rapj(Yey-mR& z+j{CN3uM26d*=k4nM*8(>OPCovkb>vdO^#tfcv`7e=x_=;py##-;n(hOvU1Su-ac2 z&8A?4ff1U+EdavUq)hO76=NmF=nTwswO#C0R65X5I06v#X;vt8fuA!o;Kd#?23ZO+ zfDgHbF9QshiT6aM6<;Huc`)me8rjfKZUfWWM3YI?NXvptUq7882;Y6^0XbXG%h&`O zV`Ra@qt37Q09PsH!IDyQ%eDd?B{og>go5n*N?xP7`f|Og3NhENasV)y3MCvM0BV|) zaUkedf=lDB_7kz=3B1M^!Ohudq>AO*2CmGD?bpIzqg9dxTQ3m+^<9*;5XuP5^bP2# zzaBW4(gPevBvYh_gdYwnXu6U*G=Z2Wk(ycZ6u=&}6mjcE-XfzJ2Z&s{=mn}Lc}c%V zmkK98{(I88ko|#HM}TN-ng3L4TriRY&H3X{>m8U@&>ZrN6vVyBX~>}ap7+K#6FRXE zfBo1Uh*tRfq|0iJ^FW*)X{u}H(o^}LdQ8VQjo?Qe>Q8!v`k`QN&I~`dp6LqP*~SKd z@$>OKnGc@o6`R|H5uXeV5ahHC+Bk)^{&IOb^263tEqi~mOFgtN4tHOH$sE|B5DCQF z7=LFYr{dcxMd7X0cEf1}zC}^3Kno0LYdPN)Lu`zdxSO}OF9PgrSOeFt2Gu%XN2;B1 z@8x*?Vj#9O>G-hyhO*s{d?6cCDqQdvc1_!0Dn}<$C!_D>BKi4zFiUg$;;43qGvsU` zlz-Z5R|)hEhAw>L zY};&6Nl>pH_FfD10Cs%}I5H`_N@DjJ-VYN;vLdA??Z=Agh29|fZGhc^fD3(uc`ffV z#NYy>^ag?8HX@RV0rHNFdXa&Lnh|voe|1y!EW)v@LT{D|bQtCE4$Az7`c=`78acqv zZbgSW#9(Uo_0xt5aA~~=e|Sb}ADDn2(N?bk=(75k6b&1hOWCn%Ark6N>_g40qjDhb zw7Wa+x$fKBiu4rvw?wyOL|5AmHbXAf1n#dZ#gf9o`j19!ChJ_x^m9|paED=aHQbt@ zz|B#1NE*=g#3k3~^0_qbwIzukDaO?N+by)Yz`-B|GY*Q-PDkLlu;3UY8k62yacP_F z0(;zkS=M%#pA}JQih-SKEzgUL=@#l#RP{;l*h{OQTT=mDfQ{*fDl+v9=^2sfS*CYV zPt1(D0(kMCr(0dtNEIS}+Oi_$ZH2Qpqm@9nK5l+Q(hA@wYz4q^}YC-pH3C&zV86FOdohB7H{YWx87#e*14nTzm7n z2dK+V4?Cz&I!%p#I$W^U?FIx9%fH&JMH3#9gir#d*ud-o(A*g7HFP*J9WE4r!t2F;FlSX9j#WZV~CxKg>U|Zo1k$_tJqUY~QHT z^6g7C+6RJo=NVMsq7>l7G65Z+iwva9^NS$nGQ^EngCCJMNl1PrA%8?d@|fh^8c-Jf zLIS=+LUNacP6E)Ok|^4)ZPd{NRnr$YS$eTUIUcc}KLHZw&EFIXzZrHEKjPvjHtScE z?uNG$Xb1TpTX>-lD|t4%ib^Xacbae}95;oECsH`xEN3Vw`(1vIzmr>=m zA4HX0Q!}M%rT~L61~3{)!gq5rFYrTaZ-q89R?Xh^V^5TN4(?4pu=+WW*Khou7kk!5 zQ)=Ln2!UJmxUMJ8TWn2kD334bGD5sh#ydTiM{$#=5^QU>9GA@hm&)Nt*3q9UJ}WI5 zFYgVs;WOE0uxLFWeiE0VRiNyDhoXHzb5i#mIPreBcRzObiOn=sT)KED?khbV&HBF}bY!rKpu^p)5rsIK(~TJN%WruZRh$_< zv!!TcwgVVzJ1o88bC+87mMBy`KxXeLdUrv&`1l8sZ`x&7(YVG=K?Nlnw2dp4<1vBn z@sZwB%GNWht2*8oiww~=*faHBZrk!aD9PEZ;-9K7mydLA*gC2wc=VQ`i!E@7qa(D) zR)Gyq8xvLKtank0|L}Z!lDE#wW&K3UHB`sN`f6jX=P8QU+17OHy9~=0Er3wD1Xwgh zyFN*3a0bRZ2d(r-%FVAw;LE-?z_6vqwDLl#Cc>X%_KmEL^UG!U-)g_QW_TEtW|zX| z0;D=ne`SVl5x8|N77k*&9QtB(1@^eEP*1_fsTayu{vgNQyVUZ5qK7(R67f)mAk^99 zhSPY`TY>g_N*p3_H8PI(s8@H8zV>qkMdy3;ptH!<*dSTVeXfUQg3rU@CyScZ7aq@M znP54%IZIZKNjB;NfYZJ;3>ri0n<x6%R-Ho=eJ_3`z4)^%-v1~9*l<|D09esi^T3r8`uFJpct*;82x>AuRj>Elj6Yv1z34zQEB`|c!w%X_10-?DVq-A11Ha2s zrn|}}wlH6yvo2||Kg}4g1Zf`7+KJHHivsDpBfKp1nx9(A{XX)I-rUeRHHFu_(`oZgcMPvqmAH zG0o~x#B6rCU>{HxxsHl9bqM1pSiA>bkCk{`<)2(0P4PRf+3Q3~?Q`K?otWK3UMz`0 z1KAWJs-ra6l$<8L$lC>$A~g2y2bs#I)Iq~Xod$j;*TNF;zZKMNJvtUEje#uz;sy1d zu_mCl;BZ{SNAvJIH-wUM2c#ba=lmBXV6k?WngyT+A8(0|mY=%wH!juUJNhRmn#^;%LUOP|zBegAs}VM3#(U-LX9q*4 zyypC8!r2=?G`8u`-e532p1W9#0#i{iqQXotCzR>FKO6bpoOYV6UYI{aARRJlWca^m z904T9AJvmax#xYpH8VHZoa{8q&Kj;7nbaPX3B)7d+qdeHER{^Hu!lRER;UcIs zFa`Bd2ZUaWQ9gBL{}Q4>2m2fE@93WA09PGaNx}WDcF43KsRuKuOsro9W?9KW?ZTd2 z&mDkV(Q8oNBd?w^e^iFOz%vT01Kooyz~|jn&Oor4Kk(l_Q+c|tp?vk1?0tY7<(v27 zS_i~MqGWrW*rFsYrw7Cw$N!4FK{C$s{qnP8%zf}2%A-icd3xL#L(r4lsvf=wZh3B0 z-O&~I%mN4TN(bZ_5I%AZjUnAgK%L?sHvQo<#I=>$6Ts|KAAh-d@s^2{oI$dEj2J|Tq zpXGRBi+O3&nSJU@*Ua;P<}bhfJ)UMHkgNQUAya@RhK%2=X__9ra47|-Nkl*V^(sL4 zBirZ^KlRb!X}Oo?J1~o+XE9o*HJItWnLi<(%nLu#Nh!Jcf;NLCQu-{vH(7|2$rJ@G*oeNuUL9X;#whc-&fN?r zeQr?xc)`#b97OJlsd6Z7XzLSSWh&Cj2?1Rm4r|)I+j*>cp2+Qc<~NS!Do6UJL5JR! zYBEYd^T{Ha#D@SnWL`PG{!Og|t`CnZW1-F~UpS_@ra`WiFc8BdfJvd3&5{ql=zPqg zRiH3c=TfJYqjW7aH8H^CO}St}&i*qs4vB=#iD96+w*x@`A&aL@zQ&){{fMndPunlw zEjwds-IkST#~jxDl;XJNl?|nkYPpHBTV{o60mM^4r)}run%~$&JaY*6{o@ND30;#i zfYxC(GJ;hz(0QUVN4v8A`w&o! z&4E%s9{tiyX6lIGEsHQxmJ_hDJ0q`3Ssr8wFsbpMF zC5%Nz+RrurzDCJ?dVn(Gr+&qJoep{IGokj+8HH`H^Pk}@dIHH#<3V43y^1hGkdvVH zS?M)i6VS)Z@DHyGPy?O*hTXe5PfzJlD?460vs;mUzvaiSb84RJ8$iuZW_@=~vwmR$ zG8?K(r-km@%HnZ?_+g=L(IlY#Vxd-8H2k0i=wF4s_F8ErKaai0#nL{C1PGt0Yw1m7 zA8vrfZ})Yov_DElf^}~!{p78FilqkUuzKbZf6OO8Pn3q!csWvr;fJPW5Z|@#C{@a* z^4u(vbcaHUFrrmFkew{k)Wc(LQ z>RR-}CulkO2D~lE zzeT6N>l%>Dr*PO)wF+aeDmy7(d!QdbLr8oy{3W z5R!##fl}|3M;1?9vA>b-7xKn0S5X(L;}>_W*<6U5^CA zI&vg_BdK_|CMR3jrVT;?qz|VxeCwL+0t9bdOr}-V;UacJKbLb%Kf=Ixdf$h+dnyTe zSRBU)TclSLAW|d`La;qt1s>A*=RoLJ%kVrJrvg@hLekbr0hqU$UR5#*g8f%xio)8u zwWdJ^!SHDr$UvJ=ywoB+Ec2jsz&&`ui1U}nA^^sEVz^ikq}ehmLp-t2Vd&k16`6=c z`T*UHFRPM)G~;X1OU$zfyv|$pe(xZ}nxBYlD0207YmM5CSN7KnXl$!8X>dCN1dT!Z z;G)DV#uMAu(eMwl2T?|#Z9-J_kP-NMjRUT>HIx?Zq=$cv0jS=2DGx8Zi2csbW7<`9SUUq6og02b&So~KuCUq3X3&ooZ3CyUav zVDVXs-saOJ^707kQ8;W+nlVg{PzB5O>DyNr0YvN!riUMMIJ8TXbfK7F^8}2W#`Bal zzQ0D$>26)moVoO-GGK>m^XjCnQ41!3CB*5@OusOwB|AT9Mc17oDgoZTeWsg&gk=2| zcrJ862}%*b5pxyc;2T1tX=f`k=s)}m$z%U_Yf++ypP2!kr{-ESnHphxRl!X|LSo5G z{%ELeyuxB8WECL0#(R+tYNBp6Lclwe|Gxn9$G|TnBsWNcC`m}}k^GC0|36{U|9s^? z7W{Fq`KH%DOyl3pzd~Q~;Nmg_~eg!kwl|o^>innb%_)+deO3j7^ zB77o>1J~ZG6kgifYcN6(hq130ryNjEQYA#fhm1_7u_?^EyirlShrbj ze&99!^_Ha5&*pSdKcX6=pbMHJt)>^IHsd(unc|V!)LM91{{wLa_54E>qY%k_T}7_` zfdE*3m+LCyjcU>hR*no%v_e-95zv#2XAlqb=+a%==(kU9(VE;NNMVuu5Yz|&M`&YR zYQF%)?60AgL8i6D4^z7vo{UwtiQ$lHp~L!Nd2#JIXKc@`H71Y9Ab2<1$hbHJ5P)2=4>x`mfP+3{#|LQ~0d2o5gOD@mCF`k(^q zl>iAw^4I_{xGy-U2|6RnNGo`_7wR=x--=Fah%_m0x!phE>~G^(;lm?}MjopgdrgLT zV2uj!pWp9ysu$^()dDv$zVxDie^yX>v&j5J)(GwC^v|GY7Lg#D2N{aj8*Le583gyb zj6Tv@r9LvqTNV``AqzmY+xs?k+cQde`Q|4!wGf8RzrfaKI9)1BABc^g^-gW}O@b}< z-^ww_<224=*p=T$@B&~M1zmp+G!`Sp6DWPMdj~FWGtC z)ukthXE^LNDp0yN^|K>x`ZApgGsDCW;=(fTPMx&mF|Isg|K0zJ>I1Y_rKU0|2*0Kf#G|Bv0#-jcdm zd;X@A_dVh(od4Q7!9%qy{fWhNJ)@j$o~=%ogsCV)NyoGOImeE)^rIb09uvR7s7|ph zOdoF&qcEq7n!jqtz)n8o1sKN!gTq$Sy)sw&0SJq~=*duj!Y<_Ane{4Y8>ri0WkVaJhA!i-`4v^epx};U98kU zdNgpAF#gv%qmz9{PhMcQDGc|U@#efs!sG@-Zya1ggGPE0MuLN?-4-c%bc@~v%>ww; zZxrY@a)Dg{co|MF!~uA6Tt>1o^DV){X37SDl46naE|=`gije4vkRf{KU0*zC?M)LG za%T2@@^4#Eg7wE+%=l|U=6LHAjGtG&96Ytm!|fPQ7VQzDe%=7#Ki?cEU^mPjSzb{vCHUr`9 zlN>yVZ|0)!g>Pf0ANnBc^ypPxiRW=1S&8LLpr?8}uU_qjUY;-d%R&II47dwkQXQvCacg9kvZe(!k<{aLu~orz2lSMlJB ze+Nf+3*$|v*+R3e1|oWEBEw637+yHXm&f^Lo-<(9?rIx7%&cF(!{>#o@8&uB*2yVD z*ueF}jyBhyW+epsw9NolgLW$vm&Ha+=zOvr*Bbc#9SS9987z6k9BX`v>L#akjUBhU zcty{>N+zpY-ttU|In7w5)@@Zn&|XuITxc9SX87qFYjf9$+bD~)D{qdaKY-Z%N-d^m z0J|+djJWvlWoB0?0DTeI6p;TO!AC}DOGoTj=wrum%w)ecd+_f|J zx4u;@fs#{R0%ypjba=HxovTfE^`y NE2kz~`sUrI{{_Y#a{T}R literal 0 HcmV?d00001 diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerVariableViewerPlugin/images/DebuggerVariableViewerPluginRightClick.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerVariableViewerPlugin/images/DebuggerVariableViewerPluginRightClick.png new file mode 100644 index 0000000000000000000000000000000000000000..099a98a6961a21995583c6a6deb3d0113c323c1a GIT binary patch literal 26683 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�cyTdE_^b=FY=UW zJ<{**hQ#uE4FTHJ0tOr;eJs=)tmNQ@N3ZQn)@){s&a+2VxNa7vmiP;Y#;E!fw4uzdVQ18uR~%4dfen1HD#`A z38@9xY-G)9!3`Kh;LTy~FF?M0ECWEc<86SRLrcI{5CczPxp?$fz&V6e&joKp4*d@R z*o=qU00L*ZL(D|!S7~yZ1|Wuf01EQn7&-<~?y>}QH4IE&hr~?*fGVIZtfC7eJ0IjP z6dIG$tt9mkAao64f9`mb$n@W-JZ(K3*10uv?s`z-I|tZSkuL7`MYmL6T?*ycFwc%d z%%FR?@)*?f+!pRTQ3FW*8H5}4h)h9eBwj)NcQI3D3GW5p)kI!5V=8nwaM`Jt-YrB% z5K~J#h+X!C^GHa{zRm>p$5H(G%KSNXI2Oz@|B^bnfdT}f#2%VX-BhX%j$@nhdOT$!`qJeWPo_9^0>l#R}hchuM*T@fL~T)9$2ZuP}qF5^@lTQSBK2 zb`Fb-FZvltNt~gH8xdm@^0$YxxDXB{pqKqrBr_=I(zqVwBHB0{HTit&ag>PYDC@}O z=^kTRco%Gnf>+Qh=(^KX^eM4m^S~_m^W9B^G8Xp6GHDMWjjpU%t2C^6$%Cl#fg!9d zEPC7hFTo6ZB1CF%tRwBb9C|^kD4$rPI=i(@ITvFO#y{c6#AsCbv$;EuJNz1j8X1p( zV%We`nJVI;c;@`F7tcSmV8Hp>*2$we-Va^E>|$^D@#|h!z1x~ye;!Tofe71wiRtGK z1K{iZ61Q3;vkW1ZylFm$&M%SrrLXxLYV7>Sy4fpFVA~Qs<5Q<_`GO)HCbinuotAgC zM@PLL?_U98Sl3l0^PxB27+)iX0a^Eit4=5S1W_mt3(VgSHg;roCpw|$z!9sGm49LO z@}nNwYtLE0_1^-qnAiTZ#=}z(>4O*?I!ZBV=d2~KQ3Np!R4m8Y|`%~g;tETI1aypFkS;a z^{i<#36yrwd_Z9C8@%*%LtAfT*9d5faI~=mdNS-`SSO+PmPsvU}9_>!sgle z0NV%>QhFf$VXf98-P;l$x@$Dw44Y#PITd-l%53$>`R4f@40`<V5JYwpJ|z%PN7D3fLkTU^c$OLBG$lHIo;dSH4|P; zeht{W<6Zuvk(7M;W+|agJn|`gX1ss*%f*@?M%V9V_sv2+EJ?7ZjpM8|3@)W|@2~Lp z0^9f#K>zR0A?1_3@6XiuLOs?F;qrc^3os4?JSO1p$@7pnv2UTf6Fbm`Uu^|9K-@h| zUqMYXxnBL?-<=vIRjln~hKdHIk-pWY#GNHvEq@Tx$#1mk9Miryr@9U;cQZ!!Ib>r2 z^}6f$(i50yF~)uqqK&8vdPvikwwtQ0u}zn7k+YB!;4i zqKV-SrN%l0HOvXi#h=G;+}{@r3bCBV`0jD?hbMxz*mTiAOUhJ>Qo^F5Wpb27(SEM< za#9_z^=H`tvonuN&5Mc`F{d&V={jg>$_t>5v>G`f0&4z+smCRzIPjKMpopl@Mq#bh zPIcVg_!^{Rpzh;3Rs?g~?R7u9$Q}M;qGVR@5Y$67{cE-R!>31LAK8w8Q#t*@D3g2$ zPN#i0@yOEuY45w^ss8`IMRt+MUS(G@GLMy0R)NUDy41-1qgkuKSPszu%wLTkrShJznGad_7;xZjglA>g-wl2GNWt zq}_Rd<-Z<@KFRT$1`nQ?r#_7bH*@J3m+vnnP$s!5SV!#CRJ(i@BubtGawdxV{M+7m z%aY;pRZTny8m zIq8(?brV&FBQ8|C6U+&cQDNuO?Lr)TQV(-#MklrpJt(!L57Hv&%!h5Q8q9r>tn={l zZlZA0j#}2JZmwyo>1e;B$c=33(MBa+I*C>ZdW_OqztMy0Px9Y62Ske^Zv&CQ^N_-^ zJ0*!-+O>GkfG%+(Un`lk$3We=T-K$JUz{Fa0zS;fy!}i7`nA2;Q-90+xx6GkjguvL zk~qI)k#+E!r3XBNmonVb=PWYk=bl}|m5b1e(iM(9DY#BS_gr96&|Bp#r#{i^NJ)>S zQJuS`KyY=f4zHbWQO3D`B8HNcD`dW^i=uH}TH0+e1p-#eLP9N>urD%Q#Wk3YkAUv7 zHXhtcl`)zxR$LD1B&pBLZV}+wXoym1#aDGrr<|ZT+d^$UN1*L zuA1lxp;rH%^M^^V&76$>GBZ7;x;NJqZlHzuCH=|W1~uvhcY*p9PM>R}?tM^~8qylR zLu$EDoV+USv(lrnio*=!Y;@9xe%ctah`QD}2Zd;j=zJp=@Hv;;r7DH)qWlds+yl6r z?+`*y{^OUXX^5_p5&gg|Gyk?RX(ea6%AF2Iy%eZGp)B{oSq6~%4cuZxH7-#fAFn!P ze$bMbD4$<3C-{QnYf1;W~Z9pBqcX@%~3Wma(U*uYu+=D_6?xXn!0{wcw) zC8rH}8M?>+(?yM{$jY!>xYh%fhxv{u?VAXR(Eza|mi+ezVys94?>szW=s9%k8CTPU zIt3l4u>3D;UVCs$-oX z&aW%%J0S$On(7WCP1fI`fMSGWz{MrX<>AB^Fq9HRei6$F9TxBO(?`$&Rw()6h?AiB@Z`~;F-U-&iF#e1R(LZ>yx$^e32 z+Dl=FhG5!xNi;<{cZQRO;ayH?6gBDN$S2yz#PugyWFw`@QexqeatPEkcQx9cqw zs+r){K*qVCc3=s`F6GRNXfZQEl55!D?O5}J-Qr==Am!tT-3CNC`4KgDTEwFE>FhD* z&xQAfS+d{m@hSXjd!YL=LcL=iG69u3otoSL-Cgq$sOM!D4t}b~* z@1^%pT-ChVIais{d0_6BJN{~wT}<=lMC|%J2`GjP;hC7=LZNhpdd9zK|C-nz+z$Ac zK(d1R$u_nSq(&DTL3C(Jz=Ig{K1?h3Y=rq*{+fdSyfAQ@HKila#3tWkw8d2^#Tr2` z?EM7BK>*au;M{=d&HS1`$WD=pN6zOcyz714G*fo!05O1Jf1 zfG3q-te@;dYYAKmGUD{x1klF=nd^z1VVf3T zblhX6d(jqY3LS(}ld_zk;1=dB2)?4sH?Db}C{raM#Srhn6p^lAca#H{#@c)p^@$yN z`a}(q^&q%Vr9aQ5$%b>V9i!M)f!i?Er!8jkN;vR+`wsy!BREivSkAqWdnEDvzQ&j3 z@lr_N0i|e=^N6iTL?Ws4O*>I(x+0n2II{UrH>j#QV4+ zS&!=~(XdzsfsH7f#i#@><;yME?Z;TjFkXV02 zl%%B$&HinY5EEGV=w zNh_0*o9Re9JMMG%0GXIqUJaqf&CJBNNFRr>zbewAdBy0FZ-p&23Nl2QX z|HtIO81r+acIxnDP}y!{D6%4 zXy1~djz@O@whq=?m+H6|dfx(pFUkD>I;>HzO$^QT?uTU2(Gcrj+cW$FfjdVnO8>Z@ zgc}9gY26ZCoP2*=#OXjCupd;90(wO2G@;NWYPvHPzivMcP`7Di&&L{^RT)?eSK1xT z$B*-cHcR?|2Y&})YiYP(P4L=m9~dOqp6O+ySG`9PuwHS>;02EVf(iorN_Oe}J=kKn zadD~^?{3t3s>QaQBBV;_Lxyac_f+?n7mRO`+3OogC_LY>(%|CiSaeGBJ_ zl`q#HDdE92N81lRz48;V^PWXQ(}J2RKbn}Ho?c4Xc9=5{N`7jcco_aTqD)|=)jmQX zE$>TA423E}L}5Q%_V)YZh%+E_Pk!+crQHpxb*LON5k2^Vqbc;)PghH$yP)1Tm6-Wl zlz{STTgjDdnttT=EyYMT3E>xp0SdkR$!%NM;_7w_)QNrr%VvVt2x?@|BG$HjmglIH2!il%1FhbKAvP_@kJ zQviPY?y*zfI$5l%olXJuvj`FSPw)T-%}IfoG9xTDG&Dp`LF0%NI6-q0b$NODzB&)< z0nr2;xMq8Sz@1kVg-pGoL2uZcioLOlJFA~dr)bUV+{=S0^n-FS7`d)^uCmmi>#g97 zT)zVHJrHhOYOKW_zB%5uuEXo=n*cp$&I%(qWluY`(%0`@GE1nXVaObdvJ;qqXxxH8 zxp+f~Q_kJ9?`{>Fxi87Y&9UVxT{8MS#9zx)TtclwH`)5-m;XGKt^?}~<(EVaZY*vf zLfgINV2BkIfl|9<({RTkty)CQ7z0Pq0__v7>g1h9m>WMr@4fp1+85hz9wz&|zE006 z$19ZSiJ6V>|7W;bD_&ty&g6}ZRn!D_lH@ftSI5flA$2%NvL3DA8_8Fxf&iype{y7` zapd?SkUZocKCjeZp#+OV601Wg^pzd-pLy!{Xr3~j`g1=x$5KV#Qf)u6sC4cHZoJ%8 z-u&B<9Gne@MPOU%3H7fnKf6!OMl|cb(B^UM1&<-n)>oii_PrD!R-1;GJ8*C%exCO| z5%l`1_d5aCudq{Ob1w1uJ;>75Wi(+`@|r%71;DDBqZbE{%6`vV1TnfKBJQU?Xt%!l ztS2j9fhibP!qK!=8pV8vnROk180KdlhDhfDiNP6G{r&=N7HOU-!)j-Pk}EF?Pg^x# z&XO`N)>kEv=2z9Vx)V?}Dw`aK?=S~Tee&>#%BM%XR31Ac19+$teho%M{;XWA{XtSB zV>Z!lJ6JgmJ||<=ziW5m(H7KrL=EQM2euI8JIwPDzD3t2x7E{9mvQ2&iW zLDO8l3>lrQW@2)BVD{)&K`j;W+pEAh8Kxy>hpk`n`+gotEqe?o$Ieh@@(z|5X>iGc zt8$tIJn9f?kxw-@+4t7}G!OY7rYrx?!;&vWQ5<$y8hf=q&%4y)(teA+&PnLt_OD-M z*P{99_H!mBy4O3+M1&RuxRCnN=wD9N{+@pP1>z9P?~c+e0FO*X>mEZ*VRrx+q(~RE z=IS4h>UAU*n>Vf*vx`KFgXI=c69O(4#J~QA%?oAn5!V_JW64$kQ0 zVo_gNX(i#F=Qip5ciAF*wF_gv zj&)0DkhDtQiap0@_;$G>yb|yAFHSu;>jTi3&`|sy(iOvJ1CXU}fW*u)Bzsd2M zhU>{`^XlSDStt|JimM`ibAu+5(lJ&|{@0O& z-9U=5?x&}-U2gdsvl|Bu1upb}J*`Lu_~Kd9NM2C*KY4bYcO$2wIm?j^-qa-~TG<|H zG?NXeKNC>>7J4>aUfa6#-i;W`ENX~W{#W4L@a?{Ke=}@5r4n5eDdGC48tfhJmmOFcK)c-$iQJpZP6PKY@z zmvt&eOy?DE`N+r!TEw?mChkNlBz#lQ=^zFEA1wgD(TnGQ43=jgY393iBy54qkz5q_ zXI8)@`-Qimki6I>B>*nLejGc|8B2LG&GXN!$NE)^WA%k*#C-eE8iW|sAwRYlT|?De zhAoI{pkpJN>VP|1!%{6b8Iz+=1$2EOwwF9^I}gFiRWT?kKZaR;BVsZ1c)af#3NU}= zjG%956$C8Q=y zC=seqQQwt8=}^u0NsIN@)BrD`If|_AJ;P#g*?WsYnBpYORigPU5E_eWvXyxVXpR9C zC1_`4j@wr@H^Yzj_?rTYl;{#|Sm z5K)V0>Qm;Pk!->*%za;{f_{bkw4+pnay+3W-u-Jr{8>A|Y77%|=+Kr9Un98Z)_he|DG7q zNYGlNu8FWt(^txD- zoU10&5|<+TF}VA(c`9v(+Bub~<_=h@5VuJEZZXTxGKIA^q`ikWjkVY>D4};9Y3P9D z#+KAY0Y4>u-B`=Ip_-AJv6^peH*Mb&w^VT~<`c!*)o<5G>OCbl8vS*1lN}~Ga`A?B zF%?Z;*Y;_GaL3v~ohr8mw^wsx?cL&sq8|E1RfzfSq>QM6LWL?ZjR)kcH%?7=n7f=TMtFOMZNpwtKMd!g-UYH#n8=1;oS>v zB{y;le;4o<4G<0F3e`kbwm;riX+psJMFv4<`k$<1;|aH14L(2Fstj)&20lC=B#0<~ zrQA7s(ZA?>RzA%rwUT+sEykwQCXqnVAgIIgl$bkYnLrHg)c&@NOnRrV4VhGty`pXl>o;{Aye5|&Ea6vbnQDrP7H$;n|JzqF-{T;rS#}p3i>(ClT)Wc{38jK3T z#mT3!rs5i+Y)b1VbSw%6Sp0OaQh5d^5mq%ve%3$CP8&eu6nPQhP(EK9p4HyF1nout zd3vFC@i?xguT(;S?CPc`J4~F)CEFegNDh{(!h3Jr-LZ9KohIJ1RH^T*aB7B?Bx7C& zpefgHwQ0}R4!u11N&Jvce$^bCY?9G*KJRh?Hgd=InSI3V6I$7}tkaryxU;>QnUX>! z9d&5j5YM5yA)Yg^0}fpkw??48ZTTfudYw`rb%^HzQlC~emvk8(zP@vGMU{#i>}5Fh zacI@S*m!5h){gb2mLJtJZHze-(4nc`MZpU{g6;#cApA)S0qUua^B+dQ%jiTYfY$&0 zkN@6;f8T`v%X9d(w~%RZiRlXI&3nt8ta)!_*IrRh#?rqje&O}v-COm;j8c3TG|bqR zpT9}EBGhxu>8gH;^xIj7t{zF6if$cePD^z_o7Ha%B;2ywv(hF#qi=?WHERD3m5xCldaGco=8N`DI&z7|@nRmvxlKiSE8D>ak;oT3 z(GDe7n&{@cO!1V+#;#W9xm1vPAorNb0@-a{H}ydDf|~~6ADKxY4{zVSiw+KMytbEN zYTJzo-(0fIFD#7rfLb4lBE83hoEtvxU?sP!mX58CX35&xbj05mRJinsOI%t(fB0M5 zOLYz!SB)e~`Dg>mL<1!Z5&y|+$u4Wu;8S-u+RpCD$hl6a)SFyiz;lQF-mJQo{jOMi zJm<$q1LNmHozL|^umtS^3qT0h<62!`_m`59ah(pckc1t!I}M-kt;}$h95wpK_?_PCa8muyuXGCsW4O)mn~yKluT2(E85M6VQIobviwcCY(GB zps?byGM~>z`2(s6@$qi}0+s4|Dar;XDZ$)=;XY0N@?`*1LVk`}HEOANK%{Hum5;*R zx$AF3WH4_&9uJxc!_J;_`XNqge^+WH@UvZ2n}g)NE|j34ddrPtJxkg1Gc&#K&$1o+ zO%r_i^22K*$;eenl)Y1#6R|l!7P@XJ^xEBT?2hlT7L^`MlnXPH>`;E0Z&T=l>{FHn zPReW-wj#EAWu@-k^V*PJxpbi_?o8@1et1}F8-+q8rl#I3EEN3EQlbw>Q$e>`h8NPy z_O&RaKXfRitFwt|IsO{puMcHCxS_=|=H^X`I{7n}jnR;E*?!EFulF1$-P+!+f|zN3 zxJKKD?yCblvX0Avw83Q!JUsj|V|rIChmwaQyIJgq#5#Y+UZth`jgP~yb6jM%G-$Or ziy4_^Sf%??wd_&ws6jBV{)9^S@A{EO=-8Ok(qiQkCp1u3A2VwojqEdEJwFxV%#I12 zS`VRZyzS}Wz)wm_ipAq&Ta_LH`SKbbf6iW!e8=<(i~p!3--*w0VK|g$H?8M=IH1+X%7vO+X3F0nxb}$hdj&e~tcUtm;+TzX~xkg|nj$ zOsD!pL`1ybi&?kCEiSr$kVrNeccR^b;)tohShKaO+0*|y0aS&p+Adg^J=?>}{G+nR zxp$r8yt6lla>FjEEw!j{Mb$W^$h71ALP5%l1vwTA_Efij{tyYMnUGn94KgsF4KElS z8F?!2Uuqm!rfS{fzpz;wh?5LhyqbyfyLdLONM4W+v7m2W!*0*TKd{+QdGu`ght8&O z`(1i58NM;!vofQcs+x@^GIBcXd%d<9jIF;`I(~T2T3A^0_Vr0tI6r#coSmFJS*vFd zwEhoFW3Nh2NB0J#4_zuAX(=hu>1Um~ALER;=MrLLk)kB8wONy2^i0|dKml@pH$Fr| zgT8Pf`r1gwpFOo!-CO8AQSEE7d}W-qrG#Sl3OT7BkgwV5@{H=JJNrcm2%DCNzk zbiZfm1Eg01jq0pVPwHX8QXv(_HbCb7tgZLpRZf+08$A8=auquKr)At@c^?XBw3=++ z>fC$cmrJ0Y4^8Kf@~aI;b8~Ya`78*rGPcD6%{=B->p zMlC7VzsWzd_~*O)l*hdgF-5bp39>6ID@j>dqNmWJ?1j+^$B)~Fj+O;C4g5x(yd*~q zPD9MQ{rD-Os)3sLhDEP))stMegNLUX`gfdhIhLl1UzDBw?40|lzYnoub|*&fH<>d8 zF84|;?<`JmO!jY&M$_zjGs}rnM3FDjLmLIuKlYYGnm1g&YPVZfq*lCfq@SL^-TL`# z+nBmys^4|`S3%idXVik(ttkFK9Fr~9^5nit^renkG#t;OL4h;0FWI%;J5#z?Hy))6 zK9JqOuaymPm&UhBx67#!cZyzZ*V}im$G2XK678b){iZQp4T5-l~|3l(S^%>M$xG_F_x literal 0 HcmV?d00001 diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/variable/DebuggerVariableViewerProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/variable/DebuggerVariableViewerProvider.java index a741546a11..7022e741fc 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/variable/DebuggerVariableViewerProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/variable/DebuggerVariableViewerProvider.java @@ -80,14 +80,13 @@ public class DebuggerVariableViewerProvider extends ComponentProviderAdapter interface DebuggerVariableViewerPopupAction { String NAME = "Debugger variable viewer Popup Actions"; String DESCRIPTION = "Popup actions for debugger variable viewer"; - String HELP_ANCHOR = ""; + String HELP_ANCHOR = "popup_actions"; String GROUP1 = "z"; String GROUP2 = "zz"; - static ActionBuilder builder(ComponentProvider owner, String subgroup, String... path) { - final String ownerName = owner.getName(); - return new ActionBuilder(NAME, ownerName).description(DESCRIPTION) - .helpLocation(new HelpLocation(ownerName, HELP_ANCHOR)) + static ActionBuilder builder(String subgroup, String... path) { + return new ActionBuilder(NAME, "DebuggerVariableViewerPlugin").description(DESCRIPTION) + .helpLocation(new HelpLocation("DebuggerVariableViewerPlugin", HELP_ANCHOR)) .popupMenuGroup(GROUP1, subgroup) .popupMenuPath(path) .popupWhen(c -> true) @@ -142,6 +141,8 @@ public class DebuggerVariableViewerProvider extends ComponentProviderAdapter public DebuggerVariableViewerProvider(DebuggerVariableViewerPlugin plugin) { super(plugin.getTool(), "Variable Viewer", plugin.getName()); + setHelpLocation(new HelpLocation("DebuggerVariableViewerPlugin", "plugin")); + autoServiceWiring = AutoService.wireServicesConsumed(plugin, this); pluginTool = plugin.getTool(); model = new DebuggerVariableViewerModel(plugin.getTool(), this); @@ -174,6 +175,7 @@ public class DebuggerVariableViewerProvider extends ComponentProviderAdapter c -> currentCoordinates != null && currentCoordinates.getTrace() != null) .onAction(c -> { }) + .helpLocation(new HelpLocation("DebuggerVariableViewerPlugin", "enable_edits")) .buildAndInstallLocal(this); actionShowVariables = @@ -188,6 +190,7 @@ public class DebuggerVariableViewerProvider extends ComponentProviderAdapter new GIcon("icon.decompiler.action.provider"), VariableViewerStates.DECOMPILER) .toolBarGroup("z") + .helpLocation(new HelpLocation("DebuggerVariableViewerPlugin", "show_variables")) .buildAndInstallLocal(this); setVisible(true); @@ -394,7 +397,7 @@ public class DebuggerVariableViewerProvider extends ComponentProviderAdapter .getAddressFactory() .getAddress(selected.getFirst().getValue()); if (address != null) { - addActions(result, "View *%s @ 0x%x in...".formatted(selected.getFirst().getSymbol(), + addActions(result, "Deref *%s @ 0x%x in...".formatted(selected.getFirst().getSymbol(), address.getOffset()), address); } return result; @@ -403,7 +406,7 @@ public class DebuggerVariableViewerProvider extends ComponentProviderAdapter private void addActions(List result, String name, Address address) { // Add action for each additional debugger listing window int i = 0; - result.add(DebuggerVariableViewerPopupAction.builder(this, Integer.toString(i), name, + result.add(DebuggerVariableViewerPopupAction.builder(Integer.toString(i), name, "Main Listing").onAction(ctx -> { if (listingService == null) { return; @@ -420,7 +423,7 @@ public class DebuggerVariableViewerProvider extends ComponentProviderAdapter continue; } - result.add(DebuggerVariableViewerPopupAction.builder(this, Integer.toString(i), name, + result.add(DebuggerVariableViewerPopupAction.builder(Integer.toString(i), name, dl.getTitle()).onAction(ctx -> { if (listingService == null) { return; @@ -433,8 +436,8 @@ public class DebuggerVariableViewerProvider extends ComponentProviderAdapter i++; } - result.add(DebuggerVariableViewerPopupAction.builder(this, Integer.toString(i), name, - "New Listing") + result.add( + DebuggerVariableViewerPopupAction.builder(Integer.toString(i), name, "New Listing") .popupMenuGroup(DebuggerVariableViewerPopupAction.GROUP2) .onAction(ctx -> { if (listingService == null) { diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/variable/DebuggerVariableViewerPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/variable/DebuggerVariableViewerPluginScreenShots.java new file mode 100644 index 0000000000..a3aee5bf21 --- /dev/null +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/variable/DebuggerVariableViewerPluginScreenShots.java @@ -0,0 +1,251 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.gui.variable; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +import db.Transaction; +import generic.test.category.NightlyCategory; +import ghidra.app.plugin.core.debug.gui.stack.vars.VariableValueHoverPlugin; +import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils; +import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingServicePlugin; +import ghidra.app.plugin.core.debug.service.progress.ProgressServicePlugin; +import ghidra.app.plugin.core.debug.service.tracemgr.DebuggerTraceManagerServicePlugin; +import ghidra.app.plugin.core.progmgr.ProgramManagerPlugin; +import ghidra.app.services.ProgressService; +import ghidra.async.AsyncTestUtils; +import ghidra.debug.api.progress.MonitorReceiver; +import ghidra.framework.model.DomainFolder; +import ghidra.framework.model.DomainObject; +import ghidra.program.model.data.*; +import ghidra.program.model.lang.Register; +import ghidra.program.model.lang.RegisterValue; +import ghidra.program.model.listing.*; +import ghidra.program.model.symbol.SourceType; +import ghidra.test.ToyProgramBuilder; +import ghidra.trace.database.ToyDBTraceBuilder; +import ghidra.trace.model.Lifespan; +import ghidra.trace.model.memory.TraceMemoryFlag; +import ghidra.trace.model.memory.TraceMemorySpace; +import ghidra.trace.model.thread.TraceThread; +import ghidra.trace.model.time.TraceSnapshot; +import ghidra.util.InvalidNameException; +import ghidra.util.exception.AssertException; +import ghidra.util.exception.CancelledException; +import ghidra.util.task.ConsoleTaskMonitor; +import ghidra.util.task.TaskMonitor; +import help.screenshot.GhidraScreenShotGenerator; +import org.junit.*; +import org.junit.experimental.categories.Category; + +@Category(NightlyCategory.class) // this may actually be an @PortSensitive test +public class DebuggerVariableViewerPluginScreenShots extends GhidraScreenShotGenerator + implements AsyncTestUtils { + + private static final TaskMonitor MONITOR = new ConsoleTaskMonitor(); + ToyDBTraceBuilder tb; + Program progHw; + private ProgramManagerPlugin programManager; + private DebuggerTraceManagerServicePlugin traceManager; + private DebuggerVariableViewerProvider provider; + private DebuggerStaticMappingServicePlugin mappingService; + private ProgressService progressService; + + @Before + public void setUpMine() throws Exception { + programManager = addPlugin(tool, ProgramManagerPlugin.class); + traceManager = addPlugin(tool, DebuggerTraceManagerServicePlugin.class); + mappingService = addPlugin(tool, DebuggerStaticMappingServicePlugin.class); + progressService = addPlugin(tool, ProgressServicePlugin.class); + + addPlugin(tool, DebuggerVariableViewerPlugin.class); + + // The unwinder has a dependency on this plugin so it's required + addPlugin(tool, VariableValueHoverPlugin.class); + + provider = waitForComponentProvider(DebuggerVariableViewerProvider.class); + + populateTraceAndPrograms(); + } + + private void populateTraceAndPrograms() throws Exception { + ToyProgramBuilder helloworldBuilder = new ToyProgramBuilder("helloworld", false, this); + helloworldBuilder.tx(() -> { + helloworldBuilder.createMemory(".text", "0x00400000", 0x50); + Function function = + helloworldBuilder.createEmptyFunction("main", null, "__fastcall", false, + "0x00400000", 6, IntegerDataType.dataType, + new ParameterImpl("argc", IntegerDataType.dataType, + helloworldBuilder.getProgram()), + new ParameterImpl("argv", new PointerDataType(CharDataType.dataType), + helloworldBuilder.getProgram()), + new ParameterImpl("float_arg", FloatDataType.dataType, + helloworldBuilder.getProgram())); + + progHw = helloworldBuilder.getProgram(); + + helloworldBuilder.createReturnInstruction("0x00400000"); + + function.addLocalVariable( + new LocalVariableImpl("StackVar", IntegerDataType.dataType, 4, progHw), + SourceType.USER_DEFINED); + }); + + tb = new ToyDBTraceBuilder("toy", progHw.getLanguage().getLanguageID().getIdAsString()); + + intoProject(progHw); + intoProject(tb.trace); + programManager.openProgram(progHw); + + traceManager.openTrace(tb.trace); + mappingService.changesSettled().get(1, TimeUnit.SECONDS); + + try (Transaction tx = tb.startTransaction()) { + tb.trace.getObjectManager().createRootObject(ProgramEmulationUtils.EMU_SESSION_SCHEMA); + + tb.trace.getModuleManager() + .addLoadedModule("Modules[helloword]", "helloworld", + tb.range(0x00400000, 0x00400050), 0); + + tb.trace.getMemoryManager() + .addRegion("Memory[ALL]", Lifespan.nowOn(0), + tb.range(0x0, 0xFFFF_FFFF_FFFF_FFFFL), TraceMemoryFlag.READ, + TraceMemoryFlag.EXECUTE, TraceMemoryFlag.WRITE); + + mappingService.addIdentityMapping(tb.trace, progHw, Lifespan.nowOn(0), true); + + TraceThread thread = tb.getOrAddThread("Threads[1]", 0); + tb.createObjectsRegsForThread(thread, Lifespan.nowOn(0), tb.host); + TraceMemorySpace regs = + tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true); + Register pc = tb.trace.getBaseLanguage().getProgramCounter(); + Register arg1 = tb.trace.getBaseLanguage().getRegister("r12"); + Register arg2 = tb.trace.getBaseLanguage().getRegister("r11"); + Register arg3 = tb.trace.getBaseLanguage().getRegister("r10"); + Register sp = tb.trace.getBaseLanguage().getRegister("sp"); + + TraceSnapshot snap = tb.trace.getTimeManager().createSnapshot("Start main"); + snap.setEventThread(thread); + + regs.setValue(snap.getKey(), new RegisterValue(pc, BigInteger.valueOf(0x00400000))); + regs.setValue(snap.getKey(), new RegisterValue(arg1, BigInteger.valueOf(0x3))); + regs.setValue(snap.getKey(), new RegisterValue(arg2, BigInteger.valueOf(0xdeadbeefL))); + regs.setValue(snap.getKey(), + new RegisterValue(arg3, BigInteger.valueOf(Float.floatToIntBits(1.5f)))); + regs.setValue(snap.getKey(), new RegisterValue(sp, BigInteger.valueOf(0x00200000))); + + tb.trace.getStackManager() + .getStack(thread, snap.getKey(), true) + .getFrame(snap.getKey(), 0, true) + .setProgramCounter(Lifespan.at(snap.getKey()), tb.addr(0x00400000)); + + tb.trace.getMemoryManager() + .putBytes(snap.getKey(), tb.addr(0x00200004), + ByteBuffer.wrap(new byte[] { 0x21, 0x43, 0x65, (byte) 0x87 })); + } + + mappingService.changesSettled().get(1, TimeUnit.SECONDS); + + traceManager.activateTrace(tb.trace); + traceManager.activateSnap(0); + } + + protected void intoProject(DomainObject obj) { + waitForDomainObject(obj); + DomainFolder rootFolder = tool.getProject().getProjectData().getRootFolder(); + waitForCondition(() -> { + try { + rootFolder.createFile(obj.getName(), obj, MONITOR); + return true; + } + catch (InvalidNameException | CancelledException e) { + throw new AssertionError(e); + } + catch (IOException e) { + // Usually "object is busy". Try again. + return false; + } + }); + } + + public static void waitForDomainObject(DomainObject object) { + object.flushEvents(); + waitForSwing(); + } + + @After + public void tearDownMine() { + tb.close(); + + if (progHw != null) { + progHw.release(this); + progHw = null; + } + } + + @Test + public void testCaptureDebuggerVariableViewerPlugin() throws InterruptedException { + for (MonitorReceiver e : progressService.getAllMonitors()) { + waitFor(() -> !e.isValid()); + } + JTable table = findComponent(provider.getComponent(), JTable.class); + Thread.sleep(2000); + waitFor(() -> table.getRowCount() > 0); + captureIsolatedProvider(provider, 500, 500); + } + + @Test + public void testCaptureDebuggerVariableViewerPluginRightClick() throws InterruptedException { + for (MonitorReceiver e : progressService.getAllMonitors()) { + waitFor(() -> !e.isValid()); + } + runSwing(() -> { + Window window = tool.getWindowManager().getProviderWindow(provider); + if (window == null) { + throw new AssertException( + "Could not find window for " + "provider--is it showing?: " + + provider.getName()); + } + + window.setSize(new Dimension(500, 500)); + window.toFront(); + provider.getComponent().requestFocus(); + paintFix(window); + }); + + waitForSwing(); + JTable table = findComponent(provider.getComponent(), JTable.class); + Thread.sleep(2000); + waitFor(() -> table.getRowCount() > 0); + selectRow(table, 0); + Rectangle cellRect = table.getCellRect(0, 0, true); + rightClick(table, cellRect.x + cellRect.width / 2, cellRect.y + cellRect.height / 2); + JPopupMenu popupMenu = getPopupMenu(); + MenuElement menuElement = + Arrays.stream(popupMenu.getSubElements()).findFirst().orElseThrow(); + postEvent(new MouseEvent(menuElement.getComponent(), MouseEvent.MOUSE_ENTERED, + System.currentTimeMillis(), 0, menuElement.getComponent().getWidth(), 0, 0, + false)); + captureProviderWithScreenShot(provider); + } +}