This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] PR ld/16322: ld fails to generate GNU_RELRO segment


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]