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