13 个版本 (8 个破坏性更新)

0.16.0 2022 年 8 月 24 日
0.15.0 2022 年 3 月 19 日
0.14.0 2021 年 6 月 24 日
0.11.0 2020 年 10 月 22 日
0.0.1 2015 年 7 月 5 日

#287 in Unix APIs

Download history 79/week @ 2024-03-11 46/week @ 2024-03-18 41/week @ 2024-03-25 91/week @ 2024-04-01 24/week @ 2024-04-08 31/week @ 2024-04-15 29/week @ 2024-04-22 9/week @ 2024-04-29 26/week @ 2024-05-06 37/week @ 2024-05-13 41/week @ 2024-05-20 63/week @ 2024-05-27 93/week @ 2024-06-03 40/week @ 2024-06-10 21/week @ 2024-06-17 59/week @ 2024-06-24

每月 218 次下载
用于 user-mode-riscv

MIT/Apache 许可协议

60KB
1K SLoC

包含 (ELF 可执行文件/库, 16KB) test/tls.x86,(ELF 可执行文件/库, 9KB) test/test.aarch64,(ELF 可执行文件/库, 16KB) test/test.x86,(ELF 可执行文件/库, 9KB) test/test.x86_64,(ELF 可执行文件/库, 9KB) test/test_nopie.aarch64,(ELF 可执行文件/库, 16KB) test/test_nopie.x86 以及 3 个其他文件。

Build cargo-badge docs-badge

elfloader

一个用于在内存中加载和重定位 ELF 文件的库。此库只依赖于 libcore,因此可以用于内核级代码,例如加载用户空间程序。

如何使用

客户端必须实现 ElfLoader 特性

use elfloader::*;
use log::info;

/// A simple ExampleLoader, that implements ElfLoader
/// but does nothing but logging
struct ExampleLoader {
    vbase: u64,
}

impl ElfLoader for ExampleLoader {
    fn allocate(&mut self, load_headers: LoadableHeaders) -> Result<(), ElfLoaderErr> {
        for header in load_headers {
            info!(
                "allocate base = {:#x} size = {:#x} flags = {}",
                header.virtual_addr(),
                header.mem_size(),
                header.flags()
            );
        }
        Ok(())
    }

    fn relocate(&mut self, entry: RelocationEntry) -> Result<(), ElfLoaderErr> {
        use RelocationType::x86_64;
        use crate::arch::x86_64::RelocationTypes::*;

        let addr: *mut u64 = (self.vbase + entry.offset) as *mut u64;

        match entry.rtype {
            x86_64(R_AMD64_RELATIVE) => {

                // This type requires addend to be present
                let addend = entry
                    .addend
                    .ok_or(ElfLoaderErr::UnsupportedRelocationEntry)?;

                // This is a relative relocation, add the offset (where we put our
                // binary in the vspace) to the addend and we're done.
                info!(
                    "R_RELATIVE *{:p} = {:#x}",
                    addr,
                    self.vbase + addend
                );
                Ok(())
            }
            _ => Ok((/* not implemented */)),
        }
    }

    fn load(&mut self, flags: Flags, base: VAddr, region: &[u8]) -> Result<(), ElfLoaderErr> {
        let start = self.vbase + base;
        let end = self.vbase + base + region.len() as u64;
        info!("load region into = {:#x} -- {:#x}", start, end);
        Ok(())
    }

    fn tls(
        &mut self,
        tdata_start: VAddr,
        _tdata_length: u64,
        total_size: u64,
        _align: u64
    ) -> Result<(), ElfLoaderErr> {
        let tls_end = tdata_start +  total_size;
        info!("Initial TLS region is at = {:#x} -- {:#x}", tdata_start, tls_end);
        Ok(())
    }

}

// Then, with ElfBinary, a ELF file is loaded using `load`:
fn main() {
    use std::fs;

    let binary_blob = fs::read("test/test.x86_64").expect("Can't read binary");
    let binary = ElfBinary::new(binary_blob.as_slice()).expect("Got proper ELF file");
    let mut loader = ExampleLoader { vbase: 0x1000_0000 };
    binary.load(&mut loader).expect("Can't load the binary?");
}

依赖项

~195–265KB