debuggers.hg

changeset 22906:700ac6445812 tip

Now add KDB to the non-kdb tree
author Mukesh Rathor
date Thu Feb 03 15:42:41 2011 -0800 (2011-02-03)
parents 842ff5b82889
children
files xen/Makefile xen/Rules.mk xen/arch/x86/debug.c xen/arch/x86/hvm/svm/entry.S xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/svm/vmcb.c xen/arch/x86/hvm/vmx/entry.S xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/irq.c xen/arch/x86/setup.c xen/arch/x86/smp.c xen/arch/x86/time.c xen/arch/x86/traps.c xen/arch/x86/x86_64/compat/entry.S xen/arch/x86/x86_64/entry.S xen/common/domain.c xen/common/sched_credit.c xen/common/schedule.c xen/common/symbols.c xen/common/timer.c xen/drivers/char/console.c xen/include/asm-x86/debugger.h xen/include/xen/lib.h xen/include/xen/sched.h xen/kdb/Makefile xen/kdb/README xen/kdb/guest/Makefile xen/kdb/guest/kdb_guest.c xen/kdb/include/kdbdefs.h xen/kdb/include/kdbinc.h xen/kdb/include/kdbproto.h xen/kdb/kdb_cmds.c xen/kdb/kdb_io.c xen/kdb/kdbmain.c xen/kdb/x86/Makefile xen/kdb/x86/kdb_wp.c xen/kdb/x86/udis86-1.6/LICENSE xen/kdb/x86/udis86-1.6/Makefile xen/kdb/x86/udis86-1.6/README xen/kdb/x86/udis86-1.6/decode.c xen/kdb/x86/udis86-1.6/extern.h xen/kdb/x86/udis86-1.6/input.c xen/kdb/x86/udis86-1.6/input.h xen/kdb/x86/udis86-1.6/kdb_dis.c xen/kdb/x86/udis86-1.6/mnemonics.c xen/kdb/x86/udis86-1.6/mnemonics.h xen/kdb/x86/udis86-1.6/opcmap.c xen/kdb/x86/udis86-1.6/opcmap.h xen/kdb/x86/udis86-1.6/syn-att.c xen/kdb/x86/udis86-1.6/syn-intel.c xen/kdb/x86/udis86-1.6/syn.c xen/kdb/x86/udis86-1.6/syn.h xen/kdb/x86/udis86-1.6/types.h xen/kdb/x86/udis86-1.6/udis86.c
line diff
     1.1 --- a/xen/Makefile	Thu Feb 03 14:20:29 2011 -0800
     1.2 +++ b/xen/Makefile	Thu Feb 03 15:42:41 2011 -0800
     1.3 @@ -46,6 +46,7 @@ build install debug clean distclean csco
     1.4  	$(MAKE) -f $(BASEDIR)/Rules.mk -C xsm clean
     1.5  	$(MAKE) -f $(BASEDIR)/Rules.mk -C crypto clean
     1.6  	$(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) clean
     1.7 +	$(MAKE) -f $(BASEDIR)/Rules.mk -C kdb clean
     1.8  	rm -f include/asm *.o $(TARGET)* *~ core
     1.9  	rm -f include/asm-*/asm-offsets.h
    1.10  	[ -d tools/figlet ] && rm -f .banner*
    1.11 @@ -114,7 +115,7 @@ include/asm-$(TARGET_ARCH)/asm-offsets.h
    1.12  	  echo ""; \
    1.13  	  echo "#endif") <$< >$@
    1.14  
    1.15 -SUBDIRS = xsm arch/$(TARGET_ARCH) common drivers
    1.16 +SUBDIRS = xsm arch/$(TARGET_ARCH) common drivers kdb
    1.17  define all_sources
    1.18      ( find include/asm-$(TARGET_ARCH) -name '*.h' -print; \
    1.19        find include -name 'asm-*' -prune -o -name '*.h' -print; \
     2.1 --- a/xen/Rules.mk	Thu Feb 03 14:20:29 2011 -0800
     2.2 +++ b/xen/Rules.mk	Thu Feb 03 15:42:41 2011 -0800
     2.3 @@ -9,6 +9,7 @@ perfc_arrays  ?= n
     2.4  lock_profile  ?= n
     2.5  crash_debug   ?= n
     2.6  frame_pointer ?= n
     2.7 +kdb           ?= n
     2.8  
     2.9  XEN_ROOT=$(BASEDIR)/..
    2.10  include $(XEN_ROOT)/Config.mk
    2.11 @@ -40,6 +41,7 @@ ALL_OBJS-y               += $(BASEDIR)/d
    2.12  ALL_OBJS-y               += $(BASEDIR)/xsm/built_in.o
    2.13  ALL_OBJS-y               += $(BASEDIR)/arch/$(TARGET_ARCH)/built_in.o
    2.14  ALL_OBJS-$(x86)          += $(BASEDIR)/crypto/built_in.o
    2.15 +ALL_OBJS-$(kdb)          += $(BASEDIR)/kdb/built_in.o
    2.16  
    2.17  CFLAGS-y                += -g -D__XEN__
    2.18  CFLAGS-$(XSM_ENABLE)    += -DXSM_ENABLE
    2.19 @@ -52,6 +54,7 @@ CFLAGS-$(perfc)         += -DPERF_COUNTE
    2.20  CFLAGS-$(perfc_arrays)  += -DPERF_ARRAYS
    2.21  CFLAGS-$(lock_profile)  += -DLOCK_PROFILE
    2.22  CFLAGS-$(frame_pointer) += -fno-omit-frame-pointer -DCONFIG_FRAME_POINTER
    2.23 +CFLAGS-$(kdb)           += -DXEN_KDB_CONFIG
    2.24  
    2.25  ifneq ($(max_phys_cpus),)
    2.26  CFLAGS-y                += -DMAX_PHYS_CPUS=$(max_phys_cpus)
     3.1 --- a/xen/arch/x86/debug.c	Thu Feb 03 14:20:29 2011 -0800
     3.2 +++ b/xen/arch/x86/debug.c	Thu Feb 03 15:42:41 2011 -0800
     3.3 @@ -31,7 +31,6 @@
     3.4  
     3.5  #ifdef XEN_KDB_CONFIG
     3.6  extern volatile int kdbdbg;
     3.7 -extern void kdbp(const char *fmt, ...);
     3.8  #define DBGP(...) {(kdbdbg) ? kdbp(__VA_ARGS__):0;}
     3.9  #define DBGP1(...) {(kdbdbg>1) ? kdbp(__VA_ARGS__):0;}
    3.10  #define DBGP2(...) {(kdbdbg>2) ? kdbp(__VA_ARGS__):0;}
     4.1 --- a/xen/arch/x86/hvm/svm/entry.S	Thu Feb 03 14:20:29 2011 -0800
     4.2 +++ b/xen/arch/x86/hvm/svm/entry.S	Thu Feb 03 15:42:41 2011 -0800
     4.3 @@ -58,12 +58,23 @@ ENTRY(svm_asm_do_resume)
     4.4          get_current(bx)
     4.5          CLGI
     4.6  
     4.7 +#ifdef XEN_KDB_CONFIG
     4.8 +#if defined(__x86_64__)
     4.9 +        testl $1, kdb_session_begun(%rip)
    4.10 +#else
    4.11 +        testl $1, kdb_session_begun
    4.12 +#endif
    4.13 +        jnz  .Lkdb_skip_softirq
    4.14 +#endif
    4.15          mov  VCPU_processor(r(bx)),%eax
    4.16          shl  $IRQSTAT_shift,r(ax)
    4.17          lea  addr_of(irq_stat),r(dx)
    4.18          testl $~0,(r(dx),r(ax),1)
    4.19          jnz  .Lsvm_process_softirqs
    4.20  
    4.21 +#ifdef XEN_KDB_CONFIG
    4.22 +.Lkdb_skip_softirq:
    4.23 +#endif
    4.24          call svm_asid_handle_vmrun
    4.25  
    4.26          cmpb $0,addr_of(tb_init_done)
     5.1 --- a/xen/arch/x86/hvm/svm/svm.c	Thu Feb 03 14:20:29 2011 -0800
     5.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Thu Feb 03 15:42:41 2011 -0800
     5.3 @@ -1492,6 +1492,10 @@ asmlinkage void svm_vmexit_handler(struc
     5.4          break;
     5.5  
     5.6      case VMEXIT_EXCEPTION_DB:
     5.7 +#ifdef XEN_KDB_CONFIG
     5.8 +        if (kdb_handle_trap_entry(TRAP_debug, regs))
     5.9 +            break;
    5.10 +#endif
    5.11          if ( !v->domain->debugger_attached )
    5.12              goto exit_and_crash;
    5.13          domain_pause_for_debugger();
    5.14 @@ -1504,6 +1508,10 @@ asmlinkage void svm_vmexit_handler(struc
    5.15          if ( (inst_len = __get_instruction_length(v, INSTR_INT3)) == 0 )
    5.16              break;
    5.17          __update_guest_eip(regs, inst_len);
    5.18 +#ifdef XEN_KDB_CONFIG
    5.19 +        if (kdb_handle_trap_entry(TRAP_int3, regs))
    5.20 +            break;
    5.21 +#endif
    5.22          current->arch.gdbsx_vcpu_event = TRAP_int3;
    5.23          domain_pause_for_debugger();
    5.24          break;
     6.1 --- a/xen/arch/x86/hvm/svm/vmcb.c	Thu Feb 03 14:20:29 2011 -0800
     6.2 +++ b/xen/arch/x86/hvm/svm/vmcb.c	Thu Feb 03 15:42:41 2011 -0800
     6.3 @@ -416,6 +416,36 @@ void setup_vmcb_dump(void)
     6.4      register_keyhandler('v', &vmcb_dump_keyhandler);
     6.5  }
     6.6  
     6.7 +#if defined(XEN_KDB_CONFIG)
     6.8 +/* did == 0 : display for all HVM domains. domid 0 is never HVM.
     6.9 + *  * vid == -1 : display for all HVM VCPUs
    6.10 + *   */
    6.11 +void kdb_dump_vmcb(domid_t did, int vid)
    6.12 +{
    6.13 +    struct domain *dp;
    6.14 +    struct vcpu *vp;
    6.15 +
    6.16 +    rcu_read_lock(&domlist_read_lock);
    6.17 +    for_each_domain (dp) {
    6.18 +        if (!is_hvm_domain(dp) || dp->is_dying)
    6.19 +            continue;
    6.20 +        if (did != 0 && did != dp->domain_id)
    6.21 +            continue;
    6.22 +
    6.23 +        for_each_vcpu (dp, vp) {
    6.24 +            if (vid != -1 && vid != vp->vcpu_id)
    6.25 +                continue;
    6.26 +
    6.27 +            kdbp("  VMCB [domid: %d  vcpu:%d]:\n", dp->domain_id, vp->vcpu_id);
    6.28 +            svm_dump_vmcb("kdb", vp->arch.hvm_svm.vmcb);
    6.29 +            kdbp("\n");
    6.30 +        }
    6.31 +        kdbp("\n");
    6.32 +    }
    6.33 +    rcu_read_unlock(&domlist_read_lock);
    6.34 +}
    6.35 +#endif
    6.36 +
    6.37  /*
    6.38   * Local variables:
    6.39   * mode: C
     7.1 --- a/xen/arch/x86/hvm/vmx/entry.S	Thu Feb 03 14:20:29 2011 -0800
     7.2 +++ b/xen/arch/x86/hvm/vmx/entry.S	Thu Feb 03 15:42:41 2011 -0800
     7.3 @@ -123,12 +123,23 @@ vmx_asm_do_vmentry:
     7.4          get_current(bx)
     7.5          cli
     7.6  
     7.7 +#ifdef XEN_KDB_CONFIG
     7.8 +#if defined(__x86_64__)
     7.9 +        testl $1, kdb_session_begun(%rip)
    7.10 +#else
    7.11 +        testl $1, kdb_session_begun
    7.12 +#endif
    7.13 +        jnz  .Lkdb_skip_softirq
    7.14 +#endif
    7.15          mov  VCPU_processor(r(bx)),%eax
    7.16          shl  $IRQSTAT_shift,r(ax)
    7.17          lea  addr_of(irq_stat),r(dx)
    7.18          cmpl $0,(r(dx),r(ax),1)
    7.19          jnz  .Lvmx_process_softirqs
    7.20  
    7.21 +#ifdef XEN_KDB_CONFIG
    7.22 +.Lkdb_skip_softirq:
    7.23 +#endif
    7.24          testb $0xff,VCPU_vmx_emulate(r(bx))
    7.25          jnz .Lvmx_goto_emulator
    7.26          testb $0xff,VCPU_vmx_realmode(r(bx))
     8.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Thu Feb 03 14:20:29 2011 -0800
     8.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Thu Feb 03 15:42:41 2011 -0800
     8.3 @@ -1290,6 +1290,122 @@ void setup_vmcs_dump(void)
     8.4      register_keyhandler('v', &vmcs_dump_keyhandler);
     8.5  }
     8.6  
     8.7 +#if defined(XEN_KDB_CONFIG)
     8.8 +
     8.9 +/* it's a shame we can't use vmcs_dump_vcpu(), but it does vmx_vmcs_enter which
    8.10 + * will IPI other CPUs. also, print a subset relevant to software debugging */
    8.11 +static void noinline kdb_print_vmcs(void)
    8.12 +{
    8.13 +    kdbp("CR0: actual=%016llx  shadow=%016llx  gh_mask=%016llx\n",
    8.14 +         (unsigned long long)vmr(GUEST_CR0),
    8.15 +         (unsigned long long)vmr(CR0_READ_SHADOW), 
    8.16 +         (unsigned long long)vmr(CR0_GUEST_HOST_MASK));
    8.17 +    kdbp("CR4: actual=%016llx  shadow=%016llx  gh_mask=%016llx\n",
    8.18 +         (unsigned long long)vmr(GUEST_CR4),
    8.19 +         (unsigned long long)vmr(CR4_READ_SHADOW), 
    8.20 +         (unsigned long long)vmr(CR4_GUEST_HOST_MASK));
    8.21 +    kdbp("CR3: actual=%016llx  target_count=%d\n",
    8.22 +         (unsigned long long)vmr(GUEST_CR3),
    8.23 +         (int)vmr(CR3_TARGET_COUNT));
    8.24 +    kdbp("RSP = %016llx RIP = %016llx ", 
    8.25 +         (unsigned long long)vmr(GUEST_RSP),(unsigned long long)vmr(GUEST_RIP));
    8.26 +    kdbp("RFLAGS=%016llx\n", (unsigned long long)vmr(GUEST_RFLAGS));
    8.27 +    kdbp("Sysenter RSP=%016llx CS:RIP=%04x:%016llx\n",
    8.28 +         (unsigned long long)vmr(GUEST_SYSENTER_ESP),
    8.29 +         (int)vmr(GUEST_SYSENTER_CS),
    8.30 +         (unsigned long long)vmr(GUEST_SYSENTER_EIP));
    8.31 +
    8.32 +    kdbp("EntryControls=%08x ExitControls=%08x\n",
    8.33 +         (uint32_t)vmr(VM_ENTRY_CONTROLS),
    8.34 +         (uint32_t)vmr(VM_EXIT_CONTROLS));
    8.35 +    kdbp("ExceptionBitmap=%08x\n",
    8.36 +         (uint32_t)vmr(EXCEPTION_BITMAP));
    8.37 +    kdbp("VMEntry: intr_info=%08x errcode=%08x ilen=%08x\n",
    8.38 +         (uint32_t)vmr(VM_ENTRY_INTR_INFO),
    8.39 +         (uint32_t)vmr(VM_ENTRY_EXCEPTION_ERROR_CODE),
    8.40 +         (uint32_t)vmr(VM_ENTRY_INSTRUCTION_LEN));
    8.41 +    kdbp("VMExit: intr_info=%08x errcode=%08x ilen=%08x\n",
    8.42 +         (uint32_t)vmr(VM_EXIT_INTR_INFO),
    8.43 +         (uint32_t)vmr(VM_EXIT_INTR_ERROR_CODE),
    8.44 +         (uint32_t)vmr(VM_ENTRY_INSTRUCTION_LEN));
    8.45 +    kdbp("        exit_reason=%08x exit_qualification=%08x\n",
    8.46 +         (uint32_t)vmr(VM_EXIT_REASON),
    8.47 +         (uint32_t)vmr(EXIT_QUALIFICATION));
    8.48 +    kdbp("IDTVectoring: info=%08x errcode=%08x\n",
    8.49 +         (uint32_t)vmr(IDT_VECTORING_INFO),
    8.50 +         (uint32_t)vmr(IDT_VECTORING_ERROR_CODE));
    8.51 +    kdbp("EPT pointer = 0x%08x%08x\n",
    8.52 +         (uint32_t)vmr(EPT_POINTER_HIGH), (uint32_t)vmr(EPT_POINTER));
    8.53 +    kdbp("Virtual processor ID = 0x%04x\n",
    8.54 +         (uint32_t)vmr(VIRTUAL_PROCESSOR_ID));
    8.55 +    kdbp("\n");
    8.56 +}
    8.57 +
    8.58 +/* Flush VMCS on this cpu if it needs to: 
    8.59 + *   - Upon leaving kdb, the HVM cpu will resume in vmx_vmexit_handler() and 
    8.60 + *     do __vmreads. So, the VMCS pointer can't be left cleared.
    8.61 + *   - Doing __vmpclear will set the vmx state to 'clear', so to resume a
    8.62 + *     vmlaunch must be done and not vmresume. This means, we must clear 
    8.63 + *     arch_vmx->launched. Just call __vmx_clear_vmcs(), hopefully it won't keep
    8.64 + *     changing...
    8.65 + */
    8.66 +void kdb_curr_cpu_flush_vmcs(void)
    8.67 +{
    8.68 +    struct domain *dp;
    8.69 +    struct vcpu *vp;
    8.70 +
    8.71 +    if (this_cpu(current_vmcs) == NULL)
    8.72 +        return;             /* no HVM active on this CPU */
    8.73 +
    8.74 +    /* looks like we got one. unfortunately, current_vmcs points to vmcs 
    8.75 +     * and not VCPU, so we gotta search the entire list... */
    8.76 +    for_each_domain (dp) {
    8.77 +        if ( !is_hvm_domain(dp) || dp->is_dying)
    8.78 +            continue;
    8.79 +        for_each_vcpu (dp, vp) {
    8.80 +            if (vp->arch.hvm_vmx.active_cpu == smp_processor_id()) {
    8.81 +                __vmx_clear_vmcs(vp);
    8.82 +                __vmptrld(virt_to_maddr(vp->arch.hvm_vmx.vmcs));
    8.83 +            }
    8.84 +        }
    8.85 +    }
    8.86 +}
    8.87 +
    8.88 +/*
    8.89 + * domid == 0 : display for all HVM domains  (dom0 is never an HVM domain)
    8.90 + * vcpu id == -1 : display all vcpuids
    8.91 + * PreCondition: all HVM cpus (including current cpu) have flushed VMCS
    8.92 + */
    8.93 +void kdb_dump_vmcs(domid_t did, int vid)
    8.94 +{
    8.95 +    struct domain *dp;
    8.96 +    struct vcpu *vp;
    8.97 +
    8.98 +    ASSERT(!local_irq_is_enabled());     /* kdb should always run disabled */
    8.99 +
   8.100 +    for_each_domain (dp) {
   8.101 +        if ( !is_hvm_domain(dp) || dp->is_dying)
   8.102 +            continue;
   8.103 +        if (did != 0 && did != dp->domain_id)
   8.104 +            continue;
   8.105 +
   8.106 +        for_each_vcpu (dp, vp) {
   8.107 +            if (vid != -1 && vid != vp->vcpu_id)
   8.108 +                continue;
   8.109 +
   8.110 +            kdbp("  VMCS [domid: %d vcpu:%d]:\n", dp->domain_id, vp->vcpu_id);
   8.111 +
   8.112 +            __vmptrld(virt_to_maddr(vp->arch.hvm_vmx.vmcs));
   8.113 +            kdb_print_vmcs();
   8.114 +            __vmpclear(virt_to_maddr(vp->arch.hvm_vmx.vmcs));
   8.115 +        }
   8.116 +        kdbp("\n");
   8.117 +    }
   8.118 +    /* restore orig vmcs pointer for __vmreads in vmx_vmexit_handler() */
   8.119 +    if (is_hvm_vcpu(current))
   8.120 +        __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
   8.121 +}
   8.122 +#endif
   8.123  
   8.124  /*
   8.125   * Local variables:
     9.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Feb 03 14:20:29 2011 -0800
     9.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu Feb 03 15:42:41 2011 -0800
     9.3 @@ -2379,6 +2379,12 @@ asmlinkage void vmx_vmexit_handler(struc
     9.4              write_debugreg(6, exit_qualification | 0xffff0ff0);
     9.5              if ( !v->domain->debugger_attached || cpu_has_monitor_trap_flag )
     9.6                  goto exit_and_crash;
     9.7 +
     9.8 +#if defined(XEN_KDB_CONFIG)
     9.9 +            /* TRAP_debug: IP points correctly to next instr */
    9.10 +            if (kdb_handle_trap_entry(vector, regs))
    9.11 +                break;
    9.12 +#endif
    9.13              domain_pause_for_debugger();
    9.14              break;
    9.15          case TRAP_int3: 
    9.16 @@ -2386,6 +2392,13 @@ asmlinkage void vmx_vmexit_handler(struc
    9.17              if ( v->domain->debugger_attached )
    9.18              {
    9.19                  update_guest_eip(); /* Safe: INT3 */            
    9.20 +#if defined(XEN_KDB_CONFIG)
    9.21 +            /* vmcs.IP points to bp, kdb expects bp+1. Hence after the above
    9.22 +             * __update_guest_eip which updates to bp+1. works for gdbsx too 
    9.23 +             */
    9.24 +            if (kdb_handle_trap_entry(vector, regs))
    9.25 +                break;
    9.26 +#endif
    9.27                  current->arch.gdbsx_vcpu_event = TRAP_int3;
    9.28                  domain_pause_for_debugger();
    9.29                  break;
    10.1 --- a/xen/arch/x86/irq.c	Thu Feb 03 14:20:29 2011 -0800
    10.2 +++ b/xen/arch/x86/irq.c	Thu Feb 03 15:42:41 2011 -0800
    10.3 @@ -1874,3 +1874,30 @@ int hvm_domain_use_pirq(struct domain *d
    10.4      else
    10.5          return 0;
    10.6  }
    10.7 +
    10.8 +#ifdef XEN_KDB_CONFIG
    10.9 +void kdb_prnt_guest_mapped_irqs(void)
   10.10 +{
   10.11 +    int irq, j;
   10.12 +    char affstr[NR_CPUS/4+NR_CPUS/32+2];    /* courtesy dump_irqs() */
   10.13 +
   10.14 +    kdbp("irq  vec  aff  type  domid:mapped-pirq pairs  (all in decimal)\n");
   10.15 +    for (irq=0; irq < nr_irqs; irq++) {
   10.16 +        irq_desc_t  *dp = irq_to_desc(irq);
   10.17 +        struct irq_cfg *cfgp = dp->chip_data;
   10.18 +        irq_guest_action_t *actp = (irq_guest_action_t *)dp->action;
   10.19 +
   10.20 +        if (!dp->handler ||dp->handler==&no_irq_type || !(dp->status&IRQ_GUEST))
   10.21 +            continue;
   10.22 +
   10.23 +        cpumask_scnprintf(affstr, sizeof(affstr), dp->affinity);
   10.24 +        kdbp("[%3ld] %3d %3s %-13s ", irq, cfgp->vector, affstr,
   10.25 +             dp->handler->typename);
   10.26 +        for (j=0; j < actp->nr_guests; j++)
   10.27 +            kdbp("%03d:%04d ", actp->guest[j]->domain_id,
   10.28 +                 domain_irq_to_pirq(actp->guest[j], irq));
   10.29 +        kdbp("\n");
   10.30 +    }
   10.31 +}
   10.32 +#endif
   10.33 +
    11.1 --- a/xen/arch/x86/setup.c	Thu Feb 03 14:20:29 2011 -0800
    11.2 +++ b/xen/arch/x86/setup.c	Thu Feb 03 15:42:41 2011 -0800
    11.3 @@ -45,6 +45,13 @@
    11.4  #include <asm/setup.h>
    11.5  #include <xen/cpu.h>
    11.6  
    11.7 +#ifdef XEN_KDB_CONFIG
    11.8 +#include <asm/debugger.h>
    11.9 +
   11.10 +int opt_earlykdb=0;
   11.11 +boolean_param("earlykdb", opt_earlykdb);
   11.12 +#endif
   11.13 +
   11.14  extern u16 boot_edid_caps;
   11.15  extern u8 boot_edid_info[128];
   11.16  extern struct boot_video_info boot_vid_info;
   11.17 @@ -1197,6 +1204,12 @@ void __init __start_xen(unsigned long mb
   11.18  
   11.19      trap_init();
   11.20  
   11.21 +#ifdef XEN_KDB_CONFIG
   11.22 +    kdb_init();
   11.23 +    if (opt_earlykdb)
   11.24 +        kdb_trap_immed(KDB_TRAP_NONFATAL);
   11.25 +#endif
   11.26 +
   11.27      rcu_init();
   11.28      
   11.29      early_time_init();
    12.1 --- a/xen/arch/x86/smp.c	Thu Feb 03 14:20:29 2011 -0800
    12.2 +++ b/xen/arch/x86/smp.c	Thu Feb 03 15:42:41 2011 -0800
    12.3 @@ -274,7 +274,7 @@ void smp_send_event_check_mask(const cpu
    12.4   * Structure and data for smp_call_function()/on_selected_cpus().
    12.5   */
    12.6  
    12.7 -static void __smp_call_function_interrupt(void);
    12.8 +static void __smp_call_function_interrupt(struct cpu_user_regs *regs);
    12.9  static DEFINE_SPINLOCK(call_lock);
   12.10  static struct call_data_struct {
   12.11      void (*func) (void *info);
   12.12 @@ -324,7 +324,7 @@ void on_selected_cpus(
   12.13      if ( cpu_isset(smp_processor_id(), call_data.selected) )
   12.14      {
   12.15          local_irq_disable();
   12.16 -        __smp_call_function_interrupt();
   12.17 +        __smp_call_function_interrupt(NULL);
   12.18          local_irq_enable();
   12.19      }
   12.20  
   12.21 @@ -393,7 +393,7 @@ fastcall void smp_event_check_interrupt(
   12.22      set_irq_regs(old_regs);
   12.23  }
   12.24  
   12.25 -static void __smp_call_function_interrupt(void)
   12.26 +static void __smp_call_function_interrupt(struct cpu_user_regs *regs)
   12.27  {
   12.28      void (*func)(void *info) = call_data.func;
   12.29      void *info = call_data.info;
   12.30 @@ -413,6 +413,11 @@ static void __smp_call_function_interrup
   12.31      {
   12.32          mb();
   12.33          atomic_inc(&call_data.started);
   12.34 +#ifdef XEN_KDB_CONFIG
   12.35 +        if (info && !strcmp(info, "XENKDB")) {           /* called from kdb */
   12.36 +                (*(void (*)(struct cpu_user_regs *, void *))func)(regs, info);
   12.37 +        } else
   12.38 +#endif
   12.39          (*func)(info);
   12.40      }
   12.41  
   12.42 @@ -425,6 +430,6 @@ fastcall void smp_call_function_interrup
   12.43  
   12.44      ack_APIC_irq();
   12.45      perfc_incr(ipis);
   12.46 -    __smp_call_function_interrupt();
   12.47 +    __smp_call_function_interrupt(regs);
   12.48      set_irq_regs(old_regs);
   12.49  }
    13.1 --- a/xen/arch/x86/time.c	Thu Feb 03 14:20:29 2011 -0800
    13.2 +++ b/xen/arch/x86/time.c	Thu Feb 03 15:42:41 2011 -0800
    13.3 @@ -1905,6 +1905,37 @@ static int __init setup_dump_softtsc(voi
    13.4  }
    13.5  __initcall(setup_dump_softtsc);
    13.6  
    13.7 +#ifdef XEN_KDB_CONFIG
    13.8 +void kdb_time_resume(int update_domains)
    13.9 +{
   13.10 +        s_time_t now;
   13.11 +        int ccpu = smp_processor_id();
   13.12 +        struct cpu_time *t = &this_cpu(cpu_time);
   13.13 +
   13.14 +        if (!plt_src.read_counter)            /* not initialized for earlykdb */
   13.15 +                return;
   13.16 +
   13.17 +        if (update_domains) {
   13.18 +                plt_stamp = plt_src.read_counter();
   13.19 +                platform_timer_stamp = plt_stamp64;
   13.20 +                platform_time_calibration();
   13.21 +                do_settime(get_cmos_time(), 0, read_platform_stime());
   13.22 +        }
   13.23 +        if (local_irq_is_enabled())
   13.24 +                kdbp("kdb BUG: enabled in time_resume(). ccpu:%d\n", ccpu);
   13.25 +
   13.26 +        rdtscll(t->local_tsc_stamp);
   13.27 +        now = read_platform_stime();
   13.28 +        t->stime_master_stamp = now;
   13.29 +        t->stime_local_stamp  = now;
   13.30 +
   13.31 +        update_vcpu_system_time(current);
   13.32 +
   13.33 +        if (update_domains)
   13.34 +                set_timer(&calibration_timer, NOW() + EPOCH);
   13.35 +}
   13.36 +#endif
   13.37 +
   13.38  /*
   13.39   * Local variables:
   13.40   * mode: C
    14.1 --- a/xen/arch/x86/traps.c	Thu Feb 03 14:20:29 2011 -0800
    14.2 +++ b/xen/arch/x86/traps.c	Thu Feb 03 15:42:41 2011 -0800
    14.3 @@ -196,7 +196,7 @@ static void show_guest_stack(struct vcpu
    14.4  
    14.5  #if !defined(CONFIG_FRAME_POINTER)
    14.6  
    14.7 -static void show_trace(struct cpu_user_regs *regs)
    14.8 +void show_trace(struct cpu_user_regs *regs)
    14.9  {
   14.10      unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
   14.11  
   14.12 @@ -220,7 +220,7 @@ static void show_trace(struct cpu_user_r
   14.13  
   14.14  #else
   14.15  
   14.16 -static void show_trace(struct cpu_user_regs *regs)
   14.17 +void show_trace(struct cpu_user_regs *regs)
   14.18  {
   14.19      unsigned long *frame, next, addr, low, high;
   14.20  
   14.21 @@ -3144,6 +3144,10 @@ asmlinkage void do_nmi(struct cpu_user_r
   14.22      if ( nmi_callback(regs, cpu) )
   14.23          return;
   14.24  
   14.25 +#ifdef XEN_KDB_CONFIG
   14.26 +    if (kdb_enabled && kdb_handle_trap_entry(TRAP_nmi, regs))
   14.27 +        return;
   14.28 +#endif
   14.29      if ( nmi_watchdog )
   14.30          nmi_watchdog_tick(regs);
   14.31  
    15.1 --- a/xen/arch/x86/x86_64/compat/entry.S	Thu Feb 03 14:20:29 2011 -0800
    15.2 +++ b/xen/arch/x86/x86_64/compat/entry.S	Thu Feb 03 15:42:41 2011 -0800
    15.3 @@ -86,6 +86,10 @@ compat_skip_clobber:
    15.4  /* %rbx: struct vcpu */
    15.5  ENTRY(compat_test_all_events)
    15.6          cli                             # tests must not race interrupts
    15.7 +#ifdef XEN_KDB_CONFIG
    15.8 +        testl $1, kdb_session_begun(%rip)
    15.9 +        jnz   compat_restore_all_guest
   15.10 +#endif
   15.11  /*compat_test_softirqs:*/
   15.12          movl  VCPU_processor(%rbx),%eax
   15.13          shlq  $IRQSTAT_shift,%rax
    16.1 --- a/xen/arch/x86/x86_64/entry.S	Thu Feb 03 14:20:29 2011 -0800
    16.2 +++ b/xen/arch/x86/x86_64/entry.S	Thu Feb 03 15:42:41 2011 -0800
    16.3 @@ -12,6 +12,17 @@
    16.4  #include <asm/page.h>
    16.5  #include <public/xen.h>
    16.6  
    16.7 +#ifdef XEN_KDB_CONFIG
    16.8 +/* return (int) smp_processor_id in reg. the upper 32bits should already be
    16.9 + *  * zeroed(?), but we clear anyways by shifting left and right */
   16.10 +#define GET_PROCESSOR_ID(reg)         \
   16.11 +        movq $~(STACK_SIZE-1),reg;    \
   16.12 +        andq %rsp,reg;                \
   16.13 +        orq  $(STACK_SIZE-16),reg;    \
   16.14 +        movq (reg),reg;               \
   16.15 +        shl $32,reg;                  \
   16.16 +        shr $32,reg;
   16.17 +#endif
   16.18          ALIGN
   16.19  /* %rbx: struct vcpu */
   16.20  switch_to_kernel:
   16.21 @@ -185,6 +196,10 @@ skip_clobber:
   16.22  /* %rbx: struct vcpu */
   16.23  test_all_events:
   16.24          cli                             # tests must not race interrupts
   16.25 +#ifdef XEN_KDB_CONFIG                   /* 64bit dom0 will resume here */
   16.26 +        testl $1, kdb_session_begun(%rip)
   16.27 +        jnz   restore_all_guest
   16.28 +#endif
   16.29  /*test_softirqs:*/  
   16.30          movl  VCPU_processor(%rbx),%eax
   16.31          shl   $IRQSTAT_shift,%rax
   16.32 @@ -533,6 +548,12 @@ ENTRY(debug)
   16.33  
   16.34  ENTRY(int3)
   16.35          pushq $0
   16.36 +#ifdef XEN_KDB_CONFIG
   16.37 +        pushq %rax
   16.38 +        GET_PROCESSOR_ID(%rax)
   16.39 +        lock  bts %rax, kdb_cpu_traps(%rip)
   16.40 +        popq  %rax
   16.41 +#endif
   16.42          movl  $TRAP_int3,4(%rsp)
   16.43          jmp   handle_exception
   16.44  
    17.1 --- a/xen/common/domain.c	Thu Feb 03 14:20:29 2011 -0800
    17.2 +++ b/xen/common/domain.c	Thu Feb 03 15:42:41 2011 -0800
    17.3 @@ -513,6 +513,15 @@ void domain_shutdown(struct domain *d, u
    17.4  {
    17.5      struct vcpu *v;
    17.6  
    17.7 +#ifdef XEN_KDB_CONFIG
    17.8 +    if (reason == SHUTDOWN_crash) {
    17.9 +        if ( IS_PRIV(d) )
   17.10 +            kdb_trap_immed(KDB_TRAP_FATAL);
   17.11 +        else
   17.12 +            kdb_trap_immed(KDB_TRAP_NONFATAL);
   17.13 +    }
   17.14 +#endif
   17.15 +
   17.16      spin_lock(&d->shutdown_lock);
   17.17  
   17.18      if ( d->shutdown_code == -1 )
    18.1 --- a/xen/common/sched_credit.c	Thu Feb 03 14:20:29 2011 -0800
    18.2 +++ b/xen/common/sched_credit.c	Thu Feb 03 15:42:41 2011 -0800
    18.3 @@ -1407,6 +1407,33 @@ csched_dump_vcpu(struct csched_vcpu *svc
    18.4      printk("\n");
    18.5  }
    18.6  
    18.7 +#ifdef XEN_KDB_CONFIG
    18.8 +static void kdb_csched_dump(int cpu)
    18.9 +{
   18.10 +    struct csched_pcpu *pcpup = CSCHED_PCPU(cpu);
   18.11 +    struct vcpu *scurrvp = (CSCHED_VCPU(current))->vcpu;
   18.12 +    struct list_head *tmp, *runq = RUNQ(cpu);
   18.13 +
   18.14 +    kdbp("    csched_pcpu: %p\n", pcpup);
   18.15 +    kdbp("    curr csched:%p {vcpu:%p id:%d domid:%d}\n", (current)->sched_priv,
   18.16 +         scurrvp, scurrvp->vcpu_id, scurrvp->domain->domain_id);
   18.17 +    kdbp("    runq:\n");
   18.18 +
   18.19 +    /* next is top of struct, so screw stupid, ugly hard to follow macros */
   18.20 +    if (offsetof(struct csched_vcpu, runq_elem.next) != 0) {
   18.21 +        kdbp("next is not first in struct csched_vcpu. please fixme\n");
   18.22 +        return;        /* otherwise for loop will crash */
   18.23 +    }
   18.24 +    for (tmp = runq->next; tmp != runq; tmp = tmp->next) {
   18.25 +
   18.26 +        struct csched_vcpu *csp = (struct csched_vcpu *)tmp;
   18.27 +        struct vcpu *vp = csp->vcpu;
   18.28 +        kdbp("      csp:%p pri:%02d vcpu: {p:%p id:%d domid:%d}\n", csp,
   18.29 +             csp->pri, vp, vp->vcpu_id, vp->domain->domain_id);
   18.30 +    };
   18.31 +}
   18.32 +#endif
   18.33 +
   18.34  static void
   18.35  csched_dump_pcpu(const struct scheduler *ops, int cpu)
   18.36  {
   18.37 @@ -1416,6 +1443,10 @@ csched_dump_pcpu(const struct scheduler 
   18.38      int loop;
   18.39  #define cpustr keyhandler_scratch
   18.40  
   18.41 +#ifdef XEN_KDB_CONFIG
   18.42 +    kdb_csched_dump(cpu);
   18.43 +    return;
   18.44 +#endif
   18.45      spc = CSCHED_PCPU(cpu);
   18.46      runq = &spc->runq;
   18.47  
    19.1 --- a/xen/common/schedule.c	Thu Feb 03 14:20:29 2011 -0800
    19.2 +++ b/xen/common/schedule.c	Thu Feb 03 15:42:41 2011 -0800
    19.3 @@ -1400,6 +1400,25 @@ void wait(void)
    19.4      schedule();
    19.5  }
    19.6  
    19.7 +#ifdef XEN_KDB_CONFIG
    19.8 +void kdb_print_sched_info(void)
    19.9 +{
   19.10 +    int cpu;
   19.11 +
   19.12 +    kdbp("Scheduler: name:%s opt_name:%s id:%d\n", ops.name, ops.opt_name,
   19.13 +         ops.sched_id);
   19.14 +    kdbp("per cpu schedule_data:\n");
   19.15 +    for_each_online_cpu(cpu) {
   19.16 +        struct schedule_data *p =  &per_cpu(schedule_data, cpu);
   19.17 +        kdbp("  cpu:%d  &(per cpu)schedule_data:%p\n", cpu, p);
   19.18 +        kdbp("         curr:%p sched_priv:%p\n", p->curr, p->sched_priv);
   19.19 +        kdbp("\n");
   19.20 +        /* ops.dump_cpu_state(&ops, cpu); */
   19.21 +        kdbp("\n");
   19.22 +    }
   19.23 +}
   19.24 +#endif
   19.25 +
   19.26  #ifdef CONFIG_COMPAT
   19.27  #include "compat/schedule.c"
   19.28  #endif
    20.1 --- a/xen/common/symbols.c	Thu Feb 03 14:20:29 2011 -0800
    20.2 +++ b/xen/common/symbols.c	Thu Feb 03 15:42:41 2011 -0800
    20.3 @@ -168,3 +168,22 @@ void __print_symbol(const char *fmt, uns
    20.4  
    20.5      spin_unlock_irqrestore(&lock, flags);
    20.6  }
    20.7 +
    20.8 +#ifdef XEN_KDB_CONFIG
    20.9 +/*
   20.10 + *  * Given a symbol, return its address 
   20.11 + *   */
   20.12 +unsigned long address_lookup(char *symp)
   20.13 +{
   20.14 +    int i, off = 0;
   20.15 +    char namebuf[KSYM_NAME_LEN+1];
   20.16 +
   20.17 +    for (i=0; i < symbols_num_syms; i++) {
   20.18 +        off = symbols_expand_symbol(off, namebuf);
   20.19 +        if (strcmp(namebuf, symp) == 0)                  /* found it */
   20.20 +            return symbols_address(i);
   20.21 +    }
   20.22 +    return 0;
   20.23 +}
   20.24 +#endif
   20.25 +
    21.1 --- a/xen/common/timer.c	Thu Feb 03 14:20:29 2011 -0800
    21.2 +++ b/xen/common/timer.c	Thu Feb 03 15:42:41 2011 -0800
    21.3 @@ -643,6 +643,41 @@ void __init timer_init(void)
    21.4      register_keyhandler('a', &dump_timerq_keyhandler);
    21.5  }
    21.6  
    21.7 +#ifdef XEN_KDB_CONFIG
    21.8 +#include <xen/symbols.h>
    21.9 +void kdb_dump_timer_queues(void)
   21.10 +{
   21.11 +    struct timer  *t;
   21.12 +    struct timers *ts;
   21.13 +    unsigned long sz, offs;
   21.14 +    char buf[KSYM_NAME_LEN+1];
   21.15 +    int            cpu, j;
   21.16 +    s_time_t       now = NOW();
   21.17 +
   21.18 +    for_each_online_cpu( cpu )
   21.19 +    {
   21.20 +        ts = &per_cpu(timers, cpu);
   21.21 +        kdbp("CPU[%02d]: NOW:0x%08x%08x\n", cpu, (u32)(now>>32), (u32)now);
   21.22 +
   21.23 +        /* timers in the heap */
   21.24 +        for ( j = 1; j <= GET_HEAP_SIZE(ts->heap); j++ ) {
   21.25 +            t = ts->heap[j];
   21.26 +            kdbp("  %d: exp=0x%08x%08x fn:%s data:%p\n",
   21.27 +                 j, (u32)(t->expires>>32), (u32)t->expires,
   21.28 +                 symbols_lookup((unsigned long)t->function, &sz, &offs, buf),
   21.29 +                 t->data);
   21.30 +        }
   21.31 +        /* timers on the link list */
   21.32 +        for ( t = ts->list, j = 0; t != NULL; t = t->list_next, j++ ) {
   21.33 +            kdbp(" L%d: exp=0x%08x%08x fn:%s data:%p\n",
   21.34 +                 j, (u32)(t->expires>>32), (u32)t->expires,
   21.35 +                 symbols_lookup((unsigned long)t->function, &sz, &offs, buf),
   21.36 +                 t->data);
   21.37 +        }
   21.38 +    }
   21.39 +}
   21.40 +#endif
   21.41 +
   21.42  /*
   21.43   * Local variables:
   21.44   * mode: C
    22.1 --- a/xen/drivers/char/console.c	Thu Feb 03 14:20:29 2011 -0800
    22.2 +++ b/xen/drivers/char/console.c	Thu Feb 03 15:42:41 2011 -0800
    22.3 @@ -305,6 +305,23 @@ static void serial_rx(char c, struct cpu
    22.4  {
    22.5      static int switch_code_count = 0;
    22.6  
    22.7 +#ifdef XEN_KDB_CONFIG
    22.8 +    extern volatile int kdb_session_begun;
    22.9 +
   22.10 +    /* if ctrl-\ pressed and kdb handles it, return */
   22.11 +    if (kdb_enabled && c == 0x1c) {
   22.12 +        if (!kdb_session_begun) {
   22.13 +            if (kdb_keyboard(regs))
   22.14 +                return;
   22.15 +        } else {
   22.16 +            kdbp("Sorry... kdb session already active.. please try again..\n");
   22.17 +            return;
   22.18 +        }
   22.19 +    }
   22.20 +    if (kdb_session_begun)      /* kdb should already be polling */
   22.21 +        return;                 /* swallow chars so they don't buffer in dom0 */
   22.22 +#endif
   22.23 +
   22.24      if ( switch_code && (c == switch_code) )
   22.25      {
   22.26          /* We eat CTRL-<switch_char> in groups of 3 to switch console input. */
   22.27 @@ -717,6 +734,18 @@ void console_end_sync(void)
   22.28      atomic_dec(&print_everything);
   22.29  }
   22.30  
   22.31 +#ifdef XEN_KDB_CONFIG
   22.32 +void console_putc(char c)
   22.33 +{
   22.34 +    serial_putc(sercon_handle, c);
   22.35 +}
   22.36 +
   22.37 +int console_getc(void)
   22.38 +{
   22.39 +    return serial_getc(sercon_handle);
   22.40 +}
   22.41 +#endif
   22.42 +
   22.43  /*
   22.44   * printk rate limiting, lifted from Linux.
   22.45   *
    23.1 --- a/xen/include/asm-x86/debugger.h	Thu Feb 03 14:20:29 2011 -0800
    23.2 +++ b/xen/include/asm-x86/debugger.h	Thu Feb 03 15:42:41 2011 -0800
    23.3 @@ -39,7 +39,18 @@
    23.4  #define DEBUGGER_trap_fatal(_v, _r) \
    23.5      if ( debugger_trap_fatal(_v, _r) ) return;
    23.6  
    23.7 -#if defined(CRASH_DEBUG)
    23.8 +#if defined(XEN_KDB_CONFIG)
    23.9 +extern volatile int kdb_enabled;
   23.10 +extern void kdb_init(void);
   23.11 +extern int kdb_keyboard(struct cpu_user_regs *);
   23.12 +extern void kdb_ssni_reenter(struct cpu_user_regs *);
   23.13 +extern int kdb_handle_trap_entry(int, struct cpu_user_regs *);
   23.14 +extern int kdb_trap_fatal(int, struct cpu_user_regs *);  /* fatal with regs */
   23.15 +
   23.16 +#define debugger_trap_immediate() kdb_trap_immed(KDB_TRAP_NONFATAL)
   23.17 +#define debugger_trap_fatal(_v, _r) kdb_trap_fatal(_v, _r)
   23.18 +
   23.19 +#elif defined(CRASH_DEBUG)
   23.20  
   23.21  #include <xen/gdbstub.h>
   23.22  
   23.23 @@ -65,6 +76,11 @@ static inline int debugger_trap_entry(
   23.24  {
   23.25      struct vcpu *v = current;
   23.26  
   23.27 +#ifdef XEN_KDB_CONFIG
   23.28 +    if (kdb_handle_trap_entry(vector, regs))
   23.29 +        return 1;
   23.30 +#endif
   23.31 +
   23.32      if ( guest_kernel_mode(v, regs) && v->domain->debugger_attached &&
   23.33           ((vector == TRAP_int3) || (vector == TRAP_debug)) )
   23.34      {
    24.1 --- a/xen/include/xen/lib.h	Thu Feb 03 14:20:29 2011 -0800
    24.2 +++ b/xen/include/xen/lib.h	Thu Feb 03 15:42:41 2011 -0800
    24.3 @@ -120,4 +120,16 @@ extern void add_taint(unsigned);
    24.4  struct cpu_user_regs;
    24.5  void dump_execstate(struct cpu_user_regs *);
    24.6  
    24.7 +#ifdef XEN_KDB_CONFIG
    24.8 +/* debugger.h is not included from everywhere, hence here */
    24.9 +#define KDB_TRAP_FATAL     1    /* trap is fatal. can't resume from kdb */
   24.10 +#define KDB_TRAP_NONFATAL  2    /* can resume from kdb */
   24.11 +#define KDB_TRAP_KDBSTACK  3    /* to debug kdb itself. dump kdb stack */
   24.12 +
   24.13 +/* following can be called from anywhere in xen to debug */
   24.14 +extern void kdb_trap_immed(int);
   24.15 +extern void kdbtrc(unsigned int, unsigned int, uint64_t, uint64_t, uint64_t);
   24.16 +extern void kdbp(const char *fmt, ...);
   24.17 +#endif
   24.18 +
   24.19  #endif /* __LIB_H__ */
    25.1 --- a/xen/include/xen/sched.h	Thu Feb 03 14:20:29 2011 -0800
    25.2 +++ b/xen/include/xen/sched.h	Thu Feb 03 15:42:41 2011 -0800
    25.3 @@ -548,10 +548,14 @@ void startup_cpu_idle_loop(void);
    25.4  unsigned long hypercall_create_continuation(
    25.5      unsigned int op, const char *format, ...);
    25.6  
    25.7 +#ifdef XEN_KDB_CONFIG
    25.8 +#define hypercall_preempt_check() (0)
    25.9 +#else
   25.10  #define hypercall_preempt_check() (unlikely(    \
   25.11          softirq_pending(smp_processor_id()) |   \
   25.12          local_events_need_delivery()            \
   25.13      ))
   25.14 +#endif
   25.15  
   25.16  extern struct domain *domain_list;
   25.17  
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/xen/kdb/Makefile	Thu Feb 03 15:42:41 2011 -0800
    26.3 @@ -0,0 +1,5 @@
    26.4 +
    26.5 +obj-y		:= kdbmain.o kdb_cmds.o kdb_io.o 
    26.6 +
    26.7 +subdir-y += x86 guest
    26.8 +
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/xen/kdb/README	Thu Feb 03 15:42:41 2011 -0800
    27.3 @@ -0,0 +1,243 @@
    27.4 +
    27.5 +Welcome to kdb for xen, a hypervisor built in debugger.
    27.6 +
    27.7 +FEATURES:
    27.8 +   - set breakpoints in hypervisor
    27.9 +   - examine virt/machine memory, registers, domains, vcpus, etc...
   27.10 +   - single step, single step till jump/call, step over call to next
   27.11 +     instruction after the call.
   27.12 +   - examine memory of a PV/HVM guest. 
   27.13 +   - set breakpoints, single step, etc... for a PV guest.
   27.14 +   - breaking into the debugger will freeze the system, all CPUs will pause,
   27.15 +     no interrupts are acknowledged in the debugger. (Hence, the wall clock
   27.16 +     will drift)
   27.17 +   - single step will step only that cpu.
   27.18 +   - earlykdb: break into kdb very early during boot. Put "earlykdb" on the
   27.19 +               xen command line in grub.conf.
   27.20 +   - generic tracing functions (see below) for quick tracing to debug timing
   27.21 +     related problems. To use:
   27.22 +        o set KDBTRCMAX to max num of recs in circular trc buffer in kdbmain.c
   27.23 +	o call kdb_trc() from anywhere in xen
   27.24 +	o turn tracing on by setting kdb_trcon in kdbmain.c or trcon command.
   27.25 +	o trcp in kdb will give hints to dump trace recs. Use dd to see buffer
   27.26 +	o trcz will zero out the entire buffer if needed.
   27.27 +
   27.28 +NOTE:
   27.29 +   - since almost all numbers are in hex, 0x is not prefixed. Instead, decimal
   27.30 +     numbers are preceded by $, as in $17 (sorry, one gets used to it). Note,
   27.31 +     vcpu num, cpu num, domid are always displayed in decimal, without $.
   27.32 +   - watchdog must be disabled to use kdb
   27.33 +
   27.34 +ISSUES:
   27.35 +   - Currently, debug hypervisor is not supported. Make sure NDEBUG is defined
   27.36 +     or compile with debug=n
   27.37 +   - "timer went backwards" messages on dom0, but kdb/hyp should be fine.
   27.38 +     I usually do "echo 2 > /proc/sys/kernel/printk" when using kdb.
   27.39 +   - 32bit hypervisor may hang. Tested on 64bit hypervisor only.
   27.40 +    
   27.41 +
   27.42 +TO BUILD:
   27.43 + - do >make kdb=y
   27.44 +
   27.45 +HOW TO USE:
   27.46 +  1. A serial line is needed to use the debugger. Set up a serial line
   27.47 +     from the source machine to target victim. Make sure the serial line
   27.48 +     is working properly by displaying login prompt and loging in etc....
   27.49 +
   27.50 +  2. Add following to grub.conf:
   27.51 +        kernel /xen.kdb console=com1,vga com1=57600,8n1 dom0_mem=542M
   27.52 +
   27.53 +        (57600 or whatever used in step 1 above)
   27.54 +
   27.55 +  3. Boot the hypervisor built with the debugger. 
   27.56 +
   27.57 +  4. ctrl-\ (ctrl and backslash) will break into the debugger. If the system is
   27.58 +     badly hung, pressing NMI would also break into it. However, once kdb is
   27.59 +     entered via NMI, normal execution can't continue.
   27.60 +
   27.61 +  5. type 'h' for list of commands.
   27.62 +
   27.63 +  6. Command line editing is limited to backspace. ctrl-c to start a new cmd.
   27.64 +
   27.65 +
   27.66 +
   27.67 +GUEST debug:
   27.68 +  - type sym in the debugger
   27.69 +  - for REL4, grep kallsyms_names, kallsyms_addresses, and kallsyms_num_syms
   27.70 +    in the guest System.map* file. Run sym again with domid and the three
   27.71 +    values on the command line.
   27.72 +  - Now basic symbols can be used for guest debug. Note, if the binary is not
   27.73 +    built with symbols, only function names are available, but not global vars.
   27.74 +
   27.75 +    Eg: sym 0 c0696084 c068a590 c0696080 c06b43e8 c06b4740
   27.76 +        will set symbols for dom 0. Then :
   27.77 +
   27.78 +        [4]xkdb> bp some_function 0
   27.79 +
   27.80 +	wills set bp at some_function in dom 0
   27.81 +
   27.82 +	[3]xkdb> dw c068a590 32 0 : display 32 bytes of dom0 memory
   27.83 +
   27.84 +
   27.85 +Tips:
   27.86 +  - In "[0]xkdb>"  : 0 is the cpu number in decimal
   27.87 +  - In
   27.88 +      00000000c042645c: 0:do_timer+17                  push %ebp
   27.89 +    0:do_timer : 0 is the domid in hex
   27.90 +    offset +17 is in hex.
   27.91 +
   27.92 +    absense of 0: would indicate it's a hypervisor function
   27.93 +
   27.94 +  - commands starting with kdb (kdb*) are for kdb debug only.
   27.95 +
   27.96 +
   27.97 +Finally,
   27.98 + - think hex.
   27.99 + - bug/problem: enter kdbdbg, reproduce, and send me the output.
  27.100 +   If the output is not enough, I may ask to run kdbdbg twice, then collect
  27.101 +   output.
  27.102 +
  27.103 +
  27.104 +Thanks,
  27.105 +Mukesh Rathor
  27.106 +Oracle Corporatin, 
  27.107 +Redwood Shores, CA 94065
  27.108 +
  27.109 +--------------------------------------------------------------------------------
  27.110 +COMMAND DESCRIPTION:
  27.111 +
  27.112 +info:  Print basic info like version, compile flags, etc..
  27.113 +
  27.114 +cur:  print current domain id and vcpu id
  27.115 +
  27.116 +f: display current stack. If a vcpu ptr is given, then print stack for that
  27.117 +   VCPU by using its IP and SP.
  27.118 +
  27.119 +fg: display stack for a guest given domid, SP and IP.
  27.120 +
  27.121 +dw: display words of memory. 'num' of bytes is optional, but if displaying guest
  27.122 +    memory, then is required.
  27.123 +
  27.124 +dd: same as above, but display doublewords.
  27.125 +
  27.126 +dwm: same as above but the address is machine address instead of virtual.
  27.127 +
  27.128 +ddm: same as above, but display doublewords.
  27.129 +
  27.130 +dr: display registers. if 'sp' is specified then print few extra registers.
  27.131 +
  27.132 +drg: display guest context saved on stack bottom.
  27.133 +
  27.134 +dis: disassemble instructions. If disassembling for guest, then 'num' must
  27.135 +     be specified. 'num' is number of instrs to display.
  27.136 +
  27.137 +dism: toggle disassembly mode between Intel and ATT/GAS.
  27.138 +
  27.139 +mw: modify word in memory given virtual address. 'domid' may be specified if
  27.140 +    modifying guest memory. value is assumed in hex even without 0x.
  27.141 +
  27.142 +md: same as above but modify doubleword.
  27.143 +
  27.144 +mr: modify register. value is assumd hex.
  27.145 +
  27.146 +bc: clear given or all breakpoints
  27.147 +
  27.148 +bp: display breakpoints or set a breakpoint. Domid may be specified to set a bp
  27.149 +    in guest. kdb functions may not be specified if debugging kdb.
  27.150 +    Example:
  27.151 +      xkdb> bp acpi_processor_idle  : will set bp in xen
  27.152 +      xkdb> bp default_idle 0 :   will set bp in domid 0
  27.153 +      xkdb> bp idle_cpu 9 :   will set bp in domid 9
  27.154 +
  27.155 +     Conditions may be specified for a bp: lhs == rhs or lhs != rhs
  27.156 +     where : lhs is register like 'r6', 'rax', etc...  or memory location
  27.157 +             rhs is hex value with or without leading 0x.
  27.158 +     Thus,
  27.159 +      xkdb> bp acpi_processor_idle rdi == c000 
  27.160 +      xkdb> bp 0xffffffff80062ebc 0 rsi == ffff880021edbc98 : will break into
  27.161 +            kdb at 0xffffffff80062ebc in dom0 when rsi is ffff880021edbc98 
  27.162 +
  27.163 +btp: break point trace. Upon bp, print some info and continue without stopping.
  27.164 +   Ex: btp idle_cpu 7 rax rbx 0x20ef5a5 r9
  27.165 +
  27.166 +   will print: rax, rbx, *(long *)0x20ef5a5, r9 upon hitting idle_cpu() and 
  27.167 +               continue.
  27.168 +
  27.169 +wp: set a watchpoint at a virtual address which can belong to hypervisor or
  27.170 +    any guest. Do not specify wp in kdb path if debugging kdb.
  27.171 +
  27.172 +wc: clear given or all watchpoints.
  27.173 +
  27.174 +ni: single step, stepping over function calls.
  27.175 +
  27.176 +ss: single step. Be carefull when in interrupt handlers or context switches.
  27.177 +    
  27.178 +ssb: single step to branch. Use with care.
  27.179 +
  27.180 +go: leave kdb and continue.
  27.181 +
  27.182 +cpu: go back to orig cpu when entering kdb. If 'cpu number' given, then switch 
  27.183 +     to that cpu. If 'all' then show status of all cpus.
  27.184 +
  27.185 +nmi: Only available in hung/crash state. Send NMI to a cpu that may be hung.
  27.186 +
  27.187 +sym: Initialize a symbol table for debugging a guest. Look into the System.map
  27.188 +     file of guest for certain symbol values and provide them here.
  27.189 +
  27.190 +vcpuh: Given vcpu ptr, display hvm_vcpu struct.
  27.191 +
  27.192 +vcpu: Display current vcpu struct. If 'vcpu-ptr' given, display that vcpu.
  27.193 +
  27.194 +dom: display current domain. If 'domid' then display that domid. If 'all', then
  27.195 +     display all domains.
  27.196 +
  27.197 +sched: show schedular info and run queues.
  27.198 +
  27.199 +mmu: print basic mmu info
  27.200 +
  27.201 +p2m: convert a gpfn to mfn given a domid. value in hex even without 0x.
  27.202 +
  27.203 +m2p: convert mfn to pfn. value in hex even without 0x.
  27.204 +
  27.205 +dpage: display struct page given a mfn or struct page ptr. Since, no info is 
  27.206 +       kept on page type, we display all possible page types.
  27.207 +
  27.208 +dtrq: display timer queues.
  27.209 +
  27.210 +didt: dump IDT table.
  27.211 +
  27.212 +dgt: dump GDT table.
  27.213 +
  27.214 +dirq: display IRQ bindings.
  27.215 +
  27.216 +dvmc: display all or given dom/vcpu VMCS or VMCB.
  27.217 +
  27.218 +trcon: turn tracing on. Trace hooks must be added in xen and kdb function
  27.219 +       called directly from there.
  27.220 +
  27.221 +trcoff: turn tracing off.
  27.222 +
  27.223 +trcz: zero trace buffer.
  27.224 +
  27.225 +trcp: give hints to print the circular trace buffer, like current active ptr.
  27.226 +
  27.227 +usr1: allows to add any arbitraty command quickly.
  27.228 +
  27.229 +--------------------------------------------------------------------------------
  27.230 +/*
  27.231 + * Copyright (C) 2008 Oracle.  All rights reserved.
  27.232 + *
  27.233 + * This program is free software; you can redistribute it and/or
  27.234 + * modify it under the terms of the GNU General Public
  27.235 + * License v2 as published by the Free Software Foundation.
  27.236 + *
  27.237 + * This program is distributed in the hope that it will be useful,
  27.238 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27.239 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  27.240 + * General Public License for more details.
  27.241 + *
  27.242 + * You should have received a copy of the GNU General Public
  27.243 + * License along with this program; if not, write to the
  27.244 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  27.245 + * Boston, MA 021110-1307, USA.
  27.246 + */
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/xen/kdb/guest/Makefile	Thu Feb 03 15:42:41 2011 -0800
    28.3 @@ -0,0 +1,3 @@
    28.4 +
    28.5 +obj-y           := kdb_guest.o
    28.6 +
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/xen/kdb/guest/kdb_guest.c	Thu Feb 03 15:42:41 2011 -0800
    29.3 @@ -0,0 +1,319 @@
    29.4 +/*
    29.5 + * Copyright (C) 2009, Mukesh Rathor, Oracle Corp.  All rights reserved.
    29.6 + *
    29.7 + * This program is free software; you can redistribute it and/or
    29.8 + * modify it under the terms of the GNU General Public
    29.9 + * License v2 as published by the Free Software Foundation.
   29.10 + *
   29.11 + * This program is distributed in the hope that it will be useful,
   29.12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   29.13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   29.14 + * General Public License for more details.
   29.15 + *
   29.16 + * You should have received a copy of the GNU General Public
   29.17 + * License along with this program; if not, write to the
   29.18 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   29.19 + * Boston, MA 021110-1307, USA.
   29.20 + */
   29.21 +
   29.22 +#include "../include/kdbinc.h"
   29.23 +
   29.24 +/* information for symbols for a guest (includeing dom 0 ) is saved here */
   29.25 +struct gst_syminfo {           /* guest symbols info */
   29.26 +    int   domid;               /* which domain */
   29.27 +    int   bitness;             /* 32 or 64 */
   29.28 +    void *addrtblp;            /* ptr to (32/64)addresses tbl */
   29.29 +    u8   *toktbl;              /* ptr to kallsyms_token_table */
   29.30 +    u16  *tokidxtbl;           /* ptr to kallsyms_token_index */
   29.31 +    u8   *kallsyms_names;      /* ptr to kallsyms_names */
   29.32 +    long  kallsyms_num_syms;   /* ptr to kallsyms_num_syms */
   29.33 +    kdbva_t  stext;            /* value of _stext in guest */
   29.34 +    kdbva_t  etext;            /* value of _etext in guest */
   29.35 +    kdbva_t  sinittext;        /* value of _sinittext in guest */
   29.36 +    kdbva_t  einittext;        /* value of _einittext in guest */
   29.37 +};
   29.38 +
   29.39 +#define MAX_CACHE 16                              /* cache upto 16 guests */
   29.40 +struct gst_syminfo gst_syminfoa[MAX_CACHE];       /* guest symbol info array */
   29.41 +
   29.42 +static struct gst_syminfo *
   29.43 +kdb_domid2syminfop(domid_t domid)
   29.44 +{
   29.45 +    return (&gst_syminfoa[domid % MAX_CACHE]);      
   29.46 +}
   29.47 +
   29.48 +/* check if an address looks like text address in guest */
   29.49 +int
   29.50 +kdb_is_addr_guest_text(kdbva_t addr, int domid)
   29.51 +{
   29.52 +    struct gst_syminfo *gp = kdb_domid2syminfop(domid);
   29.53 +
   29.54 +    if (!gp->stext || !gp->etext)
   29.55 +        return 0;
   29.56 +    KDBGP1("guestaddr: addr:%lx domid:%d\n", addr, domid);
   29.57 +
   29.58 +    return ( (addr >= gp->stext && addr <= gp->etext) ||
   29.59 +             (addr >= gp->sinittext && addr <= gp->einittext) );
   29.60 +}
   29.61 +
   29.62 +/*
   29.63 + * returns: value of kallsyms_addresses[idx];
   29.64 + */
   29.65 +static kdbva_t
   29.66 +kdb_rd_guest_addrtbl(struct gst_syminfo *gp, int idx)
   29.67 +{
   29.68 +    kdbva_t addr, retaddr=0;
   29.69 +    int num = gp->bitness/8;       /* whether 4 byte or 8 byte ptrs */
   29.70 +    domid_t id = gp->domid;
   29.71 +
   29.72 +    addr = (kdbva_t)(((char *)gp->addrtblp) + idx * num);
   29.73 +    KDBGP1("rdguestaddrtbl:addr:%lx idx:%d\n", addr, idx);
   29.74 +
   29.75 +    if (kdb_read_mem(addr, (kdbbyt_t *)&retaddr,num,id) != num) {
   29.76 +        kdbp("Can't read addrtbl domid:%d at:%lx\n", id, addr);
   29.77 +        return 0;
   29.78 +    }
   29.79 +    KDBGP1("rdguestaddrtbl:exit:retaddr:%lx\n", retaddr);
   29.80 +    return retaddr;
   29.81 +}
   29.82 +
   29.83 +/* Based on el5 kallsyms.c file. */
   29.84 +static unsigned int 
   29.85 +kdb_expand_el5_sym(struct gst_syminfo *gp, unsigned int off, char *result)
   29.86 +{   
   29.87 +    int len, skipped_first = 0;
   29.88 +    u8 u8idx, *tptr, *datap;
   29.89 +    domid_t domid = gp->domid;
   29.90 +
   29.91 +    *result = '\0';
   29.92 +
   29.93 +    /* get the compressed symbol length from the first symbol byte */
   29.94 +    datap = gp->kallsyms_names + off;
   29.95 +    len = 0;
   29.96 +    if ((kdb_read_mem((kdbva_t)datap, (kdbbyt_t *)&len, 1, domid)) != 1) {
   29.97 +        KDBGP("failed to read guest memory\n");
   29.98 +        return 0;
   29.99 +    }
  29.100 +    datap++;
  29.101 +
  29.102 +    /* update the offset to return the offset for the next symbol on
  29.103 +     * the compressed stream */
  29.104 +    off += len + 1;
  29.105 +
  29.106 +    /* for every byte on the compressed symbol data, copy the table
  29.107 +     * entry for that byte */
  29.108 +    while(len) {
  29.109 +        u16 u16idx, *u16p;
  29.110 +        if (kdb_read_mem((kdbva_t)datap,(kdbbyt_t *)&u8idx,1,domid)!=1){
  29.111 +            kdbp("memory (u8idx) read error:%p\n",gp->tokidxtbl);
  29.112 +            return 0;
  29.113 +        }
  29.114 +        u16p = u8idx + gp->tokidxtbl;
  29.115 +        if (kdb_read_mem((kdbva_t)u16p,(kdbbyt_t *)&u16idx,2,domid)!=2){
  29.116 +            kdbp("tokidxtbl read error:%p\n", u16p);
  29.117 +            return 0;
  29.118 +        }
  29.119 +        tptr = gp->toktbl + u16idx;
  29.120 +        datap++;
  29.121 +        len--;
  29.122 +
  29.123 +        while ((kdb_read_mem((kdbva_t)tptr, (kdbbyt_t *)&u8idx, 1, domid)==1) &&
  29.124 +               u8idx) {
  29.125 +
  29.126 +            if(skipped_first) {
  29.127 +                *result = u8idx;
  29.128 +                result++;
  29.129 +            } else
  29.130 +                skipped_first = 1;
  29.131 +            tptr++;
  29.132 +        }
  29.133 +    }
  29.134 +    *result = '\0';
  29.135 +    return off;          /* return to offset to the next symbol */
  29.136 +}
  29.137 +
  29.138 +#define EL4_NMLEN 127
  29.139 +/* so much pain, so not sure of it's worth .. :).. */
  29.140 +static kdbva_t
  29.141 +kdb_expand_el4_sym(struct gst_syminfo *gp, int low, char *result, char *symp)
  29.142 +{   
  29.143 +    int i, j;
  29.144 +    u8 *nmp = gp->kallsyms_names;       /* guest address space */
  29.145 +    kdbbyt_t byte, prefix;
  29.146 +    domid_t id = gp->domid;
  29.147 +    kdbva_t addr;
  29.148 +
  29.149 +    KDBGP1("Eel4sym:nmp:%p maxidx:$%d sym:%s\n", nmp, low, symp);
  29.150 +    for (i=0; i <= low; i++) {
  29.151 +        /* unsigned prefix = *name++; */
  29.152 +        if (kdb_read_mem((kdbva_t)nmp, &prefix, 1, id) != 1) {
  29.153 +            kdbp("failed to read:%p domid:%x\n", nmp, id);
  29.154 +            return 0;
  29.155 +        }
  29.156 +        KDBGP2("el4:i:%d prefix:%x\n", i, prefix);
  29.157 +        nmp++;
  29.158 +        /* strncpy(namebuf + prefix, name, KSYM_NAME_LEN - prefix); */
  29.159 +        addr = (long)result + prefix;
  29.160 +        for (j=0; j < EL4_NMLEN-prefix; j++) {
  29.161 +            if (kdb_read_mem((kdbva_t)nmp, &byte, 1, id) != 1) {
  29.162 +                kdbp("failed read:%p domid:%x\n", nmp, id);
  29.163 +                return 0;
  29.164 +            }
  29.165 +            KDBGP2("el4:j:%d byte:%x\n", j, byte);
  29.166 +            *(kdbbyt_t *)addr = byte;
  29.167 +            addr++; nmp++;
  29.168 +            if (byte == '\0')
  29.169 +                break;
  29.170 +        }
  29.171 +        KDBGP2("el4sym:i:%d res:%s\n", i, result);
  29.172 +        if (symp && strcmp(result, symp) == 0)
  29.173 +            return(kdb_rd_guest_addrtbl(gp, i));
  29.174 +
  29.175 +        /* kallsyms.c: name += strlen(name) + 1; */
  29.176 +        if (j == EL4_NMLEN-prefix && byte != '\0')
  29.177 +            while (kdb_read_mem((kdbva_t)nmp, &byte, 1, id) && byte != '\0')
  29.178 +                nmp++;
  29.179 +    }
  29.180 +    KDBGP1("Xel4sym: na-ga-da\n");
  29.181 +    return 0;
  29.182 +}
  29.183 +
  29.184 +static unsigned int
  29.185 +kdb_get_el5_symoffset(struct gst_syminfo *gp, long pos)
  29.186 +{
  29.187 +    int i;
  29.188 +    u8 data, *namep;
  29.189 +    domid_t domid = gp->domid;
  29.190 +
  29.191 +    namep = gp->kallsyms_names;
  29.192 +    for (i=0; i < pos; i++) {
  29.193 +        if (kdb_read_mem((kdbva_t)namep, &data, 1, domid) != 1) {
  29.194 +            kdbp("Can't read id:$%d mem:%p\n", domid, namep);
  29.195 +            return 0;
  29.196 +        }
  29.197 +        namep = namep + data + 1;
  29.198 +    }
  29.199 +    return namep - gp->kallsyms_names;
  29.200 +}
  29.201 +
  29.202 +/*
  29.203 + * for a given guest domid (domid >= 0 && < KDB_HYPDOMID), convert addr to
  29.204 + * symbol. offset is set to  addr - symbolstart
  29.205 + */
  29.206 +char *
  29.207 +kdb_guest_addr2sym(unsigned long addr, domid_t domid, ulong *offsp)
  29.208 +{
  29.209 +    static char namebuf[KSYM_NAME_LEN+1];
  29.210 +    unsigned long low, high, mid;
  29.211 +    struct gst_syminfo *gp = kdb_domid2syminfop(domid);
  29.212 +
  29.213 +    *offsp = 0;
  29.214 +    if(gp->kallsyms_num_syms == 0)
  29.215 +        return " ??? ";
  29.216 +
  29.217 +    namebuf[0] = namebuf[KSYM_NAME_LEN] = '\0';
  29.218 +    if (1) {
  29.219 +        /* do a binary search on the sorted kallsyms_addresses array */
  29.220 +        low = 0;
  29.221 +        high = gp->kallsyms_num_syms;
  29.222 +
  29.223 +        while (high-low > 1) {
  29.224 +            mid = (low + high) / 2;
  29.225 +            if (kdb_rd_guest_addrtbl(gp, mid) <= addr) 
  29.226 +                low = mid;
  29.227 +            else 
  29.228 +                high = mid;
  29.229 +        }
  29.230 +        /* Grab name */
  29.231 +        if (gp->toktbl) {
  29.232 +            int symoff = kdb_get_el5_symoffset(gp,low);
  29.233 +            kdb_expand_el5_sym(gp, symoff, namebuf);
  29.234 +        } else
  29.235 +            kdb_expand_el4_sym(gp, low, namebuf, NULL);
  29.236 +        *offsp = addr - kdb_rd_guest_addrtbl(gp, low);
  29.237 +        return namebuf;
  29.238 +    }
  29.239 +    return " ???? ";
  29.240 +}
  29.241 +
  29.242 +
  29.243 +/* 
  29.244 + * save guest (dom0 and others) symbols info : domid and following addresses:
  29.245 + *     &kallsyms_names &kallsyms_addresses &kallsyms_num_syms \
  29.246 + *     &kallsyms_token_table &kallsyms_token_index
  29.247 + */
  29.248 +void
  29.249 +kdb_sav_dom_syminfo(domid_t domid, long namesp, long addrap, long nump,
  29.250 +                    long toktblp, long tokidxp)
  29.251 +{
  29.252 +    int bytes;
  29.253 +    long val = 0;    /* must be set to zero for 32 on 64 cases */
  29.254 +    struct gst_syminfo *gp = kdb_domid2syminfop(domid);
  29.255 +
  29.256 +    memset(gp, 0, sizeof(*gp));
  29.257 +
  29.258 +    gp->domid = domid;
  29.259 +    gp->bitness = kdb_guest_bitness(domid);
  29.260 +    gp->addrtblp = (void *)addrap;
  29.261 +    gp->kallsyms_names = (u8 *)namesp;
  29.262 +    gp->toktbl = (u8 *)toktblp;
  29.263 +    gp->tokidxtbl = (u16 *)tokidxp;
  29.264 +
  29.265 +    KDBGP("domid:%x bitness:$%d numsyms:$%ld arrayp:%p\n", domid,
  29.266 +          gp->bitness, gp->kallsyms_num_syms, gp->addrtblp);
  29.267 +
  29.268 +    bytes = gp->bitness/8;
  29.269 +    if (kdb_read_mem(nump, (kdbbyt_t *)&val, bytes, domid) != bytes) {
  29.270 +
  29.271 +        kdbp("Unable to read number of symbols from:%lx\n", nump);
  29.272 +        memset(gp, 0, sizeof(*gp));
  29.273 +        return;
  29.274 +    } else
  29.275 +        kdbp("Number of symbols:$%ld\n", val);
  29.276 +
  29.277 +    gp->kallsyms_num_syms = val;
  29.278 +
  29.279 +    bytes = (gp->bitness/8) * gp->kallsyms_num_syms;
  29.280 +    gp->stext = kdb_guest_sym2addr("_stext", domid);
  29.281 +    gp->etext = kdb_guest_sym2addr("_etext", domid);
  29.282 +    if (!gp->stext || !gp->etext)
  29.283 +        kdbp("Warn: Can't find stext/etext\n");
  29.284 +
  29.285 +    if (gp->toktbl && gp->tokidxtbl) {
  29.286 +        gp->sinittext = kdb_guest_sym2addr("_sinittext", domid);
  29.287 +        gp->einittext = kdb_guest_sym2addr("_einittext", domid);
  29.288 +        if (!gp->sinittext || !gp->einittext) {
  29.289 +            kdbp("Warn: Can't find sinittext/einittext\n");
  29.290 +    } 
  29.291 +    }
  29.292 +    KDBGP1("stxt:%lx etxt:%lx sitxt:%lx eitxt:%lx\n", gp->stext, gp->etext,
  29.293 +           gp->sinittext, gp->einittext);
  29.294 +    kdbp("Succesfully saved symbol info\n");
  29.295 +}
  29.296 +
  29.297 +/*
  29.298 + * given a symbol string for a guest/domid, return its address
  29.299 + */
  29.300 +kdbva_t
  29.301 +kdb_guest_sym2addr(char *symp, domid_t domid)
  29.302 +{
  29.303 +    char namebuf[KSYM_NAME_LEN+1];
  29.304 +    int i, off=0;
  29.305 +    struct gst_syminfo *gp = kdb_domid2syminfop(domid);
  29.306 +
  29.307 +    KDBGP("sym2a: sym:%s domid:%x numsyms:%ld\n", symp, domid,
  29.308 +          gp->kallsyms_num_syms);
  29.309 +
  29.310 +    if (gp->toktbl == 0 || gp->tokidxtbl == 0)
  29.311 +        return(kdb_expand_el4_sym(gp, gp->kallsyms_num_syms, namebuf, symp));
  29.312 +
  29.313 +    for (i=0; i < gp->kallsyms_num_syms; i++) {
  29.314 +        off = kdb_expand_el5_sym(gp, off, namebuf);
  29.315 +        KDBGP1("i:%d namebuf:%s\n", i, namebuf);
  29.316 +        if (strcmp(namebuf, symp) == 0) {
  29.317 +            return(kdb_rd_guest_addrtbl(gp, i));
  29.318 +        }
  29.319 +    }
  29.320 +    KDBGP("sym2a:exit:na-ga-da\n");
  29.321 +    return 0;
  29.322 +}
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/xen/kdb/include/kdbdefs.h	Thu Feb 03 15:42:41 2011 -0800
    30.3 @@ -0,0 +1,90 @@
    30.4 +/*
    30.5 + * Copyright (C) 2009, Mukesh Rathor, Oracle Corp.  All rights reserved.
    30.6 + *
    30.7 + * This program is free software; you can redistribute it and/or
    30.8 + * modify it under the terms of the GNU General Public
    30.9 + * License v2 as published by the Free Software Foundation.
   30.10 + *
   30.11 + * This program is distributed in the hope that it will be useful,
   30.12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   30.13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   30.14 + * General Public License for more details.
   30.15 + *
   30.16 + * You should have received a copy of the GNU General Public
   30.17 + * License along with this program; if not, write to the
   30.18 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   30.19 + * Boston, MA 021110-1307, USA.
   30.20 + */
   30.21 +
   30.22 +#ifndef _KDBDEFS_H
   30.23 +#define _KDBDEFS_H
   30.24 +
   30.25 +/* reason we are entering kdbmain (bp == breakpoint) */
   30.26 +typedef enum {
   30.27 +    KDB_REASON_KEYBOARD=1,  /* Keyboard entry - always 1 */
   30.28 +    KDB_REASON_BPEXCP,      /* #BP excp: sw bp (INT3) */
   30.29 +    KDB_REASON_DBEXCP,      /* #DB excp: TF flag or HW bp */
   30.30 +    KDB_REASON_PAUSE_IPI,   /* received pause IPI from another CPU */
   30.31 +} kdb_reason_t;
   30.32 +
   30.33 +
   30.34 +/* cpu state: past, present, and future */
   30.35 +typedef enum {
   30.36 +    KDB_CPU_INVAL=0,     /* invalid value. not in or leaving kdb */
   30.37 +    KDB_CPU_QUIT,        /* main cpu does GO. all others do QUIT */
   30.38 +    KDB_CPU_PAUSE,       /* cpu is paused */
   30.39 +    KDB_CPU_DISABLE,     /* disable interrupts */
   30.40 +    KDB_CPU_SHOWPC,      /* all cpus must display their pc */
   30.41 +    KDB_CPU_DO_VMEXIT,   /* all cpus must do vmcs vmexit. intel only */
   30.42 +    KDB_CPU_MAIN_KDB,    /* cpu in kdb main command loop */
   30.43 +    KDB_CPU_GO,          /* user entered go for this cpu */
   30.44 +    KDB_CPU_SS,          /* single step for this cpu */
   30.45 +    KDB_CPU_NI,          /* go to next instr after the call instr */
   30.46 +    KDB_CPU_INSTALL_BP,  /* delayed install of sw bp(s) by this cpu */
   30.47 +} kdb_cpu_cmd_t;
   30.48 +
   30.49 +/* ============= kdb commands ============================================= */
   30.50 +
   30.51 +typedef kdb_cpu_cmd_t (*kdb_func_t)(int, const char **, struct cpu_user_regs *);
   30.52 +typedef kdb_cpu_cmd_t (*kdb_usgf_t)(void);
   30.53 +
   30.54 +typedef enum {
   30.55 +    KDB_REPEAT_NONE = 0,    /* Do not repeat this command */
   30.56 +    KDB_REPEAT_NO_ARGS,     /* Repeat the command without arguments */
   30.57 +    KDB_REPEAT_WITH_ARGS,   /* Repeat the command including its arguments */
   30.58 +} kdb_repeat_t;
   30.59 +
   30.60 +typedef struct _kdbtab {
   30.61 +    char        *kdb_cmd_name;        /* Command name */
   30.62 +    kdb_func_t   kdb_cmd_func;        /* ptr to function to execute command */
   30.63 +    kdb_usgf_t   kdb_cmd_usgf;        /* usage function ptr */
   30.64 +    int          kdb_cmd_crash_avail; /* available in sys fatal/crash state */
   30.65 +    kdb_repeat_t kdb_cmd_repeat;      /* Does command auto repeat on enter? */
   30.66 +} kdbtab_t;
   30.67 +
   30.68 +
   30.69 +/* ============= types and stuff ========================================= */
   30.70 +#define BFD_INVAL (~0UL)            /* invalid bfd_vma */
   30.71 +
   30.72 +#if defined(__x86_64__)
   30.73 +  #define KDBIP rip
   30.74 +  #define KDBSP rsp
   30.75 +#else
   30.76 +  #define KDBIP eip
   30.77 +  #define KDBSP esp
   30.78 +#endif
   30.79 +
   30.80 +typedef unsigned long kdbva_t;
   30.81 +typedef unsigned char kdbbyt_t;
   30.82 +typedef unsigned long kdbma_t;
   30.83 +
   30.84 +/* ============= macros ================================================== */
   30.85 +extern volatile int kdbdbg;
   30.86 +#define KDBGP(...) {(kdbdbg) ? kdbp(__VA_ARGS__):0;}
   30.87 +#define KDBGP1(...) {(kdbdbg>1) ? kdbp(__VA_ARGS__):0;}
   30.88 +#define KDBGP2(...) {(kdbdbg>2) ? kdbp(__VA_ARGS__):0;}
   30.89 +#define KDBGP3(...) {0;};
   30.90 +
   30.91 +#define KDBMIN(x,y) (((x)<(y))?(x):(y))
   30.92 +
   30.93 +#endif  /* !_KDBDEFS_H */
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/xen/kdb/include/kdbinc.h	Thu Feb 03 15:42:41 2011 -0800
    31.3 @@ -0,0 +1,65 @@
    31.4 +/*
    31.5 + * Copyright (C) 2009, Mukesh Rathor, Oracle Corp.  All rights reserved.
    31.6 + *
    31.7 + * This program is free software; you can redistribute it and/or
    31.8 + * modify it under the terms of the GNU General Public
    31.9 + * License v2 as published by the Free Software Foundation.
   31.10 + *
   31.11 + * This program is distributed in the hope that it will be useful,
   31.12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   31.13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   31.14 + * General Public License for more details.
   31.15 + *
   31.16 + * You should have received a copy of the GNU General Public
   31.17 + * License along with this program; if not, write to the
   31.18 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   31.19 + * Boston, MA 021110-1307, USA.
   31.20 + */
   31.21 +
   31.22 +#ifndef _KDBINC_H
   31.23 +#define _KDBINC_H
   31.24 +
   31.25 +#include <xen/compile.h>
   31.26 +#include <xen/config.h>
   31.27 +#include <xen/version.h>
   31.28 +#include <xen/compat.h>
   31.29 +#include <xen/init.h>
   31.30 +#include <xen/lib.h>
   31.31 +#include <xen/errno.h>
   31.32 +#include <xen/sched.h>
   31.33 +#include <xen/domain.h>
   31.34 +#include <xen/mm.h>
   31.35 +#include <xen/event.h>
   31.36 +#include <xen/time.h>
   31.37 +#include <xen/console.h>
   31.38 +#include <xen/softirq.h>
   31.39 +#include <xen/domain_page.h>
   31.40 +#include <xen/rangeset.h>
   31.41 +#include <xen/guest_access.h>
   31.42 +#include <xen/hypercall.h>
   31.43 +#include <xen/delay.h>
   31.44 +#include <xen/shutdown.h>
   31.45 +#include <xen/percpu.h>
   31.46 +#include <xen/multicall.h>
   31.47 +#include <xen/rcupdate.h>
   31.48 +#include <xen/ctype.h>
   31.49 +#include <xen/symbols.h>
   31.50 +#include <xen/shutdown.h>
   31.51 +#include <xen/serial.h>
   31.52 +#include <asm/debugger.h>
   31.53 +#include <asm/shared.h>
   31.54 +#include <asm/apicdef.h>
   31.55 +
   31.56 +#include <asm/nmi.h>
   31.57 +#include <asm/p2m.h>
   31.58 +#include <public/sched.h>
   31.59 +#include <public/vcpu.h>
   31.60 +#ifdef _XEN_LATEST
   31.61 +#include <xsm/xsm.h>
   31.62 +#endif
   31.63 +
   31.64 +
   31.65 +#include "kdbdefs.h"
   31.66 +#include "kdbproto.h"
   31.67 +
   31.68 +#endif /* !_KDBINC_H */
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/xen/kdb/include/kdbproto.h	Thu Feb 03 15:42:41 2011 -0800
    32.3 @@ -0,0 +1,83 @@
    32.4 +/*
    32.5 + * Copyright (C) 2009, Mukesh Rathor, Oracle Corp.  All rights reserved.
    32.6 + *
    32.7 + * This program is free software; you can redistribute it and/or
    32.8 + * modify it under the terms of the GNU General Public
    32.9 + * License v2 as published by the Free Software Foundation.
   32.10 + *
   32.11 + * This program is distributed in the hope that it will be useful,
   32.12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   32.13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   32.14 + * General Public License for more details.
   32.15 + *
   32.16 + * You should have received a copy of the GNU General Public
   32.17 + * License along with this program; if not, write to the
   32.18 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   32.19 + * Boston, MA 021110-1307, USA.
   32.20 + */
   32.21 +
   32.22 +#ifndef _KDBPROTO_H
   32.23 +#define _KDBPROTO_H
   32.24 +
   32.25 +/* hypervisor interfaces use by kdb or kdb interfaces in xen files */
   32.26 +extern void console_putc(char);
   32.27 +extern int console_getc(void);
   32.28 +extern void show_trace(struct cpu_user_regs *);
   32.29 +extern void kdb_dump_timer_queues(void);
   32.30 +extern void kdb_time_resume(int);
   32.31 +extern void kdb_print_sched_info(void);
   32.32 +extern void kdb_curr_cpu_flush_vmcs(void);
   32.33 +extern void kdb_dump_vmcs(domid_t, int);
   32.34 +extern void kdb_dump_vmcb(domid_t, int);
   32.35 +extern unsigned long address_lookup(char *);
   32.36 +extern void kdb_prnt_guest_mapped_irqs(void);
   32.37 +
   32.38 +/* kdb globals */
   32.39 +extern kdbtab_t *kdb_cmd_tbl;
   32.40 +extern char kdb_prompt[32];
   32.41 +extern volatile int kdb_sys_crash;
   32.42 +extern volatile kdb_cpu_cmd_t kdb_cpu_cmd[NR_CPUS];
   32.43 +extern volatile int kdb_trcon;
   32.44 +
   32.45 +/* kdb interfaces */
   32.46 +extern void __init kdb_io_init(void);
   32.47 +extern void kdb_init_cmdtab(void);
   32.48 +extern void kdb_do_cmds(struct cpu_user_regs *);
   32.49 +extern int kdb_check_sw_bkpts(struct cpu_user_regs *);
   32.50 +extern int kdb_check_watchpoints(struct cpu_user_regs *);
   32.51 +extern void kdb_do_watchpoints(kdbva_t, int, int);
   32.52 +extern void kdb_install_watchpoints(void);
   32.53 +extern void kdb_clear_wps(int);
   32.54 +extern kdbma_t kdb_rd_dbgreg(int);
   32.55 +
   32.56 +
   32.57 +
   32.58 +extern char *kdb_get_cmdline(char *);
   32.59 +extern void kdb_clear_prev_cmd(void);
   32.60 +extern void kdb_toggle_dis_syntax(void);
   32.61 +extern int kdb_check_call_instr(domid_t, kdbva_t);
   32.62 +extern void kdb_display_pc(struct cpu_user_regs *);
   32.63 +extern kdbva_t kdb_print_instr(kdbva_t, long, domid_t);
   32.64 +extern int kdb_read_mmem(kdbva_t, kdbbyt_t *, int);
   32.65 +extern int kdb_read_mem(kdbva_t, kdbbyt_t *, int, domid_t);
   32.66 +extern int kdb_write_mem(kdbva_t, kdbbyt_t *, int, domid_t);
   32.67 +
   32.68 +extern void kdb_install_all_swbp(void);
   32.69 +extern void kdb_uninstall_all_swbp(void);
   32.70 +extern int kdb_swbp_exists(void);
   32.71 +extern void kdb_flush_swbp_table(void);
   32.72 +extern int kdb_is_addr_guest_text(kdbva_t, int);
   32.73 +extern kdbva_t kdb_guest_sym2addr(char *, domid_t);
   32.74 +extern char *kdb_guest_addr2sym(unsigned long, domid_t, ulong *);
   32.75 +extern void kdb_prnt_addr2sym(domid_t, kdbva_t, char *);
   32.76 +extern void kdb_sav_dom_syminfo(domid_t, long, long, long, long, long);
   32.77 +extern int kdb_guest_bitness(domid_t);
   32.78 +extern int dbg_rw_mem(kdbva_t, kdbbyt_t *, int, domid_t, int, uint64_t);
   32.79 +extern void kdb_nmi_pause_cpus(cpumask_t);
   32.80 +
   32.81 +extern void kdb_trczero(void);
   32.82 +void kdb_trcp(void);
   32.83 +
   32.84 +
   32.85 +
   32.86 +#endif /* !_KDBPROTO_H */
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/xen/kdb/kdb_cmds.c	Thu Feb 03 15:42:41 2011 -0800
    33.3 @@ -0,0 +1,3526 @@
    33.4 +/*
    33.5 + * Copyright (C) 2009, Mukesh Rathor, Oracle Corp.  All rights reserved.
    33.6 + *
    33.7 + * This program is free software; you can redistribute it and/or
    33.8 + * modify it under the terms of the GNU General Public
    33.9 + * License v2 as published by the Free Software Foundation.
   33.10 + *
   33.11 + * This program is distributed in the hope that it will be useful,
   33.12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   33.13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   33.14 + * General Public License for more details.
   33.15 + *
   33.16 + * You should have received a copy of the GNU General Public
   33.17 + * License along with this program; if not, write to the
   33.18 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   33.19 + * Boston, MA 021110-1307, USA.
   33.20 + */
   33.21 +
   33.22 +#include "include/kdbinc.h"
   33.23 +
   33.24 +#if defined(__x86_64__)
   33.25 +    #define KDBF64 "%lx"
   33.26 +    #define KDBFL "%016lx"         /* print long all digits */
   33.27 +#else
   33.28 +    #define KDBF64 "%llx"
   33.29 +    #define KDBFL "%08lx"
   33.30 +#endif
   33.31 +
   33.32 +#if XEN_SUBVERSION > 4 || XEN_VERSION == 4              /* xen 3.5.x or above */
   33.33 +    #define KDB_LKDEF(l) ((l).raw.lock)
   33.34 +    #define KDB_PGLLE(t) ((t).tail)    /* page list last element ^%$#@ */
   33.35 +#else
   33.36 +    #define KDB_LKDEF(l) ((l).lock)
   33.37 +    #define KDB_PGLLE(t) ((t).prev)    /* page list last element ^%$#@ */
   33.38 +#endif
   33.39 +
   33.40 +#define KDB_CMD_HISTORY_COUNT   32
   33.41 +#define CMD_BUFLEN              200     /* kdb_printf: max printline == 256 */
   33.42 +
   33.43 +#define KDBMAXSBP 16                    /* max number of software breakpoints */
   33.44 +#define KDB_MAXARGC 16                  /* max args in a kdb command */
   33.45 +#define KDB_MAXBTP  8                   /* max display args in btp */
   33.46 +
   33.47 +/* condition is: 'r6 == 0x123f' or '0xffffffff82800000 != deadbeef'  */
   33.48 +struct kdb_bpcond {
   33.49 +    kdbbyt_t bp_cond_status;       /* 0 == off, 1 == register, 2 == memory */
   33.50 +    kdbbyt_t bp_cond_type;         /* 0 == bad, 1 == equal, 2 == not equal */
   33.51 +    ulong    bp_cond_lhs;          /* lhs of condition: reg offset or mem loc */
   33.52 +    ulong    bp_cond_rhs;          /* right hand side of condition */
   33.53 +};
   33.54 +
   33.55 +/* software breakpoint structure */
   33.56 +struct kdb_sbrkpt {
   33.57 +    kdbva_t  bp_addr;              /* address the bp is set at */
   33.58 +    domid_t  bp_domid;             /* which domain the bp belongs to */
   33.59 +    kdbbyt_t bp_originst;          /* save orig instr/s here */
   33.60 +    kdbbyt_t bp_deleted;           /* delete pending on this bp */
   33.61 +    kdbbyt_t bp_ni;                /* set for KDB_CPU_NI */
   33.62 +    kdbbyt_t bp_just_added;        /* added in the current kdb session */
   33.63 +    kdbbyt_t bp_type;              /* 0 = normal, 1 == cond,  2 == btp */
   33.64 +    union {
   33.65 +        struct kdb_bpcond bp_cond;
   33.66 +        ulong *bp_btp;
   33.67 +    } u;
   33.68 +};
   33.69 +
   33.70 +/* don't use kmalloc in kdb which hijacks all cpus */
   33.71 +static ulong kdb_btp_argsa[KDBMAXSBP][KDB_MAXBTP];
   33.72 +static ulong *kdb_btp_ap[KDBMAXSBP];
   33.73 +
   33.74 +static struct kdb_reg_nmofs {
   33.75 +    char *reg_nm;
   33.76 +    int reg_offs;
   33.77 +} kdb_reg_nm_offs[] =  {
   33.78 +       { "rax", offsetof(struct cpu_user_regs, rax) },
   33.79 +       { "rbx", offsetof(struct cpu_user_regs, rbx) },
   33.80 +       { "rcx", offsetof(struct cpu_user_regs, rcx) },
   33.81 +       { "rdx", offsetof(struct cpu_user_regs, rdx) },
   33.82 +       { "rsi", offsetof(struct cpu_user_regs, rsi) },
   33.83 +       { "rdi", offsetof(struct cpu_user_regs, rdi) },
   33.84 +       { "rbp", offsetof(struct cpu_user_regs, rbp) },
   33.85 +       { "rsp", offsetof(struct cpu_user_regs, rsp) },
   33.86 +       { "r8",  offsetof(struct cpu_user_regs, r8) },
   33.87 +       { "r9",  offsetof(struct cpu_user_regs, r9) },
   33.88 +       { "r10", offsetof(struct cpu_user_regs, r10) },
   33.89 +       { "r11", offsetof(struct cpu_user_regs, r11) },
   33.90 +       { "r12", offsetof(struct cpu_user_regs, r12) },
   33.91 +       { "r13", offsetof(struct cpu_user_regs, r13) },
   33.92 +       { "r14", offsetof(struct cpu_user_regs, r14) },
   33.93 +       { "r15", offsetof(struct cpu_user_regs, r15) },
   33.94 +       { "rflags", offsetof(struct cpu_user_regs, rflags) } };
   33.95 +
   33.96 +static const int KDBBPSZ=1;                   /* size of KDB_BPINST is 1 byte*/
   33.97 +static kdbbyt_t kdb_bpinst = 0xcc;            /* breakpoint instr: INT3 */
   33.98 +static struct kdb_sbrkpt kdb_sbpa[KDBMAXSBP]; /* soft brkpt array/table */
   33.99 +static kdbtab_t *tbp;
  33.100 +
  33.101 +static int kdb_set_bp(domid_t, kdbva_t, int, ulong *, char*, char*, char*);
  33.102 +static void kdb_print_uregs(struct cpu_user_regs *);
  33.103 +
  33.104 +
  33.105 +/* ===================== cmdline functions  ================================ */
  33.106 +
  33.107 +/* lp points to a string of only alpha numeric chars terminated by '\n'.
  33.108 + * Parse the string into argv pointers, and RETURN argc
  33.109 + * Eg:  if lp --> "dr  sp\n" :  argv[0]=="dr\0"  argv[1]=="sp\0"  argc==2
  33.110 + */
  33.111 +static int
  33.112 +kdb_parse_cmdline(char *lp, const char **argv)
  33.113 +{
  33.114 +    int i=0;
  33.115 +
  33.116 +    for (; *lp == ' '; lp++);      /* note: isspace() skips '\n' also */
  33.117 +    while ( *lp != '\n' ) {
  33.118 +        if (i == KDB_MAXARGC) {
  33.119 +            printk("kdb: max args exceeded\n");
  33.120 +            break;
  33.121 +        }
  33.122 +        argv[i++] = lp;
  33.123 +        for (; *lp != ' ' && *lp != '\n'; lp++);
  33.124 +        if (*lp != '\n')
  33.125 +            *lp++ = '\0';
  33.126 +        for (; *lp == ' '; lp++);
  33.127 +    }
  33.128 +    *lp = '\0';
  33.129 +    return i;
  33.130 +}
  33.131 +
  33.132 +void
  33.133 +kdb_clear_prev_cmd()             /* so previous command is not repeated */
  33.134 +{
  33.135 +    tbp = NULL;
  33.136 +}
  33.137 +
  33.138 +void
  33.139 +kdb_do_cmds(struct cpu_user_regs *regs)
  33.140 +{
  33.141 +    char *cmdlinep;
  33.142 +    const char *argv[KDB_MAXARGC];
  33.143 +    int argc = 0, curcpu = smp_processor_id();
  33.144 +    kdb_cpu_cmd_t result = KDB_CPU_MAIN_KDB;
  33.145 +
  33.146 +    snprintf(kdb_prompt, sizeof(kdb_prompt), "[%d]xkdb> ", curcpu);
  33.147 +
  33.148 +    while (result == KDB_CPU_MAIN_KDB) {
  33.149 +        cmdlinep = kdb_get_cmdline(kdb_prompt);
  33.150 +        if (*cmdlinep == '\n') {
  33.151 +            if (tbp==NULL || tbp->kdb_cmd_func==NULL)
  33.152 +                continue;
  33.153 +            else
  33.154 +                argc = -1;    /* repeat prev command */
  33.155 +        } else {
  33.156 +            argc = kdb_parse_cmdline(cmdlinep, argv);
  33.157 +            for(tbp=kdb_cmd_tbl; tbp->kdb_cmd_func; tbp++)  {
  33.158 +                if (strcmp(argv[0], tbp->kdb_cmd_name)==0) 
  33.159 +                    break;
  33.160 +            }
  33.161 +        }
  33.162 +        if (kdb_sys_crash && tbp->kdb_cmd_func && !tbp->kdb_cmd_crash_avail) {
  33.163 +            kdbp("cmd not available in fatal/crashed state....\n");
  33.164 +            continue;
  33.165 +        }
  33.166 +        if (tbp->kdb_cmd_func) {
  33.167 +            result = (*tbp->kdb_cmd_func)(argc, argv, regs);
  33.168 +            if (tbp->kdb_cmd_repeat == KDB_REPEAT_NONE)
  33.169 +                tbp = NULL;
  33.170 +        } else
  33.171 +            kdbp("kdb: Unknown cmd: %s\n", cmdlinep);
  33.172 +    }
  33.173 +    kdb_cpu_cmd[curcpu] = result;
  33.174 +    return;
  33.175 +}
  33.176 +
  33.177 +/* ===================== Util functions  ==================================== */
  33.178 +
  33.179 +static int
  33.180 +kdb_vcpu_valid(struct vcpu *in_vp)
  33.181 +{
  33.182 +    struct domain *dp;
  33.183 +    struct vcpu *vp;
  33.184 +
  33.185 +    for(dp=domain_list; in_vp && dp; dp=dp->next_in_list)
  33.186 +        for_each_vcpu(dp, vp)
  33.187 +            if (in_vp == vp)
  33.188 +                return 1;
  33.189 +    return 0;     /* not found */
  33.190 +}
  33.191 +
  33.192 +/*
  33.193 + * Given a symbol, find it's address
  33.194 + */
  33.195 +static kdbva_t
  33.196 +kdb_sym2addr(const char *p, domid_t domid)
  33.197 +{
  33.198 +    kdbva_t addr;
  33.199 +
  33.200 +    KDBGP1("sym2addr: p:%s domid:%d\n", p, domid);
  33.201 +    if (domid == DOMID_IDLE)
  33.202 +        addr = address_lookup((char *)p);
  33.203 +    else
  33.204 +        addr = (kdbva_t)kdb_guest_sym2addr((char *)p, domid);
  33.205 +    KDBGP1("sym2addr: exit: addr returned:0x%lx\n", addr);
  33.206 +    return addr;
  33.207 +}
  33.208 +
  33.209 +/*
  33.210 + * convert ascii to int decimal (base 10). 
  33.211 + * Return: 0 : failed to convert, otherwise 1 
  33.212 + */
  33.213 +static int
  33.214 +kdb_str2deci(const char *strp, int *intp)
  33.215 +{
  33.216 +    const char *endp;
  33.217 +
  33.218 +    KDBGP2("str2deci: str:%s\n", strp);
  33.219 +    if (!isdigit(*strp))
  33.220 +        return 0;
  33.221 +    *intp = (int)simple_strtoul(strp, &endp, 10);
  33.222 +    if (endp != strp+strlen(strp))
  33.223 +        return 0;
  33.224 +    KDBGP2("str2deci: intval:$%d\n", *intp);
  33.225 +    return 1;
  33.226 +}
  33.227 +/*
  33.228 + * convert ascii to long. NOTE: base is 16
  33.229 + * Return: 0 : failed to convert, otherwise 1 
  33.230 + */
  33.231 +static int
  33.232 +kdb_str2ulong(const char *strp, ulong *longp)
  33.233 +{
  33.234 +    ulong val;
  33.235 +    const char *endp;
  33.236 +
  33.237 +    KDBGP2("str2long: str:%s\n", strp);
  33.238 +    if (!isxdigit(*strp))
  33.239 +        return 0;
  33.240 +    val = (long)simple_strtoul(strp, &endp, 16);   /* handles leading 0x */
  33.241 +    if (endp != strp+strlen(strp))
  33.242 +        return 0;
  33.243 +    if (longp)
  33.244 +        *longp = val;
  33.245 +    KDBGP2("str2long: val:0x%lx\n", val);
  33.246 +    return 1;
  33.247 +}
  33.248 +/*
  33.249 + * convert a symbol or ascii address to hex address
  33.250 + * Return: 0 : failed to convert, otherwise 1 
  33.251 + */
  33.252 +static int
  33.253 +kdb_str2addr(const char *strp, kdbva_t *addrp, domid_t id)
  33.254 +{
  33.255 +    kdbva_t addr;
  33.256 +    const char *endp;
  33.257 +
  33.258 +    /* assume it's an address */
  33.259 +    KDBGP2("str2addr: str:%s id:%d\n", strp, id);
  33.260 +    addr = (kdbva_t)simple_strtoul(strp, &endp, 16); /*handles leading 0x */
  33.261 +    if (endp != strp+strlen(strp))
  33.262 +        if ( !(addr=kdb_sym2addr(strp, id)) )
  33.263 +            return 0;
  33.264 +    *addrp = addr;
  33.265 +    KDBGP2("str2addr: addr:0x%lx\n", addr);
  33.266 +    return 1;
  33.267 +}
  33.268 +
  33.269 +/* Given domid, return ptr to struct domain 
  33.270 + * IF domid == DOMID_IDLE return ptr to idle_domain 
  33.271 + * IF domid == valid domain, return ptr to domain struct
  33.272 + * else domid is bad and return NULL
  33.273 + */
  33.274 +static struct domain *
  33.275 +kdb_domid2ptr(domid_t domid)
  33.276 +{
  33.277 +    struct domain *dp;
  33.278 +
  33.279 +    /* get_domain_by_id() ret NULL for both DOMID_IDLE and bad domids */
  33.280 +    if (domid == DOMID_IDLE)
  33.281 +        dp = idle_vcpu[smp_processor_id()]->domain;
  33.282 +    else 
  33.283 +        dp = get_domain_by_id(domid);   /* NULL now means bad domid */
  33.284 +    return dp;
  33.285 +}
  33.286 +
  33.287 +/*
  33.288 + * Returns:  0: failed. invalid domid or string, *idp not changed.
  33.289 + */
  33.290 +static int
  33.291 +kdb_str2domid(const char *domstr, domid_t *idp, int perr)
  33.292 +{
  33.293 +    int id;
  33.294 +    if (!kdb_str2deci(domstr, &id) || !kdb_domid2ptr((domid_t)id)) {
  33.295 +        if (perr)
  33.296 +            kdbp("Invalid domid:%s\n", domstr);
  33.297 +        return 0;
  33.298 +    }
  33.299 +    *idp = (domid_t)id;
  33.300 +    return 1;
  33.301 +}
  33.302 +
  33.303 +static struct domain *
  33.304 +kdb_strdomid2ptr(const char *domstr)
  33.305 +{
  33.306 +    ulong l;
  33.307 +    struct domain *dp;
  33.308 +    if (!kdb_str2ulong(domstr, &l) || !(dp=kdb_domid2ptr((domid_t)l))) {
  33.309 +        kdbp("Invalid domid:%s\n", domstr);
  33.310 +        return NULL;
  33.311 +    } else
  33.312 +        return dp;
  33.313 +}
  33.314 +
  33.315 +/* return a guest bitness: 32 or 64 */
  33.316 +int
  33.317 +kdb_guest_bitness(domid_t domid)
  33.318 +{
  33.319 +    const int HYPSZ = sizeof(long) * 8;
  33.320 +    struct domain *dp = kdb_domid2ptr(domid);
  33.321 +    int retval; 
  33.322 +
  33.323 +    if (is_idle_domain(dp))
  33.324 +        retval = HYPSZ;
  33.325 +    else if (is_hvm_domain(dp))
  33.326 +        retval = (hvm_long_mode_enabled(dp->vcpu[0])) ? HYPSZ : 32;
  33.327 +    else 
  33.328 +        retval = is_pv_32bit_domain(dp) ? 32 : HYPSZ;
  33.329 +    KDBGP1("gbitness: domid:%d dp:%p bitness:%d\n", domid, dp, retval);
  33.330 +    return retval;
  33.331 +}
  33.332 +
  33.333 +/* kdb_print_spin_lock(&xyz_lock, "xyz_lock:", "\n"); */
  33.334 +static void
  33.335 +kdb_print_spin_lock(char *strp, spinlock_t *lkp, char *nlp)
  33.336 +{
  33.337 +    kdbp("%s %04hx %d %d%s", strp, KDB_LKDEF(*lkp), lkp->recurse_cpu,
  33.338 +         lkp->recurse_cnt, nlp);
  33.339 +}
  33.340 +
  33.341 +/* check if register string is valid. if yes, return offset to the register
  33.342 + * in cpu_user_regs, else return -1 */
  33.343 +static int
  33.344 +kdb_valid_reg(const char *nmp) 
  33.345 +{
  33.346 +    int i;
  33.347 +    for (i=0; i < sizeof(kdb_reg_nm_offs)/sizeof(kdb_reg_nm_offs[0]); i++)
  33.348 +        if (strcmp(kdb_reg_nm_offs[i].reg_nm, nmp) == 0)
  33.349 +            return kdb_reg_nm_offs[i].reg_offs;
  33.350 +    return -1;
  33.351 +}
  33.352 +
  33.353 +/* given offset of register, return register name string. if offset is invalid
  33.354 + * return NULL */
  33.355 +static char *kdb_regoffs_to_name(int offs)
  33.356 +{
  33.357 +    int i;
  33.358 +    for (i=0; i < sizeof(kdb_reg_nm_offs)/sizeof(kdb_reg_nm_offs[0]); i++)
  33.359 +        if (kdb_reg_nm_offs[i].reg_offs == offs)
  33.360 +            return kdb_reg_nm_offs[i].reg_nm;
  33.361 +    return NULL;
  33.362 +}
  33.363 +
  33.364 +/* ===================== util struct funcs ================================= */
  33.365 +static void
  33.366 +kdb_prnt_timer(struct timer *tp)
  33.367 +{
  33.368 +#if XEN_SUBVERSION == 0 
  33.369 +    kdbp(" expires:%016lx expires_end:%016lx cpu:%d status:%x\n", tp->expires, 
  33.370 +         tp->expires_end, tp->cpu, tp->status);
  33.371 +#else
  33.372 +    kdbp(" expires:%016lx cpu:%d status:%x\n", tp->expires, tp->cpu,tp->status);
  33.373 +#endif
  33.374 +    kdbp(" function data:%p ptr:%p ", tp->data, tp->function);
  33.375 +    kdb_prnt_addr2sym(DOMID_IDLE, (kdbva_t)tp->function, "\n");
  33.376 +}
  33.377 +
  33.378 +static void 
  33.379 +kdb_prnt_periodic_time(struct periodic_time *ptp)
  33.380 +{
  33.381 +    kdbp(" next:%p prev:%p\n", ptp->list.next, ptp->list.prev);
  33.382 +    kdbp(" on_list:%d one_shot:%d dont_freeze:%d irq_issued:%d src:%x irq:%x\n",
  33.383 +         ptp->on_list, ptp->one_shot, ptp->do_not_freeze, ptp->irq_issued,
  33.384 +         ptp->source, ptp->irq);
  33.385 +    kdbp(" vcpu:%p pending_intr_nr:%08x period:%016lx\n", ptp->vcpu,
  33.386 +         ptp->pending_intr_nr, ptp->period);
  33.387 +    kdbp(" scheduled:%016lx last_plt_gtime:%016lx\n", ptp->scheduled,
  33.388 +         ptp->last_plt_gtime);
  33.389 +    kdbp(" \n          timer info:\n");
  33.390 +    kdb_prnt_timer(&ptp->timer);
  33.391 +    kdbp("\n");
  33.392 +}
  33.393 +
  33.394 +/* ===================== cmd functions  ==================================== */
  33.395 +
  33.396 +/*
  33.397 + * FUNCTION: Disassemble instructions
  33.398 + */
  33.399 +static kdb_cpu_cmd_t
  33.400 +kdb_usgf_dis(void)
  33.401 +{
  33.402 +    kdbp("dis [addr|sym][num][domid] : Disassemble instrs\n");
  33.403 +    return KDB_CPU_MAIN_KDB;
  33.404 +}
  33.405 +static kdb_cpu_cmd_t 
  33.406 +kdb_cmdf_dis(int argc, const char **argv, struct cpu_user_regs *regs)
  33.407 +{
  33.408 +    int num = 8;                           /* display 8 instr by default */
  33.409 +    static kdbva_t addr = BFD_INVAL;
  33.410 +    static domid_t domid;
  33.411 +
  33.412 +    if (argc > 1 && *argv[1] == '?')
  33.413 +        return kdb_usgf_dis();
  33.414 +
  33.415 +    if (argc != -1)      /* not a command repeat */
  33.416 +        domid = guest_mode(regs) ?  current->domain->domain_id : DOMID_IDLE;
  33.417 +
  33.418 +    if (argc >= 4 && !kdb_str2domid(argv[3], &domid, 1)) { 
  33.419 +        return KDB_CPU_MAIN_KDB;
  33.420 +    } 
  33.421 +    if (argc >= 3 && !kdb_str2deci(argv[2], &num)) {
  33.422 +        kdbp("kdb:Invalid num\n");
  33.423 +        return KDB_CPU_MAIN_KDB;
  33.424 +    } 
  33.425 +    if (argc > 1 && !kdb_str2addr(argv[1], &addr, domid)) {
  33.426 +        kdbp("kdb:Invalid addr/sym\n");
  33.427 +        kdbp("(num has to be specified if providing domid)\n");
  33.428 +        return KDB_CPU_MAIN_KDB;
  33.429 +    } 
  33.430 +    if (argc == 1)                    /* not command repeat */
  33.431 +        addr = regs->KDBIP;           /* PC is the default */
  33.432 +    else if (addr == BFD_INVAL) {
  33.433 +        kdbp("kdb:Invalid addr/sym\n");
  33.434 +        return KDB_CPU_MAIN_KDB;
  33.435 +    }
  33.436 +    addr = kdb_print_instr(addr, num, domid);
  33.437 +    return KDB_CPU_MAIN_KDB;
  33.438 +}
  33.439 +
  33.440 +/* FUNCTION: kdb_cmdf_dism() Toggle disassembly syntax from Intel to ATT/GAS */
  33.441 +static kdb_cpu_cmd_t
  33.442 +kdb_usgf_dism(void)
  33.443 +{
  33.444 +    kdbp("dism: toggle disassembly mode between ATT/GAS and INTEL\n");
  33.445 +    return KDB_CPU_MAIN_KDB;
  33.446 +}
  33.447 +static kdb_cpu_cmd_t 
  33.448 +kdb_cmdf_dism(int argc, const char **argv, struct cpu_user_regs *regs)
  33.449 +{
  33.450 +    if (argc > 1 && *argv[1] == '?')
  33.451 +        return kdb_usgf_dism();
  33.452 +
  33.453 +    kdb_toggle_dis_syntax();
  33.454 +    return KDB_CPU_MAIN_KDB;
  33.455 +}
  33.456 +
  33.457 +static void
  33.458 +_kdb_show_guest_stack(domid_t domid, kdbva_t ipaddr, kdbva_t spaddr)
  33.459 +{
  33.460 +    kdbva_t val;
  33.461 +    int num=0, max=0, rd = kdb_guest_bitness(domid)/8;
  33.462 +
  33.463 +    kdb_print_instr(ipaddr, 1, domid);
  33.464 +    KDBGP("_guest_stack:sp:%lx domid:%d rd:$%d\n", spaddr, domid, rd);
  33.465 +    val = 0;                          /* must zero, in case guest is 32bit */
  33.466 +    while((kdb_read_mem(spaddr,(kdbbyt_t *)&val,rd,domid)==rd) && num < 16){
  33.467 +        KDBGP1("gstk:addr:%lx val:%lx\n", spaddr, val);
  33.468 +        if (kdb_is_addr_guest_text(val, domid)) {
  33.469 +            kdb_print_instr(val, 1, domid);
  33.470 +            num++;
  33.471 +        }
  33.472 +        if (max++ > 10000)            /* don't walk down the stack forever */
  33.473 +            break;                    /* 10k is chosen randomly */
  33.474 +        spaddr += rd;
  33.475 +    }
  33.476 +}
  33.477 +
  33.478 +/* Read guest memory and display address that looks like text. */
  33.479 +static void
  33.480 +kdb_show_guest_stack(struct cpu_user_regs *regs, struct vcpu *vcpup)
  33.481 +{
  33.482 +    kdbva_t ipaddr=regs->KDBIP, spaddr = regs->KDBSP;
  33.483 +    domid_t domid = vcpup->domain->domain_id;
  33.484 +
  33.485 +    ASSERT(domid != DOMID_IDLE);
  33.486 +    _kdb_show_guest_stack(domid, ipaddr, spaddr);
  33.487 +}
  33.488 +
  33.489 +/* display stack. if vcpu ptr given, then display stack for that. Otherwise,
  33.490 + * use current regs */
  33.491 +static kdb_cpu_cmd_t
  33.492 +kdb_usgf_f(void)
  33.493 +{
  33.494 +    kdbp("f [vcpu-ptr]: dump current/vcpu stack\n");
  33.495 +    return KDB_CPU_MAIN_KDB;
  33.496 +}
  33.497 +static kdb_cpu_cmd_t 
  33.498 +kdb_cmdf_f(int argc, const char **argv, struct cpu_user_regs *regs)
  33.499 +{
  33.500 +    if (argc > 1 && *argv[1] == '?')
  33.501 +        return kdb_usgf_f();
  33.502 +
  33.503 +    if (argc > 1 ) {
  33.504 +        struct vcpu *vp;
  33.505 +        if (!kdb_str2ulong(argv[1], (ulong *)&vp) || !kdb_vcpu_valid(vp)) {
  33.506 +            kdbp("kdb: Bad VCPU ptr:%s\n", argv[1]);
  33.507 +            return KDB_CPU_MAIN_KDB;
  33.508 +        }
  33.509 +        kdb_show_guest_stack(&vp->arch.guest_context.user_regs, vp);
  33.510 +        return KDB_CPU_MAIN_KDB;
  33.511 +    }
  33.512 +    if (guest_mode(regs))
  33.513 +        kdb_show_guest_stack(regs, current);
  33.514 +    else
  33.515 +        show_trace(regs);
  33.516 +    return KDB_CPU_MAIN_KDB;
  33.517 +}
  33.518 +
  33.519 +/* given an spaddr and domid for guest, dump stack */
  33.520 +static kdb_cpu_cmd_t
  33.521 +kdb_usgf_fg(void)
  33.522 +{
  33.523 +    kdbp("fg domid RIP ESP: dump guest stack given domid, RIP, and ESP\n");
  33.524 +    return KDB_CPU_MAIN_KDB;
  33.525 +}
  33.526 +static kdb_cpu_cmd_t 
  33.527 +kdb_cmdf_fg(int argc, const char **argv, struct cpu_user_regs *regs)
  33.528 +{
  33.529 +    domid_t domid;
  33.530 +    kdbva_t ipaddr, spaddr;
  33.531 +
  33.532 +    if (argc != 4) 
  33.533 +        return kdb_usgf_fg();
  33.534 +
  33.535 +    if (kdb_str2domid(argv[1], &domid, 1)==0) {
  33.536 +        return KDB_CPU_MAIN_KDB;
  33.537 +    }
  33.538 +    if (kdb_str2ulong(argv[2], &ipaddr)==0) {
  33.539 +        kdbp("Bad ipaddr:%s\n", argv[2]);
  33.540 +        return KDB_CPU_MAIN_KDB;
  33.541 +    }
  33.542 +    if (kdb_str2ulong(argv[3], &spaddr)==0) {
  33.543 +        kdbp("Bad spaddr:%s\n", argv[3]);
  33.544 +        return KDB_CPU_MAIN_KDB;
  33.545 +    }
  33.546 +    _kdb_show_guest_stack(domid, ipaddr, spaddr);
  33.547 +    return KDB_CPU_MAIN_KDB;
  33.548 +}
  33.549 +
  33.550 +/* Display kdb stack. for debugging kdb itself */
  33.551 +static kdb_cpu_cmd_t
  33.552 +kdb_usgf_kdbf(void)
  33.553 +{
  33.554 +    kdbp("kdbf: display kdb stack. for debugging kdb only\n");
  33.555 +    return KDB_CPU_MAIN_KDB;
  33.556 +}
  33.557 +static kdb_cpu_cmd_t 
  33.558 +kdb_cmdf_kdbf(int argc, const char **argv, struct cpu_user_regs *regs)
  33.559 +{
  33.560 +    if (argc > 1 && *argv[1] == '?')
  33.561 +        return kdb_usgf_kdbf();
  33.562 +
  33.563 +    kdb_trap_immed(KDB_TRAP_KDBSTACK);
  33.564 +    return KDB_CPU_MAIN_KDB;
  33.565 +}
  33.566 +
  33.567 +/* worker function to display memory. Request could be for any guest, domid.
  33.568 + * Also address could be machine or virtual */
  33.569 +static void
  33.570 +_kdb_display_mem(kdbva_t *addrp, int *lenp, int wordsz, int domid, int is_maddr)
  33.571 +{
  33.572 +    #define DDBUFSZ 4096
  33.573 +
  33.574 +    kdbbyt_t buf[DDBUFSZ], *bp;
  33.575 +    int numrd, bytes;
  33.576 +    int len = *lenp;
  33.577 +    kdbva_t addr = *addrp;
  33.578 +
  33.579 +    /* round len down to wordsz boundry because on intel endian, printing
  33.580 +     * characters is not prudent, (long and ints can't be interpreted 
  33.581 +     * easily) */
  33.582 +    len &= ~(wordsz-1);
  33.583 +    len = KDBMIN(DDBUFSZ, len);
  33.584 +    len = len ? len : wordsz;
  33.585 +
  33.586 +    KDBGP("dmem:addr:%lx buf:%p len:$%d domid:%d sz:$%d maddr:%d\n", addr,
  33.587 +          buf, len, domid, wordsz, is_maddr);
  33.588 +    if (is_maddr)
  33.589 +        numrd=kdb_read_mmem((kdbma_t)addr, buf, len);
  33.590 +    else
  33.591 +        numrd=kdb_read_mem(addr, buf, len, domid);
  33.592 +    if (numrd != len)
  33.593 +        kdbp("Memory read error. Bytes read:$%d\n", numrd);
  33.594 +
  33.595 +    for (bp = buf; numrd > 0;) {
  33.596 +        kdbp("%016lx: ", addr); 
  33.597 +
  33.598 +        /* display 16 bytes per line */
  33.599 +        for (bytes=0; bytes < 16 && numrd > 0; bytes += wordsz) {
  33.600 +            if (numrd >= wordsz) {
  33.601 +                if (wordsz == 8)
  33.602 +                    kdbp(" %016lx", *(long *)bp);
  33.603 +                else
  33.604 +                    kdbp(" %08x", *(int *)bp);
  33.605 +                bp += wordsz;
  33.606 +                numrd -= wordsz;
  33.607 +                addr += wordsz;
  33.608 +            }
  33.609 +        }
  33.610 +        kdbp("\n");
  33.611 +        continue;
  33.612 +    }
  33.613 +    *lenp = len;
  33.614 +    *addrp = addr;
  33.615 +}
  33.616 +
  33.617 +/* display machine mem, ie, the given address is machine address */
  33.618 +static kdb_cpu_cmd_t 
  33.619 +kdb_display_mmem(int argc, const char **argv, int wordsz, kdb_usgf_t usg_fp)
  33.620 +{
  33.621 +    static kdbma_t maddr;
  33.622 +    static int len;
  33.623 +    static domid_t id = DOMID_IDLE;
  33.624 +
  33.625 +    if (argc == -1) {
  33.626 +        _kdb_display_mem(&maddr, &len, wordsz, id, 1);  /* cmd repeat */
  33.627 +        return KDB_CPU_MAIN_KDB;
  33.628 +    }
  33.629 +    if (argc <= 1 || *argv[1] == '?')
  33.630 +        return (*usg_fp)();
  33.631 +
  33.632 +    /* check if num of bytes to display is given by user */
  33.633 +    if (argc >= 3) {
  33.634 +        if (!kdb_str2deci(argv[2], &len)) {
  33.635 +            kdbp("Invalid length:%s\n", argv[2]);
  33.636 +            return KDB_CPU_MAIN_KDB;
  33.637 +        } 
  33.638 +    } else
  33.639 +        len = 32;                                     /* default read len */
  33.640 +
  33.641 +    if (!kdb_str2ulong(argv[1], &maddr)) {
  33.642 +        kdbp("Invalid argument:%s\n", argv[1]);
  33.643 +        return KDB_CPU_MAIN_KDB;
  33.644 +    }
  33.645 +    _kdb_display_mem(&maddr, &len, wordsz, 0, 1);
  33.646 +    return KDB_CPU_MAIN_KDB;
  33.647 +}
  33.648 +
  33.649 +/* 
  33.650 + * FUNCTION: Dispaly machine Memory Word
  33.651 + */
  33.652 +static kdb_cpu_cmd_t
  33.653 +kdb_usgf_dwm(void)
  33.654 +{
  33.655 +    kdbp("dwm:  maddr|sym [num] : dump memory word given machine addr\n");
  33.656 +    return KDB_CPU_MAIN_KDB;
  33.657 +}
  33.658 +static kdb_cpu_cmd_t 
  33.659 +kdb_cmdf_dwm(int argc, const char **argv, struct cpu_user_regs *regs)
  33.660 +{
  33.661 +    return kdb_display_mmem(argc, argv, 4, kdb_usgf_dwm);
  33.662 +}
  33.663 +
  33.664 +/* 
  33.665 + * FUNCTION: Dispaly machine Memory DoubleWord 
  33.666 + */
  33.667 +static kdb_cpu_cmd_t
  33.668 +kdb_usgf_ddm(void)
  33.669 +{
  33.670 +    kdbp("ddm:  maddr|sym [num] : dump double word given machine addr\n");
  33.671 +    return KDB_CPU_MAIN_KDB;
  33.672 +}
  33.673 +static kdb_cpu_cmd_t 
  33.674 +kdb_cmdf_ddm(int argc, const char **argv, struct cpu_user_regs *regs)
  33.675 +{
  33.676 +    return kdb_display_mmem(argc, argv, 8, kdb_usgf_ddm);
  33.677 +}
  33.678 +
  33.679 +/* 
  33.680 + * FUNCTION: Dispaly Memory : word or doubleword
  33.681 + *           wordsz : bytes in word. 4 or 8
  33.682 + *
  33.683 + *           We display upto BUFSZ bytes. User can just press enter for more.
  33.684 + *           addr is always in hex with or without leading 0x
  33.685 + */
  33.686 +static kdb_cpu_cmd_t 
  33.687 +kdb_display_mem(int argc, const char **argv, int wordsz, kdb_usgf_t usg_fp)
  33.688 +{
  33.689 +    static kdbva_t addr;
  33.690 +    static int len;
  33.691 +    static domid_t id = DOMID_IDLE;
  33.692 +
  33.693 +    if (argc == -1) {
  33.694 +        _kdb_display_mem(&addr, &len, wordsz, id, 0);  /* cmd repeat */
  33.695 +        return KDB_CPU_MAIN_KDB;
  33.696 +    }
  33.697 +    if (argc <= 1 || *argv[1] == '?')
  33.698 +        return (*usg_fp)();
  33.699 +
  33.700 +    id = DOMID_IDLE;                /* not a command repeat, reset dom id */
  33.701 +    if (argc >= 4) { 
  33.702 +        if (!kdb_str2domid(argv[3], &id, 1)) 
  33.703 +            return KDB_CPU_MAIN_KDB;
  33.704 +    }
  33.705 +    /* check if num of bytes to display is given by user */
  33.706 +    if (argc >= 3) {
  33.707 +        if (!kdb_str2deci(argv[2], &len)) {
  33.708 +            kdbp("Invalid length:%s\n", argv[2]);
  33.709 +            return KDB_CPU_MAIN_KDB;
  33.710 +        } 
  33.711 +    } else
  33.712 +        len = 32;                       /* default read len */
  33.713 +    if (!kdb_str2addr(argv[1], &addr, id)) {
  33.714 +        kdbp("Invalid argument:%s\n", argv[1]);
  33.715 +        return KDB_CPU_MAIN_KDB;
  33.716 +    }
  33.717 +
  33.718 +    _kdb_display_mem(&addr, &len, wordsz, id, 0);
  33.719 +    return KDB_CPU_MAIN_KDB;
  33.720 +}
  33.721 +
  33.722 +/* 
  33.723 + * FUNCTION: Dispaly Memory Word
  33.724 + */
  33.725 +static kdb_cpu_cmd_t
  33.726 +kdb_usgf_dw(void)
  33.727 +{
  33.728 +    kdbp("dw vaddr|sym [num][domid] : dump mem word. num required for domid\n");
  33.729 +    return KDB_CPU_MAIN_KDB;
  33.730 +}
  33.731 +static kdb_cpu_cmd_t 
  33.732 +kdb_cmdf_dw(int argc, const char **argv, struct cpu_user_regs *regs)
  33.733 +{
  33.734 +    return kdb_display_mem(argc, argv, 4, kdb_usgf_dw);
  33.735 +}
  33.736 +
  33.737 +/* 
  33.738 + * FUNCTION: Dispaly Memory DoubleWord 
  33.739 + */
  33.740 +static kdb_cpu_cmd_t
  33.741 +kdb_usgf_dd(void)
  33.742 +{
  33.743 +    kdbp("dd vaddr|sym [num][domid] : dump dword. num required for domid\n");
  33.744 +    return KDB_CPU_MAIN_KDB;
  33.745 +}
  33.746 +static kdb_cpu_cmd_t 
  33.747 +kdb_cmdf_dd(int argc, const char **argv, struct cpu_user_regs *regs)
  33.748 +{
  33.749 +    return kdb_display_mem(argc, argv, 8, kdb_usgf_dd);
  33.750 +}
  33.751 +
  33.752 +/* 
  33.753 + * FUNCTION: Modify Memory Word 
  33.754 + */
  33.755 +static kdb_cpu_cmd_t
  33.756 +kdb_usgf_mw(void)
  33.757 +{
  33.758 +    kdbp("mw vaddr|sym val [domid] : modify memory word in vaddr\n");
  33.759 +    return KDB_CPU_MAIN_KDB;
  33.760 +}
  33.761 +static kdb_cpu_cmd_t 
  33.762 +kdb_cmdf_mw(int argc, const char **argv, struct cpu_user_regs *regs)
  33.763 +{
  33.764 +    ulong val;
  33.765 +    kdbva_t addr;
  33.766 +    domid_t id = DOMID_IDLE;
  33.767 +
  33.768 +    if (argc < 3) {
  33.769 +        return kdb_usgf_mw();
  33.770 +    }
  33.771 +    if (argc >=4) {
  33.772 +        if (!kdb_str2domid(argv[3], &id, 1)) 
  33.773 +            return KDB_CPU_MAIN_KDB;
  33.774 +    }
  33.775 +    if (!kdb_str2ulong(argv[2], &val)) {
  33.776 +        kdbp("Invalid val: %s\n", argv[2]);
  33.777 +        return KDB_CPU_MAIN_KDB;
  33.778 +    }
  33.779 +    if (!kdb_str2addr(argv[1], &addr, id)) {
  33.780 +        kdbp("Invalid addr/sym: %s\n", argv[1]);
  33.781 +        return KDB_CPU_MAIN_KDB;
  33.782 +    }
  33.783 +    if (kdb_write_mem(addr, (kdbbyt_t *)&val, 4, id) != 4)
  33.784 +        kdbp("Unable to set 0x%lx to 0x%lx\n", addr, val);
  33.785 +    return KDB_CPU_MAIN_KDB;
  33.786 +}
  33.787 +
  33.788 +/* 
  33.789 + * FUNCTION: Modify Memory DoubleWord 
  33.790 + */
  33.791 +static kdb_cpu_cmd_t
  33.792 +kdb_usgf_md(void)
  33.793 +{
  33.794 +    kdbp("md vaddr|sym val [domid] : modify memory dword in vaddr\n");
  33.795 +    return KDB_CPU_MAIN_KDB;
  33.796 +}
  33.797 +static kdb_cpu_cmd_t 
  33.798 +kdb_cmdf_md(int argc, const char **argv, struct cpu_user_regs *regs)
  33.799 +{
  33.800 +    ulong val;
  33.801 +    kdbva_t addr;
  33.802 +    domid_t id = DOMID_IDLE;
  33.803 +
  33.804 +    if (argc < 3) {
  33.805 +        return kdb_usgf_md();
  33.806 +    }
  33.807 +    if (argc >=4) {
  33.808 +        if (!kdb_str2domid(argv[3], &id, 1)) {
  33.809 +            return KDB_CPU_MAIN_KDB;
  33.810 +        }
  33.811 +    }
  33.812 +    if (!kdb_str2ulong(argv[2], &val)) {
  33.813 +        kdbp("Invalid val: %s\n", argv[2]);
  33.814 +        return KDB_CPU_MAIN_KDB;
  33.815 +    }
  33.816 +    if (!kdb_str2addr(argv[1], &addr, id)) {
  33.817 +        kdbp("Invalid addr/sym: %s\n", argv[1]);
  33.818 +        return KDB_CPU_MAIN_KDB;
  33.819 +    }
  33.820 +    if (kdb_write_mem(addr, (kdbbyt_t *)&val,sizeof(val),id) != sizeof(val))
  33.821 +        kdbp("Unable to set 0x%lx to 0x%lx\n", addr, val);
  33.822 +
  33.823 +    return KDB_CPU_MAIN_KDB;
  33.824 +}
  33.825 +
  33.826 +struct  Xgt_desc_struct {
  33.827 +    unsigned short size;
  33.828 +    unsigned long address __attribute__((packed));
  33.829 +};
  33.830 +
  33.831 +static void
  33.832 +kdb_show_special_regs(struct cpu_user_regs *regs)
  33.833 +{
  33.834 +    struct Xgt_desc_struct desc;
  33.835 +    unsigned short tr;                 /* Task Register segment selector */
  33.836 +    __u64 efer;
  33.837 +
  33.838 +    kdbp("\nSpecial Registers:\n");
  33.839 +    __asm__ __volatile__ ("sidt  (%0) \n" :: "a"(&desc) : "memory");
  33.840 +    kdbp("IDTR: addr: %016lx limit: %04x\n", desc.address, desc.size);
  33.841 +    __asm__ __volatile__ ("sgdt  (%0) \n" :: "a"(&desc) : "memory");
  33.842 +    kdbp("GDTR: addr: %016lx limit: %04x\n", desc.address, desc.size);
  33.843 +
  33.844 +    kdbp("cr0: %016lx  cr2: %016lx\n", read_cr0(), read_cr2());
  33.845 +    kdbp("cr3: %016lx  cr4: %016lx\n", read_cr3(), read_cr4());
  33.846 +    __asm__ __volatile__ ("str (%0) \n":: "a"(&tr) : "memory");
  33.847 +    kdbp("TR: %x\n", tr);
  33.848 +
  33.849 +    rdmsrl(MSR_EFER, efer);    /* IA32_EFER */
  33.850 +    kdbp("efer:"KDBF64" LMA(IA-32e mode):%d SCE(syscall/sysret):%d\n",
  33.851 +         efer, ((efer&EFER_LMA) != 0), ((efer&EFER_SCE) != 0));
  33.852 +
  33.853 +    kdbp("DR0: %016lx  DR1:%016lx  DR2:%016lx\n", kdb_rd_dbgreg(0),
  33.854 +         kdb_rd_dbgreg(1), kdb_rd_dbgreg(2)); 
  33.855 +    kdbp("DR3: %016lx  DR6:%016lx  DR7:%016lx\n", kdb_rd_dbgreg(3),
  33.856 +         kdb_rd_dbgreg(6), kdb_rd_dbgreg(7)); 
  33.857 +}
  33.858 +
  33.859 +/* 
  33.860 + * FUNCTION: Dispaly Registers. If "sp" argument, then display additional regs
  33.861 + */
  33.862 +static kdb_cpu_cmd_t
  33.863 +kdb_usgf_dr(void)
  33.864 +{
  33.865 +    kdbp("dr [sp]: display registers. sp to display special regs also\n");
  33.866 +    return KDB_CPU_MAIN_KDB;
  33.867 +}
  33.868 +static kdb_cpu_cmd_t 
  33.869 +kdb_cmdf_dr(int argc, const char **argv, struct cpu_user_regs *regs)
  33.870 +{
  33.871 +    if (argc > 1 && *argv[1] == '?')
  33.872 +        return kdb_usgf_dr();
  33.873 +
  33.874 +    KDBGP1("regs:%p .rsp:%lx .rip:%lx\n", regs, regs->rsp, regs->rip);
  33.875 +    show_registers(regs);
  33.876 +    if (argc > 1 && !strcmp(argv[1], "sp")) 
  33.877 +        kdb_show_special_regs(regs);
  33.878 +    return KDB_CPU_MAIN_KDB;
  33.879 +}
  33.880 +
  33.881 +/* show registers on stack bottom where guest context is. same as dr if
  33.882 + * not running in guest mode */
  33.883 +static kdb_cpu_cmd_t
  33.884 +kdb_usgf_drg(void)
  33.885 +{
  33.886 +    kdbp("drg: display active guest registers at stack bottom\n");
  33.887 +    return KDB_CPU_MAIN_KDB;
  33.888 +}
  33.889 +static kdb_cpu_cmd_t 
  33.890 +kdb_cmdf_drg(int argc, const char **argv, struct cpu_user_regs *regs)
  33.891 +{
  33.892 +    if (argc > 1 && *argv[1] == '?')
  33.893 +        return kdb_usgf_drg();
  33.894 +
  33.895 +    kdb_print_uregs(guest_cpu_user_regs());
  33.896 +    return KDB_CPU_MAIN_KDB;
  33.897 +}
  33.898 +
  33.899 +/* 
  33.900 + * FUNCTION: Modify Register
  33.901 + */
  33.902 +static kdb_cpu_cmd_t
  33.903 +kdb_usgf_mr(void)
  33.904 +{
  33.905 +    kdbp("mr reg val : Modify Register. val assumed in hex\n");
  33.906 +    return KDB_CPU_MAIN_KDB;
  33.907 +}
  33.908 +static kdb_cpu_cmd_t 
  33.909 +kdb_cmdf_mr(int argc, const char **argv, struct cpu_user_regs *regs)
  33.910 +{
  33.911 +    const char *argp;
  33.912 +    int regoffs;
  33.913 +    ulong val;
  33.914 +
  33.915 +    if (argc != 3 || !kdb_str2ulong(argv[2], &val)) {
  33.916 +        return kdb_usgf_mr();
  33.917 +    }
  33.918 +    argp = argv[1];
  33.919 +
  33.920 +#if defined(__x86_64__)
  33.921 +    if ((regoffs=kdb_valid_reg(argp)) != -1)
  33.922 +        *((uint64_t *)((char *)regs+regoffs)) = val;
  33.923 +#else
  33.924 +    if (!strcmp(argp, "eax"))
  33.925 +        regs->eax = val;
  33.926 +    else if (!strcmp(argp, "ebx"))
  33.927 +        regs->ebx = val;
  33.928 +    else if (!strcmp(argp, "ecx"))
  33.929 +        regs->ecx = val;
  33.930 +    else if (!strcmp(argp, "edx"))
  33.931 +        regs->edx = val;
  33.932 +    else if (!strcmp(argp, "esi"))
  33.933 +        regs->esi = val;
  33.934 +    else if (!strcmp(argp, "edi"))
  33.935 +        regs->edi = val;
  33.936 +    else if (!strcmp(argp, "ebp"))
  33.937 +        regs->ebp = val;
  33.938 +    else if (!strcmp(argp, "esp"))
  33.939 +        regs->esp = val;
  33.940 +    else if (!strcmp(argp, "eflags") || !strcmp(argp, "rflags"))
  33.941 +        regs->eflags = val;
  33.942 +#endif
  33.943 +    else
  33.944 +        kdbp("Error. Bad register : %s\n", argp);
  33.945 +
  33.946 +    return KDB_CPU_MAIN_KDB;
  33.947 +}
  33.948 +
  33.949 +/* 
  33.950 + * FUNCTION: Single Step
  33.951 + */
  33.952 +static kdb_cpu_cmd_t
  33.953 +kdb_usgf_ss(void)
  33.954 +{
  33.955 +    kdbp("ss: single step\n");
  33.956 +    return KDB_CPU_MAIN_KDB;
  33.957 +}
  33.958 +static kdb_cpu_cmd_t 
  33.959 +kdb_cmdf_ss(int argc, const char **argv, struct cpu_user_regs *regs)
  33.960 +{
  33.961 +    #define KDB_HALT_INSTR 0xf4
  33.962 +
  33.963 +    kdbbyt_t byte;
  33.964 +    domid_t id = guest_mode(regs) ? current->domain->domain_id : DOMID_IDLE;
  33.965 +
  33.966 +    if (argc > 1 && *argv[1] == '?')
  33.967 +        return kdb_usgf_ss();
  33.968 +
  33.969 +    KDBGP("enter kdb_cmdf_ss \n");
  33.970 +    if (!regs) {
  33.971 +        kdbp("%s: regs not available\n", __FUNCTION__);
  33.972 +        return KDB_CPU_MAIN_KDB;
  33.973 +    }
  33.974 +    if (kdb_read_mem(regs->KDBIP, &byte, 1, id) == 1) {
  33.975 +        if (byte == KDB_HALT_INSTR) {
  33.976 +            kdbp("kdb: jumping over halt instruction\n");
  33.977 +            regs->KDBIP++;
  33.978 +        }
  33.979 +    } else {
  33.980 +        kdbp("kdb: Failed to read byte at: %lx\n", regs->KDBIP);
  33.981 +        return KDB_CPU_MAIN_KDB;
  33.982 +    }
  33.983 +#if 0
  33.984 +    if (guest_mode(regs)) {
  33.985 +        kdbp("Currently not possible in guest mode\n");
  33.986 +        return KDB_CPU_MAIN_KDB;
  33.987 +    }
  33.988 +#endif
  33.989 +    regs->eflags |= X86_EFLAGS_TF;
  33.990 +    if (guest_mode(regs) && is_hvm_vcpu(current)) {
  33.991 +        struct domain *dp = current->domain;
  33.992 +        dp->debugger_attached = 1;  /* see svm_do_resume/vmx_do_ */
  33.993 +    }
  33.994 +    return KDB_CPU_SS;
  33.995 +}
  33.996 +
  33.997 +/* 
  33.998 + * FUNCTION: Next Instruction, step over the call instr to the next instr
  33.999 + */
 33.1000 +static kdb_cpu_cmd_t
 33.1001 +kdb_usgf_ni(void)
 33.1002 +{
 33.1003 +    kdbp("ni: single step, stepping over function calls\n");
 33.1004 +    return KDB_CPU_MAIN_KDB;
 33.1005 +}
 33.1006 +static kdb_cpu_cmd_t 
 33.1007 +kdb_cmdf_ni(int argc, const char **argv, struct cpu_user_regs *regs)
 33.1008 +{
 33.1009 +    int sz, i;
 33.1010 +    domid_t id=guest_mode(regs) ? current->domain->domain_id:DOMID_IDLE;
 33.1011 +
 33.1012 +    if (argc > 1 && *argv[1] == '?')
 33.1013 +        return kdb_usgf_ni();
 33.1014 +
 33.1015 +    KDBGP("enter kdb_cmdf_ni \n");
 33.1016 +    if (!regs) {
 33.1017 +        kdbp("%s: regs not available\n", __FUNCTION__);
 33.1018 +        return KDB_CPU_MAIN_KDB;
 33.1019 +    }
 33.1020 +    if ((sz=kdb_check_call_instr(id, regs->KDBIP)) == 0)  /* !call instr */
 33.1021 +        return kdb_cmdf_ss(argc, argv, regs);         /* just do ss */
 33.1022 +
 33.1023 +    if ((i=kdb_set_bp(id, regs->KDBIP+sz, 1,0,0,0,0)) >= KDBMAXSBP) /* failed */
 33.1024 +        return KDB_CPU_MAIN_KDB;
 33.1025 +
 33.1026 +    kdb_sbpa[i].bp_ni = 1;
 33.1027 +    regs->eflags &= ~X86_EFLAGS_TF;
 33.1028 +    return KDB_CPU_NI;
 33.1029 +}
 33.1030 +
 33.1031 +static void
 33.1032 +kdb_btf_enable(void)
 33.1033 +{
 33.1034 +    u64 debugctl;
 33.1035 +    rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
 33.1036 +    wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl | 0x2);
 33.1037 +}
 33.1038 +
 33.1039 +/* 
 33.1040 + * FUNCTION: Single Step to branch. Doesn't seem to work very well.
 33.1041 + */
 33.1042 +static kdb_cpu_cmd_t
 33.1043 +kdb_usgf_ssb(void)
 33.1044 +{
 33.1045 +    kdbp("ssb: singe step to branch\n");
 33.1046 +    return KDB_CPU_MAIN_KDB;
 33.1047 +}
 33.1048 +static kdb_cpu_cmd_t 
 33.1049 +kdb_cmdf_ssb(int argc, const char **argv, struct cpu_user_regs *regs)
 33.1050 +{
 33.1051 +    if (argc > 1 && *argv[1] == '?')
 33.1052 +        return kdb_usgf_ssb();
 33.1053 +
 33.1054 +    KDBGP("MUK: enter kdb_cmdf_ssb\n");
 33.1055 +    if (!regs) {
 33.1056 +        kdbp("%s: regs not available\n", __FUNCTION__);
 33.1057 +        return KDB_CPU_MAIN_KDB;
 33.1058 +    }
 33.1059 +    if (is_hvm_vcpu(current)) 
 33.1060 +        current->domain->debugger_attached = 1;        /* vmx/svm_do_resume()*/
 33.1061 +
 33.1062 +    regs->eflags |= X86_EFLAGS_TF;
 33.1063 +    kdb_btf_enable();
 33.1064 +    return KDB_CPU_SS;
 33.1065 +}
 33.1066 +
 33.1067 +/* 
 33.1068 + * FUNCTION: Continue Execution. TF must be cleared here as this could run on 
 33.1069 + *           any cpu. Hence not OK to do it from kdb_end_session.
 33.1070 + */
 33.1071 +static kdb_cpu_cmd_t
 33.1072 +kdb_usgf_go(void)
 33.1073 +{
 33.1074 +    kdbp("go: leave kdb and continue execution\n");
 33.1075 +    return KDB_CPU_MAIN_KDB;
 33.1076 +}
 33.1077 +static kdb_cpu_cmd_t 
 33.1078 +kdb_cmdf_go(int argc, const char **argv, struct cpu_user_regs *regs)
 33.1079 +{
 33.1080 +    if (argc > 1 && *argv[1] == '?')
 33.1081 +        return kdb_usgf_go();
 33.1082 +
 33.1083 +    regs->eflags &= ~X86_EFLAGS_TF;
 33.1084 +    return KDB_CPU_GO;
 33.1085 +}
 33.1086 +
 33.1087 +/* All cpus must display their current context */
 33.1088 +static kdb_cpu_cmd_t 
 33.1089 +kdb_cpu_status_all(int ccpu, struct cpu_user_regs *regs)
 33.1090 +{
 33.1091 +    int cpu;
 33.1092 +    for_each_online_cpu(cpu) {
 33.1093 +        if (cpu == ccpu) {
 33.1094 +            kdbp("[%d]", ccpu);
 33.1095 +            kdb_display_pc(regs);
 33.1096 +        } else {
 33.1097 +            if (kdb_cpu_cmd[cpu] != KDB_CPU_PAUSE)   /* hung cpu */
 33.1098 +                continue;
 33.1099 +            kdb_cpu_cmd[cpu] = KDB_CPU_SHOWPC;
 33.1100 +            while (kdb_cpu_cmd[cpu]==KDB_CPU_SHOWPC);
 33.1101 +        }
 33.1102 +    }
 33.1103 +    return KDB_CPU_MAIN_KDB;
 33.1104 +}
 33.1105 +
 33.1106 +/* 
 33.1107 + * display/switch CPU. 
 33.1108 + *  Argument:
 33.1109 + *     none:   just go back to initial cpu
 33.1110 + *     cpunum: switch to given vpu
 33.1111 + *     "all":  show one line status of all cpus
 33.1112 + */
 33.1113 +extern volatile int kdb_init_cpu;
 33.1114 +static kdb_cpu_cmd_t
 33.1115 +kdb_usgf_cpu(void)
 33.1116 +{
 33.1117 +    kdbp("cpu [all|num]: none will switch back to initial cpu\n");
 33.1118 +    kdbp("               cpunum to switch to the vcpu. all to show status\n");
 33.1119 +    return KDB_CPU_MAIN_KDB;
 33.1120 +}
 33.1121 +static kdb_cpu_cmd_t 
 33.1122 +kdb_cmdf_cpu(int argc, const char **argv, struct cpu_user_regs *regs)
 33.1123 +{
 33.1124 +    int cpu;
 33.1125 +    int ccpu = smp_processor_id();
 33.1126 +
 33.1127 +    if (argc > 1 && *argv[1] == '?')
 33.1128 +        return kdb_usgf_cpu();
 33.1129 +
 33.1130 +    if (argc > 1) {
 33.1131 +        if (!strcmp(argv[1], "all"))
 33.1132 +            return kdb_cpu_status_all(ccpu, regs);
 33.1133 +
 33.1134 +            cpu = (int)simple_strtoul(argv[1], NULL, 0); /* handles 0x */
 33.1135 +            if (cpu >= 0 && cpu < NR_CPUS && cpu != ccpu && 
 33.1136 +                cpu_online(cpu) && kdb_cpu_cmd[cpu] == KDB_CPU_PAUSE)
 33.1137 +            {
 33.1138 +                kdbp("Switching to cpu:%d\n", cpu);
 33.1139 +                kdb_cpu_cmd[cpu] = KDB_CPU_MAIN_KDB;
 33.1140 +
 33.1141 +                /* clear any single step on the current cpu */
 33.1142 +                regs->eflags &= ~X86_EFLAGS_TF;
 33.1143 +                return KDB_CPU_PAUSE;
 33.1144 +            } else {
 33.1145 +                if (cpu != ccpu)
 33.1146 +                    kdbp("Unable to switch to cpu:%d\n", cpu);
 33.1147 +                else {
 33.1148 +                    kdb_display_pc(regs);
 33.1149 +                }
 33.1150 +                return KDB_CPU_MAIN_KDB;
 33.1151 +            }
 33.1152 +    }
 33.1153 +    /* no arg means back to initial cpu */
 33.1154 +    if (!kdb_sys_crash && ccpu != kdb_init_cpu) {
 33.1155 +        if (kdb_cpu_cmd[kdb_init_cpu] == KDB_CPU_PAUSE) {
 33.1156 +            regs->eflags &= ~X86_EFLAGS_TF;
 33.1157 +            kdb_cpu_cmd[kdb_init_cpu] = KDB_CPU_MAIN_KDB;
 33.1158 +            return KDB_CPU_PAUSE;
 33.1159 +        } else
 33.1160 +            kdbp("Unable to switch to: %d\n", kdb_init_cpu);
 33.1161 +    }
 33.1162 +    return KDB_CPU_MAIN_KDB;
 33.1163 +}
 33.1164 +
 33.1165 +/* send NMI to all or given CPU. Must be crashed/fatal state */
 33.1166 +static kdb_cpu_cmd_t
 33.1167 +kdb_usgf_nmi(void)
 33.1168 +{
 33.1169 +    kdbp("nmi cpu#|all: send nmi cpu/s. must reboot when done with kdb\n");
 33.1170 +    return KDB_CPU_MAIN_KDB;
 33.1171 +}
 33.1172 +static kdb_cpu_cmd_t 
 33.1173 +kdb_cmdf_nmi(int argc, const char **argv, struct cpu_user_regs *regs)
 33.1174 +{
 33.1175 +    cpumask_t cpumask;
 33.1176 +    int ccpu = smp_processor_id();
 33.1177 +
 33.1178 +    if (argc <= 1 || (argc > 1 && *argv[1] == '?'))
 33.1179 +        return kdb_usgf_nmi();
 33.1180 +
 33.1181 +    if (!kdb_sys_crash) {
 33.1182 +        kdbp("kdb: nmi cmd available in crashed state only\n");
 33.1183 +        return KDB_CPU_MAIN_KDB;
 33.1184 +    }
 33.1185 +    if (!strcmp(argv[1], "all"))
 33.1186 +        cpumask = cpu_online_map;
 33.1187 +    else {
 33.1188 +        int cpu = (int)simple_strtoul(argv[1], NULL, 0);
 33.1189 +        if (cpu >= 0 && cpu < NR_CPUS && cpu != ccpu && cpu_online(cpu))
 33.1190 +            cpumask = cpumask_of_cpu(cpu);
 33.1191 +        else {
 33.1192 +            kdbp("KDB nmi: invalid cpu %s\n", argv[1]);
 33.1193 +            return KDB_CPU_MAIN_KDB;
 33.1194 +        }
 33.1195 +    }
 33.1196 +    kdb_nmi_pause_cpus(cpumask);
 33.1197 +    return KDB_CPU_MAIN_KDB;
 33.1198 +}
 33.1199 +
 33.1200 +/* ========================= Breakpoints ==================================== */
 33.1201 +
 33.1202 +static void
 33.1203 +kdb_prnt_bp_cond(int bpnum)
 33.1204 +{
 33.1205 +    struct kdb_bpcond *bpcp = &kdb_sbpa[bpnum].u.bp_cond;
 33.1206 +
 33.1207 +    if (bpcp->bp_cond_status == 1) {
 33.1208 +        kdbp("     ( %s %c%c %lx )\n", 
 33.1209 +             kdb_regoffs_to_name(bpcp->bp_cond_lhs),
 33.1210 +             bpcp->bp_cond_type == 1 ? '=' : '!', '=', bpcp->bp_cond_rhs);
 33.1211 +    } else {
 33.1212 +        kdbp("     ( %lx %c%c %lx )\n", bpcp->bp_cond_lhs,
 33.1213 +             bpcp->bp_cond_type == 1 ? '=' : '!', '=', bpcp->bp_cond_rhs);
 33.1214 +    }
 33.1215 +}
 33.1216 +
 33.1217 +static void
 33.1218 +kdb_prnt_bp_extra(int bpnum)
 33.1219 +{
 33.1220 +    if (kdb_sbpa[bpnum].bp_type == 2) {
 33.1221 +        ulong i, arg, *btp = kdb_sbpa[bpnum].u.bp_btp;
 33.1222 +        
 33.1223 +        kdbp("   will trace ");
 33.1224 +        for (i=0; i < KDB_MAXBTP && btp[i]; i++)
 33.1225 +            if ((arg=btp[i]) < sizeof (struct cpu_user_regs)) {
 33.1226 +                kdbp(" %s ", kdb_regoffs_to_name(arg));
 33.1227 +            } else {
 33.1228 +                kdbp(" %lx ", arg);
 33.1229 +            }
 33.1230 +        kdbp("\n");
 33.1231 +
 33.1232 +    } else if (kdb_sbpa[bpnum].bp_type == 1)
 33.1233 +        kdb_prnt_bp_cond(bpnum);
 33.1234 +}
 33.1235 +
 33.1236 +/*
 33.1237 + * List software breakpoints
 33.1238 + */
 33.1239 +static kdb_cpu_cmd_t
 33.1240 +kdb_display_sbkpts(void)
 33.1241 +{
 33.1242 +    int i;
 33.1243 +    for(i=0; i < KDBMAXSBP; i++)
 33.1244 +        if (kdb_sbpa[i].bp_addr && !kdb_sbpa[i].bp_deleted) {
 33.1245 +            struct domain *dp = kdb_domid2ptr(kdb_sbpa[i].bp_domid);
 33.1246 +
 33.1247 +            if (dp == NULL || dp->is_dying) {
 33.1248 +                memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
 33.1249 +                continue;
 33.1250 +            }
 33.1251 +            kdbp("[%d]: domid:%d 0x%lx   ", i, 
 33.1252 +                 kdb_sbpa[i].bp_domid, kdb_sbpa[i].bp_addr);
 33.1253 +            kdb_prnt_addr2sym(kdb_sbpa[i].bp_domid, kdb_sbpa[i].bp_addr,"\n");
 33.1254 +            kdb_prnt_bp_extra(i);
 33.1255 +        }
 33.1256 +    return KDB_CPU_MAIN_KDB;
 33.1257 +}
 33.1258 +
 33.1259 +/*
 33.1260 + * Check if any breakpoints that we need to install (delayed install)
 33.1261 + * Returns: 1 if yes, 0 if none.
 33.1262 + */
 33.1263 +int
 33.1264 +kdb_swbp_exists(void)
 33.1265 +{
 33.1266 +    int i;
 33.1267 +    for (i=0; i < KDBMAXSBP; i++)
 33.1268 +        if (kdb_sbpa[i].bp_addr && !kdb_sbpa[i].bp_deleted)
 33.1269 +            return 1;
 33.1270 +    return 0;
 33.1271 +}
 33.1272 +/*
 33.1273 + * Check if any breakpoints were deleted this kdb session
 33.1274 + * Returns: 0 if none, 1 if yes
 33.1275 + */
 33.1276 +static int
 33.1277 +kdb_swbp_deleted(void)
 33.1278 +{
 33.1279 +    int i;
 33.1280 +    for (i=0; i < KDBMAXSBP; i++)
 33.1281 +        if (kdb_sbpa[i].bp_addr && kdb_sbpa[i].bp_deleted)
 33.1282 +            return 1;
 33.1283 +    return 0;
 33.1284 +}
 33.1285 +
 33.1286 +/*
 33.1287 + * Flush deleted sw breakpoints
 33.1288 + */
 33.1289 +void
 33.1290 +kdb_flush_swbp_table(void)
 33.1291 +{
 33.1292 +    int i;
 33.1293 +    KDBGP("ccpu:%d flush_swbp_table: deleted:%x\n", smp_processor_id(), 
 33.1294 +          kdb_swbp_deleted());
 33.1295 +    for(i=0; i < KDBMAXSBP; i++)
 33.1296 +        if (kdb_sbpa[i].bp_addr && kdb_sbpa[i].bp_deleted) {
 33.1297 +            KDBGP("flush:[%x] addr:0x%lx\n",i,kdb_sbpa[i].bp_addr);
 33.1298 +            memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
 33.1299 +        }
 33.1300 +}
 33.1301 +
 33.1302 +/*
 33.1303 + * Delete/Clear a sw breakpoint
 33.1304 + */
 33.1305 +static kdb_cpu_cmd_t
 33.1306 +kdb_usgf_bc(void)
 33.1307 +{
 33.1308 +    kdbp("bc $num|all : clear given or all breakpoints\n");
 33.1309 +    return KDB_CPU_MAIN_KDB;
 33.1310 +}
 33.1311 +static kdb_cpu_cmd_t 
 33.1312 +kdb_cmdf_bc(int argc, const char **argv, struct cpu_user_regs *regs)
 33.1313 +{
 33.1314 +    int i, bpnum = -1, delall = 0;
 33.1315 +    const char *argp;
 33.1316 +
 33.1317 +    if (argc != 2 || *argv[1] == '?')
 33.1318 +        return kdb_usgf_bc();
 33.1319 +
 33.1320 +    if (!kdb_swbp_exists()) {
 33.1321 +        kdbp("No breakpoints are set\n");
 33.1322 +        return KDB_CPU_MAIN_KDB;
 33.1323 +    }
 33.1324 +    argp = argv[1];
 33.1325 +
 33.1326 +    if (!strcmp(argp, "all"))
 33.1327 +        delall = 1;
 33.1328 +    else if (!kdb_str2deci(argp, &bpnum) || bpnum < 0 || bpnum > KDBMAXSBP) {
 33.1329 +        kdbp("Invalid bpnum: %s\n", argp);
 33.1330 +        return KDB_CPU_MAIN_KDB;
 33.1331 +    }
 33.1332 +    for (i=0; i < KDBMAXSBP; i++) {
 33.1333 +        if (delall && kdb_sbpa[i].bp_addr) {
 33.1334 +            kdbp("Deleted breakpoint [%x] addr:0x%lx domid:%d\n", 
 33.1335 +                 (int)i, kdb_sbpa[i].bp_addr, kdb_sbpa[i].bp_domid);
 33.1336 +            if (kdb_sbpa[i].bp_just_added)
 33.1337 +                memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
 33.1338 +            else
 33.1339 +                kdb_sbpa[i].bp_deleted = 1;
 33.1340 +            continue;
 33.1341 +        }
 33.1342 +        if (bpnum != -1 && bpnum == i) {
 33.1343 +            kdbp("Deleted breakpoint [%x] at 0x%lx domid:%d\n", 
 33.1344 +                 (int)i, kdb_sbpa[i].bp_addr, kdb_sbpa[i].bp_domid);
 33.1345 +            if (kdb_sbpa[i].bp_just_added)
 33.1346 +                memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
 33.1347 +            else
 33.1348 +                kdb_sbpa[i].bp_deleted = 1;
 33.1349 +            break;
 33.1350 +        }
 33.1351 +    }
 33.1352 +    if (i >= KDBMAXSBP && !delall)
 33.1353 +        kdbp("Unable to delete breakpoint: %s\n", argp);
 33.1354 +
 33.1355 +    return KDB_CPU_MAIN_KDB;
 33.1356 +}
 33.1357 +
 33.1358 +/*
 33.1359 + * Install a breakpoint in the given array entry
 33.1360 + * Returns: 0 : failed to install
 33.1361 + *          1 : installed successfully
 33.1362 + */
 33.1363 +static int
 33.1364 +kdb_install_swbp(int idx)                   /* which entry in the bp array */
 33.1365 +{
 33.1366 +    kdbva_t addr = kdb_sbpa[idx].bp_addr;
 33.1367 +    domid_t domid = kdb_sbpa[idx].bp_domid;
 33.1368 +    kdbbyt_t *p = &kdb_sbpa[idx].bp_originst;
 33.1369 +    struct domain *dp = kdb_domid2ptr(domid);
 33.1370 +
 33.1371 +    if (dp == NULL || dp->is_dying) {
 33.1372 +        memset(&kdb_sbpa[idx], 0, sizeof(kdb_sbpa[idx]));
 33.1373 +        kdbp("Removed bp %d addr:%p domid:%d\n", idx, addr, domid);
 33.1374 +        return 0;
 33.1375 +    }
 33.1376 +
 33.1377 +    if (kdb_read_mem(addr, p, KDBBPSZ, domid) != KDBBPSZ){
 33.1378 +        kdbp("Failed(R) to install bp:%x at:0x%lx domid:%d\n",
 33.1379 +             idx, kdb_sbpa[idx].bp_addr, domid);
 33.1380 +        return 0;
 33.1381 +    }
 33.1382 +    if (kdb_write_mem(addr, &kdb_bpinst, KDBBPSZ, domid) != KDBBPSZ) {
 33.1383 +        kdbp("Failed(W) to install bp:%x at:0x%lx domid:%d\n",
 33.1384 +             idx, kdb_sbpa[idx].bp_addr, domid);
 33.1385 +        return 0;
 33.1386 +    }
 33.1387 +    KDBGP("install_swbp: installed bp:%x at:0x%lx ccpu:%x domid:%d\n",
 33.1388 +          idx, kdb_sbpa[idx].bp_addr, smp_processor_id(), domid);
 33.1389 +    return 1;
 33.1390 +}
 33.1391 +
 33.1392 +/*
 33.1393 + * Install all the software breakpoints
 33.1394 + */
 33.1395 +void
 33.1396 +kdb_install_all_swbp(void)
 33.1397 +{
 33.1398 +    int i;
 33.1399 +    for(i=0; i < KDBMAXSBP; i++)
 33.1400 +        if (!kdb_sbpa[i].bp_deleted && kdb_sbpa[i].bp_addr)
 33.1401 +            kdb_install_swbp(i);
 33.1402 +}
 33.1403 +
 33.1404 +static void
 33.1405 +kdb_uninstall_a_swbp(int i)
 33.1406 +{
 33.1407 +    kdbva_t addr = kdb_sbpa[i].bp_addr;
 33.1408 +    kdbbyt_t originst = kdb_sbpa[i].bp_originst;
 33.1409 +    domid_t id = kdb_sbpa[i].bp_domid;
 33.1410 +
 33.1411 +    kdb_sbpa[i].bp_just_added = 0;
 33.1412 +    if (!addr)
 33.1413 +        return;
 33.1414 +    if (kdb_write_mem(addr, &originst, KDBBPSZ, id) != KDBBPSZ) {
 33.1415 +        kdbp("Failed to uninstall breakpoint %x at:0x%lx domid:%d\n",
 33.1416 +             i, kdb_sbpa[i].bp_addr, id);
 33.1417 +    }
 33.1418 +}
 33.1419 +
 33.1420 +/*
 33.1421 + * Uninstall all the software breakpoints at beginning of kdb session
 33.1422 + */
 33.1423 +void
 33.1424 +kdb_uninstall_all_swbp(void)
 33.1425 +{
 33.1426 +    int i;
 33.1427 +    for(i=0; i < KDBMAXSBP; i++) 
 33.1428 +        kdb_uninstall_a_swbp(i);
 33.1429 +    KDBGP("ccpu:%d uninstalled all bps\n", smp_processor_id());
 33.1430 +}
 33.1431 +
 33.1432 +/* RETURNS: rc == 2: condition was not met,  rc == 3: condition was met */
 33.1433 +static int
 33.1434 +kdb_check_bp_condition(int bpnum, struct cpu_user_regs *regs, domid_t domid)
 33.1435 +{
 33.1436 +    ulong res = 0, lhsval=0;
 33.1437 +    struct kdb_bpcond *bpcp = &kdb_sbpa[bpnum].u.bp_cond;
 33.1438 +
 33.1439 +    if (bpcp->bp_cond_status == 1) {             /* register condition */
 33.1440 +        uint64_t *rp = (uint64_t *)((char *)regs + bpcp->bp_cond_lhs);
 33.1441 +        lhsval = *rp;
 33.1442 +    } else if (bpcp->bp_cond_status == 2) {      /* memaddr condition */
 33.1443 +        ulong addr = bpcp->bp_cond_lhs;
 33.1444 +        int num = sizeof(lhsval);
 33.1445 +
 33.1446 +        if (kdb_read_mem(addr, (kdbbyt_t *)&lhsval, num, domid) != num) {
 33.1447 +            kdbp("kdb: unable to read %d bytes at %lx\n", num, addr);
 33.1448 +            return 3;
 33.1449 +        }
 33.1450 +    }
 33.1451 +    if (bpcp->bp_cond_type == 1)                 /* lhs == rhs */
 33.1452 +        res = (lhsval == bpcp->bp_cond_rhs);
 33.1453 +    else                                         /* lhs != rhs */
 33.1454 +        res = (lhsval != bpcp->bp_cond_rhs);
 33.1455 +
 33.1456 +    if (!res)
 33.1457 +        kdbp("KDB: [%d]Ignoring bp:%d condition not met. val:%lx\n", 
 33.1458 +              smp_processor_id(), bpnum, lhsval); 
 33.1459 +
 33.1460 +    KDBGP1("bpnum:%d domid:%d cond: %d %d %lx %lx res:%d\n", bpnum, domid, 
 33.1461 +           bpcp->bp_cond_status, bpcp->bp_cond_type, bpcp->bp_cond_lhs, 
 33.1462 +           bpcp->bp_cond_rhs, res);
 33.1463 +
 33.1464 +    return (res ? 3 : 2);
 33.1465 +}
 33.1466 +
 33.1467 +static void
 33.1468 +kdb_prnt_btp_info(int bpnum, struct cpu_user_regs *regs, domid_t domid)
 33.1469 +{
 33.1470 +    ulong i, arg, val, num, *btp = kdb_sbpa[bpnum].u.bp_btp;
 33.1471 +
 33.1472 +    kdb_prnt_addr2sym(domid, regs->KDBIP, "\n");
 33.1473 +    num = kdb_guest_bitness(domid)/8;
 33.1474 +    for (i=0; i < KDB_MAXBTP && (arg=btp[i]); i++) {
 33.1475 +        if (arg < sizeof (struct cpu_user_regs)) {
 33.1476 +            uint64_t *rp = (uint64_t *)((char *)regs + arg);
 33.1477 +            kdbp(" %s: %016lx ", kdb_regoffs_to_name(arg), *rp);
 33.1478 +        } else {
 33.1479 +            if (kdb_read_mem(arg, (kdbbyt_t *)&val, num, domid) != num)
 33.1480 +                kdbp("kdb: unable to read %d bytes at %lx\n", num, arg);
 33.1481 +            if (num == 8)
 33.1482 +                kdbp(" %016lx:%016lx ", arg, val);
 33.1483 +            else
 33.1484 +                kdbp(" %08lx:%08lx ", arg, val);
 33.1485 +        }
 33.1486 +    }
 33.1487 +    kdbp("\n");
 33.1488 +    KDBGP1("bpnum:%d domid:%d btp:%p num:%d\n", bpnum, domid, btp, num);
 33.1489 +}
 33.1490 +
 33.1491 +/*
 33.1492 + * Check if the BP trap belongs to us. 
 33.1493 + * Return: 0 : not one of ours. IP not changed. (leave kdb)
 33.1494 + *         1 : one of ours but deleted. IP decremented. (leave kdb)
 33.1495 + *         2 : one of ours but condition not met, or btp. IP decremented.(leave)
 33.1496 + *         3 : one of ours and active. IP decremented. (stay in kdb)
 33.1497 + */
 33.1498 +int 
 33.1499 +kdb_check_sw_bkpts(struct cpu_user_regs *regs)
 33.1500 +{
 33.1501 +    int i, rc=0;
 33.1502 +    domid_t curid;
 33.1503 +
 33.1504 +    curid = guest_mode(regs) ? current->domain->domain_id : DOMID_IDLE;
 33.1505 +    for(i=0; i < KDBMAXSBP; i++) {
 33.1506 +        if (kdb_sbpa[i].bp_domid == curid  && 
 33.1507 +            kdb_sbpa[i].bp_addr == (regs->KDBIP- KDBBPSZ)) {
 33.1508 +
 33.1509 +            regs->KDBIP -= KDBBPSZ;
 33.1510 +            rc = 3;
 33.1511 +
 33.1512 +            if (kdb_sbpa[i].bp_ni) {
 33.1513 +                kdb_uninstall_a_swbp(i);
 33.1514 +                memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
 33.1515 +            } else if (kdb_sbpa[i].bp_deleted) {
 33.1516 +                rc = 1;
 33.1517 +            } else if (kdb_sbpa[i].bp_type == 1) {
 33.1518 +                rc = kdb_check_bp_condition(i, regs, curid);
 33.1519 +            } else if (kdb_sbpa[i].bp_type == 2) {
 33.1520 +                kdb_prnt_btp_info(i, regs, curid);
 33.1521 +                rc = 2;
 33.1522 +            }
 33.1523 +            KDBGP1("ccpu:%d rc:%d curid:%d domid:%d addr:%lx\n", 
 33.1524 +                   smp_processor_id(), rc, curid, kdb_sbpa[i].bp_domid, 
 33.1525 +                   kdb_sbpa[i].bp_addr);
 33.1526 +            break;
 33.1527 +        }
 33.1528 +    }
 33.1529 +    return (rc);
 33.1530 +}
 33.1531 +
 33.1532 +/* Eg: r6 == 0x123EDF  or 0xFFFF2034 != 0xDEADBEEF
 33.1533 + * regoffs: -1 means lhs is not reg. else offset of reg in cpu_user_regs
 33.1534 + * addr: memory location if lhs is not register, eg, 0xFFFF2034
 33.1535 + * condp : points to != or ==
 33.1536 + * rhsval : right hand side value
 33.1537 + */
 33.1538 +static void
 33.1539 +kdb_set_bp_cond(int bpnum, int regoffs, ulong addr, char *condp, ulong rhsval)
 33.1540 +{
 33.1541 +    if (bpnum >= KDBMAXSBP) {
 33.1542 +        kdbp("BUG: %s got invalid bpnum\n", __FUNCTION__);
 33.1543 +        return;
 33.1544 +    }
 33.1545 +    if (regoffs != -1) {
 33.1546 +        kdb_sbpa[bpnum].u.bp_cond.bp_cond_status = 1;
 33.1547 +        kdb_sbpa[bpnum].u.bp_cond.bp_cond_lhs = regoffs;
 33.1548 +    } else if (addr != 0) {
 33.1549 +        kdb_sbpa[bpnum].u.bp_cond.bp_cond_status = 2;
 33.1550 +        kdb_sbpa[bpnum].u.bp_cond.bp_cond_lhs = addr;
 33.1551 +    } else {
 33.1552 +        kdbp("error: invalid call to kdb_set_bp_cond\n");
 33.1553 +        return;
 33.1554 +    }
 33.1555 +    kdb_sbpa[bpnum].u.bp_cond.bp_cond_rhs = rhsval;
 33.1556 +
 33.1557 +    if (*condp == '!')
 33.1558 +        kdb_sbpa[bpnum].u.bp_cond.bp_cond_type = 2;
 33.1559 +    else
 33.1560 +        kdb_sbpa[bpnum].u.bp_cond.bp_cond_type = 1;
 33.1561 +}
 33.1562 +
 33.1563 +/* install breakpt at given addr. 
 33.1564 + * ni: bp for next instr 
 33.1565 + * btpa: ptr to args for btp for printing when bp is hit
 33.1566 + * lhsp/condp/rhsp: point to strings of condition
 33.1567 + *
 33.1568 + * RETURNS: the index in array where installed. KDBMAXSBP if error 
 33.1569 + */
 33.1570 +static int
 33.1571 +kdb_set_bp(domid_t domid, kdbva_t addr, int ni, ulong *btpa, char *lhsp, 
 33.1572 +           char *condp, char *rhsp)
 33.1573 +{
 33.1574 +    int i, pre_existing = 0, regoffs = -1;
 33.1575 +    ulong memloc=0, rhsval=0, tmpul;
 33.1576 +
 33.1577 +    if (btpa && (lhsp || rhsp || condp)) {
 33.1578 +        kdbp("internal error. btpa and (lhsp || rhsp || condp) set\n");
 33.1579 +        return KDBMAXSBP;
 33.1580 +    }
 33.1581 +    if (lhsp && ((regoffs=kdb_valid_reg(lhsp)) == -1)  &&
 33.1582 +        kdb_str2ulong(lhsp, &memloc) &&
 33.1583 +        kdb_read_mem(memloc, (kdbbyt_t *)&tmpul, sizeof(tmpul), domid)==0) {
 33.1584 +
 33.1585 +        kdbp("error: invalid argument: %s\n", lhsp);
 33.1586 +        return KDBMAXSBP;
 33.1587 +    }
 33.1588 +    if (rhsp && ! kdb_str2ulong(rhsp, &rhsval)) {
 33.1589 +        kdbp("error: invalid argument: %s\n", rhsp);
 33.1590 +        return KDBMAXSBP;
 33.1591 +    }
 33.1592 +
 33.1593 +    /* see if bp already set */
 33.1594 +    for (i=0; i < KDBMAXSBP; i++) {
 33.1595 +        if (kdb_sbpa[i].bp_addr==addr && kdb_sbpa[i].bp_domid==domid) {
 33.1596 +
 33.1597 +            if (kdb_sbpa[i].bp_deleted) {
 33.1598 +                /* just re-set this bp again */
 33.1599 +                memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
 33.1600 +                pre_existing = 1;
 33.1601 +            } else {
 33.1602 +                kdbp("Breakpoint already set \n");
 33.1603 +                return KDBMAXSBP;
 33.1604 +            }
 33.1605 +        }
 33.1606 +    }
 33.1607 +    /* see if any room left for another breakpoint */
 33.1608 +    for (i=0; i < KDBMAXSBP; i++)
 33.1609 +        if (!kdb_sbpa[i].bp_addr)
 33.1610 +            break;
 33.1611 +    if (i >= KDBMAXSBP) {
 33.1612 +        kdbp("ERROR: Breakpoint table full....\n");
 33.1613 +        return i;
 33.1614 +    }
 33.1615 +    kdb_sbpa[i].bp_addr = addr;
 33.1616 +    kdb_sbpa[i].bp_domid = domid;
 33.1617 +    if (btpa) {
 33.1618 +        kdb_sbpa[i].bp_type = 2;
 33.1619 +        kdb_sbpa[i].u.bp_btp = btpa;
 33.1620 +    } else if (regoffs != -1 || memloc) {
 33.1621 +        kdb_sbpa[i].bp_type = 1;
 33.1622 +        kdb_set_bp_cond(i, regoffs, memloc, condp, rhsval);
 33.1623 +    } else
 33.1624 +        kdb_sbpa[i].bp_type = 0;
 33.1625 +
 33.1626 +    if (kdb_install_swbp(i)) {                  /* make sure it can be done */
 33.1627 +        if (ni)
 33.1628 +            return i;
 33.1629 +
 33.1630 +        kdb_uninstall_a_swbp(i);                /* dont' show user INT3 */
 33.1631 +        if (!pre_existing)               /* make sure no is cpu sitting on it */
 33.1632 +            kdb_sbpa[i].bp_just_added = 1;
 33.1633 +
 33.1634 +        kdbp("bp %d set for domid:%d at: 0x%lx ", i, kdb_sbpa[i].bp_domid, 
 33.1635 +             kdb_sbpa[i].bp_addr);
 33.1636 +        kdb_prnt_addr2sym(domid, addr, "\n");
 33.1637 +        kdb_prnt_bp_extra(i);
 33.1638 +    } else {
 33.1639 +        kdbp("ERROR:Can't install bp: 0x%lx domid:%d\n", addr, domid);
 33.1640 +        if (pre_existing)     /* in case a cpu is sitting on this bp in traps */
 33.1641 +            kdb_sbpa[i].bp_deleted = 1;
 33.1642 +        else
 33.1643 +            memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
 33.1644 +        return KDBMAXSBP;
 33.1645 +    }
 33.1646 +    /* make sure swbp reporting is enabled in the vmcb/vmcs */
 33.1647 +    if (is_hvm_domain(kdb_domid2ptr(domid))) {
 33.1648 +        struct domain *dp = kdb_domid2ptr(domid);
 33.1649 +        dp->debugger_attached = 1;              /* see svm_do_resume/vmx_do_ */
 33.1650 +        KDBGP("debugger_attached set. domid:%d\n", domid);
 33.1651 +    }
 33.1652 +    return i;
 33.1653 +}
 33.1654 +
 33.1655 +/* 
 33.1656 + * Set/List Software Breakpoint/s
 33.1657 + */
 33.1658 +static kdb_cpu_cmd_t
 33.1659 +kdb_usgf_bp(void)
 33.1660 +{
 33.1661 +    kdbp("bp [addr|sym][domid][condition]: display or set a breakpoint\n");
 33.1662 +    kdbp("  where cond is like: r6 == 0x123F or rax != DEADBEEF or \n");
 33.1663 +    kdbp("       ffff82c48038fe58 == 321E or 0xffff82c48038fe58 != 0\n");
 33.1664 +    kdbp("  regs: rax rbx rcx rdx rsi rdi rbp rsp r8 r9");
 33.1665 +    kdbp(" r10 r11 r12 r13 r14 r15 rflags\n");
 33.1666 +    return KDB_CPU_MAIN_KDB;
 33.1667 +}
 33.1668 +static kdb_cpu_cmd_t 
 33.1669 +kdb_cmdf_bp(int argc, const char **argv, struct cpu_user_regs *regs)
 33.1670 +{
 33.1671 +    kdbva_t addr;
 33.1672 +    int idx = -1;
 33.1673 +    domid_t domid = DOMID_IDLE;
 33.1674 +    char *domidstrp, *lhsp=NULL, *condp=NULL, *rhsp=NULL;
 33.1675 +
 33.1676 +    if ((argc > 1 && *argv[1] == '?') || argc == 4 || argc > 6)
 33.1677 +        return kdb_usgf_bp();
 33.1678 +
 33.1679 +    if (argc < 2 || kdb_sys_crash)         /* list all set breakpoints */
 33.1680 +        return kdb_display_sbkpts();
 33.1681 +
 33.1682 +    /* valid argc either: 2 3 5 or 6 
 33.1683 +     * 'bp idle_loop r6 == 0xc000' OR 'bp idle_loop 3 r9 != 0xdeadbeef' */
 33.1684 +    idx = (argc == 5) ? 2 : ((argc == 6) ? 3 : idx);
 33.1685 +    if (argc >= 5 ) {
 33.1686 +        lhsp = (char *)argv[idx];
 33.1687 +        condp = (char *)argv[idx+1];
 33.1688 +        rhsp = (char *)argv[idx+2];
 33.1689 +
 33.1690 +        if (!kdb_str2ulong(rhsp, NULL) || *(condp+1) != '=' || 
 33.1691 +            (*condp != '=' && *condp != '!')) {
 33.1692 +
 33.1693 +            return kdb_usgf_bp();
 33.1694 +        }
 33.1695 +    }
 33.1696 +    domidstrp = (argc == 3 || argc == 6 ) ? (char *)argv[2] : NULL;
 33.1697 +    if (domidstrp && !kdb_str2domid(domidstrp, &domid, 1)) {
 33.1698 +        return kdb_usgf_bp();
 33.1699 +    }
 33.1700 +    if (argc > 3 && is_hvm_domain(kdb_domid2ptr(domid))) {
 33.1701 +        kdbp("HVM domain not supported yet for conditional bp\n");
 33.1702 +        return KDB_CPU_MAIN_KDB;
 33.1703 +    }
 33.1704 +
 33.1705 +    if (!kdb_str2addr(argv[1], &addr, domid) || addr == 0) {
 33.1706 +        kdbp("Invalid argument:%s\n", argv[1]);
 33.1707 +        return KDB_CPU_MAIN_KDB;
 33.1708 +    }
 33.1709 +
 33.1710 +    /* make sure xen addr is in xen text, otherwise bp set in 64bit dom0/U */
 33.1711 +    if (domid == DOMID_IDLE && 
 33.1712 +        (addr < XEN_VIRT_START || addr > XEN_VIRT_END))
 33.1713 +    {
 33.1714 +        kdbp("addr:%lx not in  xen text\n", addr);
 33.1715 +        return KDB_CPU_MAIN_KDB;
 33.1716 +    }
 33.1717 +    kdb_set_bp(domid, addr, 0, NULL, lhsp, condp, rhsp);     /* 0 is ni flag */
 33.1718 +    return KDB_CPU_MAIN_KDB;
 33.1719 +}
 33.1720 +
 33.1721 +
 33.1722 +/* trace breakpoint, meaning, upon bp trace/print some info and continue */
 33.1723 +
 33.1724 +static kdb_cpu_cmd_t
 33.1725 +kdb_usgf_btp(void)
 33.1726 +{
 33.1727 +    kdbp("btp addr|sym [domid] reg|domid-mem-addr... : breakpoint trace\n");
 33.1728 +    kdbp("  regs: rax rbx rcx rdx rsi rdi rbp rsp r8 r9 ");
 33.1729 +    kdbp("r10 r11 r12 r13 r14 r15 rflags\n");
 33.1730 +    kdbp("  Eg. btp idle_cpu 7 rax rbx 0x20ef5a5 r9\n");
 33.1731 +    kdbp("      will print rax, rbx, *(long *)0x20ef5a5, r9 and continue\n");
 33.1732 +    return KDB_CPU_MAIN_KDB;
 33.1733 +}
 33.1734 +static kdb_cpu_cmd_t 
 33.1735 +kdb_cmdf_btp(int argc, const char **argv, struct cpu_user_regs *regs)
 33.1736 +{
 33.1737 +    int i, btpidx, numrd, argsidx, regoffs = -1;
 33.1738 +    kdbva_t addr, memloc=0;
 33.1739 +    domid_t domid = DOMID_IDLE;
 33.1740 +    ulong *btpa, tmpul;
 33.1741 +
 33.1742 +    if ((argc > 1 && *argv[1] == '?') || argc < 3)
 33.1743 +        return kdb_usgf_btp();
 33.1744 +
 33.1745 +    argsidx = 2;                   /* assume 3rd arg is not domid */
 33.1746 +    if (argc > 3 && kdb_str2domid(argv[2], &domid, 0)) {
 33.1747 +
 33.1748 +        if (is_hvm_domain(kdb_domid2ptr(domid))) {
 33.1749 +            kdbp("HVM domains are not currently supprted\n");
 33.1750 +            return KDB_CPU_MAIN_KDB;
 33.1751 +        } else
 33.1752 +            argsidx = 3;               /* 3rd arg is a domid */
 33.1753 +    }
 33.1754 +    if (!kdb_str2addr(argv[1], &addr, domid) || addr == 0) {
 33.1755 +        kdbp("Invalid argument:%s\n", argv[1]);
 33.1756 +        return KDB_CPU_MAIN_KDB;
 33.1757 +    }
 33.1758 +    /* make sure xen addr is in xen text, otherwise will trace 64bit dom0/U */
 33.1759 +    if (domid == DOMID_IDLE && 
 33.1760 +        (addr < XEN_VIRT_START || addr > XEN_VIRT_END))
 33.1761 +    {
 33.1762 +        kdbp("addr:%lx not in  xen text\n", addr);
 33.1763 +        return KDB_CPU_MAIN_KDB;
 33.1764 +    }
 33.1765 +
 33.1766 +    numrd = kdb_guest_bitness(domid)/8;
 33.1767 +    if (kdb_read_mem(addr, (kdbbyt_t *)&tmpul, numrd, domid) != numrd) {
 33.1768 +        kdbp("Unable to read mem from %s (%lx)\n", argv[1], addr);
 33.1769 +        return KDB_CPU_MAIN_KDB;
 33.1770 +    }
 33.1771 +
 33.1772 +    for (btpidx=0; btpidx < KDBMAXSBP && kdb_btp_ap[btpidx]; btpidx++);
 33.1773 +    if (btpidx >= KDBMAXSBP) {
 33.1774 +        kdbp("error: table full. delete few breakpoints\n");
 33.1775 +        return KDB_CPU_MAIN_KDB;
 33.1776 +    }
 33.1777 +    btpa = kdb_btp_argsa[btpidx];
 33.1778 +    memset(btpa, 0, sizeof(kdb_btp_argsa[0]));
 33.1779 +
 33.1780 +    for (i=0; argv[argsidx]; i++, argsidx++) {
 33.1781 +
 33.1782 +        if (((regoffs=kdb_valid_reg(argv[argsidx])) == -1)  &&
 33.1783 +            kdb_str2ulong(argv[argsidx], &memloc) &&
 33.1784 +            (memloc < sizeof (struct cpu_user_regs) ||
 33.1785 +            kdb_read_mem(memloc, (kdbbyt_t *)&tmpul, sizeof(tmpul), domid)==0)){
 33.1786 +
 33.1787 +            kdbp("error: invalid argument: %s\n", argv[argsidx]);
 33.1788 +            return KDB_CPU_MAIN_KDB;
 33.1789 +        }
 33.1790 +        if (i >= KDB_MAXBTP) {
 33.1791 +            kdbp("error: cannot specify more than %d args\n", KDB_MAXBTP);
 33.1792 +            return KDB_CPU_MAIN_KDB;
 33.1793 +        }
 33.1794 +        btpa[i] = (regoffs == -1) ? memloc : regoffs;
 33.1795 +    }
 33.1796 +
 33.1797 +    i = kdb_set_bp(domid, addr, 0, btpa, 0, 0, 0);     /* 0 is ni flag */
 33.1798 +    if (i < KDBMAXSBP)
 33.1799 +        kdb_btp_ap[btpidx] = kdb_btp_argsa[btpidx];
 33.1800 +
 33.1801 +    return KDB_CPU_MAIN_KDB;
 33.1802 +}
 33.1803 +
 33.1804 +/* 
 33.1805 + * Set/List watchpoints, ie, hardware breakpoint/s, in hypervisor
 33.1806 + *   Usage: wp [sym|addr] [w|i]   w == write only data watchpoint
 33.1807 + *                                i == IO watchpoint (read/write)
 33.1808 + *
 33.1809 + *   Eg:  wp        : list all watchpoints set
 33.1810 + *        wp addr   : set a read/write wp at given addr
 33.1811 + *        wp addr w : set a write only wp at given addr
 33.1812 + *        wp addr i : set an IO wp at given addr (16bits port #)
 33.1813 + *
 33.1814 + *  TBD: allow to be set on particular cpu
 33.1815 + */
 33.1816 +static kdb_cpu_cmd_t
 33.1817 +kdb_usgf_wp(void)
 33.1818 +{
 33.1819 +    kdbp("wp [addr|sym][w|i]: display or set watchpoint. writeonly or IO\n");
 33.1820 +    kdbp("\tnote: watchpoint is triggered after the instruction executes\n");
 33.1821 +    return KDB_CPU_MAIN_KDB;
 33.1822 +}
 33.1823 +static kdb_cpu_cmd_t 
 33.1824 +kdb_cmdf_wp(int argc, const char **argv, struct cpu_user_regs *regs)
 33.1825 +{
 33.1826 +    kdbva_t addr;
 33.1827 +    domid_t domid = DOMID_IDLE;
 33.1828 +    int rw = 3, len = 4;       /* for now just default to 4 bytes len */
 33.1829 +
 33.1830 +    if (argc > 1 && *argv[1] == '?')
 33.1831 +        return kdb_usgf_wp();
 33.1832 +
 33.1833 +    if (argc <= 1 || kdb_sys_crash) {       /* list all set watchpoints */
 33.1834 +        kdb_do_watchpoints(0, 0, 0);
 33.1835 +        return KDB_CPU_MAIN_KDB;
 33.1836 +    }
 33.1837 +    if (!kdb_str2addr(argv[1], &addr, domid) || addr == 0) {
 33.1838 +        kdbp("Invalid argument:%s\n", argv[1]);
 33.1839 +        return KDB_CPU_MAIN_KDB;
 33.1840 +    }
 33.1841 +    if (argc > 2) {
 33.1842 +        if (!strcmp(argv[2], "w"))
 33.1843 +            rw = 1;
 33.1844 +        else if (!strcmp(argv[2], "i"))
 33.1845 +            rw = 2;
 33.1846 +        else {
 33.1847 +            return kdb_usgf_wp();
 33.1848 +        }
 33.1849 +    }
 33.1850 +    kdb_do_watchpoints(addr, rw, len);
 33.1851 +    return KDB_CPU_MAIN_KDB;
 33.1852 +}
 33.1853 +
 33.1854 +static kdb_cpu_cmd_t
 33.1855 +kdb_usgf_wc(void)
 33.1856 +{
 33.1857 +    kdbp("wc $num|all : clear given or all watchpoints\n");
 33.1858 +    return KDB_CPU_MAIN_KDB;
 33.1859 +}
 33.1860 +static kdb_cpu_cmd_t 
 33.1861 +kdb_cmdf_wc(int argc, const char **argv, struct cpu_user_regs *regs)
 33.1862 +{
 33.1863 +    const char *argp;
 33.1864 +    int wpnum;              /* wp num to delete. -1 for all */
 33.1865 +
 33.1866 +    if (argc != 2 || *argv[1] == '?') 
 33.1867 +        return kdb_usgf_wc();
 33.1868 +
 33.1869 +    argp = argv[1];
 33.1870 +
 33.1871 +    if (!strcmp(argp, "all"))
 33.1872 +        wpnum = -1;
 33.1873 +    else if (!kdb_str2deci(argp, &wpnum)) {
 33.1874 +        kdbp("Invalid wpnum: %s\n", argp);
 33.1875 +        return KDB_CPU_MAIN_KDB;
 33.1876 +    }
 33.1877 +    kdb_clear_wps(wpnum);
 33.1878 +    return KDB_CPU_MAIN_KDB;
 33.1879 +}
 33.1880 +
 33.1881 +/* display struct hvm_vcpu{} in struct vcpu.arch{} */
 33.1882 +static kdb_cpu_cmd_t
 33.1883 +kdb_usgf_vcpuh(void)
 33.1884 +{
 33.1885 +    kdbp("vcpuh vcpu-ptr : display hvm_vcpu struct\n");
 33.1886 +    return KDB_CPU_MAIN_KDB;
 33.1887 +}
 33.1888 +static kdb_cpu_cmd_t 
 33.1889 +kdb_cmdf_vcpuh(int argc, const char **argv, struct cpu_user_regs *regs)
 33.1890 +{
 33.1891 +    struct vcpu *vp;
 33.1892 +    struct hvm_vcpu *hvp;
 33.1893 +    struct hvm_io_op *ioop;
 33.1894 +    struct vlapic *vlp;
 33.1895 +
 33.1896 +    if (argc < 2 || *argv[1] == '?') 
 33.1897 +        return kdb_usgf_vcpuh();
 33.1898 +
 33.1899 +    if (!kdb_str2ulong(argv[1], (ulong *)&vp) || !kdb_vcpu_valid(vp) ||
 33.1900 +        !is_hvm_vcpu(vp)) {
 33.1901 +
 33.1902 +        kdbp("kdb: Bad VCPU: %s\n", argv[1]);
 33.1903 +        return KDB_CPU_MAIN_KDB;
 33.1904 +    }
 33.1905 +
 33.1906 +    hvp = &vp->arch.hvm_vcpu;
 33.1907 +    vlp = &hvp->vlapic;
 33.1908 +    kdbp("vcpu:%lx id:%d domid:%d\n", vp, vp->vcpu_id, vp->domain->domain_id);
 33.1909 +
 33.1910 +    ioop = NULL;   /* compiler warning */
 33.1911 +    kdbp("&hvm_vcpu:%lx  guest_efer:"KDBFL"\n", hvp, hvp->guest_efer);
 33.1912 +    kdbp("  guest_cr: [0]:"KDBFL" [1]:"KDBFL" [2]:"KDBFL"\n", hvp->guest_cr[0],
 33.1913 +         hvp->guest_cr[1],hvp->guest_cr[2]);
 33.1914 +    kdbp("            [3]:"KDBFL" [4]:"KDBFL"\n", hvp->guest_cr[3],
 33.1915 +         hvp->guest_cr[4]);
 33.1916 +    kdbp("  hw_cr: [0]:"KDBFL" [1]:"KDBFL" [2]:"KDBFL"\n", hvp->hw_cr[0],
 33.1917 +         hvp->hw_cr[1], hvp->hw_cr[2]);
 33.1918 +    kdbp("          [3]:"KDBFL" [4]:"KDBFL"\n", hvp->hw_cr[3], hvp->hw_cr[4]);
 33.1919 +
 33.1920 +    kdbp("  VLAPIC: base msr:"KDBF64" dis:%x tmrdiv:%x\n", 
 33.1921 +         vlp->hw.apic_base_msr, vlp->hw.disabled, vlp->hw.timer_divisor);
 33.1922 +    kdbp("          regs:%p regs_page:%p\n", vlp->regs, vlp->regs_page);
 33.1923 +    kdbp("          periodic time:\n"); 
 33.1924 +    kdb_prnt_periodic_time(&vlp->pt);
 33.1925 +
 33.1926 +    kdbp("  xen_port:%x flag_dr_dirty:%x dbg_st_latch:%x\n", hvp->xen_port,
 33.1927 +         hvp->flag_dr_dirty, hvp->debug_state_latch);
 33.1928 +
 33.1929 +    if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
 33.1930 +
 33.1931 +        struct arch_vmx_struct *vxp = &hvp->u.vmx;
 33.1932 +        kdbp("  &vmx: %p vmcs:%lx active_cpu:%x launched:%x\n", vxp, vxp->vmcs, 
 33.1933 +             vxp->active_cpu, vxp->launched);
 33.1934 +#if XEN_VERSION != 4               /* xen 3.x.x */
 33.1935 +        kdbp("    exec_ctrl:%x vpid:$%d\n", vxp->exec_control, vxp->vpid);
 33.1936 +#endif
 33.1937 +        kdbp("    host_cr0: "KDBFL" vmx: {realm:%x emulate:%x}\n",
 33.1938 +             vxp->host_cr0, vxp->vmx_realmode, vxp->vmx_emulate);
 33.1939 +
 33.1940 +#ifdef __x86_64__
 33.1941 +        kdbp("    &msr_state:%p\n", &vxp->msr_state);
 33.1942 +#endif
 33.1943 +    } else if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
 33.1944 +        struct arch_svm_struct *svp = &hvp->u.svm;
 33.1945 +#if XEN_VERSION != 4               /* xen 3.x.x */
 33.1946 +        kdbp("  &svm: vmcb:%lx pa:"KDBF64" asid:"KDBF64"\n", svp, svp->vmcb,
 33.1947 +             svp->vmcb_pa, svp->asid_generation);
 33.1948 +#endif
 33.1949 +        kdbp("    msrpm:%p lnch_core:%x vmcb_sync:%x\n", svp->msrpm, 
 33.1950 +             svp->launch_core, svp->vmcb_in_sync);
 33.1951 +    }
 33.1952 +    kdbp("  cachemode:%x io: {state: %x data: "KDBFL"}\n", hvp->cache_mode,
 33.1953 +         hvp->io_state, hvp->io_data);
 33.1954 +    kdbp("  mmio: {gva: "KDBFL" gpfn: "KDBFL"}\n",hvp->mmio_gva,hvp->mmio_gpfn);
 33.1955 +
 33.1956 +    return KDB_CPU_MAIN_KDB;
 33.1957 +}
 33.1958 +
 33.1959 +/* also look into arch_get_info_guest() to get context */
 33.1960 +static void
 33.1961 +kdb_print_uregs(struct cpu_user_regs *regs)
 33.1962 +{
 33.1963 +#ifdef __x86_64__
 33.1964 +    kdbp("      rflags: %016lx   rip: %016lx\n", regs->rflags, regs->rip);
 33.1965 +    kdbp("         rax: %016lx   rbx: %016lx   rcx: %016lx\n",
 33.1966 +         regs->rax, regs->rbx, regs->rcx);
 33.1967 +    kdbp("         rdx: %016lx   rsi: %016lx   rdi: %016lx\n",
 33.1968 +         regs->rdx, regs->rsi, regs->rdi);
 33.1969 +    kdbp("         rbp: %016lx   rsp: %016lx    r8: %016lx\n",
 33.1970 +         regs->rbp, regs->rsp, regs->r8);
 33.1971 +    kdbp("          r9:  %016lx  r10: %016lx   r11: %016lx\n",
 33.1972 +         regs->r9,  regs->r10, regs->r11);
 33.1973 +    kdbp("         r12: %016lx   r13: %016lx   r14: %016lx\n",
 33.1974 +         regs->r12, regs->r13, regs->r14);
 33.1975 +    kdbp("         r15: %016lx\n", regs->r15);
 33.1976 +    kdbp("      ds: %04x   es: %04x   fs: %04x   gs: %04x   "
 33.1977 +         "      ss: %04x   cs: %04x\n", regs->ds, regs->es, regs->fs,
 33.1978 +         regs->gs, regs->ss, regs->cs);
 33.1979 +    kdbp("      errcode:%08lx entryvec:%08lx upcall_mask:%lx\n",
 33.1980 +         regs->error_code, regs->entry_vector, regs->saved_upcall_mask);
 33.1981 +#else
 33.1982 +    kdbp("      eflags: %016lx eip: 016lx\n", regs->eflags, regs->eip);
 33.1983 +    kdbp("      eax: %08x   ebx: %08x   ecx: %08x   edx: %08x\n",
 33.1984 +         regs->eax, regs->ebx, regs->ecx, regs->edx);
 33.1985 +    kdbp("      esi: %08x   edi: %08x   ebp: %08x   esp: %08x\n",
 33.1986 +         regs->esi, regs->edi, regs->ebp, regs->esp);
 33.1987 +    kdbp("      ds: %04x   es: %04x   fs: %04x   gs: %04x   "
 33.1988 +     "      ss: %04x   cs: %04x\n", regs->ds, regs->es, regs->fs,
 33.1989 +         regs->gs, regs->ss, regs->cs);
 33.1990 +    kdbp("      errcode:%04lx entryvec:%04lx upcall_mask:%lx\n", 
 33.1991 +         regs->error_code, regs->entry_vector, regs->saved_upcall_mask);
 33.1992 +#endif
 33.1993 +}
 33.1994 +
 33.1995 +#if XEN_SUBVERSION < 3             /* xen 3.1.x or xen 3.2.x */
 33.1996 +#ifdef CONFIG_COMPAT
 33.1997 +    #undef vcpu_info
 33.1998 +    #define vcpu_info(v, field)             \
 33.1999 +    (*(!has_32bit_shinfo((v)->domain) ?                                       \
 33.2000 +       (typeof(&(v)->vcpu_info->compat.field))&(v)->vcpu_info->native.field : \
 33.2001 +       (typeof(&(v)->vcpu_info->compat.field))&(v)->vcpu_info->compat.field))
 33.2002 +
 33.2003 +    #undef __shared_info
 33.2004 +    #define __shared_info(d, s, field)                      \
 33.2005 +    (*(!has_32bit_shinfo(d) ?                           \
 33.2006 +       (typeof(&(s)->compat.field))&(s)->native.field : \
 33.2007 +       (typeof(&(s)->compat.field))&(s)->compat.field))
 33.2008 +#endif
 33.2009 +#endif
 33.2010 +
 33.2011 +/* Display one VCPU info */
 33.2012 +static void
 33.2013 +kdb_display_vcpu(struct vcpu *vp)
 33.2014 +{
 33.2015 +    int i;
 33.2016 +    struct vcpu_guest_context *gp = &vp->arch.guest_context;
 33.2017 +    struct paging_vcpu *pvp = &vp->arch.paging;
 33.2018 +    int domid = vp->domain->domain_id;
 33.2019 +
 33.2020 +    kdbp("\nVCPU:  vcpu-id:%d  vcpu-ptr:%p ", vp->vcpu_id, vp);
 33.2021 +    kdbp("  processor:%d domid:%d  domp:%p\n", vp->processor, domid,vp->domain);
 33.2022 +
 33.2023 +    if (domid == DOMID_IDLE) {
 33.2024 +        kdbp("    IDLE vcpu.\n");
 33.2025 +        return;
 33.2026 +    }
 33.2027 +    kdbp("  pause: flags:0x%016lx count:%x\n", vp->pause_flags, 
 33.2028 +         vp->pause_count.counter);
 33.2029 +    kdbp("  vcpu: initdone:%d running:%d\n", 
 33.2030 +         vp->is_initialised, vp->is_running);
 33.2031 +    kdbp("  mcepend:%d nmipend:%d shut: def:%d paused:%d\n", 
 33.2032 +         vp->mce_pending,  vp->nmi_pending, vp->defer_shutdown, 
 33.2033 +         vp->paused_for_shutdown);
 33.2034 +    kdbp("  &vcpu_info:%p : evtchn_upc_pend:%x _mask:%x\n",
 33.2035 +         vp->vcpu_info, vcpu_info(vp, evtchn_upcall_pending),
 33.2036 +         vcpu_info(vp, evtchn_upcall_mask));
 33.2037 +    kdbp("  evt_pend_sel:%lx poll_evtchn:%x ", 
 33.2038 +         *(unsigned long *)&vcpu_info(vp, evtchn_pending_sel), vp->poll_evtchn);
 33.2039 +    kdb_print_spin_lock("virq_lock:", &vp->virq_lock, "\n");
 33.2040 +    for (i=0; i < NR_VIRQS; i++)
 33.2041 +        if (vp->virq_to_evtchn[i] != 0)
 33.2042 +            kdbp("      virq:$%d port:$%d\n", i, vp->virq_to_evtchn[i]);
 33.2043 +
 33.2044 +    kdbp("  next:%p periodic: period:0x%lx last_event:0x%lx\n", 
 33.2045 +         vp->next_in_list, vp->periodic_period, vp->periodic_last_event);
 33.2046 +    kdbp("  cpu_affinity:0x%lx vcpu_dirty_cpumask:0x%lx sched_priv:0x%p\n",
 33.2047 +         vp->cpu_affinity.bits[0], vp->vcpu_dirty_cpumask.bits[0],
 33.2048 +         vp->sched_priv);
 33.2049 +    kdbp("  &runstate: %p state: %x\n", &vp->runstate, vp->runstate.state);
 33.2050 +    kdbp("\n");
 33.2051 +    kdbp("  arch info: (%p)\n", &vp->arch);
 33.2052 +    kdbp("    guest_context: VGCF_ flags:%lx", gp->flags); /* VGCF_in_kernel */
 33.2053 +    if (is_hvm_vcpu(vp))
 33.2054 +        kdbp("    (HVM guest: IP, SP, EFLAGS may be stale)");
 33.2055 +    kdbp("\n");
 33.2056 +    kdb_print_uregs(&gp->user_regs);
 33.2057 +
 33.2058 +    kdbp("      GDT: entries:0x%lx  frames:\n", gp->gdt_ents);
 33.2059 +    for (i=0; i < 16; i=i+4) 
 33.2060 +        kdbp("          %016lx %016lx %016lx %016lx\n", gp->gdt_frames[i], 
 33.2061 +             gp->gdt_frames[i+1], gp->gdt_frames[i+2],gp->gdt_frames[i+3]);
 33.2062 +    
 33.2063 +    kdbp("      trap_ctxt:%lx kernel_ss:%lx kernel_sp:%lx\n", gp->trap_ctxt,
 33.2064 +         gp->kernel_ss, gp->kernel_sp);
 33.2065 +    kdbp("      ctrlregs:\n");
 33.2066 +    for (i=0; i < 8; i=i+4)
 33.2067 +        kdbp("          %016lx %016lx %016lx %016lx\n", gp->ctrlreg[i], 
 33.2068 +             gp->ctrlreg[i+1], gp->ctrlreg[i+2], gp->ctrlreg[i+3]);
 33.2069 +    kdbp("      debugregs:\n");
 33.2070 +    for (i=0; i < 8; i=i+4)
 33.2071 +        kdbp("          %016lx %016lx %016lx %016lx\n", gp->debugreg[i], 
 33.2072 +             gp->debugreg[i+1], gp->debugreg[i+2], gp->debugreg[i+3]);
 33.2073 +#ifdef __x86_64__
 33.2074 +    kdbp("      callback:   event: %016lx   failsafe: %016lx\n", 
 33.2075 +         gp->event_callback_eip, gp->failsafe_callback_eip);
 33.2076 +    kdbp("      base: fs:0x%lx gskern:0x%lx gsuser:0x%lx\n", 
 33.2077 +         gp->fs_base, gp->gs_base_kernel, gp->gs_base_user);
 33.2078 +#else
 33.2079 +    kdbp("      callback:   event: %08lx:%08lx   failsafe: %08lx:%08lx\n", 
 33.2080 +         gp->event_callback_cs, gp->event_callback_eip, 
 33.2081 +         gp->failsafe_callback_cs, gp->failsafe_callback_eip);
 33.2082 +#endif
 33.2083 +    kdbp("\n");
 33.2084 +    kdbp("    TF_flags:0x%016lx  guest_table:0x%016lx\n", vp->arch.flags, 
 33.2085 +         vp->arch.guest_table.pfn); 
 33.2086 +    kdbp("    cr3: 0x%016lx  vcpu_info_mfn:0x%lx\n", vp->arch.cr3, 
 33.2087 +         vp->arch.vcpu_info_mfn);
 33.2088 +    kdbp("    paging: \n");
 33.2089 +    kdbp("      vtlb:%p\n", &pvp->vtlb);
 33.2090 +    kdbp("      &pg_mode:%p gstlevels:%d &shadow:%p shlevels:%d\n",
 33.2091 +         pvp->mode, pvp->mode->guest_levels, &pvp->mode->shadow,
 33.2092 +         pvp->mode->shadow.shadow_levels);
 33.2093 +    kdbp("      shadow_vcpu:\n");
 33.2094 +    kdbp("        guest_vtable:%p last em_mfn:"KDBFL"\n",
 33.2095 +         pvp->shadow.guest_vtable, pvp->shadow.last_emulated_mfn);
 33.2096 +#if CONFIG_PAGING_LEVELS >= 3
 33.2097 +    kdbp("         l3tbl: 3:"KDBFL" 2:"KDBFL"\n"
 33.2098 +         "                1:"KDBFL" 0:"KDBFL"\n",
 33.2099 +     pvp->shadow.l3table[3].l3, pvp->shadow.l3table[2].l3, 
 33.2100 +     pvp->shadow.l3table[1].l3, pvp->shadow.l3table[0].l3);
 33.2101 +    kdbp("        gl3tbl: 3:"KDBFL" 2:"KDBFL"\n"
 33.2102 +         "                1:"KDBFL" 0:"KDBFL"\n",
 33.2103 +     pvp->shadow.gl3e[3].l3, pvp->shadow.gl3e[2].l3, 
 33.2104 +     pvp->shadow.gl3e[1].l3, pvp->shadow.gl3e[0].l3);
 33.2105 +#endif
 33.2106 +    kdbp("  gdbsx_vcpu_event:%x\n", vp->arch.gdbsx_vcpu_event);
 33.2107 +}
 33.2108 +
 33.2109 +/* 
 33.2110 + * FUNCTION: Dispaly (current) VCPU/s
 33.2111 + */
 33.2112 +static kdb_cpu_cmd_t
 33.2113 +kdb_usgf_vcpu(void)
 33.2114 +{
 33.2115 +    kdbp("vcpu [vcpu-ptr] : display current/vcpu-ptr vcpu info\n");
 33.2116 +    return KDB_CPU_MAIN_KDB;
 33.2117 +}
 33.2118 +static kdb_cpu_cmd_t 
 33.2119 +kdb_cmdf_vcpu(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2120 +{
 33.2121 +    struct vcpu *v = current;
 33.2122 +
 33.2123 +    if (argc > 2 || (argc > 1 && *argv[1] == '?'))
 33.2124 +        kdb_usgf_vcpu();
 33.2125 +    else if (argc <= 1)
 33.2126 +        kdb_display_vcpu(v);
 33.2127 +    else if (kdb_str2ulong(argv[1], (ulong *)&v) && kdb_vcpu_valid(v))
 33.2128 +        kdb_display_vcpu(v);
 33.2129 +    else 
 33.2130 +        kdbp("Invalid usage/argument:%s v:%lx\n", argv[1], (long)v);
 33.2131 +    return KDB_CPU_MAIN_KDB;
 33.2132 +}
 33.2133 +
 33.2134 +/* from paging_dump_domain_info() */
 33.2135 +static void kdb_pr_dom_pg_modes(struct domain *d)
 33.2136 +{
 33.2137 +    if (paging_mode_enabled(d)) {
 33.2138 +        kdbp(" paging mode enabled");
 33.2139 +        if ( paging_mode_shadow(d) )
 33.2140 +            kdbp(" shadow(PG_SH_enable)");
 33.2141 +        if ( paging_mode_hap(d) )
 33.2142 +            kdbp(" hap(PG_HAP_enable) ");
 33.2143 +        if ( paging_mode_refcounts(d) )
 33.2144 +            kdbp(" refcounts(PG_refcounts) ");
 33.2145 +        if ( paging_mode_log_dirty(d) )
 33.2146 +            kdbp(" log_dirty(PG_log_dirty) ");
 33.2147 +        if ( paging_mode_translate(d) )
 33.2148 +            kdbp(" translate(PG_translate) ");
 33.2149 +        if ( paging_mode_external(d) )
 33.2150 +            kdbp(" external(PG_external) ");
 33.2151 +    } else
 33.2152 +        kdbp("disabled");
 33.2153 +    kdbp("\n");
 33.2154 +}
 33.2155 +
 33.2156 +/* print event channels info for a given domain 
 33.2157 + * NOTE: very confusing, port and event channel refer to the same thing. evtchn
 33.2158 + * is arry of pointers to a bucket of pointers to 128 struct evtchn{}. while
 33.2159 + * 64bit xen can handle 4096 max channels, a 32bit guest is limited to 1024 */
 33.2160 +static void noinline kdb_print_dom_eventinfo(struct domain *dp)
 33.2161 +{
 33.2162 +    uint chn;
 33.2163 +
 33.2164 +    kdbp("\n");
 33.2165 +    kdbp("  Evt: MAX_EVTCHNS:$%d ptr:%p pollmsk:%08lx ",
 33.2166 +         MAX_EVTCHNS(dp), dp->evtchn, dp->poll_mask[0]);
 33.2167 +    kdb_print_spin_lock("lk:", &dp->event_lock, "\n");
 33.2168 +    kdbp("    &evtchn_pending:%p &evtchn_mask:%p\n", 
 33.2169 +         shared_info(dp, evtchn_pending), shared_info(dp, evtchn_mask));
 33.2170 +
 33.2171 +    kdbp("   Channels info: (everything is in decimal):\n");
 33.2172 +    for (chn=0; chn < MAX_EVTCHNS(dp); chn++ ) {
 33.2173 +        struct evtchn *bktp = dp->evtchn[chn/EVTCHNS_PER_BUCKET];
 33.2174 +        struct evtchn *chnp = &bktp[chn & (EVTCHNS_PER_BUCKET-1)];
 33.2175 +        char pbit = test_bit(chn, &shared_info(dp, evtchn_pending)) ? 'Y' : 'N';
 33.2176 +        char mbit = test_bit(chn, &shared_info(dp, evtchn_mask)) ? 'Y' : 'N';
 33.2177 +
 33.2178 +        if (bktp==NULL || chnp->state==ECS_FREE)
 33.2179 +            continue;
 33.2180 +
 33.2181 +        kdbp("    chn:%4u st:%d _xen=%d _vcpu_id:%2d ", chn, chnp->state,
 33.2182 +             chnp->consumer_is_xen, chnp->notify_vcpu_id);
 33.2183 +        if (chnp->state == ECS_UNBOUND)
 33.2184 +            kdbp(" rem-domid:%d", chnp->u.unbound.remote_domid);
 33.2185 +        else if (chnp->state == ECS_INTERDOMAIN)
 33.2186 +            kdbp(" rem-port:%d rem-dom:%d", chnp->u.interdomain.remote_port,
 33.2187 +                 chnp->u.interdomain.remote_dom->domain_id);
 33.2188 +        else if (chnp->state == ECS_PIRQ)
 33.2189 +            kdbp(" pirq:%d", chnp->u.pirq);
 33.2190 +        else if (chnp->state == ECS_VIRQ)
 33.2191 +            kdbp(" virq:%d", chnp->u.virq);
 33.2192 +
 33.2193 +        kdbp("  pend:%c mask:%c\n", pbit, mbit);
 33.2194 +    }
 33.2195 +#if 0
 33.2196 +    kdbp("pirq to evtchn mapping (pirq:evtchn) (all decimal):\n");
 33.2197 +    for (i=0; i < dp->nr_pirqs; i ++)
 33.2198 +        if (dp->pirq_to_evtchn[i])
 33.2199 +            kdbp("(%d:%d) ", i, dp->pirq_to_evtchn[i]);
 33.2200 +    kdbp("\n");
 33.2201 +#endif
 33.2202 +}
 33.2203 +
 33.2204 +/* display one domain info */
 33.2205 +static void
 33.2206 +kdb_display_dom(struct domain *dp)
 33.2207 +{
 33.2208 +    int printed = 0;
 33.2209 +    struct grant_table *gp;
 33.2210 +    struct arch_domain *ap = &dp->arch;
 33.2211 +    struct vcpu *vp;
 33.2212 +
 33.2213 +    kdbp("\nDOMAIN :    domid:0x%04x ptr:0x%p\n", dp->domain_id, dp);
 33.2214 +    if (dp->domain_id == DOMID_IDLE) {
 33.2215 +        kdbp("    IDLE domain.\n");
 33.2216 +        return;
 33.2217 +    }
 33.2218 +    if (dp->is_dying) {
 33.2219 +        kdbp("    domain is DYING.\n");
 33.2220 +        return;
 33.2221 +    }
 33.2222 +    kdb_print_spin_lock("  pgalk:", &dp->page_alloc_lock, "\n");
 33.2223 +    kdbp("  pglist:  0x%p 0x%p\n", dp->page_list.next,KDB_PGLLE(dp->page_list));
 33.2224 +    kdbp("  xpglist: 0x%p 0x%p\n", dp->xenpage_list.next, 
 33.2225 +         KDB_PGLLE(dp->xenpage_list));
 33.2226 +    kdbp("  PAGES: tot:0x%08x max:0x%08x xenheap:0x%08x\n", 
 33.2227 +         dp->tot_pages, dp->max_pages, dp->xenheap_pages);
 33.2228 +    kdbp("  next:0x%p hashnext:0x%p\n", 
 33.2229 +         dp->next_in_list, dp->next_in_hashbucket);
 33.2230 +    kdbp("  rangesets: nxt:0x%p prev:0x%p ", dp->rangesets.next, 
 33.2231 +         dp->rangesets.prev); 
 33.2232 +    kdb_print_spin_lock("lk:", &dp->rangesets_lock, "\n");
 33.2233 +
 33.2234 +    kdb_print_dom_eventinfo(dp);
 33.2235 +    kdbp("\n");
 33.2236 +    gp = dp->grant_table;
 33.2237 +    kdbp("  Grant table: gp:0x%p\n", gp);
 33.2238 +    if (gp) {
 33.2239 +        kdbp("    nr_frames:0x%08x shpp:0x%p active:0x%p\n",
 33.2240 +             gp->nr_grant_frames, gp->shared_raw, gp->active);
 33.2241 +        kdbp("    maptrk:0x%p maphd:0x%08x maplmt:0x%08x\n", 
 33.2242 +             gp->maptrack, gp->maptrack_head, gp->maptrack_limit);
 33.2243 +        kdbp("    mapcnt:");
 33.2244 +        kdb_print_spin_lock("mapcnt: lk:", &gp->lock, "\n");
 33.2245 +    }
 33.2246 +    kdbp("  hvm:%d priv:%d dbg:%d dying:%d paused:%d\n",
 33.2247 +         dp->is_hvm, dp->is_privileged, dp->debugger_attached,
 33.2248 +         dp->is_dying, dp->is_paused_by_controller);
 33.2249 +    kdb_print_spin_lock("  shutdown: lk:", &dp->shutdown_lock, "\n");
 33.2250 +    kdbp("  shutn:%d shut:%d code:%d \n", dp->is_shutting_down,
 33.2251 +         dp->is_shut_down, dp->shutdown_code);
 33.2252 +    kdbp("  pausecnt:0x%08x vm_assist:0x"KDBFL" refcnt:0x%08x\n",
 33.2253 +         dp->pause_count.counter, dp->vm_assist, dp->refcnt.counter);
 33.2254 +    kdbp("  cpumask:%lx\n", dp->domain_dirty_cpumask.bits[0]); 
 33.2255 +
 33.2256 +    kdbp("  shared == vcpu_info[]: %p\n",  dp->shared_info); 
 33.2257 +    kdbp("    arch_shared: maxpfn: %lx pfn-mfn-frame-ll mfn: %lx\n", 
 33.2258 +         arch_get_max_pfn(dp), arch_get_pfn_to_mfn_frame_list_list(dp));
 33.2259 +    kdbp("\n");
 33.2260 +    kdbp("  arch_domain at : %p\n", ap);
 33.2261 +
 33.2262 +#ifdef CONFIG_X86_64
 33.2263 +    kdbp("    pt_pages:0x%p ", ap->mm_perdomain_pt_pages);
 33.2264 +    kdbp("    l2:0x%p l3:0x%p\n", ap->mm_perdomain_l2, ap->mm_perdomain_l3);
 33.2265 +#else
 33.2266 +    kdbp("    pt:0x%p ", ap->mm_perdomain_pt);
 33.2267 +#endif
 33.2268 +#ifdef CONFIG_X86_32
 33.2269 +    kdbp("    &mapchache:0x%xp\n", &ap->mapcache);
 33.2270 +#endif
 33.2271 +    kdbp("    ioport:0x%p &hvm_dom:0x%p\n", ap->ioport_caps, &ap->hvm_domain);
 33.2272 +    kdbp("    &pging_dom:%p mode:%lx", &ap->paging, ap->paging.mode); 
 33.2273 +    kdb_pr_dom_pg_modes(dp);
 33.2274 +    kdbp("    p2m ptr:%p  pages:{%p, %p}\n", ap->p2m, ap->p2m->pages.next,
 33.2275 +         KDB_PGLLE(ap->p2m->pages));
 33.2276 +    kdbp("            max_mapped_pfn:"KDBFL"\n", ap->p2m->max_mapped_pfn);
 33.2277 +#if XEN_SUBVERSION > 0 && XEN_VERSION == 4              /* xen 4.1 and above */
 33.2278 +    kdbp("    p2m dom:%p phys_table:%p\n", ap->p2m, ap->p2m->phys_table.pfn);
 33.2279 +#else
 33.2280 +    kdbp("    phys_table.pfn:"KDBFL"\n", ap->phys_table.pfn);
 33.2281 +#endif
 33.2282 +    kdbp("    physaddr_bitsz:%d 32bit_pv:%d has_32bit_shinfo:%d\n", 
 33.2283 +         ap->physaddr_bitsize, ap->is_32bit_pv, ap->has_32bit_shinfo);
 33.2284 +    kdbp("  sched:0x%p  &handle:0x%p\n", dp->sched_priv, &dp->handle);
 33.2285 +
 33.2286 +    kdbp("  vcpu ptrs:\n   ");
 33.2287 +    for_each_vcpu(dp, vp) {
 33.2288 +        kdbp(" %d:%p", vp->vcpu_id, vp);
 33.2289 +        if (++printed % 4 == 0) kdbp("\n   ");
 33.2290 +    }
 33.2291 +    kdbp("\n");
 33.2292 +}
 33.2293 +
 33.2294 +/* 
 33.2295 + * FUNCTION: Dispaly (current) domain/s
 33.2296 + */
 33.2297 +static kdb_cpu_cmd_t
 33.2298 +kdb_usgf_dom(void)
 33.2299 +{
 33.2300 +    kdbp("dom [all|domid]: Display current/all/given domain/s\n");
 33.2301 +    return KDB_CPU_MAIN_KDB;
 33.2302 +}
 33.2303 +static kdb_cpu_cmd_t 
 33.2304 +kdb_cmdf_dom(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2305 +{
 33.2306 +    int id;
 33.2307 +    struct domain *dp = current->domain;
 33.2308 +
 33.2309 +    if (argc > 1 && *argv[1] == '?')
 33.2310 +        return kdb_usgf_dom();
 33.2311 +
 33.2312 +    if (argc > 1) {
 33.2313 +        for(dp=domain_list; dp; dp=dp->next_in_list)
 33.2314 +            if (kdb_str2deci(argv[1], &id) && dp->domain_id==id)
 33.2315 +                kdb_display_dom(dp);
 33.2316 +            else if (!strcmp(argv[1], "all")) 
 33.2317 +                kdb_display_dom(dp);
 33.2318 +    } else {
 33.2319 +        kdbp("Displaying current domain :\n");
 33.2320 +        kdb_display_dom(dp);
 33.2321 +    }
 33.2322 +    return KDB_CPU_MAIN_KDB;
 33.2323 +}
 33.2324 +
 33.2325 +/* Dump irq desc table */
 33.2326 +static kdb_cpu_cmd_t
 33.2327 +kdb_usgf_dirq(void)
 33.2328 +{
 33.2329 +    kdbp("dirq : dump irq bindings\n");
 33.2330 +    return KDB_CPU_MAIN_KDB;
 33.2331 +}
 33.2332 +static kdb_cpu_cmd_t
 33.2333 +kdb_cmdf_dirq(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2334 +{
 33.2335 +    unsigned long irq, sz, offs, addr;
 33.2336 +    char buf[KSYM_NAME_LEN+1];
 33.2337 +    char affstr[NR_CPUS/4+NR_CPUS/32+2];    /* courtesy dump_irqs() */
 33.2338 +
 33.2339 +    if (argc > 1 && *argv[1] == '?')
 33.2340 +        return kdb_usgf_dirq();
 33.2341 +
 33.2342 +#if XEN_VERSION < 4 && XEN_SUBVERSION < 5           /* xen 3.4.x or below */
 33.2343 +    kdbp("idx/irq#/status: all are in decimal\n");
 33.2344 +    kdbp("idx  irq#  status   action(handler name devid)\n");
 33.2345 +    for (irq=0; irq < NR_VECTORS; irq++) {
 33.2346 +        irq_desc_t  *dp = &irq_desc[irq];
 33.2347 +        if (!dp->action)
 33.2348 +            continue;
 33.2349 +        addr = (unsigned long)dp->action->handler;
 33.2350 +        kdbp("[%3ld]:irq:%3d st:%3d f:%s devnm:%s devid:0x%p\n",
 33.2351 +             i, vector_to_irq(irq), dp->status, (dp->status & IRQ_GUEST) ? 
 33.2352 +                            "GUEST IRQ" : symbols_lookup(addr, &sz, &offs, buf),
 33.2353 +             dp->action->name, dp->action->dev_id);
 33.2354 +    }
 33.2355 +#else
 33.2356 +    kdbp("irq_desc[]:%p nr_irqs: $%d nr_irqs_gsi: $%d\n", irq_desc, nr_irqs, 
 33.2357 +          nr_irqs_gsi);
 33.2358 +    kdbp("irq/vec#/status: in decimal. affinity in hex, not bitmap\n");
 33.2359 +    kdbp("irq-- vec sta function----------- name---- type--------- ");
 33.2360 +    kdbp("aff devid------------\n");
 33.2361 +    for (irq=0; irq < nr_irqs; irq++) {
 33.2362 +        void *devidp;
 33.2363 +        const char *symp, *nmp;
 33.2364 +        irq_desc_t  *dp = irq_to_desc(irq);
 33.2365 +        struct irq_cfg *cfgp = dp->chip_data;
 33.2366 +
 33.2367 +        if (!dp->handler || dp->handler==&no_irq_type || dp->status & IRQ_GUEST)
 33.2368 +            continue;
 33.2369 +
 33.2370 +        addr = dp->action ? (unsigned long)dp->action->handler : 0;
 33.2371 +        symp = addr ? symbols_lookup(addr, &sz, &offs, buf) : "n/a ";
 33.2372 +        nmp = addr ? dp->action->name : "n/a ";
 33.2373 +        devidp = addr ? dp->action->dev_id : NULL;
 33.2374 +        cpumask_scnprintf(affstr, sizeof(affstr), dp->affinity);
 33.2375 +        kdbp("[%3ld] %03d %03d %-19s %-8s %-13s %3s 0x%p\n", irq, cfgp->vector, 
 33.2376 +             dp->status, symp, nmp, dp->handler->typename, affstr, devidp);
 33.2377 +    }
 33.2378 +    kdb_prnt_guest_mapped_irqs();
 33.2379 +#endif
 33.2380 +    return KDB_CPU_MAIN_KDB;
 33.2381 +}
 33.2382 +
 33.2383 +static void
 33.2384 +kdb_prnt_vec_irq_table(int cpu)
 33.2385 +{
 33.2386 +    int i,j, *tbl = per_cpu(vector_irq, cpu);
 33.2387 +
 33.2388 +    kdbp("CPU %d : ", cpu);
 33.2389 +    for (i=0, j=0; i < NR_VECTORS; i++)
 33.2390 +        if (tbl[i] != -1) {
 33.2391 +            kdbp("(%3d:%3d) ", i, tbl[i]);
 33.2392 +            if (!(++j % 5))
 33.2393 +                kdbp("\n        ");
 33.2394 +        }
 33.2395 +    kdbp("\n");
 33.2396 +}
 33.2397 +
 33.2398 +/* Dump irq desc table */
 33.2399 +static kdb_cpu_cmd_t
 33.2400 +kdb_usgf_dvit(void)
 33.2401 +{
 33.2402 +    kdbp("dvit [cpu|all]: dump (per cpu)vector irq table\n");
 33.2403 +    return KDB_CPU_MAIN_KDB;
 33.2404 +}
 33.2405 +static kdb_cpu_cmd_t
 33.2406 +kdb_cmdf_dvit(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2407 +{
 33.2408 +    int cpu, ccpu = smp_processor_id();
 33.2409 +
 33.2410 +    if (argc > 1 && *argv[1] == '?')
 33.2411 +        return kdb_usgf_dvit();
 33.2412 +    
 33.2413 +    if (argc > 1) {
 33.2414 +        if (!strcmp(argv[1], "all")) 
 33.2415 +            cpu = -1;
 33.2416 +        else if (!kdb_str2deci(argv[1], &cpu)) {
 33.2417 +            kdbp("Invalid cpu:%d\n", cpu);
 33.2418 +            return kdb_usgf_dvit();
 33.2419 +        }
 33.2420 +    } else
 33.2421 +        cpu = ccpu;
 33.2422 +
 33.2423 +    kdbp("Per CPU vector irq table pairs (vector:irq) (all decimals):\n");
 33.2424 +    if (cpu != -1) 
 33.2425 +        kdb_prnt_vec_irq_table(cpu);
 33.2426 +    else
 33.2427 +        for_each_online_cpu(cpu) 
 33.2428 +            kdb_prnt_vec_irq_table(cpu);
 33.2429 +
 33.2430 +    return KDB_CPU_MAIN_KDB;
 33.2431 +}
 33.2432 +
 33.2433 +/* do vmexit on all cpu's so intel VMCS can be dumped */
 33.2434 +static kdb_cpu_cmd_t 
 33.2435 +kdb_all_cpu_flush_vmcs(void)
 33.2436 +{
 33.2437 +    int cpu, ccpu = smp_processor_id();
 33.2438 +    for_each_online_cpu(cpu) {
 33.2439 +        if (cpu == ccpu) {
 33.2440 +            kdb_curr_cpu_flush_vmcs();
 33.2441 +        } else {
 33.2442 +            if (kdb_cpu_cmd[cpu] != KDB_CPU_PAUSE){  /* hung cpu */
 33.2443 +                kdbp("Skipping (hung?) cpu %d\n", cpu);
 33.2444 +                continue;
 33.2445 +            }
 33.2446 +            kdb_cpu_cmd[cpu] = KDB_CPU_DO_VMEXIT;
 33.2447 +            while (kdb_cpu_cmd[cpu]==KDB_CPU_DO_VMEXIT);
 33.2448 +        }
 33.2449 +    }
 33.2450 +    return KDB_CPU_MAIN_KDB;
 33.2451 +}
 33.2452 +
 33.2453 +/* Display VMCS or VMCB */
 33.2454 +static kdb_cpu_cmd_t
 33.2455 +kdb_usgf_dvmc(void)
 33.2456 +{
 33.2457 +    kdbp("dvmc [domid][vcpuid] : Dump vmcs/vmcb\n");
 33.2458 +    return KDB_CPU_MAIN_KDB;
 33.2459 +}
 33.2460 +static kdb_cpu_cmd_t
 33.2461 +kdb_cmdf_dvmc(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2462 +{
 33.2463 +    domid_t domid = 0;  /* unsigned type don't like -1 */
 33.2464 +    int vcpuid = -1;
 33.2465 +
 33.2466 +    if (argc > 1 && *argv[1] == '?')
 33.2467 +        return kdb_usgf_dvmc();
 33.2468 +
 33.2469 +    if (argc > 1) { 
 33.2470 +        if (!kdb_str2domid(argv[1], &domid, 1))
 33.2471 +            return KDB_CPU_MAIN_KDB;
 33.2472 +    }
 33.2473 +    if (argc > 2 && !kdb_str2deci(argv[2], &vcpuid)) {
 33.2474 +        kdbp("Bad vcpuid: 0x%x\n", vcpuid);
 33.2475 +        return KDB_CPU_MAIN_KDB;
 33.2476 +    }
 33.2477 +    if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
 33.2478 +        kdb_all_cpu_flush_vmcs();
 33.2479 +        kdb_dump_vmcs(domid, (int)vcpuid);
 33.2480 +    } else {
 33.2481 +        kdb_dump_vmcb(domid, (int)vcpuid);
 33.2482 +    }
 33.2483 +    return KDB_CPU_MAIN_KDB;
 33.2484 +}
 33.2485 +
 33.2486 +/* Dump timer/timers queues */
 33.2487 +static kdb_cpu_cmd_t
 33.2488 +kdb_usgf_dtrq(void)
 33.2489 +{
 33.2490 +    kdbp("dtrq: dump timer queues on all cpus\n");
 33.2491 +    return KDB_CPU_MAIN_KDB;
 33.2492 +}
 33.2493 +static kdb_cpu_cmd_t
 33.2494 +kdb_cmdf_dtrq(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2495 +{
 33.2496 +    if (argc > 1 && *argv[1] == '?')
 33.2497 +        return kdb_usgf_dtrq();
 33.2498 +
 33.2499 +    kdb_dump_timer_queues();
 33.2500 +    return KDB_CPU_MAIN_KDB;
 33.2501 +}
 33.2502 +
 33.2503 +struct idte {
 33.2504 +    uint16_t offs0_15;
 33.2505 +    uint16_t selector;
 33.2506 +    uint16_t meta;
 33.2507 +    uint16_t offs16_31;
 33.2508 +    uint32_t offs32_63;
 33.2509 +    uint32_t resvd;
 33.2510 +};
 33.2511 +
 33.2512 +#ifdef __x86_64__
 33.2513 +static void
 33.2514 +kdb_print_idte(int num, struct idte *idtp) 
 33.2515 +{
 33.2516 +    uint16_t mta = idtp->meta;
 33.2517 +    char dpl = ((mta & 0x6000) >> 13);
 33.2518 +    char present = ((mta &0x8000) >> 15);
 33.2519 +    int tval = ((mta &0x300) >> 8);
 33.2520 +    char *type = (tval == 1) ? "Task" : ((tval== 2) ? "Intr" : "Trap");
 33.2521 +    domid_t domid = idtp->selector==__HYPERVISOR_CS64 ? DOMID_IDLE :
 33.2522 +                    current->domain->domain_id;
 33.2523 +    uint64_t addr = idtp->offs0_15 | ((uint64_t)idtp->offs16_31 << 16) | 
 33.2524 +                    ((uint64_t)idtp->offs32_63 << 32);
 33.2525 +
 33.2526 +    kdbp("[%03d]: %s %x  %x %04x:%016lx ", num, type, dpl, present,
 33.2527 +         idtp->selector, addr); 
 33.2528 +    kdb_prnt_addr2sym(domid, addr, "\n");
 33.2529 +}
 33.2530 +
 33.2531 +/* Dump 64bit idt table currently on this cpu. Intel Vol 3 section 5.14.1 */
 33.2532 +static kdb_cpu_cmd_t
 33.2533 +kdb_usgf_didt(void)
 33.2534 +{
 33.2535 +    kdbp("didt : dump IDT table on the current cpu\n");
 33.2536 +    return KDB_CPU_MAIN_KDB;
 33.2537 +}
 33.2538 +static kdb_cpu_cmd_t
 33.2539 +kdb_cmdf_didt(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2540 +{
 33.2541 +    int i;
 33.2542 +    struct idte *idtp = (struct idte *)idt_tables[smp_processor_id()];
 33.2543 +
 33.2544 +    if (argc > 1 && *argv[1] == '?')
 33.2545 +        return kdb_usgf_didt();
 33.2546 +
 33.2547 +    kdbp("IDT at:%p\n", idtp);
 33.2548 +    kdbp("idt#  Type DPL P addr (all hex except idt#)\n", idtp);
 33.2549 +    for (i=0; i < 256; i++, idtp++) 
 33.2550 +        kdb_print_idte(i, idtp);
 33.2551 +    return KDB_CPU_MAIN_KDB;
 33.2552 +}
 33.2553 +#else
 33.2554 +static kdb_cpu_cmd_t
 33.2555 +kdb_cmdf_didt(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2556 +{
 33.2557 +    kdbp("kdb: Please implement me in 32bit hypervisor\n");
 33.2558 +    return KDB_CPU_MAIN_KDB;
 33.2559 +}
 33.2560 +#endif
 33.2561 +
 33.2562 +struct gdte {
 33.2563 +    ulong limit0:16;
 33.2564 +    ulong base0:24;       /* linear address base, not pa */
 33.2565 +    ulong acctype:4;      /* Type: access rights */
 33.2566 +    ulong S:1;            /* S: 0 = system, 1 = code/data */
 33.2567 +    ulong DPL:2;          /* DPL */
 33.2568 +    ulong P:1;            /* P: Segment Present */
 33.2569 +    ulong limit1:4;
 33.2570 +    ulong AVL:1;          /* AVL: avail for use by system software */
 33.2571 +    ulong L:1;            /* L: 64bit code segment */
 33.2572 +    ulong DB:1;           /* D/B */
 33.2573 +    ulong G:1;            /* G: granularity */
 33.2574 +    ulong base1:8;        /* linear address base, not pa */
 33.2575 +};
 33.2576 +
 33.2577 +union gdte_u {
 33.2578 +    struct gdte gdte;
 33.2579 +    u64 gval;
 33.2580 +};
 33.2581 +
 33.2582 +struct sgdte {           /* system gdte */
 33.2583 +    unsigned short offs0:16;
 33.2584 +    unsigned short sel:16;
 33.2585 +    unsigned short misc0:16;
 33.2586 +    unsigned short offs1:16;
 33.2587 +};
 33.2588 +
 33.2589 +union sgdte_u {
 33.2590 +    struct sgdte sgdte;
 33.2591 +    u64 sgval;
 33.2592 +};
 33.2593 +
 33.2594 +/* return binary form of a hex in string : max 4 chars 0000 to 1111 */
 33.2595 +static char *kdb_ret_acctype(uint acctype)
 33.2596 +{
 33.2597 +    static char buf[16];
 33.2598 +    char *p = buf;
 33.2599 +    int i;
 33.2600 +
 33.2601 +    if (acctype > 0xf) {
 33.2602 +        buf[0] = buf[1] = buf[2] = buf[3] = '?';
 33.2603 +        buf[5] = '\n';
 33.2604 +        return buf;
 33.2605 +    }
 33.2606 +    for (i=0; i < 4; i++, p++, acctype=acctype>>1)
 33.2607 +        *p = (acctype & 0x1) ? '1' : '0';
 33.2608 +
 33.2609 +    return buf;
 33.2610 +}
 33.2611 +
 33.2612 +/* Display GDT table */
 33.2613 +/* first display non system descriptors then display system descriptors */
 33.2614 +static kdb_cpu_cmd_t
 33.2615 +kdb_usgf_dgdt(void)
 33.2616 +{
 33.2617 +    kdbp("dgdt: dump GDT table on current cpu\n");
 33.2618 +    return KDB_CPU_MAIN_KDB;
 33.2619 +}
 33.2620 +static kdb_cpu_cmd_t
 33.2621 +kdb_cmdf_dgdt(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2622 +{
 33.2623 +    struct Xgt_desc_struct desc;
 33.2624 +    union gdte_u u1;
 33.2625 +    ulong addr, end;
 33.2626 +    domid_t domid = DOMID_IDLE;
 33.2627 +    int i;
 33.2628 +
 33.2629 +    if (argc > 1 && *argv[1] == '?')
 33.2630 +        return kdb_usgf_dgdt();
 33.2631 +
 33.2632 +    __asm__ __volatile__ ("sgdt  (%0) \n" :: "a"(&desc) : "memory");
 33.2633 +    kdbp("GDT: address:0x%lx size:0x%x\n", desc.address, desc.size);
 33.2634 +
 33.2635 +    addr = (ulong)desc.address + 8;         /* skip null descriptor */
 33.2636 +    end = (ulong)desc.address + desc.size;
 33.2637 +
 33.2638 +    kdbp("[idx]   sel --- val --------  Accs DPL P AVL L DB G "
 33.2639 +         "--Base Addr ----  Limit\n");
 33.2640 +    kdbp("                              Type\n");
 33.2641 +
 33.2642 +    for (i=1;  addr < end;  i++, addr += sizeof(ulong)) {
 33.2643 +
 33.2644 +        /* not all entries are mapped. do this to avoid GP even if hyp */
 33.2645 +        if (!kdb_read_mem(addr, (kdbbyt_t *)&u1, sizeof(u1),domid) || !u1.gval)
 33.2646 +            continue;
 33.2647 +
 33.2648 +        if (u1.gdte.S == 0) {       /* System Desc are 16 bytes in 64bit mode */
 33.2649 +            addr += sizeof(ulong);
 33.2650 +            i++;
 33.2651 +            continue;
 33.2652 +        }
 33.2653 +        kdbp("[%04x] %04x %016lx  %4s  %x  %d  %d  %d  %d %d %016lx  %05x\n",
 33.2654 +             i, (i<<3), u1.gval, kdb_ret_acctype(u1.gdte.acctype), u1.gdte.DPL, 
 33.2655 +             u1.gdte.P, u1.gdte.AVL, u1.gdte.L, u1.gdte.DB, 
 33.2656 +             u1.gdte.G,  (u64)((u64)u1.gdte.base0 | (u64)(u1.gdte.base1<<24)), 
 33.2657 +             u1.gdte.limit0 | (u1.gdte.limit1<<16));
 33.2658 +    }
 33.2659 +
 33.2660 +    kdbp("\nSystem descriptors (S=0) :\n");
 33.2661 +    addr = (ulong)desc.address + 8;         /* skip null descriptor */
 33.2662 +
 33.2663 +    for (i=1;  addr < end;  i++, addr += sizeof(ulong)) {
 33.2664 +        union sgdte_u u2;
 33.2665 +        uint acctype;
 33.2666 +        u64 upper, offs0_64=0, offs32_63=0;
 33.2667 +
 33.2668 +        /* not all entries are mapped. do this to avoid GP even if hyp */
 33.2669 +        if (kdb_read_mem(addr, (kdbbyt_t *)&u1, sizeof(u1),domid)==0 || 
 33.2670 +            u1.gval == 0 || u1.gdte.S == 1) {
 33.2671 +            continue;
 33.2672 +        }
 33.2673 +
 33.2674 +        addr += sizeof(ulong);
 33.2675 +        if (kdb_read_mem(addr, (kdbbyt_t *)&upper, 8, domid) == 0) {
 33.2676 +            kdbp("Could not read upper 8 bytes of system desc\n");
 33.2677 +            upper = 0;
 33.2678 +        }
 33.2679 +        acctype = u1.gdte.acctype;
 33.2680 +        kdbp("[%04x] %04x  val:%016lx DPL:%x P:%d acctype:%x ",
 33.2681 +             i, (i<<3), u1.gval, u1.gdte.DPL, u1.gdte.P, acctype); 
 33.2682 +
 33.2683 +        u2.sgval = u1.gval;
 33.2684 +        offs32_63 = (u64)((upper & 0xFFFFFFFF)) << 32;
 33.2685 +
 33.2686 +        /* Vol 3A: table: 3-2  page: 3-19 */
 33.2687 +        if (acctype == 2) {
 33.2688 +            kdbp("LDT gate (0010)\n");
 33.2689 +        }
 33.2690 +        else if (acctype == 9) {
 33.2691 +            kdbp("TSS avail gate(1001)\n");
 33.2692 +        }
 33.2693 +        else if (acctype == 11) {
 33.2694 +            kdbp("TSS busy gate(1011)\n");
 33.2695 +        }
 33.2696 +        else if (acctype == 12) {
 33.2697 +            kdbp("CALL gate (1100)\n");
 33.2698 +        }
 33.2699 +        else if (acctype == 14) {
 33.2700 +            kdbp("IDT gate (1110)\n");
 33.2701 +        }
 33.2702 +        else if (acctype == 15) {
 33.2703 +            kdbp("Trap gate (1111)\n"); 
 33.2704 +        }
 33.2705 +
 33.2706 +        if (acctype == 2 || acctype == 9 || acctype == 11) {
 33.2707 +            kdbp("        AVL:%d L:%d D/B:%d G:%d Base Addr:%016lx Limit:%x\n",
 33.2708 +                 u1.gdte.AVL, u1.gdte.L, u1.gdte.DB, u1.gdte.G,  
 33.2709 +                 u1.gdte.base0 | (u1.gdte.base1<<24) | offs32_63,
 33.2710 +                 u1.gdte.limit0 | (u1.gdte.limit1<<16));
 33.2711 +
 33.2712 +        } else if (acctype == 12 || acctype == 14 || acctype == 15) {
 33.2713 +            offs0_64 = u2.sgdte.offs0 | (u64)u2.sgdte.offs1<<48 | offs32_63;
 33.2714 +            kdbp("        Entry: %04x:%016lx\n", u2.sgdte.sel, offs0_64);
 33.2715 +        }
 33.2716 +
 33.2717 +        i++;
 33.2718 +    }
 33.2719 +    return KDB_CPU_MAIN_KDB;
 33.2720 +}
 33.2721 +
 33.2722 +/* Display scheduler basic and extended info */
 33.2723 +static kdb_cpu_cmd_t
 33.2724 +kdb_usgf_sched(void)
 33.2725 +{
 33.2726 +    kdbp("sched: show schedular info and run queues\n");
 33.2727 +    return KDB_CPU_MAIN_KDB;
 33.2728 +}
 33.2729 +static kdb_cpu_cmd_t
 33.2730 +kdb_cmdf_sched(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2731 +{
 33.2732 +    if (argc > 1 && *argv[1] == '?')
 33.2733 +        return kdb_usgf_sched();
 33.2734 +
 33.2735 +    kdb_print_sched_info();
 33.2736 +    return KDB_CPU_MAIN_KDB;
 33.2737 +}
 33.2738 +
 33.2739 +/* Display MMU basic and extended info */
 33.2740 +static kdb_cpu_cmd_t
 33.2741 +kdb_usgf_mmu(void)
 33.2742 +{
 33.2743 +    kdbp("mmu: print basic MMU info\n");
 33.2744 +    return KDB_CPU_MAIN_KDB;
 33.2745 +}
 33.2746 +static kdb_cpu_cmd_t
 33.2747 +kdb_cmdf_mmu(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2748 +{
 33.2749 +    if (argc > 1 && *argv[1] == '?')
 33.2750 +        return kdb_usgf_mmu();
 33.2751 +
 33.2752 +    kdbp("MMU Info:\n");
 33.2753 +    kdbp("total  pages: %lx\n", total_pages);
 33.2754 +    kdbp("max page/mfn: %lx\n", max_page);
 33.2755 +    kdbp("frame_table:  %p\n", frame_table);
 33.2756 +    kdbp("DIRECTMAP_VIRT_START:  %lx\n", DIRECTMAP_VIRT_START);
 33.2757 +    kdbp("HYPERVISOR_VIRT_START: %lx\n", HYPERVISOR_VIRT_START);
 33.2758 +    kdbp("HYPERVISOR_VIRT_END:   %lx\n", HYPERVISOR_VIRT_END);
 33.2759 +    kdbp("RO_MPT_VIRT_START:     %lx\n", RO_MPT_VIRT_START);
 33.2760 +    kdbp("PERDOMAIN_VIRT_START:  %lx\n", PERDOMAIN_VIRT_START);
 33.2761 +    kdbp("CONFIG_PAGING_LEVELS:%d\n", CONFIG_PAGING_LEVELS);
 33.2762 +    kdbp("__HYPERVISOR_COMPAT_VIRT_START: %lx\n", 
 33.2763 +         (ulong)__HYPERVISOR_COMPAT_VIRT_START);
 33.2764 +
 33.2765 +    return KDB_CPU_MAIN_KDB;
 33.2766 +}
 33.2767 +
 33.2768 +/* btree: pfn_to_mfn_frame_list_list is root that points (has mfns of) upto 16
 33.2769 + * pages (call 'em l2 nodes) that contain mfns of guest p2m table pages 
 33.2770 + * NOTE: num of entries in a p2m page is same as num of entries in l2 node */
 33.2771 +static noinline ulong
 33.2772 +kdb_gpfn2mfn(struct domain *dp, ulong gpfn) 
 33.2773 +{
 33.2774 +    int idx;
 33.2775 +    mfn_t mfn;
 33.2776 +    p2m_type_t type;
 33.2777 +
 33.2778 +
 33.2779 +    if ((mfn=arch_get_pfn_to_mfn_frame_list_list(dp))) {
 33.2780 +
 33.2781 +        mfn_t *mfn_va = map_domain_page(mfn);
 33.2782 +        int g_longsz = kdb_guest_bitness(dp->domain_id)/8;
 33.2783 +        int entries_per_pg = PAGE_SIZE/g_longsz;
 33.2784 +        const int shift = get_count_order(entries_per_pg);
 33.2785 +
 33.2786 +        idx = gpfn >> 2*shift;     /* index in root page/node */
 33.2787 +        if (idx > 15) {
 33.2788 +            kdbp("gpfn:%lx idx:%x not in frame list limit of z16\n", gpfn, idx);
 33.2789 +            unmap_domain_page(mfn_va);
 33.2790 +            return INVALID_MFN;
 33.2791 +        }
 33.2792 +        mfn = (g_longsz == 4) ? ((int *)mfn_va)[idx] : mfn_va[idx];
 33.2793 +        if (mfn==0) {
 33.2794 +            kdbp("No mfn for idx:%d for gpfn:%lx in root pg\n", idx, gpfn);
 33.2795 +            unmap_domain_page(mfn_va);
 33.2796 +            return INVALID_MFN;
 33.2797 +        }
 33.2798 +        mfn_va = map_domain_page(mfn);
 33.2799 +        KDBGP1("p2m: idx:%x fll:%lx mfn of 2nd lvl page:%lx\n", idx,
 33.2800 +               arch_get_pfn_to_mfn_frame_list_list(dp), mfn);
 33.2801 +
 33.2802 +        idx = (gpfn>>shift) & ((1<<shift)-1);     /* idx in l2 node */
 33.2803 +        mfn = (g_longsz == 4) ? ((int *)mfn_va)[idx] : mfn_va[idx];
 33.2804 +        unmap_domain_page(mfn_va);
 33.2805 +        if (mfn == 0) {
 33.2806 +            kdbp("No mfn entry at:%x in 2nd lvl pg for gpfn:%lx\n", idx, gpfn);
 33.2807 +            return INVALID_MFN;
 33.2808 +        }
 33.2809 +        KDBGP1("p2m: idx:%x  mfn of p2m page:%lx\n", idx, mfn); 
 33.2810 +        mfn_va = map_domain_page(mfn);
 33.2811 +        idx = gpfn & ((1<<shift)-1);
 33.2812 +        mfn = (g_longsz == 4) ? ((int *)mfn_va)[idx] : mfn_va[idx];
 33.2813 +        unmap_domain_page(mfn_va);
 33.2814 +
 33.2815 +        return mfn;
 33.2816 +    } else
 33.2817 +#if XEN_SUBVERSION > 0 
 33.2818 +        return gfn_to_mfn(p2m_get_hostp2m(dp), gpfn, &type);
 33.2819 +#else
 33.2820 +        return gfn_to_mfn(dp, gpfn, &type);
 33.2821 +#endif
 33.2822 +
 33.2823 +    return INVALID_MFN;
 33.2824 +}
 33.2825 +
 33.2826 +/* given a pfn, find it's mfn */
 33.2827 +static kdb_cpu_cmd_t
 33.2828 +kdb_usgf_p2m(void)
 33.2829 +{
 33.2830 +    kdbp("p2m domid 0xgpfn : gpfn to mfn\n");
 33.2831 +    return KDB_CPU_MAIN_KDB;
 33.2832 +}
 33.2833 +static kdb_cpu_cmd_t
 33.2834 +kdb_cmdf_p2m(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2835 +{
 33.2836 +    struct domain *dp;
 33.2837 +    ulong gpfn;
 33.2838 +
 33.2839 +    if (argc < 3                                ||
 33.2840 +        (dp=kdb_strdomid2ptr(argv[1])) == NULL  ||
 33.2841 +        !kdb_str2ulong(argv[2], &gpfn)) {
 33.2842 +
 33.2843 +        return kdb_usgf_p2m();
 33.2844 +    }
 33.2845 +    kdbp("p2m[%lx] == %lx\n", gpfn, kdb_gpfn2mfn(dp, gpfn));
 33.2846 +    return KDB_CPU_MAIN_KDB;
 33.2847 +}
 33.2848 +
 33.2849 +/* given an mfn, lookup pfn in the MPT */
 33.2850 +static kdb_cpu_cmd_t
 33.2851 +kdb_usgf_m2p(void)
 33.2852 +{
 33.2853 +    kdbp("m2p 0xmfn: mfn to pfn\n");
 33.2854 +    return KDB_CPU_MAIN_KDB;
 33.2855 +}
 33.2856 +static kdb_cpu_cmd_t
 33.2857 +kdb_cmdf_m2p(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2858 +{
 33.2859 +    mfn_t mfn;
 33.2860 +    if (argc > 1 && kdb_str2ulong(argv[1], &mfn))
 33.2861 +        kdbp("mpt[%x] == %lx\n", mfn, machine_to_phys_mapping[mfn]);
 33.2862 +    else
 33.2863 +        kdb_usgf_m2p();
 33.2864 +    return KDB_CPU_MAIN_KDB;
 33.2865 +}
 33.2866 +
 33.2867 +static void 
 33.2868 +kdb_pr_pg_pgt_flds(unsigned long type_info)
 33.2869 +{
 33.2870 +    switch (type_info & PGT_type_mask) {
 33.2871 +        case (PGT_l1_page_table):
 33.2872 +            kdbp("    page is PGT_l1_page_table\n");
 33.2873 +            break;
 33.2874 +        case PGT_l2_page_table:
 33.2875 +            kdbp("    page is PGT_l2_page_table\n");
 33.2876 +            break;
 33.2877 +        case PGT_l3_page_table:
 33.2878 +            kdbp("    page is PGT_l3_page_table\n");
 33.2879 +            break;
 33.2880 +        case PGT_l4_page_table:
 33.2881 +            kdbp("    page is PGT_l4_page_table\n");
 33.2882 +            break;
 33.2883 +        case PGT_seg_desc_page:
 33.2884 +            kdbp("    page is seg desc page\n");
 33.2885 +            break;
 33.2886 +        case PGT_writable_page:
 33.2887 +            kdbp("    page is writable page\n");
 33.2888 +            break;
 33.2889 +    }
 33.2890 +    if (type_info & PGT_pinned)
 33.2891 +        kdbp("    page is pinned\n");
 33.2892 +    if (type_info & PGT_validated)
 33.2893 +        kdbp("    page is validated\n");
 33.2894 +    if (type_info & PGT_pae_xen_l2)
 33.2895 +        kdbp("    page is PGT_pae_xen_l2\n");
 33.2896 +    if (type_info & PGT_partial)
 33.2897 +        kdbp("    page is PGT_partial\n");
 33.2898 +    if (type_info & PGT_locked)
 33.2899 +        kdbp("    page is PGT_locked\n");
 33.2900 +}
 33.2901 +
 33.2902 +static void
 33.2903 +kdb_pr_pg_pgc_flds(unsigned long count_info)
 33.2904 +{
 33.2905 +    if (count_info & PGC_allocated)
 33.2906 +        kdbp("  PGC_allocated");
 33.2907 +    if (count_info & PGC_xen_heap)
 33.2908 +        kdbp("  PGC_xen_heap");
 33.2909 +    if (count_info & PGC_page_table)
 33.2910 +        kdbp("  PGC_page_table");
 33.2911 +    if (count_info & PGC_broken)
 33.2912 +        kdbp("  PGC_broken");
 33.2913 +#if XEN_VERSION < 4                                 /* xen 3.x.x */
 33.2914 +    if (count_info & PGC_offlining)
 33.2915 +        kdbp("  PGC_offlining");
 33.2916 +    if (count_info & PGC_offlined)
 33.2917 +        kdbp("  PGC_offlined");
 33.2918 +#else
 33.2919 +    if (count_info & PGC_state_inuse)
 33.2920 +        kdbp("  PGC_inuse");
 33.2921 +    if (count_info & PGC_state_offlining)
 33.2922 +        kdbp("  PGC_state_offlining");
 33.2923 +    if (count_info & PGC_state_offlined)
 33.2924 +        kdbp("  PGC_state_offlined");
 33.2925 +    if (count_info & PGC_state_free)
 33.2926 +        kdbp("  PGC_state_free");
 33.2927 +#endif
 33.2928 +    kdbp("\n");
 33.2929 +}
 33.2930 +
 33.2931 +/* print struct page_info{} given ptr to it or an mfn
 33.2932 + * NOTE: that given an mfn there seems no way of knowing how it's used, so
 33.2933 + *       here we just print all info and let user decide what's applicable */
 33.2934 +static kdb_cpu_cmd_t
 33.2935 +kdb_usgf_dpage(void)
 33.2936 +{
 33.2937 +    kdbp("dpage mfn|page-ptr : Display struct page\n");
 33.2938 +    return KDB_CPU_MAIN_KDB;
 33.2939 +}
 33.2940 +static kdb_cpu_cmd_t
 33.2941 +kdb_cmdf_dpage(int argc, const char **argv, struct cpu_user_regs *regs)
 33.2942 +{
 33.2943 +    unsigned long val;
 33.2944 +    struct page_info *pgp;
 33.2945 +    struct domain *dp;
 33.2946 +
 33.2947 +    if (argc <= 1 || *argv[1] == '?') 
 33.2948 +        return kdb_usgf_dpage();
 33.2949 +
 33.2950 +    if ((kdb_str2ulong(argv[1], &val) == 0)      ||
 33.2951 +        (val <  (ulong)frame_table && !mfn_valid(val))) {
 33.2952 +
 33.2953 +        kdbp("Invalid arg:%s\n", argv[1]);
 33.2954 +        return KDB_CPU_MAIN_KDB;
 33.2955 +    }
 33.2956 +    kdbp("Page Info:\n");
 33.2957 +    if (val <= (ulong)frame_table) {       /* arg is mfn */
 33.2958 +        pgp = mfn_to_page(val);
 33.2959 +        kdbp("  mfn: %lx page_info:%p\n", val, pgp);
 33.2960 +    } else {
 33.2961 +        pgp = (struct page_info *)val; /* arg is struct page{} */
 33.2962 +        if (pgp < frame_table || pgp >= frame_table+max_page) {
 33.2963 +            kdbp("Invalid page ptr. below/beyond max_page\n");
 33.2964 +            return KDB_CPU_MAIN_KDB;
 33.2965 +        }
 33.2966 +        kdbp("  mfn: %lx page_info:%p\n", page_to_mfn(pgp), pgp);
 33.2967 +    } 
 33.2968 +    kdbp("  count_info: %x  (refcnt: %x)\n", pgp->count_info,
 33.2969 +         pgp->count_info & PGC_count_mask);
 33.2970 +#if XEN_VERSION > 3 || XEN_SUBVERSION > 3             /* xen 3.4.x or later */
 33.2971 +    kdb_pr_pg_pgc_flds(pgp->count_info);
 33.2972 +
 33.2973 +    kdbp("In use info:\n");
 33.2974 +    kdbp("  type_info:%x\n", pgp->u.inuse.type_info);
 33.2975 +    kdb_pr_pg_pgt_flds(pgp->u.inuse.type_info);
 33.2976 +    dp = page_get_owner(pgp);
 33.2977 +    kdbp("  domid:%d (pickled:%lx)\n", dp ? dp->domain_id : -1, 
 33.2978 +         pgp->v.inuse._domain);
 33.2979 +
 33.2980 +    kdbp("Shadow Info:\n");
 33.2981 +    kdbp("  type:%x pinned:%x count:%x\n", pgp->u.sh.type, pgp->u.sh.pinned,
 33.2982 +         pgp->u.sh.count);
 33.2983 +    kdbp("  back:%lx  shadow_flags:%x  next_shadow:%lx\n", pgp->v.sh.back,
 33.2984 +         pgp->shadow_flags, pgp->next_shadow);
 33.2985 +
 33.2986 +    kdbp("Free Info\n");
 33.2987 +    kdbp("  need_tlbflush:%d order:%d tlbflush_timestamp:%x\n",
 33.2988 +         pgp->u.free.need_tlbflush, pgp->v.free.order, 
 33.2989 +         pgp->tlbflush_timestamp);
 33.2990 +#else
 33.2991 +    if (pgp->count_info & PGC_allocated)            /* page allocated */
 33.2992 +        kdbp("  PGC_allocated");
 33.2993 +    if (pgp->count_info & PGC_page_table)           /* page table page */
 33.2994 +        kdbp("  PGC_page_table");
 33.2995 +    kdbp("\n");
 33.2996 +    kdbp("  page is %s xen heap page\n", is_xen_heap_page(pgp) ? "a":"NOT");
 33.2997 +    kdbp("  cacheattr:%x\n", (pgp->count_info>>PGC_cacheattr_base) & 7);
 33.2998 +    if (pgp->count_info & PGC_count_mask) {         /* page in use */
 33.2999 +        dp = pgp->u.inuse._domain;         /* pickled domain */
 33.3000 +        kdbp("  page is in use\n");
 33.3001 +        kdbp("    domid: %d  (pickled dom:%x)\n", 
 33.3002 +             dp ? (unpickle_domptr(dp))->domain_id : -1, dp);
 33.3003 +        kdbp("    type_info: %lx\n", pgp->u.inuse.type_info);
 33.3004 +        kdb_prt_pg_type(pgp->u.inuse.type_info);
 33.3005 +    } else {                                         /* page is free */
 33.3006 +        kdbp("  page is free\n");
 33.3007 +        kdbp("    order: %x\n", pgp->u.free.order);
 33.3008 +        kdbp("    cpumask: %lx\n", pgp->u.free.cpumask.bits);
 33.3009 +    }
 33.3010 +    kdbp("  tlbflush/shadow_flags: %lx\n", pgp->shadow_flags);
 33.3011 +#endif
 33.3012 +    return KDB_CPU_MAIN_KDB;
 33.3013 +}
 33.3014 +
 33.3015 +/* display asked msr value */
 33.3016 +static kdb_cpu_cmd_t
 33.3017 +kdb_usgf_dmsr(void)
 33.3018 +{
 33.3019 +    kdbp("dmsr address : Display msr value\n");
 33.3020 +    return KDB_CPU_MAIN_KDB;
 33.3021 +}
 33.3022 +static kdb_cpu_cmd_t
 33.3023 +kdb_cmdf_dmsr(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3024 +{
 33.3025 +    unsigned long addr, val;
 33.3026 +
 33.3027 +    if (argc <= 1 || *argv[1] == '?') 
 33.3028 +        return kdb_usgf_dmsr();
 33.3029 +
 33.3030 +    if ((kdb_str2ulong(argv[1], &addr) == 0)) {
 33.3031 +        kdbp("Invalid arg:%s\n", argv[1]);
 33.3032 +        return KDB_CPU_MAIN_KDB;
 33.3033 +    }
 33.3034 +    rdmsrl(addr, val);
 33.3035 +    kdbp("msr: %lx  val:%lx\n", addr, val);
 33.3036 +
 33.3037 +    return KDB_CPU_MAIN_KDB;
 33.3038 +}
 33.3039 +
 33.3040 +/* execute cpuid for given value */
 33.3041 +static kdb_cpu_cmd_t
 33.3042 +kdb_usgf_cpuid(void)
 33.3043 +{
 33.3044 +    kdbp("cpuid eax : Display cpuid value returned in rax\n");
 33.3045 +    return KDB_CPU_MAIN_KDB;
 33.3046 +}
 33.3047 +static kdb_cpu_cmd_t
 33.3048 +kdb_cmdf_cpuid(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3049 +{
 33.3050 +    unsigned long rax=0, rbx=0, rcx=0, rdx=0;
 33.3051 +
 33.3052 +    if (argc <= 1 || *argv[1] == '?') 
 33.3053 +        return kdb_usgf_cpuid();
 33.3054 +
 33.3055 +    if ((kdb_str2ulong(argv[1], &rax) == 0)) {
 33.3056 +        kdbp("Invalid arg:%s\n", argv[1]);
 33.3057 +        return KDB_CPU_MAIN_KDB;
 33.3058 +    }
 33.3059 +#if 0
 33.3060 +    __asm__ __volatile__ (
 33.3061 +            /* "pushl %%rax  \n" */
 33.3062 +
 33.3063 +            "movl %0, %%rax  \n"
 33.3064 +            "cpuid           \n" 
 33.3065 +            : "=&a" (rax), "=b" (rbx), "=c" (rcx), "=d" (rdx)
 33.3066 +            : "0" (rax)
 33.3067 +            : "rax", "rbx", "rcx", "rdx", "memory");
 33.3068 +#endif
 33.3069 +    cpuid(rax, &rax, &rbx, &rcx, &rdx);
 33.3070 +    kdbp("rax: %016lx  rbx:%016lx rcx:%016lx rdx:%016lx\n", rax, rbx,
 33.3071 +         rcx, rdx);
 33.3072 +    return KDB_CPU_MAIN_KDB;
 33.3073 +}
 33.3074 +
 33.3075 +/*
 33.3076 + * Save symbols info for a guest, dom0 or other...
 33.3077 + */
 33.3078 +static kdb_cpu_cmd_t
 33.3079 +kdb_usgf_sym(void)
 33.3080 +{
 33.3081 +   kdbp("sym domid &kallsyms_names &kallsyms_addresses &kallsyms_num_syms\n");
 33.3082 +   kdbp("\t [&kallsyms_token_table] [&kallsyms_token_index]\n");
 33.3083 +   kdbp("\ttoken _table and _index MUST be specified for el5\n");
 33.3084 +   return KDB_CPU_MAIN_KDB;
 33.3085 +}
 33.3086 +static kdb_cpu_cmd_t
 33.3087 +kdb_cmdf_sym(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3088 +{
 33.3089 +    ulong namesp, addrap, nump, toktblp, tokidxp;
 33.3090 +    domid_t domid;
 33.3091 +
 33.3092 +    if (argc < 5) {
 33.3093 +        return kdb_usgf_sym();
 33.3094 +    }
 33.3095 +    toktblp = tokidxp = 0;     /* optional parameters */
 33.3096 +    if (kdb_str2domid(argv[1], &domid, 1) &&
 33.3097 +        kdb_str2ulong(argv[2], &namesp)   &&
 33.3098 +        kdb_str2ulong(argv[3], &addrap)   &&
 33.3099 +        kdb_str2ulong(argv[4], &nump)     && 
 33.3100 +        (argc==5 || (argc==7 && kdb_str2ulong(argv[5], &toktblp) &&
 33.3101 +                                kdb_str2ulong(argv[6], &tokidxp)))) {
 33.3102 +
 33.3103 +        kdb_sav_dom_syminfo(domid, namesp, addrap,nump,toktblp,tokidxp);
 33.3104 +    } else
 33.3105 +        kdb_usgf_sym();
 33.3106 +    return KDB_CPU_MAIN_KDB;
 33.3107 +}
 33.3108 +
 33.3109 +
 33.3110 +/* mods is the dumb ass &modules. modules is struct {nxt, prev}, and not ptr */
 33.3111 +static void
 33.3112 +kdb_dump_linux_modules(domid_t domid, ulong mods, uint nxtoffs, uint nmoffs, 
 33.3113 +                       uint coreoffs)
 33.3114 +{
 33.3115 +    const int bufsz = 56;
 33.3116 +    char buf[bufsz];
 33.3117 +    uint64_t addr, addrval, *nxtptr, *modptr;
 33.3118 +    uint i, num = 8;
 33.3119 +
 33.3120 +    if (kdb_guest_bitness(domid) == 32)
 33.3121 +        num = 4;
 33.3122 +
 33.3123 +    /* first read modules{}.next ptr */
 33.3124 +    if (kdb_read_mem(mods, (kdbbyt_t *)&nxtptr, num, domid) != num) {
 33.3125 +        kdbp("ERROR: Could not read next at mod:%p\n", (void *)mods);
 33.3126 +        return;
 33.3127 +    }
 33.3128 +
 33.3129 +    KDBGP("mods:%p nxtptr:%p nmoffs:%x coreoffs:%x\n", (void *)mods, nxtptr,
 33.3130 +          nmoffs, coreoffs);
 33.3131 +
 33.3132 +    while ((uint64_t)nxtptr != mods) {
 33.3133 +
 33.3134 +        modptr = (uint64_t *) ((ulong)nxtptr - nxtoffs);
 33.3135 +
 33.3136 +        addr = (ulong)modptr + coreoffs;
 33.3137 +        if (kdb_read_mem(addr, (kdbbyt_t *)&addrval, num, domid) != num) {
 33.3138 +            kdbp("ERROR: Could not read mod addr at :%p\n", (void *)addr);
 33.3139 +            return;
 33.3140 +        }
 33.3141 +
 33.3142 +        KDBGP("modptr:%p addr:%p\n", modptr, (void *)addr);
 33.3143 +        addr = (ulong)modptr + nmoffs;
 33.3144 +        i=0;
 33.3145 +        do {
 33.3146 +            if (kdb_read_mem(addr, (kdbbyt_t *)&buf[i], 1, domid) != 1) {
 33.3147 +                kdbp("ERROR:Could not read name ch at addr:%p\n", (void *)addr);
 33.3148 +                return;
 33.3149 +            }
 33.3150 +            addr++;
 33.3151 +        } while (buf[i] && i++ < bufsz);
 33.3152 +        buf[bufsz-1] = '\0';
 33.3153 +
 33.3154 +        kdbp("%016lx %016lx %s\n", modptr, addrval, buf);
 33.3155 +
 33.3156 +        if (kdb_read_mem((ulong)nxtptr, (kdbbyt_t *)&nxtptr, num, domid)!=num) {
 33.3157 +            kdbp("ERROR: Could not read next at mod:%p\n", (void *)mods);
 33.3158 +            return;
 33.3159 +        }
 33.3160 +        KDBGP("nxtptr:%p addr:%p\n", nxtptr, (void *)addr);
 33.3161 +    } 
 33.3162 +}
 33.3163 +
 33.3164 +/* Display modules loaded in linux guest */
 33.3165 +static kdb_cpu_cmd_t
 33.3166 +kdb_usgf_mod(void)
 33.3167 +{
 33.3168 +   kdbp("mod domid &modules next-offs name-offs module_core-offs\n");
 33.3169 +   kdbp("\twhere next-offs: &((struct module *)0)->list.next\n");
 33.3170 +   kdbp("\tname-offs: &((struct module *)0)->name etc..\n");
 33.3171 +   kdbp("\tDisplays all loaded modules in the linux guest\n");
 33.3172 +   kdbp("\tEg: mod 0 ffffffff80302780 8 0x18 0x178\n");
 33.3173 +
 33.3174 +   return KDB_CPU_MAIN_KDB;
 33.3175 +}
 33.3176 +
 33.3177 +static kdb_cpu_cmd_t
 33.3178 +kdb_cmdf_mod(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3179 +{
 33.3180 +    ulong mods, nxtoffs, nmoffs, coreoffs;
 33.3181 +    domid_t domid;
 33.3182 +
 33.3183 +    if (argc < 6) {
 33.3184 +        return kdb_usgf_mod();
 33.3185 +    }
 33.3186 +    if (kdb_str2domid(argv[1], &domid, 1) &&
 33.3187 +        kdb_str2ulong(argv[2], &mods)     &&
 33.3188 +        kdb_str2ulong(argv[3], &nxtoffs)  &&
 33.3189 +        kdb_str2ulong(argv[4], &nmoffs)   &&
 33.3190 +        kdb_str2ulong(argv[5], &coreoffs)) {
 33.3191 +
 33.3192 +        kdbp("modptr address name\n");
 33.3193 +        kdb_dump_linux_modules(domid, mods, nxtoffs, nmoffs, coreoffs);
 33.3194 +    } else
 33.3195 +        kdb_usgf_mod();
 33.3196 +    return KDB_CPU_MAIN_KDB;
 33.3197 +}
 33.3198 +
 33.3199 +/* toggle kdb debug trace level */
 33.3200 +static kdb_cpu_cmd_t
 33.3201 +kdb_usgf_kdbdbg(void)
 33.3202 +{
 33.3203 +    kdbp("kdbdbg : trace info to debug kdb\n");
 33.3204 +    return KDB_CPU_MAIN_KDB;
 33.3205 +}
 33.3206 +static kdb_cpu_cmd_t
 33.3207 +kdb_cmdf_kdbdbg(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3208 +{
 33.3209 +    if (argc > 1 && *argv[1] == '?')
 33.3210 +        return kdb_usgf_kdbdbg();
 33.3211 +
 33.3212 +    kdbdbg = (kdbdbg==3) ? 0 : (kdbdbg+1);
 33.3213 +    kdbp("kdbdbg set to:%d\n", kdbdbg);
 33.3214 +    return KDB_CPU_MAIN_KDB;
 33.3215 +}
 33.3216 +
 33.3217 +static kdb_cpu_cmd_t
 33.3218 +kdb_usgf_reboot(void)
 33.3219 +{
 33.3220 +    kdbp("reboot: reboot system\n");
 33.3221 +    return KDB_CPU_MAIN_KDB;
 33.3222 +}
 33.3223 +static kdb_cpu_cmd_t
 33.3224 +kdb_cmdf_reboot(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3225 +{
 33.3226 +    if (argc > 1 && *argv[1] == '?')
 33.3227 +        return kdb_usgf_reboot();
 33.3228 +
 33.3229 +    machine_restart(500);
 33.3230 +    return KDB_CPU_MAIN_KDB;              /* not reached */
 33.3231 +}
 33.3232 +
 33.3233 +
 33.3234 +static kdb_cpu_cmd_t
 33.3235 +kdb_usgf_trcon(void)
 33.3236 +{
 33.3237 +    kdbp("trcon: turn user added kdb tracing on\n");
 33.3238 +    return KDB_CPU_MAIN_KDB;
 33.3239 +}
 33.3240 +static kdb_cpu_cmd_t
 33.3241 +kdb_cmdf_trcon(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3242 +{
 33.3243 +    if (argc > 1 && *argv[1] == '?')
 33.3244 +        return kdb_usgf_trcon();
 33.3245 +
 33.3246 +    kdb_trcon = 1;
 33.3247 +    kdbp("kdb tracing is now on\n");
 33.3248 +    return KDB_CPU_MAIN_KDB;
 33.3249 +}
 33.3250 +
 33.3251 +static kdb_cpu_cmd_t
 33.3252 +kdb_usgf_trcoff(void)
 33.3253 +{
 33.3254 +    kdbp("trcoff: turn user added kdb tracing off\n");
 33.3255 +    return KDB_CPU_MAIN_KDB;
 33.3256 +}
 33.3257 +static kdb_cpu_cmd_t
 33.3258 +kdb_cmdf_trcoff(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3259 +{
 33.3260 +    if (argc > 1 && *argv[1] == '?')
 33.3261 +        return kdb_usgf_trcoff();
 33.3262 +
 33.3263 +    kdb_trcon = 0;
 33.3264 +    kdbp("kdb tracing is now off\n");
 33.3265 +    return KDB_CPU_MAIN_KDB;
 33.3266 +}
 33.3267 +
 33.3268 +static kdb_cpu_cmd_t
 33.3269 +kdb_usgf_trcz(void)
 33.3270 +{
 33.3271 +    kdbp("trcz : zero entire trace buffer\n");
 33.3272 +    return KDB_CPU_MAIN_KDB;
 33.3273 +}
 33.3274 +static kdb_cpu_cmd_t
 33.3275 +kdb_cmdf_trcz(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3276 +{
 33.3277 +    if (argc > 1 && *argv[1] == '?')
 33.3278 +        return kdb_usgf_trcz();
 33.3279 +
 33.3280 +    kdb_trczero();
 33.3281 +    return KDB_CPU_MAIN_KDB;
 33.3282 +}
 33.3283 +
 33.3284 +static kdb_cpu_cmd_t
 33.3285 +kdb_usgf_trcp(void)
 33.3286 +{
 33.3287 +    kdbp("trcp : give hints to dump trace buffer via dw/dd command\n");
 33.3288 +    return KDB_CPU_MAIN_KDB;
 33.3289 +}
 33.3290 +static kdb_cpu_cmd_t
 33.3291 +kdb_cmdf_trcp(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3292 +{
 33.3293 +    if (argc > 1 && *argv[1] == '?')
 33.3294 +        return kdb_usgf_trcp();
 33.3295 +
 33.3296 +    kdb_trcp();
 33.3297 +    return KDB_CPU_MAIN_KDB;
 33.3298 +}
 33.3299 +
 33.3300 +/* print some basic info, constants, etc.. */
 33.3301 +static kdb_cpu_cmd_t
 33.3302 +kdb_usgf_info(void)
 33.3303 +{
 33.3304 +    kdbp("info : display basic info, constants, etc..\n");
 33.3305 +    return KDB_CPU_MAIN_KDB;
 33.3306 +}
 33.3307 +static kdb_cpu_cmd_t
 33.3308 +kdb_cmdf_info(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3309 +{
 33.3310 +    struct domain *dp;
 33.3311 +    struct cpuinfo_x86 *bcdp;
 33.3312 +
 33.3313 +    if (argc > 1 && *argv[1] == '?')
 33.3314 +        return kdb_usgf_info();
 33.3315 +
 33.3316 +    kdbp("Version: %d.%d.%s (%s@%s) %s\n", xen_major_version(), 
 33.3317 +         xen_minor_version(), xen_extra_version(), xen_compile_by(), 
 33.3318 +         xen_compile_domain(), xen_compile_date());
 33.3319 +    kdbp("__XEN_LATEST_INTERFACE_VERSION__ : 0x%x\n", 
 33.3320 +         __XEN_LATEST_INTERFACE_VERSION__);
 33.3321 +    kdbp("__XEN_INTERFACE_VERSION__: 0x%x\n", __XEN_INTERFACE_VERSION__);
 33.3322 +
 33.3323 +    bcdp = &boot_cpu_data;
 33.3324 +    kdbp("CPU: (all decimal)");
 33.3325 +        if (bcdp->x86_vendor == X86_VENDOR_AMD)
 33.3326 +            kdbp(" AMD");
 33.3327 +        else
 33.3328 +            kdbp(" INTEL");
 33.3329 +        kdbp(" family:%d model:%d\n", bcdp->x86, bcdp->x86_model);
 33.3330 +        kdbp("     vendor_id:%16s model_id:%64s\n", bcdp->x86_vendor_id,
 33.3331 +             bcdp->x86_model_id);
 33.3332 +        kdbp("     cpuidlvl:%d cache:sz:%d align:%d\n", bcdp->cpuid_level,
 33.3333 +             bcdp->x86_cache_size, bcdp->x86_cache_alignment);
 33.3334 +        kdbp("     power:%d cores: max:%d booted:%d siblings:%d apicid:%d\n",
 33.3335 +             bcdp->x86_power, bcdp->x86_max_cores, bcdp->booted_cores,
 33.3336 +             bcdp->x86_num_siblings, bcdp->apicid);
 33.3337 +        kdbp("     ");
 33.3338 +        if (cpu_has_apic)
 33.3339 +            kdbp("_apic");
 33.3340 +        if (cpu_has_sep)
 33.3341 +            kdbp("|_sep");
 33.3342 +        if (cpu_has_xmm3)
 33.3343 +            kdbp("|_xmm3");
 33.3344 +        if (cpu_has_ht)
 33.3345 +            kdbp("|_ht");
 33.3346 +        if (cpu_has_nx)
 33.3347 +            kdbp("|_nx");
 33.3348 +        if (cpu_has_clflush)
 33.3349 +            kdbp("|_clflush");
 33.3350 +        if (cpu_has_page1gb)
 33.3351 +            kdbp("|_page1gb");
 33.3352 +        if (cpu_has_ffxsr)
 33.3353 +            kdbp("|_ffxsr");
 33.3354 +        if (cpu_has_x2apic)
 33.3355 +            kdbp("|_x2apic");
 33.3356 +    kdbp("\n\n");
 33.3357 +    kdbp("CC:");
 33.3358 +#if defined(CONFIG_X86_64)
 33.3359 +        kdbp(" CONFIG_X86_64");
 33.3360 +#endif
 33.3361 +#if defined(CONFIG_COMPAT)
 33.3362 +        kdbp(" CONFIG_COMPAT");
 33.3363 +#endif
 33.3364 +#if defined(CONFIG_PAGING_ASSISTANCE)
 33.3365 +        kdbp(" CONFIG_PAGING_ASSISTANCE");
 33.3366 +#endif
 33.3367 +    kdbp("\n");
 33.3368 +    kdbp("NR_EVENT_CHANNELS: $%d\n", NR_EVENT_CHANNELS);
 33.3369 +    kdbp("NR_EVTCHN_BUCKETS: $%d\n", NR_EVTCHN_BUCKETS);
 33.3370 +
 33.3371 +    kdbp("\nDomains and their vcpus:\n");
 33.3372 +    for_each_domain(dp) {
 33.3373 +        struct vcpu *vp;
 33.3374 +        int printed=0;
 33.3375 +        kdbp("  Domain: {id:%d 0x%x   ptr:%p%s}  VCPUs:\n", 
 33.3376 +             dp->domain_id, dp->domain_id, dp, dp->is_dying ? " DYING":"");
 33.3377 +        for(vp=dp->vcpu[0]; vp; vp = vp->next_in_list) {
 33.3378 +            kdbp("  {id:%d p:%p runstate:%d}", vp->vcpu_id, vp, 
 33.3379 +                 vp->runstate.state);
 33.3380 +            if (++printed % 2 == 0) kdbp("\n");
 33.3381 +        }
 33.3382 +        kdbp("\n");
 33.3383 +    }
 33.3384 +    return KDB_CPU_MAIN_KDB;
 33.3385 +}
 33.3386 +
 33.3387 +static kdb_cpu_cmd_t
 33.3388 +kdb_usgf_cur(void)
 33.3389 +{
 33.3390 +    kdbp("cur : display current domid and vcpu\n");
 33.3391 +    return KDB_CPU_MAIN_KDB;
 33.3392 +}
 33.3393 +
 33.3394 +/* Checking for guest_mode() not feasible here. if dom0->hcall->bp in xen, 
 33.3395 + * then g_m() will show xen, but vcpu is still dom0. hence just look at 
 33.3396 + * current only */
 33.3397 +static kdb_cpu_cmd_t
 33.3398 +kdb_cmdf_cur(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3399 +{
 33.3400 +    domid_t id = current->domain->domain_id;
 33.3401 +
 33.3402 +    if (argc > 1 && *argv[1] == '?')
 33.3403 +        return kdb_usgf_info();
 33.3404 +
 33.3405 +    kdbp("Current domid: %d {%p} %s  vcpuid:%d {%p}\n", id, current->domain,
 33.3406 +         (id==DOMID_IDLE) ? "(IDLE)" : "", current->vcpu_id, current);
 33.3407 +    return KDB_CPU_MAIN_KDB;
 33.3408 +}
 33.3409 +
 33.3410 +/* stub to quickly and easily add a new command */
 33.3411 +static kdb_cpu_cmd_t
 33.3412 +kdb_usgf_usr1(void)
 33.3413 +{
 33.3414 +    kdbp("usr1: add any arbitrary cmd using this in kdb_cmds.c\n");
 33.3415 +    return KDB_CPU_MAIN_KDB;
 33.3416 +}
 33.3417 +static kdb_cpu_cmd_t
 33.3418 +kdb_cmdf_usr1(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3419 +{
 33.3420 +    return KDB_CPU_MAIN_KDB;
 33.3421 +}
 33.3422 +
 33.3423 +static kdb_cpu_cmd_t
 33.3424 +kdb_usgf_h(void)
 33.3425 +{
 33.3426 +    kdbp("h: display all commands. See kdb/README for more info\n");
 33.3427 +    return KDB_CPU_MAIN_KDB;
 33.3428 +}
 33.3429 +static kdb_cpu_cmd_t
 33.3430 +kdb_cmdf_h(int argc, const char **argv, struct cpu_user_regs *regs)
 33.3431 +{
 33.3432 +    kdbtab_t *tbp;
 33.3433 +
 33.3434 +    kdbp(" - ccpu is current cpu \n");
 33.3435 +    kdbp(" - following are always in decimal:\n");
 33.3436 +    kdbp("     vcpu num, cpu num, domid\n");
 33.3437 +    kdbp(" - otherwise, almost all numbers are in hex (0x not needed)\n");
 33.3438 +    kdbp(" - output: $17 means decimal 17\n");
 33.3439 +    kdbp(" - domid 7fff($32767) refers to hypervisor\n");
 33.3440 +    kdbp(" - if no domid before function name, then it's hypervisor\n");
 33.3441 +    kdbp(" - earlykdb in xen grub line to break into kdb during boot\n");
 33.3442 +    kdbp(" - command ? will show the command usage\n");
 33.3443 +    kdbp("\n");
 33.3444 +
 33.3445 +    for(tbp=kdb_cmd_tbl; tbp->kdb_cmd_usgf; tbp++)
 33.3446 +        (*tbp->kdb_cmd_usgf)();
 33.3447 +    return KDB_CPU_MAIN_KDB;
 33.3448 +}
 33.3449 +
 33.3450 +/* ===================== cmd table initialization ========================== */
 33.3451 +void __init
 33.3452 +kdb_init_cmdtab(void)
 33.3453 +{
 33.3454 +  static kdbtab_t _kdb_cmd_table[] = {
 33.3455 +
 33.3456 +    {"info", kdb_cmdf_info, kdb_usgf_info, 1, KDB_REPEAT_NONE},
 33.3457 +    {"cur",  kdb_cmdf_cur, kdb_usgf_cur, 1, KDB_REPEAT_NONE},
 33.3458 +
 33.3459 +    {"f",  kdb_cmdf_f,  kdb_usgf_f,  1, KDB_REPEAT_NONE},
 33.3460 +    {"fg", kdb_cmdf_fg, kdb_usgf_fg, 1, KDB_REPEAT_NONE},
 33.3461 +
 33.3462 +    {"dw",  kdb_cmdf_dw,  kdb_usgf_dw,  1, KDB_REPEAT_NO_ARGS},
 33.3463 +    {"dd",  kdb_cmdf_dd,  kdb_usgf_dd,  1, KDB_REPEAT_NO_ARGS},
 33.3464 +    {"dwm", kdb_cmdf_dwm, kdb_usgf_dwm, 1, KDB_REPEAT_NO_ARGS},
 33.3465 +    {"ddm", kdb_cmdf_ddm, kdb_usgf_ddm, 1, KDB_REPEAT_NO_ARGS},
 33.3466 +    {"dr",  kdb_cmdf_dr,  kdb_usgf_dr,  1, KDB_REPEAT_NONE},
 33.3467 +    {"drg", kdb_cmdf_drg, kdb_usgf_drg, 1, KDB_REPEAT_NONE},
 33.3468 +
 33.3469 +    {"dis", kdb_cmdf_dis,  kdb_usgf_dis,  1, KDB_REPEAT_NO_ARGS},
 33.3470 +    {"dism",kdb_cmdf_dism, kdb_usgf_dism, 1, KDB_REPEAT_NO_ARGS},
 33.3471 +
 33.3472 +    {"mw", kdb_cmdf_mw, kdb_usgf_mw, 1, KDB_REPEAT_NONE},
 33.3473 +    {"md", kdb_cmdf_md, kdb_usgf_md, 1, KDB_REPEAT_NONE},
 33.3474 +    {"mr", kdb_cmdf_mr, kdb_usgf_mr, 1, KDB_REPEAT_NONE},
 33.3475 +
 33.3476 +    {"bc", kdb_cmdf_bc, kdb_usgf_bc, 0, KDB_REPEAT_NONE},
 33.3477 +    {"bp", kdb_cmdf_bp, kdb_usgf_bp, 1, KDB_REPEAT_NONE},
 33.3478 +    {"btp", kdb_cmdf_btp, kdb_usgf_btp, 1, KDB_REPEAT_NONE},
 33.3479 +
 33.3480 +    {"wp", kdb_cmdf_wp, kdb_usgf_wp, 1, KDB_REPEAT_NONE},
 33.3481 +    {"wc", kdb_cmdf_wc, kdb_usgf_wc, 0, KDB_REPEAT_NONE},
 33.3482 +
 33.3483 +    {"ni", kdb_cmdf_ni, kdb_usgf_ni, 0, KDB_REPEAT_NO_ARGS},
 33.3484 +    {"ss", kdb_cmdf_ss, kdb_usgf_ss, 1, KDB_REPEAT_NO_ARGS},
 33.3485 +    {"ssb",kdb_cmdf_ssb,kdb_usgf_ssb,0, KDB_REPEAT_NO_ARGS},
 33.3486 +    {"go", kdb_cmdf_go, kdb_usgf_go, 0, KDB_REPEAT_NONE},
 33.3487 +
 33.3488 +    {"cpu",kdb_cmdf_cpu, kdb_usgf_cpu, 1, KDB_REPEAT_NONE},
 33.3489 +    {"nmi",kdb_cmdf_nmi, kdb_usgf_nmi, 1, KDB_REPEAT_NONE},
 33.3490 +
 33.3491 +    {"sym",  kdb_cmdf_sym,   kdb_usgf_sym,   1, KDB_REPEAT_NONE},
 33.3492 +    {"mod",  kdb_cmdf_mod,   kdb_usgf_mod,   1, KDB_REPEAT_NONE},
 33.3493 +
 33.3494 +    {"vcpuh",kdb_cmdf_vcpuh, kdb_usgf_vcpuh, 1, KDB_REPEAT_NONE},
 33.3495 +    {"vcpu", kdb_cmdf_vcpu,  kdb_usgf_vcpu,  1, KDB_REPEAT_NONE},
 33.3496 +    {"dom",  kdb_cmdf_dom,   kdb_usgf_dom,   1, KDB_REPEAT_NONE},
 33.3497 +
 33.3498 +    {"sched", kdb_cmdf_sched, kdb_usgf_sched, 1, KDB_REPEAT_NONE},
 33.3499 +    {"mmu",   kdb_cmdf_mmu,   kdb_usgf_mmu,   1, KDB_REPEAT_NONE},
 33.3500 +    {"p2m",   kdb_cmdf_p2m,   kdb_usgf_p2m,   1, KDB_REPEAT_NONE},
 33.3501 +    {"m2p",   kdb_cmdf_m2p,   kdb_usgf_m2p,   1, KDB_REPEAT_NONE},
 33.3502 +    {"dpage", kdb_cmdf_dpage, kdb_usgf_dpage, 1, KDB_REPEAT_NONE},
 33.3503 +    {"dmsr",  kdb_cmdf_dmsr,  kdb_usgf_dmsr, 1, KDB_REPEAT_NONE},
 33.3504 +    {"cpuid",  kdb_cmdf_cpuid,  kdb_usgf_cpuid, 1, KDB_REPEAT_NONE},
 33.3505 +
 33.3506 +    {"dtrq", kdb_cmdf_dtrq,  kdb_usgf_dtrq, 1, KDB_REPEAT_NONE},
 33.3507 +    {"didt", kdb_cmdf_didt,  kdb_usgf_didt, 1, KDB_REPEAT_NONE},
 33.3508 +    {"dgdt", kdb_cmdf_dgdt,  kdb_usgf_dgdt, 1, KDB_REPEAT_NONE},
 33.3509 +    {"dirq", kdb_cmdf_dirq,  kdb_usgf_dirq, 1, KDB_REPEAT_NONE},
 33.3510 +    {"dvit", kdb_cmdf_dvit,  kdb_usgf_dvit, 1, KDB_REPEAT_NONE},
 33.3511 +    {"dvmc", kdb_cmdf_dvmc,  kdb_usgf_dvmc, 1, KDB_REPEAT_NONE},
 33.3512 +
 33.3513 +    /* tracing related commands */
 33.3514 +    {"trcon", kdb_cmdf_trcon,  kdb_usgf_trcon,  0, KDB_REPEAT_NONE},
 33.3515 +    {"trcoff",kdb_cmdf_trcoff, kdb_usgf_trcoff, 0, KDB_REPEAT_NONE},
 33.3516 +    {"trcz",  kdb_cmdf_trcz,   kdb_usgf_trcz,   0, KDB_REPEAT_NONE},
 33.3517 +    {"trcp",  kdb_cmdf_trcp,   kdb_usgf_trcp,   1, KDB_REPEAT_NONE},
 33.3518 +
 33.3519 +    {"usr1",  kdb_cmdf_usr1,   kdb_usgf_usr1,   1, KDB_REPEAT_NONE},
 33.3520 +    {"kdbf",  kdb_cmdf_kdbf,   kdb_usgf_kdbf,   1, KDB_REPEAT_NONE},
 33.3521 +    {"kdbdbg",kdb_cmdf_kdbdbg, kdb_usgf_kdbdbg, 1, KDB_REPEAT_NONE},
 33.3522 +    {"reboot",kdb_cmdf_reboot, kdb_usgf_reboot, 1, KDB_REPEAT_NONE},
 33.3523 +    {"h",     kdb_cmdf_h,      kdb_usgf_h,      1, KDB_REPEAT_NONE},
 33.3524 +
 33.3525 +    {"", NULL, NULL, 0, 0},
 33.3526 +  };
 33.3527 +    kdb_cmd_tbl = _kdb_cmd_table;
 33.3528 +    return;
 33.3529 +}
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/xen/kdb/kdb_io.c	Thu Feb 03 15:42:41 2011 -0800
    34.3 @@ -0,0 +1,174 @@
    34.4 +/*
    34.5 + * Copyright (C) 2009, Mukesh Rathor, Oracle Corp.  All rights reserved.
    34.6 + *
    34.7 + * This program is free software; you can redistribute it and/or
    34.8 + * modify it under the terms of the GNU General Public
    34.9 + * License v2 as published by the Free Software Foundation.
   34.10 + *
   34.11 + * This program is distributed in the hope that it will be useful,
   34.12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   34.13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   34.14 + * General Public License for more details.
   34.15 + *
   34.16 + * You should have received a copy of the GNU General Public
   34.17 + * License along with this program; if not, write to the
   34.18 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   34.19 + * Boston, MA 021110-1307, USA.
   34.20 + */
   34.21 +#include "include/kdbinc.h"
   34.22 +
   34.23 +#define K_BACKSPACE  0x8                   /* ctrl-H */
   34.24 +#define K_BACKSPACE1 0x7f                  /* ctrl-? */
   34.25 +#define K_UNDERSCORE 0x5f
   34.26 +#define K_CMD_BUFSZ  160
   34.27 +#define K_CMD_MAXI   (K_CMD_BUFSZ - 1)     /* max index in buffer */
   34.28 +
   34.29 +#if 0        /* make a history array some day */
   34.30 +#define K_UP_ARROW                         /* sequence : 1b 5b 41 ie, '\e[A' */
   34.31 +#define K_DN_ARROW                         /* sequence : 1b 5b 42 ie, '\e[B' */
   34.32 +#define K_NUM_HIST   32
   34.33 +static int cursor;
   34.34 +static char cmds_a[NUM_HIST][K_CMD_BUFSZ];
   34.35 +#endif
   34.36 +
   34.37 +static char cmds_a[K_CMD_BUFSZ];
   34.38 +
   34.39 +
   34.40 +static int
   34.41 +kdb_key_valid(int key)
   34.42 +{
   34.43 +    /* note: isspace() is more than ' ', hence we don't use it here */
   34.44 +    if (isalnum(key) || key == ' ' || key == K_BACKSPACE || key == '\n' ||
   34.45 +        key == '?' || key == K_UNDERSCORE || key == '=')
   34.46 +            return 1;
   34.47 +    return 0;
   34.48 +}
   34.49 +
   34.50 +/* display kdb prompt and read command from the console 
   34.51 + * RETURNS: a '\n' terminated command buffer */
   34.52 +char *
   34.53 +kdb_get_cmdline(char *prompt)
   34.54 +{
   34.55 +    #define K_BELL     0x7
   34.56 +    #define K_CTRL_C   0x3
   34.57 +
   34.58 +    int key, i=0;
   34.59 +
   34.60 +    kdbp(prompt);
   34.61 +    memset(cmds_a, 0, K_CMD_BUFSZ);
   34.62 +    cmds_a[K_CMD_BUFSZ-1] = '\n';
   34.63 +
   34.64 +    do {
   34.65 +        key = console_getc();
   34.66 +        if (key == '\r') 
   34.67 +            key = '\n';
   34.68 +        if (key == K_BACKSPACE1) 
   34.69 +            key = K_BACKSPACE;
   34.70 +
   34.71 +        if (key == K_CTRL_C || (i==K_CMD_MAXI && key != '\n')) {
   34.72 +            console_putc('\n');
   34.73 +            if (i >= K_CMD_MAXI) {
   34.74 +                kdbp("KDB: cmd buffer overflow\n");
   34.75 +                console_putc(K_BELL);
   34.76 +            }
   34.77 +            memset(cmds_a, 0, K_CMD_BUFSZ);
   34.78 +            i = 0;
   34.79 +            kdbp(prompt);
   34.80 +            continue;
   34.81 +        }
   34.82 +        if (!kdb_key_valid(key)) {
   34.83 +            console_putc(K_BELL);
   34.84 +            continue;
   34.85 +        }
   34.86 +        if (key == K_BACKSPACE) {
   34.87 +            if (i==0) {
   34.88 +                console_putc(K_BELL);
   34.89 +                continue;
   34.90 +            } else 
   34.91 +                cmds_a[--i] = '\0';
   34.92 +                console_putc(K_BACKSPACE);
   34.93 +                console_putc(' ');        /* erase character */
   34.94 +        } else
   34.95 +            cmds_a[i++] = key;
   34.96 +
   34.97 +        console_putc(key);
   34.98 +
   34.99 +    } while (key != '\n');
  34.100 +
  34.101 +    return cmds_a;
  34.102 +}
  34.103 +
  34.104 +/*
  34.105 + * printk takes a lock, an NMI could come in after that, and another cpu may 
  34.106 + * spin. also, the console lock is forced unlock, so panic is been seen on 
  34.107 + * 8 way. hence, no printk() calls.
  34.108 + */
  34.109 +static volatile int kdbp_gate = 0;
  34.110 +void
  34.111 +kdbp(const char *fmt, ...)
  34.112 +{
  34.113 +    static char buf[1024];
  34.114 +    va_list args;
  34.115 +    char *p;
  34.116 +    int i=0;
  34.117 +
  34.118 +    while ((__cmpxchg(&kdbp_gate, 0,1, sizeof(kdbp_gate)) != 0) && i++<1000)
  34.119 +        mdelay(10);
  34.120 +
  34.121 +    va_start(args, fmt);
  34.122 +    (void)vsnprintf(buf, sizeof(buf), fmt, args);
  34.123 +    va_end(args);
  34.124 +
  34.125 +    for (p=buf; *p != '\0'; p++)
  34.126 +        console_putc(*p);
  34.127 +    kdbp_gate = 0;
  34.128 +}
  34.129 +
  34.130 +
  34.131 +/*
  34.132 + * copy/read machine memory. 
  34.133 + * RETURNS: number of bytes copied 
  34.134 + */
  34.135 +int
  34.136 +kdb_read_mmem(kdbma_t maddr, kdbbyt_t *dbuf, int len)
  34.137 +{
  34.138 +    ulong remain, orig=len;
  34.139 +
  34.140 +    while (len > 0) {
  34.141 +        ulong pagecnt = min_t(long, PAGE_SIZE-(maddr&~PAGE_MASK), len);
  34.142 +        char *va = map_domain_page(maddr >> PAGE_SHIFT);
  34.143 +
  34.144 +        va = va + (maddr & (PAGE_SIZE-1));        /* add page offset */
  34.145 +        remain = __copy_from_user(dbuf, (void *)va, pagecnt);
  34.146 +        KDBGP1("maddr:%x va:%p len:%x pagecnt:%x rem:%x\n", 
  34.147 +               maddr, va, len, pagecnt, remain);
  34.148 +        unmap_domain_page(va);
  34.149 +        len = len  - (pagecnt - remain);
  34.150 +        if (remain != 0)
  34.151 +            break;
  34.152 +        maddr += pagecnt;
  34.153 +        dbuf += pagecnt;
  34.154 +    }
  34.155 +    return orig - len;
  34.156 +}
  34.157 +
  34.158 +
  34.159 +/*
  34.160 + * copy/read guest or hypervisor memory. (domid == DOMID_IDLE) => hyp
  34.161 + * RETURNS: number of bytes copied 
  34.162 + */
  34.163 +int
  34.164 +kdb_read_mem(kdbva_t saddr, kdbbyt_t *dbuf, int len, domid_t domid)
  34.165 +{
  34.166 +    return (len - dbg_rw_mem(saddr, dbuf, len, domid, 0, 0));
  34.167 +}
  34.168 +
  34.169 +/*
  34.170 + * write guest or hypervisor memory. (domid == DOMID_IDLE) => hyp
  34.171 + * RETURNS: number of bytes written
  34.172 + */
  34.173 +int
  34.174 +kdb_write_mem(kdbva_t daddr, kdbbyt_t *sbuf, int len, domid_t domid)
  34.175 +{
  34.176 +    return (len - dbg_rw_mem(daddr, sbuf, len, domid, 1, 0));
  34.177 +}
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/xen/kdb/kdbmain.c	Thu Feb 03 15:42:41 2011 -0800
    35.3 @@ -0,0 +1,725 @@
    35.4 +/*
    35.5 + * Copyright (C) 2009, Mukesh Rathor, Oracle Corp.  All rights reserved.
    35.6 + *
    35.7 + * This program is free software; you can redistribute it and/or
    35.8 + * modify it under the terms of the GNU General Public
    35.9 + * License v2 as published by the Free Software Foundation.
   35.10 + *
   35.11 + * This program is distributed in the hope that it will be useful,
   35.12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   35.13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   35.14 + * General Public License for more details.
   35.15 + *
   35.16 + * You should have received a copy of the GNU General Public
   35.17 + * License along with this program; if not, write to the
   35.18 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   35.19 + * Boston, MA 021110-1307, USA.
   35.20 + */
   35.21 +
   35.22 +#include "include/kdbinc.h"
   35.23 +
   35.24 +static int kdbmain(kdb_reason_t, struct cpu_user_regs *);
   35.25 +static int kdbmain_fatal(struct cpu_user_regs *, int);
   35.26 +static const char *kdb_gettrapname(int);
   35.27 +
   35.28 +/* ======================== GLOBAL VARIABLES =============================== */
   35.29 +/* All global variables used by KDB must be defined here only. Module specific
   35.30 + * static variables must be declared in respective modules.
   35.31 + */
   35.32 +kdbtab_t *kdb_cmd_tbl;
   35.33 +char kdb_prompt[32];
   35.34 +
   35.35 +volatile kdb_cpu_cmd_t kdb_cpu_cmd[NR_CPUS];
   35.36 +cpumask_t kdb_cpu_traps;    /* bit per cpu to tell which cpus hit int3 */
   35.37 +
   35.38 +#ifndef NDEBUG
   35.39 +    #error KDB is not supported on debug xen. Turn debug off
   35.40 +#endif
   35.41 +
   35.42 +volatile int kdb_init_cpu = -1;           /* initial kdb cpu */
   35.43 +volatile int kdb_session_begun = 0;       /* active kdb session? */
   35.44 +volatile int kdb_enabled = 1;             /* kdb enabled currently? */
   35.45 +volatile int kdb_sys_crash = 0;           /* are we in crashed state? */
   35.46 +volatile int kdbdbg = 0;                  /* to debug kdb itself */
   35.47 +
   35.48 +static volatile int kdb_trap_immed_reason = 0;   /* reason for immed trap */
   35.49 +
   35.50 +static cpumask_t kdb_fatal_cpumask;       /* which cpus in fatal path */
   35.51 +
   35.52 +/* return index of first bit set in val. if val is 0, retval is undefined */
   35.53 +static inline unsigned int kdb_firstbit(unsigned long val)
   35.54 +{
   35.55 +    __asm__ ( "bsf %1,%0" : "=r" (val) : "r" (val), "0" (BITS_PER_LONG) );
   35.56 +    return (unsigned int)val;
   35.57 +}
   35.58 +
   35.59 +static void 
   35.60 +kdb_dbg_prnt_ctrps(char *label, int ccpu)
   35.61 +{
   35.62 +    int i;
   35.63 +    if (!kdbdbg)
   35.64 +        return;
   35.65 +
   35.66 +    if (label || *label)
   35.67 +        kdbp("%s ", label);
   35.68 +    if (ccpu != -1)
   35.69 +        kdbp("ccpu:%d ", ccpu);
   35.70 +    kdbp("cputrps:");
   35.71 +    for (i=sizeof(kdb_cpu_traps)/sizeof(kdb_cpu_traps.bits[0]) - 1; i >=0; i--)
   35.72 +        kdbp(" %lx", kdb_cpu_traps.bits[i]);
   35.73 +    kdbp("\n");
   35.74 +}
   35.75 +
   35.76 +/* 
   35.77 + * Hold this cpu. Don't disable until all CPUs in kdb to avoid IPI deadlock 
   35.78 + */
   35.79 +static void
   35.80 +kdb_hold_this_cpu(int ccpu, struct cpu_user_regs *regs)
   35.81 +{
   35.82 +    do {
   35.83 +        for(; kdb_cpu_cmd[ccpu] == KDB_CPU_PAUSE; cpu_relax());
   35.84 +
   35.85 +        if (kdb_cpu_cmd[ccpu] == KDB_CPU_DISABLE) {
   35.86 +            local_irq_disable();
   35.87 +            kdb_cpu_cmd[ccpu] = KDB_CPU_PAUSE;
   35.88 +        }
   35.89 +        if (kdb_cpu_cmd[ccpu] == KDB_CPU_DO_VMEXIT) {
   35.90 +            kdb_curr_cpu_flush_vmcs();
   35.91 +            kdb_cpu_cmd[ccpu] = KDB_CPU_PAUSE;
   35.92 +        }
   35.93 +        if (kdb_cpu_cmd[ccpu] == KDB_CPU_SHOWPC) {
   35.94 +            kdbp("[%d]", ccpu);
   35.95 +            kdb_display_pc(regs);
   35.96 +            kdb_cpu_cmd[ccpu] = KDB_CPU_PAUSE;
   35.97 +        }
   35.98 +    } while (kdb_cpu_cmd[ccpu] == KDB_CPU_PAUSE);     /* No goto, eh! */
   35.99 +    KDBGP1("un hold: ccpu:%d cmd:%d\n", ccpu, kdb_cpu_cmd[ccpu]);
  35.100 +}
  35.101 +
  35.102 +/*
  35.103 + * Pause this cpu while one CPU does main kdb processing. If that CPU does
  35.104 + * a "cpu switch" to this cpu, this cpu will become the main kdb cpu. If the
  35.105 + * user next does single step of some sort, this function will be exited,
  35.106 + * and this cpu will come back into kdb via kdb_handle_trap_entry function.
  35.107 + */
  35.108 +static void 
  35.109 +kdb_pause_this_cpu(struct cpu_user_regs *regs, void *unused)
  35.110 +{
  35.111 +    kdbmain(KDB_REASON_PAUSE_IPI, regs);
  35.112 +}
  35.113 +
  35.114 +/* pause other cpus via an IPI. Note, disabled CPUs can't receive IPIs until
  35.115 + * enabled */
  35.116 +static void
  35.117 +kdb_smp_pause_cpus(void)
  35.118 +{
  35.119 +    int cpu, wait_count = 0;
  35.120 +    int ccpu = smp_processor_id();      /* current cpu */
  35.121 +    cpumask_t cpumask = cpu_online_map;
  35.122 +
  35.123 +    cpu_clear(smp_processor_id(), cpumask);
  35.124 +    for_each_cpu_mask(cpu, cpumask) 
  35.125 +        if (kdb_cpu_cmd[cpu] != KDB_CPU_INVAL) {
  35.126 +            kdbp("KDB: won't pause cpu:%d, cmd[cpu]=%d\n",cpu,kdb_cpu_cmd[cpu]);
  35.127 +            cpu_clear(cpu, cpumask);
  35.128 +        }
  35.129 +    KDBGP("ccpu:%d will pause cpus. mask:0x%lx\n", ccpu, cpumask.bits[0]);
  35.130 +#if XEN_SUBVERSION > 4 || XEN_VERSION == 4              /* xen 3.5.x or above */
  35.131 +    on_selected_cpus(&cpumask, (void (*)(void *))kdb_pause_this_cpu, 
  35.132 +                     "XENKDB", 0);
  35.133 +#else
  35.134 +    on_selected_cpus(cpumask, (void (*)(void *))kdb_pause_this_cpu, 
  35.135 +                     "XENKDB", 0, 0);
  35.136 +#endif
  35.137 +    mdelay(300);                     /* wait a bit for other CPUs to stop */
  35.138 +    while(wait_count++ < 10) {
  35.139 +        int bummer = 0;
  35.140 +        for_each_cpu_mask(cpu, cpumask)
  35.141 +            if (kdb_cpu_cmd[cpu] != KDB_CPU_PAUSE)
  35.142 +                bummer = 1;
  35.143 +        if (!bummer)
  35.144 +            break;
  35.145 +        kdbp("ccpu:%d trying to stop other cpus...\n", ccpu);
  35.146 +        mdelay(100);  /* wait 100 ms */
  35.147 +    };
  35.148 +    for_each_cpu_mask(cpu, cpumask)          /* now check who is with us */
  35.149 +        if (kdb_cpu_cmd[cpu] != KDB_CPU_PAUSE)
  35.150 +            kdbp("Bummer cpu %d not paused. ccpu:%d\n", cpu,ccpu);
  35.151 +        else {
  35.152 +            kdb_cpu_cmd[cpu] = KDB_CPU_DISABLE;  /* tell it to disable ints */
  35.153 +            while (kdb_cpu_cmd[cpu] != KDB_CPU_PAUSE);
  35.154 +        }
  35.155 +}
  35.156 +
  35.157 +/* 
  35.158 + * Do once per kdb session:  A kdb session lasts from 
  35.159 + *    keybord/HWBP/SWBP till KDB_CPU_INSTALL_BP is done. Within a session,
  35.160 + *    user may do several cpu switches, single step, next instr,  etc..
  35.161 + *
  35.162 + * DO: 1. pause other cpus if they are not already. they would already be 
  35.163 + *        if we are in single step mode
  35.164 + *     2. watchdog_disable() 
  35.165 + *     3. uninstall all sw breakpoints so that user doesn't see them
  35.166 + */
  35.167 +static void
  35.168 +kdb_begin_session(void)
  35.169 +{
  35.170 +    if (!kdb_session_begun) {
  35.171 +        kdb_session_begun = 1;
  35.172 +        kdb_smp_pause_cpus();
  35.173 +        local_irq_disable();
  35.174 +        watchdog_disable();
  35.175 +        kdb_uninstall_all_swbp();
  35.176 +    }
  35.177 +}
  35.178 +
  35.179 +static void
  35.180 +kdb_smp_unpause_cpus(int ccpu)
  35.181 +{
  35.182 +    int cpu;
  35.183 +
  35.184 +    int wait_count = 0;
  35.185 +    cpumask_t cpumask = cpu_online_map;
  35.186 +
  35.187 +    cpu_clear(smp_processor_id(), cpumask);
  35.188 +
  35.189 +    KDBGP("kdb_smp_unpause_other_cpus(). ccpu:%d\n", ccpu);
  35.190 +    for_each_cpu_mask(cpu, cpumask)
  35.191 +        kdb_cpu_cmd[cpu] = KDB_CPU_QUIT;
  35.192 +
  35.193 +    while(wait_count++ < 10) {
  35.194 +        int bummer = 0;
  35.195 +        for_each_cpu_mask(cpu, cpumask)
  35.196 +            if (kdb_cpu_cmd[cpu] != KDB_CPU_INVAL)
  35.197 +                bummer = 1;
  35.198 +            if (!bummer)
  35.199 +                break;
  35.200 +            mdelay(90);  /* wait 90 ms, 50 too short on large systems */
  35.201 +    };
  35.202 +    /* now make sure they are all in there */
  35.203 +    for_each_cpu_mask(cpu, cpumask)
  35.204 +        if (kdb_cpu_cmd[cpu] != KDB_CPU_INVAL)
  35.205 +            kdbp("KDB: cpu %d still paused (cmd==%d). ccpu:%d\n",
  35.206 +                 cpu, kdb_cpu_cmd[cpu], ccpu);
  35.207 +}
  35.208 +
  35.209 +/*
  35.210 + * End of KDB session. 
  35.211 + *   This is called at the very end. In case of multiple cpus hitting BPs
  35.212 + *   and sitting on a trap handlers, the last cpu to exit will call this.
  35.213 + *   - isnstall all sw breakpoints, and purge deleted ones from table.
  35.214 + *   - clear TF here also in case go is entered on a different cpu after switch
  35.215 + */
  35.216 +static void
  35.217 +kdb_end_session(int ccpu, struct cpu_user_regs *regs)
  35.218 +{
  35.219 +    ASSERT(!cpus_empty(kdb_cpu_traps));
  35.220 +    ASSERT(kdb_session_begun);
  35.221 +    kdb_install_all_swbp();
  35.222 +    kdb_flush_swbp_table();
  35.223 +    kdb_install_watchpoints();
  35.224 +
  35.225 +    regs->eflags &= ~X86_EFLAGS_TF;
  35.226 +    kdb_cpu_cmd[ccpu] = KDB_CPU_INVAL;
  35.227 +    kdb_time_resume(1);
  35.228 +    kdb_session_begun = 0;      /* before unpause for kdb_install_watchpoints */
  35.229 +    kdb_smp_unpause_cpus(ccpu);
  35.230 +    watchdog_enable();
  35.231 +    KDBGP("end_session:ccpu:%d\n", ccpu);
  35.232 +}
  35.233 +
  35.234 +/* 
  35.235 + * check if we entered kdb because of DB trap. If yes, then check if
  35.236 + * we caused it or someone else.
  35.237 + * RETURNS: 0 : not one of ours. hypervisor must handle it. 
  35.238 + *          1 : #DB for delayed sw bp install. 
  35.239 + *          2 : this cpu must stay in kdb.
  35.240 + */
  35.241 +static noinline int
  35.242 +kdb_check_dbtrap(kdb_reason_t *reasp, int ss_mode, struct cpu_user_regs *regs) 
  35.243 +{
  35.244 +    int rc = 2;
  35.245 +    int ccpu = smp_processor_id();
  35.246 +
  35.247 +    /* DB excp caused by hw breakpoint or the TF flag. The TF flag is set
  35.248 +     * by us for ss mode or to install breakpoints. In ss mode, none of the
  35.249 +     * breakpoints are installed. Check to make sure we intended BP INSTALL
  35.250 +     * so we don't do it on a spurious DB trap.
  35.251 +     * check for kdb_cpu_traps here also, because each cpu sitting on a trap
  35.252 +     * must execute the instruction without the BP before passing control
  35.253 +     * to next cpu in kdb_cpu_traps.
  35.254 +     */
  35.255 +    if (*reasp == KDB_REASON_DBEXCP && !ss_mode) {
  35.256 +        if (kdb_cpu_cmd[ccpu] == KDB_CPU_INSTALL_BP) {
  35.257 +            if (!cpus_empty(kdb_cpu_traps)) {
  35.258 +                int a_trap_cpu = first_cpu(kdb_cpu_traps);
  35.259 +                KDBGP("ccpu:%d trapcpu:%d\n", ccpu, a_trap_cpu);
  35.260 +                kdb_cpu_cmd[a_trap_cpu] = KDB_CPU_QUIT;
  35.261 +                *reasp = KDB_REASON_PAUSE_IPI;
  35.262 +                regs->eflags &= ~X86_EFLAGS_TF;
  35.263 +                kdb_init_cpu = -1;
  35.264 +            } else {
  35.265 +                kdb_end_session(ccpu, regs);
  35.266 +                rc = 1;
  35.267 +            }
  35.268 +        } else if (! kdb_check_watchpoints(regs)) {
  35.269 +            rc = 0;                        /* hyp must handle it */
  35.270 +        }
  35.271 +    }
  35.272 +    return rc;
  35.273 +}
  35.274 +
  35.275 +/* 
  35.276 + * Misc processing on kdb entry like displaying PC, adjust IP for sw bp.... 
  35.277 + */
  35.278 +static void
  35.279 +kdb_main_entry_misc(kdb_reason_t reason, struct cpu_user_regs *regs, 
  35.280 +                    int ccpu, int ss_mode, int enabled)
  35.281 +{
  35.282 +    if (reason == KDB_REASON_KEYBOARD)
  35.283 +        kdbp("\nEnter kdb (cpu:%d reason:%d vcpu=%d domid:%d"
  35.284 +             " eflg:0x%lx irqs:%d)\n", ccpu, reason, current->vcpu_id, 
  35.285 +             current->domain->domain_id, regs->eflags, enabled);
  35.286 +    else if (ss_mode)
  35.287 +        KDBGP1("KDBG: KDB single step mode. ccpu:%d\n", ccpu);
  35.288 +
  35.289 +    if (reason == KDB_REASON_BPEXCP && !ss_mode) 
  35.290 +        kdbp("Breakpoint on cpu %d at 0x%lx\n", ccpu, regs->KDBIP);
  35.291 +
  35.292 +    /* display the current PC and instruction at it */
  35.293 +    if (reason != KDB_REASON_PAUSE_IPI)
  35.294 +        kdb_display_pc(regs);
  35.295 +    console_start_sync();
  35.296 +}
  35.297 +
  35.298 +/* 
  35.299 + * The MAIN kdb function. All cpus go thru this. IRQ is enabled on entry because
  35.300 + * a cpu could hit a bp set in disabled code.
  35.301 + * IPI: Even the main cpu must enable in case another CPU is trying to IPI us.
  35.302 + *      That way, it would IPI us, then get out and be ready for our pause IPI.
  35.303 + * IRQs: The reason irqs enable/disable is scattered is because on a typical
  35.304 + *       system IPIs are constantly going on amongs CPUs in a set of any size. 
  35.305 + *       As a result,  to avoid deadlock, cpus have to loop enabled, until a 
  35.306 + *       quorum is established and the session has begun.
  35.307 + * Step: Intel Vol3B 18.3.1.4 : An external interrupt may be serviced upon
  35.308 + *       single step. Since, the likely ext timer_interrupt and 
  35.309 + *       apic_timer_interrupt dont' mess with time data structs, we are prob OK
  35.310 + *       leaving enabled.
  35.311 + * Time: Very messy. Most platform timers are readonly, so we can't stop time
  35.312 + *       in the debugger. We take the only resort, let the TSC and plt run as
  35.313 + *       normal, upon leaving, "attempt" to bring everybody to current time.
  35.314 + * kdbcputraps: bit per cpu. each cpu sets it bit in entry.S. The bit is 
  35.315 + *              reliable because upon traps, Ints are disabled. the bit is set
  35.316 + *              before Ints are enabled.
  35.317 + *
  35.318 + * RETURNS: 0 : kdb was called for event it was not responsible
  35.319 + *          1 : event owned and handled by kdb 
  35.320 + */
  35.321 +static int
  35.322 +kdbmain(kdb_reason_t reason, struct cpu_user_regs *regs)
  35.323 +{
  35.324 +    int ccpu = smp_processor_id();                /* current cpu */
  35.325 +    int rc = 1, cmd = kdb_cpu_cmd[ccpu];
  35.326 +    int ss_mode = (cmd == KDB_CPU_SS || cmd == KDB_CPU_NI);
  35.327 +    int delayed_install = (kdb_cpu_cmd[ccpu] == KDB_CPU_INSTALL_BP);
  35.328 +    int enabled = local_irq_is_enabled();
  35.329 +
  35.330 +    KDBGP("kdbmain:ccpu:%d rsn:%d eflgs:0x%lx cmd:%d initc:%d irqs:%d "
  35.331 +          "regs:%lx IP:%lx ", ccpu, reason, regs->eflags, cmd, 
  35.332 +          kdb_init_cpu, enabled, regs, regs->KDBIP);
  35.333 +    kdb_dbg_prnt_ctrps("", -1);
  35.334 +
  35.335 +    if (!ss_mode && !delayed_install)    /* initial kdb enter */
  35.336 +        local_irq_enable();              /* so we can receive IPI */
  35.337 +
  35.338 +    if (!ss_mode && ccpu != kdb_init_cpu && reason != KDB_REASON_PAUSE_IPI){
  35.339 +        int sz = sizeof(kdb_init_cpu);
  35.340 +        while (__cmpxchg(&kdb_init_cpu, -1, ccpu, sz) != -1)
  35.341 +            for(; kdb_init_cpu != -1; cpu_relax());
  35.342 +    }
  35.343 +    if (kdb_session_begun)
  35.344 +        local_irq_disable();             /* kdb always runs disabled */
  35.345 +
  35.346 +    if (reason == KDB_REASON_BPEXCP) {             /* INT 3 */
  35.347 +        cpu_clear(ccpu, kdb_cpu_traps);            /* remove ourself */
  35.348 +        rc = kdb_check_sw_bkpts(regs);
  35.349 +        if (rc == 0) {               /* not one of ours. leave kdb */
  35.350 +            kdb_init_cpu = -1;
  35.351 +            goto out;
  35.352 +        } else if (rc == 1) {        /* one of ours but deleted */
  35.353 +            if (cpus_empty(kdb_cpu_traps)) {
  35.354 +                kdb_end_session(ccpu,regs);     
  35.355 +                kdb_init_cpu = -1;
  35.356 +                goto out;
  35.357 +            } else {                 
  35.358 +                /* release another trap cpu, and put ourself in a pause mode */
  35.359 +                int a_trap_cpu = first_cpu(kdb_cpu_traps);
  35.360 +                KDBGP("ccpu:%d cmd:%d rsn:%d atrpcpu:%d initcpu:%d\n", ccpu, 
  35.361 +                      kdb_cpu_cmd[ccpu], reason, a_trap_cpu, kdb_init_cpu);
  35.362 +                kdb_cpu_cmd[a_trap_cpu] = KDB_CPU_QUIT;
  35.363 +                reason = KDB_REASON_PAUSE_IPI;
  35.364 +                kdb_init_cpu = -1;
  35.365 +            }
  35.366 +        } else if (rc == 2) {        /* one of ours but condition not met */
  35.367 +                kdb_begin_session();
  35.368 +                regs->eflags |= X86_EFLAGS_TF;  
  35.369 +                kdb_cpu_cmd[ccpu] = KDB_CPU_INSTALL_BP;
  35.370 +                goto out;
  35.371 +        }
  35.372 +    }
  35.373 +
  35.374 +    /* following will take care of KDB_CPU_INSTALL_BP, and also release
  35.375 +     * kdb_init_cpu. it should not be done twice */
  35.376 +    if ((rc=kdb_check_dbtrap(&reason, ss_mode, regs)) == 0 || rc == 1) {
  35.377 +        kdb_init_cpu = -1;       /* leaving kdb */
  35.378 +        goto out;                /* rc properly set to 0 or 1 */
  35.379 +    }
  35.380 +    if (reason != KDB_REASON_PAUSE_IPI) {
  35.381 +        kdb_cpu_cmd[ccpu] = KDB_CPU_MAIN_KDB;
  35.382 +    } else
  35.383 +        kdb_cpu_cmd[ccpu] = KDB_CPU_PAUSE;
  35.384 +
  35.385 +    if (kdb_cpu_cmd[ccpu] == KDB_CPU_MAIN_KDB && !ss_mode)
  35.386 +        kdb_begin_session(); 
  35.387 +
  35.388 +    kdb_main_entry_misc(reason, regs, ccpu, ss_mode, enabled);
  35.389 +    /* note, one or more cpu switches may occur in between */
  35.390 +    while (1) {
  35.391 +        if (kdb_cpu_cmd[ccpu] == KDB_CPU_PAUSE)
  35.392 +            kdb_hold_this_cpu(ccpu, regs);
  35.393 +        if (kdb_cpu_cmd[ccpu] == KDB_CPU_MAIN_KDB)
  35.394 +            kdb_do_cmds(regs);
  35.395 +
  35.396 +        if (kdb_cpu_cmd[ccpu] == KDB_CPU_GO) {
  35.397 +            if (ccpu != kdb_init_cpu) {
  35.398 +                kdb_cpu_cmd[kdb_init_cpu] = KDB_CPU_GO;
  35.399 +                kdb_cpu_cmd[ccpu] = KDB_CPU_PAUSE;
  35.400 +                continue;               /* for the pause guy */
  35.401 +            }
  35.402 +            if (!cpus_empty(kdb_cpu_traps)) {
  35.403 +                /* execute current instruction without 0xcc */
  35.404 +                kdb_dbg_prnt_ctrps("nempty:", ccpu);
  35.405 +                regs->eflags |= X86_EFLAGS_TF;  
  35.406 +                kdb_cpu_cmd[ccpu] = KDB_CPU_INSTALL_BP;
  35.407 +                goto out;
  35.408 +            }
  35.409 +        }
  35.410 +        if (kdb_cpu_cmd[ccpu] != KDB_CPU_PAUSE  && 
  35.411 +            kdb_cpu_cmd[ccpu] != KDB_CPU_MAIN_KDB)
  35.412 +                break;
  35.413 +    }
  35.414 +    if (kdb_cpu_cmd[ccpu] == KDB_CPU_GO) {
  35.415 +        ASSERT(cpus_empty(kdb_cpu_traps));
  35.416 +        if (kdb_swbp_exists()) {
  35.417 +            if (reason == KDB_REASON_BPEXCP) {
  35.418 +                /* do delayed install */
  35.419 +                regs->eflags |= X86_EFLAGS_TF;  
  35.420 +                kdb_cpu_cmd[ccpu] = KDB_CPU_INSTALL_BP;
  35.421 +                goto out;
  35.422 +            } 
  35.423 +        }
  35.424 +        kdb_end_session(ccpu, regs);
  35.425 +        kdb_init_cpu = -1;
  35.426 +    }
  35.427 +out:
  35.428 +    if (kdb_cpu_cmd[ccpu] == KDB_CPU_QUIT) {
  35.429 +        KDBGP("ccpu:%d _quit IP: %lx\n", ccpu, regs->KDBIP);
  35.430 +        if (! kdb_session_begun)
  35.431 +            kdb_install_watchpoints();
  35.432 +        kdb_time_resume(0);
  35.433 +        kdb_cpu_cmd[ccpu] = KDB_CPU_INVAL;
  35.434 +    }
  35.435 +
  35.436 +    /* for ss and delayed install, TF is set. not much in EXT INT handlers*/
  35.437 +    if (kdb_cpu_cmd[ccpu] == KDB_CPU_NI)
  35.438 +        kdb_time_resume(1);
  35.439 +    if (enabled)
  35.440 +        local_irq_enable();
  35.441 +
  35.442 +    KDBGP("kdbmain:X:ccpu:%d rc:%d cmd:%d eflg:0x%lx initc:%d sesn:%d " 
  35.443 +          "cs:%x irqs:%d ", ccpu, rc, kdb_cpu_cmd[ccpu], regs->eflags, 
  35.444 +          kdb_init_cpu, kdb_session_begun, regs->cs, local_irq_is_enabled());
  35.445 +    kdb_dbg_prnt_ctrps("", -1);
  35.446 +    return (rc ? 1 : 0);
  35.447 +}
  35.448 +
  35.449 +/* 
  35.450 + * kdb entry function when coming in via a keyboard
  35.451 + * RETURNS: 0 : kdb was called for event it was not responsible
  35.452 + *          1 : event owned and handled by kdb 
  35.453 + */
  35.454 +int
  35.455 +kdb_keyboard(struct cpu_user_regs *regs)
  35.456 +{
  35.457 +    return kdbmain(KDB_REASON_KEYBOARD, regs);
  35.458 +}
  35.459 +
  35.460 +#if 0
  35.461 +/*
  35.462 + * this function called when kdb session active and user presses ctrl\ again.
  35.463 + * the assumption is that the user typed ni/ss cmd, and it never got back into
  35.464 + * kdb, or the user is impatient. Either case, we just fake it that the SS did
  35.465 + * finish. Since, all other kdb cpus must be holding disabled, the interrupt
  35.466 + * would be on the CPU that did the ss/ni cmd
  35.467 + */
  35.468 +void
  35.469 +kdb_ssni_reenter(struct cpu_user_regs *regs)
  35.470 +{
  35.471 +    int ccpu = smp_processor_id();
  35.472 +    int ccmd = kdb_cpu_cmd[ccpu];
  35.473 +
  35.474 +    if(ccmd == KDB_CPU_SS || ccmd == KDB_CPU_INSTALL_BP)
  35.475 +        kdbmain(KDB_REASON_DBEXCP, regs); 
  35.476 +    else 
  35.477 +        kdbmain(KDB_REASON_KEYBOARD, regs);
  35.478 +}
  35.479 +#endif
  35.480 +
  35.481 +/* 
  35.482 + * All traps are routed thru here. We care about BP (#3) trap (INT 3) and
  35.483 + * the DB trap(#1) only. 
  35.484 + * returns: 0 kdb has nothing do with this trap
  35.485 + *          1 kdb handled this trap 
  35.486 + */
  35.487 +int
  35.488 +kdb_handle_trap_entry(int vector, struct cpu_user_regs *regs)
  35.489 +{
  35.490 +    int rc = 0;
  35.491 +    int ccpu = smp_processor_id();
  35.492 +
  35.493 +    if (vector == TRAP_int3) {
  35.494 +        rc = kdbmain(KDB_REASON_BPEXCP, regs);
  35.495 +
  35.496 +    } else if (vector == TRAP_debug) {
  35.497 +        KDBGP("ccpu:%d trapdbg reas:%d\n", ccpu, kdb_trap_immed_reason);
  35.498 +
  35.499 +        if (kdb_trap_immed_reason == KDB_TRAP_FATAL) { 
  35.500 +            KDBGP("kdbtrp:fatal ccpu:%d vec:%d\n", ccpu, vector);
  35.501 +            rc = kdbmain_fatal(regs, vector);
  35.502 +            BUG();                             /* no return */
  35.503 +
  35.504 +        } else if (kdb_trap_immed_reason == KDB_TRAP_KDBSTACK) {
  35.505 +            kdb_trap_immed_reason = 0;         /* show kdb stack */
  35.506 +            show_registers(regs);
  35.507 +            show_stack(regs);
  35.508 +            regs->eflags &= ~X86_EFLAGS_TF;
  35.509 +            rc = 1;
  35.510 +
  35.511 +        } else if (kdb_trap_immed_reason == KDB_TRAP_NONFATAL) {
  35.512 +            kdb_trap_immed_reason = 0;
  35.513 +            rc = kdb_keyboard(regs);
  35.514 +        } else                           /* ss/ni/delayed install... */
  35.515 +            rc = kdbmain(KDB_REASON_DBEXCP, regs); 
  35.516 +
  35.517 +    } else if (vector == TRAP_nmi) {                   /* external nmi */
  35.518 +        /* when nmi is pressed, it could go to one or more or all cpus
  35.519 +         * depending on the hardware. Also, for now assume it's fatal */
  35.520 +        KDBGP("kdbtrp:ccpu:%d vec:%d\n", ccpu, vector);
  35.521 +        rc = kdbmain_fatal(regs, TRAP_nmi);
  35.522 +    }
  35.523 +    return rc;
  35.524 +}
  35.525 +
  35.526 +int
  35.527 +kdb_trap_fatal(int vector, struct cpu_user_regs *regs)
  35.528 +{
  35.529 +    kdbmain_fatal(regs, vector);
  35.530 +    return 0;
  35.531 +}
  35.532 +
  35.533 +/* From smp_send_nmi_allbutself() in crash.c which is static */
  35.534 +void
  35.535 +kdb_nmi_pause_cpus(cpumask_t cpumask)
  35.536 +{
  35.537 +    int ccpu = smp_processor_id();
  35.538 +    mdelay(200);
  35.539 +    cpus_complement(cpumask, cpumask);               /* flip bit map */
  35.540 +    cpus_and(cpumask, cpumask, cpu_online_map);      /* remove extra bits */
  35.541 +    cpu_clear(ccpu, cpumask);     /* absolutely make sure we're not on it */
  35.542 +
  35.543 +    KDBGP("ccpu:%d nmi pause. mask:0x%lx\n", ccpu, cpumask.bits[0]);
  35.544 +    if ( !cpus_empty(cpumask) )
  35.545 +#if XEN_SUBVERSION > 4 || XEN_VERSION == 4              /* xen 3.5.x or above */
  35.546 +        send_IPI_mask(&cpumask, APIC_DM_NMI);
  35.547 +#else
  35.548 +        send_IPI_mask(cpumask, APIC_DM_NMI);
  35.549 +#endif
  35.550 +    mdelay(200);
  35.551 +    KDBGP("ccpu:%d nmi pause done...\n", ccpu);
  35.552 +}
  35.553 +
  35.554 +/* 
  35.555 + * Separate function from kdbmain to keep both within sanity levels.
  35.556 + */
  35.557 +DEFINE_SPINLOCK(kdb_fatal_lk);
  35.558 +static int
  35.559 +kdbmain_fatal(struct cpu_user_regs *regs, int vector)
  35.560 +{
  35.561 +    int ccpu = smp_processor_id();
  35.562 +
  35.563 +    console_start_sync();
  35.564 +
  35.565 +    KDBGP("mainf:ccpu:%d vec:%d irq:%d\n", ccpu, vector,local_irq_is_enabled());
  35.566 +    cpu_set(ccpu, kdb_fatal_cpumask);                /* uses LOCK_PREFIX */
  35.567 +
  35.568 +    if (spin_trylock(&kdb_fatal_lk)) {
  35.569 +
  35.570 +        kdbp("*** kdb (Fatal Error on cpu:%d vec:%d %s):\n", ccpu,
  35.571 +             vector, kdb_gettrapname(vector));
  35.572 +        kdb_cpu_cmd[ccpu] = KDB_CPU_MAIN_KDB;
  35.573 +        kdb_display_pc(regs);
  35.574 +
  35.575 +        watchdog_disable();     /* important */
  35.576 +        kdb_sys_crash = 1;
  35.577 +        kdb_session_begun = 0;  /* incase session already active */
  35.578 +        local_irq_enable();
  35.579 +        kdb_nmi_pause_cpus(kdb_fatal_cpumask);
  35.580 +
  35.581 +        kdb_clear_prev_cmd();   /* buffered CRs will repeat prev cmd */
  35.582 +        kdb_session_begun = 1;  /* for kdb_hold_this_cpu() */
  35.583 +        local_irq_disable();
  35.584 +    } else {
  35.585 +        kdb_cpu_cmd[ccpu] = KDB_CPU_PAUSE;
  35.586 +    }
  35.587 +    while (1) {
  35.588 +        if (kdb_cpu_cmd[ccpu] == KDB_CPU_PAUSE)
  35.589 +            kdb_hold_this_cpu(ccpu, regs);
  35.590 +        if (kdb_cpu_cmd[ccpu] == KDB_CPU_MAIN_KDB)
  35.591 +            kdb_do_cmds(regs);
  35.592 +#if 0
  35.593 +        /* dump is the only way to exit in crashed state */
  35.594 +        if (kdb_cpu_cmd[ccpu] == KDB_CPU_DUMP)
  35.595 +            kdb_do_dump(regs);
  35.596 +#endif
  35.597 +    }
  35.598 +    return 0;
  35.599 +}
  35.600 +
  35.601 +/* Mostly called in fatal cases. earlykdb calls non-fatal.
  35.602 + * kdb_trap_immed_reason is global, so allow only one cpu at a time. Also,
  35.603 + * multiple cpu may be crashing at the same time. We enable because if there
  35.604 + * is a bad hang, at least ctrl-\ will break into kdb. Also, we don't call
  35.605 + * call kdb_keyboard directly becaue we don't have the register context.
  35.606 + */
  35.607 +DEFINE_SPINLOCK(kdb_immed_lk);
  35.608 +void
  35.609 +kdb_trap_immed(int reason)            /* fatal, non-fatal, kdb stack etc... */
  35.610 +{
  35.611 +    int ccpu = smp_processor_id();
  35.612 +    int disabled = !local_irq_is_enabled();
  35.613 +
  35.614 +    KDBGP("trapimm:ccpu:%d reas:%d\n", ccpu, reason);
  35.615 +    local_irq_enable();
  35.616 +    spin_lock(&kdb_immed_lk);
  35.617 +    kdb_trap_immed_reason = reason;
  35.618 +    barrier();
  35.619 +    __asm__ __volatile__ ( "int $1" );
  35.620 +    kdb_trap_immed_reason = 0;
  35.621 +
  35.622 +    spin_unlock(&kdb_immed_lk);
  35.623 +    if (disabled)
  35.624 +        local_irq_disable();
  35.625 +}
  35.626 +
  35.627 +/* called very early during init, even before all CPUs are brought online */
  35.628 +void 
  35.629 +kdb_init(void)
  35.630 +{
  35.631 +        kdb_init_cmdtab();      /* Initialize Command Table */
  35.632 +}
  35.633 +
  35.634 +static const char *
  35.635 +kdb_gettrapname(int trapno)
  35.636 +{
  35.637 +    char *ret;
  35.638 +    switch (trapno) {
  35.639 +        case  0:  ret = "Divide Error"; break;
  35.640 +        case  2:  ret = "NMI Interrupt"; break;
  35.641 +        case  3:  ret = "Int 3 Trap"; break;
  35.642 +        case  4:  ret = "Overflow Error"; break;
  35.643 +        case  6:  ret = "Invalid Opcode"; break;
  35.644 +        case  8:  ret = "Double Fault"; break;
  35.645 +        case 10:  ret = "Invalid TSS"; break;
  35.646 +        case 11:  ret = "Segment Not Present"; break;
  35.647 +        case 12:  ret = "Stack-Segment Fault"; break;
  35.648 +        case 13:  ret = "General Protection"; break;
  35.649 +        case 14:  ret = "Page Fault"; break;
  35.650 +        case 17:  ret = "Alignment Check"; break;
  35.651 +        default: ret = " ????? ";
  35.652 +    }
  35.653 +    return ret;
  35.654 +}
  35.655 +
  35.656 +
  35.657 +/* ====================== Generic tracing subsystem ======================== */
  35.658 +
  35.659 +#define KDBTRCMAX 1       /* set this to max number of recs to trace. each rec 
  35.660 +                           * is 32 bytes */
  35.661 +volatile int kdb_trcon=0; /* turn tracing ON: set here or via the trcon cmd */
  35.662 +
  35.663 +typedef struct {
  35.664 +    union {
  35.665 +        struct { uint d0; uint cpu_trcid; } s0;
  35.666 +        uint64_t l0;
  35.667 +    }u;
  35.668 +    uint64_t l1, l2, l3; 
  35.669 +} trc_rec_t;
  35.670 +
  35.671 +static volatile unsigned int trcidx;    /* points to where new entry will go */
  35.672 +static trc_rec_t trca[KDBTRCMAX];       /* trace array */
  35.673 +
  35.674 +/* atomically: add i to *p, return prev value of *p (ie, val before add) */
  35.675 +static int
  35.676 +kdb_fetch_and_add(int i, uint *p)
  35.677 +{
  35.678 +    asm volatile("lock xaddl %0, %1;" : "=r"(i) : "m"(*p), "0"(i));
  35.679 +    return i;
  35.680 +}
  35.681 +
  35.682 +/* zero out the entire buffer */
  35.683 +void 
  35.684 +kdb_trczero(void)
  35.685 +{
  35.686 +    for (trcidx = KDBTRCMAX-1; trcidx; trcidx--) {
  35.687 +        memset(&trca[trcidx], 0, sizeof(trc_rec_t));
  35.688 +    }
  35.689 +    memset(&trca[trcidx], 0, sizeof(trc_rec_t));
  35.690 +    kdbp("kdb trace buffer has been zeroed\n");
  35.691 +}
  35.692 +
  35.693 +/* add trace entry: eg.: kdbtrc(0xe0f099, intdata, vcpu, domain, 0)
  35.694 + *    where:  0xe0f099 : 24bits max trcid, lower 8 bits are set to cpuid */
  35.695 +void
  35.696 +kdbtrc(uint trcid, uint int_d0, uint64_t d1_64, uint64_t d2_64, uint64_t d3_64)
  35.697 +{
  35.698 +    uint idx;
  35.699 +
  35.700 +    if (!kdb_trcon)
  35.701 +        return;
  35.702 +
  35.703 +    idx = kdb_fetch_and_add(1, (uint*)&trcidx);
  35.704 +    idx = idx % KDBTRCMAX;
  35.705 +
  35.706 +#if 0
  35.707 +    trca[idx].u.s0.cpu_trcid = (smp_processor_id()<<24) | trcid;
  35.708 +#endif
  35.709 +    trca[idx].u.s0.cpu_trcid = (trcid<<8) | smp_processor_id();
  35.710 +    trca[idx].u.s0.d0 = int_d0;
  35.711 +    trca[idx].l1 = d1_64;
  35.712 +    trca[idx].l2 = d2_64;
  35.713 +    trca[idx].l3 = d3_64;
  35.714 +}
  35.715 +
  35.716 +/* give hints so user can print trc buffer via the dd command. last has the
  35.717 + * most recent entry */
  35.718 +void
  35.719 +kdb_trcp(void)
  35.720 +{
  35.721 +    int i = trcidx % KDBTRCMAX;
  35.722 +
  35.723 +    i = (i==0) ? KDBTRCMAX-1 : i-1;
  35.724 +    kdbp("trcbuf:    [0]: %016lx [MAX-1]: %016lx\n", &trca[0],
  35.725 +         &trca[KDBTRCMAX-1]);
  35.726 +    kdbp(" [most recent]: %016lx   trcidx: 0x%x\n", &trca[i], trcidx);
  35.727 +}
  35.728 +
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/xen/kdb/x86/Makefile	Thu Feb 03 15:42:41 2011 -0800
    36.3 @@ -0,0 +1,3 @@
    36.4 +
    36.5 +obj-y    := kdb_wp.o
    36.6 +subdir-y += udis86-1.6
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/xen/kdb/x86/kdb_wp.c	Thu Feb 03 15:42:41 2011 -0800
    37.3 @@ -0,0 +1,286 @@
    37.4 +/*
    37.5 + * Copyright (C) 2009, Mukesh Rathor, Oracle Corp.  All rights reserved.
    37.6 + *
    37.7 + * This program is free software; you can redistribute it and/or
    37.8 + * modify it under the terms of the GNU General Public
    37.9 + * License v2 as published by the Free Software Foundation.
   37.10 + *
   37.11 + * This program is distributed in the hope that it will be useful,
   37.12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   37.13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   37.14 + * General Public License for more details.
   37.15 + *
   37.16 + * You should have received a copy of the GNU General Public
   37.17 + * License along with this program; if not, write to the
   37.18 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   37.19 + * Boston, MA 021110-1307, USA.
   37.20 + */
   37.21 +
   37.22 +#include "../include/kdbinc.h"
   37.23 +
   37.24 +#if 0
   37.25 +#define DR6_BT  0x00008000
   37.26 +#define DR6_BS  0x00004000
   37.27 +#define DR6_BD  0x00002000
   37.28 +#endif
   37.29 +#define DR6_B3  0x00000008
   37.30 +#define DR6_B2  0x00000004
   37.31 +#define DR6_B1  0x00000002
   37.32 +#define DR6_B0  0x00000001
   37.33 +
   37.34 +#define KDB_MAXWP 4                          /* DR0 thru DR3 */
   37.35 +
   37.36 +struct kdb_wp {
   37.37 +    kdbma_t  wp_addr;
   37.38 +    int      wp_rwflag;
   37.39 +    int      wp_len;
   37.40 +    int      wp_deleted;                     /* pending delete */
   37.41 +};
   37.42 +static struct kdb_wp kdb_wpa[KDB_MAXWP];
   37.43 +
   37.44 +
   37.45 +
   37.46 +/* Set G0-G3 bits in DR7. this does global enable of the corresponding wp */
   37.47 +static void
   37.48 +kdb_set_gx_in_dr7(int regno, kdbma_t *dr7p)
   37.49 +{
   37.50 +    if (regno == 0)
   37.51 +        *dr7p = *dr7p | 0x2;
   37.52 +    else if (regno == 1)
   37.53 +        *dr7p = *dr7p | 0x8;
   37.54 +    else if (regno == 2)
   37.55 +        *dr7p = *dr7p | 0x20;
   37.56 +    else if (regno == 3)
   37.57 +        *dr7p = *dr7p | 0x80;
   37.58 +}
   37.59 +
   37.60 +/* Set LEN0 - LEN3 pair bits in DR7 (len should be 1 2 4 or 8) */
   37.61 +static void
   37.62 +kdb_set_len_in_dr7(int regno, kdbma_t *dr7p, int len)
   37.63 +{
   37.64 +    int lenbits = (len == 8) ? 2 : len-1;
   37.65 +
   37.66 +    *dr7p &= ~(0x3 << (18 + 4*regno));
   37.67 +    *dr7p |= ((ulong)(lenbits & 0x3) << (18 + 4*regno));
   37.68 +}
   37.69 +
   37.70 +static void
   37.71 +kdb_set_dr7_rw(int regno, kdbma_t *dr7p, int rw)
   37.72 +{
   37.73 +    *dr7p &= ~(0x3 << (16 + 4*regno));
   37.74 +    *dr7p |= ((ulong)(rw & 0x3)) << (16 + 4*regno);
   37.75 +}
   37.76 +
   37.77 +/* get value of a debug register: DR0-DR3 DR6 DR7. other values return 0 */
   37.78 +kdbma_t
   37.79 +kdb_rd_dbgreg(int regnum)
   37.80 +{
   37.81 +    kdbma_t contents = 0;
   37.82 +
   37.83 +    if (regnum == 0)
   37.84 +        __asm__ ("movq %%db0,%0\n\t":"=r"(contents));
   37.85 +    else if (regnum == 1)
   37.86 +        __asm__ ("movq %%db1,%0\n\t":"=r"(contents));
   37.87 +    else if (regnum == 2)
   37.88 +        __asm__ ("movq %%db2,%0\n\t":"=r"(contents));
   37.89 +    else if (regnum == 3)
   37.90 +        __asm__ ("movq %%db3,%0\n\t":"=r"(contents));
   37.91 +    else if (regnum == 6)
   37.92 +        __asm__ ("movq %%db6,%0\n\t":"=r"(contents));
   37.93 +    else if (regnum == 7)
   37.94 +        __asm__ ("movq %%db7,%0\n\t":"=r"(contents));
   37.95 +
   37.96 +    return contents;
   37.97 +}
   37.98 +
   37.99 +static void
  37.100 +kdb_wr_dbgreg(int regnum, kdbma_t contents)
  37.101 +{
  37.102 +    if (regnum == 0)
  37.103 +        __asm__ ("movq %0,%%db0\n\t"::"r"(contents));
  37.104 +    else if (regnum == 1)
  37.105 +        __asm__ ("movq %0,%%db1\n\t"::"r"(contents));
  37.106 +    else if (regnum == 2)
  37.107 +        __asm__ ("movq %0,%%db2\n\t"::"r"(contents));
  37.108 +    else if (regnum == 3)
  37.109 +        __asm__ ("movq %0,%%db3\n\t"::"r"(contents));
  37.110 +    else if (regnum == 6)
  37.111 +        __asm__ ("movq %0,%%db6\n\t"::"r"(contents));
  37.112 +    else if (regnum == 7)
  37.113 +        __asm__ ("movq %0,%%db7\n\t"::"r"(contents));
  37.114 +}
  37.115 +
  37.116 +static void
  37.117 +kdb_print_wp_info(char *strp, int idx)
  37.118 +{
  37.119 +    kdbp("%s[%d]:%016lx len:%d ", strp, idx, kdb_wpa[idx].wp_addr,
  37.120 +         kdb_wpa[idx].wp_len);
  37.121 +    if (kdb_wpa[idx].wp_rwflag == 1)
  37.122 +        kdbp("on data write only\n");
  37.123 +    else if (kdb_wpa[idx].wp_rwflag == 2)
  37.124 +        kdbp("on IO read/write\n");
  37.125 +    else 
  37.126 +        kdbp("on data read/write\n");
  37.127 +}
  37.128 +
  37.129 +/*
  37.130 + * Returns : 0 if not one of ours
  37.131 + *           1 if one of ours
  37.132 + */
  37.133 +int
  37.134 +kdb_check_watchpoints(struct cpu_user_regs *regs)
  37.135 +{
  37.136 +    int wpnum;
  37.137 +    kdbma_t dr6 = kdb_rd_dbgreg(6);
  37.138 +
  37.139 +    KDBGP1("check_wp: IP:%lx EFLAGS:%lx\n", regs->rip, regs->rflags);
  37.140 +    if (dr6 & DR6_B0)
  37.141 +        wpnum = 0;
  37.142 +    else if (dr6 & DR6_B1)
  37.143 +        wpnum = 1;
  37.144 +    else if (dr6 & DR6_B2)
  37.145 +        wpnum = 2;
  37.146 +    else if (dr6 & DR6_B3)
  37.147 +        wpnum = 3;
  37.148 +    else
  37.149 +        return 0;
  37.150 +
  37.151 +    kdb_print_wp_info("Watchpoint ", wpnum);
  37.152 +    return 1;
  37.153 +}
  37.154 +
  37.155 +/* set a watchpoint at a given address 
  37.156 + * PreCondition: addr != 0 */
  37.157 +static void
  37.158 +kdb_set_wp(kdbva_t addr, int rwflag, int len)
  37.159 +{
  37.160 +    int regno;
  37.161 +
  37.162 +    for (regno=0; regno < KDB_MAXWP; regno++) {
  37.163 +        if (kdb_wpa[regno].wp_addr == addr && !kdb_wpa[regno].wp_deleted) {
  37.164 +            kdbp("Watchpoint already set\n");
  37.165 +            return;
  37.166 +        }
  37.167 +    }
  37.168 +    for (regno=0; regno < KDB_MAXWP && kdb_wpa[regno].wp_addr; regno++);
  37.169 +    if (regno >= KDB_MAXWP) {
  37.170 +        kdbp("watchpoint table full. limit:%d\n", KDB_MAXWP);
  37.171 +        return;
  37.172 +    }
  37.173 +    kdb_wpa[regno].wp_addr = addr;
  37.174 +    kdb_wpa[regno].wp_rwflag = rwflag;
  37.175 +    kdb_wpa[regno].wp_len = len;
  37.176 +    kdb_print_wp_info("Watchpoint set ", regno);
  37.177 +}
  37.178 +
  37.179 +/* write reg DR0-3 with address. Update corresponding bits in DR7 */
  37.180 +static void
  37.181 +kdb_install_watchpoint(int regno, kdbma_t *dr7p)
  37.182 +{
  37.183 +    kdb_set_gx_in_dr7(regno, dr7p);
  37.184 +    kdb_set_len_in_dr7(regno, dr7p, kdb_wpa[regno].wp_len); 
  37.185 +    kdb_set_dr7_rw(regno, dr7p, kdb_wpa[regno].wp_rwflag);
  37.186 +    kdb_wr_dbgreg(regno, kdb_wpa[regno].wp_addr);
  37.187 +
  37.188 +    KDBGP1("ccpu:%d installed wp. addr:%lx rw:%x len:%x dr7:%016lx\n",
  37.189 +           smp_processor_id(), kdb_wpa[regno].wp_addr, 
  37.190 +           kdb_wpa[regno].wp_rwflag, kdb_wpa[regno].wp_len, *dr7p);
  37.191 +}
  37.192 +
  37.193 +/* clear G0-G3 bits in DR7 for given DR0-3 */
  37.194 +static void
  37.195 +kdb_clear_dr7_gx(int regno, kdbma_t *dr7p)
  37.196 +{
  37.197 +    if (regno == 0)
  37.198 +        *dr7p = *dr7p & ~0x2;
  37.199 +    else if (regno == 1)
  37.200 +        *dr7p = *dr7p & ~0x8;
  37.201 +    else if (regno == 2)
  37.202 +        *dr7p = *dr7p & ~0x20;
  37.203 +    else if (regno == 3)
  37.204 +        *dr7p = *dr7p & ~0x80;
  37.205 +}
  37.206 +
  37.207 +/* update dr7 once, as it's slow to update debug regs and cpu's will still be 
  37.208 + * paused when leaving kdb.
  37.209 + *
  37.210 + * Just leave DR0-3 clobbered but remove bits from DR7 to disable wp 
  37.211 + */
  37.212 +void
  37.213 +kdb_install_watchpoints(void)
  37.214 +{
  37.215 +    int regno;
  37.216 +    kdbma_t dr7 = kdb_rd_dbgreg(7);
  37.217 +
  37.218 +    for (regno=0; regno < KDB_MAXWP; regno++) {
  37.219 +        if (kdb_wpa[regno].wp_deleted) {
  37.220 +            kdb_clear_dr7_gx(regno, &dr7);
  37.221 +            memset(&kdb_wpa[regno], 0, sizeof(kdb_wpa[regno]));
  37.222 +            continue;
  37.223 +        }
  37.224 +        if (kdb_wpa[regno].wp_addr)
  37.225 +            kdb_install_watchpoint(regno, &dr7);
  37.226 +    }
  37.227 +    /* always clear DR6 when leaving */
  37.228 +    kdb_wr_dbgreg(6, 0);
  37.229 +    kdb_wr_dbgreg(7, dr7);
  37.230 +}
  37.231 +
  37.232 +/* clear watchpoint/s. wpnum == -1 to clear all watchpoints */
  37.233 +void
  37.234 +kdb_clear_wps(int wpnum)
  37.235 +{
  37.236 +    int i;
  37.237 +
  37.238 +    if (wpnum >= KDB_MAXWP) {
  37.239 +        kdbp("Invalid wpnum %d\n", wpnum);
  37.240 +        return;
  37.241 +    }
  37.242 +    if (wpnum >=0) {
  37.243 +        if (kdb_wpa[wpnum].wp_addr) {
  37.244 +            kdb_wpa[wpnum].wp_deleted = 1;
  37.245 +            kdb_print_wp_info("Deleted watchpoint", wpnum);
  37.246 +        } else
  37.247 +            kdbp("watchpoint %d not set\n", wpnum);
  37.248 +        return;
  37.249 +    }
  37.250 +    for (i=0; i < KDB_MAXWP; i++) {
  37.251 +        if (kdb_wpa[i].wp_addr) {
  37.252 +            kdb_wpa[i].wp_deleted = 1;
  37.253 +            kdb_print_wp_info("Deleted watchpoint", i);
  37.254 +        }
  37.255 +    }
  37.256 +}
  37.257 +
  37.258 +/* display any watchpoints that are set */
  37.259 +static void
  37.260 +kdb_display_wps(void)
  37.261 +{
  37.262 +    int i;
  37.263 +    for (i=0; i < KDB_MAXWP; i++)
  37.264 +        if (kdb_wpa[i].wp_addr && !kdb_wpa[i].wp_deleted) 
  37.265 +            kdb_print_wp_info("", i);
  37.266 +}
  37.267 +
  37.268 +/* 
  37.269 + * Display or Set hardware breakpoints, ie, watchpoints:
  37.270 + *   - Upto 4 are allowed
  37.271 + *   
  37.272 + *  rw_flag should be one of: 
  37.273 + *     01 == break on data write only
  37.274 + *     10 == break on IO read/write
  37.275 + *     11 == Break on data reads or writes
  37.276 + *
  37.277 + *  len should be one of : 1 2 4 8 
  37.278 + */
  37.279 +void
  37.280 +kdb_do_watchpoints(kdbva_t addr, int rw_flag, int len)
  37.281 +{
  37.282 +    if (addr == 0) {
  37.283 +        kdb_display_wps();        /* display set watchpoints */
  37.284 +        return;
  37.285 +    }
  37.286 +    kdb_set_wp(addr, rw_flag, len);
  37.287 +    return;
  37.288 +}
  37.289 +
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/xen/kdb/x86/udis86-1.6/LICENSE	Thu Feb 03 15:42:41 2011 -0800
    38.3 @@ -0,0 +1,22 @@
    38.4 +Copyright (c) 2002, 2003, 2004, 2005, 2006 <vivek@sig9.com>
    38.5 +All rights reserved.
    38.6 +
    38.7 +Redistribution and use in source and binary forms, with or without modification, 
    38.8 +are permitted provided that the following conditions are met:
    38.9 +
   38.10 +    * Redistributions of source code must retain the above copyright notice, 
   38.11 +      this list of conditions and the following disclaimer.
   38.12 +    * Redistributions in binary form must reproduce the above copyright notice, 
   38.13 +      this list of conditions and the following disclaimer in the documentation 
   38.14 +      and/or other materials provided with the distribution.
   38.15 +
   38.16 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
   38.17 +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
   38.18 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
   38.19 +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
   38.20 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
   38.21 +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
   38.22 +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
   38.23 +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   38.24 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
   38.25 +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/xen/kdb/x86/udis86-1.6/Makefile	Thu Feb 03 15:42:41 2011 -0800
    39.3 @@ -0,0 +1,5 @@
    39.4 +
    39.5 +CFLAGS		+= -D__UD_STANDALONE__
    39.6 +obj-y		:= mnemonics.o opcmap.o input.o decode.o syn.o syn-intel.o \
    39.7 +		   syn-att.o udis86.o kdb_dis.o
    39.8 +
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/xen/kdb/x86/udis86-1.6/README	Thu Feb 03 15:42:41 2011 -0800
    40.3 @@ -0,0 +1,10 @@
    40.4 +
    40.5 +http://udis86.sourceforge.net/
    40.6 +udis86-1.6 : 
    40.7 +  - cd libudis86
    40.8 +  - cp *c to here
    40.9 +  - cp *h to here
   40.10 +   
   40.11 +Mukesh Rathor
   40.12 +04/30/2008
   40.13 +
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/xen/kdb/x86/udis86-1.6/decode.c	Thu Feb 03 15:42:41 2011 -0800
    41.3 @@ -0,0 +1,1047 @@
    41.4 +/* -----------------------------------------------------------------------------
    41.5 + * decode.c
    41.6 + *
    41.7 + * Copyright (c) 2005, 2006, Vivek Mohan <vivek@sig9.com>
    41.8 + * All rights reserved. See LICENSE
    41.9 + * -----------------------------------------------------------------------------
   41.10 + */
   41.11 +
   41.12 +#include "../../include/kdbinc.h"
   41.13 +
   41.14 +/* #include <string.h> */
   41.15 +
   41.16 +#include "types.h"
   41.17 +#include "input.h"
   41.18 +#include "opcmap.h"
   41.19 +#include "mnemonics.h"
   41.20 +
   41.21 +/* The max number of prefixes to an instruction */
   41.22 +#define MAX_PREFIXES    15
   41.23 +
   41.24 +/* register types */
   41.25 +#define T_NONE  0
   41.26 +#define T_GPR   1
   41.27 +#define T_MMX   2
   41.28 +#define T_CRG   3
   41.29 +#define T_DBG   4
   41.30 +#define T_SEG   5
   41.31 +#define T_XMM   6
   41.32 +
   41.33 +struct map_entry* ud_me_db(void);
   41.34 +struct map_entry* ud_me_invalid(void);
   41.35 +
   41.36 +/* -----------------------------------------------------------------------------
   41.37 + * resolve_oprsize()- Resolves the size of operand depending on the current
   41.38 + * disassembly mode, effective operand sizes, etc.
   41.39 + * -----------------------------------------------------------------------------
   41.40 + */
   41.41 +static unsigned int 
   41.42 +resolve_oprsize(register struct ud* u, unsigned int s)
   41.43 +{
   41.44 +  switch (s) {
   41.45 +        case SZ_V:      return (u->opr_mode);
   41.46 +        case SZ_Z:      return (u->opr_mode == 16) ? 16 : 32;
   41.47 +        case SZ_P:      return (u->opr_mode == 16) ? SZ_WP : SZ_DP;
   41.48 +        case SZ_MDQ:    return (u->opr_mode == 16) ? 32 : u->opr_mode;
   41.49 +        case SZ_RDQ:    return (u->dis_mode == 64) ? 64 : 32;
   41.50 +        default:        return s;
   41.51 +  }
   41.52 +}
   41.53 +
   41.54 +/* -----------------------------------------------------------------------------
   41.55 + * resolve_mnemonic()- Resolves the correct mnemonic that depends on the 
   41.56 + * current effective operand or address mode.
   41.57 + * -----------------------------------------------------------------------------
   41.58 + */
   41.59 +static enum ud_mnemonic_code resolve_mnemonic_by_mode( struct ud* u )
   41.60 +{
   41.61 +  /* operand size == 32 */
   41.62 +  if ( u->opr_mode == 32 ) {
   41.63 +        switch ( u->mnemonic ) {
   41.64 +                case UD_Icbw:   return UD_Icwde;
   41.65 +                case UD_Icwd:   return UD_Icdq;
   41.66 +                case UD_Ilodsw: return UD_Ilodsd;
   41.67 +                case UD_Imovsw: return UD_Imovsd;
   41.68 +                case UD_Icmpsw: return UD_Icmpsd;
   41.69 +                case UD_Iinsw:  return UD_Iinsd;
   41.70 +                case UD_Ioutsw: return UD_Ioutsd;
   41.71 +                case UD_Ipushfw:return UD_Ipushfd;
   41.72 +                case UD_Ipopfw: return UD_Ipopfd;
   41.73 +                case UD_Istosw: return UD_Istosd;
   41.74 +                case UD_Iscasw: return UD_Iscasd;
   41.75 +                case UD_Iiretw: return UD_Iiretd;
   41.76 +                case UD_Ipusha: return UD_Ipushad;
   41.77 +                case UD_Ipopa:  return UD_Ipopad;
   41.78 +                default:        break;
   41.79 +        }
   41.80 +  } /* operand size == 64*/
   41.81 +  else if ( u->opr_mode == 64 ) {
   41.82 +        switch( u->mnemonic ) {
   41.83 +                case UD_Icbw:   return UD_Icdqe;
   41.84 +                case UD_Icwd:   return UD_Icqo;
   41.85 +                case UD_Ilodsw: return UD_Ilodsq;
   41.86 +                case UD_Imovsw: return UD_Imovsq;
   41.87 +                case UD_Icmpsw: return UD_Icmpsq;
   41.88 +                case UD_Iinsw:  return UD_Iinsd;
   41.89 +                case UD_Ioutsw: return UD_Ioutsd;
   41.90 +                case UD_Icmpxchg8b: return UD_Icmpxchg16b;              
   41.91 +                case UD_Istosw: return UD_Istosq;
   41.92 +                case UD_Iscasw: return UD_Iscasq;
   41.93 +                case UD_Iiretw: return UD_Iiretq;
   41.94 +                case UD_Ipushfw:return UD_Ipushfq;
   41.95 +                case UD_Ipopfw: return UD_Ipopfq;
   41.96 +                default:        break; 
   41.97 +        } 
   41.98 +  }
   41.99 +
  41.100 +  /* address == 32 */
  41.101 +  if ( u->adr_mode == 32 ) {
  41.102 +        switch( u->mnemonic ) {
  41.103 +                case UD_Ijcxz:  return UD_Ijecxz;
  41.104 +                default:        break; 
  41.105 +        } 
  41.106 +  } /* address == 64 */
  41.107 +  else if ( u->adr_mode == 64 ) {
  41.108 +        switch( u->mnemonic ) {
  41.109 +                case UD_Ijcxz:  return UD_Ijrcxz;
  41.110 +                default:        break; 
  41.111 +        } 
  41.112 +  }
  41.113 +
  41.114 +  return u->mnemonic;
  41.115 +} 
  41.116 +
  41.117 +static int resolve_mnemonic( struct ud* u )
  41.118 +{
  41.119 +  /* the opcode map has hardcoded information about the
  41.120 +   * dependency of the instruction mnemonic on the mode.
  41.121 +   */
  41.122 +  if ( P_DEPM( u->mapen->prefix ) ) {
  41.123 +        u->mnemonic = resolve_mnemonic_by_mode( u );
  41.124 +  }
  41.125 +  /* far/near flags */
  41.126 +  u->br_far = 0;
  41.127 +  u->br_near = 0;
  41.128 +  /* readjust operand sizes for call/jmp instrcutions */
  41.129 +  if ( u->mnemonic == UD_Icall || u->mnemonic == UD_Ijmp ) {
  41.130 +        /* WP: 16bit pointer */
  41.131 +        if ( u->operand[ 0 ].size == SZ_WP ) {
  41.132 +                u->operand[ 0 ].size = 16;
  41.133 +                u->br_far = 1;
  41.134 +                u->br_near= 0;
  41.135 +        /* DP: 32bit pointer */
  41.136 +        } else if ( u->operand[ 0 ].size == SZ_DP ) {
  41.137 +                u->operand[ 0 ].size = 32;
  41.138 +                u->br_far = 1;
  41.139 +                u->br_near= 0;
  41.140 +        } else {
  41.141 +                u->br_far = 0;
  41.142 +                u->br_near= 1;
  41.143 +        }
  41.144 +  /* resolve 3dnow weirdness. */
  41.145 +  } else if ( u->mnemonic == UD_I3dnow ) {
  41.146 +        u->mnemonic = ud_map_get_3dnow( inp_curr( u ) );
  41.147 +  }
  41.148 +  /* SWAPGS is only valid in 64bits mode */
  41.149 +  if ( u->mnemonic == UD_Iswapgs && u->dis_mode != 64 ) {
  41.150 +        u->error = 1;
  41.151 +        return -1;
  41.152 +  }
  41.153 +
  41.154 +  return 0;
  41.155 +}
  41.156 +
  41.157 +
  41.158 +/* -----------------------------------------------------------------------------
  41.159 + * decode_a()- Decodes operands of the type seg:offset
  41.160 + * -----------------------------------------------------------------------------
  41.161 + */
  41.162 +static void 
  41.163 +decode_a(struct ud* u, struct ud_operand *op)
  41.164 +{
  41.165 +  if (u->opr_mode == 16) {      
  41.166 +        /* seg16:off16 */
  41.167 +        op->type = UD_OP_PTR;
  41.168 +        op->size = 32;
  41.169 +        op->lval.ptr.off = inp_uint16(u);
  41.170 +        op->lval.ptr.seg = inp_uint16(u);
  41.171 +  } else {
  41.172 +        /* seg16:off32 */
  41.173 +        op->type = UD_OP_PTR;
  41.174 +        op->size = 48;
  41.175 +        op->lval.ptr.off = inp_uint32(u);
  41.176 +        op->lval.ptr.seg = inp_uint16(u);
  41.177 +  }
  41.178 +}
  41.179 +
  41.180 +/* -----------------------------------------------------------------------------
  41.181 + * decode_gpr() - Returns decoded General Purpose Register 
  41.182 + * -----------------------------------------------------------------------------
  41.183 + */
  41.184 +static enum ud_type 
  41.185 +decode_gpr(register struct ud* u, unsigned int s, unsigned char rm)
  41.186 +{
  41.187 +  s = resolve_oprsize(u, s);
  41.188 +                
  41.189 +  switch (s) {
  41.190 +        case 64:
  41.191 +                return UD_R_RAX + rm;
  41.192 +        case SZ_DP:
  41.193 +        case 32:
  41.194 +                return UD_R_EAX + rm;
  41.195 +        case SZ_WP:
  41.196 +        case 16:
  41.197 +                return UD_R_AX  + rm;
  41.198 +        case  8:
  41.199 +                if (u->dis_mode == 64 && u->pfx_rex) {
  41.200 +                        if (rm >= 4)
  41.201 +                                return UD_R_SPL + (rm-4);
  41.202 +                        return UD_R_AL + rm;
  41.203 +                } else return UD_R_AL + rm;
  41.204 +        default:
  41.205 +                return 0;
  41.206 +  }
  41.207 +}
  41.208 +
  41.209 +/* -----------------------------------------------------------------------------
  41.210 + * resolve_gpr64() - 64bit General Purpose Register-Selection. 
  41.211 + * -----------------------------------------------------------------------------
  41.212 + */
  41.213 +static enum ud_type 
  41.214 +resolve_gpr64(struct ud* u, enum map_operand_type gpr_op)
  41.215 +{
  41.216 +  if (gpr_op >= OP_rAXr8 && gpr_op <= OP_rDIr15)
  41.217 +        gpr_op = (gpr_op - OP_rAXr8) | (P_REX_B(u->pfx_rex) << 3);                      
  41.218 +  else  gpr_op = (gpr_op - OP_rAX);
  41.219 +
  41.220 +  if (u->opr_mode == 16)
  41.221 +        return gpr_op + UD_R_AX;
  41.222 +  if (u->dis_mode == 32 || 
  41.223 +        (u->opr_mode == 32 && ! (P_REX_W(u->pfx_rex) || u->default64))) {
  41.224 +        return gpr_op + UD_R_EAX;
  41.225 +  }
  41.226 +
  41.227 +  return gpr_op + UD_R_RAX;
  41.228 +}
  41.229 +
  41.230 +/* -----------------------------------------------------------------------------
  41.231 + * resolve_gpr32 () - 32bit General Purpose Register-Selection. 
  41.232 + * -----------------------------------------------------------------------------
  41.233 + */
  41.234 +static enum ud_type 
  41.235 +resolve_gpr32(struct ud* u, enum map_operand_type gpr_op)
  41.236 +{
  41.237 +  gpr_op = gpr_op - OP_eAX;
  41.238 +
  41.239 +  if (u->opr_mode == 16) 
  41.240 +        return gpr_op + UD_R_AX;
  41.241 +
  41.242 +  return gpr_op +  UD_R_EAX;
  41.243 +}
  41.244 +
  41.245 +/* -----------------------------------------------------------------------------
  41.246 + * resolve_reg() - Resolves the register type 
  41.247 + * -----------------------------------------------------------------------------
  41.248 + */
  41.249 +static enum ud_type 
  41.250 +resolve_reg(struct ud* u, unsigned int type, unsigned char i)
  41.251 +{
  41.252 +  switch (type) {
  41.253 +        case T_MMX :    return UD_R_MM0  + (i & 7);
  41.254 +        case T_XMM :    return UD_R_XMM0 + i;
  41.255 +        case T_CRG :    return UD_R_CR0  + i;
  41.256 +        case T_DBG :    return UD_R_DR0  + i;
  41.257 +        case T_SEG :    return UD_R_ES   + (i & 7);
  41.258 +        case T_NONE:
  41.259 +        default:        return UD_NONE;
  41.260 +  }
  41.261 +}
  41.262 +
  41.263 +/* -----------------------------------------------------------------------------
  41.264 + * decode_imm() - Decodes Immediate values.
  41.265 + * -----------------------------------------------------------------------------
  41.266 + */
  41.267 +static void 
  41.268 +decode_imm(struct ud* u, unsigned int s, struct ud_operand *op)
  41.269 +{
  41.270 +  op->size = resolve_oprsize(u, s);
  41.271 +  op->type = UD_OP_IMM;
  41.272 +
  41.273 +  switch (op->size) {
  41.274 +        case  8: op->lval.sbyte = inp_uint8(u);   break;
  41.275 +        case 16: op->lval.uword = inp_uint16(u);  break;
  41.276 +        case 32: op->lval.udword = inp_uint32(u); break;
  41.277 +        case 64: op->lval.uqword = inp_uint64(u); break;
  41.278 +        default: return;
  41.279 +  }
  41.280 +}
  41.281 +
  41.282 +/* -----------------------------------------------------------------------------
  41.283 + * decode_modrm() - Decodes ModRM Byte
  41.284 + * -----------------------------------------------------------------------------
  41.285 + */
  41.286 +static void 
  41.287 +decode_modrm(struct ud* u, struct ud_operand *op, unsigned int s, 
  41.288 +             unsigned char rm_type, struct ud_operand *opreg, 
  41.289 +             unsigned char reg_size, unsigned char reg_type)
  41.290 +{
  41.291 +  unsigned char mod, rm, reg;
  41.292 +
  41.293 +  inp_next(u);
  41.294 +
  41.295 +  /* get mod, r/m and reg fields */
  41.296 +  mod = MODRM_MOD(inp_curr(u));
  41.297 +  rm  = (P_REX_B(u->pfx_rex) << 3) | MODRM_RM(inp_curr(u));
  41.298 +  reg = (P_REX_R(u->pfx_rex) << 3) | MODRM_REG(inp_curr(u));
  41.299 +
  41.300 +  op->size = resolve_oprsize(u, s);
  41.301 +
  41.302 +  /* if mod is 11b, then the UD_R_m specifies a gpr/mmx/sse/control/debug */
  41.303 +  if (mod == 3) {
  41.304 +        op->type = UD_OP_REG;
  41.305 +        if (rm_type ==  T_GPR)
  41.306 +                op->base = decode_gpr(u, op->size, rm);
  41.307 +        else    op->base = resolve_reg(u, rm_type, (P_REX_B(u->pfx_rex) << 3) | (rm&7));
  41.308 +  } 
  41.309 +  /* else its memory addressing */  
  41.310 +  else {
  41.311 +        op->type = UD_OP_MEM;
  41.312 +
  41.313 +        /* 64bit addressing */
  41.314 +        if (u->adr_mode == 64) {
  41.315 +
  41.316 +                op->base = UD_R_RAX + rm;
  41.317 +
  41.318 +                /* get offset type */
  41.319 +                if (mod == 1)
  41.320 +                        op->offset = 8;
  41.321 +                else if (mod == 2)
  41.322 +                        op->offset = 32;
  41.323 +                else if (mod == 0 && (rm & 7) == 5) {                   
  41.324 +                        op->base = UD_R_RIP;
  41.325 +                        op->offset = 32;
  41.326 +                } else  op->offset = 0;
  41.327 +
  41.328 +                /* Scale-Index-Base (SIB) */
  41.329 +                if ((rm & 7) == 4) {
  41.330 +                        inp_next(u);
  41.331 +                        
  41.332 +                        op->scale = (1 << SIB_S(inp_curr(u))) & ~1;
  41.333 +                        op->index = UD_R_RAX + (SIB_I(inp_curr(u)) | (P_REX_X(u->pfx_rex) << 3));
  41.334 +                        op->base  = UD_R_RAX + (SIB_B(inp_curr(u)) | (P_REX_B(u->pfx_rex) << 3));
  41.335 +
  41.336 +                        /* special conditions for base reference */
  41.337 +                        if (op->index == UD_R_RSP) {
  41.338 +                                op->index = UD_NONE;
  41.339 +                                op->scale = UD_NONE;
  41.340 +                        }
  41.341 +
  41.342 +                        if (op->base == UD_R_RBP || op->base == UD_R_R13) {
  41.343 +                                if (mod == 0) 
  41.344 +                                        op->base = UD_NONE;
  41.345 +                                if (mod == 1)
  41.346 +                                        op->offset = 8;
  41.347 +                                else op->offset = 32;
  41.348 +                        }
  41.349 +                }
  41.350 +        } 
  41.351 +
  41.352 +        /* 32-Bit addressing mode */
  41.353 +        else if (u->adr_mode == 32) {
  41.354 +
  41.355 +                /* get base */
  41.356 +                op->base = UD_R_EAX + rm;
  41.357 +
  41.358 +                /* get offset type */
  41.359 +                if (mod == 1)
  41.360 +                        op->offset = 8;
  41.361 +                else if (mod == 2)
  41.362 +                        op->offset = 32;
  41.363 +                else if (mod == 0 && rm == 5) {
  41.364 +                        op->base = UD_NONE;
  41.365 +                        op->offset = 32;
  41.366 +                } else  op->offset = 0;
  41.367 +
  41.368 +                /* Scale-Index-Base (SIB) */
  41.369 +                if ((rm & 7) == 4) {
  41.370 +                        inp_next(u);
  41.371 +
  41.372 +                        op->scale = (1 << SIB_S(inp_curr(u))) & ~1;
  41.373 +                        op->index = UD_R_EAX + (SIB_I(inp_curr(u)) | (P_REX_X(u->pfx_rex) << 3));
  41.374 +                        op->base  = UD_R_EAX + (SIB_B(inp_curr(u)) | (P_REX_B(u->pfx_rex) << 3));
  41.375 +
  41.376 +                        if (op->index == UD_R_ESP) {
  41.377 +                                op->index = UD_NONE;
  41.378 +                                op->scale = UD_NONE;
  41.379 +                        }
  41.380 +
  41.381 +                        /* special condition for base reference */
  41.382 +                        if (op->base == UD_R_EBP) {
  41.383 +                                if (mod == 0)
  41.384 +                                        op->base = UD_NONE;
  41.385 +                                if (mod == 1)
  41.386 +                                        op->offset = 8;
  41.387 +                                else op->offset = 32;
  41.388 +                        }
  41.389 +                }
  41.390 +        } 
  41.391 +
  41.392 +        /* 16bit addressing mode */
  41.393 +        else  {
  41.394 +                switch (rm) {
  41.395 +                        case 0: op->base = UD_R_BX; op->index = UD_R_SI; break;
  41.396 +                        case 1: op->base = UD_R_BX; op->index = UD_R_DI; break;
  41.397 +                        case 2: op->base = UD_R_BP; op->index = UD_R_SI; break;
  41.398 +                        case 3: op->base = UD_R_BP; op->index = UD_R_DI; break;
  41.399 +                        case 4: op->base = UD_R_SI; break;
  41.400 +                        case 5: op->base = UD_R_DI; break;
  41.401 +                        case 6: op->base = UD_R_BP; break;
  41.402 +                        case 7: op->base = UD_R_BX; break;
  41.403 +                }
  41.404 +
  41.405 +                if (mod == 0 && rm == 6) {
  41.406 +                        op->offset= 16;
  41.407 +                        op->base = UD_NONE;
  41.408 +                }
  41.409 +                else if (mod == 1)
  41.410 +                        op->offset = 8;
  41.411 +                else if (mod == 2) 
  41.412 +                        op->offset = 16;
  41.413 +        }
  41.414 +  }  
  41.415 +
  41.416 +  /* extract offset, if any */
  41.417 +  switch(op->offset) {
  41.418 +        case 8 : op->lval.ubyte  = inp_uint8(u);  break;
  41.419 +        case 16: op->lval.uword  = inp_uint16(u);  break;
  41.420 +        case 32: op->lval.udword = inp_uint32(u); break;
  41.421 +        case 64: op->lval.uqword = inp_uint64(u); break;
  41.422 +        default: break;
  41.423 +  }
  41.424 +
  41.425 +  /* resolve register encoded in reg field */
  41.426 +  if (opreg) {
  41.427 +        opreg->type = UD_OP_REG;
  41.428 +        opreg->size = resolve_oprsize(u, reg_size);
  41.429 +        if (reg_type == T_GPR) 
  41.430 +                opreg->base = decode_gpr(u, opreg->size, reg);
  41.431 +        else opreg->base = resolve_reg(u, reg_type, reg);
  41.432 +  }
  41.433 +}
  41.434 +
  41.435 +/* -----------------------------------------------------------------------------
  41.436 + * decode_o() - Decodes offset
  41.437 + * -----------------------------------------------------------------------------
  41.438 + */
  41.439 +static void 
  41.440 +decode_o(struct ud* u, unsigned int s, struct ud_operand *op)
  41.441 +{
  41.442 +  switch (u->adr_mode) {
  41.443 +        case 64:
  41.444 +                op->offset = 64; 
  41.445 +                op->lval.uqword = inp_uint64(u); 
  41.446 +                break;
  41.447 +        case 32:
  41.448 +                op->offset = 32; 
  41.449 +                op->lval.udword = inp_uint32(u); 
  41.450 +                break;
  41.451 +        case 16:
  41.452 +                op->offset = 16; 
  41.453 +                op->lval.uword  = inp_uint16(u); 
  41.454 +                break;
  41.455 +        default:
  41.456 +                return;
  41.457 +  }
  41.458 +  op->type = UD_OP_MEM;
  41.459 +  op->size = resolve_oprsize(u, s);
  41.460 +}
  41.461 +
  41.462 +/* -----------------------------------------------------------------------------
  41.463 + * disasm_operands() - Disassembles Operands.
  41.464 + * -----------------------------------------------------------------------------
  41.465 + */
  41.466 +static int disasm_operands(register struct ud* u)
  41.467 +{
  41.468 +
  41.469 +
  41.470 +  /* mopXt = map entry, operand X, type; */
  41.471 +  enum map_operand_type mop1t = u->mapen->operand1.type;
  41.472 +  enum map_operand_type mop2t = u->mapen->operand2.type;
  41.473 +  enum map_operand_type mop3t = u->mapen->operand3.type;
  41.474 +
  41.475 +  /* mopXs = map entry, operand X, size */
  41.476 +  unsigned int mop1s = u->mapen->operand1.size;
  41.477 +  unsigned int mop2s = u->mapen->operand2.size;
  41.478 +  unsigned int mop3s = u->mapen->operand3.size;
  41.479 +
  41.480 +  /* iop = instruction operand */
  41.481 +  register struct ud_operand* iop = u->operand;
  41.482 +        
  41.483 +  switch(mop1t) {
  41.484 +        
  41.485 +        case OP_A :
  41.486 +                decode_a(u, &(iop[0]));
  41.487 +                break;
  41.488 +        
  41.489 +        /* M[b] ... */
  41.490 +        case OP_M :
  41.491 +                if (MODRM_MOD(inp_peek(u)) == 3)
  41.492 +                        u->error= 1;
  41.493 +        /* E, G/P/V/I/CL/1/S */
  41.494 +        case OP_E :
  41.495 +                if (mop2t == OP_G) {
  41.496 +                        decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_GPR);
  41.497 +                        if (mop3t == OP_I)
  41.498 +                                decode_imm(u, mop3s, &(iop[2]));
  41.499 +                        else if (mop3t == OP_CL) {
  41.500 +                                iop[2].type = UD_OP_REG;
  41.501 +                                iop[2].base = UD_R_CL;
  41.502 +                                iop[2].size = 8;
  41.503 +                        }
  41.504 +                }
  41.505 +                else if (mop2t == OP_P)
  41.506 +                        decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_MMX);
  41.507 +                else if (mop2t == OP_V)
  41.508 +                        decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_XMM);
  41.509 +                else if (mop2t == OP_S)
  41.510 +                        decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_SEG);
  41.511 +                else {
  41.512 +                        decode_modrm(u, &(iop[0]), mop1s, T_GPR, NULL, 0, T_NONE);
  41.513 +                        if (mop2t == OP_CL) {
  41.514 +                                iop[1].type = UD_OP_REG;
  41.515 +                                iop[1].base = UD_R_CL;
  41.516 +                                iop[1].size = 8;
  41.517 +                        } else if (mop2t == OP_I1) {
  41.518 +                                iop[1].type = UD_OP_CONST;
  41.519 +                                u->operand[1].lval.udword = 1;
  41.520 +                        } else if (mop2t == OP_I) {
  41.521 +                                decode_imm(u, mop2s, &(iop[1]));
  41.522 +                        }
  41.523 +                }
  41.524 +                break;
  41.525 +
  41.526 +        /* G, E/PR[,I]/VR */
  41.527 +        case OP_G :
  41.528 +
  41.529 +                if (mop2t == OP_M) {
  41.530 +                        if (MODRM_MOD(inp_peek(u)) == 3)
  41.531 +                                u->error= 1;
  41.532 +                        decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_GPR);
  41.533 +                } else if (mop2t == OP_E) {
  41.534 +                        decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_GPR);
  41.535 +                        if (mop3t == OP_I)
  41.536 +                                decode_imm(u, mop3s, &(iop[2]));
  41.537 +                } else if (mop2t == OP_PR) {
  41.538 +                        decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_GPR);
  41.539 +                        if (mop3t == OP_I)
  41.540 +                                decode_imm(u, mop3s, &(iop[2]));
  41.541 +                } else if (mop2t == OP_VR) {
  41.542 +                        if (MODRM_MOD(inp_peek(u)) != 3)
  41.543 +                                u->error = 1;
  41.544 +                        decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_GPR);
  41.545 +                } else if (mop2t == OP_W)
  41.546 +                        decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_GPR);
  41.547 +                break;
  41.548 +
  41.549 +        /* AL..BH, I/O/DX */
  41.550 +        case OP_AL : case OP_CL : case OP_DL : case OP_BL :
  41.551 +        case OP_AH : case OP_CH : case OP_DH : case OP_BH :
  41.552 +
  41.553 +                iop[0].type = UD_OP_REG;
  41.554 +                iop[0].base = UD_R_AL + (mop1t - OP_AL);
  41.555 +                iop[0].size = 8;
  41.556 +
  41.557 +                if (mop2t == OP_I)
  41.558 +                        decode_imm(u, mop2s, &(iop[1]));
  41.559 +                else if (mop2t == OP_DX) {
  41.560 +                        iop[1].type = UD_OP_REG;
  41.561 +                        iop[1].base = UD_R_DX;
  41.562 +                        iop[1].size = 16;
  41.563 +                }
  41.564 +                else if (mop2t == OP_O)
  41.565 +                        decode_o(u, mop2s, &(iop[1]));
  41.566 +                break;
  41.567 +
  41.568 +        /* rAX[r8]..rDI[r15], I/rAX..rDI/O */
  41.569 +        case OP_rAXr8 : case OP_rCXr9 : case OP_rDXr10 : case OP_rBXr11 :
  41.570 +        case OP_rSPr12: case OP_rBPr13: case OP_rSIr14 : case OP_rDIr15 :
  41.571 +        case OP_rAX : case OP_rCX : case OP_rDX : case OP_rBX :
  41.572 +        case OP_rSP : case OP_rBP : case OP_rSI : case OP_rDI :
  41.573 +
  41.574 +                iop[0].type = UD_OP_REG;
  41.575 +                iop[0].base = resolve_gpr64(u, mop1t);
  41.576 +
  41.577 +                if (mop2t == OP_I)
  41.578 +                        decode_imm(u, mop2s, &(iop[1]));
  41.579 +                else if (mop2t >= OP_rAX && mop2t <= OP_rDI) {
  41.580 +                        iop[1].type = UD_OP_REG;
  41.581 +                        iop[1].base = resolve_gpr64(u, mop2t);
  41.582 +                }
  41.583 +                else if (mop2t == OP_O) {
  41.584 +                        decode_o(u, mop2s, &(iop[1]));  
  41.585 +                        iop[0].size = resolve_oprsize(u, mop2s);
  41.586 +                }
  41.587 +                break;
  41.588 +
  41.589 +        /* AL[r8b]..BH[r15b], I */
  41.590 +        case OP_ALr8b : case OP_CLr9b : case OP_DLr10b : case OP_BLr11b :
  41.591 +        case OP_AHr12b: case OP_CHr13b: case OP_DHr14b : case OP_BHr15b :
  41.592 +        {
  41.593 +                ud_type_t gpr = (mop1t - OP_ALr8b) + UD_R_AL + 
  41.594 +                                                (P_REX_B(u->pfx_rex) << 3);
  41.595 +                if (UD_R_AH <= gpr && u->pfx_rex)
  41.596 +                        gpr = gpr + 4;
  41.597 +                iop[0].type = UD_OP_REG;
  41.598 +                iop[0].base = gpr;
  41.599 +                if (mop2t == OP_I)
  41.600 +                        decode_imm(u, mop2s, &(iop[1]));
  41.601 +                break;
  41.602 +        }
  41.603 +
  41.604 +        /* eAX..eDX, DX/I */
  41.605 +        case OP_eAX : case OP_eCX : case OP_eDX : case OP_eBX :
  41.606 +        case OP_eSP : case OP_eBP : case OP_eSI : case OP_eDI :
  41.607 +
  41.608 +                iop[0].type = UD_OP_REG;
  41.609 +                iop[0].base = resolve_gpr32(u, mop1t);
  41.610 +                if (mop2t == OP_DX) {
  41.611 +                        iop[1].type = UD_OP_REG;
  41.612 +                        iop[1].base = UD_R_DX;
  41.613 +                        iop[1].size = 16;
  41.614 +                } else if (mop2t == OP_I)
  41.615 +                        decode_imm(u, mop2s, &(iop[1]));
  41.616 +                break;
  41.617 +
  41.618 +        /* ES..GS */
  41.619 +        case OP_ES : case OP_CS : case OP_DS :
  41.620 +        case OP_SS : case OP_FS : case OP_GS :
  41.621 +
  41.622 +                /* in 64bits mode, only fs and gs are allowed */
  41.623 +                if (u->dis_mode == 64)
  41.624 +                        if (mop1t != OP_FS && mop1t != OP_GS)
  41.625 +                                u->error= 1;
  41.626 +                iop[0].type = UD_OP_REG;
  41.627 +                iop[0].base = (mop1t - OP_ES) + UD_R_ES;
  41.628 +                iop[0].size = 16;
  41.629 +
  41.630 +                break;
  41.631 +
  41.632 +        /* J */
  41.633 +        case OP_J :
  41.634 +                decode_imm(u, mop1s, &(iop[0]));                
  41.635 +                iop[0].type = UD_OP_JIMM;
  41.636 +                break ;
  41.637 +
  41.638 +        /* PR, I */
  41.639 +        case OP_PR:
  41.640 +                if (MODRM_MOD(inp_peek(u)) != 3)
  41.641 +                        u->error = 1;
  41.642 +                decode_modrm(u, &(iop[0]), mop1s, T_MMX, NULL, 0, T_NONE);
  41.643 +                if (mop2t == OP_I)
  41.644 +                        decode_imm(u, mop2s, &(iop[1]));
  41.645 +                break; 
  41.646 +
  41.647 +        /* VR, I */
  41.648 +        case OP_VR:
  41.649 +                if (MODRM_MOD(inp_peek(u)) != 3)
  41.650 +                        u->error = 1;
  41.651 +                decode_modrm(u, &(iop[0]), mop1s, T_XMM, NULL, 0, T_NONE);
  41.652 +                if (mop2t == OP_I)
  41.653 +                        decode_imm(u, mop2s, &(iop[1]));
  41.654 +                break; 
  41.655 +
  41.656 +        /* P, Q[,I]/W/E[,I],VR */
  41.657 +        case OP_P :
  41.658 +                if (mop2t == OP_Q) {
  41.659 +                        decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_MMX);
  41.660 +                        if (mop3t == OP_I)
  41.661 +                                decode_imm(u, mop3s, &(iop[2]));
  41.662 +                } else if (mop2t == OP_W) {
  41.663 +                        decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_MMX);
  41.664 +                } else if (mop2t == OP_VR) {
  41.665 +                        if (MODRM_MOD(inp_peek(u)) != 3)
  41.666 +                                u->error = 1;
  41.667 +                        decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_MMX);
  41.668 +                } else if (mop2t == OP_E) {
  41.669 +                        decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_MMX);
  41.670 +                        if (mop3t == OP_I)
  41.671 +                                decode_imm(u, mop3s, &(iop[2]));
  41.672 +                }
  41.673 +                break;
  41.674 +
  41.675 +        /* R, C/D */
  41.676 +        case OP_R :
  41.677 +                if (mop2t == OP_C)
  41.678 +                        decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_CRG);
  41.679 +                else if (mop2t == OP_D)
  41.680 +                        decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_DBG);
  41.681 +                break;
  41.682 +
  41.683 +        /* C, R */
  41.684 +        case OP_C :
  41.685 +                decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_CRG);
  41.686 +                break;
  41.687 +
  41.688 +        /* D, R */
  41.689 +        case OP_D :
  41.690 +                decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_DBG);
  41.691 +                break;
  41.692 +
  41.693 +        /* Q, P */
  41.694 +        case OP_Q :
  41.695 +                decode_modrm(u, &(iop[0]), mop1s, T_MMX, &(iop[1]), mop2s, T_MMX);
  41.696 +                break;
  41.697 +
  41.698 +        /* S, E */
  41.699 +        case OP_S :
  41.700 +                decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_SEG);
  41.701 +                break;
  41.702 +
  41.703 +        /* W, V */
  41.704 +        case OP_W :
  41.705 +                decode_modrm(u, &(iop[0]), mop1s, T_XMM, &(iop[1]), mop2s, T_XMM);
  41.706 +                break;
  41.707 +
  41.708 +        /* V, W[,I]/Q/M/E */
  41.709 +        case OP_V :
  41.710 +                if (mop2t == OP_W) {
  41.711 +                        /* special cases for movlps and movhps */
  41.712 +                        if (MODRM_MOD(inp_peek(u)) == 3) {
  41.713 +                                if (u->mnemonic == UD_Imovlps)
  41.714 +                                        u->mnemonic = UD_Imovhlps;
  41.715 +                                else
  41.716 +                                if (u->mnemonic == UD_Imovhps)
  41.717 +                                        u->mnemonic = UD_Imovlhps;
  41.718 +                        }
  41.719 +                        decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_XMM);
  41.720 +                        if (mop3t == OP_I)
  41.721 +                                decode_imm(u, mop3s, &(iop[2]));
  41.722 +                } else if (mop2t == OP_Q)
  41.723 +                        decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_XMM);
  41.724 +                else if (mop2t == OP_M) {
  41.725 +                        if (MODRM_MOD(inp_peek(u)) == 3)
  41.726 +                                u->error= 1;
  41.727 +                        decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_XMM);
  41.728 +                } else if (mop2t == OP_E) {
  41.729 +                        decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_XMM);
  41.730 +                } else if (mop2t == OP_PR) {
  41.731 +                        decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_XMM);
  41.732 +                }
  41.733 +                break;
  41.734 +
  41.735 +        /* DX, eAX/AL */
  41.736 +        case OP_DX :
  41.737 +                iop[0].type = UD_OP_REG;
  41.738 +                iop[0].base = UD_R_DX;
  41.739 +                iop[0].size = 16;
  41.740 +
  41.741 +                if (mop2t == OP_eAX) {
  41.742 +                        iop[1].type = UD_OP_REG;        
  41.743 +                        iop[1].base = resolve_gpr32(u, mop2t);
  41.744 +                } else if (mop2t == OP_AL) {
  41.745 +                        iop[1].type = UD_OP_REG;
  41.746 +                        iop[1].base = UD_R_AL;
  41.747 +                        iop[1].size = 8;
  41.748 +                }
  41.749 +
  41.750 +                break;
  41.751 +
  41.752 +        /* I, I/AL/eAX */
  41.753 +        case OP_I :
  41.754 +                decode_imm(u, mop1s, &(iop[0]));
  41.755 +                if (mop2t == OP_I)
  41.756 +                        decode_imm(u, mop2s, &(iop[1]));
  41.757 +                else if (mop2t == OP_AL) {
  41.758 +                        iop[1].type = UD_OP_REG;
  41.759 +                        iop[1].base = UD_R_AL;
  41.760 +                        iop[1].size = 16;
  41.761 +                } else if (mop2t == OP_eAX) {
  41.762 +                        iop[1].type = UD_OP_REG;        
  41.763 +                        iop[1].base = resolve_gpr32(u, mop2t);
  41.764 +                }
  41.765 +                break;
  41.766 +
  41.767 +        /* O, AL/eAX */
  41.768 +        case OP_O :
  41.769 +                decode_o(u, mop1s, &(iop[0]));
  41.770 +                iop[1].type = UD_OP_REG;
  41.771 +                iop[1].size = resolve_oprsize(u, mop1s);
  41.772 +                if (mop2t == OP_AL)
  41.773 +                        iop[1].base = UD_R_AL;
  41.774 +                else if (mop2t == OP_eAX)
  41.775 +                        iop[1].base = resolve_gpr32(u, mop2t);
  41.776 +                else if (mop2t == OP_rAX)
  41.777 +                        iop[1].base = resolve_gpr64(u, mop2t);          
  41.778 +                break;
  41.779 +
  41.780 +        /* 3 */
  41.781 +        case OP_I3 :
  41.782 +                iop[0].type = UD_OP_CONST;
  41.783 +                iop[0].lval.sbyte = 3;
  41.784 +                break;
  41.785 +
  41.786 +        /* ST(n), ST(n) */
  41.787 +        case OP_ST0 : case OP_ST1 : case OP_ST2 : case OP_ST3 :
  41.788 +        case OP_ST4 : case OP_ST5 : case OP_ST6 : case OP_ST7 :
  41.789 +
  41.790 +                iop[0].type = UD_OP_REG;
  41.791 +                iop[0].base = (mop1t-OP_ST0) + UD_R_ST0;
  41.792 +                iop[0].size = 0;
  41.793 +
  41.794 +                if (mop2t >= OP_ST0 && mop2t <= OP_ST7) {
  41.795 +                        iop[1].type = UD_OP_REG;
  41.796 +                        iop[1].base = (mop2t-OP_ST0) + UD_R_ST0;
  41.797 +                        iop[1].size = 0;
  41.798 +                }
  41.799 +                break;
  41.800 +
  41.801 +        /* AX */
  41.802 +        case OP_AX:
  41.803 +                iop[0].type = UD_OP_REG;
  41.804 +                iop[0].base = UD_R_AX;
  41.805 +                iop[0].size = 16;
  41.806 +                break;
  41.807 +
  41.808 +        /* none */
  41.809 +        default :
  41.810 +                iop[0].type = iop[1].type = iop[2].type = UD_NONE;
  41.811 +  }
  41.812 +
  41.813 +  return 0;
  41.814 +}
  41.815 +
  41.816 +/* -----------------------------------------------------------------------------
  41.817 + * clear_insn() - clear instruction pointer 
  41.818 + * -----------------------------------------------------------------------------
  41.819 + */
  41.820 +static int clear_insn(register struct ud* u)
  41.821 +{
  41.822 +  u->error = 0;
  41.823 +  u->pfx_seg = 0;
  41.824 +  u->pfx_opr = 0;
  41.825 +  u->pfx_adr = 0;
  41.826 +  u->pfx_lock = 0;
  41.827 +  u->pfx_repne = 0;
  41.828 +  u->pfx_rep = 0;
  41.829 +  u->pfx_seg = 0;
  41.830 +  u->pfx_rex = 0;
  41.831 +  u->pfx_insn= 0;
  41.832 +  u->mnemonic = UD_Inone;
  41.833 +  u->mapen = NULL;
  41.834 +
  41.835 +  memset( &u->operand[ 0 ], 0, sizeof( struct ud_operand ) );
  41.836 +  memset( &u->operand[ 1 ], 0, sizeof( struct ud_operand ) );
  41.837 +  memset( &u->operand[ 2 ], 0, sizeof( struct ud_operand ) );
  41.838 + 
  41.839 +  return 0;
  41.840 +}
  41.841 +
  41.842 +static int do_prefixes( struct ud* u )
  41.843 +{
  41.844 +  int have_pfx = 1;
  41.845 +  int i;
  41.846 +  uint8_t last_pfx = -1;
  41.847 +  if ( u->error ) return -1; /* if in error state, bail out */
  41.848 +
  41.849 +  for ( i = 0; have_pfx ; ++i ) {
  41.850 +
  41.851 +        uint8_t curr;
  41.852 +        /* Get next byte. */
  41.853 +        inp_next(u); if ( u->error ) return -1;
  41.854 +        curr = inp_curr( u );
  41.855 +        /* Rex prefixes in 64bit mode */
  41.856 +        if ( u->dis_mode == 64 && ( curr & 0xF0 ) == 0x40 ) {
  41.857 +                u->pfx_rex = curr;      
  41.858 +        } else {
  41.859 +                switch ( curr )  
  41.860 +                {
  41.861 +                /* TBD: Need to find out the behavior in the case of multiple
  41.862 +                 * segment prefixes.
  41.863 +                 */
  41.864 +                case 0x2E : 
  41.865 +                        u->pfx_seg = UD_R_CS; 
  41.866 +                        break;
  41.867 +                case 0x36 :     
  41.868 +                        u->pfx_seg = UD_R_SS; 
  41.869 +                        break;
  41.870 +                case 0x3E : 
  41.871 +                        u->pfx_seg = UD_R_DS; 
  41.872 +                        break;
  41.873 +                case 0x26 : 
  41.874 +                        u->pfx_seg = UD_R_ES; 
  41.875 +                        break;
  41.876 +                case 0x64 : 
  41.877 +                        u->pfx_seg = UD_R_FS; 
  41.878 +                        break;
  41.879 +                case 0x65 : 
  41.880 +                        u->pfx_seg = UD_R_GS; 
  41.881 +                        break;
  41.882 +                case 0x67 : /* adress-size override prefix */ 
  41.883 +                        u->pfx_adr = 0x67;
  41.884 +                        break;
  41.885 +                case 0xF0 : 
  41.886 +                        u->pfx_lock= 0xF0;
  41.887 +                        break;
  41.888 +                case 0x66 : { /* operand-size override, and SSE modifier */
  41.889 +                        /* if there was already an F2, F3 prefix, 66 becomes
  41.890 +                         * in effective.
  41.891 +                         */
  41.892 +                        if ( u->pfx_insn != 0xF2 &&  u->pfx_insn != 0xF3 ) {
  41.893 +                                u->pfx_insn = 0x66;
  41.894 +                        } 
  41.895 +                        /* operand size prefix */
  41.896 +                        u->pfx_opr = 0x66;                       
  41.897 +                        break;
  41.898 +                        }
  41.899 +                /* 0xF2 is an SSE instruction modifier */
  41.900 +                case 0xF2 : {
  41.901 +                        u->pfx_insn = 0xF2;
  41.902 +                        u->pfx_repne= 0xF2; 
  41.903 +                        break;
  41.904 +                        }
  41.905 +                /* 0xF3 is an SSE instruction modifier */
  41.906 +                case 0xF3 : {
  41.907 +                        u->pfx_insn = 0xF3;
  41.908 +                        u->pfx_rep  = 0xF3; 
  41.909 +                        break;
  41.910 +                        }
  41.911 +                default : {
  41.912 +                        /* No more prefixes */
  41.913 +                        have_pfx = 0;
  41.914 +                        }
  41.915 +                }
  41.916 +        }
  41.917 +
  41.918 +        /* check if we reached max instruction length */
  41.919 +        if ( i == 14 ) {
  41.920 +                u->error = 1;
  41.921 +                break;
  41.922 +        }
  41.923 +        /* we keep the last prefix for checking 0x66 insn modifier. */  
  41.924 +        last_pfx = curr;
  41.925 +  }
  41.926 +
  41.927 +  /* return status */
  41.928 +  if ( u->error ) return -1; 
  41.929 +
  41.930 +  /* rewind back one byte in stream, since the above loop stopped 
  41.931 +   * with a non-prefix byte. 
  41.932 +   */
  41.933 +  inp_back(u);
  41.934 +
  41.935 +  return 0;
  41.936 +}
  41.937 +
  41.938 +static int do_mode( struct ud* u )
  41.939 +{
  41.940 +  /* if in error state, bail out */
  41.941 +  if ( u->error ) return -1; 
  41.942 +
  41.943 +  /* propagate perfix effects */
  41.944 +  if ( u->dis_mode == 64 ) {  /* set 64bit-mode flags */
  41.945 +
  41.946 +        /* Check validity of  instruction m64 */
  41.947 +        if ( P_INV64( u->mapen->prefix ) ) {
  41.948 +                u->error = 1;
  41.949 +                return -1;
  41.950 +        }
  41.951 +
  41.952 +        /* effective rex prefix is the  effective mask for the 
  41.953 +         * instruction hard-coded in the opcode map.
  41.954 +         */
  41.955 +        u->pfx_rex = u->pfx_rex & P_REX_MASK( u->mapen->prefix ); 
  41.956 +
  41.957 +        /* whether this instruction has a default operand size of 
  41.958 +         * 64bit, also hardcoded into the opcode map.
  41.959 +         */
  41.960 +        u->default64 = P_DEF64( u->mapen->prefix ); 
  41.961 +        /* calculate effective operand size */
  41.962 +        if ( P_REX( u->mapen->prefix ) && P_REX_W( u->pfx_rex ) ) {
  41.963 +                u->opr_mode = 64;
  41.964 +        } else if ( u->pfx_opr ) {
  41.965 +                u->opr_mode = 16;
  41.966 +        } else {
  41.967 +                /* unless the default opr size of instruction is 64,
  41.968 +                 * the effective operand size in the absence of rex.w
  41.969 +                 * prefix is 32.
  41.970 +                 */
  41.971 +                u->opr_mode = ( u->default64 ) ? 64 : 32;
  41.972 +        }
  41.973 +
  41.974 +        /* calculate effective address size */
  41.975 +        u->adr_mode = (u->pfx_adr) ? 32 : 64;
  41.976 +  } else if ( u->dis_mode == 32 ) { /* set 32bit-mode flags */
  41.977 +        u->opr_mode = ( u->pfx_opr ) ? 16 : 32;
  41.978 +        u->adr_mode = ( u->pfx_adr ) ? 16 : 32;
  41.979 +  } else if ( u->dis_mode == 16 ) { /* set 16bit-mode flags */
  41.980 +        u->opr_mode = ( u->pfx_opr ) ? 32 : 16;
  41.981 +        u->adr_mode = ( u->pfx_adr ) ? 32 : 16;
  41.982 +  }
  41.983 +
  41.984 +  /* These flags determine which operand to apply the operand size
  41.985 +   * cast to.
  41.986 +   */
  41.987 +  u->c1 = ( P_C1( u->mapen->prefix ) ) ? 1 : 0;
  41.988 +  u->c2 = ( P_C2( u->mapen->prefix ) ) ? 1 : 0;
  41.989 +  u->c3 = ( P_C3( u->mapen->prefix ) ) ? 1 : 0;
  41.990 +
  41.991 +  return 0;
  41.992 +}
  41.993 +
  41.994 +static int gen_hex( struct ud *u )
  41.995 +{
  41.996 +  unsigned int i;
  41.997 +  unsigned char *src_ptr = inp_sess( u );
  41.998 +  char* src_hex;
  41.999 +
 41.1000 +  /* bail out if in error stat. */
 41.1001 +  if ( u->error ) return -1; 
 41.1002 +  /* output buffer pointe */
 41.1003 +  src_hex = ( char* ) u->insn_hexcode;
 41.1004 +  /* for each byte used to decode instruction */
 41.1005 +  for ( i = 0; i < u->inp_ctr; ++i, ++src_ptr) {
 41.1006 +        snprintf( src_hex, 2, "%02x", *src_ptr & 0xFF );
 41.1007 +        src_hex += 2;
 41.1008 +  }
 41.1009 +  return 0;
 41.1010 +}
 41.1011 +
 41.1012 +/* =============================================================================
 41.1013 + * ud_decode() - Instruction decoder. Returns the number of bytes decoded.
 41.1014 + * =============================================================================
 41.1015 + */
 41.1016 +unsigned int ud_decode( struct ud* u )
 41.1017 +{
 41.1018 +  inp_start(u);
 41.1019 +
 41.1020 +  if ( clear_insn( u ) ) {
 41.1021 +        ; /* error */
 41.1022 +  } else if ( do_prefixes( u ) != 0 ) {
 41.1023 +        ; /* error */
 41.1024 +  } else if ( ud_search_map( u ) != 0 ) {
 41.1025 +        ; /* error */
 41.1026 +  } else if ( do_mode( u ) != 0 ) {
 41.1027 +        ; /* error */
 41.1028 +  } else if ( disasm_operands( u ) != 0 ) {
 41.1029 +        ; /* error */
 41.1030 +  } else if ( resolve_mnemonic( u ) != 0 ) {
 41.1031 +        ; /* error */
 41.1032 +  }
 41.1033 +
 41.1034 +  /* Handle decode error. */
 41.1035 +  if ( u->error ) {
 41.1036 +        /* clear out the decode data. */
 41.1037 +        clear_insn( u );
 41.1038 +        /* mark the sequence of bytes as invalid. */
 41.1039 +        u->mapen = ud_me_invalid();
 41.1040 +        u->mnemonic = u->mapen->mnemonic;
 41.1041 +  } 
 41.1042 +
 41.1043 +  u->insn_offset = u->pc; /* set offset of instruction */
 41.1044 +  u->insn_fill = 0;       /* set translation buffer index to 0 */
 41.1045 +  u->pc += u->inp_ctr;    /* move program counter by bytes decoded */
 41.1046 +  gen_hex( u );           /* generate hex code */
 41.1047 +
 41.1048 +  /* return number of bytes disassembled. */
 41.1049 +  return u->inp_ctr;
 41.1050 +}
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/xen/kdb/x86/udis86-1.6/extern.h	Thu Feb 03 15:42:41 2011 -0800
    42.3 @@ -0,0 +1,67 @@
    42.4 +/* -----------------------------------------------------------------------------
    42.5 + * extern.h
    42.6 + *
    42.7 + * Copyright (c) 2004, 2005, 2006, Vivek Mohan <vivek@sig9.com>
    42.8 + * All rights reserved. See LICENSE
    42.9 + * -----------------------------------------------------------------------------
   42.10 + */
   42.11 +#ifndef UD_EXTERN_H
   42.12 +#define UD_EXTERN_H
   42.13 +
   42.14 +#ifdef __cplusplus
   42.15 +extern "C" {
   42.16 +#endif
   42.17 +
   42.18 +/* #include <stdio.h> */
   42.19 +#include "types.h"
   42.20 +
   42.21 +/* ============================= PUBLIC API ================================= */
   42.22 +
   42.23 +extern void ud_init(struct ud*);
   42.24 +
   42.25 +extern void ud_set_mode(struct ud*, uint8_t);
   42.26 +
   42.27 +extern void ud_set_pc(struct ud*, uint64_t);
   42.28 +
   42.29 +extern void ud_set_input_hook(struct ud*, int (*)(struct ud*));
   42.30 +
   42.31 +extern void ud_set_input_buffer(struct ud*, uint8_t*, size_t);
   42.32 +
   42.33 +#ifndef __UD_STANDALONE__
   42.34 +extern void ud_set_input_file(struct ud*, FILE*);
   42.35 +#endif /* __UD_STANDALONE__ */
   42.36 +
   42.37 +extern void ud_set_vendor(struct ud*, unsigned);
   42.38 +
   42.39 +extern void ud_set_syntax(struct ud*, void (*)(struct ud*));
   42.40 +
   42.41 +extern void ud_input_skip(struct ud*, size_t);
   42.42 +
   42.43 +extern int ud_input_end(struct ud*);
   42.44 +
   42.45 +extern unsigned int ud_decode(struct ud*);
   42.46 +
   42.47 +extern unsigned int ud_disassemble(struct ud*);
   42.48 +
   42.49 +extern void ud_translate_intel(struct ud*);
   42.50 +
   42.51 +extern void ud_translate_att(struct ud*);
   42.52 +
   42.53 +extern char* ud_insn_asm(struct ud* u);
   42.54 +
   42.55 +extern uint8_t* ud_insn_ptr(struct ud* u);
   42.56 +
   42.57 +extern uint64_t ud_insn_off(struct ud*);
   42.58 +
   42.59 +extern char* ud_insn_hex(struct ud*);
   42.60 +
   42.61 +extern unsigned int ud_insn_len(struct ud* u);
   42.62 +
   42.63 +extern const char* ud_lookup_mnemonic(enum ud_mnemonic_code c);
   42.64 +
   42.65 +/* ========================================================================== */
   42.66 +
   42.67 +#ifdef __cplusplus
   42.68 +}
   42.69 +#endif
   42.70 +#endif
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/xen/kdb/x86/udis86-1.6/input.c	Thu Feb 03 15:42:41 2011 -0800
    43.3 @@ -0,0 +1,229 @@
    43.4 +/* -----------------------------------------------------------------------------
    43.5 + * input.c
    43.6 + *
    43.7 + * Copyright (c) 2004, 2005, 2006, Vivek Mohan <vivek@sig9.com>
    43.8 + * All rights reserved. See LICENSE
    43.9 + * -----------------------------------------------------------------------------
   43.10 + */
   43.11 +
   43.12 +#include "../../include/kdbinc.h"
   43.13 +
   43.14 +#include "extern.h"
   43.15 +#include "types.h"
   43.16 +#include "input.h"
   43.17 +
   43.18 +/* -----------------------------------------------------------------------------
   43.19 + * inp_buff_hook() - Hook for buffered inputs.
   43.20 + * -----------------------------------------------------------------------------
   43.21 + */
   43.22 +static int 
   43.23 +inp_buff_hook(struct ud* u)
   43.24 +{
   43.25 +  if (u->inp_buff < u->inp_buff_end)
   43.26 +        return *u->inp_buff++;
   43.27 +  else  return -1;
   43.28 +}
   43.29 +
   43.30 +#ifndef __UD_STANDALONE__
   43.31 +/* -----------------------------------------------------------------------------
   43.32 + * inp_file_hook() - Hook for FILE inputs.
   43.33 + * -----------------------------------------------------------------------------
   43.34 + */
   43.35 +static int 
   43.36 +inp_file_hook(struct ud* u)
   43.37 +{
   43.38 +  return fgetc(u->inp_file);
   43.39 +}
   43.40 +#endif /* __UD_STANDALONE__*/
   43.41 +
   43.42 +/* =============================================================================
   43.43 + * ud_inp_set_hook() - Sets input hook.
   43.44 + * =============================================================================
   43.45 + */
   43.46 +extern void 
   43.47 +ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*))
   43.48 +{
   43.49 +  u->inp_hook = hook;
   43.50 +  inp_init(u);
   43.51 +}
   43.52 +
   43.53 +/* =============================================================================
   43.54 + * ud_inp_set_buffer() - Set buffer as input.
   43.55 + * =============================================================================
   43.56 + */
   43.57 +extern void 
   43.58 +ud_set_input_buffer(register struct ud* u, uint8_t* buf, size_t len)
   43.59 +{
   43.60 +  u->inp_hook = inp_buff_hook;
   43.61 +  u->inp_buff = buf;
   43.62 +  u->inp_buff_end = buf + len;
   43.63 +  inp_init(u);
   43.64 +}
   43.65 +
   43.66 +#ifndef __UD_STANDALONE__
   43.67 +/* =============================================================================
   43.68 + * ud_input_set_file() - Set buffer as input.
   43.69 + * =============================================================================
   43.70 + */
   43.71 +extern void 
   43.72 +ud_set_input_file(register struct ud* u, FILE* f)
   43.73 +{
   43.74 +  u->inp_hook = inp_file_hook;
   43.75 +  u->inp_file = f;
   43.76 +  inp_init(u);
   43.77 +}
   43.78 +#endif /* __UD_STANDALONE__ */
   43.79 +
   43.80 +/* =============================================================================
   43.81 + * ud_input_skip() - Skip n input bytes.
   43.82 + * =============================================================================
   43.83 + */
   43.84 +extern void 
   43.85 +ud_input_skip(struct ud* u, size_t n)
   43.86 +{
   43.87 +  while (n--) {
   43.88 +        u->inp_hook(u);
   43.89 +  }
   43.90 +}
   43.91 +
   43.92 +/* =============================================================================
   43.93 + * ud_input_end() - Test for end of input.
   43.94 + * =============================================================================
   43.95 + */
   43.96 +extern int 
   43.97 +ud_input_end(struct ud* u)
   43.98 +{
   43.99 +  return (u->inp_curr == u->inp_fill) && u->inp_end;
  43.100 +}
  43.101 +
  43.102 +/* -----------------------------------------------------------------------------
  43.103 + * inp_next() - Loads and returns the next byte from input.
  43.104 + *
  43.105 + * inp_curr and inp_fill are pointers to the cache. The program is written based
  43.106 + * on the property that they are 8-bits in size, and will eventually wrap around
  43.107 + * forming a circular buffer. So, the size of the cache is 256 in size, kind of
  43.108 + * unnecessary yet optimized.
  43.109 + *
  43.110 + * A buffer inp_sess stores the bytes disassembled for a single session.
  43.111 + * -----------------------------------------------------------------------------
  43.112 + */
  43.113 +extern uint8_t inp_next(struct ud* u) 
  43.114 +{
  43.115 +  int c = -1;
  43.116 +  /* if current pointer is not upto the fill point in the 
  43.117 +   * input cache.
  43.118 +   */
  43.119 +  if ( u->inp_curr != u->inp_fill ) {
  43.120 +        c = u->inp_cache[ ++u->inp_curr ];
  43.121 +  /* if !end-of-input, call the input hook and get a byte */
  43.122 +  } else if ( u->inp_end || ( c = u->inp_hook( u ) ) == -1 ) {
  43.123 +        /* end-of-input, mark it as an error, since the decoder,
  43.124 +         * expected a byte more.
  43.125 +         */
  43.126 +        u->error = 1;
  43.127 +        /* flag end of input */
  43.128 +        u->inp_end = 1;
  43.129 +        return 0;
  43.130 +  } else {
  43.131 +        /* increment pointers, we have a new byte.  */
  43.132 +        u->inp_curr = ++u->inp_fill;
  43.133 +        /* add the byte to the cache */
  43.134 +        u->inp_cache[ u->inp_fill ] = c;
  43.135 +  }
  43.136 +  /* record bytes input per decode-session. */
  43.137 +  u->inp_sess[ u->inp_ctr++ ] = c;
  43.138 +  /* return byte */
  43.139 +  return ( uint8_t ) c;
  43.140 +}
  43.141 +
  43.142 +/* -----------------------------------------------------------------------------
  43.143 + * inp_back() - Move back a single byte in the stream.
  43.144 + * -----------------------------------------------------------------------------
  43.145 + */
  43.146 +extern void
  43.147 +inp_back(struct ud* u) 
  43.148 +{
  43.149 +  if ( u->inp_ctr > 0 ) {
  43.150 +        --u->inp_curr;
  43.151 +        --u->inp_ctr;
  43.152 +  }
  43.153 +}
  43.154 +
  43.155 +/* -----------------------------------------------------------------------------
  43.156 + * inp_peek() - Peek into the next byte in source. 
  43.157 + * -----------------------------------------------------------------------------
  43.158 + */
  43.159 +extern uint8_t
  43.160 +inp_peek(struct ud* u) 
  43.161 +{
  43.162 +  uint8_t r = inp_next(u);
  43.163 +  if ( !u->error ) inp_back(u); /* Don't backup if there was an error */
  43.164 +  return r;
  43.165 +}
  43.166 +
  43.167 +/* -----------------------------------------------------------------------------
  43.168 + * inp_move() - Move ahead n input bytes.
  43.169 + * -----------------------------------------------------------------------------
  43.170 + */
  43.171 +extern void
  43.172 +inp_move(struct ud* u, size_t n) 
  43.173 +{
  43.174 +  while (n--)
  43.175 +        inp_next(u);
  43.176 +}
  43.177 +
  43.178 +/*------------------------------------------------------------------------------
  43.179 + *  inp_uintN() - return uintN from source.
  43.180 + *------------------------------------------------------------------------------
  43.181 + */
  43.182 +extern uint8_t 
  43.183 +inp_uint8(struct ud* u)
  43.184 +{
  43.185 +  return inp_next(u);
  43.186 +}
  43.187 +
  43.188 +extern uint16_t 
  43.189 +inp_uint16(struct ud* u)
  43.190 +{
  43.191 +  uint16_t r, ret;
  43.192 +
  43.193 +  ret = inp_next(u);
  43.194 +  r = inp_next(u);
  43.195 +  return ret | (r << 8);
  43.196 +}
  43.197 +
  43.198 +extern uint32_t 
  43.199 +inp_uint32(struct ud* u)
  43.200 +{
  43.201 +  uint32_t r, ret;
  43.202 +
  43.203 +  ret = inp_next(u);
  43.204 +  r = inp_next(u);
  43.205 +  ret = ret | (r << 8);
  43.206 +  r = inp_next(u);
  43.207 +  ret = ret | (r << 16);
  43.208 +  r = inp_next(u);
  43.209 +  return ret | (r << 24);
  43.210 +}
  43.211 +
  43.212 +extern uint64_t 
  43.213 +inp_uint64(struct ud* u)
  43.214 +{
  43.215 +  uint64_t r, ret;
  43.216 +
  43.217 +  ret = inp_next(u);
  43.218 +  r = inp_next(u);
  43.219 +  ret = ret | (r << 8);
  43.220 +  r = inp_next(u);
  43.221 +  ret = ret | (r << 16);
  43.222 +  r = inp_next(u);
  43.223 +  ret = ret | (r << 24);
  43.224 +  r = inp_next(u);
  43.225 +  ret = ret | (r << 32);
  43.226 +  r = inp_next(u);
  43.227 +  ret = ret | (r << 40);
  43.228 +  r = inp_next(u);
  43.229 +  ret = ret | (r << 48);
  43.230 +  r = inp_next(u);
  43.231 +  return ret | (r << 56);
  43.232 +}
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/xen/kdb/x86/udis86-1.6/input.h	Thu Feb 03 15:42:41 2011 -0800
    44.3 @@ -0,0 +1,49 @@
    44.4 +/* -----------------------------------------------------------------------------
    44.5 + * input.h
    44.6 + *
    44.7 + * Copyright (c) 2006, Vivek Mohan <vivek@sig9.com>
    44.8 + * All rights reserved. See LICENSE
    44.9 + * -----------------------------------------------------------------------------
   44.10 + */
   44.11 +#ifndef UD_INPUT_H
   44.12 +#define UD_INPUT_H
   44.13 +
   44.14 +#include "types.h"
   44.15 +
   44.16 +uint8_t inp_next(struct ud*);
   44.17 +uint8_t inp_peek(struct ud*);
   44.18 +uint8_t inp_uint8(struct ud*);
   44.19 +uint16_t inp_uint16(struct ud*);
   44.20 +uint32_t inp_uint32(struct ud*);
   44.21 +uint64_t inp_uint64(struct ud*);
   44.22 +void inp_move(struct ud*, size_t);
   44.23 +void inp_back(struct ud*);
   44.24 +
   44.25 +/* inp_init() - Initializes the input system. */
   44.26 +#define inp_init(u) \
   44.27 +do { \
   44.28 +  u->inp_curr = 0; \
   44.29 +  u->inp_fill = 0; \
   44.30 +  u->inp_ctr  = 0; \
   44.31 +  u->inp_end  = 0; \
   44.32 +} while (0)
   44.33 +
   44.34 +/* inp_start() - Should be called before each de-code operation. */
   44.35 +#define inp_start(u) u->inp_ctr = 0
   44.36 +
   44.37 +/* inp_back() - Resets the current pointer to its position before the current
   44.38 + * instruction disassembly was started.
   44.39 + */
   44.40 +#define inp_reset(u) \
   44.41 +do { \
   44.42 +  u->inp_curr -= u->inp_ctr; \
   44.43 +  u->inp_ctr = 0; \
   44.44 +} while (0)
   44.45 +
   44.46 +/* inp_sess() - Returns the pointer to current session. */
   44.47 +#define inp_sess(u) (u->inp_sess)
   44.48 +
   44.49 +/* inp_cur() - Returns the current input byte. */
   44.50 +#define inp_curr(u) ((u)->inp_cache[(u)->inp_curr])
   44.51 +
   44.52 +#endif
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/xen/kdb/x86/udis86-1.6/kdb_dis.c	Thu Feb 03 15:42:41 2011 -0800
    45.3 @@ -0,0 +1,202 @@
    45.4 +/*
    45.5 + * Copyright (C) 2009, Mukesh Rathor, Oracle Corp.  All rights reserved.
    45.6 + *
    45.7 + * This program is free software; you can redistribute it and/or
    45.8 + * modify it under the terms of the GNU General Public
    45.9 + * License v2 as published by the Free Software Foundation.
   45.10 + *
   45.11 + * This program is distributed in the hope that it will be useful,
   45.12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   45.13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   45.14 + * General Public License for more details.
   45.15 + *
   45.16 + * You should have received a copy of the GNU General Public
   45.17 + * License along with this program; if not, write to the
   45.18 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   45.19 + * Boston, MA 021110-1307, USA.
   45.20 + */
   45.21 +
   45.22 +#include <xen/compile.h>                /* for XEN_SUBVERSION */
   45.23 +#include "../../include/kdbinc.h"
   45.24 +#include "extern.h"
   45.25 +
   45.26 +static void (*dis_syntax)(ud_t*) = UD_SYN_ATT; /* default dis-assembly syntax */
   45.27 +
   45.28 +static struct {                         /* info for kdb_read_byte_for_ud() */
   45.29 +    kdbva_t kud_instr_addr;
   45.30 +    domid_t kud_domid;
   45.31 +} kdb_ud_rd_info;
   45.32 +
   45.33 +/* called via function ptr by ud when disassembling. 
   45.34 + * kdb info passed via kdb_ud_rd_info{} 
   45.35 + */
   45.36 +static int
   45.37 +kdb_read_byte_for_ud(struct ud *udp)
   45.38 +{
   45.39 +    kdbbyt_t bytebuf;
   45.40 +    domid_t domid = kdb_ud_rd_info.kud_domid;
   45.41 +    kdbva_t addr = kdb_ud_rd_info.kud_instr_addr;
   45.42 +
   45.43 +    if (kdb_read_mem(addr, &bytebuf, 1, domid) == 1) {
   45.44 +        kdb_ud_rd_info.kud_instr_addr++;
   45.45 +        KDBGP1("udrd:addr:%lx domid:%d byt:%x\n", addr, domid, bytebuf);
   45.46 +        return bytebuf;
   45.47 +    }
   45.48 +    KDBGP1("udrd:addr:%lx domid:%d err\n", addr, domid);
   45.49 +    return UD_EOI;
   45.50 +}
   45.51 +
   45.52 +/* 
   45.53 + * given a domid, convert addr to symbol and print it 
   45.54 + * Eg: ffff828c801235e2: idle_loop+52                  jmp  idle_loop+55
   45.55 + *    Called twice here for idle_loop. In first case, nl is null, 
   45.56 + *    in the second case nl == '\n'
   45.57 + */
   45.58 +void
   45.59 +kdb_prnt_addr2sym(domid_t domid, kdbva_t addr, char *nl)
   45.60 +{
   45.61 +    unsigned long sz, offs;
   45.62 +    char buf[KSYM_NAME_LEN+1], pbuf[150], prefix[8];
   45.63 +    char *p = buf;
   45.64 +
   45.65 +    prefix[0]='\0';
   45.66 +    if (domid != DOMID_IDLE) {
   45.67 +        snprintf(prefix, 8, "%x:", domid);
   45.68 +        p = kdb_guest_addr2sym(addr, domid, &offs);
   45.69 +    } else
   45.70 +        symbols_lookup(addr, &sz, &offs, buf);
   45.71 +    snprintf(pbuf, 150, "%s%s+%lx", prefix, p, offs);
   45.72 +    if (*nl != '\n')
   45.73 +        kdbp("%-30s%s", pbuf, nl);  /* prints more than 30 if needed */
   45.74 +    else
   45.75 +        kdbp("%s%s", pbuf, nl);
   45.76 +}
   45.77 +
   45.78 +static int
   45.79 +kdb_jump_instr(enum ud_mnemonic_code mnemonic)
   45.80 +{
   45.81 +    return (mnemonic >= UD_Ijmp && mnemonic <= UD_Ijnle);
   45.82 +}
   45.83 +
   45.84 +/*
   45.85 + * print one instr: function so that we can print offsets of jmp etc.. as
   45.86 + *  symbol+offset instead of just address
   45.87 + */
   45.88 +static void
   45.89 +kdb_print_one_instr(struct ud *udp, domid_t domid)
   45.90 +{
   45.91 +    signed long val = 0;
   45.92 +    ud_type_t type = udp->operand[0].type;
   45.93 +
   45.94 +    if ((udp->mnemonic == UD_Icall || kdb_jump_instr(udp->mnemonic)) &&
   45.95 +        type == UD_OP_JIMM) {
   45.96 +        
   45.97 +        int sz = udp->operand[0].size;
   45.98 +        char *p, ibuf[40], *q = ibuf;
   45.99 +        kdbva_t addr;
  45.100 +
  45.101 +        if (sz == 8) val = udp->operand[0].lval.sbyte;
  45.102 +        else if (sz == 16) val = udp->operand[0].lval.sword;
  45.103 +        else if (sz == 32) val = udp->operand[0].lval.sdword;
  45.104 +        else if (sz == 64) val = udp->operand[0].lval.sqword;
  45.105 +        else kdbp("kdb_print_one_instr: Inval sz:z%d\n", sz);
  45.106 +
  45.107 +        addr = udp->pc + val;
  45.108 +        for(p=ud_insn_asm(udp); (*q=*p) && *p!=' '; p++,q++);
  45.109 +        *q='\0';
  45.110 +        kdbp(" %-4s ", ibuf);    /* space before for long func names */
  45.111 +        kdb_prnt_addr2sym(domid, addr, "\n");
  45.112 +    } else
  45.113 +        kdbp(" %-24s\n", ud_insn_asm(udp));
  45.114 +#if 0
  45.115 +    kdbp("mnemonic:z%d ", udp->mnemonic);
  45.116 +    if (type == UD_OP_CONST) kdbp("type is const\n");
  45.117 +    else if (type == UD_OP_JIMM) kdbp("type is JIMM\n");
  45.118 +    else if (type == UD_OP_IMM) kdbp("type is IMM\n");
  45.119 +    else if (type == UD_OP_PTR) kdbp("type is PTR\n");
  45.120 +#endif
  45.121 +}
  45.122 +
  45.123 +static void
  45.124 +kdb_setup_ud(struct ud *udp, kdbva_t addr, domid_t domid)
  45.125 +{
  45.126 +    int bitness = kdb_guest_bitness(domid);
  45.127 +    uint vendor = (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) ?
  45.128 +                                           UD_VENDOR_AMD : UD_VENDOR_INTEL;
  45.129 +
  45.130 +    KDBGP1("setup_ud:domid:%d bitness:%d addr:%lx\n", domid, bitness, addr);
  45.131 +    ud_init(udp);
  45.132 +    ud_set_mode(udp, kdb_guest_bitness(domid));
  45.133 +    ud_set_syntax(udp, dis_syntax); 
  45.134 +    ud_set_vendor(udp, vendor);           /* HVM: vmx/svm different instrs*/
  45.135 +    ud_set_pc(udp, addr);                 /* for numbers printed on left */
  45.136 +    ud_set_input_hook(udp, kdb_read_byte_for_ud);
  45.137 +    kdb_ud_rd_info.kud_instr_addr = addr;
  45.138 +    kdb_ud_rd_info.kud_domid = domid;
  45.139 +}
  45.140 +
  45.141 +/*
  45.142 + * given an addr, print given number of instructions.
  45.143 + * Returns: address of next instruction in the stream
  45.144 + */
  45.145 +kdbva_t
  45.146 +kdb_print_instr(kdbva_t addr, long num, domid_t domid)
  45.147 +{
  45.148 +    struct ud ud_s;
  45.149 +
  45.150 +    KDBGP1("print_instr:addr:0x%lx num:%ld domid:%x\n", addr, num, domid);
  45.151 +
  45.152 +    kdb_setup_ud(&ud_s, addr, domid);
  45.153 +    while(num--) {
  45.154 +        if (ud_disassemble(&ud_s)) {
  45.155 +            uint64_t pc = ud_insn_off(&ud_s);
  45.156 +            /* kdbp("%08x: ",(int)pc); */
  45.157 +            kdbp("%016lx: ", pc);
  45.158 +            kdb_prnt_addr2sym(domid, pc, "");
  45.159 +            kdb_print_one_instr(&ud_s, domid);
  45.160 +        } else
  45.161 +            kdbp("KDB:Couldn't disassemble PC:0x%lx\n", addr);
  45.162 +            /* for stack reads, don't always display error */
  45.163 +    }
  45.164 +    KDBGP1("print_instr:kudaddr:0x%lx\n", kdb_ud_rd_info.kud_instr_addr);
  45.165 +    return kdb_ud_rd_info.kud_instr_addr;
  45.166 +}
  45.167 +
  45.168 +void
  45.169 +kdb_display_pc(struct cpu_user_regs *regs)
  45.170 +{   
  45.171 +    domid_t domid;
  45.172 +    struct cpu_user_regs regs1 = *regs;
  45.173 +    domid = guest_mode(regs) ? current->domain->domain_id : DOMID_IDLE;
  45.174 +
  45.175 +    regs1.KDBIP = regs->KDBIP;
  45.176 +    kdb_print_instr(regs1.KDBIP, 1, domid);
  45.177 +}
  45.178 +
  45.179 +/* check if the instr at the addr is call instruction
  45.180 + * RETURNS: size of the instr if it's a call instr, else 0
  45.181 + */
  45.182 +int
  45.183 +kdb_check_call_instr(domid_t domid, kdbva_t addr)
  45.184 +{
  45.185 +    struct ud ud_s;
  45.186 +    int sz;
  45.187 +
  45.188 +    kdb_setup_ud(&ud_s, addr, domid);
  45.189 +    if ((sz=ud_disassemble(&ud_s)) && ud_s.mnemonic == UD_Icall)
  45.190 +        return (sz);
  45.191 +    return 0;
  45.192 +}
  45.193 +
  45.194 +/* toggle ATT and Intel syntaxes */
  45.195 +void
  45.196 +kdb_toggle_dis_syntax(void)
  45.197 +{
  45.198 +    if (dis_syntax == UD_SYN_INTEL) {
  45.199 +        dis_syntax = UD_SYN_ATT;
  45.200 +        kdbp("dis syntax now set to ATT (Gas)\n");
  45.201 +    } else {
  45.202 +        dis_syntax = UD_SYN_INTEL;
  45.203 +        kdbp("dis syntax now set to Intel (NASM)\n");
  45.204 +    }
  45.205 +}
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/xen/kdb/x86/udis86-1.6/mnemonics.c	Thu Feb 03 15:42:41 2011 -0800
    46.3 @@ -0,0 +1,605 @@
    46.4 +/* Do not edit, generated by mnemonics.pl */ 
    46.5 +const char* ud_mnemonics[] = 
    46.6 +{
    46.7 +  "aaa",
    46.8 +  "aad",
    46.9 +  "aam",
   46.10 +  "aas",
   46.11 +  "adc",
   46.12 +  "add",
   46.13 +  "addpd",
   46.14 +  "addps",
   46.15 +  "addsd",
   46.16 +  "addss",
   46.17 +  "and",
   46.18 +  "andnpd",
   46.19 +  "andnps",
   46.20 +  "andpd",
   46.21 +  "andps",
   46.22 +  "arpl",
   46.23 +  "bound",
   46.24 +  "bsf",
   46.25 +  "bsr",
   46.26 +  "bswap",
   46.27 +  "bt",
   46.28 +  "btc",
   46.29 +  "btr",
   46.30 +  "bts",
   46.31 +  "call",
   46.32 +  "cbw",
   46.33 +  "cdqe",
   46.34 +  "clc",
   46.35 +  "cld",
   46.36 +  "clflush",
   46.37 +  "cli",
   46.38 +  "clts",
   46.39 +  "cmc",
   46.40 +  "cmovo",
   46.41 +  "cmovno",
   46.42 +  "cmovb",
   46.43 +  "cmovnb",
   46.44 +  "cmovz",
   46.45 +  "cmovnz",
   46.46 +  "cmovbe",
   46.47 +  "cmovnbe",
   46.48 +  "cmovs",
   46.49 +  "cmovns",
   46.50 +  "cmovp",
   46.51 +  "cmovnp",
   46.52 +  "cmovl",
   46.53 +  "cmovnl",
   46.54 +  "cmovle",
   46.55 +  "cmovnle",
   46.56 +  "cmp",
   46.57 +  "cmppd",
   46.58 +  "cmpps",
   46.59 +  "cmps",
   46.60 +  "cmpsb",
   46.61 +  "cmpsd",
   46.62 +  "cmpsq",
   46.63 +  "cmpss",
   46.64 +  "cmpsw",
   46.65 +  "cmpxchg",
   46.66 +  "cmpxchg8b",
   46.67 +  "comisd",
   46.68 +  "comiss",
   46.69 +  "cpuid",
   46.70 +  "cqd",
   46.71 +  "cqo",
   46.72 +  "cvtdq2pd",
   46.73 +  "cvtdq2ps",
   46.74 +  "cvtpd2dq",
   46.75 +  "cvtpd2pi",
   46.76 +  "cvtpd2ps",
   46.77 +  "cvtpi2pd",
   46.78 +  "cvtpi2ps",
   46.79 +  "cvtps2dq",
   46.80 +  "cvtps2pd",
   46.81 +  "cvtps2pi",
   46.82 +  "cvtsd2si",
   46.83 +  "cvtsd2ss",
   46.84 +  "cvtsi2sd",
   46.85 +  "cvtsi2ss",
   46.86 +  "cvtss2sd",
   46.87 +  "cvtss2si",
   46.88 +  "cvttpd2dq",
   46.89 +  "cvttpd2pi",
   46.90 +  "cvttps2dq",
   46.91 +  "cvttps2pi",
   46.92 +  "cvttsd2si",
   46.93 +  "cvttsi2sd",
   46.94 +  "cvttsi2ss",
   46.95 +  "cvttss2si",
   46.96 +  "cwd",
   46.97 +  "cwde",
   46.98 +  "cdq",
   46.99 +  "daa",
  46.100 +  "das",
  46.101 +  "dec",
  46.102 +  "div",
  46.103 +  "divpd",
  46.104 +  "divps",
  46.105 +  "divsd",
  46.106 +  "divss",
  46.107 +  "emms",
  46.108 +  "enter",
  46.109 +  "esc",
  46.110 +  "f2xm1",
  46.111 +  "fsxm1",
  46.112 +  "fabs",
  46.113 +  "fadd",
  46.114 +  "faddp",
  46.115 +  "fbld",
  46.116 +  "fbstp",
  46.117 +  "fchs",
  46.118 +  "fclex",
  46.119 +  "fcmovb",
  46.120 +  "fcmovbe",
  46.121 +  "fcmove",
  46.122 +  "fcmovnb",
  46.123 +  "fcmovnbe",
  46.124 +  "fcmovne",
  46.125 +  "fcmovnu",
  46.126 +  "fcmovu",
  46.127 +  "fcom",
  46.128 +  "fcomi",
  46.129 +  "fcomp",
  46.130 +  "fcomip",
  46.131 +  "fcompp",
  46.132 +  "fcos",
  46.133 +  "fdecstp",
  46.134 +  "fdiv",
  46.135 +  "fdivp",
  46.136 +  "fdivr",
  46.137 +  "fdivrp",
  46.138 +  "femms",
  46.139 +  "ffree",
  46.140 +  "fiadd",
  46.141 +  "ficom",
  46.142 +  "ficomp",
  46.143 +  "fidiv",
  46.144 +  "fidivr",
  46.145 +  "fidw",
  46.146 +  "fidwr",
  46.147 +  "fild",
  46.148 +  "fimul",
  46.149 +  "fincstp",
  46.150 +  "finit",
  46.151 +  "fist",
  46.152 +  "fistp",
  46.153 +  "fisub",
  46.154 +  "fisubr",
  46.155 +  "fld",
  46.156 +  "fld1",
  46.157 +  "fldcw",
  46.158 +  "fldenv",
  46.159 +  "fldl2e",
  46.160 +  "fldl2t",
  46.161 +  "fldlg2",
  46.162 +  "fldln2",
  46.163 +  "fldlpi",
  46.164 +  "fldx",
  46.165 +  "fldz",
  46.166 +  "fmul",
  46.167 +  "fmulp",
  46.168 +  "fnclex",
  46.169 +  "fncstp",
  46.170 +  "fninit",
  46.171 +  "fnop",
  46.172 +  "fnsave",
  46.173 +  "fnstcw",
  46.174 +  "fnstenv",
  46.175 +  "fnstsw",
  46.176 +  "fpatan",
  46.177 +  "fprem",
  46.178 +  "fprem1",
  46.179 +  "fptan",
  46.180 +  "fpxtract",
  46.181 +  "frndint",
  46.182 +  "frstor",
  46.183 +  "fsave",
  46.184 +  "fscale",
  46.185 +  "fsin",
  46.186 +  "fsincos",
  46.187 +  "fsqrt",
  46.188 +  "fst",
  46.189 +  "fstcw",
  46.190 +  "fstenv",
  46.191 +  "fstp",
  46.192 +  "fstsw",
  46.193 +  "fsub",
  46.194 +  "fsubp",
  46.195 +  "fsubr",
  46.196 +  "fsubrp",
  46.197 +  "ftst",
  46.198 +  "fucom",
  46.199 +  "fucomi",
  46.200 +  "fucomip",
  46.201 +  "fucomp",
  46.202 +  "fucompp",
  46.203 +  "fwait",
  46.204 +  "fxam",
  46.205 +  "fxch",
  46.206 +  "fxrstor",
  46.207 +  "fxsave",
  46.208 +  "fxtract",
  46.209 +  "fyl2x",
  46.210 +  "fyl2xp1",
  46.211 +  "hlt",
  46.212 +  "idiv",
  46.213 +  "imul",
  46.214 +  "in",
  46.215 +  "inc",
  46.216 +  "ins",
  46.217 +  "insb",
  46.218 +  "insd",
  46.219 +  "insw",
  46.220 +  "int",
  46.221 +  "into",
  46.222 +  "invd",
  46.223 +  "invlpg",
  46.224 +  "iretw",
  46.225 +  "iretd",
  46.226 +  "iretq",
  46.227 +  "jcxz",
  46.228 +  "jecxz",
  46.229 +  "jmp",
  46.230 +  "jrcxz",
  46.231 +  "jo",
  46.232 +  "jno",
  46.233 +  "jb",
  46.234 +  "jnb",
  46.235 +  "jz",
  46.236 +  "jnz",
  46.237 +  "jbe",
  46.238 +  "jnbe",
  46.239 +  "js",
  46.240 +  "jns",
  46.241 +  "jp",
  46.242 +  "jnp",
  46.243 +  "jl",
  46.244 +  "jnl",
  46.245 +  "jle",
  46.246 +  "jnle",
  46.247 +  "lahf",
  46.248 +  "lar",
  46.249 +  "ldmxcsr",
  46.250 +  "lds",
  46.251 +  "lea",
  46.252 +  "leave",
  46.253 +  "les",
  46.254 +  "lfence",
  46.255 +  "lfs",
  46.256 +  "lgdt",
  46.257 +  "lgs",
  46.258 +  "lidt",
  46.259 +  "lldt",
  46.260 +  "lmsw",
  46.261 +  "lock",
  46.262 +  "lods",
  46.263 +  "lodsb",
  46.264 +  "lodsd",
  46.265 +  "lodsq",
  46.266 +  "lodsw",
  46.267 +  "loop",
  46.268 +  "loope",
  46.269 +  "loopn",
  46.270 +  "loopne",
  46.271 +  "loopnz",
  46.272 +  "loopz",
  46.273 +  "lsl",
  46.274 +  "lss",
  46.275 +  "ltr",
  46.276 +  "maskmovdqu",
  46.277 +  "maskmovq",
  46.278 +  "maxpd",
  46.279 +  "maxps",
  46.280 +  "maxsd",
  46.281 +  "maxss",
  46.282 +  "mfence",
  46.283 +  "minpd",
  46.284 +  "minps",
  46.285 +  "minsd",
  46.286 +  "minss",
  46.287 +  "mov",
  46.288 +  "movapd",
  46.289 +  "movaps",
  46.290 +  "movd",
  46.291 +  "movdq2q",
  46.292 +  "movdqa",
  46.293 +  "movdqu",
  46.294 +  "movhlps",
  46.295 +  "movhpd",
  46.296 +  "movhps",
  46.297 +  "movlhps",
  46.298 +  "movlpd",
  46.299 +  "movlps",
  46.300 +  "movmskpd",
  46.301 +  "movmskps",
  46.302 +  "movnig",
  46.303 +  "movntdq",
  46.304 +  "movnti",
  46.305 +  "movntpd",
  46.306 +  "movntps",
  46.307 +  "movntq",
  46.308 +  "movq",
  46.309 +  "movq2dq",
  46.310 +  "movqa",
  46.311 +  "movs",
  46.312 +  "movsb",
  46.313 +  "movsd",
  46.314 +  "movsq",
  46.315 +  "movss",
  46.316 +  "movsw",
  46.317 +  "movsx",
  46.318 +  "movsxd",
  46.319 +  "movupd",
  46.320 +  "movups",
  46.321 +  "movzx",
  46.322 +  "mul",
  46.323 +  "mulpd",
  46.324 +  "mulps",
  46.325 +  "mulsd",
  46.326 +  "mulss",
  46.327 +  "neg",
  46.328 +  "nop",
  46.329 +  "not",
  46.330 +  "or",
  46.331 +  "orpd",
  46.332 +  "orps",
  46.333 +  "out",
  46.334 +  "outs",
  46.335 +  "outsb",
  46.336 +  "outsd",
  46.337 +  "outsw",
  46.338 +  "packssdw",
  46.339 +  "packsswb",
  46.340 +  "packusdw",
  46.341 +  "packuswb",
  46.342 +  "paddb",
  46.343 +  "paddd",
  46.344 +  "paddq",
  46.345 +  "paddsb",
  46.346 +  "paddsw",
  46.347 +  "paddusb",
  46.348 +  "paddusw",
  46.349 +  "paddw",
  46.350 +  "pand",
  46.351 +  "pandn",
  46.352 +  "pavgb",
  46.353 +  "pavgusb",
  46.354 +  "pavgw",
  46.355 +  "pcmpeqb",
  46.356 +  "pcmpeqd",
  46.357 +  "pcmpeqw",
  46.358 +  "pcmpgtb",
  46.359 +  "pcmpgtd",
  46.360 +  "pcmpgtw",
  46.361 +  "pextrw",
  46.362 +  "pf2id",
  46.363 +  "pf2iw",
  46.364 +  "pfacc",
  46.365 +  "pfadd",
  46.366 +  "pfcmpeq",
  46.367 +  "pfcmpge",
  46.368 +  "pfcmpgt",
  46.369 +  "pfmax",
  46.370 +  "pfmin",
  46.371 +  "pfmul",
  46.372 +  "pfnacc",
  46.373 +  "pfpnacc",
  46.374 +  "pfrcp",
  46.375 +  "pfrcpit1",
  46.376 +  "pfrcpit2",
  46.377 +  "pfrsqit1",
  46.378 +  "pfrsqrt",
  46.379 +  "pfsub",
  46.380 +  "pfsubr",
  46.381 +  "pi2fd",
  46.382 +  "pi2fw",
  46.383 +  "pinsrw",
  46.384 +  "pmaddwd",
  46.385 +  "pmaxsw",
  46.386 +  "pmaxub",
  46.387 +  "pminsw",
  46.388 +  "pminub",
  46.389 +  "pmovmskb",
  46.390 +  "pmulhrw",
  46.391 +  "pmulhuw",
  46.392 +  "pmulhw",
  46.393 +  "pmullw",
  46.394 +  "pmuludq",
  46.395 +  "pop",
  46.396 +  "popa",
  46.397 +  "popad",
  46.398 +  "popfw",
  46.399 +  "popfd",
  46.400 +  "popfq",
  46.401 +  "por",
  46.402 +  "prefetch",
  46.403 +  "psadbw",
  46.404 +  "pshufd",
  46.405 +  "pshufhw",
  46.406 +  "pshuflw",
  46.407 +  "pshufw",
  46.408 +  "pslld",
  46.409 +  "pslldq",
  46.410 +  "psllq",
  46.411 +  "psllw",
  46.412 +  "psrad",
  46.413 +  "psraw",
  46.414 +  "psraq",
  46.415 +  "psrld",
  46.416 +  "psrldq",
  46.417 +  "psrlq",
  46.418 +  "psrlw",
  46.419 +  "psubb",
  46.420 +  "psubd",
  46.421 +  "psubq",
  46.422 +  "psubsb",
  46.423 +  "psubsw",
  46.424 +  "psubusb",
  46.425 +  "psubusw",
  46.426 +  "psubw",
  46.427 +  "pswapd",
  46.428 +  "punpckhbw",
  46.429 +  "punpckhdq",
  46.430 +  "punpckhqdq",
  46.431 +  "punpckhwd",
  46.432 +  "punpcklbw",
  46.433 +  "punpckldq",
  46.434 +  "punpcklqdq",
  46.435 +  "punpcklwd",
  46.436 +  "push",
  46.437 +  "pusha",
  46.438 +  "pushad",
  46.439 +  "pushfw",
  46.440 +  "pushfd",
  46.441 +  "pushfq",
  46.442 +  "pxor",
  46.443 +  "rcl",
  46.444 +  "rcpps",
  46.445 +  "rcpss",
  46.446 +  "rcr",
  46.447 +  "rdivisr",
  46.448 +  "rdmsr",
  46.449 +  "rdpmc",
  46.450 +  "rdtsc",
  46.451 +  "rep",
  46.452 +  "repne",
  46.453 +  "ret",
  46.454 +  "retf",
  46.455 +  "rol",
  46.456 +  "ror",
  46.457 +  "rsm",
  46.458 +  "rsqrtps",
  46.459 +  "rsqrtss",
  46.460 +  "sahf",
  46.461 +  "sal",
  46.462 +  "salc",
  46.463 +  "sar",
  46.464 +  "sbb",
  46.465 +  "scas",
  46.466 +  "scasb",
  46.467 +  "scasd",
  46.468 +  "scasq",
  46.469 +  "scasw",
  46.470 +  "seto",
  46.471 +  "setno",
  46.472 +  "setb",
  46.473 +  "setnb",
  46.474 +  "setz",
  46.475 +  "setnz",
  46.476 +  "setbe",
  46.477 +  "setnbe",
  46.478 +  "sets",
  46.479 +  "setns",
  46.480 +  "setp",
  46.481 +  "setnp",
  46.482 +  "setl",
  46.483 +  "setnl",
  46.484 +  "setle",
  46.485 +  "setnle",
  46.486 +  "sfence",
  46.487 +  "sgdt",
  46.488 +  "shl",
  46.489 +  "shld",
  46.490 +  "shr",
  46.491 +  "shrd",
  46.492 +  "shufpd",
  46.493 +  "shufps",
  46.494 +  "sidt",
  46.495 +  "sldt",
  46.496 +  "smsw",
  46.497 +  "sqrtpd",
  46.498 +  "sqrtps",
  46.499 +  "sqrtsd",
  46.500 +  "sqrtss",
  46.501 +  "stc",
  46.502 +  "std",
  46.503 +  "sti",
  46.504 +  "stmxcsr",
  46.505 +  "stos",
  46.506 +  "stosb",
  46.507 +  "stosw",
  46.508 +  "stosd",
  46.509 +  "str",
  46.510 +  "sub",
  46.511 +  "subpd",
  46.512 +  "subps",
  46.513 +  "subsd",
  46.514 +  "subss",
  46.515 +  "swapgs",
  46.516 +  "syscall",
  46.517 +  "sysenter",
  46.518 +  "sysexit",
  46.519 +  "sysret",
  46.520 +  "test",
  46.521 +  "ucomisd",
  46.522 +  "ucomiss",
  46.523 +  "ud2",
  46.524 +  "unpckhpd",
  46.525 +  "unpckhps",
  46.526 +  "unpcklpd",
  46.527 +  "unpcklps",
  46.528 +  "verr",
  46.529 +  "verw",
  46.530 +  "wait",
  46.531 +  "wbinvd",
  46.532 +  "wrmsr",
  46.533 +  "xadd",
  46.534 +  "xchg",
  46.535 +  "xlat",
  46.536 +  "xlatb",
  46.537 +  "xor",
  46.538 +  "xorpd",
  46.539 +  "xorps",
  46.540 +  "invalid",
  46.541 +  "grp",
  46.542 +  "a32",
  46.543 +  "o32",
  46.544 +  "es",
  46.545 +  "fs",
  46.546 +  "gs",
  46.547 +  "cs",
  46.548 +  "ds",
  46.549 +  "ss",
  46.550 +  "x87",
  46.551 +  "3dnow",
  46.552 +  "db",
  46.553 +  "cmpxchg16b",
  46.554 +  "stosq",
  46.555 +  "int3",
  46.556 +  "movsldup",
  46.557 +  "movshdup",
  46.558 +  "movddup",
  46.559 +  "rdtscp",
  46.560 +  "vmrun",
  46.561 +  "vmmcall",
  46.562 +  "vmload",
  46.563 +  "vmsave",
  46.564 +  "stgi",
  46.565 +  "clgi",
  46.566 +  "skinit",
  46.567 +  "invlpga",
  46.568 +  "ja",
  46.569 +  "jae",
  46.570 +  "jg",
  46.571 +  "jge",
  46.572 +  "jc",
  46.573 +  "jnc",
  46.574 +  "fisttp",
  46.575 +  "prefetchnta",
  46.576 +  "prefetcht0",
  46.577 +  "prefetcht1",
  46.578 +  "prefetcht2",
  46.579 +  "cmovae",
  46.580 +  "cmova",
  46.581 +  "cmovge",
  46.582 +  "cmovg",
  46.583 +  "seta",
  46.584 +  "setge",
  46.585 +  "setg",
  46.586 +  "pause",
  46.587 +  "na",
  46.588 +  "haddpd",
  46.589 +  "hsubpd",
  46.590 +  "addsubpd",
  46.591 +  "haddps",
  46.592 +  "hsubps",
  46.593 +  "addsubps",
  46.594 +  "lddqu",
  46.595 +  "int1",
  46.596 +  "vmcall",
  46.597 +  "vmlaunch",
  46.598 +  "vmresume",
  46.599 +  "vmxoff",
  46.600 +  "monitor",
  46.601 +  "mwait",
  46.602 +  "vmptrld",
  46.603 +  "vmptrst",
  46.604 +  "vmclear",
  46.605 +  "vmxon",
  46.606 +  "none",
  46.607 +  "I3vil",
  46.608 +};
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/xen/kdb/x86/udis86-1.6/mnemonics.h	Thu Feb 03 15:42:41 2011 -0800
    47.3 @@ -0,0 +1,612 @@
    47.4 +/* Do not edit, Generated by mnemonics.pl */ 
    47.5 +
    47.6 +#ifndef UD_MNEMONICS_H
    47.7 +#define UD_MNEMONICS_H
    47.8 +
    47.9 +extern const char* ud_mnemonics[];
   47.10 +
   47.11 +enum ud_mnemonic_code 
   47.12 +{ 
   47.13 +  UD_Iaaa,
   47.14 +  UD_Iaad,
   47.15 +  UD_Iaam,
   47.16 +  UD_Iaas,
   47.17 +  UD_Iadc,
   47.18 +  UD_Iadd,
   47.19 +  UD_Iaddpd,
   47.20 +  UD_Iaddps,
   47.21 +  UD_Iaddsd,
   47.22 +  UD_Iaddss,
   47.23 +  UD_Iand,
   47.24 +  UD_Iandnpd,
   47.25 +  UD_Iandnps,
   47.26 +  UD_Iandpd,
   47.27 +  UD_Iandps,
   47.28 +  UD_Iarpl,
   47.29 +  UD_Ibound,
   47.30 +  UD_Ibsf,
   47.31 +  UD_Ibsr,
   47.32 +  UD_Ibswap,
   47.33 +  UD_Ibt,
   47.34 +  UD_Ibtc,
   47.35 +  UD_Ibtr,
   47.36 +  UD_Ibts,
   47.37 +  UD_Icall,
   47.38 +  UD_Icbw,
   47.39 +  UD_Icdqe,
   47.40 +  UD_Iclc,
   47.41 +  UD_Icld,
   47.42 +  UD_Iclflush,
   47.43 +  UD_Icli,
   47.44 +  UD_Iclts,
   47.45 +  UD_Icmc,
   47.46 +  UD_Icmovo,
   47.47 +  UD_Icmovno,
   47.48 +  UD_Icmovb,
   47.49 +  UD_Icmovnb,
   47.50 +  UD_Icmovz,
   47.51 +  UD_Icmovnz,
   47.52 +  UD_Icmovbe,
   47.53 +  UD_Icmovnbe,
   47.54 +  UD_Icmovs,
   47.55 +  UD_Icmovns,
   47.56 +  UD_Icmovp,
   47.57 +  UD_Icmovnp,
   47.58 +  UD_Icmovl,
   47.59 +  UD_Icmovnl,
   47.60 +  UD_Icmovle,
   47.61 +  UD_Icmovnle,
   47.62 +  UD_Icmp,
   47.63 +  UD_Icmppd,
   47.64 +  UD_Icmpps,
   47.65 +  UD_Icmps,
   47.66 +  UD_Icmpsb,
   47.67 +  UD_Icmpsd,
   47.68 +  UD_Icmpsq,
   47.69 +  UD_Icmpss,
   47.70 +  UD_Icmpsw,
   47.71 +  UD_Icmpxchg,
   47.72 +  UD_Icmpxchg8b,
   47.73 +  UD_Icomisd,
   47.74 +  UD_Icomiss,
   47.75 +  UD_Icpuid,
   47.76 +  UD_Icqd,
   47.77 +  UD_Icqo,
   47.78 +  UD_Icvtdq2pd,
   47.79 +  UD_Icvtdq2ps,
   47.80 +  UD_Icvtpd2dq,
   47.81 +  UD_Icvtpd2pi,
   47.82 +  UD_Icvtpd2ps,
   47.83 +  UD_Icvtpi2pd,
   47.84 +  UD_Icvtpi2ps,
   47.85 +  UD_Icvtps2dq,
   47.86 +  UD_Icvtps2pd,
   47.87 +  UD_Icvtps2pi,
   47.88 +  UD_Icvtsd2si,
   47.89 +  UD_Icvtsd2ss,
   47.90 +  UD_Icvtsi2sd,
   47.91 +  UD_Icvtsi2ss,
   47.92 +  UD_Icvtss2sd,
   47.93 +  UD_Icvtss2si,
   47.94 +  UD_Icvttpd2dq,
   47.95 +  UD_Icvttpd2pi,
   47.96 +  UD_Icvttps2dq,
   47.97 +  UD_Icvttps2pi,
   47.98 +  UD_Icvttsd2si,
   47.99 +  UD_Icvttsi2sd,
  47.100 +  UD_Icvttsi2ss,
  47.101 +  UD_Icvttss2si,
  47.102 +  UD_Icwd,
  47.103 +  UD_Icwde,
  47.104 +  UD_Icdq,
  47.105 +  UD_Idaa,
  47.106 +  UD_Idas,
  47.107 +  UD_Idec,
  47.108 +  UD_Idiv,
  47.109 +  UD_Idivpd,
  47.110 +  UD_Idivps,
  47.111 +  UD_Idivsd,
  47.112 +  UD_Idivss,
  47.113 +  UD_Iemms,
  47.114 +  UD_Ienter,
  47.115 +  UD_Iesc,
  47.116 +  UD_If2xm1,
  47.117 +  UD_Ifsxm1,
  47.118 +  UD_Ifabs,
  47.119 +  UD_Ifadd,
  47.120 +  UD_Ifaddp,
  47.121 +  UD_Ifbld,
  47.122 +  UD_Ifbstp,
  47.123 +  UD_Ifchs,
  47.124 +  UD_Ifclex,
  47.125 +  UD_Ifcmovb,
  47.126 +  UD_Ifcmovbe,
  47.127 +  UD_Ifcmove,
  47.128 +  UD_Ifcmovnb,
  47.129 +  UD_Ifcmovnbe,
  47.130 +  UD_Ifcmovne,
  47.131 +  UD_Ifcmovnu,
  47.132 +  UD_Ifcmovu,
  47.133 +  UD_Ifcom,
  47.134 +  UD_Ifcomi,
  47.135 +  UD_Ifcomp,
  47.136 +  UD_Ifcomip,
  47.137 +  UD_Ifcompp,
  47.138 +  UD_Ifcos,
  47.139 +  UD_Ifdecstp,
  47.140 +  UD_Ifdiv,
  47.141 +  UD_Ifdivp,
  47.142 +  UD_Ifdivr,
  47.143 +  UD_Ifdivrp,
  47.144 +  UD_Ifemms,
  47.145 +  UD_Iffree,
  47.146 +  UD_Ifiadd,
  47.147 +  UD_Ificom,
  47.148 +  UD_Ificomp,
  47.149 +  UD_Ifidiv,
  47.150 +  UD_Ifidivr,
  47.151 +  UD_Ifidw,
  47.152 +  UD_Ifidwr,
  47.153 +  UD_Ifild,
  47.154 +  UD_Ifimul,
  47.155 +  UD_Ifincstp,
  47.156 +  UD_Ifinit,
  47.157 +  UD_Ifist,
  47.158 +  UD_Ifistp,
  47.159 +  UD_Ifisub,
  47.160 +  UD_Ifisubr,
  47.161 +  UD_Ifld,
  47.162 +  UD_Ifld1,
  47.163 +  UD_Ifldcw,
  47.164 +  UD_Ifldenv,
  47.165 +  UD_Ifldl2e,
  47.166 +  UD_Ifldl2t,
  47.167 +  UD_Ifldlg2,
  47.168 +  UD_Ifldln2,
  47.169 +  UD_Ifldlpi,
  47.170 +  UD_Ifldx,
  47.171 +  UD_Ifldz,
  47.172 +  UD_Ifmul,
  47.173 +  UD_Ifmulp,
  47.174 +  UD_Ifnclex,
  47.175 +  UD_Ifncstp,
  47.176 +  UD_Ifninit,
  47.177 +  UD_Ifnop,
  47.178 +  UD_Ifnsave,
  47.179 +  UD_Ifnstcw,
  47.180 +  UD_Ifnstenv,
  47.181 +  UD_Ifnstsw,
  47.182 +  UD_Ifpatan,
  47.183 +  UD_Ifprem,
  47.184 +  UD_Ifprem1,
  47.185 +  UD_Ifptan,
  47.186 +  UD_Ifpxtract,
  47.187 +  UD_Ifrndint,
  47.188 +  UD_Ifrstor,
  47.189 +  UD_Ifsave,
  47.190 +  UD_Ifscale,
  47.191 +  UD_Ifsin,
  47.192 +  UD_Ifsincos,
  47.193 +  UD_Ifsqrt,
  47.194 +  UD_Ifst,
  47.195 +  UD_Ifstcw,
  47.196 +  UD_Ifstenv,
  47.197 +  UD_Ifstp,
  47.198 +  UD_Ifstsw,
  47.199 +  UD_Ifsub,
  47.200 +  UD_Ifsubp,
  47.201 +  UD_Ifsubr,
  47.202 +  UD_Ifsubrp,
  47.203 +  UD_Iftst,
  47.204 +  UD_Ifucom,
  47.205 +  UD_Ifucomi,
  47.206 +  UD_Ifucomip,
  47.207 +  UD_Ifucomp,
  47.208 +  UD_Ifucompp,
  47.209 +  UD_Ifwait,
  47.210 +  UD_Ifxam,
  47.211 +  UD_Ifxch,
  47.212 +  UD_Ifxrstor,
  47.213 +  UD_Ifxsave,
  47.214 +  UD_Ifxtract,
  47.215 +  UD_Ifyl2x,
  47.216 +  UD_Ifyl2xp1,
  47.217 +  UD_Ihlt,
  47.218 +  UD_Iidiv,
  47.219 +  UD_Iimul,
  47.220 +  UD_Iin,
  47.221 +  UD_Iinc,
  47.222 +  UD_Iins,
  47.223 +  UD_Iinsb,
  47.224 +  UD_Iinsd,
  47.225 +  UD_Iinsw,
  47.226 +  UD_Iint,
  47.227 +  UD_Iinto,
  47.228 +  UD_Iinvd,
  47.229 +  UD_Iinvlpg,
  47.230 +  UD_Iiretw,
  47.231 +  UD_Iiretd,
  47.232 +  UD_Iiretq,
  47.233 +  UD_Ijcxz,
  47.234 +  UD_Ijecxz,
  47.235 +  UD_Ijmp,
  47.236 +  UD_Ijrcxz,
  47.237 +  UD_Ijo,
  47.238 +  UD_Ijno,
  47.239 +  UD_Ijb,
  47.240 +  UD_Ijnb,
  47.241 +  UD_Ijz,
  47.242 +  UD_Ijnz,
  47.243 +  UD_Ijbe,
  47.244 +  UD_Ijnbe,
  47.245 +  UD_Ijs,
  47.246 +  UD_Ijns,
  47.247 +  UD_Ijp,
  47.248 +  UD_Ijnp,
  47.249 +  UD_Ijl,
  47.250 +  UD_Ijnl,
  47.251 +  UD_Ijle,
  47.252 +  UD_Ijnle,
  47.253 +  UD_Ilahf,
  47.254 +  UD_Ilar,
  47.255 +  UD_Ildmxcsr,
  47.256 +  UD_Ilds,
  47.257 +  UD_Ilea,
  47.258 +  UD_Ileave,
  47.259 +  UD_Iles,
  47.260 +  UD_Ilfence,
  47.261 +  UD_Ilfs,
  47.262 +  UD_Ilgdt,
  47.263 +  UD_Ilgs,
  47.264 +  UD_Ilidt,
  47.265 +  UD_Illdt,
  47.266 +  UD_Ilmsw,
  47.267 +  UD_Ilock,
  47.268 +  UD_Ilods,
  47.269 +  UD_Ilodsb,
  47.270 +  UD_Ilodsd,
  47.271 +  UD_Ilodsq,
  47.272 +  UD_Ilodsw,
  47.273 +  UD_Iloop,
  47.274 +  UD_Iloope,
  47.275 +  UD_Iloopn,
  47.276 +  UD_Iloopne,
  47.277 +  UD_Iloopnz,
  47.278 +  UD_Iloopz,
  47.279 +  UD_Ilsl,
  47.280 +  UD_Ilss,
  47.281 +  UD_Iltr,
  47.282 +  UD_Imaskmovdqu,
  47.283 +  UD_Imaskmovq,
  47.284 +  UD_Imaxpd,
  47.285 +  UD_Imaxps,
  47.286 +  UD_Imaxsd,
  47.287 +  UD_Imaxss,
  47.288 +  UD_Imfence,
  47.289 +  UD_Iminpd,
  47.290 +  UD_Iminps,
  47.291 +  UD_Iminsd,
  47.292 +  UD_Iminss,
  47.293 +  UD_Imov,
  47.294 +  UD_Imovapd,
  47.295 +  UD_Imovaps,
  47.296 +  UD_Imovd,
  47.297 +  UD_Imovdq2q,
  47.298 +  UD_Imovdqa,
  47.299 +  UD_Imovdqu,
  47.300 +  UD_Imovhlps,
  47.301 +  UD_Imovhpd,
  47.302 +  UD_Imovhps,
  47.303 +  UD_Imovlhps,
  47.304 +  UD_Imovlpd,
  47.305 +  UD_Imovlps,
  47.306 +  UD_Imovmskpd,
  47.307 +  UD_Imovmskps,
  47.308 +  UD_Imovnig,
  47.309 +  UD_Imovntdq,
  47.310 +  UD_Imovnti,
  47.311 +  UD_Imovntpd,
  47.312 +  UD_Imovntps,
  47.313 +  UD_Imovntq,
  47.314 +  UD_Imovq,
  47.315 +  UD_Imovq2dq,
  47.316 +  UD_Imovqa,
  47.317 +  UD_Imovs,
  47.318 +  UD_Imovsb,
  47.319 +  UD_Imovsd,
  47.320 +  UD_Imovsq,
  47.321 +  UD_Imovss,
  47.322 +  UD_Imovsw,
  47.323 +  UD_Imovsx,
  47.324 +  UD_Imovsxd,
  47.325 +  UD_Imovupd,
  47.326 +  UD_Imovups,
  47.327 +  UD_Imovzx,
  47.328 +  UD_Imul,
  47.329 +  UD_Imulpd,
  47.330 +  UD_Imulps,
  47.331 +  UD_Imulsd,
  47.332 +  UD_Imulss,
  47.333 +  UD_Ineg,
  47.334 +  UD_Inop,
  47.335 +  UD_Inot,
  47.336 +  UD_Ior,
  47.337 +  UD_Iorpd,
  47.338 +  UD_Iorps,
  47.339 +  UD_Iout,
  47.340 +  UD_Iouts,
  47.341 +  UD_Ioutsb,
  47.342 +  UD_Ioutsd,
  47.343 +  UD_Ioutsw,
  47.344 +  UD_Ipackssdw,
  47.345 +  UD_Ipacksswb,
  47.346 +  UD_Ipackusdw,
  47.347 +  UD_Ipackuswb,
  47.348 +  UD_Ipaddb,
  47.349 +  UD_Ipaddd,
  47.350 +  UD_Ipaddq,
  47.351 +  UD_Ipaddsb,
  47.352 +  UD_Ipaddsw,
  47.353 +  UD_Ipaddusb,
  47.354 +  UD_Ipaddusw,
  47.355 +  UD_Ipaddw,
  47.356 +  UD_Ipand,
  47.357 +  UD_Ipandn,
  47.358 +  UD_Ipavgb,
  47.359 +  UD_Ipavgusb,
  47.360 +  UD_Ipavgw,
  47.361 +  UD_Ipcmpeqb,
  47.362 +  UD_Ipcmpeqd,
  47.363 +  UD_Ipcmpeqw,
  47.364 +  UD_Ipcmpgtb,
  47.365 +  UD_Ipcmpgtd,
  47.366 +  UD_Ipcmpgtw,
  47.367 +  UD_Ipextrw,
  47.368 +  UD_Ipf2id,
  47.369 +  UD_Ipf2iw,
  47.370 +  UD_Ipfacc,
  47.371 +  UD_Ipfadd,
  47.372 +  UD_Ipfcmpeq,
  47.373 +  UD_Ipfcmpge,
  47.374 +  UD_Ipfcmpgt,
  47.375 +  UD_Ipfmax,
  47.376 +  UD_Ipfmin,
  47.377 +  UD_Ipfmul,
  47.378 +  UD_Ipfnacc,
  47.379 +  UD_Ipfpnacc,
  47.380 +  UD_Ipfrcp,
  47.381 +  UD_Ipfrcpit1,
  47.382 +  UD_Ipfrcpit2,
  47.383 +  UD_Ipfrsqit1,
  47.384 +  UD_Ipfrsqrt,
  47.385 +  UD_Ipfsub,
  47.386 +  UD_Ipfsubr,
  47.387 +  UD_Ipi2fd,
  47.388 +  UD_Ipi2fw,
  47.389 +  UD_Ipinsrw,
  47.390 +  UD_Ipmaddwd,
  47.391 +  UD_Ipmaxsw,
  47.392 +  UD_Ipmaxub,
  47.393 +  UD_Ipminsw,
  47.394 +  UD_Ipminub,
  47.395 +  UD_Ipmovmskb,
  47.396 +  UD_Ipmulhrw,
  47.397 +  UD_Ipmulhuw,
  47.398 +  UD_Ipmulhw,
  47.399 +  UD_Ipmullw,
  47.400 +  UD_Ipmuludq,
  47.401 +  UD_Ipop,
  47.402 +  UD_Ipopa,
  47.403 +  UD_Ipopad,
  47.404 +  UD_Ipopfw,
  47.405 +  UD_Ipopfd,
  47.406 +  UD_Ipopfq,
  47.407 +  UD_Ipor,
  47.408 +  UD_Iprefetch,
  47.409 +  UD_Ipsadbw,
  47.410 +  UD_Ipshufd,
  47.411 +  UD_Ipshufhw,
  47.412 +  UD_Ipshuflw,
  47.413 +  UD_Ipshufw,
  47.414 +  UD_Ipslld,
  47.415 +  UD_Ipslldq,
  47.416 +  UD_Ipsllq,
  47.417 +  UD_Ipsllw,
  47.418 +  UD_Ipsrad,
  47.419 +  UD_Ipsraw,
  47.420 +  UD_Ipsraq,
  47.421 +  UD_Ipsrld,
  47.422 +  UD_Ipsrldq,
  47.423 +  UD_Ipsrlq,
  47.424 +  UD_Ipsrlw,
  47.425 +  UD_Ipsubb,
  47.426 +  UD_Ipsubd,
  47.427 +  UD_Ipsubq,
  47.428 +  UD_Ipsubsb,
  47.429 +  UD_Ipsubsw,
  47.430 +  UD_Ipsubusb,
  47.431 +  UD_Ipsubusw,
  47.432 +  UD_Ipsubw,
  47.433 +  UD_Ipswapd,
  47.434 +  UD_Ipunpckhbw,
  47.435 +  UD_Ipunpckhdq,
  47.436 +  UD_Ipunpckhqdq,
  47.437 +  UD_Ipunpckhwd,
  47.438 +  UD_Ipunpcklbw,
  47.439 +  UD_Ipunpckldq,
  47.440 +  UD_Ipunpcklqdq,
  47.441 +  UD_Ipunpcklwd,
  47.442 +  UD_Ipush,
  47.443 +  UD_Ipusha,
  47.444 +  UD_Ipushad,
  47.445 +  UD_Ipushfw,
  47.446 +  UD_Ipushfd,
  47.447 +  UD_Ipushfq,
  47.448 +  UD_Ipxor,
  47.449 +  UD_Ircl,
  47.450 +  UD_Ircpps,
  47.451 +  UD_Ircpss,
  47.452 +  UD_Ircr,
  47.453 +  UD_Irdivisr,
  47.454 +  UD_Irdmsr,
  47.455 +  UD_Irdpmc,
  47.456 +  UD_Irdtsc,
  47.457 +  UD_Irep,
  47.458 +  UD_Irepne,
  47.459 +  UD_Iret,
  47.460 +  UD_Iretf,
  47.461 +  UD_Irol,
  47.462 +  UD_Iror,
  47.463 +  UD_Irsm,
  47.464 +  UD_Irsqrtps,
  47.465 +  UD_Irsqrtss,
  47.466 +  UD_Isahf,
  47.467 +  UD_Isal,
  47.468 +  UD_Isalc,
  47.469 +  UD_Isar,
  47.470 +  UD_Isbb,
  47.471 +  UD_Iscas,
  47.472 +  UD_Iscasb,
  47.473 +  UD_Iscasd,
  47.474 +  UD_Iscasq,
  47.475 +  UD_Iscasw,
  47.476 +  UD_Iseto,
  47.477 +  UD_Isetno,
  47.478 +  UD_Isetb,
  47.479 +  UD_Isetnb,
  47.480 +  UD_Isetz,
  47.481 +  UD_Isetnz,
  47.482 +  UD_Isetbe,
  47.483 +  UD_Isetnbe,
  47.484 +  UD_Isets,
  47.485 +  UD_Isetns,
  47.486 +  UD_Isetp,
  47.487 +  UD_Isetnp,
  47.488 +  UD_Isetl,
  47.489 +  UD_Isetnl,
  47.490 +  UD_Isetle,
  47.491 +  UD_Isetnle,
  47.492 +  UD_Isfence,
  47.493 +  UD_Isgdt,
  47.494 +  UD_Ishl,
  47.495 +  UD_Ishld,
  47.496 +  UD_Ishr,
  47.497 +  UD_Ishrd,
  47.498 +  UD_Ishufpd,
  47.499 +  UD_Ishufps,
  47.500 +  UD_Isidt,
  47.501 +  UD_Isldt,
  47.502 +  UD_Ismsw,
  47.503 +  UD_Isqrtpd,
  47.504 +  UD_Isqrtps,
  47.505 +  UD_Isqrtsd,
  47.506 +  UD_Isqrtss,
  47.507 +  UD_Istc,
  47.508 +  UD_Istd,
  47.509 +  UD_Isti,
  47.510 +  UD_Istmxcsr,
  47.511 +  UD_Istos,
  47.512 +  UD_Istosb,
  47.513 +  UD_Istosw,
  47.514 +  UD_Istosd,
  47.515 +  UD_Istr,
  47.516 +  UD_Isub,
  47.517 +  UD_Isubpd,
  47.518 +  UD_Isubps,
  47.519 +  UD_Isubsd,
  47.520 +  UD_Isubss,
  47.521 +  UD_Iswapgs,
  47.522 +  UD_Isyscall,
  47.523 +  UD_Isysenter,
  47.524 +  UD_Isysexit,
  47.525 +  UD_Isysret,
  47.526 +  UD_Itest,
  47.527 +  UD_Iucomisd,
  47.528 +  UD_Iucomiss,
  47.529 +  UD_Iud2,
  47.530 +  UD_Iunpckhpd,
  47.531 +  UD_Iunpckhps,
  47.532 +  UD_Iunpcklpd,
  47.533 +  UD_Iunpcklps,
  47.534 +  UD_Iverr,
  47.535 +  UD_Iverw,
  47.536 +  UD_Iwait,
  47.537 +  UD_Iwbinvd,
  47.538 +  UD_Iwrmsr,
  47.539 +  UD_Ixadd,
  47.540 +  UD_Ixchg,
  47.541 +  UD_Ixlat,
  47.542 +  UD_Ixlatb,
  47.543 +  UD_Ixor,
  47.544 +  UD_Ixorpd,
  47.545 +  UD_Ixorps,
  47.546 +  UD_Iinvalid,
  47.547 +  UD_Igrp,
  47.548 +  UD_Ia32,
  47.549 +  UD_Io32,
  47.550 +  UD_Ies,
  47.551 +  UD_Ifs,
  47.552 +  UD_Igs,
  47.553 +  UD_Ics,
  47.554 +  UD_Ids,
  47.555 +  UD_Iss,
  47.556 +  UD_Ix87,
  47.557 +  UD_I3dnow,
  47.558 +  UD_Idb,
  47.559 +  UD_Icmpxchg16b,
  47.560 +  UD_Istosq,
  47.561 +  UD_Iint3,
  47.562 +  UD_Imovsldup,
  47.563 +  UD_Imovshdup,
  47.564 +  UD_Imovddup,
  47.565 +  UD_Irdtscp,
  47.566 +  UD_Ivmrun,
  47.567 +  UD_Ivmmcall,
  47.568 +  UD_Ivmload,
  47.569 +  UD_Ivmsave,
  47.570 +  UD_Istgi,
  47.571 +  UD_Iclgi,
  47.572 +  UD_Iskinit,
  47.573 +  UD_Iinvlpga,
  47.574 +  UD_Ija,
  47.575 +  UD_Ijae,
  47.576 +  UD_Ijg,
  47.577 +  UD_Ijge,
  47.578 +  UD_Ijc,
  47.579 +  UD_Ijnc,
  47.580 +  UD_Ifisttp,
  47.581 +  UD_Iprefetchnta,
  47.582 +  UD_Iprefetcht0,
  47.583 +  UD_Iprefetcht1,
  47.584 +  UD_Iprefetcht2,
  47.585 +  UD_Icmovae,
  47.586 +  UD_Icmova,
  47.587 +  UD_Icmovge,
  47.588 +  UD_Icmovg,
  47.589 +  UD_Iseta,
  47.590 +  UD_Isetge,
  47.591 +  UD_Isetg,
  47.592 +  UD_Ipause,
  47.593 +  UD_Ina,
  47.594 +  UD_Ihaddpd,
  47.595 +  UD_Ihsubpd,
  47.596 +  UD_Iaddsubpd,
  47.597 +  UD_Ihaddps,
  47.598 +  UD_Ihsubps,
  47.599 +  UD_Iaddsubps,
  47.600 +  UD_Ilddqu,
  47.601 +  UD_Iint1,
  47.602 +  UD_Ivmcall,
  47.603 +  UD_Ivmlaunch,
  47.604 +  UD_Ivmresume,
  47.605 +  UD_Ivmxoff,
  47.606 +  UD_Imonitor,
  47.607 +  UD_Imwait,
  47.608 +  UD_Ivmptrld,
  47.609 +  UD_Ivmptrst,
  47.610 +  UD_Ivmclear,
  47.611 +  UD_Ivmxon,
  47.612 +  UD_Inone,
  47.613 +  UD_I3vil
  47.614 +};
  47.615 +#endif
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/xen/kdb/x86/udis86-1.6/opcmap.c	Thu Feb 03 15:42:41 2011 -0800
    48.3 @@ -0,0 +1,3087 @@
    48.4 +/* -----------------------------------------------------------------------------
    48.5 + * opcmap.c
    48.6 + *
    48.7 + * Copyright (c) 2006, Vivek Mohan <vivek@sig9.com>
    48.8 + * All rights reserved. See LICENSE
    48.9 + * -----------------------------------------------------------------------------
   48.10 + */
   48.11 +/* #include <assert.h> */
   48.12 +#include "../../include/kdbinc.h"
   48.13 +#include "types.h"
   48.14 +#include "mnemonics.h"
   48.15 +#include "opcmap.h"
   48.16 +#include "input.h"
   48.17 +
   48.18 +/* operand types - check out the intel/amd manuals */
   48.19 +#define Ap      { OP_A, SZ_P    }
   48.20 +#define E       { OP_E, 0       }
   48.21 +#define Eb      { OP_E, SZ_B    }
   48.22 +#define Ew      { OP_E, SZ_W    }
   48.23 +#define Ev      { OP_E, SZ_V    }
   48.24 +#define Ed      { OP_E, SZ_D    }
   48.25 +#define Ez      { OP_E, SZ_Z    }
   48.26 +#define Ex      { OP_E, SZ_MDQ  }
   48.27 +#define Ep      { OP_E, SZ_P    }
   48.28 +#define G       { OP_G, 0       }
   48.29 +#define Gb      { OP_G, SZ_B    }
   48.30 +#define Gw      { OP_G, SZ_W    }
   48.31 +#define Gv      { OP_G, SZ_V    }
   48.32 +#define Gvw     { OP_G, SZ_MDQ  }
   48.33 +#define Gd      { OP_G, SZ_D    }
   48.34 +#define Gx      { OP_G, SZ_MDQ  }
   48.35 +#define Gz      { OP_G, SZ_Z    }
   48.36 +#define M       { OP_M, 0       }
   48.37 +#define Mb      { OP_M, SZ_B    }
   48.38 +#define Mw      { OP_M, SZ_W    }
   48.39 +#define Ms      { OP_M, SZ_W    }
   48.40 +#define Md      { OP_M, SZ_D    }
   48.41 +#define Mq      { OP_M, SZ_Q    }
   48.42 +#define Mt      { OP_M, SZ_T    }
   48.43 +#define I1      { OP_I1, 0      }
   48.44 +#define I3      { OP_I3, 0      }
   48.45 +#define Ib      { OP_I, SZ_B    }
   48.46 +#define Isb     { OP_I, SZ_SB   }
   48.47 +#define Iw      { OP_I, SZ_W    }
   48.48 +#define Iv      { OP_I, SZ_V    }
   48.49 +#define Iz      { OP_I, SZ_Z    }
   48.50 +#define Jv      { OP_J, SZ_V    }
   48.51 +#define Jz      { OP_J, SZ_Z    }
   48.52 +#define Jb      { OP_J, SZ_B    }
   48.53 +#define R       { OP_R, SZ_RDQ  }
   48.54 +#define C       { OP_C, 0       } 
   48.55 +#define D       { OP_D, 0       }
   48.56 +#define S       { OP_S, 0       }
   48.57 +#define Ob      { OP_O, SZ_B    }
   48.58 +#define Ow      { OP_O, SZ_W    }
   48.59 +#define Ov      { OP_O, SZ_V    }
   48.60 +#define V       { OP_V, 0       }
   48.61 +#define W       { OP_W, 0       }
   48.62 +#define P       { OP_P, 0       }
   48.63 +#define Q       { OP_Q, 0       }
   48.64 +#define VR      { OP_VR, 0      }
   48.65 +#define PR      { OP_PR, 0      }
   48.66 +#define AL      { OP_AL, 0      }
   48.67 +#define CL      { OP_CL, 0      }
   48.68 +#define DL      { OP_DL, 0      }
   48.69 +#define BL      { OP_BL, 0      }
   48.70 +#define AH      { OP_AH, 0      }
   48.71 +#define CH      { OP_CH, 0      }
   48.72 +#define DH      { OP_DH, 0      }
   48.73 +#define BH      { OP_BH, 0      }
   48.74 +#define AX      { OP_AX, 0      }
   48.75 +#define CX      { OP_CX, 0      }
   48.76 +#define DX      { OP_DX, 0      }
   48.77 +#define BX      { OP_BX, 0      }
   48.78 +#define SI      { OP_SI, 0      }
   48.79 +#define DI      { OP_DI, 0      }
   48.80 +#define SP      { OP_SP, 0      }
   48.81 +#define BP      { OP_BP, 0      }
   48.82 +#define eAX     { OP_eAX, 0     }
   48.83 +#define eCX     { OP_eCX, 0     }
   48.84 +#define eDX     { OP_eDX, 0     }
   48.85 +#define eBX     { OP_eBX, 0     }
   48.86 +#define eSI     { OP_eSI, 0     }
   48.87 +#define eDI     { OP_eDI, 0     }
   48.88 +#define eSP     { OP_eSP, 0     }
   48.89 +#define eBP     { OP_eBP, 0     }
   48.90 +#define rAX     { OP_rAX, 0     }
   48.91 +#define rCX     { OP_rCX, 0     }
   48.92 +#define rBX     { OP_rDX, 0     }
   48.93 +#define rDX     { OP_rDX, 0     }
   48.94 +#define rSI     { OP_rSI, 0     }
   48.95 +#define rDI     { OP_rDI, 0     }
   48.96 +#define rSP     { OP_rSP, 0     }
   48.97 +#define rBP     { OP_rBP, 0     }
   48.98 +#define ES      { OP_ES, 0      }
   48.99 +#define CS      { OP_CS, 0      }
  48.100 +#define DS      { OP_DS, 0      }
  48.101 +#define SS      { OP_SS, 0      }
  48.102 +#define GS      { OP_GS, 0      }
  48.103 +#define FS      { OP_FS, 0      }
  48.104 +#define ST0     { OP_ST0, 0     }
  48.105 +#define ST1     { OP_ST1, 0     }
  48.106 +#define ST2     { OP_ST2, 0     }
  48.107 +#define ST3     { OP_ST3, 0     }
  48.108 +#define ST4     { OP_ST4, 0     }
  48.109 +#define ST5     { OP_ST5, 0     }
  48.110 +#define ST6     { OP_ST6, 0     }
  48.111 +#define ST7     { OP_ST7, 0     }
  48.112 +#define NOARG   { 0, 0          }
  48.113 +#define ALr8b   { OP_ALr8b,0    }
  48.114 +#define CLr9b   { OP_CLr9b,0    }
  48.115 +#define DLr10b  { OP_DLr10b,0   }
  48.116 +#define BLr11b  { OP_BLr11b,0   }
  48.117 +#define AHr12b  { OP_AHr12b,0   }
  48.118 +#define CHr13b  { OP_CHr13b,0   }
  48.119 +#define DHr14b  { OP_DHr14b,0   }
  48.120 +#define BHr15b  { OP_BHr15b,0   }
  48.121 +#define rAXr8   { OP_rAXr8,0    }
  48.122 +#define rCXr9   { OP_rCXr9,0    }
  48.123 +#define rDXr10  { OP_rDXr10,0   }
  48.124 +#define rBXr11  { OP_rBXr11,0   }
  48.125 +#define rSPr12  { OP_rSPr12,0   }
  48.126 +#define rBPr13  { OP_rBPr13,0   }
  48.127 +#define rSIr14  { OP_rSIr14,0   }
  48.128 +#define rDIr15  { OP_rDIr15,0   }
  48.129 +
  48.130 +enum INSN_GROUPS
  48.131 +{
  48.132 +  GRP_80, 
  48.133 +  GRP_81, 
  48.134 +  GRP_82,
  48.135 +  GRP_83,
  48.136 +  GRP_8F,
  48.137 +  GRP_C0,
  48.138 +  GRP_C1,
  48.139 +  GRP_C6,
  48.140 +  GRP_C7,
  48.141 +  GRP_D0,
  48.142 +  GRP_D1,
  48.143 +  GRP_D2,
  48.144 +  GRP_D3,
  48.145 +  GRP_F6,
  48.146 +  GRP_F7,
  48.147 +  GRP_FE,
  48.148 +  GRP_FF,
  48.149 +  GRP_0F00,
  48.150 +  GRP_0F01,
  48.151 +  GRP_0F0D,
  48.152 +  GRP_0F18,
  48.153 +  GRP_0F71,
  48.154 +  GRP_0F72,
  48.155 +  GRP_0F73,
  48.156 +  GRP_0FAE,
  48.157 +  GRP_0FBA,
  48.158 +  GRP_0FB9,
  48.159 +  GRP_0FC7
  48.160 +};
  48.161 +
  48.162 +/* 1 byte opcode */
  48.163 +struct map_entry itab_1byte[0x100] = 
  48.164 +{
  48.165 +        /* Instruction, op1, op2, op3, Valid Prefixes */
  48.166 +
  48.167 +/* 00 */ { UD_Iadd,     Eb,     Gb,     NOARG,  Pa32 | REX(_X|_B|_R) },
  48.168 +/* 01 */ { UD_Iadd,     Ev,     Gv,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.169 +/* 02 */ { UD_Iadd,     Gb,     Eb,     NOARG,  Pa32 | REX(_X|_B|_R) },
  48.170 +/* 03 */ { UD_Iadd,     Gv,     Ev,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.171 +/* 04 */ { UD_Iadd,     AL,     Ib,     NOARG,  Pnone },
  48.172 +/* 05 */ { UD_Iadd,     rAX,    Iz,     NOARG,  Po32 | REX(_W) },
  48.173 +/* 06 */ { UD_Ipush,    ES,     NOARG,  NOARG,  Pinv64 },
  48.174 +/* 07 */ { UD_Ipop,     ES,     NOARG,  NOARG,  Pinv64 },
  48.175 +/* 08 */ { UD_Ior,      Eb,     Gb,     NOARG,  Pa32 | REX(_X|_B|_R) },
  48.176 +/* 09 */ { UD_Ior,      Ev,     Gv,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.177 +/* 0A */ { UD_Ior,      Gb,     Eb,     NOARG,  Pa32 | REX(_X|_B|_R)},
  48.178 +/* 0B */ { UD_Ior,      Gv,     Ev,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.179 +/* 0C */ { UD_Ior,      AL,     Ib,     NOARG,  Pnone },
  48.180 +/* 0D */ { UD_Ior,      rAX,    Iz,     NOARG,  Po32 | REX(_W) },
  48.181 +/* 0E */ { UD_Ipush,    CS,     NOARG,  NOARG,  Pinv64 },
  48.182 +/* 0F */ { UD_Iesc,     NOARG,  NOARG,  NOARG,  Pnone },
  48.183 +/* 10 */ { UD_Iadc,     Eb,     Gb,     NOARG,  Pa32 | REX(_X|_B|_R)  },
  48.184 +/* 11 */ { UD_Iadc,     Ev,     Gv,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.185 +/* 12 */ { UD_Iadc,     Gb,     Eb,     NOARG,  Pa32 | REX(_X|_B|_R)  },
  48.186 +/* 13 */ { UD_Iadc,     Gv,     Ev,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.187 +/* 14 */ { UD_Iadc,     AL,     Ib,     NOARG,  Pnone },
  48.188 +/* 15 */ { UD_Iadc,     rAX,    Iz,     NOARG,  Po32 | REX(_W) },
  48.189 +/* 16 */ { UD_Ipush,    SS,     NOARG,  NOARG,  Pinv64 },
  48.190 +/* 17 */ { UD_Ipop,     SS,     NOARG,  NOARG,  Pinv64 },
  48.191 +/* 18 */ { UD_Isbb,     Eb,     Gb,     NOARG,  Pa32 | REX(_X|_B|_R)  },
  48.192 +/* 19 */ { UD_Isbb,     Ev,     Gv,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.193 +/* 1A */ { UD_Isbb,     Gb,     Eb,     NOARG,  Pa32 | REX(_X|_B|_R)  },
  48.194 +/* 1B */ { UD_Isbb,     Gv,     Ev,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.195 +/* 1C */ { UD_Isbb,     AL,     Ib,     NOARG,  Pnone },
  48.196 +/* 1D */ { UD_Isbb,     rAX,    Iz,     NOARG,  Po32 | REX(_W) },
  48.197 +/* 1E */ { UD_Ipush,    DS,     NOARG,  NOARG,  Pinv64 },
  48.198 +/* 1F */ { UD_Ipop,     DS,     NOARG,  NOARG,  Pinv64 },
  48.199 +/* 20 */ { UD_Iand,     Eb,     Gb,     NOARG,  Pa32 | REX(_X|_B|_R)  },
  48.200 +/* 21 */ { UD_Iand,     Ev,     Gv,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.201 +/* 22 */ { UD_Iand,     Gb,     Eb,     NOARG,  Pa32 | REX(_X|_B|_R)  },
  48.202 +/* 23 */ { UD_Iand,     Gv,     Ev,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.203 +/* 24 */ { UD_Iand,     AL,     Ib,     NOARG,  Pnone },
  48.204 +/* 25 */ { UD_Iand,     rAX,    Iz,     NOARG,  Po32 | REX(_W) },
  48.205 +/* 26 */ { UD_Ies,      ES,     NOARG,  NOARG,  Pnone },
  48.206 +/* 27 */ { UD_Idaa,     NOARG,  NOARG,  NOARG,  Pinv64 },
  48.207 +/* 28 */ { UD_Isub,     Eb,     Gb,     NOARG,  Pa32 | REX(_X|_B|_R)  },
  48.208 +/* 29 */ { UD_Isub,     Ev,     Gv,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.209 +/* 2A */ { UD_Isub,     Gb,     Eb,     NOARG,  Pa32 | REX(_X|_B|_R)  },
  48.210 +/* 2B */ { UD_Isub,     Gv,     Ev,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.211 +/* 2C */ { UD_Isub,     AL,     Ib,     NOARG,  Pnone },
  48.212 +/* 2D */ { UD_Isub,     rAX,    Iz,     NOARG,  Po32 | REX(_W) },
  48.213 +/* 2E */ { UD_Ics,      CS,     NOARG,  NOARG,  Pnone },
  48.214 +/* 2F */ { UD_Idas,     NOARG,  NOARG,  NOARG,  Pinv64 },
  48.215 +/* 30 */ { UD_Ixor,     Eb,     Gb,     NOARG,  Pa32 | REX(_X|_B|_R)  },
  48.216 +/* 31 */ { UD_Ixor,     Ev,     Gv,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.217 +/* 32 */ { UD_Ixor,     Gb,     Eb,     NOARG,  Pa32 | REX(_X|_B|_R)  },
  48.218 +/* 33 */ { UD_Ixor,     Gv,     Ev,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.219 +/* 34 */ { UD_Ixor,     AL,     Ib,     NOARG,  Pnone },
  48.220 +/* 35 */ { UD_Ixor,     rAX,    Iz,     NOARG,  Po32 | REX(_W) },
  48.221 +/* 36 */ { UD_Iss,      ES,     NOARG,  NOARG,  Pinv64 },
  48.222 +/* 37 */ { UD_Iaaa,     NOARG,  NOARG,  NOARG,  Pinv64 },
  48.223 +/* 38 */ { UD_Icmp,     Eb,     Gb,     NOARG,  Pa32 | REX(_X|_B|_R)  },
  48.224 +/* 39 */ { UD_Icmp,     Ev,     Gv,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.225 +/* 3A */ { UD_Icmp,     Gb,     Eb,     NOARG,  Pa32 | REX(_X|_B|_R)  },
  48.226 +/* 3B */ { UD_Icmp,     Gv,     Ev,     NOARG,  Pa32 | Po32 | REX(_W|_R|_X|_B) },
  48.227 +/* 3C */ { UD_Icmp,     AL,     Ib,     NOARG,  Pnone },
  48.228 +/* 3D */ { UD_Icmp,     rAX,    Iz,     NOARG,  Po32 | REX(_W) },
  48.229 +/* 3E */ { UD_Ids,      ES,     NOARG,  NOARG,  Pnone },
  48.230 +/* 3F */ { UD_Iaas,     NOARG,  NOARG,  NOARG,  Pinv64 },
  48.231 +/* 40 */ { UD_Iinc,     eAX,    NOARG,  NOARG,  Po32 },
  48.232 +/* 41 */ { UD_Iinc,     eCX,    NOARG,  NOARG,  Po32 },
  48.233 +/* 42 */ { UD_Iinc,     eDX,    NOARG,  NOARG,  Po32 },
  48.234 +/* 43 */ { UD_Iinc,     eBX,    NOARG,  NOARG,  Po32 },
  48.235 +/* 44 */ { UD_Iinc,     eSP,    NOARG,  NOARG,  Po32 },
  48.236 +/* 45 */ { UD_Iinc,     eBP,    NOARG,  NOARG,  Po32 },
  48.237 +/* 46 */ { UD_Iinc,     eSI,    NOARG,  NOARG,  Po32 },
  48.238 +/* 47 */ { UD_Iinc,     eDI,    NOARG,  NOARG,  Po32 },
  48.239 +/* 48 */ { UD_Idec,     eAX,    NOARG,  NOARG,  Po32 },
  48.240 +/* 49 */ { UD_Idec,     eCX,    NOARG,  NOARG,  Po32 },
  48.241 +/* 4A */ { UD_Idec,     eDX,    NOARG,  NOARG,  Po32 },
  48.242 +/* 4B */ { UD_Idec,     eBX,    NOARG,  NOARG,  Po32 },
  48.243 +/* 4C */ { UD_Idec,     eSP,    NOARG,  NOARG,  Po32 },
  48.244 +/* 4D */ { UD_Idec,     eBP,    NOARG,  NOARG,  Po32 },
  48.245 +/* 4E */ { UD_Idec,     eSI,    NOARG,  NOARG,  Po32 },
  48.246 +/* 4F */ { UD_Idec,     eDI,    NOARG,  NOARG,  Po32 },
  48.247 +/* 50 */ { UD_Ipush,    rAXr8,  NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.248 +/* 51 */ { UD_Ipush,    rCXr9,  NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.249 +/* 52 */ { UD_Ipush,    rDXr10, NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.250 +/* 53 */ { UD_Ipush,    rBXr11, NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.251 +/* 54 */ { UD_Ipush,    rSPr12, NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.252 +/* 55 */ { UD_Ipush,    rBPr13, NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.253 +/* 56 */ { UD_Ipush,    rSIr14, NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.254 +/* 57 */ { UD_Ipush,    rDIr15, NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.255 +/* 58 */ { UD_Ipop,     rAXr8,  NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.256 +/* 59 */ { UD_Ipop,     rCXr9,  NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.257 +/* 5A */ { UD_Ipop,     rDXr10, NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.258 +/* 5B */ { UD_Ipop,     rBXr11, NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.259 +/* 5C */ { UD_Ipop,     rSPr12, NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.260 +/* 5D */ { UD_Ipop,     rBPr13, NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.261 +/* 5E */ { UD_Ipop,     rSIr14, NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.262 +/* 5F */ { UD_Ipop,     rDIr15, NOARG,  NOARG,  Po32 | Pdef64 | REX(_B) },
  48.263 +/* 60 */ { UD_Ipusha,   NOARG,  NOARG,  NOARG,  Po32 | Pinv64 | PdepM },
  48.264 +/* 61 */ { UD_Ipopa,    NOARG,  NOARG,  NOARG,  Po32 | Pinv64 | PdepM },
  48.265 +/* 62 */ { UD_Ibound,   Gv,     M,      NOARG,  Po32 | Pa32 | Pinv64 },
  48.266 +/* 63 */ { UD_Iarpl,    Ew,     Gw,     NOARG,  Pa32 | Pinv64 },
  48.267 +/* 64 */ { UD_Ifs,      ES,     NOARG,  NOARG,  Pnone },
  48.268 +/* 65 */ { UD_Igs,      GS,     NOARG,  NOARG,  Pnone },
  48.269 +/* 66 */ { UD_Ia32,     NOARG,  NOARG,  NOARG,  Pnone },
  48.270 +/* 67 */ { UD_Io32,     NOARG,  NOARG,  NOARG,  Pnone },
  48.271 +/* 68 */ { UD_Ipush,    Iz,     NOARG,  NOARG,  Pc1 | Po32 },
  48.272 +/* 69 */ { UD_Iimul,    Gv,     Ev,     Iz,     Po32 | Pa32 | REX(_W|_R|_X|_B) },
  48.273 +/* 6A */ { UD_Ipush,    Ib,     NOARG,  NOARG,  Pnone },
  48.274 +/* 6B */ { UD_Iimul,    Gv,     Ev,     Ib,     Po32 | Pa32 | REX(_W|_R|_X|_B) },
  48.275 +/* 6C */ { UD_Iinsb,    NOARG,  NOARG,  NOARG,  Pnone },
  48.276 +/* 6D */ { UD_Iinsw,    NOARG,  NOARG,  NOARG,  Po32 | PdepM },
  48.277 +/* 6E */ { UD_Ioutsb,   NOARG,  NOARG,  NOARG,  Pnone },
  48.278 +/* 6F */ { UD_Ioutsw,   NOARG,  NOARG,  NOARG,  Po32 | PdepM },
  48.279 +/* 70 */ { UD_Ijo,      Jb,     NOARG,  NOARG,  Pnone },
  48.280 +/* 71 */ { UD_Ijno,     Jb,     NOARG,  NOARG,  Pnone },
  48.281 +/* 72 */ { UD_Ijb,      Jb,     NOARG,  NOARG,  Pnone },
  48.282 +/* 73 */ { UD_Ijae,     Jb,     NOARG,  NOARG,  Pnone },
  48.283 +/* 74 */ { UD_Ijz,      Jb,     NOARG,  NOARG,  Pnone },
  48.284 +/* 75 */ { UD_Ijnz,     Jb,     NOARG,  NOARG,  Pnone },
  48.285 +/* 76 */ { UD_Ijbe,     Jb,     NOARG,  NOARG,  Pnone },
  48.286 +/* 77 */ { UD_Ija,      Jb,     NOARG,  NOARG,  Pnone },
  48.287 +/* 78 */ { UD_Ijs,      Jb,     NOARG,  NOARG,  Pnone },
  48.288 +/* 79 */ { UD_Ijns,     Jb,     NOARG,  NOARG,  Pnone },
  48.289 +/* 7A */ { UD_Ijp,      Jb,     NOARG,  NOARG,  Pnone },
  48.290 +/* 7B */ { UD_Ijnp,     Jb,     NOARG,  NOARG,  Pnone },
  48.291 +/* 7C */ { UD_Ijl,      Jb,     NOARG,  NOARG,  Pnone },
  48.292 +/* 7D */ { UD_Ijge,     Jb,     NOARG,  NOARG,  Pnone },
  48.293 +/* 7E */ { UD_Ijle,     Jb,     NOARG,  NOARG,  Pnone },
  48.294 +/* 7F */ { UD_Ijg,      Jb,     NOARG,  NOARG,  Pnone },
  48.295 +/* 80 */ { UD_Igrp,     NOARG,  NOARG,  NOARG,  GRP_80 },
  48.296 +/* 81 */ { UD_Igrp,     NOARG,  NOARG,  NOARG,  GRP_81 },
  48.297 +/* 82 */ { UD_Igrp,     NOARG,  NOARG,  NOARG,  GRP_82 },
  48.298 +/* 83 */ { UD_Igrp,     NOARG,  NOARG,  NOARG,  GRP_83 },
  48.299 +/* 84 */ { UD_Itest,    Eb,     Gb,     NOARG,  Pa32 | REX(_R|_X|_B) },
  48.300 +/* 85 */ { UD_Itest,    Ev,     Gv,     NOARG,  Po32 | Pa32 | REX(_W|_R|_X|_B) },
  48.301 +/* 86 */ { UD_Ixchg,    Eb,     Gb,     NOARG,  Pa32 | REX(_R|_X|_B) },
  48.302 +/* 87 */ { UD_Ixchg,    Ev,     Gv,     NOARG,  Po32 | Pa32 | REX(_W|_R|_X|_B) },
  48.303 +/* 88 */ { UD_Imov,     Eb,     Gb,     NOARG,  Pa32 | REX(_R|_X|_B) },
  48.304 +/* 89 */ { UD_Imov,     Ev,     Gv,     NOARG,  Po32 | Pa32 | REX(_W|_R|_X|_B) },
  48.305 +/* 8A */ { UD_Imov,     Gb,     Eb,     NOARG,  Pa32 | REX(_R|_X|_B) },
  48.306 +/* 8B */ { UD_Imov,     Gv,     Ev,     NOARG,  Po32 | Pa32 | REX(_W|_R|_X|_B) },
  48.307 +/* 8C */ { UD_Imov,     Ev,     S,      NOARG,  Po32 | Pa32 | REX(_R|_X|_B) },
  48.308 +/* 8D */ { UD_Ilea,     Gv,     M,      NOARG,  Po32 | Pa32 | REX(_W|_R|_X|_B) },
  48.309 +/* 8E */ { UD_Imov,     S,      Ev,     NOARG,  Po32 | Pa32 | REX(_R|_X|_B) },
  48.310 +/* 8F */ { UD_Igrp,     NOARG,  NOARG,  NOARG,  GRP_8F },
  48.311 +/* 90 */ { UD_Ixchg,    rAXr8,  rAX,    NOARG,  Po32 | REX(_W|_B) },
  48.312 +/* 91 */ { UD_Ixchg,    rCXr9,  rAX,    NOARG,  Po32 | REX(_W|_B) },
  48.313 +/* 92 */ { UD_Ixchg,    rDXr10, rAX,    NOARG,  Po32 | REX(_W|_B) },
  48.314 +/* 93 */ { UD_Ixchg,    rBXr11, rAX,    NOARG,  Po32 | REX(_W|_B) },
  48.315 +/* 94 */ { UD_Ixchg,    rSPr12, rAX,    NOARG,  Po32 | REX(_W|_B) },
  48.316 +/* 95 */ { UD_Ixchg,    rBPr13, rAX,    NOARG,  Po32 | REX(_W|_B) },
  48.317 +/* 96 */ { UD_Ixchg,    rSIr14, rAX,    NOARG,  Po32 | REX(_W|_B) },
  48.318 +/* 97 */ { UD_Ixchg,    rDIr15, rAX,    NOARG,  Po32 | REX(_W|_B) },
  48.319 +/* 98 */ { UD_Icbw,     NOARG,  NOARG,  NOARG,  Po32 | PdepM | REX(_W) },
  48.320 +/* 99 */ { UD_Icwd,     NOARG,  NOARG,  NOARG,  Po32 | PdepM | REX(_W) },
  48.321 +/* 9A */ { UD_Icall,    Ap,     NOARG,  NOARG,  Pc1 | Po32 | Pinv64 },
  48.322 +/* 9B */ { UD_Iwait,    NOARG,  NOARG,  NOARG,  Pnone },
  48.323 +/* 9C */ { UD_Ipushfw,  NOARG,  NOARG,  NOARG,  Po32 | PdepM | Pdef64 },
  48.324 +/* 9D */ { UD_Ipopfw,   NOARG,  NOARG,  NOARG,  Po32 | PdepM | Pdef64 },
  48.325 +/* 9E */ { UD_Isahf,    NOARG,  NOARG,  NOARG,  Pnone },
  48.326 +/* 9F */ { UD_Ilahf,    NOARG,  NOARG,  NOARG,  Pnone },
  48.327 +/* A0 */ { UD_Imov,     AL,     Ob,     NOARG,  Pnone },
  48.328 +/* A1 */ { UD_Imov,     rAX,    Ov,     NOARG,  Po32 | Pa32 | REX(_W) },
  48.329 +/* A2 */ { UD_Imov,     Ob,     AL,     NOARG,  Pnone },
  48.330 +/* A3 */ { UD_Imov,     Ov,     rAX,    NOARG,  Po32 | Pa32 | REX(_W) },
  48.331 +/* A4 */ { UD_Imovsb,   NOARG,  NOARG,  NOARG,  Pnone },
  48.332 +/* A5 */ { UD_Imovsw,   NOARG,  NOARG,  NOARG,  Po32 | PdepM | REX(_W) },
  48.333 +/* A6 */ { UD_Icmpsb,   NOARG,  NOARG,  NOARG,  Pnone },
  48.334 +/* A7 */ { UD_Icmpsw,   NOARG,  NOARG,  NOARG,  Po32 | PdepM | REX(_W) },
  48.335 +/* A8 */ { UD_Itest,    AL,     Ib,     NOARG,  Pnone },
  48.336 +/* A9 */ { UD_Itest,    rAX,    Iz,     NOARG,  Po32 | REX(_W) },
  48.337 +/* AA */ { UD_Istosb,   NOARG,  NOARG,  NOARG,  Pnone },
  48.338 +/* AB */ { UD_Istosw,   NOARG,  NOARG,  NOARG,  Po32 | PdepM | REX(_W) },
  48.339 +/* AC */ { UD_Ilodsb,   NOARG,  NOARG,  NOARG,  Pnone },
  48.340 +/* AD */ { UD_Ilodsw,   NOARG,  NOARG,  NOARG,  Po32 | PdepM | REX(_W) },
  48.341 +/* AE */ { UD_Iscasb,   NOARG,  NOARG,  NOARG,  Pnone },
  48.342 +/* AF */ { UD_Iscasw,   NOARG,  NOARG,  NOARG,  Po32 | PdepM | REX(_W) },
  48.343 +/* B0 */ { UD_Imov,     ALr8b,  Ib,     NOARG,  REX(_B) },
  48.344 +/* B1 */ { UD_Imov,     CLr9b,  Ib,     NOARG,  REX(_B) },
  48.345 +/* B2 */ { UD_Imov,     DLr10b, Ib,     NOARG,  REX(_B) },
  48.346 +/* B3 */ { UD_Imov,     BLr11b, Ib,     NOARG,  REX(_B) },
  48.347 +/* B4 */ { UD_Imov,     AHr12b, Ib,     NOARG,  REX(_B) },
  48.348 +/* B5 */ { UD_Imov,     CHr13b, Ib,     NOARG,  REX(_B) },
  48.349 +/* B6 */ { UD_Imov,     DHr14b, Ib,     NOARG,  REX(_B) },
  48.350 +/* B7 */ { UD_Imov,     BHr15b, Ib,     NOARG,  REX(_B) },
  48.351 +/* B8 */ { UD_Imov,     rAXr8,  Iv,     NOARG,  Po32 | REX(_W|_B) },
  48.352 +/* B9 */ { UD_Imov,     rCXr9,  Iv,     NOARG,  Po32 | REX(_W|_B) },
  48.353 +/* BA */ { UD_Imov,     rDXr10, Iv,     NOARG,  Po32 | REX(_W|_B) },
  48.354 +/* BB */ { UD_Imov,     rBXr11, Iv,     NOARG,  Po32 | REX(_W|_B) },
  48.355 +/* BC */ { UD_Imov,     rSPr12, Iv,     NOARG,  Po32 | REX(_W|_B) },
  48.356 +/* BD */ { UD_Imov,     rBPr13, Iv,     NOARG,  Po32 | REX(_W|_B) },
  48.357 +/* BE */ { UD_Imov,     rSIr14, Iv,     NOARG,  Po32 | REX(_W|_B) },
  48.358 +/* BF */ { UD_Imov,     rDIr15, Iv,     NOARG,  Po32 | REX(_W|_B) },
  48.359 +/* C0 */ { UD_Igrp,     NOARG,  NOARG,  NOARG,  GRP_C0 },