| 1 | /* Motorola 68HC12-specific support for 32-bit ELF
|
|---|
| 2 | Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
|
|---|
| 3 | Contributed by Stephane Carrez ([email protected])
|
|---|
| 4 | (Heavily copied from the D10V port by Martin Hunt ([email protected]))
|
|---|
| 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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|---|
| 21 |
|
|---|
| 22 | #include "bfd.h"
|
|---|
| 23 | #include "sysdep.h"
|
|---|
| 24 | #include "bfdlink.h"
|
|---|
| 25 | #include "libbfd.h"
|
|---|
| 26 | #include "elf-bfd.h"
|
|---|
| 27 | #include "elf32-m68hc1x.h"
|
|---|
| 28 | #include "elf/m68hc11.h"
|
|---|
| 29 | #include "opcode/m68hc11.h"
|
|---|
| 30 |
|
|---|
| 31 | /* Relocation functions. */
|
|---|
| 32 | static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
|
|---|
| 33 | PARAMS ((bfd *, bfd_reloc_code_real_type));
|
|---|
| 34 | static void m68hc11_info_to_howto_rel
|
|---|
| 35 | PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
|
|---|
| 36 |
|
|---|
| 37 | /* Trampoline generation. */
|
|---|
| 38 | static bfd_boolean m68hc12_elf_size_one_stub
|
|---|
| 39 | PARAMS((struct bfd_hash_entry *gen_entry, PTR in_arg));
|
|---|
| 40 | static bfd_boolean m68hc12_elf_build_one_stub
|
|---|
| 41 | PARAMS((struct bfd_hash_entry *gen_entry, PTR in_arg));
|
|---|
| 42 | static struct bfd_link_hash_table* m68hc12_elf_bfd_link_hash_table_create
|
|---|
| 43 | PARAMS((bfd*));
|
|---|
| 44 |
|
|---|
| 45 | static bfd_boolean m68hc12_elf_set_mach_from_flags PARAMS ((bfd *));
|
|---|
| 46 |
|
|---|
| 47 | /* Use REL instead of RELA to save space */
|
|---|
| 48 | #define USE_REL 1
|
|---|
| 49 |
|
|---|
| 50 | /* The 68HC12 microcontroler has a memory bank switching system
|
|---|
| 51 | with a 16Kb window in the 64Kb address space. The extended memory
|
|---|
| 52 | is mapped in the 16Kb window (at 0x8000). The page register controls
|
|---|
| 53 | which 16Kb bank is mapped. The call/rtc instructions take care of
|
|---|
| 54 | bank switching in function calls/returns.
|
|---|
| 55 |
|
|---|
| 56 | For GNU Binutils to work, we consider there is a physical memory
|
|---|
| 57 | at 0..0x0ffff and a kind of virtual memory above that. Symbols
|
|---|
| 58 | in virtual memory have their addresses treated in a special way
|
|---|
| 59 | when disassembling and when linking.
|
|---|
| 60 |
|
|---|
| 61 | For the linker to work properly, we must always relocate the virtual
|
|---|
| 62 | memory as if it is mapped at 0x8000. When a 16-bit relocation is
|
|---|
| 63 | made in the virtual memory, we check that it does not cross the
|
|---|
| 64 | memory bank where it is used. This would involve a page change
|
|---|
| 65 | which would be wrong. The 24-bit relocation is for that and it
|
|---|
| 66 | treats the address as a physical address + page number.
|
|---|
| 67 |
|
|---|
| 68 |
|
|---|
| 69 | Banked
|
|---|
| 70 | Address Space
|
|---|
| 71 | | | Page n
|
|---|
| 72 | +---------------+ 0x1010000
|
|---|
| 73 | | |
|
|---|
| 74 | | jsr _foo |
|
|---|
| 75 | | .. | Page 3
|
|---|
| 76 | | _foo: |
|
|---|
| 77 | +---------------+ 0x100C000
|
|---|
| 78 | | |
|
|---|
| 79 | | call _bar |
|
|---|
| 80 | | .. | Page 2
|
|---|
| 81 | | _bar: |
|
|---|
| 82 | +---------------+ 0x1008000
|
|---|
| 83 | /------>| |
|
|---|
| 84 | | | call _foo | Page 1
|
|---|
| 85 | | | |
|
|---|
| 86 | | +---------------+ 0x1004000
|
|---|
| 87 | Physical | | |
|
|---|
| 88 | Address Space | | | Page 0
|
|---|
| 89 | | | |
|
|---|
| 90 | +-----------+ 0x00FFFF | +---------------+ 0x1000000
|
|---|
| 91 | | | |
|
|---|
| 92 | | call _foo | |
|
|---|
| 93 | | | |
|
|---|
| 94 | +-----------+ 0x00BFFF -+---/
|
|---|
| 95 | | | |
|
|---|
| 96 | | | |
|
|---|
| 97 | | | 16K |
|
|---|
| 98 | | | |
|
|---|
| 99 | +-----------+ 0x008000 -+
|
|---|
| 100 | | |
|
|---|
| 101 | | |
|
|---|
| 102 | = =
|
|---|
| 103 | | |
|
|---|
| 104 | | |
|
|---|
| 105 | +-----------+ 0000
|
|---|
| 106 |
|
|---|
| 107 |
|
|---|
| 108 | The 'call _foo' must be relocated with page 3 and 16-bit address
|
|---|
| 109 | mapped at 0x8000.
|
|---|
| 110 |
|
|---|
| 111 | The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
|
|---|
| 112 | static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|---|
| 113 | /* This reloc does nothing. */
|
|---|
| 114 | HOWTO (R_M68HC11_NONE, /* type */
|
|---|
| 115 | 0, /* rightshift */
|
|---|
| 116 | 2, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 117 | 32, /* bitsize */
|
|---|
| 118 | FALSE, /* pc_relative */
|
|---|
| 119 | 0, /* bitpos */
|
|---|
| 120 | complain_overflow_dont,/* complain_on_overflow */
|
|---|
| 121 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 122 | "R_M68HC12_NONE", /* name */
|
|---|
| 123 | FALSE, /* partial_inplace */
|
|---|
| 124 | 0, /* src_mask */
|
|---|
| 125 | 0, /* dst_mask */
|
|---|
| 126 | FALSE), /* pcrel_offset */
|
|---|
| 127 |
|
|---|
| 128 | /* A 8 bit absolute relocation */
|
|---|
| 129 | HOWTO (R_M68HC11_8, /* type */
|
|---|
| 130 | 0, /* rightshift */
|
|---|
| 131 | 0, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 132 | 8, /* bitsize */
|
|---|
| 133 | FALSE, /* pc_relative */
|
|---|
| 134 | 0, /* bitpos */
|
|---|
| 135 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 136 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 137 | "R_M68HC12_8", /* name */
|
|---|
| 138 | FALSE, /* partial_inplace */
|
|---|
| 139 | 0x00ff, /* src_mask */
|
|---|
| 140 | 0x00ff, /* dst_mask */
|
|---|
| 141 | FALSE), /* pcrel_offset */
|
|---|
| 142 |
|
|---|
| 143 | /* A 8 bit absolute relocation (upper address) */
|
|---|
| 144 | HOWTO (R_M68HC11_HI8, /* type */
|
|---|
| 145 | 8, /* rightshift */
|
|---|
| 146 | 0, /* size (0 = byte, 1 = short, 2 = long) */
|
|---|
| 147 | 8, /* bitsize */
|
|---|
| 148 | FALSE, /* pc_relative */
|
|---|
| 149 | 0, /* bitpos */
|
|---|
| 150 | complain_overflow_bitfield, /* complain_on_overflow */
|
|---|
| 151 | bfd_elf_generic_reloc, /* special_function */
|
|---|
| 152 | "R_M68HC12_HI8", /* name */
|
|---|
|
|---|