summaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/BUILD8
-rw-r--r--tools/bazeldefs/go.bzl2
-rw-r--r--tools/bigquery/BUILD1
-rw-r--r--tools/bigquery/bigquery.go8
-rw-r--r--tools/deps.bzl114
-rw-r--r--tools/go_marshal/defs.bzl3
-rw-r--r--tools/go_marshal/gomarshal/generator.go4
-rw-r--r--tools/go_marshal/gomarshal/generator_interfaces.go24
-rw-r--r--tools/go_marshal/gomarshal/generator_interfaces_array_newtype.go14
-rw-r--r--tools/go_marshal/gomarshal/generator_interfaces_dynamic.go12
-rw-r--r--tools/go_marshal/gomarshal/generator_interfaces_primitive_newtype.go60
-rw-r--r--tools/go_marshal/gomarshal/generator_interfaces_struct.go51
-rw-r--r--tools/go_marshal/gomarshal/generator_tests.go6
-rw-r--r--tools/go_marshal/test/BUILD3
-rw-r--r--tools/go_marshal/test/benchmark_test.go80
-rw-r--r--tools/go_marshal/test/escape/BUILD2
-rw-r--r--tools/go_marshal/test/escape/escape.go22
-rw-r--r--tools/go_marshal/test/marshal_test.go57
-rw-r--r--tools/nogo/analyzers.go6
-rw-r--r--tools/nogo/check/main.go17
-rw-r--r--tools/nogo/defs.bzl46
21 files changed, 327 insertions, 213 deletions
diff --git a/tools/BUILD b/tools/BUILD
index faf310676..3861ff2a5 100644
--- a/tools/BUILD
+++ b/tools/BUILD
@@ -9,3 +9,11 @@ bzl_library(
"//:sandbox",
],
)
+
+bzl_library(
+ name = "deps_bzl",
+ srcs = ["deps.bzl"],
+ visibility = [
+ "//:sandbox",
+ ],
+)
diff --git a/tools/bazeldefs/go.bzl b/tools/bazeldefs/go.bzl
index bcd8cffe7..d16376032 100644
--- a/tools/bazeldefs/go.bzl
+++ b/tools/bazeldefs/go.bzl
@@ -132,7 +132,7 @@ def go_context(ctx, goos = None, goarch = None, std = False):
runfiles = depset([go_ctx.go] + go_ctx.sdk.srcs + go_ctx.sdk.tools + go_ctx.stdlib.libs),
goos = go_ctx.sdk.goos,
goarch = go_ctx.sdk.goarch,
- tags = go_ctx.tags,
+ gotags = go_ctx.tags,
)
def select_goarch():
diff --git a/tools/bigquery/BUILD b/tools/bigquery/BUILD
index 1cea9e1c9..81994f954 100644
--- a/tools/bigquery/BUILD
+++ b/tools/bigquery/BUILD
@@ -12,5 +12,6 @@ go_library(
deps = [
"@com_google_cloud_go_bigquery//:go_default_library",
"@org_golang_google_api//option:go_default_library",
+ "@org_golang_x_oauth2//:go_default_library",
],
)
diff --git a/tools/bigquery/bigquery.go b/tools/bigquery/bigquery.go
index a4ca93ec2..935154acc 100644
--- a/tools/bigquery/bigquery.go
+++ b/tools/bigquery/bigquery.go
@@ -119,6 +119,14 @@ func NewBenchmark(name string, iters int) *Benchmark {
}
}
+// NewBenchmarkWithMetric creates a new sending to BigQuery, initialized with a
+// single iteration and single metric.
+func NewBenchmarkWithMetric(name, metric, unit string, value float64) *Benchmark {
+ b := NewBenchmark(name, 1)
+ b.AddMetric(metric, unit, value)
+ return b
+}
+
// NewSuite initializes a new Suite.
func NewSuite(name string, official bool) *Suite {
return &Suite{
diff --git a/tools/deps.bzl b/tools/deps.bzl
new file mode 100644
index 000000000..ed1135a9e
--- /dev/null
+++ b/tools/deps.bzl
@@ -0,0 +1,114 @@
+"""Rules for dependency checking."""
+
+# DepsInfo provides a list of dependencies found when building a target.
+DepsInfo = provider(
+ "lists dependencies encountered while building",
+ fields = {
+ "nodes": "a dict from targets to a list of their dependencies",
+ },
+)
+
+def _deps_check_impl(target, ctx):
+ # Check the target's dependencies and add any of our own deps.
+ deps = []
+ for dep in ctx.rule.attr.deps:
+ deps.append(dep)
+ nodes = {}
+ if len(deps) != 0:
+ nodes[target] = deps
+
+ # Keep and propagate each dep's providers.
+ for dep in ctx.rule.attr.deps:
+ nodes.update(dep[DepsInfo].nodes)
+
+ return [DepsInfo(nodes = nodes)]
+
+_deps_check = aspect(
+ implementation = _deps_check_impl,
+ attr_aspects = ["deps"],
+)
+
+def _is_allowed(target, allowlist, prefixes):
+ # Check for allowed prefixes.
+ for prefix in prefixes:
+ workspace, pfx = prefix.split("//", 1)
+ if len(workspace) > 0 and workspace[0] == "@":
+ workspace = workspace[1:]
+ if target.workspace_name == workspace and target.package.startswith(pfx):
+ return True
+
+ # Check the allowlist.
+ for allowed in allowlist:
+ if target == allowed.label:
+ return True
+
+ return False
+
+def _deps_test_impl(ctx):
+ nodes = {}
+ for target in ctx.attr.targets:
+ for (node_target, node_deps) in target[DepsInfo].nodes.items():
+ # Ignore any disallowed targets. This generates more useful error
+ # messages. Consider the case where A dependes on B and B depends
+ # on C, and both B and C are disallowed. Avoid emitting an error
+ # that B depends on C, when the real issue is that A depends on B.
+ if not _is_allowed(node_target.label, ctx.attr.allowed, ctx.attr.allowed_prefixes) and node_target.label != target.label:
+ continue
+ bad_deps = []
+ for dep in node_deps:
+ if not _is_allowed(dep.label, ctx.attr.allowed, ctx.attr.allowed_prefixes):
+ bad_deps.append(dep)
+ if len(bad_deps) > 0:
+ nodes[node_target] = bad_deps
+
+ # If there aren't any violations, write a passing test.
+ if len(nodes) == 0:
+ ctx.actions.write(
+ output = ctx.outputs.executable,
+ content = "#!/bin/bash\n\nexit 0\n",
+ )
+ return []
+
+ # If we're here, we've found at least one violation.
+ script_lines = [
+ "#!/bin/bash",
+ "echo Invalid dependencies found. If you\\'re sure you want to add dependencies,",
+ "echo modify this target.",
+ "echo",
+ ]
+
+ # List the violations.
+ for target, deps in nodes.items():
+ script_lines.append(
+ 'echo "{target} depends on:"'.format(target = target.label),
+ )
+ for dep in deps:
+ script_lines.append('echo "\t{dep}"'.format(dep = dep.label))
+
+ # The test must fail.
+ script_lines.append("exit 1\n")
+
+ ctx.actions.write(
+ output = ctx.outputs.executable,
+ content = "\n".join(script_lines),
+ )
+ return []
+
+# Checks that library and its deps only depends on gVisor and an allowlist of
+# other dependencies.
+deps_test = rule(
+ implementation = _deps_test_impl,
+ attrs = {
+ "targets": attr.label_list(
+ doc = "The targets to check the transitive dependencies of.",
+ aspects = [_deps_check],
+ ),
+ "allowed": attr.label_list(
+ doc = "The allowed dependency targets.",
+ ),
+ "allowed_prefixes": attr.string_list(
+ doc = "Any packages beginning with these prefixes are allowed.",
+ ),
+ },
+ test = True,
+)
diff --git a/tools/go_marshal/defs.bzl b/tools/go_marshal/defs.bzl
index f44f83eab..9f620cb76 100644
--- a/tools/go_marshal/defs.bzl
+++ b/tools/go_marshal/defs.bzl
@@ -57,8 +57,7 @@ go_marshal = rule(
# marshal_deps are the dependencies requied by generated code.
marshal_deps = [
"//pkg/gohacks",
- "//pkg/safecopy",
- "//pkg/usermem",
+ "//pkg/hostarch",
"//pkg/marshal",
]
diff --git a/tools/go_marshal/gomarshal/generator.go b/tools/go_marshal/gomarshal/generator.go
index 39394d2a7..00961c90d 100644
--- a/tools/go_marshal/gomarshal/generator.go
+++ b/tools/go_marshal/gomarshal/generator.go
@@ -112,10 +112,8 @@ func NewGenerator(srcs []string, out, outTest, outTestUnconditional, pkg string,
g.imports.add("runtime")
g.imports.add("unsafe")
g.imports.add("gvisor.dev/gvisor/pkg/gohacks")
- g.imports.add("gvisor.dev/gvisor/pkg/safecopy")
- g.imports.add("gvisor.dev/gvisor/pkg/usermem")
+ g.imports.add("gvisor.dev/gvisor/pkg/hostarch")
g.imports.add("gvisor.dev/gvisor/pkg/marshal")
-
return &g, nil
}
diff --git a/tools/go_marshal/gomarshal/generator_interfaces.go b/tools/go_marshal/gomarshal/generator_interfaces.go
index 65f5ea34d..3e643e77f 100644
--- a/tools/go_marshal/gomarshal/generator_interfaces.go
+++ b/tools/go_marshal/gomarshal/generator_interfaces.go
@@ -120,16 +120,16 @@ func (g *interfaceGenerator) marshalScalar(accessor, typ, bufVar string) {
g.emit("%s[0] = byte(%s)\n", bufVar, accessor)
g.shift(bufVar, 1)
case "int16", "uint16":
- g.recordUsedImport("usermem")
- g.emit("usermem.ByteOrder.PutUint16(%s[:2], uint16(%s))\n", bufVar, accessor)
+ g.recordUsedImport("hostarch")
+ g.emit("hostarch.ByteOrder.PutUint16(%s[:2], uint16(%s))\n", bufVar, accessor)
g.shift(bufVar, 2)
case "int32", "uint32":
- g.recordUsedImport("usermem")
- g.emit("usermem.ByteOrder.PutUint32(%s[:4], uint32(%s))\n", bufVar, accessor)
+ g.recordUsedImport("hostarch")
+ g.emit("hostarch.ByteOrder.PutUint32(%s[:4], uint32(%s))\n", bufVar, accessor)
g.shift(bufVar, 4)
case "int64", "uint64":
- g.recordUsedImport("usermem")
- g.emit("usermem.ByteOrder.PutUint64(%s[:8], uint64(%s))\n", bufVar, accessor)
+ g.recordUsedImport("hostarch")
+ g.emit("hostarch.ByteOrder.PutUint64(%s[:8], uint64(%s))\n", bufVar, accessor)
g.shift(bufVar, 8)
default:
g.emit("%s.MarshalBytes(%s[:%s.SizeBytes()])\n", accessor, bufVar, accessor)
@@ -147,16 +147,16 @@ func (g *interfaceGenerator) unmarshalScalar(accessor, typ, bufVar string) {
g.emit("%s = %s(%s[0])\n", accessor, typ, bufVar)
g.shift(bufVar, 1)
case "int16", "uint16":
- g.recordUsedImport("usermem")
- g.emit("%s = %s(usermem.ByteOrder.Uint16(%s[:2]))\n", accessor, typ, bufVar)
+ g.recordUsedImport("hostarch")
+ g.emit("%s = %s(hostarch.ByteOrder.Uint16(%s[:2]))\n", accessor, typ, bufVar)
g.shift(bufVar, 2)
case "int32", "uint32":
- g.recordUsedImport("usermem")
- g.emit("%s = %s(usermem.ByteOrder.Uint32(%s[:4]))\n", accessor, typ, bufVar)
+ g.recordUsedImport("hostarch")
+ g.emit("%s = %s(hostarch.ByteOrder.Uint32(%s[:4]))\n", accessor, typ, bufVar)
g.shift(bufVar, 4)
case "int64", "uint64":
- g.recordUsedImport("usermem")
- g.emit("%s = %s(usermem.ByteOrder.Uint64(%s[:8]))\n", accessor, typ, bufVar)
+ g.recordUsedImport("hostarch")
+ g.emit("%s = %s(hostarch.ByteOrder.Uint64(%s[:8]))\n", accessor, typ, bufVar)
g.shift(bufVar, 8)
default:
g.emit("%s.UnmarshalBytes(%s[:%s.SizeBytes()])\n", accessor, bufVar, accessor)
diff --git a/tools/go_marshal/gomarshal/generator_interfaces_array_newtype.go b/tools/go_marshal/gomarshal/generator_interfaces_array_newtype.go
index 7525b52da..bd7741ae5 100644
--- a/tools/go_marshal/gomarshal/generator_interfaces_array_newtype.go
+++ b/tools/go_marshal/gomarshal/generator_interfaces_array_newtype.go
@@ -33,13 +33,13 @@ func (g *interfaceGenerator) validateArrayNewtype(n *ast.Ident, a *ast.ArrayType
}
func (g *interfaceGenerator) emitMarshallableForArrayNewtype(n *ast.Ident, a *ast.ArrayType, elt *ast.Ident) {
+ g.recordUsedImport("gohacks")
+ g.recordUsedImport("hostarch")
g.recordUsedImport("io")
g.recordUsedImport("marshal")
g.recordUsedImport("reflect")
g.recordUsedImport("runtime")
- g.recordUsedImport("safecopy")
g.recordUsedImport("unsafe")
- g.recordUsedImport("usermem")
lenExpr := g.arrayLenExpr(a)
@@ -89,20 +89,20 @@ func (g *interfaceGenerator) emitMarshallableForArrayNewtype(n *ast.Ident, a *as
g.emit("// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.\n")
g.emit("func (%s *%s) MarshalUnsafe(dst []byte) {\n", g.r, g.typeName())
g.inIndent(func() {
- g.emit("safecopy.CopyIn(dst, unsafe.Pointer(%s))\n", g.r)
+ g.emit("gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(&%s[0]), uintptr(%s.SizeBytes()))\n", g.r, g.r)
})
g.emit("}\n\n")
g.emit("// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.\n")
g.emit("func (%s *%s) UnmarshalUnsafe(src []byte) {\n", g.r, g.typeName())
g.inIndent(func() {
- g.emit("safecopy.CopyOut(unsafe.Pointer(%s), src)\n", g.r)
+ g.emit("gohacks.Memmove(unsafe.Pointer(%s), unsafe.Pointer(&src[0]), uintptr(%s.SizeBytes()))\n", g.r, g.r)
})
g.emit("}\n\n")
g.emit("// CopyOutN implements marshal.Marshallable.CopyOutN.\n")
g.emit("//go:nosplit\n")
- g.emit("func (%s *%s) CopyOutN(cc marshal.CopyContext, addr usermem.Addr, limit int) (int, error) {\n", g.r, g.typeName())
+ g.emit("func (%s *%s) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {\n", g.r, g.typeName())
g.inIndent(func() {
g.emitCastToByteSlice(g.r, "buf", fmt.Sprintf("%s.SizeBytes()", g.r))
@@ -114,7 +114,7 @@ func (g *interfaceGenerator) emitMarshallableForArrayNewtype(n *ast.Ident, a *as
g.emit("// CopyOut implements marshal.Marshallable.CopyOut.\n")
g.emit("//go:nosplit\n")
- g.emit("func (%s *%s) CopyOut(cc marshal.CopyContext, addr usermem.Addr) (int, error) {\n", g.r, g.typeName())
+ g.emit("func (%s *%s) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {\n", g.r, g.typeName())
g.inIndent(func() {
g.emit("return %s.CopyOutN(cc, addr, %s.SizeBytes())\n", g.r, g.r)
})
@@ -122,7 +122,7 @@ func (g *interfaceGenerator) emitMarshallableForArrayNewtype(n *ast.Ident, a *as
g.emit("// CopyIn implements marshal.Marshallable.CopyIn.\n")
g.emit("//go:nosplit\n")
- g.emit("func (%s *%s) CopyIn(cc marshal.CopyContext, addr usermem.Addr) (int, error) {\n", g.r, g.typeName())
+ g.emit("func (%s *%s) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {\n", g.r, g.typeName())
g.inIndent(func() {
g.emitCastToByteSlice(g.r, "buf", fmt.Sprintf("%s.SizeBytes()", g.r))
diff --git a/tools/go_marshal/gomarshal/generator_interfaces_dynamic.go b/tools/go_marshal/gomarshal/generator_interfaces_dynamic.go
index b1a8622cd..345020ddc 100644
--- a/tools/go_marshal/gomarshal/generator_interfaces_dynamic.go
+++ b/tools/go_marshal/gomarshal/generator_interfaces_dynamic.go
@@ -46,8 +46,8 @@ func (g *interfaceGenerator) emitMarshallableForDynamicType() {
g.emit("// CopyOutN implements marshal.Marshallable.CopyOutN.\n")
g.emit("//go:nosplit\n")
g.recordUsedImport("marshal")
- g.recordUsedImport("usermem")
- g.emit("func (%s *%s) CopyOutN(cc marshal.CopyContext, addr usermem.Addr, limit int) (int, error) {\n", g.r, g.typeName())
+ g.recordUsedImport("hostarch")
+ g.emit("func (%s *%s) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {\n", g.r, g.typeName())
g.inIndent(func() {
g.emit("// Type %s doesn't have a packed layout in memory, fall back to MarshalBytes.\n", g.typeName())
g.emit("buf := cc.CopyScratchBuffer(%s.SizeBytes()) // escapes: okay.\n", g.r)
@@ -59,8 +59,8 @@ func (g *interfaceGenerator) emitMarshallableForDynamicType() {
g.emit("// CopyOut implements marshal.Marshallable.CopyOut.\n")
g.emit("//go:nosplit\n")
g.recordUsedImport("marshal")
- g.recordUsedImport("usermem")
- g.emit("func (%s *%s) CopyOut(cc marshal.CopyContext, addr usermem.Addr) (int, error) {\n", g.r, g.typeName())
+ g.recordUsedImport("hostarch")
+ g.emit("func (%s *%s) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {\n", g.r, g.typeName())
g.inIndent(func() {
g.emit("return %s.CopyOutN(cc, addr, %s.SizeBytes())\n", g.r, g.r)
})
@@ -69,8 +69,8 @@ func (g *interfaceGenerator) emitMarshallableForDynamicType() {
g.emit("// CopyIn implements marshal.Marshallable.CopyIn.\n")
g.emit("//go:nosplit\n")
g.recordUsedImport("marshal")
- g.recordUsedImport("usermem")
- g.emit("func (%s *%s) CopyIn(cc marshal.CopyContext, addr usermem.Addr) (int, error) {\n", g.r, g.typeName())
+ g.recordUsedImport("hostarch")
+ g.emit("func (%s *%s) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {\n", g.r, g.typeName())
g.inIndent(func() {
g.emit("// Type %s doesn't have a packed layout in memory, fall back to UnmarshalBytes.\n", g.typeName())
g.emit("buf := cc.CopyScratchBuffer(%s.SizeBytes()) // escapes: okay.\n", g.r)
diff --git a/tools/go_marshal/gomarshal/generator_interfaces_primitive_newtype.go b/tools/go_marshal/gomarshal/generator_interfaces_primitive_newtype.go
index 7edaf666c..ba4b7324e 100644
--- a/tools/go_marshal/gomarshal/generator_interfaces_primitive_newtype.go
+++ b/tools/go_marshal/gomarshal/generator_interfaces_primitive_newtype.go
@@ -29,14 +29,14 @@ func (g *interfaceGenerator) marshalPrimitiveScalar(accessor, typ, bufVar string
case "int8", "uint8", "byte":
g.emit("%s[0] = byte(*%s)\n", bufVar, accessor)
case "int16", "uint16":
- g.recordUsedImport("usermem")
- g.emit("usermem.ByteOrder.PutUint16(%s[:2], uint16(*%s))\n", bufVar, accessor)
+ g.recordUsedImport("hostarch")
+ g.emit("hostarch.ByteOrder.PutUint16(%s[:2], uint16(*%s))\n", bufVar, accessor)
case "int32", "uint32":
- g.recordUsedImport("usermem")
- g.emit("usermem.ByteOrder.PutUint32(%s[:4], uint32(*%s))\n", bufVar, accessor)
+ g.recordUsedImport("hostarch")
+ g.emit("hostarch.ByteOrder.PutUint32(%s[:4], uint32(*%s))\n", bufVar, accessor)
case "int64", "uint64":
- g.recordUsedImport("usermem")
- g.emit("usermem.ByteOrder.PutUint64(%s[:8], uint64(*%s))\n", bufVar, accessor)
+ g.recordUsedImport("hostarch")
+ g.emit("hostarch.ByteOrder.PutUint64(%s[:8], uint64(*%s))\n", bufVar, accessor)
default:
g.emit("// Explicilty cast to the underlying type before dispatching to\n")
g.emit("// MarshalBytes, so we don't recursively call %s.MarshalBytes\n", accessor)
@@ -53,14 +53,14 @@ func (g *interfaceGenerator) unmarshalPrimitiveScalar(accessor, typ, bufVar, typ
case "int8", "uint8":
g.emit("*%s = %s(%s(%s[0]))\n", accessor, typeCast, typ, bufVar)
case "int16", "uint16":
- g.recordUsedImport("usermem")
- g.emit("*%s = %s(%s(usermem.ByteOrder.Uint16(%s[:2])))\n", accessor, typeCast, typ, bufVar)
+ g.recordUsedImport("hostarch")
+ g.emit("*%s = %s(%s(hostarch.ByteOrder.Uint16(%s[:2])))\n", accessor, typeCast, typ, bufVar)
case "int32", "uint32":
- g.recordUsedImport("usermem")
- g.emit("*%s = %s(%s(usermem.ByteOrder.Uint32(%s[:4])))\n", accessor, typeCast, typ, bufVar)
+ g.recordUsedImport("hostarch")
+ g.emit("*%s = %s(%s(hostarch.ByteOrder.Uint32(%s[:4])))\n", accessor, typeCast, typ, bufVar)
case "int64", "uint64":
- g.recordUsedImport("usermem")
- g.emit("*%s = %s(%s(usermem.ByteOrder.Uint64(%s[:8])))\n", accessor, typeCast, typ, bufVar)
+ g.recordUsedImport("hostarch")
+ g.emit("*%s = %s(%s(hostarch.ByteOrder.Uint64(%s[:8])))\n", accessor, typeCast, typ, bufVar)
default:
g.emit("// Explicilty cast to the underlying type before dispatching to\n")
g.emit("// UnmarshalBytes, so we don't recursively call %s.UnmarshalBytes\n", accessor)
@@ -95,13 +95,13 @@ func (g *interfaceGenerator) validatePrimitiveNewtype(t *ast.Ident) {
// newtypes are always packed, so we can omit the various fallbacks required for
// non-packed structs.
func (g *interfaceGenerator) emitMarshallableForPrimitiveNewtype(nt *ast.Ident) {
+ g.recordUsedImport("gohacks")
+ g.recordUsedImport("hostarch")
g.recordUsedImport("io")
g.recordUsedImport("marshal")
g.recordUsedImport("reflect")
g.recordUsedImport("runtime")
- g.recordUsedImport("safecopy")
g.recordUsedImport("unsafe")
- g.recordUsedImport("usermem")
g.emit("// SizeBytes implements marshal.Marshallable.SizeBytes.\n")
g.emit("//go:nosplit\n")
@@ -141,20 +141,20 @@ func (g *interfaceGenerator) emitMarshallableForPrimitiveNewtype(nt *ast.Ident)
g.emit("// MarshalUnsafe implements marshal.Marshallable.MarshalUnsafe.\n")
g.emit("func (%s *%s) MarshalUnsafe(dst []byte) {\n", g.r, g.typeName())
g.inIndent(func() {
- g.emit("safecopy.CopyIn(dst, unsafe.Pointer(%s))\n", g.r)
+ g.emit("gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(%s), uintptr(%s.SizeBytes()))\n", g.r, g.r)
})
g.emit("}\n\n")
g.emit("// UnmarshalUnsafe implements marshal.Marshallable.UnmarshalUnsafe.\n")
g.emit("func (%s *%s) UnmarshalUnsafe(src []byte) {\n", g.r, g.typeName())
g.inIndent(func() {
- g.emit("safecopy.CopyOut(unsafe.Pointer(%s), src)\n", g.r)
+ g.emit("gohacks.Memmove(unsafe.Pointer(%s), unsafe.Pointer(&src[0]), uintptr(%s.SizeBytes()))\n", g.r, g.r)
})
g.emit("}\n\n")
g.emit("// CopyOutN implements marshal.Marshallable.CopyOutN.\n")
g.emit("//go:nosplit\n")
- g.emit("func (%s *%s) CopyOutN(cc marshal.CopyContext, addr usermem.Addr, limit int) (int, error) {\n", g.r, g.typeName())
+ g.emit("func (%s *%s) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {\n", g.r, g.typeName())
g.inIndent(func() {
g.emitCastToByteSlice(g.r, "buf", fmt.Sprintf("%s.SizeBytes()", g.r))
@@ -166,7 +166,7 @@ func (g *interfaceGenerator) emitMarshallableForPrimitiveNewtype(nt *ast.Ident)
g.emit("// CopyOut implements marshal.Marshallable.CopyOut.\n")
g.emit("//go:nosplit\n")
- g.emit("func (%s *%s) CopyOut(cc marshal.CopyContext, addr usermem.Addr) (int, error) {\n", g.r, g.typeName())
+ g.emit("func (%s *%s) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {\n", g.r, g.typeName())
g.inIndent(func() {
g.emit("return %s.CopyOutN(cc, addr, %s.SizeBytes())\n", g.r, g.r)
})
@@ -174,7 +174,7 @@ func (g *interfaceGenerator) emitMarshallableForPrimitiveNewtype(nt *ast.Ident)
g.emit("// CopyIn implements marshal.Marshallable.CopyIn.\n")
g.emit("//go:nosplit\n")
- g.emit("func (%s *%s) CopyIn(cc marshal.CopyContext, addr usermem.Addr) (int, error) {\n", g.r, g.typeName())
+ g.emit("func (%s *%s) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {\n", g.r, g.typeName())
g.inIndent(func() {
g.emitCastToByteSlice(g.r, "buf", fmt.Sprintf("%s.SizeBytes()", g.r))
@@ -199,7 +199,7 @@ func (g *interfaceGenerator) emitMarshallableForPrimitiveNewtype(nt *ast.Ident)
func (g *interfaceGenerator) emitMarshallableSliceForPrimitiveNewtype(nt *ast.Ident, slice *sliceAPI) {
g.recordUsedImport("marshal")
- g.recordUsedImport("usermem")
+ g.recordUsedImport("hostarch")
g.recordUsedImport("reflect")
g.recordUsedImport("runtime")
g.recordUsedImport("unsafe")
@@ -211,7 +211,7 @@ func (g *interfaceGenerator) emitMarshallableSliceForPrimitiveNewtype(nt *ast.Id
g.emit("// Copy%sIn copies in a slice of %s objects from the task's memory.\n", slice.ident, eltType)
g.emit("//go:nosplit\n")
- g.emit("func Copy%sIn(cc marshal.CopyContext, addr usermem.Addr, dst []%s) (int, error) {\n", slice.ident, eltType)
+ g.emit("func Copy%sIn(cc marshal.CopyContext, addr hostarch.Addr, dst []%s) (int, error) {\n", slice.ident, eltType)
g.inIndent(func() {
g.emit("count := len(dst)\n")
g.emit("if count == 0 {\n")
@@ -231,7 +231,7 @@ func (g *interfaceGenerator) emitMarshallableSliceForPrimitiveNewtype(nt *ast.Id
g.emit("// Copy%sOut copies a slice of %s objects to the task's memory.\n", slice.ident, eltType)
g.emit("//go:nosplit\n")
- g.emit("func Copy%sOut(cc marshal.CopyContext, addr usermem.Addr, src []%s) (int, error) {\n", slice.ident, eltType)
+ g.emit("func Copy%sOut(cc marshal.CopyContext, addr hostarch.Addr, src []%s) (int, error) {\n", slice.ident, eltType)
g.inIndent(func() {
g.emit("count := len(src)\n")
g.emit("if count == 0 {\n")
@@ -260,11 +260,9 @@ func (g *interfaceGenerator) emitMarshallableSliceForPrimitiveNewtype(nt *ast.Id
g.emit("}\n")
g.emit("size := (*%s)(nil).SizeBytes()\n\n", g.typeName())
- g.emitNoEscapeSliceDataPointer("&src", "val")
-
- g.emit("length, err := safecopy.CopyIn(dst[:(size*count)], val)\n")
- g.emitKeepAlive("src")
- g.emit("return length, err\n")
+ g.emit("dst = dst[:size*count]\n")
+ g.emit("gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(&src[0]), uintptr(len(dst)))\n")
+ g.emit("return size*count, nil\n")
})
g.emit("}\n\n")
@@ -279,11 +277,9 @@ func (g *interfaceGenerator) emitMarshallableSliceForPrimitiveNewtype(nt *ast.Id
g.emit("}\n")
g.emit("size := (*%s)(nil).SizeBytes()\n\n", g.typeName())
- g.emitNoEscapeSliceDataPointer("&dst", "val")
-
- g.emit("length, err := safecopy.CopyOut(val, src[:(size*count)])\n")
- g.emitKeepAlive("dst")
- g.emit("return length, err\n")
+ g.emit("src = src[:(size*count)]\n")
+ g.emit("gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(&src[0]), uintptr(len(src)))\n")
+ g.emit("return size*count, nil\n")
})
g.emit("}\n\n")
}
diff --git a/tools/go_marshal/gomarshal/generator_interfaces_struct.go b/tools/go_marshal/gomarshal/generator_interfaces_struct.go
index 5f6306b8f..4c47218f1 100644
--- a/tools/go_marshal/gomarshal/generator_interfaces_struct.go
+++ b/tools/go_marshal/gomarshal/generator_interfaces_struct.go
@@ -270,18 +270,18 @@ func (g *interfaceGenerator) emitMarshallableForStruct(st *ast.StructType) {
g.emit("%s.MarshalBytes(dst)\n", g.r)
}
if thisPacked {
- g.recordUsedImport("safecopy")
+ g.recordUsedImport("gohacks")
g.recordUsedImport("unsafe")
if cond, ok := g.areFieldsPackedExpression(); ok {
g.emit("if %s {\n", cond)
g.inIndent(func() {
- g.emit("safecopy.CopyIn(dst, unsafe.Pointer(%s))\n", g.r)
+ g.emit("gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(%s), uintptr(%s.SizeBytes()))\n", g.r, g.r)
})
g.emit("} else {\n")
g.inIndent(fallback)
g.emit("}\n")
} else {
- g.emit("safecopy.CopyIn(dst, unsafe.Pointer(%s))\n", g.r)
+ g.emit("gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(%s), uintptr(%s.SizeBytes()))\n", g.r, g.r)
}
} else {
fallback()
@@ -297,30 +297,28 @@ func (g *interfaceGenerator) emitMarshallableForStruct(st *ast.StructType) {
g.emit("%s.UnmarshalBytes(src)\n", g.r)
}
if thisPacked {
- g.recordUsedImport("safecopy")
- g.recordUsedImport("unsafe")
+ g.recordUsedImport("gohacks")
if cond, ok := g.areFieldsPackedExpression(); ok {
g.emit("if %s {\n", cond)
g.inIndent(func() {
- g.emit("safecopy.CopyOut(unsafe.Pointer(%s), src)\n", g.r)
+ g.emit("gohacks.Memmove(unsafe.Pointer(%s), unsafe.Pointer(&src[0]), uintptr(%s.SizeBytes()))\n", g.r, g.r)
})
g.emit("} else {\n")
g.inIndent(fallback)
g.emit("}\n")
} else {
- g.emit("safecopy.CopyOut(unsafe.Pointer(%s), src)\n", g.r)
+ g.emit("gohacks.Memmove(unsafe.Pointer(%s), unsafe.Pointer(&src[0]), uintptr(%s.SizeBytes()))\n", g.r, g.r)
}
} else {
fallback()
}
})
g.emit("}\n\n")
-
g.emit("// CopyOutN implements marshal.Marshallable.CopyOutN.\n")
g.emit("//go:nosplit\n")
g.recordUsedImport("marshal")
- g.recordUsedImport("usermem")
- g.emit("func (%s *%s) CopyOutN(cc marshal.CopyContext, addr usermem.Addr, limit int) (int, error) {\n", g.r, g.typeName())
+ g.recordUsedImport("hostarch")
+ g.emit("func (%s *%s) CopyOutN(cc marshal.CopyContext, addr hostarch.Addr, limit int) (int, error) {\n", g.r, g.typeName())
g.inIndent(func() {
fallback := func() {
g.emit("// Type %s doesn't have a packed layout in memory, fall back to MarshalBytes.\n", g.typeName())
@@ -352,8 +350,8 @@ func (g *interfaceGenerator) emitMarshallableForStruct(st *ast.StructType) {
g.emit("// CopyOut implements marshal.Marshallable.CopyOut.\n")
g.emit("//go:nosplit\n")
g.recordUsedImport("marshal")
- g.recordUsedImport("usermem")
- g.emit("func (%s *%s) CopyOut(cc marshal.CopyContext, addr usermem.Addr) (int, error) {\n", g.r, g.typeName())
+ g.recordUsedImport("hostarch")
+ g.emit("func (%s *%s) CopyOut(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {\n", g.r, g.typeName())
g.inIndent(func() {
g.emit("return %s.CopyOutN(cc, addr, %s.SizeBytes())\n", g.r, g.r)
})
@@ -362,8 +360,8 @@ func (g *interfaceGenerator) emitMarshallableForStruct(st *ast.StructType) {
g.emit("// CopyIn implements marshal.Marshallable.CopyIn.\n")
g.emit("//go:nosplit\n")
g.recordUsedImport("marshal")
- g.recordUsedImport("usermem")
- g.emit("func (%s *%s) CopyIn(cc marshal.CopyContext, addr usermem.Addr) (int, error) {\n", g.r, g.typeName())
+ g.recordUsedImport("hostarch")
+ g.emit("func (%s *%s) CopyIn(cc marshal.CopyContext, addr hostarch.Addr) (int, error) {\n", g.r, g.typeName())
g.inIndent(func() {
fallback := func() {
g.emit("// Type %s doesn't have a packed layout in memory, fall back to UnmarshalBytes.\n", g.typeName())
@@ -436,10 +434,10 @@ func (g *interfaceGenerator) emitMarshallableSliceForStruct(st *ast.StructType,
}
g.recordUsedImport("marshal")
- g.recordUsedImport("usermem")
+ g.recordUsedImport("hostarch")
g.emit("// Copy%sIn copies in a slice of %s objects from the task's memory.\n", slice.ident, g.typeName())
- g.emit("func Copy%sIn(cc marshal.CopyContext, addr usermem.Addr, dst []%s) (int, error) {\n", slice.ident, g.typeName())
+ g.emit("func Copy%sIn(cc marshal.CopyContext, addr hostarch.Addr, dst []%s) (int, error) {\n", slice.ident, g.typeName())
g.inIndent(func() {
g.emit("count := len(dst)\n")
g.emit("if count == 0 {\n")
@@ -496,7 +494,7 @@ func (g *interfaceGenerator) emitMarshallableSliceForStruct(st *ast.StructType,
g.emit("}\n\n")
g.emit("// Copy%sOut copies a slice of %s objects to the task's memory.\n", slice.ident, g.typeName())
- g.emit("func Copy%sOut(cc marshal.CopyContext, addr usermem.Addr, src []%s) (int, error) {\n", slice.ident, g.typeName())
+ g.emit("func Copy%sOut(cc marshal.CopyContext, addr hostarch.Addr, src []%s) (int, error) {\n", slice.ident, g.typeName())
g.inIndent(func() {
g.emit("count := len(src)\n")
g.emit("if count == 0 {\n")
@@ -561,16 +559,15 @@ func (g *interfaceGenerator) emitMarshallableSliceForStruct(st *ast.StructType,
g.recordUsedImport("reflect")
g.recordUsedImport("runtime")
g.recordUsedImport("unsafe")
+ g.recordUsedImport("gohacks")
if _, ok := g.areFieldsPackedExpression(); ok {
g.emit("if !src[0].Packed() {\n")
g.inIndent(fallback)
g.emit("}\n\n")
}
- g.emitNoEscapeSliceDataPointer("&src", "val")
-
- g.emit("length, err := safecopy.CopyIn(dst[:(size*count)], val)\n")
- g.emitKeepAlive("src")
- g.emit("return length, err\n")
+ g.emit("dst = dst[:size*count]\n")
+ g.emit("gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(&src[0]), uintptr(len(dst)))\n")
+ g.emit("return size * count, nil\n")
} else {
fallback()
}
@@ -598,19 +595,19 @@ func (g *interfaceGenerator) emitMarshallableSliceForStruct(st *ast.StructType,
g.emit("return size * count, nil\n")
}
if thisPacked {
+ g.recordUsedImport("gohacks")
g.recordUsedImport("reflect")
g.recordUsedImport("runtime")
- g.recordUsedImport("unsafe")
if _, ok := g.areFieldsPackedExpression(); ok {
g.emit("if !dst[0].Packed() {\n")
g.inIndent(fallback)
g.emit("}\n\n")
}
- g.emitNoEscapeSliceDataPointer("&dst", "val")
- g.emit("length, err := safecopy.CopyOut(val, src[:(size*count)])\n")
- g.emitKeepAlive("dst")
- g.emit("return length, err\n")
+ g.emit("src = src[:(size*count)]\n")
+ g.emit("gohacks.Memmove(unsafe.Pointer(&dst[0]), unsafe.Pointer(&src[0]), uintptr(len(src)))\n")
+
+ g.emit("return count*size, nil\n")
} else {
fallback()
}
diff --git a/tools/go_marshal/gomarshal/generator_tests.go b/tools/go_marshal/gomarshal/generator_tests.go
index 6cf00843f..8f93a1de5 100644
--- a/tools/go_marshal/gomarshal/generator_tests.go
+++ b/tools/go_marshal/gomarshal/generator_tests.go
@@ -32,7 +32,7 @@ var standardImports = []string{
var sliceAPIImports = []string{
"encoding/binary",
- "gvisor.dev/gvisor/pkg/usermem",
+ "gvisor.dev/gvisor/pkg/hostarch",
}
type testGenerator struct {
@@ -143,7 +143,7 @@ func (g *testGenerator) emitTestMarshalUnmarshalPreservesData() {
}
func (g *testGenerator) emitTestMarshalUnmarshalSlicePreservesData(slice *sliceAPI) {
- for _, name := range []string{"binary", "usermem"} {
+ for _, name := range []string{"binary", "hostarch"} {
if !g.imports.markUsed(name) {
panic(fmt.Sprintf("Generated test for '%s' referenced a non-existent import with local name '%s'", g.typeName(), name))
}
@@ -155,7 +155,7 @@ func (g *testGenerator) emitTestMarshalUnmarshalSlicePreservesData(slice *sliceA
g.emit("size := (*%s)(nil).SizeBytes() * len(x)\n", g.typeName())
g.emit("buf := bytes.NewBuffer(make([]byte, size))\n")
g.emit("buf.Reset()\n")
- g.emit("if err := binary.Write(buf, usermem.ByteOrder, x[:]); err != nil {\n")
+ g.emit("if err := binary.Write(buf, hostarch.ByteOrder, x[:]); err != nil {\n")
g.inIndent(func() {
g.emit("t.Fatal(fmt.Sprintf(\"binary.Write failed: %v\", err))\n")
})
diff --git a/tools/go_marshal/test/BUILD b/tools/go_marshal/test/BUILD
index 5bceacd32..e872560a9 100644
--- a/tools/go_marshal/test/BUILD
+++ b/tools/go_marshal/test/BUILD
@@ -15,7 +15,7 @@ go_test(
deps = [
":test",
"//pkg/binary",
- "//pkg/usermem",
+ "//pkg/hostarch",
"//tools/go_marshal/analysis",
],
)
@@ -41,6 +41,7 @@ go_test(
srcs = ["marshal_test.go"],
deps = [
":test",
+ "//pkg/hostarch",
"//pkg/marshal",
"//pkg/marshal/primitive",
"//pkg/syserror",
diff --git a/tools/go_marshal/test/benchmark_test.go b/tools/go_marshal/test/benchmark_test.go
index 224d308c7..16f478ff7 100644
--- a/tools/go_marshal/test/benchmark_test.go
+++ b/tools/go_marshal/test/benchmark_test.go
@@ -22,7 +22,7 @@ import (
"testing"
"gvisor.dev/gvisor/pkg/binary"
- "gvisor.dev/gvisor/pkg/usermem"
+ "gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/tools/go_marshal/analysis"
"gvisor.dev/gvisor/tools/go_marshal/test"
)
@@ -39,10 +39,10 @@ func BenchmarkEncodingBinary(b *testing.B) {
for n := 0; n < b.N; n++ {
buf := bytes.NewBuffer(make([]byte, size))
buf.Reset()
- if err := encbin.Write(buf, usermem.ByteOrder, &s1); err != nil {
+ if err := encbin.Write(buf, hostarch.ByteOrder, &s1); err != nil {
b.Error("Write:", err)
}
- if err := encbin.Read(buf, usermem.ByteOrder, &s2); err != nil {
+ if err := encbin.Read(buf, hostarch.ByteOrder, &s2); err != nil {
b.Error("Read:", err)
}
}
@@ -66,8 +66,8 @@ func BenchmarkBinary(b *testing.B) {
for n := 0; n < b.N; n++ {
buf := make([]byte, 0, size)
- buf = binary.Marshal(buf, usermem.ByteOrder, &s1)
- binary.Unmarshal(buf, usermem.ByteOrder, &s2)
+ buf = binary.Marshal(buf, hostarch.ByteOrder, &s1)
+ binary.Unmarshal(buf, hostarch.ByteOrder, &s2)
}
b.StopTimer()
@@ -89,42 +89,42 @@ func BenchmarkMarshalManual(b *testing.B) {
buf := make([]byte, 0, s1.SizeBytes())
// Marshal
- buf = binary.AppendUint64(buf, usermem.ByteOrder, s1.Dev)
- buf = binary.AppendUint64(buf, usermem.ByteOrder, s1.Ino)
- buf = binary.AppendUint64(buf, usermem.ByteOrder, s1.Nlink)
- buf = binary.AppendUint32(buf, usermem.ByteOrder, s1.Mode)
- buf = binary.AppendUint32(buf, usermem.ByteOrder, s1.UID)
- buf = binary.AppendUint32(buf, usermem.ByteOrder, s1.GID)
- buf = binary.AppendUint32(buf, usermem.ByteOrder, 0)
- buf = binary.AppendUint64(buf, usermem.ByteOrder, s1.Rdev)
- buf = binary.AppendUint64(buf, usermem.ByteOrder, uint64(s1.Size))
- buf = binary.AppendUint64(buf, usermem.ByteOrder, uint64(s1.Blksize))
- buf = binary.AppendUint64(buf, usermem.ByteOrder, uint64(s1.Blocks))
- buf = binary.AppendUint64(buf, usermem.ByteOrder, uint64(s1.ATime.Sec))
- buf = binary.AppendUint64(buf, usermem.ByteOrder, uint64(s1.ATime.Nsec))
- buf = binary.AppendUint64(buf, usermem.ByteOrder, uint64(s1.MTime.Sec))
- buf = binary.AppendUint64(buf, usermem.ByteOrder, uint64(s1.MTime.Nsec))
- buf = binary.AppendUint64(buf, usermem.ByteOrder, uint64(s1.CTime.Sec))
- buf = binary.AppendUint64(buf, usermem.ByteOrder, uint64(s1.CTime.Nsec))
+ buf = binary.AppendUint64(buf, hostarch.ByteOrder, s1.Dev)
+ buf = binary.AppendUint64(buf, hostarch.ByteOrder, s1.Ino)
+ buf = binary.AppendUint64(buf, hostarch.ByteOrder, s1.Nlink)
+ buf = binary.AppendUint32(buf, hostarch.ByteOrder, s1.Mode)
+ buf = binary.AppendUint32(buf, hostarch.ByteOrder, s1.UID)
+ buf = binary.AppendUint32(buf, hostarch.ByteOrder, s1.GID)
+ buf = binary.AppendUint32(buf, hostarch.ByteOrder, 0)
+ buf = binary.AppendUint64(buf, hostarch.ByteOrder, s1.Rdev)
+ buf = binary.AppendUint64(buf, hostarch.ByteOrder, uint64(s1.Size))
+ buf = binary.AppendUint64(buf, hostarch.ByteOrder, uint64(s1.Blksize))
+ buf = binary.AppendUint64(buf, hostarch.ByteOrder, uint64(s1.Blocks))
+ buf = binary.AppendUint64(buf, hostarch.ByteOrder, uint64(s1.ATime.Sec))
+ buf = binary.AppendUint64(buf, hostarch.ByteOrder, uint64(s1.ATime.Nsec))
+ buf = binary.AppendUint64(buf, hostarch.ByteOrder, uint64(s1.MTime.Sec))
+ buf = binary.AppendUint64(buf, hostarch.ByteOrder, uint64(s1.MTime.Nsec))
+ buf = binary.AppendUint64(buf, hostarch.ByteOrder, uint64(s1.CTime.Sec))
+ buf = binary.AppendUint64(buf, hostarch.ByteOrder, uint64(s1.CTime.Nsec))
// Unmarshal
- s2.Dev = usermem.ByteOrder.Uint64(buf[0:8])
- s2.Ino = usermem.ByteOrder.Uint64(buf[8:16])
- s2.Nlink = usermem.ByteOrder.Uint64(buf[16:24])
- s2.Mode = usermem.ByteOrder.Uint32(buf[24:28])
- s2.UID = usermem.ByteOrder.Uint32(buf[28:32])
- s2.GID = usermem.ByteOrder.Uint32(buf[32:36])
+ s2.Dev = hostarch.ByteOrder.Uint64(buf[0:8])
+ s2.Ino = hostarch.ByteOrder.Uint64(buf[8:16])
+ s2.Nlink = hostarch.ByteOrder.Uint64(buf[16:24])
+ s2.Mode = hostarch.ByteOrder.Uint32(buf[24:28])
+ s2.UID = hostarch.ByteOrder.Uint32(buf[28:32])
+ s2.GID = hostarch.ByteOrder.Uint32(buf[32:36])
// Padding: buf[36:40]
- s2.Rdev = usermem.ByteOrder.Uint64(buf[40:48])
- s2.Size = int64(usermem.ByteOrder.Uint64(buf[48:56]))
- s2.Blksize = int64(usermem.ByteOrder.Uint64(buf[56:64]))
- s2.Blocks = int64(usermem.ByteOrder.Uint64(buf[64:72]))
- s2.ATime.Sec = int64(usermem.ByteOrder.Uint64(buf[72:80]))
- s2.ATime.Nsec = int64(usermem.ByteOrder.Uint64(buf[80:88]))
- s2.MTime.Sec = int64(usermem.ByteOrder.Uint64(buf[88:96]))
- s2.MTime.Nsec = int64(usermem.ByteOrder.Uint64(buf[96:104]))
- s2.CTime.Sec = int64(usermem.ByteOrder.Uint64(buf[104:112]))
- s2.CTime.Nsec = int64(usermem.ByteOrder.Uint64(buf[112:120]))
+ s2.Rdev = hostarch.ByteOrder.Uint64(buf[40:48])
+ s2.Size = int64(hostarch.ByteOrder.Uint64(buf[48:56]))
+ s2.Blksize = int64(hostarch.ByteOrder.Uint64(buf[56:64]))
+ s2.Blocks = int64(hostarch.ByteOrder.Uint64(buf[64:72]))
+ s2.ATime.Sec = int64(hostarch.ByteOrder.Uint64(buf[72:80]))
+ s2.ATime.Nsec = int64(hostarch.ByteOrder.Uint64(buf[80:88]))
+ s2.MTime.Sec = int64(hostarch.ByteOrder.Uint64(buf[88:96]))
+ s2.MTime.Nsec = int64(hostarch.ByteOrder.Uint64(buf[96:104]))
+ s2.CTime.Sec = int64(hostarch.ByteOrder.Uint64(buf[104:112]))
+ s2.CTime.Nsec = int64(hostarch.ByteOrder.Uint64(buf[112:120]))
}
b.StopTimer()
@@ -187,8 +187,8 @@ func BenchmarkBinarySlice(b *testing.B) {
for n := 0; n < b.N; n++ {
buf := make([]byte, 0, size)
- buf = binary.Marshal(buf, usermem.ByteOrder, &s1)
- binary.Unmarshal(buf, usermem.ByteOrder, &s2)
+ buf = binary.Marshal(buf, hostarch.ByteOrder, &s1)
+ binary.Unmarshal(buf, hostarch.ByteOrder, &s2)
}
b.StopTimer()
diff --git a/tools/go_marshal/test/escape/BUILD b/tools/go_marshal/test/escape/BUILD
index 2981ef196..62e0b4665 100644
--- a/tools/go_marshal/test/escape/BUILD
+++ b/tools/go_marshal/test/escape/BUILD
@@ -7,8 +7,8 @@ go_library(
testonly = 1,
srcs = ["escape.go"],
deps = [
+ "//pkg/hostarch",
"//pkg/marshal",
- "//pkg/usermem",
"//tools/go_marshal/test",
],
)
diff --git a/tools/go_marshal/test/escape/escape.go b/tools/go_marshal/test/escape/escape.go
index df14ae98e..1ac606862 100644
--- a/tools/go_marshal/test/escape/escape.go
+++ b/tools/go_marshal/test/escape/escape.go
@@ -16,8 +16,8 @@
package escape
import (
+ "gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/marshal"
- "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/tools/go_marshal/test"
)
@@ -29,21 +29,21 @@ func (*dummyCopyContext) CopyScratchBuffer(size int) []byte {
return make([]byte, size)
}
-func (*dummyCopyContext) CopyOutBytes(addr usermem.Addr, b []byte) (int, error) {
+func (*dummyCopyContext) CopyOutBytes(addr hostarch.Addr, b []byte) (int, error) {
return len(b), nil
}
-func (*dummyCopyContext) CopyInBytes(addr usermem.Addr, b []byte) (int, error) {
+func (*dummyCopyContext) CopyInBytes(addr hostarch.Addr, b []byte) (int, error) {
return len(b), nil
}
-func (t *dummyCopyContext) MarshalBytes(addr usermem.Addr, marshallable marshal.Marshallable) {
+func (t *dummyCopyContext) MarshalBytes(addr hostarch.Addr, marshallable marshal.Marshallable) {
buf := t.CopyScratchBuffer(marshallable.SizeBytes())
marshallable.MarshalBytes(buf)
t.CopyOutBytes(addr, buf)
}
-func (t *dummyCopyContext) MarshalUnsafe(addr usermem.Addr, marshallable marshal.Marshallable) {
+func (t *dummyCopyContext) MarshalUnsafe(addr hostarch.Addr, marshallable marshal.Marshallable) {
buf := t.CopyScratchBuffer(marshallable.SizeBytes())
marshallable.MarshalUnsafe(buf)
t.CopyOutBytes(addr, buf)
@@ -53,14 +53,14 @@ func (t *dummyCopyContext) MarshalUnsafe(addr usermem.Addr, marshallable marshal
//go:nosplit
func doCopyIn(t *dummyCopyContext) {
var stat test.Stat
- stat.CopyIn(t, usermem.Addr(0xf000ba12))
+ stat.CopyIn(t, hostarch.Addr(0xf000ba12))
}
// +checkescape:all
//go:nosplit
func doCopyOut(t *dummyCopyContext) {
var stat test.Stat
- stat.CopyOut(t, usermem.Addr(0xf000ba12))
+ stat.CopyOut(t, hostarch.Addr(0xf000ba12))
}
// +mustescape:builtin
@@ -70,7 +70,7 @@ func doMarshalBytesDirect(t *dummyCopyContext) {
var stat test.Stat
buf := t.CopyScratchBuffer(stat.SizeBytes())
stat.MarshalBytes(buf)
- t.CopyOutBytes(usermem.Addr(0xf000ba12), buf)
+ t.CopyOutBytes(hostarch.Addr(0xf000ba12), buf)
}
// +mustescape:builtin
@@ -80,7 +80,7 @@ func doMarshalUnsafeDirect(t *dummyCopyContext) {
var stat test.Stat
buf := t.CopyScratchBuffer(stat.SizeBytes())
stat.MarshalUnsafe(buf)
- t.CopyOutBytes(usermem.Addr(0xf000ba12), buf)
+ t.CopyOutBytes(hostarch.Addr(0xf000ba12), buf)
}
// +mustescape:local,heap
@@ -88,7 +88,7 @@ func doMarshalUnsafeDirect(t *dummyCopyContext) {
//go:nosplit
func doMarshalBytesViaMarshallable(t *dummyCopyContext) {
var stat test.Stat
- t.MarshalBytes(usermem.Addr(0xf000ba12), &stat)
+ t.MarshalBytes(hostarch.Addr(0xf000ba12), &stat)
}
// +mustescape:local,heap
@@ -96,5 +96,5 @@ func doMarshalBytesViaMarshallable(t *dummyCopyContext) {
//go:nosplit
func doMarshalUnsafeViaMarshallable(t *dummyCopyContext) {
var stat test.Stat
- t.MarshalUnsafe(usermem.Addr(0xf000ba12), &stat)
+ t.MarshalUnsafe(hostarch.Addr(0xf000ba12), &stat)
}
diff --git a/tools/go_marshal/test/marshal_test.go b/tools/go_marshal/test/marshal_test.go
index 733689c79..43bafbf96 100644
--- a/tools/go_marshal/test/marshal_test.go
+++ b/tools/go_marshal/test/marshal_test.go
@@ -27,6 +27,7 @@ import (
"unsafe"
"github.com/google/go-cmp/cmp"
+ "gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/marshal"
"gvisor.dev/gvisor/pkg/marshal/primitive"
"gvisor.dev/gvisor/pkg/syserror"
@@ -47,7 +48,7 @@ func (t *mockCopyContext) populate(val interface{}) {
var buf bytes.Buffer
// Use binary.Write so we aren't testing go-marshal against its own
// potentially buggy implementation.
- if err := binary.Write(&buf, usermem.ByteOrder, val); err != nil {
+ if err := binary.Write(&buf, hostarch.ByteOrder, val); err != nil {
panic(err)
}
t.taskMem.Bytes = buf.Bytes()
@@ -71,14 +72,14 @@ func (t *mockCopyContext) CopyScratchBuffer(size int) []byte {
// CopyOutBytes implements marshal.CopyContext.CopyOutBytes. The implementation
// completely ignores the target address and stores a copy of b in its
// internally buffer, overriding any previous contents.
-func (t *mockCopyContext) CopyOutBytes(_ usermem.Addr, b []byte) (int, error) {
+func (t *mockCopyContext) CopyOutBytes(_ hostarch.Addr, b []byte) (int, error) {
return t.taskMem.CopyOut(nil, 0, b, usermem.IOOpts{})
}
// CopyInBytes implements marshal.CopyContext.CopyInBytes. The implementation
// completely ignores the source address and always fills b from the begining of
// its internal buffer.
-func (t *mockCopyContext) CopyInBytes(_ usermem.Addr, b []byte) (int, error) {
+func (t *mockCopyContext) CopyInBytes(_ hostarch.Addr, b []byte) (int, error) {
return t.taskMem.CopyIn(nil, 0, b, usermem.IOOpts{})
}
@@ -91,7 +92,7 @@ func unsafeMemory(m marshal.Marshallable) []byte {
// since the layout isn't packed. Allocate a temporary buffer
// and marshal instead.
var buf bytes.Buffer
- if err := binary.Write(&buf, usermem.ByteOrder, m); err != nil {
+ if err := binary.Write(&buf, hostarch.ByteOrder, m); err != nil {
panic(err)
}
return buf.Bytes()
@@ -130,7 +131,7 @@ func unsafeMemorySlice(m interface{}, elt marshal.Marshallable) []byte {
// since the layout isn't packed. Allocate a temporary buffer
// and marshal instead.
var buf bytes.Buffer
- if err := binary.Write(&buf, usermem.ByteOrder, m); err != nil {
+ if err := binary.Write(&buf, hostarch.ByteOrder, m); err != nil {
panic(err)
}
return buf.Bytes()
@@ -176,7 +177,7 @@ func limitedCopyIn(t *testing.T, src, dst marshal.Marshallable, limit int) {
cc.populate(src)
cc.setLimit(limit)
- n, err := dst.CopyIn(&cc, usermem.Addr(0))
+ n, err := dst.CopyIn(&cc, hostarch.Addr(0))
if n != limit {
t.Errorf("CopyIn copied unexpected number of bytes, expected %d, got %d", limit, n)
}
@@ -206,7 +207,7 @@ func limitedCopyOut(t *testing.T, src marshal.Marshallable, limit int) {
var cc mockCopyContext
cc.setLimit(limit)
- n, err := src.CopyOut(&cc, usermem.Addr(0))
+ n, err := src.CopyOut(&cc, hostarch.Addr(0))
if n != limit {
t.Errorf("CopyOut copied unexpected number of bytes, expected %d, got %d", limit, n)
}
@@ -227,7 +228,7 @@ func copyOutN(t *testing.T, src marshal.Marshallable, limit int) {
var cc mockCopyContext
cc.setLimit(limit)
- n, err := src.CopyOutN(&cc, usermem.Addr(0), limit)
+ n, err := src.CopyOutN(&cc, hostarch.Addr(0), limit)
if err != nil {
t.Errorf("CopyOut returned unexpected error: %v", err)
}
@@ -304,18 +305,18 @@ func TestLimitedMarshalling(t *testing.T) {
func TestLimitedSliceMarshalling(t *testing.T) {
types := []struct {
arrayPtrType reflect.Type
- copySliceIn func(cc marshal.CopyContext, addr usermem.Addr, dstSlice interface{}) (int, error)
- copySliceOut func(cc marshal.CopyContext, addr usermem.Addr, srcSlice interface{}) (int, error)
+ copySliceIn func(cc marshal.CopyContext, addr hostarch.Addr, dstSlice interface{}) (int, error)
+ copySliceOut func(cc marshal.CopyContext, addr hostarch.Addr, srcSlice interface{}) (int, error)
unsafeMemory func(arrPtr interface{}) []byte
}{
// Packed types.
{
reflect.TypeOf((*[20]test.Stat)(nil)),
- func(cc marshal.CopyContext, addr usermem.Addr, dst interface{}) (int, error) {
+ func(cc marshal.CopyContext, addr hostarch.Addr, dst interface{}) (int, error) {
slice := dst.(*[20]test.Stat)[:]
return test.CopyStatSliceIn(cc, addr, slice)
},
- func(cc marshal.CopyContext, addr usermem.Addr, src interface{}) (int, error) {
+ func(cc marshal.CopyContext, addr hostarch.Addr, src interface{}) (int, error) {
slice := src.(*[20]test.Stat)[:]
return test.CopyStatSliceOut(cc, addr, slice)
},
@@ -326,11 +327,11 @@ func TestLimitedSliceMarshalling(t *testing.T) {
},
{
reflect.TypeOf((*[1]test.Stat)(nil)),
- func(cc marshal.CopyContext, addr usermem.Addr, dst interface{}) (int, error) {
+ func(cc marshal.CopyContext, addr hostarch.Addr, dst interface{}) (int, error) {
slice := dst.(*[1]test.Stat)[:]
return test.CopyStatSliceIn(cc, addr, slice)
},
- func(cc marshal.CopyContext, addr usermem.Addr, src interface{}) (int, error) {
+ func(cc marshal.CopyContext, addr hostarch.Addr, src interface{}) (int, error) {
slice := src.(*[1]test.Stat)[:]
return test.CopyStatSliceOut(cc, addr, slice)
},
@@ -341,11 +342,11 @@ func TestLimitedSliceMarshalling(t *testing.T) {
},
{
reflect.TypeOf((*[5]test.SignalSetAlias)(nil)),
- func(cc marshal.CopyContext, addr usermem.Addr, dst interface{}) (int, error) {
+ func(cc marshal.CopyContext, addr hostarch.Addr, dst interface{}) (int, error) {
slice := dst.(*[5]test.SignalSetAlias)[:]
return test.CopySignalSetAliasSliceIn(cc, addr, slice)
},
- func(cc marshal.CopyContext, addr usermem.Addr, src interface{}) (int, error) {
+ func(cc marshal.CopyContext, addr hostarch.Addr, src interface{}) (int, error) {
slice := src.(*[5]test.SignalSetAlias)[:]
return test.CopySignalSetAliasSliceOut(cc, addr, slice)
},
@@ -357,11 +358,11 @@ func TestLimitedSliceMarshalling(t *testing.T) {
// Non-packed types.
{
reflect.TypeOf((*[20]test.Type1)(nil)),
- func(cc marshal.CopyContext, addr usermem.Addr, dst interface{}) (int, error) {
+ func(cc marshal.CopyContext, addr hostarch.Addr, dst interface{}) (int, error) {
slice := dst.(*[20]test.Type1)[:]
return test.CopyType1SliceIn(cc, addr, slice)
},
- func(cc marshal.CopyContext, addr usermem.Addr, src interface{}) (int, error) {
+ func(cc marshal.CopyContext, addr hostarch.Addr, src interface{}) (int, error) {
slice := src.(*[20]test.Type1)[:]
return test.CopyType1SliceOut(cc, addr, slice)
},
@@ -372,11 +373,11 @@ func TestLimitedSliceMarshalling(t *testing.T) {
},
{
reflect.TypeOf((*[1]test.Type1)(nil)),
- func(cc marshal.CopyContext, addr usermem.Addr, dst interface{}) (int, error) {
+ func(cc marshal.CopyContext, addr hostarch.Addr, dst interface{}) (int, error) {
slice := dst.(*[1]test.Type1)[:]
return test.CopyType1SliceIn(cc, addr, slice)
},
- func(cc marshal.CopyContext, addr usermem.Addr, src interface{}) (int, error) {
+ func(cc marshal.CopyContext, addr hostarch.Addr, src interface{}) (int, error) {
slice := src.(*[1]test.Type1)[:]
return test.CopyType1SliceOut(cc, addr, slice)
},
@@ -387,11 +388,11 @@ func TestLimitedSliceMarshalling(t *testing.T) {
},
{
reflect.TypeOf((*[7]test.Type8)(nil)),
- func(cc marshal.CopyContext, addr usermem.Addr, dst interface{}) (int, error) {
+ func(cc marshal.CopyContext, addr hostarch.Addr, dst interface{}) (int, error) {
slice := dst.(*[7]test.Type8)[:]
return test.CopyType8SliceIn(cc, addr, slice)
},
- func(cc marshal.CopyContext, addr usermem.Addr, src interface{}) (int, error) {
+ func(cc marshal.CopyContext, addr hostarch.Addr, src interface{}) (int, error) {
slice := src.(*[7]test.Type8)[:]
return test.CopyType8SliceOut(cc, addr, slice)
},
@@ -444,7 +445,7 @@ func TestLimitedSliceMarshalling(t *testing.T) {
cc.populate(expected)
cc.setLimit(limit)
- n, err := tt.copySliceIn(&cc, usermem.Addr(0), actual)
+ n, err := tt.copySliceIn(&cc, hostarch.Addr(0), actual)
if n != limit {
t.Errorf("CopyIn copied unexpected number of bytes, expected %d, got %d", limit, n)
}
@@ -498,7 +499,7 @@ func TestLimitedSliceMarshalling(t *testing.T) {
cc.populate(expected)
cc.setLimit(limit)
- n, err := tt.copySliceOut(&cc, usermem.Addr(0), expected)
+ n, err := tt.copySliceOut(&cc, hostarch.Addr(0), expected)
if n != limit {
t.Errorf("CopyIn copied unexpected number of bytes, expected %d, got %d", limit, n)
}
@@ -523,14 +524,14 @@ func TestDynamicTypeStruct(t *testing.T) {
var cc mockCopyContext
cc.setLimit(t12.SizeBytes())
- if _, err := t12.CopyOut(&cc, usermem.Addr(0)); err != nil {
+ if _, err := t12.CopyOut(&cc, hostarch.Addr(0)); err != nil {
t.Fatalf("cc.CopyOut faile: %v", err)
}
res := test.Type12Dynamic{
Y: make([]primitive.Int64, len(t12.Y)),
}
- res.CopyIn(&cc, usermem.Addr(0))
+ res.CopyIn(&cc, hostarch.Addr(0))
if !reflect.DeepEqual(t12, res) {
t.Errorf("dynamic type is not same after marshalling and unmarshalling: before = %+v, after = %+v", t12, res)
}
@@ -541,12 +542,12 @@ func TestDynamicTypeIdentifier(t *testing.T) {
var cc mockCopyContext
cc.setLimit(s.SizeBytes())
- if _, err := s.CopyOut(&cc, usermem.Addr(0)); err != nil {
+ if _, err := s.CopyOut(&cc, hostarch.Addr(0)); err != nil {
t.Fatalf("cc.CopyOut faile: %v", err)
}
res := test.Type13Dynamic(make([]byte, len(s)))
- res.CopyIn(&cc, usermem.Addr(0))
+ res.CopyIn(&cc, hostarch.Addr(0))
if res != s {
t.Errorf("dynamic type is not same after marshalling and unmarshalling: before = %s, after = %s", s, res)
}
diff --git a/tools/nogo/analyzers.go b/tools/nogo/analyzers.go
index 8b4bff3b6..2b3c03fec 100644
--- a/tools/nogo/analyzers.go
+++ b/tools/nogo/analyzers.go
@@ -83,11 +83,6 @@ var AllAnalyzers = []*analysis.Analyzer{
checklocks.Analyzer,
}
-// EscapeAnalyzers is a list of escape-related analyzers.
-var EscapeAnalyzers = []*analysis.Analyzer{
- checkescape.EscapeAnalyzer,
-}
-
func register(all []*analysis.Analyzer) {
// Register all fact types.
//
@@ -129,5 +124,4 @@ func init() {
// Register lists.
register(AllAnalyzers)
- register(EscapeAnalyzers)
}
diff --git a/tools/nogo/check/main.go b/tools/nogo/check/main.go
index 69bdfe502..4194770be 100644
--- a/tools/nogo/check/main.go
+++ b/tools/nogo/check/main.go
@@ -31,7 +31,6 @@ var (
stdlibFile = flag.String("stdlib", "", "stdlib configuration file (in JSON format)")
findingsOutput = flag.String("findings", "", "output file (or stdout, if not specified)")
factsOutput = flag.String("facts", "", "output file for facts (optional)")
- escapesOutput = flag.String("escapes", "", "output file for escapes (optional)")
)
func loadConfig(file string, config interface{}) interface{} {
@@ -66,25 +65,13 @@ func main() {
// Run the configuration.
if *stdlibFile != "" {
- // Perform basic analysis.
+ // Perform stdlib analysis.
c := loadConfig(*stdlibFile, new(nogo.StdlibConfig)).(*nogo.StdlibConfig)
findings, factData, err = nogo.CheckStdlib(c, nogo.AllAnalyzers)
-
} else if *packageFile != "" {
- // Perform basic analysis.
+ // Perform standard analysis.
c := loadConfig(*packageFile, new(nogo.PackageConfig)).(*nogo.PackageConfig)
findings, factData, err = nogo.CheckPackage(c, nogo.AllAnalyzers, nil)
-
- // Do we need to do escape analysis?
- if *escapesOutput != "" {
- escapes, _, err := nogo.CheckPackage(c, nogo.EscapeAnalyzers, nil)
- if err != nil {
- log.Fatalf("error performing escape analysis: %v", err)
- }
- if err := nogo.WriteFindingsToFile(escapes, *escapesOutput); err != nil {
- log.Fatalf("error writing escapes to %q: %v", *escapesOutput, err)
- }
- }
} else {
log.Fatalf("please provide at least one of package or stdlib!")
}
diff --git a/tools/nogo/defs.bzl b/tools/nogo/defs.bzl
index 0c48a7a5a..be8b82f9c 100644
--- a/tools/nogo/defs.bzl
+++ b/tools/nogo/defs.bzl
@@ -120,7 +120,7 @@ def _nogo_stdlib_impl(ctx):
Srcs = [f.path for f in go_ctx.stdlib_srcs],
GOOS = go_ctx.goos,
GOARCH = go_ctx.goarch,
- Tags = go_ctx.tags,
+ Tags = go_ctx.gotags,
)
config_file = ctx.actions.declare_file(ctx.label.name + ".cfg")
ctx.actions.write(config_file, config.to_json())
@@ -174,7 +174,6 @@ NogoInfo = provider(
fields = {
"facts": "serialized package facts",
"raw_findings": "raw package findings (if relevant)",
- "escapes": "escape-only findings (if relevant)",
"importpath": "package import path",
"binaries": "package binary files",
"srcs": "srcs (for go_test support)",
@@ -281,14 +280,13 @@ def _nogo_aspect_impl(target, ctx):
go_ctx = go_context(ctx, goos = nogo_target_info.goos, goarch = nogo_target_info.goarch)
facts = ctx.actions.declare_file(target.label.name + ".facts")
raw_findings = ctx.actions.declare_file(target.label.name + ".raw_findings")
- escapes = ctx.actions.declare_file(target.label.name + ".escapes")
config = struct(
ImportPath = importpath,
GoFiles = [src.path for src in srcs if src.path.endswith(".go")],
NonGoFiles = [src.path for src in srcs if not src.path.endswith(".go")],
GOOS = go_ctx.goos,
GOARCH = go_ctx.goarch,
- Tags = go_ctx.tags,
+ Tags = go_ctx.gotags,
FactMap = fact_map,
ImportMap = import_map,
StdlibFacts = stdlib_facts.path,
@@ -298,7 +296,7 @@ def _nogo_aspect_impl(target, ctx):
inputs.append(config_file)
ctx.actions.run(
inputs = inputs,
- outputs = [facts, raw_findings, escapes],
+ outputs = [facts, raw_findings],
tools = depset(go_ctx.runfiles.to_list() + ctx.files._nogo_objdump_tool),
executable = ctx.files._nogo_check[0],
mnemonic = "NogoAnalysis",
@@ -309,7 +307,6 @@ def _nogo_aspect_impl(target, ctx):
"-package=%s" % config_file.path,
"-findings=%s" % raw_findings.path,
"-facts=%s" % facts.path,
- "-escapes=%s" % escapes.path,
],
)
@@ -322,15 +319,16 @@ def _nogo_aspect_impl(target, ctx):
all_raw_findings = [stdlib_info.raw_findings] + depset(all_raw_findings).to_list() + [raw_findings]
# Return the package facts as output.
- return [NogoInfo(
- facts = facts,
- raw_findings = all_raw_findings,
- escapes = escapes,
- importpath = importpath,
- binaries = binaries,
- srcs = srcs,
- deps = deps,
- )]
+ return [
+ NogoInfo(
+ facts = facts,
+ raw_findings = all_raw_findings,
+ importpath = importpath,
+ binaries = binaries,
+ srcs = srcs,
+ deps = deps,
+ ),
+ ]
nogo_aspect = go_rule(
aspect,
@@ -367,7 +365,6 @@ def _nogo_test_impl(ctx):
if len(ctx.attr.deps) != 1:
fail("nogo_test requires exactly one dep.")
raw_findings = ctx.attr.deps[0][NogoInfo].raw_findings
- escapes = ctx.attr.deps[0][NogoInfo].escapes
# Build a step that applies the configuration.
config_srcs = ctx.attr.config[NogoConfigInfo].srcs
@@ -409,8 +406,6 @@ def _nogo_test_impl(ctx):
# pays attention to the mnemoic above, so this must be
# what is expected by the tooling.
nogo_findings = depset([findings]),
- # Expose all escape analysis findings (see above).
- nogo_escapes = depset([escapes]),
)]
nogo_test = rule(
@@ -432,3 +427,18 @@ nogo_test = rule(
},
test = True,
)
+
+def _nogo_aspect_tricorder_impl(target, ctx):
+ if ctx.rule.kind != "nogo_test" or OutputGroupInfo not in target:
+ return []
+ if not hasattr(target[OutputGroupInfo], "nogo_findings"):
+ return []
+ return [
+ OutputGroupInfo(tricorder = target[OutputGroupInfo].nogo_findings),
+ ]
+
+# Trivial aspect that forwards the findings from a nogo_test rule to
+# go/tricorder, which reads from the `tricorder` output group.
+nogo_aspect_tricorder = aspect(
+ implementation = _nogo_aspect_tricorder_impl,
+)