/* Matsushita 10300 specific support for 32-bit ELF
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
to the target when it's valid and profitable to do so. */
unsigned char movm_args;
- /* For funtion symbols, the amount of stack space that would be allocated
+ /* For function symbols, the amount of stack space that would be allocated
by the movm instruction. This is redundant with movm_args, but we
add it to the hash table to avoid computing it over and over. */
unsigned char movm_stack_size;
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;
}
asection **local_sections;
{
Elf_Internal_Shdr *symtab_hdr;
- struct elf32_mn10300_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **sym_hashes;
Elf_Internal_Rela *rel, *relend;
if (info->relocatable)
return TRUE;
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
- sym_hashes = (struct elf32_mn10300_link_hash_entry **)
- (elf_sym_hashes (input_bfd));
+ sym_hashes = elf_sym_hashes (input_bfd);
rel = relocs;
relend = relocs + input_section->reloc_count;
bfd_boolean warned;
struct elf_link_hash_entry *hh;
- RELOC_FOR_GLOBAL_SYMBOL (hh, (struct elf_link_hash_entry *) sym_hashes,
- r_symndx, symtab_hdr, relocation,
- sec, unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ hh, sec, relocation,
+ unresolved_reloc, warned);
h = (struct elf32_mn10300_link_hash_entry *) hh;
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. */
byte_count += 2;
/* Count the insn to allocate stack space too. */
- if (entry->stack_size > 0 && entry->stack_size <= 128)
- byte_count += 3;
- else if (entry->stack_size > 0 && entry->stack_size < 256)
- byte_count += 4;
+ if (entry->stack_size > 0)
+ {
+ if (entry->stack_size <= 128)
+ byte_count += 3;
+ else
+ byte_count += 4;
+ }
/* If using "call" will result in larger code, then turn all
- the associated "call" instructions into "calls" instrutions. */
+ the associated "call" instructions into "calls" instructions. */
if (byte_count < entry->direct_calls)
entry->flags |= MN10300_CONVERT_CALL_TO_CALLS;
/* This function handles relaxing for the mn10300.
- There's quite a few relaxing opportunites available on the mn10300:
+ There are quite a few relaxing opportunities available on the mn10300:
* calls:32 -> calls:16 2 bytes
* call:32 -> call:16 2 bytes
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;
if (sym_hash->movm_args)
bytes += 2;
- if (sym_hash->stack_size && sym_hash->stack_size <= 128)
- bytes += 3;
- else if (sym_hash->stack_size
- && sym_hash->stack_size < 256)
- bytes += 4;
+ if (sym_hash->stack_size > 0)
+ {
+ if (sym_hash->stack_size <= 128)
+ bytes += 3;
+ else
+ bytes += 4;
+ }
/* Note that we've deleted prologue bytes for this
function. */
if (sym_hash->movm_args)
bytes += 2;
- if (sym_hash->stack_size && sym_hash->stack_size <= 128)
- bytes += 3;
- else if (sym_hash->stack_size
- && sym_hash->stack_size < 256)
- bytes += 4;
+ if (sym_hash->stack_size > 0)
+ {
+ if (sym_hash->stack_size <= 128)
+ bytes += 3;
+ else
+ bytes += 4;
+ }
/* Note that we've deleted prologue bytes for this
function. */
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);
}
/* Now figure out how much stack space will be allocated by the movm
- instruction. We need this kept separate from the funtion's normal
+ instruction. We need this kept separate from the function's normal
stack space. */
if (hash->movm_args)
{
/* Return offset of the GOT id in PLT0 entry. */
#define elf_mn10300_plt0_gotid_offset(info) 9
-/* Return offset of the tempoline in PLT entry */
+/* Return offset of the temporary in PLT entry */
#define elf_mn10300_plt_temp_offset(info) 8
/* Return offset of the symbol in PLT entry. */
/* 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;
}
if (elf_hash_table (info)->dynamic_sections_created)
{
/* Set the contents of the .interp section to the interpreter. */
- if (! info->shared)
+ if (info->executable)
{
s = bfd_get_section_by_name (dynobj, ".interp");
BFD_ASSERT (s != NULL);
in by the dynamic linker and used by the debugger. */
if (! info->shared)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
return FALSE;
}
if (plt)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
- || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+ || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
return FALSE;
}
if (relocs)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_RELA, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_RELAENT,
- sizeof (Elf32_External_Rela)))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
+ sizeof (Elf32_External_Rela)))
return FALSE;
}
if (reltext)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
return FALSE;
}
}