pub fn load(config: Config, bytes: &[u8]) -> Result<Self, ELFError> {
        let elf = Elf::parse(bytes)?;
        let mut elf_bytes = bytes.to_vec();
        Self::validate(&elf, &elf_bytes)?;

        let mut calls = HashMap::default();
        Self::relocate(&elf, &mut elf_bytes, &mut calls)?;

        let text_section = Self::get_section(&elf, ".text")?;

        // calculate entrypoint offset into the text section
        let offset = elf.header.e_entry - text_section.sh_addr;
        if offset % ebpf::INSN_SIZE as u64 != 0 {
            return Err(ELFError::InvalidEntrypoint);
        }
        let entrypoint = offset as usize / ebpf::INSN_SIZE;

        // calculate the text section info
        let text_section_info = SectionInfo {
            vaddr: text_section.sh_addr.saturating_add(ebpf::MM_PROGRAM_START),
            offset_range: text_section.file_range(),
        };

        // calculate the read-only section infos
        let ro_section_infos = elf
            .section_headers
            .iter()
            .filter_map(|section_header| {
                if let Some(Ok(this_name)) = elf.shdr_strtab.get(section_header.sh_name) {
                    if this_name == ".rodata"
                        || this_name == ".data.rel.ro"
                        || this_name == ".eh_frame"
                    {
                        return Some(SectionInfo {
                            vaddr: section_header
                                .sh_addr
                                .saturating_add(ebpf::MM_PROGRAM_START),
                            offset_range: section_header.file_range(),
                        });
                    }
                }
                None
            })
            .collect();

        Ok(Self {
            config,
            elf_bytes,
            entrypoint,
            text_section_info,
            ro_section_infos,
            calls,
            syscall_registry: SyscallRegistry::default(),
            compiled_program: None,
        })
    }
/// Fully loads an ELF, including validation and relocation
Fully loads an ELF, including validation and relocation
Fully loads an ELF including validation and relocation
pub fn load(config: Config, bytes: &[u8]) -> Result<Self, ELFError> {
        let elf = Elf::parse(bytes)?;
        let mut elf_bytes = bytes.to_vec();
        Self::validate(&elf, &elf_bytes)?;
        let mut calls = HashMap::default();
        Self::relocate(&elf, &mut elf_bytes, &mut calls)?;
        let text_section = Self::get_section(&elf, ".text")?;
        // calculate entrypoint offset into the text section
        let offset = elf.header.e_entry - text_section.sh_addr;
        if offset % ebpf::INSN_SIZE as u64 != 0 {
            return Err(ELFError::InvalidEntrypoint);
        }
        let entrypoint = offset as usize / ebpf::INSN_SIZE;
        // calculate the text section info
        let text_section_info = SectionInfo {
            vaddr: text_section.sh_addr.saturating_add(ebpf::MM_PROGRAM_START),
            offset_range: text_section.file_range(),
        };
        // calculate the read-only section infos
        let ro_section_infos = elf
            .section_headers
            .iter()
            .filter_map(|section_header| {
                if let Some(Ok(this_name)) = elf.shdr_strtab.get(section_header.sh_name) {
                    if this_name == ".rodata"
                        || this_name == ".data.rel.ro"
                        || this_name == ".eh_frame"
                    {
                        return Some(SectionInfo {
                            vaddr: section_header
                                .sh_addr
                                .saturating_add(ebpf::MM_PROGRAM_START),
                            offset_range: section_header.file_range(),
                        });
                    }
                }
                None
            })
            .collect();
        Ok(Self {
            config,
            elf_bytes,
            entrypoint,
            text_section_info,
            ro_section_infos,
            calls,
            syscall_registry: SyscallRegistry::default(),
            compiled_program: None,
        })
    }
pub fn load ( config : Config , bytes : & [ u8 ] ) -> Result < Self , ELFError > { let elf = Elf :: parse ( bytes ) ? ; let mut elf_bytes = bytes . to_vec ( ) ; Self :: validate ( & elf , & elf_bytes ) ? ; let mut calls = HashMap :: default ( ) ; Self :: relocate ( & elf , & mut elf_bytes , & mut calls ) ? ; let text_section = Self :: get_section ( & elf , " " ) ? ; // calculate entrypoint offset into the text section let offset = elf . header . e_entry - text_section . sh_addr ; if offset % ebpf :: INSN_SIZE as u64 != 0 { return Err ( ELFError :: InvalidEntrypoint ) ; } let entrypoint = offset as usize / ebpf :: INSN_SIZE ; // calculate the text section info let text_section_info = SectionInfo { vaddr : text_section . sh_addr . saturating_add ( ebpf :: MM_PROGRAM_START ) , offset_range : text_section . file_range ( ) , } ; // calculate the read-only section infos let ro_section_infos = elf . section_headers . iter ( ) . filter_map ( | section_header | { if let Some ( Ok ( this_name ) ) = elf . shdr_strtab . get ( section_header . sh_name ) { if this_name == " " || this_name == " " || this_name == " " { return Some ( SectionInfo { vaddr : section_header . sh_addr . saturating_add ( ebpf :: MM_PROGRAM_START ) , offset_range : section_header . file_range ( ) , } ) ; } } None } ) . collect ( ) ; Ok ( Self { config , elf_bytes , entrypoint , text_section_info , ro_section_infos , calls , syscall_registry : SyscallRegistry :: default ( ) , compiled_program : None , } ) }
Fully loads an ELF, including validation and relocation
Fully loads an ELF including validation and relocation
config
Config
bytes
&[u8]