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-v850.c
Line
Count
Source
1
/* V850-specific support for 32-bit ELF
2
   Copyright (C) 1996-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
22
/* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char
23
   dependencies.  As is the gas & simulator code for the v850.  */
24
25
#include "sysdep.h"
26
#include "bfd.h"
27
#include "bfdlink.h"
28
#include "libbfd.h"
29
#include "elf-bfd.h"
30
#include "elf/v850.h"
31
#include "libiberty.h"
32
#include "elf32-v850.h"
33
34
/* Sign-extend a 17-bit number.  */
35
0
#define SEXT17(x) ((((x) & 0x1ffff) ^ 0x10000) - 0x10000)
36
37
/* Sign-extend a 22-bit number.  */
38
0
#define SEXT22(x) ((((x) & 0x3fffff) ^ 0x200000) - 0x200000)
39
40
static reloc_howto_type v850_elf_howto_table[];
41
42
/* Look through the relocs for a section during the first phase, and
43
   allocate space in the global offset table or procedure linkage
44
   table.  */
45
46
static bool
47
v850_elf_check_relocs (bfd *abfd,
48
           struct bfd_link_info *info,
49
           asection *sec,
50
           const Elf_Internal_Rela *relocs)
51
0
{
52
0
  bool ret = true;
53
0
  Elf_Internal_Shdr *symtab_hdr;
54
0
  struct elf_link_hash_entry **sym_hashes;
55
0
  const Elf_Internal_Rela *rel;
56
0
  const Elf_Internal_Rela *rel_end;
57
0
  unsigned int r_type;
58
0
  int other = 0;
59
0
  const char *common = NULL;
60
61
0
  if (bfd_link_relocatable (info))
62
0
    return true;
63
64
#ifdef DEBUG
65
  _bfd_error_handler ("v850_elf_check_relocs called for section %pA in %pB",
66
          sec, abfd);
67
#endif
68
69
0
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
70
0
  sym_hashes = elf_sym_hashes (abfd);
71
72
0
  rel_end = relocs + sec->reloc_count;
73
0
  for (rel = relocs; rel < rel_end; rel++)
74
0
    {
75
0
      unsigned long r_symndx;
76
0
      struct elf_link_hash_entry *h;
77
78
0
      r_symndx = ELF32_R_SYM (rel->r_info);
79
0
      if (r_symndx < symtab_hdr->sh_info)
80
0
  h = NULL;
81
0
      else
82
0
  {
83
0
    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
84
0
    while (h->root.type == bfd_link_hash_indirect
85
0
     || h->root.type == bfd_link_hash_warning)
86
0
      h = (struct elf_link_hash_entry *) h->root.u.i.link;
87
0
  }
88
89
0
      r_type = ELF32_R_TYPE (rel->r_info);
90
0
      switch (r_type)
91
0
  {
92
0
  default:
93
0
    break;
94
95
  /* This relocation describes the C++ object vtable hierarchy.
96
     Reconstruct it for later use during GC.  */
97
0
  case R_V850_GNU_VTINHERIT:
98
0
    if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
99
0
      return false;
100
0
    break;
101
102
  /* This relocation describes which C++ vtable entries
103
     are actually used.  Record for later use during GC.  */
104
0
  case R_V850_GNU_VTENTRY:
105
0
    if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
106
0
      return false;
107
0
    break;
108
109
0
  case R_V850_SDA_16_16_SPLIT_OFFSET:
110
0
  case R_V850_SDA_16_16_OFFSET:
111
0
  case R_V850_SDA_15_16_OFFSET:
112
0
  case R_V810_GPWLO_1:
113
0
  case R_V850_HWLO:
114
0
  case R_V850_HWLO_1:
115
0
    other = V850_OTHER_SDA;
116
0
    common = ".scommon";
117
0
    goto small_data_common;
118
119
0
  case R_V850_ZDA_16_16_SPLIT_OFFSET:
120
0
  case R_V850_ZDA_16_16_OFFSET:
121
0
  case R_V850_ZDA_15_16_OFFSET:
122
0
    other = V850_OTHER_ZDA;
123
0
    common = ".zcommon";
124
0
    goto small_data_common;
125
126
0
  case R_V850_TDA_4_4_OFFSET:
127
0
  case R_V850_TDA_4_5_OFFSET:
128
0
  case R_V850_TDA_7_7_OFFSET:
129
0
  case R_V850_TDA_6_8_OFFSET:
130
0
  case R_V850_TDA_7_8_OFFSET:
131
0
  case R_V850_TDA_16_16_OFFSET:
132
0
    other = V850_OTHER_TDA;
133
0
    common = ".tcommon";
134
    /* fall through */
135
136
0
#define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
137
138
0
  small_data_common:
139
0
    if (h)
140
0
      {
141
        /* Flag which type of relocation was used.  */
142
0
        h->other |= other;
143
0
        if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK)
144
0
      && (h->other & V850_OTHER_ERROR) == 0)
145
0
    {
146
0
      const char * msg;
147
0
      char *buff;
148
149
0
      switch (h->other & V850_OTHER_MASK)
150
0
        {
151
0
        default:
152
0
          msg = _("variable `%s' cannot occupy in multiple small data regions");
153
0
          break;
154
0
        case V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA:
155
0
          msg = _("variable `%s' can only be in one of the small, zero, and tiny data regions");
156
0
          break;
157
0
        case V850_OTHER_SDA | V850_OTHER_ZDA:
158
0
          msg = _("variable `%s' cannot be in both small and zero data regions simultaneously");
159
0
          break;
160
0
        case V850_OTHER_SDA | V850_OTHER_TDA:
161
0
          msg = _("variable `%s' cannot be in both small and tiny data regions simultaneously");
162
0
          break;
163
0
        case V850_OTHER_ZDA | V850_OTHER_TDA:
164
0
          msg = _("variable `%s' cannot be in both zero and tiny data regions simultaneously");
165
0
          break;
166
0
        }
167
168
0
      if (asprintf (&buff, msg, h->root.root.string) < 0)
169
0
        buff = NULL;
170
0
      else
171
0
        msg = buff;
172
0
      info->callbacks->warning (info, msg, h->root.root.string,
173
0
              abfd, h->root.u.def.section,
174
0
              (bfd_vma) 0);
175
0
      free (buff);
176
177
0
      bfd_set_error (bfd_error_bad_value);
178
0
      h->other |= V850_OTHER_ERROR;
179
0
      ret = false;
180
0
    }
181
0
      }
182
183
0
    if (h && h->root.type == bfd_link_hash_common
184
0
        && h->root.u.c.p
185
0
        && !strcmp (bfd_section_name (h->root.u.c.p->section), "COMMON"))
186
0
      {
187
0
        asection * section;
188
189
0
        section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
190
0
        section->flags |= SEC_IS_COMMON | SEC_SMALL_DATA;
191
0
      }
192
193
#ifdef DEBUG
194
    fprintf (stderr, "v850_elf_check_relocs, found %s relocation for %s%s\n",
195
       v850_elf_howto_table[ (int)r_type ].name,
196
       (h && h->root.root.string) ? h->root.root.string : "<unknown>",
197
       (h->root.type == bfd_link_hash_common) ? ", symbol is common" : "");
198
#endif
199
0
    break;
200
0
  }
201
0
    }
202
203
0
  return ret;
204
0
}
205
206
/* In the old version, when an entry was checked out from the table,
207
   it was deleted.  This produced an error if the entry was needed
208
   more than once, as the second attempted retry failed.
209
210
   In the current version, the entry is not deleted, instead we set
211
   the field 'found' to TRUE.  If a second lookup matches the same
212
   entry, then we know that the hi16s reloc has already been updated
213
   and does not need to be updated a second time.
214
215
   TODO - TOFIX: If it is possible that we need to restore 2 different
216
   addresses from the same table entry, where the first generates an
217
   overflow, whilst the second do not, then this code will fail.  */
218
219
typedef struct hi16s_location
220
{
221
  bfd_vma addend;
222
  bfd_byte *address;
223
  unsigned long counter;
224
  bool found;
225
  struct hi16s_location *next;
226
}
227
hi16s_location;
228
229
static hi16s_location * previous_hi16s;
230
static hi16s_location * free_hi16s;
231
static unsigned long    hi16s_counter;
232
233
static void
234
remember_hi16s_reloc (bfd *abfd, bfd_vma addend, bfd_byte *address)
235
0
{
236
0
  hi16s_location * entry = NULL;
237
0
  size_t amt = sizeof (* free_hi16s);
238
239
  /* Find a free structure.  */
240
0
  if (free_hi16s == NULL)
241
0
    free_hi16s = bfd_zalloc (abfd, amt);
242
243
0
  entry      = free_hi16s;
244
0
  free_hi16s = free_hi16s->next;
245
246
0
  entry->addend  = addend;
247
0
  entry->address = address;
248
0
  entry->counter = hi16s_counter ++;
249
0
  entry->found   = false;
250
0
  entry->next    = previous_hi16s;
251
0
  previous_hi16s = entry;
252
253
  /* Cope with wrap around of our counter.  */
254
0
  if (hi16s_counter == 0)
255
0
    {
256
      /* XXX: Assume that all counter entries differ only in their low 16 bits.  */
257
0
      for (entry = previous_hi16s; entry != NULL; entry = entry->next)
258
0
  entry->counter &= 0xffff;
259
260
0
      hi16s_counter = 0x10000;
261
0
    }
262
0
}
263
264
static bfd_byte *
265
find_remembered_hi16s_reloc (bfd_vma addend, bool *already_found)
266
0
{
267
0
  hi16s_location *match = NULL;
268
0
  hi16s_location *entry;
269
0
  bfd_byte *addr;
270
271
  /* Search the table.  Record the most recent entry that matches.  */
272
0
  for (entry = previous_hi16s; entry; entry = entry->next)
273
0
    {
274
0
      if (entry->addend == addend
275
0
    && (match == NULL || match->counter < entry->counter))
276
0
  {
277
0
    match    = entry;
278
0
  }
279
0
    }
280
281
0
  if (match == NULL)
282
0
    return NULL;
283
284
  /* Extract the address.  */
285
0
  addr = match->address;
286
287
  /* Remember if this entry has already been used before.  */
288
0
  if (already_found)
289
0
    * already_found = match->found;
290
291
  /* Note that this entry has now been used.  */
292
0
  match->found = true;
293
294
0
  return addr;
295
0
}
296
297
/* Calculate the final operand value for a R_V850_LO16 or
298
   R_V850_LO16_SPLIT_OFFSET.  *INSN is the current operand value and
299
   ADDEND is the sum of the relocation symbol and offset.  Store the
300
   operand value in *INSN and return true on success.
301
302
   The assembler has already done some of this: If the value stored in
303
   the instruction has its 15th bit set, (counting from zero) then the
304
   assembler will have added 1 to the value stored in the associated
305
   HI16S reloc.  So for example, these relocations:
306
307
       movhi hi( fred ), r0, r1
308
       movea lo( fred ), r1, r1
309
310
   will store 0 in the value fields for the MOVHI and MOVEA instructions
311
   and addend will be the address of fred, but for these instructions:
312
313
       movhi hi( fred + 0x123456 ), r0, r1
314
       movea lo( fred + 0x123456 ), r1, r1
315
316
   the value stored in the MOVHI instruction will be 0x12 and the value
317
   stored in the MOVEA instruction will be 0x3456.  If however the
318
   instructions were:
319
320
       movhi hi( fred + 0x10ffff ), r0, r1
321
       movea lo( fred + 0x10ffff ), r1, r1
322
323
   then the value stored in the MOVHI instruction would be 0x11 (not
324
   0x10) and the value stored in the MOVEA instruction would be 0xffff.
325
   Thus (assuming for the moment that the addend is 0), at run time the
326
   MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction
327
   adds 0xffffffff (sign extension!) producing 0x10ffff.  Similarly if
328
   the instructions were:
329
330
       movhi hi( fred - 1 ), r0, r1
331
       movea lo( fred - 1 ), r1, r1
332
333
   then 0 is stored in the MOVHI instruction and -1 is stored in the
334
   MOVEA instruction.
335
336
   Overflow can occur if the addition of the value stored in the
337
   instruction plus the addend sets the 15th bit when before it was clear.
338
   This is because the 15th bit will be sign extended into the high part,
339
   thus reducing its value by one, but since the 15th bit was originally
340
   clear, the assembler will not have added 1 to the previous HI16S reloc
341
   to compensate for this effect.  For example:
342
343
      movhi hi( fred + 0x123456 ), r0, r1
344
      movea lo( fred + 0x123456 ), r1, r1
345
346
   The value stored in HI16S reloc is 0x12, the value stored in the LO16
347
   reloc is 0x3456.  If we assume that the address of fred is 0x00007000
348
   then the relocations become:
349
350
     HI16S: 0x0012 + (0x00007000 >> 16)    = 0x12
351
     LO16:  0x3456 + (0x00007000 & 0xffff) = 0xa456
352
353
   but when the instructions are executed, the MOVEA instruction's value
354
   is signed extended, so the sum becomes:
355
356
  0x00120000
357
      + 0xffffa456
358
      ------------
359
  0x0011a456    but 'fred + 0x123456' = 0x0012a456
360
361
   Note that if the 15th bit was set in the value stored in the LO16
362
   reloc, then we do not have to do anything:
363
364
      movhi hi( fred + 0x10ffff ), r0, r1
365
      movea lo( fred + 0x10ffff ), r1, r1
366
367
      HI16S:  0x0011 + (0x00007000 >> 16)    = 0x11
368
      LO16:   0xffff + (0x00007000 & 0xffff) = 0x6fff
369
370
  0x00110000
371
      + 0x00006fff
372
      ------------
373
  0x00116fff  = fred + 0x10ffff = 0x7000 + 0x10ffff
374
375
   Overflow can also occur if the computation carries into the 16th bit
376
   and it also results in the 15th bit having the same value as the 15th
377
   bit of the original value.   What happens is that the HI16S reloc
378
   will have already examined the 15th bit of the original value and
379
   added 1 to the high part if the bit is set.  This compensates for the
380
   sign extension of 15th bit of the result of the computation.  But now
381
   there is a carry into the 16th bit, and this has not been allowed for.
382
383
   So, for example if fred is at address 0xf000:
384
385
     movhi hi( fred + 0xffff ), r0, r1    [bit 15 of the offset is set]
386
     movea lo( fred + 0xffff ), r1, r1
387
388
     HI16S: 0x0001 + (0x0000f000 >> 16)    = 0x0001
389
     LO16:  0xffff + (0x0000f000 & 0xffff) = 0xefff   (carry into bit 16 is lost)
390
391
       0x00010000
392
     + 0xffffefff
393
     ------------
394
       0x0000efff   but 'fred + 0xffff' = 0x0001efff
395
396
   Similarly, if the 15th bit remains clear, but overflow occurs into
397
   the 16th bit then (assuming the address of fred is 0xf000):
398
399
     movhi hi( fred + 0x7000 ), r0, r1    [bit 15 of the offset is clear]
400
     movea lo( fred + 0x7000 ), r1, r1
401
402
     HI16S: 0x0000 + (0x0000f000 >> 16)    = 0x0000
403
     LO16:  0x7000 + (0x0000f000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
404
405
       0x00000000
406
     + 0x00006fff
407
     ------------
408
       0x00006fff   but 'fred + 0x7000' = 0x00016fff
409
410
   Note - there is no need to change anything if a carry occurs, and the
411
   15th bit changes its value from being set to being clear, as the HI16S
412
   reloc will have already added in 1 to the high part for us:
413
414
     movhi hi( fred + 0xffff ), r0, r1     [bit 15 of the offset is set]
415
     movea lo( fred + 0xffff ), r1, r1
416
417
     HI16S: 0x0001 + (0x00007000 >> 16)
418
     LO16:  0xffff + (0x00007000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
419
420
       0x00010000
421
     + 0x00006fff   (bit 15 not set, so the top half is zero)
422
     ------------
423
       0x00016fff   which is right (assuming that fred is at 0x7000)
424
425
   but if the 15th bit goes from being clear to being set, then we must
426
   once again handle overflow:
427
428
     movhi hi( fred + 0x7000 ), r0, r1     [bit 15 of the offset is clear]
429
     movea lo( fred + 0x7000 ), r1, r1
430
431
     HI16S: 0x0000 + (0x0000ffff >> 16)
432
     LO16:  0x7000 + (0x0000ffff & 0xffff) = 0x6fff  (carry into bit 16)
433
434
       0x00000000
435
     + 0x00006fff   (bit 15 not set, so the top half is zero)
436
     ------------
437
       0x00006fff   which is wrong (assuming that fred is at 0xffff).  */
438
439
static bool
440
v850_elf_perform_lo16_relocation (bfd *abfd, unsigned long *insn,
441
          unsigned long addend)
442
0
{
443
0
#define BIT15_SET(x) ((x) & 0x8000)
444
0
#define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
445
446
0
  if ((BIT15_SET (*insn + addend) && ! BIT15_SET (addend))
447
0
      || (OVERFLOWS (addend, *insn)
448
0
    && ((! BIT15_SET (*insn)) || (BIT15_SET (addend)))))
449
0
    {
450
0
      bool already_updated;
451
0
      bfd_byte *hi16s_address = find_remembered_hi16s_reloc
452
0
  (addend, & already_updated);
453
454
      /* Amend the matching HI16_S relocation.  */
455
0
      if (hi16s_address != NULL)
456
0
  {
457
0
    if (! already_updated)
458
0
      {
459
0
        unsigned long hi_insn = bfd_get_16 (abfd, hi16s_address);
460
0
        hi_insn += 1;
461
0
        bfd_put_16 (abfd, hi_insn, hi16s_address);
462
0
      }
463
0
  }
464
0
      else
465
0
  {
466
0
    _bfd_error_handler (_("failed to find previous HI16 reloc"));
467
0
    return false;
468
0
  }
469
0
    }
470
0
#undef OVERFLOWS
471
0
#undef BIT15_SET
472
473
  /* Do not complain if value has top bit set, as this has been
474
     anticipated.  */
475
0
  *insn = (*insn + addend) & 0xffff;
476
0
  return true;
477
0
}
478
479
/* FIXME:  The code here probably ought to be removed and the code in reloc.c
480
   allowed to do its stuff instead.  At least for most of the relocs, anyway.  */
481
482
static bfd_reloc_status_type
483
v850_elf_perform_relocation (bfd *abfd,
484
           unsigned int r_type,
485
           bfd_vma addend,
486
           bfd_byte *address)
