Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PPC: Instruction Disassembly/Lifting Completion #4023

Open
lwerdna opened this issue Sep 15, 2017 · 21 comments
Open

PPC: Instruction Disassembly/Lifting Completion #4023

lwerdna opened this issue Sep 15, 2017 · 21 comments
Labels
Arch: PowerPC Issues with the PowerPC architecture plugin Component: Architecture Issue needs changes to an architecture plugin Impact: Medium Issue is impactful with a bad, or no, workaround Type: Enhancement Issue is a small enhancement to existing functionality

Comments

@lwerdna
Copy link
Contributor

lwerdna commented Sep 15, 2017

The following is the list of instructions which we currently disassemble and lift (Fully or Partially). If you have any instructions which differ from this table, there is likely a bug or a documentation failure, please let us know.

Mnem Disasm Lifting
add Full Full
addc Full Full
adde Full Full
addi Full Full
addic Full Full
addis Full None
addme Full None
addze Full None
and Full None
andc Full None
andi Full None
andis Full None
b Full Full
ba Full Full
bc Full Full
bca Full None
bcctr Full Full
bcctrl Full Full
bcl Full None
bcla Full None
bclr Full None
bclrl Full None
bctr Full Full
bctrl Full Full
bdnz Full None
bdnza Full None
bdnzf Full None
bdnzfa Full None
bdnzfl Full None
bdnzfla Full None
bdnzflrl Full None
bdnzl Full None
bdnzla Full None
bdnzlr Full None
bdnzlrl Full None
bdnzt Full None
bdnzta Full None
bdnztl Full None
bdnztla Full None
bdnztlr Full None
bdnztlrl Full None
bdz Full None
bdza Full None
bdzf Full None
bdzfa Full None
bdzfl Full None
bdzfla Full None
bdzflr Full None
bdzflrl Full None
bdzl Full None
bdzla Full None
bdzlr Full None
bdzlrl Full None
bdzt Full None
bdzta Full None
bdztl Full None
bdztla Full None
bdztlr Full None
bdztlrl Full None
bf Full None
bfa Full None
bfctr Full None
bfctrl Full None
bfl Full None
bfla Full None
bflr Full None
bflrl Full None
bl Full Full
bla Full Full
blr Full Full
blrl Full Full
brinc Full None
bt Full None
bta Full None
btctr Full None
btctrl Full None
btl Full None
btla Full None
btlr Full None
btlrl Full None
clrldi Full None
clrlwi Full None
cmpd Full Full
cmpdi Full Full
cmpld Full Full
cmpldi Full Full
cmplw Full Full
cmplwi Full Full
cmpw Full Full
cmpwi Full Full
cntlzd Full None
cntlzw Full None
crand Full None
crandc Full None
crclr Full None
creqv Full None
crmove Full None
crnand Full None
crnor Full None
crnot Full None
cror Full None
crorc Full None
crset Full None
crxor Full None
dcba Full None
dcbf Full None
dcbi Full None
dcbst Full None
dcbt Full None
dcbtst Full None
dcbz Full None
dcbzl Full None
dccci Full None
divd Full None
divdu Full None
divw Full None
divwu Full None
dss Full None
dssall Full None
dst Full None
dstst Full None
dststt Full None
dstt Full None
eieio Full None
eqv Full None
evabs Full None
evaddiw Full None
evaddsmiaaw Full None
evaddssiaaw Full None
evaddumiaaw Full None
evaddusiaaw Full None
evaddw Full None
evand Full None
evandc Full None
evcmpeq Full None
evcmpgts Full None
evcmpgtu Full None
evcmplts Full None
evcmpltu Full None
evcntlsw Full None
evcntlzw Full None
evdivws Full None
evdivwu Full None
eveqv Full None
evextsb Full None
evextsh Full None
evldd Full None
evlddx Full None
evldh Full None
evldhx Full None
evldw Full None
evldwx Full None
evlhhesplat Full None
evlhhesplatx Full None
evlhhossplat Full None
evlhhossplatx Full None
evlhhousplat Full None
evlhhousplatx Full None
evlwhe Full None
evlwhex Full None
evlwhos Full None
evlwhosx Full None
evlwhou Full None
evlwhoux Full None
evlwhsplat Full None
evlwhsplatx Full None
evlwwsplat Full None
evlwwsplatx Full None
evmergehi Full None
evmergehilo Full None
evmergelo Full None
evmergelohi Full None
evmhegsmfaa Full None
evmhegsmfan Full None
evmhegsmiaa Full None
evmhegsmian Full None
evmhegumiaa Full None
evmhegumian Full None
evmhesmf Full None
evmhesmfa Full None
evmhesmfaaw Full None
evmhesmfanw Full None
evmhesmi Full None
evmhesmia Full None
evmhesmiaaw Full None
evmhesmianw Full None
evmhessf Full None
evmhessfa Full None
evmhessfaaw Full None
evmhessfanw Full None
evmhessiaaw Full None
evmhessianw Full None
evmheumi Full None
evmheumia Full None
evmheumiaaw Full None
evmheumianw Full None
evmheusiaaw Full None
evmheusianw Full None
evmhogsmfaa Full None
evmhogsmfan Full None
evmhogsmiaa Full None
evmhogsmian Full None
evmhogumiaa Full None
evmhogumian Full None
evmhosmf Full None
evmhosmfa Full None
evmhosmfaaw Full None
evmhosmfanw Full None
evmhosmi Full None
evmhosmia Full None
evmhosmiaaw Full None
evmhosmianw Full None
evmhossf Full None
evmhossfa Full None
evmhossfaaw Full None
evmhossfanw Full None
evmhossiaaw Full None
evmhossianw Full None
evmhoumi Full None
evmhoumia Full None
evmhoumiaaw Full None
evmhoumianw Full None
evmhousiaaw Full None
evmhousianw Full None
evmra Full None
evmwhsmf Full None
evmwhsmfa Full None
evmwhsmi Full None
evmwhsmia Full None
evmwhssf Full None
evmwhssfa Full None
evmwhumi Full None
evmwhumia Full None
evmwlsmiaaw Full None
evmwlsmianw Full None
evmwlssiaaw Full None
evmwlssianw Full None
evmwlumi Full None
evmwlumia Full None
evmwlumiaaw Full None
evmwlumianw Full None
evmwlusiaaw Full None
evmwlusianw Full None
evmwsmf Full None
evmwsmfa Full None
evmwsmfaa Full None
evmwsmfan Full None
evmwsmi Full None
evmwsmia Full None
evmwsmiaa Full None
evmwsmian Full None
evmwssf Full None
evmwssfa Full None
evmwssfaa Full None
evmwssfan Full None
evmwumi Full None
evmwumia Full None
evmwumiaa Full None
evmwumian Full None
evnand Full None
evneg Full None
evnor Full None
evor Full None
evorc Full None
evrlw Full None
evrlwi Full None
evrndw Full None
evslw Full None
evslwi Full None
evsplatfi Full None
evsplati Full None
evsrwis Full None
evsrwiu Full None
evsrws Full None
evsrwu Full None
evstdd Full None
evstddx Full None
evstdh Full None
evstdhx Full None
evstdw Full None
evstdwx Full None
evstwhe Full None
evstwhex Full None
evstwho Full None
evstwhox Full None
evstwwe Full None
evstwwex Full None
evstwwo Full None
evstwwox Full None
evsubfsmiaaw Full None
evsubfssiaaw Full None
evsubfumiaaw Full None
evsubfusiaaw Full None
evsubfw Full None
evsubifw Full None
evxor Full None
extsb Full None
extsh Full None
extsw Full None
fabs Full None
fadd Full None
fadds Full None
fcfid Full None
fcfids Full None
fcfidu Full None
fcfidus Full None
fcmpu Full None
fcpsgn Full None
fctid Full None
fctiduz Full None
fctidz Full None
fctiw Full None
fctiwuz Full None
fctiwz Full None
fdiv Full None
fdivs Full None
fmadd Full None
fmadds Full None
fmr Full None
fmsub Full None
fmsubs Full None
fmul Full None
fmuls Full None
fnabs Full None
fneg Full None
fnmadd Full None
fnmadds Full None
fnmsub Full None
fnmsubs Full None
fre Full None
fres Full None
frim Full None
frin Full None
frip Full None
friz Full None
frsp Full None
frsqrte Full None
frsqrtes Full None
fsel Full None
fsqrt Full None
fsqrts Full None
fsub Full None
fsubs Full None
icbi Full None
iccci Full None
isel Full None
isync Full None
la Full Full
lbz Full None
lbzu Full None
lbzux Full None
lbzx Full None
ld Full None
ldarx Full None
ldbrx Full None
ldu Full None
ldux Full None
ldx Full None
lfd Full None
lfdu Full None
lfdux Full None
lfdx Full None
lfiwax Full None
lfiwzx Full None
lfs Full None
lfsu Full None
lfsux Full None
lfsx Full None
lha Full None
lhau Full None
lhaux Full None
lhax Full None
lhbrx Full None
lhz Full None
lhzu Full None
lhzux Full None
lhzx Full None
li Full Full
lis Full Full
lmw Full Full
lswi Full None
lvebx Full None
lvehx Full None
lvewx Full None
lvsl Full None
lvsr Full None
lvx Full None
lvxl Full None
lwa Full None
lwarx Full None
lwaux Full None
lwax Full None
lwbrx Full None
lwsync Full None
lwz Full Full
lwzu Full Full
lwzux Full None
lwzx Full None
lxsdx Full None
lxvd2x Full None
lxvdsx Full None
lxvw4x Full None
mbar Full None
mcrf Full None
mfamr Full None
mfasr Full None
mfbr0 Full None
mfbr1 Full None
mfbr2 Full None
mfbr3 Full None
mfbr4 Full None
mfbr5 Full None
mfbr6 Full None
mfbr7 Full None
mfcfar Full None
mfcr Full None
mfctr Full None
mfdar Full None
mfdbatl Full None
mfdbatu Full None
mfdccr Full None
mfdcr Full None
mfdear Full None
mfdscr Full None
mfdsisr Full None
mfesr Full None
mffs Full None
mfibatl Full None
mfibatu Full None
mficcr Full None
mflr Full Full
mfmsr Full None
mfocrf Full None
mfpid Full None
mfpvr Full None
mfrtcl Full None
mfrtcu Full None
mfspefscr Full None
mfspr Full None
mfsr Full None
mfsrin Full None
mfsrr2 Full None
mfsrr3 Full None
mftb Full None
mftbhi Full None
mftblo Full None
mftbu Full None
mftcr Full None
mfvscr Full None
mfxer Full None
mr Full Full
msync Full None
mtamr Full None
mtbr0 Full None
mtbr1 Full None
mtbr2 Full None
mtbr3 Full None
mtbr4 Full None
mtbr5 Full None
mtbr6 Full None
mtbr7 Full None
mtcfar Full None
mtcr Full None
mtcrf Full None
mtctr Full Full
mtdar Full None
mtdbatl Full None
mtdbatu Full None
mtdccr Full None
mtdcr Full None
mtdear Full None
mtdscr Full None
mtdsisr Full None
mtesr Full None
mtfsb0 Full None
mtfsb1 Full None
mtfsf Full None
mtibatl Full None
mtibatu Full None
mticcr Full None
mtlr Full Full
mtmsr Full None
mtmsrd Full None
mtocrf Full None
mtpid Full None
mtspefscr Full None
mtspr Full None
mtsr Full None
mtsrin Full None
mtsrr2 Full None
mtsrr3 Full None
mttbhi Full None
mttbl Full None
mttblo Full None
mttbu Full None
mttcr Full None
mtvscr Full None
mtxer Full None
mulhd Full None
mulhdu Full None
mulhw Full None
mulhwu Full None
mulld Full None
mulli Full None
mullw Full None
nand Full None
neg Full None
nop Full Full
nor Full None
not Full None
or Full None
orc Full None
ori Full Full
oris Full None
popcntd Full None
popcntw Full None
ptesync Full None
rfci Full None
rfdi Full None
rfi Full None
rfid Full None
rfmci Full None
rldcl Full None
rldcr Full None
rldic Full None
rldicl Full None
rldicr Full None
rldimi Full None
rlwimi Full None
rlwinm Full None
rlwnm Full None
rotld Full None
rotldi Full None
rotlw Full None
rotlwi Full None
sc Full Full
slbia Full None
slbie Full None
slbmfee Full None
slbmte Full None
sld Full None
sldi Full None
slw Full None
slwi Full Full
srad Full None
sradi Full None
sraw Full None
srawi Full None
srd Full None
srw Full None
srwi Full None
stb Full None
stbu Full None
stbux Full None
stbx Full None
std Full None
stdbrx Full None
stdcx Full None
stdu Full None
stdux Full None
stdx Full None
stfd Full None
stfdu Full None
stfdux Full None
stfdx Full None
stfiwx Full None
stfs Full None
stfsu Full None
stfsux Full None
stfsx Full None
sth Full None
sthbrx Full None
sthu Full None
sthux Full None
sthx Full None
stmw Full Full
stswi Full None
stvebx Full None
stvehx Full None
stvewx Full None
stvx Full None
stvxl Full None
stw Full Full
stwbrx Full None
stwcx Full None
stwu Full Full
stwux Full None
stwx Full None
stxsdx Full None
stxvd2x Full None
stxvw4x Full None
sub Full None
subc Full None
subf Full None
subfc Full None
subfe Full None
subfic Full None
subfme Full None
subfze Full None
sync Full None
td Full None
tdeq Full None
tdeqi Full None
tdgt Full None
tdgti Full None
tdi Full None
tdlgt Full None
tdlgti Full None
tdllt Full None
tdllti Full None
tdlt Full None
tdlti Full None
tdne Full None
tdnei Full None
tdu Full None
tdui Full None
tlbia Full None
tlbie Full None
tlbiel Full None
tlbivax Full None
tlbld Full None
tlbli Full None
tlbre Full None
tlbrehi Full None
tlbrelo Full None
tlbsx Full None
tlbsync Full None
tlbwe Full None
tlbwehi Full None
tlbwelo Full None
trap Full None
tw Full None
tweq Full None
tweqi Full None
twgt Full None
twgti Full None
twi Full None
twlgt Full None
twlgti Full None
twllt Full None
twllti Full None
twlt Full None
twlti Full None
twne Full None
twnei Full None
twu Full None
twui Full None
vaddcuw Full None
vaddfp Full None
vaddsbs Full None
vaddshs Full None
vaddsws Full None
vaddubm Full None
vaddubs Full None
vadduhm Full None
vadduhs Full None
vadduwm Full None
vadduws Full None
vand Full None
vandc Full None
vavgsb Full None
vavgsh Full None
vavgsw Full None
vavgub Full None
vavguh Full None
vavguw Full None
vcfsx Full None
vcfux Full None
vcmpbfp Full None
vcmpeqfp Full None
vcmpequb Full None
vcmpequh Full None
vcmpequw Full None
vcmpgefp Full None
vcmpgtfp Full None
vcmpgtsb Full None
vcmpgtsh Full None
vcmpgtsw Full None
vcmpgtub Full None
vcmpgtuh Full None
vcmpgtuw Full None
vctsxs Full None
vctuxs Full None
vexptefp Full None
vlogefp Full None
vmaddfp Full None
vmaxfp Full None
vmaxsb Full None
vmaxsh Full None
vmaxsw Full None
vmaxub Full None
vmaxuh Full None
vmaxuw Full None
vmhaddshs Full None
vmhraddshs Full None
vminfp Full None
vminsb Full None
vminsh Full None
vminsw Full None
vminub Full None
vminuh Full None
vminuw Full None
vmladduhm Full None
vmrghb Full None
vmrghh Full None
vmrghw Full None
vmrglb Full None
vmrglh Full None
vmrglw Full None
vmsummbm Full None
vmsumshm Full None
vmsumshs Full None
vmsumubm Full None
vmsumuhm Full None
vmsumuhs Full None
vmulesb Full None
vmulesh Full None
vmuleub Full None
vmuleuh Full None
vmulosb Full None
vmulosh Full None
vmuloub Full None
vmulouh Full None
vnmsubfp Full None
vnor Full None
vor Full None
vperm Full None
vpkpx Full None
vpkshss Full None
vpkshus Full None
vpkswss Full None
vpkswus Full None
vpkuhum Full None
vpkuhus Full None
vpkuwum Full None
vpkuwus Full None
vrefp Full None
vrfim Full None
vrfin Full None
vrfip Full None
vrfiz Full None
vrlb Full None
vrlh Full None
vrlw Full None
vrsqrtefp Full None
vsel Full None
vsl Full None
vslb Full None
vsldoi Full None
vslh Full None
vslo Full None
vslw Full None
vspltb Full None
vsplth Full None
vspltisb Full None
vspltish Full None
vspltisw Full None
vspltw Full None
vsr Full None
vsrab Full None
vsrah Full None
vsraw Full None
vsrb Full None
vsrh Full None
vsro Full None
vsrw Full None
vsubcuw Full None
vsubfp Full None
vsubsbs Full None
vsubshs Full None
vsubsws Full None
vsububm Full None
vsububs Full None
vsubuhm Full None
vsubuhs Full None
vsubuwm Full None
vsubuws Full None
vsum2sws Full None
vsum4sbs Full None
vsum4shs Full None
vsum4ubs Full None
vsumsws Full None
vupkhpx Full None
vupkhsb Full None
vupkhsh Full None
vupklpx Full None
vupklsb Full None
vupklsh Full None
vxor Full None
wait Full None
waitimpl Full None
waitrsv Full None
wrtee Full None
wrteei Full None
xnop Full None
xor Full None
xori Full None
xoris Full None
xsabsdp Full None
xsadddp Full None
xscmpodp Full None
xscmpudp Full None
xscpsgndp Full None
xscvdpsp Full None
xscvdpsxds Full None
xscvdpsxws Full None
xscvdpuxds Full None
xscvdpuxws Full None
xscvspdp Full None
xscvsxddp Full None
xscvuxddp Full None
xsdivdp Full None
xsmaddadp Full None
xsmaddmdp Full None
xsmaxdp Full None
xsmindp Full None
xsmsubadp Full None
xsmsubmdp Full None
xsmuldp Full None
xsnabsdp Full None
xsnegdp Full None
xsnmaddadp Full None
xsnmaddmdp Full None
xsnmsubadp Full None
xsnmsubmdp Full None
xsrdpi Full None
xsrdpic Full None
xsrdpim Full None
xsrdpip Full None
xsrdpiz Full None
xsredp Full None
xsrsqrtedp Full None
xssqrtdp Full None
xssubdp Full None
xstdivdp Full None
xstsqrtdp Full None
xvabsdp Full None
xvabssp Full None
xvadddp Full None
xvaddsp Full None
xvcmpeqdp Full None
xvcmpeqsp Full None
xvcmpgedp Full None
xvcmpgesp Full None
xvcmpgtdp Full None
xvcmpgtsp Full None
xvcpsgndp Full None
xvcpsgnsp Full None
xvcvdpsp Full None
xvcvdpsxds Full None
xvcvdpsxws Full None
xvcvdpuxds Full None
xvcvdpuxws Full None
xvcvspdp Full None
xvcvspsxds Full None
xvcvspsxws Full None
xvcvspuxds Full None
xvcvspuxws Full None
xvcvsxddp Full None
xvcvsxdsp Full None
xvcvsxwdp Full None
xvcvsxwsp Full None
xvcvuxddp Full None
xvcvuxdsp Full None
xvcvuxwdp Full None
xvcvuxwsp Full None
xvdivdp Full None
xvdivsp Full None
xvmaddadp Full None
xvmaddasp Full None
xvmaddmdp Full None
xvmaddmsp Full None
xvmaxdp Full None
xvmaxsp Full None
xvmindp Full None
xvminsp Full None
xvmovdp Full None
xvmovsp Full None
xvmsubadp Full None
xvmsubasp Full None
xvmsubmdp Full None
xvmsubmsp Full None
xvmuldp Full None
xvmulsp Full None
xvnabsdp Full None
xvnabssp Full None
xvnegdp Full None
xvnegsp Full None
xvnmaddadp Full None
xvnmaddasp Full None
xvnmaddmdp Full None
xvnmaddmsp Full None
xvnmsubadp Full None
xvnmsubasp Full None
xvnmsubmdp Full None
xvnmsubmsp Full None
xvrdpi Full None
xvrdpic Full None
xvrdpim Full None
xvrdpip Full None
xvrdpiz Full None
xvredp Full None
xvresp Full None
xvrspi Full None
xvrspic Full None
xvrspim Full None
xvrspip Full None
xvrspiz Full None
xvrsqrtedp Full None
xvrsqrtesp Full None
xvsqrtdp Full None
xvsqrtsp Full None
xvsubdp Full None
xvsubsp Full None
xvtdivdp Full None
xvtdivsp Full None
xvtsqrtdp Full None
xvtsqrtsp Full None
xxland Full None
xxlandc Full None
xxlnor Full None
xxlor Full None
xxlxor Full None
xxmrghd Full None
xxmrghw Full None
xxmrgld Full None
xxmrglw Full None
xxpermdi Full None
xxsel Full None
xxsldwi Full None
xxspltd Full None
xxspltw Full None
xxswapd Full None
@lwerdna lwerdna self-assigned this Sep 15, 2017
@Leseratte10
Copy link

