Skip to content

Commit 71fcbc2

Browse files
committed
elf: supplementary object file support
1 parent 1f48036 commit 71fcbc2

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

src/symbolize/gimli.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct Mapping {
5858
// 'static lifetime is a lie to hack around lack of support for self-referential structs.
5959
cx: Context<'static>,
6060
_map: Mmap,
61+
_map_sup: Option<Mmap>,
6162
_stash: Stash,
6263
}
6364

@@ -74,6 +75,7 @@ impl Mapping {
7475
// only borrow `map` and `stash` and we're preserving them below.
7576
cx: unsafe { core::mem::transmute::<Context<'_>, Context<'static>>(cx) },
7677
_map: data,
78+
_map_sup: None,
7779
_stash: stash,
7880
})
7981
}
@@ -95,6 +97,26 @@ impl<'data> Context<'data> {
9597

9698
Some(Context { dwarf, object })
9799
}
100+
101+
fn new_sup(
102+
stash: &'data Stash,
103+
object: Object<'data>,
104+
sup: Object<'data>,
105+
) -> Option<Context<'data>> {
106+
let mut sections = gimli::Dwarf::load(|id| -> Result<_, ()> {
107+
let data = object.section(stash, id.name()).unwrap_or(&[]);
108+
Ok(EndianSlice::new(data, Endian))
109+
})
110+
.ok()?;
111+
sections
112+
.load_sup(|id| -> Result<_, ()> {
113+
let data = sup.section(stash, id.name()).unwrap_or(&[]);
114+
Ok(EndianSlice::new(data, Endian))
115+
})
116+
.ok()?;
117+
let dwarf = addr2line::Context::from_dwarf(sections).ok()?;
118+
Some(Context { dwarf, object })
119+
}
98120
}
99121

100122
fn mmap(path: &Path) -> Option<Mmap> {

src/symbolize/gimli/elf.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ impl Mapping {
7777
// only borrow `map` and `stash` and we're preserving them below.
7878
cx: unsafe { core::mem::transmute::<Context<'_>, Context<'static>>(cx) },
7979
_map: map,
80+
_map_sup: None,
8081
_stash: stash,
8182
})
8283
}
@@ -90,13 +91,44 @@ impl Mapping {
9091
// TODO: check crc
9192
}
9293

94+
// Try to locate a supplementary object file.
95+
let tmp_stash = Stash::new();
96+
if let Some(section) = object.section(&tmp_stash, ".gnu_debugaltlink") {
97+
if let Some(len) = section.iter().position(|x| *x == 0) {
98+
let filename = &section[..len];
99+
let build_id_sup = &section[len + 1..];
100+
if let Some(path_sup) = locate_debuglink(path, filename) {
101+
if let Some(map_sup) = super::mmap(&path_sup) {
102+
if let Some(sup) = Object::parse(&map_sup) {
103+
if sup.build_id() == Some(build_id_sup) {
104+
let stash = Stash::new();
105+
let cx = Context::new_sup(&stash, object, sup)?;
106+
return Some(Mapping {
107+
// Convert to 'static lifetimes since the symbols should
108+
// only borrow `map`, `map_sup`, and `stash` and we're
109+
// preserving them below.
110+
cx: unsafe {
111+
core::mem::transmute::<Context<'_>, Context<'static>>(cx)
112+
},
113+
_map: map,
114+
_map_sup: Some(map_sup),
115+
_stash: stash,
116+
});
117+
}
118+
}
119+
}
120+
}
121+
}
122+
}
123+
93124
let stash = Stash::new();
94125
let cx = Context::new(&stash, object)?;
95126
Some(Mapping {
96127
// Convert to 'static lifetimes since the symbols should
97128
// only borrow `map` and `stash` and we're preserving them below.
98129
cx: unsafe { core::mem::transmute::<Context<'_>, Context<'static>>(cx) },
99130
_map: map,
131+
_map_sup: None,
100132
_stash: stash,
101133
})
102134
}

0 commit comments

Comments
 (0)