Skip to content

[WebAssembly] Incorrect data section offsets when using -pie and TLS #127355

Open
@qianxichen233

Description

@qianxichen233

I recently encountered an unexpected behavior when compiling a WebAssembly module with wasm-ld using Position-Independent Executable (PIE) mode and Thread-Local Storage (TLS) (__thread variables). The generated code appears to access a string in .data at an incorrect offset, which causes misalignment.

I am unsure if this is an intended behavior or a potential bug in wasm-ld. I would appreciate any insights from the wasm-ld maintainers.

Reproduce the behavior

When compiling the following obj.c and lib.c files:

// obj.c
__thread int test = 10;

void obj_func() {
    test = 1;
}
// lib.c
extern void obj_func();

int str_func(const char *s) {
    return 42;
}

int lib_func() {
    obj_func();
    return str_func("this is a string");
}

using

clang --target=wasm32-unknown-wasi \
    -nostdlib -fPIC -matomics -mbulk-memory -c obj.c -o obj.o

clang --target=wasm32-unknown-wasi \
    -fPIC -nostdlib -Wl,-pie,--no-entry,--export=lib_func lib.c obj.o -o lib.wasm

I found that the generated WAT file places the string in .data with this definition:

(data $.data (global.get $__memory_base) "\0a\00\00\00this is a string\00")

which means the string starts at an offset of 4 relative to __memory_base. However, in the compiled code, the reference to the string is:

i32.const 8
local.set 0
global.get $__memory_base
local.set 1
local.get 1
local.get 0
i32.add
local.set 2
local.get 2
call $str_func

which uses an offset of 8 instead of 4.
And I also found out that If I remove __thread from obj.c, the issue disappears, and the correct offset is used.

I encountered this behavior when I was using clang version 18.1.8 with LLD version 18.1.8. I also tried to download the LLVM main branch and made a fresh build, and I am still encountering the same behavior.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions