[PATCH] Linux/x86: Enable --rosegment by default

Fangrui Song i@maskray.me
Fri Mar 20 03:34:29 GMT 2026


On Wed, Mar 18, 2026 at 9:11 PM hev <r@hev.cc> wrote:
>
> On Thu, Mar 19, 2026 at 11:15 AM Fangrui Song <i@maskray.me> wrote:
> >
> > On Wed, Mar 18, 2026 at 7:56 PM hev <r@hev.cc> wrote:
> > >
> > > On Thu, Mar 19, 2026 at 10:06 AM Fangrui Song <i@maskray.me> wrote:
> > > > For x86, --no-rosegment -z noseparate-code -z max-page-size=2097152 is
> > > > the most compact layout that works with transparent hugepages.
> > > > Google and ChromeOS have been using such a layout for a long time.
> > >
> > > --no-rosegment -z noseparate-code -z max-page-size=2097152 is somewhat
> > > more compact than --no-rosegment -z separate-code -z
> > > max-page-size=2097152. However, due to alignment, there is still a
> > > sizable gap between the RE and RW segments, which significantly
> > > increases the file size (e.g. hello world: 6K -> 2.1M). This is almost
> > > impractical with 32M huge pages.
> > >
> > >   LOAD           0x0000000000000000 0x0000000000000000
> > > 0x0000000000000000
> > >                  0x0000000000000738 0x0000000000000738  R E
> > > 0x200000
> > >   LOAD           0x00000000001ffe10 0x00000000003ffe10 0x00000000003ffe10
> > >                  0x0000000000000200 0x0000000000000208  RW     0x200000
> >
> > This is due to the suboptimal PT_GNU_RELRO layout in GNU ld. See
> > https://sourceware.org/bugzilla/show_bug.cgi?id=30612
> > mold and ld.lld avoid this issue by introducing the .relro_padding
> > section. lld's implementation also emulates
> > DATA_SEGMENT_ALIGN/DATA_RELRO_END.
> >
> > https://maskray.me/blog/2020-11-15-explain-gnu-linker-options#z-relro
> >
> > """
> > GNU ld uses one RW PT_LOAD program header with padding at the start.
> > The first half of the PT_LOAD overlaps with PT_GNU_RELRO. The padding
> > is added so that the end of PT_GNU_RELRO is aligned by max-page-size.
> > (See ld.bfd --verbose output.) Prior to GNU ld 2.39, the end was
> > aligned by common-page-size. GNU ld's one RW PT_LOAD layout makes the
> > alignment increase the file size. max-page-size can be large, such as
> > 65536 for many systems, causing wasted space.
> >
> > lld utilitizes two RW PT_LOAD program headers: one for RELRO sections
> > and the other for non-RELRO sections. Although this might appear
> > unusual initially, it eliminates the need for alignment padding as
> > seen in GNU ld's layout. Key changes:
> >
> > https://reviews.llvm.org/D58892 switched from
> > PT_LOAD(PT_GNU_RELRO(.data.rel.ro .bss.rel.ro) .data .bss) to
> > PT_LOAD(PT_GNU_RELRO(.data.rel.ro .bss.rel.ro)) PT_LOAD(.data. .bss).
> > The end of the PT_GNU_RELRO segment and the associated RW PT_LOAD
> > segment is padded to a common-page-size boundary. The padding section
> > .relro_padding is like mold. Before LLD 18, there is an issue that
> > runtime_page_size < common-page-size does not work.
> >
> > The layout used by mold is similar to that of lld. In mold's case, the
> > end of PT_GNU_RELRO is padded to max-page-size by appending a
> > SHT_NOBITS .relro_padding section. This approach ensures that the last
> > page of PT_GNU_RELRO is protected, regardless of the system page size.
> > However, when the system page size is less than max-page-size, the map
> > from the first RW PT_LOAD is larger than needed.
> > """
>
> Thanks for the explanation.
>
> With -z separate-code --rosegment, the segments are page-aligned, so
> there’s no overlap when mapped.
>
> With the default -z noseparate-code --rosegment, read-only data ends
> up in a non-executable segment, but since the layout is packed, the RO
> and RX segments aren’t fully separated. From a THP-friendly
> perspective, I’m curious what you think about LLD defaulting to
> --no-rosegment?
>
> Thanks,
> Rui

No, ld.lld will not switch to --no-rosegment.

* THP preferences are better managed through compiler driver options
rather than changing the fundamental defaults of the linker itself.
* Maintaining separate segments for different permissions has
aesthetic benefits.
* Changing the default will break 475 tests, causing unneeded churn.


More information about the Binutils mailing list