diff mbox series

[v3,15/22] golang/xenlight: begin C to Go type marshaling

Message ID 3c638e0022455d8c670af7aa0ad5c98305c91221.1575990937.git.rosbrookn@ainfosec.com (mailing list archive)
State Superseded
Headers show
Series generated Go libxl bindings using IDL | expand

Commit Message

Nick Rosbrook Dec. 10, 2019, 3:47 p.m. UTC
From: Nick Rosbrook <rosbrookn@ainfosec.com>

Begin implementation of fromC marshaling functions for generated struct
types. This includes support for converting fields that are basic
primitive types such as string and integer types, nested anonymous
structs, nested libxl structs, and libxl built-in types.

This patch does not implement conversion of arrays or keyed unions.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Changes in v2:
- Add Makefile changes for helpers.gen.go.
- Re-generate helpers.gen.go to include libxl changes after rebase.
Changes in v3:
- Break out field copying/type conversion code into its own function
  called xenlight_golang_convert_from_C to allow that code to be easily
  re-used.
- Use consistent style for calling fromC on struct fields that require
  it. Namely, do not use a temporary variable - call fromC directly on
  the struct field.
---
 tools/golang/xenlight/Makefile       |   2 +
 tools/golang/xenlight/gengotypes.py  | 118 ++++
 tools/golang/xenlight/helpers.gen.go | 901 +++++++++++++++++++++++++++
 tools/golang/xenlight/xenlight.go    | 111 +---
 4 files changed, 1032 insertions(+), 100 deletions(-)
 create mode 100644 tools/golang/xenlight/helpers.gen.go

Comments

George Dunlap Dec. 16, 2019, 5:56 p.m. UTC | #1
On 12/10/19 3:47 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Begin implementation of fromC marshaling functions for generated struct
> types. This includes support for converting fields that are basic
> primitive types such as string and integer types, nested anonymous
> structs, nested libxl structs, and libxl built-in types.
> 
> This patch does not implement conversion of arrays or keyed unions.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
> ---
> Changes in v2:
> - Add Makefile changes for helpers.gen.go.
> - Re-generate helpers.gen.go to include libxl changes after rebase.
> Changes in v3:
> - Break out field copying/type conversion code into its own function
>   called xenlight_golang_convert_from_C to allow that code to be easily
>   re-used.
> - Use consistent style for calling fromC on struct fields that require
>   it. Namely, do not use a temporary variable - call fromC directly on
>   the struct field.

Looks good!  One minor comment...

> ---
>  tools/golang/xenlight/Makefile       |   2 +
>  tools/golang/xenlight/gengotypes.py  | 118 ++++
>  tools/golang/xenlight/helpers.gen.go | 901 +++++++++++++++++++++++++++
>  tools/golang/xenlight/xenlight.go    | 111 +---
>  4 files changed, 1032 insertions(+), 100 deletions(-)
>  create mode 100644 tools/golang/xenlight/helpers.gen.go
> 
> diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
> index 681f32c234..07b8896e5b 100644
> --- a/tools/golang/xenlight/Makefile
> +++ b/tools/golang/xenlight/Makefile
> @@ -19,6 +19,7 @@ $(XEN_GOPATH)/src/$(XEN_GOCODE_URL)/xenlight/: %.gen.go
>  	$(INSTALL_DIR) $(XEN_GOPATH)$(GOXL_PKG_DIR)
>  	$(INSTALL_DATA) xenlight.go $(XEN_GOPATH)$(GOXL_PKG_DIR)
>  	$(INSTALL_DATA) types.gen.go $(XEN_GOPATH)$(GOXL_PKG_DIR)
> +	$(INSTALL_DATA) helpers.gen.go $(XEN_GOPATH)$(GOXL_PKG_DIR)



I'll have to edit this stanza on check-in to depend on helpers.gen.go
directly; with that:

Reviewed-by: George Dunlap <george.dunlap@citrix.com>
diff mbox series

Patch

diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
index 681f32c234..07b8896e5b 100644
--- a/tools/golang/xenlight/Makefile
+++ b/tools/golang/xenlight/Makefile
@@ -19,6 +19,7 @@  $(XEN_GOPATH)/src/$(XEN_GOCODE_URL)/xenlight/: %.gen.go
 	$(INSTALL_DIR) $(XEN_GOPATH)$(GOXL_PKG_DIR)
 	$(INSTALL_DATA) xenlight.go $(XEN_GOPATH)$(GOXL_PKG_DIR)
 	$(INSTALL_DATA) types.gen.go $(XEN_GOPATH)$(GOXL_PKG_DIR)
+	$(INSTALL_DATA) helpers.gen.go $(XEN_GOPATH)$(GOXL_PKG_DIR)
 
 %.gen.go: gengotypes.py $(XEN_ROOT)/tools/libxl/libxl_types.idl $(XEN_ROOT)/tools/libxl/idl.py
 	XEN_ROOT=$(XEN_ROOT) $(PYTHON) gengotypes.py ../../libxl/libxl_types.idl
@@ -39,6 +40,7 @@  install: build
 	$(INSTALL_DIR) $(DESTDIR)$(GOXL_INSTALL_DIR)
 	$(INSTALL_DATA) $(XEN_GOPATH)$(GOXL_PKG_DIR)xenlight.go $(DESTDIR)$(GOXL_INSTALL_DIR)
 	$(INSTALL_DATA) $(XEN_GOPATH)$(GOXL_PKG_DIR)types.gen.go $(DESTDIR)$(GOXL_INSTALL_DIR)
+	$(INSTALL_DATA) $(XEN_GOPATH)$(GOXL_PKG_DIR)helpers.gen.go $(DESTDIR)$(GOXL_INSTALL_DIR)
 
 .PHONY: uninstall
 	rm -rf $(DESTDIR)$(GOXL_INSTALL_DIR)
diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py
index 8963b14eee..1fe56179e2 100644
--- a/tools/golang/xenlight/gengotypes.py
+++ b/tools/golang/xenlight/gengotypes.py
@@ -18,6 +18,12 @@  builtin_type_names = {
     idl.uint64.typename: 'uint64',
 }
 
