arm-dis.c revision 89857
1/* Instruction printing code for the ARM 2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 3 Free Software Foundation, Inc. 4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) 5 Modification by James G. Smith (jsmith@cygnus.co.uk) 6 7This file is part of libopcodes. 8 9This program is free software; you can redistribute it and/or modify it under 10the terms of the GNU General Public License as published by the Free 11Software Foundation; either version 2 of the License, or (at your option) 12any later version. 13 14This program is distributed in the hope that it will be useful, but WITHOUT 15ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17more details. 18 19You should have received a copy of the GNU General Public License 20along with this program; if not, write to the Free Software 21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 22 23#include "sysdep.h" 24#include "dis-asm.h" 25#define DEFINE_TABLE 26#include "arm-opc.h" 27#include "coff/internal.h" 28#include "libcoff.h" 29#include "opintl.h" 30 31/* FIXME: This shouldn't be done here */ 32#include "elf-bfd.h" 33#include "elf/internal.h" 34#include "elf/arm.h" 35 36#ifndef streq 37#define streq(a,b) (strcmp ((a), (b)) == 0) 38#endif 39 40#ifndef strneq 41#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0) 42#endif 43 44#ifndef NUM_ELEM 45#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0]) 46#endif 47 48static char * arm_conditional[] = 49{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", 50 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"}; 51 52typedef struct 53{ 54 const char * name; 55 const char * description; 56 const char * reg_names[16]; 57} 58arm_regname; 59 60static arm_regname regnames[] = 61{ 62 { "raw" , "Select raw register names", 63 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}}, 64 { "gcc", "Select register names used by GCC", 65 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }}, 66 { "std", "Select register names used in ARM's ISA documentation", 67 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }}, 68 { "apcs", "Select register names used in the APCS", 69 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }}, 70 { "atpcs", "Select register names used in the ATPCS", 71 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }}, 72 { "special-atpcs", "Select special register names used in the ATPCS", 73 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }} 74}; 75 76/* Default to GCC register name set. */ 77static unsigned int regname_selected = 1; 78 79#define NUM_ARM_REGNAMES NUM_ELEM (regnames) 80#define arm_regnames regnames[regname_selected].reg_names 81 82static boolean force_thumb = false; 83 84static char * arm_fp_const[] = 85{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"}; 86 87static char * arm_shift[] = 88{"lsl", "lsr", "asr", "ror"}; 89 90/* Forward declarations. */ 91static void arm_decode_shift PARAMS ((long, fprintf_ftype, void *)); 92static int print_insn_arm PARAMS ((bfd_vma, struct disassemble_info *, long)); 93static int print_insn_thumb PARAMS ((bfd_vma, struct disassemble_info *, long)); 94static void parse_disassembler_options PARAMS ((char *)); 95static int print_insn PARAMS ((bfd_vma, struct disassemble_info *, boolean)); 96int get_arm_regname_num_options (void); 97int set_arm_regname_option (int option); 98int get_arm_regnames (int option, const char **setname, 99 const char **setdescription, 100 const char ***register_names); 101 102/* Functions. */ 103int 104get_arm_regname_num_options (void) 105{ 106 return NUM_ARM_REGNAMES; 107} 108 109int 110set_arm_regname_option (int option) 111{ 112 int old = regname_selected; 113 regname_selected = option; 114 return old; 115} 116 117int 118get_arm_regnames (int option, const char **setname, 119 const char **setdescription, 120 const char ***register_names) 121{ 122 *setname = regnames[option].name; 123 *setdescription = regnames[option].description; 124 *register_names = regnames[option].reg_names; 125 return 16; 126} 127 128static void 129arm_decode_shift (given, func, stream) 130 long given; 131 fprintf_ftype func; 132 void * stream; 133{ 134 func (stream, "%s", arm_regnames[given & 0xf]); 135 136 if ((given & 0xff0) != 0) 137 { 138 if ((given & 0x10) == 0) 139 { 140 int amount = (given & 0xf80) >> 7; 141 int shift = (given & 0x60) >> 5; 142 143 if (amount == 0) 144 { 145 if (shift == 3) 146 { 147 func (stream, ", rrx"); 148 return; 149 } 150 151 amount = 32; 152 } 153 154 func (stream, ", %s #%d", arm_shift[shift], amount); 155 } 156 else 157 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5], 158 arm_regnames[(given & 0xf00) >> 8]); 159 } 160} 161 162/* Print one instruction from PC on INFO->STREAM. 163 Return the size of the instruction (always 4 on ARM). */ 164static int 165print_insn_arm (pc, info, given) 166 bfd_vma pc; 167 struct disassemble_info * info; 168 long given; 169{ 170 struct arm_opcode * insn; 171 void * stream = info->stream; 172 fprintf_ftype func = info->fprintf_func; 173 174 for (insn = arm_opcodes; insn->assembler; insn++) 175 { 176 if ((given & insn->mask) == insn->value) 177 { 178 char * c; 179 180 for (c = insn->assembler; *c; c++) 181 { 182 if (*c == '%') 183 { 184 switch (*++c) 185 { 186 case '%': 187 func (stream, "%%"); 188 break; 189 190 case 'a': 191 if (((given & 0x000f0000) == 0x000f0000) 192 && ((given & 0x02000000) == 0)) 193 { 194 int offset = given & 0xfff; 195 196 func (stream, "[pc"); 197 198 if (given & 0x01000000) 199 { 200 if ((given & 0x00800000) == 0) 201 offset = - offset; 202 203 /* pre-indexed */ 204 func (stream, ", #%d]", offset); 205 206 offset += pc + 8; 207 208 /* Cope with the possibility of write-back 209 being used. Probably a very dangerous thing 210 for the programmer to do, but who are we to 211 argue ? */ 212 if (given & 0x00200000) 213 func (stream, "!"); 214 } 215 else 216 { 217 /* Post indexed. */ 218 func (stream, "], #%d", offset); 219 220 offset = pc + 8; /* ie ignore the offset. */ 221 } 222 223 func (stream, "\t; "); 224 info->print_address_func (offset, info); 225 } 226 else 227 { 228 func (stream, "[%s", 229 arm_regnames[(given >> 16) & 0xf]); 230 if ((given & 0x01000000) != 0) 231 { 232 if ((given & 0x02000000) == 0) 233 { 234 int offset = given & 0xfff; 235 if (offset) 236 func (stream, ", %s#%d", 237 (((given & 0x00800000) == 0) 238 ? "-" : ""), offset); 239 } 240 else 241 { 242 func (stream, ", %s", 243 (((given & 0x00800000) == 0) 244 ? "-" : "")); 245 arm_decode_shift (given, func, stream); 246 } 247 248 func (stream, "]%s", 249 ((given & 0x00200000) != 0) ? "!" : ""); 250 } 251 else 252 { 253 if ((given & 0x02000000) == 0) 254 { 255 int offset = given & 0xfff; 256 if (offset) 257 func (stream, "], %s#%d", 258 (((given & 0x00800000) == 0) 259 ? "-" : ""), offset); 260 else 261 func (stream, "]"); 262 } 263 else 264 { 265 func (stream, "], %s", 266 (((given & 0x00800000) == 0) 267 ? "-" : "")); 268 arm_decode_shift (given, func, stream); 269 } 270 } 271 } 272 break; 273 274 case 's': 275 if ((given & 0x004f0000) == 0x004f0000) 276 { 277 /* PC relative with immediate offset. */ 278 int offset = ((given & 0xf00) >> 4) | (given & 0xf); 279 280 if ((given & 0x00800000) == 0) 281 offset = -offset; 282 283 func (stream, "[pc, #%d]\t; ", offset); 284 285 (*info->print_address_func) 286 (offset + pc + 8, info); 287 } 288 else 289 { 290 func (stream, "[%s", 291 arm_regnames[(given >> 16) & 0xf]); 292 if ((given & 0x01000000) != 0) 293 { 294 /* Pre-indexed. */ 295 if ((given & 0x00400000) == 0x00400000) 296 { 297 /* Immediate. */ 298 int offset = ((given & 0xf00) >> 4) | (given & 0xf); 299 if (offset) 300 func (stream, ", %s#%d", 301 (((given & 0x00800000) == 0) 302 ? "-" : ""), offset); 303 } 304 else 305 { 306 /* Register. */ 307 func (stream, ", %s%s", 308 (((given & 0x00800000) == 0) 309 ? "-" : ""), 310 arm_regnames[given & 0xf]); 311 } 312 313 func (stream, "]%s", 314 ((given & 0x00200000) != 0) ? "!" : ""); 315 } 316 else 317 { 318 /* Post-indexed. */ 319 if ((given & 0x00400000) == 0x00400000) 320 { 321 /* Immediate. */ 322 int offset = ((given & 0xf00) >> 4) | (given & 0xf); 323 if (offset) 324 func (stream, "], %s#%d", 325 (((given & 0x00800000) == 0) 326 ? "-" : ""), offset); 327 else 328 func (stream, "]"); 329 } 330 else 331 { 332 /* Register. */ 333 func (stream, "], %s%s", 334 (((given & 0x00800000) == 0) 335 ? "-" : ""), 336 arm_regnames[given & 0xf]); 337 } 338 } 339 } 340 break; 341 342 case 'b': 343 (*info->print_address_func) 344 (BDISP (given) * 4 + pc + 8, info); 345 break; 346 347 case 'c': 348 func (stream, "%s", 349 arm_conditional [(given >> 28) & 0xf]); 350 break; 351 352 case 'm': 353 { 354 int started = 0; 355 int reg; 356 357 func (stream, "{"); 358 for (reg = 0; reg < 16; reg++) 359 if ((given & (1 << reg)) != 0) 360 { 361 if (started) 362 func (stream, ", "); 363 started = 1; 364 func (stream, "%s", arm_regnames[reg]); 365 } 366 func (stream, "}"); 367 } 368 break; 369 370 case 'o': 371 if ((given & 0x02000000) != 0) 372 { 373 int rotate = (given & 0xf00) >> 7; 374 int immed = (given & 0xff); 375 immed = (((immed << (32 - rotate)) 376 | (immed >> rotate)) & 0xffffffff); 377 func (stream, "#%d\t; 0x%x", immed, immed); 378 } 379 else 380 arm_decode_shift (given, func, stream); 381 break; 382 383 case 'p': 384 if ((given & 0x0000f000) == 0x0000f000) 385 func (stream, "p"); 386 break; 387 388 case 't': 389 if ((given & 0x01200000) == 0x00200000) 390 func (stream, "t"); 391 break; 392 393 case 'A': 394 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]); 395 if ((given & 0x01000000) != 0) 396 { 397 int offset = given & 0xff; 398 if (offset) 399 func (stream, ", %s#%d]%s", 400 ((given & 0x00800000) == 0 ? "-" : ""), 401 offset * 4, 402 ((given & 0x00200000) != 0 ? "!" : "")); 403 else 404 func (stream, "]"); 405 } 406 else 407 { 408 int offset = given & 0xff; 409 if (offset) 410 func (stream, "], %s#%d", 411 ((given & 0x00800000) == 0 ? "-" : ""), 412 offset * 4); 413 else 414 func (stream, "]"); 415 } 416 break; 417 418 case 'B': 419 /* Print ARM V5 BLX(1) address: pc+25 bits. */ 420 { 421 bfd_vma address; 422 bfd_vma offset = 0; 423 424 if (given & 0x00800000) 425 /* Is signed, hi bits should be ones. */ 426 offset = (-1) ^ 0x00ffffff; 427 428 /* Offset is (SignExtend(offset field)<<2). */ 429 offset += given & 0x00ffffff; 430 offset <<= 2; 431 address = offset + pc + 8; 432 433 if (given & 0x01000000) 434 /* H bit allows addressing to 2-byte boundaries. */ 435 address += 2; 436 437 info->print_address_func (address, info); 438 } 439 break; 440 441 case 'I': 442 /* Print a Cirrus/DSP shift immediate. */ 443 /* Immediates are 7bit signed ints with bits 0..3 in 444 bits 0..3 of opcode and bits 4..6 in bits 5..7 445 of opcode. */ 446 { 447 int imm; 448 449 imm = (given & 0xf) | ((given & 0xe0) >> 1); 450 451 /* Is ``imm'' a negative number? */ 452 if (imm & 0x40) 453 imm |= (-1 << 7); 454 455 func (stream, "%d", imm); 456 } 457 458 break; 459 460 case 'C': 461 func (stream, "_"); 462 if (given & 0x80000) 463 func (stream, "f"); 464 if (given & 0x40000) 465 func (stream, "s"); 466 if (given & 0x20000) 467 func (stream, "x"); 468 if (given & 0x10000) 469 func (stream, "c"); 470 break; 471 472 case 'F': 473 switch (given & 0x00408000) 474 { 475 case 0: 476 func (stream, "4"); 477 break; 478 case 0x8000: 479 func (stream, "1"); 480 break; 481 case 0x00400000: 482 func (stream, "2"); 483 break; 484 default: 485 func (stream, "3"); 486 } 487 break; 488 489 case 'P': 490 switch (given & 0x00080080) 491 { 492 case 0: 493 func (stream, "s"); 494 break; 495 case 0x80: 496 func (stream, "d"); 497 break; 498 case 0x00080000: 499 func (stream, "e"); 500 break; 501 default: 502 func (stream, _("<illegal precision>")); 503 break; 504 } 505 break; 506 case 'Q': 507 switch (given & 0x00408000) 508 { 509 case 0: 510 func (stream, "s"); 511 break; 512 case 0x8000: 513 func (stream, "d"); 514 break; 515 case 0x00400000: 516 func (stream, "e"); 517 break; 518 default: 519 func (stream, "p"); 520 break; 521 } 522 break; 523 case 'R': 524 switch (given & 0x60) 525 { 526 case 0: 527 break; 528 case 0x20: 529 func (stream, "p"); 530 break; 531 case 0x40: 532 func (stream, "m"); 533 break; 534 default: 535 func (stream, "z"); 536 break; 537 } 538 break; 539 540 case '0': case '1': case '2': case '3': case '4': 541 case '5': case '6': case '7': case '8': case '9': 542 { 543 int bitstart = *c++ - '0'; 544 int bitend = 0; 545 while (*c >= '0' && *c <= '9') 546 bitstart = (bitstart * 10) + *c++ - '0'; 547 548 switch (*c) 549 { 550 case '-': 551 c++; 552 553 while (*c >= '0' && *c <= '9') 554 bitend = (bitend * 10) + *c++ - '0'; 555 556 if (!bitend) 557 abort (); 558 559 switch (*c) 560 { 561 case 'r': 562 { 563 long reg; 564 565 reg = given >> bitstart; 566 reg &= (2 << (bitend - bitstart)) - 1; 567 568 func (stream, "%s", arm_regnames[reg]); 569 } 570 break; 571 case 'd': 572 { 573 long reg; 574 575 reg = given >> bitstart; 576 reg &= (2 << (bitend - bitstart)) - 1; 577 578 func (stream, "%d", reg); 579 } 580 break; 581 case 'x': 582 { 583 long reg; 584 585 reg = given >> bitstart; 586 reg &= (2 << (bitend - bitstart)) - 1; 587 588 func (stream, "0x%08x", reg); 589 590 /* Some SWI instructions have special 591 meanings. */ 592 if ((given & 0x0fffffff) == 0x0FF00000) 593 func (stream, "\t; IMB"); 594 else if ((given & 0x0fffffff) == 0x0FF00001) 595 func (stream, "\t; IMBRange"); 596 } 597 break; 598 case 'X': 599 { 600 long reg; 601 602 reg = given >> bitstart; 603 reg &= (2 << (bitend - bitstart)) - 1; 604 605 func (stream, "%01x", reg & 0xf); 606 } 607 break; 608 case 'f': 609 { 610 long reg; 611 612 reg = given >> bitstart; 613 reg &= (2 << (bitend - bitstart)) - 1; 614 615 if (reg > 7) 616 func (stream, "#%s", 617 arm_fp_const[reg & 7]); 618 else 619 func (stream, "f%d", reg); 620 } 621 break; 622 default: 623 abort (); 624 } 625 break; 626 627 case 'y': 628 case 'z': 629 { 630 int single = *c == 'y'; 631 int regno; 632 633 switch (bitstart) 634 { 635 case 4: /* Sm pair */ 636 func (stream, "{"); 637 /* Fall through. */ 638 case 0: /* Sm, Dm */ 639 regno = given & 0x0000000f; 640 if (single) 641 { 642 regno <<= 1; 643 regno += (given >> 5) & 1; 644 } 645 break; 646 647 case 1: /* Sd, Dd */ 648 regno = (given >> 12) & 0x0000000f; 649 if (single) 650 { 651 regno <<= 1; 652 regno += (given >> 22) & 1; 653 } 654 break; 655 656 case 2: /* Sn, Dn */ 657 regno = (given >> 16) & 0x0000000f; 658 if (single) 659 { 660 regno <<= 1; 661 regno += (given >> 7) & 1; 662 } 663 break; 664 665 case 3: /* List */ 666 func (stream, "{"); 667 regno = (given >> 12) & 0x0000000f; 668 if (single) 669 { 670 regno <<= 1; 671 regno += (given >> 22) & 1; 672 } 673 break; 674 675 676 default: 677 abort (); 678 } 679 680 func (stream, "%c%d", single ? 's' : 'd', regno); 681 682 if (bitstart == 3) 683 { 684 int count = given & 0xff; 685 686 if (single == 0) 687 count >>= 1; 688 689 if (--count) 690 { 691 func (stream, "-%c%d", 692 single ? 's' : 'd', 693 regno + count); 694 } 695 696 func (stream, "}"); 697 } 698 else if (bitstart == 4) 699 func (stream, ", %c%d}", single ? 's' : 'd', 700 regno + 1); 701 702 break; 703 } 704 705 case '`': 706 c++; 707 if ((given & (1 << bitstart)) == 0) 708 func (stream, "%c", *c); 709 break; 710 case '\'': 711 c++; 712 if ((given & (1 << bitstart)) != 0) 713 func (stream, "%c", *c); 714 break; 715 case '?': 716 ++c; 717 if ((given & (1 << bitstart)) != 0) 718 func (stream, "%c", *c++); 719 else 720 func (stream, "%c", *++c); 721 break; 722 default: 723 abort (); 724 } 725 break; 726 727 default: 728 abort (); 729 } 730 } 731 } 732 else 733 func (stream, "%c", *c); 734 } 735 return 4; 736 } 737 } 738 abort (); 739} 740 741/* Print one instruction from PC on INFO->STREAM. 742 Return the size of the instruction. */ 743static int 744print_insn_thumb (pc, info, given) 745 bfd_vma pc; 746 struct disassemble_info * info; 747 long given; 748{ 749 struct thumb_opcode * insn; 750 void * stream = info->stream; 751 fprintf_ftype func = info->fprintf_func; 752 753 for (insn = thumb_opcodes; insn->assembler; insn++) 754 { 755 if ((given & insn->mask) == insn->value) 756 { 757 char * c = insn->assembler; 758 759 /* Special processing for Thumb 2 instruction BL sequence: */ 760 if (!*c) /* Check for empty (not NULL) assembler string. */ 761 { 762 long offset; 763 764 info->bytes_per_chunk = 4; 765 info->bytes_per_line = 4; 766 767 offset = BDISP23 (given); 768 769 if ((given & 0x10000000) == 0) 770 { 771 func (stream, "blx\t"); 772 773 /* The spec says that bit 1 of the branch's destination 774 address comes from bit 1 of the instruction's 775 address and not from the offset in the instruction. */ 776 if (offset & 0x1) 777 { 778 /* func (stream, "*malformed!* "); */ 779 offset &= ~ 0x1; 780 } 781 782 offset |= ((pc & 0x2) >> 1); 783 } 784 else 785 func (stream, "bl\t"); 786 787 info->print_address_func (offset * 2 + pc + 4, info); 788 return 4; 789 } 790 else 791 { 792 info->bytes_per_chunk = 2; 793 info->bytes_per_line = 4; 794 795 given &= 0xffff; 796 797 for (; *c; c++) 798 { 799 if (*c == '%') 800 { 801 int domaskpc = 0; 802 int domasklr = 0; 803 804 switch (*++c) 805 { 806 case '%': 807 func (stream, "%%"); 808 break; 809 810 case 'S': 811 { 812 long reg; 813 814 reg = (given >> 3) & 0x7; 815 if (given & (1 << 6)) 816 reg += 8; 817 818 func (stream, "%s", arm_regnames[reg]); 819 } 820 break; 821 822 case 'D': 823 { 824 long reg; 825 826 reg = given & 0x7; 827 if (given & (1 << 7)) 828 reg += 8; 829 830 func (stream, "%s", arm_regnames[reg]); 831 } 832 break; 833 834 case 'T': 835 func (stream, "%s", 836 arm_conditional [(given >> 8) & 0xf]); 837 break; 838 839 case 'N': 840 if (given & (1 << 8)) 841 domasklr = 1; 842 /* Fall through. */ 843 case 'O': 844 if (*c == 'O' && (given & (1 << 8))) 845 domaskpc = 1; 846 /* Fall through. */ 847 case 'M': 848 { 849 int started = 0; 850 int reg; 851 852 func (stream, "{"); 853 854 /* It would be nice if we could spot 855 ranges, and generate the rS-rE format: */ 856 for (reg = 0; (reg < 8); reg++) 857 if ((given & (1 << reg)) != 0) 858 { 859 if (started) 860 func (stream, ", "); 861 started = 1; 862 func (stream, "%s", arm_regnames[reg]); 863 } 864 865 if (domasklr) 866 { 867 if (started) 868 func (stream, ", "); 869 started = 1; 870 func (stream, arm_regnames[14] /* "lr" */); 871 } 872 873 if (domaskpc) 874 { 875 if (started) 876 func (stream, ", "); 877 func (stream, arm_regnames[15] /* "pc" */); 878 } 879 880 func (stream, "}"); 881 } 882 break; 883 884 885 case '0': case '1': case '2': case '3': case '4': 886 case '5': case '6': case '7': case '8': case '9': 887 { 888 int bitstart = *c++ - '0'; 889 int bitend = 0; 890 891 while (*c >= '0' && *c <= '9') 892 bitstart = (bitstart * 10) + *c++ - '0'; 893 894 switch (*c) 895 { 896 case '-': 897 { 898 long reg; 899 900 c++; 901 while (*c >= '0' && *c <= '9') 902 bitend = (bitend * 10) + *c++ - '0'; 903 if (!bitend) 904 abort (); 905 reg = given >> bitstart; 906 reg &= (2 << (bitend - bitstart)) - 1; 907 switch (*c) 908 { 909 case 'r': 910 func (stream, "%s", arm_regnames[reg]); 911 break; 912 913 case 'd': 914 func (stream, "%d", reg); 915 break; 916 917 case 'H': 918 func (stream, "%d", reg << 1); 919 break; 920 921 case 'W': 922 func (stream, "%d", reg << 2); 923 break; 924 925 case 'a': 926 /* PC-relative address -- the bottom two 927 bits of the address are dropped 928 before the calculation. */ 929 info->print_address_func 930 (((pc + 4) & ~3) + (reg << 2), info); 931 break; 932 933 case 'x': 934 func (stream, "0x%04x", reg); 935 break; 936 937 case 'I': 938 reg = ((reg ^ (1 << bitend)) - (1 << bitend)); 939 func (stream, "%d", reg); 940 break; 941 942 case 'B': 943 reg = ((reg ^ (1 << bitend)) - (1 << bitend)); 944 (*info->print_address_func) 945 (reg * 2 + pc + 4, info); 946 break; 947 948 default: 949 abort (); 950 } 951 } 952 break; 953 954 case '\'': 955 c++; 956 if ((given & (1 << bitstart)) != 0) 957 func (stream, "%c", *c); 958 break; 959 960 case '?': 961 ++c; 962 if ((given & (1 << bitstart)) != 0) 963 func (stream, "%c", *c++); 964 else 965 func (stream, "%c", *++c); 966 break; 967 968 default: 969 abort (); 970 } 971 } 972 break; 973 974 default: 975 abort (); 976 } 977 } 978 else 979 func (stream, "%c", *c); 980 } 981 } 982 return 2; 983 } 984 } 985 986 /* No match. */ 987 abort (); 988} 989 990/* Parse an individual disassembler option. */ 991void 992parse_arm_disassembler_option (option) 993 char * option; 994{ 995 if (option == NULL) 996 return; 997 998 if (strneq (option, "reg-names-", 10)) 999 { 1000 int i; 1001 1002 option += 10; 1003 1004 for (i = NUM_ARM_REGNAMES; i--;) 1005 if (streq (option, regnames[i].name)) 1006 { 1007 regname_selected = i; 1008 break; 1009 } 1010 1011 if (i < 0) 1012 fprintf (stderr, _("Unrecognised register name set: %s\n"), option); 1013 } 1014 else if (streq (option, "force-thumb")) 1015 force_thumb = 1; 1016 else if (streq (option, "no-force-thumb")) 1017 force_thumb = 0; 1018 else 1019 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option); 1020 1021 return; 1022} 1023 1024/* Parse the string of disassembler options, spliting it at whitespaces. */ 1025static void 1026parse_disassembler_options (options) 1027 char * options; 1028{ 1029 char * space; 1030 1031 if (options == NULL) 1032 return; 1033 1034 do 1035 { 1036 space = strchr (options, ' '); 1037 1038 if (space) 1039 { 1040 * space = '\0'; 1041 parse_arm_disassembler_option (options); 1042 * space = ' '; 1043 options = space + 1; 1044 } 1045 else 1046 parse_arm_disassembler_option (options); 1047 } 1048 while (space); 1049} 1050 1051/* NOTE: There are no checks in these routines that 1052 the relevant number of data bytes exist. */ 1053static int 1054print_insn (pc, info, little) 1055 bfd_vma pc; 1056 struct disassemble_info * info; 1057 boolean little; 1058{ 1059 unsigned char b[4]; 1060 long given; 1061 int status; 1062 int is_thumb; 1063 1064 if (info->disassembler_options) 1065 { 1066 parse_disassembler_options (info->disassembler_options); 1067 1068 /* To avoid repeated parsing of these options, we remove them here. */ 1069 info->disassembler_options = NULL; 1070 } 1071 1072 is_thumb = force_thumb; 1073 1074 if (!is_thumb && info->symbols != NULL) 1075 { 1076 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour) 1077 { 1078 coff_symbol_type * cs; 1079 1080 cs = coffsymbol (*info->symbols); 1081 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT 1082 || cs->native->u.syment.n_sclass == C_THUMBSTAT 1083 || cs->native->u.syment.n_sclass == C_THUMBLABEL 1084 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC 1085 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC); 1086 } 1087 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour) 1088 { 1089 elf_symbol_type * es; 1090 unsigned int type; 1091 1092 es = *(elf_symbol_type **)(info->symbols); 1093 type = ELF_ST_TYPE (es->internal_elf_sym.st_info); 1094 1095 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT); 1096 } 1097 } 1098 1099 info->bytes_per_chunk = 4; 1100 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG; 1101 1102 if (little) 1103 { 1104 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info); 1105 if (status != 0 && is_thumb) 1106 { 1107 info->bytes_per_chunk = 2; 1108 1109 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info); 1110 b[3] = b[2] = 0; 1111 } 1112 1113 if (status != 0) 1114 { 1115 info->memory_error_func (status, pc, info); 1116 return -1; 1117 } 1118 1119 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24); 1120 } 1121 else 1122 { 1123 status = info->read_memory_func 1124 (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info); 1125 if (status != 0) 1126 { 1127 info->memory_error_func (status, pc, info); 1128 return -1; 1129 } 1130 1131 if (is_thumb) 1132 { 1133 if (pc & 0x2) 1134 { 1135 given = (b[2] << 8) | b[3]; 1136 1137 status = info->read_memory_func 1138 ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info); 1139 if (status != 0) 1140 { 1141 info->memory_error_func (status, pc + 4, info); 1142 return -1; 1143 } 1144 1145 given |= (b[0] << 24) | (b[1] << 16); 1146 } 1147 else 1148 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16); 1149 } 1150 else 1151 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]); 1152 } 1153 1154 if (info->flags & INSN_HAS_RELOC) 1155 /* If the instruction has a reloc associated with it, then 1156 the offset field in the instruction will actually be the 1157 addend for the reloc. (We are using REL type relocs). 1158 In such cases, we can ignore the pc when computing 1159 addresses, since the addend is not currently pc-relative. */ 1160 pc = 0; 1161 1162 if (is_thumb) 1163 status = print_insn_thumb (pc, info, given); 1164 else 1165 status = print_insn_arm (pc, info, given); 1166 1167 return status; 1168} 1169 1170int 1171print_insn_big_arm (pc, info) 1172 bfd_vma pc; 1173 struct disassemble_info * info; 1174{ 1175 return print_insn (pc, info, false); 1176} 1177 1178int 1179print_insn_little_arm (pc, info) 1180 bfd_vma pc; 1181 struct disassemble_info * info; 1182{ 1183 return print_insn (pc, info, true); 1184} 1185 1186void 1187print_arm_disassembler_options (FILE * stream) 1188{ 1189 int i; 1190 1191 fprintf (stream, _("\n\ 1192The following ARM specific disassembler options are supported for use with\n\ 1193the -M switch:\n")); 1194 1195 for (i = NUM_ARM_REGNAMES; i--;) 1196 fprintf (stream, " reg-names-%s %*c%s\n", 1197 regnames[i].name, 1198 (int)(14 - strlen (regnames[i].name)), ' ', 1199 regnames[i].description); 1200 1201 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n"); 1202 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n"); 1203} 1204