Back to index

cell-binutils  2.17cvs20070401
elf32-m68hc12.c
Go to the documentation of this file.
00001 /* Motorola 68HC12-specific support for 32-bit ELF
00002    Copyright 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007
00003    Free Software Foundation, Inc.
00004    Contributed by Stephane Carrez (stcarrez@nerim.fr)
00005    (Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
00006 
00007 This file is part of BFD, the Binary File Descriptor library.
00008 
00009 This program is free software; you can redistribute it and/or modify
00010 it under the terms of the GNU General Public License as published by
00011 the Free Software Foundation; either version 2 of the License, or
00012 (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00022 
00023 #include "bfd.h"
00024 #include "sysdep.h"
00025 #include "bfdlink.h"
00026 #include "libbfd.h"
00027 #include "elf-bfd.h"
00028 #include "elf32-m68hc1x.h"
00029 #include "elf/m68hc11.h"
00030 #include "opcode/m68hc11.h"
00031 
00032 /* Relocation functions.  */
00033 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
00034   (bfd *, bfd_reloc_code_real_type);
00035 static void m68hc11_info_to_howto_rel
00036   (bfd *, arelent *, Elf_Internal_Rela *);
00037 
00038 /* Trampoline generation.  */
00039 static bfd_boolean m68hc12_elf_size_one_stub
00040   (struct bfd_hash_entry *gen_entry, void *in_arg);
00041 static bfd_boolean m68hc12_elf_build_one_stub
00042   (struct bfd_hash_entry *gen_entry, void *in_arg);
00043 static struct bfd_link_hash_table* m68hc12_elf_bfd_link_hash_table_create
00044   (bfd*);
00045 
00046 static bfd_boolean m68hc12_elf_set_mach_from_flags PARAMS ((bfd *));
00047 
00048 /* Use REL instead of RELA to save space */
00049 #define USE_REL      1
00050 
00051 /* The 68HC12 microcontroler has a memory bank switching system
00052    with a 16Kb window in the 64Kb address space.  The extended memory
00053    is mapped in the 16Kb window (at 0x8000).  The page register controls
00054    which 16Kb bank is mapped.  The call/rtc instructions take care of
00055    bank switching in function calls/returns.
00056 
00057    For GNU Binutils to work, we consider there is a physical memory
00058    at 0..0x0ffff and a kind of virtual memory above that.  Symbols
00059    in virtual memory have their addresses treated in a special way
00060    when disassembling and when linking.
00061 
00062    For the linker to work properly, we must always relocate the virtual
00063    memory as if it is mapped at 0x8000.  When a 16-bit relocation is
00064    made in the virtual memory, we check that it does not cross the
00065    memory bank where it is used.  This would involve a page change
00066    which would be wrong.  The 24-bit relocation is for that and it
00067    treats the address as a physical address + page number.
00068 
00069 
00070                                    Banked
00071                                    Address Space
00072                                         |               |       Page n
00073                                    +---------------+ 0x1010000
00074                                         |               |
00075                                         | jsr _foo      |
00076                                         | ..            |       Page 3
00077                                         | _foo:         |
00078                                    +---------------+ 0x100C000
00079                                    |              |
00080                                         | call _bar     |
00081                                    | ..           |     Page 2
00082                                    | _bar:               |
00083                                    +---------------+ 0x1008000
00084                             /------>|             |
00085                             |      | call _foo     |    Page 1
00086                             |      |             |
00087                             |      +---------------+ 0x1004000
00088       Physical                     |      |              |
00089       Address Space         |      |              |     Page 0
00090                             |      |              |
00091     +-----------+ 0x00FFFF  |      +---------------+ 0x1000000
00092     |         |             |
00093     | call _foo      |             |
00094     |         |             |
00095     +-----------+ 0x00BFFF -+---/
00096     |         |           |
00097     |         |          |
00098     |         | 16K      |
00099     |         |          |
00100     +-----------+ 0x008000 -+
00101     |         |
00102     |         |
00103     =         =
00104     |         |
00105     |         |
00106     +-----------+ 0000
00107 
00108 
00109    The 'call _foo' must be relocated with page 3 and 16-bit address
00110    mapped at 0x8000.
00111 
00112    The 3-bit and 16-bit PC rel relocation is only used by 68HC12.  */
00113 static reloc_howto_type elf_m68hc11_howto_table[] = {
00114   /* This reloc does nothing.  */
00115   HOWTO (R_M68HC11_NONE,    /* type */
00116         0,                  /* rightshift */
00117         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00118         32,                 /* bitsize */
00119         FALSE,                     /* pc_relative */
00120         0,                  /* bitpos */
00121         complain_overflow_dont,/* complain_on_overflow */
00122         bfd_elf_generic_reloc,     /* special_function */
00123         "R_M68HC12_NONE",   /* name */
00124         FALSE,                     /* partial_inplace */
00125         0,                  /* src_mask */
00126         0,                  /* dst_mask */
00127         FALSE),             /* pcrel_offset */
00128 
00129   /* A 8 bit absolute relocation */
00130   HOWTO (R_M68HC11_8,              /* type */
00131         0,                  /* rightshift */
00132         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00133         8,                  /* bitsize */
00134         FALSE,                     /* pc_relative */
00135         0,                  /* bitpos */
00136         complain_overflow_bitfield,       /* complain_on_overflow */
00137         bfd_elf_generic_reloc,     /* special_function */
00138         "R_M68HC12_8",             /* name */
00139         FALSE,                     /* partial_inplace */
00140         0x00ff,             /* src_mask */
00141         0x00ff,             /* dst_mask */
00142         FALSE),             /* pcrel_offset */
00143 
00144   /* A 8 bit absolute relocation (upper address) */
00145   HOWTO (R_M68HC11_HI8,            /* type */
00146         8,                  /* rightshift */
00147         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00148         8,                  /* bitsize */
00149         FALSE,                     /* pc_relative */
00150         0,                  /* bitpos */
00151         complain_overflow_bitfield,       /* complain_on_overflow */
00152         bfd_elf_generic_reloc,     /* special_function */
00153         "R_M68HC12_HI8",    /* name */
00154         FALSE,                     /* partial_inplace */
00155         0x00ff,             /* src_mask */
00156         0x00ff,             /* dst_mask */
00157         FALSE),             /* pcrel_offset */
00158 
00159   /* A 8 bit absolute relocation (upper address) */
00160   HOWTO (R_M68HC11_LO8,            /* type */
00161         0,                  /* rightshift */
00162         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00163         8,                  /* bitsize */
00164         FALSE,                     /* pc_relative */
00165         0,                  /* bitpos */
00166         complain_overflow_dont,    /* complain_on_overflow */
00167         bfd_elf_generic_reloc,     /* special_function */
00168         "R_M68HC12_LO8",    /* name */
00169         FALSE,                     /* partial_inplace */
00170         0x00ff,             /* src_mask */
00171         0x00ff,             /* dst_mask */
00172         FALSE),             /* pcrel_offset */
00173 
00174   /* A 8 bit PC-rel relocation */
00175   HOWTO (R_M68HC11_PCREL_8, /* type */
00176         0,                  /* rightshift */
00177         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00178         8,                  /* bitsize */
00179         TRUE,               /* pc_relative */
00180         0,                  /* bitpos */
00181         complain_overflow_bitfield,       /* complain_on_overflow */
00182         bfd_elf_generic_reloc,     /* special_function */
00183         "R_M68HC12_PCREL_8",       /* name */
00184         FALSE,                     /* partial_inplace */
00185         0x00ff,             /* src_mask */
00186         0x00ff,             /* dst_mask */
00187         TRUE),                 /* pcrel_offset */
00188 
00189   /* A 16 bit absolute relocation */
00190   HOWTO (R_M68HC11_16,             /* type */
00191         0,                  /* rightshift */
00192         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00193         16,                 /* bitsize */
00194         FALSE,                     /* pc_relative */
00195         0,                  /* bitpos */
00196         complain_overflow_dont /*bitfield */ ,   /* complain_on_overflow */
00197         bfd_elf_generic_reloc,     /* special_function */
00198         "R_M68HC12_16",     /* name */
00199         FALSE,                     /* partial_inplace */
00200         0xffff,             /* src_mask */
00201         0xffff,             /* dst_mask */
00202         FALSE),             /* pcrel_offset */
00203 
00204   /* A 32 bit absolute relocation.  This one is never used for the
00205      code relocation.  It's used by gas for -gstabs generation.  */
00206   HOWTO (R_M68HC11_32,             /* type */
00207         0,                  /* rightshift */
00208         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00209         32,                 /* bitsize */
00210         FALSE,                     /* pc_relative */
00211         0,                  /* bitpos */
00212         complain_overflow_bitfield,       /* complain_on_overflow */
00213         bfd_elf_generic_reloc,     /* special_function */
00214         "R_M68HC12_32",     /* name */
00215         FALSE,                     /* partial_inplace */
00216         0xffffffff,         /* src_mask */
00217         0xffffffff,         /* dst_mask */
00218         FALSE),             /* pcrel_offset */
00219 
00220   /* A 3 bit absolute relocation */
00221   HOWTO (R_M68HC11_3B,             /* type */
00222         0,                  /* rightshift */
00223         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00224         3,                  /* bitsize */
00225         FALSE,                     /* pc_relative */
00226         0,                  /* bitpos */
00227         complain_overflow_bitfield,       /* complain_on_overflow */
00228         bfd_elf_generic_reloc,     /* special_function */
00229         "R_M68HC12_4B",     /* name */
00230         FALSE,                     /* partial_inplace */
00231         0x003,                     /* src_mask */
00232         0x003,                     /* dst_mask */
00233         FALSE),             /* pcrel_offset */
00234 
00235   /* A 16 bit PC-rel relocation */
00236   HOWTO (R_M68HC11_PCREL_16,       /* type */
00237         0,                  /* rightshift */
00238         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00239         16,                 /* bitsize */
00240         TRUE,               /* pc_relative */
00241         0,                  /* bitpos */
00242         complain_overflow_dont,    /* complain_on_overflow */
00243         bfd_elf_generic_reloc,     /* special_function */
00244         "R_M68HC12_PCREL_16",      /* name */
00245         FALSE,                     /* partial_inplace */
00246         0xffff,             /* src_mask */
00247         0xffff,             /* dst_mask */
00248         TRUE),                 /* pcrel_offset */
00249 
00250   /* GNU extension to record C++ vtable hierarchy */
00251   HOWTO (R_M68HC11_GNU_VTINHERIT,  /* type */
00252         0,                  /* rightshift */
00253         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00254         0,                  /* bitsize */
00255         FALSE,                     /* pc_relative */
00256         0,                  /* bitpos */
00257         complain_overflow_dont,    /* complain_on_overflow */
00258         NULL,               /* special_function */
00259         "R_M68HC11_GNU_VTINHERIT", /* name */
00260         FALSE,                     /* partial_inplace */
00261         0,                  /* src_mask */
00262         0,                  /* dst_mask */
00263         FALSE),             /* pcrel_offset */
00264 
00265   /* GNU extension to record C++ vtable member usage */
00266   HOWTO (R_M68HC11_GNU_VTENTRY,    /* type */
00267         0,                  /* rightshift */
00268         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00269         0,                  /* bitsize */
00270         FALSE,                     /* pc_relative */
00271         0,                  /* bitpos */
00272         complain_overflow_dont,    /* complain_on_overflow */
00273         _bfd_elf_rel_vtable_reloc_fn,     /* special_function */
00274         "R_M68HC11_GNU_VTENTRY",   /* name */
00275         FALSE,                     /* partial_inplace */
00276         0,                  /* src_mask */
00277         0,                  /* dst_mask */
00278         FALSE),             /* pcrel_offset */
00279 
00280   /* A 24 bit relocation */
00281   HOWTO (R_M68HC11_24,              /* type */
00282         0,                  /* rightshift */
00283         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00284         24,                 /* bitsize */
00285         FALSE,                     /* pc_relative */
00286         0,                  /* bitpos */
00287         complain_overflow_dont,    /* complain_on_overflow */
00288         m68hc11_elf_special_reloc, /* special_function */
00289         "R_M68HC12_24",     /* name */
00290         FALSE,                     /* partial_inplace */
00291         0xffffff,           /* src_mask */
00292         0xffffff,           /* dst_mask */
00293         FALSE),             /* pcrel_offset */
00294 
00295   /* A 16-bit low relocation */
00296   HOWTO (R_M68HC11_LO16,        /* type */
00297         0,                  /* rightshift */
00298         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00299         16,                 /* bitsize */
00300         FALSE,                     /* pc_relative */
00301         0,                  /* bitpos */
00302         complain_overflow_dont,    /* complain_on_overflow */
00303         m68hc11_elf_special_reloc,/* special_function */
00304         "R_M68HC12_LO16",   /* name */
00305         FALSE,                     /* partial_inplace */
00306         0xffff,             /* src_mask */
00307         0xffff,             /* dst_mask */
00308         FALSE),             /* pcrel_offset */
00309 
00310   /* A page relocation */
00311   HOWTO (R_M68HC11_PAGE,        /* type */
00312         0,                  /* rightshift */
00313         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00314         8,                  /* bitsize */
00315         FALSE,                     /* pc_relative */
00316         0,                  /* bitpos */
00317         complain_overflow_dont,    /* complain_on_overflow */
00318         m68hc11_elf_special_reloc,/* special_function */
00319         "R_M68HC12_PAGE",   /* name */
00320         FALSE,                     /* partial_inplace */
00321         0x00ff,             /* src_mask */
00322         0x00ff,             /* dst_mask */
00323         FALSE),             /* pcrel_offset */
00324 
00325   EMPTY_HOWTO (14),
00326   EMPTY_HOWTO (15),
00327   EMPTY_HOWTO (16),
00328   EMPTY_HOWTO (17),
00329   EMPTY_HOWTO (18),
00330   EMPTY_HOWTO (19),
00331 
00332   /* Mark beginning of a jump instruction (any form).  */
00333   HOWTO (R_M68HC11_RL_JUMP, /* type */
00334         0,                  /* rightshift */
00335         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00336         0,                  /* bitsize */
00337         FALSE,                     /* pc_relative */
00338         0,                  /* bitpos */
00339         complain_overflow_dont,    /* complain_on_overflow */
00340         m68hc11_elf_ignore_reloc,  /* special_function */
00341         "R_M68HC12_RL_JUMP",       /* name */
00342         TRUE,               /* partial_inplace */
00343         0,                  /* src_mask */
00344         0,                  /* dst_mask */
00345         TRUE),                 /* pcrel_offset */
00346 
00347   /* Mark beginning of Gcc relaxation group instruction.  */
00348   HOWTO (R_M68HC11_RL_GROUP,       /* type */
00349         0,                  /* rightshift */
00350         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00351         0,                  /* bitsize */
00352         FALSE,                     /* pc_relative */
00353         0,                  /* bitpos */
00354         complain_overflow_dont,    /* complain_on_overflow */
00355         m68hc11_elf_ignore_reloc,  /* special_function */
00356         "R_M68HC12_RL_GROUP",      /* name */
00357         TRUE,               /* partial_inplace */
00358         0,                  /* src_mask */
00359         0,                  /* dst_mask */
00360         TRUE),                 /* pcrel_offset */
00361 };
00362 
00363 /* Map BFD reloc types to M68HC11 ELF reloc types.  */
00364 
00365 struct m68hc11_reloc_map
00366 {
00367   bfd_reloc_code_real_type bfd_reloc_val;
00368   unsigned char elf_reloc_val;
00369 };
00370 
00371 static const struct m68hc11_reloc_map m68hc11_reloc_map[] = {
00372   {BFD_RELOC_NONE, R_M68HC11_NONE,},
00373   {BFD_RELOC_8, R_M68HC11_8},
00374   {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
00375   {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
00376   {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
00377   {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
00378   {BFD_RELOC_16, R_M68HC11_16},
00379   {BFD_RELOC_32, R_M68HC11_32},
00380   {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
00381 
00382   {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
00383   {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
00384 
00385   {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
00386   {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
00387   {BFD_RELOC_M68HC11_24, R_M68HC11_24},
00388 
00389   {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
00390   {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
00391 };
00392 
00393 static reloc_howto_type *
00394 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00395                                  bfd_reloc_code_real_type code)
00396 {
00397   unsigned int i;
00398 
00399   for (i = 0;
00400        i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
00401        i++)
00402     {
00403       if (m68hc11_reloc_map[i].bfd_reloc_val == code)
00404        return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
00405     }
00406 
00407   return NULL;
00408 }
00409 
00410 static reloc_howto_type *
00411 bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00412                              const char *r_name)
00413 {
00414   unsigned int i;
00415 
00416   for (i = 0;
00417        i < (sizeof (elf_m68hc11_howto_table)
00418            / sizeof (elf_m68hc11_howto_table[0]));
00419        i++)
00420     if (elf_m68hc11_howto_table[i].name != NULL
00421        && strcasecmp (elf_m68hc11_howto_table[i].name, r_name) == 0)
00422       return &elf_m68hc11_howto_table[i];
00423 
00424   return NULL;
00425 }
00426 
00427 /* Set the howto pointer for an M68HC11 ELF reloc.  */
00428 
00429 static void
00430 m68hc11_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
00431                            arelent *cache_ptr, Elf_Internal_Rela *dst)
00432 {
00433   unsigned int r_type;
00434 
00435   r_type = ELF32_R_TYPE (dst->r_info);
00436   BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
00437   cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
00438 }
00439 
00440 
00441 /* Far trampoline generation.  */
00442 
00443 /* Build a 68HC12 trampoline stub.  */
00444 static bfd_boolean
00445 m68hc12_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
00446 {
00447   struct elf32_m68hc11_stub_hash_entry *stub_entry;
00448   struct bfd_link_info *info;
00449   struct m68hc11_elf_link_hash_table *htab;
00450   asection *stub_sec;
00451   bfd *stub_bfd;
00452   bfd_byte *loc;
00453   bfd_vma sym_value, phys_page, phys_addr;
00454 
00455   /* Massage our args to the form they really have.  */
00456   stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
00457   info = (struct bfd_link_info *) in_arg;
00458 
00459   htab = m68hc11_elf_hash_table (info);
00460 
00461   stub_sec = stub_entry->stub_sec;
00462 
00463   /* Make a note of the offset within the stubs for this entry.  */
00464   stub_entry->stub_offset = stub_sec->size;
00465   stub_sec->size += 7;
00466   loc = stub_sec->contents + stub_entry->stub_offset;
00467 
00468   stub_bfd = stub_sec->owner;
00469 
00470   /* Create the trampoline call stub:
00471 
00472      ldy #%addr(symbol)
00473      call %page(symbol), __trampoline
00474 
00475   */
00476   sym_value = (stub_entry->target_value
00477                + stub_entry->target_section->output_offset
00478                + stub_entry->target_section->output_section->vma);
00479   phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value);
00480   phys_page = m68hc11_phys_page (&htab->pinfo, sym_value);
00481 
00482   /* ldy #%page(sym) */
00483   bfd_put_8 (stub_bfd, 0xCD, loc);
00484   bfd_put_16 (stub_bfd, phys_addr, loc + 1);
00485   loc += 3;
00486 
00487   /* call %page(sym), __trampoline  */
00488   bfd_put_8 (stub_bfd, 0x4a, loc);
00489   bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1);
00490   bfd_put_8 (stub_bfd, phys_page, loc + 3);
00491 
00492   return TRUE;
00493 }
00494 
00495 /* As above, but don't actually build the stub.  Just bump offset so
00496    we know stub section sizes.  */
00497 
00498 static bfd_boolean
00499 m68hc12_elf_size_one_stub (struct bfd_hash_entry *gen_entry,
00500                            void *in_arg ATTRIBUTE_UNUSED)
00501 {
00502   struct elf32_m68hc11_stub_hash_entry *stub_entry;
00503 
00504   /* Massage our args to the form they really have.  */
00505   stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
00506 
00507   stub_entry->stub_sec->size += 7;
00508   return TRUE;
00509 }
00510 
00511 /* Create a 68HC12 ELF linker hash table.  */
00512 
00513 static struct bfd_link_hash_table *
00514 m68hc12_elf_bfd_link_hash_table_create (bfd *abfd)
00515 {
00516   struct m68hc11_elf_link_hash_table *ret;
00517 
00518   ret = m68hc11_elf_hash_table_create (abfd);
00519   if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
00520     return NULL;
00521 
00522   ret->size_one_stub = m68hc12_elf_size_one_stub;
00523   ret->build_one_stub = m68hc12_elf_build_one_stub;
00524 
00525   return &ret->root.root;
00526 }
00527 
00528 static bfd_boolean
00529 m68hc12_elf_set_mach_from_flags (bfd *abfd)
00530 {
00531   flagword flags = elf_elfheader (abfd)->e_flags;
00532 
00533   switch (flags & EF_M68HC11_MACH_MASK)
00534     {
00535     case EF_M68HC12_MACH:
00536       bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, bfd_mach_m6812);
00537       break;
00538     case EF_M68HCS12_MACH:
00539       bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, bfd_mach_m6812s);
00540       break;
00541     case EF_M68HC11_GENERIC:
00542       bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12,
00543                                  bfd_mach_m6812_default);
00544       break;
00545     default:
00546       return FALSE;
00547     }
00548   return TRUE;
00549 }
00550 
00551 /* Specific sections:
00552    - The .page0 is a data section that is mapped in [0x0000..0x00FF].
00553      Page0 accesses are faster on the M68HC12.
00554    - The .vectors is the section that represents the interrupt
00555      vectors.  */
00556 static const struct bfd_elf_special_section elf32_m68hc12_special_sections[] =
00557 {
00558   { STRING_COMMA_LEN (".eeprom"),   0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
00559   { STRING_COMMA_LEN (".page0"),    0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
00560   { STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
00561   { STRING_COMMA_LEN (".vectors"),  0, SHT_PROGBITS, SHF_ALLOC },
00562   { NULL,                       0,  0, 0,            0 }
00563 };
00564 
00565 #define ELF_ARCH            bfd_arch_m68hc12
00566 #define ELF_MACHINE_CODE    EM_68HC12
00567 #define ELF_MAXPAGESIZE            0x1000
00568 
00569 #define TARGET_BIG_SYM          bfd_elf32_m68hc12_vec
00570 #define TARGET_BIG_NAME            "elf32-m68hc12"
00571 
00572 #define elf_info_to_howto   0
00573 #define elf_info_to_howto_rel      m68hc11_info_to_howto_rel
00574 #define elf_backend_check_relocs     elf32_m68hc11_check_relocs
00575 #define elf_backend_relocate_section elf32_m68hc11_relocate_section
00576 #define elf_backend_object_p              m68hc12_elf_set_mach_from_flags
00577 #define elf_backend_final_write_processing       0
00578 #define elf_backend_can_gc_sections              1
00579 #define elf_backend_special_sections elf32_m68hc12_special_sections
00580 #define elf_backend_post_process_headers     elf32_m68hc11_post_process_headers
00581 #define elf_backend_add_symbol_hook  elf32_m68hc11_add_symbol_hook
00582 
00583 #define bfd_elf32_bfd_link_hash_table_create \
00584                                 m68hc12_elf_bfd_link_hash_table_create
00585 #define bfd_elf32_bfd_link_hash_table_free \
00586                             m68hc11_elf_bfd_link_hash_table_free
00587 #define bfd_elf32_bfd_merge_private_bfd_data \
00588                                    _bfd_m68hc11_elf_merge_private_bfd_data
00589 #define bfd_elf32_bfd_set_private_flags   _bfd_m68hc11_elf_set_private_flags
00590 #define bfd_elf32_bfd_print_private_bfd_data \
00591                                    _bfd_m68hc11_elf_print_private_bfd_data
00592 
00593 #include "elf32-target.h"