PATCH: PR ld/4504: Copy relocation doesn't preserve section alignment
H. J. Lu
hjl@lucon.org
Tue May 15 00:50:00 GMT 2007
On Mon, May 14, 2007 at 03:51:49PM -0700, H. J. Lu wrote:
> On Mon, May 14, 2007 at 12:52:44PM -0700, H. J. Lu wrote:
> > This patch fixes the longstanding ELF linker bug by applying
> > the maximum alignment to all symbols needing copy relocation. We
> > can get the maximum alignment from the section alignment where
> > they are defined.
> >
> >
>
> Here are an updated patch and a testcase patch.
>
> There may be more than one shared libraries with different section
> alignments. The alignment of .dynbss is the maximum alignment among
> all section alignments. When we align the symbol in .dynbss, we only
> need to apply the current section alignment, not the maximum alignment
> of .dynbss.
>
>
We can move symbol setup and section size adjustment to the generic
function. Also shared libray can only guarantee symbol alignment up
to the page size. So my original test will fail on systems which don't
use copy relocation.
Here are updated patches. Tested on Linux/ia32/Intel64/ia64.
H.J.
-------------- next part --------------
2007-05-14 H.J. Lu <hongjiu.lu@intel.com>
PR ld/4504
* elf-bfd.h (_bfd_elf_adjust_dynamic_copy): New.
* elflink.c (_bfd_elf_adjust_dynamic_copy): New.
* elf-m10300.c (_bfd_mn10300_elf_adjust_dynamic_symbol): Call
_bfd_elf_adjust_dynamic_copy to adjust for the copy in dynamic
bss section.
* elf32-arm.c (elf32_arm_adjust_dynamic_symbol): Likewise.
* elf32-cris.c (elf_cris_adjust_dynamic_symbol): Likewise.
* elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol): Likewise.
* elf32-i370.c (i370_elf_adjust_dynamic_symbol): Likewise.
* elf32-i386.c (elf_i386_adjust_dynamic_symbol): Likewise.
* elf32-m32r.c (m32r_elf_adjust_dynamic_symbol): Likewise.
* elf32-m68k.c (elf_m68k_adjust_dynamic_symbol): Likewise.
* elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Likewise.
* elf32-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
* elf32-sh.c (sh_elf_adjust_dynamic_symbol): Likewise.
* elf32-vax.c (elf_vax_adjust_dynamic_symbol): Likewise.
* elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise.
* elf64-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
* elf64-sh64.c (sh64_elf64_adjust_dynamic_symbol): Likewise.
* elf64-x86-64.c (elf64_x86_64_adjust_dynamic_symbol): Likewise.
* elfxx-mips.c (_bfd_mips_vxworks_adjust_dynamic_symbol): Likewise.
* elfxx-sparc.c (_bfd_sparc_elf_adjust_dynamic_symbol): Likewise.
--- bfd/elf-bfd.h.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elf-bfd.h 2007-05-14 17:32:35.000000000 -0700
@@ -1740,6 +1740,9 @@ extern bfd_boolean _bfd_elf_fix_symbol_f
extern bfd_boolean _bfd_elf_adjust_dynamic_symbol
(struct elf_link_hash_entry *, void *);
+extern bfd_boolean _bfd_elf_adjust_dynamic_copy
+ (struct elf_link_hash_entry *, asection *);
+
extern bfd_boolean _bfd_elf_link_sec_merge_syms
(struct elf_link_hash_entry *, void *);
--- bfd/elf-m10300.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elf-m10300.c 2007-05-14 17:34:20.000000000 -0700
@@ -4096,7 +4096,6 @@ _bfd_mn10300_elf_adjust_dynamic_symbol (
{
bfd * dynobj;
asection * s;
- unsigned int power_of_two;
dynobj = elf_hash_table (info)->dynobj;
@@ -4236,28 +4235,7 @@ _bfd_mn10300_elf_adjust_dynamic_symbol (
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (dynobj, s))
- {
- if (! bfd_set_section_alignment (dynobj, s, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Set the sizes of the dynamic sections. */
--- bfd/elf32-arm.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elf32-arm.c 2007-05-14 17:32:06.000000000 -0700
@@ -8387,7 +8387,6 @@ elf32_arm_adjust_dynamic_symbol (struct
{
bfd * dynobj;
asection * s;
- unsigned int power_of_two;
struct elf32_arm_link_hash_entry * eh;
struct elf32_arm_link_hash_table *globals;
@@ -8500,28 +8499,7 @@ elf32_arm_adjust_dynamic_symbol (struct
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (dynobj, s))
- {
- if (! bfd_set_section_alignment (dynobj, s, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Allocate space in .plt, .got and associated reloc sections for
--- bfd/elf32-cris.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elf32-cris.c 2007-05-14 17:32:00.000000000 -0700
@@ -2221,7 +2221,6 @@ elf_cris_adjust_dynamic_symbol (info, h)
{
bfd *dynobj;
asection *s;
- unsigned int power_of_two;
bfd_size_type plt_entry_size;
dynobj = elf_hash_table (info)->dynobj;
@@ -2429,31 +2428,7 @@ elf_cris_adjust_dynamic_symbol (info, h)
h->needs_copy = 1;
}
- /* Historic precedent: m68k and i386 allow max 8-byte alignment for the
- thing to copy; so do we. */
-
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (dynobj, s))
- {
- if (!bfd_set_section_alignment (dynobj, s, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Look through the relocs for a section during the first phase. */
--- bfd/elf32-hppa.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elf32-hppa.c 2007-05-14 17:31:53.000000000 -0700
@@ -1819,7 +1819,6 @@ elf32_hppa_adjust_dynamic_symbol (struct
{
struct elf32_hppa_link_hash_table *htab;
asection *sec;
- unsigned int power_of_two;
/* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later. */
@@ -1929,30 +1928,9 @@ elf32_hppa_adjust_dynamic_symbol (struct
eh->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how other ELF linkers handle this. */
-
- power_of_two = bfd_log2 (eh->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
sec = htab->sdynbss;
- sec->size = BFD_ALIGN (sec->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (htab->etab.dynobj, sec))
- {
- if (! bfd_set_section_alignment (htab->etab.dynobj, sec, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- eh->root.u.def.section = sec;
- eh->root.u.def.value = sec->size;
- /* Increment the section size to make room for the symbol. */
- sec->size += eh->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (eh, sec);
}
/* Allocate space in the .plt for entries that won't have relocations.
--- bfd/elf32-i370.c.dynbss 2007-04-26 08:57:30.000000000 -0700
+++ bfd/elf32-i370.c 2007-05-14 17:32:22.000000000 -0700
@@ -461,7 +461,6 @@ i370_elf_adjust_dynamic_symbol (struct b
{
bfd *dynobj = elf_hash_table (info)->dynobj;
asection *s;
- unsigned int power_of_two;
#ifdef DEBUG
fprintf (stderr, "i370_elf_adjust_dynamic_symbol called for %s\n",
@@ -546,28 +545,7 @@ i370_elf_adjust_dynamic_symbol (struct b
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 4)
- power_of_two = 4;
-
- /* Apply the required alignment. */
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (dynobj, s))
- {
- if (! bfd_set_section_alignment (dynobj, s, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Increment the index of a dynamic symbol by a given amount. Called
--- bfd/elf32-i386.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elf32-i386.c 2007-05-14 17:32:45.000000000 -0700
@@ -1432,7 +1432,6 @@ elf_i386_adjust_dynamic_symbol (struct b
{
struct elf_i386_link_hash_table *htab;
asection *s;
- unsigned int power_of_two;
/* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later,
@@ -1560,28 +1559,7 @@ elf_i386_adjust_dynamic_symbol (struct b
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
- {
- if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Allocate space in .plt, .got and associated reloc sections for
--- bfd/elf32-m32r.c.dynbss 2007-04-26 08:57:30.000000000 -0700
+++ bfd/elf32-m32r.c 2007-05-14 17:32:52.000000000 -0700
@@ -1833,7 +1833,6 @@ m32r_elf_adjust_dynamic_symbol (struct b
struct elf_m32r_dyn_relocs *p;
bfd *dynobj;
asection *s;
- unsigned int power_of_two;
#ifdef DEBUG_PIC
printf ("m32r_elf_adjust_dynamic_symbol()\n");
@@ -1961,28 +1960,7 @@ m32r_elf_adjust_dynamic_symbol (struct b
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (dynobj, s))
- {
- if (! bfd_set_section_alignment (dynobj, s, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Allocate space in .plt, .got and associated reloc sections for
--- bfd/elf32-m68k.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elf32-m68k.c 2007-05-14 17:32:59.000000000 -0700
@@ -1215,7 +1215,6 @@ elf_m68k_adjust_dynamic_symbol (info, h)
struct elf_m68k_link_hash_table *htab;
bfd *dynobj;
asection *s;
- unsigned int power_of_two;
htab = elf_m68k_hash_table (info);
dynobj = elf_hash_table (info)->dynobj;
@@ -1360,28 +1359,7 @@ elf_m68k_adjust_dynamic_symbol (info, h)
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (dynobj, s))
- {
- if (!bfd_set_section_alignment (dynobj, s, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Set the sizes of the dynamic sections. */
--- bfd/elf32-ppc.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elf32-ppc.c 2007-05-14 17:33:05.000000000 -0700
@@ -4136,7 +4136,6 @@ ppc_elf_adjust_dynamic_symbol (struct bf
{
struct ppc_elf_link_hash_table *htab;
asection *s;
- unsigned int power_of_two;
#ifdef DEBUG
fprintf (stderr, "ppc_elf_adjust_dynamic_symbol called for %s\n",
@@ -4278,28 +4277,7 @@ ppc_elf_adjust_dynamic_symbol (struct bf
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 4)
- power_of_two = 4;
-
- /* Apply the required alignment. */
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
- {
- if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Generate a symbol to mark plt call stubs. For non-PIC code the sym is
--- bfd/elf32-s390.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elf32-s390.c 2007-05-14 17:33:21.000000000 -0700
@@ -1582,7 +1582,6 @@ elf_s390_adjust_dynamic_symbol (info, h)
{
struct elf_s390_link_hash_table *htab;
asection *s;
- unsigned int power_of_two;
/* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later
@@ -1703,29 +1702,9 @@ elf_s390_adjust_dynamic_symbol (info, h)
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
s = htab->sdynbss;
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
- {
- if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
- return FALSE;
- }
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Allocate space in .plt, .got and associated reloc sections for
--- bfd/elf32-sh.c.dynbss 2007-04-26 08:57:31.000000000 -0700
+++ bfd/elf32-sh.c 2007-05-14 17:33:28.000000000 -0700
@@ -2489,7 +2489,6 @@ sh_elf_adjust_dynamic_symbol (struct bfd
struct elf_sh_link_hash_entry *eh;
struct elf_sh_dyn_relocs *p;
asection *s;
- unsigned int power_of_two;
htab = sh_elf_hash_table (info);
@@ -2613,28 +2612,7 @@ sh_elf_adjust_dynamic_symbol (struct bfd
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (htab->root.dynobj, s))
- {
- if (! bfd_set_section_alignment (htab->root.dynobj, s, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Allocate space in .plt, .got and associated reloc sections for
--- bfd/elf32-vax.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elf32-vax.c 2007-05-14 17:33:34.000000000 -0700
@@ -925,7 +925,6 @@ elf_vax_adjust_dynamic_symbol (info, h)
{
bfd *dynobj;
asection *s;
- unsigned int power_of_two;
dynobj = elf_hash_table (info)->dynobj;
@@ -1079,28 +1078,7 @@ elf_vax_adjust_dynamic_symbol (info, h)
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (dynobj, s))
- {
- if (!bfd_set_section_alignment (dynobj, s, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Set the sizes of the dynamic sections. */
--- bfd/elf64-ppc.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elf64-ppc.c 2007-05-14 17:33:44.000000000 -0700
@@ -5799,7 +5799,6 @@ ppc64_elf_adjust_dynamic_symbol (struct
{
struct ppc_link_hash_table *htab;
asection *s;
- unsigned int power_of_two;
htab = ppc_hash_table (info);
@@ -5920,29 +5919,9 @@ ppc64_elf_adjust_dynamic_symbol (struct
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 4)
- power_of_two = 4;
-
- /* Apply the required alignment. */
s = htab->dynbss;
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
- {
- if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
- return FALSE;
- }
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* If given a function descriptor symbol, hide both the function code
--- bfd/elf64-s390.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elf64-s390.c 2007-05-14 17:33:51.000000000 -0700
@@ -1557,7 +1557,6 @@ elf_s390_adjust_dynamic_symbol (info, h)
{
struct elf_s390_link_hash_table *htab;
asection *s;
- unsigned int power_of_two;
/* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later
@@ -1678,29 +1677,9 @@ elf_s390_adjust_dynamic_symbol (info, h)
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
s = htab->sdynbss;
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
- {
- if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
- return FALSE;
- }
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Allocate space in .plt, .got and associated reloc sections for
--- bfd/elf64-sh64.c.dynbss 2007-04-26 08:57:32.000000000 -0700
+++ bfd/elf64-sh64.c 2007-05-14 17:34:03.000000000 -0700
@@ -3324,7 +3324,6 @@ sh64_elf64_adjust_dynamic_symbol (struct
{
bfd *dynobj;
asection *s;
- unsigned int power_of_two;
dynobj = elf_hash_table (info)->dynobj;
@@ -3464,28 +3463,7 @@ sh64_elf64_adjust_dynamic_symbol (struct
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (dynobj, s))
- {
- if (! bfd_set_section_alignment (dynobj, s, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* This function is called via sh_elf_link_hash_traverse if we are
--- bfd/elf64-x86-64.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elf64-x86-64.c 2007-05-14 17:34:12.000000000 -0700
@@ -1300,7 +1300,6 @@ elf64_x86_64_adjust_dynamic_symbol (stru
{
struct elf64_x86_64_link_hash_table *htab;
asection *s;
- unsigned int power_of_two;
/* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later,
@@ -1426,31 +1425,7 @@ elf64_x86_64_adjust_dynamic_symbol (stru
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. 16-bytes is the size
- of the largest type that requires hard alignment -- long double. */
- /* FIXME: This is VERY ugly. Should be fixed for all architectures using
- this construct. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 4)
- power_of_two = 4;
-
- /* Apply the required alignment. */
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
- {
- if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
- return FALSE;
- }
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Allocate space in .plt, .got and associated reloc sections for
--- bfd/elflink.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elflink.c 2007-05-14 17:43:58.000000000 -0700
@@ -2649,6 +2649,45 @@ _bfd_elf_adjust_dynamic_symbol (struct e
return TRUE;
}
+/* Adjust the dynamic symbol, H, for copy in the dynamic bss section,
+ DYNBSS. */
+
+bfd_boolean
+_bfd_elf_adjust_dynamic_copy (struct elf_link_hash_entry *h,
+ asection *dynbss)
+{
+ unsigned int power_of_two, orig_power_of_two;
+ asection *sec = h->root.u.def.section;
+
+ /* The section aligment of definition is the maximum alignment
+ requirement of symbols defined in the section. Since we don't
+ know the alignment requirement of individual symbols, we apply
+ the maximum alignment to all symbols needing dynamic copy. */
+ power_of_two = bfd_get_section_alignment (dynbss->owner, dynbss);
+ 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. */
+ dynbss->size = BFD_ALIGN (dynbss->size,
+ (bfd_size_type) (1 << orig_power_of_two));
+
+ /* Define the symbol as being at this point in DYNBSS. */
+ h->root.u.def.section = dynbss;
+ h->root.u.def.value = dynbss->size;
+
+ /* Increment the size of DYNBSS to make room for the symbol. */
+ dynbss->size += h->size;
+
+ return TRUE;
+}
+
/* Adjust all external symbols pointing into SEC_MERGE sections
to reflect the object merging within the sections. */
--- bfd/elfxx-mips.c.dynbss 2007-04-29 18:13:55.000000000 -0700
+++ bfd/elfxx-mips.c 2007-05-14 17:34:47.000000000 -0700
@@ -7045,7 +7045,6 @@ _bfd_mips_vxworks_adjust_dynamic_symbol
bfd *dynobj;
struct mips_elf_link_hash_entry *hmips;
struct mips_elf_link_hash_table *htab;
- unsigned int power_of_two;
htab = mips_elf_hash_table (info);
dynobj = elf_hash_table (info)->dynobj;
@@ -7168,26 +7167,7 @@ _bfd_mips_vxworks_adjust_dynamic_symbol
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 4)
- power_of_two = 4;
-
- /* Apply the required alignment. */
- htab->sdynbss->size = BFD_ALIGN (htab->sdynbss->size,
- (bfd_size_type) 1 << power_of_two);
- if (power_of_two > bfd_get_section_alignment (dynobj, htab->sdynbss)
- && !bfd_set_section_alignment (dynobj, htab->sdynbss, power_of_two))
- return FALSE;
-
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = htab->sdynbss;
- h->root.u.def.value = htab->sdynbss->size;
-
- /* Increment the section size to make room for the symbol. */
- htab->sdynbss->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, htab->sdynbss);
}
/* Return the number of dynamic section symbols required by OUTPUT_BFD.
--- bfd/elfxx-sparc.c.dynbss 2007-05-14 09:01:48.000000000 -0700
+++ bfd/elfxx-sparc.c 2007-05-14 17:34:59.000000000 -0700
@@ -1701,7 +1701,6 @@ _bfd_sparc_elf_adjust_dynamic_symbol (st
struct _bfd_sparc_elf_link_hash_entry * eh;
struct _bfd_sparc_elf_dyn_relocs *p;
asection *s;
- unsigned int power_of_two;
htab = _bfd_sparc_elf_hash_table (info);
@@ -1818,29 +1817,9 @@ _bfd_sparc_elf_adjust_dynamic_symbol (st
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > htab->align_power_max)
- power_of_two = htab->align_power_max;
-
- /* Apply the required alignment. */
s = htab->sdynbss;
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (dynobj, s))
- {
- if (! bfd_set_section_alignment (dynobj, s, power_of_two))
- return FALSE;
- }
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Allocate space in .plt, .got and associated reloc sections for
-------------- next part --------------
2007-05-14 H.J. Lu <hongjiu.lu@intel.com>
PR ld/4504
* ld-elf/data1.c: New file.
* ld-elf/data1.h: Likewise.
* ld-elf/dynbss1.c: Likewise.
* ld-elf/pass.out: Likewise.
* ld-elf/shared.exp (build_tests): Add "Build libdata1.so".
(run_tests): Add "Run with libdata1.so".
--- ld/testsuite/ld-elf/data1.c.dynbss 2007-05-14 15:40:50.000000000 -0700
+++ ld/testsuite/ld-elf/data1.c 2007-05-14 15:34:49.000000000 -0700
@@ -0,0 +1,6 @@
+#include "data1.h"
+
+char a1[1] __attribute__ ((aligned (ALIGNMENT1))) = { 10 };
+char a2[2] __attribute__ ((aligned (ALIGNMENT2)));
+char a3[3] __attribute__ ((aligned (ALIGNMENT3)));
+char a4[4] __attribute__ ((aligned (ALIGNMENT4)));
--- ld/testsuite/ld-elf/data1.h.dynbss 2007-05-14 15:40:47.000000000 -0700
+++ ld/testsuite/ld-elf/data1.h 2007-05-14 16:17:51.000000000 -0700
@@ -0,0 +1,9 @@
+#define ALIGNMENT1 0x800
+#define ALIGNMENT2 0x400
+#define ALIGNMENT3 0x200
+#define ALIGNMENT4 0x100
+
+extern char a1[1];
+extern char a2[2];
+extern char a3[3];
+extern char a4[4];
--- ld/testsuite/ld-elf/dynbss1.c.dynbss 2007-05-14 15:40:59.000000000 -0700
+++ ld/testsuite/ld-elf/dynbss1.c 2007-05-14 15:38:56.000000000 -0700
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "data1.h"
+
+int
+main (void)
+{
+ if ((((long) (&a1)) & (ALIGNMENT1 - 1)))
+ abort ();
+ if ((((long) (&a2)) & (ALIGNMENT2 - 1)))
+ abort ();
+ if ((((long) (&a2)) & (ALIGNMENT3 - 1)))
+ abort ();
+ if ((((long) (&a3)) & (ALIGNMENT4 - 1)))
+ abort ();
+
+ printf ("PASS\n");
+
+ return(0) ;
+}
--- ld/testsuite/ld-elf/pass.out.dynbss 2007-05-14 15:41:11.000000000 -0700
+++ ld/testsuite/ld-elf/pass.out 2007-05-14 15:39:29.000000000 -0700
@@ -0,0 +1 @@
+PASS
--- ld/testsuite/ld-elf/shared.exp.dynbss 2007-05-14 15:30:07.000000000 -0700
+++ ld/testsuite/ld-elf/shared.exp 2007-05-14 15:39:56.000000000 -0700
@@ -117,6 +117,9 @@ set build_tests {
{"Build libdl6d.so with --dynamic-list-data -Bsymbolic"
"-shared -Wl,--dynamic-list-data,-Bsymbolic" "-fPIC"
{dl6.c} {} "libdl6d.so"}
+ {"Build libdata1.so"
+ "-shared" "-fPIC"
+ {data1.c} {} "libdata1.so"}
}
set run_tests {
@@ -226,6 +229,9 @@ set run_tests {
{"Run dl6d1 with --dynamic-list-data and dlopen on libdl6d.so"
"--dynamic-list-data -ldl" ""
{dl6dmain.c} "dl6d1" "dl6b.out"}
+ {"Run with libdata1.so"
+ "tmpdir/libdata1.so" ""
+ {dynbss1.c} "dynbss1" "pass.out"}
}
run_cc_link_tests $build_tests
More information about the Binutils
mailing list