Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/bfd/elf32-m68hc12.c
Line
Count
Source (jump to first uncovered line)
1
/* Motorola 68HC12-specific support for 32-bit ELF
2
   Copyright (C) 1999-2025 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 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
/* Relocation functions.  */
33
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
34
  (bfd *, bfd_reloc_code_real_type);
35
static bool m68hc11_info_to_howto_rel
36
  (bfd *, arelent *, Elf_Internal_Rela *);
37
38
/* Trampoline generation.  */
39
40
41
/* Use REL instead of RELA to save space */
42
#define USE_REL 1
43
44
/* The 68HC12 microcontroler has a memory bank switching system
45
   with a 16Kb window in the 64Kb address space.  The extended memory
46
   is mapped in the 16Kb window (at 0x8000).  The page register controls
47
   which 16Kb bank is mapped.  The call/rtc instructions take care of
48
   bank switching in function calls/returns.
49
50
   For GNU Binutils to work, we consider there is a physical memory
51
   at 0..0x0ffff and a kind of virtual memory above that.  Symbols
52
   in virtual memory have their addresses treated in a special way
53
   when disassembling and when linking.
54
55
   For the linker to work properly, we must always relocate the virtual
56
   memory as if it is mapped at 0x8000.  When a 16-bit relocation is
57
   made in the virtual memory, we check that it does not cross the
58
   memory bank where it is used.  This would involve a page change
59
   which would be wrong.  The 24-bit relocation is for that and it
60
   treats the address as a physical address + page number.
61
62
63
          Banked
64
          Address Space
65
          |   | Page n
66
          +---------------+ 0x1010000
67
          |   |
68
          | jsr _foo  |
69
          | ..    | Page 3
70
          | _foo:   |
71
          +---------------+ 0x100C000
72
          |   |
73
          | call _bar |
74
          | ..    | Page 2
75
          | _bar:   |
76
          +---------------+ 0x1008000
77
        /------>|   |
78
        | | call _foo | Page 1
79
        | |   |
80
        | +---------------+ 0x1004000
81
      Physical      | |   |
82
      Address Space   | |   | Page 0
83
        | |   |
84
    +-----------+ 0x00FFFF  | +---------------+ 0x1000000
85
    |   |   |
86
    | call _foo |   |
87
    |   |   |
88
    +-----------+ 0x00BFFF -+---/
89
    |   |     |
90
    |   |     |
91
    |   | 16K     |
92
    |   |     |
93
    +-----------+ 0x008000 -+
94
    |   |
95
    |   |
96
    =   =
97
    |   |
98
    |   |
99
    +-----------+ 0000
100
101
102
   The 'call _foo' must be relocated with page 3 and 16-bit address
103
   mapped at 0x8000.
104
105
   The 3-bit and 16-bit PC rel relocation is only used by 68HC12.  */
