<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/116575>116575</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[LLD] LLD unexpectedly removes definition of a weak symbol
</td>
</tr>
<tr>
<th>Labels</th>
<td>
lld
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
jinghao-jia
</td>
</tr>
</table>
<pre>
We are currently working on incorporating LLVM-cov to the Linux kernel. However,
it seems that `lld` removes the definition of a LLVM-cov related symbol at linking
stage and breaks our kernel.
## Steps to reproduce:
```bash
# download the linux source
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
# apply our mcdc patches
wget https://raw.githubusercontent.com/whentojump/linux-mcdc/refs/heads/llvm-trunk-next/patches/v3.0/0001-llvm-cov-add-Clang-s-Source-based-Code-Coverage-supp.patch -O- | patch -p1
wget https://raw.githubusercontent.com/whentojump/linux-mcdc/refs/heads/llvm-trunk-next/patches/v3.0/0002-llvm-cov-add-Clang-s-MC-DC-support.patch -O- | patch -p1
wget https://raw.githubusercontent.com/whentojump/linux-mcdc/refs/heads/llvm-trunk-next/patches/v3.0/0003-x86-disable-llvm-cov-instrumentation.patch -O- | patch -p1
wget https://raw.githubusercontent.com/whentojump/linux-mcdc/refs/heads/llvm-trunk-next/patches/v3.0/0004-x86-enable-llvm-cov-support.patch -O- | patch -p1
# build the kernel
echo 'CONFIG_LLVM_COV_KERNEL=y
CONFIG_LLVM_COV_PROFILE_ALL=y' >kernel/configs/llvm_cov.config
echo CONFIG_FORTIFY_SOURCE=y >kernel/configs/fortify_source.config
echo CONFIG_AMD_MEM_ENCRYPT=y >arch/x86/configs/amd_mem_encrypt.config
make -kj"$(nproc)" ARCH=x86_64 LLVM=1 mrproper {def,amd_mem_encrypt.,fortify_source.,llvm_cov.}config bzImage
```
The issue is that symbol `__profc__Z13sized_strscpyPcU25pass_dynamic_object_size1PKcU25pass_dynamic_object_size1m` is undefined in `vmlinux` but defined as a weak symbol in `vmlinux.o`:
```bash
$ nm -C vmlinux | grep __profc__Z13sized_strscpyPcU25pass_dynamic_object_size1PKcU25pass_dynamic_object_size1m
U __profc__Z13sized_strscpyPcU25pass_dynamic_object_size1PKcU25pass_dynamic_object_size1m
$ nm -C vmlinux.o | grep __profc__Z13sized_strscpyPcU25pass_dynamic_object_size1PKcU25pass_dynamic_object_size1m
0000000000000000 V __profc__Z13sized_strscpyPcU25pass_dynamic_object_size1PKcU25pass_dynamic_object_size1m
```
Other similar symbols, however, seem to be processed correctly:
```bash
$ nm -C vmlinux | grep __profc__Z7strlcatPcU25pass_dynamic_object_size1PKcU25pass_dynamic_object_size1m
ffffffff84366920 d __profc__Z7strlcatPcU25pass_dynamic_object_size1PKcU25pass_dynamic_object_size1m
$ nm -C vmlinux.o | grep __profc__Z7strlcatPcU25pass_dynamic_object_size1PKcU25pass_dynamic_object_size1m
0000000000000000 V __profc__Z7strlcatPcU25pass_dynamic_object_size1PKcU25pass_dynamic_object_size1m
```
Because the symbol is undefined in the final kernel image, all instructions referencing it now accesses address `0x0`, which triggers kernel panics. This seems to be an issue with `lld` when producing the `vmlinux.o` file, since if we produce `vmlinux.o` with `mold`, the symbol will be properly defined.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMV11v2zoS_TX0y0CGTNmy_eCHVI73BtdpgjTtovsiUORIYkKRAknZcX_9gpKdD29bFNjmokIgIOLwzDn0fJE5JyuNuCKzD2S2HrHO18auHqSuamaiB8lGhRGH1b8RmEXgnbWovTrA3thHqSswGqTmxrbGMh8-bLdfriNuduAN-BphK3X3BI9oNaox_GX2uENLaEbiNYkvpAeH2DjwNfNA0lgpQdIYLDZmh65HEFhKLb00GkwJ7MWDRcU8CnCHpjAKmAcldWA1YDvPKgSmBRQW2aMD09kTkcHi-KYJoQl88ti6wNpia43oOJLkZJHGw1_BXP28CYTZa2WY6FmqXqczneU4mFTSA1dGI1TSByy6IXRTST8-kjC2InTTdgWhG8cbQjc9CKGbwWCwJnTjjd0xJdzJYhw-9z64GByf6QHWturQC2644NAyz2t0w_q-Qg-19617JmXZPmDWXdE5tNxoj9qPuQmc9jVqbx66pj25jwJm2IVloFQjG6ipXRN52-nHSONT4H1ySze7ZBwTuonjeBL1dtzsIiZElCmmq8hFn_qDiwrmUESZERhlZoeWVRi5rm3HPRRENxGQeQbH_9rJn6CIfl_RdRats568sf5P5p9ET4s0EtKxQuGLFqmdt12D2rOQe3-ygmmvAPVbAb909C8pU3RSDal8zL5-BXltgNB5dvNxc_WvPNSePLv5kv99effxckuS9WGwO1-_vbvZXG0v84vtYETnQJLL57zmRpeyOinMudmNh0-vvB4hNzd391ebr_mnm8932WUA-wFSaayX5SEfatAP8S6u1_n15XV--TG7-3p7fwJklteEbp4W6RtQ1oi8wSZHze2h9W9QG_aIED0-EEoJnRK60K01nNAloRQu7rK_SLJ-WqR5Ou1rNknWE2hsa02LFsj8g8CS0OzcA6HZmRJCs-dTIvP1QAGKb1cNq_CsQr_-Ve9rBOlcF95Dgzl2CpLGed5aU_I8_88kcfIbitx563h7uOWf6axlzuXioFkjeW6KB-Q-D1aT279_utyE3iUddLpvWihA6uBt1wxVOo2h6DycFpkDBntkjydib6zHJuj5aQ-agm4gyuC4ow_wymIL7yWv9wuf3xf_B-rG5h_SF5898OWd9X4veG98jRacbKRi9hgfjtAM6ucRqh-dwsRSIITMQ-dQADfWIvfq8H-Hztx5qzjzv0NjeXwW0yRNlzQG8U6OfjFsfqfLn8bLb9X2vUD5gJx1DvvOdSojZxUoLJVSM3VsbSD7ykkzYCoUndDoeWjyDiyWaFHzMMpLD9rsgfE-shwwISw6F0pU_NTToBnsa8lr8FZWFVp3ctAyLbkbw30t3WnC7-OU6WNJ3ktfvxr4w0QAw9wdXAfGZ5UQSql6zk5qjiBL2ONxx__antAb08OHba_OZy-VOiZNi1YdTgV5PBKrRCyTJRvhajJPJst4Ei_oqF4hYjljmJbLYi7ELEVGl3EyFWmRsJng05Fc0ZhOJ5PJIk6SRUzHHMWyTCbFki2LWZHGZBpjw6Qah1YWRv9Rfw6rySSdzWcjxQpUrr-GURrOhNJwH7OrfpwpusqRaayk8-4FwEuv-pvbdrsmszVst2voND61yD0KdXi-RZ3foF61nFFn1ert4DYMbcdJLTg7zWGtNSEkCd301MN4cGS_W9H_BgAA__9OZMf6">