[BACK]Return to elf32-m68hc12.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / bfd

Annotation of src/external/gpl3/binutils.old/dist/bfd/elf32-m68hc12.c, Revision 1.6

1.1       christos    1: /* Motorola 68HC12-specific support for 32-bit ELF
1.6     ! christos    2:    Copyright (C) 1999-2018 Free Software Foundation, Inc.
1.1       christos    3:    Contributed by Stephane Carrez (stcarrez@nerim.fr)
                      4:    (Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
                      5:
                      6:    This file is part of BFD, the Binary File Descriptor library.
                      7:
                      8:    This program is free software; you can redistribute it and/or modify
                      9:    it under the terms of the GNU General Public License as published by
                     10:    the Free Software Foundation; either version 3 of the License, or
                     11:    (at your option) any later version.
                     12:
                     13:    This program is distributed in the hope that it will be useful,
                     14:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16:    GNU General Public License for more details.
                     17:
                     18:    You should have received a copy of the GNU General Public License
                     19:    along with this program; if not, write to the Free Software
                     20:    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
                     21:    MA 02110-1301, USA.  */
                     22:
                     23: #include "sysdep.h"
                     24: #include "bfd.h"
                     25: #include "bfdlink.h"
                     26: #include "libbfd.h"
                     27: #include "elf-bfd.h"
                     28: #include "elf32-m68hc1x.h"
                     29: #include "elf/m68hc11.h"
                     30: #include "opcode/m68hc11.h"
                     31:
                     32: /* Relocation functions.  */
                     33: static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
                     34:   (bfd *, bfd_reloc_code_real_type);