Leseratte10 commented Aug 20, 2018

As described in #1123, while disassembling a PPC binary for the Broadway (750CL) I found multiple PPC instructions not supported by Binary Ninja, which aren't present in the table above:

  • fcmpo (fc 01 00 40 = fcmpo cr0, f1, f0)
  • lq (e3 e1 00 38 = lq r30, 48(r1))
  • psq_st (f3 e1 00 28 = psq_st f31, 40(r1), 0, 0)
  • xxpermr (f0 25 01 d0 = xxpermr vs1,vs5,vs0)
  • ps_muls0 (10 23 00 18 = ps_muls0 f1,f3,f0)

and probably more which I just haven't seen yet (or are hidden behind these non-supported instructions).

For the future (for other unsupported ASM instructions), would it be possible to make Binary Ninja detect an unsupported instruction, display it as "??" but still continue disassembling the function? PPC asm instructions always have 4 bytes so it should be possible to ignore an unknown instruction and continue anyways ...

@Leseratte10
Copy link

Leseratte10 commented Jan 14, 2019

Sorry for bringing this up again, but is there any time frame when these missing instructions (#1123) can be added to Binary Ninja? I tried implementing them myself with an architecture plugin, but the examples I found are more about creating a new architecture, not adding instructions to an existing one so I was unable to get that to work.

Also, I noticed that for floating-point related instructions like lfs or stfs (and others), Binary Ninja doesn't display the corresponding memory address (like data_80123456), even though it can determine that just fine if the instruction were lwz (load integer) instead of lfs (load float); so one cannot assign variable names to these float variables. I'm not sure though if that is related to PPC lifting completion or if that would better fit into a new bug report.

@Leseratte10
Copy link

Leseratte10 commented Oct 10, 2019

Bringing this up again, still not fixed in 1.2. It's now over a year that I first reported the issue of lots of PPC instructions missing, and I am kinda annoyed that this is still not fixed. Am I the only one who uses Binary Ninja with PPC binaries? This issue must come up for other people as well, with the amount of instructions missing. And I don't even know if these are all the ones missing because Binary Ninja just stops disassembling a function when it encounters an unknown instruction...

Any update on when Binary NInja will support ALL PPC instructions? I don't need them to be fully lifted to the Intermediate Languages (that's whole another story, my binary shows 144107 "unimplemented instructions" in the new tag type view), but Binary Ninja should recognize the byte code and display the ASM code line and continue disassembling the function instead of just stopping ...

