pub fn load_elf(&mut self, filename: &Path, base_address: u64) -> Result<()> {
        let path = self
            .ld_paths
            .as_ref()
            .map(|ld_paths| {
                ld_paths
                    .iter()
                    .map(|ld_path| {
                        let filename = if filename.starts_with("/") {
                            let filename = filename.to_str().unwrap();
                            Path::new(filename.split_at(1).1)
                        } else {
                            filename
                        };
                        ld_path.to_path_buf().join(filename)
                    })
                    .find(|path| path.exists())
                    .unwrap_or_else(|| filename.to_path_buf())
            })
            .unwrap_or_else(|| filename.to_path_buf());

        let elf = Elf::from_file_with_base_address(&path, base_address)?;

        // Update our memory map based on what's in the Elf
        for (address, section) in elf.memory()?.sections() {
            self.memory
                .set_memory(*address, section.data().to_owned(), section.permissions());
        }

        // Add this Elf to the loaded Elfs
        let filename = filename.file_name().unwrap().to_str().unwrap().to_string();
        self.loaded.insert(filename.clone(), elf);

        {
            let elf = &self.loaded[&filename];

            // Add its exported symbols to our symbols
            for symbol in elf.exported_symbols() {
                if self.symbols.get(symbol.name()).is_some() {
                    continue;
                }
                self.symbols.insert(
                    symbol.name().to_string(),
                    elf.base_address() + symbol.address(),
                );
            }
        }

        if self.just_interpreter {
            let interpreter_filename = self.loaded[&filename]
                .elf()
                .interpreter
                .map(|s| s.to_string());
            if let Some(interpreter_filename) = interpreter_filename {
                self.load_elf(Path::new(&interpreter_filename), DEFAULT_LIB_BASE)?;
            }
        } else {
            // Ensure all shared objects we rely on are loaded
            for so_name in self.loaded[&filename].dt_needed()?.clone() {
                if self.loaded.get(&so_name).is_none() {
                    self.next_lib_address += LIB_BASE_STEP;
                    let next_lib_address = self.next_lib_address;
                    self.load_elf(Path::new(&so_name), next_lib_address)?;
                }
            }
        }

        if self.do_relocations {
            match self.loaded[&filename].elf().header.e_machine {
                goblin::elf::header::EM_386 => self.relocations_x86(&filename)?,
                goblin::elf::header::EM_MIPS => self.relocations_mips(&filename)?,
                _ => bail!("relocations unsupported for target architecture"),
            }
        }

        Ok(())
    }
/// Takes the path to an Elf, and a base address the Elf should be loaded
/// at. Loads the Elf, all it's dependencies (DT_NEEDED), and then handles
/// the supported relocations.
Takes the path to an Elf, and a base address the Elf should be loaded
at. Loads the Elf, all it's dependencies (DT_NEEDED), and then handles
the supported relocations.
Takes the path to an Elf and a base address the Elf should be loaded at . Loads the Elf all it ' s dependencies ( DT_NEEDED ) and then handles the supported relocations .
pub fn load_elf(&mut self, filename: &Path, base_address: u64) -> Result<()> {
        let path = self
            .ld_paths
            .as_ref()
            .map(|ld_paths| {
                ld_paths
                    .iter()
                    .map(|ld_path| {
                        let filename = if filename.starts_with("/") {
                            let filename = filename.to_str().unwrap();
                            Path::new(filename.split_at(1).1)
                        } else {
                            filename
                        };
                        ld_path.to_path_buf().join(filename)
                    })
                    .find(|path| path.exists())
                    .unwrap_or_else(|| filename.to_path_buf())
            })
            .unwrap_or_else(|| filename.to_path_buf());
        let elf = Elf::from_file_with_base_address(&path, base_address)?;
        // Update our memory map based on what's in the Elf
        for (address, section) in elf.memory()?.sections() {
            self.memory
                .set_memory(*address, section.data().to_owned(), section.permissions());
        }
        // Add this Elf to the loaded Elfs
        let filename = filename.file_name().unwrap().to_str().unwrap().to_string();
        self.loaded.insert(filename.clone(), elf);
        {
            let elf = &self.loaded[&filename];
            // Add its exported symbols to our symbols
            for symbol in elf.exported_symbols() {
                if self.symbols.get(symbol.name()).is_some() {
                    continue;
                }
                self.symbols.insert(
                    symbol.name().to_string(),
                    elf.base_address() + symbol.address(),
                );
            }
        }
        if self.just_interpreter {
            let interpreter_filename = self.loaded[&filename]
                .elf()
                .interpreter
                .map(|s| s.to_string());
            if let Some(interpreter_filename) = interpreter_filename {
                self.load_elf(Path::new(&interpreter_filename), DEFAULT_LIB_BASE)?;
            }
        } else {
            // Ensure all shared objects we rely on are loaded
            for so_name in self.loaded[&filename].dt_needed()?.clone() {
                if self.loaded.get(&so_name).is_none() {
                    self.next_lib_address += LIB_BASE_STEP;
                    let next_lib_address = self.next_lib_address;
                    self.load_elf(Path::new(&so_name), next_lib_address)?;
                }
            }
        }
        if self.do_relocations {
            match self.loaded[&filename].elf().header.e_machine {
                goblin::elf::header::EM_386 => self.relocations_x86(&filename)?,
                goblin::elf::header::EM_MIPS => self.relocations_mips(&filename)?,
                _ => bail!("relocations unsupported for target architecture"),
            }
        }
        Ok(())
    }
