diff --git a/ebpf/symtab/elf/elf_sym.go b/ebpf/symtab/elf/elf_sym.go index 81a604a439..e549d84812 100644 --- a/ebpf/symtab/elf/elf_sym.go +++ b/ebpf/symtab/elf/elf_sym.go @@ -51,6 +51,14 @@ func (f *InMemElfFile) getSymbols(typ elf.SectionType, opt *SymbolsOptions) ([]S // if there is no such section in the File. var ErrNoSymbols = errors.New("no symbol section") +func clampSymSize(size uint64) uint32 { + const maxU32 = uint64(^uint32(0)) + if size > maxU32 { + return uint32(maxU32) + } + return uint32(size) +} + func (f *InMemElfFile) getSymbols64(typ elf.SectionType, opt *SymbolsOptions) ([]SymbolIndex, uint32, error) { symtabSection := f.sectionByType(typ) if symtabSection == nil { @@ -88,7 +96,7 @@ func (f *InMemElfFile) getSymbols64(typ elf.SectionType, opt *SymbolsOptions) ([ //Other: rawSym[5], //Shndx: f.ByteOrder.Uint16(rawSym[6:8]), // not used Value: f.ByteOrder.Uint64(rawSym[8:16]), - //Size: f.ByteOrder.Uint64(rawSym[16:24]), // not used + Size: f.ByteOrder.Uint64(rawSym[16:24]), } if sym.Value != 0 && sym.Info&0xf == byte(elf.STT_FUNC) { @@ -101,6 +109,7 @@ func (f *InMemElfFile) getSymbols64(typ elf.SectionType, opt *SymbolsOptions) ([ } symbols[i].Value = pc symbols[i].Name = NewName(sym.Name, linkIndex) + symbols[i].Size = clampSymSize(sym.Size) i++ } } @@ -142,8 +151,8 @@ func (f *InMemElfFile) getSymbols32(typ elf.SectionType, opt *SymbolsOptions) ([ sym = elf.Sym32{ Name: f.ByteOrder.Uint32(rawSym[:4]), Value: f.ByteOrder.Uint32(rawSym[4:8]), - //Size: f.ByteOrder.Uint32(rawSym[8:12]), - Info: rawSym[12], + Size: f.ByteOrder.Uint32(rawSym[8:12]), + Info: rawSym[12], //Other: rawSym[13], //Shndx: f.ByteOrder.Uint16(rawSym[14:16]), } @@ -156,7 +165,9 @@ func (f *InMemElfFile) getSymbols32(typ elf.SectionType, opt *SymbolsOptions) ([ if pc >= opt.FilterFrom && pc < opt.FilterTo { continue } + symbols[i].Value = pc symbols[i].Name = NewName(sym.Name, linkIndex) + symbols[i].Size = sym.Size i++ } } diff --git a/ebpf/symtab/elf/symbol_table.go b/ebpf/symtab/elf/symbol_table.go index 826446fd05..4f3db4b9dc 100644 --- a/ebpf/symtab/elf/symbol_table.go +++ b/ebpf/symtab/elf/symbol_table.go @@ -25,8 +25,10 @@ type SymbolTableInterface interface { } type SymbolIndex struct { - Name Name Value uint64 + Name Name + // st_size, or 0 when unknown; build-time only (see addEndOfSymbolSentinels) + Size uint32 } type SectionLinkIndex uint8 @@ -48,6 +50,26 @@ func (n *Name) LinkIndex() SectionLinkIndex { return SectionLinkIndex(*n >> 31) } +const sentinelNameIndex = 0x7fffffff + +const minGapSentinel = 64 + +func addEndOfSymbolSentinels(all []SymbolIndex) []SymbolIndex { + out := make([]SymbolIndex, 0, len(all)+len(all)/64+1) + for i := range all { + out = append(out, all[i]) + if all[i].Size == 0 { + continue + } + end := all[i].Value + uint64(all[i].Size) + if i+1 < len(all) && all[i+1].Value < end+minGapSentinel { + continue + } + out = append(out, SymbolIndex{Name: NewName(sentinelNameIndex, sectionTypeSym), Value: end}) + } + return out +} + type FlatSymbolIndex struct { Links []elf.SectionHeader Names []Name @@ -104,6 +126,9 @@ func (st *SymbolTable) Resolve(addr uint64) string { if i == -1 { return "" } + if st.Index.Names[i].NameIndex() == sentinelNameIndex { + return "" + } name, _ := st.symbolName(i) return name } @@ -136,14 +161,15 @@ func (f *InMemElfFile) NewSymbolTable(opt *SymbolsOptions, symReader ElfSymbolRe } return all[i].Value < all[j].Value }) + all = addEndOfSymbolSentinels(all) res := &SymbolTable{Index: FlatSymbolIndex{ Links: []elf.SectionHeader{ f.Sections[sectionSym], // should be at 0 - SectionTypeSym f.Sections[sectionDynSym], // should be at 1 - SectionTypeDynSym }, - Names: make([]Name, total), - Values: gosym.NewPCIndex(total), + Names: make([]Name, len(all)), + Values: gosym.NewPCIndex(len(all)), }, hasSection: map[elf.SectionType]bool{ elf.SHT_SYMTAB: len(sym) > 0,