Skip to content

Commit 3f1a755

Browse files
committed
map: add MapSpec.Tags field for reading btf_decl_tag attributes set on maps
This commit exposes btf_decl_tag values set on map defintions in the following manner: ``` struct { __uint(type, BPF_MAP_TYPE_ARRAY); ... } map_def __attribute__((btf_decl_tag("my_tag"))) __section(".maps"); ``` The MapSpec.Tags field is currently read-only and doesn't affect what's being loaded into the kernel. Signed-off-by: Timo Beckers <[email protected]>
1 parent 87af60f commit 3f1a755

11 files changed

+66
-0
lines changed

elf_reader.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"io"
1111
"math"
1212
"os"
13+
"slices"
1314
"strings"
1415

1516
"github.com/cilium/ebpf/asm"
@@ -724,6 +725,20 @@ func (ec *elfCode) loadMaps() error {
724725
return fmt.Errorf("section %v: map descriptors are not of equal size", sec.Name)
725726
}
726727

728+
// If the ELF has BTF, pull out the btf.Var for each map definition to
729+
// extract decl tags from.
730+
varsByName := make(map[string]*btf.Var)
731+
var ds *btf.Datasec
732+
if err := ec.btf.TypeByName(sec.Name, &ds); err == nil {
733+
for _, vsi := range ds.Vars {
734+
v, ok := btf.As[*btf.Var](vsi.Type)
735+
if !ok {
736+
return fmt.Errorf("section %v: btf.VarSecInfo doesn't point to a *btf.Var: %T", sec.Name, vsi.Type)
737+
}
738+
varsByName[string(v.Name)] = v
739+
}
740+
}
741+
727742
var (
728743
r = bufio.NewReader(sec.Open())
729744
size = sec.Size / uint64(nSym)
@@ -765,6 +780,10 @@ func (ec *elfCode) loadMaps() error {
765780
spec.Extra = bytes.NewReader(extra)
766781
}
767782

783+
if v, ok := varsByName[mapName]; ok {
784+
spec.Tags = slices.Clone(v.Tags)
785+
}
786+
768787
ec.maps[mapName] = &spec
769788
}
770789
}
@@ -1028,6 +1047,11 @@ func mapSpecFromBTF(es *elfSection, vs *btf.VarSecinfo, def *btf.Struct, spec *b
10281047
valueSize = 0
10291048
}
10301049

1050+
v, ok := btf.As[*btf.Var](vs.Type)
1051+
if !ok {
1052+
return nil, fmt.Errorf("BTF map definition: btf.VarSecInfo doesn't point to a *btf.Var: %T", vs.Type)
1053+
}
1054+
10311055
return &MapSpec{
10321056
Name: sanitizeName(name, -1),
10331057
Type: MapType(mapType),
@@ -1040,6 +1064,7 @@ func mapSpecFromBTF(es *elfSection, vs *btf.VarSecinfo, def *btf.Struct, spec *b
10401064
Pinning: pinType,
10411065
InnerMap: innerMapSpec,
10421066
Contents: contents,
1067+
Tags: slices.Clone(v.Tags),
10431068
}, nil
10441069
}
10451070

elf_reader_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,22 @@ func TestLoadCollectionSpec(t *testing.T) {
8282
MaxEntries: 1,
8383
Pinning: PinByName,
8484
},
85+
"bpf_decl_map": {
86+
Name: "bpf_decl_map",
87+
Type: Array,
88+
KeySize: 4,
89+
ValueSize: 8,
90+
MaxEntries: 1,
91+
Tags: []string{"a", "b"},
92+
},
93+
"btf_decl_map": {
94+
Name: "btf_decl_map",
95+
Type: Array,
96+
KeySize: 4,
97+
ValueSize: 8,
98+
MaxEntries: 1,
99+
Tags: []string{"a", "b"},
100+
},
85101
"btf_outer_map": {
86102
Name: "btf_outer_map",
87103
Type: ArrayOfMaps,

map.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ type MapSpec struct {
8585

8686
// The key and value type of this map. May be nil.
8787
Key, Value btf.Type
88+
89+
// Tags is a list of btf_decl_tag attributes set on the map definition.
90+
//
91+
// Decorate a map definition with `__attribute__((btf_decl_tag("foo")))`.
92+
Tags []string
8893
}
8994

9095
func (ms *MapSpec) String() string {
@@ -103,6 +108,7 @@ func (ms *MapSpec) Copy() *MapSpec {
103108
cpy.Contents = slices.Clone(cpy.Contents)
104109
cpy.Key = btf.Copy(cpy.Key)
105110
cpy.Value = btf.Copy(cpy.Value)
111+
cpy.Tags = slices.Clone(cpy.Tags)
106112

107113
if cpy.InnerMap == ms {
108114
cpy.InnerMap = &cpy

map_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ func TestMapSpecCopy(t *testing.T) {
9696
bytes.NewReader(nil),
9797
&btf.Int{},
9898
&btf.Int{},
99+
nil,
99100
}
100101
a.InnerMap = a
101102

testdata/loader-clang-14-eb.elf

368 Bytes
Binary file not shown.

testdata/loader-clang-14-el.elf

368 Bytes
Binary file not shown.

testdata/loader-clang-17-eb.elf

368 Bytes
Binary file not shown.

testdata/loader-clang-17-el.elf

368 Bytes
Binary file not shown.

testdata/loader-clang-20-eb.elf

360 Bytes
Binary file not shown.

testdata/loader-clang-20-el.elf

360 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)