Coverage Report

Created: 2026-03-10 08:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/bfd/elf32-rl78.c
Line
Count
Source
1
/* Renesas RL78 specific support for 32-bit ELF.
2
   Copyright (C) 2011-2026 Free Software Foundation, Inc.
3
4
   This file is part of BFD, the Binary File Descriptor library.
5
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3 of the License, or
9
   (at your option) any later version.
10
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   MA 02110-1301, USA.  */
20
21
#include "sysdep.h"
22
#include "bfd.h"
23
#include "libbfd.h"
24
#include "elf-bfd.h"
25
#include "elf/rl78.h"
26
#include "libiberty.h"
27
28
0
#define valid_16bit_address(v) ((v) <= 0x0ffff || (v) >= 0xf0000)
29
30
#define RL78REL(n,sz,bit,mask,shift,complain,pcrel) \
31
  HOWTO (R_RL78_##n, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
32
   bfd_elf_generic_reloc, "R_RL78_" #n, false, 0, mask, false)
33
34
static bfd_reloc_status_type rl78_special_reloc (bfd *, arelent *, asymbol *, void *,
35
             asection *, bfd *, char **);
36
37
#define RL78_OP_REL(n,sz,bit,mask,shift,complain,pcrel)     \
38
  HOWTO (R_RL78_##n, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
39
   rl78_special_reloc, "R_RL78_" #n, false, 0, mask, false)
40
41
/* Note that the relocations around 0x7f are internal to this file;
42
   feel free to move them as needed to avoid conflicts with published
43
   relocation numbers.  */
44
45
static reloc_howto_type rl78_elf_howto_table [] =
46
{
47
  RL78REL (NONE,   0,  0, 0,          0, dont,     false),
48
  RL78REL (DIR32,  4, 32, 0xffffffff, 0, dont,     false),
49
  RL78REL (DIR24S,   4, 24, 0xffffff,   0, signed,   false),
50
  RL78REL (DIR16,  2, 16, 0xffff,     0, bitfield, false),
51
  RL78REL (DIR16U,   2, 16, 0xffff,     0, unsigned, false),
52
  RL78REL (DIR16S,   2, 16, 0xffff,     0, bitfield, false),
53
  RL78REL (DIR8,   1,  8, 0xff,       0, dont,     false),
54
  RL78REL (DIR8U,  1,  8, 0xff,       0, unsigned, false),
55
  RL78REL (DIR8S,  1,  8, 0xff,       0, bitfield, false),
56
  RL78REL (DIR24S_PCREL, 4, 24, 0xffffff,   0, signed,   true),
57
  RL78REL (DIR16S_PCREL, 2, 16, 0xffff,     0, signed,   true),
58
  RL78REL (DIR8S_PCREL,  1,  8, 0xff,       0, signed,   true),
59
  RL78REL (DIR16UL,  2, 16, 0xffff,     2, unsigned, false),
60
  RL78REL (DIR16UW,  2, 16, 0xffff,     1, unsigned, false),
61
  RL78REL (DIR8UL,   1,  8, 0xff,       2, unsigned, false),
62
  RL78REL (DIR8UW,   1,  8, 0xff,       1, unsigned, false),
63
  RL78REL (DIR32_REV,  4, 32, 0xffffffff, 0, dont,     false),
64
  RL78REL (DIR16_REV,  2, 16, 0xffff,     0, bitfield, false),
65
  RL78REL (DIR3U_PCREL,  1,  3, 0x7,        0, unsigned, true),
66
67
  EMPTY_HOWTO (0x13),
68
  EMPTY_HOWTO (0x14),
69
  EMPTY_HOWTO (0x15),
70
  EMPTY_HOWTO (0x16),
71
  EMPTY_HOWTO (0x17),
72
  EMPTY_HOWTO (0x18),
73
  EMPTY_HOWTO (0x19),
74
  EMPTY_HOWTO (0x1a),
75
  EMPTY_HOWTO (0x1b),
76
  EMPTY_HOWTO (0x1c),
77
  EMPTY_HOWTO (0x1d),
78
  EMPTY_HOWTO (0x1e),
79
  EMPTY_HOWTO (0x1f),
80
81
  EMPTY_HOWTO (0x20),
82
  EMPTY_HOWTO (0x21),
83
  EMPTY_HOWTO (0x22),
84
  EMPTY_HOWTO (0x23),
85
  EMPTY_HOWTO (0x24),
86
  EMPTY_HOWTO (0x25),
87
  EMPTY_HOWTO (0x26),
88
  EMPTY_HOWTO (0x27),
89
  EMPTY_HOWTO (0x28),
90
  EMPTY_HOWTO (0x29),
91
  EMPTY_HOWTO (0x2a),
92
  EMPTY_HOWTO (0x2b),
93
  EMPTY_HOWTO (0x2c),
94
95
  RL78REL (RH_RELAX,   0,  0, 0,          0, dont,   false),
96
  RL78REL (RH_SFR,   1,  8, 0xff,       0, unsigned, false),
97
  RL78REL (RH_SADDR,   1,  8, 0xff,       0, unsigned, false),
98
99
  EMPTY_HOWTO (0x30),
100
  EMPTY_HOWTO (0x31),
101
  EMPTY_HOWTO (0x32),
102
  EMPTY_HOWTO (0x33),
103
  EMPTY_HOWTO (0x34),
104
  EMPTY_HOWTO (0x35),
105
  EMPTY_HOWTO (0x36),
106
  EMPTY_HOWTO (0x37),
107
  EMPTY_HOWTO (0x38),
108
  EMPTY_HOWTO (0x39),
109
  EMPTY_HOWTO (0x3a),
110
  EMPTY_HOWTO (0x3b),
111
  EMPTY_HOWTO (0x3c),
112
  EMPTY_HOWTO (0x3d),
113
  EMPTY_HOWTO (0x3e),
114
  EMPTY_HOWTO (0x3f),
115
  EMPTY_HOWTO (0x40),
116
117
  RL78_OP_REL (ABS32,      4, 32, 0xffffffff, 0, dont,  false),
118
  RL78_OP_REL (ABS24S,       4, 24, 0xffffff,   0, signed,  false),
119
  RL78_OP_REL (ABS16,      2, 16, 0xffff,     0, bitfield,  false),
120
  RL78_OP_REL (ABS16U,       2, 16, 0xffff,     0, unsigned,  false),
121
  RL78_OP_REL (ABS16S,       2, 16, 0xffff,     0, signed,  false),
122
  RL78_OP_REL (ABS8,       1,  8, 0xff,       0, bitfield,  false),
123
  RL78_OP_REL (ABS8U,      1,  8, 0xff,       0, unsigned,  false),
124
  RL78_OP_REL (ABS8S,      1,  8, 0xff,       0, signed,  false),
125
  RL78_OP_REL (ABS24S_PCREL, 4, 24, 0xffffff,   0, signed,  true),
126
  RL78_OP_REL (ABS16S_PCREL, 2, 16, 0xffff,     0, signed,  true),
127
  RL78_OP_REL (ABS8S_PCREL,  1,  8, 0xff,       0, signed,  true),
128
  RL78_OP_REL (ABS16UL,      2, 16, 0xffff,     0, unsigned,  false),
129
  RL78_OP_REL (ABS16UW,      2, 16, 0xffff,     0, unsigned,  false),
130
  RL78_OP_REL (ABS8UL,       1,  8, 0xff,       0, unsigned,  false),
131
  RL78_OP_REL (ABS8UW,       1,  8, 0xff,       0, unsigned,  false),
132
  RL78_OP_REL (ABS32_REV,    4, 32, 0xffffffff, 0, dont,  false),
133
  RL78_OP_REL (ABS16_REV,    2, 16, 0xffff,     0, bitfield,  false),
134
135
0
#define STACK_REL_P(x) ((x) <= R_RL78_ABS16_REV && (x) >= R_RL78_ABS32)
136
137
  EMPTY_HOWTO (0x52),
138
  EMPTY_HOWTO (0x53),
139
  EMPTY_HOWTO (0x54),
140
  EMPTY_HOWTO (0x55),
141
  EMPTY_HOWTO (0x56),
142
  EMPTY_HOWTO (0x57),
143
  EMPTY_HOWTO (0x58),
144
  EMPTY_HOWTO (0x59),
145
  EMPTY_HOWTO (0x5a),
146
  EMPTY_HOWTO (0x5b),
147
  EMPTY_HOWTO (0x5c),
148
  EMPTY_HOWTO (0x5d),
149
  EMPTY_HOWTO (0x5e),
150
  EMPTY_HOWTO (0x5f),
151
  EMPTY_HOWTO (0x60),
152
  EMPTY_HOWTO (0x61),
153
  EMPTY_HOWTO (0x62),
154
  EMPTY_HOWTO (0x63),
155
  EMPTY_HOWTO (0x64),
156
  EMPTY_HOWTO (0x65),
157
  EMPTY_HOWTO (0x66),
158
  EMPTY_HOWTO (0x67),
159
  EMPTY_HOWTO (0x68),
160
  EMPTY_HOWTO (0x69),
161
  EMPTY_HOWTO (0x6a),
162
  EMPTY_HOWTO (0x6b),
163
  EMPTY_HOWTO (0x6c),
164
  EMPTY_HOWTO (0x6d),
165
  EMPTY_HOWTO (0x6e),
166
  EMPTY_HOWTO (0x6f),
167
  EMPTY_HOWTO (0x70),
168
  EMPTY_HOWTO (0x71),
169
  EMPTY_HOWTO (0x72),
170
  EMPTY_HOWTO (0x73),
171
  EMPTY_HOWTO (0x74),
172
  EMPTY_HOWTO (0x75),
173
  EMPTY_HOWTO (0x76),
174
  EMPTY_HOWTO (0x77),
175
176
  EMPTY_HOWTO (0x78),
177
  EMPTY_HOWTO (0x79),
178
  EMPTY_HOWTO (0x7a),
179
  EMPTY_HOWTO (0x7b),
180
  EMPTY_HOWTO (0x7c),
181
  EMPTY_HOWTO (0x7d),
182
  EMPTY_HOWTO (0x7e),
183
  EMPTY_HOWTO (0x7f),
184
185
  RL78_OP_REL (SYM,   0, 0, 0, 0, dont, false),
186
  RL78_OP_REL (OPneg,   0, 0, 0, 0, dont, false),
187
  RL78_OP_REL (OPadd,   0, 0, 0, 0, dont, false),
188
  RL78_OP_REL (OPsub,   0, 0, 0, 0, dont, false),
189
  RL78_OP_REL (OPmul,   0, 0, 0, 0, dont, false),
190
  RL78_OP_REL (OPdiv,   0, 0, 0, 0, dont, false),
191
  RL78_OP_REL (OPshla,    0, 0, 0, 0, dont, false),
192
  RL78_OP_REL (OPshra,    0, 0, 0, 0, dont, false),
193
  RL78_OP_REL (OPsctsize, 0, 0, 0, 0, dont, false),
194
  EMPTY_HOWTO (0x89),
195
  EMPTY_HOWTO (0x8a),
196
  EMPTY_HOWTO (0x8b),
197
  EMPTY_HOWTO (0x8c),
198
  RL78_OP_REL (OPscttop,  0, 0, 0, 0, dont, false),
199
  EMPTY_HOWTO (0x8e),
200
  EMPTY_HOWTO (0x8f),
201
  RL78_OP_REL (OPand,   0, 0, 0, 0, dont, false),
202
  RL78_OP_REL (OPor,    0, 0, 0, 0, dont, false),
203
  RL78_OP_REL (OPxor,   0, 0, 0, 0, dont, false),
204
  RL78_OP_REL (OPnot,   0, 0, 0, 0, dont, false),
205
  RL78_OP_REL (OPmod,   0, 0, 0, 0, dont, false),
206
  RL78_OP_REL (OPromtop,  0, 0, 0, 0, dont, false),
207
  RL78_OP_REL (OPramtop,  0, 0, 0, 0, dont, false)
208
};
209

210
/* Map BFD reloc types to RL78 ELF reloc types.  */
211
212
struct rl78_reloc_map
213
{
214
  bfd_reloc_code_real_type  bfd_reloc_val;
215
  unsigned int        rl78_reloc_val;
216
};
217
218
static const struct rl78_reloc_map rl78_reloc_map [] =
219
{
220
  { BFD_RELOC_NONE,   R_RL78_NONE },
221
  { BFD_RELOC_8,    R_RL78_DIR8S },
222
  { BFD_RELOC_16,   R_RL78_DIR16S },
223
  { BFD_RELOC_24,   R_RL78_DIR24S },
224
  { BFD_RELOC_32,   R_RL78_DIR32 },
225
  { BFD_RELOC_RL78_16_OP, R_RL78_DIR16 },
226
  { BFD_RELOC_RL78_DIR3U_PCREL, R_RL78_DIR3U_PCREL },
227
  { BFD_RELOC_8_PCREL,    R_RL78_DIR8S_PCREL },
228
  { BFD_RELOC_16_PCREL,   R_RL78_DIR16S_PCREL },
229
  { BFD_RELOC_24_PCREL,   R_RL78_DIR24S_PCREL },
230
  { BFD_RELOC_RL78_8U,    R_RL78_DIR8U },
231
  { BFD_RELOC_RL78_16U,   R_RL78_DIR16U },
232
  { BFD_RELOC_RL78_SYM,   R_RL78_SYM },
233
  { BFD_RELOC_RL78_OP_SUBTRACT, R_RL78_OPsub },
234
  { BFD_RELOC_RL78_OP_NEG,  R_RL78_OPneg },
235
  { BFD_RELOC_RL78_OP_AND,  R_RL78_OPand },
236
  { BFD_RELOC_RL78_OP_SHRA, R_RL78_OPshra },
237
  { BFD_RELOC_RL78_ABS8,  R_RL78_ABS8 },
238
  { BFD_RELOC_RL78_ABS16, R_RL78_ABS16 },
239
  { BFD_RELOC_RL78_ABS16_REV, R_RL78_ABS16_REV },
240
  { BFD_RELOC_RL78_ABS32, R_RL78_ABS32 },
241
  { BFD_RELOC_RL78_ABS32_REV, R_RL78_ABS32_REV },
242
  { BFD_RELOC_RL78_ABS16UL, R_RL78_ABS16UL },
243
  { BFD_RELOC_RL78_ABS16UW, R_RL78_ABS16UW },
244
  { BFD_RELOC_RL78_ABS16U,  R_RL78_ABS16U },
245
  { BFD_RELOC_RL78_SADDR, R_RL78_RH_SADDR },
246
  { BFD_RELOC_RL78_RELAX, R_RL78_RH_RELAX }
247
};
248
249
static reloc_howto_type *
250
rl78_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
251
      bfd_reloc_code_real_type code)
252
0
{
253
0
  unsigned int i;
254
255
0
  if (code == BFD_RELOC_RL78_32_OP)
256
0
    return rl78_elf_howto_table + R_RL78_DIR32;
257
258
0
  for (i = ARRAY_SIZE (rl78_reloc_map); i--;)
259
0
    if (rl78_reloc_map [i].bfd_reloc_val == code)
260
0
      return rl78_elf_howto_table + rl78_reloc_map[i].rl78_reloc_val;
261
262
0
  return NULL;
263
0
}
264
265
static reloc_howto_type *
266
rl78_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED, const char * r_name)
267
0
{
268
0
  unsigned int i;
269
270
0
  for (i = 0; i < ARRAY_SIZE (rl78_elf_howto_table); i++)
271
0
    if (rl78_elf_howto_table[i].name != NULL
272
0
  && strcasecmp (rl78_elf_howto_table[i].name, r_name) == 0)
273
0
      return rl78_elf_howto_table + i;
274
275
0
  return NULL;
276
0
}
277
278
/* Set the howto pointer for an RL78 ELF reloc.  */
279
280
static bool
281
rl78_info_to_howto_rela (bfd *         abfd,
282
       arelent *       cache_ptr,
283
       Elf_Internal_Rela * dst)
