[PATCH] PR ld/16322: ld fails to generate GNU_RELRO segment
H.J. Lu
hjl.tools@gmail.com
Thu Jan 9 12:08:00 GMT 2014
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.
More information about the Binutils
mailing list