From 0e973b045d37e70ad9aeaf3cf2f6ff4ea01eb214 Mon Sep 17 00:00:00 2001 From: Greg V Date: Mon, 10 Feb 2020 02:34:53 +0300 Subject: [PATCH 01/11] [lucet-runtime-internals] add UContext support for FreeBSD --- .../src/sysdeps/freebsd.rs | 56 +++++++++++++++++++ .../src/sysdeps/mod.rs | 6 ++ 2 files changed, 62 insertions(+) create mode 100644 lucet-runtime/lucet-runtime-internals/src/sysdeps/freebsd.rs diff --git a/lucet-runtime/lucet-runtime-internals/src/sysdeps/freebsd.rs b/lucet-runtime/lucet-runtime-internals/src/sysdeps/freebsd.rs new file mode 100644 index 000000000..ee93a536f --- /dev/null +++ b/lucet-runtime/lucet-runtime-internals/src/sysdeps/freebsd.rs @@ -0,0 +1,56 @@ +use libc::{c_void, ucontext_t}; + +#[derive(Clone, Copy, Debug)] +pub struct UContextPtr(*mut ucontext_t); + +impl UContextPtr { + #[inline] + pub fn new(ptr: *mut c_void) -> Self { + assert!(!ptr.is_null(), "non-null context"); + UContextPtr(ptr as *mut ucontext_t) + } + + #[inline] + pub fn get_ip(self) -> *const c_void { + let mcontext = &unsafe { self.0.as_ref().unwrap() }.uc_mcontext; + mcontext.mc_rip as *const _ + } + + #[inline] + pub fn set_ip(self, new_ip: *const c_void) { + let mut mcontext = &mut unsafe { self.0.as_mut().unwrap() }.uc_mcontext; + mcontext.mc_rip = new_ip as i64; + } + + #[inline] + pub fn set_rdi(self, new_rdi: u64) { + let mut mcontext = &mut unsafe { self.0.as_mut().unwrap() }.uc_mcontext; + mcontext.mc_rdi = new_rdi as i64; + } +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct UContext { + context: *mut ucontext_t, +} + +impl UContext { + #[inline] + pub fn new(ptr: *mut c_void) -> Self { + UContext { + context: unsafe { (ptr as *mut ucontext_t).as_mut().expect("non-null context") }, + } + } + + pub fn as_ptr(&mut self) -> UContextPtr { + UContextPtr::new(self.context as *mut _ as *mut _) + } +} + +impl Into for UContextPtr { + #[inline] + fn into(self) -> UContext { + UContext { context: self.0 } + } +} diff --git a/lucet-runtime/lucet-runtime-internals/src/sysdeps/mod.rs b/lucet-runtime/lucet-runtime-internals/src/sysdeps/mod.rs index 0af38e7ff..519b01302 100644 --- a/lucet-runtime/lucet-runtime-internals/src/sysdeps/mod.rs +++ b/lucet-runtime/lucet-runtime-internals/src/sysdeps/mod.rs @@ -4,6 +4,9 @@ mod macos; #[cfg(target_os = "linux")] mod linux; +#[cfg(target_os = "freebsd")] +mod freebsd; + #[cfg(unix)] mod unix; @@ -13,5 +16,8 @@ pub use macos::*; #[cfg(target_os = "linux")] pub use linux::*; +#[cfg(target_os = "freebsd")] +pub use freebsd::*; + #[cfg(unix)] pub use unix::*; From c2705f3569db8c451ee3b00dee703eb489e181d8 Mon Sep 17 00:00:00 2001 From: Greg V Date: Mon, 30 Dec 2019 17:03:56 +0300 Subject: [PATCH 02/11] [lucet-runtime-internals] Call MAP_ANON mmap with fd -1 Linux is not strict on this, but e.g. FreeBSD is. --- lucet-runtime/lucet-runtime-internals/src/region/mmap.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lucet-runtime/lucet-runtime-internals/src/region/mmap.rs b/lucet-runtime/lucet-runtime-internals/src/region/mmap.rs index 99196d4b3..753ba7a77 100644 --- a/lucet-runtime/lucet-runtime-internals/src/region/mmap.rs +++ b/lucet-runtime/lucet-runtime-internals/src/region/mmap.rs @@ -365,7 +365,7 @@ impl MmapRegion { region.limits.total_memory_size(), ProtFlags::PROT_NONE, MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, - 0, + -1, 0, )? } @@ -436,7 +436,7 @@ unsafe fn mmap_aligned( alignment_offset: usize, ) -> Result<*mut c_void, Error> { let addr = ptr::null_mut(); - let fd = 0; + let fd = -1; let offset = 0; let padded_length = requested_length + alignment + alignment_offset; From ac98cbfaf5c2d17b6b4887a21e31e2bf3eff4822 Mon Sep 17 00:00:00 2001 From: Greg V Date: Mon, 30 Dec 2019 17:05:07 +0300 Subject: [PATCH 03/11] [lucet-runtime-internals] Enable non-executable stack on FreeBSD too --- lucet-runtime/lucet-runtime-internals/src/context/context_asm.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucet-runtime/lucet-runtime-internals/src/context/context_asm.S b/lucet-runtime/lucet-runtime-internals/src/context/context_asm.S index f313ddea9..e0fbb6bf3 100644 --- a/lucet-runtime/lucet-runtime-internals/src/context/context_asm.S +++ b/lucet-runtime/lucet-runtime-internals/src/context/context_asm.S @@ -221,6 +221,6 @@ _lucet_context_activate: #endif /* Mark that we don't need executable stack. */ -#if defined(__linux__) && defined(__ELF__) +#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif From 11ba059ea25f61b045b5a4c97f778c7ecd3dfd88 Mon Sep 17 00:00:00 2001 From: Greg V Date: Mon, 10 Feb 2020 02:33:05 +0300 Subject: [PATCH 04/11] [lucetc] Use -shared linker flag on BSD platforms --- lucetc/src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lucetc/src/lib.rs b/lucetc/src/lib.rs index 0d08a1ab6..5192c5e15 100644 --- a/lucetc/src/lib.rs +++ b/lucetc/src/lib.rs @@ -407,7 +407,11 @@ fn ldflags_default(target: &Triple) -> String { use target_lexicon::OperatingSystem; match target.operating_system { - OperatingSystem::Linux => "-shared", + OperatingSystem::Linux + | OperatingSystem::Freebsd + | OperatingSystem::Dragonfly + | OperatingSystem::Netbsd + | OperatingSystem::Openbsd => "-shared", OperatingSystem::Darwin | OperatingSystem::MacOSX { .. } => { "-dylib -dead_strip -export_dynamic -undefined dynamic_lookup" } From c721efe5439db4b821665e116a17796ee69e9965 Mon Sep 17 00:00:00 2001 From: Greg V Date: Wed, 4 Mar 2020 00:08:27 +0300 Subject: [PATCH 05/11] [lucet-runtime-tests] Call MAP_ANON mmap with fd -1 --- lucet-runtime/lucet-runtime-tests/src/guest_fault.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucet-runtime/lucet-runtime-tests/src/guest_fault.rs b/lucet-runtime/lucet-runtime-tests/src/guest_fault.rs index 55b61b3c7..f3a02be46 100644 --- a/lucet-runtime/lucet-runtime-tests/src/guest_fault.rs +++ b/lucet-runtime/lucet-runtime-tests/src/guest_fault.rs @@ -299,7 +299,7 @@ macro_rules! guest_fault_tests { 4096, ProtFlags::PROT_NONE, MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, - 0, + -1, 0, ) .expect("mmap succeeds") as *mut libc::c_char; From 64d74629039e697216780333a8b839fde2160d30 Mon Sep 17 00:00:00 2001 From: Greg V Date: Wed, 4 Mar 2020 00:09:06 +0300 Subject: [PATCH 06/11] [lucet-runtime-tests] Enable non-executable stack on FreeBSD too --- lucet-runtime/lucet-runtime-tests/src/guest_fault/traps.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucet-runtime/lucet-runtime-tests/src/guest_fault/traps.S b/lucet-runtime/lucet-runtime-tests/src/guest_fault/traps.S index f7df486ec..cddf484ba 100644 --- a/lucet-runtime/lucet-runtime-tests/src/guest_fault/traps.S +++ b/lucet-runtime/lucet-runtime-tests/src/guest_fault/traps.S @@ -65,6 +65,6 @@ _guest_func_oob: #endif .cfi_endproc -#if defined(__linux__) && defined(__ELF__) +#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__) .section ".note.GNU-stack","",@progbits #endif From c8f6926de4f97aa61e8591bf264a891bbf0fa7b7 Mon Sep 17 00:00:00 2001 From: Greg V Date: Sat, 9 May 2020 15:44:27 +0300 Subject: [PATCH 07/11] [lucet-runtime-tests] expect SIGSEGV on FreeBSD like on Linux --- lucet-runtime/lucet-runtime-tests/src/guest_fault.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lucet-runtime/lucet-runtime-tests/src/guest_fault.rs b/lucet-runtime/lucet-runtime-tests/src/guest_fault.rs index f3a02be46..a22f7d927 100644 --- a/lucet-runtime/lucet-runtime-tests/src/guest_fault.rs +++ b/lucet-runtime/lucet-runtime-tests/src/guest_fault.rs @@ -258,14 +258,14 @@ macro_rules! guest_fault_tests { static ref RECOVERABLE_PTR_LOCK: Mutex<()> = Mutex::new(()); } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] const INVALID_PERMISSION_FAULT: libc::c_int = SIGSEGV; - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "freebsd")))] const INVALID_PERMISSION_FAULT: libc::c_int = SIGBUS; - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] const INVALID_PERMISSION_SIGNAL: Signal = Signal::SIGSEGV; - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "freebsd")))] const INVALID_PERMISSION_SIGNAL: Signal = Signal::SIGBUS; $( From 801dd76c069940c240c11ab66ca1a52f6df3df9f Mon Sep 17 00:00:00 2001 From: Greg V Date: Sat, 9 May 2020 15:44:50 +0300 Subject: [PATCH 08/11] [lucet-spectest] respect LD environment variable --- lucet-spectest/src/script.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucet-spectest/src/script.rs b/lucet-spectest/src/script.rs index a7f49d5f8..bb037ddf9 100644 --- a/lucet-spectest/src/script.rs +++ b/lucet-spectest/src/script.rs @@ -78,7 +78,7 @@ impl ScriptEnv { .write(&objfile_path) .map_err(ScriptError::CodegenError)?; - let mut cmd_ld = Command::new("ld"); + let mut cmd_ld = Command::new(std::env::var("LD").unwrap_or("ld".to_string())); cmd_ld.arg(objfile_path.clone()); cmd_ld.arg("-shared"); cmd_ld.arg("-o"); From d87be72d6d97c48ee3ada2988fd90e73d2d4376e Mon Sep 17 00:00:00 2001 From: Greg V Date: Sun, 17 May 2020 02:12:47 +0300 Subject: [PATCH 09/11] [lucet-runtime-internals] use custom stack size on FreeBSD, use cfg-if On FreeBSD/amd64, SIGSTKSZ == MINSIGSTKSZ(4 * 512) + 32768 == 34816. This is not a multiple of the 4k page size, which is required, so use the custom size. Plus, rewrite the choice using cfg_if, as manual cfgs are getting unwieldy. --- .../lucet-runtime-internals/Cargo.toml | 1 + .../lucet-runtime-internals/src/alloc/mod.rs | 30 +++++++++++-------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/lucet-runtime/lucet-runtime-internals/Cargo.toml b/lucet-runtime/lucet-runtime-internals/Cargo.toml index 34e92478c..ed5339c4e 100644 --- a/lucet-runtime/lucet-runtime-internals/Cargo.toml +++ b/lucet-runtime/lucet-runtime-internals/Cargo.toml @@ -17,6 +17,7 @@ anyhow = "1.0" bitflags = "1.0" bincode = "1.1.4" byteorder = "1.3" +cfg-if = "0.1" lazy_static = "1.4" libc = "0.2.65" libloading = "0.6" diff --git a/lucet-runtime/lucet-runtime-internals/src/alloc/mod.rs b/lucet-runtime/lucet-runtime-internals/src/alloc/mod.rs index 267dac21d..420142f64 100644 --- a/lucet-runtime/lucet-runtime-internals/src/alloc/mod.rs +++ b/lucet-runtime/lucet-runtime-internals/src/alloc/mod.rs @@ -465,19 +465,23 @@ pub const MINSIGSTKSZ: usize = libc::MINSIGSTKSZ; /// /// [sigstksz]: https://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html pub const DEFAULT_SIGNAL_STACK_SIZE: usize = { - // on Linux, `SIGSTKSZ` is too small for the signal handler when compiled in debug mode - #[cfg(all(debug_assertions, not(target_os = "macos")))] - const SIZE: usize = 12 * 1024; - - // on Mac, `SIGSTKSZ` is way larger than we need; it would be nice to combine these debug cases once - // `std::cmp::max` is a const fn - #[cfg(all(debug_assertions, target_os = "macos"))] - const SIZE: usize = libc::SIGSTKSZ; - - #[cfg(not(debug_assertions))] - const SIZE: usize = libc::SIGSTKSZ; - - SIZE + cfg_if::cfg_if! { + if #[cfg(target_os = "freebsd")] { + // on FreeBSD/amd64, `SIGSTKSZ` is not a multiple of the page size + // (34816 == MINSIGSTKSZ(2048) + 32768) + 12 * 1024 + } else if #[cfg(target_os = "macos")] { + // on Mac, `SIGSTKSZ` is way larger than we need; + // it would be nice to combine these debug cases once + // `std::cmp::max` is a const fn + libc::SIGSTKSZ + } else if #[cfg(debug_assertions)] { + // on Linux, `SIGSTKSZ` is too small for the signal handler when compiled in debug mode + 12 * 1024 + } else { + libc::SIGSTKSZ + } + } }; impl Limits { From 1adc4dbcb6cb271b86ffa9d545643532f76d4ce1 Mon Sep 17 00:00:00 2001 From: Greg V Date: Wed, 8 Jul 2020 20:38:16 +0300 Subject: [PATCH 10/11] Update libc to 0.2.72 Finally includes FreeBSD/amd64 mcontext/ucontext --- Cargo.lock | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f16f4330..1c29fa0f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -826,9 +826,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" [[package]] name = "libc" -version = "0.2.70" +version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f" +checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701" [[package]] name = "libloading" @@ -954,6 +954,7 @@ dependencies = [ "bitflags 1.2.1", "byteorder", "cc", + "cfg-if", "lazy_static", "libc", "libloading 0.6.2", From a1ec5275878b0d29c624a454efd9ba264815a70a Mon Sep 17 00:00:00 2001 From: Greg V Date: Wed, 8 Jul 2020 21:01:45 +0300 Subject: [PATCH 11/11] [lucet-module,lucet-objdump] Update object dependency --- Cargo.lock | 25 ++++++++----------------- lucet-module/Cargo.toml | 2 +- lucet-objdump/Cargo.toml | 2 +- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c29fa0f5..c1e59864e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -898,7 +898,7 @@ dependencies = [ "derivative", "memoffset", "minisign", - "object 0.18.0", + "object 0.20.0", "serde", "serde-big-array", "serde_json", @@ -912,7 +912,7 @@ dependencies = [ "byteorder", "colored", "lucet-module", - "object 0.18.0", + "object 0.20.0", ] [[package]] @@ -1297,17 +1297,6 @@ dependencies = [ "libc", ] -[[package]] -name = "object" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5666bbb90bc4d1e5bdcb26c0afda1822d25928341e9384ab187a9b37ab69e36" -dependencies = [ - "flate2", - "target-lexicon", - "wasmparser 0.51.4", -] - [[package]] name = "object" version = "0.19.0" @@ -1321,7 +1310,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" dependencies = [ "crc32fast", + "flate2", "indexmap", + "wasmparser 0.57.0", ] [[package]] @@ -2362,15 +2353,15 @@ checksum = "a91c2916119c17a8e316507afaaa2dd94b47646048014bbdf6bef098c1bb58ad" [[package]] name = "wasmparser" -version = "0.51.4" +version = "0.52.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeb1956b19469d1c5e63e459d29e7b5aa0f558d9f16fcef09736f8a265e6c10a" +checksum = "733954023c0b39602439e60a65126fd31b003196d3a1e8e4531b055165a79b31" [[package]] name = "wasmparser" -version = "0.52.2" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733954023c0b39602439e60a65126fd31b003196d3a1e8e4531b055165a79b31" +checksum = "32fddd575d477c6e9702484139cf9f23dcd554b06d185ed0f56c857dd3a47aa6" [[package]] name = "wasmparser" diff --git a/lucet-module/Cargo.toml b/lucet-module/Cargo.toml index 33371a06d..bb71dec8f 100644 --- a/lucet-module/Cargo.toml +++ b/lucet-module/Cargo.toml @@ -16,7 +16,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" bincode = "1.1.4" minisign = "0.5.19" -object = "0.18.0" +object = "0.20.0" byteorder = "1.3" memoffset = "0.5.3" thiserror = "1.0.4" diff --git a/lucet-objdump/Cargo.toml b/lucet-objdump/Cargo.toml index 86d8752de..3088b77d3 100644 --- a/lucet-objdump/Cargo.toml +++ b/lucet-objdump/Cargo.toml @@ -10,7 +10,7 @@ authors = ["Lucet team "] edition = "2018" [dependencies] -object = "0.18" +object = "0.20" byteorder="1.2.1" colored="1.8.0" lucet-module = { path = "../lucet-module", version = "=0.7.0-dev" }