Skip to content

Commit 249bb51

Browse files
committed
fixed disassembly for fp stuff
1 parent 65d0a3e commit 249bb51

File tree

4 files changed

+95
-14
lines changed

4 files changed

+95
-14
lines changed

arch/powerpc/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ 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+
target_compile_definitions(test_disasm PRIVATE FORCE_TEST=1)
61+
6062
set_target_properties(test_disasm test_asm PROPERTIES
6163
CXX_STANDARD 17
6264
CXX_VISIBILITY_PRESET hidden

arch/powerpc/arch_ppc.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -482,25 +482,25 @@ class PowerpcArchitecture: public Architecture
482482
case PPC_INS_BN_FCMPO:
483483
result.emplace_back(InstructionToken, insn->mnemonic);
484484
result.emplace_back(TextToken, " ");
485-
snprintf(buf, sizeof(buf), "cr%d", ppc->operands[0].reg);
485+
snprintf(buf, sizeof(buf), "cr%d", ppc->operands[0].reg - PPC_REG_CR0);
486486
result.emplace_back(RegisterToken, buf);
487487
result.emplace_back(OperandSeparatorToken, ", ");
488-
snprintf(buf, sizeof(buf), "f%d", ppc->operands[1].reg);
488+
snprintf(buf, sizeof(buf), "f%d", ppc->operands[1].reg - PPC_REG_F0);
489489
result.emplace_back(RegisterToken, buf);
490490
result.emplace_back(OperandSeparatorToken, ", ");
491-
snprintf(buf, sizeof(buf), "f%d", ppc->operands[2].reg);
491+
snprintf(buf, sizeof(buf), "f%d", ppc->operands[2].reg - PPC_REG_F0);
492492
result.emplace_back(RegisterToken, buf);
493493
break;
494494
case PPC_INS_BN_XXPERMR:
495495
result.emplace_back(InstructionToken, insn->mnemonic);
496496
result.emplace_back(TextToken, " ");
497-
snprintf(buf, sizeof(buf), "vs%d", ppc->operands[0].reg);
497+
snprintf(buf, sizeof(buf), "vs%d", ppc->operands[0].reg - PPC_REG_VS0);
498498
result.emplace_back(RegisterToken, buf);
499499
result.emplace_back(OperandSeparatorToken, ", ");
500-
snprintf(buf, sizeof(buf), "vs%d", ppc->operands[1].reg);
500+
snprintf(buf, sizeof(buf), "vs%d", ppc->operands[1].reg - PPC_REG_VS0);
501501
result.emplace_back(RegisterToken, buf);
502502
result.emplace_back(OperandSeparatorToken, ", ");
503-
snprintf(buf, sizeof(buf), "vs%d", ppc->operands[2].reg);
503+
snprintf(buf, sizeof(buf), "vs%d", ppc->operands[2].reg - PPC_REG_VS0);
504504
result.emplace_back(RegisterToken, buf);
505505
break;
506506
default:
@@ -531,8 +531,10 @@ class PowerpcArchitecture: public Architecture
531531
}
532532

