OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

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

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

Line No. Rev Author Line
1 24 jeremybenn
/* 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
                  hdr = elf_elfsections (input_bfd)[sym->st_shndx];
454
                  sym_sec = hdr->bfd_section;
455
                  stub_name = (bfd_elf_string_from_elf_section
456
                               (input_bfd, symtab_hdr->sh_link,
457
                                sym->st_name));
458
                  sym_value = sym->st_value;
459
                  hash = NULL;
460
                }
461
              else
462
                {
463
                  /* It's an external symbol.  */
464
                  int e_indx;
465
 
466
                  e_indx = r_indx - symtab_hdr->sh_info;
467
                  hash = (struct elf_link_hash_entry *)
468
                    (sym_hashes[e_indx]);
469
 
470
                  while (hash->root.type == bfd_link_hash_indirect
471
                         || hash->root.type == bfd_link_hash_warning)
472
                    hash = ((struct elf_link_hash_entry *)
473
                            hash->root.u.i.link);
474
 
475
                  if (hash->root.type == bfd_link_hash_defined
476
                      || hash->root.type == bfd_link_hash_defweak
477
                      || hash->root.type == bfd_link_hash_new)
478
                    {
479
                      if (!(hash->other & STO_M68HC12_FAR))
480
                        continue;
481
                    }
482
                  else if (hash->root.type == bfd_link_hash_undefweak)
483
                    {
484
                      continue;
485
                    }
486
                  else if (hash->root.type == bfd_link_hash_undefined)
487
                    {
488
                      continue;
489
                    }
490
                  else
491
                    {
492
                      bfd_set_error (bfd_error_bad_value);
493
                      goto error_ret_free_internal;
494
                    }
495
                  sym_sec = hash->root.u.def.section;
496
                  sym_value = hash->root.u.def.value;
497
                  stub_name = hash->root.root.string;
498
                }
499
 
500
              if (!stub_name)
501
                goto error_ret_free_internal;
502
 
503
              stub_entry = m68hc12_stub_hash_lookup
504
                (htab->stub_hash_table,
505
                 stub_name,
506
                 FALSE, FALSE);
507
              if (stub_entry == NULL)
508
                {
509
                  if (add_stub_section == 0)
510
                    continue;
511
 
512
                  stub_entry = m68hc12_add_stub (stub_name, section, htab);
513
                  if (stub_entry == NULL)
514
                    {
515
                    error_ret_free_internal:
516
                      if (elf_section_data (section)->relocs == NULL)
517
                        free (internal_relocs);
518
                      goto error_ret_free_local;
519
                    }
520
                }
521
 
522
              stub_entry->target_value = sym_value;
523
              stub_entry->target_section = sym_sec;
524
            }
525
 
526
          /* We're done with the internal relocs, free them.  */
527
          if (elf_section_data (section)->relocs == NULL)
528
            free (internal_relocs);
529
        }
530
    }
531
 
532
  if (add_stub_section)
533
    {
534
      /* OK, we've added some stubs.  Find out the new size of the
535
         stub sections.  */
536
      for (stub_sec = htab->stub_bfd->sections;
537
           stub_sec != NULL;
538
           stub_sec = stub_sec->next)
539
        {
540
          stub_sec->size = 0;
541
        }
542
 
543
      bfd_hash_traverse (htab->stub_hash_table, htab->size_one_stub, htab);
544
    }
545
  free (all_local_syms);
546
  return TRUE;
547
 
548
 error_ret_free_local:
549
  free (all_local_syms);
550
  return FALSE;
551
}
552
 