487
0
{
488
0
  unsigned long insn;
489
0
  unsigned long result;
490
0
  bfd_signed_vma saddend = (bfd_signed_vma) addend;
491
492
0
  switch (r_type)
493
0
    {
494
0
    default:
495
#ifdef DEBUG
496
      _bfd_error_handler ("%pB: unsupported relocation type %#x",
497
        abfd, r_type);
498
#endif
499
0
      return bfd_reloc_notsupported;
500
501
0
    case R_V850_REL32:
502
0
    case R_V850_ABS32:
503
0
    case R_V810_WORD:
504
0
    case R_V850_PC32:
505
0
      bfd_put_32 (abfd, addend, address);
506
0
      return bfd_reloc_ok;
507
508
0
    case R_V850_WLO23:
509
0
    case R_V850_23:
510
0
      insn  = bfd_get_32 (abfd, address);
511
0
      insn &= ~((0x7f << 4) | (0x7fff80 << (16-7)));
512
0
      insn |= ((addend & 0x7f) << 4) | ((addend & 0x7fff80) << (16-7));
513
0
      bfd_put_32 (abfd, (bfd_vma) insn, address);
514
0
      return bfd_reloc_ok;
515
516
0
    case R_V850_PCR22:
517
0
    case R_V850_22_PCREL:
518
0
      if (saddend > 0x1fffff || saddend < -0x200000)
519
0
  return bfd_reloc_overflow;
520
521
0
      if ((addend % 2) != 0)
522
0
  return bfd_reloc_dangerous;
523
524
0
      insn  = bfd_get_32 (abfd, address);
525
0
      insn &= ~0xfffe003f;
526
0
      insn |= (((addend & 0xfffe) << 16) | ((addend & 0x3f0000) >> 16));
527
0
      bfd_put_32 (abfd, (bfd_vma) insn, address);
528
0
      return bfd_reloc_ok;
529
530
0
    case R_V850_PC17:
531
0
    case R_V850_17_PCREL:
532
0
      if (saddend > 0xffff || saddend < -0x10000)
533
0
  return bfd_reloc_overflow;
534
535
0
      if ((addend % 2) != 0)
536
0
  return bfd_reloc_dangerous;
537
538
0
      insn  = bfd_get_32 (abfd, address);
539
0
      insn &= ~ 0xfffe0010;
540
0
      insn |= ((addend & 0xfffe) << 16) | ((addend & 0x10000) >> (16-4));
541
0
      break;
542
543
0
    case R_V850_PC16U:
544
0
    case R_V850_16_PCREL:
545
0
      if ((saddend < -0xffff) || (saddend > 0))
546
0
  return bfd_reloc_overflow;
547
548
0
      if ((addend % 2) != 0)
549
0
  return bfd_reloc_dangerous;
550
551
0
      insn  = bfd_get_16 (abfd, address);
552
0
      insn &= ~0xfffe;
553
0
      insn |= (-addend & 0xfffe);
554
0
      break;
555
556
0
    case R_V850_PC9:
557
0
    case R_V850_9_PCREL:
558
0
      if (saddend > 0xff || saddend < -0x100)
559
0
  return bfd_reloc_overflow;
560
561
0
      if ((addend % 2) != 0)
562
0
  return bfd_reloc_dangerous;
563
564
0
      insn  = bfd_get_16 (abfd, address);
565
0
      insn &= ~ 0xf870;
566
0
      insn |= ((addend & 0x1f0) << 7) | ((addend & 0x0e) << 3);
567
0
      break;
568
569
0
    case R_V810_WHI:
570
0
    case R_V850_HI16:
571
0
      addend += (bfd_get_16 (abfd, address) << 16);
572
0
      addend = (addend >> 16);
573
0
      insn = addend;
574
0
      break;
575
576
0
    case R_V810_WHI1:
577
0
    case R_V850_HI16_S:
578
      /* Remember where this relocation took place.  */
579
0
      remember_hi16s_reloc (abfd, addend, address);
580
581
0
      addend += (bfd_get_16 (abfd, address) << 16);
582
0
      addend = (addend >> 16) + ((addend & 0x8000) != 0);
583
584
      /* This relocation cannot overflow.  */
585
0
      if (addend > 0xffff)
586
0
  addend = 0;
587
588
0
      insn = addend;
589
0
      break;
590
591
0
    case R_V810_WLO:
592
0
    case R_V850_LO16:
593
0
      insn = bfd_get_16 (abfd, address);
594
0
      if (! v850_elf_perform_lo16_relocation (abfd, &insn, addend))
595
0
  return bfd_reloc_overflow;
596
0
      break;
597
598
0
    case R_V810_BYTE:
599
0
    case R_V850_8:
600
0
      addend += (char) bfd_get_8 (abfd, address);
601
602
0
      saddend = (bfd_signed_vma) addend;
603
604
0
      if (saddend > 0x7f || saddend < -0x80)
605
0
  return bfd_reloc_overflow;
606
607
0
      bfd_put_8 (abfd, addend, address);
608
0
      return bfd_reloc_ok;
609
610
0
    case R_V850_CALLT_16_16_OFFSET:
611
0
      addend += bfd_get_16 (abfd, address);
612
613
0
      saddend = (bfd_signed_vma) addend;
614
615
0
      if (saddend > 0xffff || saddend < 0)
616
0
  return bfd_reloc_overflow;
617
618
0
      insn = addend;
619
0
      break;
620
621
0
    case R_V850_CALLT_15_16_OFFSET:
622
0
      insn = bfd_get_16 (abfd, address);
623
624
0
      addend += insn & 0xfffe;
625
626
0
      saddend = (bfd_signed_vma) addend;
627
628
0
      if (saddend > 0xffff || saddend < 0)
629
0
  return bfd_reloc_overflow;
630
631
0
      insn = (0xfffe & addend)
632
0
  | (insn & ~0xfffe);
633
0
      break;
634
635
0
    case R_V850_CALLT_6_7_OFFSET:
636
0
      insn = bfd_get_16 (abfd, address);
637
0
      addend += ((insn & 0x3f) << 1);
638
639
0
      saddend = (bfd_signed_vma) addend;
640
641
0
      if (saddend > 0x7e || saddend < 0)
642
0
  return bfd_reloc_overflow;
643
644
0
      if (addend & 1)
645
0
  return bfd_reloc_dangerous;
646
647
0
      insn &= 0xff80;
648
0
      insn |= (addend >> 1);
649
0
      break;
650
651
0
    case R_V850_16:
652
0
    case R_V810_HWORD:
653
0
    case R_V850_SDA_16_16_OFFSET:
654
0
    case R_V850_ZDA_16_16_OFFSET:
655
0
    case R_V850_TDA_16_16_OFFSET:
656
0
      addend += bfd_get_16 (abfd, address);
657
658
0
      saddend = (bfd_signed_vma) addend;
659
660
0
      if (saddend > 0x7fff || saddend < -0x8000)
661
0
  return bfd_reloc_overflow;
662
663
0
      insn = addend;
664
0
      break;
665
666
0
    case R_V850_16_S1:
667
0
    case R_V850_SDA_15_16_OFFSET:
668
0
    case R_V850_ZDA_15_16_OFFSET:
669
0
    case R_V810_GPWLO_1:
670
0
      insn = bfd_get_16 (abfd, address);
671
0
      addend += (insn & 0xfffe);
672
673
0
      saddend = (bfd_signed_vma) addend;
674
675
0
      if (saddend > 0x7ffe || saddend < -0x8000)
676
0
  return bfd_reloc_overflow;
677
678
0
      if (addend & 1)
679
0
  return bfd_reloc_dangerous;
680
681
0
      insn = (addend &~ (bfd_vma) 1) | (insn & 1);
682
0
      break;
683
684
0
    case R_V850_TDA_6_8_OFFSET:
685
0
      insn = bfd_get_16 (abfd, address);
686
0
      addend += ((insn & 0x7e) << 1);
687
688
0
      saddend = (bfd_signed_vma) addend;
689
690
0
      if (saddend > 0xfc || saddend < 0)
691
0
  return bfd_reloc_overflow;
692
693
0
      if (addend & 3)
694
0
  return bfd_reloc_dangerous;
695
696
0
      insn &= 0xff81;
697
0
      insn |= (addend >> 1);
698
0
      break;
699
700
0
    case R_V850_TDA_7_8_OFFSET:
701
0
      insn = bfd_get_16 (abfd, address);
702
0
      addend += ((insn & 0x7f) << 1);
703
704
0
      saddend = (bfd_signed_vma) addend;
705
706
0
      if (saddend > 0xfe || saddend < 0)
707
0
  return bfd_reloc_overflow;
708
709
0
      if (addend & 1)
710
0
  return bfd_reloc_dangerous;
711
712
0
      insn &= 0xff80;
713
0
      insn |= (addend >> 1);
714
0
      break;
715
716
0
    case R_V850_TDA_7_7_OFFSET:
717
0
      insn = bfd_get_16 (abfd, address);
718
0
      addend += insn & 0x7f;
719
720
0
      saddend = (bfd_signed_vma) addend;
721
722
0
      if (saddend > 0x7f || saddend < 0)
723
0
  return bfd_reloc_overflow;
724
725
0
      insn &= 0xff80;
726
0
      insn |= addend;
727
0
      break;
728
729
0
    case R_V850_TDA_4_5_OFFSET:
730
0
      insn = bfd_get_16 (abfd, address);
731
0
      addend += ((insn & 0xf) << 1);
732
733
0
      saddend = (bfd_signed_vma) addend;
734
735
0
      if (saddend > 0x1e || saddend < 0)
736
0
  return bfd_reloc_overflow;
737
738
0
      if (addend & 1)
739
0
  return bfd_reloc_dangerous;
740
741
0
      insn &= 0xfff0;
742
0
      insn |= (addend >> 1);
743
0
      break;
744
745
0
    case R_V850_TDA_4_4_OFFSET:
746
0
      insn = bfd_get_16 (abfd, address);
747
0
      addend += insn & 0xf;
748
749
0
      saddend = (bfd_signed_vma) addend;
750
751
0
      if (saddend > 0xf || saddend < 0)
752
0
  return bfd_reloc_overflow;
753
754
0
      insn &= 0xfff0;
755
0
      insn |= addend;
756
0
      break;
757
758
0
    case R_V810_WLO_1:
759
0
    case R_V850_HWLO:
760
0
    case R_V850_HWLO_1:
761
0
    case R_V850_LO16_S1:
762
0
      insn = bfd_get_16 (abfd, address);
763
0
      result = insn & 0xfffe;
764
0
      if (! v850_elf_perform_lo16_relocation (abfd, &result, addend))
765
0
  return bfd_reloc_overflow;
766
0
      if (result & 1)
767
0
  return bfd_reloc_overflow;
768
0
      insn = (result & 0xfffe)
769
0
  | (insn & ~0xfffe);
770
0
  bfd_put_16 (abfd, insn, address);
771
0
      return bfd_reloc_ok;
772
773
0
    case R_V850_BLO:
774
0
    case R_V850_LO16_SPLIT_OFFSET:
775
0
      insn = bfd_get_32 (abfd, address);
776
0
      result = ((insn & 0xfffe0000) >> 16) | ((insn & 0x20) >> 5);
777
0
      if (! v850_elf_perform_lo16_relocation (abfd, &result, addend))
778
0
  return bfd_reloc_overflow;
779
0
      insn = (((result << 16) & 0xfffe0000)
780
0
        | ((result << 5) & 0x20)
781
0
        | (insn & ~0xfffe0020));
782
0
      bfd_put_32 (abfd, insn, address);
783
0
      return bfd_reloc_ok;
784
785
0
    case R_V850_16_SPLIT_OFFSET:
786
0
    case R_V850_SDA_16_16_SPLIT_OFFSET:
787
0
    case R_V850_ZDA_16_16_SPLIT_OFFSET:
788
0
      insn = bfd_get_32 (abfd, address);
789
0
      addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
790
791
0
      saddend = (bfd_signed_vma) addend;
792
793
0
      if (saddend > 0x7fff || saddend < -0x8000)
794
0
  return bfd_reloc_overflow;
795
796
0
      insn &= 0x0001ffdf;
797
0
      insn |= (addend & 1) << 5;
798
0
      insn |= (addend &~ (bfd_vma) 1) << 16;
799
800
0
      bfd_put_32 (abfd, (bfd_vma) insn, address);
801
0
      return bfd_reloc_ok;
802
803
0
    case R_V850_GNU_VTINHERIT:
804
0
    case R_V850_GNU_VTENTRY:
805
0
      return bfd_reloc_ok;
806
807
0
    }
808
809
0
  bfd_put_16 (abfd, (bfd_vma) insn, address);
810
0
  return bfd_reloc_ok;
811
0
}
812

813
/* Insert the addend into the instruction.  */
814
815
static bfd_reloc_status_type
816
v850_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
817
    arelent *reloc,
818
    asymbol *symbol,
819
    void * data ATTRIBUTE_UNUSED,
820
    asection *isection,
821
    bfd *obfd,
822
    char **err ATTRIBUTE_UNUSED)
823
1
{
824
1
  long relocation;
825
826
  /* If there is an output BFD,
827
     and the symbol is not a section name (which is only defined at final link time),
828
     and either we are not putting the addend into the instruction
829
      or the addend is zero, so there is nothing to add into the instruction
830
     then just fixup the address and return.  */
831
1
  if (obfd != NULL
832
0
      && (symbol->flags & BSF_SECTION_SYM) == 0
833
0
      && (! reloc->howto->partial_inplace
834
0
    || reloc->addend == 0))
835
0
    {
836
0
      reloc->address += isection->output_offset;
837
0
      return bfd_reloc_ok;
838
0
    }
839
840
  /* Catch relocs involving undefined symbols.  */
841
1
  if (bfd_is_und_section (symbol->section)
842
0
      && (symbol->flags & BSF_WEAK) == 0
843
0
      && obfd == NULL)
844
0
    return bfd_reloc_undefined;
845
846
  /* We handle final linking of some relocs ourselves.  */
847
848
  /* Is the address of the relocation really within the section?  */
849
1
  if (reloc->address > bfd_get_section_limit (abfd, isection))
850
1
    return bfd_reloc_outofrange;
851
852
  /* Work out which section the relocation is targeted at and the
853
     initial relocation command value.  */
854
855
0
  if (reloc->howto->pc_relative)
856
0
    return bfd_reloc_ok;
857
858
  /* Get symbol value.  (Common symbols are special.)  */
859
0
  if (bfd_is_com_section (symbol->section))
860
0
    relocation = 0;
861
0
  else
862
0
    relocation = symbol->value;
863
864
  /* Convert input-section-relative symbol value to absolute + addend.  */
865
0
  relocation += symbol->section->output_section->vma;
866
0
  relocation += symbol->section->output_offset;
867
0
  relocation += reloc->addend;
868
869
0
  reloc->addend = relocation;
870
0
  return bfd_reloc_ok;
871
0
}
872
873
/* This function is used for relocs which are only used
874
   for relaxing, which the linker should otherwise ignore.  */
875
876
static bfd_reloc_status_type
877
v850_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
878
           arelent *reloc_entry,
879
           asymbol *symbol ATTRIBUTE_UNUSED,
880
           void * data ATTRIBUTE_UNUSED,
881
           asection *input_section,
882
           bfd *output_bfd,
883
           char **error_message ATTRIBUTE_UNUSED)
884
0
{
885
0
  if (output_bfd != NULL)
886
0
    reloc_entry->address += input_section->output_offset;
887
888
0
  return bfd_reloc_ok;
889
0
}
890
/* Note: It is REQUIRED that the 'type' value of each entry
891
   in this array match the index of the entry in the array.
892
   SeeAlso: RELOC_NUBMER in include/elf/v850.h.  */
893
static reloc_howto_type v850_elf_howto_table[] =
894
{
895
  /* This reloc does nothing.  */
896
  HOWTO (R_V850_NONE,     /* Type.  */
897
   0,       /* Rightshift.  */
898
   0,       /* Size.  */
899
   0,       /* Bitsize.  */
900
   false,       /* PC_relative.  */
901
   0,       /* Bitpos.  */
902
   complain_overflow_dont,  /* Complain_on_overflow.  */
903
   bfd_elf_generic_reloc,   /* Special_function.  */
904
   "R_V850_NONE",     /* Name.  */
905
   false,       /* Partial_inplace.  */
906
   0,       /* Src_mask.  */
907
   0,       /* Dst_mask.  */
908
   false),      /* PCrel_offset.  */
909
910
  /* A PC relative 9 bit branch.  */
911
  HOWTO (R_V850_9_PCREL,    /* Type.  */
912
   0,       /* Rightshift.  */
913
   2,       /* Size.  */
914
   9,       /* Bitsize.  */
915
   true,        /* PC_relative.  */
916
   0,       /* Bitpos.  */
917
   complain_overflow_bitfield,  /* Complain_on_overflow.  */
918
   v850_elf_reloc,    /* Special_function.  */
919
   "R_V850_9_PCREL",    /* Name.  */
920
   false,       /* Partial_inplace.  */
921
   0x00ffffff,      /* Src_mask.  */
922
   0x00ffffff,      /* Dst_mask.  */
923
   true),       /* PCrel_offset.  */
924
925
  /* A PC relative 22 bit branch.  */
926
  HOWTO (R_V850_22_PCREL,   /* Type.  */
927
   0,       /* Rightshift.  */
928
   4,       /* Size.  */
929
   22,        /* Bitsize.  */
930
   true,        /* PC_relative.  */
931
   0,       /* Bitpos.  */
932
   complain_overflow_signed,  /* Complain_on_overflow.  */
933
   v850_elf_reloc,    /* Special_function.  */
934
   "R_V850_22_PCREL",   /* Name.  */
935
   false,       /* Partial_inplace.  */
936
   0x07ffff80,      /* Src_mask.  */
937
   0x07ffff80,      /* Dst_mask.  */
938
   true),       /* PCrel_offset.  */
939
940
  /* High 16 bits of symbol value.  */
941
  HOWTO (R_V850_HI16_S,     /* Type.  */
942
   0,       /* Rightshift.  */
943
   2,       /* Size.  */
944
   16,        /* Bitsize.  */
945
   false,       /* PC_relative.  */
946
   0,       /* Bitpos.  */
947
   complain_overflow_dont,  /* Complain_on_overflow.  */
948
   v850_elf_reloc,    /* Special_function.  */
949
   "R_V850_HI16_S",   /* Name.  */
950
   false,       /* Partial_inplace.  */
951
   0xffff,      /* Src_mask.  */
952
   0xffff,      /* Dst_mask.  */
953
   false),      /* PCrel_offset.  */
954
955
  /* High 16 bits of symbol value.  */
956
  HOWTO (R_V850_HI16,     /* Type.  */
957
   0,       /* Rightshift.  */
958
   2,       /* Size.  */
959
   16,        /* Bitsize.  */
960
   false,       /* PC_relative.  */
961
   0,       /* Bitpos.  */
962
   complain_overflow_dont,  /* Complain_on_overflow.  */
963
   v850_elf_reloc,    /* Special_function.  */
964
   "R_V850_HI16",     /* Name.  */
965
   false,       /* Partial_inplace.  */
966
   0xffff,      /* Src_mask.  */
967
   0xffff,      /* Dst_mask.  */
968
   false),      /* PCrel_offset.  */
969
970
  /* Low 16 bits of symbol value.  */
971
  HOWTO (R_V850_LO16,     /* Type.  */
972
   0,       /* Rightshift.  */
973
   2,       /* Size.  */
974
   16,        /* Bitsize.  */
975
   false,       /* PC_relative.  */
976
   0,       /* Bitpos.  */
977
   complain_overflow_dont,  /* Complain_on_overflow.  */
978
   v850_elf_reloc,    /* Special_function.  */
979
   "R_V850_LO16",     /* Name.  */
980
   false,       /* Partial_inplace.  */
981
   0xffff,      /* Src_mask.  */
982
   0xffff,      /* Dst_mask.  */
983
   false),      /* PCrel_offset.  */
984
985
  /* Simple 32bit reloc.  */
986
  HOWTO (R_V850_ABS32,      /* Type.  */
987
   0,       /* Rightshift.  */
988
   4,       /* Size.  */
989
   32,        /* Bitsize.  */
990
   false,       /* PC_relative.  */
991
   0,       /* Bitpos.  */
992
   complain_overflow_dont,  /* Complain_on_overflow.  */
993
   v850_elf_reloc,    /* Special_function.  */
994
   "R_V850_ABS32",    /* Name.  */
995
   false,       /* Partial_inplace.  */
996
   0xffffffff,      /* Src_mask.  */
997
   0xffffffff,      /* Dst_mask.  */
998
   false),      /* PCrel_offset.  */
999
1000
  /* Simple 16bit reloc.  */
1001
  HOWTO (R_V850_16,     /* Type.  */
1002
   0,       /* Rightshift.  */
1003
   2,       /* Size.  */
1004
   16,        /* Bitsize.  */
1005
   false,       /* PC_relative.  */
1006
   0,       /* Bitpos.  */
1007
   complain_overflow_dont,  /* Complain_on_overflow.  */
1008
   bfd_elf_generic_reloc,   /* Special_function.  */
1009
   "R_V850_16",     /* Name.  */
1010
   false,       /* Partial_inplace.  */
1011
   0xffff,      /* Src_mask.  */
1012
   0xffff,      /* Dst_mask.  */
1013
   false),      /* PCrel_offset.  */
1014
1015
  /* Simple 8bit reloc.  */
1016
  HOWTO (R_V850_8,      /* Type.  */
1017
   0,       /* Rightshift.  */
1018
   1,       /* Size.  */
1019
   8,       /* Bitsize.  */
1020
   false,       /* PC_relative.  */
1021
   0,       /* Bitpos.  */
1022
   complain_overflow_dont,  /* Complain_on_overflow.  */
1023
   bfd_elf_generic_reloc,   /* Special_function.  */
1024
   "R_V850_8",      /* Name.  */
1025
   false,       /* Partial_inplace.  */
1026
   0xff,        /* Src_mask.  */
1027
   0xff,        /* Dst_mask.  */
1028
   false),      /* PCrel_offset.  */
1029
1030
  /* 16 bit offset from the short data area pointer.  */
1031
  HOWTO (R_V850_SDA_16_16_OFFSET, /* Type.  */
1032
   0,       /* Rightshift.  */
1033
   2,       /* Size.  */
1034
   16,        /* Bitsize.  */
1035
   false,       /* PC_relative.  */
1036
   0,       /* Bitpos.  */
1037
   complain_overflow_dont,  /* Complain_on_overflow.  */
1038
   v850_elf_reloc,    /* Special_function.  */
1039
   "R_V850_SDA_16_16_OFFSET", /* Name.  */
1040
   false,       /* Partial_inplace.  */
1041
   0xffff,      /* Src_mask.  */
1042
   0xffff,      /* Dst_mask.  */
1043
   false),      /* PCrel_offset.  */
1044
1045
  /* 15 bit offset from the short data area pointer.  */
1046
  HOWTO (R_V850_SDA_15_16_OFFSET, /* Type.  */
1047
   1,       /* Rightshift.  */
1048
   2,       /* Size.  */
1049
   16,        /* Bitsize.  */
1050
   false,       /* PC_relative.  */
1051
   1,       /* Bitpos.  */
1052
   complain_overflow_dont,  /* Complain_on_overflow.  */
1053
   v850_elf_reloc,    /* Special_function.  */
1054
   "R_V850_SDA_15_16_OFFSET", /* Name.  */
1055
   false,       /* Partial_inplace.  */
1056
   0xfffe,      /* Src_mask.  */
1057
   0xfffe,      /* Dst_mask.  */
1058
   false),      /* PCrel_offset.  */
1059
1060
  /* 16 bit offset from the zero data area pointer.  */
1061
  HOWTO (R_V850_ZDA_16_16_OFFSET, /* Type.  */
1062
   0,       /* Rightshift.  */
1063
   2,       /* Size.  */
1064
   16,        /* Bitsize.  */
1065
   false,       /* PC_relative.  */
1066
   0,       /* Bitpos.  */
1067
   complain_overflow_dont,  /* Complain_on_overflow.  */
1068
   v850_elf_reloc,    /* Special_function.  */
1069
   "R_V850_ZDA_16_16_OFFSET", /* Name.  */
1070
   false,       /* Partial_inplace.  */
1071
   0xffff,      /* Src_mask.  */
1072
   0xffff,      /* Dst_mask.  */
1073
   false),      /* PCrel_offset.  */
1074
1075
  /* 15 bit offset from the zero data area pointer.  */
1076
  HOWTO (R_V850_ZDA_15_16_OFFSET, /* Type.  */
1077
   1,       /* Rightshift.  */
1078
   2,       /* Size.  */
1079
   16,        /* Bitsize.  */
1080
   false,       /* PC_relative.  */
1081
   1,       /* Bitpos.  */
1082
   complain_overflow_dont,  /* Complain_on_overflow.  */
1083
   v850_elf_reloc,    /* Special_function.  */
1084
   "R_V850_ZDA_15_16_OFFSET", /* Name.  */
1085
   false,       /* Partial_inplace.  */
1086
   0xfffe,      /* Src_mask.  */
1087
   0xfffe,      /* Dst_mask.  */
1088
   false),      /* PCrel_offset.  */
1089
1090
  /* 6 bit offset from the tiny data area pointer.  */
1091
  HOWTO (R_V850_TDA_6_8_OFFSET,   /* Type.  */
1092
   2,       /* Rightshift.  */
1093
   2,       /* Size.  */
1094
   8,       /* Bitsize.  */
1095
   false,       /* PC_relative.  */
1096
   1,       /* Bitpos.  */
1097
   complain_overflow_dont,  /* Complain_on_overflow.  */
1098
   v850_elf_reloc,    /* Special_function.  */
1099
   "R_V850_TDA_6_8_OFFSET", /* Name.  */
1100
   false,       /* Partial_inplace.  */
1101
   0x7e,        /* Src_mask.  */
1102
   0x7e,        /* Dst_mask.  */
1103
   false),      /* PCrel_offset.  */
1104
1105
  /* 8 bit offset from the tiny data area pointer.  */
1106
  HOWTO (R_V850_TDA_7_8_OFFSET,   /* Type.  */
1107
   1,       /* Rightshift.  */
1108
   2,       /* Size.  */
1109
   8,       /* Bitsize.  */
1110
   false,       /* PC_relative.  */
1111
   0,       /* Bitpos.  */
1112
   complain_overflow_dont,  /* Complain_on_overflow.  */
1113
   v850_elf_reloc,    /* Special_function.  */
1114
   "R_V850_TDA_7_8_OFFSET", /* Name.  */
1115
   false,       /* Partial_inplace.  */
1116
   0x7f,        /* Src_mask.  */
1117
   0x7f,        /* Dst_mask.  */
1118
   false),      /* PCrel_offset.  */
1119
1120
  /* 7 bit offset from the tiny data area pointer.  */
1121
  HOWTO (R_V850_TDA_7_7_OFFSET,   /* Type.  */
1122
   0,       /* Rightshift.  */
1123
   2,       /* Size.  */
1124
   7,       /* Bitsize.  */
1125
   false,       /* PC_relative.  */
1126
   0,       /* Bitpos.  */
1127
   complain_overflow_dont,  /* Complain_on_overflow.  */
1128
   v850_elf_reloc,    /* Special_function.  */
1129
   "R_V850_TDA_7_7_OFFSET", /* Name.  */
1130
   false,       /* Partial_inplace.  */
1131
   0x7f,        /* Src_mask.  */
1132
   0x7f,        /* Dst_mask.  */
1133
   false),      /* PCrel_offset.  */
1134
1135
  /* 16 bit offset from the tiny data area pointer!  */
1136
  HOWTO (R_V850_TDA_16_16_OFFSET, /* Type.  */
1137
   0,       /* Rightshift.  */
1138
   2,       /* Size.  */
1139
   16,        /* Bitsize.  */
1140
   false,       /* PC_relative.  */
1141
   0,       /* Bitpos.  */
1142
   complain_overflow_dont,  /* Complain_on_overflow.  */
1143
   v850_elf_reloc,    /* Special_function.  */
1144
   "R_V850_TDA_16_16_OFFSET", /* Name.  */
1145
   false,       /* Partial_inplace.  */
1146
   0xffff,      /* Src_mask.  */
1147
   0xfff,       /* Dst_mask.  */
1148
   false),      /* PCrel_offset.  */
1149
1150
  /* 5 bit offset from the tiny data area pointer.  */
1151
  HOWTO (R_V850_TDA_4_5_OFFSET,   /* Type.  */
1152
   1,       /* Rightshift.  */
1153
   2,       /* Size.  */
1154
   5,       /* Bitsize.  */
1155
   false,       /* PC_relative.  */
1156
   0,       /* Bitpos.  */
1157
   complain_overflow_dont,  /* Complain_on_overflow.  */
1158
   v850_elf_reloc,    /* Special_function.  */
1159
   "R_V850_TDA_4_5_OFFSET", /* Name.  */
1160
   false,       /* Partial_inplace.  */
1161
   0x0f,        /* Src_mask.  */
1162
   0x0f,        /* Dst_mask.  */
1163
   false),      /* PCrel_offset.  */
1164
1165
  /* 4 bit offset from the tiny data area pointer.  */
1166
  HOWTO (R_V850_TDA_4_4_OFFSET,   /* Type.  */
1167
   0,       /* Rightshift.  */
1168
   2,       /* Size.  */
1169
   4,       /* Bitsize.  */
1170
   false,       /* PC_relative.  */
1171
   0,       /* Bitpos.  */
1172
   complain_overflow_dont,  /* Complain_on_overflow.  */
1173
   v850_elf_reloc,    /* Special_function.  */
1174
   "R_V850_TDA_4_4_OFFSET", /* Name.  */
1175
   false,       /* Partial_inplace.  */
1176
   0x0f,        /* Src_mask.  */
1177
   0x0f,        /* Dst_mask.  */
1178
   false),      /* PCrel_offset.  */
1179
1180
  /* 16 bit offset from the short data area pointer.  */
1181
  HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* Type.  */
1182
   0,       /* Rightshift.  */
1183
   4,       /* Size.  */
1184
   16,        /* Bitsize.  */
1185
   false,       /* PC_relative.  */
1186
   0,       /* Bitpos.  */
1187
   complain_overflow_dont,  /* Complain_on_overflow.  */
1188
   v850_elf_reloc,    /* Special_function.  */
1189
   "R_V850_SDA_16_16_SPLIT_OFFSET",/* Name.  */
1190
   false,       /* Partial_inplace.  */
1191
   0xfffe0020,      /* Src_mask.  */
1192
   0xfffe0020,      /* Dst_mask.  */
1193
   false),      /* PCrel_offset.  */