284
0
{
285
0
  unsigned int r_type;
286
287
0
  r_type = ELF32_R_TYPE (dst->r_info);
288
0
  if (r_type >= (unsigned int) R_RL78_max)
289
0
    {
290
      /* xgettext:c-format */
291
0
      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
292
0
        abfd, r_type);
293
0
      bfd_set_error (bfd_error_bad_value);
294
0
      return false;
295
0
    }
296
0
  cache_ptr->howto = rl78_elf_howto_table + r_type;
297
0
  return true;
298
0
}
299

300
static bfd_vma
301
get_symbol_value (const char *      name,
302
      struct bfd_link_info *  info,
303
      bfd *       input_bfd,
304
      asection *      input_section,
305
      int       offset)
306
0
{
307
0
  struct bfd_link_hash_entry * h;
308
309
0
  if (info == NULL)
310
0
    return 0;
311
312
0
  h = bfd_link_hash_lookup (info->hash, name, false, false, true);
313
314
0
  if (h == NULL
315
0
      || (h->type != bfd_link_hash_defined
316
0
    && h->type != bfd_link_hash_defweak))
317
0
    {
318
0
      (*info->callbacks->undefined_symbol)
319
0
  (info, name, input_bfd, input_section, offset, true);
320
0
      return 0;
321
0
    }
322
323
0
  return (h->u.def.value
324
0
    + h->u.def.section->output_section->vma
325
0
    + h->u.def.section->output_offset);
326
0
}
327
328
static bfd_vma
329
get_romstart (struct bfd_link_info *  info,
330
        bfd *         abfd,
331
        asection *        sec,
332
        int         offset)
333
0
{
334
0
  static bool cached = false;
335
0
  static bfd_vma cached_value = 0;
336
337
0
  if (!cached)
338
0
    {
339
0
      cached_value = get_symbol_value ("_start", info, abfd, sec, offset);
340
0
      cached = true;
341
0
    }
342
0
  return cached_value;
343
0
}
344
345
static bfd_vma
346
get_ramstart (struct bfd_link_info *  info,
347
        bfd *         abfd,
348
        asection *        sec,
349
        int         offset)
350
0
{
351
0
  static bool cached = false;
352
0
  static bfd_vma cached_value = 0;
353
354
0
  if (!cached)
355
0
    {
356
0
      cached_value = get_symbol_value ("__datastart", info, abfd, sec, offset);
357
0
      cached = true;
358
0
    }
359
0
  return cached_value;
360
0
}
361
362
0
#define NUM_STACK_ENTRIES 16
363
static int32_t rl78_stack [ NUM_STACK_ENTRIES ];
364
static unsigned int rl78_stack_top;
365
366
static inline void
367
rl78_stack_push (bfd_vma val, bfd_reloc_status_type *r)
368
0
{
369
0
  if (rl78_stack_top < NUM_STACK_ENTRIES)
370
0
    rl78_stack[rl78_stack_top++] = val;
371
0
  else
372
0
    *r = bfd_reloc_dangerous;
373
0
}
374
375
static inline bfd_vma
376
rl78_stack_pop (bfd_reloc_status_type *r)
377
0
{
378
0
  if (rl78_stack_top > 0)
379
0
    return rl78_stack[-- rl78_stack_top];
380
0
  else
381
0
    *r = bfd_reloc_dangerous;
382
0
  return 0;
383
0
}
384
385
/* Special handling for RL78 complex relocs.  Returns the
386
   value of the reloc, or 0 for relocs which do not generate
387
   a result.  SYMVAL is the value of the symbol for relocs
388
   which use a symbolic argument.  */
389
390
static bfd_vma
391
rl78_compute_complex_reloc (unsigned long  r_type,
392
          bfd_vma symval,
393
          asection *input_section,
394
          bfd_reloc_status_type *r,
395
          char **error_message)
396
0
{
397
0
  int32_t tmp1, tmp2;
398
0
  bfd_vma relocation = 0;
399
0
  bfd_reloc_status_type status = bfd_reloc_ok;
400
401
0
  switch (r_type)
402
0
    {
403
0
    default:
404
0
      status = bfd_reloc_notsupported;
405
0
      break;
406
407
0
    case R_RL78_ABS24S_PCREL:
408
0
    case R_RL78_ABS16S_PCREL:
409
0
    case R_RL78_ABS8S_PCREL:
410
0
      relocation = rl78_stack_pop (&status);
411
0
      relocation -= input_section->output_section->vma + input_section->output_offset;
412
0
      break;
413
414
0
    case R_RL78_ABS32:
415
0
    case R_RL78_ABS32_REV:
416
0
    case R_RL78_ABS16:
417
0
    case R_RL78_ABS16_REV:
418
0
    case R_RL78_ABS16S:
419
0
    case R_RL78_ABS16U:
420
0
    case R_RL78_ABS8:
421
0
    case R_RL78_ABS8U:
422
0
    case R_RL78_ABS8S:
423
0
      relocation = rl78_stack_pop (&status);
424
0
      break;
425
426
0
    case R_RL78_ABS16UL:
427
0
    case R_RL78_ABS8UL:
428
0
      relocation = rl78_stack_pop (&status) >> 2;
429
0
      break;;
430
431
0
    case R_RL78_ABS16UW:
432
0
    case R_RL78_ABS8UW:
433
0
      relocation = rl78_stack_pop (&status) >> 1;
434
0
      break;
435
436
      /* The rest of the relocs compute values and then push them onto the stack.  */
437
0
    case R_RL78_OPramtop:
438
0
    case R_RL78_OPromtop:
439
0
    case R_RL78_SYM:
440
0
      rl78_stack_push (symval, &status);
441
0
      break;
442
443
0
    case R_RL78_OPneg:
444
0
      tmp1 = rl78_stack_pop (&status);
445
0
      tmp1 = - tmp1;
446
0
      rl78_stack_push (tmp1, &status);
447
0
      break;
448
449
0
    case R_RL78_OPadd:
450
0
      tmp2 = rl78_stack_pop (&status);
451
0
      tmp1 = rl78_stack_pop (&status);
452
0
      tmp1 += tmp2;
453
0
      rl78_stack_push (tmp1, &status);
454
0
      break;
455
456
0
    case R_RL78_OPsub:
457
      /* For the expression "A - B", the assembler pushes A,
458
   then B, then OPSUB.  So the first op we pop is B, not A.  */
459
0
      tmp2 = rl78_stack_pop (&status);  /* B */
460
0
      tmp1 = rl78_stack_pop (&status);  /* A */
461
0
      tmp1 -= tmp2;   /* A - B */
462
0
      rl78_stack_push (tmp1, &status);
463
0
      break;
464
465
0
    case R_RL78_OPmul:
466
0
      tmp2 = rl78_stack_pop (&status);
467
0
      tmp1 = rl78_stack_pop (&status);
468
0
      tmp1 *= tmp2;
469
0
      rl78_stack_push (tmp1, &status);
470
0
      break;
471
472
0
    case R_RL78_OPdiv:
473
0
      tmp2 = rl78_stack_pop (&status);
474
0
      tmp1 = rl78_stack_pop (&status);
475
0
      if (tmp2 != 0)
476
0
  tmp1 /= tmp2;
477
0
      else
478
0
  {
479
0
    tmp1 = 0;
480
0
    status = bfd_reloc_overflow;
481
0
  }
482
0
      rl78_stack_push (tmp1, &status);
483
0
      break;
484
485
0
    case R_RL78_OPshla:
486
0
      tmp2 = rl78_stack_pop (&status);
487
0
      tmp1 = rl78_stack_pop (&status);
488
0
      tmp1 <<= tmp2;
489
0
      rl78_stack_push (tmp1, &status);
490
0
      break;
491
492
0
    case R_RL78_OPshra:
493
0
      tmp2 = rl78_stack_pop (&status);
494
0
      tmp1 = rl78_stack_pop (&status);
495
0
      tmp1 >>= tmp2;
496
0
      rl78_stack_push (tmp1, &status);
497
0
      break;
498
499
0
    case R_RL78_OPsctsize:
500
0
      rl78_stack_push (input_section->size, &status);
501
0
      break;
502
503
0
    case R_RL78_OPscttop:
504
0
      rl78_stack_push (input_section->output_section->vma, &status);
505
0
      break;
506
507
0
    case R_RL78_OPand:
508
0
      tmp2 = rl78_stack_pop (&status);
509
0
      tmp1 = rl78_stack_pop (&status);
510
0
      tmp1 &= tmp2;
511
0
      rl78_stack_push (tmp1, &status);
512
0
      break;
513
514
0
    case R_RL78_OPor:
515
0
      tmp2 = rl78_stack_pop (&status);
516
0
      tmp1 = rl78_stack_pop (&status);
517
0
      tmp1 |= tmp2;
518
0
      rl78_stack_push (tmp1, &status);
519
0
      break;
520
521
0
    case R_RL78_OPxor:
522
0
      tmp2 = rl78_stack_pop (&status);
523
0
      tmp1 = rl78_stack_pop (&status);
524
0
      tmp1 ^= tmp2;
525
0
      rl78_stack_push (tmp1, &status);
526
0
      break;
527
528
0
    case R_RL78_OPnot:
529
0
      tmp1 = rl78_stack_pop (&status);
530
0
      tmp1 = ~ tmp1;
531
0
      rl78_stack_push (tmp1, &status);
532
0
      break;
533
534
0
    case R_RL78_OPmod:
535
0
      tmp2 = rl78_stack_pop (&status);
536
0
      tmp1 = rl78_stack_pop (&status);
537
0
      if (tmp2 != 0)
538
0
  tmp1 %= tmp2;
539
0
      else
540
0
  {
541
0
    tmp1 = 0;
542
0
    status = bfd_reloc_overflow;
543
0
  }
544
0
      rl78_stack_push (tmp1, &status);
545
0
      break;
546
0
    }
547
548
0
  if (r)
549
0
    {
550
0
      if (status == bfd_reloc_dangerous)
551
0
  *error_message = (_("RL78 reloc stack overflow/underflow"));
552
0
      else if (status == bfd_reloc_overflow)
553
0
  {
554
0
    status = bfd_reloc_dangerous;
555
0
    *error_message = (_("RL78 reloc divide by zero"));
556
0
  }
557
0
      *r = status;
558
0
    }
559
0
  return relocation;
560
0
}
561
562
/* Check whether RELOCATION overflows a relocation field described by
563
   HOWTO.  */
564
565
static bfd_reloc_status_type
566
check_overflow (reloc_howto_type *howto, bfd_vma relocation)
567
0
{
568
0
  switch (howto->complain_on_overflow)
569
0
    {
570
0
    case complain_overflow_dont:
571
0
      break;
572
573
0
    case complain_overflow_bitfield:
574
0
      if ((bfd_signed_vma) relocation < -(1LL << (howto->bitsize - 1))
575
0
    || (bfd_signed_vma) relocation >= 1LL << howto->bitsize)
576
0
  return bfd_reloc_overflow;
577
0
      break;
578
579
0
    case complain_overflow_signed:
580
0
      if ((bfd_signed_vma) relocation < -(1LL << (howto->bitsize - 1))
581
0
    || (bfd_signed_vma) relocation >= 1LL << (howto->bitsize - 1))
582
0
  return bfd_reloc_overflow;
583
0
      break;
584
585
0
    case complain_overflow_unsigned:
586
0
      if (relocation >= 1ULL << howto->bitsize)
587
0
  return bfd_reloc_overflow;
588
0
      break;
589
0
    }
590
0
  return bfd_reloc_ok;
591
0
}
592
593
static bfd_reloc_status_type
594
rl78_special_reloc (bfd *      input_bfd,
595
        arelent *  reloc,
596
        asymbol *  symbol,
597
        void *     data,
598
        asection * input_section,
599
        bfd *      output_bfd ATTRIBUTE_UNUSED,
600
        char **    error_message)