553
/* Export the trampoline addresses in the symbol table.  */
554
static bfd_boolean
555
m68hc11_elf_export_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
556
{
557
  struct bfd_link_info *info;
558
  struct m68hc11_elf_link_hash_table *htab;
559
  struct elf32_m68hc11_stub_hash_entry *stub_entry;
560
  char* name;
561
  bfd_boolean result;
562
 
563
  info = (struct bfd_link_info *) in_arg;
564
  htab = m68hc11_elf_hash_table (info);
565
 
566
  /* Massage our args to the form they really have.  */
567
  stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
568
 
569
  /* Generate the trampoline according to HC11 or HC12.  */
570
  result = (* htab->build_one_stub) (gen_entry, in_arg);
571
 
572
  /* Make a printable name that does not conflict with the real function.  */
573
  name = alloca (strlen (stub_entry->root.string) + 16);
574
  sprintf (name, "tramp.%s", stub_entry->root.string);
575
 
576
  /* Export the symbol for debugging/disassembling.  */
577
  m68hc11_elf_set_symbol (htab->stub_bfd, info, name,
578
                          stub_entry->stub_offset,
579
                          stub_entry->stub_sec);
580
  return result;
581
}
582
 
583
/* Export a symbol or set its value and section.  */
584
static void
585
m68hc11_elf_set_symbol (bfd *abfd, struct bfd_link_info *info,
586
                        const char *name, bfd_vma value, asection *sec)
587
{
588
  struct elf_link_hash_entry *h;
589
 
590
  h = (struct elf_link_hash_entry *)
591
    bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, FALSE);
592
  if (h == NULL)
593
    {
594
      _bfd_generic_link_add_one_symbol (info, abfd,
595
                                        name,
596
                                        BSF_GLOBAL,
597
                                        sec,
598
                                        value,
599
                                        (const char*) NULL,
600
                                        TRUE, FALSE, NULL);
601
    }
602
  else
603
    {
604
      h->root.type = bfd_link_hash_defined;
605
      h->root.u.def.value = value;
606
      h->root.u.def.section = sec;
607
    }
608
}
609
 
610
 
611
/* Build all the stubs associated with the current output file.  The
612
   stubs are kept in a hash table attached to the main linker hash
613
   table.  This function is called via m68hc12elf_finish in the
614
   linker.  */
615
 
616
bfd_boolean
617
elf32_m68hc11_build_stubs (bfd *abfd, struct bfd_link_info *info)
618
{
619
  asection *stub_sec;
620
  struct bfd_hash_table *table;
621
  struct m68hc11_elf_link_hash_table *htab;
622
  struct m68hc11_scan_param param;
623
 
624
  m68hc11_elf_get_bank_parameters (info);
625
  htab = m68hc11_elf_hash_table (info);
626
 
627
  for (stub_sec = htab->stub_bfd->sections;
628
       stub_sec != NULL;
629
       stub_sec = stub_sec->next)
630
    {
631
      bfd_size_type size;
632
 
633
      /* Allocate memory to hold the linker stubs.  */
634
      size = stub_sec->size;
635
      stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
636
      if (stub_sec->contents == NULL && size != 0)
637
        return FALSE;
638
      stub_sec->size = 0;
639
    }
640
 
641
  /* Build the stubs as directed by the stub hash table.  */
642
  table = htab->stub_hash_table;
643
  bfd_hash_traverse (table, m68hc11_elf_export_one_stub, info);
644
 
645
  /* Scan the output sections to see if we use the memory banks.
646
     If so, export the symbols that define how the memory banks
647
     are mapped.  This is used by gdb and the simulator to obtain
648
     the information.  It can be used by programs to burn the eprom
649
     at the good addresses.  */
650
  param.use_memory_banks = FALSE;
651
  param.pinfo = &htab->pinfo;
652
  bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
653
  if (param.use_memory_banks)
654
    {
655
      m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_START_NAME,
656
                              htab->pinfo.bank_physical,
657
                              bfd_abs_section_ptr);
658
      m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_VIRTUAL_NAME,
659
                              htab->pinfo.bank_virtual,
660
                              bfd_abs_section_ptr);
661
      m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_SIZE_NAME,
662
                              htab->pinfo.bank_size,
663
                              bfd_abs_section_ptr);
664
    }
665
 
666
  return TRUE;
667
}
668
 
