diff options
-rw-r--r-- | bfd/ChangeLog | 23 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 19 | ||||
-rw-r--r-- | bfd/elflink.h | 14 | ||||
-rw-r--r-- | bfd/elfxx-ia64.c | 34 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-elfvsb/main.c | 31 | ||||
-rw-r--r-- | ld/testsuite/ld-elfvsb/sh1.c | 31 |
7 files changed, 143 insertions, 14 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index dfbc26d..e209e3d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,28 @@ 2003-05-04 H.J. Lu <hjl@gnu.org> + * elf32-i386.c (allocate_dynrelocs): Don't allocate dynamic + relocation entries for weak undefined symbols with non-default + visibility. + (elf_i386_relocate_section): Initialize the GOT entries and + skip R_386_32/R_386_PC32 for weak undefined symbols with + non-default visibility. + + * elfxx-ia64.c (allocate_fptr): Don't allocate function + descriptors for weak undefined symbols with non-default + visibility. + (allocate_dynrel_entries): Don't allocate relocation entries + for symbols resolved to 0. + (set_got_entry): Don't install dynamic relocation for weak + undefined symbols with non-default visibility. + (set_pltoff_entry): Likewise. + + * elflink.h (elf_fix_symbol_flags): Hide weak undefined symbols + with non-default visibility. + (elf_link_output_extsym): Don't make weak undefined symbols + with non-default visibility dynamic. + +2003-05-04 H.J. Lu <hjl@gnu.org> + * elflink.h (elf_merge_symbol): Correctly handle weak definiton. 2003-05-04 H.J. Lu <hjl@gnu.org> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 060d66c..ac292a1 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1569,8 +1569,10 @@ allocate_dynrelocs (h, inf) return FALSE; } - if (info->shared - || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)) + if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || h->root.type != bfd_link_hash_undefweak) + && (info->shared + || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))) { asection *s = htab->splt; @@ -1656,8 +1658,10 @@ allocate_dynrelocs (h, inf) htab->srelgot->_raw_size += sizeof (Elf32_External_Rel); else if (tls_type == GOT_TLS_GD) htab->srelgot->_raw_size += 2 * sizeof (Elf32_External_Rel); - else if (info->shared - || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)) + else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || h->root.type != bfd_link_hash_undefweak) + && (info->shared + || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) htab->srelgot->_raw_size += sizeof (Elf32_External_Rel); } else @@ -2298,7 +2302,9 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, && (info->symbolic || h->dynindx == -1 || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) + || (ELF_ST_VISIBILITY (h->other) + && h->root.type == bfd_link_hash_undefweak)) { /* This is actually a static link, or it is a -Bsymbolic link and the symbol is defined @@ -2422,6 +2428,9 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, break; if ((info->shared + && (h == NULL + || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || h->root.type != bfd_link_hash_undefweak) && (r_type != R_386_PC32 || (h != NULL && h->dynindx != -1 diff --git a/bfd/elflink.h b/bfd/elflink.h index dfcce7d..0f590a4 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -4151,6 +4151,16 @@ elf_fix_symbol_flags (h, eif) (*bed->elf_backend_hide_symbol) (eif->info, h, force_local); } + /* If a weak undefined symbol has non-default visibility, we also + hide it from the dynamic linker. */ + if (ELF_ST_VISIBILITY (h->other) + && h->root.type == bfd_link_hash_undefweak) + { + struct elf_backend_data *bed; + bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj); + (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE); + } + /* If this is a weak defined symbol in a dynamic object, and we know the real definition in the dynamic object, copy interesting flags over to the real definition. */ @@ -6546,7 +6556,9 @@ elf_link_output_extsym (h, data) forced local syms when non-shared is due to a historical quirk. */ if ((h->dynindx != -1 || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) - && (finfo->info->shared + && ((finfo->info->shared + && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || h->root.type != bfd_link_hash_undefweak)) || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) && elf_hash_table (finfo->info)->dynamic_sections_created) { diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index 946157f..31f05e9 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -2635,7 +2635,10 @@ allocate_fptr (dyn_i, data) || h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (x->info->shared + if ((x->info->shared + && (!h + || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || h->root.type != bfd_link_hash_undefweak)) /* AIX needs an FPTR in this case. */ || (elfNN_ia64_aix_vec (x->info->hash->creator) && (!h @@ -2760,15 +2763,18 @@ allocate_dynrel_entries (dyn_i, data) struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data; struct elfNN_ia64_link_hash_table *ia64_info; struct elfNN_ia64_dyn_reloc_entry *rent; - bfd_boolean dynamic_symbol, shared; + bfd_boolean dynamic_symbol, shared, resolved_zero; ia64_info = elfNN_ia64_hash_table (x->info); dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info) || (elfNN_ia64_aix_vec (x->info->hash->creator) /* Don't allocate an entry for __GLOB_DATA_PTR */ && (!dyn_i->h || strcmp (dyn_i->h->root.root.string, - "__GLOB_DATA_PTR") != 0)); + "__GLOB_DATA_PTR") != 0)); shared = x->info->shared; + resolved_zero = (dyn_i->h + && ELF_ST_VISIBILITY (dyn_i->h->other) + && dyn_i->h->root.type == bfd_link_hash_undefweak); /* Take care of the normal data relocations. */ @@ -2813,8 +2819,12 @@ allocate_dynrel_entries (dyn_i, data) /* Take care of the GOT and PLT relocations. */ - if (((dynamic_symbol || shared) && (dyn_i->want_got || dyn_i->want_gotx)) - || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1)) + if ((!resolved_zero + && (dynamic_symbol || shared) + && (dyn_i->want_got || dyn_i->want_gotx)) + || (dyn_i->want_ltoff_fptr + && dyn_i->h + && dyn_i->h->dynindx != -1)) ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela); if ((dynamic_symbol || shared) && dyn_i->want_tprel) ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela); @@ -2823,7 +2833,7 @@ allocate_dynrel_entries (dyn_i, data) if (dynamic_symbol && dyn_i->want_dtprel) ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela); - if (dyn_i->want_pltoff) + if (!resolved_zero && dyn_i->want_pltoff) { bfd_size_type t = 0; @@ -3431,7 +3441,11 @@ set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type) bfd_put_64 (abfd, value, got_sec->contents + got_offset); /* Install a dynamic relocation if needed. */ - if ((info->shared && dyn_r_type != R_IA64_DTPREL64LSB) + if ((info->shared + && (!dyn_i->h + || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT + || dyn_i->h->root.type != bfd_link_hash_undefweak) + && dyn_r_type != R_IA64_DTPREL64LSB) || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info) || elfNN_ia64_aix_vec (abfd->xvec) || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB)) @@ -3552,7 +3566,11 @@ set_pltoff_entry (abfd, info, dyn_i, value, is_plt) bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8); /* Install dynamic relocations if needed. */ - if (!is_plt && info->shared) + if (!is_plt + && info->shared + && (!dyn_i->h + || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT + || dyn_i->h->root.type != bfd_link_hash_undefweak)) { unsigned int dyn_r_type; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index dcd5724..10d1ddd 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2003-05-04 H.J. Lu <hjl@gnu.org> + * ld-elfvsb/main.c: Updated. + * ld-elfvsb/sh1.c: Likewise. + +2003-05-04 H.J. Lu <hjl@gnu.org> + * ld-elfvers/vers18.dsym: Updated for weak definiton change. * ld-elfvers/vers18.ver: Likewise. * ld-elfvers/vers19.ver: Likewise. diff --git a/ld/testsuite/ld-elfvsb/main.c b/ld/testsuite/ld-elfvsb/main.c index 6ce97bf..1ce2e3e 100644 --- a/ld/testsuite/ld-elfvsb/main.c +++ b/ld/testsuite/ld-elfvsb/main.c @@ -165,6 +165,37 @@ main_visibility_checkweak () { return 1; } +#elif defined (HIDDEN_WEAK_TEST) +int +main_visibility_checkcom () +{ + return 1; +} + +#pragma weak visibility_undef_var_weak +extern int visibility_undef_var_weak; +asm (".hidden visibility_undef_var_weak"); + +#pragma weak visibility_undef_func_weak +extern int visibility_undef_func_weak (); +asm (".hidden visibility_undef_func_weak"); + +#pragma weak visibility_var_weak +extern int visibility_var_weak; +asm (".hidden visibility_var_weak"); + +#pragma weak visibility_func_weak +extern int visibility_func_weak (); +asm (".hidden visibility_func_weak"); + +int +main_visibility_checkweak () +{ + return &visibility_undef_var_weak == NULL + && &visibility_undef_func_weak == NULL + && &visibility_func_weak == NULL + && &visibility_var_weak == NULL; +} #elif defined (HIDDEN_UNDEF_TEST) extern int visibility_def; asm (".hidden visibility_def"); diff --git a/ld/testsuite/ld-elfvsb/sh1.c b/ld/testsuite/ld-elfvsb/sh1.c index 2b9b9ee..8d9fcdb 100644 --- a/ld/testsuite/ld-elfvsb/sh1.c +++ b/ld/testsuite/ld-elfvsb/sh1.c @@ -339,6 +339,37 @@ shlib_visibility_checkweak () { return 1; } +#elif defined (HIDDEN_WEAK_TEST) +#pragma weak shlib_visibility_undef_var_weak +extern int shlib_visibility_undef_var_weak; +asm (".hidden shlib_visibility_undef_var_weak"); + +#pragma weak shlib_visibility_undef_func_weak +extern int shlib_visibility_undef_func_weak (); +asm (".hidden shlib_visibility_undef_func_weak"); + +#pragma weak shlib_visibility_var_weak +extern int shlib_visibility_var_weak; +asm (".hidden shlib_visibility_var_weak"); + +#pragma weak shlib_visibility_func_weak +extern int shlib_visibility_func_weak (); +asm (".hidden shlib_visibility_func_weak"); + +int +shlib_visibility_checkcom () +{ + return 1; +} + +int +shlib_visibility_checkweak () +{ + return &shlib_visibility_undef_var_weak == NULL + && &shlib_visibility_undef_func_weak == NULL + && &shlib_visibility_func_weak == NULL + && &shlib_visibility_var_weak == NULL; +} #else int shlib_visibility_checkcom () |