[PATCH] ld: Avoid moving desired relro end below relro section

Alan Modra amodra@gmail.com
Mon Feb 17 06:29:38 GMT 2025


On Mon, Feb 17, 2025 at 04:56:57AM +0800, H.J. Lu wrote:
> On Sun, Feb 16, 2025 at 12:38 PM Alan Modra <amodra@gmail.com> wrote:
> >
> > On Sun, Feb 16, 2025 at 06:19:07AM +0800, H.J. Lu wrote:
> > > --- a/ld/ldlang.c
> > > +++ b/ld/ldlang.c
> > > @@ -6605,10 +6605,16 @@ lang_size_relro_segment_1 (void)
> > >       end = start = sec->vma;
> > >       if (!IS_TBSS (sec))
> > >         end += TO_ADDR (sec->size);
> > > -     bump = desired_end - end;
> > > -     /* We'd like to increase START by BUMP, but we must heed
> > > -        alignment so the increase might be less than optimum.  */
> > > -     start += bump;
> > > +     if (desired_end > end)
> > > +       {
> > > +         /* Avoid moving START backwards.  */
> > > +         bump = desired_end - end;
> > > +         /* We'd like to increase START by BUMP, but we must heed
> > > +            alignment so the increase might be less than optimum.  */
> > > +         start += bump;
> > > +       }
> > > +     else
> > > +       start = end;
> > >       start &= ~(((bfd_vma) 1 << sec->alignment_power) - 1);
> > >       /* This is now the desired end for the previous section.  */
> > >       desired_end = start;
> >
> > This doesn't make any sense at all.  You're putting sections on top of
> > each other!
> >
> > The assert failure can't be fixed by totally breaking this function.
> >
> > Look instead at why sections now don't fit.  Have they changed in size
> > since the time seg->relro_end and seg->base were set?
> 
> When setting seg->base to 0x2f3000, there are:
> 
> section       vma           size      vma + size    alignment
> .got   0x2c2118   0x0    0x2c2118   8
> .dynamic   0x2c20e8   0x0    0x2c20e8   8
> .data.rel.ro   0x298020   0x0    0x298020   32
> .fini_array   0x298008   0x0    0x298008   8
> .init_array   0x298000   0x0    0x298000   8

Something doesn't add up here.  The change in vma indicates the size
of .init_array is 8, .fini_array between 0 and 0x18, .data.rel.ro is
0x2a0c8, .dynamic is 0x30.

> 
> When setting seg->relro_end to 0x320fe8 after that, there are
> 
> section       vma           size      vma + size    alignment
> .got   0x320268   0xd80    0x320fe8   8
> .dynamic   0x31ffe8   0x280    0x320268   8
> .data.rel.ro   0x2f3020   0x2cfc8    0x31ffe8   128
> .fini_array   0x2f3008   0x8    0x2f3010   8
> .init_array   0x2f3000   0x8    0x2f3008   8

Lot's of things changed according to this, including .data.rel.ro
alignment.  There can be multiple iterations of layout and sizing.

For the iteration of lang_size_relro_segment_1 that failed the
assertion, what were the most recent assignments to relro_end and
base?  After those particular assignments, did any relro section size
or alignment change?  If they did, you've found the real problem.

> 
> All section sizes are 0 when setting seg->base.
> 
> -- 
> H.J.

-- 
Alan Modra


More information about the Binutils mailing list