Skip to contentSkip to conversation

32bit gdbserver-xen/libxc to debug 64bit guest

PATCH In review Mukesh Rathor 2 participants 4 messages Nov 2, 2007 – Nov 3, 2007

lore
Share & tools
lore
#0 lore raw

cover 32bit gdbserver-xen/libxc to debug 64bit guest

Hi Folks,

Please allow me to submit my first patch set. The main purpose is to allow a
32bit dom0 to support debug of a 64bit guest via gdbserver-xen. This also fixes gdbserver-xen not attaching to a 32 PAE guest.

Description:
At present libxc and gdbserver-xen are compiled on the same architecture
that dom0 is, ie, 32bit or 64bit. As a result, when 32bit binary is run on dom0 to attach to a 64bit guest, the data structures are incorrect, and the process fails. This patch addresses that by :

- introducing a new compiler directive, _GDB_CROSS_COMP that will create a
32bit binary on an x86_64 system (by using -m32).

- including x86_64 data structures if the above is defined.

- changing long's to long long's in relevant cases if the above is defined.

- linking libxc statically to the gdbserver-xen binary if above is defined.

The process is explained in the debugger/gdb/README file. The patch set is divided in three parts:
- part 0 : description + libxc/xen related changes
- part 1 : files changed in gdbserver xen-sparse tree.
- part 2 : new files in gdbserver xen-sparse tree.

Please note, to achieve the above, an ifdef had to be added to user.h. This forced it to be copied locally. As a result, files that included this header, had also to be created/copied in the xen-sparse tree from the gdbserver tree to include local user.h.

Finally, mkbuildtree fixes "find" warning in the new version, and is not related to the patch objectives.

In summary, files changed are:
config/x86_64.mk
tools/libxc/xc_ptrace.c
tools/libxc/xenctrl.h
tools/libxc/xc_ptrace.h
tools/libxc/xg_private.h
xen/include/public/arch-x86/xen.h
xen/include/public/arch-x86/xen-x86_32.h
xen/include/public/foreign/mkheader.py
xen/include/public/domctl.h

tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/Makefile.in tools/debugger/gdb/gdb-6.2.1-xen-sparse/mkbuildtree tools/debugger/gdb/gdbbuild
tools/debugger/gdb/README

tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-x86-64-low.c tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdb_proc_service.h tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/amd64-linux-nat.c tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/linux-proc.c tools/debugger/gdb/gdb-6.2.1-xen-sparse/bfd/elf.c tools/debugger/gdb/gdb-6.2.1-xen-sparse/include/user.h

Testing:
After the above patch, I was able to build three binaries and attach to
32bit, 32bit PAE, and 64bit guests on a 32bit dom0, and was able to set breakpoints, see stacks, step, walk the task list, and set correct 32bit/64bit values for global long variables.

Thanks a lot,
Mukesh Rathor

config/x86_64.mk +2 -0
diff -uNpr xen-3.1.1-ovs.orig/config/x86_64.mk xen-3.1.1-ovs.new/config/x86_64.mk
@@ -8,7 +8,9 @@ CONFIG_MIGRATE := y
 CONFIG_XCUTILS := y
 CONFIG_IOEMU := y
 
+ifeq "$(findstring _GDB_CROSS_COMP, $(CFLAGS))" ""
 CFLAGS += -m64
+endif
 LIBDIR = $(LIB64DIR)
 
 # Use only if calling $(LD) directly.
tools/libxc/xc_ptrace.c +61 -63

295 lines not on this page · raw message

tools/libxc/xc_ptrace.h +35 -28

71 lines not on this page · raw message

