* elf64-ppc.c (ppc64_elf_func_desc_adjust): Don't emit out-of-line
[platform/upstream/binutils.git] / bfd / elf32-m68hc1x.c
1 /* Motorola 68HC11/HC12-specific support for 32-bit ELF
2    Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3    2009, 2010, 2011, 2012 Free Software Foundation, Inc.
4    Contributed by Stephane Carrez (stcarrez@nerim.fr)
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 3 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., 51 Franklin Street - Fifth Floor, Boston,
21    MA 02110-1301, USA.  */
22
23 #include "sysdep.h"
24 #include "alloca-conf.h"
25 #include "bfd.h"
26 #include "bfdlink.h"
27 #include "libbfd.h"
28 #include "elf-bfd.h"
29 #include "elf32-m68hc1x.h"
30 #include "elf/m68hc11.h"
31 #include "opcode/m68hc11.h"
32
33
34 #define m68hc12_stub_hash_lookup(table, string, create, copy) \
35   ((struct elf32_m68hc11_stub_hash_entry *) \
36    bfd_hash_lookup ((table), (string), (create), (copy)))
37
38 static struct elf32_m68hc11_stub_hash_entry* m68hc12_add_stub
39   (const char *stub_name,
40    asection *section,
41    struct m68hc11_elf_link_hash_table *htab);
42
43 static struct bfd_hash_entry *stub_hash_newfunc
44   (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
45
46 static void m68hc11_elf_set_symbol (bfd* abfd, struct bfd_link_info *info,
47                                     const char* name, bfd_vma value,
48                                     asection* sec);
49
50 static bfd_boolean m68hc11_elf_export_one_stub
51   (struct bfd_hash_entry *gen_entry, void *in_arg);
52
53 static void scan_sections_for_abi (bfd*, asection*, PTR);
54
55 struct m68hc11_scan_param
56 {
57    struct m68hc11_page_info* pinfo;
58    bfd_boolean use_memory_banks;
59 };
60
61
62 /* Create a 68HC11/68HC12 ELF linker hash table.  */
63
64 struct m68hc11_elf_link_hash_table*
65 m68hc11_elf_hash_table_create (bfd *abfd)
66 {
67   struct m68hc11_elf_link_hash_table *ret;
68   bfd_size_type amt = sizeof (struct m68hc11_elf_link_hash_table);
69
70   ret = (struct m68hc11_elf_link_hash_table *) bfd_malloc (amt);
71   if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
72     return NULL;
73
74   memset (ret, 0, amt);
75   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
76                                       _bfd_elf_link_hash_newfunc,
77                                       sizeof (struct elf_link_hash_entry),
78                                       M68HC11_ELF_DATA))
79     {
80       free (ret);
81       return NULL;
82     }
83
84   /* Init the stub hash table too.  */
85   amt = sizeof (struct bfd_hash_table);
86   ret->stub_hash_table = (struct bfd_hash_table*) bfd_malloc (amt);
87   if (ret->stub_hash_table == NULL)
88     {
89       free (ret);
90       return NULL;
91     }
92   if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc,
93                             sizeof (struct elf32_m68hc11_stub_hash_entry)))
94     return NULL;
95
96   ret->stub_bfd = NULL;
97   ret->stub_section = 0;
98   ret->add_stub_section = NULL;
99   ret->sym_cache.abfd = NULL;
100
101   return ret;
102 }
103
104 /* Free the derived linker hash table.  */
105
106 void
107 m68hc11_elf_bfd_link_hash_table_free (struct bfd_link_hash_table *hash)
108 {
109   struct m68hc11_elf_link_hash_table *ret
110     = (struct m68hc11_elf_link_hash_table *) hash;
111
112   bfd_hash_table_free (ret->stub_hash_table);
113   free (ret->stub_hash_table);
114   _bfd_generic_link_hash_table_free (hash);
115 }
116
117 /* Assorted hash table functions.  */
118
119 /* Initialize an entry in the stub hash table.  */
120
121 static struct bfd_hash_entry *
122 stub_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
123                    const char *string)
124 {
125   /* Allocate the structure if it has not already been allocated by a
126      subclass.  */
127   if (entry == NULL)
128     {
129       entry = bfd_hash_allocate (table,
130                                  sizeof (struct elf32_m68hc11_stub_hash_entry));
131       if (entry == NULL)
132         return entry;
133     }
134
135   /* Call the allocation method of the superclass.  */
136   entry = bfd_hash_newfunc (entry, table, string);
137   if (entry != NULL)
138     {
139       struct elf32_m68hc11_stub_hash_entry *eh;
140
141       /* Initialize the local fields.  */
142       eh = (struct elf32_m68hc11_stub_hash_entry *) entry;
143       eh->stub_sec = NULL;
144       eh->stub_offset = 0;
145       eh->target_value = 0;
146       eh->target_section = NULL;
147     }
148
149   return entry;
150 }
151
152 /* Add a new stub entry to the stub hash.  Not all fields of the new
153    stub entry are initialised.  */
154
155 static struct elf32_m68hc11_stub_hash_entry *
156 m68hc12_add_stub (const char *stub_name, asection *section,
157                   struct m68hc11_elf_link_hash_table *htab)
158 {
159   struct elf32_m68hc11_stub_hash_entry *stub_entry;
160
161   /* Enter this entry into the linker stub hash table.  */
162   stub_entry = m68hc12_stub_hash_lookup (htab->stub_hash_table, stub_name,
163                                          TRUE, FALSE);
164   if (stub_entry == NULL)
165     {
166       (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
167                              section->owner, stub_name);
168       return NULL;
169     }
170
171   if (htab->stub_section == 0)
172     {
173       htab->stub_section = (*htab->add_stub_section) (".tramp",
174                                                       htab->tramp_section);
175     }
176
177   stub_entry->stub_sec = htab->stub_section;
178   stub_entry->stub_offset = 0;
179   return stub_entry;
180 }
181
182 /* Hook called by the linker routine which adds symbols from an object
183    file.  We use it for identify far symbols and force a loading of
184    the trampoline handler.  */
185
186 bfd_boolean
187 elf32_m68hc11_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
188                                Elf_Internal_Sym *sym,
189                                const char **namep ATTRIBUTE_UNUSED,
190                                flagword *flagsp ATTRIBUTE_UNUSED,
191                                asection **secp ATTRIBUTE_UNUSED,
192                                bfd_vma *valp ATTRIBUTE_UNUSED)
193 {
194   if (sym->st_other & STO_M68HC12_FAR)
195     {
196       struct elf_link_hash_entry *h;
197
198       h = (struct elf_link_hash_entry *)
199         bfd_link_hash_lookup (info->hash, "__far_trampoline",
200                               FALSE, FALSE, FALSE);
201       if (h == NULL)
202         {
203           struct bfd_link_hash_entry* entry = NULL;
204
205           _bfd_generic_link_add_one_symbol (info, abfd,
206                                             "__far_trampoline",
207                                             BSF_GLOBAL,
208                                             bfd_und_section_ptr,
209                                             (bfd_vma) 0, (const char*) NULL,
210                                             FALSE, FALSE, &entry);
211         }
212
213     }
214   return TRUE;
215 }
216
217 /* Merge non-visibility st_other attributes, STO_M68HC12_FAR and
218    STO_M68HC12_INTERRUPT.  */
219
220 void
221 elf32_m68hc11_merge_symbol_attribute (struct elf_link_hash_entry *h,
222                                       const Elf_Internal_Sym *isym,
223                                       bfd_boolean definition,
224                                       bfd_boolean dynamic ATTRIBUTE_UNUSED)
225 {
226   if (definition)
227     h->other = ((isym->st_other & ~ELF_ST_VISIBILITY (-1))
228                 | ELF_ST_VISIBILITY (h->other));
229 }
230
231 /* External entry points for sizing and building linker stubs.  */
232
233 /* Set up various things so that we can make a list of input sections
234    for each output section included in the link.  Returns -1 on error,
235    0 when no stubs will be needed, and 1 on success.  */
236
237 int
238 elf32_m68hc11_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
239 {
240   bfd *input_bfd;
241   unsigned int bfd_count;
242   int top_id, top_index;
243   asection *section;
244   asection **input_list, **list;
245   bfd_size_type amt;
246   asection *text_section;
247   struct m68hc11_elf_link_hash_table *htab;
248
249   htab = m68hc11_elf_hash_table (info);
250   if (htab == NULL)
251     return -1;
252
253   if (bfd_get_flavour (info->output_bfd) != bfd_target_elf_flavour)
254     return 0;
255
256   /* Count the number of input BFDs and find the top input section id.
257      Also search for an existing ".tramp" section so that we know
258      where generated trampolines must go.  Default to ".text" if we
259      can't find it.  */
260   htab->tramp_section = 0;
261   text_section = 0;
262   for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
263        input_bfd != NULL;
264        input_bfd = input_bfd->link_next)
265     {
266       bfd_count += 1;
267       for (section = input_bfd->sections;
268            section != NULL;
269            section = section->next)
270         {
271           const char* name = bfd_get_section_name (input_bfd, section);
272
273           if (!strcmp (name, ".tramp"))
274             htab->tramp_section = section;
275
276           if (!strcmp (name, ".text"))
277             text_section = section;
278
279           if (top_id < section->id)
280             top_id = section->id;
281         }
282     }
283   htab->bfd_count = bfd_count;
284   if (htab->tramp_section == 0)
285     htab->tramp_section = text_section;
286
287   /* We can't use output_bfd->section_count here to find the top output
288      section index as some sections may have been removed, and
289      strip_excluded_output_sections doesn't renumber the indices.  */
290   for (section = output_bfd->sections, top_index = 0;
291        section != NULL;
292        section = section->next)
293     {
294       if (top_index < section->index)
295         top_index = section->index;
296     }
297
298   htab->top_index = top_index;
299   amt = sizeof (asection *) * (top_index + 1);
300   input_list = (asection **) bfd_malloc (amt);
301   htab->input_list = input_list;
302   if (input_list == NULL)
303     return -1;
304
305   /* For sections we aren't interested in, mark their entries with a
306      value we can check later.  */
307   list = input_list + top_index;
308   do
309     *list = bfd_abs_section_ptr;
310   while (list-- != input_list);
311
312   for (section = output_bfd->sections;
313        section != NULL;
314        section = section->next)
315     {
316       if ((section->flags & SEC_CODE) != 0)
317         input_list[section->index] = NULL;
318     }
319
320   return 1;
321 }
322
323 /* Determine and set the size of the stub section for a final link.
324
325    The basic idea here is to examine all the relocations looking for
326    PC-relative calls to a target that is unreachable with a "bl"
327    instruction.  */
328
329 bfd_boolean
330 elf32_m68hc11_size_stubs (bfd *output_bfd, bfd *stub_bfd,
331                           struct bfd_link_info *info,
332                           asection * (*add_stub_section) (const char*, asection*))
333 {
334   bfd *input_bfd;
335   asection *section;
336   Elf_Internal_Sym *local_syms, **all_local_syms;
337   unsigned int bfd_indx, bfd_count;
338   bfd_size_type amt;
339   asection *stub_sec;
340   struct m68hc11_elf_link_hash_table *htab = m68hc11_elf_hash_table (info);
341
342   if (htab == NULL)
343     return FALSE;
344
345   /* Stash our params away.  */
346   htab->stub_bfd = stub_bfd;
347   htab->add_stub_section = add_stub_section;
348
349   /* Count the number of input BFDs and find the top input section id.  */
350   for (input_bfd = info->input_bfds, bfd_count = 0;
351        input_bfd != NULL;
352        input_bfd = input_bfd->link_next)
353     bfd_count += 1;
354
355   /* We want to read in symbol extension records only once.  To do this
356      we need to read in the local symbols in parallel and save them for
357      later use; so hold pointers to the local symbols in an array.  */
358   amt = sizeof (Elf_Internal_Sym *) * bfd_count;
359   all_local_syms = (Elf_Internal_Sym **) bfd_zmalloc (amt);
360   if (all_local_syms == NULL)
361     return FALSE;
362
363   /* Walk over all the input BFDs, swapping in local symbols.  */
364   for (input_bfd = info->input_bfds, bfd_indx = 0;
365        input_bfd != NULL;
366        input_bfd = input_bfd->link_next, bfd_indx++)
367     {
368       Elf_Internal_Shdr *symtab_hdr;
369
370       /* We'll need the symbol table in a second.  */
371       symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
372       if (symtab_hdr->sh_info == 0)
373         continue;
374
375       /* We need an array of the local symbols attached to the input bfd.  */
376       local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
377       if (local_syms == NULL)
378         {
379           local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
380                                              symtab_hdr->sh_info, 0,
381                                              NULL, NULL, NULL);
382           /* Cache them for elf_link_input_bfd.  */
383           symtab_hdr->contents = (unsigned char *) local_syms;
384         }
385       if (local_syms == NULL)
386         {
387           free (all_local_syms);
388           return FALSE;
389         }
390
391       all_local_syms[bfd_indx] = local_syms;
392     }
393
394   for (input_bfd = info->input_bfds, bfd_indx = 0;
395        input_bfd != NULL;
396        input_bfd = input_bfd->link_next, bfd_indx++)
397     {
398       Elf_Internal_Shdr *symtab_hdr;
399       struct elf_link_hash_entry ** sym_hashes;
400
401       sym_hashes = elf_sym_hashes (input_bfd);
402
403       /* We'll need the symbol table in a second.  */
404       symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
405       if (symtab_hdr->sh_info == 0)
406         continue;
407
408       local_syms = all_local_syms[bfd_indx];
409
410       /* Walk over each section attached to the input bfd.  */
411       for (section = input_bfd->sections;
412            section != NULL;
413            section = section->next)
414         {
415           Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
416
417           /* If there aren't any relocs, then there's nothing more
418              to do.  */
419           if ((section->flags & SEC_RELOC) == 0
420               || section->reloc_count == 0)
421             continue;
422
423           /* If this section is a link-once section that will be
424              discarded, then don't create any stubs.  */
425           if (section->output_section == NULL
426               || section->output_section->owner != output_bfd)
427             continue;
428
429           /* Get the relocs.  */
430           internal_relocs
431             = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
432                                          (Elf_Internal_Rela *) NULL,
433                                          info->keep_memory);
434           if (internal_relocs == NULL)
435             goto error_ret_free_local;
436
437           /* Now examine each relocation.  */
438           irela = internal_relocs;
439           irelaend = irela + section->reloc_count;
440           for (; irela < irelaend; irela++)
441             {
442               unsigned int r_type, r_indx;
443               struct elf32_m68hc11_stub_hash_entry *stub_entry;
444               asection *sym_sec;
445               bfd_vma sym_value;
446               struct elf_link_hash_entry *hash;
447               const char *stub_name;
448               Elf_Internal_Sym *sym;
449
450               r_type = ELF32_R_TYPE (irela->r_info);
451
452               /* Only look at 16-bit relocs.  */
453               if (r_type != (unsigned int) R_M68HC11_16)
454                 continue;
455
456               /* Now determine the call target, its name, value,
457                  section.  */
458               r_indx = ELF32_R_SYM (irela->r_info);
459               if (r_indx < symtab_hdr->sh_info)
460                 {
461                   /* It's a local symbol.  */
462                   Elf_Internal_Shdr *hdr;
463                   bfd_boolean is_far;
464
465                   sym = local_syms + r_indx;
466                   is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
467                   if (!is_far)
468                     continue;
469
470                   if (sym->st_shndx >= elf_numsections (input_bfd))
471                     sym_sec = NULL;
472                   else
473                     {
474                       hdr = elf_elfsections (input_bfd)[sym->st_shndx];
475                       sym_sec = hdr->bfd_section;
476                     }
477                   stub_name = (bfd_elf_string_from_elf_section
478                                (input_bfd, symtab_hdr->sh_link,
479                                 sym->st_name));
480                   sym_value = sym->st_value;
481                   hash = NULL;
482                 }
483               else
484                 {
485                   /* It's an external symbol.  */
486                   int e_indx;
487
488                   e_indx = r_indx - symtab_hdr->sh_info;
489                   hash = (struct elf_link_hash_entry *)
490                     (sym_hashes[e_indx]);
491
492                   while (hash->root.type == bfd_link_hash_indirect
493                          || hash->root.type == bfd_link_hash_warning)
494                     hash = ((struct elf_link_hash_entry *)
495                             hash->root.u.i.link);
496
497                   if (hash->root.type == bfd_link_hash_defined
498                       || hash->root.type == bfd_link_hash_defweak
499                       || hash->root.type == bfd_link_hash_new)
500                     {
501                       if (!(hash->other & STO_M68HC12_FAR))
502                         continue;
503                     }
504                   else if (hash->root.type == bfd_link_hash_undefweak)
505                     {
506                       continue;
507                     }
508                   else if (hash->root.type == bfd_link_hash_undefined)
509                     {
510                       continue;
511                     }
512                   else
513                     {
514                       bfd_set_error (bfd_error_bad_value);
515                       goto error_ret_free_internal;
516                     }
517                   sym_sec = hash->root.u.def.section;
518                   sym_value = hash->root.u.def.value;
519                   stub_name = hash->root.root.string;
520                 }
521
522               if (!stub_name)
523                 goto error_ret_free_internal;
524
525               stub_entry = m68hc12_stub_hash_lookup
526                 (htab->stub_hash_table,
527                  stub_name,
528                  FALSE, FALSE);
529               if (stub_entry == NULL)
530                 {
531                   if (add_stub_section == 0)
532                     continue;
533
534                   stub_entry = m68hc12_add_stub (stub_name, section, htab);
535                   if (stub_entry == NULL)
536                     {
537                     error_ret_free_internal:
538                       if (elf_section_data (section)->relocs == NULL)
539                         free (internal_relocs);
540                       goto error_ret_free_local;
541                     }
542                 }
543
544               stub_entry->target_value = sym_value;
545               stub_entry->target_section = sym_sec;
546             }
547
548           /* We're done with the internal relocs, free them.  */
549           if (elf_section_data (section)->relocs == NULL)
550             free (internal_relocs);
551         }
552     }
553
554   if (add_stub_section)
555     {
556       /* OK, we've added some stubs.  Find out the new size of the
557          stub sections.  */
558       for (stub_sec = htab->stub_bfd->sections;
559            stub_sec != NULL;
560            stub_sec = stub_sec->next)
561         {
562           stub_sec->size = 0;
563         }
564
565       bfd_hash_traverse (htab->stub_hash_table, htab->size_one_stub, htab);
566     }
567   free (all_local_syms);
568   return TRUE;
569
570  error_ret_free_local:
571   free (all_local_syms);
572   return FALSE;
573 }
574
575 /* Export the trampoline addresses in the symbol table.  */
576 static bfd_boolean
577 m68hc11_elf_export_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
578 {
579   struct bfd_link_info *info;
580   struct m68hc11_elf_link_hash_table *htab;
581   struct elf32_m68hc11_stub_hash_entry *stub_entry;
582   char* name;
583   bfd_boolean result;
584
585   info = (struct bfd_link_info *) in_arg;
586   htab = m68hc11_elf_hash_table (info);
587   if (htab == NULL)
588     return FALSE;
589
590   /* Massage our args to the form they really have.  */
591   stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
592
593   /* Generate the trampoline according to HC11 or HC12.  */
594   result = (* htab->build_one_stub) (gen_entry, in_arg);
595
596   /* Make a printable name that does not conflict with the real function.  */
597   name = alloca (strlen (stub_entry->root.string) + 16);
598   sprintf (name, "tramp.%s", stub_entry->root.string);
599
600   /* Export the symbol for debugging/disassembling.  */
601   m68hc11_elf_set_symbol (htab->stub_bfd, info, name,
602                           stub_entry->stub_offset,
603                           stub_entry->stub_sec);
604   return result;
605 }
606
607 /* Export a symbol or set its value and section.  */
608 static void
609 m68hc11_elf_set_symbol (bfd *abfd, struct bfd_link_info *info,
610                         const char *name, bfd_vma value, asection *sec)
611 {
612   struct elf_link_hash_entry *h;
613
614   h = (struct elf_link_hash_entry *)
615     bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, FALSE);
616   if (h == NULL)
617     {
618       _bfd_generic_link_add_one_symbol (info, abfd,
619                                         name,
620                                         BSF_GLOBAL,
621                                         sec,
622                                         value,
623                                         (const char*) NULL,
624                                         TRUE, FALSE, NULL);
625     }
626   else
627     {
628       h->root.type = bfd_link_hash_defined;
629       h->root.u.def.value = value;
630       h->root.u.def.section = sec;
631     }
632 }
633
634
635 /* Build all the stubs associated with the current output file.  The
636    stubs are kept in a hash table attached to the main linker hash
637    table.  This function is called via m68hc12elf_finish in the
638    linker.  */
639
640 bfd_boolean
641 elf32_m68hc11_build_stubs (bfd *abfd, struct bfd_link_info *info)
642 {
643   asection *stub_sec;
644   struct bfd_hash_table *table;
645   struct m68hc11_elf_link_hash_table *htab;
646   struct m68hc11_scan_param param;
647
648   m68hc11_elf_get_bank_parameters (info);
649   htab = m68hc11_elf_hash_table (info);
650   if (htab == NULL)
651     return FALSE;
652
653   for (stub_sec = htab->stub_bfd->sections;
654        stub_sec != NULL;
655        stub_sec = stub_sec->next)
656     {
657       bfd_size_type size;
658
659       /* Allocate memory to hold the linker stubs.  */
660       size = stub_sec->size;
661       stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
662       if (stub_sec->contents == NULL && size != 0)
663         return FALSE;
664       stub_sec->size = 0;
665     }
666
667   /* Build the stubs as directed by the stub hash table.  */
668   table = htab->stub_hash_table;
669   bfd_hash_traverse (table, m68hc11_elf_export_one_stub, info);
670   
671   /* Scan the output sections to see if we use the memory banks.
672      If so, export the symbols that define how the memory banks
673      are mapped.  This is used by gdb and the simulator to obtain
674      the information.  It can be used by programs to burn the eprom
675      at the good addresses.  */
676   param.use_memory_banks = FALSE;
677   param.pinfo = &htab->pinfo;
678   bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
679   if (param.use_memory_banks)
680     {
681       m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_START_NAME,
682                               htab->pinfo.bank_physical,
683                               bfd_abs_section_ptr);
684       m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_VIRTUAL_NAME,
685                               htab->pinfo.bank_virtual,
686                               bfd_abs_section_ptr);
687       m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_SIZE_NAME,
688                               htab->pinfo.bank_size,
689                               bfd_abs_section_ptr);
690     }
691
692   return TRUE;
693 }
694
695 void
696 m68hc11_elf_get_bank_parameters (struct bfd_link_info *info)
697 {
698   unsigned i;
699   struct m68hc11_page_info *pinfo;
700   struct bfd_link_hash_entry *h;
701   struct m68hc11_elf_link_hash_table *htab;
702
703   htab = m68hc11_elf_hash_table (info);
704   if (htab == NULL)
705     return;
706
707   pinfo = & htab->pinfo;
708   if (pinfo->bank_param_initialized)
709     return;
710
711   pinfo->bank_virtual = M68HC12_BANK_VIRT;
712   pinfo->bank_mask = M68HC12_BANK_MASK;
713   pinfo->bank_physical = M68HC12_BANK_BASE;
714   pinfo->bank_shift = M68HC12_BANK_SHIFT;
715   pinfo->bank_size = 1 << M68HC12_BANK_SHIFT;
716
717   h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_START_NAME,
718                             FALSE, FALSE, TRUE);
719   if (h != (struct bfd_link_hash_entry*) NULL
720       && h->type == bfd_link_hash_defined)
721     pinfo->bank_physical = (h->u.def.value
722                             + h->u.def.section->output_section->vma
723                             + h->u.def.section->output_offset);
724
725   h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_VIRTUAL_NAME,
726                             FALSE, FALSE, TRUE);
727   if (h != (struct bfd_link_hash_entry*) NULL
728       && h->type == bfd_link_hash_defined)
729     pinfo->bank_virtual = (h->u.def.value
730                            + h->u.def.section->output_section->vma
731                            + h->u.def.section->output_offset);
732
733   h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_SIZE_NAME,
734                             FALSE, FALSE, TRUE);
735   if (h != (struct bfd_link_hash_entry*) NULL
736       && h->type == bfd_link_hash_defined)
737     pinfo->bank_size = (h->u.def.value
738                         + h->u.def.section->output_section->vma
739                         + h->u.def.section->output_offset);
740
741   pinfo->bank_shift = 0;
742   for (i = pinfo->bank_size; i != 0; i >>= 1)
743     pinfo->bank_shift++;
744   pinfo->bank_shift--;
745   pinfo->bank_mask = (1 << pinfo->bank_shift) - 1;
746   pinfo->bank_physical_end = pinfo->bank_physical + pinfo->bank_size;
747   pinfo->bank_param_initialized = 1;
748
749   h = bfd_link_hash_lookup (info->hash, "__far_trampoline", FALSE,
750                             FALSE, TRUE);
751   if (h != (struct bfd_link_hash_entry*) NULL
752       && h->type == bfd_link_hash_defined)
753     pinfo->trampoline_addr = (h->u.def.value
754                               + h->u.def.section->output_section->vma
755                               + h->u.def.section->output_offset);
756 }
757
758 /* Return 1 if the address is in banked memory.
759    This can be applied to a virtual address and to a physical address.  */
760 int
761 m68hc11_addr_is_banked (struct m68hc11_page_info *pinfo, bfd_vma addr)
762 {
763   if (addr >= pinfo->bank_virtual)
764     return 1;
765
766   if (addr >= pinfo->bank_physical && addr <= pinfo->bank_physical_end)
767     return 1;
768
769   return 0;
770 }
771
772 /* Return the physical address seen by the processor, taking
773    into account banked memory.  */
774 bfd_vma
775 m68hc11_phys_addr (struct m68hc11_page_info *pinfo, bfd_vma addr)
776 {
777   if (addr < pinfo->bank_virtual)
778     return addr;
779
780   /* Map the address to the memory bank.  */
781   addr -= pinfo->bank_virtual;
782   addr &= pinfo->bank_mask;
783   addr += pinfo->bank_physical;
784   return addr;
785 }
786
787 /* Return the page number corresponding to an address in banked memory.  */
788 bfd_vma
789 m68hc11_phys_page (struct m68hc11_page_info *pinfo, bfd_vma addr)
790 {
791   if (addr < pinfo->bank_virtual)
792     return 0;
793
794   /* Map the address to the memory bank.  */
795   addr -= pinfo->bank_virtual;
796   addr >>= pinfo->bank_shift;
797   addr &= 0x0ff;
798   return addr;
799 }
800
801 /* This function is used for relocs which are only used for relaxing,
802    which the linker should otherwise ignore.  */
803
804 bfd_reloc_status_type
805 m68hc11_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
806                           arelent *reloc_entry,
807                           asymbol *symbol ATTRIBUTE_UNUSED,
808                           void *data ATTRIBUTE_UNUSED,
809                           asection *input_section,
810                           bfd *output_bfd,
811                           char **error_message ATTRIBUTE_UNUSED)
812 {
813   if (output_bfd != NULL)
814     reloc_entry->address += input_section->output_offset;
815   return bfd_reloc_ok;
816 }
817
818 bfd_reloc_status_type
819 m68hc11_elf_special_reloc (bfd *abfd ATTRIBUTE_UNUSED,
820                            arelent *reloc_entry,
821                            asymbol *symbol,
822                            void *data ATTRIBUTE_UNUSED,
823                            asection *input_section,
824                            bfd *output_bfd,
825                            char **error_message ATTRIBUTE_UNUSED)
826 {
827   if (output_bfd != (bfd *) NULL
828       && (symbol->flags & BSF_SECTION_SYM) == 0
829       && (! reloc_entry->howto->partial_inplace
830           || reloc_entry->addend == 0))
831     {
832       reloc_entry->address += input_section->output_offset;
833       return bfd_reloc_ok;
834     }
835
836   if (output_bfd != NULL)
837     return bfd_reloc_continue;
838
839   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
840     return bfd_reloc_outofrange;
841
842   abort();
843 }
844
845 /* Look through the relocs for a section during the first phase.
846    Since we don't do .gots or .plts, we just need to consider the
847    virtual table relocs for gc.  */
848
849 bfd_boolean
850 elf32_m68hc11_check_relocs (bfd *abfd, struct bfd_link_info *info,
851                             asection *sec, const Elf_Internal_Rela *relocs)
852 {
853   Elf_Internal_Shdr *           symtab_hdr;
854   struct elf_link_hash_entry ** sym_hashes;
855   const Elf_Internal_Rela *     rel;
856   const Elf_Internal_Rela *     rel_end;
857
858   if (info->relocatable)
859     return TRUE;
860
861   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
862   sym_hashes = elf_sym_hashes (abfd);
863   rel_end = relocs + sec->reloc_count;
864
865   for (rel = relocs; rel < rel_end; rel++)
866     {
867       struct elf_link_hash_entry * h;
868       unsigned long r_symndx;
869
870       r_symndx = ELF32_R_SYM (rel->r_info);
871
872       if (r_symndx < symtab_hdr->sh_info)
873         h = NULL;
874       else
875         {
876           h = sym_hashes [r_symndx - symtab_hdr->sh_info];
877           while (h->root.type == bfd_link_hash_indirect
878                  || h->root.type == bfd_link_hash_warning)
879             h = (struct elf_link_hash_entry *) h->root.u.i.link;
880         }
881
882       switch (ELF32_R_TYPE (rel->r_info))
883         {
884         /* This relocation describes the C++ object vtable hierarchy.
885            Reconstruct it for later use during GC.  */
886         case R_M68HC11_GNU_VTINHERIT:
887           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
888             return FALSE;
889           break;
890
891         /* This relocation describes which C++ vtable entries are actually
892            used.  Record for later use during GC.  */
893         case R_M68HC11_GNU_VTENTRY:
894           BFD_ASSERT (h != NULL);
895           if (h != NULL
896               && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
897             return FALSE;
898           break;
899         }
900     }
901
902   return TRUE;
903 }
904
905 /* Relocate a 68hc11/68hc12 ELF section.  */
906 bfd_boolean
907 elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
908                                 struct bfd_link_info *info,
909                                 bfd *input_bfd, asection *input_section,
910                                 bfd_byte *contents, Elf_Internal_Rela *relocs,
911                                 Elf_Internal_Sym *local_syms,
912                                 asection **local_sections)
913 {
914   Elf_Internal_Shdr *symtab_hdr;
915   struct elf_link_hash_entry **sym_hashes;
916   Elf_Internal_Rela *rel, *relend;
917   const char *name = NULL;
918   struct m68hc11_page_info *pinfo;
919   const struct elf_backend_data * const ebd = get_elf_backend_data (input_bfd);
920   struct m68hc11_elf_link_hash_table *htab;
921
922   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
923   sym_hashes = elf_sym_hashes (input_bfd);
924
925   htab = m68hc11_elf_hash_table (info);
926   if (htab == NULL)
927     return FALSE;
928
929   /* Get memory bank parameters.  */
930   m68hc11_elf_get_bank_parameters (info);
931
932   pinfo = & htab->pinfo;
933   rel = relocs;
934   relend = relocs + input_section->reloc_count;
935
936   for (; rel < relend; rel++)
937     {
938       int r_type;
939       arelent arel;
940       reloc_howto_type *howto;
941       unsigned long r_symndx;
942       Elf_Internal_Sym *sym;
943       asection *sec;
944       bfd_vma relocation = 0;
945       bfd_reloc_status_type r = bfd_reloc_undefined;
946       bfd_vma phys_page;
947       bfd_vma phys_addr;
948       bfd_vma insn_addr;
949       bfd_vma insn_page;
950       bfd_boolean is_far = FALSE;
951       struct elf_link_hash_entry *h;
952       bfd_vma val;
953
954       r_symndx = ELF32_R_SYM (rel->r_info);
955       r_type = ELF32_R_TYPE (rel->r_info);
956
957       if (r_type == R_M68HC11_GNU_VTENTRY
958           || r_type == R_M68HC11_GNU_VTINHERIT )
959         continue;
960
961       (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
962       howto = arel.howto;
963
964       h = NULL;
965       sym = NULL;
966       sec = NULL;
967       if (r_symndx < symtab_hdr->sh_info)
968         {
969           sym = local_syms + r_symndx;
970           sec = local_sections[r_symndx];
971           relocation = (sec->output_section->vma
972                         + sec->output_offset
973                         + sym->st_value);
974           is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
975         }
976       else
977         {
978           bfd_boolean unresolved_reloc, warned;
979
980           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
981                                    r_symndx, symtab_hdr, sym_hashes,
982                                    h, sec, relocation, unresolved_reloc,
983                                    warned);
984
985           is_far = (h && (h->other & STO_M68HC12_FAR));
986         }
987
988       if (sec != NULL && discarded_section (sec))
989         RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
990                                          rel, 1, relend, howto, 0, contents);
991
992       if (info->relocatable)
993         {
994           /* This is a relocatable link.  We don't have to change
995              anything, unless the reloc is against a section symbol,
996              in which case we have to adjust according to where the
997              section symbol winds up in the output section.  */
998           if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
999             rel->r_addend += sec->output_offset;
1000           continue;
1001         }
1002
1003       if (h != NULL)
1004         name = h->root.root.string;
1005       else
1006         {
1007           name = (bfd_elf_string_from_elf_section
1008                   (input_bfd, symtab_hdr->sh_link, sym->st_name));
1009           if (name == NULL || *name == '\0')
1010             name = bfd_section_name (input_bfd, sec);
1011         }
1012
1013       if (is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16)
1014         {
1015           struct elf32_m68hc11_stub_hash_entry* stub;
1016
1017           stub = m68hc12_stub_hash_lookup (htab->stub_hash_table,
1018                                            name, FALSE, FALSE);
1019           if (stub)
1020             {
1021               relocation = stub->stub_offset
1022                 + stub->stub_sec->output_section->vma
1023                 + stub->stub_sec->output_offset;
1024               is_far = FALSE;
1025             }
1026         }
1027
1028       /* Do the memory bank mapping.  */
1029       phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend);
1030       phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend);
1031       switch (r_type)
1032         {
1033         case R_M68HC12_LO8XG:
1034           /* This relocation is specific to XGATE IMM16 calls and will precede
1035              a HI8. tc-m68hc11 only generates them in pairs.
1036              Leave the relocation to the HI8XG step.  */
1037           r = bfd_reloc_ok;
1038           r_type = R_M68HC11_NONE;
1039           break;
1040
1041         case R_M68HC12_HI8XG:
1042           /* This relocation is specific to XGATE IMM16 calls and must follow
1043              a LO8XG. Does not actually check that it was a LO8XG.
1044              Adjusts high and low bytes.  */
1045           relocation = phys_addr;
1046           if ((elf_elfheader (input_bfd)->e_flags & E_M68HC11_XGATE_RAMOFFSET)
1047               && (relocation >= 0x2000))
1048             relocation += 0xc000; /* HARDCODED RAM offset for XGATE.  */
1049
1050           /* Fetch 16 bit value including low byte in previous insn.  */
1051           val = (bfd_get_8 (input_bfd, (bfd_byte*) contents + rel->r_offset) << 8)
1052             | bfd_get_8 (input_bfd, (bfd_byte*) contents + rel->r_offset - 2);
1053
1054           /* Add on value to preserve carry, then write zero to high byte.  */
1055           relocation += val;
1056
1057           /* Write out top byte.  */
1058           bfd_put_8 (input_bfd, (relocation >> 8) & 0xff,
1059                      (bfd_byte*) contents + rel->r_offset);
1060
1061           /* Write out low byte to previous instruction.  */
1062           bfd_put_8 (input_bfd, relocation & 0xff,
1063                      (bfd_byte*) contents + rel->r_offset - 2);
1064
1065           /* Mark as relocation completed.  */
1066           r = bfd_reloc_ok;
1067           r_type = R_M68HC11_NONE;
1068           break;
1069
1070         /* The HI8 and LO8 relocs are generated by %hi(expr) %lo(expr)
1071            assembler directives. %hi does not support carry.  */
1072         case R_M68HC11_HI8:
1073         case R_M68HC11_LO8:
1074           relocation = phys_addr;
1075           break;
1076
1077         case R_M68HC11_24:
1078           /* Reloc used by 68HC12 call instruction.  */
1079           bfd_put_16 (input_bfd, phys_addr,
1080                       (bfd_byte*) contents + rel->r_offset);
1081           bfd_put_8 (input_bfd, phys_page,
1082                      (bfd_byte*) contents + rel->r_offset + 2);
1083           r = bfd_reloc_ok;
1084           r_type = R_M68HC11_NONE;
1085           break;
1086
1087         case R_M68HC11_NONE:
1088           r = bfd_reloc_ok;
1089           break;
1090
1091         case R_M68HC11_LO16:
1092           /* Reloc generated by %addr(expr) gas to obtain the
1093              address as mapped in the memory bank window.  */
1094           relocation = phys_addr;
1095           break;
1096
1097         case R_M68HC11_PAGE:
1098           /* Reloc generated by %page(expr) gas to obtain the
1099              page number associated with the address.  */
1100           relocation = phys_page;
1101           break;
1102
1103         case R_M68HC11_16:
1104           /* Get virtual address of instruction having the relocation.  */
1105           if (is_far)
1106             {
1107               const char* msg;
1108               char* buf;
1109               msg = _("Reference to the far symbol `%s' using a wrong "
1110                       "relocation may result in incorrect execution");
1111               buf = alloca (strlen (msg) + strlen (name) + 10);
1112               sprintf (buf, msg, name);
1113               
1114               (* info->callbacks->warning)
1115                 (info, buf, name, input_bfd, NULL, rel->r_offset);
1116             }
1117
1118           /* Get virtual address of instruction having the relocation.  */
1119           insn_addr = input_section->output_section->vma
1120             + input_section->output_offset
1121             + rel->r_offset;
1122
1123           insn_page = m68hc11_phys_page (pinfo, insn_addr);
1124
1125           if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend)
1126               && m68hc11_addr_is_banked (pinfo, insn_addr)
1127               && phys_page != insn_page)
1128             {
1129               const char* msg;
1130               char* buf;
1131
1132               msg = _("banked address [%lx:%04lx] (%lx) is not in the same bank "
1133                       "as current banked address [%lx:%04lx] (%lx)");
1134
1135               buf = alloca (strlen (msg) + 128);
1136               sprintf (buf, msg, phys_page, phys_addr,
1137                        (long) (relocation + rel->r_addend),
1138                        insn_page, m68hc11_phys_addr (pinfo, insn_addr),
1139                        (long) (insn_addr));
1140               if (!((*info->callbacks->warning)
1141                     (info, buf, name, input_bfd, input_section,
1142                      rel->r_offset)))
1143                 return FALSE;
1144               break;
1145             }
1146           if (phys_page != 0 && insn_page == 0)
1147             {
1148               const char* msg;
1149               char* buf;
1150
1151               msg = _("reference to a banked address [%lx:%04lx] in the "
1152                       "normal address space at %04lx");
1153
1154               buf = alloca (strlen (msg) + 128);
1155               sprintf (buf, msg, phys_page, phys_addr, insn_addr);
1156               if (!((*info->callbacks->warning)
1157                     (info, buf, name, input_bfd, input_section,
1158                      insn_addr)))
1159                 return FALSE;
1160
1161               relocation = phys_addr;
1162               break;
1163             }
1164
1165           /* If this is a banked address use the phys_addr so that
1166              we stay in the banked window.  */
1167           if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend))
1168             relocation = phys_addr;
1169           break;
1170         }
1171
1172       if (r_type != R_M68HC11_NONE)
1173         {
1174           if ((r_type == R_M68HC12_PCREL_9) || (r_type == R_M68HC12_PCREL_10))
1175             r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1176                                       contents, rel->r_offset,
1177                                       relocation - 2, rel->r_addend);
1178           else
1179             r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1180                                           contents, rel->r_offset,
1181                                           relocation, rel->r_addend);
1182         }
1183
1184       if (r != bfd_reloc_ok)
1185         {
1186           const char * msg = (const char *) 0;
1187
1188           switch (r)
1189             {
1190             case bfd_reloc_overflow:
1191               if (!((*info->callbacks->reloc_overflow)
1192                     (info, NULL, name, howto->name, (bfd_vma) 0,
1193                      input_bfd, input_section, rel->r_offset)))
1194                 return FALSE;
1195               break;
1196
1197             case bfd_reloc_undefined:
1198               if (!((*info->callbacks->undefined_symbol)
1199                     (info, name, input_bfd, input_section,
1200                      rel->r_offset, TRUE)))
1201                 return FALSE;
1202               break;
1203
1204             case bfd_reloc_outofrange:
1205               msg = _ ("internal error: out of range error");
1206               goto common_error;
1207
1208             case bfd_reloc_notsupported:
1209               msg = _ ("internal error: unsupported relocation error");
1210               goto common_error;
1211
1212             case bfd_reloc_dangerous:
1213               msg = _ ("internal error: dangerous error");
1214               goto common_error;
1215
1216             default:
1217               msg = _ ("internal error: unknown error");
1218               /* fall through */
1219
1220             common_error:
1221               if (!((*info->callbacks->warning)
1222                     (info, msg, name, input_bfd, input_section,
1223                      rel->r_offset)))
1224                 return FALSE;
1225               break;
1226             }
1227         }
1228     }
1229
1230   return TRUE;
1231 }
1232
1233
1234 \f
1235 /* Set and control ELF flags in ELF header.  */
1236
1237 bfd_boolean
1238 _bfd_m68hc11_elf_set_private_flags (bfd *abfd, flagword flags)
1239 {
1240   BFD_ASSERT (!elf_flags_init (abfd)
1241               || elf_elfheader (abfd)->e_flags == flags);
1242
1243   elf_elfheader (abfd)->e_flags = flags;
1244   elf_flags_init (abfd) = TRUE;
1245   return TRUE;
1246 }
1247
1248 /* Merge backend specific data from an object file to the output
1249    object file when linking.  */
1250
1251 bfd_boolean
1252 _bfd_m68hc11_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
1253 {
1254   flagword old_flags;
1255   flagword new_flags;
1256   bfd_boolean ok = TRUE;
1257
1258   /* Check if we have the same endianness */
1259   if (!_bfd_generic_verify_endian_match (ibfd, obfd))
1260     return FALSE;
1261
1262   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1263       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1264     return TRUE;
1265
1266   new_flags = elf_elfheader (ibfd)->e_flags;
1267   elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
1268   old_flags = elf_elfheader (obfd)->e_flags;
1269
1270   if (! elf_flags_init (obfd))
1271     {
1272       elf_flags_init (obfd) = TRUE;
1273       elf_elfheader (obfd)->e_flags = new_flags;
1274       elf_elfheader (obfd)->e_ident[EI_CLASS]
1275         = elf_elfheader (ibfd)->e_ident[EI_CLASS];
1276
1277       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1278           && bfd_get_arch_info (obfd)->the_default)
1279         {
1280           if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
1281                                    bfd_get_mach (ibfd)))
1282             return FALSE;
1283         }
1284
1285       return TRUE;
1286     }
1287
1288   /* Check ABI compatibility.  */
1289   if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
1290     {
1291       (*_bfd_error_handler)
1292         (_("%B: linking files compiled for 16-bit integers (-mshort) "
1293            "and others for 32-bit integers"), ibfd);
1294       ok = FALSE;
1295     }
1296   if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
1297     {
1298       (*_bfd_error_handler)
1299         (_("%B: linking files compiled for 32-bit double (-fshort-double) "
1300            "and others for 64-bit double"), ibfd);
1301       ok = FALSE;
1302     }
1303
1304   /* Processor compatibility.  */
1305   if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags))
1306     {
1307       (*_bfd_error_handler)
1308         (_("%B: linking files compiled for HCS12 with "
1309            "others compiled for HC12"), ibfd);
1310       ok = FALSE;
1311     }
1312   new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK)
1313                | (EF_M68HC11_MERGE_MACH (new_flags, old_flags)));
1314
1315   elf_elfheader (obfd)->e_flags = new_flags;
1316
1317   new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
1318   old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
1319
1320   /* Warn about any other mismatches */
1321   if (new_flags != old_flags)
1322     {
1323       (*_bfd_error_handler)
1324         (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
1325          ibfd, (unsigned long) new_flags, (unsigned long) old_flags);
1326       ok = FALSE;
1327     }
1328
1329   if (! ok)
1330     {
1331       bfd_set_error (bfd_error_bad_value);
1332       return FALSE;
1333     }
1334
1335   return TRUE;
1336 }
1337
1338 bfd_boolean
1339 _bfd_m68hc11_elf_print_private_bfd_data (bfd *abfd, void *ptr)
1340 {
1341   FILE *file = (FILE *) ptr;
1342
1343   BFD_ASSERT (abfd != NULL && ptr != NULL);
1344
1345   /* Print normal ELF private data.  */
1346   _bfd_elf_print_private_bfd_data (abfd, ptr);
1347
1348   /* xgettext:c-format */
1349   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1350
1351   if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
1352     fprintf (file, _("[abi=32-bit int, "));
1353   else
1354     fprintf (file, _("[abi=16-bit int, "));
1355
1356   if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
1357     fprintf (file, _("64-bit double, "));
1358   else
1359     fprintf (file, _("32-bit double, "));
1360
1361   if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0)
1362     fprintf (file, _("cpu=HC11]"));
1363   else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
1364     fprintf (file, _("cpu=HCS12]"));
1365   else
1366     fprintf (file, _("cpu=HC12]"));    
1367
1368   if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
1369     fprintf (file, _(" [memory=bank-model]"));
1370   else
1371     fprintf (file, _(" [memory=flat]"));
1372
1373   if (elf_elfheader (abfd)->e_flags & E_M68HC11_XGATE_RAMOFFSET)
1374     fprintf (file, _(" [XGATE RAM offsetting]"));
1375
1376   fputc ('\n', file);
1377
1378   return TRUE;
1379 }
1380
1381 static void scan_sections_for_abi (bfd *abfd ATTRIBUTE_UNUSED,
1382                                    asection *asect, void *arg)
1383 {
1384   struct m68hc11_scan_param* p = (struct m68hc11_scan_param*) arg;
1385
1386   if (asect->vma >= p->pinfo->bank_virtual)
1387     p->use_memory_banks = TRUE;
1388 }
1389   
1390 /* Tweak the OSABI field of the elf header.  */
1391
1392 void
1393 elf32_m68hc11_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
1394 {
1395   struct m68hc11_scan_param param;
1396   struct m68hc11_elf_link_hash_table *htab;
1397
1398   if (link_info == NULL)
1399     return;
1400
1401   htab = m68hc11_elf_hash_table (link_info);
1402   if (htab == NULL)
1403     return;
1404
1405   m68hc11_elf_get_bank_parameters (link_info);
1406
1407   param.use_memory_banks = FALSE;
1408   param.pinfo = & htab->pinfo;
1409
1410   bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
1411
1412   if (param.use_memory_banks)
1413     {
1414       Elf_Internal_Ehdr * i_ehdrp;
1415
1416       i_ehdrp = elf_elfheader (abfd);
1417       i_ehdrp->e_flags |= E_M68HC12_BANKS;
1418     }
1419 }