669
void
670
m68hc11_elf_get_bank_parameters (struct bfd_link_info *info)
671
{
672
  unsigned i;
673
  struct m68hc11_page_info *pinfo;
674
  struct bfd_link_hash_entry *h;
675
 
676
  pinfo = &m68hc11_elf_hash_table (info)->pinfo;
677
  if (pinfo->bank_param_initialized)
678
    return;
679
 
680
  pinfo->bank_virtual = M68HC12_BANK_VIRT;
681
  pinfo->bank_mask = M68HC12_BANK_MASK;
682
  pinfo->bank_physical = M68HC12_BANK_BASE;
683
  pinfo->bank_shift = M68HC12_BANK_SHIFT;
684
  pinfo->bank_size = 1 << M68HC12_BANK_SHIFT;
685
 
686
  h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_START_NAME,
687
                            FALSE, FALSE, TRUE);
688
  if (h != (struct bfd_link_hash_entry*) NULL
689
      && h->type == bfd_link_hash_defined)
690
    pinfo->bank_physical = (h->u.def.value
691
                            + h->u.def.section->output_section->vma
692
                            + h->u.def.section->output_offset);
693
 
694
  h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_VIRTUAL_NAME,
695
                            FALSE, FALSE, TRUE);
696
  if (h != (struct bfd_link_hash_entry*) NULL
697
      && h->type == bfd_link_hash_defined)
698
    pinfo->bank_virtual = (h->u.def.value
699
                           + h->u.def.section->output_section->vma
700
                           + h->u.def.section->output_offset);
701
 
702
  h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_SIZE_NAME,
703
                            FALSE, FALSE, TRUE);
704
  if (h != (struct bfd_link_hash_entry*) NULL
705
      && h->type == bfd_link_hash_defined)
706
    pinfo->bank_size = (h->u.def.value
707
                        + h->u.def.section->output_section->vma
708
                        + h->u.def.section->output_offset);
709
 
710
  pinfo->bank_shift = 0;
711
  for (i = pinfo->bank_size; i != 0; i >>= 1)
712
    pinfo->bank_shift++;
713
  pinfo->bank_shift--;
714
  pinfo->bank_mask = (1 << pinfo->bank_shift) - 1;
715
  pinfo->bank_physical_end = pinfo->bank_physical + pinfo->bank_size;
716
  pinfo->bank_param_initialized = 1;
717
 
718
  h = bfd_link_hash_lookup (info->hash, "__far_trampoline", FALSE,
719
                            FALSE, TRUE);
720
  if (h != (struct bfd_link_hash_entry*) NULL
721
      && h->type == bfd_link_hash_defined)
722
    pinfo->trampoline_addr = (h->u.def.value
723
                              + h->u.def.section->output_section->vma
724
                              + h->u.def.section->output_offset);
725
}
726
 
727
/* Return 1 if the address is in banked memory.
728
   This can be applied to a virtual address and to a physical address.  */
729
int
730
m68hc11_addr_is_banked (struct m68hc11_page_info *pinfo, bfd_vma addr)
731
{
732
  if (addr >= pinfo->bank_virtual)
733
    return 1;
734
 
735
  if (addr >= pinfo->bank_physical && addr <= pinfo->bank_physical_end)
736
    return 1;
737
 
738
  return 0;
739
}
740
 
741
/* Return the physical address seen by the processor, taking
742
   into account banked memory.  */
743
bfd_vma
744
m68hc11_phys_addr (struct m68hc11_page_info *pinfo, bfd_vma addr)
745
{
746
  if (addr < pinfo->bank_virtual)
747
    return addr;
748
 
749
  /* Map the address to the memory bank.  */
750
  addr -= pinfo->bank_virtual;
751
  addr &= pinfo->bank_mask;
752
  addr += pinfo->bank_physical;
753
  return addr;
754
}
755
 
756
/* Return the page number corresponding to an address in banked memory.  */
757
bfd_vma
758
m68hc11_phys_page (struct m68hc11_page_info *pinfo, bfd_vma addr)
759
{
760
  if (addr < pinfo->bank_virtual)
761
    return 0;
762
 
763
  /* Map the address to the memory bank.  */
764
  addr -= pinfo->bank_virtual;
765
  addr >>= pinfo->bank_shift;
766
  addr &= 0x0ff;
767
  return addr;
768
}
769
 
