From 2860c293838471c1eea182499c83e686e59e871a Mon Sep 17 00:00:00 2001 From: dev747368 <48332326+dev747368@users.noreply.github.com> Date: Thu, 26 Dec 2024 18:26:48 -0500 Subject: [PATCH] GP-4870 add support for golang 1.23 Also fix namespace issue for interface, slices, ptrs, arrays, etc.Remove GoFuncID enum as it mutates between versionsFix stack storage logic for DWARF variables. --- Ghidra/Features/Base/certification.manifest | 1 + .../golang/golang_1.23_anybit_any.gdt | Bin 0 -> 11650 bytes .../core/analysis/GolangSymbolAnalyzer.java | 10 +- .../util/bin/format/dwarf/DWARFVariable.java | 7 +- .../util/bin/format/golang/GoBuildInfo.java | 95 +++++++++++++++++- .../bin/format/golang/rtti/GoFuncData.java | 20 ++-- .../util/bin/format/golang/rtti/GoFuncID.java | 49 --------- .../util/bin/format/golang/rtti/GoItab.java | 22 ++-- .../bin/format/golang/rtti/GoRttiMapper.java | 9 +- .../format/golang/rtti/types/GoArrayType.java | 21 +++- .../format/golang/rtti/types/GoFuncType.java | 8 +- .../golang/rtti/types/GoInterfaceType.java | 5 +- .../golang/rtti/types/GoPointerType.java | 20 +++- .../format/golang/rtti/types/GoSliceType.java | 6 +- .../bin/format/golang/rtti/types/GoType.java | 12 +-- .../core/datamgr/DataTypeArchiveIDTest.java | 5 +- .../languages/AARCH64_golang.register.info | 2 +- .../languages/x86-64-golang.register.info | 2 +- 18 files changed, 190 insertions(+), 104 deletions(-) create mode 100644 Ghidra/Features/Base/data/typeinfo/golang/golang_1.23_anybit_any.gdt delete mode 100644 Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoFuncID.java diff --git a/Ghidra/Features/Base/certification.manifest b/Ghidra/Features/Base/certification.manifest index 7f03be2e0c..f7159481fa 100644 --- a/Ghidra/Features/Base/certification.manifest +++ b/Ghidra/Features/Base/certification.manifest @@ -99,6 +99,7 @@ data/typeinfo/golang/golang_1.19_anybit_any.gdt||GHIDRA||||END| data/typeinfo/golang/golang_1.20_anybit_any.gdt||GHIDRA||||END| data/typeinfo/golang/golang_1.21_anybit_any.gdt||GHIDRA||||END| data/typeinfo/golang/golang_1.22_anybit_any.gdt||GHIDRA||||END| +data/typeinfo/golang/golang_1.23_anybit_any.gdt||GHIDRA||||END| data/typeinfo/golang/runtimesnapshot.go||GHIDRA||||END| data/typeinfo/mac_10.9/mac_osx.gdt||GHIDRA||||END| data/typeinfo/rust/rust-common.gdt||GHIDRA||||END| diff --git a/Ghidra/Features/Base/data/typeinfo/golang/golang_1.23_anybit_any.gdt b/Ghidra/Features/Base/data/typeinfo/golang/golang_1.23_anybit_any.gdt new file mode 100644 index 0000000000000000000000000000000000000000..3e0eaf6ac084405de822257fc3532cfbd1516544 GIT binary patch literal 11650 zcmb7q2Ut^C*RC_p$S5Ks2nwhu0YXtwP&#Ck76cLrZK$zOq)V5U%!mpI2mwN*k4Uf5 z2`!^iL&*pMq$?yKgd!&dNFlkI@4x?@`JZpTd!L)<$vNw+wfEU&?Y-B#);d)ihrSP2 zQn_+b{@UuL3x^IJ`sR?pjiCDvyu#f7BKYio{RDnGbld#!cc%{h@WT&>@_g?){I}rG zyCDB>0=Fj4e0vjz&AX<6B8?nd{~`MV4)UG@fcZ-FE2dP4m;Y1m}Kp|L{08 z+hX+9fGkYD*!X0P%#4`Pj|?RlnVVvP-x%2iUcT@xuV9kV=4wA{Po|Nmyu5+EeCG0S z?rNEH4~@>bkhP+}6}_U%&hnbyIvcuE$TVLWDqyob!>aV?%B845dPn?9-ul7Rr*Hn= z%YUbTUr2GJqwjZf;x8Ex=s#`J1uD58^uPW0f`8}i<3Nizt~A%v{9+gI_QLyqZ5dk= z`R7LZ0X^w5S3#Qb-N|Q_)2@gdSGv6s0rnFuzp7?iG(m@Px}bS0mwCz1PE3@sWRjb) zr2f{EfaljF@D4>&^cTXciF*_!OrQx&Okyiy@VuDUb>J381N3(K!CuFbfr{E&s7ZHK z(vqXGj^5VC+Jq3vELF7u`ilrVw|dNsQOOx?2fq0Ju)=wDV+mYW8ggV@|x=qMbITVp%5Ik(zbUL)ia=XcYV%!%*2=SqgVSV4d83VV1VYb2!Fd~YQ* zIOsytY=9fHm-4X2XNGGLKDpbNP;KcM%x<4xfZ2fhp7hCV)aIQAoT{K&%tBW%twJ3> z)e*Cj&5+WlX==!O)7@1zm%3`UL1%9f-mWq=-!06#0>iHE0se{0xM`mD_Kvk{W3-Q2 z4w1rcMeYS4p8uW zbq`QJBimypr2@3*koINpe%{%$XRaKK&u9~1a}nRobVNgzNQP384)14v$ZYAo^yYN( za?4E<@ymq9`e>gtyv@R$FaqSR6RVI6_{D;z{KJJap?9}bx{pP9qC8z1bhB2?laJi0 zYR#^WUA0ibV(%Ajrs{g)B5}xeJDTdy7nun9dLt*0vP*KQN-noR`iFNJ)_w3OohkuW zSu*5JS;JPDMCxc(*Jl;<+^OofoWO<8ar78x*9-^mi%uaq?k(l^Z`%c<0Fi$!4zu&2$-9r1?vw)F5jc_u$o1YMdutoZ}^WfVEmFNY>NVs})2Bg?k#PW2FW>9_#Uf zuK0?u_-a4yv8xleObJc!AZ`%&Q2S&S-Ld# z*s$@oOa0RaPcQFRLO$1Gdw;%kvbv%I*u!$#@aoY4Q&(m~?RwXJibsB}WR1mSMNcea zesx*?I5RpUR#owN#cy&ddwsqk+FB>Qzy(!oYH~WP%jJ_Kp*r8DwyGr4(Dho5d56#J zMf(~QjcVneq3EVubXJclU+x;9MIo5h~QnJ-dvMHlj+NW+l&gp z+^LYu6L9_Pfu?>V{I}!bpU95iig;yRZ@F$I0V{=16LIT$VXHME{+?(Z^?E*MDf4V+ z$kgKf)8`0}2I`;2=;NQh$CLjkj9)RXLGPAd508K)6Qmv5FG2K7t}P3nOjWROUWJsP ziXpcLh~aFA3LU+^gU7Fl?YR`iCY&YQSYx||DD>07~c<*O*a=V5 z{_yMDd<@qHu7c zdxU+iBTB|k%&b}cc`OghvQs4IAstuJ=c}c{(e25anO>YXX~_ZShy40q3Td6vNQ}=m zww9wscy2*UoLaONYA_z-h4v*qBfm8axU4?)bZ-+7IC4aNW=}YI>iOknM(YfVN;;=k zWkC~7bX>?Bd=av8t0|_@esTYbUwEch)Xl&d?p^x|uc^FBn=#SBYjbwwoeAe%Rj)@k zvz|F6O3r5xH_opgbs}9I_xI^JH=l7`4mOLmGc^b6F(a_tQKS%q;7ci*(T$hb*_9Y9@qbctwxC zp!1rSQ?#{;IoecJEupi)4-s;uzlO-?&E%h*e=Q|6;uB@S!n%iuWFa#)Ro(Se<{WBdXz1`{nJtJ+GAciRiyO6bN7vf z0$?YS@P4T@*ALUz&-qujjw3WdF3sbSDr=~BhRBj4}VmFB$B z9nSC)&9z>exioWa6x8(2le0WfNM2HeiTm}x_eQ!FUyFlUBP)ib1PqDuf! zhIDy!CNM=@Q7EX4&Ig$1|Gwq^js6`XblsT2Q@i)eDc0a4F+_oCtS?l*E9plW#-5tp z6Eb`7fh;0L6;ug5=uA2aV(hBvy&#VbelkEnR1b@qb#^30$}#}8!Zh;WU>OXdsv2u+ z7SoZGD96}V`xZy;8+;?F=KAaLLl>8%`~MJ9GkBaNB+uAU`yq?}lCsnM=i?}O21AXQ zO`aUQb5#xX>+!Gh{6^-VCJ`>g4w@Zw9(M=xd-Ab>FFylTn}3{C3R=3@pBjrmtH!qU z?+dEIa7mC0vFC5abRCzMT>|(2oQSAZeSc}-(NVSEUz4{6Us|cTK28EFEPdbq39Xj@ zOHx8nujjwb!~bCHgMVu#a=xUoct1lkEmGeFN=RRj5v{m)QM4$d;}$$M8z{^F5q^rK z`!Y54JN;KW=SMThdElKVj#5zC_f-w3U-K`>tzK^{KVtTWXc4s25uWPJ(9wV8AhPo$ z^AXf~$?eV|{Tn719!!Y3DLf90yqQyxB`n`)9@v$C;kCHMAENR^@ljE?v#~J!S7TlG zhc?v}PpaLmm;G{7P5hmk{*5DfXXqy+F5k`1zwrL{kdXYN|Izt>d*Jzynb)Z|4hTjJ ztwR;Q^VZ|QNtXlF*WW6nD5WT-D8m(M?Ob2~f33LX|GQiDJ0zYHyy0VWfKFMdjKR&Ex_C<`eiP^W%0g@7sx)|`3~h8M&G2U>i@n*4-rM%A6}WckCL8h(Va`T zR5?pLvFo0GSWw_d6yiWIDh*G07i`h%NWaH-U^3VvF0ru(%X_(B!)r7o%H2xHIeRBc zgs;vtSehh+%Rh_q#hrda2zP2zOZQ%CTSV%_$riH3V3cJqq&P}Ln4vfgfS(4l@2Oe-c5^JJxZ{{^%O6KCX| z)B!7+fEGaWFk&(clW8MKy{)3H=hq}7el8m57m^t^8I`$gVwaetKB}TN&v!8Epp_VS ze4_;3tZ1%3zW+N=j*+}%*2U4!5rb&uQ7?)F#?0hIyoE+kLjNhy%5#hB^-#W>+9)5wc>N*)zw|3K2^mdcn)Mp(FIVseZ{+vKd?l5wT#Vi@Y)JJ84+8jdP zUTpZ#50c4A`YvwB1N8P@z*UiTU8m&l*dr1il^kb^1&Ci_xZlaBSxVxR_F%sfrXl&e zIJ&k+EDuU?2Bkdj=>)jFIx8=+CK=AmE(SAP}+?k`W>o`em7s^6XNJ0lO zHxdN~yg@g7a1#9XCeIvoY@h8H$0#Qaox+dijz6BLQ3Hzl$N9jJ%U8XbtB+fI|8*0O z1ZSV3Ta?h{b>{aNT2cp+!Z3LZ+K&XOisRq*-^6IX3=VwLKKnrS!A7#lV?iJ%spA%9 z*knY6DGU-cn!g95zn!91n>=n9v^1Gl2KYe?>H%K|)B`>O?V3v?Joq^x4xbxsMzI6E zP3s!#$I7(uyZ0$v;wWstMXFpJ|K7R0ODX90egUI-KYmbT@6429P$}lV@w`uw6-6cZ zB&WHbo%9_pWl!p8O}6wEk)4fLlgCn7?aALweu^4mFlaJ+l1Ev)7eTe+cvAnAjI@Tx z*~Yz`%Fs6i{W}yzj6m|N3XsZ2s=`u7UpzHU`mXPt=}_`de@wqNdEB0yB6$?1AgwMk z>lZx>{i6kbCJPLhf!@xu6@%ZO^c~|jb+B<2^tSG6E9MjI%TbWEk%6B-5+wr^VLqJ& zBtQYDB8bq3m`Bt7k$*W-u8)jN(8GHGuPUcc+Q48s?`%D2uy2TG3v(Q@q`}>D8{^aE zBbt_ZkJR|^EnLLCnLfl*UwWEP77E?-Y~I;DQ5pmbi%p-Sx=jj)uB5g17ES7|TIcTc z&WE5Y$Wm*$nju;NWvk~U(w%6OW^KG>Cn#&vBIv^P<#X3ZbRBcU$;$|K&`i)kRgUw9 ztma3GJRL2w6ps2hV4;<@nVIOx$=6B<1lLV#NHCDX)cTpx)5X3O1!BPnQJ8o1g}kZO zUb7?}eu=9Z8S4(~6kF|xtJs$Qfkdr{{NX{uS?F$YyZO3S@NlI{dz>Y`)P0B;0xauB z)C*r@3Fgf}G9(qITUNBo{dO6?X!cI%mgIRpGTo{h;5z2hWHq%0LSyE*ASs*Ov*7j# zl{DVhCtqsZQW|y|@){+>1vg;X%u;pOTGh>pJpp!G4`<=Zm5=J91!@5w&#lV|E%QKm z9OTU8(gF9yGF!K5Yyp(J?z!PZSZG?c(7~w>E^FwInQ<$|u+y*fWA3v8Thlq(Ez*Vu zpqSO6+iEQ{t9{48>_B$g_=2|1i0Is+?WjO+H%FZ>>g zkV4rNz*=6%hJWngff&QhI;#~~|I4?odH$eTH(@sWW&X#V5_Nsk|G@AvN>k+zobm2ogF#s$Lg(*t3s#&R zeCV2HutcVl7C6E`WG55_)6FX~0eijhs~dr@Z@_o8BZOe{zBwyMKM`({W>u&fEpI4m zuwae~V(P8{r3Yy;nA~ zkdrs`Bz+1oyZ9z*Pb?ge%3QH@KiDJm|HYNvcK8=cuYb+}1O=L`yPA55|@3}>F#a#C%^KU~@J*Wopg5qpO}>I6Fm z3s*^k1M3==$kpdp=hKPW(h3K8rPBkhlzcP^wwqE!E+sulk8WgN{jx(wVI{*6D>KRJ zQvvrnd2io$=Jw#MI4`V@D=kac)pdLsb*~m(BNY}_ zqXcf~^2Vo+#trJ&`Qnn(R-&@ z`kUQE58b-@DOd>qHtP$1^fYEjczpfVi5!x;e({Ji%6~|I>=gRO$-q%P@Z~Q1CNSN< z))zCQ>_iFk#DFuLC>owuIfAIh9Y)u%LlTE!V9knLaGXLk+BKi59zitXoSp}|ey&;y zZ!++C(Z2H&ajJ4|ioF^XMkieN{Yt2@W?qLudbJyl@tVhm%kF&c)fHTkKK|jebNNAG zasBma#FT|oZdP-q)9Yc^yM+F|KX|#?KLhU*3v_m4VSzQ*W^ATLuh}+Vvm6;sQf;}$ z^m)bZTzVb!?EwAdSer3K9Qn}P~_WltxgPUaMZ07gjHmXK>gxsFLf!SN zYO3PKVZu^G#+A=is~oTP9slfyb|Lr_FYesq=yxONGYfx)Yc4TQ&cLg`g2J%saY33r z+r){x9rdAS!YA%p;zQ2_i_pVC-1NCPb6HkQ!D7|=bTxi`_w7den14`S`t0W_;7fDi zSY&nj#PX0{;97Q5F~N|oPMuyR>7$5)CTRz-drj#d&#GQ>;_QT!c$Qj*Kz?K=SdJX{ z#&Fpgwg;eMu~36swY%oxPnG)qPw8 zisRFrLQ1LV-UWwy!7PGg;nOVB$>a=H(wXu%DNM0X&R1tUXE%^WBEHBaDK)%JxpEi$ z`?%OKXZ-uO!-E0oSL0&g=>*{;3?5+TgrO>?C=_imvxv$GyvjMpf>a>4M>R&q*W7VG6o5^qkyk#LNx-$LF#@nb$}d^y1?yqfWVk))V@LRceFkQ$V6l%Lo`Fx9#zQDpn(;U zcRS};x2Rxcqp!yigXM4h&C#9Tp0s zD*^S4g7WAbV1r0Ppqhc;DtI%h1~{#Vu45=pgeyScOePU|FQ$T#M?_ZWdGWI*?HS?9 zTXhD*k+&jh0Rw6~wiJu}Ejk52Q4deFS9xX#D@h}`YP7LxPpq(0!Cn2*=x)~Mi9IF4 zZKeTDy?VC4w1qCS#$B zvq227;+~+kD4|P%nGAwCbAz~b8}$>j9ZN7}<`EYvIV#jGYc7f^eVcoO8m`Reb`l{) z90RJf9f|-5WI)O|7pcO^Xd|X+6{&$+2BawQUIHn~ye9x$iI)My5~Z!VtpGR!?Z`}@ zSaISd0i_v`jsF-|==f~__eRtF0DYGni%ronRH}-`+Mk)dOFim(*CJjFy?g91ysC9U zBFN3SS2-!S?p}#{{iYe@$MUN|IA}G-AEN_0C&S1OUsRV7GI0fs@;#Tf0eU9yYXB1T z-wyge-qG+#I^;fR)ndd%M$K!RnI};50P^wP%}EHGoUKb~iE-Q~b4U?~2VR}?;+^pX1@OVZcDG74w-qLW41Av)obXOUDWOk-lL+M z#hV)aWyd=2`auna+@-vw$5MIG?9`Gq!|XN1x)7f*u)5FKRBEQTq2qKqFYBx3=feAj z8jG#g=<2Ek9IC!V)DYd9 z{8FDPHZ56y({w?n>rr*al)iji$lZ{E$^(_-)LWY;OGN!H=AF?W1)_{rhrQ=@yU0mS zL%k|w-r$J~J*;}^TM1q3pAp5X0x74~1|2i6e&e<@@a9ku`POAZm57APPhnCL+CPn) zMr^8r70UN0@v@T2l5}H5>rj_vkEn*hhu%tlz3{Tu#)b05QLb#xkJwcW1BZ!r ziD{E-&+KFBIZ6hDy`tXw zB)h<@t+Q-yHZ(B0rph$Se~B*pw%4b6L^wh9_O?!?>A)jN?}(HW399u6L-biGgj%()A?v$2|{y@-R)Z=8$!4N5=Ki%8C zExEw0Q_gj^Kum++%J0$uW|2F{#XByp>AmTdPfB0a=$dG&Y6;XpJ*Si(@NA?4>}Ypm zpwY20OON=SDs>1*;}=mx%)%1_P9y|0ZQo|C061%x}(~ zI(~W}75=OH!?X$~g6$U9qP2WGt*I+Ed?j?Vii`reu2Kb;#{4)pbFP@>LH3?@?^U+u zLR1lfpYMs`xXv@f68^n&7(F95V&?Pi^&H5z;`t^jYkC|NF&uqpLrG=t zaQKsM;g9&A9?L&Mf8)n)-NTt5c7A)SRdY z!M^9I@YC+C29>>|)_$D#8pus2&#CAN-xNgWv5uO_q0x4b$Lg|(*2Jx6LyT@BYQYxbzNbryQzSkGP zay2zu@R`=={8Tzcov()$p662Vco?VZ`5dA?$4uQneRC0M6NrcK(z?f) zyupjxykiMyIa%&_>i#5OB%FW-$#REN_tA0P1Thg_7?h)XaeM1oH{rAh4+Z5+rS1#g zT!b7?;3>#*ms0oP{0Cch!fXN0qKEp3gMThaxE;vU1I)#6BoF}+$ei8t5yLIf@Tp-a z(b18Baex@{DO?HNoXmqmIeQi7@Y3wqWRmqt3xvO!_uv<|A-ET&9jT9udNu;jl_LTx zF%O`6;v)Q65WTp)mf9M<1>Os#`#N{+A(OMLR)Ir^PUp()f8B}hL(-A2rWwJo!>`a1vW~5iSk2VZXb{||= zFz;+68=J*6a9mgeM0;gin`gNIM#sI}$-ov*)*oCLH=nB`UkpHWIpE3X1{Y}NopodZ zXv`b3U_rI>T5_??`CHyLkepi z^Do+^l)*@AqeRUPbj(s)JzJ*U(0qwOYQq{O|*JetiTPp0kkj%ps^FQ}8FuTPyu<4wlwGH>& zBX}g16@!Q5y;{q4&y~kRux%drg^cZZ3d*|oVj9~_!V|g)cJH`=M`r{+rf{u#ze!^o zO0<}63cKr_!$UH*11PB5y)78_4T*4*%{@20Gx&w{ZC45k-fM_qYf2D|HcQ>2MexY9 zKr;&0w3nI6mXbgluAOmbL-X$CRY-NhlPj;onbA~1vX-JDv4I%;A5%yjzh~X9;Ud>Q zJZ8zTZ>}ZEJK$J_2}B0nt=5hYhxs@-9XL$fvQc5wAQs54IQ)$wtjvI`aew+6{fLI( zg(QWRqaA%+*677t*xGhViweUEu?6N|(8>%0pDOd146^5~81fMsLYkpWMJ#|B2&Zb= zN&;;qKCz&jgCiE_-(IUOGO${!9%)ix*deygkewWGk;>&rY-A;0v$+6C85e0+PLh11 z!f>$X_pfTurgJlvSUhi+PpY6rpi7;{O-S6Arc=}}n`u?|$ysVJj-sY@#<-&b@6B>>8{om7Nv zKm;D;+FC)#h&0zGT(W22lx+^Ej<)EC>?%YEarO_{yi(= zJxlxjn)VxSbi5HG_yL3N$q4pj&^@XL8MRjW@RmOv*DPWRg6~=iVz;bO=|GDjfxkV7 z()L^@Dw<3>IYAPhAPF_AOpb}ug3h!k6%=!PsV$1U-(oIKE@@C3um!L6iaYF??Nx&e zrtE*YM_?@Eu1n1p8@o`(NhSu^p;~|_zL*zD3+jYC;7bbXRVMdlunVtx1@}8cBSwOa zl7+9hjPp|dW7_xYw_s#FQjWoU8i~OM>>lfpQBL9Yg`D`CiTDTdH<1@#&JBc+&JP?1 zM_CKDoG4Mp+k|mPPST?kaCsnA&bvtVvrjh`o@$5}EJS<)R!;N|b<+xByoX($F3jhS z4xeV`=CvOYU@K=EcXVIsIKi93@srMtukxiNtVqe<{X>&~WBsy%9Vuj?C6azxJ8-A` zVl<`kH{m~#p91b9x;aqj0Xp getVarnodes() { List tmp = new ArrayList<>(storage); if (stackStorage != null) { - tmp.add(stackStorage); + // add stack storage to the front for LE and back of the list for BE + tmp.add(program.isBigEndian() ? tmp.size() : 0, stackStorage); } return tmp; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoBuildInfo.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoBuildInfo.java index f347e77d6a..8ec9af1c20 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoBuildInfo.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoBuildInfo.java @@ -4,9 +4,9 @@ * 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. @@ -25,6 +25,7 @@ import java.util.*; import ghidra.app.util.bin.*; import ghidra.app.util.bin.format.elf.info.ElfInfoItem; import ghidra.app.util.bin.format.golang.rtti.GoRttiMapper; +import ghidra.app.util.opinion.*; import ghidra.framework.options.Options; import ghidra.program.model.address.Address; import ghidra.program.model.data.*; @@ -59,6 +60,17 @@ public class GoBuildInfo implements ElfInfoItem { private static final int FLAG_ENDIAN = (1 << 0); private static final int FLAG_INLINE_STRING = (1 << 1); + // map from ghidra arch string to golang arch name + private static final Map GHIDRA_GOARCH_MAP = Map.of( + "aarch64_64", "arm64", + "arm_32", "arm", + "mips_64", "mips64", + "mips_32", "mips", + "x86_64", "amd64", + "x86_32", "386"); + + private static final Set GOLANG_DUALENDIAN_ARCH = Set.of("mips", "mips64", "ppc64"); + /** * Reads a GoBuildInfo ".go.buildinfo" section from the specified Program, if present. * @@ -209,6 +221,85 @@ public class GoBuildInfo implements ElfInfoItem { return buildSettings; } + public GoBuildSettings getBuildSetting(String key) { + return buildSettings + .stream() + .filter(buildSetting -> buildSetting.key().equals(key)) + .findFirst() + .orElse(null); + } + + /** + * Returns the Golang OS string for the specified program, either from previously parsed + * metadata value, or from a static Ghidra-loader to golang mapping. + * + * @param program {@link Program} + * @return golang GOOS string, see https://go.dev/doc/install/source#environment + */ + public String getGOOS(Program program) { + GoBuildSettings goos = getBuildSetting("GOOS"); + return goos != null ? goos.value() : getProgramGOOS(program); + } + + /** + * Returns a Golang "GOOS" string created by a mapping from the Ghidra program's loader type. + * + * @param program {@link Program} + * @return Golang "GOOS" string + */ + public static String getProgramGOOS(Program program) { + // TODO: this mapping needs more logic + String loaderName = program.getExecutableFormat(); + if (ElfLoader.ELF_NAME.equals(loaderName)) { + // TODO: this will require additional work to map all Golang OSs to Ghidra loader info + return "linux"; + } + else if (PeLoader.PE_NAME.equals(loaderName)) { + return "windows"; + } + else if (MachoLoader.MACH_O_NAME.equals(loaderName)) { + return "darwin"; + } + return "unknown"; + } + + /** + * Returns the Golang Arch string for the specified program, either from previously parsed + * metadata value, or from a static Ghidra language to golang mapping. + * + * @param program {@link Program} + * @return golang GOARCH string, see https://go.dev/doc/install/source#environment + */ + public String getGOARCH(Program program) { + GoBuildSettings goos = getBuildSetting("GOARCH"); + return goos != null ? goos.value() : getProgramGOARCH(program); + } + + /** + * Returns a Golang "GOARCH" string created by a mapping from the Ghidra program's language (arch). + * + * @param program {@link Program} + * @return Golang "GOARCH" string + */ + public static String getProgramGOARCH(Program program) { + String langArch = + "%s_%d".formatted( + getLanguageArch(program.getLanguageID().getIdAsString()).toLowerCase(), + program.getDefaultPointerSize() * 8); + + String goarch = GHIDRA_GOARCH_MAP.getOrDefault(langArch, "unknown"); + if (GOLANG_DUALENDIAN_ARCH.contains(goarch) && !program.getMemory().isBigEndian()) { + // golang seems to mark the LE variant and assumes BE as the default if not marked + goarch += "le"; + } + return goarch; + } + + private static String getLanguageArch(String langId) { + int firstColon = langId.indexOf(':'); + return firstColon > 0 ? langId.substring(0, firstColon) : langId; + } + @Override public void markupProgram(Program program, Address address) { decorateProgramInfo(program.getOptions(Program.PROGRAM_INFO)); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoFuncData.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoFuncData.java index 01c3660f2f..9377410ec7 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoFuncData.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoFuncData.java @@ -69,8 +69,7 @@ public class GoFuncData implements StructureMarkup { private long cuOffset = -1; @FieldMapping - @EOLComment("getFuncIDEnum") - private byte funcID; // see GoFuncID enum + private byte funcID; @FieldMapping(presentWhen = "1.17+") @EOLComment("flags") @@ -344,14 +343,6 @@ public class GoFuncData implements StructureMarkup { return GoFuncFlag.ASM.isSet(flag); } - /** - * Returns the {@link GoFuncID} enum that categorizes this function - * @return the {@link GoFuncID} enum that categorizes this function - */ - public GoFuncID getFuncIDEnum() { - return GoFuncID.parseIDByte(funcID); - } - /** * Returns information about the source file that this function was defined in. * @@ -407,6 +398,11 @@ public class GoFuncData implements StructureMarkup { return getName(); } + @Override + public String getStructureNamespace() throws IOException { + return getSymbolName().packagePath(); + } + @Override public void additionalMarkup(MarkupSession session) throws IOException, CancelledException { if (npcdata > 0) { @@ -414,14 +410,14 @@ public class GoFuncData implements StructureMarkup { -1, programContext.getDTM()); Address addr = context.getStructureAddress().add(getPcDataStartOffset(0)); session.markupAddress(addr, pcdataArrayDT); - session.labelAddress(addr, getStructureLabel() + "___pcdata"); + session.labelAddress(addr, getStructureLabel() + "___pcdata", getStructureNamespace()); } if (nfuncdata > 0) { ArrayDataType funcdataArrayDT = new ArrayDataType(programContext.getUint32DT(), nfuncdata, -1, programContext.getDTM()); Address addr = context.getStructureAddress().add(getPcDataStartOffset(npcdata)); session.markupAddress(addr, funcdataArrayDT); - session.labelAddress(addr, getStructureLabel() + "___funcdata"); + session.labelAddress(addr, getStructureLabel() + "___funcdata", getStructureNamespace()); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoFuncID.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoFuncID.java deleted file mode 100644 index 791d8575f7..0000000000 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoFuncID.java +++ /dev/null @@ -1,49 +0,0 @@ -/* ### - * 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.util.bin.format.golang.rtti; - -/** - * List of function ids for runtime._func (GoFuncData) funcID field. - */ -public enum GoFuncID { - NORMAL, - ABORT, - ASMCGOCALL, - ASYNCPREEMPT, - CGOCALLBACK, - DEBUGCALLV2, - GCBGMARKWORKER, - GOEXIT, - GOGO, - GOPANIC, - HANDLEASYNCEVENT, - MCALL, - MORESTACK, - MSTART, - PANICWRAP, - RT0_GO, - RUNFINQ, - RUNTIME_MAIN, - SIGPANIC, - SYSTEMSTACK, - SYSTEMSTACK_SWITCH, - WRAPPER; - - public static GoFuncID parseIDByte(int b) { - GoFuncID[] values = values(); - return 0 <= b && b < values.length ? values[b] : null; - } -} diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoItab.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoItab.java index 3a4007e3ca..833e36f9c2 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoItab.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoItab.java @@ -4,9 +4,9 @@ * 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. @@ -32,7 +32,7 @@ import ghidra.util.Msg; * the interface. */ @PlateComment -@StructureMapping(structureName = "runtime.itab") +@StructureMapping(structureName = {"runtime.itab", "internal/abi.ITab"}) public class GoItab implements StructureMarkup { @ContextField private GoRttiMapper programContext; @@ -40,11 +40,11 @@ public class GoItab implements StructureMarkup { @ContextField private StructureContext context; - @FieldMapping + @FieldMapping(fieldName = {"inter", "Inter"}) @MarkupReference("getInterfaceType") long inter; // runtime.interfacetype * - @FieldMapping + @FieldMapping(fieldName = {"_type", "Type"}) @MarkupReference("getType") long _type; // runtime._type * @@ -59,7 +59,8 @@ public class GoItab implements StructureMarkup { */ @Markup public GoInterfaceType getInterfaceType() throws IOException { - return programContext.readStructure(GoInterfaceType.class, inter); + GoType result = programContext.getGoType(inter); + return result instanceof GoInterfaceType ifaceType ? ifaceType : null; } /** @@ -172,6 +173,11 @@ public class GoItab implements StructureMarkup { return context; } + @Override + public String getStructureNamespace() throws IOException { + return getType().getStructureNamespace(); + } + @Override public void additionalMarkup(MarkupSession session) throws IOException { GoSlice funSlice = getFunSlice(); @@ -185,8 +191,8 @@ public class GoItab implements StructureMarkup { GoSlice extraFunSlice = funSlice.getSubSlice(1, funSlice.getLen() - 1, programContext.getPtrSize()); - extraFunSlice.markupArray(getStructureName() + "_extra_itab_functions", null, - (DataType) null, true, session); + extraFunSlice.markupArray(getStructureName() + "_extra_itab_functions", + getStructureNamespace(), (DataType) null, true, session); } @Override diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoRttiMapper.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoRttiMapper.java index 891d828e1f..29885217e8 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoRttiMapper.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoRttiMapper.java @@ -82,7 +82,7 @@ import ghidra.util.task.UnknownProgressWrappingTaskMonitor; */ public class GoRttiMapper extends DataTypeMapper implements DataTypeMapperContext { public static final GoVer SUPPORTED_MIN_VER = new GoVer(1, 15); - public static final GoVer SUPPORTED_MAX_VER = new GoVer(1, 22); + public static final GoVer SUPPORTED_MAX_VER = new GoVer(1, 23); private static final List SYMBOL_SEARCH_PREFIXES = List.of("", "_" /* macho symbols */); private static final List SECTION_PREFIXES = @@ -1162,6 +1162,13 @@ public class GoRttiMapper extends DataTypeMapper implements DataTypeMapperContex GoType type = it.next(); type.discoverGoTypes(discoveredTypes); } + for (GoItab itab : module.getItabs()) { + upwtm.checkCancelled(); + upwtm.setProgress(discoveredTypes.size()); + + itab.getInterfaceType().discoverGoTypes(discoveredTypes); + itab.getType().discoverGoTypes(discoveredTypes); + } } // Fix non-unique type names, which can happen when types are embedded inside a function, diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoArrayType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoArrayType.java index f17c7f4e07..4cfc9b6d5d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoArrayType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoArrayType.java @@ -4,9 +4,9 @@ * 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. @@ -81,6 +81,23 @@ public class GoArrayType extends GoType { private boolean isValidLength() { return 0 <= len && len <= Integer.MAX_VALUE; } + + @Override + public String getPackagePathString() { + String ppStr = super.getPackagePathString(); + if (ppStr == null || ppStr.isEmpty()) { + try { + GoType elemType = getElement(); + if (elemType != null) { + ppStr = elemType.getPackagePathString(); + } + } + catch (IOException e) { + // fall thru + } + } + return ppStr; + } @Override public boolean discoverGoTypes(Set discoveredTypes) throws IOException { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoFuncType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoFuncType.java index af85ddff3f..05753e9fb0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoFuncType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoFuncType.java @@ -4,9 +4,9 @@ * 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. @@ -23,6 +23,7 @@ import ghidra.app.util.bin.format.golang.rtti.GoSlice; import ghidra.app.util.bin.format.golang.structmapping.*; import ghidra.program.model.address.Address; import ghidra.program.model.data.*; +import ghidra.util.exception.CancelledException; /** * A {@link GoType} structure that defines a function type. @@ -117,7 +118,8 @@ public class GoFuncType extends GoType { } @Override - public void additionalMarkup(MarkupSession session) throws IOException { + public void additionalMarkup(MarkupSession session) throws IOException, CancelledException { + super.additionalMarkup(session); GoSlice slice = getParamListSlice(); slice.markupArray(getStructureLabel() + "_paramlist", getStructureNamespace(), GoBaseType.class, true, session); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoInterfaceType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoInterfaceType.java index 8382a02844..68181c08a2 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoInterfaceType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoInterfaceType.java @@ -4,9 +4,9 @@ * 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. @@ -73,6 +73,7 @@ public class GoInterfaceType extends GoType { @Override public void additionalMarkup(MarkupSession session) throws IOException, CancelledException { + super.additionalMarkup(session); mhdr.markupArray(null, getStructureNamespace(), GoIMethod.class, false, session); mhdr.markupArrayElements(GoIMethod.class, session); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoPointerType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoPointerType.java index 6d4824a31b..d6ff730e38 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoPointerType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoPointerType.java @@ -4,9 +4,9 @@ * 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. @@ -68,6 +68,22 @@ public class GoPointerType extends GoType { } return true; } + + @Override + public String getPackagePathString() { + String ppStr = super.getPackagePathString(); + if ( ppStr == null || ppStr.isEmpty() ) { + try { + GoType elemType = getElement(); + if ( elemType != null ) { + ppStr = elemType.getPackagePathString(); + } + } catch (IOException e) { + // fall thru + } + } + return ppStr; + } @Override public String getStructureNamespace() throws IOException { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoSliceType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoSliceType.java index 741355ccb6..dad0508764 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoSliceType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoSliceType.java @@ -4,9 +4,9 @@ * 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. @@ -93,7 +93,7 @@ public class GoSliceType extends GoType { @Override public String getStructureNamespace() throws IOException { String packagePath = getPackagePathString(); - if (packagePath != null) { + if (packagePath != null && !packagePath.isEmpty() ) { return packagePath; } GoType elementType = getElement(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoType.java index e7836716cc..cb19c34473 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/types/GoType.java @@ -4,9 +4,9 @@ * 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. @@ -190,14 +190,10 @@ public abstract class GoType implements StructureMarkup { GoUncommonType ut = getUncommonType(); if (ut != null) { GoSlice slice = ut.getMethodsSlice(); - slice.markupArray(getStructureName() + "_methods", getStructureNamespace(), + slice.markupArray(getStructureLabel() + "_methods", getStructureNamespace(), GoMethod.class, false, session); slice.markupArrayElements(GoMethod.class, session); - - session.labelStructure(ut, - typ.getName() + "_" + - programContext.getStructureDataTypeName(GoUncommonType.class), - getStructureNamespace()); + session.labelStructure(ut, getStructureLabel() + "_uncommon", getStructureNamespace()); } } diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datamgr/DataTypeArchiveIDTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datamgr/DataTypeArchiveIDTest.java index 4cbcc7b02b..71390fceb2 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datamgr/DataTypeArchiveIDTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/datamgr/DataTypeArchiveIDTest.java @@ -4,9 +4,9 @@ * 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. @@ -53,6 +53,7 @@ public class DataTypeArchiveIDTest extends AbstractGenericTest { Map.entry("typeinfo/golang/golang_1.20_anybit_any.gdt", "3533817003441909616"), Map.entry("typeinfo/golang/golang_1.21_anybit_any.gdt", "3574190573109087960"), Map.entry("typeinfo/golang/golang_1.22_anybit_any.gdt", "3596108668808850319"), + Map.entry("typeinfo/golang/golang_1.23_anybit_any.gdt", "3629085086035854850"), Map.entry("typeinfo/rust/rust-common.gdt", "3557867258392862055")); //@formatter:on diff --git a/Ghidra/Processors/AARCH64/data/languages/AARCH64_golang.register.info b/Ghidra/Processors/AARCH64/data/languages/AARCH64_golang.register.info index 683cba8998..01544d09b1 100644 --- a/Ghidra/Processors/AARCH64/data/languages/AARCH64_golang.register.info +++ b/Ghidra/Processors/AARCH64/data/languages/AARCH64_golang.register.info @@ -1,6 +1,6 @@ - + diff --git a/Ghidra/Processors/x86/data/languages/x86-64-golang.register.info b/Ghidra/Processors/x86/data/languages/x86-64-golang.register.info index 802caffb0a..c21bc9ad15 100644 --- a/Ghidra/Processors/x86/data/languages/x86-64-golang.register.info +++ b/Ghidra/Processors/x86/data/languages/x86-64-golang.register.info @@ -1,6 +1,6 @@ - +