Skip to content

Commit

Permalink
Move gdbjit C helpers to a separate file (bytecodealliance#9939)
Browse files Browse the repository at this point in the history
* Move gdbjit C helpers to a separate file

This commit splits out the gdbjit-related helpers from `helpers.c` in
Wasmtime to a separate C file built as part of the `wasmtime-jit-debug`
crate. This'll help excise these helpers if gdbjit support is disabled
at compile time and additionally brings them closer to the actual
definition in the `wasmtime-jit-debug` crate.

* Fix linkage issues

* Fix miri tests
  • Loading branch information
alexcrichton authored Jan 7, 2025
1 parent f309bfd commit 115da98
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 40 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions crates/jit-debug/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ rust-version.workspace = true
[lints]
workspace = true

[build-dependencies]
cc = { workspace = true }
wasmtime-versioned-export-macros = { workspace = true }

[dependencies]
object = { workspace = true, optional = true }
wasmtime-versioned-export-macros = { workspace = true }
Expand Down
17 changes: 17 additions & 0 deletions crates/jit-debug/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use wasmtime_versioned_export_macros::versioned_suffix;

fn main() {
if !cfg!(feature = "gdb_jit_int") {
return;
}

let mut build = cc::Build::new();
build.warnings(true);
let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
build.define(&format!("CFG_TARGET_OS_{os}"), None);
build.define("VERSIONED_SUFFIX", Some(versioned_suffix!()));

println!("cargo:rerun-if-changed=gdbjit.c");
build.file("gdbjit.c");
build.compile("gdbjit-helpers");
}
46 changes: 46 additions & 0 deletions crates/jit-debug/gdbjit.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <stdint.h>
#include <stdlib.h>

#define CONCAT2(a, b) a##b
#define CONCAT(a, b) CONCAT2(a, b)
#define VERSIONED_SYMBOL(a) CONCAT(a, VERSIONED_SUFFIX)

#ifdef CFG_TARGET_OS_windows
// export required for external access.
__declspec(dllexport)
#else
// Note the `weak` linkage here, though, which is intended to let other code
// override this symbol if it's defined elsewhere, since this definition doesn't
// matter.
// Just in case cross-language LTO is enabled we set the `noinline` attribute
// and also try to have some sort of side effect in this function with a dummy
// `asm` statement.
__attribute__((weak, noinline))
#endif
void __jit_debug_register_code() {
#ifndef CFG_TARGET_OS_windows
__asm__("");
#endif
}

struct JITDescriptor {
uint32_t version_;
uint32_t action_flag_;
void *relevant_entry_;
void *first_entry_;
};

#ifdef CFG_TARGET_OS_windows
// export required for external access.
__declspec(dllexport)
#else
// Note the `weak` linkage here which is the same purpose as above. We want to
// let other runtimes be able to override this since our own definition isn't
// important.
__attribute__((weak))
#endif
struct JITDescriptor __jit_debug_descriptor = {1, 0, NULL, NULL};

struct JITDescriptor *VERSIONED_SYMBOL(wasmtime_jit_debug_descriptor)() {
return &__jit_debug_descriptor;
}
4 changes: 4 additions & 0 deletions crates/wasmtime/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ impl Engine {
// handlers, etc.
#[cfg(all(feature = "signals-based-traps", not(miri)))]
crate::runtime::vm::init_traps(config.macos_use_mach_ports);
if !cfg!(miri) {
#[cfg(feature = "debug-builtins")]
crate::runtime::vm::debug_builtins::init();
}
}

#[cfg(any(feature = "cranelift", feature = "winch"))]
Expand Down
15 changes: 15 additions & 0 deletions crates/wasmtime/src/runtime/vm/debug_builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,18 @@ pub unsafe extern "C" fn set_vmctx_memory(vmctx_ptr: *mut VMContext) {
// TODO multi-memory
VMCTX_AND_MEMORY = (vmctx_ptr, 0);
}

/// A bit of a hack around various linkage things. The goal here is to force the
/// `wasmtime_*` symbols defined in `helpers.c` to actually get exported. That
/// means they need to be referenced for the linker to include them which is
/// what this function does with trickery in C.
pub fn init() {
extern "C" {
#[wasmtime_versioned_export_macros::versioned_link]
fn wasmtime_debug_builtins_init();
}

unsafe {
wasmtime_debug_builtins_init();
}
}
44 changes: 4 additions & 40 deletions crates/wasmtime/src/runtime/vm/helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,54 +96,18 @@ void VERSIONED_SYMBOL(set_vmctx_memory)(void *);
DEBUG_BUILTIN_EXPORT void VERSIONED_SYMBOL(wasmtime_set_vmctx_memory)(void *p) {
VERSIONED_SYMBOL(set_vmctx_memory)(p);
}
#endif // FEATURE_DEBUG_BUILTINS

#ifdef CFG_TARGET_OS_windows
// export required for external access.
__declspec(dllexport)
#else
// Note the `weak` linkage here, though, which is intended to let other code
// override this symbol if it's defined elsewhere, since this definition doesn't
// matter.
// Just in case cross-language LTO is enabled we set the `noinline` attribute
// and also try to have some sort of side effect in this function with a dummy
// `asm` statement.
__attribute__((weak, noinline))
#endif
void __jit_debug_register_code() {
// Helper symbol called from Rust to force the above two functions to not get
// stripped by the linker.
void VERSIONED_SYMBOL(wasmtime_debug_builtins_init)() {
#ifndef CFG_TARGET_OS_windows
__asm__("");
#ifdef FEATURE_DEBUG_BUILTINS
// Make sure these symbols do not get stripped by the compiler or linker.
void *volatile p;
p = (void *)&VERSIONED_SYMBOL(wasmtime_resolve_vmctx_memory_ptr);
p = (void *)&VERSIONED_SYMBOL(wasmtime_set_vmctx_memory);
(void)p;
#endif // FEATURE_DEBUG_BUILTINS
#endif
}

struct JITDescriptor {
uint32_t version_;
uint32_t action_flag_;
void *relevant_entry_;
void *first_entry_;
};

#ifdef CFG_TARGET_OS_windows
// export required for external access.
__declspec(dllexport)
#else
// Note the `weak` linkage here which is the same purpose as above. We want to
// let other runtimes be able to override this since our own definition isn't
// important.
__attribute__((weak))
#endif
struct JITDescriptor __jit_debug_descriptor = {1, 0, NULL, NULL};

struct JITDescriptor *VERSIONED_SYMBOL(wasmtime_jit_debug_descriptor)() {
return &__jit_debug_descriptor;
}
#endif // FEATURE_DEBUG_BUILTINS

// For more information about this see `unix/unwind.rs` and the
// `using_libunwind` function. The basic idea is that weak symbols aren't stable
Expand Down

0 comments on commit 115da98

Please sign in to comment.