770
/* This function is used for relocs which are only used for relaxing,
771
   which the linker should otherwise ignore.  */
772
 
773
bfd_reloc_status_type
774
m68hc11_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
775
                          arelent *reloc_entry,
776
                          asymbol *symbol ATTRIBUTE_UNUSED,
777
                          void *data ATTRIBUTE_UNUSED,
778
                          asection *input_section,
779
                          bfd *output_bfd,
780
                          char **error_message ATTRIBUTE_UNUSED)
781
{
782
  if (output_bfd != NULL)
783
    reloc_entry->address += input_section->output_offset;
784
  return bfd_reloc_ok;
785
}
786
 
787
bfd_reloc_status_type
788
m68hc11_elf_special_reloc (bfd *abfd ATTRIBUTE_UNUSED,
789
                           arelent *reloc_entry,
790
                           asymbol *symbol,
791
                           void *data ATTRIBUTE_UNUSED,
792
                           asection *input_section,
793
                           bfd *output_bfd,
794
                           char **error_message ATTRIBUTE_UNUSED)
795
{
796
  if (output_bfd != (bfd *) NULL
797
      && (symbol->flags & BSF_SECTION_SYM) == 0
798
      && (! reloc_entry->howto->partial_inplace
799
          || reloc_entry->addend == 0))
800
    {
801
      reloc_entry->address += input_section->output_offset;
802
      return bfd_reloc_ok;
803
    }
804
 
805
  if (output_bfd != NULL)
806
    return bfd_reloc_continue;
807
 
808
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
809
    return bfd_reloc_outofrange;
810
 
811
  abort();
812
}
813
 
814
/* Look through the relocs for a section during the first phase.
815
   Since we don't do .gots or .plts, we just need to consider the
816
   virtual table relocs for gc.  */
817
 
818
bfd_boolean
819
elf32_m68hc11_check_relocs (bfd *abfd, struct bfd_link_info *info,
820
                            asection *sec, const Elf_Internal_Rela *relocs)
821
{
822
  Elf_Internal_Shdr *           symtab_hdr;
823
  struct elf_link_hash_entry ** sym_hashes;
824
  const Elf_Internal_Rela *     rel;
825
  const Elf_Internal_Rela *     rel_end;
826
 
827
  if (info->relocatable)
828
    return TRUE;
829
 
830
  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
831
  sym_hashes = elf_sym_hashes (abfd);
832
  rel_end = relocs + sec->reloc_count;
833
 
834
  for (rel = relocs; rel < rel_end; rel++)
835
    {
836
      struct elf_link_hash_entry * h;
837
      unsigned long r_symndx;
838
 
839
      r_symndx = ELF32_R_SYM (rel->r_info);
840
 
841
      if (r_symndx < symtab_hdr->sh_info)
842
        h = NULL;
843
      else
844
        {
845
          h = sym_hashes [r_symndx - symtab_hdr->sh_info];
846
          while (h->root.type == bfd_link_hash_indirect
847
                 || h->root.type == bfd_link_hash_warning)
848
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
849
        }
850
 
851
      switch (ELF32_R_TYPE (rel->r_info))
852
        {
853
        /* This relocation describes the C++ object vtable hierarchy.
854
           Reconstruct it for later use during GC.  */
855
        case R_M68HC11_GNU_VTINHERIT:
856
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
857
            return FALSE;
858
          break;
859
 
860
        /* This relocation describes which C++ vtable entries are actually
861
           used.  Record for later use during GC.  */
862
        case R_M68HC11_GNU_VTENTRY:
863
          BFD_ASSERT (h != NULL);
864
          if (h != NULL
865
              && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
866
            return FALSE;
867
          break;
868
        }
869
    }
870
 
871
  return TRUE;
872
}
873
 
874
/* Relocate a 68hc11/68hc12 ELF section.  */
875
bfd_boolean
876
elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
877
                                struct bfd_link_info *info,
878
                                bfd *input_bfd, asection *input_section,
879
                                bfd_byte *contents, Elf_Internal_Rela *relocs,
880
                                Elf_Internal_Sym *local_syms,
881
                                asection **local_sections)
