From 81cca9e325cfbb22a26d141a87c9dd89fc0e3d5e Mon Sep 17 00:00:00 2001 From: Dan <46821332+nsadeveloper789@users.noreply.github.com> Date: Tue, 7 Sep 2021 11:04:25 -0400 Subject: [PATCH] GP-1264: Can modify 'raw' value in Watches provider. --- .../images/DebuggerModulesPlugin.png | Bin 28629 -> 29095 bytes .../DebuggerRegistersPlugin.html | 4 +- .../DebuggerWatchesPlugin.html | 17 +- .../images/DebuggerWatchesPlugin.png | Bin 19832 -> 19547 bytes .../core/debug/gui/DebuggerResources.java | 6 +- .../register/DebuggerRegistersProvider.java | 9 +- .../gui/watch/DebuggerWatchesProvider.java | 29 ++- .../plugin/core/debug/gui/watch/WatchRow.java | 90 +++++++++- .../ghidra/app/services/TraceRecorder.java | 86 ++++++++- .../TraceRecorderAsyncPcodeExecutorState.java | 25 +-- .../watch/DebuggerWatchesProviderTest.java | 168 +++++++++++++++++- 11 files changed, 380 insertions(+), 54 deletions(-) diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerModulesPlugin/images/DebuggerModulesPlugin.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerModulesPlugin/images/DebuggerModulesPlugin.png index c30378df45f8e3ca6fce46b939ac94b103bf3910..a0b9768c8926a697469d6474fac9bb59df3ddb61 100644 GIT binary patch literal 29095 zcmeFZcUV)~x9^QuP^74IkYJ@l1O%j8C{jZ2B?zGi2uLTPi3mzF7OFG>=>ZJABQ2Cr zq(*uTy@wK{-39KwfBT+u&-?%TJcoroi_Ar`)|g|CImUN>Cc)~e3Y6r`OfH=HOhV%1peXxD+Y`E+aK4PTf4}+s5$8Pe+NF>DbtE=dK76=v zo=#o-9PNjw)rbpM%Un$>DuFL8=0}enj~~}q$2#pSFVj|v?)cVr5#X!saO=+YM31RT z>&|7L@EaFj1K(fu29T6-Kkb}vo_ll!__k2H{TKsh&T$y6I0M`S2?^OebIx=I|LHji z3nOz*1eXHh19$&Zr3Ay9vLDzX7t

?Y!Y8WGafaTH9@PfqtOy<7L!DqAChnQphl z4|b5Tl@VW}CY~^``OM5tBTYY9UbloR4xqq$7Lq=jpI!`(Sahx4YCiYqee_Jbn7=dr z%RGB&+z9{X3|w(cF+wyc&Ktb9)!Vvd<14yns`>R*=xeQW=Ve?7v7wIx(<``^(_enf z(w0r0zyGMaE2Dc3%%#iQ2iZ{PhSozarO&uNYSna5icC~ZQ|@}Hg@MEt2xYzy6UDc6 zxDuLFeorZjn)-@iA$tbeHLv5yP0RNda|XBiaSk;{Rw6!HPVdR+csi1mB1g6JByk<3 zE(^nJBi?$JiAs^#4%xacTDiZyBNv57`ZCL3+4ebW5$+b-g1-*A(P#H%Ev2vShMpV8 z?IRJ}qkWFwV-}Am((9CciB7>w6Wia+Qt$R4QjtgJy0Y_W)h^2j>Gpb+TneXwggPL048imL!*Xn*)qaCF z<{P%$2+FmTeWl0pk7NSRuw)(ofV@5va0HupCK?d*f}X-EsDf#8iN5ZqnbEvn;P?my zOHHIN%LZG6f&)$1MJJ(8On7#SE%&-ifnx#0GF4rSlf?67Pc;nWm*O->jm4+9OP}4l z8(SUNA$!PHEsx9TDlS(St!(E(bwvwaoURyUtBP1@7jQ=m-fH$mpwE4~_i=+Rrh<-a z9kHdR_dIIi;FpbgC2z#6nb)O6^ST$lY<*<7^{GkOv|#xPAH1~(4>oXm7nLi?tAF%~ zF2@)peM`R_)4^?(8`r<|o_wH8zw+oV%lqz%aEF0fiw1UvIOJs!2dBc|LB!+l@VGd> zVYQ#Sfvg$I)scAE&Qv#c)?tTL^2t6ORRZ1h z2i{RsAdLqc4_vpdvr5m-wm1b6T({n^>|MC#{9gw*MXZ2FmY#v+II!Xml*UvfjMX!^7JV;1{tWbZ1wJ2P>YmYc)+zdkx^@(lH#gVYjb z)s?vNSx-Q3X=nT^lhImFW4MRS!SCVwRx9?*<-gevOQtSRnz$!i;IC2gVK7dIx_~uH z4dyak<_(zdABX8l)qHo>vKA6{>bb)#=KSs1QGJu^%rB-|W?r8CWc;pCw9VRwRo9mD zYIfN2FxZfDj{YDrFf_WCcw{O`@{W0+L-`XwX}CjZiI%Eo|MX=Z(e2z}53T3V zIXmLTwC*`g$?D~aRtypEtvET&&)ej?Et^})(5fbsKlB@yQLM$hhunt3DqosJ2uOBV zUZ1usQ-O|Ot*~$FNxG-V2MeQ%rJ{8X}VNCZC zThAjcd2}zk6tDfzFe}-qI2u~%C@5efr)D!rJ5Q(7y};(H9!?i65Q3g!1UFc2{+8Dt zq!v+xHAB=PI?bvH#&gTYxN`9>4i?e1_3Y+05mOf*dU^g*=2A=4FKwSqML+Oa{AE*2 zNPjtj9SrzP9r@LOe|3PMkglOn6MHBneJW!P8rF<>)~_FK;$akXH)qO{CGh%Yb~A&# zsN4A_eSw2PM$5!Ymo6no=HR;94GL}Q-vr<1bFH|i=PY${SF>%!%C3mIbB62P3bMBq zdhUs6$cH_C;jnBECgTLs<7kgjI*QDmCZ;qL(N6 zZLGR9c$*H^^eLQ9xl11%%q)zMF{wRz2a@(yQjShcPT{}(jWH)3qSu?H<*~3M{wKEFrC4=MdKJm~jaYr{- z$;%FxUcJ3kIccNE)a=Owjlxa3;eT&^FJK#XUlp>Lj$-XAcd_1x`TpcBRgv>H0!*;< zh%>xx*{>}S6&Bf_WTZ|JIoQSbUHaHtJVDw=Z%Z4E7WXF7NAgJ+HPXW9t`#J?FPCvg z@#(%0Um0>6#mn#JU_z!xusT(Z6x;^R>?>m(`Cj5ex=-G&rjL5%Rfb`V^?Z75@NF*l zeSQn{>!Z<2znoIBcOa>@{q#Lwgc<%5G3&eaoxqeVS^jx(OQ)8O;3>87ZI}BL z{4KGaDJ-I(EX?9;hm1|j2NQEIPuh#H^QQ;h5ipRFr$Eyzf4szaw>ojETW$u5<-df32aXr}N%kHzT{M!O)TkFp|Ps+Wd^<2At zE0Rb{3yb6*eY!EMt0ac3H5an9LM`?=`Fx-DnE!_|^!u|4--tNY9BiVe+45MH#QzB#IWO<)w#9Jc za~~$oIS;A~3h1rTY4aN_HSgO@K%ljdwfP<9vx5dlIz#%jZ?lp~&Ny z>_-7_-=X#8r%|XES|U2S9g(JCkptRX5#0TQefk?l{?=V%4C`IIEtobXq)s6D@wUDX zA>10--<7zegn^JjY)bL>)71awms)-vpe^WF*Q z-ZkcQq~pdcPSnMjtLXZZYR!j&XMd(cqGgS{^eI7A%3gX)^`!*f(~!)UW8~30nTh<4N9vPrXEZ)@4gASe*f=e{ znr2w*lw;Ugt=D!x4qOi68NM&5E-!GtmXQbVkyrF`Fo!v3d5}Z>`MidiIb&jH>{4wh z>EMlyM4!h#Jm2;5?ah6f^mVeU9#Vw(ZO(`#$oM5yxDMVqb(D+?R6}7Hay;e!TNW)5$aCyg+ zx@^+78gHk6@3btNL7-mrwm*n%vS;F9YSQ260=J+)-K`|v*Y!UD#+Ne7U-zDqX@;6f zGWZz~U1*0gRFi(>!FB{G1xY3^d9d~3jr@9WH*K=o^INlieQ4Bv_Ru?9Y(tB=Jd342 z!SJ>8-rY++y&e@OGbeEKFV}i89m6)5cCq_zLlh>n?M4%}bGM;OhD~k0oa?n&aOdMY z+dhYG{rWb?X_P0a#ihpDA|^?T%%v{_I7pId`rP@)7wN)ueuPEtm{u{G;qFDW}tJ**~7ww7#r z=%Il(b^nR0F1aYZ$`oe{Ig0P`P?AmadZS6WdgR0N!OX>NVqHS9pyo>!2jX+QX#Zl2enLgOyt<@6gUtfmqP5&&W8Bunk^H9ZB?)XD>Z&b?QJ3n z=B@e$hvk8;3$$T=4rl(!n#nPXI$@E{XA48BR&zdOdA(2?6u6K(Tsp{OC4a+l(fwrs z+lWNkt`K=mTkeE~4AGCwefd|b8|Ci~H*Z!#NZh1FoUZ@BGS!d>40l0+FV-QyVEqR7 zn!=6JOMgvUe+;uV(jRI-kDn?UKct};C3n+5=gjy1yy#1cIgw;Yey9O* zhuO`~r$Wf9GeB^Wi^L^xIuP<^an>*ssi%ig8)fciVtts$;3|I1ZfWwUR(E>AY*oA zmQ9Mx;k`Ht@8@y2kR-XgHcmE4vH9mSW^S0jl6)gm60S3UVImNx0x$cFae4T~zP)GGJ`&hA*(g{mCz*4saU!=4w_%kh z8YlQe+MRIa`Bq7e9=*yh5#8G*TRBl_*izo+!i<0J0qT&U}U z>3TL<7VYQ1H5lP9SJq9D@L0_ZV-^lEM4I4>|Gfr?)J^)A!FXqZ z;77c^V4J@&JB<{=wZeO^Ku_#@SI*4MEA#ex`MfdT?NJvTYjQ7(Mz|kE>o6=FL;ap4 zII>lIE}-RBaKu0!qQ^p%+5B{)5d30k7#6Bng*8iJjCsvftYwg(<~Dz7->|#G*YfX;zS^68maQy*$zh817dH)JBH?pt0>(Q>8u z1yBrW=NbxM)oL5aH&shhj!q|TOl!qIaLTl3{Z!<4?0c0*{p+jwFM3f408R0^JYoIxRTe-@&cO8$|-SmxDMCm`{GOd%;m!o%O&5oQnuCjj zSL%pimQVp~Sby8VPnp4i)3RczhoD{H%b|4W1S;mW8KTY{o7n5~X|h}_nBm3etV`j! zjZDIu6=U9HyT?70(uF3|e=gA&NHNVp3sP2URV<&+a+`-PR?Xk{(X6^fm)ZBzj*S+9 zs#p|!b}4fO6+kNT)HuCSCcpnn&m1vqs6+bBl#LA61p3&@$?r#!*<5D=R3+w~KX)nH z!f8KScgAnL-gRjRqKpuL$vX*53LarP$@rQh@Pd|YvRWCcX@GaX3nd@F&#jloYd&(f ziy?=GL-i-1Z!82*OMmUp(ettoouv7ohT$_Rxk#Lu61+S1O_8Qs;=9|D?$xe1(fnrL zm?n6IKH9vQMTX zjO)$b*N?V()oe%FoU%*pt8FUFLwK7%X;94wmK#GcFWAC5VR_1}bPc_L>+4MG4rP08 zOcgmz%L66kJz=|nFz1<;NwnWproa1A^~|aU-tK;bX?wV{U0P?$dwW>FSB-xfXjhWF z=4YhHm(I3jsOGN*5|I|HN;-)4it#<%*4rR{eOC7xBp|i3Ja`)s7_kSgJ3+Ou*Kec&Tfg| zM9FoX*txE5G)%!M`DdOry~}F@P=wELwO6S^ImnsH(?Dcc(r5nX&HO!_sh^3-01EP& zwNNr9ftpM6+qyW_-Y@Oh-0K-NC46eb9Xb|bQSHt*rgMB43w`d1Bg^^i^P+eSrame& zRhO6(Q0;|#Gl>H5>USZdk}<`_243ssg)asL-4ch#I7@XG!}2B~u0S zmP((uwTe+1Ew)N=xnDganz4f2smm!%A!NPx`-RCWlqz)Kvat&OP33!ua9rTTZ#STw-a$Zac~1rdnZ}-^apI%)TYy- z-SB47sIeR{8}gC~)(pKB7$!?4#4LSsN$W@(E!ote*FeXS6_yMbsTpDHu~Ki_szzNJ zGIizS}7TG=1DhBkzxWkiM)Omo?nyW~eqcg$AF57Z_@Fta|Bl zp>>z$$83nK*S3LMx1EnPyfaB=?fhDXU@iscob|kOSZy8p=2YIx)ruKMiXqQLN%(xU zsc$kMVW>BS&{dZ-tczMpGvP~S1>bWGPd2}66K}iCxZ=y$RNPB`Kxs#q?SSG156bu0 z+mMvYjmyvOQa2;n7#RGHg4q4sf#97q`h3hb?i`Qq<}-Kcb#z8MA^H-3FDCrGR!#Z( z?U$B`UP(Uq9*4YJShU4mvYIx$C2BQb4Bqb6TK>t!CL`B7Qcin$whooMJ@6S>4a9^@ z!e)7$e8+R2)Pj}}d)VFDg!CWbDJs;XFC)1{)*xJhzNn}sNK6d#R>I?2hYHovxz$uP za=%HmYSinrtkG|j_g$xjZ6Cb6(4-tA8}4Kh>r9u@*<0HCVOuY=gD9MbSB9^gCAfVC zMU=jv%ir|2%;^z@c!ezVxcR2H!$UOJsm%5v_PYv1d5D@D|{w9^~#j<&y=&A?i zKEEAL`8a8hwL}P5lJKxRSpChXl^(`C=Z_jOY6@5<-k5a!?Oo8a?Y25%K;asJg;$ZX z2qw;2&yD0X$%kqr*79J#G;K>$`?*8klO;Pl(tB(Z2#CAT6xmCLX!F3b=gw+!Q;oqV z6Rt3|WLe4MK=LS;uX=C0s|@1KN$3(LcrdWcvcm|4&9<`ZcOBg0XWL^x8 zK;z(LT3!^#vnM3m2Wxep3ft-WD+0&mbV=`reGzrc!>p7<<`?`G1I7?Tg3=yD>j2_M z?gsn(a1NCi^}ZFmzb${9_=!|Bq<+bD=D8W#E`i6I-&7eU{#q9%YWs1h8Ig6}TJmwX zXG-D#=5+?7Zg~fMf22eyUV>~26V9S-{~`!*|6|ezFXa<<&T{$1Dn(_EI=sUD_Ff;W zaJ&3QsO3o`3H+kpEhQ@A1-@vxyY&*(2kC4qyycSIX2bfe$AwgHsJ%BwDm|$GeeEy( zR!fcG^_C|<7SaTJ>Dv&&c7C&}N=3WA1a0VkaONG!dMjal^2wFX8`M|N&fGi*<`jDd zyLrBv(nK;UF1bih8D*o2Nxl%cIlV z1DbQ^*j`^GNs{bJlsfz0OD8%G%F}wz6G+@feYU`-Kl}tr)svGSYCrT(OF!ZzMxN6a znKQ8S2lekXXty<%?mL$#RMwjG!v`#xOA6)MQn{) z+;`r(qr4>0s`c$#`0$R`irQE6s|gRsE}k{;xL06?g(^i$r^blbNfefaB~+LOJ{(}B zUq7;wIcqBOMa1#R#x%#3`;LR1OJA-R5OsGY4@mzqi^6Xxbn&mT;+q+Dk zetZaiU&hgoGD+%$*4#F46G-!LV6+Ec5n!ri%BeZ)o2FJU_w8(RXYWz!94D4z(B{X7 ztLXxPm$a<9_hY5kpWjK{t{0~_xc8ev9!+Ogs+rQL`21id)^)YbL>#e5u9K(P;3^e3 z-<|5UqI?5(m9_fwsOdStR&Ts+5ns3T9ywG#9LT-ly7AHPqm9~AY=VP^GQ!Csu z4w`ZHYrJ*2s_T%9I-@VEH^i}iT=cn$=;~1}#)IvFqG`l&(6u|Balq(Mu&gD9sG3%# zVHkJ~o){EZ(Nw=>8t+m`ZB`>>N?5d8Y{=c&iF4HKG=|$OB67X;C&b)>=-NF)jMLupKpD>+##bqrt(dQH?%(II#3VqUa8ro0EsB6 zP+u4Sq!f8nZ|4(u8MoTYf;NXoEa1nVd-=a>C3fgH1=HZBZ`DzK27{~w(jPUXYgfU<1Ki$#S~`leS3Z&hwZN7@4We0-eaA+S4EA~9<5DKS@5Pb>_ao33Um{i z*IkFHO!|p$*({Ugumj!2Mt;Gea@B0UDa^%-Sx%h|-)vmwf3Gwbxr{sgPS>PER=`y* z`ngm%6F$xhJ0Y~l-BlBgO|Eyc5L2a;YoEbG4jyvEcfPLGSLDQh;7sjTy7xS zijT>L1oyhZRl{01az1u$p>14;0Z4(oHb*EC92(~N;y-dyqaE>}g0&Wdwhsa{Ce?c! zXpT2>*Ag0Bg4}o5l zPpae9O*6E2a+);m%kF(>{Gok7>!(E7S*FnW^%}=<7wv@clKqQmik~~}!~#QcZ112( zmPgeyT(UUABu#Wx6uv?&zB;dya6Z^eYzF_McFU;6^LN2xIkz!hZ~3fVuddDpW1%S(kqZ!+J6<4yiNo6I;3iDzH1g^ijgsm_Hwj8Z6Ut{XxMZ*2%*@7cVdb zy6&0sHG^b_qlxp{ zL@rrZ)8(^>r08++Ni>_cM)v?8I75%Vf6_6+yKq*)T`AT8TC|dhOIM2hT#@SBiT9z* z5zwvnWx6xuy%9pGUH04wO$p+l5p)lEXA|ATnDfKToqCcXjkvK~s$+-9#RlNU;T#`Z zkk?^bn~p`*4;w8GtWaf_<0=i|6eJC)bH%9(K1~+?m&FH)txdDH?1i0D)j{XEVUquT z00ur?O;*PSh8L@=x>Mf0@!~LPlUjmo7}vxY^~xNdNlBIGo4RU{_oK-T(V>d%5{_s& zH_v+yOeu;jt>E1ysn9rXOV!2qZDP^8kz`yf)pVR-aFmRJlwL{^fxu#+?m~-HaG71|3rxm zN6CX~_1<)<`I4^N$>uEA?ceEI!;7RGPUWJTtOb2fhnPHPb)-4tZxt9?HIM=5nI` zV7y9A3QUSq)C8KR#0>B{cIk)d>9l>3(-}!hQb!R+cQSRKNWi2gC+jpN;dFmcw{KuZ zo>KOOU-l@ML+~y=XA;T zJKB3|SoHj+LzN1UkIj$!9aHM_7Ch~I^p)_nCG#XyRTPQpoAzFXkWquaUAwFF)5x(} zZlNbF)uuPSHB?q{v&P zk}gniEdZ;dJDi~)sfy-L{<)+g$0dDRjni){P3-F$)KGXiW{^Q!4q>OtgNnd5`c**ZDw#)!Jt=NEo&FWIW( zsTpM$uOjs=J|4h}dT+~zeJ!#9Qi2vhc}mYvOUibVo(1$|Uc?eHX3o;b21rOF_>4q8 z7PiL<0ZdXR^Zx!?ZI(fyRm%H2il5%u@DuLVv{JE28}n0<<2w`L26Bx!((%U6Gr~9P zHx;Bbgljj&+Hw7OY;+Dm5-_xH$F+gGxD{>XXkg6|q5i9FzQ!oeSd3W;Q4~W3U^d_y z;$sulfrhu#a*n*%zfH2eIvQu&pM95MDUoEY_E+}8-aiX}6^e<+GBWcPE9YcvzaW3OEK5_{!Fm?kdCR(JN!&ntp%@s+n z9hG)$`A=0Ae3R+6Z2v*qT)|jz)G#i1rUD=ah@&3k!8?PM9$@?75{QakJ~RO&={bSs z9ftv9ZCT^Oc_^a!wez@?$Le*)vzf&&LY{-H^#0wl=D zCqWz}q2L>iHGApeNzy(DarfmItKj2CWN<|2b&ul>*Dyu_Qu@#ro7N!B3{?m&&xEGe zo5ZEMAZ(FBmN!MYX3#dHxcUCv+vZBnDcDiV$J>ilABo*m9%`mF-Ud{`Aet5TGSwA# ziw&nvQ5KOa6yssGxI8{E{la~-`g7U(=oE4A++zv*2nN4?8XW>p5_ZUrZ%HSw*m=}& zqr?69=y0l=WB0-4^lcG!N$7i+p;MPRP<=|Zef@!5uEClz{-W?$8PehF4Iy;BT+7}3 z)^zF%d!zc{OhWQLom|Rm=O$KHc?}AFF6GzeiF`-_wAtXes>HAn*bVcKkfZhn7RRca zR5zr*1Dbrg#ExRVs@zG0YZWzGDcXsdwUO?mV`3!~5NCfl3T@oZpkM-W2g8p`A4_kC zB7LOC=r%fb6FkPcd9R9XcZiO^D^;dzJ?XvT=-S1P1oLmt+VW3wKf9GJeJ&iQR1vVm zlGJAdx}71c3YKz!g|on?#id?V?BvmYu_ zq`K5fCKXy6*^wk;>TNV({cXsSI6S&B-7Ktp%;7s$j@Y(!gZk1huIXERswMmwf6pd` z_+~Iwat@9f|A**ogIIeyYrlL%9}vEa)e25aX`xZlb&zv(7me0p%n47 zPj8f&p8=rX|4g5e}wfOf~oZYZ% zW4vDT!LAvzUiJVK&;YwMBk;i43y5w|$=Qi9@*1w^Y~4Uu?1oWLA*Ci59?`bCg|o>( ztG<5q(Qb59l(TXIqr5>a|JP&gH=O+#K1Lo99X(ep7_xySJ$r%TD?8-NyJr89S;^51 zH8!NeM^uH|QivA`ZHZvT+NRnY@AW#eTgZdxIl2va37lZHk(NYgbNoRlx70lyb+#z! z!!0d91xhqVDFI&TNHucUR%=-=k!KP_?d==*$xF*~J#9xv{|Iu);pu7!>_k{=^<}z0_W!Y zEo+|B!RI4V3J%PCNwe~6ev{W$QSCwQ=>iD8`oks+cS;=3#m(qvsMB2J^}(HgGL_a6 zbWi8m)0F1;L-n=4vYRIs`R8EgPhOq4GRRZ+N49t%yQB2iiZ<29|Go5oE%3h<_+JbB zuLb`9Y5@yd)JcFRdF9B<@<)z-#`?D|oot6HyK>s9-~3bG>E`L_J%t_h3XIa~*lFQQ zk~k0N{OfwM|LHW7(+qWi5_IwluQ*>XpCt`Ud>e8N!)?*`dF$R0w?*dkQB$AnDN|n$S=%e1{t27fOzku8 z@%_Du8`XAd$vb9j^E0sw@X#FnFxqFic}Cp(pbGap>{cSM59DOt5Z+m!EeYctj)g z00MX-3WP8h*rIBf%L0ywOI$0Jo3D3F;j6#*<99B)Y)6PB9meUh9b+v~N69`o)1P^E zU75H|Y@gM#15%uJqsSiC6r?E6A{0lZ_Gb#`v~9^oXHN*~;?|BKWX1q-+CS$yv3S|6 zz}*xfZ`37~R-6Iq4UF>(QFx6^l+1|RJx=*#BI?zb{4Rr)iKkqJ`mY3_URgK1Kl-eP zMz5S`*1*B|!u&Raw%;DBZ5ffuUg|i)9qP@F$Q`(T92&*yBdbhx{D>MbT-(mrtj610 zi90#y9wDt7MCtp)2MUn5;*{MnWmTtXOlp2jmh3(ih@fAqkY5vV$3`=Rp6?5;B%b7t zVKtuUhV`%BX2{&iB=kA&*=Gw)dx-l^vt_Rd>evsAB(u$qr9d*0dfs1la4BBhf*HDO z3XC2Tm?BpS8&W}XlB_Rbchz``Y;YepXR&HIIQ#SjFRC5}Q(a)6+#(#MwM78P46JGc zV)>sB1PJqyq08EKV-Q>PGQE$?p~sN>EK|b4q3MwOs#t&QG=Ki8piymZ4fsNdqu3nC z#SLePYTMc=M1ShWw5QYcq(c<2x_Mf2r7wn`w0^3dLw62Q8c7Xw=QLBDrdd~Lg)OX5 zww*PqD|%zeYw0Gbxg2agPSIK7ldrvUqpl-VbTUjc20|TsJf`!3ZW(bY9&O5f+m&gd zCc^^s2zb`c@TM+GpBB)ZA8pNdH%&_)<(SO1bWlgydrxY}WAFURWRm&IjrCR+?g6(-1(Og@ah0&hF~+R> zHa$IGwvDRVwg+|@{&njyCT}~nCRaH!kNWJkM)RZRTZ;WMe-rJtrrTMxd1lD%r4A!@ zDpmTS43+%S843Kb?U_Lt?J^(6YPxx>el@_{6uIs(BQ1wLmLKm)cYxb=*(6m9=lD}@ z$%QWDIci&x{WB8GQ88T-ju}G@{F>$d3|X5!9NNA!mfSr+_s8tU)Ic|7*Za-&_LPqh zzh7^b4$YtV8Wjz!>1_XWWB8H=#__!SavvnDID}3@#AmC!IdA2CzsY!J`+s_(U!QKF zEH-b%=P^X|_{nG0Ymf(z?(aP4=ERME%&Wa^Od%t`HLQ{Hdnu_mNi9)p6=Ns0sNUEM zz>gLe{%Ch8K`7>&uAvtxmrIXR*hCMW$e_G#wrf>ygU`8{5XSSpRNV%oGlnEzTQ?CPU~}QgYd_BXPp3*a z{nM?y=N=7MJpZeLxUsZpg9-{%IoViDLLvgF?}lolCsCV(JOw|>c))w!C4v9?_xKz=oc3s&XiBgFGiUcr^&0 zBhvG6dT!xYYv}ul|I#Kj$KNvv%XmJQ7*OPcJ7csiUd4~Qi35OIv-3b1bEE#{3Wg7{ zF~x>=wlMmqDKHPcSh~)6dZ*w0)c_{L=Ct}D3EQywYd-Y(%Qy#blF^?k%T6zS#ZeNb zQ|d7K=Lf2i@ct44^`j4UWc7r(u18n=<1eta*t~pQb%70Ns_6B5bt6D+`2^LyK`KTm z{h@c_9Gp@bSU$FFW;<;H|LAc4#=D2A z0n{`1A3TBvP!D6cU5~53&J^RI1nxo_YBlnREMDg(j`?{?>*^`1bwsJ-I2BD9E51Ol z4kcaa`Tbgy*m<)jo-=)&doXK*b+*ZmdX+aycL0zSvsROXouK33Oj^3Y1~xMfIn=%0 z7QZB9E9_mvJlEK=^q@{vDp>1V@*S=oMC6j0ZoYw}3DR%H3rk10-ykYcHeG*HypSN`gx)USU%gRNAqJUHV{mf%HSP+>iQ;Qo0IlY(obk2-n))tCz406YNCrbx|-X{jbH!!tDX!suzuOgWIbcdsWGQ`GG2URzW@9oAi;k< z!5Oy}db#|L4xm`Eo2cP0rFwwOe6pccue|ETy$PO-19+iD>thBmbc^#CfD28_`Ib?R z)&{YeQObPs@JMVuY4yrt}DZv`^0DFu|`73p^H#tW!Q`Mug~ zo|3qAfJ8xC`XPU}Pi^`-4gSB`UqzFQ$q(=?Xb_TXmIZBW1-`AbCfKIgPA;aTodT>C zWZk#zd#BWIuiP*GRz1UDzbYzvl4id?@G^9LE&@A4oTv-ndJ;rIE8+g4EsBo?;Bb|~ z0Ri*`*?j~kY8fZ8IRH#RmQeo{?2YZWrk`7=@!8h|WOcc*vgMI-m%eNr9;HM{v8GT4 zB)3ksEFkD>;U;$u)*Gm~fC;jGnUYn!Pm{N5BeGX?+`D(0&>Bc>tXa)nor_0OIz$7TLqlBj2kDRd z&5Knhf&n1Z`jF40$D&nXuO?d|H+^+8L?E8A{C}W(M_~!no6#xmE>tW7w|imzI??5d z5ACg4X}>=L*x4g^?m&cevvr@t&dsZ8`-*3fh>j`5zD~NChf;L)jbf@%)x{ z(WTAO8Q`k_EAg6)*}Kp_{soAPN=79wlB?hZ=7ClQvKsaE0*WM}u~o5j;R7`W9^J4K z`{DGcV#jePs?e(-x*z&oC1%HNVMP{ zr9V8gd)V>3(#nlg4T$jkIgX1x0JYnukw@PIpEE&B=ay}K#9l9oae5l=Vm{+$F~l#a z>@==8i&ibn+Lw$%YpON9hjH5PJYMu3T29hvQib*Joom(9YCs$H?Xfk#*v!Q7=9QYR zeQS9b&hbKPu3T#Bu3}ziGbAERNq7;`@r2qFWldjL-<+iP4dDCW0>JilZsS5qpW|UA zTYUv=y#51JO=4q4D|nDZoJGX9BiL+5<9Kn zkpjaWg@kv=084CC79rln6kcS=vEEpMUaUTf;$od;%Q%Q+*8GA>%C?MWgqO?T%;B;x zc|Fz5)EqnC4f90x+KobxZd;2V;WBCh*&}A(#7(mfpCV)&o!pLqO%(wZe;D5qXkpoy z?*>eA%!A#qXnsnA=2&OyA8Z(^a*7R`aao;TMNc_8*GvfL$=Ma}oZ!|kj?#G=lC*%O zaXakT3C_Es3E;fdZnQ)rTIzb8zggcB<0OElE@v^Wgw#AZL4&VIRY*7<=misEz^nMF zF(F?S0f&(X%BR*YUjBuCB1zSjAW>>)H2`vEvFpa>8u*r}I2xo1Rx|E?^Ep1;h2nvn zgh2{CLeqw)@Dr&PZ=e0kt_8@??2r^{Y2ri4#90OZAx7B15yENjV58U`KIC8|S8Qx6 zfXxXTtXTqT7qSs-Ui)xIp$5}SfMx^u-{EUMy3i}rc@c2cnkovUX?Bm z1O%UphZwihN|AlBqdjr6jfjVv?~v!v`7`3|(5$`0A6w#cp9&|zYIxaSzqkW>4)RH-&9dG zjH~ZGzBw0;ePER)4Rlk<-tag8@>RE4dK#Y{M-exY67)SMc`^jOHSkV)ZB+(d-~EBG zlBOrtFqdx3KKIrorQJo!IK3355er=gwxyVl6OD?iAR_u@*r1x|oT5r4qZ zi}y3Dh;_~1t_#`u6%yV$wj4Z%#?C>VOzmy{LI`OBI~J zl%PM2b81b9lI%f#_~&$K)Z#NTWy7r^jy`+a9{6q0XwEGROAQ3a-4hU=mk9J7bxo+~ z8dXT5J$igcIoK{Ee6f4;{~PfI5W&q~Q3l42wE$Jj7d7p}QgB3G%v2jxK+BtkDWv6v ztgzdEO=ij0Xz&-}gx24QGS{6bB?VUYZG(;P@*r}%ICg-=;_8VmuISjNV#|Z;iC)RS z7zNr2z2U6sE_0pcSJI6;VVo7N3+7pW3|&ZYmb@3`RR~b|w=mZ@H%{P!5IUa5z<957 zL~C+XV?7HnM=InVFiZQvq&(NZGCJ15(u~fdvQjyQ*mU|K)6sy`Wa=yz zac~E*M4k~X36DHrc}ji|r*kl@gC09zYf@aN!gKyUPpR+yG~92vildsTc{DI5LYPJH z^QUwrHGv~Adv(HnF`dKmddZlipy$^50CMou*9 zDZ83l;qGUp7KK8W?7c=hhs}@2AqoCaBwd`Q_0gLz6cjqs;rnV=hy4!2^&>V9dHcjI zKBmRc5j{{SZpSPo=n^3q$W7dU*>^EHd?`0og|IX(scs0zz8i1pHG10`FDBFxC)$-0 zk0ovdMFJ@vVz>se&Aq+Yuk4MTtIGqB0XlZYU>7x7$E3<}`1(@3mpOp zj}O(1A7Z2UcmQyC1SJKK^miOE2T^p$-YF4X^A{t)A7of6?AWts0$E^1pPrDyCxONk zZHLPXE{!b0A8<+nyBKJNtW*$d)w_+>gknFd|JFG~E9}{*y+XpU8Gz{$2BX}Em5wOt z5>FH0N#{bJXqi%Dj95Ojy2A5YTeV)5kAoI~ga6Y*IioiYvU+`Q;K5q0*NTTJ*MXRT zGAecWr+&Iq1uPBzM%R79`n$Yf;n_QG_iv$2`UT80XCIw&X7;|3QK#rRQw)6i)JOhW zzE&hD916Ygp!p9Yd{L0t=u2F`dGQudrJWU{RIR_Ae~Jcc?R^Bm>A%omk~ttlw^KVl z^O`~$%?6;suP@HrCjw;|&5SS+D5Xjg{Vtv~B}sW*_%BVw8>dAh$r$hs9&CqyHhjAN zgAe_;J)%GK{Vz8E%>1S;mRH{!|Ahc|g#H%qlF`poJK4b?LIR|61#|UFT z(Du@nCrm%cZyKoh~rj6E4F!=+$bokPQL-p%hbY$*-8v!s2JN_bFwM z*l$Je-=^>1=;uG^Ks}iQMF?8jhOo(;(aD9r%^UH)V;&evpCNWxHxtVbtw~gh;9V-@ zzaj#FvvKtNCOqlohx^nZ)hw-yw9;|ar+=fl{5(l)H(~6d;D_jO@6XP&|EIn03TrBB z!&S%5jHomLDI&cJ2uKN7=)Fj94v0t-r4tM&$c)rTjkF-WgLFs?s1RBNgwO*7=|y^n z1kMWT{PW+Oi}Rez{|ep2?6uck-}ipyeLveY%)ME>EVh?^VQuPEf{tSZ0Z9#zTa zX0g-}H)=x4mX1f;0!}mA6Pz^OC>AFA2a{yhyhJ?%en?r&Or+3O?^4FrjZjf-xBPeB z=|`LCgh0YhciRUmFc8~1ENeC5>I<|Z5-Vs${gd0I>WIsbtfcMKkR(o`Cam|=iO#(B z`Y;umWE$j*94)_ocq9_VF*aAlg38C?n({Sk&ySnmO0r){X^WAnpFk;)c&UWUsv?U= z_QHfM&^nv`Kz7}epVJh>2}6MT%)NeBh3u65NW4^BzR4)V#pEj^G+Qjv8jNC((hH;x zGdCDV8P?bKp#3aIZD~N99#;`+Yi%Yz@Rb2WNwQ1-FyGc2=Tw{fJ|$~o^^->Y`5mqV*ej4X&Rpu(PQB%4nKHwCWt&^N$b5Qy^Gy1TSwet_@A*~Lsg)27 zD_r6t)miN?OXmPXHtj?zU7F9^7~?8UhO1I|Yq79dAWgCswGA4=+5p&u~_bG^-^~ ztWi+~EMzGg?Aq%Et%bP3BEOOBk^Ap;^;XX&AnYon*jUeYV)RK@L|st7-*g%k8(CzE zdpY*`JMyFT+RiOqXp`MWrhwppet6a#{ILwOitT5O$(0sXwnIsw& z%~c9#c!&S8TsrUNHFlLcc5ykVm2Bduv8M8Wy0Wa%K%q4E)$oPo4>2th%B>r7 zQi|az-`xDKmU~SI^BYcUT$=ba@BCpWyVbT3&^`rRMxTAPw`706^5ALRm=o?+vr<^x z{pLG#yB}WpB&SC#XyE{{^-)G6B(Z;4?$X4cHO(66h;BPvSlWqUJhmyc*`k#YSIvU} zJ35Pe@34PdG&`n50#He&HaGvZtx_TW&chZS5u$PfakwuwV*h1&ttRbxqibS-yTmo= zHTH6TSm4^sYY`5)zEEPvIF;&bVK7G%#*ikb!w6xQft50|_I&yA^Njw!_6Ve{hP>O3 zIU=~O&-Xd;hDS;kO9>&Q^ZcfVvp)MYhcg<;@lQ{vq9ge5Gv~xR;7PmKGpw`1uEwKC zi_?Kr8Ga|~gXNz0oD^-JAP=+%EUcDZv(2K=6aftsAjvBsIqeX?7eHTdu?2Pf?4w`B z%9H=k#MB3c@6Lj19k(87XNfH_mhSbHNxllbNh9`kpg{TS-TPQ#crPF|-V-vbxF{u( z4Ybo6fDf41WU|m#ltJ2EHvmZqAJDzu^eyv~{eeJjxsY%hK^|#C;Fi^8o{qgxNl3rl z$gVS3`)SaW{(Le>;8hsKAJO6;NsETz$_%y(c;9&5yJT#%bPlTT?_#-JBbqOMQPdQG z5QrHvK-kg^WRbJrX0bruPbsiDI1{Q|Vu5BmQNoEH5M|-TRv2{&$DSLO6#uD5feQCT z1EsDEmF>6v{1-)A44@4B)@9{_w6{E$M=dQjOb1&3^xQ! z!^ge(hVvv4)A9oHU3RJ4R9hFQTlT&+`qvX`yXTWna|F;t;mCk6gp`M=M=(jGR}=k{ z0AH0yn081~#&ez)w%#tq!75@Uw>Mu<0_JcLIHn6MBl=#R$NIZc;&hbYSeFy*1y8}=DU7HcP)K`>*`rup$ zXwB?(!H2susp;OKY~KXR%)#UACf@K~vVg8lo=ds)EHM9mUV77)tyAZ<8AoU+vi<}y zyL3k&ZP%EF zTk{=w^ZDz^G%nh3RtW!EVT4nT>u^n4$NC@PelfIzMdtCz`xJVz3O_=`x=(N_ez5NL zC%$sOy9i;+Mh5wV%eg!lr#BRWck5bGshFF)a_OySYmp!i4z!jZ`pb2-11$^ymetmv>f>h zRHndmuTD0=b}j0_b#lY76yf?hw=+cvlAazu)WAD^GbeOIo0dY|w0q{-04lh>zDqB^ zR?#)@MrbejK3^RV_F=rk3Q`7?9cfh!7J1IAkZIExgs&6{h?`=4=@F5>?(^ZLn z{z;C2aUOfqLBCSdRT?A4Tl3IMXN(~=-?&5@Di$I>v+6bjCXK2k>iPTZl) z+z2=%S6?B1gj^Z&NmmS!dr~1-?#X@_awcf~l(oPUCl_svSl(-_IgclxcsHQ=Xm8P* zfOu4!st_P=*Pdt?o-$tjo9{a`M+WR=pt17yt8r{tf$Q6K9|g&^(4B!ddjFUWr6c&B z4sI~c`tCNx@9N$FBPfq3693jK{D&+^XqsQj2>3Cz2DDg@(wYCvwD~1!47nj;bX{31 z(`R*9ft$Da_9W*;X$guKKNfh-y1Ayr&3ead)L8o1#|WT8B2ndjIXqx!woRDi)9-F_ z*~j#GeqL0t(rrjJd!59EuW=ASt*@jWy3WXtW%4d7M4s_cI&PiLQDwq0KxU3;di0mFLZd{dx7~LheC9VLglc=@zS;rlrhh4H{&$07mmdTJdY=lOL=IR@2wGT zzH#Z`Y;rU0(QY+Pc29eL&@<&N6O7VHqNFOCi13sT5Pk!%_F(}wpG$GSIRH*8SSOZ&%PTHvt1JNmK_#!X&`-H7s*=XLa1#rNlXT& zN_hm#J#b!}w(QPxHWXsgJ)=M-!_Y1#taO+-?70vJ@<-U$vUAbERg! zj=1TN_)PeIc)7n@-@g zR->?f0!m!zJnJ`+66LnXXpe$nLwHg+$f<}(>PTt#RHT}({mnWZ@0pTv{T2Rh*q(r$&i_f}n!y(D8c_mSoH z=DS?`^J4A6lkMgeO|YA31VvZEWm>BPrG_Rk_fa<$#G#Khd|;-FxVkRl%$^DpwVoC< z;i^ZM!W_TId|$afiA7i=3>VfX@qFd@jvEfr_}b0(^N5GI=V00LX`zc?j9X0ouwYuMI~B7ujh^XB@y&OgxDH3 zenfX9+AO>BzIWYr(i$s$C9(C$w7z5KOL_LtY>xc}xjeUZP8|{*a&Yqd-zSuC0k~4u1cra!z8L!^mxA0 zaJ5wsq3UEXqM_aoRag&y)@cw=Tzz3Bc!So9peTID_qagf%PNIPVLw-0oPR)(Fo7>m`q( zGm^V|t+Pf{h`X9Q&PE~4yyOq=E9T2NPY9iNCs=WYbhTRL?Fo}6!ualo{c~FvtQqW6 z0zQdMuGV$7SRZWFpbz*77OL@ePJQs@3dNHP&gagH{2j2p;jH`gG;gtQEPZAfvh@6{ z|8(!2<(h@OK+h?N?PmENLnfK*S*x9L@93B~G>|rnccIn+6dFb&XD?wRUpG`kV==SS+-Xi7usDw6;z1wgk zuk`LegHPp$4rdQeYq|*{24?P1%T>)D?3Tc5oycpDWZ#yqx1ciiSn%e3P zgq@&q&u{pL$}(qR)kUPwHZ7rYG={+MU9$aGx$qV+3JolifRG5LS%$ZD8#4=VrIR*JpNI`y1uTHfJsOoDIg{ zsgmP2!gvvLW3_~OTPTscWB3jd;R9frz0xG)YUu(_pxF1AE+wh7xkphmzCMQqR3LWlDPf~m7w?|E#wkN90DioB^Y(5j z2jxl#->(b$Y1ny?U&Q`KJ-kkRHX3tX%^6QQ@XFl{?i=+fngkL2o@T4Zq2|K5Ykrr_ zOUn*Vlsh3_oU7Qku0S(Y-cq=B^75c-J$bTbA~FU{gBctRzF)S( z>fO-Hm2_l*G~nj76Opo$V4#<_xiJVPD+okx*xp7|d8fQNy@-_{=ru-{cgScUq4Rl- zO{xHiRVkkG`drA6o}Ieyl14P{H)^>tuf0S~0w;d&>3HG{x&?H)CucL@UUrUP25*_i zoW4U>dN77L@8Q3(SS{0JE(`^-k}@zP=?4}kD+JV8cn#X=10|fp!27g)jWdIFFm#3U zV0UE$mB6sQVIANp=M*bU-`g~0-&$tA6 z6{u|7a6;8Ji)`9g*JI9L4x) z1fBllA<%7>0r{5$kQ6$8nSOme@(oBP)%^YIfF6@)@%NZ`@f34w#3!e6Fp4ZqB}WC< ze~%h6Io+cl(C~*;3+O;Dj;L}`Fc>gorY2*4VQ^9|O!sIfLNF$Cvgcucb|y>XFDS_$ z|28XP45$tU)o{p`i79AMn)k6(bTBI_44v}=BPt|4aiA8V;Vg(S(EE8daZ|IV`JlU# z^`!Hy==BBntl*v8j7as74lg46mMG__+#zY*4e*b%pHQNW3$9K8gBRI2i+v*%4t%y{ z_%${%WXZ4XKn=mGCFN3iNjm`GE|@3SXp1}dK}!iC=`u8cj#7{RiNFgxQ|t!@Cx;GY-$|eT zJsO17IY2d9Ogh~)wc;+}yY|qbCpYS<$JaY~E{vlIKi?2DdBCuKlZo?#*7vfJJ`_2q zQ34LrvJ0~kBo>;AZ%2)v<4I-*DUe3Qpzn9EYI5~bdC=q9d@yltmNio>yJBJqlvPHY zv_(W;tM|zBQlh`X#-A`O<@Mb}cJlJ($ywR>Yxn-D>6`^8KGBN})?5Z8pkFcdA^xM% zpc>QTvTyo$*tRwiVA-#=t8^awf`rI=ns>^-N)=!Un9D*u1pP7n`}Ze{E2-d4(p7wm zqMUWJ=ttxoZ4JeXN70W}wy!Eb$17-d&KC1kUnJZJTIs(tPp)ZplK_E4kYYO{XGp0BrFQSGM@Pq0Oo)0a2pgox{FJ@%ijV1iB<%m7OYKr8~b)eA(d-U@=F0Qrd?107H6*Ixk$N5EJf|2R(ogg>lz#C!@mL+H&@gd7L*z&F64dSK4) z0#;XG8-bNcu62Vfxts3$fDxG8v_XvhT5`CMcgwTi(!17EEn>=%-!18MNTRqZ2>EFD zHVJkGJk>GgDgiwT zV9N~_D^ehPCam)G8H{@lX;EE$R&{&o&dn8-*SU~sfMug>9O$hg!X=XS<(i?PvD(e zX~TD`&Tw+&--4CBtGxDTZV~;w$T>*1C6e7#R2ps zej5h6mi21g~|$D){?+ku^*1b&$7*|P-Y{QbD?UoHG5IkE@Nmb;tzAfx-X`c zhA0e1b7(t>&9wNxKkvUjaB?uQT7z3~kc$RE-_~dsyfznoch~3H%kY$XgTFdQg=MLf zMpKe_Mn*087molX%esxi^B*5kz+(bh&wILrw%*1x~4+>VREI#r|LC#$Cz+J@R? zGu7bm?&-7XI4f*haoCUiro}rBe2oAblDE3P(#VY3^t!k)U8`1ur0PDXt?VeB0?%o= zRM^`xDEn~si_2OEgLP~CqHNY&5L-_BB}Ig-kddApKYp+%!JWQskwvyON`)2t?_DhH z#@6dj31Tp#p$We&f7J`Jq^DrQv3f}ARFI7l@br_)ZTf}W?IwZ<2u5{@smf}o4yF94 zWK>9s4w2t+U8;rcbWu#HHGRt~tY2I2tjPMq$zi#{4=}_{^7^X^U$DF5*f!xaGKYC# zq{4$;F`EsQwYkYTH*8#crWS!2&x)T-51VRumij0qM~;^QJE~7ID{MA9^}@0?$12@s zzIv|hzjT_M*hN2FN-UY02oCPv+Jr2a(;NeSnNE4y2+xjaK*#{ z_Y%4p8I#talJf+%K^m*BF28%wlCXsg`c(`W=Y-rdp||xwl%3l_-M%TG&w#@AeMF zjQU`LbPgCsvNR!27AL(mb=NpBzeGHJbc$OeVvP#-sLgqWtjzdWtjw?XE1)f!+J&BG zIS!Lf)E;0V3ncQYyPj?!Yk|CERxmH&*y4~w&fS@jXWrd$UTFL0pqUjidF`sk zyM93s6o!OEI_P};BU{SLm5{;*>v`h}se*mp@hvpsN>7*!cnRxNQ_1GaS(Mx0EDH}1 zdX%^Xyj0V$-cDI~9CpE56;17hV^e0RUGtcD%Q54PtqxE?=?+Em$4Wx|?nmt#4+ISP zD-K<~EFF1t!)F#9N4 zdb(CFZ@600_1D4%NAXZue^wzjztahyX;-r9_HEI2GKWRkKZDF_U(Hskg1)p?Zmy!f zenvi;$2v7$Qsts$_K|ORSfXJXW_a~qPK?)x?!`~T1An}oI!Uc?70|M_+$fR5i^Dtr zH`h&P`Xe?|9gMC#`ubOI%6M!kq1f%+EII)UrArb}Y%&)Bey%K%6)f=%ug4Ykx(m|z!9s%ji&}$Isgd)AS zK&a9ZS|Gr?!E??%_kQ<&+C+&M_n3)!by9!9^Di7F`u4_k?j*_I+>Z!Wi-v%dN1(~YM@ z(Kl{oC{=6H%2w|6-7~1Jsi{#?6eD{2^x59^>4(ktf68WC`b6 zXTN}d`~qjZAV)tND^=~w(7ckdy_{^`HuKO-{==iEnaU>7qBy1EFmiL~i=q5EHhrNF zTkn34CfDvwDNVtjY}C&OkR^HV&nh`7f4j@u9*<*YRJrZF{l%b)MSXpOw_QN@(;_nz zr<&=F&lG9jczB{jLgDeEAxG=`r>JMV`29I+RT6Rb-(R19hEW{Jz1${eg^RF(?5d;C zsv)p98qZSauW{gWqSTBva`ewDN!=m^}EUZX6Vx2V#3CbMCzOhjxsvKG_8i+ow zTrKPJs18*QzlHgdo&}K{{=i% zT}KspFxEaSNR>U1kNF0&XDwUh(#p{selh78nl#|9vBA7U$CY;ZI#tcD@1LXOr@2xg zv^9PE`mEDJx-0WF83Xgo(?0den?9O42}1hvT?xGIeLr8|V5P6C-szQlzOZF2FzT!B zQe?H)(MWVt9V^#oem#85ES;aW%ZpEKv|*)Bc3GPLW|k#5kb_gI7FnJcd;u%8&9SY3 zxw!Wg9Ev^NW8ht`ityZa>MI%cd|EWcyFB;Jefs)qXy* zht%1RUXve*jI@8fpGXuy`OzWseq;HSk2l;cMy{|nDmY}^B1umQBUmTC8hFhr%_l8R zBWYPPvxqq1V=)hWWtSaw^TQ+7)Hyee5f7afl@VrYX-6uRxcQEz_8Ow7%v$pmhXe`N z$X6YYSvCFek=FftB);)mU*53xH||}v?3_@TEivLBZ|@vEBq~`DiI;?l-is6HX`jIJ z>b`lqz%9ZSSO2U1ogA;O_w(<+8q%0~byv){iW}cC--zY$YY%zw&VpALiDk}<_!Tm! zK*VWWY}2JQ#E?F?nv|~&-Y{SLIQP!=#t_82J(K+1^~7X5V8DH&JcYt;YQa48=dNa{ zYhaYUc(R?&h^yXrvpwsvobQWauZE3SYxa^;B}oo@NOl?C6mNX}SyX!RDe7Wi@?9+v zr-&Q$u1@=LKcNku=Tsw7MATYUISg*zmBz>-KVSGt)I##Fi{nc8U_Kr-*})XhHbUm- zK>n{el9rB4#Fy5grTfz!=_FGLp>tW?c}XH`US`W{zIUZO#~ceI(|HW5MY@Zs92_}4 zYE;BMEb{v@>18sM+_MgL5;X%ZcV*j+uHO(41POvv5+3*d`{o?K!Urd+oF%aw3pR}n zbdPNhB@>GA3@T$Dfh|S#GWTsEy*+sjzp^QZtw;Lu9>4CjSdl)ty_4dc;`tt)K1=H7 zn%7D`6-O$hshO#o@#)jehM&z!%OkH?Q znyhuOv#NIS^0n=@pK_>w?pm1@60XsmBtvg$k)7y|l{Kg4jIC%1Au{`qYlox7W~|iu z=kstHftD^Xg8lQ>5Ljhu{xN8lm8GxL%;fR%CN+t;NQm#0aJ2ky{O8LXzm<+EcD_yN zS8MEr(>E6vu-k)XAWsRS z%=6mgc4*0c5v9#^`Cm^@X&4qWq>N}c4QOU-vHAJ_DvyV4K8s!DgU&A%Xp6)T435B) z$uB&6$_KjUCnO(l^-M;_dS~qVW3O(51PLff*A+N>XN*DQt*PIwh^WQat%XOAg&u}o zzE1mFgv#oQjQe&|5l3J|O4{|r^3XM$gmg>vD)5vcj(q}Z@_a-^VKGIFM8y&GHQZrQ zL*TV3AC;z8`TudHUXo)H0Qcf&l09A_YEnx$~m(e0grVBL3Up(d!$~FF%VQ>yeCgDUjBV^m9r&;nT|6y z1z~!TlGg20p|PJV8KYE&1*%)aG4QHJn09Ea?NVpF*Y@5t?-IJ1I6`QQplmyA^cL~%pX+wrW4mu3uhT7HS-yToXncZn=*jcc%abumr&ozXdc7@&?e)H| z-r=5b4!yH6i%%S|X<^-7i#8~A*?_prw#ej)npfycrfjwtd`FBy*JESBLL6yvcfZL(^A@VZ{6&9PfDG^<#P9pDZ|6 zsYe)PA`gRAa~+5f?|Y253T&X=0G;i^9AY+#u`kAtOSf*qAT+` zVDdp=w=l}#ogV3vT*4u5aD50Ocls5L{U|o^U<6@Uv-1e_AD07!2rB_YS$2fvnEDzl zRW1_nVX^BqDyUs?YkH$-Jr&;P(`qQCa26lgNhepe>@B7=;U!qh z#Nr(6kO964Y^@UWtjbAJIh?Yd(qnzX=X@gjC|Gw5aeyWrX2{D@Gk%%+tY6DaySkI> z*02Bw#v}QLIt-c_Ff4uS!Ev(IaKLvZ%f`6U)4A@aOyavTI5>M84p}KXZ-t*>oT*)myqHiLF~B zI8DQ}m;1U!fZ4zslN58MBl}u~5-=eMUZrU#Y;bed>vd0x?G5Mezf3-6itqZxdr0I^ z=W$0YAMC(L0xtc_A!SU+mbEC#+ZN`>abzz3#{C2rxKeWnX?F^1I$hNiG_|*-t*sWl z4jz5)$!q)EN5@;iME_7dIY*979}aeKT{f}gp%wxWA3q&OfKiV+FBsA~#S zyP{4`BLf3%9wm$l5y`g#dMSTeb=`_Qtc2OjEv(sy?isQ7+ac#YYezFb`}2pe?>B+j z>zy+`pn%x0WmZcg5J5`b_&$)4>LXyTP^@Zdm9tuKtMf$7VEu_30%@9`tF8ZBA#y5> zRV}6e1L5`e9{g4E`2|OgdjDTsy0qZh6=^8L;AUe{Q{e|9`yH zJA{*fCV%azr*KJj{OIdWofodK5p+11Y3822`~LT1s|_}iY00F_wY$%v+^;#sr^CGK+h6Y%}L;6jke7bTWG>B|C^%lwcACIv4>XZ>M)AfViOpdecK zG$833L7hl@{B$?>5=`gA1JMzEN$7FV2hBLbNQXN%XmHJHuTTwfV=66+7 z#2kLqOhh1kI6s* zYR)D^;)e|<;@|Zv)+1J%dm<)M-h?KaSS3zf_}9K5GTR|(;ixWl95<>cZo9|7+Xx?j z|1Yz7hah=oMnt&yFDaZUZ1WaFIOSPA{5>KO@nw?gY`l4cn)7VHc;1ZYbTISaTKM47 zFYB`xf1Cr1fFb&9;#?9~2qexUaY_B0>J)CV=jp=$3EAtP0^5j1gJ|!OeU7v+E1Uhz zc#q@^(`;gXRgx;HNsm=2$)nr*} z9D_ICZy;Ch2nVR89PVudJiiP*y9b%mO~EG&OpK@&4#LdF`F7i)x&@FWvqKCMrA^Q- zChFBhrn7^ifJdFU`?{=BB{znjb1PfcrCa9SEgI-|rzAaHp=vCLXq=EeZH96@KigRQ zbgd!-Q^=E^5(_gy>kUc6%2bLe4;*(#N(I{vyar`o74%SdWjk8J^>T%iq(?pQfsT0; z9L6$9=a?0vzhZavG-Dv*z27NYCu4D!ioE7pt_yoe2Lj0jh=GBD$JD8+=s8?U(xUBC zLxBNV$j^qpD?r%qvI!(sdbg&Wl_%U_i6t&DzLrdTZU zRd1SHG`l8C1G+hM63uUUXmTe~ks6Z|@K}oqr&q~3?E%ui#tV&f@0pB(!$&+7s2teV2$8lty(e|YAH}Aby@fGs zpx~)6co4dl5-vsf#U}m5jmR> zI^O%3qL)#Z3y!+%8A~Y+@)@)Vh2q+FeO-Kp)67CHje;Bm=mP}rizyX_!LjR(qkbio zyltA9VqI~3G8wuhmRg1Cthtj9qN{sEXUc1@!6m48ja&luaO05rjL#1gaxJ1*RMN)E zY(wKT${pwAIgF7K%*t_}09hzlpkgxuh{;00pPA%jhii*}=j)bao40>isa5Vu5X=Em zy@6C2;#}>#Sf$^;M@zIS91Ick$DpwyV`&(mY~1$OrvYqoArur3Vv$ zKt7E6DNq<@RyxjU6dF{?9s=7aVo)NktW4Ky6Z&(Jyn?ktw4zSkp)NYgXNd+9*?p>1 z4))Wlzi82cyXu?ZYEG?NR)tuK@yV--_kd51H~`8?OlUXn03txZB9p-4CcV4fv>R3&U!c zTdSLk6ZL-5+Bq5@Xa#M)wcuO$EIX;idk!(eU(XqpGNV(~c`Of;P zsr_hYij%eI6>q{f_8fzf^8+k|PvgaqtZwBl){U2o<2|CPSHEOA0q@kS*owaI&gUv6 zv#yq{w|8~LJ1u%Sd-=Wn3Sn=qBFJY~Xq{AwP)fTtTGATMu9^9A%aeXN5w4>-9v?V4 zq&X867#?|TgY^W%kO}uacp)LhrdOJ+q#WsUxEpMA-{QEWM~b}eWwN+?CIpFZv4;{J z4>ho6@Ed2pyx%MSwG$^Che5&eaCT#*fDc<-zD_4pX&2S%RA5l0k-QknO6IM-fOmFT z9a1r1D_xCm{{1SJ*kXEjeR5T!Ffi$&QEZox8l$LFll}3|u(1wI&^GExD;JsNqRh%b z&SZp)lu!&5ki6P>Y*xVnNA+DLOVLkT15#n5Qq;+<1~4HVR4li1dq$X%J^~6_81;7Q ziK{izYPMnM92?7*+@H`zn0^rJv4=$KLsr7p0hfMJXlm%xrLWhm6fapQ!f|G0`MOJb z9iQ^DJ)&Dt{Cs9D8gpH(1zCF`(e6^dN-_Q`WC#II?iS`A|IryJ}giKL+Wbd{%a z2CO}I$r`=x)-As>tw5Sf0lEV>rD#vcCSLj{cDzq;RbidQ#~QkAsVPbp8xTXN!x z$2@7#Jbd(*RXY`yR+Wx{QaaK&K)6>!L!PVFs7m{)#h39Fo(|M8aynded9(T(OFzTY zl207hAU|)i<0L>imcx7lkgB02D)SWVJ|qB6{^1L=~4lrhX|EVbu3G`+J&B+;@mRp-SZ>b`zACVNn$bohrL zY+`6JYVqd>Qin}nj{c6fPQD*`TKDPh(lM=*EEXyqw|ot!Vte`4m$0R_K_63lu|zLkC2VE+GWg$-Kz*y8y64&A4R=+qiFZL`nt zQleTEeZ^J$>Ez-W%9c5_Z3W(HSm9rChr%Dy2-0km9+hImcH;fsN^uyCS|s0e4;({j zy!t!j{TRCAC!?g%-_9#VT&;9iL&i0i^-p!KHb97WR|Zj>*qDNaaw)h3;ZFE9h(1q$ zDEme5=nuzX$OjV20TD8D%oGR1`&Qzse*KG4a)m_-kqo9^(+#@kC`UeRJ(d<55{o@4mAd>bpaB)J(Q^NC@+4A9* zsE03@R(4B~>bfq?#fUF{YA*oM&+Z7LUuGr|WxMa+5uEazw^RHqMBaQ*KLVsf9JxD< z_YnEFAyV^Hipltk2#17x(QKKe+k!%ld-Mo`_%eV0sv}yX`ZuFG%4F8z@W;1~Z7J7l z`aqbmFpyS@9QREQ@$3CG6#@_Xf=rB9abs90=CyQOD;36hZf<~~dG9c}H3dDajXSHu zlQZ@x3r{}ZiM9oHx8Eb%>opr1C&x#FB9T$F(!RCTzX^C;^PFTA5=ede-w}~cbX0|P zQLEu>*9o8qtPo}WY}O=MN#)dHmFG_Gi1E75%+pFy=LHHX9p>)oSJ12$e3>`5U5>vh?oGc&7 zu*L@iIWzlx%=YA>!90_>W9B1ts9N}2TrZMkju$|)dfAo8$i7Or{ZDFoqr4Y z<)r)Q)+lsF_-N!+JEq~i1%Qh5h}{(3Y{wmL)c;emsA;vIr{k>RiVF&pcx*qWC2@IC zSQ)Q=uLp&?L>?PH7!pPHgyOAQN+22IyT8kvfB(%j1_`hP2-CWBo%Zop{R)RFZgOQH zaIE$mpHDmIjg{~vP|NbS$qbx>26=x9$Ucv~i3g^~c~9#!DQJqM*JUP}`TI6+C1j=A zo}Rr6SfVQJS$X#csJg26mW1O23whk>v%eOs- z45qA05n3N-V*2|q20ZuVSLIx|s$Xr>gqe1tF{?RG8h%o+Iv6N!sVb7t2oL7%#A)U9 z|5~6Yp4@FUMr21wL*5_fi{BhAwU@T&jFwYQEKAlkXi=OjdMCXaamC}L4DMgVSTN@D z4M>Wwj+L(dc2fy{9+8Yx4kl+!CDrkB5B1k+P4o(4AdSsW{V5mPe{xKvHW9TVxF6eX zh~zZw;LC7#ptkQ}%P)am*WmeG2aD}!ED`O7s(HCd}h^aq0(mR^mS2_ zI{SdE-g`0aziaD9I*9uX6*R+L6)s_q$xhg{3>5Y~(+o7_!)Z3kjbt_QRAp!->`L`T zJzQ(60+-akzr2;e=XEQ&%0r1d*OGf&ebgz&Aog=4cgY(50n40#Sqv-Wd_uiPnV7Wu ztYQbO{*!eWeyxQu8at^~>fLn*CeN?On`YKal-~1-VlKc{dBnWppmV6-*Y;DrWE%z< zBuC`|4-BK0S?;sAIsLxgx-ZFL;!r<)L((OILkIumHnXDg)*S2CkQnK#5|~5YmK6UWZ)|uWZfD5$FgErlSMO@fZTNi( zhy?(;VTTiDo;%_7wohGGg+X&kfjI&Ty*uKO)_eX@+ZHbbQEOcR+=s45e%JtkIEgDF{b_&@iV$YUX@PTp7M}5tf1N-9YSfwj` zDSmO8)_C}q=r10x1HyGraclkxu^)NqFbIahX=X&UBZ-;Lux^Ldq9aMW6Sd0uzDJh} zY494gjfIp-`Zbw*TjuX0!kzrtHOtfDA}Bdyt?l}EFGh1gNnneaMS5A%rf2HD10-br zm6dOJR)p=Cc%ECXvM6#A2$|l4}aPaYVshqVt#^_1n%%4-fKf1YM`Nc#9GIHdcAAs7spN7-wBC6_f2k z_9>>}0!*N)WRv7VTf0)4JL1h}Q#5U>*_=qGVXPMwP%E#2h&^08*YDGd?NNNJFoT^S zgW7(N`8~U)Gn>L>UuAS0UcML^7uFLN^Epu<1k(|vR(q7uR2ptxY9!m5Mk)_)U~37u z2sH{mIvA(#4Yepwc{kOt)&tfG+)MUihz9adHxtN6F)ZW`C;R1fY;oA`Lky|(-pe;P z_{}?iV@G6*47WRe)T4V7y?yvPLd)rQ#(Zq0+zzrdt86Sb9rC&)>_X{3Tv_L=(EQiNpzWS)_RJm)229bU_TA zHfGj{dzwivdctATVzUTFZ}r|GZr&`NJHI!D6_L8Q2jUr>T)bm$1GbtOovM=!NzPE? z2R32aCyariLdMlL`y{u#Qk^aGLJS{+{J*S7 zDV8HIqGFa*$laaO5oxUoFZ)zD?ZebU@n$1%7Z+OumXr87V?>7hy17qhKj}Fhg?dNN zaIKq4#y(!xsB|rRI8!k``OGaKvG**}D=uI#7%0T7VqH32>L~D6#dHNla%j2Pv=cZo0q5;7(4 z63$1^dkBkfHviAYL@el@h%+NOX6ZIlh-TnQ-=WyP;o#SjCRV#a_y`^=U2fKYMHumi zWGi~_5-_G;St6HbrdQEXphKu%eAQd2{YP2U3XPDEt*=&pFHg#{#${tp!!nl2UVNo2 zN5eAfk9kdS4i~!;?+E+rRjkcp6Q5wQ*xCv{h{=Oa$?b_yw$>kcW-es2DYBSw7lw-L zHNp9bl?GnsHjA;jAFsWRgWC5y!ROCC(R$a)?nw5@V4akp>wXVSiknm0&*I%gt^UyY z0nDG<aL)hQ|0k5khEx8bPJQF0=KRB%V!YZyaz>tNQvjNyr!1-~*w0J@V3lOC znA;Q1}t~*&=VWn)hBZf2j;fveVekaJg?+9Eqdy`#>!kTz2hTWI2 zAI)!}Xw&!YDu9ZrHHEEgD=5bTo+e+&e(V>SG+{>Lj)0{y46oC>)SJ!@nW}Z!Ld#XZ znZ1DNPELIG>>1%sXd%{}fr4gmITEY|%c9HA!nO?oAQ_wM$^hE(5XkxZA@xV{g0@4^ zRH3oxlq<-4#S&%pSxyDs+G^%(#W>CiB``Ry5{Y#MRSl`eJ!-Is4+1rQyuQ2$_lpg^ zFO6FFsQ>`iQqyJW?`L ztR^ZQb7X^Wn`Ti;`W+`#yKksk_h)8MuxtDZy7gcH?0Q`>3$%Xa-Y4Tv40lZwbYJv)}#DvGa&H^N>M8j`>bNUkiAE~OrrL^a~ zJNK4)WwwX5_m%^~lQ~O7Mo!1@+5CniAC!N}y zu*1aHOqIl3KHW1c7A_4>k$^q}7(PzR{xgZf!(EvPCM6RkR%%^ih3G^afCkGZ+qJ9? z=26{@lyjJ@W=7tW@Y+@G{3DlUot;azzCb|T&_k`+DmYE*ZCMcxR*U2ge^1xLfeP$? z=ITI>3>kyO8{OCqzV3b)jCAE)4<6hZWS+Jw>mM^qz%|YpQf%@0{T|_SoqA4q9axjaYmDRy zl#L8_6F10m6EEHuSxmf6cjY5Q9;jSCQH8nz3?6;}0#QkZIj1HIb%YkJTpc2GEEezT zp*&-33k)hi-X)SAn_oS)+a)6i`$5+!B4KlJpotP{aW^{{f7=Ov%?6h0vQT54=Z*%d z6ipDA@XC|0<~uV5V2Qx$bl}b%ed6aUYs3{I?rsB;%e(%KO*Kgb%~HhrU~efB>=MO` z+ianO1YHaw%ctfuU5fDO%hUWUZK`gF?E;AxNM=G4BAw;rTWh(HqMPH&gf@2Pg-)JG z(7fmTS{vF79_cRUjq^ENs}NL@RrA4PVCXdsIVYade)%;_p67fmHTx$lCmiKDtOq0$ z9fFEv1$w2gQ&n-)q6P6^yhwY^C`J3k@09LM0^F<6TCB)ZHFQdQp2=iU^Wa<`=t#kU41~^%Q@A`FYdxQmD0|(@gm6>?6tb`1U+uaoo9?potHFYX zp{J3x5om3^7dKbP4XSCYvW3+gQ!^A4(bsLPf?d88;eMEnCkWcITyDfwT=osSr&OdW zcN&A*h4t4SM;dFk%xr!z5EuH`+Pp=5mqF=XWW(q2bj27BG#~LEXjA3sVNf|xDf5`U z@%Vkd{z}^OLR(;oXd+g{rIAs} za0gopFX=UUv1q+=J9Y+Qr$pTL5C4mX406Q)n*VV9{L7|}B_vAv7Iw;OBUl1!oTAgT zI673I-wgBZ=Bz*8vly#;=C5-Q2m5o8)l$+oH{Dj>!%eo?A1Yc=SWwq*XRuA*A$3DQ>Mnds?D z0Pr1!f?Q}vp>TRM&9#(?uYBh_j2Ti-{WDA)l&KuglnG5rFIV{N6;{a_JAG;1`K?!3 zwD3^)S%g(P%{yLd-I8{jV}R?#0DImN|C6w<3HLh|^@Y-7<6q^UW*+q+;o4flIydJz z8^C`U-uUN_Kxb6%r&3=m%rcUR&!C8t`(Dg{HLMfcjDQ5@^wl3M#X9f)U>4tlf5*Ja zKYObk)BnEpeI}0!=WI@vVVgg{&V4pB6Ot16cVzJYpN1qPW`f>L&rkp0($!+JO)5_Y4z@7u z*CQfh6%gsumoMB!E~2D<7%xGyzdiy9SaqiXY4Js1;@*#0FXZowgbyi!z^9aX?$GWu z%A7_mic0k9#CBXUR-`Q1^Aqyenpc~yYEfE#%UEGFXmWtfg?A^(Ehr+TcBWh^Jt)iM zEDT;D5rNv~CxnkHRWM3qPM;7G*ZCrk=hkHwt|nI>fAZw2Q&y4j8x+(D@u2-vynlTg zRnfAN_qk?icFwAFwNGFSH|{*XQHng>V ziy}||#lM!=_61mCiHTSC;1_)@zgZPA-y_raahLU}i_fEX!DT&veauk63PJ-L}N$ADh)8Bm{=^wkUZ@q_X z)WVnK4tzB+gSjgD>Lmz4#_hq8lz&nnHW72ne3ruc=Q~srY2};_{lWr}z6fJ@?{eZv zUj(ivXI8=rN*_3S0A2Ip`|dLiU5v}~x?!em@-{L&CQQgusNmCm8F@W~XMk9}eXEpW zJk}8AIs_S8FOD#h1pTw9cto!7o|vny4-A>&7+wzdea=dsxe|SGy-d$-o^LP#nk>du zCugiy&B1Whsb^4?xPnnCz4*x6E`OfCE-uUZgNP&gB|r|i1W*$wA`kbA+>*(&CjB_k z+W)!*Z3R|hFv%@Ep{wqNE2}}OeHNTVvutfROUpgCr1oRFcW1}+@(&DEX{29BLqj8L zPmWemGLI`edie?;$kXf_07^eu6>@Oq9M+!(fUQ&8eEFuW6U^roVel30quN{1U(`D+ zeIyT@0FiNJF-+gEn*Mr_s`L7AG|T0eN$#%ri1V`Onj3Wdrn_aiPX_ zgS$nqIhYP6wLc@%>c+bCpYLFsujn$asIxAa3erDG&B+R8fioq%`NGz@CET>-o*%%+ z8ssaby1mx2xDBujqU-UVFfod)QVTQ6WPm38$3%gR5f!1ogifwsI#fCN7pa50b|HWoLWqFZ}O<>J)9BQ*!yQ0^-PJ^dzgxY`0nU zn?t^2ul8hxo=XH4U{mrg_0${x!cp;NcaqT=uDopO|0^jcN&@zF`XWQx*ipG=FNlua zxWx6Oci_cTrfsr!eJn{iSiyL2RMBja-sw~@jenAQiZ|FHF#dv^#PvV^=H-v8EgTpA zwws$_+LwNW*Ftf3PJQkrk-xf+y*DMvfCEscuf4kXKMet&e+FQ_ySHKf`kx`D7aV>g z`Sf7wxpQ1IyBjhltl1gq>?ONnTT7+_K+qrP=iR>vO zHi-W_UxJv~eQsTZe{9i|-BqK&VT{g&q1ssZQ8n4^ZfTrd+}YXPR5j zBHvpg34mm+^5<0Rt1yK>f;g8Cct}0p`EHl*X5ew< z!ZoRz05){v!j<{Qn@?0PlFtin0#iasM;9+qdz(r_v6n90Y_p#6PrA&~W;+9LHw#4Y z=gy`)x3Bz{DQ*!@Mp?cD7e-aMR_^^P(>{aT4wvC0dmGcl=Pxx02X;3WD3BcAZBXP35j%u;#oARm-1G|Qhh&pUu{qiuq64IRh8!wf*Yj!8sQ8lbK zfpthD9m%5kTZ8CS?eNyVQ}fo^&+mmt+-F*zV%`38`bYPhWegB)z9j1Z>HY!4qc6&M%^-Q0}U zJgyaWn*XW<>S*Z|G=6?# zX9vin46D8AzpQq$(e9Hurcn;SX%8MmDqW%aY!6-V8VgjIUfWi zF}U`)veqi+#cY63eA@Ko5XvZ_LTU6F8r#h4h9xD!(B!94)q3o@of+L17nFQY5NIimsBg1ery`{1%hl zWg#iW`MTr#bZVlQo=t!R+}HN`!C>)=C>C{qwZvUkFT5DZU!aqjTs{VBh*jd2hsL0& zOMHaIBSjXy?cUS?^kVs>#*Xs+qC1e)ONFN#Md7I-W}k>>T1&W=0pA0L3hKt-&nOLZ zk4V}`@N*xKVP*=dTRk;*`Xw^N)nEu(^hR_=Vk6r`lHX_8z%?#WcEGyZOS&DgXvz0kaCSd2=(_8SDJEs#WAk(Vj<@V_SQHge_or)Owa9RZ9I%d~-E2NCa&Lo`>UzJUip~TnPJ)j`wr4 za=z#w+FCSKaTt^W&~Zoy`X@Eb)Fr#G$IH1X0mh$@-N+N*2m-}|PVh1Yq(4*(bylzV zV%)73dWYK}R!}U(Ji5C60N`himF4M+M*WM6Jn?>1WFT9;(Lxv5{)TJ{03MrF0$}P3 z()%+PU3E*!w}elsgzd`;-f_bK+8YOq&+^d0 zjbV!lvQ9t0dQbCP5boHr)UZU%pEEXGyQi$e#aen%1e2o$N7o(QsM`X0AN(-6G1e`X z)*{M>72{9715e+FWVz^O?QCDLLzbsoPAHd79_pA3`9Us7N zv_k&UV|4CMrZ*>RvkxaTk-fQ=_qZ#0}v}%nM4i**% z2iz7+Dt0LLn-*H1@e@RMezo8)wY3*x~oA8jQ_QO&;TxHh{b7rq8{Q&(R-k1=>8-_L`Q{NFOH1nApD3 z6*b(x0Q7HCFrD8VdsfFHw{G#nqwRh*v?HxFcCZD||K0*&tJEGkW}{D}&r=qM(QdJu z?&^LZbpvRsq;@-ZOJaJ*&onUjHoQV*xq9;qIIKUC79mAHL~|^n~5)(EDC0cH&o5|I`O$tiA}<(=XCBfYk5v zF>HvFKaf}6$__r^*jkty>i3fC5NG7g?0B+6+yxw|zdm8sJUuVbU{HoXE?TQtA!3dp26SK@43phS;5BeKChDufWbqkc-LJ|x5$FSn>8Uk`X(oc z>uG0PckPxjbGI3?5*F&!v(MMu6ii+hA}5sMlxs0uXoz-vc}&0$@|Wy>8V83OIdowg zEj&@QG0V-BtZRu7q$8(s<(t$c=xoYM9;^M5h`9*&;XB< zWZ+b;!=b3f$SiwQKWLm|#3`qls|et_7gnTr-+jYd!w(Vck+=8}44mNcUZn@lFCL^( zyJvJdV=)#U1dXmjv+QZ7RuvbV%1ZsuQA~DIS-*c!nhs|L-ek;LQKP>KQmXA9g z+;C04(O+I=hdOmh?S1BH4$frNF{o?fPKmT+DKEBevzAZ@ylVvm&Zp;r1W%@HL2Ozw zabeXwz)~Hd;xTv=@RuOBglEn=Gaczyq4Xc?Q?VbOb<@EdI}?HE>^Z&w@dKI@uAH!0 z$LroD=vF_F>E{nwNgbPVF|CH|ILoz$%T9n#0m3Uh(J4NOu{)T*XXj1)RI$8;CjvNF z72-1o8N>>W=Ht>ItfwtP#^hVy19ZtVk3YDcjztqQMmcrnA9ZyzBJbnUp#a0AS+Xo+ zu$-jaz-Ei3NUw9(5F%McKU|=n)s2D*iARQayd^*7{iZAXPoJ9?J|9>hsTQD`hGDVF#pB7-5jpZ$B+y)xc*M3H$px5Mppk9~T1L)BH_;>AHvM|h4J`i++5tkHefg@j~ zHiI0F_ZJz?AID#Sn0^k=O2Vdte6Pdn5e!n^;IN7rKFzV6u(1GRt{H_=!u~AafK9K3 z-d6hZFc_>>BWa(Aqh=`7hiY{l_T_4GPFjR_NHp(b{DJ0rbu?!{93Dlq;S6}EYmrye zp?|zJ$3{t3obF*_vNUjnBg1WNtQW{Sn@8>*|4td}v(ayd-~Z*D(`;kZb*dJ;$P9d8 zRw3uwq5&NclK;}o@%4v9$6Xx9Yq=tj<482KXCgK_Us(pmpgw0@wyXeYadw;KuqaUI z&ZMvwP|rUJRSDMomZm3t%_-P6D}1H*3rGLq0H0lsz9=lCo8TYEP;n$id6IU&j#By- zvyU+S;F?6|Y4$Z$&bp3#uzQm162H77;>d2e8<~yy{zh=hyN%cMu&Dl4V4r!{Q~GBx z4?s7^^qdgw?*^`bVr1)lkE#L10G@kiNIet317Tn*sI_Q<%r6%-n)jq6-{At!0Q_Tu zN8_J8fb`tq*x8si_C_r>6rM7ISzZJ?t5HDUHPg_|RiFf{J@X_T5cw@Ryx++oyz(vJ zLDdZmVgScY*d2$UEjuB)TO!;JX3Q-uk^s4bVLWL%cJ^txcYwJ^0%|)}kON0iCV(+hcSzmBxG zE-RStxw%v|U>dDM!y`QIj(0{`B;mwdSArCBC%l@+7lpLZmWv2=nm4AS;P(2l>rC*E zh9A{uNe1iEo-U?3tm1-Q4|nZvJ^_j%Vkg=-SvMoRinI{eN%T8#RFe4wE_(B5mi!PP zP5e_ky)d6I1IQcb&ph?q?U5ItMn;!MP7g*pV$WZBwBO{rzj^=4y-)o=E{a}PW_nNr z989|tsfqvmCgAe*C7=Q6fI4^h7d05D`VfrLzSsUs)d!$urv)Jb4$y-C%hdk8v$FBr z>8X@Gh9lBHMdW`+1wNhmq3{Fj&(=Efojv;A(`Q?}=2qIh)-wiAi&cxwuV3(`^a<$l zuV7M_&3$OcmbwG2m{Y#BvI&;gna#F*&w#f5bzM*d(F6H46AI1m37Y?qa~r~@*+^!2S~3Dp?j*I4m2lvy}RYv8h*yU0q9qlcKx>tyha7xJ%*KEuozx* zS~K68E#eGsVM=b}lID!hVMC!y;76td4Dx&}s;XtvPv#*^PF1|74G~#xvk*%|uk8%r zpNFXbd>@<*O8$6CA-%{E7MLc($zoczIzIx)C2Fy*R>{X-b4)? z;kwAIn)Dv|7c*NJQv~Clzi^zuJAZ z$C)7{hE1-u$KckcOIBgs0LH>hJ5@t_i#w@HU{95j4LssD`7eI1997X|R?BqR*XkX* zysdfmsnq|%(KXs2y`mhpew8>PIlWW2xOY(BPb0Hax4E_!Ipx}VN;x|t(5iVU)(~b?v-!ae;DD|WmT|&tt_h_p5_AQ~iyt)r z2Bs!zi2mB@h2zD=UoWh!ygD@V)we1||;Xx?U-x2aUz8~J>Ii8RA zCvk&bEI4)1#@#E4_tS-#<-){$tQz}z58WWufBzy{%%5%UitiRLf&C*yAdkWDxqF? znIlx$$ibkX%^F8vwwRIDpcE+ITzxaWW_#tHJ0bcx z5{v@&*|T}I``;_vqjE9leUR4ud+;<%!?Apt8i7lC?{SpYy}3Mymbz^1PCMfV%U6%M zAb|Aq5XSJ*pvN6@cQl_6@ja~q7Y%l&n%U=uFBMJ zVE2TykOfsN+;!d}y&f7ruq=6b^6&B{<*JZ1>Ky;n6Qey1je$)@EhEtwj@TEUzRV_l zgwHVFMnx6~@5RpGNuT|m>ki`^_2@-xQ$X!Y3s90=@YX0HyLcz@BPRPQoNT9K5)-(UBH7P_Vo!613gE!P zb8<(&=iWTGtxj=)A%!d&wkl3|-vHM~?`ltVR;Fh0kR6bwkDc*y`7iQJPzQ)>Q6OmP zZU~~C12>BT^8T}D&fE?G^#s2N4s|tvkfj3dH8J0$MhRr5!p1<4@tHGy<5u8MJ35W5 z6lt?Lno`ZVXbydSnzdxWSF!T#+=R{4C%f3-f8X~(x48Xpa8>)?!A?{mAfUQ{iof^0 z&cDpCO03W4|EzG>*yTW? z8WjM;P8B0a^Kw9feWfN46i2~fj#7Dvb|{0`6L25m)~Xp|<@<2}qrJQ)YMF1UHihz3);1!aJNpViBMT7O=ip{2r{vZgCB&ZC0ALA12x4-T>>P z_aFD_fVwONn4eOjsDaMA>I+kbpzIe1at>67lUj)wh=0qQi$(GiYoATNx!Wmvi=e7$ zUTUxJNYKhuhA+TgoX(#C&No)ya;vY;0|Ar)vNm z4>C6_J_7cb2O**Ne=H*H4{m9kYrwrwgDwSKo++H>jj3cz`mw0EQ)^mX|T!_}s11mz}Qj%xJ79t!}VGSxAGp-4a&~n~_yQ<&u z-YL0rVe58r67iSq!wZ@#cdb|)C8xjLAyD%lbdgN0Y?DE>J;soIJlT>!VLGu-B zfmN9E2rWZ#5kdtuw#{{Ki)KmpesMzg!RD*4Z!ZSL(t%SRzJs;un>A+jM={QJo8GE} zM2S@oS^hv)timmB+uwqGZ#Hh)Tk=ny;i+N#f4^cj%*pX%b%zI@t2DHAa}5q-Ph!c! z^{YbH0EoM4_}J@NS0iBc`5bNGjLmL8oX`&AwZNzJ1D^uymYfM_x4^wde(_{4D1zMw zCXvgsBf)f$s*bVwB#xSH=^RzL0Ej;Mj19cMCN%99zSFI5dK1j@+X#?h1i4)Ige#lJ zw(lS0(!V^R{|^j!^;`e<_P>R^c^zk=Iw)o*ukUVK~`E={wa+ zep1Iyvq>;cCbdE*tUT25$BuCTAlW8=r%T>d>5e$N4jF}v+#4RH+sWf@MPq~8V1W_Z7u5>~~jvY=n zle^A8PB2RNBsqFTA>V{DEMTs#_^MHpEe#0zsyK%lVqK2gI1~B}jfft@S`dlo-Snj9 z$IGcbL?G(=qLNtW7#5mPEeq2rm@8xOH>jTX)?IcNI=XG$RUXMKN+9%WQiIW~8(4CQ zx9!V!Xrcx1Txz4`JTi4b*H)j%mm;uPudS@|_=B<5H2;!ZHpV4xe&s}`x0v$s&^-g<9qoIM>!)YP}mTM zw4G#E)iN`#+=%*XDb=~$Y!;{Y^K%WRimXjrRXB;w-f({T-L>{(aeSY)hi+XFsO zET%mzDK<%6g164j{oTj|gRBBO7eD9fbxBcFrk47hRdfBC)K4`p=80UhHiv^B zeT3du_LMbt$`9SQzdTSi@883R@*Qrc+81`F*GH10$8`qJ?G#%xmut1E>&zL^_WP5&ivcO(#|B^e7$v&ciMh=q=|k(j>p+CeR*N|DM{juv?vK=gWcVTAQYshWfo>Gi9HO zjbYE_-la-XXe57T8@G#8MyBga#^*k!{dh7OE)vt8ZH?41?_g^z((heQ6E9NinMT>$ z9Peih{%pr<0EHaFbmNz+tF#&`!mDX_YFKp3p2Ss>Cn~mAm08z`VALF4pIzSCQiNsN zTc%|ah*a1Cr`VWlJ*=h^$>~mSd_yyKt-bB6r61MV3@PP1;L3XUAJ#-|*5<$slwD>h zd^wl@*4RxvdXo(%xk;X>b-SsqHGzl|#D^<~369x|g-sB939n?RO`oGf+s18fEl(BG zn@H_Gk#-@=2(zJ^^B!G20+nAMRtlm)`3YlmuRePUUc78DW1++(CLMy+c+SxdS$ zT6Tl8n&AM~1K;-!_Dl-g3#A~MZe#fzCe*n4#mj28efHhgyk?B#wxZJWYwo+;8(+}p2GJi@57q+|Q_Yn?CraAG?dIkn1F zVLoedD}9TaVH${9rx~n@B6Gq6KHqw*^7P9d+MjJZd+U z*9PjK%lUP!LbMSX$?+s&VvPUeL|*9${K|3?@ zKjs(7=XQu~zAQQPG0xYTNzvTAPtqLQC6o?~&xXp*qm6gg)Fa_>Et#jNwv&h z#4McDP=D@|c6IIZY5j<*mPDP?*@|bE7 zQiMWV?dTDqo&?2EIOVRyEPWVnrMd(up{h)7V4?JUx+Ib<*2Fb~z9*=!)IAUPXez(( zE`A`hrTmOwYr?sf?)0x4n>{fpD@7*DSB>a1d}FScTX5xjM45!42lVDhw>GZv?C#j~ z?{RNC?>%x8QVNPTal90a8$c@$3+o{4P(G^}xuE~S{@cBS%6_ZN6JHyc`m|7+#{27Z z2-Qr24G~sj$K(K`z#nY|o5H&bi|bP)%%9N)O#X-yJ2iXiXs2(V2_y15Opw|zpTNqQ z0}9;bOEtGv(V3nZjYOpK4#^ivl}Y?zU>w`4SC-vs7jMIVW4I#?7Ks7I$6cl*i z>=Aj|AyexKh(H+4fxutW6gQa5v8eJ-?a zHWO!R;j{x1O1@2`lRXpi40C}IK1d#GNQQh_X~M#s{jzDx^q!6MG5#B6QlG9NpFU+>>d$PK#4_OWt~H} z(Obd^$`ROJv=$x+JlwDocAEW;`T;gc$=smM9Inh)A-geT$t1QhXohbW9WQZX?z>sL zTs5(I|2QUX@NW_s)F#~My5<1Y%dgffG)j-qj z2eN0+p8Wu72lgZL99}q$SIMm2#g)_XHltfUyGtCpFz?b_Lrh0VG^yGG@s}dIWui+= zFa$cxJ2K$wUI7wQP0)QzY~|BQJgD!xjYuWjndai=j*y3V)HB|YB!0V(^TxJjX{1kq z6IZw0z(}>bierd{yxu{OE8;((>CUSDKl+je`iVpuTU98tc&x_9N%A2s)bK{eTyx#8<`riOpXT9 zK2#&|;Rr8glx5s|Gm*GBq-9^d+SscH;^`jOet-eHh_8NVEP`qms`|;c)3F5<+Nxpf zae$&=F9JeN-T2beZYi|aR9{0q+}Kq z4Nc`p*&nZC{p|9bx4Yz-R70ACJI%tN?4XHN)a!G!tsvq1093W;+sLmM#8p7oYqss} zZ2>pJXbG!|L5H)wxAC6^?LbTR29gNjg{ez!e?V#}@2iU9*yu&=OWaudZi0PC%WJ^K zk>sA{$=|g}U1LXCda;$fv_uMNdG=*f`4>UIyrI-)j_VBjc;J9*v@l^}(^vIDzGm3Z zSkgf+tG@Jy`19#@WYupsjLx>Z#s;iwFx-jA*+)+HF(BBFTdnAp@tS%kkFvL{bhxw& zrfK3$(zXIA(0tjEXDI6*x5OPt|A?O{pA2;>NDq`%$IWrYfU~+GW;fZkT9L0(O%FEv zL`R?c@%V$O>vWgd8G4FpwgVrLA7jPax5IpkTVprnXjxNw79!>{Vn;8ADD_gNynRWc zBtSeDCmO$Q4mou~alYjTOxa`~>mm?0Y<9(LC?R_oC7m|?S46#@2!MhO^7sDi!ml_9 z!&|AWM#~EqLH2{TqZ^Bpg%;qUZ|doxOWEUy^H;{$U5D&#jz-;7ixQCIk8$Wqdo7-! zSLfqRCt|B--PU2|8yZ5Wb4g~D#cG3Efz0OhzT5bkXH{CT6MPTX|EFuy(~i zODz;~{Jo&1+I$(r`?Qqq-2xzzou$^na;sQCzkIae-*<}ED12kQ087E>{BRcX;V!Cr)40Y+ zHVk-V92mUe@4?T5BYG#P>Regq@tpwEspfYCXK5gO?I!eq&iZbD=MmnQ=FO+#t|PYe z_)B`vrAPncj#ahod#-CZ{iz6|A=6}vnozld7w2I7l(k{CU2`_~)F~E7=Mj%sCGs7N zCPejBJ;In*<-#tEjH~||{%;p7gn*(<%rZvCOw8ag3SDEDXceSLJ7Y+sNlQ2woo<6o# zIYhnk*@sjfj zm$5jvabVW4_MMhV9*vB1S#9LEwXYopfp+)5PPVDa9sibNh{+!rGjM^LNjv*j#&p>OdA5`4GdZVOx8H^}-jKUzy60 z9qkoEPV#@9X1@LU*99$ZP8a?62}Bhj4XMnOrox@ly&hI^55fGHqSzqh#F2m~#K zo^$-?2mbRM{<9wbSNBDRV-UGpSF6qhd8<7SOegQWdbT3HIVEuUkx`>*1`oLMP;w-d zB`6wNP5vQg4aUHujmeySUxOT8OUSx#9<9u`Sr?+I8|LFIlYy#9|I5bn53(*gt|tVo+J-D?$!Qtl>)y!xAqvK1BM=5sqc&fAENADUsh z(#~;5h9%sXkD6D9aaTR26uD;pwSTF|#BTdD2B}@!){eUw=JiqKF46Fke*Vi@fuE6o zl@Yf=Zoa4eOWO{fs58oE;oaRVaV5D5?0j4i{ElbM7hf(3cy;IunXs*ORZDnGjVot( zCwJqy{rNa_a(z~VU{MB}TIqV1fo&Ul7f6$nlbm#Y+>R$4jSYeiucbx!2AK!)=$;a= zpKztSZE2`jILxf&6a?>XmGQ706qwsvn<^1|IqR4a6ivg7zA#MzRlwk*@I8@J`I`d@Nah^4j(y?i-9^K>mCqOfpJy*rj5KFM4MGx%Ro`?B zvoQJWC)y5I8plf=$dNxvtlyMc8`XNZQrL#TQn5hT#rv~{Mh%y4M&=Z3*Qg}k7GGM0 zLOeA=S?3|S27yk-`~4ohW-fbY+dB(>zL?!Nd6BLT1uua{OTh1yiwEYDhfyr@Ni9X7add9VU^8dGfDic55gh?v@Dvbb<4ub zmh2ThRVIV@Vmc+0-#<%gP5Jfk*8=;b9^e&_pKYebQo(uHNnI@MxwG)G`DJ{NoLn~n zm$=}-$z{kNJUGi|d+62GVUyn9?14}UtHX~n#_&Z2kA``ankau2{Z8CN|xCE`pIaH z`1zU@sr9Uz(!($#Z++9HX&I|w!D&E8CR6z=f z?w(&(hEKOLI)3Hh$=E;4ixAn5!ES-qVxWlL$*%u!Lr$RZgC3ri5dP+(P8a3`mRpB{ z;puZPAzSldZ>Gg=?GEU&7sh8eSZu8$Wivx#lKov+XGy-m(c)8Z{lL`B@SwAM`g9srTQip^L-Mv6 zP&3RNKfAcLl1?zlG4Ncv0bsj@h~!qfPXb0eBjS| z=ofRTJJzf|Y6k!1| zkv$;Zli||2+WkHM_8Kyj)%V-qnS$cMgXsO!Vl$!dy0drh%&ilM|9;0GmtThis toggle is a write protector for live registers. To modify live register values, this toggle must be enabled, and the trace must be live and "at the present." Note that editing - recorded historical values is not permitted via the UI, regardless of this toggle, but can be - accomplished via scripts.

+ recorded historical values is not permitted, regardless of this toggle, but can be accomplished + via watches or scripts.

Snapshot Window

diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/DebuggerWatchesPlugin.html b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/DebuggerWatchesPlugin.html index d82b143c25..5247ccc4f5 100644 --- a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/DebuggerWatchesPlugin.html +++ b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/DebuggerWatchesPlugin.html @@ -61,14 +61,17 @@ possible.
  • Value - the raw bytes of the watched buffer. If the expression is a register, then this - is its hexadecimal value. If the value has changed since the last navigation event, this cell - is rendered in red.
  • + is its hexadecimal value. This field is user modifiable when the Enable Edits toggle + is on. Changes are sent to the target if the trace is live and "at the present." If the value + has changed since the last navigation event, this cell is rendered in red.
  • Type - the user-modifiable type of the watch. Note the type is not marked up in the trace. Clicking the Apply Data Type action will apply it to the current trace, if possible.
  • -
  • Representation - the value of the watch as interpreted by the selected data type.
  • +
  • Representation - the value of the watch as interpreted by the selected data type. This + field is not yet user modifiable, even if the Enable Edits toggle is on.
  • Error - if an error occurs during compilation or evaluation of the expression, that error is rendered here. Double-clicking the row will display the stack trace. Note that errors @@ -118,6 +121,14 @@

    This action is available when at least one watch is selected. It removes those watches.

    +

    Enable Edits

    + +

    This toggle is a write protector for recorded and/or live values. To modify a watch's value, + this toggle must be enabled. Editing a value when the trace is live and "at the present" will + cause the value to be modified on the target. Editing historical and/or emulated values is + permitted, but it has no effect on the target. Note that only the raw "Value" column can be + edited directly. The "Repr" column cannot be edited, yet.

    +

    Tool Options: Colors

    The watch window uses colors to hint about changes in and freshness of displayed values. diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/images/DebuggerWatchesPlugin.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/images/DebuggerWatchesPlugin.png index c9b63a6770a1d1580ec7d35139507e150b67f360..cc375abf7a27b8bf98b5119d21818577282b27b9 100644 GIT binary patch literal 19547 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 RdbA!S;pyt|;g=NkY3 diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerResources.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerResources.java index a6bf9b40b3..67047d5f53 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerResources.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerResources.java @@ -895,10 +895,10 @@ public interface DebuggerResources { } } - interface EnableRegisterEditsAction { + interface EnableEditsAction { String NAME = "Enable Edits"; - String DESCRIPTION = "Enable editing of recorded register values"; - String GROUP = "yyyy"; + String DESCRIPTION = "Enable editing of recorded or live values"; + String GROUP = "yyyy2"; Icon ICON = ResourceManager.loadImage("images/editbytes.gif"); String HELP_ANCHOR = "enable_edits"; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProvider.java index 06aa6b86fc..877baba0f2 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProvider.java @@ -604,7 +604,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter .onAction(c -> createSnapshotActivated()) .buildAndInstallLocal(this); } - actionEnableEdits = DebuggerResources.EnableRegisterEditsAction.builder(plugin) + actionEnableEdits = DebuggerResources.EnableEditsAction.builder(plugin) .enabledWhen(c -> current.getThread() != null) .onAction(c -> { }) @@ -758,12 +758,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter if (!computeEditsEnabled()) { return false; } - Collection onTarget = - current.getRecorder().getRegisterMapper(current.getThread()).getRegistersOnTarget(); - if (!onTarget.contains(register) && !onTarget.contains(register.getBaseRegister())) { - return false; - } - return true; + return current.getRecorder().isRegisterOnTarget(current.getThread(), register); } BigInteger getRegisterValue(Register register) { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProvider.java index 3498d7301a..87795d1c37 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProvider.java @@ -21,8 +21,7 @@ import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.function.BiConsumer; -import java.util.function.Function; +import java.util.function.*; import javax.swing.*; import javax.swing.table.TableColumn; @@ -31,6 +30,7 @@ import javax.swing.table.TableColumnModel; import docking.ActionContext; import docking.WindowPosition; import docking.action.DockingAction; +import docking.action.ToggleDockingAction; import docking.widgets.table.*; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; import ghidra.app.plugin.core.debug.DebuggerCoordinates; @@ -75,7 +75,7 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter { protected enum WatchTableColumns implements EnumeratedTableColumn { EXPRESSION("Expression", String.class, WatchRow::getExpression, WatchRow::setExpression), ADDRESS("Address", Address.class, WatchRow::getAddress), - VALUE("Value", String.class, WatchRow::getRawValueString), + VALUE("Value", String.class, WatchRow::getRawValueString, WatchRow::setRawValueString, WatchRow::isValueEditable), TYPE("Type", DataType.class, WatchRow::getDataType, WatchRow::setDataType), REPR("Repr", String.class, WatchRow::getValueString), ERROR("Error", String.class, WatchRow::getErrorMessage); @@ -83,19 +83,26 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter { private final String header; private final Function getter; private final BiConsumer setter; + private final Predicate editable; private final Class cls; @SuppressWarnings("unchecked") WatchTableColumns(String header, Class cls, Function getter, - BiConsumer setter) { + BiConsumer setter, Predicate editable) { this.header = header; this.cls = cls; this.getter = getter; this.setter = (BiConsumer) setter; + this.editable = editable; + } + + WatchTableColumns(String header, Class cls, Function getter, + BiConsumer setter) { + this(header, cls, getter, setter, null); } WatchTableColumns(String header, Class cls, Function getter) { - this(header, cls, getter, null); + this(header, cls, getter, null, null); } @Override @@ -120,7 +127,7 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter { @Override public boolean isEditable(WatchRow row) { - return setter != null; + return setter != null && (editable == null || editable.test(row)); } } @@ -267,6 +274,7 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter { protected GhidraTable watchTable; protected GhidraTableFilterPanel watchFilterPanel; + ToggleDockingAction actionEnableEdits; DockingAction actionApplyDataType; DockingAction actionSelectRange; DockingAction actionSelectAllReads; @@ -360,6 +368,11 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter { } protected void createActions() { + actionEnableEdits = DebuggerResources.EnableEditsAction.builder(plugin) + .enabledWhen(c -> current.getTrace() != null) + .onAction(c -> { + }) + .buildAndInstallLocal(this); actionApplyDataType = ApplyDataTypeAction.builder(plugin) .withContext(DebuggerWatchActionContext.class) .enabledWhen(ctx -> current.getTrace() != null && selHasDataType(ctx)) @@ -622,4 +635,8 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter { } watchTableModel.addAll(rows); } + + public boolean isEditsEnabled() { + return actionEnableEdits.isSelected(); + } } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/WatchRow.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/WatchRow.java index 16f79849ed..beab74594d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/WatchRow.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/WatchRow.java @@ -16,6 +16,7 @@ package ghidra.app.plugin.core.debug.gui.watch; import java.math.BigInteger; +import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Objects; @@ -38,12 +39,15 @@ import ghidra.trace.model.Trace; import ghidra.trace.model.memory.TraceMemorySpace; import ghidra.trace.model.memory.TraceMemoryState; import ghidra.trace.model.thread.TraceThread; -import ghidra.util.NumericUtilities; -import ghidra.util.Swing; +import ghidra.util.*; +import ghidra.util.database.UndoableTransaction; public class WatchRow { + public static final int TRUNCATE_BYTES_LENGTH = 64; + private final DebuggerWatchesProvider provider; private Trace trace; + private DebuggerCoordinates coordinates; private SleighLanguage language; private PcodeExecutor> executorWithState; private ReadDepsPcodeExecutor executorWithAddress; @@ -218,6 +222,7 @@ public class WatchRow { // NB. Caller has already verified coordinates actually changed prevValue = value; trace = coordinates.getTrace(); + this.coordinates = coordinates; updateType(); if (trace == null) { blank(); @@ -327,8 +332,12 @@ public class WatchRow { Utils.bytesToBigInteger(value, value.length, language.isBigEndian(), false); return "0x" + asBigInt.toString(16); } - if (value.length > 20) { - return "{ " + NumericUtilities.convertBytesToString(value, 0, 20, " ") + " ... }"; + if (value.length > TRUNCATE_BYTES_LENGTH) { + // TODO: I'd like this not to affect the actual value, just the display + // esp., since this will be the "value" when starting to edit. + return "{ " + + NumericUtilities.convertBytesToString(value, 0, TRUNCATE_BYTES_LENGTH, " ") + + " ... }"; } return "{ " + NumericUtilities.convertBytesToString(value, " ") + " }"; } @@ -345,6 +354,79 @@ public class WatchRow { return valueString; } + public boolean isValueEditable() { + return address != null && provider.isEditsEnabled(); + } + + public void setRawValueString(String valueString) { + valueString = valueString.trim(); + if (valueString.startsWith("{")) { + if (!valueString.endsWith("}")) { + throw new NumberFormatException("Byte array values must be hex enclosed in {}"); + } + + setRawValueBytesString(valueString.substring(1, valueString.length() - 1)); + return; + } + + setRawValueIntString(valueString); + } + + public void setRawValueBytesString(String bytesString) { + setRawValueBytes(NumericUtilities.convertStringToBytes(bytesString)); + } + + public void setRawValueIntString(String intString) { + intString = intString.trim(); + final BigInteger val; + if (intString.startsWith("0x")) { + val = new BigInteger(intString.substring(2), 16); + } + else { + val = new BigInteger(intString, 10); + } + setRawValueBytes( + Utils.bigIntegerToBytes(val, value.length, trace.getBaseLanguage().isBigEndian())); + } + + public void setRawValueBytes(byte[] bytes) { + if (address == null) { + throw new IllegalStateException("Cannot write to watch variable without an address"); + } + if (bytes.length != value.length) { + throw new IllegalArgumentException("Byte array values must match length of variable"); + } + + // Allow writes to unmappable registers to fall through to trace + // However, attempts to write "weird" register addresses is forbidden + if (coordinates.isAliveAndPresent() && coordinates.getRecorder() + .isVariableOnTarget(coordinates.getThread(), address, bytes.length)) { + coordinates.getRecorder() + .writeVariable(coordinates.getThread(), coordinates.getFrame(), address, bytes) + .exceptionally(ex -> { + Msg.showError(this, null, "Write Failed", + "Could not modify watch value (on target)", ex); + return null; + }); + // NB: if successful, recorder will write to trace + return; + } + + try (UndoableTransaction tid = + UndoableTransaction.start(trace, "Write watch at " + address, true)) { + final TraceMemorySpace space; + if (address.isRegisterAddress()) { + space = trace.getMemoryManager() + .getMemoryRegisterSpace(coordinates.getThread(), coordinates.getFrame(), + true); + } + else { + space = trace.getMemoryManager().getMemorySpace(address.getAddressSpace(), true); + } + space.putBytes(coordinates.getViewSnap(), address, ByteBuffer.wrap(bytes)); + } + } + public int getValueLength() { return value == null ? 0 : value.length; } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/TraceRecorder.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/TraceRecorder.java index d560555f43..1f587f7a55 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/TraceRecorder.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/TraceRecorder.java @@ -26,20 +26,22 @@ import ghidra.dbg.target.*; import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; import ghidra.lifecycle.Internal; +import ghidra.pcode.utils.Utils; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSetView; -import ghidra.program.model.lang.Register; -import ghidra.program.model.lang.RegisterValue; +import ghidra.program.model.lang.*; import ghidra.trace.model.Trace; import ghidra.trace.model.breakpoint.TraceBreakpoint; import ghidra.trace.model.breakpoint.TraceBreakpointKind; import ghidra.trace.model.memory.TraceMemoryRegion; +import ghidra.trace.model.memory.TraceMemoryRegisterSpace; import ghidra.trace.model.modules.TraceModule; import ghidra.trace.model.modules.TraceSection; import ghidra.trace.model.stack.TraceStackFrame; import ghidra.trace.model.thread.TraceThread; import ghidra.trace.model.time.TraceSnapshot; import ghidra.trace.model.time.TraceTimeManager; +import ghidra.trace.util.TraceRegisterUtils; import ghidra.util.task.TaskMonitor; /** @@ -331,6 +333,86 @@ public interface TraceRecorder { CompletableFuture> captureProcessMemory(AddressSetView selection, TaskMonitor monitor); + /** + * Write a variable (memory or register) of the given thread or the process + * + *

    + * This is a convenience for writing target memory or registers, based on address. If the given + * address represents a register, this will attempt to map it to a register and write it in the + * given thread and frame. If the address is in memory, it will simply delegate to + * {@link #writeProcessMemory(Address, byte[])}. + * + * @param thread the thread. Ignored (may be null) if address is in memory + * @param frameLevel the frame, usually 0. Ignored if address is in memory + * @param address the starting address + * @param data the value to write + * @return a future which completes when the write is complete + */ + default CompletableFuture writeVariable(TraceThread thread, int frameLevel, + Address address, byte[] data) { + if (address.isMemoryAddress()) { + return writeProcessMemory(address, data); + } + if (address.isRegisterAddress()) { + Language lang = getTrace().getBaseLanguage(); + Register register = lang.getRegister(address, data.length); + if (register == null) { + throw new IllegalArgumentException( + "Cannot identify the (single) register to write: " + address); + } + + RegisterValue rv = new RegisterValue(register, + Utils.bytesToBigInteger(data, data.length, lang.isBigEndian(), false)); + TraceMemoryRegisterSpace regs = + getTrace().getMemoryManager().getMemoryRegisterSpace(thread, frameLevel, false); + rv = TraceRegisterUtils.combineWithTraceBaseRegisterValue(rv, getSnap(), regs, true); + return writeThreadRegisters(thread, frameLevel, Map.of(rv.getRegister(), rv)); + } + throw new IllegalArgumentException("Address is not in a recognized space: " + address); + } + + /** + * Check if the given register exists on target (is mappable) for the given thread + * + * @param thread the thread whose registers to examine + * @param register the register to check + * @return true if the given register is known for the given thread on target + */ + default boolean isRegisterOnTarget(TraceThread thread, Register register) { + Collection onTarget = getRegisterMapper(thread).getRegistersOnTarget(); + return onTarget.contains(register) || onTarget.contains(register.getBaseRegister()); + } + + /** + * Check if the given trace address exists in target memory + * + * @param address the address to check + * @return true if the given trace address can be mapped to the target's memory + */ + default boolean isMemoryOnTarget(Address address) { + return getMemoryMapper().traceToTarget(address) != null; + } + + /** + * Check if a given variable (register or memory) exists on target + * + * @param thread if a register, the thread whose registers to examine + * @param address the address of the variable + * @param size the size of the variable. Ignored for memory + * @return true if the variable can be mapped to the target + */ + default boolean isVariableOnTarget(TraceThread thread, Address address, int size) { + if (address.isMemoryAddress()) { + return isMemoryOnTarget(address); + } + Register register = getTrace().getBaseLanguage().getRegister(address, size); + if (register == null) { + throw new IllegalArgumentException("Cannot identify the (single) register: " + address); + } + + return isRegisterOnTarget(thread, register); + } + /** * Capture the data types of a target's module. * diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/TraceRecorderAsyncPcodeExecutorState.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/TraceRecorderAsyncPcodeExecutorState.java index e513b0040f..b3b4b0b9d5 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/TraceRecorderAsyncPcodeExecutorState.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/TraceRecorderAsyncPcodeExecutorState.java @@ -25,10 +25,8 @@ import ghidra.pcode.exec.trace.TraceMemoryStatePcodeExecutorStatePiece; import ghidra.pcode.utils.Utils; import ghidra.program.model.address.*; import ghidra.program.model.lang.*; -import ghidra.trace.model.memory.TraceMemoryRegisterSpace; import ghidra.trace.model.memory.TraceMemoryState; import ghidra.trace.model.thread.TraceThread; -import ghidra.trace.util.TraceRegisterUtils; import ghidra.util.task.TaskMonitor; public class TraceRecorderAsyncPcodeExecutorState @@ -48,28 +46,7 @@ public class TraceRecorderAsyncPcodeExecutorState protected CompletableFuture doSetTargetVar(AddressSpace space, long offset, int size, boolean truncateAddressableUnit, byte[] val) { - if (space.isMemorySpace()) { - return recorder.writeProcessMemory(space.getAddress(offset), val); - } - assert space.isRegisterSpace(); - - Language lang = recorder.getTrace().getBaseLanguage(); - Register register = lang.getRegister(space, offset, size); - if (register == null) { - // TODO: Is this too restrictive? I can't imagine any code producing such nonsense - throw new IllegalArgumentException( - "write to register space must be to one register"); - } - - RegisterValue rv = new RegisterValue(register, Utils.bytesToBigInteger( - val, size, recorder.getTrace().getBaseLanguage().isBigEndian(), false)); - TraceMemoryRegisterSpace regs = recorder.getTrace() - .getMemoryManager() - .getMemoryRegisterSpace(traceState.getThread(), false); - rv = TraceRegisterUtils.combineWithTraceBaseRegisterValue(rv, traceState.getSnap(), - regs, true); - return recorder.writeThreadRegisters(traceState.getThread(), traceState.getFrame(), - Map.of(rv.getRegister(), rv)); + return recorder.writeVariable(traceState.getThread(), 0, space.getAddress(offset), val); } protected byte[] knitFromResults(NavigableMap map, Address addr, int size) { diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProviderTest.java index 8b09279d48..05976b2654 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProviderTest.java @@ -19,6 +19,7 @@ import static org.junit.Assert.*; import java.math.BigInteger; import java.nio.ByteBuffer; +import java.util.List; import org.apache.commons.lang3.exception.ExceptionUtils; import org.junit.*; @@ -27,6 +28,7 @@ import generic.Unique; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.services.TraceRecorder; +import ghidra.async.AsyncTestUtils; import ghidra.dbg.model.TestTargetRegisterBankInThread; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressRangeImpl; @@ -35,13 +37,15 @@ import ghidra.program.model.data.LongLongDataType; import ghidra.program.model.lang.Register; import ghidra.program.model.lang.RegisterValue; import ghidra.trace.model.Trace; +import ghidra.trace.model.memory.TraceMemoryOperations; import ghidra.trace.model.memory.TraceMemoryRegisterSpace; import ghidra.trace.model.thread.TraceThread; import ghidra.trace.util.TraceRegisterUtils; import ghidra.util.Msg; import ghidra.util.database.UndoableTransaction; -public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUITest { +public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUITest + implements AsyncTestUtils { protected static void assertNoErr(WatchRow row) { Throwable error = row.getError(); @@ -55,8 +59,12 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI protected DebuggerListingPlugin listingPlugin; protected Register r0; + protected Register r1; protected TraceThread thread; + protected TestTargetRegisterBankInThread bank; + protected TraceRecorder recorder; + @Before public void setUpWatchesProviderTest() throws Exception { watchesPlugin = addPlugin(tool, DebuggerWatchesPlugin.class); @@ -65,6 +73,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI createTrace(); r0 = tb.language.getRegister("r0"); + r1 = tb.language.getRegister("r1"); try (UndoableTransaction tid = tb.startTransaction()) { thread = tb.getOrAddThread("Thread1", 0); } @@ -189,7 +198,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI public void testLiveCausesReads() throws Exception { createTestModel(); mb.createTestProcessesAndThreads(); - TestTargetRegisterBankInThread bank = mb.testThread1.addRegisterBank(); + bank = mb.testThread1.addRegisterBank(); // Write before we record, and verify trace has not recorded it before setting watch mb.testProcess1.regs.addRegistersFromLanguage(tb.language, Register::isBaseRegister); @@ -198,7 +207,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI mb.testProcess1.addRegion(".text", mb.rng(0x00400000, 0x00401000), "rx"); mb.testProcess1.memory.writeMemory(mb.addr(0x00400000), tb.arr(1, 2, 3, 4)); - TraceRecorder recorder = modelService.recordTarget(mb.testProcess1, + recorder = modelService.recordTarget(mb.testProcess1, new TestDebuggerTargetTraceMapper(mb.testProcess1)); Trace trace = recorder.getTrace(); TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1)); @@ -231,4 +240,157 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI }); assertNoErr(row); } + + protected void runTestDeadIsEditable(String expression, boolean expectWritable) { + setRegisterValues(thread); + + performAction(watchesProvider.actionAdd); + WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + row.setExpression(expression); + + assertFalse(row.isValueEditable()); + traceManager.openTrace(tb.trace); + traceManager.activateThread(thread); + waitForSwing(); + + assertNoErr(row); + assertFalse(row.isValueEditable()); + + performAction(watchesProvider.actionEnableEdits); + assertEquals(expectWritable, row.isValueEditable()); + } + + @Test + public void testDeadIsRegisterEditable() { + runTestDeadIsEditable("r0", true); + } + + @Test + public void testDeadIsUniqueEditable() { + runTestDeadIsEditable("r0 + 8", false); + } + + @Test + public void testDeadIsMemoryEditable() { + runTestDeadIsEditable("*:8 r0", true); + } + + protected WatchRow prepareTestDeadEdit(String expression) { + setRegisterValues(thread); + + performAction(watchesProvider.actionAdd); + WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + row.setExpression("r0"); + + traceManager.openTrace(tb.trace); + traceManager.activateThread(thread); + performAction(watchesProvider.actionEnableEdits); + + return row; + } + + @Test + public void testDeadEditRegister() { + WatchRow row = prepareTestDeadEdit("r0"); + + row.setRawValueString("0x1234"); + waitForSwing(); + + TraceMemoryRegisterSpace regVals = + tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, false); + assertEquals(BigInteger.valueOf(0x1234), regVals.getValue(0, r0).getUnsignedValue()); + + row.setRawValueString("1234"); + waitForSwing(); + + assertEquals(BigInteger.valueOf(1234), regVals.getValue(0, r0).getUnsignedValue()); + } + + @Test + public void testDeadEditMemory() { + WatchRow row = prepareTestDeadEdit("*:8 r0"); + + row.setRawValueString("0x1234"); + waitForSwing(); + + TraceMemoryOperations mem = tb.trace.getMemoryManager(); + ByteBuffer buf = ByteBuffer.allocate(8); + mem.getBytes(0, tb.addr(0x00400000), buf); + buf.flip(); + assertEquals(0x1234, buf.getLong()); + + row.setRawValueString("{ 12 34 56 78 9a bc de f0 }"); + waitForSwing(); + buf.clear(); + mem.getBytes(0, tb.addr(0x00400000), buf); + buf.flip(); + assertEquals(0x123456789abcdef0L, buf.getLong()); + } + + protected WatchRow prepareTestLiveEdit(String expression) throws Exception { + createTestModel(); + mb.createTestProcessesAndThreads(); + bank = mb.testThread1.addRegisterBank(); + + mb.testProcess1.regs.addRegistersFromLanguage(tb.language, + r -> r != r1 && r.isBaseRegister()); + bank.writeRegister("r0", tb.arr(0, 0, 0, 0, 0, 0x40, 0, 0)); + mb.testProcess1.addRegion(".text", mb.rng(0x00400000, 0x00401000), "rx"); + + recorder = modelService.recordTarget(mb.testProcess1, + new TestDebuggerTargetTraceMapper(mb.testProcess1)); + Trace trace = recorder.getTrace(); + TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1)); + + traceManager.openTrace(trace); + traceManager.activateThread(thread); + waitForSwing(); + + performAction(watchesProvider.actionAdd); + WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + row.setExpression(expression); + performAction(watchesProvider.actionEnableEdits); + + return row; + } + + @Test + public void testLiveEditRegister() throws Throwable { + WatchRow row = prepareTestLiveEdit("r0"); + + row.setRawValueString("0x1234"); + retryVoid(() -> { + assertArrayEquals(tb.arr(0, 0, 0, 0, 0, 0, 0x12, 0x34), bank.regVals.get("r0")); + }, List.of(AssertionError.class)); + } + + @Test + public void testLiveEditMemory() throws Throwable { + WatchRow row = prepareTestLiveEdit("*:8 r0"); + + row.setRawValueString("0x1234"); + retryVoid(() -> { + assertArrayEquals(tb.arr(0, 0, 0, 0, 0, 0, 0x12, 0x34), + waitOn(mb.testProcess1.memory.readMemory(tb.addr(0x00400000), 8))); + }, List.of(AssertionError.class)); + } + + @Test + public void testLiveEditNonMappableRegister() throws Throwable { + WatchRow row = prepareTestLiveEdit("r1"); + TraceThread thread = recorder.getTraceThread(mb.testThread1); + + // Sanity check + assertFalse(recorder.isRegisterOnTarget(thread, r1)); + + row.setRawValueString("0x1234"); + waitForSwing(); + + TraceMemoryRegisterSpace regs = + recorder.getTrace().getMemoryManager().getMemoryRegisterSpace(thread, false); + assertEquals(BigInteger.valueOf(0x1234), + regs.getValue(recorder.getSnap(), r1).getUnsignedValue()); + + assertFalse(bank.regVals.containsKey("r1")); + } }