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