OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf32-m68hc1x.c] - Blame information for rev 14

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.