aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2005-02-28 15:57:13 +0000
committerH.J. Lu <hjl.tools@gmail.com>2005-02-28 15:57:13 +0000
commitaf44c138410f6f30e1b01a5551ebbb36fd93682d (patch)
tree036587f724506f733fd502c0a01e7d39c60d3fa4
parente9e446227d91e4e0902ee7a3a1381b64eacfcd68 (diff)
downloadgdb-af44c138410f6f30e1b01a5551ebbb36fd93682d.zip
gdb-af44c138410f6f30e1b01a5551ebbb36fd93682d.tar.gz
gdb-af44c138410f6f30e1b01a5551ebbb36fd93682d.tar.bz2
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.
-rw-r--r--bfd/ChangeLog18
-rw-r--r--bfd/elf-bfd.h3
-rw-r--r--bfd/elf32-sh-symbian.c7
-rw-r--r--bfd/elflink.c37
4 files changed, 50 insertions, 15 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 94fd6f0..a0cc726 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 4c93e80..fae6f31 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -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
diff --git a/bfd/elf32-sh-symbian.c b/bfd/elf32-sh-symbian.c
index 8b15606..6a74f57 100644
--- a/bfd/elf32-sh-symbian.c
+++ b/bfd/elf32-sh-symbian.c
@@ -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"),
diff --git a/bfd/elflink.c b/bfd/elflink.c
index a21a54b..1721f3f 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -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. */