|
@@ -1,6 +1,6 @@
|
|
//! User space probes.
|
|
//! User space probes.
|
|
use libc::pid_t;
|
|
use libc::pid_t;
|
|
-use object::{Object, ObjectSymbol};
|
|
|
|
|
|
+use object::{Object, ObjectSection, ObjectSymbol};
|
|
use std::{
|
|
use std::{
|
|
error::Error,
|
|
error::Error,
|
|
ffi::CStr,
|
|
ffi::CStr,
|
|
@@ -319,15 +319,41 @@ enum ResolveSymbolError {
|
|
|
|
|
|
#[error("unknown symbol `{0}`")]
|
|
#[error("unknown symbol `{0}`")]
|
|
Unknown(String),
|
|
Unknown(String),
|
|
|
|
+
|
|
|
|
+ #[error("symbol `{0}` does not appear in section")]
|
|
|
|
+ NotInSection(String),
|
|
|
|
+
|
|
|
|
+ #[error("symbol `{0}` in section `{1:?}` which has no offset")]
|
|
|
|
+ SectionFileRangeNone(String, Result<String, object::Error>),
|
|
}
|
|
}
|
|
|
|
|
|
fn resolve_symbol(path: &str, symbol: &str) -> Result<u64, ResolveSymbolError> {
|
|
fn resolve_symbol(path: &str, symbol: &str) -> Result<u64, ResolveSymbolError> {
|
|
let data = fs::read(path)?;
|
|
let data = fs::read(path)?;
|
|
let obj = object::read::File::parse(&*data)?;
|
|
let obj = object::read::File::parse(&*data)?;
|
|
|
|
|
|
- obj.dynamic_symbols()
|
|
|
|
|
|
+ let sym = obj
|
|
|
|
+ .dynamic_symbols()
|
|
.chain(obj.symbols())
|
|
.chain(obj.symbols())
|
|
.find(|sym| sym.name().map(|name| name == symbol).unwrap_or(false))
|
|
.find(|sym| sym.name().map(|name| name == symbol).unwrap_or(false))
|
|
- .map(|s| s.address())
|
|
|
|
- .ok_or_else(|| ResolveSymbolError::Unknown(symbol.to_string()))
|
|
|
|
|
|
+ .ok_or_else(|| ResolveSymbolError::Unknown(symbol.to_string()))?;
|
|
|
|
+
|
|
|
|
+ let needs_addr_translation = matches!(
|
|
|
|
+ obj.kind(),
|
|
|
|
+ object::ObjectKind::Dynamic | object::ObjectKind::Executable
|
|
|
|
+ );
|
|
|
|
+ if !needs_addr_translation {
|
|
|
|
+ Ok(sym.address())
|
|
|
|
+ } else {
|
|
|
|
+ let index = sym
|
|
|
|
+ .section_index()
|
|
|
|
+ .ok_or_else(|| ResolveSymbolError::NotInSection(symbol.to_string()))?;
|
|
|
|
+ let section = obj.section_by_index(index)?;
|
|
|
|
+ let (offset, _size) = section.file_range().ok_or_else(|| {
|
|
|
|
+ ResolveSymbolError::SectionFileRangeNone(
|
|
|
|
+ symbol.to_string(),
|
|
|
|
+ section.name().map(str::to_owned),
|
|
|
|
+ )
|
|
|
|
+ })?;
|
|
|
|
+ Ok(sym.address() - section.address() + offset)
|
|
|
|
+ }
|
|
}
|
|
}
|