106
static reloc_howto_type elf_m68hc11_howto_table[] = {
107
  /* This reloc does nothing.  */
108
  HOWTO (R_M68HC11_NONE,  /* type */
109
   0,     /* rightshift */
110
   0,     /* size */
111
   0,     /* bitsize */
112
   false,     /* pc_relative */
113
   0,     /* bitpos */
114
   complain_overflow_dont,/* complain_on_overflow */
115
   bfd_elf_generic_reloc, /* special_function */
116
   "R_M68HC12_NONE",  /* name */
117
   false,     /* partial_inplace */
118
   0,     /* src_mask */
119
   0,     /* dst_mask */
120
   false),    /* pcrel_offset */
121
122
  /* A 8 bit absolute relocation */
123
  HOWTO (R_M68HC11_8,   /* type */
124
   0,     /* rightshift */
125
   1,     /* size */
126
   8,     /* bitsize */
127
   false,     /* pc_relative */
128
   0,     /* bitpos */
129
   complain_overflow_bitfield,  /* complain_on_overflow */
130
   bfd_elf_generic_reloc, /* special_function */
131
   "R_M68HC12_8",   /* name */
132
   false,     /* partial_inplace */
133
   0x00ff,    /* src_mask */
134
   0x00ff,    /* dst_mask */
135
   false),    /* pcrel_offset */
136
137
  /* A 8 bit absolute relocation (upper address) */
138
  HOWTO (R_M68HC11_HI8,   /* type */
139
   8,     /* rightshift */
140
   1,     /* size */
141
   8,     /* bitsize */
142
   false,     /* pc_relative */
143
   0,     /* bitpos */
144
   complain_overflow_bitfield,  /* complain_on_overflow */
145
   bfd_elf_generic_reloc, /* special_function */
146
   "R_M68HC12_HI8", /* name */
147
   false,     /* partial_inplace */
148
   0x00ff,    /* src_mask */
149
   0x00ff,    /* dst_mask */
150
   false),    /* pcrel_offset */
151
152
  /* A 8 bit absolute relocation (upper address) */
153
  HOWTO (R_M68HC11_LO8,   /* type */
154
   0,     /* rightshift */
155
   1,     /* size */
156
   8,     /* bitsize */
157
   false,     /* pc_relative */
158
   0,     /* bitpos */
159
   complain_overflow_dont,  /* complain_on_overflow */
160
   bfd_elf_generic_reloc, /* special_function */
161
   "R_M68HC12_LO8", /* name */
162
   false,     /* partial_inplace */
163
   0x00ff,    /* src_mask */
164
   0x00ff,    /* dst_mask */
165
   false),    /* pcrel_offset */
166
167
  /* A 8 bit PC-rel relocation */
168
  HOWTO (R_M68HC11_PCREL_8, /* type */
169
   0,     /* rightshift */
170
   1,     /* size */
171
   8,     /* bitsize */
172
   true,      /* pc_relative */
173
   0,     /* bitpos */
174
   complain_overflow_bitfield,  /* complain_on_overflow */
175
   bfd_elf_generic_reloc, /* special_function */
176
   "R_M68HC12_PCREL_8", /* name */
177
   false,     /* partial_inplace */
178
   0x00ff,    /* src_mask */
179
   0x00ff,    /* dst_mask */
180
   true),     /* pcrel_offset */
181
182
  /* A 16 bit absolute relocation */
183
  HOWTO (R_M68HC11_16,    /* type */
184
   0,     /* rightshift */
185
   2,     /* size */
186
   16,      /* bitsize */
187
   false,     /* pc_relative */
188
   0,     /* bitpos */
189
   complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
190
   bfd_elf_generic_reloc, /* special_function */
191
   "R_M68HC12_16",  /* name */
192
   false,     /* partial_inplace */
193
   0xffff,    /* src_mask */
194
   0xffff,    /* dst_mask */
195
   false),    /* pcrel_offset */
196
197
  /* A 32 bit absolute relocation.  This one is never used for the
198
     code relocation.  It's used by gas for -gstabs generation.  */
199
  HOWTO (R_M68HC11_32,    /* type */
200
   0,     /* rightshift */
201
   4,     /* size */
202
   32,      /* bitsize */
203
   false,     /* pc_relative */
204
   0,     /* bitpos */
205
   complain_overflow_bitfield,  /* complain_on_overflow */
206
   bfd_elf_generic_reloc, /* special_function */
207
   "R_M68HC12_32",  /* name */
208
   false,     /* partial_inplace */
209
   0xffffffff,    /* src_mask */
210
   0xffffffff,    /* dst_mask */
211
   false),    /* pcrel_offset */
212
213
  /* A 3 bit absolute relocation */
214
  HOWTO (R_M68HC11_3B,    /* type */
215
   0,     /* rightshift */
216
   1,     /* size */
217
   3,     /* bitsize */
218
   false,     /* pc_relative */
219
   0,     /* bitpos */
220
   complain_overflow_bitfield,  /* complain_on_overflow */
221
   bfd_elf_generic_reloc, /* special_function */
222
   "R_M68HC12_4B",  /* name */
223
   false,     /* partial_inplace */
224
   0x003,     /* src_mask */
225
   0x003,     /* dst_mask */
226
   false),    /* pcrel_offset */
227
228
  /* A 16 bit PC-rel relocation */
229
  HOWTO (R_M68HC11_PCREL_16,  /* type */
230
   0,     /* rightshift */
231
   2,     /* size */
232
   16,      /* bitsize */
233
   true,      /* pc_relative */
234
   0,     /* bitpos */
235
   complain_overflow_dont,  /* complain_on_overflow */
236
   bfd_elf_generic_reloc, /* special_function */
237
   "R_M68HC12_PCREL_16",  /* name */
238
   false,     /* partial_inplace */
239
   0xffff,    /* src_mask */
240
   0xffff,    /* dst_mask */
241
   true),     /* pcrel_offset */
242
243
  /* GNU extension to record C++ vtable hierarchy */
244
  HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */
245
   0,     /* rightshift */
246
   2,     /* size */
247
   0,     /* bitsize */
248
   false,     /* pc_relative */
249
   0,     /* bitpos */
250
   complain_overflow_dont,  /* complain_on_overflow */
251
   NULL,      /* special_function */
252
   "R_M68HC11_GNU_VTINHERIT", /* name */
253
   false,     /* partial_inplace */
254
   0,     /* src_mask */
255
   0,     /* dst_mask */
256
   false),    /* pcrel_offset */
