]>
git.ipfire.org Git - people/ms/u-boot.git/blob - common/bedbug.c
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>
11 #define Elf32_Word unsigned long
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.
18 /* #define USE_SOURCE_CODE 1 */
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 */
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 *));
42 /*======================================================================
43 * Entry point for the PPC disassembler.
46 * memaddr The address to start disassembling from.
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.
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.
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.
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
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.
75 * Returns true if the area was successfully disassembled or false if
76 * a problem was encountered with accessing the memory.
79 int disppc (unsigned char *memaddr
, unsigned char *virtual, int num_instr
,
80 int (*pfunc
) (const char *), unsigned long flags
)
85 #ifdef USE_SOURCE_CODE
88 char funcname
[128] = { 0 };
89 char filename
[256] = { 0 };
90 char last_funcname
[128] = { 0 };
93 char *cursym
= (char *) 0;
94 #endif /* USE_SOURCE_CODE */
95 /*------------------------------------------------------------*/
98 ctx
.virtual = virtual;
100 /* Figure out the output radix before we go any further */
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");
112 /* Unsigned hex output */
113 strcpy (ctx
.radix_fmt
, "0x%x");
116 if (ctx
.virtual == 0) {
117 ctx
.virtual = memaddr
;
119 #ifdef USE_SOURCE_CODE
120 if (ctx
.flags
& F_SYMBOL
) {
121 if (symByAddr
== 0) /* no symbols loaded */
122 ctx
.flags
&= ~F_SYMBOL
;
128 #endif /* USE_SOURCE_CODE */
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 */
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
);
146 last_line_no
= line_no
;
147 strcpy (last_funcname
, funcname
);
149 #endif /* USE_SOURCE_CODE */
151 sprintf (ctx
.data
, "%08lx: ", (unsigned long) ctx
.virtual);
154 #ifdef USE_SOURCE_CODE
155 if (ctx
.flags
& F_SYMBOL
) {
157 symbol_name_from_addr((Elf32_Word
) ctx
.virtual,
164 symbol_name_from_addr((Elf32_Word
) ctx
.virtual,
165 false, &symoffset
)) != 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
);
180 #endif /* USE_SOURCE_CODE */
182 ctx
.instr
= INSTRUCTION (memaddr
);
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),
194 strcat (ctx
.data
, " ");
198 if ((ctx
.op
= find_opcode (ctx
.instr
)) == 0) {
200 sprintf (&ctx
.data
[ctx
.datalen
], " .long 0x%08lx",
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
);
212 print_operands (&ctx
);
223 /*======================================================================
224 * Called by the disassembler to print the operands for an instruction.
227 * ctx A pointer to the disassembler context record.
232 int print_operands (struct ppc_ctx
*ctx
)
236 unsigned long operand
;
239 #ifdef USE_SOURCE_CODE
242 #endif /* USE_SOURCE_CODE */
243 /*------------------------------------------------------------*/
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 ?! */
251 opr
= &operands
[ctx
->op
->fields
[field
] - 1];
253 if (opr
->hint
& OH_SILENT
) {
257 if ((field
> 0) && !open_parens
) {
258 strcat (ctx
->data
, ",");
262 operand
= (ctx
->instr
>> opr
->shift
) & ((1 << opr
->bits
) - 1);
264 if (opr
->hint
& OH_ADDR
) {
265 if ((operand
& (1 << (opr
->bits
- 1))) != 0) {
266 operand
= operand
- (1 << opr
->bits
);
269 if (ctx
->op
->hint
& H_RELATIVE
)
270 operand
= (operand
<< 2) + (unsigned long) ctx
->virtual;
272 operand
= (operand
<< 2);
275 sprintf (&ctx
->data
[ctx
->datalen
], "0x%lx", operand
);
276 ctx
->datalen
= strlen (ctx
->data
);
278 #ifdef USE_SOURCE_CODE
279 if ((ctx
->flags
& F_SYMBOL
) &&
281 symbol_name_from_addr (operand
, 0, &offset
)) != 0)) {
282 sprintf (&ctx
->data
[ctx
->datalen
], " <%s", symname
);
284 strcat (ctx
->data
, "+");
285 ctx
->datalen
= strlen (ctx
->data
);
286 sprintf (&ctx
->data
[ctx
->datalen
], ctx
->radix_fmt
,
289 strcat (ctx
->data
, ">");
291 #endif /* USE_SOURCE_CODE */
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");
299 sprintf (&ctx
->data
[ctx
->datalen
], "r%d", (short) operand
);
303 strcat (ctx
->data
, ")");
308 else if (opr
->hint
& OH_SPR
) {
309 strcat (ctx
->data
, spr_name (operand
));
312 else if (opr
->hint
& OH_TBR
) {
313 strcat (ctx
->data
, tbr_name (operand
));
316 else if (opr
->hint
& OH_LITERAL
) {
317 switch (opr
->field
) {
319 strcat (ctx
->data
, "cr2");
329 sprintf (&ctx
->data
[ctx
->datalen
], ctx
->radix_fmt
,
330 (unsigned short) operand
);
333 strcat (ctx
->data
, ")");
337 else if (opr
->hint
& OH_OFFSET
) {
338 strcat (ctx
->data
, "(");
343 ctx
->datalen
= strlen (ctx
->data
);
347 } /* print_operands */
351 /*======================================================================
352 * Called to get the value of an arbitrary operand with in an instruction.
355 * op The pointer to the opcode structure to which
356 * the operands belong.
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.
363 * field The field (operand) to get the value of.
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
371 * Returns true if the operand was found or false if it was not.
374 int get_operand_value (struct opcode
*op
, unsigned long instr
,
375 enum OP_FIELD field
, unsigned long *value
)
380 /*------------------------------------------------------------*/
382 if (field
> n_operands
) {
383 return false; /* bad operand ?! */
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
) {
392 opr
= &operands
[op
->fields
[i
] - 1];
395 *value
= (instr
>> opr
->shift
) & ((1 << opr
->bits
) - 1);
401 } /* operand_value */
405 /*======================================================================
406 * Called by the disassembler to match an opcode value to an opcode structure.
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
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.
418 struct opcode
*find_opcode (unsigned long instr
)
422 int bottom
= n_opcodes
- 1;
425 /*------------------------------------------------------------*/
427 while (top
<= bottom
) {
428 idx
= (top
+ bottom
) >> 1;
431 if ((instr
& ptr
->mask
) < ptr
->opcode
) {
433 } else if ((instr
& ptr
->mask
) > ptr
->opcode
) {
440 return (struct opcode
*) 0;
445 /*======================================================================
446 * Called by the assembler to match an opcode name to an opcode structure.
449 * name The text name of the opcode, e.g. "b", "mtspr", etc.
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.
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.
459 struct opcode
*find_opcode_by_name (char *name
)
463 /*------------------------------------------------------------*/
467 for (idx
= 0; idx
< n_opcodes
; ++idx
) {
468 if (!strcmp (name
, opcodes
[idx
].name
))
469 return &opcodes
[idx
];
472 return (struct opcode
*) 0;
473 } /* find_opcode_by_name */
477 /*======================================================================
478 * Convert the 'spr' operand from its numeric value to its symbolic name.
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.
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.
491 char *spr_name (int value
)
494 static char other
[10];
497 /*------------------------------------------------------------*/
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 */
502 spr
= ((value
>> 5) & 0x1f) | ((value
& 0x1f) << 5);
504 for (i
= 0; i
< n_sprs
; ++i
) {
505 if (spr
== spr_map
[i
].spr_val
)
506 return spr_map
[i
].spr_name
;
509 sprintf (other
, "%d", spr
);
515 /*======================================================================
516 * Convert the 'spr' operand from its symbolic name to its numeric value
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.
523 * Returns the numeric value for the spr appropriate for encoding a machine
524 * instruction. Returns 0 if unable to find the SPR.
527 int spr_value (char *name
)
529 struct spr_info
*sprp
;
533 /*------------------------------------------------------------*/
538 if (isdigit ((int) name
[0])) {
539 i
= htonl (read_number (name
));
540 spr
= ((i
>> 5) & 0x1f) | ((i
& 0x1f) << 5);
546 for (i
= 0; i
< n_sprs
; ++i
) {
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);
564 /*======================================================================
565 * Convert the 'tbr' operand from its numeric value to its symbolic name.
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.
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.
578 char *tbr_name (int value
)
582 /*------------------------------------------------------------*/
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 */
587 tbr
= ((value
>> 5) & 0x1f) | ((value
& 0x1f) << 5);
601 /*======================================================================
602 * Convert the 'tbr' operand from its symbolic name to its numeric value.
605 * name The symbolic name of the 'tbr' operand. The
606 * split-field encoding will be done by this routine.
608 * Returns the numeric value for the spr appropriate for encoding a machine
609 * instruction. Returns 0 if unable to find the TBR.
612 int tbr_value (char *name
)
617 /*------------------------------------------------------------*/
624 if (isdigit ((int) name
[0])) {
625 val
= read_number (name
);
627 if (val
!= 268 && val
!= 269)
629 } else if (strcmp (name
, "tbl") == 0)
631 else if (strcmp (name
, "tbu") == 0)
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 */
640 tbr
= ((val
>> 5) & 0x1f) | ((val
& 0x1f) << 5);
646 /*======================================================================
647 * The next several functions (handle_xxx) are the routines that handle
648 * disassembling the opcodes with simplified mnemonics.
651 * ctx A pointer to the disassembler context record.
653 * Returns true if the simpler form was printed or false if it was not.
656 int handle_bc (struct ppc_ctx
*ctx
)
660 static struct opcode blt
= { B_OPCODE (16, 0, 0), B_MASK
, {O_BD
, 0},
663 static struct opcode bne
=
664 { B_OPCODE (16, 0, 0), B_MASK
, {O_cr2
, O_BD
, 0},
667 static struct opcode bdnz
= { B_OPCODE (16, 0, 0), B_MASK
, {O_BD
, 0},
668 0, "bdnz", H_RELATIVE
671 /*------------------------------------------------------------*/
673 if (get_operand_value(ctx
->op
, ctx
->instr
, O_BO
, &bo
) == false)
676 if (get_operand_value(ctx
->op
, ctx
->instr
, O_BI
, &bi
) == false)
679 if ((bo
== 12) && (bi
== 0)) {
681 sprintf (&ctx
->data
[ctx
->datalen
], "%-7s ", ctx
->op
->name
);
683 print_operands (ctx
);
685 } else if ((bo
== 4) && (bi
== 10)) {
687 sprintf (&ctx
->data
[ctx
->datalen
], "%-7s ", ctx
->op
->name
);
689 print_operands (ctx
);
691 } else if ((bo
== 16) && (bi
== 0)) {
693 sprintf (&ctx
->data
[ctx
->datalen
], "%-7s ", ctx
->op
->name
);
695 print_operands (ctx
);
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.
710 * filename The address of a character array containing the
711 * absolute path and file name of the source file.
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.
717 * line_no An integer specifying the source line number that
718 * generated this code.
720 * pfunc The address of a function to call to print the output.
723 * Returns true if it was able to output the line info, or false if it was
727 int print_source_line (char *filename
, char *funcname
,
728 int line_no
, int (*pfunc
) (const char *))
732 /*------------------------------------------------------------*/
734 (*pfunc
) (""); /* output a newline */
735 sprintf (out_buf
, "%s %s(): line %d", filename
, funcname
, line_no
);
739 } /* print_source_line */
743 /*======================================================================
744 * Entry point for the PPC assembler.
747 * asm_buf An array of characters containing the assembly opcode
748 * and operands to convert to a POWERPC machine
751 * Returns the machine instruction or zero.
754 unsigned long asmppc (unsigned long memaddr
, char *asm_buf
, int *err
)
757 struct operand
*oper
[MAX_OPERANDS
];
763 int w_operands
= 0; /* wanted # of operands */
764 int n_operands
= 0; /* # of operands read */
767 /*------------------------------------------------------------*/
772 if (get_word (&ptr
, scratch
) == 0)
775 /* Lookup the opcode structure based on the opcode name */
776 if ((opc
= find_opcode_by_name (scratch
)) == (struct opcode
*) 0) {
778 *err
= E_ASM_BAD_OPCODE
;
783 printf ("asmppc: Opcode = \"%s\"\n", opc
->name
);
786 for (i
= 0; i
< 8; ++i
) {
787 if (opc
->fields
[i
] == 0)
793 printf ("asmppc: Expecting %d operands\n", w_operands
);
798 /* read each operand */
799 while (n_operands
< w_operands
) {
801 oper
[n_operands
] = &operands
[opc
->fields
[n_operands
] - 1];
803 if (oper
[n_operands
]->hint
& OH_SILENT
) {
804 /* Skip silent operands, they are covered in opc->opcode */
807 printf ("asmppc: Operand %d \"%s\" SILENT\n", n_operands
,
808 oper
[n_operands
]->name
);
815 if (get_word (&ptr
, scratch
) == 0)
819 printf ("asmppc: Operand %d \"%s\" : \"%s\"\n", n_operands
,
820 oper
[n_operands
]->name
, scratch
);
823 if ((param
= parse_operand (memaddr
, opc
, oper
[n_operands
],
824 scratch
, err
)) == -1)
831 if (n_operands
< w_operands
) {
833 *err
= E_ASM_NUM_OPERANDS
;
838 printf ("asmppc: Instruction = 0x%08lx\n", instr
);
846 /*======================================================================
847 * Called by the assembler to interpret a single operand
850 * ctx A pointer to the disassembler context record.
852 * Returns 0 if the operand is ok, or -1 if it is bad.
855 int parse_operand (unsigned long memaddr
, struct opcode
*opc
,
856 struct operand
*oper
, char *txt
, int *err
)
862 /*------------------------------------------------------------*/
864 mask
= (1 << oper
->bits
) - 1;
866 if (oper
->hint
& OH_ADDR
) {
867 data
= read_number (txt
);
869 if (opc
->hint
& H_RELATIVE
)
870 data
= data
- memaddr
;
879 data
|= 1 << (oper
->bits
- 1);
882 else if (oper
->hint
& OH_REG
) {
883 if (txt
[0] == 'r' || txt
[0] == 'R')
885 else if (txt
[0] == '%' && (txt
[1] == 'r' || txt
[1] == 'R'))
888 data
= read_number (txt
);
891 *err
= E_ASM_BAD_REGISTER
;
898 else if (oper
->hint
& OH_SPR
) {
899 if ((data
= spr_value (txt
)) == 0) {
901 *err
= E_ASM_BAD_SPR
;
906 else if (oper
->hint
& OH_TBR
) {
907 if ((data
= tbr_value (txt
)) == 0) {
909 *err
= E_ASM_BAD_TBR
;
915 data
= htonl (read_number (txt
));
918 return (data
& mask
) << oper
->shift
;
919 } /* parse_operand */
922 char *asm_error_str (int err
)
925 case E_ASM_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";
932 return "Bad SPR name or number";
934 return "Bad TBR name or number";
938 } /* asm_error_str */
942 /*======================================================================
943 * Copy a word from one buffer to another, ignores leading white spaces.
946 * src The address of a character pointer to the
948 * dest A pointer to a character buffer to write the word
951 * Returns the number of non-white space characters copied, or zero.
954 int get_word (char **src
, char *dest
)
959 /*------------------------------------------------------------*/
961 /* Eat white spaces */
962 while (*ptr
&& isblank (*ptr
))
970 /* Find the text of the word */
971 while (*ptr
&& !isblank (*ptr
) && (*ptr
!= ','))
972 dest
[nchars
++] = *ptr
++;
973 ptr
= (*ptr
== ',') ? ptr
+ 1 : ptr
;
982 /*======================================================================
983 * Convert a numeric string to a number, be aware of base notations.
986 * txt The numeric string.
988 * Returns the converted numeric value.
991 long read_number (char *txt
)
996 /*------------------------------------------------------------*/
998 if (txt
== 0 || *txt
== 0)
1006 if (txt
[0] == '0' && (txt
[1] == 'x' || txt
[1] == 'X')) /* hex */
1007 val
= simple_strtoul (&txt
[2], NULL
, 16);
1009 val
= simple_strtoul (txt
, NULL
, 10);
1018 int downstring (char *s
)
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
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.
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)
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.
1054 int find_next_address (unsigned char *nextaddr
, int step_over
,
1055 struct pt_regs
*regs
)
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' */
1072 int conditional
= 0;
1075 /*------------------------------------------------------------*/
1077 if (nextaddr
== 0 || regs
== 0) {
1078 printf ("find_next_address: bad args");
1082 pc
= regs
->nip
& 0xfffffffc;
1083 instr
= INSTRUCTION (pc
);
1085 if ((op
= find_opcode (instr
)) == (struct opcode
*) 0) {
1086 printf ("find_next_address: can't parse opcode 0x%lx", instr
);
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
))
1106 if ((addr
& (1 << 13)) != 0)
1107 addr
= addr
- (1 << 14);
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
))
1122 if ((addr
& (1 << 23)) != 0)
1123 addr
= addr
- (1 << 24);
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
))
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
))
1162 switch ((bo
& 0x1e) >> 1) {
1167 cond_ok
= !(cr
& (1 << (31 - bi
)));
1174 cond_ok
= !(cr
& (1 << (31 - bi
)));
1179 cond_ok
= !(cr
& (1 << (31 - bi
)));
1186 cond_ok
= cr
& (1 << (31 - bi
));
1193 cond_ok
= cr
& (1 << (31 - bi
));
1198 cond_ok
= cr
& (1 << (31 - bi
));
1203 ctr_ok
= cond_ok
= 1;
1208 ctr_ok
= cond_ok
= 1;
1211 case 10: /* 1z1zz */
1212 ctr_ok
= cond_ok
= 1;
1217 if (branch
&& (!conditional
|| (ctr_ok
&& cond_ok
))) {
1228 step
= next
= pc
+ 4;
1231 if (step_over
== true)
1232 *(unsigned long *) nextaddr
= next
;
1234 *(unsigned long *) nextaddr
= step
;
1237 } /* find_next_address */
1241 * Copyright (c) 2000 William L. Pitts and W. Gerald Hicks
1242 * All rights reserved.
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
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