diff options
Diffstat (limited to 'tools/go_marshal/README.md')
-rw-r--r-- | tools/go_marshal/README.md | 145 |
1 files changed, 0 insertions, 145 deletions
diff --git a/tools/go_marshal/README.md b/tools/go_marshal/README.md deleted file mode 100644 index bbd4c9f48..000000000 --- a/tools/go_marshal/README.md +++ /dev/null @@ -1,145 +0,0 @@ -This package implements the go_marshal utility. - -# Overview - -`go_marshal` is a code generation utility similar to `go_stateify` for -marshalling go data structures to and from memory. - -`go_marshal` attempts to improve on `binary.Write` and the sentry's -`binary.Marshal` by moving the expensive use of reflection from runtime to -compile-time. - -`go_marshal` automatically generates implementations for `marshal.Marshallable` -interface. Data structures that require custom serialization can be accomodated -through a manual implementation this interface. - -Data structures can be flagged for code generation by adding a struct-level -comment `// +marshal`. For additional details and options, see the documentation -for the `marshal.Marshallable` interface. - -# Usage - -See `defs.bzl`: a new rule is provided, `go_marshal`. - -Under the hood, the `go_marshal` rule is used to generate a file that will -appear in a Go target; the output file should appear explicitly in a srcs list. -For example (note that the above is the preferred method): - -``` -load("<PKGPATH>/gvisor/tools/go_marshal:defs.bzl", "go_marshal") - -go_marshal( - name = "foo_abi", - srcs = ["foo.go"], - out = "foo_abi.go", - package = "foo", -) - -go_library( - name = "foo", - srcs = [ - "foo.go", - "foo_abi.go", - ], - ... -) -``` - -As part of the interface generation, `go_marshal` also generates some tests for -sanity checking the struct definitions for potential alignment issues, and a -simple round-trip test through Marshal/Unmarshal to verify the implementation. -These tests use reflection to verify properties of the ABI struct, and should be -considered part of the generated interfaces (but are too expensive to execute at -runtime). Ensure these tests run at some point. - -# Restrictions - -Not all valid go type definitions can be used with `go_marshal`. `go_marshal` is -intended for ABI structs, which have these additional restrictions: - -- At the moment, `go_marshal` only supports struct declarations. - -- Structs are marshalled as packed types. This means no implicit padding is - inserted between fields shorter than the platform register size. For - alignment, manually insert padding fields. - -- Structs used with `go_marshal` must have a compile-time static size. This - means no dynamically sizes fields like slices or strings. Use statically - sized array (byte arrays for strings) instead. - -- No pointers, channel, map or function pointer fields, and no fields that are - arrays of these types. These don't make sense in an ABI data structure. - -- We could support opaque pointers as `uintptr`, but this is currently not - implemented. Implementing this would require handling the architecture - dependent native pointer size. - -- Fields must either be a primitive integer type (`byte`, - `[u]int{8,16,32,64}`), or of a type that implements `marshal.Marshallable`. - -- `int` and `uint` fields are not allowed. Use an explicitly-sized numeric - type. - -- `float*` fields are currently not supported, but could be if necessary. - -# Appendix - -## Working with Non-Packed Structs - -ABI structs must generally be packed types, meaning they should have no implicit -padding between short fields. However, if a field is tagged -`marshal:"unaligned"`, `go_marshal` will fall back to a safer but slower -mechanism to deal with potentially unaligned fields. - -Note that the non-packed property is inheritted by any other struct that embeds -this struct, since the `go_marshal` tool currently can't reason about alignments -for embedded structs that are not aligned. - -Because of this, it's generally best to avoid using `marshal:"unaligned"` and -insert explicit padding fields instead. - -## Working with dynamically sized structs - -While `go_marshal` seamlessly supports statically sized structs (which most ABI -structs are), it can also used for other uses cases where marshalling is -required. There is some provision to partially support dynamically sized structs -that may not be ABI structs. A user can define a dynamic struct and define -`SizeBytes()`, `MarshalBytes(dst)` and `UnmarshalBytes(src)` for it. Then user -can then add a comment above the struct like `// +marshal dynamic` while will -make `go_marshal` autogenerate the remaining methods required to complete the -`Marshallable` interface. This feature is currently only available for structs -and can not be used alongside the Slice API. - -## Modifying the `go_marshal` Tool - -The following are some guidelines for modifying the `go_marshal` tool: - -- The `go_marshal` tool currently does a single pass over all types requesting - code generation, in arbitrary order. This means the generated code can't - directly obtain information about embedded marshallable types at - compile-time. One way to work around this restriction is to add a new - Marshallable interface method providing this piece of information, and - calling it from the generated code. Use this sparingly, as we want to rely - on compile-time information as much as possible for performance. - -- No runtime reflection in the code generated for the marshallable interface. - The entire point of the tool is to avoid runtime reflection. The generated - tests may use reflection. - -## Debugging - -To enable debugging output from the go-marshal tool, use one of the following -options, depending on how go-marshal is being invoked: - -- Pass `--define gomarshal=verbose` to the bazel command. Note that this can - generate a lot of output depending on what's being compiled, as this will - enable debugging for all packages built by the command. - -- Set `marshal_debug = True` on the top-level `go_library` BUILD rule. - -- Set `debug = True` on the `go_marshal` BUILD rule. - -- Pass `-debug` to the go-marshal tool invocation. - -If bazel complains about stdout output being too large, set a larger value -through `--experimental_ui_max_stdouterr_bytes`, or `-1` for unlimited output. |