257
258
  /* GNU extension to record C++ vtable member usage */
259
  HOWTO (R_M68HC11_GNU_VTENTRY, /* type */
260
   0,     /* rightshift */
261
   2,     /* size */
262
   0,     /* bitsize */
263
   false,     /* pc_relative */
264
   0,     /* bitpos */
265
   complain_overflow_dont,  /* complain_on_overflow */
266
   _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
267
   "R_M68HC11_GNU_VTENTRY", /* name */
268
   false,     /* partial_inplace */
269
   0,     /* src_mask */
270
   0,     /* dst_mask */
271
   false),    /* pcrel_offset */
272
273
  /* A 24 bit relocation */
274
  HOWTO (R_M68HC11_24,    /* type */
275
   0,     /* rightshift */
276
   4,     /* size */
277
   24,      /* bitsize */
278
   false,     /* pc_relative */
279
   0,     /* bitpos */
280
   complain_overflow_dont,  /* complain_on_overflow */
281
   m68hc11_elf_special_reloc, /* special_function */
282
   "R_M68HC12_24",  /* name */
283
   false,     /* partial_inplace */
284
   0xffffff,    /* src_mask */
285
   0xffffff,    /* dst_mask */
286
   false),    /* pcrel_offset */
287
288
  /* A 16-bit low relocation */
289
  HOWTO (R_M68HC11_LO16,  /* type */
290
   0,     /* rightshift */
291
   2,     /* size */
292
   16,      /* bitsize */
293
   false,     /* pc_relative */
294
   0,     /* bitpos */
295
   complain_overflow_dont,  /* complain_on_overflow */
296
   m68hc11_elf_special_reloc,/* special_function */
297
   "R_M68HC12_LO16",  /* name */
298
   false,     /* partial_inplace */
299
   0xffff,    /* src_mask */
300
   0xffff,    /* dst_mask */
301
   false),    /* pcrel_offset */
302
303
  /* A page relocation */
304
  HOWTO (R_M68HC11_PAGE,  /* type */
305
   0,     /* rightshift */
306
   1,     /* size */
307
   8,     /* bitsize */
308
   false,     /* pc_relative */
309
   0,     /* bitpos */
310
   complain_overflow_dont,  /* complain_on_overflow */
311
   m68hc11_elf_special_reloc,/* special_function */
312
   "R_M68HC12_PAGE",  /* name */
313
   false,     /* partial_inplace */
314
   0x00ff,    /* src_mask */
315
   0x00ff,    /* dst_mask */
316
   false),    /* pcrel_offset */
317
318
  EMPTY_HOWTO (14),
319
320
  /* A 16 bit absolute relocation.  */
321
  HOWTO (R_M68HC12_16B,   /* type */
322
   0,     /* rightshift */
323
   2,     /* size */
324
   16,      /* bitsize */
325
   false,     /* pc_relative */
326
   0,     /* bitpos */
327
   complain_overflow_bitfield,  /* complain_on_overflow */
328
   bfd_elf_generic_reloc, /* special_function */
329
   "R_M68HC12_16B", /* name */
330
   false,     /* partial_inplace */
331
   0xffff,    /* src_mask */
332
   0xffff,    /* dst_mask */
333
   false),    /* pcrel_offset */
334
335
  /* A 9 bit PC-rel relocation.  */
336
  HOWTO (R_M68HC12_PCREL_9, /* type */
337
   1,     /* rightshift */
338
   2,     /* size */
339
   10,      /* bitsize (result is >>1) */
340
   true,      /* pc_relative */
341
   0,     /* bitpos */
342
   complain_overflow_dont,  /* complain_on_overflow */
343
   bfd_elf_generic_reloc, /* special_function */
344
   "R_M68HC12_PCREL_9", /* name */
345
   true,      /* partial_inplace */
346
   0xfe00,    /* src_mask */
347
   0x01ff,    /* dst_mask */
348
   true),     /* pcrel_offset */
349
350
  /* A 10 bit PC-rel relocation.  */
