h->type = STT_OBJECT;
if (info->shared
- && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
}
h->type = STT_OBJECT;
if (info->shared
- && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
elf_hash_table (info)->hgot = h;
/* This relocation describes the C++ object vtable hierarchy.
Reconstruct it for later use during GC. */
case R_MN10300_GNU_VTINHERIT:
- if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
return FALSE;
break;
/* This relocation describes which C++ vtable entries are actually
used. Record for later use during GC. */
case R_MN10300_GNU_VTENTRY:
- if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return FALSE;
break;
case R_MN10300_GOT32:
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
- if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
}
static bfd_boolean
elf32_mn10300_finish_hash_table_entry (gen_entry, in_args)
struct bfd_hash_entry *gen_entry;
- PTR in_args ATTRIBUTE_UNUSED;
+ PTR in_args;
{
struct elf32_mn10300_link_hash_entry *entry;
+ struct bfd_link_info *link_info = (struct bfd_link_info *)in_args;
unsigned int byte_count = 0;
entry = (struct elf32_mn10300_link_hash_entry *) gen_entry;
return TRUE;
/* If there are no named calls to this symbol, or there's nothing we
- can move from the function itself into the "call" instruction, then
- note that all "call" instructions should be converted into "calls"
- instructions and return. */
+ can move from the function itself into the "call" instruction,
+ then note that all "call" instructions should be converted into
+ "calls" instructions and return. If a symbol is available for
+ dynamic symbol resolution (overridable or overriding), avoid
+ custom calling conventions. */
if (entry->direct_calls == 0
- || (entry->stack_size == 0 && entry->movm_args == 0))
+ || (entry->stack_size == 0 && entry->movm_args == 0)
+ || (elf_hash_table (link_info)->dynamic_sections_created
+ && ELF_ST_VISIBILITY (entry->root.other) != STV_INTERNAL
+ && ELF_ST_VISIBILITY (entry->root.other) != STV_HIDDEN))
{
/* Make a note that we should convert "call" instructions to "calls"
instructions for calls to this symbol. */
sec_shndx = _bfd_elf_section_from_bfd_section (input_bfd,
section);
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ hashes = elf_sym_hashes (input_bfd);
+ end_hashes = hashes + symcount;
+
/* Look at each function defined in this section and
update info for that function. */
isymend = isymbuf + symtab_hdr->sh_info;
{
struct elf_link_hash_table *elftab;
bfd_size_type amt;
+ struct elf_link_hash_entry **lhashes = hashes;
+
+ /* Skip a local symbol if it aliases a
+ global one. */
+ for (; lhashes < end_hashes; lhashes++)
+ {
+ hash = (struct elf32_mn10300_link_hash_entry *) *lhashes;
+ if ((hash->root.root.type == bfd_link_hash_defined
+ || hash->root.root.type == bfd_link_hash_defweak)
+ && hash->root.root.u.def.section == section
+ && hash->root.type == STT_FUNC
+ && hash->root.root.u.def.value == isym->st_value)
+ break;
+ }
+ if (lhashes != end_hashes)
+ continue;
if (isym->st_shndx == SHN_UNDEF)
sym_sec = bfd_und_section_ptr;
}
}
- symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
- - symtab_hdr->sh_info);
- hashes = elf_sym_hashes (input_bfd);
- end_hashes = hashes + symcount;
for (; hashes < end_hashes; hashes++)
{
hash = (struct elf32_mn10300_link_hash_entry *) *hashes;
if ((hash->root.root.type == bfd_link_hash_defined
|| hash->root.root.type == bfd_link_hash_defweak)
&& hash->root.root.u.def.section == section
- && ELF_ST_TYPE (isym->st_info) == STT_FUNC)
+ && hash->root.type == STT_FUNC)
compute_function_info (input_bfd, hash,
(hash)->root.root.u.def.value,
contents);
the final initialization steps on each. */
elf32_mn10300_link_hash_traverse (hash_table,
elf32_mn10300_finish_hash_table_entry,
- NULL);
+ link_info);
elf32_mn10300_link_hash_traverse (hash_table->static_hash_table,
elf32_mn10300_finish_hash_table_entry,
- NULL);
+ link_info);
/* All entries in the hash table are fully initialized. */
hash_table->flags |= MN10300_HASH_ENTRIES_INITIALIZED;
asection *sym_sec = NULL;
const char *sym_name;
char *new_name;
+ bfd_vma saved_addend;
/* A local symbol. */
isym = isymbuf + ELF32_R_SYM (irel->r_info);
else
sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
- symval = (isym->st_value
- + sym_sec->output_section->vma
- + sym_sec->output_offset);
sym_name = bfd_elf_string_from_elf_section (abfd,
symtab_hdr->sh_link,
isym->st_name);
+ if ((sym_sec->flags & SEC_MERGE)
+ && ELF_ST_TYPE (isym->st_info) == STT_SECTION
+ && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
+ {
+ saved_addend = irel->r_addend;
+ symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
+ symval += irel->r_addend;
+ irel->r_addend = saved_addend;
+ }
+ else
+ {
+ symval = (isym->st_value
+ + sym_sec->output_section->vma
+ + sym_sec->output_offset);
+ }
/* Tack on an ID so we can uniquely identify this
local symbol in the global hash table. */
new_name = bfd_malloc ((bfd_size_type) strlen (sym_name) + 10);
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
- if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
}