[PATCH] D44028: [WebAssembly] Handle weak undefined functions with a synthetic stub
Nicholas Wilson via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 7 10:13:40 PST 2018
ncw added a comment.
Good questions. So the call pattern we want to support is fairly common in libraries like libc - you have an optional function that's called only if the linker pulls it in.
For C code looking like this:
int foo() __attribute__((weak));
void callFooOrSkip() {
if (&foo)
foo();
}
On x86, you get code like this:
00000000 <callFooOrSkip>:
0: b8 00 00 00 00 mov $0x0,%eax
1: R_386_32 foo
5: 85 c0 test %eax,%eax
7: 74 05 je e <callFooOrSkip+0xe>
9: e9 fc ff ff ff jmp a <callFooOrSkip+0xa>
a: R_386_PC32 foo
e: c3 ret
There's a relocation for the function pointer, and a second one for the operand of the call. At link time, the linker can just put null in there for both values, or garbage - if the CPU ever were to take the "if" branch, or if the call to foo() were not guarded with an if, it wouldn't matter if process were to crash with SIGSEGV. The jmp doesn't need to legal - only if it's ever actually taken.
On Wasm, you get code like this:
block
i32.const @R_WEBASSEMBLY_TABLE_INDEX(foo) ; push function index to stack
i32.eqz ; pop value from stack, push bool to stack whether it's equal
br_if ; pop value from stack, break out of block if it's true
call @R_WEBASSEMBLY_FUNC_INDEX(foo) ; call and push rv to stack
drop ; pop ignored rv from stack
end
Again there are two relocations. But here's the difference - you can't put null/zero as the operand to the call instruction. The Wasm validator is precisely designed to make it impossible to write code that fails with SIGSEGV! Regardless of whether the branch is ever taken, there has to be _something_ to go there. Hence the creation of the linker-synthetic functions. We don't expect the stubs to be called, they just have to exist to make the Wasm legal (and abort sensibly if they are somehow called).
Repository:
rLLD LLVM Linker
https://reviews.llvm.org/D44028
More information about the llvm-commits
mailing list