601
0
{
602
0
  bfd_reloc_status_type  r = bfd_reloc_ok;
603
0
  bfd_vma    relocation = 0;
604
0
  unsigned long    r_type = reloc->howto->type;
605
0
  bfd_byte *     contents = data;
606
607
  /* If necessary, compute the symbolic value of the relocation.  */
608
0
  switch (r_type)
609
0
    {
610
0
    case R_RL78_SYM:
611
0
      relocation = (symbol->value
612
0
        + symbol->section->output_section->vma
613
0
        + symbol->section->output_offset
614
0
        + reloc->addend);
615
0
  break;
616
617
0
    case R_RL78_OPromtop:
618
0
      relocation = get_romstart (NULL, input_bfd, input_section,
619
0
         reloc->address);
620
0
      break;
621
622
0
    case R_RL78_OPramtop:
623
0
      relocation = get_ramstart (NULL, input_bfd, input_section,
624
0
         reloc->address);
625
0
      break;
626
0
    }
627
628
  /* Get the value of the relocation.  */
629
0
  relocation = rl78_compute_complex_reloc (r_type, relocation, input_section,
630
0
             &r, error_message);
631
632
0
  if (STACK_REL_P (r_type))
633
0
    {
634
0
      bfd_size_type limit;
635
0
      unsigned int nbytes;
636
637
0
      if (r == bfd_reloc_ok)
638
0
  r = check_overflow (reloc->howto, relocation);
639
640
0
      if (r_type == R_RL78_ABS16_REV)
641
0
  relocation = ((relocation & 0xff) << 8) | ((relocation >> 8) & 0xff);
642
0
      else if (r_type == R_RL78_ABS32_REV)
643
0
  relocation = (((relocation & 0xff) << 24)
644
0
          | ((relocation & 0xff00) << 8)
645
0
          | ((relocation >> 8) & 0xff00)
646
0
          | ((relocation >> 24) & 0xff));
647
648
0
      limit = bfd_get_section_limit_octets (input_bfd, input_section);
649
0
      nbytes = reloc->howto->bitsize / 8;
650
0
      if (reloc->address < limit
651
0
    && nbytes <= limit - reloc->address)
652
0
  {
653
0
    unsigned int i;
654
655
0
    for (i = 0; i < nbytes; i++)
656
0
      {
657
0
        contents[reloc->address + i] = relocation;
658
0
        relocation >>= 8;
659
0
      }
660
0
  }
661
0
      else
662
0
  r = bfd_reloc_outofrange;
663
0
    }
664
665
0
  return r;
666
0
}
667
668
0
#define OP(i)      (contents[rel->r_offset + (i)])
669
670
/* Relocate an RL78 ELF section.
671
   There is some attempt to make this function usable for many architectures,
672
   both USE_REL and USE_RELA ['twould be nice if such a critter existed],
673
   if only to serve as a learning tool.
674
675
   The RELOCATE_SECTION function is called by the new ELF backend linker
676
   to handle the relocations for a section.
677
678
   The relocs are always passed as Rela structures; if the section
679
   actually uses Rel structures, the r_addend field will always be
680
   zero.
681
682
   This function is responsible for adjusting the section contents as
683
   necessary, and (if using Rela relocs and generating a relocatable
684
   output file) adjusting the reloc addend as necessary.
685
686
   This function does not have to worry about setting the reloc
687
   address or the reloc symbol index.
688
689
   LOCAL_SYMS is a pointer to the swapped in local symbols.
690
691
   LOCAL_SECTIONS is an array giving the section in the input file
692
   corresponding to the st_shndx field of each local symbol.
693
694
   The global hash table entry for the global symbols can be found
695
   via elf_sym_hashes (input_bfd).
696
697
   When generating relocatable output, this function must handle
698
   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
699
   going to be the section symbol corresponding to the output
700
   section, which means that the addend must be adjusted
701
   accordingly.  */
702
703
static int
704
rl78_elf_relocate_section
705
    (bfd *         output_bfd,
706
     struct bfd_link_info *  info,
707
     bfd *         input_bfd,
708
     asection *        input_section,
709
     bfd_byte *        contents,
710
     Elf_Internal_Rela *     relocs,
711
     Elf_Internal_Sym *      local_syms,
712
     asection **       local_sections)
713
0
{
714
0
  Elf_Internal_Shdr *   symtab_hdr;
715
0
  struct elf_link_hash_entry ** sym_hashes;
716
0
  Elf_Internal_Rela *   rel;
717
0
  Elf_Internal_Rela *   relend;
718
0
  asection *splt;
719
0
  bool ret;
720
721
0
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
722
0
  sym_hashes = elf_sym_hashes (input_bfd);
723
0
  relend     = relocs + input_section->reloc_count;
724
725
0
  splt = elf_hash_table (info)->splt;
726
0
  ret = true;
727
0
  for (rel = relocs; rel < relend; rel ++)
728
0
    {
729
0
      reloc_howto_type *howto;
730
0
      unsigned long r_symndx;
731
0
      Elf_Internal_Sym *sym;
732
0
      asection *sec;
733
0
      struct elf_link_hash_entry *h;
734
0
      bfd_vma relocation;
735
0
      bfd_reloc_status_type r;
736
0
      const char *name = NULL;
737
0
      bool unresolved_reloc = true;
738
0
      int r_type;
739
0
      char *error_message;
740
741
0
      r_type = ELF32_R_TYPE (rel->r_info);
742
0
      r_symndx = ELF32_R_SYM (rel->r_info);
743
744
0
      howto  = rl78_elf_howto_table + ELF32_R_TYPE (rel->r_info);
745
0
      h      = NULL;
746
0
      sym    = NULL;
747
0
      sec    = NULL;
748
0
      relocation = 0;
749
750
0
      if (r_symndx < symtab_hdr->sh_info)
751
0
  {
752
0
    sym = local_syms + r_symndx;
753
0
    sec = local_sections [r_symndx];
754
0
    relocation = _bfd_elf_rela_local_sym (output_bfd, sym, & sec, rel);
755
756
0
    name = bfd_elf_string_from_elf_section
757
0
      (input_bfd, symtab_hdr->sh_link, sym->st_name);
758
0
    name = sym->st_name == 0 ? bfd_section_name (sec) : name;
759
0
  }
760
0
      else
761
0
  {
762
0
    bool warned ATTRIBUTE_UNUSED;
763
0
    bool ignored ATTRIBUTE_UNUSED;
764
765
0
    RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
766
0
           r_symndx, symtab_hdr, sym_hashes, h,
767
0
           sec, relocation, unresolved_reloc,
768
0
           warned, ignored);
769
770
0
    name = h->root.root.string;
771
0
  }
772
773
0
      if (sec != NULL && discarded_section (sec))
774
0
  RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
775
0
           rel, 1, relend, R_RL78_NONE,
776
0
           howto, 0, contents);
777
778
0
      if (bfd_link_relocatable (info))
779
0
  {
780
    /* This is a relocatable link.  We don't have to change
781
       anything, unless the reloc is against a section symbol,
782
       in which case we have to adjust according to where the
783
       section symbol winds up in the output section.  */
784
0
    if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
785
0
      rel->r_addend += sec->output_offset;
786
0
    continue;
787
0
  }
788
789
0
      switch (ELF32_R_TYPE (rel->r_info))
790
0
  {
791
0
  case R_RL78_DIR16S:
792
0
    {
793
0
      bfd_vma *plt_offset;
794
795
0
      if (h != NULL)
796
0
        plt_offset = &h->plt.offset;
797
0
      else
798
0
        plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
799
800
0
      if (! valid_16bit_address (relocation))
801
0
        {
802
    /* If this is the first time we've processed this symbol,
803
       fill in the plt entry with the correct symbol address.  */
804
0
    if ((*plt_offset & 1) == 0)
805
0
      {
806
0
        unsigned int x;
807
808
0
        x = 0x000000ec;  /* br !!abs24 */
809
0
        x |= (relocation << 8) & 0xffffff00;
810
0
        bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
811
0
        *plt_offset |= 1;
812
0
      }
813
814
0
    relocation = (splt->output_section->vma
815
0
            + splt->output_offset
816
0
            + (*plt_offset & -2));
817
0
    if (name)
818
0
    {
819
0
      char *newname = bfd_malloc (strlen(name)+5);
820
0
      strcpy (newname, name);
821
0
      strcat(newname, ".plt");
822
0
      _bfd_generic_link_add_one_symbol (info,
823
0
                input_bfd,
824
0
                newname,
825
0
                BSF_FUNCTION | BSF_WEAK,
826
0
                splt,
827
0
                (*plt_offset & -2),
828
0
                0,
829
0
                1,
830
0
                0,
831
0
                0);
832
0
    }
833
0
        }
834
0
    }
835
0
    break;
836
0
  }
837
838
0
      if (h != NULL && h->root.type == bfd_link_hash_undefweak)
839
  /* If the symbol is undefined and weak
840
     then the relocation resolves to zero.  */
841
0
  relocation = 0;
842
0
      else
843
0
  {
844
0
    if (howto->pc_relative)
845
0
      {
846
0
        relocation -= (input_section->output_section->vma
847
0
           + input_section->output_offset
848
0
           + rel->r_offset);
849
0
        relocation -= bfd_get_reloc_size (howto);
850
0
      }
851
852
0
    relocation += rel->r_addend;
853
0
  }
854
855
0
      r = bfd_reloc_ok;
856
0
      if (howto->bitsize != 0
857
0
    && (rel->r_offset >= input_section->size
858
0
        || ((howto->bitsize + 7u) / 8
859
0
      > input_section->size - rel->r_offset)))
860
0
  r = bfd_reloc_outofrange;
861
0
      else
862
0
  switch (r_type)