@psifertex
Copy link
Member

I'm very sorry for the delay on responding to this--it's totally understandable that you'd be frustrated.

There are definitely other users using Binary Ninja on PowerPC, but because there's a wide variety of different compilers and specific hardware revisions, it's entirely possible that the set of instructions you're missing are not as common across other people's environments. From the instructions you're describing my guess is you're doing Gamecube/Wii reversing while, for example, lots of other users might be analyzing networking equipment which also runs on powerpc and is less likely to use some of the same instructions.

As for just continuing disassembly, we don't want to just treat all four-byte patterns as valid instructions and keep scanning for bytes because that would produce a tremendous amount of garbage functions and not actually improve the results.

The good news is that there's three ways to fix/work around the problem. The first is to simply replace byte patterns that are commonly stopping execution with a NOP (at the least that would let you see how many total instructions are missing). The better fix though is to create an architecture extension that adds support for the specific instructions you're running into. The good news is there are several example architecture extensions:
https://github.com/Vector35/binaryninja-api/blob/dev/python/examples/arch_hook.py
https://github.com/Vector35/binaryninja-api/tree/dev/examples/x86_extension

Performance is much worse with python versus a native plugin, but it might be worth it depending on the size of the binaries.

Finally, you can even see how we're implementing our PPC support (https://github.com/Vector35/ppc-capstone) and submit PRs to that, though it's potentially a lot more involved than the other two.

