[PATCH] ld: Avoid moving desired relro end below relro section
H.J. Lu
hjl.tools@gmail.com
Mon Feb 17 07:20:43 GMT 2025
On Mon, Feb 17, 2025 at 2:29 PM Alan Modra <amodra@gmail.com> wrote:
>
> 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
lang_size_relro_segment_1 failed at the first interation.
> 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.
There were no changes in size nor alignment after he most recent
assignments to relro_end and base before lang_size_relro_segment_1
was called.
(gdb) run
...
Hardware watchpoint 2: expld.dataseg.base
Old value = 0
New value = 2719744
fold_segment_align (lhs=0x7fffffffb350)
at /export/gnu/import/git/gitlab/x86-binutils/ld/ldexp.c:487
487 seg->commonpagesize = commonpage;
(gdb) c
Continuing.
Hardware watchpoint 3: expld.dataseg.relro_end
Old value = 0
New value = 2892056
fold_segment_relro_end (lhs=0x7fffffffb350)
at /export/gnu/import/git/gitlab/x86-binutils/ld/ldexp.c:519
519 if (seg->phase == exp_seg_relro_adjust
(gdb)
Continuing.
Hardware watchpoint 2: expld.dataseg.base
Old value = 2719744
New value = 3092480
fold_segment_align (lhs=0x7fffffffb350)
at /export/gnu/import/git/gitlab/x86-binutils/ld/ldexp.c:487
487 seg->commonpagesize = commonpage;
(gdb)
Continuing.
Hardware watchpoint 3: expld.dataseg.relro_end
Old value = 2892056
New value = 0
fold_segment_align (lhs=0x7fffffffb350)
at /export/gnu/import/git/gitlab/x86-binutils/ld/ldexp.c:496
496 }
(gdb)
Continuing.
Hardware watchpoint 3: expld.dataseg.relro_end
Old value = 0
New value = 3280872
fold_segment_relro_end (lhs=0x7fffffffb350)
at /export/gnu/import/git/gitlab/x86-binutils/ld/ldexp.c:519
519 if (seg->phase == exp_seg_relro_adjust
(gdb) call debug_vma ()
section vma size vma + size alignment
.got (0x6f91130) 0x320268 0xd80 0x320fe8 8
.dynamic (0x6f91008) 0x31ffe8 0x280 0x320268 8
.data.rel.ro (0x6f90ee0) 0x2f3020 0x2cfc8 0x31ffe8 128
.fini_array (0x6f90db8) 0x2f3008 0x8 0x2f3010 8
.init_array (0x6f80a60) 0x2f3000 0x8 0x2f3008 8
(gdb) c
Continuing.
Breakpoint 1, lang_size_relro_segment_1 ()
at /export/gnu/import/git/gitlab/x86-binutils/ld/ldlang.c:6616
6616 seg_align_type *seg = &expld.dataseg;
(gdb) call debug_vma ()
section vma size vma + size alignment
.got (0x6f91130) 0x320268 0xd80 0x320fe8 8
.dynamic (0x6f91008) 0x31ffe8 0x280 0x320268 8
.data.rel.ro (0x6f90ee0) 0x2f3020 0x2cfc8 0x31ffe8 128
.fini_array (0x6f90db8) 0x2f3008 0x8 0x2f3010 8
.init_array (0x6f80a60) 0x2f3000 0x8 0x2f3008 8
(gdb)
H.J.
More information about the Binutils
mailing list