xref: /openbmc/u-boot/common/bedbug.c (revision fd0bc623)
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,
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);
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) ||
209 			((*ctx.op->hfunc) (&ctx) == false)) {
210 			sprintf (&ctx.data[ctx.datalen], "%-7s ", ctx.op->name);
211 			ctx.datalen += 8;
212 			print_operands (&ctx);
213 		}
214 
215 		(*pfunc) (ctx.data);
216 	}
217 
218 	return true;
219 }								/* disppc */
220 
221 
222 
223 /*======================================================================
224  * Called by the disassembler to print the operands for an instruction.
225  *
226  * Arguments:
227  *	ctx		A pointer to the disassembler context record.
228  *
229  * always returns 0.
230  */
231 
232 int print_operands (struct ppc_ctx *ctx)
233 {
234 	int open_parens = 0;
235 	int field;
236 	unsigned long operand;
237 	struct operand *opr;
238 
239 #ifdef USE_SOURCE_CODE
240 	char *symname;
241 	int offset;
242 #endif /* USE_SOURCE_CODE */
243   /*------------------------------------------------------------*/
244 
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 ?! */
249 		}
250 
251 		opr = &operands[ctx->op->fields[field] - 1];
252 
253 		if (opr->hint & OH_SILENT) {
254 			continue;
255 		}
256 
257 		if ((field > 0) && !open_parens) {
258 			strcat (ctx->data, ",");
259 			ctx->datalen++;
260 		}
261 
262 		operand = (ctx->instr >> opr->shift) & ((1 << opr->bits) - 1);
263 
264 		if (opr->hint & OH_ADDR) {
265 			if ((operand & (1 << (opr->bits - 1))) != 0) {
266 				operand = operand - (1 << opr->bits);
267 			}
268 
269 			if (ctx->op->hint & H_RELATIVE)
270 				operand = (operand << 2) + (unsigned long) ctx->virtual;
271 			else
272 				operand = (operand << 2);
273 
274 
275 			sprintf (&ctx->data[ctx->datalen], "0x%lx", operand);
276 			ctx->datalen = strlen (ctx->data);
277 
278 #ifdef USE_SOURCE_CODE
279 			if ((ctx->flags & F_SYMBOL) &&
280 				((symname =
281 				  symbol_name_from_addr (operand, 0, &offset)) != 0)) {
282 				sprintf (&ctx->data[ctx->datalen], " <%s", symname);
283 				if (offset != 0) {
284 					strcat (ctx->data, "+");
285 					ctx->datalen = strlen (ctx->data);
286 					sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt,
287 							 offset);
288 				}
289 				strcat (ctx->data, ">");
290 			}
291 #endif /* USE_SOURCE_CODE */
292 		}
293 
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");
298 			} else {
299 				sprintf (&ctx->data[ctx->datalen], "r%d", (short) operand);
300 			}
301 
302 			if (open_parens) {
303 				strcat (ctx->data, ")");
304 				open_parens--;
305 			}
306 		}
307 
308 		else if (opr->hint & OH_SPR) {
309 			strcat (ctx->data, spr_name (operand));
310 		}
311 
312 		else if (opr->hint & OH_TBR) {
313 			strcat (ctx->data, tbr_name (operand));
314 		}
315 
316 		else if (opr->hint & OH_LITERAL) {
317 			switch (opr->field) {
318 			case O_cr2:
319 				strcat (ctx->data, "cr2");
320 				ctx->datalen += 3;
321 				break;
322 
323 			default:
324 				break;
325 			}
326 		}
327 
328 		else {
329 			sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt,
330 					 (unsigned short) operand);
331 
332 			if (open_parens) {
333 				strcat (ctx->data, ")");
334 				open_parens--;
335 			}
336 
337 			else if (opr->hint & OH_OFFSET) {
338 				strcat (ctx->data, "(");
339 				open_parens++;
340 			}
341 		}
342 
343 		ctx->datalen = strlen (ctx->data);
344 	}
345 
346 	return 0;
347 }								/* print_operands */
348 
349 
350 
351 /*======================================================================
352  * Called to get the value of an arbitrary operand with in an instruction.
353  *
354  * Arguments:
355  *	op		The pointer to the opcode structure to which
356  *			the operands belong.
357  *
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.
362  *
363  *	field		The field (operand) to get the value of.
364  *
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
369  *			not required.
370  *
371  * Returns true if the operand was found or false if it was not.
372  */
373 
374 int get_operand_value (struct opcode *op, unsigned long instr,
375 					   enum OP_FIELD field, unsigned long *value)
376 {
377 	int i;
378 	struct operand *opr;
379 
380   /*------------------------------------------------------------*/
381 
382 	if (field > n_operands) {
383 		return false;			/* bad operand ?! */
384 	}
385 
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) {
389 			continue;
390 		}
391 
392 		opr = &operands[op->fields[i] - 1];
393 
394 		if (value) {
395 			*value = (instr >> opr->shift) & ((1 << opr->bits) - 1);
396 		}
397 		return true;
398 	}
399 
400 	return false;
401 }								/* operand_value */
402 
403 
404 
405 /*======================================================================
406  * Called by the disassembler to match an opcode value to an opcode structure.
407  *
408  * Arguments:
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
412  *			search.
413  *
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.
416  */
417 
418 struct opcode *find_opcode (unsigned long instr)
419 {
420 	struct opcode *ptr;
421 	int top = 0;
422 	int bottom = n_opcodes - 1;
423 	int idx;
424 
425   /*------------------------------------------------------------*/
426 
427 	while (top <= bottom) {
428 		idx = (top + bottom) >> 1;
429 		ptr = &opcodes[idx];
430 
431 		if ((instr & ptr->mask) < ptr->opcode) {
432 			bottom = idx - 1;
433 		} else if ((instr & ptr->mask) > ptr->opcode) {
434 			top = idx + 1;
435 		} else {
436 			return ptr;
437 		}
438 	}
439 
440 	return (struct opcode *) 0;
441 }								/* find_opcode */
442 
443 
444 
445 /*======================================================================
446  * Called by the assembler to match an opcode name to an opcode structure.
447  *
448  * Arguments:
449  *	name		The text name of the opcode, e.g. "b", "mtspr", etc.
450  *
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.
454  *
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.
457  */
458 
459 struct opcode *find_opcode_by_name (char *name)
460 {
461 	int idx;
462 
463   /*------------------------------------------------------------*/
464 
465 	downstring (name);
466 
467 	for (idx = 0; idx < n_opcodes; ++idx) {
468 		if (!strcmp (name, opcodes[idx].name))
469 			return &opcodes[idx];
470 	}
471 
472 	return (struct opcode *) 0;
473 }								/* find_opcode_by_name */
474 
475 
476 
477 /*======================================================================
478  * Convert the 'spr' operand from its numeric value to its symbolic name.
479  *
480  * Arguments:
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.
485  *
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.
489  */
490 
491 char *spr_name (int value)
492 {
493 	unsigned short spr;
494 	static char other[10];
495 	int i;
496 
497   /*------------------------------------------------------------*/
498 
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 */
501 
502 	spr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5);
503 
504 	for (i = 0; i < n_sprs; ++i) {
505 		if (spr == spr_map[i].spr_val)
506 			return spr_map[i].spr_name;
507 	}
508 
509 	sprintf (other, "%d", spr);
510 	return other;
511 }								/* spr_name */
512 
513 
514 
515 /*======================================================================
516  * Convert the 'spr' operand from its symbolic name to its numeric value
517  *
518  * Arguments:
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.
522  *
523  * Returns the numeric value for the spr appropriate for encoding a machine
524  * instruction.  Returns 0 if unable to find the SPR.
525  */
526 
527 int spr_value (char *name)
528 {
529 	struct spr_info *sprp;
530 	int spr;
531 	int i;
532 
533   /*------------------------------------------------------------*/
534 
535 	if (!name || !*name)
536 		return 0;
537 
538 	if (isdigit ((int) name[0])) {
539 		i = htonl (read_number (name));
540 		spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5);
541 		return spr;
542 	}
543 
544 	downstring (name);
545 
546 	for (i = 0; i < n_sprs; ++i) {
547 		sprp = &spr_map[i];
548 
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);
554 
555 			return spr;
556 		}
557 	}
558 
559 	return 0;
560 }								/* spr_value */
561 
562 
563 
564 /*======================================================================
565  * Convert the 'tbr' operand from its numeric value to its symbolic name.
566  *
567  * Arguments:
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.
572  *
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.
576  */
577 
578 char *tbr_name (int value)
579 {
580 	unsigned short tbr;
581 
582   /*------------------------------------------------------------*/
583 
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 */
586 
587 	tbr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5);
588 
589 	if (tbr == 268)
590 		return "TBL";
591 
592 	else if (tbr == 269)
593 		return "TBU";
594 
595 
596 	return "???";
597 }								/* tbr_name */
598 
599 
600 
601 /*======================================================================
602  * Convert the 'tbr' operand from its symbolic name to its numeric value.
603  *
604  * Arguments:
605  *	name		The symbolic name of the 'tbr' operand.  The
606  *			split-field encoding will be done by this routine.
607  *
608  * Returns the numeric value for the spr appropriate for encoding a machine
609  * instruction.  Returns 0 if unable to find the TBR.
610  */
611 
612 int tbr_value (char *name)
613 {
614 	int tbr;
615 	int val;
616 
617   /*------------------------------------------------------------*/
618 
619 	if (!name || !*name)
620 		return 0;
621 
622 	downstring (name);
623 
624 	if (isdigit ((int) name[0])) {
625 		val = read_number (name);
626 
627 		if (val != 268 && val != 269)
628 			return 0;
629 	} else if (strcmp (name, "tbl") == 0)
630 		val = 268;
631 	else if (strcmp (name, "tbu") == 0)
632 		val = 269;
633 	else
634 		return 0;
635 
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 */
638 
639 	val = htonl (val);
640 	tbr = ((val >> 5) & 0x1f) | ((val & 0x1f) << 5);
641 	return tbr;
642 }								/* tbr_name */
643 
644 
645 
646 /*======================================================================
647  * The next several functions (handle_xxx) are the routines that handle
648  * disassembling the opcodes with simplified mnemonics.
649  *
650  * Arguments:
651  *	ctx		A pointer to the disassembler context record.
652  *
653  * Returns true if the simpler form was printed or false if it was not.
654  */
655 
656 int handle_bc (struct ppc_ctx *ctx)
657 {
658 	unsigned long bo;
659 	unsigned long bi;
660 	static struct opcode blt = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0},
661 	0, "blt", H_RELATIVE
662 	};
663 	static struct opcode bne =
664 			{ B_OPCODE (16, 0, 0), B_MASK, {O_cr2, O_BD, 0},
665 	0, "bne", H_RELATIVE
666 	};
667 	static struct opcode bdnz = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0},
668 	0, "bdnz", H_RELATIVE
669 	};
670 
671   /*------------------------------------------------------------*/
672 
673 	if (get_operand_value(ctx->op, ctx->instr, O_BO, &bo) == false)
674 		return false;
675 
676 	if (get_operand_value(ctx->op, ctx->instr, O_BI, &bi) == false)
677 		return false;
678 
679 	if ((bo == 12) && (bi == 0)) {
680 		ctx->op = &blt;
681 		sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
682 		ctx->datalen += 8;
683 		print_operands (ctx);
684 		return true;
685 	} else if ((bo == 4) && (bi == 10)) {
686 		ctx->op = &bne;
687 		sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
688 		ctx->datalen += 8;
689 		print_operands (ctx);
690 		return true;
691 	} else if ((bo == 16) && (bi == 0)) {
692 		ctx->op = &bdnz;
693 		sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
694 		ctx->datalen += 8;
695 		print_operands (ctx);
696 		return true;
697 	}
698 
699 	return false;
700 }								/* handle_blt */
701 
702 
703 
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.
708  *
709  * Arguments:
710  *	filename	The address of a character array containing the
711  *			absolute path and file name of the source file.
712  *
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.
716  *
717  *	line_no		An integer specifying the source line number that
718  *			generated this code.
719  *
720  *	pfunc		The address of a function to call to print the output.
721  *
722  *
723  * Returns true if it was able to output the line info, or false if it was
724  * not.
725  */
726 
727 int print_source_line (char *filename, char *funcname,
728 					   int line_no, int (*pfunc) (const char *))
729 {
730 	char out_buf[256];
731 
732   /*------------------------------------------------------------*/
733 
734 	(*pfunc) ("");				/* output a newline */
735 	sprintf (out_buf, "%s %s(): line %d", filename, funcname, line_no);
736 	(*pfunc) (out_buf);
737 
738 	return true;
739 }								/* print_source_line */
740 
741 
742 
743 /*======================================================================
744  * Entry point for the PPC assembler.
745  *
746  * Arguments:
747  *	asm_buf		An array of characters containing the assembly opcode
748  *			and operands to convert to a POWERPC machine
749  *			instruction.
750  *
751  * Returns the machine instruction or zero.
752  */
753 
754 unsigned long asmppc (unsigned long memaddr, char *asm_buf, int *err)
755 {
756 	struct opcode *opc;
757 	struct operand *oper[MAX_OPERANDS];
758 	unsigned long instr;
759 	unsigned long param;
760 	char *ptr = asm_buf;
761 	char scratch[20];
762 	int i;
763 	int w_operands = 0;			/* wanted # of operands */
764 	int n_operands = 0;			/* # of operands read */
765 	int asm_debug = 0;
766 
767   /*------------------------------------------------------------*/
768 
769 	if (err)
770 		*err = 0;
771 
772 	if (get_word (&ptr, scratch) == 0)
773 		return 0;
774 
775 	/* Lookup the opcode structure based on the opcode name */
776 	if ((opc = find_opcode_by_name (scratch)) == (struct opcode *) 0) {
777 		if (err)
778 			*err = E_ASM_BAD_OPCODE;
779 		return 0;
780 	}
781 
782 	if (asm_debug) {
783 		printf ("asmppc: Opcode = \"%s\"\n", opc->name);
784 	}
785 
786 	for (i = 0; i < 8; ++i) {
787 		if (opc->fields[i] == 0)
788 			break;
789 		++w_operands;
790 	}
791 
792 	if (asm_debug) {
793 		printf ("asmppc: Expecting %d operands\n", w_operands);
794 	}
795 
796 	instr = opc->opcode;
797 
798 	/* read each operand */
799 	while (n_operands < w_operands) {
800 
801 		oper[n_operands] = &operands[opc->fields[n_operands] - 1];
802 
803 		if (oper[n_operands]->hint & OH_SILENT) {
804 			/* Skip silent operands, they are covered in opc->opcode */
805 
806 			if (asm_debug) {
807 				printf ("asmppc: Operand %d \"%s\" SILENT\n", n_operands,
808 						oper[n_operands]->name);
809 			}
810 
811 			++n_operands;
812 			continue;
813 		}
814 
815 		if (get_word (&ptr, scratch) == 0)
816 			break;
817 
818 		if (asm_debug) {
819 			printf ("asmppc: Operand %d \"%s\" : \"%s\"\n", n_operands,
820 					oper[n_operands]->name, scratch);
821 		}
822 
823 		if ((param = parse_operand (memaddr, opc, oper[n_operands],
824 									scratch, err)) == -1)
825 			return 0;
826 
827 		instr |= param;
828 		++n_operands;
829 	}
830 
831 	if (n_operands < w_operands) {
832 		if (err)
833 			*err = E_ASM_NUM_OPERANDS;
834 		return 0;
835 	}
836 
837 	if (asm_debug) {
838 		printf ("asmppc: Instruction = 0x%08lx\n", instr);
839 	}
840 
841 	return instr;
842 }								/* asmppc */
843 
844 
845 
846 /*======================================================================
847  * Called by the assembler to interpret a single operand
848  *
849  * Arguments:
850  *	ctx		A pointer to the disassembler context record.
851  *
852  * Returns 0 if the operand is ok, or -1 if it is bad.
853  */
854 
855 int parse_operand (unsigned long memaddr, struct opcode *opc,
856 				   struct operand *oper, char *txt, int *err)
857 {
858 	long data;
859 	long mask;
860 	int is_neg = 0;
861 
862   /*------------------------------------------------------------*/
863 
864 	mask = (1 << oper->bits) - 1;
865 
866 	if (oper->hint & OH_ADDR) {
867 		data = read_number (txt);
868 
869 		if (opc->hint & H_RELATIVE)
870 			data = data - memaddr;
871 
872 		if (data < 0)
873 			is_neg = 1;
874 
875 		data >>= 2;
876 		data &= (mask >> 1);
877 
878 		if (is_neg)
879 			data |= 1 << (oper->bits - 1);
880 	}
881 
882 	else if (oper->hint & OH_REG) {
883 		if (txt[0] == 'r' || txt[0] == 'R')
884 			txt++;
885 		else if (txt[0] == '%' && (txt[1] == 'r' || txt[1] == 'R'))
886 			txt += 2;
887 
888 		data = read_number (txt);
889 		if (data > 31) {
890 			if (err)
891 				*err = E_ASM_BAD_REGISTER;
892 			return -1;
893 		}
894 
895 		data = htonl (data);
896 	}
897 
898 	else if (oper->hint & OH_SPR) {
899 		if ((data = spr_value (txt)) == 0) {
900 			if (err)
901 				*err = E_ASM_BAD_SPR;
902 			return -1;
903 		}
904 	}
905 
906 	else if (oper->hint & OH_TBR) {
907 		if ((data = tbr_value (txt)) == 0) {
908 			if (err)
909 				*err = E_ASM_BAD_TBR;
910 			return -1;
911 		}
912 	}
913 
914 	else {
915 		data = htonl (read_number (txt));
916 	}
917 
918 	return (data & mask) << oper->shift;
919 }								/* parse_operand */
920 
921 
922 char *asm_error_str (int err)
923 {
924 	switch (err) {
925 	case E_ASM_BAD_OPCODE:
926 		return "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";
931 	case E_ASM_BAD_SPR:
932 		return "Bad SPR name or number";
933 	case E_ASM_BAD_TBR:
934 		return "Bad TBR name or number";
935 	}
936 
937 	return "";
938 }								/* asm_error_str */
939 
940 
941 
942 /*======================================================================
943  * Copy a word from one buffer to another, ignores leading white spaces.
944  *
945  * Arguments:
946  *	src		The address of a character pointer to the
947  *			source buffer.
948  *	dest		A pointer to a character buffer to write the word
949  *			into.
950  *
951  * Returns the number of non-white space characters copied, or zero.
952  */
953 
954 int get_word (char **src, char *dest)
955 {
956 	char *ptr = *src;
957 	int nchars = 0;
958 
959   /*------------------------------------------------------------*/
960 
961 	/* Eat white spaces */
962 	while (*ptr && isblank (*ptr))
963 		ptr++;
964 
965 	if (*ptr == 0) {
966 		*src = ptr;
967 		return 0;
968 	}
969 
970 	/* Find the text of the word */
971 	while (*ptr && !isblank (*ptr) && (*ptr != ','))
972 		dest[nchars++] = *ptr++;
973 	ptr = (*ptr == ',') ? ptr + 1 : ptr;
974 	dest[nchars] = 0;
975 
976 	*src = ptr;
977 	return nchars;
978 }								/* get_word */
979 
980 
981 
982 /*======================================================================
983  * Convert a numeric string to a number, be aware of base notations.
984  *
985  * Arguments:
986  *	txt		The numeric string.
987  *
988  * Returns the converted numeric value.
989  */
990 
991 long read_number (char *txt)
992 {
993 	long val;
994 	int is_neg = 0;
995 
996   /*------------------------------------------------------------*/
997 
998 	if (txt == 0 || *txt == 0)
999 		return 0;
1000 
1001 	if (*txt == '-') {
1002 		is_neg = 1;
1003 		++txt;
1004 	}
1005 
1006 	if (txt[0] == '0' && (txt[1] == 'x' || txt[1] == 'X'))	/* hex */
1007 		val = simple_strtoul (&txt[2], NULL, 16);
1008 	else						/* decimal */
1009 		val = simple_strtoul (txt, NULL, 10);
1010 
1011 	if (is_neg)
1012 		val = -val;
1013 
1014 	return val;
1015 }								/* read_number */
1016 
1017 
1018 int downstring (char *s)
1019 {
1020 	if (!s || !*s)
1021 		return 0;
1022 
1023 	while (*s) {
1024 		if (isupper (*s))
1025 			*s = tolower (*s);
1026 		s++;
1027 	}
1028 
1029 	return 0;
1030 }								/* downstring */
1031 
1032 
1033 
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
1038  * supported.
1039  *
1040  * Arguments:
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.
1044  *
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)
1049  *
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.
1052  */
1053 
1054 int find_next_address (unsigned char *nextaddr, int step_over,
1055 					   struct pt_regs *regs)
1056 {
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' */
1070 	int ctr_ok = 0;
1071 	int cond_ok = 0;
1072 	int conditional = 0;
1073 	int branch = 0;
1074 
1075   /*------------------------------------------------------------*/
1076 
1077 	if (nextaddr == 0 || regs == 0) {
1078 		printf ("find_next_address: bad args");
1079 		return false;
1080 	}
1081 
1082 	pc = regs->nip & 0xfffffffc;
1083 	instr = INSTRUCTION (pc);
1084 
1085 	if ((op = find_opcode (instr)) == (struct opcode *) 0) {
1086 		printf ("find_next_address: can't parse opcode 0x%lx", instr);
1087 		return false;
1088 	}
1089 
1090 	ctr = regs->ctr;
1091 	cr = regs->ccr;
1092 	lr = regs->link;
1093 
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))
1104 			return false;
1105 
1106 		if ((addr & (1 << 13)) != 0)
1107 			addr = addr - (1 << 14);
1108 		addr <<= 2;
1109 		conditional = 1;
1110 		branch = 1;
1111 		break;
1112 
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))
1120 			return false;
1121 
1122 		if ((addr & (1 << 23)) != 0)
1123 			addr = addr - (1 << 24);
1124 		addr <<= 2;
1125 		conditional = 0;
1126 		branch = 1;
1127 		break;
1128 
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))
1134 			return false;
1135 
1136 		addr = ctr;
1137 		aa = 1;
1138 		conditional = 1;
1139 		branch = 1;
1140 		break;
1141 
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))
1147 			return false;
1148 
1149 		addr = lr;
1150 		aa = 1;
1151 		conditional = 1;
1152 		branch = 1;
1153 		break;
1154 
1155 	default:
1156 		conditional = 0;
1157 		branch = 0;
1158 		break;
1159 	}
1160 
1161 	if (conditional) {
1162 		switch ((bo & 0x1e) >> 1) {
1163 		case 0:				/* 0000y */
1164 			if (--ctr != 0)
1165 				ctr_ok = 1;
1166 
1167 			cond_ok = !(cr & (1 << (31 - bi)));
1168 			break;
1169 
1170 		case 1:				/* 0001y */
1171 			if (--ctr == 0)
1172 				ctr_ok = 1;
1173 
1174 			cond_ok = !(cr & (1 << (31 - bi)));
1175 			break;
1176 
1177 		case 2:				/* 001zy */
1178 			ctr_ok = 1;
1179 			cond_ok = !(cr & (1 << (31 - bi)));
1180 			break;
1181 
1182 		case 4:				/* 0100y */
1183 			if (--ctr != 0)
1184 				ctr_ok = 1;
1185 
1186 			cond_ok = cr & (1 << (31 - bi));
1187 			break;
1188 
1189 		case 5:				/* 0101y */
1190 			if (--ctr == 0)
1191 				ctr_ok = 1;
1192 
1193 			cond_ok = cr & (1 << (31 - bi));
1194 			break;
1195 
1196 		case 6:				/* 011zy */
1197 			ctr_ok = 1;
1198 			cond_ok = cr & (1 << (31 - bi));
1199 			break;
1200 
1201 		case 8:				/* 1z00y */
1202 			if (--ctr != 0)
1203 				ctr_ok = cond_ok = 1;
1204 			break;
1205 
1206 		case 9:				/* 1z01y */
1207 			if (--ctr == 0)
1208 				ctr_ok = cond_ok = 1;
1209 			break;
1210 
1211 		case 10:				/* 1z1zz */
1212 			ctr_ok = cond_ok = 1;
1213 			break;
1214 		}
1215 	}
1216 
1217 	if (branch && (!conditional || (ctr_ok && cond_ok))) {
1218 		if (aa)
1219 			step = addr;
1220 		else
1221 			step = addr + pc;
1222 
1223 		if (lk)
1224 			next = pc + 4;
1225 		else
1226 			next = step;
1227 	} else {
1228 		step = next = pc + 4;
1229 	}
1230 
1231 	if (step_over == true)
1232 		*(unsigned long *) nextaddr = next;
1233 	else
1234 		*(unsigned long *) nextaddr = step;
1235 
1236 	return true;
1237 }								/* find_next_address */
1238 
1239 
1240 /*
1241  * Copyright (c) 2000 William L. Pitts and W. Gerald Hicks
1242  * All rights reserved.
1243  *
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
1247  * such forms.
1248  *
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
1252  * purpose.
1253  */
1254