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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [bfd/] [elf32-m68hc1x.c] - Blame information for rev 373

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

Line No. Rev Author Line
1 227 jeremybenn
/* Motorola 68HC11/HC12-specific support for 32-bit ELF
2
   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3
   2009, 2010  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
      const char* stub_name = 0;
939
 
940
      r_symndx = ELF32_R_SYM (rel->r_info);
941
      r_type = ELF32_R_TYPE (rel->r_info);
942
 
943
      if (r_type == R_M68HC11_GNU_VTENTRY
944
          || r_type == R_M68HC11_GNU_VTINHERIT )
945
        continue;
946
 
947
      (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
948
      howto = arel.howto;
949
 
950
      h = NULL;
951
      sym = NULL;
952
      sec = NULL;
953
      if (r_symndx < symtab_hdr->sh_info)
954
        {
955
          sym = local_syms + r_symndx;
956
          sec = local_sections[r_symndx];
957
          relocation = (sec->output_section->vma
958
                        + sec->output_offset
959
                        + sym->st_value);
960
          is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
961
          if (is_far)
962
            stub_name = (bfd_elf_string_from_elf_section
963
                         (input_bfd, symtab_hdr->sh_link,
964
                          sym->st_name));
965
        }
966
      else
967
        {
968
          bfd_boolean unresolved_reloc, warned;
969
 
970
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
971
                                   r_symndx, symtab_hdr, sym_hashes,
972
                                   h, sec, relocation, unresolved_reloc,
973
                                   warned);
974
 
975
          is_far = (h && (h->other & STO_M68HC12_FAR));
976
          stub_name = h->root.root.string;
977
        }
978
 
979
      if (sec != NULL && elf_discarded_section (sec))
980
        {
981
          /* For relocs against symbols from removed linkonce sections,
982
             or sections discarded by a linker script, we just want the
983
             section contents zeroed.  Avoid any special processing.  */
984
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
985
          rel->r_info = 0;
986
          rel->r_addend = 0;
987
          continue;
988
        }
989
 
990
      if (info->relocatable)
991
        {
992
          /* This is a relocatable link.  We don't have to change
993
             anything, unless the reloc is against a section symbol,
994
             in which case we have to adjust according to where the
995
             section symbol winds up in the output section.  */
996
          if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
997
            rel->r_addend += sec->output_offset;
998
          continue;
999
        }
1000
 
1001
      if (h != NULL)
1002
        name = h->root.root.string;
1003
      else
1004
        {
1005
          name = (bfd_elf_string_from_elf_section
1006
                  (input_bfd, symtab_hdr->sh_link, sym->st_name));
1007
          if (name == NULL || *name == '\0')
1008
            name = bfd_section_name (input_bfd, sec);
1009
        }
1010
 
1011
      if (is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16)
1012
        {
1013
          struct elf32_m68hc11_stub_hash_entry* stub;
1014
 
1015
          stub = m68hc12_stub_hash_lookup (htab->stub_hash_table,
1016
                                           name, FALSE, FALSE);
1017
          if (stub)
1018
            {
1019
              relocation = stub->stub_offset
1020
                + stub->stub_sec->output_section->vma
1021
                + stub->stub_sec->output_offset;
1022
              is_far = FALSE;
1023
            }
1024
        }
1025
 
1026
      /* Do the memory bank mapping.  */
1027
      phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend);
1028
      phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend);
1029
      switch (r_type)
1030
        {
1031
        case R_M68HC11_24:
1032
          /* Reloc used by 68HC12 call instruction.  */
1033
          bfd_put_16 (input_bfd, phys_addr,
1034
                      (bfd_byte*) contents + rel->r_offset);
1035
          bfd_put_8 (input_bfd, phys_page,
1036
                     (bfd_byte*) contents + rel->r_offset + 2);
1037
          r = bfd_reloc_ok;
1038
          r_type = R_M68HC11_NONE;
1039
          break;
1040
 
1041
        case R_M68HC11_NONE:
1042
          r = bfd_reloc_ok;
1043
          break;
1044
 
1045
        case R_M68HC11_LO16:
1046
          /* Reloc generated by %addr(expr) gas to obtain the
1047
             address as mapped in the memory bank window.  */
1048
          relocation = phys_addr;
1049
          break;
1050
 
1051
        case R_M68HC11_PAGE:
1052
          /* Reloc generated by %page(expr) gas to obtain the
1053
             page number associated with the address.  */
1054
          relocation = phys_page;
1055
          break;
1056
 
1057
        case R_M68HC11_16:
1058
          /* Get virtual address of instruction having the relocation.  */
1059
          if (is_far)
1060
            {
1061
              const char* msg;
1062
              char* buf;
1063
              msg = _("Reference to the far symbol `%s' using a wrong "
1064
                      "relocation may result in incorrect execution");
1065
              buf = alloca (strlen (msg) + strlen (name) + 10);
1066
              sprintf (buf, msg, name);
1067
 
1068
              (* info->callbacks->warning)
1069
                (info, buf, name, input_bfd, NULL, rel->r_offset);
1070
            }
1071
 
1072
          /* Get virtual address of instruction having the relocation.  */
1073
          insn_addr = input_section->output_section->vma
1074
            + input_section->output_offset
1075
            + rel->r_offset;
1076
 
1077
          insn_page = m68hc11_phys_page (pinfo, insn_addr);
1078
 
1079
          if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend)