+# Some go keywords that conflict with field names in libxl structs.
+go_keywords = ['type', 'func']
+
+go_builtin_types = ['bool', 'string', 'int', 'byte',
+                    'uint16', 'uint32', 'uint64']
+
 def xenlight_golang_generate_types(path = None, types = None, comment = None):
     """
     Generate a .go file (types.gen.go by default)
@@ -176,6 +182,116 @@  def xenlight_golang_define_union(ty = None, structname = ''):
 
     return (s,extras)
 
+def xenlight_golang_generate_helpers(path = None, types = None, comment = None):
+    """
+    Generate a .go file (helpers.gen.go by default)
+    that contains helper functions for marshaling between
+    C and Go types.
+    """
+    if path is None:
+        path = 'helpers.gen.go'
+
+    with open(path, 'w') as f:
+        if comment is not None:
+            f.write(comment)
+        f.write('package xenlight\n')
+
+        # Cgo preamble
+        f.write('/*\n')
+        f.write('#cgo LDFLAGS: -lxenlight\n')
+        f.write('#include <stdlib.h>\n')
+        f.write('#include <libxl.h>\n')
+        f.write('\n')
+
+        f.write('*/\nimport "C"\n')
+
+        for ty in types:
+            if not isinstance(ty, idl.Struct):
+                continue
+
+            f.write(xenlight_golang_define_from_C(ty))
+            f.write('\n')
+
+    go_fmt(path)
+
+def xenlight_golang_define_from_C(ty = None):
+    """
+    Define the fromC marshaling function for the type
+    represented by ty.
+    """
+    func = 'func (x *{}) fromC(xc *C.{}) error {{\n {} \n return nil}}\n'
+
+    goname = xenlight_golang_fmt_name(ty.typename)
+    cname  = ty.typename
+
+    body = ''
+
+    for f in ty.fields:
+        if f.type.typename is not None:
+            if isinstance(f.type, idl.Array):
+                # TODO
+                continue
+
+            body += xenlight_golang_convert_from_C(f)
+
+        elif isinstance(f.type, idl.Struct):
+            # Go through the fields of the anonymous nested struct.
+            for nf in f.type.fields:
+                body += xenlight_golang_convert_from_C(nf,outer_name=f.name)
+
+        elif isinstance(f.type, idl.KeyedUnion):
+            pass
+
+        else:
+            raise Exception('type {} not supported'.format(f.type))
+
+    return func.format(goname, cname, body)
+
+def xenlight_golang_convert_from_C(ty = None, outer_name = None):
+    """
+    Returns a line of Go code that converts the C type represented
+    by ty to its corresponding Go type.
+
+    If outer_name is set, the type is treated as nested within another field
+    named outer_name.
+    """
+    s = ''
+
+    gotypename = xenlight_golang_fmt_name(ty.type.typename)
+    goname     = xenlight_golang_fmt_name(ty.name)
+    cname      = ty.name
+
+    # In cgo, C names that conflict with Go keywords can be
+    # accessed by prepending an underscore to the name.
+    if cname in go_keywords:
+        cname = '_' + cname
+
+    # If outer_name is set, treat this as nested.
+    if outer_name is not None:
+        goname = '{}.{}'.format(xenlight_golang_fmt_name(outer_name), goname)
+        cname  = '{}.{}'.format(outer_name, cname)
+
+    # Types that satisfy this condition can be easily casted or
+    # converted to a Go builtin type.
+    is_castable = (ty.type.json_parse_type == 'JSON_INTEGER' or
+                   isinstance(ty.type, idl.Enumeration) or
+                   gotypename in go_builtin_types)
+
+    if not is_castable:
+        # If the type is not castable, we need to call its fromC
+        # function.
+        s += 'if err := x.{}.fromC(&xc.{});'.format(goname,cname)
+        s += 'err != nil {\n return err \n}\n'
+
+    elif gotypename == 'string':
+        # Use the cgo helper for converting C strings.
+        s += 'x.{} = C.GoString(xc.{})\n'.format(goname, cname)
+
+    else:
+        s += 'x.{} = {}(xc.{})\n'.format(goname, gotypename, cname)
+
+    return s
+
 def xenlight_golang_fmt_name(name, exported = True):
     """
     Take a given type name and return an
@@ -218,3 +334,5 @@  if __name__ == '__main__':
 
     xenlight_golang_generate_types(types=types,
                                    comment=header_comment)
