<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/92864>92864</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
lld sometimes does not generate PHDRs for orphaned input sections
</td>
</tr>
<tr>
<th>Labels</th>
<td>
lld
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
mintsuki
</td>
</tr>
</table>
<pre>
Hello,
The following was tested with LLVM/Clang version 17.0.6.
lld and ld.bfd differ in behaviour if there are orphaned input sections, and if there aren't other non-orphaned input sections triggering the output of an appropriate PHDR, even if said PHDR is explicitly defined in the linker script.
Reproducer: https://github.com/limine-bootloader/limine-c-template/archive/cd873447da8d405905285d325c13e43e0b473670.tar.gz
Usage (in extracted directory):
```sh
make -C kernel clean all KCC=clang KLD=ld.lld # To build with clang/ld.lld
make -C kernel clean all KCC=gcc KLD=ld.bfd # To build with gcc/ld.bfd
```
Then, running `llvm-readelf -l` on `kernel/bin/kernel`, we get the following 2 outputs:
With clang/ld.lld:
```
Elf file type is DYN (Shared object file)
Entry point 0xffffffff80001270
There are 4 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x001000 0xffffffff80000000 0xffffffff80000000 0x000080 0x000080 RW 0x1000
LOAD 0x002000 0xffffffff80001000 0xffffffff80001000 0x00036d 0x00036d R E 0x1000
LOAD 0x003000 0xffffffff80002000 0xffffffff80002000 0x000090 0x000090 RW 0x1000
DYNAMIC 0x003000 0xffffffff80002000 0xffffffff80002000 0x000090 0x000090 RW 0x8
Section to Segment mapping:
Segment Sections...
00 .requests
01 .text .dynsym .gnu.hash .hash .dynstr
02 .dynamic
03 .dynamic
None .debug_loclists .debug_abbrev .debug_info .debug_rnglists .debug_str_offsets .debug_str .debug_addr .comment .debug_frame .debug_line .debug_line_str .symtab .shstrtab .strtab
```
With gcc/ld.bfd:
```
Elf file type is EXEC (Executable file)
Entry point 0xffffffff80001110
There are 5 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x001000 0xffffffff80000000 0xffffffff80000000 0x000080 0x000080 RW 0x1000
LOAD 0x002000 0xffffffff80001000 0xffffffff80001000 0x00018b 0x00018b R E 0x1000
LOAD 0x003000 0xffffffff80002000 0xffffffff80002000 0x00004c 0x00004c R 0x1000
LOAD 0x004000 0xffffffff80003000 0xffffffff80003000 0x0000e0 0x0000e0 RW 0x1000
DYNAMIC 0x004000 0xffffffff80003000 0xffffffff80003000 0x0000e0 0x0000e0 RW 0x8
Section to Segment mapping:
Segment Sections...
00 .requests
01 .text
02 .dynsym .dynstr .hash .gnu.hash
03 .dynamic
04 .dynamic
None .debug_info .debug_abbrev .debug_loclists .debug_aranges .debug_rnglists .debug_line .debug_str .debug_line_str .comment .symtab .strtab .shstrtab
```
As one can see, the lld version of the created file lacks an appropriate read-only PHDR, despite one being defined in the linker script (`kernel/linker.ld`), because there are no input sections for the compiled template kernel matching the names `.rodata/.rodata.*`, thus not triggering the creation of the `rodata` PHDR as described in the linker script.
This causes the orphaned input sections `.dynsym .gnu.hash .hash .dynstr` to be assigned to the `text` PHDR instead, giving them unintended executable permissions, thus also being a potential security issue.
It also does not align with what ld.bfd does.
Is there something I am missing in the reproducer, like a flag or linker script directive, that would ensure consistent behaviour here? (Preferably BFD's) Or if this is an LLD bug, it would be nice if it was fixed in coming versions.
Thanks!
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWEtv4zgS_jX0pRCBpvw8-JCxY3Rj0g-ke6d3TgNKLEncUKSWpJJ4fv2ClGzJsdMIsLPYyxiBVHzUi1X8VBXunCw14obMfyHz3YS3vjJ2U0vtXfsoJ5kRh80HVMoQtiV0R-ht9_xeIRRGKfMsdQnP3IFH51HAs_QV3N__9omw_VZxXcITWieNhukyockiGUtRSgDXApRIskKAkEWBFqSGDCv-JE1rQRbgK7QI3CIY21RcowCpm9aDw9xLox1h2yhmvFcTtvRgwhi00TdvsIK3sizRBi98hWBaH5ZNAVwDbxprGiu5R_j6YfcQ9OAT6qDIcSniJEgH-NIomUuvDiCwkJ2aKE9J_YgWXG5l4898f8DGGtHmaEl6C5X3jSPpLWF7wval9FWbJbmpCdsrWUuNN5kxXhku0A5z-Y3HulHcI2F7bvNKPgUqF6tlOpstBV-JGZ2v6Zyt5iJl83ya4ixFms2W6WJJE89tUv45tuofjpcIhK2kBnzxluchqEJazL2xB8LWwciOYUG7P1d1EzV_RLjZwiNajQpyheEMlYJft1uS7vKYDb_e70i6UyIJsScshe8GslaqPnPipuBg3PAuuWWeD1JDGl1KLfO8k5kV4pXxp3TWIbq21TqkAllQpZ7qG4tcoCrgRpEFBaPDQmcGYftMasL2_XBBA_8zQok-Rn64HazPKjccXXz-uOLwxeF2wztVQCEVgj80GDJu9_vnEKVvFbcowGT_wtzHHSFCHYv29gCNkdoDfSn634pSOmXLwe3-Zs2gsaa0vIYquGzjnXKeWx884OFGFA49LGZjD772PB96nqP1AN-DncPvS8cN8Ju0_lYIC1-rg4vE8NtLhd_knwCfsI5v2KsSbpUs9VHs_Zfb3YiDvlA6pZS-cpC-ORVeqxHx8CMICSLONIR1dinkiqrpSW66EAPxAHfX5J5bnl6Ku6KUDZavR8Sl5bvfP99--rj9izWsxvGGbx1sgjfwDcsatYeaN43U5Sj2x5V-s0uS5LgElEbjEov_btF5B8PKtFvx-OIhEQftDjUkpW6TirsK-meY93bExToucdC8lvloIX1j4bPRGBcwa8s_lMmVDHb0Y55lFp-OI6kLc6StLs92Om__6C7FeOokJ6R2APB4Ev1kYXmNJ81Sn9EdtzvUnmeQuMp521HxfRUVflxg23vh4-6fd9uAH3cvmLeeZwrfDR7T6QV4zP8Gj_8SPKarbCD-N-AxywfiAa5afq5hdinuitJ00IAj4l3w9Bdo-P_A0zX4iXDVw1MPVifwGqPSFaiavQuqxmB0DlMXIGa5LtG9hVxj5BlB1gBCJ9g6odERi6qfoFH3vHUQrM65BocYgCCWwUqc-gATq3TILfJQW0ZcUjx_dK9L7lB83RitDqfiW6BrpMeoIcMALj8rtwPAjeu1bjFRIhZr6yAww5y3DkcthjavO4TC2M5gUzdSoYBjzX0sSGvu8-rYQGheowtlYmKN4J4Ttu-phLDbvkz0VetAG_-6-4hnMjojsqC9lAXtmg3uwiHkVmbv6TG-V9JB9NB13c0bTVAw9-df3GCAN5Ah9C2jCMPexnAnThZK7TxyEdws5VPvWQ2tltqjFigAh49Og7aWzh2buHguXDnTR5dDYzxqL7kKxrZW-gNI51o8c_Oj75iEwe5YeYD9rvR_rrg_9ZcG3Tmj6yPvTI0-xvAj8BqiTbo8HrAdWjW2BSUfETgUipdg7KuU6zql2IYFd7iHZ9MqAahda0MOaSddcGnU4gYLSLoP6frVYoGWZ-oAv-x3hC0dYWv40rfB0oVvN9dwf7-DrC2DDnnUkCFomWPYGea4g0K-dEmSm1oOjbh7lSJcPzrCphOxScU6XfMJbqbL6YItWcropNoIni_SGSITYrkSKS75jGZ0zop0vhJiySZywyib0Tmb0sV0NaPJas7pOl3imrM8XRcLMqNYc6mS0FMlxpaTGMPNmq0Ws4niGSoX_wPBWOiBGCPz3cRuYgeWtaUjMxoBbOD30ivcBFSJkZPhzp2iX6JGe-zZu_v7RuJPWqs2P2u91dPxddNYE5oswvbReEfYPtr_nwAAAP__J99Tlg">