Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions arch/powerpc/arch_ppc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ class PowerpcArchitecture: public Architecture
{
private:
BNEndianness endian;
size_t addressSize;

/* this can maybe be moved to the API later */
BNRegisterInfo RegisterInfo(uint32_t fullWidthReg, size_t offset, size_t size, bool zeroExtend = false)
Expand All @@ -296,9 +297,10 @@ class PowerpcArchitecture: public Architecture
public:

/* initialization list */
PowerpcArchitecture(const char* name, BNEndianness endian_): Architecture(name)
PowerpcArchitecture(const char* name, BNEndianness endian_, size_t addressSize_=4): Architecture(name)
{
endian = endian_;
addressSize = addressSize_;
}

/*************************************************************************/
Expand All @@ -312,7 +314,7 @@ class PowerpcArchitecture: public Architecture
virtual size_t GetAddressSize() const override
{
//MYLOG("%s()\n", __func__);
return 4;
return addressSize;
}

virtual size_t GetDefaultIntegerSize() const override
Expand Down Expand Up @@ -360,7 +362,7 @@ class PowerpcArchitecture: public Architecture
}

/* decompose the instruction to get branch info */
if(powerpc_decompose(data, 4, (uint32_t)addr, endian == LittleEndian, &res)) {
if(powerpc_decompose(data, 4, (uint32_t)addr, endian == LittleEndian, &res, GetAddressSize() == 8)) {
MYLOG("ERROR: powerpc_decompose()\n");
return false;
}
Expand Down Expand Up @@ -622,7 +624,7 @@ class PowerpcArchitecture: public Architecture
if (DoesQualifyForLocalDisassembly(data))
return PerformLocalDisassembly(data, addr, len, result);

if(powerpc_decompose(data, 4, (uint32_t)addr, endian == LittleEndian, &res)) {
if(powerpc_decompose(data, 4, (uint32_t)addr, endian == LittleEndian, &res, GetAddressSize() == 8)) {
MYLOG("ERROR: powerpc_decompose()\n");
goto cleanup;
}
Expand Down Expand Up @@ -748,7 +750,7 @@ class PowerpcArchitecture: public Architecture
goto cleanup;
}

if(powerpc_decompose(data, 4, (uint32_t)addr, endian == LittleEndian, &res)) {
if(powerpc_decompose(data, 4, (uint32_t)addr, endian == LittleEndian, &res, GetAddressSize() == 8)) {
MYLOG("ERROR: powerpc_decompose()\n");
il.AddInstruction(il.Undefined());
goto cleanup;
Expand Down Expand Up @@ -2471,13 +2473,13 @@ extern "C"
Architecture* ppc = new PowerpcArchitecture("ppc", BigEndian);
Architecture::Register(ppc);

Architecture* ppc64 = new PowerpcArchitecture("ppc64", BigEndian);
Architecture* ppc64 = new PowerpcArchitecture("ppc64", BigEndian, 8);
Architecture::Register(ppc64);

Architecture* ppc_le = new PowerpcArchitecture("ppc_le", LittleEndian);
Architecture::Register(ppc_le);

Architecture* ppc64_le = new PowerpcArchitecture("ppc64_le", LittleEndian);
Architecture* ppc64_le = new PowerpcArchitecture("ppc64_le", LittleEndian, 8);
Architecture::Register(ppc64_le);

/* calling conventions */
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ powerpc_release(void)

extern "C" int
powerpc_decompose(const uint8_t *data, int size, uint32_t addr, bool lil_end,
struct decomp_result *res)
struct decomp_result *res, bool is_64bit)
{
int rc = -1;
res->status = STATUS_ERROR_UNSPEC;
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/disassembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ struct decomp_result
extern "C" int powerpc_init(void);
extern "C" void powerpc_release(void);
extern "C" int powerpc_decompose(const uint8_t *data, int size, uint32_t addr,
bool lil_end, struct decomp_result *result);
bool lil_end, struct decomp_result *result, bool is_64bit);
extern "C" int powerpc_disassemble(struct decomp_result *, char *buf, size_t len);

extern "C" const char *powerpc_reg_to_str(uint32_t rid);
Expand Down
134 changes: 121 additions & 13 deletions arch/powerpc/il.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,17 @@ bool GetLowLevelILForPPCInstruction(Architecture *arch, LowLevelILFunction &il,
il.AddInstruction(ei0);
break;

case PPC_INS_EXTSW:
REQUIRE2OPS
ei0 = il.Register(8, oper1->reg);
ei0 = il.LowPart(4, ei0);
ei0 = il.SignExtend(8, ei0);
ei0 = il.SetRegister(8, oper0->reg, ei0,
ppc->update_cr0 ? IL_FLAGWRITE_CR0_S : 0
);
il.AddInstruction(ei0);
break;

case PPC_INS_ISEL:
REQUIRE4OPS
{
Expand Down Expand Up @@ -1030,6 +1041,44 @@ bool GetLowLevelILForPPCInstruction(Architecture *arch, LowLevelILFunction &il,

break;

/*
load doubleword [and update]
*/
case PPC_INS_LD:
case PPC_INS_LDU:
REQUIRE2OPS
ei0 = operToIL(il, oper1, OTI_GPR0_ZERO); // d(rA) or 0
ei0 = il.Load(8, ei0); // [d(rA)]
ei0 = il.SetRegister(8, oper0->reg, ei0); // rD = [d(rA)]
il.AddInstruction(ei0);

// if update, rA is set to effective address (d(rA))
if(insn->id == PPC_INS_LWZU) {
ei0 = il.SetRegister(8, oper1->mem.base, operToIL(il, oper1));
il.AddInstruction(ei0);
}

break;

/*
load doubleword [and update]
*/
case PPC_INS_LDX:
case PPC_INS_LDUX:
REQUIRE3OPS
ei0 = operToIL(il, oper1, OTI_GPR0_ZERO); // d(rA) or 0
ei0 = il.Load(8, il.Add(8, ei0, operToIL(il, oper2))); // [d(rA) + d(rB)]
ei0 = il.SetRegister(8, oper0->reg, ei0); // rD = [d(rA)]
il.AddInstruction(ei0);

// if update, rA is set to effective address (d(rA))
if(insn->id == PPC_INS_LWZUX && oper1->reg != oper0->reg && oper1->reg != PPC_REG_R0) {
ei0 = il.SetRegister(8, oper1->reg, operToIL(il, oper1));
il.AddInstruction(ei0);
}

break;

case PPC_INS_LHBRX:
REQUIRE3OPS
ByteReversedLoad(il, ppc, 2);
Expand Down Expand Up @@ -1331,6 +1380,44 @@ bool GetLowLevelILForPPCInstruction(Architecture *arch, LowLevelILFunction &il,

break;

/* store double word [with update] */
case PPC_INS_STD:
case PPC_INS_STDU: /* store(size, addr, val) */
REQUIRE2OPS
ei0 = il.Store(8,
operToIL(il, oper1, OTI_GPR0_ZERO),
operToIL(il, oper0)
);
il.AddInstruction(ei0);

// if update, then rA gets updated address
if(insn->id == PPC_INS_STWU) {
ei0 = il.SetRegister(8, oper1->mem.base, operToIL(il, oper1));
il.AddInstruction(ei0);
}

break;

/* store word indexed [with update] */
case PPC_INS_STDX:
case PPC_INS_STDUX: /* store(size, addr, val) */
REQUIRE3OPS
ei0 = il.Store(8,
il.Add(8, operToIL(il, oper1, OTI_GPR0_ZERO), operToIL(il, oper2)),
operToIL(il, oper0)
);
il.AddInstruction(ei0);

// if update, then rA gets updated address
if(insn->id == PPC_INS_STDUX) {
ei0 = il.SetRegister(8, oper1->reg,
il.Add(8, operToIL(il, oper1), operToIL(il, oper2))
);
il.AddInstruction(ei0);
}

break;

case PPC_INS_RLWIMI:
REQUIRE5OPS
{
Expand Down Expand Up @@ -1484,6 +1571,21 @@ bool GetLowLevelILForPPCInstruction(Architecture *arch, LowLevelILFunction &il,
));
break;

case PPC_INS_SLD:
case PPC_INS_SRD:
REQUIRE3OPS
ei0 = il.Register(8, oper1->reg);
// permit bit 25 to survive to enable clearing the whole register
ei1 = il.And(8, il.Register(8, oper2->reg), il.Const(8, 0x7f));
if (insn->id == PPC_INS_SLD)
ei0 = il.ShiftLeft(8, ei0, ei1);
else
ei0 = il.LogicalShiftRight(8, ei0, ei1);
il.AddInstruction(il.SetRegister(8, oper0->reg, ei0,
ppc->update_cr0 ? IL_FLAGWRITE_CR0_S : 0
));
break;

case PPC_INS_SRAW:
REQUIRE3OPS
ei0 = il.Register(4, oper1->reg);
Expand All @@ -1503,6 +1605,25 @@ bool GetLowLevelILForPPCInstruction(Architecture *arch, LowLevelILFunction &il,
));
break;

case PPC_INS_SRAD:
REQUIRE3OPS
ei0 = il.Register(8, oper1->reg);
ei1 = il.And(8, il.Register(8, oper2->reg), il.Const(8, 0x3f));
ei0 = il.ArithShiftRight(8, ei0, ei1, IL_FLAGWRITE_XER_CA);
il.AddInstruction(il.SetRegister(8, oper0->reg, ei0,
ppc->update_cr0 ? IL_FLAGWRITE_CR0_S : 0
));
break;

case PPC_INS_SRADI:
REQUIRE3OPS
ei0 = il.Register(8, oper1->reg);
ei0 = il.ArithShiftRight(8, ei0, il.Const(8, oper2->imm), IL_FLAGWRITE_XER_CA);
il.AddInstruction(il.SetRegister(8, oper0->reg, ei0,
ppc->update_cr0 ? IL_FLAGWRITE_CR0_S : 0
));
break;

case PPC_INS_MULLW:
REQUIRE3OPS
ei0 = il.Register(4, oper1->reg);
Expand Down Expand Up @@ -1768,7 +1889,6 @@ bool GetLowLevelILForPPCInstruction(Architecture *arch, LowLevelILFunction &il,
case PPC_INS_EVSUBFW:
case PPC_INS_EVSUBIFW:
case PPC_INS_EVXOR:
case PPC_INS_EXTSW:
case PPC_INS_FABS:
case PPC_INS_FADD:
case PPC_INS_FADDS:
Expand Down Expand Up @@ -1815,12 +1935,8 @@ bool GetLowLevelILForPPCInstruction(Architecture *arch, LowLevelILFunction &il,
case PPC_INS_ICBI:
case PPC_INS_ICCCI:
case PPC_INS_ISYNC:
case PPC_INS_LD:
case PPC_INS_LDARX:
case PPC_INS_LDBRX:
case PPC_INS_LDU:
case PPC_INS_LDUX:
case PPC_INS_LDX:
case PPC_INS_LFD:
case PPC_INS_LFDU:
case PPC_INS_LFDUX:
Expand Down Expand Up @@ -1889,16 +2005,8 @@ bool GetLowLevelILForPPCInstruction(Architecture *arch, LowLevelILFunction &il,
case PPC_INS_SLBIE:
case PPC_INS_SLBMFEE:
case PPC_INS_SLBMTE:
case PPC_INS_SLD:
case PPC_INS_SRAD:
case PPC_INS_SRADI:
case PPC_INS_SRD:
case PPC_INS_STD:
case PPC_INS_STDBRX:
case PPC_INS_STDCX:
case PPC_INS_STDU:
case PPC_INS_STDUX:
case PPC_INS_STDX:
case PPC_INS_STFD:
case PPC_INS_STFDU:
case PPC_INS_STFDUX:
Expand Down