Merge commit 'wd/master'
[platform/kernel/u-boot.git] / common / bedbug.c
1 /* $Id$ */
2
3 #include <common.h>
4
5 #if defined(CONFIG_CMD_BEDBUG)
6
7 #include <linux/ctype.h>
8 #include <bedbug/bedbug.h>
9 #include <bedbug/ppc.h>
10 #include <bedbug/regs.h>
11 #include <bedbug/tables.h>
12
13 #define Elf32_Word      unsigned long
14
15 /* USE_SOURCE_CODE enables some symbolic debugging functions of this
16    code.  This is only useful if the program will have access to the
17    source code for the binary being examined.
18 */
19
20 /* #define USE_SOURCE_CODE 1 */
21
22 #ifdef USE_SOURCE_CODE
23 extern int line_info_from_addr __P ((Elf32_Word, char *, char *, int *));
24 extern struct symreflist *symByAddr;
25 extern char *symbol_name_from_addr __P ((Elf32_Word, int, int *));
26 #endif /* USE_SOURCE_CODE */
27
28 int print_operands __P ((struct ppc_ctx *));
29 int get_operand_value __P ((struct opcode *, unsigned long,
30                                 enum OP_FIELD, unsigned long *));
31 struct opcode *find_opcode __P ((unsigned long));
32 struct opcode *find_opcode_by_name __P ((char *));
33 char *spr_name __P ((int));
34 int spr_value __P ((char *));
35 char *tbr_name __P ((int));
36 int tbr_value __P ((char *));
37 int parse_operand __P ((unsigned long, struct opcode *,
38                         struct operand *, char *, int *));
39 int get_word __P ((char **, char *));
40 long read_number __P ((char *));
41 int downstring __P ((char *));
42 \f
43
44 /*======================================================================
45  * Entry point for the PPC disassembler.
46  *
47  * Arguments:
48  *      memaddr         The address to start disassembling from.
49  *
50  *      virtual         If this value is non-zero, then this will be
51  *                      used as the base address for the output and
52  *                      symbol lookups.  If this value is zero then
53  *                      memaddr is used as the absolute address.
54  *
55  *      num_instr       The number of instructions to disassemble.  Since
56  *                      each instruction is 32 bits long, this can be
57  *                      computed if you know the total size of the region.
58  *
59  *      pfunc           The address of a function that is called to print
60  *                      each line of output.  The function should take a
61  *                      single character pointer as its parameters a la puts.
62  *
63  *      flags           Sets options for the output.  This is a
64  *                      bitwise-inclusive-OR of the following
65  *                      values.  Note that only one of the radix
66  *                      options may be set.
67  *
68  *                      F_RADOCTAL      - output radix is unsigned base 8.
69  *                      F_RADUDECIMAL   - output radix is unsigned base 10.
70  *                      F_RADSDECIMAL   - output radix is signed base 10.
71  *                      F_RADHEX        - output radix is unsigned base 16.
72  *                      F_SIMPLE        - use simplified mnemonics.
73  *                      F_SYMBOL        - lookup symbols for addresses.
74  *                      F_INSTR         - output raw instruction.
75  *                      F_LINENO        - show line # info if available.
76  *
77  * Returns TRUE if the area was successfully disassembled or FALSE if
78  * a problem was encountered with accessing the memory.
79  */
80
81 int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr,
82                         int (*pfunc) (const char *), unsigned long flags)
83 {
84         int i;
85         struct ppc_ctx ctx;
86
87 #ifdef USE_SOURCE_CODE
88         int line_no = 0;
89         int last_line_no = 0;
90         char funcname[128] = { 0 };
91         char filename[256] = { 0 };
92         char last_funcname[128] = { 0 };
93         int symoffset;
94         char *symname;
95         char *cursym = (char *) 0;
96 #endif /* USE_SOURCE_CODE */
97   /*------------------------------------------------------------*/
98
99         ctx.flags = flags;
100         ctx.virtual = virtual;
101
102         /* Figure out the output radix before we go any further */
103
104         if (ctx.flags & F_RADOCTAL) {
105                 /* Unsigned octal output */
106                 strcpy (ctx.radix_fmt, "O%o");
107         } else if (ctx.flags & F_RADUDECIMAL) {
108                 /* Unsigned decimal output */
109                 strcpy (ctx.radix_fmt, "%u");
110         } else if (ctx.flags & F_RADSDECIMAL) {
111                 /* Signed decimal output */
112                 strcpy (ctx.radix_fmt, "%d");
113         } else {
114                 /* Unsigned hex output */
115                 strcpy (ctx.radix_fmt, "0x%x");
116         }
117
118         if (ctx.virtual == 0) {
119                 ctx.virtual = memaddr;
120         }
121 #ifdef USE_SOURCE_CODE
122         if (ctx.flags & F_SYMBOL) {
123                 if (symByAddr == 0)             /* no symbols loaded */
124                         ctx.flags &= ~F_SYMBOL;
125                 else {
126                         cursym = (char *) 0;
127                         symoffset = 0;
128                 }
129         }
130 #endif /* USE_SOURCE_CODE */
131
132         /* format each line as "XXXXXXXX: <symbol> IIIIIIII  disassembly" where,
133            XXXXXXXX is the memory address in hex,
134            <symbol> is the symbolic location if F_SYMBOL is set.
135            IIIIIIII is the raw machine code in hex if F_INSTR is set,
136            and disassembly is the disassembled machine code with numbers
137            formatted according to the 'radix' parameter */
138
139         for (i = 0; i < num_instr; ++i, memaddr += 4, ctx.virtual += 4) {
140 #ifdef USE_SOURCE_CODE
141                 if (ctx.flags & F_LINENO) {
142                         if ((line_info_from_addr ((Elf32_Word) ctx.virtual, filename,
143                                                                           funcname, &line_no) == TRUE) &&
144                                 ((line_no != last_line_no) ||
145                                  (strcmp (last_funcname, funcname) != 0))) {
146                                 print_source_line (filename, funcname, line_no, pfunc);
147                         }
148                         last_line_no = line_no;
149                         strcpy (last_funcname, funcname);
150                 }
151 #endif /* USE_SOURCE_CODE */
152
153                 sprintf (ctx.data, "%08lx: ", (unsigned long) ctx.virtual);
154                 ctx.datalen = 10;
155
156 #ifdef USE_SOURCE_CODE
157                 if (ctx.flags & F_SYMBOL) {
158                         if ((symname =
159                                  symbol_name_from_addr ((Elf32_Word) ctx.virtual,
160                                                                                 TRUE, 0)) != 0) {
161                                 cursym = symname;
162                                 symoffset = 0;
163                         } else {
164                                 if ((cursym == 0) &&
165                                         ((symname =
166                                           symbol_name_from_addr ((Elf32_Word) ctx.virtual,
167                                                                                          FALSE, &symoffset)) != 0)) {
168                                         cursym = symname;
169                                 } else {
170                                         symoffset += 4;
171                                 }
172                         }
173
174                         if (cursym != 0) {
175                                 sprintf (&ctx.data[ctx.datalen], "<%s+", cursym);
176                                 ctx.datalen = strlen (ctx.data);
177                                 sprintf (&ctx.data[ctx.datalen], ctx.radix_fmt, symoffset);
178                                 strcat (ctx.data, ">");
179                                 ctx.datalen = strlen (ctx.data);
180                         }
181                 }
182 #endif /* USE_SOURCE_CODE */
183
184                 ctx.instr = INSTRUCTION (memaddr);
185
186                 if (ctx.flags & F_INSTR) {
187                         /* Find the opcode structure for this opcode.  If one is not found
188                            then it must be an illegal instruction */
189                         sprintf (&ctx.data[ctx.datalen],
190                                          "   %02lx %02lx %02lx %02lx    ",
191                                          ((ctx.instr >> 24) & 0xff),
192                                          ((ctx.instr >> 16) & 0xff), ((ctx.instr >> 8) & 0xff),
193                                          (ctx.instr & 0xff));
194                         ctx.datalen += 18;
195                 } else {
196                         strcat (ctx.data, "   ");
197                         ctx.datalen += 3;
198                 }
199
200                 if ((ctx.op = find_opcode (ctx.instr)) == 0) {
201                         /* Illegal Opcode */
202                         sprintf (&ctx.data[ctx.datalen], "        .long 0x%08lx",
203                                          ctx.instr);
204                         ctx.datalen += 24;
205                         (*pfunc) (ctx.data);
206                         continue;
207                 }
208
209                 if (((ctx.flags & F_SIMPLE) == 0) ||
210                         (ctx.op->hfunc == 0) || ((*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 \f
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
233 int 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 \f
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
375 int 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 \f
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
419 struct 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 \f
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
460 struct 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 \f
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
492 char *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 \f
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
528 int 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 \f
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
579 char *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 \f
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
613 int 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 \f
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
657 int 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 \f
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
728 int 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 \f
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
755 unsigned 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 \f
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
856 int 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
923 char *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 \f
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
955 int 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 \f
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
992 long 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 = simple_strtoul (&txt[2], NULL, 16);
1009         else                                            /* decimal */
1010                 val = simple_strtoul (txt, NULL, 10);
1011
1012         if (is_neg)
1013                 val = -val;
1014
1015         return val;
1016 }                                                               /* read_number */
1017
1018
1019 int 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 \f
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
1055 int 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
1256 #endif