863
0
    {
864
0
    case R_RL78_NONE:
865
0
      break;
866
867
0
    case R_RL78_RH_RELAX:
868
0
      break;
869
870
0
    case R_RL78_DIR8S_PCREL:
871
0
      OP (0) = relocation;
872
0
      break;
873
874
0
    case R_RL78_DIR8S:
875
0
      OP (0) = relocation;
876
0
      break;
877
878
0
    case R_RL78_DIR8U:
879
0
      OP (0) = relocation;
880
0
      break;
881
882
0
    case R_RL78_DIR16S_PCREL:
883
0
      OP (0) = relocation;
884
0
      OP (1) = relocation >> 8;
885
0
      break;
886
887
0
    case R_RL78_DIR16S:
888
0
      if ((relocation & 0xf0000) == 0xf0000)
889
0
        relocation &= 0xffff;
890
0
      OP (0) = relocation;
891
0
      OP (1) = relocation >> 8;
892
0
      break;
893
894
0
    case R_RL78_DIR16U:
895
0
      OP (0) = relocation;
896
0
      OP (1) = relocation >> 8;
897
0
      break;
898
899
0
    case R_RL78_DIR16:
900
0
      OP (0) = relocation;
901
0
      OP (1) = relocation >> 8;
902
0
      break;
903
904
0
    case R_RL78_DIR16_REV:
905
0
      OP (1) = relocation;
906
0
      OP (0) = relocation >> 8;
907
0
      break;
908
909
0
    case R_RL78_DIR3U_PCREL:
910
0
      OP (0) &= 0xf8;
911
0
      OP (0) |= relocation & 0x07;
912
      /* Map [3, 10] to [0, 7].  The code below using howto
913
         bitsize will check for unsigned overflow.  */
914
0
      relocation -= 3;
915
0
      break;
916
917
0
    case R_RL78_DIR24S_PCREL:
918
0
      OP (0) = relocation;
919
0
      OP (1) = relocation >> 8;
920
0
      OP (2) = relocation >> 16;
921
0
      break;
922
923
0
    case R_RL78_DIR24S:
924
0
      OP (0) = relocation;
925
0
      OP (1) = relocation >> 8;
926
0
      OP (2) = relocation >> 16;
927
0
      break;
928
929
0
    case R_RL78_DIR32:
930
0
      OP (0) = relocation;
931
0
      OP (1) = relocation >> 8;
932
0
      OP (2) = relocation >> 16;
933
0
      OP (3) = relocation >> 24;
934
0
      break;
935
936
0
    case R_RL78_DIR32_REV:
937
0
      OP (3) = relocation;
938
0
      OP (2) = relocation >> 8;
939
0
      OP (1) = relocation >> 16;
940
0
      OP (0) = relocation >> 24;
941
0
      break;
942
943
0
    case R_RL78_RH_SFR:
944
0
      relocation -= 0xfff00;
945
0
      OP (0) = relocation;
946
0
      break;
947
948
0
    case R_RL78_RH_SADDR:
949
0
      relocation -= 0xffe20;
950
0
      OP (0) = relocation;
951
0
      break;
952
953
      /* Complex reloc handling:  */
954
0
    case R_RL78_ABS32:
955
0
    case R_RL78_ABS32_REV:
956
0
    case R_RL78_ABS24S_PCREL:
957
0
    case R_RL78_ABS24S:
958
0
    case R_RL78_ABS16:
959
0
    case R_RL78_ABS16_REV:
960
0
    case R_RL78_ABS16S_PCREL:
961
0
    case R_RL78_ABS16S:
962
0
    case R_RL78_ABS16U:
963
0
    case R_RL78_ABS16UL:
964
0
    case R_RL78_ABS16UW:
965
0
    case R_RL78_ABS8:
966
0
    case R_RL78_ABS8U:
967
0
    case R_RL78_ABS8UL:
968
0
    case R_RL78_ABS8UW:
969
0
    case R_RL78_ABS8S_PCREL:
970
0
    case R_RL78_ABS8S:
971
0
    case R_RL78_OPneg:
972
0
    case R_RL78_OPadd:
973
0
    case R_RL78_OPsub:
974
0
    case R_RL78_OPmul:
975
0
    case R_RL78_OPdiv:
976
0
    case R_RL78_OPshla:
977
0
    case R_RL78_OPshra:
978
0
    case R_RL78_OPsctsize:
979
0
    case R_RL78_OPscttop:
980
0
    case R_RL78_OPand:
981
0
    case R_RL78_OPor:
982
0
    case R_RL78_OPxor:
983
0
    case R_RL78_OPnot:
984
0
    case R_RL78_OPmod:
985
0
      relocation = rl78_compute_complex_reloc (r_type, 0, input_section,
986
0
                 &r, &error_message);
987
988
0
      switch (r_type)
989
0
        {
990
0
        case R_RL78_ABS32:
991
0
    OP (0) = relocation;
992
0
    OP (1) = relocation >> 8;
993
0
    OP (2) = relocation >> 16;
994
0
    OP (3) = relocation >> 24;
995
0
    break;
996
997
0
        case R_RL78_ABS32_REV:
998
0
    OP (3) = relocation;
999
0
    OP (2) = relocation >> 8;
1000
0
    OP (1) = relocation >> 16;
1001
0
    OP (0) = relocation >> 24;
1002
0
    break;
1003
1004
0
        case R_RL78_ABS24S_PCREL:
1005
0
        case R_RL78_ABS24S:
1006
0
    OP (0) = relocation;
1007
0
    OP (1) = relocation >> 8;
1008
0
    OP (2) = relocation >> 16;
1009
0
    break;
1010
1011
0
        case R_RL78_ABS16:
1012
0
    OP (0) = relocation;
1013
0
    OP (1) = relocation >> 8;
1014
0
    break;
1015
1016
0
        case R_RL78_ABS16_REV:
1017
0
    OP (1) = relocation;
1018
0
    OP (0) = relocation >> 8;
1019
0
    break;
1020
1021
0
        case R_RL78_ABS16S_PCREL:
1022
0
        case R_RL78_ABS16S:
1023
0
    OP (0) = relocation;
1024
0
    OP (1) = relocation >> 8;
1025
0
    break;
1026
1027
0
        case R_RL78_ABS16U:
1028
0
        case R_RL78_ABS16UL:
1029
0
        case R_RL78_ABS16UW:
1030
0
    OP (0) = relocation;
1031
0
    OP (1) = relocation >> 8;
1032
0
    break;
1033
1034
0
        case R_RL78_ABS8:
1035
0
    OP (0) = relocation;
1036
0
    break;
1037
1038
0
        case R_RL78_ABS8U:
1039
0
        case R_RL78_ABS8UL:
1040
0
        case R_RL78_ABS8UW:
1041
0
    OP (0) = relocation;
1042
0
    break;
1043
1044
0
        case R_RL78_ABS8S_PCREL:
1045
0
        case R_RL78_ABS8S:
1046
0
    OP (0) = relocation;
1047
0
    break;
1048
1049
0
        default:
1050
0
    break;
1051
0
        }
1052
0
      break;
1053
1054
0
    case R_RL78_SYM:
1055
0
      if (r_symndx < symtab_hdr->sh_info)
1056
0
        relocation = sec->output_section->vma + sec->output_offset
1057
0
    + sym->st_value + rel->r_addend;
1058
0
      else if (h != NULL
1059
0
         && (h->root.type == bfd_link_hash_defined
1060
0
       || h->root.type == bfd_link_hash_defweak))
1061
0
        relocation = h->root.u.def.value
1062
0
    + sec->output_section->vma
1063
0
    + sec->output_offset
1064
0
    + rel->r_addend;
1065
0
      else
1066
0
        {
1067
0
    relocation = 0;
1068
0
    if (h->root.type != bfd_link_hash_undefweak)
1069
0
      _bfd_error_handler
1070
0
        (_("warning: RL78_SYM reloc with an unknown symbol"));
1071
0
        }
1072
0
      (void) rl78_compute_complex_reloc (r_type, relocation, input_section,
1073
0
                 &r, &error_message);
1074
0
      break;
1075
1076
0
    case R_RL78_OPromtop:
1077
0
      relocation = get_romstart (info, input_bfd, input_section,
1078
0
               rel->r_offset);
1079
0
      (void) rl78_compute_complex_reloc (r_type, relocation, input_section,
1080
0
                 &r, &error_message);
1081
0
      break;
1082
1083
0
    case R_RL78_OPramtop:
1084
0
      relocation = get_ramstart (info, input_bfd, input_section,
1085
0
               rel->r_offset);
1086
0
      (void) rl78_compute_complex_reloc (r_type, relocation, input_section,
1087
0
                 &r, &error_message);
1088
0
      break;
1089
1090
0
    default:
1091
0
      r = bfd_reloc_notsupported;
1092
0
      break;
1093
0
    }
1094
1095
0
      if (r == bfd_reloc_ok)
1096
0
  r = check_overflow (howto, relocation);
1097
1098
0
      if (r != bfd_reloc_ok)
1099
0
  {
1100
0
    switch (r)
1101
0
      {
1102
0
      case bfd_reloc_overflow:
1103
0
        (*info->callbacks->reloc_overflow)
1104
0
    (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
1105
0
     input_bfd, input_section, rel->r_offset);
1106
0
        break;
1107
1108
0
      case bfd_reloc_undefined:
1109
0
        (*info->callbacks->undefined_symbol)
1110
0
    (info, name, input_bfd, input_section, rel->r_offset, true);
1111
0
        break;
1112
1113
0
      case bfd_reloc_outofrange:
1114
         /* xgettext:c-format */
1115
0
        (*info->callbacks->einfo)
1116
0
    (_("%H: %s out of range\n"),
1117
0
     input_bfd, input_section, rel->r_offset, howto->name);
1118
0
        break;
1119
1120
0
      case bfd_reloc_notsupported:
1121
        /* xgettext:c-format */
1122
0
        (*info->callbacks->einfo)
1123
0
    (_("%H: relocation type %u is not supported\n"),
1124
0
     input_bfd, input_section, rel->r_offset, r_type);
1125
0
        break;
1126
1127
0
      case bfd_reloc_dangerous:
1128
0
        (*info->callbacks->reloc_dangerous)
1129
0
    (info, error_message, input_bfd, input_section, rel->r_offset);
1130
0
        break;
1131
1132
0
      default:
1133
        /* xgettext:c-format */
1134
0
        (*info->callbacks->einfo)
1135
0
    (_("%H: relocation %s returns an unrecognized value %x\n"),
1136
0
     input_bfd, input_section, rel->r_offset, howto->name, r);
1137
0
        break;
1138
0
      }
1139
0
    ret = false;
1140
0
  }
1141
0
    }
1142
1143
0
  return ret;
1144
0
}
1145

1146
/* Function to set the ELF flag bits.  */
1147
1148
static bool
1149
rl78_elf_set_private_flags (bfd * abfd, flagword flags)
1150
0
{
1151
0
  elf_elfheader (abfd)->e_flags = flags;
1152
0
  elf_flags_init (abfd) = true;
1153
0
  return true;
1154
0
}
1155
1156
static bool no_warn_mismatch = false;
1157
1158
void bfd_elf32_rl78_set_target_flags (bool);
1159
1160
void
1161
bfd_elf32_rl78_set_target_flags (bool user_no_warn_mismatch)
1162
0
{
1163
0
  no_warn_mismatch = user_no_warn_mismatch;
1164
0
}
1165
1166
static const char *
1167
rl78_cpu_name (flagword flags)
1168
4
{
1169
4
  switch (flags & E_FLAG_RL78_CPU_MASK)
1170
4
    {
1171
0
    default: return "";
1172
3
    case E_FLAG_RL78_G10:     return "G10";
1173
0
    case E_FLAG_RL78_G13:     return "G13";
1174
1
    case E_FLAG_RL78_G14:     return "G14";
1175
4
    }
1176
4
}
1177
1178
/* Merge backend specific data from an object file to the output
1179
   object file when linking.  */
1180
1181
static bool
1182
rl78_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
1183
0
{
1184
0
  bfd *obfd = info->output_bfd;
1185
0
  flagword new_flags;
1186
0
  flagword old_flags;
1187
0
  bool error = false;
1188
1189
0
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
1190
0
    return true;
1191
1192
0
  new_flags = elf_elfheader (ibfd)->e_flags;
1193
0
  old_flags = elf_elfheader (obfd)->e_flags;
1194
1195
0
  if (!elf_flags_init (obfd))
1196
0
    {
1197
      /* First call, no flags set.  */
1198
0
      elf_flags_init (obfd) = true;
1199
0
      elf_elfheader (obfd)->e_flags = new_flags;
1200
0
    }
1201
0
  else if (old_flags != new_flags)
1202
0
    {
1203
0
      flagword changed_flags = old_flags ^ new_flags;
1204
1205
0
      if (changed_flags & E_FLAG_RL78_CPU_MASK)
1206
0
  {
1207
0
    flagword out_cpu = old_flags & E_FLAG_RL78_CPU_MASK;
1208
0
    flagword in_cpu = new_flags & E_FLAG_RL78_CPU_MASK;
1209
1210
0
    if (in_cpu == E_FLAG_RL78_ANY_CPU || in_cpu == out_cpu)
1211
0
      /* It does not matter what new_cpu may have.  */;
1212
0
    else if (out_cpu == E_FLAG_RL78_ANY_CPU)
1213
0
      {
1214
0
        if (in_cpu == E_FLAG_RL78_G10)
1215
0
    {
1216
      /* G10 files can only be linked with other G10 files.
1217
         If the output is set to "any" this means that it is
1218
         a G14 file that does not use hardware multiply/divide,
1219
         but that is still incompatible with the G10 ABI.  */
1220
0
      error = true;
1221
1222
0
      _bfd_error_handler
1223
        /* xgettext:c-format */
1224
0
        (_("RL78 ABI conflict: G10 file %pB cannot be linked"
1225
0
           " with %s file %pB"),
1226
0
         ibfd, rl78_cpu_name (out_cpu), obfd);
1227
0
    }
1228
0
        else
1229
0
    {
1230
0
      old_flags &= ~ E_FLAG_RL78_CPU_MASK;
1231
0
      old_flags |= in_cpu;
1232
0
      elf_elfheader (obfd)->e_flags = old_flags;
1233
0
    }
1234
0
      }
1235
0
    else
1236
0
      {
1237
0
        error = true;
1238
1239
0
        _bfd_error_handler
1240
    /* xgettext:c-format */
1241
0
    (_("RL78 ABI conflict: cannot link %s file %pB with %s file %pB"),
1242
0
     rl78_cpu_name (in_cpu),  ibfd,
1243
0
     rl78_cpu_name (out_cpu), obfd);
1244
0
      }
1245
0
  }
1246
1247
0
      if (changed_flags & E_FLAG_RL78_64BIT_DOUBLES)
1248
0
  {
1249
0
    _bfd_error_handler
1250
0
      (_("RL78 merge conflict: cannot link 32-bit and 64-bit objects together"));
1251
1252
0
    if (old_flags & E_FLAG_RL78_64BIT_DOUBLES)
1253
      /* xgettext:c-format */
1254
0
      _bfd_error_handler (_("- %pB is 64-bit, %pB is not"),
1255
0
        obfd, ibfd);
1256
0
    else
1257
      /* xgettext:c-format */
1258
0
      _bfd_error_handler (_("- %pB is 64-bit, %pB is not"),
1259
0
        ibfd, obfd);
1260
0
    error = true;
1261
0
  }
1262
0
    }
1263
1264
0
  return !error;
1265
0
}
1266

1267
static bool
1268
rl78_elf_print_private_bfd_data (bfd * abfd, void * ptr)
1269
569
{
1270
569
  FILE * file = (FILE *) ptr;
1271
569
  flagword flags;
1272
1273
569
  BFD_ASSERT (abfd != NULL && ptr != NULL);
1274
1275
  /* Print normal ELF private data.  */
1276
569
  _bfd_elf_print_private_bfd_data (abfd, ptr);
1277
1278
569
  flags = elf_elfheader (abfd)->e_flags;
1279
569
  fprintf (file, _("private flags = 0x%lx:"), (long) flags);
1280
1281
569
  if (flags & E_FLAG_RL78_CPU_MASK)
1282
4
    fprintf (file, " [%s]", rl78_cpu_name (flags));
1283
1284
569
  if (flags & E_FLAG_RL78_64BIT_DOUBLES)
1285
2
    fprintf (file, _(" [64-bit doubles]"));
1286
1287
569
  fputc ('\n', file);
1288
569
  return true;
1289
569
}
1290
1291
/* Return the MACH for an e_flags value.  */
1292
1293
static int
1294
elf32_rl78_machine (bfd * abfd ATTRIBUTE_UNUSED)
1295
1.14k
{
1296
1.14k
  return bfd_mach_rl78;
1297
1.14k
}
1298
1299
static bool
1300
rl78_elf_object_p (bfd * abfd)
1301
1.14k
{
1302
1.14k
  bfd_default_set_arch_mach (abfd, bfd_arch_rl78,
1303
1.14k
           elf32_rl78_machine (abfd));
1304
1.14k
  return true;
1305
1.14k
}
1306

1307
/* support PLT for 16-bit references to 24-bit functions.  */
1308
1309
/* We support 16-bit pointers to code above 64k by generating a thunk
1310
   below 64k containing a JMP instruction to the final address.  */
1311
1312
static bool
1313
rl78_elf_check_relocs
1314
    (bfd *           abfd,
1315
     struct bfd_link_info *    info,
1316
     asection *          sec,
1317
     const Elf_Internal_Rela * relocs)
