port(wasm): Synthesize GOT.mem globals for R_WASM_GLOBAL_INDEX - #2271
Conversation
|
Running CRuby requires at least version 4.0.0 when using wasi-sdk23+. Without this, builds fail locally even with wasm-ld. This is because a patch for mprotect isn't included before this version. |
| slot | ||
| } else { | ||
| let Some(&def_obj_idx) = | ||
| file_id_to_index.get(&symbol_db.file_id_for_symbol(def_id)) |
There was a problem hiding this comment.
What about symbols that aren't from files like __heap_base?
There was a problem hiding this comment.
Ah, you're right, I forgot to consider that.
| && entry_is_defined_function(&layout_inputs, symbol_db); | ||
| let indices = LinkerDefinedIndices::compute( | ||
|
|
||
| let file_id_to_index: HashMap<crate::input_data::FileId, usize> = layout_inputs |
There was a problem hiding this comment.
Didn't we already build a file_id_to_index map elsewhere?
There was a problem hiding this comment.
Changed to build a map in a single location.
|
|
||
| for (obj_idx, input) in layout_inputs.iter().enumerate() { | ||
| let mut hits: Vec<(usize, usize)> = Vec::new(); | ||
| for reloc in input |
There was a problem hiding this comment.
Ideally it'd be good if we could loop through the relocations just once during the layout phase and once during the write phase. Doing that would avoid repeating work and potentially repeating logic each time we iterate.
| let def_ok = def_input | ||
| .symbols | ||
| .get(def_off) | ||
| .is_some_and(|s| s.kind == WasmSymbolKind::Data && !s.is_undefined()); | ||
| ensure!( | ||
| def_ok, | ||
| "GOT.mem for `{}` requires a defined data symbol in the link", | ||
| symbol_db.symbol_name_for_display(def_id) | ||
| ); |
There was a problem hiding this comment.
Might need to deal with undefined weak symbols here, including adding a test, but let's do that in a separate PR.
There was a problem hiding this comment.
Not handling undefined weak symbols currently causes runtime traps when running sqlite, so I planned to address this in a separate patch.
With
-fPIC, clang refers to data via linker-made i32 globals (import module GOT.mem / name-sectionGOT.data.internal.*).R_WASM_GLOBAL_INDEX_*then targets those Data symbols.Now Wild synthesize one i32 global per unique defined data target, initialize it with the final linear-memory address after data layout, absorb matching GOT.mem.* imports, and resolve GLOBAL_INDEX relocs to the synthetic global index. True Global symbols keep the previous path.
This enables building CRuby for WebAssembly (see https://github.com/ruby/ruby/tree/master/wasm#readme). I verified with v4.0.6.
Part of #1431