PR savannah/4358:
[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"
3a65329d 27#include "elf32-m68hc1x.h"
60bcf0fa 28#include "elf/m68hc11.h"
3a65329d 29#include "opcode/m68hc11.h"
60bcf0fa 30
3a65329d 31/* Relocation functions. */
60bcf0fa 32static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
56780f18 33 PARAMS ((bfd *, bfd_reloc_code_real_type));
60bcf0fa 34static void m68hc11_info_to_howto_rel
947216bf 35 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
60bcf0fa 36
3a65329d
SC
37/* Trampoline generation. */
38static bfd_boolean m68hc11_elf_size_one_stub
39 PARAMS((struct bfd_hash_entry *gen_entry, PTR in_arg));
40static bfd_boolean m68hc11_elf_build_one_stub
41 PARAMS((struct bfd_hash_entry *gen_entry, PTR in_arg));
42static struct bfd_link_hash_table* m68hc11_elf_bfd_link_hash_table_create
43 PARAMS ((bfd* abfd));
44
45/* Linker relaxation. */
b34976b6
AM
46static bfd_boolean m68hc11_elf_relax_section
47 PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
1fd03b5a 48static void m68hc11_elf_relax_delete_bytes
56780f18 49 PARAMS ((bfd *, asection *, bfd_vma, int));
1fd03b5a 50static void m68hc11_relax_group
56780f18
AM
51 PARAMS ((bfd *, asection *, bfd_byte *, unsigned,
52 unsigned long, unsigned long));
53static int compare_reloc PARAMS ((const void *, const void *));
1fd03b5a 54
60bcf0fa 55/* Use REL instead of RELA to save space */
acf8aed4 56#define USE_REL 1
60bcf0fa 57
3a65329d
SC
58/* The Motorola 68HC11 microcontroller only addresses 64Kb but we also
59 support a memory bank switching mechanism similar to 68HC12.
60bcf0fa 60 We must handle 8 and 16-bit relocations. The 32-bit relocation
3a65329d
SC
61 are used for debugging sections (DWARF2) to represent a virtual
62 address.
60bcf0fa
NC
63 The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
64static reloc_howto_type elf_m68hc11_howto_table[] = {
65 /* This reloc does nothing. */
66 HOWTO (R_M68HC11_NONE, /* type */
67 0, /* rightshift */
68 2, /* size (0 = byte, 1 = short, 2 = long) */
69 32, /* bitsize */
b34976b6 70 FALSE, /* pc_relative */
60bcf0fa 71 0, /* bitpos */
7a897be4 72 complain_overflow_dont,/* complain_on_overflow */
60bcf0fa
NC
73 bfd_elf_generic_reloc, /* special_function */
74 "R_M68HC11_NONE", /* name */
b34976b6 75 FALSE, /* partial_inplace */
60bcf0fa
NC
76 0, /* src_mask */
77 0, /* dst_mask */
b34976b6 78 FALSE), /* pcrel_offset */
60bcf0fa
NC
79
80 /* A 8 bit absolute relocation */
81 HOWTO (R_M68HC11_8, /* type */
82 0, /* rightshift */
83 0, /* size (0 = byte, 1 = short, 2 = long) */
84 8, /* bitsize */
b34976b6 85 FALSE, /* pc_relative */
60bcf0fa
NC
86 0, /* bitpos */
87 complain_overflow_bitfield, /* complain_on_overflow */
88 bfd_elf_generic_reloc, /* special_function */
89 "R_M68HC11_8", /* name */
b34976b6 90 FALSE, /* partial_inplace */
60bcf0fa
NC
91 0x00ff, /* src_mask */
92 0x00ff, /* dst_mask */
b34976b6 93 FALSE), /* pcrel_offset */
60bcf0fa
NC
94
95 /* A 8 bit absolute relocation (upper address) */
96 HOWTO (R_M68HC11_HI8, /* type */
97 8, /* rightshift */
98 0, /* size (0 = byte, 1 = short, 2 = long) */
99 8, /* bitsize */
b34976b6 100 FALSE, /* pc_relative */
60bcf0fa
NC
101 0, /* bitpos */
102 complain_overflow_bitfield, /* complain_on_overflow */
103 bfd_elf_generic_reloc, /* special_function */
104 "R_M68HC11_HI8", /* name */
b34976b6 105 FALSE, /* partial_inplace */
60bcf0fa
NC
106 0x00ff, /* src_mask */
107 0x00ff, /* dst_mask */
b34976b6 108 FALSE), /* pcrel_offset */
60bcf0fa
NC
109
110 /* A 8 bit absolute relocation (upper address) */
111 HOWTO (R_M68HC11_LO8, /* type */
112 0, /* rightshift */
113 0, /* size (0 = byte, 1 = short, 2 = long) */
114 8, /* bitsize */
b34976b6 115 FALSE, /* pc_relative */
60bcf0fa
NC
116 0, /* bitpos */
117 complain_overflow_dont, /* complain_on_overflow */
118 bfd_elf_generic_reloc, /* special_function */
119 "R_M68HC11_LO8", /* name */
b34976b6 120 FALSE, /* partial_inplace */
60bcf0fa
NC
121 0x00ff, /* src_mask */
122 0x00ff, /* dst_mask */
b34976b6 123 FALSE), /* pcrel_offset */
60bcf0fa
NC
124
125 /* A 8 bit PC-rel relocation */
126 HOWTO (R_M68HC11_PCREL_8, /* type */
127 0, /* rightshift */
128 0, /* size (0 = byte, 1 = short, 2 = long) */
129 8, /* bitsize */
b34976b6 130 TRUE, /* pc_relative */
60bcf0fa
NC
131 0, /* bitpos */
132 complain_overflow_bitfield, /* complain_on_overflow */
133 bfd_elf_generic_reloc, /* special_function */
134 "R_M68HC11_PCREL_8", /* name */
b34976b6 135 FALSE, /* partial_inplace */
dae78fb0 136 0x00ff, /* src_mask */
60bcf0fa 137 0x00ff, /* dst_mask */
196486be 138 TRUE), /* pcrel_offset */
60bcf0fa
NC
139
140 /* A 16 bit absolute relocation */
141 HOWTO (R_M68HC11_16, /* type */
142 0, /* rightshift */
143 1, /* size (0 = byte, 1 = short, 2 = long) */
144 16, /* bitsize */
b34976b6 145 FALSE, /* pc_relative */
60bcf0fa
NC
146 0, /* bitpos */
147 complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
148 bfd_elf_generic_reloc, /* special_function */
149 "R_M68HC11_16", /* name */
b34976b6 150 FALSE, /* partial_inplace */
60bcf0fa
NC
151 0xffff, /* src_mask */
152 0xffff, /* dst_mask */
b34976b6 153 FALSE), /* pcrel_offset */
60bcf0fa
NC
154
155 /* A 32 bit absolute relocation. This one is never used for the
156 code relocation. It's used by gas for -gstabs generation. */
157 HOWTO (R_M68HC11_32, /* type */
158 0, /* rightshift */
159 2, /* size (0 = byte, 1 = short, 2 = long) */
160 32, /* bitsize */
b34976b6 161 FALSE, /* pc_relative */
60bcf0fa
NC
162 0, /* bitpos */
163 complain_overflow_bitfield, /* complain_on_overflow */
164 bfd_elf_generic_reloc, /* special_function */
165 "R_M68HC11_32", /* name */
b34976b6 166 FALSE, /* partial_inplace */
60bcf0fa
NC
167 0xffffffff, /* src_mask */
168 0xffffffff, /* dst_mask */
b34976b6 169 FALSE), /* pcrel_offset */
60bcf0fa
NC
170
171 /* A 3 bit absolute relocation */
172 HOWTO (R_M68HC11_3B, /* type */
173 0, /* rightshift */
174 0, /* size (0 = byte, 1 = short, 2 = long) */
175 3, /* bitsize */
b34976b6 176 FALSE, /* pc_relative */
60bcf0fa
NC
177 0, /* bitpos */
178 complain_overflow_bitfield, /* complain_on_overflow */
179 bfd_elf_generic_reloc, /* special_function */
180 "R_M68HC11_4B", /* name */
b34976b6 181 FALSE, /* partial_inplace */
60bcf0fa
NC
182 0x003, /* src_mask */
183 0x003, /* dst_mask */
b34976b6 184 FALSE), /* pcrel_offset */
60bcf0fa
NC
185
186 /* A 16 bit PC-rel relocation */
187 HOWTO (R_M68HC11_PCREL_16, /* type */
188 0, /* rightshift */
189 1, /* size (0 = byte, 1 = short, 2 = long) */
190 16, /* bitsize */
b34976b6 191 TRUE, /* pc_relative */
60bcf0fa
NC
192 0, /* bitpos */
193 complain_overflow_dont, /* complain_on_overflow */
194 bfd_elf_generic_reloc, /* special_function */
195 "R_M68HC11_PCREL_16", /* name */
b34976b6 196 FALSE, /* partial_inplace */
dae78fb0 197 0xffff, /* src_mask */
60bcf0fa 198 0xffff, /* dst_mask */
196486be 199 TRUE), /* pcrel_offset */
60bcf0fa
NC
200
201 /* GNU extension to record C++ vtable hierarchy */
202 HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */
203 0, /* rightshift */
204 1, /* size (0 = byte, 1 = short, 2 = long) */
205 0, /* bitsize */
b34976b6 206 FALSE, /* pc_relative */
60bcf0fa
NC
207 0, /* bitpos */
208 complain_overflow_dont, /* complain_on_overflow */
209 NULL, /* special_function */
210 "R_M68HC11_GNU_VTINHERIT", /* name */
b34976b6 211 FALSE, /* partial_inplace */
60bcf0fa
NC
212 0, /* src_mask */
213 0, /* dst_mask */
b34976b6 214 FALSE), /* pcrel_offset */
60bcf0fa
NC
215
216 /* GNU extension to record C++ vtable member usage */
217 HOWTO (R_M68HC11_GNU_VTENTRY, /* type */
218 0, /* rightshift */
219 1, /* size (0 = byte, 1 = short, 2 = long) */
220 0, /* bitsize */
b34976b6 221 FALSE, /* pc_relative */
60bcf0fa
NC
222 0, /* bitpos */
223 complain_overflow_dont, /* complain_on_overflow */
224 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
225 "R_M68HC11_GNU_VTENTRY", /* name */
b34976b6 226 FALSE, /* partial_inplace */
60bcf0fa
NC
227 0, /* src_mask */
228 0, /* dst_mask */
b34976b6 229 FALSE), /* pcrel_offset */
dae78fb0 230
7a897be4
SC
231 /* A 24 bit relocation */
232 HOWTO (R_M68HC11_24, /* type */
233 0, /* rightshift */
234 1, /* size (0 = byte, 1 = short, 2 = long) */
235 24, /* bitsize */
b34976b6 236 FALSE, /* pc_relative */
7a897be4
SC
237 0, /* bitpos */
238 complain_overflow_bitfield, /* complain_on_overflow */
239 bfd_elf_generic_reloc, /* special_function */
240 "R_M68HC11_24", /* name */
b34976b6 241 FALSE, /* partial_inplace */
196486be
SC
242 0xffffff, /* src_mask */
243 0xffffff, /* dst_mask */
b34976b6
AM
244 FALSE), /* pcrel_offset */
245
7a897be4
SC
246 /* A 16-bit low relocation */
247 HOWTO (R_M68HC11_LO16, /* type */
248 0, /* rightshift */
249 1, /* size (0 = byte, 1 = short, 2 = long) */
250 16, /* bitsize */
b34976b6 251 FALSE, /* pc_relative */
7a897be4
SC
252 0, /* bitpos */
253 complain_overflow_bitfield, /* complain_on_overflow */
254 bfd_elf_generic_reloc, /* special_function */
255 "R_M68HC11_LO16", /* name */
b34976b6 256 FALSE, /* partial_inplace */
7a897be4
SC
257 0xffff, /* src_mask */
258 0xffff, /* dst_mask */
b34976b6 259 FALSE), /* pcrel_offset */
7a897be4
SC
260
261 /* A page relocation */
262 HOWTO (R_M68HC11_PAGE, /* type */
263 0, /* rightshift */
264 0, /* size (0 = byte, 1 = short, 2 = long) */
265 8, /* bitsize */
b34976b6 266 FALSE, /* pc_relative */
7a897be4
SC
267 0, /* bitpos */
268 complain_overflow_bitfield, /* complain_on_overflow */
269 bfd_elf_generic_reloc, /* special_function */
270 "R_M68HC11_PAGE", /* name */
b34976b6 271 FALSE, /* partial_inplace */
7a897be4
SC
272 0x00ff, /* src_mask */
273 0x00ff, /* dst_mask */
b34976b6 274 FALSE), /* pcrel_offset */
7a897be4 275
dae78fb0
SC
276 EMPTY_HOWTO (14),
277 EMPTY_HOWTO (15),
278 EMPTY_HOWTO (16),
279 EMPTY_HOWTO (17),
280 EMPTY_HOWTO (18),
281 EMPTY_HOWTO (19),
b34976b6 282
dae78fb0
SC
283 /* Mark beginning of a jump instruction (any form). */
284 HOWTO (R_M68HC11_RL_JUMP, /* type */
285 0, /* rightshift */
286 1, /* size (0 = byte, 1 = short, 2 = long) */
287 0, /* bitsize */
b34976b6 288 FALSE, /* pc_relative */
dae78fb0
SC
289 0, /* bitpos */
290 complain_overflow_dont, /* complain_on_overflow */
291 m68hc11_elf_ignore_reloc, /* special_function */
292 "R_M68HC11_RL_JUMP", /* name */
b34976b6 293 TRUE, /* partial_inplace */
dae78fb0
SC
294 0, /* src_mask */
295 0, /* dst_mask */
b34976b6 296 TRUE), /* pcrel_offset */
dae78fb0
SC
297
298 /* Mark beginning of Gcc relaxation group instruction. */
299 HOWTO (R_M68HC11_RL_GROUP, /* type */
300 0, /* rightshift */
301 1, /* size (0 = byte, 1 = short, 2 = long) */
302 0, /* bitsize */
b34976b6 303 FALSE, /* pc_relative */
dae78fb0
SC
304 0, /* bitpos */
305 complain_overflow_dont, /* complain_on_overflow */
306 m68hc11_elf_ignore_reloc, /* special_function */
307 "R_M68HC11_RL_GROUP", /* name */
b34976b6 308 TRUE, /* partial_inplace */
dae78fb0
SC
309 0, /* src_mask */
310 0, /* dst_mask */
b34976b6 311 TRUE), /* pcrel_offset */
60bcf0fa
NC
312};
313
314/* Map BFD reloc types to M68HC11 ELF reloc types. */
315
316struct m68hc11_reloc_map
317{
318 bfd_reloc_code_real_type bfd_reloc_val;
319 unsigned char elf_reloc_val;
320};
321
322static const struct m68hc11_reloc_map m68hc11_reloc_map[] = {
323 {BFD_RELOC_NONE, R_M68HC11_NONE,},
324 {BFD_RELOC_8, R_M68HC11_8},
325 {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
326 {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
327 {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
328 {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
329 {BFD_RELOC_16, R_M68HC11_16},
330 {BFD_RELOC_32, R_M68HC11_32},
331 {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
332
60bcf0fa
NC
333 {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
334 {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
dae78fb0 335
7a897be4
SC
336 {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
337 {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
338 {BFD_RELOC_M68HC11_24, R_M68HC11_24},
339
dae78fb0
SC
340 {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
341 {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
60bcf0fa
NC
342};
343
344static reloc_howto_type *
345bfd_elf32_bfd_reloc_type_lookup (abfd, code)
346 bfd *abfd ATTRIBUTE_UNUSED;
347 bfd_reloc_code_real_type code;
348{
349 unsigned int i;
350
351 for (i = 0;
352 i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
353 i++)
354 {
355 if (m68hc11_reloc_map[i].bfd_reloc_val == code)
356 return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
357 }
358
359 return NULL;
360}
361
362/* Set the howto pointer for an M68HC11 ELF reloc. */
363
364static void
365m68hc11_info_to_howto_rel (abfd, cache_ptr, dst)
366 bfd *abfd ATTRIBUTE_UNUSED;
367 arelent *cache_ptr;
947216bf 368 Elf_Internal_Rela *dst;
60bcf0fa
NC
369{
370 unsigned int r_type;
371
372 r_type = ELF32_R_TYPE (dst->r_info);
373 BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
374 cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
375}
376
3a65329d
SC
377\f
378/* Far trampoline generation. */
9b701e44 379
3a65329d
SC
380/* Build a 68HC11 trampoline stub. */
381static bfd_boolean
382m68hc11_elf_build_one_stub (gen_entry, in_arg)
383 struct bfd_hash_entry *gen_entry;
384 PTR in_arg;
385{
386 struct elf32_m68hc11_stub_hash_entry *stub_entry;
387 struct bfd_link_info *info;
388 struct m68hc11_elf_link_hash_table *htab;
389 asection *stub_sec;
390 bfd *stub_bfd;
391 bfd_byte *loc;
392 bfd_vma sym_value, phys_page, phys_addr;
393
394 /* Massage our args to the form they really have. */
395 stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
396 info = (struct bfd_link_info *) in_arg;
397
398 htab = m68hc11_elf_hash_table (info);
399
400 stub_sec = stub_entry->stub_sec;
401
402 /* Make a note of the offset within the stubs for this entry. */
403 stub_entry->stub_offset = stub_sec->_raw_size;
404 stub_sec->_raw_size += 10;
405 loc = stub_sec->contents + stub_entry->stub_offset;
406
407 stub_bfd = stub_sec->owner;
408
409 /* Create the trampoline call stub:
410
411 pshb
412 ldab #%page(symbol)
413 ldy #%addr(symbol)
414 jmp __trampoline
415
416 */
417 sym_value = (stub_entry->target_value
418 + stub_entry->target_section->output_offset
419 + stub_entry->target_section->output_section->vma);
420 phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value);
421 phys_page = m68hc11_phys_page (&htab->pinfo, sym_value);
422
423 /* pshb; ldab #%page(sym) */
424 bfd_put_8 (stub_bfd, 0x37, loc);
425 bfd_put_8 (stub_bfd, 0xC6, loc + 1);
426 bfd_put_8 (stub_bfd, phys_page, loc + 2);
427 loc += 3;
428
429 /* ldy #%addr(sym) */
430 bfd_put_8 (stub_bfd, 0x18, loc);
431 bfd_put_8 (stub_bfd, 0xCE, loc + 1);
432 bfd_put_16 (stub_bfd, phys_addr, loc + 2);
433 loc += 4;
434
435 /* jmp __trampoline */
436 bfd_put_8 (stub_bfd, 0x7E, loc);
437 bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1);
56780f18 438
3a65329d 439 return TRUE;
9b701e44
SC
440}
441
3a65329d
SC
442/* As above, but don't actually build the stub. Just bump offset so
443 we know stub section sizes. */
444
b34976b6 445static bfd_boolean
3a65329d
SC
446m68hc11_elf_size_one_stub (gen_entry, in_arg)
447 struct bfd_hash_entry *gen_entry;
448 PTR in_arg ATTRIBUTE_UNUSED;
9b701e44 449{
3a65329d
SC
450 struct elf32_m68hc11_stub_hash_entry *stub_entry;
451
452 /* Massage our args to the form they really have. */
453 stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
454
455 stub_entry->stub_sec->_raw_size += 10;
b34976b6 456 return TRUE;
9b701e44
SC
457}
458
3a65329d
SC
459/* Create a 68HC11 ELF linker hash table. */
460
461static struct bfd_link_hash_table *
462m68hc11_elf_bfd_link_hash_table_create (abfd)
463 bfd *abfd;
464{
465 struct m68hc11_elf_link_hash_table *ret;
466
467 ret = m68hc11_elf_hash_table_create (abfd);
468 if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
469 return NULL;
470
471 ret->size_one_stub = m68hc11_elf_size_one_stub;
472 ret->build_one_stub = m68hc11_elf_build_one_stub;
473
474 return &ret->root.root;
475}
476
196486be
SC
477\f
478/* 68HC11 Linker Relaxation. */
479
b34976b6 480struct m68hc11_direct_relax
1fd03b5a
SC
481{
482 const char *name;
483 unsigned char code;
484 unsigned char direct_code;
485} m68hc11_direct_relax_table[] = {
486 { "adca", 0xB9, 0x99 },
487 { "adcb", 0xF9, 0xD9 },
488 { "adda", 0xBB, 0x9B },
489 { "addb", 0xFB, 0xDB },
490 { "addd", 0xF3, 0xD3 },
491 { "anda", 0xB4, 0x94 },
492 { "andb", 0xF4, 0xD4 },
493 { "cmpa", 0xB1, 0x91 },
494 { "cmpb", 0xF1, 0xD1 },
495 { "cpd", 0xB3, 0x93 },
496 { "cpxy", 0xBC, 0x9C },
497/* { "cpy", 0xBC, 0x9C }, */
498 { "eora", 0xB8, 0x98 },
499 { "eorb", 0xF8, 0xD8 },
500 { "jsr", 0xBD, 0x9D },
501 { "ldaa", 0xB6, 0x96 },
502 { "ldab", 0xF6, 0xD6 },
503 { "ldd", 0xFC, 0xDC },
504 { "lds", 0xBE, 0x9E },
505 { "ldxy", 0xFE, 0xDE },
506 /* { "ldy", 0xFE, 0xDE },*/
507 { "oraa", 0xBA, 0x9A },
508 { "orab", 0xFA, 0xDA },
509 { "sbca", 0xB2, 0x92 },
510 { "sbcb", 0xF2, 0xD2 },
511 { "staa", 0xB7, 0x97 },
512 { "stab", 0xF7, 0xD7 },
513 { "std", 0xFD, 0xDD },
514 { "sts", 0xBF, 0x9F },
515 { "stxy", 0xFF, 0xDF },
516 /* { "sty", 0xFF, 0xDF },*/
517 { "suba", 0xB0, 0x90 },
518 { "subb", 0xF0, 0xD0 },
519 { "subd", 0xB3, 0x93 },
520 { 0, 0, 0 }
521};
522
523static struct m68hc11_direct_relax *
524find_relaxable_insn (unsigned char code)
525{
526 int i;
527
528 for (i = 0; m68hc11_direct_relax_table[i].name; i++)
529 if (m68hc11_direct_relax_table[i].code == code)
530 return &m68hc11_direct_relax_table[i];
531
532 return 0;
533}
534
535static int
536compare_reloc (e1, e2)
537 const void *e1;
538 const void *e2;
539{
540 const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1;
541 const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2;
542
543 if (i1->r_offset == i2->r_offset)
544 return 0;
545 else
546 return i1->r_offset < i2->r_offset ? -1 : 1;
547}
548
549#define M6811_OP_LDX_IMMEDIATE (0xCE)
550
551static void
552m68hc11_relax_group (abfd, sec, contents, value, offset, end_group)
553 bfd *abfd;
554 asection *sec;
555 bfd_byte *contents;
556 unsigned value;
557 unsigned long offset;
558 unsigned long end_group;
559{
560 unsigned char code;
561 unsigned long start_offset;
562 unsigned long ldx_offset = offset;
563 unsigned long ldx_size;
564 int can_delete_ldx;
565 int relax_ldy = 0;
566
567 /* First instruction of the relax group must be a
568 LDX #value or LDY #value. If this is not the case,
569 ignore the relax group. */
570 code = bfd_get_8 (abfd, contents + offset);
571 if (code == 0x18)
572 {
573 relax_ldy++;
574 offset++;
575 code = bfd_get_8 (abfd, contents + offset);
576 }
577 ldx_size = offset - ldx_offset + 3;
578 offset += 3;
579 if (code != M6811_OP_LDX_IMMEDIATE || offset >= end_group)
580 return;
581
582
583 /* We can remove the LDX/LDY only when all bset/brclr instructions
584 of the relax group have been converted to use direct addressing
585 mode. */
586 can_delete_ldx = 1;
587 while (offset < end_group)
588 {
589 unsigned isize;
590 unsigned new_value;
591 int bset_use_y;
592
593 bset_use_y = 0;
594 start_offset = offset;
595 code = bfd_get_8 (abfd, contents + offset);
596 if (code == 0x18)
597 {
598 bset_use_y++;
599 offset++;
600 code = bfd_get_8 (abfd, contents + offset);
601 }
602
603 /* Check the instruction and translate to use direct addressing mode. */
604 switch (code)
605 {
606 /* bset */
607 case 0x1C:
608 code = 0x14;
609 isize = 3;
610 break;
611
612 /* brclr */
613 case 0x1F:
614 code = 0x13;
615 isize = 4;
616 break;
617
618 /* brset */
619 case 0x1E:
620 code = 0x12;
621 isize = 4;
622 break;
623
624 /* bclr */
625 case 0x1D:
626 code = 0x15;
627 isize = 3;
628 break;
629
630 /* This instruction is not recognized and we are not
631 at end of the relax group. Ignore and don't remove
632 the first LDX (we don't know what it is used for...). */
633 default:
634 return;
635 }
636 new_value = (unsigned) bfd_get_8 (abfd, contents + offset + 1);
637 new_value += value;
638 if ((new_value & 0xff00) == 0 && bset_use_y == relax_ldy)
639 {
640 bfd_put_8 (abfd, code, contents + offset);
641 bfd_put_8 (abfd, new_value, contents + offset + 1);
642 if (start_offset != offset)
643 {
644 m68hc11_elf_relax_delete_bytes (abfd, sec, start_offset,
645 offset - start_offset);
646 end_group--;
647 }
648 }
649 else
650 {
651 can_delete_ldx = 0;
652 }
653 offset = start_offset + isize;
654 }
655 if (can_delete_ldx)
656 {
657 /* Remove the move instruction (3 or 4 bytes win). */
658 m68hc11_elf_relax_delete_bytes (abfd, sec, ldx_offset, ldx_size);
659 }
660}
661
662/* This function handles relaxing for the 68HC11.
663
b34976b6 664
1fd03b5a
SC
665 and somewhat more difficult to support. */
666
b34976b6 667static bfd_boolean
1fd03b5a
SC
668m68hc11_elf_relax_section (abfd, sec, link_info, again)
669 bfd *abfd;
670 asection *sec;
671 struct bfd_link_info *link_info;
b34976b6 672 bfd_boolean *again;
1fd03b5a
SC
673{
674 Elf_Internal_Shdr *symtab_hdr;
675 Elf_Internal_Shdr *shndx_hdr;
676 Elf_Internal_Rela *internal_relocs;
677 Elf_Internal_Rela *free_relocs = NULL;
678 Elf_Internal_Rela *irel, *irelend;
679 bfd_byte *contents = NULL;
680 bfd_byte *free_contents = NULL;
1fd03b5a
SC
681 Elf32_External_Sym *free_extsyms = NULL;
682 Elf_Internal_Rela *prev_insn_branch = NULL;
683 Elf_Internal_Rela *prev_insn_group = NULL;
684 unsigned insn_group_value = 0;
1f4c5b47 685 Elf_Internal_Sym *isymbuf = NULL;
1fd03b5a
SC
686
687 /* Assume nothing changes. */
b34976b6 688 *again = FALSE;
1fd03b5a 689
1049f94e 690 /* We don't have to do anything for a relocatable link, if
1fd03b5a
SC
691 this section does not have relocs, or if this is not a
692 code section. */
1049f94e 693 if (link_info->relocatable
1fd03b5a
SC
694 || (sec->flags & SEC_RELOC) == 0
695 || sec->reloc_count == 0
696 || (sec->flags & SEC_CODE) == 0)
b34976b6 697 return TRUE;
1fd03b5a
SC
698
699 /* If this is the first time we have been called for this section,
700 initialize the cooked size. */
701 if (sec->_cooked_size == 0)
702 sec->_cooked_size = sec->_raw_size;
703
704 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
705 shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
706
707 /* Get a copy of the native relocations. */
45d6a902 708 internal_relocs = (_bfd_elf_link_read_relocs
1fd03b5a
SC
709 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
710 link_info->keep_memory));
711 if (internal_relocs == NULL)
712 goto error_return;
713 if (! link_info->keep_memory)
714 free_relocs = internal_relocs;
715
716 /* Checking for branch relaxation relies on the relocations to
717 be sorted on 'r_offset'. This is not guaranteed so we must sort. */
718 qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
719 compare_reloc);
720
721 /* Walk through them looking for relaxing opportunities. */
722 irelend = internal_relocs + sec->reloc_count;
723 for (irel = internal_relocs; irel < irelend; irel++)
724 {
725 bfd_vma symval;
726 bfd_vma value;
1f4c5b47 727 Elf_Internal_Sym *isym;
9b691193 728 asection *sym_sec;
196486be 729 int is_far = 0;
1fd03b5a
SC
730
731 /* If this isn't something that can be relaxed, then ignore
732 this reloc. */
733 if (ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_16
734 && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_JUMP
735 && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_GROUP)
736 {
737 prev_insn_branch = 0;
738 prev_insn_group = 0;
739 continue;
740 }
741
742 /* Get the section contents if we haven't done so already. */
743 if (contents == NULL)
744 {
745 /* Get cached copy if it exists. */
746 if (elf_section_data (sec)->this_hdr.contents != NULL)
747 contents = elf_section_data (sec)->this_hdr.contents;
748 else
749 {
750 /* Go get them off disk. */
751 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
752 if (contents == NULL)
753 goto error_return;
754 free_contents = contents;
755
756 if (! bfd_get_section_contents (abfd, sec, contents,
757 (file_ptr) 0, sec->_raw_size))
758 goto error_return;
759 }
760 }
761
762 /* Try to eliminate an unconditional 8 bit pc-relative branch
763 which immediately follows a conditional 8 bit pc-relative
764 branch around the unconditional branch.
765
766 original: new:
767 bCC lab1 bCC' lab2
768 bra lab2
769 lab1: lab1:
770
771 This happens when the bCC can't reach lab2 at assembly time,
772 but due to other relaxations it can reach at link time. */
773 if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_JUMP)
774 {
775 Elf_Internal_Rela *nrel;
776 unsigned char code;
777 unsigned char roffset;
778
779 prev_insn_branch = 0;
780 prev_insn_group = 0;
b34976b6 781
1fd03b5a 782 /* Do nothing if this reloc is the last byte in the section. */
196486be 783 if (irel->r_offset + 2 >= sec->_cooked_size)
1fd03b5a
SC
784 continue;
785
786 /* See if the next instruction is an unconditional pc-relative
787 branch, more often than not this test will fail, so we
788 test it first to speed things up. */
789 code = bfd_get_8 (abfd, contents + irel->r_offset + 2);
790 if (code != 0x7e)
791 continue;
792
793 /* Also make sure the next relocation applies to the next
794 instruction and that it's a pc-relative 8 bit branch. */
795 nrel = irel + 1;
796 if (nrel == irelend
797 || irel->r_offset + 3 != nrel->r_offset
798 || ELF32_R_TYPE (nrel->r_info) != (int) R_M68HC11_16)
799 continue;
800
801 /* Make sure our destination immediately follows the
802 unconditional branch. */
803 roffset = bfd_get_8 (abfd, contents + irel->r_offset + 1);
804 if (roffset != 3)
805 continue;
806
807 prev_insn_branch = irel;
808 prev_insn_group = 0;
809 continue;
810 }
811
812 /* Read this BFD's symbols if we haven't done so already. */
1f4c5b47 813 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1fd03b5a 814 {
1f4c5b47
SC
815 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
816 if (isymbuf == NULL)
817 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
818 symtab_hdr->sh_info, 0,
819 NULL, NULL, NULL);
820 if (isymbuf == NULL)
821 goto error_return;
1fd03b5a
SC
822 }
823
824 /* Get the value of the symbol referred to by the reloc. */
825 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
826 {
1fd03b5a 827 /* A local symbol. */
1f4c5b47 828 isym = isymbuf + ELF32_R_SYM (irel->r_info);
196486be 829 is_far = isym->st_other & STO_M68HC12_FAR;
1f4c5b47
SC
830 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
831 symval = (isym->st_value
1fd03b5a
SC
832 + sym_sec->output_section->vma
833 + sym_sec->output_offset);
834 }
835 else
836 {
837 unsigned long indx;
838 struct elf_link_hash_entry *h;
839
840 /* An external symbol. */
841 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
842 h = elf_sym_hashes (abfd)[indx];
843 BFD_ASSERT (h != NULL);
844 if (h->root.type != bfd_link_hash_defined
845 && h->root.type != bfd_link_hash_defweak)
846 {
847 /* This appears to be a reference to an undefined
848 symbol. Just ignore it--it will be caught by the
849 regular reloc processing. */
850 prev_insn_branch = 0;
851 prev_insn_group = 0;
852 continue;
853 }
854
196486be 855 is_far = h->other & STO_M68HC12_FAR;
9b691193
SC
856 isym = 0;
857 sym_sec = h->root.u.def.section;
1fd03b5a 858 symval = (h->root.u.def.value
9b691193
SC
859 + sym_sec->output_section->vma
860 + sym_sec->output_offset);
1fd03b5a
SC
861 }
862
863 if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_GROUP)
864 {
865 prev_insn_branch = 0;
866 prev_insn_group = 0;
b34976b6 867
1fd03b5a
SC
868 /* Do nothing if this reloc is the last byte in the section. */
869 if (irel->r_offset == sec->_cooked_size)
870 continue;
871
872 prev_insn_group = irel;
1f4c5b47 873 insn_group_value = isym->st_value;
1fd03b5a
SC
874 continue;
875 }
876
9b691193
SC
877 /* When we relax some bytes, the size of our section changes.
878 This affects the layout of next input sections that go in our
879 output section. When the symbol is part of another section that
880 will go in the same output section as the current one, it's
881 final address may now be incorrect (too far). We must let the
882 linker re-compute all section offsets before processing this
883 reloc. Code example:
884
885 Initial Final
886 .sect .text section size = 6 section size = 4
887 jmp foo
888 jmp bar
889 .sect .text.foo_bar output_offset = 6 output_offset = 4
890 foo: rts
891 bar: rts
892
893 If we process the reloc now, the jmp bar is replaced by a
894 relative branch to the initial bar address (output_offset 6). */
895 if (*again && sym_sec != sec
896 && sym_sec->output_section == sec->output_section)
897 {
898 prev_insn_group = 0;
899 prev_insn_branch = 0;
900 continue;
901 }
b34976b6 902
1fd03b5a
SC
903 value = symval;
904 /* Try to turn a far branch to a near branch. */
905 if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
906 && prev_insn_branch)
907 {
908 bfd_vma offset;
909 unsigned char code;
910
911 offset = value - (prev_insn_branch->r_offset
912 + sec->output_section->vma
913 + sec->output_offset + 2);
914
915 /* If the offset is still out of -128..+127 range,
916 leave that far branch unchanged. */
917 if ((offset & 0xff80) != 0 && (offset & 0xff80) != 0xff80)
918 {
919 prev_insn_branch = 0;
920 continue;
921 }
922
923 /* Shrink the branch. */
924 code = bfd_get_8 (abfd, contents + prev_insn_branch->r_offset);
925 if (code == 0x7e)
926 {
927 code = 0x20;
928 bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
196486be 929 bfd_put_8 (abfd, 0xff,
1fd03b5a 930 contents + prev_insn_branch->r_offset + 1);
196486be 931 irel->r_offset = prev_insn_branch->r_offset + 1;
1fd03b5a 932 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
196486be 933 R_M68HC11_PCREL_8);
1fd03b5a 934 m68hc11_elf_relax_delete_bytes (abfd, sec,
196486be 935 irel->r_offset + 1, 1);
1fd03b5a
SC
936 }
937 else
938 {
939 code ^= 0x1;
940 bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
196486be 941 bfd_put_8 (abfd, 0xff,
1fd03b5a 942 contents + prev_insn_branch->r_offset + 1);
196486be 943 irel->r_offset = prev_insn_branch->r_offset + 1;
1fd03b5a 944 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
196486be 945 R_M68HC11_PCREL_8);
1fd03b5a 946 m68hc11_elf_relax_delete_bytes (abfd, sec,
196486be 947 irel->r_offset + 1, 3);
1fd03b5a
SC
948 }
949 prev_insn_branch = 0;
b34976b6 950 *again = TRUE;
1fd03b5a
SC
951 }
952
953 /* Try to turn a 16 bit address into a 8 bit page0 address. */
954 else if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
955 && (value & 0xff00) == 0)
956 {
957 unsigned char code;
958 unsigned short offset;
959 struct m68hc11_direct_relax *rinfo;
960
961 prev_insn_branch = 0;
962 offset = bfd_get_16 (abfd, contents + irel->r_offset);
963 offset += value;
964 if ((offset & 0xff00) != 0)
965 {
966 prev_insn_group = 0;
967 continue;
968 }
969
970 if (prev_insn_group)
971 {
9b691193 972 unsigned long old_sec_size = sec->_cooked_size;
b34976b6 973
1fd03b5a
SC
974 /* Note that we've changed the reldection contents, etc. */
975 elf_section_data (sec)->relocs = internal_relocs;
976 free_relocs = NULL;
977
978 elf_section_data (sec)->this_hdr.contents = contents;
979 free_contents = NULL;
980
1f4c5b47 981 symtab_hdr->contents = (bfd_byte *) isymbuf;
1fd03b5a
SC
982 free_extsyms = NULL;
983
984 m68hc11_relax_group (abfd, sec, contents, offset,
985 prev_insn_group->r_offset,
986 insn_group_value);
987 irel = prev_insn_group;
988 prev_insn_group = 0;
989 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
990 R_M68HC11_NONE);
9b691193 991 if (sec->_cooked_size != old_sec_size)
b34976b6 992 *again = TRUE;
1fd03b5a
SC
993 continue;
994 }
b34976b6 995
1fd03b5a
SC
996 /* Get the opcode. */
997 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
998 rinfo = find_relaxable_insn (code);
999 if (rinfo == 0)
1000 {
1001 prev_insn_group = 0;
1002 continue;
1003 }
1004
1005 /* Note that we've changed the reldection contents, etc. */
1006 elf_section_data (sec)->relocs = internal_relocs;
1007 free_relocs = NULL;
1008
1009 elf_section_data (sec)->this_hdr.contents = contents;
1010 free_contents = NULL;
1011
1f4c5b47 1012 symtab_hdr->contents = (bfd_byte *) isymbuf;
1fd03b5a
SC
1013 free_extsyms = NULL;
1014
1015 /* Fix the opcode. */
1016 /* printf ("A relaxable case : 0x%02x (%s)\n",
1017 code, rinfo->name); */
1018 bfd_put_8 (abfd, rinfo->direct_code,
1019 contents + irel->r_offset - 1);
1020
1021 /* Delete one byte of data (upper byte of address). */
1022 m68hc11_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 1);
1023
1024 /* Fix the relocation's type. */
1025 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1026 R_M68HC11_8);
1027
9b691193 1028 /* That will change things, so, we should relax again. */
b34976b6 1029 *again = TRUE;
1fd03b5a 1030 }
196486be 1031 else if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_16 && !is_far)
1fd03b5a
SC
1032 {
1033 unsigned char code;
1034 bfd_vma offset;
1035
1036 prev_insn_branch = 0;
1037 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
196486be 1038 if (code == 0x7e || code == 0xbd)
1fd03b5a
SC
1039 {
1040 offset = value - (irel->r_offset
1041 + sec->output_section->vma
1042 + sec->output_offset + 1);
1043 offset += bfd_get_16 (abfd, contents + irel->r_offset);
1044
1045 /* If the offset is still out of -128..+127 range,
1046 leave that far branch unchanged. */
1047 if ((offset & 0xff80) == 0 || (offset & 0xff80) == 0xff80)
1048 {
1049
1050 /* Note that we've changed the reldection contents, etc. */
1051 elf_section_data (sec)->relocs = internal_relocs;
1052 free_relocs = NULL;
b34976b6 1053
1fd03b5a
SC
1054 elf_section_data (sec)->this_hdr.contents = contents;
1055 free_contents = NULL;
b34976b6 1056
1f4c5b47 1057 symtab_hdr->contents = (bfd_byte *) isymbuf;
1fd03b5a
SC
1058 free_extsyms = NULL;
1059
1060 /* Shrink the branch. */
196486be 1061 code = (code == 0x7e) ? 0x20 : 0x8d;
1fd03b5a
SC
1062 bfd_put_8 (abfd, code,
1063 contents + irel->r_offset - 1);
196486be 1064 bfd_put_8 (abfd, 0xff,
1fd03b5a
SC
1065 contents + irel->r_offset);
1066 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
196486be 1067 R_M68HC11_PCREL_8);
1fd03b5a
SC
1068 m68hc11_elf_relax_delete_bytes (abfd, sec,
1069 irel->r_offset + 1, 1);
9b691193 1070 /* That will change things, so, we should relax again. */
b34976b6 1071 *again = TRUE;
1fd03b5a
SC
1072 }
1073 }
1074 }
1075 prev_insn_branch = 0;
d204f4c0 1076 prev_insn_group = 0;
1fd03b5a
SC
1077 }
1078
1079 if (free_relocs != NULL)
1080 {
1081 free (free_relocs);
1082 free_relocs = NULL;
1083 }
1084
1085 if (free_contents != NULL)
1086 {
1087 if (! link_info->keep_memory)
1088 free (free_contents);
1089 else
1090 {
1091 /* Cache the section contents for elf_link_input_bfd. */
1092 elf_section_data (sec)->this_hdr.contents = contents;
1093 }
1094 free_contents = NULL;
1095 }
1096
1097 if (free_extsyms != NULL)
1098 {
1099 if (! link_info->keep_memory)
1100 free (free_extsyms);
1101 else
1102 {
1103 /* Cache the symbols for elf_link_input_bfd. */
1f4c5b47 1104 symtab_hdr->contents = (unsigned char *) isymbuf;
1fd03b5a
SC
1105 }
1106 free_extsyms = NULL;
1107 }
1108
b34976b6 1109 return TRUE;
1fd03b5a
SC
1110
1111 error_return:
1112 if (free_relocs != NULL)
1113 free (free_relocs);
1114 if (free_contents != NULL)
1115 free (free_contents);
1116 if (free_extsyms != NULL)
1117 free (free_extsyms);
b34976b6 1118 return FALSE;
1fd03b5a
SC
1119}
1120
1121/* Delete some bytes from a section while relaxing. */
1122
1123static void
1124m68hc11_elf_relax_delete_bytes (abfd, sec, addr, count)
1125 bfd *abfd;
1126 asection *sec;
1127 bfd_vma addr;
1128 int count;
1129{
1130 Elf_Internal_Shdr *symtab_hdr;
1fd03b5a 1131 unsigned int sec_shndx;
1fd03b5a
SC
1132 bfd_byte *contents;
1133 Elf_Internal_Rela *irel, *irelend;
1134 bfd_vma toaddr;
1f4c5b47 1135 Elf_Internal_Sym *isymbuf, *isym, *isymend;
1fd03b5a
SC
1136 struct elf_link_hash_entry **sym_hashes;
1137 struct elf_link_hash_entry **end_hashes;
1138 unsigned int symcount;
1139
1140 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1f4c5b47 1141 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1fd03b5a
SC
1142
1143 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1144
1145 contents = elf_section_data (sec)->this_hdr.contents;
1146
1147 toaddr = sec->_cooked_size;
1148
1149 irel = elf_section_data (sec)->relocs;
1150 irelend = irel + sec->reloc_count;
1151
1152 /* Actually delete the bytes. */
1153 memmove (contents + addr, contents + addr + count,
1154 (size_t) (toaddr - addr - count));
1fd03b5a 1155
1f4c5b47 1156 sec->_cooked_size -= count;
b34976b6 1157
1fd03b5a
SC
1158 /* Adjust all the relocs. */
1159 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1160 {
1161 unsigned char code;
1162 unsigned char offset;
1163 unsigned short raddr;
1164 unsigned long old_offset;
1165 int branch_pos;
1166
1167 old_offset = irel->r_offset;
1168
1169 /* See if this reloc was for the bytes we have deleted, in which
1170 case we no longer care about it. Don't delete relocs which
1171 represent addresses, though. */
1172 if (ELF32_R_TYPE (irel->r_info) != R_M68HC11_RL_JUMP
1173 && irel->r_offset >= addr && irel->r_offset < addr + count)
1174 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1175 R_M68HC11_NONE);
1176
1177 if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_NONE)
1178 continue;
1179
1180 /* Get the new reloc address. */
1181 if ((irel->r_offset > addr
1182 && irel->r_offset < toaddr))
1183 irel->r_offset -= count;
1184
1185 /* If this is a PC relative reloc, see if the range it covers
1186 includes the bytes we have deleted. */
1187 switch (ELF32_R_TYPE (irel->r_info))
1188 {
1189 default:
1190 break;
1191
1192 case R_M68HC11_RL_JUMP:
1193 code = bfd_get_8 (abfd, contents + irel->r_offset);
1194 switch (code)
1195 {
1196 /* jsr and jmp instruction are also marked with RL_JUMP
1197 relocs but no adjustment must be made. */
1198 case 0x7e:
1199 case 0x9d:
1200 case 0xbd:
1201 continue;
1202
1203 case 0x12:
1204 case 0x13:
1205 branch_pos = 3;
1206 raddr = 4;
1207
1208 /* Special case when we translate a brclr N,y into brclr *<addr>
1209 In this case, the 0x18 page2 prefix is removed.
1210 The reloc offset is not modified but the instruction
1211 size is reduced by 1. */
1212 if (old_offset == addr)
1213 raddr++;
1214 break;
1215
1216 case 0x1e:
1217 case 0x1f:
1218 branch_pos = 3;
1219 raddr = 4;
1220 break;
1221
1222 case 0x18:
1223 branch_pos = 4;
1224 raddr = 5;
1225 break;
1226
1227 default:
1228 branch_pos = 1;
1229 raddr = 2;
1230 break;
1231 }
1232 offset = bfd_get_8 (abfd, contents + irel->r_offset + branch_pos);
1233 raddr += old_offset;
1234 raddr += ((unsigned short) offset | ((offset & 0x80) ? 0xff00 : 0));
30491647 1235 if (irel->r_offset < addr && raddr > addr)
1fd03b5a
SC
1236 {
1237 offset -= count;
1238 bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
1239 }
1240 else if (irel->r_offset >= addr && raddr <= addr)
1241 {
1242 offset += count;
1243 bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
1244 }
1245 else
1246 {
1247 /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr,
1248 irel->r_offset, addr);*/
1249 }
b34976b6 1250
1fd03b5a
SC
1251 break;
1252 }
1253 }
1254
1255 /* Adjust the local symbols defined in this section. */
1f4c5b47
SC
1256 isymend = isymbuf + symtab_hdr->sh_info;
1257 for (isym = isymbuf; isym < isymend; isym++)
1fd03b5a 1258 {
1f4c5b47
SC
1259 if (isym->st_shndx == sec_shndx
1260 && isym->st_value > addr
196486be 1261 && isym->st_value <= toaddr)
1f4c5b47 1262 isym->st_value -= count;
1fd03b5a
SC
1263 }
1264
1265 /* Now adjust the global symbols defined in this section. */
1266 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1267 - symtab_hdr->sh_info);
1268 sym_hashes = elf_sym_hashes (abfd);
1269 end_hashes = sym_hashes + symcount;
1270 for (; sym_hashes < end_hashes; sym_hashes++)
1271 {
1272 struct elf_link_hash_entry *sym_hash = *sym_hashes;
1273 if ((sym_hash->root.type == bfd_link_hash_defined
1274 || sym_hash->root.type == bfd_link_hash_defweak)
1275 && sym_hash->root.u.def.section == sec
1276 && sym_hash->root.u.def.value > addr
196486be 1277 && sym_hash->root.u.def.value <= toaddr)
1fd03b5a
SC
1278 {
1279 sym_hash->root.u.def.value -= count;
1280 }
1281 }
1282}
1283
2f89ff8d
L
1284/* Specific sections:
1285 - The .page0 is a data section that is mapped in [0x0000..0x00FF].
1286 Page0 accesses are faster on the M68HC11. Soft registers used by GCC-m6811
1287 are located in .page0.
1288 - The .vectors is the data section that represents the interrupt
1289 vectors. */
1290static struct bfd_elf_special_section const elf32_m68hc11_special_sections[]=
1291{
1292 { ".eeprom", 0, NULL, 0,
1293 SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
1294 { ".softregs", 0, NULL, 0,
1295 SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
1296 { ".page0", 0, NULL, 0,
1297 SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
1298 { ".vectors", 0, NULL, 0,
1299 SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
1300 { NULL, 0, NULL, 0,
1301 0, 0 }
1302};
96405e3c 1303\f
60bcf0fa
NC
1304#define ELF_ARCH bfd_arch_m68hc11
1305#define ELF_MACHINE_CODE EM_68HC11
1306#define ELF_MAXPAGESIZE 0x1000
1307
1308#define TARGET_BIG_SYM bfd_elf32_m68hc11_vec
1309#define TARGET_BIG_NAME "elf32-m68hc11"
1310
1311#define elf_info_to_howto 0
1312#define elf_info_to_howto_rel m68hc11_info_to_howto_rel
1fd03b5a 1313#define bfd_elf32_bfd_relax_section m68hc11_elf_relax_section
9b701e44
SC
1314#define elf_backend_gc_mark_hook elf32_m68hc11_gc_mark_hook
1315#define elf_backend_gc_sweep_hook elf32_m68hc11_gc_sweep_hook
1fd03b5a
SC
1316#define elf_backend_check_relocs elf32_m68hc11_check_relocs
1317#define elf_backend_relocate_section elf32_m68hc11_relocate_section
3a65329d 1318#define elf_backend_add_symbol_hook elf32_m68hc11_add_symbol_hook
60bcf0fa
NC
1319#define elf_backend_object_p 0
1320#define elf_backend_final_write_processing 0
9b701e44 1321#define elf_backend_can_gc_sections 1
2f89ff8d 1322#define elf_backend_special_sections elf32_m68hc11_special_sections
3a65329d
SC
1323
1324#define bfd_elf32_bfd_link_hash_table_create \
1325 m68hc11_elf_bfd_link_hash_table_create
1326#define bfd_elf32_bfd_link_hash_table_free \
1327 m68hc11_elf_bfd_link_hash_table_free
96405e3c
SC
1328#define bfd_elf32_bfd_merge_private_bfd_data \
1329 _bfd_m68hc11_elf_merge_private_bfd_data
1330#define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags
1331#define bfd_elf32_bfd_print_private_bfd_data \
1332 _bfd_m68hc11_elf_print_private_bfd_data
1333
60bcf0fa 1334#include "elf32-target.h"
This page took 0.256512 seconds and 4 git commands to generate.