I wish I could tell you we had an immediate fix planned for all PPC, but we don't have it currently scheduled at this time. I'll bring it up during our next team meeting to see if anyone has some time to put into it.

@lwerdna
Copy link
Contributor Author

lwerdna commented Oct 13, 2019

Hi Leseratte10, thanks for your feedback and sorry that you've been blocked on this issue.

This architecture was written to demonstrate how an existing disassembler could quickly bootstrap a creating an architecture. Obviously a huge drawback is that we adopt whatever shortcomings the disassembler has and Capstone unfortunately only makes available "ppc64" which won't decode those instructions.

We're tempted to make one-off exceptions for the 5 cases you provided (fcmpo, lq, psq_st, xxpermr, ps_muls0) but as soon as we start with psq_st for example, we know psq_stx, psq_stu, psq_stux will be an issue.

Your suggestion to return "???" is also tempting, but we rely on the disassembler failing to decode certain instructions to help Binary Ninja in the phase where it's searching about the binary and discerning between code and data.

The right thing to do is dump Capstone and make a disassembler that lets you choose which PPC variant you're working on, 750 in your case. According to binutils/libopcodes, different variants can have different ideas of which instructions are missing, and in some cases how a fixed instruction word should be decoded:

fcmpo:

           (ppc) FC010040: fcmpo   cr0,f1,f0
         (ppc64) FC010040: fcmpo   cr0,f1,f0
       (ppc_403) FC010040: fcmpo   cr0,f1,f0
     (ppc_403gc) FC010040: fcmpo   cr0,f1,f0
       (ppc_405) FC010040: fcmpo   cr0,f1,f0
       (ppc_505) FC010040: fcmpo   cr0,f1,f0
       (ppc_601) FC010040: fcmpo   cr0,f1,f0
       (ppc_602) FC010040: fcmpo   cr0,f1,f0
       (ppc_603) FC010040: fcmpo   cr0,f1,f0
    (ppc_ec603e) FC010040: fcmpo   cr0,f1,f0
       (ppc_604) FC010040: fcmpo   cr0,f1,f0
       (ppc_620) FC010040: fcmpo   cr0,f1,f0
       (ppc_630) FC010040: fcmpo   cr0,f1,f0
       (ppc_750) FC010040: fcmpo   cr0,f1,f0
       (ppc_860) FC010040: fcmpo   cr0,f1,f0
       (ppc_a35) FC010040: fcmpo   0,f1,f0
    (ppc_rs64ii) FC010040: fcmpo   0,f1,f0
   (ppc_rs64iii) FC010040: fcmpo   0,f1,f0
      (ppc_7400) FC010040: fcmpo   cr0,f1,f0
      (ppc_e500) FC010040:
    (ppc_e500mc) FC010040: fcmpo   cr0,f1,f0
  (ppc_e500mc64) FC010040: fcmpo   cr0,f1,f0
     (ppc_e5500) FC010040: fcmpo   cr0,f1,f0
     (ppc_e6500) FC010040: fcmpo   cr0,f1,f0
     (ppc_titan) FC010040: fcmpo   cr0,f1,f0
       (ppc_vle) FC010040:

