github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/kallsyms/symbol-resolver.go (about) 1 // Copyright 2024 The Inspektor Gadget authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package kallsyms 16 17 import ( 18 "fmt" 19 "os" 20 21 "github.com/inspektor-gadget/inspektor-gadget/pkg/kfilefields" 22 ) 23 24 // symbolResolver is an interface to resolve kernel symbols. 25 type symbolResolver interface { 26 resolve(symbol string) (uint64, error) 27 } 28 29 // kAllSymsResolver is a symbolResolver that resolves kernel symbols using a KAllSyms. 30 // It isn't safe for concurrent use. 31 type kAllSymsResolver struct { 32 kAllSyms *KAllSyms 33 } 34 35 // newKAllSymsResolver returns a new kAllSymsResolver. 36 func newKAllSymsResolver() *kAllSymsResolver { 37 return &kAllSymsResolver{} 38 } 39 40 // Resolve resolves a kernel symbol using the KAllSyms. 41 func (r *kAllSymsResolver) resolve(symbol string) (uint64, error) { 42 if r.kAllSyms == nil { 43 if err := r.init(); err != nil { 44 return 0, fmt.Errorf("initializing kallsyms: %w", err) 45 } 46 } 47 addr, ok := r.kAllSyms.symbolsMap[symbol] 48 if !ok { 49 return 0, fmt.Errorf("symbol %q was not found in kallsyms", symbol) 50 } 51 return addr, nil 52 } 53 54 func (r *kAllSymsResolver) init() error { 55 kAllSyms, err := NewKAllSyms() 56 if err != nil { 57 return err 58 } 59 r.kAllSyms = kAllSyms 60 return nil 61 } 62 63 // ebpfResolver is a symbolResolver that resolves kernel symbols using eBPF. 64 type ebpfResolver struct { 65 symbolsBypass map[string]kfilefields.FdType 66 } 67 68 // newEbpfResolver returns a new ebpfResolver. 69 func newEbpfResolver() *ebpfResolver { 70 // List of symbols that we're able to find in 'struct file *' using eBPF 71 return &ebpfResolver{ 72 symbolsBypass: map[string]kfilefields.FdType{ 73 "bpf_prog_fops": kfilefields.FdTypeEbpfProgram, 74 "socket_file_ops": kfilefields.FdTypeSocket, 75 }, 76 } 77 } 78 79 // Resolve resolves a kernel symbol using eBPF. 80 func (r *ebpfResolver) resolve(symbol string) (uint64, error) { 81 fdT, ok := r.symbolsBypass[symbol] 82 if !ok { 83 return 0, os.ErrInvalid 84 } 85 86 fop, err := kfilefields.ReadFOpForFdType(fdT) 87 if err != nil { 88 return 0, err 89 } 90 return fop, nil 91 }