* xen debugger (kdb/xdb/hdb) patch for c/s 25467
@ 2012-08-29 21:35 Mukesh Rathor
2012-08-29 21:41 ` Mukesh Rathor
2012-08-29 23:18 ` Keir Fraser
0 siblings, 2 replies; 5+ messages in thread
From: Mukesh Rathor @ 2012-08-29 21:35 UTC (permalink / raw)
To: Xen-devel, msw; +Cc: Ben Guthro
Hi Guys,
Thanks for the interest in the xen hypervisor debugger, prev known as
kdb. Btw. I'm gonna rename it to xdb for xen-debugger or hdb for
hypervisor debugger. KDB is confusing people with linux kdb debugger
and I often get emails where people think they need to apply linux kdb
patch also...
Anyways, attaching patch that is cleaned up of my debug code that I
accidentally left in prev posting. Should apply cleanly to c/s 25467.
JFYI... http://xenbits.xen.org/ext/debuggers.hg/ has gotten outdated,
I wasn't sure if anyone was even looking at it. But, it looks like
there is much interest, so I will just submit patch to Keir for
his feedback on merging it in xen.
Please voice your opinion here. Good seeing all at the summit :).
Thanks,
Mukesh
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: xen debugger (kdb/xdb/hdb) patch for c/s 25467
2012-08-29 21:35 xen debugger (kdb/xdb/hdb) patch for c/s 25467 Mukesh Rathor
@ 2012-08-29 21:41 ` Mukesh Rathor
2012-09-05 16:02 ` Ben Guthro
2012-08-29 23:18 ` Keir Fraser
1 sibling, 1 reply; 5+ messages in thread
From: Mukesh Rathor @ 2012-08-29 21:41 UTC (permalink / raw)
To: Xen-devel; +Cc: Ben Guthro, msw
[-- Attachment #1: Type: text/plain, Size: 263 bytes --]
On Wed, 29 Aug 2012 14:35:12 -0700
Mukesh Rathor <mukesh.rathor@oracle.com> wrote:
>
> Anyways, attaching patch that is cleaned up of my debug code that I
> accidentally left in prev posting. Should apply cleanly to c/s 25467.
really attaching this time :).
[-- Attachment #2: kdb.diff --]
[-- Type: text/x-patch, Size: 553166 bytes --]
diff -r 32034d1914a6 xen/Makefile
--- a/xen/Makefile Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/Makefile Wed Aug 29 14:39:57 2012 -0700
@@ -61,6 +61,7 @@
$(MAKE) -f $(BASEDIR)/Rules.mk -C xsm clean
$(MAKE) -f $(BASEDIR)/Rules.mk -C crypto clean
$(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) clean
+ $(MAKE) -f $(BASEDIR)/Rules.mk -C kdb clean
rm -f include/asm *.o $(TARGET) $(TARGET).gz $(TARGET)-syms *~ core
rm -f include/asm-*/asm-offsets.h
[ -d tools/figlet ] && rm -f .banner*
@@ -129,7 +130,7 @@
echo ""; \
echo "#endif") <$< >$@
-SUBDIRS = xsm arch/$(TARGET_ARCH) common drivers
+SUBDIRS = xsm arch/$(TARGET_ARCH) common drivers kdb
define all_sources
( find include/asm-$(TARGET_ARCH) -name '*.h' -print; \
find include -name 'asm-*' -prune -o -name '*.h' -print; \
diff -r 32034d1914a6 xen/Rules.mk
--- a/xen/Rules.mk Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/Rules.mk Wed Aug 29 14:39:57 2012 -0700
@@ -10,6 +10,7 @@
crash_debug ?= n
frame_pointer ?= n
lto ?= n
+kdb ?= n
include $(XEN_ROOT)/Config.mk
@@ -40,6 +41,7 @@
ALL_OBJS-y += $(BASEDIR)/xsm/built_in.o
ALL_OBJS-y += $(BASEDIR)/arch/$(TARGET_ARCH)/built_in.o
ALL_OBJS-$(x86) += $(BASEDIR)/crypto/built_in.o
+ALL_OBJS-$(kdb) += $(BASEDIR)/kdb/built_in.o
CFLAGS-y += -g -D__XEN__ -include $(BASEDIR)/include/xen/config.h
CFLAGS-$(XSM_ENABLE) += -DXSM_ENABLE
@@ -53,6 +55,7 @@
CFLAGS-$(HAS_ACPI) += -DHAS_ACPI
CFLAGS-$(HAS_PASSTHROUGH) += -DHAS_PASSTHROUGH
CFLAGS-$(frame_pointer) += -fno-omit-frame-pointer -DCONFIG_FRAME_POINTER
+CFLAGS-$(kdb) += -DXEN_KDB_CONFIG
ifneq ($(max_phys_cpus),)
CFLAGS-y += -DMAX_PHYS_CPUS=$(max_phys_cpus)
diff -r 32034d1914a6 xen/arch/x86/hvm/svm/entry.S
--- a/xen/arch/x86/hvm/svm/entry.S Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/arch/x86/hvm/svm/entry.S Wed Aug 29 14:39:57 2012 -0700
@@ -59,12 +59,23 @@
get_current(bx)
CLGI
+#ifdef XEN_KDB_CONFIG
+#if defined(__x86_64__)
+ testl $1, kdb_session_begun(%rip)
+#else
+ testl $1, kdb_session_begun
+#endif
+ jnz .Lkdb_skip_softirq
+#endif
mov VCPU_processor(r(bx)),%eax
shl $IRQSTAT_shift,r(ax)
lea addr_of(irq_stat),r(dx)
testl $~0,(r(dx),r(ax),1)
jnz .Lsvm_process_softirqs
+#ifdef XEN_KDB_CONFIG
+.Lkdb_skip_softirq:
+#endif
testb $0, VCPU_nsvm_hap_enabled(r(bx))
UNLIKELY_START(nz, nsvm_hap)
mov VCPU_nhvm_p2m(r(bx)),r(ax)
diff -r 32034d1914a6 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c Wed Aug 29 14:39:57 2012 -0700
@@ -2170,6 +2170,10 @@
break;
case VMEXIT_EXCEPTION_DB:
+#ifdef XEN_KDB_CONFIG
+ if (kdb_handle_trap_entry(TRAP_debug, regs))
+ break;
+#endif
if ( !v->domain->debugger_attached )
goto exit_and_crash;
domain_pause_for_debugger();
@@ -2182,6 +2186,10 @@
if ( (inst_len = __get_instruction_length(v, INSTR_INT3)) == 0 )
break;
__update_guest_eip(regs, inst_len);
+#ifdef XEN_KDB_CONFIG
+ if (kdb_handle_trap_entry(TRAP_int3, regs))
+ break;
+#endif
current->arch.gdbsx_vcpu_event = TRAP_int3;
domain_pause_for_debugger();
break;
diff -r 32034d1914a6 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/arch/x86/hvm/svm/vmcb.c Wed Aug 29 14:39:57 2012 -0700
@@ -315,6 +315,36 @@
register_keyhandler('v', &vmcb_dump_keyhandler);
}
+#if defined(XEN_KDB_CONFIG)
+/* did == 0 : display for all HVM domains. domid 0 is never HVM.
+ * * vid == -1 : display for all HVM VCPUs
+ * */
+void kdb_dump_vmcb(domid_t did, int vid)
+{
+ struct domain *dp;
+ struct vcpu *vp;
+
+ rcu_read_lock(&domlist_read_lock);
+ for_each_domain (dp) {
+ if (!is_hvm_or_hyb_domain(dp) || dp->is_dying)
+ continue;
+ if (did != 0 && did != dp->domain_id)
+ continue;
+
+ for_each_vcpu (dp, vp) {
+ if (vid != -1 && vid != vp->vcpu_id)
+ continue;
+
+ kdbp(" VMCB [domid: %d vcpu:%d]:\n", dp->domain_id, vp->vcpu_id);
+ svm_vmcb_dump("kdb", vp->arch.hvm_svm.vmcb);
+ kdbp("\n");
+ }
+ kdbp("\n");
+ }
+ rcu_read_unlock(&domlist_read_lock);
+}
+#endif
+
/*
* Local variables:
* mode: C
diff -r 32034d1914a6 xen/arch/x86/hvm/vmx/entry.S
--- a/xen/arch/x86/hvm/vmx/entry.S Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/arch/x86/hvm/vmx/entry.S Wed Aug 29 14:39:57 2012 -0700
@@ -124,12 +124,23 @@
get_current(bx)
cli
+#ifdef XEN_KDB_CONFIG
+#if defined(__x86_64__)
+ testl $1, kdb_session_begun(%rip)
+#else
+ testl $1, kdb_session_begun
+#endif
+ jnz .Lkdb_skip_softirq
+#endif
mov VCPU_processor(r(bx)),%eax
shl $IRQSTAT_shift,r(ax)
lea addr_of(irq_stat),r(dx)
cmpl $0,(r(dx),r(ax),1)
jnz .Lvmx_process_softirqs
+#ifdef XEN_KDB_CONFIG
+.Lkdb_skip_softirq:
+#endif
testb $0xff,VCPU_vmx_emulate(r(bx))
jnz .Lvmx_goto_emulator
testb $0xff,VCPU_vmx_realmode(r(bx))
diff -r 32034d1914a6 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c Wed Aug 29 14:39:57 2012 -0700
@@ -1117,6 +1117,13 @@
hvm_asid_flush_vcpu(v);
}
+#if defined(XEN_KDB_CONFIG)
+ if (kdb_dr7)
+ __vmwrite(GUEST_DR7, kdb_dr7);
+ else
+ __vmwrite(GUEST_DR7, 0);
+#endif
+
debug_state = v->domain->debugger_attached
|| v->domain->arch.hvm_domain.params[HVM_PARAM_MEMORY_EVENT_INT3]
|| v->domain->arch.hvm_domain.params[HVM_PARAM_MEMORY_EVENT_SINGLE_STEP];
@@ -1326,6 +1333,220 @@
register_keyhandler('v', &vmcs_dump_keyhandler);
}
+#if defined(XEN_KDB_CONFIG)
+#define GUEST_EFER 0x2806 /* see page 23-20 */
+#define GUEST_EFER_HIGH 0x2807 /* see page 23-20 */
+
+/* it's a shame we can't use vmcs_dump_vcpu(), but it does vmx_vmcs_enter which
+ * will IPI other CPUs. also, print a subset relevant to software debugging */
+static void noinline kdb_print_vmcs(struct vcpu *vp)
+{
+ struct cpu_user_regs *regs = &vp->arch.user_regs;
+ unsigned long long x;
+
+ kdbp("*** Guest State ***\n");
+ kdbp("CR0: actual=0x%016llx, shadow=0x%016llx, gh_mask=%016llx\n",
+ (unsigned long long)vmr(GUEST_CR0),
+ (unsigned long long)vmr(CR0_READ_SHADOW),
+ (unsigned long long)vmr(CR0_GUEST_HOST_MASK));
+ kdbp("CR4: actual=0x%016llx, shadow=0x%016llx, gh_mask=%016llx\n",
+ (unsigned long long)vmr(GUEST_CR4),
+ (unsigned long long)vmr(CR4_READ_SHADOW),
+ (unsigned long long)vmr(CR4_GUEST_HOST_MASK));
+ kdbp("CR3: actual=0x%016llx, target_count=%d\n",
+ (unsigned long long)vmr(GUEST_CR3),
+ (int)vmr(CR3_TARGET_COUNT));
+ kdbp(" target0=%016llx, target1=%016llx\n",
+ (unsigned long long)vmr(CR3_TARGET_VALUE0),
+ (unsigned long long)vmr(CR3_TARGET_VALUE1));
+ kdbp(" target2=%016llx, target3=%016llx\n",
+ (unsigned long long)vmr(CR3_TARGET_VALUE2),
+ (unsigned long long)vmr(CR3_TARGET_VALUE3));
+ kdbp("RSP = 0x%016llx (0x%016llx) RIP = 0x%016llx (0x%016llx)\n",
+ (unsigned long long)vmr(GUEST_RSP),
+ (unsigned long long)regs->esp,
+ (unsigned long long)vmr(GUEST_RIP),
+ (unsigned long long)regs->eip);
+ kdbp("RFLAGS=0x%016llx (0x%016llx) DR7 = 0x%016llx\n",
+ (unsigned long long)vmr(GUEST_RFLAGS),
+ (unsigned long long)regs->eflags,
+ (unsigned long long)vmr(GUEST_DR7));
+ kdbp("Sysenter RSP=%016llx CS:RIP=%04x:%016llx\n",
+ (unsigned long long)vmr(GUEST_SYSENTER_ESP),
+ (int)vmr(GUEST_SYSENTER_CS),
+ (unsigned long long)vmr(GUEST_SYSENTER_EIP));
+ vmx_dump_sel("CS", GUEST_CS_SELECTOR);
+ vmx_dump_sel("DS", GUEST_DS_SELECTOR);
+ vmx_dump_sel("SS", GUEST_SS_SELECTOR);
+ vmx_dump_sel("ES", GUEST_ES_SELECTOR);
+ vmx_dump_sel("FS", GUEST_FS_SELECTOR);
+ vmx_dump_sel("GS", GUEST_GS_SELECTOR);
+ vmx_dump_sel2("GDTR", GUEST_GDTR_LIMIT);
+ vmx_dump_sel("LDTR", GUEST_LDTR_SELECTOR);
+ vmx_dump_sel2("IDTR", GUEST_IDTR_LIMIT);
+ vmx_dump_sel("TR", GUEST_TR_SELECTOR);
+ kdbp("Guest EFER = 0x%08x%08x\n",
+ (uint32_t)vmr(GUEST_EFER_HIGH), (uint32_t)vmr(GUEST_EFER));
+ kdbp("Guest PAT = 0x%08x%08x\n",
+ (uint32_t)vmr(GUEST_PAT_HIGH), (uint32_t)vmr(GUEST_PAT));
+ x = (unsigned long long)vmr(TSC_OFFSET_HIGH) << 32;
+ x |= (uint32_t)vmr(TSC_OFFSET);
+ kdbp("TSC Offset = %016llx\n", x);
+ x = (unsigned long long)vmr(GUEST_IA32_DEBUGCTL_HIGH) << 32;
+ x |= (uint32_t)vmr(GUEST_IA32_DEBUGCTL);
+ kdbp("DebugCtl=%016llx DebugExceptions=%016llx\n", x,
+ (unsigned long long)vmr(GUEST_PENDING_DBG_EXCEPTIONS));
+ kdbp("Interruptibility=%04x ActivityState=%04x\n",
+ (int)vmr(GUEST_INTERRUPTIBILITY_INFO),
+ (int)vmr(GUEST_ACTIVITY_STATE));
+
+ kdbp("MSRs: entry_load:$%d exit_load:$%d exit_store:$%d\n",
+ vmr(VM_ENTRY_MSR_LOAD_COUNT), vmr(VM_EXIT_MSR_LOAD_COUNT),
+ vmr(VM_EXIT_MSR_STORE_COUNT));
+
+ kdbp("\n*** Host State ***\n");
+ kdbp("RSP = 0x%016llx RIP = 0x%016llx\n",
+ (unsigned long long)vmr(HOST_RSP),
+ (unsigned long long)vmr(HOST_RIP));
+ kdbp("CS=%04x DS=%04x ES=%04x FS=%04x GS=%04x SS=%04x TR=%04x\n",
+ (uint16_t)vmr(HOST_CS_SELECTOR),
+ (uint16_t)vmr(HOST_DS_SELECTOR),
+ (uint16_t)vmr(HOST_ES_SELECTOR),
+ (uint16_t)vmr(HOST_FS_SELECTOR),
+ (uint16_t)vmr(HOST_GS_SELECTOR),
+ (uint16_t)vmr(HOST_SS_SELECTOR),
+ (uint16_t)vmr(HOST_TR_SELECTOR));
+ kdbp("FSBase=%016llx GSBase=%016llx TRBase=%016llx\n",
+ (unsigned long long)vmr(HOST_FS_BASE),
+ (unsigned long long)vmr(HOST_GS_BASE),
+ (unsigned long long)vmr(HOST_TR_BASE));
+ kdbp("GDTBase=%016llx IDTBase=%016llx\n",
+ (unsigned long long)vmr(HOST_GDTR_BASE),
+ (unsigned long long)vmr(HOST_IDTR_BASE));
+ kdbp("CR0=%016llx CR3=%016llx CR4=%016llx\n",
+ (unsigned long long)vmr(HOST_CR0),
+ (unsigned long long)vmr(HOST_CR3),
+ (unsigned long long)vmr(HOST_CR4));
+ kdbp("Sysenter RSP=%016llx CS:RIP=%04x:%016llx\n",
+ (unsigned long long)vmr(HOST_SYSENTER_ESP),
+ (int)vmr(HOST_SYSENTER_CS),
+ (unsigned long long)vmr(HOST_SYSENTER_EIP));
+ kdbp("Host PAT = 0x%08x%08x\n",
+ (uint32_t)vmr(HOST_PAT_HIGH), (uint32_t)vmr(HOST_PAT));
+
+ kdbp("\n*** Control State ***\n");
+ kdbp("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n",
+ (uint32_t)vmr(PIN_BASED_VM_EXEC_CONTROL),
+ (uint32_t)vmr(CPU_BASED_VM_EXEC_CONTROL),
+ (uint32_t)vmr(SECONDARY_VM_EXEC_CONTROL));
+ kdbp("EntryControls=%08x ExitControls=%08x\n",
+ (uint32_t)vmr(VM_ENTRY_CONTROLS),
+ (uint32_t)vmr(VM_EXIT_CONTROLS));
+ kdbp("ExceptionBitmap=%08x\n",
+ (uint32_t)vmr(EXCEPTION_BITMAP));
+ kdbp("PAGE_FAULT_ERROR_CODE MASK:0x%lx MATCH:0x%lx\n",
+ (unsigned long)vmr(PAGE_FAULT_ERROR_CODE_MASK),
+ (unsigned long)vmr(PAGE_FAULT_ERROR_CODE_MATCH));
+ kdbp("VMEntry: intr_info=%08x errcode=%08x ilen=%08x\n",
+ (uint32_t)vmr(VM_ENTRY_INTR_INFO),
+ (uint32_t)vmr(VM_ENTRY_EXCEPTION_ERROR_CODE),
+ (uint32_t)vmr(VM_ENTRY_INSTRUCTION_LEN));
+ kdbp("VMExit: intr_info=%08x errcode=%08x ilen=%08x\n",
+ (uint32_t)vmr(VM_EXIT_INTR_INFO),
+ (uint32_t)vmr(VM_EXIT_INTR_ERROR_CODE),
+ (uint32_t)vmr(VM_ENTRY_INSTRUCTION_LEN));
+ kdbp(" reason=%08x qualification=%08x\n",
+ (uint32_t)vmr(VM_EXIT_REASON),
+ (uint32_t)vmr(EXIT_QUALIFICATION));
+ kdbp("IDTVectoring: info=%08x errcode=%08x\n",
+ (uint32_t)vmr(IDT_VECTORING_INFO),
+ (uint32_t)vmr(IDT_VECTORING_ERROR_CODE));
+ kdbp("TPR Threshold = 0x%02x\n",
+ (uint32_t)vmr(TPR_THRESHOLD));
+ kdbp("EPT pointer = 0x%08x%08x\n",
+ (uint32_t)vmr(EPT_POINTER_HIGH), (uint32_t)vmr(EPT_POINTER));
+ kdbp("Virtual processor ID = 0x%04x\n",
+ (uint32_t)vmr(VIRTUAL_PROCESSOR_ID));
+ kdbp("=================================================================\n");
+}
+
+/* Flush VMCS on this cpu if it needs to:
+ * - Upon leaving kdb, the HVM cpu will resume in vmx_vmexit_handler() and
+ * do __vmreads. So, the VMCS pointer can't be left cleared.
+ * - Doing __vmpclear will set the vmx state to 'clear', so to resume a
+ * vmlaunch must be done and not vmresume. This means, we must clear
+ * arch_vmx->launched.
+ */
+void kdb_curr_cpu_flush_vmcs(void)
+{
+ struct domain *dp;
+ struct vcpu *vp;
+ int ccpu = smp_processor_id();
+ struct vmcs_struct *cvp = this_cpu(current_vmcs);
+
+ if (this_cpu(current_vmcs) == NULL)
+ return; /* no HVM active on this CPU */
+
+ kdbp("KDB:[%d] curvmcs:%lx/%lx\n", ccpu, cvp, virt_to_maddr(cvp));
+
+ /* looks like we got one. unfortunately, current_vmcs points to vmcs
+ * and not VCPU, so we gotta search the entire list... */
+ for_each_domain (dp) {
+ if ( !(is_hvm_or_hyb_domain(dp)) || dp->is_dying)
+ continue;
+ for_each_vcpu (dp, vp) {
+ if ( vp->arch.hvm_vmx.vmcs == cvp ) {
+ __vmpclear(virt_to_maddr(vp->arch.hvm_vmx.vmcs));
+ __vmptrld(virt_to_maddr(vp->arch.hvm_vmx.vmcs));
+ vp->arch.hvm_vmx.launched = 0;
+ this_cpu(current_vmcs) = NULL;
+ kdbp("KDB:[%d] %d:%d current_vmcs:%lx flushed\n",
+ ccpu, dp->domain_id, vp->vcpu_id, cvp, virt_to_maddr(cvp));
+ }
+ }
+ }
+}
+
+/*
+ * domid == 0 : display for all HVM domains (dom0 is never an HVM domain)
+ * vcpu id == -1 : display all vcpuids
+ * PreCondition: all HVM cpus (including current cpu) have flushed VMCS
+ */
+void kdb_dump_vmcs(domid_t did, int vid)
+{
+ struct domain *dp;
+ struct vcpu *vp;
+ struct vmcs_struct *vmcsp;
+ u64 addr = -1;
+
+ ASSERT(!local_irq_is_enabled()); /* kdb should always run disabled */
+ __vmptrst(&addr);
+
+ for_each_domain (dp) {
+ if ( !(is_hvm_or_hyb_domain(dp)) || dp->is_dying)
+ continue;
+ if (did != 0 && did != dp->domain_id)
+ continue;
+
+ for_each_vcpu (dp, vp) {
+ if (vid != -1 && vid != vp->vcpu_id)
+ continue;
+
+ vmcsp = vp->arch.hvm_vmx.vmcs;
+ kdbp("VMCS %lx/%lx [domid:%d (%p) vcpu:%d (%p)]:\n", vmcsp,
+ virt_to_maddr(vmcsp), dp->domain_id, dp, vp->vcpu_id, vp);
+ __vmptrld(virt_to_maddr(vmcsp));
+ kdb_print_vmcs(vp);
+ __vmpclear(virt_to_maddr(vmcsp));
+ vp->arch.hvm_vmx.launched = 0;
+ }
+ kdbp("\n");
+ }
+ /* restore orig vmcs pointer for __vmreads in vmx_vmexit_handler() */
+ if (addr && addr != (u64)-1)
+ __vmptrld(addr);
+}
+#endif
/*
* Local variables:
diff -r 32034d1914a6 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Aug 29 14:39:57 2012 -0700
@@ -2183,11 +2183,14 @@
printk("reason not known yet!");
break;
}
-
+#if defined(XEN_KDB_CONFIG)
+ kdbp("\n************* VMCS Area **************\n");
+ kdb_dump_vmcs(curr->domain->domain_id, (curr)->vcpu_id);
+#else
printk("************* VMCS Area **************\n");
vmcs_dump_vcpu(curr);
printk("**************************************\n");
-
+#endif
domain_crash(curr->domain);
}
@@ -2415,6 +2418,12 @@
write_debugreg(6, exit_qualification | 0xffff0ff0);
if ( !v->domain->debugger_attached || cpu_has_monitor_trap_flag )
goto exit_and_crash;
+
+#if defined(XEN_KDB_CONFIG)
+ /* TRAP_debug: IP points correctly to next instr */
+ if (kdb_handle_trap_entry(vector, regs))
+ break;
+#endif
domain_pause_for_debugger();
break;
case TRAP_int3:
@@ -2423,6 +2432,13 @@
if ( v->domain->debugger_attached )
{
update_guest_eip(); /* Safe: INT3 */
+#if defined(XEN_KDB_CONFIG)
+ /* vmcs.IP points to bp, kdb expects bp+1. Hence after the above
+ * update_guest_eip which updates to bp+1. works for gdbsx too
+ */
+ if (kdb_handle_trap_entry(vector, regs))
+ break;
+#endif
current->arch.gdbsx_vcpu_event = TRAP_int3;
domain_pause_for_debugger();
break;
@@ -2707,6 +2723,10 @@
case EXIT_REASON_MONITOR_TRAP_FLAG:
v->arch.hvm_vmx.exec_control &= ~CPU_BASED_MONITOR_TRAP_FLAG;
vmx_update_cpu_exec_control(v);
+#if defined(XEN_KDB_CONFIG)
+ if (kdb_handle_trap_entry(TRAP_debug, regs))
+ break;
+#endif
if ( v->arch.hvm_vcpu.single_step ) {
hvm_memory_event_single_step(regs->eip);
if ( v->domain->debugger_attached )
diff -r 32034d1914a6 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/arch/x86/irq.c Wed Aug 29 14:39:57 2012 -0700
@@ -2305,3 +2305,29 @@
return is_hvm_domain(d) && pirq &&
pirq->arch.hvm.emuirq != IRQ_UNBOUND;
}
+
+#ifdef XEN_KDB_CONFIG
+void kdb_prnt_guest_mapped_irqs(void)
+{
+ int irq, j;
+ char affstr[NR_CPUS/4+NR_CPUS/32+2]; /* courtesy dump_irqs() */
+
+ kdbp("irq vec aff type domid:mapped-pirq pairs (all in decimal)\n");
+ for (irq=0; irq < nr_irqs; irq++) {
+ irq_desc_t *dp = irq_to_desc(irq);
+ struct arch_irq_desc *archp = &dp->arch;
+ irq_guest_action_t *actp = (irq_guest_action_t *)dp->action;
+
+ if (!dp->handler ||dp->handler==&no_irq_type || !(dp->status&IRQ_GUEST))
+ continue;
+
+ cpumask_scnprintf(affstr, sizeof(affstr), dp->affinity);
+ kdbp("[%3ld] %3d %3s %-13s ", irq, archp->vector, affstr,
+ dp->handler->typename);
+ for (j=0; j < actp->nr_guests; j++)
+ kdbp("%03d:%04d ", actp->guest[j]->domain_id,
+ domain_irq_to_pirq(actp->guest[j], irq));
+ kdbp("\n");
+ }
+}
+#endif
diff -r 32034d1914a6 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/arch/x86/setup.c Wed Aug 29 14:39:57 2012 -0700
@@ -47,6 +47,13 @@
#include <xen/cpu.h>
#include <asm/nmi.h>
+#ifdef XEN_KDB_CONFIG
+#include <asm/debugger.h>
+
+int opt_earlykdb=0;
+boolean_param("earlykdb", opt_earlykdb);
+#endif
+
/* opt_nosmp: If true, secondary processors are ignored. */
static bool_t __initdata opt_nosmp;
boolean_param("nosmp", opt_nosmp);
@@ -1242,6 +1249,11 @@
trap_init();
+#ifdef XEN_KDB_CONFIG
+ kdb_init();
+ if (opt_earlykdb)
+ kdb_trap_immed(KDB_TRAP_NONFATAL);
+#endif
rcu_init();
early_time_init();
diff -r 32034d1914a6 xen/arch/x86/smp.c
--- a/xen/arch/x86/smp.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/arch/x86/smp.c Wed Aug 29 14:39:57 2012 -0700
@@ -273,7 +273,7 @@
* Structure and data for smp_call_function()/on_selected_cpus().
*/
-static void __smp_call_function_interrupt(void);
+static void __smp_call_function_interrupt(struct cpu_user_regs *regs);
static DEFINE_SPINLOCK(call_lock);
static struct call_data_struct {
void (*func) (void *info);
@@ -321,7 +321,7 @@
if ( cpumask_test_cpu(smp_processor_id(), &call_data.selected) )
{
local_irq_disable();
- __smp_call_function_interrupt();
+ __smp_call_function_interrupt(NULL);
local_irq_enable();
}
@@ -390,7 +390,7 @@
this_cpu(irq_count)++;
}
-static void __smp_call_function_interrupt(void)
+static void __smp_call_function_interrupt(struct cpu_user_regs *regs)
{
void (*func)(void *info) = call_data.func;
void *info = call_data.info;
@@ -411,6 +411,11 @@
{
mb();
cpumask_clear_cpu(cpu, &call_data.selected);
+#ifdef XEN_KDB_CONFIG
+ if (info && !strcmp(info, "XENKDB")) { /* called from kdb */
+ (*(void (*)(struct cpu_user_regs *, void *))func)(regs, info);
+ } else
+#endif
(*func)(info);
}
@@ -421,5 +426,5 @@
{
ack_APIC_irq();
perfc_incr(ipis);
- __smp_call_function_interrupt();
+ __smp_call_function_interrupt(regs);
}
diff -r 32034d1914a6 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/arch/x86/time.c Wed Aug 29 14:39:57 2012 -0700
@@ -2007,6 +2007,46 @@
}
__initcall(setup_dump_softtsc);
+#ifdef XEN_KDB_CONFIG
+void kdb_time_resume(int update_domains)
+{
+ s_time_t now;
+ int ccpu = smp_processor_id();
+ struct cpu_time *t = &this_cpu(cpu_time);
+
+ if (!plt_src.read_counter) /* not initialized for earlykdb */
+ return;
+
+ if (update_domains) {
+ plt_stamp = plt_src.read_counter();
+ platform_timer_stamp = plt_stamp64;
+ platform_time_calibration();
+ do_settime(get_cmos_time(), 0, read_platform_stime());
+ }
+ if (local_irq_is_enabled())
+ kdbp("kdb BUG: enabled in time_resume(). ccpu:%d\n", ccpu);
+
+ rdtscll(t->local_tsc_stamp);
+ now = read_platform_stime();
+ t->stime_master_stamp = now;
+ t->stime_local_stamp = now;
+
+ update_vcpu_system_time(current);
+
+ if (update_domains)
+ set_timer(&calibration_timer, NOW() + EPOCH);
+}
+
+void kdb_dump_time_pcpu(void)
+{
+ int cpu;
+ for_each_online_cpu(cpu) {
+ kdbp("[%d]: cpu_time: %016lx\n", cpu, &per_cpu(cpu_time, cpu));
+ kdbp("[%d]: cpu_calibration: %016lx\n", cpu,
+ &per_cpu(cpu_calibration, cpu));
+ }
+}
+#endif
/*
* Local variables:
* mode: C
diff -r 32034d1914a6 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/arch/x86/traps.c Wed Aug 29 14:39:57 2012 -0700
@@ -225,7 +225,7 @@
#else
-static void show_trace(struct cpu_user_regs *regs)
+void show_trace(struct cpu_user_regs *regs)
{
unsigned long *frame, next, addr, low, high;
@@ -3326,6 +3326,10 @@
if ( nmi_callback(regs, cpu) )
return;
+#ifdef XEN_KDB_CONFIG
+ if (kdb_enabled && kdb_handle_trap_entry(TRAP_nmi, regs))
+ return;
+#endif
if ( nmi_watchdog )
nmi_watchdog_tick(regs);
diff -r 32034d1914a6 xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/arch/x86/x86_64/compat/entry.S Wed Aug 29 14:39:57 2012 -0700
@@ -95,6 +95,10 @@
/* %rbx: struct vcpu */
ENTRY(compat_test_all_events)
cli # tests must not race interrupts
+#ifdef XEN_KDB_CONFIG
+ testl $1, kdb_session_begun(%rip)
+ jnz compat_restore_all_guest
+#endif
/*compat_test_softirqs:*/
movl VCPU_processor(%rbx),%eax
shlq $IRQSTAT_shift,%rax
diff -r 32034d1914a6 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/arch/x86/x86_64/entry.S Wed Aug 29 14:39:57 2012 -0700
@@ -184,6 +184,10 @@
/* %rbx: struct vcpu */
test_all_events:
cli # tests must not race interrupts
+#ifdef XEN_KDB_CONFIG /* 64bit dom0 will resume here */
+ testl $1, kdb_session_begun(%rip)
+ jnz restore_all_guest
+#endif
/*test_softirqs:*/
movl VCPU_processor(%rbx),%eax
shl $IRQSTAT_shift,%rax
@@ -546,6 +550,13 @@
ENTRY(int3)
pushq $0
+#ifdef XEN_KDB_CONFIG
+ pushq %rax
+ GET_CPUINFO_FIELD(CPUINFO_processor_id, %rax)
+ movq (%rax), %rax
+ lock bts %rax, kdb_cpu_traps(%rip)
+ popq %rax
+#endif
movl $TRAP_int3,4(%rsp)
jmp handle_exception
diff -r 32034d1914a6 xen/common/domain.c
--- a/xen/common/domain.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/common/domain.c Wed Aug 29 14:39:57 2012 -0700
@@ -530,6 +530,14 @@
{
struct vcpu *v;
+#ifdef XEN_KDB_CONFIG
+ if (reason == SHUTDOWN_crash) {
+ if ( IS_PRIV(d) )
+ kdb_trap_immed(KDB_TRAP_FATAL);
+ else
+ kdb_trap_immed(KDB_TRAP_NONFATAL);
+ }
+#endif
spin_lock(&d->shutdown_lock);
if ( d->shutdown_code == -1 )
@@ -624,7 +632,9 @@
for_each_vcpu ( d, v )
vcpu_sleep_nosync(v);
- send_global_virq(VIRQ_DEBUGGER);
+ /* send VIRQ_DEBUGGER to guest only if gdbsx_vcpu_event is not active */
+ if (current->arch.gdbsx_vcpu_event == 0)
+ send_global_virq(VIRQ_DEBUGGER);
}
/* Complete domain destroy after RCU readers are not holding old references. */
diff -r 32034d1914a6 xen/common/sched_credit.c
--- a/xen/common/sched_credit.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/common/sched_credit.c Wed Aug 29 14:39:57 2012 -0700
@@ -1475,6 +1475,33 @@
printk("\n");
}
+#ifdef XEN_KDB_CONFIG
+static void kdb_csched_dump(int cpu)
+{
+ struct csched_pcpu *pcpup = CSCHED_PCPU(cpu);
+ struct vcpu *scurrvp = (CSCHED_VCPU(current))->vcpu;
+ struct list_head *tmp, *runq = RUNQ(cpu);
+
+ kdbp(" csched_pcpu: %p\n", pcpup);
+ kdbp(" curr csched:%p {vcpu:%p id:%d domid:%d}\n", (current)->sched_priv,
+ scurrvp, scurrvp->vcpu_id, scurrvp->domain->domain_id);
+ kdbp(" runq:\n");
+
+ /* next is top of struct, so screw stupid, ugly hard to follow macros */
+ if (offsetof(struct csched_vcpu, runq_elem.next) != 0) {
+ kdbp("next is not first in struct csched_vcpu. please fixme\n");
+ return; /* otherwise for loop will crash */
+ }
+ for (tmp = runq->next; tmp != runq; tmp = tmp->next) {
+
+ struct csched_vcpu *csp = (struct csched_vcpu *)tmp;
+ struct vcpu *vp = csp->vcpu;
+ kdbp(" csp:%p pri:%02d vcpu: {p:%p id:%d domid:%d}\n", csp,
+ csp->pri, vp, vp->vcpu_id, vp->domain->domain_id);
+ };
+}
+#endif
+
static void
csched_dump_pcpu(const struct scheduler *ops, int cpu)
{
@@ -1484,6 +1511,10 @@
int loop;
#define cpustr keyhandler_scratch
+#ifdef XEN_KDB_CONFIG
+ kdb_csched_dump(cpu);
+ return;
+#endif
spc = CSCHED_PCPU(cpu);
runq = &spc->runq;
diff -r 32034d1914a6 xen/common/schedule.c
--- a/xen/common/schedule.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/common/schedule.c Wed Aug 29 14:39:57 2012 -0700
@@ -1454,6 +1454,25 @@
schedule();
}
+#ifdef XEN_KDB_CONFIG
+void kdb_print_sched_info(void)
+{
+ int cpu;
+
+ kdbp("Scheduler: name:%s opt_name:%s id:%d\n", ops.name, ops.opt_name,
+ ops.sched_id);
+ kdbp("per cpu schedule_data:\n");
+ for_each_online_cpu(cpu) {
+ struct schedule_data *p = &per_cpu(schedule_data, cpu);
+ kdbp(" cpu:%d &(per cpu)schedule_data:%p\n", cpu, p);
+ kdbp(" curr:%p sched_priv:%p\n", p->curr, p->sched_priv);
+ kdbp("\n");
+ ops.dump_cpu_state(&ops, cpu);
+ kdbp("\n");
+ }
+}
+#endif
+
#ifdef CONFIG_COMPAT
#include "compat/schedule.c"
#endif
diff -r 32034d1914a6 xen/common/symbols.c
--- a/xen/common/symbols.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/common/symbols.c Wed Aug 29 14:39:57 2012 -0700
@@ -168,3 +168,21 @@
spin_unlock_irqrestore(&lock, flags);
}
+
+#ifdef XEN_KDB_CONFIG
+/*
+ * * Given a symbol, return its address
+ * */
+unsigned long address_lookup(char *symp)
+{
+ int i, off = 0;
+ char namebuf[KSYM_NAME_LEN+1];
+
+ for (i=0; i < symbols_num_syms; i++) {
+ off = symbols_expand_symbol(off, namebuf);
+ if (strcmp(namebuf, symp) == 0) /* found it */
+ return symbols_address(i);
+ }
+ return 0;
+}
+#endif
diff -r 32034d1914a6 xen/common/timer.c
--- a/xen/common/timer.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/common/timer.c Wed Aug 29 14:39:57 2012 -0700
@@ -643,6 +643,48 @@
register_keyhandler('a', &dump_timerq_keyhandler);
}
+#ifdef XEN_KDB_CONFIG
+#include <xen/symbols.h>
+void kdb_dump_timer_queues(void)
+{
+ struct timer *t;
+ struct timers *ts;
+ unsigned long sz, offs;
+ char buf[KSYM_NAME_LEN+1];
+ int cpu, j;
+ u64 tsc;
+
+ for_each_online_cpu( cpu )
+ {
+ ts = &per_cpu(timers, cpu);
+ kdbp("CPU[%02d]:", cpu);
+
+ if (cpu == smp_processor_id()) {
+ s_time_t now = NOW();
+ rdtscll(tsc);
+ kdbp("NOW:0x%08x%08x TSC:0x%016lx\n", (u32)(now>>32),(u32)now, tsc);
+ } else
+ kdbp("\n");
+
+ /* timers in the heap */
+ for ( j = 1; j <= GET_HEAP_SIZE(ts->heap); j++ ) {
+ t = ts->heap[j];
+ kdbp(" %d: exp=0x%08x%08x fn:%s data:%p\n",
+ j, (u32)(t->expires>>32), (u32)t->expires,
+ symbols_lookup((unsigned long)t->function, &sz, &offs, buf),
+ t->data);
+ }
+ /* timers on the link list */
+ for ( t = ts->list, j = 0; t != NULL; t = t->list_next, j++ ) {
+ kdbp(" L%d: exp=0x%08x%08x fn:%s data:%p\n",
+ j, (u32)(t->expires>>32), (u32)t->expires,
+ symbols_lookup((unsigned long)t->function, &sz, &offs, buf),
+ t->data);
+ }
+ }
+}
+#endif
+
/*
* Local variables:
* mode: C
diff -r 32034d1914a6 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/drivers/char/console.c Wed Aug 29 14:39:57 2012 -0700
@@ -295,6 +295,21 @@
{
static int switch_code_count = 0;
+#ifdef XEN_KDB_CONFIG
+ /* if ctrl-\ pressed and kdb handles it, return */
+ if (kdb_enabled && c == 0x1c) {
+ if (!kdb_session_begun) {
+ if (kdb_keyboard(regs))
+ return;
+ } else {
+ kdbp("Sorry... kdb session already active.. please try again..\n");
+ return;
+ }
+ }
+ if (kdb_session_begun) /* kdb should already be polling */
+ return; /* swallow chars so they don't buffer in dom0 */
+#endif
+
if ( switch_code && (c == switch_code) )
{
/* We eat CTRL-<switch_char> in groups of 3 to switch console input. */
@@ -710,6 +725,18 @@
atomic_dec(&print_everything);
}
+#ifdef XEN_KDB_CONFIG
+void console_putc(char c)
+{
+ serial_putc(sercon_handle, c);
+}
+
+int console_getc(void)
+{
+ return serial_getc(sercon_handle);
+}
+#endif
+
/*
* printk rate limiting, lifted from Linux.
*
diff -r 32034d1914a6 xen/include/asm-x86/debugger.h
--- a/xen/include/asm-x86/debugger.h Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/include/asm-x86/debugger.h Wed Aug 29 14:39:57 2012 -0700
@@ -39,7 +39,11 @@
#define DEBUGGER_trap_fatal(_v, _r) \
if ( debugger_trap_fatal(_v, _r) ) return;
-#if defined(CRASH_DEBUG)
+#if defined(XEN_KDB_CONFIG)
+#define debugger_trap_immediate() kdb_trap_immed(KDB_TRAP_NONFATAL)
+#define debugger_trap_fatal(_v, _r) kdb_trap_fatal(_v, _r)
+
+#elif defined(CRASH_DEBUG)
#include <xen/gdbstub.h>
@@ -70,6 +74,10 @@
{
struct vcpu *v = current;
+#ifdef XEN_KDB_CONFIG
+ if (kdb_handle_trap_entry(vector, regs))
+ return 1;
+#endif
if ( guest_kernel_mode(v, regs) && v->domain->debugger_attached &&
((vector == TRAP_int3) || (vector == TRAP_debug)) )
{
diff -r 32034d1914a6 xen/include/xen/lib.h
--- a/xen/include/xen/lib.h Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/include/xen/lib.h Wed Aug 29 14:39:57 2012 -0700
@@ -116,4 +116,7 @@
struct cpu_user_regs;
void dump_execstate(struct cpu_user_regs *);
+#ifdef XEN_KDB_CONFIG
+#include "../../kdb/include/kdb_extern.h"
+#endif
#endif /* __LIB_H__ */
diff -r 32034d1914a6 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Thu Jun 07 19:46:57 2012 +0100
+++ b/xen/include/xen/sched.h Wed Aug 29 14:39:57 2012 -0700
@@ -576,11 +576,14 @@
unsigned long hypercall_create_continuation(
unsigned int op, const char *format, ...);
void hypercall_cancel_continuation(void);
-
+#ifdef XEN_KDB_CONFIG
+#define hypercall_preempt_check() (0)
+#else
#define hypercall_preempt_check() (unlikely( \
softirq_pending(smp_processor_id()) | \
local_events_need_delivery() \
))
+#endif
extern struct domain *domain_list;
diff -r 32034d1914a6 xen/kdb/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/Makefile Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,5 @@
+
+obj-y += kdbmain.o kdb_cmds.o kdb_io.o
+
+subdir-y += x86 guest
+
diff -r 32034d1914a6 xen/kdb/README
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/README Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,243 @@
+
+Welcome to kdb for xen, a hypervisor built in debugger.
+
+FEATURES:
+ - set breakpoints in hypervisor
+ - examine virt/machine memory, registers, domains, vcpus, etc...
+ - single step, single step till jump/call, step over call to next
+ instruction after the call.
+ - examine memory of a PV/HVM guest.
+ - set breakpoints, single step, etc... for a PV guest.
+ - breaking into the debugger will freeze the system, all CPUs will pause,
+ no interrupts are acknowledged in the debugger. (Hence, the wall clock
+ will drift)
+ - single step will step only that cpu.
+ - earlykdb: break into kdb very early during boot. Put "earlykdb" on the
+ xen command line in grub.conf.
+ - generic tracing functions (see below) for quick tracing to debug timing
+ related problems. To use:
+ o set KDBTRCMAX to max num of recs in circular trc buffer in kdbmain.c
+ o call kdb_trc() from anywhere in xen
+ o turn tracing on by setting kdb_trcon in kdbmain.c or trcon command.
+ o trcp in kdb will give hints to dump trace recs. Use dd to see buffer
+ o trcz will zero out the entire buffer if needed.
+
+NOTE:
+ - since almost all numbers are in hex, 0x is not prefixed. Instead, decimal
+ numbers are preceded by $, as in $17 (sorry, one gets used to it). Note,
+ vcpu num, cpu num, domid are always displayed in decimal, without $.
+ - watchdog must be disabled to use kdb
+
+ISSUES:
+ - Currently, debug hypervisor is not supported. Make sure NDEBUG is defined
+ or compile with debug=n
+ - "timer went backwards" messages on dom0, but kdb/hyp should be fine.
+ I usually do "echo 2 > /proc/sys/kernel/printk" when using kdb.
+ - 32bit hypervisor may hang. Tested on 64bit hypervisor only.
+
+
+TO BUILD:
+ - do >make kdb=y
+
+HOW TO USE:
+ 1. A serial line is needed to use the debugger. Set up a serial line
+ from the source machine to target victim. Make sure the serial line
+ is working properly by displaying login prompt and loging in etc....
+
+ 2. Add following to grub.conf:
+ kernel /xen.kdb console=com1,vga com1=57600,8n1 dom0_mem=542M
+
+ (57600 or whatever used in step 1 above)
+
+ 3. Boot the hypervisor built with the debugger.
+
+ 4. ctrl-\ (ctrl and backslash) will break into the debugger. If the system is
+ badly hung, pressing NMI would also break into it. However, once kdb is
+ entered via NMI, normal execution can't continue.
+
+ 5. type 'h' for list of commands.
+
+ 6. Command line editing is limited to backspace. ctrl-c to start a new cmd.
+
+
+
+GUEST debug:
+ - type sym in the debugger
+ - for REL4, grep kallsyms_names, kallsyms_addresses, and kallsyms_num_syms
+ in the guest System.map* file. Run sym again with domid and the three
+ values on the command line.
+ - Now basic symbols can be used for guest debug. Note, if the binary is not
+ built with symbols, only function names are available, but not global vars.
+
+ Eg: sym 0 c0696084 c068a590 c0696080 c06b43e8 c06b4740
+ will set symbols for dom 0. Then :
+
+ [4]xkdb> bp some_function 0
+
+ wills set bp at some_function in dom 0
+
+ [3]xkdb> dw c068a590 32 0 : display 32 bytes of dom0 memory
+
+
+Tips:
+ - In "[0]xkdb>" : 0 is the cpu number in decimal
+ - In
+ 00000000c042645c: 0:do_timer+17 push %ebp
+ 0:do_timer : 0 is the domid in hex
+ offset +17 is in hex.
+
+ absense of 0: would indicate it's a hypervisor function
+
+ - commands starting with kdb (kdb*) are for kdb debug only.
+
+
+Finally,
+ - think hex.
+ - bug/problem: enter kdbdbg, reproduce, and send me the output.
+ If the output is not enough, I may ask to run kdbdbg twice, then collect
+ output.
+
+
+Thanks,
+Mukesh Rathor
+Oracle Corporatin,
+Redwood Shores, CA 94065
+
+--------------------------------------------------------------------------------
+COMMAND DESCRIPTION:
+
+info: Print basic info like version, compile flags, etc..
+
+cur: print current domain id and vcpu id
+
+f: display current stack. If a vcpu ptr is given, then print stack for that
+ VCPU by using its IP and SP.
+
+fg: display stack for a guest given domid, SP and IP.
+
+dw: display words of memory. 'num' of bytes is optional, but if displaying guest
+ memory, then is required.
+
+dd: same as above, but display doublewords.
+
+dwm: same as above but the address is machine address instead of virtual.
+
+ddm: same as above, but display doublewords.
+
+dr: display registers. if 'sp' is specified then print few extra registers.
+
+drg: display guest context saved on stack bottom.
+
+dis: disassemble instructions. If disassembling for guest, then 'num' must
+ be specified. 'num' is number of instrs to display.
+
+dism: toggle disassembly mode between Intel and ATT/GAS.
+
+mw: modify word in memory given virtual address. 'domid' may be specified if
+ modifying guest memory. value is assumed in hex even without 0x.
+
+md: same as above but modify doubleword.
+
+mr: modify register. value is assumd hex.
+
+bc: clear given or all breakpoints
+
+bp: display breakpoints or set a breakpoint. Domid may be specified to set a bp
+ in guest. kdb functions may not be specified if debugging kdb.
+ Example:
+ xkdb> bp acpi_processor_idle : will set bp in xen
+ xkdb> bp default_idle 0 : will set bp in domid 0
+ xkdb> bp idle_cpu 9 : will set bp in domid 9
+
+ Conditions may be specified for a bp: lhs == rhs or lhs != rhs
+ where : lhs is register like 'r6', 'rax', etc... or memory location
+ rhs is hex value with or without leading 0x.
+ Thus,
+ xkdb> bp acpi_processor_idle rdi == c000
+ xkdb> bp 0xffffffff80062ebc 0 rsi == ffff880021edbc98 : will break into
+ kdb at 0xffffffff80062ebc in dom0 when rsi is ffff880021edbc98
+
+btp: break point trace. Upon bp, print some info and continue without stopping.
+ Ex: btp idle_cpu 7 rax rbx 0x20ef5a5 r9
+
+ will print: rax, rbx, *(long *)0x20ef5a5, r9 upon hitting idle_cpu() and
+ continue.
+
+wp: set a watchpoint at a virtual address which can belong to hypervisor or
+ any guest. Do not specify wp in kdb path if debugging kdb.
+
+wc: clear given or all watchpoints.
+
+ni: single step, stepping over function calls.
+
+ss: single step. Be carefull when in interrupt handlers or context switches.
+
+ssb: single step to branch. Use with care.
+
+go: leave kdb and continue.
+
+cpu: go back to orig cpu when entering kdb. If 'cpu number' given, then switch
+ to that cpu. If 'all' then show status of all cpus.
+
+nmi: Only available in hung/crash state. Send NMI to a cpu that may be hung.
+
+sym: Initialize a symbol table for debugging a guest. Look into the System.map
+ file of guest for certain symbol values and provide them here.
+
+vcpuh: Given vcpu ptr, display hvm_vcpu struct.
+
+vcpu: Display current vcpu struct. If 'vcpu-ptr' given, display that vcpu.
+
+dom: display current domain. If 'domid' then display that domid. If 'all', then
+ display all domains.
+
+sched: show schedular info and run queues.
+
+mmu: print basic mmu info
+
+p2m: convert a gpfn to mfn given a domid. value in hex even without 0x.
+
+m2p: convert mfn to pfn. value in hex even without 0x.
+
+dpage: display struct page given a mfn or struct page ptr. Since, no info is
+ kept on page type, we display all possible page types.
+
+dtrq: display timer queues.
+
+didt: dump IDT table.
+
+dgt: dump GDT table.
+
+dirq: display IRQ bindings.
+
+dvmc: display all or given dom/vcpu VMCS or VMCB.
+
+trcon: turn tracing on. Trace hooks must be added in xen and kdb function
+ called directly from there.
+
+trcoff: turn tracing off.
+
+trcz: zero trace buffer.
+
+trcp: give hints to print the circular trace buffer, like current active ptr.
+
+usr1: allows to add any arbitraty command quickly.
+
+--------------------------------------------------------------------------------
+/*
+ * Copyright (C) 2008 Oracle. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
diff -r 32034d1914a6 xen/kdb/guest/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/guest/Makefile Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,3 @@
+
+obj-y := kdb_guest.o
+
diff -r 32034d1914a6 xen/kdb/guest/kdb_guest.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/guest/kdb_guest.c Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2009, Mukesh Rathor, Oracle Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include "../include/kdbinc.h"
+
+/* information for symbols for a guest (includeing dom 0 ) is saved here */
+struct gst_syminfo { /* guest symbols info */
+ int domid; /* which domain */
+ int bitness; /* 32 or 64 */
+ void *addrtblp; /* ptr to (32/64)addresses tbl */
+ u8 *toktbl; /* ptr to kallsyms_token_table */
+ u16 *tokidxtbl; /* ptr to kallsyms_token_index */
+ u8 *kallsyms_names; /* ptr to kallsyms_names */
+ long kallsyms_num_syms; /* ptr to kallsyms_num_syms */
+ kdbva_t stext; /* value of _stext in guest */
+ kdbva_t etext; /* value of _etext in guest */
+ kdbva_t sinittext; /* value of _sinittext in guest */
+ kdbva_t einittext; /* value of _einittext in guest */
+};
+
+#define MAX_CACHE 16 /* cache upto 16 guests */
+struct gst_syminfo gst_syminfoa[MAX_CACHE]; /* guest symbol info array */
+
+static struct gst_syminfo *
+kdb_get_syminfo_slot(void)
+{
+ int i;
+ for (i=0; i < MAX_CACHE; i++)
+ if (gst_syminfoa[i].addrtblp == NULL)
+ return (&gst_syminfoa[i]);
+
+ return NULL;
+}
+
+static struct gst_syminfo *
+kdb_domid2syminfop(domid_t domid)
+{
+ int i;
+ for (i=0; i < MAX_CACHE; i++)
+ if (gst_syminfoa[i].domid == domid)
+ return (&gst_syminfoa[i]);
+
+ return NULL;
+}
+
+/* check if an address looks like text address in guest */
+int
+kdb_is_addr_guest_text(kdbva_t addr, int domid)
+{
+ struct gst_syminfo *gp = kdb_domid2syminfop(domid);
+
+ if (!gp || !gp->stext || !gp->etext)
+ return 0;
+ KDBGP1("guestaddr: addr:%lx domid:%d\n", addr, domid);
+
+ return ( (addr >= gp->stext && addr <= gp->etext) ||
+ (addr >= gp->sinittext && addr <= gp->einittext) );
+}
+
+/*
+ * returns: value of kallsyms_addresses[idx];
+ */
+static kdbva_t
+kdb_rd_guest_addrtbl(struct gst_syminfo *gp, int idx)
+{
+ kdbva_t addr, retaddr=0;
+ int num = gp->bitness/8; /* whether 4 byte or 8 byte ptrs */
+ domid_t id = gp->domid;
+
+ addr = (kdbva_t)(((char *)gp->addrtblp) + idx * num);
+ KDBGP1("rdguestaddrtbl:addr:%lx idx:%d\n", addr, idx);
+
+ if (kdb_read_mem(addr, (kdbbyt_t *)&retaddr,num,id) != num) {
+ kdbp("Can't read addrtbl domid:%d at:%lx\n", id, addr);
+ return 0;
+ }
+ KDBGP1("rdguestaddrtbl:exit:retaddr:%lx\n", retaddr);
+ return retaddr;
+}
+
+/* Based on el5 kallsyms.c file. */
+static unsigned int
+kdb_expand_el5_sym(struct gst_syminfo *gp, unsigned int off, char *result)
+{
+ int len, skipped_first = 0;
+ u8 u8idx, *tptr, *datap;
+ domid_t domid = gp->domid;
+
+ *result = '\0';
+
+ /* get the compressed symbol length from the first symbol byte */
+ datap = gp->kallsyms_names + off;
+ len = 0;
+ if ((kdb_read_mem((kdbva_t)datap, (kdbbyt_t *)&len, 1, domid)) != 1) {
+ KDBGP("failed to read guest memory\n");
+ return 0;
+ }
+ datap++;
+
+ /* update the offset to return the offset for the next symbol on
+ * the compressed stream */
+ off += len + 1;
+
+ /* for every byte on the compressed symbol data, copy the table
+ * entry for that byte */
+ while(len) {
+ u16 u16idx, *u16p;
+ if (kdb_read_mem((kdbva_t)datap,(kdbbyt_t *)&u8idx,1,domid)!=1){
+ kdbp("memory (u8idx) read error:%p\n",gp->tokidxtbl);
+ return 0;
+ }
+ u16p = u8idx + gp->tokidxtbl;
+ if (kdb_read_mem((kdbva_t)u16p,(kdbbyt_t *)&u16idx,2,domid)!=2){
+ kdbp("tokidxtbl read error:%p\n", u16p);
+ return 0;
+ }
+ tptr = gp->toktbl + u16idx;
+ datap++;
+ len--;
+
+ while ((kdb_read_mem((kdbva_t)tptr, (kdbbyt_t *)&u8idx, 1, domid)==1) &&
+ u8idx) {
+
+ if(skipped_first) {
+ *result = u8idx;
+ result++;
+ } else
+ skipped_first = 1;
+ tptr++;
+ }
+ }
+ *result = '\0';
+ return off; /* return to offset to the next symbol */
+}
+
+#define EL4_NMLEN 127
+/* so much pain, so not sure of it's worth .. :).. */
+static kdbva_t
+kdb_expand_el4_sym(struct gst_syminfo *gp, int low, char *result, char *symp)
+{
+ int i, j;
+ u8 *nmp = gp->kallsyms_names; /* guest address space */
+ kdbbyt_t byte, prefix;
+ domid_t id = gp->domid;
+ kdbva_t addr;
+
+ KDBGP1("Eel4sym:nmp:%p maxidx:$%d sym:%s\n", nmp, low, symp);
+ for (i=0; i <= low; i++) {
+ /* unsigned prefix = *name++; */
+ if (kdb_read_mem((kdbva_t)nmp, &prefix, 1, id) != 1) {
+ kdbp("failed to read:%p domid:%x\n", nmp, id);
+ return 0;
+ }
+ KDBGP2("el4:i:%d prefix:%x\n", i, prefix);
+ nmp++;
+ /* strncpy(namebuf + prefix, name, KSYM_NAME_LEN - prefix); */
+ addr = (long)result + prefix;
+ for (j=0; j < EL4_NMLEN-prefix; j++) {
+ if (kdb_read_mem((kdbva_t)nmp, &byte, 1, id) != 1) {
+ kdbp("failed read:%p domid:%x\n", nmp, id);
+ return 0;
+ }
+ KDBGP2("el4:j:%d byte:%x\n", j, byte);
+ *(kdbbyt_t *)addr = byte;
+ addr++; nmp++;
+ if (byte == '\0')
+ break;
+ }
+ KDBGP2("el4sym:i:%d res:%s\n", i, result);
+ if (symp && strcmp(result, symp) == 0)
+ return(kdb_rd_guest_addrtbl(gp, i));
+
+ /* kallsyms.c: name += strlen(name) + 1; */
+ if (j == EL4_NMLEN-prefix && byte != '\0')
+ while (kdb_read_mem((kdbva_t)nmp, &byte, 1, id) && byte != '\0')
+ nmp++;
+ }
+ KDBGP1("Xel4sym: na-ga-da\n");
+ return 0;
+}
+
+static unsigned int
+kdb_get_el5_symoffset(struct gst_syminfo *gp, long pos)
+{
+ int i;
+ u8 data, *namep;
+ domid_t domid = gp->domid;
+
+ namep = gp->kallsyms_names;
+ for (i=0; i < pos; i++) {
+ if (kdb_read_mem((kdbva_t)namep, &data, 1, domid) != 1) {
+ kdbp("Can't read id:$%d mem:%p\n", domid, namep);
+ return 0;
+ }
+ namep = namep + data + 1;
+ }
+ return namep - gp->kallsyms_names;
+}
+
+/*
+ * for a given guest domid (domid >= 0 && < KDB_HYPDOMID), convert addr to
+ * symbol. offset is set to addr - symbolstart
+ */
+char *
+kdb_guest_addr2sym(unsigned long addr, domid_t domid, ulong *offsp)
+{
+ static char namebuf[KSYM_NAME_LEN+1];
+ unsigned long low, high, mid;
+ struct gst_syminfo *gp = kdb_domid2syminfop(domid);
+
+ *offsp = 0;
+ if(!gp || gp->kallsyms_num_syms == 0)
+ return " ??? ";
+
+ namebuf[0] = namebuf[KSYM_NAME_LEN] = '\0';
+ if (1) {
+ /* do a binary search on the sorted kallsyms_addresses array */
+ low = 0;
+ high = gp->kallsyms_num_syms;
+
+ while (high-low > 1) {
+ mid = (low + high) / 2;
+ if (kdb_rd_guest_addrtbl(gp, mid) <= addr)
+ low = mid;
+ else
+ high = mid;
+ }
+ /* Grab name */
+ if (gp->toktbl) {
+ int symoff = kdb_get_el5_symoffset(gp,low);
+ kdb_expand_el5_sym(gp, symoff, namebuf);
+ } else
+ kdb_expand_el4_sym(gp, low, namebuf, NULL);
+ *offsp = addr - kdb_rd_guest_addrtbl(gp, low);
+ return namebuf;
+ }
+ return " ???? ";
+}
+
+
+/*
+ * save guest (dom0 and others) symbols info : domid and following addresses:
+ * &kallsyms_names &kallsyms_addresses &kallsyms_num_syms \
+ * &kallsyms_token_table &kallsyms_token_index
+ */
+void
+kdb_sav_dom_syminfo(domid_t domid, long namesp, long addrap, long nump,
+ long toktblp, long tokidxp)
+{
+ int bytes;
+ long val = 0; /* must be set to zero for 32 on 64 cases */
+ struct gst_syminfo *gp = kdb_get_syminfo_slot();
+
+ if (gp == NULL) {
+ kdbp("kdb:kdb_sav_dom_syminfo():Table full.. symbols not saved\n");
+ return;
+ }
+ memset(gp, 0, sizeof(*gp));
+
+ gp->domid = domid;
+ gp->bitness = kdb_guest_bitness(domid);
+ gp->addrtblp = (void *)addrap;
+ gp->kallsyms_names = (u8 *)namesp;
+ gp->toktbl = (u8 *)toktblp;
+ gp->tokidxtbl = (u16 *)tokidxp;
+
+ KDBGP("domid:%x bitness:$%d numsyms:$%ld arrayp:%p\n", domid,
+ gp->bitness, gp->kallsyms_num_syms, gp->addrtblp);
+
+ bytes = gp->bitness/8;
+ if (kdb_read_mem(nump, (kdbbyt_t *)&val, bytes, domid) != bytes) {
+
+ kdbp("Unable to read number of symbols from:%lx\n", nump);
+ memset(gp, 0, sizeof(*gp));
+ return;
+ } else
+ kdbp("Number of symbols:$%ld\n", val);
+
+ gp->kallsyms_num_syms = val;
+
+ bytes = (gp->bitness/8) * gp->kallsyms_num_syms;
+ gp->stext = kdb_guest_sym2addr("_stext", domid);
+ gp->etext = kdb_guest_sym2addr("_etext", domid);
+ if (!gp->stext || !gp->etext)
+ kdbp("Warn: Can't find stext/etext\n");
+
+ if (gp->toktbl && gp->tokidxtbl) {
+ gp->sinittext = kdb_guest_sym2addr("_sinittext", domid);
+ gp->einittext = kdb_guest_sym2addr("_einittext", domid);
+ if (!gp->sinittext || !gp->einittext) {
+ kdbp("Warn: Can't find sinittext/einittext\n");
+ }
+ }
+ KDBGP1("stxt:%lx etxt:%lx sitxt:%lx eitxt:%lx\n", gp->stext, gp->etext,
+ gp->sinittext, gp->einittext);
+ kdbp("Succesfully saved symbol info\n");
+}
+
+/*
+ * given a symbol string for a guest/domid, return its address
+ */
+kdbva_t
+kdb_guest_sym2addr(char *symp, domid_t domid)
+{
+ char namebuf[KSYM_NAME_LEN+1];
+ int i, off=0;
+ struct gst_syminfo *gp = kdb_domid2syminfop(domid);
+
+ KDBGP("sym2a: sym:%s domid:%x numsyms:%ld\n", symp, domid,
+ gp ? gp->kallsyms_num_syms: -1);
+
+ if (!gp)
+ return 0;
+
+ if (gp->toktbl == 0 || gp->tokidxtbl == 0)
+ return(kdb_expand_el4_sym(gp, gp->kallsyms_num_syms, namebuf, symp));
+
+ for (i=0; i < gp->kallsyms_num_syms; i++) {
+ off = kdb_expand_el5_sym(gp, off, namebuf);
+ KDBGP1("i:%d namebuf:%s\n", i, namebuf);
+ if (strcmp(namebuf, symp) == 0) {
+ return(kdb_rd_guest_addrtbl(gp, i));
+ }
+ }
+ KDBGP("sym2a:exit:na-ga-da\n");
+ return 0;
+}
diff -r 32034d1914a6 xen/kdb/include/kdb_extern.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/include/kdb_extern.h Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009, Mukesh Rathor, Oracle Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#ifndef _KDB_EXTERN_H
+#define _KDB_EXTERN_H
+
+#define KDB_TRAP_FATAL 1 /* trap is fatal. can't resume from kdb */
+#define KDB_TRAP_NONFATAL 2 /* can resume from kdb */
+#define KDB_TRAP_KDBSTACK 3 /* to debug kdb itself. dump kdb stack */
+
+/* following can be called from anywhere in xen to debug */
+extern void kdb_trap_immed(int);
+extern void kdbtrc(unsigned int, unsigned int, uint64_t, uint64_t, uint64_t);
+extern void kdbp(const char *fmt, ...);
+
+typedef unsigned long kdbva_t;
+typedef unsigned char kdbbyt_t;
+typedef unsigned long kdbma_t;
+
+extern unsigned long kdb_dr7;
+
+
+extern volatile int kdb_session_begun;
+extern volatile int kdb_enabled;
+extern void kdb_init(void);
+extern int kdb_keyboard(struct cpu_user_regs *);
+extern void kdb_ssni_reenter(struct cpu_user_regs *);
+extern int kdb_handle_trap_entry(int, struct cpu_user_regs *);
+extern int kdb_trap_fatal(int, struct cpu_user_regs *); /* fatal with regs */
+extern void kdb_dump_vmcs(uint16_t did, int vid);
+void kdb_dump_vmcb(uint16_t did, int vid);
+extern void kdb_dump_time_pcpu(void);
+
+
+#define VMPTRST_OPCODE ".byte 0x0f,0xc7\n" /* reg/opcode: /7 */
+#define MODRM_EAX_07 ".byte 0x38\n" /* [EAX], with reg/opcode: /7 */
+static inline void __vmptrst(u64 *addr)
+{
+ asm volatile ( VMPTRST_OPCODE
+ MODRM_EAX_07
+ :
+ : "a" (addr)
+ : "memory");
+}
+
+#define is_hvm_or_hyb_domain is_hvm_domain
+#define is_hvm_or_hyb_vcpu is_hvm_vcpu
+#define is_hybrid_vcpu(x) (0)
+
+
+#endif /* _KDB_EXTERN_H */
diff -r 32034d1914a6 xen/kdb/include/kdbdefs.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/include/kdbdefs.h Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2009, Mukesh Rathor, Oracle Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#ifndef _KDBDEFS_H
+#define _KDBDEFS_H
+
+/* reason we are entering kdbmain (bp == breakpoint) */
+typedef enum {
+ KDB_REASON_KEYBOARD=1, /* Keyboard entry - always 1 */
+ KDB_REASON_BPEXCP, /* #BP excp: sw bp (INT3) */
+ KDB_REASON_DBEXCP, /* #DB excp: TF flag or HW bp */
+ KDB_REASON_PAUSE_IPI, /* received pause IPI from another CPU */
+} kdb_reason_t;
+
+
+/* cpu state: past, present, and future */
+typedef enum {
+ KDB_CPU_INVAL=0, /* invalid value. not in or leaving kdb */
+ KDB_CPU_QUIT, /* main cpu does GO. all others do QUIT */
+ KDB_CPU_PAUSE, /* cpu is paused */
+ KDB_CPU_DISABLE, /* disable interrupts */
+ KDB_CPU_SHOWPC, /* all cpus must display their pc */
+ KDB_CPU_DO_VMEXIT, /* all cpus must do vmcs vmexit. intel only */
+ KDB_CPU_MAIN_KDB, /* cpu in kdb main command loop */
+ KDB_CPU_GO, /* user entered go for this cpu */
+ KDB_CPU_SS, /* single step for this cpu */
+ KDB_CPU_NI, /* go to next instr after the call instr */
+ KDB_CPU_INSTALL_BP, /* delayed install of sw bp(s) by this cpu */
+} kdb_cpu_cmd_t;
+
+/* ============= kdb commands ============================================= */
+
+typedef kdb_cpu_cmd_t (*kdb_func_t)(int, const char **, struct cpu_user_regs *);
+typedef kdb_cpu_cmd_t (*kdb_usgf_t)(void);
+
+typedef enum {
+ KDB_REPEAT_NONE = 0, /* Do not repeat this command */
+ KDB_REPEAT_NO_ARGS, /* Repeat the command without arguments */
+ KDB_REPEAT_WITH_ARGS, /* Repeat the command including its arguments */
+} kdb_repeat_t;
+
+typedef struct _kdbtab {
+ char *kdb_cmd_name; /* Command name */
+ kdb_func_t kdb_cmd_func; /* ptr to function to execute command */
+ kdb_usgf_t kdb_cmd_usgf; /* usage function ptr */
+ int kdb_cmd_crash_avail; /* available in sys fatal/crash state */
+ kdb_repeat_t kdb_cmd_repeat; /* Does command auto repeat on enter? */
+} kdbtab_t;
+
+
+/* ============= types and stuff ========================================= */
+#define BFD_INVAL (~0UL) /* invalid bfd_vma */
+
+#if defined(__x86_64__)
+ #define KDBIP rip
+ #define KDBSP rsp
+#else
+ #define KDBIP eip
+ #define KDBSP esp
+#endif
+
+/* ============= macros ================================================== */
+extern volatile int kdbdbg;
+#define KDBGP(...) {(kdbdbg) ? kdbp(__VA_ARGS__):0;}
+#define KDBGP1(...) {(kdbdbg>1) ? kdbp(__VA_ARGS__):0;}
+#define KDBGP2(...) {(kdbdbg>2) ? kdbp(__VA_ARGS__):0;}
+#define KDBGP3(...) {0;};
+
+#define KDBMIN(x,y) (((x)<(y))?(x):(y))
+
+#endif /* !_KDBDEFS_H */
diff -r 32034d1914a6 xen/kdb/include/kdbinc.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/include/kdbinc.h Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009, Mukesh Rathor, Oracle Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#ifndef _KDBINC_H
+#define _KDBINC_H
+
+#include <xen/compile.h>
+#include <xen/config.h>
+#include <xen/version.h>
+#include <xen/compat.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/errno.h>
+#include <xen/sched.h>
+#include <xen/domain.h>
+#include <xen/mm.h>
+#include <xen/event.h>
+#include <xen/time.h>
+#include <xen/console.h>
+#include <xen/softirq.h>
+#include <xen/domain_page.h>
+#include <xen/rangeset.h>
+#include <xen/guest_access.h>
+#include <xen/hypercall.h>
+#include <xen/delay.h>
+#include <xen/shutdown.h>
+#include <xen/percpu.h>
+#include <xen/multicall.h>
+#include <xen/rcupdate.h>
+#include <xen/ctype.h>
+#include <xen/symbols.h>
+#include <xen/shutdown.h>
+#include <xen/serial.h>
+#include <xen/grant_table.h>
+#include <asm/debugger.h>
+#include <asm/shared.h>
+#include <asm/apicdef.h>
+
+#include <asm/nmi.h>
+#include <asm/p2m.h>
+#include <asm/debugreg.h>
+#include <public/sched.h>
+#include <public/vcpu.h>
+#ifdef _XEN_LATEST
+#include <xsm/xsm.h>
+#endif
+
+#include <asm/hvm/vmx/vmx.h>
+
+#include "kdb_extern.h"
+#include "kdbdefs.h"
+#include "kdbproto.h"
+
+#endif /* !_KDBINC_H */
diff -r 32034d1914a6 xen/kdb/include/kdbproto.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/include/kdbproto.h Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2009, Mukesh Rathor, Oracle Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#ifndef _KDBPROTO_H
+#define _KDBPROTO_H
+
+/* hypervisor interfaces use by kdb or kdb interfaces in xen files */
+extern void console_putc(char);
+extern int console_getc(void);
+extern void show_trace(struct cpu_user_regs *);
+extern void kdb_dump_timer_queues(void);
+extern void kdb_time_resume(int);
+extern void kdb_print_sched_info(void);
+extern void kdb_curr_cpu_flush_vmcs(void);
+extern unsigned long address_lookup(char *);
+extern void kdb_prnt_guest_mapped_irqs(void);
+
+/* kdb globals */
+extern kdbtab_t *kdb_cmd_tbl;
+extern char kdb_prompt[32];
+extern volatile int kdb_sys_crash;
+extern volatile kdb_cpu_cmd_t kdb_cpu_cmd[NR_CPUS];
+extern volatile int kdb_trcon;
+
+/* kdb interfaces */
+extern void __init kdb_io_init(void);
+extern void kdb_init_cmdtab(void);
+extern void kdb_do_cmds(struct cpu_user_regs *);
+extern int kdb_check_sw_bkpts(struct cpu_user_regs *);
+extern int kdb_check_watchpoints(struct cpu_user_regs *);
+extern void kdb_do_watchpoints(kdbva_t, int, int);
+extern void kdb_install_watchpoints(void);
+extern void kdb_clear_wps(int);
+extern kdbma_t kdb_rd_dbgreg(int);
+
+
+
+extern char *kdb_get_cmdline(char *);
+extern void kdb_clear_prev_cmd(void);
+extern void kdb_toggle_dis_syntax(void);
+extern int kdb_check_call_instr(domid_t, kdbva_t);
+extern void kdb_display_pc(struct cpu_user_regs *);
+extern kdbva_t kdb_print_instr(kdbva_t, long, domid_t);
+extern int kdb_read_mmem(kdbva_t, kdbbyt_t *, int);
+extern int kdb_read_mem(kdbva_t, kdbbyt_t *, int, domid_t);
+extern int kdb_write_mem(kdbva_t, kdbbyt_t *, int, domid_t);
+
+extern void kdb_install_all_swbp(void);
+extern void kdb_uninstall_all_swbp(void);
+extern int kdb_swbp_exists(void);
+extern void kdb_flush_swbp_table(void);
+extern int kdb_is_addr_guest_text(kdbva_t, int);
+extern kdbva_t kdb_guest_sym2addr(char *, domid_t);
+extern char *kdb_guest_addr2sym(unsigned long, domid_t, ulong *);
+extern void kdb_prnt_addr2sym(domid_t, kdbva_t, char *);
+extern void kdb_sav_dom_syminfo(domid_t, long, long, long, long, long);
+extern int kdb_guest_bitness(domid_t);
+extern void kdb_nmi_pause_cpus(cpumask_t);
+
+extern void kdb_trczero(void);
+void kdb_trcp(void);
+
+
+
+#endif /* !_KDBPROTO_H */
diff -r 32034d1914a6 xen/kdb/kdb_cmds.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/kdb_cmds.c Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,3789 @@
+/*
+ * Copyright (C) 2009, Mukesh Rathor, Oracle Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include "include/kdbinc.h"
+
+#if defined(__x86_64__)
+ #define KDBF64 "%lx"
+ #define KDBFL "%016lx" /* print long all digits */
+#else
+ #define KDBF64 "%llx"
+ #define KDBFL "%08lx"
+#endif
+
+#if XEN_SUBVERSION > 4 || XEN_VERSION == 4 /* xen 3.5.x or above */
+ #define KDB_LKDEF(l) ((l).raw.lock)
+ #define KDB_PGLLE(t) ((t).tail) /* page list last element ^%$#@ */
+#else
+ #define KDB_LKDEF(l) ((l).lock)
+ #define KDB_PGLLE(t) ((t).prev) /* page list last element ^%$#@ */
+#endif
+
+#define KDB_CMD_HISTORY_COUNT 32
+#define CMD_BUFLEN 200 /* kdb_printf: max printline == 256 */
+
+#define KDBMAXSBP 16 /* max number of software breakpoints */
+#define KDB_MAXARGC 16 /* max args in a kdb command */
+#define KDB_MAXBTP 8 /* max display args in btp */
+
+/* condition is: 'r6 == 0x123f' or '0xffffffff82800000 != deadbeef' */
+struct kdb_bpcond {
+ kdbbyt_t bp_cond_status; /* 0 == off, 1 == register, 2 == memory */
+ kdbbyt_t bp_cond_type; /* 0 == bad, 1 == equal, 2 == not equal */
+ ulong bp_cond_lhs; /* lhs of condition: reg offset or mem loc */
+ ulong bp_cond_rhs; /* right hand side of condition */
+};
+
+/* software breakpoint structure */
+struct kdb_sbrkpt {
+ kdbva_t bp_addr; /* address the bp is set at */
+ domid_t bp_domid; /* which domain the bp belongs to */
+ kdbbyt_t bp_originst; /* save orig instr/s here */
+ kdbbyt_t bp_deleted; /* delete pending on this bp */
+ kdbbyt_t bp_ni; /* set for KDB_CPU_NI */
+ kdbbyt_t bp_just_added; /* added in the current kdb session */
+ kdbbyt_t bp_type; /* 0 = normal, 1 == cond, 2 == btp */
+ union {
+ struct kdb_bpcond bp_cond;
+ ulong *bp_btp;
+ } u;
+};
+
+/* don't use kmalloc in kdb which hijacks all cpus */
+static ulong kdb_btp_argsa[KDBMAXSBP][KDB_MAXBTP];
+static ulong *kdb_btp_ap[KDBMAXSBP];
+
+static struct kdb_reg_nmofs {
+ char *reg_nm;
+ int reg_offs;
+} kdb_reg_nm_offs[] = {
+ { "rax", offsetof(struct cpu_user_regs, rax) },
+ { "rbx", offsetof(struct cpu_user_regs, rbx) },
+ { "rcx", offsetof(struct cpu_user_regs, rcx) },
+ { "rdx", offsetof(struct cpu_user_regs, rdx) },
+ { "rsi", offsetof(struct cpu_user_regs, rsi) },
+ { "rdi", offsetof(struct cpu_user_regs, rdi) },
+ { "rbp", offsetof(struct cpu_user_regs, rbp) },
+ { "rsp", offsetof(struct cpu_user_regs, rsp) },
+ { "r8", offsetof(struct cpu_user_regs, r8) },
+ { "r9", offsetof(struct cpu_user_regs, r9) },
+ { "r10", offsetof(struct cpu_user_regs, r10) },
+ { "r11", offsetof(struct cpu_user_regs, r11) },
+ { "r12", offsetof(struct cpu_user_regs, r12) },
+ { "r13", offsetof(struct cpu_user_regs, r13) },
+ { "r14", offsetof(struct cpu_user_regs, r14) },
+ { "r15", offsetof(struct cpu_user_regs, r15) },
+ { "rflags", offsetof(struct cpu_user_regs, rflags) } };
+
+static const int KDBBPSZ=1; /* size of KDB_BPINST is 1 byte*/
+static kdbbyt_t kdb_bpinst = 0xcc; /* breakpoint instr: INT3 */
+static struct kdb_sbrkpt kdb_sbpa[KDBMAXSBP]; /* soft brkpt array/table */
+static kdbtab_t *tbp;
+
+static int kdb_set_bp(domid_t, kdbva_t, int, ulong *, char*, char*, char*);
+static void kdb_print_uregs(struct cpu_user_regs *);
+
+
+/* ===================== cmdline functions ================================ */
+
+/* lp points to a string of only alpha numeric chars terminated by '\n'.
+ * Parse the string into argv pointers, and RETURN argc
+ * Eg: if lp --> "dr sp\n" : argv[0]=="dr\0" argv[1]=="sp\0" argc==2
+ */
+static int
+kdb_parse_cmdline(char *lp, const char **argv)
+{
+ int i=0;
+
+ for (; *lp == ' '; lp++); /* note: isspace() skips '\n' also */
+ while ( *lp != '\n' ) {
+ if (i == KDB_MAXARGC) {
+ printk("kdb: max args exceeded\n");
+ break;
+ }
+ argv[i++] = lp;
+ for (; *lp != ' ' && *lp != '\n'; lp++);
+ if (*lp != '\n')
+ *lp++ = '\0';
+ for (; *lp == ' '; lp++);
+ }
+ *lp = '\0';
+ return i;
+}
+
+void
+kdb_clear_prev_cmd() /* so previous command is not repeated */
+{
+ tbp = NULL;
+}
+
+void
+kdb_do_cmds(struct cpu_user_regs *regs)
+{
+ char *cmdlinep;
+ const char *argv[KDB_MAXARGC];
+ int argc = 0, curcpu = smp_processor_id();
+ kdb_cpu_cmd_t result = KDB_CPU_MAIN_KDB;
+
+ snprintf(kdb_prompt, sizeof(kdb_prompt), "[%d]xkdb> ", curcpu);
+
+ while (result == KDB_CPU_MAIN_KDB) {
+ cmdlinep = kdb_get_cmdline(kdb_prompt);
+ if (*cmdlinep == '\n') {
+ if (tbp==NULL || tbp->kdb_cmd_func==NULL)
+ continue;
+ else
+ argc = -1; /* repeat prev command */
+ } else {
+ argc = kdb_parse_cmdline(cmdlinep, argv);
+ for(tbp=kdb_cmd_tbl; tbp->kdb_cmd_func; tbp++) {
+ if (strcmp(argv[0], tbp->kdb_cmd_name)==0)
+ break;
+ }
+ }
+ if (kdb_sys_crash && tbp->kdb_cmd_func && !tbp->kdb_cmd_crash_avail) {
+ kdbp("cmd not available in fatal/crashed state....\n");
+ continue;
+ }
+ if (tbp->kdb_cmd_func) {
+ result = (*tbp->kdb_cmd_func)(argc, argv, regs);
+ if (tbp->kdb_cmd_repeat == KDB_REPEAT_NONE)
+ tbp = NULL;
+ } else
+ kdbp("kdb: Unknown cmd: %s\n", cmdlinep);
+ }
+ kdb_cpu_cmd[curcpu] = result;
+ return;
+}
+
+/* ===================== Util functions ==================================== */
+
+int
+kdb_vcpu_valid(struct vcpu *in_vp)
+{
+ struct domain *dp;
+ struct vcpu *vp;
+
+ for(dp=domain_list; in_vp && dp; dp=dp->next_in_list)
+ for_each_vcpu(dp, vp)
+ if (in_vp == vp)
+ return 1;
+ return 0; /* not found */
+}
+
+/*
+ * Given a symbol, find it's address
+ */
+static kdbva_t
+kdb_sym2addr(const char *p, domid_t domid)
+{
+ kdbva_t addr;
+
+ KDBGP1("sym2addr: p:%s domid:%d\n", p, domid);
+ if (domid == DOMID_IDLE)
+ addr = address_lookup((char *)p);
+ else
+ addr = (kdbva_t)kdb_guest_sym2addr((char *)p, domid);
+ KDBGP1("sym2addr: exit: addr returned:0x%lx\n", addr);
+ return addr;
+}
+
+/*
+ * convert ascii to int decimal (base 10).
+ * Return: 0 : failed to convert, otherwise 1
+ */
+static int
+kdb_str2deci(const char *strp, int *intp)
+{
+ const char *endp;
+
+ KDBGP2("str2deci: str:%s\n", strp);
+ if (!isdigit(*strp))
+ return 0;
+ *intp = (int)simple_strtoul(strp, &endp, 10);
+ if (endp != strp+strlen(strp))
+ return 0;
+ KDBGP2("str2deci: intval:$%d\n", *intp);
+ return 1;
+}
+/*
+ * convert ascii to long. NOTE: base is 16
+ * Return: 0 : failed to convert, otherwise 1
+ */
+static int
+kdb_str2ulong(const char *strp, ulong *longp)
+{
+ ulong val;
+ const char *endp;
+
+ KDBGP2("str2long: str:%s\n", strp);
+ if (!isxdigit(*strp))
+ return 0;
+ val = (long)simple_strtoul(strp, &endp, 16); /* handles leading 0x */
+ if (endp != strp+strlen(strp))
+ return 0;
+ if (longp)
+ *longp = val;
+ KDBGP2("str2long: val:0x%lx\n", val);
+ return 1;
+}
+/*
+ * convert a symbol or ascii address to hex address
+ * Return: 0 : failed to convert, otherwise 1
+ */
+static int
+kdb_str2addr(const char *strp, kdbva_t *addrp, domid_t id)
+{
+ kdbva_t addr;
+ const char *endp;
+
+ /* assume it's an address */
+ KDBGP2("str2addr: str:%s id:%d\n", strp, id);
+ addr = (kdbva_t)simple_strtoul(strp, &endp, 16); /*handles leading 0x */
+ if (endp != strp+strlen(strp))
+ if ( !(addr=kdb_sym2addr(strp, id)) )
+ return 0;
+ *addrp = addr;
+ KDBGP2("str2addr: addr:0x%lx\n", addr);
+ return 1;
+}
+
+/* Given domid, return ptr to struct domain
+ * IF domid == DOMID_IDLE return ptr to idle_domain
+ * IF domid == valid domain, return ptr to domain struct
+ * else domid is bad and return NULL
+ */
+static struct domain *
+kdb_domid2ptr(domid_t domid)
+{
+ struct domain *dp;
+
+ /* get_domain_by_id() ret NULL for both DOMID_IDLE and bad domids */
+ if (domid == DOMID_IDLE)
+ dp = idle_vcpu[smp_processor_id()]->domain;
+ else
+ dp = get_domain_by_id(domid); /* NULL now means bad domid */
+ return dp;
+}
+
+/*
+ * Returns: 0: failed. invalid domid or string, *idp not changed.
+ */
+static int
+kdb_str2domid(const char *domstr, domid_t *idp, int perr)
+{
+ int id;
+ if (!kdb_str2deci(domstr, &id) || !kdb_domid2ptr((domid_t)id)) {
+ if (perr)
+ kdbp("Invalid domid:%s\n", domstr);
+ return 0;
+ }
+ *idp = (domid_t)id;
+ return 1;
+}
+
+static struct domain *
+kdb_strdomid2ptr(const char *domstr, int perror)
+{
+ domid_t domid;
+ if (kdb_str2domid(domstr, &domid, perror)) {
+ return(kdb_domid2ptr(domid));
+ }
+ return NULL;
+}
+
+/* return a guest bitness: 32 or 64 */
+int
+kdb_guest_bitness(domid_t domid)
+{
+ const int HYPSZ = sizeof(long) * 8;
+ struct domain *dp = kdb_domid2ptr(domid);
+ int retval;
+
+ if (is_idle_domain(dp))
+ retval = HYPSZ;
+ else if (is_hvm_or_hyb_domain(dp))
+ retval = (hvm_long_mode_enabled(dp->vcpu[0])) ? HYPSZ : 32;
+ else
+ retval = is_pv_32bit_domain(dp) ? 32 : HYPSZ;
+ KDBGP1("gbitness: domid:%d dp:%p bitness:%d\n", domid, dp, retval);
+ return retval;
+}
+
+/* kdb_print_spin_lock(&xyz_lock, "xyz_lock:", "\n"); */
+static void
+kdb_print_spin_lock(char *strp, spinlock_t *lkp, char *nlp)
+{
+ kdbp("%s %04hx %d %d%s", strp, KDB_LKDEF(*lkp), lkp->recurse_cpu,
+ lkp->recurse_cnt, nlp);
+}
+
+/* check if register string is valid. if yes, return offset to the register
+ * in cpu_user_regs, else return -1 */
+static int
+kdb_valid_reg(const char *nmp)
+{
+ int i;
+ for (i=0; i < sizeof(kdb_reg_nm_offs)/sizeof(kdb_reg_nm_offs[0]); i++)
+ if (strcmp(kdb_reg_nm_offs[i].reg_nm, nmp) == 0)
+ return kdb_reg_nm_offs[i].reg_offs;
+ return -1;
+}
+
+/* given offset of register, return register name string. if offset is invalid
+ * return NULL */
+static char *kdb_regoffs_to_name(int offs)
+{
+ int i;
+ for (i=0; i < sizeof(kdb_reg_nm_offs)/sizeof(kdb_reg_nm_offs[0]); i++)
+ if (kdb_reg_nm_offs[i].reg_offs == offs)
+ return kdb_reg_nm_offs[i].reg_nm;
+ return NULL;
+}
+
+/* ===================== util struct funcs ================================= */
+static void
+kdb_prnt_timer(struct timer *tp)
+{
+#if XEN_SUBVERSION == 0
+ kdbp(" expires:%016lx expires_end:%016lx cpu:%d status:%x\n", tp->expires,
+ tp->expires_end, tp->cpu, tp->status);
+#else
+ kdbp(" expires:%016lx cpu:%d status:%x\n", tp->expires, tp->cpu,tp->status);
+#endif
+ kdbp(" function data:%p ptr:%p ", tp->data, tp->function);
+ kdb_prnt_addr2sym(DOMID_IDLE, (kdbva_t)tp->function, "\n");
+}
+
+static void
+kdb_prnt_periodic_time(struct periodic_time *ptp)
+{
+ kdbp(" next:%p prev:%p\n", ptp->list.next, ptp->list.prev);
+ kdbp(" on_list:%d one_shot:%d dont_freeze:%d irq_issued:%d src:%x irq:%x\n",
+ ptp->on_list, ptp->one_shot, ptp->do_not_freeze, ptp->irq_issued,
+ ptp->source, ptp->irq);
+ kdbp(" vcpu:%p pending_intr_nr:%08x period:%016lx\n", ptp->vcpu,
+ ptp->pending_intr_nr, ptp->period);
+ kdbp(" scheduled:%016lx last_plt_gtime:%016lx\n", ptp->scheduled,
+ ptp->last_plt_gtime);
+ kdbp(" \n timer info:\n");
+ kdb_prnt_timer(&ptp->timer);
+ kdbp("\n");
+}
+
+/* ===================== cmd functions ==================================== */
+
+/*
+ * FUNCTION: Disassemble instructions
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_dis(void)
+{
+ kdbp("dis [addr|sym][num][domid] : Disassemble instrs\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dis(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ int num = 8; /* display 8 instr by default */
+ static kdbva_t addr = BFD_INVAL;
+ static domid_t domid;
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_dis();
+
+ if (argc != -1) /* not a command repeat */
+ domid = guest_mode(regs) ? current->domain->domain_id : DOMID_IDLE;
+
+ if (argc >= 4 && !kdb_str2domid(argv[3], &domid, 1)) {
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (argc >= 3 && !kdb_str2deci(argv[2], &num)) {
+ kdbp("kdb:Invalid num\n");
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (argc > 1 && !kdb_str2addr(argv[1], &addr, domid)) {
+ kdbp("kdb:Invalid addr/sym\n");
+ kdbp("(num has to be specified if providing domid)\n");
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (argc == 1) /* not command repeat */
+ addr = regs->KDBIP; /* PC is the default */
+ else if (addr == BFD_INVAL) {
+ kdbp("kdb:Invalid addr/sym\n");
+ return KDB_CPU_MAIN_KDB;
+ }
+ addr = kdb_print_instr(addr, num, domid);
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* FUNCTION: kdb_cmdf_dism() Toggle disassembly syntax from Intel to ATT/GAS */
+static kdb_cpu_cmd_t
+kdb_usgf_dism(void)
+{
+ kdbp("dism: toggle disassembly mode between ATT/GAS and INTEL\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dism(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_dism();
+
+ kdb_toggle_dis_syntax();
+ return KDB_CPU_MAIN_KDB;
+}
+
+static void
+_kdb_show_guest_stack(domid_t domid, kdbva_t ipaddr, kdbva_t spaddr)
+{
+ kdbva_t val;
+ int num=0, max=0, rd = kdb_guest_bitness(domid)/8;
+
+ kdb_print_instr(ipaddr, 1, domid);
+ KDBGP("_guest_stack:sp:%lx domid:%d rd:$%d\n", spaddr, domid, rd);
+ val = 0; /* must zero, in case guest is 32bit */
+ while((kdb_read_mem(spaddr,(kdbbyt_t *)&val,rd,domid)==rd) && num < 16){
+ KDBGP1("gstk:addr:%lx val:%lx\n", spaddr, val);
+ if (kdb_is_addr_guest_text(val, domid)) {
+ kdb_print_instr(val, 1, domid);
+ num++;
+ }
+ if (max++ > 10000) /* don't walk down the stack forever */
+ break; /* 10k is chosen randomly */
+ spaddr += rd;
+ }
+}
+
+/* Read guest memory and display address that looks like text. */
+static void
+kdb_show_guest_stack(struct cpu_user_regs *regs, struct vcpu *vcpup)
+{
+ kdbva_t ipaddr=regs->KDBIP, spaddr = regs->KDBSP;
+ domid_t domid = vcpup->domain->domain_id;
+
+ ASSERT(domid != DOMID_IDLE);
+ _kdb_show_guest_stack(domid, ipaddr, spaddr);
+}
+
+/* display stack. if vcpu ptr given, then display stack for that. Otherwise,
+ * use current regs */
+static kdb_cpu_cmd_t
+kdb_usgf_f(void)
+{
+ kdbp("f [vcpu-ptr]: dump current/vcpu stack\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_f(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_f();
+
+ if (argc > 1 ) {
+ struct vcpu *vp;
+ if (!kdb_str2ulong(argv[1], (ulong *)&vp) || !kdb_vcpu_valid(vp)) {
+ kdbp("kdb: Bad VCPU ptr:%s\n", argv[1]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ kdb_show_guest_stack(&vp->arch.user_regs, vp);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (guest_mode(regs))
+ kdb_show_guest_stack(regs, current);
+ else
+ show_trace(regs);
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* given an spaddr and domid for guest, dump stack */
+static kdb_cpu_cmd_t
+kdb_usgf_fg(void)
+{
+ kdbp("fg domid RIP ESP: dump guest stack given domid, RIP, and ESP\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_fg(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ domid_t domid;
+ kdbva_t ipaddr, spaddr;
+
+ if (argc != 4)
+ return kdb_usgf_fg();
+
+ if (kdb_str2domid(argv[1], &domid, 1)==0) {
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (kdb_str2ulong(argv[2], &ipaddr)==0) {
+ kdbp("Bad ipaddr:%s\n", argv[2]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (kdb_str2ulong(argv[3], &spaddr)==0) {
+ kdbp("Bad spaddr:%s\n", argv[3]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ _kdb_show_guest_stack(domid, ipaddr, spaddr);
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* Display kdb stack. for debugging kdb itself */
+static kdb_cpu_cmd_t
+kdb_usgf_kdbf(void)
+{
+ kdbp("kdbf: display kdb stack. for debugging kdb only\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_kdbf(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_kdbf();
+
+ kdb_trap_immed(KDB_TRAP_KDBSTACK);
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* worker function to display memory. Request could be for any guest, domid.
+ * Also address could be machine or virtual */
+static void
+_kdb_display_mem(kdbva_t *addrp, int *lenp, int wordsz, int domid, int is_maddr)
+{
+ #define DDBUFSZ 4096
+
+ kdbbyt_t buf[DDBUFSZ], *bp;
+ int numrd, bytes;
+ int len = *lenp;
+ kdbva_t addr = *addrp;
+
+ /* round len down to wordsz boundry because on intel endian, printing
+ * characters is not prudent, (long and ints can't be interpreted
+ * easily) */
+ len &= ~(wordsz-1);
+ len = KDBMIN(DDBUFSZ, len);
+ len = len ? len : wordsz;
+
+ KDBGP("dmem:addr:%lx buf:%p len:$%d domid:%d sz:$%d maddr:%d\n", addr,
+ buf, len, domid, wordsz, is_maddr);
+ if (is_maddr)
+ numrd=kdb_read_mmem((kdbma_t)addr, buf, len);
+ else
+ numrd=kdb_read_mem(addr, buf, len, domid);
+ if (numrd != len)
+ kdbp("Memory read error. Bytes read:$%d\n", numrd);
+
+ for (bp = buf; numrd > 0;) {
+ kdbp("%016lx: ", addr);
+
+ /* display 16 bytes per line */
+ for (bytes=0; bytes < 16 && numrd > 0; bytes += wordsz) {
+ if (numrd >= wordsz) {
+ if (wordsz == 8)
+ kdbp(" %016lx", *(long *)bp);
+ else
+ kdbp(" %08x", *(int *)bp);
+ bp += wordsz;
+ numrd -= wordsz;
+ addr += wordsz;
+ }
+ }
+ kdbp("\n");
+ continue;
+ }
+ *lenp = len;
+ *addrp = addr;
+}
+
+/* display machine mem, ie, the given address is machine address */
+static kdb_cpu_cmd_t
+kdb_display_mmem(int argc, const char **argv, int wordsz, kdb_usgf_t usg_fp)
+{
+ static kdbma_t maddr;
+ static int len;
+ static domid_t id = DOMID_IDLE;
+
+ if (argc == -1) {
+ _kdb_display_mem(&maddr, &len, wordsz, id, 1); /* cmd repeat */
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (argc <= 1 || *argv[1] == '?')
+ return (*usg_fp)();
+
+ /* check if num of bytes to display is given by user */
+ if (argc >= 3) {
+ if (!kdb_str2deci(argv[2], &len)) {
+ kdbp("Invalid length:%s\n", argv[2]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ } else
+ len = 32; /* default read len */
+
+ if (!kdb_str2ulong(argv[1], &maddr)) {
+ kdbp("Invalid argument:%s\n", argv[1]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ _kdb_display_mem(&maddr, &len, wordsz, 0, 1);
+ return KDB_CPU_MAIN_KDB;
+}
+
+/*
+ * FUNCTION: Dispaly machine Memory Word
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_dwm(void)
+{
+ kdbp("dwm: maddr|sym [num] : dump memory word given machine addr\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dwm(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ return kdb_display_mmem(argc, argv, 4, kdb_usgf_dwm);
+}
+
+/*
+ * FUNCTION: Dispaly machine Memory DoubleWord
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_ddm(void)
+{
+ kdbp("ddm: maddr|sym [num] : dump double word given machine addr\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_ddm(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ return kdb_display_mmem(argc, argv, 8, kdb_usgf_ddm);
+}
+
+/*
+ * FUNCTION: Dispaly Memory : word or doubleword
+ * wordsz : bytes in word. 4 or 8
+ *
+ * We display upto BUFSZ bytes. User can just press enter for more.
+ * addr is always in hex with or without leading 0x
+ */
+static kdb_cpu_cmd_t
+kdb_display_mem(int argc, const char **argv, int wordsz, kdb_usgf_t usg_fp)
+{
+ static kdbva_t addr;
+ static int len;
+ static domid_t id = DOMID_IDLE;
+
+ if (argc == -1) {
+ _kdb_display_mem(&addr, &len, wordsz, id, 0); /* cmd repeat */
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (argc <= 1 || *argv[1] == '?')
+ return (*usg_fp)();
+
+ id = DOMID_IDLE; /* not a command repeat, reset dom id */
+ if (argc >= 4) {
+ if (!kdb_str2domid(argv[3], &id, 1))
+ return KDB_CPU_MAIN_KDB;
+ }
+ /* check if num of bytes to display is given by user */
+ if (argc >= 3) {
+ if (!kdb_str2deci(argv[2], &len)) {
+ kdbp("Invalid length:%s\n", argv[2]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ } else
+ len = 32; /* default read len */
+ if (!kdb_str2addr(argv[1], &addr, id)) {
+ kdbp("Invalid argument:%s\n", argv[1]);
+ return KDB_CPU_MAIN_KDB;
+ }
+
+ _kdb_display_mem(&addr, &len, wordsz, id, 0);
+ return KDB_CPU_MAIN_KDB;
+}
+
+/*
+ * FUNCTION: Dispaly Memory Word
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_dw(void)
+{
+ kdbp("dw vaddr|sym [num][domid] : dump mem word. num required for domid\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dw(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ return kdb_display_mem(argc, argv, 4, kdb_usgf_dw);
+}
+
+/*
+ * FUNCTION: Dispaly Memory DoubleWord
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_dd(void)
+{
+ kdbp("dd vaddr|sym [num][domid] : dump dword. num required for domid\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dd(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ return kdb_display_mem(argc, argv, 8, kdb_usgf_dd);
+}
+
+/*
+ * FUNCTION: Modify Memory Word
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_mw(void)
+{
+ kdbp("mw vaddr|sym val [domid] : modify memory word in vaddr\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_mw(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ ulong val;
+ kdbva_t addr;
+ domid_t id = DOMID_IDLE;
+
+ if (argc < 3) {
+ return kdb_usgf_mw();
+ }
+ if (argc >=4) {
+ if (!kdb_str2domid(argv[3], &id, 1))
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (!kdb_str2ulong(argv[2], &val)) {
+ kdbp("Invalid val: %s\n", argv[2]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (!kdb_str2addr(argv[1], &addr, id)) {
+ kdbp("Invalid addr/sym: %s\n", argv[1]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (kdb_write_mem(addr, (kdbbyt_t *)&val, 4, id) != 4)
+ kdbp("Unable to set 0x%lx to 0x%lx\n", addr, val);
+ return KDB_CPU_MAIN_KDB;
+}
+
+/*
+ * FUNCTION: Modify Memory DoubleWord
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_md(void)
+{
+ kdbp("md vaddr|sym val [domid] : modify memory dword in vaddr\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_md(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ ulong val;
+ kdbva_t addr;
+ domid_t id = DOMID_IDLE;
+
+ if (argc < 3) {
+ return kdb_usgf_md();
+ }
+ if (argc >=4) {
+ if (!kdb_str2domid(argv[3], &id, 1)) {
+ return KDB_CPU_MAIN_KDB;
+ }
+ }
+ if (!kdb_str2ulong(argv[2], &val)) {
+ kdbp("Invalid val: %s\n", argv[2]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (!kdb_str2addr(argv[1], &addr, id)) {
+ kdbp("Invalid addr/sym: %s\n", argv[1]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (kdb_write_mem(addr, (kdbbyt_t *)&val,sizeof(val),id) != sizeof(val))
+ kdbp("Unable to set 0x%lx to 0x%lx\n", addr, val);
+
+ return KDB_CPU_MAIN_KDB;
+}
+
+struct Xgt_desc_struct {
+ unsigned short size;
+ unsigned long address __attribute__((packed));
+};
+
+void
+kdb_show_special_regs(struct cpu_user_regs *regs)
+{
+ struct Xgt_desc_struct desc;
+ unsigned short tr; /* Task Register segment selector */
+ __u64 efer;
+
+ kdbp("\nSpecial Registers:\n");
+ __asm__ __volatile__ ("sidt (%0) \n" :: "a"(&desc) : "memory");
+ kdbp("IDTR: addr: %016lx limit: %04x\n", desc.address, desc.size);
+ __asm__ __volatile__ ("sgdt (%0) \n" :: "a"(&desc) : "memory");
+ kdbp("GDTR: addr: %016lx limit: %04x\n", desc.address, desc.size);
+
+ kdbp("cr0: %016lx cr2: %016lx\n", read_cr0(), read_cr2());
+ kdbp("cr3: %016lx cr4: %016lx\n", read_cr3(), read_cr4());
+ __asm__ __volatile__ ("str (%0) \n":: "a"(&tr) : "memory");
+ kdbp("TR: %x\n", tr);
+
+ rdmsrl(MSR_EFER, efer); /* IA32_EFER */
+ kdbp("efer:"KDBF64" LMA(IA-32e mode):%d SCE(syscall/sysret):%d\n",
+ efer, ((efer&EFER_LMA) != 0), ((efer&EFER_SCE) != 0));
+
+ kdbp("DR0: %016lx DR1:%016lx DR2:%016lx\n", kdb_rd_dbgreg(0),
+ kdb_rd_dbgreg(1), kdb_rd_dbgreg(2));
+ kdbp("DR3: %016lx DR6:%016lx DR7:%016lx\n", kdb_rd_dbgreg(3),
+ kdb_rd_dbgreg(6), kdb_rd_dbgreg(7));
+}
+
+/*
+ * FUNCTION: Dispaly Registers. If "sp" argument, then display additional regs
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_dr(void)
+{
+ kdbp("dr [sp]: display registers. sp to display special regs also\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dr(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_dr();
+
+ KDBGP1("regs:%p .rsp:%lx .rip:%lx\n", regs, regs->rsp, regs->rip);
+ show_registers(regs);
+ if (argc > 1 && !strcmp(argv[1], "sp"))
+ kdb_show_special_regs(regs);
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* show registers on stack bottom where guest context is. same as dr if
+ * not running in guest mode */
+static kdb_cpu_cmd_t
+kdb_usgf_drg(void)
+{
+ kdbp("drg: display active guest registers at stack bottom\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_drg(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_drg();
+
+ kdbp("\tNote: ds/es/fs/gs etc.. are not saved from the cpu\n");
+ kdb_print_uregs(guest_cpu_user_regs());
+ return KDB_CPU_MAIN_KDB;
+}
+
+/*
+ * FUNCTION: Modify Register
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_mr(void)
+{
+ kdbp("mr reg val : Modify Register. val assumed in hex\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_mr(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ const char *argp;
+ int regoffs;
+ ulong val;
+
+ if (argc != 3 || !kdb_str2ulong(argv[2], &val)) {
+ return kdb_usgf_mr();
+ }
+ argp = argv[1];
+
+#if defined(__x86_64__)
+ if ((regoffs=kdb_valid_reg(argp)) != -1)
+ *((uint64_t *)((char *)regs+regoffs)) = val;
+#else
+ if (!strcmp(argp, "eax"))
+ regs->eax = val;
+ else if (!strcmp(argp, "ebx"))
+ regs->ebx = val;
+ else if (!strcmp(argp, "ecx"))
+ regs->ecx = val;
+ else if (!strcmp(argp, "edx"))
+ regs->edx = val;
+ else if (!strcmp(argp, "esi"))
+ regs->esi = val;
+ else if (!strcmp(argp, "edi"))
+ regs->edi = val;
+ else if (!strcmp(argp, "ebp"))
+ regs->ebp = val;
+ else if (!strcmp(argp, "esp"))
+ regs->esp = val;
+ else if (!strcmp(argp, "eflags") || !strcmp(argp, "rflags"))
+ regs->eflags = val;
+#endif
+ else
+ kdbp("Error. Bad register : %s\n", argp);
+
+ return KDB_CPU_MAIN_KDB;
+}
+
+/*
+ * FUNCTION: Single Step
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_ss(void)
+{
+ kdbp("ss: single step\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_ss(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ #define KDB_HALT_INSTR 0xf4
+
+ kdbbyt_t byte;
+ struct domain *dp = current->domain;
+ domid_t id = guest_mode(regs) ? dp->domain_id : DOMID_IDLE;
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_ss();
+
+ KDBGP("enter kdb_cmdf_ss \n");
+ if (!regs) {
+ kdbp("%s: regs not available\n", __FUNCTION__);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (kdb_read_mem(regs->KDBIP, &byte, 1, id) == 1) {
+ if (byte == KDB_HALT_INSTR) {
+ kdbp("kdb: jumping over halt instruction\n");
+ regs->KDBIP++;
+ }
+ } else {
+ kdbp("kdb: Failed to read byte at: %lx\n", regs->KDBIP);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (guest_mode(regs) && is_hvm_or_hyb_vcpu(current)) {
+ dp->debugger_attached = 1; /* see svm_do_resume/vmx_do_ */
+ current->arch.hvm_vcpu.single_step = 1;
+ } else
+ regs->eflags |= X86_EFLAGS_TF;
+
+ return KDB_CPU_SS;
+}
+
+/*
+ * FUNCTION: Next Instruction, step over the call instr to the next instr
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_ni(void)
+{
+ kdbp("ni: single step, stepping over function calls\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_ni(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ int sz, i;
+ domid_t id=guest_mode(regs) ? current->domain->domain_id:DOMID_IDLE;
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_ni();
+
+ KDBGP("enter kdb_cmdf_ni \n");
+ if (!regs) {
+ kdbp("%s: regs not available\n", __FUNCTION__);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if ((sz=kdb_check_call_instr(id, regs->KDBIP)) == 0) /* !call instr */
+ return kdb_cmdf_ss(argc, argv, regs); /* just do ss */
+
+ if ((i=kdb_set_bp(id, regs->KDBIP+sz, 1,0,0,0,0)) >= KDBMAXSBP) /* failed */
+ return KDB_CPU_MAIN_KDB;
+
+ kdb_sbpa[i].bp_ni = 1;
+ if (guest_mode(regs) && is_hvm_or_hyb_vcpu(current))
+ current->arch.hvm_vcpu.single_step = 0;
+ else
+ regs->eflags &= ~X86_EFLAGS_TF;
+
+ return KDB_CPU_NI;
+}
+
+static void
+kdb_btf_enable(void)
+{
+ u64 debugctl;
+ rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+ wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl | 0x2);
+}
+
+/*
+ * FUNCTION: Single Step to branch. Doesn't seem to work very well.
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_ssb(void)
+{
+ kdbp("ssb: singe step to branch\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_ssb(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_ssb();
+
+ KDBGP("MUK: enter kdb_cmdf_ssb\n");
+ if (!regs) {
+ kdbp("%s: regs not available\n", __FUNCTION__);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (is_hvm_or_hyb_vcpu(current))
+ current->domain->debugger_attached = 1; /* vmx/svm_do_resume()*/
+
+ regs->eflags |= X86_EFLAGS_TF;
+ kdb_btf_enable();
+ return KDB_CPU_SS;
+}
+
+/*
+ * FUNCTION: Continue Execution. TF must be cleared here as this could run on
+ * any cpu. Hence not OK to do it from kdb_end_session.
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_go(void)
+{
+ kdbp("go: leave kdb and continue execution\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_go(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_go();
+
+ regs->eflags &= ~X86_EFLAGS_TF;
+ return KDB_CPU_GO;
+}
+
+/* All cpus must display their current context */
+static kdb_cpu_cmd_t
+kdb_cpu_status_all(int ccpu, struct cpu_user_regs *regs)
+{
+ int cpu;
+ for_each_online_cpu(cpu) {
+ if (cpu == ccpu) {
+ kdbp("[%d]", ccpu);
+ kdb_display_pc(regs);
+ } else {
+ if (kdb_cpu_cmd[cpu] != KDB_CPU_PAUSE) /* hung cpu */
+ continue;
+ kdb_cpu_cmd[cpu] = KDB_CPU_SHOWPC;
+ while (kdb_cpu_cmd[cpu]==KDB_CPU_SHOWPC);
+ }
+ }
+ return KDB_CPU_MAIN_KDB;
+}
+
+/*
+ * display/switch CPU.
+ * Argument:
+ * none: just go back to initial cpu
+ * cpunum: switch to given vpu
+ * "all": show one line status of all cpus
+ */
+extern volatile int kdb_init_cpu;
+static kdb_cpu_cmd_t
+kdb_usgf_cpu(void)
+{
+ kdbp("cpu [all|num]: none will switch back to initial cpu\n");
+ kdbp(" cpunum to switch to the vcpu. all to show status\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_cpu(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ int cpu;
+ int ccpu = smp_processor_id();
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_cpu();
+
+ if (argc > 1) {
+ if (!strcmp(argv[1], "all"))
+ return kdb_cpu_status_all(ccpu, regs);
+
+ cpu = (int)simple_strtoul(argv[1], NULL, 0); /* handles 0x */
+ if (cpu >= 0 && cpu < NR_CPUS && cpu != ccpu &&
+ cpu_online(cpu) && kdb_cpu_cmd[cpu] == KDB_CPU_PAUSE)
+ {
+ kdbp("Switching to cpu:%d\n", cpu);
+ kdb_cpu_cmd[cpu] = KDB_CPU_MAIN_KDB;
+
+ /* clear any single step on the current cpu */
+ regs->eflags &= ~X86_EFLAGS_TF;
+ return KDB_CPU_PAUSE;
+ } else {
+ if (cpu != ccpu)
+ kdbp("Unable to switch to cpu:%d\n", cpu);
+ else {
+ kdb_display_pc(regs);
+ }
+ return KDB_CPU_MAIN_KDB;
+ }
+ }
+ /* no arg means back to initial cpu */
+ if (!kdb_sys_crash && ccpu != kdb_init_cpu) {
+ if (kdb_cpu_cmd[kdb_init_cpu] == KDB_CPU_PAUSE) {
+ regs->eflags &= ~X86_EFLAGS_TF;
+ kdb_cpu_cmd[kdb_init_cpu] = KDB_CPU_MAIN_KDB;
+ return KDB_CPU_PAUSE;
+ } else
+ kdbp("Unable to switch to: %d\n", kdb_init_cpu);
+ }
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* send NMI to all or given CPU. Must be crashed/fatal state */
+static kdb_cpu_cmd_t
+kdb_usgf_nmi(void)
+{
+ kdbp("nmi cpu#|all: send nmi cpu/s. must reboot when done with kdb\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_nmi(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ cpumask_t cpumask;
+ int ccpu = smp_processor_id();
+
+ if (argc <= 1 || (argc > 1 && *argv[1] == '?'))
+ return kdb_usgf_nmi();
+
+ if (!kdb_sys_crash) {
+ kdbp("kdb: nmi cmd available in crashed state only\n");
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (!strcmp(argv[1], "all"))
+ cpumask = cpu_online_map;
+ else {
+ int cpu = (int)simple_strtoul(argv[1], NULL, 0);
+ if (cpu >= 0 && cpu < NR_CPUS && cpu != ccpu && cpu_online(cpu))
+ cpumask = *cpumask_of(cpu);
+ else {
+ kdbp("KDB nmi: invalid cpu %s\n", argv[1]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ }
+ kdb_nmi_pause_cpus(cpumask);
+ return KDB_CPU_MAIN_KDB;
+}
+
+static kdb_cpu_cmd_t
+kdb_usgf_percpu(void)
+{
+ kdbp("percpu: display per cpu pointers\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_percpu(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_percpu();
+ kdb_dump_time_pcpu();
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* ========================= Breakpoints ==================================== */
+
+static void
+kdb_prnt_bp_cond(int bpnum)
+{
+ struct kdb_bpcond *bpcp = &kdb_sbpa[bpnum].u.bp_cond;
+
+ if (bpcp->bp_cond_status == 1) {
+ kdbp(" ( %s %c%c %lx )\n",
+ kdb_regoffs_to_name(bpcp->bp_cond_lhs),
+ bpcp->bp_cond_type == 1 ? '=' : '!', '=', bpcp->bp_cond_rhs);
+ } else {
+ kdbp(" ( %lx %c%c %lx )\n", bpcp->bp_cond_lhs,
+ bpcp->bp_cond_type == 1 ? '=' : '!', '=', bpcp->bp_cond_rhs);
+ }
+}
+
+static void
+kdb_prnt_bp_extra(int bpnum)
+{
+ if (kdb_sbpa[bpnum].bp_type == 2) {
+ ulong i, arg, *btp = kdb_sbpa[bpnum].u.bp_btp;
+
+ kdbp(" will trace ");
+ for (i=0; i < KDB_MAXBTP && btp[i]; i++)
+ if ((arg=btp[i]) < sizeof (struct cpu_user_regs)) {
+ kdbp(" %s ", kdb_regoffs_to_name(arg));
+ } else {
+ kdbp(" %lx ", arg);
+ }
+ kdbp("\n");
+
+ } else if (kdb_sbpa[bpnum].bp_type == 1)
+ kdb_prnt_bp_cond(bpnum);
+}
+
+/*
+ * List software breakpoints
+ */
+static kdb_cpu_cmd_t
+kdb_display_sbkpts(void)
+{
+ int i;
+ for(i=0; i < KDBMAXSBP; i++)
+ if (kdb_sbpa[i].bp_addr && !kdb_sbpa[i].bp_deleted) {
+ struct domain *dp = kdb_domid2ptr(kdb_sbpa[i].bp_domid);
+
+ if (dp == NULL || dp->is_dying) {
+ memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
+ continue;
+ }
+ kdbp("[%d]: domid:%d 0x%lx ", i,
+ kdb_sbpa[i].bp_domid, kdb_sbpa[i].bp_addr);
+ kdb_prnt_addr2sym(kdb_sbpa[i].bp_domid, kdb_sbpa[i].bp_addr,"\n");
+ kdb_prnt_bp_extra(i);
+ }
+ return KDB_CPU_MAIN_KDB;
+}
+
+/*
+ * Check if any breakpoints that we need to install (delayed install)
+ * Returns: 1 if yes, 0 if none.
+ */
+int
+kdb_swbp_exists(void)
+{
+ int i;
+ for (i=0; i < KDBMAXSBP; i++)
+ if (kdb_sbpa[i].bp_addr && !kdb_sbpa[i].bp_deleted)
+ return 1;
+ return 0;
+}
+/*
+ * Check if any breakpoints were deleted this kdb session
+ * Returns: 0 if none, 1 if yes
+ */
+static int
+kdb_swbp_deleted(void)
+{
+ int i;
+ for (i=0; i < KDBMAXSBP; i++)
+ if (kdb_sbpa[i].bp_addr && kdb_sbpa[i].bp_deleted)
+ return 1;
+ return 0;
+}
+
+/*
+ * Flush deleted sw breakpoints
+ */
+void
+kdb_flush_swbp_table(void)
+{
+ int i;
+ KDBGP("ccpu:%d flush_swbp_table: deleted:%x\n", smp_processor_id(),
+ kdb_swbp_deleted());
+ for(i=0; i < KDBMAXSBP; i++)
+ if (kdb_sbpa[i].bp_addr && kdb_sbpa[i].bp_deleted) {
+ KDBGP("flush:[%x] addr:0x%lx\n",i,kdb_sbpa[i].bp_addr);
+ memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
+ }
+}
+
+/*
+ * Delete/Clear a sw breakpoint
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_bc(void)
+{
+ kdbp("bc $num|all : clear given or all breakpoints\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_bc(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ int i, bpnum = -1, delall = 0;
+ const char *argp;
+
+ if (argc != 2 || *argv[1] == '?')
+ return kdb_usgf_bc();
+
+ if (!kdb_swbp_exists()) {
+ kdbp("No breakpoints are set\n");
+ return KDB_CPU_MAIN_KDB;
+ }
+ argp = argv[1];
+
+ if (!strcmp(argp, "all"))
+ delall = 1;
+ else if (!kdb_str2deci(argp, &bpnum) || bpnum < 0 || bpnum > KDBMAXSBP) {
+ kdbp("Invalid bpnum: %s\n", argp);
+ return KDB_CPU_MAIN_KDB;
+ }
+ for (i=0; i < KDBMAXSBP; i++) {
+ if (delall && kdb_sbpa[i].bp_addr) {
+ kdbp("Deleted breakpoint [%x] addr:0x%lx domid:%d\n",
+ (int)i, kdb_sbpa[i].bp_addr, kdb_sbpa[i].bp_domid);
+ if (kdb_sbpa[i].bp_just_added)
+ memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
+ else
+ kdb_sbpa[i].bp_deleted = 1;
+ continue;
+ }
+ if (bpnum != -1 && bpnum == i) {
+ kdbp("Deleted breakpoint [%x] at 0x%lx domid:%d\n",
+ (int)i, kdb_sbpa[i].bp_addr, kdb_sbpa[i].bp_domid);
+ if (kdb_sbpa[i].bp_just_added)
+ memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
+ else
+ kdb_sbpa[i].bp_deleted = 1;
+ break;
+ }
+ }
+ if (i >= KDBMAXSBP && !delall)
+ kdbp("Unable to delete breakpoint: %s\n", argp);
+
+ return KDB_CPU_MAIN_KDB;
+}
+
+/*
+ * Install a breakpoint in the given array entry
+ * Returns: 0 : failed to install
+ * 1 : installed successfully
+ */
+static int
+kdb_install_swbp(int idx) /* which entry in the bp array */
+{
+ kdbva_t addr = kdb_sbpa[idx].bp_addr;
+ domid_t domid = kdb_sbpa[idx].bp_domid;
+ kdbbyt_t *p = &kdb_sbpa[idx].bp_originst;
+ struct domain *dp = kdb_domid2ptr(domid);
+
+ if (dp == NULL || dp->is_dying) {
+ memset(&kdb_sbpa[idx], 0, sizeof(kdb_sbpa[idx]));
+ kdbp("Removed bp %d addr:%p domid:%d\n", idx, addr, domid);
+ return 0;
+ }
+
+ if (kdb_read_mem(addr, p, KDBBPSZ, domid) != KDBBPSZ){
+ kdbp("Failed(R) to install bp:%x at:0x%lx domid:%d\n",
+ idx, kdb_sbpa[idx].bp_addr, domid);
+ return 0;
+ }
+ if (kdb_write_mem(addr, &kdb_bpinst, KDBBPSZ, domid) != KDBBPSZ) {
+ kdbp("Failed(W) to install bp:%x at:0x%lx domid:%d\n",
+ idx, kdb_sbpa[idx].bp_addr, domid);
+ return 0;
+ }
+ KDBGP("install_swbp: installed bp:%x at:0x%lx ccpu:%x domid:%d\n",
+ idx, kdb_sbpa[idx].bp_addr, smp_processor_id(), domid);
+ return 1;
+}
+
+/*
+ * Install all the software breakpoints
+ */
+void
+kdb_install_all_swbp(void)
+{
+ int i;
+ for(i=0; i < KDBMAXSBP; i++)
+ if (!kdb_sbpa[i].bp_deleted && kdb_sbpa[i].bp_addr)
+ kdb_install_swbp(i);
+}
+
+static void
+kdb_uninstall_a_swbp(int i)
+{
+ kdbva_t addr = kdb_sbpa[i].bp_addr;
+ kdbbyt_t originst = kdb_sbpa[i].bp_originst;
+ domid_t id = kdb_sbpa[i].bp_domid;
+
+ kdb_sbpa[i].bp_just_added = 0;
+ if (!addr)
+ return;
+ if (kdb_write_mem(addr, &originst, KDBBPSZ, id) != KDBBPSZ) {
+ kdbp("Failed to uninstall breakpoint %x at:0x%lx domid:%d\n",
+ i, kdb_sbpa[i].bp_addr, id);
+ }
+}
+
+/*
+ * Uninstall all the software breakpoints at beginning of kdb session
+ */
+void
+kdb_uninstall_all_swbp(void)
+{
+ int i;
+ for(i=0; i < KDBMAXSBP; i++)
+ kdb_uninstall_a_swbp(i);
+ KDBGP("ccpu:%d uninstalled all bps\n", smp_processor_id());
+}
+
+/* RETURNS: rc == 2: condition was not met, rc == 3: condition was met */
+static int
+kdb_check_bp_condition(int bpnum, struct cpu_user_regs *regs, domid_t domid)
+{
+ ulong res = 0, lhsval=0;
+ struct kdb_bpcond *bpcp = &kdb_sbpa[bpnum].u.bp_cond;
+
+ if (bpcp->bp_cond_status == 1) { /* register condition */
+ uint64_t *rp = (uint64_t *)((char *)regs + bpcp->bp_cond_lhs);
+ lhsval = *rp;
+ } else if (bpcp->bp_cond_status == 2) { /* memaddr condition */
+ ulong addr = bpcp->bp_cond_lhs;
+ int num = sizeof(lhsval);
+
+ if (kdb_read_mem(addr, (kdbbyt_t *)&lhsval, num, domid) != num) {
+ kdbp("kdb: unable to read %d bytes at %lx\n", num, addr);
+ return 3;
+ }
+ }
+ if (bpcp->bp_cond_type == 1) /* lhs == rhs */
+ res = (lhsval == bpcp->bp_cond_rhs);
+ else /* lhs != rhs */
+ res = (lhsval != bpcp->bp_cond_rhs);
+
+ if (!res)
+ kdbp("KDB: [%d]Ignoring bp:%d condition not met. val:%lx\n",
+ smp_processor_id(), bpnum, lhsval);
+
+ KDBGP1("bpnum:%d domid:%d cond: %d %d %lx %lx res:%d\n", bpnum, domid,
+ bpcp->bp_cond_status, bpcp->bp_cond_type, bpcp->bp_cond_lhs,
+ bpcp->bp_cond_rhs, res);
+
+ return (res ? 3 : 2);
+}
+
+static void
+kdb_prnt_btp_info(int bpnum, struct cpu_user_regs *regs, domid_t domid)
+{
+ ulong i, arg, val, num, *btp = kdb_sbpa[bpnum].u.bp_btp;
+
+ kdb_prnt_addr2sym(domid, regs->KDBIP, "\n");
+ num = kdb_guest_bitness(domid)/8;
+ for (i=0; i < KDB_MAXBTP && (arg=btp[i]); i++) {
+ if (arg < sizeof (struct cpu_user_regs)) {
+ uint64_t *rp = (uint64_t *)((char *)regs + arg);
+ kdbp(" %s: %016lx ", kdb_regoffs_to_name(arg), *rp);
+ } else {
+ if (kdb_read_mem(arg, (kdbbyt_t *)&val, num, domid) != num)
+ kdbp("kdb: unable to read %d bytes at %lx\n", num, arg);
+ if (num == 8)
+ kdbp(" %016lx:%016lx ", arg, val);
+ else
+ kdbp(" %08lx:%08lx ", arg, val);
+ }
+ }
+ kdbp("\n");
+ KDBGP1("bpnum:%d domid:%d btp:%p num:%d\n", bpnum, domid, btp, num);
+}
+
+/*
+ * Check if the BP trap belongs to us.
+ * Return: 0 : not one of ours. IP not changed. (leave kdb)
+ * 1 : one of ours but deleted. IP decremented. (leave kdb)
+ * 2 : one of ours but condition not met, or btp. IP decremented.(leave)
+ * 3 : one of ours and active. IP decremented. (stay in kdb)
+ */
+int
+kdb_check_sw_bkpts(struct cpu_user_regs *regs)
+{
+ int i, rc=0;
+ domid_t curid;
+
+ curid = guest_mode(regs) ? current->domain->domain_id : DOMID_IDLE;
+ for(i=0; i < KDBMAXSBP; i++) {
+ if (kdb_sbpa[i].bp_domid == curid &&
+ kdb_sbpa[i].bp_addr == (regs->KDBIP- KDBBPSZ)) {
+
+ regs->KDBIP -= KDBBPSZ;
+ rc = 3;
+
+ if (kdb_sbpa[i].bp_ni) {
+ kdb_uninstall_a_swbp(i);
+ memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
+ } else if (kdb_sbpa[i].bp_deleted) {
+ rc = 1;
+ } else if (kdb_sbpa[i].bp_type == 1) {
+ rc = kdb_check_bp_condition(i, regs, curid);
+ } else if (kdb_sbpa[i].bp_type == 2) {
+ kdb_prnt_btp_info(i, regs, curid);
+ rc = 2;
+ }
+ KDBGP1("ccpu:%d rc:%d curid:%d domid:%d addr:%lx\n",
+ smp_processor_id(), rc, curid, kdb_sbpa[i].bp_domid,
+ kdb_sbpa[i].bp_addr);
+ break;
+ }
+ }
+ return (rc);
+}
+
+/* Eg: r6 == 0x123EDF or 0xFFFF2034 != 0xDEADBEEF
+ * regoffs: -1 means lhs is not reg. else offset of reg in cpu_user_regs
+ * addr: memory location if lhs is not register, eg, 0xFFFF2034
+ * condp : points to != or ==
+ * rhsval : right hand side value
+ */
+static void
+kdb_set_bp_cond(int bpnum, int regoffs, ulong addr, char *condp, ulong rhsval)
+{
+ if (bpnum >= KDBMAXSBP) {
+ kdbp("BUG: %s got invalid bpnum\n", __FUNCTION__);
+ return;
+ }
+ if (regoffs != -1) {
+ kdb_sbpa[bpnum].u.bp_cond.bp_cond_status = 1;
+ kdb_sbpa[bpnum].u.bp_cond.bp_cond_lhs = regoffs;
+ } else if (addr != 0) {
+ kdb_sbpa[bpnum].u.bp_cond.bp_cond_status = 2;
+ kdb_sbpa[bpnum].u.bp_cond.bp_cond_lhs = addr;
+ } else {
+ kdbp("error: invalid call to kdb_set_bp_cond\n");
+ return;
+ }
+ kdb_sbpa[bpnum].u.bp_cond.bp_cond_rhs = rhsval;
+
+ if (*condp == '!')
+ kdb_sbpa[bpnum].u.bp_cond.bp_cond_type = 2;
+ else
+ kdb_sbpa[bpnum].u.bp_cond.bp_cond_type = 1;
+}
+
+/* install breakpt at given addr.
+ * ni: bp for next instr
+ * btpa: ptr to args for btp for printing when bp is hit
+ * lhsp/condp/rhsp: point to strings of condition
+ *
+ * RETURNS: the index in array where installed. KDBMAXSBP if error
+ */
+static int
+kdb_set_bp(domid_t domid, kdbva_t addr, int ni, ulong *btpa, char *lhsp,
+ char *condp, char *rhsp)
+{
+ int i, pre_existing = 0, regoffs = -1;
+ ulong memloc=0, rhsval=0, tmpul;
+
+ if (btpa && (lhsp || rhsp || condp)) {
+ kdbp("internal error. btpa and (lhsp || rhsp || condp) set\n");
+ return KDBMAXSBP;
+ }
+ if (lhsp && ((regoffs=kdb_valid_reg(lhsp)) == -1) &&
+ kdb_str2ulong(lhsp, &memloc) &&
+ kdb_read_mem(memloc, (kdbbyt_t *)&tmpul, sizeof(tmpul), domid)==0) {
+
+ kdbp("error: invalid argument: %s\n", lhsp);
+ return KDBMAXSBP;
+ }
+ if (rhsp && ! kdb_str2ulong(rhsp, &rhsval)) {
+ kdbp("error: invalid argument: %s\n", rhsp);
+ return KDBMAXSBP;
+ }
+
+ /* see if bp already set */
+ for (i=0; i < KDBMAXSBP; i++) {
+ if (kdb_sbpa[i].bp_addr==addr && kdb_sbpa[i].bp_domid==domid) {
+
+ if (kdb_sbpa[i].bp_deleted) {
+ /* just re-set this bp again */
+ memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
+ pre_existing = 1;
+ } else {
+ kdbp("Breakpoint already set \n");
+ return KDBMAXSBP;
+ }
+ }
+ }
+ /* see if any room left for another breakpoint */
+ for (i=0; i < KDBMAXSBP; i++)
+ if (!kdb_sbpa[i].bp_addr)
+ break;
+ if (i >= KDBMAXSBP) {
+ kdbp("ERROR: Breakpoint table full....\n");
+ return i;
+ }
+ kdb_sbpa[i].bp_addr = addr;
+ kdb_sbpa[i].bp_domid = domid;
+ if (btpa) {
+ kdb_sbpa[i].bp_type = 2;
+ kdb_sbpa[i].u.bp_btp = btpa;
+ } else if (regoffs != -1 || memloc) {
+ kdb_sbpa[i].bp_type = 1;
+ kdb_set_bp_cond(i, regoffs, memloc, condp, rhsval);
+ } else
+ kdb_sbpa[i].bp_type = 0;
+
+ if (kdb_install_swbp(i)) { /* make sure it can be done */
+ if (ni)
+ return i;
+
+ kdb_uninstall_a_swbp(i); /* dont' show user INT3 */
+ if (!pre_existing) /* make sure no is cpu sitting on it */
+ kdb_sbpa[i].bp_just_added = 1;
+
+ kdbp("bp %d set for domid:%d at: 0x%lx ", i, kdb_sbpa[i].bp_domid,
+ kdb_sbpa[i].bp_addr);
+ kdb_prnt_addr2sym(domid, addr, "\n");
+ kdb_prnt_bp_extra(i);
+ } else {
+ kdbp("ERROR:Can't install bp: 0x%lx domid:%d\n", addr, domid);
+ if (pre_existing) /* in case a cpu is sitting on this bp in traps */
+ kdb_sbpa[i].bp_deleted = 1;
+ else
+ memset(&kdb_sbpa[i], 0, sizeof(kdb_sbpa[i]));
+ return KDBMAXSBP;
+ }
+ /* make sure swbp reporting is enabled in the vmcb/vmcs */
+ if (is_hvm_or_hyb_domain(kdb_domid2ptr(domid))) {
+ struct domain *dp = kdb_domid2ptr(domid);
+ dp->debugger_attached = 1; /* see svm_do_resume/vmx_do_ */
+ KDBGP("debugger_attached set. domid:%d\n", domid);
+ }
+ return i;
+}
+
+/*
+ * Set/List Software Breakpoint/s
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_bp(void)
+{
+ kdbp("bp [addr|sym][domid][condition]: display or set a breakpoint\n");
+ kdbp(" where cond is like: r6 == 0x123F or rax != DEADBEEF or \n");
+ kdbp(" ffff82c48038fe58 == 321E or 0xffff82c48038fe58 != 0\n");
+ kdbp(" regs: rax rbx rcx rdx rsi rdi rbp rsp r8 r9");
+ kdbp(" r10 r11 r12 r13 r14 r15 rflags\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_bp(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ kdbva_t addr;
+ int idx = -1;
+ domid_t domid = DOMID_IDLE;
+ char *domidstrp, *lhsp=NULL, *condp=NULL, *rhsp=NULL;
+
+ if ((argc > 1 && *argv[1] == '?') || argc == 4 || argc > 6)
+ return kdb_usgf_bp();
+
+ if (argc < 2 || kdb_sys_crash) /* list all set breakpoints */
+ return kdb_display_sbkpts();
+
+ /* valid argc either: 2 3 5 or 6
+ * 'bp idle_loop r6 == 0xc000' OR 'bp idle_loop 3 r9 != 0xdeadbeef' */
+ idx = (argc == 5) ? 2 : ((argc == 6) ? 3 : idx);
+ if (argc >= 5 ) {
+ lhsp = (char *)argv[idx];
+ condp = (char *)argv[idx+1];
+ rhsp = (char *)argv[idx+2];
+
+ if (!kdb_str2ulong(rhsp, NULL) || *(condp+1) != '=' ||
+ (*condp != '=' && *condp != '!')) {
+
+ return kdb_usgf_bp();
+ }
+ }
+ domidstrp = (argc == 3 || argc == 6 ) ? (char *)argv[2] : NULL;
+ if (domidstrp && !kdb_str2domid(domidstrp, &domid, 1)) {
+ return kdb_usgf_bp();
+ }
+ if (argc > 3 && is_hvm_or_hyb_domain(kdb_domid2ptr(domid))) {
+ kdbp("HVM domain not supported yet for conditional bp\n");
+ return KDB_CPU_MAIN_KDB;
+ }
+
+ if (!kdb_str2addr(argv[1], &addr, domid) || addr == 0) {
+ kdbp("Invalid argument:%s\n", argv[1]);
+ return KDB_CPU_MAIN_KDB;
+ }
+
+ /* make sure xen addr is in xen text, otherwise bp set in 64bit dom0/U */
+ if (domid == DOMID_IDLE &&
+ (addr < XEN_VIRT_START || addr > XEN_VIRT_END))
+ {
+ kdbp("addr:%lx not in xen text\n", addr);
+ return KDB_CPU_MAIN_KDB;
+ }
+ kdb_set_bp(domid, addr, 0, NULL, lhsp, condp, rhsp); /* 0 is ni flag */
+ return KDB_CPU_MAIN_KDB;
+}
+
+
+/* trace breakpoint, meaning, upon bp trace/print some info and continue */
+
+static kdb_cpu_cmd_t
+kdb_usgf_btp(void)
+{
+ kdbp("btp addr|sym [domid] reg|domid-mem-addr... : breakpoint trace\n");
+ kdbp(" regs: rax rbx rcx rdx rsi rdi rbp rsp r8 r9 ");
+ kdbp("r10 r11 r12 r13 r14 r15 rflags\n");
+ kdbp(" Eg. btp idle_cpu 7 rax rbx 0x20ef5a5 r9\n");
+ kdbp(" will print rax, rbx, *(long *)0x20ef5a5, r9 and continue\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_btp(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ int i, btpidx, numrd, argsidx, regoffs = -1;
+ kdbva_t addr, memloc=0;
+ domid_t domid = DOMID_IDLE;
+ ulong *btpa, tmpul;
+
+ if ((argc > 1 && *argv[1] == '?') || argc < 3)
+ return kdb_usgf_btp();
+
+ argsidx = 2; /* assume 3rd arg is not domid */
+ if (argc > 3 && kdb_str2domid(argv[2], &domid, 0)) {
+
+ if (is_hvm_or_hyb_domain(kdb_domid2ptr(domid))) {
+ kdbp("HVM domains are not currently supprted\n");
+ return KDB_CPU_MAIN_KDB;
+ } else
+ argsidx = 3; /* 3rd arg is a domid */
+ }
+ if (!kdb_str2addr(argv[1], &addr, domid) || addr == 0) {
+ kdbp("Invalid argument:%s\n", argv[1]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ /* make sure xen addr is in xen text, otherwise will trace 64bit dom0/U */
+ if (domid == DOMID_IDLE &&
+ (addr < XEN_VIRT_START || addr > XEN_VIRT_END))
+ {
+ kdbp("addr:%lx not in xen text\n", addr);
+ return KDB_CPU_MAIN_KDB;
+ }
+
+ numrd = kdb_guest_bitness(domid)/8;
+ if (kdb_read_mem(addr, (kdbbyt_t *)&tmpul, numrd, domid) != numrd) {
+ kdbp("Unable to read mem from %s (%lx)\n", argv[1], addr);
+ return KDB_CPU_MAIN_KDB;
+ }
+
+ for (btpidx=0; btpidx < KDBMAXSBP && kdb_btp_ap[btpidx]; btpidx++);
+ if (btpidx >= KDBMAXSBP) {
+ kdbp("error: table full. delete few breakpoints\n");
+ return KDB_CPU_MAIN_KDB;
+ }
+ btpa = kdb_btp_argsa[btpidx];
+ memset(btpa, 0, sizeof(kdb_btp_argsa[0]));
+
+ for (i=0; argv[argsidx]; i++, argsidx++) {
+
+ if (((regoffs=kdb_valid_reg(argv[argsidx])) == -1) &&
+ kdb_str2ulong(argv[argsidx], &memloc) &&
+ (memloc < sizeof (struct cpu_user_regs) ||
+ kdb_read_mem(memloc, (kdbbyt_t *)&tmpul, sizeof(tmpul), domid)==0)){
+
+ kdbp("error: invalid argument: %s\n", argv[argsidx]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (i >= KDB_MAXBTP) {
+ kdbp("error: cannot specify more than %d args\n", KDB_MAXBTP);
+ return KDB_CPU_MAIN_KDB;
+ }
+ btpa[i] = (regoffs == -1) ? memloc : regoffs;
+ }
+
+ i = kdb_set_bp(domid, addr, 0, btpa, 0, 0, 0); /* 0 is ni flag */
+ if (i < KDBMAXSBP)
+ kdb_btp_ap[btpidx] = kdb_btp_argsa[btpidx];
+
+ return KDB_CPU_MAIN_KDB;
+}
+
+/*
+ * Set/List watchpoints, ie, hardware breakpoint/s, in hypervisor
+ * Usage: wp [sym|addr] [w|i] w == write only data watchpoint
+ * i == IO watchpoint (read/write)
+ *
+ * Eg: wp : list all watchpoints set
+ * wp addr : set a read/write wp at given addr
+ * wp addr w : set a write only wp at given addr
+ * wp addr i : set an IO wp at given addr (16bits port #)
+ *
+ * TBD: allow to be set on particular cpu
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_wp(void)
+{
+ kdbp("wp [addr|sym][w|i]: display or set watchpoint. writeonly or IO\n");
+ kdbp("\tnote: watchpoint is triggered after the instruction executes\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_wp(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ kdbva_t addr;
+ domid_t domid = DOMID_IDLE;
+ int rw = 3, len = 4; /* for now just default to 4 bytes len */
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_wp();
+
+ if (argc <= 1 || kdb_sys_crash) { /* list all set watchpoints */
+ kdb_do_watchpoints(0, 0, 0);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (!kdb_str2addr(argv[1], &addr, domid) || addr == 0) {
+ kdbp("Invalid argument:%s\n", argv[1]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (argc > 2) {
+ if (!strcmp(argv[2], "w"))
+ rw = 1;
+ else if (!strcmp(argv[2], "i"))
+ rw = 2;
+ else {
+ return kdb_usgf_wp();
+ }
+ }
+ kdb_do_watchpoints(addr, rw, len);
+ return KDB_CPU_MAIN_KDB;
+}
+
+static kdb_cpu_cmd_t
+kdb_usgf_wc(void)
+{
+ kdbp("wc $num|all : clear given or all watchpoints\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_wc(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ const char *argp;
+ int wpnum; /* wp num to delete. -1 for all */
+
+ if (argc != 2 || *argv[1] == '?')
+ return kdb_usgf_wc();
+
+ argp = argv[1];
+
+ if (!strcmp(argp, "all"))
+ wpnum = -1;
+ else if (!kdb_str2deci(argp, &wpnum)) {
+ kdbp("Invalid wpnum: %s\n", argp);
+ return KDB_CPU_MAIN_KDB;
+ }
+ kdb_clear_wps(wpnum);
+ return KDB_CPU_MAIN_KDB;
+}
+
+static void
+kdb_display_hvm_vcpu(struct vcpu *vp)
+{
+ struct hvm_vcpu *hvp;
+ struct vlapic *vlp;
+ struct hvm_io_op *ioop;
+
+ hvp = &vp->arch.hvm_vcpu;
+ vlp = &hvp->vlapic;
+ kdbp("vcpu:%lx id:%d domid:%d\n", vp, vp->vcpu_id, vp->domain->domain_id);
+
+#if 0
+ if (is_hybrid_vcpu(vp)) {
+ struct hybrid_ext *hp = &hvp->hv_hybrid;
+ kdbp(" &hybrid_ext:%p limit:%x iopl:%x vcpu_info_mfn:%lx\n",
+ hp, hp->hyb_iobmp_limit, hp->hyb_iopl, hp->hyb_vcpu_info_mfn);
+ }
+#endif
+
+ ioop = NULL; /* compiler warning */
+ kdbp(" &hvm_vcpu:%lx guest_efer:"KDBFL"\n", hvp, hvp->guest_efer);
+ kdbp(" guest_cr: [0]:"KDBFL" [1]:"KDBFL" [2]:"KDBFL"\n",
+ hvp->guest_cr[0], hvp->guest_cr[1],hvp->guest_cr[2]);
+ kdbp(" [3]:"KDBFL" [4]:"KDBFL"\n", hvp->guest_cr[3],
+ hvp->guest_cr[4]);
+ kdbp(" hw_cr: [0]:"KDBFL" [1]:"KDBFL" [2]:"KDBFL"\n", hvp->hw_cr[0],
+ hvp->hw_cr[1], hvp->hw_cr[2]);
+ kdbp(" [3]:"KDBFL" [4]:"KDBFL"\n", hvp->hw_cr[3],
+ hvp->hw_cr[4]);
+
+ kdbp(" VLAPIC: base msr:"KDBF64" dis:%x tmrdiv:%x\n",
+ vlp->hw.apic_base_msr, vlp->hw.disabled, vlp->hw.timer_divisor);
+ kdbp(" regs:%p regs_page:%p\n", vlp->regs, vlp->regs_page);
+ kdbp(" periodic time:\n");
+ kdb_prnt_periodic_time(&vlp->pt);
+
+ kdbp(" xen_port:%x flag_dr_dirty:%x dbg_st_latch:%x\n", hvp->xen_port,
+ hvp->flag_dr_dirty, hvp->debug_state_latch);
+
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
+
+ struct arch_vmx_struct *vxp = &hvp->u.vmx;
+ kdbp(" &vmx: %p vmcs:%lx active_cpu:%x launched:%x\n", vxp,
+ vxp->vmcs, vxp->active_cpu, vxp->launched);
+#if XEN_VERSION != 4 /* xen 3.x.x */
+ kdbp(" exec_ctrl:%x vpid:$%d\n", vxp->exec_control, vxp->vpid);
+#endif
+ kdbp(" host_cr0: "KDBFL" vmx: {realm:%x emulate:%x}\n",
+ vxp->host_cr0, vxp->vmx_realmode, vxp->vmx_emulate);
+
+#ifdef __x86_64__
+ kdbp(" &msr_state:%p exception_bitmap:%lx\n", &vxp->msr_state,
+ vxp->exception_bitmap);
+#endif
+ } else if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
+ struct arch_svm_struct *svp = &hvp->u.svm;
+#if XEN_VERSION != 4 /* xen 3.x.x */
+ kdbp(" &svm: vmcb:%lx pa:"KDBF64" asid:"KDBF64"\n", svp, svp->vmcb,
+ svp->vmcb_pa, svp->asid_generation);
+#endif
+ kdbp(" msrpm:%p lnch_core:%x vmcb_sync:%x\n", svp->msrpm,
+ svp->launch_core, svp->vmcb_in_sync);
+ }
+ kdbp(" cachemode:%x io: {state: %x data: "KDBFL"}\n", hvp->cache_mode,
+ hvp->hvm_io.io_state, hvp->hvm_io.io_data);
+ kdbp(" mmio: {gva: "KDBFL" gpfn: "KDBFL"}\n", hvp->hvm_io.mmio_gva,
+ hvp->hvm_io.mmio_gpfn);
+}
+
+/* display struct hvm_vcpu{} in struct vcpu.arch{} */
+static kdb_cpu_cmd_t
+kdb_usgf_vcpuh(void)
+{
+ kdbp("vcpuh vcpu-ptr : display hvm_vcpu struct\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_vcpuh(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ struct vcpu *vp;
+
+ if (argc < 2 || *argv[1] == '?')
+ return kdb_usgf_vcpuh();
+
+ if (!kdb_str2ulong(argv[1], (ulong *)&vp) || !kdb_vcpu_valid(vp) ||
+ !is_hvm_or_hyb_vcpu(vp)) {
+
+ kdbp("kdb: Bad VCPU: %s\n", argv[1]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ kdb_display_hvm_vcpu(vp);
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* also look into arch_get_info_guest() to get context */
+static void
+kdb_print_uregs(struct cpu_user_regs *regs)
+{
+#ifdef __x86_64__
+ kdbp(" rflags: %016lx rip: %016lx\n", regs->rflags, regs->rip);
+ kdbp(" rax: %016lx rbx: %016lx rcx: %016lx\n",
+ regs->rax, regs->rbx, regs->rcx);
+ kdbp(" rdx: %016lx rsi: %016lx rdi: %016lx\n",
+ regs->rdx, regs->rsi, regs->rdi);
+ kdbp(" rbp: %016lx rsp: %016lx r8: %016lx\n",
+ regs->rbp, regs->rsp, regs->r8);
+ kdbp(" r9: %016lx r10: %016lx r11: %016lx\n",
+ regs->r9, regs->r10, regs->r11);
+ kdbp(" r12: %016lx r13: %016lx r14: %016lx\n",
+ regs->r12, regs->r13, regs->r14);
+ kdbp(" r15: %016lx\n", regs->r15);
+ kdbp(" ds: %04x es: %04x fs: %04x gs: %04x "
+ " ss: %04x cs: %04x\n", regs->ds, regs->es, regs->fs,
+ regs->gs, regs->ss, regs->cs);
+ kdbp(" errcode:%08lx entryvec:%08lx upcall_mask:%lx\n",
+ regs->error_code, regs->entry_vector, regs->saved_upcall_mask);
+#else
+ kdbp(" eflags: %016lx eip: 016lx\n", regs->eflags, regs->eip);
+ kdbp(" eax: %08x ebx: %08x ecx: %08x edx: %08x\n",
+ regs->eax, regs->ebx, regs->ecx, regs->edx);
+ kdbp(" esi: %08x edi: %08x ebp: %08x esp: %08x\n",
+ regs->esi, regs->edi, regs->ebp, regs->esp);
+ kdbp(" ds: %04x es: %04x fs: %04x gs: %04x "
+ " ss: %04x cs: %04x\n", regs->ds, regs->es, regs->fs,
+ regs->gs, regs->ss, regs->cs);
+ kdbp(" errcode:%04lx entryvec:%04lx upcall_mask:%lx\n",
+ regs->error_code, regs->entry_vector, regs->saved_upcall_mask);
+#endif
+}
+
+#if XEN_SUBVERSION < 3 /* xen 3.1.x or xen 3.2.x */
+#ifdef CONFIG_COMPAT
+ #undef vcpu_info
+ #define vcpu_info(v, field) \
+ (*(!has_32bit_shinfo((v)->domain) ? \
+ (typeof(&(v)->vcpu_info->compat.field))&(v)->vcpu_info->native.field : \
+ (typeof(&(v)->vcpu_info->compat.field))&(v)->vcpu_info->compat.field))
+
+ #undef __shared_info
+ #define __shared_info(d, s, field) \
+ (*(!has_32bit_shinfo(d) ? \
+ (typeof(&(s)->compat.field))&(s)->native.field : \
+ (typeof(&(s)->compat.field))&(s)->compat.field))
+#endif
+#endif
+
+static void kdb_display_pv_vcpu(struct vcpu *vp)
+{
+ int i;
+ struct pv_vcpu *gp = &vp->arch.pv_vcpu;
+
+ kdbp(" GDT_VIRT_START(vcpu): %lx\n", GDT_VIRT_START(vp));
+ kdbp(" GDT: entries:0x%lx frames:\n", gp->gdt_ents);
+ for (i=0; i < 16; i=i+4)
+ kdbp(" %016lx %016lx %016lx %016lx\n", gp->gdt_frames[i],
+ gp->gdt_frames[i+1], gp->gdt_frames[i+2],gp->gdt_frames[i+3]);
+
+ kdbp(" trap_ctxt:%lx kernel_ss:%lx kernel_sp:%lx\n", gp->trap_ctxt,
+ gp->kernel_ss, gp->kernel_sp);
+ kdbp(" ctrlregs:\n");
+ for (i=0; i < 8; i=i+4)
+ kdbp(" %016lx %016lx %016lx %016lx\n", gp->ctrlreg[i],
+ gp->ctrlreg[i+1], gp->ctrlreg[i+2], gp->ctrlreg[i+3]);
+#ifdef __x86_64__
+ kdbp(" callback: event: %016lx failsafe: %016lx\n",
+ gp->event_callback_eip, gp->failsafe_callback_eip);
+ kdbp(" base: fs:0x%lx gskern:0x%lx gsuser:0x%lx\n",
+ gp->fs_base, gp->gs_base_kernel, gp->gs_base_user);
+#else
+ kdbp(" callback: event: %08lx:%08lx failsafe: %08lx:%08lx\n",
+ gp->event_callback_cs, gp->event_callback_eip,
+ gp->failsafe_callback_cs, gp->failsafe_callback_eip);
+#endif
+ kdbp(" vcpu_info_mfn: %lx iopl: %x\n", gp->vcpu_info_mfn, gp->iopl);
+ kdbp("\n");
+}
+
+/* Display one VCPU info */
+static void
+kdb_display_vcpu(struct vcpu *vp)
+{
+ int i;
+ struct arch_vcpu *avp = &vp->arch;
+ struct paging_vcpu *pvp = &vp->arch.paging;
+ int domid = vp->domain->domain_id;
+
+ kdbp("\nVCPU: vcpu-id:%d vcpu-ptr:%p ", vp->vcpu_id, vp);
+ kdbp(" processor:%d domid:%d domp:%p\n", vp->processor, domid,vp->domain);
+
+ if (domid == DOMID_IDLE) {
+ kdbp(" IDLE vcpu.\n");
+ return;
+ }
+ kdbp(" pause: flags:0x%016lx count:%x\n", vp->pause_flags,
+ vp->pause_count.counter);
+ kdbp(" vcpu: initdone:%d running:%d\n",
+ vp->is_initialised, vp->is_running);
+ kdbp(" mcepend:%d nmipend:%d shut: def:%d paused:%d\n",
+ vp->mce_pending, vp->nmi_pending, vp->defer_shutdown,
+ vp->paused_for_shutdown);
+ kdbp(" &vcpu_info:%p : evtchn_upc_pend:%x _mask:%x\n",
+ vp->vcpu_info, vcpu_info(vp, evtchn_upcall_pending),
+ vcpu_info(vp, evtchn_upcall_mask));
+ kdbp(" evt_pend_sel:%lx poll_evtchn:%x ",
+ *(unsigned long *)&vcpu_info(vp, evtchn_pending_sel), vp->poll_evtchn);
+ kdb_print_spin_lock("virq_lock:", &vp->virq_lock, "\n");
+ for (i=0; i < NR_VIRQS; i++)
+ if (vp->virq_to_evtchn[i] != 0)
+ kdbp(" virq:$%d port:$%d\n", i, vp->virq_to_evtchn[i]);
+
+ kdbp(" next:%p periodic: period:0x%lx last_event:0x%lx\n",
+ vp->next_in_list, vp->periodic_period, vp->periodic_last_event);
+ kdbp(" cpu_affinity:0x%lx vcpu_dirty_cpumask:%p sched_priv:0x%p\n",
+ vp->cpu_affinity, vp->vcpu_dirty_cpumask, vp->sched_priv);
+ kdbp(" &runstate: %p state: %x (eg. RUNSTATE_running) guestptr:%p\n",
+ &vp->runstate, vp->runstate.state, runstate_guest(vp));
+ kdbp("\n");
+ kdbp(" arch info: (%p)\n", &vp->arch);
+ kdbp(" guest_context: VGCF_ flags:%lx",
+ vp->arch.vgc_flags); /* VGCF_in_kernel */
+ if (is_hvm_or_hyb_vcpu(vp))
+ kdbp(" (HVM guest: IP, SP, EFLAGS may be stale)");
+ kdbp("\n");
+ kdb_print_uregs(&vp->arch.user_regs);
+ kdbp(" debugregs:\n");
+ for (i=0; i < 8; i=i+4)
+ kdbp(" %016lx %016lx %016lx %016lx\n", avp->debugreg[i],
+ avp->debugreg[i+1], avp->debugreg[i+2], avp->debugreg[i+3]);
+
+ if (is_hvm_or_hyb_vcpu(vp))
+ kdb_display_hvm_vcpu(vp);
+ else
+ kdb_display_pv_vcpu(vp);
+
+ kdbp(" TF_flags: %016lx guest_table: %016lx cr3:%016lx\n",
+ vp->arch.flags, vp->arch.guest_table.pfn, avp->cr3);
+ kdbp(" paging: \n");
+ kdbp(" vtlb:%p\n", &pvp->vtlb);
+ kdbp(" &pg_mode:%p gstlevels:%d &shadow:%p shlevels:%d\n",
+ pvp->mode, pvp->mode->guest_levels, &pvp->mode->shadow,
+ pvp->mode->shadow.shadow_levels);
+ kdbp(" shadow_vcpu:\n");
+ kdbp(" guest_vtable:%p last em_mfn:"KDBFL"\n",
+ pvp->shadow.guest_vtable, pvp->shadow.last_emulated_mfn);
+#if CONFIG_PAGING_LEVELS >= 3
+ kdbp(" l3tbl: 3:"KDBFL" 2:"KDBFL"\n"
+ " 1:"KDBFL" 0:"KDBFL"\n",
+ pvp->shadow.l3table[3].l3, pvp->shadow.l3table[2].l3,
+ pvp->shadow.l3table[1].l3, pvp->shadow.l3table[0].l3);
+ kdbp(" gl3tbl: 3:"KDBFL" 2:"KDBFL"\n"
+ " 1:"KDBFL" 0:"KDBFL"\n",
+ pvp->shadow.gl3e[3].l3, pvp->shadow.gl3e[2].l3,
+ pvp->shadow.gl3e[1].l3, pvp->shadow.gl3e[0].l3);
+#endif
+ kdbp(" gdbsx_vcpu_event:%x\n", vp->arch.gdbsx_vcpu_event);
+}
+
+/*
+ * FUNCTION: Dispaly (current) VCPU/s
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_vcpu(void)
+{
+ kdbp("vcpu [vcpu-ptr] : display current/vcpu-ptr vcpu info\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_vcpu(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ struct vcpu *v = current;
+
+ if (argc > 2 || (argc > 1 && *argv[1] == '?'))
+ kdb_usgf_vcpu();
+ else if (argc <= 1)
+ kdb_display_vcpu(v);
+ else if (kdb_str2ulong(argv[1], (ulong *)&v) && kdb_vcpu_valid(v))
+ kdb_display_vcpu(v);
+ else
+ kdbp("Invalid usage/argument:%s v:%lx\n", argv[1], (long)v);
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* from paging_dump_domain_info() */
+static void kdb_pr_dom_pg_modes(struct domain *d)
+{
+ if (paging_mode_enabled(d)) {
+ kdbp(" paging mode enabled");
+ if ( paging_mode_shadow(d) )
+ kdbp(" shadow(PG_SH_enable)");
+ if ( paging_mode_hap(d) )
+ kdbp(" hap(PG_HAP_enable) ");
+ if ( paging_mode_refcounts(d) )
+ kdbp(" refcounts(PG_refcounts) ");
+ if ( paging_mode_log_dirty(d) )
+ kdbp(" log_dirty(PG_log_dirty) ");
+ if ( paging_mode_translate(d) )
+ kdbp(" translate(PG_translate) ");
+ if ( paging_mode_external(d) )
+ kdbp(" external(PG_external) ");
+ } else
+ kdbp(" disabled");
+ kdbp("\n");
+}
+
+/* print event channels info for a given domain
+ * NOTE: very confusing, port and event channel refer to the same thing. evtchn
+ * is arry of pointers to a bucket of pointers to 128 struct evtchn{}. while
+ * 64bit xen can handle 4096 max channels, a 32bit guest is limited to 1024 */
+static void noinline kdb_print_dom_eventinfo(struct domain *dp)
+{
+ uint chn;
+
+ kdbp("\n");
+ kdbp(" Evt: MAX_EVTCHNS:$%d ptr:%p pollmsk:%08lx ",
+ MAX_EVTCHNS(dp), dp->evtchn, dp->poll_mask[0]);
+ kdb_print_spin_lock("lk:", &dp->event_lock, "\n");
+ kdbp(" &evtchn_pending:%p &evtchn_mask:%p\n",
+ shared_info(dp, evtchn_pending), shared_info(dp, evtchn_mask));
+
+ kdbp(" Channels info: (everything is in decimal):\n");
+ for (chn=0; chn < MAX_EVTCHNS(dp); chn++ ) {
+ struct evtchn *bktp = dp->evtchn[chn/EVTCHNS_PER_BUCKET];
+ struct evtchn *chnp = &bktp[chn & (EVTCHNS_PER_BUCKET-1)];
+ char pbit = test_bit(chn, &shared_info(dp, evtchn_pending)) ? 'Y' : 'N';
+ char mbit = test_bit(chn, &shared_info(dp, evtchn_mask)) ? 'Y' : 'N';
+
+ if (bktp==NULL || chnp->state==ECS_FREE)
+ continue;
+
+ kdbp(" chn:%4u st:%d _xen=%d _vcpu_id:%2d ", chn, chnp->state,
+ chnp->xen_consumer, chnp->notify_vcpu_id);
+ if (chnp->state == ECS_UNBOUND)
+ kdbp(" rem-domid:%d", chnp->u.unbound.remote_domid);
+ else if (chnp->state == ECS_INTERDOMAIN)
+ kdbp(" rem-port:%d rem-dom:%d", chnp->u.interdomain.remote_port,
+ chnp->u.interdomain.remote_dom->domain_id);
+ else if (chnp->state == ECS_PIRQ)
+ kdbp(" pirq:%d", chnp->u.pirq);
+ else if (chnp->state == ECS_VIRQ)
+ kdbp(" virq:%d", chnp->u.virq);
+
+ kdbp(" pend:%c mask:%c\n", pbit, mbit);
+ }
+#if 0
+ kdbp("pirq to evtchn mapping (pirq:evtchn) (all decimal):\n");
+ for (i=0; i < dp->nr_pirqs; i ++)
+ if (dp->pirq_to_evtchn[i])
+ kdbp("(%d:%d) ", i, dp->pirq_to_evtchn[i]);
+ kdbp("\n");
+#endif
+}
+
+static void kdb_prnt_hvm_dom_info(struct domain *dp)
+{
+ struct hvm_domain *hvp = &dp->arch.hvm_domain;
+
+ kdbp(" HVM info: Hap is%s enabled\n",
+ dp->arch.hvm_domain.hap_enabled ? "" : " not");
+
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
+ struct vmx_domain *vdp = &dp->arch.hvm_domain.vmx;
+ kdbp(" EPT: ept_mt:%x ept_wl:%x asr:%013lx\n",
+ vdp->ept_control.ept_mt, vdp->ept_control.ept_wl,
+ vdp->ept_control.asr);
+ }
+ if (hvp == NULL)
+ return;
+
+ if (hvp->irq.callback_via_type == HVMIRQ_callback_vector)
+ kdbp(" HVMIRQ_callback_vector: %x\n", hvp->irq.callback_via.vector);
+
+ if (!is_hvm_domain(dp))
+ return;
+
+ kdbp(" HVM PARAMS (all in hex):\n");
+ kdbp("\tioreq.page:%lx ioreq.va:%lx\n", hvp->ioreq.page, hvp->ioreq.va);
+ kdbp("\tbuf_ioreq.page:%lx ioreq.va:%lx\n", hvp->buf_ioreq.page,
+ hvp->buf_ioreq.va);
+ kdbp("\tHVM_PARAM_CALLBACK_IRQ: %x\n", hvp->params[HVM_PARAM_CALLBACK_IRQ]);
+ kdbp("\tHVM_PARAM_STORE_PFN: %x\n", hvp->params[HVM_PARAM_STORE_PFN]);
+ kdbp("\tHVM_PARAM_STORE_EVTCHN: %x\n", hvp->params[HVM_PARAM_STORE_EVTCHN]);
+ kdbp("\tHVM_PARAM_PAE_ENABLED: %x\n", hvp->params[HVM_PARAM_PAE_ENABLED]);
+ kdbp("\tHVM_PARAM_IOREQ_PFN: %x\n", hvp->params[HVM_PARAM_IOREQ_PFN]);
+ kdbp("\tHVM_PARAM_BUFIOREQ_PFN: %x\n", hvp->params[HVM_PARAM_BUFIOREQ_PFN]);
+ kdbp("\tHVM_PARAM_VIRIDIAN: %x\n", hvp->params[HVM_PARAM_VIRIDIAN]);
+ kdbp("\tHVM_PARAM_TIMER_MODE: %x\n", hvp->params[HVM_PARAM_TIMER_MODE]);
+ kdbp("\tHVM_PARAM_HPET_ENABLED: %x\n", hvp->params[HVM_PARAM_HPET_ENABLED]);
+ kdbp("\tHVM_PARAM_IDENT_PT: %x\n", hvp->params[HVM_PARAM_IDENT_PT]);
+ kdbp("\tHVM_PARAM_DM_DOMAIN: %x\n", hvp->params[HVM_PARAM_DM_DOMAIN]);
+ kdbp("\tHVM_PARAM_ACPI_S_STATE: %x\n", hvp->params[HVM_PARAM_ACPI_S_STATE]);
+ kdbp("\tHVM_PARAM_VM86_TSS: %x\n", hvp->params[HVM_PARAM_VM86_TSS]);
+ kdbp("\tHVM_PARAM_VPT_ALIGN: %x\n", hvp->params[HVM_PARAM_VPT_ALIGN]);
+ kdbp("\tHVM_PARAM_CONSOLE_PFN: %x\n", hvp->params[HVM_PARAM_CONSOLE_PFN]);
+ kdbp("\tHVM_PARAM_CONSOLE_EVTCHN: %x\n",
+ hvp->params[HVM_PARAM_CONSOLE_EVTCHN]);
+ kdbp("\tHVM_PARAM_ACPI_IOPORTS_LOCATION: %x\n",
+ hvp->params[HVM_PARAM_ACPI_IOPORTS_LOCATION]);
+ kdbp("\tHVM_PARAM_MEMORY_EVENT_SINGLE_STEP: %x\n",
+ hvp->params[HVM_PARAM_MEMORY_EVENT_SINGLE_STEP]);
+}
+static void kdb_print_rangesets(struct domain *dp)
+{
+ int locked = spin_is_locked(&dp->rangesets_lock);
+
+ if (locked)
+ spin_unlock(&dp->rangesets_lock);
+ rangeset_domain_printk(dp);
+ if (locked)
+ spin_lock(&dp->rangesets_lock);
+}
+
+static void kdb_pr_vtsc_info(struct arch_domain *ap)
+{
+ kdbp(" VTSC info: tsc_mode:%x vtsc:%x vtsc_last:%016lx\n",
+ ap->tsc_mode, ap->vtsc, ap->vtsc_last);
+ kdbp(" vtsc_offset:%016lx tsc_khz:%08lx incarnation:%x\n",
+ ap->vtsc_offset, ap->vtsc_offset, ap->incarnation);
+ kdbp(" vtsc_kerncount:%016lx _usercount:%016lx\n",
+ ap->vtsc_kerncount, ap->vtsc_usercount);
+}
+
+/* display one domain info */
+static void
+kdb_display_dom(struct domain *dp)
+{
+ struct vcpu *vp;
+ int printed = 0;
+ struct grant_table *gp = dp->grant_table;
+ struct arch_domain *ap = &dp->arch;
+
+ kdbp("\nDOMAIN : domid:0x%04x ptr:0x%p\n", dp->domain_id, dp);
+ if (dp->domain_id == DOMID_IDLE) {
+ kdbp(" IDLE domain.\n");
+ return;
+ }
+ if (dp->is_dying) {
+ kdbp(" domain is DYING.\n");
+ return;
+ }
+#if 0
+ kdb_print_spin_lock(" pgalk:", &dp->page_alloc_lock, "\n");
+ kdbp(" pglist: 0x%p 0x%p\n", dp->page_list.next,KDB_PGLLE(dp->page_list));
+ kdbp(" xpglist: 0x%p 0x%p\n", dp->xenpage_list.next,
+ KDB_PGLLE(dp->xenpage_list));
+ kdbp(" next:0x%p hashnext:0x%p\n",
+ dp->next_in_list, dp->next_in_hashbucket);
+#endif
+ kdbp(" PAGES: tot:0x%08x max:0x%08x xenheap:0x%08x\n",
+ dp->tot_pages, dp->max_pages, dp->xenheap_pages);
+
+ kdb_print_rangesets(dp);
+ kdb_print_dom_eventinfo(dp);
+ kdbp("\n");
+ kdbp(" Grant table: gp:0x%p\n", gp);
+ if (gp) {
+ kdbp(" nr_frames:0x%08x shpp:0x%p active:0x%p\n",
+ gp->nr_grant_frames, gp->shared_raw, gp->active);
+ kdbp(" maptrk:0x%p maphd:0x%08x maplmt:0x%08x\n",
+ gp->maptrack, gp->maptrack_head, gp->maptrack_limit);
+ kdbp(" mapcnt:");
+ kdb_print_spin_lock("mapcnt: lk:", &gp->lock, "\n");
+ }
+ kdbp(" hvm:%d priv:%d need_iommu:%d dbg:%d dying:%d paused:%d\n",
+ dp->is_hvm, dp->is_privileged, dp->need_iommu,
+ dp->debugger_attached, dp->is_dying, dp->is_paused_by_controller);
+ kdb_print_spin_lock(" shutdown: lk:", &dp->shutdown_lock, "\n");
+ kdbp(" shutn:%d shut:%d code:%d \n", dp->is_shutting_down,
+ dp->is_shut_down, dp->shutdown_code);
+ kdbp(" pausecnt:0x%08x vm_assist:0x"KDBFL" refcnt:0x%08x\n",
+ dp->pause_count.counter, dp->vm_assist, dp->refcnt.counter);
+ kdbp(" &domain_dirty_cpumask:%p\n", &dp->domain_dirty_cpumask);
+
+ kdbp(" shared == vcpu_info[]: %p\n", dp->shared_info);
+ kdbp(" arch_shared: maxpfn: %lx pfn-mfn-frame-ll mfn: %lx\n",
+ arch_get_max_pfn(dp), arch_get_pfn_to_mfn_frame_list_list(dp));
+ kdbp("\n");
+ kdbp(" arch_domain at : %p\n", ap);
+
+#ifdef CONFIG_X86_64
+ kdbp(" pt_pages:0x%p ", ap->mm_perdomain_pt_pages);
+ kdbp(" l2:0x%p l3:0x%p\n", ap->mm_perdomain_l2, ap->mm_perdomain_l3);
+#else
+ kdbp(" pt:0x%p ", ap->mm_perdomain_pt);
+#endif
+#ifdef CONFIG_X86_32
+ kdbp(" &mapchache:0x%xp\n", &ap->mapcache);
+#endif
+ kdbp(" ioport:0x%p &hvm_dom:0x%p\n", ap->ioport_caps, &ap->hvm_domain);
+ if (is_hvm_or_hyb_domain(dp))
+ kdb_prnt_hvm_dom_info(dp);
+
+ kdbp(" &pging_dom:%p mode: %lx", &ap->paging, ap->paging.mode);
+ kdb_pr_dom_pg_modes(dp);
+ kdbp(" p2m ptr:%p pages:{%p, %p}\n", ap->p2m, ap->p2m->pages.next,
+ KDB_PGLLE(ap->p2m->pages));
+ kdbp(" max_mapped_pfn:"KDBFL, ap->p2m->max_mapped_pfn);
+#if XEN_SUBVERSION > 0 && XEN_VERSION == 4 /* xen 4.1 and above */
+ kdbp(" phys_table:%p\n", ap->p2m->phys_table.pfn);
+#else
+ kdbp(" phys_table.pfn:"KDBFL"\n", ap->phys_table.pfn);
+#endif
+ kdbp(" physaddr_bitsz:%d 32bit_pv:%d has_32bit_shinfo:%d\n",
+ ap->physaddr_bitsize, ap->is_32bit_pv, ap->has_32bit_shinfo);
+ kdb_pr_vtsc_info(ap);
+ kdbp(" sched:0x%p &handle:0x%p\n", dp->sched_priv, &dp->handle);
+ kdbp(" vcpu ptrs:\n ");
+ for_each_vcpu(dp, vp) {
+ kdbp(" %d:%p", vp->vcpu_id, vp);
+ if (++printed % 4 == 0) kdbp("\n ");
+ }
+ kdbp("\n");
+}
+
+/*
+ * FUNCTION: Dispaly (current) domain/s
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_dom(void)
+{
+ kdbp("dom [all|domid]: Display current/all/given domain/s\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dom(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ int id;
+ struct domain *dp = current->domain;
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_dom();
+
+ if (argc > 1) {
+ for(dp=domain_list; dp; dp=dp->next_in_list)
+ if (kdb_str2deci(argv[1], &id) && dp->domain_id==id)
+ kdb_display_dom(dp);
+ else if (!strcmp(argv[1], "all"))
+ kdb_display_dom(dp);
+ } else {
+ kdbp("Displaying current domain :\n");
+ kdb_display_dom(dp);
+ }
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* Dump irq desc table */
+static kdb_cpu_cmd_t
+kdb_usgf_dirq(void)
+{
+ kdbp("dirq : dump irq bindings\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dirq(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ unsigned long irq, sz, offs, addr;
+ char buf[KSYM_NAME_LEN+1];
+ char affstr[NR_CPUS/4+NR_CPUS/32+2]; /* courtesy dump_irqs() */
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_dirq();
+
+#if XEN_VERSION < 4 && XEN_SUBVERSION < 5 /* xen 3.4.x or below */
+ kdbp("idx/irq#/status: all are in decimal\n");
+ kdbp("idx irq# status action(handler name devid)\n");
+ for (irq=0; irq < NR_VECTORS; irq++) {
+ irq_desc_t *dp = &irq_desc[irq];
+ if (!dp->action)
+ continue;
+ addr = (unsigned long)dp->action->handler;
+ kdbp("[%3ld]:irq:%3d st:%3d f:%s devnm:%s devid:0x%p\n",
+ i, vector_to_irq(irq), dp->status, (dp->status & IRQ_GUEST) ?
+ "GUEST IRQ" : symbols_lookup(addr, &sz, &offs, buf),
+ dp->action->name, dp->action->dev_id);
+ }
+#else
+ kdbp("irq_desc[]:%p nr_irqs: $%d nr_irqs_gsi: $%d\n", irq_desc, nr_irqs,
+ nr_irqs_gsi);
+ kdbp("irq/vec#/status: in decimal. affinity in hex, not bitmap\n");
+ kdbp("irq-- vec sta function----------- name---- type--------- ");
+ kdbp("aff devid------------\n");
+ for (irq=0; irq < nr_irqs; irq++) {
+ void *devidp;
+ const char *symp, *nmp;
+ irq_desc_t *dp = irq_to_desc(irq);
+ struct arch_irq_desc *archp = &dp->arch;
+
+ if (!dp->handler || dp->handler==&no_irq_type || dp->status & IRQ_GUEST)
+ continue;
+
+ addr = dp->action ? (unsigned long)dp->action->handler : 0;
+ symp = addr ? symbols_lookup(addr, &sz, &offs, buf) : "n/a ";
+ nmp = addr ? dp->action->name : "n/a ";
+ devidp = addr ? dp->action->dev_id : NULL;
+ cpumask_scnprintf(affstr, sizeof(affstr), dp->affinity);
+ kdbp("[%3ld] %03d %03d %-19s %-8s %-13s %3s 0x%p\n", irq, archp->vector,
+ dp->status, symp, nmp, dp->handler->typename, affstr, devidp);
+ }
+ kdb_prnt_guest_mapped_irqs();
+#endif
+ return KDB_CPU_MAIN_KDB;
+}
+
+static void
+kdb_prnt_vec_irq_table(int cpu)
+{
+ int i,j, *tbl = per_cpu(vector_irq, cpu);
+
+ kdbp("CPU %d : ", cpu);
+ for (i=0, j=0; i < NR_VECTORS; i++)
+ if (tbl[i] != -1) {
+ kdbp("(%3d:%3d) ", i, tbl[i]);
+ if (!(++j % 5))
+ kdbp("\n ");
+ }
+ kdbp("\n");
+}
+
+/* Dump irq desc table */
+static kdb_cpu_cmd_t
+kdb_usgf_dvit(void)
+{
+ kdbp("dvit [cpu|all]: dump (per cpu)vector irq table\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dvit(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ int cpu, ccpu = smp_processor_id();
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_dvit();
+
+ if (argc > 1) {
+ if (!strcmp(argv[1], "all"))
+ cpu = -1;
+ else if (!kdb_str2deci(argv[1], &cpu)) {
+ kdbp("Invalid cpu:%d\n", cpu);
+ return kdb_usgf_dvit();
+ }
+ } else
+ cpu = ccpu;
+
+ kdbp("Per CPU vector irq table pairs (vector:irq) (all decimals):\n");
+ if (cpu != -1)
+ kdb_prnt_vec_irq_table(cpu);
+ else
+ for_each_online_cpu(cpu)
+ kdb_prnt_vec_irq_table(cpu);
+
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* do vmexit on all cpu's so intel VMCS can be dumped */
+static kdb_cpu_cmd_t
+kdb_all_cpu_flush_vmcs(void)
+{
+ int cpu, ccpu = smp_processor_id();
+ for_each_online_cpu(cpu) {
+ if (cpu == ccpu) {
+ kdb_curr_cpu_flush_vmcs();
+ } else {
+ if (kdb_cpu_cmd[cpu] != KDB_CPU_PAUSE){ /* hung cpu */
+ kdbp("Skipping (hung?) cpu %d\n", cpu);
+ continue;
+ }
+ kdb_cpu_cmd[cpu] = KDB_CPU_DO_VMEXIT;
+ while (kdb_cpu_cmd[cpu]==KDB_CPU_DO_VMEXIT);
+ }
+ }
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* Display VMCS or VMCB */
+static kdb_cpu_cmd_t
+kdb_usgf_dvmc(void)
+{
+ kdbp("dvmc [domid][vcpuid] : Dump vmcs/vmcb\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dvmc(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ domid_t domid = 0; /* unsigned type don't like -1 */
+ int vcpuid = -1;
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_dvmc();
+
+ if (argc > 1) {
+ if (!kdb_str2domid(argv[1], &domid, 1))
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (argc > 2 && !kdb_str2deci(argv[2], &vcpuid)) {
+ kdbp("Bad vcpuid: 0x%x\n", vcpuid);
+ return KDB_CPU_MAIN_KDB;
+ }
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
+ kdb_all_cpu_flush_vmcs();
+ kdb_dump_vmcs(domid, (int)vcpuid);
+ } else {
+ kdb_dump_vmcb(domid, (int)vcpuid);
+ }
+ return KDB_CPU_MAIN_KDB;
+}
+
+static kdb_cpu_cmd_t
+kdb_usgf_mmio(void)
+{
+ kdbp("mmio: dump mmio related info\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_mmio(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_mmio();
+
+ kdbp("r/o mmio ranges:\n");
+ rangeset_printk(mmio_ro_ranges);
+ kdbp("\n");
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* Dump timer/timers queues */
+static kdb_cpu_cmd_t
+kdb_usgf_dtrq(void)
+{
+ kdbp("dtrq: dump timer queues on all cpus\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dtrq(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_dtrq();
+
+ kdb_dump_timer_queues();
+ return KDB_CPU_MAIN_KDB;
+}
+
+struct idte {
+ uint16_t offs0_15;
+ uint16_t selector;
+ uint16_t meta;
+ uint16_t offs16_31;
+ uint32_t offs32_63;
+ uint32_t resvd;
+};
+
+#ifdef __x86_64__
+static void
+kdb_print_idte(int num, struct idte *idtp)
+{
+ uint16_t mta = idtp->meta;
+ char dpl = ((mta & 0x6000) >> 13);
+ char present = ((mta &0x8000) >> 15);
+ int tval = ((mta &0x300) >> 8);
+ char *type = (tval == 1) ? "Task" : ((tval== 2) ? "Intr" : "Trap");
+ domid_t domid = idtp->selector==__HYPERVISOR_CS64 ? DOMID_IDLE :
+ current->domain->domain_id;
+ uint64_t addr = idtp->offs0_15 | ((uint64_t)idtp->offs16_31 << 16) |
+ ((uint64_t)idtp->offs32_63 << 32);
+
+ kdbp("[%03d]: %s %x %x %04x:%016lx ", num, type, dpl, present,
+ idtp->selector, addr);
+ kdb_prnt_addr2sym(domid, addr, "\n");
+}
+
+/* Dump 64bit idt table currently on this cpu. Intel Vol 3 section 5.14.1 */
+static kdb_cpu_cmd_t
+kdb_usgf_didt(void)
+{
+ kdbp("didt : dump IDT table on the current cpu\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_didt(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ int i;
+ struct idte *idtp = (struct idte *)idt_tables[smp_processor_id()];
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_didt();
+
+ kdbp("IDT at:%p\n", idtp);
+ kdbp("idt# Type DPL P addr (all hex except idt#)\n", idtp);
+ for (i=0; i < 256; i++, idtp++)
+ kdb_print_idte(i, idtp);
+ return KDB_CPU_MAIN_KDB;
+}
+#else
+static kdb_cpu_cmd_t
+kdb_cmdf_didt(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ kdbp("kdb: Please implement me in 32bit hypervisor\n");
+ return KDB_CPU_MAIN_KDB;
+}
+#endif
+
+struct gdte { /* same for TSS and LDT */
+ ulong limit0:16;
+ ulong base0:24; /* linear address base, not pa */
+ ulong acctype:4; /* Type: access rights */
+ ulong S:1; /* S: 0 = system, 1 = code/data */
+ ulong DPL:2; /* DPL */
+ ulong P:1; /* P: Segment Present */
+ ulong limit1:4;
+ ulong AVL:1; /* AVL: avail for use by system software */
+ ulong L:1; /* L: 64bit code segment */
+ ulong DB:1; /* D/B */
+ ulong G:1; /* G: granularity */
+ ulong base1:8; /* linear address base, not pa */
+};
+
+union gdte_u {
+ struct gdte gdte;
+ u64 gval;
+};
+
+struct call_gdte {
+ unsigned short offs0:16;
+ unsigned short sel:16;
+ unsigned short misc0:16;
+ unsigned short offs1:16;
+};
+
+struct idt_gdte {
+ unsigned long offs0:16;
+ unsigned long sel:16;
+ unsigned long ist:3;
+ unsigned long unused0:13;
+ unsigned long offs1:16;
+};
+union sgdte_u {
+ struct call_gdte cgdte;
+ struct idt_gdte igdte;
+ u64 sgval;
+};
+
+/* return binary form of a hex in string : max 4 chars 0000 to 1111 */
+static char *kdb_ret_acctype(uint acctype)
+{
+ static char buf[16];
+ char *p = buf;
+ int i;
+
+ if (acctype > 0xf) {
+ buf[0] = buf[1] = buf[2] = buf[3] = '?';
+ buf[5] = '\n';
+ return buf;
+ }
+ for (i=0; i < 4; i++, p++, acctype=acctype>>1)
+ *p = (acctype & 0x1) ? '1' : '0';
+
+ return buf;
+}
+
+/* Display GDT table. IA-32e mode is assumded. */
+/* first display non system descriptors then display system descriptors */
+static kdb_cpu_cmd_t
+kdb_usgf_dgdt(void)
+{
+ kdbp("dgdt [gdt-ptr decimal-byte-size] dump GDT table on current cpu or for"
+ "given vcpu\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dgdt(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ struct Xgt_desc_struct desc;
+ union gdte_u u1;
+ ulong start_addr, end_addr, taddr=0;
+ domid_t domid = DOMID_IDLE;
+ int idx;
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_dgdt();
+
+ if (argc > 1) {
+ if (argc != 3)
+ return kdb_usgf_dgdt();
+
+ if (kdb_str2ulong(argv[1], (ulong *)&start_addr) &&
+ kdb_str2deci(argv[2], (int *)&taddr)) {
+ end_addr = start_addr + taddr;
+ } else {
+ kdbp("dgdt: Bad arg:%s or %s\n", argv[1], argv[2]);
+ return kdb_usgf_dgdt();
+ }
+ } else {
+ __asm__ __volatile__ ("sgdt (%0) \n" :: "a"(&desc) : "memory");
+ start_addr = (ulong)desc.address;
+ end_addr = (ulong)desc.address + desc.size;
+ }
+ kdbp("GDT: Will skip null desc at 0, start:%lx end:%lx\n", start_addr,
+ end_addr);
+ kdbp("[idx] sel --- val -------- Accs DPL P AVL L DB G "
+ "--Base Addr ---- Limit\n");
+ kdbp(" Type\n");
+
+ /* skip first 8 null bytes */
+ /* the cpu multiplies the index by 8 and adds to GDT.base */
+ for (taddr = start_addr+8; taddr < end_addr; taddr += sizeof(ulong)) {
+
+ /* not all entries are mapped. do this to avoid GP even if hyp */
+ if (!kdb_read_mem(taddr, (kdbbyt_t *)&u1, sizeof(u1),domid) || !u1.gval)
+ continue;
+
+ if (u1.gval == 0xffffffffffffffff || u1.gval == 0x5555555555555555)
+ continue; /* what an effin x86 mess */
+
+ idx = (taddr - start_addr) / 8;
+ if (u1.gdte.S == 0) { /* System Desc are 16 bytes in 64bit mode */
+ taddr += sizeof(ulong);
+ continue;
+ }
+ kdbp("[%04x] %04x %016lx %4s %x %d %d %d %d %d %016lx %05x\n",
+ idx, (idx<<3), u1.gval, kdb_ret_acctype(u1.gdte.acctype),
+ u1.gdte.DPL,
+ u1.gdte.P, u1.gdte.AVL, u1.gdte.L, u1.gdte.DB, u1.gdte.G,
+ (u64)((u64)u1.gdte.base0 | (u64)((u64)u1.gdte.base1<<24)),
+ u1.gdte.limit0 | (u1.gdte.limit1<<16));
+ }
+
+ kdbp("\nSystem descriptors (S=0) : (skipping 0th entry)\n");
+ for (taddr=start_addr+8; taddr < end_addr; taddr += sizeof(ulong)) {
+ uint acctype;
+ u64 upper, addr64=0;
+
+ /* not all entries are mapped. do this to avoid GP even if hyp */
+ if (kdb_read_mem(taddr, (kdbbyt_t *)&u1, sizeof(u1), domid)==0 ||
+ u1.gval == 0 || u1.gdte.S == 1) {
+ continue;
+ }
+ idx = (taddr - start_addr) / 8;
+ taddr += sizeof(ulong);
+ if (kdb_read_mem(taddr, (kdbbyt_t *)&upper, 8, domid) == 0) {
+ kdbp("Could not read upper 8 bytes of system desc\n");
+ upper = 0;
+ }
+ acctype = u1.gdte.acctype;
+ if (acctype != 2 && acctype != 9 && acctype != 11 && acctype !=12 &&
+ acctype != 14 && acctype != 15)
+ continue;
+
+ kdbp("[%04x] %04x val:%016lx DPL:%x P:%d type:%x ",
+ idx, (idx<<3), u1.gval, u1.gdte.DPL, u1.gdte.P, acctype);
+
+ upper = (u64)((u64)(upper & 0xFFFFFFFF) << 32);
+
+ /* Vol 3A: table: 3-2 page: 3-19 */
+ if (acctype == 2) {
+ kdbp("LDT gate (0010)\n");
+ }
+ else if (acctype == 9) {
+ kdbp("TSS avail gate(1001)\n");
+ }
+ else if (acctype == 11) {
+ kdbp("TSS busy gate(1011)\n");
+ }
+ else if (acctype == 12) {
+ kdbp("CALL gate (1100)\n");
+ }
+ else if (acctype == 14) {
+ kdbp("IDT gate (1110)\n");
+ }
+ else if (acctype == 15) {
+ kdbp("Trap gate (1111)\n");
+ }
+
+ if (acctype == 2 || acctype == 9 || acctype == 11) {
+ kdbp(" AVL:%d G:%d Base Addr:%016lx Limit:%x\n",
+ u1.gdte.AVL, u1.gdte.G,
+ (u64)((u64)u1.gdte.base0 | ((u64)u1.gdte.base1<<24)| upper),
+ (u32)u1.gdte.limit0 | (u32)((u32)u1.gdte.limit1<<16));
+
+ } else if (acctype == 12) {
+ union sgdte_u u2;
+ u2.sgval = u1.gval;
+
+ addr64 = (u64)((u64)u2.cgdte.offs0 |
+ (u64)((u64)u2.cgdte.offs1<<16) | upper);
+ kdbp(" Entry: %04x:%016lx\n", u2.cgdte.sel, addr64);
+ } else if (acctype == 14 || acctype == 15) {
+ union sgdte_u u2;
+ u2.sgval = u1.gval;
+
+ addr64 = (u64)((u64)u2.igdte.offs0 |
+ (u64)((u64)u2.igdte.offs1<<16) | upper);
+ kdbp(" Entry: %04x:%016lx ist:%03x\n", u2.igdte.sel, addr64,
+ u2.igdte.ist);
+ } else
+ kdbp(" Error: Unrecongized type:%lx\n", acctype);
+ }
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* Display scheduler basic and extended info */
+static kdb_cpu_cmd_t
+kdb_usgf_sched(void)
+{
+ kdbp("sched: show schedular info and run queues\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_sched(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_sched();
+
+ kdb_print_sched_info();
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* Display MMU basic and extended info */
+static kdb_cpu_cmd_t
+kdb_usgf_mmu(void)
+{
+ kdbp("mmu: print basic MMU info\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_mmu(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ int cpu;
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_mmu();
+
+ kdbp("MMU Info:\n");
+ kdbp("total pages: %lx\n", total_pages);
+ kdbp("max page/mfn: %lx\n", max_page);
+ kdbp("frame_table: %p\n", frame_table);
+ kdbp("DIRECTMAP_VIRT_START: %lx\n", DIRECTMAP_VIRT_START);
+ kdbp("HYPERVISOR_VIRT_START: %lx\n", HYPERVISOR_VIRT_START);
+ kdbp("HYPERVISOR_VIRT_END: %lx\n", HYPERVISOR_VIRT_END);
+ kdbp("RO_MPT_VIRT_START: %lx\n", RO_MPT_VIRT_START);
+ kdbp("PERDOMAIN_VIRT_START: %lx\n", PERDOMAIN_VIRT_START);
+ kdbp("CONFIG_PAGING_LEVELS:%d\n", CONFIG_PAGING_LEVELS);
+ kdbp("__HYPERVISOR_COMPAT_VIRT_START: %lx\n",
+ (ulong)__HYPERVISOR_COMPAT_VIRT_START);
+ kdbp("&MPT[0] == %016lx\n", &machine_to_phys_mapping[0]);
+
+ kdbp("\nFIRST_RESERVED_GDT_PAGE: %x\n", FIRST_RESERVED_GDT_PAGE);
+ kdbp("FIRST_RESERVED_GDT_ENTRY: %lx\n", (ulong)FIRST_RESERVED_GDT_ENTRY);
+ kdbp("LAST_RESERVED_GDT_ENTRY: %lx\n", (ulong)LAST_RESERVED_GDT_ENTRY);
+ kdbp(" Per cpu non-compat gdt_table:\n");
+ for_each_online_cpu(cpu) {
+ kdbp("\tcpu:%d gdt_table:%p\n", cpu, per_cpu(gdt_table, cpu));
+ }
+ kdbp(" Per cpu compat gdt_table:\n");
+ for_each_online_cpu(cpu) {
+ kdbp("\tcpu:%d gdt_table:%p\n", cpu, per_cpu(compat_gdt_table, cpu));
+ }
+ kdbp("\n");
+ kdbp(" Per cpu tss:\n");
+ for_each_online_cpu(cpu) {
+ struct tss_struct *tssp = &per_cpu(init_tss, cpu);
+ kdbp("\tcpu:%d tss:%p (rsp0:%016lx)\n", cpu, tssp, tssp->rsp0);
+ }
+#ifdef USER_MAPPINGS_ARE_GLOBAL
+ kdbp("USER_MAPPINGS_ARE_GLOBAL is defined\n");
+#else
+ kdbp("USER_MAPPINGS_ARE_GLOBAL is NOT defined\n");
+#endif
+ kdbp("\n");
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* for HVM/HYB guests, go thru EPT. For PV guest we need to go to the btree.
+ * btree: pfn_to_mfn_frame_list_list is root that points (has mfns of) upto 16
+ * pages (call 'em l2 nodes) that contain mfns of guest p2m table pages
+ * NOTE: num of entries in a p2m page is same as num of entries in l2 node */
+static noinline ulong
+kdb_gpfn2mfn(struct domain *dp, ulong gpfn, p2m_type_t *typep)
+{
+ int idx;
+
+ if ( !paging_mode_translate(dp) ) {
+ mfn_t *mfn_va, mfn = arch_get_pfn_to_mfn_frame_list_list(dp);
+ int g_longsz = kdb_guest_bitness(dp->domain_id)/8;
+ int entries_per_pg = PAGE_SIZE/g_longsz;
+ const int shift = get_count_order(entries_per_pg);
+
+ if ( !mfn_valid(mfn) ) {
+ kdbp("Invalid frame_list_list mfn:%lx for non-xlate guest\n", mfn);
+ return INVALID_MFN;
+ }
+
+ mfn_va = map_domain_page(mfn);
+ idx = gpfn >> 2*shift; /* index in root page/node */
+ if (idx > 15) {
+ kdbp("gpfn:%lx idx:%x not in frame list limit of z16\n", gpfn, idx);
+ unmap_domain_page(mfn_va);
+ return INVALID_MFN;
+ }
+ mfn = (g_longsz == 4) ? ((int *)mfn_va)[idx] : mfn_va[idx];
+ if (mfn==0) {
+ kdbp("No mfn for idx:%d for gpfn:%lx in root pg\n", idx, gpfn);
+ unmap_domain_page(mfn_va);
+ return INVALID_MFN;
+ }
+ mfn_va = map_domain_page(mfn);
+ KDBGP1("p2m: idx:%x fll:%lx mfn of 2nd lvl page:%lx\n", idx,
+ arch_get_pfn_to_mfn_frame_list_list(dp), mfn);
+
+ idx = (gpfn>>shift) & ((1<<shift)-1); /* idx in l2 node */
+ mfn = (g_longsz == 4) ? ((int *)mfn_va)[idx] : mfn_va[idx];
+ unmap_domain_page(mfn_va);
+ if (mfn == 0) {
+ kdbp("No mfn entry at:%x in 2nd lvl pg for gpfn:%lx\n", idx, gpfn);
+ return INVALID_MFN;
+ }
+ KDBGP1("p2m: idx:%x mfn of p2m page:%lx\n", idx, mfn);
+ mfn_va = map_domain_page(mfn);
+ idx = gpfn & ((1<<shift)-1);
+ mfn = (g_longsz == 4) ? ((int *)mfn_va)[idx] : mfn_va[idx];
+ unmap_domain_page(mfn_va);
+
+ *typep = -1;
+ return mfn;
+ } else
+ return mfn_x(get_gfn_query_unlocked(dp, gpfn, typep));
+
+ return INVALID_MFN;
+}
+
+/* given a pfn, find it's mfn */
+static kdb_cpu_cmd_t
+kdb_usgf_p2m(void)
+{
+ kdbp("p2m domid 0xgpfn : gpfn to mfn\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_p2m(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ struct domain *dp;
+ ulong gpfn, mfn=0xdeadbeef;
+ p2m_type_t p2mtype = -1;
+
+ if (argc < 3 ||
+ (dp=kdb_strdomid2ptr(argv[1], 1)) == NULL ||
+ !kdb_str2ulong(argv[2], &gpfn)) {
+
+ return kdb_usgf_p2m();
+ }
+ mfn = kdb_gpfn2mfn(dp, gpfn, &p2mtype);
+ if ( paging_mode_translate(dp) )
+ kdbp("p2m[%lx] == %lx type:%d/0x%x\n", gpfn, mfn, p2mtype, p2mtype);
+ else
+ kdbp("p2m[%lx] == %lx type:N/A(PV)\n", gpfn, mfn);
+
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* given an mfn, lookup pfn in the MPT */
+static kdb_cpu_cmd_t
+kdb_usgf_m2p(void)
+{
+ kdbp("m2p 0xmfn: mfn to pfn\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_m2p(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ mfn_t mfn;
+ if (argc > 1 && kdb_str2ulong(argv[1], &mfn))
+ if (mfn_valid(mfn))
+ kdbp("mpt[%x] == %lx\n", mfn, machine_to_phys_mapping[mfn]);
+ else
+ kdbp("Invalid mfn:%lx\n", mfn);
+ else
+ kdb_usgf_m2p();
+ return KDB_CPU_MAIN_KDB;
+}
+
+static void
+kdb_pr_pg_pgt_flds(unsigned long type_info)
+{
+ switch (type_info & PGT_type_mask) {
+ case (PGT_l1_page_table):
+ kdbp(" page is PGT_l1_page_table\n");
+ break;
+ case PGT_l2_page_table:
+ kdbp(" page is PGT_l2_page_table\n");
+ break;
+ case PGT_l3_page_table:
+ kdbp(" page is PGT_l3_page_table\n");
+ break;
+ case PGT_l4_page_table:
+ kdbp(" page is PGT_l4_page_table\n");
+ break;
+ case PGT_seg_desc_page:
+ kdbp(" page is seg desc page\n");
+ break;
+ case PGT_writable_page:
+ kdbp(" page is writable page\n");
+ break;
+ case PGT_shared_page:
+ kdbp(" page is shared page\n");
+ break;
+ }
+ if (type_info & PGT_pinned)
+ kdbp(" page is pinned\n");
+ if (type_info & PGT_validated)
+ kdbp(" page is validated\n");
+ if (type_info & PGT_pae_xen_l2)
+ kdbp(" page is PGT_pae_xen_l2\n");
+ if (type_info & PGT_partial)
+ kdbp(" page is PGT_partial\n");
+ if (type_info & PGT_locked)
+ kdbp(" page is PGT_locked\n");
+}
+
+static void
+kdb_pr_pg_pgc_flds(unsigned long count_info)
+{
+ if (count_info & PGC_allocated)
+ kdbp(" PGC_allocated");
+ if (count_info & PGC_xen_heap)
+ kdbp(" PGC_xen_heap");
+ if (count_info & PGC_page_table)
+ kdbp(" PGC_page_table");
+ if (count_info & PGC_broken)
+ kdbp(" PGC_broken");
+#if XEN_VERSION < 4 /* xen 3.x.x */
+ if (count_info & PGC_offlining)
+ kdbp(" PGC_offlining");
+ if (count_info & PGC_offlined)
+ kdbp(" PGC_offlined");
+#else
+ if (count_info & PGC_state_inuse)
+ kdbp(" PGC_inuse");
+ if (count_info & PGC_state_offlining)
+ kdbp(" PGC_state_offlining");
+ if (count_info & PGC_state_offlined)
+ kdbp(" PGC_state_offlined");
+ if (count_info & PGC_state_free)
+ kdbp(" PGC_state_free");
+#endif
+ kdbp("\n");
+}
+
+/* print struct page_info{} given ptr to it or an mfn
+ * NOTE: that given an mfn there seems no way of knowing how it's used, so
+ * here we just print all info and let user decide what's applicable */
+static kdb_cpu_cmd_t
+kdb_usgf_dpage(void)
+{
+ kdbp("dpage mfn|page-ptr : Display struct page\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dpage(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ unsigned long val;
+ struct page_info *pgp;
+ struct domain *dp;
+
+ if (argc <= 1 || *argv[1] == '?')
+ return kdb_usgf_dpage();
+
+ if ((kdb_str2ulong(argv[1], &val) == 0) ||
+ (val < (ulong)frame_table && !mfn_valid(val))) {
+
+ kdbp("Invalid arg:%s\n", argv[1]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ kdbp("Page Info:\n");
+ if (val <= (ulong)frame_table) { /* arg is mfn */
+ pgp = mfn_to_page(val);
+ kdbp(" mfn: %lx page_info:%p\n", val, pgp);
+ } else {
+ pgp = (struct page_info *)val; /* arg is struct page{} */
+ if (pgp < frame_table || pgp >= frame_table+max_page) {
+ kdbp("Invalid page ptr. below/beyond max_page\n");
+ return KDB_CPU_MAIN_KDB;
+ }
+ kdbp(" mfn: %lx page_info:%p\n", page_to_mfn(pgp), pgp);
+ }
+ kdbp(" count_info: %016lx (refcnt: %x)\n", pgp->count_info,
+ pgp->count_info & PGC_count_mask);
+#if XEN_VERSION > 3 || XEN_SUBVERSION > 3 /* xen 3.4.x or later */
+ kdb_pr_pg_pgc_flds(pgp->count_info);
+
+ kdbp("In use info:\n");
+ kdbp(" type_info:%016lx\n", pgp->u.inuse.type_info);
+ kdb_pr_pg_pgt_flds(pgp->u.inuse.type_info);
+ dp = page_get_owner(pgp);
+ kdbp(" domid:%d (pickled:%lx)\n", dp ? dp->domain_id : -1,
+ pgp->v.inuse._domain);
+
+ kdbp("Shadow Info:\n");
+ kdbp(" type:%x pinned:%x count:%x\n", pgp->u.sh.type, pgp->u.sh.pinned,
+ pgp->u.sh.count);
+ kdbp(" back:%lx shadow_flags:%x next_shadow:%lx\n", pgp->v.sh.back,
+ pgp->shadow_flags, pgp->next_shadow);
+
+ kdbp("Free Info\n");
+ kdbp(" need_tlbflush:%d order:%d tlbflush_timestamp:%x\n",
+ pgp->u.free.need_tlbflush, pgp->v.free.order,
+ pgp->tlbflush_timestamp);
+#else
+ if (pgp->count_info & PGC_allocated) /* page allocated */
+ kdbp(" PGC_allocated");
+ if (pgp->count_info & PGC_page_table) /* page table page */
+ kdbp(" PGC_page_table");
+ kdbp("\n");
+ kdbp(" page is %s xen heap page\n", is_xen_heap_page(pgp) ? "a":"NOT");
+ kdbp(" cacheattr:%x\n", (pgp->count_info>>PGC_cacheattr_base) & 7);
+ if (pgp->count_info & PGC_count_mask) { /* page in use */
+ dp = pgp->u.inuse._domain; /* pickled domain */
+ kdbp(" page is in use\n");
+ kdbp(" domid: %d (pickled dom:%x)\n",
+ dp ? (unpickle_domptr(dp))->domain_id : -1, dp);
+ kdbp(" type_info: %lx\n", pgp->u.inuse.type_info);
+ kdb_prt_pg_type(pgp->u.inuse.type_info);
+ } else { /* page is free */
+ kdbp(" page is free\n");
+ kdbp(" order: %x\n", pgp->u.free.order);
+ kdbp(" cpumask: %lx\n", pgp->u.free.cpumask.bits);
+ }
+ kdbp(" tlbflush/shadow_flags: %lx\n", pgp->shadow_flags);
+#endif
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* display asked msr value */
+static kdb_cpu_cmd_t
+kdb_usgf_dmsr(void)
+{
+ kdbp("dmsr address : Display msr value\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_dmsr(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ unsigned long addr, val;
+
+ if (argc <= 1 || *argv[1] == '?')
+ return kdb_usgf_dmsr();
+
+ if ((kdb_str2ulong(argv[1], &addr) == 0)) {
+ kdbp("Invalid arg:%s\n", argv[1]);
+ return KDB_CPU_MAIN_KDB;
+ }
+ rdmsrl(addr, val);
+ kdbp("msr: %lx val:%lx\n", addr, val);
+
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* execute cpuid for given value */
+static kdb_cpu_cmd_t
+kdb_usgf_cpuid(void)
+{
+ kdbp("cpuid eax : Display cpuid value returned in rax\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_cpuid(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ unsigned long rax=0, rbx=0, rcx=0, rdx=0;
+
+ if (argc <= 1 || *argv[1] == '?')
+ return kdb_usgf_cpuid();
+
+ if ((kdb_str2ulong(argv[1], &rax) == 0)) {
+ kdbp("Invalid arg:%s\n", argv[1]);
+ return KDB_CPU_MAIN_KDB;
+ }
+#if 0
+ __asm__ __volatile__ (
+ /* "pushl %%rax \n" */
+
+ "movl %0, %%rax \n"
+ "cpuid \n"
+ : "=&a" (rax), "=b" (rbx), "=c" (rcx), "=d" (rdx)
+ : "0" (rax)
+ : "rax", "rbx", "rcx", "rdx", "memory");
+#endif
+ cpuid(rax, &rax, &rbx, &rcx, &rdx);
+ kdbp("rax: %016lx rbx:%016lx rcx:%016lx rdx:%016lx\n", rax, rbx,
+ rcx, rdx);
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* execute cpuid for given value */
+static kdb_cpu_cmd_t
+kdb_usgf_wept(void)
+{
+ kdbp("wept domid gfn: walk ept table for given domid and gfn\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_wept(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ struct domain *dp;
+ ulong gfn;
+
+ if ((argc > 1 && *argv[1] == '?') || argc != 3)
+ return kdb_usgf_wept();
+ if ((dp=kdb_strdomid2ptr(argv[1], 1)) && kdb_str2ulong(argv[2], &gfn))
+ ept_walk_table(dp, gfn);
+ else
+ kdb_usgf_wept();
+
+ return KDB_CPU_MAIN_KDB;
+}
+
+/*
+ * Save symbols info for a guest, dom0 or other...
+ */
+static kdb_cpu_cmd_t
+kdb_usgf_sym(void)
+{
+ kdbp("sym domid &kallsyms_names &kallsyms_addresses &kallsyms_num_syms\n");
+ kdbp("\t [&kallsyms_token_table] [&kallsyms_token_index]\n");
+ kdbp("\ttoken _table and _index MUST be specified for el5\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_sym(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ ulong namesp, addrap, nump, toktblp, tokidxp;
+ domid_t domid;
+
+ if (argc < 5) {
+ return kdb_usgf_sym();
+ }
+ toktblp = tokidxp = 0; /* optional parameters */
+ if (kdb_str2domid(argv[1], &domid, 1) &&
+ kdb_str2ulong(argv[2], &namesp) &&
+ kdb_str2ulong(argv[3], &addrap) &&
+ kdb_str2ulong(argv[4], &nump) &&
+ (argc==5 || (argc==7 && kdb_str2ulong(argv[5], &toktblp) &&
+ kdb_str2ulong(argv[6], &tokidxp)))) {
+
+ kdb_sav_dom_syminfo(domid, namesp, addrap,nump,toktblp,tokidxp);
+ } else
+ kdb_usgf_sym();
+ return KDB_CPU_MAIN_KDB;
+}
+
+
+/* mods is the dumb ass &modules. modules is struct {nxt, prev}, and not ptr */
+static void
+kdb_dump_linux_modules(domid_t domid, ulong mods, uint nxtoffs, uint nmoffs,
+ uint coreoffs)
+{
+ const int bufsz = 56;
+ char buf[bufsz];
+ uint64_t addr, addrval, *nxtptr, *modptr;
+ uint i, num = 8;
+
+ if (kdb_guest_bitness(domid) == 32)
+ num = 4;
+
+ /* first read modules{}.next ptr */
+ if (kdb_read_mem(mods, (kdbbyt_t *)&nxtptr, num, domid) != num) {
+ kdbp("ERROR: Could not read next at mod:%p\n", (void *)mods);
+ return;
+ }
+
+ KDBGP("mods:%p nxtptr:%p nmoffs:%x coreoffs:%x\n", (void *)mods, nxtptr,
+ nmoffs, coreoffs);
+
+ while ((uint64_t)nxtptr != mods) {
+
+ modptr = (uint64_t *) ((ulong)nxtptr - nxtoffs);
+
+ addr = (ulong)modptr + coreoffs;
+ if (kdb_read_mem(addr, (kdbbyt_t *)&addrval, num, domid) != num) {
+ kdbp("ERROR: Could not read mod addr at :%p\n", (void *)addr);
+ return;
+ }
+
+ KDBGP("modptr:%p addr:%p\n", modptr, (void *)addr);
+ addr = (ulong)modptr + nmoffs;
+ i=0;
+ do {
+ if (kdb_read_mem(addr, (kdbbyt_t *)&buf[i], 1, domid) != 1) {
+ kdbp("ERROR:Could not read name ch at addr:%p\n", (void *)addr);
+ return;
+ }
+ addr++;
+ } while (buf[i] && i++ < bufsz);
+ buf[bufsz-1] = '\0';
+
+ kdbp("%016lx %016lx %s\n", modptr, addrval, buf);
+
+ if (kdb_read_mem((ulong)nxtptr, (kdbbyt_t *)&nxtptr, num, domid)!=num) {
+ kdbp("ERROR: Could not read next at mod:%p\n", (void *)mods);
+ return;
+ }
+ KDBGP("nxtptr:%p addr:%p\n", nxtptr, (void *)addr);
+ }
+}
+
+/* Display modules loaded in linux guest */
+static kdb_cpu_cmd_t
+kdb_usgf_mod(void)
+{
+ kdbp("mod domid &modules next-offs name-offs module_core-offs\n");
+ kdbp("\twhere next-offs: &((struct module *)0)->list.next\n");
+ kdbp("\tname-offs: &((struct module *)0)->name etc..\n");
+ kdbp("\tDisplays all loaded modules in the linux guest\n");
+ kdbp("\tEg: mod 0 ffffffff80302780 8 0x18 0x178\n");
+
+ return KDB_CPU_MAIN_KDB;
+}
+
+static kdb_cpu_cmd_t
+kdb_cmdf_mod(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ ulong mods, nxtoffs, nmoffs, coreoffs;
+ domid_t domid;
+
+ if (argc < 6) {
+ return kdb_usgf_mod();
+ }
+ if (kdb_str2domid(argv[1], &domid, 1) &&
+ kdb_str2ulong(argv[2], &mods) &&
+ kdb_str2ulong(argv[3], &nxtoffs) &&
+ kdb_str2ulong(argv[4], &nmoffs) &&
+ kdb_str2ulong(argv[5], &coreoffs)) {
+
+ kdbp("modptr address name\n");
+ kdb_dump_linux_modules(domid, mods, nxtoffs, nmoffs, coreoffs);
+ } else
+ kdb_usgf_mod();
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* toggle kdb debug trace level */
+static kdb_cpu_cmd_t
+kdb_usgf_kdbdbg(void)
+{
+ kdbp("kdbdbg : trace info to debug kdb\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_kdbdbg(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_kdbdbg();
+
+ kdbdbg = (kdbdbg==3) ? 0 : (kdbdbg+1);
+ kdbp("kdbdbg set to:%d\n", kdbdbg);
+ return KDB_CPU_MAIN_KDB;
+}
+
+static kdb_cpu_cmd_t
+kdb_usgf_reboot(void)
+{
+ kdbp("reboot: reboot system\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_reboot(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_reboot();
+
+ machine_restart(500);
+ return KDB_CPU_MAIN_KDB; /* not reached */
+}
+
+
+static kdb_cpu_cmd_t
+kdb_usgf_trcon(void)
+{
+ kdbp("trcon: turn user added kdb tracing on\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_trcon(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_trcon();
+
+ kdb_trcon = 1;
+ kdbp("kdb tracing is now on\n");
+ return KDB_CPU_MAIN_KDB;
+}
+
+static kdb_cpu_cmd_t
+kdb_usgf_trcoff(void)
+{
+ kdbp("trcoff: turn user added kdb tracing off\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_trcoff(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_trcoff();
+
+ kdb_trcon = 0;
+ kdbp("kdb tracing is now off\n");
+ return KDB_CPU_MAIN_KDB;
+}
+
+static kdb_cpu_cmd_t
+kdb_usgf_trcz(void)
+{
+ kdbp("trcz : zero entire trace buffer\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_trcz(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_trcz();
+
+ kdb_trczero();
+ return KDB_CPU_MAIN_KDB;
+}
+
+static kdb_cpu_cmd_t
+kdb_usgf_trcp(void)
+{
+ kdbp("trcp : give hints to dump trace buffer via dw/dd command\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_trcp(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_trcp();
+
+ kdb_trcp();
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* print some basic info, constants, etc.. */
+static kdb_cpu_cmd_t
+kdb_usgf_info(void)
+{
+ kdbp("info : display basic info, constants, etc..\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_info(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ struct domain *dp;
+ struct cpuinfo_x86 *bcdp;
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_info();
+
+ kdbp("Version: %d.%d.%s (%s@%s) %s\n", xen_major_version(),
+ xen_minor_version(), xen_extra_version(), xen_compile_by(),
+ xen_compile_domain(), xen_compile_date());
+ kdbp("__XEN_LATEST_INTERFACE_VERSION__ : 0x%x\n",
+ __XEN_LATEST_INTERFACE_VERSION__);
+ kdbp("__XEN_INTERFACE_VERSION__: 0x%x\n", __XEN_INTERFACE_VERSION__);
+
+ bcdp = &boot_cpu_data;
+ kdbp("CPU: (all decimal)");
+ if (bcdp->x86_vendor == X86_VENDOR_AMD)
+ kdbp(" AMD");
+ else
+ kdbp(" INTEL");
+ kdbp(" family:%d model:%d\n", bcdp->x86, bcdp->x86_model);
+ kdbp(" vendor_id:%16s model_id:%64s\n", bcdp->x86_vendor_id,
+ bcdp->x86_model_id);
+ kdbp(" cpuidlvl:%d cache:sz:%d align:%d\n", bcdp->cpuid_level,
+ bcdp->x86_cache_size, bcdp->x86_cache_alignment);
+ kdbp(" power:%d cores: max:%d booted:%d siblings:%d apicid:%d\n",
+ bcdp->x86_power, bcdp->x86_max_cores, bcdp->booted_cores,
+ bcdp->x86_num_siblings, bcdp->apicid);
+ kdbp(" ");
+ if (cpu_has_apic)
+ kdbp("_apic");
+ if (cpu_has_sep)
+ kdbp("|_sep");
+ if (cpu_has_xmm3)
+ kdbp("|_xmm3");
+ if (cpu_has_ht)
+ kdbp("|_ht");
+ if (cpu_has_nx)
+ kdbp("|_nx");
+ if (cpu_has_clflush)
+ kdbp("|_clflush");
+ if (cpu_has_page1gb)
+ kdbp("|_page1gb");
+ if (cpu_has_ffxsr)
+ kdbp("|_ffxsr");
+ if (cpu_has_x2apic)
+ kdbp("|_x2apic");
+ kdbp("\n\n");
+ kdbp("CC:");
+#if defined(CONFIG_X86_64)
+ kdbp(" CONFIG_X86_64");
+#endif
+#if defined(CONFIG_COMPAT)
+ kdbp(" CONFIG_COMPAT");
+#endif
+#if defined(CONFIG_PAGING_ASSISTANCE)
+ kdbp(" CONFIG_PAGING_ASSISTANCE");
+#endif
+ kdbp("\n");
+ kdbp("cpu has following features:\n");
+ kdbp(" %s\n", boot_cpu_has(X86_FEATURE_TSC_RELIABLE) ?
+ "X86_FEATURE_TSC_RELIABLE" : "");
+ kdbp(" %s\n",
+ boot_cpu_has(X86_FEATURE_CONSTANT_TSC)? "X86_FEATURE_CONSTANT_TSC":"");
+ kdbp(" %s\n",
+ boot_cpu_has(X86_FEATURE_NONSTOP_TSC) ? "X86_FEATURE_NONSTOP_TSC" :"");
+ kdbp(" %s\n",
+ boot_cpu_has(X86_FEATURE_RDTSCP) ? "X86_FEATURE_RDTSCP" : "");
+ kdbp(" %s\n", boot_cpu_has(X86_FEATURE_FXSR) ? "X86_FEATURE_FXSR" : "");
+ kdbp(" %s\n", boot_cpu_has(X86_FEATURE_CPUID_FAULTING) ?
+ "X86_FEATURE_CPUID_FAULTING" : "");
+ kdbp(" %s\n",
+ boot_cpu_has(X86_FEATURE_PAGE1GB) ? "X86_FEATURE_PAGE1GB" : "");
+ kdbp(" %s\n", boot_cpu_has(X86_FEATURE_MWAIT) ? "X86_FEATURE_MWAIT" : "");
+ kdbp(" %s\n", boot_cpu_has(X86_FEATURE_X2APIC) ? "X86_FEATURE_X2APIC":"");
+ kdbp(" %s\n", boot_cpu_has(X86_FEATURE_XSAVE) ? "X86_FEATURE_XSAVE":"");
+ kdbp("\n");
+
+ kdbp("MAX_VIRT_CPUS:$%d MAX_HVM_VCPUS:$%d\n", MAX_VIRT_CPUS,MAX_HVM_VCPUS);
+ kdbp("NR_EVENT_CHANNELS: $%d\n", NR_EVENT_CHANNELS);
+ kdbp("NR_EVTCHN_BUCKETS: $%d\n", NR_EVTCHN_BUCKETS);
+
+ kdbp("\nDomains and their vcpus:\n");
+ for_each_domain(dp) {
+ struct vcpu *vp;
+ int printed=0;
+ kdbp(" Domain: {id:%d 0x%x ptr:%p%s} VCPUs:\n",
+ dp->domain_id, dp->domain_id, dp, dp->is_dying ? " DYING":"");
+ for(vp=dp->vcpu[0]; vp; vp = vp->next_in_list) {
+ kdbp(" {id:%d p:%p runstate:%d}", vp->vcpu_id, vp,
+ vp->runstate.state);
+ if (++printed % 2 == 0) kdbp("\n");
+ }
+ kdbp("\n");
+ }
+ return KDB_CPU_MAIN_KDB;
+}
+
+static kdb_cpu_cmd_t
+kdb_usgf_cur(void)
+{
+ kdbp("cur : display current domid and vcpu\n");
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* Checking for guest_mode() not feasible here. if dom0->hcall->bp in xen,
+ * then g_m() will show xen, but vcpu is still dom0. hence just look at
+ * current only */
+static kdb_cpu_cmd_t
+kdb_cmdf_cur(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ domid_t id = current->domain->domain_id;
+
+ if (argc > 1 && *argv[1] == '?')
+ return kdb_usgf_cur();
+
+ kdbp("domid: %d{%p} %s vcpu:%d {%p} ", id, current->domain,
+ (id==DOMID_IDLE) ? "(IDLE)" : "", current->vcpu_id, current);
+
+ /* if (id != DOMID_IDLE) { */
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
+ u64 addr = -1;
+ __vmptrst(&addr);
+ kdbp(" VMCS:"KDBFL, addr);
+ }
+ /* } */
+ kdbp("\n");
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* stub to quickly and easily add a new command */
+static kdb_cpu_cmd_t
+kdb_usgf_usr1(void)
+{
+ kdbp("usr1: add any arbitrary cmd using this in kdb_cmds.c\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_usr1(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ return KDB_CPU_MAIN_KDB;
+}
+
+static kdb_cpu_cmd_t
+kdb_usgf_h(void)
+{
+ kdbp("h: display all commands. See kdb/README for more info\n");
+ return KDB_CPU_MAIN_KDB;
+}
+static kdb_cpu_cmd_t
+kdb_cmdf_h(int argc, const char **argv, struct cpu_user_regs *regs)
+{
+ kdbtab_t *tbp;
+
+ kdbp(" - ccpu is current cpu \n");
+ kdbp(" - following are always in decimal:\n");
+ kdbp(" vcpu num, cpu num, domid\n");
+ kdbp(" - otherwise, almost all numbers are in hex (0x not needed)\n");
+ kdbp(" - output: $17 means decimal 17\n");
+ kdbp(" - domid 7fff($32767) refers to hypervisor\n");
+ kdbp(" - if no domid before function name, then it's hypervisor\n");
+ kdbp(" - earlykdb in xen grub line to break into kdb during boot\n");
+ kdbp(" - command ? will show the command usage\n");
+ kdbp("\n");
+
+ for(tbp=kdb_cmd_tbl; tbp->kdb_cmd_usgf; tbp++)
+ (*tbp->kdb_cmd_usgf)();
+ return KDB_CPU_MAIN_KDB;
+}
+
+/* ===================== cmd table initialization ========================== */
+void __init
+kdb_init_cmdtab(void)
+{
+ static kdbtab_t _kdb_cmd_table[] = {
+
+ {"info", kdb_cmdf_info, kdb_usgf_info, 1, KDB_REPEAT_NONE},
+ {"cur", kdb_cmdf_cur, kdb_usgf_cur, 1, KDB_REPEAT_NONE},
+
+ {"f", kdb_cmdf_f, kdb_usgf_f, 1, KDB_REPEAT_NONE},
+ {"fg", kdb_cmdf_fg, kdb_usgf_fg, 1, KDB_REPEAT_NONE},
+
+ {"dw", kdb_cmdf_dw, kdb_usgf_dw, 1, KDB_REPEAT_NO_ARGS},
+ {"dd", kdb_cmdf_dd, kdb_usgf_dd, 1, KDB_REPEAT_NO_ARGS},
+ {"dwm", kdb_cmdf_dwm, kdb_usgf_dwm, 1, KDB_REPEAT_NO_ARGS},
+ {"ddm", kdb_cmdf_ddm, kdb_usgf_ddm, 1, KDB_REPEAT_NO_ARGS},
+ {"dr", kdb_cmdf_dr, kdb_usgf_dr, 1, KDB_REPEAT_NONE},
+ {"drg", kdb_cmdf_drg, kdb_usgf_drg, 1, KDB_REPEAT_NONE},
+
+ {"dis", kdb_cmdf_dis, kdb_usgf_dis, 1, KDB_REPEAT_NO_ARGS},
+ {"dism",kdb_cmdf_dism, kdb_usgf_dism, 1, KDB_REPEAT_NO_ARGS},
+
+ {"mw", kdb_cmdf_mw, kdb_usgf_mw, 1, KDB_REPEAT_NONE},
+ {"md", kdb_cmdf_md, kdb_usgf_md, 1, KDB_REPEAT_NONE},
+ {"mr", kdb_cmdf_mr, kdb_usgf_mr, 1, KDB_REPEAT_NONE},
+
+ {"bc", kdb_cmdf_bc, kdb_usgf_bc, 0, KDB_REPEAT_NONE},
+ {"bp", kdb_cmdf_bp, kdb_usgf_bp, 1, KDB_REPEAT_NONE},
+ {"btp", kdb_cmdf_btp, kdb_usgf_btp, 1, KDB_REPEAT_NONE},
+
+ {"wp", kdb_cmdf_wp, kdb_usgf_wp, 1, KDB_REPEAT_NONE},
+ {"wc", kdb_cmdf_wc, kdb_usgf_wc, 0, KDB_REPEAT_NONE},
+
+ {"ni", kdb_cmdf_ni, kdb_usgf_ni, 0, KDB_REPEAT_NO_ARGS},
+ {"ss", kdb_cmdf_ss, kdb_usgf_ss, 1, KDB_REPEAT_NO_ARGS},
+ {"ssb",kdb_cmdf_ssb,kdb_usgf_ssb,0, KDB_REPEAT_NO_ARGS},
+ {"go", kdb_cmdf_go, kdb_usgf_go, 0, KDB_REPEAT_NONE},
+
+ {"cpu",kdb_cmdf_cpu, kdb_usgf_cpu, 1, KDB_REPEAT_NONE},
+ {"nmi",kdb_cmdf_nmi, kdb_usgf_nmi, 1, KDB_REPEAT_NONE},
+ {"percpu",kdb_cmdf_percpu, kdb_usgf_percpu, 1, KDB_REPEAT_NONE},
+
+ {"sym", kdb_cmdf_sym, kdb_usgf_sym, 1, KDB_REPEAT_NONE},
+ {"mod", kdb_cmdf_mod, kdb_usgf_mod, 1, KDB_REPEAT_NONE},
+
+ {"vcpuh",kdb_cmdf_vcpuh, kdb_usgf_vcpuh, 1, KDB_REPEAT_NONE},
+ {"vcpu", kdb_cmdf_vcpu, kdb_usgf_vcpu, 1, KDB_REPEAT_NONE},
+ {"dom", kdb_cmdf_dom, kdb_usgf_dom, 1, KDB_REPEAT_NONE},
+
+ {"sched", kdb_cmdf_sched, kdb_usgf_sched, 1, KDB_REPEAT_NONE},
+ {"mmu", kdb_cmdf_mmu, kdb_usgf_mmu, 1, KDB_REPEAT_NONE},
+ {"p2m", kdb_cmdf_p2m, kdb_usgf_p2m, 1, KDB_REPEAT_NONE},
+ {"m2p", kdb_cmdf_m2p, kdb_usgf_m2p, 1, KDB_REPEAT_NONE},
+ {"dpage", kdb_cmdf_dpage, kdb_usgf_dpage, 1, KDB_REPEAT_NONE},
+ {"dmsr", kdb_cmdf_dmsr, kdb_usgf_dmsr, 1, KDB_REPEAT_NONE},
+ {"cpuid", kdb_cmdf_cpuid, kdb_usgf_cpuid, 1, KDB_REPEAT_NONE},
+ {"wept", kdb_cmdf_wept, kdb_usgf_wept, 1, KDB_REPEAT_NONE},
+
+ {"dtrq", kdb_cmdf_dtrq, kdb_usgf_dtrq, 1, KDB_REPEAT_NONE},
+ {"didt", kdb_cmdf_didt, kdb_usgf_didt, 1, KDB_REPEAT_NONE},
+ {"dgdt", kdb_cmdf_dgdt, kdb_usgf_dgdt, 1, KDB_REPEAT_NONE},
+ {"dirq", kdb_cmdf_dirq, kdb_usgf_dirq, 1, KDB_REPEAT_NONE},
+ {"dvit", kdb_cmdf_dvit, kdb_usgf_dvit, 1, KDB_REPEAT_NONE},
+ {"dvmc", kdb_cmdf_dvmc, kdb_usgf_dvmc, 1, KDB_REPEAT_NONE},
+ {"mmio", kdb_cmdf_mmio, kdb_usgf_mmio, 1, KDB_REPEAT_NONE},
+
+ /* tracing related commands */
+ {"trcon", kdb_cmdf_trcon, kdb_usgf_trcon, 0, KDB_REPEAT_NONE},
+ {"trcoff",kdb_cmdf_trcoff, kdb_usgf_trcoff, 0, KDB_REPEAT_NONE},
+ {"trcz", kdb_cmdf_trcz, kdb_usgf_trcz, 0, KDB_REPEAT_NONE},
+ {"trcp", kdb_cmdf_trcp, kdb_usgf_trcp, 1, KDB_REPEAT_NONE},
+
+ {"usr1", kdb_cmdf_usr1, kdb_usgf_usr1, 1, KDB_REPEAT_NONE},
+ {"kdbf", kdb_cmdf_kdbf, kdb_usgf_kdbf, 1, KDB_REPEAT_NONE},
+ {"kdbdbg",kdb_cmdf_kdbdbg, kdb_usgf_kdbdbg, 1, KDB_REPEAT_NONE},
+ {"reboot",kdb_cmdf_reboot, kdb_usgf_reboot, 1, KDB_REPEAT_NONE},
+ {"h", kdb_cmdf_h, kdb_usgf_h, 1, KDB_REPEAT_NONE},
+
+ {"", NULL, NULL, 0, 0},
+ };
+ kdb_cmd_tbl = _kdb_cmd_table;
+ return;
+}
diff -r 32034d1914a6 xen/kdb/kdb_io.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/kdb_io.c Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2009, Mukesh Rathor, Oracle Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+#include "include/kdbinc.h"
+
+#define K_BACKSPACE 0x8 /* ctrl-H */
+#define K_BACKSPACE1 0x7f /* ctrl-? */
+#define K_UNDERSCORE 0x5f
+#define K_CMD_BUFSZ 160
+#define K_CMD_MAXI (K_CMD_BUFSZ - 1) /* max index in buffer */
+
+#if 0 /* make a history array some day */
+#define K_UP_ARROW /* sequence : 1b 5b 41 ie, '\e[A' */
+#define K_DN_ARROW /* sequence : 1b 5b 42 ie, '\e[B' */
+#define K_NUM_HIST 32
+static int cursor;
+static char cmds_a[NUM_HIST][K_CMD_BUFSZ];
+#endif
+
+static char cmds_a[K_CMD_BUFSZ];
+
+
+static int
+kdb_key_valid(int key)
+{
+ /* note: isspace() is more than ' ', hence we don't use it here */
+ if (isalnum(key) || key == ' ' || key == K_BACKSPACE || key == '\n' ||
+ key == '?' || key == K_UNDERSCORE || key == '=' || key == '!')
+ return 1;
+ return 0;
+}
+
+/* display kdb prompt and read command from the console
+ * RETURNS: a '\n' terminated command buffer */
+char *
+kdb_get_cmdline(char *prompt)
+{
+ #define K_BELL 0x7
+ #define K_CTRL_C 0x3
+
+ int key, i=0;
+
+ kdbp(prompt);
+ memset(cmds_a, 0, K_CMD_BUFSZ);
+ cmds_a[K_CMD_BUFSZ-1] = '\n';
+
+ do {
+ key = console_getc();
+ if (key == '\r')
+ key = '\n';
+ if (key == K_BACKSPACE1)
+ key = K_BACKSPACE;
+
+ if (key == K_CTRL_C || (i==K_CMD_MAXI && key != '\n')) {
+ console_putc('\n');
+ if (i >= K_CMD_MAXI) {
+ kdbp("KDB: cmd buffer overflow\n");
+ console_putc(K_BELL);
+ }
+ memset(cmds_a, 0, K_CMD_BUFSZ);
+ i = 0;
+ kdbp(prompt);
+ continue;
+ }
+ if (!kdb_key_valid(key)) {
+ console_putc(K_BELL);
+ continue;
+ }
+ if (key == K_BACKSPACE) {
+ if (i==0) {
+ console_putc(K_BELL);
+ continue;
+ } else
+ cmds_a[--i] = '\0';
+ console_putc(K_BACKSPACE);
+ console_putc(' '); /* erase character */
+ } else
+ cmds_a[i++] = key;
+
+ console_putc(key);
+
+ } while (key != '\n');
+
+ return cmds_a;
+}
+
+/*
+ * printk takes a lock, an NMI could come in after that, and another cpu may
+ * spin. also, the console lock is forced unlock, so panic is been seen on
+ * 8 way. hence, no printk() calls.
+ */
+static volatile int kdbp_gate = 0;
+void
+kdbp(const char *fmt, ...)
+{
+ static char buf[1024];
+ va_list args;
+ char *p;
+ int i=0;
+
+ while ((__cmpxchg(&kdbp_gate, 0,1, sizeof(kdbp_gate)) != 0) && i++<1000)
+ mdelay(10);
+
+ va_start(args, fmt);
+ (void)vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ for (p=buf; *p != '\0'; p++)
+ console_putc(*p);
+ kdbp_gate = 0;
+}
+
+
+/*
+ * copy/read machine memory.
+ * RETURNS: number of bytes copied
+ */
+int
+kdb_read_mmem(kdbma_t maddr, kdbbyt_t *dbuf, int len)
+{
+ ulong remain, orig=len;
+
+ while (len > 0) {
+ ulong pagecnt = min_t(long, PAGE_SIZE-(maddr&~PAGE_MASK), len);
+ char *va = map_domain_page(maddr >> PAGE_SHIFT);
+
+ va = va + (maddr & (PAGE_SIZE-1)); /* add page offset */
+ remain = __copy_from_user(dbuf, (void *)va, pagecnt);
+ KDBGP1("maddr:%x va:%p len:%x pagecnt:%x rem:%x\n",
+ maddr, va, len, pagecnt, remain);
+ unmap_domain_page(va);
+ len = len - (pagecnt - remain);
+ if (remain != 0)
+ break;
+ maddr += pagecnt;
+ dbuf += pagecnt;
+ }
+ return orig - len;
+}
+
+
+/*
+ * copy/read guest or hypervisor memory. (domid == DOMID_IDLE) => hyp
+ * RETURNS: number of bytes copied
+ */
+int
+kdb_read_mem(kdbva_t saddr, kdbbyt_t *dbuf, int len, domid_t domid)
+{
+ return (len - dbg_rw_mem(saddr, dbuf, len, domid, 0, 0));
+}
+
+/*
+ * write guest or hypervisor memory. (domid == DOMID_IDLE) => hyp
+ * RETURNS: number of bytes written
+ */
+int
+kdb_write_mem(kdbva_t daddr, kdbbyt_t *sbuf, int len, domid_t domid)
+{
+ return (len - dbg_rw_mem(daddr, sbuf, len, domid, 1, 0));
+}
diff -r 32034d1914a6 xen/kdb/kdbmain.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/kdbmain.c Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,739 @@
+/*
+ * Copyright (C) 2009, Mukesh Rathor, Oracle Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include "include/kdbinc.h"
+
+static int kdbmain(kdb_reason_t, struct cpu_user_regs *);
+static int kdbmain_fatal(struct cpu_user_regs *, int);
+static const char *kdb_gettrapname(int);
+
+/* ======================== GLOBAL VARIABLES =============================== */
+/* All global variables used by KDB must be defined here only. Module specific
+ * static variables must be declared in respective modules.
+ */
+kdbtab_t *kdb_cmd_tbl;
+char kdb_prompt[32];
+
+volatile kdb_cpu_cmd_t kdb_cpu_cmd[NR_CPUS];
+cpumask_t kdb_cpu_traps; /* bit per cpu to tell which cpus hit int3 */
+
+#ifndef NDEBUG
+ #error KDB is not supported on debug xen. Turn debug off
+#endif
+
+volatile int kdb_init_cpu = -1; /* initial kdb cpu */
+volatile int kdb_session_begun = 0; /* active kdb session? */
+volatile int kdb_enabled = 1; /* kdb enabled currently? */
+volatile int kdb_sys_crash = 0; /* are we in crashed state? */
+volatile int kdbdbg = 0; /* to debug kdb itself */
+
+static volatile int kdb_trap_immed_reason = 0; /* reason for immed trap */
+
+static cpumask_t kdb_fatal_cpumask; /* which cpus in fatal path */
+
+/* return index of first bit set in val. if val is 0, retval is undefined */
+static inline unsigned int kdb_firstbit(unsigned long val)
+{
+ __asm__ ( "bsf %1,%0" : "=r" (val) : "r" (val), "0" (BITS_PER_LONG) );
+ return (unsigned int)val;
+}
+
+static void
+kdb_dbg_prnt_ctrps(char *label, int ccpu)
+{
+ int i;
+ if (!kdbdbg)
+ return;
+
+ if (label || *label)
+ kdbp("%s ", label);
+ if (ccpu != -1)
+ kdbp("ccpu:%d ", ccpu);
+ kdbp("cputrps:");
+ for (i=sizeof(kdb_cpu_traps)/sizeof(kdb_cpu_traps.bits[0]) - 1; i >=0; i--)
+ kdbp(" %lx", kdb_cpu_traps.bits[i]);
+ kdbp("\n");
+}
+
+/*
+ * Hold this cpu. Don't disable until all CPUs in kdb to avoid IPI deadlock
+ */
+static void
+kdb_hold_this_cpu(int ccpu, struct cpu_user_regs *regs)
+{
+ KDBGP("ccpu:%d hold. cmd:%x\n", kdb_cpu_cmd[ccpu]);
+ do {
+ for(; kdb_cpu_cmd[ccpu] == KDB_CPU_PAUSE; cpu_relax());
+ KDBGP("ccpu:%d hold. cmd:%x\n", kdb_cpu_cmd[ccpu]);
+
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_DISABLE) {
+ local_irq_disable();
+ kdb_cpu_cmd[ccpu] = KDB_CPU_PAUSE;
+ }
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_DO_VMEXIT) {
+ kdb_curr_cpu_flush_vmcs();
+ kdb_cpu_cmd[ccpu] = KDB_CPU_PAUSE;
+ }
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_SHOWPC) {
+ kdbp("[%d]", ccpu);
+ kdb_display_pc(regs);
+ kdb_cpu_cmd[ccpu] = KDB_CPU_PAUSE;
+ }
+ } while (kdb_cpu_cmd[ccpu] == KDB_CPU_PAUSE); /* No goto, eh! */
+ KDBGP1("un hold: ccpu:%d cmd:%d\n", ccpu, kdb_cpu_cmd[ccpu]);
+}
+
+/*
+ * Pause this cpu while one CPU does main kdb processing. If that CPU does
+ * a "cpu switch" to this cpu, this cpu will become the main kdb cpu. If the
+ * user next does single step of some sort, this function will be exited,
+ * and this cpu will come back into kdb via kdb_handle_trap_entry function.
+ */
+static void
+kdb_pause_this_cpu(struct cpu_user_regs *regs, void *unused)
+{
+ kdbmain(KDB_REASON_PAUSE_IPI, regs);
+}
+
+/* pause other cpus via an IPI. Note, disabled CPUs can't receive IPIs until
+ * enabled */
+static void
+kdb_smp_pause_cpus(void)
+{
+ int cpu, wait_count = 0;
+ int ccpu = smp_processor_id(); /* current cpu */
+ cpumask_t cpumask = cpu_online_map;
+
+ cpumask_clear_cpu(smp_processor_id(), &cpumask);
+ for_each_cpu(cpu, &cpumask)
+ if (kdb_cpu_cmd[cpu] != KDB_CPU_INVAL) {
+ kdbp("KDB: won't pause cpu:%d, cmd[cpu]=%d\n",cpu,kdb_cpu_cmd[cpu]);
+ cpumask_clear_cpu(cpu, &cpumask);
+ }
+ KDBGP("ccpu:%d will pause cpus. mask:0x%lx\n", ccpu, cpumask.bits[0]);
+#if XEN_SUBVERSION > 4 || XEN_VERSION == 4 /* xen 3.5.x or above */
+ on_selected_cpus(&cpumask, (void (*)(void *))kdb_pause_this_cpu,
+ "XENKDB", 0);
+#else
+ on_selected_cpus(cpumask, (void (*)(void *))kdb_pause_this_cpu,
+ "XENKDB", 0, 0);
+#endif
+ mdelay(300); /* wait a bit for other CPUs to stop */
+ while(wait_count++ < 10) {
+ int bummer = 0;
+ for_each_cpu(cpu, &cpumask)
+ if (kdb_cpu_cmd[cpu] != KDB_CPU_PAUSE)
+ bummer = 1;
+ if (!bummer)
+ break;
+ kdbp("ccpu:%d trying to stop other cpus...\n", ccpu);
+ mdelay(100); /* wait 100 ms */
+ };
+ for_each_cpu(cpu, &cpumask) /* now check who is with us */
+ if (kdb_cpu_cmd[cpu] != KDB_CPU_PAUSE)
+ kdbp("Bummer cpu %d not paused. ccpu:%d\n", cpu,ccpu);
+ else {
+ kdb_cpu_cmd[cpu] = KDB_CPU_DISABLE; /* tell it to disable ints */
+ while (kdb_cpu_cmd[cpu] != KDB_CPU_PAUSE);
+ }
+}
+
+/*
+ * Do once per kdb session: A kdb session lasts from
+ * keybord/HWBP/SWBP till KDB_CPU_INSTALL_BP is done. Within a session,
+ * user may do several cpu switches, single step, next instr, etc..
+ *
+ * DO: 1. pause other cpus if they are not already. they would already be
+ * if we are in single step mode
+ * 2. watchdog_disable()
+ * 3. uninstall all sw breakpoints so that user doesn't see them
+ */
+static void
+kdb_begin_session(void)
+{
+ if (!kdb_session_begun) {
+ kdb_session_begun = 1;
+ kdb_smp_pause_cpus();
+ local_irq_disable();
+ watchdog_disable();
+ kdb_uninstall_all_swbp();
+ }
+}
+
+static void
+kdb_smp_unpause_cpus(int ccpu)
+{
+ int cpu;
+
+ int wait_count = 0;
+ cpumask_t cpumask = cpu_online_map;
+
+ cpumask_clear_cpu(smp_processor_id(), &cpumask);
+
+ KDBGP("kdb_smp_unpause_other_cpus(). ccpu:%d\n", ccpu);
+ for_each_cpu(cpu, &cpumask)
+ kdb_cpu_cmd[cpu] = KDB_CPU_QUIT;
+
+ while(wait_count++ < 10) {
+ int bummer = 0;
+ for_each_cpu(cpu, &cpumask)
+ if (kdb_cpu_cmd[cpu] != KDB_CPU_INVAL)
+ bummer = 1;
+ if (!bummer)
+ break;
+ mdelay(90); /* wait 90 ms, 50 too short on large systems */
+ };
+ /* now make sure they are all in there */
+ for_each_cpu(cpu, &cpumask)
+ if (kdb_cpu_cmd[cpu] != KDB_CPU_INVAL)
+ kdbp("KDB: cpu %d still paused (cmd==%d). ccpu:%d\n",
+ cpu, kdb_cpu_cmd[cpu], ccpu);
+}
+
+/*
+ * End of KDB session.
+ * This is called at the very end. In case of multiple cpus hitting BPs
+ * and sitting on a trap handlers, the last cpu to exit will call this.
+ * - isnstall all sw breakpoints, and purge deleted ones from table.
+ * - clear TF here also in case go is entered on a different cpu after switch
+ */
+static void
+kdb_end_session(int ccpu, struct cpu_user_regs *regs)
+{
+ ASSERT(!cpumask_empty(&kdb_cpu_traps));
+ ASSERT(kdb_session_begun);
+ kdb_install_all_swbp();
+ kdb_flush_swbp_table();
+ kdb_install_watchpoints();
+
+ regs->eflags &= ~X86_EFLAGS_TF;
+ kdb_cpu_cmd[ccpu] = KDB_CPU_INVAL;
+ kdb_time_resume(1);
+ kdb_session_begun = 0; /* before unpause for kdb_install_watchpoints */
+ kdb_smp_unpause_cpus(ccpu);
+ watchdog_enable();
+ KDBGP("end_session:ccpu:%d\n", ccpu);
+}
+
+/*
+ * check if we entered kdb because of DB trap. If yes, then check if
+ * we caused it or someone else.
+ * RETURNS: 0 : not one of ours. hypervisor must handle it.
+ * 1 : #DB for delayed sw bp install.
+ * 2 : this cpu must stay in kdb.
+ */
+static noinline int
+kdb_check_dbtrap(kdb_reason_t *reasp, int ss_mode, struct cpu_user_regs *regs)
+{
+ int rc = 2;
+ int ccpu = smp_processor_id();
+
+ /* DB excp caused by hw breakpoint or the TF flag. The TF flag is set
+ * by us for ss mode or to install breakpoints. In ss mode, none of the
+ * breakpoints are installed. Check to make sure we intended BP INSTALL
+ * so we don't do it on a spurious DB trap.
+ * check for kdb_cpu_traps here also, because each cpu sitting on a trap
+ * must execute the instruction without the BP before passing control
+ * to next cpu in kdb_cpu_traps.
+ */
+ if (*reasp == KDB_REASON_DBEXCP && !ss_mode) {
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_INSTALL_BP) {
+ if (!cpumask_empty(&kdb_cpu_traps)) {
+ int a_trap_cpu = cpumask_first(&kdb_cpu_traps);
+ KDBGP("ccpu:%d trapcpu:%d\n", ccpu, a_trap_cpu);
+ kdb_cpu_cmd[a_trap_cpu] = KDB_CPU_QUIT;
+ *reasp = KDB_REASON_PAUSE_IPI;
+ regs->eflags &= ~X86_EFLAGS_TF; /* hvm: exit handler ss = 0 */
+ kdb_init_cpu = -1;
+ } else {
+ kdb_end_session(ccpu, regs);
+ rc = 1;
+ }
+ } else if (! kdb_check_watchpoints(regs)) {
+ rc = 0; /* hyp must handle it */
+ }
+ }
+ return rc;
+}
+
+/*
+ * Misc processing on kdb entry like displaying PC, adjust IP for sw bp....
+ */
+static void
+kdb_main_entry_misc(kdb_reason_t reason, struct cpu_user_regs *regs,
+ int ccpu, int ss_mode, int enabled)
+{
+ if (reason == KDB_REASON_KEYBOARD)
+ kdbp("\nEnter kdb (cpu:%d reason:%d vcpu=%d domid:%d"
+ " eflg:0x%lx irqs:%d)\n", ccpu, reason, current->vcpu_id,
+ current->domain->domain_id, regs->eflags, enabled);
+ else if (ss_mode)
+ KDBGP1("KDBG: KDB single step mode. ccpu:%d\n", ccpu);
+
+ if (reason == KDB_REASON_BPEXCP && !ss_mode)
+ kdbp("Breakpoint on cpu %d at 0x%lx\n", ccpu, regs->KDBIP);
+
+ /* display the current PC and instruction at it */
+ if (reason != KDB_REASON_PAUSE_IPI)
+ kdb_display_pc(regs);
+ console_start_sync();
+}
+
+/*
+ * The MAIN kdb function. All cpus go thru this. IRQ is enabled on entry because
+ * a cpu could hit a bp set in disabled code.
+ * IPI: Even the main cpu must enable in case another CPU is trying to IPI us.
+ * That way, it would IPI us, then get out and be ready for our pause IPI.
+ * IRQs: The reason irqs enable/disable is scattered is because on a typical
+ * system IPIs are constantly going on amongs CPUs in a set of any size.
+ * As a result, to avoid deadlock, cpus have to loop enabled, until a
+ * quorum is established and the session has begun.
+ * Step: Intel Vol3B 18.3.1.4 : An external interrupt may be serviced upon
+ * single step. Since, the likely ext timer_interrupt and
+ * apic_timer_interrupt dont' mess with time data structs, we are prob OK
+ * leaving enabled.
+ * Time: Very messy. Most platform timers are readonly, so we can't stop time
+ * in the debugger. We take the only resort, let the TSC and plt run as
+ * normal, upon leaving, "attempt" to bring everybody to current time.
+ * kdbcputraps: bit per cpu. each cpu sets it bit in entry.S. The bit is
+ * reliable because upon traps, Ints are disabled. the bit is set
+ * before Ints are enabled.
+ *
+ * RETURNS: 0 : kdb was called for event it was not responsible
+ * 1 : event owned and handled by kdb
+ */
+static int
+kdbmain(kdb_reason_t reason, struct cpu_user_regs *regs)
+{
+ int ccpu = smp_processor_id(); /* current cpu */
+ int rc = 1, cmd = kdb_cpu_cmd[ccpu];
+ int ss_mode = (cmd == KDB_CPU_SS || cmd == KDB_CPU_NI);
+ int delayed_install = (kdb_cpu_cmd[ccpu] == KDB_CPU_INSTALL_BP);
+ int enabled = local_irq_is_enabled();
+
+ KDBGP("kdbmain:ccpu:%d rsn:%d eflgs:0x%lx cmd:%d initc:%d irqs:%d "
+ "regs:%lx IP:%lx ", ccpu, reason, regs->eflags, cmd,
+ kdb_init_cpu, enabled, regs, regs->KDBIP);
+ kdb_dbg_prnt_ctrps("", -1);
+
+ if (!ss_mode && !delayed_install) /* initial kdb enter */
+ local_irq_enable(); /* so we can receive IPI */
+
+ if (!ss_mode && ccpu != kdb_init_cpu && reason != KDB_REASON_PAUSE_IPI){
+ int sz = sizeof(kdb_init_cpu);
+ while (__cmpxchg(&kdb_init_cpu, -1, ccpu, sz) != -1)
+ for(; kdb_init_cpu != -1; cpu_relax());
+ }
+ if (kdb_session_begun)
+ local_irq_disable(); /* kdb always runs disabled */
+
+ if (reason == KDB_REASON_BPEXCP) { /* INT 3 */
+ cpumask_clear_cpu(ccpu, &kdb_cpu_traps); /* remove ourself */
+ rc = kdb_check_sw_bkpts(regs);
+ if (rc == 0) { /* not one of ours. leave kdb */
+ kdb_init_cpu = -1;
+ goto out;
+ } else if (rc == 1) { /* one of ours but deleted */
+ if (cpumask_empty(&kdb_cpu_traps)) {
+ kdb_end_session(ccpu,regs);
+ kdb_init_cpu = -1;
+ goto out;
+ } else {
+ /* release another trap cpu, and put ourself in a pause mode */
+ int a_trap_cpu = cpumask_first(&kdb_cpu_traps);
+ KDBGP("ccpu:%d cmd:%d rsn:%d atrpcpu:%d initcpu:%d\n", ccpu,
+ kdb_cpu_cmd[ccpu], reason, a_trap_cpu, kdb_init_cpu);
+ kdb_cpu_cmd[a_trap_cpu] = KDB_CPU_QUIT;
+ reason = KDB_REASON_PAUSE_IPI;
+ kdb_init_cpu = -1;
+ }
+ } else if (rc == 2) { /* one of ours but condition not met */
+ kdb_begin_session();
+ if (guest_mode(regs) && is_hvm_or_hyb_vcpu(current))
+ current->arch.hvm_vcpu.single_step = 1;
+ else
+ regs->eflags |= X86_EFLAGS_TF;
+ kdb_cpu_cmd[ccpu] = KDB_CPU_INSTALL_BP;
+ goto out;
+ }
+ }
+
+ /* following will take care of KDB_CPU_INSTALL_BP, and also release
+ * kdb_init_cpu. it should not be done twice */
+ if ((rc=kdb_check_dbtrap(&reason, ss_mode, regs)) == 0 || rc == 1) {
+ kdb_init_cpu = -1; /* leaving kdb */
+ goto out; /* rc properly set to 0 or 1 */
+ }
+ if (reason != KDB_REASON_PAUSE_IPI) {
+ kdb_cpu_cmd[ccpu] = KDB_CPU_MAIN_KDB;
+ } else
+ kdb_cpu_cmd[ccpu] = KDB_CPU_PAUSE;
+
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_MAIN_KDB && !ss_mode)
+ kdb_begin_session();
+
+ kdb_main_entry_misc(reason, regs, ccpu, ss_mode, enabled);
+ /* note, one or more cpu switches may occur in between */
+ while (1) {
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_PAUSE)
+ kdb_hold_this_cpu(ccpu, regs);
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_MAIN_KDB)
+ kdb_do_cmds(regs);
+
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_GO) {
+ if (ccpu != kdb_init_cpu) {
+ kdb_cpu_cmd[kdb_init_cpu] = KDB_CPU_GO;
+ kdb_cpu_cmd[ccpu] = KDB_CPU_PAUSE;
+ continue; /* for the pause guy */
+ }
+ if (!cpumask_empty(&kdb_cpu_traps)) {
+ /* execute current instruction without 0xcc */
+ kdb_dbg_prnt_ctrps("nempty:", ccpu);
+ if (guest_mode(regs) && is_hvm_or_hyb_vcpu(current))
+ current->arch.hvm_vcpu.single_step = 1;
+ else
+ regs->eflags |= X86_EFLAGS_TF;
+ kdb_cpu_cmd[ccpu] = KDB_CPU_INSTALL_BP;
+ goto out;
+ }
+ }
+ if (kdb_cpu_cmd[ccpu] != KDB_CPU_PAUSE &&
+ kdb_cpu_cmd[ccpu] != KDB_CPU_MAIN_KDB)
+ break;
+ }
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_GO) {
+ ASSERT(cpumask_empty(&kdb_cpu_traps));
+ if (kdb_swbp_exists()) {
+ if (reason == KDB_REASON_BPEXCP) {
+ /* do delayed install */
+ if (guest_mode(regs) && is_hvm_or_hyb_vcpu(current))
+ current->arch.hvm_vcpu.single_step = 1;
+ else
+ regs->eflags |= X86_EFLAGS_TF;
+ kdb_cpu_cmd[ccpu] = KDB_CPU_INSTALL_BP;
+ goto out;
+ }
+ }
+ kdb_end_session(ccpu, regs);
+ kdb_init_cpu = -1;
+ }
+out:
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_QUIT) {
+ KDBGP("ccpu:%d _quit IP: %lx\n", ccpu, regs->KDBIP);
+ if (! kdb_session_begun)
+ kdb_install_watchpoints();
+ kdb_time_resume(0);
+ kdb_cpu_cmd[ccpu] = KDB_CPU_INVAL;
+ }
+
+ /* for ss and delayed install, TF is set. not much in EXT INT handlers*/
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_NI)
+ kdb_time_resume(1);
+ if (enabled)
+ local_irq_enable();
+
+ KDBGP("kdbmain:X:ccpu:%d rc:%d cmd:%d eflg:0x%lx initc:%d sesn:%d "
+ "cs:%x irqs:%d ", ccpu, rc, kdb_cpu_cmd[ccpu], regs->eflags,
+ kdb_init_cpu, kdb_session_begun, regs->cs, local_irq_is_enabled());
+ kdb_dbg_prnt_ctrps("", -1);
+ return (rc ? 1 : 0);
+}
+
+/*
+ * kdb entry function when coming in via a keyboard
+ * RETURNS: 0 : kdb was called for event it was not responsible
+ * 1 : event owned and handled by kdb
+ */
+int
+kdb_keyboard(struct cpu_user_regs *regs)
+{
+ return kdbmain(KDB_REASON_KEYBOARD, regs);
+}
+
+#if 0
+/*
+ * this function called when kdb session active and user presses ctrl\ again.
+ * the assumption is that the user typed ni/ss cmd, and it never got back into
+ * kdb, or the user is impatient. Either case, we just fake it that the SS did
+ * finish. Since, all other kdb cpus must be holding disabled, the interrupt
+ * would be on the CPU that did the ss/ni cmd
+ */
+void
+kdb_ssni_reenter(struct cpu_user_regs *regs)
+{
+ int ccpu = smp_processor_id();
+ int ccmd = kdb_cpu_cmd[ccpu];
+
+ if(ccmd == KDB_CPU_SS || ccmd == KDB_CPU_INSTALL_BP)
+ kdbmain(KDB_REASON_DBEXCP, regs);
+ else
+ kdbmain(KDB_REASON_KEYBOARD, regs);
+}
+#endif
+
+/*
+ * All traps are routed thru here. We care about BP (#3) trap (INT 3) and
+ * the DB trap(#1) only.
+ * returns: 0 kdb has nothing do with this trap
+ * 1 kdb handled this trap
+ */
+int
+kdb_handle_trap_entry(int vector, struct cpu_user_regs *regs)
+{
+ int rc = 0;
+ int ccpu = smp_processor_id();
+
+ if (vector == TRAP_int3) {
+ rc = kdbmain(KDB_REASON_BPEXCP, regs);
+
+ } else if (vector == TRAP_debug) {
+ KDBGP("ccpu:%d trapdbg reas:%d\n", ccpu, kdb_trap_immed_reason);
+
+ if (kdb_trap_immed_reason == KDB_TRAP_FATAL) {
+ KDBGP("kdbtrp:fatal ccpu:%d vec:%d\n", ccpu, vector);
+ rc = kdbmain_fatal(regs, vector);
+ BUG(); /* no return */
+
+ } else if (kdb_trap_immed_reason == KDB_TRAP_KDBSTACK) {
+ kdb_trap_immed_reason = 0; /* show kdb stack */
+ show_registers(regs);
+ show_stack(regs);
+ regs->eflags &= ~X86_EFLAGS_TF;
+ rc = 1;
+
+ } else if (kdb_trap_immed_reason == KDB_TRAP_NONFATAL) {
+ kdb_trap_immed_reason = 0;
+ rc = kdb_keyboard(regs);
+ } else { /* ss/ni/delayed install... */
+ if (guest_mode(regs) && is_hvm_or_hyb_vcpu(current))
+ current->arch.hvm_vcpu.single_step = 0;
+ rc = kdbmain(KDB_REASON_DBEXCP, regs);
+ }
+
+ } else if (vector == TRAP_nmi) { /* external nmi */
+ /* when nmi is pressed, it could go to one or more or all cpus
+ * depending on the hardware. Also, for now assume it's fatal */
+ KDBGP("kdbtrp:ccpu:%d vec:%d\n", ccpu, vector);
+ rc = kdbmain_fatal(regs, TRAP_nmi);
+ }
+ return rc;
+}
+
+int
+kdb_trap_fatal(int vector, struct cpu_user_regs *regs)
+{
+ kdbmain_fatal(regs, vector);
+ return 0;
+}
+
+/* From smp_send_nmi_allbutself() in crash.c which is static */
+void
+kdb_nmi_pause_cpus(cpumask_t cpumask)
+{
+ int ccpu = smp_processor_id();
+ mdelay(200);
+ cpumask_complement(&cpumask, &cpumask); /* flip bit map */
+ cpumask_and(&cpumask, &cpumask, &cpu_online_map); /* remove extra bits */
+ cpumask_clear_cpu(ccpu, &cpumask);/* absolutely make sure we're not on it */
+
+ KDBGP("ccpu:%d nmi pause. mask:0x%lx\n", ccpu, cpumask.bits[0]);
+ if ( !cpumask_empty(&cpumask) )
+#if XEN_SUBVERSION > 4 || XEN_VERSION == 4 /* xen 3.5.x or above */
+ send_IPI_mask(&cpumask, APIC_DM_NMI);
+#else
+ send_IPI_mask(cpumask, APIC_DM_NMI);
+#endif
+ mdelay(200);
+ KDBGP("ccpu:%d nmi pause done...\n", ccpu);
+}
+
+/*
+ * Separate function from kdbmain to keep both within sanity levels.
+ */
+DEFINE_SPINLOCK(kdb_fatal_lk);
+static int
+kdbmain_fatal(struct cpu_user_regs *regs, int vector)
+{
+ int ccpu = smp_processor_id();
+
+ console_start_sync();
+
+ KDBGP("mainf:ccpu:%d vec:%d irq:%d\n", ccpu, vector,local_irq_is_enabled());
+ cpumask_set_cpu(ccpu, &kdb_fatal_cpumask); /* uses LOCK_PREFIX */
+
+ if (spin_trylock(&kdb_fatal_lk)) {
+
+ kdbp("*** kdb (Fatal Error on cpu:%d vec:%d %s):\n", ccpu,
+ vector, kdb_gettrapname(vector));
+ kdb_cpu_cmd[ccpu] = KDB_CPU_MAIN_KDB;
+ kdb_display_pc(regs);
+
+ watchdog_disable(); /* important */
+ kdb_sys_crash = 1;
+ kdb_session_begun = 0; /* incase session already active */
+ local_irq_enable();
+ kdb_nmi_pause_cpus(kdb_fatal_cpumask);
+
+ kdb_clear_prev_cmd(); /* buffered CRs will repeat prev cmd */
+ kdb_session_begun = 1; /* for kdb_hold_this_cpu() */
+ local_irq_disable();
+ } else {
+ kdb_cpu_cmd[ccpu] = KDB_CPU_PAUSE;
+ }
+ while (1) {
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_PAUSE)
+ kdb_hold_this_cpu(ccpu, regs);
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_MAIN_KDB)
+ kdb_do_cmds(regs);
+#if 0
+ /* dump is the only way to exit in crashed state */
+ if (kdb_cpu_cmd[ccpu] == KDB_CPU_DUMP)
+ kdb_do_dump(regs);
+#endif
+ }
+ return 0;
+}
+
+/* Mostly called in fatal cases. earlykdb calls non-fatal.
+ * kdb_trap_immed_reason is global, so allow only one cpu at a time. Also,
+ * multiple cpu may be crashing at the same time. We enable because if there
+ * is a bad hang, at least ctrl-\ will break into kdb. Also, we don't call
+ * call kdb_keyboard directly becaue we don't have the register context.
+ */
+DEFINE_SPINLOCK(kdb_immed_lk);
+void
+kdb_trap_immed(int reason) /* fatal, non-fatal, kdb stack etc... */
+{
+ int ccpu = smp_processor_id();
+ int disabled = !local_irq_is_enabled();
+
+ KDBGP("trapimm:ccpu:%d reas:%d\n", ccpu, reason);
+ local_irq_enable();
+ spin_lock(&kdb_immed_lk);
+ kdb_trap_immed_reason = reason;
+ barrier();
+ __asm__ __volatile__ ( "int $1" );
+ kdb_trap_immed_reason = 0;
+
+ spin_unlock(&kdb_immed_lk);
+ if (disabled)
+ local_irq_disable();
+}
+
+/* called very early during init, even before all CPUs are brought online */
+void
+kdb_init(void)
+{
+ kdb_init_cmdtab(); /* Initialize Command Table */
+}
+
+static const char *
+kdb_gettrapname(int trapno)
+{
+ char *ret;
+ switch (trapno) {
+ case 0: ret = "Divide Error"; break;
+ case 2: ret = "NMI Interrupt"; break;
+ case 3: ret = "Int 3 Trap"; break;
+ case 4: ret = "Overflow Error"; break;
+ case 6: ret = "Invalid Opcode"; break;
+ case 8: ret = "Double Fault"; break;
+ case 10: ret = "Invalid TSS"; break;
+ case 11: ret = "Segment Not Present"; break;
+ case 12: ret = "Stack-Segment Fault"; break;
+ case 13: ret = "General Protection"; break;
+ case 14: ret = "Page Fault"; break;
+ case 17: ret = "Alignment Check"; break;
+ default: ret = " ????? ";
+ }
+ return ret;
+}
+
+
+/* ====================== Generic tracing subsystem ======================== */
+
+#define KDBTRCMAX 1 /* set this to max number of recs to trace. each rec
+ * is 32 bytes */
+volatile int kdb_trcon=1; /* turn tracing ON: set here or via the trcon cmd */
+
+typedef struct {
+ union {
+ struct { uint d0; uint cpu_trcid; } s0;
+ uint64_t l0;
+ }u;
+ uint64_t l1, l2, l3;
+} trc_rec_t;
+
+static volatile unsigned int trcidx; /* points to where new entry will go */
+static trc_rec_t trca[KDBTRCMAX]; /* trace array */
+
+/* atomically: add i to *p, return prev value of *p (ie, val before add) */
+static int
+kdb_fetch_and_add(int i, uint *p)
+{
+ asm volatile("lock xaddl %0, %1;" : "=r"(i) : "m"(*p), "0"(i));
+ return i;
+}
+
+/* zero out the entire buffer */
+void
+kdb_trczero(void)
+{
+ for (trcidx = KDBTRCMAX-1; trcidx; trcidx--) {
+ memset(&trca[trcidx], 0, sizeof(trc_rec_t));
+ }
+ memset(&trca[trcidx], 0, sizeof(trc_rec_t));
+ kdbp("kdb trace buffer has been zeroed\n");
+}
+
+/* add trace entry: eg.: kdbtrc(0xe0f099, intdata, vcpu, domain, 0)
+ * where: 0xe0f099 : 24bits max trcid, lower 8 bits are set to cpuid */
+void
+kdbtrc(uint trcid, uint int_d0, uint64_t d1_64, uint64_t d2_64, uint64_t d3_64)
+{
+ uint idx;
+
+ if (!kdb_trcon)
+ return;
+
+ idx = kdb_fetch_and_add(1, (uint*)&trcidx);
+ idx = idx % KDBTRCMAX;
+
+#if 0
+ trca[idx].u.s0.cpu_trcid = (smp_processor_id()<<24) | trcid;
+#endif
+ trca[idx].u.s0.cpu_trcid = (trcid<<8) | smp_processor_id();
+ trca[idx].u.s0.d0 = int_d0;
+ trca[idx].l1 = d1_64;
+ trca[idx].l2 = d2_64;
+ trca[idx].l3 = d3_64;
+}
+
+/* give hints so user can print trc buffer via the dd command. last has the
+ * most recent entry */
+void
+kdb_trcp(void)
+{
+ int i = trcidx % KDBTRCMAX;
+
+ i = (i==0) ? KDBTRCMAX-1 : i-1;
+ kdbp("trcbuf: [0]: %016lx [MAX-1]: %016lx\n", &trca[0],
+ &trca[KDBTRCMAX-1]);
+ kdbp(" [most recent]: %016lx trcidx: 0x%x\n", &trca[i], trcidx);
+}
+
diff -r 32034d1914a6 xen/kdb/x86/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/Makefile Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,3 @@
+
+obj-y := kdb_wp.o
+subdir-y += udis86-1.7
diff -r 32034d1914a6 xen/kdb/x86/kdb_wp.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/kdb_wp.c Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2009, Mukesh Rathor, Oracle Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include "../include/kdbinc.h"
+
+#if 0
+#define DR6_BT 0x00008000
+#define DR6_BS 0x00004000
+#define DR6_BD 0x00002000
+#endif
+#define DR6_B3 0x00000008
+#define DR6_B2 0x00000004
+#define DR6_B1 0x00000002
+#define DR6_B0 0x00000001
+
+#define KDB_MAXWP 4 /* DR0 thru DR3 */
+
+struct kdb_wp {
+ kdbma_t wp_addr;
+ int wp_rwflag;
+ int wp_len;
+ int wp_deleted; /* pending delete */
+};
+static struct kdb_wp kdb_wpa[KDB_MAXWP];
+
+/* following because vmcs has it's own dr7. when vmcs runs, it messes up the
+ * native dr7 so we need to save/restore it */
+unsigned long kdb_dr7;
+
+
+/* Set G0-G3 bits in DR7. this does global enable of the corresponding wp */
+static void
+kdb_set_gx_in_dr7(int regno, kdbma_t *dr7p)
+{
+ if (regno == 0)
+ *dr7p = *dr7p | 0x2;
+ else if (regno == 1)
+ *dr7p = *dr7p | 0x8;
+ else if (regno == 2)
+ *dr7p = *dr7p | 0x20;
+ else if (regno == 3)
+ *dr7p = *dr7p | 0x80;
+}
+
+/* Set LEN0 - LEN3 pair bits in DR7 (len should be 1 2 4 or 8) */
+static void
+kdb_set_len_in_dr7(int regno, kdbma_t *dr7p, int len)
+{
+ int lenbits = (len == 8) ? 2 : len-1;
+
+ *dr7p &= ~(0x3 << (18 + 4*regno));
+ *dr7p |= ((ulong)(lenbits & 0x3) << (18 + 4*regno));
+}
+
+static void
+kdb_set_dr7_rw(int regno, kdbma_t *dr7p, int rw)
+{
+ *dr7p &= ~(0x3 << (16 + 4*regno));
+ *dr7p |= ((ulong)(rw & 0x3)) << (16 + 4*regno);
+}
+
+/* get value of a debug register: DR0-DR3 DR6 DR7. other values return 0 */
+kdbma_t
+kdb_rd_dbgreg(int regnum)
+{
+ kdbma_t contents = 0;
+
+ if (regnum == 0)
+ __asm__ ("movq %%db0,%0\n\t":"=r"(contents));
+ else if (regnum == 1)
+ __asm__ ("movq %%db1,%0\n\t":"=r"(contents));
+ else if (regnum == 2)
+ __asm__ ("movq %%db2,%0\n\t":"=r"(contents));
+ else if (regnum == 3)
+ __asm__ ("movq %%db3,%0\n\t":"=r"(contents));
+ else if (regnum == 6)
+ __asm__ ("movq %%db6,%0\n\t":"=r"(contents));
+ else if (regnum == 7)
+ __asm__ ("movq %%db7,%0\n\t":"=r"(contents));
+
+ return contents;
+}
+
+static void
+kdb_wr_dbgreg(int regnum, kdbma_t contents)
+{
+ if (regnum == 0)
+ __asm__ ("movq %0,%%db0\n\t"::"r"(contents));
+ else if (regnum == 1)
+ __asm__ ("movq %0,%%db1\n\t"::"r"(contents));
+ else if (regnum == 2)
+ __asm__ ("movq %0,%%db2\n\t"::"r"(contents));
+ else if (regnum == 3)
+ __asm__ ("movq %0,%%db3\n\t"::"r"(contents));
+ else if (regnum == 6)
+ __asm__ ("movq %0,%%db6\n\t"::"r"(contents));
+ else if (regnum == 7)
+ __asm__ ("movq %0,%%db7\n\t"::"r"(contents));
+}
+
+static void
+kdb_print_wp_info(char *strp, int idx)
+{
+ kdbp("%s[%d]:%016lx len:%d ", strp, idx, kdb_wpa[idx].wp_addr,
+ kdb_wpa[idx].wp_len);
+ if (kdb_wpa[idx].wp_rwflag == 1)
+ kdbp("on data write only\n");
+ else if (kdb_wpa[idx].wp_rwflag == 2)
+ kdbp("on IO read/write\n");
+ else
+ kdbp("on data read/write\n");
+}
+
+/*
+ * Returns : 0 if not one of ours
+ * 1 if one of ours
+ */
+int
+kdb_check_watchpoints(struct cpu_user_regs *regs)
+{
+ int wpnum;
+ kdbma_t dr6 = kdb_rd_dbgreg(6);
+
+ KDBGP1("check_wp: IP:%lx EFLAGS:%lx\n", regs->rip, regs->rflags);
+ if (dr6 & DR6_B0)
+ wpnum = 0;
+ else if (dr6 & DR6_B1)
+ wpnum = 1;
+ else if (dr6 & DR6_B2)
+ wpnum = 2;
+ else if (dr6 & DR6_B3)
+ wpnum = 3;
+ else
+ return 0;
+
+ kdb_print_wp_info("Watchpoint ", wpnum);
+ return 1;
+}
+
+/* set a watchpoint at a given address
+ * PreCondition: addr != 0 */
+static void
+kdb_set_wp(kdbva_t addr, int rwflag, int len)
+{
+ int regno;
+
+ for (regno=0; regno < KDB_MAXWP; regno++) {
+ if (kdb_wpa[regno].wp_addr == addr && !kdb_wpa[regno].wp_deleted) {
+ kdbp("Watchpoint already set\n");
+ return;
+ }
+ if (kdb_wpa[regno].wp_deleted)
+ memset(&kdb_wpa[regno], 0, sizeof(kdb_wpa[regno]));
+ }
+ for (regno=0; regno < KDB_MAXWP && kdb_wpa[regno].wp_addr; regno++);
+ if (regno >= KDB_MAXWP) {
+ kdbp("watchpoint table full. limit:%d\n", KDB_MAXWP);
+ return;
+ }
+ kdb_wpa[regno].wp_addr = addr;
+ kdb_wpa[regno].wp_rwflag = rwflag;
+ kdb_wpa[regno].wp_len = len;
+ kdb_print_wp_info("Watchpoint set ", regno);
+}
+
+/* write reg DR0-3 with address. Update corresponding bits in DR7 */
+static void
+kdb_install_watchpoint(int regno, kdbma_t *dr7p)
+{
+ kdb_set_gx_in_dr7(regno, dr7p);
+ kdb_set_len_in_dr7(regno, dr7p, kdb_wpa[regno].wp_len);
+ kdb_set_dr7_rw(regno, dr7p, kdb_wpa[regno].wp_rwflag);
+ kdb_wr_dbgreg(regno, kdb_wpa[regno].wp_addr);
+
+ KDBGP1("ccpu:%d installed wp. addr:%lx rw:%x len:%x dr7:%016lx\n",
+ smp_processor_id(), kdb_wpa[regno].wp_addr,
+ kdb_wpa[regno].wp_rwflag, kdb_wpa[regno].wp_len, *dr7p);
+}
+
+/* clear G0-G3 bits in DR7 for given DR0-3 */
+static void
+kdb_clear_dr7_gx(int regno, kdbma_t *dr7p)
+{
+ if (regno == 0)
+ *dr7p = *dr7p & ~0x2;
+ else if (regno == 1)
+ *dr7p = *dr7p & ~0x8;
+ else if (regno == 2)
+ *dr7p = *dr7p & ~0x20;
+ else if (regno == 3)
+ *dr7p = *dr7p & ~0x80;
+}
+
+/* update dr7 once, as it's slow to update debug regs and cpu's will still be
+ * paused when leaving kdb.
+ *
+ * Just leave DR0-3 clobbered but remove bits from DR7 to disable wp
+ */
+void
+kdb_install_watchpoints(void)
+{
+ int regno;
+ kdbma_t dr7 = kdb_rd_dbgreg(7);
+
+ for (regno=0; regno < KDB_MAXWP; regno++) {
+ /* do not clear wp_deleted here as all cpus must clear wps */
+ if (kdb_wpa[regno].wp_deleted) {
+ kdb_clear_dr7_gx(regno, &dr7);
+ continue;
+ }
+ if (kdb_wpa[regno].wp_addr)
+ kdb_install_watchpoint(regno, &dr7);
+ }
+ /* always clear DR6 when leaving */
+ kdb_wr_dbgreg(6, 0);
+ kdb_wr_dbgreg(7, dr7);
+
+ if (dr7 & DR7_ACTIVE_MASK)
+ kdb_dr7 = dr7;
+ else
+ kdb_dr7 = 0;
+#if 0
+ for(dp=domain_list; dp; dp=dp->next_in_list) {
+ struct vcpu *vp;
+ for_each_vcpu(dp, vp) {
+ for (regno=0; regno < KDB_MAXWP; regno++)
+ vp->arch.guest_context.debugreg[regno] = kdb_wpa[regno].wp_addr;
+
+ vp->arch.guest_context.debugreg[6] = 0;
+ vp->arch.guest_context.debugreg[7] = dr7;
+ KDBGP("kdb_install_watchpoints(): v:%p dr7:%lx\n", vp, dr7);
+ /* hvm_set_info_guest(vp);: Can't because can't vmcs_enter in kdb */
+ }
+ }
+#endif
+}
+
+/* clear watchpoint/s. wpnum == -1 to clear all watchpoints */
+void
+kdb_clear_wps(int wpnum)
+{
+ int i;
+
+ if (wpnum >= KDB_MAXWP) {
+ kdbp("Invalid wpnum %d\n", wpnum);
+ return;
+ }
+ if (wpnum >=0) {
+ if (kdb_wpa[wpnum].wp_addr) {
+ kdb_wpa[wpnum].wp_deleted = 1;
+ kdb_print_wp_info("Deleted watchpoint", wpnum);
+ } else
+ kdbp("watchpoint %d not set\n", wpnum);
+ return;
+ }
+ for (i=0; i < KDB_MAXWP; i++) {
+ if (kdb_wpa[i].wp_addr) {
+ kdb_wpa[i].wp_deleted = 1;
+ kdb_print_wp_info("Deleted watchpoint", i);
+ }
+ }
+}
+
+/* display any watchpoints that are set */
+static void
+kdb_display_wps(void)
+{
+ int i;
+ for (i=0; i < KDB_MAXWP; i++)
+ if (kdb_wpa[i].wp_addr && !kdb_wpa[i].wp_deleted)
+ kdb_print_wp_info("", i);
+}
+
+/*
+ * Display or Set hardware breakpoints, ie, watchpoints:
+ * - Upto 4 are allowed
+ *
+ * rw_flag should be one of:
+ * 01 == break on data write only
+ * 10 == break on IO read/write
+ * 11 == Break on data reads or writes
+ *
+ * len should be one of : 1 2 4 8
+ */
+void
+kdb_do_watchpoints(kdbva_t addr, int rw_flag, int len)
+{
+ if (addr == 0) {
+ kdb_display_wps(); /* display set watchpoints */
+ return;
+ }
+ kdb_set_wp(addr, rw_flag, len);
+ return;
+}
+
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/LICENSE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/LICENSE Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,22 @@
+Copyright (c) 2002, 2003, 2004, 2005, 2006 <vivek@sig9.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/Makefile Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,5 @@
+
+CFLAGS += -D__UD_STANDALONE__
+obj-y := decode.o input.o itab.o kdb_dis.o syn-att.o syn.o \
+ syn-intel.o udis86.o
+
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/README
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/README Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,10 @@
+
+http://udis86.sourceforge.net/
+udis86-1.6 :
+ - cd libudis86
+ - cp *c to here
+ - cp *h to here
+
+Mukesh Rathor
+04/30/2008
+
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/decode.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/decode.c Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,1197 @@
+/* -----------------------------------------------------------------------------
+ * decode.c
+ *
+ * Copyright (c) 2005, 2006, Vivek Mohan <vivek@sig9.com>
+ * All rights reserved. See LICENSE
+ * -----------------------------------------------------------------------------
+ */
+
+#if 0
+#include <assert.h>
+#include <string.h>
+#endif
+
+#include "types.h"
+#include "itab.h"
+#include "input.h"
+#include "decode.h"
+
+/* The max number of prefixes to an instruction */
+#define MAX_PREFIXES 15
+
+static struct ud_itab_entry ie_invalid = { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none };
+static struct ud_itab_entry ie_pause = { UD_Ipause, O_NONE, O_NONE, O_NONE, P_none };
+static struct ud_itab_entry ie_nop = { UD_Inop, O_NONE, O_NONE, O_NONE, P_none };
+
+
+/* Looks up mnemonic code in the mnemonic string table
+ * Returns NULL if the mnemonic code is invalid
+ */
+const char * ud_lookup_mnemonic( enum ud_mnemonic_code c )
+{
+ if ( c < UD_Id3vil )
+ return ud_mnemonics_str[ c ];
+ return NULL;
+}
+
+
+/* Extracts instruction prefixes.
+ */
+static int get_prefixes( struct ud* u )
+{
+ unsigned int have_pfx = 1;
+ unsigned int i;
+ uint8_t curr;
+
+ /* if in error state, bail out */
+ if ( u->error )
+ return -1;
+
+ /* keep going as long as there are prefixes available */
+ for ( i = 0; have_pfx ; ++i ) {
+
+ /* Get next byte. */
+ inp_next(u);
+ if ( u->error )
+ return -1;
+ curr = inp_curr( u );
+
+ /* rex prefixes in 64bit mode */
+ if ( u->dis_mode == 64 && ( curr & 0xF0 ) == 0x40 ) {
+ u->pfx_rex = curr;
+ } else {
+ switch ( curr )
+ {
+ case 0x2E :
+ u->pfx_seg = UD_R_CS;
+ u->pfx_rex = 0;
+ break;
+ case 0x36 :
+ u->pfx_seg = UD_R_SS;
+ u->pfx_rex = 0;
+ break;
+ case 0x3E :
+ u->pfx_seg = UD_R_DS;
+ u->pfx_rex = 0;
+ break;
+ case 0x26 :
+ u->pfx_seg = UD_R_ES;
+ u->pfx_rex = 0;
+ break;
+ case 0x64 :
+ u->pfx_seg = UD_R_FS;
+ u->pfx_rex = 0;
+ break;
+ case 0x65 :
+ u->pfx_seg = UD_R_GS;
+ u->pfx_rex = 0;
+ break;
+ case 0x67 : /* adress-size override prefix */
+ u->pfx_adr = 0x67;
+ u->pfx_rex = 0;
+ break;
+ case 0xF0 :
+ u->pfx_lock = 0xF0;
+ u->pfx_rex = 0;
+ break;
+ case 0x66:
+ /* the 0x66 sse prefix is only effective if no other sse prefix
+ * has already been specified.
+ */
+ if ( !u->pfx_insn ) u->pfx_insn = 0x66;
+ u->pfx_opr = 0x66;
+ u->pfx_rex = 0;
+ break;
+ case 0xF2:
+ u->pfx_insn = 0xF2;
+ u->pfx_repne = 0xF2;
+ u->pfx_rex = 0;
+ break;
+ case 0xF3:
+ u->pfx_insn = 0xF3;
+ u->pfx_rep = 0xF3;
+ u->pfx_repe = 0xF3;
+ u->pfx_rex = 0;
+ break;
+ default :
+ /* No more prefixes */
+ have_pfx = 0;
+ break;
+ }
+ }
+
+ /* check if we reached max instruction length */
+ if ( i + 1 == MAX_INSN_LENGTH ) {
+ u->error = 1;
+ break;
+ }
+ }
+
+ /* return status */
+ if ( u->error )
+ return -1;
+
+ /* rewind back one byte in stream, since the above loop
+ * stops with a non-prefix byte.
+ */
+ inp_back(u);
+
+ /* speculatively determine the effective operand mode,
+ * based on the prefixes and the current disassembly
+ * mode. This may be inaccurate, but useful for mode
+ * dependent decoding.
+ */
+ if ( u->dis_mode == 64 ) {
+ u->opr_mode = REX_W( u->pfx_rex ) ? 64 : ( ( u->pfx_opr ) ? 16 : 32 ) ;
+ u->adr_mode = ( u->pfx_adr ) ? 32 : 64;
+ } else if ( u->dis_mode == 32 ) {
+ u->opr_mode = ( u->pfx_opr ) ? 16 : 32;
+ u->adr_mode = ( u->pfx_adr ) ? 16 : 32;
+ } else if ( u->dis_mode == 16 ) {
+ u->opr_mode = ( u->pfx_opr ) ? 32 : 16;
+ u->adr_mode = ( u->pfx_adr ) ? 32 : 16;
+ }
+
+ return 0;
+}
+
+
+/* Searches the instruction tables for the right entry.
+ */
+static int search_itab( struct ud * u )
+{
+ struct ud_itab_entry * e = NULL;
+ enum ud_itab_index table;
+ uint8_t peek;
+ uint8_t did_peek = 0;
+ uint8_t curr;
+ uint8_t index;
+
+ /* if in state of error, return */
+ if ( u->error )
+ return -1;
+
+ /* get first byte of opcode. */
+ inp_next(u);
+ if ( u->error )
+ return -1;
+ curr = inp_curr(u);
+
+ /* resolve xchg, nop, pause crazyness */
+ if ( 0x90 == curr ) {
+ if ( !( u->dis_mode == 64 && REX_B( u->pfx_rex ) ) ) {
+ if ( u->pfx_rep ) {
+ u->pfx_rep = 0;
+ e = & ie_pause;
+ } else {
+ e = & ie_nop;
+ }
+ goto found_entry;
+ }
+ }
+
+ /* get top-level table */
+ if ( 0x0F == curr ) {
+ table = ITAB__0F;
+ curr = inp_next(u);
+ if ( u->error )
+ return -1;
+
+ /* 2byte opcodes can be modified by 0x66, F3, and F2 prefixes */
+ if ( 0x66 == u->pfx_insn ) {
+ if ( ud_itab_list[ ITAB__PFX_SSE66__0F ][ curr ].mnemonic != UD_Iinvalid ) {
+ table = ITAB__PFX_SSE66__0F;
+ u->pfx_opr = 0;
+ }
+ } else if ( 0xF2 == u->pfx_insn ) {
+ if ( ud_itab_list[ ITAB__PFX_SSEF2__0F ][ curr ].mnemonic != UD_Iinvalid ) {
+ table = ITAB__PFX_SSEF2__0F;
+ u->pfx_repne = 0;
+ }
+ } else if ( 0xF3 == u->pfx_insn ) {
+ if ( ud_itab_list[ ITAB__PFX_SSEF3__0F ][ curr ].mnemonic != UD_Iinvalid ) {
+ table = ITAB__PFX_SSEF3__0F;
+ u->pfx_repe = 0;
+ u->pfx_rep = 0;
+ }
+ }
+ /* pick an instruction from the 1byte table */
+ } else {
+ table = ITAB__1BYTE;
+ }
+
+ index = curr;
+
+search:
+
+ e = & ud_itab_list[ table ][ index ];
+
+ /* if mnemonic constant is a standard instruction constant
+ * our search is over.
+ */
+
+ if ( e->mnemonic < UD_Id3vil ) {
+ if ( e->mnemonic == UD_Iinvalid ) {
+ if ( did_peek ) {
+ inp_next( u ); if ( u->error ) return -1;
+ }
+ goto found_entry;
+ }
+ goto found_entry;
+ }
+
+ table = e->prefix;
+
+ switch ( e->mnemonic )
+ {
+ case UD_Igrp_reg:
+ peek = inp_peek( u );
+ did_peek = 1;
+ index = MODRM_REG( peek );
+ break;
+
+ case UD_Igrp_mod:
+ peek = inp_peek( u );
+ did_peek = 1;
+ index = MODRM_MOD( peek );
+ if ( index == 3 )
+ index = ITAB__MOD_INDX__11;
+ else
+ index = ITAB__MOD_INDX__NOT_11;
+ break;
+
+ case UD_Igrp_rm:
+ curr = inp_next( u );
+ did_peek = 0;
+ if ( u->error )
+ return -1;
+ index = MODRM_RM( curr );
+ break;
+
+ case UD_Igrp_x87:
+ curr = inp_next( u );
+ did_peek = 0;
+ if ( u->error )
+ return -1;
+ index = curr - 0xC0;
+ break;
+
+ case UD_Igrp_osize:
+ if ( u->opr_mode == 64 )
+ index = ITAB__MODE_INDX__64;
+ else if ( u->opr_mode == 32 )
+ index = ITAB__MODE_INDX__32;
+ else
+ index = ITAB__MODE_INDX__16;
+ break;
+
+ case UD_Igrp_asize:
+ if ( u->adr_mode == 64 )
+ index = ITAB__MODE_INDX__64;
+ else if ( u->adr_mode == 32 )
+ index = ITAB__MODE_INDX__32;
+ else
+ index = ITAB__MODE_INDX__16;
+ break;
+
+ case UD_Igrp_mode:
+ if ( u->dis_mode == 64 )
+ index = ITAB__MODE_INDX__64;
+ else if ( u->dis_mode == 32 )
+ index = ITAB__MODE_INDX__32;
+ else
+ index = ITAB__MODE_INDX__16;
+ break;
+
+ case UD_Igrp_vendor:
+ if ( u->vendor == UD_VENDOR_INTEL )
+ index = ITAB__VENDOR_INDX__INTEL;
+ else if ( u->vendor == UD_VENDOR_AMD )
+ index = ITAB__VENDOR_INDX__AMD;
+ else {
+ kdbp("KDB:search_itab(): unrecognized vendor id\n");
+ return -1;
+ }
+ break;
+
+ case UD_Id3vil:
+ kdbp("KDB:search_itab(): invalid instr mnemonic constant Id3vil\n");
+ return -1;
+
+ default:
+ kdbp("KDB:search_itab(): invalid instruction mnemonic constant\n");
+ return -1;
+ }
+
+ goto search;
+
+found_entry:
+
+ u->itab_entry = e;
+ u->mnemonic = u->itab_entry->mnemonic;
+
+ return 0;
+}
+
+
+static unsigned int resolve_operand_size( const struct ud * u, unsigned int s )
+{
+ switch ( s )
+ {
+ case SZ_V:
+ return ( u->opr_mode );
+ case SZ_Z:
+ return ( u->opr_mode == 16 ) ? 16 : 32;
+ case SZ_P:
+ return ( u->opr_mode == 16 ) ? SZ_WP : SZ_DP;
+ case SZ_MDQ:
+ return ( u->opr_mode == 16 ) ? 32 : u->opr_mode;
+ case SZ_RDQ:
+ return ( u->dis_mode == 64 ) ? 64 : 32;
+ default:
+ return s;
+ }
+}
+
+
+static int resolve_mnemonic( struct ud* u )
+{
+ /* far/near flags */
+ u->br_far = 0;
+ u->br_near = 0;
+ /* readjust operand sizes for call/jmp instrcutions */
+ if ( u->mnemonic == UD_Icall || u->mnemonic == UD_Ijmp ) {
+ /* WP: 16bit pointer */
+ if ( u->operand[ 0 ].size == SZ_WP ) {
+ u->operand[ 0 ].size = 16;
+ u->br_far = 1;
+ u->br_near= 0;
+ /* DP: 32bit pointer */
+ } else if ( u->operand[ 0 ].size == SZ_DP ) {
+ u->operand[ 0 ].size = 32;
+ u->br_far = 1;
+ u->br_near= 0;
+ } else {
+ u->br_far = 0;
+ u->br_near= 1;
+ }
+ /* resolve 3dnow weirdness. */
+ } else if ( u->mnemonic == UD_I3dnow ) {
+ u->mnemonic = ud_itab_list[ ITAB__3DNOW ][ inp_curr( u ) ].mnemonic;
+ }
+ /* SWAPGS is only valid in 64bits mode */
+ if ( u->mnemonic == UD_Iswapgs && u->dis_mode != 64 ) {
+ u->error = 1;
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * decode_a()- Decodes operands of the type seg:offset
+ * -----------------------------------------------------------------------------
+ */
+static void
+decode_a(struct ud* u, struct ud_operand *op)
+{
+ if (u->opr_mode == 16) {
+ /* seg16:off16 */
+ op->type = UD_OP_PTR;
+ op->size = 32;
+ op->lval.ptr.off = inp_uint16(u);
+ op->lval.ptr.seg = inp_uint16(u);
+ } else {
+ /* seg16:off32 */
+ op->type = UD_OP_PTR;
+ op->size = 48;
+ op->lval.ptr.off = inp_uint32(u);
+ op->lval.ptr.seg = inp_uint16(u);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * decode_gpr() - Returns decoded General Purpose Register
+ * -----------------------------------------------------------------------------
+ */
+static enum ud_type
+decode_gpr(register struct ud* u, unsigned int s, unsigned char rm)
+{
+ s = resolve_operand_size(u, s);
+
+ switch (s) {
+ case 64:
+ return UD_R_RAX + rm;
+ case SZ_DP:
+ case 32:
+ return UD_R_EAX + rm;
+ case SZ_WP:
+ case 16:
+ return UD_R_AX + rm;
+ case 8:
+ if (u->dis_mode == 64 && u->pfx_rex) {
+ if (rm >= 4)
+ return UD_R_SPL + (rm-4);
+ return UD_R_AL + rm;
+ } else return UD_R_AL + rm;
+ default:
+ return 0;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * resolve_gpr64() - 64bit General Purpose Register-Selection.
+ * -----------------------------------------------------------------------------
+ */
+static enum ud_type
+resolve_gpr64(struct ud* u, enum ud_operand_code gpr_op)
+{
+ if (gpr_op >= OP_rAXr8 && gpr_op <= OP_rDIr15)
+ gpr_op = (gpr_op - OP_rAXr8) | (REX_B(u->pfx_rex) << 3);
+ else gpr_op = (gpr_op - OP_rAX);
+
+ if (u->opr_mode == 16)
+ return gpr_op + UD_R_AX;
+ if (u->dis_mode == 32 ||
+ (u->opr_mode == 32 && ! (REX_W(u->pfx_rex) || u->default64))) {
+ return gpr_op + UD_R_EAX;
+ }
+
+ return gpr_op + UD_R_RAX;
+}
+
+/* -----------------------------------------------------------------------------
+ * resolve_gpr32 () - 32bit General Purpose Register-Selection.
+ * -----------------------------------------------------------------------------
+ */
+static enum ud_type
+resolve_gpr32(struct ud* u, enum ud_operand_code gpr_op)
+{
+ gpr_op = gpr_op - OP_eAX;
+
+ if (u->opr_mode == 16)
+ return gpr_op + UD_R_AX;
+
+ return gpr_op + UD_R_EAX;
+}
+
+/* -----------------------------------------------------------------------------
+ * resolve_reg() - Resolves the register type
+ * -----------------------------------------------------------------------------
+ */
+static enum ud_type
+resolve_reg(struct ud* u, unsigned int type, unsigned char i)
+{
+ switch (type) {
+ case T_MMX : return UD_R_MM0 + (i & 7);
+ case T_XMM : return UD_R_XMM0 + i;
+ case T_CRG : return UD_R_CR0 + i;
+ case T_DBG : return UD_R_DR0 + i;
+ case T_SEG : return UD_R_ES + (i & 7);
+ case T_NONE:
+ default: return UD_NONE;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * decode_imm() - Decodes Immediate values.
+ * -----------------------------------------------------------------------------
+ */
+static void
+decode_imm(struct ud* u, unsigned int s, struct ud_operand *op)
+{
+ op->size = resolve_operand_size(u, s);
+ op->type = UD_OP_IMM;
+
+ switch (op->size) {
+ case 8: op->lval.sbyte = inp_uint8(u); break;
+ case 16: op->lval.uword = inp_uint16(u); break;
+ case 32: op->lval.udword = inp_uint32(u); break;
+ case 64: op->lval.uqword = inp_uint64(u); break;
+ default: return;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * decode_modrm() - Decodes ModRM Byte
+ * -----------------------------------------------------------------------------
+ */
+static void
+decode_modrm(struct ud* u, struct ud_operand *op, unsigned int s,
+ unsigned char rm_type, struct ud_operand *opreg,
+ unsigned char reg_size, unsigned char reg_type)
+{
+ unsigned char mod, rm, reg;
+
+ inp_next(u);
+
+ /* get mod, r/m and reg fields */
+ mod = MODRM_MOD(inp_curr(u));
+ rm = (REX_B(u->pfx_rex) << 3) | MODRM_RM(inp_curr(u));
+ reg = (REX_R(u->pfx_rex) << 3) | MODRM_REG(inp_curr(u));
+
+ op->size = resolve_operand_size(u, s);
+
+ /* if mod is 11b, then the UD_R_m specifies a gpr/mmx/sse/control/debug */
+ if (mod == 3) {
+ op->type = UD_OP_REG;
+ if (rm_type == T_GPR)
+ op->base = decode_gpr(u, op->size, rm);
+ else op->base = resolve_reg(u, rm_type, (REX_B(u->pfx_rex) << 3) | (rm&7));
+ }
+ /* else its memory addressing */
+ else {
+ op->type = UD_OP_MEM;
+
+ /* 64bit addressing */
+ if (u->adr_mode == 64) {
+
+ op->base = UD_R_RAX + rm;
+
+ /* get offset type */
+ if (mod == 1)
+ op->offset = 8;
+ else if (mod == 2)
+ op->offset = 32;
+ else if (mod == 0 && (rm & 7) == 5) {
+ op->base = UD_R_RIP;
+ op->offset = 32;
+ } else op->offset = 0;
+
+ /* Scale-Index-Base (SIB) */
+ if ((rm & 7) == 4) {
+ inp_next(u);
+
+ op->scale = (1 << SIB_S(inp_curr(u))) & ~1;
+ op->index = UD_R_RAX + (SIB_I(inp_curr(u)) | (REX_X(u->pfx_rex) << 3));
+ op->base = UD_R_RAX + (SIB_B(inp_curr(u)) | (REX_B(u->pfx_rex) << 3));
+
+ /* special conditions for base reference */
+ if (op->index == UD_R_RSP) {
+ op->index = UD_NONE;
+ op->scale = UD_NONE;
+ }
+
+ if (op->base == UD_R_RBP || op->base == UD_R_R13) {
+ if (mod == 0)
+ op->base = UD_NONE;
+ if (mod == 1)
+ op->offset = 8;
+ else op->offset = 32;
+ }
+ }
+ }
+
+ /* 32-Bit addressing mode */
+ else if (u->adr_mode == 32) {
+
+ /* get base */
+ op->base = UD_R_EAX + rm;
+
+ /* get offset type */
+ if (mod == 1)
+ op->offset = 8;
+ else if (mod == 2)
+ op->offset = 32;
+ else if (mod == 0 && rm == 5) {
+ op->base = UD_NONE;
+ op->offset = 32;
+ } else op->offset = 0;
+
+ /* Scale-Index-Base (SIB) */
+ if ((rm & 7) == 4) {
+ inp_next(u);
+
+ op->scale = (1 << SIB_S(inp_curr(u))) & ~1;
+ op->index = UD_R_EAX + (SIB_I(inp_curr(u)) | (REX_X(u->pfx_rex) << 3));
+ op->base = UD_R_EAX + (SIB_B(inp_curr(u)) | (REX_B(u->pfx_rex) << 3));
+
+ if (op->index == UD_R_ESP) {
+ op->index = UD_NONE;
+ op->scale = UD_NONE;
+ }
+
+ /* special condition for base reference */
+ if (op->base == UD_R_EBP) {
+ if (mod == 0)
+ op->base = UD_NONE;
+ if (mod == 1)
+ op->offset = 8;
+ else op->offset = 32;
+ }
+ }
+ }
+
+ /* 16bit addressing mode */
+ else {
+ switch (rm) {
+ case 0: op->base = UD_R_BX; op->index = UD_R_SI; break;
+ case 1: op->base = UD_R_BX; op->index = UD_R_DI; break;
+ case 2: op->base = UD_R_BP; op->index = UD_R_SI; break;
+ case 3: op->base = UD_R_BP; op->index = UD_R_DI; break;
+ case 4: op->base = UD_R_SI; break;
+ case 5: op->base = UD_R_DI; break;
+ case 6: op->base = UD_R_BP; break;
+ case 7: op->base = UD_R_BX; break;
+ }
+
+ if (mod == 0 && rm == 6) {
+ op->offset= 16;
+ op->base = UD_NONE;
+ }
+ else if (mod == 1)
+ op->offset = 8;
+ else if (mod == 2)
+ op->offset = 16;
+ }
+ }
+
+ /* extract offset, if any */
+ switch(op->offset) {
+ case 8 : op->lval.ubyte = inp_uint8(u); break;
+ case 16: op->lval.uword = inp_uint16(u); break;
+ case 32: op->lval.udword = inp_uint32(u); break;
+ case 64: op->lval.uqword = inp_uint64(u); break;
+ default: break;
+ }
+
+ /* resolve register encoded in reg field */
+ if (opreg) {
+ opreg->type = UD_OP_REG;
+ opreg->size = resolve_operand_size(u, reg_size);
+ if (reg_type == T_GPR)
+ opreg->base = decode_gpr(u, opreg->size, reg);
+ else opreg->base = resolve_reg(u, reg_type, reg);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * decode_o() - Decodes offset
+ * -----------------------------------------------------------------------------
+ */
+static void
+decode_o(struct ud* u, unsigned int s, struct ud_operand *op)
+{
+ switch (u->adr_mode) {
+ case 64:
+ op->offset = 64;
+ op->lval.uqword = inp_uint64(u);
+ break;
+ case 32:
+ op->offset = 32;
+ op->lval.udword = inp_uint32(u);
+ break;
+ case 16:
+ op->offset = 16;
+ op->lval.uword = inp_uint16(u);
+ break;
+ default:
+ return;
+ }
+ op->type = UD_OP_MEM;
+ op->size = resolve_operand_size(u, s);
+}
+
+/* -----------------------------------------------------------------------------
+ * disasm_operands() - Disassembles Operands.
+ * -----------------------------------------------------------------------------
+ */
+static int disasm_operands(register struct ud* u)
+{
+
+
+ /* mopXt = map entry, operand X, type; */
+ enum ud_operand_code mop1t = u->itab_entry->operand1.type;
+ enum ud_operand_code mop2t = u->itab_entry->operand2.type;
+ enum ud_operand_code mop3t = u->itab_entry->operand3.type;
+
+ /* mopXs = map entry, operand X, size */
+ unsigned int mop1s = u->itab_entry->operand1.size;
+ unsigned int mop2s = u->itab_entry->operand2.size;
+ unsigned int mop3s = u->itab_entry->operand3.size;
+
+ /* iop = instruction operand */
+ register struct ud_operand* iop = u->operand;
+
+ switch(mop1t) {
+
+ case OP_A :
+ decode_a(u, &(iop[0]));
+ break;
+
+ /* M[b] ... */
+ case OP_M :
+ if (MODRM_MOD(inp_peek(u)) == 3)
+ u->error= 1;
+ /* E, G/P/V/I/CL/1/S */
+ case OP_E :
+ if (mop2t == OP_G) {
+ decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_GPR);
+ if (mop3t == OP_I)
+ decode_imm(u, mop3s, &(iop[2]));
+ else if (mop3t == OP_CL) {
+ iop[2].type = UD_OP_REG;
+ iop[2].base = UD_R_CL;
+ iop[2].size = 8;
+ }
+ }
+ else if (mop2t == OP_P)
+ decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_MMX);
+ else if (mop2t == OP_V)
+ decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_XMM);
+ else if (mop2t == OP_S)
+ decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_SEG);
+ else {
+ decode_modrm(u, &(iop[0]), mop1s, T_GPR, NULL, 0, T_NONE);
+ if (mop2t == OP_CL) {
+ iop[1].type = UD_OP_REG;
+ iop[1].base = UD_R_CL;
+ iop[1].size = 8;
+ } else if (mop2t == OP_I1) {
+ iop[1].type = UD_OP_CONST;
+ u->operand[1].lval.udword = 1;
+ } else if (mop2t == OP_I) {
+ decode_imm(u, mop2s, &(iop[1]));
+ }
+ }
+ break;
+
+ /* G, E/PR[,I]/VR */
+ case OP_G :
+ if (mop2t == OP_M) {
+ if (MODRM_MOD(inp_peek(u)) == 3)
+ u->error= 1;
+ decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_GPR);
+ } else if (mop2t == OP_E) {
+ decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_GPR);
+ if (mop3t == OP_I)
+ decode_imm(u, mop3s, &(iop[2]));
+ } else if (mop2t == OP_PR) {
+ decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_GPR);
+ if (mop3t == OP_I)
+ decode_imm(u, mop3s, &(iop[2]));
+ } else if (mop2t == OP_VR) {
+ if (MODRM_MOD(inp_peek(u)) != 3)
+ u->error = 1;
+ decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_GPR);
+ } else if (mop2t == OP_W)
+ decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_GPR);
+ break;
+
+ /* AL..BH, I/O/DX */
+ case OP_AL : case OP_CL : case OP_DL : case OP_BL :
+ case OP_AH : case OP_CH : case OP_DH : case OP_BH :
+
+ iop[0].type = UD_OP_REG;
+ iop[0].base = UD_R_AL + (mop1t - OP_AL);
+ iop[0].size = 8;
+
+ if (mop2t == OP_I)
+ decode_imm(u, mop2s, &(iop[1]));
+ else if (mop2t == OP_DX) {
+ iop[1].type = UD_OP_REG;
+ iop[1].base = UD_R_DX;
+ iop[1].size = 16;
+ }
+ else if (mop2t == OP_O)
+ decode_o(u, mop2s, &(iop[1]));
+ break;
+
+ /* rAX[r8]..rDI[r15], I/rAX..rDI/O */
+ case OP_rAXr8 : case OP_rCXr9 : case OP_rDXr10 : case OP_rBXr11 :
+ case OP_rSPr12: case OP_rBPr13: case OP_rSIr14 : case OP_rDIr15 :
+ case OP_rAX : case OP_rCX : case OP_rDX : case OP_rBX :
+ case OP_rSP : case OP_rBP : case OP_rSI : case OP_rDI :
+
+ iop[0].type = UD_OP_REG;
+ iop[0].base = resolve_gpr64(u, mop1t);
+
+ if (mop2t == OP_I)
+ decode_imm(u, mop2s, &(iop[1]));
+ else if (mop2t >= OP_rAX && mop2t <= OP_rDI) {
+ iop[1].type = UD_OP_REG;
+ iop[1].base = resolve_gpr64(u, mop2t);
+ }
+ else if (mop2t == OP_O) {
+ decode_o(u, mop2s, &(iop[1]));
+ iop[0].size = resolve_operand_size(u, mop2s);
+ }
+ break;
+
+ /* AL[r8b]..BH[r15b], I */
+ case OP_ALr8b : case OP_CLr9b : case OP_DLr10b : case OP_BLr11b :
+ case OP_AHr12b: case OP_CHr13b: case OP_DHr14b : case OP_BHr15b :
+ {
+ ud_type_t gpr = (mop1t - OP_ALr8b) + UD_R_AL +
+ (REX_B(u->pfx_rex) << 3);
+ if (UD_R_AH <= gpr && u->pfx_rex)
+ gpr = gpr + 4;
+ iop[0].type = UD_OP_REG;
+ iop[0].base = gpr;
+ if (mop2t == OP_I)
+ decode_imm(u, mop2s, &(iop[1]));
+ break;
+ }
+
+ /* eAX..eDX, DX/I */
+ case OP_eAX : case OP_eCX : case OP_eDX : case OP_eBX :
+ case OP_eSP : case OP_eBP : case OP_eSI : case OP_eDI :
+ iop[0].type = UD_OP_REG;
+ iop[0].base = resolve_gpr32(u, mop1t);
+ if (mop2t == OP_DX) {
+ iop[1].type = UD_OP_REG;
+ iop[1].base = UD_R_DX;
+ iop[1].size = 16;
+ } else if (mop2t == OP_I)
+ decode_imm(u, mop2s, &(iop[1]));
+ break;
+
+ /* ES..GS */
+ case OP_ES : case OP_CS : case OP_DS :
+ case OP_SS : case OP_FS : case OP_GS :
+
+ /* in 64bits mode, only fs and gs are allowed */
+ if (u->dis_mode == 64)
+ if (mop1t != OP_FS && mop1t != OP_GS)
+ u->error= 1;
+ iop[0].type = UD_OP_REG;
+ iop[0].base = (mop1t - OP_ES) + UD_R_ES;
+ iop[0].size = 16;
+
+ break;
+
+ /* J */
+ case OP_J :
+ decode_imm(u, mop1s, &(iop[0]));
+ iop[0].type = UD_OP_JIMM;
+ break ;
+
+ /* PR, I */
+ case OP_PR:
+ if (MODRM_MOD(inp_peek(u)) != 3)
+ u->error = 1;
+ decode_modrm(u, &(iop[0]), mop1s, T_MMX, NULL, 0, T_NONE);
+ if (mop2t == OP_I)
+ decode_imm(u, mop2s, &(iop[1]));
+ break;
+
+ /* VR, I */
+ case OP_VR:
+ if (MODRM_MOD(inp_peek(u)) != 3)
+ u->error = 1;
+ decode_modrm(u, &(iop[0]), mop1s, T_XMM, NULL, 0, T_NONE);
+ if (mop2t == OP_I)
+ decode_imm(u, mop2s, &(iop[1]));
+ break;
+
+ /* P, Q[,I]/W/E[,I],VR */
+ case OP_P :
+ if (mop2t == OP_Q) {
+ decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_MMX);
+ if (mop3t == OP_I)
+ decode_imm(u, mop3s, &(iop[2]));
+ } else if (mop2t == OP_W) {
+ decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_MMX);
+ } else if (mop2t == OP_VR) {
+ if (MODRM_MOD(inp_peek(u)) != 3)
+ u->error = 1;
+ decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_MMX);
+ } else if (mop2t == OP_E) {
+ decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_MMX);
+ if (mop3t == OP_I)
+ decode_imm(u, mop3s, &(iop[2]));
+ }
+ break;
+
+ /* R, C/D */
+ case OP_R :
+ if (mop2t == OP_C)
+ decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_CRG);
+ else if (mop2t == OP_D)
+ decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_DBG);
+ break;
+
+ /* C, R */
+ case OP_C :
+ decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_CRG);
+ break;
+
+ /* D, R */
+ case OP_D :
+ decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_DBG);
+ break;
+
+ /* Q, P */
+ case OP_Q :
+ decode_modrm(u, &(iop[0]), mop1s, T_MMX, &(iop[1]), mop2s, T_MMX);
+ break;
+
+ /* S, E */
+ case OP_S :
+ decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_SEG);
+ break;
+
+ /* W, V */
+ case OP_W :
+ decode_modrm(u, &(iop[0]), mop1s, T_XMM, &(iop[1]), mop2s, T_XMM);
+ break;
+
+ /* V, W[,I]/Q/M/E */
+ case OP_V :
+ if (mop2t == OP_W) {
+ /* special cases for movlps and movhps */
+ if (MODRM_MOD(inp_peek(u)) == 3) {
+ if (u->mnemonic == UD_Imovlps)
+ u->mnemonic = UD_Imovhlps;
+ else
+ if (u->mnemonic == UD_Imovhps)
+ u->mnemonic = UD_Imovlhps;
+ }
+ decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_XMM);
+ if (mop3t == OP_I)
+ decode_imm(u, mop3s, &(iop[2]));
+ } else if (mop2t == OP_Q)
+ decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_XMM);
+ else if (mop2t == OP_M) {
+ if (MODRM_MOD(inp_peek(u)) == 3)
+ u->error= 1;
+ decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_XMM);
+ } else if (mop2t == OP_E) {
+ decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_XMM);
+ } else if (mop2t == OP_PR) {
+ decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_XMM);
+ }
+ break;
+
+ /* DX, eAX/AL */
+ case OP_DX :
+ iop[0].type = UD_OP_REG;
+ iop[0].base = UD_R_DX;
+ iop[0].size = 16;
+
+ if (mop2t == OP_eAX) {
+ iop[1].type = UD_OP_REG;
+ iop[1].base = resolve_gpr32(u, mop2t);
+ } else if (mop2t == OP_AL) {
+ iop[1].type = UD_OP_REG;
+ iop[1].base = UD_R_AL;
+ iop[1].size = 8;
+ }
+
+ break;
+
+ /* I, I/AL/eAX */
+ case OP_I :
+ decode_imm(u, mop1s, &(iop[0]));
+ if (mop2t == OP_I)
+ decode_imm(u, mop2s, &(iop[1]));
+ else if (mop2t == OP_AL) {
+ iop[1].type = UD_OP_REG;
+ iop[1].base = UD_R_AL;
+ iop[1].size = 16;
+ } else if (mop2t == OP_eAX) {
+ iop[1].type = UD_OP_REG;
+ iop[1].base = resolve_gpr32(u, mop2t);
+ }
+ break;
+
+ /* O, AL/eAX */
+ case OP_O :
+ decode_o(u, mop1s, &(iop[0]));
+ iop[1].type = UD_OP_REG;
+ iop[1].size = resolve_operand_size(u, mop1s);
+ if (mop2t == OP_AL)
+ iop[1].base = UD_R_AL;
+ else if (mop2t == OP_eAX)
+ iop[1].base = resolve_gpr32(u, mop2t);
+ else if (mop2t == OP_rAX)
+ iop[1].base = resolve_gpr64(u, mop2t);
+ break;
+
+ /* 3 */
+ case OP_I3 :
+ iop[0].type = UD_OP_CONST;
+ iop[0].lval.sbyte = 3;
+ break;
+
+ /* ST(n), ST(n) */
+ case OP_ST0 : case OP_ST1 : case OP_ST2 : case OP_ST3 :
+ case OP_ST4 : case OP_ST5 : case OP_ST6 : case OP_ST7 :
+
+ iop[0].type = UD_OP_REG;
+ iop[0].base = (mop1t-OP_ST0) + UD_R_ST0;
+ iop[0].size = 0;
+
+ if (mop2t >= OP_ST0 && mop2t <= OP_ST7) {
+ iop[1].type = UD_OP_REG;
+ iop[1].base = (mop2t-OP_ST0) + UD_R_ST0;
+ iop[1].size = 0;
+ }
+ break;
+
+ /* AX */
+ case OP_AX:
+ iop[0].type = UD_OP_REG;
+ iop[0].base = UD_R_AX;
+ iop[0].size = 16;
+ break;
+
+ /* none */
+ default :
+ iop[0].type = iop[1].type = iop[2].type = UD_NONE;
+ }
+
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * clear_insn() - clear instruction pointer
+ * -----------------------------------------------------------------------------
+ */
+static int clear_insn(register struct ud* u)
+{
+ u->error = 0;
+ u->pfx_seg = 0;
+ u->pfx_opr = 0;
+ u->pfx_adr = 0;
+ u->pfx_lock = 0;
+ u->pfx_repne = 0;
+ u->pfx_rep = 0;
+ u->pfx_repe = 0;
+ u->pfx_seg = 0;
+ u->pfx_rex = 0;
+ u->pfx_insn = 0;
+ u->mnemonic = UD_Inone;
+ u->itab_entry = NULL;
+
+ memset( &u->operand[ 0 ], 0, sizeof( struct ud_operand ) );
+ memset( &u->operand[ 1 ], 0, sizeof( struct ud_operand ) );
+ memset( &u->operand[ 2 ], 0, sizeof( struct ud_operand ) );
+
+ return 0;
+}
+
+static int do_mode( struct ud* u )
+{
+ /* if in error state, bail out */
+ if ( u->error ) return -1;
+
+ /* propagate perfix effects */
+ if ( u->dis_mode == 64 ) { /* set 64bit-mode flags */
+
+ /* Check validity of instruction m64 */
+ if ( P_INV64( u->itab_entry->prefix ) ) {
+ u->error = 1;
+ return -1;
+ }
+
+ /* effective rex prefix is the effective mask for the
+ * instruction hard-coded in the opcode map.
+ */
+ u->pfx_rex = ( u->pfx_rex & 0x40 ) |
+ ( u->pfx_rex & REX_PFX_MASK( u->itab_entry->prefix ) );
+
+ /* whether this instruction has a default operand size of
+ * 64bit, also hardcoded into the opcode map.
+ */
+ u->default64 = P_DEF64( u->itab_entry->prefix );
+ /* calculate effective operand size */
+ if ( REX_W( u->pfx_rex ) ) {
+ u->opr_mode = 64;
+ } else if ( u->pfx_opr ) {
+ u->opr_mode = 16;
+ } else {
+ /* unless the default opr size of instruction is 64,
+ * the effective operand size in the absence of rex.w
+ * prefix is 32.
+ */
+ u->opr_mode = ( u->default64 ) ? 64 : 32;
+ }
+
+ /* calculate effective address size */
+ u->adr_mode = (u->pfx_adr) ? 32 : 64;
+ } else if ( u->dis_mode == 32 ) { /* set 32bit-mode flags */
+ u->opr_mode = ( u->pfx_opr ) ? 16 : 32;
+ u->adr_mode = ( u->pfx_adr ) ? 16 : 32;
+ } else if ( u->dis_mode == 16 ) { /* set 16bit-mode flags */
+ u->opr_mode = ( u->pfx_opr ) ? 32 : 16;
+ u->adr_mode = ( u->pfx_adr ) ? 32 : 16;
+ }
+
+ /* These flags determine which operand to apply the operand size
+ * cast to.
+ */
+ u->c1 = ( P_C1( u->itab_entry->prefix ) ) ? 1 : 0;
+ u->c2 = ( P_C2( u->itab_entry->prefix ) ) ? 1 : 0;
+ u->c3 = ( P_C3( u->itab_entry->prefix ) ) ? 1 : 0;
+
+ /* set flags for implicit addressing */
+ u->implicit_addr = P_IMPADDR( u->itab_entry->prefix );
+
+ return 0;
+}
+
+static int gen_hex( struct ud *u )
+{
+ unsigned int i;
+ unsigned char *src_ptr = inp_sess( u );
+ char* src_hex;
+
+ /* bail out if in error stat. */
+ if ( u->error ) return -1;
+ /* output buffer pointe */
+ src_hex = ( char* ) u->insn_hexcode;
+ /* for each byte used to decode instruction */
+ for ( i = 0; i < u->inp_ctr; ++i, ++src_ptr) {
+ snprintf( src_hex, 2, "%02x", *src_ptr & 0xFF );
+ src_hex += 2;
+ }
+ return 0;
+}
+
+/* =============================================================================
+ * ud_decode() - Instruction decoder. Returns the number of bytes decoded.
+ * =============================================================================
+ */
+unsigned int ud_decode( struct ud* u )
+{
+ inp_start(u);
+
+ if ( clear_insn( u ) ) {
+ ; /* error */
+ } else if ( get_prefixes( u ) != 0 ) {
+ ; /* error */
+ } else if ( search_itab( u ) != 0 ) {
+ ; /* error */
+ } else if ( do_mode( u ) != 0 ) {
+ ; /* error */
+ } else if ( disasm_operands( u ) != 0 ) {
+ ; /* error */
+ } else if ( resolve_mnemonic( u ) != 0 ) {
+ ; /* error */
+ }
+
+ /* Handle decode error. */
+ if ( u->error ) {
+ /* clear out the decode data. */
+ clear_insn( u );
+ /* mark the sequence of bytes as invalid. */
+ u->itab_entry = & ie_invalid;
+ u->mnemonic = u->itab_entry->mnemonic;
+ }
+
+ u->insn_offset = u->pc; /* set offset of instruction */
+ u->insn_fill = 0; /* set translation buffer index to 0 */
+ u->pc += u->inp_ctr; /* move program counter by bytes decoded */
+ gen_hex( u ); /* generate hex code */
+
+ /* return number of bytes disassembled. */
+ return u->inp_ctr;
+}
+
+/* vim:cindent
+ * vim:ts=4
+ * vim:sw=4
+ * vim:expandtab
+ */
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/decode.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/decode.h Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,273 @@
+#ifndef UD_DECODE_H
+#define UD_DECODE_H
+
+#define MAX_INSN_LENGTH 15
+
+/* register classes */
+#define T_NONE 0
+#define T_GPR 1
+#define T_MMX 2
+#define T_CRG 3
+#define T_DBG 4
+#define T_SEG 5
+#define T_XMM 6
+
+/* itab prefix bits */
+#define P_none ( 0 )
+#define P_c1 ( 1 << 0 )
+#define P_C1(n) ( ( n >> 0 ) & 1 )
+#define P_rexb ( 1 << 1 )
+#define P_REXB(n) ( ( n >> 1 ) & 1 )
+#define P_depM ( 1 << 2 )
+#define P_DEPM(n) ( ( n >> 2 ) & 1 )
+#define P_c3 ( 1 << 3 )
+#define P_C3(n) ( ( n >> 3 ) & 1 )
+#define P_inv64 ( 1 << 4 )
+#define P_INV64(n) ( ( n >> 4 ) & 1 )
+#define P_rexw ( 1 << 5 )
+#define P_REXW(n) ( ( n >> 5 ) & 1 )
+#define P_c2 ( 1 << 6 )
+#define P_C2(n) ( ( n >> 6 ) & 1 )
+#define P_def64 ( 1 << 7 )
+#define P_DEF64(n) ( ( n >> 7 ) & 1 )
+#define P_rexr ( 1 << 8 )
+#define P_REXR(n) ( ( n >> 8 ) & 1 )
+#define P_oso ( 1 << 9 )
+#define P_OSO(n) ( ( n >> 9 ) & 1 )
+#define P_aso ( 1 << 10 )
+#define P_ASO(n) ( ( n >> 10 ) & 1 )
+#define P_rexx ( 1 << 11 )
+#define P_REXX(n) ( ( n >> 11 ) & 1 )
+#define P_ImpAddr ( 1 << 12 )
+#define P_IMPADDR(n) ( ( n >> 12 ) & 1 )
+
+/* rex prefix bits */
+#define REX_W(r) ( ( 0xF & ( r ) ) >> 3 )
+#define REX_R(r) ( ( 0x7 & ( r ) ) >> 2 )
+#define REX_X(r) ( ( 0x3 & ( r ) ) >> 1 )
+#define REX_B(r) ( ( 0x1 & ( r ) ) >> 0 )
+#define REX_PFX_MASK(n) ( ( P_REXW(n) << 3 ) | \
+ ( P_REXR(n) << 2 ) | \
+ ( P_REXX(n) << 1 ) | \
+ ( P_REXB(n) << 0 ) )
+
+/* scable-index-base bits */
+#define SIB_S(b) ( ( b ) >> 6 )
+#define SIB_I(b) ( ( ( b ) >> 3 ) & 7 )
+#define SIB_B(b) ( ( b ) & 7 )
+
+/* modrm bits */
+#define MODRM_REG(b) ( ( ( b ) >> 3 ) & 7 )
+#define MODRM_NNN(b) ( ( ( b ) >> 3 ) & 7 )
+#define MODRM_MOD(b) ( ( ( b ) >> 6 ) & 3 )
+#define MODRM_RM(b) ( ( b ) & 7 )
+
+/* operand type constants -- order is important! */
+
+enum ud_operand_code {
+ OP_NONE,
+
+ OP_A, OP_E, OP_M, OP_G,
+ OP_I,
+
+ OP_AL, OP_CL, OP_DL, OP_BL,
+ OP_AH, OP_CH, OP_DH, OP_BH,
+
+ OP_ALr8b, OP_CLr9b, OP_DLr10b, OP_BLr11b,
+ OP_AHr12b, OP_CHr13b, OP_DHr14b, OP_BHr15b,
+
+ OP_AX, OP_CX, OP_DX, OP_BX,
+ OP_SI, OP_DI, OP_SP, OP_BP,
+
+ OP_rAX, OP_rCX, OP_rDX, OP_rBX,
+ OP_rSP, OP_rBP, OP_rSI, OP_rDI,
+
+ OP_rAXr8, OP_rCXr9, OP_rDXr10, OP_rBXr11,
+ OP_rSPr12, OP_rBPr13, OP_rSIr14, OP_rDIr15,
+
+ OP_eAX, OP_eCX, OP_eDX, OP_eBX,
+ OP_eSP, OP_eBP, OP_eSI, OP_eDI,
+
+ OP_ES, OP_CS, OP_SS, OP_DS,
+ OP_FS, OP_GS,
+
+ OP_ST0, OP_ST1, OP_ST2, OP_ST3,
+ OP_ST4, OP_ST5, OP_ST6, OP_ST7,
+
+ OP_J, OP_S, OP_O,
+ OP_I1, OP_I3,
+
+ OP_V, OP_W, OP_Q, OP_P,
+
+ OP_R, OP_C, OP_D, OP_VR, OP_PR
+};
+
+
+/* operand size constants */
+
+enum ud_operand_size {
+ SZ_NA = 0,
+ SZ_Z = 1,
+ SZ_V = 2,
+ SZ_P = 3,
+ SZ_WP = 4,
+ SZ_DP = 5,
+ SZ_MDQ = 6,
+ SZ_RDQ = 7,
+
+ /* the following values are used as is,
+ * and thus hard-coded. changing them
+ * will break internals
+ */
+ SZ_B = 8,
+ SZ_W = 16,
+ SZ_D = 32,
+ SZ_Q = 64,
+ SZ_T = 80,
+};
+
+/* itab entry operand definitions */
+
+#define O_rSPr12 { OP_rSPr12, SZ_NA }
+#define O_BL { OP_BL, SZ_NA }
+#define O_BH { OP_BH, SZ_NA }
+#define O_BP { OP_BP, SZ_NA }
+#define O_AHr12b { OP_AHr12b, SZ_NA }
+#define O_BX { OP_BX, SZ_NA }
+#define O_Jz { OP_J, SZ_Z }
+#define O_Jv { OP_J, SZ_V }
+#define O_Jb { OP_J, SZ_B }
+#define O_rSIr14 { OP_rSIr14, SZ_NA }
+#define O_GS { OP_GS, SZ_NA }
+#define O_D { OP_D, SZ_NA }
+#define O_rBPr13 { OP_rBPr13, SZ_NA }
+#define O_Ob { OP_O, SZ_B }
+#define O_P { OP_P, SZ_NA }
+#define O_Ow { OP_O, SZ_W }
+#define O_Ov { OP_O, SZ_V }
+#define O_Gw { OP_G, SZ_W }
+#define O_Gv { OP_G, SZ_V }
+#define O_rDX { OP_rDX, SZ_NA }
+#define O_Gx { OP_G, SZ_MDQ }
+#define O_Gd { OP_G, SZ_D }
+#define O_Gb { OP_G, SZ_B }
+#define O_rBXr11 { OP_rBXr11, SZ_NA }
+#define O_rDI { OP_rDI, SZ_NA }
+#define O_rSI { OP_rSI, SZ_NA }
+#define O_ALr8b { OP_ALr8b, SZ_NA }
+#define O_eDI { OP_eDI, SZ_NA }
+#define O_Gz { OP_G, SZ_Z }
+#define O_eDX { OP_eDX, SZ_NA }
+#define O_DHr14b { OP_DHr14b, SZ_NA }
+#define O_rSP { OP_rSP, SZ_NA }
+#define O_PR { OP_PR, SZ_NA }
+#define O_NONE { OP_NONE, SZ_NA }
+#define O_rCX { OP_rCX, SZ_NA }
+#define O_jWP { OP_J, SZ_WP }
+#define O_rDXr10 { OP_rDXr10, SZ_NA }
+#define O_Md { OP_M, SZ_D }
+#define O_C { OP_C, SZ_NA }
+#define O_G { OP_G, SZ_NA }
+#define O_Mb { OP_M, SZ_B }
+#define O_Mt { OP_M, SZ_T }
+#define O_S { OP_S, SZ_NA }
+#define O_Mq { OP_M, SZ_Q }
+#define O_W { OP_W, SZ_NA }
+#define O_ES { OP_ES, SZ_NA }
+#define O_rBX { OP_rBX, SZ_NA }
+#define O_Ed { OP_E, SZ_D }
+#define O_DLr10b { OP_DLr10b, SZ_NA }
+#define O_Mw { OP_M, SZ_W }
+#define O_Eb { OP_E, SZ_B }
+#define O_Ex { OP_E, SZ_MDQ }
+#define O_Ez { OP_E, SZ_Z }
+#define O_Ew { OP_E, SZ_W }
+#define O_Ev { OP_E, SZ_V }
+#define O_Ep { OP_E, SZ_P }
+#define O_FS { OP_FS, SZ_NA }
+#define O_Ms { OP_M, SZ_W }
+#define O_rAXr8 { OP_rAXr8, SZ_NA }
+#define O_eBP { OP_eBP, SZ_NA }
+#define O_Isb { OP_I, SZ_SB }
+#define O_eBX { OP_eBX, SZ_NA }
+#define O_rCXr9 { OP_rCXr9, SZ_NA }
+#define O_jDP { OP_J, SZ_DP }
+#define O_CH { OP_CH, SZ_NA }
+#define O_CL { OP_CL, SZ_NA }
+#define O_R { OP_R, SZ_RDQ }
+#define O_V { OP_V, SZ_NA }
+#define O_CS { OP_CS, SZ_NA }
+#define O_CHr13b { OP_CHr13b, SZ_NA }
+#define O_eCX { OP_eCX, SZ_NA }
+#define O_eSP { OP_eSP, SZ_NA }
+#define O_SS { OP_SS, SZ_NA }
+#define O_SP { OP_SP, SZ_NA }
+#define O_BLr11b { OP_BLr11b, SZ_NA }
+#define O_SI { OP_SI, SZ_NA }
+#define O_eSI { OP_eSI, SZ_NA }
+#define O_DL { OP_DL, SZ_NA }
+#define O_DH { OP_DH, SZ_NA }
+#define O_DI { OP_DI, SZ_NA }
+#define O_DX { OP_DX, SZ_NA }
+#define O_rBP { OP_rBP, SZ_NA }
+#define O_Gvw { OP_G, SZ_MDQ }
+#define O_I1 { OP_I1, SZ_NA }
+#define O_I3 { OP_I3, SZ_NA }
+#define O_DS { OP_DS, SZ_NA }
+#define O_ST4 { OP_ST4, SZ_NA }
+#define O_ST5 { OP_ST5, SZ_NA }
+#define O_ST6 { OP_ST6, SZ_NA }
+#define O_ST7 { OP_ST7, SZ_NA }
+#define O_ST0 { OP_ST0, SZ_NA }
+#define O_ST1 { OP_ST1, SZ_NA }
+#define O_ST2 { OP_ST2, SZ_NA }
+#define O_ST3 { OP_ST3, SZ_NA }
+#define O_E { OP_E, SZ_NA }
+#define O_AH { OP_AH, SZ_NA }
+#define O_M { OP_M, SZ_NA }
+#define O_AL { OP_AL, SZ_NA }
+#define O_CLr9b { OP_CLr9b, SZ_NA }
+#define O_Q { OP_Q, SZ_NA }
+#define O_eAX { OP_eAX, SZ_NA }
+#define O_VR { OP_VR, SZ_NA }
+#define O_AX { OP_AX, SZ_NA }
+#define O_rAX { OP_rAX, SZ_NA }
+#define O_Iz { OP_I, SZ_Z }
+#define O_rDIr15 { OP_rDIr15, SZ_NA }
+#define O_Iw { OP_I, SZ_W }
+#define O_Iv { OP_I, SZ_V }
+#define O_Ap { OP_A, SZ_P }
+#define O_CX { OP_CX, SZ_NA }
+#define O_Ib { OP_I, SZ_B }
+#define O_BHr15b { OP_BHr15b, SZ_NA }
+
+
+/* A single operand of an entry in the instruction table.
+ * (internal use only)
+ */
+struct ud_itab_entry_operand
+{
+ enum ud_operand_code type;
+ enum ud_operand_size size;
+};
+
+
+/* A single entry in an instruction table.
+ *(internal use only)
+ */
+struct ud_itab_entry
+{
+ enum ud_mnemonic_code mnemonic;
+ struct ud_itab_entry_operand operand1;
+ struct ud_itab_entry_operand operand2;
+ struct ud_itab_entry_operand operand3;
+ uint32_t prefix;
+};
+
+#endif /* UD_DECODE_H */
+
+/* vim:cindent
+ * vim:expandtab
+ * vim:ts=4
+ * vim:sw=4
+ */
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/extern.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/extern.h Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,67 @@
+/* -----------------------------------------------------------------------------
+ * extern.h
+ *
+ * Copyright (c) 2004, 2005, 2006, Vivek Mohan <vivek@sig9.com>
+ * All rights reserved. See LICENSE
+ * -----------------------------------------------------------------------------
+ */
+#ifndef UD_EXTERN_H
+#define UD_EXTERN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* #include <stdio.h> */
+#include "types.h"
+
+/* ============================= PUBLIC API ================================= */
+
+extern void ud_init(struct ud*);
+
+extern void ud_set_mode(struct ud*, uint8_t);
+
+extern void ud_set_pc(struct ud*, uint64_t);
+
+extern void ud_set_input_hook(struct ud*, int (*)(struct ud*));
+
+extern void ud_set_input_buffer(struct ud*, uint8_t*, size_t);
+
+#ifndef __UD_STANDALONE__
+extern void ud_set_input_file(struct ud*, FILE*);
+#endif /* __UD_STANDALONE__ */
+
+extern void ud_set_vendor(struct ud*, unsigned);
+
+extern void ud_set_syntax(struct ud*, void (*)(struct ud*));
+
+extern void ud_input_skip(struct ud*, size_t);
+
+extern int ud_input_end(struct ud*);
+
+extern unsigned int ud_decode(struct ud*);
+
+extern unsigned int ud_disassemble(struct ud*);
+
+extern void ud_translate_intel(struct ud*);
+
+extern void ud_translate_att(struct ud*);
+
+extern char* ud_insn_asm(struct ud* u);
+
+extern uint8_t* ud_insn_ptr(struct ud* u);
+
+extern uint64_t ud_insn_off(struct ud*);
+
+extern char* ud_insn_hex(struct ud*);
+
+extern unsigned int ud_insn_len(struct ud* u);
+
+extern const char* ud_lookup_mnemonic(enum ud_mnemonic_code c);
+
+/* ========================================================================== */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/input.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/input.c Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,226 @@
+/* -----------------------------------------------------------------------------
+ * input.c
+ *
+ * Copyright (c) 2004, 2005, 2006, Vivek Mohan <vivek@sig9.com>
+ * All rights reserved. See LICENSE
+ * -----------------------------------------------------------------------------
+ */
+#include "extern.h"
+#include "types.h"
+#include "input.h"
+
+/* -----------------------------------------------------------------------------
+ * inp_buff_hook() - Hook for buffered inputs.
+ * -----------------------------------------------------------------------------
+ */
+static int
+inp_buff_hook(struct ud* u)
+{
+ if (u->inp_buff < u->inp_buff_end)
+ return *u->inp_buff++;
+ else return -1;
+}
+
+#ifndef __UD_STANDALONE__
+/* -----------------------------------------------------------------------------
+ * inp_file_hook() - Hook for FILE inputs.
+ * -----------------------------------------------------------------------------
+ */
+static int
+inp_file_hook(struct ud* u)
+{
+ return fgetc(u->inp_file);
+}
+#endif /* __UD_STANDALONE__*/
+
+/* =============================================================================
+ * ud_inp_set_hook() - Sets input hook.
+ * =============================================================================
+ */
+extern void
+ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*))
+{
+ u->inp_hook = hook;
+ inp_init(u);
+}
+
+/* =============================================================================
+ * ud_inp_set_buffer() - Set buffer as input.
+ * =============================================================================
+ */
+extern void
+ud_set_input_buffer(register struct ud* u, uint8_t* buf, size_t len)
+{
+ u->inp_hook = inp_buff_hook;
+ u->inp_buff = buf;
+ u->inp_buff_end = buf + len;
+ inp_init(u);
+}
+
+#ifndef __UD_STANDALONE__
+/* =============================================================================
+ * ud_input_set_file() - Set buffer as input.
+ * =============================================================================
+ */
+extern void
+ud_set_input_file(register struct ud* u, FILE* f)
+{
+ u->inp_hook = inp_file_hook;
+ u->inp_file = f;
+ inp_init(u);
+}
+#endif /* __UD_STANDALONE__ */
+
+/* =============================================================================
+ * ud_input_skip() - Skip n input bytes.
+ * =============================================================================
+ */
+extern void
+ud_input_skip(struct ud* u, size_t n)
+{
+ while (n--) {
+ u->inp_hook(u);
+ }
+}
+
+/* =============================================================================
+ * ud_input_end() - Test for end of input.
+ * =============================================================================
+ */
+extern int
+ud_input_end(struct ud* u)
+{
+ return (u->inp_curr == u->inp_fill) && u->inp_end;
+}
+
+/* -----------------------------------------------------------------------------
+ * inp_next() - Loads and returns the next byte from input.
+ *
+ * inp_curr and inp_fill are pointers to the cache. The program is written based
+ * on the property that they are 8-bits in size, and will eventually wrap around
+ * forming a circular buffer. So, the size of the cache is 256 in size, kind of
+ * unnecessary yet optimized.
+ *
+ * A buffer inp_sess stores the bytes disassembled for a single session.
+ * -----------------------------------------------------------------------------
+ */
+extern uint8_t inp_next(struct ud* u)
+{
+ int c = -1;
+ /* if current pointer is not upto the fill point in the
+ * input cache.
+ */
+ if ( u->inp_curr != u->inp_fill ) {
+ c = u->inp_cache[ ++u->inp_curr ];
+ /* if !end-of-input, call the input hook and get a byte */
+ } else if ( u->inp_end || ( c = u->inp_hook( u ) ) == -1 ) {
+ /* end-of-input, mark it as an error, since the decoder,
+ * expected a byte more.
+ */
+ u->error = 1;
+ /* flag end of input */
+ u->inp_end = 1;
+ return 0;
+ } else {
+ /* increment pointers, we have a new byte. */
+ u->inp_curr = ++u->inp_fill;
+ /* add the byte to the cache */
+ u->inp_cache[ u->inp_fill ] = c;
+ }
+ /* record bytes input per decode-session. */
+ u->inp_sess[ u->inp_ctr++ ] = c;
+ /* return byte */
+ return ( uint8_t ) c;
+}
+
+/* -----------------------------------------------------------------------------
+ * inp_back() - Move back a single byte in the stream.
+ * -----------------------------------------------------------------------------
+ */
+extern void
+inp_back(struct ud* u)
+{
+ if ( u->inp_ctr > 0 ) {
+ --u->inp_curr;
+ --u->inp_ctr;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * inp_peek() - Peek into the next byte in source.
+ * -----------------------------------------------------------------------------
+ */
+extern uint8_t
+inp_peek(struct ud* u)
+{
+ uint8_t r = inp_next(u);
+ if ( !u->error ) inp_back(u); /* Don't backup if there was an error */
+ return r;
+}
+
+/* -----------------------------------------------------------------------------
+ * inp_move() - Move ahead n input bytes.
+ * -----------------------------------------------------------------------------
+ */
+extern void
+inp_move(struct ud* u, size_t n)
+{
+ while (n--)
+ inp_next(u);
+}
+
+/*------------------------------------------------------------------------------
+ * inp_uintN() - return uintN from source.
+ *------------------------------------------------------------------------------
+ */
+extern uint8_t
+inp_uint8(struct ud* u)
+{
+ return inp_next(u);
+}
+
+extern uint16_t
+inp_uint16(struct ud* u)
+{
+ uint16_t r, ret;
+
+ ret = inp_next(u);
+ r = inp_next(u);
+ return ret | (r << 8);
+}
+
+extern uint32_t
+inp_uint32(struct ud* u)
+{
+ uint32_t r, ret;
+
+ ret = inp_next(u);
+ r = inp_next(u);
+ ret = ret | (r << 8);
+ r = inp_next(u);
+ ret = ret | (r << 16);
+ r = inp_next(u);
+ return ret | (r << 24);
+}
+
+extern uint64_t
+inp_uint64(struct ud* u)
+{
+ uint64_t r, ret;
+
+ ret = inp_next(u);
+ r = inp_next(u);
+ ret = ret | (r << 8);
+ r = inp_next(u);
+ ret = ret | (r << 16);
+ r = inp_next(u);
+ ret = ret | (r << 24);
+ r = inp_next(u);
+ ret = ret | (r << 32);
+ r = inp_next(u);
+ ret = ret | (r << 40);
+ r = inp_next(u);
+ ret = ret | (r << 48);
+ r = inp_next(u);
+ return ret | (r << 56);
+}
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/input.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/input.h Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,49 @@
+/* -----------------------------------------------------------------------------
+ * input.h
+ *
+ * Copyright (c) 2006, Vivek Mohan <vivek@sig9.com>
+ * All rights reserved. See LICENSE
+ * -----------------------------------------------------------------------------
+ */
+#ifndef UD_INPUT_H
+#define UD_INPUT_H
+
+#include "types.h"
+
+uint8_t inp_next(struct ud*);
+uint8_t inp_peek(struct ud*);
+uint8_t inp_uint8(struct ud*);
+uint16_t inp_uint16(struct ud*);
+uint32_t inp_uint32(struct ud*);
+uint64_t inp_uint64(struct ud*);
+void inp_move(struct ud*, size_t);
+void inp_back(struct ud*);
+
+/* inp_init() - Initializes the input system. */
+#define inp_init(u) \
+do { \
+ u->inp_curr = 0; \
+ u->inp_fill = 0; \
+ u->inp_ctr = 0; \
+ u->inp_end = 0; \
+} while (0)
+
+/* inp_start() - Should be called before each de-code operation. */
+#define inp_start(u) u->inp_ctr = 0
+
+/* inp_back() - Resets the current pointer to its position before the current
+ * instruction disassembly was started.
+ */
+#define inp_reset(u) \
+do { \
+ u->inp_curr -= u->inp_ctr; \
+ u->inp_ctr = 0; \
+} while (0)
+
+/* inp_sess() - Returns the pointer to current session. */
+#define inp_sess(u) (u->inp_sess)
+
+/* inp_cur() - Returns the current input byte. */
+#define inp_curr(u) ((u)->inp_cache[(u)->inp_curr])
+
+#endif
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/itab.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/itab.c Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,3668 @@
+
+/* itab.c -- auto generated by opgen.py, do not edit. */
+
+#include "types.h"
+#include "decode.h"
+#include "itab.h"
+
+const char * ud_mnemonics_str[] = {
+ "3dnow",
+ "aaa",
+ "aad",
+ "aam",
+ "aas",
+ "adc",
+ "add",
+ "addpd",
+ "addps",
+ "addsd",
+ "addss",
+ "addsubpd",
+ "addsubps",
+ "and",
+ "andpd",
+ "andps",
+ "andnpd",
+ "andnps",
+ "arpl",
+ "movsxd",
+ "bound",
+ "bsf",
+ "bsr",
+ "bswap",
+ "bt",
+ "btc",
+ "btr",
+ "bts",
+ "call",
+ "cbw",
+ "cwde",
+ "cdqe",
+ "clc",
+ "cld",
+ "clflush",
+ "clgi",
+ "cli",
+ "clts",
+ "cmc",
+ "cmovo",
+ "cmovno",
+ "cmovb",
+ "cmovae",
+ "cmovz",
+ "cmovnz",
+ "cmovbe",
+ "cmova",
+ "cmovs",
+ "cmovns",
+ "cmovp",
+ "cmovnp",
+ "cmovl",
+ "cmovge",
+ "cmovle",
+ "cmovg",
+ "cmp",
+ "cmppd",
+ "cmpps",
+ "cmpsb",
+ "cmpsw",
+ "cmpsd",
+ "cmpsq",
+ "cmpss",
+ "cmpxchg",
+ "cmpxchg8b",
+ "comisd",
+ "comiss",
+ "cpuid",
+ "cvtdq2pd",
+ "cvtdq2ps",
+ "cvtpd2dq",
+ "cvtpd2pi",
+ "cvtpd2ps",
+ "cvtpi2ps",
+ "cvtpi2pd",
+ "cvtps2dq",
+ "cvtps2pi",
+ "cvtps2pd",
+ "cvtsd2si",
+ "cvtsd2ss",
+ "cvtsi2ss",
+ "cvtss2si",
+ "cvtss2sd",
+ "cvttpd2pi",
+ "cvttpd2dq",
+ "cvttps2dq",
+ "cvttps2pi",
+ "cvttsd2si",
+ "cvtsi2sd",
+ "cvttss2si",
+ "cwd",
+ "cdq",
+ "cqo",
+ "daa",
+ "das",
+ "dec",
+ "div",
+ "divpd",
+ "divps",
+ "divsd",
+ "divss",
+ "emms",
+ "enter",
+ "f2xm1",
+ "fabs",
+ "fadd",
+ "faddp",
+ "fbld",
+ "fbstp",
+ "fchs",
+ "fclex",
+ "fcmovb",
+ "fcmove",
+ "fcmovbe",
+ "fcmovu",
+ "fcmovnb",
+ "fcmovne",
+ "fcmovnbe",
+ "fcmovnu",
+ "fucomi",
+ "fcom",
+ "fcom2",
+ "fcomp3",
+ "fcomi",
+ "fucomip",
+ "fcomip",
+ "fcomp",
+ "fcomp5",
+ "fcompp",
+ "fcos",
+ "fdecstp",
+ "fdiv",
+ "fdivp",
+ "fdivr",
+ "fdivrp",
+ "femms",
+ "ffree",
+ "ffreep",
+ "ficom",
+ "ficomp",
+ "fild",
+ "fncstp",
+ "fninit",
+ "fiadd",
+ "fidivr",
+ "fidiv",
+ "fisub",
+ "fisubr",
+ "fist",
+ "fistp",
+ "fisttp",
+ "fld",
+ "fld1",
+ "fldl2t",
+ "fldl2e",
+ "fldlpi",
+ "fldlg2",
+ "fldln2",
+ "fldz",
+ "fldcw",
+ "fldenv",
+ "fmul",
+ "fmulp",
+ "fimul",
+ "fnop",
+ "fpatan",
+ "fprem",
+ "fprem1",
+ "fptan",
+ "frndint",
+ "frstor",
+ "fnsave",
+ "fscale",
+ "fsin",
+ "fsincos",
+ "fsqrt",
+ "fstp",
+ "fstp1",
+ "fstp8",
+ "fstp9",
+ "fst",
+ "fnstcw",
+ "fnstenv",
+ "fnstsw",
+ "fsub",
+ "fsubp",
+ "fsubr",
+ "fsubrp",
+ "ftst",
+ "fucom",
+ "fucomp",
+ "fucompp",
+ "fxam",
+ "fxch",
+ "fxch4",
+ "fxch7",
+ "fxrstor",
+ "fxsave",
+ "fpxtract",
+ "fyl2x",
+ "fyl2xp1",
+ "haddpd",
+ "haddps",
+ "hlt",
+ "hsubpd",
+ "hsubps",
+ "idiv",
+ "in",
+ "imul",
+ "inc",
+ "insb",
+ "insw",
+ "insd",
+ "int1",
+ "int3",
+ "int",
+ "into",
+ "invd",
+ "invlpg",
+ "invlpga",
+ "iretw",
+ "iretd",
+ "iretq",
+ "jo",
+ "jno",
+ "jb",
+ "jae",
+ "jz",
+ "jnz",
+ "jbe",
+ "ja",
+ "js",
+ "jns",
+ "jp",
+ "jnp",
+ "jl",
+ "jge",
+ "jle",
+ "jg",
+ "jcxz",
+ "jecxz",
+ "jrcxz",
+ "jmp",
+ "lahf",
+ "lar",
+ "lddqu",
+ "ldmxcsr",
+ "lds",
+ "lea",
+ "les",
+ "lfs",
+ "lgs",
+ "lidt",
+ "lss",
+ "leave",
+ "lfence",
+ "lgdt",
+ "lldt",
+ "lmsw",
+ "lock",
+ "lodsb",
+ "lodsw",
+ "lodsd",
+ "lodsq",
+ "loopnz",
+ "loope",
+ "loop",
+ "lsl",
+ "ltr",
+ "maskmovq",
+ "maxpd",
+ "maxps",
+ "maxsd",
+ "maxss",
+ "mfence",
+ "minpd",
+ "minps",
+ "minsd",
+ "minss",
+ "monitor",
+ "mov",
+ "movapd",
+ "movaps",
+ "movd",
+ "movddup",
+ "movdqa",
+ "movdqu",
+ "movdq2q",
+ "movhpd",
+ "movhps",
+ "movlhps",
+ "movlpd",
+ "movlps",
+ "movhlps",
+ "movmskpd",
+ "movmskps",
+ "movntdq",
+ "movnti",
+ "movntpd",
+ "movntps",
+ "movntq",
+ "movq",
+ "movqa",
+ "movq2dq",
+ "movsb",
+ "movsw",
+ "movsd",
+ "movsq",
+ "movsldup",
+ "movshdup",
+ "movss",
+ "movsx",
+ "movupd",
+ "movups",
+ "movzx",
+ "mul",
+ "mulpd",
+ "mulps",
+ "mulsd",
+ "mulss",
+ "mwait",
+ "neg",
+ "nop",
+ "not",
+ "or",
+ "orpd",
+ "orps",
+ "out",
+ "outsb",
+ "outsw",
+ "outsd",
+ "outsq",
+ "packsswb",
+ "packssdw",
+ "packuswb",
+ "paddb",
+ "paddw",
+ "paddq",
+ "paddsb",
+ "paddsw",
+ "paddusb",
+ "paddusw",
+ "pand",
+ "pandn",
+ "pause",
+ "pavgb",
+ "pavgw",
+ "pcmpeqb",
+ "pcmpeqw",
+ "pcmpeqd",
+ "pcmpgtb",
+ "pcmpgtw",
+ "pcmpgtd",
+ "pextrw",
+ "pinsrw",
+ "pmaddwd",
+ "pmaxsw",
+ "pmaxub",
+ "pminsw",
+ "pminub",
+ "pmovmskb",
+ "pmulhuw",
+ "pmulhw",
+ "pmullw",
+ "pmuludq",
+ "pop",
+ "popa",
+ "popad",
+ "popfw",
+ "popfd",
+ "popfq",
+ "por",
+ "prefetch",
+ "prefetchnta",
+ "prefetcht0",
+ "prefetcht1",
+ "prefetcht2",
+ "psadbw",
+ "pshufd",
+ "pshufhw",
+ "pshuflw",
+ "pshufw",
+ "pslldq",
+ "psllw",
+ "pslld",
+ "psllq",
+ "psraw",
+ "psrad",
+ "psrlw",
+ "psrld",
+ "psrlq",
+ "psrldq",
+ "psubb",
+ "psubw",
+ "psubd",
+ "psubq",
+ "psubsb",
+ "psubsw",
+ "psubusb",
+ "psubusw",
+ "punpckhbw",
+ "punpckhwd",
+ "punpckhdq",
+ "punpckhqdq",
+ "punpcklbw",
+ "punpcklwd",
+ "punpckldq",
+ "punpcklqdq",
+ "pi2fw",
+ "pi2fd",
+ "pf2iw",
+ "pf2id",
+ "pfnacc",
+ "pfpnacc",
+ "pfcmpge",
+ "pfmin",
+ "pfrcp",
+ "pfrsqrt",
+ "pfsub",
+ "pfadd",
+ "pfcmpgt",
+ "pfmax",
+ "pfrcpit1",
+ "pfrspit1",
+ "pfsubr",
+ "pfacc",
+ "pfcmpeq",
+ "pfmul",
+ "pfrcpit2",
+ "pmulhrw",
+ "pswapd",
+ "pavgusb",
+ "push",
+ "pusha",
+ "pushad",
+ "pushfw",
+ "pushfd",
+ "pushfq",
+ "pxor",
+ "rcl",
+ "rcr",
+ "rol",
+ "ror",
+ "rcpps",
+ "rcpss",
+ "rdmsr",
+ "rdpmc",
+ "rdtsc",
+ "rdtscp",
+ "repne",
+ "rep",
+ "ret",
+ "retf",
+ "rsm",
+ "rsqrtps",
+ "rsqrtss",
+ "sahf",
+ "sal",
+ "salc",
+ "sar",
+ "shl",
+ "shr",
+ "sbb",
+ "scasb",
+ "scasw",
+ "scasd",
+ "scasq",
+ "seto",
+ "setno",
+ "setb",
+ "setnb",
+ "setz",
+ "setnz",
+ "setbe",
+ "seta",
+ "sets",
+ "setns",
+ "setp",
+ "setnp",
+ "setl",
+ "setge",
+ "setle",
+ "setg",
+ "sfence",
+ "sgdt",
+ "shld",
+ "shrd",
+ "shufpd",
+ "shufps",
+ "sidt",
+ "sldt",
+ "smsw",
+ "sqrtps",
+ "sqrtpd",
+ "sqrtsd",
+ "sqrtss",
+ "stc",
+ "std",
+ "stgi",
+ "sti",
+ "skinit",
+ "stmxcsr",
+ "stosb",
+ "stosw",
+ "stosd",
+ "stosq",
+ "str",
+ "sub",
+ "subpd",
+ "subps",
+ "subsd",
+ "subss",
+ "swapgs",
+ "syscall",
+ "sysenter",
+ "sysexit",
+ "sysret",
+ "test",
+ "ucomisd",
+ "ucomiss",
+ "ud2",
+ "unpckhpd",
+ "unpckhps",
+ "unpcklps",
+ "unpcklpd",
+ "verr",
+ "verw",
+ "vmcall",
+ "vmclear",
+ "vmxon",
+ "vmptrld",
+ "vmptrst",
+ "vmresume",
+ "vmxoff",
+ "vmrun",
+ "vmmcall",
+ "vmload",
+ "vmsave",
+ "wait",
+ "wbinvd",
+ "wrmsr",
+ "xadd",
+ "xchg",
+ "xlatb",
+ "xor",
+ "xorpd",
+ "xorps",
+ "db",
+ "invalid",
+};
+
+
+
+static struct ud_itab_entry itab__0f[256] = {
+ /* 00 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_00__REG },
+ /* 01 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG },
+ /* 02 */ { UD_Ilar, O_Gv, O_Ew, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ilsl, O_Gv, O_Ew, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Isyscall, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iclts, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Isysret, O_NONE, O_NONE, O_NONE, P_none },
+ /* 08 */ { UD_Iinvd, O_NONE, O_NONE, O_NONE, P_none },
+ /* 09 */ { UD_Iwbinvd, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0B */ { UD_Iud2, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0D */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_0D__REG },
+ /* 0E */ { UD_Ifemms, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 10 */ { UD_Imovups, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 11 */ { UD_Imovups, O_W, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 12 */ { UD_Imovlps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 13 */ { UD_Imovlps, O_M, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 14 */ { UD_Iunpcklps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 15 */ { UD_Iunpckhps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 16 */ { UD_Imovhps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 17 */ { UD_Imovhps, O_M, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 18 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_18__REG },
+ /* 19 */ { UD_Inop, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 1A */ { UD_Inop, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 1B */ { UD_Inop, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 1C */ { UD_Inop, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 1D */ { UD_Inop, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 1E */ { UD_Inop, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 1F */ { UD_Inop, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 20 */ { UD_Imov, O_R, O_C, O_NONE, P_rexr },
+ /* 21 */ { UD_Imov, O_R, O_D, O_NONE, P_rexr },
+ /* 22 */ { UD_Imov, O_C, O_R, O_NONE, P_rexr },
+ /* 23 */ { UD_Imov, O_D, O_R, O_NONE, P_rexr },
+ /* 24 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 25 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 26 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 27 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 28 */ { UD_Imovaps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 29 */ { UD_Imovaps, O_W, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2A */ { UD_Icvtpi2ps, O_V, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2B */ { UD_Imovntps, O_M, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2C */ { UD_Icvttps2pi, O_P, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2D */ { UD_Icvtps2pi, O_P, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2E */ { UD_Iucomiss, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2F */ { UD_Icomiss, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 30 */ { UD_Iwrmsr, O_NONE, O_NONE, O_NONE, P_none },
+ /* 31 */ { UD_Irdtsc, O_NONE, O_NONE, O_NONE, P_none },
+ /* 32 */ { UD_Irdmsr, O_NONE, O_NONE, O_NONE, P_none },
+ /* 33 */ { UD_Irdpmc, O_NONE, O_NONE, O_NONE, P_none },
+ /* 34 */ { UD_Isysenter, O_NONE, O_NONE, O_NONE, P_inv64|P_none },
+ /* 35 */ { UD_Isysexit, O_NONE, O_NONE, O_NONE, P_none },
+ /* 36 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 37 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 38 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 39 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 40 */ { UD_Icmovo, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 41 */ { UD_Icmovno, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 42 */ { UD_Icmovb, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 43 */ { UD_Icmovae, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 44 */ { UD_Icmovz, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 45 */ { UD_Icmovnz, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 46 */ { UD_Icmovbe, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 47 */ { UD_Icmova, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 48 */ { UD_Icmovs, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 49 */ { UD_Icmovns, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 4A */ { UD_Icmovp, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 4B */ { UD_Icmovnp, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 4C */ { UD_Icmovl, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 4D */ { UD_Icmovge, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 4E */ { UD_Icmovle, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 4F */ { UD_Icmovg, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 50 */ { UD_Imovmskps, O_Gd, O_VR, O_NONE, P_oso|P_rexr|P_rexb },
+ /* 51 */ { UD_Isqrtps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 52 */ { UD_Irsqrtps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 53 */ { UD_Ircpps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 54 */ { UD_Iandps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 55 */ { UD_Iandnps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 56 */ { UD_Iorps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 57 */ { UD_Ixorps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 58 */ { UD_Iaddps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 59 */ { UD_Imulps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5A */ { UD_Icvtps2pd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5B */ { UD_Icvtdq2ps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5C */ { UD_Isubps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5D */ { UD_Iminps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5E */ { UD_Idivps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5F */ { UD_Imaxps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 60 */ { UD_Ipunpcklbw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 61 */ { UD_Ipunpcklwd, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 62 */ { UD_Ipunpckldq, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 63 */ { UD_Ipacksswb, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 64 */ { UD_Ipcmpgtb, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 65 */ { UD_Ipcmpgtw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 66 */ { UD_Ipcmpgtd, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 67 */ { UD_Ipackuswb, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 68 */ { UD_Ipunpckhbw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 69 */ { UD_Ipunpckhwd, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 6A */ { UD_Ipunpckhdq, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 6B */ { UD_Ipackssdw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 6C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6E */ { UD_Imovd, O_P, O_Ex, O_NONE, P_c2|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 6F */ { UD_Imovq, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 70 */ { UD_Ipshufw, O_P, O_Q, O_Ib, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 71 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_71__REG },
+ /* 72 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_72__REG },
+ /* 73 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_73__REG },
+ /* 74 */ { UD_Ipcmpeqb, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 75 */ { UD_Ipcmpeqw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 76 */ { UD_Ipcmpeqd, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 77 */ { UD_Iemms, O_NONE, O_NONE, O_NONE, P_none },
+ /* 78 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 79 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7E */ { UD_Imovd, O_Ex, O_P, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 7F */ { UD_Imovq, O_Q, O_P, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 80 */ { UD_Ijo, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 81 */ { UD_Ijno, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 82 */ { UD_Ijb, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 83 */ { UD_Ijae, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 84 */ { UD_Ijz, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 85 */ { UD_Ijnz, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 86 */ { UD_Ijbe, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 87 */ { UD_Ija, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 88 */ { UD_Ijs, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 89 */ { UD_Ijns, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 8A */ { UD_Ijp, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 8B */ { UD_Ijnp, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 8C */ { UD_Ijl, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 8D */ { UD_Ijge, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 8E */ { UD_Ijle, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 8F */ { UD_Ijg, O_Jz, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_oso },
+ /* 90 */ { UD_Iseto, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 91 */ { UD_Isetno, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 92 */ { UD_Isetb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 93 */ { UD_Isetnb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 94 */ { UD_Isetz, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 95 */ { UD_Isetnz, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 96 */ { UD_Isetbe, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 97 */ { UD_Iseta, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 98 */ { UD_Isets, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 99 */ { UD_Isetns, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 9A */ { UD_Isetp, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 9B */ { UD_Isetnp, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 9C */ { UD_Isetl, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 9D */ { UD_Isetge, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 9E */ { UD_Isetle, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 9F */ { UD_Isetg, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* A0 */ { UD_Ipush, O_FS, O_NONE, O_NONE, P_none },
+ /* A1 */ { UD_Ipop, O_FS, O_NONE, O_NONE, P_none },
+ /* A2 */ { UD_Icpuid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A3 */ { UD_Ibt, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* A4 */ { UD_Ishld, O_Ev, O_Gv, O_Ib, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* A5 */ { UD_Ishld, O_Ev, O_Gv, O_CL, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* A6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A8 */ { UD_Ipush, O_GS, O_NONE, O_NONE, P_none },
+ /* A9 */ { UD_Ipop, O_GS, O_NONE, O_NONE, P_none },
+ /* AA */ { UD_Irsm, O_NONE, O_NONE, O_NONE, P_none },
+ /* AB */ { UD_Ibts, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* AC */ { UD_Ishrd, O_Ev, O_Gv, O_Ib, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* AD */ { UD_Ishrd, O_Ev, O_Gv, O_CL, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* AE */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_AE__REG },
+ /* AF */ { UD_Iimul, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* B0 */ { UD_Icmpxchg, O_Eb, O_Gb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* B1 */ { UD_Icmpxchg, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* B2 */ { UD_Ilss, O_Gz, O_M, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* B3 */ { UD_Ibtr, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* B4 */ { UD_Ilfs, O_Gz, O_M, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* B5 */ { UD_Ilgs, O_Gz, O_M, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* B6 */ { UD_Imovzx, O_Gv, O_Eb, O_NONE, P_c2|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* B7 */ { UD_Imovzx, O_Gv, O_Ew, O_NONE, P_c2|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* B8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BA */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_BA__REG },
+ /* BB */ { UD_Ibtc, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* BC */ { UD_Ibsf, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* BD */ { UD_Ibsr, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* BE */ { UD_Imovsx, O_Gv, O_Eb, O_NONE, P_c2|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* BF */ { UD_Imovsx, O_Gv, O_Ew, O_NONE, P_c2|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* C0 */ { UD_Ixadd, O_Eb, O_Gb, O_NONE, P_aso|P_oso|P_rexr|P_rexx|P_rexb },
+ /* C1 */ { UD_Ixadd, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* C2 */ { UD_Icmpps, O_V, O_W, O_Ib, P_aso|P_rexr|P_rexx|P_rexb },
+ /* C3 */ { UD_Imovnti, O_M, O_Gvw, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* C4 */ { UD_Ipinsrw, O_P, O_Ew, O_Ib, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* C5 */ { UD_Ipextrw, O_Gd, O_PR, O_Ib, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* C6 */ { UD_Ishufps, O_V, O_W, O_Ib, P_aso|P_rexr|P_rexx|P_rexb },
+ /* C7 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_C7__REG },
+ /* C8 */ { UD_Ibswap, O_rAXr8, O_NONE, O_NONE, P_oso|P_rexw|P_rexb },
+ /* C9 */ { UD_Ibswap, O_rCXr9, O_NONE, O_NONE, P_oso|P_rexw|P_rexb },
+ /* CA */ { UD_Ibswap, O_rDXr10, O_NONE, O_NONE, P_oso|P_rexw|P_rexb },
+ /* CB */ { UD_Ibswap, O_rBXr11, O_NONE, O_NONE, P_oso|P_rexw|P_rexb },
+ /* CC */ { UD_Ibswap, O_rSPr12, O_NONE, O_NONE, P_oso|P_rexw|P_rexb },
+ /* CD */ { UD_Ibswap, O_rBPr13, O_NONE, O_NONE, P_oso|P_rexw|P_rexb },
+ /* CE */ { UD_Ibswap, O_rSIr14, O_NONE, O_NONE, P_oso|P_rexw|P_rexb },
+ /* CF */ { UD_Ibswap, O_rDIr15, O_NONE, O_NONE, P_oso|P_rexw|P_rexb },
+ /* D0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D1 */ { UD_Ipsrlw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D2 */ { UD_Ipsrld, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D3 */ { UD_Ipsrlq, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D4 */ { UD_Ipaddq, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D5 */ { UD_Ipmullw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D7 */ { UD_Ipmovmskb, O_Gd, O_PR, O_NONE, P_oso|P_rexr|P_rexb },
+ /* D8 */ { UD_Ipsubusb, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D9 */ { UD_Ipsubusw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* DA */ { UD_Ipminub, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* DB */ { UD_Ipand, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* DC */ { UD_Ipaddusb, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* DD */ { UD_Ipaddusw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* DE */ { UD_Ipmaxub, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* DF */ { UD_Ipandn, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E0 */ { UD_Ipavgb, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E1 */ { UD_Ipsraw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E2 */ { UD_Ipsrad, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E3 */ { UD_Ipavgw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E4 */ { UD_Ipmulhuw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E5 */ { UD_Ipmulhw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E7 */ { UD_Imovntq, O_M, O_P, O_NONE, P_none },
+ /* E8 */ { UD_Ipsubsb, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E9 */ { UD_Ipsubsw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* EA */ { UD_Ipminsw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* EB */ { UD_Ipor, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* EC */ { UD_Ipaddsb, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* ED */ { UD_Ipaddsw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* EE */ { UD_Ipmaxsw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* EF */ { UD_Ipxor, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F1 */ { UD_Ipsllw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F2 */ { UD_Ipslld, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F3 */ { UD_Ipsllq, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F4 */ { UD_Ipmuludq, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F5 */ { UD_Ipmaddwd, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F6 */ { UD_Ipsadbw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F7 */ { UD_Imaskmovq, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F8 */ { UD_Ipsubb, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F9 */ { UD_Ipsubw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* FA */ { UD_Ipsubd, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* FB */ { UD_Ipsubq, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* FC */ { UD_Ipaddb, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* FD */ { UD_Ipaddw, O_P, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* FE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_00__reg[8] = {
+ /* 00 */ { UD_Isldt, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Istr, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Illdt, O_Ew, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Iltr, O_Ew, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Iverr, O_Ew, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Iverw, O_Ew, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg[8] = {
+ /* 00 */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_00__MOD },
+ /* 01 */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_01__MOD },
+ /* 02 */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_02__MOD },
+ /* 03 */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_03__MOD },
+ /* 04 */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_04__MOD },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_06__MOD },
+ /* 07 */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_07__MOD },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_00__mod[2] = {
+ /* 00 */ { UD_Isgdt, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Igrp_rm, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_00__mod__op_01__rm[8] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM__OP_01__VENDOR },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM__OP_03__VENDOR },
+ /* 04 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM__OP_04__VENDOR },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_00__mod__op_01__rm__op_01__vendor[2] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Ivmcall, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_00__mod__op_01__rm__op_03__vendor[2] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Ivmresume, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_00__mod__op_01__rm__op_04__vendor[2] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Ivmxoff, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_01__mod[2] = {
+ /* 00 */ { UD_Isidt, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Igrp_rm, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_01__MOD__OP_01__RM },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_01__mod__op_01__rm[8] = {
+ /* 00 */ { UD_Imonitor, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Imwait, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_02__mod[2] = {
+ /* 00 */ { UD_Ilgdt, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_03__mod[2] = {
+ /* 00 */ { UD_Ilidt, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Igrp_rm, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_03__mod__op_01__rm[8] = {
+ /* 00 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_00__VENDOR },
+ /* 01 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_01__VENDOR },
+ /* 02 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_02__VENDOR },
+ /* 03 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_03__VENDOR },
+ /* 04 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_04__VENDOR },
+ /* 05 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_05__VENDOR },
+ /* 06 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_06__VENDOR },
+ /* 07 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_07__VENDOR },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_03__mod__op_01__rm__op_00__vendor[2] = {
+ /* 00 */ { UD_Ivmrun, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_03__mod__op_01__rm__op_01__vendor[2] = {
+ /* 00 */ { UD_Ivmmcall, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_03__mod__op_01__rm__op_02__vendor[2] = {
+ /* 00 */ { UD_Ivmload, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_03__mod__op_01__rm__op_03__vendor[2] = {
+ /* 00 */ { UD_Ivmsave, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_03__mod__op_01__rm__op_04__vendor[2] = {
+ /* 00 */ { UD_Istgi, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_03__mod__op_01__rm__op_05__vendor[2] = {
+ /* 00 */ { UD_Iclgi, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_03__mod__op_01__rm__op_06__vendor[2] = {
+ /* 00 */ { UD_Iskinit, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_03__mod__op_01__rm__op_07__vendor[2] = {
+ /* 00 */ { UD_Iinvlpga, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_04__mod[2] = {
+ /* 00 */ { UD_Ismsw, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_06__mod[2] = {
+ /* 00 */ { UD_Ilmsw, O_Ew, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_07__mod[2] = {
+ /* 00 */ { UD_Iinvlpg, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Igrp_rm, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_07__MOD__OP_01__RM },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_07__mod__op_01__rm[8] = {
+ /* 00 */ { UD_Iswapgs, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_01__REG__OP_07__MOD__OP_01__RM__OP_01__VENDOR },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_01__reg__op_07__mod__op_01__rm__op_01__vendor[2] = {
+ /* 00 */ { UD_Irdtscp, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_0d__reg[8] = {
+ /* 00 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__0f__op_18__reg[8] = {
+ /* 00 */ { UD_Iprefetchnta, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iprefetcht0, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Iprefetcht1, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Iprefetcht2, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_71__reg[8] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Ipsrlw, O_PR, O_Ib, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Ipsraw, O_PR, O_Ib, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Ipsllw, O_PR, O_Ib, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_72__reg[8] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Ipsrld, O_PR, O_Ib, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Ipsrad, O_PR, O_Ib, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Ipslld, O_PR, O_Ib, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_73__reg[8] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Ipsrlq, O_PR, O_Ib, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Ipsllq, O_PR, O_Ib, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_ae__reg[8] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Ildmxcsr, O_Md, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Istmxcsr, O_Md, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_AE__REG__OP_05__MOD },
+ /* 06 */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_AE__REG__OP_06__MOD },
+ /* 07 */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_AE__REG__OP_07__MOD },
+};
+
+static struct ud_itab_entry itab__0f__op_ae__reg__op_05__mod[2] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Igrp_rm, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_AE__REG__OP_05__MOD__OP_01__RM },
+};
+
+static struct ud_itab_entry itab__0f__op_ae__reg__op_05__mod__op_01__rm[8] = {
+ /* 00 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_ae__reg__op_06__mod[2] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Igrp_rm, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_AE__REG__OP_06__MOD__OP_01__RM },
+};
+
+static struct ud_itab_entry itab__0f__op_ae__reg__op_06__mod__op_01__rm[8] = {
+ /* 00 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_ae__reg__op_07__mod[2] = {
+ /* 00 */ { UD_Iclflush, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Igrp_rm, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_AE__REG__OP_07__MOD__OP_01__RM },
+};
+
+static struct ud_itab_entry itab__0f__op_ae__reg__op_07__mod__op_01__rm[8] = {
+ /* 00 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__0f__op_ba__reg[8] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Ibt, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ibts, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ibtr, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Ibtc, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__0f__op_c7__reg[8] = {
+ /* 00 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_C7__REG__OP_00__VENDOR },
+ /* 01 */ { UD_Icmpxchg8b, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_C7__REG__OP_07__VENDOR },
+};
+
+static struct ud_itab_entry itab__0f__op_c7__reg__op_00__vendor[2] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Ivmptrld, O_Mq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__0f__op_c7__reg__op_07__vendor[2] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Ivmptrst, O_Mq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__0f__op_d9__mod[2] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Igrp_x87, O_NONE, O_NONE, O_NONE, ITAB__0F__OP_D9__MOD__OP_01__X87 },
+};
+
+static struct ud_itab_entry itab__0f__op_d9__mod__op_01__x87[64] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 08 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 09 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 10 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 11 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 12 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 13 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 14 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 15 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 16 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 17 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 18 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 19 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 20 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 21 */ { UD_Ifabs, O_NONE, O_NONE, O_NONE, P_none },
+ /* 22 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 23 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 24 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 25 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 26 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 27 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 28 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 29 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 30 */ { UD_If2xm1, O_NONE, O_NONE, O_NONE, P_none },
+ /* 31 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 32 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 33 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 34 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 35 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 36 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 37 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 38 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 39 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte[256] = {
+ /* 00 */ { UD_Iadd, O_Eb, O_Gb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iadd, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Iadd, O_Gb, O_Eb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Iadd, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Iadd, O_AL, O_Ib, O_NONE, P_none },
+ /* 05 */ { UD_Iadd, O_rAX, O_Iz, O_NONE, P_oso|P_rexw },
+ /* 06 */ { UD_Ipush, O_ES, O_NONE, O_NONE, P_inv64|P_none },
+ /* 07 */ { UD_Ipop, O_ES, O_NONE, O_NONE, P_inv64|P_none },
+ /* 08 */ { UD_Ior, O_Eb, O_Gb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 09 */ { UD_Ior, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 0A */ { UD_Ior, O_Gb, O_Eb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 0B */ { UD_Ior, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 0C */ { UD_Ior, O_AL, O_Ib, O_NONE, P_none },
+ /* 0D */ { UD_Ior, O_rAX, O_Iz, O_NONE, P_oso|P_rexw },
+ /* 0E */ { UD_Ipush, O_CS, O_NONE, O_NONE, P_inv64|P_none },
+ /* 0F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 10 */ { UD_Iadc, O_Eb, O_Gb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 11 */ { UD_Iadc, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 12 */ { UD_Iadc, O_Gb, O_Eb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 13 */ { UD_Iadc, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 14 */ { UD_Iadc, O_AL, O_Ib, O_NONE, P_none },
+ /* 15 */ { UD_Iadc, O_rAX, O_Iz, O_NONE, P_oso|P_rexw },
+ /* 16 */ { UD_Ipush, O_SS, O_NONE, O_NONE, P_inv64|P_none },
+ /* 17 */ { UD_Ipop, O_SS, O_NONE, O_NONE, P_inv64|P_none },
+ /* 18 */ { UD_Isbb, O_Eb, O_Gb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 19 */ { UD_Isbb, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 1A */ { UD_Isbb, O_Gb, O_Eb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 1B */ { UD_Isbb, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 1C */ { UD_Isbb, O_AL, O_Ib, O_NONE, P_none },
+ /* 1D */ { UD_Isbb, O_rAX, O_Iz, O_NONE, P_oso|P_rexw },
+ /* 1E */ { UD_Ipush, O_DS, O_NONE, O_NONE, P_inv64|P_none },
+ /* 1F */ { UD_Ipop, O_DS, O_NONE, O_NONE, P_inv64|P_none },
+ /* 20 */ { UD_Iand, O_Eb, O_Gb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 21 */ { UD_Iand, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 22 */ { UD_Iand, O_Gb, O_Eb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 23 */ { UD_Iand, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 24 */ { UD_Iand, O_AL, O_Ib, O_NONE, P_none },
+ /* 25 */ { UD_Iand, O_rAX, O_Iz, O_NONE, P_oso|P_rexw },
+ /* 26 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 27 */ { UD_Idaa, O_NONE, O_NONE, O_NONE, P_inv64|P_none },
+ /* 28 */ { UD_Isub, O_Eb, O_Gb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 29 */ { UD_Isub, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 2A */ { UD_Isub, O_Gb, O_Eb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2B */ { UD_Isub, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 2C */ { UD_Isub, O_AL, O_Ib, O_NONE, P_none },
+ /* 2D */ { UD_Isub, O_rAX, O_Iz, O_NONE, P_oso|P_rexw },
+ /* 2E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2F */ { UD_Idas, O_NONE, O_NONE, O_NONE, P_inv64|P_none },
+ /* 30 */ { UD_Ixor, O_Eb, O_Gb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 31 */ { UD_Ixor, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 32 */ { UD_Ixor, O_Gb, O_Eb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 33 */ { UD_Ixor, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 34 */ { UD_Ixor, O_AL, O_Ib, O_NONE, P_none },
+ /* 35 */ { UD_Ixor, O_rAX, O_Iz, O_NONE, P_oso|P_rexw },
+ /* 36 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 37 */ { UD_Iaaa, O_NONE, O_NONE, O_NONE, P_inv64|P_none },
+ /* 38 */ { UD_Icmp, O_Eb, O_Gb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 39 */ { UD_Icmp, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 3A */ { UD_Icmp, O_Gb, O_Eb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 3B */ { UD_Icmp, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 3C */ { UD_Icmp, O_AL, O_Ib, O_NONE, P_none },
+ /* 3D */ { UD_Icmp, O_rAX, O_Iz, O_NONE, P_oso|P_rexw },
+ /* 3E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3F */ { UD_Iaas, O_NONE, O_NONE, O_NONE, P_inv64|P_none },
+ /* 40 */ { UD_Iinc, O_eAX, O_NONE, O_NONE, P_oso },
+ /* 41 */ { UD_Iinc, O_eCX, O_NONE, O_NONE, P_oso },
+ /* 42 */ { UD_Iinc, O_eDX, O_NONE, O_NONE, P_oso },
+ /* 43 */ { UD_Iinc, O_eBX, O_NONE, O_NONE, P_oso },
+ /* 44 */ { UD_Iinc, O_eSP, O_NONE, O_NONE, P_oso },
+ /* 45 */ { UD_Iinc, O_eBP, O_NONE, O_NONE, P_oso },
+ /* 46 */ { UD_Iinc, O_eSI, O_NONE, O_NONE, P_oso },
+ /* 47 */ { UD_Iinc, O_eDI, O_NONE, O_NONE, P_oso },
+ /* 48 */ { UD_Idec, O_eAX, O_NONE, O_NONE, P_oso },
+ /* 49 */ { UD_Idec, O_eCX, O_NONE, O_NONE, P_oso },
+ /* 4A */ { UD_Idec, O_eDX, O_NONE, O_NONE, P_oso },
+ /* 4B */ { UD_Idec, O_eBX, O_NONE, O_NONE, P_oso },
+ /* 4C */ { UD_Idec, O_eSP, O_NONE, O_NONE, P_oso },
+ /* 4D */ { UD_Idec, O_eBP, O_NONE, O_NONE, P_oso },
+ /* 4E */ { UD_Idec, O_eSI, O_NONE, O_NONE, P_oso },
+ /* 4F */ { UD_Idec, O_eDI, O_NONE, O_NONE, P_oso },
+ /* 50 */ { UD_Ipush, O_rAXr8, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 51 */ { UD_Ipush, O_rCXr9, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 52 */ { UD_Ipush, O_rDXr10, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 53 */ { UD_Ipush, O_rBXr11, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 54 */ { UD_Ipush, O_rSPr12, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 55 */ { UD_Ipush, O_rBPr13, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 56 */ { UD_Ipush, O_rSIr14, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 57 */ { UD_Ipush, O_rDIr15, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 58 */ { UD_Ipop, O_rAXr8, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 59 */ { UD_Ipop, O_rCXr9, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 5A */ { UD_Ipop, O_rDXr10, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 5B */ { UD_Ipop, O_rBXr11, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 5C */ { UD_Ipop, O_rSPr12, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 5D */ { UD_Ipop, O_rBPr13, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 5E */ { UD_Ipop, O_rSIr14, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 5F */ { UD_Ipop, O_rDIr15, O_NONE, O_NONE, P_def64|P_depM|P_oso|P_rexb },
+ /* 60 */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_60__OSIZE },
+ /* 61 */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_61__OSIZE },
+ /* 62 */ { UD_Ibound, O_Gv, O_M, O_NONE, P_inv64|P_aso|P_oso },
+ /* 63 */ { UD_Igrp_mode, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_63__MODE },
+ /* 64 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 65 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 66 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 67 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 68 */ { UD_Ipush, O_Iz, O_NONE, O_NONE, P_c1|P_oso },
+ /* 69 */ { UD_Iimul, O_Gv, O_Ev, O_Iz, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 6A */ { UD_Ipush, O_Ib, O_NONE, O_NONE, P_none },
+ /* 6B */ { UD_Iimul, O_Gv, O_Ev, O_Ib, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 6C */ { UD_Iinsb, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6D */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_6D__OSIZE },
+ /* 6E */ { UD_Ioutsb, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6F */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_6F__OSIZE },
+ /* 70 */ { UD_Ijo, O_Jb, O_NONE, O_NONE, P_none },
+ /* 71 */ { UD_Ijno, O_Jb, O_NONE, O_NONE, P_none },
+ /* 72 */ { UD_Ijb, O_Jb, O_NONE, O_NONE, P_none },
+ /* 73 */ { UD_Ijae, O_Jb, O_NONE, O_NONE, P_none },
+ /* 74 */ { UD_Ijz, O_Jb, O_NONE, O_NONE, P_none },
+ /* 75 */ { UD_Ijnz, O_Jb, O_NONE, O_NONE, P_none },
+ /* 76 */ { UD_Ijbe, O_Jb, O_NONE, O_NONE, P_none },
+ /* 77 */ { UD_Ija, O_Jb, O_NONE, O_NONE, P_none },
+ /* 78 */ { UD_Ijs, O_Jb, O_NONE, O_NONE, P_none },
+ /* 79 */ { UD_Ijns, O_Jb, O_NONE, O_NONE, P_none },
+ /* 7A */ { UD_Ijp, O_Jb, O_NONE, O_NONE, P_none },
+ /* 7B */ { UD_Ijnp, O_Jb, O_NONE, O_NONE, P_none },
+ /* 7C */ { UD_Ijl, O_Jb, O_NONE, O_NONE, P_none },
+ /* 7D */ { UD_Ijge, O_Jb, O_NONE, O_NONE, P_none },
+ /* 7E */ { UD_Ijle, O_Jb, O_NONE, O_NONE, P_none },
+ /* 7F */ { UD_Ijg, O_Jb, O_NONE, O_NONE, P_none },
+ /* 80 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_80__REG },
+ /* 81 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_81__REG },
+ /* 82 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_82__REG },
+ /* 83 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_83__REG },
+ /* 84 */ { UD_Itest, O_Eb, O_Gb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 85 */ { UD_Itest, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 86 */ { UD_Ixchg, O_Eb, O_Gb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 87 */ { UD_Ixchg, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 88 */ { UD_Imov, O_Eb, O_Gb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 89 */ { UD_Imov, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 8A */ { UD_Imov, O_Gb, O_Eb, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 8B */ { UD_Imov, O_Gv, O_Ev, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 8C */ { UD_Imov, O_Ev, O_S, O_NONE, P_aso|P_oso|P_rexr|P_rexx|P_rexb },
+ /* 8D */ { UD_Ilea, O_Gv, O_M, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 8E */ { UD_Imov, O_S, O_Ev, O_NONE, P_aso|P_oso|P_rexr|P_rexx|P_rexb },
+ /* 8F */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_8F__REG },
+ /* 90 */ { UD_Ixchg, O_rAXr8, O_rAX, O_NONE, P_oso|P_rexw|P_rexb },
+ /* 91 */ { UD_Ixchg, O_rCXr9, O_rAX, O_NONE, P_oso|P_rexw|P_rexb },
+ /* 92 */ { UD_Ixchg, O_rDXr10, O_rAX, O_NONE, P_oso|P_rexw|P_rexb },
+ /* 93 */ { UD_Ixchg, O_rBXr11, O_rAX, O_NONE, P_oso|P_rexw|P_rexb },
+ /* 94 */ { UD_Ixchg, O_rSPr12, O_rAX, O_NONE, P_oso|P_rexw|P_rexb },
+ /* 95 */ { UD_Ixchg, O_rBPr13, O_rAX, O_NONE, P_oso|P_rexw|P_rexb },
+ /* 96 */ { UD_Ixchg, O_rSIr14, O_rAX, O_NONE, P_oso|P_rexw|P_rexb },
+ /* 97 */ { UD_Ixchg, O_rDIr15, O_rAX, O_NONE, P_oso|P_rexw|P_rexb },
+ /* 98 */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_98__OSIZE },
+ /* 99 */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_99__OSIZE },
+ /* 9A */ { UD_Icall, O_Ap, O_NONE, O_NONE, P_inv64|P_oso },
+ /* 9B */ { UD_Iwait, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9C */ { UD_Igrp_mode, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_9C__MODE },
+ /* 9D */ { UD_Igrp_mode, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_9D__MODE },
+ /* 9E */ { UD_Isahf, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9F */ { UD_Ilahf, O_NONE, O_NONE, O_NONE, P_none },
+ /* A0 */ { UD_Imov, O_AL, O_Ob, O_NONE, P_none },
+ /* A1 */ { UD_Imov, O_rAX, O_Ov, O_NONE, P_aso|P_oso|P_rexw },
+ /* A2 */ { UD_Imov, O_Ob, O_AL, O_NONE, P_none },
+ /* A3 */ { UD_Imov, O_Ov, O_rAX, O_NONE, P_aso|P_oso|P_rexw },
+ /* A4 */ { UD_Imovsb, O_NONE, O_NONE, O_NONE, P_ImpAddr|P_none },
+ /* A5 */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_A5__OSIZE },
+ /* A6 */ { UD_Icmpsb, O_NONE, O_NONE, O_NONE, P_none },
+ /* A7 */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_A7__OSIZE },
+ /* A8 */ { UD_Itest, O_AL, O_Ib, O_NONE, P_none },
+ /* A9 */ { UD_Itest, O_rAX, O_Iz, O_NONE, P_oso|P_rexw },
+ /* AA */ { UD_Istosb, O_NONE, O_NONE, O_NONE, P_ImpAddr|P_none },
+ /* AB */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_AB__OSIZE },
+ /* AC */ { UD_Ilodsb, O_NONE, O_NONE, O_NONE, P_ImpAddr|P_none },
+ /* AD */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_AD__OSIZE },
+ /* AE */ { UD_Iscasb, O_NONE, O_NONE, O_NONE, P_none },
+ /* AF */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_AF__OSIZE },
+ /* B0 */ { UD_Imov, O_ALr8b, O_Ib, O_NONE, P_rexb },
+ /* B1 */ { UD_Imov, O_CLr9b, O_Ib, O_NONE, P_rexb },
+ /* B2 */ { UD_Imov, O_DLr10b, O_Ib, O_NONE, P_rexb },
+ /* B3 */ { UD_Imov, O_BLr11b, O_Ib, O_NONE, P_rexb },
+ /* B4 */ { UD_Imov, O_AHr12b, O_Ib, O_NONE, P_rexb },
+ /* B5 */ { UD_Imov, O_CHr13b, O_Ib, O_NONE, P_rexb },
+ /* B6 */ { UD_Imov, O_DHr14b, O_Ib, O_NONE, P_rexb },
+ /* B7 */ { UD_Imov, O_BHr15b, O_Ib, O_NONE, P_rexb },
+ /* B8 */ { UD_Imov, O_rAXr8, O_Iv, O_NONE, P_oso|P_rexw|P_rexb },
+ /* B9 */ { UD_Imov, O_rCXr9, O_Iv, O_NONE, P_oso|P_rexw|P_rexb },
+ /* BA */ { UD_Imov, O_rDXr10, O_Iv, O_NONE, P_oso|P_rexw|P_rexb },
+ /* BB */ { UD_Imov, O_rBXr11, O_Iv, O_NONE, P_oso|P_rexw|P_rexb },
+ /* BC */ { UD_Imov, O_rSPr12, O_Iv, O_NONE, P_oso|P_rexw|P_rexb },
+ /* BD */ { UD_Imov, O_rBPr13, O_Iv, O_NONE, P_oso|P_rexw|P_rexb },
+ /* BE */ { UD_Imov, O_rSIr14, O_Iv, O_NONE, P_oso|P_rexw|P_rexb },
+ /* BF */ { UD_Imov, O_rDIr15, O_Iv, O_NONE, P_oso|P_rexw|P_rexb },
+ /* C0 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_C0__REG },
+ /* C1 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_C1__REG },
+ /* C2 */ { UD_Iret, O_Iw, O_NONE, O_NONE, P_none },
+ /* C3 */ { UD_Iret, O_NONE, O_NONE, O_NONE, P_none },
+ /* C4 */ { UD_Iles, O_Gv, O_M, O_NONE, P_inv64|P_aso|P_oso },
+ /* C5 */ { UD_Ilds, O_Gv, O_M, O_NONE, P_inv64|P_aso|P_oso },
+ /* C6 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_C6__REG },
+ /* C7 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_C7__REG },
+ /* C8 */ { UD_Ienter, O_Iw, O_Ib, O_NONE, P_def64|P_depM|P_none },
+ /* C9 */ { UD_Ileave, O_NONE, O_NONE, O_NONE, P_none },
+ /* CA */ { UD_Iretf, O_Iw, O_NONE, O_NONE, P_none },
+ /* CB */ { UD_Iretf, O_NONE, O_NONE, O_NONE, P_none },
+ /* CC */ { UD_Iint3, O_NONE, O_NONE, O_NONE, P_none },
+ /* CD */ { UD_Iint, O_Ib, O_NONE, O_NONE, P_none },
+ /* CE */ { UD_Iinto, O_NONE, O_NONE, O_NONE, P_inv64|P_none },
+ /* CF */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_CF__OSIZE },
+ /* D0 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_D0__REG },
+ /* D1 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_D1__REG },
+ /* D2 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_D2__REG },
+ /* D3 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_D3__REG },
+ /* D4 */ { UD_Iaam, O_Ib, O_NONE, O_NONE, P_inv64|P_none },
+ /* D5 */ { UD_Iaad, O_Ib, O_NONE, O_NONE, P_inv64|P_none },
+ /* D6 */ { UD_Isalc, O_NONE, O_NONE, O_NONE, P_inv64|P_none },
+ /* D7 */ { UD_Ixlatb, O_NONE, O_NONE, O_NONE, P_rexw },
+ /* D8 */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_D8__MOD },
+ /* D9 */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_D9__MOD },
+ /* DA */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DA__MOD },
+ /* DB */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DB__MOD },
+ /* DC */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DC__MOD },
+ /* DD */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DD__MOD },
+ /* DE */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DE__MOD },
+ /* DF */ { UD_Igrp_mod, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DF__MOD },
+ /* E0 */ { UD_Iloopnz, O_Jb, O_NONE, O_NONE, P_none },
+ /* E1 */ { UD_Iloope, O_Jb, O_NONE, O_NONE, P_none },
+ /* E2 */ { UD_Iloop, O_Jb, O_NONE, O_NONE, P_none },
+ /* E3 */ { UD_Igrp_asize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_E3__ASIZE },
+ /* E4 */ { UD_Iin, O_AL, O_Ib, O_NONE, P_none },
+ /* E5 */ { UD_Iin, O_eAX, O_Ib, O_NONE, P_oso },
+ /* E6 */ { UD_Iout, O_Ib, O_AL, O_NONE, P_none },
+ /* E7 */ { UD_Iout, O_Ib, O_eAX, O_NONE, P_oso },
+ /* E8 */ { UD_Icall, O_Jz, O_NONE, O_NONE, P_def64|P_oso },
+ /* E9 */ { UD_Ijmp, O_Jz, O_NONE, O_NONE, P_def64|P_depM|P_oso },
+ /* EA */ { UD_Ijmp, O_Ap, O_NONE, O_NONE, P_inv64|P_none },
+ /* EB */ { UD_Ijmp, O_Jb, O_NONE, O_NONE, P_none },
+ /* EC */ { UD_Iin, O_AL, O_DX, O_NONE, P_none },
+ /* ED */ { UD_Iin, O_eAX, O_DX, O_NONE, P_oso },
+ /* EE */ { UD_Iout, O_DX, O_AL, O_NONE, P_none },
+ /* EF */ { UD_Iout, O_DX, O_eAX, O_NONE, P_oso },
+ /* F0 */ { UD_Ilock, O_NONE, O_NONE, O_NONE, P_none },
+ /* F1 */ { UD_Iint1, O_NONE, O_NONE, O_NONE, P_none },
+ /* F2 */ { UD_Irepne, O_NONE, O_NONE, O_NONE, P_none },
+ /* F3 */ { UD_Irep, O_NONE, O_NONE, O_NONE, P_none },
+ /* F4 */ { UD_Ihlt, O_NONE, O_NONE, O_NONE, P_none },
+ /* F5 */ { UD_Icmc, O_NONE, O_NONE, O_NONE, P_none },
+ /* F6 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_F6__REG },
+ /* F7 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_F7__REG },
+ /* F8 */ { UD_Iclc, O_NONE, O_NONE, O_NONE, P_none },
+ /* F9 */ { UD_Istc, O_NONE, O_NONE, O_NONE, P_none },
+ /* FA */ { UD_Icli, O_NONE, O_NONE, O_NONE, P_none },
+ /* FB */ { UD_Isti, O_NONE, O_NONE, O_NONE, P_none },
+ /* FC */ { UD_Icld, O_NONE, O_NONE, O_NONE, P_none },
+ /* FD */ { UD_Istd, O_NONE, O_NONE, O_NONE, P_none },
+ /* FE */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_FE__REG },
+ /* FF */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_FF__REG },
+};
+
+static struct ud_itab_entry itab__1byte__op_60__osize[3] = {
+ /* 00 */ { UD_Ipusha, O_NONE, O_NONE, O_NONE, P_inv64|P_oso },
+ /* 01 */ { UD_Ipushad, O_NONE, O_NONE, O_NONE, P_inv64|P_oso },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_61__osize[3] = {
+ /* 00 */ { UD_Ipopa, O_NONE, O_NONE, O_NONE, P_inv64|P_oso },
+ /* 01 */ { UD_Ipopad, O_NONE, O_NONE, O_NONE, P_inv64|P_oso },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_63__mode[3] = {
+ /* 00 */ { UD_Iarpl, O_Ew, O_Gw, O_NONE, P_inv64|P_aso },
+ /* 01 */ { UD_Iarpl, O_Ew, O_Gw, O_NONE, P_inv64|P_aso },
+ /* 02 */ { UD_Imovsxd, O_Gv, O_Ed, O_NONE, P_c2|P_aso|P_oso|P_rexw|P_rexx|P_rexr|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_6d__osize[3] = {
+ /* 00 */ { UD_Iinsw, O_NONE, O_NONE, O_NONE, P_oso },
+ /* 01 */ { UD_Iinsd, O_NONE, O_NONE, O_NONE, P_oso },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_6f__osize[3] = {
+ /* 00 */ { UD_Ioutsw, O_NONE, O_NONE, O_NONE, P_oso },
+ /* 01 */ { UD_Ioutsd, O_NONE, O_NONE, O_NONE, P_oso },
+ /* 02 */ { UD_Ioutsq, O_NONE, O_NONE, O_NONE, P_oso },
+};
+
+static struct ud_itab_entry itab__1byte__op_80__reg[8] = {
+ /* 00 */ { UD_Iadd, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Ior, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Iadc, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Isbb, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Iand, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Isub, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ixor, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Icmp, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_81__reg[8] = {
+ /* 00 */ { UD_Iadd, O_Ev, O_Iz, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Ior, O_Ev, O_Iz, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Iadc, O_Ev, O_Iz, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Isbb, O_Ev, O_Iz, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Iand, O_Ev, O_Iz, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Isub, O_Ev, O_Iz, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ixor, O_Ev, O_Iz, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Icmp, O_Ev, O_Iz, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_82__reg[8] = {
+ /* 00 */ { UD_Iadd, O_Eb, O_Ib, O_NONE, P_c1|P_inv64|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Ior, O_Eb, O_Ib, O_NONE, P_c1|P_inv64|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Iadc, O_Eb, O_Ib, O_NONE, P_c1|P_inv64|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Isbb, O_Eb, O_Ib, O_NONE, P_c1|P_inv64|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Iand, O_Eb, O_Ib, O_NONE, P_c1|P_inv64|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Isub, O_Eb, O_Ib, O_NONE, P_c1|P_inv64|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ixor, O_Eb, O_Ib, O_NONE, P_c1|P_inv64|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Icmp, O_Eb, O_Ib, O_NONE, P_c1|P_inv64|P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_83__reg[8] = {
+ /* 00 */ { UD_Iadd, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Ior, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Iadc, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Isbb, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Iand, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Isub, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ixor, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Icmp, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_8f__reg[8] = {
+ /* 00 */ { UD_Ipop, O_Ev, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_98__osize[3] = {
+ /* 00 */ { UD_Icbw, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+ /* 01 */ { UD_Icwde, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+ /* 02 */ { UD_Icdqe, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+};
+
+static struct ud_itab_entry itab__1byte__op_99__osize[3] = {
+ /* 00 */ { UD_Icwd, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+ /* 01 */ { UD_Icdq, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+ /* 02 */ { UD_Icqo, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+};
+
+static struct ud_itab_entry itab__1byte__op_9c__mode[3] = {
+ /* 00 */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_9C__MODE__OP_00__OSIZE },
+ /* 01 */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_9C__MODE__OP_01__OSIZE },
+ /* 02 */ { UD_Ipushfq, O_NONE, O_NONE, O_NONE, P_def64|P_oso|P_rexw },
+};
+
+static struct ud_itab_entry itab__1byte__op_9c__mode__op_00__osize[3] = {
+ /* 00 */ { UD_Ipushfw, O_NONE, O_NONE, O_NONE, P_def64|P_oso },
+ /* 01 */ { UD_Ipushfd, O_NONE, O_NONE, O_NONE, P_def64|P_oso },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_9c__mode__op_01__osize[3] = {
+ /* 00 */ { UD_Ipushfw, O_NONE, O_NONE, O_NONE, P_def64|P_oso },
+ /* 01 */ { UD_Ipushfd, O_NONE, O_NONE, O_NONE, P_def64|P_oso },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_9d__mode[3] = {
+ /* 00 */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_9D__MODE__OP_00__OSIZE },
+ /* 01 */ { UD_Igrp_osize, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_9D__MODE__OP_01__OSIZE },
+ /* 02 */ { UD_Ipopfq, O_NONE, O_NONE, O_NONE, P_def64|P_depM|P_oso },
+};
+
+static struct ud_itab_entry itab__1byte__op_9d__mode__op_00__osize[3] = {
+ /* 00 */ { UD_Ipopfw, O_NONE, O_NONE, O_NONE, P_def64|P_depM|P_oso },
+ /* 01 */ { UD_Ipopfd, O_NONE, O_NONE, O_NONE, P_def64|P_depM|P_oso },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_9d__mode__op_01__osize[3] = {
+ /* 00 */ { UD_Ipopfw, O_NONE, O_NONE, O_NONE, P_def64|P_depM|P_oso },
+ /* 01 */ { UD_Ipopfd, O_NONE, O_NONE, O_NONE, P_def64|P_depM|P_oso },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_a5__osize[3] = {
+ /* 00 */ { UD_Imovsw, O_NONE, O_NONE, O_NONE, P_ImpAddr|P_oso|P_rexw },
+ /* 01 */ { UD_Imovsd, O_NONE, O_NONE, O_NONE, P_ImpAddr|P_oso|P_rexw },
+ /* 02 */ { UD_Imovsq, O_NONE, O_NONE, O_NONE, P_ImpAddr|P_oso|P_rexw },
+};
+
+static struct ud_itab_entry itab__1byte__op_a7__osize[3] = {
+ /* 00 */ { UD_Icmpsw, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+ /* 01 */ { UD_Icmpsd, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+ /* 02 */ { UD_Icmpsq, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+};
+
+static struct ud_itab_entry itab__1byte__op_ab__osize[3] = {
+ /* 00 */ { UD_Istosw, O_NONE, O_NONE, O_NONE, P_ImpAddr|P_oso|P_rexw },
+ /* 01 */ { UD_Istosd, O_NONE, O_NONE, O_NONE, P_ImpAddr|P_oso|P_rexw },
+ /* 02 */ { UD_Istosq, O_NONE, O_NONE, O_NONE, P_ImpAddr|P_oso|P_rexw },
+};
+
+static struct ud_itab_entry itab__1byte__op_ad__osize[3] = {
+ /* 00 */ { UD_Ilodsw, O_NONE, O_NONE, O_NONE, P_ImpAddr|P_oso|P_rexw },
+ /* 01 */ { UD_Ilodsd, O_NONE, O_NONE, O_NONE, P_ImpAddr|P_oso|P_rexw },
+ /* 02 */ { UD_Ilodsq, O_NONE, O_NONE, O_NONE, P_ImpAddr|P_oso|P_rexw },
+};
+
+static struct ud_itab_entry itab__1byte__op_ae__mod[2] = {
+ /* 00 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_AE__MOD__OP_00__REG },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_ae__mod__op_00__reg[8] = {
+ /* 00 */ { UD_Ifxsave, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Ifxrstor, O_M, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_af__osize[3] = {
+ /* 00 */ { UD_Iscasw, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+ /* 01 */ { UD_Iscasd, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+ /* 02 */ { UD_Iscasq, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+};
+
+static struct ud_itab_entry itab__1byte__op_c0__reg[8] = {
+ /* 00 */ { UD_Irol, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iror, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Ircl, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ircr, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ishl, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ishr, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ishl, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Isar, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_c1__reg[8] = {
+ /* 00 */ { UD_Irol, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iror, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Ircl, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ircr, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ishl, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ishr, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ishl, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Isar, O_Ev, O_Ib, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_c6__reg[8] = {
+ /* 00 */ { UD_Imov, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_c7__reg[8] = {
+ /* 00 */ { UD_Imov, O_Ev, O_Iz, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_cf__osize[3] = {
+ /* 00 */ { UD_Iiretw, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+ /* 01 */ { UD_Iiretd, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+ /* 02 */ { UD_Iiretq, O_NONE, O_NONE, O_NONE, P_oso|P_rexw },
+};
+
+static struct ud_itab_entry itab__1byte__op_d0__reg[8] = {
+ /* 00 */ { UD_Irol, O_Eb, O_I1, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iror, O_Eb, O_I1, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Ircl, O_Eb, O_I1, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ircr, O_Eb, O_I1, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ishl, O_Eb, O_I1, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ishr, O_Eb, O_I1, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ishl, O_Eb, O_I1, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Isar, O_Eb, O_I1, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_d1__reg[8] = {
+ /* 00 */ { UD_Irol, O_Ev, O_I1, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iror, O_Ev, O_I1, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Ircl, O_Ev, O_I1, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ircr, O_Ev, O_I1, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ishl, O_Ev, O_I1, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ishr, O_Ev, O_I1, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ishl, O_Ev, O_I1, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Isar, O_Ev, O_I1, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_d2__reg[8] = {
+ /* 00 */ { UD_Irol, O_Eb, O_CL, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iror, O_Eb, O_CL, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Ircl, O_Eb, O_CL, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ircr, O_Eb, O_CL, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ishl, O_Eb, O_CL, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ishr, O_Eb, O_CL, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ishl, O_Eb, O_CL, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Isar, O_Eb, O_CL, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_d3__reg[8] = {
+ /* 00 */ { UD_Irol, O_Ev, O_CL, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iror, O_Ev, O_CL, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Ircl, O_Ev, O_CL, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ircr, O_Ev, O_CL, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ishl, O_Ev, O_CL, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ishr, O_Ev, O_CL, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ishl, O_Ev, O_CL, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Isar, O_Ev, O_CL, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_d8__mod[2] = {
+ /* 00 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_D8__MOD__OP_00__REG },
+ /* 01 */ { UD_Igrp_x87, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_D8__MOD__OP_01__X87 },
+};
+
+static struct ud_itab_entry itab__1byte__op_d8__mod__op_00__reg[8] = {
+ /* 00 */ { UD_Ifadd, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Ifmul, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Ifcom, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ifcomp, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ifsub, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ifsubr, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ifdiv, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Ifdivr, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_d8__mod__op_01__x87[64] = {
+ /* 00 */ { UD_Ifadd, O_ST0, O_ST0, O_NONE, P_none },
+ /* 01 */ { UD_Ifadd, O_ST0, O_ST1, O_NONE, P_none },
+ /* 02 */ { UD_Ifadd, O_ST0, O_ST2, O_NONE, P_none },
+ /* 03 */ { UD_Ifadd, O_ST0, O_ST3, O_NONE, P_none },
+ /* 04 */ { UD_Ifadd, O_ST0, O_ST4, O_NONE, P_none },
+ /* 05 */ { UD_Ifadd, O_ST0, O_ST5, O_NONE, P_none },
+ /* 06 */ { UD_Ifadd, O_ST0, O_ST6, O_NONE, P_none },
+ /* 07 */ { UD_Ifadd, O_ST0, O_ST7, O_NONE, P_none },
+ /* 08 */ { UD_Ifmul, O_ST0, O_ST0, O_NONE, P_none },
+ /* 09 */ { UD_Ifmul, O_ST0, O_ST1, O_NONE, P_none },
+ /* 0A */ { UD_Ifmul, O_ST0, O_ST2, O_NONE, P_none },
+ /* 0B */ { UD_Ifmul, O_ST0, O_ST3, O_NONE, P_none },
+ /* 0C */ { UD_Ifmul, O_ST0, O_ST4, O_NONE, P_none },
+ /* 0D */ { UD_Ifmul, O_ST0, O_ST5, O_NONE, P_none },
+ /* 0E */ { UD_Ifmul, O_ST0, O_ST6, O_NONE, P_none },
+ /* 0F */ { UD_Ifmul, O_ST0, O_ST7, O_NONE, P_none },
+ /* 10 */ { UD_Ifcom, O_ST0, O_ST0, O_NONE, P_none },
+ /* 11 */ { UD_Ifcom, O_ST0, O_ST1, O_NONE, P_none },
+ /* 12 */ { UD_Ifcom, O_ST0, O_ST2, O_NONE, P_none },
+ /* 13 */ { UD_Ifcom, O_ST0, O_ST3, O_NONE, P_none },
+ /* 14 */ { UD_Ifcom, O_ST0, O_ST4, O_NONE, P_none },
+ /* 15 */ { UD_Ifcom, O_ST0, O_ST5, O_NONE, P_none },
+ /* 16 */ { UD_Ifcom, O_ST0, O_ST6, O_NONE, P_none },
+ /* 17 */ { UD_Ifcom, O_ST0, O_ST7, O_NONE, P_none },
+ /* 18 */ { UD_Ifcomp, O_ST0, O_ST0, O_NONE, P_none },
+ /* 19 */ { UD_Ifcomp, O_ST0, O_ST1, O_NONE, P_none },
+ /* 1A */ { UD_Ifcomp, O_ST0, O_ST2, O_NONE, P_none },
+ /* 1B */ { UD_Ifcomp, O_ST0, O_ST3, O_NONE, P_none },
+ /* 1C */ { UD_Ifcomp, O_ST0, O_ST4, O_NONE, P_none },
+ /* 1D */ { UD_Ifcomp, O_ST0, O_ST5, O_NONE, P_none },
+ /* 1E */ { UD_Ifcomp, O_ST0, O_ST6, O_NONE, P_none },
+ /* 1F */ { UD_Ifcomp, O_ST0, O_ST7, O_NONE, P_none },
+ /* 20 */ { UD_Ifsub, O_ST0, O_ST0, O_NONE, P_none },
+ /* 21 */ { UD_Ifsub, O_ST0, O_ST1, O_NONE, P_none },
+ /* 22 */ { UD_Ifsub, O_ST0, O_ST2, O_NONE, P_none },
+ /* 23 */ { UD_Ifsub, O_ST0, O_ST3, O_NONE, P_none },
+ /* 24 */ { UD_Ifsub, O_ST0, O_ST4, O_NONE, P_none },
+ /* 25 */ { UD_Ifsub, O_ST0, O_ST5, O_NONE, P_none },
+ /* 26 */ { UD_Ifsub, O_ST0, O_ST6, O_NONE, P_none },
+ /* 27 */ { UD_Ifsub, O_ST0, O_ST7, O_NONE, P_none },
+ /* 28 */ { UD_Ifsubr, O_ST0, O_ST0, O_NONE, P_none },
+ /* 29 */ { UD_Ifsubr, O_ST0, O_ST1, O_NONE, P_none },
+ /* 2A */ { UD_Ifsubr, O_ST0, O_ST2, O_NONE, P_none },
+ /* 2B */ { UD_Ifsubr, O_ST0, O_ST3, O_NONE, P_none },
+ /* 2C */ { UD_Ifsubr, O_ST0, O_ST4, O_NONE, P_none },
+ /* 2D */ { UD_Ifsubr, O_ST0, O_ST5, O_NONE, P_none },
+ /* 2E */ { UD_Ifsubr, O_ST0, O_ST6, O_NONE, P_none },
+ /* 2F */ { UD_Ifsubr, O_ST0, O_ST7, O_NONE, P_none },
+ /* 30 */ { UD_Ifdiv, O_ST0, O_ST0, O_NONE, P_none },
+ /* 31 */ { UD_Ifdiv, O_ST0, O_ST1, O_NONE, P_none },
+ /* 32 */ { UD_Ifdiv, O_ST0, O_ST2, O_NONE, P_none },
+ /* 33 */ { UD_Ifdiv, O_ST0, O_ST3, O_NONE, P_none },
+ /* 34 */ { UD_Ifdiv, O_ST0, O_ST4, O_NONE, P_none },
+ /* 35 */ { UD_Ifdiv, O_ST0, O_ST5, O_NONE, P_none },
+ /* 36 */ { UD_Ifdiv, O_ST0, O_ST6, O_NONE, P_none },
+ /* 37 */ { UD_Ifdiv, O_ST0, O_ST7, O_NONE, P_none },
+ /* 38 */ { UD_Ifdivr, O_ST0, O_ST0, O_NONE, P_none },
+ /* 39 */ { UD_Ifdivr, O_ST0, O_ST1, O_NONE, P_none },
+ /* 3A */ { UD_Ifdivr, O_ST0, O_ST2, O_NONE, P_none },
+ /* 3B */ { UD_Ifdivr, O_ST0, O_ST3, O_NONE, P_none },
+ /* 3C */ { UD_Ifdivr, O_ST0, O_ST4, O_NONE, P_none },
+ /* 3D */ { UD_Ifdivr, O_ST0, O_ST5, O_NONE, P_none },
+ /* 3E */ { UD_Ifdivr, O_ST0, O_ST6, O_NONE, P_none },
+ /* 3F */ { UD_Ifdivr, O_ST0, O_ST7, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_d9__mod[2] = {
+ /* 00 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_D9__MOD__OP_00__REG },
+ /* 01 */ { UD_Igrp_x87, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_D9__MOD__OP_01__X87 },
+};
+
+static struct ud_itab_entry itab__1byte__op_d9__mod__op_00__reg[8] = {
+ /* 00 */ { UD_Ifld, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Ifst, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ifstp, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ifldenv, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ifldcw, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ifnstenv, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Ifnstcw, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_d9__mod__op_01__x87[64] = {
+ /* 00 */ { UD_Ifld, O_ST0, O_ST0, O_NONE, P_none },
+ /* 01 */ { UD_Ifld, O_ST0, O_ST1, O_NONE, P_none },
+ /* 02 */ { UD_Ifld, O_ST0, O_ST2, O_NONE, P_none },
+ /* 03 */ { UD_Ifld, O_ST0, O_ST3, O_NONE, P_none },
+ /* 04 */ { UD_Ifld, O_ST0, O_ST4, O_NONE, P_none },
+ /* 05 */ { UD_Ifld, O_ST0, O_ST5, O_NONE, P_none },
+ /* 06 */ { UD_Ifld, O_ST0, O_ST6, O_NONE, P_none },
+ /* 07 */ { UD_Ifld, O_ST0, O_ST7, O_NONE, P_none },
+ /* 08 */ { UD_Ifxch, O_ST0, O_ST0, O_NONE, P_none },
+ /* 09 */ { UD_Ifxch, O_ST0, O_ST1, O_NONE, P_none },
+ /* 0A */ { UD_Ifxch, O_ST0, O_ST2, O_NONE, P_none },
+ /* 0B */ { UD_Ifxch, O_ST0, O_ST3, O_NONE, P_none },
+ /* 0C */ { UD_Ifxch, O_ST0, O_ST4, O_NONE, P_none },
+ /* 0D */ { UD_Ifxch, O_ST0, O_ST5, O_NONE, P_none },
+ /* 0E */ { UD_Ifxch, O_ST0, O_ST6, O_NONE, P_none },
+ /* 0F */ { UD_Ifxch, O_ST0, O_ST7, O_NONE, P_none },
+ /* 10 */ { UD_Ifnop, O_NONE, O_NONE, O_NONE, P_none },
+ /* 11 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 12 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 13 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 14 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 15 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 16 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 17 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 18 */ { UD_Ifstp1, O_ST0, O_NONE, O_NONE, P_none },
+ /* 19 */ { UD_Ifstp1, O_ST1, O_NONE, O_NONE, P_none },
+ /* 1A */ { UD_Ifstp1, O_ST2, O_NONE, O_NONE, P_none },
+ /* 1B */ { UD_Ifstp1, O_ST3, O_NONE, O_NONE, P_none },
+ /* 1C */ { UD_Ifstp1, O_ST4, O_NONE, O_NONE, P_none },
+ /* 1D */ { UD_Ifstp1, O_ST5, O_NONE, O_NONE, P_none },
+ /* 1E */ { UD_Ifstp1, O_ST6, O_NONE, O_NONE, P_none },
+ /* 1F */ { UD_Ifstp1, O_ST7, O_NONE, O_NONE, P_none },
+ /* 20 */ { UD_Ifchs, O_NONE, O_NONE, O_NONE, P_none },
+ /* 21 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 22 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 23 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 24 */ { UD_Iftst, O_NONE, O_NONE, O_NONE, P_none },
+ /* 25 */ { UD_Ifxam, O_NONE, O_NONE, O_NONE, P_none },
+ /* 26 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 27 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 28 */ { UD_Ifld1, O_NONE, O_NONE, O_NONE, P_none },
+ /* 29 */ { UD_Ifldl2t, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2A */ { UD_Ifldl2e, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2B */ { UD_Ifldlpi, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2C */ { UD_Ifldlg2, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2D */ { UD_Ifldln2, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2E */ { UD_Ifldz, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 30 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 31 */ { UD_Ifyl2x, O_NONE, O_NONE, O_NONE, P_none },
+ /* 32 */ { UD_Ifptan, O_NONE, O_NONE, O_NONE, P_none },
+ /* 33 */ { UD_Ifpatan, O_NONE, O_NONE, O_NONE, P_none },
+ /* 34 */ { UD_Ifpxtract, O_NONE, O_NONE, O_NONE, P_none },
+ /* 35 */ { UD_Ifprem1, O_NONE, O_NONE, O_NONE, P_none },
+ /* 36 */ { UD_Ifdecstp, O_NONE, O_NONE, O_NONE, P_none },
+ /* 37 */ { UD_Ifncstp, O_NONE, O_NONE, O_NONE, P_none },
+ /* 38 */ { UD_Ifprem, O_NONE, O_NONE, O_NONE, P_none },
+ /* 39 */ { UD_Ifyl2xp1, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3A */ { UD_Ifsqrt, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3B */ { UD_Ifsincos, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3C */ { UD_Ifrndint, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3D */ { UD_Ifscale, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3E */ { UD_Ifsin, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3F */ { UD_Ifcos, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_da__mod[2] = {
+ /* 00 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DA__MOD__OP_00__REG },
+ /* 01 */ { UD_Igrp_x87, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DA__MOD__OP_01__X87 },
+};
+
+static struct ud_itab_entry itab__1byte__op_da__mod__op_00__reg[8] = {
+ /* 00 */ { UD_Ifiadd, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Ifimul, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Ificom, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ificomp, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ifisub, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ifisubr, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ifidiv, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Ifidivr, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_da__mod__op_01__x87[64] = {
+ /* 00 */ { UD_Ifcmovb, O_ST0, O_ST0, O_NONE, P_none },
+ /* 01 */ { UD_Ifcmovb, O_ST0, O_ST1, O_NONE, P_none },
+ /* 02 */ { UD_Ifcmovb, O_ST0, O_ST2, O_NONE, P_none },
+ /* 03 */ { UD_Ifcmovb, O_ST0, O_ST3, O_NONE, P_none },
+ /* 04 */ { UD_Ifcmovb, O_ST0, O_ST4, O_NONE, P_none },
+ /* 05 */ { UD_Ifcmovb, O_ST0, O_ST5, O_NONE, P_none },
+ /* 06 */ { UD_Ifcmovb, O_ST0, O_ST6, O_NONE, P_none },
+ /* 07 */ { UD_Ifcmovb, O_ST0, O_ST7, O_NONE, P_none },
+ /* 08 */ { UD_Ifcmove, O_ST0, O_ST0, O_NONE, P_none },
+ /* 09 */ { UD_Ifcmove, O_ST0, O_ST1, O_NONE, P_none },
+ /* 0A */ { UD_Ifcmove, O_ST0, O_ST2, O_NONE, P_none },
+ /* 0B */ { UD_Ifcmove, O_ST0, O_ST3, O_NONE, P_none },
+ /* 0C */ { UD_Ifcmove, O_ST0, O_ST4, O_NONE, P_none },
+ /* 0D */ { UD_Ifcmove, O_ST0, O_ST5, O_NONE, P_none },
+ /* 0E */ { UD_Ifcmove, O_ST0, O_ST6, O_NONE, P_none },
+ /* 0F */ { UD_Ifcmove, O_ST0, O_ST7, O_NONE, P_none },
+ /* 10 */ { UD_Ifcmovbe, O_ST0, O_ST0, O_NONE, P_none },
+ /* 11 */ { UD_Ifcmovbe, O_ST0, O_ST1, O_NONE, P_none },
+ /* 12 */ { UD_Ifcmovbe, O_ST0, O_ST2, O_NONE, P_none },
+ /* 13 */ { UD_Ifcmovbe, O_ST0, O_ST3, O_NONE, P_none },
+ /* 14 */ { UD_Ifcmovbe, O_ST0, O_ST4, O_NONE, P_none },
+ /* 15 */ { UD_Ifcmovbe, O_ST0, O_ST5, O_NONE, P_none },
+ /* 16 */ { UD_Ifcmovbe, O_ST0, O_ST6, O_NONE, P_none },
+ /* 17 */ { UD_Ifcmovbe, O_ST0, O_ST7, O_NONE, P_none },
+ /* 18 */ { UD_Ifcmovu, O_ST0, O_ST0, O_NONE, P_none },
+ /* 19 */ { UD_Ifcmovu, O_ST0, O_ST1, O_NONE, P_none },
+ /* 1A */ { UD_Ifcmovu, O_ST0, O_ST2, O_NONE, P_none },
+ /* 1B */ { UD_Ifcmovu, O_ST0, O_ST3, O_NONE, P_none },
+ /* 1C */ { UD_Ifcmovu, O_ST0, O_ST4, O_NONE, P_none },
+ /* 1D */ { UD_Ifcmovu, O_ST0, O_ST5, O_NONE, P_none },
+ /* 1E */ { UD_Ifcmovu, O_ST0, O_ST6, O_NONE, P_none },
+ /* 1F */ { UD_Ifcmovu, O_ST0, O_ST7, O_NONE, P_none },
+ /* 20 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 21 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 22 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 23 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 24 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 25 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 26 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 27 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 28 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 29 */ { UD_Ifucompp, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 30 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 31 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 32 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 33 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 34 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 35 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 36 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 37 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 38 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 39 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_db__mod[2] = {
+ /* 00 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DB__MOD__OP_00__REG },
+ /* 01 */ { UD_Igrp_x87, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DB__MOD__OP_01__X87 },
+};
+
+static struct ud_itab_entry itab__1byte__op_db__mod__op_00__reg[8] = {
+ /* 00 */ { UD_Ifild, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Ifisttp, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Ifist, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ifistp, O_Md, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Ifld, O_Mt, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Ifstp, O_Mt, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_db__mod__op_01__x87[64] = {
+ /* 00 */ { UD_Ifcmovnb, O_ST0, O_ST0, O_NONE, P_none },
+ /* 01 */ { UD_Ifcmovnb, O_ST0, O_ST1, O_NONE, P_none },
+ /* 02 */ { UD_Ifcmovnb, O_ST0, O_ST2, O_NONE, P_none },
+ /* 03 */ { UD_Ifcmovnb, O_ST0, O_ST3, O_NONE, P_none },
+ /* 04 */ { UD_Ifcmovnb, O_ST0, O_ST4, O_NONE, P_none },
+ /* 05 */ { UD_Ifcmovnb, O_ST0, O_ST5, O_NONE, P_none },
+ /* 06 */ { UD_Ifcmovnb, O_ST0, O_ST6, O_NONE, P_none },
+ /* 07 */ { UD_Ifcmovnb, O_ST0, O_ST7, O_NONE, P_none },
+ /* 08 */ { UD_Ifcmovne, O_ST0, O_ST0, O_NONE, P_none },
+ /* 09 */ { UD_Ifcmovne, O_ST0, O_ST1, O_NONE, P_none },
+ /* 0A */ { UD_Ifcmovne, O_ST0, O_ST2, O_NONE, P_none },
+ /* 0B */ { UD_Ifcmovne, O_ST0, O_ST3, O_NONE, P_none },
+ /* 0C */ { UD_Ifcmovne, O_ST0, O_ST4, O_NONE, P_none },
+ /* 0D */ { UD_Ifcmovne, O_ST0, O_ST5, O_NONE, P_none },
+ /* 0E */ { UD_Ifcmovne, O_ST0, O_ST6, O_NONE, P_none },
+ /* 0F */ { UD_Ifcmovne, O_ST0, O_ST7, O_NONE, P_none },
+ /* 10 */ { UD_Ifcmovnbe, O_ST0, O_ST0, O_NONE, P_none },
+ /* 11 */ { UD_Ifcmovnbe, O_ST0, O_ST1, O_NONE, P_none },
+ /* 12 */ { UD_Ifcmovnbe, O_ST0, O_ST2, O_NONE, P_none },
+ /* 13 */ { UD_Ifcmovnbe, O_ST0, O_ST3, O_NONE, P_none },
+ /* 14 */ { UD_Ifcmovnbe, O_ST0, O_ST4, O_NONE, P_none },
+ /* 15 */ { UD_Ifcmovnbe, O_ST0, O_ST5, O_NONE, P_none },
+ /* 16 */ { UD_Ifcmovnbe, O_ST0, O_ST6, O_NONE, P_none },
+ /* 17 */ { UD_Ifcmovnbe, O_ST0, O_ST7, O_NONE, P_none },
+ /* 18 */ { UD_Ifcmovnu, O_ST0, O_ST0, O_NONE, P_none },
+ /* 19 */ { UD_Ifcmovnu, O_ST0, O_ST1, O_NONE, P_none },
+ /* 1A */ { UD_Ifcmovnu, O_ST0, O_ST2, O_NONE, P_none },
+ /* 1B */ { UD_Ifcmovnu, O_ST0, O_ST3, O_NONE, P_none },
+ /* 1C */ { UD_Ifcmovnu, O_ST0, O_ST4, O_NONE, P_none },
+ /* 1D */ { UD_Ifcmovnu, O_ST0, O_ST5, O_NONE, P_none },
+ /* 1E */ { UD_Ifcmovnu, O_ST0, O_ST6, O_NONE, P_none },
+ /* 1F */ { UD_Ifcmovnu, O_ST0, O_ST7, O_NONE, P_none },
+ /* 20 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 21 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 22 */ { UD_Ifclex, O_NONE, O_NONE, O_NONE, P_none },
+ /* 23 */ { UD_Ifninit, O_NONE, O_NONE, O_NONE, P_none },
+ /* 24 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 25 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 26 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 27 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 28 */ { UD_Ifucomi, O_ST0, O_ST0, O_NONE, P_none },
+ /* 29 */ { UD_Ifucomi, O_ST0, O_ST1, O_NONE, P_none },
+ /* 2A */ { UD_Ifucomi, O_ST0, O_ST2, O_NONE, P_none },
+ /* 2B */ { UD_Ifucomi, O_ST0, O_ST3, O_NONE, P_none },
+ /* 2C */ { UD_Ifucomi, O_ST0, O_ST4, O_NONE, P_none },
+ /* 2D */ { UD_Ifucomi, O_ST0, O_ST5, O_NONE, P_none },
+ /* 2E */ { UD_Ifucomi, O_ST0, O_ST6, O_NONE, P_none },
+ /* 2F */ { UD_Ifucomi, O_ST0, O_ST7, O_NONE, P_none },
+ /* 30 */ { UD_Ifcomi, O_ST0, O_ST0, O_NONE, P_none },
+ /* 31 */ { UD_Ifcomi, O_ST0, O_ST1, O_NONE, P_none },
+ /* 32 */ { UD_Ifcomi, O_ST0, O_ST2, O_NONE, P_none },
+ /* 33 */ { UD_Ifcomi, O_ST0, O_ST3, O_NONE, P_none },
+ /* 34 */ { UD_Ifcomi, O_ST0, O_ST4, O_NONE, P_none },
+ /* 35 */ { UD_Ifcomi, O_ST0, O_ST5, O_NONE, P_none },
+ /* 36 */ { UD_Ifcomi, O_ST0, O_ST6, O_NONE, P_none },
+ /* 37 */ { UD_Ifcomi, O_ST0, O_ST7, O_NONE, P_none },
+ /* 38 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 39 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_dc__mod[2] = {
+ /* 00 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DC__MOD__OP_00__REG },
+ /* 01 */ { UD_Igrp_x87, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DC__MOD__OP_01__X87 },
+};
+
+static struct ud_itab_entry itab__1byte__op_dc__mod__op_00__reg[8] = {
+ /* 00 */ { UD_Ifadd, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Ifmul, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Ifcom, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ifcomp, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ifsub, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ifsubr, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ifdiv, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Ifdivr, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_dc__mod__op_01__x87[64] = {
+ /* 00 */ { UD_Ifadd, O_ST0, O_ST0, O_NONE, P_none },
+ /* 01 */ { UD_Ifadd, O_ST1, O_ST0, O_NONE, P_none },
+ /* 02 */ { UD_Ifadd, O_ST2, O_ST0, O_NONE, P_none },
+ /* 03 */ { UD_Ifadd, O_ST3, O_ST0, O_NONE, P_none },
+ /* 04 */ { UD_Ifadd, O_ST4, O_ST0, O_NONE, P_none },
+ /* 05 */ { UD_Ifadd, O_ST5, O_ST0, O_NONE, P_none },
+ /* 06 */ { UD_Ifadd, O_ST6, O_ST0, O_NONE, P_none },
+ /* 07 */ { UD_Ifadd, O_ST7, O_ST0, O_NONE, P_none },
+ /* 08 */ { UD_Ifmul, O_ST0, O_ST0, O_NONE, P_none },
+ /* 09 */ { UD_Ifmul, O_ST1, O_ST0, O_NONE, P_none },
+ /* 0A */ { UD_Ifmul, O_ST2, O_ST0, O_NONE, P_none },
+ /* 0B */ { UD_Ifmul, O_ST3, O_ST0, O_NONE, P_none },
+ /* 0C */ { UD_Ifmul, O_ST4, O_ST0, O_NONE, P_none },
+ /* 0D */ { UD_Ifmul, O_ST5, O_ST0, O_NONE, P_none },
+ /* 0E */ { UD_Ifmul, O_ST6, O_ST0, O_NONE, P_none },
+ /* 0F */ { UD_Ifmul, O_ST7, O_ST0, O_NONE, P_none },
+ /* 10 */ { UD_Ifcom2, O_ST0, O_NONE, O_NONE, P_none },
+ /* 11 */ { UD_Ifcom2, O_ST1, O_NONE, O_NONE, P_none },
+ /* 12 */ { UD_Ifcom2, O_ST2, O_NONE, O_NONE, P_none },
+ /* 13 */ { UD_Ifcom2, O_ST3, O_NONE, O_NONE, P_none },
+ /* 14 */ { UD_Ifcom2, O_ST4, O_NONE, O_NONE, P_none },
+ /* 15 */ { UD_Ifcom2, O_ST5, O_NONE, O_NONE, P_none },
+ /* 16 */ { UD_Ifcom2, O_ST6, O_NONE, O_NONE, P_none },
+ /* 17 */ { UD_Ifcom2, O_ST7, O_NONE, O_NONE, P_none },
+ /* 18 */ { UD_Ifcomp3, O_ST0, O_NONE, O_NONE, P_none },
+ /* 19 */ { UD_Ifcomp3, O_ST1, O_NONE, O_NONE, P_none },
+ /* 1A */ { UD_Ifcomp3, O_ST2, O_NONE, O_NONE, P_none },
+ /* 1B */ { UD_Ifcomp3, O_ST3, O_NONE, O_NONE, P_none },
+ /* 1C */ { UD_Ifcomp3, O_ST4, O_NONE, O_NONE, P_none },
+ /* 1D */ { UD_Ifcomp3, O_ST5, O_NONE, O_NONE, P_none },
+ /* 1E */ { UD_Ifcomp3, O_ST6, O_NONE, O_NONE, P_none },
+ /* 1F */ { UD_Ifcomp3, O_ST7, O_NONE, O_NONE, P_none },
+ /* 20 */ { UD_Ifsubr, O_ST0, O_ST0, O_NONE, P_none },
+ /* 21 */ { UD_Ifsubr, O_ST1, O_ST0, O_NONE, P_none },
+ /* 22 */ { UD_Ifsubr, O_ST2, O_ST0, O_NONE, P_none },
+ /* 23 */ { UD_Ifsubr, O_ST3, O_ST0, O_NONE, P_none },
+ /* 24 */ { UD_Ifsubr, O_ST4, O_ST0, O_NONE, P_none },
+ /* 25 */ { UD_Ifsubr, O_ST5, O_ST0, O_NONE, P_none },
+ /* 26 */ { UD_Ifsubr, O_ST6, O_ST0, O_NONE, P_none },
+ /* 27 */ { UD_Ifsubr, O_ST7, O_ST0, O_NONE, P_none },
+ /* 28 */ { UD_Ifsub, O_ST0, O_ST0, O_NONE, P_none },
+ /* 29 */ { UD_Ifsub, O_ST1, O_ST0, O_NONE, P_none },
+ /* 2A */ { UD_Ifsub, O_ST2, O_ST0, O_NONE, P_none },
+ /* 2B */ { UD_Ifsub, O_ST3, O_ST0, O_NONE, P_none },
+ /* 2C */ { UD_Ifsub, O_ST4, O_ST0, O_NONE, P_none },
+ /* 2D */ { UD_Ifsub, O_ST5, O_ST0, O_NONE, P_none },
+ /* 2E */ { UD_Ifsub, O_ST6, O_ST0, O_NONE, P_none },
+ /* 2F */ { UD_Ifsub, O_ST7, O_ST0, O_NONE, P_none },
+ /* 30 */ { UD_Ifdivr, O_ST0, O_ST0, O_NONE, P_none },
+ /* 31 */ { UD_Ifdivr, O_ST1, O_ST0, O_NONE, P_none },
+ /* 32 */ { UD_Ifdivr, O_ST2, O_ST0, O_NONE, P_none },
+ /* 33 */ { UD_Ifdivr, O_ST3, O_ST0, O_NONE, P_none },
+ /* 34 */ { UD_Ifdivr, O_ST4, O_ST0, O_NONE, P_none },
+ /* 35 */ { UD_Ifdivr, O_ST5, O_ST0, O_NONE, P_none },
+ /* 36 */ { UD_Ifdivr, O_ST6, O_ST0, O_NONE, P_none },
+ /* 37 */ { UD_Ifdivr, O_ST7, O_ST0, O_NONE, P_none },
+ /* 38 */ { UD_Ifdiv, O_ST0, O_ST0, O_NONE, P_none },
+ /* 39 */ { UD_Ifdiv, O_ST1, O_ST0, O_NONE, P_none },
+ /* 3A */ { UD_Ifdiv, O_ST2, O_ST0, O_NONE, P_none },
+ /* 3B */ { UD_Ifdiv, O_ST3, O_ST0, O_NONE, P_none },
+ /* 3C */ { UD_Ifdiv, O_ST4, O_ST0, O_NONE, P_none },
+ /* 3D */ { UD_Ifdiv, O_ST5, O_ST0, O_NONE, P_none },
+ /* 3E */ { UD_Ifdiv, O_ST6, O_ST0, O_NONE, P_none },
+ /* 3F */ { UD_Ifdiv, O_ST7, O_ST0, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_dd__mod[2] = {
+ /* 00 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DD__MOD__OP_00__REG },
+ /* 01 */ { UD_Igrp_x87, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DD__MOD__OP_01__X87 },
+};
+
+static struct ud_itab_entry itab__1byte__op_dd__mod__op_00__reg[8] = {
+ /* 00 */ { UD_Ifld, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Ifisttp, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Ifst, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ifstp, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ifrstor, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Ifnsave, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Ifnstsw, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_dd__mod__op_01__x87[64] = {
+ /* 00 */ { UD_Iffree, O_ST0, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iffree, O_ST1, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iffree, O_ST2, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iffree, O_ST3, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iffree, O_ST4, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iffree, O_ST5, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iffree, O_ST6, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iffree, O_ST7, O_NONE, O_NONE, P_none },
+ /* 08 */ { UD_Ifxch4, O_ST0, O_NONE, O_NONE, P_none },
+ /* 09 */ { UD_Ifxch4, O_ST1, O_NONE, O_NONE, P_none },
+ /* 0A */ { UD_Ifxch4, O_ST2, O_NONE, O_NONE, P_none },
+ /* 0B */ { UD_Ifxch4, O_ST3, O_NONE, O_NONE, P_none },
+ /* 0C */ { UD_Ifxch4, O_ST4, O_NONE, O_NONE, P_none },
+ /* 0D */ { UD_Ifxch4, O_ST5, O_NONE, O_NONE, P_none },
+ /* 0E */ { UD_Ifxch4, O_ST6, O_NONE, O_NONE, P_none },
+ /* 0F */ { UD_Ifxch4, O_ST7, O_NONE, O_NONE, P_none },
+ /* 10 */ { UD_Ifst, O_ST0, O_NONE, O_NONE, P_none },
+ /* 11 */ { UD_Ifst, O_ST1, O_NONE, O_NONE, P_none },
+ /* 12 */ { UD_Ifst, O_ST2, O_NONE, O_NONE, P_none },
+ /* 13 */ { UD_Ifst, O_ST3, O_NONE, O_NONE, P_none },
+ /* 14 */ { UD_Ifst, O_ST4, O_NONE, O_NONE, P_none },
+ /* 15 */ { UD_Ifst, O_ST5, O_NONE, O_NONE, P_none },
+ /* 16 */ { UD_Ifst, O_ST6, O_NONE, O_NONE, P_none },
+ /* 17 */ { UD_Ifst, O_ST7, O_NONE, O_NONE, P_none },
+ /* 18 */ { UD_Ifstp, O_ST0, O_NONE, O_NONE, P_none },
+ /* 19 */ { UD_Ifstp, O_ST1, O_NONE, O_NONE, P_none },
+ /* 1A */ { UD_Ifstp, O_ST2, O_NONE, O_NONE, P_none },
+ /* 1B */ { UD_Ifstp, O_ST3, O_NONE, O_NONE, P_none },
+ /* 1C */ { UD_Ifstp, O_ST4, O_NONE, O_NONE, P_none },
+ /* 1D */ { UD_Ifstp, O_ST5, O_NONE, O_NONE, P_none },
+ /* 1E */ { UD_Ifstp, O_ST6, O_NONE, O_NONE, P_none },
+ /* 1F */ { UD_Ifstp, O_ST7, O_NONE, O_NONE, P_none },
+ /* 20 */ { UD_Ifucom, O_ST0, O_NONE, O_NONE, P_none },
+ /* 21 */ { UD_Ifucom, O_ST1, O_NONE, O_NONE, P_none },
+ /* 22 */ { UD_Ifucom, O_ST2, O_NONE, O_NONE, P_none },
+ /* 23 */ { UD_Ifucom, O_ST3, O_NONE, O_NONE, P_none },
+ /* 24 */ { UD_Ifucom, O_ST4, O_NONE, O_NONE, P_none },
+ /* 25 */ { UD_Ifucom, O_ST5, O_NONE, O_NONE, P_none },
+ /* 26 */ { UD_Ifucom, O_ST6, O_NONE, O_NONE, P_none },
+ /* 27 */ { UD_Ifucom, O_ST7, O_NONE, O_NONE, P_none },
+ /* 28 */ { UD_Ifucomp, O_ST0, O_NONE, O_NONE, P_none },
+ /* 29 */ { UD_Ifucomp, O_ST1, O_NONE, O_NONE, P_none },
+ /* 2A */ { UD_Ifucomp, O_ST2, O_NONE, O_NONE, P_none },
+ /* 2B */ { UD_Ifucomp, O_ST3, O_NONE, O_NONE, P_none },
+ /* 2C */ { UD_Ifucomp, O_ST4, O_NONE, O_NONE, P_none },
+ /* 2D */ { UD_Ifucomp, O_ST5, O_NONE, O_NONE, P_none },
+ /* 2E */ { UD_Ifucomp, O_ST6, O_NONE, O_NONE, P_none },
+ /* 2F */ { UD_Ifucomp, O_ST7, O_NONE, O_NONE, P_none },
+ /* 30 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 31 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 32 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 33 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 34 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 35 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 36 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 37 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 38 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 39 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_de__mod[2] = {
+ /* 00 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DE__MOD__OP_00__REG },
+ /* 01 */ { UD_Igrp_x87, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DE__MOD__OP_01__X87 },
+};
+
+static struct ud_itab_entry itab__1byte__op_de__mod__op_00__reg[8] = {
+ /* 00 */ { UD_Ifiadd, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Ifimul, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Ificom, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ificomp, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ifisub, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ifisubr, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ifidiv, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Ifidivr, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_de__mod__op_01__x87[64] = {
+ /* 00 */ { UD_Ifaddp, O_ST0, O_ST0, O_NONE, P_none },
+ /* 01 */ { UD_Ifaddp, O_ST1, O_ST0, O_NONE, P_none },
+ /* 02 */ { UD_Ifaddp, O_ST2, O_ST0, O_NONE, P_none },
+ /* 03 */ { UD_Ifaddp, O_ST3, O_ST0, O_NONE, P_none },
+ /* 04 */ { UD_Ifaddp, O_ST4, O_ST0, O_NONE, P_none },
+ /* 05 */ { UD_Ifaddp, O_ST5, O_ST0, O_NONE, P_none },
+ /* 06 */ { UD_Ifaddp, O_ST6, O_ST0, O_NONE, P_none },
+ /* 07 */ { UD_Ifaddp, O_ST7, O_ST0, O_NONE, P_none },
+ /* 08 */ { UD_Ifmulp, O_ST0, O_ST0, O_NONE, P_none },
+ /* 09 */ { UD_Ifmulp, O_ST1, O_ST0, O_NONE, P_none },
+ /* 0A */ { UD_Ifmulp, O_ST2, O_ST0, O_NONE, P_none },
+ /* 0B */ { UD_Ifmulp, O_ST3, O_ST0, O_NONE, P_none },
+ /* 0C */ { UD_Ifmulp, O_ST4, O_ST0, O_NONE, P_none },
+ /* 0D */ { UD_Ifmulp, O_ST5, O_ST0, O_NONE, P_none },
+ /* 0E */ { UD_Ifmulp, O_ST6, O_ST0, O_NONE, P_none },
+ /* 0F */ { UD_Ifmulp, O_ST7, O_ST0, O_NONE, P_none },
+ /* 10 */ { UD_Ifcomp5, O_ST0, O_NONE, O_NONE, P_none },
+ /* 11 */ { UD_Ifcomp5, O_ST1, O_NONE, O_NONE, P_none },
+ /* 12 */ { UD_Ifcomp5, O_ST2, O_NONE, O_NONE, P_none },
+ /* 13 */ { UD_Ifcomp5, O_ST3, O_NONE, O_NONE, P_none },
+ /* 14 */ { UD_Ifcomp5, O_ST4, O_NONE, O_NONE, P_none },
+ /* 15 */ { UD_Ifcomp5, O_ST5, O_NONE, O_NONE, P_none },
+ /* 16 */ { UD_Ifcomp5, O_ST6, O_NONE, O_NONE, P_none },
+ /* 17 */ { UD_Ifcomp5, O_ST7, O_NONE, O_NONE, P_none },
+ /* 18 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 19 */ { UD_Ifcompp, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 20 */ { UD_Ifsubrp, O_ST0, O_ST0, O_NONE, P_none },
+ /* 21 */ { UD_Ifsubrp, O_ST1, O_ST0, O_NONE, P_none },
+ /* 22 */ { UD_Ifsubrp, O_ST2, O_ST0, O_NONE, P_none },
+ /* 23 */ { UD_Ifsubrp, O_ST3, O_ST0, O_NONE, P_none },
+ /* 24 */ { UD_Ifsubrp, O_ST4, O_ST0, O_NONE, P_none },
+ /* 25 */ { UD_Ifsubrp, O_ST5, O_ST0, O_NONE, P_none },
+ /* 26 */ { UD_Ifsubrp, O_ST6, O_ST0, O_NONE, P_none },
+ /* 27 */ { UD_Ifsubrp, O_ST7, O_ST0, O_NONE, P_none },
+ /* 28 */ { UD_Ifsubp, O_ST0, O_ST0, O_NONE, P_none },
+ /* 29 */ { UD_Ifsubp, O_ST1, O_ST0, O_NONE, P_none },
+ /* 2A */ { UD_Ifsubp, O_ST2, O_ST0, O_NONE, P_none },
+ /* 2B */ { UD_Ifsubp, O_ST3, O_ST0, O_NONE, P_none },
+ /* 2C */ { UD_Ifsubp, O_ST4, O_ST0, O_NONE, P_none },
+ /* 2D */ { UD_Ifsubp, O_ST5, O_ST0, O_NONE, P_none },
+ /* 2E */ { UD_Ifsubp, O_ST6, O_ST0, O_NONE, P_none },
+ /* 2F */ { UD_Ifsubp, O_ST7, O_ST0, O_NONE, P_none },
+ /* 30 */ { UD_Ifdivrp, O_ST0, O_ST0, O_NONE, P_none },
+ /* 31 */ { UD_Ifdivrp, O_ST1, O_ST0, O_NONE, P_none },
+ /* 32 */ { UD_Ifdivrp, O_ST2, O_ST0, O_NONE, P_none },
+ /* 33 */ { UD_Ifdivrp, O_ST3, O_ST0, O_NONE, P_none },
+ /* 34 */ { UD_Ifdivrp, O_ST4, O_ST0, O_NONE, P_none },
+ /* 35 */ { UD_Ifdivrp, O_ST5, O_ST0, O_NONE, P_none },
+ /* 36 */ { UD_Ifdivrp, O_ST6, O_ST0, O_NONE, P_none },
+ /* 37 */ { UD_Ifdivrp, O_ST7, O_ST0, O_NONE, P_none },
+ /* 38 */ { UD_Ifdivp, O_ST0, O_ST0, O_NONE, P_none },
+ /* 39 */ { UD_Ifdivp, O_ST1, O_ST0, O_NONE, P_none },
+ /* 3A */ { UD_Ifdivp, O_ST2, O_ST0, O_NONE, P_none },
+ /* 3B */ { UD_Ifdivp, O_ST3, O_ST0, O_NONE, P_none },
+ /* 3C */ { UD_Ifdivp, O_ST4, O_ST0, O_NONE, P_none },
+ /* 3D */ { UD_Ifdivp, O_ST5, O_ST0, O_NONE, P_none },
+ /* 3E */ { UD_Ifdivp, O_ST6, O_ST0, O_NONE, P_none },
+ /* 3F */ { UD_Ifdivp, O_ST7, O_ST0, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_df__mod[2] = {
+ /* 00 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DF__MOD__OP_00__REG },
+ /* 01 */ { UD_Igrp_x87, O_NONE, O_NONE, O_NONE, ITAB__1BYTE__OP_DF__MOD__OP_01__X87 },
+};
+
+static struct ud_itab_entry itab__1byte__op_df__mod__op_00__reg[8] = {
+ /* 00 */ { UD_Ifild, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Ifisttp, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Ifist, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ifistp, O_Mw, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ifbld, O_Mt, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ifild, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ifbstp, O_Mt, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Ifistp, O_Mq, O_NONE, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_df__mod__op_01__x87[64] = {
+ /* 00 */ { UD_Iffreep, O_ST0, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iffreep, O_ST1, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iffreep, O_ST2, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iffreep, O_ST3, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iffreep, O_ST4, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iffreep, O_ST5, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iffreep, O_ST6, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iffreep, O_ST7, O_NONE, O_NONE, P_none },
+ /* 08 */ { UD_Ifxch7, O_ST0, O_NONE, O_NONE, P_none },
+ /* 09 */ { UD_Ifxch7, O_ST1, O_NONE, O_NONE, P_none },
+ /* 0A */ { UD_Ifxch7, O_ST2, O_NONE, O_NONE, P_none },
+ /* 0B */ { UD_Ifxch7, O_ST3, O_NONE, O_NONE, P_none },
+ /* 0C */ { UD_Ifxch7, O_ST4, O_NONE, O_NONE, P_none },
+ /* 0D */ { UD_Ifxch7, O_ST5, O_NONE, O_NONE, P_none },
+ /* 0E */ { UD_Ifxch7, O_ST6, O_NONE, O_NONE, P_none },
+ /* 0F */ { UD_Ifxch7, O_ST7, O_NONE, O_NONE, P_none },
+ /* 10 */ { UD_Ifstp8, O_ST0, O_NONE, O_NONE, P_none },
+ /* 11 */ { UD_Ifstp8, O_ST1, O_NONE, O_NONE, P_none },
+ /* 12 */ { UD_Ifstp8, O_ST2, O_NONE, O_NONE, P_none },
+ /* 13 */ { UD_Ifstp8, O_ST3, O_NONE, O_NONE, P_none },
+ /* 14 */ { UD_Ifstp8, O_ST4, O_NONE, O_NONE, P_none },
+ /* 15 */ { UD_Ifstp8, O_ST5, O_NONE, O_NONE, P_none },
+ /* 16 */ { UD_Ifstp8, O_ST6, O_NONE, O_NONE, P_none },
+ /* 17 */ { UD_Ifstp8, O_ST7, O_NONE, O_NONE, P_none },
+ /* 18 */ { UD_Ifstp9, O_ST0, O_NONE, O_NONE, P_none },
+ /* 19 */ { UD_Ifstp9, O_ST1, O_NONE, O_NONE, P_none },
+ /* 1A */ { UD_Ifstp9, O_ST2, O_NONE, O_NONE, P_none },
+ /* 1B */ { UD_Ifstp9, O_ST3, O_NONE, O_NONE, P_none },
+ /* 1C */ { UD_Ifstp9, O_ST4, O_NONE, O_NONE, P_none },
+ /* 1D */ { UD_Ifstp9, O_ST5, O_NONE, O_NONE, P_none },
+ /* 1E */ { UD_Ifstp9, O_ST6, O_NONE, O_NONE, P_none },
+ /* 1F */ { UD_Ifstp9, O_ST7, O_NONE, O_NONE, P_none },
+ /* 20 */ { UD_Ifnstsw, O_AX, O_NONE, O_NONE, P_none },
+ /* 21 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 22 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 23 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 24 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 25 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 26 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 27 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 28 */ { UD_Ifucomip, O_ST0, O_ST0, O_NONE, P_none },
+ /* 29 */ { UD_Ifucomip, O_ST0, O_ST1, O_NONE, P_none },
+ /* 2A */ { UD_Ifucomip, O_ST0, O_ST2, O_NONE, P_none },
+ /* 2B */ { UD_Ifucomip, O_ST0, O_ST3, O_NONE, P_none },
+ /* 2C */ { UD_Ifucomip, O_ST0, O_ST4, O_NONE, P_none },
+ /* 2D */ { UD_Ifucomip, O_ST0, O_ST5, O_NONE, P_none },
+ /* 2E */ { UD_Ifucomip, O_ST0, O_ST6, O_NONE, P_none },
+ /* 2F */ { UD_Ifucomip, O_ST0, O_ST7, O_NONE, P_none },
+ /* 30 */ { UD_Ifcomip, O_ST0, O_ST0, O_NONE, P_none },
+ /* 31 */ { UD_Ifcomip, O_ST0, O_ST1, O_NONE, P_none },
+ /* 32 */ { UD_Ifcomip, O_ST0, O_ST2, O_NONE, P_none },
+ /* 33 */ { UD_Ifcomip, O_ST0, O_ST3, O_NONE, P_none },
+ /* 34 */ { UD_Ifcomip, O_ST0, O_ST4, O_NONE, P_none },
+ /* 35 */ { UD_Ifcomip, O_ST0, O_ST5, O_NONE, P_none },
+ /* 36 */ { UD_Ifcomip, O_ST0, O_ST6, O_NONE, P_none },
+ /* 37 */ { UD_Ifcomip, O_ST0, O_ST7, O_NONE, P_none },
+ /* 38 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 39 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_e3__asize[3] = {
+ /* 00 */ { UD_Ijcxz, O_Jb, O_NONE, O_NONE, P_aso },
+ /* 01 */ { UD_Ijecxz, O_Jb, O_NONE, O_NONE, P_aso },
+ /* 02 */ { UD_Ijrcxz, O_Jb, O_NONE, O_NONE, P_aso },
+};
+
+static struct ud_itab_entry itab__1byte__op_f6__reg[8] = {
+ /* 00 */ { UD_Itest, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Itest, O_Eb, O_Ib, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Inot, O_Eb, O_NONE, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ineg, O_Eb, O_NONE, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Imul, O_Eb, O_NONE, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Iimul, O_Eb, O_NONE, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Idiv, O_Eb, O_NONE, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Iidiv, O_Eb, O_NONE, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_f7__reg[8] = {
+ /* 00 */ { UD_Itest, O_Ev, O_Iz, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Itest, O_Ev, O_Iz, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Inot, O_Ev, O_NONE, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Ineg, O_Ev, O_NONE, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Imul, O_Ev, O_NONE, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Iimul, O_Ev, O_NONE, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Idiv, O_Ev, O_NONE, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Iidiv, O_Ev, O_NONE, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__1byte__op_fe__reg[8] = {
+ /* 00 */ { UD_Iinc, O_Eb, O_NONE, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Idec, O_Eb, O_NONE, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__1byte__op_ff__reg[8] = {
+ /* 00 */ { UD_Iinc, O_Ev, O_NONE, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 01 */ { UD_Idec, O_Ev, O_NONE, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 02 */ { UD_Icall, O_Ev, O_NONE, O_NONE, P_c1|P_def64|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 03 */ { UD_Icall, O_Ep, O_NONE, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 04 */ { UD_Ijmp, O_Ev, O_NONE, O_NONE, P_c1|P_def64|P_depM|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 05 */ { UD_Ijmp, O_Ep, O_NONE, O_NONE, P_c1|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 06 */ { UD_Ipush, O_Ev, O_NONE, O_NONE, P_c1|P_def64|P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__3dnow[256] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 08 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 09 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 10 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 11 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 12 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 13 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 14 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 15 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 16 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 17 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 18 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 19 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 20 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 21 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 22 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 23 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 24 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 25 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 26 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 27 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 28 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 29 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 30 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 31 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 32 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 33 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 34 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 35 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 36 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 37 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 38 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 39 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 40 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 41 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 42 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 43 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 44 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 45 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 46 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 47 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 48 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 49 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 50 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 51 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 52 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 53 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 54 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 55 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 56 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 57 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 58 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 59 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 5A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 5B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 5C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 5D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 5E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 5F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 60 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 61 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 62 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 63 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 64 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 65 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 66 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 67 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 68 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 69 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 70 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 71 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 72 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 73 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 74 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 75 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 76 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 77 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 78 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 79 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 80 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 81 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 82 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 83 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 84 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 85 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 86 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 87 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 88 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 89 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 90 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 91 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 92 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 93 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 94 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 95 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 96 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 97 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 98 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 99 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* ED */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__pfx_sse66__0f[256] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 08 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 09 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 10 */ { UD_Imovupd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 11 */ { UD_Imovupd, O_W, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 12 */ { UD_Imovlpd, O_V, O_M, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 13 */ { UD_Imovlpd, O_M, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 14 */ { UD_Iunpcklpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 15 */ { UD_Iunpckhpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 16 */ { UD_Imovhpd, O_V, O_M, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 17 */ { UD_Imovhpd, O_M, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 18 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 19 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 20 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 21 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 22 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 23 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 24 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 25 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 26 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 27 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 28 */ { UD_Imovapd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 29 */ { UD_Imovapd, O_W, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2A */ { UD_Icvtpi2pd, O_V, O_Q, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2B */ { UD_Imovntpd, O_M, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2C */ { UD_Icvttpd2pi, O_P, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2D */ { UD_Icvtpd2pi, O_P, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2E */ { UD_Iucomisd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2F */ { UD_Icomisd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 30 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 31 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 32 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 33 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 34 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 35 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 36 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 37 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 38 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 39 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 40 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 41 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 42 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 43 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 44 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 45 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 46 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 47 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 48 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 49 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 50 */ { UD_Imovmskpd, O_Gd, O_VR, O_NONE, P_oso|P_rexr|P_rexb },
+ /* 51 */ { UD_Isqrtpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 52 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 53 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 54 */ { UD_Iandpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 55 */ { UD_Iandnpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 56 */ { UD_Iorpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 57 */ { UD_Ixorpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 58 */ { UD_Iaddpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 59 */ { UD_Imulpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5A */ { UD_Icvtpd2ps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5B */ { UD_Icvtps2dq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5C */ { UD_Isubpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5D */ { UD_Iminpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5E */ { UD_Idivpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5F */ { UD_Imaxpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 60 */ { UD_Ipunpcklbw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 61 */ { UD_Ipunpcklwd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 62 */ { UD_Ipunpckldq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 63 */ { UD_Ipacksswb, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 64 */ { UD_Ipcmpgtb, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 65 */ { UD_Ipcmpgtw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 66 */ { UD_Ipcmpgtd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 67 */ { UD_Ipackuswb, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 68 */ { UD_Ipunpckhbw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 69 */ { UD_Ipunpckhwd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 6A */ { UD_Ipunpckhdq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 6B */ { UD_Ipackssdw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 6C */ { UD_Ipunpcklqdq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 6D */ { UD_Ipunpckhqdq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 6E */ { UD_Imovd, O_V, O_Ex, O_NONE, P_c2|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 6F */ { UD_Imovqa, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 70 */ { UD_Ipshufd, O_V, O_W, O_Ib, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 71 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__PFX_SSE66__0F__OP_71__REG },
+ /* 72 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__PFX_SSE66__0F__OP_72__REG },
+ /* 73 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__PFX_SSE66__0F__OP_73__REG },
+ /* 74 */ { UD_Ipcmpeqb, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 75 */ { UD_Ipcmpeqw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 76 */ { UD_Ipcmpeqd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 77 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 78 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 79 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7C */ { UD_Ihaddpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 7D */ { UD_Ihsubpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 7E */ { UD_Imovd, O_Ex, O_V, O_NONE, P_c1|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 7F */ { UD_Imovdqa, O_W, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 80 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 81 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 82 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 83 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 84 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 85 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 86 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 87 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 88 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 89 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 90 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 91 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 92 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 93 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 94 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 95 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 96 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 97 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 98 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 99 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C0 */ { UD_Ixadd, O_Eb, O_Gb, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* C1 */ { UD_Ixadd, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* C2 */ { UD_Icmppd, O_V, O_W, O_Ib, P_aso|P_rexr|P_rexx|P_rexb },
+ /* C3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C4 */ { UD_Ipinsrw, O_V, O_Ew, O_Ib, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* C5 */ { UD_Ipextrw, O_Gd, O_VR, O_Ib, P_aso|P_rexr|P_rexb },
+ /* C6 */ { UD_Ishufpd, O_V, O_W, O_Ib, P_aso|P_rexr|P_rexx|P_rexb },
+ /* C7 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__PFX_SSE66__0F__OP_C7__REG },
+ /* C8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D0 */ { UD_Iaddsubpd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D1 */ { UD_Ipsrlw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D2 */ { UD_Ipsrld, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D3 */ { UD_Ipsrlq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D4 */ { UD_Ipaddq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D5 */ { UD_Ipmullw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D6 */ { UD_Imovq, O_W, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D7 */ { UD_Ipmovmskb, O_Gd, O_VR, O_NONE, P_rexr|P_rexb },
+ /* D8 */ { UD_Ipsubusb, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D9 */ { UD_Ipsubusw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* DA */ { UD_Ipminub, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* DB */ { UD_Ipand, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* DC */ { UD_Ipsubusb, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* DD */ { UD_Ipunpckhbw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* DE */ { UD_Ipmaxub, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* DF */ { UD_Ipandn, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E0 */ { UD_Ipavgb, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E1 */ { UD_Ipsraw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E2 */ { UD_Ipsrad, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E3 */ { UD_Ipavgw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E4 */ { UD_Ipmulhuw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E5 */ { UD_Ipmulhw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E6 */ { UD_Icvttpd2dq, O_V, O_W, O_NONE, P_none },
+ /* E7 */ { UD_Imovntdq, O_M, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E8 */ { UD_Ipsubsb, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E9 */ { UD_Ipsubsw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* EA */ { UD_Ipminsw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* EB */ { UD_Ipor, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* EC */ { UD_Ipaddsb, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* ED */ { UD_Ipaddsw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* EE */ { UD_Ipmaxsw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* EF */ { UD_Ipxor, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F1 */ { UD_Ipsllw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F2 */ { UD_Ipslld, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F3 */ { UD_Ipsllq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F4 */ { UD_Ipmuludq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F5 */ { UD_Ipmaddwd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F6 */ { UD_Ipsadbw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F7 */ { UD_Imaskmovq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F8 */ { UD_Ipsubb, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F9 */ { UD_Ipsubw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* FA */ { UD_Ipsubd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* FB */ { UD_Ipsubq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* FC */ { UD_Ipaddb, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* FD */ { UD_Ipaddw, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* FE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__pfx_sse66__0f__op_71__reg[8] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Ipsrlw, O_VR, O_Ib, O_NONE, P_rexb },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Ipsraw, O_VR, O_Ib, O_NONE, P_rexb },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Ipsllw, O_VR, O_Ib, O_NONE, P_rexb },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__pfx_sse66__0f__op_72__reg[8] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Ipsrld, O_VR, O_Ib, O_NONE, P_rexb },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Ipsrad, O_VR, O_Ib, O_NONE, P_rexb },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Ipslld, O_VR, O_Ib, O_NONE, P_rexb },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__pfx_sse66__0f__op_73__reg[8] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Ipsrlq, O_VR, O_Ib, O_NONE, P_rexb },
+ /* 03 */ { UD_Ipsrldq, O_VR, O_Ib, O_NONE, P_rexb },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Ipsllq, O_VR, O_Ib, O_NONE, P_rexb },
+ /* 07 */ { UD_Ipslldq, O_VR, O_Ib, O_NONE, P_rexb },
+};
+
+static struct ud_itab_entry itab__pfx_sse66__0f__op_c7__reg[8] = {
+ /* 00 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__PFX_SSE66__0F__OP_C7__REG__OP_00__VENDOR },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__pfx_sse66__0f__op_c7__reg__op_00__vendor[2] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Ivmclear, O_Mq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+static struct ud_itab_entry itab__pfx_ssef2__0f[256] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 08 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 09 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 10 */ { UD_Imovsd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 11 */ { UD_Imovsd, O_W, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 12 */ { UD_Imovddup, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 13 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 14 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 15 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 16 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 17 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 18 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 19 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 20 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 21 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 22 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 23 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 24 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 25 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 26 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 27 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 28 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 29 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2A */ { UD_Icvtsi2sd, O_V, O_Ex, O_NONE, P_c2|P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* 2B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2C */ { UD_Icvttsd2si, O_Gvw, O_W, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2D */ { UD_Icvtsd2si, O_Gvw, O_W, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 30 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 31 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 32 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 33 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 34 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 35 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 36 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 37 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 38 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 39 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 40 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 41 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 42 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 43 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 44 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 45 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 46 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 47 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 48 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 49 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 50 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 51 */ { UD_Isqrtsd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 52 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 53 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 54 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 55 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 56 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 57 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 58 */ { UD_Iaddsd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 59 */ { UD_Imulsd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5A */ { UD_Icvtsd2ss, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 5C */ { UD_Isubsd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5D */ { UD_Iminsd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5E */ { UD_Idivsd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5F */ { UD_Imaxsd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 60 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 61 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 62 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 63 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 64 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 65 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 66 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 67 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 68 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 69 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 70 */ { UD_Ipshuflw, O_V, O_W, O_Ib, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 71 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 72 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 73 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 74 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 75 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 76 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 77 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 78 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 79 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7C */ { UD_Ihaddps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 7D */ { UD_Ihsubps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 7E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 80 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 81 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 82 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 83 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 84 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 85 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 86 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 87 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 88 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 89 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 90 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 91 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 92 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 93 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 94 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 95 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 96 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 97 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 98 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 99 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C0 */ { UD_Ixadd, O_Eb, O_Gb, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* C1 */ { UD_Ixadd, O_Ev, O_Gv, O_NONE, P_aso|P_oso|P_rexr|P_rexx|P_rexb },
+ /* C2 */ { UD_Icmpsd, O_V, O_W, O_Ib, P_aso|P_rexr|P_rexx|P_rexb },
+ /* C3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D0 */ { UD_Iaddsubps, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* D1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D6 */ { UD_Imovdq2q, O_P, O_VR, O_NONE, P_aso|P_rexb },
+ /* D7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E6 */ { UD_Icvtpd2dq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* ED */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F0 */ { UD_Ilddqu, O_V, O_M, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* F1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__pfx_ssef3__0f[256] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 08 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 09 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 0F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 10 */ { UD_Imovss, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 11 */ { UD_Imovss, O_W, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 12 */ { UD_Imovsldup, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 13 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 14 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 15 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 16 */ { UD_Imovshdup, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 17 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 18 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 19 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 1F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 20 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 21 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 22 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 23 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 24 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 25 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 26 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 27 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 28 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 29 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2A */ { UD_Icvtsi2ss, O_V, O_Ex, O_NONE, P_c2|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2C */ { UD_Icvttss2si, O_Gvw, O_W, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2D */ { UD_Icvtss2si, O_Gvw, O_W, O_NONE, P_c1|P_aso|P_rexr|P_rexx|P_rexb },
+ /* 2E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 2F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 30 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 31 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 32 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 33 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 34 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 35 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 36 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 37 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 38 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 39 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 3F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 40 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 41 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 42 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 43 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 44 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 45 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 46 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 47 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 48 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 49 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 4F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 50 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 51 */ { UD_Isqrtss, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 52 */ { UD_Irsqrtss, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 53 */ { UD_Ircpss, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 54 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 55 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 56 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 57 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 58 */ { UD_Iaddss, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 59 */ { UD_Imulss, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5A */ { UD_Icvtss2sd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5B */ { UD_Icvttps2dq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5C */ { UD_Isubss, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5D */ { UD_Iminss, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5E */ { UD_Idivss, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 5F */ { UD_Imaxss, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 60 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 61 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 62 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 63 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 64 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 65 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 66 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 67 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 68 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 69 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 6F */ { UD_Imovdqu, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 70 */ { UD_Ipshufhw, O_V, O_W, O_Ib, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 71 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 72 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 73 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 74 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 75 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 76 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 77 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 78 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 79 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 7E */ { UD_Imovq, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 7F */ { UD_Imovdqu, O_W, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* 80 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 81 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 82 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 83 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 84 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 85 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 86 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 87 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 88 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 89 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 8F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 90 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 91 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 92 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 93 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 94 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 95 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 96 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 97 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 98 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 99 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9A */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9B */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9C */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9D */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9E */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 9F */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* A9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* AF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* B9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* BF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C0 */ { UD_Ixadd, O_Eb, O_Gb, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* C1 */ { UD_Ixadd, O_Ev, O_Gv, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb },
+ /* C2 */ { UD_Icmpss, O_V, O_W, O_Ib, P_aso|P_rexr|P_rexx|P_rexb },
+ /* C3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C7 */ { UD_Igrp_reg, O_NONE, O_NONE, O_NONE, ITAB__PFX_SSEF3__0F__OP_C7__REG },
+ /* C8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* C9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* CF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D6 */ { UD_Imovq2dq, O_V, O_PR, O_NONE, P_aso },
+ /* D7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* D9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* DF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E6 */ { UD_Icvtdq2pd, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+ /* E7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* E9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* ED */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* EF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F0 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F1 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F2 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F3 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F4 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F5 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F6 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F7 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F8 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* F9 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FA */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FB */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FC */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FD */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FE */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* FF */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+};
+
+static struct ud_itab_entry itab__pfx_ssef3__0f__op_c7__reg[8] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 02 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 03 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 04 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 05 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 06 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 07 */ { UD_Igrp_vendor, O_NONE, O_NONE, O_NONE, ITAB__PFX_SSEF3__0F__OP_C7__REG__OP_07__VENDOR },
+};
+
+static struct ud_itab_entry itab__pfx_ssef3__0f__op_c7__reg__op_07__vendor[2] = {
+ /* 00 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none },
+ /* 01 */ { UD_Ivmxon, O_Mq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb },
+};
+
+/* the order of this table matches enum ud_itab_index */
+struct ud_itab_entry * ud_itab_list[] = {
+ itab__0f,
+ itab__0f__op_00__reg,
+ itab__0f__op_01__reg,
+ itab__0f__op_01__reg__op_00__mod,
+ itab__0f__op_01__reg__op_00__mod__op_01__rm,
+ itab__0f__op_01__reg__op_00__mod__op_01__rm__op_01__vendor,
+ itab__0f__op_01__reg__op_00__mod__op_01__rm__op_03__vendor,
+ itab__0f__op_01__reg__op_00__mod__op_01__rm__op_04__vendor,
+ itab__0f__op_01__reg__op_01__mod,
+ itab__0f__op_01__reg__op_01__mod__op_01__rm,
+ itab__0f__op_01__reg__op_02__mod,
+ itab__0f__op_01__reg__op_03__mod,
+ itab__0f__op_01__reg__op_03__mod__op_01__rm,
+ itab__0f__op_01__reg__op_03__mod__op_01__rm__op_00__vendor,
+ itab__0f__op_01__reg__op_03__mod__op_01__rm__op_01__vendor,
+ itab__0f__op_01__reg__op_03__mod__op_01__rm__op_02__vendor,
+ itab__0f__op_01__reg__op_03__mod__op_01__rm__op_03__vendor,
+ itab__0f__op_01__reg__op_03__mod__op_01__rm__op_04__vendor,
+ itab__0f__op_01__reg__op_03__mod__op_01__rm__op_05__vendor,
+ itab__0f__op_01__reg__op_03__mod__op_01__rm__op_06__vendor,
+ itab__0f__op_01__reg__op_03__mod__op_01__rm__op_07__vendor,
+ itab__0f__op_01__reg__op_04__mod,
+ itab__0f__op_01__reg__op_06__mod,
+ itab__0f__op_01__reg__op_07__mod,
+ itab__0f__op_01__reg__op_07__mod__op_01__rm,
+ itab__0f__op_01__reg__op_07__mod__op_01__rm__op_01__vendor,
+ itab__0f__op_0d__reg,
+ itab__0f__op_18__reg,
+ itab__0f__op_71__reg,
+ itab__0f__op_72__reg,
+ itab__0f__op_73__reg,
+ itab__0f__op_ae__reg,
+ itab__0f__op_ae__reg__op_05__mod,
+ itab__0f__op_ae__reg__op_05__mod__op_01__rm,
+ itab__0f__op_ae__reg__op_06__mod,
+ itab__0f__op_ae__reg__op_06__mod__op_01__rm,
+ itab__0f__op_ae__reg__op_07__mod,
+ itab__0f__op_ae__reg__op_07__mod__op_01__rm,
+ itab__0f__op_ba__reg,
+ itab__0f__op_c7__reg,
+ itab__0f__op_c7__reg__op_00__vendor,
+ itab__0f__op_c7__reg__op_07__vendor,
+ itab__0f__op_d9__mod,
+ itab__0f__op_d9__mod__op_01__x87,
+ itab__1byte,
+ itab__1byte__op_60__osize,
+ itab__1byte__op_61__osize,
+ itab__1byte__op_63__mode,
+ itab__1byte__op_6d__osize,
+ itab__1byte__op_6f__osize,
+ itab__1byte__op_80__reg,
+ itab__1byte__op_81__reg,
+ itab__1byte__op_82__reg,
+ itab__1byte__op_83__reg,
+ itab__1byte__op_8f__reg,
+ itab__1byte__op_98__osize,
+ itab__1byte__op_99__osize,
+ itab__1byte__op_9c__mode,
+ itab__1byte__op_9c__mode__op_00__osize,
+ itab__1byte__op_9c__mode__op_01__osize,
+ itab__1byte__op_9d__mode,
+ itab__1byte__op_9d__mode__op_00__osize,
+ itab__1byte__op_9d__mode__op_01__osize,
+ itab__1byte__op_a5__osize,
+ itab__1byte__op_a7__osize,
+ itab__1byte__op_ab__osize,
+ itab__1byte__op_ad__osize,
+ itab__1byte__op_ae__mod,
+ itab__1byte__op_ae__mod__op_00__reg,
+ itab__1byte__op_af__osize,
+ itab__1byte__op_c0__reg,
+ itab__1byte__op_c1__reg,
+ itab__1byte__op_c6__reg,
+ itab__1byte__op_c7__reg,
+ itab__1byte__op_cf__osize,
+ itab__1byte__op_d0__reg,
+ itab__1byte__op_d1__reg,
+ itab__1byte__op_d2__reg,
+ itab__1byte__op_d3__reg,
+ itab__1byte__op_d8__mod,
+ itab__1byte__op_d8__mod__op_00__reg,
+ itab__1byte__op_d8__mod__op_01__x87,
+ itab__1byte__op_d9__mod,
+ itab__1byte__op_d9__mod__op_00__reg,
+ itab__1byte__op_d9__mod__op_01__x87,
+ itab__1byte__op_da__mod,
+ itab__1byte__op_da__mod__op_00__reg,
+ itab__1byte__op_da__mod__op_01__x87,
+ itab__1byte__op_db__mod,
+ itab__1byte__op_db__mod__op_00__reg,
+ itab__1byte__op_db__mod__op_01__x87,
+ itab__1byte__op_dc__mod,
+ itab__1byte__op_dc__mod__op_00__reg,
+ itab__1byte__op_dc__mod__op_01__x87,
+ itab__1byte__op_dd__mod,
+ itab__1byte__op_dd__mod__op_00__reg,
+ itab__1byte__op_dd__mod__op_01__x87,
+ itab__1byte__op_de__mod,
+ itab__1byte__op_de__mod__op_00__reg,
+ itab__1byte__op_de__mod__op_01__x87,
+ itab__1byte__op_df__mod,
+ itab__1byte__op_df__mod__op_00__reg,
+ itab__1byte__op_df__mod__op_01__x87,
+ itab__1byte__op_e3__asize,
+ itab__1byte__op_f6__reg,
+ itab__1byte__op_f7__reg,
+ itab__1byte__op_fe__reg,
+ itab__1byte__op_ff__reg,
+ itab__3dnow,
+ itab__pfx_sse66__0f,
+ itab__pfx_sse66__0f__op_71__reg,
+ itab__pfx_sse66__0f__op_72__reg,
+ itab__pfx_sse66__0f__op_73__reg,
+ itab__pfx_sse66__0f__op_c7__reg,
+ itab__pfx_sse66__0f__op_c7__reg__op_00__vendor,
+ itab__pfx_ssef2__0f,
+ itab__pfx_ssef3__0f,
+ itab__pfx_ssef3__0f__op_c7__reg,
+ itab__pfx_ssef3__0f__op_c7__reg__op_07__vendor,
+};
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/itab.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/itab.h Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,719 @@
+
+/* itab.h -- auto generated by opgen.py, do not edit. */
+
+#ifndef UD_ITAB_H
+#define UD_ITAB_H
+
+
+
+enum ud_itab_vendor_index {
+ ITAB__VENDOR_INDX__AMD,
+ ITAB__VENDOR_INDX__INTEL,
+};
+
+
+enum ud_itab_mode_index {
+ ITAB__MODE_INDX__16,
+ ITAB__MODE_INDX__32,
+ ITAB__MODE_INDX__64
+};
+
+
+enum ud_itab_mod_index {
+ ITAB__MOD_INDX__NOT_11,
+ ITAB__MOD_INDX__11
+};
+
+
+enum ud_itab_index {
+ ITAB__0F,
+ ITAB__0F__OP_00__REG,
+ ITAB__0F__OP_01__REG,
+ ITAB__0F__OP_01__REG__OP_00__MOD,
+ ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM,
+ ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM__OP_01__VENDOR,
+ ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM__OP_03__VENDOR,
+ ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM__OP_04__VENDOR,
+ ITAB__0F__OP_01__REG__OP_01__MOD,
+ ITAB__0F__OP_01__REG__OP_01__MOD__OP_01__RM,
+ ITAB__0F__OP_01__REG__OP_02__MOD,
+ ITAB__0F__OP_01__REG__OP_03__MOD,
+ ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM,
+ ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_00__VENDOR,
+ ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_01__VENDOR,
+ ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_02__VENDOR,
+ ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_03__VENDOR,
+ ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_04__VENDOR,
+ ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_05__VENDOR,
+ ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_06__VENDOR,
+ ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_07__VENDOR,
+ ITAB__0F__OP_01__REG__OP_04__MOD,
+ ITAB__0F__OP_01__REG__OP_06__MOD,
+ ITAB__0F__OP_01__REG__OP_07__MOD,
+ ITAB__0F__OP_01__REG__OP_07__MOD__OP_01__RM,
+ ITAB__0F__OP_01__REG__OP_07__MOD__OP_01__RM__OP_01__VENDOR,
+ ITAB__0F__OP_0D__REG,
+ ITAB__0F__OP_18__REG,
+ ITAB__0F__OP_71__REG,
+ ITAB__0F__OP_72__REG,
+ ITAB__0F__OP_73__REG,
+ ITAB__0F__OP_AE__REG,
+ ITAB__0F__OP_AE__REG__OP_05__MOD,
+ ITAB__0F__OP_AE__REG__OP_05__MOD__OP_01__RM,
+ ITAB__0F__OP_AE__REG__OP_06__MOD,
+ ITAB__0F__OP_AE__REG__OP_06__MOD__OP_01__RM,
+ ITAB__0F__OP_AE__REG__OP_07__MOD,
+ ITAB__0F__OP_AE__REG__OP_07__MOD__OP_01__RM,
+ ITAB__0F__OP_BA__REG,
+ ITAB__0F__OP_C7__REG,
+ ITAB__0F__OP_C7__REG__OP_00__VENDOR,
+ ITAB__0F__OP_C7__REG__OP_07__VENDOR,
+ ITAB__0F__OP_D9__MOD,
+ ITAB__0F__OP_D9__MOD__OP_01__X87,
+ ITAB__1BYTE,
+ ITAB__1BYTE__OP_60__OSIZE,
+ ITAB__1BYTE__OP_61__OSIZE,
+ ITAB__1BYTE__OP_63__MODE,
+ ITAB__1BYTE__OP_6D__OSIZE,
+ ITAB__1BYTE__OP_6F__OSIZE,
+ ITAB__1BYTE__OP_80__REG,
+ ITAB__1BYTE__OP_81__REG,
+ ITAB__1BYTE__OP_82__REG,
+ ITAB__1BYTE__OP_83__REG,
+ ITAB__1BYTE__OP_8F__REG,
+ ITAB__1BYTE__OP_98__OSIZE,
+ ITAB__1BYTE__OP_99__OSIZE,
+ ITAB__1BYTE__OP_9C__MODE,
+ ITAB__1BYTE__OP_9C__MODE__OP_00__OSIZE,
+ ITAB__1BYTE__OP_9C__MODE__OP_01__OSIZE,
+ ITAB__1BYTE__OP_9D__MODE,
+ ITAB__1BYTE__OP_9D__MODE__OP_00__OSIZE,
+ ITAB__1BYTE__OP_9D__MODE__OP_01__OSIZE,
+ ITAB__1BYTE__OP_A5__OSIZE,
+ ITAB__1BYTE__OP_A7__OSIZE,
+ ITAB__1BYTE__OP_AB__OSIZE,
+ ITAB__1BYTE__OP_AD__OSIZE,
+ ITAB__1BYTE__OP_AE__MOD,
+ ITAB__1BYTE__OP_AE__MOD__OP_00__REG,
+ ITAB__1BYTE__OP_AF__OSIZE,
+ ITAB__1BYTE__OP_C0__REG,
+ ITAB__1BYTE__OP_C1__REG,
+ ITAB__1BYTE__OP_C6__REG,
+ ITAB__1BYTE__OP_C7__REG,
+ ITAB__1BYTE__OP_CF__OSIZE,
+ ITAB__1BYTE__OP_D0__REG,
+ ITAB__1BYTE__OP_D1__REG,
+ ITAB__1BYTE__OP_D2__REG,
+ ITAB__1BYTE__OP_D3__REG,
+ ITAB__1BYTE__OP_D8__MOD,
+ ITAB__1BYTE__OP_D8__MOD__OP_00__REG,
+ ITAB__1BYTE__OP_D8__MOD__OP_01__X87,
+ ITAB__1BYTE__OP_D9__MOD,
+ ITAB__1BYTE__OP_D9__MOD__OP_00__REG,
+ ITAB__1BYTE__OP_D9__MOD__OP_01__X87,
+ ITAB__1BYTE__OP_DA__MOD,
+ ITAB__1BYTE__OP_DA__MOD__OP_00__REG,
+ ITAB__1BYTE__OP_DA__MOD__OP_01__X87,
+ ITAB__1BYTE__OP_DB__MOD,
+ ITAB__1BYTE__OP_DB__MOD__OP_00__REG,
+ ITAB__1BYTE__OP_DB__MOD__OP_01__X87,
+ ITAB__1BYTE__OP_DC__MOD,
+ ITAB__1BYTE__OP_DC__MOD__OP_00__REG,
+ ITAB__1BYTE__OP_DC__MOD__OP_01__X87,
+ ITAB__1BYTE__OP_DD__MOD,
+ ITAB__1BYTE__OP_DD__MOD__OP_00__REG,
+ ITAB__1BYTE__OP_DD__MOD__OP_01__X87,
+ ITAB__1BYTE__OP_DE__MOD,
+ ITAB__1BYTE__OP_DE__MOD__OP_00__REG,
+ ITAB__1BYTE__OP_DE__MOD__OP_01__X87,
+ ITAB__1BYTE__OP_DF__MOD,
+ ITAB__1BYTE__OP_DF__MOD__OP_00__REG,
+ ITAB__1BYTE__OP_DF__MOD__OP_01__X87,
+ ITAB__1BYTE__OP_E3__ASIZE,
+ ITAB__1BYTE__OP_F6__REG,
+ ITAB__1BYTE__OP_F7__REG,
+ ITAB__1BYTE__OP_FE__REG,
+ ITAB__1BYTE__OP_FF__REG,
+ ITAB__3DNOW,
+ ITAB__PFX_SSE66__0F,
+ ITAB__PFX_SSE66__0F__OP_71__REG,
+ ITAB__PFX_SSE66__0F__OP_72__REG,
+ ITAB__PFX_SSE66__0F__OP_73__REG,
+ ITAB__PFX_SSE66__0F__OP_C7__REG,
+ ITAB__PFX_SSE66__0F__OP_C7__REG__OP_00__VENDOR,
+ ITAB__PFX_SSEF2__0F,
+ ITAB__PFX_SSEF3__0F,
+ ITAB__PFX_SSEF3__0F__OP_C7__REG,
+ ITAB__PFX_SSEF3__0F__OP_C7__REG__OP_07__VENDOR,
+};
+
+
+enum ud_mnemonic_code {
+ UD_I3dnow,
+ UD_Iaaa,
+ UD_Iaad,
+ UD_Iaam,
+ UD_Iaas,
+ UD_Iadc,
+ UD_Iadd,
+ UD_Iaddpd,
+ UD_Iaddps,
+ UD_Iaddsd,
+ UD_Iaddss,
+ UD_Iaddsubpd,
+ UD_Iaddsubps,
+ UD_Iand,
+ UD_Iandpd,
+ UD_Iandps,
+ UD_Iandnpd,
+ UD_Iandnps,
+ UD_Iarpl,
+ UD_Imovsxd,
+ UD_Ibound,
+ UD_Ibsf,
+ UD_Ibsr,
+ UD_Ibswap,
+ UD_Ibt,
+ UD_Ibtc,
+ UD_Ibtr,
+ UD_Ibts,
+ UD_Icall,
+ UD_Icbw,
+ UD_Icwde,
+ UD_Icdqe,
+ UD_Iclc,
+ UD_Icld,
+ UD_Iclflush,
+ UD_Iclgi,
+ UD_Icli,
+ UD_Iclts,
+ UD_Icmc,
+ UD_Icmovo,
+ UD_Icmovno,
+ UD_Icmovb,
+ UD_Icmovae,
+ UD_Icmovz,
+ UD_Icmovnz,
+ UD_Icmovbe,
+ UD_Icmova,
+ UD_Icmovs,
+ UD_Icmovns,
+ UD_Icmovp,
+ UD_Icmovnp,
+ UD_Icmovl,
+ UD_Icmovge,
+ UD_Icmovle,
+ UD_Icmovg,
+ UD_Icmp,
+ UD_Icmppd,
+ UD_Icmpps,
+ UD_Icmpsb,
+ UD_Icmpsw,
+ UD_Icmpsd,
+ UD_Icmpsq,
+ UD_Icmpss,
+ UD_Icmpxchg,
+ UD_Icmpxchg8b,
+ UD_Icomisd,
+ UD_Icomiss,
+ UD_Icpuid,
+ UD_Icvtdq2pd,
+ UD_Icvtdq2ps,
+ UD_Icvtpd2dq,
+ UD_Icvtpd2pi,
+ UD_Icvtpd2ps,
+ UD_Icvtpi2ps,
+ UD_Icvtpi2pd,
+ UD_Icvtps2dq,
+ UD_Icvtps2pi,
+ UD_Icvtps2pd,
+ UD_Icvtsd2si,
+ UD_Icvtsd2ss,
+ UD_Icvtsi2ss,
+ UD_Icvtss2si,
+ UD_Icvtss2sd,
+ UD_Icvttpd2pi,
+ UD_Icvttpd2dq,
+ UD_Icvttps2dq,
+ UD_Icvttps2pi,
+ UD_Icvttsd2si,
+ UD_Icvtsi2sd,
+ UD_Icvttss2si,
+ UD_Icwd,
+ UD_Icdq,
+ UD_Icqo,
+ UD_Idaa,
+ UD_Idas,
+ UD_Idec,
+ UD_Idiv,
+ UD_Idivpd,
+ UD_Idivps,
+ UD_Idivsd,
+ UD_Idivss,
+ UD_Iemms,
+ UD_Ienter,
+ UD_If2xm1,
+ UD_Ifabs,
+ UD_Ifadd,
+ UD_Ifaddp,
+ UD_Ifbld,
+ UD_Ifbstp,
+ UD_Ifchs,
+ UD_Ifclex,
+ UD_Ifcmovb,
+ UD_Ifcmove,
+ UD_Ifcmovbe,
+ UD_Ifcmovu,
+ UD_Ifcmovnb,
+ UD_Ifcmovne,
+ UD_Ifcmovnbe,
+ UD_Ifcmovnu,
+ UD_Ifucomi,
+ UD_Ifcom,
+ UD_Ifcom2,
+ UD_Ifcomp3,
+ UD_Ifcomi,
+ UD_Ifucomip,
+ UD_Ifcomip,
+ UD_Ifcomp,
+ UD_Ifcomp5,
+ UD_Ifcompp,
+ UD_Ifcos,
+ UD_Ifdecstp,
+ UD_Ifdiv,
+ UD_Ifdivp,
+ UD_Ifdivr,
+ UD_Ifdivrp,
+ UD_Ifemms,
+ UD_Iffree,
+ UD_Iffreep,
+ UD_Ificom,
+ UD_Ificomp,
+ UD_Ifild,
+ UD_Ifncstp,
+ UD_Ifninit,
+ UD_Ifiadd,
+ UD_Ifidivr,
+ UD_Ifidiv,
+ UD_Ifisub,
+ UD_Ifisubr,
+ UD_Ifist,
+ UD_Ifistp,
+ UD_Ifisttp,
+ UD_Ifld,
+ UD_Ifld1,
+ UD_Ifldl2t,
+ UD_Ifldl2e,
+ UD_Ifldlpi,
+ UD_Ifldlg2,
+ UD_Ifldln2,
+ UD_Ifldz,
+ UD_Ifldcw,
+ UD_Ifldenv,
+ UD_Ifmul,
+ UD_Ifmulp,
+ UD_Ifimul,
+ UD_Ifnop,
+ UD_Ifpatan,
+ UD_Ifprem,
+ UD_Ifprem1,
+ UD_Ifptan,
+ UD_Ifrndint,
+ UD_Ifrstor,
+ UD_Ifnsave,
+ UD_Ifscale,
+ UD_Ifsin,
+ UD_Ifsincos,
+ UD_Ifsqrt,
+ UD_Ifstp,
+ UD_Ifstp1,
+ UD_Ifstp8,
+ UD_Ifstp9,
+ UD_Ifst,
+ UD_Ifnstcw,
+ UD_Ifnstenv,
+ UD_Ifnstsw,
+ UD_Ifsub,
+ UD_Ifsubp,
+ UD_Ifsubr,
+ UD_Ifsubrp,
+ UD_Iftst,
+ UD_Ifucom,
+ UD_Ifucomp,
+ UD_Ifucompp,
+ UD_Ifxam,
+ UD_Ifxch,
+ UD_Ifxch4,
+ UD_Ifxch7,
+ UD_Ifxrstor,
+ UD_Ifxsave,
+ UD_Ifpxtract,
+ UD_Ifyl2x,
+ UD_Ifyl2xp1,
+ UD_Ihaddpd,
+ UD_Ihaddps,
+ UD_Ihlt,
+ UD_Ihsubpd,
+ UD_Ihsubps,
+ UD_Iidiv,
+ UD_Iin,
+ UD_Iimul,
+ UD_Iinc,
+ UD_Iinsb,
+ UD_Iinsw,
+ UD_Iinsd,
+ UD_Iint1,
+ UD_Iint3,
+ UD_Iint,
+ UD_Iinto,
+ UD_Iinvd,
+ UD_Iinvlpg,
+ UD_Iinvlpga,
+ UD_Iiretw,
+ UD_Iiretd,
+ UD_Iiretq,
+ UD_Ijo,
+ UD_Ijno,
+ UD_Ijb,
+ UD_Ijae,
+ UD_Ijz,
+ UD_Ijnz,
+ UD_Ijbe,
+ UD_Ija,
+ UD_Ijs,
+ UD_Ijns,
+ UD_Ijp,
+ UD_Ijnp,
+ UD_Ijl,
+ UD_Ijge,
+ UD_Ijle,
+ UD_Ijg,
+ UD_Ijcxz,
+ UD_Ijecxz,
+ UD_Ijrcxz,
+ UD_Ijmp,
+ UD_Ilahf,
+ UD_Ilar,
+ UD_Ilddqu,
+ UD_Ildmxcsr,
+ UD_Ilds,
+ UD_Ilea,
+ UD_Iles,
+ UD_Ilfs,
+ UD_Ilgs,
+ UD_Ilidt,
+ UD_Ilss,
+ UD_Ileave,
+ UD_Ilfence,
+ UD_Ilgdt,
+ UD_Illdt,
+ UD_Ilmsw,
+ UD_Ilock,
+ UD_Ilodsb,
+ UD_Ilodsw,
+ UD_Ilodsd,
+ UD_Ilodsq,
+ UD_Iloopnz,
+ UD_Iloope,
+ UD_Iloop,
+ UD_Ilsl,
+ UD_Iltr,
+ UD_Imaskmovq,
+ UD_Imaxpd,
+ UD_Imaxps,
+ UD_Imaxsd,
+ UD_Imaxss,
+ UD_Imfence,
+ UD_Iminpd,
+ UD_Iminps,
+ UD_Iminsd,
+ UD_Iminss,
+ UD_Imonitor,
+ UD_Imov,
+ UD_Imovapd,
+ UD_Imovaps,
+ UD_Imovd,
+ UD_Imovddup,
+ UD_Imovdqa,
+ UD_Imovdqu,
+ UD_Imovdq2q,
+ UD_Imovhpd,
+ UD_Imovhps,
+ UD_Imovlhps,
+ UD_Imovlpd,
+ UD_Imovlps,
+ UD_Imovhlps,
+ UD_Imovmskpd,
+ UD_Imovmskps,
+ UD_Imovntdq,
+ UD_Imovnti,
+ UD_Imovntpd,
+ UD_Imovntps,
+ UD_Imovntq,
+ UD_Imovq,
+ UD_Imovqa,
+ UD_Imovq2dq,
+ UD_Imovsb,
+ UD_Imovsw,
+ UD_Imovsd,
+ UD_Imovsq,
+ UD_Imovsldup,
+ UD_Imovshdup,
+ UD_Imovss,
+ UD_Imovsx,
+ UD_Imovupd,
+ UD_Imovups,
+ UD_Imovzx,
+ UD_Imul,
+ UD_Imulpd,
+ UD_Imulps,
+ UD_Imulsd,
+ UD_Imulss,
+ UD_Imwait,
+ UD_Ineg,
+ UD_Inop,
+ UD_Inot,
+ UD_Ior,
+ UD_Iorpd,
+ UD_Iorps,
+ UD_Iout,
+ UD_Ioutsb,
+ UD_Ioutsw,
+ UD_Ioutsd,
+ UD_Ioutsq,
+ UD_Ipacksswb,
+ UD_Ipackssdw,
+ UD_Ipackuswb,
+ UD_Ipaddb,
+ UD_Ipaddw,
+ UD_Ipaddq,
+ UD_Ipaddsb,
+ UD_Ipaddsw,
+ UD_Ipaddusb,
+ UD_Ipaddusw,
+ UD_Ipand,
+ UD_Ipandn,
+ UD_Ipause,
+ UD_Ipavgb,
+ UD_Ipavgw,
+ UD_Ipcmpeqb,
+ UD_Ipcmpeqw,
+ UD_Ipcmpeqd,
+ UD_Ipcmpgtb,
+ UD_Ipcmpgtw,
+ UD_Ipcmpgtd,
+ UD_Ipextrw,
+ UD_Ipinsrw,
+ UD_Ipmaddwd,
+ UD_Ipmaxsw,
+ UD_Ipmaxub,
+ UD_Ipminsw,
+ UD_Ipminub,
+ UD_Ipmovmskb,
+ UD_Ipmulhuw,
+ UD_Ipmulhw,
+ UD_Ipmullw,
+ UD_Ipmuludq,
+ UD_Ipop,
+ UD_Ipopa,
+ UD_Ipopad,
+ UD_Ipopfw,
+ UD_Ipopfd,
+ UD_Ipopfq,
+ UD_Ipor,
+ UD_Iprefetch,
+ UD_Iprefetchnta,
+ UD_Iprefetcht0,
+ UD_Iprefetcht1,
+ UD_Iprefetcht2,
+ UD_Ipsadbw,
+ UD_Ipshufd,
+ UD_Ipshufhw,
+ UD_Ipshuflw,
+ UD_Ipshufw,
+ UD_Ipslldq,
+ UD_Ipsllw,
+ UD_Ipslld,
+ UD_Ipsllq,
+ UD_Ipsraw,
+ UD_Ipsrad,
+ UD_Ipsrlw,
+ UD_Ipsrld,
+ UD_Ipsrlq,
+ UD_Ipsrldq,
+ UD_Ipsubb,
+ UD_Ipsubw,
+ UD_Ipsubd,
+ UD_Ipsubq,
+ UD_Ipsubsb,
+ UD_Ipsubsw,
+ UD_Ipsubusb,
+ UD_Ipsubusw,
+ UD_Ipunpckhbw,
+ UD_Ipunpckhwd,
+ UD_Ipunpckhdq,
+ UD_Ipunpckhqdq,
+ UD_Ipunpcklbw,
+ UD_Ipunpcklwd,
+ UD_Ipunpckldq,
+ UD_Ipunpcklqdq,
+ UD_Ipi2fw,
+ UD_Ipi2fd,
+ UD_Ipf2iw,
+ UD_Ipf2id,
+ UD_Ipfnacc,
+ UD_Ipfpnacc,
+ UD_Ipfcmpge,
+ UD_Ipfmin,
+ UD_Ipfrcp,
+ UD_Ipfrsqrt,
+ UD_Ipfsub,
+ UD_Ipfadd,
+ UD_Ipfcmpgt,
+ UD_Ipfmax,
+ UD_Ipfrcpit1,
+ UD_Ipfrspit1,
+ UD_Ipfsubr,
+ UD_Ipfacc,
+ UD_Ipfcmpeq,
+ UD_Ipfmul,
+ UD_Ipfrcpit2,
+ UD_Ipmulhrw,
+ UD_Ipswapd,
+ UD_Ipavgusb,
+ UD_Ipush,
+ UD_Ipusha,
+ UD_Ipushad,
+ UD_Ipushfw,
+ UD_Ipushfd,
+ UD_Ipushfq,
+ UD_Ipxor,
+ UD_Ircl,
+ UD_Ircr,
+ UD_Irol,
+ UD_Iror,
+ UD_Ircpps,
+ UD_Ircpss,
+ UD_Irdmsr,
+ UD_Irdpmc,
+ UD_Irdtsc,
+ UD_Irdtscp,
+ UD_Irepne,
+ UD_Irep,
+ UD_Iret,
+ UD_Iretf,
+ UD_Irsm,
+ UD_Irsqrtps,
+ UD_Irsqrtss,
+ UD_Isahf,
+ UD_Isal,
+ UD_Isalc,
+ UD_Isar,
+ UD_Ishl,
+ UD_Ishr,
+ UD_Isbb,
+ UD_Iscasb,
+ UD_Iscasw,
+ UD_Iscasd,
+ UD_Iscasq,
+ UD_Iseto,
+ UD_Isetno,
+ UD_Isetb,
+ UD_Isetnb,
+ UD_Isetz,
+ UD_Isetnz,
+ UD_Isetbe,
+ UD_Iseta,
+ UD_Isets,
+ UD_Isetns,
+ UD_Isetp,
+ UD_Isetnp,
+ UD_Isetl,
+ UD_Isetge,
+ UD_Isetle,
+ UD_Isetg,
+ UD_Isfence,
+ UD_Isgdt,
+ UD_Ishld,
+ UD_Ishrd,
+ UD_Ishufpd,
+ UD_Ishufps,
+ UD_Isidt,
+ UD_Isldt,
+ UD_Ismsw,
+ UD_Isqrtps,
+ UD_Isqrtpd,
+ UD_Isqrtsd,
+ UD_Isqrtss,
+ UD_Istc,
+ UD_Istd,
+ UD_Istgi,
+ UD_Isti,
+ UD_Iskinit,
+ UD_Istmxcsr,
+ UD_Istosb,
+ UD_Istosw,
+ UD_Istosd,
+ UD_Istosq,
+ UD_Istr,
+ UD_Isub,
+ UD_Isubpd,
+ UD_Isubps,
+ UD_Isubsd,
+ UD_Isubss,
+ UD_Iswapgs,
+ UD_Isyscall,
+ UD_Isysenter,
+ UD_Isysexit,
+ UD_Isysret,
+ UD_Itest,
+ UD_Iucomisd,
+ UD_Iucomiss,
+ UD_Iud2,
+ UD_Iunpckhpd,
+ UD_Iunpckhps,
+ UD_Iunpcklps,
+ UD_Iunpcklpd,
+ UD_Iverr,
+ UD_Iverw,
+ UD_Ivmcall,
+ UD_Ivmclear,
+ UD_Ivmxon,
+ UD_Ivmptrld,
+ UD_Ivmptrst,
+ UD_Ivmresume,
+ UD_Ivmxoff,
+ UD_Ivmrun,
+ UD_Ivmmcall,
+ UD_Ivmload,
+ UD_Ivmsave,
+ UD_Iwait,
+ UD_Iwbinvd,
+ UD_Iwrmsr,
+ UD_Ixadd,
+ UD_Ixchg,
+ UD_Ixlatb,
+ UD_Ixor,
+ UD_Ixorpd,
+ UD_Ixorps,
+ UD_Idb,
+ UD_Iinvalid,
+ UD_Id3vil,
+ UD_Ina,
+ UD_Igrp_reg,
+ UD_Igrp_rm,
+ UD_Igrp_vendor,
+ UD_Igrp_x87,
+ UD_Igrp_mode,
+ UD_Igrp_osize,
+ UD_Igrp_asize,
+ UD_Igrp_mod,
+ UD_Inone,
+};
+
+
+
+extern const char* ud_mnemonics_str[];;
+extern struct ud_itab_entry* ud_itab_list[];
+
+#endif
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/kdb_dis.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/kdb_dis.c Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2009, Mukesh Rathor, Oracle Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include <xen/compile.h> /* for XEN_SUBVERSION */
+#include "../../include/kdbinc.h"
+#include "extern.h"
+
+static void (*dis_syntax)(ud_t*) = UD_SYN_ATT; /* default dis-assembly syntax */
+
+static struct { /* info for kdb_read_byte_for_ud() */
+ kdbva_t kud_instr_addr;
+ domid_t kud_domid;
+} kdb_ud_rd_info;
+
+/* called via function ptr by ud when disassembling.
+ * kdb info passed via kdb_ud_rd_info{}
+ */
+static int
+kdb_read_byte_for_ud(struct ud *udp)
+{
+ kdbbyt_t bytebuf;
+ domid_t domid = kdb_ud_rd_info.kud_domid;
+ kdbva_t addr = kdb_ud_rd_info.kud_instr_addr;
+
+ if (kdb_read_mem(addr, &bytebuf, 1, domid) == 1) {
+ kdb_ud_rd_info.kud_instr_addr++;
+ KDBGP1("udrd:addr:%lx domid:%d byt:%x\n", addr, domid, bytebuf);
+ return bytebuf;
+ }
+ KDBGP1("udrd:addr:%lx domid:%d err\n", addr, domid);
+ return UD_EOI;
+}
+
+/*
+ * given a domid, convert addr to symbol and print it
+ * Eg: ffff828c801235e2: idle_loop+52 jmp idle_loop+55
+ * Called twice here for idle_loop. In first case, nl is null,
+ * in the second case nl == '\n'
+ */
+void
+kdb_prnt_addr2sym(domid_t domid, kdbva_t addr, char *nl)
+{
+ unsigned long sz, offs;
+ char buf[KSYM_NAME_LEN+1], pbuf[150], prefix[8];
+ char *p = buf;
+
+ prefix[0]='\0';
+ if (domid != DOMID_IDLE) {
+ snprintf(prefix, 8, "%x:", domid);
+ p = kdb_guest_addr2sym(addr, domid, &offs);
+ } else
+ symbols_lookup(addr, &sz, &offs, buf);
+
+ snprintf(pbuf, 150, "%s%s+%lx", prefix, p, offs);
+ if (*nl != '\n')
+ kdbp("%-30s%s", pbuf, nl); /* prints more than 30 if needed */
+ else
+ kdbp("%s%s", pbuf, nl);
+
+}
+
+static int
+kdb_jump_instr(enum ud_mnemonic_code mnemonic)
+{
+ return (mnemonic >= UD_Ijo && mnemonic <= UD_Ijmp);
+}
+
+/*
+ * print one instr: function so that we can print offsets of jmp etc.. as
+ * symbol+offset instead of just address
+ */
+static void
+kdb_print_one_instr(struct ud *udp, domid_t domid)
+{
+ signed long val = 0;
+ ud_type_t type = udp->operand[0].type;
+
+ if ((udp->mnemonic == UD_Icall || kdb_jump_instr(udp->mnemonic)) &&
+ type == UD_OP_JIMM) {
+
+ int sz = udp->operand[0].size;
+ char *p, ibuf[40], *q = ibuf;
+ kdbva_t addr;
+
+ if (sz == 8) val = udp->operand[0].lval.sbyte;
+ else if (sz == 16) val = udp->operand[0].lval.sword;
+ else if (sz == 32) val = udp->operand[0].lval.sdword;
+ else if (sz == 64) val = udp->operand[0].lval.sqword;
+ else kdbp("kdb_print_one_instr: Inval sz:z%d\n", sz);
+
+ addr = udp->pc + val;
+ for(p=ud_insn_asm(udp); (*q=*p) && *p!=' '; p++,q++);
+ *q='\0';
+ kdbp(" %-4s ", ibuf); /* space before for long func names */
+ kdb_prnt_addr2sym(domid, addr, "\n");
+ } else
+ kdbp(" %-24s\n", ud_insn_asm(udp));
+#if 0
+ kdbp("mnemonic:z%d ", udp->mnemonic);
+ if (type == UD_OP_CONST) kdbp("type is const\n");
+ else if (type == UD_OP_JIMM) kdbp("type is JIMM\n");
+ else if (type == UD_OP_IMM) kdbp("type is IMM\n");
+ else if (type == UD_OP_PTR) kdbp("type is PTR\n");
+#endif
+}
+
+static void
+kdb_setup_ud(struct ud *udp, kdbva_t addr, domid_t domid)
+{
+ int bitness = kdb_guest_bitness(domid);
+ uint vendor = (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) ?
+ UD_VENDOR_AMD : UD_VENDOR_INTEL;
+
+ KDBGP1("setup_ud:domid:%d bitness:%d addr:%lx\n", domid, bitness, addr);
+ ud_init(udp);
+ ud_set_mode(udp, kdb_guest_bitness(domid));
+ ud_set_syntax(udp, dis_syntax);
+ ud_set_vendor(udp, vendor); /* HVM: vmx/svm different instrs*/
+ ud_set_pc(udp, addr); /* for numbers printed on left */
+ ud_set_input_hook(udp, kdb_read_byte_for_ud);
+ kdb_ud_rd_info.kud_instr_addr = addr;
+ kdb_ud_rd_info.kud_domid = domid;
+}
+
+/*
+ * given an addr, print given number of instructions.
+ * Returns: address of next instruction in the stream
+ */
+kdbva_t
+kdb_print_instr(kdbva_t addr, long num, domid_t domid)
+{
+ struct ud ud_s;
+
+ KDBGP1("print_instr:addr:0x%lx num:%ld domid:%x\n", addr, num, domid);
+
+ kdb_setup_ud(&ud_s, addr, domid);
+ while(num--) {
+ if (ud_disassemble(&ud_s)) {
+ uint64_t pc = ud_insn_off(&ud_s);
+ /* kdbp("%08x: ",(int)pc); */
+ kdbp("%016lx: ", pc);
+ kdb_prnt_addr2sym(domid, pc, "");
+ kdb_print_one_instr(&ud_s, domid);
+ } else
+ kdbp("KDB:Couldn't disassemble PC:0x%lx\n", addr);
+ /* for stack reads, don't always display error */
+ }
+ KDBGP1("print_instr:kudaddr:0x%lx\n", kdb_ud_rd_info.kud_instr_addr);
+ return kdb_ud_rd_info.kud_instr_addr;
+}
+
+void
+kdb_display_pc(struct cpu_user_regs *regs)
+{
+ domid_t domid;
+ struct cpu_user_regs regs1 = *regs;
+ domid = guest_mode(regs) ? current->domain->domain_id : DOMID_IDLE;
+
+ regs1.KDBIP = regs->KDBIP;
+ kdb_print_instr(regs1.KDBIP, 1, domid);
+}
+
+/* check if the instr at the addr is call instruction
+ * RETURNS: size of the instr if it's a call instr, else 0
+ */
+int
+kdb_check_call_instr(domid_t domid, kdbva_t addr)
+{
+ struct ud ud_s;
+ int sz;
+
+ kdb_setup_ud(&ud_s, addr, domid);
+ if ((sz=ud_disassemble(&ud_s)) && ud_s.mnemonic == UD_Icall)
+ return (sz);
+ return 0;
+}
+
+/* toggle ATT and Intel syntaxes */
+void
+kdb_toggle_dis_syntax(void)
+{
+ if (dis_syntax == UD_SYN_INTEL) {
+ dis_syntax = UD_SYN_ATT;
+ kdbp("dis syntax now set to ATT (Gas)\n");
+ } else {
+ dis_syntax = UD_SYN_INTEL;
+ kdbp("dis syntax now set to Intel (NASM)\n");
+ }
+}
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/syn-att.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/syn-att.c Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,211 @@
+/* -----------------------------------------------------------------------------
+ * syn-att.c
+ *
+ * Copyright (c) 2004, 2005, 2006 Vivek Mohan <vivek@sig9.com>
+ * All rights reserved. See (LICENSE)
+ * -----------------------------------------------------------------------------
+ */
+
+#include "types.h"
+#include "extern.h"
+#include "decode.h"
+#include "itab.h"
+#include "syn.h"
+
+/* -----------------------------------------------------------------------------
+ * opr_cast() - Prints an operand cast.
+ * -----------------------------------------------------------------------------
+ */
+static void
+opr_cast(struct ud* u, struct ud_operand* op)
+{
+ switch(op->size) {
+ case 16 : case 32 :
+ mkasm(u, "*"); break;
+ default: break;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * gen_operand() - Generates assembly output for each operand.
+ * -----------------------------------------------------------------------------
+ */
+static void
+gen_operand(struct ud* u, struct ud_operand* op)
+{
+ switch(op->type) {
+ case UD_OP_REG:
+ mkasm(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]);
+ break;
+
+ case UD_OP_MEM:
+ if (u->br_far) opr_cast(u, op);
+ if (u->pfx_seg)
+ mkasm(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
+ if (op->offset == 8) {
+ if (op->lval.sbyte < 0)
+ mkasm(u, "-0x%x", (-op->lval.sbyte) & 0xff);
+ else mkasm(u, "0x%x", op->lval.sbyte);
+ }
+ else if (op->offset == 16)
+ mkasm(u, "0x%x", op->lval.uword);
+ else if (op->offset == 32)
+ mkasm(u, "0x%lx", op->lval.udword);
+ else if (op->offset == 64)
+ mkasm(u, "0x" FMT64 "x", op->lval.uqword);
+
+ if (op->base)
+ mkasm(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]);
+ if (op->index) {
+ if (op->base)
+ mkasm(u, ",");
+ else mkasm(u, "(");
+ mkasm(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]);
+ }
+ if (op->scale)
+ mkasm(u, ",%d", op->scale);
+ if (op->base || op->index)
+ mkasm(u, ")");
+ break;
+
+ case UD_OP_IMM:
+ switch (op->size) {
+ case 8: mkasm(u, "$0x%x", op->lval.ubyte); break;
+ case 16: mkasm(u, "$0x%x", op->lval.uword); break;
+ case 32: mkasm(u, "$0x%lx", op->lval.udword); break;
+ case 64: mkasm(u, "$0x" FMT64 "x", op->lval.uqword); break;
+ default: break;
+ }
+ break;
+
+ case UD_OP_JIMM:
+ switch (op->size) {
+ case 8:
+ mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte);
+ break;
+ case 16:
+ mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword);
+ break;
+ case 32:
+ mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword);
+ break;
+ default:break;
+ }
+ break;
+
+ case UD_OP_PTR:
+ switch (op->size) {
+ case 32:
+ mkasm(u, "$0x%x, $0x%x", op->lval.ptr.seg,
+ op->lval.ptr.off & 0xFFFF);
+ break;
+ case 48:
+ mkasm(u, "$0x%x, $0x%lx", op->lval.ptr.seg,
+ op->lval.ptr.off);
+ break;
+ }
+ break;
+
+ default: return;
+ }
+}
+
+/* =============================================================================
+ * translates to AT&T syntax
+ * =============================================================================
+ */
+extern void
+ud_translate_att(struct ud *u)
+{
+ int size = 0;
+
+ /* check if P_OSO prefix is used */
+ if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
+ switch (u->dis_mode) {
+ case 16:
+ mkasm(u, "o32 ");
+ break;
+ case 32:
+ case 64:
+ mkasm(u, "o16 ");
+ break;
+ }
+ }
+
+ /* check if P_ASO prefix was used */
+ if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
+ switch (u->dis_mode) {
+ case 16:
+ mkasm(u, "a32 ");
+ break;
+ case 32:
+ mkasm(u, "a16 ");
+ break;
+ case 64:
+ mkasm(u, "a32 ");
+ break;
+ }
+ }
+
+ if (u->pfx_lock)
+ mkasm(u, "lock ");
+ if (u->pfx_rep)
+ mkasm(u, "rep ");
+ if (u->pfx_repne)
+ mkasm(u, "repne ");
+
+ /* special instructions */
+ switch (u->mnemonic) {
+ case UD_Iretf:
+ mkasm(u, "lret ");
+ break;
+ case UD_Idb:
+ mkasm(u, ".byte 0x%x", u->operand[0].lval.ubyte);
+ return;
+ case UD_Ijmp:
+ case UD_Icall:
+ if (u->br_far) mkasm(u, "l");
+ mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic));
+ break;
+ case UD_Ibound:
+ case UD_Ienter:
+ if (u->operand[0].type != UD_NONE)
+ gen_operand(u, &u->operand[0]);
+ if (u->operand[1].type != UD_NONE) {
+ mkasm(u, ",");
+ gen_operand(u, &u->operand[1]);
+ }
+ return;
+ default:
+ mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic));
+ }
+
+ if (u->c1)
+ size = u->operand[0].size;
+ else if (u->c2)
+ size = u->operand[1].size;
+ else if (u->c3)
+ size = u->operand[2].size;
+
+ if (size == 8)
+ mkasm(u, "b");
+ else if (size == 16)
+ mkasm(u, "w");
+ else if (size == 64)
+ mkasm(u, "q");
+
+ mkasm(u, " ");
+
+ if (u->operand[2].type != UD_NONE) {
+ gen_operand(u, &u->operand[2]);
+ mkasm(u, ", ");
+ }
+
+ if (u->operand[1].type != UD_NONE) {
+ gen_operand(u, &u->operand[1]);
+ mkasm(u, ", ");
+ }
+
+ if (u->operand[0].type != UD_NONE)
+ gen_operand(u, &u->operand[0]);
+}
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/syn-intel.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/syn-intel.c Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,208 @@
+/* -----------------------------------------------------------------------------
+ * syn-intel.c
+ *
+ * Copyright (c) 2002, 2003, 2004 Vivek Mohan <vivek@sig9.com>
+ * All rights reserved. See (LICENSE)
+ * -----------------------------------------------------------------------------
+ */
+
+#include "types.h"
+#include "extern.h"
+#include "decode.h"
+#include "itab.h"
+#include "syn.h"
+
+/* -----------------------------------------------------------------------------
+ * opr_cast() - Prints an operand cast.
+ * -----------------------------------------------------------------------------
+ */
+static void
+opr_cast(struct ud* u, struct ud_operand* op)
+{
+ switch(op->size) {
+ case 8: mkasm(u, "byte " ); break;
+ case 16: mkasm(u, "word " ); break;
+ case 32: mkasm(u, "dword "); break;
+ case 64: mkasm(u, "qword "); break;
+ case 80: mkasm(u, "tword "); break;
+ default: break;
+ }
+ if (u->br_far)
+ mkasm(u, "far ");
+ else if (u->br_near)
+ mkasm(u, "near ");
+}
+
+/* -----------------------------------------------------------------------------
+ * gen_operand() - Generates assembly output for each operand.
+ * -----------------------------------------------------------------------------
+ */
+static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
+{
+ switch(op->type) {
+ case UD_OP_REG:
+ mkasm(u, ud_reg_tab[op->base - UD_R_AL]);
+ break;
+
+ case UD_OP_MEM: {
+
+ int op_f = 0;
+
+ if (syn_cast)
+ opr_cast(u, op);
+
+ mkasm(u, "[");
+
+ if (u->pfx_seg)
+ mkasm(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
+
+ if (op->base) {
+ mkasm(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
+ op_f = 1;
+ }
+
+ if (op->index) {
+ if (op_f)
+ mkasm(u, "+");
+ mkasm(u, "%s", ud_reg_tab[op->index - UD_R_AL]);
+ op_f = 1;
+ }
+
+ if (op->scale)
+ mkasm(u, "*%d", op->scale);
+
+ if (op->offset == 8) {
+ if (op->lval.sbyte < 0)
+ mkasm(u, "-0x%x", -op->lval.sbyte);
+ else mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sbyte);
+ }
+ else if (op->offset == 16)
+ mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.uword);
+ else if (op->offset == 32) {
+ if (u->adr_mode == 64) {
+ if (op->lval.sdword < 0)
+ mkasm(u, "-0x%x", -op->lval.sdword);
+ else mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sdword);
+ }
+ else mkasm(u, "%s0x%lx", (op_f) ? "+" : "", op->lval.udword);
+ }
+ else if (op->offset == 64)
+ mkasm(u, "%s0x" FMT64 "x", (op_f) ? "+" : "", op->lval.uqword);
+
+ mkasm(u, "]");
+ break;
+ }
+
+ case UD_OP_IMM:
+ if (syn_cast) opr_cast(u, op);
+ switch (op->size) {
+ case 8: mkasm(u, "0x%x", op->lval.ubyte); break;
+ case 16: mkasm(u, "0x%x", op->lval.uword); break;
+ case 32: mkasm(u, "0x%lx", op->lval.udword); break;
+ case 64: mkasm(u, "0x" FMT64 "x", op->lval.uqword); break;
+ default: break;
+ }
+ break;
+
+ case UD_OP_JIMM:
+ if (syn_cast) opr_cast(u, op);
+ switch (op->size) {
+ case 8:
+ mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte);
+ break;
+ case 16:
+ mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword);
+ break;
+ case 32:
+ mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword);
+ break;
+ default:break;
+ }
+ break;
+
+ case UD_OP_PTR:
+ switch (op->size) {
+ case 32:
+ mkasm(u, "word 0x%x:0x%x", op->lval.ptr.seg,
+ op->lval.ptr.off & 0xFFFF);
+ break;
+ case 48:
+ mkasm(u, "dword 0x%x:0x%lx", op->lval.ptr.seg,
+ op->lval.ptr.off);
+ break;
+ }
+ break;
+
+ case UD_OP_CONST:
+ if (syn_cast) opr_cast(u, op);
+ mkasm(u, "%d", op->lval.udword);
+ break;
+
+ default: return;
+ }
+}
+
+/* =============================================================================
+ * translates to intel syntax
+ * =============================================================================
+ */
+extern void ud_translate_intel(struct ud* u)
+{
+ /* -- prefixes -- */
+
+ /* check if P_OSO prefix is used */
+ if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
+ switch (u->dis_mode) {
+ case 16:
+ mkasm(u, "o32 ");
+ break;
+ case 32:
+ case 64:
+ mkasm(u, "o16 ");
+ break;
+ }
+ }
+
+ /* check if P_ASO prefix was used */
+ if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
+ switch (u->dis_mode) {
+ case 16:
+ mkasm(u, "a32 ");
+ break;
+ case 32:
+ mkasm(u, "a16 ");
+ break;
+ case 64:
+ mkasm(u, "a32 ");
+ break;
+ }
+ }
+
+ if (u->pfx_lock)
+ mkasm(u, "lock ");
+ if (u->pfx_rep)
+ mkasm(u, "rep ");
+ if (u->pfx_repne)
+ mkasm(u, "repne ");
+ if (u->implicit_addr && u->pfx_seg)
+ mkasm(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]);
+
+ /* print the instruction mnemonic */
+ mkasm(u, "%s ", ud_lookup_mnemonic(u->mnemonic));
+
+ /* operand 1 */
+ if (u->operand[0].type != UD_NONE) {
+ gen_operand(u, &u->operand[0], u->c1);
+ }
+ /* operand 2 */
+ if (u->operand[1].type != UD_NONE) {
+ mkasm(u, ", ");
+ gen_operand(u, &u->operand[1], u->c2);
+ }
+
+ /* operand 3 */
+ if (u->operand[2].type != UD_NONE) {
+ mkasm(u, ", ");
+ gen_operand(u, &u->operand[2], u->c3);
+ }
+}
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/syn.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/syn.c Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,61 @@
+/* -----------------------------------------------------------------------------
+ * syn.c
+ *
+ * Copyright (c) 2002, 2003, 2004 Vivek Mohan <vivek@sig9.com>
+ * All rights reserved. See (LICENSE)
+ * -----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------
+ * Intel Register Table - Order Matters (types.h)!
+ * -----------------------------------------------------------------------------
+ */
+const char* ud_reg_tab[] =
+{
+ "al", "cl", "dl", "bl",
+ "ah", "ch", "dh", "bh",
+ "spl", "bpl", "sil", "dil",
+ "r8b", "r9b", "r10b", "r11b",
+ "r12b", "r13b", "r14b", "r15b",
+
+ "ax", "cx", "dx", "bx",
+ "sp", "bp", "si", "di",
+ "r8w", "r9w", "r10w", "r11w",
+ "r12w", "r13W" , "r14w", "r15w",
+
+ "eax", "ecx", "edx", "ebx",
+ "esp", "ebp", "esi", "edi",
+ "r8d", "r9d", "r10d", "r11d",
+ "r12d", "r13d", "r14d", "r15d",
+
+ "rax", "rcx", "rdx", "rbx",
+ "rsp", "rbp", "rsi", "rdi",
+ "r8", "r9", "r10", "r11",
+ "r12", "r13", "r14", "r15",
+
+ "es", "cs", "ss", "ds",
+ "fs", "gs",
+
+ "cr0", "cr1", "cr2", "cr3",
+ "cr4", "cr5", "cr6", "cr7",
+ "cr8", "cr9", "cr10", "cr11",
+ "cr12", "cr13", "cr14", "cr15",
+
+ "dr0", "dr1", "dr2", "dr3",
+ "dr4", "dr5", "dr6", "dr7",
+ "dr8", "dr9", "dr10", "dr11",
+ "dr12", "dr13", "dr14", "dr15",
+
+ "mm0", "mm1", "mm2", "mm3",
+ "mm4", "mm5", "mm6", "mm7",
+
+ "st0", "st1", "st2", "st3",
+ "st4", "st5", "st6", "st7",
+
+ "xmm0", "xmm1", "xmm2", "xmm3",
+ "xmm4", "xmm5", "xmm6", "xmm7",
+ "xmm8", "xmm9", "xmm10", "xmm11",
+ "xmm12", "xmm13", "xmm14", "xmm15",
+
+ "rip"
+};
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/syn.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/syn.h Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,27 @@
+/* -----------------------------------------------------------------------------
+ * syn.h
+ *
+ * Copyright (c) 2006, Vivek Mohan <vivek@sig9.com>
+ * All rights reserved. See LICENSE
+ * -----------------------------------------------------------------------------
+ */
+#ifndef UD_SYN_H
+#define UD_SYN_H
+
+#if 0
+#include <stdio.h>
+#include <stdarg.h>
+#endif
+#include "types.h"
+
+extern const char* ud_reg_tab[];
+
+static void mkasm(struct ud* u, const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ u->insn_fill += vsnprintf((char*) u->insn_buffer + u->insn_fill, 64, fmt, ap);
+ va_end(ap);
+}
+
+#endif
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/types.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/types.h Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,186 @@
+/* -----------------------------------------------------------------------------
+ * types.h
+ *
+ * Copyright (c) 2006, Vivek Mohan <vivek@sig9.com>
+ * All rights reserved. See LICENSE
+ * -----------------------------------------------------------------------------
+ */
+#ifndef UD_TYPES_H
+#define UD_TYPES_H
+
+
+#include "../../include/kdbinc.h"
+
+#define FMT64 "%ll"
+#include "itab.h"
+
+/* -----------------------------------------------------------------------------
+ * All possible "types" of objects in udis86. Order is Important!
+ * -----------------------------------------------------------------------------
+ */
+enum ud_type
+{
+ UD_NONE,
+
+ /* 8 bit GPRs */
+ UD_R_AL, UD_R_CL, UD_R_DL, UD_R_BL,
+ UD_R_AH, UD_R_CH, UD_R_DH, UD_R_BH,
+ UD_R_SPL, UD_R_BPL, UD_R_SIL, UD_R_DIL,
+ UD_R_R8B, UD_R_R9B, UD_R_R10B, UD_R_R11B,
+ UD_R_R12B, UD_R_R13B, UD_R_R14B, UD_R_R15B,
+
+ /* 16 bit GPRs */
+ UD_R_AX, UD_R_CX, UD_R_DX, UD_R_BX,
+ UD_R_SP, UD_R_BP, UD_R_SI, UD_R_DI,
+ UD_R_R8W, UD_R_R9W, UD_R_R10W, UD_R_R11W,
+ UD_R_R12W, UD_R_R13W, UD_R_R14W, UD_R_R15W,
+
+ /* 32 bit GPRs */
+ UD_R_EAX, UD_R_ECX, UD_R_EDX, UD_R_EBX,
+ UD_R_ESP, UD_R_EBP, UD_R_ESI, UD_R_EDI,
+ UD_R_R8D, UD_R_R9D, UD_R_R10D, UD_R_R11D,
+ UD_R_R12D, UD_R_R13D, UD_R_R14D, UD_R_R15D,
+
+ /* 64 bit GPRs */
+ UD_R_RAX, UD_R_RCX, UD_R_RDX, UD_R_RBX,
+ UD_R_RSP, UD_R_RBP, UD_R_RSI, UD_R_RDI,
+ UD_R_R8, UD_R_R9, UD_R_R10, UD_R_R11,
+ UD_R_R12, UD_R_R13, UD_R_R14, UD_R_R15,
+
+ /* segment registers */
+ UD_R_ES, UD_R_CS, UD_R_SS, UD_R_DS,
+ UD_R_FS, UD_R_GS,
+
+ /* control registers*/
+ UD_R_CR0, UD_R_CR1, UD_R_CR2, UD_R_CR3,
+ UD_R_CR4, UD_R_CR5, UD_R_CR6, UD_R_CR7,
+ UD_R_CR8, UD_R_CR9, UD_R_CR10, UD_R_CR11,
+ UD_R_CR12, UD_R_CR13, UD_R_CR14, UD_R_CR15,
+
+ /* debug registers */
+ UD_R_DR0, UD_R_DR1, UD_R_DR2, UD_R_DR3,
+ UD_R_DR4, UD_R_DR5, UD_R_DR6, UD_R_DR7,
+ UD_R_DR8, UD_R_DR9, UD_R_DR10, UD_R_DR11,
+ UD_R_DR12, UD_R_DR13, UD_R_DR14, UD_R_DR15,
+
+ /* mmx registers */
+ UD_R_MM0, UD_R_MM1, UD_R_MM2, UD_R_MM3,
+ UD_R_MM4, UD_R_MM5, UD_R_MM6, UD_R_MM7,
+
+ /* x87 registers */
+ UD_R_ST0, UD_R_ST1, UD_R_ST2, UD_R_ST3,
+ UD_R_ST4, UD_R_ST5, UD_R_ST6, UD_R_ST7,
+
+ /* extended multimedia registers */
+ UD_R_XMM0, UD_R_XMM1, UD_R_XMM2, UD_R_XMM3,
+ UD_R_XMM4, UD_R_XMM5, UD_R_XMM6, UD_R_XMM7,
+ UD_R_XMM8, UD_R_XMM9, UD_R_XMM10, UD_R_XMM11,
+ UD_R_XMM12, UD_R_XMM13, UD_R_XMM14, UD_R_XMM15,
+
+ UD_R_RIP,
+
+ /* Operand Types */
+ UD_OP_REG, UD_OP_MEM, UD_OP_PTR, UD_OP_IMM,
+ UD_OP_JIMM, UD_OP_CONST
+};
+
+/* -----------------------------------------------------------------------------
+ * struct ud_operand - Disassembled instruction Operand.
+ * -----------------------------------------------------------------------------
+ */
+struct ud_operand
+{
+ enum ud_type type;
+ uint8_t size;
+ union {
+ int8_t sbyte;
+ uint8_t ubyte;
+ int16_t sword;
+ uint16_t uword;
+ int32_t sdword;
+ uint32_t udword;
+ int64_t sqword;
+ uint64_t uqword;
+
+ struct {
+ uint16_t seg;
+ uint32_t off;
+ } ptr;
+ } lval;
+
+ enum ud_type base;
+ enum ud_type index;
+ uint8_t offset;
+ uint8_t scale;
+};
+
+/* -----------------------------------------------------------------------------
+ * struct ud - The udis86 object.
+ * -----------------------------------------------------------------------------
+ */
+struct ud
+{
+ int (*inp_hook) (struct ud*);
+ uint8_t inp_curr;
+ uint8_t inp_fill;
+ uint8_t inp_ctr;
+ uint8_t* inp_buff;
+ uint8_t* inp_buff_end;
+ uint8_t inp_end;
+ void (*translator)(struct ud*);
+ uint64_t insn_offset;
+ char insn_hexcode[32];
+ char insn_buffer[64];
+ unsigned int insn_fill;
+ uint8_t dis_mode;
+ uint64_t pc;
+ uint8_t vendor;
+ struct map_entry* mapen;
+ enum ud_mnemonic_code mnemonic;
+ struct ud_operand operand[3];
+ uint8_t error;
+ uint8_t pfx_rex;
+ uint8_t pfx_seg;
+ uint8_t pfx_opr;
+ uint8_t pfx_adr;
+ uint8_t pfx_lock;
+ uint8_t pfx_rep;
+ uint8_t pfx_repe;
+ uint8_t pfx_repne;
+ uint8_t pfx_insn;
+ uint8_t default64;
+ uint8_t opr_mode;
+ uint8_t adr_mode;
+ uint8_t br_far;
+ uint8_t br_near;
+ uint8_t implicit_addr;
+ uint8_t c1;
+ uint8_t c2;
+ uint8_t c3;
+ uint8_t inp_cache[256];
+ uint8_t inp_sess[64];
+ struct ud_itab_entry * itab_entry;
+};
+
+/* -----------------------------------------------------------------------------
+ * Type-definitions
+ * -----------------------------------------------------------------------------
+ */
+typedef enum ud_type ud_type_t;
+typedef enum ud_mnemonic_code ud_mnemonic_code_t;
+
+typedef struct ud ud_t;
+typedef struct ud_operand ud_operand_t;
+
+#define UD_SYN_INTEL ud_translate_intel
+#define UD_SYN_ATT ud_translate_att
+#define UD_EOI -1
+#define UD_INP_CACHE_SZ 32
+#define UD_VENDOR_AMD 0
+#define UD_VENDOR_INTEL 1
+
+#define bail_out(ud,error_code) longjmp( (ud)->bailout, error_code )
+#define try_decode(ud) if ( setjmp( (ud)->bailout ) == 0 )
+#define catch_error() else
+
+#endif
diff -r 32034d1914a6 xen/kdb/x86/udis86-1.7/udis86.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/kdb/x86/udis86-1.7/udis86.c Wed Aug 29 14:39:57 2012 -0700
@@ -0,0 +1,156 @@
+/* -----------------------------------------------------------------------------
+ * udis86.c
+ *
+ * Copyright (c) 2004, 2005, 2006, Vivek Mohan <vivek@sig9.com>
+ * All rights reserved. See LICENSE
+ * -----------------------------------------------------------------------------
+ */
+
+#if 0
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+
+#include "input.h"
+#include "extern.h"
+
+/* =============================================================================
+ * ud_init() - Initializes ud_t object.
+ * =============================================================================
+ */
+extern void
+ud_init(struct ud* u)
+{
+ memset((void*)u, 0, sizeof(struct ud));
+ ud_set_mode(u, 16);
+ u->mnemonic = UD_Iinvalid;
+ ud_set_pc(u, 0);
+#ifndef __UD_STANDALONE__
+ ud_set_input_file(u, stdin);
+#endif /* __UD_STANDALONE__ */
+}
+
+/* =============================================================================
+ * ud_disassemble() - disassembles one instruction and returns the number of
+ * bytes disassembled. A zero means end of disassembly.
+ * =============================================================================
+ */
+extern unsigned int
+ud_disassemble(struct ud* u)
+{
+ if (ud_input_end(u))
+ return 0;
+
+
+ u->insn_buffer[0] = u->insn_hexcode[0] = 0;
+
+
+ if (ud_decode(u) == 0)
+ return 0;
+ if (u->translator)
+ u->translator(u);
+ return ud_insn_len(u);
+}
+
+/* =============================================================================
+ * ud_set_mode() - Set Disassemly Mode.
+ * =============================================================================
+ */
+extern void
+ud_set_mode(struct ud* u, uint8_t m)
+{
+ switch(m) {
+ case 16:
+ case 32:
+ case 64: u->dis_mode = m ; return;
+ default: u->dis_mode = 16; return;
+ }
+}
+
+/* =============================================================================
+ * ud_set_vendor() - Set vendor.
+ * =============================================================================
+ */
+extern void
+ud_set_vendor(struct ud* u, unsigned v)
+{
+ switch(v) {
+ case UD_VENDOR_INTEL:
+ u->vendor = v;
+ break;
+ default:
+ u->vendor = UD_VENDOR_AMD;
+ }
+}
+
+/* =============================================================================
+ * ud_set_pc() - Sets code origin.
+ * =============================================================================
+ */
+extern void
+ud_set_pc(struct ud* u, uint64_t o)
+{
+ u->pc = o;
+}
+
+/* =============================================================================
+ * ud_set_syntax() - Sets the output syntax.
+ * =============================================================================
+ */
+extern void
+ud_set_syntax(struct ud* u, void (*t)(struct ud*))
+{
+ u->translator = t;
+}
+
+/* =============================================================================
+ * ud_insn() - returns the disassembled instruction
+ * =============================================================================
+ */
+extern char*
+ud_insn_asm(struct ud* u)
+{
+ return u->insn_buffer;
+}
+
+/* =============================================================================
+ * ud_insn_offset() - Returns the offset.
+ * =============================================================================
+ */
+extern uint64_t
+ud_insn_off(struct ud* u)
+{
+ return u->insn_offset;
+}
+
+
+/* =============================================================================
+ * ud_insn_hex() - Returns hex form of disassembled instruction.
+ * =============================================================================
+ */
+extern char*
+ud_insn_hex(struct ud* u)
+{
+ return u->insn_hexcode;
+}
+
+/* =============================================================================
+ * ud_insn_ptr() - Returns code disassembled.
+ * =============================================================================
+ */
+extern uint8_t*
+ud_insn_ptr(struct ud* u)
+{
+ return u->inp_sess;
+}
+
+/* =============================================================================
+ * ud_insn_len() - Returns the count of bytes disassembled.
+ * =============================================================================
+ */
+extern unsigned int
+ud_insn_len(struct ud* u)
+{
+ return u->inp_ctr;
+}
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: xen debugger (kdb/xdb/hdb) patch for c/s 25467
2012-08-29 21:35 xen debugger (kdb/xdb/hdb) patch for c/s 25467 Mukesh Rathor
2012-08-29 21:41 ` Mukesh Rathor
@ 2012-08-29 23:18 ` Keir Fraser
1 sibling, 0 replies; 5+ messages in thread
From: Keir Fraser @ 2012-08-29 23:18 UTC (permalink / raw)
To: Mukesh Rathor, Xen-devel, msw; +Cc: Ben Guthro
On 29/08/2012 22:35, "Mukesh Rathor" <mukesh.rathor@oracle.com> wrote:
> Hi Guys,
>
> Thanks for the interest in the xen hypervisor debugger, prev known as
> kdb. Btw. I'm gonna rename it to xdb for xen-debugger or hdb for
> hypervisor debugger. KDB is confusing people with linux kdb debugger
> and I often get emails where people think they need to apply linux kdb
> patch also...
>
> Anyways, attaching patch that is cleaned up of my debug code that I
> accidentally left in prev posting. Should apply cleanly to c/s 25467.
>
> JFYI... http://xenbits.xen.org/ext/debuggers.hg/ has gotten outdated,
> I wasn't sure if anyone was even looking at it. But, it looks like
> there is much interest, so I will just submit patch to Keir for
> his feedback on merging it in xen.
>
> Please voice your opinion here. Good seeing all at the summit :).
Split off the support bits you need scattered into Xen from the main bulk of
the debugger. Then we can review and apply those trickiest bits first.
-- Keir
> Thanks,
> Mukesh
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: xen debugger (kdb/xdb/hdb) patch for c/s 25467
2012-08-29 21:41 ` Mukesh Rathor
@ 2012-09-05 16:02 ` Ben Guthro
2012-09-05 18:52 ` Mukesh Rathor
0 siblings, 1 reply; 5+ messages in thread
From: Ben Guthro @ 2012-09-05 16:02 UTC (permalink / raw)
To: Mukesh Rathor; +Cc: Xen-devel, msw
FYI - I applied this against the tip, and turned it on (and debug off)
- but I get link errors:
ld -melf_x86_64 -T xen.lds -N prelink.o \
/data/home/bguthro/dev/orc-newdev.git/orc-xen/xen-4.2/xen/common/symbols-dummy.o
-o /data/home/bguthro/dev/orc-newdev.git/orc-xen/xen-4.2/xen/.xen-syms.0
prelink.o: In function `kdb_cmdf_f':
/data/home/bguthro/dev/orc-newdev.git/orc-xen/xen-4.2/xen/kdb/kdb_cmds.c:510:
undefined reference to `show_trace'
/data/home/bguthro/dev/orc-newdev.git/orc-xen/xen-4.2/xen/kdb/kdb_cmds.c:510:(.text+0x11f6b9):
relocation truncated to fit: R_X86_64_PC32 against undefined symbol
`show_trace'
ld: /data/home/bguthro/dev/orc-newdev.git/orc-xen/xen-4.2/xen/.xen-syms.0:
hidden symbol `show_trace' isn't defined
ld: final link failed: Bad value
make[5]: *** [/data/home/bguthro/dev/orc-newdev.git/orc-xen/xen-4.2/xen/xen-syms]
Error 1
make[5]: Leaving directory
`/data/home/bguthro/dev/orc-newdev.git/orc-xen/xen-4.2/xen/arch/x86'
make[4]: *** [/data/home/bguthro/dev/orc-newdev.git/orc-xen/xen-4.2/xen/xen]
Error 2
On Wed, Aug 29, 2012 at 5:41 PM, Mukesh Rathor <mukesh.rathor@oracle.com> wrote:
> On Wed, 29 Aug 2012 14:35:12 -0700
> Mukesh Rathor <mukesh.rathor@oracle.com> wrote:
>
>
>>
>> Anyways, attaching patch that is cleaned up of my debug code that I
>> accidentally left in prev posting. Should apply cleanly to c/s 25467.
>
> really attaching this time :).
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: xen debugger (kdb/xdb/hdb) patch for c/s 25467
2012-09-05 16:02 ` Ben Guthro
@ 2012-09-05 18:52 ` Mukesh Rathor
0 siblings, 0 replies; 5+ messages in thread
From: Mukesh Rathor @ 2012-09-05 18:52 UTC (permalink / raw)
To: Ben Guthro; +Cc: Xen-devel, msw
On Wed, 5 Sep 2012 12:02:13 -0400
Ben Guthro <ben@guthro.net> wrote:
> FYI - I applied this against the tip, and turned it on (and debug off)
> - but I get link errors:
>
> ld -melf_x86_64 -T xen.lds -N prelink.o \
> /data/home/bguthro/dev/orc-newdev.git/orc-xen/xen-4.2/xen/common/symbols-dummy.o
> -o /data/home/bguthro/dev/orc-newdev.git/orc-xen/xen-4.2/xen/.xen-syms.0
> prelink.o: In function `kdb_cmdf_f':
> /data/home/bguthro/dev/orc-newdev.git/orc-xen/xen-4.2/xen/kdb/kdb_cmds.c:510:
> undefined reference to `show_trace'
> /data/home/bguthro/dev/orc-newdev.git/orc-xen/xen-4.2/xen/kdb/kdb_cmds.c:510:(.text+0x11f6b9):
> relocation truncated to fit: R_X86_64_PC32 against undefined symbol
> `show_trace'
> ld: /data/home/bguthro/dev/orc-newdev.git/orc-xen/xen-4.2/xen/.xen-syms.0:
> hidden symbol `show_trace' isn't defined
> ld: final link failed: Bad value
It's prob static. Just un-static it :). Missed in patch because we
might have it that way here already in our tree.
LMK. thanks. Mukesh
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-09-05 18:52 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-29 21:35 xen debugger (kdb/xdb/hdb) patch for c/s 25467 Mukesh Rathor
2012-08-29 21:41 ` Mukesh Rathor
2012-09-05 16:02 ` Ben Guthro
2012-09-05 18:52 ` Mukesh Rathor
2012-08-29 23:18 ` Keir Fraser
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.