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

    <tr>
        <th>Summary</th>
        <td>
            Unresolved TPOFF64 in -static-pie when using lld
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            lld
      </td>
    </tr>

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

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

<pre>
    Here is the `demo.go` file that I compiled:

```go
package main

// #cgo LDFLAGS: -ldl
// #include <stdlib.h>
// #include <dlfcn.h>
import "C"
import (
        "fmt"
)

func main() {
        fmt.Printf("This is a Go demo.\n")
        C.CString("libsystemd-login.so.0")
        return
}
```

When I compile it with the following command:
```shell
export CC=
go build -buildmode=pie -o demo-ld.exe -ldflags '-buildid=none -tmpdir=. -extldflags=-ftrapv -extldflags=-Wl,-z,relro,-z,now -linkmode=external -extldflags=-static-pie' demo.go;
```
`demo-ld` can be executed correctly. However, if I compile it with:
```shell
export CC=clang
go build -buildmode=pie -o demo-lld.exe -ldflags '-buildid=none -tmpdir=. -extldflags=-ftrapv -extldflags=-Wl,-z,relro,-z,now -linkmode=external -extldflags=-static-pie' demo.go;
```
`demo-lld` cannot be executed and ends with a "Segmentation fault (core dumped)" error.

Hence, I tried to use `readelf -r` on these files to identify the cause of the failure. I discovered that `demo-lld.exe` cannot resolve the TPOFF64 relocation type statically, while `demo-ld.exe` can. As a result, `demo-lld.exe` has several TPOFF64 entries in its dynamic relocation section. I also attempted to debug `demo-lld` with GDB and found that when the linker skips the resolution of TPOFF64, it can be executed correctly. However, if the resolution is performed, it fails at `dl_allocate_static_tls` due to uninitialized TLS, which does not occur with `demo-ld.exe`.

![image](https://github.com/llvm/llvm-project/assets/152485077/60a0dc79-1897-42e1-a68e-726382ae418c)

During my search on glibc, I came across an existing issue report (https://sourceware.org/bugzilla/show_bug.cgi?id=31302) that addresses this problem. According to their conclusion, `lld` should be able to resolve TPOFF64 relocations with -static-pie.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzcVk1v2zgT_jX0ZSBBoqwPH3xI7NdtgQJvgXTRY0CRI4ktRQokFdv99QtSduK4xaJ7XaCoEGk4nHk-Zsyck71G3JLykZT7FZv9YOz2yLOsqWiTlez7qjXivP2IFkE68AMCqTKBo0l7Q6oMOqkQ_MA8fAJuxkkqFKR4INmeZNf_q2z515vlxcT4D9YjjEzqd4H0QOgBCC14b-Dz_vD54cMTKR4gUULdh0jN1SwQSLFzXijZpgMp_vcPUUJ1XN8EyXEy1gOhdEcovXvXXOvaEEq70b9GELq5LbmbNV_6oA2hGyD14-vJbvTpFyu17-JH-nWQLoDI4IOBCCEpdzpkfsu52aW7J2-l7pczSrbu7DyOIlGmlzp1Js3ujlj0s70CWe_vQL-t9tuA-o0nkB6O0g-R1c4oZY5S9-HryPQNiddMbkB1oQFPEafdjhSX-3oD7SyVgCQ-RiOQFPtJIiRLs4kSKZ4wcNkp1jsgtF5ipSDFXhuNkPhxEtKSYp9Cgid_CSXFPum8ZdPL_dtvitBd8pPQnUVlzfUPbY6QKKl_XMrAk0ermbo_7jzzkieTREJruKq6ePw9hIvuEyWC7jnT0CLgCfnsUQA31iL36pzCR3PEF7SE7kB2v8L9x8ByxXT_x-j-Z-B9xVcb_w5ipgWgFm4RLQvOfcJ-RB2uMRo6NqvoXW4sgpjHCUXwCaWA1hqb3lrhI2qOgaJP4K1EAd7A7OJ0s8gEqg4SGwoxOvjDYZx0LoRJgdrL7hx9w1k4ZbrFREyq2WIKn0BIx80L2pA5TMeb9gJPNy1adEa9YEzw9cv_D4dqDRaV4UtX_jwhLEgypc6h5OMQ5PSmx5uEKTyEAWPRzcqH2N_cOzAHLiiUqdcLUQcUHEgN0jsQZ81GyW_rcMjDM_TGlDPAvMdx8gtyAtu5hzsKI00f9o-RuM7M-gLFMUyh0G2QEFpwP-S0rJYIxRyvM921tugj_-eGu0skHUxoO2PHoIaYKtDk4EKKemYqNonPC8rPXrlQvpgxikJLLb1kSv5EAV8_P10Y4AMIgw4ChYbz2S79_sJK-n7D5aR8lCPrkZR7QpvB-8mFiRA3Vi_9MLcpNyOhB6Vero9ksuY7ck_ogTmH3hF6yEu6bsqsrgk9VBnLBK83Sd5s6mRNMU9Y1WBS06poKMN13vC7xbWfw5KB8QwOmeVD0HmvZMsXT3A2IjBujXPANOBJOh_ipXNzgPe6Jt_X78xsOR6ZxdTYntBDO_c_pVIsfBvM8bmd-5T3khSHOJWKvMjCKlt0wYSw6FwwWdiUkzWtwjGFB86NFeF2bwK70gI3Ya87afRF4xfJucHMSgSdsFZF-q7u-tVZlzlyM6XSldgWYlNs2Aq3eZ1n66reFNVq2G5oW2d5lfOmyilt6ZpVNed50ayZKIq6XMktzeg6K_Iyy8umrNKqwTarWZU1Rc7ZmpN1hiOTKg18BnRWEcptUxbrzUqxFpWLP8MoDb1QGn6P2W1kv517R9aZks67t_NeeoXbv_SlQ_HaotS3TS12m13ATymxmq3a_mvVxVqD6mK5fwcAAP__8c86CQ">