]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elf32-m68hc11.c
* elf32-m68hc11.c (elf_m68hc11_howto_table): Add the new relocs;
[thirdparty/binutils-gdb.git] / bfd / elf32-m68hc11.c
CommitLineData
60bcf0fa 1/* Motorola 68HC11-specific support for 32-bit ELF
dae78fb0
SC
2 Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Contributed by Stephane Carrez (stcarrez@nerim.fr)
60bcf0fa
NC
4 (Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22#include "bfd.h"
23#include "sysdep.h"
24#include "libbfd.h"
25#include "elf-bfd.h"
26#include "elf/m68hc11.h"
27
28static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
29PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
30static void m68hc11_info_to_howto_rel
31PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
32
dae78fb0
SC
33static bfd_reloc_status_type m68hc11_elf_ignore_reloc
34PARAMS ((bfd *abfd, arelent *reloc_entry,
35 asymbol *symbol, PTR data, asection *input_section,
36 bfd *output_bfd, char **error_message));
37
60bcf0fa
NC
38/* Use REL instead of RELA to save space */
39#define USE_REL
40
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
44 is wrong).
45 The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
46static reloc_howto_type elf_m68hc11_howto_table[] = {
47 /* This reloc does nothing. */
48 HOWTO (R_M68HC11_NONE, /* type */
49 0, /* rightshift */
50 2, /* size (0 = byte, 1 = short, 2 = long) */
51 32, /* bitsize */
52 false, /* pc_relative */
53 0, /* bitpos */
54 complain_overflow_bitfield, /* complain_on_overflow */
55 bfd_elf_generic_reloc, /* special_function */
56 "R_M68HC11_NONE", /* name */
57 false, /* partial_inplace */
58 0, /* src_mask */
59 0, /* dst_mask */
60 false), /* pcrel_offset */
61
62 /* A 8 bit absolute relocation */
63 HOWTO (R_M68HC11_8, /* type */
64 0, /* rightshift */
65 0, /* size (0 = byte, 1 = short, 2 = long) */
66 8, /* bitsize */
67 false, /* pc_relative */
68 0, /* bitpos */
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 */
76
77 /* A 8 bit absolute relocation (upper address) */
78 HOWTO (R_M68HC11_HI8, /* type */
79 8, /* rightshift */
80 0, /* size (0 = byte, 1 = short, 2 = long) */
81 8, /* bitsize */
82 false, /* pc_relative */
83 0, /* bitpos */
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 */
91
92 /* A 8 bit absolute relocation (upper address) */
93 HOWTO (R_M68HC11_LO8, /* type */
94 0, /* rightshift */
95 0, /* size (0 = byte, 1 = short, 2 = long) */
96 8, /* bitsize */
97 false, /* pc_relative */
98 0, /* bitpos */
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 */
106
107 /* A 8 bit PC-rel relocation */
108 HOWTO (R_M68HC11_PCREL_8, /* type */
109 0, /* rightshift */
110 0, /* size (0 = byte, 1 = short, 2 = long) */
111 8, /* bitsize */
112 true, /* pc_relative */
113 0, /* bitpos */
114 complain_overflow_bitfield, /* complain_on_overflow */
115 bfd_elf_generic_reloc, /* special_function */
116 "R_M68HC11_PCREL_8", /* name */
117 false, /* partial_inplace */
dae78fb0 118 0x00ff, /* src_mask */
60bcf0fa
NC
119 0x00ff, /* dst_mask */
120 false), /* pcrel_offset */
121
122 /* A 16 bit absolute relocation */
123 HOWTO (R_M68HC11_16, /* type */
124 0, /* rightshift */
125 1, /* size (0 = byte, 1 = short, 2 = long) */
126 16, /* bitsize */
127 false, /* pc_relative */
128 0, /* bitpos */
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 */
136
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 */
140 0, /* rightshift */
141 2, /* size (0 = byte, 1 = short, 2 = long) */
142 32, /* bitsize */
143 false, /* pc_relative */
144 0, /* bitpos */
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 */
152
153 /* A 3 bit absolute relocation */
154 HOWTO (R_M68HC11_3B, /* type */
155 0, /* rightshift */
156 0, /* size (0 = byte, 1 = short, 2 = long) */
157 3, /* bitsize */
158 false, /* pc_relative */
159 0, /* bitpos */
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 */
167
168 /* A 16 bit PC-rel relocation */
169 HOWTO (R_M68HC11_PCREL_16, /* type */
170 0, /* rightshift */
171 1, /* size (0 = byte, 1 = short, 2 = long) */
172 16, /* bitsize */
173 true, /* pc_relative */
174 0, /* bitpos */
175 complain_overflow_dont, /* complain_on_overflow */
176 bfd_elf_generic_reloc, /* special_function */
177 "R_M68HC11_PCREL_16", /* name */
178 false, /* partial_inplace */
dae78fb0 179 0xffff, /* src_mask */
60bcf0fa
NC
180 0xffff, /* dst_mask */
181 false), /* pcrel_offset */
182
183 /* GNU extension to record C++ vtable hierarchy */
184 HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */
185 0, /* rightshift */
186 1, /* size (0 = byte, 1 = short, 2 = long) */
187 0, /* bitsize */
188 false, /* pc_relative */
189 0, /* bitpos */
190 complain_overflow_dont, /* complain_on_overflow */
191 NULL, /* special_function */
192 "R_M68HC11_GNU_VTINHERIT", /* name */
193 false, /* partial_inplace */
194 0, /* src_mask */
195 0, /* dst_mask */
196 false), /* pcrel_offset */
197
198 /* GNU extension to record C++ vtable member usage */
199 HOWTO (R_M68HC11_GNU_VTENTRY, /* type */
200 0, /* rightshift */
201 1, /* size (0 = byte, 1 = short, 2 = long) */
202 0, /* bitsize */
203 false, /* pc_relative */
204 0, /* bitpos */
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 */
209 0, /* src_mask */
210 0, /* dst_mask */
211 false), /* pcrel_offset */
dae78fb0
SC
212
213 EMPTY_HOWTO (11),
214 EMPTY_HOWTO (12),
215 EMPTY_HOWTO (13),
216 EMPTY_HOWTO (14),
217 EMPTY_HOWTO (15),
218 EMPTY_HOWTO (16),
219 EMPTY_HOWTO (17),
220 EMPTY_HOWTO (18),
221 EMPTY_HOWTO (19),
222
223 /* Mark beginning of a jump instruction (any form). */
224 HOWTO (R_M68HC11_RL_JUMP, /* type */
225 0, /* rightshift */
226 1, /* size (0 = byte, 1 = short, 2 = long) */
227 0, /* bitsize */
228 false, /* pc_relative */
229 0, /* bitpos */
230 complain_overflow_dont, /* complain_on_overflow */
231 m68hc11_elf_ignore_reloc, /* special_function */
232 "R_M68HC11_RL_JUMP", /* name */
233 true, /* partial_inplace */
234 0, /* src_mask */
235 0, /* dst_mask */
236 true), /* pcrel_offset */
237
238 /* Mark beginning of Gcc relaxation group instruction. */
239 HOWTO (R_M68HC11_RL_GROUP, /* type */
240 0, /* rightshift */
241 1, /* size (0 = byte, 1 = short, 2 = long) */
242 0, /* bitsize */
243 false, /* pc_relative */
244 0, /* bitpos */
245 complain_overflow_dont, /* complain_on_overflow */
246 m68hc11_elf_ignore_reloc, /* special_function */
247 "R_M68HC11_RL_GROUP", /* name */
248 true, /* partial_inplace */
249 0, /* src_mask */
250 0, /* dst_mask */
251 true), /* pcrel_offset */
60bcf0fa
NC
252};
253
254/* Map BFD reloc types to M68HC11 ELF reloc types. */
255
256struct m68hc11_reloc_map
257{
258 bfd_reloc_code_real_type bfd_reloc_val;
259 unsigned char elf_reloc_val;
260};
261
262static 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},
272
60bcf0fa
NC
273 {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
274 {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
dae78fb0
SC
275
276 {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
277 {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
60bcf0fa
NC
278};
279
280static reloc_howto_type *
281bfd_elf32_bfd_reloc_type_lookup (abfd, code)
282 bfd *abfd ATTRIBUTE_UNUSED;
283 bfd_reloc_code_real_type code;
284{
285 unsigned int i;
286
287 for (i = 0;
288 i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
289 i++)
290 {
291 if (m68hc11_reloc_map[i].bfd_reloc_val == code)
292 return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
293 }
294
295 return NULL;
296}
297
dae78fb0
SC
298/* This function is used for relocs which are only used for relaxing,
299 which the linker should otherwise ignore. */
300
301static bfd_reloc_status_type
302m68hc11_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;
309 bfd *output_bfd;
310 char **error_message ATTRIBUTE_UNUSED;
311{
312 if (output_bfd != NULL)
313 reloc_entry->address += input_section->output_offset;
314 return bfd_reloc_ok;
315}
316
60bcf0fa
NC
317/* Set the howto pointer for an M68HC11 ELF reloc. */
318
319static void
320m68hc11_info_to_howto_rel (abfd, cache_ptr, dst)
321 bfd *abfd ATTRIBUTE_UNUSED;
322 arelent *cache_ptr;
323 Elf32_Internal_Rel *dst;
324{
325 unsigned int r_type;
326
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];
330}
331
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
337
338#define TARGET_BIG_SYM bfd_elf32_m68hc11_vec
339#define TARGET_BIG_NAME "elf32-m68hc11"
340
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
345
346#include "elf32-target.h"