[PATCH] ld: Disable separate code by default for Linux/x86
H.J. Lu
hjl.tools@gmail.com
Tue Mar 17 02:15:16 GMT 2026
On Mon, Mar 16, 2026 at 7:11 PM hev <r@hev.cc> wrote:
>
> On Tue, Mar 17, 2026 at 9:47 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > On Mon, Mar 16, 2026 at 5:27 PM hev <r@hev.cc> wrote:
> > >
> > > On Tue, Mar 17, 2026 at 5:47 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > >
> > > > > One benefit of -z noseparate-code is that the executable PT_LOAD ends
> > > > > up at virtual address 0 with file offset 0. For huge page mappings,
> > > > > both the virtual address and the file offset need to be aligned to the
> > > > > huge page size, e.g.
> > > > >
> > > > > ((p_vaddr | p_offset) & (HUGE_PAGE_SIZE - 1)) == 0
> > > > >
> > > > > Are you suggesting that, with the -z separate-code layout, ld.so would
> > > > > ignore the non-executable flag of the first PT_LOAD and merge it with
> > > > > the second PT_LOAD, mapping them together as read-only executable?
> > > > > That might help with existing binaries, but wouldn't it blur the
> > > > > permission boundaries between segments?
> > > > >
> > > >
> > > > That is correct. It should have the similar effect as -z noseparate-code.
> > > > The difference is link-time vs run-time. Of course, ld.so should do it only
> > > > when huge page is in use.
> > >
> > > Having ld.so transparently merge the mappings doesn't always seem
> > > workable. For example, in chromium the RE segment has different
> > > virtual addresses and file offsets, so we can't construct a correct
> > > mapping when attempting to merge them.
> > >
> > > LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
> > > 0x00000000014d2b2c 0x00000000014d2b2c R 0x1000
> > > LOAD 0x00000000014d3000 0x00000000014d4000 0x00000000014d4000
> > > 0x000000000fb7a420 0x000000000fb7a420 R E 0x1000
> > > LOAD 0x000000001104d420 0x000000001104f420 0x000000001104f420
> > > 0x0000000000ac0f58 0x0000000000ac1be0 RW 0x1000
> > > LOAD 0x0000000011b0f000 0x0000000011b12000 0x0000000011b12000
> > > 0x0000000000146001 0x0000000000428d34 RW 0x1000
> > >
> >
> > This layout won't work. It can be an option for compatible layouts. For
> > ld on Linux/x86, we can default to --rosegment.
>
> With -z separate-code + --rosegment, the layout appears as RE, R, and
> RW, which also looks reasonable.
I think ld.so can map RE + R to RE when huge page is enabled if it
is shown to improve performance.
> With -z noseparate-code + --no-rosegment, the RE and R segments are
> merged, resulting in RE and RW.
>
> One advantage of the latter is that read-only data can also benefit
> from huge page mappings. In addition, the merged segment has a better
> chance of being mapped with huge pages. Since a PMD-sized huge page is
> 2 MB, a segment shorter than that cannot use it. Merging segments
> increases the total size, making PMD usage more likely.
>
> Thanks,
> Rui
--
H.J.
More information about the Libc-alpha
mailing list