1318
0
{
1319
0
  Elf_Internal_Shdr *   symtab_hdr;
1320
0
  struct elf_link_hash_entry ** sym_hashes;
1321
0
  const Elf_Internal_Rela * rel;
1322
0
  const Elf_Internal_Rela * rel_end;
1323
0
  bfd_vma *local_plt_offsets;
1324
0
  asection *splt;
1325
0
  bfd *dynobj;
1326
1327
0
  if (bfd_link_relocatable (info))
1328
0
    return true;
1329
1330
0
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1331
0
  sym_hashes = elf_sym_hashes (abfd);
1332
0
  local_plt_offsets = elf_local_got_offsets (abfd);
1333
0
  dynobj = elf_hash_table(info)->dynobj;
1334
1335
0
  rel_end = relocs + sec->reloc_count;
1336
0
  for (rel = relocs; rel < rel_end; rel++)
1337
0
    {
1338
0
      struct elf_link_hash_entry *h;
1339
0
      unsigned long r_symndx;
1340
0
      bfd_vma *offset;
1341
1342
0
      r_symndx = ELF32_R_SYM (rel->r_info);
1343
0
      if (r_symndx < symtab_hdr->sh_info)
1344
0
  h = NULL;
1345
0
      else
1346
0
  {
1347
0
    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1348
0
    while (h->root.type == bfd_link_hash_indirect
1349
0
     || h->root.type == bfd_link_hash_warning)
1350
0
      h = (struct elf_link_hash_entry *) h->root.u.i.link;
1351
0
  }
1352
1353
0
      switch (ELF32_R_TYPE (rel->r_info))
1354
0
  {
1355
    /* This relocation describes a 16-bit pointer to a function.
1356
       We may need to allocate a thunk in low memory; reserve memory
1357
       for it now.  */
1358
0
  case R_RL78_DIR16S:
1359
0
    if (dynobj == NULL)
1360
0
      elf_hash_table (info)->dynobj = dynobj = abfd;
1361
0
    splt = elf_hash_table (info)->splt;
1362
0
    if (splt == NULL)
1363
0
      {
1364
0
        flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
1365
0
        | SEC_IN_MEMORY | SEC_LINKER_CREATED
1366
0
        | SEC_READONLY | SEC_CODE);
1367
0
        splt = bfd_make_section_anyway_with_flags (dynobj, ".plt",
1368
0
               flags);
1369
0
        elf_hash_table (info)->splt = splt;
1370
0
        if (splt == NULL
1371
0
      || !bfd_set_section_alignment (splt, 1))
1372
0
    return false;
1373
0
      }
1374
1375
0
    if (h != NULL)
1376
0
      offset = &h->plt.offset;
1377
0
    else
1378
0
      {
1379
0
        if (local_plt_offsets == NULL)
1380
0
    {
1381
0
      size_t size;
1382
0
      unsigned int i;
1383
1384
0
      size = symtab_hdr->sh_info * sizeof (bfd_vma);
1385
0
      local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size);
1386
0
      if (local_plt_offsets == NULL)
1387
0
        return false;
1388
0
      elf_local_got_offsets (abfd) = local_plt_offsets;
1389
1390
0
      for (i = 0; i < symtab_hdr->sh_info; i++)
1391
0
        local_plt_offsets[i] = (bfd_vma) -1;
1392
0
    }
1393
0
        offset = &local_plt_offsets[r_symndx];
1394
0
      }
1395
1396
0
    if (*offset == (bfd_vma) -1)
1397
0
      {
1398
0
        *offset = splt->size;
1399
0
        splt->size += 4;
1400
0
      }
1401
0
    break;
1402
0
  }
1403
0
    }
1404
1405
0
  return true;
1406
0
}
1407
1408
/* This must exist if dynobj is ever set.  */
1409
1410
static bool
1411
rl78_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
1412
          struct bfd_link_info *info,
1413
          bfd_byte *buf ATTRIBUTE_UNUSED)
1414
0
{
1415
0
  bfd *dynobj;
1416
0
  asection *splt;
1417
1418
0
  if (!elf_hash_table (info)->dynamic_sections_created)
1419
0
    return true;
1420
1421
  /* As an extra sanity check, verify that all plt entries have been
1422
     filled in.  However, relaxing might have changed the relocs so
1423
     that some plt entries don't get filled in, so we have to skip
1424
     this check if we're relaxing.  Unfortunately, check_relocs is
1425
     called before relaxation.  */
1426
1427
0
  if (info->relax_trip > 0)
1428
0
    return true;
1429
1430
0
  dynobj = elf_hash_table (info)->dynobj;
1431
0
  splt = elf_hash_table (info)->splt;
1432
0
  if (dynobj != NULL && splt != NULL)
1433
0
    {
1434
0
      bfd_byte *contents = splt->contents;
1435
0
      unsigned int i, size = splt->size;
1436
1437
0
      for (i = 0; i < size; i += 4)
1438
0
  {
1439
0
    unsigned int x = bfd_get_32 (dynobj, contents + i);
1440
0
    BFD_ASSERT (x != 0);
1441
0
  }
1442
0
    }
1443
1444
0
  return true;
1445
0
}
1446
1447
static bool
1448
rl78_elf_early_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
1449
            struct bfd_link_info *info)
1450
0
{
1451
0
  bfd *dynobj;
1452
0
  asection *splt;
1453
1454
0
  if (bfd_link_relocatable (info))
1455
0
    return true;
1456
1457
0
  dynobj = elf_hash_table (info)->dynobj;
1458
0
  if (dynobj == NULL)
1459
0
    return true;
1460
1461
0
  splt = elf_hash_table (info)->splt;
1462
0
  BFD_ASSERT (splt != NULL);
1463
1464
0
  splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
1465
0
  if (splt->contents == NULL)
1466
0
    return false;
1467
0
  splt->alloced = 1;
1468
1469
0
  return true;
1470
0
}
1471
1472

1473
1474
/* Handle relaxing.  */
1475
1476
/* A subroutine of rl78_elf_relax_section.  If the global symbol H
1477
   is within the low 64k, remove any entry for it in the plt.  */
1478
1479
struct relax_plt_data
1480
{
1481
  asection *splt;
1482
  bool *again;
1483
};
1484
1485
static bool
1486
rl78_relax_plt_check (struct elf_link_hash_entry *h, void * xdata)
1487
0
{
1488
0
  struct relax_plt_data *data = (struct relax_plt_data *) xdata;
1489
1490
0
  if (h->plt.offset != (bfd_vma) -1)
1491
0
    {
1492
0
      bfd_vma address;
1493
1494
0
      if (h->root.type == bfd_link_hash_undefined
1495
0
    || h->root.type == bfd_link_hash_undefweak)
1496
0
  address = 0;
1497
0
      else
1498
0
  address = (h->root.u.def.section->output_section->vma
1499
0
       + h->root.u.def.section->output_offset
1500
0
       + h->root.u.def.value);
1501
1502
0
      if (valid_16bit_address (address))
1503
0
  {
1504
0
    h->plt.offset = -1;
1505
0
    data->splt->size -= 4;
1506
0
    *data->again = true;
1507
0
  }
1508
0
    }
1509
1510
0
  return true;
1511
0
}
1512
1513
/* A subroutine of rl78_elf_relax_section.  If the global symbol H
1514
   previously had a plt entry, give it a new entry offset.  */
1515
1516
static bool
1517
rl78_relax_plt_realloc (struct elf_link_hash_entry *h, void * xdata)
1518
0
{
1519
0
  bfd_vma *entry = (bfd_vma *) xdata;
1520
1521
0
  if (h->plt.offset != (bfd_vma) -1)
1522
0
    {
1523
0
      h->plt.offset = *entry;
1524
0
      *entry += 4;
1525
0
    }
1526
1527
0
  return true;
1528
0
}
1529
1530
static bool
1531
rl78_elf_relax_plt_section (bfd *dynobj,
1532
          asection *splt,
1533
          struct bfd_link_info *info,
1534
          bool *again)
1535
0
{
1536
0
  struct relax_plt_data relax_plt_data;
1537
0
  bfd *ibfd;
1538
1539
  /* Assume nothing changes.  */
1540
0
  *again = false;
1541
1542
0
  if (bfd_link_relocatable (info))
1543
0
    return true;
1544
1545
  /* We only relax the .plt section at the moment.  */
1546
0
  if (dynobj != elf_hash_table (info)->dynobj
1547
0
      || strcmp (splt->name, ".plt") != 0)
1548
0
    return true;
1549
1550
  /* Quick check for an empty plt.  */
1551
0
  if (splt->size == 0)
1552
0
    return true;
1553
1554
  /* Map across all global symbols; see which ones happen to
1555
     fall in the low 64k.  */
1556
0
  relax_plt_data.splt = splt;
1557
0
  relax_plt_data.again = again;
1558
0
  elf_link_hash_traverse (elf_hash_table (info), rl78_relax_plt_check,
1559
0
        &relax_plt_data);
1560
1561
  /* Likewise for local symbols, though that's somewhat less convenient
1562
     as we have to walk the list of input bfds and swap in symbol data.  */
1563
0
  for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
1564
0
    {
1565
0
      bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1566
0
      Elf_Internal_Shdr *symtab_hdr;
1567
0
      Elf_Internal_Sym *isymbuf = NULL;
1568
0
      unsigned int idx;
1569
1570
0
      if (! local_plt_offsets)
1571
0
  continue;
1572
1573
0
      symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
1574
0
      if (symtab_hdr->sh_info != 0)
1575
0
  {
1576
0
    isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1577
0
    if (isymbuf == NULL)
1578
0
      isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
1579
0
              symtab_hdr->sh_info, 0,
1580
0
              NULL, NULL, NULL);
1581
0
    if (isymbuf == NULL)
1582
0
      return false;
1583
0
  }
1584
1585
0
      for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
1586
0
  {
1587
0
    Elf_Internal_Sym *isym;
1588
0
    asection *tsec;
1589
0
    bfd_vma address;
1590
1591
0
    if (local_plt_offsets[idx] == (bfd_vma) -1)
1592
0
      continue;
1593
1594
0
    isym = &isymbuf[idx];
1595
0
    if (isym->st_shndx == SHN_UNDEF)
1596
0
      continue;
1597
0
    else if (isym->st_shndx == SHN_ABS)
1598
0
      tsec = bfd_abs_section_ptr;
1599
0
    else if (isym->st_shndx == SHN_COMMON)
1600
0
      tsec = bfd_com_section_ptr;
1601
0
    else
1602
0
      tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
1603
1604
0
    address = (tsec->output_section->vma
1605
0
         + tsec->output_offset
1606
0
         + isym->st_value);
1607
0
    if (valid_16bit_address (address))
1608
0
      {
1609
0
        local_plt_offsets[idx] = -1;
1610
0
        splt->size -= 4;
1611
0
        *again = true;
1612
0
      }
1613
0
  }
1614
1615
0
      if (isymbuf != NULL
1616
0
    && symtab_hdr->contents != (unsigned char *) isymbuf)
1617
0
  {
1618
0
    if (! info->keep_memory)
1619
0
      free (isymbuf);
1620
0
    else
1621
0
      {
1622
        /* Cache the symbols for elf_link_input_bfd.  */
1623
0
        symtab_hdr->contents = (unsigned char *) isymbuf;
1624
0
      }
1625
0
  }
1626
0
    }
1627
1628
  /* If we changed anything, walk the symbols again to reallocate
1629
     .plt entry addresses.  */
1630
0
  if (*again && splt->size > 0)
1631
0
    {
1632
0
      bfd_vma entry = 0;
1633
1634
0
      elf_link_hash_traverse (elf_hash_table (info),
1635
0
            rl78_relax_plt_realloc, &entry);
1636
1637
0
      for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
1638
0
  {
1639
0
    bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1640
0
    unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
1641
0
    unsigned int idx;
1642
1643
0
    if (! local_plt_offsets)
1644
0
      continue;
1645
1646
0
    for (idx = 0; idx < nlocals; ++idx)
1647
0
      if (local_plt_offsets[idx] != (bfd_vma) -1)
1648
0
        {
1649
0
    local_plt_offsets[idx] = entry;
1650
0
    entry += 4;
1651
0
        }
1652
0
  }
1653
0
    }
1654
1655
0
  return true;
1656
0
}
1657
1658
/* Delete some bytes from a section while relaxing.  */
1659
1660
static bool
1661
elf32_rl78_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count,
1662
             Elf_Internal_Rela *alignment_rel, int force_snip)
1663
0
{
1664
0
  Elf_Internal_Shdr * symtab_hdr;
1665
0
  unsigned int        sec_shndx;
1666
0
  bfd_byte *        contents;
1667
0
  Elf_Internal_Rela * irel;
1668
0
  Elf_Internal_Rela * irelend;
1669
0
  Elf_Internal_Sym *  isym;
1670
0
  Elf_Internal_Sym *  isymend;
1671
0
  bfd_vma       toaddr;
1672
0
  unsigned int        symcount;
1673
0
  struct elf_link_hash_entry ** sym_hashes;
1674
0
  struct elf_link_hash_entry ** end_hashes;
1675
1676
0
  if (!alignment_rel)
1677
0
    force_snip = 1;
1678
1679
0
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1680
1681
0
  contents = elf_section_data (sec)->this_hdr.contents;
1682
1683
  /* The deletion must stop at the next alignment boundary, if
1684
     ALIGNMENT_REL is non-NULL.  */
1685
0
  toaddr = sec->size;
1686
0
  if (alignment_rel)
1687
0
    toaddr = alignment_rel->r_offset;
1688
1689
0
  irel = elf_section_data (sec)->relocs;
1690
0
  if (irel == NULL)
1691
0
    {
1692
0
      _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL, true);
1693
0
      irel = elf_section_data (sec)->relocs;
1694
0
    }
1695
1696
0
  irelend = irel + sec->reloc_count;
1697
1698
  /* Actually delete the bytes.  */
1699
0
  memmove (contents + addr, contents + addr + count,
1700
0
     (size_t) (toaddr - addr - count));
1701
1702
  /* If we don't have an alignment marker to worry about, we can just
1703
     shrink the section.  Otherwise, we have to fill in the newly
1704
     created gap with NOP insns (0x03).  */
1705
0
  if (force_snip)
1706
0
    sec->size -= count;
1707
0
  else
1708
0
    memset (contents + toaddr - count, 0x03, count);
1709
1710
  /* Adjust all the relocs.  */