1194
1195
  /* 16 bit offset from the zero data area pointer.  */
1196
  HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* Type.  */
1197
   0,       /* Rightshift.  */
1198
   4,       /* Size.  */
1199
   16,        /* Bitsize.  */
1200
   false,       /* PC_relative.  */
1201
   0,       /* Bitpos.  */
1202
   complain_overflow_dont,  /* Complain_on_overflow.  */
1203
   v850_elf_reloc,    /* Special_function.  */
1204
   "R_V850_ZDA_16_16_SPLIT_OFFSET",/* Name.  */
1205
   false,       /* Partial_inplace.  */
1206
   0xfffe0020,      /* Src_mask.  */
1207
   0xfffe0020,      /* Dst_mask.  */
1208
   false),      /* PCrel_offset.  */
1209
1210
  /* 6 bit offset from the call table base pointer.  */
1211
  HOWTO (R_V850_CALLT_6_7_OFFSET, /* Type.  */
1212
   0,       /* Rightshift.  */
1213
   2,       /* Size.  */
1214
   7,       /* Bitsize.  */
1215
   false,       /* PC_relative.  */
1216
   0,       /* Bitpos.  */
1217
   complain_overflow_dont,  /* Complain_on_overflow.  */
1218
   v850_elf_reloc,    /* Special_function.  */
1219
   "R_V850_CALLT_6_7_OFFSET", /* Name.  */
1220
   false,       /* Partial_inplace.  */
1221
   0x3f,        /* Src_mask.  */
1222
   0x3f,        /* Dst_mask.  */
1223
   false),      /* PCrel_offset.  */
1224
1225
  /* 16 bit offset from the call table base pointer.  */
1226
  HOWTO (R_V850_CALLT_16_16_OFFSET, /* Type.  */
1227
   0,       /* Rightshift.  */
1228
   2,       /* Size.  */
1229
   16,        /* Bitsize.  */
1230
   false,       /* PC_relative.  */
1231
   0,       /* Bitpos.  */
1232
   complain_overflow_dont,  /* Complain_on_overflow.  */
1233
   v850_elf_reloc,    /* Special_function.  */
1234
   "R_V850_CALLT_16_16_OFFSET", /* Name.  */
1235
   false,       /* Partial_inplace.  */
1236
   0xffff,      /* Src_mask.  */
1237
   0xffff,      /* Dst_mask.  */
1238
   false),      /* PCrel_offset.  */
1239
1240
1241
  /* GNU extension to record C++ vtable hierarchy */
1242
  HOWTO (R_V850_GNU_VTINHERIT, /* Type.  */
1243
   0,     /* Rightshift.  */
1244
   4,     /* Size.  */
1245
   0,     /* Bitsize.  */
1246
   false,     /* PC_relative.  */
1247
   0,     /* Bitpos.  */
1248
   complain_overflow_dont, /* Complain_on_overflow.  */
1249
   NULL,      /* Special_function.  */
1250
   "R_V850_GNU_VTINHERIT", /* Name.  */
1251
   false,     /* Partial_inplace.  */
1252
   0,     /* Src_mask.  */
1253
   0,     /* Dst_mask.  */
1254
   false),    /* PCrel_offset.  */
1255
1256
  /* GNU extension to record C++ vtable member usage.  */
1257
  HOWTO (R_V850_GNU_VTENTRY,   /* Type.  */
1258
   0,     /* Rightshift.  */
1259
   4,     /* Size.  */
1260
   0,     /* Bitsize.  */
1261
   false,     /* PC_relative.  */
1262
   0,     /* Bitpos.  */
1263
   complain_overflow_dont, /* Complain_on_overflow.  */
1264
   _bfd_elf_rel_vtable_reloc_fn,  /* Special_function.  */
1265
   "R_V850_GNU_VTENTRY",   /* Name.  */
1266
   false,     /* Partial_inplace.  */
1267
   0,     /* Src_mask.  */
1268
   0,     /* Dst_mask.  */
1269
   false),    /* PCrel_offset.  */
1270
1271
  /* Indicates a .longcall pseudo-op.  The compiler will generate a .longcall
1272
     pseudo-op when it finds a function call which can be relaxed.  */
1273
  HOWTO (R_V850_LONGCALL,     /* Type.  */
1274
   0,     /* Rightshift.  */
1275
   4,     /* Size.  */
1276
   32,      /* Bitsize.  */
1277
   true,      /* PC_relative.  */
1278
   0,     /* Bitpos.  */
1279
   complain_overflow_signed, /* Complain_on_overflow.  */
1280
   v850_elf_ignore_reloc, /* Special_function.  */
1281
   "R_V850_LONGCALL", /* Name.  */
1282
   false,     /* Partial_inplace.  */
1283
   0,     /* Src_mask.  */
1284
   0,     /* Dst_mask.  */
1285
   true),     /* PCrel_offset.  */
1286
1287
  /* Indicates a .longjump pseudo-op.  The compiler will generate a
1288
     .longjump pseudo-op when it finds a branch which can be relaxed.  */
1289
  HOWTO (R_V850_LONGJUMP,     /* Type.  */
1290
   0,     /* Rightshift.  */
1291
   4,     /* Size.  */
1292
   32,      /* Bitsize.  */
1293
   true,      /* PC_relative.  */
1294
   0,     /* Bitpos.  */
1295
   complain_overflow_signed, /* Complain_on_overflow.  */
1296
   v850_elf_ignore_reloc, /* Special_function.  */
1297
   "R_V850_LONGJUMP", /* Name.  */
1298
   false,     /* Partial_inplace.  */
1299
   0,     /* Src_mask.  */
1300
   0,     /* Dst_mask.  */
1301
   true),     /* PCrel_offset.  */
1302
1303
  HOWTO (R_V850_ALIGN,        /* Type.  */
1304
   0,     /* Rightshift.  */
1305
   2,     /* Size.  */
1306
   0,     /* Bitsize.  */
1307
   false,     /* PC_relative.  */
1308
   0,     /* Bitpos.  */
1309
   complain_overflow_unsigned, /* Complain_on_overflow.  */
1310
   v850_elf_ignore_reloc, /* Special_function.  */
1311
   "R_V850_ALIGN",  /* Name.  */
1312
   false,     /* Partial_inplace.  */
1313
   0,     /* Src_mask.  */
1314
   0,     /* Dst_mask.  */
1315
   true),     /* PCrel_offset.  */
1316
1317
  /* Simple pc-relative 32bit reloc.  */
1318
  HOWTO (R_V850_REL32,      /* Type.  */
1319
   0,       /* Rightshift.  */
1320
   4,       /* Size.  */
1321
   32,        /* Bitsize.  */
1322
   true,        /* PC_relative.  */
1323
   0,       /* Bitpos.  */
1324
   complain_overflow_dont,  /* Complain_on_overflow.  */
1325
   v850_elf_reloc,    /* Special_function.  */
1326
   "R_V850_REL32",    /* Name.  */
1327
   false,       /* Partial_inplace.  */
1328
   0xffffffff,      /* Src_mask.  */
1329
   0xffffffff,      /* Dst_mask.  */
1330
   false),      /* PCrel_offset.  */
1331
1332
  /* An ld.bu version of R_V850_LO16.  */
1333
  HOWTO (R_V850_LO16_SPLIT_OFFSET,  /* Type.  */
1334
   0,       /* Rightshift.  */
1335
   4,       /* Size.  */
1336
   16,        /* Bitsize.  */
1337
   false,       /* PC_relative.  */
1338
   0,       /* Bitpos.  */
1339
   complain_overflow_dont,  /* Complain_on_overflow.  */
1340
   v850_elf_reloc,    /* Special_function.  */
1341
   "R_V850_LO16_SPLIT_OFFSET",  /* Name.  */
1342
   false,       /* Partial_inplace.  */
1343
   0xfffe0020,      /* Src_mask.  */
1344
   0xfffe0020,      /* Dst_mask.  */
1345
   false),      /* PCrel_offset.  */
1346
1347
  /* A unsigned PC relative 16 bit loop.  */
1348
  HOWTO (R_V850_16_PCREL,   /* Type.  */
1349
   0,       /* Rightshift.  */
1350
   2,       /* Size.  */
1351
   16,        /* Bitsize.  */
1352
   true,        /* PC_relative.  */
1353
   0,       /* Bitpos.  */
1354
   complain_overflow_bitfield,  /* Complain_on_overflow.  */
1355
   v850_elf_reloc,    /* Special_function.  */
1356
   "R_V850_16_PCREL",   /* Name.  */
1357
   false,       /* Partial_inplace.  */
1358
   0xfffe,      /* Src_mask.  */
1359
   0xfffe,      /* Dst_mask.  */
1360
   true),       /* PCrel_offset.  */
1361
1362
  /* A PC relative 17 bit branch.  */
1363
  HOWTO (R_V850_17_PCREL,   /* Type.  */
1364
   0,       /* Rightshift.  */
1365
   4,       /* Size.  */
1366
   17,        /* Bitsize.  */
1367
   true,        /* PC_relative.  */
1368
   0,       /* Bitpos.  */
1369
   complain_overflow_bitfield,  /* Complain_on_overflow.  */
1370
   v850_elf_reloc,    /* Special_function.  */
1371
   "R_V850_17_PCREL",   /* Name.  */
1372
   false,       /* Partial_inplace.  */
1373
   0x0010fffe,      /* Src_mask.  */
1374
   0x0010fffe,      /* Dst_mask.  */
1375
   true),       /* PCrel_offset.  */
1376
1377
  /* A 23bit offset ld/st.  */
1378
  HOWTO (R_V850_23,     /* type.  */
1379
   0,       /* rightshift.  */
1380
   4,       /* size.  */
1381
   23,        /* bitsize.  */
1382
   false,       /* pc_relative.  */
1383
   0,       /* bitpos.  */
1384
   complain_overflow_dont,  /* complain_on_overflow.  */
1385
   v850_elf_reloc,    /* special_function.  */
1386
   "R_V850_23",     /* name.  */
1387
   false,       /* partial_inplace.  */
1388
   0xffff07f0,      /* src_mask.  */
1389
   0xffff07f0,      /* dst_mask.  */
1390
   false),      /* pcrel_offset.  */
1391
1392
  /* A PC relative 32 bit branch.  */
1393
  HOWTO (R_V850_32_PCREL,   /* type.  */
1394
   1,       /* rightshift.  */
1395
   4,       /* size.  */
1396
   32,        /* bitsize.  */
1397
   true,        /* pc_relative.  */
1398
   1,       /* bitpos.  */
1399
   complain_overflow_signed,  /* complain_on_overflow.  */
1400
   v850_elf_reloc,    /* special_function.  */
1401
   "R_V850_32_PCREL",   /* name.  */
1402
   false,       /* partial_inplace.  */
1403
   0xfffffffe,      /* src_mask.  */
1404
   0xfffffffe,      /* dst_mask.  */
1405
   true),       /* pcrel_offset.  */
1406
1407
  /* A absolute 32 bit branch.  */
1408
  HOWTO (R_V850_32_ABS,     /* type.  */
1409
   1,       /* rightshift.  */
1410
   4,       /* size.  */
1411
   32,        /* bitsize.  */
1412
   true,        /* pc_relative.  */
1413
   1,       /* bitpos.  */
1414
   complain_overflow_signed,  /* complain_on_overflow.  */
1415
   v850_elf_reloc,    /* special_function.  */
1416
   "R_V850_32_ABS",   /* name.  */
1417
   false,       /* partial_inplace.  */
1418
   0xfffffffe,      /* src_mask.  */
1419
   0xfffffffe,      /* dst_mask.  */
1420
   false),      /* pcrel_offset.  */
1421
1422
  /* High 16 bits of symbol value.  */
1423
  HOWTO (R_V850_HI16,     /* Type.  */
1424
   0,       /* Rightshift.  */
1425
   2,       /* Size.  */
1426
   16,        /* Bitsize.  */
1427
   false,       /* PC_relative.  */
1428
   0,       /* Bitpos.  */
1429
   complain_overflow_dont,  /* Complain_on_overflow.  */
1430
   v850_elf_reloc,    /* Special_function.  */
1431
   "R_V850_HI16",     /* Name.  */
1432
   false,       /* Partial_inplace.  */
1433
   0xffff,      /* Src_mask.  */
1434
   0xffff,      /* Dst_mask.  */
1435
   false),      /* PCrel_offset.  */
1436
1437
  /* Low 16 bits of symbol value.  */
1438
  HOWTO (R_V850_16_S1,      /* type.  */
1439
   1,       /* rightshift.  */
1440
   2,       /* size.  */
1441
   16,        /* bitsize.  */
1442
   false,       /* pc_relative.  */
1443
   1,       /* bitpos.  */
1444
   complain_overflow_dont,  /* complain_on_overflow.  */
1445
   v850_elf_reloc,    /* special_function.  */
1446
   "R_V850_16_S1",    /* name.  */
1447
   false,       /* partial_inplace.  */
1448
   0xfffe,      /* src_mask.  */
1449
   0xfffe,      /* dst_mask.  */
1450
   false),      /* pcrel_offset.  */
1451
1452
  /* Low 16 bits of symbol value.  */
1453
  HOWTO (R_V850_LO16_S1,    /* type.  */
1454
   1,       /* rightshift.  */
1455
   2,       /* size.  */
1456
   16,        /* bitsize.  */
1457
   false,       /* pc_relative.  */
1458
   1,       /* bitpos.  */
1459
   complain_overflow_dont,  /* complain_on_overflow.  */
1460
   v850_elf_reloc,    /* special_function.  */
1461
   "R_V850_LO16_S1",    /* name.  */
1462
   false,       /* partial_inplace.  */
1463
   0xfffe,      /* src_mask.  */
1464
   0xfffe,      /* dst_mask.  */
1465
   false),      /* pcrel_offset.  */
1466
1467
  /* 16 bit offset from the call table base pointer.  */
1468
  HOWTO (R_V850_CALLT_15_16_OFFSET, /* type.  */
1469
   1,       /* rightshift.  */
1470
   2,       /* size.  */
1471
   16,        /* bitsize.  */
1472
   false,       /* pc_relative.  */
1473
   1,       /* bitpos.  */
1474
   complain_overflow_dont,  /* complain_on_overflow.  */
1475
   v850_elf_reloc,    /* special_function.  */
1476
   "R_V850_CALLT_15_16_OFFSET", /* name.  */
1477
   false,       /* partial_inplace.  */
1478
   0xfffe,      /* src_mask.  */
1479
   0xfffe,      /* dst_mask.  */
1480
   false),      /* pcrel_offset.  */
1481
1482
  /* Like R_V850_32 PCREL, but referring to the GOT table entry for
1483
     the symbol.  */
1484
  HOWTO (R_V850_32_GOTPCREL,    /* type.  */
1485
   0,       /* rightshift.  */
1486
   4,       /* size.  */
1487
   32,        /* bitsize.  */
1488
   true,        /* pc_relative.  */
1489
   0,       /* bitpos.  */
1490
   complain_overflow_unsigned,  /* complain_on_overflow.  */
1491
   v850_elf_reloc,    /* special_function.  */
1492
   "R_V850_32_GOTPCREL",    /* name.  */
1493
   false,       /* partial_inplace.  */
1494
   0xffffffff,      /* src_mask.  */
1495
   0xffffffff,      /* dst_mask.  */
1496
   true),       /* pcrel_offset.  */
1497
1498
  /* Like R_V850_SDA_, but referring to the GOT table entry for
1499
     the symbol.  */
1500
  HOWTO (R_V850_16_GOT,     /* type.  */
1501
   0,       /* rightshift.  */
1502
   4,       /* size.  */
1503
   16,        /* bitsize.  */
1504
   false,       /* pc_relative.  */
1505
   0,       /* bitpos.  */
1506
   complain_overflow_unsigned,  /* complain_on_overflow.  */
1507
   bfd_elf_generic_reloc,   /* special_function.  */
1508
   "R_V850_16_GOT",   /* name.  */
1509
   false,       /* partial_inplace.  */
1510
   0xffff,      /* src_mask.  */
1511
   0xffff,      /* dst_mask.  */
1512
   false),      /* pcrel_offset.  */
1513
1514
  HOWTO (R_V850_32_GOT,     /* type.  */
1515
   0,       /* rightshift.  */
1516
   4,       /* size.  */
1517
   32,        /* bitsize.  */
1518
   false,       /* pc_relative.  */
1519
   0,       /* bitpos.  */
1520
   complain_overflow_unsigned,  /* complain_on_overflow.  */
1521
   bfd_elf_generic_reloc,   /* special_function.  */
1522
   "R_V850_32_GOT",   /* name.  */
1523
   false,       /* partial_inplace.  */
1524
   0xffffffff,      /* src_mask.  */
1525
   0xffffffff,      /* dst_mask.  */
1526
   false),      /* pcrel_offset.  */
1527
1528
  /* Like R_V850_22_PCREL, but referring to the procedure linkage table
1529
     entry for the symbol.  */
1530
  HOWTO (R_V850_22_PLT,     /* type.  */
1531
   1,       /* rightshift.  */
1532
   4,       /* size.  */
1533
   22,        /* bitsize.  */
1534
   true,        /* pc_relative.  */
1535
   7,       /* bitpos.  */
1536
   complain_overflow_signed,  /* complain_on_overflow.  */
1537
   bfd_elf_generic_reloc,   /* special_function.  */
1538
   "R_V850_22_PLT",   /* name.  */
1539
   false,       /* partial_inplace.  */
1540
   0x07ffff80,      /* src_mask.  */
1541
   0x07ffff80,      /* dst_mask.  */
1542
   true),       /* pcrel_offset.  */
1543
1544
  HOWTO (R_V850_32_PLT,     /* type.  */
1545
   1,       /* rightshift.  */
1546
   4,       /* size.  */
1547
   32,        /* bitsize.  */
1548
   true,        /* pc_relative.  */
1549
   1,       /* bitpos.  */
1550
   complain_overflow_signed,  /* complain_on_overflow.  */
1551
   bfd_elf_generic_reloc,   /* special_function.  */
1552
   "R_V850_32_PLT",   /* name.  */
1553
   false,       /* partial_inplace.  */
1554
   0xffffffff,      /* src_mask.  */
1555
   0xffffffff,      /* dst_mask.  */
1556
   true),       /* pcrel_offset.  */
1557
1558
  /* This is used only by the dynamic linker.  The symbol should exist
1559
     both in the object being run and in some shared library.  The
1560
     dynamic linker copies the data addressed by the symbol from the
1561
     shared library into the object, because the object being
1562
     run has to have the data at some particular address.  */
1563
  HOWTO (R_V850_COPY,     /* type.  */
1564
   0,       /* rightshift.  */
1565
   4,       /* size.  */
1566
   32,        /* bitsize.  */
1567
   false,       /* pc_relative.  */
1568
   0,       /* bitpos.  */
1569
   complain_overflow_bitfield,  /* complain_on_overflow.  */
1570
   bfd_elf_generic_reloc,   /* special_function.  */
1571
   "R_V850_COPY",     /* name.  */
1572
   false,       /* partial_inplace.  */
1573
   0xffffffff,      /* src_mask.  */
1574
   0xffffffff,      /* dst_mask.  */
1575
   false),      /* pcrel_offset.  */
1576
1577
  /* Like R_M32R_24, but used when setting global offset table
1578
     entries.  */
1579
  HOWTO (R_V850_GLOB_DAT,   /* type.  */
1580
   0,       /* rightshift.  */
1581
   4,       /* size */
1582
   32,        /* bitsize.  */
1583
   false,       /* pc_relative.  */
1584
   0,       /* bitpos.  */
1585
   complain_overflow_bitfield,  /* complain_on_overflow.  */
1586
   bfd_elf_generic_reloc,   /* special_function.  */
1587
   "R_V850_GLOB_DAT",   /* name.  */
1588
   false,       /* partial_inplace.  */
1589
   0xffffffff,      /* src_mask.  */
1590
   0xffffffff,      /* dst_mask.  */
1591
   false),      /* pcrel_offset.  */
1592
1593
  /* Marks a procedure linkage table entry for a symbol.  */
1594
  HOWTO (R_V850_JMP_SLOT,   /* type.  */
1595
   0,       /* rightshift.  */
1596
   4,       /* size */
1597
   32,        /* bitsize.  */
1598
   false,       /* pc_relative.  */
1599
   0,       /* bitpos.  */
1600
   complain_overflow_bitfield,  /* complain_on_overflow.  */
1601
   bfd_elf_generic_reloc,   /* special_function.  */
1602
   "R_V850_JMP_SLOT",   /* name.  */
1603
   false,       /* partial_inplace.  */
1604
   0xffffffff,      /* src_mask.  */
1605
   0xffffffff,      /* dst_mask.  */
1606
   false),      /* pcrel_offset.  */
1607
1608
  /* Used only by the dynamic linker.  When the object is run, this
1609
     longword is set to the load address of the object, plus the
1610
     addend.  */
1611
  HOWTO (R_V850_RELATIVE,   /* type.  */
1612
   0,       /* rightshift.  */
1613
   4,       /* size */
1614
   32,        /* bitsize.  */
1615
   false,       /* pc_relative.  */
1616
   0,       /* bitpos.  */
1617
   complain_overflow_bitfield,  /* complain_on_overflow.  */
1618
   bfd_elf_generic_reloc,   /* special_function.  */
1619
   "R_V850_RELATIVE",   /* name.  */
1620
   false,       /* partial_inplace.  */
1621
   0xffffffff,      /* src_mask.  */
1622
   0xffffffff,      /* dst_mask.  */
1623
   false),      /* pcrel_offset.  */
1624
1625
  HOWTO (R_V850_16_GOTOFF,    /* type.  */
1626
   0,       /* rightshift.  */
1627
   4,       /* size */
1628
   16,        /* bitsize.  */
1629
   false,       /* pc_relative.  */
1630
   0,       /* bitpos.  */
1631
   complain_overflow_bitfield,  /* complain_on_overflow.  */
1632
   bfd_elf_generic_reloc,   /* special_function.  */
1633
   "R_V850_16_GOTOFF",    /* name.  */
1634
   false,       /* partial_inplace.  */
1635
   0xffff,      /* src_mask.  */
1636
   0xffff,      /* dst_mask.  */
1637
   false),      /* pcrel_offset.  */
