daily update
[deliverable/binutils-gdb.git] / bfd / elf32-m68hc11.c
CommitLineData
60bcf0fa 1/* Motorola 68HC11-specific support for 32-bit ELF
196486be 2 Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
dae78fb0 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"
1fd03b5a 24#include "bfdlink.h"
60bcf0fa
NC
25#include "libbfd.h"
26#include "elf-bfd.h"
27#include "elf/m68hc11.h"
28
29static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
56780f18 30 PARAMS ((bfd *, bfd_reloc_code_real_type));
60bcf0fa 31static void m68hc11_info_to_howto_rel
947216bf 32 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
60bcf0fa 33
dae78fb0 34static bfd_reloc_status_type m68hc11_elf_ignore_reloc
56780f18 35 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
dae78fb0 36
9b701e44
SC
37/* GC mark and sweep. */
38static asection *elf32_m68hc11_gc_mark_hook
56780f18
AM
39 PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
40 struct elf_link_hash_entry *, Elf_Internal_Sym *));
b34976b6 41static bfd_boolean elf32_m68hc11_gc_sweep_hook
56780f18
AM
42 PARAMS ((bfd *, struct bfd_link_info *, asection *,
43 const Elf_Internal_Rela *));
b34976b6 44static bfd_boolean elf32_m68hc11_check_relocs
56780f18
AM
45 PARAMS ((bfd *, struct bfd_link_info *, asection *,
46 const Elf_Internal_Rela *));
b34976b6 47static bfd_boolean elf32_m68hc11_relocate_section
56780f18
AM
48 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
49 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
b34976b6
AM
50static bfd_boolean m68hc11_elf_relax_section
51 PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
1fd03b5a 52static void m68hc11_elf_relax_delete_bytes
56780f18 53 PARAMS ((bfd *, asection *, bfd_vma, int));
1fd03b5a 54static void m68hc11_relax_group
56780f18
AM
55 PARAMS ((bfd *, asection *, bfd_byte *, unsigned,
56 unsigned long, unsigned long));
57static int compare_reloc PARAMS ((const void *, const void *));
1fd03b5a 58
9b701e44 59
b34976b6
AM
60bfd_boolean _bfd_m68hc11_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
61bfd_boolean _bfd_m68hc11_elf_set_private_flags PARAMS ((bfd *, flagword));
62bfd_boolean _bfd_m68hc11_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
96405e3c 63
60bcf0fa 64/* Use REL instead of RELA to save space */
acf8aed4 65#define USE_REL 1
60bcf0fa
NC
66
67/* The Motorola 68HC11 microcontroler only addresses 64Kb.
68 We must handle 8 and 16-bit relocations. The 32-bit relocation
69 is defined but not used except by gas when -gstabs is used (which
70 is wrong).
71 The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
72static reloc_howto_type elf_m68hc11_howto_table[] = {
73 /* This reloc does nothing. */
74 HOWTO (R_M68HC11_NONE, /* type */
75 0, /* rightshift */
76 2, /* size (0 = byte, 1 = short, 2 = long) */
77 32, /* bitsize */
b34976b6 78 FALSE, /* pc_relative */
60bcf0fa 79 0, /* bitpos */
7a897be4 80 complain_overflow_dont,/* complain_on_overflow */
60bcf0fa
NC
81 bfd_elf_generic_reloc, /* special_function */
82 "R_M68HC11_NONE", /* name */
b34976b6 83 FALSE, /* partial_inplace */
60bcf0fa
NC
84 0, /* src_mask */
85 0, /* dst_mask */
b34976b6 86 FALSE), /* pcrel_offset */
60bcf0fa
NC
87
88 /* A 8 bit absolute relocation */
89 HOWTO (R_M68HC11_8, /* type */
90 0, /* rightshift */
91 0, /* size (0 = byte, 1 = short, 2 = long) */
92 8, /* bitsize */
b34976b6 93 FALSE, /* pc_relative */
60bcf0fa
NC
94 0, /* bitpos */
95 complain_overflow_bitfield, /* complain_on_overflow */
96 bfd_elf_generic_reloc, /* special_function */
97 "R_M68HC11_8", /* name */
b34976b6 98 FALSE, /* partial_inplace */
60bcf0fa
NC
99 0x00ff, /* src_mask */
100 0x00ff, /* dst_mask */
b34976b6 101 FALSE), /* pcrel_offset */
60bcf0fa
NC
102
103 /* A 8 bit absolute relocation (upper address) */
104 HOWTO (R_M68HC11_HI8, /* type */
105 8, /* rightshift */
106 0, /* size (0 = byte, 1 = short, 2 = long) */
107 8, /* bitsize */
b34976b6 108 FALSE, /* pc_relative */
60bcf0fa
NC
109 0, /* bitpos */
110 complain_overflow_bitfield, /* complain_on_overflow */
111 bfd_elf_generic_reloc, /* special_function */
112 "R_M68HC11_HI8", /* name */
b34976b6 113 FALSE, /* partial_inplace */
60bcf0fa
NC
114 0x00ff, /* src_mask */
115 0x00ff, /* dst_mask */
b34976b6 116 FALSE), /* pcrel_offset */
60bcf0fa
NC
117
118 /* A 8 bit absolute relocation (upper address) */
119 HOWTO (R_M68HC11_LO8, /* type */
120 0, /* rightshift */
121 0, /* size (0 = byte, 1 = short, 2 = long) */
122 8, /* bitsize */
b34976b6 123 FALSE, /* pc_relative */
60bcf0fa
NC
124 0, /* bitpos */
125 complain_overflow_dont, /* complain_on_overflow */
126 bfd_elf_generic_reloc, /* special_function */
127 "R_M68HC11_LO8", /* name */
b34976b6 128 FALSE, /* partial_inplace */
60bcf0fa
NC
129 0x00ff, /* src_mask */
130 0x00ff, /* dst_mask */
b34976b6 131 FALSE), /* pcrel_offset */
60bcf0fa
NC
132
133 /* A 8 bit PC-rel relocation */
134 HOWTO (R_M68HC11_PCREL_8, /* type */
135 0, /* rightshift */
136 0, /* size (0 = byte, 1 = short, 2 = long) */
137 8, /* bitsize */
b34976b6 138 TRUE, /* pc_relative */
60bcf0fa
NC
139 0, /* bitpos */
140 complain_overflow_bitfield, /* complain_on_overflow */
141 bfd_elf_generic_reloc, /* special_function */
142 "R_M68HC11_PCREL_8", /* name */
b34976b6 143 FALSE, /* partial_inplace */
dae78fb0 144 0x00ff, /* src_mask */
60bcf0fa 145 0x00ff, /* dst_mask */
196486be 146 TRUE), /* pcrel_offset */
60bcf0fa
NC
147
148 /* A 16 bit absolute relocation */
149 HOWTO (R_M68HC11_16, /* type */
150 0, /* rightshift */
151 1, /* size (0 = byte, 1 = short, 2 = long) */
152 16, /* bitsize */
b34976b6 153 FALSE, /* pc_relative */
60bcf0fa
NC
154 0, /* bitpos */
155 complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
156 bfd_elf_generic_reloc, /* special_function */
157 "R_M68HC11_16", /* name */
b34976b6 158 FALSE, /* partial_inplace */
60bcf0fa
NC
159 0xffff, /* src_mask */
160 0xffff, /* dst_mask */
b34976b6 161 FALSE), /* pcrel_offset */
60bcf0fa
NC
162
163 /* A 32 bit absolute relocation. This one is never used for the
164 code relocation. It's used by gas for -gstabs generation. */
165 HOWTO (R_M68HC11_32, /* type */
166 0, /* rightshift */
167 2, /* size (0 = byte, 1 = short, 2 = long) */
168 32, /* bitsize */
b34976b6 169 FALSE, /* pc_relative */
60bcf0fa
NC
170 0, /* bitpos */
171 complain_overflow_bitfield, /* complain_on_overflow */
172 bfd_elf_generic_reloc, /* special_function */
173 "R_M68HC11_32", /* name */
b34976b6 174 FALSE, /* partial_inplace */
60bcf0fa
NC
175 0xffffffff, /* src_mask */
176 0xffffffff, /* dst_mask */
b34976b6 177 FALSE), /* pcrel_offset */
60bcf0fa
NC
178
179 /* A 3 bit absolute relocation */
180 HOWTO (R_M68HC11_3B, /* type */
181 0, /* rightshift */
182 0, /* size (0 = byte, 1 = short, 2 = long) */
183 3, /* bitsize */
b34976b6 184 FALSE, /* pc_relative */
60bcf0fa
NC
185 0, /* bitpos */
186 complain_overflow_bitfield, /* complain_on_overflow */
187 bfd_elf_generic_reloc, /* special_function */
188 "R_M68HC11_4B", /* name */
b34976b6 189 FALSE, /* partial_inplace */
60bcf0fa
NC
190 0x003, /* src_mask */
191 0x003, /* dst_mask */
b34976b6 192 FALSE), /* pcrel_offset */
60bcf0fa
NC
193
194 /* A 16 bit PC-rel relocation */
195 HOWTO (R_M68HC11_PCREL_16, /* type */
196 0, /* rightshift */
197 1, /* size (0 = byte, 1 = short, 2 = long) */
198 16, /* bitsize */
b34976b6 199 TRUE, /* pc_relative */
60bcf0fa
NC
200 0, /* bitpos */
201 complain_overflow_dont, /* complain_on_overflow */
202 bfd_elf_generic_reloc, /* special_function */
203 "R_M68HC11_PCREL_16", /* name */
b34976b6 204 FALSE, /* partial_inplace */
dae78fb0 205 0xffff, /* src_mask */
60bcf0fa 206 0xffff, /* dst_mask */
196486be 207 TRUE), /* pcrel_offset */
60bcf0fa
NC
208
209 /* GNU extension to record C++ vtable hierarchy */
210 HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */
211 0, /* rightshift */
212 1, /* size (0 = byte, 1 = short, 2 = long) */
213 0, /* bitsize */
b34976b6 214 FALSE, /* pc_relative */
60bcf0fa
NC
215 0, /* bitpos */
216 complain_overflow_dont, /* complain_on_overflow */
217 NULL, /* special_function */
218 "R_M68HC11_GNU_VTINHERIT", /* name */
b34976b6 219 FALSE, /* partial_inplace */
60bcf0fa
NC
220 0, /* src_mask */
221 0, /* dst_mask */
b34976b6 222 FALSE), /* pcrel_offset */
60bcf0fa
NC
223
224 /* GNU extension to record C++ vtable member usage */
225 HOWTO (R_M68HC11_GNU_VTENTRY, /* type */
226 0, /* rightshift */
227 1, /* size (0 = byte, 1 = short, 2 = long) */
228 0, /* bitsize */
b34976b6 229 FALSE, /* pc_relative */
60bcf0fa
NC
230 0, /* bitpos */
231 complain_overflow_dont, /* complain_on_overflow */
232 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
233 "R_M68HC11_GNU_VTENTRY", /* name */
b34976b6 234 FALSE, /* partial_inplace */
60bcf0fa
NC
235 0, /* src_mask */
236 0, /* dst_mask */
b34976b6 237 FALSE), /* pcrel_offset */
dae78fb0 238
7a897be4
SC
239 /* A 24 bit relocation */
240 HOWTO (R_M68HC11_24, /* type */
241 0, /* rightshift */
242 1, /* size (0 = byte, 1 = short, 2 = long) */
243 24, /* bitsize */
b34976b6 244 FALSE, /* pc_relative */
7a897be4
SC
245 0, /* bitpos */
246 complain_overflow_bitfield, /* complain_on_overflow */
247 bfd_elf_generic_reloc, /* special_function */
248 "R_M68HC11_24", /* name */
b34976b6 249 FALSE, /* partial_inplace */
196486be
SC
250 0xffffff, /* src_mask */
251 0xffffff, /* dst_mask */
b34976b6
AM
252 FALSE), /* pcrel_offset */
253
7a897be4
SC
254 /* A 16-bit low relocation */
255 HOWTO (R_M68HC11_LO16, /* type */
256 0, /* rightshift */
257 1, /* size (0 = byte, 1 = short, 2 = long) */
258 16, /* bitsize */
b34976b6 259 FALSE, /* pc_relative */
7a897be4
SC
260 0, /* bitpos */
261 complain_overflow_bitfield, /* complain_on_overflow */
262 bfd_elf_generic_reloc, /* special_function */
263 "R_M68HC11_LO16", /* name */
b34976b6 264 FALSE, /* partial_inplace */
7a897be4
SC
265 0xffff, /* src_mask */
266 0xffff, /* dst_mask */
b34976b6 267 FALSE), /* pcrel_offset */
7a897be4
SC
268
269 /* A page relocation */
270 HOWTO (R_M68HC11_PAGE, /* type */
271 0, /* rightshift */
272 0, /* size (0 = byte, 1 = short, 2 = long) */
273 8, /* bitsize */
b34976b6 274 FALSE, /* pc_relative */
7a897be4
SC
275 0, /* bitpos */
276 complain_overflow_bitfield, /* complain_on_overflow */
277 bfd_elf_generic_reloc, /* special_function */
278 "R_M68HC11_PAGE", /* name */
b34976b6 279 FALSE, /* partial_inplace */
7a897be4
SC
280 0x00ff, /* src_mask */
281 0x00ff, /* dst_mask */
b34976b6 282 FALSE), /* pcrel_offset */
7a897be4 283
dae78fb0
SC
284 EMPTY_HOWTO (14),
285 EMPTY_HOWTO (15),
286 EMPTY_HOWTO (16),
287 EMPTY_HOWTO (17),
288 EMPTY_HOWTO (18),
289 EMPTY_HOWTO (19),
b34976b6 290
dae78fb0
SC
291 /* Mark beginning of a jump instruction (any form). */
292 HOWTO (R_M68HC11_RL_JUMP, /* type */
293 0, /* rightshift */
294 1, /* size (0 = byte, 1 = short, 2 = long) */
295 0, /* bitsize */
b34976b6 296 FALSE, /* pc_relative */
dae78fb0
SC
297 0, /* bitpos */
298 complain_overflow_dont, /* complain_on_overflow */
299 m68hc11_elf_ignore_reloc, /* special_function */
300 "R_M68HC11_RL_JUMP", /* name */
b34976b6 301 TRUE, /* partial_inplace */
dae78fb0
SC
302 0, /* src_mask */
303 0, /* dst_mask */
b34976b6 304 TRUE), /* pcrel_offset */
dae78fb0
SC
305
306 /* Mark beginning of Gcc relaxation group instruction. */
307 HOWTO (R_M68HC11_RL_GROUP, /* type */
308 0, /* rightshift */
309 1, /* size (0 = byte, 1 = short, 2 = long) */
310 0, /* bitsize */
b34976b6 311 FALSE, /* pc_relative */
dae78fb0
SC
312 0, /* bitpos */
313 complain_overflow_dont, /* complain_on_overflow */
314 m68hc11_elf_ignore_reloc, /* special_function */
315 "R_M68HC11_RL_GROUP", /* name */
b34976b6 316 TRUE, /* partial_inplace */
dae78fb0
SC
317 0, /* src_mask */
318 0, /* dst_mask */
b34976b6 319 TRUE), /* pcrel_offset */
60bcf0fa
NC
320};
321
322/* Map BFD reloc types to M68HC11 ELF reloc types. */
323
324struct m68hc11_reloc_map
325{
326 bfd_reloc_code_real_type bfd_reloc_val;
327 unsigned char elf_reloc_val;
328};
329
330static const struct m68hc11_reloc_map m68hc11_reloc_map[] = {
331 {BFD_RELOC_NONE, R_M68HC11_NONE,},
332 {BFD_RELOC_8, R_M68HC11_8},
333 {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
334 {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
335 {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
336 {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
337 {BFD_RELOC_16, R_M68HC11_16},
338 {BFD_RELOC_32, R_M68HC11_32},
339 {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
340
60bcf0fa
NC
341 {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
342 {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
dae78fb0 343
7a897be4
SC
344 {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
345 {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
346 {BFD_RELOC_M68HC11_24, R_M68HC11_24},
347
dae78fb0
SC
348 {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
349 {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
60bcf0fa
NC
350};
351
352static reloc_howto_type *
353bfd_elf32_bfd_reloc_type_lookup (abfd, code)
354 bfd *abfd ATTRIBUTE_UNUSED;
355 bfd_reloc_code_real_type code;
356{
357 unsigned int i;
358
359 for (i = 0;
360 i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
361 i++)
362 {
363 if (m68hc11_reloc_map[i].bfd_reloc_val == code)
364 return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
365 }
366
367 return NULL;
368}
369
dae78fb0
SC
370/* This function is used for relocs which are only used for relaxing,
371 which the linker should otherwise ignore. */
372
373static bfd_reloc_status_type
374m68hc11_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
375 output_bfd, error_message)
376 bfd *abfd ATTRIBUTE_UNUSED;
377 arelent *reloc_entry;
378 asymbol *symbol ATTRIBUTE_UNUSED;
379 PTR data ATTRIBUTE_UNUSED;
380 asection *input_section;
381 bfd *output_bfd;
382 char **error_message ATTRIBUTE_UNUSED;
383{
384 if (output_bfd != NULL)
385 reloc_entry->address += input_section->output_offset;
386 return bfd_reloc_ok;
387}
388
60bcf0fa
NC
389/* Set the howto pointer for an M68HC11 ELF reloc. */
390
391static void
392m68hc11_info_to_howto_rel (abfd, cache_ptr, dst)
393 bfd *abfd ATTRIBUTE_UNUSED;
394 arelent *cache_ptr;
947216bf 395 Elf_Internal_Rela *dst;
60bcf0fa
NC
396{
397 unsigned int r_type;
398
399 r_type = ELF32_R_TYPE (dst->r_info);
400 BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
401 cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
402}
403
9b701e44 404static asection *
56780f18
AM
405elf32_m68hc11_gc_mark_hook (sec, info, rel, h, sym)
406 asection *sec;
9b701e44
SC
407 struct bfd_link_info *info ATTRIBUTE_UNUSED;
408 Elf_Internal_Rela *rel;
409 struct elf_link_hash_entry *h;
410 Elf_Internal_Sym *sym;
411{
412 if (h != NULL)
413 {
414 switch (ELF32_R_TYPE (rel->r_info))
415 {
416 default:
417 switch (h->root.type)
418 {
419 case bfd_link_hash_defined:
420 case bfd_link_hash_defweak:
421 return h->root.u.def.section;
422
423 case bfd_link_hash_common:
424 return h->root.u.c.p->section;
425
426 default:
427 break;
428 }
429 }
430 }
431 else
56780f18
AM
432 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
433
9b701e44
SC
434 return NULL;
435}
436
b34976b6 437static bfd_boolean
9b701e44
SC
438elf32_m68hc11_gc_sweep_hook (abfd, info, sec, relocs)
439 bfd *abfd ATTRIBUTE_UNUSED;
440 struct bfd_link_info *info ATTRIBUTE_UNUSED;
441 asection *sec ATTRIBUTE_UNUSED;
442 const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
443{
444 /* We don't use got and plt entries for 68hc11/68hc12. */
b34976b6 445 return TRUE;
9b701e44
SC
446}
447
196486be
SC
448\f
449/* 68HC11 Linker Relaxation. */
450
b34976b6 451struct m68hc11_direct_relax
1fd03b5a
SC
452{
453 const char *name;
454 unsigned char code;
455 unsigned char direct_code;
456} m68hc11_direct_relax_table[] = {
457 { "adca", 0xB9, 0x99 },
458 { "adcb", 0xF9, 0xD9 },
459 { "adda", 0xBB, 0x9B },
460 { "addb", 0xFB, 0xDB },
461 { "addd", 0xF3, 0xD3 },
462 { "anda", 0xB4, 0x94 },
463 { "andb", 0xF4, 0xD4 },
464 { "cmpa", 0xB1, 0x91 },
465 { "cmpb", 0xF1, 0xD1 },
466 { "cpd", 0xB3, 0x93 },
467 { "cpxy", 0xBC, 0x9C },
468/* { "cpy", 0xBC, 0x9C }, */
469 { "eora", 0xB8, 0x98 },
470 { "eorb", 0xF8, 0xD8 },
471 { "jsr", 0xBD, 0x9D },
472 { "ldaa", 0xB6, 0x96 },
473 { "ldab", 0xF6, 0xD6 },
474 { "ldd", 0xFC, 0xDC },
475 { "lds", 0xBE, 0x9E },
476 { "ldxy", 0xFE, 0xDE },
477 /* { "ldy", 0xFE, 0xDE },*/
478 { "oraa", 0xBA, 0x9A },
479 { "orab", 0xFA, 0xDA },
480 { "sbca", 0xB2, 0x92 },
481 { "sbcb", 0xF2, 0xD2 },
482 { "staa", 0xB7, 0x97 },
483 { "stab", 0xF7, 0xD7 },
484 { "std", 0xFD, 0xDD },
485 { "sts", 0xBF, 0x9F },
486 { "stxy", 0xFF, 0xDF },
487 /* { "sty", 0xFF, 0xDF },*/
488 { "suba", 0xB0, 0x90 },
489 { "subb", 0xF0, 0xD0 },
490 { "subd", 0xB3, 0x93 },
491 { 0, 0, 0 }
492};
493
494static struct m68hc11_direct_relax *
495find_relaxable_insn (unsigned char code)
496{
497 int i;
498
499 for (i = 0; m68hc11_direct_relax_table[i].name; i++)
500 if (m68hc11_direct_relax_table[i].code == code)
501 return &m68hc11_direct_relax_table[i];
502
503 return 0;
504}
505
506static int
507compare_reloc (e1, e2)
508 const void *e1;
509 const void *e2;
510{
511 const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1;
512 const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2;
513
514 if (i1->r_offset == i2->r_offset)
515 return 0;
516 else
517 return i1->r_offset < i2->r_offset ? -1 : 1;
518}
519
520#define M6811_OP_LDX_IMMEDIATE (0xCE)
521
522static void
523m68hc11_relax_group (abfd, sec, contents, value, offset, end_group)
524 bfd *abfd;
525 asection *sec;
526 bfd_byte *contents;
527 unsigned value;
528 unsigned long offset;
529 unsigned long end_group;
530{
531 unsigned char code;
532 unsigned long start_offset;
533 unsigned long ldx_offset = offset;
534 unsigned long ldx_size;
535 int can_delete_ldx;
536 int relax_ldy = 0;
537
538 /* First instruction of the relax group must be a
539 LDX #value or LDY #value. If this is not the case,
540 ignore the relax group. */
541 code = bfd_get_8 (abfd, contents + offset);
542 if (code == 0x18)
543 {
544 relax_ldy++;
545 offset++;
546 code = bfd_get_8 (abfd, contents + offset);
547 }
548 ldx_size = offset - ldx_offset + 3;
549 offset += 3;
550 if (code != M6811_OP_LDX_IMMEDIATE || offset >= end_group)
551 return;
552
553
554 /* We can remove the LDX/LDY only when all bset/brclr instructions
555 of the relax group have been converted to use direct addressing
556 mode. */
557 can_delete_ldx = 1;
558 while (offset < end_group)
559 {
560 unsigned isize;
561 unsigned new_value;
562 int bset_use_y;
563
564 bset_use_y = 0;
565 start_offset = offset;
566 code = bfd_get_8 (abfd, contents + offset);
567 if (code == 0x18)
568 {
569 bset_use_y++;
570 offset++;
571 code = bfd_get_8 (abfd, contents + offset);
572 }
573
574 /* Check the instruction and translate to use direct addressing mode. */
575 switch (code)
576 {
577 /* bset */
578 case 0x1C:
579 code = 0x14;
580 isize = 3;
581 break;
582
583 /* brclr */
584 case 0x1F:
585 code = 0x13;
586 isize = 4;
587 break;
588
589 /* brset */
590 case 0x1E:
591 code = 0x12;
592 isize = 4;
593 break;
594
595 /* bclr */
596 case 0x1D:
597 code = 0x15;
598 isize = 3;
599 break;
600
601 /* This instruction is not recognized and we are not
602 at end of the relax group. Ignore and don't remove
603 the first LDX (we don't know what it is used for...). */
604 default:
605 return;
606 }
607 new_value = (unsigned) bfd_get_8 (abfd, contents + offset + 1);
608 new_value += value;
609 if ((new_value & 0xff00) == 0 && bset_use_y == relax_ldy)
610 {
611 bfd_put_8 (abfd, code, contents + offset);
612 bfd_put_8 (abfd, new_value, contents + offset + 1);
613 if (start_offset != offset)
614 {
615 m68hc11_elf_relax_delete_bytes (abfd, sec, start_offset,
616 offset - start_offset);
617 end_group--;
618 }
619 }
620 else
621 {
622 can_delete_ldx = 0;
623 }
624 offset = start_offset + isize;
625 }
626 if (can_delete_ldx)
627 {
628 /* Remove the move instruction (3 or 4 bytes win). */
629 m68hc11_elf_relax_delete_bytes (abfd, sec, ldx_offset, ldx_size);
630 }
631}
632
633/* This function handles relaxing for the 68HC11.
634
b34976b6 635
1fd03b5a
SC
636 and somewhat more difficult to support. */
637
b34976b6 638static bfd_boolean
1fd03b5a
SC
639m68hc11_elf_relax_section (abfd, sec, link_info, again)
640 bfd *abfd;
641 asection *sec;
642 struct bfd_link_info *link_info;
b34976b6 643 bfd_boolean *again;
1fd03b5a
SC
644{
645 Elf_Internal_Shdr *symtab_hdr;
646 Elf_Internal_Shdr *shndx_hdr;
647 Elf_Internal_Rela *internal_relocs;
648 Elf_Internal_Rela *free_relocs = NULL;
649 Elf_Internal_Rela *irel, *irelend;
650 bfd_byte *contents = NULL;
651 bfd_byte *free_contents = NULL;
1fd03b5a
SC
652 Elf32_External_Sym *free_extsyms = NULL;
653 Elf_Internal_Rela *prev_insn_branch = NULL;
654 Elf_Internal_Rela *prev_insn_group = NULL;
655 unsigned insn_group_value = 0;
1f4c5b47 656 Elf_Internal_Sym *isymbuf = NULL;
1fd03b5a
SC
657
658 /* Assume nothing changes. */
b34976b6 659 *again = FALSE;
1fd03b5a
SC
660
661 /* We don't have to do anything for a relocateable link, if
662 this section does not have relocs, or if this is not a
663 code section. */
664 if (link_info->relocateable
665 || (sec->flags & SEC_RELOC) == 0
666 || sec->reloc_count == 0
667 || (sec->flags & SEC_CODE) == 0)
b34976b6 668 return TRUE;
1fd03b5a
SC
669
670 /* If this is the first time we have been called for this section,
671 initialize the cooked size. */
672 if (sec->_cooked_size == 0)
673 sec->_cooked_size = sec->_raw_size;
674
675 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
676 shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
677
678 /* Get a copy of the native relocations. */
679 internal_relocs = (_bfd_elf32_link_read_relocs
680 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
681 link_info->keep_memory));
682 if (internal_relocs == NULL)
683 goto error_return;
684 if (! link_info->keep_memory)
685 free_relocs = internal_relocs;
686
687 /* Checking for branch relaxation relies on the relocations to
688 be sorted on 'r_offset'. This is not guaranteed so we must sort. */
689 qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
690 compare_reloc);
691
692 /* Walk through them looking for relaxing opportunities. */
693 irelend = internal_relocs + sec->reloc_count;
694 for (irel = internal_relocs; irel < irelend; irel++)
695 {
696 bfd_vma symval;
697 bfd_vma value;
1f4c5b47 698 Elf_Internal_Sym *isym;
9b691193 699 asection *sym_sec;
196486be 700 int is_far = 0;
1fd03b5a
SC
701
702 /* If this isn't something that can be relaxed, then ignore
703 this reloc. */
704 if (ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_16
705 && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_JUMP
706 && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_GROUP)
707 {
708 prev_insn_branch = 0;
709 prev_insn_group = 0;
710 continue;
711 }
712
713 /* Get the section contents if we haven't done so already. */
714 if (contents == NULL)
715 {
716 /* Get cached copy if it exists. */
717 if (elf_section_data (sec)->this_hdr.contents != NULL)
718 contents = elf_section_data (sec)->this_hdr.contents;
719 else
720 {
721 /* Go get them off disk. */
722 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
723 if (contents == NULL)
724 goto error_return;
725 free_contents = contents;
726
727 if (! bfd_get_section_contents (abfd, sec, contents,
728 (file_ptr) 0, sec->_raw_size))
729 goto error_return;
730 }
731 }
732
733 /* Try to eliminate an unconditional 8 bit pc-relative branch
734 which immediately follows a conditional 8 bit pc-relative
735 branch around the unconditional branch.
736
737 original: new:
738 bCC lab1 bCC' lab2
739 bra lab2
740 lab1: lab1:
741
742 This happens when the bCC can't reach lab2 at assembly time,
743 but due to other relaxations it can reach at link time. */
744 if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_JUMP)
745 {
746 Elf_Internal_Rela *nrel;
747 unsigned char code;
748 unsigned char roffset;
749
750 prev_insn_branch = 0;
751 prev_insn_group = 0;
b34976b6 752
1fd03b5a 753 /* Do nothing if this reloc is the last byte in the section. */
196486be 754 if (irel->r_offset + 2 >= sec->_cooked_size)
1fd03b5a
SC
755 continue;
756
757 /* See if the next instruction is an unconditional pc-relative
758 branch, more often than not this test will fail, so we
759 test it first to speed things up. */
760 code = bfd_get_8 (abfd, contents + irel->r_offset + 2);
761 if (code != 0x7e)
762 continue;
763
764 /* Also make sure the next relocation applies to the next
765 instruction and that it's a pc-relative 8 bit branch. */
766 nrel = irel + 1;
767 if (nrel == irelend
768 || irel->r_offset + 3 != nrel->r_offset
769 || ELF32_R_TYPE (nrel->r_info) != (int) R_M68HC11_16)
770 continue;
771
772 /* Make sure our destination immediately follows the
773 unconditional branch. */
774 roffset = bfd_get_8 (abfd, contents + irel->r_offset + 1);
775 if (roffset != 3)
776 continue;
777
778 prev_insn_branch = irel;
779 prev_insn_group = 0;
780 continue;
781 }
782
783 /* Read this BFD's symbols if we haven't done so already. */
1f4c5b47 784 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1fd03b5a 785 {
1f4c5b47
SC
786 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
787 if (isymbuf == NULL)
788 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
789 symtab_hdr->sh_info, 0,
790 NULL, NULL, NULL);
791 if (isymbuf == NULL)
792 goto error_return;
1fd03b5a
SC
793 }
794
795 /* Get the value of the symbol referred to by the reloc. */
796 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
797 {
1fd03b5a 798 /* A local symbol. */
1f4c5b47 799 isym = isymbuf + ELF32_R_SYM (irel->r_info);
196486be 800 is_far = isym->st_other & STO_M68HC12_FAR;
1f4c5b47
SC
801 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
802 symval = (isym->st_value
1fd03b5a
SC
803 + sym_sec->output_section->vma
804 + sym_sec->output_offset);
805 }
806 else
807 {
808 unsigned long indx;
809 struct elf_link_hash_entry *h;
810
811 /* An external symbol. */
812 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
813 h = elf_sym_hashes (abfd)[indx];
814 BFD_ASSERT (h != NULL);
815 if (h->root.type != bfd_link_hash_defined
816 && h->root.type != bfd_link_hash_defweak)
817 {
818 /* This appears to be a reference to an undefined
819 symbol. Just ignore it--it will be caught by the
820 regular reloc processing. */
821 prev_insn_branch = 0;
822 prev_insn_group = 0;
823 continue;
824 }
825
196486be 826 is_far = h->other & STO_M68HC12_FAR;
9b691193
SC
827 isym = 0;
828 sym_sec = h->root.u.def.section;
1fd03b5a 829 symval = (h->root.u.def.value
9b691193
SC
830 + sym_sec->output_section->vma
831 + sym_sec->output_offset);
1fd03b5a
SC
832 }
833
834 if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_GROUP)
835 {
836 prev_insn_branch = 0;
837 prev_insn_group = 0;
b34976b6 838
1fd03b5a
SC
839 /* Do nothing if this reloc is the last byte in the section. */
840 if (irel->r_offset == sec->_cooked_size)
841 continue;
842
843 prev_insn_group = irel;
1f4c5b47 844 insn_group_value = isym->st_value;
1fd03b5a
SC
845 continue;
846 }
847
9b691193
SC
848 /* When we relax some bytes, the size of our section changes.
849 This affects the layout of next input sections that go in our
850 output section. When the symbol is part of another section that
851 will go in the same output section as the current one, it's
852 final address may now be incorrect (too far). We must let the
853 linker re-compute all section offsets before processing this
854 reloc. Code example:
855
856 Initial Final
857 .sect .text section size = 6 section size = 4
858 jmp foo
859 jmp bar
860 .sect .text.foo_bar output_offset = 6 output_offset = 4
861 foo: rts
862 bar: rts
863
864 If we process the reloc now, the jmp bar is replaced by a
865 relative branch to the initial bar address (output_offset 6). */
866 if (*again && sym_sec != sec
867 && sym_sec->output_section == sec->output_section)
868 {
869 prev_insn_group = 0;
870 prev_insn_branch = 0;
871 continue;
872 }
b34976b6 873
1fd03b5a
SC
874 value = symval;
875 /* Try to turn a far branch to a near branch. */
876 if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
877 && prev_insn_branch)
878 {
879 bfd_vma offset;
880 unsigned char code;
881
882 offset = value - (prev_insn_branch->r_offset
883 + sec->output_section->vma
884 + sec->output_offset + 2);
885
886 /* If the offset is still out of -128..+127 range,
887 leave that far branch unchanged. */
888 if ((offset & 0xff80) != 0 && (offset & 0xff80) != 0xff80)
889 {
890 prev_insn_branch = 0;
891 continue;
892 }
893
894 /* Shrink the branch. */
895 code = bfd_get_8 (abfd, contents + prev_insn_branch->r_offset);
896 if (code == 0x7e)
897 {
898 code = 0x20;
899 bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
196486be 900 bfd_put_8 (abfd, 0xff,
1fd03b5a 901 contents + prev_insn_branch->r_offset + 1);
196486be 902 irel->r_offset = prev_insn_branch->r_offset + 1;
1fd03b5a 903 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
196486be 904 R_M68HC11_PCREL_8);
1fd03b5a 905 m68hc11_elf_relax_delete_bytes (abfd, sec,
196486be 906 irel->r_offset + 1, 1);
1fd03b5a
SC
907 }
908 else
909 {
910 code ^= 0x1;
911 bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
196486be 912 bfd_put_8 (abfd, 0xff,
1fd03b5a 913 contents + prev_insn_branch->r_offset + 1);
196486be 914 irel->r_offset = prev_insn_branch->r_offset + 1;
1fd03b5a 915 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
196486be 916 R_M68HC11_PCREL_8);
1fd03b5a 917 m68hc11_elf_relax_delete_bytes (abfd, sec,
196486be 918 irel->r_offset + 1, 3);
1fd03b5a
SC
919 }
920 prev_insn_branch = 0;
b34976b6 921 *again = TRUE;
1fd03b5a
SC
922 }
923
924 /* Try to turn a 16 bit address into a 8 bit page0 address. */
925 else if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
926 && (value & 0xff00) == 0)
927 {
928 unsigned char code;
929 unsigned short offset;
930 struct m68hc11_direct_relax *rinfo;
931
932 prev_insn_branch = 0;
933 offset = bfd_get_16 (abfd, contents + irel->r_offset);
934 offset += value;
935 if ((offset & 0xff00) != 0)
936 {
937 prev_insn_group = 0;
938 continue;
939 }
940
941 if (prev_insn_group)
942 {
9b691193 943 unsigned long old_sec_size = sec->_cooked_size;
b34976b6 944
1fd03b5a
SC
945 /* Note that we've changed the reldection contents, etc. */
946 elf_section_data (sec)->relocs = internal_relocs;
947 free_relocs = NULL;
948
949 elf_section_data (sec)->this_hdr.contents = contents;
950 free_contents = NULL;
951
1f4c5b47 952 symtab_hdr->contents = (bfd_byte *) isymbuf;
1fd03b5a
SC
953 free_extsyms = NULL;
954
955 m68hc11_relax_group (abfd, sec, contents, offset,
956 prev_insn_group->r_offset,
957 insn_group_value);
958 irel = prev_insn_group;
959 prev_insn_group = 0;
960 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
961 R_M68HC11_NONE);
9b691193 962 if (sec->_cooked_size != old_sec_size)
b34976b6 963 *again = TRUE;
1fd03b5a
SC
964 continue;
965 }
b34976b6 966
1fd03b5a
SC
967 /* Get the opcode. */
968 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
969 rinfo = find_relaxable_insn (code);
970 if (rinfo == 0)
971 {
972 prev_insn_group = 0;
973 continue;
974 }
975
976 /* Note that we've changed the reldection contents, etc. */
977 elf_section_data (sec)->relocs = internal_relocs;
978 free_relocs = NULL;
979
980 elf_section_data (sec)->this_hdr.contents = contents;
981 free_contents = NULL;
982
1f4c5b47 983 symtab_hdr->contents = (bfd_byte *) isymbuf;
1fd03b5a
SC
984 free_extsyms = NULL;
985
986 /* Fix the opcode. */
987 /* printf ("A relaxable case : 0x%02x (%s)\n",
988 code, rinfo->name); */
989 bfd_put_8 (abfd, rinfo->direct_code,
990 contents + irel->r_offset - 1);
991
992 /* Delete one byte of data (upper byte of address). */
993 m68hc11_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 1);
994
995 /* Fix the relocation's type. */
996 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
997 R_M68HC11_8);
998
9b691193 999 /* That will change things, so, we should relax again. */
b34976b6 1000 *again = TRUE;
1fd03b5a 1001 }
196486be 1002 else if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_16 && !is_far)
1fd03b5a
SC
1003 {
1004 unsigned char code;
1005 bfd_vma offset;
1006
1007 prev_insn_branch = 0;
1008 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
196486be 1009 if (code == 0x7e || code == 0xbd)
1fd03b5a
SC
1010 {
1011 offset = value - (irel->r_offset
1012 + sec->output_section->vma
1013 + sec->output_offset + 1);
1014 offset += bfd_get_16 (abfd, contents + irel->r_offset);
1015
1016 /* If the offset is still out of -128..+127 range,
1017 leave that far branch unchanged. */
1018 if ((offset & 0xff80) == 0 || (offset & 0xff80) == 0xff80)
1019 {
1020
1021 /* Note that we've changed the reldection contents, etc. */
1022 elf_section_data (sec)->relocs = internal_relocs;
1023 free_relocs = NULL;
b34976b6 1024
1fd03b5a
SC
1025 elf_section_data (sec)->this_hdr.contents = contents;
1026 free_contents = NULL;
b34976b6 1027
1f4c5b47 1028 symtab_hdr->contents = (bfd_byte *) isymbuf;
1fd03b5a
SC
1029 free_extsyms = NULL;
1030
1031 /* Shrink the branch. */
196486be 1032 code = (code == 0x7e) ? 0x20 : 0x8d;
1fd03b5a
SC
1033 bfd_put_8 (abfd, code,
1034 contents + irel->r_offset - 1);
196486be 1035 bfd_put_8 (abfd, 0xff,
1fd03b5a
SC
1036 contents + irel->r_offset);
1037 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
196486be 1038 R_M68HC11_PCREL_8);
1fd03b5a
SC
1039 m68hc11_elf_relax_delete_bytes (abfd, sec,
1040 irel->r_offset + 1, 1);
9b691193 1041 /* That will change things, so, we should relax again. */
b34976b6 1042 *again = TRUE;
1fd03b5a
SC
1043 }
1044 }
1045 }
1046 prev_insn_branch = 0;
1047 }
1048
1049 if (free_relocs != NULL)
1050 {
1051 free (free_relocs);
1052 free_relocs = NULL;
1053 }
1054
1055 if (free_contents != NULL)
1056 {
1057 if (! link_info->keep_memory)
1058 free (free_contents);
1059 else
1060 {
1061 /* Cache the section contents for elf_link_input_bfd. */
1062 elf_section_data (sec)->this_hdr.contents = contents;
1063 }
1064 free_contents = NULL;
1065 }
1066
1067 if (free_extsyms != NULL)
1068 {
1069 if (! link_info->keep_memory)
1070 free (free_extsyms);
1071 else
1072 {
1073 /* Cache the symbols for elf_link_input_bfd. */
1f4c5b47 1074 symtab_hdr->contents = (unsigned char *) isymbuf;
1fd03b5a
SC
1075 }
1076 free_extsyms = NULL;
1077 }
1078
b34976b6 1079 return TRUE;
1fd03b5a
SC
1080
1081 error_return:
1082 if (free_relocs != NULL)
1083 free (free_relocs);
1084 if (free_contents != NULL)
1085 free (free_contents);
1086 if (free_extsyms != NULL)
1087 free (free_extsyms);
b34976b6 1088 return FALSE;
1fd03b5a
SC
1089}
1090
1091/* Delete some bytes from a section while relaxing. */
1092
1093static void
1094m68hc11_elf_relax_delete_bytes (abfd, sec, addr, count)
1095 bfd *abfd;
1096 asection *sec;
1097 bfd_vma addr;
1098 int count;
1099{
1100 Elf_Internal_Shdr *symtab_hdr;
1fd03b5a 1101 unsigned int sec_shndx;
1fd03b5a
SC
1102 bfd_byte *contents;
1103 Elf_Internal_Rela *irel, *irelend;
1104 bfd_vma toaddr;
1f4c5b47 1105 Elf_Internal_Sym *isymbuf, *isym, *isymend;
1fd03b5a
SC
1106 struct elf_link_hash_entry **sym_hashes;
1107 struct elf_link_hash_entry **end_hashes;
1108 unsigned int symcount;
1109
1110 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1f4c5b47 1111 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1fd03b5a
SC
1112
1113 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1114
1115 contents = elf_section_data (sec)->this_hdr.contents;
1116
1117 toaddr = sec->_cooked_size;
1118
1119 irel = elf_section_data (sec)->relocs;
1120 irelend = irel + sec->reloc_count;
1121
1122 /* Actually delete the bytes. */
1123 memmove (contents + addr, contents + addr + count,
1124 (size_t) (toaddr - addr - count));
1fd03b5a 1125
1f4c5b47 1126 sec->_cooked_size -= count;
b34976b6 1127
1fd03b5a
SC
1128 /* Adjust all the relocs. */
1129 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1130 {
1131 unsigned char code;
1132 unsigned char offset;
1133 unsigned short raddr;
1134 unsigned long old_offset;
1135 int branch_pos;
1136
1137 old_offset = irel->r_offset;
1138
1139 /* See if this reloc was for the bytes we have deleted, in which
1140 case we no longer care about it. Don't delete relocs which
1141 represent addresses, though. */
1142 if (ELF32_R_TYPE (irel->r_info) != R_M68HC11_RL_JUMP
1143 && irel->r_offset >= addr && irel->r_offset < addr + count)
1144 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1145 R_M68HC11_NONE);
1146
1147 if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_NONE)
1148 continue;
1149
1150 /* Get the new reloc address. */
1151 if ((irel->r_offset > addr
1152 && irel->r_offset < toaddr))
1153 irel->r_offset -= count;
1154
1155 /* If this is a PC relative reloc, see if the range it covers
1156 includes the bytes we have deleted. */
1157 switch (ELF32_R_TYPE (irel->r_info))
1158 {
1159 default:
1160 break;
1161
1162 case R_M68HC11_RL_JUMP:
1163 code = bfd_get_8 (abfd, contents + irel->r_offset);
1164 switch (code)
1165 {
1166 /* jsr and jmp instruction are also marked with RL_JUMP
1167 relocs but no adjustment must be made. */
1168 case 0x7e:
1169 case 0x9d:
1170 case 0xbd:
1171 continue;
1172
1173 case 0x12:
1174 case 0x13:
1175 branch_pos = 3;
1176 raddr = 4;
1177
1178 /* Special case when we translate a brclr N,y into brclr *<addr>
1179 In this case, the 0x18 page2 prefix is removed.
1180 The reloc offset is not modified but the instruction
1181 size is reduced by 1. */
1182 if (old_offset == addr)
1183 raddr++;
1184 break;
1185
1186 case 0x1e:
1187 case 0x1f:
1188 branch_pos = 3;
1189 raddr = 4;
1190 break;
1191
1192 case 0x18:
1193 branch_pos = 4;
1194 raddr = 5;
1195 break;
1196
1197 default:
1198 branch_pos = 1;
1199 raddr = 2;
1200 break;
1201 }
1202 offset = bfd_get_8 (abfd, contents + irel->r_offset + branch_pos);
1203 raddr += old_offset;
1204 raddr += ((unsigned short) offset | ((offset & 0x80) ? 0xff00 : 0));
30491647 1205 if (irel->r_offset < addr && raddr > addr)
1fd03b5a
SC
1206 {
1207 offset -= count;
1208 bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
1209 }
1210 else if (irel->r_offset >= addr && raddr <= addr)
1211 {
1212 offset += count;
1213 bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
1214 }
1215 else
1216 {
1217 /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr,
1218 irel->r_offset, addr);*/
1219 }
b34976b6 1220
1fd03b5a
SC
1221 break;
1222 }
1223 }
1224
1225 /* Adjust the local symbols defined in this section. */
1f4c5b47
SC
1226 isymend = isymbuf + symtab_hdr->sh_info;
1227 for (isym = isymbuf; isym < isymend; isym++)
1fd03b5a 1228 {
1f4c5b47
SC
1229 if (isym->st_shndx == sec_shndx
1230 && isym->st_value > addr
196486be 1231 && isym->st_value <= toaddr)
1f4c5b47 1232 isym->st_value -= count;
1fd03b5a
SC
1233 }
1234
1235 /* Now adjust the global symbols defined in this section. */
1236 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1237 - symtab_hdr->sh_info);
1238 sym_hashes = elf_sym_hashes (abfd);
1239 end_hashes = sym_hashes + symcount;
1240 for (; sym_hashes < end_hashes; sym_hashes++)
1241 {
1242 struct elf_link_hash_entry *sym_hash = *sym_hashes;
1243 if ((sym_hash->root.type == bfd_link_hash_defined
1244 || sym_hash->root.type == bfd_link_hash_defweak)
1245 && sym_hash->root.u.def.section == sec
1246 && sym_hash->root.u.def.value > addr
196486be 1247 && sym_hash->root.u.def.value <= toaddr)
1fd03b5a
SC
1248 {
1249 sym_hash->root.u.def.value -= count;
1250 }
1251 }
1252}
1253
1254/* Look through the relocs for a section during the first phase.
1255 Since we don't do .gots or .plts, we just need to consider the
1256 virtual table relocs for gc. */
1257
b34976b6 1258static bfd_boolean
1fd03b5a
SC
1259elf32_m68hc11_check_relocs (abfd, info, sec, relocs)
1260 bfd * abfd;
1261 struct bfd_link_info * info;
1262 asection * sec;
1263 const Elf_Internal_Rela * relocs;
1264{
1265 Elf_Internal_Shdr * symtab_hdr;
1266 struct elf_link_hash_entry ** sym_hashes;
1267 struct elf_link_hash_entry ** sym_hashes_end;
1268 const Elf_Internal_Rela * rel;
1269 const Elf_Internal_Rela * rel_end;
1270
1271 if (info->relocateable)
b34976b6 1272 return TRUE;
1fd03b5a
SC
1273
1274 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1275 sym_hashes = elf_sym_hashes (abfd);
1276 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1277 if (!elf_bad_symtab (abfd))
1278 sym_hashes_end -= symtab_hdr->sh_info;
1279
1280 rel_end = relocs + sec->reloc_count;
1281
1282 for (rel = relocs; rel < rel_end; rel++)
1283 {
1284 struct elf_link_hash_entry * h;
1285 unsigned long r_symndx;
1286
1287 r_symndx = ELF32_R_SYM (rel->r_info);
1288
1289 if (r_symndx < symtab_hdr->sh_info)
1290 h = NULL;
1291 else
1292 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
1293
1294 switch (ELF32_R_TYPE (rel->r_info))
1295 {
1296 /* This relocation describes the C++ object vtable hierarchy.
1297 Reconstruct it for later use during GC. */
1298 case R_M68HC11_GNU_VTINHERIT:
1299 if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
b34976b6 1300 return FALSE;
1fd03b5a
SC
1301 break;
1302
1303 /* This relocation describes which C++ vtable entries are actually
1304 used. Record for later use during GC. */
1305 case R_M68HC11_GNU_VTENTRY:
1306 if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
b34976b6 1307 return FALSE;
1fd03b5a
SC
1308 break;
1309 }
1310 }
1311
b34976b6 1312 return TRUE;
1fd03b5a
SC
1313}
1314
1315/* Relocate a 68hc11/68hc12 ELF section. */
b34976b6 1316static bfd_boolean
1fd03b5a
SC
1317elf32_m68hc11_relocate_section (output_bfd, info, input_bfd, input_section,
1318 contents, relocs, local_syms, local_sections)
1319 bfd *output_bfd ATTRIBUTE_UNUSED;
1320 struct bfd_link_info *info;
1321 bfd *input_bfd;
1322 asection *input_section;
1323 bfd_byte *contents;
1324 Elf_Internal_Rela *relocs;
1325 Elf_Internal_Sym *local_syms;
1326 asection **local_sections;
1327{
1328 Elf_Internal_Shdr *symtab_hdr;
1329 struct elf_link_hash_entry **sym_hashes;
1330 Elf_Internal_Rela *rel, *relend;
1331 const char *name;
1332
1333 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1334 sym_hashes = elf_sym_hashes (input_bfd);
1335
1336 rel = relocs;
1337 relend = relocs + input_section->reloc_count;
1338 for (; rel < relend; rel++)
1339 {
1340 int r_type;
1341 reloc_howto_type *howto;
1342 unsigned long r_symndx;
1343 Elf_Internal_Sym *sym;
1344 asection *sec;
1345 struct elf_link_hash_entry *h;
1346 bfd_vma relocation;
1347 bfd_reloc_status_type r;
1348
1349 r_symndx = ELF32_R_SYM (rel->r_info);
1350 r_type = ELF32_R_TYPE (rel->r_info);
1351
1352 if (r_type == R_M68HC11_GNU_VTENTRY
1353 || r_type == R_M68HC11_GNU_VTINHERIT )
1354 continue;
1355
1356 howto = elf_m68hc11_howto_table + r_type;
1357
1358 if (info->relocateable)
1359 {
1360 /* This is a relocateable link. We don't have to change
1361 anything, unless the reloc is against a section symbol,
1362 in which case we have to adjust according to where the
1363 section symbol winds up in the output section. */
1364 if (r_symndx < symtab_hdr->sh_info)
1365 {
1366 sym = local_syms + r_symndx;
1367 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1368 {
1369 sec = local_sections[r_symndx];
1370 rel->r_addend += sec->output_offset + sym->st_value;
1371 }
1372 }
1373
1374 continue;
1375 }
1376
1377 /* This is a final link. */
1378 h = NULL;
1379 sym = NULL;
1380 sec = NULL;
1381 if (r_symndx < symtab_hdr->sh_info)
1382 {
1383 sym = local_syms + r_symndx;
1384 sec = local_sections[r_symndx];
1385 relocation = (sec->output_section->vma
1386 + sec->output_offset
1387 + sym->st_value);
1388 }
1389 else
1390 {
1391 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1392 while (h->root.type == bfd_link_hash_indirect
1393 || h->root.type == bfd_link_hash_warning)
1394 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1395 if (h->root.type == bfd_link_hash_defined
1396 || h->root.type == bfd_link_hash_defweak)
1397 {
1398 sec = h->root.u.def.section;
1399 relocation = (h->root.u.def.value
1400 + sec->output_section->vma
1401 + sec->output_offset);
1402 }
1403 else if (h->root.type == bfd_link_hash_undefweak)
1404 relocation = 0;
1405 else
1406 {
1407 if (!((*info->callbacks->undefined_symbol)
1408 (info, h->root.root.string, input_bfd,
b34976b6
AM
1409 input_section, rel->r_offset, TRUE)))
1410 return FALSE;
1fd03b5a
SC
1411 relocation = 0;
1412 }
1413 }
1414
1415 if (h != NULL)
1416 name = h->root.root.string;
1417 else
1418 {
1419 name = (bfd_elf_string_from_elf_section
1420 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1421 if (name == NULL || *name == '\0')
1422 name = bfd_section_name (input_bfd, sec);
1423 }
1424
1425 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1426 contents, rel->r_offset,
1427 relocation, rel->r_addend);
1428
1429 if (r != bfd_reloc_ok)
1430 {
1431 const char * msg = (const char *) 0;
1432
1433 switch (r)
1434 {
1435 case bfd_reloc_overflow:
1436 if (!((*info->callbacks->reloc_overflow)
1437 (info, name, howto->name, (bfd_vma) 0,
1438 input_bfd, input_section, rel->r_offset)))
b34976b6 1439 return FALSE;
1fd03b5a
SC
1440 break;
1441
1442 case bfd_reloc_undefined:
1443 if (!((*info->callbacks->undefined_symbol)
1444 (info, name, input_bfd, input_section,
b34976b6
AM
1445 rel->r_offset, TRUE)))
1446 return FALSE;
1fd03b5a
SC
1447 break;
1448
1449 case bfd_reloc_outofrange:
1450 msg = _ ("internal error: out of range error");
1451 goto common_error;
1452
1453 case bfd_reloc_notsupported:
1454 msg = _ ("internal error: unsupported relocation error");
1455 goto common_error;
1456
1457 case bfd_reloc_dangerous:
1458 msg = _ ("internal error: dangerous error");
1459 goto common_error;
1460
1461 default:
1462 msg = _ ("internal error: unknown error");
1463 /* fall through */
1464
1465 common_error:
1466 if (!((*info->callbacks->warning)
1467 (info, msg, name, input_bfd, input_section,
1468 rel->r_offset)))
b34976b6 1469 return FALSE;
1fd03b5a
SC
1470 break;
1471 }
1472 }
1473 }
1474
b34976b6 1475 return TRUE;
1fd03b5a
SC
1476}
1477
1478
96405e3c
SC
1479\f
1480/* Set and control ELF flags in ELF header. */
1481
b34976b6 1482bfd_boolean
96405e3c
SC
1483_bfd_m68hc11_elf_set_private_flags (abfd, flags)
1484 bfd *abfd;
1485 flagword flags;
1486{
1487 BFD_ASSERT (!elf_flags_init (abfd)
1488 || elf_elfheader (abfd)->e_flags == flags);
1489
1490 elf_elfheader (abfd)->e_flags = flags;
b34976b6
AM
1491 elf_flags_init (abfd) = TRUE;
1492 return TRUE;
96405e3c
SC
1493}
1494
1495/* Merge backend specific data from an object file to the output
1496 object file when linking. */
1497
b34976b6 1498bfd_boolean
96405e3c
SC
1499_bfd_m68hc11_elf_merge_private_bfd_data (ibfd, obfd)
1500 bfd *ibfd;
1501 bfd *obfd;
1502{
1503 flagword old_flags;
1504 flagword new_flags;
b34976b6 1505 bfd_boolean ok = TRUE;
96405e3c
SC
1506
1507 /* Check if we have the same endianess */
b34976b6
AM
1508 if (!_bfd_generic_verify_endian_match (ibfd, obfd))
1509 return FALSE;
96405e3c
SC
1510
1511 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1512 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
b34976b6 1513 return TRUE;
96405e3c
SC
1514
1515 new_flags = elf_elfheader (ibfd)->e_flags;
1516 elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
1517 old_flags = elf_elfheader (obfd)->e_flags;
1518
1519 if (! elf_flags_init (obfd))
1520 {
b34976b6 1521 elf_flags_init (obfd) = TRUE;
96405e3c
SC
1522 elf_elfheader (obfd)->e_flags = new_flags;
1523 elf_elfheader (obfd)->e_ident[EI_CLASS]
1524 = elf_elfheader (ibfd)->e_ident[EI_CLASS];
1525
1526 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1527 && bfd_get_arch_info (obfd)->the_default)
1528 {
1529 if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
1530 bfd_get_mach (ibfd)))
b34976b6 1531 return FALSE;
96405e3c
SC
1532 }
1533
b34976b6 1534 return TRUE;
96405e3c
SC
1535 }
1536
1537 /* Check ABI compatibility. */
1538 if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
1539 {
1540 (*_bfd_error_handler)
1541 (_("%s: linking files compiled for 16-bit integers (-mshort) "
1542 "and others for 32-bit integers"),
1543 bfd_archive_filename (ibfd));
b34976b6 1544 ok = FALSE;
96405e3c
SC
1545 }
1546 if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
1547 {
1548 (*_bfd_error_handler)
1549 (_("%s: linking files compiled for 32-bit double (-fshort-double) "
1550 "and others for 64-bit double"),
1551 bfd_archive_filename (ibfd));
b34976b6 1552 ok = FALSE;
96405e3c
SC
1553 }
1554 new_flags &= ~EF_M68HC11_ABI;
1555 old_flags &= ~EF_M68HC11_ABI;
1556
1557 /* Warn about any other mismatches */
1558 if (new_flags != old_flags)
1559 {
1560 (*_bfd_error_handler)
1561 (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
1562 bfd_archive_filename (ibfd), (unsigned long) new_flags,
1563 (unsigned long) old_flags);
b34976b6 1564 ok = FALSE;
96405e3c
SC
1565 }
1566
1567 if (! ok)
1568 {
1569 bfd_set_error (bfd_error_bad_value);
b34976b6 1570 return FALSE;
96405e3c
SC
1571 }
1572
b34976b6 1573 return TRUE;
96405e3c
SC
1574}
1575
b34976b6 1576bfd_boolean
96405e3c
SC
1577_bfd_m68hc11_elf_print_private_bfd_data (abfd, ptr)
1578 bfd *abfd;
1579 PTR ptr;
1580{
1581 FILE *file = (FILE *) ptr;
1582
1583 BFD_ASSERT (abfd != NULL && ptr != NULL);
1584
1585 /* Print normal ELF private data. */
1586 _bfd_elf_print_private_bfd_data (abfd, ptr);
1587
1588 /* xgettext:c-format */
1589 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1590
1591 if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
1592 fprintf (file, _("[abi=32-bit int,"));
1593 else
1594 fprintf (file, _("[abi=16-bit int,"));
1595
1596 if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
1597 fprintf (file, _(" 64-bit double]"));
1598 else
1599 fprintf (file, _(" 32-bit double]"));
1600
1601 if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
1602 fprintf (file, _(" [memory=bank-model]"));
1603 else
1604 fprintf (file, _(" [memory=flat]"));
1605
1606 fputc ('\n', file);
1607
b34976b6 1608 return TRUE;
96405e3c
SC
1609}
1610
60bcf0fa
NC
1611/* Below is the only difference between elf32-m68hc12.c and elf32-m68hc11.c.
1612 The Motorola spec says to use a different Elf machine code. */
1613#define ELF_ARCH bfd_arch_m68hc11
1614#define ELF_MACHINE_CODE EM_68HC11
1615#define ELF_MAXPAGESIZE 0x1000
1616
1617#define TARGET_BIG_SYM bfd_elf32_m68hc11_vec
1618#define TARGET_BIG_NAME "elf32-m68hc11"
1619
1620#define elf_info_to_howto 0
1621#define elf_info_to_howto_rel m68hc11_info_to_howto_rel
1fd03b5a 1622#define bfd_elf32_bfd_relax_section m68hc11_elf_relax_section
9b701e44
SC
1623#define elf_backend_gc_mark_hook elf32_m68hc11_gc_mark_hook
1624#define elf_backend_gc_sweep_hook elf32_m68hc11_gc_sweep_hook
1fd03b5a
SC
1625#define elf_backend_check_relocs elf32_m68hc11_check_relocs
1626#define elf_backend_relocate_section elf32_m68hc11_relocate_section
60bcf0fa
NC
1627#define elf_backend_object_p 0
1628#define elf_backend_final_write_processing 0
9b701e44 1629#define elf_backend_can_gc_sections 1
96405e3c
SC
1630#define bfd_elf32_bfd_merge_private_bfd_data \
1631 _bfd_m68hc11_elf_merge_private_bfd_data
1632#define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags
1633#define bfd_elf32_bfd_print_private_bfd_data \
1634 _bfd_m68hc11_elf_print_private_bfd_data
1635
60bcf0fa 1636#include "elf32-target.h"
This page took 0.239938 seconds and 4 git commands to generate.