* 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:
parent
22b0d388c7
commit
986a241f8b
7 changed files with 121 additions and 155 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue