Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bitcasts from extern symbols to function pointers produce corrupted WebAssembly binary #60003

Closed
RReverser opened this issue Jan 13, 2023 · 1 comment
Assignees

Comments

@RReverser
Copy link

RReverser commented Jan 13, 2023

Original issue in emscripten-core/emscripten#15722 / rust-lang/rust#91628.

The minimal repro for C/C++ looks like this:

extern char maybe_func;

int main() {
    int(*func)() = (int(*)())&maybe_func;
    return func();
}

This produces the following LLVM IR with -target wasm32-unknown-emscripten (but likely reproducible with other Wasm targets too):

@maybe_func = external local_unnamed_addr global i8, align 1

define hidden noundef i32 @__main_argc_argv(i32 noundef %0, ptr nocapture noundef readnone %1) local_unnamed_addr #0 {
  %3 = tail call noundef i32 @maybe_func()
  ret i32 %3
}

attributes #0 = { mustprogress norecurse "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" }

The Wasm generated by LLVM is corrupted, and wasm-opt, wasm-validate etc fail:

$ emcc temp.c -O -Wl,--allow-undefined
[parse exception: attempted pop from empty stack / beyond block start boundary at 262 (at 0:262)]
Fatal: error in parsing input
emcc: error: '/home/rreverser/emsdk/upstream/bin/wasm-emscripten-finalize --dyncalls-i64 --pass-arg=legalize-js-interface-exported-helpers a.out.wasm -o a.out.wasm --detect-features' failed (returned 1)

As discussed in linked issues, this is likely due to maybe_func being called directly without bitcast handling that Wasm function pointers require. IIUC this is not possible to solve in general for arbitrary casts, but should be doable for extern symbols.

@llvmbot
Copy link
Member

llvmbot commented Jan 13, 2023

@llvm/issue-subscribers-backend-webassembly

@HerrCai0907 HerrCai0907 self-assigned this Mar 22, 2023
@aheejin aheejin closed this as completed in 0e37487 Apr 5, 2023
gysit pushed a commit to nextsilicon/llvm-project that referenced this issue Apr 27, 2023
When selecting calls, currently we unconditionally remove `Wrapper`s of
the call target. But we are supposed to do that only when the target is
a function, an external symbol (= library function), or an alias of a
function. Otherwise we end up directly calling globals that are not
functions.

Fixes llvm#60003.

Reviewed By: tlively, HerrCai0907

Differential Revision: https://reviews.llvm.org/D147397
DianQK pushed a commit to DianQK/llvm-project that referenced this issue Oct 10, 2023
When selecting calls, currently we unconditionally remove `Wrapper`s of
the call target. But we are supposed to do that only when the target is
a function, an external symbol (= library function), or an alias of a
function. Otherwise we end up directly calling globals that are not
functions.

Fixes llvm#60003.

Reviewed By: tlively, HerrCai0907

Differential Revision: https://reviews.llvm.org/D147397
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants