| Trees | Indices | Help |
|---|
|
|
1
2 import envi.bits as e_bits
3 from envi.bits import binary
4 import envi.bintree as e_btree
5
6 import envi.archs.arm.disasm as arm_dis
7 import envi.archs.arm.armdisasm as arm_armdis
8 import envi.archs.arm.regs as arm_reg
9
10 thumb_32 = [
11 binary('11101'),
12 binary('11110'),
13 binary('11111'),
14 ]
15
16 O_REG = 0
17 O_IMM = 1
18
19 -def shmaskval(value, shval, mask): #FIXME: unnecessary to make this another fn call. will be called a bajillion times.
20 return (value >> shval) & mask
21
32
33 imm5_rm_rd = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7), (O_IMM, 6, 0x1f))
34 rm_rn_rd = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7), (O_REG, 6, 0x7))
35 imm3_rn_rd = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7), (O_IMM, 6, 0x7))
36 imm8_rd = simpleops((O_REG, 8, 0x7), (O_IMM, 0, 0xff))
37 rm_rd = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7))
38 rn_rdm = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7))
39 rm_rdn = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7))
40 rm_rd_imm0 = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7), (O_IMM, 0, 0))
41 rm4_shift3 = simpleops((O_REG, 3, 0xf))
42 rm_rn_rt = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7), (O_REG, 6, 0x7))
43 imm8 = simpleops((O_IMM, 8, 0xff))
44 imm11 = simpleops((O_IMM, 11, 0x7ff))
45
46 sh4_imm1 = simpleops((O_IMM, 3, 0x1))
47
49 # 0 1 0 0 0 1 0 0 DN(1) Rm(4) Rdn(3)
50 rdbit = shmaskval(value, 4, 0x8)
51 rd = shmaskval(value, 0, 0x7) + rdbit
52 rm = shmaskval(value, 3, 0xf)
53 return ArmRegOper(rd),ArmRegOper(rn)
54
56 rt = shmask(value, 0, 0x7) # target
57 rn = shmask(value, 3, 0x7) # base
58 rm = shmask(value, 6, 0x7) # offset
59 oper0 = arm_dis.ArmRegOper(rt)
60 oper1 = arm_dis.ArmRegOffsetOper(rn, rm, va)
61 return oper0,oper1
62
64 imm = shmask(value, 6, 0x1f)
65 rn = shmask(value, 3, 0x7)
66 rt = shmask(value, 0, 0x7)
67 oper0 = arm_dis.ArmRegOper(rt)
68 oper1 = arm_dis.ArmImmOffsetOper(rn, imm, va)
69 return oper0,oper1
70
72 rd = shmask(value, 8, 0x7)
73 imm = shmask(value, 0, 0xff)
74 oper0 = arm_dis.ArmRegOper(rd)
75 # pre-compute PC relative addr
76 oper1 = arm_dis.ArmImmOffsetOper(REG_SP, imm)
77 return oper0,oper1
78
80 rd = shmask(value, 8, 0x7)
81 imm = shmask(value, 0, 0xff)
82 oper0 = arm_dis.ArmRegOper(rd)
83 # pre-compute PC relative addr
84 oper1 = arm_dis.ArmImmOper(va+imm)
85 return oper0,oper1
86
88 rt = shmask(value, 8, 0x7)
89 imm = shmask(value, 0, 0xff)
90 oper0 = arm_dis.ArmRegOper(rt)
91 oper1 = arm_dis.ArmImmOffsetOper() # FIXME offset from PC
92 return oper0,oper1
93
95 rd = shmask(value, 8, 0x7)
96 reg_list = value & 0xff
97 oper0 = arm_dis.ArmRegOper(rd)
98 oper1 = arm_dis.ArmRegListOper(reg_list)
99 flags = 1<<11 # W flag indicating that write back should occur (marked by "!")
100 return oper0,oper1
101
103 imm = shmask(value, 0, 0x7f)
104 o0 = arm_dis.ArmRegOper(arm_reg.REG_SP)
105 o1 = arm_dis.ArmRegOper(arm_reg.REG_SP)
106 o2 = arm_dis.ArmImmOper(imm*4)
107 return o0,o1,o2
108
110 rm = shmask(value, 8, 0x7)
111 reglist = value & 0xff
112 oper0 = arm_dis.ArmRegOper(rm)
113 oper1 = arm_dis.ArmReglistOper(reglist)
114 return oper0,oper1
115
116
117 # opinfo is:
118 # ( <mnem>, <operdef>, <flags> )
119 # operdef is:
120 # ( (otype, oshift, omask), ...)
121 thumb_table = [
122 ('00000', ('lsl', imm5_rm_rd, 0)), # LSL<c> <Rd>,<Rm>,#<imm5>
123 ('00001', ('lsr', imm5_rm_rd, 0)), # LSR<c> <Rd>,<Rm>,#<imm>
124 ('00010', ('asr', imm5_rm_rd, 0)), # ASR<c> <Rd>,<Rm>,#<imm>
125 ('0001100', ('add', rm_rn_rd, 0)), # ADD<c> <Rd>,<Rn>,<Rm>
126 ('0001101', ('sub', rm_rn_rd, 0)), # SUB<c> <Rd>,<Rn>,<Rm>
127 ('0001110', ('add', imm3_rn_rd, 0)), # ADD<c> <Rd>,<Rn>,#<imm3>
128 ('0001111', ('sub', imm3_rn_rd, 0)), # SUB<c> <Rd>,<Rn>,#<imm3>
129 ('00100', ('mov', imm8_rd, 0)), # MOV<c> <Rd>,#<imm8>
130 ('00101', ('cmp', imm8_rd, 0)), # CMP<c> <Rn>,#<imm8>
131 ('00110', ('add', imm8_rd, 0)), # ADD<c> <Rdn>,#<imm8>
132 ('00111', ('sub', imm8_rd, 0)), # SUB<c> <Rdn>,#<imm8>
133 # Data processing instructions
134 ('0100000000', ('and', rm_rdn, 0)), # AND<c> <Rdn>,<Rm>
135 ('0100000001', ('eor', rm_rdn, 0)), # EOR<c> <Rdn>,<Rm>
136 ('0100000010', ('lsl', rm_rdn, 0)), # LSL<c> <Rdn>,<Rm>
137 ('0100000011', ('lsr', rm_rdn, 0)), # LSR<c> <Rdn>,<Rm>
138 ('0100000100', ('asr', rm_rdn, 0)), # ASR<c> <Rdn>,<Rm>
139 ('0100000101', ('adc', rm_rdn, 0)), # ADC<c> <Rdn>,<Rm>
140 ('0100000110', ('sbc', rm_rdn, 0)), # SBC<c> <Rdn>,<Rm>
141 ('0100000111', ('ror', rm_rdn, 0)), # ROR<c> <Rdn>,<Rm>
142 ('0100001000', ('tst', rm_rd, 0)), # TST<c> <Rn>,<Rm>
143 ('0100001001', ('rsb', rm_rd_imm0, 0)), # RSB<c> <Rd>,<Rn>,#0
144 ('0100001010', ('cmp', rm_rd, 0)), # CMP<c> <Rn>,<Rm>
145 ('0100001011', ('cmn', rm_rd, 0)), # CMN<c> <Rn>,<Rm>
146 ('0100001100', ('orr', rm_rdn, 0)), # ORR<c> <Rdn>,<Rm>
147 ('0100001101', ('mul', rn_rdm, 0)), # MUL<c> <Rdm>,<Rn>,<Rdm>
148 ('0100001110', ('bic', rm_rdn, 0)), # BIC<c> <Rdn>,<Rm>
149 ('0100001111', ('mvn', rm_rd, 0)), # MVN<c> <Rd>,<Rm>
150 # Special data instructions and branch and exchange
151 ('0100010000', ('add', d1_rm4_rd3, 0)), # ADD<c> <Rdn>,<Rm>
152 ('0100010001', ('add', d1_rm4_rd3, 0)), # ADD<c> <Rdn>,<Rm>
153 ('010001001', ('add', d1_rm4_rd3, 0)), # ADD<c> <Rdn>,<Rm>
154 ('0100010101', ('cmp', d1_rm4_rd3, 0)), # CMP<c> <Rn>,<Rm>
155 ('010001011', ('cmp', d1_rm4_rd3, 0)), # CMP<c> <Rn>,<Rm>
156 ('0100011000', ('mov', d1_rm4_rd3, 0)), # MOV<c> <Rd>,<Rm>
157 ('0100011001', ('mov', d1_rm4_rd3, 0)), # MOV<c> <Rd>,<Rm>
158 ('0100011010', ('mov', d1_rm4_rd3, 0)), # MOV<c> <Rd>,<Rm>
159 ('010001110', ('bx', rm4_shift3, 0)), # BX<c> <Rm>
160 ('010001111', ('blx', rm4_shift3, 0)), # BLX<c> <Rm>
161 # Load from Literal Pool
162 ('01001', ('ldr', rt_pc_imm8, 0)), # LDR<c> <Rt>,<label>
163 # Load/Stor single data item
164 ('0101000', ('str', rm_rn_rt, 0)), # STR<c> <Rt>,[<Rn>,<Rm>]
165 ('0101001', ('strh', rm_rn_rt, 0)), # STRH<c> <Rt>,[<Rn>,<Rm>]
166 ('0101010', ('strb', rm_rn_rt, 0)), # STRB<c> <Rt>,[<Rn>,<Rm>]
167 ('0101011', ('ldrsb', rm_rn_rt, 0)), # LDRSB<c> <Rt>,[<Rn>,<Rm>]
168 ('0101100', ('ldr', rm_rn_rt, 0)), # LDR<c> <Rt>,[<Rn>,<Rm>]
169 ('0101101', ('ldrh', rm_rn_rt, 0)), # LDRH<c> <Rt>,[<Rn>,<Rm>]
170 ('0101110', ('ldrb', rm_rn_rt, 0)), # LDRB<c> <Rt>,[<Rn>,<Rm>]
171 ('0101111', ('ldrsh', rm_rn_rt, 0)), # LDRSH<c> <Rt>,[<Rn>,<Rm>]
172 ('01100', ('str', imm5_rn_rt, 0)), # STR<c> <Rt>, [<Rn>{,#<imm5>}]
173 ('01101', ('ldr', imm5_rn_rt, 0)), # LDR<c> <Rt>, [<Rn>{,#<imm5>}]
174 ('01110', ('strb', imm5_rn_rt, 0)), # STRB<c> <Rt>,[<Rn>,#<imm5>]
175 ('01111', ('ldrb', imm5_rn_rt, 0)), # LDRB<c> <Rt>,[<Rn>{,#<imm5>}]
176 ('10000', ('strh', imm5_rn_rt, 0)), # STRH<c> <Rt>,[<Rn>{,#<imm>}]
177 ('10001', ('ldrh', imm5_rn_rt, 0)), # LDRH<c> <Rt>,[<Rn>{,#<imm>}]
178 ('10010', ('str', imm5_rn_rt, 0)), # STR<c> <Rt>, [<Rn>{,#<imm>}]
179 ('10011', ('ldr', imm5_rn_rt, 0)), # LDR<c> <Rt>, [<Rn>{,#<imm>}]
180 # Generate PC relative address
181 ('10100', ('add', rd_pc_imm8, 0)), # ADD<c> <Rd>,<label>
182 # Generate SP relative address
183 ('10101', ('add', rd_sp_imm8, 0)), # ADD<c> <Rd>,SP,#<imm>
184 # Miscellaneous instructions
185 ('10110110010', ('setend', sh4_imm1, 0)), # SETEND <endian_specifier>
186 ('10110110011', ('cps', simpleops(),0)), # CPS<effect> <iflags> FIXME
187 ('1011101000', ('rev', rn_rdm, 0)), # REV Rd, Rn
188 ('1011101001', ('rev16', rn_rdm, 0)), # REV16 Rd, Rn
189 ('1011101011', ('revsh', rn_rdm, 0)), # REVSH Rd, Rn
190 ('101100000', ('add', sp_sp_imm7, 0)), # ADD<c> SP,SP,#<imm>
191 ('101100001', ('sub', sp_sp_imm7, 0)), # SUB<c> SP,SP,#<imm>
192 ('10111110', ('bkpt', imm8, 0)), # BKPT <blahblah>
193 # Load / Store Multiple
194 ('11000', ('stmia', rm_reglist, 0x800)), # LDMIA Rd!, reg_list
195 ('11001', ('ldmia', rm_reglist, 0x800)), # STMIA Rd!, reg_list
196 # Conditional Branches
197 ('11010000', ('b', imm8, 0)),
198 ('11010001', ('bn', imm8, 0)),
199 ('11010010', ('bz', imm8, 0)),
200 ('11010011', ('bnz', imm8, 0)),
201 ('11010100', ('bc', imm8, 0)),
202 ('11010101', ('bnc', imm8, 0)),
203 ('11010100', ('bzc', imm8, 0)),
204 ('11010111', ('bnzc', imm8, 0)),
205 ('11011000', ('bv', imm8, 0)),
206 ('11011001', ('bnv', imm8, 0)),
207 ('11011010', ('bzv', imm8, 0)),
208 ('11011011', ('bnzv', imm8, 0)),
209 ('11011100', ('bcv', imm8, 0)),
210 ('11011101', ('bncv', imm8, 0)),
211 ('11011110', ('bzcv', imm8, 0)),
212 ('11011111', ('bnzcv', imm8, 0)),
213 # Software Interrupt
214 ('11011111', ('swi', imm8, 0)), # SWI <blahblah>
215 ('11100', ('b', imm11, 0)), # B <addr11>
216 ('11101', ('blx', imm11, 0)), # BLX suffix <addr11> -- SEE p542 of 14218.pdf manual for how this if gonna fuck with emulation.
217 ('11110', ('bl', imm11, 0)), # BL/BLX prefix <addr11> -- SEE p542 of 14218.pdf manual for how this if gonna fuck with emulation.
218 ('11111', ('blx', imm11, 0)), # BL suffix <addr11> -- SEE p542 of 14218.pdf manual for how this if gonna fuck with emulation.
219 ]
220
221 ttree = e_btree.BinaryTree()
222 for binstr, opinfo in thumb_table:
223 ttree.addBinstr(binstr, opinfo)
224
225 thumb32mask = binary('11111')
226 thumb32min = binary('11100')
227
229 '''
230 Take a 16 bit integer (opcode) value and determine
231 if it is really the first 16 bits of a 32 bit
232 instruction.
233 '''
234 bval = val >> 11
235 return (bval & thumb32mask) > thumb32min
236
237
240
241 #class ArmThumbDisasm(arm_armdis.ArmDisasmChild):
242
243 #def disasm(self, bytes, offset, va, trackMode=True):
244 #val = struct.unpack("<L", bytes[offset:offset+2])
245 #mnem, opermkr, flags = ttree.getInstr(val)
246 #olist = opermkr(va, val)
247
248 #op = ThumbOpcode(va, opcode, mnem, 0xe, 2, olist, flags)
249 #return op
250 #raise Exception("ummm. you could try Implementing disasm first... duh.")
251
| Trees | Indices | Help |
|---|
| Generated by Epydoc 3.0.1 on Fri Nov 16 18:22:20 2012 | http://epydoc.sourceforge.net |