Skip to content

Commit 0e492a2

Browse files
amscannegvisor-bot
authored andcommitted
Refactor nogo and provide facts render.
This change makes the core nogo package less of a "catch all", and splits functionality into multiple packages. Instead of separate binaries for each function, a single "cli" package is added with subcommands, and the core starlark wrappers are also refactored to minimize redundancy. The new "cli" package also adds support for a "render" command, which allows factors to be rendered via a Go text template. This is useful for debugging, but also allows code generation to be updated to use this mechanism. This eliminates the use of a QEMU wrapper for the older arch_genrule, and allows the use of a native bazel transition to extract facts for the appropriate generated file. In other words, the correct facts will be rendered for generating XXX_arm64.s, even on amd64. PiperOrigin-RevId: 422846459
1 parent 3d578af commit 0e492a2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+3228
-2205
lines changed

BUILD

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ doc(
5454
yaml_test(
5555
name = "nogo_config_test",
5656
srcs = glob(["nogo*.yaml"]),
57-
schema = "//tools/nogo:config-schema.json",
57+
schema = "//tools/nogo/config:schema.json",
5858
)
5959

6060
yaml_test(

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ nogo-tests:
196196
# For unit tests, we take everything in the root, pkg/... and tools/..., and
197197
# pull in all directories in runsc except runsc/container.
198198
unit-tests: ## Local package unit tests in pkg/..., tools/.., etc.
199-
@$(call test,--build_tag_filters=-nogo --test_tag_filters=-nogo --test_filter=-//runsc/container/... //:all pkg/... tools/... runsc/...)
199+
@$(call test,--build_tag_filters=-nogo --test_tag_filters=-nogo --test_filter=-//runsc/container/... //:all pkg/... tools/... runsc/... vdso/...)
200200
.PHONY: unit-tests
201201

202202
# See unit-tests: this includes runsc/container.

WORKSPACE

-9
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ http_archive(
3636
name = "io_bazel_rules_go",
3737
patch_args = ["-p1"],
3838
patches = [
39-
# Ensure we don't destroy the facts visibility.
40-
"//tools:rules_go_visibility.patch",
4139
# Newer versions of the rules_go rules will automatically strip test
4240
# binaries of symbols, which we don't want.
4341
"//tools:rules_go_symbols.patch",
@@ -51,13 +49,6 @@ http_archive(
5149

5250
http_archive(
5351
name = "bazel_gazelle",
54-
patch_args = ["-p1"],
55-
patches = [
56-
# Fix permissions for facts for go_library, not just tool library.
57-
# This is actually a no-op with the hacky patch above, but should
58-
# slightly future proof this mechanism.
59-
"//tools:bazel_gazelle_generate.patch",
60-
],
6152
sha256 = "62ca106be173579c0a167deb23358fdfe71ffa1e4cfdddf5582af26520f1c66f",
6253
urls = [
6354
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.23.0/bazel-gazelle-v0.23.0.tar.gz",

pkg/ring0/BUILD

+30-49
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,50 @@
1-
load("//tools:defs.bzl", "arch_genrule", "go_library")
2-
load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance")
1+
load("//tools:defs.bzl", "arch_genrule", "go_library", "select_arch")
2+
load("//tools/nogo:defs.bzl", "nogo_facts")
33

44
package(licenses = ["notice"])
55

6-
go_template(
7-
name = "defs_amd64",
8-
srcs = [
9-
"defs.go",
10-
"defs_amd64.go",
11-
"offsets_amd64.go",
12-
"x86.go",
13-
],
14-
visibility = [":__subpackages__"],
15-
)
6+
exports_files(glob(["*.go"]))
167

17-
go_template(
18-
name = "defs_arm64",
8+
nogo_facts(
9+
name = "entry_impl",
1910
srcs = [
2011
"aarch64.go",
2112
"defs.go",
13+
"defs_amd64.go",
2214
"defs_arm64.go",
23-
"offsets_arm64.go",
15+
"entry_template.go",
16+
"x86.go",
17+
],
18+
output = "entry_impl.s",
19+
template = select_arch(
20+
amd64 = "entry_amd64.s",
21+
arm64 = "entry_arm64.s",
22+
),
23+
deps = [
24+
"//pkg/abi/linux",
25+
"//pkg/cpuid",
26+
"//pkg/hostarch",
27+
"//pkg/ring0/pagetables",
28+
"//pkg/sentry/arch",
29+
"//pkg/sentry/arch/fpu",
2430
],
25-
visibility = [":__subpackages__"],
26-
)
27-
28-
go_template_instance(
29-
name = "defs_impl_amd64",
30-
out = "defs_impl_amd64.go",
31-
package = "ring0",
32-
template = ":defs_amd64",
33-
)
34-
35-
go_template_instance(
36-
name = "defs_impl_arm64",
37-
out = "defs_impl_arm64.go",
38-
package = "ring0",
39-
template = ":defs_arm64",
40-
)
41-
42-
arch_genrule(
43-
name = "entry_impl_amd64",
44-
srcs = ["entry_amd64.s"],
45-
outs = ["entry_impl_amd64.s"],
46-
cmd = "(echo -e '// build +amd64\\n' && QEMU $(location //pkg/ring0/gen_offsets) && cat $(location entry_amd64.s)) > $@",
47-
tools = ["//pkg/ring0/gen_offsets"],
4831
)
4932

5033
arch_genrule(
51-
name = "entry_impl_arm64",
52-
srcs = ["entry_arm64.s"],
53-
outs = ["entry_impl_arm64.s"],
54-
cmd = "(echo -e '// build +arm64\\n' && QEMU $(location //pkg/ring0/gen_offsets) && cat $(location entry_arm64.s)) > $@",
55-
tools = ["//pkg/ring0/gen_offsets"],
34+
name = "entry_impl_arch",
35+
src = ":entry_impl",
36+
template = "entry_impl_%s.s",
5637
)
5738

5839
go_library(
5940
name = "ring0",
6041
srcs = [
61-
"defs_impl_amd64.go",
62-
"defs_impl_arm64.go",
42+
"aarch64.go",
43+
"defs.go",
44+
"defs_amd64.go",
45+
"defs_arm64.go",
6346
"entry_amd64.go",
6447
"entry_arm64.go",
65-
"entry_impl_amd64.s",
66-
"entry_impl_arm64.s",
6748
"kernel.go",
6849
"kernel_amd64.go",
6950
"kernel_arm64.go",
@@ -73,15 +54,15 @@ go_library(
7354
"lib_arm64.go",
7455
"lib_arm64.s",
7556
"ring0.go",
57+
"x86.go",
58+
":entry_impl_arch",
7659
],
7760
visibility = ["//pkg/sentry:internal"],
7861
deps = [
7962
"//pkg/cpuid",
8063
"//pkg/hostarch",
8164
"//pkg/ring0/pagetables",
82-
"//pkg/safecopy",
8365
"//pkg/sentry/arch",
8466
"//pkg/sentry/arch/fpu",
85-
"//pkg/sync",
8667
],
8768
)

pkg/ring0/defs_arm64.go

-3
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,3 @@ type SwitchArchOpts struct {
137137
// KernelASID indicates that the kernel ASID to be used on return,
138138
KernelASID uint16
139139
}
140-
141-
func init() {
142-
}

pkg/ring0/entry_amd64.s

+71-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,77 @@
1515
#include "funcdata.h"
1616
#include "textflag.h"
1717

18-
// NB: Offsets are programmatically generated (see BUILD).
19-
//
20-
// This file is concatenated with the definitions.
18+
// CPU offsets.
19+
#define CPU_REGISTERS {{ .CPU.registers.Offset }}
20+
#define CPU_FPU_STATE {{ .CPU.floatingPointState.Offset }}
21+
#define CPU_ERROR_CODE ({{ .CPU.CPUArchState.Offset }}+{{ .CPUArchState.errorCode.Offset }})
22+
#define CPU_ERROR_TYPE ({{ .CPU.CPUArchState.Offset }}+{{ .CPUArchState.errorType.Offset }})
23+
#define CPU_ENTRY ({{ .CPU.CPUArchState.Offset }}+{{ .CPUArchState.kernelEntry.Offset }})
24+
#define CPU_HAS_XSAVE ({{ .CPU.CPUArchState.Offset }}+{{ .CPUArchState.hasXSAVE.Offset }})
25+
#define CPU_HAS_XSAVEOPT ({{ .CPU.CPUArchState.Offset }}+{{ .CPUArchState.hasXSAVEOPT.Offset }})
26+
27+
{{ with .kernelEntry }}
28+
#define ENTRY_SCRATCH0 {{ .scratch0.Offset }}
29+
#define ENTRY_STACK_TOP {{ .stackTop.Offset }}
30+
#define ENTRY_CPU_SELF {{ .cpuSelf.Offset }}
31+
#define ENTRY_KERNEL_CR3 {{ .kernelCR3.Offset }}
32+
{{ end }}
33+
34+
// Bits.
35+
#define _RFLAGS_IF {{ ._RFLAGS_IF.Value }}
36+
#define _RFLAGS_IOPL0 {{ ._RFLAGS_IOPL0.Value }}
37+
#define _KERNEL_FLAGS {{ .KernelFlagsSet.Value }}
38+
39+
// Vectors.
40+
#define DivideByZero {{ .DivideByZero.Value }}
41+
#define Debug {{ .Debug.Value }}
42+
#define NMI {{ .NMI.Value }}
43+
#define Breakpoint {{ .Breakpoint.Value }}
44+
#define Overflow {{ .Overflow.Value }}
45+
#define BoundRangeExceeded {{ .BoundRangeExceeded.Value }}
46+
#define InvalidOpcode {{ .InvalidOpcode.Value }}
47+
#define DeviceNotAvailable {{ .DeviceNotAvailable.Value }}
48+
#define DoubleFault {{ .DoubleFault.Value }}
49+
#define CoprocessorSegmentOverrun {{ .CoprocessorSegmentOverrun.Value }}
50+
#define InvalidTSS {{ .InvalidTSS.Value }}
51+
#define SegmentNotPresent {{ .SegmentNotPresent.Value }}
52+
#define StackSegmentFault {{ .StackSegmentFault.Value }}
53+
#define GeneralProtectionFault {{ .GeneralProtectionFault.Value }}
54+
#define PageFault {{ .PageFault.Value }}
55+
#define X87FloatingPointException {{ .X87FloatingPointException.Value }}
56+
#define AlignmentCheck {{ .AlignmentCheck.Value }}
57+
#define MachineCheck {{ .MachineCheck.Value }}
58+
#define SIMDFloatingPointException {{ .SIMDFloatingPointException.Value }}
59+
#define VirtualizationException {{ .VirtualizationException.Value }}
60+
#define SecurityException {{ .SecurityException.Value }}
61+
#define SyscallInt80 {{ .SyscallInt80.Value }}
62+
#define Syscall {{ .Syscall.Value }}
63+
64+
{{ with .import.linux.PtraceRegs }}
65+
#define PTRACE_R15 {{ .R15.Offset }}
66+
#define PTRACE_R14 {{ .R14.Offset }}
67+
#define PTRACE_R13 {{ .R13.Offset }}
68+
#define PTRACE_R12 {{ .R12.Offset }}
69+
#define PTRACE_RBP {{ .Rbp.Offset }}
70+
#define PTRACE_RBX {{ .Rbx.Offset }}
71+
#define PTRACE_R11 {{ .R11.Offset }}
72+
#define PTRACE_R10 {{ .R10.Offset }}
73+
#define PTRACE_R9 {{ .R9.Offset }}
74+
#define PTRACE_R8 {{ .R8.Offset }}
75+
#define PTRACE_RAX {{ .Rax.Offset }}
76+
#define PTRACE_RCX {{ .Rcx.Offset }}
77+
#define PTRACE_RDX {{ .Rdx.Offset }}
78+
#define PTRACE_RSI {{ .Rsi.Offset }}
79+
#define PTRACE_RDI {{ .Rdi.Offset }}
80+
#define PTRACE_ORIGRAX {{ .Orig_rax.Offset }}
81+
#define PTRACE_RIP {{ .Rip.Offset }}
82+
#define PTRACE_CS {{ .Cs.Offset }}
83+
#define PTRACE_FLAGS {{ .Eflags.Offset }}
84+
#define PTRACE_RSP {{ .Rsp.Offset }}
85+
#define PTRACE_SS {{ .Ss.Offset }}
86+
#define PTRACE_FS_BASE {{ .Fs_base.Offset }}
87+
#define PTRACE_GS_BASE {{ .Gs_base.Offset }}
88+
{{ end }}
2189

2290
// Saves a register set.
2391
//

pkg/ring0/entry_arm64.s

+92-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,98 @@
1515
#include "funcdata.h"
1616
#include "textflag.h"
1717

18-
// NB: Offsets are programatically generated (see BUILD).
19-
//
20-
// This file is concatenated with the definitions.
18+
{{ with .CPU }}
19+
#define CPU_SELF {{ .self.Offset }}
20+
#define CPU_REGISTERS {{ .registers.Offset }}
21+
{{ end }}
22+
{{ with .CPUArchState }}
23+
#define CPU_STACK_TOP ({{ .stack.Offset }} + {{ .stack.Size }})
24+
#define CPU_ERROR_CODE {{ .errorCode.Offset }}
25+
#define CPU_ERROR_TYPE {{ .errorType.Offset }}
26+
#define CPU_FAULT_ADDR {{ .faultAddr.Offset }}
27+
#define CPU_FPSTATE_EL0 {{ .el0Fp.Offset }}
28+
#define CPU_TTBR0_KVM {{ .ttbr0Kvm.Offset }}
29+
#define CPU_TTBR0_APP {{ .ttbr0App.Offset }}
30+
#define CPU_VECTOR_CODE {{ .vecCode.Offset }}
31+
#define CPU_APP_ADDR {{ .appAddr.Offset }}
32+
#define CPU_LAZY_VFP {{ .lazyVFP.Offset }}
33+
#define CPU_APP_ASID {{ .appASID.Offset }}
34+
{{ end }}
35+
36+
// Bits.
37+
#define _KERNEL_FLAGS {{ .KernelFlagsSet.Value }}
38+
39+
// Vectors.
40+
#define El1Sync {{ .El1Sync.Value }}
41+
#define El1Irq {{ .El1Irq.Value }}
42+
#define El1Fiq {{ .El1Fiq.Value }}
43+
#define El1Err {{ .El1Err.Value }}
44+
#define El0Sync {{ .El0Sync.Value }}
45+
#define El0Irq {{ .El0Irq.Value }}
46+
#define El0Fiq {{ .El0Fiq.Value }}
47+
#define El0Err {{ .El0Err.Value }}
48+
#define El1SyncDa {{ .El1SyncDa.Value }}
49+
#define El1SyncIa {{ .El1SyncIa.Value }}
50+
#define El1SyncSpPc {{ .El1SyncSpPc.Value }}
51+
#define El1SyncUndef {{ .El1SyncUndef.Value }}
52+
#define El1SyncDbg {{ .El1SyncDbg.Value }}
53+
#define El1SyncInv {{ .El1SyncInv.Value }}
54+
#define El0SyncSVC {{ .El0SyncSVC.Value }}
55+
#define El0SyncDa {{ .El0SyncDa.Value }}
56+
#define El0SyncIa {{ .El0SyncIa.Value }}
57+
#define El0SyncFpsimdAcc {{ .El0SyncFpsimdAcc.Value }}
58+
#define El0SyncSveAcc {{ .El0SyncSveAcc.Value }}
59+
#define El0SyncFpsimdExc {{ .El0SyncFpsimdExc.Value }}
60+
#define El0SyncSys {{ .El0SyncSys.Value }}
61+
#define El0SyncSpPc {{ .El0SyncSpPc.Value }}
62+
#define El0SyncUndef {{ .El0SyncUndef.Value }}
63+
#define El0SyncDbg {{ .El0SyncDbg.Value }}
64+
#define El0SyncWfx {{ .El0SyncWfx.Value }}
65+
#define El0SyncInv {{ .El0SyncInv.Value }}
66+
#define El0ErrNMI {{ .El0ErrNMI.Value }}
67+
#define PageFault {{ .PageFault.Value }}
68+
#define Syscall {{ .Syscall.Value }}
69+
#define VirtualizationException {{ .VirtualizationException.Value }}
70+
71+
{{ with .import.linux.PtraceRegs }}
72+
#define PTRACE_R0 ({{ .Regs.Offset }} + 0*8)
73+
#define PTRACE_R1 ({{ .Regs.Offset }} + 1*8)
74+
#define PTRACE_R2 ({{ .Regs.Offset }} + 2*8)
75+
#define PTRACE_R3 ({{ .Regs.Offset }} + 3*8)
76+
#define PTRACE_R4 ({{ .Regs.Offset }} + 4*8)
77+
#define PTRACE_R5 ({{ .Regs.Offset }} + 5*8)
78+
#define PTRACE_R6 ({{ .Regs.Offset }} + 6*8)
79+
#define PTRACE_R7 ({{ .Regs.Offset }} + 7*8)
80+
#define PTRACE_R8 ({{ .Regs.Offset }} + 8*8)
81+
#define PTRACE_R9 ({{ .Regs.Offset }} + 9*8)
82+
#define PTRACE_R10 ({{ .Regs.Offset }} + 10*8)
83+
#define PTRACE_R11 ({{ .Regs.Offset }} + 11*8)
84+
#define PTRACE_R12 ({{ .Regs.Offset }} + 12*8)
85+
#define PTRACE_R13 ({{ .Regs.Offset }} + 13*8)
86+
#define PTRACE_R14 ({{ .Regs.Offset }} + 14*8)
87+
#define PTRACE_R15 ({{ .Regs.Offset }} + 15*8)
88+
#define PTRACE_R16 ({{ .Regs.Offset }} + 16*8)
89+
#define PTRACE_R17 ({{ .Regs.Offset }} + 17*8)
90+
#define PTRACE_R18 ({{ .Regs.Offset }} + 18*8)
91+
#define PTRACE_R19 ({{ .Regs.Offset }} + 19*8)
92+
#define PTRACE_R20 ({{ .Regs.Offset }} + 20*8)
93+
#define PTRACE_R21 ({{ .Regs.Offset }} + 21*8)
94+
#define PTRACE_R22 ({{ .Regs.Offset }} + 22*8)
95+
#define PTRACE_R23 ({{ .Regs.Offset }} + 23*8)
96+
#define PTRACE_R24 ({{ .Regs.Offset }} + 24*8)
97+
#define PTRACE_R25 ({{ .Regs.Offset }} + 25*8)
98+
#define PTRACE_R26 ({{ .Regs.Offset }} + 26*8)
99+
#define PTRACE_R27 ({{ .Regs.Offset }} + 27*8)
100+
#define PTRACE_R28 ({{ .Regs.Offset }} + 28*8)
101+
#define PTRACE_R29 ({{ .Regs.Offset }} + 29*8)
102+
#define PTRACE_R30 ({{ .Regs.Offset }} + 30*8)
103+
#define PTRACE_SP {{ .Sp.Offset }}
104+
#define PTRACE_PC {{ .Pc.Offset }}
105+
#define PTRACE_PSTATE {{ .Pstate.Offset }}
106+
{{ end }}
107+
{{ with .import.arch.Registers }}
108+
#define PTRACE_TLS {{ .TPIDR_EL0.Offset }}
109+
{{ end }}
21110

22111
// Saves a register set.
23112
//

pkg/ring0/gen_offsets/main.go pkg/ring0/entry_template.go

+3-7
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,9 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
// Binary gen_offsets is a helper for generating offset headers.
16-
package main
15+
package ring0
1716

1817
import (
19-
"os"
18+
// Used for template generation.
19+
_ "gvisor.dev/gvisor/pkg/abi/linux"
2020
)
21-
22-
func main() {
23-
Emit(os.Stdout)
24-
}

0 commit comments

Comments
 (0)