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

Subversion Repositories open8_urisc

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

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

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

powered by: WebSVN 2.1.0

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