Coverage Report

Created: 2026-07-25 10:20

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