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