1080
              && m68hc11_addr_is_banked (pinfo, insn_addr)
1081
              && phys_page != insn_page)
1082
            {
1083
              const char* msg;
1084
              char* buf;
1085
 
1086
              msg = _("banked address [%lx:%04lx] (%lx) is not in the same bank "
1087
                      "as current banked address [%lx:%04lx] (%lx)");
1088
 
1089
              buf = alloca (strlen (msg) + 128);
1090
              sprintf (buf, msg, phys_page, phys_addr,
1091
                       (long) (relocation + rel->r_addend),
1092
                       insn_page, m68hc11_phys_addr (pinfo, insn_addr),
1093
                       (long) (insn_addr));
1094
              if (!((*info->callbacks->warning)
1095
                    (info, buf, name, input_bfd, input_section,
1096
                     rel->r_offset)))
1097
                return FALSE;
1098
              break;
1099
            }
1100
          if (phys_page != 0 && insn_page == 0)
1101
            {
1102
              const char* msg;
1103
              char* buf;
1104
 
1105
              msg = _("reference to a banked address [%lx:%04lx] in the "
1106
                      "normal address space at %04lx");
1107
 
1108
              buf = alloca (strlen (msg) + 128);
1109
              sprintf (buf, msg, phys_page, phys_addr, insn_addr);
1110
              if (!((*info->callbacks->warning)
1111
                    (info, buf, name, input_bfd, input_section,
1112
                     insn_addr)))
1113
                return FALSE;
1114
 
1115
              relocation = phys_addr;
1116
              break;
1117
            }
1118
 
1119
          /* If this is a banked address use the phys_addr so that
1120
             we stay in the banked window.  */
1121
          if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend))
1122
            relocation = phys_addr;
1123
          break;
1124
        }
1125
      if (r_type != R_M68HC11_NONE)
1126
        r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1127
                                      contents, rel->r_offset,
1128
                                      relocation, rel->r_addend);
1129
 
1130
      if (r != bfd_reloc_ok)
1131
        {
1132
          const char * msg = (const char *) 0;
1133
 
1134
          switch (r)
1135
            {
1136
            case bfd_reloc_overflow:
1137
              if (!((*info->callbacks->reloc_overflow)
1138
                    (info, NULL, name, howto->name, (bfd_vma) 0,
1139
                     input_bfd, input_section, rel->r_offset)))
1140
                return FALSE;
1141
              break;
1142
 
1143
            case bfd_reloc_undefined:
1144
              if (!((*info->callbacks->undefined_symbol)
1145
                    (info, name, input_bfd, input_section,
1146
                     rel->r_offset, TRUE)))
1147
                return FALSE;
1148
              break;
1149
 
1150
            case bfd_reloc_outofrange:
1151
              msg = _ ("internal error: out of range error");
1152
              goto common_error;
1153
 
1154
            case bfd_reloc_notsupported:
1155
              msg = _ ("internal error: unsupported relocation error");
1156
              goto common_error;
1157
 
1158
            case bfd_reloc_dangerous:
1159
              msg = _ ("internal error: dangerous error");
1160
              goto common_error;
1161
 
1162
            default:
1163
              msg = _ ("internal error: unknown error");
1164
              /* fall through */
1165
 
1166
            common_error:
1167
              if (!((*info->callbacks->warning)
1168
                    (info, msg, name, input_bfd, input_section,
1169
                     rel->r_offset)))
1170
                return FALSE;
1171
              break;
1172
            }
1173
        }
1174
    }
1175
 
1176
  return TRUE;
1177
}
1178
 
1179
 
1180
 
1181
/* Set and control ELF flags in ELF header.  */
1182
 
1183
bfd_boolean
1184
_bfd_m68hc11_elf_set_private_flags (bfd *abfd, flagword flags)
1185
{
1186
  BFD_ASSERT (!elf_flags_init (abfd)
1187
              || elf_elfheader (abfd)->e_flags == flags);
1188
 
1189
  elf_elfheader (abfd)->e_flags = flags;
1190
  elf_flags_init (abfd) = TRUE;
1191
  return TRUE;
1192
}
1193
 
1194
/* Merge backend specific data from an object file to the output
1195
   object file when linking.  */
1196
 
1197
bfd_boolean
1198
_bfd_m68hc11_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
1199
{
1200
  flagword old_flags;
1201
  flagword new_flags;
1202
  bfd_boolean ok = TRUE;
1203
 
1204
  /* Check if we have the same endianess */
1205
  if (!_bfd_generic_verify_endian_match (ibfd, obfd))
1206
    return FALSE;
1207
 
1208
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1209
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1210
    return TRUE;
1211
 
1212
  new_flags = elf_elfheader (ibfd)->e_flags;
1213
  elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
1214
  old_flags = elf_elfheader (obfd)->e_flags;
1215
 
1216
  if (! elf_flags_init (obfd))
1217
    {
1218
      elf_flags_init (obfd) = TRUE;
1219
      elf_elfheader (obfd)->e_flags = new_flags;
1220
      elf_elfheader (obfd)->e_ident[EI_CLASS]
1221
        = elf_elfheader (ibfd)->e_ident[EI_CLASS];
1222
 
1223
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1224
          && bfd_get_arch_info (obfd)->the_default)
1225
        {
1226
          if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
1227
                                   bfd_get_mach (ibfd)))
