diff options
| author | Galen Williamson <galen@vector35.com> | 2025-06-09 19:30:13 -0400 |
|---|---|---|
| committer | Galen Williamson <galen@vector35.com> | 2025-06-09 19:30:13 -0400 |
| commit | 35c2a4cf35589e1c3046ecbe2c480a57b6d10360 (patch) | |
| tree | 9c95fc3d75c0c376c82e4fbe7e197ec5352260f8 /arch/armv7/thumb2_disasm/arch_thumb2.cpp | |
| parent | 9373cab26ee2e7b2febab7674360d54d6fb8adc6 (diff) | |
[thumb2] Converted MSR system registers into enum
Diffstat (limited to 'arch/armv7/thumb2_disasm/arch_thumb2.cpp')
| -rw-r--r-- | arch/armv7/thumb2_disasm/arch_thumb2.cpp | 142 |
1 files changed, 131 insertions, 11 deletions
diff --git a/arch/armv7/thumb2_disasm/arch_thumb2.cpp b/arch/armv7/thumb2_disasm/arch_thumb2.cpp index a4a3c1cc..873b9b27 100644 --- a/arch/armv7/thumb2_disasm/arch_thumb2.cpp +++ b/arch/armv7/thumb2_disasm/arch_thumb2.cpp @@ -20,6 +20,72 @@ using namespace std; #define snprintf _snprintf #endif +static Ref<Enumeration> get_msr_op_enum() +{ + EnumerationBuilder builder; + builder.AddMemberWithValue("msp", REGS_MSP); + builder.AddMemberWithValue("psp", REGS_PSP); + builder.AddMemberWithValue("basepri", REGS_BASEPRI); + builder.AddMemberWithValue("basepri_max", REGS_BASEPRI_MAX); + builder.AddMemberWithValue("primask", REGS_PRIMASK); + builder.AddMemberWithValue("faultmask", REGS_FAULTMASK); + builder.AddMemberWithValue("control", REGS_CONTROL); + builder.AddMemberWithValue("ipsr", REGS_IPSR); + builder.AddMemberWithValue("epsr", REGS_EPSR); + builder.AddMemberWithValue("iepsr", REGS_IEPSR); + builder.AddMemberWithValue("apsr", REGS_APSR); + builder.AddMemberWithValue("apsr_g", REGS_APSR_G); + builder.AddMemberWithValue("apsr_nzcvq", REGS_APSR_NZCVQ); + builder.AddMemberWithValue("apsr_nzcvqg", REGS_APSR_NZCVQG); + builder.AddMemberWithValue("iapsr", REGS_IAPSR); + builder.AddMemberWithValue("iapsr_g", REGS_IAPSR_G); + builder.AddMemberWithValue("iapsr_nzcvq", REGS_IAPSR_NZCVQ); + builder.AddMemberWithValue("iapsr_nzcvqg", REGS_IAPSR_NZCVQG); + builder.AddMemberWithValue("eapsr", REGS_EAPSR); + builder.AddMemberWithValue("eapsr_g", REGS_EAPSR_G); + builder.AddMemberWithValue("eapsr_nzcvq", REGS_EAPSR_NZCVQ); + builder.AddMemberWithValue("eapsr_nzcvqg", REGS_EAPSR_NZCVQG); + builder.AddMemberWithValue("xpsr", REGS_XPSR); + builder.AddMemberWithValue("xpsr_g", REGS_XPSR_G); + builder.AddMemberWithValue("xpsr_nzcvq", REGS_XPSR_NZCVQ); + builder.AddMemberWithValue("xpsr_nzcvqg", REGS_XPSR_NZCVQG); + builder.AddMemberWithValue("cpsr", REGS_CPSR); + builder.AddMemberWithValue("cpsr_c", REGS_CPSR_C); + builder.AddMemberWithValue("cpsr_x", REGS_CPSR_X); + builder.AddMemberWithValue("cpsr_xc", REGS_CPSR_XC); + builder.AddMemberWithValue("cpsr_s", REGS_CPSR_S); + builder.AddMemberWithValue("cpsr_sc", REGS_CPSR_SC); + builder.AddMemberWithValue("cpsr_sx", REGS_CPSR_SX); + builder.AddMemberWithValue("cpsr_sxc", REGS_CPSR_SXC); + builder.AddMemberWithValue("cpsr_f", REGS_CPSR_F); + builder.AddMemberWithValue("cpsr_fc", REGS_CPSR_FC); + builder.AddMemberWithValue("cpsr_fx", REGS_CPSR_FX); + builder.AddMemberWithValue("cpsr_fxc", REGS_CPSR_FXC); + builder.AddMemberWithValue("cpsr_fs", REGS_CPSR_FS); + builder.AddMemberWithValue("cpsr_fsc", REGS_CPSR_FSC); + builder.AddMemberWithValue("cpsr_fsx", REGS_CPSR_FSX); + builder.AddMemberWithValue("cpsr_fsxc", REGS_CPSR_FSXC); + builder.AddMemberWithValue("spsr", REGS_SPSR); + builder.AddMemberWithValue("spsr_c", REGS_SPSR_C); + builder.AddMemberWithValue("spsr_x", REGS_SPSR_X); + builder.AddMemberWithValue("spsr_xc", REGS_SPSR_XC); + builder.AddMemberWithValue("spsr_s", REGS_SPSR_S); + builder.AddMemberWithValue("spsr_sc", REGS_SPSR_SC); + builder.AddMemberWithValue("spsr_sx", REGS_SPSR_SX); + builder.AddMemberWithValue("spsr_sxc", REGS_SPSR_SXC); + builder.AddMemberWithValue("spsr_f", REGS_SPSR_F); + builder.AddMemberWithValue("spsr_fc", REGS_SPSR_FC); + builder.AddMemberWithValue("spsr_fx", REGS_SPSR_FX); + builder.AddMemberWithValue("spsr_fxc", REGS_SPSR_FXC); + builder.AddMemberWithValue("spsr_fs", REGS_SPSR_FS); + builder.AddMemberWithValue("spsr_fsc", REGS_SPSR_FSC); + builder.AddMemberWithValue("spsr_fsx", REGS_SPSR_FSX); + builder.AddMemberWithValue("spsr_fsxc", REGS_SPSR_FSXC); + builder.AddMemberWithValue("apsr_nzcv", REGS_APSR_NZCV); + Ref<Enumeration> _enum = builder.Finalize(); + return _enum; +} + /* class Architecture from binaryninjaapi.h */ class Thumb2Architecture: public ArmCommonArchitecture { @@ -1217,13 +1283,16 @@ public: } /* application level form */ else { - uint32_t tmp = (decomp.fields[FIELD_write_nzcvq] << 1) | decomp.fields[FIELD_write_g]; + uint32_t mask = (decomp.fields[FIELD_write_nzcvq] << 1) | decomp.fields[FIELD_write_g]; uint8_t sysm = decomp.fields[FIELD_SYSm]; bool xPSR = ((sysm >> 2) & 1) == 1; switch (sysm >> 3) { case 0: /* xPSR access */ + { + string reg_name = ""; + string reg_bits = ""; if (xPSR) - switch (sysm) { + switch (sysm & 7) { case 5: // '101' == IPSR result.emplace_back(RegisterToken, "ipsr"); break; @@ -1235,23 +1304,41 @@ public: break; } else - switch(tmp) { + { + switch (sysm & 3) + { + case 0: + reg_name = "apsr"; + break; + case 1: + reg_name = "iapsr"; + break; + case 2: + reg_name = "eapsr"; + break; + case 3: + reg_name = "xpsr"; + break; + } + switch(mask) { case 0: // unpredictable break; case 1: // '01' == write_g /* aka CPSR_f */ - result.emplace_back(RegisterToken, "apsr_g"); + result.emplace_back(RegisterToken, reg_name + "_g"); break; case 2: // '10' == write_nzcvq /* aka CPSR_s */ - result.emplace_back(RegisterToken, "apsr_nzcvq"); + result.emplace_back(RegisterToken, reg_name + "_nzcvq"); break; case 3: // '11' == write_nzcvq | write_g /* aka CPSR_fs */ - result.emplace_back(RegisterToken, "apsr_nzcvqg"); + result.emplace_back(RegisterToken, reg_name + "_nzcvqg"); break; + } } break; + } case 1: /* SP access */ switch (sysm & 7) { case 0: @@ -1269,9 +1356,11 @@ public: result.emplace_back(RegisterToken, "primask"); break; case 1: - case 2: result.emplace_back(RegisterToken, "basepri"); break; + case 2: + result.emplace_back(RegisterToken, "basepri_max"); + break; case 3: result.emplace_back(RegisterToken, "faultmask"); break; @@ -1292,7 +1381,30 @@ public: uint8_t sysm = decomp.fields[FIELD_SYSm]; switch (sysm >> 3) { case 0: /* xPSR access */ - result.emplace_back(RegisterToken, "apsr"); + switch (sysm & 7) + { + case 0: + result.emplace_back(RegisterToken, "apsr"); + break; + case 1: + result.emplace_back(RegisterToken, "iapsr"); + break; + case 2: + result.emplace_back(RegisterToken, "eapsr"); + break; + case 3: + result.emplace_back(RegisterToken, "xpsr"); + break; + case 5: // '101' == IPSR + result.emplace_back(RegisterToken, "ipsr"); + break; + case 6: // '110' == EPSR + result.emplace_back(RegisterToken, "epsr"); + break; + case 7: // '111' == IEPSR + result.emplace_back(RegisterToken, "iepsr"); + break; + } break; case 1: /* SP access */ switch (sysm & 7) { @@ -1495,9 +1607,16 @@ public: NameAndType("m", Type::IntegerType(1, false)), }; case ARMV7_INTRIN_MRS: - return {NameAndType(Type::IntegerType(4, false))}; + // return {NameAndType(Type::IntegerType(4, false))}; + return { + NameAndType("msr", Confidence<Ref<Type>>(Type::EnumerationType(this, get_msr_op_enum(), 4, false), BN_FULL_CONFIDENCE)) + }; case ARMV7_INTRIN_MSR: - return {NameAndType(Type::IntegerType(4, false))}; + // return {NameAndType(Type::IntegerType(4, false))}; + return { + NameAndType("msr", Confidence<Ref<Type>>(Type::EnumerationType(this, get_msr_op_enum(), 4, false), BN_FULL_CONFIDENCE)), + NameAndType(Type::IntegerType(4, false)) + }; case ARMV7_INTRIN_DBG: return {NameAndType(Type::IntegerType(1, false))}; default: @@ -1516,7 +1635,8 @@ public: case ARMV7_INTRIN_MRS: return {Type::IntegerType(4, false)}; case ARMV7_INTRIN_MSR: - return {Type::IntegerType(4, false)}; + // return {Type::IntegerType(4, false)}; + return {}; default: return vector<Confidence<Ref<Type>>>(); } |
