GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ along with this program; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* This file is based on a preliminary PowerPC ELF ABI. The
information may not match the final PowerPC ELF ABI. It includes
#define DTP_OFFSET 0x8000
/* Will references to this symbol always reference the symbol
- in this object? */
+ 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->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) \
+#define SYMBOL_CALLS_LOCAL(INFO, H) \
((! INFO->shared \
|| INFO->symbolic \
|| H->dynindx == -1 \
struct ppc_elf_dyn_relocs *dyn_relocs;
/* Contexts in which symbol is used in the GOT (or TOC).
- TLS_GD .. TLS_EXPLICIT bits are or'd into the mask as the
+ TLS_GD .. TLS_TLS bits are or'd into the mask as the
corresponding relocs are encountered during check_relocs.
tls_optimize clears TLS_GD .. TLS_TPREL when optimizing to
indicate the corresponding GOT entry type is not needed. */
return &ret->elf.root;
}
+/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
+ copying dynamic variables from a shared lib into an app's dynbss
+ section, and instead use a dynamic relocation to point into the
+ shared lib. */
+#define ELIMINATE_COPY_RELOCS 1
+
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
edir->tls_mask |= eind->tls_mask;
- _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ if (ELIMINATE_COPY_RELOCS
+ && ind->root.type != bfd_link_hash_indirect
+ && (dir->elf_link_hash_flags & ELF_LINK_HASH_DYNAMIC_ADJUSTED) != 0)
+ /* If called to transfer flags for a weakdef during processing
+ of elf_adjust_dynamic_symbol, don't copy ELF_LINK_NON_GOT_REF.
+ We clear it ourselves for ELIMINATE_COPY_RELOCS. */
+ dir->elf_link_hash_flags |=
+ (ind->elf_link_hash_flags & (ELF_LINK_HASH_REF_DYNAMIC
+ | ELF_LINK_HASH_REF_REGULAR
+ | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
+ else
+ _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
}
\f
static reloc_howto_type *ppc_elf_howto_table[(int) R_PPC_max];
{
unsigned int i, type;
- for (i = 0; i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]); i++)
+ for (i = 0;
+ i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]);
+ i++)
{
type = ppc_elf_howto_raw[i].type;
- BFD_ASSERT (type < sizeof (ppc_elf_howto_table) / sizeof (ppc_elf_howto_table[0]));
+ if (type >= (sizeof (ppc_elf_howto_table)
+ / sizeof (ppc_elf_howto_table[0])))
+ abort ();
ppc_elf_howto_table[type] = &ppc_elf_howto_raw[i];
}
}
2/ The branch is predicted as not taken.
3/ The branch is taken.
4/ The branch is located in the last 5 words of a page.
- (The EOP limit is 5 by default but may be specified as any value from 1-10.)
+ (The EOP limit is 5 by default but may be specified as any value
+ from 1-10.)
Our software solution is to detect these problematic branches in a
linker pass and modify them as follows:
return bfd_set_section_flags (abfd, s, flags);
}
-/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
- copying dynamic variables from a shared lib into an app's dynbss
- section, and instead use a dynamic relocation to point into the
- shared lib. */
-#define ELIMINATE_COPY_RELOCS 1
-
/* Adjust a symbol defined by a dynamic object and referenced by a
regular object. The current definition is in some section of the
dynamic object, but we're not including those sections. We have to
/* Clear procedure linkage table information for any symbol that
won't need a .plt entry. */
if (! htab->elf.dynamic_sections_created
- || SYMBOL_CALLS_LOCAL (info, h)
+ || SYMBOL_CALLS_LOCAL (info, h)
|| h->plt.refcount <= 0)
{
/* A PLT entry is not required/allowed when:
htab = ppc_elf_hash_table (info);
if (htab->elf.dynamic_sections_created
- && h->plt.refcount > 0)
+ && h->plt.refcount > 0
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
{
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1
else
htab->got->_raw_size += 4;
dyn = htab->elf.dynamic_sections_created;
- if (info->shared
- || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, &eh->elf))
+ if ((info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, &eh->elf))
+ && (ELF_ST_VISIBILITY (eh->elf.other) == STV_DEFAULT
+ || eh->elf.root.type != bfd_link_hash_undefweak))
{
/* All the entries we allocated need relocs. */
htab->relgot->_raw_size
pp = &p->next;
}
}
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak)
+ eh->dyn_relocs = NULL;
}
else if (ELIMINATE_COPY_RELOCS)
{
case R_PPC_REL14_BRNTAKEN:
case R_PPC_REL32:
if (h == NULL
- || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
- || SYMBOL_REFERENCES_LOCAL (info, h))
+ || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
break;
/* fall through */
case R_PPC_REL14_BRNTAKEN:
case R_PPC_REL32:
if (h == NULL
- || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
- || SYMBOL_REFERENCES_LOCAL (info, h))
+ || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
break;
/* Fall thru */
}
/* Generate relocs for the dynamic linker. */
- if (info->shared || indx != 0)
+ if ((info->shared || indx != 0)
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
{
outrel.r_offset = (htab->got->output_section->vma
+ htab->got->output_offset
/* Fall thru. */
if ((info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
&& (MUST_BE_DYN_RELOC (r_type)
|| (h != NULL
&& h->dynindx != -1