1711
0
  for (; irel && irel < irelend; irel++)
1712
0
    {
1713
      /* Get the new reloc address.  */
1714
0
      if (irel->r_offset > addr
1715
0
    && (irel->r_offset < toaddr
1716
0
        || (force_snip && irel->r_offset == toaddr)))
1717
0
  irel->r_offset -= count;
1718
1719
      /* If we see an ALIGN marker at the end of the gap, we move it
1720
   to the beginning of the gap, since marking these gaps is what
1721
   they're for.  */
1722
0
      if (irel->r_offset == toaddr
1723
0
    && ELF32_R_TYPE (irel->r_info) == R_RL78_RH_RELAX
1724
0
    && irel->r_addend & RL78_RELAXA_ALIGN)
1725
0
  irel->r_offset -= count;
1726
0
    }
1727
1728
  /* Adjust the local symbols defined in this section.  */
1729
0
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1730
0
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1731
0
  isymend = isym + symtab_hdr->sh_info;
1732
1733
0
  for (; isym < isymend; isym++)
1734
0
    {
1735
      /* If the symbol is in the range of memory we just moved, we
1736
   have to adjust its value.  */
1737
0
      if (isym->st_shndx == sec_shndx
1738
0
    && isym->st_value > addr
1739
0
    && isym->st_value < toaddr)
1740
0
  isym->st_value -= count;
1741
1742
      /* If the symbol *spans* the bytes we just deleted (i.e. it's
1743
   *end* is in the moved bytes but it's *start* isn't), then we
1744
   must adjust its size.  */
1745
0
      if (isym->st_shndx == sec_shndx
1746
0
    && isym->st_value < addr
1747
0
    && isym->st_value + isym->st_size > addr
1748
0
    && isym->st_value + isym->st_size < toaddr)
1749
0
  isym->st_size -= count;
1750
0
    }
1751
1752
  /* Now adjust the global symbols defined in this section.  */
1753
0
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1754
0
        - symtab_hdr->sh_info);
1755
0
  sym_hashes = elf_sym_hashes (abfd);
1756
0
  end_hashes = sym_hashes + symcount;
1757
1758
0
  for (; sym_hashes < end_hashes; sym_hashes++)
1759
0
    {
1760
0
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
1761
1762
0
      if ((sym_hash->root.type == bfd_link_hash_defined
1763
0
     || sym_hash->root.type == bfd_link_hash_defweak)
1764
0
    && sym_hash->root.u.def.section == sec)
1765
0
  {
1766
    /* As above, adjust the value if needed.  */
1767
0
    if (sym_hash->root.u.def.value > addr
1768
0
        && sym_hash->root.u.def.value < toaddr)
1769
0
      sym_hash->root.u.def.value -= count;
1770
1771
    /* As above, adjust the size if needed.  */
1772
0
    if (sym_hash->root.u.def.value < addr
1773
0
        && sym_hash->root.u.def.value + sym_hash->size > addr
1774
0
        && sym_hash->root.u.def.value + sym_hash->size < toaddr)
1775
0
      sym_hash->size -= count;
1776
0
  }
1777
0
    }
1778
1779
0
  return true;
1780
0
}
1781
1782
/* Used to sort relocs by address.  If relocs have the same address,
1783
   we maintain their relative order, except that R_RL78_RH_RELAX
1784
   alignment relocs must be the first reloc for any given address.  */
1785
1786
static void
1787
reloc_bubblesort (Elf_Internal_Rela * r, int count)
1788
0
{
1789
0
  int i;
1790
0
  bool again;
1791
0
  bool swappit;
1792
1793
  /* This is almost a classic bubblesort.  It's the slowest sort, but
1794
     we're taking advantage of the fact that the relocations are
1795
     mostly in order already (the assembler emits them that way) and
1796
     we need relocs with the same address to remain in the same
1797
     relative order.  */
1798
0
  again = true;
1799
0
  while (again)
1800
0
    {
1801
0
      again = false;
1802
0
      for (i = 0; i < count - 1; i ++)
1803
0
  {
1804
0
    if (r[i].r_offset > r[i + 1].r_offset)
1805
0
      swappit = true;
1806
0
    else if (r[i].r_offset < r[i + 1].r_offset)
1807
0
      swappit = false;
1808
0
    else if (ELF32_R_TYPE (r[i + 1].r_info) == R_RL78_RH_RELAX
1809
0
       && (r[i + 1].r_addend & RL78_RELAXA_ALIGN))
1810
0
      swappit = true;
1811
0
    else if (ELF32_R_TYPE (r[i + 1].r_info) == R_RL78_RH_RELAX
1812
0
       && (r[i + 1].r_addend & RL78_RELAXA_ELIGN)
1813
0
       && !(ELF32_R_TYPE (r[i].r_info) == R_RL78_RH_RELAX
1814
0
      && (r[i].r_addend & RL78_RELAXA_ALIGN)))
1815
0
      swappit = true;
1816
0
    else
1817
0
      swappit = false;
1818
1819
0
    if (swappit)
1820
0
      {
1821
0
        Elf_Internal_Rela tmp;
1822
1823
0
        tmp = r[i];
1824
0
        r[i] = r[i + 1];
1825
0
        r[i + 1] = tmp;
1826
        /* If we do move a reloc back, re-scan to see if it
1827
     needs to be moved even further back.  This avoids
1828
     most of the O(n^2) behavior for our cases.  */
1829
0
        if (i > 0)
1830
0
    i -= 2;
1831
0
        again = true;
1832
0
      }
1833
0
  }
1834
0
    }
1835
0
}
1836
1837
1838
#define OFFSET_FOR_RELOC(rel, lrel, scale) \
1839
0
  rl78_offset_for_reloc (abfd, rel + 1, symtab_hdr, shndx_buf, intsyms, \
1840
0
       lrel, abfd, sec, link_info, scale)
1841
1842
static bfd_vma
1843
rl78_offset_for_reloc (bfd *      abfd,
1844
           Elf_Internal_Rela *  rel,
1845
           Elf_Internal_Shdr *  symtab_hdr,
1846
           bfd_byte *   shndx_buf ATTRIBUTE_UNUSED,
1847
           Elf_Internal_Sym * intsyms,
1848
           Elf_Internal_Rela ** lrel,
1849
           bfd *      input_bfd,
1850
           asection *   input_section,
1851
           struct bfd_link_info * info,
1852
           int *      scale)
1853
0
{
1854
0
  bfd_vma symval;
1855
1856
0
  *scale = 1;
1857
1858
  /* REL is the first of 1..N relocations.  We compute the symbol
1859
     value for each relocation, then combine them if needed.  LREL
1860
     gets a pointer to the last relocation used.  */
1861
0
  while (1)
1862
0
    {
1863
0
      unsigned long r_type;
1864
1865
      /* Get the value of the symbol referred to by the reloc.  */
1866
0
      if (ELF32_R_SYM (rel->r_info) < symtab_hdr->sh_info)
1867
0
  {
1868
    /* A local symbol.  */
1869
0
    Elf_Internal_Sym *isym;
1870
0
    asection *ssec;
1871
1872
0
    isym = intsyms + ELF32_R_SYM (rel->r_info);
1873
1874
0
    if (isym->st_shndx == SHN_UNDEF)
1875
0
      ssec = bfd_und_section_ptr;
1876
0
    else if (isym->st_shndx == SHN_ABS)
1877
0
      ssec = bfd_abs_section_ptr;
1878
0
    else if (isym->st_shndx == SHN_COMMON)
1879
0
      ssec = bfd_com_section_ptr;
1880
0
    else
1881
0
      ssec = bfd_section_from_elf_index (abfd,
1882
0
                 isym->st_shndx);
1883
1884
    /* Initial symbol value.  */
1885
0
    symval = isym->st_value;
1886
1887
    /* GAS may have made this symbol relative to a section, in
1888
       which case, we have to add the addend to find the
1889
       symbol.  */
1890
0
    if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
1891
0
      symval += rel->r_addend;
1892
1893
0
    if (ssec)
1894
0
      {
1895
0
        if ((ssec->flags & SEC_MERGE)
1896
0
      && ssec->sec_info_type == SEC_INFO_TYPE_MERGE)
1897
0
    symval = _bfd_merged_section_offset (abfd, & ssec, symval);
1898
0
      }
1899
1900
    /* Now make the offset relative to where the linker is putting it.  */
1901
0
    if (ssec)
1902
0
      symval +=
1903
0
        ssec->output_section->vma + ssec->output_offset;
1904
1905
0
    symval += rel->r_addend;
1906
0
  }
1907
0
      else
1908
0
  {
1909
0
    unsigned long indx;
1910
0
    struct elf_link_hash_entry * h;
1911
1912
    /* An external symbol.  */
1913
0
    indx = ELF32_R_SYM (rel->r_info) - symtab_hdr->sh_info;
1914
0
    h = elf_sym_hashes (abfd)[indx];
1915
0
    BFD_ASSERT (h != NULL);
1916
1917
0
    if (h->root.type != bfd_link_hash_defined
1918
0
        && h->root.type != bfd_link_hash_defweak)
1919
0
      {
1920
        /* This appears to be a reference to an undefined
1921
     symbol.  Just ignore it--it will be caught by the
1922
     regular reloc processing.  */
1923
0
        if (lrel)
1924
0
    *lrel = rel;
1925
0
        return 0;
1926
0
      }
1927
1928
0
    symval = (h->root.u.def.value
1929
0
        + h->root.u.def.section->output_section->vma
1930
0
        + h->root.u.def.section->output_offset);
1931
1932
0
    symval += rel->r_addend;
1933
0
  }
1934
1935
0
      r_type = ELF32_R_TYPE (rel->r_info);
1936
0
      switch (r_type)
1937
0
  {
1938
0
  case R_RL78_SYM:
1939
0
    (void) rl78_compute_complex_reloc (r_type, symval, input_section,
1940
0
               NULL, NULL);
1941
0
    break;
1942
1943
0
  case R_RL78_OPromtop:
1944
0
    symval = get_romstart (info, input_bfd, input_section, rel->r_offset);
1945
0
    (void) rl78_compute_complex_reloc (r_type, symval, input_section,
1946
0
               NULL, NULL);
1947
0
    break;
1948
1949
0
  case R_RL78_OPramtop:
1950
0
    symval = get_ramstart (info, input_bfd, input_section, rel->r_offset);
1951
0
    (void) rl78_compute_complex_reloc (r_type, symval, input_section,
1952
0
               NULL, NULL);
1953
0
    break;
1954
1955
0
  case R_RL78_OPneg:
1956
0
  case R_RL78_OPadd:
1957
0
  case R_RL78_OPsub:
1958
0
  case R_RL78_OPmul:
1959
0
  case R_RL78_OPdiv:
1960
0
  case R_RL78_OPshla:
1961
0
  case R_RL78_OPshra:
1962
0
  case R_RL78_OPsctsize:
1963
0
  case R_RL78_OPscttop:
1964
0
  case R_RL78_OPand:
1965
0
  case R_RL78_OPor:
1966
0
  case R_RL78_OPxor:
1967
0
  case R_RL78_OPnot:
1968
0
  case R_RL78_OPmod:
1969
0
    (void) rl78_compute_complex_reloc (r_type, 0, input_section,
1970
0
               NULL, NULL);
1971
0
    break;
1972
1973
0
  case R_RL78_DIR16UL:
1974
0
  case R_RL78_DIR8UL:
1975
0
  case R_RL78_ABS16UL:
1976
0
  case R_RL78_ABS8UL:
1977
0
    *scale = 4;
1978
0
    goto reloc_computes_value;
1979
1980
0
  case R_RL78_DIR16UW:
1981
0
  case R_RL78_DIR8UW:
1982
0
  case R_RL78_ABS16UW:
1983
0
  case R_RL78_ABS8UW:
1984
0
    *scale = 2;
1985
0
    goto reloc_computes_value;
1986
1987
0
  default:
1988
0
  reloc_computes_value:
1989
0
    symval = rl78_compute_complex_reloc (r_type, symval, input_section,
1990
0
                 NULL, NULL);
1991
    /* Fall through.  */
1992
0
  case R_RL78_DIR32:
1993
0
  case R_RL78_DIR24S:
1994
0
  case R_RL78_DIR16:
1995
0
  case R_RL78_DIR16U:
1996
0
  case R_RL78_DIR16S:
1997
0
  case R_RL78_DIR24S_PCREL:
1998
0
  case R_RL78_DIR16S_PCREL:
1999
0
  case R_RL78_DIR8S_PCREL:
2000
0
    if (lrel)
2001
0
      *lrel = rel;
2002
0
    return symval;
2003
0
  }
2004
2005
0
      rel ++;
2006
0
    }
2007
0
}
2008
2009
const struct {
2010
  int prefix;   /* or -1 for "no prefix" */
2011
  int insn;   /* or -1 for "end of list" */
2012
  int insn_for_saddr; /* or -1 for "no alternative" */
2013
  int insn_for_sfr; /* or -1 for "no alternative" */
2014
} relax_addr16[] = {
2015
  { -1, 0x02, 0x06, -1 }, /* ADDW AX, !addr16 */
2016
  { -1, 0x22, 0x26, -1 }, /* SUBW AX, !addr16 */
2017
  { -1, 0x42, 0x46, -1 }, /* CMPW AX, !addr16 */
2018
  { -1, 0x40, 0x4a, -1 }, /* CMP  !addr16, #byte */
2019
2020
  { -1, 0x0f, 0x0b, -1 }, /* ADD  A, !addr16 */
2021
  { -1, 0x1f, 0x1b, -1 }, /* ADDC A, !addr16 */
2022
  { -1, 0x2f, 0x2b, -1 }, /* SUB  A, !addr16 */
2023
  { -1, 0x3f, 0x3b, -1 }, /* SUBC A, !addr16 */
2024
  { -1, 0x4f, 0x4b, -1 }, /* CMP  A, !addr16 */
2025
  { -1, 0x5f, 0x5b, -1 }, /* AND  A, !addr16 */
2026
  { -1, 0x6f, 0x6b, -1 }, /* OR A, !addr16 */
2027
  { -1, 0x7f, 0x7b, -1 }, /* XOR  A, !addr16 */
2028
2029
  { -1, 0x8f, 0x8d, 0x8e }, /* MOV  A, !addr16 */
2030
  { -1, 0x9f, 0x9d, 0x9e }, /* MOV  !addr16, A */
2031
  { -1, 0xaf, 0xad, 0xae }, /* MOVW AX, !addr16 */
2032
  { -1, 0xbf, 0xbd, 0xbe }, /* MOVW !addr16, AX */
2033
  { -1, 0xcf, 0xcd, 0xce }, /* MOVW !addr16, #word */
2034
2035
  { -1, 0xa0, 0xa4, -1 }, /* INC  !addr16 */
2036
  { -1, 0xa2, 0xa6, -1 }, /* INCW !addr16 */
2037
  { -1, 0xb0, 0xb4, -1 }, /* DEC  !addr16 */
2038
  { -1, 0xb2, 0xb6, -1 }, /* DECW !addr16 */
2039
2040
  { -1, 0xd5, 0xd4, -1 }, /* CMP0 !addr16 */
2041
  { -1, 0xe5, 0xe4, -1 }, /* ONEB !addr16 */
2042
  { -1, 0xf5, 0xf4, -1 }, /* CLRB !addr16 */
2043
2044
  { -1, 0xd9, 0xd8, -1 }, /* MOV  X, !addr16 */
2045
  { -1, 0xe9, 0xe8, -1 }, /* MOV  B, !addr16 */
2046
  { -1, 0xf9, 0xf8, -1 }, /* MOV  C, !addr16 */
2047
  { -1, 0xdb, 0xda, -1 }, /* MOVW BC, !addr16 */
2048
  { -1, 0xeb, 0xea, -1 }, /* MOVW DE, !addr16 */
2049
  { -1, 0xfb, 0xfa, -1 }, /* MOVW HL, !addr16 */
2050
2051
  { 0x61, 0xaa, 0xa8, -1 }, /* XCH  A, !addr16 */
2052
2053
  { 0x71, 0x00, 0x02, 0x0a }, /* SET1 !addr16.0 */
2054
  { 0x71, 0x10, 0x12, 0x1a }, /* SET1 !addr16.0 */
2055
  { 0x71, 0x20, 0x22, 0x2a }, /* SET1 !addr16.0 */
2056
  { 0x71, 0x30, 0x32, 0x3a }, /* SET1 !addr16.0 */
2057
  { 0x71, 0x40, 0x42, 0x4a }, /* SET1 !addr16.0 */
2058
  { 0x71, 0x50, 0x52, 0x5a }, /* SET1 !addr16.0 */
2059
  { 0x71, 0x60, 0x62, 0x6a }, /* SET1 !addr16.0 */
2060
  { 0x71, 0x70, 0x72, 0x7a }, /* SET1 !addr16.0 */
2061
2062
  { 0x71, 0x08, 0x03, 0x0b }, /* CLR1 !addr16.0 */
2063
  { 0x71, 0x18, 0x13, 0x1b }, /* CLR1 !addr16.0 */
2064
  { 0x71, 0x28, 0x23, 0x2b }, /* CLR1 !addr16.0 */
2065
  { 0x71, 0x38, 0x33, 0x3b }, /* CLR1 !addr16.0 */
2066
  { 0x71, 0x48, 0x43, 0x4b }, /* CLR1 !addr16.0 */
2067
  { 0x71, 0x58, 0x53, 0x5b }, /* CLR1 !addr16.0 */
2068
  { 0x71, 0x68, 0x63, 0x6b }, /* CLR1 !addr16.0 */
2069
  { 0x71, 0x78, 0x73, 0x7b }, /* CLR1 !addr16.0 */
2070
2071
  { -1, -1, -1, -1 }
2072
};
2073
2074
/* Relax one section.  */
2075
2076
static bool
2077
rl78_elf_relax_section (bfd *abfd,
2078
      asection *sec,
2079
      struct bfd_link_info *link_info,
2080
      bool *again)
