Skip to content

Commit f2950ea

Browse files
committed
moved around the external routines, and added them to the il
1 parent e6754f7 commit f2950ea

File tree

6 files changed

+162
-154
lines changed

6 files changed

+162
-154
lines changed

arch/powerpc/CMakeLists.txt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,7 @@ if (DEFINED FORCE_TEST)
5757
add_executable(test_disasm test_disasm.cpp disassembler.cpp)
5858
add_executable(test_asm test_asm.cpp assembler.cpp)
5959

60-
set_target_properties(test_disasm PROPERTIES
61-
CXX_STANDARD 17
62-
CXX_VISIBILITY_PRESET hidden
63-
CXX_STANDARD_REQUIRED ON
64-
VISIBILITY_INLINES_HIDDEN ON
65-
POSITION_INDEPENDENT_CODE ON)
66-
67-
set_target_properties(test_asm PROPERTIES
60+
set_target_properties(test_disasm test_asm PROPERTIES
6861
CXX_STANDARD 17
6962
CXX_VISIBILITY_PRESET hidden
7063
CXX_STANDARD_REQUIRED ON

arch/powerpc/arch_ppc.cpp

Lines changed: 39 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ class PowerpcArchitecture: public Architecture
358358
return false;
359359
}
360360

361-
if (DoesQualifyForLocalDisassembly(data)) {
361+
if (DoesQualifyForLocalDisassembly(data, endian == BigEndian)) {
362362
result.length = 4;
363363
return true;
364364
}
@@ -457,149 +457,56 @@ class PowerpcArchitecture: public Architecture
457457
return true;
458458
}
459459

460-
bool DoesQualifyForLocalDisassembly(const uint8_t *data)
461-
{
462-
uint32_t insword = *(uint32_t *)data;
463-
if(endian == BigEndian)
464-
insword = bswap32(insword);
465-
466-
// 111111xxx00xxxxxxxxxx00001000000 <- fcmpo
467-
uint32_t tmp = insword & 0xFC6007FF;
468-
if (tmp==0xFC000040)
469-
return true;
470-
// 111100xxxxxxxxxxxxxxx00111010xxx <- xxpermr
471-
if((insword & 0xFC0007F8) == 0xF00001D0)
472-
return true;
473-
// 000100xxxxxxxxxxxxxxxxxxx000110x <- psq_lx
474-
// 000100xxxxxxxxxxxxxxxxxxx000111x <- psq_stx
475-
// 000100xxxxxxxxxxxxxxxxxxx100110x <- psq_lux
476-
// 000100xxxxxxxxxxxxxxxxxxx100111x <- psq_stux
477-
tmp = insword & 0xFC00007E;
478-
if (tmp==0x1000000C || tmp==0x1000000E || tmp==0x1000004C || tmp==0x1000004E)
479-
return true;
480-
// 000100xxxxxxxxxx00000xxxxx011000 <- ps_muls0
481-
// 000100xxxxxxxxxx00000xxxxx011001 <- ps_muls0.
482-
// 000100xxxxxxxxxx00000xxxxx011010 <- ps_muls1
483-
// 000100xxxxxxxxxx00000xxxxx011011 <- ps_muls1.
484-
tmp = insword & 0xFC00F83F;
485-
if (tmp==0x10000018 || tmp==0x10000019 || tmp==0x1000001A || tmp==0x1000001B)
486-
return true;
487-
488-
return false;
489-
}
490-
491-
bool PerformLocalDisassembly(const uint8_t *data, uint64_t addr, size_t &len, vector<InstructionTextToken> &result)
460+
bool PrintLocalDisassembly(const uint8_t *data, uint64_t addr, size_t &len, vector<InstructionTextToken> &result, decomp_result* res)
492461
{
493462
(void)addr;
463+
char buf[16];
464+
uint32_t local_op = PPC_INS_INVALID;
494465

495-
if (len < 4) return false;
496-
uint32_t insword = *(uint32_t *)data;
497-
if(endian == BigEndian)
498-
insword = bswap32(insword);
466+
struct cs_detail *detail = 0;
467+
struct cs_ppc *ppc = 0;
468+
struct cs_insn *insn = &(res->insn);
469+
470+
detail = &(res->detail);
471+
ppc = &(detail->ppc);
499472

473+
if (len < 4)
474+
return false;
500475
len = 4;
501476

502-
char buf[16];
477+
local_op = DoesQualifyForLocalDisassembly(data, endian == BigEndian);
478+
PerformLocalDisassembly(data, addr, len, res, endian == BigEndian);
503479

504-
// 111111AAA00BBBBBCCCCC00001000000 "fcmpo crA,fB,fC"
505-
uint32_t tmp = insword & 0xFC6007FF;
506-
if (tmp==0xFC000040) {
507-
result.emplace_back(InstructionToken, "fcmpo");
480+
switch (local_op)
481+
{
482+
case PPC_INS_BN_FCMPO:
483+
result.emplace_back(InstructionToken, insn->mnemonic);
508484
result.emplace_back(TextToken, " ");
509-
snprintf(buf, sizeof(buf), "cr%d", (insword >> 23) & 7);
485+
snprintf(buf, sizeof(buf), "cr%d", ppc->operands[0].reg);
510486
result.emplace_back(RegisterToken, buf);
511487
result.emplace_back(OperandSeparatorToken, ", ");
512-
snprintf(buf, sizeof(buf), "f%d", (insword >> 16) & 31);
488+
snprintf(buf, sizeof(buf), "f%d", ppc->operands[1].reg);
513489
result.emplace_back(RegisterToken, buf);
514490
result.emplace_back(OperandSeparatorToken, ", ");
515-
snprintf(buf, sizeof(buf), "f%d", (insword >> 11) & 31);
516-
result.emplace_back(RegisterToken, buf);
517-
return true;
518-
}
519-
520-
// 111100AAAAABBBBBCCCCC00011010BCA "xxpermr vsA,vsB,vsC"
521-
if ((insword & 0xFC0007F8)==0xF00001D0) {
522-
int a = ((insword & 0x3E00000)>>21)|((insword & 0x1)<<5);
523-
int b = ((insword & 0x1F0000)>>16)|((insword & 0x4)<<3);
524-
int c = ((insword & 0xF800)>>11)|((insword & 0x2)<<4);
525-
result.emplace_back(InstructionToken, "xxpermr");
526-
result.emplace_back(TextToken, " ");
527-
snprintf(buf, sizeof(buf), "vs%d", a);
491+
snprintf(buf, sizeof(buf), "f%d", ppc->operands[2].reg);
528492
result.emplace_back(RegisterToken, buf);
529-
result.emplace_back(OperandSeparatorToken, ", ");
530-
snprintf(buf, sizeof(buf), "vs%d", b);
531-
result.emplace_back(RegisterToken, buf);
532-
result.emplace_back(OperandSeparatorToken, ", ");
533-
snprintf(buf, sizeof(buf), "vs%d", c);
534-
result.emplace_back(RegisterToken, buf);
535-
return true;
536-
}
537-
538-
// 000100AAAAABBBBBCCCCCDEEE000110x psq_lx FREG,GPR,GPR,NUM,NUM
539-
// 000100AAAAABBBBBCCCCCDEEE000111x psq_stx FREG,GPR,GPR,NUM,NUM
540-
// 000100AAAAABBBBBCCCCCDEEE100110x psq_lux FREG,GPR,GPR,NUM,NUM
541-
// 000100AAAAABBBBBCCCCCDEEE100111x psq_stux FREG,GPR,GPR,NUM,NUM
542-
tmp = insword & 0xFC00007E;
543-
if (tmp==0x1000000C || tmp==0x1000000E || tmp==0x1000004C || tmp==0x1000004E) {
544-
switch(tmp) {
545-
case 0x1000000C:
546-
result.emplace_back(InstructionToken, "psq_lx");
547-
result.emplace_back(TextToken, " ");
548-
break;
549-
case 0x1000000E: result.emplace_back(InstructionToken, "psq_stx");
550-
result.emplace_back(TextToken, " ");
551-
break;
552-
case 0x1000004C: result.emplace_back(InstructionToken, "psq_lux");
553-
result.emplace_back(TextToken, " ");
554-
break;
555-
case 0x1000004E: result.emplace_back(InstructionToken, "psq_stux");
556-
result.emplace_back(TextToken, " ");
557-
break;
558-
}
559-
snprintf(buf, sizeof(buf), "f%d", (insword & 0x3E00000) >> 21);
560-
result.emplace_back(RegisterToken, buf);
561-
result.emplace_back(OperandSeparatorToken, ", ");
562-
snprintf(buf, sizeof(buf), "r%d", (insword & 0x1F0000) >> 16);
563-
result.emplace_back(RegisterToken, buf);
564-
result.emplace_back(OperandSeparatorToken, ", ");
565-
snprintf(buf, sizeof(buf), "r%d", (insword & 0xF800) >> 11);
566-
result.emplace_back(RegisterToken, buf);
567-
result.emplace_back(OperandSeparatorToken, ", ");
568-
tmp = (insword & 0x400)>>10;
569-
snprintf(buf, sizeof(buf), "%d", tmp);
570-
result.emplace_back(IntegerToken, buf, tmp, 1);
571-
result.emplace_back(OperandSeparatorToken, ", ");
572-
tmp = (insword & 0x380)>>7;
573-
snprintf(buf, sizeof(buf), "%d", tmp);
574-
result.emplace_back(IntegerToken, buf, tmp, 1);
575-
return true;
576-
}
577-
578-
// 000100AAAAABBBBB00000CCCCC011000 ps_muls0 FREG,FREG,FREG
579-
// 000100AAAAABBBBB00000CCCCC011001 ps_muls0. FREG,FREG,FREG
580-
// 000100AAAAABBBBB00000CCCCC011010 ps_muls1 FREG,FREG,FREG
581-
// 000100AAAAABBBBB00000CCCCC011011 ps_muls1. FREG,FREG,FREG
582-
tmp = insword & 0xFC00F83F;
583-
if (tmp==0x10000018 || tmp==0x10000019 || tmp==0x1000001A || tmp==0x1000001B) {
584-
switch(tmp) {
585-
case 0x10000018: result.emplace_back(InstructionToken, "ps_muls0"); break;
586-
case 0x10000019: result.emplace_back(InstructionToken, "ps_muls0."); break;
587-
case 0x1000001A: result.emplace_back(InstructionToken, "ps_muls1"); break;
588-
case 0x1000001B: result.emplace_back(InstructionToken, "ps_muls1."); break;
589-
}
493+
break;
494+
case PPC_INS_BN_XXPERMR:
495+
result.emplace_back(InstructionToken, insn->mnemonic);
590496
result.emplace_back(TextToken, " ");
591-
snprintf(buf, sizeof(buf), "f%d", (insword & 0x3E00000) >> 21);
497+
snprintf(buf, sizeof(buf), "vs%d", ppc->operands[0].reg);
592498
result.emplace_back(RegisterToken, buf);
593499
result.emplace_back(OperandSeparatorToken, ", ");
594-
snprintf(buf, sizeof(buf), "f%d", (insword & 0x1F0000) >> 16);
500+
snprintf(buf, sizeof(buf), "vs%d", ppc->operands[1].reg);
595501
result.emplace_back(RegisterToken, buf);
596502
result.emplace_back(OperandSeparatorToken, ", ");
597-
snprintf(buf, sizeof(buf), "f%d", (insword & 0x7C0) >> 6);
503+
snprintf(buf, sizeof(buf), "vs%d", ppc->operands[2].reg);
598504
result.emplace_back(RegisterToken, buf);
599-
return true;
505+
break;
506+
default:
507+
return false;
600508
}
601-
602-
return false;
509+
return true;
603510
}
604511

605512
/* populate the vector result with InstructionTextToken
@@ -623,9 +530,9 @@ class PowerpcArchitecture: public Architecture
623530
goto cleanup;
624531
}
625532

626-
if (DoesQualifyForLocalDisassembly(data))
627-
return PerformLocalDisassembly(data, addr, len, result);
628-
533+
if (DoesQualifyForLocalDisassembly(data, endian == BigEndian))
534+
// PerformLocalDisassembly(data, addr, len, &res, endian == BigEndian);
535+
return PrintLocalDisassembly(data, addr, len, result, &res);
629536
if(powerpc_decompose(data, 4, (uint32_t)addr, endian == LittleEndian, &res, GetAddressSize() == 8, cs_mode_local)) {
630537
MYLOG("ERROR: powerpc_decompose()\n");
631538
goto cleanup;
@@ -733,6 +640,7 @@ class PowerpcArchitecture: public Architecture
733640
virtual bool GetInstructionLowLevelIL(const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il) override
734641
{
735642
bool rc = false;
643+
struct decomp_result res = {0};
736644

737645
if (len < 4) {
738646
MYLOG("ERROR: need at least 4 bytes\n");
@@ -743,21 +651,16 @@ class PowerpcArchitecture: public Architecture
743651
// MYLOG("%s(data, 0x%llX, 0x%zX, il)\n", __func__, addr, len);
744652
//}
745653

746-
struct decomp_result res;
747-
748-
if (DoesQualifyForLocalDisassembly(data)) {
749-
il.AddInstruction(il.Unimplemented());
750-
rc = true;
751-
len = 4;
752-
goto cleanup;
654+
if (DoesQualifyForLocalDisassembly(data, endian == BigEndian)) {
655+
PerformLocalDisassembly(data, addr, len, &res, endian == BigEndian);
753656
}
754-
755-
if(powerpc_decompose(data, 4, (uint32_t)addr, endian == LittleEndian, &res, GetAddressSize() == 8, cs_mode_local)) {
657+
else if(powerpc_decompose(data, 4, (uint32_t)addr, endian == LittleEndian, &res, GetAddressSize() == 8, cs_mode_local)) {
756658
MYLOG("ERROR: powerpc_decompose()\n");
757659
il.AddInstruction(il.Undefined());
758660
goto cleanup;
759661
}
760662

663+
getil:
761664
rc = GetLowLevelILForPPCInstruction(this, il, data, addr, &res, endian == LittleEndian);
762665
len = 4;
763666

arch/powerpc/disassembler.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,90 @@ architecture plugin picture.
1212
//#define MYLOG BinaryNinja::LogDebug
1313

1414
#include "disassembler.h"
15+
#include "util.h"
1516

1617
/* have to do this... while options can be toggled after initialization (thru
1718
cs_option(), the modes cannot, and endianness is considered a mode) */
1819
thread_local csh handle_lil = 0;
1920
thread_local csh handle_big = 0;
2021

22+
int DoesQualifyForLocalDisassembly(const uint8_t *data, bool bigendian)
23+
{
24+
uint32_t insword = *(uint32_t *)data;
25+
int result = PPC_INS_INVALID;
26+
uint32_t tmp = 0;
27+
28+
if(bigendian == true)
29+
insword = bswap32(insword);
30+
31+
// 111111xxx00xxxxxxxxxx00001000000 <- fcmpo
32+
tmp = insword & 0xFC6007FF;
33+
if (tmp==0xFC000040)
34+
result = PPC_INS_BN_FCMPO;
35+
// 111100xxxxxxxxxxxxxxx00111010xxx <- xxpermr
36+
if((insword & 0xFC0007F8) == 0xF00001D0)
37+
result = PPC_INS_BN_XXPERMR;
38+
39+
return result;
40+
}
41+
42+
void ppc_fcmpo(uint32_t insword, decomp_result *res)
43+
{
44+
// 111111AAA00BBBBBCCCCC00001000000 "fcmpo crA,fB,fC"
45+
res->detail.ppc.operands[0].reg = (ppc_reg)(PPC_REG_CR0 + (insword >> 23) & 7);
46+
res->detail.ppc.operands[0].type = PPC_OP_REG;
47+
res->detail.ppc.operands[1].reg = (ppc_reg)(PPC_REG_F0 + (insword >> 16) & 31);
48+
res->detail.ppc.operands[1].type = PPC_OP_REG;
49+
res->detail.ppc.operands[2].reg = (ppc_reg)(PPC_REG_F0 + (insword >> 11) & 31);
50+
res->detail.ppc.operands[2].type = PPC_OP_REG;
51+
52+
res->insn.id = PPC_INS_BN_FCMPO;
53+
res->detail.ppc.op_count = 3;
54+
strncpy(res->insn.mnemonic, "fcmpo", sizeof(res->insn.mnemonic));
55+
}
56+
57+
void ppc_xxpermr(uint32_t insword, decomp_result *res)
58+
{
59+
// 111100AAAAABBBBBCCCCC00011010BCA "xxpermr vsA,vsB,vsC"
60+
int a = ((insword & 0x3E00000)>>21)|((insword & 0x1)<<5);
61+
int b = ((insword & 0x1F0000)>>16)|((insword & 0x4)<<3);
62+
int c = ((insword & 0xF800)>>11)|((insword & 0x2)<<4);
63+
64+
res->detail.ppc.operands[0].reg = (ppc_reg)(PPC_REG_VS0 + a);
65+
res->detail.ppc.operands[0].type = PPC_OP_REG;
66+
res->detail.ppc.operands[1].reg = (ppc_reg)(PPC_REG_VS0 + b);
67+
res->detail.ppc.operands[1].type = PPC_OP_REG;
68+
res->detail.ppc.operands[2].reg = (ppc_reg)(PPC_REG_VS0 + c);
69+
res->detail.ppc.operands[2].type = PPC_OP_REG;
70+
71+
res->insn.id = PPC_INS_BN_XXPERMR;
72+
res->detail.ppc.op_count = 3;
73+
strncpy(res->insn.mnemonic, "xxpermr", sizeof(res->insn.mnemonic));
74+
}
75+
76+
bool PerformLocalDisassembly(const uint8_t *data, uint64_t addr, size_t &len, decomp_result* res, bool bigendian)
77+
{
78+
uint32_t local_op = 0;
79+
uint32_t insword = 0;
80+
81+
if(bigendian == true)
82+
insword = bswap32(insword);
83+
local_op = DoesQualifyForLocalDisassembly(data, bigendian);
84+
85+
switch(local_op)
86+
{
87+
case PPC_INS_BN_FCMPO:
88+
ppc_fcmpo(insword, res);
89+
break;
90+
case PPC_INS_BN_XXPERMR:
91+
ppc_xxpermr(insword, res);
92+
break;
93+
default:
94+
return false;
95+
}
96+
return true;
97+
}
98+
2199
extern "C" int
22100
powerpc_init(int cs_mode_arg)
23101
{

arch/powerpc/disassembler.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ enum ppc_status_t {
3333
STATUS_ERROR_UNSPEC=-1, STATUS_SUCCESS=0, STATUS_UNDEF_INSTR
3434
};
3535

36+
typedef enum ppc_insn_bn {
37+
PPC_INS_BN_FCMPO = PPC_INS_ENDING+1,
38+
PPC_INS_BN_XXPERMR,
39+
PPC_INS_BN_PSQ_LX,
40+
PPC_INS_BN_PSQ_STX,
41+
PPC_INS_BN_PSQ_LUX,
42+
PPC_INS_BN_PSQ_STUX,
43+
PPC_INS_BN_PS_MULS0,
44+
PPC_INS_BN_PS_MULS0D,
45+
PPC_INS_BN_PS_MULS1,
46+
PPC_INS_BN_PS_MULS1D,
47+
PPC_INS_BN_ENDING
48+
} ppc_insn_bn;
3649

3750
/* operand type */
3851
enum operand_type_t { REG, VAL, LABEL };
@@ -60,6 +73,9 @@ struct decomp_result
6073
//*****************************************************************************
6174
// function prototypes
6275
//*****************************************************************************
76+
int DoesQualifyForLocalDisassembly(const uint8_t *data, bool bigendian);
77+
bool PerformLocalDisassembly(const uint8_t *data, uint64_t addr, size_t &len, decomp_result* res, bool bigendian);
78+
6379
extern "C" int powerpc_init(int);
6480
extern "C" void powerpc_release(void);
6581
extern "C" int powerpc_decompose(const uint8_t *data, int size, uint32_t addr,

0 commit comments

Comments
 (0)