1 /* Motorola 68HC11-specific support for 32-bit ELF
2    Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3    Contributed by Stephane Carrez (stcarrez@nerim.fr)
4    (Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
5 
6 This file is part of BFD, the Binary File Descriptor library.
7 
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21 
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "bfdlink.h"
25 #include "libbfd.h"
26 #include "elf-bfd.h"
27 #include "elf32-m68hc1x.h"
28 #include "elf/m68hc11.h"
29 #include "opcode/m68hc11.h"
30 
31 /* Relocation functions.  */
32 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
33   (bfd *, bfd_reloc_code_real_type);
34 static void m68hc11_info_to_howto_rel
35   (bfd *, arelent *, Elf_Internal_Rela *);
36 
37 /* Trampoline generation.  */
38 static bfd_boolean m68hc11_elf_size_one_stub
39   (struct bfd_hash_entry *gen_entry, void *in_arg);
40 static bfd_boolean m68hc11_elf_build_one_stub
41   (struct bfd_hash_entry *gen_entry, void *in_arg);
42 static struct bfd_link_hash_table* m68hc11_elf_bfd_link_hash_table_create
43   (bfd* abfd);
44 
45 /* Linker relaxation.  */
46 static bfd_boolean m68hc11_elf_relax_section
47   (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
48 static void m68hc11_elf_relax_delete_bytes
49   (bfd *, asection *, bfd_vma, int);
50 static void m68hc11_relax_group
51   (bfd *, asection *, bfd_byte *, unsigned, unsigned long, unsigned long);
52 static int compare_reloc (const void *, const void *);
53 
54 /* Use REL instead of RELA to save space */
55 #define USE_REL	1
56 
57 /* The Motorola 68HC11 microcontroller only addresses 64Kb but we also
58    support a memory bank switching mechanism similar to 68HC12.
59    We must handle 8 and 16-bit relocations.  The 32-bit relocation
60    are used for debugging sections (DWARF2) to represent a virtual
61    address.
62    The 3-bit and 16-bit PC rel relocation is only used by 68HC12.  */
63 static 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 */
69 	 FALSE,			/* pc_relative */
70 	 0,			/* bitpos */
71 	 complain_overflow_dont,/* complain_on_overflow */
72 	 bfd_elf_generic_reloc,	/* special_function */
73 	 "R_M68HC11_NONE",	/* name */
74 	 FALSE,			/* partial_inplace */
75 	 0,			/* src_mask */
76 	 0,			/* dst_mask */
77 	 FALSE),		/* pcrel_offset */
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 */
84 	 FALSE,			/* pc_relative */
85 	 0,			/* bitpos */
86 	 complain_overflow_bitfield,	/* complain_on_overflow */
87 	 bfd_elf_generic_reloc,	/* special_function */
88 	 "R_M68HC11_8",		/* name */
89 	 FALSE,			/* partial_inplace */
90 	 0x00ff,		/* src_mask */
91 	 0x00ff,		/* dst_mask */
92 	 FALSE),		/* pcrel_offset */
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 */
99 	 FALSE,			/* pc_relative */
100 	 0,			/* bitpos */
101 	 complain_overflow_bitfield,	/* complain_on_overflow */
102 	 bfd_elf_generic_reloc,	/* special_function */
103 	 "R_M68HC11_HI8",	/* name */
104 	 FALSE,			/* partial_inplace */
105 	 0x00ff,		/* src_mask */
106 	 0x00ff,		/* dst_mask */
107 	 FALSE),		/* pcrel_offset */
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 */
114 	 FALSE,			/* pc_relative */
115 	 0,			/* bitpos */
116 	 complain_overflow_dont,	/* complain_on_overflow */
117 	 bfd_elf_generic_reloc,	/* special_function */
118 	 "R_M68HC11_LO8",	/* name */
119 	 FALSE,			/* partial_inplace */
120 	 0x00ff,		/* src_mask */
121 	 0x00ff,		/* dst_mask */
122 	 FALSE),		/* pcrel_offset */
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 */
129 	 TRUE,			/* pc_relative */
130 	 0,			/* bitpos */
131 	 complain_overflow_bitfield,	/* complain_on_overflow */
132 	 bfd_elf_generic_reloc,	/* special_function */
133 	 "R_M68HC11_PCREL_8",	/* name */
134 	 FALSE,			/* partial_inplace */
135 	 0x00ff,		/* src_mask */
136 	 0x00ff,		/* dst_mask */
137 	 TRUE),                 /* pcrel_offset */
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 */
144 	 FALSE,			/* pc_relative */
145 	 0,			/* bitpos */
146 	 complain_overflow_dont /*bitfield */ ,	/* complain_on_overflow */
147 	 bfd_elf_generic_reloc,	/* special_function */
148 	 "R_M68HC11_16",	/* name */
149 	 FALSE,			/* partial_inplace */
150 	 0xffff,		/* src_mask */
151 	 0xffff,		/* dst_mask */
152 	 FALSE),		/* pcrel_offset */
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 */
160 	 FALSE,			/* pc_relative */
161 	 0,			/* bitpos */
162 	 complain_overflow_bitfield,	/* complain_on_overflow */
163 	 bfd_elf_generic_reloc,	/* special_function */
164 	 "R_M68HC11_32",	/* name */
165 	 FALSE,			/* partial_inplace */
166 	 0xffffffff,		/* src_mask */
167 	 0xffffffff,		/* dst_mask */
168 	 FALSE),		/* pcrel_offset */
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 */
175 	 FALSE,			/* pc_relative */
176 	 0,			/* bitpos */
177 	 complain_overflow_bitfield,	/* complain_on_overflow */
178 	 bfd_elf_generic_reloc,	/* special_function */
179 	 "R_M68HC11_4B",	/* name */
180 	 FALSE,			/* partial_inplace */
181 	 0x003,			/* src_mask */
182 	 0x003,			/* dst_mask */
183 	 FALSE),		/* pcrel_offset */
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 */
190 	 TRUE,			/* pc_relative */
191 	 0,			/* bitpos */
192 	 complain_overflow_dont,	/* complain_on_overflow */
193 	 bfd_elf_generic_reloc,	/* special_function */
194 	 "R_M68HC11_PCREL_16",	/* name */
195 	 FALSE,			/* partial_inplace */
196 	 0xffff,		/* src_mask */
197 	 0xffff,		/* dst_mask */
198 	 TRUE),                 /* pcrel_offset */
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 */
205 	 FALSE,			/* pc_relative */
206 	 0,			/* bitpos */
207 	 complain_overflow_dont,	/* complain_on_overflow */
208 	 NULL,			/* special_function */
209 	 "R_M68HC11_GNU_VTINHERIT",	/* name */
210 	 FALSE,			/* partial_inplace */
211 	 0,			/* src_mask */
212 	 0,			/* dst_mask */
213 	 FALSE),		/* pcrel_offset */
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 */
220 	 FALSE,			/* pc_relative */
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 */
225 	 FALSE,			/* partial_inplace */
226 	 0,			/* src_mask */
227 	 0,			/* dst_mask */
228 	 FALSE),		/* pcrel_offset */
229 
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 */
235 	 FALSE,			/* pc_relative */
236 	 0,			/* bitpos */
237 	 complain_overflow_bitfield,	/* complain_on_overflow */
238 	 bfd_elf_generic_reloc,	/* special_function */
239 	 "R_M68HC11_24",	/* name */
240 	 FALSE,			/* partial_inplace */
241 	 0xffffff,		/* src_mask */
242 	 0xffffff,		/* dst_mask */
243 	 FALSE),		/* pcrel_offset */
244 
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 */
250 	 FALSE,			/* pc_relative */
251 	 0,			/* bitpos */
252 	 complain_overflow_bitfield,	/* complain_on_overflow */
253 	 bfd_elf_generic_reloc,	/* special_function */
254 	 "R_M68HC11_LO16",	/* name */
255 	 FALSE,			/* partial_inplace */
256 	 0xffff,		/* src_mask */
257 	 0xffff,		/* dst_mask */
258 	 FALSE),		/* pcrel_offset */
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 */
265 	 FALSE,			/* pc_relative */
266 	 0,			/* bitpos */
267 	 complain_overflow_bitfield,	/* complain_on_overflow */
268 	 bfd_elf_generic_reloc,	/* special_function */
269 	 "R_M68HC11_PAGE",	/* name */
270 	 FALSE,			/* partial_inplace */
271 	 0x00ff,		/* src_mask */
272 	 0x00ff,		/* dst_mask */
273 	 FALSE),		/* pcrel_offset */
274 
275   EMPTY_HOWTO (14),
276   EMPTY_HOWTO (15),
277   EMPTY_HOWTO (16),
278   EMPTY_HOWTO (17),
279   EMPTY_HOWTO (18),
280   EMPTY_HOWTO (19),
281 
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 */
287 	 FALSE,			/* pc_relative */
288 	 0,			/* bitpos */
289 	 complain_overflow_dont,	/* complain_on_overflow */
290 	 m68hc11_elf_ignore_reloc,	/* special_function */
291 	 "R_M68HC11_RL_JUMP",	/* name */
292 	 TRUE,			/* partial_inplace */
293 	 0,			/* src_mask */
294 	 0,			/* dst_mask */
295 	 TRUE),                 /* pcrel_offset */
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 */
302 	 FALSE,			/* pc_relative */
303 	 0,			/* bitpos */
304 	 complain_overflow_dont,	/* complain_on_overflow */
305 	 m68hc11_elf_ignore_reloc,	/* special_function */
306 	 "R_M68HC11_RL_GROUP",	/* name */
307 	 TRUE,			/* partial_inplace */
308 	 0,			/* src_mask */
309 	 0,			/* dst_mask */
310 	 TRUE),                 /* pcrel_offset */
311 };
312 
313 /* Map BFD reloc types to M68HC11 ELF reloc types.  */
314 
315 struct m68hc11_reloc_map
316 {
317   bfd_reloc_code_real_type bfd_reloc_val;
318   unsigned char elf_reloc_val;
319 };
320 
321 static 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 
332   {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
333   {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
334 
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 
339   {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
340   {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
341 };
342 
343 static reloc_howto_type *
bfd_elf32_bfd_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)344 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
345                                  bfd_reloc_code_real_type code)
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 
362 static void
m68hc11_info_to_howto_rel(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr,Elf_Internal_Rela * dst)363 m68hc11_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
364                            arelent *cache_ptr, Elf_Internal_Rela *dst)
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 
373 
374 /* Far trampoline generation.  */
375 
376 /* Build a 68HC11 trampoline stub.  */
377 static bfd_boolean
m68hc11_elf_build_one_stub(struct bfd_hash_entry * gen_entry,void * in_arg)378 m68hc11_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
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);
432 
433   return TRUE;
434 }
435 
436 /* As above, but don't actually build the stub.  Just bump offset so
437    we know stub section sizes.  */
438 
439 static bfd_boolean
m68hc11_elf_size_one_stub(struct bfd_hash_entry * gen_entry,void * in_arg ATTRIBUTE_UNUSED)440 m68hc11_elf_size_one_stub (struct bfd_hash_entry *gen_entry,
441                            void *in_arg ATTRIBUTE_UNUSED)
442 {
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;
449   return TRUE;
450 }
451 
452 /* Create a 68HC11 ELF linker hash table.  */
453 
454 static struct bfd_link_hash_table *
m68hc11_elf_bfd_link_hash_table_create(bfd * abfd)455 m68hc11_elf_bfd_link_hash_table_create (bfd *abfd)
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 
469 
470 /* 68HC11 Linker Relaxation.  */
471 
472 struct m68hc11_direct_relax
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 
515 static struct m68hc11_direct_relax *
find_relaxable_insn(unsigned char code)516 find_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 
527 static int
compare_reloc(const void * e1,const void * e2)528 compare_reloc (const void *e1, const void *e2)
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 
541 static void
m68hc11_relax_group(bfd * abfd,asection * sec,bfd_byte * contents,unsigned value,unsigned long offset,unsigned long end_group)542 m68hc11_relax_group (bfd *abfd, asection *sec, bfd_byte *contents,
543                      unsigned value, unsigned long offset,
544                      unsigned long end_group)
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 
650 
651 	and somewhat more difficult to support.  */
652 
653 static bfd_boolean
m68hc11_elf_relax_section(bfd * abfd,asection * sec,struct bfd_link_info * link_info,bfd_boolean * again)654 m68hc11_elf_relax_section (bfd *abfd, asection *sec,
655                            struct bfd_link_info *link_info, bfd_boolean *again)
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;
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;
668   Elf_Internal_Sym *isymbuf = NULL;
669 
670   /* Assume nothing changes.  */
671   *again = FALSE;
672 
673   /* We don't have to do anything for a relocatable link, if
674      this section does not have relocs, or if this is not a
675      code section.  */
676   if (link_info->relocatable
677       || (sec->flags & SEC_RELOC) == 0
678       || sec->reloc_count == 0
679       || (sec->flags & SEC_CODE) == 0)
680     return TRUE;
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.  */
691   internal_relocs = (_bfd_elf_link_read_relocs
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;
710       Elf_Internal_Sym *isym;
711       asection *sym_sec;
712       int is_far = 0;
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;
764 
765 	  /* Do nothing if this reloc is the last byte in the section.  */
766 	  if (irel->r_offset + 2 >= sec->_cooked_size)
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.  */
796       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
797 	{
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;
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 	{
810 	  /* A local symbol.  */
811 	  isym = isymbuf + ELF32_R_SYM (irel->r_info);
812           is_far = isym->st_other & STO_M68HC12_FAR;
813           sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
814 	  symval = (isym->st_value
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 
838           is_far = h->other & STO_M68HC12_FAR;
839           isym = 0;
840           sym_sec = h->root.u.def.section;
841 	  symval = (h->root.u.def.value
842 		    + sym_sec->output_section->vma
843 		    + sym_sec->output_offset);
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;
850 
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;
856           insn_group_value = isym->st_value;
857           continue;
858         }
859 
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         }
885 
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);
912               bfd_put_8 (abfd, 0xff,
913                          contents + prev_insn_branch->r_offset + 1);
914               irel->r_offset = prev_insn_branch->r_offset + 1;
915               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
916                                            R_M68HC11_PCREL_8);
917               m68hc11_elf_relax_delete_bytes (abfd, sec,
918                                               irel->r_offset + 1, 1);
919             }
920           else
921             {
922               code ^= 0x1;
923               bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
924               bfd_put_8 (abfd, 0xff,
925                          contents + prev_insn_branch->r_offset + 1);
926               irel->r_offset = prev_insn_branch->r_offset + 1;
927               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
928                                            R_M68HC11_PCREL_8);
929               m68hc11_elf_relax_delete_bytes (abfd, sec,
930                                               irel->r_offset + 1, 3);
931             }
932           prev_insn_branch = 0;
933           *again = TRUE;
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             {
955               unsigned long old_sec_size = sec->_cooked_size;
956 
957               /* Note that we've changed the relocation 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 
964               symtab_hdr->contents = (bfd_byte *) isymbuf;
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);
974               if (sec->_cooked_size != old_sec_size)
975                 *again = TRUE;
976               continue;
977             }
978 
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 relocation 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 
995           symtab_hdr->contents = (bfd_byte *) isymbuf;
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 
1011           /* That will change things, so, we should relax again.  */
1012           *again = TRUE;
1013         }
1014       else if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_16 && !is_far)
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);
1021           if (code == 0x7e || code == 0xbd)
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 relocation contents, etc.  */
1034                   elf_section_data (sec)->relocs = internal_relocs;
1035                   free_relocs = NULL;
1036 
1037                   elf_section_data (sec)->this_hdr.contents = contents;
1038                   free_contents = NULL;
1039 
1040                   symtab_hdr->contents = (bfd_byte *) isymbuf;
1041                   free_extsyms = NULL;
1042 
1043                   /* Shrink the branch.  */
1044                   code = (code == 0x7e) ? 0x20 : 0x8d;
1045                   bfd_put_8 (abfd, code,
1046                              contents + irel->r_offset - 1);
1047                   bfd_put_8 (abfd, 0xff,
1048                              contents + irel->r_offset);
1049                   irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1050                                                R_M68HC11_PCREL_8);
1051                   m68hc11_elf_relax_delete_bytes (abfd, sec,
1052                                                   irel->r_offset + 1, 1);
1053                   /* That will change things, so, we should relax again.  */
1054                   *again = TRUE;
1055                 }
1056             }
1057         }
1058       prev_insn_branch = 0;
1059       prev_insn_group = 0;
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.  */
1087 	  symtab_hdr->contents = (unsigned char *) isymbuf;
1088 	}
1089       free_extsyms = NULL;
1090     }
1091 
1092   return TRUE;
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);
1101   return FALSE;
1102 }
1103 
1104 /* Delete some bytes from a section while relaxing.  */
1105 
1106 static void
m68hc11_elf_relax_delete_bytes(bfd * abfd,asection * sec,bfd_vma addr,int count)1107 m68hc11_elf_relax_delete_bytes (bfd *abfd, asection *sec,
1108                                 bfd_vma addr, int count)
1109 {
1110   Elf_Internal_Shdr *symtab_hdr;
1111   unsigned int sec_shndx;
1112   bfd_byte *contents;
1113   Elf_Internal_Rela *irel, *irelend;
1114   bfd_vma toaddr;
1115   Elf_Internal_Sym *isymbuf, *isym, *isymend;
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;
1121   isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
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));
1135 
1136   sec->_cooked_size -= count;
1137 
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));
1215           if (irel->r_offset < addr && raddr > addr)
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             }
1230 
1231           break;
1232 	}
1233     }
1234 
1235   /* Adjust the local symbols defined in this section.  */
1236   isymend = isymbuf + symtab_hdr->sh_info;
1237   for (isym = isymbuf; isym < isymend; isym++)
1238     {
1239       if (isym->st_shndx == sec_shndx
1240 	  && isym->st_value > addr
1241 	  && isym->st_value <= toaddr)
1242 	isym->st_value -= count;
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
1257 	  && sym_hash->root.u.def.value <= toaddr)
1258 	{
1259 	  sym_hash->root.u.def.value -= count;
1260 	}
1261     }
1262 }
1263 
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.
1268    - The .vectors is the section that represents the interrupt
1269      vectors.  */
1270 static struct bfd_elf_special_section const elf32_m68hc11_special_sections[]=
1271 {
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 }
1277 };
1278 
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
1288 #define bfd_elf32_bfd_relax_section  m68hc11_elf_relax_section
1289 #define elf_backend_gc_mark_hook     elf32_m68hc11_gc_mark_hook
1290 #define elf_backend_gc_sweep_hook    elf32_m68hc11_gc_sweep_hook
1291 #define elf_backend_check_relocs     elf32_m68hc11_check_relocs
1292 #define elf_backend_relocate_section elf32_m68hc11_relocate_section
1293 #define elf_backend_add_symbol_hook  elf32_m68hc11_add_symbol_hook
1294 #define elf_backend_object_p	0
1295 #define elf_backend_final_write_processing	0
1296 #define elf_backend_can_gc_sections		1
1297 #define elf_backend_special_sections elf32_m68hc11_special_sections
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
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 
1309 #include "elf32-target.h"
1310