1638
1639
  HOWTO (R_V850_32_GOTOFF,    /* type.  */
1640
   0,       /* rightshift.  */
1641
   4,       /* size */
1642
   32,        /* bitsize.  */
1643
   false,       /* pc_relative.  */
1644
   0,       /* bitpos.  */
1645
   complain_overflow_bitfield,  /* complain_on_overflow.  */
1646
   bfd_elf_generic_reloc,   /* special_function.  */
1647
   "R_V850_32_GOTOFF",    /* name.  */
1648
   false,       /* partial_inplace.  */
1649
   0xffffffff,      /* src_mask.  */
1650
   0xffffffff,      /* dst_mask.  */
1651
   false),      /* pcrel_offset.  */
1652
1653
  HOWTO (R_V850_CODE,     /* type.  */
1654
   0,       /* rightshift.  */
1655
   2,       /* size */
1656
   0,       /* bitsize.  */
1657
   false,       /* pc_relative.  */
1658
   0,       /* bitpos.  */
1659
   complain_overflow_unsigned,  /* complain_on_overflow.  */
1660
   v850_elf_ignore_reloc,   /* special_function.  */
1661
   "R_V850_CODE",     /* name.  */
1662
   false,       /* partial_inplace.  */
1663
   0,       /* src_mask.  */
1664
   0,       /* dst_mask.  */
1665
   true),       /* pcrel_offset.  */
1666
1667
  HOWTO (R_V850_DATA,     /* type.  */
1668
   0,       /* rightshift.  */
1669
   2,       /* size */
1670
   0,       /* bitsize.  */
1671
   false,       /* pc_relative.  */
1672
   0,       /* bitpos.  */
1673
   complain_overflow_unsigned,  /* complain_on_overflow.  */
1674
   v850_elf_ignore_reloc,   /* special_function.  */
1675
   "R_V850_DATA",     /* name.  */
1676
   false,       /* partial_inplace.  */
1677
   0,       /* src_mask.  */
1678
   0,       /* dst_mask.  */
1679
   true),       /* pcrel_offset.  */
1680
1681
};
1682
1683
/* Map BFD reloc types to V850 ELF reloc types.  */
1684
1685
struct v850_elf_reloc_map
1686
{
1687
  /* BFD_RELOC_V850_CALLT_16_16_OFFSET is 258, which will not fix in an
1688
     unsigned char.  */
1689
  bfd_reloc_code_real_type bfd_reloc_val;
1690
  unsigned int elf_reloc_val;
1691
};
1692
1693
static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
1694
{
1695
  { BFD_RELOC_NONE,        R_V850_NONE       },
1696
  { BFD_RELOC_V850_9_PCREL,      R_V850_9_PCREL    },
1697
  { BFD_RELOC_V850_22_PCREL,       R_V850_22_PCREL     },
1698
  { BFD_RELOC_HI16_S,        R_V850_HI16_S     },
1699
  { BFD_RELOC_HI16,        R_V850_HI16       },
1700
  { BFD_RELOC_LO16,        R_V850_LO16       },
1701
  { BFD_RELOC_32,        R_V850_ABS32      },
1702
  { BFD_RELOC_32_PCREL,        R_V850_REL32      },
1703
  { BFD_RELOC_16,        R_V850_16       },
1704
  { BFD_RELOC_8,         R_V850_8      },
1705
  { BFD_RELOC_V850_SDA_16_16_OFFSET,     R_V850_SDA_16_16_OFFSET   },
1706
  { BFD_RELOC_V850_SDA_15_16_OFFSET,     R_V850_SDA_15_16_OFFSET   },
1707
  { BFD_RELOC_V850_ZDA_16_16_OFFSET,     R_V850_ZDA_16_16_OFFSET   },
1708
  { BFD_RELOC_V850_ZDA_15_16_OFFSET,     R_V850_ZDA_15_16_OFFSET   },
1709
  { BFD_RELOC_V850_TDA_6_8_OFFSET,     R_V850_TDA_6_8_OFFSET   },
1710
  { BFD_RELOC_V850_TDA_7_8_OFFSET,     R_V850_TDA_7_8_OFFSET   },
1711
  { BFD_RELOC_V850_TDA_7_7_OFFSET,     R_V850_TDA_7_7_OFFSET   },
1712
  { BFD_RELOC_V850_TDA_16_16_OFFSET,     R_V850_TDA_16_16_OFFSET   },
1713
  { BFD_RELOC_V850_TDA_4_5_OFFSET,     R_V850_TDA_4_5_OFFSET   },
1714
  { BFD_RELOC_V850_TDA_4_4_OFFSET,     R_V850_TDA_4_4_OFFSET   },
1715
  { BFD_RELOC_V850_LO16_SPLIT_OFFSET,    R_V850_LO16_SPLIT_OFFSET  },
1716
  { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
1717
  { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
1718
  { BFD_RELOC_V850_CALLT_6_7_OFFSET,     R_V850_CALLT_6_7_OFFSET   },
1719
  { BFD_RELOC_V850_CALLT_16_16_OFFSET,     R_V850_CALLT_16_16_OFFSET   },
1720
  { BFD_RELOC_VTABLE_INHERIT,      R_V850_GNU_VTINHERIT    },
1721
  { BFD_RELOC_VTABLE_ENTRY,      R_V850_GNU_VTENTRY    },
1722
  { BFD_RELOC_V850_LONGCALL,       R_V850_LONGCALL     },
1723
  { BFD_RELOC_V850_LONGJUMP,       R_V850_LONGJUMP     },
1724
  { BFD_RELOC_V850_ALIGN,      R_V850_ALIGN      },
1725
  { BFD_RELOC_V850_16_PCREL,       R_V850_16_PCREL     },
1726
  { BFD_RELOC_V850_17_PCREL,       R_V850_17_PCREL     },
1727
  { BFD_RELOC_V850_23,         R_V850_23       },
1728
  { BFD_RELOC_V850_32_PCREL,       R_V850_32_PCREL     },
1729
  { BFD_RELOC_V850_32_ABS,       R_V850_32_ABS     },
1730
  { BFD_RELOC_V850_16_SPLIT_OFFSET,    R_V850_HI16       },
1731
  { BFD_RELOC_V850_16_S1,      R_V850_16_S1      },
1732
  { BFD_RELOC_V850_LO16_S1,      R_V850_LO16_S1    },
1733
  { BFD_RELOC_V850_CALLT_15_16_OFFSET,     R_V850_CALLT_15_16_OFFSET   },
1734
  { BFD_RELOC_V850_32_GOTPCREL,      R_V850_32_GOTPCREL    },
1735
  { BFD_RELOC_V850_16_GOT,       R_V850_16_GOT     },
1736
  { BFD_RELOC_V850_32_GOT,       R_V850_32_GOT     },
1737
  { BFD_RELOC_V850_22_PLT_PCREL,     R_V850_22_PLT     },
1738
  { BFD_RELOC_V850_32_PLT_PCREL,     R_V850_32_PLT     },
1739
  { BFD_RELOC_COPY,        R_V850_COPY       },
1740
  { BFD_RELOC_GLOB_DAT,        R_V850_GLOB_DAT     },
1741
  { BFD_RELOC_JMP_SLOT,        R_V850_JMP_SLOT     },
1742
  { BFD_RELOC_RELATIVE,        R_V850_RELATIVE     },
1743
  { BFD_RELOC_V850_16_GOTOFF,      R_V850_16_GOTOFF    },
1744
  { BFD_RELOC_V850_32_GOTOFF,      R_V850_32_GOTOFF    },
1745
  { BFD_RELOC_V850_CODE,       R_V850_CODE       },
1746
  { BFD_RELOC_V850_DATA,       R_V850_DATA       },
1747
};
1748
1749
#define V800_RELOC(name,sz,bit,shift,complain,pcrel,resolver)    \
1750
  HOWTO (name, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
1751
   bfd_elf_ ## resolver ## _reloc, #name, false, 0, ~0, false)
1752
1753
#define V800_EMPTY(name) EMPTY_HOWTO (name - R_V810_NONE)
1754
1755
#define bfd_elf_v850_reloc v850_elf_reloc
1756
1757
/* Note: It is REQUIRED that the 'type' value (R_V810_...) of each entry
1758
   in this array match the index of the entry in the array minus 0x30.
1759
   See: bfd_elf_v850_relocate_section(), v800_elf_reloc_type_lookup()
1760
   and v800_elf_info_to_howto().  */
1761
1762
static reloc_howto_type v800_elf_howto_table[] =
1763
{
1764
  V800_RELOC (R_V810_NONE,      0,  0, 0, dont,     false, generic),  /* Type = 0x30 */
1765
  V800_RELOC (R_V810_BYTE,      1,  8, 0, dont,     false, generic),
1766
  V800_RELOC (R_V810_HWORD,     2, 16, 0, dont,     false, generic),
1767
  V800_RELOC (R_V810_WORD,      4, 32, 0, dont,     false, generic),
1768
  V800_RELOC (R_V810_WLO,       2, 16, 0, dont,     false, generic),
1769
  V800_RELOC (R_V810_WHI,       2, 16, 0, dont,     false, generic),
1770
  V800_RELOC (R_V810_WHI1,      2, 16, 0, dont,     false, generic),
1771
  V800_RELOC (R_V810_GPBYTE,    1,  8, 0, dont,     false, v850),
1772
  V800_RELOC (R_V810_GPHWORD,   2, 16, 0, dont,     false, v850),
1773
  V800_RELOC (R_V810_GPWORD,    4, 32, 0, dont,     false, v850),
1774
  V800_RELOC (R_V810_GPWLO,     2, 16, 0, dont,     false, v850),
1775
  V800_RELOC (R_V810_GPWHI,     2, 16, 0, dont,     false, v850),
1776
  V800_RELOC (R_V810_GPWHI1,    2, 16, 0, dont,     false, v850),
1777
  V800_RELOC (R_V850_HWLO,      2, 16, 0, dont,     false, generic),
1778
  V800_EMPTY (R_V810_reserved1),
1779
  V800_RELOC (R_V850_EP7BIT,    1,  7, 0, unsigned, false, v850),
1780
  V800_RELOC (R_V850_EPHBYTE,   1,  8, 1, unsigned, false, v850),
1781
  V800_RELOC (R_V850_EPWBYTE,   1,  8, 2, unsigned, false, v850),
1782
  V800_RELOC (R_V850_REGHWLO,   2, 16, 0, dont,     false, v850),
1783
  V800_EMPTY (R_V810_reserved2),
1784
  V800_RELOC (R_V850_GPHWLO,    2, 16, 0, dont,     false, v850),
1785
  V800_EMPTY (R_V810_reserved3),
1786
  V800_RELOC (R_V850_PCR22,     4, 22, 0, signed,   true,  generic),
1787
  V800_RELOC (R_V850_BLO,       4, 24, 0, dont,     false, v850),
1788
  V800_RELOC (R_V850_EP4BIT,    1,  4, 0, unsigned, false, v850),
1789
  V800_RELOC (R_V850_EP5BIT,    1,  5, 0, unsigned, false, v850),
1790
  V800_RELOC (R_V850_REGBLO,    4, 24, 0, dont,     false, v850),
1791
  V800_RELOC (R_V850_GPBLO,     4, 24, 0, dont,     false, v850),
1792
  V800_RELOC (R_V810_WLO_1,     2, 16, 0, dont,     false, v850),
1793
  V800_RELOC (R_V810_GPWLO_1,   2, 16, 0, signed,   false, v850),
1794
  V800_RELOC (R_V850_BLO_1,     4, 16, 0, signed,   false, v850),
1795
  V800_RELOC (R_V850_HWLO_1,    2, 16, 0, signed,   false, v850),
1796
  V800_EMPTY  (R_V810_reserved4),
1797
  V800_RELOC (R_V850_GPBLO_1,   4, 16, 1, signed,   false, v850),
1798
  V800_RELOC (R_V850_GPHWLO_1,  2, 16, 1, signed,   false, v850),
1799
  V800_EMPTY (R_V810_reserved5),
1800
  V800_RELOC (R_V850_EPBLO,     4, 16, 1, signed,   false, v850),
1801
  V800_RELOC (R_V850_EPHWLO,    2, 16, 1, signed,   false, v850),
1802
  V800_EMPTY (R_V810_reserved6),
1803
  V800_RELOC (R_V850_EPWLO_N,   2, 16, 1, signed,   false, v850),
1804
  V800_RELOC (R_V850_PC32,      4, 32, 1, signed,   true,  v850),
1805
  V800_RELOC (R_V850_W23BIT,    4, 23, 1, signed,   false, v850),
1806
  V800_RELOC (R_V850_GPW23BIT,  4, 23, 1, signed,   false, v850),
1807
  V800_RELOC (R_V850_EPW23BIT,  4, 23, 1, signed,   false, v850),
1808
  V800_RELOC (R_V850_B23BIT,    4, 23, 1, signed,   false, v850),
1809
  V800_RELOC (R_V850_GPB23BIT,  4, 23, 1, signed,   false, v850),
1810
  V800_RELOC (R_V850_EPB23BIT,  4, 23, 1, signed,   false, v850),
1811
  V800_RELOC (R_V850_PC16U,     2, 16, 1, unsigned, true,  generic),
1812
  V800_RELOC (R_V850_PC17,      4, 17, 1, signed,   true,  generic),
1813
  V800_RELOC (R_V850_DW8,       4,  8, 2, signed,   false, v850),
1814
  V800_RELOC (R_V850_GPDW8,     4,  8, 2, signed,   false, v850),
1815
  V800_RELOC (R_V850_EPDW8,     4,  8, 2, signed,   false, v850),
1816
  V800_RELOC (R_V850_PC9,       2,  9, 3, signed,   true,  v850),
1817
  V800_RELOC (R_V810_REGBYTE,   1,  8, 0, dont,     false, v850),
1818
  V800_RELOC (R_V810_REGHWORD,  2, 16, 0, dont,     false, v850),
1819
  V800_RELOC (R_V810_REGWORD,   4, 32, 0, dont,     false, v850),
1820
  V800_RELOC (R_V810_REGWLO,    2, 16, 0, dont,     false, v850),
1821
  V800_RELOC (R_V810_REGWHI,    2, 16, 0, dont,     false, v850),
1822
  V800_RELOC (R_V810_REGWHI1,   2, 16, 0, dont,     false, v850),
1823
  V800_RELOC (R_V850_REGW23BIT, 4, 23, 1, signed,   false, v850),
1824
  V800_RELOC (R_V850_REGB23BIT, 4, 23, 1, signed,   false, v850),
1825
  V800_RELOC (R_V850_REGDW8,    4,  8, 2, signed,   false, v850),
1826
  V800_RELOC (R_V810_EPBYTE,    1,  8, 0, dont,     false, v850),
1827
  V800_RELOC (R_V810_EPHWORD,   2, 16, 0, dont,     false, v850),
1828
  V800_RELOC (R_V810_EPWORD,    4, 32, 0, dont,     false, v850),
1829
  V800_RELOC (R_V850_WLO23,     4, 32, 1, dont,     false, v850),
1830
  V800_RELOC (R_V850_WORD_E,    4, 32, 1, dont,     false, v850),
1831
  V800_RELOC (R_V850_REGWORD_E, 4, 32, 1, dont,     false, v850),
1832
  V800_RELOC (R_V850_WORD,      4, 32, 0, dont,     false, v850),
1833
  V800_RELOC (R_V850_GPWORD,    4, 32, 0, dont,     false, v850),
1834
  V800_RELOC (R_V850_REGWORD,   4, 32, 0, dont,     false, v850),
1835
  V800_RELOC (R_V850_EPWORD,    4, 32, 0, dont,     false, v850),
1836
  V800_RELOC (R_V810_TPBYTE,    1,  8, 0, dont,     false, v850),
1837
  V800_RELOC (R_V810_TPHWORD,   2, 16, 0, dont,     false, v850),
1838
  V800_RELOC (R_V810_TPWORD,    4, 32, 0, dont,     false, v850),
1839
  V800_RELOC (R_V810_TPWLO,     2, 16, 0, dont,     false, v850),
1840
  V800_RELOC (R_V810_TPWHI,     2, 16, 0, dont,     false, v850),
1841
  V800_RELOC (R_V810_TPWHI1,    2, 16, 0, dont,     false, v850),
1842
  V800_RELOC (R_V850_TPHWLO,    2, 16, 1, dont,     false, v850),
1843
  V800_RELOC (R_V850_TPBLO,     4, 24, 0, dont,     false, v850),
1844
  V800_RELOC (R_V810_TPWLO_1,   2, 16, 0, signed,   false, v850),
1845
  V800_RELOC (R_V850_TPBLO_1,   4, 16, 0, signed,   false, v850),
1846
  V800_RELOC (R_V850_TPHWLO_1,  2, 16, 0, signed,   false, v850),
1847
  V800_RELOC (R_V850_TP23BIT,   4, 23, 0, signed,   false, v850),
1848
  V800_RELOC (R_V850_TPW23BIT,  4, 23, 0, signed,   false, v850),
1849
  V800_RELOC (R_V850_TPDW8,     4,  8, 0, signed,   false, v850)
1850
};
1851

1852
/* Map a bfd relocation into the appropriate howto structure.  */
1853
1854
static reloc_howto_type *
1855
v850_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1856
          bfd_reloc_code_real_type code)
1857
0
{
1858
0
  unsigned int i;
1859
1860
0
  for (i = ARRAY_SIZE (v850_elf_reloc_map); i --;)
1861
0
    if (v850_elf_reloc_map[i].bfd_reloc_val == code)
1862
0
      {
1863
0
  unsigned int elf_reloc_val = v850_elf_reloc_map[i].elf_reloc_val;
1864
1865
0
  BFD_ASSERT (v850_elf_howto_table[elf_reloc_val].type == elf_reloc_val);
1866
1867
0
  return v850_elf_howto_table + elf_reloc_val;
1868
0
      }
1869
1870
0
  return NULL;
1871
0
}
1872
1873
static reloc_howto_type *
1874
v850_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1875
          const char *r_name)
1876
0
{
1877
0
  unsigned int i;
1878
1879
0
  for (i = 0;
1880
0
       i < sizeof (v850_elf_howto_table) / sizeof (v850_elf_howto_table[0]);
1881
0
       i++)
1882
0
    if (v850_elf_howto_table[i].name != NULL
1883
0
  && strcasecmp (v850_elf_howto_table[i].name, r_name) == 0)
1884
0
      return &v850_elf_howto_table[i];
1885
1886
0
  return NULL;
1887
0
}
1888

1889
/* Set the howto pointer for an V850 ELF reloc.  */
1890
1891
static bool
1892
v850_elf_info_to_howto_rel (bfd *abfd,
1893
          arelent *cache_ptr,
1894
          Elf_Internal_Rela *dst)
1895
223
{
1896
223
  unsigned int r_type;
1897
1898
223
  r_type = ELF32_R_TYPE (dst->r_info);
1899
223
  if (r_type >= (unsigned int) R_V850_max)
1900
18
    {
1901
      /* xgettext:c-format */
1902
18
      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
1903
18
        abfd, r_type);
1904
18
      bfd_set_error (bfd_error_bad_value);
1905
18
      return false;
1906
18
    }
1907
205
  cache_ptr->howto = &v850_elf_howto_table[r_type];
1908
205
  return true;
1909
223
}
1910
1911
/* Set the howto pointer for a V850 ELF reloc (type RELA).  */
1912
1913
static bool
1914
v850_elf_info_to_howto_rela (bfd *abfd,
1915
           arelent * cache_ptr,
1916
           Elf_Internal_Rela *dst)
1917
0
{
1918
0
  unsigned int r_type;
1919
1920
0
  r_type = ELF32_R_TYPE (dst->r_info);
1921
0
  if (r_type >= (unsigned int) R_V850_max)
1922
0
    {
1923
      /* xgettext:c-format */
1924
0
      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
1925
0
        abfd, r_type);
1926
0
      bfd_set_error (bfd_error_bad_value);
1927
0
      return false;
1928
0
    }
1929
0
  cache_ptr->howto = &v850_elf_howto_table[r_type];
1930
0
  return true;
1931
0
}
1932