882
{
883
  Elf_Internal_Shdr *symtab_hdr;
884
  struct elf_link_hash_entry **sym_hashes;
885
  Elf_Internal_Rela *rel, *relend;
886
  const char *name = NULL;
887
  struct m68hc11_page_info *pinfo;
888
  const struct elf_backend_data * const ebd = get_elf_backend_data (input_bfd);
889
 
890
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
891
  sym_hashes = elf_sym_hashes (input_bfd);
892
 
893
  /* Get memory bank parameters.  */
894
  m68hc11_elf_get_bank_parameters (info);
895
  pinfo = &m68hc11_elf_hash_table (info)->pinfo;
896
 
897
  rel = relocs;
898
  relend = relocs + input_section->reloc_count;
899
  for (; rel < relend; rel++)
900
    {
901
      int r_type;
902
      arelent arel;
903
      reloc_howto_type *howto;
904
      unsigned long r_symndx;
905
      Elf_Internal_Sym *sym;
906
      asection *sec;
907
      bfd_vma relocation = 0;
908
      bfd_reloc_status_type r = bfd_reloc_undefined;
909
      bfd_vma phys_page;
910
      bfd_vma phys_addr;
911
      bfd_vma insn_addr;
912
      bfd_vma insn_page;
913
      bfd_boolean is_far = FALSE;
914
      struct elf_link_hash_entry *h;
915
      const char* stub_name = 0;
916
 
917
      r_symndx = ELF32_R_SYM (rel->r_info);
918
      r_type = ELF32_R_TYPE (rel->r_info);
919
 
920
      if (r_type == R_M68HC11_GNU_VTENTRY
921
          || r_type == R_M68HC11_GNU_VTINHERIT )
922
        continue;
923
 
924
      (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
925
      howto = arel.howto;
926
 
927
      h = NULL;
928
      sym = NULL;
929
      sec = NULL;
930
      if (r_symndx < symtab_hdr->sh_info)
931
        {
932
          sym = local_syms + r_symndx;
933
          sec = local_sections[r_symndx];
934
          relocation = (sec->output_section->vma
935
                        + sec->output_offset
936
                        + sym->st_value);
937
          is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
938
          if (is_far)
939
            stub_name = (bfd_elf_string_from_elf_section
940
                         (input_bfd, symtab_hdr->sh_link,
941
                          sym->st_name));
942
        }
943
      else
944
        {
945
          bfd_boolean unresolved_reloc, warned;
946
 
947
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
948
                                   r_symndx, symtab_hdr, sym_hashes,
949
                                   h, sec, relocation, unresolved_reloc,
950
                                   warned);
951
 
952
          is_far = (h && (h->other & STO_M68HC12_FAR));
953
          stub_name = h->root.root.string;
954
        }
955
 
956
      if (sec != NULL && elf_discarded_section (sec))
957
        {
958
          /* For relocs against symbols from removed linkonce sections,
959
             or sections discarded by a linker script, we just want the
960
             section contents zeroed.  Avoid any special processing.  */
961
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
962
          rel->r_info = 0;
963
          rel->r_addend = 0;
964
          continue;
965
        }
966
 
967
      if (info->relocatable)
968
        {
969
          /* This is a relocatable link.  We don't have to change
970
             anything, unless the reloc is against a section symbol,
971
             in which case we have to adjust according to where the
972
             section symbol winds up in the output section.  */
973
          if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
974
            rel->r_addend += sec->output_offset;
975
          continue;
976
        }
977
 
978
      if (h != NULL)
979
        name = h->root.root.string;
980
      else
981
        {
982
          name = (bfd_elf_string_from_elf_section
983
                  (input_bfd, symtab_hdr->sh_link, sym->st_name));
984
          if (name == NULL || *name == '\0')
985
            name = bfd_section_name (input_bfd, sec);
986
        }
987
 
988
      if (is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16)
989
        {
990
          struct elf32_m68hc11_stub_hash_entry* stub;
991
          struct m68hc11_elf_link_hash_table *htab;
992
 
993
          htab = m68hc11_elf_hash_table (info);
994
          stub = m68hc12_stub_hash_lookup (htab->stub_hash_table,
995
                                           name, FALSE, FALSE);
996
          if (stub)
997
            {
998
              relocation = stub->stub_offset
999
                + stub->stub_sec->output_section->vma
1000
                + stub->stub_sec->output_offset;
1001
              is_far = FALSE;
1002
            }
1003
        }
1004
 
1005
      /* Do the memory bank mapping.  */
1006
      phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend);
1007
      phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend);
