From 508c39462ab96fb67c48d04807c999759f5011a0 Mon Sep 17 00:00:00 2001 From: H.J. Lu Date: Feb 24 2006 15:47:25 +0000 Subject: 2006-02-24 H.J. Lu PR ld/2218 * elf-bfd.h (elf_backend_data): Add elf_backend_fixup_symbol. (_bfd_elf_link_hash_fixup_symbol): New. * elflink.c (_bfd_elf_link_hash_fixup_symbol): New. (_bfd_elf_fix_symbol_flags): Call elf_backend_fixup_symbol if it isn't NULL. * elfxx-ia64.c (elf_backend_fixup_symbol): Defined. * elfxx-target.h (elf_backend_fixup_symbol): New. (elfNN_bed): Initialize elf_backend_fixup_symbol. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4130616..89077f8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2006-02-24 H.J. Lu + + PR ld/2218 + * elf-bfd.h (elf_backend_data): Add elf_backend_fixup_symbol. + (_bfd_elf_link_hash_fixup_symbol): New. + + * elflink.c (_bfd_elf_link_hash_fixup_symbol): New. + (_bfd_elf_fix_symbol_flags): Call elf_backend_fixup_symbol if + it isn't NULL. + + * elfxx-ia64.c (elf_backend_fixup_symbol): Defined. + + * elfxx-target.h (elf_backend_fixup_symbol): New. + (elfNN_bed): Initialize elf_backend_fixup_symbol. + 2006-02-23 H.J. Lu * cpu-ia64-opc.c (ins_immu5b): New. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index b81f440..4181e36 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -883,6 +883,11 @@ struct elf_backend_data void (*elf_backend_hide_symbol) (struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean); + /* A function to do additional symbol fixup, called by + _bfd_elf_fix_symbol_flags. */ + bfd_boolean (*elf_backend_fixup_symbol) + (struct bfd_link_info *, struct elf_link_hash_entry *); + /* Merge the backend specific symbol attribute. */ void (*elf_backend_merge_symbol_attribute) (struct elf_link_hash_entry *, const Elf_Internal_Sym *, bfd_boolean, @@ -1476,6 +1481,8 @@ extern void _bfd_elf_link_hash_copy_indirect struct elf_link_hash_entry *); extern void _bfd_elf_link_hash_hide_symbol (struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean); +extern bfd_boolean _bfd_elf_link_hash_fixup_symbol + (struct bfd_link_info *, struct elf_link_hash_entry *); extern bfd_boolean _bfd_elf_link_hash_table_init (struct elf_link_hash_table *, bfd *, struct bfd_hash_entry *(*) diff --git a/bfd/elflink.c b/bfd/elflink.c index bbd3770..9a99b06 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -2187,6 +2187,20 @@ _bfd_elf_link_output_relocs (bfd *output_bfd, return TRUE; } +/* Make weak undefined symbols in PIE dynamic. */ + +bfd_boolean +_bfd_elf_link_hash_fixup_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *h) +{ + if (info->pie + && h->dynindx == -1 + && h->root.type == bfd_link_hash_undefweak) + return bfd_elf_link_record_dynamic_symbol (info, h); + + return TRUE; +} + /* Fix up the flags for a symbol. This handles various cases which can only be fixed after all the input files are seen. This is currently called by both adjust_dynamic_symbol and @@ -2197,6 +2211,8 @@ bfd_boolean _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, struct elf_info_failed *eif) { + const struct elf_backend_data *bed = NULL; + /* If this symbol was mentioned in a non-ELF file, try to set DEF_REGULAR and REF_REGULAR correctly. This is the only way to permit a non-ELF file to correctly refer to a symbol defined in @@ -2255,6 +2271,15 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, h->def_regular = 1; } + /* Backend specific symbol fixup. */ + if (elf_hash_table (eif->info)->dynobj) + { + bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj); + if (bed->elf_backend_fixup_symbol + && !(*bed->elf_backend_fixup_symbol) (eif->info, h)) + return FALSE; + } + /* If this is a final link, and the symbol was defined as a common symbol in a regular object file, and there was no definition in any dynamic object, then the linker will have allocated space for @@ -2280,11 +2305,8 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) && h->def_regular) { - const struct elf_backend_data *bed; bfd_boolean force_local; - bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj); - force_local = (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN); (*bed->elf_backend_hide_symbol) (eif->info, h, force_local); @@ -2323,12 +2345,8 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, if (weakdef->def_regular) h->u.weakdef = NULL; else - { - const struct elf_backend_data *bed; - - bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj); - (*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef, h); - } + (*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef, + h); } return TRUE; diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index 81e683c..409ce8b 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -5305,6 +5305,7 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, #define elf_backend_want_dynbss 0 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol +#define elf_backend_fixup_symbol _bfd_elf_link_hash_fixup_symbol #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class #define elf_backend_rela_normal 1 #define elf_backend_special_sections elfNN_ia64_special_sections diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 7fa5c77..503726d 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -420,6 +420,9 @@ #ifndef elf_backend_hide_symbol #define elf_backend_hide_symbol _bfd_elf_link_hash_hide_symbol #endif +#ifndef elf_backend_fixup_symbol +#define elf_backend_fixup_symbol NULL +#endif #ifndef elf_backend_merge_symbol_attribute #define elf_backend_merge_symbol_attribute NULL #endif @@ -598,6 +601,7 @@ static const struct elf_backend_data elfNN_bed = elf_backend_output_arch_syms, elf_backend_copy_indirect_symbol, elf_backend_hide_symbol, + elf_backend_fixup_symbol, elf_backend_merge_symbol_attribute, elf_backend_ignore_undef_symbol, elf_backend_emit_relocs,