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

Subversion Repositories openrisc_me

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

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

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

powered by: WebSVN 2.1.0

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