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