diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d2b0a10014..eaf2b9f453 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,21 @@ +2003-05-13 Alan Modra + H.J. Lu + + * elf-bfd.h (SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Move from + elf32-ppc.c. Add ELF_LINK_FORCED_LOCAL check. + * elf32-ppc.c: (SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Delete. + (allocate_dynrelocs): Use SYMBOL_REFERENCES_LOCAL for dynreloc check. + (ppc_elf_relocate_section): Likewise. + * elf64-ppc.c (allocate_dynrelocs): Likewise. + (ppc64_elf_relocate_section): Likewise. Use for .got relocs too. + (ppc64_elf_adjust_dynamic_symbol): Don't assume symbols with .plt + relocs need no other types. + * elf32-i386.c (allocate_dynrelocs): Use SYMBOL_REFERENCES_LOCAL for + dynreloc check. + (elf_i386_relocate_section): Likewise. Use for .got relocs too. + (elf_i386_finish_dynamic_symbol): Use SYMBOL_REFERENCES_LOCAL for + .got relocs. + 2003-05-13 Kaz Kojima * elf32-sh.c (sh_elf_adjust_dynamic_symbol): For weak symbols, diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 073aee8a17..46f612a63d 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -210,6 +210,30 @@ struct elf_link_hash_entry #define ELF_LINK_DYNAMIC_WEAK 040000 }; +/* Will references to this symbol always reference the symbol + in this object? STV_PROTECTED is excluded from the visibility test + here so that function pointer comparisons work properly. Since + function symbols not defined in an app are set to their .plt entry, + it's necessary for shared libs to also reference the .plt even + though the symbol is really local to the shared lib. */ +#define SYMBOL_REFERENCES_LOCAL(INFO, H) \ + ((! (INFO)->shared \ + || (INFO)->symbolic \ + || (H)->dynindx == -1 \ + || ELF_ST_VISIBILITY ((H)->other) == STV_INTERNAL \ + || ELF_ST_VISIBILITY ((H)->other) == STV_HIDDEN \ + || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) \ + && ((H)->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0) + +/* Will _calls_ to this symbol always call the version in this object? */ +#define SYMBOL_CALLS_LOCAL(INFO, H) \ + ((! (INFO)->shared \ + || (INFO)->symbolic \ + || (H)->dynindx == -1 \ + || ELF_ST_VISIBILITY ((H)->other) != STV_DEFAULT \ + || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) \ + && ((H)->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0) + /* Records local symbols to be emitted in the dynamic symbol table. */ struct elf_link_local_dynamic_entry diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 320e985983..8fbe8a1c60 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1679,9 +1679,7 @@ allocate_dynrelocs (h, inf) if (info->shared) { - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 - && ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0 - || info->symbolic)) + if (SYMBOL_REFERENCES_LOCAL (info, h)) { struct elf_i386_dyn_relocs **pp; @@ -2305,10 +2303,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, dyn = htab->elf.dynamic_sections_created; if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) || (info->shared - && (info->symbolic - || h->dynindx == -1 - || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) + && SYMBOL_REFERENCES_LOCAL (info, h)) || (ELF_ST_VISIBILITY (h->other) && h->root.type == bfd_link_hash_undefweak)) { @@ -2439,10 +2434,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, || h->root.type != bfd_link_hash_undefweak) && (r_type != R_386_PC32 || (h != NULL - && h->dynindx != -1 - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)))) + && !SYMBOL_REFERENCES_LOCAL (info, h)))) || (ELIMINATE_COPY_RELOCS && !info->shared && h != NULL @@ -3172,10 +3164,7 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym) The entry in the global offset table will already have been initialized in the relocate_section function. */ if (info->shared - && (info->symbolic - || h->dynindx == -1 - || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) + && SYMBOL_REFERENCES_LOCAL (info, h)) { BFD_ASSERT((h->got.offset & 1) != 0); rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 64c2839f42..ca9fbd9e21 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -147,27 +147,6 @@ static bfd_boolean ppc_elf_grok_psinfo #define TP_OFFSET 0x7000 #define DTP_OFFSET 0x8000 -/* Will references to this symbol always reference the symbol - in this object? STV_PROTECTED is excluded from the visibility test - here so that function pointer comparisons work properly. Since - function symbols not defined in an app are set to their .plt entry, - it's necessary for shared libs to also reference the .plt even - though the symbol is really local to the shared lib. */ -#define SYMBOL_REFERENCES_LOCAL(INFO, H) \ - ((! INFO->shared \ - || INFO->symbolic \ - || H->dynindx == -1 \ - || ELF_ST_VISIBILITY (H->other) == STV_INTERNAL \ - || ELF_ST_VISIBILITY (H->other) == STV_HIDDEN) \ - && (H->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0) - -/* Will _calls_ to this symbol always call the version in this object? */ -#define SYMBOL_CALLS_LOCAL(INFO, H) \ - ((! INFO->shared \ - || INFO->symbolic \ - || H->dynindx == -1 \ - || ELF_ST_VISIBILITY (H->other) != STV_DEFAULT) \ - && (H->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0) /* The PPC linker needs to keep track of the number of relocs that it decides to copy as dynamic relocs in check_relocs for each symbol. @@ -2817,11 +2796,10 @@ allocate_dynrelocs (h, inf) defined in regular objects. For the normal shared case, discard space for relocs that have become local due to symbol visibility changes. */ + if (info->shared) { - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 - && ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0 - || info->symbolic)) + if (SYMBOL_REFERENCES_LOCAL (info, h)) { struct ppc_elf_dyn_relocs **pp; @@ -5013,10 +4991,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, || h->root.type != bfd_link_hash_undefweak) && (MUST_BE_DYN_RELOC (r_type) || (h != NULL - && h->dynindx != -1 - && (!info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)))) + && !SYMBOL_REFERENCES_LOCAL (info, h)))) || (ELIMINATE_COPY_RELOCS && !info->shared && (input_section->flags & SEC_ALLOC) != 0 diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 011e637b12..331c0ba232 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -4513,7 +4513,6 @@ ppc64_elf_adjust_dynamic_symbol (info, h) h->plt.plist = NULL; h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; } - return TRUE; } else h->plt.plist = NULL; @@ -5622,9 +5621,7 @@ allocate_dynrelocs (h, inf) if (info->shared) { - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 - && ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0 - || info->symbolic)) + if (SYMBOL_REFERENCES_LOCAL (info, h)) { struct ppc_dyn_relocs **pp; @@ -7604,12 +7601,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, bfd_boolean dyn = htab->elf.dynamic_sections_created; if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) || (info->shared - && (info->symbolic - || h->dynindx == -1 - || (h->elf_link_hash_flags - & ELF_LINK_FORCED_LOCAL)) - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR))) + && SYMBOL_REFERENCES_LOCAL (info, h))) /* This is actually a static link, or it is a -Bsymbolic link and the symbol is defined locally, or the symbol was forced to be local @@ -7882,10 +7874,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, || h->root.type != bfd_link_hash_undefweak) && (MUST_BE_DYN_RELOC (r_type) || (h != NULL - && h->dynindx != -1 - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)))) + && !SYMBOL_REFERENCES_LOCAL (info, h)))) || (ELIMINATE_COPY_RELOCS && !info->shared && h != NULL @@ -7920,13 +7909,8 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, if (skip) memset (&outrel, 0, sizeof outrel); else if (h != NULL - && h->dynindx != -1 - && !is_opd - && (!MUST_BE_DYN_RELOC (r_type) - || !info->shared - || !info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) + && !SYMBOL_REFERENCES_LOCAL (info, h) + && !is_opd) outrel.r_info = ELF64_R_INFO (h->dynindx, r_type); else {