pub fn load_elf ( & mut self , filename : & Path , base_address : u64 ) -> Result < ( ) > { let path = self . ld_paths . as_ref ( ) . map ( | ld_paths | { ld_paths . iter ( ) . map ( | ld_path | { let filename = if filename . starts_with ( " " ) { let filename = filename . to_str ( ) . unwrap ( ) ; Path :: new ( filename . split_at ( 1 ) . 1 ) } else { filename } ; ld_path . to_path_buf ( ) . join ( filename ) } ) . find ( | path | path . exists ( ) ) . unwrap_or_else ( | | filename . to_path_buf ( ) ) } ) . unwrap_or_else ( | | filename . to_path_buf ( ) ) ; let elf = Elf :: from_file_with_base_address ( & path , base_address ) ? ; // Update our memory map based on what's in the Elf for ( address , section ) in elf . memory ( ) ? . sections ( ) { self . memory . set_memory ( * address , section . data ( ) . to_owned ( ) , section . permissions ( ) ) ; } // Add this Elf to the loaded Elfs let filename = filename . file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_string ( ) ; self . loaded . insert ( filename . clone ( ) , elf ) ; { let elf = & self . loaded [ & filename ] ; // Add its exported symbols to our symbols for symbol in elf . exported_symbols ( ) { if self . symbols . get ( symbol . name ( ) ) . is_some ( ) { continue ; } self . symbols . insert ( symbol . name ( ) . to_string ( ) , elf . base_address ( ) + symbol . address ( ) , ) ; } } if self . just_interpreter { let interpreter_filename = self . loaded [ & filename ] . elf ( ) . interpreter . map ( | s | s . to_string ( ) ) ; if let Some ( interpreter_filename ) = interpreter_filename { self . load_elf ( Path :: new ( & interpreter_filename ) , DEFAULT_LIB_BASE ) ? ; } } else { // Ensure all shared objects we rely on are loaded for so_name in self . loaded [ & filename ] . dt_needed ( ) ? . clone ( ) { if self . loaded . get ( & so_name ) . is_none ( ) { self . next_lib_address += LIB_BASE_STEP ; let next_lib_address = self . next_lib_address ; self . load_elf ( Path :: new ( & so_name ) , next_lib_address ) ? ; } } } if self . do_relocations { match self . loaded [ & filename ] . elf ( ) . header . e_machine { goblin :: elf :: header :: EM_386 => self . relocations_x86 ( & filename ) ? , goblin :: elf :: header :: EM_MIPS => self . relocations_mips ( & filename ) ? , _ => bail ! ( " " ) , } } Ok ( ( ) ) }
Takes the path to an Elf, and a base address the Elf should be loaded
at.
Takes the path to an Elf and a base address the Elf should be loaded at .
&mut self
filename
&Path
base_address
u64
&mut self
filename
&Path
base_address
u64