lq:

           (ppc) E3E10038: psq_l   f31,56(r1),0,0
         (ppc64) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_403) E3E10038:
     (ppc_403gc) E3E10038:
       (ppc_405) E3E10038:
       (ppc_505) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_601) E3E10038:
       (ppc_602) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_603) E3E10038: psq_l   f31,56(r1),0,0
    (ppc_ec603e) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_604) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_620) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_630) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_750) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_860) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_a35) E3E10038: lfq     f31,56(r1)
    (ppc_rs64ii) E3E10038: lfq     f31,56(r1)
   (ppc_rs64iii) E3E10038: lfq     f31,56(r1)
      (ppc_7400) E3E10038: psq_l   f31,56(r1),0,0
      (ppc_e500) E3E10038:
    (ppc_e500mc) E3E10038:
  (ppc_e500mc64) E3E10038:
     (ppc_e5500) E3E10038:
     (ppc_e6500) E3E10038:
     (ppc_titan) E3E10038:
       (ppc_vle) E3E10038:

psq_st:

           (ppc) F3E10028: psq_st  f31,40(r1),0,0
         (ppc64) F3E10028: psq_st  f31,40(r1),0,0
       (ppc_403) F3E10028:
     (ppc_403gc) F3E10028:
       (ppc_405) F3E10028:
       (ppc_505) F3E10028: psq_st  f31,40(r1),0,0
       (ppc_601) F3E10028:
       (ppc_602) F3E10028: psq_st  f31,40(r1),0,0
       (ppc_603) F3E10028: psq_st  f31,40(r1),0,0
    (ppc_ec603e) F3E10028: psq_st  f31,40(r1),0,0
       (ppc_604) F3E10028: psq_st  f31,40(r1),0,0
       (ppc_620) F3E10028: psq_st  f31,40(r1),0,0
       (ppc_630) F3E10028: psq_st  f31,40(r1),0,0
       (ppc_750) F3E10028: psq_st  f31,40(r1),0,0
       (ppc_860) F3E10028: psq_st  f31,40(r1),0,0
       (ppc_a35) F3E10028: stfq    f31,40(r1)
    (ppc_rs64ii) F3E10028: stfq    f31,40(r1)
   (ppc_rs64iii) F3E10028: stfq    f31,40(r1)
      (ppc_7400) F3E10028: psq_st  f31,40(r1),0,0
      (ppc_e500) F3E10028:
    (ppc_e500mc) F3E10028:
  (ppc_e500mc64) F3E10028:
     (ppc_e5500) F3E10028:
     (ppc_e6500) F3E10028:
     (ppc_titan) F3E10028:
       (ppc_vle) F3E10028:

