1 /* $Id: bedbug.c,v 1.1.1.1 2010-10-18 09:56:07 roylin Exp $ */
5 #if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
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>
13 #define Elf32_Word unsigned long
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.
20 /* #define USE_SOURCE_CODE 1 */
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 */
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 *));
44 /*======================================================================
45 * Entry point for the PPC disassembler.
48 * memaddr The address to start disassembling from.
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.
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.
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.
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
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.
77 * Returns TRUE if the area was successfully disassembled or FALSE if
78 * a problem was encountered with accessing the memory.
81 int disppc (unsigned char *memaddr
, unsigned char *virtual, int num_instr
,
82 int (*pfunc
) (const char *), unsigned long flags
)
87 #ifdef USE_SOURCE_CODE
90 char funcname
[128] = { 0 };
91 char filename
[256] = { 0 };
92 char last_funcname
[128] = { 0 };
95 char *cursym
= (char *) 0;
96 #endif /* USE_SOURCE_CODE */
97 /*------------------------------------------------------------*/
100 ctx
.virtual = virtual;
102 /* Figure out the output radix before we go any further */
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");
114 /* Unsigned hex output */
115 strcpy (ctx
.radix_fmt
, "0x%x");
118 if (ctx
.virtual == 0) {
119 ctx
.virtual = memaddr
;
121 #ifdef USE_SOURCE_CODE
122 if (ctx
.flags
& F_SYMBOL
) {
123 if (symByAddr
== 0) /* no symbols loaded */
124 ctx
.flags
&= ~F_SYMBOL
;
130 #endif /* USE_SOURCE_CODE */
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 */
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
);
148 last_line_no
= line_no
;
149 strcpy (last_funcname
, funcname
);
151 #endif /* USE_SOURCE_CODE */
153 sprintf (ctx
.data
, "%08lx: ", (unsigned long) ctx
.virtual);
156 #ifdef USE_SOURCE_CODE
157 if (ctx
.flags
& F_SYMBOL
) {
159 symbol_name_from_addr ((Elf32_Word
) ctx
.virtual,
166 symbol_name_from_addr ((Elf32_Word
) ctx
.virtual,
167 FALSE
, &symoffset
)) != 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
);
182 #endif /* USE_SOURCE_CODE */
184 ctx
.instr
= INSTRUCTION (memaddr
);
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),
196 strcat (ctx
.data
, " ");
200 if ((ctx
.op
= find_opcode (ctx
.instr
)) == 0) {
202 sprintf (&ctx
.data
[ctx
.datalen
], " .long 0x%08lx",
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
);
213 print_operands (&ctx
);
224 /*======================================================================
225 * Called by the disassembler to print the operands for an instruction.
228 * ctx A pointer to the disassembler context record.
233 int print_operands (struct ppc_ctx
*ctx
)
237 unsigned long operand
;
240 #ifdef USE_SOURCE_CODE
243 #endif /* USE_SOURCE_CODE */
244 /*------------------------------------------------------------*/
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 ?! */
252 opr
= &operands
[ctx
->op
->fields
[field
] - 1];
254 if (opr
->hint
& OH_SILENT
) {
258 if ((field
> 0) && !open_parens
) {
259 strcat (ctx
->data
, ",");
263 operand
= (ctx
->instr
>> opr
->shift
) & ((1 << opr
->bits
) - 1);
265 if (opr
->hint
& OH_ADDR
) {
266 if ((operand
& (1 << (opr
->bits
- 1))) != 0) {
267 operand
= operand
- (1 << opr
->bits
);
270 if (ctx
->op
->hint
& H_RELATIVE
)
271 operand
= (operand
<< 2) + (unsigned long) ctx
->virtual;
273 operand
= (operand
<< 2);
276 sprintf (&ctx
->data
[ctx
->datalen
], "0x%lx", operand
);
277 ctx
->datalen
= strlen (ctx
->data
);
279 #ifdef USE_SOURCE_CODE
280 if ((ctx
->flags
& F_SYMBOL
) &&
282 symbol_name_from_addr (operand
, 0, &offset
)) != 0)) {
283 sprintf (&ctx
->data
[ctx
->datalen
], " <%s", symname
);
285 strcat (ctx
->data
, "+");
286 ctx
->datalen
= strlen (ctx
->data
);
287 sprintf (&ctx
->data
[ctx
->datalen
], ctx
->radix_fmt
,
290 strcat (ctx
->data
, ">");
292 #endif /* USE_SOURCE_CODE */
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");
300 sprintf (&ctx
->data
[ctx
->datalen
], "r%d", (short) operand
);
304 strcat (ctx
->data
, ")");
309 else if (opr
->hint
& OH_SPR
) {
310 strcat (ctx
->data
, spr_name (operand
));
313 else if (opr
->hint
& OH_TBR
) {
314 strcat (ctx
->data
, tbr_name (operand
));
317 else if (opr
->hint
& OH_LITERAL
) {
318 switch (opr
->field
) {
320 strcat (ctx
->data
, "cr2");
330 sprintf (&ctx
->data
[ctx
->datalen
], ctx
->radix_fmt
,
331 (unsigned short) operand
);
334 strcat (ctx
->data
, ")");
338 else if (opr
->hint
& OH_OFFSET
) {
339 strcat (ctx
->data
, "(");
344 ctx
->datalen
= strlen (ctx
->data
);
348 } /* print_operands */
352 /*======================================================================
353 * Called to get the value of an arbitrary operand with in an instruction.
356 * op The pointer to the opcode structure to which
357 * the operands belong.
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.
364 * field The field (operand) to get the value of.
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
372 * Returns TRUE if the operand was found or FALSE if it was not.
375 int get_operand_value (struct opcode
*op
, unsigned long instr
,
376 enum OP_FIELD field
, unsigned long *value
)
381 /*------------------------------------------------------------*/
383 if (field
> n_operands
) {
384 return FALSE
; /* bad operand ?! */
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
) {
393 opr
= &operands
[op
->fields
[i
] - 1];
396 *value
= (instr
>> opr
->shift
) & ((1 << opr
->bits
) - 1);
402 } /* operand_value */
406 /*======================================================================
407 * Called by the disassembler to match an opcode value to an opcode structure.
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
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.
419 struct opcode
*find_opcode (unsigned long instr
)
423 int bottom
= n_opcodes
- 1;
426 /*------------------------------------------------------------*/
428 while (top
<= bottom
) {
429 idx
= (top
+ bottom
) >> 1;
432 if ((instr
& ptr
->mask
) < ptr
->opcode
) {
434 } else if ((instr
& ptr
->mask
) > ptr
->opcode
) {
441 return (struct opcode
*) 0;
446 /*======================================================================
447 * Called by the assembler to match an opcode name to an opcode structure.
450 * name The text name of the opcode, e.g. "b", "mtspr", etc.
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.
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.
460 struct opcode
*find_opcode_by_name (char *name
)
464 /*------------------------------------------------------------*/
468 for (idx
= 0; idx
< n_opcodes
; ++idx
) {
469 if (!strcmp (name
, opcodes
[idx
].name
))
470 return &opcodes
[idx
];
473 return (struct opcode
*) 0;
474 } /* find_opcode_by_name */
478 /*======================================================================
479 * Convert the 'spr' operand from its numeric value to its symbolic name.
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.
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.
492 char *spr_name (int value
)
495 static char other
[10];
498 /*------------------------------------------------------------*/
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 */
503 spr
= ((value
>> 5) & 0x1f) | ((value
& 0x1f) << 5);
505 for (i
= 0; i
< n_sprs
; ++i
) {
506 if (spr
== spr_map
[i
].spr_val
)
507 return spr_map
[i
].spr_name
;
510 sprintf (other
, "%d", spr
);
516 /*======================================================================
517 * Convert the 'spr' operand from its symbolic name to its numeric value
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.
524 * Returns the numeric value for the spr appropriate for encoding a machine
525 * instruction. Returns 0 if unable to find the SPR.
528 int spr_value (char *name
)
530 struct spr_info
*sprp
;
534 /*------------------------------------------------------------*/
539 if (isdigit ((int) name
[0])) {
540 i
= htonl (read_number (name
));
541 spr
= ((i
>> 5) & 0x1f) | ((i
& 0x1f) << 5);
547 for (i
= 0; i
< n_sprs
; ++i
) {
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);
565 /*======================================================================
566 * Convert the 'tbr' operand from its numeric value to its symbolic name.
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.
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.
579 char *tbr_name (int value
)
583 /*------------------------------------------------------------*/
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 */
588 tbr
= ((value
>> 5) & 0x1f) | ((value
& 0x1f) << 5);
602 /*======================================================================
603 * Convert the 'tbr' operand from its symbolic name to its numeric value.
606 * name The symbolic name of the 'tbr' operand. The
607 * split-field encoding will be done by this routine.
609 * Returns the numeric value for the spr appropriate for encoding a machine
610 * instruction. Returns 0 if unable to find the TBR.
613 int tbr_value (char *name
)
618 /*------------------------------------------------------------*/
625 if (isdigit ((int) name
[0])) {
626 val
= read_number (name
);
628 if (val
!= 268 && val
!= 269)
630 } else if (strcmp (name
, "tbl") == 0)
632 else if (strcmp (name
, "tbu") == 0)
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 */
641 tbr
= ((val
>> 5) & 0x1f) | ((val
& 0x1f) << 5);
647 /*======================================================================
648 * The next several functions (handle_xxx) are the routines that handle
649 * disassembling the opcodes with simplified mnemonics.
652 * ctx A pointer to the disassembler context record.
654 * Returns TRUE if the simpler form was printed or FALSE if it was not.
657 int handle_bc (struct ppc_ctx
*ctx
)
661 static struct opcode blt
= { B_OPCODE (16, 0, 0), B_MASK
, {O_BD
, 0},
664 static struct opcode bne
=
665 { B_OPCODE (16, 0, 0), B_MASK
, {O_cr2
, O_BD
, 0},
668 static struct opcode bdnz
= { B_OPCODE (16, 0, 0), B_MASK
, {O_BD
, 0},
669 0, "bdnz", H_RELATIVE
672 /*------------------------------------------------------------*/
674 if (get_operand_value (ctx
->op
, ctx
->instr
, O_BO
, &bo
) == FALSE
)
677 if (get_operand_value (ctx
->op
, ctx
->instr
, O_BI
, &bi
) == FALSE
)
680 if ((bo
== 12) && (bi
== 0)) {
682 sprintf (&ctx
->data
[ctx
->datalen
], "%-7s ", ctx
->op
->name
);
684 print_operands (ctx
);
686 } else if ((bo
== 4) && (bi
== 10)) {
688 sprintf (&ctx
->data
[ctx
->datalen
], "%-7s ", ctx
->op
->name
);
690 print_operands (ctx
);
692 } else if ((bo
== 16) && (bi
== 0)) {
694 sprintf (&ctx
->data
[ctx
->datalen
], "%-7s ", ctx
->op
->name
);
696 print_operands (ctx
);
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.
711 * filename The address of a character array containing the
712 * absolute path and file name of the source file.
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.
718 * line_no An integer specifying the source line number that
719 * generated this code.
721 * pfunc The address of a function to call to print the output.
724 * Returns TRUE if it was able to output the line info, or false if it was
728 int print_source_line (char *filename
, char *funcname
,
729 int line_no
, int (*pfunc
) (const char *))
733 /*------------------------------------------------------------*/
735 (*pfunc
) (""); /* output a newline */
736 sprintf (out_buf
, "%s %s(): line %d", filename
, funcname
, line_no
);
740 } /* print_source_line */
744 /*======================================================================
745 * Entry point for the PPC assembler.
748 * asm_buf An array of characters containing the assembly opcode
749 * and operands to convert to a POWERPC machine
752 * Returns the machine instruction or zero.
755 unsigned long asmppc (unsigned long memaddr
, char *asm_buf
, int *err
)
758 struct operand
*oper
[MAX_OPERANDS
];
764 int w_operands
= 0; /* wanted # of operands */
765 int n_operands
= 0; /* # of operands read */
768 /*------------------------------------------------------------*/
773 if (get_word (&ptr
, scratch
) == 0)
776 /* Lookup the opcode structure based on the opcode name */
777 if ((opc
= find_opcode_by_name (scratch
)) == (struct opcode
*) 0) {
779 *err
= E_ASM_BAD_OPCODE
;
784 printf ("asmppc: Opcode = \"%s\"\n", opc
->name
);
787 for (i
= 0; i
< 8; ++i
) {
788 if (opc
->fields
[i
] == 0)
794 printf ("asmppc: Expecting %d operands\n", w_operands
);
799 /* read each operand */
800 while (n_operands
< w_operands
) {
802 oper
[n_operands
] = &operands
[opc
->fields
[n_operands
] - 1];
804 if (oper
[n_operands
]->hint
& OH_SILENT
) {
805 /* Skip silent operands, they are covered in opc->opcode */
808 printf ("asmppc: Operand %d \"%s\" SILENT\n", n_operands
,
809 oper
[n_operands
]->name
);
816 if (get_word (&ptr
, scratch
) == 0)
820 printf ("asmppc: Operand %d \"%s\" : \"%s\"\n", n_operands
,
821 oper
[n_operands
]->name
, scratch
);
824 if ((param
= parse_operand (memaddr
, opc
, oper
[n_operands
],
825 scratch
, err
)) == -1)
832 if (n_operands
< w_operands
) {
834 *err
= E_ASM_NUM_OPERANDS
;
839 printf ("asmppc: Instruction = 0x%08lx\n", instr
);
847 /*======================================================================
848 * Called by the assembler to interpret a single operand
851 * ctx A pointer to the disassembler context record.
853 * Returns 0 if the operand is ok, or -1 if it is bad.
856 int parse_operand (unsigned long memaddr
, struct opcode
*opc
,
857 struct operand
*oper
, char *txt
, int *err
)
863 /*------------------------------------------------------------*/
865 mask
= (1 << oper
->bits
) - 1;
867 if (oper
->hint
& OH_ADDR
) {
868 data
= read_number (txt
);
870 if (opc
->hint
& H_RELATIVE
)
871 data
= data
- memaddr
;
880 data
|= 1 << (oper
->bits
- 1);
883 else if (oper
->hint
& OH_REG
) {
884 if (txt
[0] == 'r' || txt
[0] == 'R')
886 else if (txt
[0] == '%' && (txt
[1] == 'r' || txt
[1] == 'R'))
889 data
= read_number (txt
);
892 *err
= E_ASM_BAD_REGISTER
;
899 else if (oper
->hint
& OH_SPR
) {
900 if ((data
= spr_value (txt
)) == 0) {
902 *err
= E_ASM_BAD_SPR
;
907 else if (oper
->hint
& OH_TBR
) {
908 if ((data
= tbr_value (txt
)) == 0) {
910 *err
= E_ASM_BAD_TBR
;
916 data
= htonl (read_number (txt
));
919 return (data
& mask
) << oper
->shift
;
920 } /* parse_operand */
923 char *asm_error_str (int err
)
926 case E_ASM_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";
933 return "Bad SPR name or number";
935 return "Bad TBR name or number";
939 } /* asm_error_str */
943 /*======================================================================
944 * Copy a word from one buffer to another, ignores leading white spaces.
947 * src The address of a character pointer to the
949 * dest A pointer to a character buffer to write the word
952 * Returns the number of non-white space characters copied, or zero.
955 int get_word (char **src
, char *dest
)
960 /*------------------------------------------------------------*/
962 /* Eat white spaces */
963 while (*ptr
&& isblank (*ptr
))
971 /* Find the text of the word */
972 while (*ptr
&& !isblank (*ptr
) && (*ptr
!= ','))
973 dest
[nchars
++] = *ptr
++;
974 ptr
= (*ptr
== ',') ? ptr
+ 1 : ptr
;
983 /*======================================================================
984 * Convert a numeric string to a number, be aware of base notations.
987 * txt The numeric string.
989 * Returns the converted numeric value.
992 long read_number (char *txt
)
997 /*------------------------------------------------------------*/
999 if (txt
== 0 || *txt
== 0)
1007 if (txt
[0] == '0' && (txt
[1] == 'x' || txt
[1] == 'X')) /* hex */
1008 val
= simple_strtoul (&txt
[2], NULL
, 16);
1010 val
= simple_strtoul (txt
, NULL
, 10);
1019 int downstring (char *s
)
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
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.
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)
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.
1055 int find_next_address (unsigned char *nextaddr
, int step_over
,
1056 struct pt_regs
*regs
)
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' */
1073 int conditional
= 0;
1076 /*------------------------------------------------------------*/
1078 if (nextaddr
== 0 || regs
== 0) {
1079 printf ("find_next_address: bad args");
1083 pc
= regs
->nip
& 0xfffffffc;
1084 instr
= INSTRUCTION (pc
);
1086 if ((op
= find_opcode (instr
)) == (struct opcode
*) 0) {
1087 printf ("find_next_address: can't parse opcode 0x%lx", instr
);
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
))
1107 if ((addr
& (1 << 13)) != 0)
1108 addr
= addr
- (1 << 14);
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
))
1123 if ((addr
& (1 << 23)) != 0)
1124 addr
= addr
- (1 << 24);
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
))
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
))
1163 switch ((bo
& 0x1e) >> 1) {
1168 cond_ok
= !(cr
& (1 << (31 - bi
)));
1175 cond_ok
= !(cr
& (1 << (31 - bi
)));
1180 cond_ok
= !(cr
& (1 << (31 - bi
)));
1187 cond_ok
= cr
& (1 << (31 - bi
));
1194 cond_ok
= cr
& (1 << (31 - bi
));
1199 cond_ok
= cr
& (1 << (31 - bi
));
1204 ctr_ok
= cond_ok
= 1;
1209 ctr_ok
= cond_ok
= 1;
1212 case 10: /* 1z1zz */
1213 ctr_ok
= cond_ok
= 1;
1218 if (branch
&& (!conditional
|| (ctr_ok
&& cond_ok
))) {
1229 step
= next
= pc
+ 4;
1232 if (step_over
== TRUE
)
1233 *(unsigned long *) nextaddr
= next
;
1235 *(unsigned long *) nextaddr
= step
;
1238 } /* find_next_address */
1242 * Copyright (c) 2000 William L. Pitts and W. Gerald Hicks
1243 * All rights reserved.
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
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
1256 #endif /* CONFIG_COMMANDS & CFG_CMD_BEDBUG */