1008
      switch (r_type)
1009
        {
1010
        case R_M68HC11_24:
1011
          /* Reloc used by 68HC12 call instruction.  */
1012
          bfd_put_16 (input_bfd, phys_addr,
1013
                      (bfd_byte*) contents + rel->r_offset);
1014
          bfd_put_8 (input_bfd, phys_page,
1015
                     (bfd_byte*) contents + rel->r_offset + 2);
1016
          r = bfd_reloc_ok;
1017
          r_type = R_M68HC11_NONE;
1018
          break;
1019
 
1020
        case R_M68HC11_NONE:
1021
          r = bfd_reloc_ok;
1022
          break;
1023
 
1024
        case R_M68HC11_LO16:
1025
          /* Reloc generated by %addr(expr) gas to obtain the
1026
             address as mapped in the memory bank window.  */
1027
          relocation = phys_addr;
1028
          break;
1029
 
1030
        case R_M68HC11_PAGE:
1031
          /* Reloc generated by %page(expr) gas to obtain the
1032
             page number associated with the address.  */
1033
          relocation = phys_page;
1034
          break;
1035
 
1036
        case R_M68HC11_16:
1037
          /* Get virtual address of instruction having the relocation.  */
1038
          if (is_far)
1039
            {
1040
              const char* msg;
1041
              char* buf;
1042
              msg = _("Reference to the far symbol `%s' using a wrong "
1043
                      "relocation may result in incorrect execution");
1044
              buf = alloca (strlen (msg) + strlen (name) + 10);
1045
              sprintf (buf, msg, name);
1046
 
1047
              (* info->callbacks->warning)
1048
                (info, buf, name, input_bfd, NULL, rel->r_offset);
1049
            }
1050
 
1051
          /* Get virtual address of instruction having the relocation.  */
1052
          insn_addr = input_section->output_section->vma
1053
            + input_section->output_offset
1054
            + rel->r_offset;
1055
 
1056
          insn_page = m68hc11_phys_page (pinfo, insn_addr);
1057
 
1058
          if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend)
1059
              && m68hc11_addr_is_banked (pinfo, insn_addr)
1060
              && phys_page != insn_page)
1061
            {
1062
              const char* msg;
1063
              char* buf;
1064
 
1065
              msg = _("banked address [%lx:%04lx] (%lx) is not in the same bank "
1066
                      "as current banked address [%lx:%04lx] (%lx)");
1067
 
1068
              buf = alloca (strlen (msg) + 128);
1069
              sprintf (buf, msg, phys_page, phys_addr,
1070
                       (long) (relocation + rel->r_addend),
1071
                       insn_page, m68hc11_phys_addr (pinfo, insn_addr),
1072
                       (long) (insn_addr));
1073
              if (!((*info->callbacks->warning)
1074
                    (info, buf, name, input_bfd, input_section,
1075
                     rel->r_offset)))
1076
                return FALSE;
1077
              break;
1078
            }
1079
          if (phys_page != 0 && insn_page == 0)
1080
            {
1081
              const char* msg;
1082
              char* buf;
1083
 
1084
              msg = _("reference to a banked address [%lx:%04lx] in the "
1085
                      "normal address space at %04lx");
1086
 
1087
              buf = alloca (strlen (msg) + 128);
1088
              sprintf (buf, msg, phys_page, phys_addr, insn_addr);
1089
              if (!((*info->callbacks->warning)
1090
                    (info, buf, name, input_bfd, input_section,
1091
                     insn_addr)))
1092
                return FALSE;
1093
 
1094
              relocation = phys_addr;
1095
              break;
1096
            }
1097
 
