This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] PR ld/16322: ld fails to generate GNU_RELRO segment
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: "H.J. Lu" <hjl dot tools at gmail dot com>, Binutils <binutils at sourceware dot org>, Nick Clifton <nickc at redhat dot com>
- Date: Thu, 9 Jan 2014 04:08:17 -0800
- Subject: Re: [PATCH] PR ld/16322: ld fails to generate GNU_RELRO segment
- Authentication-results: sourceware.org; auth=none
- References: <20131212185803 dot GA2434 at intel dot com> <CAMe9rOo+hnJPNUwb3fWqx=HjWvBs+Ekrv+zRgu3F_Rr0KZ1Cjw at mail dot gmail dot com> <CAMe9rOpN28KDu8JzYoaK1b5G12S6DuGAkxOxYnyMk6T2y8iv3A at mail dot gmail dot com> <20140109041304 dot GF31693 at bubble dot grove dot modra dot org>
On Wed, Jan 8, 2014 at 8:13 PM, Alan Modra <amodra@gmail.com> wrote:
> On Wed, Jan 08, 2014 at 06:01:49AM -0800, H.J. Lu wrote:
>> >> + /* If PT_LOAD segment doesn't fit PT_GNU_RELRO segment,
>> >> + adjust its p_filesz and p_memsz. */
>
> This is broken. What if there is another LOAD segment following
> the one you're adjusting?
It will only happen with a costumer linker script using
DATA_SEGMENT_ALIGN, DATA_SEGMENT_RELRO_END,
DATA_SEGMENT_END. Do you have a testcase? We can
either ignore relro or issue an error.
>> >> if (expld.dataseg.base - (1 << max_alignment_power) < old_base)
>> >> expld.dataseg.base += expld.dataseg.pagesize;
>> >> - expld.dataseg.base -= (1 << max_alignment_power);
>> >> + /* Properly align base to max_alignment_power. */
>> >> + expld.dataseg.base &= ~((1 << max_alignment_power) - 1);
>> >> lang_reset_memory_regions ();
>> >> one_lang_size_sections_pass (relax, check_regions);
>
> This also doesn't look correct to me. Please explain why you think
> this is a good idea.
There are
if (expld.dataseg.relro_end > relro_end)
{
/* The alignment of sections between DATA_SEGMENT_ALIGN
and DATA_SEGMENT_RELRO_END caused huge padding to be
inserted at DATA_SEGMENT_RELRO_END. Try to start a bit lower so
that the section alignments will fit in. */
asection *sec;
unsigned int max_alignment_power = 0;
/* Find maximum alignment power of sections between
DATA_SEGMENT_ALIGN and DATA_SEGMENT_RELRO_END. */
for (sec = link_info.output_bfd->sections; sec; sec = sec->next)
if (sec->vma >= expld.dataseg.base
&& sec->vma < expld.dataseg.relro_end
&& sec->alignment_power > max_alignment_power)
max_alignment_power = sec->alignment_power;
if (((bfd_vma) 1 << max_alignment_power) < expld.dataseg.pagesize)
{
if (expld.dataseg.base - (1 << max_alignment_power) < old_base)
expld.dataseg.base += expld.dataseg.pagesize;
/* Properly align base to max_alignment_power. */
expld.dataseg.base &= ~((1 << max_alignment_power) - 1);
lang_reset_memory_regions ();
one_lang_size_sections_pass (relax, check_regions);
}
}
link_info.relro_start = expld.dataseg.base;
link_info.relro_end = expld.dataseg.relro_end;
max_alignment_power is the maximum alignment of sections
between DATA_SEGMENT_ALIGN and DATA_SEGMENT_RELRO_END.
If expld.dataseg.base (link_info.relro_start) isn't aligned to
max_alignment_power, some sections won't fit into RELRO
segment. If you have a testcase to show it doesn't some
cases correctly, I will fix it.
Thanks.
--
H.J.