xxpermr:

           (ppc) F02501D0: xxpermr vs1,vs5,vs0
         (ppc64) F02501D0: xxpermr vs1,vs5,vs0
       (ppc_403) F02501D0:
     (ppc_403gc) F02501D0:
       (ppc_405) F02501D0:
       (ppc_505) F02501D0: xxpermr vs1,vs5,vs0
       (ppc_601) F02501D0:
       (ppc_602) F02501D0: xxpermr vs1,vs5,vs0
       (ppc_603) F02501D0: xxpermr vs1,vs5,vs0
    (ppc_ec603e) F02501D0: xxpermr vs1,vs5,vs0
       (ppc_604) F02501D0: xxpermr vs1,vs5,vs0
       (ppc_620) F02501D0: xxpermr vs1,vs5,vs0
       (ppc_630) F02501D0: xxpermr vs1,vs5,vs0
       (ppc_750) F02501D0: xxpermr vs1,vs5,vs0
       (ppc_860) F02501D0: xxpermr vs1,vs5,vs0
       (ppc_a35) F02501D0: stfq    f1,464(r5)
    (ppc_rs64ii) F02501D0: stfq    f1,464(r5)
   (ppc_rs64iii) F02501D0: stfq    f1,464(r5)
      (ppc_7400) F02501D0: xxpermr vs1,vs5,vs0
      (ppc_e500) F02501D0:
    (ppc_e500mc) F02501D0:
  (ppc_e500mc64) F02501D0:
     (ppc_e5500) F02501D0:
     (ppc_e6500) F02501D0:
     (ppc_titan) F02501D0:
       (ppc_vle) F02501D0:

ps_muls0:

           (ppc) 10230018: ps_muls0 f1,f3,f0
         (ppc64) 10230018: ps_muls0 f1,f3,f0
       (ppc_403) 10230018:
     (ppc_403gc) 10230018:
       (ppc_405) 10230018: machhwu r1,r3,r0
       (ppc_505) 10230018: ps_muls0 f1,f3,f0
       (ppc_601) 10230018:
       (ppc_602) 10230018: ps_muls0 f1,f3,f0
       (ppc_603) 10230018: ps_muls0 f1,f3,f0
    (ppc_ec603e) 10230018: ps_muls0 f1,f3,f0
       (ppc_604) 10230018: ps_muls0 f1,f3,f0
       (ppc_620) 10230018: ps_muls0 f1,f3,f0
       (ppc_630) 10230018: ps_muls0 f1,f3,f0
       (ppc_750) 10230018: ps_muls0 f1,f3,f0
       (ppc_860) 10230018: ps_muls0 f1,f3,f0
       (ppc_a35) 10230018:
    (ppc_rs64ii) 10230018:
   (ppc_rs64iii) 10230018:
      (ppc_7400) 10230018: ps_muls0 f1,f3,f0
      (ppc_e500) 10230018:
    (ppc_e500mc) 10230018:
  (ppc_e500mc64) 10230018:
     (ppc_e5500) 10230018:
     (ppc_e6500) 10230018:
     (ppc_titan) 10230018: machhwu r1,r3,r0
       (ppc_vle) 10230018:

We're making a disassembler now that will take as input the variant you're working on, and then you can select that variant in the architecture list.

I'll try to get those 5 exceptions you listed on the dev channel just so you're not stuck until our better version comes out. But lq I can't reproduce, can you verify the E3E10038 encoding?

@Leseratte10
Copy link

Leseratte10 commented Oct 13, 2019

Hm, apparently the disassembler I used last year to get from e3e10038 to the opcode was wrong, looks like this is indeed psq_l f31,56(r1),0,0 like you found out.

I am looking forward to the release of a proper disassembler that allows me to directly select the 750(CL) so it supports all of its instructions. I don't know if there'd be more exceptions other than the five I already mentioned, as there might be some more unsupported instructions that currently hide behind the already known unsupported ones.

So did I understand that correctly, when you have that new disassembler finished that allows me to directly select the PPC variant I'm using that that will support all the instructions that processor supports?

@lwerdna
Copy link
Contributor Author

lwerdna commented Oct 13, 2019

So did I understand that correctly, when you have that new disassembler finished that allows me to directly select the PPC variant I'm using that that will support all the instructions that processor supports?

Yes. Well that's the goal. So far attempts to analyze the instruction space and automatically find points of agreement and disagreement among the variants have been promising. It's a neat problem, find me on slack if you have ideas to share.

@lwerdna
Copy link
Contributor Author

lwerdna commented Oct 27, 2019

@Leseratte10, if your Binja is set up to update from the dev channel (Binary Ninja -> Preferences -> Update Channel -> Internal development builds), would you mind giving 1.2.1937 or newer a try?

@Leseratte10
Copy link

Downloaded 1.2.1937, opened my BNDB, clicked "reanalyze current function", but instructions like fe310058 still only result in "??". Do I need to enable that new feature somewhere and tell Binary Ninja I'm using a 750CL?

@lwerdna
Copy link
Contributor Author

lwerdna commented Oct 27, 2019

You didn't miss any steps, the instructions you reported earlier should work. But I'm having trouble decoding FE310058 in particular. None of the libopcodes variants will decode it, and in the 750CL doc, it says all the new instructions specific to that core have opcode 4 (0b000100) while this has opcode 63 (0b111111) on the most significant side.

750cl_specific

@Leseratte10
Copy link

Leseratte10 commented Oct 27, 2019

Sorry for the confusion, I made a typo. I meant f3e10058.

