Skip to content

Commit cfddc9e

Browse files
committed
internal/kallsyms: drop Module, AssignModules
The library doesn't use these routines anymore. Splitting module lookup from address lookup also doesn't really make sense because the really expensive part is parsing /proc/kallsyms, not storing a bit of extra metadata. Signed-off-by: Lorenz Bauer <[email protected]>
1 parent bbe798b commit cfddc9e

File tree

2 files changed

+0
-199
lines changed

2 files changed

+0
-199
lines changed

internal/kallsyms/kallsyms.go

Lines changed: 0 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -16,128 +16,6 @@ import (
1616
var errAmbiguousKsym = errors.New("multiple kernel symbols with the same name")
1717

1818
var symAddrs cache[string, uint64]
19-
var symModules cache[string, string]
20-
21-
// Module returns the kernel module providing the given symbol in the kernel, if
22-
// any. Returns an empty string and no error if the symbol is not present in the
23-
// kernel. Only function symbols are considered. Returns an error if multiple
24-
// symbols with the same name were found.
25-
//
26-
// Consider [AssignModules] if you need to resolve multiple symbols, as it will
27-
// only perform one iteration over /proc/kallsyms.
28-
func Module(name string) (string, error) {
29-
if name == "" {
30-
return "", nil
31-
}
32-
33-
if mod, ok := symModules.Load(name); ok {
34-
return mod, nil
35-
}
36-
37-
request := map[string]string{name: ""}
38-
if err := AssignModules(request); err != nil {
39-
return "", err
40-
}
41-
42-
return request[name], nil
43-
}
44-
45-
// AssignModules looks up the kernel module providing each given symbol, if any,
46-
// and assigns them to their corresponding values in the symbols map. Only
47-
// function symbols are considered. Results of all lookups are cached,
48-
// successful or otherwise.
49-
//
50-
// Any symbols missing in the kernel are ignored. Returns an error if multiple
51-
// symbols with a given name were found.
52-
func AssignModules(symbols map[string]string) error {
53-
if !platform.IsLinux {
54-
return fmt.Errorf("read /proc/kallsyms: %w", internal.ErrNotSupportedOnOS)
55-
}
56-
57-
if len(symbols) == 0 {
58-
return nil
59-
}
60-
61-
// Attempt to fetch symbols from cache.
62-
request := make(map[string]string)
63-
for name := range symbols {
64-
if mod, ok := symModules.Load(name); ok {
65-
symbols[name] = mod
66-
continue
67-
}
68-
69-
// Mark the symbol to be read from /proc/kallsyms.
70-
request[name] = ""
71-
}
72-
if len(request) == 0 {
73-
// All symbols satisfied from cache.
74-
return nil
75-
}
76-
77-
f, err := os.Open("/proc/kallsyms")
78-
if err != nil {
79-
return err
80-
}
81-
defer f.Close()
82-
83-
if err := assignModules(f, request); err != nil {
84-
return fmt.Errorf("assigning symbol modules: %w", err)
85-
}
86-
87-
// Update the cache with the new symbols. Cache all requested symbols, even if
88-
// they're missing or don't belong to a module.
89-
for name, mod := range request {
90-
symModules.Store(name, mod)
91-
symbols[name] = mod
92-
}
93-
94-
return nil
95-
}
96-
97-
// assignModules assigns kernel symbol modules read from f to values requested
98-
// by symbols. Always scans the whole input to make sure the user didn't request
99-
// an ambiguous symbol.
100-
func assignModules(f io.Reader, symbols map[string]string) error {
101-
if len(symbols) == 0 {
102-
return nil
103-
}
104-
105-
found := make(map[string]struct{})
106-
r := newReader(f)
107-
for r.Line() {
108-
// Only look for function symbols in the kernel's text section (tT).
109-
s, err, skip := parseSymbol(r, []rune{'t', 'T'})
110-
if err != nil {
111-
return fmt.Errorf("parsing kallsyms line: %w", err)
112-
}
113-
if skip {
114-
continue
115-
}
116-
117-
if _, requested := symbols[string(s.name)]; !requested {
118-
continue
119-
}
120-
121-
if _, ok := found[string(s.name)]; ok {
122-
// We've already seen this symbol. Return an error to avoid silently
123-
// attaching to a symbol in the wrong module. libbpf also rejects
124-
// referring to ambiguous symbols.
125-
//
126-
// We can't simply check if we already have a value for the given symbol,
127-
// since many won't have an associated kernel module.
128-
return fmt.Errorf("symbol %s: duplicate found at address 0x%x (module %q): %w",
129-
s.name, s.addr, s.mod, errAmbiguousKsym)
130-
}
131-
132-
symbols[string(s.name)] = string(s.mod)
133-
found[string(s.name)] = struct{}{}
134-
}
135-
if err := r.Err(); err != nil {
136-
return fmt.Errorf("reading kallsyms: %w", err)
137-
}
138-
139-
return nil
140-
}
14119

14220
// Address returns the address of the given symbol in the kernel. Returns 0 and
14321
// no error if the symbol is not present. Returns an error if multiple addresses

internal/kallsyms/kallsyms_test.go

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -53,49 +53,6 @@ func TestParseProcKallsyms(t *testing.T) {
5353
qt.Assert(t, qt.IsNil(r.Err()))
5454
}
5555

56-
func TestAssignModulesCaching(t *testing.T) {
57-
err := AssignModules(
58-
map[string]string{
59-
"bpf_perf_event_output": "",
60-
"foo": "",
61-
},
62-
)
63-
testutils.SkipIfNotSupportedOnOS(t, err)
64-
qt.Assert(t, qt.IsNil(err))
65-
66-
// Can't assume any kernel modules are loaded, but this symbol should at least
67-
// exist in the kernel. There is no semantic difference between a missing
68-
// symbol and a symbol that doesn't belong to a module.
69-
v, ok := symModules.Load("bpf_perf_event_output")
70-
qt.Assert(t, qt.IsTrue(ok))
71-
qt.Assert(t, qt.Equals(v, ""))
72-
73-
v, ok = symModules.Load("foo")
74-
qt.Assert(t, qt.IsTrue(ok))
75-
qt.Assert(t, qt.Equals(v, ""))
76-
}
77-
78-
func TestAssignModules(t *testing.T) {
79-
mods := map[string]string{
80-
"hid_generic_probe": "",
81-
"nft_counter_seq": "",
82-
"tcp_connect": "",
83-
"foo": "",
84-
"__kstrtab_功能": "",
85-
}
86-
qt.Assert(t, qt.IsNil(assignModules(bytes.NewBuffer(syms), mods)))
87-
qt.Assert(t, qt.DeepEquals(mods, map[string]string{
88-
"hid_generic_probe": "hid_generic",
89-
"nft_counter_seq": "", // wrong symbol type
90-
"tcp_connect": "",
91-
"foo": "",
92-
"__kstrtab_功能": "mod",
93-
}))
94-
95-
qt.Assert(t, qt.ErrorIs(assignModules(bytes.NewBuffer(syms),
96-
map[string]string{"writenote": ""}), errAmbiguousKsym))
97-
}
98-
9956
func TestAssignAddressesCaching(t *testing.T) {
10057
err := AssignAddresses(
10158
map[string]uint64{
@@ -136,20 +93,6 @@ func TestAssignAddresses(t *testing.T) {
13693
qt.Assert(t, qt.ErrorIs(assignAddresses(b, ksyms), errAmbiguousKsym))
13794
}
13895

139-
func BenchmarkAssignModules(b *testing.B) {
140-
b.ReportAllocs()
141-
for i := 0; i < b.N; i++ {
142-
b.StopTimer()
143-
f := bytes.NewBuffer(syms)
144-
want := map[string]string{"bench_sym": ""}
145-
b.StartTimer()
146-
147-
if err := assignModules(f, want); err != nil {
148-
b.Fatal(err)
149-
}
150-
}
151-
}
152-
15396
func BenchmarkAssignAddresses(b *testing.B) {
15497
b.ReportAllocs()
15598
for i := 0; i < b.N; i++ {
@@ -164,26 +107,6 @@ func BenchmarkAssignAddresses(b *testing.B) {
164107
}
165108
}
166109

167-
func BenchmarkAssignModulesKallsyms(b *testing.B) {
168-
b.ReportAllocs()
169-
for i := 0; i < b.N; i++ {
170-
b.StopTimer()
171-
f := mustOpenProcKallsyms(b)
172-
want := map[string]string{
173-
"bpf_trace_vprintk": "",
174-
"bpf_send_signal": "",
175-
"bpf_event_notify": "",
176-
"bpf_trace_printk": "",
177-
"bpf_perf_event_output": "",
178-
}
179-
b.StartTimer()
180-
181-
if err := assignModules(f, want); err != nil {
182-
b.Fatal(err)
183-
}
184-
}
185-
}
186-
187110
// Benchmark getting 5 kernel symbols from /proc/kallsyms.
188111
func BenchmarkAssignAddressesKallsyms(b *testing.B) {
189112
b.ReportAllocs()

0 commit comments

Comments
 (0)