The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/osfmk/ppc/db_disasm.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 9fea4e5719ea1c8a30c15d8b9de09797


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.