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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [bfd/] [elf32-m68hc1x.c] - Blame information for rev 205

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* Motorola 68HC11/HC12-specific support for 32-bit ELF
2
   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3
   2009 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
    {
79
      free (ret);
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
    {
88
      free (ret);
89
      return NULL;
90
    }
91
  if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc,
92
                            sizeof (struct elf32_m68hc11_stub_hash_entry)))
93
    return NULL;
94
 
95
  ret->stub_bfd = NULL;
96
  ret->stub_section = 0;
97
  ret->add_stub_section = NULL;
98
  ret->sym_cache.abfd = NULL;
99
 
100
  return ret;
101
}
102
 
103
/* Free the derived linker hash table.  */
104
 
105
void
106
m68hc11_elf_bfd_link_hash_table_free (struct bfd_link_hash_table *hash)
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
 
120
static struct bfd_hash_entry *
121
stub_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
122
                   const char *string)
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
 
154
static struct elf32_m68hc11_stub_hash_entry *
155
m68hc12_add_stub (const char *stub_name, asection *section,
156
                  struct m68hc11_elf_link_hash_table *htab)
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
    {
165
      (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
166
                             section->owner, stub_name);
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
 
185
bfd_boolean
186
elf32_m68hc11_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
187
                               Elf_Internal_Sym *sym,
188
                               const char **namep ATTRIBUTE_UNUSED,
189
                               flagword *flagsp ATTRIBUTE_UNUSED,
190
                               asection **secp ATTRIBUTE_UNUSED,
191
                               bfd_vma *valp ATTRIBUTE_UNUSED)
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
 
221
 
222
int
223
elf32_m68hc11_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
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
 
236
  if (bfd_get_flavour (info->output_bfd) != bfd_target_elf_flavour)
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
272
     strip_excluded_output_sections doesn't renumber the indices.  */
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
 
312
bfd_boolean
313
elf32_m68hc11_size_stubs (bfd *output_bfd, bfd *stub_bfd,
314
                          struct bfd_link_info *info,
315
                          asection * (*add_stub_section) (const char*, asection*))
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;
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
 
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
        }
368
      if (local_syms == NULL)
369
        {
370
          free (all_local_syms);
371
          return FALSE;
372
        }
373
 
374
      all_local_syms[bfd_indx] = local_syms;
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
415
            = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
416
                                         (Elf_Internal_Rela *) NULL,
417
                                         info->keep_memory);
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;
450
                  is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
451
                  if (!is_far)
452
                    continue;
453
 
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
                    }
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
482
                      || hash->root.type == bfd_link_hash_defweak
483
                      || hash->root.type == bfd_link_hash_new)
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->size = 0;
547
        }
548
 
549
      bfd_hash_traverse (htab->stub_hash_table, htab->size_one_stub, htab);
550
    }
551
  free (all_local_syms);
552
  return TRUE;
553
 
554
 error_ret_free_local:
555
  free (all_local_syms);
556
  return FALSE;
557
}
558
 
559
/* Export the trampoline addresses in the symbol table.  */
560
static bfd_boolean
561
m68hc11_elf_export_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
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.  */
590
static void
591
m68hc11_elf_set_symbol (bfd *abfd, struct bfd_link_info *info,
592
                        const char *name, bfd_vma value, asection *sec)
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
 
622
bfd_boolean
623
elf32_m68hc11_build_stubs (bfd *abfd, struct bfd_link_info *info)
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.  */
640
      size = stub_sec->size;
641
      stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
642
      if (stub_sec->contents == NULL && size != 0)
643
        return FALSE;
644
      stub_sec->size = 0;
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
 
675
void
676
m68hc11_elf_get_bank_parameters (struct bfd_link_info *info)
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.  */
735
int
736
m68hc11_addr_is_banked (struct m68hc11_page_info *pinfo, bfd_vma addr)
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.  */
749
bfd_vma
750
m68hc11_phys_addr (struct m68hc11_page_info *pinfo, bfd_vma addr)
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.  */
763
bfd_vma
764
m68hc11_phys_page (struct m68hc11_page_info *pinfo, bfd_vma addr)
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
 
