Fix integration pb for:
[deliverable/binutils-gdb.git] / bfd / elf32-m68hc11.c
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))
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 "libbfd.h"
25 #include "elf-bfd.h"
26 #include "elf/m68hc11.h"
27
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 *));
32
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));
37
38 boolean _bfd_m68hc11_elf_merge_private_bfd_data PARAMS ((bfd*, bfd*));
39 boolean _bfd_m68hc11_elf_set_private_flags PARAMS ((bfd*, flagword));
40 boolean _bfd_m68hc11_elf_print_private_bfd_data PARAMS ((bfd*, PTR));
41
42 /* Use REL instead of RELA to save space */
43 #define USE_REL
44
45 /* The Motorola 68HC11 microcontroler only addresses 64Kb.
46 We must handle 8 and 16-bit relocations. The 32-bit relocation
47 is defined but not used except by gas when -gstabs is used (which
48 is wrong).
49 The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
50 static reloc_howto_type elf_m68hc11_howto_table[] = {
51 /* This reloc does nothing. */
52 HOWTO (R_M68HC11_NONE, /* type */
53 0, /* rightshift */
54 2, /* size (0 = byte, 1 = short, 2 = long) */
55 32, /* bitsize */
56 false, /* pc_relative */
57 0, /* bitpos */
58 complain_overflow_dont,/* complain_on_overflow */
59 bfd_elf_generic_reloc, /* special_function */
60 "R_M68HC11_NONE", /* name */
61 false, /* partial_inplace */
62 0, /* src_mask */
63 0, /* dst_mask */
64 false), /* pcrel_offset */
65
66 /* A 8 bit absolute relocation */
67 HOWTO (R_M68HC11_8, /* type */
68 0, /* rightshift */
69 0, /* size (0 = byte, 1 = short, 2 = long) */
70 8, /* bitsize */
71 false, /* pc_relative */
72 0, /* bitpos */
73 complain_overflow_bitfield, /* complain_on_overflow */
74 bfd_elf_generic_reloc, /* special_function */
75 "R_M68HC11_8", /* name */
76 false, /* partial_inplace */
77 0x00ff, /* src_mask */
78 0x00ff, /* dst_mask */
79 false), /* pcrel_offset */
80
81 /* A 8 bit absolute relocation (upper address) */
82 HOWTO (R_M68HC11_HI8, /* type */
83 8, /* rightshift */
84 0, /* size (0 = byte, 1 = short, 2 = long) */
85 8, /* bitsize */
86 false, /* pc_relative */
87 0, /* bitpos */
88 complain_overflow_bitfield, /* complain_on_overflow */
89 bfd_elf_generic_reloc, /* special_function */
90 "R_M68HC11_HI8", /* name */
91 false, /* partial_inplace */
92 0x00ff, /* src_mask */
93 0x00ff, /* dst_mask */
94 false), /* pcrel_offset */
95
96 /* A 8 bit absolute relocation (upper address) */
97 HOWTO (R_M68HC11_LO8, /* type */
98 0, /* rightshift */
99 0, /* size (0 = byte, 1 = short, 2 = long) */
100 8, /* bitsize */
101 false, /* pc_relative */
102 0, /* bitpos */
103 complain_overflow_dont, /* complain_on_overflow */
104 bfd_elf_generic_reloc, /* special_function */
105 "R_M68HC11_LO8", /* name */
106 false, /* partial_inplace */
107 0x00ff, /* src_mask */
108 0x00ff, /* dst_mask */
109 false), /* pcrel_offset */
110
111 /* A 8 bit PC-rel relocation */
112 HOWTO (R_M68HC11_PCREL_8, /* type */
113 0, /* rightshift */
114 0, /* size (0 = byte, 1 = short, 2 = long) */
115 8, /* bitsize */
116 true, /* pc_relative */
117 0, /* bitpos */
118 complain_overflow_bitfield, /* complain_on_overflow */
119 bfd_elf_generic_reloc, /* special_function */
120 "R_M68HC11_PCREL_8", /* name */
121 false, /* partial_inplace */
122 0x00ff, /* src_mask */
123 0x00ff, /* dst_mask */
124 false), /* pcrel_offset */
125
126 /* A 16 bit absolute relocation */
127 HOWTO (R_M68HC11_16, /* type */
128 0, /* rightshift */
129 1, /* size (0 = byte, 1 = short, 2 = long) */
130 16, /* bitsize */
131 false, /* pc_relative */
132 0, /* bitpos */
133 complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
134 bfd_elf_generic_reloc, /* special_function */
135 "R_M68HC11_16", /* name */
136 false, /* partial_inplace */
137 0xffff, /* src_mask */
138 0xffff, /* dst_mask */
139 false), /* pcrel_offset */
140
141 /* A 32 bit absolute relocation. This one is never used for the
142 code relocation. It's used by gas for -gstabs generation. */
143 HOWTO (R_M68HC11_32, /* type */
144 0, /* rightshift */
145 2, /* size (0 = byte, 1 = short, 2 = long) */
146 32, /* bitsize */
147 false, /* pc_relative */
148 0, /* bitpos */
149 complain_overflow_bitfield, /* complain_on_overflow */
150 bfd_elf_generic_reloc, /* special_function */
151 "R_M68HC11_32", /* name */
152 false, /* partial_inplace */
153 0xffffffff, /* src_mask */
154 0xffffffff, /* dst_mask */
155 false), /* pcrel_offset */
156
157 /* A 3 bit absolute relocation */
158 HOWTO (R_M68HC11_3B, /* type */
159 0, /* rightshift */
160 0, /* size (0 = byte, 1 = short, 2 = long) */
161 3, /* bitsize */
162 false, /* pc_relative */
163 0, /* bitpos */
164 complain_overflow_bitfield, /* complain_on_overflow */
165 bfd_elf_generic_reloc, /* special_function */
166 "R_M68HC11_4B", /* name */
167 false, /* partial_inplace */
168 0x003, /* src_mask */
169 0x003, /* dst_mask */
170 false), /* pcrel_offset */
171
172 /* A 16 bit PC-rel relocation */
173 HOWTO (R_M68HC11_PCREL_16, /* type */
174 0, /* rightshift */
175 1, /* size (0 = byte, 1 = short, 2 = long) */
176 16, /* bitsize */
177 true, /* pc_relative */
178 0, /* bitpos */
179 complain_overflow_dont, /* complain_on_overflow */
180 bfd_elf_generic_reloc, /* special_function */
181 "R_M68HC11_PCREL_16", /* name */
182 false, /* partial_inplace */
183 0xffff, /* src_mask */
184 0xffff, /* dst_mask */
185 false), /* pcrel_offset */
186
187 /* GNU extension to record C++ vtable hierarchy */
188 HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */
189 0, /* rightshift */
190 1, /* size (0 = byte, 1 = short, 2 = long) */
191 0, /* bitsize */
192 false, /* pc_relative */
193 0, /* bitpos */
194 complain_overflow_dont, /* complain_on_overflow */
195 NULL, /* special_function */
196 "R_M68HC11_GNU_VTINHERIT", /* name */
197 false, /* partial_inplace */
198 0, /* src_mask */
199 0, /* dst_mask */
200 false), /* pcrel_offset */
201
202 /* GNU extension to record C++ vtable member usage */
203 HOWTO (R_M68HC11_GNU_VTENTRY, /* type */
204 0, /* rightshift */
205 1, /* size (0 = byte, 1 = short, 2 = long) */
206 0, /* bitsize */
207 false, /* pc_relative */
208 0, /* bitpos */
209 complain_overflow_dont, /* complain_on_overflow */
210 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
211 "R_M68HC11_GNU_VTENTRY", /* name */
212 false, /* partial_inplace */
213 0, /* src_mask */
214 0, /* dst_mask */
215 false), /* pcrel_offset */
216
217 /* A 24 bit relocation */
218 HOWTO (R_M68HC11_24, /* type */
219 0, /* rightshift */
220 1, /* size (0 = byte, 1 = short, 2 = long) */
221 24, /* bitsize */
222 false, /* pc_relative */
223 0, /* bitpos */
224 complain_overflow_bitfield, /* complain_on_overflow */
225 bfd_elf_generic_reloc, /* special_function */
226 "R_M68HC11_24", /* name */
227 false, /* partial_inplace */
228 0xffff, /* src_mask */
229 0xffff, /* dst_mask */
230 false), /* pcrel_offset */
231
232 /* A 16-bit low relocation */
233 HOWTO (R_M68HC11_LO16, /* type */
234 0, /* rightshift */
235 1, /* size (0 = byte, 1 = short, 2 = long) */
236 16, /* bitsize */
237 false, /* pc_relative */
238 0, /* bitpos */
239 complain_overflow_bitfield, /* complain_on_overflow */
240 bfd_elf_generic_reloc, /* special_function */
241 "R_M68HC11_LO16", /* name */
242 false, /* partial_inplace */
243 0xffff, /* src_mask */
244 0xffff, /* dst_mask */
245 false), /* pcrel_offset */
246
247 /* A page relocation */
248 HOWTO (R_M68HC11_PAGE, /* type */
249 0, /* rightshift */
250 0, /* size (0 = byte, 1 = short, 2 = long) */
251 8, /* bitsize */
252 false, /* pc_relative */
253 0, /* bitpos */
254 complain_overflow_bitfield, /* complain_on_overflow */
255 bfd_elf_generic_reloc, /* special_function */
256 "R_M68HC11_PAGE", /* name */
257 false, /* partial_inplace */
258 0x00ff, /* src_mask */
259 0x00ff, /* dst_mask */
260 false), /* pcrel_offset */
261
262 EMPTY_HOWTO (14),
263 EMPTY_HOWTO (15),
264 EMPTY_HOWTO (16),
265 EMPTY_HOWTO (17),
266 EMPTY_HOWTO (18),
267 EMPTY_HOWTO (19),
268
269 /* Mark beginning of a jump instruction (any form). */
270 HOWTO (R_M68HC11_RL_JUMP, /* type */
271 0, /* rightshift */
272 1, /* size (0 = byte, 1 = short, 2 = long) */
273 0, /* bitsize */
274 false, /* pc_relative */
275 0, /* bitpos */
276 complain_overflow_dont, /* complain_on_overflow */
277 m68hc11_elf_ignore_reloc, /* special_function */
278 "R_M68HC11_RL_JUMP", /* name */
279 true, /* partial_inplace */
280 0, /* src_mask */
281 0, /* dst_mask */
282 true), /* pcrel_offset */
283
284 /* Mark beginning of Gcc relaxation group instruction. */
285 HOWTO (R_M68HC11_RL_GROUP, /* type */
286 0, /* rightshift */
287 1, /* size (0 = byte, 1 = short, 2 = long) */
288 0, /* bitsize */
289 false, /* pc_relative */
290 0, /* bitpos */
291 complain_overflow_dont, /* complain_on_overflow */
292 m68hc11_elf_ignore_reloc, /* special_function */
293 "R_M68HC11_RL_GROUP", /* name */
294 true, /* partial_inplace */
295 0, /* src_mask */
296 0, /* dst_mask */
297 true), /* pcrel_offset */
298 };
299
300 /* Map BFD reloc types to M68HC11 ELF reloc types. */
301
302 struct m68hc11_reloc_map
303 {
304 bfd_reloc_code_real_type bfd_reloc_val;
305 unsigned char elf_reloc_val;
306 };
307
308 static const struct m68hc11_reloc_map m68hc11_reloc_map[] = {
309 {BFD_RELOC_NONE, R_M68HC11_NONE,},
310 {BFD_RELOC_8, R_M68HC11_8},
311 {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
312 {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
313 {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
314 {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
315 {BFD_RELOC_16, R_M68HC11_16},
316 {BFD_RELOC_32, R_M68HC11_32},
317 {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
318
319 {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
320 {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
321
322 {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
323 {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
324 {BFD_RELOC_M68HC11_24, R_M68HC11_24},
325
326 {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
327 {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
328 };
329
330 static reloc_howto_type *
331 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
332 bfd *abfd ATTRIBUTE_UNUSED;
333 bfd_reloc_code_real_type code;
334 {
335 unsigned int i;
336
337 for (i = 0;
338 i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
339 i++)
340 {
341 if (m68hc11_reloc_map[i].bfd_reloc_val == code)
342 return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
343 }
344
345 return NULL;
346 }
347
348 /* This function is used for relocs which are only used for relaxing,
349 which the linker should otherwise ignore. */
350
351 static bfd_reloc_status_type
352 m68hc11_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
353 output_bfd, error_message)
354 bfd *abfd ATTRIBUTE_UNUSED;
355 arelent *reloc_entry;
356 asymbol *symbol ATTRIBUTE_UNUSED;
357 PTR data ATTRIBUTE_UNUSED;
358 asection *input_section;
359 bfd *output_bfd;
360 char **error_message ATTRIBUTE_UNUSED;
361 {
362 if (output_bfd != NULL)
363 reloc_entry->address += input_section->output_offset;
364 return bfd_reloc_ok;
365 }
366
367 /* Set the howto pointer for an M68HC11 ELF reloc. */
368
369 static void
370 m68hc11_info_to_howto_rel (abfd, cache_ptr, dst)
371 bfd *abfd ATTRIBUTE_UNUSED;
372 arelent *cache_ptr;
373 Elf32_Internal_Rel *dst;
374 {
375 unsigned int r_type;
376
377 r_type = ELF32_R_TYPE (dst->r_info);
378 BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
379 cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
380 }
381
382 \f
383 /* Set and control ELF flags in ELF header. */
384
385 boolean
386 _bfd_m68hc11_elf_set_private_flags (abfd, flags)
387 bfd *abfd;
388 flagword flags;
389 {
390 BFD_ASSERT (!elf_flags_init (abfd)
391 || elf_elfheader (abfd)->e_flags == flags);
392
393 elf_elfheader (abfd)->e_flags = flags;
394 elf_flags_init (abfd) = true;
395 return true;
396 }
397
398 /* Merge backend specific data from an object file to the output
399 object file when linking. */
400
401 boolean
402 _bfd_m68hc11_elf_merge_private_bfd_data (ibfd, obfd)
403 bfd *ibfd;
404 bfd *obfd;
405 {
406 flagword old_flags;
407 flagword new_flags;
408 boolean ok = true;
409
410 /* Check if we have the same endianess */
411 if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
412 return false;
413
414 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
415 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
416 return true;
417
418 new_flags = elf_elfheader (ibfd)->e_flags;
419 elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
420 old_flags = elf_elfheader (obfd)->e_flags;
421
422 if (! elf_flags_init (obfd))
423 {
424 elf_flags_init (obfd) = true;
425 elf_elfheader (obfd)->e_flags = new_flags;
426 elf_elfheader (obfd)->e_ident[EI_CLASS]
427 = elf_elfheader (ibfd)->e_ident[EI_CLASS];
428
429 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
430 && bfd_get_arch_info (obfd)->the_default)
431 {
432 if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
433 bfd_get_mach (ibfd)))
434 return false;
435 }
436
437 return true;
438 }
439
440 /* Check ABI compatibility. */
441 if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
442 {
443 (*_bfd_error_handler)
444 (_("%s: linking files compiled for 16-bit integers (-mshort) "
445 "and others for 32-bit integers"),
446 bfd_archive_filename (ibfd));
447 ok = false;
448 }
449 if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
450 {
451 (*_bfd_error_handler)
452 (_("%s: linking files compiled for 32-bit double (-fshort-double) "
453 "and others for 64-bit double"),
454 bfd_archive_filename (ibfd));
455 ok = false;
456 }
457 new_flags &= ~EF_M68HC11_ABI;
458 old_flags &= ~EF_M68HC11_ABI;
459
460 /* Warn about any other mismatches */
461 if (new_flags != old_flags)
462 {
463 (*_bfd_error_handler)
464 (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
465 bfd_archive_filename (ibfd), (unsigned long) new_flags,
466 (unsigned long) old_flags);
467 ok = false;
468 }
469
470 if (! ok)
471 {
472 bfd_set_error (bfd_error_bad_value);
473 return false;
474 }
475
476 return true;
477 }
478
479 boolean
480 _bfd_m68hc11_elf_print_private_bfd_data (abfd, ptr)
481 bfd *abfd;
482 PTR ptr;
483 {
484 FILE *file = (FILE *) ptr;
485
486 BFD_ASSERT (abfd != NULL && ptr != NULL);
487
488 /* Print normal ELF private data. */
489 _bfd_elf_print_private_bfd_data (abfd, ptr);
490
491 /* xgettext:c-format */
492 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
493
494 if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
495 fprintf (file, _("[abi=32-bit int,"));
496 else
497 fprintf (file, _("[abi=16-bit int,"));
498
499 if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
500 fprintf (file, _(" 64-bit double]"));
501 else
502 fprintf (file, _(" 32-bit double]"));
503
504 if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
505 fprintf (file, _(" [memory=bank-model]"));
506 else
507 fprintf (file, _(" [memory=flat]"));
508
509 fputc ('\n', file);
510
511 return true;
512 }
513
514 /* Below is the only difference between elf32-m68hc12.c and elf32-m68hc11.c.
515 The Motorola spec says to use a different Elf machine code. */
516 #define ELF_ARCH bfd_arch_m68hc11
517 #define ELF_MACHINE_CODE EM_68HC11
518 #define ELF_MAXPAGESIZE 0x1000
519
520 #define TARGET_BIG_SYM bfd_elf32_m68hc11_vec
521 #define TARGET_BIG_NAME "elf32-m68hc11"
522
523 #define elf_info_to_howto 0
524 #define elf_info_to_howto_rel m68hc11_info_to_howto_rel
525 #define elf_backend_object_p 0
526 #define elf_backend_final_write_processing 0
527
528 #define bfd_elf32_bfd_merge_private_bfd_data \
529 _bfd_m68hc11_elf_merge_private_bfd_data
530 #define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags
531 #define bfd_elf32_bfd_print_private_bfd_data \
532 _bfd_m68hc11_elf_print_private_bfd_data
533
534 #include "elf32-target.h"
This page took 0.099806 seconds and 5 git commands to generate.