1933
static bool
1934
v850_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
1935
0
{
1936
0
  if (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
1937
0
    return true;
1938
0
  if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')
1939
0
    return true;
1940
0
  return false;
1941
0
}
1942
1943
static bool
1944
v850_elf_is_target_special_symbol (bfd *abfd, asymbol *sym)
1945
0
{
1946
0
  return v850_elf_is_local_label_name (abfd, sym->name);
1947
0
}
1948

1949
/* We overload some of the bfd_reloc error codes for own purposes.  */
1950
0
#define bfd_reloc_gp_not_found    bfd_reloc_other
1951
0
#define bfd_reloc_ep_not_found    bfd_reloc_continue
1952
0
#define bfd_reloc_ctbp_not_found  (bfd_reloc_dangerous + 1)
1953
1954
/* Perform a relocation as part of a final link.  */
1955
1956
static bfd_reloc_status_type
1957
v850_elf_final_link_relocate (reloc_howto_type *howto,
1958
            bfd *input_bfd,
1959
            bfd *output_bfd ATTRIBUTE_UNUSED,
1960
            asection *input_section,
1961
            bfd_byte *contents,
1962
            bfd_vma offset,
1963
            bfd_vma value,
1964
            bfd_vma addend,
1965
            struct bfd_link_info *info,
1966
            asection *sym_sec,
1967
            int is_local ATTRIBUTE_UNUSED)
1968
0
{
1969
0
  unsigned int r_type = howto->type;
1970
0
  bfd_byte *hit_data = contents + offset;
1971
1972
  /* Adjust the value according to the relocation.  */
1973
0
  switch (r_type)
1974
0
    {
1975
0
    case R_V850_PC9:
1976
0
    case R_V850_9_PCREL:
1977
0
      value -= (input_section->output_section->vma
1978
0
    + input_section->output_offset);
1979
0
      value -= offset;
1980
0
      break;
1981
1982
0
    case R_V850_PC16U:
1983
0
    case R_V850_16_PCREL:
1984
0
      value -= (input_section->output_section->vma
1985
0
    + input_section->output_offset
1986
0
    + offset);
1987
1988
      /* If the sign extension will corrupt the value then we have overflowed.  */
1989
0
      if ((value & 0xffff0000) != 0xffff0000)
1990
0
  return bfd_reloc_overflow;
1991
1992
0
      break;
1993
1994
0
    case R_V850_PC17:
1995
0
    case R_V850_17_PCREL:
1996
0
      value -= (input_section->output_section->vma
1997
0
    + input_section->output_offset
1998
0
    + offset);
1999
2000
      /* If the sign extension will corrupt the value then we have overflowed.  */
2001
0
      if (((value & 0xffff0000) != 0x0) && ((value & 0xffff0000) != 0xffff0000))
2002
0
  return bfd_reloc_overflow;
2003
2004
0
      value = SEXT17 (value);
2005
0
      break;
2006
2007
0
    case R_V850_PCR22:
2008
0
    case R_V850_22_PCREL:
2009
0
      value -= (input_section->output_section->vma
2010
0
    + input_section->output_offset
2011
0
    + offset);
2012
2013
      /* If the sign extension will corrupt the value then we have overflowed.  */
2014
0
      if (((value & 0xffe00000) != 0x0) && ((value & 0xffe00000) != 0xffe00000))
2015
0
  return bfd_reloc_overflow;
2016
2017
      /* Only the bottom 22 bits of the PC are valid.  */
2018
0
      value = SEXT22 (value);
2019
0
      break;
2020
2021
0
    case R_V850_PC32:
2022
0
    case R_V850_32_PCREL:
2023
0
      value -= (input_section->output_section->vma
2024
0
    + input_section->output_offset
2025
0
    + offset);
2026
0
      break;
2027
2028
0
    case R_V850_32_ABS:
2029
0
    case R_V850_23:
2030
0
    case R_V850_HI16_S:
2031
0
    case R_V850_HI16:
2032
0
    case R_V850_LO16:
2033
0
    case R_V850_LO16_S1:
2034
0
    case R_V850_LO16_SPLIT_OFFSET:
2035
0
    case R_V850_16:
2036
0
    case R_V850_ABS32:
2037
0
    case R_V850_8:
2038
0
    case R_V810_BYTE:
2039
0
    case R_V810_HWORD:
2040
0
    case R_V810_WORD:
2041
0
    case R_V810_WLO:
2042
0
    case R_V810_WHI:
2043
0
    case R_V810_WHI1:
2044
0
    case R_V810_WLO_1:
2045
0
    case R_V850_WLO23:
2046
0
    case R_V850_BLO:
2047
0
      break;
2048
2049
0
    case R_V850_ZDA_15_16_OFFSET:
2050
0
    case R_V850_ZDA_16_16_OFFSET:
2051
0
    case R_V850_ZDA_16_16_SPLIT_OFFSET:
2052
0
      if (sym_sec == NULL)
2053
0
  return bfd_reloc_undefined;
2054
2055
0
      value -= sym_sec->output_section->vma;
2056
0
      break;
2057
2058
0
    case R_V850_SDA_15_16_OFFSET:
2059
0
    case R_V850_SDA_16_16_OFFSET:
2060
0
    case R_V850_SDA_16_16_SPLIT_OFFSET:
2061
0
    case R_V810_GPWLO_1:
2062
0
      {
2063
0
  unsigned long        gp;
2064
0
  struct bfd_link_hash_entry * h;
2065
2066
0
  if (sym_sec == NULL)
2067
0
    return bfd_reloc_undefined;
2068
2069
  /* Get the value of __gp.  */
2070
0
  h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
2071
0
  if (h == NULL
2072
0
      || h->type != bfd_link_hash_defined)
2073
0
    return bfd_reloc_gp_not_found;
2074
2075
0
  gp = (h->u.def.value
2076
0
        + h->u.def.section->output_section->vma
2077
0
        + h->u.def.section->output_offset);
2078
2079
0
  value -= sym_sec->output_section->vma;
2080
0
  value -= (gp - sym_sec->output_section->vma);
2081
0
      }
2082
0
    break;
2083
2084
0
    case R_V850_TDA_4_4_OFFSET:
2085
0
    case R_V850_TDA_4_5_OFFSET:
2086
0
    case R_V850_TDA_7_7_OFFSET:
2087
0
    case R_V850_TDA_7_8_OFFSET:
2088
0
    case R_V850_TDA_6_8_OFFSET:
2089
0
    case R_V850_TDA_16_16_OFFSET:
2090
0
      {
2091
0
  unsigned long        ep;
2092
0
  struct bfd_link_hash_entry * h;
2093
2094
  /* Get the value of __ep.  */
2095
0
  h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
2096
0
  if (h == NULL
2097
0
      || h->type != bfd_link_hash_defined)
2098
0
    return bfd_reloc_ep_not_found;
2099
2100
0
  ep = (h->u.def.value
2101
0
        + h->u.def.section->output_section->vma
2102
0
        + h->u.def.section->output_offset);
2103
2104
0
  value -= ep;
2105
0
      }
2106
0
    break;
2107
2108
0
    case R_V850_CALLT_6_7_OFFSET:
2109
0
      {
2110
0
  unsigned long        ctbp;
2111
0
  struct bfd_link_hash_entry * h;
2112
2113
  /* Get the value of __ctbp.  */
2114
0
  h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
2115
0
  if (h == NULL
2116
0
      || h->type != bfd_link_hash_defined)
2117
0
    return bfd_reloc_ctbp_not_found;
2118
2119
0
  ctbp = (h->u.def.value
2120
0
        + h->u.def.section->output_section->vma
2121
0
        + h->u.def.section->output_offset);
2122
0
  value -= ctbp;
2123
0
      }
2124
0
    break;
2125
2126
0
    case R_V850_CALLT_15_16_OFFSET:
2127
0
    case R_V850_CALLT_16_16_OFFSET:
2128
0
      {
2129
0
  unsigned long        ctbp;
2130
0
  struct bfd_link_hash_entry * h;
2131
2132
0
  if (sym_sec == NULL)
2133
0
    return bfd_reloc_undefined;
2134
2135
  /* Get the value of __ctbp.  */
2136
0
  h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
2137
0
  if (h == NULL
2138
0
      || h->type != bfd_link_hash_defined)
2139
0
    return bfd_reloc_ctbp_not_found;
2140
2141
0
  ctbp = (h->u.def.value
2142
0
        + h->u.def.section->output_section->vma
2143
0
        + h->u.def.section->output_offset);
2144
2145
0
  value -= sym_sec->output_section->vma;
2146
0
  value -= (ctbp - sym_sec->output_section->vma);
2147
0
      }
2148
0
    break;
2149
2150
0
    case R_V850_NONE:
2151
0
    case R_V810_NONE:
2152
0
    case R_V850_GNU_VTINHERIT:
2153
0
    case R_V850_GNU_VTENTRY:
2154
0
    case R_V850_LONGCALL:
2155
0
    case R_V850_LONGJUMP:
2156
0
    case R_V850_ALIGN:
2157
0
      return bfd_reloc_ok;
2158
2159
0
    default:
2160
#ifdef DEBUG
2161
      _bfd_error_handler ("%pB: unsupported relocation type %#x",
2162
         input_bfd, r_type);
2163
#endif
2164
0
      return bfd_reloc_notsupported;
2165
0
    }
2166
2167
  /* Perform the relocation.  */
2168
0
  return v850_elf_perform_relocation (input_bfd, r_type, value + addend, hit_data);
2169
0
}
2170

2171
/* Relocate an V850 ELF section.  */
2172
2173
static int
2174
v850_elf_relocate_section (bfd *output_bfd,
2175
         struct bfd_link_info *info,
2176
         bfd *input_bfd,
2177
         asection *input_section,
2178
         bfd_byte *contents,
2179
         Elf_Internal_Rela *relocs,
2180
         Elf_Internal_Sym *local_syms,
2181
         asection **local_sections)
2182
0
{
2183
0
  Elf_Internal_Shdr *symtab_hdr;
2184
0
  struct elf_link_hash_entry **sym_hashes;
2185
0
  Elf_Internal_Rela *rel;
2186
0
  Elf_Internal_Rela *relend;
2187
2188
0
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
2189
0
  sym_hashes = elf_sym_hashes (input_bfd);
2190
2191
  /* Reset the list of remembered HI16S relocs to empty.  */
2192
0
  free_hi16s     = previous_hi16s;
2193
0
  previous_hi16s = NULL;
2194
0
  hi16s_counter  = 0;
2195
2196
0
  rel    = relocs;
2197
0
  relend = relocs + input_section->reloc_count;
2198
0
  for (; rel < relend; rel++)
2199
0
    {
2200
0
      unsigned int r_type;
2201
0
      reloc_howto_type *howto;
2202
0
      unsigned long r_symndx;
2203
0
      Elf_Internal_Sym *sym;
2204
0
      asection *sec;
2205
0
      struct elf_link_hash_entry *h;
2206
0
      bfd_vma relocation;
2207
0
      bfd_reloc_status_type r;
2208
2209
0
      r_symndx = ELF32_R_SYM (rel->r_info);
2210
0
      r_type   = ELF32_R_TYPE (rel->r_info);
2211
2212
0
      if (r_type == R_V850_GNU_VTENTRY
2213
0
    || r_type == R_V850_GNU_VTINHERIT)
2214
0
  continue;
2215
2216
0
      if (bfd_get_arch (input_bfd) == bfd_arch_v850_rh850)
2217
0
  howto = v800_elf_howto_table + (r_type - R_V810_NONE);
2218
0
      else
2219
0
  howto = v850_elf_howto_table + r_type;
2220
2221
0
      BFD_ASSERT (r_type == howto->type);
2222
2223
0
      h = NULL;
2224
0
      sym = NULL;
2225
0
      sec = NULL;
2226
0
      if (r_symndx < symtab_hdr->sh_info)
2227
0
  {
2228
0
    sym = local_syms + r_symndx;
2229
0
    sec = local_sections[r_symndx];
2230
0
    relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2231
0
  }
2232
0
      else
2233
0
  {
2234
0
    bool unresolved_reloc, warned, ignored;
2235
2236
    /* Note - this check is delayed until now as it is possible and
2237
       valid to have a file without any symbols but with relocs that
2238
       can be processed.  */
2239
0
    if (sym_hashes == NULL)
2240
0
      {
2241
0
        info->callbacks->warning
2242
0
    (info, "no hash table available",
2243
0
     NULL, input_bfd, input_section, (bfd_vma) 0);
2244
2245
0
        return false;
2246
0
      }
2247
2248
0
    RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2249
0
           r_symndx, symtab_hdr, sym_hashes,
2250
0
           h, sec, relocation,
2251
0
           unresolved_reloc, warned, ignored);
2252
0
  }
2253
2254
0
      if (sec != NULL && discarded_section (sec))
2255
0
  RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
2256
0
           rel, 1, relend, R_V850_NONE,
2257
0
           howto, 0, contents);
2258
2259
0
      if (bfd_link_relocatable (info))
2260
0
  continue;
2261
2262
      /* FIXME: We should use the addend, but the COFF relocations don't.  */
2263
0
      r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
2264
0
          input_section,
2265
0
          contents, rel->r_offset,
2266
0
          relocation, rel->r_addend,
2267
0
          info, sec, h == NULL);
2268
2269
0
      if (r != bfd_reloc_ok)
2270
0
  {
2271
0
    const char * name;
2272
0
    const char * msg = NULL;
2273
2274
0
    if (h != NULL)
2275
0
      name = h->root.root.string;
2276
0
    else
2277
0
      {
2278
0
        name = (bfd_elf_string_from_elf_section
2279
0
          (input_bfd, symtab_hdr->sh_link, sym->st_name));
2280
0
        if (name == NULL || *name == '\0')
2281
0
    name = bfd_section_name (sec);
2282
0
      }
2283
2284
0
    switch ((int) r)
2285
0
      {
2286
0
      case bfd_reloc_overflow:
2287
0
        (*info->callbacks->reloc_overflow)
2288
0
    (info, (h ? &h->root : NULL), name, howto->name,
2289
0
     (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
2290
0
        break;
2291
2292
0
      case bfd_reloc_undefined:
2293
0
        (*info->callbacks->undefined_symbol)
2294
0
    (info, name, input_bfd, input_section, rel->r_offset, true);
2295
0
        break;
2296
2297
0
      case bfd_reloc_outofrange:
2298
0
        msg = _("internal error: out of range error");
2299
0
        goto common_error;
2300
2301
0
      case bfd_reloc_notsupported:
2302
0
        msg = _("internal error: unsupported relocation error");
2303
0
        goto common_error;
2304
2305
0
      case bfd_reloc_dangerous:
2306
0
        msg = _("internal error: dangerous relocation");
2307
0
        goto common_error;
2308
2309
0
      case bfd_reloc_gp_not_found:
2310
0
        msg = _("could not locate special linker symbol __gp");
2311
0
        goto common_error;
2312
2313
0
      case bfd_reloc_ep_not_found:
2314
0
        msg = _("could not locate special linker symbol __ep");
2315
0
        goto common_error;
2316
2317
0
      case bfd_reloc_ctbp_not_found:
2318
0
        msg = _("could not locate special linker symbol __ctbp");
2319
0
        goto common_error;
2320
2321
0
      default:
2322
0
        msg = _("internal error: unknown error");
2323
        /* fall through */
2324
2325
0
      common_error:
2326
0
        (*info->callbacks->warning) (info, msg, name, input_bfd,
2327
0
             input_section, rel->r_offset);
2328
0
        break;
2329
0
      }
2330
0
  }
2331
0
    }
2332
2333
0
  return true;
2334
0
}
2335
2336
static asection *
2337
v850_elf_gc_mark_hook (asection *sec,
2338
           struct bfd_link_info *info,
2339
           struct elf_reloc_cookie *cookie,
2340
           struct elf_link_hash_entry *h,
2341
           unsigned int symndx)
2342
0
{
2343
0
  if (h != NULL)
2344
0
    switch (ELF32_R_TYPE (cookie->rel->r_info))
2345
0
      {
2346
0
      case R_V850_GNU_VTINHERIT:
2347
0
      case R_V850_GNU_VTENTRY:
2348
0
  return NULL;
2349
0
      }
2350
2351
0
  return _bfd_elf_gc_mark_hook (sec, info, cookie, h, symndx);
2352
0
}
2353
2354
static void
2355
v850_set_note (bfd * abfd, asection * s, enum v850_notes note, unsigned int val)
2356
0
{
2357
0
  bfd_byte * data = s->contents + ((note - 1) * SIZEOF_V850_NOTE);
2358
2359
0
  bfd_put_32 (abfd, 4, data + 0);
2360
0
  bfd_put_32 (abfd, 4, data + 4);
2361
0
  bfd_put_32 (abfd, note, data + 8);
2362
0
  memcpy (data + 12, V850_NOTE_NAME, 4);
2363
0
  bfd_put_32 (abfd, val, data + 16);
2364
0
}
2365
2366
/* Create the note section if not already present.  This is done early so
2367
   that the linker maps the sections to the right place in the output.  */
2368
2369
static asection *
2370
v850_elf_make_note_section (bfd * abfd)
2371
0
{
2372
0
  asection *s;
2373
0
  bfd_byte *data;
2374
0
  flagword flags;
2375
0
  enum v850_notes id;
2376
2377
  /* Make the note section.  */
2378
0
  flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_MERGE;
2379
2380
0
  s = bfd_make_section_anyway_with_flags (abfd, V850_NOTE_SECNAME, flags);
2381
0
  if (s == NULL)
2382
0
    return NULL;
2383
2384
0
  if (!bfd_set_section_alignment (s, 2))
2385
0
    return NULL;
2386
2387
  /* Allocate space for all known notes.  */
2388
0
  if (!bfd_set_section_size (s, NUM_V850_NOTES * SIZEOF_V850_NOTE))
2389
0
    return NULL;
2390
2391
0
  data = bfd_zalloc (abfd, NUM_V850_NOTES * SIZEOF_V850_NOTE);
2392
0
  if (data == NULL)
2393
0
    return NULL;
2394
2395
0
  s->contents = data;
2396
0
  s->alloced = 1;
2397
2398
  /* Provide default (= uninitilaised) values for all of the notes.  */
2399
0
  for (id = V850_NOTE_ALIGNMENT; id <= NUM_V850_NOTES; id++)
2400
0
    v850_set_note (abfd, s, id,  0);
2401
2402
0
  return s;
2403
0
}
2404
2405
/* Create the note section if not already present.  This is done early so
2406
   that the linker maps the sections to the right place in the output.  */
2407
2408
bool
2409
v850_elf_create_sections (struct bfd_link_info * info)
2410
0
{
2411
0
  bfd * ibfd;
2412
2413
  /* If we already have a note section, do not make another.  */
2414
0
  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
2415
0
    if (bfd_get_section_by_name (ibfd, V850_NOTE_SECNAME) != NULL)
2416
0
      return true;
2417
2418
0
  return v850_elf_make_note_section (info->input_bfds) != NULL;
2419
0
}
2420
2421
bool
2422
v850_elf_set_note (bfd * abfd, unsigned int note, unsigned int val)
2423
0
{
2424
0
  asection * notes = bfd_get_section_by_name (abfd, V850_NOTE_SECNAME);
2425
2426
0
  if (val > 2)
2427
    /* At the moment, no known note has a value over 2.  */
2428
0
    return false;
2429
2430
0
  if (notes == NULL)
2431
0
    notes = v850_elf_make_note_section (abfd);
2432
0
  if (notes == NULL)
2433
0
    return false;
2434
2435
0
  v850_set_note (abfd, notes, note, val);
2436
0
  return true;
2437
0
}
2438
2439
/* Copy a v850 note section from one object module to another.  */
2440
2441
static void
2442
v850_elf_copy_notes (bfd *ibfd, bfd *obfd)
2443
8
{
2444
8
  asection * onotes;
2445
8
  asection * inotes;
2446
2447
  /* If the output bfd does not have a note section, then
2448
     skip the merge.  The normal input to output section
2449
     copying will take care of everythng for us.  */
2450
8
  if ((onotes = bfd_get_section_by_name (obfd, V850_NOTE_SECNAME)) == NULL)
2451
8
    return;
2452
2453
0
  if ((inotes = bfd_get_section_by_name (ibfd, V850_NOTE_SECNAME)) == NULL)
2454
0
    return;
2455
2456
0
  if (bfd_section_size (inotes) == bfd_section_size (onotes))
2457
0
    {
2458
0
      bfd_byte * icont;
2459
0
      bfd_byte * ocont;
2460
2461
0
      if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
2462
0
    || (icont = elf_section_data (inotes)->this_hdr.contents) == NULL)
2463
0
  BFD_ASSERT (bfd_malloc_and_get_section (ibfd, inotes, & icont));
2464
2465
0
      if ((ocont = elf_section_data (onotes)->this_hdr.contents) == NULL)
2466
  /* If the output is being stripped then it is possible for
2467
     the notes section to disappear.  In this case do nothing.  */
2468
0
  return;
2469
2470
      /* Copy/overwrite notes from the input to the output.  */
2471
0
      memcpy (ocont, icont, bfd_section_size (onotes));
2472
0
    }