779
bfd_reloc_status_type
780
m68hc11_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)
787
{
788
  if (output_bfd != NULL)
789
    reloc_entry->address += input_section->output_offset;
790
  return bfd_reloc_ok;
791
}
792
 
793
bfd_reloc_status_type
794
m68hc11_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)
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
 
814
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
815
    return bfd_reloc_outofrange;
816
 
817
  abort();
818
}
819
 
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
 
824
bfd_boolean
825
elf32_m68hc11_check_relocs (bfd *abfd, struct bfd_link_info *info,
826
                            asection *sec, const Elf_Internal_Rela *relocs)
827
{
828
  Elf_Internal_Shdr *           symtab_hdr;
829
  struct elf_link_hash_entry ** sym_hashes;
830
  const Elf_Internal_Rela *     rel;
831
  const Elf_Internal_Rela *     rel_end;
832
 
833
  if (info->relocatable)
834
    return TRUE;
835
 
836
  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
837
  sym_hashes = elf_sym_hashes (abfd);
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
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
        }
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:
862
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
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:
869
          BFD_ASSERT (h != NULL);
870
          if (h != NULL
871
              && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
872
            return FALSE;
873
          break;
874
        }
875
    }
876
 
877
  return TRUE;
878
}
879
 
880
/* Relocate a 68hc11/68hc12 ELF section.  */
881
bfd_boolean
882
elf32_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)
888
{
889
  Elf_Internal_Shdr *symtab_hdr;
890
  struct elf_link_hash_entry **sym_hashes;
891
  Elf_Internal_Rela *rel, *relend;
892
  const char *name = NULL;
893
  struct m68hc11_page_info *pinfo;
894
  const struct elf_backend_data * const ebd = get_elf_backend_data (input_bfd);
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;
913
      bfd_vma relocation = 0;
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;
919
      bfd_boolean is_far = FALSE;
920
      struct elf_link_hash_entry *h;
921
      const char* stub_name = 0;
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
 
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
 
973
      if (info->relocatable)
974
        {
975
          /* This is a relocatable link.  We don't have to change
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.  */
979
          if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
980
            rel->r_addend += sec->output_offset;
981
          continue;
982
        }
983
 
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
        }
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)
1123
                    (info, NULL, name, howto->name, (bfd_vma) 0,
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
 
1166
/* Set and control ELF flags in ELF header.  */
1167
 
1168
bfd_boolean
1169
_bfd_m68hc11_elf_set_private_flags (bfd *abfd, flagword flags)
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
 
1182
bfd_boolean
1183
_bfd_m68hc11_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
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)
1223
        (_("%B: linking files compiled for 16-bit integers (-mshort) "
1224
           "and others for 32-bit integers"), ibfd);
1225
      ok = FALSE;
1226
    }
1227
  if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
1228
    {
1229
      (*_bfd_error_handler)
1230
        (_("%B: linking files compiled for 32-bit double (-fshort-double) "
1231
           "and others for 64-bit double"), ibfd);
1232
      ok = FALSE;
1233
    }
1234
 
1235
  /* Processor compatibility.  */
1236
  if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags))
1237
    {
1238
      (*_bfd_error_handler)
1239
        (_("%B: linking files compiled for HCS12 with "
1240
           "others compiled for HC12"), ibfd);
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
 
1248
  new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
1249
  old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
1250
 
1251
  /* Warn about any other mismatches */
1252
  if (new_flags != old_flags)
1253
    {
1254
      (*_bfd_error_handler)
1255
        (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
1256
         ibfd, (unsigned long) new_flags, (unsigned long) old_flags);
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
 
1269
bfd_boolean
1270
_bfd_m68hc11_elf_print_private_bfd_data (bfd *abfd, void *ptr)
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
 
1309
static void scan_sections_for_abi (bfd *abfd ATTRIBUTE_UNUSED,
1310
                                   asection *asect, void *arg)
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
 
1320
void
1321
elf32_m68hc11_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
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
 

powered by: WebSVN 2.1.0

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