diff options
author | Bob Wilson <bob.wilson@acm.org> | 2004-04-21 18:12:47 +0000 |
---|---|---|
committer | Bob Wilson <bob.wilson@acm.org> | 2004-04-21 18:12:47 +0000 |
commit | 2c8c90bcd5362e8fa0b8cb40fa97ac874a3b57a9 (patch) | |
tree | 5157d8c5ae3474a4dc30562aa11a60f2baf0dbed /bfd | |
parent | 00e32a35b6e3c980338d7fe47dab8658f211efb9 (diff) | |
download | binutils-2c8c90bcd5362e8fa0b8cb40fa97ac874a3b57a9.zip binutils-2c8c90bcd5362e8fa0b8cb40fa97ac874a3b57a9.tar.gz binutils-2c8c90bcd5362e8fa0b8cb40fa97ac874a3b57a9.tar.bz2 |
* elf32-xtensa.c (is_same_value): Add final_static_link argument and
require relocations against a weak symbol to reference the same
symbol hash entry if not a final, static link.
(get_cached_value, add_value_map): Add final_static_link argument.
(remove_literals): Pass final_static_link argument as needed.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 8 | ||||
-rw-r--r-- | bfd/elf32-xtensa.c | 48 |
2 files changed, 39 insertions, 17 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 23cc010..a36324a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2004-04-21 Bob Wilson <bob.wilson@acm.org> + + * elf32-xtensa.c (is_same_value): Add final_static_link argument and + require relocations against a weak symbol to reference the same + symbol hash entry if not a final, static link. + (get_cached_value, add_value_map): Add final_static_link argument. + (remove_literals): Pass final_static_link argument as needed. + 2004-04-21 Andrew Cagney <cagney@redhat.com> * opncls.c (_bfd_new_bfd_contained_in): Copy "iovec". diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index e897777..b7639b7 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -3431,7 +3431,7 @@ struct value_map_hash_table_struct static bfd_boolean is_same_value - PARAMS ((const literal_value *, const literal_value *)); + PARAMS ((const literal_value *, const literal_value *, bfd_boolean)); static value_map_hash_table *value_map_hash_table_init PARAMS ((void)); static unsigned hash_literal_value @@ -3439,16 +3439,20 @@ static unsigned hash_literal_value static unsigned hash_bfd_vma PARAMS ((bfd_vma)); static value_map *get_cached_value - PARAMS ((value_map_hash_table *, const literal_value *)); + PARAMS ((value_map_hash_table *, const literal_value *, bfd_boolean)); static value_map *add_value_map - PARAMS ((value_map_hash_table *, const literal_value *, const r_reloc *)); + PARAMS ((value_map_hash_table *, const literal_value *, const r_reloc *, + bfd_boolean)); static bfd_boolean -is_same_value (src1, src2) +is_same_value (src1, src2, final_static_link) const literal_value *src1; const literal_value *src2; + bfd_boolean final_static_link; { + struct elf_link_hash_entry *h1, *h2; + if (r_reloc_is_const (&src1->r_rel) != r_reloc_is_const (&src2->r_rel)) return FALSE; @@ -3466,8 +3470,14 @@ is_same_value (src1, src2) if (src1->value != src2->value) return FALSE; - /* Now check for the same section and the same elf_hash. */ - if (r_reloc_is_defined (&src1->r_rel)) + /* Now check for the same section (if defined) or the same elf_hash + (if undefined or weak). */ + h1 = r_reloc_get_hash_entry (&src1->r_rel); + h2 = r_reloc_get_hash_entry (&src2->r_rel); + if (r_reloc_is_defined (&src1->r_rel) + && (final_static_link + || ((!h1 || h1->root.type != bfd_link_hash_defweak) + && (!h2 || h2->root.type != bfd_link_hash_defweak)))) { if (r_reloc_get_section (&src1->r_rel) != r_reloc_get_section (&src2->r_rel)) @@ -3475,11 +3485,8 @@ is_same_value (src1, src2) } else { - if (r_reloc_get_hash_entry (&src1->r_rel) - != r_reloc_get_hash_entry (&src2->r_rel)) - return FALSE; - - if (r_reloc_get_hash_entry (&src1->r_rel) == 0) + /* Require that the hash entries (i.e., symbols) be identical. */ + if (h1 != h2 || h1 == 0) return FALSE; } @@ -3540,9 +3547,10 @@ hash_literal_value (src) /* Check if the specified literal_value has been seen before. */ static value_map * -get_cached_value (map, val) +get_cached_value (map, val, final_static_link) value_map_hash_table *map; const literal_value *val; + bfd_boolean final_static_link; { value_map *map_e; value_map *bucket; @@ -3553,7 +3561,7 @@ get_cached_value (map, val) bucket = map->buckets[idx]; for (map_e = bucket; map_e; map_e = map_e->next) { - if (is_same_value (&map_e->val, val)) + if (is_same_value (&map_e->val, val, final_static_link)) return map_e; } return NULL; @@ -3564,17 +3572,18 @@ get_cached_value (map, val) already has an entry here. */ static value_map * -add_value_map (map, val, loc) +add_value_map (map, val, loc, final_static_link) value_map_hash_table *map; const literal_value *val; const r_reloc *loc; + bfd_boolean final_static_link; { value_map **bucket_p; unsigned idx; value_map *val_e = (value_map *) bfd_zmalloc (sizeof (value_map)); - BFD_ASSERT (get_cached_value (map, val) == NULL); + BFD_ASSERT (get_cached_value (map, val, final_static_link) == NULL); val_e->val = *val; val_e->loc = *loc; @@ -4480,6 +4489,7 @@ remove_literals (abfd, sec, link_info, values) bfd_byte *contents; Elf_Internal_Rela *internal_relocs; source_reloc *src_relocs; + bfd_boolean final_static_link; bfd_boolean ok = TRUE; int i; @@ -4500,6 +4510,10 @@ remove_literals (abfd, sec, link_info, values) goto error_return; } + final_static_link = + (!link_info->relocatable + && !elf_hash_table (link_info)->dynamic_sections_created); + /* Sort the source_relocs by target offset. */ src_relocs = relax_info->src_relocs; qsort (src_relocs, relax_info->src_count, @@ -4552,7 +4566,7 @@ remove_literals (abfd, sec, link_info, values) val.value = bfd_get_32 (abfd, contents + rel->r_rel.target_offset); /* Check if we've seen another literal with the same value. */ - val_map = get_cached_value (values, &val); + val_map = get_cached_value (values, &val, final_static_link); if (val_map != NULL) { /* First check that THIS and all the other relocs to this @@ -4575,7 +4589,7 @@ remove_literals (abfd, sec, link_info, values) { /* This is the first time we've seen this literal value. */ BFD_ASSERT (sec == r_reloc_get_section (&rel->r_rel)); - add_value_map (values, &val, &rel->r_rel); + add_value_map (values, &val, &rel->r_rel, final_static_link); } } |