Skip to content

Commit

Permalink
Try #1583:
Browse files Browse the repository at this point in the history
  • Loading branch information
bors[bot] authored Sep 1, 2020
2 parents 92e028f + 4376e30 commit 6fa3a43
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 48 deletions.
15 changes: 7 additions & 8 deletions lib/engine-jit/src/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::link::link_module;
#[cfg(feature = "compiler")]
use crate::serialize::SerializableCompilation;
use crate::serialize::SerializableModule;
use crate::unwind::UnwindRegistry;
use crate::unwind::{UnwindRegistry, UnwindRegistryExt};
use std::sync::{Arc, Mutex};
use wasmer_compiler::{CompileError, Features, Triple};
#[cfg(feature = "compiler")]
Expand Down Expand Up @@ -135,10 +135,6 @@ impl JITArtifact {
}

let inner_bytes = &bytes[Self::MAGIC_HEADER.len()..];

// let r = flexbuffers::Reader::get_root(bytes).map_err(|e| DeserializeError::CorruptedBinary(format!("{:?}", e)))?;
// let serializable = SerializableModule::deserialize(r).map_err(|e| DeserializeError::CorruptedBinary(format!("{:?}", e)))?;

let serializable: SerializableModule = bincode::deserialize(inner_bytes)
.map_err(|e| DeserializeError::CorruptedBinary(format!("{:?}", e)))?;

Expand Down Expand Up @@ -193,9 +189,12 @@ impl JITArtifact {
.bytes
.len();
let eh_frame_section_pointer = custom_sections[debug.eh_frame];
Some(unsafe {
std::slice::from_raw_parts(eh_frame_section_pointer, eh_frame_section_size)
})
Some(
unsafe {
std::slice::from_raw_parts(eh_frame_section_pointer, eh_frame_section_size)
}
.to_vec(),
)
}
None => None,
};
Expand Down
2 changes: 1 addition & 1 deletion lib/engine-jit/src/code_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Attributions: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md

//! Memory management for executable code.
use crate::unwind::UnwindRegistry;
use crate::unwind::{UnwindRegistry, UnwindRegistryExt};
use std::mem::ManuallyDrop;
use std::sync::Arc;
use std::{cmp, mem};
Expand Down
5 changes: 4 additions & 1 deletion lib/engine-jit/src/unwind/dummy.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Module for Dummy unwind registry.
use crate::unwind::UnwindRegistryExt;
use wasmer_compiler::CompiledFunctionUnwindInfo;

/// Represents a registry of function unwind information when the host system
Expand All @@ -11,7 +12,9 @@ impl DummyUnwindRegistry {
pub fn new() -> Self {
DummyUnwindRegistry {}
}
}

