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

Subversion Repositories openrisc_me

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

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

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

powered by: WebSVN 2.1.0

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