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
每月 218 次下载
用于 user-mode-riscv
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 个其他文件。
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