Merge pull request #1914 from peterhuene/fix-musl-unwind
Register individual FDEs for musl libc.
This commit is contained in:
@@ -90,8 +90,10 @@ impl UnwindRegistry {
|
|||||||
let mut eh_frame = EhFrame(EndianVec::new(RunTimeEndian::default()));
|
let mut eh_frame = EhFrame(EndianVec::new(RunTimeEndian::default()));
|
||||||
table.write_eh_frame(&mut eh_frame).unwrap();
|
table.write_eh_frame(&mut eh_frame).unwrap();
|
||||||
|
|
||||||
// GCC expects a terminating "empty" length, so write a 0 length at the end of the table.
|
if cfg!(all(target_os = "linux", target_env = "gnu")) {
|
||||||
eh_frame.0.write_u32(0).unwrap();
|
// libgcc expects a terminating "empty" length, so write a 0 length at the end of the table.
|
||||||
|
eh_frame.0.write_u32(0).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
self.frame_table = eh_frame.0.into_vec();
|
self.frame_table = eh_frame.0.into_vec();
|
||||||
|
|
||||||
@@ -99,31 +101,29 @@ impl UnwindRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn register_frames(&mut self) {
|
unsafe fn register_frames(&mut self) {
|
||||||
cfg_if::cfg_if! {
|
if cfg!(all(target_os = "linux", target_env = "gnu")) {
|
||||||
if #[cfg(target_os = "macos")] {
|
// On gnu (libgcc), `__register_frame` will walk the FDEs until an entry of length 0
|
||||||
// On macOS, `__register_frame` takes a pointer to a single FDE
|
let ptr = self.frame_table.as_ptr();
|
||||||
let start = self.frame_table.as_ptr();
|
__register_frame(ptr);
|
||||||
let end = start.add(self.frame_table.len());
|
self.registrations.push(ptr as usize);
|
||||||
let mut current = start;
|
} else {
|
||||||
|
// For libunwind, `__register_frame` takes a pointer to a single FDE
|
||||||
|
let start = self.frame_table.as_ptr();
|
||||||
|
let end = start.add(self.frame_table.len());
|
||||||
|
let mut current = start;
|
||||||
|
|
||||||
// Walk all of the entries in the frame table and register them
|
// Walk all of the entries in the frame table and register them
|
||||||
while current < end {
|
while current < end {
|
||||||
let len = std::ptr::read::<u32>(current as *const u32) as usize;
|
let len = std::ptr::read::<u32>(current as *const u32) as usize;
|
||||||
|
|
||||||
// Skip over the CIE
|
// Skip over the CIE
|
||||||
if current != start {
|
if current != start {
|
||||||
__register_frame(current);
|
__register_frame(current);
|
||||||
self.registrations.push(current as usize);
|
self.registrations.push(current as usize);
|
||||||
}
|
|
||||||
|
|
||||||
// Move to the next table entry (+4 because the length itself is not inclusive)
|
|
||||||
current = current.add(len + 4);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// On other platforms, `__register_frame` will walk the FDEs until an entry of length 0
|
// Move to the next table entry (+4 because the length itself is not inclusive)
|
||||||
let ptr = self.frame_table.as_ptr();
|
current = current.add(len + 4);
|
||||||
__register_frame(ptr);
|
|
||||||
self.registrations.push(ptr as usize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user