+    xenlight_golang_generate_helpers(types=types,
+                                     comment=header_comment)
diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go
new file mode 100644
index 0000000000..576aebcf6d
--- /dev/null
+++ b/tools/golang/xenlight/helpers.gen.go
@@ -0,0 +1,901 @@ 
+// DO NOT EDIT.
+//
+// This file is generated by:
+// gengotypes.py ../../libxl/libxl_types.idl
+//
+package xenlight
+
+/*
+#cgo LDFLAGS: -lxenlight
+#include <stdlib.h>
+#include <libxl.h>
+
+*/
+import "C"
+
+func (x *IoportRange) fromC(xc *C.libxl_ioport_range) error {
+	x.First = uint32(xc.first)
+	x.Number = uint32(xc.number)
+
+	return nil
+}
+
+func (x *IomemRange) fromC(xc *C.libxl_iomem_range) error {
+	x.Start = uint64(xc.start)
+	x.Number = uint64(xc.number)
+	x.Gfn = uint64(xc.gfn)
+
+	return nil
+}
+
+func (x *VgaInterfaceInfo) fromC(xc *C.libxl_vga_interface_info) error {
+	x.Kind = VgaInterfaceType(xc.kind)
+
+	return nil
+}
+
+func (x *VncInfo) fromC(xc *C.libxl_vnc_info) error {
+	if err := x.Enable.fromC(&xc.enable); err != nil {
+		return err
+	}
+	x.Listen = C.GoString(xc.listen)
+	x.Passwd = C.GoString(xc.passwd)
+	x.Display = int(xc.display)
+	if err := x.Findunused.fromC(&xc.findunused); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (x *SpiceInfo) fromC(xc *C.libxl_spice_info) error {
+	if err := x.Enable.fromC(&xc.enable); err != nil {
+		return err
+	}
+	x.Port = int(xc.port)
+	x.TlsPort = int(xc.tls_port)
+	x.Host = C.GoString(xc.host)
+	if err := x.DisableTicketing.fromC(&xc.disable_ticketing); err != nil {
+		return err
+	}
+	x.Passwd = C.GoString(xc.passwd)
+	if err := x.AgentMouse.fromC(&xc.agent_mouse); err != nil {
+		return err
+	}
+	if err := x.Vdagent.fromC(&xc.vdagent); err != nil {
+		return err
+	}
+	if err := x.ClipboardSharing.fromC(&xc.clipboard_sharing); err != nil {
+		return err
+	}
+	x.Usbredirection = int(xc.usbredirection)
+	x.ImageCompression = C.GoString(xc.image_compression)
+	x.StreamingVideo = C.GoString(xc.streaming_video)
+
+	return nil
+}
+
+func (x *SdlInfo) fromC(xc *C.libxl_sdl_info) error {
+	if err := x.Enable.fromC(&xc.enable); err != nil {
+		return err
+	}
+	if err := x.Opengl.fromC(&xc.opengl); err != nil {
+		return err
+	}
+	x.Display = C.GoString(xc.display)
+	x.Xauthority = C.GoString(xc.xauthority)
+
+	return nil
+}
+
+func (x *Dominfo) fromC(xc *C.libxl_dominfo) error {
+	if err := x.Uuid.fromC(&xc.uuid); err != nil {
+		return err
+	}
+	x.Domid = Domid(xc.domid)
+	x.Ssidref = uint32(xc.ssidref)
+	x.SsidLabel = C.GoString(xc.ssid_label)
+	x.Running = bool(xc.running)
+	x.Blocked = bool(xc.blocked)
+	x.Paused = bool(xc.paused)
+	x.Shutdown = bool(xc.shutdown)
+	x.Dying = bool(xc.dying)
+	x.NeverStop = bool(xc.never_stop)
+	x.ShutdownReason = ShutdownReason(xc.shutdown_reason)
+	x.OutstandingMemkb = uint64(xc.outstanding_memkb)
+	x.CurrentMemkb = uint64(xc.current_memkb)
+	x.SharedMemkb = uint64(xc.shared_memkb)
+	x.PagedMemkb = uint64(xc.paged_memkb)
+	x.MaxMemkb = uint64(xc.max_memkb)
+	x.CpuTime = uint64(xc.cpu_time)
+	x.VcpuMaxId = uint32(xc.vcpu_max_id)
+	x.VcpuOnline = uint32(xc.vcpu_online)
+	x.Cpupool = uint32(xc.cpupool)
+	x.DomainType = DomainType(xc.domain_type)
+
+	return nil
+}
+
+func (x *Cpupoolinfo) fromC(xc *C.libxl_cpupoolinfo) error {
+	x.Poolid = uint32(xc.poolid)
+	x.PoolName = C.GoString(xc.pool_name)
+	x.Sched = Scheduler(xc.sched)
+	x.NDom = uint32(xc.n_dom)
+	if err := x.Cpumap.fromC(&xc.cpumap); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (x *Channelinfo) fromC(xc *C.libxl_channelinfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+	x.Evtch = int(xc.evtch)
+	x.Rref = int(xc.rref)
+
+	return nil
+}
+
+func (x *Vminfo) fromC(xc *C.libxl_vminfo) error {
+	if err := x.Uuid.fromC(&xc.uuid); err != nil {
+		return err
+	}
+	x.Domid = Domid(xc.domid)
+
+	return nil
+}
+
+func (x *VersionInfo) fromC(xc *C.libxl_version_info) error {
+	x.XenVersionMajor = int(xc.xen_version_major)
+	x.XenVersionMinor = int(xc.xen_version_minor)
+	x.XenVersionExtra = C.GoString(xc.xen_version_extra)
+	x.Compiler = C.GoString(xc.compiler)
+	x.CompileBy = C.GoString(xc.compile_by)
+	x.CompileDomain = C.GoString(xc.compile_domain)
+	x.CompileDate = C.GoString(xc.compile_date)
+	x.Capabilities = C.GoString(xc.capabilities)
+	x.Changeset = C.GoString(xc.changeset)
+	x.VirtStart = uint64(xc.virt_start)
+	x.Pagesize = int(xc.pagesize)
+	x.Commandline = C.GoString(xc.commandline)
+	x.BuildId = C.GoString(xc.build_id)
+
+	return nil
+}
+
+func (x *DomainCreateInfo) fromC(xc *C.libxl_domain_create_info) error {
+	x.Type = DomainType(xc._type)
+	if err := x.Hap.fromC(&xc.hap); err != nil {
+		return err
+	}
+	if err := x.Oos.fromC(&xc.oos); err != nil {
+		return err
+	}
+	x.Ssidref = uint32(xc.ssidref)
+	x.SsidLabel = C.GoString(xc.ssid_label)
+	x.Name = C.GoString(xc.name)
+	if err := x.Uuid.fromC(&xc.uuid); err != nil {
+		return err
+	}
+	if err := x.Xsdata.fromC(&xc.xsdata); err != nil {
+		return err
+	}
+	if err := x.Platformdata.fromC(&xc.platformdata); err != nil {
+		return err
+	}
+	x.Poolid = uint32(xc.poolid)
+	x.PoolName = C.GoString(xc.pool_name)
+	if err := x.RunHotplugScripts.fromC(&xc.run_hotplug_scripts); err != nil {
+		return err
+	}
+	if err := x.DriverDomain.fromC(&xc.driver_domain); err != nil {
+		return err
+	}
+	x.Passthrough = Passthrough(xc.passthrough)
+
+	return nil
+}
+
+func (x *DomainRestoreParams) fromC(xc *C.libxl_domain_restore_params) error {
+	x.CheckpointedStream = int(xc.checkpointed_stream)
+	x.StreamVersion = uint32(xc.stream_version)
+	x.ColoProxyScript = C.GoString(xc.colo_proxy_script)
+	if err := x.UserspaceColoProxy.fromC(&xc.userspace_colo_proxy); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (x *SchedParams) fromC(xc *C.libxl_sched_params) error {
+	x.Vcpuid = int(xc.vcpuid)
+	x.Weight = int(xc.weight)
+	x.Cap = int(xc.cap)
+	x.Period = int(xc.period)
+	x.Extratime = int(xc.extratime)
+	x.Budget = int(xc.budget)
+
+	return nil
+}
+
+func (x *VcpuSchedParams) fromC(xc *C.libxl_vcpu_sched_params) error {
+	x.Sched = Scheduler(xc.sched)
+
+	return nil
+}
+
+func (x *DomainSchedParams) fromC(xc *C.libxl_domain_sched_params) error {
+	x.Sched = Scheduler(xc.sched)
+	x.Weight = int(xc.weight)
+	x.Cap = int(xc.cap)
+	x.Period = int(xc.period)
+	x.Budget = int(xc.budget)
+	x.Extratime = int(xc.extratime)
+	x.Slice = int(xc.slice)
+	x.Latency = int(xc.latency)
+
+	return nil
+}
+
+func (x *VnodeInfo) fromC(xc *C.libxl_vnode_info) error {
+	x.Memkb = uint64(xc.memkb)
+	x.Pnode = uint32(xc.pnode)
+	if err := x.Vcpus.fromC(&xc.vcpus); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (x *RdmReserve) fromC(xc *C.libxl_rdm_reserve) error {
+	x.Strategy = RdmReserveStrategy(xc.strategy)
+	x.Policy = RdmReservePolicy(xc.policy)
+
+	return nil
+}
+
+func (x *DomainBuildInfo) fromC(xc *C.libxl_domain_build_info) error {
+	x.MaxVcpus = int(xc.max_vcpus)
+	if err := x.AvailVcpus.fromC(&xc.avail_vcpus); err != nil {
+		return err
+	}
+	if err := x.Cpumap.fromC(&xc.cpumap); err != nil {
+		return err
+	}
+	if err := x.Nodemap.fromC(&xc.nodemap); err != nil {
+		return err
+	}
+	if err := x.NumaPlacement.fromC(&xc.numa_placement); err != nil {
+		return err
+	}
+	x.TscMode = TscMode(xc.tsc_mode)
+	x.MaxMemkb = uint64(xc.max_memkb)
+	x.TargetMemkb = uint64(xc.target_memkb)
+	x.VideoMemkb = uint64(xc.video_memkb)
+	x.ShadowMemkb = uint64(xc.shadow_memkb)
+	x.IommuMemkb = uint64(xc.iommu_memkb)
+	x.RtcTimeoffset = uint32(xc.rtc_timeoffset)
+	x.ExecSsidref = uint32(xc.exec_ssidref)
+	x.ExecSsidLabel = C.GoString(xc.exec_ssid_label)
+	if err := x.Localtime.fromC(&xc.localtime); err != nil {
+		return err
+	}
+	if err := x.DisableMigrate.fromC(&xc.disable_migrate); err != nil {
+		return err
+	}
+	if err := x.Cpuid.fromC(&xc.cpuid); err != nil {
+		return err
+	}
+	x.BlkdevStart = C.GoString(xc.blkdev_start)
+	x.MaxGrantFrames = uint32(xc.max_grant_frames)
+	x.MaxMaptrackFrames = uint32(xc.max_maptrack_frames)
+	x.DeviceModelVersion = DeviceModelVersion(xc.device_model_version)
+	if err := x.DeviceModelStubdomain.fromC(&xc.device_model_stubdomain); err != nil {
+		return err
+	}
+	x.DeviceModel = C.GoString(xc.device_model)
+	x.DeviceModelSsidref = uint32(xc.device_model_ssidref)
+	x.DeviceModelSsidLabel = C.GoString(xc.device_model_ssid_label)
+	x.DeviceModelUser = C.GoString(xc.device_model_user)
+	if err := x.Extra.fromC(&xc.extra); err != nil {
+		return err
+	}
+	if err := x.ExtraPv.fromC(&xc.extra_pv); err != nil {
+		return err
+	}
+	if err := x.ExtraHvm.fromC(&xc.extra_hvm); err != nil {
+		return err
+	}
+	if err := x.SchedParams.fromC(&xc.sched_params); err != nil {
+		return err
+	}
+	if err := x.ClaimMode.fromC(&xc.claim_mode); err != nil {
+		return err
+	}
+	x.EventChannels = uint32(xc.event_channels)
+	x.Kernel = C.GoString(xc.kernel)
+	x.Cmdline = C.GoString(xc.cmdline)
+	x.Ramdisk = C.GoString(xc.ramdisk)
+	x.DeviceTree = C.GoString(xc.device_tree)
+	if err := x.Acpi.fromC(&xc.acpi); err != nil {
+		return err
+	}
+	x.Bootloader = C.GoString(xc.bootloader)
+	if err := x.BootloaderArgs.fromC(&xc.bootloader_args); err != nil {
+		return err
+	}
+	x.TimerMode = TimerMode(xc.timer_mode)
+	if err := x.NestedHvm.fromC(&xc.nested_hvm); err != nil {
+		return err
+	}
+	if err := x.Apic.fromC(&xc.apic); err != nil {
+		return err
+	}
+	if err := x.DmRestrict.fromC(&xc.dm_restrict); err != nil {
+		return err
+	}
+	x.Tee = TeeType(xc.tee)
+	x.ArchArm.GicVersion = GicVersion(xc.arch_arm.gic_version)
+	x.ArchArm.Vuart = VuartType(xc.arch_arm.vuart)
+	x.Altp2M = Altp2MMode(xc.altp2m)
+
+	return nil
+}
+
+func (x *DeviceVfb) fromC(xc *C.libxl_device_vfb) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+	if err := x.Vnc.fromC(&xc.vnc); err != nil {
+		return err
+	}
+	if err := x.Sdl.fromC(&xc.sdl); err != nil {
+		return err
+	}
+	x.Keymap = C.GoString(xc.keymap)
+
+	return nil
+}
+
+func (x *DeviceVkb) fromC(xc *C.libxl_device_vkb) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+	x.BackendType = VkbBackend(xc.backend_type)
+	x.UniqueId = C.GoString(xc.unique_id)
+	x.FeatureDisableKeyboard = bool(xc.feature_disable_keyboard)
+	x.FeatureDisablePointer = bool(xc.feature_disable_pointer)
+	x.FeatureAbsPointer = bool(xc.feature_abs_pointer)
+	x.FeatureRawPointer = bool(xc.feature_raw_pointer)
+	x.FeatureMultiTouch = bool(xc.feature_multi_touch)
+	x.Width = uint32(xc.width)
+	x.Height = uint32(xc.height)
+	x.MultiTouchWidth = uint32(xc.multi_touch_width)
+	x.MultiTouchHeight = uint32(xc.multi_touch_height)
+	x.MultiTouchNumContacts = uint32(xc.multi_touch_num_contacts)
+
+	return nil
+}
+
+func (x *DeviceDisk) fromC(xc *C.libxl_device_disk) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.PdevPath = C.GoString(xc.pdev_path)
+	x.Vdev = C.GoString(xc.vdev)
+	x.Backend = DiskBackend(xc.backend)
+	x.Format = DiskFormat(xc.format)
+	x.Script = C.GoString(xc.script)
+	x.Removable = int(xc.removable)
+	x.Readwrite = int(xc.readwrite)
+	x.IsCdrom = int(xc.is_cdrom)
+	x.DirectIoSafe = bool(xc.direct_io_safe)
+	if err := x.DiscardEnable.fromC(&xc.discard_enable); err != nil {
+		return err
+	}
+	if err := x.ColoEnable.fromC(&xc.colo_enable); err != nil {
+		return err
+	}
+	if err := x.ColoRestoreEnable.fromC(&xc.colo_restore_enable); err != nil {
+		return err
+	}
+	x.ColoHost = C.GoString(xc.colo_host)
+	x.ColoPort = int(xc.colo_port)
+	x.ColoExport = C.GoString(xc.colo_export)
+	x.ActiveDisk = C.GoString(xc.active_disk)
+	x.HiddenDisk = C.GoString(xc.hidden_disk)
+
+	return nil
+}
+
+func (x *DeviceNic) fromC(xc *C.libxl_device_nic) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+	x.Mtu = int(xc.mtu)
+	x.Model = C.GoString(xc.model)
+	if err := x.Mac.fromC(&xc.mac); err != nil {
+		return err
+	}
+	x.Ip = C.GoString(xc.ip)
+	x.Bridge = C.GoString(xc.bridge)
+	x.Ifname = C.GoString(xc.ifname)
+	x.Script = C.GoString(xc.script)
+	x.Nictype = NicType(xc.nictype)
+	x.RateBytesPerInterval = uint64(xc.rate_bytes_per_interval)
+	x.RateIntervalUsecs = uint32(xc.rate_interval_usecs)
+	x.Gatewaydev = C.GoString(xc.gatewaydev)
+	x.ColoftForwarddev = C.GoString(xc.coloft_forwarddev)
+	x.ColoSockMirrorId = C.GoString(xc.colo_sock_mirror_id)
+	x.ColoSockMirrorIp = C.GoString(xc.colo_sock_mirror_ip)
+	x.ColoSockMirrorPort = C.GoString(xc.colo_sock_mirror_port)
+	x.ColoSockComparePriInId = C.GoString(xc.colo_sock_compare_pri_in_id)
+	x.ColoSockComparePriInIp = C.GoString(xc.colo_sock_compare_pri_in_ip)
+	x.ColoSockComparePriInPort = C.GoString(xc.colo_sock_compare_pri_in_port)
+	x.ColoSockCompareSecInId = C.GoString(xc.colo_sock_compare_sec_in_id)
+	x.ColoSockCompareSecInIp = C.GoString(xc.colo_sock_compare_sec_in_ip)
+	x.ColoSockCompareSecInPort = C.GoString(xc.colo_sock_compare_sec_in_port)
+	x.ColoSockCompareNotifyId = C.GoString(xc.colo_sock_compare_notify_id)
+	x.ColoSockCompareNotifyIp = C.GoString(xc.colo_sock_compare_notify_ip)
+	x.ColoSockCompareNotifyPort = C.GoString(xc.colo_sock_compare_notify_port)
+	x.ColoSockRedirector0Id = C.GoString(xc.colo_sock_redirector0_id)
+	x.ColoSockRedirector0Ip = C.GoString(xc.colo_sock_redirector0_ip)
+	x.ColoSockRedirector0Port = C.GoString(xc.colo_sock_redirector0_port)
+	x.ColoSockRedirector1Id = C.GoString(xc.colo_sock_redirector1_id)
+	x.ColoSockRedirector1Ip = C.GoString(xc.colo_sock_redirector1_ip)
+	x.ColoSockRedirector1Port = C.GoString(xc.colo_sock_redirector1_port)
+	x.ColoSockRedirector2Id = C.GoString(xc.colo_sock_redirector2_id)
+	x.ColoSockRedirector2Ip = C.GoString(xc.colo_sock_redirector2_ip)
+	x.ColoSockRedirector2Port = C.GoString(xc.colo_sock_redirector2_port)
+	x.ColoFilterMirrorQueue = C.GoString(xc.colo_filter_mirror_queue)
+	x.ColoFilterMirrorOutdev = C.GoString(xc.colo_filter_mirror_outdev)
+	x.ColoFilterRedirector0Queue = C.GoString(xc.colo_filter_redirector0_queue)
+	x.ColoFilterRedirector0Indev = C.GoString(xc.colo_filter_redirector0_indev)
+	x.ColoFilterRedirector0Outdev = C.GoString(xc.colo_filter_redirector0_outdev)
+	x.ColoFilterRedirector1Queue = C.GoString(xc.colo_filter_redirector1_queue)
+	x.ColoFilterRedirector1Indev = C.GoString(xc.colo_filter_redirector1_indev)
+	x.ColoFilterRedirector1Outdev = C.GoString(xc.colo_filter_redirector1_outdev)
+	x.ColoComparePriIn = C.GoString(xc.colo_compare_pri_in)
+	x.ColoCompareSecIn = C.GoString(xc.colo_compare_sec_in)
+	x.ColoCompareOut = C.GoString(xc.colo_compare_out)
+	x.ColoCompareNotifyDev = C.GoString(xc.colo_compare_notify_dev)
+	x.ColoSockSecRedirector0Id = C.GoString(xc.colo_sock_sec_redirector0_id)
+	x.ColoSockSecRedirector0Ip = C.GoString(xc.colo_sock_sec_redirector0_ip)
+	x.ColoSockSecRedirector0Port = C.GoString(xc.colo_sock_sec_redirector0_port)
+	x.ColoSockSecRedirector1Id = C.GoString(xc.colo_sock_sec_redirector1_id)
+	x.ColoSockSecRedirector1Ip = C.GoString(xc.colo_sock_sec_redirector1_ip)
+	x.ColoSockSecRedirector1Port = C.GoString(xc.colo_sock_sec_redirector1_port)
+	x.ColoFilterSecRedirector0Queue = C.GoString(xc.colo_filter_sec_redirector0_queue)
+	x.ColoFilterSecRedirector0Indev = C.GoString(xc.colo_filter_sec_redirector0_indev)
+	x.ColoFilterSecRedirector0Outdev = C.GoString(xc.colo_filter_sec_redirector0_outdev)
+	x.ColoFilterSecRedirector1Queue = C.GoString(xc.colo_filter_sec_redirector1_queue)
+	x.ColoFilterSecRedirector1Indev = C.GoString(xc.colo_filter_sec_redirector1_indev)
+	x.ColoFilterSecRedirector1Outdev = C.GoString(xc.colo_filter_sec_redirector1_outdev)
+	x.ColoFilterSecRewriter0Queue = C.GoString(xc.colo_filter_sec_rewriter0_queue)
+	x.ColoCheckpointHost = C.GoString(xc.colo_checkpoint_host)
+	x.ColoCheckpointPort = C.GoString(xc.colo_checkpoint_port)
+
+	return nil
+}
+
+func (x *DevicePci) fromC(xc *C.libxl_device_pci) error {
+	x.Func = byte(xc._func)
+	x.Dev = byte(xc.dev)
+	x.Bus = byte(xc.bus)
+	x.Domain = int(xc.domain)
+	x.Vdevfn = uint32(xc.vdevfn)
+	x.VfuncMask = uint32(xc.vfunc_mask)
+	x.Msitranslate = bool(xc.msitranslate)
+	x.PowerMgmt = bool(xc.power_mgmt)
+	x.Permissive = bool(xc.permissive)
+	x.Seize = bool(xc.seize)
+	x.RdmPolicy = RdmReservePolicy(xc.rdm_policy)
+
+	return nil
+}
+
+func (x *DeviceRdm) fromC(xc *C.libxl_device_rdm) error {
+	x.Start = uint64(xc.start)
+	x.Size = uint64(xc.size)
+	x.Policy = RdmReservePolicy(xc.policy)
+
+	return nil
+}
+
+func (x *DeviceUsbctrl) fromC(xc *C.libxl_device_usbctrl) error {
+	x.Type = UsbctrlType(xc._type)
+	x.Devid = Devid(xc.devid)
+	x.Version = int(xc.version)
+	x.Ports = int(xc.ports)
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+
+	return nil
+}
+
+func (x *DeviceUsbdev) fromC(xc *C.libxl_device_usbdev) error {
+	x.Ctrl = Devid(xc.ctrl)
+	x.Port = int(xc.port)
+
+	return nil
+}
+
+func (x *DeviceDtdev) fromC(xc *C.libxl_device_dtdev) error {
+	x.Path = C.GoString(xc.path)
+
+	return nil
+}
+
+func (x *DeviceVtpm) fromC(xc *C.libxl_device_vtpm) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+	if err := x.Uuid.fromC(&xc.uuid); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (x *DeviceP9) fromC(xc *C.libxl_device_p9) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Tag = C.GoString(xc.tag)
+	x.Path = C.GoString(xc.path)
+	x.SecurityModel = C.GoString(xc.security_model)
+	x.Devid = Devid(xc.devid)
+
+	return nil
+}
+
+func (x *DevicePvcallsif) fromC(xc *C.libxl_device_pvcallsif) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+
+	return nil
+}
+
+func (x *DeviceChannel) fromC(xc *C.libxl_device_channel) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+	x.Name = C.GoString(xc.name)
+
+	return nil
+}
+
+func (x *ConnectorParam) fromC(xc *C.libxl_connector_param) error {
+	x.UniqueId = C.GoString(xc.unique_id)
+	x.Width = uint32(xc.width)
+	x.Height = uint32(xc.height)
+
+	return nil
+}
+
+func (x *DeviceVdispl) fromC(xc *C.libxl_device_vdispl) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+	x.BeAlloc = bool(xc.be_alloc)
+
+	return nil
+}
+
+func (x *VsndParams) fromC(xc *C.libxl_vsnd_params) error {
+	x.ChannelsMin = uint32(xc.channels_min)
+	x.ChannelsMax = uint32(xc.channels_max)
+	x.BufferSize = uint32(xc.buffer_size)
+
+	return nil
+}
+
+func (x *VsndStream) fromC(xc *C.libxl_vsnd_stream) error {
+	x.UniqueId = C.GoString(xc.unique_id)
+	x.Type = VsndStreamType(xc._type)
+	if err := x.Params.fromC(&xc.params); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (x *VsndPcm) fromC(xc *C.libxl_vsnd_pcm) error {
+	x.Name = C.GoString(xc.name)
+	if err := x.Params.fromC(&xc.params); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (x *DeviceVsnd) fromC(xc *C.libxl_device_vsnd) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+	x.ShortName = C.GoString(xc.short_name)
+	x.LongName = C.GoString(xc.long_name)
+	if err := x.Params.fromC(&xc.params); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (x *DomainConfig) fromC(xc *C.libxl_domain_config) error {
+	if err := x.CInfo.fromC(&xc.c_info); err != nil {
+		return err
+	}
+	if err := x.BInfo.fromC(&xc.b_info); err != nil {
+		return err
+	}
+	x.OnPoweroff = ActionOnShutdown(xc.on_poweroff)
+	x.OnReboot = ActionOnShutdown(xc.on_reboot)
+	x.OnWatchdog = ActionOnShutdown(xc.on_watchdog)
+	x.OnCrash = ActionOnShutdown(xc.on_crash)
+	x.OnSoftReset = ActionOnShutdown(xc.on_soft_reset)
+
+	return nil
+}
+
+func (x *Diskinfo) fromC(xc *C.libxl_diskinfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+	x.Evtch = int(xc.evtch)
+	x.Rref = int(xc.rref)
+
+	return nil
+}
+
+func (x *Nicinfo) fromC(xc *C.libxl_nicinfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+	x.Evtch = int(xc.evtch)
+	x.RrefTx = int(xc.rref_tx)
+	x.RrefRx = int(xc.rref_rx)
+
+	return nil
+}
+
+func (x *Vtpminfo) fromC(xc *C.libxl_vtpminfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+	x.Evtch = int(xc.evtch)
+	x.Rref = int(xc.rref)
+	if err := x.Uuid.fromC(&xc.uuid); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (x *Usbctrlinfo) fromC(xc *C.libxl_usbctrlinfo) error {
+	x.Type = UsbctrlType(xc._type)
+	x.Devid = Devid(xc.devid)
+	x.Version = int(xc.version)
+	x.Ports = int(xc.ports)
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.State = int(xc.state)
+	x.Evtch = int(xc.evtch)
+	x.RefUrb = int(xc.ref_urb)
+	x.RefConn = int(xc.ref_conn)
+
+	return nil
+}
+
+func (x *Vcpuinfo) fromC(xc *C.libxl_vcpuinfo) error {
+	x.Vcpuid = uint32(xc.vcpuid)
+	x.Cpu = uint32(xc.cpu)
+	x.Online = bool(xc.online)
+	x.Blocked = bool(xc.blocked)
+	x.Running = bool(xc.running)
+	x.VcpuTime = uint64(xc.vcpu_time)
+	if err := x.Cpumap.fromC(&xc.cpumap); err != nil {
+		return err
+	}
+	if err := x.CpumapSoft.fromC(&xc.cpumap_soft); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (x *Physinfo) fromC(xc *C.libxl_physinfo) error {
+	x.ThreadsPerCore = uint32(xc.threads_per_core)
+	x.CoresPerSocket = uint32(xc.cores_per_socket)
+	x.MaxCpuId = uint32(xc.max_cpu_id)
+	x.NrCpus = uint32(xc.nr_cpus)
+	x.CpuKhz = uint32(xc.cpu_khz)
+	x.TotalPages = uint64(xc.total_pages)
+	x.FreePages = uint64(xc.free_pages)
+	x.ScrubPages = uint64(xc.scrub_pages)
+	x.OutstandingPages = uint64(xc.outstanding_pages)
+	x.SharingFreedPages = uint64(xc.sharing_freed_pages)
+	x.SharingUsedFrames = uint64(xc.sharing_used_frames)
+	x.MaxPossibleMfn = uint64(xc.max_possible_mfn)
+	x.NrNodes = uint32(xc.nr_nodes)
+	if err := x.HwCap.fromC(&xc.hw_cap); err != nil {
+		return err
+	}
+	x.CapHvm = bool(xc.cap_hvm)
+	x.CapPv = bool(xc.cap_pv)
+	x.CapHvmDirectio = bool(xc.cap_hvm_directio)
+	x.CapHap = bool(xc.cap_hap)
+	x.CapShadow = bool(xc.cap_shadow)
+	x.CapIommuHapPtShare = bool(xc.cap_iommu_hap_pt_share)
+
+	return nil
+}
+
+func (x *Connectorinfo) fromC(xc *C.libxl_connectorinfo) error {
+	x.UniqueId = C.GoString(xc.unique_id)
+	x.Width = uint32(xc.width)
+	x.Height = uint32(xc.height)
+	x.ReqEvtch = int(xc.req_evtch)
+	x.ReqRref = int(xc.req_rref)
+	x.EvtEvtch = int(xc.evt_evtch)
+	x.EvtRref = int(xc.evt_rref)
+
+	return nil
+}
+
+func (x *Vdisplinfo) fromC(xc *C.libxl_vdisplinfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+	x.BeAlloc = bool(xc.be_alloc)
+
+	return nil
+}
+
+func (x *Streaminfo) fromC(xc *C.libxl_streaminfo) error {
+	x.ReqEvtch = int(xc.req_evtch)
+	x.ReqRref = int(xc.req_rref)
+
+	return nil
+}
+
+func (x *Pcminfo) fromC(xc *C.libxl_pcminfo) error {
+
+	return nil
+}
+
+func (x *Vsndinfo) fromC(xc *C.libxl_vsndinfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+
+	return nil
+}
+
+func (x *Vkbinfo) fromC(xc *C.libxl_vkbinfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+	x.Evtch = int(xc.evtch)
+	x.Rref = int(xc.rref)
+
+	return nil
+}
+
+func (x *Numainfo) fromC(xc *C.libxl_numainfo) error {
+	x.Size = uint64(xc.size)
+	x.Free = uint64(xc.free)
+
+	return nil
+}
+
+func (x *Cputopology) fromC(xc *C.libxl_cputopology) error {
+	x.Core = uint32(xc.core)
+	x.Socket = uint32(xc.socket)
+	x.Node = uint32(xc.node)
+
+	return nil
+}
+
+func (x *Pcitopology) fromC(xc *C.libxl_pcitopology) error {
+	x.Seg = uint16(xc.seg)
+	x.Bus = byte(xc.bus)
+	x.Devfn = byte(xc.devfn)
+	x.Node = uint32(xc.node)
+
+	return nil
+}
+
+func (x *SchedCreditParams) fromC(xc *C.libxl_sched_credit_params) error {
+	x.TsliceMs = int(xc.tslice_ms)
+	x.RatelimitUs = int(xc.ratelimit_us)
+	x.VcpuMigrDelayUs = int(xc.vcpu_migr_delay_us)
+
+	return nil
+}
+
+func (x *SchedCredit2Params) fromC(xc *C.libxl_sched_credit2_params) error {
+	x.RatelimitUs = int(xc.ratelimit_us)
+
+	return nil
+}
+
+func (x *DomainRemusInfo) fromC(xc *C.libxl_domain_remus_info) error {
+	x.Interval = int(xc.interval)
+	if err := x.AllowUnsafe.fromC(&xc.allow_unsafe); err != nil {
+		return err
+	}
+	if err := x.Blackhole.fromC(&xc.blackhole); err != nil {
+		return err
+	}
+	if err := x.Compression.fromC(&xc.compression); err != nil {
+		return err
+	}
+	if err := x.Netbuf.fromC(&xc.netbuf); err != nil {
+		return err
+	}
+	x.Netbufscript = C.GoString(xc.netbufscript)
+	if err := x.Diskbuf.fromC(&xc.diskbuf); err != nil {
+		return err
+	}
+	if err := x.Colo.fromC(&xc.colo); err != nil {
+		return err
+	}
+	if err := x.UserspaceColoProxy.fromC(&xc.userspace_colo_proxy); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (x *Event) fromC(xc *C.libxl_event) error {
+	if err := x.Link.fromC(&xc.link); err != nil {
+		return err
+	}
+	x.Domid = Domid(xc.domid)
+	if err := x.Domuuid.fromC(&xc.domuuid); err != nil {
+		return err
+	}
+	x.ForUser = uint64(xc.for_user)
+
+	return nil
+}
+
+func (x *PsrCatInfo) fromC(xc *C.libxl_psr_cat_info) error {
+	x.Id = uint32(xc.id)
+	x.CosMax = uint32(xc.cos_max)
+	x.CbmLen = uint32(xc.cbm_len)
+	x.CdpEnabled = bool(xc.cdp_enabled)
+
+	return nil
+}
+
+func (x *PsrHwInfo) fromC(xc *C.libxl_psr_hw_info) error {
+	x.Id = uint32(xc.id)
+
+	return nil
+}
diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index fb1c6d9e51..f32eb11384 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -405,47 +405,6 @@  func (bm *Bitmap) toC() (C.libxl_bitmap, error) {
 	return cbm, nil
 }
 
-func (cphys *C.libxl_physinfo) toGo() (physinfo *Physinfo) {
-
-	physinfo = &Physinfo{}
-	physinfo.ThreadsPerCore = uint32(cphys.threads_per_core)
-	physinfo.CoresPerSocket = uint32(cphys.cores_per_socket)
-	physinfo.MaxCpuId = uint32(cphys.max_cpu_id)
-	physinfo.NrCpus = uint32(cphys.nr_cpus)
-	physinfo.CpuKhz = uint32(cphys.cpu_khz)
-	physinfo.TotalPages = uint64(cphys.total_pages)
-	physinfo.FreePages = uint64(cphys.free_pages)
-	physinfo.ScrubPages = uint64(cphys.scrub_pages)
-	physinfo.ScrubPages = uint64(cphys.scrub_pages)
-	physinfo.SharingFreedPages = uint64(cphys.sharing_freed_pages)
-	physinfo.SharingUsedFrames = uint64(cphys.sharing_used_frames)
-	physinfo.NrNodes = uint32(cphys.nr_nodes)
-	physinfo.HwCap.fromC(&cphys.hw_cap)
-	physinfo.CapHvm = bool(cphys.cap_hvm)
-	physinfo.CapHvmDirectio = bool(cphys.cap_hvm_directio)
-
-	return
-}
-
-func (cinfo *C.libxl_version_info) toGo() (info *VersionInfo) {
-	info = &VersionInfo{}
-	info.XenVersionMajor = int(cinfo.xen_version_major)
-	info.XenVersionMinor = int(cinfo.xen_version_minor)
-	info.XenVersionExtra = C.GoString(cinfo.xen_version_extra)
-	info.Compiler = C.GoString(cinfo.compiler)
-	info.CompileBy = C.GoString(cinfo.compile_by)
-	info.CompileDomain = C.GoString(cinfo.compile_domain)
-	info.CompileDate = C.GoString(cinfo.compile_date)
-	info.Capabilities = C.GoString(cinfo.capabilities)
-	info.Changeset = C.GoString(cinfo.changeset)
-	info.VirtStart = uint64(cinfo.virt_start)
-	info.Pagesize = int(cinfo.pagesize)
-	info.Commandline = C.GoString(cinfo.commandline)
-	info.BuildId = C.GoString(cinfo.build_id)
-
-	return
-}
-
 func (sr ShutdownReason) String() (str string) {
 	cstr := C.libxl_shutdown_reason_to_string(C.libxl_shutdown_reason(sr))
 	str = C.GoString(cstr)
@@ -460,34 +419,6 @@  func (dt DomainType) String() (str string) {
 	return
 }
 
-func (cdi *C.libxl_dominfo) toGo() (di *Dominfo) {
-
-	di = &Dominfo{}
-	di.Uuid.fromC(&cdi.uuid)
-	di.Domid = Domid(cdi.domid)
-	di.Ssidref = uint32(cdi.ssidref)
-	di.SsidLabel = C.GoString(cdi.ssid_label)
-	di.Running = bool(cdi.running)
-	di.Blocked = bool(cdi.blocked)
-	di.Paused = bool(cdi.paused)
-	di.Shutdown = bool(cdi.shutdown)
-	di.Dying = bool(cdi.dying)
-	di.NeverStop = bool(cdi.never_stop)
-	di.ShutdownReason = ShutdownReason(cdi.shutdown_reason)
-	di.OutstandingMemkb = uint64(cdi.outstanding_memkb)
-	di.CurrentMemkb = uint64(cdi.current_memkb)
-	di.SharedMemkb = uint64(cdi.shared_memkb)
-	di.PagedMemkb = uint64(cdi.paged_memkb)
-	di.MaxMemkb = uint64(cdi.max_memkb)
-	di.CpuTime = uint64(cdi.cpu_time)
-	di.VcpuMaxId = uint32(cdi.vcpu_max_id)
-	di.VcpuOnline = uint32(cdi.vcpu_online)
-	di.Cpupool = uint32(cdi.cpupool)
-	di.DomainType = DomainType(cdi.domain_type)
-
-	return
-}
-
 // const char *libxl_scheduler_to_string(libxl_scheduler p);
 func (s Scheduler) String() string {
 	cs := C.libxl_scheduler_to_string(C.libxl_scheduler(s))
@@ -519,16 +450,6 @@  func SchedulerFromString(name string) (s Scheduler, err error) {
 	return
 }
 
-func (cci C.libxl_cpupoolinfo) toGo() (gci Cpupoolinfo) {
-	gci.Poolid = uint32(cci.poolid)
-	gci.PoolName = C.GoString(cci.pool_name)
-	gci.Sched = Scheduler(cci.sched)
-	gci.NDom = uint32(cci.n_dom)
-	gci.Cpumap.fromC(&cci.cpumap)
-
-	return
-}
-
 // libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool_out);
 // void libxl_cpupoolinfo_list_free(libxl_cpupoolinfo *list, int nb_pool);
 func (Ctx *Context) ListCpupool() (list []Cpupoolinfo) {
@@ -550,7 +471,8 @@  func (Ctx *Context) ListCpupool() (list []Cpupoolinfo) {
 	// Magic
 	cpupoolListSlice := (*[1 << 30]C.libxl_cpupoolinfo)(unsafe.Pointer(c_cpupool_list))[:nbPool:nbPool]
 	for i := range cpupoolListSlice {
-		info := cpupoolListSlice[i].toGo()
+		var info Cpupoolinfo
+		_ = info.fromC(&cpupoolListSlice[i])
 		list = append(list, info)
 	}
 
@@ -573,7 +495,7 @@  func (Ctx *Context) CpupoolInfo(Poolid uint32) (pool Cpupoolinfo) {
 	}
 	defer C.libxl_cpupoolinfo_dispose(&c_cpupool)
 
-	pool = c_cpupool.toGo()
+	_ = pool.fromC(&c_cpupool)
 
 	return
 }
@@ -1064,7 +986,7 @@  func (Ctx *Context) GetPhysinfo() (physinfo *Physinfo, err error) {
 		err = Error(ret)
 		return
 	}
-	physinfo = cphys.toGo()
+	err = physinfo.fromC(&cphys)
 
 	return
 }
@@ -1080,7 +1002,7 @@  func (Ctx *Context) GetVersionInfo() (info *VersionInfo, err error) {
 
 	cinfo = C.libxl_get_version_info(Ctx.ctx)
 
-	info = cinfo.toGo()
+	err = info.fromC(cinfo)
 
 	return
 }
@@ -1102,7 +1024,7 @@  func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
 		return
 	}
 
-	di = cdi.toGo()
+	err = di.fromC(&cdi)
 
 	return
 }
@@ -1184,26 +1106,14 @@  func (Ctx *Context) ListDomain() (glist []Dominfo) {
 
 	gslice := (*[1 << 30]C.libxl_dominfo)(unsafe.Pointer(clist))[:nbDomain:nbDomain]
 	for i := range gslice {
-		info := gslice[i].toGo()
-		glist = append(glist, *info)
+		var info Dominfo
+		_ = info.fromC(&gslice[i])
+		glist = append(glist, info)
 	}
 
 	return
 }
 
-func (cvci C.libxl_vcpuinfo) toGo() (gvci Vcpuinfo) {
-	gvci.Vcpuid = uint32(cvci.vcpuid)
-	gvci.Cpu = uint32(cvci.cpu)
-	gvci.Online = bool(cvci.online)
-	gvci.Blocked = bool(cvci.blocked)
-	gvci.Running = bool(cvci.running)
-	gvci.VcpuTime = uint64(cvci.vcpu_time)
-	gvci.Cpumap.fromC(&cvci.cpumap)
-	gvci.CpumapSoft.fromC(&cvci.cpumap_soft)
-
-	return
-}
-
 //libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid,
 //				int *nb_vcpu, int *nr_cpus_out);
 //void libxl_vcpuinfo_list_free(libxl_vcpuinfo *, int nr_vcpus);
@@ -1225,7 +1135,8 @@  func (Ctx *Context) ListVcpu(id Domid) (glist []Vcpuinfo) {
 
 	gslice := (*[1 << 30]C.libxl_vcpuinfo)(unsafe.Pointer(clist))[:nbVcpu:nbVcpu]
 	for i := range gslice {
-		info := gslice[i].toGo()
+		var info Vcpuinfo
+		_ = info.fromC(&gslice[i])
 		glist = append(glist, info)
 	}