xref: /openbmc/u-boot/common/bedbug.c (revision 9b914727)
1 /* $Id$ */
2 
3 #include <common.h>
4 
5 #include <linux/ctype.h>
6 #include <bedbug/bedbug.h>
7 #include <bedbug/ppc.h>
8 #include <bedbug/regs.h>
9 #include <bedbug/tables.h>
10 
11 #define Elf32_Word	unsigned long
12 
13 /* USE_SOURCE_CODE enables some symbolic debugging functions of this
14    code.  This is only useful if the program will have access to the
15    source code for the binary being examined.
16 */
17 
18 /* #define USE_SOURCE_CODE 1 */
19 
20 #ifdef USE_SOURCE_CODE
21 extern int line_info_from_addr __P ((Elf32_Word, char *, char *, int *));
22 extern struct symreflist *symByAddr;
23 extern char *symbol_name_from_addr __P ((Elf32_Word, int, int *));
24 #endif /* USE_SOURCE_CODE */
25 
26 int print_operands __P ((struct ppc_ctx *));
27 int get_operand_value __P ((struct opcode *, unsigned long,
28 				enum OP_FIELD, unsigned long *));
29 struct opcode *find_opcode __P ((unsigned long));
30 struct opcode *find_opcode_by_name __P ((char *));
31 char *spr_name __P ((int));
32 int spr_value __P ((char *));
33 char *tbr_name __P ((int));
34 int tbr_value __P ((char *));
35 int parse_operand __P ((unsigned long, struct opcode *,
36 			struct operand *, char *, int *));
37 int get_word __P ((char **, char *));
38 long read_number __P ((char *));
39 int downstring __P ((char *));
40 
41 
42 /*======================================================================
43  * Entry point for the PPC disassembler.
44  *
45  * Arguments:
46  *	memaddr		The address to start disassembling from.
47  *
48  *	virtual		If this value is non-zero, then this will be
49  *			used as the base address for the output and
50  *			symbol lookups.  If this value is zero then
51  *			memaddr is used as the absolute address.
52  *
53  *	num_instr	The number of instructions to disassemble.  Since
54  *			each instruction is 32 bits long, this can be
55  *			computed if you know the total size of the region.
56  *
57  *	pfunc		The address of a function that is called to print
58  *			each line of output.  The function should take a
59  *			single character pointer as its parameters a la puts.
60  *
61  *	flags		Sets options for the output.  This is a
62  *			bitwise-inclusive-OR of the following
63  *			values.  Note that only one of the radix
64  *			options may be set.
65  *
66  *			F_RADOCTAL	- output radix is unsigned base 8.
67  *			F_RADUDECIMAL	- output radix is unsigned base 10.
68  *			F_RADSDECIMAL	- output radix is signed base 10.
69  *			F_RADHEX	- output radix is unsigned base 16.
70  *			F_SIMPLE	- use simplified mnemonics.
71  *			F_SYMBOL	- lookup symbols for addresses.
72  *			F_INSTR		- output raw instruction.
73  *			F_LINENO	- show line # info if available.
74  *
75  * Returns TRUE if the area was successfully disassembled or FALSE if
76  * a problem was encountered with accessing the memory.
77  */
78 
79 int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr,
80 			int (*pfunc) (const char *), unsigned long flags)
81 {
82 	int i;
83 	struct ppc_ctx ctx;
84 
85 #ifdef USE_SOURCE_CODE
86 	int line_no = 0;
87 	int last_line_no = 0;
88 	char funcname[128] = { 0 };
89 	char filename[256] = { 0 };
90 	char last_funcname[128] = { 0 };
91 	int symoffset;
92 	char *symname;
93 	char *cursym = (char *) 0;
94 #endif /* USE_SOURCE_CODE */
95   /*------------------------------------------------------------*/
96 
97 	ctx.flags = flags;
98 	ctx.virtual = virtual;
99 
100 	/* Figure out the output radix before we go any further */
101 
102 	if (ctx.flags & F_RADOCTAL) {
103 		/* Unsigned octal output */
104 		strcpy (ctx.radix_fmt, "O%o");
105 	} else if (ctx.flags & F_RADUDECIMAL) {
106 		/* Unsigned decimal output */
107 		strcpy (ctx.radix_fmt, "%u");
108 	} else if (ctx.flags & F_RADSDECIMAL) {
109 		/* Signed decimal output */
110 		strcpy (ctx.radix_fmt, "%d");
111 	} else {
112 		/* Unsigned hex output */
113 		strcpy (ctx.radix_fmt, "0x%x");
114 	}
115 
116 	if (ctx.virtual == 0) {
117 		ctx.virtual = memaddr;
118 	}
119 #ifdef USE_SOURCE_CODE
120 	if (ctx.flags & F_SYMBOL) {
121 		if (symByAddr == 0)		/* no symbols loaded */
122 			ctx.flags &= ~F_SYMBOL;
123 		else {
124 			cursym = (char *) 0;
125 			symoffset = 0;
126 		}
127 	}
128 #endif /* USE_SOURCE_CODE */
129 
130 	/* format each line as "XXXXXXXX: <symbol> IIIIIIII  disassembly" where,
131 	   XXXXXXXX is the memory address in hex,
132 	   <symbol> is the symbolic location if F_SYMBOL is set.
133 	   IIIIIIII is the raw machine code in hex if F_INSTR is set,
134 	   and disassembly is the disassembled machine code with numbers
135 	   formatted according to the 'radix' parameter */
136 
137 	for (i = 0; i < num_instr; ++i, memaddr += 4, ctx.virtual += 4) {
138 #ifdef USE_SOURCE_CODE
139 		if (ctx.flags & F_LINENO) {
140 			if ((line_info_from_addr ((Elf32_Word) ctx.virtual, 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 
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 
231 int 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 
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 
373 int 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 
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 
417 struct 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 
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 
458 struct 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 
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 
490 char *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 
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 
526 int 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 
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 
577 char *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 
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 
611 int 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 
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 
655 int 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 
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 
726 int 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 
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 
753 unsigned 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 
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 
854 int 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 
921 char *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 
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 
953 int 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 
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 
990 long 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 
1017 int 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 
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 
1053 int 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  */
1253