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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [bfd/] [elf32-m68hc12.c] - Blame information for rev 1776

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

Line No. Rev Author Line
1 1181 sfurman
/* Motorola 68HC12-specific support for 32-bit ELF
2
   Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
3
   Contributed by Stephane Carrez (stcarrez@nerim.fr)
4
   (Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
 
22
#include "bfd.h"
23
#include "sysdep.h"
24
#include "libbfd.h"
25
#include "elf-bfd.h"
26
#include "elf/m68hc11.h"
27
#include "opcode/m68hc11.h"
28
 
29
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
30
  PARAMS ((bfd *, bfd_reloc_code_real_type));
31
static void m68hc11_info_to_howto_rel
32
  PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
33
 
34
static bfd_reloc_status_type m68hc11_elf_ignore_reloc
35
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
36
static bfd_reloc_status_type m68hc12_elf_special_reloc
37
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
38
static int m68hc12_addr_is_banked PARAMS ((bfd_vma));
39
static bfd_vma m68hc12_phys_addr PARAMS ((bfd_vma));
40
static bfd_vma m68hc12_phys_page PARAMS ((bfd_vma));
41
 
42
/* GC mark and sweep.  */
43
static asection *elf32_m68hc11_gc_mark_hook
44
  PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
45
           struct elf_link_hash_entry *, Elf_Internal_Sym *));
46
static boolean elf32_m68hc11_gc_sweep_hook
47
  PARAMS ((bfd *, struct bfd_link_info *, asection *,
48
           const Elf_Internal_Rela *));
49
 
50
boolean _bfd_m68hc12_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
51
boolean _bfd_m68hc12_elf_set_private_flags PARAMS ((bfd *, flagword));
52
boolean _bfd_m68hc12_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
53
 
54
 
55
 
56
/* Use REL instead of RELA to save space */
57
#define USE_REL
58
 
59
/* The Motorola 68HC11 microcontroler only addresses 64Kb.
60
   We must handle 8 and 16-bit relocations.  The 32-bit relocation
61
   is defined but not used except by gas when -gstabs is used (which
62
   is wrong).
63
 
64
   The 68HC12 microcontroler has a memory bank switching system
65
   with a 16Kb window in the 64Kb address space.  The extended memory
66
   is mapped in the 16Kb window (at 0x8000).  The page register controls
67
   which 16Kb bank is mapped.  The call/rtc instructions take care of
68
   bank switching in function calls/returns.
69
 
70
   For GNU Binutils to work, we consider there is a physical memory
71
   at 0..0x0ffff and a kind of virtual memory above that.  Symbols
72
   in virtual memory have their addresses treated in a special way
73
   when disassembling and when linking.
74
 
75
   For the linker to work properly, we must always relocate the virtual
76
   memory as if it is mapped at 0x8000.  When a 16-bit relocation is
77
   made in the virtual memory, we check that it does not cross the
78
   memory bank where it is used.  This would involve a page change
79
   which would be wrong.  The 24-bit relocation is for that and it
80
   treats the address as a physical address + page number.
81
 
82
 
83
                                        Banked
84
                                        Address Space
85
                                        |               |       Page n
86
                                        +---------------+ 0x1010000
87
                                        |               |
88
                                        | jsr _foo      |
89
                                        | ..            |       Page 3
90
                                        | _foo:         |
91
                                        +---------------+ 0x100C000
92
                                        |               |
93
                                        | call _bar     |
94
                                        | ..            |       Page 2
95
                                        | _bar:         |
96
                                        +---------------+ 0x1008000
97
                                /------>|               |
98
                                |       | call _foo     |       Page 1
99
                                |       |               |
100
                                |       +---------------+ 0x1004000
101
      Physical                  |       |               |
102
      Address Space             |       |               |       Page 0
103
                                |       |               |
104
    +-----------+ 0x00FFFF      |       +---------------+ 0x1000000
105
    |           |               |
106
    | call _foo |               |
107
    |           |               |
108
    +-----------+ 0x00BFFF -+---/
109
    |           |           |
110
    |           |           |
111
    |           | 16K       |
112
    |           |           |
113
    +-----------+ 0x008000 -+
114
    |           |
115
    |           |
116
    =           =
117
    |           |
118
    |           |
119
    +-----------+ 0000
120
 
121
 
122
   The 'call _foo' must be relocated with page 3 and 16-bit address
123
   mapped at 0x8000.
124
 
125
   The 3-bit and 16-bit PC rel relocation is only used by 68HC12.  */
