fixupMagicFields fills fields of MapSpec which are usually left empty in ELF or which depend on runtime information. The method doesn't modify Spec, instead returning a copy. The copy is only performed if fixups are necessary, so callers mustn't mutate the returned spec.
()
| 135 | // The copy is only performed if fixups are necessary, so callers mustn't mutate |
| 136 | // the returned spec. |
| 137 | func (spec *MapSpec) fixupMagicFields() (*MapSpec, error) { |
| 138 | switch { |
| 139 | case spec.Type.canStoreMap(): |
| 140 | if spec.ValueSize != 0 && spec.ValueSize != 4 { |
| 141 | return nil, errors.New("ValueSize must be zero or four for map of map") |
| 142 | } |
| 143 | |
| 144 | spec = spec.Copy() |
| 145 | spec.ValueSize = 4 |
| 146 | |
| 147 | case spec.Type == PerfEventArray: |
| 148 | if spec.KeySize != 0 && spec.KeySize != 4 { |
| 149 | return nil, errors.New("KeySize must be zero or four for perf event array") |
| 150 | } |
| 151 | |
| 152 | if spec.ValueSize != 0 && spec.ValueSize != 4 { |
| 153 | return nil, errors.New("ValueSize must be zero or four for perf event array") |
| 154 | } |
| 155 | |
| 156 | spec = spec.Copy() |
| 157 | spec.KeySize = 4 |
| 158 | spec.ValueSize = 4 |
| 159 | |
| 160 | n, err := PossibleCPU() |
| 161 | if err != nil { |
| 162 | return nil, fmt.Errorf("fixup perf event array: %w", err) |
| 163 | } |
| 164 | |
| 165 | if n := uint32(n); spec.MaxEntries == 0 || spec.MaxEntries > n { |
| 166 | // MaxEntries should be zero most of the time, but there is code |
| 167 | // out there which hardcodes large constants. Clamp the number |
| 168 | // of entries to the number of CPUs at most. Allow creating maps with |
| 169 | // less than n items since some kernel selftests relied on this |
| 170 | // behaviour in the past. |
| 171 | spec.MaxEntries = n |
| 172 | } |
| 173 | |
| 174 | case spec.Type == CPUMap: |
| 175 | n, err := PossibleCPU() |
| 176 | if err != nil { |
| 177 | return nil, fmt.Errorf("fixup cpu map: %w", err) |
| 178 | } |
| 179 | |
| 180 | if n := uint32(n); spec.MaxEntries == 0 || spec.MaxEntries > n { |
| 181 | // Perform clamping similar to PerfEventArray. |
| 182 | spec.MaxEntries = n |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | return spec, nil |
| 187 | } |
| 188 | |
| 189 | // dataSection returns the contents of a datasec if the MapSpec represents one. |
| 190 | func (ms *MapSpec) dataSection() ([]byte, error) { |
no test coverage detected