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

     1  package internal
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	_ "unsafe"
     7  )
     8  
     9  type auxvPairReader interface {
    10  	Close() error
    11  	ReadAuxvPair() (uint64, uint64, error)
    12  }
    13  
    14  // See https://elixir.bootlin.com/linux/v6.5.5/source/include/uapi/linux/auxvec.h
    15  const (
    16  	_AT_NULL         = 0  // End of vector
    17  	_AT_SYSINFO_EHDR = 33 // Offset to vDSO blob in process image
    18  )
    19  
    20  //go:linkname runtime_getAuxv runtime.getAuxv
    21  func runtime_getAuxv() []uintptr
    22  
    23  type auxvRuntimeReader struct {
    24  	data  []uintptr
    25  	index int
    26  }
    27  
    28  func (r *auxvRuntimeReader) Close() error {
    29  	return nil
    30  }
    31  
    32  func (r *auxvRuntimeReader) ReadAuxvPair() (uint64, uint64, error) {
    33  	if r.index >= len(r.data)+2 {
    34  		return 0, 0, io.EOF
    35  	}
    36  
    37  	// we manually add the (_AT_NULL, _AT_NULL) pair at the end
    38  	// that is not provided by the go runtime
    39  	var tag, value uintptr
    40  	if r.index+1 < len(r.data) {
    41  		tag, value = r.data[r.index], r.data[r.index+1]
    42  	} else {
    43  		tag, value = _AT_NULL, _AT_NULL
    44  	}
    45  	r.index += 2
    46  	return uint64(tag), uint64(value), nil
    47  }
    48  
    49  func newAuxvRuntimeReader() (auxvPairReader, error) {
    50  	data := runtime_getAuxv()
    51  
    52  	if len(data)%2 != 0 {
    53  		return nil, errors.New("malformed auxv passed from runtime")
    54  	}
    55  
    56  	return &auxvRuntimeReader{
    57  		data:  data,
    58  		index: 0,
    59  	}, nil
    60  }