From: Nick Rosbrook <rosbrookn@gmail.com>
To: xen-devel@lists.xenproject.prg, xen-devel@lists.xenproject.org
Cc: Nick Rosbrook <rosbrookn@ainfosec.com>,
George Dunlap <george.dunlap@citrix.com>,
Ian Jackson <iwj@xenproject.org>, Wei Liu <wl@xen.org>
Subject: [RESEND PATCH 05/12] golang/xenlight: use struct pointers in keyed union fields
Date: Mon, 24 May 2021 16:36:46 -0400 [thread overview]
Message-ID: <ebeb085b9b4b5d3dddd66607b409590f5e7cdfc6.1621887506.git.rosbrookn@ainfosec.com> (raw)
In-Reply-To: <cover.1621887506.git.rosbrookn@ainfosec.com>
In-Reply-To: <cover.1621887506.git.rosbrookn@ainfosec.com>
Currently, when marshalig Go types with keyed union fields, we assign the
value of the struct (e.g. DomainBuildInfoTypeUnionHvm) which implements the
interface of the keyed union field (e.g. DomainBuildInfoTypeUnion).
As-is, this means that if a populated DomainBuildInfo is marshaled to
e.g. JSON, unmarshaling back to DomainBuildInfo will fail.
When the encoding/json is unmarshaling data into a Go type, and
encounters a JSON object, it basically can either marshal the data into
an empty interface, a map, or a struct. It cannot, however, marshal data
into an interface with at least one method defined on it (e.g.
DomainBuildInfoTypeUnion). Before this check is done, however, the
decoder will check if the Go type is a pointer, and dereference it if
so. It will then use the type of this value as the "target" type.
This means that if the TypeUnion field is populated with a
DomainBuildInfoTypeUnion, the decoder will see a non-empty interface and
fail. If the TypeUnion field is populated with a
*DomainBuildInfoTypeUnionHvm, it dereferences the pointer and sees a
struct instead, allowing decoding to continue normally.
Since there does not appear to be a strict need for NOT using pointers
in these fields, update code generation to set keyed union fields to
pointers of their implementing structs.
Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
tools/golang/xenlight/gengotypes.py | 4 +--
tools/golang/xenlight/helpers.gen.go | 44 ++++++++++++++--------------
2 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py
index 3796632f7d..57f2576468 100644
--- a/tools/golang/xenlight/gengotypes.py
+++ b/tools/golang/xenlight/gengotypes.py
@@ -404,7 +404,7 @@ def xenlight_golang_union_from_C(ty = None, union_name = '', struct_name = ''):
s += 'if err := {0}.fromC(xc);'.format(goname)
s += 'err != nil {{\n return fmt.Errorf("converting field {0}: %v", err)\n}}\n'.format(goname)
- s += 'x.{0} = {1}\n'.format(field_name, goname)
+ s += 'x.{0} = &{1}\n'.format(field_name, goname)
# End switch statement
s += 'default:\n'
@@ -571,7 +571,7 @@ def xenlight_golang_union_to_C(ty = None, union_name = '',
gotype = xenlight_golang_fmt_name(cgotype)
field_name = xenlight_golang_fmt_name('{0}_union'.format(keyname))
- s += 'tmp, ok := x.{0}.({1})\n'.format(field_name,gotype)
+ s += 'tmp, ok := x.{0}.(*{1})\n'.format(field_name,gotype)
s += 'if !ok {\n'
s += 'return errors.New("wrong type for union key {0}")\n'.format(keyname)
s += '}\n'
diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go
index 5222898fb8..8fc5ec1649 100644
--- a/tools/golang/xenlight/helpers.gen.go
+++ b/tools/golang/xenlight/helpers.gen.go
@@ -443,7 +443,7 @@ var connectionPty ChannelinfoConnectionUnionPty
if err := connectionPty.fromC(xc);err != nil {
return fmt.Errorf("converting field connectionPty: %v", err)
}
-x.ConnectionUnion = connectionPty
+x.ConnectionUnion = &connectionPty
case ChannelConnectionSocket:
x.ConnectionUnion = nil
case ChannelConnectionUnknown:
@@ -485,7 +485,7 @@ switch x.Connection{
case ChannelConnectionUnknown:
break
case ChannelConnectionPty:
-tmp, ok := x.ConnectionUnion.(ChannelinfoConnectionUnionPty)
+tmp, ok := x.ConnectionUnion.(*ChannelinfoConnectionUnionPty)
if !ok {
return errors.New("wrong type for union key connection")
}
@@ -1120,7 +1120,7 @@ var typeHvm DomainBuildInfoTypeUnionHvm
if err := typeHvm.fromC(xc);err != nil {
return fmt.Errorf("converting field typeHvm: %v", err)
}
-x.TypeUnion = typeHvm
+x.TypeUnion = &typeHvm
case DomainTypeInvalid:
x.TypeUnion = nil
case DomainTypePv:
@@ -1128,13 +1128,13 @@ var typePv DomainBuildInfoTypeUnionPv
if err := typePv.fromC(xc);err != nil {
return fmt.Errorf("converting field typePv: %v", err)
}
-x.TypeUnion = typePv
+x.TypeUnion = &typePv
case DomainTypePvh:
var typePvh DomainBuildInfoTypeUnionPvh
if err := typePvh.fromC(xc);err != nil {
return fmt.Errorf("converting field typePvh: %v", err)
}
-x.TypeUnion = typePvh
+x.TypeUnion = &typePvh
default:
return fmt.Errorf("invalid union key '%v'", x.Type)}
x.ArchArm.GicVersion = GicVersion(xc.arch_arm.gic_version)
@@ -1465,7 +1465,7 @@ xc.tee = C.libxl_tee_type(x.Tee)
xc._type = C.libxl_domain_type(x.Type)
switch x.Type{
case DomainTypeHvm:
-tmp, ok := x.TypeUnion.(DomainBuildInfoTypeUnionHvm)
+tmp, ok := x.TypeUnion.(*DomainBuildInfoTypeUnionHvm)
if !ok {
return errors.New("wrong type for union key type")
}
@@ -1593,7 +1593,7 @@ hvm.mca_caps = C.uint64_t(tmp.McaCaps)
hvmBytes := C.GoBytes(unsafe.Pointer(&hvm),C.sizeof_libxl_domain_build_info_type_union_hvm)
copy(xc.u[:],hvmBytes)
case DomainTypePv:
-tmp, ok := x.TypeUnion.(DomainBuildInfoTypeUnionPv)
+tmp, ok := x.TypeUnion.(*DomainBuildInfoTypeUnionPv)
if !ok {
return errors.New("wrong type for union key type")
}
@@ -1623,7 +1623,7 @@ return fmt.Errorf("converting field E820Host: %v", err)
pvBytes := C.GoBytes(unsafe.Pointer(&pv),C.sizeof_libxl_domain_build_info_type_union_pv)
copy(xc.u[:],pvBytes)
case DomainTypePvh:
-tmp, ok := x.TypeUnion.(DomainBuildInfoTypeUnionPvh)
+tmp, ok := x.TypeUnion.(*DomainBuildInfoTypeUnionPvh)
if !ok {
return errors.New("wrong type for union key type")
}
@@ -2283,7 +2283,7 @@ var typeHostdev DeviceUsbdevTypeUnionHostdev
if err := typeHostdev.fromC(xc);err != nil {
return fmt.Errorf("converting field typeHostdev: %v", err)
}
-x.TypeUnion = typeHostdev
+x.TypeUnion = &typeHostdev
default:
return fmt.Errorf("invalid union key '%v'", x.Type)}
@@ -2310,7 +2310,7 @@ xc.port = C.int(x.Port)
xc._type = C.libxl_usbdev_type(x.Type)
switch x.Type{
case UsbdevTypeHostdev:
-tmp, ok := x.TypeUnion.(DeviceUsbdevTypeUnionHostdev)
+tmp, ok := x.TypeUnion.(*DeviceUsbdevTypeUnionHostdev)
if !ok {
return errors.New("wrong type for union key type")
}
@@ -2508,7 +2508,7 @@ var connectionSocket DeviceChannelConnectionUnionSocket
if err := connectionSocket.fromC(xc);err != nil {
return fmt.Errorf("converting field connectionSocket: %v", err)
}
-x.ConnectionUnion = connectionSocket
+x.ConnectionUnion = &connectionSocket
case ChannelConnectionUnknown:
x.ConnectionUnion = nil
default:
@@ -2546,7 +2546,7 @@ break
case ChannelConnectionPty:
break
case ChannelConnectionSocket:
-tmp, ok := x.ConnectionUnion.(DeviceChannelConnectionUnionSocket)
+tmp, ok := x.ConnectionUnion.(*DeviceChannelConnectionUnionSocket)
if !ok {
return errors.New("wrong type for union key connection")
}
@@ -4107,7 +4107,7 @@ var typeDiskEject EventTypeUnionDiskEject
if err := typeDiskEject.fromC(xc);err != nil {
return fmt.Errorf("converting field typeDiskEject: %v", err)
}
-x.TypeUnion = typeDiskEject
+x.TypeUnion = &typeDiskEject
case EventTypeDomainCreateConsoleAvailable:
x.TypeUnion = nil
case EventTypeDomainDeath:
@@ -4117,13 +4117,13 @@ var typeDomainShutdown EventTypeUnionDomainShutdown
if err := typeDomainShutdown.fromC(xc);err != nil {
return fmt.Errorf("converting field typeDomainShutdown: %v", err)
}
-x.TypeUnion = typeDomainShutdown
+x.TypeUnion = &typeDomainShutdown
case EventTypeOperationComplete:
var typeOperationComplete EventTypeUnionOperationComplete
if err := typeOperationComplete.fromC(xc);err != nil {
return fmt.Errorf("converting field typeOperationComplete: %v", err)
}
-x.TypeUnion = typeOperationComplete
+x.TypeUnion = &typeOperationComplete
default:
return fmt.Errorf("invalid union key '%v'", x.Type)}
@@ -4178,7 +4178,7 @@ xc.for_user = C.uint64_t(x.ForUser)
xc._type = C.libxl_event_type(x.Type)
switch x.Type{
case EventTypeDomainShutdown:
-tmp, ok := x.TypeUnion.(EventTypeUnionDomainShutdown)
+tmp, ok := x.TypeUnion.(*EventTypeUnionDomainShutdown)
if !ok {
return errors.New("wrong type for union key type")
}
@@ -4189,7 +4189,7 @@ copy(xc.u[:],domain_shutdownBytes)
case EventTypeDomainDeath:
break
case EventTypeDiskEject:
-tmp, ok := x.TypeUnion.(EventTypeUnionDiskEject)
+tmp, ok := x.TypeUnion.(*EventTypeUnionDiskEject)
if !ok {
return errors.New("wrong type for union key type")
}
@@ -4203,7 +4203,7 @@ return fmt.Errorf("converting field Disk: %v", err)
disk_ejectBytes := C.GoBytes(unsafe.Pointer(&disk_eject),C.sizeof_libxl_event_type_union_disk_eject)
copy(xc.u[:],disk_ejectBytes)
case EventTypeOperationComplete:
-tmp, ok := x.TypeUnion.(EventTypeUnionOperationComplete)
+tmp, ok := x.TypeUnion.(*EventTypeUnionOperationComplete)
if !ok {
return errors.New("wrong type for union key type")
}
@@ -4278,13 +4278,13 @@ var typeCat PsrHwInfoTypeUnionCat
if err := typeCat.fromC(xc);err != nil {
return fmt.Errorf("converting field typeCat: %v", err)
}
-x.TypeUnion = typeCat
+x.TypeUnion = &typeCat
case PsrFeatTypeMba:
var typeMba PsrHwInfoTypeUnionMba
if err := typeMba.fromC(xc);err != nil {
return fmt.Errorf("converting field typeMba: %v", err)
}
-x.TypeUnion = typeMba
+x.TypeUnion = &typeMba
default:
return fmt.Errorf("invalid union key '%v'", x.Type)}
@@ -4323,7 +4323,7 @@ xc.id = C.uint32_t(x.Id)
xc._type = C.libxl_psr_feat_type(x.Type)
switch x.Type{
case PsrFeatTypeCat:
-tmp, ok := x.TypeUnion.(PsrHwInfoTypeUnionCat)
+tmp, ok := x.TypeUnion.(*PsrHwInfoTypeUnionCat)
if !ok {
return errors.New("wrong type for union key type")
}
@@ -4334,7 +4334,7 @@ cat.cdp_enabled = C.bool(tmp.CdpEnabled)
catBytes := C.GoBytes(unsafe.Pointer(&cat),C.sizeof_libxl_psr_hw_info_type_union_cat)
copy(xc.u[:],catBytes)
case PsrFeatTypeMba:
-tmp, ok := x.TypeUnion.(PsrHwInfoTypeUnionMba)
+tmp, ok := x.TypeUnion.(*PsrHwInfoTypeUnionMba)
if !ok {
return errors.New("wrong type for union key type")
}
--
2.17.1
next prev parent reply other threads:[~2021-05-24 20:38 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-24 20:36 [RESEND PATCH 00/12] golang/xenlight: domain life cycle support Nick Rosbrook
2021-05-24 20:36 ` [RESEND PATCH 01/12] golang/xenlight: update generated code Nick Rosbrook
2021-06-18 10:30 ` George Dunlap
2021-05-24 20:36 ` [RESEND PATCH 02/12] golang/xenlight: fix StringList toC conversion Nick Rosbrook
2021-06-18 10:51 ` George Dunlap
2021-05-24 20:36 ` [RESEND PATCH 03/12] golang/xenlight: fix string conversion in generated toC functions Nick Rosbrook
2021-06-18 11:00 ` George Dunlap
2021-06-21 16:11 ` Nick Rosbrook
2021-07-01 14:09 ` George Dunlap
2021-07-07 19:29 ` Nick Rosbrook
2021-05-24 20:36 ` [RESEND PATCH 04/12] golang/xenlight: export keyed union interface types Nick Rosbrook
2021-06-18 11:19 ` George Dunlap
2021-05-24 20:36 ` Nick Rosbrook [this message]
2021-06-18 11:26 ` [RESEND PATCH 05/12] golang/xenlight: use struct pointers in keyed union fields George Dunlap
2021-05-24 20:36 ` [RESEND PATCH 06/12] golang/xenlight: rename Ctx receivers to ctx Nick Rosbrook
2021-06-18 11:39 ` George Dunlap
2021-05-24 20:36 ` [RESEND PATCH 07/12] golang/xenlight: add logging conveniences for within xenlight Nick Rosbrook
2021-06-18 13:17 ` George Dunlap
2021-06-18 13:21 ` George Dunlap
2021-06-18 15:26 ` Nick Rosbrook
2021-06-18 16:30 ` George Dunlap
2021-06-18 15:17 ` Nick Rosbrook
2021-06-18 16:28 ` George Dunlap
2021-05-24 20:36 ` [RESEND PATCH 08/12] golang/xenlight: add functional options to configure Context Nick Rosbrook
2021-06-18 14:44 ` George Dunlap
2021-06-18 15:08 ` Nick Rosbrook
2021-06-18 16:18 ` George Dunlap
2021-06-18 17:00 ` Nick Rosbrook
2021-06-18 18:12 ` George Dunlap
2021-05-24 20:36 ` [RESEND PATCH 09/12] golang/xenlight: add DomainDestroy wrapper Nick Rosbrook
2021-06-18 14:47 ` George Dunlap
2021-05-24 20:36 ` [RESEND PATCH 10/12] golang/xenlight: add SendTrigger wrapper Nick Rosbrook
2021-06-18 14:54 ` George Dunlap
2021-05-24 20:36 ` [RESEND PATCH 11/12] golang/xenlight: do not negate ret when converting to Error Nick Rosbrook
2021-06-18 15:13 ` George Dunlap
2021-06-18 15:32 ` Nick Rosbrook
2021-05-24 20:36 ` [RESEND PATCH 12/12] golang/xenlight: add NotifyDomainDeath method to Context Nick Rosbrook
2021-06-18 18:28 ` George Dunlap
2021-06-18 19:31 ` George Dunlap
2021-06-21 21:41 ` Nick Rosbrook
2021-06-17 15:29 ` [RESEND PATCH 00/12] golang/xenlight: domain life cycle support Nick Rosbrook
2021-06-21 15:53 ` George Dunlap
2021-06-21 16:19 ` Nick Rosbrook
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ebeb085b9b4b5d3dddd66607b409590f5e7cdfc6.1621887506.git.rosbrookn@ainfosec.com \
--to=rosbrookn@gmail.com \
--cc=george.dunlap@citrix.com \
--cc=iwj@xenproject.org \
--cc=rosbrookn@ainfosec.com \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
--cc=xen-devel@lists.xenproject.prg \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.