uboot/common/bedbug.c
<<
>>
Prefs
   1/* $Id$ */
   2
   3#include <common.h>
   4
   5#include <linux/ctype.h>
   6#include <bedbug/bedbug.h>
   7#include <bedbug/ppc.h>
   8#include <bedbug/regs.h>
   9#include <bedbug/tables.h>
  10
  11#define Elf32_Word      unsigned long
  12
  13/* USE_SOURCE_CODE enables some symbolic debugging functions of this
  14   code.  This is only useful if the program will have access to the
  15   source code for the binary being examined.
  16*/
  17
  18/* #define USE_SOURCE_CODE 1 */
  19
  20#ifdef USE_SOURCE_CODE
  21extern int line_info_from_addr __P ((Elf32_Word, char *, char *, int *));
  22extern struct symreflist *symByAddr;
  23extern char *symbol_name_from_addr __P ((Elf32_Word, int, int *));
  24#endif /* USE_SOURCE_CODE */
  25
  26int print_operands __P ((struct ppc_ctx *));
  27int get_operand_value __P ((struct opcode *, unsigned long,
  28                                enum OP_FIELD, unsigned long *));
  29struct opcode *find_opcode __P ((unsigned long));
  30struct opcode *find_opcode_by_name __P ((char *));
  31char *spr_name __P ((int));
  32int spr_value __P ((char *));
  33char *tbr_name __P ((int));
  34int tbr_value __P ((char *));
  35int parse_operand __P ((unsigned long, struct opcode *,
  36                        struct operand *, char *, int *));
  37int get_word __P ((char **, char *));
  38long read_number __P ((char *));
  39int downstring __P ((char *));
  40
  41
  42/*======================================================================
  43 * Entry point for the PPC disassembler.
  44 *
  45 * Arguments:
  46 *      memaddr         The address to start disassembling from.
  47 *
  48 *      virtual         If this value is non-zero, then this will be
  49 *                      used as the base address for the output and
  50 *                      symbol lookups.  If this value is zero then
  51 *                      memaddr is used as the absolute address.
  52 *
  53 *      num_instr       The number of instructions to disassemble.  Since
  54 *                      each instruction is 32 bits long, this can be
  55 *                      computed if you know the total size of the region.
  56 *
  57 *      pfunc           The address of a function that is called to print
  58 *                      each line of output.  The function should take a
  59 *                      single character pointer as its parameters a la puts.
  60 *
  61 *      flags           Sets options for the output.  This is a
  62 *                      bitwise-inclusive-OR of the following
  63 *                      values.  Note that only one of the radix
  64 *                      options may be set.
  65 *
  66 *                      F_RADOCTAL      - output radix is unsigned base 8.
  67 *                      F_RADUDECIMAL   - output radix is unsigned base 10.
  68 *                      F_RADSDECIMAL   - output radix is signed base 10.
  69 *                      F_RADHEX        - output radix is unsigned base 16.
  70 *                      F_SIMPLE        - use simplified mnemonics.
  71 *                      F_SYMBOL        - lookup symbols for addresses.
  72 *                      F_INSTR         - output raw instruction.
  73 *                      F_LINENO        - show line # info if available.
  74 *
  75 * Returns TRUE if the area was successfully disassembled or FALSE if
  76 * a problem was encountered with accessing the memory.
  77 */
  78
  79int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr,
  80                        int (*pfunc) (const char *), unsigned long flags)
  81{
  82        int i;
  83        struct ppc_ctx ctx;
  84
  85#ifdef USE_SOURCE_CODE
  86        int line_no = 0;
  87        int last_line_no = 0;
  88        char funcname[128] = { 0 };
  89        char filename[256] = { 0 };
  90        char last_funcname[128] = { 0 };
  91        int symoffset;
  92        char *symname;
  93        char *cursym = (char *) 0;
  94#endif /* USE_SOURCE_CODE */
  95  /*------------------------------------------------------------*/
  96
  97        ctx.flags = flags;
  98        ctx.virtual = virtual;
  99
 100        /* Figure out the output radix before we go any further */
 101
 102        if (ctx.flags & F_RADOCTAL) {
 103                /* Unsigned octal output */
 104                strcpy (ctx.radix_fmt, "O%o");
 105        } else if (ctx.flags & F_RADUDECIMAL) {
 106                /* Unsigned decimal output */
 107                strcpy (ctx.radix_fmt, "%u");
 108        } else if (ctx.flags & F_RADSDECIMAL) {
 109                /* Signed decimal output */
 110                strcpy (ctx.radix_fmt, "%d");
 111        } else {
 112                /* Unsigned hex output */
 113                strcpy (ctx.radix_fmt, "0x%x");
 114        }
 115
 116        if (ctx.virtual == 0) {
 117                ctx.virtual = memaddr;
 118        }
 119#ifdef USE_SOURCE_CODE
 120        if (ctx.flags & F_SYMBOL) {
 121                if (symByAddr == 0)             /* no symbols loaded */
 122                        ctx.flags &= ~F_SYMBOL;
 123                else {
 124                        cursym = (char *) 0;
 125                        symoffset = 0;
 126                }
 127        }
 128#endif /* USE_SOURCE_CODE */
 129
 130        /* format each line as "XXXXXXXX: <symbol> IIIIIIII  disassembly" where,
 131           XXXXXXXX is the memory address in hex,
 132           <symbol> is the symbolic location if F_SYMBOL is set.
 133           IIIIIIII is the raw machine code in hex if F_INSTR is set,
 134           and disassembly is the disassembled machine code with numbers
 135           formatted according to the 'radix' parameter */
 136
 137        for (i = 0; i < num_instr; ++i, memaddr += 4, ctx.virtual += 4) {
 138#ifdef USE_SOURCE_CODE
 139                if (ctx.flags & F_LINENO) {
 140                        if ((line_info_from_addr ((Elf32_Word) ctx.virtual, filename,
 141                                                                          funcname, &line_no) == TRUE) &&
 142                                ((line_no != last_line_no) ||
 143                                 (strcmp (last_funcname, funcname) != 0))) {
 144                                print_source_line (filename, funcname, line_no, pfunc);
 145                        }
 146                        last_line_no = line_no;
 147                        strcpy (last_funcname, funcname);
 148                }
 149#endif /* USE_SOURCE_CODE */
 150
 151                sprintf (ctx.data, "%08lx: ", (unsigned long) ctx.virtual);
 152                ctx.datalen = 10;
 153
 154#ifdef USE_SOURCE_CODE
 155                if (ctx.flags & F_SYMBOL) {
 156                        if ((symname =
 157                                 symbol_name_from_addr ((Elf32_Word) ctx.virtual,
 158                                                                                TRUE, 0)) != 0) {
 159                                cursym = symname;
 160                                symoffset = 0;
 161                        } else {
 162                                if ((cursym == 0) &&
 163                                        ((symname =
 164                                          symbol_name_from_addr ((Elf32_Word) ctx.virtual,
 165                                                                                         FALSE, &symoffset)) != 0)) {
 166                                        cursym = symname;
 167                                } else {
 168                                        symoffset += 4;
 169                                }
 170                        }
 171
 172                        if (cursym != 0) {
 173                                sprintf (&ctx.data[ctx.datalen], "<%s+", cursym);
 174                                ctx.datalen = strlen (ctx.data);
 175                                sprintf (&ctx.data[ctx.datalen], ctx.radix_fmt, symoffset);
 176                                strcat (ctx.data, ">");
 177                                ctx.datalen = strlen (ctx.data);
 178                        }
 179                }
 180#endif /* USE_SOURCE_CODE */
 181
 182                ctx.instr = INSTRUCTION (memaddr);
 183
 184                if (ctx.flags & F_INSTR) {
 185                        /* Find the opcode structure for this opcode.  If one is not found
 186                           then it must be an illegal instruction */
 187                        sprintf (&ctx.data[ctx.datalen],
 188                                         "   %02lx %02lx %02lx %02lx    ",
 189                                         ((ctx.instr >> 24) & 0xff),
 190                                         ((ctx.instr >> 16) & 0xff), ((ctx.instr >> 8) & 0xff),
 191                                         (ctx.instr & 0xff));
 192                        ctx.datalen += 18;
 193                } else {
 194                        strcat (ctx.data, "   ");
 195                        ctx.datalen += 3;
 196                }
 197
 198                if ((ctx.op = find_opcode (ctx.instr)) == 0) {
 199                        /* Illegal Opcode */
 200                        sprintf (&ctx.data[ctx.datalen], "        .long 0x%08lx",
 201                                         ctx.instr);
 202                        ctx.datalen += 24;
 203                        (*pfunc) (ctx.data);
 204                        continue;
 205                }
 206
 207                if (((ctx.flags & F_SIMPLE) == 0) ||
 208                        (ctx.op->hfunc == 0) || ((*ctx.op->hfunc) (&ctx) == FALSE)) {
 209                        sprintf (&ctx.data[ctx.datalen], "%-7s ", ctx.op->name);
 210                        ctx.datalen += 8;
 211                        print_operands (&ctx);
 212                }
 213
 214                (*pfunc) (ctx.data);
 215        }
 216
 217        return TRUE;
 218}                                                               /* disppc */
 219
 220
 221
 222/*======================================================================
 223 * Called by the disassembler to print the operands for an instruction.
 224 *
 225 * Arguments:
 226 *      ctx             A pointer to the disassembler context record.
 227 *
 228 * always returns 0.
 229 */
 230
 231int print_operands (struct ppc_ctx *ctx)
 232{
 233        int open_parens = 0;
 234        int field;
 235        unsigned long operand;
 236        struct operand *opr;
 237
 238#ifdef USE_SOURCE_CODE
 239        char *symname;
 240        int offset;
 241#endif /* USE_SOURCE_CODE */
 242  /*------------------------------------------------------------*/
 243
 244        /* Walk through the operands and list each in order */
 245        for (field = 0; ctx->op->fields[field] != 0; ++field) {
 246                if (ctx->op->fields[field] > n_operands) {
 247                        continue;                       /* bad operand ?! */
 248                }
 249
 250                opr = &operands[ctx->op->fields[field] - 1];
 251
 252                if (opr->hint & OH_SILENT) {
 253                        continue;
 254                }
 255
 256                if ((field > 0) && !open_parens) {
 257                        strcat (ctx->data, ",");
 258                        ctx->datalen++;
 259                }
 260
 261                operand = (ctx->instr >> opr->shift) & ((1 << opr->bits) - 1);
 262
 263                if (opr->hint & OH_ADDR) {
 264                        if ((operand & (1 << (opr->bits - 1))) != 0) {
 265                                operand = operand - (1 << opr->bits);
 266                        }
 267
 268                        if (ctx->op->hint & H_RELATIVE)
 269                                operand = (operand << 2) + (unsigned long) ctx->virtual;
 270                        else
 271                                operand = (operand << 2);
 272
 273
 274                        sprintf (&ctx->data[ctx->datalen], "0x%lx", operand);
 275                        ctx->datalen = strlen (ctx->data);
 276
 277#ifdef USE_SOURCE_CODE
 278                        if ((ctx->flags & F_SYMBOL) &&
 279                                ((symname =
 280                                  symbol_name_from_addr (operand, 0, &offset)) != 0)) {
 281                                sprintf (&ctx->data[ctx->datalen], " <%s", symname);
 282                                if (offset != 0) {
 283                                        strcat (ctx->data, "+");
 284                                        ctx->datalen = strlen (ctx->data);
 285                                        sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt,
 286                                                         offset);
 287                                }
 288                                strcat (ctx->data, ">");
 289                        }
 290#endif /* USE_SOURCE_CODE */
 291                }
 292
 293                else if (opr->hint & OH_REG) {
 294                        if ((operand == 0) &&
 295                                (opr->field == O_rA) && (ctx->op->hint & H_RA0_IS_0)) {
 296                                strcat (ctx->data, "0");
 297                        } else {
 298                                sprintf (&ctx->data[ctx->datalen], "r%d", (short) operand);
 299                        }
 300
 301                        if (open_parens) {
 302                                strcat (ctx->data, ")");
 303                                open_parens--;
 304                        }
 305                }
 306
 307                else if (opr->hint & OH_SPR) {
 308                        strcat (ctx->data, spr_name (operand));
 309                }
 310
 311                else if (opr->hint & OH_TBR) {
 312                        strcat (ctx->data, tbr_name (operand));
 313                }
 314
 315                else if (opr->hint & OH_LITERAL) {
 316                        switch (opr->field) {
 317                        case O_cr2:
 318                                strcat (ctx->data, "cr2");
 319                                ctx->datalen += 3;
 320                                break;
 321
 322                        default:
 323                                break;
 324                        }
 325                }
 326
 327                else {
 328                        sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt,
 329                                         (unsigned short) operand);
 330
 331                        if (open_parens) {
 332                                strcat (ctx->data, ")");
 333                                open_parens--;
 334                        }
 335
 336                        else if (opr->hint & OH_OFFSET) {
 337                                strcat (ctx->data, "(");
 338                                open_parens++;
 339                        }
 340                }
 341
 342                ctx->datalen = strlen (ctx->data);
 343        }
 344
 345        return 0;
 346}                                                               /* print_operands */
 347
 348
 349
 350/*======================================================================
 351 * Called to get the value of an arbitrary operand with in an instruction.
 352 *
 353 * Arguments:
 354 *      op              The pointer to the opcode structure to which
 355 *                      the operands belong.
 356 *
 357 *      instr           The instruction (32 bits) containing the opcode
 358 *                      and the operands to print.  By the time that
 359 *                      this routine is called the operand has already
 360 *                      been added to the output.
 361 *
 362 *      field           The field (operand) to get the value of.
 363 *
 364 *      value           The address of an unsigned long to be filled in
 365 *                      with the value of the operand if it is found.  This
 366 *                      will only be filled in if the function returns
 367 *                      TRUE.  This may be passed as 0 if the value is
 368 *                      not required.
 369 *
 370 * Returns TRUE if the operand was found or FALSE if it was not.
 371 */
 372
 373int get_operand_value (struct opcode *op, unsigned long instr,
 374                                           enum OP_FIELD field, unsigned long *value)
 375{
 376        int i;
 377        struct operand *opr;
 378
 379  /*------------------------------------------------------------*/
 380
 381        if (field > n_operands) {
 382                return FALSE;                   /* bad operand ?! */
 383        }
 384
 385        /* Walk through the operands and list each in order */
 386        for (i = 0; op->fields[i] != 0; ++i) {
 387                if (op->fields[i] != field) {
 388                        continue;
 389                }
 390
 391                opr = &operands[op->fields[i] - 1];
 392
 393                if (value) {
 394                        *value = (instr >> opr->shift) & ((1 << opr->bits) - 1);
 395                }
 396                return TRUE;
 397        }
 398
 399        return FALSE;
 400}                                                               /* operand_value */
 401
 402
 403
 404/*======================================================================
 405 * Called by the disassembler to match an opcode value to an opcode structure.
 406 *
 407 * Arguments:
 408 *      instr           The instruction (32 bits) to match.  This value
 409 *                      may contain operand values as well as the opcode
 410 *                      since they will be masked out anyway for this
 411 *                      search.
 412 *
 413 * Returns the address of an opcode struct (from the opcode table) if the
 414 * operand successfully matched an entry, or 0 if no match was found.
 415 */
 416
 417struct opcode *find_opcode (unsigned long instr)
 418{
 419        struct opcode *ptr;
 420        int top = 0;
 421        int bottom = n_opcodes - 1;
 422        int idx;
 423
 424  /*------------------------------------------------------------*/
 425
 426        while (top <= bottom) {
 427                idx = (top + bottom) >> 1;
 428                ptr = &opcodes[idx];
 429
 430                if ((instr & ptr->mask) < ptr->opcode) {
 431                        bottom = idx - 1;
 432                } else if ((instr & ptr->mask) > ptr->opcode) {
 433                        top = idx + 1;
 434                } else {
 435                        return ptr;
 436                }
 437        }
 438
 439        return (struct opcode *) 0;
 440}                                                               /* find_opcode */
 441
 442
 443
 444/*======================================================================
 445 * Called by the assembler to match an opcode name to an opcode structure.
 446 *
 447 * Arguments:
 448 *      name            The text name of the opcode, e.g. "b", "mtspr", etc.
 449 *
 450 * The opcodes are sorted numerically by their instruction binary code
 451 * so a search for the name cannot use the binary search used by the
 452 * other find routine.
 453 *
 454 * Returns the address of an opcode struct (from the opcode table) if the
 455 * name successfully matched an entry, or 0 if no match was found.
 456 */
 457
 458struct opcode *find_opcode_by_name (char *name)
 459{
 460        int idx;
 461
 462  /*------------------------------------------------------------*/
 463
 464        downstring (name);
 465
 466        for (idx = 0; idx < n_opcodes; ++idx) {
 467                if (!strcmp (name, opcodes[idx].name))
 468                        return &opcodes[idx];
 469        }
 470
 471        return (struct opcode *) 0;
 472}                                                               /* find_opcode_by_name */
 473
 474
 475
 476/*======================================================================
 477 * Convert the 'spr' operand from its numeric value to its symbolic name.
 478 *
 479 * Arguments:
 480 *      value           The value of the 'spr' operand.  This value should
 481 *                      be unmodified from its encoding in the instruction.
 482 *                      the split-field computations will be performed
 483 *                      here before the switch.
 484 *
 485 * Returns the address of a character array containing the name of the
 486 * special purpose register defined by the 'value' parameter, or the
 487 * address of a character array containing "???" if no match was found.
 488 */
 489
 490char *spr_name (int value)
 491{
 492        unsigned short spr;
 493        static char other[10];
 494        int i;
 495
 496  /*------------------------------------------------------------*/
 497
 498        /* spr is a 10 bit field whose interpretation has the high and low
 499           five-bit fields reversed from their encoding in the operand */
 500
 501        spr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5);
 502
 503        for (i = 0; i < n_sprs; ++i) {
 504                if (spr == spr_map[i].spr_val)
 505                        return spr_map[i].spr_name;
 506        }
 507
 508        sprintf (other, "%d", spr);
 509        return other;
 510}                                                               /* spr_name */
 511
 512
 513
 514/*======================================================================
 515 * Convert the 'spr' operand from its symbolic name to its numeric value
 516 *
 517 * Arguments:
 518 *      name            The symbolic name of the 'spr' operand.  The
 519 *                      split-field encoding will be done by this routine.
 520 *                      NOTE: name can be a number.
 521 *
 522 * Returns the numeric value for the spr appropriate for encoding a machine
 523 * instruction.  Returns 0 if unable to find the SPR.
 524 */
 525
 526int spr_value (char *name)
 527{
 528        struct spr_info *sprp;
 529        int spr;
 530        int i;
 531
 532  /*------------------------------------------------------------*/
 533
 534        if (!name || !*name)
 535                return 0;
 536
 537        if (isdigit ((int) name[0])) {
 538                i = htonl (read_number (name));
 539                spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5);
 540                return spr;
 541        }
 542
 543        downstring (name);
 544
 545        for (i = 0; i < n_sprs; ++i) {
 546                sprp = &spr_map[i];
 547
 548                if (strcmp (name, sprp->spr_name) == 0) {
 549                        /* spr is a 10 bit field whose interpretation has the high and low
 550                           five-bit fields reversed from their encoding in the operand */
 551                        i = htonl (sprp->spr_val);
 552                        spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5);
 553
 554                        return spr;
 555                }
 556        }
 557
 558        return 0;
 559}                                                               /* spr_value */
 560
 561
 562
 563/*======================================================================
 564 * Convert the 'tbr' operand from its numeric value to its symbolic name.
 565 *
 566 * Arguments:
 567 *      value           The value of the 'tbr' operand.  This value should
 568 *                      be unmodified from its encoding in the instruction.
 569 *                      the split-field computations will be performed
 570 *                      here before the switch.
 571 *
 572 * Returns the address of a character array containing the name of the
 573 * time base register defined by the 'value' parameter, or the address
 574 * of a character array containing "???" if no match was found.
 575 */
 576
 577char *tbr_name (int value)
 578{
 579        unsigned short tbr;
 580
 581  /*------------------------------------------------------------*/
 582
 583        /* tbr is a 10 bit field whose interpretation has the high and low
 584           five-bit fields reversed from their encoding in the operand */
 585
 586        tbr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5);
 587
 588        if (tbr == 268)
 589                return "TBL";
 590
 591        else if (tbr == 269)
 592                return "TBU";
 593
 594
 595        return "???";
 596}                                                               /* tbr_name */
 597
 598
 599
 600/*======================================================================
 601 * Convert the 'tbr' operand from its symbolic name to its numeric value.
 602 *
 603 * Arguments:
 604 *      name            The symbolic name of the 'tbr' operand.  The
 605 *                      split-field encoding will be done by this routine.
 606 *
 607 * Returns the numeric value for the spr appropriate for encoding a machine
 608 * instruction.  Returns 0 if unable to find the TBR.
 609 */
 610
 611int tbr_value (char *name)
 612{
 613        int tbr;
 614        int val;
 615
 616  /*------------------------------------------------------------*/
 617
 618        if (!name || !*name)
 619                return 0;
 620
 621        downstring (name);
 622
 623        if (isdigit ((int) name[0])) {
 624                val = read_number (name);
 625
 626                if (val != 268 && val != 269)
 627                        return 0;
 628        } else if (strcmp (name, "tbl") == 0)
 629                val = 268;
 630        else if (strcmp (name, "tbu") == 0)
 631                val = 269;
 632        else
 633                return 0;
 634
 635        /* tbr is a 10 bit field whose interpretation has the high and low
 636           five-bit fields reversed from their encoding in the operand */
 637
 638        val = htonl (val);
 639        tbr = ((val >> 5) & 0x1f) | ((val & 0x1f) << 5);
 640        return tbr;
 641}                                                               /* tbr_name */
 642
 643
 644
 645/*======================================================================
 646 * The next several functions (handle_xxx) are the routines that handle
 647 * disassembling the opcodes with simplified mnemonics.
 648 *
 649 * Arguments:
 650 *      ctx             A pointer to the disassembler context record.
 651 *
 652 * Returns TRUE if the simpler form was printed or FALSE if it was not.
 653 */
 654
 655int handle_bc (struct ppc_ctx *ctx)
 656{
 657        unsigned long bo;
 658        unsigned long bi;
 659        static struct opcode blt = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0},
 660        0, "blt", H_RELATIVE
 661        };
 662        static struct opcode bne =
 663                        { B_OPCODE (16, 0, 0), B_MASK, {O_cr2, O_BD, 0},
 664        0, "bne", H_RELATIVE
 665        };
 666        static struct opcode bdnz = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0},
 667        0, "bdnz", H_RELATIVE
 668        };
 669
 670  /*------------------------------------------------------------*/
 671
 672        if (get_operand_value (ctx->op, ctx->instr, O_BO, &bo) == FALSE)
 673                return FALSE;
 674
 675        if (get_operand_value (ctx->op, ctx->instr, O_BI, &bi) == FALSE)
 676                return FALSE;
 677
 678        if ((bo == 12) && (bi == 0)) {
 679                ctx->op = &blt;
 680                sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
 681                ctx->datalen += 8;
 682                print_operands (ctx);
 683                return TRUE;
 684        } else if ((bo == 4) && (bi == 10)) {
 685                ctx->op = &bne;
 686                sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
 687                ctx->datalen += 8;
 688                print_operands (ctx);
 689                return TRUE;
 690        } else if ((bo == 16) && (bi == 0)) {
 691                ctx->op = &bdnz;
 692                sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
 693                ctx->datalen += 8;
 694                print_operands (ctx);
 695                return TRUE;
 696        }
 697
 698        return FALSE;
 699}                                                               /* handle_blt */
 700
 701
 702
 703/*======================================================================
 704 * Outputs source line information for the disassembler.  This should
 705 * be modified in the future to lookup the actual line of source code
 706 * from the file, but for now this will do.
 707 *
 708 * Arguments:
 709 *      filename        The address of a character array containing the
 710 *                      absolute path and file name of the source file.
 711 *
 712 *      funcname        The address of a character array containing the
 713 *                      name of the function (not C++ demangled (yet))
 714 *                      to which this code belongs.
 715 *
 716 *      line_no         An integer specifying the source line number that
 717 *                      generated this code.
 718 *
 719 *      pfunc           The address of a function to call to print the output.
 720 *
 721 *
 722 * Returns TRUE if it was able to output the line info, or false if it was
 723 * not.
 724 */
 725
 726int print_source_line (char *filename, char *funcname,
 727                                           int line_no, int (*pfunc) (const char *))
 728{
 729        char out_buf[256];
 730
 731  /*------------------------------------------------------------*/
 732
 733        (*pfunc) ("");                          /* output a newline */
 734        sprintf (out_buf, "%s %s(): line %d", filename, funcname, line_no);
 735        (*pfunc) (out_buf);
 736
 737        return TRUE;
 738}                                                               /* print_source_line */
 739
 740
 741
 742/*======================================================================
 743 * Entry point for the PPC assembler.
 744 *
 745 * Arguments:
 746 *      asm_buf         An array of characters containing the assembly opcode
 747 *                      and operands to convert to a POWERPC machine
 748 *                      instruction.
 749 *
 750 * Returns the machine instruction or zero.
 751 */
 752
 753unsigned long asmppc (unsigned long memaddr, char *asm_buf, int *err)
 754{
 755        struct opcode *opc;
 756        struct operand *oper[MAX_OPERANDS];
 757        unsigned long instr;
 758        unsigned long param;
 759        char *ptr = asm_buf;
 760        char scratch[20];
 761        int i;
 762        int w_operands = 0;                     /* wanted # of operands */
 763        int n_operands = 0;                     /* # of operands read */
 764        int asm_debug = 0;
 765
 766  /*------------------------------------------------------------*/
 767
 768        if (err)
 769                *err = 0;
 770
 771        if (get_word (&ptr, scratch) == 0)
 772                return 0;
 773
 774        /* Lookup the opcode structure based on the opcode name */
 775        if ((opc = find_opcode_by_name (scratch)) == (struct opcode *) 0) {
 776                if (err)
 777                        *err = E_ASM_BAD_OPCODE;
 778                return 0;
 779        }
 780
 781        if (asm_debug) {
 782                printf ("asmppc: Opcode = \"%s\"\n", opc->name);
 783        }
 784
 785        for (i = 0; i < 8; ++i) {
 786                if (opc->fields[i] == 0)
 787                        break;
 788                ++w_operands;
 789        }
 790
 791        if (asm_debug) {
 792                printf ("asmppc: Expecting %d operands\n", w_operands);
 793        }
 794
 795        instr = opc->opcode;
 796
 797        /* read each operand */
 798        while (n_operands < w_operands) {
 799
 800                oper[n_operands] = &operands[opc->fields[n_operands] - 1];
 801
 802                if (oper[n_operands]->hint & OH_SILENT) {
 803                        /* Skip silent operands, they are covered in opc->opcode */
 804
 805                        if (asm_debug) {
 806                                printf ("asmppc: Operand %d \"%s\" SILENT\n", n_operands,
 807                                                oper[n_operands]->name);
 808                        }
 809
 810                        ++n_operands;
 811                        continue;
 812                }
 813
 814                if (get_word (&ptr, scratch) == 0)
 815                        break;
 816
 817                if (asm_debug) {
 818                        printf ("asmppc: Operand %d \"%s\" : \"%s\"\n", n_operands,
 819                                        oper[n_operands]->name, scratch);
 820                }
 821
 822                if ((param = parse_operand (memaddr, opc, oper[n_operands],
 823                                                                        scratch, err)) == -1)
 824                        return 0;
 825
 826                instr |= param;
 827                ++n_operands;
 828        }
 829
 830        if (n_operands < w_operands) {
 831                if (err)
 832                        *err = E_ASM_NUM_OPERANDS;
 833                return 0;
 834        }
 835
 836        if (asm_debug) {
 837                printf ("asmppc: Instruction = 0x%08lx\n", instr);
 838        }
 839
 840        return instr;
 841}                                                               /* asmppc */
 842
 843
 844
 845/*======================================================================
 846 * Called by the assembler to interpret a single operand
 847 *
 848 * Arguments:
 849 *      ctx             A pointer to the disassembler context record.
 850 *
 851 * Returns 0 if the operand is ok, or -1 if it is bad.
 852 */
 853
 854int parse_operand (unsigned long memaddr, struct opcode *opc,
 855                                   struct operand *oper, char *txt, int *err)
 856{
 857        long data;
 858        long mask;
 859        int is_neg = 0;
 860
 861  /*------------------------------------------------------------*/
 862
 863        mask = (1 << oper->bits) - 1;
 864
 865        if (oper->hint & OH_ADDR) {
 866                data = read_number (txt);
 867
 868                if (opc->hint & H_RELATIVE)
 869                        data = data - memaddr;
 870
 871                if (data < 0)
 872                        is_neg = 1;
 873
 874                data >>= 2;
 875                data &= (mask >> 1);
 876
 877                if (is_neg)
 878                        data |= 1 << (oper->bits - 1);
 879        }
 880
 881        else if (oper->hint & OH_REG) {
 882                if (txt[0] == 'r' || txt[0] == 'R')
 883                        txt++;
 884                else if (txt[0] == '%' && (txt[1] == 'r' || txt[1] == 'R'))
 885                        txt += 2;
 886
 887                data = read_number (txt);
 888                if (data > 31) {
 889                        if (err)
 890                                *err = E_ASM_BAD_REGISTER;
 891                        return -1;
 892                }
 893
 894                data = htonl (data);
 895        }
 896
 897        else if (oper->hint & OH_SPR) {
 898                if ((data = spr_value (txt)) == 0) {
 899                        if (err)
 900                                *err = E_ASM_BAD_SPR;
 901                        return -1;
 902                }
 903        }
 904
 905        else if (oper->hint & OH_TBR) {
 906                if ((data = tbr_value (txt)) == 0) {
 907                        if (err)
 908                                *err = E_ASM_BAD_TBR;
 909                        return -1;
 910                }
 911        }
 912
 913        else {
 914                data = htonl (read_number (txt));
 915        }
 916
 917        return (data & mask) << oper->shift;
 918}                                                               /* parse_operand */
 919
 920
 921char *asm_error_str (int err)
 922{
 923        switch (err) {
 924        case E_ASM_BAD_OPCODE:
 925                return "Bad opcode";
 926        case E_ASM_NUM_OPERANDS:
 927                return "Bad number of operands";
 928        case E_ASM_BAD_REGISTER:
 929                return "Bad register number";
 930        case E_ASM_BAD_SPR:
 931                return "Bad SPR name or number";
 932        case E_ASM_BAD_TBR:
 933                return "Bad TBR name or number";
 934        }
 935
 936        return "";
 937}                                                               /* asm_error_str */
 938
 939
 940
 941/*======================================================================
 942 * Copy a word from one buffer to another, ignores leading white spaces.
 943 *
 944 * Arguments:
 945 *      src             The address of a character pointer to the
 946 *                      source buffer.
 947 *      dest            A pointer to a character buffer to write the word
 948 *                      into.
 949 *
 950 * Returns the number of non-white space characters copied, or zero.
 951 */
 952
 953int get_word (char **src, char *dest)
 954{
 955        char *ptr = *src;
 956        int nchars = 0;
 957
 958  /*------------------------------------------------------------*/
 959
 960        /* Eat white spaces */
 961        while (*ptr && isblank (*ptr))
 962                ptr++;
 963
 964        if (*ptr == 0) {
 965                *src = ptr;
 966                return 0;
 967        }
 968
 969        /* Find the text of the word */
 970        while (*ptr && !isblank (*ptr) && (*ptr != ','))
 971                dest[nchars++] = *ptr++;
 972        ptr = (*ptr == ',') ? ptr + 1 : ptr;
 973        dest[nchars] = 0;
 974
 975        *src = ptr;
 976        return nchars;
 977}                                                               /* get_word */
 978
 979
 980
 981/*======================================================================
 982 * Convert a numeric string to a number, be aware of base notations.
 983 *
 984 * Arguments:
 985 *      txt             The numeric string.
 986 *
 987 * Returns the converted numeric value.
 988 */
 989
 990long read_number (char *txt)
 991{
 992        long val;
 993        int is_neg = 0;
 994
 995  /*------------------------------------------------------------*/
 996
 997        if (txt == 0 || *txt == 0)
 998                return 0;
 999
1000        if (*txt == '-') {
1001                is_neg = 1;
1002                ++txt;
1003        }
1004
1005        if (txt[0] == '0' && (txt[1] == 'x' || txt[1] == 'X'))  /* hex */
1006                val = simple_strtoul (&txt[2], NULL, 16);
1007        else                                            /* decimal */
1008                val = simple_strtoul (txt, NULL, 10);
1009
1010        if (is_neg)
1011                val = -val;
1012
1013        return val;
1014}                                                               /* read_number */
1015
1016
1017int downstring (char *s)
1018{
1019        if (!s || !*s)
1020                return 0;
1021
1022        while (*s) {
1023                if (isupper (*s))
1024                        *s = tolower (*s);
1025                s++;
1026        }
1027
1028        return 0;
1029}                                                               /* downstring */
1030
1031
1032
1033/*======================================================================
1034 * Examines the instruction at the current address and determines the
1035 * next address to be executed.  This will take into account branches
1036 * of different types so that a "step" and "next" operations can be
1037 * supported.
1038 *
1039 * Arguments:
1040 *      nextaddr        The address (to be filled in) of the next
1041 *                      instruction to execute.  This will only be a valid
1042 *                      address if TRUE is returned.
1043 *
1044 *      step_over       A flag indicating how to compute addresses for
1045 *                      branch statements:
1046 *                       TRUE  = Step over the branch (next)
1047 *                       FALSE = step into the branch (step)
1048 *
1049 * Returns TRUE if it was able to compute the address.  Returns FALSE if
1050 * it has a problem reading the current instruction or one of the registers.
1051 */
1052
1053int find_next_address (unsigned char *nextaddr, int step_over,
1054                                           struct pt_regs *regs)
1055{
1056        unsigned long pc;                       /* SRR0 register from PPC */
1057        unsigned long ctr;                      /* CTR register from PPC */
1058        unsigned long cr;                       /* CR register from PPC */
1059        unsigned long lr;                       /* LR register from PPC */
1060        unsigned long instr;            /* instruction at SRR0 */
1061        unsigned long next;                     /* computed instruction for 'next' */
1062        unsigned long step;                     /* computed instruction for 'step' */
1063        unsigned long addr = 0;         /* target address operand */
1064        unsigned long aa = 0;           /* AA operand */
1065        unsigned long lk = 0;           /* LK operand */
1066        unsigned long bo = 0;           /* BO operand */
1067        unsigned long bi = 0;           /* BI operand */
1068        struct opcode *op = 0;          /* opcode structure for 'instr' */
1069        int ctr_ok = 0;
1070        int cond_ok = 0;
1071        int conditional = 0;
1072        int branch = 0;
1073
1074  /*------------------------------------------------------------*/
1075
1076        if (nextaddr == 0 || regs == 0) {
1077                printf ("find_next_address: bad args");
1078                return FALSE;
1079        }
1080
1081        pc = regs->nip & 0xfffffffc;
1082        instr = INSTRUCTION (pc);
1083
1084        if ((op = find_opcode (instr)) == (struct opcode *) 0) {
1085                printf ("find_next_address: can't parse opcode 0x%lx", instr);
1086                return FALSE;
1087        }
1088
1089        ctr = regs->ctr;
1090        cr = regs->ccr;
1091        lr = regs->link;
1092
1093        switch (op->opcode) {
1094        case B_OPCODE (16, 0, 0):       /* bc */
1095        case B_OPCODE (16, 0, 1):       /* bcl */
1096        case B_OPCODE (16, 1, 0):       /* bca */
1097        case B_OPCODE (16, 1, 1):       /* bcla */
1098                if (!get_operand_value (op, instr, O_BD, &addr) ||
1099                        !get_operand_value (op, instr, O_BO, &bo) ||
1100                        !get_operand_value (op, instr, O_BI, &bi) ||
1101                        !get_operand_value (op, instr, O_AA, &aa) ||
1102                        !get_operand_value (op, instr, O_LK, &lk))
1103                        return FALSE;
1104
1105                if ((addr & (1 << 13)) != 0)
1106                        addr = addr - (1 << 14);
1107                addr <<= 2;
1108                conditional = 1;
1109                branch = 1;
1110                break;
1111
1112        case I_OPCODE (18, 0, 0):       /* b */
1113        case I_OPCODE (18, 0, 1):       /* bl */
1114        case I_OPCODE (18, 1, 0):       /* ba */
1115        case I_OPCODE (18, 1, 1):       /* bla */
1116                if (!get_operand_value (op, instr, O_LI, &addr) ||
1117                        !get_operand_value (op, instr, O_AA, &aa) ||
1118                        !get_operand_value (op, instr, O_LK, &lk))
1119                        return FALSE;
1120
1121                if ((addr & (1 << 23)) != 0)
1122                        addr = addr - (1 << 24);
1123                addr <<= 2;
1124                conditional = 0;
1125                branch = 1;
1126                break;
1127
1128        case XL_OPCODE (19, 528, 0):    /* bcctr */
1129        case XL_OPCODE (19, 528, 1):    /* bcctrl */
1130                if (!get_operand_value (op, instr, O_BO, &bo) ||
1131                        !get_operand_value (op, instr, O_BI, &bi) ||
1132                        !get_operand_value (op, instr, O_LK, &lk))
1133                        return FALSE;
1134
1135                addr = ctr;
1136                aa = 1;
1137                conditional = 1;
1138                branch = 1;
1139                break;
1140
1141        case XL_OPCODE (19, 16, 0):     /* bclr */
1142        case XL_OPCODE (19, 16, 1):     /* bclrl */
1143                if (!get_operand_value (op, instr, O_BO, &bo) ||
1144                        !get_operand_value (op, instr, O_BI, &bi) ||
1145                        !get_operand_value (op, instr, O_LK, &lk))
1146                        return FALSE;
1147
1148                addr = lr;
1149                aa = 1;
1150                conditional = 1;
1151                branch = 1;
1152                break;
1153
1154        default:
1155                conditional = 0;
1156                branch = 0;
1157                break;
1158        }
1159
1160        if (conditional) {
1161                switch ((bo & 0x1e) >> 1) {
1162                case 0:                         /* 0000y */
1163                        if (--ctr != 0)
1164                                ctr_ok = 1;
1165
1166                        cond_ok = !(cr & (1 << (31 - bi)));
1167                        break;
1168
1169                case 1:                         /* 0001y */
1170                        if (--ctr == 0)
1171                                ctr_ok = 1;
1172
1173                        cond_ok = !(cr & (1 << (31 - bi)));
1174                        break;
1175
1176                case 2:                         /* 001zy */
1177                        ctr_ok = 1;
1178                        cond_ok = !(cr & (1 << (31 - bi)));
1179                        break;
1180
1181                case 4:                         /* 0100y */
1182                        if (--ctr != 0)
1183                                ctr_ok = 1;
1184
1185                        cond_ok = cr & (1 << (31 - bi));
1186                        break;
1187
1188                case 5:                         /* 0101y */
1189                        if (--ctr == 0)
1190                                ctr_ok = 1;
1191
1192                        cond_ok = cr & (1 << (31 - bi));
1193                        break;
1194
1195                case 6:                         /* 011zy */
1196                        ctr_ok = 1;
1197                        cond_ok = cr & (1 << (31 - bi));
1198                        break;
1199
1200                case 8:                         /* 1z00y */
1201                        if (--ctr != 0)
1202                                ctr_ok = cond_ok = 1;
1203                        break;
1204
1205                case 9:                         /* 1z01y */
1206                        if (--ctr == 0)
1207                                ctr_ok = cond_ok = 1;
1208                        break;
1209
1210                case 10:                                /* 1z1zz */
1211                        ctr_ok = cond_ok = 1;
1212                        break;
1213                }
1214        }
1215
1216        if (branch && (!conditional || (ctr_ok && cond_ok))) {
1217                if (aa)
1218                        step = addr;
1219                else
1220                        step = addr + pc;
1221
1222                if (lk)
1223                        next = pc + 4;
1224                else
1225                        next = step;
1226        } else {
1227                step = next = pc + 4;
1228        }
1229
1230        if (step_over == TRUE)
1231                *(unsigned long *) nextaddr = next;
1232        else
1233                *(unsigned long *) nextaddr = step;
1234
1235        return TRUE;
1236}                                                               /* find_next_address */
1237
1238
1239/*
1240 * Copyright (c) 2000 William L. Pitts and W. Gerald Hicks
1241 * All rights reserved.
1242 *
1243 * Redistribution and use in source and binary forms are freely
1244 * permitted provided that the above copyright notice and this
1245 * paragraph and the following disclaimer are duplicated in all
1246 * such forms.
1247 *
1248 * This software is provided "AS IS" and without any express or
1249 * implied warranties, including, without limitation, the implied
1250 * warranties of merchantability and fitness for a particular
1251 * purpose.
1252 */
1253