|
|
1.1 ! root 1: /* Print GOULD RISC instructions for GDB, the GNU debugger. ! 2: Copyright (C) 1986, 1987 Free Software Foundation, Inc. ! 3: ! 4: GDB is distributed in the hope that it will be useful, but WITHOUT ANY ! 5: WARRANTY. No author or distributor accepts responsibility to anyone ! 6: for the consequences of using it or for whether it serves any ! 7: particular purpose or works at all, unless he says so in writing. ! 8: Refer to the GDB General Public License for full details. ! 9: ! 10: Everyone is granted permission to copy, modify and redistribute GDB, ! 11: but only under the conditions described in the GDB General Public ! 12: License. A copy of this license is supposed to have been given to you ! 13: along with GDB so you can know your rights and responsibilities. It ! 14: should be in a file named COPYING. Among other things, the copyright ! 15: notice and this notice must be preserved on all copies. ! 16: ! 17: In other words, go ahead and share GDB, but don't try to stop ! 18: anyone else from sharing it farther. Help stamp out software hoarding! ! 19: */ ! 20: ! 21: #include <stdio.h> ! 22: #include <a.out.h> ! 23: ! 24: #include "defs.h" ! 25: #include "param.h" ! 26: #include "symtab.h" ! 27: #include "frame.h" ! 28: #include "opcode.h" ! 29: ! 30: /* GOULD RISC instructions are never longer than this many bytes. */ ! 31: #define MAXLEN 4 ! 32: ! 33: /* Number of elements in the opcode table. */ ! 34: #define NOPCODES (sizeof gld_opcodes / sizeof gld_opcodes[0]) ! 35: ! 36: ! 37: /* Print the GOULD instruction at address MEMADDR in debugged memory, ! 38: on STREAM. Returns length of the instruction, in bytes. */ ! 39: ! 40: int ! 41: print_insn (memaddr, stream) ! 42: CORE_ADDR memaddr; ! 43: FILE *stream; ! 44: { ! 45: unsigned char buffer[MAXLEN]; ! 46: register int i; ! 47: register char *d; ! 48: register int bestmask; ! 49: unsigned best; ! 50: int temp, index, bestlen; ! 51: ! 52: read_memory (memaddr, buffer, MAXLEN); ! 53: ! 54: bestmask = 0; ! 55: index = -1; ! 56: best = 0xffffffff; ! 57: for (i = 0; i < NOPCODES; i++) ! 58: { ! 59: register unsigned int opcode = gld_opcodes[i].opcode; ! 60: register unsigned int mask = gld_opcodes[i].mask; ! 61: register unsigned int len = gld_opcodes[i].length; ! 62: register unsigned int test; ! 63: ! 64: /* Get possible opcode bytes into integer */ ! 65: test = buffer[0] << 24; ! 66: test |= buffer[1] << 16; ! 67: test |= buffer[2] << 8; ! 68: test |= buffer[3]; ! 69: ! 70: /* Mask with opcode and see if match */ ! 71: if ((opcode & mask) == (test & mask)) ! 72: { ! 73: /* See if second or third match */ ! 74: if (index >= 0) ! 75: { ! 76: /* Take new one if it looks good */ ! 77: if (bestlen == MAXLEN && len == MAXLEN) ! 78: { ! 79: /* See if lower bits matched */ ! 80: if (((bestmask & 3) == 0) && ! 81: ((mask & 3) != 0)) ! 82: { ! 83: bestmask = mask; ! 84: bestlen = len; ! 85: best = test; ! 86: index = i; ! 87: } ! 88: } ! 89: } ! 90: else ! 91: { ! 92: /* First match, save it */ ! 93: bestmask = mask; ! 94: bestlen = len; ! 95: best = test; ! 96: index = i; ! 97: } ! 98: } ! 99: } ! 100: ! 101: /* Handle undefined instructions. */ ! 102: if (index < 0) ! 103: { ! 104: fprintf (stream, "undefined 0%o",(buffer[0]<<8)+buffer[1]); ! 105: return 2; ! 106: } ! 107: ! 108: /* Print instruction name */ ! 109: fprintf (stream, "%-12s", gld_opcodes[index].name); ! 110: ! 111: /* Adjust if short instruction */ ! 112: if (gld_opcodes[index].length < 4) ! 113: { ! 114: best >>= 16; ! 115: i = 0; ! 116: } ! 117: else ! 118: { ! 119: i = 16; ! 120: } ! 121: ! 122: /* Dump out instruction arguments */ ! 123: for (d = gld_opcodes[index].args; *d; ++d) ! 124: { ! 125: switch (*d) ! 126: { ! 127: case 'f': ! 128: fprintf (stream, "%d", (best >> (7 + i)) & 7); ! 129: break; ! 130: case 'r': ! 131: fprintf (stream, "r%d", (best >> (7 + i)) & 7); ! 132: break; ! 133: case 'R': ! 134: fprintf (stream, "r%d", (best >> (4 + i)) & 7); ! 135: break; ! 136: case 'b': ! 137: fprintf (stream, "b%d", (best >> (7 + i)) & 7); ! 138: break; ! 139: case 'B': ! 140: fprintf (stream, "b%d", (best >> (4 + i)) & 7); ! 141: break; ! 142: case 'v': ! 143: fprintf (stream, "b%d", (best >> (7 + i)) & 7); ! 144: break; ! 145: case 'V': ! 146: fprintf (stream, "b%d", (best >> (4 + i)) & 7); ! 147: break; ! 148: case 'X': ! 149: temp = (best >> 20) & 7; ! 150: if (temp) ! 151: fprintf (stream, "r%d", temp); ! 152: else ! 153: putc ('0', stream); ! 154: break; ! 155: case 'A': ! 156: temp = (best >> 16) & 7; ! 157: if (temp) ! 158: fprintf (stream, "(b%d)", temp); ! 159: break; ! 160: case 'S': ! 161: fprintf (stream, "#%d", best & 0x1f); ! 162: break; ! 163: case 'I': ! 164: fprintf (stream, "#%x", best & 0xffff); ! 165: break; ! 166: case 'O': ! 167: fprintf (stream, "%x", best & 0xffff); ! 168: break; ! 169: case 'h': ! 170: fprintf (stream, "%d", best & 0xfffe); ! 171: break; ! 172: case 'd': ! 173: fprintf (stream, "%d", best & 0xfffc); ! 174: break; ! 175: case 'T': ! 176: fprintf (stream, "%d", (best >> 8) & 0xff); ! 177: break; ! 178: case 'N': ! 179: fprintf (stream, "%d", best & 0xff); ! 180: break; ! 181: default: ! 182: putc (*d, stream); ! 183: break; ! 184: } ! 185: } ! 186: ! 187: /* Return length of instruction */ ! 188: return (gld_opcodes[index].length); ! 189: } ! 190: ! 191: /* ! 192: * Find the number of arguments to a function. ! 193: */ ! 194: findarg(frame) ! 195: struct frame_info frame; ! 196: { ! 197: register struct symbol *func; ! 198: register unsigned pc; ! 199: ! 200: #ifdef notdef ! 201: /* find starting address of frame function */ ! 202: pc = get_pc_function_start (frame.pc); ! 203: ! 204: /* find function symbol info */ ! 205: func = find_pc_function (pc); ! 206: ! 207: /* call blockframe code to look for match */ ! 208: if (func != NULL) ! 209: return (func->value.block->nsyms / sizeof(int)); ! 210: #endif ! 211: ! 212: return (-1); ! 213: } ! 214: ! 215: /* ! 216: * In the case of the NPL, the frame's norminal address is Br2 and the ! 217: * previous routines frame is up the stack X bytes. Finding out what ! 218: * 'X' is can be tricky. ! 219: * ! 220: * 1.) stored in the code function header xA(Br1). ! 221: * 2.) must be careful of recurssion. ! 222: */ ! 223: findframe(thisframe) ! 224: FRAME thisframe; ! 225: { ! 226: register FRAME pointer; ! 227: struct frame_info frame; ! 228: ! 229: /* Setup toplevel frame structure */ ! 230: frame.pc = read_pc(); ! 231: frame.next_frame = 0; ! 232: frame.frame = read_register (SP_REGNUM); /* Br2 */ ! 233: ! 234: /* Search for this frame (start at current Br2) */ ! 235: do ! 236: { ! 237: pointer = framechain(frame); ! 238: frame.next_frame = frame.frame; ! 239: frame.frame = pointer; ! 240: frame.pc = FRAME_SAVED_PC(frame.next_frame); ! 241: } ! 242: while (frame.next_frame != thisframe); ! 243: ! 244: /* stop gap for now, end at __base3 */ ! 245: if (frame.pc == 0) ! 246: return 0; ! 247: ! 248: return pointer; ! 249: } ! 250: ! 251: /* ! 252: * Gdb front-end and internal framechain routine. ! 253: * Go back up stack one level. Tricky... ! 254: */ ! 255: framechain(frame) ! 256: register struct frame_info frame; ! 257: { ! 258: register CORE_ADDR func, prevsp; ! 259: register unsigned value; ! 260: ! 261: /* Get real function start address from internal frame address */ ! 262: func = get_pc_function_start(frame.pc); ! 263: ! 264: /* If no stack given, read register Br1 "(sp)" */ ! 265: if (!frame.frame) ! 266: prevsp = read_register (SP_REGNUM); ! 267: else ! 268: prevsp = frame.frame; ! 269: ! 270: /* Check function header, case #2 */ ! 271: value = read_memory_integer (func, 4); ! 272: if (value) ! 273: { ! 274: /* 32bit call push value stored in function header */ ! 275: prevsp += value; ! 276: } ! 277: else ! 278: { ! 279: /* read half-word from suabr at start of function */ ! 280: prevsp += read_memory_integer (func + 10, 2); ! 281: } ! 282: ! 283: return (prevsp); ! 284: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.