in pkg/elfparser/elf.go [542:630]
func (e *elfLoader) parseProg(loadedMaps map[string]ebpf_maps.BpfMap) (map[string]ebpf_progs.CreateEBPFProgInput, error) {
//Get prog data
var pgmList = make(map[string]ebpf_progs.CreateEBPFProgInput)
for progIndex, progEntry := range e.progSectionMap {
dataProg := progEntry.progSection
data, err := progEntry.progSection.Data()
if err != nil {
return nil, fmt.Errorf("failed to get progEntry Data")
}
if len(data) == 0 {
log.Infof("Missing data in prog Section")
return nil, fmt.Errorf("missing data in prog section")
}
var linkedMaps map[int]string
//Apply relocation
if e.reloSectionMap[progIndex] == nil {
log.Infof("Relocation is not needed")
} else {
progData, associatedMaps, err := e.parseAndApplyRelocSection(progIndex, loadedMaps)
if err != nil {
return nil, fmt.Errorf("failed to apply relocation: %v", err)
}
//Replace data with relocated data
data = progData
linkedMaps = associatedMaps
}
symbolTable, err := e.elfFile.Symbols()
if err != nil {
log.Infof("Get symbol failed")
return nil, fmt.Errorf("get symbols: %w", err)
}
// Iterate over the symbols in the symbol table
for _, symbol := range symbolTable {
// Check if the symbol is a function
if elf.ST_TYPE(symbol.Info) == elf.STT_FUNC {
// Check if sectionIndex matches
if uint32(symbol.Section) == uint32(progIndex) && elf.ST_BIND(symbol.Info) == elf.STB_GLOBAL {
// Check if the symbol's value (offset) is within the range of the section data
progSize := symbol.Size
secOff := symbol.Value
ProgName := symbol.Name
if secOff+progSize > dataProg.Size {
log.Infof("Section out of bound secOff %d - progSize %d for name %s and data size %d", progSize, secOff, ProgName, dataProg.Size)
return nil, fmt.Errorf("failed to Load the prog")
}
log.Infof("Sec '%s': found program '%s' at insn offset %d (%d bytes), code size %d insns (%d bytes)\n",
progEntry.progType, ProgName, secOff/uint64(bpfInsDefSize), secOff, progSize/uint64(bpfInsDefSize), progSize)
if symbol.Value >= dataProg.Addr && symbol.Value < dataProg.Addr+dataProg.Size {
dataStart := (symbol.Value - dataProg.Addr)
dataEnd := dataStart + progSize
programData := make([]byte, progSize)
copy(programData, data[dataStart:dataEnd])
pinLocation := ProgName
if len(e.customizedPinPath) != 0 {
pinLocation = e.customizedPinPath + "_" + ProgName
}
pinPath := constdef.PROG_BPF_FS + pinLocation
progMetaData := ebpf_progs.CreateEBPFProgInput{
ProgType: progEntry.progType,
SubSystem: progEntry.subSystem,
SubProgType: progEntry.subProgType,
ProgData: programData,
LicenseStr: e.license,
PinPath: pinPath,
InsDefSize: bpfInsDefSize,
AssociatedMaps: linkedMaps,
}
pgmList[pinPath] = progMetaData
} else {
log.Infof("Invalid ELF file\n")
return nil, fmt.Errorf("failed to Load the prog")
}
}
}
}
}
return pgmList, nil
}