* elflink.c (_bfd_elf_dynamic_symbol_p): New.

* elf-bfd.h (_bfd_elf_dynamic_symbol_p): Declare it.
        (SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Use it.
        * elf32-xtensa.c (xtensa_elf_dynamic_symbol_p): Likewise.
        * elf64-alpha.c (alpha_elf_dynamic_symbol_p): Likewise.
        * elf64-hppa.c (elf64_hppa_dynamic_symbol_p): Likewise.
        * elfxx-ia64.c (elfNN_ia64_dynamic_symbol_p): Likewise.
        Update all callers to provide the relocation being resolved.
This commit is contained in:
Richard Henderson 2003-07-18 21:09:28 +00:00
parent 22b0d388c7
commit 986a241f8b
7 changed files with 121 additions and 155 deletions

View file

@ -1,3 +1,14 @@
2003-07-18 Richard Henderson <rth@redhat.com>
* elflink.c (_bfd_elf_dynamic_symbol_p): New.
* elf-bfd.h (_bfd_elf_dynamic_symbol_p): Declare it.
(SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Use it.
* elf32-xtensa.c (xtensa_elf_dynamic_symbol_p): Likewise.
* elf64-alpha.c (alpha_elf_dynamic_symbol_p): Likewise.
* elf64-hppa.c (elf64_hppa_dynamic_symbol_p): Likewise.
* elfxx-ia64.c (elfNN_ia64_dynamic_symbol_p): Likewise.
Update all callers to provide the relocation being resolved.
2003-07-17 Shaun Jackman <sjackman@pathwayconnect.com>
* config.bfd (arm-wince-pe): Add -DARM_COFF_BUGFIX to

View file

@ -211,23 +211,12 @@ struct elf_link_hash_entry
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)->executable \
|| (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)
#define SYMBOL_REFERENCES_LOCAL(INFO, H) \
_bfd_elf_dynamic_symbol_p (H, INFO, 1)
/* Will _calls_ to this symbol always call the version in this object? */
#define SYMBOL_CALLS_LOCAL(INFO, H) \
(((INFO)->executable \
|| (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)
#define SYMBOL_CALLS_LOCAL(INFO, H) \
_bfd_elf_dynamic_symbol_p (H, INFO, 0)
/* Records local symbols to be emitted in the dynamic symbol table. */
@ -1506,6 +1495,9 @@ extern bfd_boolean _bfd_elf_adjust_dynamic_symbol
extern bfd_boolean _bfd_elf_link_sec_merge_syms
PARAMS ((struct elf_link_hash_entry *, PTR));
extern bfd_boolean _bfd_elf_dynamic_symbol_p
PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean));
extern const bfd_target *bfd_elf32_object_p
PARAMS ((bfd *));
extern const bfd_target *bfd_elf32_core_file_p

View file

@ -1838,38 +1838,9 @@ xtensa_elf_dynamic_symbol_p (info, h)
struct bfd_link_info *info;
struct elf_link_hash_entry *h;
{
if (h == NULL)
return FALSE;
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->dynindx == -1)
return FALSE;
if (h->root.type == bfd_link_hash_undefweak
|| h->root.type == bfd_link_hash_defweak)
return TRUE;
switch (ELF_ST_VISIBILITY (h->other))
{
case STV_DEFAULT:
break;
case STV_HIDDEN:
case STV_INTERNAL:
return FALSE;
case STV_PROTECTED:
if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
return FALSE;
break;
}
if ((info->shared && !info->symbolic)
|| (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
return TRUE;
return FALSE;
/* ??? What, if anything, needs to happen wrt STV_PROTECTED and PLT
entries? For now assume the worst. */
return _bfd_elf_dynamic_symbol_p (h, info, 1);
}

View file

@ -47,7 +47,7 @@
#define ECOFF_64
#include "ecoffswap.h"
static int alpha_elf_dynamic_symbol_p
static bfd_boolean alpha_elf_dynamic_symbol_p
PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *));
static struct bfd_hash_entry * elf64_alpha_link_hash_newfunc
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
@ -269,49 +269,17 @@ struct alpha_elf_link_hash_table
#define alpha_elf_sym_hashes(abfd) \
((struct alpha_elf_link_hash_entry **)elf_sym_hashes(abfd))
/* Should we do dynamic things to this symbol? */
/* Should we do dynamic things to this symbol? This differs from the
generic version in that we never need to consider function pointer
equality wrt PLT entries -- we don't create a PLT entry if a symbol's
address is ever taken. */
static int
static inline bfd_boolean
alpha_elf_dynamic_symbol_p (h, info)
struct elf_link_hash_entry *h;
struct bfd_link_info *info;
{
if (h == NULL)
return FALSE;
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->dynindx == -1)
return FALSE;
if (h->root.type == bfd_link_hash_undefweak
|| h->root.type == bfd_link_hash_defweak)
return TRUE;
switch (ELF_ST_VISIBILITY (h->other))
{
case STV_DEFAULT:
break;
case STV_HIDDEN:
case STV_INTERNAL:
return FALSE;
case STV_PROTECTED:
if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
return FALSE;
break;
}
if ((info->shared && !info->symbolic)
|| ((h->elf_link_hash_flags
& (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_DEF_REGULAR
| ELF_LINK_HASH_REF_REGULAR))
== (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
return TRUE;
return FALSE;
return _bfd_elf_dynamic_symbol_p (h, info, 0);
}
/* Create an entry in a Alpha ELF linker hash table. */

View file

@ -956,30 +956,19 @@ elf64_hppa_dynamic_symbol_p (h, info)
struct elf_link_hash_entry *h;
struct bfd_link_info *info;
{
if (h == NULL)
/* ??? What, if anything, needs to happen wrt STV_PROTECTED symbols
and relocations that retrieve a function descriptor? Assume the
worst for now. */
if (_bfd_elf_dynamic_symbol_p (h, info, 1))
{
/* ??? Why is this here and not elsewhere is_local_label_name. */
if (h->root.root.string[0] == '$' && h->root.root.string[1] == '$')
return FALSE;
return TRUE;
}
else
return FALSE;
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->dynindx == -1)
return FALSE;
if (h->root.type == bfd_link_hash_undefweak
|| h->root.type == bfd_link_hash_defweak)
return TRUE;
if (h->root.root.string[0] == '$' && h->root.root.string[1] == '$')
return FALSE;
if ((info->shared && (!info->symbolic || info->allow_shlib_undefined))
|| ((h->elf_link_hash_flags
& (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
== (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
return TRUE;
return FALSE;
}
/* Mark all funtions exported by this file so that we can later allocate

View file

@ -2474,3 +2474,63 @@ _bfd_elf_link_sec_merge_syms (h, data)
return TRUE;
}
/* Returns false if the symbol referred to by H should be considered
to resolve local to the current module, and true if it should be
considered to bind dynamically. */
bfd_boolean
_bfd_elf_dynamic_symbol_p (h, info, ignore_protected)
struct elf_link_hash_entry *h;
struct bfd_link_info *info;
bfd_boolean ignore_protected;
{
bfd_boolean binding_stays_local_p;
if (h == NULL)
return FALSE;
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 it was forced local, then clearly it's not dynamic. */
if (h->dynindx == -1)
return FALSE;
if (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)
return FALSE;
/* Identify the cases where name binding rules say that a
visible symbol resolves locally. */
binding_stays_local_p = info->executable || info->symbolic;
switch (ELF_ST_VISIBILITY (h->other))
{
case STV_INTERNAL:
case STV_HIDDEN:
return FALSE;
case STV_PROTECTED:
/* Proper resolution for function pointer equality may require
that these symbols perhaps be resolved dynamically, even though
we should be resolving them to the current module. */
if (!ignore_protected)
binding_stays_local_p = TRUE;
break;
default:
/* With STV_DEFAULT, weak symbols do not bind locally. */
if (h->root.type == bfd_link_hash_undefweak
|| h->root.type == bfd_link_hash_defweak)
return TRUE;
break;
}
/* If it isn't defined locally, then clearly it's dynamic. */
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
return TRUE;
/* Otherwise, the symbol is dynamic if binding rules don't tell
us that it remains local. */
return !binding_stays_local_p;
}

View file

@ -200,7 +200,7 @@ static bfd_boolean elfNN_ia64_modify_segment_map
static bfd_boolean elfNN_ia64_is_local_label_name
PARAMS ((bfd *abfd, const char *name));
static bfd_boolean elfNN_ia64_dynamic_symbol_p
PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info));
PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info, int));
static bfd_boolean elfNN_ia64_local_hash_table_init
PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd,
new_hash_entry_func new));
@ -831,7 +831,7 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
}
/* Can't do anything else with dynamic symbols. */
else if (elfNN_ia64_dynamic_symbol_p (h, link_info))
else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
continue;
else
@ -1508,38 +1508,16 @@ elfNN_ia64_is_local_label_name (abfd, name)
/* Should we do dynamic things to this symbol? */
static bfd_boolean
elfNN_ia64_dynamic_symbol_p (h, info)
elfNN_ia64_dynamic_symbol_p (h, info, r_type)
struct elf_link_hash_entry *h;
struct bfd_link_info *info;
int r_type;
{
if (h == NULL)
return FALSE;
bfd_boolean ignore_protected
= ((r_type & 0xf8) == 0x40 /* FPTR relocs */
|| (r_type & 0xf8) == 0x50); /* LTOFF_FPTR relocs */
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->dynindx == -1)
return FALSE;
switch (ELF_ST_VISIBILITY (h->other))
{
case STV_INTERNAL:
case STV_HIDDEN:
return FALSE;
default:
break;
}
if (h->root.type == bfd_link_hash_undefweak
|| h->root.type == bfd_link_hash_defweak)
return TRUE;
/* If it isn't defined locally, then clearly it's dynamic. */
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
return TRUE;
/* Identify the cases where name binding rules say it resolves local. */
return !(info->executable || info->symbolic);
return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
}
static bfd_boolean
@ -2415,7 +2393,7 @@ allocate_global_data_got (dyn_i, data)
if ((dyn_i->want_got || dyn_i->want_gotx)
&& ! dyn_i->want_fptr
&& elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
&& elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
{
dyn_i->got_offset = x->ofs;
x->ofs += 8;
@ -2427,7 +2405,7 @@ allocate_global_data_got (dyn_i, data)
}
if (dyn_i->want_dtpmod)
{
if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
{
dyn_i->dtpmod_offset = x->ofs;
x->ofs += 8;
@ -2464,7 +2442,7 @@ allocate_global_fptr_got (dyn_i, data)
if (dyn_i->want_got
&& dyn_i->want_fptr
&& elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
&& elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTR64LSB))
{
dyn_i->got_offset = x->ofs;
x->ofs += 8;
@ -2482,7 +2460,7 @@ allocate_local_got (dyn_i, data)
struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
if ((dyn_i->want_got || dyn_i->want_gotx)
&& !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
&& !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
{
dyn_i->got_offset = x->ofs;
x->ofs += 8;
@ -2576,7 +2554,7 @@ allocate_plt_entries (dyn_i, data)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
/* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
if (elfNN_ia64_dynamic_symbol_p (h, x->info))
if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
{
bfd_size_type offset = x->ofs;
if (offset == 0)
@ -2654,7 +2632,10 @@ allocate_dynrel_entries (dyn_i, data)
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);
/* Note that this can't be used in relation to FPTR relocs below. */
dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
shared = x->info->shared;
resolved_zero = (dyn_i->h
&& ELF_ST_VISIBILITY (dyn_i->h->other)
@ -3342,7 +3323,7 @@ set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
|| 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_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
|| (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
&& (!dyn_i->want_ltoff_fptr
|| !info->pie
@ -3807,7 +3788,6 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
asection *sym_sec;
bfd_byte *hit_addr;
bfd_boolean dynamic_symbol_p;
bfd_boolean local_symbol_p;
bfd_boolean undef_weak_ref;
r_type = ELFNN_R_TYPE (rel->r_info);
@ -3918,12 +3898,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
hit_addr = contents + rel->r_offset;
value += rel->r_addend;
dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
/* Is this symbol locally defined? A protected symbol is locallly
defined. But its function descriptor may not. Use it with
caution. */
local_symbol_p = (! dynamic_symbol_p
|| ELF_ST_VISIBILITY (h->other) != STV_DEFAULT);
dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
switch (r_type)
{
@ -3952,7 +3927,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
/* If we don't need dynamic symbol lookup, find a
matching RELATIVE relocation. */
dyn_r_type = r_type;
if (! local_symbol_p)
if (dynamic_symbol_p)
{
dynindx = h->dynindx;
addend = rel->r_addend;
@ -4300,7 +4275,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
/* If we don't need dynamic symbol lookup, install two
RELATIVE relocations. */
if (local_symbol_p)
if (!dynamic_symbol_p)
{
unsigned int dyn_r_type;