From 8d7cab1f462b2032b5977c11a0ef57ba61107dbc Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Wed, 20 Aug 2003 08:37:19 +0000 Subject: Better handking for unresolved symbols --- bfd/ChangeLog | 42 ++++++++++++++++++++ bfd/elf-bfd.h | 56 +++++++++++++++++++++++++++ bfd/elf-hppa.h | 7 ++-- bfd/elf-m10300.c | 94 ++++++++++++++++++--------------------------- bfd/elf32-arm.h | 72 +++++++++++----------------------- bfd/elf32-cris.c | 111 ++++++++++++++++++++--------------------------------- bfd/elf32-hppa.c | 64 +++++++++++++----------------- bfd/elf32-i386.c | 37 +----------------- bfd/elf32-ip2k.c | 27 ++----------- bfd/elf32-iq2000.c | 46 +++------------------- bfd/elf32-m68k.c | 38 ++---------------- bfd/elf32-ppc.c | 96 ++++++++------------------------------------- bfd/elf32-s390.c | 43 +++------------------ bfd/elf32-sh.c | 15 +++++--- bfd/elf32-sparc.c | 40 +++---------------- bfd/elf32-vax.c | 49 +++++++---------------- bfd/elf32-xtensa.c | 51 ++++++------------------ bfd/elf64-alpha.c | 57 ++++++++------------------- bfd/elf64-hppa.c | 17 ++++---- bfd/elf64-ppc.c | 41 ++------------------ bfd/elf64-s390.c | 43 +++------------------ bfd/elf64-sh64.c | 6 ++- bfd/elf64-sparc.c | 40 +++---------------- bfd/elf64-x86-64.c | 43 +++------------------ bfd/elflink.h | 26 +++++-------- bfd/elfxx-ia64.c | 55 ++++++-------------------- bfd/elfxx-mips.c | 13 ++++--- include/ChangeLog | 9 +++++ include/bfdlink.h | 42 +++++++++++--------- 29 files changed, 416 insertions(+), 864 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 66d6002bb22..61006251743 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,45 @@ +2003-08-20 Nick Clifton + + * elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): New macro used to + replace some duplicated code in most elfxx-xxxx.c files. This + version uses the new fields in bfd_link_info. + + * elf-m10300.c (mn10300_elf_relocate_section): Use new macro. + * elf32-arm.h (elf32_arm_relocate_section): Likewise. + * elf32-cris.c (cris_elf_relocate_section): Likewise. + * elf32-hppa.c (elf32_hppa_relocate_section): Likewise. + * elf32-i386.c (elf_i386_relocate_section): Likewise. + * elf32-ip2k.c (ip2k_elf_relocate_section): Likewise. + * elf32-iq2000.c (iq2000_elf_relocate_section): Likewise. + * elf32-m68k.c (elf_m68k_relocate_section): Likewise. + * elf32-ppc.c (ppc_elf_relocate_section): Likewise. + * elf32-s390.c (elf_s390_relocate_section): Likewise. + * elf32-sparc.c (elf32_sparc_relocate_section): Likewise. + * elf32-vax.c (elf_vax_relocate_section): Likewise. + * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise. + * elf64-alpha.c (elf64_alpha_relocate_section): Likewise. + * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. + * elf64-s390.c (elf_s390_relocate_section): Likewise. + * elf64-sparc.c (sparc64_elf_relocate_section): Likewise. + * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise. + * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise. + + * elf-hppa.h (elf_hppa_unmark_useless_dynamic_symbols, + elf_hppa_remark_useless_dynamic_symbols, + elf_hppa_relocate_section): Use the new fields in + bfd_link_info structure. + * elf32-sh.c (sh_elf_relocate_section): Likewise. + * elf64-alpha.c (elf64_alpha_check_relocs): Likewise. + * elf64-hppa.c (elf64_hppa_check_relocs): Likewise. + * elf64-sh64.c (sh_elf64_relocate_section): Likewise. + * elfxx-ia64.c (elfNN_ia64_check_relocs): Likewise. + * elfxx-mips.c (mips_elf_calculate_relocation): Likewise. + + * elflink.h (elf_link_output_extsym): Fix test for reporting + undefined symbols in shared libraries. Remove redundant test + of shlib_undefined when reporting references to forced local + symbols. + 2003-08-18 Andreas Schwab * libpei.h (bfd_pe_executable_p): Also recognize efi-app diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 93f265fa147..abbe377e491 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1682,4 +1682,60 @@ extern bfd *_bfd_elf64_bfd_from_remote_memory extern bfd_boolean _sh_elf_set_mach_from_flags (bfd *); +/* This macro is to avoid lots of duplicated code in the body + of xxx_relocate_section() in the various elfxx-xxxx.c files. */ +#define RELOC_FOR_GLOBAL_SYMBOL(h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned) \ + do \ + { \ + /* It seems this can happen with erroneous or unsupported \ + input (mixing a.out and elf in an archive, for example.) */ \ + if (sym_hashes == NULL) \ + return FALSE; \ + \ + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; \ + \ + while (h->root.type == bfd_link_hash_indirect \ + || h->root.type == bfd_link_hash_warning) \ + h = (struct elf_link_hash_entry *) h->root.u.i.link; \ + \ + warned = FALSE; \ + unresolved_reloc = FALSE; \ + relocation = 0; \ + if (h->root.type == bfd_link_hash_defined \ + || h->root.type == bfd_link_hash_defweak) \ + { \ + sec = h->root.u.def.section; \ + if (sec == NULL \ + || sec->output_section == NULL) \ + /* Set a flag that will be cleared later if we find a \ + relocation value for this symbol. output_section \ + is typically NULL for symbols satisfied by a shared \ + library. */ \ + unresolved_reloc = TRUE; \ + else \ + relocation = (h->root.u.def.value \ + + sec->output_section->vma \ + + sec->output_offset); \ + } \ + else if (h->root.type == bfd_link_hash_undefweak) \ + ; \ + else if (!info->executable \ + && info->unresolved_syms_in_objects == RM_IGNORE \ + && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) \ + ; \ + else \ + { \ + if (! info->callbacks->undefined_symbol \ + (info, h->root.root.string, input_bfd, \ + input_section, rel->r_offset, \ + ((info->shared && info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR) \ + || (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR) \ + || ELF_ST_VISIBILITY (h->other)) \ + )) \ + return FALSE; \ + warned = TRUE; \ + } \ + } \ + while (0) + #endif /* _LIBELF_H_ */ diff --git a/bfd/elf-hppa.h b/bfd/elf-hppa.h index b0be7018d99..bdd7a7471e6 100644 --- a/bfd/elf-hppa.h +++ b/bfd/elf-hppa.h @@ -1097,7 +1097,7 @@ elf_hppa_unmark_useless_dynamic_symbols (struct elf_link_hash_entry *h, linker code. */ if (! info->relocatable && ! (info->shared - && !info->no_undefined) + && info->unresolved_syms_in_shared_libs == RM_IGNORE) && h->root.type == bfd_link_hash_undefined && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0 && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) @@ -1132,7 +1132,7 @@ elf_hppa_remark_useless_dynamic_symbols (struct elf_link_hash_entry *h, linker code. */ if (! info->relocatable && ! (info->shared - && !info->no_undefined) + && info->unresolved_syms_in_shared_libs == RM_IGNORE) && h->root.type == bfd_link_hash_undefined && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0 && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0 @@ -1399,7 +1399,8 @@ elf_hppa_relocate_section (bfd *output_bfd, relocation = 0; } /* Allow undefined symbols in shared libraries. */ - else if (info->shared && !info->no_undefined + else if (info->shared + && info->unresolved_syms_in_shared_libs == RM_IGNORE && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) { if (info->symbolic) diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c index 212fde7e8f4..dc25c38aff1 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -1158,9 +1158,8 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, } bfd_elf32_swap_reloca_out (output_bfd, &outrel, - (((Elf32_External_Rela *) - sreloc->contents) - + sreloc->reloc_count)); + (bfd_byte *) (((Elf32_External_Rela *) sreloc->contents) + + sreloc->reloc_count)); ++sreloc->reloc_count; /* If this reloc is against an external symbol, we do @@ -1295,9 +1294,9 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, } bfd_elf32_swap_reloca_out (output_bfd, &outrel, - (((Elf32_External_Rela *) - sreloc->contents) - + sreloc->reloc_count)); + (bfd_byte *) (((Elf32_External_Rela *) + sreloc->contents) + + sreloc->reloc_count)); ++sreloc->reloc_count; return bfd_reloc_ok; @@ -1480,9 +1479,9 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, outrel.r_info = ELF32_R_INFO (0, R_MN10300_RELATIVE); outrel.r_addend = value; bfd_elf32_swap_reloca_out (output_bfd, &outrel, - (((Elf32_External_Rela *) - srelgot->contents) - + srelgot->reloc_count)); + (bfd_byte *) (((Elf32_External_Rela *) + srelgot->contents) + + srelgot->reloc_count)); ++ srelgot->reloc_count; } @@ -1579,15 +1578,20 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section, } else { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.root.type == bfd_link_hash_indirect - || h->root.root.type == bfd_link_hash_warning) - h = (struct elf32_mn10300_link_hash_entry *) h->root.root.u.i.link; - if (h->root.root.type == bfd_link_hash_defined + bfd_boolean unresolved_reloc; + bfd_boolean warned; + struct elf_link_hash_entry *hh; + + RELOC_FOR_GLOBAL_SYMBOL (hh, (struct elf_link_hash_entry *) sym_hashes, + r_symndx, symtab_hdr, relocation, + sec, unresolved_reloc, info, + warned); + + h = (struct elf32_mn10300_link_hash_entry *) hh; + + if ((h->root.root.type == bfd_link_hash_defined || h->root.root.type == bfd_link_hash_defweak) - { - sec = h->root.root.u.def.section; - if ( r_type == R_MN10300_GOTPC32 + && ( r_type == R_MN10300_GOTPC32 || r_type == R_MN10300_GOTPC16 || (( r_type == R_MN10300_PLT32 || r_type == R_MN10300_PLT16) @@ -1615,41 +1619,17 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section, do anything with them here. */ || ((input_section->flags & SEC_DEBUGGING) != 0 && (h->root.elf_link_hash_flags - & ELF_LINK_HASH_DEF_DYNAMIC) != 0)))) - { - /* In these cases, we don't need the relocation - value. We check specially because in some - obscure cases sec->output_section will be NULL. */ - relocation = 0; - } - else if (sec->output_section == NULL) - { - (*_bfd_error_handler) - (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"), - bfd_get_filename (input_bfd), h->root.root.root.string, - bfd_get_section_name (input_bfd, input_section)); - relocation = 0; - } - else - relocation = (h->root.root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared && !info->symbolic && !info->no_undefined - && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT) + & ELF_LINK_HASH_DEF_DYNAMIC) != 0))))) + /* In these cases, we don't need the relocation + value. We check specially because in some + obscure cases sec->output_section will be NULL. */ relocation = 0; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.root.string, input_bfd, - input_section, rel->r_offset, - (!info->shared || info->no_undefined - || ELF_ST_VISIBILITY (h->root.other))))) - return FALSE; - relocation = 0; - } + + else if (unresolved_reloc) + (*_bfd_error_handler) + (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"), + bfd_get_filename (input_bfd), h->root.root.root.string, + bfd_get_section_name (input_bfd, input_section)); } r = mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, @@ -4626,8 +4606,8 @@ _bfd_mn10300_elf_finish_dynamic_symbol (output_bfd, info, h, sym) rel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_JMP_SLOT); rel.r_addend = 0; bfd_elf32_swap_reloca_out (output_bfd, &rel, - ((Elf32_External_Rela *) srel->contents - + plt_index)); + (bfd_byte *) ((Elf32_External_Rela *) srel->contents + + plt_index)); if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) /* Mark the symbol as undefined, rather than as defined in @@ -4673,8 +4653,8 @@ _bfd_mn10300_elf_finish_dynamic_symbol (output_bfd, info, h, sym) } bfd_elf32_swap_reloca_out (output_bfd, &rel, - ((Elf32_External_Rela *) srel->contents - + srel->reloc_count)); + (bfd_byte *) ((Elf32_External_Rela *) srel->contents + + srel->reloc_count)); ++ srel->reloc_count; } @@ -4698,8 +4678,8 @@ _bfd_mn10300_elf_finish_dynamic_symbol (output_bfd, info, h, sym) rel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_COPY); rel.r_addend = 0; bfd_elf32_swap_reloca_out (output_bfd, &rel, - ((Elf32_External_Rela *) s->contents - + s->reloc_count)); + (bfd_byte *) ((Elf32_External_Rela *) s->contents + + s->reloc_count)); ++ s->reloc_count; } diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index 2c62ec665ba..a28c558f1db 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -1963,19 +1963,16 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section, } else { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - - while ( h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - if ( h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) + bfd_boolean warned; + bfd_boolean unresolved_reloc; + + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, + symtab_hdr, relocation, + sec, unresolved_reloc, info, + warned); + + if (unresolved_reloc || relocation != 0) { - int relocation_needed = 1; - - sec = h->root.u.def.section; - /* In these cases, we don't need the relocation value. We check specially because in some obscure cases sec->output_section will be NULL. */ @@ -1998,64 +1995,39 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section, && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)) ) - relocation_needed = 0; + relocation = 0; break; case R_ARM_GOTPC: - relocation_needed = 0; + relocation = 0; break; case R_ARM_GOT32: if ((WILL_CALL_FINISH_DYNAMIC_SYMBOL - (elf_hash_table(info)->dynamic_sections_created, + (elf_hash_table (info)->dynamic_sections_created, info->shared, h)) && (!info->shared || (!info->symbolic && h->dynindx != -1) || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)) - relocation_needed = 0; + relocation = 0; break; case R_ARM_PLT32: if (h->plt.offset != (bfd_vma)-1) - relocation_needed = 0; + relocation = 0; break; default: - if (sec->output_section == NULL) - { - (*_bfd_error_handler) - (_("%s: warning: unresolvable relocation %d against symbol `%s' from %s section"), - bfd_archive_filename (input_bfd), - r_type, - h->root.root.string, - bfd_get_section_name (input_bfd, input_section)); - relocation_needed = 0; - } + if (unresolved_reloc) + _bfd_error_handler + (_("%s: warning: unresolvable relocation %d against symbol `%s' from %s section"), + bfd_archive_filename (input_bfd), + r_type, + h->root.root.string, + bfd_get_section_name (input_bfd, input_section)); + break; } - - if (relocation_needed) - relocation = h->root.u.def.value - + sec->output_section->vma - + sec->output_offset; - else - relocation = 0; - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared && !info->symbolic - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - relocation = 0; - else - { - if (!((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (!info->shared || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - relocation = 0; } } diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c index 4618a8f2830..d630a2a84c9 100644 --- a/bfd/elf32-cris.c +++ b/bfd/elf32-cris.c @@ -856,24 +856,12 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section, } else { - /* It seems this can happen with erroneous or unsupported input - (mixing a.out and elf in an archive, for example.) */ - if (sym_hashes == NULL) - return FALSE; - - h = sym_hashes [r_symndx - symtab_hdr->sh_info]; - - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; + bfd_boolean warned; + bfd_boolean unresolved_reloc; - symname = h->root.root.string; - - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned); + if (unresolved_reloc /* Perhaps we should detect the cases that sec->output_section is expected to be NULL like i386 and m68k, but apparently (and according to elfxx-ia64.c) all @@ -888,46 +876,45 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section, is *not* dynamically linked against. Thus this will automatically remind us so we can see if there are other valid cases we need to revisit. */ - if ((sec->output_section == NULL - && (sec->owner->flags & DYNAMIC) != 0) - - /* Here follow the cases where the relocation value must - be zero (or when further handling is simplified when - zero). I can't claim to understand the various - conditions and they weren't described in the files - where I copied them from (elf32-m68k.c and - elf32-i386.c), but let's mention examples of where - they happen. FIXME: Perhaps define and use a - dynamic_symbol_p function like ia64. - - - When creating a shared library, we can have an - ordinary relocation for a symbol defined in a shared - library (perhaps the one we create). We then make - the relocation value zero, as the value seen now will - be added into the relocation addend in this shared - library, but must be handled only at dynamic-link - time. FIXME: Not sure this example covers the - h->elf_link_hash_flags test, though it's there in - other targets. */ - || (info->shared - && ((! info->symbolic && h->dynindx != -1) - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0) - && (input_section->flags & SEC_ALLOC) != 0 - && (r_type == R_CRIS_8 - || r_type == R_CRIS_16 - || r_type == R_CRIS_32 - || r_type == R_CRIS_8_PCREL - || r_type == R_CRIS_16_PCREL - || r_type == R_CRIS_32_PCREL))) + && (sec->owner->flags & DYNAMIC) != 0) + relocation = 0; + + else if (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + { + /* Here follow the cases where the relocation value must + be zero (or when further handling is simplified when + zero). I can't claim to understand the various + conditions and they weren't described in the files + where I copied them from (elf32-m68k.c and + elf32-i386.c), but let's mention examples of where + they happen. FIXME: Perhaps define and use a + dynamic_symbol_p function like ia64. + + - When creating a shared library, we can have an + ordinary relocation for a symbol defined in a shared + library (perhaps the one we create). We then make + the relocation value zero, as the value seen now will + be added into the relocation addend in this shared + library, but must be handled only at dynamic-link + time. FIXME: Not sure this example covers the + h->elf_link_hash_flags test, though it's there in + other targets. */ + if (info->shared + && ((! info->symbolic && h->dynindx != -1) + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0) + && (input_section->flags & SEC_ALLOC) != 0 + && (r_type == R_CRIS_8 + || r_type == R_CRIS_16 + || r_type == R_CRIS_32 + || r_type == R_CRIS_8_PCREL + || r_type == R_CRIS_16_PCREL + || r_type == R_CRIS_32_PCREL)) relocation = 0; - else if (sec->output_section != NULL) - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - else + else if (unresolved_reloc) { - (*_bfd_error_handler) + _bfd_error_handler (_("%s: unresolvable relocation %s against symbol `%s' from %s section"), bfd_archive_filename (input_bfd), cris_elf_howto_table[r_type].name, @@ -937,22 +924,6 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section, return FALSE; } } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - relocation = 0; - else - { - if (!(info->callbacks->undefined_symbol - (info, symname, input_bfd, - input_section, rel->r_offset, - (!info->shared || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - relocation = 0; - } } switch (r_type) diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index ae09096f2be..3c03a063528 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -2853,7 +2853,7 @@ elf32_hppa_size_stubs else if (hash->elf.root.type == bfd_link_hash_undefined) { if (! (info->shared - && !info->no_undefined + && info->unresolved_syms_in_objects == RM_IGNORE && (ELF_ST_VISIBILITY (hash->elf.other) == STV_DEFAULT) && hash->elf.type != STT_PARISC_MILLI)) @@ -3444,43 +3444,33 @@ elf32_hppa_relocate_section (bfd *output_bfd, } else { - int indx; - - /* It's a global; Find its entry in the link hash. */ - indx = r_symndx - symtab_hdr->sh_info; - h = ((struct elf32_hppa_link_hash_entry *) - elf_sym_hashes (input_bfd)[indx]); - while (h->elf.root.type == bfd_link_hash_indirect - || h->elf.root.type == bfd_link_hash_warning) - h = (struct elf32_hppa_link_hash_entry *) h->elf.root.u.i.link; - - relocation = 0; - if (h->elf.root.type == bfd_link_hash_defined - || h->elf.root.type == bfd_link_hash_defweak) - { - sym_sec = h->elf.root.u.def.section; - /* If sym_sec->output_section is NULL, then it's a - symbol defined in a shared library. */ - if (sym_sec->output_section != NULL) - relocation = (h->elf.root.u.def.value - + sym_sec->output_offset - + sym_sec->output_section->vma); - } - else if (h->elf.root.type == bfd_link_hash_undefweak) - ; - else if (info->shared - && !info->no_undefined - && ELF_ST_VISIBILITY (h->elf.other) == STV_DEFAULT - && h->elf.type != STT_PARISC_MILLI) - ; - else - { - if (!((*info->callbacks->undefined_symbol) - (info, h->elf.root.root.string, input_bfd, - input_section, rel->r_offset, TRUE))) - return FALSE; - warned_undef = TRUE; + struct elf_link_hash_entry *hh; + bfd_boolean unresolved_reloc; + + RELOC_FOR_GLOBAL_SYMBOL (hh, elf_sym_hashes (input_bfd), r_symndx, symtab_hdr, + relocation, sym_sec, unresolved_reloc, info, + warned_undef); + + if (relocation == 0 + && hh->root.type != bfd_link_hash_defined + && hh->root.type != bfd_link_hash_defweak + && hh->root.type != bfd_link_hash_undefweak) + { + if (!info->executable + && info->unresolved_syms_in_objects == RM_IGNORE + && ELF_ST_VISIBILITY (hh->other) == STV_DEFAULT + && hh->type == STT_PARISC_MILLI) + { + if (! info->callbacks->undefined_symbol + (info, hh->root.root.string, input_bfd, + input_section, rel->r_offset, + ((info->shared && info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR) + || (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR)))) + return FALSE; + warned_undef = TRUE; + } } + h = (struct elf32_hppa_link_hash_entry *) hh; } /* Do any required modifications to the relocation value, and diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 77b5e369bce..11fadabc998 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -2154,42 +2154,9 @@ elf_i386_relocate_section (bfd *output_bfd, } else { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; + bfd_boolean warned; - relocation = 0; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if (sec->output_section == NULL) - /* Set a flag that will be cleared later if we find a - relocation value for this symbol. output_section - is typically NULL for symbols satisfied by a shared - library. */ - unresolved_reloc = TRUE; - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - ; - else if (!info->executable - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - ; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (info->executable || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - } + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned); } switch (r_type) diff --git a/bfd/elf32-ip2k.c b/bfd/elf32-ip2k.c index 4cb28bb31b8..e8cb1771887 100644 --- a/bfd/elf32-ip2k.c +++ b/bfd/elf32-ip2k.c @@ -1532,33 +1532,12 @@ ip2k_elf_relocate_section (output_bfd, info, input_bfd, input_section, } else { - h = sym_hashes [r_symndx - symtab_hdr->sh_info]; + bfd_boolean warned; + bfd_boolean unresolved_reloc; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned); name = h->root.root.string; - - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - relocation = h->root.u.def.value + BASEADDR (sec); - } - - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (! info->shared || info->no_undefined)))) - return FALSE; - relocation = 0; - } } /* Finally, the sole IP2K-specific part. */ diff --git a/bfd/elf32-iq2000.c b/bfd/elf32-iq2000.c index e2a3b17aee5..f85ffac8431 100644 --- a/bfd/elf32-iq2000.c +++ b/bfd/elf32-iq2000.c @@ -618,48 +618,14 @@ iq2000_elf_relocate_section (output_bfd, info, input_bfd, input_section, } else { - h = sym_hashes [r_symndx]; - - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; + bfd_boolean unresolved_reloc; + bfd_boolean warned; + + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, + symtab_hdr, relocation, + sec, unresolved_reloc, info, warned); name = h->root.root.string; - - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); -#ifdef DEBUG - fprintf (stderr, - "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n", - sec->name, name, h->root.u.def.value, - sec->output_section->vma, sec->output_offset, relocation); -#endif - } - else if (h->root.type == bfd_link_hash_undefweak) - { -#ifdef DEBUG - fprintf (stderr, "undefined: sec: %s, name: %s\n", - sec->name, name); -#endif - relocation = 0; - } - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (!info->shared || info->no_undefined)))) - return FALSE; -#ifdef DEBUG - fprintf (stderr, "unknown: name: %s\n", name); -#endif - relocation = 0; - } } switch (r_type) diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index 1320429cf1f..7688bfd9fc2 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -1398,6 +1398,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, sym = NULL; sec = NULL; unresolved_reloc = FALSE; + if (r_symndx < symtab_hdr->sh_info) { sym = local_syms + r_symndx; @@ -1406,42 +1407,9 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, } else { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; + bfd_boolean warned; - relocation = 0; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if (sec->output_section == NULL) - /* Set a flag that will be cleared later if we find a - relocation value for this symbol. output_section - is typically NULL for symbols satisfied by a shared - library. */ - unresolved_reloc = TRUE; - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - ; - else if (info->shared - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - ; - else - { - if (!(info->callbacks->undefined_symbol - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (!info->shared || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - } + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned); } switch (r_type) diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index b78a64c0cf5..3bffc70c786 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -4718,6 +4718,7 @@ ppc_elf_relocate_section (bfd *output_bfd, unresolved_reloc = FALSE; warned = FALSE; r_symndx = ELF32_R_SYM (rel->r_info); + if (r_symndx < symtab_hdr->sh_info) { sym = local_syms + r_symndx; @@ -4728,44 +4729,12 @@ ppc_elf_relocate_section (bfd *output_bfd, } else { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, + symtab_hdr, relocation, sec, + unresolved_reloc, info, + warned); + sym_name = h->root.root.string; - - relocation = 0; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - /* Set a flag that will be cleared later if we find a - relocation value for this symbol. output_section - is typically NULL for symbols satisfied by a shared - library. */ - if (sec->output_section == NULL) - unresolved_reloc = TRUE; - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - ; - else if (!info->executable - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - ; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_offset, (info->executable - || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - warned = TRUE; - } } /* TLS optimizations. Replace instruction sequences and relocs @@ -5500,49 +5469,16 @@ ppc_elf_relocate_section (bfd *output_bfd, } else { - long indx; - - indx = r_symndx - symtab_hdr->sh_info; - h = elf_sym_hashes (input_bfd)[indx]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - value = 0; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sym_sec = h->root.u.def.section; - - /* Detect the cases that sym_sec->output_section is - expected to be NULL -- all cases in which the symbol - is defined in another shared module. This includes - PLT relocs for which we've created a PLT entry and - other relocs for which we're prepared to create - dynamic relocations. */ - /* ??? Just accept it NULL and continue. */ - - if (sym_sec->output_section != NULL) - { - value = (h->root.u.def.value - + sym_sec->output_section->vma - + sym_sec->output_offset); - } - } - else if (!info->executable - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - ; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (info->executable || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - continue; - } + bfd_boolean warned; + bfd_boolean unresolved_reloc; + + RELOC_FOR_GLOBAL_SYMBOL (h, elf_sym_hashes (input_bfd), + r_symndx, symtab_hdr, + value, sym_sec, + unresolved_reloc, info, + warned); + if (warned) + continue; } hit_addr = contents + rel->r_offset; value += rel->r_addend; diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index bead5d02758..5b07ab0db7b 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -2331,45 +2331,12 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, } else { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; + bfd_boolean warned ATTRIBUTE_UNUSED; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if (sec->output_section == NULL) - { - /* Set a flag that will be cleared later if we find a - relocation value for this symbol. output_section - is typically NULL for symbols satisfied by a shared - library. */ - unresolved_reloc = TRUE; - relocation = 0; - } - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (!info->executable - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - relocation = 0; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (info->executable || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - relocation = 0; - } + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, + symtab_hdr, relocation, sec, + unresolved_reloc, info, + warned); } switch (r_type) diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index b509536e476..368bbca37a1 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -4663,6 +4663,8 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, } else { + /* FIXME: Ought to make use of the RELOC_FOR_GLOBAL_SYMBOL macro. */ + /* Section symbol are never (?) placed in the hash table, so we can just ignore hash relocations when creating a relocatable object file. */ @@ -4765,16 +4767,17 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, else if (h->root.type == bfd_link_hash_undefweak) relocation = 0; else if (! info->executable - && ! info->no_undefined + && info->unresolved_syms_in_objects == RM_IGNORE && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) relocation = 0; else { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (info->executable || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) + if (! info->callbacks->undefined_symbol + (info, h->root.root.string, input_bfd, + input_section, rel->r_offset, + ((info->shared && info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR) + || (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR) + || ELF_ST_VISIBILITY (h->other)))) return FALSE; relocation = 0; } diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c index d8ad11d77ab..50d968e6734 100644 --- a/bfd/elf32-sparc.c +++ b/bfd/elf32-sparc.c @@ -2186,42 +2186,12 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section, } else { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; + bfd_boolean warned ATTRIBUTE_UNUSED; - relocation = 0; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if (sec->output_section == NULL) - /* Set a flag that will be cleared later if we find a - relocation value for this symbol. output_section - is typically NULL for symbols satisfied by a shared - library. */ - unresolved_reloc = TRUE; - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - ; - else if (!info->executable - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - ; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (info->executable || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - } + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, + symtab_hdr, relocation, sec, + unresolved_reloc, info, + warned); } switch (r_type) diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c index 3ad97478856..7d78e0ff3bd 100644 --- a/bfd/elf32-vax.c +++ b/bfd/elf32-vax.c @@ -1487,15 +1487,17 @@ elf_vax_relocate_section (output_bfd, info, input_bfd, input_section, } else { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type == bfd_link_hash_defined + bfd_boolean unresolved_reloc; + bfd_boolean warned; + + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, + symtab_hdr, relocation, sec, + unresolved_reloc, info, + warned); + + if ((h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if ((r_type == R_VAX_PLT32 + && ((r_type == R_VAX_PLT32 && h->plt.offset != (bfd_vma) -1 && elf_hash_table (info)->dynamic_sections_created) || (r_type == R_VAX_GOT32 @@ -1524,34 +1526,11 @@ elf_vax_relocate_section (output_bfd, info, input_bfd, input_section, || r_type == R_VAX_32 || r_type == R_VAX_PC8 || r_type == R_VAX_PC16 - || r_type == R_VAX_PC32))) - { - /* In these cases, we don't need the relocation - value. We check specially because in some - obscure cases sec->output_section will be NULL. */ - relocation = 0; - } - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) + || r_type == R_VAX_PC32)))) + /* In these cases, we don't need the relocation + value. We check specially because in some + obscure cases sec->output_section will be NULL. */ relocation = 0; - else if (info->shared - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - relocation = 0; - else - { - if (!(info->callbacks->undefined_symbol - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (!info->shared || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - relocation = 0; - } } switch (r_type) diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 8b09305eab2..251c3323959 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -2009,45 +2009,15 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, } else { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - relocation = 0; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - - if (sec->output_section == NULL) - /* Set a flag that will be cleared later if we find a - relocation value for this symbol. output_section - is typically NULL for symbols satisfied by a shared - library. */ - unresolved_reloc = TRUE; - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, + symtab_hdr, relocation, sec, + unresolved_reloc, info, + warned); + + if (relocation == 0 + && !unresolved_reloc + && h->root.type == bfd_link_hash_undefweak) is_weak_undef = TRUE; - else if (info->shared - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - ; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (!info->shared || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - warned = TRUE; - } } if (relaxing_section) @@ -3575,6 +3545,7 @@ hash_literal_value (src) const literal_value *src; { unsigned hash_val; + if (r_reloc_is_const (&src->r_rel)) return hash_bfd_vma (src->value); @@ -3583,9 +3554,9 @@ hash_literal_value (src) /* Now check for the same section and the same elf_hash. */ if (r_reloc_is_defined (&src->r_rel)) - hash_val += hash_bfd_vma ((bfd_vma) r_reloc_get_section (&src->r_rel)); + hash_val += hash_bfd_vma ((bfd_vma) (unsigned) r_reloc_get_section (&src->r_rel)); else - hash_val += hash_bfd_vma ((bfd_vma) r_reloc_get_hash_entry (&src->r_rel)); + hash_val += hash_bfd_vma ((bfd_vma) (unsigned) r_reloc_get_hash_entry (&src->r_rel)); return hash_val; } diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 4511f71cb5e..0b64bd310f8 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -3074,7 +3074,7 @@ elf64_alpha_check_relocs (abfd, info, sec, relocs) this may help reduce memory usage and processing time later. */ maybe_dynamic = FALSE; if (h && ((info->shared - && (!info->symbolic || info->allow_shlib_undefined)) + && (!info->symbolic || info->unresolved_syms_in_shared_libs == RM_IGNORE)) || ! (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) || h->root.root.type == bfd_link_hash_defweak)) maybe_dynamic = TRUE; @@ -4445,48 +4445,25 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section, } else { - h = alpha_elf_sym_hashes (input_bfd)[r_symndx - symtab_hdr->sh_info]; - - while (h->root.root.type == bfd_link_hash_indirect - || h->root.root.type == bfd_link_hash_warning) - h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link; + bfd_boolean warned; + bfd_boolean unresolved_reloc; + struct elf_link_hash_entry *hh; + + RELOC_FOR_GLOBAL_SYMBOL (hh, + (struct elf_link_hash_entry *) alpha_elf_sym_hashes (input_bfd), + r_symndx, symtab_hdr, value, + sec, unresolved_reloc, info, + warned); + + if (warned) + continue; - value = 0; - if (h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak) - { - sec = h->root.root.u.def.section; - - /* Detect the cases that sym_sec->output_section is - expected to be NULL -- all cases in which the symbol - is defined in another shared module. This includes - PLT relocs for which we've created a PLT entry and - other relocs for which we're prepared to create - dynamic relocations. */ - /* ??? Just accept it NULL and continue. */ - - if (sec->output_section != NULL) - value = (h->root.root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.root.type == bfd_link_hash_undefweak) + if (value == 0 + && ! unresolved_reloc + && hh->root.type == bfd_link_hash_undefweak) undef_weak_ref = TRUE; - else if (!info->executable - && !info->no_undefined - && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT) - ; - else - { - if (!((*info->callbacks->undefined_symbol) - (info, h->root.root.root.string, input_bfd, - input_section, rel->r_offset, - (info->executable || info->no_undefined - || ELF_ST_VISIBILITY (h->root.other))))) - return FALSE; - continue; - } + h = (struct alpha_elf_link_hash_entry *) hh; dynamic_symbol_p = alpha_elf_dynamic_symbol_p (&h->root, info); gotent = h->got_entries; } diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c index f3398c15030..9523862e354 100644 --- a/bfd/elf64-hppa.c +++ b/bfd/elf64-hppa.c @@ -710,13 +710,14 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) relend = relocs + sec->reloc_count; for (rel = relocs; rel < relend; ++rel) { - enum { - NEED_DLT = 1, - NEED_PLT = 2, - NEED_STUB = 4, - NEED_OPD = 8, - NEED_DYNREL = 16, - }; + enum + { + NEED_DLT = 1, + NEED_PLT = 2, + NEED_STUB = 4, + NEED_OPD = 8, + NEED_DYNREL = 16, + }; struct elf_link_hash_entry *h = NULL; unsigned long r_symndx = ELF64_R_SYM (rel->r_info); @@ -746,7 +747,7 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) this may help reduce memory usage and processing time later. */ maybe_dynamic = FALSE; if (h && ((info->shared - && (!info->symbolic || info->allow_shlib_undefined) ) + && (!info->symbolic || info->unresolved_syms_in_shared_libs == RM_IGNORE)) || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) || h->root.type == bfd_link_hash_defweak)) maybe_dynamic = TRUE; diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index e7666507c50..2042e6ae323 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -7362,44 +7362,11 @@ ppc64_elf_relocate_section (bfd *output_bfd, } else { - /* It's a global symbol. */ - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, + symtab_hdr, relocation, sec, + unresolved_reloc, info, + warned); sym_name = h->root.root.string; - relocation = 0; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if (sec->output_section == NULL) - /* Set a flag that will be cleared later if we find a - relocation value for this symbol. output_section - is typically NULL for symbols satisfied by a shared - library. */ - unresolved_reloc = TRUE; - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - ; - else if (!info->executable - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - ; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_offset, (info->executable - || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - warned = TRUE; - } } /* TLS optimizations. Replace instruction sequences and relocs diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 0a5e4724672..de712f77e3b 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -2301,45 +2301,12 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, } else { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; + bfd_boolean warned ATTRIBUTE_UNUSED; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if (sec->output_section == NULL) - { - /* Set a flag that will be cleared later if we find a - relocation value for this symbol. output_section - is typically NULL for symbols satisfied by a shared - library. */ - unresolved_reloc = TRUE; - relocation = 0; - } - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (!info->executable - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - relocation = 0; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (info->executable || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - relocation = 0; - } + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, + symtab_hdr, relocation, sec, + unresolved_reloc, info, + warned); } switch (r_type) diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index 2abf3c135a2..e0bc8df7e5d 100644 --- a/bfd/elf64-sh64.c +++ b/bfd/elf64-sh64.c @@ -1610,6 +1610,8 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, } else { + /* ??? Could we use the RELOC_FOR_GLOBAL_SYMBOL macro here ? */ + /* Section symbols are never (?) placed in the hash table, so we can just ignore hash relocations when creating a relocatable object file. */ @@ -1699,7 +1701,9 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, } else if (h->root.type == bfd_link_hash_undefweak) relocation = 0; - else if (info->shared && !info->symbolic && !info->no_undefined) + else if (info->shared + && !info->symbolic + && info->unresolved_syms_in_objects == RM_IGNORE) relocation = 0; else { diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c index d554134b349..a74a7f339c0 100644 --- a/bfd/elf64-sparc.c +++ b/bfd/elf64-sparc.c @@ -2074,42 +2074,14 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, } else { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; + bfd_boolean warned; - relocation = 0; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, + symtab_hdr, relocation, sec, + unresolved_reloc, info, + warned); + if (warned) { - sec = h->root.u.def.section; - if (sec->output_section == NULL) - /* Set a flag that will be cleared later if we find a - relocation value for this symbol. output_section - is typically NULL for symbols satisfied by a shared - library. */ - unresolved_reloc = TRUE; - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - ; - else if (!info->executable - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - ; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (info->executable || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - /* To avoid generating warning messages about truncated relocations, set the relocation's address to be the same as the start of this section. */ diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 970d742d0d1..8aed4982337 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1827,45 +1827,12 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, } else { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; + bfd_boolean warned; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if (sec->output_section == NULL) - { - /* Set a flag that will be cleared later if we find a - relocation value for this symbol. output_section - is typically NULL for symbols satisfied by a shared - library. */ - unresolved_reloc = TRUE; - relocation = 0; - } - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (!info->executable - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - relocation = 0; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (info->executable || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - relocation = 0; - } + RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, + symtab_hdr, relocation, sec, + unresolved_reloc, info, + warned); } /* When generating a shared object, the relocations handled here are copied into the output file to be resolved at run time. */ diff --git a/bfd/elflink.h b/bfd/elflink.h index 5e9cb3c0a9e..d6679938963 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -4363,24 +4363,19 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data) return TRUE; } - /* If we are not creating a shared library, and this symbol is - referenced by a shared library but is not defined anywhere, then - warn that it is undefined. If we do not do this, the runtime - linker will complain that the symbol is undefined when the - program is run. We don't have to worry about symbols that are - referenced by regular files, because we will already have issued - warnings for them. */ - if (! finfo->info->relocatable - && (finfo->info->executable - || ! finfo->info->allow_shlib_undefined) - && h->root.type == bfd_link_hash_undefined + /* If we have an undefined symbol reference here then it must have + come from a shared library that is being linked in. (Undefined + references in regular files have already been handled). If we + are reporting errors for this situation then do so now. */ + if (h->root.type == bfd_link_hash_undefined && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0 && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0 - && ! elf_link_check_versioned_symbol (finfo->info, h)) + && ! elf_link_check_versioned_symbol (finfo->info, h) + && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE) { if (! ((*finfo->info->callbacks->undefined_symbol) (finfo->info, h->root.root.string, h->root.u.undef.abfd, - NULL, 0, TRUE))) + NULL, 0, finfo->info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR))) { eoinfo->failed = TRUE; return FALSE; @@ -4390,10 +4385,9 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data) /* We should also warn if a forced local symbol is referenced from shared libraries. */ if (! finfo->info->relocatable - && (! finfo->info->shared || ! finfo->info->allow_shlib_undefined) + && (! finfo->info->shared) && (h->elf_link_hash_flags - & (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC - | ELF_LINK_DYNAMIC_DEF | ELF_LINK_DYNAMIC_WEAK)) + & (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_DYNAMIC_DEF | ELF_LINK_DYNAMIC_WEAK)) == (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC) && ! elf_link_check_versioned_symbol (finfo->info, h)) { diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index 3175b815f31..5cc311086ba 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -2162,7 +2162,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs) this may help reduce memory usage and processing time later. */ maybe_dynamic = FALSE; if (h && ((!info->executable - && (!info->symbolic || info->allow_shlib_undefined)) + && (!info->symbolic || info->unresolved_syms_in_shared_libs == RM_IGNORE)) || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) || h->root.type == bfd_link_hash_defweak)) maybe_dynamic = TRUE; @@ -3852,52 +3852,19 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, } else { - long indx; + bfd_boolean unresolved_reloc; + bfd_boolean warned; - /* Reloc against global symbol. */ - indx = r_symndx - symtab_hdr->sh_info; - h = elf_sym_hashes (input_bfd)[indx]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - value = 0; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sym_sec = h->root.u.def.section; - - /* Detect the cases that sym_sec->output_section is - expected to be NULL -- all cases in which the symbol - is defined in another shared module. This includes - PLT relocs for which we've created a PLT entry and - other relocs for which we're prepared to create - dynamic relocations. */ - /* ??? Just accept it NULL and continue. */ + RELOC_FOR_GLOBAL_SYMBOL (h, elf_sym_hashes (input_bfd), + r_symndx, + symtab_hdr, value, sym_sec, + unresolved_reloc, info, + warned); - if (sym_sec->output_section != NULL) - { - value = (h->root.u.def.value - + sym_sec->output_section->vma - + sym_sec->output_offset); - } - } - else if (h->root.type == bfd_link_hash_undefweak) + if (h->root.type == bfd_link_hash_undefweak) undef_weak_ref = TRUE; - else if (! info->executable - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - ; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (info->executable || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - continue; - } + else if (warned) + continue; } hit_addr = contents + rel->r_offset; diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 2ff49417ea7..919593d1873 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -3008,6 +3008,8 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info, } else { + /* ??? Could we use RELOC_FOR_GLOBAL_SYMBOL here ? */ + /* For global symbols we look up the symbol in the hash-table. */ h = ((struct mips_elf_link_hash_entry *) elf_sym_hashes (input_bfd) [r_symndx - extsymoff]); @@ -3021,7 +3023,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info, /* See if this is the special _gp_disp symbol. Note that such a symbol must always be a global symbol. */ - if (strcmp (h->root.root.root.string, "_gp_disp") == 0 + if (strcmp (*namep, "_gp_disp") == 0 && ! NEWABI_P (input_bfd)) { /* Relocations against _gp_disp are permitted only with @@ -3054,11 +3056,11 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info, addresses. */ symbol = 0; else if (info->shared - && !info->no_undefined + && info->unresolved_syms_in_objects == RM_IGNORE && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT) symbol = 0; - else if (strcmp (h->root.root.root.string, "_DYNAMIC_LINK") == 0 || - strcmp (h->root.root.root.string, "_DYNAMIC_LINKING") == 0) + else if (strcmp (*namep, "_DYNAMIC_LINK") == 0 || + strcmp (*namep, "_DYNAMIC_LINKING") == 0) { /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol or _DYNAMIC_LINKING(for normal mips) symbol @@ -3075,7 +3077,8 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info, if (! ((*info->callbacks->undefined_symbol) (info, h->root.root.root.string, input_bfd, input_section, relocation->r_offset, - (!info->shared || info->no_undefined + ((info->shared && info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR) + || (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR) || ELF_ST_VISIBILITY (h->root.other))))) return bfd_reloc_undefined; symbol = 0; diff --git a/include/ChangeLog b/include/ChangeLog index fb8eaf728bf..971de5060a9 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,12 @@ +2003-08-20 Nick Clifton + + * bfdlink.h (enum report_method): New enum. Describes how to + report something. + (struct bfd_link_info): Delete fields 'no_undefined' and + 'allow_shlib_undefined'. Replace with + 'unresolved_symbols_in_objects' and + 'unresolved_symbols_in_shared_libs'. + 2003-08-07 Alan Modra * bfdlink.h: Remove PARAMS macro. Replace PTR with void *. diff --git a/include/bfdlink.h b/include/bfdlink.h index e8fc65f4bd0..c174dcdc698 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -198,6 +198,19 @@ struct bfd_sym_chain const char *name; }; +/* How to handle unresolved symbols. + There are four possibilities which are enumerated below: */ +enum report_method +{ + /* This is the initial value when then link_info structure is created. + It allows the various stages of the linker to determine whether they + allowed to set the value. */ + RM_NOT_YET_SET = 0, + RM_IGNORE, + RM_GENERATE_WARNING, + RM_GENERATE_ERROR +}; + /* This structure holds all the information needed to communicate between BFD and the linker when doing a link. */ @@ -238,24 +251,6 @@ struct bfd_link_info need much more time and therefore must be explicitly selected. */ unsigned int optimize: 1; - /* TRUE if BFD should generate errors for undefined symbols - even if generating a shared object. */ - unsigned int no_undefined: 1; - - /* TRUE if BFD should allow undefined symbols in shared objects even - when no_undefined is set to disallow undefined symbols. The net - result will be that undefined symbols in regular objects will - still trigger an error, but undefined symbols in shared objects - will be ignored. The implementation of no_undefined makes the - assumption that the runtime linker will choke on undefined - symbols. However there is at least one system (BeOS) where - undefined symbols in shared libraries is normal since the kernel - patches them at load time to select which function is most - appropriate for the current architecture. I.E. dynamically - select an appropriate memset function. Apparently it is also - normal for HPPA shared libraries to have undefined symbols. */ - unsigned int allow_shlib_undefined: 1; - /* TRUE if ok to have multiple definition. */ unsigned int allow_multiple_definition: 1; @@ -305,6 +300,17 @@ struct bfd_link_info flags. */ unsigned int noexecstack: 1; + /* What to do with unresolved symbols in an object file. + When producing static binaries the default is GENERATE_ERROR. + When producing dynamic binaries the default is IGNORE. The + assumption with dynamic binaries is that the reference will be + resolved at load/execution time. */ + enum report_method unresolved_syms_in_objects; + + /* What to do with unresolved symbols in a shared library. + The same defaults apply. */ + enum report_method unresolved_syms_in_shared_libs; + /* Which symbols to strip. */ enum bfd_link_strip strip; -- cgit v1.2.1