impl UnwindRegistryExt for DummyUnwindRegistry {
/// Registers a function given the start offset, length, and unwind information.
pub fn register(
&mut self,
Expand All @@ -25,7 +28,7 @@ impl DummyUnwindRegistry {
}

/// Publishes all registered functions.
pub fn publish(&mut self, eh_frame: Option<&[u8]>) -> Result<(), String> {
pub fn publish(&mut self, eh_frame: Option<Vec<u8>>) -> Result<(), String> {
// Do nothing
Ok(())
}
Expand Down
17 changes: 17 additions & 0 deletions lib/engine-jit/src/unwind/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
use wasmer_compiler::CompiledFunctionUnwindInfo;

pub trait UnwindRegistryExt {
/// Registers a function given the start offset, length, and
/// unwind information.
fn register(
&mut self,
base_address: usize,
func_start: u32,
func_len: u32,
info: &CompiledFunctionUnwindInfo,
) -> Result<(), String>;

/// Publishes all registered functions.
fn publish(&mut self, eh_frame: Option<Vec<u8>>) -> Result<(), String>;
}

cfg_if::cfg_if! {
if #[cfg(all(windows, target_arch = "x86_64"))] {
mod windows_x64;
Expand Down
82 changes: 45 additions & 37 deletions lib/engine-jit/src/unwind/systemv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
// Attributions: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md

//! Module for System V ABI unwind registry.
use crate::unwind::UnwindRegistryExt;
use wasmer_compiler::CompiledFunctionUnwindInfo;

/// Represents a registry of function unwind information for System V ABI.
pub struct UnwindRegistry {
eh_frame: Vec<u8>,
registrations: Vec<usize>,
published: bool,
}
Expand All @@ -20,50 +23,21 @@ impl UnwindRegistry {
/// Creates a new unwind registry with the given base address.
pub fn new() -> Self {
Self {
eh_frame: Vec::new(),
registrations: Vec::new(),
published: false,
}
}

/// Registers a function given the start offset, length, and unwind information.
pub fn register(
&mut self,
_base_address: usize,
_func_start: u32,
_func_len: u32,
info: &CompiledFunctionUnwindInfo,
) -> Result<(), String> {
match info {
CompiledFunctionUnwindInfo::Dwarf => {}
_ => return Err("unsupported unwind information".to_string()),
};
Ok(())
}

/// Publishes all registered functions.
pub fn publish(&mut self, eh_frame: Option<&[u8]>) -> Result<(), String> {
if self.published {
return Err("unwind registry has already been published".to_string());
}

if let Some(eh_frame) = eh_frame {
unsafe {
self.register_frames(eh_frame);
}
}

self.published = true;

Ok(())
}

#[allow(clippy::cast_ptr_alignment)]
unsafe fn register_frames(&mut self, eh_frame: &[u8]) {
unsafe fn register_frames(&mut self, eh_frame: Vec<u8>) {
self.eh_frame = eh_frame;

cfg_if::cfg_if! {
if #[cfg(target_os = "macos")] {
// On macOS, `__register_frame` takes a pointer to a single FDE
let start = eh_frame.as_ptr();
let end = start.add(eh_frame.len());
let start = self.eh_frame.as_ptr();
let end = start.add(self.eh_frame.len());
let mut current = start;

// Walk all of the entries in the frame table and register them
Expand All @@ -87,16 +61,50 @@ impl UnwindRegistry {
// deregistering it. We must avoid this
// scenario. Usually, this is handled upstream by the
// compilers.
debug_assert_ne!(eh_frame, &[0, 0, 0, 0], "`eh_frame` seems to contain empty FDEs");
debug_assert_ne!(self.eh_frame.as_slice(), &[0, 0, 0, 0], "`eh_frame` seems to contain empty FDEs");

let ptr = eh_frame.as_ptr();
let ptr = self.eh_frame.as_ptr();
__register_frame(ptr);
self.registrations.push(ptr as usize);
}
}
}
}

impl UnwindRegistryExt for UnwindRegistry {
/// Registers a function given the start offset, length, and unwind information.
fn register(
&mut self,
_base_address: usize,
_func_start: u32,
_func_len: u32,
info: &CompiledFunctionUnwindInfo,
) -> Result<(), String> {
match info {
CompiledFunctionUnwindInfo::Dwarf => {}
_ => return Err("unsupported unwind information".to_string()),
};
Ok(())
}

/// Publishes all registered functions.
fn publish(&mut self, eh_frame: Option<Vec<u8>>) -> Result<(), String> {
if self.published {
return Err("unwind registry has already been published".to_string());
}

if let Some(eh_frame) = eh_frame {
unsafe {
self.register_frames(eh_frame);
}
}

self.published = true;

Ok(())
}
}

impl Drop for UnwindRegistry {
fn drop(&mut self) {
if self.published {
Expand Down
5 changes: 4 additions & 1 deletion lib/engine-jit/src/unwind/windows_x64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Attributions: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md

//! Module for Windows x64 ABI unwind registry.
use crate::unwind::UnwindRegistryExt;
use std::collections::HashMap;
use wasmer_compiler::CompiledFunctionUnwindInfo;
use winapi::um::winnt;
Expand All @@ -21,7 +22,9 @@ impl UnwindRegistry {
published: false,
}
}
}

impl UnwindRegistryExt for UnwindRegistry {
/// Registers a function given the start offset, length, and unwind information.
pub fn register(
&mut self,
Expand Down Expand Up @@ -60,7 +63,7 @@ impl UnwindRegistry {
}

/// Publishes all registered functions.
pub fn publish(&mut self, _eh_frame: Option<&[u8]>) -> Result<(), String> {
pub fn publish(&mut self, _eh_frame: Option<Vec<u8>>) -> Result<(), String> {
if self.published {
return Err("unwind registry has already been published".to_string());
}
Expand Down

0 comments on commit 6fa3a43

Please sign in to comment.