Skip to content

Instantly share code, notes, and snippets.

@alexcrichton
Last active March 3, 2020 18:56
Show Gist options
  • Save alexcrichton/3d9cc6c7daf17763d11126f563aeac9b to your computer and use it in GitHub Desktop.
Save alexcrichton/3d9cc6c7daf17763d11126f563aeac9b to your computer and use it in GitHub Desktop.
diff --git a/src/symbolize/gimli.rs b/src/symbolize/gimli.rs
index 1529a90..6753260 100644
--- a/src/symbolize/gimli.rs
+++ b/src/symbolize/gimli.rs
@@ -154,10 +154,12 @@ cfg_if::cfg_if! {
}
} else if #[cfg(target_os = "macos")] {
use goblin::mach::MachO;
+ use goblin::mach::symbols::Nlist;
struct Object<'a> {
macho: MachO<'a>,
dwarf: Option<usize>,
+ syms: Vec<(&'a str, Nlist)>,
}
impl<'a> Object<'a> {
@@ -171,7 +173,15 @@ cfg_if::cfg_if! {
.enumerate()
.find(|(_, segment)| segment.name().ok() == Some("__DWARF"))
.map(|p| p.0);
- Some(Object { macho, dwarf })
+ let mut syms = Vec::new();
+ if let Some(s) = &macho.symbols {
+ syms = s.iter()
+ .filter_map(|e| e.ok())
+ .filter(|(name, nlist)| name.len() > 0 && !nlist.is_undefined())
+ .collect();
+ }
+ syms.sort_unstable_by_key(|s| s.1.n_value);
+ Some(Object { macho, dwarf, syms })
}
fn section(&self, name: &str) -> Option<&'a [u8]> {
@@ -194,12 +204,13 @@ cfg_if::cfg_if! {
.map(|p| p.1)
}
- fn search_symtab<'b>(&'b self, _addr: u64) -> Option<&'b [u8]> {
- // So far it seems that we don't need to implement this. Maybe
- // `dladdr` on OSX has us covered? Maybe there's not much in the
- // symbol table? In any case our relevant tests are passing
- // without this being implemented, so let's skip it for now.
- None
+ fn search_symtab<'b>(&'b self, addr: u64) -> Option<&'b [u8]> {
+ let i = match self.syms.binary_search_by_key(&addr, |s| s.1.n_value) {
+ Ok(i) => i,
+ Err(i) => i.checked_sub(1)?,
+ };
+ let (sym, _nlist) = self.syms.get(i)?;
+ Some(sym.as_bytes())
}
}
} else {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment