2005-02-28 H.J. Lu <hongjiu.lu@intel.com>
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 28 Feb 2005 15:57:13 +0000 (15:57 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 28 Feb 2005 15:57:13 +0000 (15:57 +0000)
PR 757
* elf-bfd.h (_bfd_elf_merge_symbol): Add a pointer to unsigned
int.

* elf32-sh-symbian.c (sh_symbian_relocate_section): Pass NULL
to _bfd_elf_merge_symbol.

* elflink.c (_bfd_elf_merge_symbol): Use the pointer to
unsigned int to return the alignment of the old common symbol
in the dynamic object.
(_bfd_elf_add_default_symbol): Pass NULL to
_bfd_elf_merge_symbol.
(elf_link_add_object_symbols): Pass &old_alignment to
_bfd_elf_merge_symbol. Get the alignment of the new common
symbol in the dynamic object.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf32-sh-symbian.c
bfd/elflink.c

index 94fd6f08f14d579089b0a4602cd5e05288ec6df5..a0cc726edd582f24f0ad6960f270cc7759f0a225 100644 (file)
@@ -1,3 +1,21 @@
+2005-02-28  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR 757
+       * elf-bfd.h (_bfd_elf_merge_symbol): Add a pointer to unsigned
+       int.
+
+       * elf32-sh-symbian.c (sh_symbian_relocate_section): Pass NULL
+       to _bfd_elf_merge_symbol.
+
+       * elflink.c (_bfd_elf_merge_symbol): Use the pointer to
+       unsigned int to return the alignment of the old common symbol
+       in the dynamic object.
+       (_bfd_elf_add_default_symbol): Pass NULL to
+       _bfd_elf_merge_symbol.
+       (elf_link_add_object_symbols): Pass &old_alignment to
+       _bfd_elf_merge_symbol. Get the alignment of the new common
+       symbol in the dynamic object.
+
 2005-02-24  Ben Elliston  <bje@au.ibm.com>
 
        * coffcode.h (coff_sym_filepos): Remove GNU960 conditional code.
index 4c93e8089128226283768b8ca6c1a33260caaca4..fae6f3128b9ab2ea53b57686c0be66caadb6bd85 100644 (file)
@@ -1554,7 +1554,8 @@ extern bfd_boolean _bfd_elf_maybe_strip_eh_frame_hdr
 
 extern bfd_boolean _bfd_elf_merge_symbol
   (bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
-   asection **, bfd_vma *, struct elf_link_hash_entry **, bfd_boolean *,
+   asection **, bfd_vma *, unsigned int *,
+   struct elf_link_hash_entry **, bfd_boolean *,
    bfd_boolean *, bfd_boolean *, bfd_boolean *);
 
 extern bfd_boolean _bfd_elf_add_default_symbol
index 8b15606dde4876ff0b18f23fa1b95df765d9e7b5..6a74f575bcfa85cca12dea8f2f454898d4b58db7 100644 (file)
@@ -492,8 +492,11 @@ sh_symbian_relocate_section (bfd *                  output_bfd,
              new_sym.st_other = ELF_ST_VISIBILITY (STV_DEFAULT);
              new_sym.st_shndx = SHN_UNDEF;
 
-             if (! _bfd_elf_merge_symbol (input_bfd, info, ptr->new_name, & new_sym, & psec,
-                                          & new_value, & new_hash, & skip, & override, & type_change_ok,
+             if (! _bfd_elf_merge_symbol (input_bfd, info,
+                                          ptr->new_name, & new_sym,
+                                          & psec, & new_value, NULL,
+                                          & new_hash, & skip,
+                                          & override, & type_change_ok,
                                           & size_change_ok))
                {
                  _bfd_error_handler (_("%B: Failed to add renamed symbol %s"),
index a21a54b93240e8ac22e36f15b5f611573a22c722..1721f3f8a3c478a55cf1bf60dd6d5605032ec393 100644 (file)
@@ -756,7 +756,8 @@ _bfd_elf_link_renumber_dynsyms (bfd *output_bfd, struct bfd_link_info *info)
    TYPE_CHANGE_OK if it is OK for the type to change.  We set
    SIZE_CHANGE_OK if it is OK for the size to change.  By OK to
    change, we mean that we shouldn't warn if the type or size does
-   change.  */
+   change.  We set POLD_ALIGNMENT if an old common symbol in a dynamic
+   object is overridden by a regular object.  */
 
 bfd_boolean
 _bfd_elf_merge_symbol (bfd *abfd,
@@ -765,6 +766,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
                       Elf_Internal_Sym *sym,
                       asection **psec,
                       bfd_vma *pvalue,
+                      unsigned int *pold_alignment,
                       struct elf_link_hash_entry **sym_hash,
                       bfd_boolean *skip,
                       bfd_boolean *override,
@@ -1269,9 +1271,10 @@ _bfd_elf_merge_symbol (bfd *abfd,
       if (h->size > *pvalue)
        *pvalue = h->size;
 
-      /* FIXME: We no longer know the alignment required by the symbol
-        in the dynamic object, so we just wind up using the one from
-        the regular object.  */
+      /* We need to remember the alignment required by the symbol
+        in the dynamic object.  */
+      BFD_ASSERT (pold_alignment);
+      *pold_alignment = h->root.u.def.section->alignment_power;
 
       olddef = FALSE;
       olddyncommon = FALSE;
@@ -1383,8 +1386,8 @@ _bfd_elf_add_default_symbol (bfd *abfd,
   size_change_ok = FALSE;
   sec = *psec;
   if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
-                             &hi, &skip, &override, &type_change_ok,
-                             &size_change_ok))
+                             NULL, &hi, &skip, &override,
+                             &type_change_ok, &size_change_ok))
     return FALSE;
 
   if (skip)
@@ -1487,8 +1490,8 @@ nondefault:
   size_change_ok = FALSE;
   sec = *psec;
   if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
-                             &hi, &skip, &override, &type_change_ok,
-                             &size_change_ok))
+                             NULL, &hi, &skip, &override,
+                             &type_change_ok, &size_change_ok))
     return FALSE;
 
   if (skip)
@@ -3525,7 +3528,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
     {
       int bind;
       bfd_vma value;
-      asection *sec;
+      asection *sec, *new_sec;
       flagword flags;
       const char *name;
       struct elf_link_hash_entry *h;
@@ -3650,6 +3653,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
       type_change_ok = get_elf_backend_data (abfd)->type_change_ok;
       old_alignment = 0;
       old_bfd = NULL;
+      new_sec = sec;
 
       if (is_elf_hash_table (hash_table))
        {
@@ -3762,7 +3766,8 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
              name = newname;
            }
 
-         if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value,
+         if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec,
+                                     &value, &old_alignment,
                                      sym_hash, &skip, &override,
                                      &type_change_ok, &size_change_ok))
            goto error_free_vers;
@@ -3844,12 +3849,20 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
        }
 
       /* Set the alignment of a common symbol.  */
-      if (isym->st_shndx == SHN_COMMON
+      if ((isym->st_shndx == SHN_COMMON
+          || bfd_is_com_section (sec))
          && h->root.type == bfd_link_hash_common)
        {
          unsigned int align;
 
-         align = bfd_log2 (isym->st_value);
+         if (isym->st_shndx == SHN_COMMON)
+           align = bfd_log2 (isym->st_value);
+         else
+           {
+             /* The new symbol is a common symbol in a shared object.
+                We need to get the alignment from the section.  */
+             align = new_sec->alignment_power;
+           }
          if (align > old_alignment
              /* Permit an alignment power of zero if an alignment of one
                 is specified and no other alignments have been specified.  */