This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: PR ld/4504: Copy relocation doesn't preserve section alignment
On Wed, May 16, 2007 at 11:50:42AM +0930, Alan Modra wrote:
> On Tue, May 15, 2007 at 06:46:20AM -0700, H. J. Lu wrote:
> > + orig_power_of_two = bfd_get_section_alignment (sec->owner, sec);
> > +
> > + if (orig_power_of_two > power_of_two)
> > + {
> > + /* Adjust the section alignment if needed. */
> > + if (! bfd_set_section_alignment (dynbss->owner, dynbss,
> > + orig_power_of_two))
> > + return FALSE;
> > + }
> > +
> > + /* We make sure that the symbol will be aligned properly. Since we
> > + don't know its alignment requirement, we start with the maximum
> > + alignment and check low bits of the symbol address for the
> > + minimum alignment. */
> > + mask = ((bfd_vma) 1 << orig_power_of_two) - 1;
> > + while ((h->root.u.def.value & mask) != 0)
> > + {
> > + mask >>= 1;
> > + --orig_power_of_two;
> > + }
>
> You didn't put this loop where I suggested, before setting .dynbss
> alignment. Why? There is no need to align .dynbss more than the
> required symbol alignment.
>
Like this?
H.J.
---
2007-05-15 H.J. Lu <hongjiu.lu@intel.com>
* elflink.c (_bfd_elf_adjust_dynamic_copy): Align dynamic bss
section to the minimum alignment.
--- bfd/elflink.c.foo 2007-05-15 20:53:44.000000000 -0700
+++ bfd/elflink.c 2007-05-15 21:00:23.000000000 -0700
@@ -2656,33 +2656,33 @@ bfd_boolean
_bfd_elf_adjust_dynamic_copy (struct elf_link_hash_entry *h,
asection *dynbss)
{
- unsigned int power_of_two, orig_power_of_two;
+ unsigned int power_of_two;
bfd_vma mask;
asection *sec = h->root.u.def.section;
/* The section aligment of definition is the maximum alignment
- requirement of symbols defined in the section. */
- power_of_two = bfd_get_section_alignment (dynbss->owner, dynbss);
- orig_power_of_two = bfd_get_section_alignment (sec->owner, sec);
+ requirement of symbols defined in the section. Since we don't
+ know the symbol alignment requirement, we start with the
+ maximum alignment and check low bits of the symbol address
+ for the minimum alignment. */
+ power_of_two = bfd_get_section_alignment (sec->owner, sec);
+ mask = ((bfd_vma) 1 << power_of_two) - 1;
+ while ((h->root.u.def.value & mask) != 0)
+ {
+ mask >>= 1;
+ --power_of_two;
+ }
- if (orig_power_of_two > power_of_two)
+ if (power_of_two > bfd_get_section_alignment (dynbss->owner,
+ dynbss))
{
/* Adjust the section alignment if needed. */
if (! bfd_set_section_alignment (dynbss->owner, dynbss,
- orig_power_of_two))
+ power_of_two))
return FALSE;
}
- /* We make sure that the symbol will be aligned properly. Since we
- don't know its alignment requirement, we start with the maximum
- alignment and check low bits of the symbol address for the
- minimum alignment. */
- mask = ((bfd_vma) 1 << orig_power_of_two) - 1;
- while ((h->root.u.def.value & mask) != 0)
- {
- mask >>= 1;
- --orig_power_of_two;
- }
+ /* We make sure that the symbol will be aligned properly. */
dynbss->size = BFD_ALIGN (dynbss->size, mask + 1);
/* Define the symbol as being at this point in DYNBSS. */