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