1098
          /* If this is a banked address use the phys_addr so that
1099
             we stay in the banked window.  */
1100
          if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend))
1101
            relocation = phys_addr;
1102
          break;
1103
        }
1104
      if (r_type != R_M68HC11_NONE)
1105
        r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1106
                                      contents, rel->r_offset,
1107
                                      relocation, rel->r_addend);
1108
 
1109
      if (r != bfd_reloc_ok)
1110
        {
1111
          const char * msg = (const char *) 0;
1112
 
1113
          switch (r)
1114
            {
1115
            case bfd_reloc_overflow:
1116
              if (!((*info->callbacks->reloc_overflow)
1117
                    (info, NULL, name, howto->name, (bfd_vma) 0,
1118
                     input_bfd, input_section, rel->r_offset)))
1119
                return FALSE;
1120
              break;
1121
 
1122
            case bfd_reloc_undefined:
1123
              if (!((*info->callbacks->undefined_symbol)
1124
                    (info, name, input_bfd, input_section,
1125
                     rel->r_offset, TRUE)))
1126
                return FALSE;
1127
              break;
1128
 
1129
            case bfd_reloc_outofrange:
1130
              msg = _ ("internal error: out of range error");
1131
              goto common_error;
1132
 
1133
            case bfd_reloc_notsupported:
1134
              msg = _ ("internal error: unsupported relocation error");
1135
              goto common_error;
1136
 
1137
            case bfd_reloc_dangerous:
1138
              msg = _ ("internal error: dangerous error");
1139
              goto common_error;
1140
 
1141
            default:
1142
              msg = _ ("internal error: unknown error");
1143
              /* fall through */
1144
 
1145
            common_error:
1146
              if (!((*info->callbacks->warning)
1147
                    (info, msg, name, input_bfd, input_section,
1148
                     rel->r_offset)))
1149
                return FALSE;
1150
              break;
1151
            }
1152
        }
1153
    }
1154
 
1155
  return TRUE;
1156
}
1157
 
1158
 
1159
 
1160
/* Set and control ELF flags in ELF header.  */
1161
 
1162
bfd_boolean
1163
_bfd_m68hc11_elf_set_private_flags (bfd *abfd, flagword flags)
1164
{
1165
  BFD_ASSERT (!elf_flags_init (abfd)
1166
              || elf_elfheader (abfd)->e_flags == flags);
1167
 
1168
  elf_elfheader (abfd)->e_flags = flags;
1169
  elf_flags_init (abfd) = TRUE;
1170
  return TRUE;
1171
}
1172
 
1173
/* Merge backend specific data from an object file to the output
1174
   object file when linking.  */
1175
 
1176
bfd_boolean
1177
_bfd_m68hc11_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
1178
{
1179
  flagword old_flags;
1180
  flagword new_flags;
1181
  bfd_boolean ok = TRUE;
1182
 
1183
  /* Check if we have the same endianess */
1184
  if (!_bfd_generic_verify_endian_match (ibfd, obfd))
1185
    return FALSE;
1186
 
1187
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1188
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1189
    return TRUE;
1190
 
1191
  new_flags = elf_elfheader (ibfd)->e_flags;
1192
  elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
1193
  old_flags = elf_elfheader (obfd)->e_flags;
1194
 
1195
  if (! elf_flags_init (obfd))
1196
    {
1197
      elf_flags_init (obfd) = TRUE;
1198
      elf_elfheader (obfd)->e_flags = new_flags;
1199
      elf_elfheader (obfd)->e_ident[EI_CLASS]
1200
        = elf_elfheader (ibfd)->e_ident[EI_CLASS];
1201
 
1202
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1203
          && bfd_get_arch_info (obfd)->the_default)
1204
        {
1205
          if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
1206
                                   bfd_get_mach (ibfd)))
1207
            return FALSE;
1208
        }
1209
 
1210
      return TRUE;
1211
    }
1212
 
1213
  /* Check ABI compatibility.  */
1214
  if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
1215
    {
1216
      (*_bfd_error_handler)
1217
        (_("%B: linking files compiled for 16-bit integers (-mshort) "
1218
           "and others for 32-bit integers"), ibfd);
1219
      ok = FALSE;
1220
    }