f02501d0 (xxpermr) and fc010040 (fcmpo) and 10230018 (ps_muls0) are now displayed correctly.
f3e10058/f04501d8/f03e8028 (psq_st) or e3e10038 (lq) aren't recognized.

@lwerdna
Copy link
Contributor Author

lwerdna commented Oct 27, 2019

No problem! Would you mind sharing the reference disassembler you're using? I was sad to find recently libopcodes output sometimes disagrees the spec.

f3e10058/f04501d8/f03e8028 (psq_st)

f04501d8 and f03e8028 disassemble to psq_st for me but f3e10058 is xscmpgtdp according to libopcodes:

           (ppc) F3E10058: xscmpgtdp vs31,vs1,vs0
         (ppc64) F3E10058: xscmpgtdp vs31,vs1,vs0
       (ppc_403) F3E10058:
     (ppc_403gc) F3E10058:
       (ppc_405) F3E10058:
       (ppc_505) F3E10058: xscmpgtdp vs31,vs1,vs0
       (ppc_601) F3E10058:
       (ppc_602) F3E10058: xscmpgtdp vs31,vs1,vs0
       (ppc_603) F3E10058: xscmpgtdp vs31,vs1,vs0
    (ppc_ec603e) F3E10058: xscmpgtdp vs31,vs1,vs0
       (ppc_604) F3E10058: xscmpgtdp vs31,vs1,vs0
       (ppc_620) F3E10058: xscmpgtdp vs31,vs1,vs0
       (ppc_630) F3E10058: xscmpgtdp vs31,vs1,vs0
       (ppc_750) F3E10058: xscmpgtdp vs31,vs1,vs0
       (ppc_860) F3E10058: xscmpgtdp vs31,vs1,vs0
       (ppc_a35) F3E10058: stfq    f31,88(r1)
    (ppc_rs64ii) F3E10058: stfq    f31,88(r1)
   (ppc_rs64iii) F3E10058: stfq    f31,88(r1)
      (ppc_7400) F3E10058: xscmpgtdp vs31,vs1,vs0
      (ppc_e500) F3E10058:
    (ppc_e500mc) F3E10058:
  (ppc_e500mc64) F3E10058:
     (ppc_e5500) F3E10058:
     (ppc_e6500) F3E10058:
     (ppc_titan) F3E10058:
       (ppc_vle) F3E10058:

e3e10038 (lq)

e3e10038 is psq_l according to libopcodes:

           (ppc) E3E10038: psq_l   f31,56(r1),0,0
         (ppc64) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_403) E3E10038:
     (ppc_403gc) E3E10038:
       (ppc_405) E3E10038:
       (ppc_505) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_601) E3E10038:
       (ppc_602) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_603) E3E10038: psq_l   f31,56(r1),0,0
    (ppc_ec603e) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_604) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_620) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_630) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_750) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_860) E3E10038: psq_l   f31,56(r1),0,0
       (ppc_a35) E3E10038: lfq     f31,56(r1)
    (ppc_rs64ii) E3E10038: lfq     f31,56(r1)
   (ppc_rs64iii) E3E10038: lfq     f31,56(r1)
      (ppc_7400) E3E10038: psq_l   f31,56(r1),0,0
      (ppc_e500) E3E10038:
    (ppc_e500mc) E3E10038:
  (ppc_e500mc64) E3E10038:
     (ppc_e5500) E3E10038:
     (ppc_e6500) E3E10038:
     (ppc_titan) E3E10038:
       (ppc_vle) E3E10038:

@Leseratte10
Copy link

Leseratte10 commented Oct 27, 2019

I used powerpc-eabi-objdump v2.32 from devkitPPC, set to the CPU type "powerpc:750". That returns "psq_st f31,88(r1),0,0" for the op code f3 e1 00 58, and "lq r30,48(r1)" for op code e3 e1 00 38.

https://onlinedisassembler.com/odaweb/ returns the same instructions when set to "powerpc:750" and big-endian.

Maybe that is just an alias / simplification? Like "nop" is an alias for "or r0, r0, r0"?

@lwerdna
Copy link
Contributor Author

lwerdna commented Oct 27, 2019

I would have thought powerpc-eabi-objdump linked against libbfd and libopcodes.

The lq instruction isn't in my 750CL pdf, but it is in the PowerISA v2.0.7 pdf and by hand decoding you're right: E3E10038 should be lq.

But no psq_* instructions appear in the PowerISA pdf. The 750CL doc has psq_stx and psq_stux (and they should decode in Binja) but it does not have psq_st and I'm pretty confident it's not a synonym or alias because the ones with x at the end have opcode 4 while f3e10058 has opcode 60.

But then a search turns up psq_st and psq_stu in the Gekko manual:

gecko_psq

I'll stick those encodings into what Binja calls PPC, but doing this right will take some thought. Before seeing psq_st missing from the PowerISA spec, I'd mistakenly believed it contained the union of all instructions from each variant, sort of a super lookup table. And all variants would just select or subset some portion from this super lookup table.

@lwerdna
Copy link
Contributor Author

lwerdna commented Oct 27, 2019

Hmmm, maybe libopcodes had good reason not to decode e3e10038 to lq:

bad_lq

Note the bit:

If RTp is odd or RTp=RA, the instruction form is invalid."

Instruction word e3e10038 splits to opcode==111000, RTp==11111, RA==00001, DQ==000000000011 so RTp is odd. If we change it to even, RTp==11110 then the word becomes e3c10038 and:

           (ppc) E3C10038: lq      r30,48(r1)
         (ppc64) E3C10038: lq      r30,48(r1)
       (ppc_403) E3C10038:
     (ppc_403gc) E3C10038:
       (ppc_405) E3C10038:
       (ppc_505) E3C10038: lq      r30,48(r1)
       (ppc_601) E3C10038:
       (ppc_602) E3C10038: lq      r30,48(r1)
       (ppc_603) E3C10038: lq      r30,48(r1)
    (ppc_ec603e) E3C10038: lq      r30,48(r1)
       (ppc_604) E3C10038: lq      r30,48(r1)
       (ppc_620) E3C10038: lq      r30,48(r1)
       (ppc_630) E3C10038: lq      r30,48(r1)
       (ppc_750) E3C10038: lq      r30,48(r1)
       (ppc_860) E3C10038: lq      r30,48(r1)
       (ppc_a35) E3C10038: lfq     f30,56(r1)
    (ppc_rs64ii) E3C10038: lfq     f30,56(r1)
   (ppc_rs64iii) E3C10038: lfq     f30,56(r1)
      (ppc_7400) E3C10038: lq      r30,48(r1)
      (ppc_e500) E3C10038:
    (ppc_e500mc) E3C10038:
  (ppc_e500mc64) E3C10038:
     (ppc_e5500) E3C10038: lq      r30,48(r1)
     (ppc_e6500) E3C10038: lq      r30,48(r1)
     (ppc_titan) E3C10038:
       (ppc_vle) E3C10038:

