diff --git a/src/arch/sparc.c b/src/arch/sparc.c index d550e8f..c81dc85 100644 --- a/src/arch/sparc.c +++ b/src/arch/sparc.c @@ -55,5 +55,5 @@ ArchPlugin arch_plugin = _sparc_registers, _sparc_instructions, _sparc_write, - NULL + _sparc_decode }; diff --git a/src/arch/sparc.h b/src/arch/sparc.h index e0d4910..fac14bf 100644 --- a/src/arch/sparc.h +++ b/src/arch/sparc.h @@ -22,12 +22,45 @@ /* private */ /* prototypes */ /* plug-in */ +static int _sparc_decode(ArchPlugin * plugin, ArchInstructionCall * call); static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction, ArchInstructionCall * call); /* functions */ /* plug-in */ +/* sparc_decode */ +static int _sparc_decode(ArchPlugin * plugin, ArchInstructionCall * call) +{ + ArchPluginHelper * helper = plugin->helper; + uint32_t u32; + uint32_t opcode; + ArchInstruction * ai; + + if(helper->read(helper->arch, &u32, sizeof(u32)) != sizeof(u32)) + return -1; + u32 = _htob32(u32); + if((u32 & 0xc0000000) == 0xc0000000) /* load store */ + opcode = u32 & (0xc0000000 | (0xf << 19) | (0x1 << 13)); + else if((u32 & 0xc1c00000) == 0x01000000) /* sethi */ + opcode = u32 & (0x7 << 22); + else if((u32 & 0xc0000000) == 0x80000000) /* integer arithmetic */ + opcode = u32 & (0x80000000 | (0x1f << 19) | (0x1 << 13)); + else if((u32 & 0xc1c00000) == 0x00800000) /* branch */ +#if 0 /* FIXME figure what's wrong */ + opcode = u32 & (0x00800000 | (0xf << 25) | (0x3 << 2)); +#else + opcode = u32 & (0x00800000 | (0xf << 25)); +#endif + else + return -1; + if((ai = helper->get_instruction_by_opcode(helper->arch, 32, opcode)) + == NULL) + return -1; + return 0; +} + + /* sparc_write */ static int _write_branch(ArchInstruction * instruction, ArchInstructionCall * call, uint32_t * opcode); diff --git a/src/arch/sparc.ins b/src/arch/sparc.ins index 8c570aa..74ae5b7 100644 --- a/src/arch/sparc.ins +++ b/src/arch/sparc.ins @@ -38,7 +38,7 @@ #define bgeu 0xd #define bcc bgeu /* flags */ -#define OPCBF (4 << AOD_SIZE) +#define OPCBF (32 << AOD_SIZE) /* helpers */ #define OPCB(opcode) (opcode << 25 | 0x2 << 22) #define OPCB_U22 AO_IMMEDIATE(0, 21, 0) @@ -70,8 +70,8 @@ #define udivcc (0x10 | udiv) #define sdivcc (0x10 | sdiv) /* flags */ -#define OPIA1F (4 << AOD_SIZE) -#define OPIA2F (4 << AOD_SIZE) +#define OPIA1F (32 << AOD_SIZE) +#define OPIA2F (32 << AOD_SIZE) /* registers */ #define OPIA_RS1 AO_REGISTER(0, 32, 0) #define OPIA_RS2 AO_REGISTER(0, 32, 0) @@ -94,8 +94,8 @@ #define ldsb 0x9 #define ldsh 0xa /* flags */ -#define OPLS1F (4 << AOD_SIZE) -#define OPLS2F (4 << AOD_SIZE) +#define OPLS1F (32 << AOD_SIZE) +#define OPLS2F (32 << AOD_SIZE) /* registers */ #define OPLS_RS1 AO_DREGISTER(0, 12, 32, 0) #define OPLS_RS1D AO_DREGISTER(0, 0, 32, 0) @@ -108,7 +108,7 @@ /* opcodes */ #define sethi 0x4 /* flags */ -#define OPSHF (4 << AOD_SIZE) +#define OPSHF (32 << AOD_SIZE) /* helpers */ #define OPSH(opcode) (opcode << 22) #define OPSH_U21 AO_IMMEDIATE(0, 32, 0) diff --git a/src/arch/sparc64.c b/src/arch/sparc64.c index 599d489..c775af6 100644 --- a/src/arch/sparc64.c +++ b/src/arch/sparc64.c @@ -55,5 +55,5 @@ ArchPlugin arch_plugin = _sparc64_registers, _sparc64_instructions, _sparc_write, - NULL + _sparc_decode };