Skip to content

Commit 6b9c844

Browse files
committed
Add symbol stripper binary
This will be used to take the kernel symbols and append it as payload to the kernel itself. That way the kernel will have the complete amount of information it needs to perform symbolication.
1 parent 54c4d18 commit 6b9c844

File tree

5 files changed

+165
-1
lines changed

5 files changed

+165
-1
lines changed

Cargo.lock

+62
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
members = [
44
"p1c0_kernel",
55
"p1c0_macros",
6-
"test_fwk"
6+
"test_fwk",
7+
"stripper"
78
]
89

910
exclude = [

stripper/Cargo.toml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "stripper"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
structopt = "0.3.26"
10+
anyhow = "1.0.56"
11+
object = "0.28"
12+
rustc-demangle = "0.1.21"

stripper/src/lib.rs

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use object::{
2+
elf, endian, read::elf::ElfFile, Object, ObjectSymbol, ObjectSymbolTable, SymbolKind,
3+
};
4+
use rustc_demangle::demangle;
5+
6+
struct Symbol {
7+
address: u64,
8+
size: u64,
9+
name_offset: u32,
10+
name_length: u32,
11+
}
12+
13+
pub fn symbols_from_elf_file(
14+
elf: &ElfFile<elf::FileHeader64<endian::LittleEndian>>,
15+
symbol_file: &mut impl std::io::Write,
16+
) -> anyhow::Result<()> {
17+
let mut symbols = vec![];
18+
let mut string_table: Vec<u8> = vec![];
19+
20+
if let Some(symbol_table) = elf.symbol_table() {
21+
symbol_table
22+
.symbols()
23+
.filter(|symbol| symbol.kind() == SymbolKind::Text)
24+
.for_each(|symbol| {
25+
if let Ok(name) = symbol.name() {
26+
let name = demangle(name).to_string();
27+
28+
let name_offset = string_table.len() as u32;
29+
let name_length = name.bytes().len() as u32;
30+
31+
name.bytes().for_each(|byte| string_table.push(byte));
32+
33+
symbols.push(Symbol {
34+
address: symbol.address(),
35+
size: symbol.size(),
36+
name_offset,
37+
name_length,
38+
});
39+
} else {
40+
panic!("Symbol has invalid name!");
41+
}
42+
});
43+
}
44+
45+
const MAGIC_BYTES: [u8; 4] = *b"Smbl";
46+
const SYMBOL_TABLE_OFFSET: u32 = 0x14;
47+
const SYMBOL_ENTRY_SIZE: u32 = 0x18;
48+
49+
let num_symbols = symbols.len() as u32;
50+
let string_table_offset = SYMBOL_TABLE_OFFSET + num_symbols * SYMBOL_ENTRY_SIZE;
51+
let filesize = string_table_offset + string_table.len() as u32;
52+
53+
symbol_file.write_all(&MAGIC_BYTES)?;
54+
symbol_file.write_all(&u32::to_le_bytes(filesize))?;
55+
symbol_file.write_all(&u32::to_le_bytes(symbols.len() as u32))?;
56+
symbol_file.write_all(&u32::to_le_bytes(SYMBOL_TABLE_OFFSET))?;
57+
symbol_file.write_all(&u32::to_le_bytes(string_table_offset))?;
58+
59+
for symbol in symbols {
60+
symbol_file.write_all(&u32::to_le_bytes(symbol.name_offset))?;
61+
symbol_file.write_all(&u32::to_le_bytes(symbol.name_length))?;
62+
symbol_file.write_all(&u64::to_le_bytes(symbol.address))?;
63+
symbol_file.write_all(&u64::to_le_bytes(symbol.size))?;
64+
}
65+
66+
symbol_file.write_all(&string_table[..])?;
67+
68+
Ok(())
69+
}

stripper/src/main.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use std::fs;
2+
3+
use object::read::elf::ElfFile;
4+
use structopt::StructOpt;
5+
6+
#[derive(StructOpt, Debug)]
7+
struct Options {
8+
elf_file: std::path::PathBuf,
9+
symbol_file: std::path::PathBuf,
10+
}
11+
12+
fn main() -> anyhow::Result<()> {
13+
let options = Options::from_args();
14+
15+
let elf_file = fs::read(options.elf_file)?;
16+
let elf_file = ElfFile::parse(&elf_file[..])?;
17+
let mut symbol_file = fs::File::create(options.symbol_file)?;
18+
19+
stripper::symbols_from_elf_file(&elf_file, &mut symbol_file)
20+
}

0 commit comments

Comments
 (0)