|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: ! 26: /* ! 27: * Instruction disassembler. ! 28: */ ! 29: ! 30: #include <mach/boolean.h> ! 31: #include <machine/db_machdep.h> ! 32: ! 33: #include <ddb/db_access.h> ! 34: #include <ddb/db_sym.h> ! 35: #include <ddb/db_output.h> ! 36: ! 37: #include <kern/task.h> ! 38: #include <kern/misc_protos.h> ! 39: ! 40: #include "ppc_disasm.h" ! 41: ! 42: db_addr_t db_disasm_pc, db_disasm_symaddr; ! 43: boolean_t db_disasm_print_symaddr; ! 44: ! 45: /* ! 46: * Disassemble instruction at 'loc'. 'altfmt' specifies an ! 47: * (optional) alternate format. Return address of start of ! 48: * next instruction. ! 49: */ ! 50: db_addr_t ! 51: db_disasm( ! 52: db_addr_t loc, ! 53: boolean_t altfmt, ! 54: task_t task) ! 55: { ! 56: int inst; ! 57: char *p; ! 58: ! 59: inst = db_get_task_value(loc, 4, FALSE, task); ! 60: db_disasm_pc = loc; ! 61: db_disasm_print_symaddr = FALSE; ! 62: p = in(inst); ! 63: db_printf("%s", p); ! 64: if (db_disasm_print_symaddr) { ! 65: db_printf(" <"); ! 66: db_task_printsym(db_disasm_symaddr, DB_STGY_ANY, task); ! 67: db_printf(">"); ! 68: } ! 69: dis_done(); ! 70: return (loc+4); ! 71: } ! 72: ! 73: /* ! 74: * Given four bytes of instruction (stored as an int, not an ! 75: * array of characters), compute if the instruction reads ! 76: * memory. ! 77: */ ! 78: int ! 79: db_inst_load( ! 80: unsigned long insw) ! 81: { ! 82: #if 1 ! 83: db_printf("db_inst_load: coming soon in a debugger near you!\n"); ! 84: return 0; ! 85: #else ! 86: unsigned char insb, bits; ! 87: ! 88: insb = insw & 0xff; ! 89: insw >>= 8; ! 90: bits = db_ldstrtab[insb]; ! 91: if (!(bits & DBLS_LOAD)) ! 92: return (0); ! 93: while (1) { ! 94: switch (bits & DBLS_MODS) { ! 95: case 0: ! 96: return (1); ! 97: case DBLS_MODRM: ! 98: insb = insw & 0xff; ! 99: return ((insb & 0xc0) != 0xc0); ! 100: case DBLS_SECOND|DBLS_MODRM: ! 101: insb = insw & 0xff; ! 102: return ((insb & 0xc0) != 0xc0 ? 2 : 0); ! 103: case DBLS_SECOND: ! 104: return (2); ! 105: case DBLS_ESCAPE: ! 106: insb = insw & 0xff; ! 107: insw >>= 8; ! 108: bits = db_ldstrtab0f[insb]; ! 109: break; ! 110: case DBLS_SWREG: ! 111: return (db_inst_swreg(TRUE, insw, insb)); ! 112: default: ! 113: panic ("db_inst_load: unknown mod bits"); ! 114: } ! 115: } ! 116: #endif ! 117: } ! 118: ! 119: /* ! 120: * Given four bytes of instruction (stored as an int, not an ! 121: * array of characters), compute if the instruction writes ! 122: * memory. ! 123: */ ! 124: int ! 125: db_inst_store( ! 126: unsigned long insw) ! 127: { ! 128: #if 1 ! 129: db_printf("db_inst_store: coming soon in a debugger near you!\n"); ! 130: return 0; ! 131: #else ! 132: unsigned char insb, bits; ! 133: ! 134: insb = insw & 0xff; ! 135: insw >>= 8; ! 136: bits = db_ldstrtab[insb]; ! 137: if (!(bits & DBLS_STORE)) ! 138: return (0); ! 139: while (1) { ! 140: switch (bits & DBLS_MODS) { ! 141: case 0: ! 142: return (1); ! 143: case DBLS_MODRM: ! 144: insb = insw & 0xff; ! 145: return ((insb & 0xc0) != 0xc0); ! 146: case DBLS_SECOND|DBLS_MODRM: ! 147: insb = insw & 0xff; ! 148: return ((insb & 0xc0) != 0xc0 ? 2 : 0); ! 149: case DBLS_SECOND: ! 150: return (2); ! 151: case DBLS_ESCAPE: ! 152: insb = insw & 0xff; ! 153: insw >>= 8; ! 154: bits = db_ldstrtab0f[insb]; ! 155: break; ! 156: case DBLS_SWREG: ! 157: return (db_inst_swreg(FALSE, insw, insb)); ! 158: default: ! 159: panic ("db_inst_store: unknown mod bits"); ! 160: } ! 161: } ! 162: #endif ! 163: } ! 164: ! 165: /* ! 166: * Extra routines for the automatically generated disassembler ! 167: */ ! 168: char * ! 169: hex( ! 170: bits n) ! 171: { ! 172: char *p; ! 173: ! 174: if (n < 10) ! 175: return dec(n); ! 176: p = dis_alloc(11); ! 177: sprintf(p, "0x%lx", n); ! 178: return p; ! 179: } ! 180: ! 181: char * ! 182: dec( ! 183: bits n) ! 184: { ! 185: char *p = dis_alloc(11); ! 186: sprintf(p, "%lu", n); ! 187: return p; ! 188: } ! 189: ! 190: char * ! 191: brdispl( ! 192: bits displ, ! 193: bits nbits) ! 194: { ! 195: int sign, extended; ! 196: ! 197: sign = 1 << (nbits - 1); ! 198: extended = (displ & sign ? displ - (sign << 1) : displ); ! 199: db_disasm_symaddr = db_disasm_pc + (extended << 2); ! 200: db_disasm_print_symaddr = TRUE; ! 201: return hex(extended << 2); ! 202: } ! 203: ! 204: char * ! 205: mbz( ! 206: bits n) ! 207: { ! 208: return n ? "[reserved bits not zero]" : ""; ! 209: } ! 210: ! 211: size_t db_disasm_string_size = 0; ! 212: #define DB_DISASM_STRING_MAXSIZE 4096 ! 213: char db_disasm_string[DB_DISASM_STRING_MAXSIZE]; ! 214: ! 215: void *db_disasm_malloc(size_t size); /* forward */ ! 216: void * ! 217: db_disasm_malloc( ! 218: size_t size) ! 219: { ! 220: void * new_buf; ! 221: ! 222: if (db_disasm_string_size + size <= DB_DISASM_STRING_MAXSIZE) { ! 223: new_buf = (void *) (db_disasm_string + db_disasm_string_size); ! 224: db_disasm_string_size += size; ! 225: return new_buf; ! 226: } ! 227: db_printf("db_disasm_malloc(size=%d) failed: %d left !\n", ! 228: size, ! 229: DB_DISASM_STRING_MAXSIZE - db_disasm_string_size); ! 230: return (void *) 0; ! 231: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.