126
static reloc_howto_type elf_m68hc11_howto_table[] = {
127
  /* This reloc does nothing.  */
128
  HOWTO (R_M68HC11_NONE,        /* type */
129
         0,                      /* rightshift */
130
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
131
         32,                    /* bitsize */
132
         false,                 /* pc_relative */
133
         0,                      /* bitpos */
134
         complain_overflow_dont,/* complain_on_overflow */
135
         bfd_elf_generic_reloc, /* special_function */
136
         "R_M68HC12_NONE",      /* name */
137
         false,                 /* partial_inplace */
138
         0,                      /* src_mask */
139
         0,                      /* dst_mask */
140
         false),                /* pcrel_offset */
141
 
142
  /* A 8 bit absolute relocation */
143
  HOWTO (R_M68HC11_8,           /* type */
144
         0,                      /* rightshift */
145
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
146
         8,                     /* bitsize */
147
         false,                 /* pc_relative */
148
         0,                      /* bitpos */
149
         complain_overflow_bitfield,    /* complain_on_overflow */
150
         bfd_elf_generic_reloc, /* special_function */
151
         "R_M68HC12_8",         /* name */
152
         false,                 /* partial_inplace */
153
         0x00ff,                /* src_mask */
154
         0x00ff,                /* dst_mask */
155
         false),                /* pcrel_offset */
156
 
157
  /* A 8 bit absolute relocation (upper address) */
158
  HOWTO (R_M68HC11_HI8,         /* type */
159
         8,                     /* rightshift */
160
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
161
         8,                     /* bitsize */
162
         false,                 /* pc_relative */
163
         0,                      /* bitpos */
164
         complain_overflow_bitfield,    /* complain_on_overflow */
165
         bfd_elf_generic_reloc, /* special_function */
166
         "R_M68HC12_HI8",       /* name */
167
         false,                 /* partial_inplace */
168
         0x00ff,                /* src_mask */
169
         0x00ff,                /* dst_mask */
170
         false),                /* pcrel_offset */
171
 
172
  /* A 8 bit absolute relocation (upper address) */
173
  HOWTO (R_M68HC11_LO8,         /* type */
174
         0,                      /* rightshift */
175
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
176
         8,                     /* bitsize */
177
         false,                 /* pc_relative */
178
         0,                      /* bitpos */
179
         complain_overflow_dont,        /* complain_on_overflow */
180
         bfd_elf_generic_reloc, /* special_function */
181
         "R_M68HC12_LO8",       /* name */
182
         false,                 /* partial_inplace */
183
         0x00ff,                /* src_mask */
184
         0x00ff,                /* dst_mask */
185
         false),                /* pcrel_offset */
186
 
187
  /* A 8 bit PC-rel relocation */
188
  HOWTO (R_M68HC11_PCREL_8,     /* type */
189
         0,                      /* rightshift */
190
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
191
         8,                     /* bitsize */
192
         true,                  /* pc_relative */
193
         0,                      /* bitpos */
194
         complain_overflow_bitfield,    /* complain_on_overflow */
195
         bfd_elf_generic_reloc, /* special_function */
196
         "R_M68HC12_PCREL_8",   /* name */
197
         false,                 /* partial_inplace */
198
         0x00ff,                /* src_mask */
199
         0x00ff,                /* dst_mask */
200
         false),                /* pcrel_offset */
201
 
202
  /* A 16 bit absolute relocation */
203
  HOWTO (R_M68HC11_16,          /* type */
204
         0,                      /* rightshift */
205
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
206
         16,                    /* bitsize */
207
         false,                 /* pc_relative */
208
         0,                      /* bitpos */
209
         complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
210
         m68hc12_elf_special_reloc,     /* special_function */
211
         "R_M68HC12_16",        /* name */
212
         false,                 /* partial_inplace */
213
         0xffff,                /* src_mask */
214
         0xffff,                /* dst_mask */
215
         false),                /* pcrel_offset */
216
 
217
  /* A 32 bit absolute relocation.  This one is never used for the
218
     code relocation.  It's used by gas for -gstabs generation.  */
219
  HOWTO (R_M68HC11_32,          /* type */
220
         0,                      /* rightshift */
221
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
222
         32,                    /* bitsize */
223
         false,                 /* pc_relative */
224
         0,                      /* bitpos */
225
         complain_overflow_bitfield,    /* complain_on_overflow */
226
         bfd_elf_generic_reloc, /* special_function */
227
         "R_M68HC12_32",        /* name */
228
         false,                 /* partial_inplace */
229
         0xffffffff,            /* src_mask */
230
         0xffffffff,            /* dst_mask */
231
         false),                /* pcrel_offset */
232
 
233
  /* A 3 bit absolute relocation */
234
  HOWTO (R_M68HC11_3B,          /* type */
235
         0,                      /* rightshift */
236
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
237
         3,                     /* bitsize */
238
         false,                 /* pc_relative */
239
         0,                      /* bitpos */
240
         complain_overflow_bitfield,    /* complain_on_overflow */
241
         bfd_elf_generic_reloc, /* special_function */
242
         "R_M68HC12_4B",        /* name */
243
         false,                 /* partial_inplace */
244
         0x003,                 /* src_mask */
245
         0x003,                 /* dst_mask */
246
         false),                /* pcrel_offset */
247
 
248
  /* A 16 bit PC-rel relocation */
249
  HOWTO (R_M68HC11_PCREL_16,    /* type */
250
         0,                      /* rightshift */
251
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
252
         16,                    /* bitsize */
253
         true,                  /* pc_relative */
254
         0,                      /* bitpos */
255
         complain_overflow_dont,        /* complain_on_overflow */
256
         bfd_elf_generic_reloc, /* special_function */
257
         "R_M68HC12_PCREL_16",  /* name */
258
         false,                 /* partial_inplace */
259
         0xffff,                /* src_mask */
260
         0xffff,                /* dst_mask */
261
         false),                /* pcrel_offset */
262
 
263
  /* GNU extension to record C++ vtable hierarchy */
264
  HOWTO (R_M68HC11_GNU_VTINHERIT,       /* type */
265
         0,                      /* rightshift */
266
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
267
         0,                      /* bitsize */
268
         false,                 /* pc_relative */
269
         0,                      /* bitpos */
270
         complain_overflow_dont,        /* complain_on_overflow */
271
         NULL,                  /* special_function */
272
         "R_M68HC11_GNU_VTINHERIT",     /* name */
273
         false,                 /* partial_inplace */
274
         0,                      /* src_mask */
275
         0,                      /* dst_mask */
276
         false),                /* pcrel_offset */
277
 
278
  /* GNU extension to record C++ vtable member usage */
279
  HOWTO (R_M68HC11_GNU_VTENTRY, /* type */
280
         0,                      /* rightshift */
281
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
282
         0,                      /* bitsize */
283
         false,                 /* pc_relative */
284
         0,                      /* bitpos */
285
         complain_overflow_dont,        /* complain_on_overflow */
286
         _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
287
         "R_M68HC11_GNU_VTENTRY",       /* name */
288
         false,                 /* partial_inplace */
289
         0,                      /* src_mask */
290
         0,                      /* dst_mask */
291
         false),                /* pcrel_offset */
292
 
293
  /* A 24 bit relocation */
294
  HOWTO (R_M68HC11_24,          /* type */
295
         0,                      /* rightshift */
296
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
297
         24,                    /* bitsize */
298
         false,                 /* pc_relative */
299
         0,                      /* bitpos */
300
         complain_overflow_dont,        /* complain_on_overflow */
301
         m68hc12_elf_special_reloc,     /* special_function */
302
         "R_M68HC12_24",        /* name */
303
         false,                 /* partial_inplace */
304
         0xffff,                /* src_mask */
305
         0xffff,                /* dst_mask */
306
         false),                /* pcrel_offset */
307
 
308
  /* A 16-bit low relocation */
309
  HOWTO (R_M68HC11_LO16,        /* type */
310
         0,                      /* rightshift */
311
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
312
         16,                    /* bitsize */
313
         false,                 /* pc_relative */
314
         0,                      /* bitpos */
315
         complain_overflow_dont,        /* complain_on_overflow */
316
         m68hc12_elf_special_reloc,/* special_function */
317
         "R_M68HC12_LO16",      /* name */
318
         false,                 /* partial_inplace */
319
         0xffff,                /* src_mask */
320
         0xffff,                /* dst_mask */
321
         false),                /* pcrel_offset */
322
 
323
  /* A page relocation */
324
  HOWTO (R_M68HC11_PAGE,        /* type */
325
         0,                      /* rightshift */
326
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
327
         8,                     /* bitsize */
328
         false,                 /* pc_relative */
329
         0,                      /* bitpos */
330
         complain_overflow_dont,        /* complain_on_overflow */
331
         m68hc12_elf_special_reloc,/* special_function */
332
         "R_M68HC12_PAGE",      /* name */
333
         false,                 /* partial_inplace */
334
         0x00ff,                /* src_mask */
335
         0x00ff,                /* dst_mask */
336
         false),                /* pcrel_offset */
337
 
338
  EMPTY_HOWTO (14),
339
  EMPTY_HOWTO (15),
340
  EMPTY_HOWTO (16),
341
  EMPTY_HOWTO (17),
342
  EMPTY_HOWTO (18),
343
  EMPTY_HOWTO (19),
344
 
345
  /* Mark beginning of a jump instruction (any form).  */
346
  HOWTO (R_M68HC11_RL_JUMP,     /* type */
347
         0,                      /* rightshift */
348
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
349
         0,                      /* bitsize */
350
         false,                 /* pc_relative */
351
         0,                      /* bitpos */
352
         complain_overflow_dont,        /* complain_on_overflow */
353
         m68hc11_elf_ignore_reloc,      /* special_function */
354
         "R_M68HC12_RL_JUMP",   /* name */
355
         true,                  /* partial_inplace */
356
         0,                      /* src_mask */
357
         0,                      /* dst_mask */
358
         true),                 /* pcrel_offset */
359
 
360
  /* Mark beginning of Gcc relaxation group instruction.  */
361
  HOWTO (R_M68HC11_RL_GROUP,    /* type */
362
         0,                      /* rightshift */
363
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
364
         0,                      /* bitsize */
365
         false,                 /* pc_relative */
366
         0,                      /* bitpos */
367
         complain_overflow_dont,        /* complain_on_overflow */
368
         m68hc11_elf_ignore_reloc,      /* special_function */
369
         "R_M68HC12_RL_GROUP",  /* name */
370
         true,                  /* partial_inplace */
371
         0,                      /* src_mask */
372
         0,                      /* dst_mask */
373
         true),                 /* pcrel_offset */
374
};
375
 