2473
0
}
2474
2475
/* Copy backend specific data from one object module to another.  */
2476
2477
static bool
2478
v850_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
2479
8
{
2480
8
  v850_elf_copy_notes (ibfd, obfd);
2481
8
  return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
2482
8
}
2483
#define bfd_elf32_bfd_copy_private_bfd_data v850_elf_copy_private_bfd_data
2484
2485
static bool
2486
v850_elf_merge_notes (bfd * ibfd, bfd *obfd)
2487
0
{
2488
0
  asection * onotes;
2489
0
  asection * inotes;
2490
0
  bool result = true;
2491
2492
  /* If the output bfd does not have a note section, then
2493
     skip the merge.  The normal input to output section
2494
     copying will take care of everythng for us.  */
2495
0
  if ((onotes = bfd_get_section_by_name (obfd, V850_NOTE_SECNAME)) == NULL)
2496
0
    return true;
2497
2498
0
  if ((inotes = bfd_get_section_by_name (ibfd, V850_NOTE_SECNAME)) != NULL)
2499
0
    {
2500
0
      enum v850_notes id;
2501
0
      bfd_byte * icont;
2502
0
      bfd_byte * ocont;
2503
2504
0
      BFD_ASSERT (bfd_section_size (inotes) == bfd_section_size (onotes));
2505
2506
0
      if ((icont = elf_section_data (inotes)->this_hdr.contents) == NULL)
2507
0
  BFD_ASSERT (bfd_malloc_and_get_section (ibfd, inotes, & icont));
2508
2509
0
      if ((ocont = elf_section_data (onotes)->this_hdr.contents) == NULL)
2510
0
  BFD_ASSERT (bfd_malloc_and_get_section (obfd, onotes, & ocont));
2511
2512
0
      for (id = V850_NOTE_ALIGNMENT; id <= NUM_V850_NOTES; id++)
2513
0
  {
2514
0
    unsigned int ival;
2515
0
    unsigned int oval;
2516
0
    bfd_byte * idata = icont + ((id - 1) * SIZEOF_V850_NOTE) + 16;
2517
0
    bfd_byte * odata = ocont + ((id - 1) * SIZEOF_V850_NOTE) + 16;
2518
2519
0
    ival = bfd_get_32 (ibfd, idata);
2520
0
    oval = bfd_get_32 (obfd, odata);
2521
2522
0
    if (ival == 0 || ival == oval)
2523
0
      continue;
2524
2525
0
    if (oval == 0)
2526
0
      {
2527
0
        bfd_put_32 (obfd, ival, odata);
2528
0
        v850_set_note (obfd, onotes, id, ival);
2529
0
        continue;
2530
0
      }
2531
2532
    /* We have a mismatch.  The ABI defines how to handle
2533
       this siutation on a per note type basis.  */
2534
0
    switch (id)
2535
0
      {
2536
0
      case V850_NOTE_ALIGNMENT:
2537
0
        if (oval == EF_RH850_DATA_ALIGN4)
2538
0
    {
2539
0
      _bfd_error_handler
2540
        /* xgettext:c-format */
2541
0
        (_("error: %pB needs 8-byte alignment but %pB is set for 4-byte alignment"),
2542
0
              ibfd, obfd);
2543
0
      result = false;
2544
0
    }
2545
0
        else
2546
    /* ibfd uses 4-byte alignment, obfd uses 8-byte alignment.
2547
       Leave the obfd alignment as it is.  */
2548
0
    BFD_ASSERT (oval == EF_RH850_DATA_ALIGN8);
2549
2550
0
        break;
2551
2552
0
      case V850_NOTE_DATA_SIZE:
2553
0
        if (oval == EF_RH850_DOUBLE32)
2554
0
    {
2555
0
      _bfd_error_handler
2556
        /* xgettext:c-format */
2557
0
        (_("error: %pB uses 64-bit doubles but "
2558
0
           "%pB uses 32-bit doubles"), ibfd, obfd);
2559
0
      result = false;
2560
0
    }
2561
0
        else
2562
    /* ibfd uses 32-bit doubles, obfd uses 64-bit doubles.
2563
       This is acceptable.  Honest, that is what the ABI says.  */
2564
0
    BFD_ASSERT (oval == EF_RH850_DOUBLE64);
2565
0
        break;
2566
2567
0
      case V850_NOTE_FPU_INFO:
2568
0
        if (oval == EF_RH850_FPU20)
2569
0
    {
2570
0
      _bfd_error_handler
2571
        /* xgettext:c-format */
2572
0
        (_("error: %pB uses FPU-3.0 but %pB only supports FPU-2.0"),
2573
0
         ibfd, obfd);
2574
0
      result = false;
2575
0
    }
2576
0
        else
2577
    /* ibfd uses FPU-2.0, obfd uses FPU-3.0.  Leave obfd as it is.  */
2578
0
    BFD_ASSERT (oval == EF_RH850_FPU30);
2579
2580
0
        break;
2581
2582
0
      default:
2583
        /* None of the other conflicts matter.
2584
     Stick with the current output values.  */
2585
0
        break;
2586
0
      }
2587
0
  }
2588
2589
      /* FIXME:  We should also check for conflicts between the notes
2590
   and the EF flags in the ELF header.  */
2591
0
    }
2592
2593
0
  return result;
2594
0
}
2595
2596
static void
2597
print_v850_note (bfd * abfd, FILE * file, bfd_byte * data, enum v850_notes id)
2598
0
{
2599
0
  unsigned int value = bfd_get_32 (abfd, data + ((id - 1) * SIZEOF_V850_NOTE) + 16);
2600
2601
0
  switch (id)
2602
0
    {
2603
0
    case V850_NOTE_ALIGNMENT:
2604
0
      fprintf (file, _(" alignment of 8-byte entities: "));
2605
0
      switch (value)
2606
0
  {
2607
0
  case EF_RH850_DATA_ALIGN4: fprintf (file, _("4-byte")); break;
2608
0
  case EF_RH850_DATA_ALIGN8: fprintf (file, _("8-byte")); break;
2609
0
  case 0:  fprintf (file, _("not set")); break;
2610
0
  default: fprintf (file, _("unknown: %x"), value); break;
2611
0
  }
2612
0
      fputc ('\n', file);
2613
0
      break;
2614
2615
0
    case V850_NOTE_DATA_SIZE:
2616
0
      fprintf (file, _(" size of doubles: "));
2617
0
      switch (value)
2618
0
  {
2619
0
  case EF_RH850_DOUBLE32: fprintf (file, _("4-bytes")); break;
2620
0
  case EF_RH850_DOUBLE64: fprintf (file, _("8-bytes")); break;
2621
0
  case 0:  fprintf (file, _("not set")); break;
2622
0
  default: fprintf (file, _("unknown: %x"), value); break;
2623
0
  }
2624
0
      fputc ('\n', file);
2625
0
      break;
2626
2627
0
    case V850_NOTE_FPU_INFO:
2628
0
      fprintf (file, _(" FPU support required: "));
2629
0
      switch (value)
2630
0
  {
2631
0
  case EF_RH850_FPU20: fprintf (file, _("FPU-2.0")); break;
2632
0
  case EF_RH850_FPU30: fprintf (file, _("FPU-3.0")); break;
2633
0
  case 0:  fprintf (file, _("none")); break;
2634
0
  default: fprintf (file, _("unknown: %x"), value); break;
2635
0
  }
2636
0
      fputc ('\n', file);
2637
0
      break;
2638
2639
0
    case V850_NOTE_SIMD_INFO:
2640
0
      fprintf (file, _("SIMD use: "));
2641
0
      switch (value)
2642
0
  {
2643
0
  case EF_RH850_SIMD: fprintf (file, _("yes")); break;
2644
0
  case 0:  fprintf (file, _("no")); break;
2645
0
  default: fprintf (file, _("unknown: %x"), value); break;
2646
0
  }
2647
0
      fputc ('\n', file);
2648
0
      break;
2649
2650
0
    case V850_NOTE_CACHE_INFO:
2651
0
      fprintf (file, _("CACHE use: "));
2652
0
      switch (value)
2653
0
  {
2654
0
  case EF_RH850_CACHE: fprintf (file, _("yes")); break;
2655
0
  case 0:  fprintf (file, _("no")); break;
2656
0
  default: fprintf (file, _("unknown: %x"), value); break;
2657
0
  }
2658
0
      fputc ('\n', file);
2659
0
      break;
2660
2661
0
    case V850_NOTE_MMU_INFO:
2662
0
      fprintf (file, _("MMU use: "));
2663
0
      switch (value)
2664
0
  {
2665
0
  case EF_RH850_MMU: fprintf (file, _("yes")); break;
2666
0
  case 0:  fprintf (file, _("no")); break;
2667
0
  default: fprintf (file, _("unknown: %x"), value); break;
2668
0
  }
2669
0
      fputc ('\n', file);
2670
0
      break;
2671
2672
0
    default:
2673
0
      BFD_ASSERT (0);
2674
0
    }
2675
0
}
2676
2677
static void
2678
v850_elf_print_notes (bfd * abfd, FILE * file)
2679
15
{
2680
15
  asection * notes = bfd_get_section_by_name (abfd, V850_NOTE_SECNAME);
2681
15
  enum v850_notes id;
2682
2683
15
  if (notes == NULL || notes->contents == NULL)
2684
15
    return;
2685
2686
0
  BFD_ASSERT (bfd_section_size (notes) == NUM_V850_NOTES * SIZEOF_V850_NOTE);
2687
2688
0
  for (id = V850_NOTE_ALIGNMENT; id <= NUM_V850_NOTES; id++)
2689
0
    print_v850_note (abfd, file, notes->contents, id);
2690
0
}
2691
2692
/* Set the right machine number and architecture.  */
2693
2694
static bool
2695
v850_elf_object_p (bfd *abfd)
2696
209
{
2697
209
  enum bfd_architecture arch;
2698
209
  unsigned long mach;
2699
2700
209
  switch (elf_elfheader (abfd)->e_machine)
2701
209
    {
2702
40
    case EM_V800:
2703
40
      arch = bfd_arch_v850_rh850;
2704
40
      mach = (elf_elfheader (abfd)->e_flags & EF_V800_850E3)
2705
40
  ? bfd_mach_v850e3v5 : bfd_mach_v850e2v3;
2706
40
      break;
2707
2708
60
    case EM_CYGNUS_V850:
2709
169
    case EM_V850:
2710
169
      arch = bfd_arch_v850;
2711
169
      switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
2712
169
  {
2713
14
  default:
2714
91
  case E_V850_ARCH:     mach = bfd_mach_v850; break;
2715
8
  case E_V850E_ARCH:    mach = bfd_mach_v850e; break;
2716
14
  case E_V850E1_ARCH:   mach = bfd_mach_v850e1; break;
2717
33
  case E_V850E2_ARCH:   mach = bfd_mach_v850e2; break;
2718
6
  case E_V850E2V3_ARCH: mach = bfd_mach_v850e2v3; break;
2719
17
  case E_V850E3V5_ARCH: mach = bfd_mach_v850e3v5; break;
2720
169
  }
2721
169
      break;
2722
2723
169
    default:
2724
0
      return false;
2725
209
    }
2726
2727
209
  return bfd_default_set_arch_mach (abfd, arch, mach);
2728
209
}
2729
2730
/* Store the machine number in the flags field.  */
2731
2732
static bool
2733
v850_elf_final_write_processing (bfd *abfd)
2734
8
{
2735
8
  unsigned long val;
2736
2737
8
  switch (bfd_get_arch (abfd))
2738
8
    {
2739
1
    case bfd_arch_v850_rh850:
2740
1
      val = EF_RH850_ABI;
2741
1
      if (bfd_get_mach (abfd) == bfd_mach_v850e3v5)
2742
0
  val |= EF_V800_850E3;
2743
1
      elf_elfheader (abfd)->e_flags |= val;
2744
1
      break;
2745
2746
7
    case bfd_arch_v850:
2747
7
      switch (bfd_get_mach (abfd))
2748
7
  {
2749
0
  default:
2750
1
  case bfd_mach_v850:     val = E_V850_ARCH; break;
2751
1
  case bfd_mach_v850e:    val = E_V850E_ARCH; break;
2752
2
  case bfd_mach_v850e1:   val = E_V850E1_ARCH; break;
2753
1
  case bfd_mach_v850e2:   val = E_V850E2_ARCH; break;
2754
1
  case bfd_mach_v850e2v3: val = E_V850E2V3_ARCH; break;
2755
1
  case bfd_mach_v850e3v5: val = E_V850E3V5_ARCH; break;
2756
7
  }
2757
7
      elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
2758
7
      elf_elfheader (abfd)->e_flags |= val;
2759
7
      break;
2760
0
    default:
2761
0
      break;
2762
8
    }
2763
8
  return _bfd_elf_final_write_processing (abfd);
2764
8
}
2765
2766
/* Function to keep V850 specific file flags.  */
2767
2768
static bool
2769
v850_elf_set_private_flags (bfd *abfd, flagword flags)
2770
0
{
2771
0
  BFD_ASSERT (!elf_flags_init (abfd)
2772
0
        || elf_elfheader (abfd)->e_flags == flags);
2773
2774
0
  elf_elfheader (abfd)->e_flags = flags;
2775
0
  elf_flags_init (abfd) = true;
2776
0
  return true;
2777
0
}
2778
2779
/* Merge backend specific data from an object file
2780
   to the output object file when linking.  */
2781
2782
static bool
2783
v850_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
2784
0
{
2785
0
  bfd *obfd = info->output_bfd;
2786
0
  flagword out_flags;
2787
0
  flagword in_flags;
2788
0
  bool result = true;
2789
2790
0
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
2791
0
    return true;
2792
2793
0
  result &= v850_elf_merge_notes (ibfd, obfd);
2794
2795
0
  in_flags = elf_elfheader (ibfd)->e_flags;
2796
0
  out_flags = elf_elfheader (obfd)->e_flags;
2797
2798
0
  if (! elf_flags_init (obfd))
2799
0
    {
2800
      /* If the input is the default architecture then do not
2801
   bother setting the flags for the output architecture,
2802
   instead allow future merges to do this.  If no future
2803
   merges ever set these flags then they will retain their
2804
   unitialised values, which surprise surprise, correspond
2805
   to the default values.  */
2806
0
      if (bfd_get_arch_info (ibfd)->the_default)
2807
0
  return true;
2808
2809
0
      elf_flags_init (obfd) = true;
2810
0
      elf_elfheader (obfd)->e_flags = in_flags;
2811
2812
0
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
2813
0
    && bfd_get_arch_info (obfd)->the_default)
2814
0
  result &= bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
2815
2816
0
      return result;
2817
0
    }
2818
2819
  /* Check flag compatibility.  */
2820
0
  if (in_flags == out_flags)
2821
0
    return result;
2822
2823
0
  if (bfd_get_arch (obfd) == bfd_arch_v850_rh850)
2824
0
    {
2825
0
      if ((in_flags & EF_V800_850E3) != (out_flags & EF_V800_850E3))
2826
0
  {
2827
0
    _bfd_error_handler
2828
0
      (_("%pB: architecture mismatch with previous modules"), ibfd);
2829
0
    elf_elfheader (obfd)->e_flags |= EF_V800_850E3;
2830
0
  }
2831
2832
0
      return result;
2833
0
    }
2834
2835
0
  if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
2836
0
      && (in_flags & EF_V850_ARCH) != E_V850_ARCH)
2837
0
    {
2838
      /* Allow earlier architecture binaries to be linked with later binaries.
2839
   Set the output binary to the later architecture, except for v850e1,
2840
   which we set to v850e.  */
2841
0
      if (   (in_flags  & EF_V850_ARCH) == E_V850E1_ARCH
2842
0
    && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
2843
0
  return result;
2844
2845
0
      if (   (in_flags  & EF_V850_ARCH) == E_V850_ARCH
2846
0
    && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
2847
0
  {
2848
0
    elf_elfheader (obfd)->e_flags =
2849
0
      ((out_flags & ~ EF_V850_ARCH) | E_V850E_ARCH);
2850
0
    return result;
2851
0
  }
2852
2853
0
      if ((   (in_flags & EF_V850_ARCH) == E_V850_ARCH
2854
0
     || (in_flags & EF_V850_ARCH) == E_V850E_ARCH)
2855
0
    && (out_flags & EF_V850_ARCH) == E_V850E2_ARCH)
2856
0
  {
2857
0
    elf_elfheader (obfd)->e_flags =
2858
0
      ((out_flags & ~ EF_V850_ARCH) | E_V850E2_ARCH);
2859
0
    return result;
2860
0
  }
2861
2862
0
      if ((   (in_flags & EF_V850_ARCH) == E_V850_ARCH
2863
0
     || (in_flags & EF_V850_ARCH) == E_V850E_ARCH
2864
0
     || (in_flags & EF_V850_ARCH) == E_V850E2_ARCH)
2865
0
    && (out_flags & EF_V850_ARCH) == E_V850E2V3_ARCH)
2866
0
  {
2867
0
    elf_elfheader (obfd)->e_flags =
2868
0
      ((out_flags & ~ EF_V850_ARCH) | E_V850E2V3_ARCH);
2869
0
    return result;
2870
0
  }
2871
2872
0
      if ((   (in_flags & EF_V850_ARCH) == E_V850_ARCH
2873
0
     || (in_flags & EF_V850_ARCH) == E_V850E_ARCH
2874
0
     || (in_flags & EF_V850_ARCH) == E_V850E2_ARCH
2875
0
     || (in_flags & EF_V850_ARCH) == E_V850E2V3_ARCH)
2876
0
    && (out_flags & EF_V850_ARCH) == E_V850E3V5_ARCH)
2877
0
  {
2878
0
    elf_elfheader (obfd)->e_flags =
2879
0
      ((out_flags & ~ EF_V850_ARCH) | E_V850E3V5_ARCH);
2880
0
    return result;
2881
0
  }
2882
2883
0
      _bfd_error_handler
2884
0
  (_("%pB: architecture mismatch with previous modules"), ibfd);
2885
0
    }
2886
2887
0
  return result;
2888
0
}
2889
2890
/* Display the flags field.  */
2891
2892
static bool
2893
v850_elf_print_private_bfd_data (bfd *abfd, void * ptr)
2894
15
{
2895
15
  FILE * file = (FILE *) ptr;
2896
2897
15
  BFD_ASSERT (abfd != NULL && ptr != NULL);
2898
2899
15
  _bfd_elf_print_private_bfd_data (abfd, ptr);
2900
2901
  /* xgettext:c-format.  */
2902
15
  fprintf (file, _("private flags = %lx: "), elf_elfheader (abfd)->e_flags);
2903
2904
15
  if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
2905
0
    {
2906
0
      if ((elf_elfheader (abfd)->e_flags & EF_RH850_ABI) != EF_RH850_ABI)
2907
0
  fprintf (file, _("unknown v850 architecture"));
2908
0
      else if (elf_elfheader (abfd)->e_flags & EF_V800_850E3)
2909
0
  fprintf (file, _("v850 E3 architecture"));
2910
0
      else
2911
0
  fprintf (file, _("v850 architecture"));
2912
0
    }
2913
15
  else
2914
15
    {
2915
15
      switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
2916
15
  {
2917
0
  default:
2918
2
  case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;
2919
0
  case E_V850E_ARCH: fprintf (file, _("v850e architecture")); break;
2920
0
  case E_V850E1_ARCH: fprintf (file, _("v850e1 architecture")); break;
2921
8
  case E_V850E2_ARCH: fprintf (file, _("v850e2 architecture")); break;
2922
0
  case E_V850E2V3_ARCH: fprintf (file, _("v850e2v3 architecture")); break;
2923
5
  case E_V850E3V5_ARCH: fprintf (file, _("v850e3v5 architecture")); break;
2924
15
  }
2925
15
    }
2926
2927
15
  fputc ('\n', file);
2928
2929
15
  v850_elf_print_notes (abfd, file);
2930
2931
15
  return true;
2932
15
}
2933
2934
/* V850 ELF uses four common sections.  One is the usual one, and the
2935
   others are for (small) objects in one of the special data areas:
2936
   small, tiny and zero.  All the objects are kept together, and then
2937
   referenced via the gp register, the ep register or the r0 register
2938
   respectively, which yields smaller, faster assembler code.  This
2939
   approach is copied from elf32-mips.c.  */
2940
2941
static asection v850_elf_scom_section;
2942
static const asymbol v850_elf_scom_symbol =
2943
  GLOBAL_SYM_INIT (".scommon", &v850_elf_scom_section);
2944
static asection v850_elf_scom_section =
2945
  BFD_FAKE_SECTION (v850_elf_scom_section, &v850_elf_scom_symbol,
2946
        ".scommon", 0,
2947
        SEC_IS_COMMON | SEC_SMALL_DATA | SEC_ALLOC | SEC_DATA);
2948
2949
static asection v850_elf_tcom_section;
2950
static const asymbol v850_elf_tcom_symbol =
2951
  GLOBAL_SYM_INIT (".tcommon", &v850_elf_tcom_section);
2952
static asection v850_elf_tcom_section =
2953
  BFD_FAKE_SECTION (v850_elf_tcom_section, &v850_elf_tcom_symbol,
2954
        ".tcommon", 0,
2955
        SEC_IS_COMMON | SEC_SMALL_DATA);
2956
2957
static asection v850_elf_zcom_section;
2958
static const asymbol v850_elf_zcom_symbol =
2959
  GLOBAL_SYM_INIT (".zcommon", &v850_elf_zcom_section);
2960
static asection v850_elf_zcom_section =
2961
  BFD_FAKE_SECTION (v850_elf_zcom_section, &v850_elf_zcom_symbol,
2962
        ".zcommon", 0,
2963
        SEC_IS_COMMON | SEC_SMALL_DATA);
2964
2965
/* Given a BFD section, try to locate the
2966
   corresponding ELF section index.  */
2967
2968
static bool
2969
v850_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
2970
           asection *sec,
2971
           int *retval)
2972
0
{
2973
0
  if (strcmp (bfd_section_name (sec), ".scommon") == 0)
2974
0
    *retval = SHN_V850_SCOMMON;
2975
0
  else if (strcmp (bfd_section_name (sec), ".tcommon") == 0)
2976
0
    *retval = SHN_V850_TCOMMON;
2977
0
  else if (strcmp (bfd_section_name (sec), ".zcommon") == 0)
2978
0
    *retval = SHN_V850_ZCOMMON;
2979
0
  else
2980
0
    return false;
2981
2982
0
  return true;
2983
0
}
2984
2985
/* Handle the special V850 section numbers that a symbol may use.  */
2986
2987
static void
2988
v850_elf_symbol_processing (bfd *abfd, asymbol *asym)
2989
699
{
2990
699
  elf_symbol_type * elfsym = (elf_symbol_type *) asym;
2991
699
  unsigned int indx;
2992
2993
699
  indx = elfsym->internal_elf_sym.st_shndx;
2994
2995
  /* If the section index is an "ordinary" index, then it may
2996
     refer to a v850 specific section created by the assembler.
2997
     Check the section's type and change the index it matches.
2998
2999
     FIXME: Should we alter the st_shndx field as well ?  */
3000
3001
699
  if (indx < elf_numsections (abfd))
3002
473
    switch (elf_elfsections (abfd)[indx]->sh_type)
3003
473
      {
3004
0
      case SHT_V850_SCOMMON:
3005
0
  indx = SHN_V850_SCOMMON;
3006
0
  break;
3007
3008
0
      case SHT_V850_TCOMMON:
3009
0
  indx = SHN_V850_TCOMMON;
3010
0
  break;
3011
3012
0
      case SHT_V850_ZCOMMON:
3013
0
  indx = SHN_V850_ZCOMMON;
3014
0
  break;
3015
3016
473
      default:
3017
473
  break;
3018
473
      }
3019
3020
699
  switch (indx)
3021
699
    {
3022
5
    case SHN_V850_SCOMMON:
3023
5
      asym->section = & v850_elf_scom_section;
3024
5
      asym->value = elfsym->internal_elf_sym.st_size;
3025
5
      break;
3026
3027
0
    case SHN_V850_TCOMMON:
3028
0
      asym->section = & v850_elf_tcom_section;
3029
0
      asym->value = elfsym->internal_elf_sym.st_size;
3030
0
      break;
3031
3032
0
    case SHN_V850_ZCOMMON:
3033
0
      asym->section = & v850_elf_zcom_section;
3034
0
      asym->value = elfsym->internal_elf_sym.st_size;
3035
0
      break;
3036
699
    }
3037
699
}
3038
3039
/* Hook called by the linker routine which adds symbols from an object
3040
   file.  We must handle the special v850 section numbers here.  */
3041
3042
static bool
3043
v850_elf_add_symbol_hook (bfd *abfd,
3044
        struct bfd_link_info *info ATTRIBUTE_UNUSED,
3045
        Elf_Internal_Sym *sym,
3046
        const char **namep ATTRIBUTE_UNUSED,
3047
        flagword *flagsp ATTRIBUTE_UNUSED,
3048
        asection **secp,
3049
        bfd_vma *valp)
3050
0
{
3051
0
  unsigned int indx = sym->st_shndx;
3052
3053
  /* If the section index is an "ordinary" index, then it may
3054
     refer to a v850 specific section created by the assembler.
3055
     Check the section's type and change the index it matches.
3056
3057
     FIXME: Should we alter the st_shndx field as well ?  */
3058
3059
0
  if (indx < elf_numsections (abfd))
3060
0
    switch (elf_elfsections (abfd)[indx]->sh_type)
3061
0
      {
3062
0
      case SHT_V850_SCOMMON:
3063
0
  indx = SHN_V850_SCOMMON;
3064
0
  break;
3065
3066
0
      case SHT_V850_TCOMMON:
3067
0
  indx = SHN_V850_TCOMMON;
3068
0
  break;
3069
3070
0
      case SHT_V850_ZCOMMON:
3071
0
  indx = SHN_V850_ZCOMMON;
3072
0
  break;
3073
3074
0
      default:
3075
0
  break;
3076
0
      }
3077
3078
0
  switch (indx)
3079
0
    {
3080
0
    case SHN_V850_SCOMMON:
3081
0
      *secp = bfd_make_section_old_way (abfd, ".scommon");
3082
0
      (*secp)->flags |= SEC_IS_COMMON | SEC_SMALL_DATA;
3083
0
      *valp = sym->st_size;
3084
0
      break;
3085
3086
0
    case SHN_V850_TCOMMON:
3087
0
      *secp = bfd_make_section_old_way (abfd, ".tcommon");
3088
0
      (*secp)->flags |= SEC_IS_COMMON | SEC_SMALL_DATA;
3089
0
      *valp = sym->st_size;
3090
0
      break;
3091
3092
0
    case SHN_V850_ZCOMMON:
3093
0
      *secp = bfd_make_section_old_way (abfd, ".zcommon");
3094
0
      (*secp)->flags |= SEC_IS_COMMON | SEC_SMALL_DATA;
3095
0
      *valp = sym->st_size;
3096
0
      break;
3097
0
    }
3098
3099
0
  return true;
3100
0
}
3101
3102
static int
3103
v850_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
3104
          const char *name ATTRIBUTE_UNUSED,
3105
          Elf_Internal_Sym *sym,
3106
          asection *input_sec,
3107
          struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
3108
0
{
3109
  /* If we see a common symbol, which implies a relocatable link, then
3110
     if a symbol was in a special common section in an input file, mark
3111
     it as a special common in the output file.  */
3112
3113
0
  if (sym->st_shndx == SHN_COMMON)
3114
0
    {
3115
0
      if (strcmp (input_sec->name, ".scommon") == 0)
3116
0
  sym->st_shndx = SHN_V850_SCOMMON;
3117
0
      else if (strcmp (input_sec->name, ".tcommon") == 0)
3118
0
  sym->st_shndx = SHN_V850_TCOMMON;
3119
0
      else if (strcmp (input_sec->name, ".zcommon") == 0)
3120
0
  sym->st_shndx = SHN_V850_ZCOMMON;
3121
0
    }
3122
3123
  /* The price we pay for using h->other unused bits as flags in the
3124
     linker is cleaning up after ourselves.  */
3125
3126
0
  sym->st_other &= ~(V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA
3127
0
         | V850_OTHER_ERROR);
3128
3129
0
  return 1;
3130
0
}
3131
3132
static bool
3133
v850_elf_section_from_shdr (bfd *abfd,
3134
          Elf_Internal_Shdr *hdr,
3135
          const char *name,
3136
          int shindex)
3137
1.13k
{
3138
1.13k
  flagword flags;
3139
3140
  /* There ought to be a place to keep ELF backend specific flags, but
3141
     at the moment there isn't one.  We just keep track of the
3142
     sections by their name, instead.  */
3143
3144
1.13k
  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
3145
5
    return false;
3146
3147
1.12k
  flags = 0;
3148
1.12k
  switch (hdr->sh_type)
3149
1.12k
    {
3150
18
    case SHT_V850_SCOMMON:
3151
18
    case SHT_V850_TCOMMON:
3152
18
    case SHT_V850_ZCOMMON:
3153
18
      flags = SEC_IS_COMMON;
3154
1.12k
    }
3155
3156
1.12k
  if ((hdr->sh_flags & SHF_V850_GPREL) != 0)
3157
233
    flags |= SEC_SMALL_DATA;
3158
3159
1.12k
  return (flags == 0
3160
247
    || bfd_set_section_flags (hdr->bfd_section,
3161
247
            hdr->bfd_section->flags | flags));
3162
1.12k
}
3163
3164
/* Set the correct type for a V850 ELF section.  We do this
3165
   by the section name, which is a hack, but ought to work.  */
3166
3167
static bool
3168
v850_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
3169
      Elf_Internal_Shdr *hdr,
3170
      asection *sec)
