<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">