Skip to content

port(wasm): Synthesize GOT.mem globals for R_WASM_GLOBAL_INDEX - #2271

Merged
lapla-cogito merged 4 commits into
wild-linker:mainfrom
lapla-cogito:wasm_gotmem
Jul 29, 2026
Merged

port(wasm): Synthesize GOT.mem globals for R_WASM_GLOBAL_INDEX#2271
lapla-cogito merged 4 commits into
wild-linker:mainfrom
lapla-cogito:wasm_gotmem

Conversation

@lapla-cogito

@lapla-cogito lapla-cogito commented Jul 26, 2026

Copy link
Copy Markdown
Member

With -fPIC, clang refers to data via linker-made i32 globals (import module GOT.mem / name-section GOT.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

@lapla-cogito

lapla-cogito commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

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.

Comment thread libwild/src/wasm.rs Outdated
slot
} else {
let Some(&def_obj_idx) =
file_id_to_index.get(&symbol_db.file_id_for_symbol(def_id))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about symbols that aren't from files like __heap_base?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you're right, I forgot to consider that.

Comment thread libwild/src/wasm.rs Outdated
&& 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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't we already build a file_id_to_index map elsewhere?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to build a map in a single location.

Comment thread libwild/src/wasm.rs

for (obj_idx, input) in layout_inputs.iter().enumerate() {
let mut hits: Vec<(usize, usize)> = Vec::new();
for reloc in input

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, done.

Comment thread libwild/src/wasm.rs
Comment on lines +3118 to +3126
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)
);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might need to deal with undefined weak symbols here, including adding a test, but let's do that in a separate PR.

@lapla-cogito lapla-cogito Jul 29, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not handling undefined weak symbols currently causes runtime traps when running sqlite, so I planned to address this in a separate patch.

@lapla-cogito
lapla-cogito merged commit 0e7351c into wild-linker:main Jul 29, 2026
23 checks passed
@lapla-cogito
lapla-cogito deleted the wasm_gotmem branch July 29, 2026 07:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants