mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add constants to package-level fact
Unexported constants can end up unaddressable in objectpath and thus their object facts get lost on fact import. Work around this by adding a package-level fact which is a map of all constants to their value. Remove the Value facts because it is confusing to have two ways to access the same thing (especially when one only works sometimes). PiperOrigin-RevId: 505153453
This commit is contained in:
committed by
gVisor bot
parent
16c24b1cec
commit
845fb007de
+26
-26
@@ -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 }}
|
||||
|
||||
+31
-31
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user