Since there's no reason an invalid instruction would be randomly in the stream of valid instructions, or no reason for the compiler to have emitted this, I'm forced to think this parity rule on RTp is only a PowerISA rule and doesn't exist on the Gecko.

Current collection of PPC complexities:

  • encodings/disassembly that exist on some variants but not others
  • same encodings, different disassembly depending on the variant
  • same encoding/disassembly, but different constraints depending on the variants

@NWPlayer123
Copy link

I think @Leseratte10 is getting confused, and also I'd like to jump in with my two cents
Sorry this is so long, I was searching around for answers, found this, and went on a tangent

  • "E3E10038" is "psq_l f31, 0x38(r1), 0, 0", which you can see if you manually edit a binary in IDA (or manually assemble? I've never used that though)
  • AFAICT, IDA disassembles opcodes correctly when set to Paired Singles, devkitPro isn't a very good reference (screenshot from 7.2 but it's supported Paired Singles for a while)
    image
my two cents, lots of screenshots
  • looks like it's missing some reloc types that CodeWarrior uses in its elf files
    image

  • Binja 2.0 performs decent on my test function, InsertAlarm which is part of the SDK, uses 64-bit math in a 32-bit implementation and thus has to use xor and carry stuff, but has a long way to go
    image

  • It's missing a bunch of "assumptions" that I've come to expect, from my quick testing

    • it doesn't know that r14-r31 are "temporary" variables and not passed
    • it doesn't look like there's a way to set r2/r13 for Small Data Area static addresses (although it did pick up the addresses after I played with it a bit.....somehow)
    • changing a function type in the disassembly doesn't re-analyze the rest of the function or force the analyzer to change the variables before/after to match the new data (see pic 2, after I change ReadProjData to return a bool [which it doesn't actually use and correctly detects, see pic 3 with a lot of cleanup], it doesn't "force" it to change ctr/r5/6/7)
      image
      image
      image
  • I don't know if this is because of the missing assumptions above/poor decompilation, but it creates a loooot of variables/doesn't consolidate them
    image

  • I see some people have made C++ plugins but it doesn't feel that usable (from my very quick testing), there's no way to "set" the this variable like Ghidra can without manually defining a class object structure or just doing void* this
    image

  • wrt the UI, the tags are a nice feature but it seems like even if there was C++ support, there's no way to "group" functions like Ghidra's Symbol Tree, e.g. these 15 functions are from this file, these 23 are from this other file

  • being locked into C structs to define types seems very clunky, and it doesn't look like there's a way to group types in the UI if you start to have A Lot Of Them

  • on the bright side, you're being very open wrt APIs and custom scripting and plugins which I have to appreciate, seems easy enough to fix smaller issues e.g. add support for the GameCube's "dol" format or add a symbol demangler for CodeWarrior

  • the layout of the main body is decent, did a good job embedding data, tags, and decomp/disassembly

@Leseratte10
Copy link

To be honest, I don't really care what these instructions disassemble into, I'd just like them all to disassemble into something so Binary NInja can finally disassemble all the functions and doesn't stop at the first unknown instruction ...

@plafosse plafosse transferred this issue from Vector35/binaryninja-api Feb 10, 2021
@riptl
Copy link

riptl commented Aug 1, 2021

Are there any plans to add the missing PowerPC instructions, specifically floating-point support? I've bought Binary Ninja specifically for PowerPC, but can't really use it with any code heavy on floats. Am I just using it wrong or have the wrong settings?
grafik

Looking at the FAQ, I was assuming that BN supports lifting for the PowerPC instruction set.

grafik

@plafosse plafosse transferred this issue from Vector35/arch-ppc Mar 1, 2023
@fuzyll fuzyll added Component: Architecture Issue needs changes to an architecture plugin Arch: PowerPC Issues with the PowerPC architecture plugin labels Mar 6, 2023
@plafosse plafosse added the Impact: Medium Issue is impactful with a bad, or no, workaround label Mar 22, 2023
@xusheng6 xusheng6 added the Type: Enhancement Issue is a small enhancement to existing functionality label Jul 3, 2023
@v1X3Q0
Copy link

v1X3Q0 commented Jan 28, 2024

I'm very interested in this thread! Was there ever any resolution, any instructions added or any way to disassemble instructions with opcodes like opcode 60?

@psifertex
Copy link
Member

Since we originally filed this issue we've open-sourced our architectures so it's possible to extend out the architecture for any given situation but we don't have specific architectures or instructions scheduled for a refresh at this time.

https://github.com/Vector35/arch-ppc

You'll notice however that we are still maintaining them and adding instructions that can serve as a model for any changes you want made:

Vector35/arch-ppc@e9e8f72

If you're interested in using your own modified architecture module, simply make any modifications, build your local copy as described in the readme, and then disable the built-in arch in Settings / Core Plugins / architectures:

Screenshot 2024-02-02 at 12 38 27

@galenbwill
Copy link
Contributor

The open source PPC architecture plugin -- like all architecture plugins -- has moved:

https://github.com/Vector35/binaryninja-api/tree/dev/arch/powerpc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Arch: PowerPC Issues with the PowerPC architecture plugin Component: Architecture Issue needs changes to an architecture plugin Impact: Medium Issue is impactful with a bad, or no, workaround Type: Enhancement Issue is a small enhancement to existing functionality
Projects
None yet
Development

No branches or pull requests

10 participants