[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