mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-10 05:52:21 +08:00
* elf32-m68hc1x.c: New file (from elf32-m68hc11.c and elf32-m68hc12.c)
(m68hc11_elf_hash_table_create): New function. (elf32_m68hc11_link_hash_table_free): New function. (stub_hash_newfunc): New function. (m68hc11_add_stub): New function. (elf32_m68hc11_add_symbol_hook): New function. (elf32_m68hc11_setup_section_lists): New function. (elf32_m68hc11_next_input_section): New function. (elf32_m68hc11_size_stubs): New function. (elf32_m68hc11_build_stubs): New function. (m68hc11_get_relocation_value): New function. (elf32_m68hc11_relocate_section): Call the above to redirect some relocations to the trampoline code. (m68hc11_elf_export_one_stub): New function. (m68hc11_elf_set_symbol): New function. (elf32_m68hc11_build_stubs): Call it via bfd_hash_traverse. (m68hc11_elf_get_bank_parameters): Get parameters only when the info is not yet initialized. * elf32-m68hc1x.h: New file (from elf32-m68hc11.c and elf32-m68hc12.c) (elf32_m68hc11_stub_hash_entry): New struct. (m68hc11_page_info): Add trampoline handler address. (m68hc11_elf_link_hash_table): Add stubs generation members. (elf32_m68hc11_add_symbol_hook): Declare. (elf32_m68hc11_setup_section_lists): Declare. (elf32_m68hc11_size_stubs): Declare. (elf32_m68hc11_build_stubs): Declare. * elf32-m68hc11.c (m68hc11_elf_ignore_reloc): Move to elf32-m68hc1x.c. (elf32_m68hc11_gc_mark_hook, elf32_m68hc11_gc_sweep_hook): Likewise. (elf32_m68hc11_check_relocs, elf32_m68hc11_relocate_section): Ditto. (_bfd_m68hc11_elf_set_private_flags): Ditto. (_bfd_m68hc11_elf_merge_private_bfd_data): Ditto. (_bfd_m68hc11_elf_print_private_bfd_data): Ditto. (bfd_elf32_bfd_link_hash_table_create): Define. (elf_backend_add_symbol_hook): Define. (m68hc11_elf_bfd_link_hash_table_create): New function. (m68hc11_elf_build_one_stub): New function. (m68hc11_elf_size_one_stub): New function. (m68hc11_elf_bfd_link_hash_table_create): Install the above. (bfd_elf32_bfd_link_hash_table_create): Define. * elf32-m68hc12.c (m68hc11_elf_ignore_reloc): Remove. (m68hc12_addr_is_banked): Remove, use m68hc11_addr_is_banked. (m68hc12_phys_addr): Ditto. (m68hc12_phys_page): Ditto. (m68hc12_elf_special_reloc): Move to elf32-m68hc1x.c. (elf32_m68hc11_gc_mark_hook): Likewise. (elf32_m68hc11_gc_sweep_hook): Likewise. (elf32_m68hc11_check_relocs): Likewise. (elf32_m68hc11_relocate_section): Likewise. (_bfd_m68hc12_elf_set_private_flags): Likewise. (_bfd_m68hc12_elf_merge_private_bfd_data): Likewise. (_bfd_m68hc12_elf_print_private_bfd_data): Likewise. (m68hc12_elf_build_one_stub): New function. (m68hc12_elf_size_one_stub): New function. (m68hc12_elf_bfd_link_hash_table_create): New function, use the above. (elf_backend_add_symbol_hook): Define. (elf_m68hc11_howto_table): Use TRUE for pcrel relocs; fix masks.
This commit is contained in:
@ -24,29 +24,25 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#include "bfdlink.h"
|
||||
#include "libbfd.h"
|
||||
#include "elf-bfd.h"
|
||||
#include "elf32-m68hc1x.h"
|
||||
#include "elf/m68hc11.h"
|
||||
#include "opcode/m68hc11.h"
|
||||
|
||||
/* Relocation functions. */
|
||||
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
|
||||
PARAMS ((bfd *, bfd_reloc_code_real_type));
|
||||
static void m68hc11_info_to_howto_rel
|
||||
PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
|
||||
|
||||
static bfd_reloc_status_type m68hc11_elf_ignore_reloc
|
||||
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
|
||||
/* Trampoline generation. */
|
||||
static bfd_boolean m68hc11_elf_size_one_stub
|
||||
PARAMS((struct bfd_hash_entry *gen_entry, PTR in_arg));
|
||||
static bfd_boolean m68hc11_elf_build_one_stub
|
||||
PARAMS((struct bfd_hash_entry *gen_entry, PTR in_arg));
|
||||
static struct bfd_link_hash_table* m68hc11_elf_bfd_link_hash_table_create
|
||||
PARAMS ((bfd* abfd));
|
||||
|
||||
/* GC mark and sweep. */
|
||||
static asection *elf32_m68hc11_gc_mark_hook
|
||||
PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
|
||||
struct elf_link_hash_entry *, Elf_Internal_Sym *));
|
||||
static bfd_boolean elf32_m68hc11_gc_sweep_hook
|
||||
PARAMS ((bfd *, struct bfd_link_info *, asection *,
|
||||
const Elf_Internal_Rela *));
|
||||
static bfd_boolean elf32_m68hc11_check_relocs
|
||||
PARAMS ((bfd *, struct bfd_link_info *, asection *,
|
||||
const Elf_Internal_Rela *));
|
||||
static bfd_boolean elf32_m68hc11_relocate_section
|
||||
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
|
||||
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
|
||||
/* Linker relaxation. */
|
||||
static bfd_boolean m68hc11_elf_relax_section
|
||||
PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
|
||||
static void m68hc11_elf_relax_delete_bytes
|
||||
@ -56,18 +52,14 @@ static void m68hc11_relax_group
|
||||
unsigned long, unsigned long));
|
||||
static int compare_reloc PARAMS ((const void *, const void *));
|
||||
|
||||
|
||||
bfd_boolean _bfd_m68hc11_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
|
||||
bfd_boolean _bfd_m68hc11_elf_set_private_flags PARAMS ((bfd *, flagword));
|
||||
bfd_boolean _bfd_m68hc11_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
|
||||
|
||||
/* Use REL instead of RELA to save space */
|
||||
#define USE_REL 1
|
||||
|
||||
/* The Motorola 68HC11 microcontroler only addresses 64Kb.
|
||||
/* The Motorola 68HC11 microcontroller only addresses 64Kb but we also
|
||||
support a memory bank switching mechanism similar to 68HC12.
|
||||
We must handle 8 and 16-bit relocations. The 32-bit relocation
|
||||
is defined but not used except by gas when -gstabs is used (which
|
||||
is wrong).
|
||||
are used for debugging sections (DWARF2) to represent a virtual
|
||||
address.
|
||||
The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
|
||||
static reloc_howto_type elf_m68hc11_howto_table[] = {
|
||||
/* This reloc does nothing. */
|
||||
@ -367,25 +359,6 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This function is used for relocs which are only used for relaxing,
|
||||
which the linker should otherwise ignore. */
|
||||
|
||||
static 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;
|
||||
{
|
||||
if (output_bfd != NULL)
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
/* Set the howto pointer for an M68HC11 ELF reloc. */
|
||||
|
||||
static void
|
||||
@ -401,50 +374,106 @@ m68hc11_info_to_howto_rel (abfd, cache_ptr, dst)
|
||||
cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
|
||||
}
|
||||
|
||||
static 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;
|
||||
|
||||
/* Far trampoline generation. */
|
||||
|
||||
/* Build a 68HC11 trampoline stub. */
|
||||
static bfd_boolean
|
||||
m68hc11_elf_build_one_stub (gen_entry, in_arg)
|
||||
struct bfd_hash_entry *gen_entry;
|
||||
PTR in_arg;
|
||||
{
|
||||
if (h != NULL)
|
||||
{
|
||||
switch (ELF32_R_TYPE (rel->r_info))
|
||||
{
|
||||
default:
|
||||
switch (h->root.type)
|
||||
{
|
||||
case bfd_link_hash_defined:
|
||||
case bfd_link_hash_defweak:
|
||||
return h->root.u.def.section;
|
||||
struct elf32_m68hc11_stub_hash_entry *stub_entry;
|
||||
struct bfd_link_info *info;
|
||||
struct m68hc11_elf_link_hash_table *htab;
|
||||
asection *stub_sec;
|
||||
bfd *stub_bfd;
|
||||
bfd_byte *loc;
|
||||
bfd_vma sym_value, phys_page, phys_addr;
|
||||
|
||||
case bfd_link_hash_common:
|
||||
return h->root.u.c.p->section;
|
||||
/* Massage our args to the form they really have. */
|
||||
stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
|
||||
info = (struct bfd_link_info *) in_arg;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
|
||||
htab = m68hc11_elf_hash_table (info);
|
||||
|
||||
return NULL;
|
||||
stub_sec = stub_entry->stub_sec;
|
||||
|
||||
/* Make a note of the offset within the stubs for this entry. */
|
||||
stub_entry->stub_offset = stub_sec->_raw_size;
|
||||
stub_sec->_raw_size += 10;
|
||||
loc = stub_sec->contents + stub_entry->stub_offset;
|
||||
|
||||
stub_bfd = stub_sec->owner;
|
||||
|
||||
/* Create the trampoline call stub:
|
||||
|
||||
pshb
|
||||
ldab #%page(symbol)
|
||||
ldy #%addr(symbol)
|
||||
jmp __trampoline
|
||||
|
||||
*/
|
||||
sym_value = (stub_entry->target_value
|
||||
+ stub_entry->target_section->output_offset
|
||||
+ stub_entry->target_section->output_section->vma);
|
||||
phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value);
|
||||
phys_page = m68hc11_phys_page (&htab->pinfo, sym_value);
|
||||
|
||||
/* pshb; ldab #%page(sym) */
|
||||
bfd_put_8 (stub_bfd, 0x37, loc);
|
||||
bfd_put_8 (stub_bfd, 0xC6, loc + 1);
|
||||
bfd_put_8 (stub_bfd, phys_page, loc + 2);
|
||||
loc += 3;
|
||||
|
||||
/* ldy #%addr(sym) */
|
||||
bfd_put_8 (stub_bfd, 0x18, loc);
|
||||
bfd_put_8 (stub_bfd, 0xCE, loc + 1);
|
||||
bfd_put_16 (stub_bfd, phys_addr, loc + 2);
|
||||
loc += 4;
|
||||
|
||||
/* jmp __trampoline */
|
||||
bfd_put_8 (stub_bfd, 0x7E, loc);
|
||||
bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* As above, but don't actually build the stub. Just bump offset so
|
||||
we know stub section sizes. */
|
||||
|
||||
static 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;
|
||||
m68hc11_elf_size_one_stub (gen_entry, in_arg)
|
||||
struct bfd_hash_entry *gen_entry;
|
||||
PTR in_arg ATTRIBUTE_UNUSED;
|
||||
{
|
||||
/* We don't use got and plt entries for 68hc11/68hc12. */
|
||||
struct elf32_m68hc11_stub_hash_entry *stub_entry;
|
||||
|
||||
/* Massage our args to the form they really have. */
|
||||
stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
|
||||
|
||||
stub_entry->stub_sec->_raw_size += 10;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Create a 68HC11 ELF linker hash table. */
|
||||
|
||||
static struct bfd_link_hash_table *
|
||||
m68hc11_elf_bfd_link_hash_table_create (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
struct m68hc11_elf_link_hash_table *ret;
|
||||
|
||||
ret = m68hc11_elf_hash_table_create (abfd);
|
||||
if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
|
||||
return NULL;
|
||||
|
||||
ret->size_one_stub = m68hc11_elf_size_one_stub;
|
||||
ret->build_one_stub = m68hc11_elf_build_one_stub;
|
||||
|
||||
return &ret->root.root;
|
||||
}
|
||||
|
||||
|
||||
/* 68HC11 Linker Relaxation. */
|
||||
|
||||
@ -1251,365 +1280,7 @@ m68hc11_elf_relax_delete_bytes (abfd, sec, addr, count)
|
||||
}
|
||||
}
|
||||
|
||||
/* Look through the relocs for a section during the first phase.
|
||||
Since we don't do .gots or .plts, we just need to consider the
|
||||
virtual table relocs for gc. */
|
||||
|
||||
static bfd_boolean
|
||||
elf32_m68hc11_check_relocs (abfd, info, sec, 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;
|
||||
struct elf_link_hash_entry ** sym_hashes_end;
|
||||
const Elf_Internal_Rela * rel;
|
||||
const Elf_Internal_Rela * rel_end;
|
||||
|
||||
if (info->relocateable)
|
||||
return TRUE;
|
||||
|
||||
symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
|
||||
sym_hashes = elf_sym_hashes (abfd);
|
||||
sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
|
||||
if (!elf_bad_symtab (abfd))
|
||||
sym_hashes_end -= symtab_hdr->sh_info;
|
||||
|
||||
rel_end = relocs + sec->reloc_count;
|
||||
|
||||
for (rel = relocs; rel < rel_end; rel++)
|
||||
{
|
||||
struct elf_link_hash_entry * h;
|
||||
unsigned long r_symndx;
|
||||
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
h = NULL;
|
||||
else
|
||||
h = sym_hashes [r_symndx - symtab_hdr->sh_info];
|
||||
|
||||
switch (ELF32_R_TYPE (rel->r_info))
|
||||
{
|
||||
/* 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))
|
||||
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))
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Relocate a 68hc11/68hc12 ELF section. */
|
||||
static 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;
|
||||
{
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
struct elf_link_hash_entry **sym_hashes;
|
||||
Elf_Internal_Rela *rel, *relend;
|
||||
const char *name;
|
||||
|
||||
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
||||
sym_hashes = elf_sym_hashes (input_bfd);
|
||||
|
||||
rel = relocs;
|
||||
relend = relocs + input_section->reloc_count;
|
||||
for (; rel < relend; rel++)
|
||||
{
|
||||
int r_type;
|
||||
reloc_howto_type *howto;
|
||||
unsigned long r_symndx;
|
||||
Elf_Internal_Sym *sym;
|
||||
asection *sec;
|
||||
struct elf_link_hash_entry *h;
|
||||
bfd_vma relocation;
|
||||
bfd_reloc_status_type r;
|
||||
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
r_type = ELF32_R_TYPE (rel->r_info);
|
||||
|
||||
if (r_type == R_M68HC11_GNU_VTENTRY
|
||||
|| r_type == R_M68HC11_GNU_VTINHERIT )
|
||||
continue;
|
||||
|
||||
howto = elf_m68hc11_howto_table + r_type;
|
||||
|
||||
if (info->relocateable)
|
||||
{
|
||||
/* This is a relocateable link. We don't have to change
|
||||
anything, unless the reloc is against a section symbol,
|
||||
in which case we have to adjust according to where the
|
||||
section symbol winds up in the output section. */
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
{
|
||||
sym = local_syms + r_symndx;
|
||||
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
|
||||
{
|
||||
sec = local_sections[r_symndx];
|
||||
rel->r_addend += sec->output_offset + sym->st_value;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* This is a final link. */
|
||||
h = NULL;
|
||||
sym = NULL;
|
||||
sec = NULL;
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
{
|
||||
sym = local_syms + r_symndx;
|
||||
sec = local_sections[r_symndx];
|
||||
relocation = (sec->output_section->vma
|
||||
+ sec->output_offset
|
||||
+ sym->st_value);
|
||||
}
|
||||
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, input_bfd,
|
||||
input_section, rel->r_offset, TRUE)))
|
||||
return FALSE;
|
||||
relocation = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (h != NULL)
|
||||
name = h->root.root.string;
|
||||
else
|
||||
{
|
||||
name = (bfd_elf_string_from_elf_section
|
||||
(input_bfd, symtab_hdr->sh_link, sym->st_name));
|
||||
if (name == NULL || *name == '\0')
|
||||
name = bfd_section_name (input_bfd, sec);
|
||||
}
|
||||
|
||||
r = _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||||
contents, rel->r_offset,
|
||||
relocation, rel->r_addend);
|
||||
|
||||
if (r != bfd_reloc_ok)
|
||||
{
|
||||
const char * msg = (const char *) 0;
|
||||
|
||||
switch (r)
|
||||
{
|
||||
case bfd_reloc_overflow:
|
||||
if (!((*info->callbacks->reloc_overflow)
|
||||
(info, name, howto->name, (bfd_vma) 0,
|
||||
input_bfd, input_section, rel->r_offset)))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case bfd_reloc_undefined:
|
||||
if (!((*info->callbacks->undefined_symbol)
|
||||
(info, name, input_bfd, input_section,
|
||||
rel->r_offset, TRUE)))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case bfd_reloc_outofrange:
|
||||
msg = _ ("internal error: out of range error");
|
||||
goto common_error;
|
||||
|
||||
case bfd_reloc_notsupported:
|
||||
msg = _ ("internal error: unsupported relocation error");
|
||||
goto common_error;
|
||||
|
||||
case bfd_reloc_dangerous:
|
||||
msg = _ ("internal error: dangerous error");
|
||||
goto common_error;
|
||||
|
||||
default:
|
||||
msg = _ ("internal error: unknown error");
|
||||
/* fall through */
|
||||
|
||||
common_error:
|
||||
if (!((*info->callbacks->warning)
|
||||
(info, msg, name, input_bfd, input_section,
|
||||
rel->r_offset)))
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Set and control ELF flags in ELF header. */
|
||||
|
||||
bfd_boolean
|
||||
_bfd_m68hc11_elf_set_private_flags (abfd, flags)
|
||||
bfd *abfd;
|
||||
flagword flags;
|
||||
{
|
||||
BFD_ASSERT (!elf_flags_init (abfd)
|
||||
|| elf_elfheader (abfd)->e_flags == flags);
|
||||
|
||||
elf_elfheader (abfd)->e_flags = flags;
|
||||
elf_flags_init (abfd) = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Merge backend specific data from an object file to the output
|
||||
object file when linking. */
|
||||
|
||||
bfd_boolean
|
||||
_bfd_m68hc11_elf_merge_private_bfd_data (ibfd, obfd)
|
||||
bfd *ibfd;
|
||||
bfd *obfd;
|
||||
{
|
||||
flagword old_flags;
|
||||
flagword new_flags;
|
||||
bfd_boolean ok = TRUE;
|
||||
|
||||
/* Check if we have the same endianess */
|
||||
if (!_bfd_generic_verify_endian_match (ibfd, obfd))
|
||||
return FALSE;
|
||||
|
||||
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|
||||
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
|
||||
return TRUE;
|
||||
|
||||
new_flags = elf_elfheader (ibfd)->e_flags;
|
||||
elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
|
||||
old_flags = elf_elfheader (obfd)->e_flags;
|
||||
|
||||
if (! elf_flags_init (obfd))
|
||||
{
|
||||
elf_flags_init (obfd) = TRUE;
|
||||
elf_elfheader (obfd)->e_flags = new_flags;
|
||||
elf_elfheader (obfd)->e_ident[EI_CLASS]
|
||||
= elf_elfheader (ibfd)->e_ident[EI_CLASS];
|
||||
|
||||
if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
|
||||
&& bfd_get_arch_info (obfd)->the_default)
|
||||
{
|
||||
if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
|
||||
bfd_get_mach (ibfd)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Check ABI compatibility. */
|
||||
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));
|
||||
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));
|
||||
ok = FALSE;
|
||||
}
|
||||
new_flags &= ~EF_M68HC11_ABI;
|
||||
old_flags &= ~EF_M68HC11_ABI;
|
||||
|
||||
/* 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);
|
||||
ok = FALSE;
|
||||
}
|
||||
|
||||
if (! ok)
|
||||
{
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bfd_boolean
|
||||
_bfd_m68hc11_elf_print_private_bfd_data (abfd, ptr)
|
||||
bfd *abfd;
|
||||
PTR ptr;
|
||||
{
|
||||
FILE *file = (FILE *) ptr;
|
||||
|
||||
BFD_ASSERT (abfd != NULL && ptr != NULL);
|
||||
|
||||
/* Print normal ELF private data. */
|
||||
_bfd_elf_print_private_bfd_data (abfd, ptr);
|
||||
|
||||
/* xgettext:c-format */
|
||||
fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
|
||||
|
||||
if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
|
||||
fprintf (file, _("[abi=32-bit int,"));
|
||||
else
|
||||
fprintf (file, _("[abi=16-bit int,"));
|
||||
|
||||
if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
|
||||
fprintf (file, _(" 64-bit double]"));
|
||||
else
|
||||
fprintf (file, _(" 32-bit double]"));
|
||||
|
||||
if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
|
||||
fprintf (file, _(" [memory=bank-model]"));
|
||||
else
|
||||
fprintf (file, _(" [memory=flat]"));
|
||||
|
||||
fputc ('\n', file);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Below is the only difference between elf32-m68hc12.c and elf32-m68hc11.c.
|
||||
The Motorola spec says to use a different Elf machine code. */
|
||||
#define ELF_ARCH bfd_arch_m68hc11
|
||||
#define ELF_MACHINE_CODE EM_68HC11
|
||||
#define ELF_MAXPAGESIZE 0x1000
|
||||
@ -1624,9 +1295,15 @@ _bfd_m68hc11_elf_print_private_bfd_data (abfd, ptr)
|
||||
#define elf_backend_gc_sweep_hook elf32_m68hc11_gc_sweep_hook
|
||||
#define elf_backend_check_relocs elf32_m68hc11_check_relocs
|
||||
#define elf_backend_relocate_section elf32_m68hc11_relocate_section
|
||||
#define elf_backend_add_symbol_hook elf32_m68hc11_add_symbol_hook
|
||||
#define elf_backend_object_p 0
|
||||
#define elf_backend_final_write_processing 0
|
||||
#define elf_backend_can_gc_sections 1
|
||||
|
||||
#define bfd_elf32_bfd_link_hash_table_create \
|
||||
m68hc11_elf_bfd_link_hash_table_create
|
||||
#define bfd_elf32_bfd_link_hash_table_free \
|
||||
m68hc11_elf_bfd_link_hash_table_free
|
||||
#define bfd_elf32_bfd_merge_private_bfd_data \
|
||||
_bfd_m68hc11_elf_merge_private_bfd_data
|
||||
#define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags
|
||||
|
Reference in New Issue
Block a user