HELLO·Android
系统源代码
IT资讯
技术文章
我的收藏
注册
登录
-
我收藏的文章
创建代码块
我的代码块
我的账号
Pie
|
9.0.0_r8
下载
查看原文件
收藏
根目录
device
linaro
bootloader
edk2
ArmPkg
Library
ArmDisassemblerLib
ThumbDisassembler.c
/** @file Thumb Dissassembler. Still a work in progress. Wrong output is a bug, so please fix it. Hex output means there is not yet an entry or a decode bug. gOpThumb[] are Thumb 16-bit, and gOpThumb2[] work on the 32-bit 16-bit stream of Thumb2 instruction. Then there are big case statements to print everything out. If you are adding instructions try to reuse existing case entries if possible. Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include
#include
#include
#include
extern CHAR8 *gCondition[]; extern CHAR8 *gReg[]; // Thumb address modes #define LOAD_STORE_FORMAT1 1 #define LOAD_STORE_FORMAT1_H 101 #define LOAD_STORE_FORMAT1_B 111 #define LOAD_STORE_FORMAT2 2 #define LOAD_STORE_FORMAT3 3 #define LOAD_STORE_FORMAT4 4 #define LOAD_STORE_MULTIPLE_FORMAT1 5 #define PUSH_FORMAT 6 #define POP_FORMAT 106 #define IMMED_8 7 #define CONDITIONAL_BRANCH 8 #define UNCONDITIONAL_BRANCH 9 #define UNCONDITIONAL_BRANCH_SHORT 109 #define BRANCH_EXCHANGE 10 #define DATA_FORMAT1 11 #define DATA_FORMAT2 12 #define DATA_FORMAT3 13 #define DATA_FORMAT4 14 #define DATA_FORMAT5 15 #define DATA_FORMAT6_SP 16 #define DATA_FORMAT6_PC 116 #define DATA_FORMAT7 17 #define DATA_FORMAT8 19 #define CPS_FORMAT 20 #define ENDIAN_FORMAT 21 #define DATA_CBZ 22 #define ADR_FORMAT 23 #define IT_BLOCK 24 // Thumb2 address modes #define B_T3 200 #define B_T4 201 #define BL_T2 202 #define POP_T2 203 #define POP_T3 204 #define STM_FORMAT 205 #define LDM_REG_IMM12_SIGNED 206 #define LDM_REG_IMM12_LSL 207 #define LDM_REG_IMM8 208 #define LDM_REG_IMM12 209 #define LDM_REG_INDIRECT_LSL 210 #define LDM_REG_IMM8_SIGNED 211 #define LDRD_REG_IMM8 212 #define LDREXB 213 #define LDREXD 214 #define SRS_FORMAT 215 #define RFE_FORMAT 216 #define LDRD_REG_IMM8_SIGNED 217 #define ADD_IMM12 218 #define ADD_IMM5 219 #define ADR_THUMB2 220 #define CMN_THUMB2 221 #define ASR_IMM5 222 #define ASR_3REG 223 #define BFC_THUMB2 224 #define CDP_THUMB2 225 #define THUMB2_NO_ARGS 226 #define THUMB2_2REGS 227 #define ADD_IMM5_2REG 228 #define CPD_THUMB2 229 #define THUMB2_4REGS 230 #define ADD_IMM12_1REG 231 #define THUMB2_IMM16 232 #define MRC_THUMB2 233 #define MRRC_THUMB2 234 #define THUMB2_MRS 235 #define THUMB2_MSR 236 typedef struct { CHAR8 *Start; UINT32 OpCode; UINT32 Mask; UINT32 AddressMode; } THUMB_INSTRUCTIONS; THUMB_INSTRUCTIONS gOpThumb[] = { // Thumb 16-bit instrucitons // Op Mask Format { "ADC" , 0x4140, 0xffc0, DATA_FORMAT5 }, // ADC
,
{ "ADR", 0xa000, 0xf800, ADR_FORMAT }, // ADR
,
{ "ADD" , 0x1c00, 0xfe00, DATA_FORMAT2 }, { "ADD" , 0x3000, 0xf800, DATA_FORMAT3 }, { "ADD" , 0x1800, 0xfe00, DATA_FORMAT1 }, { "ADD" , 0x4400, 0xff00, DATA_FORMAT8 }, // A8.6.9 { "ADD" , 0xa000, 0xf100, DATA_FORMAT6_PC }, { "ADD" , 0xa800, 0xf800, DATA_FORMAT6_SP }, { "ADD" , 0xb000, 0xff80, DATA_FORMAT7 }, { "AND" , 0x4000, 0xffc0, DATA_FORMAT5 }, { "ASR" , 0x1000, 0xf800, DATA_FORMAT4 }, { "ASR" , 0x4100, 0xffc0, DATA_FORMAT5 }, { "B" , 0xd000, 0xf000, CONDITIONAL_BRANCH }, { "B" , 0xe000, 0xf800, UNCONDITIONAL_BRANCH_SHORT }, { "BLX" , 0x4780, 0xff80, BRANCH_EXCHANGE }, { "BX" , 0x4700, 0xff87, BRANCH_EXCHANGE }, { "BIC" , 0x4380, 0xffc0, DATA_FORMAT5 }, { "BKPT", 0xdf00, 0xff00, IMMED_8 }, { "CBZ", 0xb100, 0xfd00, DATA_CBZ }, { "CBNZ", 0xb900, 0xfd00, DATA_CBZ }, { "CMN" , 0x42c0, 0xffc0, DATA_FORMAT5 }, { "CMP" , 0x2800, 0xf800, DATA_FORMAT3 }, { "CMP" , 0x4280, 0xffc0, DATA_FORMAT5 }, { "CMP" , 0x4500, 0xff00, DATA_FORMAT8 }, { "CPS" , 0xb660, 0xffe8, CPS_FORMAT }, { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 }, { "EOR" , 0x4040, 0xffc0, DATA_FORMAT5 }, { "LDMIA" , 0xc800, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 }, { "LDR" , 0x6800, 0xf800, LOAD_STORE_FORMAT1 }, // LDR
, [
{,#
}] { "LDR" , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 }, // STR
, [
,
] { "LDR" , 0x4800, 0xf800, LOAD_STORE_FORMAT3 }, { "LDR" , 0x9800, 0xf800, LOAD_STORE_FORMAT4 }, // LDR
, [SP, #
] { "LDRB" , 0x7800, 0xf800, LOAD_STORE_FORMAT1_B }, { "LDRB" , 0x5c00, 0xfe00, LOAD_STORE_FORMAT2 }, // STR
, [
,
] { "LDRH" , 0x8800, 0xf800, LOAD_STORE_FORMAT1_H }, { "LDRH" , 0x7a00, 0xfe00, LOAD_STORE_FORMAT2 }, { "LDRSB" , 0x5600, 0xfe00, LOAD_STORE_FORMAT2 }, // STR
, [
,
] { "LDRSH" , 0x5e00, 0xfe00, LOAD_STORE_FORMAT2 }, { "MOVS", 0x0000, 0xffc0, DATA_FORMAT5 }, // LSL with imm5 == 0 is a MOVS, so this must go before LSL { "LSL" , 0x0000, 0xf800, DATA_FORMAT4 }, { "LSL" , 0x4080, 0xffc0, DATA_FORMAT5 }, { "LSR" , 0x0001, 0xf800, DATA_FORMAT4 }, { "LSR" , 0x40c0, 0xffc0, DATA_FORMAT5 }, { "LSRS", 0x0800, 0xf800, DATA_FORMAT4 }, // LSRS
,
, #
{ "MOVS", 0x2000, 0xf800, DATA_FORMAT3 }, { "MOV" , 0x1c00, 0xffc0, DATA_FORMAT3 }, { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 }, { "MUL" , 0x4340, 0xffc0, DATA_FORMAT5 }, { "MVN" , 0x41c0, 0xffc0, DATA_FORMAT5 }, { "NEG" , 0x4240, 0xffc0, DATA_FORMAT5 }, { "ORR" , 0x4300, 0xffc0, DATA_FORMAT5 }, { "POP" , 0xbc00, 0xfe00, POP_FORMAT }, { "PUSH", 0xb400, 0xfe00, PUSH_FORMAT }, { "REV" , 0xba00, 0xffc0, DATA_FORMAT5 }, { "REV16" , 0xba40, 0xffc0, DATA_FORMAT5 }, { "REVSH" , 0xbac0, 0xffc0, DATA_FORMAT5 }, { "ROR" , 0x41c0, 0xffc0, DATA_FORMAT5 }, { "SBC" , 0x4180, 0xffc0, DATA_FORMAT5 }, { "SETEND" , 0xb650, 0xfff0, ENDIAN_FORMAT }, { "STMIA" , 0xc000, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 }, { "STR" , 0x6000, 0xf800, LOAD_STORE_FORMAT1 }, // STR
, [
{,#
}] { "STR" , 0x5000, 0xfe00, LOAD_STORE_FORMAT2 }, // STR
, [
,
] { "STR" , 0x9000, 0xf800, LOAD_STORE_FORMAT4 }, // STR
, [SP, #
] { "STRB" , 0x7000, 0xf800, LOAD_STORE_FORMAT1_B }, // STRB
, [
, #
] { "STRB" , 0x5400, 0xfe00, LOAD_STORE_FORMAT2 }, // STRB
, [
,
] { "STRH" , 0x8000, 0xf800, LOAD_STORE_FORMAT1_H }, // STRH
, [
{,#
}] { "STRH" , 0x5200, 0xfe00, LOAD_STORE_FORMAT2 }, // STRH
, [
,
] { "SUB" , 0x1e00, 0xfe00, DATA_FORMAT2 }, { "SUB" , 0x3800, 0xf800, DATA_FORMAT3 }, { "SUB" , 0x1a00, 0xfe00, DATA_FORMAT1 }, { "SUB" , 0xb080, 0xff80, DATA_FORMAT7 }, { "SBC" , 0x4180, 0xffc0, DATA_FORMAT5 }, { "SWI" , 0xdf00, 0xff00, IMMED_8 }, { "SXTB", 0xb240, 0xffc0, DATA_FORMAT5 }, { "SXTH", 0xb200, 0xffc0, DATA_FORMAT5 }, { "TST" , 0x4200, 0xffc0, DATA_FORMAT5 }, { "UXTB", 0xb2c0, 0xffc0, DATA_FORMAT5 }, { "UXTH", 0xb280, 0xffc0, DATA_FORMAT5 }, { "IT", 0xbf00, 0xff00, IT_BLOCK } }; THUMB_INSTRUCTIONS gOpThumb2[] = { //Instruct OpCode OpCode Mask Addressig Mode { "ADR", 0xf2af0000, 0xfbff8000, ADR_THUMB2 }, // ADDR
,
;Needs to go before ADDW { "CMN", 0xf1100f00, 0xfff08f00, CMN_THUMB2 }, // CMN
, #
;Needs to go before ADD { "CMN", 0xeb100f00, 0xfff08f00, ADD_IMM5_2REG }, // CMN
,
{,
#
} { "CMP", 0xf1a00f00, 0xfff08f00, CMN_THUMB2 }, // CMP
, #
{ "TEQ", 0xf0900f00, 0xfff08f00, CMN_THUMB2 }, // CMP
, #
{ "TEQ", 0xea900f00, 0xfff08f00, ADD_IMM5_2REG }, // CMN
,
{,
#
} { "TST", 0xf0100f00, 0xfff08f00, CMN_THUMB2 }, // CMP
, #
{ "TST", 0xea100f00, 0xfff08f00, ADD_IMM5_2REG }, // TST
,
{,
#
} { "MOV", 0xf04f0000, 0xfbef8000, ADD_IMM12_1REG }, // MOV
, #
{ "MOVW", 0xf2400000, 0xfbe08000, THUMB2_IMM16 }, // MOVW
, #
{ "MOVT", 0xf2c00000, 0xfbe08000, THUMB2_IMM16 }, // MOVT
, #
{ "ADC", 0xf1400000, 0xfbe08000, ADD_IMM12 }, // ADC{S}
,
, #
{ "ADC", 0xeb400000, 0xffe08000, ADD_IMM5 }, // ADC{S}
,
,
{,
#
} { "ADD", 0xf1000000, 0xfbe08000, ADD_IMM12 }, // ADD{S}
,
, #
{ "ADD", 0xeb000000, 0xffe08000, ADD_IMM5 }, // ADD{S}
,
,
{,
#
} { "ADDW", 0xf2000000, 0xfbe08000, ADD_IMM12 }, // ADDW{S}
,
, #
{ "AND", 0xf0000000, 0xfbe08000, ADD_IMM12 }, // AND{S}
,
, #
{ "AND", 0xea000000, 0xffe08000, ADD_IMM5 }, // AND{S}
,
,
{,
#
} { "BIC", 0xf0200000, 0xfbe08000, ADD_IMM12 }, // BIC{S}
,
, #
{ "BIC", 0xea200000, 0xffe08000, ADD_IMM5 }, // BIC{S}
,
,
{,
#
} { "EOR", 0xf0800000, 0xfbe08000, ADD_IMM12 }, // EOR{S}
,
, #
{ "EOR", 0xea800000, 0xffe08000, ADD_IMM5 }, // EOR{S}
,
,
{,
#
} { "ORN", 0xf0600000, 0xfbe08000, ADD_IMM12 }, // ORN{S}
,
, #
{ "ORN", 0xea600000, 0xffe08000, ADD_IMM5 }, // ORN{S}
,
,
{,
#
} { "ORR", 0xf0400000, 0xfbe08000, ADD_IMM12 }, // ORR{S}
,
, #
{ "ORR", 0xea400000, 0xffe08000, ADD_IMM5 }, // ORR{S}
,
,
{,
#
} { "RSB", 0xf1c00000, 0xfbe08000, ADD_IMM12 }, // RSB{S}
,
, #
{ "RSB", 0xebc00000, 0xffe08000, ADD_IMM5 }, // RSB{S}
,
,
{,
#
} { "SBC", 0xf1600000, 0xfbe08000, ADD_IMM12 }, // SBC{S}
,
, #
{ "SBC", 0xeb600000, 0xffe08000, ADD_IMM5 }, // SBC{S}
,
,
{,
#
} { "SUB", 0xf1a00000, 0xfbe08000, ADD_IMM12 }, // SUB{S}
,
, #
{ "SUB", 0xeba00000, 0xffe08000, ADD_IMM5 }, // SUB{S}
,
,
{,
#
} { "ASR", 0xea4f0020, 0xffef8030, ASR_IMM5 }, // ARS
,
#
} imm3:imm2 { "ASR", 0xfa40f000, 0xffe0f0f0, ASR_3REG }, // ARS
,
,
{ "LSR", 0xea4f0010, 0xffef8030, ASR_IMM5 }, // LSR
,
#
} imm3:imm2 { "LSR", 0xfa20f000, 0xffe0f0f0, ASR_3REG }, // LSR
,
,
{ "ROR", 0xea4f0030, 0xffef8030, ASR_IMM5 }, // ROR
,
#
} imm3:imm2 { "ROR", 0xfa60f000, 0xffe0f0f0, ASR_3REG }, // ROR
,
,
{ "BFC", 0xf36f0000, 0xffff8010, BFC_THUMB2 }, // BFC
, #
, #
{ "BIC", 0xf3600000, 0xfff08010, BFC_THUMB2 }, // BIC
,
, #
, #
{ "SBFX", 0xf3400000, 0xfff08010, BFC_THUMB2 }, // SBFX
,
, #
, #
{ "UBFX", 0xf3c00000, 0xfff08010, BFC_THUMB2 }, // UBFX
,
, #
, #
{ "CPD", 0xee000000, 0xff000010, CPD_THUMB2 }, // CPD
,
,
,
,
,
{ "CPD2", 0xfe000000, 0xff000010, CPD_THUMB2 }, // CPD
,
,
,
,
,
{ "MRC", 0xee100000, 0xff100000, MRC_THUMB2 }, // MRC
,
,
,
,
,
{ "MRC2", 0xfe100000, 0xff100000, MRC_THUMB2 }, // MRC2
,
,
,
,
,
{ "MRRC", 0xec500000, 0xfff00000, MRRC_THUMB2 }, // MRRC
,
,
,
,
{ "MRRC2", 0xfc500000, 0xfff00000, MRRC_THUMB2 }, // MRR2
,
,
,
,
{ "MRS", 0xf3ef8000, 0xfffff0ff, THUMB2_MRS }, // MRS
, CPSR { "MSR", 0xf3808000, 0xfff0fcff, THUMB2_MSR }, // MSR CPSR_fs,
{ "CLREX", 0xf3bf8f2f, 0xfffffff, THUMB2_NO_ARGS }, // CLREX { "CLZ", 0xfab0f080, 0xfff0f0f0, THUMB2_2REGS }, // CLZ
,
{ "MOV", 0xec4f0000, 0xfff0f0f0, THUMB2_2REGS }, // MOV
,
{ "MOVS", 0xec5f0000, 0xfff0f0f0, THUMB2_2REGS }, // MOVS
,
{ "RBIT", 0xfb90f0a0, 0xfff0f0f0, THUMB2_2REGS }, // RBIT
,
{ "REV", 0xfb90f080, 0xfff0f0f0, THUMB2_2REGS }, // REV
,
{ "REV16", 0xfa90f090, 0xfff0f0f0, THUMB2_2REGS }, // REV16
,
{ "REVSH", 0xfa90f0b0, 0xfff0f0f0, THUMB2_2REGS }, // REVSH
,
{ "RRX", 0xea4f0030, 0xfffff0f0, THUMB2_2REGS }, // RRX
,
{ "RRXS", 0xea5f0030, 0xfffff0f0, THUMB2_2REGS }, // RRXS
,
{ "MLA", 0xfb000000, 0xfff000f0, THUMB2_4REGS }, // MLA
,
,
,
{ "MLS", 0xfb000010, 0xfff000f0, THUMB2_4REGS }, // MLA
,
,
,
{ "SMLABB", 0xfb100000, 0xfff000f0, THUMB2_4REGS }, // SMLABB
,
,