<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/127355>127355</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [WebAssembly] Incorrect data section offsets when using -pie and TLS
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          qianxichen233
      </td>
    </tr>
</table>

<pre>
    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.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJyUVltv6ygQ_jXkZWTLwXUuD3nIaU-1kbrS0Z5q-1hhGNucgyEL46T99yuwc2urlVaKkgDDzDe3bxAh6NYiblj1jVUPMzFQ5_zmHy3sm5YdWl6Ws9qp980OPEq0ZN4BrXSDJfSoQFgYLL7tURIqqLETB-08HDu0IF2_10bbFgS8YL0NAfvavEPv1GAQjpo6OIrQZ0bBEKLcDxc0aWeznVW4R6vQEnx_QzmQqA0C46sfu--Mr6MOBGEVPHcehcqenBQGfpLzok1yz08_oxzjq9dXSjJwEF5HNYHxdQ7PHUKLFr2IyGXSt9-j8AHIgZASQwABgXxEpi3kSpAAQdFnbaXzHiWBa5qAxPg9HDstO5BiCBig10EY3doeLeWs2LJiuwPRw2DD4BF0A9TpADqM2ij6ehU_50HA3hFa0sJAPSQEU7By2MHRDUZFwB6lFhRj8Q7aBt12FKDxrgfq8BzeXmhLQlv0YULDeDl-4C_ce6cGienGGcJZgBXbl9t0RrnGGeOOceXqX7lMuTC6ziU0Ooa4TEYWxfSJBh8ZfxylWbE9Z0VbAsJAwMoHmBes_DYCPDitovRrM1jJ-CplcxkPAeDqxnRh-fDR3mfbCR8rtvhG6C18YeFsPaIK5E9H0tlAIDsR47INt1g80uAt3PEbKKMOo-uvHfjK7pWyK9uM83OtTOXIOL-A_eR56qUPe9II20KWkfAtEisfYmWUPBvsb-uONjuKoIFV9xFFZl0gZXQNWfNjdw9ZL8j1WgbI-nowv7Mee-ffIZNT7jOX_rjR7f9jCuBk42LzxTB-n-01xp_Mugwt-fe0wLe981HlKaxTySXrEUZcRnMfvN9B4wargDpBqXovjf-yfU4VC3sjJIZ0-rHnE1OlHChstE0U9VWBr5I043f59GfVGlcLk7dIcfv1dYzcay0CjuzEWXVfiPhVXL4-pTudjDm_tTlyTo_C3iAPJDyFiatGhgLXwB14NIL0ASPF3aDJ4Q93xAP6yGTaJmVjw0_kGPfjpscGPVqZVFwH64uW1yXPx85ZsWJrIkXnEUo8-6_IXMvOz6v20-pkQyh1c4ffSMWVFMZEO-e2-iqMibhvAraKlEqRpWL0InNurYIdCBPcVFJuoLGsdg3EGdm7AwJbFCd-Y4tipOOR-KYo6hAGBKXDNHLivkgFGsN-PVliHQwB1XmIXE_fVCi3Q3cXOX8ap2MnHtAH7SzMV_k8X43F_PT08GE_P7lFXkfNDpQ7WuPECOrp6e8_0xSB2gsru4S2F3FoQuMxdFAP2qiTH2nWBdLGXPCeJkcQ_WXM5DO1KdW6XIsZbubLcr1YVPNqMes2Zcmlaiq5rlbLeVPjvFhXNS9VuVxxtVwtZ3rDC14VfL4oivl6vsgbxLvFXSGr9VwV82LJ7grshTa5MYc-d76dpbBv5nxZVtXMiBpNSC8fzi0ex6SklnyY-U28lNVDG9hdYXSgcFFDmkx6Ml29alj1ALvzqyD1f0AZmWJKZBjzM2Ym0tv4fHn6ORu82XRE-9RBaVK1mrqhzqXrGX-MZqefbO_dL5TE-GMCGxh_nLw5bPi_AQAA__8HpiZV">