351
  HOWTO (R_M68HC12_PCREL_10,  /* type */
352
   1,     /* rightshift */
353
   2,     /* size */
354
   11,      /* bitsize (result is >>1) */
355
   true,      /* pc_relative */
356
   0,     /* bitpos */
357
   complain_overflow_dont,  /* complain_on_overflow */
358
   bfd_elf_generic_reloc, /* special_function */
359
   "R_M68HC12_PCREL_10",  /* name */
360
   true,      /* partial_inplace */
361
   0xfc00,    /* src_mask */
362
   0x03ff,    /* dst_mask */
363
   true),     /* pcrel_offset */
364
365
  /* A 8 bit absolute relocation (upper address).  */
366
  HOWTO (R_M68HC12_HI8XG,   /* type */
367
   8,     /* rightshift */
368
   1,     /* size */
369
   8,     /* bitsize */
370
   false,     /* pc_relative */
371
   0,     /* bitpos */
372
   complain_overflow_bitfield,  /* complain_on_overflow */
373
   bfd_elf_generic_reloc, /* special_function */
374
   "R_M68HC12_HI8XG", /* name */
375
   false,     /* partial_inplace */
376
   0x00ff,    /* src_mask */
377
   0x00ff,    /* dst_mask */
378
   false),    /* pcrel_offset */
379
380
  /* A 8 bit absolute relocation (lower address).  */
381
  HOWTO (R_M68HC12_LO8XG,   /* type */
382
   8,     /* rightshift */
383
   1,     /* size */
384
   8,     /* bitsize */
385
   false,     /* pc_relative */
386
   0,     /* bitpos */
387
   complain_overflow_bitfield,  /* complain_on_overflow */
388
   bfd_elf_generic_reloc, /* special_function */
389
   "R_M68HC12_LO8XG", /* name */
390
   false,     /* partial_inplace */
391
   0x00ff,    /* src_mask */
392
   0x00ff,    /* dst_mask */
393
   false),    /* pcrel_offset */
394
395
  /* Mark beginning of a jump instruction (any form).  */
396
  HOWTO (R_M68HC11_RL_JUMP, /* type */
397
   0,     /* rightshift */
398
   2,     /* size */
399
   0,     /* bitsize */
400
   false,     /* pc_relative */
401
   0,     /* bitpos */
402
   complain_overflow_dont,  /* complain_on_overflow */
403
   m68hc11_elf_ignore_reloc,  /* special_function */
404
   "R_M68HC12_RL_JUMP", /* name */
405
   true,      /* partial_inplace */
406
   0,     /* src_mask */
407
   0,     /* dst_mask */
408
   true),     /* pcrel_offset */
409
410
  /* Mark beginning of Gcc relaxation group instruction.  */
411
  HOWTO (R_M68HC11_RL_GROUP,  /* type */
412
   0,     /* rightshift */
413
   2,     /* size */
414
   0,     /* bitsize */
415
   false,     /* pc_relative */
416
   0,     /* bitpos */
417
   complain_overflow_dont,  /* complain_on_overflow */
418
   m68hc11_elf_ignore_reloc,  /* special_function */
419
   "R_M68HC12_RL_GROUP",  /* name */
420
   true,      /* partial_inplace */
421
   0,     /* src_mask */
422
   0,     /* dst_mask */
423
   true),     /* pcrel_offset */
