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