github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/internal/sysenc/layout.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found at https://go.dev/LICENSE.
     4  
     5  package sysenc
     6  
     7  import (
     8  	"reflect"
     9  	"sync"
    10  )
    11  
    12  var hasUnexportedFieldsCache sync.Map // map[reflect.Type]bool
    13  
    14  func hasUnexportedFields(typ reflect.Type) bool {
    15  	switch typ.Kind() {
    16  	case reflect.Slice, reflect.Array, reflect.Pointer:
    17  		return hasUnexportedFields(typ.Elem())
    18  
    19  	case reflect.Struct:
    20  		if unexported, ok := hasUnexportedFieldsCache.Load(typ); ok {
    21  			return unexported.(bool)
    22  		}
    23  
    24  		unexported := false
    25  		for i, n := 0, typ.NumField(); i < n; i++ {
    26  			field := typ.Field(i)
    27  			// Package binary allows _ fields but always writes zeroes into them.
    28  			if (!field.IsExported() && field.Name != "_") || hasUnexportedFields(field.Type) {
    29  				unexported = true
    30  				break
    31  			}
    32  		}
    33  
    34  		hasUnexportedFieldsCache.Store(typ, unexported)
    35  		return unexported
    36  
    37  	default:
    38  		// NB: It's not clear what this means for Chan and so on.
    39  		return false
    40  	}
    41  }