424
};
425
426
/* Map BFD reloc types to M68HC11 ELF reloc types.  */
427
428
struct m68hc11_reloc_map
429
{
430
  bfd_reloc_code_real_type bfd_reloc_val;
431
  unsigned char elf_reloc_val;
432
};
433
434
static const struct m68hc11_reloc_map m68hc11_reloc_map[] =
435
{
436
  {BFD_RELOC_NONE, R_M68HC11_NONE,},
437
  {BFD_RELOC_8, R_M68HC11_8},
438
  {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
439
  {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
440
  {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
441
  {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
442
  {BFD_RELOC_16, R_M68HC11_16},
443
  {BFD_RELOC_32, R_M68HC11_32},
444
  {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
445
446
  {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
447
  {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
448
449
  {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
450
  {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
451
  {BFD_RELOC_M68HC11_24, R_M68HC11_24},
452
453
  {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
454
  {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
455
456
  {BFD_RELOC_M68HC12_16B, R_M68HC12_16B},
457
458
  {BFD_RELOC_M68HC12_9_PCREL, R_M68HC12_PCREL_9},
459
  {BFD_RELOC_M68HC12_10_PCREL, R_M68HC12_PCREL_10},
460
  {BFD_RELOC_M68HC12_HI8XG, R_M68HC12_HI8XG},
461
  {BFD_RELOC_M68HC12_LO8XG, R_M68HC12_LO8XG},
462
};
463
464
static reloc_howto_type *
465
bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
466
         bfd_reloc_code_real_type code)
467
0
{
468
0
  unsigned int i;
469
470
0
  for (i = 0;
471
0
       i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
472
0
       i++)
473
0
    {
474
0
      if (m68hc11_reloc_map[i].bfd_reloc_val == code)
475
0
  return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
476
0
    }
477
478
0
  return NULL;
479
0
}
480
481
static reloc_howto_type *
482
bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
483
         const char *r_name)
484
0
{
485
0
  unsigned int i;
486
487
0
  for (i = 0;
488
0
       i < (sizeof (elf_m68hc11_howto_table)
489
0
      / sizeof (elf_m68hc11_howto_table[0]));
490
0
       i++)
491
0
    if (elf_m68hc11_howto_table[i].name != NULL
492
0
  && strcasecmp (elf_m68hc11_howto_table[i].name, r_name) == 0)
493
0
      return &elf_m68hc11_howto_table[i];
494
495
0
  return NULL;
496
0
}
497
498
/* Set the howto pointer for an M68HC11 ELF reloc.  */
499
500
static bool
501
m68hc11_info_to_howto_rel (bfd *abfd,
502
         arelent *cache_ptr, Elf_Internal_Rela *dst)
503
0
{
504
0
  unsigned int r_type;
505
506
0
  r_type = ELF32_R_TYPE (dst->r_info);
507
0
  if (r_type >= (unsigned int) R_M68HC11_max)
508
0
    {
509
      /* xgettext:c-format */
510
0
      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
511
0
        abfd, r_type);
512
0
      bfd_set_error (bfd_error_bad_value);
513
0
      return false;
514
0
    }
515
0
  cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
516
0
  return true;
517
0
}
518
519

520
/* Far trampoline generation.  */
521
522
/* Build a 68HC12 trampoline stub.  */
523
static bool
524
m68hc12_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
525
0
{
526
0
  struct elf32_m68hc11_stub_hash_entry *stub_entry;
527
0
  struct bfd_link_info *info;
528
0
  struct m68hc11_elf_link_hash_table *htab;
529
0
  asection *stub_sec;
530
0
  bfd *stub_bfd;
531
0
  bfd_byte *loc;
532
0
  bfd_vma sym_value, phys_page, phys_addr;
533
534
  /* Massage our args to the form they really have.  */
535
0
  stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
536
0
  info = (struct bfd_link_info *) in_arg;
537
538
  /* Fail if the target section could not be assigned to an output
539
     section.  The user should fix his linker script.  */
540
0
  if (stub_entry->target_section->output_section == NULL
541
0
      && info->non_contiguous_regions)
542
0
    info->callbacks->fatal (_("%P: Could not assign `%pA' to an output section. "
543
0
            "Retry without --enable-non-contiguous-regions.\n"),
544
0
          stub_entry->target_section);
545
546
0
  htab = m68hc11_elf_hash_table (info);
547
548
0
  stub_sec = stub_entry->stub_sec;
549
550
  /* Make a note of the offset within the stubs for this entry.  */
551
0
  stub_entry->stub_offset = stub_sec->size;
552
0
  stub_sec->size += 7;
553
0
  loc = stub_sec->contents + stub_entry->stub_offset;
554
555
0
  stub_bfd = stub_sec->owner;
556
557
  /* Create the trampoline call stub:
558
559
     ldy #%addr(symbol)
560
     call %page(symbol), __trampoline
561
562
  */
563
0
  sym_value = (stub_entry->target_value
564
0
         + stub_entry->target_section->output_offset
565
0
         + stub_entry->target_section->output_section->vma);
566
0
  phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value);
567
0
  phys_page = m68hc11_phys_page (&htab->pinfo, sym_value);
568
569
  /* ldy #%page(sym) */
570
0
  bfd_put_8 (stub_bfd, 0xCD, loc);
571
0
  bfd_put_16 (stub_bfd, phys_addr, loc + 1);
572
0
  loc += 3;
573
574
  /* call %page(sym), __trampoline  */
575
0
  bfd_put_8 (stub_bfd, 0x4a, loc);
576
0
  bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1);
577
0
  bfd_put_8 (stub_bfd, phys_page, loc + 3);
578
579
0
  return true;
580
0
}
581
582
/* As above, but don't actually build the stub.  Just bump offset so
583
   we know stub section sizes.  */
584
585
static bool
586
m68hc12_elf_size_one_stub (struct bfd_hash_entry *gen_entry,
587
         void *in_arg ATTRIBUTE_UNUSED)
588
0
{
589
0
  struct elf32_m68hc11_stub_hash_entry *stub_entry;
590
591
  /* Massage our args to the form they really have.  */
592
0
  stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
593
594
0
  stub_entry->stub_sec->size += 7;
595
0
  return true;
596
0
}
597
598
/* Create a 68HC12 ELF linker hash table.  */
599
600
static struct bfd_link_hash_table *
601
m68hc12_elf_bfd_link_hash_table_create (bfd *abfd)
602
0
{
603
0
  struct m68hc11_elf_link_hash_table *ret;
604
605
0
  ret = m68hc11_elf_hash_table_create (abfd);
606
0
  if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
607
0
    return NULL;
608
609
0
  ret->size_one_stub = m68hc12_elf_size_one_stub;
610
0
  ret->build_one_stub = m68hc12_elf_build_one_stub;
611
612
0
  return &ret->root.root;
613
0
}
614

615
static bool
616
m68hc12_elf_set_mach_from_flags (bfd *abfd)
617
1.86k
{
618
1.86k
  flagword flags = elf_elfheader (abfd)->e_flags;
619
620
1.86k
  switch (flags & EF_M68HC11_MACH_MASK)
621
1.86k
    {
622
472
    case EF_M68HC12_MACH:
623
472
      bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, bfd_mach_m6812);
624
472
      break;
625
475
    case EF_M68HCS12_MACH:
626
475
      bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, bfd_mach_m6812s);
627
475
      break;
628
582
    case EF_M68HC11_GENERIC:
629
582
      bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12,
630
582
         bfd_mach_m6812_default);
631
582
      break;
632
334
    default:
633
334
      return false;
634
1.86k
    }
635
1.52k
  return true;
636
1.86k
}
637
638
/* Specific sections:
639
   - The .page0 is a data section that is mapped in [0x0000..0x00FF].
640
     Page0 accesses are faster on the M68HC12.
641
   - The .vectors is the section that represents the interrupt
642
     vectors.  */
643
static const struct bfd_elf_special_section elf32_m68hc12_special_sections[] =
644
{
645
  { STRING_COMMA_LEN (".eeprom"),   0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
646
  { STRING_COMMA_LEN (".page0"),    0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
647
  { STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
648
  { STRING_COMMA_LEN (".vectors"),  0, SHT_PROGBITS, SHF_ALLOC },
649
  { NULL,     0,  0, 0,      0 }
650
};
651

652
#define ELF_ARCH    bfd_arch_m68hc12
653
#define ELF_TARGET_ID   M68HC11_ELF_DATA
654
#define ELF_MACHINE_CODE  EM_68HC12
655
#define ELF_MAXPAGESIZE   0x1000
656
657
#define TARGET_BIG_SYM    m68hc12_elf32_vec
658
#define TARGET_BIG_NAME   "elf32-m68hc12"
659
660
#define elf_info_to_howto NULL
661
#define elf_info_to_howto_rel m68hc11_info_to_howto_rel
662
#define elf_backend_check_relocs     elf32_m68hc11_check_relocs
663
#define elf_backend_relocate_section elf32_m68hc11_relocate_section
664
#define elf_backend_object_p    m68hc12_elf_set_mach_from_flags
665
#define elf_backend_can_gc_sections   1
666
#define elf_backend_special_sections elf32_m68hc12_special_sections
667
#define elf_backend_init_file_header     elf32_m68hc11_init_file_header
668
#define elf_backend_add_symbol_hook  elf32_m68hc11_add_symbol_hook
669
#define elf_backend_merge_symbol_attribute elf32_m68hc11_merge_symbol_attribute
670
671
#define bfd_elf32_bfd_link_hash_table_create \
672
        m68hc12_elf_bfd_link_hash_table_create
673
#define bfd_elf32_bfd_merge_private_bfd_data \
674
          _bfd_m68hc11_elf_merge_private_bfd_data
675
#define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags
676
#define bfd_elf32_bfd_print_private_bfd_data \
677
          _bfd_m68hc11_elf_print_private_bfd_data
678
679
#include "elf32-target.h"