1228
            return FALSE;
1229
        }
1230
 
1231
      return TRUE;
1232
    }
1233
 
1234
  /* Check ABI compatibility.  */
1235
  if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
1236
    {
1237
      (*_bfd_error_handler)
1238
        (_("%B: linking files compiled for 16-bit integers (-mshort) "
1239
           "and others for 32-bit integers"), ibfd);
1240
      ok = FALSE;
1241
    }
1242
  if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
1243
    {
1244
      (*_bfd_error_handler)
1245
        (_("%B: linking files compiled for 32-bit double (-fshort-double) "
1246
           "and others for 64-bit double"), ibfd);
1247
      ok = FALSE;
1248
    }
1249
 
1250
  /* Processor compatibility.  */
1251
  if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags))
1252
    {
1253
      (*_bfd_error_handler)
1254
        (_("%B: linking files compiled for HCS12 with "
1255
           "others compiled for HC12"), ibfd);
1256
      ok = FALSE;
1257
    }
1258
  new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK)
1259
               | (EF_M68HC11_MERGE_MACH (new_flags, old_flags)));
1260
 
1261
  elf_elfheader (obfd)->e_flags = new_flags;
1262
 
1263
  new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
1264
  old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
1265
 
1266
  /* Warn about any other mismatches */
1267
  if (new_flags != old_flags)
1268
    {
1269
      (*_bfd_error_handler)
1270
        (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
1271
         ibfd, (unsigned long) new_flags, (unsigned long) old_flags);
1272
      ok = FALSE;
1273
    }
1274
 
1275
  if (! ok)
1276
    {
1277
      bfd_set_error (bfd_error_bad_value);
1278
      return FALSE;
1279
    }
1280
 
1281
  return TRUE;
1282
}
1283
 
1284
bfd_boolean
1285
_bfd_m68hc11_elf_print_private_bfd_data (bfd *abfd, void *ptr)
1286
{
1287
  FILE *file = (FILE *) ptr;
1288
 
1289
  BFD_ASSERT (abfd != NULL && ptr != NULL);
1290
 
1291
  /* Print normal ELF private data.  */
1292
  _bfd_elf_print_private_bfd_data (abfd, ptr);
1293
 
1294
  /* xgettext:c-format */
1295
  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1296
 
1297
  if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
1298
    fprintf (file, _("[abi=32-bit int, "));
1299
  else
1300
    fprintf (file, _("[abi=16-bit int, "));
1301
 
1302
  if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
1303
    fprintf (file, _("64-bit double, "));
1304
  else
1305
    fprintf (file, _("32-bit double, "));
1306
 
1307
  if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0)
1308
    fprintf (file, _("cpu=HC11]"));
1309
  else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
1310
    fprintf (file, _("cpu=HCS12]"));
1311
  else
1312
    fprintf (file, _("cpu=HC12]"));
1313
 
1314
  if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
1315
    fprintf (file, _(" [memory=bank-model]"));
1316
  else
1317
    fprintf (file, _(" [memory=flat]"));
1318
 
1319
  fputc ('\n', file);
1320
 
1321
  return TRUE;
1322
}
1323
 
1324
static void scan_sections_for_abi (bfd *abfd ATTRIBUTE_UNUSED,
1325
                                   asection *asect, void *arg)
1326
{
1327
  struct m68hc11_scan_param* p = (struct m68hc11_scan_param*) arg;
1328
 
1329
  if (asect->vma >= p->pinfo->bank_virtual)
1330
    p->use_memory_banks = TRUE;
1331
}
1332
 
1333
/* Tweak the OSABI field of the elf header.  */
1334
 
1335
void
1336
elf32_m68hc11_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
1337
{
1338
  struct m68hc11_scan_param param;
1339
  struct m68hc11_elf_link_hash_table *htab;
1340
 
1341
  if (link_info == NULL)
1342
    return;
1343
 
1344
  htab = m68hc11_elf_hash_table (link_info);
1345
  if (htab == NULL)
1346
    return;
1347
 
1348
  m68hc11_elf_get_bank_parameters (link_info);
1349
 
1350
  param.use_memory_banks = FALSE;
1351
  param.pinfo = & htab->pinfo;
1352
 
1353
  bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
1354
 
1355
  if (param.use_memory_banks)
1356
    {
1357
      Elf_Internal_Ehdr * i_ehdrp;
1358
 
1359
      i_ehdrp = elf_elfheader (abfd);
1360
      i_ehdrp->e_flags |= E_M68HC12_BANKS;
1361
    }
1362
}

powered by: WebSVN 2.1.0

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