From 90f93db51a374d865050d3d9075d6d44aa7031dc Mon Sep 17 00:00:00 2001 From: jonathanzetier <207571460+jonathanzetier@users.noreply.github.com> Date: Mon, 14 Apr 2025 07:10:58 -0700 Subject: [PATCH] Add support for MSR/MRS (banked register) --- Ghidra/Processors/ARM/data/languages/ARM.sinc | 22 ++- .../data/languages/ARMTHUMBinstructions.sinc | 144 +++++++++++++++++- .../ARM/data/languages/ARMinstructions.sinc | 86 +++++++++++ .../Processors/ARM/data/languages/ARMt.pspec | 4 + .../ARM/data/languages/ARMtTHUMB.pspec | 4 + 5 files changed, 258 insertions(+), 2 deletions(-) diff --git a/Ghidra/Processors/ARM/data/languages/ARM.sinc b/Ghidra/Processors/ARM/data/languages/ARM.sinc index 756faecbbbc..5822b8197bd 100644 --- a/Ghidra/Processors/ARM/data/languages/ARM.sinc +++ b/Ghidra/Processors/ARM/data/languages/ARM.sinc @@ -11,7 +11,6 @@ define register offset=0x0020 size=4 [ r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 define register offset=0x0060 size=1 [ NG ZR CY OV tmpNG tmpZR tmpCY tmpOV shift_carry TB Q GE1 GE2 GE3 GE4 ]; define register offset=0x0070 size=4 [ cpsr spsr ]; define register offset=0x0080 size=4 [ mult_addr ]; # Special internal register for dealing with multiple stores/loads -define register offset=0x0084 size=4 [ r14_svc r13_svc spsr_svc ]; define register offset=0x0090 size=8 [ mult_dat8 ]; # Special internal register for dealing with multiple stores/loads define register offset=0x0090 size=16 [ mult_dat16 ]; # Special internal register for dealing with multiple stores/loads define register offset=0x00A0 size=4 [ fpsr ]; # floating point state register (for FPA10 floating-point accelerator) @@ -75,6 +74,22 @@ define register offset=0x0200 size=4 [ cr0 cr1 cr2 cr3 cr4 cr5 cr6 cr7 cr8 cr9 c @endif # SIMD +@if defined(VERSION_7) + # 0x400-0x500 is marked as volatile in the .pspec; update it there if this + # space is moved or expanded + # 33 registers x 4 bytes/register = 0x84 bytes consumed + define register offset=0x0400 size=4 [ r8_usr r9_usr r10_usr r11_usr r12_usr sp_usr lr_usr + r8_fiq r9_fiq r10_fiq r11_fiq r12_fiq sp_fiq lr_fiq + sp_irq lr_irq + sp_svc lr_svc + sp_mon lr_mon + sp_abt lr_abt + sp_hyp elr_hyp + sp_und lr_und + spsr_fiq spsr_irq spsr_svc spsr_mon spsr_abt spsr_hyp spsr_und ]; + +@endif # defined(VERSION_7) + # Define context bits # WARNING: when adjusting context keep compiler packing in mind # and make sure fields do not span a 32-bit boundary before or @@ -189,6 +204,11 @@ define pcodeop ReverseBitOrder; define pcodeop SendEvent; define pcodeop setEndianState; +define pcodeop UnkBankedRegRead; +define pcodeop UnkBankedSpsrRead; +define pcodeop UnkBankedRegWrite; +define pcodeop UnkBankedSpsrWrite; + # Copies ISAModeSwitch to TMode define pcodeop setISAMode; diff --git a/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc b/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc index 8f801357db9..1f323253054 100644 --- a/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc +++ b/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc @@ -34,6 +34,7 @@ define token instr2 (16) define token instrThumb (16) op4=(4,15) + op5=(5,15) op6=(6,15) op7=(7,15) op8=(8,15) @@ -149,6 +150,12 @@ define token instrThumb (16) sysm37=(3,7) sysm02=(0,2) + mrs_banked_m1=(0,3) + mrs_banked_m=(4,4) + + msr_banked_m1=(8,11) + msr_banked_m=(4,4) + thc0001=(0,1) thc0002=(0,2) @@ -2973,7 +2980,142 @@ define pcodeop setStackMode; # TODO: should we set sp ? } -@endif +@endif # defined(VERSION_7M) + +@if defined(VERSION_7) + +BankedSysmThumb: banked_sysm is op5=0x79f & thc0003 ; thc0404 + [ banked_sysm = (thc0404 << 4) $or thc0003; ] +{ + export *[const]:4 banked_sysm; +} + +BankedSysmThumb: banked_sysm is op5=0x79c ; thc0811 & thc0404 + [ banked_sysm = (thc0404 << 4) $or thc0811; ] +{ + export *[const]:4 banked_sysm; +} + +# MRS/MSR (banked register) +# See https://developer.arm.com/documentation/ddi0597/2024-12/Base-Instructions/MSR--Banked-register---Move-general-purpose-register-to-Banked-or-Special-register- + +# MRS, SPSR = 0, M = 0 +BankedRegThumb: r8_usr is r8_usr & op4=0xf3e & mrs_banked_m1=0b0000 ; mrs_banked_m=0 { export r8_usr; } +BankedRegThumb: r9_usr is r9_usr & op4=0xf3e & mrs_banked_m1=0b0001 ; mrs_banked_m=0 { export r9_usr; } +BankedRegThumb: r10_usr is r10_usr & op4=0xf3e & mrs_banked_m1=0b0010 ; mrs_banked_m=0 { export r10_usr; } +BankedRegThumb: r11_usr is r11_usr & op4=0xf3e & mrs_banked_m1=0b0011 ; mrs_banked_m=0 { export r11_usr; } +BankedRegThumb: r12_usr is r12_usr & op4=0xf3e & mrs_banked_m1=0b0100 ; mrs_banked_m=0 { export r12_usr; } +BankedRegThumb: sp_usr is sp_usr & op4=0xf3e & mrs_banked_m1=0b0101 ; mrs_banked_m=0 { export sp_usr; } +BankedRegThumb: lr_usr is lr_usr & op4=0xf3e & mrs_banked_m1=0b0110 ; mrs_banked_m=0 { export lr_usr; } + +BankedRegThumb: r8_fiq is r8_fiq & op4=0xf3e & mrs_banked_m1=0b1000 ; mrs_banked_m=0 { export r8_fiq; } +BankedRegThumb: r9_fiq is r9_fiq & op4=0xf3e & mrs_banked_m1=0b1001 ; mrs_banked_m=0 { export r9_fiq; } +BankedRegThumb: r10_fiq is r10_fiq & op4=0xf3e & mrs_banked_m1=0b1010 ; mrs_banked_m=0 { export r10_fiq; } +BankedRegThumb: r11_fiq is r11_fiq & op4=0xf3e & mrs_banked_m1=0b1011 ; mrs_banked_m=0 { export r11_fiq; } +BankedRegThumb: r12_fiq is r12_fiq & op4=0xf3e & mrs_banked_m1=0b1100 ; mrs_banked_m=0 { export r12_fiq; } +BankedRegThumb: sp_fiq is sp_fiq & op4=0xf3e & mrs_banked_m1=0b1101 ; mrs_banked_m=0 { export sp_fiq; } +BankedRegThumb: lr_fiq is lr_fiq & op4=0xf3e & mrs_banked_m1=0b1110 ; mrs_banked_m=0 { export lr_fiq; } + +# MSR, SPSR = 0, M = 0 +BankedRegThumb: r8_usr is r8_usr & op4=0xf38 ; msr_banked_m1=0b0000 & msr_banked_m=0 { export r8_usr; } +BankedRegThumb: r9_usr is r9_usr & op4=0xf38 ; msr_banked_m1=0b0001 & msr_banked_m=0 { export r9_usr; } +BankedRegThumb: r10_usr is r10_usr & op4=0xf38 ; msr_banked_m1=0b0010 & msr_banked_m=0 { export r10_usr; } +BankedRegThumb: r11_usr is r11_usr & op4=0xf38 ; msr_banked_m1=0b0011 & msr_banked_m=0 { export r11_usr; } +BankedRegThumb: r12_usr is r12_usr & op4=0xf38 ; msr_banked_m1=0b0100 & msr_banked_m=0 { export r12_usr; } +BankedRegThumb: sp_usr is sp_usr & op4=0xf38 ; msr_banked_m1=0b0101 & msr_banked_m=0 { export sp_usr; } +BankedRegThumb: lr_usr is lr_usr & op4=0xf38 ; msr_banked_m1=0b0110 & msr_banked_m=0 { export lr_usr; } + +BankedRegThumb: r8_fiq is r8_fiq & op4=0xf38 ; msr_banked_m1=0b1000 & msr_banked_m=0 { export r8_fiq; } +BankedRegThumb: r9_fiq is r9_fiq & op4=0xf38 ; msr_banked_m1=0b1001 & msr_banked_m=0 { export r9_fiq; } +BankedRegThumb: r10_fiq is r10_fiq & op4=0xf38 ; msr_banked_m1=0b1010 & msr_banked_m=0 { export r10_fiq; } +BankedRegThumb: r11_fiq is r11_fiq & op4=0xf38 ; msr_banked_m1=0b1011 & msr_banked_m=0 { export r11_fiq; } +BankedRegThumb: r12_fiq is r12_fiq & op4=0xf38 ; msr_banked_m1=0b1100 & msr_banked_m=0 { export r12_fiq; } +BankedRegThumb: sp_fiq is sp_fiq & op4=0xf38 ; msr_banked_m1=0b1101 & msr_banked_m=0 { export sp_fiq; } +BankedRegThumb: lr_fiq is lr_fiq & op4=0xf38 ; msr_banked_m1=0b1110 & msr_banked_m=0 { export lr_fiq; } + +# MRS, SPSR = 0, M = 1 +BankedRegThumb: lr_irq is lr_irq & op4=0xf3e & mrs_banked_m1=0b0000 ; mrs_banked_m=1 { export lr_irq; } +BankedRegThumb: sp_irq is sp_irq & op4=0xf3e & mrs_banked_m1=0b0001 ; mrs_banked_m=1 { export sp_irq; } +BankedRegThumb: lr_svc is lr_svc & op4=0xf3e & mrs_banked_m1=0b0010 ; mrs_banked_m=1 { export lr_svc; } +BankedRegThumb: sp_svc is sp_svc & op4=0xf3e & mrs_banked_m1=0b0011 ; mrs_banked_m=1 { export sp_svc; } +BankedRegThumb: lr_abt is lr_abt & op4=0xf3e & mrs_banked_m1=0b0100 ; mrs_banked_m=1 { export lr_abt; } +BankedRegThumb: sp_abt is sp_abt & op4=0xf3e & mrs_banked_m1=0b0101 ; mrs_banked_m=1 { export sp_abt; } +BankedRegThumb: lr_und is lr_und & op4=0xf3e & mrs_banked_m1=0b0110 ; mrs_banked_m=1 { export lr_und; } +BankedRegThumb: sp_und is sp_und & op4=0xf3e & mrs_banked_m1=0b0111 ; mrs_banked_m=1 { export sp_und; } + +BankedRegThumb: lr_mon is lr_mon & op4=0xf3e & mrs_banked_m1=0b1100 ; mrs_banked_m=1 { export lr_mon; } +BankedRegThumb: sp_mon is sp_mon & op4=0xf3e & mrs_banked_m1=0b1101 ; mrs_banked_m=1 { export sp_mon; } +BankedRegThumb: elr_hyp is elr_hyp & op4=0xf3e & mrs_banked_m1=0b1110 ; mrs_banked_m=1 { export elr_hyp; } +BankedRegThumb: sp_hyp is sp_hyp & op4=0xf3e & mrs_banked_m1=0b1111 ; mrs_banked_m=1 { export sp_hyp; } + +# MSR, SPSR = 0, M = 1 +BankedRegThumb: lr_irq is lr_irq & op4=0xf38 ; msr_banked_m1=0b0000 & msr_banked_m=1 { export lr_irq; } +BankedRegThumb: sp_irq is sp_irq & op4=0xf38 ; msr_banked_m1=0b0001 & msr_banked_m=1 { export sp_irq; } +BankedRegThumb: lr_svc is lr_svc & op4=0xf38 ; msr_banked_m1=0b0010 & msr_banked_m=1 { export lr_svc; } +BankedRegThumb: sp_svc is sp_svc & op4=0xf38 ; msr_banked_m1=0b0011 & msr_banked_m=1 { export sp_svc; } +BankedRegThumb: lr_abt is lr_abt & op4=0xf38 ; msr_banked_m1=0b0100 & msr_banked_m=1 { export lr_abt; } +BankedRegThumb: sp_abt is sp_abt & op4=0xf38 ; msr_banked_m1=0b0101 & msr_banked_m=1 { export sp_abt; } +BankedRegThumb: lr_und is lr_und & op4=0xf38 ; msr_banked_m1=0b0110 & msr_banked_m=1 { export lr_und; } +BankedRegThumb: sp_und is sp_und & op4=0xf38 ; msr_banked_m1=0b0111 & msr_banked_m=1 { export sp_und; } + +BankedRegThumb: lr_mon is lr_mon & op4=0xf38 ; msr_banked_m1=0b1100 & msr_banked_m=1 { export lr_mon; } +BankedRegThumb: sp_mon is sp_mon & op4=0xf38 ; msr_banked_m1=0b1101 & msr_banked_m=1 { export sp_mon; } +BankedRegThumb: elr_hyp is elr_hyp & op4=0xf38 ; msr_banked_m1=0b1110 & msr_banked_m=1 { export elr_hyp; } +BankedRegThumb: sp_hyp is sp_hyp & op4=0xf38 ; msr_banked_m1=0b1111 & msr_banked_m=1 { export sp_hyp; } + +# Fallback: unknown registers +BankedRegThumb: "banked_reg_sysm("^BankedSysmThumb^")" is (op4=0xf3e ; op0) & BankedSysmThumb { tmp:4 = UnkBankedRegRead(BankedSysmThumb:1); export tmp; } +BankedRegThumb: "banked_reg_sysm("^BankedSysmThumb^")" is (op4=0xf38 & thc0404=0 & Rn0003 ; op0) & BankedSysmThumb { tmp:4 = UnkBankedRegWrite(BankedSysmThumb:1, Rn0003); export tmp; } + +# MRS, SPSR = 1 +BankedSpsrThumb: spsr_fiq is spsr_fiq & op4=0xf3f & mrs_banked_m1=0b1110 ; mrs_banked_m=0 { export spsr_fiq; } +BankedSpsrThumb: spsr_irq is spsr_irq & op4=0xf3f & mrs_banked_m1=0b0000 ; mrs_banked_m=1 { export spsr_irq; } +BankedSpsrThumb: spsr_svc is spsr_svc & op4=0xf3f & mrs_banked_m1=0b0010 ; mrs_banked_m=1 { export spsr_svc; } +BankedSpsrThumb: spsr_abt is spsr_abt & op4=0xf3f & mrs_banked_m1=0b0100 ; mrs_banked_m=1 { export spsr_abt; } +BankedSpsrThumb: spsr_und is spsr_und & op4=0xf3f & mrs_banked_m1=0b0110 ; mrs_banked_m=1 { export spsr_und; } +BankedSpsrThumb: spsr_mon is spsr_mon & op4=0xf3f & mrs_banked_m1=0b1100 ; mrs_banked_m=1 { export spsr_mon; } +BankedSpsrThumb: spsr_hyp is spsr_hyp & op4=0xf3f & mrs_banked_m1=0b1110 ; mrs_banked_m=1 { export spsr_hyp; } + +# MSR, SPSR = 1 +BankedSpsrThumb: spsr_fiq is spsr_fiq & op4=0xf39 ; msr_banked_m1=0b1110 & msr_banked_m=0 { export spsr_fiq; } +BankedSpsrThumb: spsr_irq is spsr_irq & op4=0xf39 ; msr_banked_m1=0b0000 & msr_banked_m=1 { export spsr_irq; } +BankedSpsrThumb: spsr_svc is spsr_svc & op4=0xf39 ; msr_banked_m1=0b0010 & msr_banked_m=1 { export spsr_svc; } +BankedSpsrThumb: spsr_abt is spsr_abt & op4=0xf39 ; msr_banked_m1=0b0100 & msr_banked_m=1 { export spsr_abt; } +BankedSpsrThumb: spsr_und is spsr_und & op4=0xf39 ; msr_banked_m1=0b0110 & msr_banked_m=1 { export spsr_und; } +BankedSpsrThumb: spsr_mon is spsr_mon & op4=0xf39 ; msr_banked_m1=0b1100 & msr_banked_m=1 { export spsr_mon; } +BankedSpsrThumb: spsr_hyp is spsr_hyp & op4=0xf39 ; msr_banked_m1=0b1110 & msr_banked_m=1 { export spsr_hyp; } + +# Fallback: unknown registers +BankedSpsrThumb: "banked_spsr_sysm("^BankedSysmThumb^")" is (op4=0xf3f ; op0) & BankedSysmThumb { tmp:4 = UnkBankedSpsrRead(BankedSysmThumb:1); export tmp; } +BankedSpsrThumb: "banked_spsr_sysm("^BankedSysmThumb^")" is (op4=0xf39 & Rn0003 ; op0) & BankedSysmThumb { tmp:4 = UnkBankedSpsrWrite(BankedSysmThumb:1, Rn0003); export tmp; } + + +:mrs^ItCond Rd0811,BankedRegThumb is TMode=1 & ItCond & (op4=0xf3e; op12=0x8 & Rd0811 & thc0507=0x1 & thc0003=0x0) & BankedRegThumb +{ + build ItCond; + Rd0811 = BankedRegThumb; +} + +:mrs^ItCond Rd0811,BankedSpsrThumb is TMode=1 & ItCond & (op4=0xf3f; op12=0x8 & Rd0811 & thc0507=0x1 & thc0003=0x0) & BankedSpsrThumb +{ + build ItCond; + Rd0811 = BankedSpsrThumb; +} + +:msr^ItCond BankedRegThumb,Rn0003 is TMode=1 & ItCond & (op4=0xf38 & Rn0003; op12=0x8 & thc0507=0x1 & thc0003=0x0) & BankedRegThumb +{ + build ItCond; + BankedRegThumb = Rn0003; +} + +:msr^ItCond BankedSpsrThumb,Rn0003 is TMode=1 & ItCond & (op4=0xf39 & Rn0003; op12=0x8 & thc0507=0x1 & thc0003=0x0) & BankedSpsrThumb +{ + build ItCond; + BankedSpsrThumb = Rn0003; +} + + +@endif # defined(VERSION_7) thpsrmask: is th_psrmask=0 { export 0:4; } thpsrmask: "_c" is th_psrmask=1 { export 0xff:4; } diff --git a/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc b/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc index ddd0fa648d4..b4944552cce 100644 --- a/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc +++ b/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc @@ -88,6 +88,8 @@ define token instrArm (32) x=(5,5) r=(5,5) y=(6,6) + banked_m1=(16,19) + banked_m=(8,8) # Advanced SIMD and VFP instruction fields D22=(22,22) @@ -4142,6 +4144,66 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate Rd = coprocessor_movefromRt(t_cpn,t_op1,t_opc2,CRn,CRm); } +BankedSysmArm: banked_sysm is banked_m & banked_m1 + [ banked_sysm = (banked_m << 4) $or banked_m1; ] +{ + export *[const]:4 banked_sysm; +} + +# MRS/MSR (banked register) +# See https://developer.arm.com/documentation/ddi0597/2024-12/Base-Instructions/MSR--Banked-register---Move-general-purpose-register-to-Banked-or-Special-register- +# +# M1/M are in the same places for MRS/MSR instructions, so no need to +# distinguish between them + +# SPSR = 0, M = 0 +BankedRegArm: r8_usr is r8_usr & banked_m=0 & banked_m1=0b0000 { export r8_usr; } +BankedRegArm: r9_usr is r9_usr & banked_m=0 & banked_m1=0b0001 { export r9_usr; } +BankedRegArm: r10_usr is r10_usr & banked_m=0 & banked_m1=0b0010 { export r10_usr; } +BankedRegArm: r11_usr is r11_usr & banked_m=0 & banked_m1=0b0011 { export r11_usr; } +BankedRegArm: r12_usr is r12_usr & banked_m=0 & banked_m1=0b0100 { export r12_usr; } +BankedRegArm: sp_usr is sp_usr & banked_m=0 & banked_m1=0b0101 { export sp_usr; } +BankedRegArm: lr_usr is lr_usr & banked_m=0 & banked_m1=0b0110 { export lr_usr; } + +BankedRegArm: r8_fiq is r8_fiq & banked_m=0 & banked_m1=0b1000 { export r8_fiq; } +BankedRegArm: r9_fiq is r9_fiq & banked_m=0 & banked_m1=0b1001 { export r9_fiq; } +BankedRegArm: r10_fiq is r10_fiq & banked_m=0 & banked_m1=0b1010 { export r10_fiq; } +BankedRegArm: r11_fiq is r11_fiq & banked_m=0 & banked_m1=0b1011 { export r11_fiq; } +BankedRegArm: r12_fiq is r12_fiq & banked_m=0 & banked_m1=0b1100 { export r12_fiq; } +BankedRegArm: sp_fiq is sp_fiq & banked_m=0 & banked_m1=0b1101 { export sp_fiq; } +BankedRegArm: lr_fiq is lr_fiq & banked_m=0 & banked_m1=0b1110 { export lr_fiq; } + +# SPSR = 0, M = 0 +BankedRegArm: lr_irq is lr_irq & banked_m=1 & banked_m1=0b0000 { export lr_irq; } +BankedRegArm: sp_irq is sp_irq & banked_m=1 & banked_m1=0b0001 { export sp_irq; } +BankedRegArm: lr_svc is lr_svc & banked_m=1 & banked_m1=0b0010 { export lr_svc; } +BankedRegArm: sp_svc is sp_svc & banked_m=1 & banked_m1=0b0011 { export sp_svc; } +BankedRegArm: lr_abt is lr_abt & banked_m=1 & banked_m1=0b0100 { export lr_abt; } +BankedRegArm: sp_abt is sp_abt & banked_m=1 & banked_m1=0b0101 { export sp_abt; } +BankedRegArm: lr_und is lr_und & banked_m=1 & banked_m1=0b0110 { export lr_und; } +BankedRegArm: sp_und is sp_und & banked_m=1 & banked_m1=0b0111 { export sp_und; } + +BankedRegArm: lr_mon is lr_mon & banked_m=1 & banked_m1=0b1100 { export lr_mon; } +BankedRegArm: sp_mon is sp_mon & banked_m=1 & banked_m1=0b1101 { export sp_mon; } +BankedRegArm: elr_hyp is elr_hyp & banked_m=1 & banked_m1=0b1110 { export elr_hyp; } +BankedRegArm: sp_hyp is sp_hyp & banked_m=1 & banked_m1=0b1111 { export sp_hyp; } + +# Fallback: unknown registers +BankedRegArm: "banked_reg_sysm("^BankedSysmArm^")" is c2027=0x10 & BankedSysmArm { tmp:4 = UnkBankedRegRead(BankedSysmArm:1); export tmp; } +BankedRegArm: "banked_reg_sysm("^BankedSysmArm^")" is c2027=0x12 & RnLo & BankedSysmArm { tmp:4 = UnkBankedRegWrite(BankedSysmArm:1, RnLo); export tmp; } + +# MRS/MSR (banked register), spsr=1 +BankedSpsrArm: spsr_fiq is spsr_fiq & banked_m=0 & banked_m1=0b1110 { export spsr_fiq; } +BankedSpsrArm: spsr_irq is spsr_irq & banked_m=1 & banked_m1=0b0000 { export spsr_irq; } +BankedSpsrArm: spsr_svc is spsr_svc & banked_m=1 & banked_m1=0b0010 { export spsr_svc; } +BankedSpsrArm: spsr_abt is spsr_abt & banked_m=1 & banked_m1=0b0100 { export spsr_abt; } +BankedSpsrArm: spsr_und is spsr_und & banked_m=1 & banked_m1=0b0110 { export spsr_und; } +BankedSpsrArm: spsr_mon is spsr_mon & banked_m=1 & banked_m1=0b1100 { export spsr_mon; } +BankedSpsrArm: spsr_hyp is spsr_hyp & banked_m=1 & banked_m1=0b1110 { export spsr_hyp; } + +# Fallback: unknown registers +BankedSpsrArm: "banked_spsr_sysm("^BankedSysmArm^")" is c2027=0x14 & BankedSysmArm { tmp:4 = UnkBankedSpsrRead(BankedSysmArm:1); export tmp; } +BankedSpsrArm: "banked_spsr_sysm("^BankedSysmArm^")" is c2027=0x16 & RnLo & BankedSysmArm { tmp:4 = UnkBankedSpsrWrite(BankedSysmArm:1, RnLo); export tmp; } :mrs^COND Rd,cpsr is $(AMODE) & ARMcond=1 & COND & c2027=16 & c1619=15 & Rd & offset_12=0 & cpsr { @@ -4156,6 +4218,18 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate Rd = spsr; } +:mrs^COND Rd,BankedRegArm is $(AMODE) & ARMcond=1 & COND & c2027=0x10 & Rd & c0911=1 & c0007=0 & BankedRegArm +{ + build COND; + Rd = BankedRegArm; +} + +:mrs^COND Rd,BankedSpsrArm is $(AMODE) & ARMcond=1 & COND & c2027=0x14 & Rd & c0911=1 & c0007=0 & BankedSpsrArm +{ + build COND; + Rd = BankedSpsrArm; +} + :msr^COND cpsrmask,shift1 is $(AMODE) & ARMcond=1 & COND & c2027=50 & cpsrmask & c1215=15 & c2627=0 & shift1 { build COND; @@ -4193,6 +4267,18 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate spsr = (spsr& ~spsrmask) | (rm & spsrmask); } +:msr^COND BankedRegArm,RnLo is $(AMODE) & ARMcond=1 & COND & c2027=0x12 & c0915=0x79 & c0407=0 & RnLo & BankedRegArm +{ + build COND; + BankedRegArm = RnLo; +} + +:msr^COND BankedSpsrArm,RnLo is $(AMODE) & ARMcond=1 & COND & c2027=0x16 & c0915=0x79 & c0407=0 & RnLo & BankedSpsrArm +{ + build COND; + BankedSpsrArm = RnLo; +} + :mul^COND^SBIT_ZN rn,rm,rs is $(AMODE) & ARMcond=1 & COND & c2527=0 & c2124=0 & SBIT_ZN & rn & c1215=0 & rs & c0407=9 & rm { build COND; diff --git a/Ghidra/Processors/ARM/data/languages/ARMt.pspec b/Ghidra/Processors/ARM/data/languages/ARMt.pspec index ff62a392868..11fb4acf812 100644 --- a/Ghidra/Processors/ARM/data/languages/ARMt.pspec +++ b/Ghidra/Processors/ARM/data/languages/ARMt.pspec @@ -41,6 +41,10 @@ + + + + diff --git a/Ghidra/Processors/ARM/data/languages/ARMtTHUMB.pspec b/Ghidra/Processors/ARM/data/languages/ARMtTHUMB.pspec index 58b125c9080..663c32f6dd6 100644 --- a/Ghidra/Processors/ARM/data/languages/ARMtTHUMB.pspec +++ b/Ghidra/Processors/ARM/data/languages/ARMtTHUMB.pspec @@ -42,6 +42,10 @@ + + + +