1 /* 2 * Common Development and Distribution License ("CDDL"), version 1.0. 3 * You may only use this file in accordance with the terms of version 4 * 1.0 of the CDDL. 5 * 6 * A full copy of the text of the CDDL should have accompanied this 7 * source. A copy of the CDDL is also available via the Internet at 8 * http://www.illumos.org/license/CDDL. 9 */ 10 /* 11 * Copyright (c) 2013, Joyent, Inc. All rights reserved. 12 * Copyright (c) 2015 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> 13 */ 14 15 /* 16 * This provides basic support for disassembling arm instructions. This is 17 * derived from the arm reference manual (generic), chapter A3 (ARM DDI 0100l). 18 * All instructions come in as uint32_t's. 19 */ 20 21 #include <libdisasm.h> 22 #include <stdint.h> 23 #include <stdio.h> 24 #include <sys/byteorder.h> 25 26 #include "libdisasm_impl.h" 27 28 extern size_t strlcat(char *, const char *, size_t); 29 30 /* 31 * Condition code mask and shift, aka bits 28-31. 32 */ 33 #define ARM_CC_MASK 0xf0000000 34 #define ARM_CC_SHIFT 28 35 36 /* 37 * First level of decoding, aka bits 25-27. 38 */ 39 #define ARM_L1_DEC_MASK 0x0e000000 40 #define ARM_L1_DEC_SHIFT 25 41 42 /* 43 * Masks and values for the 0b000 l1 group 44 */ 45 #define ARM_L1_0_B4_MASK 0x00000010 46 #define ARM_L1_0_B7_MASK 0x00000080 47 #define ARM_L1_0_OPMASK 0x01800000 48 #define ARM_L1_0_SPECOP 0x01000000 49 #define ARM_L1_0_SMASK 0x00100000 50 #define ARM_L1_0_ELS_MASK 0x00000060 51 52 /* 53 * Masks and values for the 0b001 l1 group. 54 */ 55 #define ARM_L1_1_OPMASK 0x01800000 56 #define ARM_L1_1_SPECOP 0x01000000 57 #define ARM_L1_1_SMASK 0x00100000 58 #define ARM_L1_1_UNDEF_MASK 0x00200000 59 60 /* 61 * Masks and values for the 0b011 l1 group 62 */ 63 #define ARM_L1_3_B4_MASK 0x00000010 64 #define ARM_L1_3_ARCHUN_MASK 0x01f000f0 65 66 /* 67 * Masks for the 0b111 l1 group 68 */ 69 #define ARM_L1_7_COPROCMASK 0x00000010 70 #define ARM_L1_7_SWINTMASK 0x01000000 71 72 /* 73 * Masks for the data processing instructions (dpi) 74 */ 75 #define ARM_DPI_OPCODE_MASK 0x01e00000 76 #define ARM_DPI_OPCODE_SHIFT 21 77 #define ARM_DPI_IBIT_MASK 0x02000000 78 #define ARM_DPI_SBIT_MASK 0x00100000 79 #define ARM_DPI_RN_MASK 0x000f0000 80 #define ARM_DPI_RN_SHIFT 16 81 #define ARM_DPI_RD_MASK 0x0000f000 82 #define ARM_DPI_RD_SHIFT 12 83 #define ARM_DPI_BIT4_MASK 0x00000010 84 85 #define ARM_DPI_IMM_ROT_MASK 0x00000f00 86 #define ARM_DPI_IMM_ROT_SHIFT 8 87 #define ARM_DPI_IMM_VAL_MASK 0x000000ff 88 89 #define ARM_DPI_IMS_SHIMM_MASK 0x00000f80 90 #define ARM_DPI_IMS_SHIMM_SHIFT 7 91 #define ARM_DPI_IMS_SHIFT_MASK 0x00000060 92 #define ARM_DPI_IMS_SHIFT_SHIFT 5 93 #define ARM_DPI_IMS_RM_MASK 0x0000000f 94 95 #define ARM_DPI_REGS_RS_MASK 0x00000f00 96 #define ARM_DPI_REGS_RS_SHIFT 8 97 #define ARM_DPI_REGS_SHIFT_MASK 0x00000060 98 #define ARM_DPI_REGS_SHIFT_SHIFT 5 99 #define ARM_DPI_REGS_RM_MASK 0x0000000f 100 101 /* 102 * Definitions for the word and byte LDR and STR instructions 103 */ 104 #define ARM_LS_IBIT_MASK 0x02000000 105 #define ARM_LS_PBIT_MASK 0x01000000 106 #define ARM_LS_UBIT_MASK 0x00800000 107 #define ARM_LS_BBIT_MASK 0x00400000 108 #define ARM_LS_WBIT_MASK 0x00200000 109 #define ARM_LS_LBIT_MASK 0x00100000 110 #define ARM_LS_RN_MASK 0x000f0000 111 #define ARM_LS_RN_SHIFT 16 112 #define ARM_LS_RD_MASK 0x0000f000 113 #define ARM_LS_RD_SHIFT 12 114 115 #define ARM_LS_IMM_MASK 0x00000fff 116 117 #define ARM_LS_REG_RM_MASK 0x0000000f 118 #define ARM_LS_REG_NRM_MASK 0x00000ff0 119 120 #define ARM_LS_SCR_SIMM_MASK 0x00000f80 121 #define ARM_LS_SCR_SIMM_SHIFT 7 122 #define ARM_LS_SCR_SCODE_MASK 0x00000060 123 #define ARM_LS_SCR_SCODE_SHIFT 5 124 #define ARM_LS_SCR_RM_MASK 0x0000000f 125 126 /* 127 * Masks for the Load and Store multiple instructions. 128 */ 129 #define ARM_LSM_PBIT_MASK 0x01000000 130 #define ARM_LSM_UBIT_MASK 0x00800000 131 #define ARM_LSM_SBIT_MASK 0x00400000 132 #define ARM_LSM_WBIT_MASK 0x00200000 133 #define ARM_LSM_LBIT_MASK 0x00100000 134 #define ARM_LSM_RN_MASK 0x000f0000 135 #define ARM_LSM_RN_SHIFT 16 136 #define ARM_LSM_RLIST_MASK 0x0000ffff 137 #define ARM_LSM_ADDR_MASK 0x01800000 138 #define ARM_LSM_ADDR_SHIFT 23 139 140 /* 141 * Masks for the Extended and Misc. Loads and stores. This is the extension 142 * space from figure A3-5. Most of them are handled by arm_dis_els() with the 143 * exception or swap / swap byte and load/store register exclusive which due to 144 * its nature is handled elsewhere. 145 */ 146 #define ARM_ELS_SWAP_MASK 0x01b00000 147 #define ARM_ELS_SWAP_BYTE_MASK 0x00400000 148 #define ARM_ELS_IS_SWAP 0x01000000 149 #define ARM_ELS_EXCL_MASK 0x01800000 150 #define ARM_ELS_PBIT_MASK 0x01000000 151 #define ARM_ELS_UBIT_MASK 0x00800000 152 #define ARM_ELS_IBIT_MASK 0x00400000 153 #define ARM_ELS_WBIT_MASK 0x00200000 154 #define ARM_ELS_LBIT_MASK 0x00100000 155 #define ARM_ELS_SBIT_MASK 0x00000040 156 #define ARM_ELS_HBIT_MASK 0x00000020 157 #define ARM_ELS_RN_MASK 0x000f0000 158 #define ARM_ELS_RN_SHIFT 16 159 #define ARM_ELS_RD_MASK 0x0000f000 160 #define ARM_ELS_RD_SHIFT 12 161 #define ARM_ELS_UP_AM_MASK 0x00000f00 162 #define ARM_ELS_UP_AM_SHIFT 8 163 #define ARM_ELS_LOW_AM_MASK 0x0000000f 164 165 /* 166 * Multiply instruction extensino space masks and values 167 */ 168 #define ARM_EMULT_UNBIT_MASK 0x00400000 169 #define ARM_EMULT_ABIT_MASK 0x00200000 170 #define ARM_EMULT_SBIT_MASK 0x00100000 171 #define ARM_EMULT_RD_MASK 0x000f0000 172 #define ARM_EMULT_RD_SHIFT 16 173 #define ARM_EMULT_RN_MASK 0x0000f000 174 #define ARM_EMULT_RN_SHIFT 12 175 #define ARM_EMULT_RS_MASK 0x00000f00 176 #define ARM_EMULT_RS_SHIFT 8 177 #define ARM_EMULT_RM_MASK 0x0000000f 178 #define ARM_EMULT_MA_MASK 0x0fc00000 179 #define ARM_EMULT_UMA_MASK 0x0ff00000 180 #define ARM_EMULT_UMA_TARG 0x00400000 181 #define ARM_EMULT_MAL_MASK 0x0f800000 182 #define ARM_EMULT_MAL_TARG 0x00800000 183 184 /* 185 * Here we have the masks and target values to indicate instructions from the 186 * Control and DSP extension space. There are a bunch of not quite related 187 * instructions, but that's okay. That's how this thing always rolls. 188 * 189 * The ARM_CDSP_STATUS_MASK and TARG do not catch the move immediate to status 190 * register. That's okay because they get handled and separated out in arm_dis. 191 */ 192 #define ARM_CDSP_STATUS_MASK 0x0f9000f0 193 #define ARM_CDSP_STATUS_TARG 0x01000000 194 #define ARM_CDSP_BEX_UP_MASK 0x0ff00000 /* Branch/exchg/link instrs */ 195 #define ARM_CDSP_BEX_UP_TARG 0x01200000 196 #define ARM_CDSP_BEX_LOW_MASK 0x000000f0 197 #define ARM_CDSP_BEX_NLOW_TARG 0x00000000 /* Here the target is inverse */ 198 #define ARM_CDSP_CLZ_MASK 0x0ff000f0 /* Count leading zeros */ 199 #define ARM_CDSP_CLZ_TARG 0x01200030 200 #define ARM_CDSP_SAT_MASK 0x0f9000f0 /* Saturating add/subtract */ 201 #define ARM_CDSP_SAT_TARG 0x01000050 202 #define ARM_CDSP_BKPT_MASK 0x0ff000f0 /* Software breakpoint */ 203 #define ARM_CDSP_BKPT_TARG 0x01200070 204 #define ARM_CDSP_SMUL_MASK 0x0f900090 /* Signed multiplies (type 2) */ 205 #define ARM_CDSP_SMUL_TARG 0x01000080 206 207 #define ARM_CDSP_RN_MASK 0x000f0000 208 #define ARM_CDSP_RN_SHIFT 16 209 #define ARM_CDSP_RD_MASK 0x0000f000 210 #define ARM_CDSP_RD_SHIFT 12 211 #define ARM_CDSP_RS_MASK 0x00000f00 212 #define ARM_CDSP_RS_SHIFT 8 213 #define ARM_CDSP_RM_MASK 0x0000000f 214 215 #define ARM_CDSP_STATUS_RBIT 0x00400000 216 #define ARM_CDSP_MRS_MASK 0x00300000 /* Ditinguish MRS and MSR */ 217 #define ARM_CDSP_MRS_TARG 0x00000000 218 #define ARM_CDSP_MSR_F_MASK 0x000f0000 219 #define ARM_CDSP_MSR_F_SHIFT 16 220 #define ARM_CDSP_MSR_RI_MASK 0x00000f00 221 #define ARM_CDSP_MSR_RI_SHIFT 8 222 #define ARM_CDSP_MSR_IMM_MASK 0x000000ff 223 #define ARM_CDSP_MSR_ISIMM_MASK 0x02000000 224 225 #define ARM_CDSP_BEX_TYPE_MASK 0x000000f0 226 #define ARM_CDSP_BEX_TYPE_SHIFT 4 227 #define ARM_CDSP_BEX_TYPE_X 1 228 #define ARM_CDSP_BEX_TYPE_J 2 229 #define ARM_CDSP_BEX_TYPE_L 3 230 231 #define ARM_CDSP_SAT_OP_MASK 0x00600000 232 #define ARM_CDSP_SAT_OP_SHIFT 21 233 234 #define ARM_CDSP_BKPT_UIMM_MASK 0x000fff00 235 #define ARM_CDSP_BKPT_UIMM_SHIFT 8 236 #define ARM_CDSP_BKPT_LIMM_MASK 0x0000000f 237 238 #define ARM_CDSP_SMUL_OP_MASK 0x00600000 239 #define ARM_CDSP_SMUL_OP_SHIFT 21 240 #define ARM_CDSP_SMUL_X_MASK 0x00000020 241 #define ARM_CDSP_SMUL_Y_MASK 0x00000040 242 243 /* 244 * Interrupt 245 */ 246 #define ARM_SWI_IMM_MASK 0x00ffffff 247 248 /* 249 * Branch and Link pieces. 250 */ 251 #define ARM_BRANCH_LBIT_MASK 0x01000000 252 #define ARM_BRANCH_IMM_MASK 0x00ffffff 253 #define ARM_BRANCH_SIGN_MASK 0x00800000 254 #define ARM_BRANCH_POS_SIGN 0x00ffffff 255 #define ARM_BRANCH_NEG_SIGN 0xff000000 256 #define ARM_BRANCH_SHIFT 2 257 258 /* 259 * Unconditional instructions 260 */ 261 #define ARM_UNI_CPS_MASK 0x0ff10010 /* Change processor state */ 262 #define ARM_UNI_CPS_TARG 0x01000000 263 #define ARM_UNI_SE_MASK 0x0fff0078 /* Set endianess */ 264 #define ARM_UNI_SE_TARG 0x01010000 265 #define ARM_UNI_PLD_MASK 0x0d70f000 /* Cach preload */ 266 #define ARM_UNI_PLD_TARG 0x0550f000 267 #define ARM_UNI_SRS_MASK 0x0e5f0f00 /* Save return state */ 268 #define ARM_UNI_SRS_TARG 0x084d0500 269 #define ARM_UNI_RFE_MASK 0x0e500f00 /* Return from exception */ 270 #define ARM_UNI_RFE_TARG 0x08100a00 271 #define ARM_UNI_BLX_MASK 0x0e000000 /* Branch with Link / Thumb */ 272 #define ARM_UNI_BLX_TARG 0x0a000000 273 #define ARM_UNI_CODRT_MASK 0x0fe00000 /* double reg to coproc */ 274 #define ARM_UNI_CODRT_TARG 0x0c400000 275 #define ARM_UNI_CORT_MASK 0x0f000010 /* single reg to coproc */ 276 #define ARM_UNI_CORT_TARG 0x0e000010 277 #define ARM_UNI_CODP_MASK 0x0f000010 /* coproc data processing */ 278 #define ARM_UNI_CODP_TARG 0x0e000000 279 280 #define ARM_UNI_CPS_IMOD_MASK 0x000c0000 281 #define ARM_UNI_CPS_IMOD_SHIFT 18 282 #define ARM_UNI_CPS_MMOD_MASK 0x00020000 283 #define ARM_UNI_CPS_A_MASK 0x00000100 284 #define ARM_UNI_CPS_I_MASK 0x00000080 285 #define ARM_UNI_CPS_F_MASK 0x00000040 286 #define ARM_UNI_CPS_MODE_MASK 0x0000001f 287 288 #define ARM_UNI_SE_BE_MASK 0x00000200 289 290 #define ARM_UNI_SRS_WBIT_MASK 0x00200000 291 #define ARM_UNI_SRS_MODE_MASK 0x0000000f 292 293 #define ARM_UNI_RFE_WBIT_MASK 0x00200000 294 295 #define ARM_UNI_BLX_IMM_MASK 0x00ffffff 296 297 /* 298 * Definitions of the ARM Media instruction extension space. 299 */ 300 #define ARM_MEDIA_L1_MASK 0x01800000 /* First level breakdown */ 301 #define ARM_MEDIA_L1_SHIFT 23 302 303 #define ARM_MEDIA_OP1_MASK 0x00700000 304 #define ARM_MEDIA_OP1_SHIFT 20 305 #define ARM_MEDIA_OP2_MASK 0x000000e0 306 #define ARM_MEDIA_OP2_SHIFT 5 307 308 #define ARM_MEDIA_RN_MASK 0x000f0000 309 #define ARM_MEDIA_RN_SHIFT 16 310 #define ARM_MEDIA_RD_MASK 0x0000f000 311 #define ARM_MEDIA_RD_SHIFT 12 312 #define ARM_MEDIA_RS_MASK 0x00000f00 313 #define ARM_MEDIA_RS_SHIFT 8 314 #define ARM_MEDIA_RM_MASK 0x0000000f 315 316 #define ARM_MEDIA_MULT_X_MASK 0x00000020 317 318 #define ARM_MEDIA_HPACK_MASK 0x00700020 /* Halfword pack */ 319 #define ARM_MEDIA_HPACK_TARG 0x00000000 320 #define ARM_MEDIA_WSAT_MASK 0x00200020 /* Word saturate */ 321 #define ARM_MEDIA_WSAT_TARG 0x00200000 322 #define ARM_MEDIA_PHSAT_MASK 0x003000e0 /* Parallel halfword saturate */ 323 #define ARM_MEDIA_PHSAT_TARG 0x00200020 324 #define ARM_MEDIA_REV_MASK 0x007000e0 /* Byte rev. word */ 325 #define ARM_MEDIA_REV_TARG 0x00300020 326 #define ARM_MEDIA_BRPH_MASK 0x007000e0 /* Byte rev. packed halfword */ 327 #define ARM_MEDIA_BRPH_TARG 0x003000a0 328 #define ARM_MEDIA_BRSH_MASK 0x007000e0 /* Byte rev. signed halfword */ 329 #define ARM_MEDIA_BRSH_TARG 0x007000a0 330 #define ARM_MEDIA_SEL_MASK 0x008000e0 /* Select bytes */ 331 #define ARM_MEDIA_SEL_TARG 0x000000a0 332 #define ARM_MEDIA_SZE_MASK 0x000000e0 /* Sign/zero extend */ 333 #define ARM_MEDIA_SZE_TARG 0x00000030 334 335 #define ARM_MEDIA_HPACK_OP_MASK 0x00000040 336 #define ARM_MEDIA_HPACK_SHIFT_MASK 0x00000f80 337 #define ARM_MEDIA_HPACK_SHIFT_IMM 7 338 339 #define ARM_MEDIA_SAT_U_MASK 0x00400000 340 #define ARM_MEDIA_SAT_IMM_MASK 0x001f0000 341 #define ARM_MEDIA_SAT_IMM_SHIFT 16 342 #define ARM_MEDIA_SAT_SHI_MASK 0x00000f80 343 #define ARM_MEDIA_SAT_SHI_SHIFT 7 344 #define ARM_MEDIA_SAT_STYPE_MASK 0x00000040 345 346 #define ARM_MEDIA_SZE_S_MASK 0x00400000 347 #define ARM_MEDIA_SZE_OP_MASK 0x00300000 348 #define ARM_MEDIA_SZE_OP_SHIFT 20 349 #define ARM_MEDIA_SZE_ROT_MASK 0x00000c00 350 #define ARM_MEDIA_SZE_ROT_SHIFT 10 351 352 /* 353 * Definitions for coprocessor instructions 354 */ 355 #define ARM_COPROC_RN_MASK 0x000f0000 356 #define ARM_COPROC_RN_SHIFT 16 357 #define ARM_COPROC_RD_MASK 0x0000f000 358 #define ARM_COPROC_RD_SHIFT 12 359 #define ARM_COPROC_RM_MASK 0x0000000f 360 #define ARM_COPROC_NUM_MASK 0x00000f00 361 #define ARM_COPROC_NUM_SHIFT 8 362 363 #define ARM_COPROC_CDP_OP1_MASK 0x00f00000 364 #define ARM_COPROC_CDP_OP1_SHIFT 20 365 #define ARM_COPROC_CDP_OP2_MASK 0x000000e0 366 #define ARM_COPROC_CDP_OP2_SHIFT 5 367 368 #define ARM_COPROC_CRT_OP1_MASK 0x00e00000 369 #define ARM_COPROC_CRT_OP1_SHIFT 21 370 #define ARM_COPROC_CRT_OP2_MASK 0x000000e0 371 #define ARM_COPROC_CRT_OP2_SHIFT 5 372 #define ARM_COPROC_CRT_DIR_MASK 0x00100000 /* MCR or MRC */ 373 374 #define ARM_COPROC_DRT_MASK 0x01e00000 375 #define ARM_COPROC_DRT_TARG 0x00400000 376 #define ARM_COPROC_DRT_OP_MASK 0x000000f0 377 #define ARM_COPROC_DRT_OP_SHIFT 4 378 #define ARM_COPROC_DRT_DIR_MASK 0x00100000 /* MCRR or MRRC */ 379 380 #define ARM_COPROC_LS_P_MASK 0x01000000 381 #define ARM_COPROC_LS_U_MASK 0x00800000 382 #define ARM_COPROC_LS_N_MASK 0x00400000 383 #define ARM_COPROC_LS_W_MASK 0x00200000 384 #define ARM_COPROC_LS_L_MASK 0x00100000 385 #define ARM_COPROC_LS_IMM_MASK 0x000000ff 386 387 /* 388 * This is the table of condition codes that instructions might have. Every 389 * instruction starts with a four bit code. The last two codes are special. 390 * 0b1110 is the always condition. Therefore we leave off its mneomic extension 391 * and treat it as the empty string. The condition code 0b1111 takes us to a 392 * separate series of encoded instructions and therefore we go elsewhere with 393 * them. 394 */ 395 static const char *arm_cond_names[] = { 396 "EQ", /* Equal */ 397 "NE", /* Not Equal */ 398 "CS/HS", /* Carry set/unsigned higher or same */ 399 "CC/LO", /* Carry clear/unsigned lower */ 400 "MI", /* Minus/negative */ 401 "PL", /* Plus/positive or zero */ 402 "VS", /* Overflow */ 403 "VC", /* No overflow */ 404 "HI", /* Unsigned higher */ 405 "LS", /* Unsigned lower or same */ 406 "GE", /* Signed greater than or equal */ 407 "LT", /* Signed less than */ 408 "GT", /* Signed greater than */ 409 "LE", /* Signed less than or equal */ 410 "", /* AL - Always (unconditional) */ 411 NULL /* Not a condition code */ 412 }; 413 414 typedef enum arm_cond_code { 415 ARM_COND_EQ, /* Equal */ 416 ARM_COND_NE, /* Not Equal */ 417 ARM_COND_CSHS, /* Carry set/unsigned higher or same */ 418 ARM_COND_CCLO, /* Carry clear/unsigned lower */ 419 ARM_COND_MI, /* Minus/negative */ 420 ARM_COND_PL, /* Plus/positive or zero */ 421 ARM_COND_VS, /* Overflow */ 422 ARM_COND_VC, /* No overflow */ 423 ARM_COND_HI, /* Unsigned higher */ 424 ARM_COND_LS, /* Unsigned lower or same */ 425 ARM_COND_GE, /* Signed greater than or equal */ 426 ARM_COND_LT, /* Signed less than */ 427 ARM_COND_GT, /* Signed greater than */ 428 ARM_COND_LE, /* Signed less than or equal */ 429 ARM_COND_AL, /* AL - Always (unconditional) */ 430 ARM_COND_NACC /* Not a condition code */ 431 } arm_cond_code_t; 432 433 /* 434 * Registers are encoded surprisingly sanely. It's a 4-bit value that indicates 435 * which register in question we're working with. 436 */ 437 static const char *arm_reg_names[] = { 438 "R0", 439 "R1", 440 "R2", 441 "R3", 442 "R4", 443 "R5", 444 "R6", 445 "R7", 446 "R8", 447 "R9", 448 "R10", 449 "R11", 450 "IP", /* Alt for R12 */ 451 "SP", /* Alt for R13 */ 452 "LR", /* Alt for R14 */ 453 "PC" /* Alt for R15 */ 454 }; 455 456 typedef enum arm_reg { 457 ARM_REG_R0, 458 ARM_REG_R1, 459 ARM_REG_R2, 460 ARM_REG_R3, 461 ARM_REG_R4, 462 ARM_REG_R5, 463 ARM_REG_R6, 464 ARM_REG_R7, 465 ARM_REG_R8, 466 ARM_REG_R9, 467 ARM_REG_R10, 468 ARM_REG_R11, 469 ARM_REG_R12, 470 ARM_REG_R13, 471 ARM_REG_R14, 472 ARM_REG_R15 473 } arm_reg_t; 474 475 /* 476 * Default coprocessor names 477 */ 478 static const char *arm_coproc_names[] = { 479 "p0", 480 "p1", 481 "p2", 482 "p3", 483 "p4", 484 "p5", 485 "p6", 486 "p7", 487 "p8", 488 "p9", 489 "p10", 490 "p11", 491 "p12", 492 "p13", 493 "p14", 494 "p15" 495 }; 496 497 /* 498 * These are the opcodes for the instructions which are considered data 499 * processing instructions. 500 */ 501 static const char *arm_dpi_opnames[] = { 502 "AND", /* Logical AND */ 503 "EOR", /* Logical Exclusive OR */ 504 "SUB", /* Subtract */ 505 "RSB", /* Reverse Subtract */ 506 "ADD", /* Add */ 507 "ADC", /* Add with Carry */ 508 "SBC", /* Subtract with Carry */ 509 "RSC", /* Reverse Subtract with Carry */ 510 "TST", /* Test */ 511 "TEQ", /* Test Equivalence */ 512 "CMP", /* Compare */ 513 "CMN", /* Compare negated */ 514 "ORR", /* Logical (inclusive) OR */ 515 "MOV", /* Move */ 516 "BIC", /* Bit clear */ 517 "MVN" /* Move not */ 518 }; 519 520 typedef enum arm_dpi_opcode { 521 DPI_OP_AND, /* Logical AND */ 522 DPI_OP_EOR, /* Logical Exclusive OR */ 523 DPI_OP_SUB, /* Subtract */ 524 DPI_OP_RSB, /* Reverse Subtract */ 525 DPI_OP_ADD, /* Add */ 526 DPI_OP_ADC, /* Add with Carry */ 527 DPI_OP_SBC, /* Subtract with Carry */ 528 DPI_OP_RSC, /* Reverse Subtract with Carry */ 529 DPI_OP_TST, /* Test */ 530 DPI_OP_TEQ, /* Test Equivalence */ 531 DPI_OP_CMP, /* Compare */ 532 DPI_OP_CMN, /* Compare negated */ 533 DPI_OP_ORR, /* Logical (inclusive) OR */ 534 DPI_OP_MOV, /* Move */ 535 DPI_OP_BIC, /* Bit clear */ 536 DPI_OP_MVN /* Move not */ 537 } arm_dpi_opcode_t; 538 539 const char *arm_dpi_shifts[] = { 540 "LSL", /* Logical shift left */ 541 "LSR", /* Logical shift right */ 542 "ASR", /* Arithmetic shift right */ 543 "ROR", /* Rotate right */ 544 "RRX" /* Rotate right with extend. This is a special case of ROR */ 545 }; 546 547 typedef enum arm_dpi_shift_code { 548 DPI_S_LSL, /* Logical shift left */ 549 DPI_S_LSR, /* Logical shift right */ 550 DPI_S_ASR, /* Arithmetic shift right */ 551 DPI_S_ROR, /* Rotate right */ 552 DPI_S_RRX, /* Rotate right with extend. Special case of ROR */ 553 DPI_S_NONE /* No shift code */ 554 } arm_dpi_shift_code_t; 555 556 #define ARM_DPI_SHIFTER_IMM32 0x00 557 #define ARM_DPI_SHIFTER_SIMM 0x01 558 #define ARM_DPI_SHIFTER_SREG 0x02 559 560 typedef struct arm_dpi_shifter_imm { 561 uint8_t dpisi_rot; /* Rotation amount */ 562 uint8_t dpisi_imm; /* Immediate value */ 563 } arm_dpi_shifter_imm_t; 564 565 typedef struct arm_dpi_shifter_simm { 566 uint8_t dpiss_imm; /* Shift value */ 567 arm_dpi_shift_code_t dpiss_code; /* Shift type */ 568 arm_reg_t dpiss_targ; /* Target register */ 569 } arm_dpi_shifter_simm_t; 570 571 typedef struct arm_dpi_shifter_sreg { 572 arm_reg_t dpisr_val; /* reg with shift value */ 573 arm_dpi_shift_code_t dpisr_code; /* Shift type */ 574 arm_reg_t dpisr_targ; /* Target register */ 575 } arm_dpi_shifter_sreg_t; 576 577 typedef struct arm_dpi_inst { 578 arm_dpi_opcode_t dpii_op; /* dpi opcode */ 579 arm_cond_code_t dpii_cond; /* condition code */ 580 int dpii_sbit; /* value of S bit */ 581 arm_reg_t dpii_rn; /* first operand */ 582 arm_reg_t dpii_rd; /* destination operand */ 583 int dpii_stype; /* type of shifter */ 584 union { /* shifter values */ 585 arm_dpi_shifter_imm_t dpii_im; 586 arm_dpi_shifter_simm_t dpii_si; 587 arm_dpi_shifter_sreg_t dpii_ri; 588 } dpii_un; 589 } arm_dpi_inst_t; 590 591 /* 592 * This table contains the names of the load store multiple addressing modes. 593 * The P and U bits are supposed to be combined to index into this. You should 594 * do this by doing P << 1 | U. 595 */ 596 static const char *arm_lsm_mode_names[] = { 597 "DA", 598 "IA", 599 "DB", 600 "IB" 601 }; 602 603 /* 604 * The MSR field has a four bit field mask. Each bit correspons to a letter. 605 * From high to low, f, s, x, c. At least one must be specified, hence 0 is 606 * NULL. The preferred manual ordering of these is csxf. 607 */ 608 static const char *arm_cdsp_msr_field_names[] = { 609 NULL, 610 "c", /* 0001 */ 611 "x", /* 0010 */ 612 "cx", /* 0011 */ 613 "s", /* 0100 */ 614 "cs", /* 0101 */ 615 "sx", /* 0110 */ 616 "csx", /* 0111 */ 617 "f", /* 1000 */ 618 "cf", /* 1001 */ 619 "xf", /* 1010 */ 620 "cxf", /* 1011 */ 621 "sf", /* 1100 */ 622 "csf", /* 1101 */ 623 "sxf", /* 1110 */ 624 "csxf" /* 1111 */ 625 }; 626 627 /* 628 * Names for specific saturating add and subtraction instructions from the 629 * extended control and dsp instructino section. 630 */ 631 static const char *arm_cdsp_sat_opnames[] = { 632 "ADD", 633 "SUB", 634 "DADD", 635 "DSUB" 636 }; 637 638 static const char *arm_padd_p_names[] = { 639 NULL, /* 000 */ 640 "S", /* 001 */ 641 "Q", /* 010 */ 642 "SH", /* 011 */ 643 NULL, /* 100 */ 644 "U", /* 101 */ 645 "UQ", /* 110 */ 646 "UH", /* 111 */ 647 }; 648 649 static const char *arm_padd_i_names[] = { 650 "ADD16", /* 000 */ 651 "ADDSUBX", /* 001 */ 652 "SUBADDX", /* 010 */ 653 "SUB16", /* 011 */ 654 "ADD8", /* 100 */ 655 NULL, /* 101 */ 656 NULL, /* 110 */ 657 "SUB8", /* 111 */ 658 }; 659 660 static const char *arm_extend_rot_names[] = { 661 "", /* 0b00, ROR #0 */ 662 ", ROR #8", /* 0b01 */ 663 ", ROR #16", /* 0b10 */ 664 ", ROR #24" /* 0b11 */ 665 }; 666 667 /* 668 * There are sixteen data processing instructions (dpi). They come in a few 669 * different forms which are based on whether immediate values are used and 670 * whether or not some special purpose shifting is done. We use this one entry 671 * point to cover all the different types. 672 * 673 * From the ARM arch manual: 674 * 675 * <opcode1>{<cond>}{S} <Rd>,<shifter> 676 * <opcode1> := MOV | MVN 677 * <opcode2>{<cond>} <Rn>,<shifter> 678 * <opcode2> := CMP, CMN, TST, TEQ 679 * <opcode3>{<cond>{S} <Rd>,<Rn>, <shifter> 680 * <opcode3> := ADD | SUB | RSB | ADC | SBC | RSC | AND | BIC | EOR | ORR 681 * 682 * 31 - 28|27 26 |25 | 24-21 |20 | 19-16 | 15-12 | 11 - 0 683 * [ cond | 0 0 | I | opcode | S | Rn | Rd | shifter ] 684 * 685 * I bit: Determines whether shifter_operand is immediate or register based 686 * S bit: Determines whether or not the insn updates condition codes 687 * Rn: First source operand register 688 * Rd: Destination register 689 * shifter: Specifies the second operand 690 * 691 * There are three primary encodings: 692 * 693 * 32-bit immediate 694 * 31 - 28|27 26|25 |24-21 |20|19-16| 15-12|11 - 8 |7 - 0 695 * [ cond | 0 0| 1 |opcode| S|Rn | Rd |rotate_imm|immed_8 ] 696 * 697 * Immediate shifts 698 * 31 - 28|27 26|25 |24-21 |20|19-16|15-12|11 - 7 |6 5 |4|3-0 699 * [ cond | 0 0| 0 |opcode| S|Rn |Rd |shift_imm|shift|0|Rm ] 700 * 701 * Register shifts 702 * 31 - 28|27 26|25 |24-21 |20|19-16|15-12|11 - 8|7|6 5 |4|3-0 703 * [ cond | 0 0| 0 |opcode| S|Rn |Rd |Rs |0|shift|1|Rm ] 704 * 705 * There are four different kinds of shifts that work with both immediate and 706 * register shifts: 707 * o Logical shift left 0b00 (LSL) 708 * o Logical shift right 0b01 (LSR) 709 * o Arithmetic shift right 0b10 (ASR) 710 * o Rotate right 0b11 (ROR) 711 * There is one special shift which only works with immediate shift format: 712 * o If shift_imm = 0 and shift = 0b11, then it is a rotate right with extend 713 * (RRX) 714 * 715 * Finally there is one special indication for no shift. An immediate shift 716 * whose shift_imm = shift = 0. This is a shortcut to a direct value from the 717 * register. 718 * 719 * While processing this, we first build up all the information into the 720 * arm_dpi_inst_t and then from there we go and print out the format based on 721 * the opcode and shifter. As per the rough grammar above we have to print 722 * different sets of instructions in different ways. 723 */ 724 static int 725 arm_dis_dpi(uint32_t in, arm_cond_code_t cond, char *buf, size_t buflen) 726 { 727 arm_dpi_inst_t dpi_inst; 728 int ibit, bit4; 729 size_t len; 730 731 dpi_inst.dpii_op = (in & ARM_DPI_OPCODE_MASK) >> ARM_DPI_OPCODE_SHIFT; 732 dpi_inst.dpii_cond = cond; 733 dpi_inst.dpii_rn = (in & ARM_DPI_RN_MASK) >> ARM_DPI_RN_SHIFT; 734 dpi_inst.dpii_rd = (in & ARM_DPI_RD_MASK) >> ARM_DPI_RD_SHIFT; 735 dpi_inst.dpii_sbit = in & ARM_DPI_SBIT_MASK; 736 737 ibit = in & ARM_DPI_IBIT_MASK; 738 bit4 = in & ARM_DPI_BIT4_MASK; 739 740 if (ibit) { 741 /* 32-bit immediate */ 742 dpi_inst.dpii_stype = ARM_DPI_SHIFTER_IMM32; 743 dpi_inst.dpii_un.dpii_im.dpisi_rot = (in & 744 ARM_DPI_IMM_ROT_MASK) >> ARM_DPI_IMM_ROT_SHIFT; 745 dpi_inst.dpii_un.dpii_im.dpisi_imm = in & ARM_DPI_IMM_VAL_MASK; 746 } else if (bit4) { 747 /* Register shift */ 748 dpi_inst.dpii_stype = ARM_DPI_SHIFTER_SREG; 749 dpi_inst.dpii_un.dpii_ri.dpisr_val = (in & 750 ARM_DPI_REGS_RS_MASK) >> ARM_DPI_REGS_RS_SHIFT; 751 dpi_inst.dpii_un.dpii_ri.dpisr_targ = in & 752 ARM_DPI_REGS_RM_MASK; 753 dpi_inst.dpii_un.dpii_ri.dpisr_code = in & 754 ARM_DPI_REGS_SHIFT_MASK >> ARM_DPI_REGS_SHIFT_SHIFT; 755 } else { 756 /* Immediate shift */ 757 dpi_inst.dpii_stype = ARM_DPI_SHIFTER_SIMM; 758 dpi_inst.dpii_un.dpii_si.dpiss_imm = (in & 759 ARM_DPI_IMS_SHIMM_MASK) >> ARM_DPI_IMS_SHIMM_SHIFT; 760 dpi_inst.dpii_un.dpii_si.dpiss_code = (in & 761 ARM_DPI_IMS_SHIFT_MASK) >> ARM_DPI_IMS_SHIFT_SHIFT; 762 dpi_inst.dpii_un.dpii_si.dpiss_targ = in & ARM_DPI_IMS_RM_MASK; 763 if (dpi_inst.dpii_un.dpii_si.dpiss_code == DPI_S_ROR && 764 dpi_inst.dpii_un.dpii_si.dpiss_imm == 0) 765 dpi_inst.dpii_un.dpii_si.dpiss_code = DPI_S_RRX; 766 767 if (dpi_inst.dpii_un.dpii_si.dpiss_code == DPI_S_LSL && 768 dpi_inst.dpii_un.dpii_si.dpiss_imm == 0) 769 dpi_inst.dpii_un.dpii_si.dpiss_code = DPI_S_NONE; 770 } 771 772 /* 773 * Print everything before the shifter based on the instruction 774 */ 775 switch (dpi_inst.dpii_op) { 776 case DPI_OP_MOV: 777 case DPI_OP_MVN: 778 len = snprintf(buf, buflen, "%s%s%s %s", 779 arm_dpi_opnames[dpi_inst.dpii_op], 780 arm_cond_names[dpi_inst.dpii_cond], 781 dpi_inst.dpii_sbit != 0 ? "S" : "", 782 arm_reg_names[dpi_inst.dpii_rd]); 783 break; 784 case DPI_OP_CMP: 785 case DPI_OP_CMN: 786 case DPI_OP_TST: 787 case DPI_OP_TEQ: 788 len = snprintf(buf, buflen, "%s%s %s", 789 arm_dpi_opnames[dpi_inst.dpii_op], 790 arm_cond_names[dpi_inst.dpii_cond], 791 arm_reg_names[dpi_inst.dpii_rn]); 792 break; 793 default: 794 len = snprintf(buf, buflen, 795 "%s%s%s %s, %s", arm_dpi_opnames[dpi_inst.dpii_op], 796 arm_cond_names[dpi_inst.dpii_cond], 797 dpi_inst.dpii_sbit != 0 ? "S" : "", 798 arm_reg_names[dpi_inst.dpii_rd], 799 arm_reg_names[dpi_inst.dpii_rn]); 800 break; 801 } 802 803 if (len >= buflen) 804 return (-1); 805 buflen -= len; 806 buf += len; 807 808 /* 809 * Print the shifter as appropriate 810 */ 811 switch (dpi_inst.dpii_stype) { 812 case ARM_DPI_SHIFTER_IMM32: { 813 uint32_t rawimm, imm; 814 int rawrot, rot; 815 816 rawimm = dpi_inst.dpii_un.dpii_im.dpisi_imm; 817 rawrot = dpi_inst.dpii_un.dpii_im.dpisi_rot; 818 819 rot = rawrot * 2; 820 imm = (rawimm << (32 - rot)) | (rawimm >> rot); 821 822 len = snprintf(buf, buflen, ", #%u, %d ; 0x%08x", rawimm, 823 rawrot, imm); 824 break; 825 } 826 case ARM_DPI_SHIFTER_SIMM: 827 if (dpi_inst.dpii_un.dpii_si.dpiss_code == DPI_S_NONE) { 828 len = snprintf(buf, buflen, ", %s", 829 arm_reg_names[dpi_inst.dpii_un.dpii_si.dpiss_targ]); 830 break; 831 } 832 if (dpi_inst.dpii_un.dpii_si.dpiss_code == DPI_S_RRX) { 833 len = snprintf(buf, buflen, ", %s RRX", 834 arm_reg_names[dpi_inst.dpii_un.dpii_si.dpiss_targ]); 835 break; 836 } 837 len = snprintf(buf, buflen, ", %s, %s #%d", 838 arm_reg_names[dpi_inst.dpii_un.dpii_si.dpiss_targ], 839 arm_dpi_shifts[dpi_inst.dpii_un.dpii_si.dpiss_code], 840 dpi_inst.dpii_un.dpii_si.dpiss_imm); 841 break; 842 case ARM_DPI_SHIFTER_SREG: 843 len = snprintf(buf, buflen, ", %s, %s %s", 844 arm_reg_names[dpi_inst.dpii_un.dpii_ri.dpisr_targ], 845 arm_dpi_shifts[dpi_inst.dpii_un.dpii_ri.dpisr_code], 846 arm_reg_names[dpi_inst.dpii_un.dpii_ri.dpisr_val]); 847 break; 848 } 849 850 return (len < buflen ? 0 : -1); 851 } 852 853 /* 854 * This handles the byte and word size loads and stores. It does not handle the 855 * multi-register loads or the 'extra' ones. The instruction has the generic 856 * form off: 857 * 858 * 31 - 28|27 26 |25|24|23|22|21|20|19-16|15-12|11 - 0 859 * [ cond | 0 0 |I |P |U |B |W |L | Rn | Rd |mode_specific] 860 * 861 * Here the bits mean the following: 862 * 863 * Rn: The base register used by the addressing mode 864 * Rd: The register to load to or store from 865 * L bit: If L==1 then a load, else store 866 * B bit: If B==1 then work on a byte, else a 32-bit word 867 * 868 * The remaining pieces determine the mode we are operating in: 869 * I bit: If 0 use immediate offsets, otherwise if 1 used register based offsets 870 * P bit: If 0 use post-indexed addressing. If 1, indexing mode is either offset 871 * addessing or pre-indexed addressing based on the W bit. 872 * U bit: If 1, offset is added to base, if 0 offset is subtracted from base 873 * W bit: This bits interpretation varies based on the P bit. If P is zero then 874 * W indicates whether a normal memory access is performed or if a read 875 * from user memory is performed (W = 1). 876 * If P is 1 then then when W = 0 the base register is not updated and 877 * when W = 1 the calculated address is written back to the base 878 * register. 879 * 880 * Based on these combinations there are a total of nine different operating 881 * modes, though not every LDR and STR variant can reach them all. 882 */ 883 static int 884 arm_dis_ldstr(uint32_t in, char *buf, size_t buflen) 885 { 886 arm_cond_code_t cc; 887 arm_reg_t rd, rn, rm; 888 int ibit, pbit, ubit, bbit, wbit, lbit; 889 arm_dpi_shift_code_t sc; 890 uint8_t simm; 891 size_t len; 892 893 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 894 ibit = in & ARM_LS_IBIT_MASK; 895 pbit = in & ARM_LS_PBIT_MASK; 896 ubit = in & ARM_LS_UBIT_MASK; 897 bbit = in & ARM_LS_BBIT_MASK; 898 wbit = in & ARM_LS_WBIT_MASK; 899 lbit = in & ARM_LS_LBIT_MASK; 900 rd = (in & ARM_LS_RD_MASK) >> ARM_LS_RD_SHIFT; 901 rn = (in & ARM_LS_RN_MASK) >> ARM_LS_RN_SHIFT; 902 903 len = snprintf(buf, buflen, "%s%s%s%s %s, ", lbit != 0 ? "LDR" : "STR", 904 arm_cond_names[cc], bbit != 0 ? "B" : "", 905 (pbit == 0 && wbit != 0) ? "T" : "", 906 arm_reg_names[rd]); 907 if (len >= buflen) 908 return (-1); 909 910 /* Figure out the specifics of the encoding for the rest */ 911 if (ibit == 0 && pbit != 0) { 912 /* 913 * This is the immediate offset mode (A5.2.2). That means that 914 * we have something of the form [ <Rn>, #+/-<offset_12> ]. All 915 * of the mode specific bits contribute to offset_12. We also 916 * handle the pre-indexed version (A5.2.5) which depends on the 917 * wbit being set. 918 */ 919 len += snprintf(buf + len, buflen - len, "[%s, #%s%d]%s", 920 arm_reg_names[rn], ubit != 0 ? "" : "-", 921 in & ARM_LS_IMM_MASK, wbit != 0 ? "!" : ""); 922 } else if (ibit != 0 && pbit != 0) { 923 /* 924 * This handles A5.2.2, A5.2.3, A5.2.6, and A5.2.7. We can have 925 * one of two options. If the non-rm bits (11-4) are all zeros 926 * then we have a special case of a register offset is just 927 * being added. Otherwise we have a scaled register offset where 928 * the shift code matters. 929 */ 930 rm = in & ARM_LS_REG_RM_MASK; 931 len += snprintf(buf + len, buflen - len, "[%s, %s%s", 932 arm_reg_names[rn], ubit != 0 ? "" : "-", 933 arm_reg_names[rm]); 934 if (len >= buflen) 935 return (-1); 936 if ((in & ARM_LS_REG_NRM_MASK) != 0) { 937 simm = (in & ARM_LS_SCR_SIMM_MASK) >> 938 ARM_LS_SCR_SIMM_SHIFT; 939 sc = (in & ARM_LS_SCR_SCODE_MASK) >> 940 ARM_LS_SCR_SCODE_SHIFT; 941 942 if (simm == 0 && sc == DPI_S_ROR) 943 sc = DPI_S_RRX; 944 945 len += snprintf(buf + len, buflen - len, "%s", 946 arm_dpi_shifts[sc]); 947 if (len >= buflen) 948 return (-1); 949 if (sc != DPI_S_RRX) { 950 len += snprintf(buf + len, buflen - len, " #%d", 951 simm); 952 if (len >= buflen) 953 return (-1); 954 } 955 } 956 len += snprintf(buf + len, buflen - len, "]%s", 957 wbit != 0 ? "!" : ""); 958 } else if (ibit == 0 && pbit == 0 && wbit == 0) { 959 /* A5.2.8 immediate post-indexed */ 960 len += snprintf(buf + len, buflen - len, "[%s], #%s%d", 961 arm_reg_names[rn], ubit != 0 ? "" : "-", 962 in & ARM_LS_IMM_MASK); 963 } else if (ibit != 0 && pbit == 0 && wbit == 0) { 964 /* A5.2.9 and A5.2.10 */ 965 rm = in & ARM_LS_REG_RM_MASK; 966 len += snprintf(buf + len, buflen - len, "[%s], %s%s", 967 arm_reg_names[rn], ubit != 0 ? "" : "-", 968 arm_reg_names[rm]); 969 if ((in & ARM_LS_REG_NRM_MASK) != 0) { 970 simm = (in & ARM_LS_SCR_SIMM_MASK) >> 971 ARM_LS_SCR_SIMM_SHIFT; 972 sc = (in & ARM_LS_SCR_SCODE_MASK) >> 973 ARM_LS_SCR_SCODE_SHIFT; 974 975 if (simm == 0 && sc == DPI_S_ROR) 976 sc = DPI_S_RRX; 977 978 len += snprintf(buf + len, buflen - len, "%s", 979 arm_dpi_shifts[sc]); 980 if (len >= buflen) 981 return (-1); 982 if (sc != DPI_S_RRX) 983 len += snprintf(buf + len, buflen - len, 984 " #%d", simm); 985 } 986 } 987 988 return (len < buflen ? 0 : -1); 989 } 990 991 /* 992 * This handles load and store multiple instructions. The general format is as 993 * follows: 994 * 995 * 31 - 28|27 26 25|24|23|22|21|20|19-16|15-0 996 * [ cond | 1 0 0 |P |U |S |W |L | Rn | register set 997 * 998 * The register set has one bit per register. If a bit is set it indicates that 999 * register and if it is not set then it indicates that the register is not 1000 * included in this. 1001 * 1002 * S bit: If the instruction is a LDM and we load the PC, the S == 1 tells us to 1003 * load the CPSR from SPSR after the other regs are loaded. If the instruction 1004 * is a STM or LDM without touching the PC it indicates that if we are 1005 * privileged we should send the banked registers. 1006 * 1007 * L bit: Where this is a load or store. Load is active high. 1008 * 1009 * P bit: If P == 0 then Rn is included in the memory region transfers and its 1010 * location is dependent on the U bit. It is at the top (U == 0) or bottom (U == 1011 * 1). If P == 1 then it is excluded and lies one word beyond the top (U == 0) 1012 * or bottom based on the U bit. 1013 * 1014 * U bit: If U == 1 then the transfer is made upwards and if U == 0 then the 1015 * transfer is made downwards. 1016 * 1017 * W bit: If set then we incremet the base register after the transfer. It is 1018 * modified by 4 times the number of registers in the list. If the U bit is 1019 * positive then that value is added to Rn otherwise it is subtracted. 1020 * 1021 * The overal layout for this is 1022 * (LDM|STM){<cond>}<addressing mode> Rn{!}, <registers>{^}. Here the ! is based 1023 * on having the W bit set. The ^ bit depends on whether S is set or not. 1024 * 1025 * There are four normal addressing modes: IA, IB, DA, DB. There are also 1026 * corresponding stack addressing modes that exist. However we have no way of 1027 * knowing which are the ones being used, therefore we are going to default to 1028 * the non-stack versions which are listed as the primary. 1029 * 1030 * Finally the last useful bit is how the registers list is specified. It is a 1031 * comma separated list inside of { }. However, a user may separate a contiguous 1032 * range by the use of a -, eg. R0 - R4. However, it is impossible for us to map 1033 * back directly to what the user did. So for now, we punt on second down and 1034 * instead just list each indidvidual register rather than attempt a joining 1035 * routine. 1036 */ 1037 static int 1038 arm_dis_ldstr_multi(uint32_t in, char *buf, size_t buflen) 1039 { 1040 int sbit, wbit, lbit, ii, cont; 1041 uint16_t regs, addr_mode; 1042 arm_reg_t rn; 1043 arm_cond_code_t cc; 1044 size_t len; 1045 1046 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 1047 sbit = in & ARM_LSM_SBIT_MASK; 1048 wbit = in & ARM_LSM_WBIT_MASK; 1049 lbit = in & ARM_LSM_LBIT_MASK; 1050 rn = (in & ARM_LSM_RN_MASK) >> ARM_LSM_RN_SHIFT; 1051 regs = in & ARM_LSM_RLIST_MASK; 1052 addr_mode = (in & ARM_LSM_ADDR_MASK) >> ARM_LSM_ADDR_SHIFT; 1053 1054 len = snprintf(buf, buflen, "%s%s%s %s%s, { ", 1055 lbit != 0 ? "LDM" : "STM", 1056 arm_cond_names[cc], 1057 arm_lsm_mode_names[addr_mode], 1058 arm_reg_names[rn], 1059 wbit != 0 ? "!" : ""); 1060 1061 cont = 0; 1062 for (ii = 0; ii < 16; ii++) { 1063 if (!(regs & (1 << ii))) 1064 continue; 1065 1066 len += snprintf(buf + len, buflen - len, "%s%s", 1067 cont > 0 ? ", " : "", arm_reg_names[ii]); 1068 if (len >= buflen) 1069 return (-1); 1070 cont++; 1071 } 1072 1073 len += snprintf(buf + len, buflen - len, " }%s", sbit != 0 ? "^" : ""); 1074 return (len >= buflen ? -1 : 0); 1075 } 1076 1077 /* 1078 * Here we need to handle miscillaneous loads and stores. This is used to load 1079 * and store signed and unsigned half words. To load a signed byte. And to load 1080 * and store double words. There is no specific store routines for signed bytes 1081 * and halfwords as they are supposed to use the SRB and STRH. There are two 1082 * primary encodings this time. The general case looks like: 1083 * 1084 * 31 - 28|27 - 25|24|23|22|21|20|19-16|15-12|11-8 |7|6|5|4|3-0 1085 * [ cond | 0 |P |U |I |W |L | Rn | Rd |amode|1|S|H|1|amode ] 1086 * 1087 * The I, P, U, and W bits specify the addressing mode. 1088 * The L, S, and H bits describe the type and size. 1089 * Rn: The base register used by the addressing mode 1090 * Rd: The register to load to or store from 1091 * 1092 * The other bits specifically mean: 1093 * I bit: If set to one the address specific pieces are immediate. Otherwise 1094 * they aren't. 1095 * P bit: If P is 0 used post-indexed addressing. If P is 1 its behavior is 1096 * based on the value of W. 1097 * U bit: If U is one the offset is added to the base otherwise subtracted 1098 * W bit: When P is one a value of W == 1 says that the resulting memory address 1099 * should be written back to the base register. The base register isn't touched 1100 * when W is zero. 1101 * 1102 * The L, S, and H bits combine in the following table: 1103 * 1104 * L | S | H | Meaning 1105 * ------------------- 1106 * 0 | 0 | 1 | store halfword 1107 * 0 | 1 | 0 | load doubleword 1108 * 0 | 1 | 1 | store doubleword 1109 * 1 | 0 | 1 | load unsigned half word 1110 * 1 | 1 | 0 | load signed byte 1111 * 1 | 1 | 1 | load signed halfword 1112 * 1113 * The final format of this is: 1114 * LDR|STR{<cond>}H|SH|SB|D <rd>, address_mode 1115 */ 1116 static int 1117 arm_dis_els(uint32_t in, char *buf, size_t buflen) 1118 { 1119 arm_cond_code_t cc; 1120 arm_reg_t rn, rd; 1121 const char *iname, *suffix; 1122 int lbit, sbit, hbit, pbit, ubit, ibit, wbit; 1123 uint8_t imm; 1124 size_t len; 1125 1126 lbit = in & ARM_ELS_LBIT_MASK; 1127 sbit = in & ARM_ELS_SBIT_MASK; 1128 hbit = in & ARM_ELS_SBIT_MASK; 1129 1130 if (lbit || (sbit && hbit == 0)) 1131 iname = "LDR"; 1132 else 1133 iname = "STR"; 1134 1135 if (sbit == 0 && hbit) 1136 suffix = "H"; 1137 else if (lbit == 0) 1138 suffix = "D"; 1139 else if (sbit && hbit == 0) 1140 suffix = "SB"; 1141 else if (sbit && hbit) 1142 suffix = "SH"; 1143 1144 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 1145 rn = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT; 1146 rd = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT; 1147 1148 len = snprintf(buf, buflen, "%s%s%s %s, ", iname, arm_cond_names[cc], 1149 suffix, arm_reg_names[rd]); 1150 if (len >= buflen) 1151 return (-1); 1152 1153 pbit = in & ARM_ELS_PBIT_MASK; 1154 ubit = in & ARM_ELS_UBIT_MASK; 1155 ibit = in & ARM_ELS_IBIT_MASK; 1156 wbit = in & ARM_ELS_WBIT_MASK; 1157 1158 if (pbit && ibit) { 1159 /* Handle A5.3.2 and A5.3.4 immediate offset and pre-indexed */ 1160 /* Bits 11-8 form the upper 4 bits of imm */ 1161 imm = (in & ARM_ELS_UP_AM_MASK) >> (ARM_ELS_UP_AM_SHIFT - 4); 1162 imm |= in & ARM_ELS_LOW_AM_MASK; 1163 len += snprintf(buf + len, buflen - len, "[%s, #%s%d]%s", 1164 arm_reg_names[rn], 1165 ubit != 0 ? "" : "-", imm, 1166 wbit != 0 ? "!" : ""); 1167 } else if (pbit && ibit == 0) { 1168 /* Handle A5.3.3 and A5.3.5 register offset and pre-indexed */ 1169 len += snprintf(buf + len, buflen - len, "[%s %s%s]%s", 1170 arm_reg_names[rn], 1171 ubit != 0 ? "" : "-", 1172 arm_reg_names[in & ARM_ELS_LOW_AM_MASK], 1173 wbit != 0 ? "!" : ""); 1174 } else if (pbit == 0 && ibit) { 1175 /* A5.3.6 Immediate post-indexed */ 1176 /* Bits 11-8 form the upper 4 bits of imm */ 1177 imm = (in & ARM_ELS_UP_AM_MASK) >> (ARM_ELS_UP_AM_SHIFT - 4); 1178 imm |= in & ARM_ELS_LOW_AM_MASK; 1179 len += snprintf(buf + len, buflen - len, "[%s], #%s%d", 1180 arm_reg_names[rn], ubit != 0 ? "" : "-", imm); 1181 } else if (pbit == 0 && ibit == 0) { 1182 /* Handle A 5.3.7 Register post-indexed */ 1183 len += snprintf(buf + len, buflen - len, "[%s], %s%s", 1184 arm_reg_names[rn], ubit != 0 ? "" : "-", 1185 arm_reg_names[in & ARM_ELS_LOW_AM_MASK]); 1186 } 1187 1188 return (len >= buflen ? -1 : 0); 1189 } 1190 1191 /* 1192 * Handle SWP and SWPB out of the extra loads/stores extensions. 1193 */ 1194 static int 1195 arm_dis_swap(uint32_t in, char *buf, size_t buflen) 1196 { 1197 arm_cond_code_t cc; 1198 arm_reg_t rn, rd, rm; 1199 1200 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 1201 rn = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT; 1202 rd = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT; 1203 rm = in & ARM_ELS_RN_MASK; 1204 1205 if (snprintf(buf, buflen, "SWP%s%s %s, %s, [%s]", 1206 arm_cond_names[cc], 1207 (in & ARM_ELS_SWAP_BYTE_MASK) ? "B" : "", 1208 arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rn]) >= 1209 buflen) 1210 return (-1); 1211 1212 return (0); 1213 } 1214 1215 /* 1216 * Handle LDREX and STREX out of the extra loads/stores extensions. 1217 */ 1218 static int 1219 arm_dis_lsexcl(uint32_t in, char *buf, size_t buflen) 1220 { 1221 arm_cond_code_t cc; 1222 arm_reg_t rn, rd, rm; 1223 int lbit; 1224 size_t len; 1225 1226 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 1227 rn = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT; 1228 rd = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT; 1229 rm = in & ARM_ELS_RN_MASK; 1230 lbit = in & ARM_ELS_LBIT_MASK; 1231 1232 len = snprintf(buf, buflen, "%s%sEX %s, ", 1233 lbit != 0 ? "LDR" : "STR", 1234 arm_cond_names[cc], arm_reg_names[rd]); 1235 if (len >= buflen) 1236 return (-1); 1237 1238 if (lbit) 1239 len += snprintf(buf + len, buflen - len, "[%s]", 1240 arm_reg_names[rn]); 1241 else 1242 len += snprintf(buf + len, buflen - len, "%s, [%s]", 1243 arm_reg_names[rm], arm_reg_names[rn]); 1244 return (len >= buflen ? -1 : 0); 1245 } 1246 1247 /* 1248 * This is designed to handle the multiplication instruction extension space. 1249 * Note that this doesn't actually cover all of the multiplication instructions 1250 * available in ARM, but all of the ones that are in this space. This includes 1251 * the following instructions: 1252 * 1253 * 1254 * There are three basic encoding formats: 1255 * 1256 * Multipy (acc): 1257 * 31 - 28|27 - 24|23|22|21|20|19-16|15-12|11-8 |7|6|5|4|3-0 1258 * [ cond | 0 |0 |0 | A |S |Rn | Rd |Rs |1|0|0|1|Rm ] 1259 * 1260 * Unsigned multipy acc acc long 1261 * 31 - 28|27 - 24|23|22|21|20|19-16|15-12|11-8 |7|6|5|4|3-0 1262 * [ cond | 0 |0 |1 |0 |0 |RdHi |RdLo |Rs |1|0|0|1|Rm ] 1263 * 1264 * Multiply (acc) long: 1265 * 31 - 28|27 - 24|23|22|21|20|19-16|15-12|11-8 |7|6|5|4|3-0 1266 * [ cond | 0 |1 |Un|A |S |RdHi| RdLo |Rs |1|0|0|1|Rm ] 1267 * 1268 * A bit: Accumulate 1269 * Un bit: Unsigned is active low, signed is active high 1270 * S bit: Indicates whethere the status register should be updated. 1271 * 1272 * MLA(S) and MUL(S) make up the first type of instructions. 1273 * UMAAL makes up the second group. 1274 * (U|S)MULL(S), (U|S)MLAL(S), Make up the third. 1275 */ 1276 static int 1277 arm_dis_extmul(uint32_t in, char *buf, size_t buflen) 1278 { 1279 arm_cond_code_t cc; 1280 arm_reg_t rd, rn, rs, rm; 1281 size_t len; 1282 1283 /* 1284 * RdHi is equal to rd here. RdLo is equal to Rn here. 1285 */ 1286 rd = (in & ARM_EMULT_RD_MASK) >> ARM_EMULT_RD_SHIFT; 1287 rn = (in & ARM_EMULT_RN_MASK) >> ARM_EMULT_RN_SHIFT; 1288 rs = (in & ARM_EMULT_RS_MASK) >> ARM_EMULT_RS_SHIFT; 1289 rm = in & ARM_EMULT_RM_MASK; 1290 1291 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 1292 1293 if ((in & ARM_EMULT_MA_MASK) == 0) { 1294 if (in & ARM_EMULT_ABIT_MASK) { 1295 len = snprintf(buf, buflen, "MLA%s%s %s, %s, %s, %s", 1296 arm_cond_names[cc], 1297 (in & ARM_EMULT_SBIT_MASK) ? "S" : "", 1298 arm_reg_names[rd], arm_reg_names[rm], 1299 arm_reg_names[rs], arm_reg_names[rs]); 1300 } else { 1301 len = snprintf(buf, buflen, "MUL%s%s %s, %s, %s", 1302 arm_cond_names[cc], 1303 (in & ARM_EMULT_SBIT_MASK) ? "S" : "", 1304 arm_reg_names[rd], arm_reg_names[rm], 1305 arm_reg_names[rs]); 1306 1307 } 1308 } else if ((in & ARM_EMULT_UMA_MASK) == ARM_EMULT_UMA_TARG) { 1309 len = snprintf(buf, buflen, "UMAAL%s %s, %s, %s, %s", 1310 arm_cond_names[cc], arm_reg_names[rn], arm_reg_names[rd], 1311 arm_reg_names[rm], arm_reg_names[rs]); 1312 } else if ((in & ARM_EMULT_MAL_MASK) == ARM_EMULT_MAL_TARG) { 1313 len = snprintf(buf, buflen, "%s%s%s%s %s, %s, %s, %s", 1314 (in & ARM_EMULT_UNBIT_MASK) ? "S" : "U", 1315 (in & ARM_EMULT_ABIT_MASK) ? "MLAL" : "MULL", 1316 arm_cond_names[cc], 1317 (in & ARM_EMULT_SBIT_MASK) ? "S" : "", 1318 arm_reg_names[rn], arm_reg_names[rd], arm_reg_names[rm], 1319 arm_reg_names[rs]); 1320 } else { 1321 /* Not a supported instruction in this space */ 1322 return (-1); 1323 } 1324 return (len >= buflen ? -1 : 0); 1325 } 1326 1327 /* 1328 * Here we handle the three different cases of moving to and from the various 1329 * status registers in both register mode and in immediate mode. 1330 */ 1331 static int 1332 arm_dis_status_regs(uint32_t in, char *buf, size_t buflen) 1333 { 1334 arm_cond_code_t cc; 1335 arm_reg_t rd, rm; 1336 uint8_t field; 1337 int imm; 1338 size_t len; 1339 1340 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 1341 1342 if ((in & ARM_CDSP_MRS_MASK) == ARM_CDSP_MRS_TARG) { 1343 rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT; 1344 if (snprintf(buf, buflen, "MRS%s %s, %s", arm_cond_names[cc], 1345 arm_reg_names[rd], 1346 (in & ARM_CDSP_STATUS_RBIT) != 0 ? "SPSR" : "CPSR") >= 1347 buflen) 1348 return (-1); 1349 return (0); 1350 } 1351 1352 field = (in & ARM_CDSP_MSR_F_MASK) >> ARM_CDSP_MSR_F_SHIFT; 1353 len = snprintf(buf, buflen, "MSR%s %s_%s, ", arm_cond_names[cc], 1354 (in & ARM_CDSP_STATUS_RBIT) != 0 ? "SPSR" : "CPSR", 1355 arm_cdsp_msr_field_names[field]); 1356 if (len >= buflen) 1357 return (-1); 1358 1359 if (in & ARM_CDSP_MSR_ISIMM_MASK) { 1360 imm = in & ARM_CDSP_MSR_IMM_MASK; 1361 imm <<= (in & ARM_CDSP_MSR_RI_MASK) >> ARM_CDSP_MSR_RI_SHIFT; 1362 len += snprintf(buf + len, buflen - len, "#%d", imm); 1363 } else { 1364 rm = in & ARM_CDSP_RM_MASK; 1365 len += snprintf(buf + len, buflen - len, "%s", 1366 arm_reg_names[rm]); 1367 } 1368 1369 return (len >= buflen ? -1 : 0); 1370 } 1371 1372 /* 1373 * Here we need to handle the Control And DSP instruction extension space. This 1374 * consists of several different instructions. Unlike other extension spaces 1375 * there isn't as much tha tis similar here as there is stuff that is different. 1376 * Oh well, that's a part of life. Instead we do a little bit of additional 1377 * parsing here. 1378 * 1379 * The first group that we separate out are the instructions that interact with 1380 * the status registers. Those are handled in their own function. 1381 */ 1382 static int 1383 arm_dis_cdsp_ext(uint32_t in, char *buf, size_t buflen) 1384 { 1385 uint16_t imm, op; 1386 arm_cond_code_t cc; 1387 arm_reg_t rd, rm, rn, rs; 1388 size_t len; 1389 1390 if ((in & ARM_CDSP_STATUS_MASK) == ARM_CDSP_STATUS_TARG) 1391 return (arm_dis_status_regs(in, buf, buflen)); 1392 1393 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 1394 1395 /* 1396 * This gets the Branch/exchange as well as the Branch and link/exchange 1397 * pieces. These generally also transform the instruction set into 1398 * something we can't actually disassemble. Here the lower mask and 1399 * target is the opposite. eg. the target bits are not what we want. 1400 */ 1401 if ((in & ARM_CDSP_BEX_UP_MASK) == ARM_CDSP_BEX_UP_TARG && 1402 (in & ARM_CDSP_BEX_LOW_MASK) != ARM_CDSP_BEX_NLOW_TARG) { 1403 rm = in & ARM_CDSP_RM_MASK; 1404 imm = (in & ARM_CDSP_BEX_TYPE_MASK) >> ARM_CDSP_BEX_TYPE_SHIFT; 1405 if (snprintf(buf, buflen, "B%s%s %s", 1406 imm == ARM_CDSP_BEX_TYPE_X ? "X" : 1407 imm == ARM_CDSP_BEX_TYPE_J ? "XJ" : "LX", 1408 arm_cond_names[cc], arm_reg_names[rm]) >= buflen) 1409 return (-1); 1410 return (0); 1411 } 1412 1413 /* Count leading zeros */ 1414 if ((in & ARM_CDSP_CLZ_MASK) == ARM_CDSP_CLZ_TARG) { 1415 rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT; 1416 rm = in & ARM_CDSP_RM_MASK; 1417 if (snprintf(buf, buflen, "CLZ%s %s, %s", arm_cond_names[cc], 1418 arm_reg_names[rd], arm_reg_names[rm]) >= buflen) 1419 return (-1); 1420 return (0); 1421 } 1422 1423 if ((in & ARM_CDSP_SAT_MASK) == ARM_CDSP_SAT_TARG) { 1424 rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT; 1425 rn = (in & ARM_CDSP_RN_MASK) >> ARM_CDSP_RN_SHIFT; 1426 rm = in & ARM_CDSP_RM_MASK; 1427 imm = (in & ARM_CDSP_SAT_OP_MASK) >> ARM_CDSP_SAT_OP_SHIFT; 1428 if (snprintf(buf, buflen, "Q%s%s %s, %s, %s", 1429 arm_cdsp_sat_opnames[imm], arm_cond_names[cc], 1430 arm_reg_names[rd], arm_reg_names[rm], 1431 arm_reg_names[rn]) >= buflen) 1432 return (-1); 1433 return (0); 1434 } 1435 1436 /* 1437 * Breakpoint instructions are a bit different. While they are in the 1438 * conditional instruction namespace, they actually aren't defined to 1439 * take a condition. That's just how it rolls. The breakpoint is a 1440 * 16-bit value. The upper 12 bits are stored together and the lower 1441 * four together. 1442 */ 1443 if ((in & ARM_CDSP_BKPT_MASK) == ARM_CDSP_BKPT_TARG) { 1444 if (cc != ARM_COND_NACC) 1445 return (-1); 1446 imm = (in & ARM_CDSP_BKPT_UIMM_MASK) >> 1447 ARM_CDSP_BKPT_UIMM_SHIFT; 1448 imm <<= 4; 1449 imm |= (in & ARM_CDSP_BKPT_LIMM_MASK); 1450 if (snprintf(buf, buflen, "BKPT %d", imm) >= buflen) 1451 return (1); 1452 return (0); 1453 } 1454 1455 /* 1456 * Here we need to handle another set of multiplies. Specifically the 1457 * Signed multiplies. This is SMLA<x><y>, SMLAW<y>, SMULW<y>, 1458 * SMLAL<x><y>, SMUL<x><y>. These instructions all follow the form: 1459 * 1460 * 31 - 28|27-25|24|23|22-21|20|19-16|15-12|11 - 8|7|6|5|4|3-0 1461 * [ cond | 0 | 1| 0| op. | 0|Rn |Rd |Rs |1|y|x|0|Rm ] 1462 * 1463 * If x is one a T is used for that part of the name. Otherwise a B is. 1464 * The same holds true for y. 1465 * 1466 * These instructions map to the following opcodes: 1467 * SMLA<x><y>: 00, 1468 * SMLAW<y>: 01 and x is zero, 1469 * SMULW<y>: 01 and x is one , 1470 * SMLAL<x><y>: 10, 1471 * SMUL<xy><y>: 11 1472 */ 1473 if ((in & ARM_CDSP_SMUL_MASK) == ARM_CDSP_SMUL_TARG) { 1474 rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT; 1475 rn = (in & ARM_CDSP_RN_MASK) >> ARM_CDSP_RN_SHIFT; 1476 rs = (in & ARM_CDSP_RS_MASK) >> ARM_CDSP_RS_SHIFT; 1477 rm = in & ARM_CDSP_RM_MASK; 1478 op = (in & ARM_CDSP_SMUL_OP_MASK) >> ARM_CDSP_SMUL_OP_SHIFT; 1479 1480 switch (op) { 1481 case 0: 1482 len = snprintf(buf, buflen, "SMLA%s%s%s %s, %s, %s, %s", 1483 (in & ARM_CDSP_SMUL_X_MASK) != 0 ? "T" : "B", 1484 (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "T" : "B", 1485 arm_cond_names[cc], arm_reg_names[rd], 1486 arm_reg_names[rm], arm_reg_names[rs], 1487 arm_reg_names[rn]); 1488 break; 1489 case 1: 1490 if (in & ARM_CDSP_SMUL_X_MASK) { 1491 len = snprintf(buf, buflen, 1492 "SMULW%s%s %s, %s, %s", 1493 (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "T" : 1494 "B", arm_cond_names[cc], arm_reg_names[rd], 1495 arm_reg_names[rm], arm_reg_names[rs]); 1496 } else { 1497 len = snprintf(buf, buflen, 1498 "SMLAW%s%s %s, %s, %s %s", 1499 (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "T" : 1500 "B", arm_cond_names[cc], arm_reg_names[rd], 1501 arm_reg_names[rm], arm_reg_names[rs], 1502 arm_reg_names[rn]); 1503 } 1504 break; 1505 case 2: 1506 len = snprintf(buf, buflen, 1507 "SMLAL%s%s%s %s, %s, %s, %s", 1508 (in & ARM_CDSP_SMUL_X_MASK) != 0 ? "T" : "B", 1509 (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "T" : "B", 1510 arm_cond_names[cc], arm_reg_names[rd], 1511 arm_reg_names[rn], arm_reg_names[rm], 1512 arm_reg_names[rs]); 1513 break; 1514 case 3: 1515 len = snprintf(buf, buflen, "SMUL%s%s%s %s, %s, %s", 1516 (in & ARM_CDSP_SMUL_X_MASK) != 0 ? "T" : "B", 1517 (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "T" : "B", 1518 arm_cond_names[cc], arm_reg_names[rd], 1519 arm_reg_names[rm], arm_reg_names[rs]); 1520 break; 1521 default: 1522 return (-1); 1523 } 1524 return (len >= buflen ? -1 : 0); 1525 } 1526 1527 /* 1528 * If we got here then this is some other instructin we don't know 1529 * about in the instruction extensino space. 1530 */ 1531 return (-1); 1532 } 1533 1534 /* 1535 * Coprocessor double register transfers 1536 * 1537 * MCRR: 1538 * 31 - 28|27-25|24|23|22|21|20|19-16|15-12|11-8|7-4|3-0 1539 * [ cond |1 1 0| 0| 0| 1| 0| 0| Rn | Rd |cp #|op |CRm 1540 * 1541 * MRRC: 1542 * 31 - 28|27-25|24|23|22|21|20|19-16|15-12|11-8|7-4|3-0 1543 * [ cond |1 1 0| 0| 0| 1| 0| 1| Rn | Rd |cp #|op |CRm 1544 * 1545 */ 1546 static int 1547 arm_dis_coproc_drt(uint32_t in, char *buf, size_t buflen) 1548 { 1549 arm_cond_code_t cc; 1550 arm_reg_t rd, rn, rm; 1551 uint8_t coproc, op; 1552 const char *ccn; 1553 size_t len; 1554 1555 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 1556 coproc = (in & ARM_COPROC_NUM_MASK) >> ARM_COPROC_NUM_SHIFT; 1557 rn = (in & ARM_COPROC_RN_MASK) >> ARM_COPROC_RN_SHIFT; 1558 rd = (in & ARM_COPROC_RD_MASK) >> ARM_COPROC_RD_SHIFT; 1559 rm = in & ARM_COPROC_RM_MASK; 1560 op = (in & ARM_COPROC_DRT_OP_MASK) >> ARM_COPROC_DRT_OP_SHIFT; 1561 1562 if (cc == ARM_COND_NACC) 1563 ccn = "2"; 1564 else 1565 ccn = arm_cond_names[cc]; 1566 1567 len = snprintf(buf, buflen, "%s%s %s, #%d, %s, %s, C%s", 1568 (in & ARM_COPROC_DRT_DIR_MASK) != 0 ? "MRRC" : "MCRR", 1569 ccn, arm_coproc_names[coproc], op, arm_reg_names[rd], 1570 arm_reg_names[rn], arm_reg_names[rm]); 1571 return (len >= buflen ? -1 : 0); 1572 } 1573 1574 /* 1575 * This serves as both the entry point for the normal load and stores as well as 1576 * the double register transfers (MCRR and MRCC). If it is a register transfer 1577 * then we quickly send it off. 1578 * LDC: 1579 * 31 - 28|27-25|24|23|22|21|20|19-16|15-12|11 - 8|7 - 0 1580 * [ cond |1 1 0| P| U| N| W| L| Rn | CRd | cp # | off ] 1581 * 1582 * STC: 1583 * 31 - 28|27-25|24|23|22|21|20|19-16|15-12|11 - 8|7 - 0 1584 * [ cond |1 1 0| P| U| N| W| L| Rn | CRd | cp # | off ] 1585 * 1586 * Here the bits mean: 1587 * 1588 * P bit: If P is zero, it is post-indexed or unindexed based on W. If P is 1 1589 * then it is offset-addressing or pre-indexed based on W again. 1590 * 1591 * U bit: If U is positive then the offset if added, subtracted otherwise.. Note 1592 * that if P is zero and W is zero, U must be one. 1593 * 1594 * N bit: If set that means that we have a Long size, this bit is set by the L 1595 * suffix, not to be confused with the L bit. 1596 * 1597 * W bit: If W is one then the memory address is written back to the base 1598 * register. Further W = 0 and P = 0 is unindexed addressing. W = 1, P = 0 is 1599 * post-indexed. W = 0, P = 1 is offset addressing and W = 1, P = 1 is 1600 * pre-indexed. 1601 */ 1602 static int 1603 arm_dis_coproc_lsdrt(uint32_t in, char *buf, size_t buflen) 1604 { 1605 arm_cond_code_t cc; 1606 arm_reg_t rn, rd; 1607 uint8_t coproc; 1608 uint32_t imm; 1609 int pbit, ubit, nbit, wbit, lbit; 1610 const char *ccn; 1611 size_t len; 1612 1613 if ((in & ARM_COPROC_DRT_MASK) == ARM_COPROC_DRT_TARG) 1614 return (arm_dis_coproc_drt(in, buf, buflen)); 1615 1616 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 1617 coproc = (in & ARM_COPROC_NUM_MASK) >> ARM_COPROC_NUM_SHIFT; 1618 rn = (in & ARM_COPROC_RN_MASK) >> ARM_COPROC_RN_SHIFT; 1619 rd = (in & ARM_COPROC_RD_MASK) >> ARM_COPROC_RD_SHIFT; 1620 imm = in & ARM_COPROC_LS_IMM_MASK; 1621 1622 pbit = in & ARM_COPROC_LS_P_MASK; 1623 ubit = in & ARM_COPROC_LS_U_MASK; 1624 nbit = in & ARM_COPROC_LS_N_MASK; 1625 wbit = in & ARM_COPROC_LS_W_MASK; 1626 lbit = in & ARM_COPROC_LS_L_MASK; 1627 1628 if (cc == ARM_COND_NACC) 1629 ccn = "2"; 1630 else 1631 ccn = arm_cond_names[cc]; 1632 1633 len = snprintf(buf, buflen, "%s%s%s %s, C%s, ", 1634 lbit != 0 ? "LDC" : "STC", ccn, nbit != 0 ? "L" : "", 1635 arm_coproc_names[coproc], arm_reg_names[rd]); 1636 if (len >= buflen) 1637 return (-1); 1638 1639 if (pbit != 0) { 1640 imm *= 4; 1641 len += snprintf(buf + len, buflen - len, "[%s, #%s%d]%s", 1642 arm_reg_names[rn], 1643 ubit != 0 ? "" : "-", imm, 1644 wbit != 0 ? "!" : ""); 1645 } else if (wbit != 0) { 1646 imm *= 4; 1647 len += snprintf(buf + len, buflen - len, "[%s], #%s%d", 1648 arm_reg_names[rn], ubit != 0 ? "" : "-", imm); 1649 } else { 1650 len += snprintf(buf + len, buflen - len, "[%s], { %d }", 1651 arm_reg_names[rn], imm); 1652 } 1653 return (len >= buflen ? -1 : 0); 1654 } 1655 1656 /* 1657 * Here we tell a coprocessor to do data processing 1658 * 1659 * CDP: 1660 * 31 - 28|27 - 24|23-20|19-16|15-12|11 - 8|7 - 5|4|3-0 1661 * [ cond |1 1 1 0| op_1| CRn | CRd | cp # | op_2|0|CRm ] 1662 */ 1663 static int 1664 arm_dis_coproc_dp(uint32_t in, char *buf, size_t buflen) 1665 { 1666 arm_cond_code_t cc; 1667 arm_reg_t rn, rd, rm; 1668 uint8_t op1, op2, coproc; 1669 const char *ccn; 1670 1671 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 1672 coproc = (in & ARM_COPROC_NUM_MASK) >> ARM_COPROC_NUM_SHIFT; 1673 rn = (in & ARM_COPROC_RN_MASK) >> ARM_COPROC_RN_SHIFT; 1674 rd = (in & ARM_COPROC_RD_MASK) >> ARM_COPROC_RD_SHIFT; 1675 rm = in & ARM_COPROC_RM_MASK; 1676 op1 = (in & ARM_COPROC_CDP_OP1_MASK) >> ARM_COPROC_CDP_OP1_SHIFT; 1677 op2 = (in & ARM_COPROC_CDP_OP2_MASK) >> ARM_COPROC_CDP_OP2_SHIFT; 1678 1679 /* 1680 * This instruction is valid with the undefined condition code. When it 1681 * does that, the instruction is intead CDP2 as opposed to CDP. 1682 */ 1683 if (cc == ARM_COND_NACC) 1684 ccn = "2"; 1685 else 1686 ccn = arm_cond_names[cc]; 1687 1688 if (snprintf(buf, buflen, "CDP%s %s, #%d, C%s, C%s, C%s, #%d", ccn, 1689 arm_coproc_names[coproc], op1, arm_reg_names[rd], 1690 arm_reg_names[rn], arm_reg_names[rm], op2) >= buflen) 1691 return (-1); 1692 1693 return (0); 1694 } 1695 1696 /* 1697 * Here we handle coprocesser single register transfers. 1698 * 1699 * MCR: 1700 * 31 - 28|27 - 24|23-21|20|19-16|15-12|11 - 8|7 - 5|4|3-0 1701 * [ cond |1 1 1 0| op_1| 0| CRn | Rd | cp # | op_2|1|CRm ] 1702 * 1703 * MRC: 1704 * 31 - 28|27 - 24|23-21|20|19-16|15-12|11 - 8|7 - 5|4|3-0 1705 * [ cond |1 1 1 0| op_1| 1| CRn | Rd | cp # | op_2|1|CRm ] 1706 */ 1707 static int 1708 arm_dis_coproc_rt(uint32_t in, char *buf, size_t buflen) 1709 { 1710 arm_cond_code_t cc; 1711 arm_reg_t rn, rd, rm; 1712 uint8_t op1, op2, coproc; 1713 const char *ccn; 1714 size_t len; 1715 1716 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 1717 coproc = (in & ARM_COPROC_NUM_MASK) >> ARM_COPROC_NUM_SHIFT; 1718 rn = (in & ARM_COPROC_RN_MASK) >> ARM_COPROC_RN_SHIFT; 1719 rd = (in & ARM_COPROC_RD_MASK) >> ARM_COPROC_RD_SHIFT; 1720 rm = in & ARM_COPROC_RM_MASK; 1721 op1 = (in & ARM_COPROC_CRT_OP1_MASK) >> ARM_COPROC_CRT_OP1_SHIFT; 1722 op2 = (in & ARM_COPROC_CRT_OP2_MASK) >> ARM_COPROC_CRT_OP2_SHIFT; 1723 1724 if (cc == ARM_COND_NACC) 1725 ccn = "2"; 1726 else 1727 ccn = arm_cond_names[cc]; 1728 1729 len = snprintf(buf, buflen, "%s%s %s, #%d, %s, C%s, C%s", 1730 (in & ARM_COPROC_CRT_DIR_MASK) != 0 ? "MRC" : "MCR", ccn, 1731 arm_coproc_names[coproc], op1, arm_reg_names[rd], 1732 arm_reg_names[rn], arm_reg_names[rm]); 1733 if (len >= buflen) 1734 return (-1); 1735 1736 if (op2 != 0) 1737 if (snprintf(buf + len, buflen - len, ", #%d", op2) >= 1738 buflen - len) 1739 return (-1); 1740 return (0); 1741 } 1742 1743 /* 1744 * Here we handle the set of unconditional instructions. 1745 */ 1746 static int 1747 arm_dis_uncond_insn(uint32_t in, char *buf, size_t buflen) 1748 { 1749 int imm, sc; 1750 arm_reg_t rn, rm; 1751 size_t len; 1752 1753 /* 1754 * The CPS instruction is a bit complicated. It has the following big 1755 * pattern which maps to a few different ways to use it: 1756 * 1757 * 1758 * 31-28|27-25|24|23-20|19-18|17 |16|15-9|8|7|6|5|4-0 1759 * 1 | 0 | 1| 0 |imod|mmod| 0|SBZ |A|I|F|0|mode 1760 * 1761 * CPS<effect> <iflags> {, #<mode> } 1762 * CPS #<mode> 1763 * 1764 * effect: determines what to do with the A, I, F interrupt bits in the 1765 * CPSR. effect is encoded in the imod field. It is either enable 1766 * interrupts 0b10 or disable interrupts 0b11. Recall that interrupts 1767 * are active low in the CPSR. If effect is not specified then this is 1768 * strictly a mode change which is required. 1769 * 1770 * A, I, F: If effect is specified then the bits which are high are 1771 * modified by the instruction. 1772 * 1773 * mode: Specifies a mode to change to. mmod will be 1 if mode is set. 1774 * 1775 */ 1776 if ((in & ARM_UNI_CPS_MASK) == ARM_UNI_CPS_TARG) { 1777 imm = (in & ARM_UNI_CPS_IMOD_MASK) > ARM_UNI_CPS_IMOD_SHIFT; 1778 1779 /* Ob01 is not a valid value for the imod */ 1780 if (imm == 1) 1781 return (-1); 1782 1783 if (imm != 0) 1784 len = snprintf(buf, buflen, "CPS%s %s%s%s%s", 1785 imm == 2 ? "IE" : "ID", 1786 (in & ARM_UNI_CPS_A_MASK) ? "a" : "", 1787 (in & ARM_UNI_CPS_I_MASK) ? "i" : "", 1788 (in & ARM_UNI_CPS_F_MASK) ? "f" : "", 1789 (in & ARM_UNI_CPS_MMOD_MASK) ? " ," : ""); 1790 else 1791 len = snprintf(buf, buflen, "CPS "); 1792 if (len >= buflen) 1793 return (-1); 1794 1795 if (in & ARM_UNI_CPS_MMOD_MASK) 1796 if (snprintf(buf + len, buflen - len, "#%d", 1797 in & ARM_UNI_CPS_MODE_MASK) >= buflen - len) 1798 return (-1); 1799 return (0); 1800 } 1801 1802 if ((in & ARM_UNI_SE_MASK) == ARM_UNI_SE_TARG) { 1803 if (snprintf(buf, buflen, "SETEND %s", 1804 (in & ARM_UNI_SE_BE_MASK) ? "BE" : "LE") >= buflen) 1805 return (-1); 1806 return (0); 1807 } 1808 1809 /* 1810 * The cache preload is like a load, but it has a much simpler set of 1811 * constraints. The only valid bits that you can transform are the I and 1812 * the U bits. We have to use pre-indexed addressing. This means that we 1813 * only have the U bit and the I bit. See arm_dis_ldstr for a full 1814 * explanation of what's happening here. 1815 */ 1816 if ((in & ARM_UNI_PLD_MASK) == ARM_UNI_PLD_TARG) { 1817 rn = (in & ARM_LS_RN_MASK) >> ARM_LS_RN_SHIFT; 1818 if ((in & ARM_LS_IBIT_MASK) == 0) { 1819 if (snprintf(buf, buflen, "PLD [%s, #%s%d", 1820 arm_reg_names[rn], 1821 (in & ARM_LS_UBIT_MASK) != 0 ? "" : "-", 1822 in & ARM_LS_IMM_MASK) >= buflen) 1823 return (-1); 1824 return (0); 1825 } 1826 1827 rm = in & ARM_LS_REG_RM_MASK; 1828 len = snprintf(buf, buflen, "PLD [%s, %s%s", arm_reg_names[rn], 1829 (in & ARM_LS_UBIT_MASK) != 0 ? "" : "-", 1830 arm_reg_names[rm]); 1831 if (len >= buflen) 1832 return (-1); 1833 1834 if ((in & ARM_LS_REG_NRM_MASK) != 0) { 1835 imm = (in & ARM_LS_SCR_SIMM_MASK) >> 1836 ARM_LS_SCR_SIMM_SHIFT; 1837 sc = (in & ARM_LS_SCR_SCODE_MASK) >> 1838 ARM_LS_SCR_SCODE_SHIFT; 1839 1840 if (imm == 0 && sc == DPI_S_ROR) 1841 sc = DPI_S_RRX; 1842 1843 len += snprintf(buf + len, buflen - len, "%s", 1844 arm_dpi_shifts[sc]); 1845 if (len >= buflen) 1846 return (-1); 1847 if (sc != DPI_S_RRX) { 1848 len += snprintf(buf + len, buflen - len, 1849 " #%d", imm); 1850 if (len >= buflen) 1851 return (-1); 1852 } 1853 } 1854 if (snprintf(buf + len, buflen - len, "]") >= buflen - len) 1855 return (-1); 1856 return (0); 1857 } 1858 1859 /* 1860 * This is a special case of STM, but it works across chip modes. 1861 */ 1862 if ((in & ARM_UNI_SRS_MASK) == ARM_UNI_SRS_TARG) { 1863 imm = (in & ARM_LSM_ADDR_MASK) >> ARM_LSM_ADDR_SHIFT; 1864 if (snprintf(buf, buflen, "SRS%s #%d%s", 1865 arm_lsm_mode_names[imm], 1866 in & ARM_UNI_SRS_MODE_MASK, 1867 (in & ARM_UNI_SRS_WBIT_MASK) != 0 ? "!" : "") >= buflen) 1868 return (-1); 1869 return (0); 1870 } 1871 1872 /* 1873 * RFE is a return from exception instruction that is similar to the LDM 1874 * and STM, but a bit different. 1875 */ 1876 if ((in & ARM_UNI_RFE_MASK) == ARM_UNI_RFE_TARG) { 1877 imm = (in & ARM_LSM_ADDR_MASK) >> ARM_LSM_ADDR_SHIFT; 1878 rn = (in & ARM_LS_RN_MASK) >> ARM_LS_RN_SHIFT; 1879 if (snprintf(buf, buflen, "RFE%s %s%s", arm_lsm_mode_names[imm], 1880 arm_reg_names[rn], 1881 (in & ARM_UNI_RFE_WBIT_MASK) != 0 ? "!" : "") >= buflen) 1882 return (-1); 1883 return (0); 1884 } 1885 1886 if ((in & ARM_UNI_BLX_MASK) == ARM_UNI_BLX_TARG) { 1887 if (snprintf(buf, buflen, "BLX %d", 1888 in & ARM_UNI_BLX_IMM_MASK) >= buflen) 1889 return (-1); 1890 return (0); 1891 } 1892 1893 if ((in & ARM_UNI_CODRT_MASK) == ARM_UNI_CODRT_TARG) { 1894 return (arm_dis_coproc_lsdrt(in, buf, buflen)); 1895 } 1896 1897 if ((in & ARM_UNI_CORT_MASK) == ARM_UNI_CORT_TARG) { 1898 return (arm_dis_coproc_rt(in, buf, buflen)); 1899 } 1900 1901 if ((in & ARM_UNI_CODP_MASK) == ARM_UNI_CORT_TARG) { 1902 return (arm_dis_coproc_dp(in, buf, buflen)); 1903 } 1904 1905 /* 1906 * An undefined or illegal instruction 1907 */ 1908 return (-1); 1909 } 1910 1911 /* 1912 * Disassemble B and BL instructions. The instruction is given a 24-bit two's 1913 * complement value as an offset address. This value gets sign extended to 30 1914 * bits and then shifted over two bits. This is then added to the PC + 8. So, 1915 * instead of dispalying an absolute address, we're going to display the delta 1916 * that the instruction has instead. 1917 */ 1918 static int 1919 arm_dis_branch(dis_handle_t *dhp, uint32_t in, char *buf, size_t buflen) 1920 { 1921 uint32_t addr; 1922 arm_cond_code_t cc; 1923 size_t len; 1924 1925 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 1926 addr = in & ARM_BRANCH_IMM_MASK; 1927 if (in & ARM_BRANCH_SIGN_MASK) 1928 addr |= ARM_BRANCH_NEG_SIGN; 1929 else 1930 addr &= ARM_BRANCH_POS_SIGN; 1931 addr <<= 2; 1932 if ((len = snprintf(buf, buflen, "B%s%s %d", 1933 (in & ARM_BRANCH_LBIT_MASK) != 0 ? "L" : "", 1934 arm_cond_names[cc], (int)addr)) >= buflen) 1935 return (-1); 1936 1937 /* Per the ARM manuals, we have to account for the extra 8 bytes here */ 1938 if (dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int)addr + 8, NULL, 0, 1939 NULL, NULL) == 0) { 1940 len += snprintf(buf + len, buflen - len, "\t<"); 1941 if (len >= buflen) 1942 return (-1); 1943 dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int)addr + 8, 1944 buf + len, buflen - len, NULL, NULL); 1945 strlcat(buf, ">", buflen); 1946 } 1947 1948 return (0); 1949 } 1950 1951 /* 1952 * There are six instructions that are covered here: ADD16, ADDSUBX, SUBADDX, 1953 * SUB16, ADD8, and SUB8. They can hae the following variations: S, Q, SH, U, 1954 * UQ, and UH. It has two differnt sets of bits to determine the opcode: 22-20 1955 * and then 7-5. 1956 * 1957 * These instructions have the general form of: 1958 * 1959 * 31 - 28|27-25|24|23|22-20|19-16|15-12|11 - 8|7-5|4|3-0 1960 * [ cond |0 1 1| 0| 0| opP |Rn |Rd |SBO |opI|1|Rm ] 1961 * 1962 * Here we use opP to refer to the prefix of the instruction, eg. S, Q, etc. 1963 * Where as opI refers to which instruction it is, eg. ADD16, ADD8, etc. We use 1964 * string tables for both of these in arm_padd_p_names and arm_padd_i_names. If 1965 * there is an empty entry that means that the instruction in question doesn't 1966 * exist. 1967 */ 1968 static int 1969 arm_dis_padd(uint32_t in, char *buf, size_t buflen) 1970 { 1971 arm_reg_t rn, rd, rm; 1972 arm_cond_code_t cc; 1973 uint8_t opp, opi; 1974 const char *pstr, *istr; 1975 1976 opp = (in & ARM_MEDIA_OP1_MASK) >> ARM_MEDIA_OP1_SHIFT; 1977 opi = (in & ARM_MEDIA_OP2_MASK) >> ARM_MEDIA_OP2_SHIFT; 1978 1979 pstr = arm_padd_p_names[opp]; 1980 istr = arm_padd_i_names[opi]; 1981 1982 if (pstr == NULL || istr == NULL) 1983 return (-1); 1984 1985 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 1986 rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT; 1987 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; 1988 rm = in & ARM_MEDIA_RM_MASK; 1989 1990 if (snprintf(buf, buflen, "%s%%s %s, %s, %s", pstr, istr, 1991 arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rn], 1992 arm_reg_names[rm]) >= buflen) 1993 return (-1); 1994 return (0); 1995 } 1996 1997 /* 1998 * Disassemble the extend instructions from ARMv6. There are six instructions: 1999 * 2000 * XTAB16, XTAB, XTAH, XTB16, XTB, XTFH. These can exist with one of the 2001 * following prefixes: S, U. The opcode exists in bits 22-20. We have the 2002 * following rules from there: 2003 * 2004 * If bit 22 is one then we are using the U prefix, otherwise the S prefix. Then 2005 * we have the following opcode maps in the lower two bits: 2006 * XTAB16 00 iff Rn != 0xf 2007 * XTAB 10 iff Rn != 0xf 2008 * XTAH 11 iff Rn != 0xf 2009 * XTB16 00 iff Rn = 0xf 2010 * XTB 10 iff Rn = 0xf 2011 * XTH 11 iff Rn = 0xf 2012 */ 2013 static int 2014 arm_dis_extend(uint32_t in, char *buf, size_t buflen) 2015 { 2016 uint8_t op, rot; 2017 int sbit; 2018 arm_cond_code_t cc; 2019 arm_reg_t rn, rm, rd; 2020 const char *opn; 2021 size_t len; 2022 2023 2024 rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT; 2025 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; 2026 rm = in & ARM_MEDIA_RM_MASK; 2027 op = (in & ARM_MEDIA_SZE_OP_MASK) >> ARM_MEDIA_SZE_OP_SHIFT; 2028 rot = (in & ARM_MEDIA_SZE_ROT_MASK) >> ARM_MEDIA_SZE_ROT_SHIFT; 2029 sbit = in & ARM_MEDIA_SZE_S_MASK; 2030 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 2031 2032 switch (op) { 2033 case 0x0: 2034 opn = rn == ARM_REG_R15 ? "XTAB16" : "XTB16"; 2035 break; 2036 case 0x2: 2037 opn = rn == ARM_REG_R15 ? "XTAB" : "XTB"; 2038 break; 2039 case 0x3: 2040 opn = rn == ARM_REG_R15 ? "XTAH" : "XTH"; 2041 break; 2042 default: 2043 return (-1); 2044 break; 2045 } 2046 2047 if (rn == ARM_REG_R15) { 2048 len = snprintf(buf, buflen, "%s%s%s %s, %s", 2049 sbit != 0 ? "U" : "S", 2050 opn, arm_cond_names[cc], arm_reg_names[rd], 2051 arm_reg_names[rn]); 2052 } else { 2053 len = snprintf(buf, buflen, "%s%s%s %s, %s, %s", 2054 sbit != 0 ? "U" : "S", 2055 opn, arm_cond_names[cc], arm_reg_names[rd], 2056 arm_reg_names[rn], arm_reg_names[rm]); 2057 } 2058 2059 if (len >= buflen) 2060 return (-1); 2061 2062 if (snprintf(buf + len, buflen - len, "%s", 2063 arm_extend_rot_names[rot]) >= buflen - len) 2064 return (-1); 2065 return (0); 2066 } 2067 2068 /* 2069 * The media instructions and extensions can be divided into different groups of 2070 * instructions. We first use bits 23 and 24 to figure out where to send it. We 2071 * call this group of bits the l1 mask. 2072 */ 2073 static int 2074 arm_dis_media(uint32_t in, char *buf, size_t buflen) 2075 { 2076 uint8_t l1, op1, op2; 2077 arm_cond_code_t cc; 2078 arm_reg_t rd, rn, rs, rm; 2079 int xbit; 2080 size_t len; 2081 2082 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 2083 l1 = (in & ARM_MEDIA_L1_MASK) >> ARM_MEDIA_L1_SHIFT; 2084 switch (l1) { 2085 case 0x0: 2086 return (arm_dis_padd(in, buf, buflen)); 2087 break; 2088 case 0x1: 2089 if ((in & ARM_MEDIA_HPACK_MASK) == ARM_MEDIA_HPACK_TARG) { 2090 rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT; 2091 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; 2092 rm = in & ARM_MEDIA_RM_MASK; 2093 op1 = (in & ARM_MEDIA_HPACK_SHIFT_MASK) >> 2094 ARM_MEDIA_HPACK_SHIFT_IMM; 2095 len = snprintf(buf, buflen, "%s%s %s, %s, %s", 2096 (in & ARM_MEDIA_HPACK_OP_MASK) != 0 ? 2097 "PKHTB" : "PKHBT", arm_cond_names[cc], 2098 arm_reg_names[rd], arm_reg_names[rn], 2099 arm_reg_names[rd]); 2100 if (len >= buflen) 2101 return (-1); 2102 2103 if (op1 != 0) { 2104 if (in & ARM_MEDIA_HPACK_OP_MASK) 2105 len += snprintf(buf + len, buflen - len, 2106 ", ASR %d", op1); 2107 else 2108 len += snprintf(buf + len, buflen - len, 2109 ", LSL %d", op1); 2110 } 2111 return (len >= buflen ? -1 : 0); 2112 } 2113 2114 if ((in & ARM_MEDIA_WSAT_MASK) == ARM_MEDIA_WSAT_TARG) { 2115 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; 2116 rm = in & ARM_MEDIA_RM_MASK; 2117 op1 = (in & ARM_MEDIA_SAT_IMM_MASK) >> 2118 ARM_MEDIA_SAT_IMM_SHIFT; 2119 op2 = (in & ARM_MEDIA_SAT_SHI_MASK) >> 2120 ARM_MEDIA_SAT_SHI_SHIFT; 2121 len = snprintf(buf, buflen, "%s%s %s, #%d, %s", 2122 (in & ARM_MEDIA_SAT_U_MASK) != 0 ? "USAT" : "SSAT", 2123 arm_cond_names[cc], arm_reg_names[rd], op1, 2124 arm_reg_names[rm]); 2125 2126 if (len >= buflen) 2127 return (-1); 2128 2129 /* 2130 * The shift is optional in the assembler and encoded as 2131 * LSL 0. However if we get ASR 0, that means ASR #32. 2132 * An ARM_MEDIA_SAT_STYPE_MASK of 0 is LSL, 1 is ASR. 2133 */ 2134 if (op2 != 0 || (in & ARM_MEDIA_SAT_STYPE_MASK) == 1) { 2135 if (op2 == 0) 2136 op2 = 32; 2137 if (snprintf(buf + len, buflen - len, 2138 ", %s #%d", 2139 (in & ARM_MEDIA_SAT_STYPE_MASK) != 0 ? 2140 "ASR" : "LSL", op2) >= buflen - len) 2141 return (-1); 2142 } 2143 return (0); 2144 } 2145 2146 if ((in & ARM_MEDIA_PHSAT_MASK) == ARM_MEDIA_PHSAT_TARG) { 2147 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; 2148 rm = in & ARM_MEDIA_RM_MASK; 2149 op1 = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT; 2150 if (snprintf(buf, buflen, "%s%s %s, #%d, %s", 2151 (in & ARM_MEDIA_SAT_U_MASK) != 0 ? 2152 "USAT16" : "SSAT16", 2153 arm_cond_names[cc], arm_reg_names[rd], op1, 2154 arm_reg_names[rm]) >= buflen) 2155 return (-1); 2156 return (0); 2157 } 2158 2159 if ((in & ARM_MEDIA_REV_MASK) == ARM_MEDIA_REV_TARG) { 2160 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; 2161 rm = in & ARM_MEDIA_RM_MASK; 2162 if (snprintf(buf, buflen, "REV%s %s, %s", 2163 arm_cond_names[cc], arm_reg_names[rd], 2164 arm_reg_names[rd]) >= buflen) 2165 return (-1); 2166 return (0); 2167 } 2168 2169 if ((in & ARM_MEDIA_BRPH_MASK) == ARM_MEDIA_BRPH_TARG) { 2170 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; 2171 rm = in & ARM_MEDIA_RM_MASK; 2172 if (snprintf(buf, buflen, "REV16%s %s, %s", 2173 arm_cond_names[cc], arm_reg_names[rd], 2174 arm_reg_names[rd]) >= buflen) 2175 return (-1); 2176 return (0); 2177 } 2178 2179 if ((in & ARM_MEDIA_BRSH_MASK) == ARM_MEDIA_BRSH_TARG) { 2180 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; 2181 rm = in & ARM_MEDIA_RM_MASK; 2182 if (snprintf(buf, buflen, "REVSH%s %s, %s", 2183 arm_cond_names[cc], arm_reg_names[rd], 2184 arm_reg_names[rd]) >= buflen) 2185 return (-1); 2186 return (0); 2187 } 2188 2189 if ((in & ARM_MEDIA_SEL_MASK) == ARM_MEDIA_SEL_TARG) { 2190 rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT; 2191 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; 2192 rm = in & ARM_MEDIA_RM_MASK; 2193 if (snprintf(buf, buflen, "SEL%s %s, %s, %s", 2194 arm_cond_names[cc], arm_reg_names[rd], 2195 arm_reg_names[rn], arm_reg_names[rm]) >= buflen) 2196 return (-1); 2197 return (0); 2198 } 2199 2200 if ((in & ARM_MEDIA_SZE_MASK) == ARM_MEDIA_SZE_TARG) 2201 return (arm_dis_extend(in, buf, buflen)); 2202 /* Unknown instruction */ 2203 return (-1); 2204 break; 2205 case 0x2: 2206 /* 2207 * This consists of the following multiply instructions: 2208 * SMLAD, SMLSD, SMLALD, SMUAD, and SMUSD. 2209 * 2210 * SMLAD and SMUAD encoding are the same, switch on Rn == R15 2211 * 22-20 are 000 7-6 are 00 2212 * SMLSD and SMUSD encoding are the same, switch on Rn == R15 2213 * 22-20 are 000 7-6 are 01 2214 * SMLALD: 22-20 are 100 7-6 are 00 2215 */ 2216 rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT; 2217 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; 2218 rs = (in & ARM_MEDIA_RS_MASK) >> ARM_MEDIA_RS_SHIFT; 2219 rm = in & ARM_MEDIA_RM_MASK; 2220 op1 = (in & ARM_MEDIA_OP1_MASK) >> ARM_MEDIA_OP1_SHIFT; 2221 op2 = (in & ARM_MEDIA_OP2_MASK) >> ARM_MEDIA_OP2_SHIFT; 2222 xbit = in & ARM_MEDIA_MULT_X_MASK; 2223 2224 if (op1 == 0x0) { 2225 if (op2 != 0x0 && op2 != 0x1) 2226 return (-1); 2227 if (rn == ARM_REG_R15) { 2228 len = snprintf(buf, buflen, "%s%s%s %s, %s, %s", 2229 op2 != 0 ? "SMUSD" : "SMUAD", 2230 xbit != 0 ? "X" : "X", 2231 arm_cond_names[cc], arm_reg_names[rd], 2232 arm_reg_names[rm], arm_reg_names[rs]); 2233 } else { 2234 len = snprintf(buf, buflen, 2235 "%s%s%s %s, %s, %s, %s", 2236 op2 != 0 ? "SMLSD" : "SMLAD", 2237 xbit != 0 ? "X" : "", 2238 arm_cond_names[cc], arm_reg_names[rd], 2239 arm_reg_names[rm], arm_reg_names[rs], 2240 arm_reg_names[rn]); 2241 2242 } 2243 } else if (op1 == 0x8) { 2244 if (op2 != 0x0) 2245 return (-1); 2246 len = snprintf(buf, buflen, "SMLALD%s%s %s, %s, %s, %s", 2247 xbit != 0 ? "X" : "", 2248 arm_cond_names[cc], arm_reg_names[rn], 2249 arm_reg_names[rd], arm_reg_names[rm], 2250 arm_reg_names[rs]); 2251 } else 2252 return (-1); 2253 2254 return (len >= buflen ? -1 : 0); 2255 break; 2256 case 0x3: 2257 /* 2258 * Here we handle USAD8 and USADA8. The main difference is the 2259 * presence of RN. USAD8 is defined as having a value of rn that 2260 * is not r15. If it is r15, then instead it is USADA8. 2261 */ 2262 if ((in & ARM_MEDIA_OP1_MASK) != 0) 2263 return (-1); 2264 if ((in & ARM_MEDIA_OP2_MASK) != 0) 2265 return (-1); 2266 2267 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 2268 rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT; 2269 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; 2270 rs = (in & ARM_MEDIA_RS_MASK) >> ARM_MEDIA_RS_SHIFT; 2271 rm = in & ARM_MEDIA_RM_MASK; 2272 2273 if (rn != ARM_REG_R15) 2274 len = snprintf(buf, buflen, "USADA8%s %s, %s, %s, %s", 2275 arm_cond_names[cc], arm_reg_names[rd], 2276 arm_reg_names[rm], arm_reg_names[rs], 2277 arm_reg_names[rn]); 2278 else 2279 len = snprintf(buf, buflen, "USAD8%s %s, %s, %s", 2280 arm_cond_names[cc], arm_reg_names[rd], 2281 arm_reg_names[rm], arm_reg_names[rs]); 2282 return (len >= buflen ? -1 : 0); 2283 break; 2284 default: 2285 return (-1); 2286 } 2287 } 2288 2289 /* 2290 * Each instruction in the ARM instruction set is a uint32_t and in our case is 2291 * LE. The upper four bits determine the condition code. If the conditoin code 2292 * is undefined then we know to immediately jump there. Otherwise we go use the 2293 * next three bits to determine where we should go next and how to further 2294 * process the instruction in question. The ARM instruction manual doesn't 2295 * define this field so we're going to call it the L1_DEC or level 1 decoding 2296 * from which it will have to be further subdivided into the specific 2297 * instruction groupings that we care about. 2298 */ 2299 static int 2300 arm_dis(dis_handle_t *dhp, uint32_t in, char *buf, size_t buflen) 2301 { 2302 uint8_t l1; 2303 arm_cond_code_t cc; 2304 2305 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; 2306 2307 if (cc == ARM_COND_NACC) 2308 return (arm_dis_uncond_insn(in, buf, buflen)); 2309 2310 l1 = (in & ARM_L1_DEC_MASK) >> ARM_L1_DEC_SHIFT; 2311 2312 switch (l1) { 2313 case 0x0: 2314 /* 2315 * The l0 group is a bit complicated. We have several different 2316 * groups of instructions to consider. The first question is 2317 * whether bit 4 is zero or not. If it is, then we have a data 2318 * processing immediate shift unless the opcode and + S bits 2319 * (24-20) is of the form 0b10xx0. 2320 * 2321 * When bit 4 is 1, we have to then also look at bit 7. If bit 2322 * 7 is one then we know that this is the class of multiplies / 2323 * extra load/stores. If bit 7 is zero then we have the same 2324 * opcode games as we did above. 2325 */ 2326 if (in & ARM_L1_0_B4_MASK) { 2327 if (in & ARM_L1_0_B7_MASK) { 2328 /* 2329 * Both the multiplication extensions and the 2330 * load and store extensions live in this 2331 * region. The load and store extensions can be 2332 * identified by having at least one of bits 5 2333 * and 6 set. The exceptions to this are the 2334 * SWP and SWPB instructions and the exclusive 2335 * load and store instructions which, unlike the 2336 * multiplication instructions. These have 2337 * specific values for the bits in the range of 2338 * 20-24. 2339 */ 2340 if ((in & ARM_L1_0_ELS_MASK) != 0) 2341 /* Extra loads/stores */ 2342 return (arm_dis_els(in, buf, buflen)); 2343 if ((in & ARM_ELS_SWAP_MASK) == ARM_ELS_IS_SWAP) 2344 return (arm_dis_swap(in, buf, buflen)); 2345 if ((in & ARM_ELS_EXCL_MASK) == 2346 ARM_ELS_EXCL_MASK) 2347 return (arm_dis_lsexcl(in, buf, 2348 buflen)); 2349 /* Multiplication instruction extension A3-3. */ 2350 return (arm_dis_extmul(in, buf, buflen)); 2351 } 2352 if ((in & ARM_L1_0_OPMASK) == ARM_L1_0_SPECOP && 2353 !(in & ARM_L1_0_SMASK)) { 2354 /* Misc. Instructions A3-4 */ 2355 return (arm_dis_cdsp_ext(in, buf, buflen)); 2356 } else { 2357 /* data processing register shift */ 2358 return (arm_dis_dpi(in, cc, buf, buflen)); 2359 } 2360 } else { 2361 if ((in & ARM_L1_0_OPMASK) == ARM_L1_0_SPECOP && 2362 !(in & ARM_L1_0_SMASK)) 2363 /* Misc. Instructions A3-4 */ 2364 return (arm_dis_cdsp_ext(in, buf, buflen)); 2365 else { 2366 /* Data processing immediate shift */ 2367 return (arm_dis_dpi(in, cc, buf, buflen)); 2368 } 2369 } 2370 break; 2371 case 0x1: 2372 /* 2373 * In l1 group 0b001 there are a few ways to tell things apart. 2374 * We are directed to first look at bits 20-24. Data processing 2375 * immediate has a 4 bit opcode 24-21 followed by an S bit. We 2376 * know it is not a data processing immediate if we have 2377 * something of the form 0b10xx0. 2378 */ 2379 if ((in & ARM_L1_1_OPMASK) == ARM_L1_1_SPECOP && 2380 !(in & ARM_L1_1_SMASK)) { 2381 if (in & ARM_L1_1_UNDEF_MASK) { 2382 /* Undefined instructions */ 2383 return (-1); 2384 } else { 2385 /* Move immediate to status register */ 2386 return (arm_dis_status_regs(in, buf, buflen)); 2387 } 2388 } else { 2389 /* Data processing immedaite */ 2390 return (arm_dis_dpi(in, cc, buf, buflen)); 2391 } 2392 break; 2393 case 0x2: 2394 /* Load/store Immediate offset */ 2395 return (arm_dis_ldstr(in, buf, buflen)); 2396 break; 2397 case 0x3: 2398 /* 2399 * Like other sets we use the 4th bit to make an intial 2400 * determination. If it is zero then this is a load/store 2401 * register offset class instruction. Following that we have a 2402 * specical mask of 0x01f000f0 to determine whether this is an 2403 * architecturally undefined instruction type or not. 2404 * 2405 * The architecturally undefined are parts of the current name 2406 * space that just aren't used, but could be used at some point 2407 * in the future. For now though, it's an invalid op code. 2408 */ 2409 if (in & ARM_L1_3_B4_MASK) { 2410 if ((in & ARM_L1_3_ARCHUN_MASK) == 2411 ARM_L1_3_ARCHUN_MASK) { 2412 /* Architecturally undefined */ 2413 return (-1); 2414 } else { 2415 /* Media instructions */ 2416 return (arm_dis_media(in, buf, buflen)); 2417 } 2418 } else { 2419 /* Load/store register offset */ 2420 return (arm_dis_ldstr(in, buf, buflen)); 2421 } 2422 break; 2423 case 0x4: 2424 /* Load/store multiple */ 2425 return (arm_dis_ldstr_multi(in, buf, buflen)); 2426 break; 2427 case 0x5: 2428 /* Branch and Branch with link */ 2429 return (arm_dis_branch(dhp, in, buf, buflen)); 2430 break; 2431 case 0x6: 2432 /* coprocessor load/store && double register transfers */ 2433 return (arm_dis_coproc_lsdrt(in, buf, buflen)); 2434 break; 2435 case 0x7: 2436 /* 2437 * In l1 group 0b111 you can determine the three groups using 2438 * the following logic. If the next bit after the l1 group (bit 2439 * 24) is one than you know that it is a software interrupt. 2440 * Otherwise it is one of the coprocessor instructions. 2441 * Furthermore you can tell apart the data processing from the 2442 * register transfers based on bit 4. If it is zero then it is 2443 * a data processing instruction, otherwise it is a register 2444 * transfer. 2445 */ 2446 if (in & ARM_L1_7_SWINTMASK) { 2447 /* 2448 * The software interrupt is pretty straightforward. The 2449 * lower 24 bits are the interrupt number. It's also 2450 * valid for it to run with a condition code. 2451 */ 2452 if (snprintf(buf, buflen, "SWI%s %d", 2453 arm_cond_names[cc], 2454 in & ARM_SWI_IMM_MASK) >= buflen) 2455 return (-1); 2456 return (0); 2457 } else if (in & ARM_L1_7_COPROCMASK) { 2458 /* coprocessor register transfers */ 2459 return (arm_dis_coproc_rt(in, buf, buflen)); 2460 } else { 2461 /* coprocessor data processing */ 2462 return (arm_dis_coproc_dp(in, buf, buflen)); 2463 } 2464 break; 2465 } 2466 2467 return (-1); 2468 } 2469 2470 static int 2471 dis_arm_supports_flags(int flags) 2472 { 2473 int archflags = flags & DIS_ARCH_MASK; 2474 2475 return (archflags == DIS_ARM); 2476 } 2477 2478 /*ARGSUSED*/ 2479 static int 2480 dis_arm_handle_attach(dis_handle_t *dhp) 2481 { 2482 return (0); 2483 } 2484 2485 /*ARGSUSED*/ 2486 static void 2487 dis_arm_handle_detach(dis_handle_t *dhp) 2488 { 2489 } 2490 2491 static int 2492 dis_arm_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen) 2493 { 2494 uint32_t in; 2495 2496 buf[0] = '\0'; 2497 dhp->dh_addr = addr; 2498 if (dhp->dh_read(dhp->dh_data, addr, &in, sizeof (in)) != 2499 sizeof (in)) 2500 return (-1); 2501 2502 /* Translate in case we're on sparc? */ 2503 in = LE_32(in); 2504 2505 return (arm_dis(dhp, in, buf, buflen)); 2506 } 2507 2508 /* 2509 * This is simple in a non Thumb world. If and when we do enter a world where we 2510 * support thumb instructions, then this becomes far less than simple. 2511 */ 2512 /*ARGSUSED*/ 2513 static uint64_t 2514 dis_arm_previnstr(dis_handle_t *dhp, uint64_t pc, int n) 2515 { 2516 if (n <= 0) 2517 return (pc); 2518 2519 return (pc - n*4); 2520 } 2521 2522 /* 2523 * If and when we support thumb, then this value should probably become two. 2524 * However, it varies based on whether or not a given instruction is in thumb 2525 * mode. 2526 */ 2527 /*ARGSUSED*/ 2528 static int 2529 dis_arm_min_instrlen(dis_handle_t *dhp) 2530 { 2531 return (4); 2532 } 2533 2534 /* 2535 * Regardless of thumb, this value does not change. 2536 */ 2537 /*ARGSUSED*/ 2538 static int 2539 dis_arm_max_instrlen(dis_handle_t *dhp) 2540 { 2541 return (4); 2542 } 2543 2544 /* ARGSUSED */ 2545 static int 2546 dis_arm_instrlen(dis_handle_t *dhp, uint64_t pc) 2547 { 2548 return (4); 2549 } 2550 2551 dis_arch_t dis_arch_arm = { 2552 dis_arm_supports_flags, 2553 dis_arm_handle_attach, 2554 dis_arm_handle_detach, 2555 dis_arm_disassemble, 2556 dis_arm_previnstr, 2557 dis_arm_min_instrlen, 2558 dis_arm_max_instrlen, 2559 dis_arm_instrlen 2560 };