Annotation of XNU/osfmk/ppc/db_disasm.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.