376
/* Map BFD reloc types to M68HC11 ELF reloc types.  */
377
 
378
struct m68hc11_reloc_map
379
{
380
  bfd_reloc_code_real_type bfd_reloc_val;
381
  unsigned char elf_reloc_val;
382
};
383
 
384
static const struct m68hc11_reloc_map m68hc11_reloc_map[] = {
385
  {BFD_RELOC_NONE, R_M68HC11_NONE,},
386
  {BFD_RELOC_8, R_M68HC11_8},
387
  {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
388
  {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
389
  {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
390
  {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
391
  {BFD_RELOC_16, R_M68HC11_16},
392
  {BFD_RELOC_32, R_M68HC11_32},
393
  {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
394
 
395
  {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
396
  {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
397
 
398
  {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
399
  {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
400
  {BFD_RELOC_M68HC11_24, R_M68HC11_24},
401
 
402
  {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
403
  {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
404
};
405
 
406
static reloc_howto_type *
407
bfd_elf32_bfd_reloc_type_lookup (abfd, code)
408
     bfd *abfd ATTRIBUTE_UNUSED;
409
     bfd_reloc_code_real_type code;
410
{
411
  unsigned int i;
412
 
413
  for (i = 0;
414
       i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
415
       i++)
416
    {
417
      if (m68hc11_reloc_map[i].bfd_reloc_val == code)
418
        return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
419
    }
420
 
421
  return NULL;
422
}
423
 
424
/* This function is used for relocs which are only used for relaxing,
425
   which the linker should otherwise ignore.  */
426
 
427
static bfd_reloc_status_type
428
m68hc11_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
429
                          output_bfd, error_message)
430
     bfd *abfd ATTRIBUTE_UNUSED;
431
     arelent *reloc_entry;
432
     asymbol *symbol ATTRIBUTE_UNUSED;
433
     PTR data ATTRIBUTE_UNUSED;
434
     asection *input_section;
435
     bfd *output_bfd;
436
     char **error_message ATTRIBUTE_UNUSED;
437
{
438
  if (output_bfd != NULL)
439
    reloc_entry->address += input_section->output_offset;
440
  return bfd_reloc_ok;
441
}
442
 
443
static int
444
m68hc12_addr_is_banked (addr)
445
     bfd_vma addr;
446
{
447
   return (addr >= M68HC12_BANK_VIRT) ? 1 : 0;
448
}
449
 
450
/* Return the physical address seen by the processor, taking
451
   into account banked memory.  */
452
static bfd_vma
453
m68hc12_phys_addr (addr)
454
     bfd_vma addr;
455
{
456
  if (addr < M68HC12_BANK_VIRT)
457
    return addr;
458
 
459
  /* Map the address to the memory bank.  */
460
  addr -= M68HC12_BANK_VIRT;
461
  addr &= M68HC12_BANK_MASK;
462
  addr += M68HC12_BANK_BASE;
463
  return addr;
464
}
465
 
466
/* Return the page number corresponding to an address in banked memory.  */
467
static bfd_vma
468
m68hc12_phys_page (addr)
469
     bfd_vma addr;
470
{
471
  if (addr < M68HC12_BANK_VIRT)
472
    return 0;
473
 
474
  /* Map the address to the memory bank.  */
475
  addr -= M68HC12_BANK_VIRT;
476
  addr >>= M68HC12_BANK_SHIFT;
477
  addr &= M68HC12_BANK_PAGE_MASK;
478
  return addr;
479
}
480
 
481
static bfd_reloc_status_type
482
m68hc12_elf_special_reloc (abfd, reloc_entry, symbol, data, input_section,
483
                           output_bfd, error_message)
484
     bfd *abfd;
485
     arelent *reloc_entry;
486
     asymbol *symbol;
487
     PTR data;
488
     asection *input_section;
489
     bfd *output_bfd;
490
     char **error_message ATTRIBUTE_UNUSED;
491
{
492
  reloc_howto_type *howto;
493
  bfd_vma relocation;
494
  bfd_vma phys_addr;
495
  bfd_vma phys_page;
496
  bfd_vma insn_page;
497
  bfd_vma insn_addr;
498
 
499
  if (output_bfd != (bfd *) NULL
500
      && (symbol->flags & BSF_SECTION_SYM) == 0
501
      && (! reloc_entry->howto->partial_inplace
502
          || reloc_entry->addend == 0))
503
    {
504
      reloc_entry->address += input_section->output_offset;
505
      return bfd_reloc_ok;
506
    }
507
 
508
  if (output_bfd != NULL)
509
    return bfd_reloc_continue;
510
 
511
  if (reloc_entry->address > input_section->_cooked_size)
512
    return bfd_reloc_outofrange;
513
 
514
  /* Compute relocation.  */
515
  relocation = (symbol->value
516
                + symbol->section->output_section->vma
517
                + symbol->section->output_offset);
518
  relocation += reloc_entry->addend;
519
  relocation += bfd_get_16 (abfd, (bfd_byte*) data + reloc_entry->address);
520
 
521
  /* Do the memory bank mapping.  */
522
  phys_addr = m68hc12_phys_addr (relocation);
523
  phys_page = m68hc12_phys_page (relocation);
524
 
525
  howto = reloc_entry->howto;
526
  if (howto->complain_on_overflow != complain_overflow_dont
527
      && (phys_addr & (((bfd_vma) -1) << 16)))
528
     return bfd_reloc_overflow;
529
 
530
  switch (howto->type)
531
    {
532
    case R_M68HC11_16:
533
          /* Get virtual address of instruction having the relocation.  */
534
       insn_addr = input_section->output_section->vma
535
          + input_section->output_offset
536
          + reloc_entry->address;
537
 
538
      insn_page = m68hc12_phys_page (insn_addr);
539
 
540
      if (m68hc12_addr_is_banked (relocation)
541
          && m68hc12_addr_is_banked (insn_addr)
542
          && phys_page != insn_page)
543
         {
544
            *error_message = _("address is not in the same bank");
545
            return bfd_reloc_dangerous;
546
         }
547
      if (m68hc12_addr_is_banked (relocation)
548
          && !m68hc12_addr_is_banked (insn_addr))
549
         {
550
            *error_message = _("reference to a banked address in "
551
                               "the normal address space");
552
            return bfd_reloc_dangerous;
553
         }
554
 
555
    case R_M68HC11_LO16:
556
      bfd_put_16 (abfd, phys_addr, (bfd_byte*) data + reloc_entry->address);
557
      break;
558
 
559
    case R_M68HC11_24:
560
      bfd_put_16 (abfd, phys_addr, (bfd_byte*) data + reloc_entry->address);
561
      bfd_put_8 (abfd, phys_page, (bfd_byte*) data + reloc_entry->address + 2);
562
      break;
563
 
564
    case R_M68HC11_PAGE:
565
      bfd_put_8 (abfd, phys_page, (bfd_byte*) data + reloc_entry->address);
566
      break;
567
 
568
    default:
569
       abort ();
570
       break;
571
    }
572
 
573
  return bfd_reloc_ok;
574
}
575
 
576
/* Set the howto pointer for an M68HC11 ELF reloc.  */
577
 
578
static void
579
m68hc11_info_to_howto_rel (abfd, cache_ptr, dst)
580
     bfd *abfd ATTRIBUTE_UNUSED;
581
     arelent *cache_ptr;
582
     Elf32_Internal_Rel *dst;
583
{
584
  unsigned int r_type;
585
 
586
  r_type = ELF32_R_TYPE (dst->r_info);
587
  BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
588
  cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
589
}
590
 
591
static asection *
592
elf32_m68hc11_gc_mark_hook (sec, info, rel, h, sym)
593
     asection *sec;
594
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
595
     Elf_Internal_Rela *rel;
596
     struct elf_link_hash_entry *h;
597
     Elf_Internal_Sym *sym;
598
{
599
  if (h != NULL)
600
    {
601
      switch (ELF32_R_TYPE (rel->r_info))
602
        {
603
        default:
604
          switch (h->root.type)
605
            {
606
            case bfd_link_hash_defined:
607
            case bfd_link_hash_defweak:
608
              return h->root.u.def.section;
609
 
610
            case bfd_link_hash_common:
611
              return h->root.u.c.p->section;
612
 
613
            default:
614
              break;
615
            }
616
        }
617
    }
618
  else
619
    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
620
 
621
  return NULL;
622
}
623
 
624
static boolean
625
elf32_m68hc11_gc_sweep_hook (abfd, info, sec, relocs)
626
     bfd *abfd ATTRIBUTE_UNUSED;
627
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
628
     asection *sec ATTRIBUTE_UNUSED;
629
     const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
630
{
631
  /* We don't use got and plt entries for 68hc11/68hc12.  */
632
  return true;
633
}
634
 
635
 
636
/* Set and control ELF flags in ELF header.  */
637
 
638
boolean
639
_bfd_m68hc12_elf_set_private_flags (abfd, flags)
640
     bfd *abfd;
641
     flagword flags;
642
{
643
  BFD_ASSERT (!elf_flags_init (abfd)
644
              || elf_elfheader (abfd)->e_flags == flags);
645
 
646
  elf_elfheader (abfd)->e_flags = flags;
647
  elf_flags_init (abfd) = true;
648
  return true;
649
}
650
 
651
/* Merge backend specific data from an object file to the output
652
   object file when linking.  */
653
 
654
boolean
655
_bfd_m68hc12_elf_merge_private_bfd_data (ibfd, obfd)
656
     bfd *ibfd;
657
     bfd *obfd;
658
{
659
  flagword old_flags;
660
  flagword new_flags;
661
  boolean ok = true;
662
 
663
  /* Check if we have the same endianess */
664
  if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
665
    return false;
666
 
667
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
668
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
669
    return true;
670
 
671
  new_flags = elf_elfheader (ibfd)->e_flags;
672
  elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
673
  old_flags = elf_elfheader (obfd)->e_flags;
674
 
675
  if (! elf_flags_init (obfd))
676
    {
677
      elf_flags_init (obfd) = true;
678
      elf_elfheader (obfd)->e_flags = new_flags;
679
      elf_elfheader (obfd)->e_ident[EI_CLASS]
680
        = elf_elfheader (ibfd)->e_ident[EI_CLASS];
681
 
682
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
683
          && bfd_get_arch_info (obfd)->the_default)
684
        {
685
          if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
686
                                   bfd_get_mach (ibfd)))
687
            return false;
688
        }
689
 
690
      return true;
691
    }
692
 
693
  /* Check ABI compatibility.  */
694
  if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
695
    {
696
      (*_bfd_error_handler)
697
        (_("%s: linking files compiled for 16-bit integers (-mshort) "
698
           "and others for 32-bit integers"),
699
         bfd_archive_filename (ibfd));
700
      ok = false;
701
    }
702
  if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
703
    {
704
      (*_bfd_error_handler)
705
        (_("%s: linking files compiled for 32-bit double (-fshort-double) "
706
           "and others for 64-bit double"),
707
         bfd_archive_filename (ibfd));
708
      ok = false;
709
    }
710
  new_flags &= ~EF_M68HC11_ABI;
711
  old_flags &= ~EF_M68HC11_ABI;
712
 
713
  /* Warn about any other mismatches */
714
  if (new_flags != old_flags)
715
    {
716
      (*_bfd_error_handler)
717
        (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
718
         bfd_archive_filename (ibfd), (unsigned long) new_flags,
719
         (unsigned long) old_flags);
720
      ok = false;
721
    }
722
 
723
  if (! ok)
724
    {
725
      bfd_set_error (bfd_error_bad_value);
726
      return false;
727
    }
728
 
729
  return true;
730
}
731
 
732
boolean
733
_bfd_m68hc12_elf_print_private_bfd_data (abfd, ptr)
734
     bfd *abfd;
735
     PTR ptr;
736
{
737
  FILE *file = (FILE *) ptr;
738
 
739
  BFD_ASSERT (abfd != NULL && ptr != NULL);
740
 
741
  /* Print normal ELF private data.  */
742
  _bfd_elf_print_private_bfd_data (abfd, ptr);
743
 
744
  /* xgettext:c-format */
745
  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
746
 
747
  if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
748
    fprintf (file, _("[abi=32-bit int,"));
749
  else
750
    fprintf (file, _("[abi=16-bit int,"));
751
 
752
  if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
753
    fprintf (file, _(" 64-bit double]"));
754
  else
755
    fprintf (file, _(" 32-bit double]"));
756
 
757
  fputc ('\n', file);
758
 
759
  return true;
760
}
761
 
762
/* Below is the only difference between elf32-m68hc12.c and elf32-m68hc11.c.
763
   The Motorola spec says to use a different Elf machine code.  */
764
#define ELF_ARCH                bfd_arch_m68hc12
765
#define ELF_MACHINE_CODE        EM_68HC12
766
#define ELF_MAXPAGESIZE         0x1000
767
 
768
#define TARGET_BIG_SYM          bfd_elf32_m68hc12_vec
769
#define TARGET_BIG_NAME         "elf32-m68hc12"
770
 
771
#define elf_info_to_howto       0
772
#define elf_info_to_howto_rel   m68hc11_info_to_howto_rel
773
#define elf_backend_gc_mark_hook     elf32_m68hc11_gc_mark_hook
774
#define elf_backend_gc_sweep_hook    elf32_m68hc11_gc_sweep_hook
775
#define elf_backend_object_p    0
776
#define elf_backend_final_write_processing      0
777
/* Disabled as this backend uses the generic linker.  */
778
#define elf_backend_can_gc_sections             0
779
 
780
#define bfd_elf32_bfd_merge_private_bfd_data \
781
                                        _bfd_m68hc12_elf_merge_private_bfd_data
782
#define bfd_elf32_bfd_set_private_flags _bfd_m68hc12_elf_set_private_flags
783
#define bfd_elf32_bfd_print_private_bfd_data \
784
                                        _bfd_m68hc12_elf_print_private_bfd_data
785
 
786
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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