Resolve libcall relocations for older CPUs (#5567)

* Resolve libcall relocations for older CPUs

Long ago Wasmtime used to have logic for resolving relocations
post-compilation for libcalls which I ended up removing during
refactorings last year. As #5563 points out, however, it's possible to
get Wasmtime to panic by disabling SSE features which forces Cranelift
to use libcalls for some floating-point operations instead. Note that
this also requires disabling SIMD because SIMD support has a baseline of
SSE 4.2.

This commit pulls back the old implementations of various libcalls and
reimplements logic necessary to have them work on CPUs without SSE 4.2

Closes #5563

* Fix log message in `wast` support

* Fix offset listed in relocations

Be sure to factor in the offset of the function itself

* Review comments
This commit is contained in:
Alex Crichton
2023-01-18 09:04:10 -06:00
committed by GitHub
parent 94b51cdb17
commit 9b896d2a70
7 changed files with 298 additions and 14 deletions

View File

@@ -48,7 +48,7 @@ pub const ELF_WASMTIME_ADDRMAP: &str = ".wasmtime.addrmap";
/// encodes the ability to map an offset in the text section to the trap code
/// that it corresponds to.
///
/// This section is used at runtime to determine what flavor fo trap happened to
/// This section is used at runtime to determine what flavor of trap happened to
/// ensure that embedders and debuggers know the reason for the wasm trap. The
/// encoding of this section is custom to Wasmtime and managed with helpers in
/// the `object` crate:
@@ -63,7 +63,7 @@ pub const ELF_WASMTIME_ADDRMAP: &str = ".wasmtime.addrmap";
///
/// This section is decoded by `lookup_trap_code` below which will read the
/// section count, slice some bytes to get the various arrays, and then perform
/// a binary search on the offsets array to find the an index corresponding to
/// a binary search on the offsets array to find the index corresponding to
/// the pc being looked up. If found the same index in the trap array (the array
/// of bytes) is the trap code for that offset.
///
@@ -128,3 +128,42 @@ pub const ELF_NAME_DATA: &'static str = ".name.wasm";
/// and is instead indexed directly by relative indices stored in compilation
/// metadata.
pub const ELF_WASMTIME_DWARF: &str = ".wasmtime.dwarf";
macro_rules! libcalls {
($($rust:ident = $sym:tt)*) => (
#[allow(missing_docs)]
pub enum LibCall {
$($rust,)*
}
impl LibCall {
/// Returns the libcall corresponding to the provided symbol name,
/// if one matches.
pub fn from_str(s: &str) -> Option<LibCall> {
match s {
$($sym => Some(LibCall::$rust),)*
_ => None,
}
}
/// Returns the symbol name in object files associated with this
/// libcall.
pub fn symbol(&self) -> &'static str {
match self {
$(LibCall::$rust => $sym,)*
}
}
}
)
}
libcalls! {
FloorF32 = "libcall_floor32"
FloorF64 = "libcall_floor64"
NearestF32 = "libcall_nearestf32"
NearestF64 = "libcall_nearestf64"
CeilF32 = "libcall_ceilf32"
CeilF64 = "libcall_ceilf64"
TruncF32 = "libcall_truncf32"
TruncF64 = "libcall_truncf64"
}