summaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl@lucon.org>2007-05-15 13:55:54 +0000
committerH.J. Lu <hjl@lucon.org>2007-05-15 13:55:54 +0000
commitcb26c3664c93ae9857f40c21541fcf990cb9bcd4 (patch)
treeb19253b06fcfc4fb4dc4dbb68e513bfd85a00333 /bfd/elflink.c
parent1f5940874092d88025f014c8f8aba36bb3b3481d (diff)
downloadgdb-cb26c3664c93ae9857f40c21541fcf990cb9bcd4.tar.gz
2007-05-15 H.J. Lu <hongjiu.lu@intel.com>
Alan Modra <amodra@bigpond.net.au> 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.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 41b518d8774..6cf1ba9f67b 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -2609,6 +2609,52 @@ _bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data)
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;
+ 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);
+
+ 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;
+ }
+ dynbss->size = BFD_ALIGN (dynbss->size, mask + 1);
+
+ /* 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. */