2081
0
{
2082
0
  Elf_Internal_Shdr * symtab_hdr;
2083
0
  Elf_Internal_Shdr * shndx_hdr;
2084
0
  Elf_Internal_Rela * internal_relocs;
2085
0
  Elf_Internal_Rela * free_relocs = NULL;
2086
0
  Elf_Internal_Rela * irel;
2087
0
  Elf_Internal_Rela * srel;
2088
0
  Elf_Internal_Rela * irelend;
2089
0
  Elf_Internal_Rela * next_alignment;
2090
0
  bfd_byte *        contents = NULL;
2091
0
  bfd_byte *        free_contents = NULL;
2092
0
  Elf_Internal_Sym *  intsyms = NULL;
2093
0
  Elf_Internal_Sym *  free_intsyms = NULL;
2094
0
  bfd_byte *        shndx_buf = NULL;
2095
0
  bfd_vma pc;
2096
0
  bfd_vma symval ATTRIBUTE_UNUSED = 0;
2097
0
  int pcrel ATTRIBUTE_UNUSED = 0;
2098
0
  int code ATTRIBUTE_UNUSED = 0;
2099
0
  int section_alignment_glue;
2100
0
  int scale;
2101
2102
0
  if (abfd == elf_hash_table (link_info)->dynobj
2103
0
      && strcmp (sec->name, ".plt") == 0)
2104
0
    return rl78_elf_relax_plt_section (abfd, sec, link_info, again);
2105
2106
  /* Assume nothing changes.  */
2107
0
  *again = false;
2108
2109
  /* We don't have to do anything for a relocatable link, if
2110
     this section does not have relocs, or if this is not a
2111
     code section.  */
2112
0
  if (bfd_link_relocatable (link_info)
2113
0
      || sec->reloc_count == 0
2114
0
      || (sec->flags & SEC_RELOC) == 0
2115
0
      || (sec->flags & SEC_HAS_CONTENTS) == 0
2116
0
      || (sec->flags & SEC_CODE) == 0)
2117
0
    return true;
2118
2119
0
  symtab_hdr = & elf_symtab_hdr (abfd);
2120
0
  if (elf_symtab_shndx_list (abfd))
2121
0
    shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
2122
0
  else
2123
0
    shndx_hdr = NULL;
2124
2125
  /* Get the section contents.  */
2126
0
  if (elf_section_data (sec)->this_hdr.contents != NULL)
2127
0
    contents = elf_section_data (sec)->this_hdr.contents;
2128
  /* Go get them off disk.  */
2129
0
  else
2130
0
    {
2131
0
      if (! bfd_malloc_and_get_section (abfd, sec, &contents))
2132
0
  goto error_return;
2133
0
      elf_section_data (sec)->this_hdr.contents = contents;
2134
0
    }
2135
2136
  /* Read this BFD's symbols.  */
2137
  /* Get cached copy if it exists.  */
2138
0
  if (symtab_hdr->contents != NULL)
2139
0
    intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
2140
0
  else
2141
0
    {
2142
0
      intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL, NULL);
2143
0
      symtab_hdr->contents = (bfd_byte *) intsyms;
2144
0
    }
2145
2146
0
  if (shndx_hdr && shndx_hdr->sh_size != 0)
2147
0
    {
2148
0
      size_t amt;
2149
2150
0
      if (_bfd_mul_overflow (symtab_hdr->sh_info,
2151
0
           sizeof (Elf_External_Sym_Shndx), &amt))
2152
0
  {
2153
0
    bfd_set_error (bfd_error_no_memory);
2154
0
    goto error_return;
2155
0
  }
2156
0
      if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0)
2157
0
  goto error_return;
2158
0
      shndx_buf = _bfd_malloc_and_read (abfd, amt, amt);
2159
0
      if (shndx_buf == NULL)
2160
0
  goto error_return;
2161
0
      shndx_hdr->contents = shndx_buf;
2162
0
    }
2163
2164
  /* Get a copy of the native relocations.  */
2165
0
  internal_relocs = (_bfd_elf_link_read_relocs
2166
0
         (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
2167
0
          link_info->keep_memory));
2168
0
  if (internal_relocs == NULL)
2169
0
    goto error_return;
2170
0
  if (! link_info->keep_memory)
2171
0
    free_relocs = internal_relocs;
2172
2173
  /* The RL_ relocs must be just before the operand relocs they go
2174
     with, so we must sort them to guarantee this.  We use bubblesort
2175
     instead of qsort so we can guarantee that relocs with the same
2176
     address remain in the same relative order.  */
2177
0
  reloc_bubblesort (internal_relocs, sec->reloc_count);
2178
2179
  /* Walk through them looking for relaxing opportunities.  */
2180
0
  irelend = internal_relocs + sec->reloc_count;
2181
2182
2183
  /* This will either be NULL or a pointer to the next alignment
2184
     relocation.  */
2185
0
  next_alignment = internal_relocs;
2186
2187
  /* We calculate worst case shrinkage caused by alignment directives.
2188
     No fool-proof, but better than either ignoring the problem or
2189
     doing heavy duty analysis of all the alignment markers in all
2190
     input sections.  */
2191
0
  section_alignment_glue = 0;
2192
0
  for (irel = internal_relocs; irel < irelend; irel++)
2193
0
      if (ELF32_R_TYPE (irel->r_info) == R_RL78_RH_RELAX
2194
0
    && irel->r_addend & RL78_RELAXA_ALIGN)
2195
0
  {
2196
0
    int this_glue = 1 << (irel->r_addend & RL78_RELAXA_ANUM);
2197
2198
0
    if (section_alignment_glue < this_glue)
2199
0
      section_alignment_glue = this_glue;
2200
0
  }
2201
  /* Worst case is all 0..N alignments, in order, causing 2*N-1 byte
2202
     shrinkage.  */
2203
0
  section_alignment_glue *= 2;
2204
2205
0
  for (irel = internal_relocs; irel < irelend; irel++)