1221
  if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
1222
    {
1223
      (*_bfd_error_handler)
1224
        (_("%B: linking files compiled for 32-bit double (-fshort-double) "
1225
           "and others for 64-bit double"), ibfd);
1226
      ok = FALSE;
1227
    }
1228
 
1229
  /* Processor compatibility.  */
1230
  if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags))
1231
    {
1232
      (*_bfd_error_handler)
1233
        (_("%B: linking files compiled for HCS12 with "
1234
           "others compiled for HC12"), ibfd);
1235
      ok = FALSE;
1236
    }
1237
  new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK)
1238
               | (EF_M68HC11_MERGE_MACH (new_flags, old_flags)));
1239
 
1240
  elf_elfheader (obfd)->e_flags = new_flags;
1241
 
1242
  new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
1243
  old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
1244
 
1245
  /* Warn about any other mismatches */
1246
  if (new_flags != old_flags)
1247
    {
1248
      (*_bfd_error_handler)
1249
        (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
1250
         ibfd, (unsigned long) new_flags, (unsigned long) old_flags);
1251
      ok = FALSE;
1252
    }
1253
 
1254
  if (! ok)
1255
    {
1256
      bfd_set_error (bfd_error_bad_value);
1257
      return FALSE;
1258
    }
1259
 
1260
  return TRUE;
1261
}
1262
 
1263
bfd_boolean
1264
_bfd_m68hc11_elf_print_private_bfd_data (bfd *abfd, void *ptr)
1265
{
1266
  FILE *file = (FILE *) ptr;
1267
 
1268
  BFD_ASSERT (abfd != NULL && ptr != NULL);
1269
 
1270
  /* Print normal ELF private data.  */
1271
  _bfd_elf_print_private_bfd_data (abfd, ptr);
1272
 
1273
  /* xgettext:c-format */
1274
  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1275
 
1276
  if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
1277
    fprintf (file, _("[abi=32-bit int, "));
1278
  else
1279
    fprintf (file, _("[abi=16-bit int, "));
1280
 
1281
  if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
1282
    fprintf (file, _("64-bit double, "));
1283
  else
1284
    fprintf (file, _("32-bit double, "));
1285
 
1286
  if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0)
1287
    fprintf (file, _("cpu=HC11]"));
1288
  else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
1289
    fprintf (file, _("cpu=HCS12]"));
1290
  else
1291
    fprintf (file, _("cpu=HC12]"));
1292
 
1293
  if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
1294
    fprintf (file, _(" [memory=bank-model]"));
1295
  else
1296
    fprintf (file, _(" [memory=flat]"));
1297
 
1298
  fputc ('\n', file);
1299
 
1300
  return TRUE;
1301
}
1302
 
1303
static void scan_sections_for_abi (bfd *abfd ATTRIBUTE_UNUSED,
1304
                                   asection *asect, void *arg)
1305
{
1306
  struct m68hc11_scan_param* p = (struct m68hc11_scan_param*) arg;
1307
 
1308
  if (asect->vma >= p->pinfo->bank_virtual)
1309
    p->use_memory_banks = TRUE;
1310
}
1311
 
1312
/* Tweak the OSABI field of the elf header.  */
1313
 
1314
void
1315
elf32_m68hc11_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
1316
{
1317
  struct m68hc11_scan_param param;
1318
 
1319
  if (link_info == 0)
1320
    return;
1321
 
1322
  m68hc11_elf_get_bank_parameters (link_info);
1323
 
1324
  param.use_memory_banks = FALSE;
1325
  param.pinfo = &m68hc11_elf_hash_table (link_info)->pinfo;
1326
  bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
1327
  if (param.use_memory_banks)
1328
    {
1329
      Elf_Internal_Ehdr * i_ehdrp;
1330
 
1331
      i_ehdrp = elf_elfheader (abfd);
1332
      i_ehdrp->e_flags |= E_M68HC12_BANKS;
1333
    }
1334
}
1335
 

powered by: WebSVN 2.1.0

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