tools/libxc/xenctrl.h +9 -3
diff -uNpr xen-3.1.1-ovs.orig/tools/libxc/xenctrl.h xen-3.1.1-ovs.new/tools/libxc/xenctrl.h
@@ -123,18 +123,24 @@ typedef struct xc_core_header {
 #include <sys/ptrace.h>
 #include <thread_db.h>
 
+#ifdef _GDB_CROSS_COMP
+#define guest_va_type unsigned long long 
+#else
+#define guest_va_type unsigned long 
+#endif
+
 typedef void (*thr_ev_handler_t)(long);
 
 void xc_register_event_handler(
     thr_ev_handler_t h,
     td_event_e e);
 
-long xc_ptrace(
+guest_va_type xc_ptrace(
     int xc_handle,
     enum __ptrace_request request,
     uint32_t  domid,
-    long addr,
-    long data);
+    guest_va_type addr,
+    guest_va_type edata);
 
 int xc_waitdomain(
     int xc_handle,
tools/libxc/xg_private.h +1 -1
diff -uNpr xen-3.1.1-ovs.orig/tools/libxc/xg_private.h xen-3.1.1-ovs.new/tools/libxc/xg_private.h
@@ -119,7 +119,7 @@ typedef l4_pgentry_64_t l4_pgentry_t;
 #define l3_table_offset_x86_64(_a) \
   (((_a) >> L3_PAGETABLE_SHIFT_X86_64) & (L3_PAGETABLE_ENTRIES_X86_64 - 1))
 #define l4_table_offset_x86_64(_a) \
-  (((_a) >> L4_PAGETABLE_SHIFT_X86_64) & (L4_PAGETABLE_ENTRIES_X86_64 - 1))
+  ((((uint64_t)_a) >> L4_PAGETABLE_SHIFT_X86_64) & ((uint64_t)L4_PAGETABLE_ENTRIES_X86_64 - 1))
 
 #if defined(__i386__)
 #define l1_table_offset(_a) l1_table_offset_i386(_a)
xen/include/public/arch-x86/xen.h +50 -20

115 lines not on this page · raw message

xen/include/public/arch-x86/xen-x86_32.h +0 -17
diff -uNpr xen-3.1.1-ovs.orig/xen/include/public/arch-x86/xen-x86_32.h xen-3.1.1-ovs.new/xen/include/public/arch-x86/xen-x86_32.h
@@ -105,23 +105,6 @@
 #define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START)
 #endif
 
-/* 32-/64-bit invariability for control interfaces (domctl/sysctl). */
-#if defined(__XEN__) || defined(__XEN_TOOLS__)
-#undef __DEFINE_XEN_GUEST_HANDLE
-#define __DEFINE_XEN_GUEST_HANDLE(name, type)                   \
-    typedef struct { type *p; }                                 \
-        __guest_handle_ ## name;                                \
-    typedef struct { union { type *p; uint64_aligned_t q; }; }  \
-        __guest_handle_64_ ## name
-#undef set_xen_guest_handle
-#define set_xen_guest_handle(hnd, val)                      \
-    do { if ( sizeof(hnd) == 8 ) *(uint64_t *)&(hnd) = 0;   \
-         (hnd).p = val;                                     \
-    } while ( 0 )
-#define uint64_aligned_t uint64_t __attribute__((aligned(8)))
-#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name
-#endif
-
 #ifndef __ASSEMBLY__
 
 struct cpu_user_regs {
xen/include/public/domctl.h +3 -0
diff -uNpr xen-3.1.1-ovs.orig/xen/include/public/domctl.h xen-3.1.1-ovs.new/xen/include/public/domctl.h
@@ -437,6 +437,9 @@ struct xen_domctl {
     uint32_t cmd;
     uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
     domid_t  domain;
+#ifdef _GDB_CROSS_COMP
+    int      pad;
+#endif
     union {
         struct xen_domctl_createdomain      createdomain;
         struct xen_domctl_getdomaininfo     getdomaininfo;
xen/include/public/foreign/mkheader.py +2 -0
diff -uNpr xen-3.1.1-ovs.orig/xen/include/public/foreign/mkheader.py xen-3.1.1-ovs.new/xen/include/public/foreign/mkheader.py
@@ -21,6 +21,7 @@ inttypes["x86_32"] = {
     "unsigned long" : "uint32_t",
     "long"          : "uint32_t",
     "xen_pfn_t"     : "uint32_t",
+    "crosscomp_type": "uint32_t",
 };
 header["x86_32"] = """
 #define __i386___X86_32 1
@@ -35,6 +36,7 @@ inttypes["x86_64"] = {
     "unsigned long" : "__align8__ uint64_t",
     "long"          : "__align8__ uint64_t",
     "xen_pfn_t"     : "__align8__ uint64_t",
+    "crosscomp_type": "__align8__ uint64_t",
 };
 header["x86_64"] = """
 #ifdef __GNUC__

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

#1 lore raw
Quoted 4 lines · Mukesh Rathor

Please note, to achieve the above, an ifdef had to be added to user.h. This forced it to be copied locally. As a result, files that included this header, had also to be created/copied in the xen-sparse tree from the gdbserver tree to include local user.h.

The sparse tree should be overlaid a normal full gdbserver tree, so user.h should be in the same place whether you've modified it or not. So I don;t see why you'd need to pull in every file that includes user.h.

The 32-on-64 compat layer inside Xen already builds 32-bit versions of structures when building 64-bit Xen. I think they're under include/compat/ or something like that. It would make sense to make use of those rather than hack up the original headers with explicit compat types.

-- Keir

#2 lore raw
Quoted 10 lines · Keir Fraser
Quoted 4 lines · Mukesh Rathor

Please note, to achieve the above, an ifdef had to be added to user.h. This forced it to be copied locally. As a result, files that included this header, had also to be created/copied in the xen-sparse tree from the gdbserver tree to include local user.h.

The sparse tree should be overlaid a normal full gdbserver tree, so user.h should be in the same place whether you've modified it or not. So I don;t see why you'd need to pull in every file that includes user.h.

You are correct, I fixed it and will resubmit the patch, I guess with a new email.

Quoted 4 lines

The 32-on-64 compat layer inside Xen already builds 32-bit versions of structures when building 64-bit Xen. I think they're under include/compat/ or something like that. It would make sense to make use of those rather than hack up the original headers with explicit compat types.

I noticed that. But I am looking for 64bit struct versions when building 32bit libxc. I figured coming with similar macros the other way would make the whole think too complex, so adding explicit compat types made sense. Besides, we kinda needed a debugger soon :).

Quoted 1 line

-- Keir

Thanks for your feedback and your time.

Mukesh Rathor
PS: I'll be offline for a while. I can come up with enhancements in future, or make further fixes, after I come back early Dec.

#3 lore raw
Quoted 6 lines · Mukesh Rathor
Quoted 3 lines

The sparse tree should be overlaid a normal full gdbserver tree, so user.h should be in the same place whether you've modified it or not. So I don;t see why you'd need to pull in every file that includes user.h.

You are correct, I fixed it and will resubmit the patch, I guess with a new email.

The new patches look much better!

Quoted 9 lines
Quoted 4 lines

The 32-on-64 compat layer inside Xen already builds 32-bit versions of structures when building 64-bit Xen. I think they're under include/compat/ or something like that. It would make sense to make use of those rather than hack up the original headers with explicit compat types.

I noticed that. But I am looking for 64bit struct versions when building 32bit libxc. I figured coming with similar macros the other way would make the whole think too complex, so adding explicit compat types made sense. Besides, we kinda needed a debugger soon :).

Well, given we can build 64-bit domains from 32-bit dom0, I'm pretty sure we can work out how to interrogate their state from 32-bit dom0, without needing to modify any of the public headers. I'm sure we can clean this up and get the improvements in without too much trouble.

-- Keir