3171
8
{
3172
8
  const char * name;
3173
3174
8
  name = bfd_section_name (sec);
3175
3176
8
  if (strcmp (name, ".scommon") == 0)
3177
0
    hdr->sh_type = SHT_V850_SCOMMON;
3178
8
  else if (strcmp (name, ".tcommon") == 0)
3179
0
    hdr->sh_type = SHT_V850_TCOMMON;
3180
8
  else if (strcmp (name, ".zcommon") == 0)
3181
0
    hdr->sh_type = SHT_V850_ZCOMMON;
3182
  /* Tweak the section type of .note.renesas.  */
3183
8
  else if (strcmp (name, V850_NOTE_SECNAME) == 0)
3184
0
    {
3185
0
      hdr->sh_type = SHT_RENESAS_INFO;
3186
0
      hdr->sh_entsize = SIZEOF_V850_NOTE;
3187
0
    }
3188
3189
8
  return true;
3190
8
}
3191
3192
/* Delete some bytes from a section while relaxing.  */
3193
3194
static bool
3195
v850_elf_relax_delete_bytes (bfd *abfd,
3196
           asection *sec,
3197
           bfd_vma addr,
3198
           bfd_vma toaddr,
3199
           int count)
3200
0
{
3201
0
  Elf_Internal_Shdr *symtab_hdr;
3202
0
  Elf32_External_Sym *extsyms;
3203
0
  Elf32_External_Sym *esym;
3204
0
  Elf32_External_Sym *esymend;
3205
0
  int sym_index;
3206
0
  unsigned int sec_shndx;
3207
0
  bfd_byte *contents;
3208
0
  Elf_Internal_Rela *irel;
3209
0
  Elf_Internal_Rela *irelend;
3210
0
  struct elf_link_hash_entry *sym_hash;
3211
0
  Elf_External_Sym_Shndx *shndx;
3212
3213
0
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3214
0
  extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
3215
3216
0
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
3217
3218
0
  contents = elf_section_data (sec)->this_hdr.contents;
3219
3220
  /* The deletion must stop at the next ALIGN reloc for an alignment
3221
     power larger than the number of bytes we are deleting.  */
3222
3223
  /* Actually delete the bytes.  */
3224
#if (DEBUG_RELAX & 2)
3225
  fprintf (stderr, "relax_delete: contents: sec: %s  %p .. %p %x\n",
3226
     sec->name, addr, toaddr, count );
3227
#endif
3228
0
  memmove (contents + addr, contents + addr + count,
3229
0
     toaddr - addr - count);
3230
0
  memset (contents + toaddr-count, 0, count);
3231
3232
  /* Adjust all the relocs.  */
3233
0
  irel = elf_section_data (sec)->relocs;
3234
0
  irelend = irel + sec->reloc_count;
3235
0
  if (elf_symtab_shndx_list (abfd))
3236
0
    {
3237
0
      Elf_Internal_Shdr *shndx_hdr;
3238
3239
0
      shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
3240
0
      shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
3241
0
    }
3242
0
  else
3243
0
    {
3244
0
      shndx = NULL;
3245
0
    }
3246
3247
0
  for (; irel < irelend; irel++)
3248
0
    {
3249
0
      bfd_vma raddr, paddr, symval;
3250
0
      Elf_Internal_Sym isym;
3251
3252
      /* Get the new reloc address.  */
3253
0
      raddr = irel->r_offset;
3254
0
      if ((raddr >= (addr + count) && raddr < toaddr))
3255
0
  irel->r_offset -= count;
3256
3257
0
      if (raddr >= addr && raddr < addr + count)
3258
0
  {
3259
0
    irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
3260
0
               (int) R_V850_NONE);
3261
0
    continue;
3262
0
  }
3263
3264
0
      if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN)
3265
0
  continue;
3266
3267
0
      bfd_elf32_swap_symbol_in (abfd,
3268
0
        extsyms + ELF32_R_SYM (irel->r_info),
3269
0
        shndx ? shndx + ELF32_R_SYM (irel->r_info) : NULL,
3270
0
        & isym);
3271
3272
0
      if (isym.st_shndx != sec_shndx)
3273
0
  continue;
3274
3275
      /* Get the value of the symbol referred to by the reloc.  */
3276
0
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
3277
0
  {
3278
0
    symval = isym.st_value;
3279
#if (DEBUG_RELAX & 2)
3280
    {
3281
      char * name = bfd_elf_string_from_elf_section
3282
         (abfd, symtab_hdr->sh_link, isym.st_name);
3283
      fprintf (stderr,
3284
         "relax_delete: local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
3285
         sec->name, name, isym.st_name,
3286
         sec->output_section->vma, sec->output_offset,
3287
         isym.st_value, irel->r_addend);
3288
    }
3289
#endif
3290
0
  }
3291
0
      else
3292
0
  {
3293
0
    unsigned long indx;
3294
0
    struct elf_link_hash_entry * h;
3295
3296
    /* An external symbol.  */
3297
0
    indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
3298
3299
0
    h = elf_sym_hashes (abfd) [indx];
3300
0
    BFD_ASSERT (h != NULL);
3301
3302
0
    symval = h->root.u.def.value;
3303
#if (DEBUG_RELAX & 2)
3304
    fprintf (stderr,
3305
       "relax_delete: defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
3306
       sec->name, h->root.root.string, h->root.u.def.value,
3307
       sec->output_section->vma, sec->output_offset, irel->r_addend);
3308
#endif
3309
0
  }
3310
3311
0
      paddr = symval + irel->r_addend;
3312
3313
0
      if ( (symval >= addr + count && symval < toaddr)
3314
0
    && (paddr < addr + count || paddr >= toaddr))
3315
0
  irel->r_addend += count;
3316
0
      else if (    (symval < addr + count || symval >= toaddr)
3317
0
    && (paddr >= addr + count && paddr < toaddr))
3318
0
  irel->r_addend -= count;
3319
0
    }
3320
3321
  /* Adjust the local symbols defined in this section.  */
3322
0
  esym = extsyms;
3323
0
  esymend = esym + symtab_hdr->sh_info;
3324
3325
0
  for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
3326
0
    {
3327
0
      Elf_Internal_Sym isym;
3328
3329
0
      bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
3330
3331
0
      if (isym.st_shndx == sec_shndx
3332
0
    && isym.st_value >= addr + count
3333
0
    && isym.st_value < toaddr)
3334
0
  {
3335
0
    isym.st_value -= count;
3336
3337
0
    if (isym.st_value + isym.st_size >= toaddr)
3338
0
      isym.st_size += count;
3339
3340
0
    bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
3341
0
  }
3342
0
      else if (isym.st_shndx == sec_shndx
3343
0
         && isym.st_value < addr + count)
3344
0
  {
3345
0
    if (isym.st_value+isym.st_size >= addr + count
3346
0
        && isym.st_value+isym.st_size < toaddr)
3347
0
      isym.st_size -= count;
3348
3349
0
    if (isym.st_value >= addr
3350
0
        && isym.st_value <  addr + count)
3351
0
      isym.st_value = addr;
3352
3353
0
    bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
3354
0
  }
3355
0
    }
3356
3357
  /* Now adjust the global symbols defined in this section.  */
3358
0
  esym = extsyms + symtab_hdr->sh_info;
3359
0
  esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
3360
3361
0
  for (sym_index = 0; esym < esymend; esym ++, sym_index ++)
3362
0
    {
3363
0
      Elf_Internal_Sym isym;
3364
3365
0
      bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
3366
0
      sym_hash = elf_sym_hashes (abfd) [sym_index];
3367
3368
0
      if (isym.st_shndx == sec_shndx
3369
0
    && ((sym_hash)->root.type == bfd_link_hash_defined
3370
0
        || (sym_hash)->root.type == bfd_link_hash_defweak)
3371
0
    && (sym_hash)->root.u.def.section == sec
3372
0
    && (sym_hash)->root.u.def.value >= addr + count
3373
0
    && (sym_hash)->root.u.def.value < toaddr)
3374
0
  {
3375
0
    if ((sym_hash)->root.u.def.value + isym.st_size >= toaddr)
3376
0
      {
3377
0
        isym.st_size += count;
3378
0
        bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
3379
0
      }
3380
3381
0
    (sym_hash)->root.u.def.value -= count;
3382
0
  }
3383
0
      else if (isym.st_shndx == sec_shndx
3384
0
         && ((sym_hash)->root.type == bfd_link_hash_defined
3385
0
       || (sym_hash)->root.type == bfd_link_hash_defweak)
3386
0
         && (sym_hash)->root.u.def.section == sec
3387
0
         && (sym_hash)->root.u.def.value < addr + count)
3388
0
  {
3389
0
    if ((sym_hash)->root.u.def.value+isym.st_size >= addr + count
3390
0
        && (sym_hash)->root.u.def.value+isym.st_size < toaddr)
3391
0
      isym.st_size -= count;
3392
3393
0
    if ((sym_hash)->root.u.def.value >= addr
3394
0
        && (sym_hash)->root.u.def.value < addr + count)
3395
0
      (sym_hash)->root.u.def.value = addr;
3396
3397
0
    bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
3398
0
  }
3399
3400
0
      if (shndx)
3401
0
  ++ shndx;
3402
0
    }
3403
3404
0
  return true;
3405
0
}
3406
3407
#define NOP_OPCODE  (0x0000)
3408
0
#define MOVHI   0x0640        /* 4byte.  */
3409
0
#define MOVHI_MASK  0x07e0
3410
0
#define MOVHI_R1(insn)  ((insn) & 0x1f)      /* 4byte.  */
3411
0
#define MOVHI_R2(insn)  ((insn) >> 11)
3412
0
#define MOVEA   0x0620        /* 2byte.  */
3413
0
#define MOVEA_MASK  0x07e0
3414
0
#define MOVEA_R1(insn)  ((insn) & 0x1f)
3415
0
#define MOVEA_R2(insn)  ((insn) >> 11)
3416
0
#define JARL_4    0x00040780        /* 4byte.  */
3417
0
#define JARL_4_MASK 0xFFFF07FF
3418
0
#define JARL_R2(insn) (int)(((insn) & (~JARL_4_MASK)) >> 11)
3419
0
#define ADD_I   0x0240          /* 2byte.  */
3420
0
#define ADD_I_MASK  0x07e0
3421
0
#define ADD_I5(insn)  ((((insn) & 0x001f) << 11) >> 11)  /* 2byte.  */
3422
0
#define ADD_R2(insn)  ((insn) >> 11)
3423
0
#define JMP_R   0x0060          /* 2byte.  */
3424
0
#define JMP_R_MASK  0xFFE0
3425
0
#define JMP_R1(insn)  ((insn) & 0x1f)
3426
3427
static bool
3428
v850_elf_relax_section (bfd *abfd,
3429
      asection *sec,
3430
      struct bfd_link_info *link_info,
3431
      bool *again)
3432
0
{
3433
0
  Elf_Internal_Shdr *symtab_hdr;
3434
0
  Elf_Internal_Rela *internal_relocs;
3435
0
  Elf_Internal_Rela *irel;
3436
0
  Elf_Internal_Rela *irelend;
3437
0
  Elf_Internal_Rela *irelalign = NULL;
3438
0
  Elf_Internal_Sym *isymbuf = NULL;
3439
0
  bfd_byte *contents = NULL;
3440
0
  bfd_vma addr = 0;
3441
0
  bfd_vma toaddr;
3442
0
  int align_pad_size = 0;
3443
0
  bool result = true;
3444
3445
0
  *again = false;
3446
3447
0
  if (bfd_link_relocatable (link_info)
3448
0
      || (sec->flags & SEC_HAS_CONTENTS) == 0
3449
0
      || (sec->flags & SEC_RELOC) == 0
3450
0
      || sec->reloc_count == 0)
3451
0
    return true;
3452
3453
0
  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
3454
3455
0
  internal_relocs = (_bfd_elf_link_read_relocs
3456
0
         (abfd, sec, NULL, NULL, link_info->keep_memory));
3457
0
  if (internal_relocs == NULL)
3458
0
    goto error_return;
3459
3460
0
  irelend = internal_relocs + sec->reloc_count;
3461
3462
0
  while (addr < sec->size)
3463
0
    {
3464
0
      toaddr = sec->size;
3465
3466
0
      for (irel = internal_relocs; irel < irelend; irel ++)
3467
0
  if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
3468
0
      && irel->r_offset > addr
3469
0
      && irel->r_offset < toaddr)
3470
0
    toaddr = irel->r_offset;
3471
3472
#ifdef DEBUG_RELAX
3473
      fprintf (stderr, "relax region 0x%x to 0x%x align pad %d\n",
3474
         addr, toaddr, align_pad_size);
3475
#endif
3476
0
      if (irelalign)
3477
0
  {
3478
0
    bfd_vma alignto;
3479
0
    bfd_vma alignmoveto;
3480
3481
0
    alignmoveto = BFD_ALIGN (addr - align_pad_size, 1 << irelalign->r_addend);
3482
0
    alignto = BFD_ALIGN (addr, 1 << irelalign->r_addend);
3483
3484
0
    if (alignmoveto < alignto)
3485
0
      {
3486
0
        bfd_vma i;
3487
3488
0
        align_pad_size = alignto - alignmoveto;
3489
#ifdef DEBUG_RELAX
3490
        fprintf (stderr, "relax move region 0x%x to 0x%x delete size 0x%x\n",
3491
           alignmoveto, toaddr, align_pad_size);
3492
#endif
3493
0
        if (!v850_elf_relax_delete_bytes (abfd, sec, alignmoveto,
3494
0
            toaddr, align_pad_size))
3495
0
    goto error_return;
3496
3497
0
        for (i  = BFD_ALIGN (toaddr - align_pad_size, 1);
3498
0
       (i + 1) < toaddr; i += 2)
3499
0
    bfd_put_16 (abfd, NOP_OPCODE, contents + i);
3500
3501
0
        addr = alignmoveto;
3502
0
      }
3503
0
    else
3504
0
      align_pad_size = 0;
3505
0
  }
3506
3507
0
      for (irel = internal_relocs; irel < irelend; irel++)
3508
0
  {
3509
0
    bfd_vma laddr;
3510
0
    bfd_vma addend;
3511
0
    bfd_vma symval;
3512
0
    int insn[5];
3513
0
    int no_match = -1;
3514
0
    Elf_Internal_Rela *hi_irelfn;
3515
0
    Elf_Internal_Rela *lo_irelfn;
3516
0
    Elf_Internal_Rela *irelcall;
3517
0
    bfd_signed_vma foff;
3518
0
    unsigned int r_type;
3519
3520
0
    if (! (irel->r_offset >= addr && irel->r_offset < toaddr
3521
0
     && (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL
3522
0
         || ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)))
3523
0
      continue;
3524
3525
#ifdef DEBUG_RELAX
3526
    fprintf (stderr, "relax check r_info 0x%x r_offset 0x%x r_addend 0x%x\n",
3527
       irel->r_info,
3528
       irel->r_offset,
3529
       irel->r_addend );
3530
#endif
3531
3532
    /* Get the section contents.  */
3533
0
    if (contents == NULL)
3534
0
      {
3535
0
        if (elf_section_data (sec)->this_hdr.contents != NULL)
3536
0
    contents = elf_section_data (sec)->this_hdr.contents;
3537
0
        else
3538
0
    {
3539
0
      if (! bfd_malloc_and_get_section (abfd, sec, &contents))
3540
0
        goto error_return;
3541
0
    }
3542
0
      }
3543
3544
    /* Read this BFD's local symbols if we haven't done so already.  */
3545
0
    if (isymbuf == NULL && symtab_hdr->sh_info != 0)
3546
0
      {
3547
0
        isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
3548
0
        if (isymbuf == NULL)
3549
0
    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
3550
0
            symtab_hdr->sh_info, 0,
3551
0
            NULL, NULL, NULL);
3552
0
        if (isymbuf == NULL)
3553
0
    goto error_return;
3554
0
      }
3555
3556
0
    laddr = irel->r_offset;
3557
3558
0
    if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL)
3559
0
      {
3560
        /* Check code for -mlong-calls output. */
3561
0
        if (laddr + 16 <= (bfd_vma) sec->size)
3562
0
    {
3563
0
      insn[0] = bfd_get_16 (abfd, contents + laddr);
3564
0
      insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
3565
0
      insn[2] = bfd_get_32 (abfd, contents + laddr + 8);
3566
0
      insn[3] = bfd_get_16 (abfd, contents + laddr + 12);
3567
0
      insn[4] = bfd_get_16 (abfd, contents + laddr + 14);
3568
3569
0
      if ((insn[0] & MOVHI_MASK) != MOVHI
3570
0
           || MOVHI_R1 (insn[0]) != 0)
3571
0
        no_match = 0;
3572
3573
0
      if (no_match < 0
3574
0
          && ((insn[1] & MOVEA_MASK) != MOVEA
3575
0
         || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
3576
0
        no_match = 1;
3577
3578
0
      if (no_match < 0
3579
0
          && (insn[2] & JARL_4_MASK) != JARL_4)
3580
0
        no_match = 2;
3581
3582
0
      if (no_match < 0
3583
0
          && ((insn[3] & ADD_I_MASK) != ADD_I
3584
0
         || ADD_I5 (insn[3]) != 4
3585
0
         || JARL_R2 (insn[2]) != ADD_R2 (insn[3])))
3586
0
        no_match = 3;
3587
3588
0
      if (no_match < 0
3589
0
          && ((insn[4] & JMP_R_MASK) != JMP_R
3590
0
         || MOVEA_R2 (insn[1]) != JMP_R1 (insn[4])))
3591
0
        no_match = 4;
3592
0
    }
3593
0
        else
3594
0
    {
3595
0
      _bfd_error_handler
3596
        /* xgettext:c-format */
3597
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3598
0
           "unrecognized insns"),
3599
0
         abfd, (uint64_t) irel->r_offset, "R_V850_LONGCALL");
3600
0
      continue;
3601
0
    }
3602
3603
0
        if (no_match >= 0)
3604
0
    {
3605
0
      _bfd_error_handler
3606
        /* xgettext:c-format */
3607
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3608
0
           "unrecognized insn %#x"),
3609
0
         abfd,
3610
0
         (uint64_t) (irel->r_offset + no_match),
3611
0
         "R_V850_LONGCALL",
3612
0
         insn[no_match]);
3613
0
      continue;
3614
0
    }
3615
3616
        /* Get the reloc for the address from which the register is
3617
     being loaded.  This reloc will tell us which function is
3618
     actually being called.  */
3619
3620
0
        for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
3621
0
    {
3622
0
      r_type = ELF32_R_TYPE (hi_irelfn->r_info);
3623
3624
0
      if (hi_irelfn->r_offset == laddr + 2
3625
0
          && (r_type == (int) R_V850_HI16_S || r_type == (int) R_V810_WHI1))
3626
0
        break;
3627
0
    }
3628
3629
0
        for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
3630
0
    {
3631
0
      r_type = ELF32_R_TYPE (lo_irelfn->r_info);
3632
3633
0
      if (lo_irelfn->r_offset == laddr + 6
3634
0
          && (r_type == (int) R_V850_LO16 || r_type == (int) R_V810_WLO))
3635
0
        break;
3636
0
    }
3637
3638
0
        for (irelcall = internal_relocs; irelcall < irelend; irelcall ++)
3639
0
    {
3640
0
      r_type = ELF32_R_TYPE (irelcall->r_info);
3641
3642
0
      if (irelcall->r_offset == laddr + 8
3643
0
          && (r_type == (int) R_V850_22_PCREL || r_type == (int) R_V850_PCR22))
3644
0
        break;
3645
0
    }
3646
3647
0
        if (   hi_irelfn == irelend
3648
0
      || lo_irelfn == irelend
3649
0
      || irelcall  == irelend)
3650
0
    {
3651
0
      _bfd_error_handler
3652
        /* xgettext:c-format */
3653
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3654
0
           "unrecognized reloc"),
3655
0
         abfd, (uint64_t) irel->r_offset, "R_V850_LONGCALL");
3656
3657
0
      continue;
3658
0
    }
3659
3660
0
        if (ELF32_R_SYM (irelcall->r_info) < symtab_hdr->sh_info)
3661
0
    {
3662
0
      Elf_Internal_Sym *  isym;
3663
3664
      /* A local symbol.  */
3665
0
      isym = isymbuf + ELF32_R_SYM (irelcall->r_info);
3666
3667
0
      symval = isym->st_value;
3668
0
    }
3669
0
        else
3670
0
    {
3671
0
      unsigned long indx;
3672
0
      struct elf_link_hash_entry * h;
3673
3674
      /* An external symbol.  */
3675
0
      indx = ELF32_R_SYM (irelcall->r_info) - symtab_hdr->sh_info;
3676
0
      h = elf_sym_hashes (abfd)[indx];
3677
0
      BFD_ASSERT (h != NULL);
3678
3679
0
      if (   h->root.type != bfd_link_hash_defined
3680
0
          && h->root.type != bfd_link_hash_defweak)
3681
        /* This appears to be a reference to an undefined
3682
           symbol.  Just ignore it--it will be caught by the
3683
           regular reloc processing.  */
3684
0
        continue;
3685
3686
0
      symval = h->root.u.def.value;
3687
0
    }
3688
3689
0
        if (symval + irelcall->r_addend != irelcall->r_offset + 4)
3690
0
    {
3691
0
      _bfd_error_handler
3692
        /* xgettext:c-format */
3693
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3694
0
           "unrecognized reloc %#" PRIx64),
3695
0
         abfd, (uint64_t) irel->r_offset, "R_V850_LONGCALL",
3696
0
         (uint64_t) irelcall->r_offset);
3697
0
      continue;
3698
0
    }
3699
3700
        /* Get the value of the symbol referred to by the reloc.  */
3701
0
        if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3702
0
    {
3703
0
      Elf_Internal_Sym *isym;
3704
0
      asection *sym_sec;
3705
3706
      /* A local symbol.  */
3707
0
      isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
3708
3709
0
      if (isym->st_shndx == SHN_UNDEF)
3710
0
        sym_sec = bfd_und_section_ptr;
3711
0
      else if (isym->st_shndx == SHN_ABS)
3712
0
        sym_sec = bfd_abs_section_ptr;
3713
0
      else if (isym->st_shndx == SHN_COMMON)
3714
0
        sym_sec = bfd_com_section_ptr;
3715
0
      else
3716
0
        sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3717
0
      symval = (isym->st_value
3718
0
          + sym_sec->output_section->vma
3719
0
          + sym_sec->output_offset);
3720
0
    }
3721
0
        else
3722
0
    {
3723
0
      unsigned long indx;
3724
0
      struct elf_link_hash_entry *h;
3725
3726
      /* An external symbol.  */
3727
0
      indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info;
3728
0
      h = elf_sym_hashes (abfd)[indx];
3729
0
      BFD_ASSERT (h != NULL);
3730
3731
0
      if (   h->root.type != bfd_link_hash_defined
3732
0
          && h->root.type != bfd_link_hash_defweak)
3733
        /* This appears to be a reference to an undefined
3734
           symbol.  Just ignore it--it will be caught by the
3735
           regular reloc processing.  */
3736
0
        continue;
3737
3738
0
      symval = (h->root.u.def.value
3739
0
          + h->root.u.def.section->output_section->vma
3740
0
          + h->root.u.def.section->output_offset);
3741
0
    }
3742
3743
0
        addend = irel->r_addend;
3744
3745
0
        foff = (symval + addend
3746
0
          - (irel->r_offset
3747
0
       + sec->output_section->vma
3748
0
       + sec->output_offset
3749
0
       + 4));
3750
#ifdef DEBUG_RELAX
3751
        fprintf (stderr, "relax longcall r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
3752
           irel->r_offset,
3753
           (irel->r_offset
3754
      + sec->output_section->vma
3755
      + sec->output_offset),
3756
           symval, addend, foff);
