/* Motorola 68HC11/HC12-specific support for 32-bit ELF
- Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Stephane Carrez (stcarrez@nerim.fr)
This file is part of BFD, the Binary File Descriptor library.
bfd_hash_lookup ((table), (string), (create), (copy)))
static struct elf32_m68hc11_stub_hash_entry* m68hc12_add_stub
- PARAMS((const char *stub_name,
- asection *section,
- struct m68hc11_elf_link_hash_table *htab));
+ (const char *stub_name,
+ asection *section,
+ struct m68hc11_elf_link_hash_table *htab);
static struct bfd_hash_entry *stub_hash_newfunc
- PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
-static void m68hc11_elf_set_symbol
- PARAMS ((bfd* abfd, struct bfd_link_info *info,
- const char* name, bfd_vma value, asection* sec));
+static void m68hc11_elf_set_symbol (bfd* abfd, struct bfd_link_info *info,
+ const char* name, bfd_vma value,
+ asection* sec);
static bfd_boolean m68hc11_elf_export_one_stub
- PARAMS((struct bfd_hash_entry *gen_entry, PTR in_arg));
+ (struct bfd_hash_entry *gen_entry, void *in_arg);
-static bfd_boolean m68hc11_get_relocation_value
- PARAMS ((bfd* abfd,
- struct bfd_link_info* info,
- asection **local_sections,
- Elf_Internal_Sym* local_syms,
- Elf_Internal_Rela* rel,
- const char** name,
- bfd_vma* relocation,
- bfd_boolean* is_far));
-
-static void scan_sections_for_abi PARAMS ((bfd*, asection*, PTR));
+static void scan_sections_for_abi (bfd*, asection*, PTR);
struct m68hc11_scan_param
{
/* Create a 68HC11/68HC12 ELF linker hash table. */
struct m68hc11_elf_link_hash_table*
-m68hc11_elf_hash_table_create (abfd)
- bfd *abfd;
+m68hc11_elf_hash_table_create (bfd *abfd)
{
struct m68hc11_elf_link_hash_table *ret;
bfd_size_type amt = sizeof (struct m68hc11_elf_link_hash_table);
/* Free the derived linker hash table. */
void
-m68hc11_elf_bfd_link_hash_table_free (hash)
- struct bfd_link_hash_table *hash;
+m68hc11_elf_bfd_link_hash_table_free (struct bfd_link_hash_table *hash)
{
struct m68hc11_elf_link_hash_table *ret
= (struct m68hc11_elf_link_hash_table *) hash;
/* Initialize an entry in the stub hash table. */
static struct bfd_hash_entry *
-stub_hash_newfunc (entry, table, string)
- struct bfd_hash_entry *entry;
- struct bfd_hash_table *table;
- const char *string;
+stub_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
+ const char *string)
{
/* Allocate the structure if it has not already been allocated by a
subclass. */
stub entry are initialised. */
static struct elf32_m68hc11_stub_hash_entry *
-m68hc12_add_stub (stub_name, section, htab)
- const char *stub_name;
- asection *section;
- struct m68hc11_elf_link_hash_table *htab;
+m68hc12_add_stub (const char *stub_name, asection *section,
+ struct m68hc11_elf_link_hash_table *htab)
{
struct elf32_m68hc11_stub_hash_entry *stub_entry;
TRUE, FALSE);
if (stub_entry == NULL)
{
- (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
- bfd_archive_filename (section->owner),
- stub_name);
+ (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
+ section->owner, stub_name);
return NULL;
}
the trampoline handler. */
bfd_boolean
-elf32_m68hc11_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
- bfd *abfd;
- struct bfd_link_info *info;
- const Elf_Internal_Sym *sym;
- const char **namep ATTRIBUTE_UNUSED;
- flagword *flagsp ATTRIBUTE_UNUSED;
- asection **secp ATTRIBUTE_UNUSED;
- bfd_vma *valp ATTRIBUTE_UNUSED;
+elf32_m68hc11_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp ATTRIBUTE_UNUSED,
+ bfd_vma *valp ATTRIBUTE_UNUSED)
{
if (sym->st_other & STO_M68HC12_FAR)
{
0 when no stubs will be needed, and 1 on success. */
int
-elf32_m68hc11_setup_section_lists (output_bfd, info)
- bfd *output_bfd;
- struct bfd_link_info *info;
+elf32_m68hc11_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
{
bfd *input_bfd;
unsigned int bfd_count;
instruction. */
bfd_boolean
-elf32_m68hc11_size_stubs (output_bfd, stub_bfd, info, add_stub_section)
- bfd *output_bfd;
- bfd *stub_bfd;
- struct bfd_link_info *info;
- asection * (*add_stub_section) PARAMS ((const char *, asection *));
+elf32_m68hc11_size_stubs (bfd *output_bfd, bfd *stub_bfd,
+ struct bfd_link_info *info,
+ asection * (*add_stub_section) (const char*, asection*))
{
bfd *input_bfd;
asection *section;
hash->root.u.i.link);
if (hash->root.type == bfd_link_hash_defined
- || hash->root.type == bfd_link_hash_defweak)
+ || hash->root.type == bfd_link_hash_defweak
+ || hash->root.type == bfd_link_hash_new)
{
if (!(hash->other & STO_M68HC12_FAR))
continue;
stub_sec != NULL;
stub_sec = stub_sec->next)
{
- stub_sec->_raw_size = 0;
- stub_sec->_cooked_size = 0;
+ stub_sec->size = 0;
}
bfd_hash_traverse (htab->stub_hash_table, htab->size_one_stub, htab);
/* Export the trampoline addresses in the symbol table. */
static bfd_boolean
-m68hc11_elf_export_one_stub (gen_entry, in_arg)
- struct bfd_hash_entry *gen_entry;
- PTR in_arg;
+m68hc11_elf_export_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
{
struct bfd_link_info *info;
struct m68hc11_elf_link_hash_table *htab;
/* Export a symbol or set its value and section. */
static void
-m68hc11_elf_set_symbol (abfd, info, name, value, sec)
- bfd* abfd;
- struct bfd_link_info *info;
- const char* name;
- bfd_vma value;
- asection* sec;
+m68hc11_elf_set_symbol (bfd *abfd, struct bfd_link_info *info,
+ const char *name, bfd_vma value, asection *sec)
{
struct elf_link_hash_entry *h;
linker. */
bfd_boolean
-elf32_m68hc11_build_stubs (abfd, info)
- bfd* abfd;
- struct bfd_link_info *info;
+elf32_m68hc11_build_stubs (bfd *abfd, struct bfd_link_info *info)
{
asection *stub_sec;
struct bfd_hash_table *table;
bfd_size_type size;
/* Allocate memory to hold the linker stubs. */
- size = stub_sec->_raw_size;
+ size = stub_sec->size;
stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
if (stub_sec->contents == NULL && size != 0)
return FALSE;
- stub_sec->_raw_size = 0;
+ stub_sec->size = 0;
}
/* Build the stubs as directed by the stub hash table. */
}
void
-m68hc11_elf_get_bank_parameters (info)
- struct bfd_link_info *info;
+m68hc11_elf_get_bank_parameters (struct bfd_link_info *info)
{
unsigned i;
struct m68hc11_page_info *pinfo;
/* Return 1 if the address is in banked memory.
This can be applied to a virtual address and to a physical address. */
int
-m68hc11_addr_is_banked (pinfo, addr)
- struct m68hc11_page_info *pinfo;
- bfd_vma addr;
+m68hc11_addr_is_banked (struct m68hc11_page_info *pinfo, bfd_vma addr)
{
if (addr >= pinfo->bank_virtual)
return 1;
/* Return the physical address seen by the processor, taking
into account banked memory. */
bfd_vma
-m68hc11_phys_addr (pinfo, addr)
- struct m68hc11_page_info *pinfo;
- bfd_vma addr;
+m68hc11_phys_addr (struct m68hc11_page_info *pinfo, bfd_vma addr)
{
if (addr < pinfo->bank_virtual)
return addr;
/* Return the page number corresponding to an address in banked memory. */
bfd_vma
-m68hc11_phys_page (pinfo, addr)
- struct m68hc11_page_info *pinfo;
- bfd_vma addr;
+m68hc11_phys_page (struct m68hc11_page_info *pinfo, bfd_vma addr)
{
if (addr < pinfo->bank_virtual)
return 0;
which the linker should otherwise ignore. */
bfd_reloc_status_type
-m68hc11_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
- output_bfd, error_message)
- bfd *abfd ATTRIBUTE_UNUSED;
- arelent *reloc_entry;
- asymbol *symbol ATTRIBUTE_UNUSED;
- PTR data ATTRIBUTE_UNUSED;
- asection *input_section;
- bfd *output_bfd;
- char **error_message ATTRIBUTE_UNUSED;
+m68hc11_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
{
if (output_bfd != NULL)
reloc_entry->address += input_section->output_offset;
}
bfd_reloc_status_type
-m68hc11_elf_special_reloc (abfd, reloc_entry, symbol, data, input_section,
- output_bfd, error_message)
- bfd *abfd ATTRIBUTE_UNUSED;
- arelent *reloc_entry;
- asymbol *symbol;
- PTR data ATTRIBUTE_UNUSED;
- asection *input_section;
- bfd *output_bfd;
- char **error_message ATTRIBUTE_UNUSED;
+m68hc11_elf_special_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
{
if (output_bfd != (bfd *) NULL
&& (symbol->flags & BSF_SECTION_SYM) == 0
if (output_bfd != NULL)
return bfd_reloc_continue;
- if (reloc_entry->address > input_section->_cooked_size)
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
return bfd_reloc_outofrange;
abort();
}
asection *
-elf32_m68hc11_gc_mark_hook (sec, info, rel, h, sym)
- asection *sec;
- struct bfd_link_info *info ATTRIBUTE_UNUSED;
- Elf_Internal_Rela *rel;
- struct elf_link_hash_entry *h;
- Elf_Internal_Sym *sym;
+elf32_m68hc11_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
{
if (h != NULL)
{
}
bfd_boolean
-elf32_m68hc11_gc_sweep_hook (abfd, info, sec, relocs)
- bfd *abfd ATTRIBUTE_UNUSED;
- struct bfd_link_info *info ATTRIBUTE_UNUSED;
- asection *sec ATTRIBUTE_UNUSED;
- const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
+elf32_m68hc11_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
{
/* We don't use got and plt entries for 68hc11/68hc12. */
return TRUE;
virtual table relocs for gc. */
bfd_boolean
-elf32_m68hc11_check_relocs (abfd, info, sec, relocs)
- bfd * abfd;
- struct bfd_link_info * info;
- asection * sec;
- const Elf_Internal_Rela * relocs;
+elf32_m68hc11_check_relocs (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, const Elf_Internal_Rela *relocs)
{
Elf_Internal_Shdr * symtab_hdr;
struct elf_link_hash_entry ** sym_hashes;
/* This relocation describes the C++ object vtable hierarchy.
Reconstruct it for later use during GC. */
case R_M68HC11_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_M68HC11_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;
}
}
static bfd_boolean
-m68hc11_get_relocation_value (abfd, info, local_sections, local_syms,
- rel, name,
- relocation, is_far)
- bfd *abfd;
- struct bfd_link_info *info;
- asection **local_sections;
- Elf_Internal_Sym* local_syms;
- Elf_Internal_Rela* rel;
- const char** name;
- bfd_vma* relocation;
- bfd_boolean* is_far;
+m68hc11_get_relocation_value (bfd *input_bfd, struct bfd_link_info *info,
+ asection *input_section,
+ asection **local_sections,
+ Elf_Internal_Sym *local_syms,
+ Elf_Internal_Rela *rel,
+ const char **name,
+ bfd_vma *relocation, bfd_boolean *is_far)
{
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
Elf_Internal_Sym *sym;
const char* stub_name = 0;
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- sym_hashes = elf_sym_hashes (abfd);
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
r_symndx = ELF32_R_SYM (rel->r_info);
*is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
if (*is_far)
stub_name = (bfd_elf_string_from_elf_section
- (abfd, symtab_hdr->sh_link,
+ (input_bfd, symtab_hdr->sh_link,
sym->st_name));
}
else
{
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- 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->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- {
- sec = h->root.u.def.section;
- *relocation = (h->root.u.def.value
- + sec->output_section->vma
- + sec->output_offset);
- }
- else if (h->root.type == bfd_link_hash_undefweak)
- *relocation = 0;
- else
- {
- if (!((*info->callbacks->undefined_symbol)
- (info, h->root.root.string, abfd,
- sec, rel->r_offset, TRUE)))
- return FALSE;
- *relocation = 0;
- }
+ bfd_boolean unresolved_reloc, warned;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, *relocation, unresolved_reloc, warned);
+
*is_far = (h && (h->other & STO_M68HC12_FAR));
stub_name = h->root.root.string;
}
else
{
*name = (bfd_elf_string_from_elf_section
- (abfd, symtab_hdr->sh_link, sym->st_name));
+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
if (*name == NULL || **name == '\0')
*name = bfd_section_name (input_bfd, sec);
}
/* Relocate a 68hc11/68hc12 ELF section. */
bfd_boolean
-elf32_m68hc11_relocate_section (output_bfd, info, input_bfd, input_section,
- contents, relocs, local_syms, local_sections)
- bfd *output_bfd ATTRIBUTE_UNUSED;
- struct bfd_link_info *info;
- bfd *input_bfd;
- asection *input_section;
- bfd_byte *contents;
- Elf_Internal_Rela *relocs;
- Elf_Internal_Sym *local_syms;
- asection **local_sections;
+elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info,
+ bfd *input_bfd, asection *input_section,
+ bfd_byte *contents, Elf_Internal_Rela *relocs,
+ Elf_Internal_Sym *local_syms,
+ asection **local_sections)
{
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
(*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
howto = arel.howto;
- m68hc11_get_relocation_value (input_bfd, info,
- local_sections, local_syms,
+ m68hc11_get_relocation_value (input_bfd, info, input_section,
+ local_sections, local_syms,
rel, &name, &relocation, &is_far);
/* Do the memory bank mapping. */
{
case bfd_reloc_overflow:
if (!((*info->callbacks->reloc_overflow)
- (info, name, howto->name, (bfd_vma) 0,
+ (info, NULL, name, howto->name, (bfd_vma) 0,
input_bfd, input_section, rel->r_offset)))
return FALSE;
break;
/* Set and control ELF flags in ELF header. */
bfd_boolean
-_bfd_m68hc11_elf_set_private_flags (abfd, flags)
- bfd *abfd;
- flagword flags;
+_bfd_m68hc11_elf_set_private_flags (bfd *abfd, flagword flags)
{
BFD_ASSERT (!elf_flags_init (abfd)
|| elf_elfheader (abfd)->e_flags == flags);
object file when linking. */
bfd_boolean
-_bfd_m68hc11_elf_merge_private_bfd_data (ibfd, obfd)
- bfd *ibfd;
- bfd *obfd;
+_bfd_m68hc11_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
{
flagword old_flags;
flagword new_flags;
if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
{
(*_bfd_error_handler)
- (_("%s: linking files compiled for 16-bit integers (-mshort) "
- "and others for 32-bit integers"),
- bfd_archive_filename (ibfd));
+ (_("%B: linking files compiled for 16-bit integers (-mshort) "
+ "and others for 32-bit integers"), ibfd);
ok = FALSE;
}
if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
{
(*_bfd_error_handler)
- (_("%s: linking files compiled for 32-bit double (-fshort-double) "
- "and others for 64-bit double"),
- bfd_archive_filename (ibfd));
+ (_("%B: linking files compiled for 32-bit double (-fshort-double) "
+ "and others for 64-bit double"), ibfd);
ok = FALSE;
}
if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags))
{
(*_bfd_error_handler)
- (_("%s: linking files compiled for HCS12 with "
- "others compiled for HC12"),
- bfd_archive_filename (ibfd));
+ (_("%B: linking files compiled for HCS12 with "
+ "others compiled for HC12"), ibfd);
ok = FALSE;
}
new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK)
elf_elfheader (obfd)->e_flags = new_flags;
- new_flags &= ~EF_M68HC11_ABI;
- old_flags &= ~EF_M68HC11_ABI;
+ new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
+ old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
/* Warn about any other mismatches */
if (new_flags != old_flags)
{
(*_bfd_error_handler)
- (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
- bfd_archive_filename (ibfd), (unsigned long) new_flags,
- (unsigned long) old_flags);
+ (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
+ ibfd, (unsigned long) new_flags, (unsigned long) old_flags);
ok = FALSE;
}
}
bfd_boolean
-_bfd_m68hc11_elf_print_private_bfd_data (abfd, ptr)
- bfd *abfd;
- PTR ptr;
+_bfd_m68hc11_elf_print_private_bfd_data (bfd *abfd, void *ptr)
{
FILE *file = (FILE *) ptr;
return TRUE;
}
-static void scan_sections_for_abi (abfd, asect, arg)
- bfd* abfd ATTRIBUTE_UNUSED;
- asection* asect;
- PTR arg;
+static void scan_sections_for_abi (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *asect, void *arg)
{
struct m68hc11_scan_param* p = (struct m68hc11_scan_param*) arg;
/* Tweak the OSABI field of the elf header. */
void
-elf32_m68hc11_post_process_headers (abfd, link_info)
- bfd *abfd;
- struct bfd_link_info *link_info;
+elf32_m68hc11_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
{
struct m68hc11_scan_param param;