* 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:
Stephane Carrez
2003-04-21 13:22:14 +00:00
parent 81eca1a78a
commit 3a65329d1f
5 changed files with 2003 additions and 808 deletions

View File

@ -1,5 +1,5 @@
/* Motorola 68HC12-specific support for 32-bit ELF
Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
Contributed by Stephane Carrez (stcarrez@nerim.fr)
(Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
@ -21,49 +21,33 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
#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 **));
static bfd_reloc_status_type m68hc12_elf_special_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
static int m68hc12_addr_is_banked PARAMS ((bfd_vma));
static bfd_vma m68hc12_phys_addr PARAMS ((bfd_vma));
static bfd_vma m68hc12_phys_page PARAMS ((bfd_vma));
/* 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 *));
/* Trampoline generation. */
static bfd_boolean m68hc12_elf_size_one_stub
PARAMS((struct bfd_hash_entry *gen_entry, PTR in_arg));
static bfd_boolean m68hc12_elf_build_one_stub
PARAMS((struct bfd_hash_entry *gen_entry, PTR in_arg));
static struct bfd_link_hash_table* m68hc12_elf_bfd_link_hash_table_create
PARAMS((bfd*));
static bfd_boolean m68hc12_elf_set_mach_from_flags PARAMS ((bfd *));
bfd_boolean _bfd_m68hc12_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
bfd_boolean _bfd_m68hc12_elf_set_private_flags PARAMS ((bfd *, flagword));
bfd_boolean _bfd_m68hc12_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.
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).
The 68HC12 microcontroler has a memory bank switching system
/* The 68HC12 microcontroler has a memory bank switching system
with a 16Kb window in the 64Kb address space. The extended memory
is mapped in the 16Kb window (at 0x8000). The page register controls
which 16Kb bank is mapped. The call/rtc instructions take care of
@ -199,7 +183,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
FALSE, /* partial_inplace */
0x00ff, /* src_mask */
0x00ff, /* dst_mask */
FALSE), /* pcrel_offset */
TRUE), /* pcrel_offset */
/* A 16 bit absolute relocation */
HOWTO (R_M68HC11_16, /* type */
@ -209,7 +193,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
m68hc12_elf_special_reloc, /* special_function */
bfd_elf_generic_reloc, /* special_function */
"R_M68HC12_16", /* name */
FALSE, /* partial_inplace */
0xffff, /* src_mask */
@ -260,7 +244,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
TRUE), /* pcrel_offset */
/* GNU extension to record C++ vtable hierarchy */
HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */
@ -295,16 +279,16 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
/* A 24 bit relocation */
HOWTO (R_M68HC11_24, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
2, /* size (0 = byte, 1 = short, 2 = long) */
24, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
m68hc12_elf_special_reloc, /* special_function */
m68hc11_elf_special_reloc, /* special_function */
"R_M68HC12_24", /* name */
FALSE, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
0xffffff, /* src_mask */
0xffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* A 16-bit low relocation */
@ -315,7 +299,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
m68hc12_elf_special_reloc,/* special_function */
m68hc11_elf_special_reloc,/* special_function */
"R_M68HC12_LO16", /* name */
FALSE, /* partial_inplace */
0xffff, /* src_mask */
@ -330,7 +314,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
m68hc12_elf_special_reloc,/* special_function */
m68hc11_elf_special_reloc,/* special_function */
"R_M68HC12_PAGE", /* name */
FALSE, /* partial_inplace */
0x00ff, /* src_mask */
@ -423,158 +407,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;
}
static int
m68hc12_addr_is_banked (addr)
bfd_vma addr;
{
return (addr >= M68HC12_BANK_VIRT) ? 1 : 0;
}
/* Return the physical address seen by the processor, taking
into account banked memory. */
static bfd_vma
m68hc12_phys_addr (addr)
bfd_vma addr;
{
if (addr < M68HC12_BANK_VIRT)
return addr;
/* Map the address to the memory bank. */
addr -= M68HC12_BANK_VIRT;
addr &= M68HC12_BANK_MASK;
addr += M68HC12_BANK_BASE;
return addr;
}
/* Return the page number corresponding to an address in banked memory. */
static bfd_vma
m68hc12_phys_page (addr)
bfd_vma addr;
{
if (addr < M68HC12_BANK_VIRT)
return 0;
/* Map the address to the memory bank. */
addr -= M68HC12_BANK_VIRT;
addr >>= M68HC12_BANK_SHIFT;
addr &= M68HC12_BANK_PAGE_MASK;
return addr;
}
static bfd_reloc_status_type
m68hc12_elf_special_reloc (abfd, reloc_entry, symbol, data, input_section,
output_bfd, error_message)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol;
PTR data;
asection *input_section;
bfd *output_bfd;
char **error_message ATTRIBUTE_UNUSED;
{
reloc_howto_type *howto;
bfd_vma relocation;
bfd_vma phys_addr;
bfd_vma phys_page;
bfd_vma insn_page;
bfd_vma insn_addr;
if (output_bfd != (bfd *) NULL
&& (symbol->flags & BSF_SECTION_SYM) == 0
&& (! reloc_entry->howto->partial_inplace
|| reloc_entry->addend == 0))
{
reloc_entry->address += input_section->output_offset;
return bfd_reloc_ok;
}
if (output_bfd != NULL)
return bfd_reloc_continue;
if (reloc_entry->address > input_section->_cooked_size)
return bfd_reloc_outofrange;
/* Compute relocation. */
relocation = (symbol->value
+ symbol->section->output_section->vma
+ symbol->section->output_offset);
relocation += reloc_entry->addend;
relocation += bfd_get_16 (abfd, (bfd_byte*) data + reloc_entry->address);
/* Do the memory bank mapping. */
phys_addr = m68hc12_phys_addr (relocation);
phys_page = m68hc12_phys_page (relocation);
howto = reloc_entry->howto;
if (howto->complain_on_overflow != complain_overflow_dont
&& (phys_addr & (((bfd_vma) -1) << 16)))
return bfd_reloc_overflow;
switch (howto->type)
{
case R_M68HC11_16:
/* Get virtual address of instruction having the relocation. */
insn_addr = input_section->output_section->vma
+ input_section->output_offset
+ reloc_entry->address;
insn_page = m68hc12_phys_page (insn_addr);
if (m68hc12_addr_is_banked (relocation)
&& m68hc12_addr_is_banked (insn_addr)
&& phys_page != insn_page)
{
*error_message = _("address is not in the same bank");
return bfd_reloc_dangerous;
}
if (m68hc12_addr_is_banked (relocation)
&& !m68hc12_addr_is_banked (insn_addr))
{
*error_message = _("reference to a banked address in "
"the normal address space");
return bfd_reloc_dangerous;
}
case R_M68HC11_LO16:
bfd_put_16 (abfd, phys_addr, (bfd_byte*) data + reloc_entry->address);
break;
case R_M68HC11_24:
bfd_put_16 (abfd, phys_addr, (bfd_byte*) data + reloc_entry->address);
bfd_put_8 (abfd, phys_page, (bfd_byte*) data + reloc_entry->address + 2);
break;
case R_M68HC11_PAGE:
bfd_put_8 (abfd, phys_page, (bfd_byte*) data + reloc_entry->address);
break;
default:
abort ();
break;
}
return bfd_reloc_ok;
}
/* Set the howto pointer for an M68HC11 ELF reloc. */
static void
@ -590,50 +422,97 @@ 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;
{
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;
case bfd_link_hash_common:
return h->root.u.c.p->section;
default:
break;
}
}
}
else
return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
return NULL;
}
/* Far trampoline generation. */
/* Build a 68HC12 trampoline stub. */
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;
m68hc12_elf_build_one_stub (gen_entry, in_arg)
struct bfd_hash_entry *gen_entry;
PTR in_arg;
{
/* We don't use got and plt entries for 68hc11/68hc12. */
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;
/* 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;
htab = m68hc11_elf_hash_table (info);
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 += 7;
loc = stub_sec->contents + stub_entry->stub_offset;
stub_bfd = stub_sec->owner;
/* Create the trampoline call stub:
ldy #%addr(symbol)
call %page(symbol), __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);
/* ldy #%page(sym) */
bfd_put_8 (stub_bfd, 0xCD, loc);
bfd_put_16 (stub_bfd, phys_addr, loc + 1);
loc += 3;
/* call %page(sym), __trampoline */
bfd_put_8 (stub_bfd, 0x4a, loc);
bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1);
bfd_put_8 (stub_bfd, phys_page, loc + 3);
return TRUE;
}
/* As above, but don't actually build the stub. Just bump offset so
we know stub section sizes. */
static bfd_boolean
m68hc12_elf_size_one_stub (gen_entry, in_arg)
struct bfd_hash_entry *gen_entry;
PTR in_arg ATTRIBUTE_UNUSED;
{
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 += 7;
return TRUE;
}
/* Create a 68HC12 ELF linker hash table. */
static struct bfd_link_hash_table *
m68hc12_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 = m68hc12_elf_size_one_stub;
ret->build_one_stub = m68hc12_elf_build_one_stub;
return &ret->root.root;
}
static bfd_boolean
m68hc12_elf_set_mach_from_flags (abfd)
@ -659,149 +538,6 @@ m68hc12_elf_set_mach_from_flags (abfd)
return TRUE;
}
/* Set and control ELF flags in ELF header. */
bfd_boolean
_bfd_m68hc12_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 m68hc12_elf_set_mach_from_flags (abfd);
}
/* Merge backend specific data from an object file to the output
object file when linking. */
bfd_boolean
_bfd_m68hc12_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;
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;
}
/* Processor compatibility. */
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));
ok = FALSE;
}
new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK)
| (EF_M68HC11_MERGE_MACH (new_flags, old_flags)));
elf_elfheader (obfd)->e_flags = new_flags;
/* Warn about any other mismatches */
new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
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_m68hc12_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 & EF_M68HCS12_MACH)
fprintf (file, _(" cpu=HCS12]"));
else
fprintf (file, _(" cpu=HC12]"));
fputc ('\n', file);
return TRUE;
}
#define ELF_ARCH bfd_arch_m68hc12
#define ELF_MACHINE_CODE EM_68HC12
#define ELF_MAXPAGESIZE 0x1000
@ -813,15 +549,22 @@ _bfd_m68hc12_elf_print_private_bfd_data (abfd, ptr)
#define elf_info_to_howto_rel m68hc11_info_to_howto_rel
#define elf_backend_gc_mark_hook elf32_m68hc11_gc_mark_hook
#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_object_p m68hc12_elf_set_mach_from_flags
#define elf_backend_final_write_processing 0
/* Disabled as this backend uses the generic linker. */
#define elf_backend_can_gc_sections 0
#define elf_backend_can_gc_sections 1
#define elf_backend_post_process_headers elf32_m68hc11_post_process_headers
#define elf_backend_add_symbol_hook elf32_m68hc11_add_symbol_hook
#define bfd_elf32_bfd_link_hash_table_create \
m68hc12_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_m68hc12_elf_merge_private_bfd_data
#define bfd_elf32_bfd_set_private_flags _bfd_m68hc12_elf_set_private_flags
_bfd_m68hc11_elf_merge_private_bfd_data
#define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags
#define bfd_elf32_bfd_print_private_bfd_data \
_bfd_m68hc12_elf_print_private_bfd_data
_bfd_m68hc11_elf_print_private_bfd_data
#include "elf32-target.h"