3757
#endif
3758
3759
0
        if (foff < -0x100000 || foff >= 0x100000)
3760
    /* After all that work, we can't shorten this function call.  */
3761
0
    continue;
3762
3763
        /* For simplicity of coding, we are going to modify the section
3764
     contents, the section relocs, and the BFD symbol table.  We
3765
     must tell the rest of the code not to free up this
3766
     information.  It would be possible to instead create a table
3767
     of changes which have to be made, as is done in coff-mips.c;
3768
     that would be more work, but would require less memory when
3769
     the linker is run.  */
3770
0
        elf_section_data (sec)->relocs = internal_relocs;
3771
0
        elf_section_data (sec)->this_hdr.contents = contents;
3772
0
        symtab_hdr->contents = (bfd_byte *) isymbuf;
3773
3774
        /* Replace the long call with a jarl.  */
3775
0
        if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
3776
0
    irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_PCR22);
3777
0
        else
3778
0
    irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_22_PCREL);
3779
3780
0
        addend = 0;
3781
3782
0
        if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3783
    /* If this needs to be changed because of future relaxing,
3784
       it will be handled here like other internal IND12W
3785
       relocs.  */
3786
0
    bfd_put_32 (abfd,
3787
0
          0x00000780 | (JARL_R2 (insn[2])<<11) | ((addend << 16) & 0xffff) | ((addend >> 16) & 0xf),
3788
0
          contents + irel->r_offset);
3789
0
        else
3790
    /* We can't fully resolve this yet, because the external
3791
       symbol value may be changed by future relaxing.
3792
       We let the final link phase handle it.  */
3793
0
    bfd_put_32 (abfd, 0x00000780 | (JARL_R2 (insn[2])<<11),
3794
0
          contents + irel->r_offset);
3795
3796
0
        hi_irelfn->r_info =
3797
0
    ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
3798
0
        lo_irelfn->r_info =
3799
0
    ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
3800
0
        irelcall->r_info =
3801
0
    ELF32_R_INFO (ELF32_R_SYM (irelcall->r_info), R_V850_NONE);
3802
3803
0
        if (! v850_elf_relax_delete_bytes (abfd, sec,
3804
0
             irel->r_offset + 4, toaddr, 12))
3805
0
    goto error_return;
3806
3807
0
        align_pad_size += 12;
3808
0
      }
3809
0
    else if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)
3810
0
      {
3811
        /* Check code for -mlong-jumps output.  */
3812
0
        if (laddr + 10 <= (bfd_vma) sec->size)
3813
0
    {
3814
0
      insn[0] = bfd_get_16 (abfd, contents + laddr);
3815
0
      insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
3816
0
      insn[2] = bfd_get_16 (abfd, contents + laddr + 8);
3817
3818
0
      if ((insn[0] & MOVHI_MASK) != MOVHI
3819
0
           || MOVHI_R1 (insn[0]) != 0)
3820
0
        no_match = 0;
3821
3822
0
      if (no_match < 0
3823
0
          && ((insn[1] & MOVEA_MASK) != MOVEA
3824
0
         || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
3825
0
        no_match = 1;
3826
3827
0
      if (no_match < 0
3828
0
          && ((insn[2] & JMP_R_MASK) != JMP_R
3829
0
         || MOVEA_R2 (insn[1]) != JMP_R1 (insn[2])))
3830
0
        no_match = 2;
3831
0
    }
3832
0
        else
3833
0
    {
3834
0
      _bfd_error_handler
3835
        /* xgettext:c-format */
3836
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3837
0
           "unrecognized insns"),
3838
0
         abfd, (uint64_t) irel->r_offset, "R_V850_LONGJUMP");
3839
0
      continue;
3840
0
    }
3841
3842
0
        if (no_match >= 0)
3843
0
    {
3844
0
      _bfd_error_handler
3845
        /* xgettext:c-format */
3846
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3847
0
           "unrecognized insn %#x"),
3848
0
         abfd,
3849
0
         (uint64_t) (irel->r_offset + no_match),
3850
0
         "R_V850_LONGJUMP",
3851
0
         insn[no_match]);
3852
0
      continue;
3853
0
    }
3854
3855
        /* Get the reloc for the address from which the register is
3856
     being loaded.  This reloc will tell us which function is
3857
     actually being called.  */
3858
0
        for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
3859
0
    {
3860
0
      r_type = ELF32_R_TYPE (hi_irelfn->r_info);
3861
3862
0
      if (hi_irelfn->r_offset == laddr + 2
3863
0
          && ((r_type == (int) R_V850_HI16_S) || r_type == (int) R_V810_WHI1))
3864
0
        break;
3865
0
    }
3866
3867
0
        for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
3868
0
    {
3869
0
      r_type = ELF32_R_TYPE (lo_irelfn->r_info);
3870
3871
0
      if (lo_irelfn->r_offset == laddr + 6
3872
0
          && (r_type == (int) R_V850_LO16 || r_type == (int) R_V810_WLO))
3873
0
        break;
3874
0
    }
3875
3876
0
        if (   hi_irelfn == irelend
3877
0
      || lo_irelfn == irelend)
3878
0
    {
3879
0
      _bfd_error_handler
3880
        /* xgettext:c-format */
3881
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3882
0
           "unrecognized reloc"),
3883
0
         abfd, (uint64_t) irel->r_offset, "R_V850_LONGJUMP");
3884
0
      continue;
3885
0
    }
3886
3887
        /* Get the value of the symbol referred to by the reloc.  */
3888
0
        if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3889
0
    {
3890
0
      Elf_Internal_Sym *  isym;
3891
0
      asection *        sym_sec;
3892
3893
      /* A local symbol.  */
3894
0
      isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
3895
3896
0
      if (isym->st_shndx == SHN_UNDEF)
3897
0
        sym_sec = bfd_und_section_ptr;
3898
0
      else if (isym->st_shndx == SHN_ABS)
3899
0
        sym_sec = bfd_abs_section_ptr;
3900
0
      else if (isym->st_shndx == SHN_COMMON)
3901
0
        sym_sec = bfd_com_section_ptr;
3902
0
      else
3903
0
        sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3904
0
      symval = (isym->st_value
3905
0
          + sym_sec->output_section->vma
3906
0
          + sym_sec->output_offset);
3907
#ifdef DEBUG_RELAX
3908
      {
3909
        char * name = bfd_elf_string_from_elf_section
3910
          (abfd, symtab_hdr->sh_link, isym->st_name);
3911
3912
        fprintf (stderr, "relax long jump local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
3913
           sym_sec->name, name, isym->st_name,
3914
           sym_sec->output_section->vma,
3915
           sym_sec->output_offset,
3916
           isym->st_value, irel->r_addend);
3917
      }
3918
#endif
3919
0
    }
3920
0
        else
3921
0
    {
3922
0
      unsigned long indx;
3923
0
      struct elf_link_hash_entry * h;
3924
3925
      /* An external symbol.  */
3926
0
      indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
3927
0
      h = elf_sym_hashes (abfd)[indx];
3928
0
      BFD_ASSERT (h != NULL);
3929
3930
0
      if (   h->root.type != bfd_link_hash_defined
3931
0
          && h->root.type != bfd_link_hash_defweak)
3932
        /* This appears to be a reference to an undefined
3933
           symbol.  Just ignore it--it will be caught by the
3934
           regular reloc processing.  */
3935
0
        continue;
3936
3937
0
      symval = (h->root.u.def.value
3938
0
          + h->root.u.def.section->output_section->vma
3939
0
          + h->root.u.def.section->output_offset);
3940
#ifdef DEBUG_RELAX
3941
      fprintf (stderr,
3942
         "relax longjump defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
3943
         sec->name, h->root.root.string, h->root.u.def.value,
3944
         sec->output_section->vma, sec->output_offset, irel->r_addend);
3945
#endif
3946
0
    }
3947
3948
0
        addend = irel->r_addend;
3949
3950
0
        foff = (symval + addend
3951
0
          - (irel->r_offset
3952
0
       + sec->output_section->vma
3953
0
       + sec->output_offset
3954
0
       + 4));
3955
#ifdef DEBUG_RELAX
3956
        fprintf (stderr, "relax longjump r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
3957
           irel->r_offset,
3958
           (irel->r_offset
3959
      + sec->output_section->vma
3960
      + sec->output_offset),
3961
           symval, addend, foff);
3962
#endif
3963
0
        if (foff < -0x100000 || foff >= 0x100000)
3964
    /* After all that work, we can't shorten this function call.  */
3965
0
    continue;
3966
3967
        /* For simplicity of coding, we are going to modify the section
3968
     contents, the section relocs, and the BFD symbol table.  We
3969
     must tell the rest of the code not to free up this
3970
     information.  It would be possible to instead create a table
3971
     of changes which have to be made, as is done in coff-mips.c;
3972
     that would be more work, but would require less memory when
3973
     the linker is run.  */
3974
0
        elf_section_data (sec)->relocs = internal_relocs;
3975
0
        elf_section_data (sec)->this_hdr.contents = contents;
3976
0
        symtab_hdr->contents = (bfd_byte *) isymbuf;
3977
3978
0
        if (foff < -0x100 || foff >= 0x100)
3979
0
    {
3980
      /* Replace the long jump with a jr.  */
3981
3982
0
      if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
3983
0
        irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_PCR22);
3984
0
      else
3985
0
        irel->r_info =
3986
0
          ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_22_PCREL);
3987
3988
0
      irel->r_addend = addend;
3989
0
      addend = 0;
3990
3991
0
      if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3992
        /* If this needs to be changed because of future relaxing,
3993
           it will be handled here like other internal IND12W
3994
           relocs.  */
3995
0
        bfd_put_32 (abfd,
3996
0
        0x00000780 | ((addend << 15) & 0xffff0000) | ((addend >> 17) & 0xf),
3997
0
        contents + irel->r_offset);
3998
0
      else
3999
        /* We can't fully resolve this yet, because the external
4000
           symbol value may be changed by future relaxing.
4001
           We let the final link phase handle it.  */
4002
0
        bfd_put_32 (abfd, 0x00000780, contents + irel->r_offset);
4003
4004
0
      hi_irelfn->r_info =
4005
0
      ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
4006
0
      lo_irelfn->r_info =
4007
0
      ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
4008
0
      if (!v850_elf_relax_delete_bytes (abfd, sec,
4009
0
                irel->r_offset + 4, toaddr, 6))
4010
0
        goto error_return;
4011
4012
0
      align_pad_size += 6;
4013
0
    }
4014
0
        else
4015
0
    {
4016
      /* Replace the long jump with a br.  */
4017
4018
0
      if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
4019
0
        irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_PC9);
4020
0
      else
4021
0
        irel->r_info =
4022
0
          ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_9_PCREL);
4023
4024
0
      irel->r_addend = addend;
4025
0
      addend = 0;
4026
4027
0
      if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
4028
        /* If this needs to be changed because of future relaxing,
4029
           it will be handled here like other internal IND12W
4030
           relocs.  */
4031
0
        bfd_put_16 (abfd,
4032
0
        0x0585 | ((addend << 10) & 0xf800) | ((addend << 3) & 0x0070),
4033
0
        contents + irel->r_offset);
4034
0
      else
4035
        /* We can't fully resolve this yet, because the external
4036
           symbol value may be changed by future relaxing.
4037
           We let the final link phase handle it.  */
4038
0
        bfd_put_16 (abfd, 0x0585, contents + irel->r_offset);
4039
4040
0
      hi_irelfn->r_info =
4041
0
      ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
4042
0
      lo_irelfn->r_info =
4043
0
      ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
4044
0
      if (!v850_elf_relax_delete_bytes (abfd, sec,
4045
0
                irel->r_offset + 2, toaddr, 8))
4046
0
        goto error_return;
4047
4048
0
      align_pad_size += 8;
4049
0
    }
4050
0
      }
4051
0
  }
4052
4053
0
      irelalign = NULL;
4054
0
      for (irel = internal_relocs; irel < irelend; irel++)
4055
0
  {
4056
0
    if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
4057
0
        && irel->r_offset == toaddr)
4058
0
      {
4059
0
        irel->r_offset -= align_pad_size;
4060
4061
0
        if (irelalign == NULL || irelalign->r_addend > irel->r_addend)
4062
0
    irelalign = irel;
4063
0
      }
4064
0
  }
4065
4066
0
      addr = toaddr;
4067
0
    }
4068
4069
0
  if (!irelalign)
4070
0
    {
4071
#ifdef DEBUG_RELAX
4072
      fprintf (stderr, "relax pad %d shorten %d -> %d\n",
4073
         align_pad_size,
4074
         sec->size,
4075
         sec->size - align_pad_size);
4076
#endif
4077
0
      sec->size -= align_pad_size;
4078
0
    }
4079
4080
0
 finish:
4081
0
  if (elf_section_data (sec)->relocs != internal_relocs)
4082
0
    free (internal_relocs);
4083
4084
0
  if (elf_section_data (sec)->this_hdr.contents != (unsigned char *) contents)
4085
0
    free (contents);
4086
4087
0
  if (symtab_hdr->contents != (bfd_byte *) isymbuf)
4088
0
    free (isymbuf);
4089
4090
0
  return result;
4091
4092
0
 error_return:
4093
0
  result = false;
4094
0
  goto finish;
4095
0
}
4096
4097
static const struct bfd_elf_special_section v850_elf_special_sections[] =
4098
{
4099
  { STRING_COMMA_LEN (".call_table_data"), 0, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE) },
4100
  { STRING_COMMA_LEN (".call_table_text"), 0, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
4101
                 + SHF_EXECINSTR) },
4102
  { STRING_COMMA_LEN (".rosdata"),    -2, SHT_PROGBITS, (SHF_ALLOC
4103
                 + SHF_V850_GPREL) },
4104
  { STRING_COMMA_LEN (".rozdata"),    -2, SHT_PROGBITS, (SHF_ALLOC
4105
                 + SHF_V850_R0REL) },
4106
  { STRING_COMMA_LEN (".sbss"),     -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
4107
                 + SHF_V850_GPREL) },
4108
  { STRING_COMMA_LEN (".scommon"),    -2, SHT_V850_SCOMMON, (SHF_ALLOC + SHF_WRITE
4109
                 + SHF_V850_GPREL) },
4110
  { STRING_COMMA_LEN (".sdata"),    -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
4111
                 + SHF_V850_GPREL) },
4112
  { STRING_COMMA_LEN (".tbss"),     -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
4113
                 + SHF_V850_EPREL) },
4114
  { STRING_COMMA_LEN (".tcommon"),    -2, SHT_V850_TCOMMON, (SHF_ALLOC + SHF_WRITE
4115
                 + SHF_V850_R0REL) },
4116
  { STRING_COMMA_LEN (".tdata"),    -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
4117
                 + SHF_V850_EPREL) },
4118
  { STRING_COMMA_LEN (".zbss"),     -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
4119
                 + SHF_V850_R0REL) },
4120
  { STRING_COMMA_LEN (".zcommon"),    -2, SHT_V850_ZCOMMON, (SHF_ALLOC + SHF_WRITE
4121
                 + SHF_V850_R0REL) },
4122
  { STRING_COMMA_LEN (".zdata"),    -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
4123
                 + SHF_V850_R0REL) },
4124
  { NULL,         0,     0, 0,    0 }
4125
};
4126

4127
#define TARGET_LITTLE_SYM     v850_elf32_vec
4128
#define TARGET_LITTLE_NAME      "elf32-v850"
4129
#define ELF_ARCH        bfd_arch_v850
4130
#define ELF_MACHINE_CODE      EM_V850
4131
#define ELF_MACHINE_ALT1      EM_CYGNUS_V850
4132
#define ELF_MAXPAGESIZE       0x1000
4133
4134
#define elf_info_to_howto     v850_elf_info_to_howto_rela
4135
#define elf_info_to_howto_rel     v850_elf_info_to_howto_rel
4136
4137
#define elf_backend_check_relocs    v850_elf_check_relocs
4138
#define elf_backend_relocate_section    v850_elf_relocate_section
4139
#define elf_backend_object_p      v850_elf_object_p
4140
#define elf_backend_final_write_processing  v850_elf_final_write_processing
4141
#define elf_backend_section_from_bfd_section  v850_elf_section_from_bfd_section
4142
#define elf_backend_symbol_processing   v850_elf_symbol_processing
4143
#define elf_backend_add_symbol_hook   v850_elf_add_symbol_hook
4144
#define elf_backend_link_output_symbol_hook v850_elf_link_output_symbol_hook
4145
#define elf_backend_section_from_shdr   v850_elf_section_from_shdr
4146
#define elf_backend_fake_sections   v850_elf_fake_sections
4147
#define elf_backend_gc_mark_hook    v850_elf_gc_mark_hook
4148
#define elf_backend_special_sections    v850_elf_special_sections
4149
4150
#define elf_backend_can_gc_sections   1
4151
#define elf_backend_rela_normal     1
4152
4153
#define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
4154
#define bfd_elf32_bfd_is_target_special_symbol  v850_elf_is_target_special_symbol
4155
4156
#define bfd_elf32_bfd_reloc_type_lookup   v850_elf_reloc_type_lookup
4157
#define bfd_elf32_bfd_reloc_name_lookup   v850_elf_reloc_name_lookup
4158
#define bfd_elf32_bfd_merge_private_bfd_data  v850_elf_merge_private_bfd_data
4159
#define bfd_elf32_bfd_set_private_flags   v850_elf_set_private_flags
4160
#define bfd_elf32_bfd_print_private_bfd_data  v850_elf_print_private_bfd_data
4161
#define bfd_elf32_bfd_relax_section   v850_elf_relax_section
4162
4163
#define elf_symbol_leading_char     '_'
4164
4165
#undef  elf32_bed
4166
#define elf32_bed elf32_v850_bed
4167
4168
#include "elf32-target.h"
4169
4170
/* Map BFD reloc types to V800 ELF reloc types.  */
4171
4172
static const struct v850_elf_reloc_map v800_elf_reloc_map[] =
4173
{
4174
  { BFD_RELOC_NONE,         R_V810_NONE    },
4175
  { BFD_RELOC_8,          R_V810_BYTE    },
4176
  { BFD_RELOC_16,         R_V810_HWORD   },
4177
  { BFD_RELOC_32,         R_V810_WORD    },
4178
  { BFD_RELOC_LO16,         R_V810_WLO     },
4179
  { BFD_RELOC_HI16,         R_V810_WHI     },
4180
  { BFD_RELOC_HI16_S,         R_V810_WHI1    },
4181
  { BFD_RELOC_V850_32_PCREL,        R_V850_PC32    },
4182
  { BFD_RELOC_V850_22_PCREL,        R_V850_PCR22   },
4183
  { BFD_RELOC_V850_17_PCREL,        R_V850_PC17    },
4184
  { BFD_RELOC_V850_16_PCREL,        R_V850_PC16U   },
4185
  { BFD_RELOC_V850_9_PCREL,       R_V850_PC9     },
4186
  { BFD_RELOC_V850_LO16_S1,       R_V810_WLO_1   }, /* Or R_V850_HWLO or R_V850_HWLO_1.  */
4187
  { BFD_RELOC_V850_23,          R_V850_WLO23   },
4188
  { BFD_RELOC_V850_LO16_SPLIT_OFFSET, R_V850_BLO     },
4189
  { BFD_RELOC_V850_ZDA_16_16_OFFSET,  R_V810_HWORD   },
4190
  { BFD_RELOC_V850_TDA_16_16_OFFSET,  R_V810_HWORD   },
4191
  { BFD_RELOC_V850_SDA_16_16_OFFSET,  R_V810_HWORD   },
4192
  { BFD_RELOC_V850_SDA_15_16_OFFSET,  R_V810_GPWLO_1 }
4193
};
4194
4195
/* Map a bfd relocation into the appropriate howto structure.  */
4196
4197
static reloc_howto_type *
4198
v800_elf_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code)
4199
0
{
4200
0
  unsigned int i;
4201
4202
0
  BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_v850_rh850);
4203
4204
0
  for (i = ARRAY_SIZE (v800_elf_reloc_map); i --;)
4205
0
    if (v800_elf_reloc_map[i].bfd_reloc_val == code)
4206
0
      {
4207
0
  unsigned int elf_reloc_val = v800_elf_reloc_map[i].elf_reloc_val;
4208
0
  unsigned int idx = elf_reloc_val - R_V810_NONE;
4209
4210
0
  BFD_ASSERT (v800_elf_howto_table[idx].type == elf_reloc_val);
4211
4212
0
  return v800_elf_howto_table + idx;
4213
0
      }
4214
4215
#ifdef DEBUG
4216
  fprintf (stderr, "failed to find v800 equiv of bfd reloc code %d\n", code);
4217
#endif
4218
0
  return NULL;
4219
0
}
4220
4221
static reloc_howto_type *
4222
v800_elf_reloc_name_lookup (bfd * abfd, const char * r_name)
4223
0
{
4224
0
  unsigned int i;
4225
4226
0
  BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_v850_rh850);
4227
4228
0
  for (i = ARRAY_SIZE (v800_elf_howto_table); i--;)
4229
0
    if (v800_elf_howto_table[i].name != NULL
4230
0
  && strcasecmp (v800_elf_howto_table[i].name, r_name) == 0)
4231
0
      return v800_elf_howto_table + i;
4232
4233
0
  return NULL;
4234
0
}
4235
4236
4237
/* Set the howto pointer in CACHE_PTR for a V800 ELF reloc.  */
4238
4239
static bool
4240
v800_elf_info_to_howto (bfd *       abfd,
4241
      arelent *     cache_ptr,
4242
      Elf_Internal_Rela * dst)
4243
0
{
4244
0
  unsigned int r_type = ELF32_R_TYPE (dst->r_info);
4245
4246
0
  if (r_type == R_V800_NONE)
4247
0
    r_type = R_V810_NONE;
4248
4249
0
  if (bfd_get_arch (abfd) != bfd_arch_v850_rh850
4250
0
      || r_type >= (unsigned int) R_V800_max
4251
0
      || r_type < (unsigned int) R_V810_NONE
4252
0
      || (r_type - R_V810_NONE) >= ARRAY_SIZE (v800_elf_howto_table))
4253
0
    {
4254
      /* xgettext:c-format */
4255
0
      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
4256
0
        abfd, r_type);
4257
0
      bfd_set_error (bfd_error_bad_value);
4258
0
      return false;
4259
0
    }
4260
4261
0
  cache_ptr->howto = v800_elf_howto_table + (r_type - R_V810_NONE);
4262
  return true;
4263
0
}
4264

4265
#undef  TARGET_LITTLE_SYM
4266
#define TARGET_LITTLE_SYM     v800_elf32_vec
4267
#undef  TARGET_LITTLE_NAME
4268
#define TARGET_LITTLE_NAME      "elf32-v850-rh850"
4269
#undef  ELF_ARCH
4270
#define ELF_ARCH        bfd_arch_v850_rh850
4271
#undef  ELF_MACHINE_CODE
4272
#define ELF_MACHINE_CODE      EM_V800
4273
#undef  ELF_MACHINE_ALT1
4274
4275
#undef  elf32_bed
4276
#define elf32_bed elf32_v850_rh850_bed
4277
4278
#undef  elf_info_to_howto
4279
#define elf_info_to_howto     v800_elf_info_to_howto
4280
#undef  elf_info_to_howto_rel
4281
#define elf_info_to_howto_rel     NULL
4282
#undef  bfd_elf32_bfd_reloc_type_lookup
4283
#define bfd_elf32_bfd_reloc_type_lookup   v800_elf_reloc_type_lookup
4284
#undef  bfd_elf32_bfd_reloc_name_lookup
4285
#define bfd_elf32_bfd_reloc_name_lookup   v800_elf_reloc_name_lookup
4286
4287
#include "elf32-target.h"