Warn if the file was modified more recently than the elf file

This commit is contained in:
Gwilym Inzani 2024-04-01 16:41:05 +01:00
parent 4b0622f6fb
commit fc6e1d5e09

View file

@ -3,6 +3,7 @@ use std::{
fs::{self, File}, fs::{self, File},
io::Read, io::Read,
path::PathBuf, path::PathBuf,
time::SystemTime,
}; };
use addr2line::{gimli, object}; use addr2line::{gimli, object};
@ -38,7 +39,11 @@ impl Default for Location {
fn main() -> anyhow::Result<()> { fn main() -> anyhow::Result<()> {
let cli = Args::parse(); let cli = Args::parse();
let file = fs::read(cli.elf_path)?; let modification_time = fs::metadata(&cli.elf_path)?
.modified()
.unwrap_or(SystemTime::UNIX_EPOCH);
let file = fs::read(&cli.elf_path)?;
let object = object::File::parse(file.as_slice())?; let object = object::File::parse(file.as_slice())?;
let ctx = addr2line::Context::new(&object)?; let ctx = addr2line::Context::new(&object)?;
@ -49,7 +54,7 @@ fn main() -> anyhow::Result<()> {
address += 0x0800_0000; address += 0x0800_0000;
} }
print_address(&ctx, i, address)?; print_address(&ctx, i, address, modification_time)?;
} }
Ok(()) Ok(())
@ -59,6 +64,7 @@ fn print_address(
ctx: &addr2line::Context<impl gimli::Reader>, ctx: &addr2line::Context<impl gimli::Reader>,
index: usize, index: usize,
address: u64, address: u64,
elf_modification_time: SystemTime,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let mut frames = ctx.find_frames(address).skip_all_loads()?; let mut frames = ctx.find_frames(address).skip_all_loads()?;
@ -101,7 +107,7 @@ fn print_address(
); );
if location.line != 0 && is_interesting { if location.line != 0 && is_interesting {
print_line_of_code(&frame, location)?; print_line_of_code(&frame, location, elf_modification_time)?;
} }
is_first = false; is_first = false;
@ -113,6 +119,7 @@ fn print_address(
fn print_line_of_code( fn print_line_of_code(
frame: &addr2line::Frame<'_, impl gimli::Reader>, frame: &addr2line::Frame<'_, impl gimli::Reader>,
location: Location, location: Location,
elf_modification_time: SystemTime,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let Some(filename) = frame.location.as_ref().and_then(|location| location.file) else { let Some(filename) = frame.location.as_ref().and_then(|location| location.file) else {
return Ok(()); return Ok(());
@ -122,6 +129,14 @@ fn print_line_of_code(
return Ok(()); return Ok(());
}; };
let modification_time = fs::metadata(filename)?
.modified()
.unwrap_or(SystemTime::UNIX_EPOCH);
if modification_time > elf_modification_time {
eprintln!("Warning: File {filename} modified more recently than the binary, line info may be incorrect");
}
let mut content = String::new(); let mut content = String::new();
file.read_to_string(&mut content)?; file.read_to_string(&mut content)?;