1.6     ! christos   35: static bfd_boolean m68hc11_info_to_howto_rel
1.1       christos   36:   (bfd *, arelent *, Elf_Internal_Rela *);
                     37:
                     38: /* Trampoline generation.  */
                     39:
                     40:
                     41: /* Use REL instead of RELA to save space */
                     42: #define USE_REL        1
                     43:
                     44: /* The 68HC12 microcontroler has a memory bank switching system
                     45:    with a 16Kb window in the 64Kb address space.  The extended memory
                     46:    is mapped in the 16Kb window (at 0x8000).  The page register controls
                     47:    which 16Kb bank is mapped.  The call/rtc instructions take care of
                     48:    bank switching in function calls/returns.
                     49:
                     50:    For GNU Binutils to work, we consider there is a physical memory
                     51:    at 0..0x0ffff and a kind of virtual memory above that.  Symbols
                     52:    in virtual memory have their addresses treated in a special way
                     53:    when disassembling and when linking.
                     54:
                     55:    For the linker to work properly, we must always relocate the virtual
                     56:    memory as if it is mapped at 0x8000.  When a 16-bit relocation is
                     57:    made in the virtual memory, we check that it does not cross the
                     58:    memory bank where it is used.  This would involve a page change
                     59:    which would be wrong.  The 24-bit relocation is for that and it
                     60:    treats the address as a physical address + page number.
                     61:
                     62:
                     63:                                        Banked
                     64:                                        Address Space
1.6     ! christos   65:                                        |               |       Page n
1.1       christos   66:                                        +---------------+ 0x1010000
1.6     ! christos   67:                                        |               |
        !            68:                                        | jsr _foo      |
        !            69:                                        | ..            |       Page 3
        !            70:                                        | _foo:         |
1.1       christos   71:                                        +---------------+ 0x100C000
1.6     ! christos   72:                                        |               |
        !            73:                                        | call _bar     |
        !            74:                                        | ..            |       Page 2
        !            75:                                        | _bar:         |
1.1       christos   76:                                        +---------------+ 0x1008000
1.6     ! christos   77:                                /------>|               |
        !            78:                                |       | call _foo     |       Page 1
        !            79:                                |       |               |
1.1       christos   80:                                |       +---------------+ 0x1004000
1.6     ! christos   81:       Physical                 |       |               |
        !            82:       Address Space            |       |               |       Page 0
        !            83:                                |       |               |
1.1       christos   84:     +-----------+ 0x00FFFF     |       +---------------+ 0x1000000
                     85:     |          |               |
                     86:     | call _foo        |               |
                     87:     |          |               |
                     88:     +-----------+ 0x00BFFF -+---/
1.6     ! christos   89:     |          |           |
1.1       christos   90:     |          |           |
                     91:     |          | 16K       |
                     92:     |          |           |
                     93:     +-----------+ 0x008000 -+
                     94:     |          |
                     95:     |          |
                     96:     =          =
                     97:     |          |
                     98:     |          |
                     99:     +-----------+ 0000
                    100:
                    101:
                    102:    The 'call _foo' must be relocated with page 3 and 16-bit address
                    103:    mapped at 0x8000.
                    104:
                    105:    The 3-bit and 16-bit PC rel relocation is only used by 68HC12.  */
                    106: static reloc_howto_type elf_m68hc11_howto_table[] = {
                    107:   /* This reloc does nothing.  */
                    108:   HOWTO (R_M68HC11_NONE,       /* type */
                    109:         0,                     /* rightshift */
1.3       christos  110:         3,                     /* size (0 = byte, 1 = short, 2 = long) */
                    111:         0,                     /* bitsize */
1.1       christos  112:         FALSE,                 /* pc_relative */
                    113:         0,                     /* bitpos */
                    114:         complain_overflow_dont,/* complain_on_overflow */
                    115:         bfd_elf_generic_reloc, /* special_function */
                    116:         "R_M68HC12_NONE",      /* name */
                    117:         FALSE,                 /* partial_inplace */
                    118:         0,                     /* src_mask */
                    119:         0,                     /* dst_mask */
                    120:         FALSE),                /* pcrel_offset */
                    121:
                    122:   /* A 8 bit absolute relocation */
                    123:   HOWTO (R_M68HC11_8,          /* type */
                    124:         0,                     /* rightshift */
                    125:         0,                     /* size (0 = byte, 1 = short, 2 = long) */
                    126:         8,                     /* bitsize */
                    127:         FALSE,                 /* pc_relative */
                    128:         0,                     /* bitpos */
                    129:         complain_overflow_bitfield,    /* complain_on_overflow */
                    130:         bfd_elf_generic_reloc, /* special_function */
                    131:         "R_M68HC12_8",         /* name */
                    132:         FALSE,                 /* partial_inplace */
                    133:         0x00ff,                /* src_mask */
                    134:         0x00ff,                /* dst_mask */
                    135:         FALSE),                /* pcrel_offset */
                    136:
                    137:   /* A 8 bit absolute relocation (upper address) */
                    138:   HOWTO (R_M68HC11_HI8,                /* type */
                    139:         8,                     /* rightshift */
                    140:         0,                     /* size (0 = byte, 1 = short, 2 = long) */
                    141:         8,                     /* bitsize */
                    142:         FALSE,                 /* pc_relative */
                    143:         0,                     /* bitpos */
                    144:         complain_overflow_bitfield,    /* complain_on_overflow */
                    145:         bfd_elf_generic_reloc, /* special_function */
                    146:         "R_M68HC12_HI8",       /* name */
                    147:         FALSE,                 /* partial_inplace */
                    148:         0x00ff,                /* src_mask */
                    149:         0x00ff,                /* dst_mask */
                    150:         FALSE),                /* pcrel_offset */
                    151:
                    152:   /* A 8 bit absolute relocation (upper address) */
                    153:   HOWTO (R_M68HC11_LO8,                /* type */
                    154:         0,                     /* rightshift */
                    155:         0,                     /* size (0 = byte, 1 = short, 2 = long) */
                    156:         8,                     /* bitsize */
                    157:         FALSE,                 /* pc_relative */
                    158:         0,                     /* bitpos */
                    159:         complain_overflow_dont,        /* complain_on_overflow */
                    160:         bfd_elf_generic_reloc, /* special_function */
                    161:         "R_M68HC12_LO8",       /* name */
                    162:         FALSE,                 /* partial_inplace */
                    163:         0x00ff,                /* src_mask */
                    164:         0x00ff,                /* dst_mask */
                    165:         FALSE),                /* pcrel_offset */
                    166:
                    167:   /* A 8 bit PC-rel relocation */
                    168:   HOWTO (R_M68HC11_PCREL_8,    /* type */
                    169:         0,                     /* rightshift */
                    170:         0,                     /* size (0 = byte, 1 = short, 2 = long) */
                    171:         8,                     /* bitsize */
                    172:         TRUE,                  /* pc_relative */
                    173:         0,                     /* bitpos */
                    174:         complain_overflow_bitfield,    /* complain_on_overflow */
                    175:         bfd_elf_generic_reloc, /* special_function */
                    176:         "R_M68HC12_PCREL_8",   /* name */
                    177:         FALSE,                 /* partial_inplace */
                    178:         0x00ff,                /* src_mask */
                    179:         0x00ff,                /* dst_mask */
1.6     ! christos  180:         TRUE),                 /* pcrel_offset */
1.1       christos  181:
                    182:   /* A 16 bit absolute relocation */
                    183:   HOWTO (R_M68HC11_16,         /* type */
                    184:         0,                     /* rightshift */
                    185:         1,                     /* size (0 = byte, 1 = short, 2 = long) */
                    186:         16,                    /* bitsize */
                    187:         FALSE,                 /* pc_relative */
                    188:         0,                     /* bitpos */
                    189:         complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
                    190:         bfd_elf_generic_reloc, /* special_function */
                    191:         "R_M68HC12_16",        /* name */
                    192:         FALSE,                 /* partial_inplace */
                    193:         0xffff,                /* src_mask */
                    194:         0xffff,                /* dst_mask */
                    195:         FALSE),                /* pcrel_offset */
                    196:
                    197:   /* A 32 bit absolute relocation.  This one is never used for the
                    198:      code relocation.  It's used by gas for -gstabs generation.  */
                    199:   HOWTO (R_M68HC11_32,         /* type */
                    200:         0,                     /* rightshift */
                    201:         2,                     /* size (0 = byte, 1 = short, 2 = long) */
                    202:         32,                    /* bitsize */
                    203:         FALSE,                 /* pc_relative */
                    204:         0,                     /* bitpos */
                    205:         complain_overflow_bitfield,    /* complain_on_overflow */
                    206:         bfd_elf_generic_reloc, /* special_function */
                    207:         "R_M68HC12_32",        /* name */
                    208:         FALSE,                 /* partial_inplace */
                    209:         0xffffffff,            /* src_mask */
                    210:         0xffffffff,            /* dst_mask */
                    211:         FALSE),                /* pcrel_offset */
                    212:
                    213:   /* A 3 bit absolute relocation */
                    214:   HOWTO (R_M68HC11_3B,         /* type */
                    215:         0,                     /* rightshift */
                    216:         0,                     /* size (0 = byte, 1 = short, 2 = long) */
                    217:         3,                     /* bitsize */
                    218:         FALSE,                 /* pc_relative */
                    219:         0,                     /* bitpos */
                    220:         complain_overflow_bitfield,    /* complain_on_overflow */
                    221:         bfd_elf_generic_reloc, /* special_function */
                    222:         "R_M68HC12_4B",        /* name */
                    223:         FALSE,                 /* partial_inplace */
                    224:         0x003,                 /* src_mask */
                    225:         0x003,                 /* dst_mask */
                    226:         FALSE),                /* pcrel_offset */
                    227:
                    228:   /* A 16 bit PC-rel relocation */
                    229:   HOWTO (R_M68HC11_PCREL_16,   /* type */
                    230:         0,                     /* rightshift */
                    231:         1,                     /* size (0 = byte, 1 = short, 2 = long) */
                    232:         16,                    /* bitsize */
                    233:         TRUE,                  /* pc_relative */
                    234:         0,                     /* bitpos */
                    235:         complain_overflow_dont,        /* complain_on_overflow */
                    236:         bfd_elf_generic_reloc, /* special_function */
                    237:         "R_M68HC12_PCREL_16",  /* name */
                    238:         FALSE,                 /* partial_inplace */
                    239:         0xffff,                /* src_mask */
                    240:         0xffff,                /* dst_mask */
1.6     ! christos  241:         TRUE),                 /* pcrel_offset */
1.1       christos  242:
                    243:   /* GNU extension to record C++ vtable hierarchy */
                    244:   HOWTO (R_M68HC11_GNU_VTINHERIT,      /* type */
                    245:         0,                     /* rightshift */
                    246:         1,                     /* size (0 = byte, 1 = short, 2 = long) */
                    247:         0,                     /* bitsize */
                    248:         FALSE,                 /* pc_relative */
                    249:         0,                     /* bitpos */
                    250:         complain_overflow_dont,        /* complain_on_overflow */
                    251:         NULL,                  /* special_function */
                    252:         "R_M68HC11_GNU_VTINHERIT",     /* name */
                    253:         FALSE,                 /* partial_inplace */
                    254:         0,                     /* src_mask */
                    255:         0,                     /* dst_mask */
                    256:         FALSE),                /* pcrel_offset */
                    257:
                    258:   /* GNU extension to record C++ vtable member usage */
                    259:   HOWTO (R_M68HC11_GNU_VTENTRY,        /* type */
                    260:         0,                     /* rightshift */
                    261:         1,                     /* size (0 = byte, 1 = short, 2 = long) */
                    262:         0,                     /* bitsize */
                    263:         FALSE,                 /* pc_relative */
                    264:         0,                     /* bitpos */
                    265:         complain_overflow_dont,        /* complain_on_overflow */
                    266:         _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
                    267:         "R_M68HC11_GNU_VTENTRY",       /* name */
                    268:         FALSE,                 /* partial_inplace */
                    269:         0,                     /* src_mask */
                    270:         0,                     /* dst_mask */
                    271:         FALSE),                /* pcrel_offset */
                    272:
                    273:   /* A 24 bit relocation */
1.6     ! christos  274:   HOWTO (R_M68HC11_24,         /* type */
1.1       christos  275:         0,                     /* rightshift */
                    276:         2,                     /* size (0 = byte, 1 = short, 2 = long) */
                    277:         24,                    /* bitsize */
                    278:         FALSE,                 /* pc_relative */
                    279:         0,                     /* bitpos */
                    280:         complain_overflow_dont,        /* complain_on_overflow */
                    281:         m68hc11_elf_special_reloc,     /* special_function */
                    282:         "R_M68HC12_24",        /* name */
                    283:         FALSE,                 /* partial_inplace */
                    284:         0xffffff,              /* src_mask */
                    285:         0xffffff,              /* dst_mask */
                    286:         FALSE),                /* pcrel_offset */
                    287:
                    288:   /* A 16-bit low relocation */
1.6     ! christos  289:   HOWTO (R_M68HC11_LO16,       /* type */
1.1       christos  290:         0,                     /* rightshift */
                    291:         1,                     /* size (0 = byte, 1 = short, 2 = long) */
                    292:         16,                    /* bitsize */
                    293:         FALSE,                 /* pc_relative */
                    294:         0,                     /* bitpos */
                    295:         complain_overflow_dont,        /* complain_on_overflow */
                    296:         m68hc11_elf_special_reloc,/* special_function */
                    297:         "R_M68HC12_LO16",      /* name */
                    298:         FALSE,                 /* partial_inplace */
                    299:         0xffff,                /* src_mask */
                    300:         0xffff,                /* dst_mask */
                    301:         FALSE),                /* pcrel_offset */
                    302:
                    303:   /* A page relocation */
1.6     ! christos  304:   HOWTO (R_M68HC11_PAGE,       /* type */
1.1       christos  305:         0,                     /* rightshift */
                    306:         0,                     /* size (0 = byte, 1 = short, 2 = long) */
                    307:         8,                     /* bitsize */
                    308:         FALSE,                 /* pc_relative */
                    309:         0,                     /* bitpos */
                    310:         complain_overflow_dont,        /* complain_on_overflow */
                    311:         m68hc11_elf_special_reloc,/* special_function */
                    312:         "R_M68HC12_PAGE",      /* name */
                    313:         FALSE,                 /* partial_inplace */
                    314:         0x00ff,                /* src_mask */
                    315:         0x00ff,                /* dst_mask */
                    316:         FALSE),                /* pcrel_offset */
                    317:
                    318:   EMPTY_HOWTO (14),
                    319:
                    320:   /* A 16 bit absolute relocation.  */
                    321:   HOWTO (R_M68HC12_16B,                /* type */
                    322:         0,                     /* rightshift */
                    323:         1,                     /* size (0 = byte, 1 = short, 2 = long) */
                    324:         16,                    /* bitsize */
                    325:         FALSE,                 /* pc_relative */
                    326:         0,                     /* bitpos */
                    327:         complain_overflow_bitfield,    /* complain_on_overflow */
                    328:         bfd_elf_generic_reloc, /* special_function */
                    329:         "R_M68HC12_16B",       /* name */
                    330:         FALSE,                 /* partial_inplace */
1.6     ! christos  331:         0xffff,                /* src_mask */
        !           332:         0xffff,                /* dst_mask */
1.1       christos  333:         FALSE),                /* pcrel_offset */
                    334:
                    335:   /* A 9 bit PC-rel relocation.  */
                    336:   HOWTO (R_M68HC12_PCREL_9,    /* type */
                    337:         1,                     /* rightshift */
                    338:         1,                     /* size (0 = byte, 1 = short, 2 = long) */
                    339:         10,                    /* bitsize (result is >>1) */
                    340:         TRUE,                  /* pc_relative */
                    341:         0,                     /* bitpos */
                    342:         complain_overflow_dont,        /* complain_on_overflow */
                    343:         bfd_elf_generic_reloc, /* special_function */
                    344:         "R_M68HC12_PCREL_9",   /* name */
                    345:         TRUE,                  /* partial_inplace */
                    346:         0xfe00,                /* src_mask */
                    347:         0x01ff,                /* dst_mask */
1.6     ! christos  348:         TRUE),                 /* pcrel_offset */
1.1       christos  349:
                    350:   /* A 10 bit PC-rel relocation.  */
                    351:   HOWTO (R_M68HC12_PCREL_10,   /* type */
                    352:         1,                     /* rightshift */
                    353:         1,                     /* size (0 = byte, 1 = short, 2 = long) */
                    354:         11,                    /* bitsize (result is >>1) */
                    355:         TRUE,                  /* pc_relative */
                    356:         0,                     /* bitpos */
                    357:         complain_overflow_dont,        /* complain_on_overflow */
                    358:         bfd_elf_generic_reloc, /* special_function */
                    359:         "R_M68HC12_PCREL_10",  /* name */
                    360:         TRUE,                  /* partial_inplace */
                    361:         0xfc00,                /* src_mask */
                    362:         0x03ff,                /* dst_mask */
1.6     ! christos  363:         TRUE),                 /* pcrel_offset */
1.1       christos  364:
                    365:   /* A 8 bit absolute relocation (upper address).  */
                    366:   HOWTO (R_M68HC12_HI8XG,              /* type */
                    367:         8,                     /* rightshift */
                    368:         0,                     /* size (0 = byte, 1 = short, 2 = long) */
                    369:         8,                     /* bitsize */
                    370:         FALSE,                 /* pc_relative */
                    371:         0,                     /* bitpos */
                    372:         complain_overflow_bitfield,    /* complain_on_overflow */
                    373:         bfd_elf_generic_reloc, /* special_function */
                    374:         "R_M68HC12_HI8XG",     /* name */
                    375:         FALSE,                 /* partial_inplace */
                    376:         0x00ff,                /* src_mask */
                    377:         0x00ff,                /* dst_mask */
                    378:         FALSE),                /* pcrel_offset */
                    379:
                    380:   /* A 8 bit absolute relocation (lower address).  */
                    381:   HOWTO (R_M68HC12_LO8XG,              /* type */
                    382:         8,                     /* rightshift */
                    383:         0,                     /* size (0 = byte, 1 = short, 2 = long) */
                    384:         8,                     /* bitsize */
                    385:         FALSE,                 /* pc_relative */
                    386:         0,                     /* bitpos */
                    387:         complain_overflow_bitfield,    /* complain_on_overflow */
                    388:         bfd_elf_generic_reloc, /* special_function */
                    389:         "R_M68HC12_LO8XG",     /* name */
                    390:         FALSE,                 /* partial_inplace */
                    391:         0x00ff,                /* src_mask */
                    392:         0x00ff,                /* dst_mask */
                    393:         FALSE),                /* pcrel_offset */
                    394:
                    395:   /* Mark beginning of a jump instruction (any form).  */
                    396:   HOWTO (R_M68HC11_RL_JUMP,    /* type */
                    397:         0,                     /* rightshift */
                    398:         1,                     /* size (0 = byte, 1 = short, 2 = long) */
                    399:         0,                     /* bitsize */
                    400:         FALSE,                 /* pc_relative */
                    401:         0,                     /* bitpos */
                    402:         complain_overflow_dont,        /* complain_on_overflow */
                    403:         m68hc11_elf_ignore_reloc,      /* special_function */
                    404:         "R_M68HC12_RL_JUMP",   /* name */
                    405:         TRUE,                  /* partial_inplace */
                    406:         0,                     /* src_mask */
                    407:         0,                     /* dst_mask */
1.6     ! christos  408:         TRUE),                 /* pcrel_offset */
1.1       christos  409:
                    410:   /* Mark beginning of Gcc relaxation group instruction.  */
                    411:   HOWTO (R_M68HC11_RL_GROUP,   /* type */
                    412:         0,                     /* rightshift */
                    413:         1,                     /* size (0 = byte, 1 = short, 2 = long) */
                    414:         0,                     /* bitsize */
                    415:         FALSE,                 /* pc_relative */
                    416:         0,                     /* bitpos */
                    417:         complain_overflow_dont,        /* complain_on_overflow */
                    418:         m68hc11_elf_ignore_reloc,      /* special_function */
                    419:         "R_M68HC12_RL_GROUP",  /* name */
                    420:         TRUE,                  /* partial_inplace */
                    421:         0,                     /* src_mask */
                    422:         0,                     /* dst_mask */
1.6     ! christos  423:         TRUE),                 /* pcrel_offset */
1.1       christos  424: };
                    425:
                    426: /* Map BFD reloc types to M68HC11 ELF reloc types.  */
                    427:
                    428: struct m68hc11_reloc_map
                    429: {
                    430:   bfd_reloc_code_real_type bfd_reloc_val;
                    431:   unsigned char elf_reloc_val;
                    432: };
                    433:
                    434: static const struct m68hc11_reloc_map m68hc11_reloc_map[] =
                    435: {
                    436:   {BFD_RELOC_NONE, R_M68HC11_NONE,},
                    437:   {BFD_RELOC_8, R_M68HC11_8},
                    438:   {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
                    439:   {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
                    440:   {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
                    441:   {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
                    442:   {BFD_RELOC_16, R_M68HC11_16},
                    443:   {BFD_RELOC_32, R_M68HC11_32},
                    444:   {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
                    445:
                    446:   {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
                    447:   {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
                    448:
                    449:   {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
                    450:   {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
                    451:   {BFD_RELOC_M68HC11_24, R_M68HC11_24},
                    452:
                    453:   {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
                    454:   {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
                    455:
                    456:   {BFD_RELOC_M68HC12_16B, R_M68HC12_16B},
                    457:
                    458:   {BFD_RELOC_M68HC12_9_PCREL, R_M68HC12_PCREL_9},
                    459:   {BFD_RELOC_M68HC12_10_PCREL, R_M68HC12_PCREL_10},
                    460:   {BFD_RELOC_M68HC12_HI8XG, R_M68HC12_HI8XG},
                    461:   {BFD_RELOC_M68HC12_LO8XG, R_M68HC12_LO8XG},
                    462: };
                    463:
                    464: static reloc_howto_type *
                    465: bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1.6     ! christos  466:                                 bfd_reloc_code_real_type code)
1.1       christos  467: {
                    468:   unsigned int i;
                    469:
                    470:   for (i = 0;
                    471:        i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
                    472:        i++)
                    473:     {
                    474:       if (m68hc11_reloc_map[i].bfd_reloc_val == code)
                    475:        return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
                    476:     }
                    477:
                    478:   return NULL;
                    479: }
                    480:
                    481: static reloc_howto_type *
                    482: bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
                    483:                                 const char *r_name)
                    484: {
                    485:   unsigned int i;
                    486:
                    487:   for (i = 0;
                    488:        i < (sizeof (elf_m68hc11_howto_table)
                    489:            / sizeof (elf_m68hc11_howto_table[0]));
                    490:        i++)
                    491:     if (elf_m68hc11_howto_table[i].name != NULL
                    492:        && strcasecmp (elf_m68hc11_howto_table[i].name, r_name) == 0)
                    493:       return &elf_m68hc11_howto_table[i];
                    494:
                    495:   return NULL;
                    496: }
                    497:
                    498: /* Set the howto pointer for an M68HC11 ELF reloc.  */
                    499:
1.6     ! christos  500: static bfd_boolean
        !           501: m68hc11_info_to_howto_rel (bfd *abfd,
        !           502:                           arelent *cache_ptr, Elf_Internal_Rela *dst)
1.1       christos  503: {
                    504:   unsigned int r_type;
                    505:
                    506:   r_type = ELF32_R_TYPE (dst->r_info);
1.3       christos  507:   if (r_type >= (unsigned int) R_M68HC11_max)
                    508:     {
1.6     ! christos  509:       /* xgettext:c-format */
        !           510:       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
        !           511:                          abfd, r_type);
        !           512:       bfd_set_error (bfd_error_bad_value);
        !           513:       return FALSE;
1.3       christos  514:     }
1.1       christos  515:   cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
1.6     ! christos  516:   return TRUE;
1.1       christos  517: }
                    518:
                    519: 
                    520: /* Far trampoline generation.  */
                    521:
                    522: /* Build a 68HC12 trampoline stub.  */
                    523: static bfd_boolean
                    524: m68hc12_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
                    525: {
                    526:   struct elf32_m68hc11_stub_hash_entry *stub_entry;
                    527:   struct bfd_link_info *info;
                    528:   struct m68hc11_elf_link_hash_table *htab;
                    529:   asection *stub_sec;
                    530:   bfd *stub_bfd;
                    531:   bfd_byte *loc;
                    532:   bfd_vma sym_value, phys_page, phys_addr;
                    533:
                    534:   /* Massage our args to the form they really have.  */
                    535:   stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
                    536:   info = (struct bfd_link_info *) in_arg;
                    537:
                    538:   htab = m68hc11_elf_hash_table (info);
                    539:
                    540:   stub_sec = stub_entry->stub_sec;
                    541:
                    542:   /* Make a note of the offset within the stubs for this entry.  */
                    543:   stub_entry->stub_offset = stub_sec->size;
                    544:   stub_sec->size += 7;
                    545:   loc = stub_sec->contents + stub_entry->stub_offset;
                    546:
                    547:   stub_bfd = stub_sec->owner;
                    548:
                    549:   /* Create the trampoline call stub:
                    550:
                    551:      ldy #%addr(symbol)
                    552:      call %page(symbol), __trampoline
                    553:
                    554:   */
                    555:   sym_value = (stub_entry->target_value
1.6     ! christos  556:               + stub_entry->target_section->output_offset
        !           557:               + stub_entry->target_section->output_section->vma);
1.1       christos  558:   phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value);
                    559:   phys_page = m68hc11_phys_page (&htab->pinfo, sym_value);
                    560:
                    561:   /* ldy #%page(sym) */
                    562:   bfd_put_8 (stub_bfd, 0xCD, loc);
                    563:   bfd_put_16 (stub_bfd, phys_addr, loc + 1);
                    564:   loc += 3;
                    565:
                    566:   /* call %page(sym), __trampoline  */
                    567:   bfd_put_8 (stub_bfd, 0x4a, loc);
                    568:   bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1);
                    569:   bfd_put_8 (stub_bfd, phys_page, loc + 3);
                    570:
                    571:   return TRUE;
                    572: }
                    573:
                    574: /* As above, but don't actually build the stub.  Just bump offset so
                    575:    we know stub section sizes.  */
                    576:
                    577: static bfd_boolean
                    578: m68hc12_elf_size_one_stub (struct bfd_hash_entry *gen_entry,
1.6     ! christos  579:                           void *in_arg ATTRIBUTE_UNUSED)
1.1       christos  580: {
                    581:   struct elf32_m68hc11_stub_hash_entry *stub_entry;
                    582:
                    583:   /* Massage our args to the form they really have.  */
                    584:   stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
                    585:
                    586:   stub_entry->stub_sec->size += 7;
                    587:   return TRUE;
                    588: }
                    589:
                    590: /* Create a 68HC12 ELF linker hash table.  */
                    591:
                    592: static struct bfd_link_hash_table *
                    593: m68hc12_elf_bfd_link_hash_table_create (bfd *abfd)
                    594: {
                    595:   struct m68hc11_elf_link_hash_table *ret;
                    596:
                    597:   ret = m68hc11_elf_hash_table_create (abfd);
                    598:   if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
                    599:     return NULL;
                    600:
                    601:   ret->size_one_stub = m68hc12_elf_size_one_stub;
                    602:   ret->build_one_stub = m68hc12_elf_build_one_stub;
                    603:
                    604:   return &ret->root.root;
                    605: }
                    606: 
                    607: static bfd_boolean
                    608: m68hc12_elf_set_mach_from_flags (bfd *abfd)
                    609: {
                    610:   flagword flags = elf_elfheader (abfd)->e_flags;
                    611:
                    612:   switch (flags & EF_M68HC11_MACH_MASK)
                    613:     {
                    614:     case EF_M68HC12_MACH:
                    615:       bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, bfd_mach_m6812);
                    616:       break;
                    617:     case EF_M68HCS12_MACH:
                    618:       bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, bfd_mach_m6812s);
                    619:       break;
                    620:     case EF_M68HC11_GENERIC:
                    621:       bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12,
1.6     ! christos  622:                                 bfd_mach_m6812_default);
1.1       christos  623:       break;
                    624:     default:
                    625:       return FALSE;
                    626:     }
                    627:   return TRUE;
                    628: }
                    629:
                    630: /* Specific sections:
                    631:    - The .page0 is a data section that is mapped in [0x0000..0x00FF].
                    632:      Page0 accesses are faster on the M68HC12.
                    633:    - The .vectors is the section that represents the interrupt
                    634:      vectors.  */
                    635: static const struct bfd_elf_special_section elf32_m68hc12_special_sections[] =
                    636: {
                    637:   { STRING_COMMA_LEN (".eeprom"),   0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
                    638:   { STRING_COMMA_LEN (".page0"),    0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
                    639:   { STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
                    640:   { STRING_COMMA_LEN (".vectors"),  0, SHT_PROGBITS, SHF_ALLOC },
1.6     ! christos  641:   { NULL,                      0,  0, 0,            0 }
1.1       christos  642: };
                    643: 
                    644: #define ELF_ARCH               bfd_arch_m68hc12
                    645: #define ELF_TARGET_ID          M68HC11_ELF_DATA
                    646: #define ELF_MACHINE_CODE       EM_68HC12
                    647: #define ELF_MAXPAGESIZE                0x1000
                    648:
1.6     ! christos  649: #define TARGET_BIG_SYM         m68hc12_elf32_vec
1.1       christos  650: #define TARGET_BIG_NAME                "elf32-m68hc12"
                    651:
1.6     ! christos  652: #define elf_info_to_howto      NULL
1.1       christos  653: #define elf_info_to_howto_rel  m68hc11_info_to_howto_rel
                    654: #define elf_backend_check_relocs     elf32_m68hc11_check_relocs
                    655: #define elf_backend_relocate_section elf32_m68hc11_relocate_section
                    656: #define elf_backend_object_p           m68hc12_elf_set_mach_from_flags
                    657: #define elf_backend_final_write_processing     0
                    658: #define elf_backend_can_gc_sections            1
                    659: #define elf_backend_special_sections elf32_m68hc12_special_sections
                    660: #define elf_backend_post_process_headers     elf32_m68hc11_post_process_headers
                    661: #define elf_backend_add_symbol_hook  elf32_m68hc11_add_symbol_hook
                    662: #define elf_backend_merge_symbol_attribute elf32_m68hc11_merge_symbol_attribute
                    663:
                    664: #define bfd_elf32_bfd_link_hash_table_create \
1.6     ! christos  665:                                m68hc12_elf_bfd_link_hash_table_create
1.1       christos  666: #define bfd_elf32_bfd_merge_private_bfd_data \
                    667:                                        _bfd_m68hc11_elf_merge_private_bfd_data
                    668: #define bfd_elf32_bfd_set_private_flags        _bfd_m68hc11_elf_set_private_flags
                    669: #define bfd_elf32_bfd_print_private_bfd_data \
                    670:                                        _bfd_m68hc11_elf_print_private_bfd_data
                    671:
                    672: #include "elf32-target.h"

CVSweb <webmaster@jp.NetBSD.org>