1 /* Motorola 68HC11-specific support for 32-bit ELF
2 Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Contributed by Stephane Carrez (stcarrez@nerim.fr)
4 (Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
6 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
26 #include "elf/m68hc11.h"
28 static reloc_howto_type
*bfd_elf32_bfd_reloc_type_lookup
29 PARAMS ((bfd
* abfd
, bfd_reloc_code_real_type code
));
30 static void m68hc11_info_to_howto_rel
31 PARAMS ((bfd
*, arelent
*, Elf32_Internal_Rel
*));
33 static bfd_reloc_status_type m68hc11_elf_ignore_reloc
34 PARAMS ((bfd
*abfd
, arelent
*reloc_entry
,
35 asymbol
*symbol
, PTR data
, asection
*input_section
,
36 bfd
*output_bfd
, char **error_message
));
38 /* Use REL instead of RELA to save space */
41 /* The Motorola 68HC11 microcontroler only addresses 64Kb.
42 We must handle 8 and 16-bit relocations. The 32-bit relocation
43 is defined but not used except by gas when -gstabs is used (which
45 The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
46 static reloc_howto_type elf_m68hc11_howto_table
[] = {
47 /* This reloc does nothing. */
48 HOWTO (R_M68HC11_NONE
, /* type */
50 2, /* size (0 = byte, 1 = short, 2 = long) */
52 false, /* pc_relative */
54 complain_overflow_bitfield
, /* complain_on_overflow */
55 bfd_elf_generic_reloc
, /* special_function */
56 "R_M68HC11_NONE", /* name */
57 false, /* partial_inplace */
60 false), /* pcrel_offset */
62 /* A 8 bit absolute relocation */
63 HOWTO (R_M68HC11_8
, /* type */
65 0, /* size (0 = byte, 1 = short, 2 = long) */
67 false, /* pc_relative */
69 complain_overflow_bitfield
, /* complain_on_overflow */
70 bfd_elf_generic_reloc
, /* special_function */
71 "R_M68HC11_8", /* name */
72 false, /* partial_inplace */
73 0x00ff, /* src_mask */
74 0x00ff, /* dst_mask */
75 false), /* pcrel_offset */
77 /* A 8 bit absolute relocation (upper address) */
78 HOWTO (R_M68HC11_HI8
, /* type */
80 0, /* size (0 = byte, 1 = short, 2 = long) */
82 false, /* pc_relative */
84 complain_overflow_bitfield
, /* complain_on_overflow */
85 bfd_elf_generic_reloc
, /* special_function */
86 "R_M68HC11_HI8", /* name */
87 false, /* partial_inplace */
88 0x00ff, /* src_mask */
89 0x00ff, /* dst_mask */
90 false), /* pcrel_offset */
92 /* A 8 bit absolute relocation (upper address) */
93 HOWTO (R_M68HC11_LO8
, /* type */
95 0, /* size (0 = byte, 1 = short, 2 = long) */
97 false, /* pc_relative */
99 complain_overflow_dont
, /* complain_on_overflow */
100 bfd_elf_generic_reloc
, /* special_function */
101 "R_M68HC11_LO8", /* name */
102 false, /* partial_inplace */
103 0x00ff, /* src_mask */
104 0x00ff, /* dst_mask */
105 false), /* pcrel_offset */
107 /* A 8 bit PC-rel relocation */
108 HOWTO (R_M68HC11_PCREL_8
, /* type */
110 0, /* size (0 = byte, 1 = short, 2 = long) */
112 true, /* pc_relative */
114 complain_overflow_bitfield
, /* complain_on_overflow */
115 bfd_elf_generic_reloc
, /* special_function */
116 "R_M68HC11_PCREL_8", /* name */
117 false, /* partial_inplace */
118 0x00ff, /* src_mask */
119 0x00ff, /* dst_mask */
120 false), /* pcrel_offset */
122 /* A 16 bit absolute relocation */
123 HOWTO (R_M68HC11_16
, /* type */
125 1, /* size (0 = byte, 1 = short, 2 = long) */
127 false, /* pc_relative */
129 complain_overflow_dont
/*bitfield */ , /* complain_on_overflow */
130 bfd_elf_generic_reloc
, /* special_function */
131 "R_M68HC11_16", /* name */
132 false, /* partial_inplace */
133 0xffff, /* src_mask */
134 0xffff, /* dst_mask */
135 false), /* pcrel_offset */
137 /* A 32 bit absolute relocation. This one is never used for the
138 code relocation. It's used by gas for -gstabs generation. */
139 HOWTO (R_M68HC11_32
, /* type */
141 2, /* size (0 = byte, 1 = short, 2 = long) */
143 false, /* pc_relative */
145 complain_overflow_bitfield
, /* complain_on_overflow */
146 bfd_elf_generic_reloc
, /* special_function */
147 "R_M68HC11_32", /* name */
148 false, /* partial_inplace */
149 0xffffffff, /* src_mask */
150 0xffffffff, /* dst_mask */
151 false), /* pcrel_offset */
153 /* A 3 bit absolute relocation */
154 HOWTO (R_M68HC11_3B
, /* type */
156 0, /* size (0 = byte, 1 = short, 2 = long) */
158 false, /* pc_relative */
160 complain_overflow_bitfield
, /* complain_on_overflow */
161 bfd_elf_generic_reloc
, /* special_function */
162 "R_M68HC11_4B", /* name */
163 false, /* partial_inplace */
164 0x003, /* src_mask */
165 0x003, /* dst_mask */
166 false), /* pcrel_offset */
168 /* A 16 bit PC-rel relocation */
169 HOWTO (R_M68HC11_PCREL_16
, /* type */
171 1, /* size (0 = byte, 1 = short, 2 = long) */
173 true, /* pc_relative */
175 complain_overflow_dont
, /* complain_on_overflow */
176 bfd_elf_generic_reloc
, /* special_function */
177 "R_M68HC11_PCREL_16", /* name */
178 false, /* partial_inplace */
179 0xffff, /* src_mask */
180 0xffff, /* dst_mask */
181 false), /* pcrel_offset */
183 /* GNU extension to record C++ vtable hierarchy */
184 HOWTO (R_M68HC11_GNU_VTINHERIT
, /* type */
186 1, /* size (0 = byte, 1 = short, 2 = long) */
188 false, /* pc_relative */
190 complain_overflow_dont
, /* complain_on_overflow */
191 NULL
, /* special_function */
192 "R_M68HC11_GNU_VTINHERIT", /* name */
193 false, /* partial_inplace */
196 false), /* pcrel_offset */
198 /* GNU extension to record C++ vtable member usage */
199 HOWTO (R_M68HC11_GNU_VTENTRY
, /* type */
201 1, /* size (0 = byte, 1 = short, 2 = long) */
203 false, /* pc_relative */
205 complain_overflow_dont
, /* complain_on_overflow */
206 _bfd_elf_rel_vtable_reloc_fn
, /* special_function */
207 "R_M68HC11_GNU_VTENTRY", /* name */
208 false, /* partial_inplace */
211 false), /* pcrel_offset */
223 /* Mark beginning of a jump instruction (any form). */
224 HOWTO (R_M68HC11_RL_JUMP
, /* type */
226 1, /* size (0 = byte, 1 = short, 2 = long) */
228 false, /* pc_relative */
230 complain_overflow_dont
, /* complain_on_overflow */
231 m68hc11_elf_ignore_reloc
, /* special_function */
232 "R_M68HC11_RL_JUMP", /* name */
233 true, /* partial_inplace */
236 true), /* pcrel_offset */
238 /* Mark beginning of Gcc relaxation group instruction. */
239 HOWTO (R_M68HC11_RL_GROUP
, /* type */
241 1, /* size (0 = byte, 1 = short, 2 = long) */
243 false, /* pc_relative */
245 complain_overflow_dont
, /* complain_on_overflow */
246 m68hc11_elf_ignore_reloc
, /* special_function */
247 "R_M68HC11_RL_GROUP", /* name */
248 true, /* partial_inplace */
251 true), /* pcrel_offset */
254 /* Map BFD reloc types to M68HC11 ELF reloc types. */
256 struct m68hc11_reloc_map
258 bfd_reloc_code_real_type bfd_reloc_val
;
259 unsigned char elf_reloc_val
;
262 static const struct m68hc11_reloc_map m68hc11_reloc_map
[] = {
263 {BFD_RELOC_NONE
, R_M68HC11_NONE
,},
264 {BFD_RELOC_8
, R_M68HC11_8
},
265 {BFD_RELOC_M68HC11_HI8
, R_M68HC11_HI8
},
266 {BFD_RELOC_M68HC11_LO8
, R_M68HC11_LO8
},
267 {BFD_RELOC_8_PCREL
, R_M68HC11_PCREL_8
},
268 {BFD_RELOC_16_PCREL
, R_M68HC11_PCREL_16
},
269 {BFD_RELOC_16
, R_M68HC11_16
},
270 {BFD_RELOC_32
, R_M68HC11_32
},
271 {BFD_RELOC_M68HC11_3B
, R_M68HC11_3B
},
273 {BFD_RELOC_VTABLE_INHERIT
, R_M68HC11_GNU_VTINHERIT
},
274 {BFD_RELOC_VTABLE_ENTRY
, R_M68HC11_GNU_VTENTRY
},
276 {BFD_RELOC_M68HC11_RL_JUMP
, R_M68HC11_RL_JUMP
},
277 {BFD_RELOC_M68HC11_RL_GROUP
, R_M68HC11_RL_GROUP
},
280 static reloc_howto_type
*
281 bfd_elf32_bfd_reloc_type_lookup (abfd
, code
)
282 bfd
*abfd ATTRIBUTE_UNUSED
;
283 bfd_reloc_code_real_type code
;
288 i
< sizeof (m68hc11_reloc_map
) / sizeof (struct m68hc11_reloc_map
);
291 if (m68hc11_reloc_map
[i
].bfd_reloc_val
== code
)
292 return &elf_m68hc11_howto_table
[m68hc11_reloc_map
[i
].elf_reloc_val
];
298 /* This function is used for relocs which are only used for relaxing,
299 which the linker should otherwise ignore. */
301 static bfd_reloc_status_type
302 m68hc11_elf_ignore_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
303 output_bfd
, error_message
)
304 bfd
*abfd ATTRIBUTE_UNUSED
;
305 arelent
*reloc_entry
;
306 asymbol
*symbol ATTRIBUTE_UNUSED
;
307 PTR data ATTRIBUTE_UNUSED
;
308 asection
*input_section
;
310 char **error_message ATTRIBUTE_UNUSED
;
312 if (output_bfd
!= NULL
)
313 reloc_entry
->address
+= input_section
->output_offset
;
317 /* Set the howto pointer for an M68HC11 ELF reloc. */
320 m68hc11_info_to_howto_rel (abfd
, cache_ptr
, dst
)
321 bfd
*abfd ATTRIBUTE_UNUSED
;
323 Elf32_Internal_Rel
*dst
;
327 r_type
= ELF32_R_TYPE (dst
->r_info
);
328 BFD_ASSERT (r_type
< (unsigned int) R_M68HC11_max
);
329 cache_ptr
->howto
= &elf_m68hc11_howto_table
[r_type
];
332 /* Below is the only difference between elf32-m68hc12.c and elf32-m68hc11.c.
333 The Motorola spec says to use a different Elf machine code. */
334 #define ELF_ARCH bfd_arch_m68hc11
335 #define ELF_MACHINE_CODE EM_68HC11
336 #define ELF_MAXPAGESIZE 0x1000
338 #define TARGET_BIG_SYM bfd_elf32_m68hc11_vec
339 #define TARGET_BIG_NAME "elf32-m68hc11"
341 #define elf_info_to_howto 0
342 #define elf_info_to_howto_rel m68hc11_info_to_howto_rel
343 #define elf_backend_object_p 0
344 #define elf_backend_final_write_processing 0
346 #include "elf32-target.h"