Add debug infos on panic
This commit is contained in:
2
build-tools/.cargo/config.toml
Normal file
2
build-tools/.cargo/config.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[build]
|
||||
target = "x86_64-unknown-linux-gnu"
|
||||
14
build-tools/Cargo.toml
Normal file
14
build-tools/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "build-tools"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[[bin]]
|
||||
name = "gen-symbols"
|
||||
path = "src/gen_symbols.rs"
|
||||
|
||||
[dependencies]
|
||||
rayon = "1.11"
|
||||
object = "0.32"
|
||||
addr2line = "0.21"
|
||||
rustc-demangle = "0.1"
|
||||
128
build-tools/src/gen_symbols.rs
Normal file
128
build-tools/src/gen_symbols.rs
Normal file
@@ -0,0 +1,128 @@
|
||||
use addr2line::Context;
|
||||
use object::{Object, ObjectSymbol, SymbolKind};
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::path::Path;
|
||||
|
||||
#[repr(C, packed(4))]
|
||||
#[derive(Debug)]
|
||||
struct RawSymbol {
|
||||
addr: u64,
|
||||
line: u32,
|
||||
name_off: u32,
|
||||
file_off: u32,
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let elf_path = "../target/riscv64/debug/kernel-rust";
|
||||
let bin_data = std::fs::read(elf_path)?;
|
||||
let obj_file = object::File::parse(&*bin_data)?;
|
||||
|
||||
let context = Context::new(&obj_file)?;
|
||||
|
||||
let mut symbols_list = Vec::new();
|
||||
let mut string_table = Vec::new();
|
||||
let mut str_cache = HashMap::new();
|
||||
|
||||
// Helper pour gérer la table des chaînes (String Table)
|
||||
let mut add_string = |s: &str| -> u32 {
|
||||
*str_cache.entry(s.to_string()).or_insert_with(|| {
|
||||
let off = string_table.len() as u32;
|
||||
string_table.extend_from_slice(s.as_bytes());
|
||||
string_table.push(0); // Null terminator
|
||||
off
|
||||
})
|
||||
};
|
||||
|
||||
println!("Extraction des symboles depuis {}...", elf_path);
|
||||
|
||||
obj_file.symbols().enumerate().for_each(|(i, sym)| {
|
||||
// On ne garde que les fonctions (Text)
|
||||
if sym.kind() == SymbolKind::Text && sym.size() > 0 {
|
||||
let addr = sym.address();
|
||||
let raw_name = sym.name().unwrap_or("unknown");
|
||||
let name = format!("{:#}", rustc_demangle::demangle(raw_name));
|
||||
|
||||
let mut frames = context.find_frames(addr).skip_all_loads().unwrap();
|
||||
|
||||
let (file, line) = if let Ok(Some(frame)) = frames.next() {
|
||||
let f = frame
|
||||
.location
|
||||
.as_ref()
|
||||
.and_then(|l| {
|
||||
l.file.and_then(|file| {
|
||||
Path::new(file)
|
||||
.strip_prefix(std::env::current_dir().unwrap().parent().unwrap())
|
||||
.map_or(Some(file), |p| p.to_str())
|
||||
})
|
||||
})
|
||||
.unwrap_or("unknown");
|
||||
let l = frame.location.as_ref().and_then(|l| l.line).unwrap_or(0);
|
||||
(f, l)
|
||||
} else {
|
||||
("unknown", 0)
|
||||
};
|
||||
|
||||
symbols_list.push(RawSymbol {
|
||||
addr,
|
||||
line,
|
||||
name_off: add_string(&name),
|
||||
file_off: add_string(file),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Tri par adresse pour la recherche binaire au runtime
|
||||
symbols_list.sort_by_key(|s| s.addr);
|
||||
|
||||
let idx = match symbols_list.binary_search_by_key(&(0x000000008004073c), |s| s.addr) {
|
||||
Ok(i) => i,
|
||||
Err(i) if i > 0 => i - 1,
|
||||
_ => panic!(),
|
||||
};
|
||||
|
||||
println!("{:?}", unsafe {
|
||||
get_str(
|
||||
string_table
|
||||
.as_ptr()
|
||||
.add(symbols_list[idx].name_off as usize),
|
||||
)
|
||||
});
|
||||
|
||||
// Écriture du fichier symbols.bin
|
||||
let mut f = BufWriter::new(File::create("../target/symbols.bin")?);
|
||||
|
||||
// Header : [u64: count] [u64: string_table_offset]
|
||||
let header_size = 16;
|
||||
let sym_table_size = symbols_list.len() * std::mem::size_of::<RawSymbol>();
|
||||
f.write_all(&(symbols_list.len() as u64).to_le_bytes())?;
|
||||
f.write_all(&((header_size + sym_table_size) as u64).to_le_bytes())?;
|
||||
|
||||
// Table des symboles
|
||||
for sym in &symbols_list {
|
||||
unsafe {
|
||||
let bytes = std::slice::from_raw_parts(
|
||||
(sym as *const RawSymbol) as *const u8,
|
||||
std::mem::size_of::<RawSymbol>(),
|
||||
);
|
||||
f.write_all(bytes)?;
|
||||
}
|
||||
}
|
||||
|
||||
// Table des noms
|
||||
f.write_all(&string_table)?;
|
||||
|
||||
println!(
|
||||
"Terminé ! {} symboles écrits dans symbols.bin",
|
||||
symbols_list.len()
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
unsafe fn get_str(ptr: *const u8) -> &'static str {
|
||||
let mut len = 0;
|
||||
while *ptr.add(len) != 0 {
|
||||
len += 1;
|
||||
}
|
||||
core::str::from_utf8_unchecked(core::slice::from_raw_parts(ptr, len))
|
||||
}
|
||||
Reference in New Issue
Block a user