Upgrade containerd/cgroups to remove github.com/cilium/ebpf's fuzzer
The fuzzer is broken and it breaks OSS-Fuzz according to #7288. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
This commit is contained in:
		
							
								
								
									
										41
									
								
								vendor/github.com/cilium/ebpf/asm/func.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										41
									
								
								vendor/github.com/cilium/ebpf/asm/func.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -5,6 +5,10 @@ package asm
 | 
			
		||||
// BuiltinFunc is a built-in eBPF function.
 | 
			
		||||
type BuiltinFunc int32
 | 
			
		||||
 | 
			
		||||
func (_ BuiltinFunc) Max() BuiltinFunc {
 | 
			
		||||
	return maxBuiltinFunc - 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// eBPF built-in functions
 | 
			
		||||
//
 | 
			
		||||
// You can regenerate this list using the following gawk script:
 | 
			
		||||
@@ -190,6 +194,43 @@ const (
 | 
			
		||||
	FnSysBpf
 | 
			
		||||
	FnBtfFindByNameKind
 | 
			
		||||
	FnSysClose
 | 
			
		||||
	FnTimerInit
 | 
			
		||||
	FnTimerSetCallback
 | 
			
		||||
	FnTimerStart
 | 
			
		||||
	FnTimerCancel
 | 
			
		||||
	FnGetFuncIp
 | 
			
		||||
	FnGetAttachCookie
 | 
			
		||||
	FnTaskPtRegs
 | 
			
		||||
	FnGetBranchSnapshot
 | 
			
		||||
	FnTraceVprintk
 | 
			
		||||
	FnSkcToUnixSock
 | 
			
		||||
	FnKallsymsLookupName
 | 
			
		||||
	FnFindVma
 | 
			
		||||
	FnLoop
 | 
			
		||||
	FnStrncmp
 | 
			
		||||
	FnGetFuncArg
 | 
			
		||||
	FnGetFuncRet
 | 
			
		||||
	FnGetFuncArgCnt
 | 
			
		||||
	FnGetRetval
 | 
			
		||||
	FnSetRetval
 | 
			
		||||
	FnXdpGetBuffLen
 | 
			
		||||
	FnXdpLoadBytes
 | 
			
		||||
	FnXdpStoreBytes
 | 
			
		||||
	FnCopyFromUserTask
 | 
			
		||||
	FnSkbSetTstamp
 | 
			
		||||
	FnImaFileHash
 | 
			
		||||
	FnKptrXchg
 | 
			
		||||
	FnMapLookupPercpuElem
 | 
			
		||||
	FnSkcToMptcpSock
 | 
			
		||||
	FnDynptrFromMem
 | 
			
		||||
	FnRingbufReserveDynptr
 | 
			
		||||
	FnRingbufSubmitDynptr
 | 
			
		||||
	FnRingbufDiscardDynptr
 | 
			
		||||
	FnDynptrRead
 | 
			
		||||
	FnDynptrWrite
 | 
			
		||||
	FnDynptrData
 | 
			
		||||
 | 
			
		||||
	maxBuiltinFunc
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Call emits a function call.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								vendor/github.com/cilium/ebpf/asm/func_string.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								vendor/github.com/cilium/ebpf/asm/func_string.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -177,11 +177,47 @@ func _() {
 | 
			
		||||
	_ = x[FnSysBpf-166]
 | 
			
		||||
	_ = x[FnBtfFindByNameKind-167]
 | 
			
		||||
	_ = x[FnSysClose-168]
 | 
			
		||||
	_ = x[FnTimerInit-169]
 | 
			
		||||
	_ = x[FnTimerSetCallback-170]
 | 
			
		||||
	_ = x[FnTimerStart-171]
 | 
			
		||||
	_ = x[FnTimerCancel-172]
 | 
			
		||||
	_ = x[FnGetFuncIp-173]
 | 
			
		||||
	_ = x[FnGetAttachCookie-174]
 | 
			
		||||
	_ = x[FnTaskPtRegs-175]
 | 
			
		||||
	_ = x[FnGetBranchSnapshot-176]
 | 
			
		||||
	_ = x[FnTraceVprintk-177]
 | 
			
		||||
	_ = x[FnSkcToUnixSock-178]
 | 
			
		||||
	_ = x[FnKallsymsLookupName-179]
 | 
			
		||||
	_ = x[FnFindVma-180]
 | 
			
		||||
	_ = x[FnLoop-181]
 | 
			
		||||
	_ = x[FnStrncmp-182]
 | 
			
		||||
	_ = x[FnGetFuncArg-183]
 | 
			
		||||
	_ = x[FnGetFuncRet-184]
 | 
			
		||||
	_ = x[FnGetFuncArgCnt-185]
 | 
			
		||||
	_ = x[FnGetRetval-186]
 | 
			
		||||
	_ = x[FnSetRetval-187]
 | 
			
		||||
	_ = x[FnXdpGetBuffLen-188]
 | 
			
		||||
	_ = x[FnXdpLoadBytes-189]
 | 
			
		||||
	_ = x[FnXdpStoreBytes-190]
 | 
			
		||||
	_ = x[FnCopyFromUserTask-191]
 | 
			
		||||
	_ = x[FnSkbSetTstamp-192]
 | 
			
		||||
	_ = x[FnImaFileHash-193]
 | 
			
		||||
	_ = x[FnKptrXchg-194]
 | 
			
		||||
	_ = x[FnMapLookupPercpuElem-195]
 | 
			
		||||
	_ = x[FnSkcToMptcpSock-196]
 | 
			
		||||
	_ = x[FnDynptrFromMem-197]
 | 
			
		||||
	_ = x[FnRingbufReserveDynptr-198]
 | 
			
		||||
	_ = x[FnRingbufSubmitDynptr-199]
 | 
			
		||||
	_ = x[FnRingbufDiscardDynptr-200]
 | 
			
		||||
	_ = x[FnDynptrRead-201]
 | 
			
		||||
	_ = x[FnDynptrWrite-202]
 | 
			
		||||
	_ = x[FnDynptrData-203]
 | 
			
		||||
	_ = x[maxBuiltinFunc-204]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const _BuiltinFunc_name = "FnUnspecFnMapLookupElemFnMapUpdateElemFnMapDeleteElemFnProbeReadFnKtimeGetNsFnTracePrintkFnGetPrandomU32FnGetSmpProcessorIdFnSkbStoreBytesFnL3CsumReplaceFnL4CsumReplaceFnTailCallFnCloneRedirectFnGetCurrentPidTgidFnGetCurrentUidGidFnGetCurrentCommFnGetCgroupClassidFnSkbVlanPushFnSkbVlanPopFnSkbGetTunnelKeyFnSkbSetTunnelKeyFnPerfEventReadFnRedirectFnGetRouteRealmFnPerfEventOutputFnSkbLoadBytesFnGetStackidFnCsumDiffFnSkbGetTunnelOptFnSkbSetTunnelOptFnSkbChangeProtoFnSkbChangeTypeFnSkbUnderCgroupFnGetHashRecalcFnGetCurrentTaskFnProbeWriteUserFnCurrentTaskUnderCgroupFnSkbChangeTailFnSkbPullDataFnCsumUpdateFnSetHashInvalidFnGetNumaNodeIdFnSkbChangeHeadFnXdpAdjustHeadFnProbeReadStrFnGetSocketCookieFnGetSocketUidFnSetHashFnSetsockoptFnSkbAdjustRoomFnRedirectMapFnSkRedirectMapFnSockMapUpdateFnXdpAdjustMetaFnPerfEventReadValueFnPerfProgReadValueFnGetsockoptFnOverrideReturnFnSockOpsCbFlagsSetFnMsgRedirectMapFnMsgApplyBytesFnMsgCorkBytesFnMsgPullDataFnBindFnXdpAdjustTailFnSkbGetXfrmStateFnGetStackFnSkbLoadBytesRelativeFnFibLookupFnSockHashUpdateFnMsgRedirectHashFnSkRedirectHashFnLwtPushEncapFnLwtSeg6StoreBytesFnLwtSeg6AdjustSrhFnLwtSeg6ActionFnRcRepeatFnRcKeydownFnSkbCgroupIdFnGetCurrentCgroupIdFnGetLocalStorageFnSkSelectReuseportFnSkbAncestorCgroupIdFnSkLookupTcpFnSkLookupUdpFnSkReleaseFnMapPushElemFnMapPopElemFnMapPeekElemFnMsgPushDataFnMsgPopDataFnRcPointerRelFnSpinLockFnSpinUnlockFnSkFullsockFnTcpSockFnSkbEcnSetCeFnGetListenerSockFnSkcLookupTcpFnTcpCheckSyncookieFnSysctlGetNameFnSysctlGetCurrentValueFnSysctlGetNewValueFnSysctlSetNewValueFnStrtolFnStrtoulFnSkStorageGetFnSkStorageDeleteFnSendSignalFnTcpGenSyncookieFnSkbOutputFnProbeReadUserFnProbeReadKernelFnProbeReadUserStrFnProbeReadKernelStrFnTcpSendAckFnSendSignalThreadFnJiffies64FnReadBranchRecordsFnGetNsCurrentPidTgidFnXdpOutputFnGetNetnsCookieFnGetCurrentAncestorCgroupIdFnSkAssignFnKtimeGetBootNsFnSeqPrintfFnSeqWriteFnSkCgroupIdFnSkAncestorCgroupIdFnRingbufOutputFnRingbufReserveFnRingbufSubmitFnRingbufDiscardFnRingbufQueryFnCsumLevelFnSkcToTcp6SockFnSkcToTcpSockFnSkcToTcpTimewaitSockFnSkcToTcpRequestSockFnSkcToUdp6SockFnGetTaskStackFnLoadHdrOptFnStoreHdrOptFnReserveHdrOptFnInodeStorageGetFnInodeStorageDeleteFnDPathFnCopyFromUserFnSnprintfBtfFnSeqPrintfBtfFnSkbCgroupClassidFnRedirectNeighFnPerCpuPtrFnThisCpuPtrFnRedirectPeerFnTaskStorageGetFnTaskStorageDeleteFnGetCurrentTaskBtfFnBprmOptsSetFnKtimeGetCoarseNsFnImaInodeHashFnSockFromFileFnCheckMtuFnForEachMapElemFnSnprintfFnSysBpfFnBtfFindByNameKindFnSysClose"
 | 
			
		||||
const _BuiltinFunc_name = "FnUnspecFnMapLookupElemFnMapUpdateElemFnMapDeleteElemFnProbeReadFnKtimeGetNsFnTracePrintkFnGetPrandomU32FnGetSmpProcessorIdFnSkbStoreBytesFnL3CsumReplaceFnL4CsumReplaceFnTailCallFnCloneRedirectFnGetCurrentPidTgidFnGetCurrentUidGidFnGetCurrentCommFnGetCgroupClassidFnSkbVlanPushFnSkbVlanPopFnSkbGetTunnelKeyFnSkbSetTunnelKeyFnPerfEventReadFnRedirectFnGetRouteRealmFnPerfEventOutputFnSkbLoadBytesFnGetStackidFnCsumDiffFnSkbGetTunnelOptFnSkbSetTunnelOptFnSkbChangeProtoFnSkbChangeTypeFnSkbUnderCgroupFnGetHashRecalcFnGetCurrentTaskFnProbeWriteUserFnCurrentTaskUnderCgroupFnSkbChangeTailFnSkbPullDataFnCsumUpdateFnSetHashInvalidFnGetNumaNodeIdFnSkbChangeHeadFnXdpAdjustHeadFnProbeReadStrFnGetSocketCookieFnGetSocketUidFnSetHashFnSetsockoptFnSkbAdjustRoomFnRedirectMapFnSkRedirectMapFnSockMapUpdateFnXdpAdjustMetaFnPerfEventReadValueFnPerfProgReadValueFnGetsockoptFnOverrideReturnFnSockOpsCbFlagsSetFnMsgRedirectMapFnMsgApplyBytesFnMsgCorkBytesFnMsgPullDataFnBindFnXdpAdjustTailFnSkbGetXfrmStateFnGetStackFnSkbLoadBytesRelativeFnFibLookupFnSockHashUpdateFnMsgRedirectHashFnSkRedirectHashFnLwtPushEncapFnLwtSeg6StoreBytesFnLwtSeg6AdjustSrhFnLwtSeg6ActionFnRcRepeatFnRcKeydownFnSkbCgroupIdFnGetCurrentCgroupIdFnGetLocalStorageFnSkSelectReuseportFnSkbAncestorCgroupIdFnSkLookupTcpFnSkLookupUdpFnSkReleaseFnMapPushElemFnMapPopElemFnMapPeekElemFnMsgPushDataFnMsgPopDataFnRcPointerRelFnSpinLockFnSpinUnlockFnSkFullsockFnTcpSockFnSkbEcnSetCeFnGetListenerSockFnSkcLookupTcpFnTcpCheckSyncookieFnSysctlGetNameFnSysctlGetCurrentValueFnSysctlGetNewValueFnSysctlSetNewValueFnStrtolFnStrtoulFnSkStorageGetFnSkStorageDeleteFnSendSignalFnTcpGenSyncookieFnSkbOutputFnProbeReadUserFnProbeReadKernelFnProbeReadUserStrFnProbeReadKernelStrFnTcpSendAckFnSendSignalThreadFnJiffies64FnReadBranchRecordsFnGetNsCurrentPidTgidFnXdpOutputFnGetNetnsCookieFnGetCurrentAncestorCgroupIdFnSkAssignFnKtimeGetBootNsFnSeqPrintfFnSeqWriteFnSkCgroupIdFnSkAncestorCgroupIdFnRingbufOutputFnRingbufReserveFnRingbufSubmitFnRingbufDiscardFnRingbufQueryFnCsumLevelFnSkcToTcp6SockFnSkcToTcpSockFnSkcToTcpTimewaitSockFnSkcToTcpRequestSockFnSkcToUdp6SockFnGetTaskStackFnLoadHdrOptFnStoreHdrOptFnReserveHdrOptFnInodeStorageGetFnInodeStorageDeleteFnDPathFnCopyFromUserFnSnprintfBtfFnSeqPrintfBtfFnSkbCgroupClassidFnRedirectNeighFnPerCpuPtrFnThisCpuPtrFnRedirectPeerFnTaskStorageGetFnTaskStorageDeleteFnGetCurrentTaskBtfFnBprmOptsSetFnKtimeGetCoarseNsFnImaInodeHashFnSockFromFileFnCheckMtuFnForEachMapElemFnSnprintfFnSysBpfFnBtfFindByNameKindFnSysCloseFnTimerInitFnTimerSetCallbackFnTimerStartFnTimerCancelFnGetFuncIpFnGetAttachCookieFnTaskPtRegsFnGetBranchSnapshotFnTraceVprintkFnSkcToUnixSockFnKallsymsLookupNameFnFindVmaFnLoopFnStrncmpFnGetFuncArgFnGetFuncRetFnGetFuncArgCntFnGetRetvalFnSetRetvalFnXdpGetBuffLenFnXdpLoadBytesFnXdpStoreBytesFnCopyFromUserTaskFnSkbSetTstampFnImaFileHashFnKptrXchgFnMapLookupPercpuElemFnSkcToMptcpSockFnDynptrFromMemFnRingbufReserveDynptrFnRingbufSubmitDynptrFnRingbufDiscardDynptrFnDynptrReadFnDynptrWriteFnDynptrDatamaxBuiltinFunc"
 | 
			
		||||
 | 
			
		||||
var _BuiltinFunc_index = [...]uint16{0, 8, 23, 38, 53, 64, 76, 89, 104, 123, 138, 153, 168, 178, 193, 212, 230, 246, 264, 277, 289, 306, 323, 338, 348, 363, 380, 394, 406, 416, 433, 450, 466, 481, 497, 512, 528, 544, 568, 583, 596, 608, 624, 639, 654, 669, 683, 700, 714, 723, 735, 750, 763, 778, 793, 808, 828, 847, 859, 875, 894, 910, 925, 939, 952, 958, 973, 990, 1000, 1022, 1033, 1049, 1066, 1082, 1096, 1115, 1133, 1148, 1158, 1169, 1182, 1202, 1219, 1238, 1259, 1272, 1285, 1296, 1309, 1321, 1334, 1347, 1359, 1373, 1383, 1395, 1407, 1416, 1429, 1446, 1460, 1479, 1494, 1517, 1536, 1555, 1563, 1572, 1586, 1603, 1615, 1632, 1643, 1658, 1675, 1693, 1713, 1725, 1743, 1754, 1773, 1794, 1805, 1821, 1849, 1859, 1875, 1886, 1896, 1908, 1928, 1943, 1959, 1974, 1990, 2004, 2015, 2030, 2044, 2066, 2087, 2102, 2116, 2128, 2141, 2156, 2173, 2193, 2200, 2214, 2227, 2241, 2259, 2274, 2285, 2297, 2311, 2327, 2346, 2365, 2378, 2396, 2410, 2424, 2434, 2450, 2460, 2468, 2487, 2497}
 | 
			
		||||
var _BuiltinFunc_index = [...]uint16{0, 8, 23, 38, 53, 64, 76, 89, 104, 123, 138, 153, 168, 178, 193, 212, 230, 246, 264, 277, 289, 306, 323, 338, 348, 363, 380, 394, 406, 416, 433, 450, 466, 481, 497, 512, 528, 544, 568, 583, 596, 608, 624, 639, 654, 669, 683, 700, 714, 723, 735, 750, 763, 778, 793, 808, 828, 847, 859, 875, 894, 910, 925, 939, 952, 958, 973, 990, 1000, 1022, 1033, 1049, 1066, 1082, 1096, 1115, 1133, 1148, 1158, 1169, 1182, 1202, 1219, 1238, 1259, 1272, 1285, 1296, 1309, 1321, 1334, 1347, 1359, 1373, 1383, 1395, 1407, 1416, 1429, 1446, 1460, 1479, 1494, 1517, 1536, 1555, 1563, 1572, 1586, 1603, 1615, 1632, 1643, 1658, 1675, 1693, 1713, 1725, 1743, 1754, 1773, 1794, 1805, 1821, 1849, 1859, 1875, 1886, 1896, 1908, 1928, 1943, 1959, 1974, 1990, 2004, 2015, 2030, 2044, 2066, 2087, 2102, 2116, 2128, 2141, 2156, 2173, 2193, 2200, 2214, 2227, 2241, 2259, 2274, 2285, 2297, 2311, 2327, 2346, 2365, 2378, 2396, 2410, 2424, 2434, 2450, 2460, 2468, 2487, 2497, 2508, 2526, 2538, 2551, 2562, 2579, 2591, 2610, 2624, 2639, 2659, 2668, 2674, 2683, 2695, 2707, 2722, 2733, 2744, 2759, 2773, 2788, 2806, 2820, 2833, 2843, 2864, 2880, 2895, 2917, 2938, 2960, 2972, 2985, 2997, 3011}
 | 
			
		||||
 | 
			
		||||
func (i BuiltinFunc) String() string {
 | 
			
		||||
	if i < 0 || i >= BuiltinFunc(len(_BuiltinFunc_index)-1) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										554
									
								
								vendor/github.com/cilium/ebpf/asm/instruction.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										554
									
								
								vendor/github.com/cilium/ebpf/asm/instruction.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -8,8 +8,10 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"math"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/cilium/ebpf/internal/sys"
 | 
			
		||||
	"github.com/cilium/ebpf/internal/unix"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -19,6 +21,10 @@ const InstructionSize = 8
 | 
			
		||||
// RawInstructionOffset is an offset in units of raw BPF instructions.
 | 
			
		||||
type RawInstructionOffset uint64
 | 
			
		||||
 | 
			
		||||
var ErrUnreferencedSymbol = errors.New("unreferenced symbol")
 | 
			
		||||
var ErrUnsatisfiedMapReference = errors.New("unsatisfied map reference")
 | 
			
		||||
var ErrUnsatisfiedProgramReference = errors.New("unsatisfied program reference")
 | 
			
		||||
 | 
			
		||||
// Bytes returns the offset of an instruction in bytes.
 | 
			
		||||
func (rio RawInstructionOffset) Bytes() uint64 {
 | 
			
		||||
	return uint64(rio) * InstructionSize
 | 
			
		||||
@@ -26,50 +32,57 @@ func (rio RawInstructionOffset) Bytes() uint64 {
 | 
			
		||||
 | 
			
		||||
// Instruction is a single eBPF instruction.
 | 
			
		||||
type Instruction struct {
 | 
			
		||||
	OpCode    OpCode
 | 
			
		||||
	Dst       Register
 | 
			
		||||
	Src       Register
 | 
			
		||||
	Offset    int16
 | 
			
		||||
	Constant  int64
 | 
			
		||||
	Reference string
 | 
			
		||||
	Symbol    string
 | 
			
		||||
}
 | 
			
		||||
	OpCode   OpCode
 | 
			
		||||
	Dst      Register
 | 
			
		||||
	Src      Register
 | 
			
		||||
	Offset   int16
 | 
			
		||||
	Constant int64
 | 
			
		||||
 | 
			
		||||
// Sym creates a symbol.
 | 
			
		||||
func (ins Instruction) Sym(name string) Instruction {
 | 
			
		||||
	ins.Symbol = name
 | 
			
		||||
	return ins
 | 
			
		||||
	// Metadata contains optional metadata about this instruction.
 | 
			
		||||
	Metadata Metadata
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unmarshal decodes a BPF instruction.
 | 
			
		||||
func (ins *Instruction) Unmarshal(r io.Reader, bo binary.ByteOrder) (uint64, error) {
 | 
			
		||||
	var bi bpfInstruction
 | 
			
		||||
	err := binary.Read(r, bo, &bi)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
	data := make([]byte, InstructionSize)
 | 
			
		||||
	if _, err := io.ReadFull(r, data); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ins.OpCode = bi.OpCode
 | 
			
		||||
	ins.Offset = bi.Offset
 | 
			
		||||
	ins.Constant = int64(bi.Constant)
 | 
			
		||||
	ins.Dst, ins.Src, err = bi.Registers.Unmarshal(bo)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, fmt.Errorf("can't unmarshal registers: %s", err)
 | 
			
		||||
	ins.OpCode = OpCode(data[0])
 | 
			
		||||
 | 
			
		||||
	regs := data[1]
 | 
			
		||||
	switch bo {
 | 
			
		||||
	case binary.LittleEndian:
 | 
			
		||||
		ins.Dst, ins.Src = Register(regs&0xF), Register(regs>>4)
 | 
			
		||||
	case binary.BigEndian:
 | 
			
		||||
		ins.Dst, ins.Src = Register(regs>>4), Register(regs&0xf)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !bi.OpCode.IsDWordLoad() {
 | 
			
		||||
	ins.Offset = int16(bo.Uint16(data[2:4]))
 | 
			
		||||
	// Convert to int32 before widening to int64
 | 
			
		||||
	// to ensure the signed bit is carried over.
 | 
			
		||||
	ins.Constant = int64(int32(bo.Uint32(data[4:8])))
 | 
			
		||||
 | 
			
		||||
	if !ins.OpCode.IsDWordLoad() {
 | 
			
		||||
		return InstructionSize, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var bi2 bpfInstruction
 | 
			
		||||
	if err := binary.Read(r, bo, &bi2); err != nil {
 | 
			
		||||
	// Pull another instruction from the stream to retrieve the second
 | 
			
		||||
	// half of the 64-bit immediate value.
 | 
			
		||||
	if _, err := io.ReadFull(r, data); err != nil {
 | 
			
		||||
		// No Wrap, to avoid io.EOF clash
 | 
			
		||||
		return 0, errors.New("64bit immediate is missing second half")
 | 
			
		||||
	}
 | 
			
		||||
	if bi2.OpCode != 0 || bi2.Offset != 0 || bi2.Registers != 0 {
 | 
			
		||||
 | 
			
		||||
	// Require that all fields other than the value are zero.
 | 
			
		||||
	if bo.Uint32(data[0:4]) != 0 {
 | 
			
		||||
		return 0, errors.New("64bit immediate has non-zero fields")
 | 
			
		||||
	}
 | 
			
		||||
	ins.Constant = int64(uint64(uint32(bi2.Constant))<<32 | uint64(uint32(bi.Constant)))
 | 
			
		||||
 | 
			
		||||
	cons1 := uint32(ins.Constant)
 | 
			
		||||
	cons2 := int32(bo.Uint32(data[4:8]))
 | 
			
		||||
	ins.Constant = int64(cons2)<<32 | int64(cons1)
 | 
			
		||||
 | 
			
		||||
	return 2 * InstructionSize, nil
 | 
			
		||||
}
 | 
			
		||||
@@ -93,14 +106,12 @@ func (ins Instruction) Marshal(w io.Writer, bo binary.ByteOrder) (uint64, error)
 | 
			
		||||
		return 0, fmt.Errorf("can't marshal registers: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bpfi := bpfInstruction{
 | 
			
		||||
		ins.OpCode,
 | 
			
		||||
		regs,
 | 
			
		||||
		ins.Offset,
 | 
			
		||||
		cons,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := binary.Write(w, bo, &bpfi); err != nil {
 | 
			
		||||
	data := make([]byte, InstructionSize)
 | 
			
		||||
	data[0] = byte(ins.OpCode)
 | 
			
		||||
	data[1] = byte(regs)
 | 
			
		||||
	bo.PutUint16(data[2:4], uint16(ins.Offset))
 | 
			
		||||
	bo.PutUint32(data[4:8], uint32(cons))
 | 
			
		||||
	if _, err := w.Write(data); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -108,42 +119,76 @@ func (ins Instruction) Marshal(w io.Writer, bo binary.ByteOrder) (uint64, error)
 | 
			
		||||
		return InstructionSize, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bpfi = bpfInstruction{
 | 
			
		||||
		Constant: int32(ins.Constant >> 32),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := binary.Write(w, bo, &bpfi); err != nil {
 | 
			
		||||
	// The first half of the second part of a double-wide instruction
 | 
			
		||||
	// must be zero. The second half carries the value.
 | 
			
		||||
	bo.PutUint32(data[0:4], 0)
 | 
			
		||||
	bo.PutUint32(data[4:8], uint32(ins.Constant>>32))
 | 
			
		||||
	if _, err := w.Write(data); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 2 * InstructionSize, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RewriteMapPtr changes an instruction to use a new map fd.
 | 
			
		||||
// AssociateMap associates a Map with this Instruction.
 | 
			
		||||
//
 | 
			
		||||
// Returns an error if the instruction doesn't load a map.
 | 
			
		||||
func (ins *Instruction) RewriteMapPtr(fd int) error {
 | 
			
		||||
	if !ins.OpCode.IsDWordLoad() {
 | 
			
		||||
		return fmt.Errorf("%s is not a 64 bit load", ins.OpCode)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ins.Src != PseudoMapFD && ins.Src != PseudoMapValue {
 | 
			
		||||
// Implicitly clears the Instruction's Reference field.
 | 
			
		||||
//
 | 
			
		||||
// Returns an error if the Instruction is not a map load.
 | 
			
		||||
func (ins *Instruction) AssociateMap(m FDer) error {
 | 
			
		||||
	if !ins.IsLoadFromMap() {
 | 
			
		||||
		return errors.New("not a load from a map")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ins.Metadata.Set(referenceMeta{}, nil)
 | 
			
		||||
	ins.Metadata.Set(mapMeta{}, m)
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RewriteMapPtr changes an instruction to use a new map fd.
 | 
			
		||||
//
 | 
			
		||||
// Returns an error if the instruction doesn't load a map.
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: use AssociateMap instead. If you cannot provide a Map,
 | 
			
		||||
// wrap an fd in a type implementing FDer.
 | 
			
		||||
func (ins *Instruction) RewriteMapPtr(fd int) error {
 | 
			
		||||
	if !ins.IsLoadFromMap() {
 | 
			
		||||
		return errors.New("not a load from a map")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ins.encodeMapFD(fd)
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ins *Instruction) encodeMapFD(fd int) {
 | 
			
		||||
	// Preserve the offset value for direct map loads.
 | 
			
		||||
	offset := uint64(ins.Constant) & (math.MaxUint32 << 32)
 | 
			
		||||
	rawFd := uint64(uint32(fd))
 | 
			
		||||
	ins.Constant = int64(offset | rawFd)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MapPtr returns the map fd for this instruction.
 | 
			
		||||
//
 | 
			
		||||
// The result is undefined if the instruction is not a load from a map,
 | 
			
		||||
// see IsLoadFromMap.
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: use Map() instead.
 | 
			
		||||
func (ins *Instruction) MapPtr() int {
 | 
			
		||||
	return int(int32(uint64(ins.Constant) & math.MaxUint32))
 | 
			
		||||
	// If there is a map associated with the instruction, return its FD.
 | 
			
		||||
	if fd := ins.Metadata.Get(mapMeta{}); fd != nil {
 | 
			
		||||
		return fd.(FDer).FD()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Fall back to the fd stored in the Constant field
 | 
			
		||||
	return ins.mapFd()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// mapFd returns the map file descriptor stored in the 32 least significant
 | 
			
		||||
// bits of ins' Constant field.
 | 
			
		||||
func (ins *Instruction) mapFd() int {
 | 
			
		||||
	return int(int32(ins.Constant))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RewriteMapOffset changes the offset of a direct load from a map.
 | 
			
		||||
@@ -181,6 +226,18 @@ func (ins *Instruction) IsFunctionCall() bool {
 | 
			
		||||
	return ins.OpCode.JumpOp() == Call && ins.Src == PseudoCall
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsLoadOfFunctionPointer returns true if the instruction loads a function pointer.
 | 
			
		||||
func (ins *Instruction) IsLoadOfFunctionPointer() bool {
 | 
			
		||||
	return ins.OpCode.IsDWordLoad() && ins.Src == PseudoFunc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsFunctionReference returns true if the instruction references another BPF
 | 
			
		||||
// function, either by invoking a Call jump operation or by loading a function
 | 
			
		||||
// pointer.
 | 
			
		||||
func (ins *Instruction) IsFunctionReference() bool {
 | 
			
		||||
	return ins.IsFunctionCall() || ins.IsLoadOfFunctionPointer()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsBuiltinCall returns true if the instruction is a built-in call, i.e. BPF helper call.
 | 
			
		||||
func (ins *Instruction) IsBuiltinCall() bool {
 | 
			
		||||
	return ins.OpCode.JumpOp() == Call && ins.Src == R0 && ins.Dst == R0
 | 
			
		||||
@@ -213,21 +270,30 @@ func (ins Instruction) Format(f fmt.State, c rune) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ins.IsLoadFromMap() {
 | 
			
		||||
		fd := ins.MapPtr()
 | 
			
		||||
		fd := ins.mapFd()
 | 
			
		||||
		m := ins.Map()
 | 
			
		||||
		switch ins.Src {
 | 
			
		||||
		case PseudoMapFD:
 | 
			
		||||
			fmt.Fprintf(f, "LoadMapPtr dst: %s fd: %d", ins.Dst, fd)
 | 
			
		||||
			if m != nil {
 | 
			
		||||
				fmt.Fprintf(f, "LoadMapPtr dst: %s map: %s", ins.Dst, m)
 | 
			
		||||
			} else {
 | 
			
		||||
				fmt.Fprintf(f, "LoadMapPtr dst: %s fd: %d", ins.Dst, fd)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		case PseudoMapValue:
 | 
			
		||||
			fmt.Fprintf(f, "LoadMapValue dst: %s, fd: %d off: %d", ins.Dst, fd, ins.mapOffset())
 | 
			
		||||
			if m != nil {
 | 
			
		||||
				fmt.Fprintf(f, "LoadMapValue dst: %s, map: %s off: %d", ins.Dst, m, ins.mapOffset())
 | 
			
		||||
			} else {
 | 
			
		||||
				fmt.Fprintf(f, "LoadMapValue dst: %s, fd: %d off: %d", ins.Dst, fd, ins.mapOffset())
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		goto ref
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fmt.Fprintf(f, "%v ", op)
 | 
			
		||||
	switch cls := op.Class(); cls {
 | 
			
		||||
	case LdClass, LdXClass, StClass, StXClass:
 | 
			
		||||
	switch cls := op.Class(); {
 | 
			
		||||
	case cls.isLoadOrStore():
 | 
			
		||||
		switch op.Mode() {
 | 
			
		||||
		case ImmMode:
 | 
			
		||||
			fmt.Fprintf(f, "dst: %s imm: %d", ins.Dst, ins.Constant)
 | 
			
		||||
@@ -241,7 +307,7 @@ func (ins Instruction) Format(f fmt.State, c rune) {
 | 
			
		||||
			fmt.Fprintf(f, "dst: %s src: %s", ins.Dst, ins.Src)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	case ALU64Class, ALUClass:
 | 
			
		||||
	case cls.IsALU():
 | 
			
		||||
		fmt.Fprintf(f, "dst: %s ", ins.Dst)
 | 
			
		||||
		if op.ALUOp() == Swap || op.Source() == ImmSource {
 | 
			
		||||
			fmt.Fprintf(f, "imm: %d", ins.Constant)
 | 
			
		||||
@@ -249,7 +315,7 @@ func (ins Instruction) Format(f fmt.State, c rune) {
 | 
			
		||||
			fmt.Fprintf(f, "src: %s", ins.Src)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	case JumpClass:
 | 
			
		||||
	case cls.IsJump():
 | 
			
		||||
		switch jop := op.JumpOp(); jop {
 | 
			
		||||
		case Call:
 | 
			
		||||
			if ins.Src == PseudoCall {
 | 
			
		||||
@@ -270,34 +336,171 @@ func (ins Instruction) Format(f fmt.State, c rune) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
ref:
 | 
			
		||||
	if ins.Reference != "" {
 | 
			
		||||
		fmt.Fprintf(f, " <%s>", ins.Reference)
 | 
			
		||||
	if ins.Reference() != "" {
 | 
			
		||||
		fmt.Fprintf(f, " <%s>", ins.Reference())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ins Instruction) equal(other Instruction) bool {
 | 
			
		||||
	return ins.OpCode == other.OpCode &&
 | 
			
		||||
		ins.Dst == other.Dst &&
 | 
			
		||||
		ins.Src == other.Src &&
 | 
			
		||||
		ins.Offset == other.Offset &&
 | 
			
		||||
		ins.Constant == other.Constant
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Size returns the amount of bytes ins would occupy in binary form.
 | 
			
		||||
func (ins Instruction) Size() uint64 {
 | 
			
		||||
	return uint64(InstructionSize * ins.OpCode.rawInstructions())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type symbolMeta struct{}
 | 
			
		||||
 | 
			
		||||
// WithSymbol marks the Instruction as a Symbol, which other Instructions
 | 
			
		||||
// can point to using corresponding calls to WithReference.
 | 
			
		||||
func (ins Instruction) WithSymbol(name string) Instruction {
 | 
			
		||||
	ins.Metadata.Set(symbolMeta{}, name)
 | 
			
		||||
	return ins
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sym creates a symbol.
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: use WithSymbol instead.
 | 
			
		||||
func (ins Instruction) Sym(name string) Instruction {
 | 
			
		||||
	return ins.WithSymbol(name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Symbol returns the value ins has been marked with using WithSymbol,
 | 
			
		||||
// otherwise returns an empty string. A symbol is often an Instruction
 | 
			
		||||
// at the start of a function body.
 | 
			
		||||
func (ins Instruction) Symbol() string {
 | 
			
		||||
	sym, _ := ins.Metadata.Get(symbolMeta{}).(string)
 | 
			
		||||
	return sym
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type referenceMeta struct{}
 | 
			
		||||
 | 
			
		||||
// WithReference makes ins reference another Symbol or map by name.
 | 
			
		||||
func (ins Instruction) WithReference(ref string) Instruction {
 | 
			
		||||
	ins.Metadata.Set(referenceMeta{}, ref)
 | 
			
		||||
	return ins
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Reference returns the Symbol or map name referenced by ins, if any.
 | 
			
		||||
func (ins Instruction) Reference() string {
 | 
			
		||||
	ref, _ := ins.Metadata.Get(referenceMeta{}).(string)
 | 
			
		||||
	return ref
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type mapMeta struct{}
 | 
			
		||||
 | 
			
		||||
// Map returns the Map referenced by ins, if any.
 | 
			
		||||
// An Instruction will contain a Map if e.g. it references an existing,
 | 
			
		||||
// pinned map that was opened during ELF loading.
 | 
			
		||||
func (ins Instruction) Map() FDer {
 | 
			
		||||
	fd, _ := ins.Metadata.Get(mapMeta{}).(FDer)
 | 
			
		||||
	return fd
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type sourceMeta struct{}
 | 
			
		||||
 | 
			
		||||
// WithSource adds source information about the Instruction.
 | 
			
		||||
func (ins Instruction) WithSource(src fmt.Stringer) Instruction {
 | 
			
		||||
	ins.Metadata.Set(sourceMeta{}, src)
 | 
			
		||||
	return ins
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Source returns source information about the Instruction. The field is
 | 
			
		||||
// present when the compiler emits BTF line info about the Instruction and
 | 
			
		||||
// usually contains the line of source code responsible for it.
 | 
			
		||||
func (ins Instruction) Source() fmt.Stringer {
 | 
			
		||||
	str, _ := ins.Metadata.Get(sourceMeta{}).(fmt.Stringer)
 | 
			
		||||
	return str
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A Comment can be passed to Instruction.WithSource to add a comment
 | 
			
		||||
// to an instruction.
 | 
			
		||||
type Comment string
 | 
			
		||||
 | 
			
		||||
func (s Comment) String() string {
 | 
			
		||||
	return string(s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FDer represents a resource tied to an underlying file descriptor.
 | 
			
		||||
// Used as a stand-in for e.g. ebpf.Map since that type cannot be
 | 
			
		||||
// imported here and FD() is the only method we rely on.
 | 
			
		||||
type FDer interface {
 | 
			
		||||
	FD() int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Instructions is an eBPF program.
 | 
			
		||||
type Instructions []Instruction
 | 
			
		||||
 | 
			
		||||
// Unmarshal unmarshals an Instructions from a binary instruction stream.
 | 
			
		||||
// All instructions in insns are replaced by instructions decoded from r.
 | 
			
		||||
func (insns *Instructions) Unmarshal(r io.Reader, bo binary.ByteOrder) error {
 | 
			
		||||
	if len(*insns) > 0 {
 | 
			
		||||
		*insns = nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var offset uint64
 | 
			
		||||
	for {
 | 
			
		||||
		var ins Instruction
 | 
			
		||||
		n, err := ins.Unmarshal(r, bo)
 | 
			
		||||
		if errors.Is(err, io.EOF) {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return fmt.Errorf("offset %d: %w", offset, err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		*insns = append(*insns, ins)
 | 
			
		||||
		offset += n
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Name returns the name of the function insns belongs to, if any.
 | 
			
		||||
func (insns Instructions) Name() string {
 | 
			
		||||
	if len(insns) == 0 {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	return insns[0].Symbol()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (insns Instructions) String() string {
 | 
			
		||||
	return fmt.Sprint(insns)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RewriteMapPtr rewrites all loads of a specific map pointer to a new fd.
 | 
			
		||||
// Size returns the amount of bytes insns would occupy in binary form.
 | 
			
		||||
func (insns Instructions) Size() uint64 {
 | 
			
		||||
	var sum uint64
 | 
			
		||||
	for _, ins := range insns {
 | 
			
		||||
		sum += ins.Size()
 | 
			
		||||
	}
 | 
			
		||||
	return sum
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AssociateMap updates all Instructions that Reference the given symbol
 | 
			
		||||
// to point to an existing Map m instead.
 | 
			
		||||
//
 | 
			
		||||
// Returns an error if the symbol isn't used, see IsUnreferencedSymbol.
 | 
			
		||||
func (insns Instructions) RewriteMapPtr(symbol string, fd int) error {
 | 
			
		||||
// Returns ErrUnreferencedSymbol error if no references to symbol are found
 | 
			
		||||
// in insns. If symbol is anything else than the symbol name of map (e.g.
 | 
			
		||||
// a bpf2bpf subprogram), an error is returned.
 | 
			
		||||
func (insns Instructions) AssociateMap(symbol string, m FDer) error {
 | 
			
		||||
	if symbol == "" {
 | 
			
		||||
		return errors.New("empty symbol")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	found := false
 | 
			
		||||
	var found bool
 | 
			
		||||
	for i := range insns {
 | 
			
		||||
		ins := &insns[i]
 | 
			
		||||
		if ins.Reference != symbol {
 | 
			
		||||
		if ins.Reference() != symbol {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if err := ins.RewriteMapPtr(fd); err != nil {
 | 
			
		||||
		if err := ins.AssociateMap(m); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -305,7 +508,40 @@ func (insns Instructions) RewriteMapPtr(symbol string, fd int) error {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !found {
 | 
			
		||||
		return &unreferencedSymbolError{symbol}
 | 
			
		||||
		return fmt.Errorf("symbol %s: %w", symbol, ErrUnreferencedSymbol)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RewriteMapPtr rewrites all loads of a specific map pointer to a new fd.
 | 
			
		||||
//
 | 
			
		||||
// Returns ErrUnreferencedSymbol if the symbol isn't used.
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: use AssociateMap instead.
 | 
			
		||||
func (insns Instructions) RewriteMapPtr(symbol string, fd int) error {
 | 
			
		||||
	if symbol == "" {
 | 
			
		||||
		return errors.New("empty symbol")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var found bool
 | 
			
		||||
	for i := range insns {
 | 
			
		||||
		ins := &insns[i]
 | 
			
		||||
		if ins.Reference() != symbol {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !ins.IsLoadFromMap() {
 | 
			
		||||
			return errors.New("not a load from a map")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ins.encodeMapFD(fd)
 | 
			
		||||
 | 
			
		||||
		found = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !found {
 | 
			
		||||
		return fmt.Errorf("symbol %s: %w", symbol, ErrUnreferencedSymbol)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
@@ -317,31 +553,61 @@ func (insns Instructions) SymbolOffsets() (map[string]int, error) {
 | 
			
		||||
	offsets := make(map[string]int)
 | 
			
		||||
 | 
			
		||||
	for i, ins := range insns {
 | 
			
		||||
		if ins.Symbol == "" {
 | 
			
		||||
		if ins.Symbol() == "" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if _, ok := offsets[ins.Symbol]; ok {
 | 
			
		||||
			return nil, fmt.Errorf("duplicate symbol %s", ins.Symbol)
 | 
			
		||||
		if _, ok := offsets[ins.Symbol()]; ok {
 | 
			
		||||
			return nil, fmt.Errorf("duplicate symbol %s", ins.Symbol())
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		offsets[ins.Symbol] = i
 | 
			
		||||
		offsets[ins.Symbol()] = i
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return offsets, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FunctionReferences returns a set of symbol names these Instructions make
 | 
			
		||||
// bpf-to-bpf calls to.
 | 
			
		||||
func (insns Instructions) FunctionReferences() []string {
 | 
			
		||||
	calls := make(map[string]struct{})
 | 
			
		||||
	for _, ins := range insns {
 | 
			
		||||
		if ins.Constant != -1 {
 | 
			
		||||
			// BPF-to-BPF calls have -1 constants.
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ins.Reference() == "" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !ins.IsFunctionReference() {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		calls[ins.Reference()] = struct{}{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	result := make([]string, 0, len(calls))
 | 
			
		||||
	for call := range calls {
 | 
			
		||||
		result = append(result, call)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sort.Strings(result)
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ReferenceOffsets returns the set of references and their offset in
 | 
			
		||||
// the instructions.
 | 
			
		||||
func (insns Instructions) ReferenceOffsets() map[string][]int {
 | 
			
		||||
	offsets := make(map[string][]int)
 | 
			
		||||
 | 
			
		||||
	for i, ins := range insns {
 | 
			
		||||
		if ins.Reference == "" {
 | 
			
		||||
		if ins.Reference() == "" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		offsets[ins.Reference] = append(offsets[ins.Reference], i)
 | 
			
		||||
		offsets[ins.Reference()] = append(offsets[ins.Reference()], i)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return offsets
 | 
			
		||||
@@ -392,18 +658,36 @@ func (insns Instructions) Format(f fmt.State, c rune) {
 | 
			
		||||
 | 
			
		||||
	iter := insns.Iterate()
 | 
			
		||||
	for iter.Next() {
 | 
			
		||||
		if iter.Ins.Symbol != "" {
 | 
			
		||||
			fmt.Fprintf(f, "%s%s:\n", symIndent, iter.Ins.Symbol)
 | 
			
		||||
		if iter.Ins.Symbol() != "" {
 | 
			
		||||
			fmt.Fprintf(f, "%s%s:\n", symIndent, iter.Ins.Symbol())
 | 
			
		||||
		}
 | 
			
		||||
		if src := iter.Ins.Source(); src != nil {
 | 
			
		||||
			line := strings.TrimSpace(src.String())
 | 
			
		||||
			if line != "" {
 | 
			
		||||
				fmt.Fprintf(f, "%s%*s; %s\n", indent, offsetWidth, " ", line)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Fprintf(f, "%s%*d: %v\n", indent, offsetWidth, iter.Offset, iter.Ins)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Marshal encodes a BPF program into the kernel format.
 | 
			
		||||
//
 | 
			
		||||
// insns may be modified if there are unresolved jumps or bpf2bpf calls.
 | 
			
		||||
//
 | 
			
		||||
// Returns ErrUnsatisfiedProgramReference if there is a Reference Instruction
 | 
			
		||||
// without a matching Symbol Instruction within insns.
 | 
			
		||||
func (insns Instructions) Marshal(w io.Writer, bo binary.ByteOrder) error {
 | 
			
		||||
	if err := insns.encodeFunctionReferences(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := insns.encodeMapPointers(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, ins := range insns {
 | 
			
		||||
		_, err := ins.Marshal(w, bo)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
		if _, err := ins.Marshal(w, bo); err != nil {
 | 
			
		||||
			return fmt.Errorf("instruction %d: %w", i, err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -429,6 +713,95 @@ func (insns Instructions) Tag(bo binary.ByteOrder) (string, error) {
 | 
			
		||||
	return hex.EncodeToString(h.Sum(nil)[:unix.BPF_TAG_SIZE]), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// encodeFunctionReferences populates the Offset (or Constant, depending on
 | 
			
		||||
// the instruction type) field of instructions with a Reference field to point
 | 
			
		||||
// to the offset of the corresponding instruction with a matching Symbol field.
 | 
			
		||||
//
 | 
			
		||||
// Only Reference Instructions that are either jumps or BPF function references
 | 
			
		||||
// (calls or function pointer loads) are populated.
 | 
			
		||||
//
 | 
			
		||||
// Returns ErrUnsatisfiedProgramReference if there is a Reference Instruction
 | 
			
		||||
// without at least one corresponding Symbol Instruction within insns.
 | 
			
		||||
func (insns Instructions) encodeFunctionReferences() error {
 | 
			
		||||
	// Index the offsets of instructions tagged as a symbol.
 | 
			
		||||
	symbolOffsets := make(map[string]RawInstructionOffset)
 | 
			
		||||
	iter := insns.Iterate()
 | 
			
		||||
	for iter.Next() {
 | 
			
		||||
		ins := iter.Ins
 | 
			
		||||
 | 
			
		||||
		if ins.Symbol() == "" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if _, ok := symbolOffsets[ins.Symbol()]; ok {
 | 
			
		||||
			return fmt.Errorf("duplicate symbol %s", ins.Symbol())
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		symbolOffsets[ins.Symbol()] = iter.Offset
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Find all instructions tagged as references to other symbols.
 | 
			
		||||
	// Depending on the instruction type, populate their constant or offset
 | 
			
		||||
	// fields to point to the symbol they refer to within the insn stream.
 | 
			
		||||
	iter = insns.Iterate()
 | 
			
		||||
	for iter.Next() {
 | 
			
		||||
		i := iter.Index
 | 
			
		||||
		offset := iter.Offset
 | 
			
		||||
		ins := iter.Ins
 | 
			
		||||
 | 
			
		||||
		if ins.Reference() == "" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch {
 | 
			
		||||
		case ins.IsFunctionReference() && ins.Constant == -1:
 | 
			
		||||
			symOffset, ok := symbolOffsets[ins.Reference()]
 | 
			
		||||
			if !ok {
 | 
			
		||||
				return fmt.Errorf("%s at insn %d: symbol %q: %w", ins.OpCode, i, ins.Reference(), ErrUnsatisfiedProgramReference)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ins.Constant = int64(symOffset - offset - 1)
 | 
			
		||||
 | 
			
		||||
		case ins.OpCode.Class().IsJump() && ins.Offset == -1:
 | 
			
		||||
			symOffset, ok := symbolOffsets[ins.Reference()]
 | 
			
		||||
			if !ok {
 | 
			
		||||
				return fmt.Errorf("%s at insn %d: symbol %q: %w", ins.OpCode, i, ins.Reference(), ErrUnsatisfiedProgramReference)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ins.Offset = int16(symOffset - offset - 1)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// encodeMapPointers finds all Map Instructions and encodes their FDs
 | 
			
		||||
// into their Constant fields.
 | 
			
		||||
func (insns Instructions) encodeMapPointers() error {
 | 
			
		||||
	iter := insns.Iterate()
 | 
			
		||||
	for iter.Next() {
 | 
			
		||||
		ins := iter.Ins
 | 
			
		||||
 | 
			
		||||
		if !ins.IsLoadFromMap() {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		m := ins.Map()
 | 
			
		||||
		if m == nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fd := m.FD()
 | 
			
		||||
		if fd < 0 {
 | 
			
		||||
			return fmt.Errorf("map %s: %w", m, sys.ErrClosedFd)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ins.encodeMapFD(m.FD())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Iterate allows iterating a BPF program while keeping track of
 | 
			
		||||
// various offsets.
 | 
			
		||||
//
 | 
			
		||||
@@ -464,13 +837,6 @@ func (iter *InstructionIterator) Next() bool {
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type bpfInstruction struct {
 | 
			
		||||
	OpCode    OpCode
 | 
			
		||||
	Registers bpfRegisters
 | 
			
		||||
	Offset    int16
 | 
			
		||||
	Constant  int32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type bpfRegisters uint8
 | 
			
		||||
 | 
			
		||||
func newBPFRegisters(dst, src Register, bo binary.ByteOrder) (bpfRegisters, error) {
 | 
			
		||||
@@ -484,28 +850,10 @@ func newBPFRegisters(dst, src Register, bo binary.ByteOrder) (bpfRegisters, erro
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r bpfRegisters) Unmarshal(bo binary.ByteOrder) (dst, src Register, err error) {
 | 
			
		||||
	switch bo {
 | 
			
		||||
	case binary.LittleEndian:
 | 
			
		||||
		return Register(r & 0xF), Register(r >> 4), nil
 | 
			
		||||
	case binary.BigEndian:
 | 
			
		||||
		return Register(r >> 4), Register(r & 0xf), nil
 | 
			
		||||
	default:
 | 
			
		||||
		return 0, 0, fmt.Errorf("unrecognized ByteOrder %T", bo)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type unreferencedSymbolError struct {
 | 
			
		||||
	symbol string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (use *unreferencedSymbolError) Error() string {
 | 
			
		||||
	return fmt.Sprintf("unreferenced symbol %s", use.symbol)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsUnreferencedSymbol returns true if err was caused by
 | 
			
		||||
// an unreferenced symbol.
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: use errors.Is(err, asm.ErrUnreferencedSymbol).
 | 
			
		||||
func IsUnreferencedSymbol(err error) bool {
 | 
			
		||||
	_, ok := err.(*unreferencedSymbolError)
 | 
			
		||||
	return ok
 | 
			
		||||
	return errors.Is(err, ErrUnreferencedSymbol)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										76
									
								
								vendor/github.com/cilium/ebpf/asm/jump.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								vendor/github.com/cilium/ebpf/asm/jump.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -60,50 +60,68 @@ func (op JumpOp) Op(source Source) OpCode {
 | 
			
		||||
	return OpCode(JumpClass).SetJumpOp(op).SetSource(source)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Imm compares dst to value, and adjusts PC by offset if the condition is fulfilled.
 | 
			
		||||
// Imm compares 64 bit dst to 64 bit value (sign extended), and adjusts PC by offset if the condition is fulfilled.
 | 
			
		||||
func (op JumpOp) Imm(dst Register, value int32, label string) Instruction {
 | 
			
		||||
	if op == Exit || op == Call || op == Ja {
 | 
			
		||||
		return Instruction{OpCode: InvalidOpCode}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return Instruction{
 | 
			
		||||
		OpCode:    OpCode(JumpClass).SetJumpOp(op).SetSource(ImmSource),
 | 
			
		||||
		Dst:       dst,
 | 
			
		||||
		Offset:    -1,
 | 
			
		||||
		Constant:  int64(value),
 | 
			
		||||
		Reference: label,
 | 
			
		||||
	}
 | 
			
		||||
		OpCode:   op.opCode(JumpClass, ImmSource),
 | 
			
		||||
		Dst:      dst,
 | 
			
		||||
		Offset:   -1,
 | 
			
		||||
		Constant: int64(value),
 | 
			
		||||
	}.WithReference(label)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Reg compares dst to src, and adjusts PC by offset if the condition is fulfilled.
 | 
			
		||||
// Imm32 compares 32 bit dst to 32 bit value, and adjusts PC by offset if the condition is fulfilled.
 | 
			
		||||
// Requires kernel 5.1.
 | 
			
		||||
func (op JumpOp) Imm32(dst Register, value int32, label string) Instruction {
 | 
			
		||||
	return Instruction{
 | 
			
		||||
		OpCode:   op.opCode(Jump32Class, ImmSource),
 | 
			
		||||
		Dst:      dst,
 | 
			
		||||
		Offset:   -1,
 | 
			
		||||
		Constant: int64(value),
 | 
			
		||||
	}.WithReference(label)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Reg compares 64 bit dst to 64 bit src, and adjusts PC by offset if the condition is fulfilled.
 | 
			
		||||
func (op JumpOp) Reg(dst, src Register, label string) Instruction {
 | 
			
		||||
	return Instruction{
 | 
			
		||||
		OpCode: op.opCode(JumpClass, RegSource),
 | 
			
		||||
		Dst:    dst,
 | 
			
		||||
		Src:    src,
 | 
			
		||||
		Offset: -1,
 | 
			
		||||
	}.WithReference(label)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Reg32 compares 32 bit dst to 32 bit src, and adjusts PC by offset if the condition is fulfilled.
 | 
			
		||||
// Requires kernel 5.1.
 | 
			
		||||
func (op JumpOp) Reg32(dst, src Register, label string) Instruction {
 | 
			
		||||
	return Instruction{
 | 
			
		||||
		OpCode: op.opCode(Jump32Class, RegSource),
 | 
			
		||||
		Dst:    dst,
 | 
			
		||||
		Src:    src,
 | 
			
		||||
		Offset: -1,
 | 
			
		||||
	}.WithReference(label)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (op JumpOp) opCode(class Class, source Source) OpCode {
 | 
			
		||||
	if op == Exit || op == Call || op == Ja {
 | 
			
		||||
		return Instruction{OpCode: InvalidOpCode}
 | 
			
		||||
		return InvalidOpCode
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return Instruction{
 | 
			
		||||
		OpCode:    OpCode(JumpClass).SetJumpOp(op).SetSource(RegSource),
 | 
			
		||||
		Dst:       dst,
 | 
			
		||||
		Src:       src,
 | 
			
		||||
		Offset:    -1,
 | 
			
		||||
		Reference: label,
 | 
			
		||||
	}
 | 
			
		||||
	return OpCode(class).SetJumpOp(op).SetSource(source)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Label adjusts PC to the address of the label.
 | 
			
		||||
func (op JumpOp) Label(label string) Instruction {
 | 
			
		||||
	if op == Call {
 | 
			
		||||
		return Instruction{
 | 
			
		||||
			OpCode:    OpCode(JumpClass).SetJumpOp(Call),
 | 
			
		||||
			Src:       PseudoCall,
 | 
			
		||||
			Constant:  -1,
 | 
			
		||||
			Reference: label,
 | 
			
		||||
		}
 | 
			
		||||
			OpCode:   OpCode(JumpClass).SetJumpOp(Call),
 | 
			
		||||
			Src:      PseudoCall,
 | 
			
		||||
			Constant: -1,
 | 
			
		||||
		}.WithReference(label)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return Instruction{
 | 
			
		||||
		OpCode:    OpCode(JumpClass).SetJumpOp(op),
 | 
			
		||||
		Offset:    -1,
 | 
			
		||||
		Reference: label,
 | 
			
		||||
	}
 | 
			
		||||
		OpCode: OpCode(JumpClass).SetJumpOp(op),
 | 
			
		||||
		Offset: -1,
 | 
			
		||||
	}.WithReference(label)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										80
									
								
								vendor/github.com/cilium/ebpf/asm/metadata.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								vendor/github.com/cilium/ebpf/asm/metadata.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
package asm
 | 
			
		||||
 | 
			
		||||
// Metadata contains metadata about an instruction.
 | 
			
		||||
type Metadata struct {
 | 
			
		||||
	head *metaElement
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type metaElement struct {
 | 
			
		||||
	next       *metaElement
 | 
			
		||||
	key, value interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Find the element containing key.
 | 
			
		||||
//
 | 
			
		||||
// Returns nil if there is no such element.
 | 
			
		||||
func (m *Metadata) find(key interface{}) *metaElement {
 | 
			
		||||
	for e := m.head; e != nil; e = e.next {
 | 
			
		||||
		if e.key == key {
 | 
			
		||||
			return e
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Remove an element from the linked list.
 | 
			
		||||
//
 | 
			
		||||
// Copies as many elements of the list as necessary to remove r, but doesn't
 | 
			
		||||
// perform a full copy.
 | 
			
		||||
func (m *Metadata) remove(r *metaElement) {
 | 
			
		||||
	current := &m.head
 | 
			
		||||
	for e := m.head; e != nil; e = e.next {
 | 
			
		||||
		if e == r {
 | 
			
		||||
			// We've found the element we want to remove.
 | 
			
		||||
			*current = e.next
 | 
			
		||||
 | 
			
		||||
			// No need to copy the tail.
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// There is another element in front of the one we want to remove.
 | 
			
		||||
		// We have to copy it to be able to change metaElement.next.
 | 
			
		||||
		cpy := &metaElement{key: e.key, value: e.value}
 | 
			
		||||
		*current = cpy
 | 
			
		||||
		current = &cpy.next
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set a key to a value.
 | 
			
		||||
//
 | 
			
		||||
// If value is nil, the key is removed. Avoids modifying old metadata by
 | 
			
		||||
// copying if necessary.
 | 
			
		||||
func (m *Metadata) Set(key, value interface{}) {
 | 
			
		||||
	if e := m.find(key); e != nil {
 | 
			
		||||
		if e.value == value {
 | 
			
		||||
			// Key is present and the value is the same. Nothing to do.
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Key is present with a different value. Create a copy of the list
 | 
			
		||||
		// which doesn't have the element in it.
 | 
			
		||||
		m.remove(e)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// m.head is now a linked list that doesn't contain key.
 | 
			
		||||
	if value == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.head = &metaElement{key: key, value: value, next: m.head}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get the value of a key.
 | 
			
		||||
//
 | 
			
		||||
// Returns nil if no value with the given key is present.
 | 
			
		||||
func (m *Metadata) Get(key interface{}) interface{} {
 | 
			
		||||
	if e := m.find(key); e != nil {
 | 
			
		||||
		return e.value
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										116
									
								
								vendor/github.com/cilium/ebpf/asm/opcode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										116
									
								
								vendor/github.com/cilium/ebpf/asm/opcode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -7,14 +7,6 @@ import (
 | 
			
		||||
 | 
			
		||||
//go:generate stringer -output opcode_string.go -type=Class
 | 
			
		||||
 | 
			
		||||
type encoding int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	unknownEncoding encoding = iota
 | 
			
		||||
	loadOrStore
 | 
			
		||||
	jumpOrALU
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Class of operations
 | 
			
		||||
//
 | 
			
		||||
//    msb      lsb
 | 
			
		||||
@@ -26,31 +18,52 @@ type Class uint8
 | 
			
		||||
const classMask OpCode = 0x07
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// LdClass load memory
 | 
			
		||||
	// LdClass loads immediate values into registers.
 | 
			
		||||
	// Also used for non-standard load operations from cBPF.
 | 
			
		||||
	LdClass Class = 0x00
 | 
			
		||||
	// LdXClass load memory from constant
 | 
			
		||||
	// LdXClass loads memory into registers.
 | 
			
		||||
	LdXClass Class = 0x01
 | 
			
		||||
	// StClass load register from memory
 | 
			
		||||
	// StClass stores immediate values to memory.
 | 
			
		||||
	StClass Class = 0x02
 | 
			
		||||
	// StXClass load register from constant
 | 
			
		||||
	// StXClass stores registers to memory.
 | 
			
		||||
	StXClass Class = 0x03
 | 
			
		||||
	// ALUClass arithmetic operators
 | 
			
		||||
	// ALUClass describes arithmetic operators.
 | 
			
		||||
	ALUClass Class = 0x04
 | 
			
		||||
	// JumpClass jump operators
 | 
			
		||||
	// JumpClass describes jump operators.
 | 
			
		||||
	JumpClass Class = 0x05
 | 
			
		||||
	// ALU64Class arithmetic in 64 bit mode
 | 
			
		||||
	// Jump32Class describes jump operators with 32-bit comparisons.
 | 
			
		||||
	// Requires kernel 5.1.
 | 
			
		||||
	Jump32Class Class = 0x06
 | 
			
		||||
	// ALU64Class describes arithmetic operators in 64-bit mode.
 | 
			
		||||
	ALU64Class Class = 0x07
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (cls Class) encoding() encoding {
 | 
			
		||||
	switch cls {
 | 
			
		||||
	case LdClass, LdXClass, StClass, StXClass:
 | 
			
		||||
		return loadOrStore
 | 
			
		||||
	case ALU64Class, ALUClass, JumpClass:
 | 
			
		||||
		return jumpOrALU
 | 
			
		||||
	default:
 | 
			
		||||
		return unknownEncoding
 | 
			
		||||
	}
 | 
			
		||||
// IsLoad checks if this is either LdClass or LdXClass.
 | 
			
		||||
func (cls Class) IsLoad() bool {
 | 
			
		||||
	return cls == LdClass || cls == LdXClass
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsStore checks if this is either StClass or StXClass.
 | 
			
		||||
func (cls Class) IsStore() bool {
 | 
			
		||||
	return cls == StClass || cls == StXClass
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cls Class) isLoadOrStore() bool {
 | 
			
		||||
	return cls.IsLoad() || cls.IsStore()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsALU checks if this is either ALUClass or ALU64Class.
 | 
			
		||||
func (cls Class) IsALU() bool {
 | 
			
		||||
	return cls == ALUClass || cls == ALU64Class
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsJump checks if this is either JumpClass or Jump32Class.
 | 
			
		||||
func (cls Class) IsJump() bool {
 | 
			
		||||
	return cls == JumpClass || cls == Jump32Class
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cls Class) isJumpOrALU() bool {
 | 
			
		||||
	return cls.IsJump() || cls.IsALU()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OpCode is a packed eBPF opcode.
 | 
			
		||||
@@ -86,7 +99,7 @@ func (op OpCode) Class() Class {
 | 
			
		||||
 | 
			
		||||
// Mode returns the mode for load and store operations.
 | 
			
		||||
func (op OpCode) Mode() Mode {
 | 
			
		||||
	if op.Class().encoding() != loadOrStore {
 | 
			
		||||
	if !op.Class().isLoadOrStore() {
 | 
			
		||||
		return InvalidMode
 | 
			
		||||
	}
 | 
			
		||||
	return Mode(op & modeMask)
 | 
			
		||||
@@ -94,7 +107,7 @@ func (op OpCode) Mode() Mode {
 | 
			
		||||
 | 
			
		||||
// Size returns the size for load and store operations.
 | 
			
		||||
func (op OpCode) Size() Size {
 | 
			
		||||
	if op.Class().encoding() != loadOrStore {
 | 
			
		||||
	if !op.Class().isLoadOrStore() {
 | 
			
		||||
		return InvalidSize
 | 
			
		||||
	}
 | 
			
		||||
	return Size(op & sizeMask)
 | 
			
		||||
@@ -102,7 +115,7 @@ func (op OpCode) Size() Size {
 | 
			
		||||
 | 
			
		||||
// Source returns the source for branch and ALU operations.
 | 
			
		||||
func (op OpCode) Source() Source {
 | 
			
		||||
	if op.Class().encoding() != jumpOrALU || op.ALUOp() == Swap {
 | 
			
		||||
	if !op.Class().isJumpOrALU() || op.ALUOp() == Swap {
 | 
			
		||||
		return InvalidSource
 | 
			
		||||
	}
 | 
			
		||||
	return Source(op & sourceMask)
 | 
			
		||||
@@ -110,7 +123,7 @@ func (op OpCode) Source() Source {
 | 
			
		||||
 | 
			
		||||
// ALUOp returns the ALUOp.
 | 
			
		||||
func (op OpCode) ALUOp() ALUOp {
 | 
			
		||||
	if op.Class().encoding() != jumpOrALU {
 | 
			
		||||
	if !op.Class().IsALU() {
 | 
			
		||||
		return InvalidALUOp
 | 
			
		||||
	}
 | 
			
		||||
	return ALUOp(op & aluMask)
 | 
			
		||||
@@ -125,18 +138,27 @@ func (op OpCode) Endianness() Endianness {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// JumpOp returns the JumpOp.
 | 
			
		||||
// Returns InvalidJumpOp if it doesn't encode a jump.
 | 
			
		||||
func (op OpCode) JumpOp() JumpOp {
 | 
			
		||||
	if op.Class().encoding() != jumpOrALU {
 | 
			
		||||
	if !op.Class().IsJump() {
 | 
			
		||||
		return InvalidJumpOp
 | 
			
		||||
	}
 | 
			
		||||
	return JumpOp(op & jumpMask)
 | 
			
		||||
 | 
			
		||||
	jumpOp := JumpOp(op & jumpMask)
 | 
			
		||||
 | 
			
		||||
	// Some JumpOps are only supported by JumpClass, not Jump32Class.
 | 
			
		||||
	if op.Class() == Jump32Class && (jumpOp == Exit || jumpOp == Call || jumpOp == Ja) {
 | 
			
		||||
		return InvalidJumpOp
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return jumpOp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetMode sets the mode on load and store operations.
 | 
			
		||||
//
 | 
			
		||||
// Returns InvalidOpCode if op is of the wrong class.
 | 
			
		||||
func (op OpCode) SetMode(mode Mode) OpCode {
 | 
			
		||||
	if op.Class().encoding() != loadOrStore || !valid(OpCode(mode), modeMask) {
 | 
			
		||||
	if !op.Class().isLoadOrStore() || !valid(OpCode(mode), modeMask) {
 | 
			
		||||
		return InvalidOpCode
 | 
			
		||||
	}
 | 
			
		||||
	return (op & ^modeMask) | OpCode(mode)
 | 
			
		||||
@@ -146,7 +168,7 @@ func (op OpCode) SetMode(mode Mode) OpCode {
 | 
			
		||||
//
 | 
			
		||||
// Returns InvalidOpCode if op is of the wrong class.
 | 
			
		||||
func (op OpCode) SetSize(size Size) OpCode {
 | 
			
		||||
	if op.Class().encoding() != loadOrStore || !valid(OpCode(size), sizeMask) {
 | 
			
		||||
	if !op.Class().isLoadOrStore() || !valid(OpCode(size), sizeMask) {
 | 
			
		||||
		return InvalidOpCode
 | 
			
		||||
	}
 | 
			
		||||
	return (op & ^sizeMask) | OpCode(size)
 | 
			
		||||
@@ -156,7 +178,7 @@ func (op OpCode) SetSize(size Size) OpCode {
 | 
			
		||||
//
 | 
			
		||||
// Returns InvalidOpCode if op is of the wrong class.
 | 
			
		||||
func (op OpCode) SetSource(source Source) OpCode {
 | 
			
		||||
	if op.Class().encoding() != jumpOrALU || !valid(OpCode(source), sourceMask) {
 | 
			
		||||
	if !op.Class().isJumpOrALU() || !valid(OpCode(source), sourceMask) {
 | 
			
		||||
		return InvalidOpCode
 | 
			
		||||
	}
 | 
			
		||||
	return (op & ^sourceMask) | OpCode(source)
 | 
			
		||||
@@ -166,8 +188,7 @@ func (op OpCode) SetSource(source Source) OpCode {
 | 
			
		||||
//
 | 
			
		||||
// Returns InvalidOpCode if op is of the wrong class.
 | 
			
		||||
func (op OpCode) SetALUOp(alu ALUOp) OpCode {
 | 
			
		||||
	class := op.Class()
 | 
			
		||||
	if (class != ALUClass && class != ALU64Class) || !valid(OpCode(alu), aluMask) {
 | 
			
		||||
	if !op.Class().IsALU() || !valid(OpCode(alu), aluMask) {
 | 
			
		||||
		return InvalidOpCode
 | 
			
		||||
	}
 | 
			
		||||
	return (op & ^aluMask) | OpCode(alu)
 | 
			
		||||
@@ -177,17 +198,25 @@ func (op OpCode) SetALUOp(alu ALUOp) OpCode {
 | 
			
		||||
//
 | 
			
		||||
// Returns InvalidOpCode if op is of the wrong class.
 | 
			
		||||
func (op OpCode) SetJumpOp(jump JumpOp) OpCode {
 | 
			
		||||
	if op.Class() != JumpClass || !valid(OpCode(jump), jumpMask) {
 | 
			
		||||
	if !op.Class().IsJump() || !valid(OpCode(jump), jumpMask) {
 | 
			
		||||
		return InvalidOpCode
 | 
			
		||||
	}
 | 
			
		||||
	return (op & ^jumpMask) | OpCode(jump)
 | 
			
		||||
 | 
			
		||||
	newOp := (op & ^jumpMask) | OpCode(jump)
 | 
			
		||||
 | 
			
		||||
	// Check newOp is legal.
 | 
			
		||||
	if newOp.JumpOp() == InvalidJumpOp {
 | 
			
		||||
		return InvalidOpCode
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return newOp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (op OpCode) String() string {
 | 
			
		||||
	var f strings.Builder
 | 
			
		||||
 | 
			
		||||
	switch class := op.Class(); class {
 | 
			
		||||
	case LdClass, LdXClass, StClass, StXClass:
 | 
			
		||||
	switch class := op.Class(); {
 | 
			
		||||
	case class.isLoadOrStore():
 | 
			
		||||
		f.WriteString(strings.TrimSuffix(class.String(), "Class"))
 | 
			
		||||
 | 
			
		||||
		mode := op.Mode()
 | 
			
		||||
@@ -204,7 +233,7 @@ func (op OpCode) String() string {
 | 
			
		||||
			f.WriteString("B")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	case ALU64Class, ALUClass:
 | 
			
		||||
	case class.IsALU():
 | 
			
		||||
		f.WriteString(op.ALUOp().String())
 | 
			
		||||
 | 
			
		||||
		if op.ALUOp() == Swap {
 | 
			
		||||
@@ -218,8 +247,13 @@ func (op OpCode) String() string {
 | 
			
		||||
			f.WriteString(strings.TrimSuffix(op.Source().String(), "Source"))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	case JumpClass:
 | 
			
		||||
	case class.IsJump():
 | 
			
		||||
		f.WriteString(op.JumpOp().String())
 | 
			
		||||
 | 
			
		||||
		if class == Jump32Class {
 | 
			
		||||
			f.WriteString("32")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if jop := op.JumpOp(); jop != Exit && jop != Call {
 | 
			
		||||
			f.WriteString(strings.TrimSuffix(op.Source().String(), "Source"))
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								vendor/github.com/cilium/ebpf/asm/opcode_string.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/cilium/ebpf/asm/opcode_string.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -14,25 +14,17 @@ func _() {
 | 
			
		||||
	_ = x[StXClass-3]
 | 
			
		||||
	_ = x[ALUClass-4]
 | 
			
		||||
	_ = x[JumpClass-5]
 | 
			
		||||
	_ = x[Jump32Class-6]
 | 
			
		||||
	_ = x[ALU64Class-7]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	_Class_name_0 = "LdClassLdXClassStClassStXClassALUClassJumpClass"
 | 
			
		||||
	_Class_name_1 = "ALU64Class"
 | 
			
		||||
)
 | 
			
		||||
const _Class_name = "LdClassLdXClassStClassStXClassALUClassJumpClassJump32ClassALU64Class"
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_Class_index_0 = [...]uint8{0, 7, 15, 22, 30, 38, 47}
 | 
			
		||||
)
 | 
			
		||||
var _Class_index = [...]uint8{0, 7, 15, 22, 30, 38, 47, 58, 68}
 | 
			
		||||
 | 
			
		||||
func (i Class) String() string {
 | 
			
		||||
	switch {
 | 
			
		||||
	case 0 <= i && i <= 5:
 | 
			
		||||
		return _Class_name_0[_Class_index_0[i]:_Class_index_0[i+1]]
 | 
			
		||||
	case i == 7:
 | 
			
		||||
		return _Class_name_1
 | 
			
		||||
	default:
 | 
			
		||||
	if i >= Class(len(_Class_index)-1) {
 | 
			
		||||
		return "Class(" + strconv.FormatInt(int64(i), 10) + ")"
 | 
			
		||||
	}
 | 
			
		||||
	return _Class_name[_Class_index[i]:_Class_index[i+1]]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/github.com/cilium/ebpf/asm/register.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/cilium/ebpf/asm/register.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -38,6 +38,7 @@ const (
 | 
			
		||||
	PseudoMapFD    = R1 // BPF_PSEUDO_MAP_FD
 | 
			
		||||
	PseudoMapValue = R2 // BPF_PSEUDO_MAP_VALUE
 | 
			
		||||
	PseudoCall     = R1 // BPF_PSEUDO_CALL
 | 
			
		||||
	PseudoFunc     = R4 // BPF_PSEUDO_FUNC
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (r Register) String() string {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user