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