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