diff --git a/pkg/ring0/entry_amd64.s b/pkg/ring0/entry_amd64.s index 775a46900..f30f48de6 100644 --- a/pkg/ring0/entry_amd64.s +++ b/pkg/ring0/entry_amd64.s @@ -34,34 +34,34 @@ {{ end }} // Bits. -#define _RFLAGS_IF {{ ._RFLAGS_IF.Value }} -#define _RFLAGS_IOPL0 {{ ._RFLAGS_IOPL0.Value }} -#define _KERNEL_FLAGS {{ .KernelFlagsSet.Value }} +#define _RFLAGS_IF {{ .Constants._RFLAGS_IF }} +#define _RFLAGS_IOPL0 {{ .Constants._RFLAGS_IOPL0 }} +#define _KERNEL_FLAGS {{ .Constants.KernelFlagsSet }} // Vectors. -#define DivideByZero {{ .DivideByZero.Value }} -#define Debug {{ .Debug.Value }} -#define NMI {{ .NMI.Value }} -#define Breakpoint {{ .Breakpoint.Value }} -#define Overflow {{ .Overflow.Value }} -#define BoundRangeExceeded {{ .BoundRangeExceeded.Value }} -#define InvalidOpcode {{ .InvalidOpcode.Value }} -#define DeviceNotAvailable {{ .DeviceNotAvailable.Value }} -#define DoubleFault {{ .DoubleFault.Value }} -#define CoprocessorSegmentOverrun {{ .CoprocessorSegmentOverrun.Value }} -#define InvalidTSS {{ .InvalidTSS.Value }} -#define SegmentNotPresent {{ .SegmentNotPresent.Value }} -#define StackSegmentFault {{ .StackSegmentFault.Value }} -#define GeneralProtectionFault {{ .GeneralProtectionFault.Value }} -#define PageFault {{ .PageFault.Value }} -#define X87FloatingPointException {{ .X87FloatingPointException.Value }} -#define AlignmentCheck {{ .AlignmentCheck.Value }} -#define MachineCheck {{ .MachineCheck.Value }} -#define SIMDFloatingPointException {{ .SIMDFloatingPointException.Value }} -#define VirtualizationException {{ .VirtualizationException.Value }} -#define SecurityException {{ .SecurityException.Value }} -#define SyscallInt80 {{ .SyscallInt80.Value }} -#define Syscall {{ .Syscall.Value }} +#define DivideByZero {{ .Constants.DivideByZero }} +#define Debug {{ .Constants.Debug }} +#define NMI {{ .Constants.NMI }} +#define Breakpoint {{ .Constants.Breakpoint }} +#define Overflow {{ .Constants.Overflow }} +#define BoundRangeExceeded {{ .Constants.BoundRangeExceeded }} +#define InvalidOpcode {{ .Constants.InvalidOpcode }} +#define DeviceNotAvailable {{ .Constants.DeviceNotAvailable }} +#define DoubleFault {{ .Constants.DoubleFault }} +#define CoprocessorSegmentOverrun {{ .Constants.CoprocessorSegmentOverrun }} +#define InvalidTSS {{ .Constants.InvalidTSS }} +#define SegmentNotPresent {{ .Constants.SegmentNotPresent }} +#define StackSegmentFault {{ .Constants.StackSegmentFault }} +#define GeneralProtectionFault {{ .Constants.GeneralProtectionFault }} +#define PageFault {{ .Constants.PageFault }} +#define X87FloatingPointException {{ .Constants.X87FloatingPointException }} +#define AlignmentCheck {{ .Constants.AlignmentCheck }} +#define MachineCheck {{ .Constants.MachineCheck }} +#define SIMDFloatingPointException {{ .Constants.SIMDFloatingPointException }} +#define VirtualizationException {{ .Constants.VirtualizationException }} +#define SecurityException {{ .Constants.SecurityException }} +#define SyscallInt80 {{ .Constants.SyscallInt80 }} +#define Syscall {{ .Constants.Syscall }} {{ with .import.linux.PtraceRegs }} #define PTRACE_R15 {{ .R15.Offset }} diff --git a/pkg/ring0/entry_arm64.s b/pkg/ring0/entry_arm64.s index 8878bcb2a..7373badaa 100644 --- a/pkg/ring0/entry_arm64.s +++ b/pkg/ring0/entry_arm64.s @@ -30,39 +30,39 @@ #define CPU_APP_ASID ({{ .CPU.CPUArchState.Offset }}+{{ .CPUArchState.appASID.Offset }}) // Bits. -#define _KERNEL_FLAGS {{ .KernelFlagsSet.Value }} +#define _KERNEL_FLAGS {{ .Constants.KernelFlagsSet }} // Vectors. -#define El1Sync {{ .El1Sync.Value }} -#define El1Irq {{ .El1Irq.Value }} -#define El1Fiq {{ .El1Fiq.Value }} -#define El1Err {{ .El1Err.Value }} -#define El0Sync {{ .El0Sync.Value }} -#define El0Irq {{ .El0Irq.Value }} -#define El0Fiq {{ .El0Fiq.Value }} -#define El0Err {{ .El0Err.Value }} -#define El1SyncDa {{ .El1SyncDa.Value }} -#define El1SyncIa {{ .El1SyncIa.Value }} -#define El1SyncSpPc {{ .El1SyncSpPc.Value }} -#define El1SyncUndef {{ .El1SyncUndef.Value }} -#define El1SyncDbg {{ .El1SyncDbg.Value }} -#define El1SyncInv {{ .El1SyncInv.Value }} -#define El0SyncSVC {{ .El0SyncSVC.Value }} -#define El0SyncDa {{ .El0SyncDa.Value }} -#define El0SyncIa {{ .El0SyncIa.Value }} -#define El0SyncFpsimdAcc {{ .El0SyncFpsimdAcc.Value }} -#define El0SyncSveAcc {{ .El0SyncSveAcc.Value }} -#define El0SyncFpsimdExc {{ .El0SyncFpsimdExc.Value }} -#define El0SyncSys {{ .El0SyncSys.Value }} -#define El0SyncSpPc {{ .El0SyncSpPc.Value }} -#define El0SyncUndef {{ .El0SyncUndef.Value }} -#define El0SyncDbg {{ .El0SyncDbg.Value }} -#define El0SyncWfx {{ .El0SyncWfx.Value }} -#define El0SyncInv {{ .El0SyncInv.Value }} -#define El0ErrNMI {{ .El0ErrNMI.Value }} -#define PageFault {{ .PageFault.Value }} -#define Syscall {{ .Syscall.Value }} -#define VirtualizationException {{ .VirtualizationException.Value }} +#define El1Sync {{ .Constants.El1Sync }} +#define El1Irq {{ .Constants.El1Irq }} +#define El1Fiq {{ .Constants.El1Fiq }} +#define El1Err {{ .Constants.El1Err }} +#define El0Sync {{ .Constants.El0Sync }} +#define El0Irq {{ .Constants.El0Irq }} +#define El0Fiq {{ .Constants.El0Fiq }} +#define El0Err {{ .Constants.El0Err }} +#define El1SyncDa {{ .Constants.El1SyncDa }} +#define El1SyncIa {{ .Constants.El1SyncIa }} +#define El1SyncSpPc {{ .Constants.El1SyncSpPc }} +#define El1SyncUndef {{ .Constants.El1SyncUndef }} +#define El1SyncDbg {{ .Constants.El1SyncDbg }} +#define El1SyncInv {{ .Constants.El1SyncInv }} +#define El0SyncSVC {{ .Constants.El0SyncSVC }} +#define El0SyncDa {{ .Constants.El0SyncDa }} +#define El0SyncIa {{ .Constants.El0SyncIa }} +#define El0SyncFpsimdAcc {{ .Constants.El0SyncFpsimdAcc }} +#define El0SyncSveAcc {{ .Constants.El0SyncSveAcc }} +#define El0SyncFpsimdExc {{ .Constants.El0SyncFpsimdExc }} +#define El0SyncSys {{ .Constants.El0SyncSys }} +#define El0SyncSpPc {{ .Constants.El0SyncSpPc }} +#define El0SyncUndef {{ .Constants.El0SyncUndef }} +#define El0SyncDbg {{ .Constants.El0SyncDbg }} +#define El0SyncWfx {{ .Constants.El0SyncWfx }} +#define El0SyncInv {{ .Constants.El0SyncInv }} +#define El0ErrNMI {{ .Constants.El0ErrNMI }} +#define PageFault {{ .Constants.PageFault }} +#define Syscall {{ .Constants.Syscall }} +#define VirtualizationException {{ .Constants.VirtualizationException }} {{ with .import.linux.PtraceRegs }} #define PTRACE_R0 ({{ .Regs.Offset }} + 0*8) diff --git a/tools/checkinfo/checkinfo.go b/tools/checkinfo/checkinfo.go index cf9eef571..d1fcffc7a 100644 --- a/tools/checkinfo/checkinfo.go +++ b/tools/checkinfo/checkinfo.go @@ -30,7 +30,7 @@ var Analyzer = &analysis.Analyzer{ (*Align)(nil), (*Offset)(nil), (*Size)(nil), - (*Value)(nil), + (*Constants)(nil), }, } @@ -52,19 +52,24 @@ type Size int64 // AFact implements analysis.Fact.AFact. func (*Size) AFact() {} -// Value is a trivial fact. -type Value string +// Constants contains all constant values. +type Constants map[string]string // AFact implements analysis.Fact.AFact. -func (*Value) AFact() {} +func (*Constants) AFact() {} -func walkObject(pass *analysis.Pass, obj types.Object) { +// pkg holds package-level facts. +type pkg struct { + constants Constants +} + +func (p *pkg) walkObject(pass *analysis.Pass, obj types.Object) { switch x := obj.(type) { case *types.Const: - // Add a special constant value. This is supported for - // constants only, and appears as a "Value" fact. - v := Value(x.Val().ExactString()) - pass.ExportObjectFact(obj, &v) + // Add to the package-global Constants fact. Unexported + // constants can end up as unaddressable via objectpath and + // thus are not accessible in downstream analyzers. + p.constants[x.Name()] = x.Val().ExactString() case *types.PkgName: // Don't walk to other packages. case *types.Var: @@ -95,7 +100,7 @@ func walkObject(pass *analysis.Pass, obj types.Object) { for i := 0; i < structType.NumFields(); i++ { fieldObj := structType.Field(i) fields = append(fields, fieldObj) - walkObject(pass, fieldObj) + p.walkObject(pass, fieldObj) } offsets := pass.TypesSizes.Offsetsof(fields) for i, field := range fields { @@ -110,31 +115,39 @@ func walkObject(pass *analysis.Pass, obj types.Object) { // Recurse to all parameters. sig := x.Type().(*types.Signature) if recv := sig.Recv(); recv != nil { - walkObject(pass, recv) + p.walkObject(pass, recv) } if params := sig.Params(); params != nil { for i := 0; i < params.Len(); i++ { - walkObject(pass, params.At(i)) + p.walkObject(pass, params.At(i)) } } if results := sig.Results(); results != nil { for i := 0; i < results.Len(); i++ { - walkObject(pass, results.At(i)) + p.walkObject(pass, results.At(i)) } } - walkScope(pass, x.Scope()) + p.walkScope(pass, x.Scope()) } } // walkScope recursively resolves a scope. -func walkScope(pass *analysis.Pass, scope *types.Scope) { +func (p *pkg) walkScope(pass *analysis.Pass, scope *types.Scope) { for _, name := range scope.Names() { - walkObject(pass, scope.Lookup(name)) + p.walkObject(pass, scope.Lookup(name)) } } func run(pass *analysis.Pass) (any, error) { - // Export all facts. - walkScope(pass, pass.Pkg.Scope()) + p := &pkg{ + constants: make(Constants), + } + + // Export all object facts and accumulate all package facts. + p.walkScope(pass, pass.Pkg.Scope()) + + // Export package facts. + pass.ExportPackageFact(&p.constants) + return nil, nil } diff --git a/tools/nogo/facts/facts.go b/tools/nogo/facts/facts.go index 2578431d5..14938d431 100644 --- a/tools/nogo/facts/facts.go +++ b/tools/nogo/facts/facts.go @@ -362,6 +362,21 @@ func (r Resolved) walkScope(parents []string, scope *types.Scope, facts *Package } } +// walkPackage adds all package facts. +func (r Resolved) walkPackage(parents []string, facts *Package, allFactNames map[reflect.Type]string) { + for _, fact := range facts.Objects[nil] { + v := reflect.ValueOf(fact) + typeName, ok := allFactNames[v.Type()] + if !ok { + continue + } + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + r.addRecursively(append(parents, typeName), v.Interface()) + } +} + // Resolve resolves all object facts. func Resolve(pkg *types.Package, localFacts *Package, allFacts *Bundle, allFactNames map[reflect.Type]string) (Resolved, error) { // Populate the tree. Allocating this slice up front prevents @@ -369,6 +384,7 @@ func Resolve(pkg *types.Package, localFacts *Package, allFacts *Bundle, allFactN // without allocating a new backing array. r := make(Resolved) names := make([]string, 0, 64) + r.walkPackage(names, localFacts, allFactNames) r.walkScope(names, pkg.Scope(), localFacts, allFactNames) for _, importPkg := range pkg.Imports() { importFacts, err := allFacts.Package(importPkg) @@ -376,8 +392,9 @@ func Resolve(pkg *types.Package, localFacts *Package, allFacts *Bundle, allFactN return nil, err } if importFacts == nil { - continue + continue // Nothing to render. } + r.walkPackage(append(names, "import", importPkg.Name()), importFacts, allFactNames) r.walkScope(append(names, "import", importPkg.Name()), importPkg.Scope(), importFacts, allFactNames) } return r, nil