2206
0
    {
2207
0
      unsigned char *insn;
2208
0
      int nrelocs;
2209
2210
      /* The insns we care about are all marked with one of these.  */
2211
0
      if (ELF32_R_TYPE (irel->r_info) != R_RL78_RH_RELAX)
2212
0
  continue;
2213
2214
0
      if (irel->r_addend & RL78_RELAXA_ALIGN
2215
0
    || next_alignment == internal_relocs)
2216
0
  {
2217
    /* When we delete bytes, we need to maintain all the alignments
2218
       indicated.  In addition, we need to be careful about relaxing
2219
       jumps across alignment boundaries - these displacements
2220
       *grow* when we delete bytes.  For now, don't shrink
2221
       displacements across an alignment boundary, just in case.
2222
       Note that this only affects relocations to the same
2223
       section.  */
2224
0
    next_alignment += 2;
2225
0
    while (next_alignment < irelend
2226
0
     && (ELF32_R_TYPE (next_alignment->r_info) != R_RL78_RH_RELAX
2227
0
         || !(next_alignment->r_addend & RL78_RELAXA_ELIGN)))
2228
0
      next_alignment ++;
2229
0
    if (next_alignment >= irelend || next_alignment->r_offset == 0)
2230
0
      next_alignment = NULL;
2231
0
  }
2232
2233
      /* When we hit alignment markers, see if we've shrunk enough
2234
   before them to reduce the gap without violating the alignment
2235
   requirements.  */
2236
0
      if (irel->r_addend & RL78_RELAXA_ALIGN)
2237
0
  {
2238
    /* At this point, the next relocation *should* be the ELIGN
2239
       end marker.  */
2240
0
    Elf_Internal_Rela *erel = irel + 1;
2241
0
    unsigned int alignment, nbytes;
2242
2243
0
    if (ELF32_R_TYPE (erel->r_info) != R_RL78_RH_RELAX)
2244
0
      continue;
2245
0
    if (!(erel->r_addend & RL78_RELAXA_ELIGN))
2246
0
      continue;
2247
2248
0
    alignment = 1 << (irel->r_addend & RL78_RELAXA_ANUM);
2249
2250
0
    if (erel->r_offset - irel->r_offset < alignment)
2251
0
      continue;
2252
2253
0
    nbytes = erel->r_offset - irel->r_offset;
2254
0
    nbytes /= alignment;
2255
0
    nbytes *= alignment;
2256
2257
0
    elf32_rl78_relax_delete_bytes (abfd, sec, erel->r_offset - nbytes, nbytes,
2258
0
           next_alignment, erel->r_offset == sec->size);
2259
0
    *again = true;
2260
2261
0
    continue;
2262
0
  }
2263
2264
0
      if (irel->r_addend & RL78_RELAXA_ELIGN)
2265
0
    continue;
2266
2267
0
      insn = contents + irel->r_offset;
2268
2269
0
      nrelocs = irel->r_addend & RL78_RELAXA_RNUM;
2270
2271
      /* At this point, we have an insn that is a candidate for linker
2272
   relaxation.  There are NRELOCS relocs following that may be
2273
   relaxed, although each reloc may be made of more than one
2274
   reloc entry (such as gp-rel symbols).  */
2275
2276
      /* Get the value of the symbol referred to by the reloc.  Just
2277
   in case this is the last reloc in the list, use the RL's
2278
   addend to choose between this reloc (no addend) or the next
2279
   (yes addend, which means at least one following reloc).  */
2280
2281
      /* srel points to the "current" reloction for this insn -
2282
   actually the last reloc for a given operand, which is the one
2283
   we need to update.  We check the relaxations in the same
2284
   order that the relocations happen, so we'll just push it
2285
   along as we go.  */
2286
0
      srel = irel;
2287
2288
0
      pc = sec->output_section->vma + sec->output_offset
2289
0
  + srel->r_offset;
2290
2291
0
#define GET_RELOC         \
2292
0
      BFD_ASSERT (nrelocs > 0);       \
2293
0
      symval = OFFSET_FOR_RELOC (srel, &srel, &scale); \
2294
0
      pcrel = symval - pc + srel->r_addend;   \
2295
0
      nrelocs --;
2296
2297
0
#define SNIPNR(offset, nbytes) \
2298
0
  elf32_rl78_relax_delete_bytes (abfd, sec, (insn - contents) + offset, nbytes, next_alignment, 0);
2299
2300
0
#define SNIP(offset, nbytes, newtype)         \
2301
0
  SNIPNR (offset, nbytes);          \
2302
0
  srel->r_info = ELF32_R_INFO (ELF32_R_SYM (srel->r_info), newtype)
2303
2304
      /* The order of these bit tests must match the order that the
2305
   relocs appear in.  Since we sorted those by offset, we can
2306
   predict them.  */
2307
2308
      /*----------------------------------------------------------------------*/
2309
      /* EF ad    BR $rel8  pcrel
2310
   ED al ah BR !abs16 abs
2311
   EE al ah BR $!rel16  pcrel
2312
   EC al ah as  BR !!abs20  abs
2313
2314
   FD al ah CALL !abs16 abs
2315
   FE al ah CALL $!rel16  pcrel
2316
   FC al ah as  CALL !!abs20  abs
2317
2318
   DC ad    BC  $rel8
2319
   DE ad    BNC $rel8
2320
   DD ad    BZ  $rel8
2321
   DF ad    BNZ $rel8
2322
   61 C3 ad BH  $rel8
2323
   61 D3 ad BNH $rel8
2324
   61 C8 EF ad  SKC  ; BR $rel8
2325
   61 D8 EF ad  SKNC ; BR $rel8
2326
   61 E8 EF ad  SKZ  ; BR $rel8
2327
   61 F8 EF ad  SKNZ ; BR $rel8
2328
   61 E3 EF ad  SKH  ; BR $rel8
2329
   61 F3 EF ad  SKNH ; BR $rel8
2330
       */
2331
2332
0
      if ((irel->r_addend & RL78_RELAXA_MASK) == RL78_RELAXA_BRA)
2333
0
  {
2334
    /* SKIP opcodes that skip non-branches will have a relax tag
2335
       but no corresponding symbol to relax against; we just
2336
       skip those.  */
2337
0
    if (irel->r_addend & RL78_RELAXA_RNUM)
2338
0
      {
2339
0
        GET_RELOC;
2340
0
      }
2341
2342
0
    switch (insn[0])
2343
0
      {
2344
0
      case 0xdc: /* BC */
2345
0
      case 0xdd: /* BZ */
2346
0
      case 0xde: /* BNC */
2347
0
      case 0xdf: /* BNZ */
2348
0
        if (insn[1] == 0x03 && insn[2] == 0xee /* BR */
2349
0
      && (srel->r_offset - irel->r_offset) > 1) /* a B<c> without its own reloc */
2350
0
    {
2351
      /* This is a "long" conditional as generated by gas:
2352
         DC 03 EE ad.dr  */
2353
0
      if (pcrel < 127
2354
0
          && pcrel > -127)
2355
0
        {
2356
0
          insn[0] ^= 0x02; /* invert conditional */
2357
0
          SNIPNR (4, 1);
2358
0
          SNIP (1, 2, R_RL78_DIR8S_PCREL);
2359
0
          insn[1] = pcrel;
2360
0
          *again = true;
2361
0
        }
2362
0
    }
2363
0
        break;
2364
2365
0
      case 0xec: /* BR !!abs20 */
2366
2367
0
        if (pcrel < 127
2368
0
      && pcrel > -127)
2369
0
    {
2370
0
      insn[0] = 0xef;
2371
0
      insn[1] = pcrel;
2372
0
      SNIP (2, 2, R_RL78_DIR8S_PCREL);
2373
0
      *again = true;
2374
0
    }
2375
0
        else if (symval < 65536)
2376
0
    {
2377
0
      insn[0] = 0xed;
2378
0
      insn[1] = symval & 0xff;
2379
0
      insn[2] = symval >> 8;
2380
0
      SNIP (2, 1, R_RL78_DIR16U);
2381
0
      *again = true;
2382
0
    }
2383
0
        else if (pcrel < 32767
2384
0
           && pcrel > -32767)
2385
0
    {
2386
0
      insn[0] = 0xee;
2387
0
      insn[1] = pcrel & 0xff;
2388
0
      insn[2] = pcrel >> 8;
2389
0
      SNIP (2, 1, R_RL78_DIR16S_PCREL);
2390
0
      *again = true;
2391
0
    }
2392
0
        break;
2393
2394
0
      case 0xee: /* BR $!pcrel16 */
2395
0
      case 0xed: /* BR $!abs16 */
2396
0
        if (pcrel < 127
2397
0
      && pcrel > -127)
2398
0
    {
2399
0
      insn[0] = 0xef;
2400
0
      insn[1] = pcrel;
2401
0
      SNIP (2, 1, R_RL78_DIR8S_PCREL);
2402
0
      *again = true;
2403
0
    }
2404
0
        break;
2405
2406
0
      case 0xfc: /* CALL !!abs20 */
2407
0
        if (symval < 65536)
2408
0
    {
2409
0
      insn[0] = 0xfd;
2410
0
      insn[1] = symval & 0xff;
2411
0
      insn[2] = symval >> 8;
2412
0
      SNIP (2, 1, R_RL78_DIR16U);
2413
0
      *again = true;
2414
0
    }
2415
0
        else if (pcrel < 32767
2416
0
           && pcrel > -32767)
2417
0
    {
2418
0
      insn[0] = 0xfe;
2419
0
      insn[1] = pcrel & 0xff;
2420
0
      insn[2] = pcrel >> 8;
2421
0
      SNIP (2, 1, R_RL78_DIR16S_PCREL);
2422
0
      *again = true;
2423
0
    }
2424
0
        break;
2425
2426
0
      case 0x61: /* PREFIX */
2427
        /* For SKIP/BR, we change the BR opcode and delete the
2428
     SKIP.  That way, we don't have to find and change the
2429
     relocation for the BR.  */
2430
        /* Note that, for the case where we're skipping some
2431
     other insn, we have no "other" reloc but that's safe
2432
     here anyway. */
2433
0
        switch (insn[1])
2434
0
    {
2435
0
    case 0xd3: /* BNH */
2436
0
    case 0xc3: /* BH */
2437
0
      if (insn[2] == 0x03 && insn[3] == 0xee
2438
0
          && (srel->r_offset - irel->r_offset) > 2) /* a B<c> without its own reloc */
2439
0
        {
2440
          /* Another long branch by gas:
2441
       61 D3 03 EE ad.dr  */
2442
0
          if (pcrel < 127
2443
0
        && pcrel > -127)
2444
0
      {
2445
0
        insn[1] ^= 0x10; /* invert conditional */
2446
0
        SNIPNR (5, 1);
2447
0
        SNIP (2, 2, R_RL78_DIR8S_PCREL);
2448
0
        insn[2] = pcrel;
2449
0
        *again = true;
2450
0
      }
2451
0
        }
2452
0
      break;
2453
2454
0
    case 0xc8: /* SKC */
2455
0
      if (insn[2] == 0xef)
2456
0
        {
2457
0
          insn[2] = 0xde; /* BNC */
2458
0
          SNIPNR (0, 2);
2459
0
        }
2460
0
      break;
2461
2462
0
    case 0xd8: /* SKNC */
2463
0
      if (insn[2] == 0xef)
2464
0
        {
2465
0
          insn[2] = 0xdc; /* BC */
2466
0
          SNIPNR (0, 2);
2467
0
        }
2468
0
      break;
2469
2470
0
    case 0xe8: /* SKZ */
2471
0
      if (insn[2] == 0xef)
2472
0
        {
2473
0
          insn[2] = 0xdf; /* BNZ */
2474
0
          SNIPNR (0, 2);
2475
0
        }
2476
0
      break;
2477
2478
0
    case 0xf8: /* SKNZ */
2479
0
      if (insn[2] == 0xef)
2480
0
        {
2481
0
          insn[2] = 0xdd; /* BZ */
2482
0
          SNIPNR (0, 2);
2483
0
        }
2484
0
      break;
2485
2486
0
    case 0xe3: /* SKH */
2487
0
      if (insn[2] == 0xef)
2488
0
        {
2489
0
          insn[2] = 0xd3; /* BNH */
2490
0
          SNIPNR (1, 1); /* we reuse the 0x61 prefix from the SKH */
2491
0
        }
2492
0
      break;
2493
2494
0
    case 0xf3: /* SKNH */
2495
0
      if (insn[2] == 0xef)
2496
0
        {
2497
0
          insn[2] = 0xc3; /* BH */
2498
0
          SNIPNR (1, 1); /* we reuse the 0x61 prefix from the SKH */
2499
0
        }
2500
0
      break;
2501
0
    }
2502
0
        break;
2503
0
      }
2504
0
  }
2505
2506
0
      if ((irel->r_addend &  RL78_RELAXA_MASK) == RL78_RELAXA_ADDR16
2507
0
    && nrelocs > 0)
2508
0
  {
2509
    /*----------------------------------------------------------------------*/
2510
    /* Some insns have both a 16-bit address operand and an 8-bit
2511
       variant if the address is within a special range:
2512
2513
       Address    16-bit operand  SADDR range SFR range
2514
       FFF00-FFFFF  0xff00-0xffff 0x00-0xff
2515
       FFE20-FFF1F  0xfe20-0xff1f     0x00-0xff
2516
2517
       The RELAX_ADDR16[] array has the insn encodings for the
2518
       16-bit operand version, as well as the SFR and SADDR
2519
       variants.  We only need to replace the encodings and
2520
       adjust the operand.
2521
2522
       Note: we intentionally do not attempt to decode and skip
2523
       any ES: prefix, as adding ES: means the addr16 (likely)
2524
       no longer points to saddr/sfr space.
2525
    */
2526
2527
0
    int is_sfr;
2528
0
    int is_saddr;
2529
0
    int idx;
2530
0
    int poff;
2531
2532
0
    GET_RELOC;
2533
2534
0
    if (0xffe20 <= symval && symval <= 0xfffff)
2535
0
      {
2536
2537
0
        is_saddr = (0xffe20 <= symval && symval <= 0xfff1f);
2538
0
        is_sfr   = (0xfff00 <= symval && symval <= 0xfffff);
2539
2540
0
        for (idx = 0; relax_addr16[idx].insn != -1; idx ++)
2541
0
    {
2542
0
      if (relax_addr16[idx].prefix != -1
2543
0
          && insn[0] == relax_addr16[idx].prefix
2544
0
          && insn[1] == relax_addr16[idx].insn)
2545
0
        {
2546
0
          poff = 1;
2547
0
        }
2548
0
      else if (relax_addr16[idx].prefix == -1
2549
0
         && insn[0] == relax_addr16[idx].insn)
2550
0
        {
2551
0
          poff = 0;
2552
0
        }
2553
0
      else
2554
0
        continue;
2555
2556
      /* We have a matched insn, and poff is 0 or 1 depending
2557
         on the base pattern size.  */
2558
2559
0
      if (is_sfr && relax_addr16[idx].insn_for_sfr != -1)
2560
0
        {
2561
0
          insn[poff] = relax_addr16[idx].insn_for_sfr;
2562
0
          SNIP (poff+2, 1, R_RL78_RH_SFR);
2563
0
        }
2564
2565
0
      else if  (is_saddr && relax_addr16[idx].insn_for_saddr != -1)
2566
0
        {
2567
0
          insn[poff] = relax_addr16[idx].insn_for_saddr;
2568
0
          SNIP (poff+2, 1, R_RL78_RH_SADDR);
2569
0
        }
2570
0
    }
2571
0
      }
2572
0
  }
2573
      /*----------------------------------------------------------------------*/
2574
0
    }
2575
2576
0
  return true;
2577
2578
0
 error_return:
2579
0
  free (free_relocs);
2580
0
  free (free_contents);
2581
2582
0
  if (shndx_buf != NULL)
2583
0
    {
2584
0
      shndx_hdr->contents = NULL;
2585
0
      free (shndx_buf);
2586
0
    }
2587
2588
0
  free (free_intsyms);
2589
2590
  return true;
2591
0
}
2592
2593

2594
2595
#define ELF_ARCH    bfd_arch_rl78
2596
#define ELF_MACHINE_CODE  EM_RL78
2597
#define ELF_MAXPAGESIZE   0x1000
2598
2599
#define TARGET_LITTLE_SYM rl78_elf32_vec
2600
#define TARGET_LITTLE_NAME  "elf32-rl78"
2601
2602
#define elf_info_to_howto_rel     NULL
2603
#define elf_info_to_howto     rl78_info_to_howto_rela
2604
#define elf_backend_object_p      rl78_elf_object_p
2605
#define elf_backend_relocate_section    rl78_elf_relocate_section
2606
#define elf_symbol_leading_char     ('_')
2607
#define elf_backend_can_gc_sections   1
2608
2609
#define bfd_elf32_bfd_reloc_type_lookup   rl78_reloc_type_lookup
2610
#define bfd_elf32_bfd_reloc_name_lookup   rl78_reloc_name_lookup
2611
#define bfd_elf32_bfd_set_private_flags   rl78_elf_set_private_flags
2612
#define bfd_elf32_bfd_merge_private_bfd_data  rl78_elf_merge_private_bfd_data
2613
#define bfd_elf32_bfd_print_private_bfd_data  rl78_elf_print_private_bfd_data
2614
2615
#define bfd_elf32_bfd_relax_section   rl78_elf_relax_section
2616
#define elf_backend_check_relocs    rl78_elf_check_relocs
2617
#define elf_backend_early_size_sections \
2618
  rl78_elf_early_size_sections
2619
#define elf_backend_finish_dynamic_sections \
2620
  rl78_elf_finish_dynamic_sections
2621
2622
#include "elf32-target.h"