github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/emulator/maps_stack.go (about) 1 package emulator 2 3 import ( 4 "fmt" 5 6 "github.com/dylandreimerink/gobpfld/ebpf" 7 ) 8 9 type StackMap struct { 10 AbstractMap 11 12 Values []*ByteMemory 13 } 14 15 func (m *StackMap) Init() error { 16 return nil 17 } 18 19 func (m *StackMap) Keys() []RegisterValue { 20 keys := make([]RegisterValue, len(m.Values)) 21 for i := range keys { 22 imm := newIMM(int64(i)) 23 keys[i] = &MemoryPtr{ 24 Memory: &ValueMemory{ 25 MemName: fmt.Sprintf("%s[%d]", m.Name, m.Def.ValueSize), 26 Mapping: []RegisterValue{ 27 imm, 28 imm, 29 imm, 30 imm, 31 }, 32 }, 33 } 34 } 35 return keys 36 } 37 38 func (m *StackMap) Lookup(key RegisterValue) (RegisterValue, error) { 39 keyPtr, ok := key.(PointerValue) 40 if !ok { 41 return nil, errMapKeyNoPtr 42 } 43 44 keyVal, err := keyPtr.Deref(0, ebpf.BPF_W) 45 if !ok { 46 return nil, fmt.Errorf("key read range: %w", err) 47 } 48 49 keyIndex := int(keyVal.Value()) 50 if keyIndex < 0 || keyIndex >= len(m.Values) { 51 return nil, errMapOutOfMemory 52 } 53 54 // Since the stack grows down(new items at the bottom), index 0 is the last value. 55 value := m.Values[len(m.Values)-1-keyIndex] 56 57 return &MemoryPtr{Memory: value, Offset: 0}, nil 58 } 59 60 func (m *StackMap) Push(value RegisterValue, size int64) error { 61 valuePtr, ok := value.(PointerValue) 62 if !ok { 63 return errMapValNoPtr 64 } 65 66 valueVal, err := valuePtr.ReadRange(0, int(size)) 67 if !ok { 68 return fmt.Errorf("value read range: %w", err) 69 } 70 71 m.Values = append(m.Values, &ByteMemory{ 72 MemName: fmt.Sprintf("%s[?]", m.Name), 73 Backing: valueVal, 74 }) 75 76 return nil 77 } 78 79 func (m *StackMap) Pop() (RegisterValue, error) { 80 if len(m.Values) == 0 { 81 return newIMM(0), nil 82 } 83 84 val := m.Values[len(m.Values)-1] 85 m.Values = m.Values[:len(m.Values)-1] 86 87 return &MemoryPtr{ 88 Memory: val, 89 }, nil 90 }