533533
if (DoesQualifyForLocalDisassembly(data, endian == BigEndian))
534+
{
534535
// PerformLocalDisassembly(data, addr, len, &res, endian == BigEndian);
535536
return PrintLocalDisassembly(data, addr, len, result, &res);
537+
}
536538
if(powerpc_decompose(data, 4, (uint32_t)addr, endian == LittleEndian, &res, GetAddressSize() == 8, cs_mode_local)) {
537539
MYLOG("ERROR: powerpc_decompose()\n");
538540
goto cleanup;

arch/powerpc/disassembler.cpp

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ int DoesQualifyForLocalDisassembly(const uint8_t *data, bool bigendian)
2626
uint32_t tmp = 0;
2727

2828
if(bigendian == true)
29+
{
2930
insword = bswap32(insword);
31+
}
3032

3133
// 111111xxx00xxxxxxxxxx00001000000 <- fcmpo
3234
tmp = insword & 0xFC6007FF;
@@ -41,17 +43,78 @@ int DoesQualifyForLocalDisassembly(const uint8_t *data, bool bigendian)
4143

4244
void ppc_fcmpo(uint32_t insword, decomp_result *res)
4345
{
46+
unsigned regtmp = 0;
47+
4448
// 111111AAA00BBBBBCCCCC00001000000 "fcmpo crA,fB,fC"
45-
res->detail.ppc.operands[0].reg = (ppc_reg)(PPC_REG_CR0 + (insword >> 23) & 7);
49+
regtmp = PPC_REG_CR0 + ((insword >> 23) & 7);
50+
res->detail.ppc.operands[0].reg = (ppc_reg)(regtmp);
4651
res->detail.ppc.operands[0].type = PPC_OP_REG;
47-
res->detail.ppc.operands[1].reg = (ppc_reg)(PPC_REG_F0 + (insword >> 16) & 31);
52+
53+
regtmp = PPC_REG_F0 + ((insword >> 16) & 31);
54+
res->detail.ppc.operands[1].reg = (ppc_reg)(regtmp);
4855
res->detail.ppc.operands[1].type = PPC_OP_REG;
49-
res->detail.ppc.operands[2].reg = (ppc_reg)(PPC_REG_F0 + (insword >> 11) & 31);
56+
57+
regtmp = PPC_REG_F0 + ((insword >> 11) & 31);
58+
res->detail.ppc.operands[2].reg = (ppc_reg)(regtmp);
5059
res->detail.ppc.operands[2].type = PPC_OP_REG;
5160

61+
62+
#ifdef FORCE_TEST
63+
SStream ss;
64+
struct cs_struct* handle = 0;
65+
struct MCInst tempmc = {0};
66+
char* first_space = 0;
67+
68+
// SStream_Init(&ss);
69+
ss.index = 0;
70+
ss.buffer[0] = '\0';
71+
regtmp = PPC_REG_CR0 + ((insword >> 23) & 7);
72+
tempmc.Operands[0].MachineOperandType = MCOperand::kRegister;
73+
tempmc.Operands[0].Kind = 1;
74+
tempmc.Operands[0].RegVal = regtmp;
75+
regtmp = PPC_REG_F0 + ((insword >> 16) & 31);
76+
tempmc.Operands[1].MachineOperandType = MCOperand::kRegister;
77+
tempmc.Operands[1].Kind = 1;
78+
tempmc.Operands[1].RegVal = regtmp;
79+
regtmp = PPC_REG_F0 + ((insword >> 11) & 31);
80+
tempmc.Operands[2].Kind = 1;
81+
tempmc.Operands[2].MachineOperandType = MCOperand::kRegister;
82+
tempmc.Operands[2].RegVal = regtmp;
83+
84+
// temporarily set this so that print processing succeeds
85+
res->insn.id = PPC_INS_FCMPU;
86+
87+
if (handle_big != 0)
88+
{
89+
handle = (struct cs_struct*)handle_big;
90+
}
91+
else if (handle_lil != 0)
92+
{
93+
handle = (struct cs_struct*)handle_lil;
94+
}
95+
96+
#define PPC_FCMPUS 804
97+
98+
tempmc.csh = handle;
99+
tempmc.Opcode = PPC_FCMPUS;
100+
tempmc.flat_insn = &res->insn;
101+
tempmc.flat_insn->detail = &res->detail;
102+
103+
if (handle != 0)
104+
{
105+
handle->printer(&tempmc, &ss, handle->printer_info);
106+
}
107+
108+
// replace the 'fcmpu' with 'fcmpo'
109+
first_space = strchr(ss.buffer, ' ');
110+
strncpy(res->insn.op_str, first_space + 1, sizeof(res->insn.op_str));
111+
#endif
112+
113+
strncpy(res->insn.mnemonic, "fcmpo", sizeof(res->insn.mnemonic));
114+
115+
// reset this to the target value
52116
res->insn.id = PPC_INS_BN_FCMPO;
53117
res->detail.ppc.op_count = 3;
54-
strncpy(res->insn.mnemonic, "fcmpo", sizeof(res->insn.mnemonic));
55118
}
56119

57120
void ppc_xxpermr(uint32_t insword, decomp_result *res)
@@ -76,10 +139,13 @@ void ppc_xxpermr(uint32_t insword, decomp_result *res)
76139
bool PerformLocalDisassembly(const uint8_t *data, uint64_t addr, size_t &len, decomp_result* res, bool bigendian)
77140
{
78141
uint32_t local_op = 0;
79-
uint32_t insword = 0;
142+
uint32_t insword = *(uint32_t *)data;
80143

81144
if(bigendian == true)
145+
{
82146
insword = bswap32(insword);
147+
}
148+
83149
local_op = DoesQualifyForLocalDisassembly(data, bigendian);
84150

85151
switch(local_op)

arch/powerpc/test_disasm.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,25 @@ int disas_instr_word(uint32_t instr_word, char *buf)
2828
{
2929
int rc = -1;
3030

31-
struct decomp_result res;
31+
struct decomp_result res = {0};
3232
struct cs_insn *insn = &(res.insn);
3333
struct cs_detail *detail = &(res.detail);
3434
struct cs_ppc *ppc = &(detail->ppc);
3535

3636
if(powerpc_decompose((const uint8_t *)&instr_word, 4, 0, bigendian, &res, address_size_, cs_mode_local)) {
37-
if(print_errors) printf("ERROR: powerpc_decompose()\n");
38-
goto cleanup;
37+
if(print_errors)
38+
{
39+
if (DoesQualifyForLocalDisassembly((uint8_t*)&instr_word, !bigendian) != PPC_INS_INVALID)
40+
{
41+
size_t instsz = 4;
42+
PerformLocalDisassembly((uint8_t*)&instr_word, 0, instsz, &res, !bigendian);
43+
}
44+
else
45+
{
46+
printf("ERROR: powerpc_decompose()\n");
47+
goto cleanup;
48+
}
49+
}
3950
}
4051

4152
/* MEGA DETAILS, IF YOU WANT 'EM */

0 commit comments

Comments
 (0)