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