Coverage Report

Created: 2023-08-28 06:26

/src/binutils-gdb/bfd/elf32-v850.c
Line
Count
Source (jump to first uncovered line)
1
/* V850-specific support for 32-bit ELF
2
   Copyright (C) 1996-2023 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
0
{
824
0
  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
0
  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
0
  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
0
  if (reloc->address > bfd_get_section_limit (abfd, isection))
850
0
    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_V850_COPY,       R_V850_COPY       },
1740
  { BFD_RELOC_V850_GLOB_DAT,       R_V850_GLOB_DAT     },
1741
  { BFD_RELOC_V850_JMP_SLOT,       R_V850_JMP_SLOT     },
1742
  { BFD_RELOC_V850_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
0
{
1896
0
  unsigned int r_type;
1897
1898
0
  r_type = ELF32_R_TYPE (dst->r_info);
1899
0
  if (r_type >= (unsigned int) R_V850_max)
1900
0
    {
1901
      /* xgettext:c-format */
1902
0
      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
1903
0
        abfd, r_type);
1904
0
      bfd_set_error (bfd_error_bad_value);
1905
0
      return false;
1906
0
    }
1907
0
  cache_ptr->howto = &v850_elf_howto_table[r_type];
1908
0
  return true;
1909
0
}
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
  return (   (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
1937
0
    || (name[0] == '_' &&  name[1] == '.' && name[2] == 'L' && name[3] == '_'));
1938
0
}
1939
1940
static bool
1941
v850_elf_is_target_special_symbol (bfd *abfd, asymbol *sym)
1942
0
{
1943
0
  return v850_elf_is_local_label_name (abfd, sym->name);
1944
0
}
1945

1946
/* We overload some of the bfd_reloc error codes for own purposes.  */
1947
0
#define bfd_reloc_gp_not_found    bfd_reloc_other
1948
0
#define bfd_reloc_ep_not_found    bfd_reloc_continue
1949
0
#define bfd_reloc_ctbp_not_found  (bfd_reloc_dangerous + 1)
1950
1951
/* Perform a relocation as part of a final link.  */
1952
1953
static bfd_reloc_status_type
1954
v850_elf_final_link_relocate (reloc_howto_type *howto,
1955
            bfd *input_bfd,
1956
            bfd *output_bfd ATTRIBUTE_UNUSED,
1957
            asection *input_section,
1958
            bfd_byte *contents,
1959
            bfd_vma offset,
1960
            bfd_vma value,
1961
            bfd_vma addend,
1962
            struct bfd_link_info *info,
1963
            asection *sym_sec,
1964
            int is_local ATTRIBUTE_UNUSED)
1965
0
{
1966
0
  unsigned int r_type = howto->type;
1967
0
  bfd_byte *hit_data = contents + offset;
1968
1969
  /* Adjust the value according to the relocation.  */
1970
0
  switch (r_type)
1971
0
    {
1972
0
    case R_V850_PC9:
1973
0
    case R_V850_9_PCREL:
1974
0
      value -= (input_section->output_section->vma
1975
0
    + input_section->output_offset);
1976
0
      value -= offset;
1977
0
      break;
1978
1979
0
    case R_V850_PC16U:
1980
0
    case R_V850_16_PCREL:
1981
0
      value -= (input_section->output_section->vma
1982
0
    + input_section->output_offset
1983
0
    + offset);
1984
1985
      /* If the sign extension will corrupt the value then we have overflowed.  */
1986
0
      if ((value & 0xffff0000) != 0xffff0000)
1987
0
  return bfd_reloc_overflow;
1988
1989
0
      break;
1990
1991
0
    case R_V850_PC17:
1992
0
    case R_V850_17_PCREL:
1993
0
      value -= (input_section->output_section->vma
1994
0
    + input_section->output_offset
1995
0
    + offset);
1996
1997
      /* If the sign extension will corrupt the value then we have overflowed.  */
1998
0
      if (((value & 0xffff0000) != 0x0) && ((value & 0xffff0000) != 0xffff0000))
1999
0
  return bfd_reloc_overflow;
2000
2001
0
      value = SEXT17 (value);
2002
0
      break;
2003
2004
0
    case R_V850_PCR22:
2005
0
    case R_V850_22_PCREL:
2006
0
      value -= (input_section->output_section->vma
2007
0
    + input_section->output_offset
2008
0
    + offset);
2009
2010
      /* If the sign extension will corrupt the value then we have overflowed.  */
2011
0
      if (((value & 0xffe00000) != 0x0) && ((value & 0xffe00000) != 0xffe00000))
2012
0
  return bfd_reloc_overflow;
2013
2014
      /* Only the bottom 22 bits of the PC are valid.  */
2015
0
      value = SEXT22 (value);
2016
0
      break;
2017
2018
0
    case R_V850_PC32:
2019
0
    case R_V850_32_PCREL:
2020
0
      value -= (input_section->output_section->vma
2021
0
    + input_section->output_offset
2022
0
    + offset);
2023
0
      break;
2024
2025
0
    case R_V850_32_ABS:
2026
0
    case R_V850_23:
2027
0
    case R_V850_HI16_S:
2028
0
    case R_V850_HI16:
2029
0
    case R_V850_LO16:
2030
0
    case R_V850_LO16_S1:
2031
0
    case R_V850_LO16_SPLIT_OFFSET:
2032
0
    case R_V850_16:
2033
0
    case R_V850_ABS32:
2034
0
    case R_V850_8:
2035
0
    case R_V810_BYTE:
2036
0
    case R_V810_HWORD:
2037
0
    case R_V810_WORD:
2038
0
    case R_V810_WLO:
2039
0
    case R_V810_WHI:
2040
0
    case R_V810_WHI1:
2041
0
    case R_V810_WLO_1:
2042
0
    case R_V850_WLO23:
2043
0
    case R_V850_BLO:
2044
0
      break;
2045
2046
0
    case R_V850_ZDA_15_16_OFFSET:
2047
0
    case R_V850_ZDA_16_16_OFFSET:
2048
0
    case R_V850_ZDA_16_16_SPLIT_OFFSET:
2049
0
      if (sym_sec == NULL)
2050
0
  return bfd_reloc_undefined;
2051
2052
0
      value -= sym_sec->output_section->vma;
2053
0
      break;
2054
2055
0
    case R_V850_SDA_15_16_OFFSET:
2056
0
    case R_V850_SDA_16_16_OFFSET:
2057
0
    case R_V850_SDA_16_16_SPLIT_OFFSET:
2058
0
    case R_V810_GPWLO_1:
2059
0
      {
2060
0
  unsigned long        gp;
2061
0
  struct bfd_link_hash_entry * h;
2062
2063
0
  if (sym_sec == NULL)
2064
0
    return bfd_reloc_undefined;
2065
2066
  /* Get the value of __gp.  */
2067
0
  h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
2068
0
  if (h == NULL
2069
0
      || h->type != bfd_link_hash_defined)
2070
0
    return bfd_reloc_gp_not_found;
2071
2072
0
  gp = (h->u.def.value
2073
0
        + h->u.def.section->output_section->vma
2074
0
        + h->u.def.section->output_offset);
2075
2076
0
  value -= sym_sec->output_section->vma;
2077
0
  value -= (gp - sym_sec->output_section->vma);
2078
0
      }
2079
0
    break;
2080
2081
0
    case R_V850_TDA_4_4_OFFSET:
2082
0
    case R_V850_TDA_4_5_OFFSET:
2083
0
    case R_V850_TDA_7_7_OFFSET:
2084
0
    case R_V850_TDA_7_8_OFFSET:
2085
0
    case R_V850_TDA_6_8_OFFSET:
2086
0
    case R_V850_TDA_16_16_OFFSET:
2087
0
      {
2088
0
  unsigned long        ep;
2089
0
  struct bfd_link_hash_entry * h;
2090
2091
  /* Get the value of __ep.  */
2092
0
  h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
2093
0
  if (h == NULL
2094
0
      || h->type != bfd_link_hash_defined)
2095
0
    return bfd_reloc_ep_not_found;
2096
2097
0
  ep = (h->u.def.value
2098
0
        + h->u.def.section->output_section->vma
2099
0
        + h->u.def.section->output_offset);
2100
2101
0
  value -= ep;
2102
0
      }
2103
0
    break;
2104
2105
0
    case R_V850_CALLT_6_7_OFFSET:
2106
0
      {
2107
0
  unsigned long        ctbp;
2108
0
  struct bfd_link_hash_entry * h;
2109
2110
  /* Get the value of __ctbp.  */
2111
0
  h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
2112
0
  if (h == NULL
2113
0
      || h->type != bfd_link_hash_defined)
2114
0
    return bfd_reloc_ctbp_not_found;
2115
2116
0
  ctbp = (h->u.def.value
2117
0
        + h->u.def.section->output_section->vma
2118
0
        + h->u.def.section->output_offset);
2119
0
  value -= ctbp;
2120
0
      }
2121
0
    break;
2122
2123
0
    case R_V850_CALLT_15_16_OFFSET:
2124
0
    case R_V850_CALLT_16_16_OFFSET:
2125
0
      {
2126
0
  unsigned long        ctbp;
2127
0
  struct bfd_link_hash_entry * h;
2128
2129
0
  if (sym_sec == NULL)
2130
0
    return bfd_reloc_undefined;
2131
2132
  /* Get the value of __ctbp.  */
2133
0
  h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
2134
0
  if (h == NULL
2135
0
      || h->type != bfd_link_hash_defined)
2136
0
    return bfd_reloc_ctbp_not_found;
2137
2138
0
  ctbp = (h->u.def.value
2139
0
        + h->u.def.section->output_section->vma
2140
0
        + h->u.def.section->output_offset);
2141
2142
0
  value -= sym_sec->output_section->vma;
2143
0
  value -= (ctbp - sym_sec->output_section->vma);
2144
0
      }
2145
0
    break;
2146
2147
0
    case R_V850_NONE:
2148
0
    case R_V810_NONE:
2149
0
    case R_V850_GNU_VTINHERIT:
2150
0
    case R_V850_GNU_VTENTRY:
2151
0
    case R_V850_LONGCALL:
2152
0
    case R_V850_LONGJUMP:
2153
0
    case R_V850_ALIGN:
2154
0
      return bfd_reloc_ok;
2155
2156
0
    default:
2157
#ifdef DEBUG
2158
      _bfd_error_handler ("%pB: unsupported relocation type %#x",
2159
         input_bfd, r_type);
2160
#endif
2161
0
      return bfd_reloc_notsupported;
2162
0
    }
2163
2164
  /* Perform the relocation.  */
2165
0
  return v850_elf_perform_relocation (input_bfd, r_type, value + addend, hit_data);
2166
0
}
2167

2168
/* Relocate an V850 ELF section.  */
2169
2170
static int
2171
v850_elf_relocate_section (bfd *output_bfd,
2172
         struct bfd_link_info *info,
2173
         bfd *input_bfd,
2174
         asection *input_section,
2175
         bfd_byte *contents,
2176
         Elf_Internal_Rela *relocs,
2177
         Elf_Internal_Sym *local_syms,
2178
         asection **local_sections)
2179
0
{
2180
0
  Elf_Internal_Shdr *symtab_hdr;
2181
0
  struct elf_link_hash_entry **sym_hashes;
2182
0
  Elf_Internal_Rela *rel;
2183
0
  Elf_Internal_Rela *relend;
2184
2185
0
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
2186
0
  sym_hashes = elf_sym_hashes (input_bfd);
2187
2188
  /* Reset the list of remembered HI16S relocs to empty.  */
2189
0
  free_hi16s     = previous_hi16s;
2190
0
  previous_hi16s = NULL;
2191
0
  hi16s_counter  = 0;
2192
2193
0
  rel    = relocs;
2194
0
  relend = relocs + input_section->reloc_count;
2195
0
  for (; rel < relend; rel++)
2196
0
    {
2197
0
      unsigned int r_type;
2198
0
      reloc_howto_type *howto;
2199
0
      unsigned long r_symndx;
2200
0
      Elf_Internal_Sym *sym;
2201
0
      asection *sec;
2202
0
      struct elf_link_hash_entry *h;
2203
0
      bfd_vma relocation;
2204
0
      bfd_reloc_status_type r;
2205
2206
0
      r_symndx = ELF32_R_SYM (rel->r_info);
2207
0
      r_type   = ELF32_R_TYPE (rel->r_info);
2208
2209
0
      if (r_type == R_V850_GNU_VTENTRY
2210
0
    || r_type == R_V850_GNU_VTINHERIT)
2211
0
  continue;
2212
2213
0
      if (bfd_get_arch (input_bfd) == bfd_arch_v850_rh850)
2214
0
  howto = v800_elf_howto_table + (r_type - R_V810_NONE);
2215
0
      else
2216
0
  howto = v850_elf_howto_table + r_type;
2217
2218
0
      BFD_ASSERT (r_type == howto->type);
2219
2220
0
      h = NULL;
2221
0
      sym = NULL;
2222
0
      sec = NULL;
2223
0
      if (r_symndx < symtab_hdr->sh_info)
2224
0
  {
2225
0
    sym = local_syms + r_symndx;
2226
0
    sec = local_sections[r_symndx];
2227
0
    relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2228
0
  }
2229
0
      else
2230
0
  {
2231
0
    bool unresolved_reloc, warned, ignored;
2232
2233
    /* Note - this check is delayed until now as it is possible and
2234
       valid to have a file without any symbols but with relocs that
2235
       can be processed.  */
2236
0
    if (sym_hashes == NULL)
2237
0
      {
2238
0
        info->callbacks->warning
2239
0
    (info, "no hash table available",
2240
0
     NULL, input_bfd, input_section, (bfd_vma) 0);
2241
2242
0
        return false;
2243
0
      }
2244
2245
0
    RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2246
0
           r_symndx, symtab_hdr, sym_hashes,
2247
0
           h, sec, relocation,
2248
0
           unresolved_reloc, warned, ignored);
2249
0
  }
2250
2251
0
      if (sec != NULL && discarded_section (sec))
2252
0
  RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
2253
0
           rel, 1, relend, howto, 0, contents);
2254
2255
0
      if (bfd_link_relocatable (info))
2256
0
  continue;
2257
2258
      /* FIXME: We should use the addend, but the COFF relocations don't.  */
2259
0
      r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
2260
0
          input_section,
2261
0
          contents, rel->r_offset,
2262
0
          relocation, rel->r_addend,
2263
0
          info, sec, h == NULL);
2264
2265
0
      if (r != bfd_reloc_ok)
2266
0
  {
2267
0
    const char * name;
2268
0
    const char * msg = NULL;
2269
2270
0
    if (h != NULL)
2271
0
      name = h->root.root.string;
2272
0
    else
2273
0
      {
2274
0
        name = (bfd_elf_string_from_elf_section
2275
0
          (input_bfd, symtab_hdr->sh_link, sym->st_name));
2276
0
        if (name == NULL || *name == '\0')
2277
0
    name = bfd_section_name (sec);
2278
0
      }
2279
2280
0
    switch ((int) r)
2281
0
      {
2282
0
      case bfd_reloc_overflow:
2283
0
        (*info->callbacks->reloc_overflow)
2284
0
    (info, (h ? &h->root : NULL), name, howto->name,
2285
0
     (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
2286
0
        break;
2287
2288
0
      case bfd_reloc_undefined:
2289
0
        (*info->callbacks->undefined_symbol)
2290
0
    (info, name, input_bfd, input_section, rel->r_offset, true);
2291
0
        break;
2292
2293
0
      case bfd_reloc_outofrange:
2294
0
        msg = _("internal error: out of range error");
2295
0
        goto common_error;
2296
2297
0
      case bfd_reloc_notsupported:
2298
0
        msg = _("internal error: unsupported relocation error");
2299
0
        goto common_error;
2300
2301
0
      case bfd_reloc_dangerous:
2302
0
        msg = _("internal error: dangerous relocation");
2303
0
        goto common_error;
2304
2305
0
      case bfd_reloc_gp_not_found:
2306
0
        msg = _("could not locate special linker symbol __gp");
2307
0
        goto common_error;
2308
2309
0
      case bfd_reloc_ep_not_found:
2310
0
        msg = _("could not locate special linker symbol __ep");
2311
0
        goto common_error;
2312
2313
0
      case bfd_reloc_ctbp_not_found:
2314
0
        msg = _("could not locate special linker symbol __ctbp");
2315
0
        goto common_error;
2316
2317
0
      default:
2318
0
        msg = _("internal error: unknown error");
2319
        /* fall through */
2320
2321
0
      common_error:
2322
0
        (*info->callbacks->warning) (info, msg, name, input_bfd,
2323
0
             input_section, rel->r_offset);
2324
0
        break;
2325
0
      }
2326
0
  }
2327
0
    }
2328
2329
0
  return true;
2330
0
}
2331
2332
static asection *
2333
v850_elf_gc_mark_hook (asection *sec,
2334
           struct bfd_link_info *info,
2335
           Elf_Internal_Rela *rel,
2336
           struct elf_link_hash_entry *h,
2337
           Elf_Internal_Sym *sym)
2338
0
{
2339
0
  if (h != NULL)
2340
0
    switch (ELF32_R_TYPE (rel->r_info))
2341
0
      {
2342
0
      case R_V850_GNU_VTINHERIT:
2343
0
      case R_V850_GNU_VTENTRY:
2344
0
  return NULL;
2345
0
      }
2346
2347
0
  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2348
0
}
2349
2350
static void
2351
v850_set_note (bfd * abfd, asection * s, enum v850_notes note, unsigned int val)
2352
0
{
2353
0
  bfd_byte * data = s->contents + ((note - 1) * SIZEOF_V850_NOTE);
2354
2355
0
  bfd_put_32 (abfd, 4, data + 0);
2356
0
  bfd_put_32 (abfd, 4, data + 4);
2357
0
  bfd_put_32 (abfd, note, data + 8);
2358
0
  memcpy (data + 12, V850_NOTE_NAME, 4);
2359
0
  bfd_put_32 (abfd, val, data + 16);
2360
0
}
2361
2362
/* Create the note section if not already present.  This is done early so
2363
   that the linker maps the sections to the right place in the output.  */
2364
2365
static asection *
2366
v850_elf_make_note_section (bfd * abfd)
2367
0
{
2368
0
  asection *s;
2369
0
  bfd_byte *data;
2370
0
  flagword flags;
2371
0
  enum v850_notes id;
2372
2373
  /* Make the note section.  */
2374
0
  flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_MERGE;
2375
2376
0
  s = bfd_make_section_anyway_with_flags (abfd, V850_NOTE_SECNAME, flags);
2377
0
  if (s == NULL)
2378
0
    return NULL;
2379
2380
0
  if (!bfd_set_section_alignment (s, 2))
2381
0
    return NULL;
2382
2383
  /* Allocate space for all known notes.  */
2384
0
  if (!bfd_set_section_size (s, NUM_V850_NOTES * SIZEOF_V850_NOTE))
2385
0
    return NULL;
2386
2387
0
  data = bfd_zalloc (abfd, NUM_V850_NOTES * SIZEOF_V850_NOTE);
2388
0
  if (data == NULL)
2389
0
    return NULL;
2390
2391
0
  s->contents = data;
2392
2393
  /* Provide default (= uninitilaised) values for all of the notes.  */
2394
0
  for (id = V850_NOTE_ALIGNMENT; id <= NUM_V850_NOTES; id++)
2395
0
    v850_set_note (abfd, s, id,  0);
2396
2397
0
  return s;
2398
0
}
2399
2400
/* Create the note section if not already present.  This is done early so
2401
   that the linker maps the sections to the right place in the output.  */
2402
2403
bool
2404
v850_elf_create_sections (struct bfd_link_info * info)
2405
0
{
2406
0
  bfd * ibfd;
2407
2408
  /* If we already have a note section, do not make another.  */
2409
0
  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
2410
0
    if (bfd_get_section_by_name (ibfd, V850_NOTE_SECNAME) != NULL)
2411
0
      return true;
2412
2413
0
  return v850_elf_make_note_section (info->input_bfds) != NULL;
2414
0
}
2415
2416
bool
2417
v850_elf_set_note (bfd * abfd, unsigned int note, unsigned int val)
2418
0
{
2419
0
  asection * notes = bfd_get_section_by_name (abfd, V850_NOTE_SECNAME);
2420
2421
0
  if (val > 2)
2422
    /* At the moment, no known note has a value over 2.  */
2423
0
    return false;
2424
2425
0
  if (notes == NULL)
2426
0
    notes = v850_elf_make_note_section (abfd);
2427
0
  if (notes == NULL)
2428
0
    return false;
2429
2430
0
  v850_set_note (abfd, notes, note, val);
2431
0
  return true;
2432
0
}
2433
2434
/* Copy a v850 note section from one object module to another.  */
2435
2436
static void
2437
v850_elf_copy_notes (bfd *ibfd, bfd *obfd)
2438
0
{
2439
0
  asection * onotes;
2440
0
  asection * inotes;
2441
2442
  /* If the output bfd does not have a note section, then
2443
     skip the merge.  The normal input to output section
2444
     copying will take care of everythng for us.  */
2445
0
  if ((onotes = bfd_get_section_by_name (obfd, V850_NOTE_SECNAME)) == NULL)
2446
0
    return;
2447
2448
0
  if ((inotes = bfd_get_section_by_name (ibfd, V850_NOTE_SECNAME)) == NULL)
2449
0
    return;
2450
2451
0
  if (bfd_section_size (inotes) == bfd_section_size (onotes))
2452
0
    {
2453
0
      bfd_byte * icont;
2454
0
      bfd_byte * ocont;
2455
2456
0
      if ((icont = elf_section_data (inotes)->this_hdr.contents) == NULL)
2457
0
  BFD_ASSERT (bfd_malloc_and_get_section (ibfd, inotes, & icont));
2458
2459
0
      if ((ocont = elf_section_data (onotes)->this_hdr.contents) == NULL)
2460
  /* If the output is being stripped then it is possible for
2461
     the notes section to disappear.  In this case do nothing.  */
2462
0
  return;
2463
2464
      /* Copy/overwrite notes from the input to the output.  */
2465
0
      memcpy (ocont, icont, bfd_section_size (onotes));
2466
0
    }
2467
0
}
2468
2469
/* Copy backend specific data from one object module to another.  */
2470
2471
static bool
2472
v850_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
2473
0
{
2474
0
  v850_elf_copy_notes (ibfd, obfd);
2475
0
  return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
2476
0
}
2477
#define bfd_elf32_bfd_copy_private_bfd_data v850_elf_copy_private_bfd_data
2478
2479
static bool
2480
v850_elf_merge_notes (bfd * ibfd, bfd *obfd)
2481
0
{
2482
0
  asection * onotes;
2483
0
  asection * inotes;
2484
0
  bool result = true;
2485
2486
  /* If the output bfd does not have a note section, then
2487
     skip the merge.  The normal input to output section
2488
     copying will take care of everythng for us.  */
2489
0
  if ((onotes = bfd_get_section_by_name (obfd, V850_NOTE_SECNAME)) == NULL)
2490
0
    return true;
2491
2492
0
  if ((inotes = bfd_get_section_by_name (ibfd, V850_NOTE_SECNAME)) != NULL)
2493
0
    {
2494
0
      enum v850_notes id;
2495
0
      bfd_byte * icont;
2496
0
      bfd_byte * ocont;
2497
2498
0
      BFD_ASSERT (bfd_section_size (inotes) == bfd_section_size (onotes));
2499
2500
0
      if ((icont = elf_section_data (inotes)->this_hdr.contents) == NULL)
2501
0
  BFD_ASSERT (bfd_malloc_and_get_section (ibfd, inotes, & icont));
2502
2503
0
      if ((ocont = elf_section_data (onotes)->this_hdr.contents) == NULL)
2504
0
  BFD_ASSERT (bfd_malloc_and_get_section (obfd, onotes, & ocont));
2505
2506
0
      for (id = V850_NOTE_ALIGNMENT; id <= NUM_V850_NOTES; id++)
2507
0
  {
2508
0
    unsigned int ival;
2509
0
    unsigned int oval;
2510
0
    bfd_byte * idata = icont + ((id - 1) * SIZEOF_V850_NOTE) + 16;
2511
0
    bfd_byte * odata = ocont + ((id - 1) * SIZEOF_V850_NOTE) + 16;
2512
2513
0
    ival = bfd_get_32 (ibfd, idata);
2514
0
    oval = bfd_get_32 (obfd, odata);
2515
2516
0
    if (ival == 0 || ival == oval)
2517
0
      continue;
2518
2519
0
    if (oval == 0)
2520
0
      {
2521
0
        bfd_put_32 (obfd, ival, odata);
2522
0
        v850_set_note (obfd, onotes, id, ival);
2523
0
        continue;
2524
0
      }
2525
2526
    /* We have a mismatch.  The ABI defines how to handle
2527
       this siutation on a per note type basis.  */
2528
0
    switch (id)
2529
0
      {
2530
0
      case V850_NOTE_ALIGNMENT:
2531
0
        if (oval == EF_RH850_DATA_ALIGN4)
2532
0
    {
2533
0
      _bfd_error_handler
2534
        /* xgettext:c-format */
2535
0
        (_("error: %pB needs 8-byte alignment but %pB is set for 4-byte alignment"),
2536
0
              ibfd, obfd);
2537
0
      result = false;
2538
0
    }
2539
0
        else
2540
    /* ibfd uses 4-byte alignment, obfd uses 8-byte alignment.
2541
       Leave the obfd alignment as it is.  */
2542
0
    BFD_ASSERT (oval == EF_RH850_DATA_ALIGN8);
2543
2544
0
        break;
2545
2546
0
      case V850_NOTE_DATA_SIZE:
2547
0
        if (oval == EF_RH850_DOUBLE32)
2548
0
    {
2549
0
      _bfd_error_handler
2550
        /* xgettext:c-format */
2551
0
        (_("error: %pB uses 64-bit doubles but "
2552
0
           "%pB uses 32-bit doubles"), ibfd, obfd);
2553
0
      result = false;
2554
0
    }
2555
0
        else
2556
    /* ibfd uses 32-bit doubles, obfd uses 64-bit doubles.
2557
       This is acceptable.  Honest, that is what the ABI says.  */
2558
0
    BFD_ASSERT (oval == EF_RH850_DOUBLE64);
2559
0
        break;
2560
2561
0
      case V850_NOTE_FPU_INFO:
2562
0
        if (oval == EF_RH850_FPU20)
2563
0
    {
2564
0
      _bfd_error_handler
2565
        /* xgettext:c-format */
2566
0
        (_("error: %pB uses FPU-3.0 but %pB only supports FPU-2.0"),
2567
0
         ibfd, obfd);
2568
0
      result = false;
2569
0
    }
2570
0
        else
2571
    /* ibfd uses FPU-2.0, obfd uses FPU-3.0.  Leave obfd as it is.  */
2572
0
    BFD_ASSERT (oval == EF_RH850_FPU30);
2573
2574
0
        break;
2575
2576
0
      default:
2577
        /* None of the other conflicts matter.
2578
     Stick with the current output values.  */
2579
0
        break;
2580
0
      }
2581
0
  }
2582
2583
      /* FIXME:  We should also check for conflicts between the notes
2584
   and the EF flags in the ELF header.  */
2585
0
    }
2586
2587
0
  return result;
2588
0
}
2589
2590
static void
2591
print_v850_note (bfd * abfd, FILE * file, bfd_byte * data, enum v850_notes id)
2592
0
{
2593
0
  unsigned int value = bfd_get_32 (abfd, data + ((id - 1) * SIZEOF_V850_NOTE) + 16);
2594
2595
0
  switch (id)
2596
0
    {
2597
0
    case V850_NOTE_ALIGNMENT:
2598
0
      fprintf (file, _(" alignment of 8-byte entities: "));
2599
0
      switch (value)
2600
0
  {
2601
0
  case EF_RH850_DATA_ALIGN4: fprintf (file, _("4-byte")); break;
2602
0
  case EF_RH850_DATA_ALIGN8: fprintf (file, _("8-byte")); break;
2603
0
  case 0:  fprintf (file, _("not set")); break;
2604
0
  default: fprintf (file, _("unknown: %x"), value); break;
2605
0
  }
2606
0
      fputc ('\n', file);
2607
0
      break;
2608
2609
0
    case V850_NOTE_DATA_SIZE:
2610
0
      fprintf (file, _(" size of doubles: "));
2611
0
      switch (value)
2612
0
  {
2613
0
  case EF_RH850_DOUBLE32: fprintf (file, _("4-bytes")); break;
2614
0
  case EF_RH850_DOUBLE64: fprintf (file, _("8-bytes")); break;
2615
0
  case 0:  fprintf (file, _("not set")); break;
2616
0
  default: fprintf (file, _("unknown: %x"), value); break;
2617
0
  }
2618
0
      fputc ('\n', file);
2619
0
      break;
2620
2621
0
    case V850_NOTE_FPU_INFO:
2622
0
      fprintf (file, _(" FPU support required: "));
2623
0
      switch (value)
2624
0
  {
2625
0
  case EF_RH850_FPU20: fprintf (file, _("FPU-2.0")); break;
2626
0
  case EF_RH850_FPU30: fprintf (file, _("FPU-3.0")); break;
2627
0
  case 0:  fprintf (file, _("none")); break;
2628
0
  default: fprintf (file, _("unknown: %x"), value); break;
2629
0
  }
2630
0
      fputc ('\n', file);
2631
0
      break;
2632
2633
0
    case V850_NOTE_SIMD_INFO:
2634
0
      fprintf (file, _("SIMD use: "));
2635
0
      switch (value)
2636
0
  {
2637
0
  case EF_RH850_SIMD: fprintf (file, _("yes")); break;
2638
0
  case 0:  fprintf (file, _("no")); break;
2639
0
  default: fprintf (file, _("unknown: %x"), value); break;
2640
0
  }
2641
0
      fputc ('\n', file);
2642
0
      break;
2643
2644
0
    case V850_NOTE_CACHE_INFO:
2645
0
      fprintf (file, _("CACHE use: "));
2646
0
      switch (value)
2647
0
  {
2648
0
  case EF_RH850_CACHE: fprintf (file, _("yes")); break;
2649
0
  case 0:  fprintf (file, _("no")); break;
2650
0
  default: fprintf (file, _("unknown: %x"), value); break;
2651
0
  }
2652
0
      fputc ('\n', file);
2653
0
      break;
2654
2655
0
    case V850_NOTE_MMU_INFO:
2656
0
      fprintf (file, _("MMU use: "));
2657
0
      switch (value)
2658
0
  {
2659
0
  case EF_RH850_MMU: fprintf (file, _("yes")); break;
2660
0
  case 0:  fprintf (file, _("no")); break;
2661
0
  default: fprintf (file, _("unknown: %x"), value); break;
2662
0
  }
2663
0
      fputc ('\n', file);
2664
0
      break;
2665
2666
0
    default:
2667
0
      BFD_ASSERT (0);
2668
0
    }
2669
0
}
2670
2671
static void
2672
v850_elf_print_notes (bfd * abfd, FILE * file)
2673
0
{
2674
0
  asection * notes = bfd_get_section_by_name (abfd, V850_NOTE_SECNAME);
2675
0
  enum v850_notes id;
2676
2677
0
  if (notes == NULL || notes->contents == NULL)
2678
0
    return;
2679
2680
0
  BFD_ASSERT (bfd_section_size (notes) == NUM_V850_NOTES * SIZEOF_V850_NOTE);
2681
2682
0
  for (id = V850_NOTE_ALIGNMENT; id <= NUM_V850_NOTES; id++)
2683
0
    print_v850_note (abfd, file, notes->contents, id);
2684
0
}
2685
2686
/* Set the right machine number and architecture.  */
2687
2688
static bool
2689
v850_elf_object_p (bfd *abfd)
2690
0
{
2691
0
  enum bfd_architecture arch;
2692
0
  unsigned long mach;
2693
2694
0
  switch (elf_elfheader (abfd)->e_machine)
2695
0
    {
2696
0
    case EM_V800:
2697
0
      arch = bfd_arch_v850_rh850;
2698
0
      mach = (elf_elfheader (abfd)->e_flags & EF_V800_850E3)
2699
0
  ? bfd_mach_v850e3v5 : bfd_mach_v850e2v3;
2700
0
      break;
2701
2702
0
    case EM_CYGNUS_V850:
2703
0
    case EM_V850:
2704
0
      arch = bfd_arch_v850;
2705
0
      switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
2706
0
  {
2707
0
  default:
2708
0
  case E_V850_ARCH:     mach = bfd_mach_v850; break;
2709
0
  case E_V850E_ARCH:    mach = bfd_mach_v850e; break;
2710
0
  case E_V850E1_ARCH:   mach = bfd_mach_v850e1; break;
2711
0
  case E_V850E2_ARCH:   mach = bfd_mach_v850e2; break;
2712
0
  case E_V850E2V3_ARCH: mach = bfd_mach_v850e2v3; break;
2713
0
  case E_V850E3V5_ARCH: mach = bfd_mach_v850e3v5; break;
2714
0
  }
2715
0
      break;
2716
2717
0
    default:
2718
0
      return false;
2719
0
    }
2720
2721
0
  return bfd_default_set_arch_mach (abfd, arch, mach);
2722
0
}
2723
2724
/* Store the machine number in the flags field.  */
2725
2726
static bool
2727
v850_elf_final_write_processing (bfd *abfd)
2728
0
{
2729
0
  unsigned long val;
2730
2731
0
  switch (bfd_get_arch (abfd))
2732
0
    {
2733
0
    case bfd_arch_v850_rh850:
2734
0
      val = EF_RH850_ABI;
2735
0
      if (bfd_get_mach (abfd) == bfd_mach_v850e3v5)
2736
0
  val |= EF_V800_850E3;
2737
0
      elf_elfheader (abfd)->e_flags |= val;
2738
0
      break;
2739
2740
0
    case bfd_arch_v850:
2741
0
      switch (bfd_get_mach (abfd))
2742
0
  {
2743
0
  default:
2744
0
  case bfd_mach_v850:     val = E_V850_ARCH; break;
2745
0
  case bfd_mach_v850e:    val = E_V850E_ARCH; break;
2746
0
  case bfd_mach_v850e1:   val = E_V850E1_ARCH; break;
2747
0
  case bfd_mach_v850e2:   val = E_V850E2_ARCH; break;
2748
0
  case bfd_mach_v850e2v3: val = E_V850E2V3_ARCH; break;
2749
0
  case bfd_mach_v850e3v5: val = E_V850E3V5_ARCH; break;
2750
0
  }
2751
0
      elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
2752
0
      elf_elfheader (abfd)->e_flags |= val;
2753
0
      break;
2754
0
    default:
2755
0
      break;
2756
0
    }
2757
0
  return _bfd_elf_final_write_processing (abfd);
2758
0
}
2759
2760
/* Function to keep V850 specific file flags.  */
2761
2762
static bool
2763
v850_elf_set_private_flags (bfd *abfd, flagword flags)
2764
0
{
2765
0
  BFD_ASSERT (!elf_flags_init (abfd)
2766
0
        || elf_elfheader (abfd)->e_flags == flags);
2767
2768
0
  elf_elfheader (abfd)->e_flags = flags;
2769
0
  elf_flags_init (abfd) = true;
2770
0
  return true;
2771
0
}
2772
2773
/* Merge backend specific data from an object file
2774
   to the output object file when linking.  */
2775
2776
static bool
2777
v850_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
2778
0
{
2779
0
  bfd *obfd = info->output_bfd;
2780
0
  flagword out_flags;
2781
0
  flagword in_flags;
2782
0
  bool result = true;
2783
2784
0
  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
2785
0
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
2786
0
    return true;
2787
2788
0
  result &= v850_elf_merge_notes (ibfd, obfd);
2789
2790
0
  in_flags = elf_elfheader (ibfd)->e_flags;
2791
0
  out_flags = elf_elfheader (obfd)->e_flags;
2792
2793
0
  if (! elf_flags_init (obfd))
2794
0
    {
2795
      /* If the input is the default architecture then do not
2796
   bother setting the flags for the output architecture,
2797
   instead allow future merges to do this.  If no future
2798
   merges ever set these flags then they will retain their
2799
   unitialised values, which surprise surprise, correspond
2800
   to the default values.  */
2801
0
      if (bfd_get_arch_info (ibfd)->the_default)
2802
0
  return true;
2803
2804
0
      elf_flags_init (obfd) = true;
2805
0
      elf_elfheader (obfd)->e_flags = in_flags;
2806
2807
0
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
2808
0
    && bfd_get_arch_info (obfd)->the_default)
2809
0
  result &= bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
2810
2811
0
      return result;
2812
0
    }
2813
2814
  /* Check flag compatibility.  */
2815
0
  if (in_flags == out_flags)
2816
0
    return result;
2817
2818
0
  if (bfd_get_arch (obfd) == bfd_arch_v850_rh850)
2819
0
    {
2820
0
      if ((in_flags & EF_V800_850E3) != (out_flags & EF_V800_850E3))
2821
0
  {
2822
0
    _bfd_error_handler
2823
0
      (_("%pB: architecture mismatch with previous modules"), ibfd);
2824
0
    elf_elfheader (obfd)->e_flags |= EF_V800_850E3;
2825
0
  }
2826
2827
0
      return result;
2828
0
    }
2829
2830
0
  if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
2831
0
      && (in_flags & EF_V850_ARCH) != E_V850_ARCH)
2832
0
    {
2833
      /* Allow earlier architecture binaries to be linked with later binaries.
2834
   Set the output binary to the later architecture, except for v850e1,
2835
   which we set to v850e.  */
2836
0
      if (   (in_flags  & EF_V850_ARCH) == E_V850E1_ARCH
2837
0
    && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
2838
0
  return result;
2839
2840
0
      if (   (in_flags  & EF_V850_ARCH) == E_V850_ARCH
2841
0
    && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
2842
0
  {
2843
0
    elf_elfheader (obfd)->e_flags =
2844
0
      ((out_flags & ~ EF_V850_ARCH) | E_V850E_ARCH);
2845
0
    return result;
2846
0
  }
2847
2848
0
      if ((   (in_flags & EF_V850_ARCH) == E_V850_ARCH
2849
0
     || (in_flags & EF_V850_ARCH) == E_V850E_ARCH)
2850
0
    && (out_flags & EF_V850_ARCH) == E_V850E2_ARCH)
2851
0
  {
2852
0
    elf_elfheader (obfd)->e_flags =
2853
0
      ((out_flags & ~ EF_V850_ARCH) | E_V850E2_ARCH);
2854
0
    return result;
2855
0
  }
2856
2857
0
      if ((   (in_flags & EF_V850_ARCH) == E_V850_ARCH
2858
0
     || (in_flags & EF_V850_ARCH) == E_V850E_ARCH
2859
0
     || (in_flags & EF_V850_ARCH) == E_V850E2_ARCH)
2860
0
    && (out_flags & EF_V850_ARCH) == E_V850E2V3_ARCH)
2861
0
  {
2862
0
    elf_elfheader (obfd)->e_flags =
2863
0
      ((out_flags & ~ EF_V850_ARCH) | E_V850E2V3_ARCH);
2864
0
    return result;
2865
0
  }
2866
2867
0
      if ((   (in_flags & EF_V850_ARCH) == E_V850_ARCH
2868
0
     || (in_flags & EF_V850_ARCH) == E_V850E_ARCH
2869
0
     || (in_flags & EF_V850_ARCH) == E_V850E2_ARCH
2870
0
     || (in_flags & EF_V850_ARCH) == E_V850E2V3_ARCH)
2871
0
    && (out_flags & EF_V850_ARCH) == E_V850E3V5_ARCH)
2872
0
  {
2873
0
    elf_elfheader (obfd)->e_flags =
2874
0
      ((out_flags & ~ EF_V850_ARCH) | E_V850E3V5_ARCH);
2875
0
    return result;
2876
0
  }
2877
2878
0
      _bfd_error_handler
2879
0
  (_("%pB: architecture mismatch with previous modules"), ibfd);
2880
0
    }
2881
2882
0
  return result;
2883
0
}
2884
2885
/* Display the flags field.  */
2886
2887
static bool
2888
v850_elf_print_private_bfd_data (bfd *abfd, void * ptr)
2889
0
{
2890
0
  FILE * file = (FILE *) ptr;
2891
2892
0
  BFD_ASSERT (abfd != NULL && ptr != NULL);
2893
2894
0
  _bfd_elf_print_private_bfd_data (abfd, ptr);
2895
2896
  /* xgettext:c-format.  */
2897
0
  fprintf (file, _("private flags = %lx: "), elf_elfheader (abfd)->e_flags);
2898
2899
0
  if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
2900
0
    {
2901
0
      if ((elf_elfheader (abfd)->e_flags & EF_RH850_ABI) != EF_RH850_ABI)
2902
0
  fprintf (file, _("unknown v850 architecture"));
2903
0
      else if (elf_elfheader (abfd)->e_flags & EF_V800_850E3)
2904
0
  fprintf (file, _("v850 E3 architecture"));
2905
0
      else
2906
0
  fprintf (file, _("v850 architecture"));
2907
0
    }
2908
0
  else
2909
0
    {
2910
0
      switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
2911
0
  {
2912
0
  default:
2913
0
  case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;
2914
0
  case E_V850E_ARCH: fprintf (file, _("v850e architecture")); break;
2915
0
  case E_V850E1_ARCH: fprintf (file, _("v850e1 architecture")); break;
2916
0
  case E_V850E2_ARCH: fprintf (file, _("v850e2 architecture")); break;
2917
0
  case E_V850E2V3_ARCH: fprintf (file, _("v850e2v3 architecture")); break;
2918
0
  case E_V850E3V5_ARCH: fprintf (file, _("v850e3v5 architecture")); break;
2919
0
  }
2920
0
    }
2921
2922
0
  fputc ('\n', file);
2923
2924
0
  v850_elf_print_notes (abfd, file);
2925
2926
0
  return true;
2927
0
}
2928
2929
/* V850 ELF uses four common sections.  One is the usual one, and the
2930
   others are for (small) objects in one of the special data areas:
2931
   small, tiny and zero.  All the objects are kept together, and then
2932
   referenced via the gp register, the ep register or the r0 register
2933
   respectively, which yields smaller, faster assembler code.  This
2934
   approach is copied from elf32-mips.c.  */
2935
2936
static asection v850_elf_scom_section;
2937
static const asymbol v850_elf_scom_symbol =
2938
  GLOBAL_SYM_INIT (".scommon", &v850_elf_scom_section);
2939
static asection v850_elf_scom_section =
2940
  BFD_FAKE_SECTION (v850_elf_scom_section, &v850_elf_scom_symbol,
2941
        ".scommon", 0,
2942
        SEC_IS_COMMON | SEC_SMALL_DATA | SEC_ALLOC | SEC_DATA);
2943
2944
static asection v850_elf_tcom_section;
2945
static const asymbol v850_elf_tcom_symbol =
2946
  GLOBAL_SYM_INIT (".tcommon", &v850_elf_tcom_section);
2947
static asection v850_elf_tcom_section =
2948
  BFD_FAKE_SECTION (v850_elf_tcom_section, &v850_elf_tcom_symbol,
2949
        ".tcommon", 0,
2950
        SEC_IS_COMMON | SEC_SMALL_DATA);
2951
2952
static asection v850_elf_zcom_section;
2953
static const asymbol v850_elf_zcom_symbol =
2954
  GLOBAL_SYM_INIT (".zcommon", &v850_elf_zcom_section);
2955
static asection v850_elf_zcom_section =
2956
  BFD_FAKE_SECTION (v850_elf_zcom_section, &v850_elf_zcom_symbol,
2957
        ".zcommon", 0,
2958
        SEC_IS_COMMON | SEC_SMALL_DATA);
2959
2960
/* Given a BFD section, try to locate the
2961
   corresponding ELF section index.  */
2962
2963
static bool
2964
v850_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
2965
           asection *sec,
2966
           int *retval)
2967
0
{
2968
0
  if (strcmp (bfd_section_name (sec), ".scommon") == 0)
2969
0
    *retval = SHN_V850_SCOMMON;
2970
0
  else if (strcmp (bfd_section_name (sec), ".tcommon") == 0)
2971
0
    *retval = SHN_V850_TCOMMON;
2972
0
  else if (strcmp (bfd_section_name (sec), ".zcommon") == 0)
2973
0
    *retval = SHN_V850_ZCOMMON;
2974
0
  else
2975
0
    return false;
2976
2977
0
  return true;
2978
0
}
2979
2980
/* Handle the special V850 section numbers that a symbol may use.  */
2981
2982
static void
2983
v850_elf_symbol_processing (bfd *abfd, asymbol *asym)
2984
0
{
2985
0
  elf_symbol_type * elfsym = (elf_symbol_type *) asym;
2986
0
  unsigned int indx;
2987
2988
0
  indx = elfsym->internal_elf_sym.st_shndx;
2989
2990
  /* If the section index is an "ordinary" index, then it may
2991
     refer to a v850 specific section created by the assembler.
2992
     Check the section's type and change the index it matches.
2993
2994
     FIXME: Should we alter the st_shndx field as well ?  */
2995
2996
0
  if (indx < elf_numsections (abfd))
2997
0
    switch (elf_elfsections (abfd)[indx]->sh_type)
2998
0
      {
2999
0
      case SHT_V850_SCOMMON:
3000
0
  indx = SHN_V850_SCOMMON;
3001
0
  break;
3002
3003
0
      case SHT_V850_TCOMMON:
3004
0
  indx = SHN_V850_TCOMMON;
3005
0
  break;
3006
3007
0
      case SHT_V850_ZCOMMON:
3008
0
  indx = SHN_V850_ZCOMMON;
3009
0
  break;
3010
3011
0
      default:
3012
0
  break;
3013
0
      }
3014
3015
0
  switch (indx)
3016
0
    {
3017
0
    case SHN_V850_SCOMMON:
3018
0
      asym->section = & v850_elf_scom_section;
3019
0
      asym->value = elfsym->internal_elf_sym.st_size;
3020
0
      break;
3021
3022
0
    case SHN_V850_TCOMMON:
3023
0
      asym->section = & v850_elf_tcom_section;
3024
0
      asym->value = elfsym->internal_elf_sym.st_size;
3025
0
      break;
3026
3027
0
    case SHN_V850_ZCOMMON:
3028
0
      asym->section = & v850_elf_zcom_section;
3029
0
      asym->value = elfsym->internal_elf_sym.st_size;
3030
0
      break;
3031
0
    }
3032
0
}
3033
3034
/* Hook called by the linker routine which adds symbols from an object
3035
   file.  We must handle the special v850 section numbers here.  */
3036
3037
static bool
3038
v850_elf_add_symbol_hook (bfd *abfd,
3039
        struct bfd_link_info *info ATTRIBUTE_UNUSED,
3040
        Elf_Internal_Sym *sym,
3041
        const char **namep ATTRIBUTE_UNUSED,
3042
        flagword *flagsp ATTRIBUTE_UNUSED,
3043
        asection **secp,
3044
        bfd_vma *valp)
3045
0
{
3046
0
  unsigned int indx = sym->st_shndx;
3047
3048
  /* If the section index is an "ordinary" index, then it may
3049
     refer to a v850 specific section created by the assembler.
3050
     Check the section's type and change the index it matches.
3051
3052
     FIXME: Should we alter the st_shndx field as well ?  */
3053
3054
0
  if (indx < elf_numsections (abfd))
3055
0
    switch (elf_elfsections (abfd)[indx]->sh_type)
3056
0
      {
3057
0
      case SHT_V850_SCOMMON:
3058
0
  indx = SHN_V850_SCOMMON;
3059
0
  break;
3060
3061
0
      case SHT_V850_TCOMMON:
3062
0
  indx = SHN_V850_TCOMMON;
3063
0
  break;
3064
3065
0
      case SHT_V850_ZCOMMON:
3066
0
  indx = SHN_V850_ZCOMMON;
3067
0
  break;
3068
3069
0
      default:
3070
0
  break;
3071
0
      }
3072
3073
0
  switch (indx)
3074
0
    {
3075
0
    case SHN_V850_SCOMMON:
3076
0
      *secp = bfd_make_section_old_way (abfd, ".scommon");
3077
0
      (*secp)->flags |= SEC_IS_COMMON | SEC_SMALL_DATA;
3078
0
      *valp = sym->st_size;
3079
0
      break;
3080
3081
0
    case SHN_V850_TCOMMON:
3082
0
      *secp = bfd_make_section_old_way (abfd, ".tcommon");
3083
0
      (*secp)->flags |= SEC_IS_COMMON | SEC_SMALL_DATA;
3084
0
      *valp = sym->st_size;
3085
0
      break;
3086
3087
0
    case SHN_V850_ZCOMMON:
3088
0
      *secp = bfd_make_section_old_way (abfd, ".zcommon");
3089
0
      (*secp)->flags |= SEC_IS_COMMON | SEC_SMALL_DATA;
3090
0
      *valp = sym->st_size;
3091
0
      break;
3092
0
    }
3093
3094
0
  return true;
3095
0
}
3096
3097
static int
3098
v850_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
3099
          const char *name ATTRIBUTE_UNUSED,
3100
          Elf_Internal_Sym *sym,
3101
          asection *input_sec,
3102
          struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
3103
0
{
3104
  /* If we see a common symbol, which implies a relocatable link, then
3105
     if a symbol was in a special common section in an input file, mark
3106
     it as a special common in the output file.  */
3107
3108
0
  if (sym->st_shndx == SHN_COMMON)
3109
0
    {
3110
0
      if (strcmp (input_sec->name, ".scommon") == 0)
3111
0
  sym->st_shndx = SHN_V850_SCOMMON;
3112
0
      else if (strcmp (input_sec->name, ".tcommon") == 0)
3113
0
  sym->st_shndx = SHN_V850_TCOMMON;
3114
0
      else if (strcmp (input_sec->name, ".zcommon") == 0)
3115
0
  sym->st_shndx = SHN_V850_ZCOMMON;
3116
0
    }
3117
3118
  /* The price we pay for using h->other unused bits as flags in the
3119
     linker is cleaning up after ourselves.  */
3120
3121
0
  sym->st_other &= ~(V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA
3122
0
         | V850_OTHER_ERROR);
3123
3124
0
  return 1;
3125
0
}
3126
3127
static bool
3128
v850_elf_section_from_shdr (bfd *abfd,
3129
          Elf_Internal_Shdr *hdr,
3130
          const char *name,
3131
          int shindex)
3132
0
{
3133
0
  flagword flags;
3134
3135
  /* There ought to be a place to keep ELF backend specific flags, but
3136
     at the moment there isn't one.  We just keep track of the
3137
     sections by their name, instead.  */
3138
3139
0
  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
3140
0
    return false;
3141
3142
0
  flags = 0;
3143
0
  switch (hdr->sh_type)
3144
0
    {
3145
0
    case SHT_V850_SCOMMON:
3146
0
    case SHT_V850_TCOMMON:
3147
0
    case SHT_V850_ZCOMMON:
3148
0
      flags = SEC_IS_COMMON;
3149
0
    }
3150
3151
0
  if ((hdr->sh_flags & SHF_V850_GPREL) != 0)
3152
0
    flags |= SEC_SMALL_DATA;
3153
3154
0
  return (flags == 0
3155
0
    || bfd_set_section_flags (hdr->bfd_section,
3156
0
            hdr->bfd_section->flags | flags));
3157
0
}
3158
3159
/* Set the correct type for a V850 ELF section.  We do this
3160
   by the section name, which is a hack, but ought to work.  */
3161
3162
static bool
3163
v850_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
3164
      Elf_Internal_Shdr *hdr,
3165
      asection *sec)
3166
0
{
3167
0
  const char * name;
3168
3169
0
  name = bfd_section_name (sec);
3170
3171
0
  if (strcmp (name, ".scommon") == 0)
3172
0
    hdr->sh_type = SHT_V850_SCOMMON;
3173
0
  else if (strcmp (name, ".tcommon") == 0)
3174
0
    hdr->sh_type = SHT_V850_TCOMMON;
3175
0
  else if (strcmp (name, ".zcommon") == 0)
3176
0
    hdr->sh_type = SHT_V850_ZCOMMON;
3177
  /* Tweak the section type of .note.renesas.  */
3178
0
  else if (strcmp (name, V850_NOTE_SECNAME) == 0)
3179
0
    {
3180
0
      hdr->sh_type = SHT_RENESAS_INFO;
3181
0
      hdr->sh_entsize = SIZEOF_V850_NOTE;
3182
0
    }
3183
3184
0
  return true;
3185
0
}
3186
3187
/* Delete some bytes from a section while relaxing.  */
3188
3189
static bool
3190
v850_elf_relax_delete_bytes (bfd *abfd,
3191
           asection *sec,
3192
           bfd_vma addr,
3193
           bfd_vma toaddr,
3194
           int count)
3195
0
{
3196
0
  Elf_Internal_Shdr *symtab_hdr;
3197
0
  Elf32_External_Sym *extsyms;
3198
0
  Elf32_External_Sym *esym;
3199
0
  Elf32_External_Sym *esymend;
3200
0
  int sym_index;
3201
0
  unsigned int sec_shndx;
3202
0
  bfd_byte *contents;
3203
0
  Elf_Internal_Rela *irel;
3204
0
  Elf_Internal_Rela *irelend;
3205
0
  struct elf_link_hash_entry *sym_hash;
3206
0
  Elf_External_Sym_Shndx *shndx;
3207
3208
0
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3209
0
  extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
3210
3211
0
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
3212
3213
0
  contents = elf_section_data (sec)->this_hdr.contents;
3214
3215
  /* The deletion must stop at the next ALIGN reloc for an alignment
3216
     power larger than the number of bytes we are deleting.  */
3217
3218
  /* Actually delete the bytes.  */
3219
#if (DEBUG_RELAX & 2)
3220
  fprintf (stderr, "relax_delete: contents: sec: %s  %p .. %p %x\n",
3221
     sec->name, addr, toaddr, count );
3222
#endif
3223
0
  memmove (contents + addr, contents + addr + count,
3224
0
     toaddr - addr - count);
3225
0
  memset (contents + toaddr-count, 0, count);
3226
3227
  /* Adjust all the relocs.  */
3228
0
  irel = elf_section_data (sec)->relocs;
3229
0
  irelend = irel + sec->reloc_count;
3230
0
  if (elf_symtab_shndx_list (abfd))
3231
0
    {
3232
0
      Elf_Internal_Shdr *shndx_hdr;
3233
3234
0
      shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
3235
0
      shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
3236
0
    }
3237
0
  else
3238
0
    {
3239
0
      shndx = NULL;
3240
0
    }
3241
3242
0
  for (; irel < irelend; irel++)
3243
0
    {
3244
0
      bfd_vma raddr, paddr, symval;
3245
0
      Elf_Internal_Sym isym;
3246
3247
      /* Get the new reloc address.  */
3248
0
      raddr = irel->r_offset;
3249
0
      if ((raddr >= (addr + count) && raddr < toaddr))
3250
0
  irel->r_offset -= count;
3251
3252
0
      if (raddr >= addr && raddr < addr + count)
3253
0
  {
3254
0
    irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
3255
0
               (int) R_V850_NONE);
3256
0
    continue;
3257
0
  }
3258
3259
0
      if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN)
3260
0
  continue;
3261
3262
0
      bfd_elf32_swap_symbol_in (abfd,
3263
0
        extsyms + ELF32_R_SYM (irel->r_info),
3264
0
        shndx ? shndx + ELF32_R_SYM (irel->r_info) : NULL,
3265
0
        & isym);
3266
3267
0
      if (isym.st_shndx != sec_shndx)
3268
0
  continue;
3269
3270
      /* Get the value of the symbol referred to by the reloc.  */
3271
0
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
3272
0
  {
3273
0
    symval = isym.st_value;
3274
#if (DEBUG_RELAX & 2)
3275
    {
3276
      char * name = bfd_elf_string_from_elf_section
3277
         (abfd, symtab_hdr->sh_link, isym.st_name);
3278
      fprintf (stderr,
3279
         "relax_delete: local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
3280
         sec->name, name, isym.st_name,
3281
         sec->output_section->vma, sec->output_offset,
3282
         isym.st_value, irel->r_addend);
3283
    }
3284
#endif
3285
0
  }
3286
0
      else
3287
0
  {
3288
0
    unsigned long indx;
3289
0
    struct elf_link_hash_entry * h;
3290
3291
    /* An external symbol.  */
3292
0
    indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
3293
3294
0
    h = elf_sym_hashes (abfd) [indx];
3295
0
    BFD_ASSERT (h != NULL);
3296
3297
0
    symval = h->root.u.def.value;
3298
#if (DEBUG_RELAX & 2)
3299
    fprintf (stderr,
3300
       "relax_delete: defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
3301
       sec->name, h->root.root.string, h->root.u.def.value,
3302
       sec->output_section->vma, sec->output_offset, irel->r_addend);
3303
#endif
3304
0
  }
3305
3306
0
      paddr = symval + irel->r_addend;
3307
3308
0
      if ( (symval >= addr + count && symval < toaddr)
3309
0
    && (paddr < addr + count || paddr >= toaddr))
3310
0
  irel->r_addend += count;
3311
0
      else if (    (symval < addr + count || symval >= toaddr)
3312
0
    && (paddr >= addr + count && paddr < toaddr))
3313
0
  irel->r_addend -= count;
3314
0
    }
3315
3316
  /* Adjust the local symbols defined in this section.  */
3317
0
  esym = extsyms;
3318
0
  esymend = esym + symtab_hdr->sh_info;
3319
3320
0
  for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
3321
0
    {
3322
0
      Elf_Internal_Sym isym;
3323
3324
0
      bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
3325
3326
0
      if (isym.st_shndx == sec_shndx
3327
0
    && isym.st_value >= addr + count
3328
0
    && isym.st_value < toaddr)
3329
0
  {
3330
0
    isym.st_value -= count;
3331
3332
0
    if (isym.st_value + isym.st_size >= toaddr)
3333
0
      isym.st_size += count;
3334
3335
0
    bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
3336
0
  }
3337
0
      else if (isym.st_shndx == sec_shndx
3338
0
         && isym.st_value < addr + count)
3339
0
  {
3340
0
    if (isym.st_value+isym.st_size >= addr + count
3341
0
        && isym.st_value+isym.st_size < toaddr)
3342
0
      isym.st_size -= count;
3343
3344
0
    if (isym.st_value >= addr
3345
0
        && isym.st_value <  addr + count)
3346
0
      isym.st_value = addr;
3347
3348
0
    bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
3349
0
  }
3350
0
    }
3351
3352
  /* Now adjust the global symbols defined in this section.  */
3353
0
  esym = extsyms + symtab_hdr->sh_info;
3354
0
  esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
3355
3356
0
  for (sym_index = 0; esym < esymend; esym ++, sym_index ++)
3357
0
    {
3358
0
      Elf_Internal_Sym isym;
3359
3360
0
      bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
3361
0
      sym_hash = elf_sym_hashes (abfd) [sym_index];
3362
3363
0
      if (isym.st_shndx == sec_shndx
3364
0
    && ((sym_hash)->root.type == bfd_link_hash_defined
3365
0
        || (sym_hash)->root.type == bfd_link_hash_defweak)
3366
0
    && (sym_hash)->root.u.def.section == sec
3367
0
    && (sym_hash)->root.u.def.value >= addr + count
3368
0
    && (sym_hash)->root.u.def.value < toaddr)
3369
0
  {
3370
0
    if ((sym_hash)->root.u.def.value + isym.st_size >= toaddr)
3371
0
      {
3372
0
        isym.st_size += count;
3373
0
        bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
3374
0
      }
3375
3376
0
    (sym_hash)->root.u.def.value -= count;
3377
0
  }
3378
0
      else if (isym.st_shndx == sec_shndx
3379
0
         && ((sym_hash)->root.type == bfd_link_hash_defined
3380
0
       || (sym_hash)->root.type == bfd_link_hash_defweak)
3381
0
         && (sym_hash)->root.u.def.section == sec
3382
0
         && (sym_hash)->root.u.def.value < addr + count)
3383
0
  {
3384
0
    if ((sym_hash)->root.u.def.value+isym.st_size >= addr + count
3385
0
        && (sym_hash)->root.u.def.value+isym.st_size < toaddr)
3386
0
      isym.st_size -= count;
3387
3388
0
    if ((sym_hash)->root.u.def.value >= addr
3389
0
        && (sym_hash)->root.u.def.value < addr + count)
3390
0
      (sym_hash)->root.u.def.value = addr;
3391
3392
0
    bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
3393
0
  }
3394
3395
0
      if (shndx)
3396
0
  ++ shndx;
3397
0
    }
3398
3399
0
  return true;
3400
0
}
3401
3402
#define NOP_OPCODE  (0x0000)
3403
0
#define MOVHI   0x0640        /* 4byte.  */
3404
0
#define MOVHI_MASK  0x07e0
3405
0
#define MOVHI_R1(insn)  ((insn) & 0x1f)      /* 4byte.  */
3406
0
#define MOVHI_R2(insn)  ((insn) >> 11)
3407
0
#define MOVEA   0x0620        /* 2byte.  */
3408
0
#define MOVEA_MASK  0x07e0
3409
0
#define MOVEA_R1(insn)  ((insn) & 0x1f)
3410
0
#define MOVEA_R2(insn)  ((insn) >> 11)
3411
0
#define JARL_4    0x00040780        /* 4byte.  */
3412
0
#define JARL_4_MASK 0xFFFF07FF
3413
0
#define JARL_R2(insn) (int)(((insn) & (~JARL_4_MASK)) >> 11)
3414
0
#define ADD_I   0x0240          /* 2byte.  */
3415
0
#define ADD_I_MASK  0x07e0
3416
0
#define ADD_I5(insn)  ((((insn) & 0x001f) << 11) >> 11)  /* 2byte.  */
3417
0
#define ADD_R2(insn)  ((insn) >> 11)
3418
0
#define JMP_R   0x0060          /* 2byte.  */
3419
0
#define JMP_R_MASK  0xFFE0
3420
0
#define JMP_R1(insn)  ((insn) & 0x1f)
3421
3422
static bool
3423
v850_elf_relax_section (bfd *abfd,
3424
      asection *sec,
3425
      struct bfd_link_info *link_info,
3426
      bool *again)
3427
0
{
3428
0
  Elf_Internal_Shdr *symtab_hdr;
3429
0
  Elf_Internal_Rela *internal_relocs;
3430
0
  Elf_Internal_Rela *irel;
3431
0
  Elf_Internal_Rela *irelend;
3432
0
  Elf_Internal_Rela *irelalign = NULL;
3433
0
  Elf_Internal_Sym *isymbuf = NULL;
3434
0
  bfd_byte *contents = NULL;
3435
0
  bfd_vma addr = 0;
3436
0
  bfd_vma toaddr;
3437
0
  int align_pad_size = 0;
3438
0
  bool result = true;
3439
3440
0
  *again = false;
3441
3442
0
  if (bfd_link_relocatable (link_info)
3443
0
      || (sec->flags & SEC_HAS_CONTENTS) == 0
3444
0
      || (sec->flags & SEC_RELOC) == 0
3445
0
      || sec->reloc_count == 0)
3446
0
    return true;
3447
3448
0
  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
3449
3450
0
  internal_relocs = (_bfd_elf_link_read_relocs
3451
0
         (abfd, sec, NULL, NULL, link_info->keep_memory));
3452
0
  if (internal_relocs == NULL)
3453
0
    goto error_return;
3454
3455
0
  irelend = internal_relocs + sec->reloc_count;
3456
3457
0
  while (addr < sec->size)
3458
0
    {
3459
0
      toaddr = sec->size;
3460
3461
0
      for (irel = internal_relocs; irel < irelend; irel ++)
3462
0
  if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
3463
0
      && irel->r_offset > addr
3464
0
      && irel->r_offset < toaddr)
3465
0
    toaddr = irel->r_offset;
3466
3467
#ifdef DEBUG_RELAX
3468
      fprintf (stderr, "relax region 0x%x to 0x%x align pad %d\n",
3469
         addr, toaddr, align_pad_size);
3470
#endif
3471
0
      if (irelalign)
3472
0
  {
3473
0
    bfd_vma alignto;
3474
0
    bfd_vma alignmoveto;
3475
3476
0
    alignmoveto = BFD_ALIGN (addr - align_pad_size, 1 << irelalign->r_addend);
3477
0
    alignto = BFD_ALIGN (addr, 1 << irelalign->r_addend);
3478
3479
0
    if (alignmoveto < alignto)
3480
0
      {
3481
0
        bfd_vma i;
3482
3483
0
        align_pad_size = alignto - alignmoveto;
3484
#ifdef DEBUG_RELAX
3485
        fprintf (stderr, "relax move region 0x%x to 0x%x delete size 0x%x\n",
3486
           alignmoveto, toaddr, align_pad_size);
3487
#endif
3488
0
        if (!v850_elf_relax_delete_bytes (abfd, sec, alignmoveto,
3489
0
            toaddr, align_pad_size))
3490
0
    goto error_return;
3491
3492
0
        for (i  = BFD_ALIGN (toaddr - align_pad_size, 1);
3493
0
       (i + 1) < toaddr; i += 2)
3494
0
    bfd_put_16 (abfd, NOP_OPCODE, contents + i);
3495
3496
0
        addr = alignmoveto;
3497
0
      }
3498
0
    else
3499
0
      align_pad_size = 0;
3500
0
  }
3501
3502
0
      for (irel = internal_relocs; irel < irelend; irel++)
3503
0
  {
3504
0
    bfd_vma laddr;
3505
0
    bfd_vma addend;
3506
0
    bfd_vma symval;
3507
0
    int insn[5];
3508
0
    int no_match = -1;
3509
0
    Elf_Internal_Rela *hi_irelfn;
3510
0
    Elf_Internal_Rela *lo_irelfn;
3511
0
    Elf_Internal_Rela *irelcall;
3512
0
    bfd_signed_vma foff;
3513
0
    unsigned int r_type;
3514
3515
0
    if (! (irel->r_offset >= addr && irel->r_offset < toaddr
3516
0
     && (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL
3517
0
         || ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)))
3518
0
      continue;
3519
3520
#ifdef DEBUG_RELAX
3521
    fprintf (stderr, "relax check r_info 0x%x r_offset 0x%x r_addend 0x%x\n",
3522
       irel->r_info,
3523
       irel->r_offset,
3524
       irel->r_addend );
3525
#endif
3526
3527
    /* Get the section contents.  */
3528
0
    if (contents == NULL)
3529
0
      {
3530
0
        if (elf_section_data (sec)->this_hdr.contents != NULL)
3531
0
    contents = elf_section_data (sec)->this_hdr.contents;
3532
0
        else
3533
0
    {
3534
0
      if (! bfd_malloc_and_get_section (abfd, sec, &contents))
3535
0
        goto error_return;
3536
0
    }
3537
0
      }
3538
3539
    /* Read this BFD's local symbols if we haven't done so already.  */
3540
0
    if (isymbuf == NULL && symtab_hdr->sh_info != 0)
3541
0
      {
3542
0
        isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
3543
0
        if (isymbuf == NULL)
3544
0
    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
3545
0
            symtab_hdr->sh_info, 0,
3546
0
            NULL, NULL, NULL);
3547
0
        if (isymbuf == NULL)
3548
0
    goto error_return;
3549
0
      }
3550
3551
0
    laddr = irel->r_offset;
3552
3553
0
    if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL)
3554
0
      {
3555
        /* Check code for -mlong-calls output. */
3556
0
        if (laddr + 16 <= (bfd_vma) sec->size)
3557
0
    {
3558
0
      insn[0] = bfd_get_16 (abfd, contents + laddr);
3559
0
      insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
3560
0
      insn[2] = bfd_get_32 (abfd, contents + laddr + 8);
3561
0
      insn[3] = bfd_get_16 (abfd, contents + laddr + 12);
3562
0
      insn[4] = bfd_get_16 (abfd, contents + laddr + 14);
3563
3564
0
      if ((insn[0] & MOVHI_MASK) != MOVHI
3565
0
           || MOVHI_R1 (insn[0]) != 0)
3566
0
        no_match = 0;
3567
3568
0
      if (no_match < 0
3569
0
          && ((insn[1] & MOVEA_MASK) != MOVEA
3570
0
         || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
3571
0
        no_match = 1;
3572
3573
0
      if (no_match < 0
3574
0
          && (insn[2] & JARL_4_MASK) != JARL_4)
3575
0
        no_match = 2;
3576
3577
0
      if (no_match < 0
3578
0
          && ((insn[3] & ADD_I_MASK) != ADD_I
3579
0
         || ADD_I5 (insn[3]) != 4
3580
0
         || JARL_R2 (insn[2]) != ADD_R2 (insn[3])))
3581
0
        no_match = 3;
3582
3583
0
      if (no_match < 0
3584
0
          && ((insn[4] & JMP_R_MASK) != JMP_R
3585
0
         || MOVEA_R2 (insn[1]) != JMP_R1 (insn[4])))
3586
0
        no_match = 4;
3587
0
    }
3588
0
        else
3589
0
    {
3590
0
      _bfd_error_handler
3591
        /* xgettext:c-format */
3592
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3593
0
           "unrecognized insns"),
3594
0
         abfd, (uint64_t) irel->r_offset, "R_V850_LONGCALL");
3595
0
      continue;
3596
0
    }
3597
3598
0
        if (no_match >= 0)
3599
0
    {
3600
0
      _bfd_error_handler
3601
        /* xgettext:c-format */
3602
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3603
0
           "unrecognized insn %#x"),
3604
0
         abfd,
3605
0
         (uint64_t) (irel->r_offset + no_match),
3606
0
         "R_V850_LONGCALL",
3607
0
         insn[no_match]);
3608
0
      continue;
3609
0
    }
3610
3611
        /* Get the reloc for the address from which the register is
3612
     being loaded.  This reloc will tell us which function is
3613
     actually being called.  */
3614
3615
0
        for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
3616
0
    {
3617
0
      r_type = ELF32_R_TYPE (hi_irelfn->r_info);
3618
3619
0
      if (hi_irelfn->r_offset == laddr + 2
3620
0
          && (r_type == (int) R_V850_HI16_S || r_type == (int) R_V810_WHI1))
3621
0
        break;
3622
0
    }
3623
3624
0
        for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
3625
0
    {
3626
0
      r_type = ELF32_R_TYPE (lo_irelfn->r_info);
3627
3628
0
      if (lo_irelfn->r_offset == laddr + 6
3629
0
          && (r_type == (int) R_V850_LO16 || r_type == (int) R_V810_WLO))
3630
0
        break;
3631
0
    }
3632
3633
0
        for (irelcall = internal_relocs; irelcall < irelend; irelcall ++)
3634
0
    {
3635
0
      r_type = ELF32_R_TYPE (irelcall->r_info);
3636
3637
0
      if (irelcall->r_offset == laddr + 8
3638
0
          && (r_type == (int) R_V850_22_PCREL || r_type == (int) R_V850_PCR22))
3639
0
        break;
3640
0
    }
3641
3642
0
        if (   hi_irelfn == irelend
3643
0
      || lo_irelfn == irelend
3644
0
      || irelcall  == irelend)
3645
0
    {
3646
0
      _bfd_error_handler
3647
        /* xgettext:c-format */
3648
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3649
0
           "unrecognized reloc"),
3650
0
         abfd, (uint64_t) irel->r_offset, "R_V850_LONGCALL");
3651
3652
0
      continue;
3653
0
    }
3654
3655
0
        if (ELF32_R_SYM (irelcall->r_info) < symtab_hdr->sh_info)
3656
0
    {
3657
0
      Elf_Internal_Sym *  isym;
3658
3659
      /* A local symbol.  */
3660
0
      isym = isymbuf + ELF32_R_SYM (irelcall->r_info);
3661
3662
0
      symval = isym->st_value;
3663
0
    }
3664
0
        else
3665
0
    {
3666
0
      unsigned long indx;
3667
0
      struct elf_link_hash_entry * h;
3668
3669
      /* An external symbol.  */
3670
0
      indx = ELF32_R_SYM (irelcall->r_info) - symtab_hdr->sh_info;
3671
0
      h = elf_sym_hashes (abfd)[indx];
3672
0
      BFD_ASSERT (h != NULL);
3673
3674
0
      if (   h->root.type != bfd_link_hash_defined
3675
0
          && h->root.type != bfd_link_hash_defweak)
3676
        /* This appears to be a reference to an undefined
3677
           symbol.  Just ignore it--it will be caught by the
3678
           regular reloc processing.  */
3679
0
        continue;
3680
3681
0
      symval = h->root.u.def.value;
3682
0
    }
3683
3684
0
        if (symval + irelcall->r_addend != irelcall->r_offset + 4)
3685
0
    {
3686
0
      _bfd_error_handler
3687
        /* xgettext:c-format */
3688
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3689
0
           "unrecognized reloc %#" PRIx64),
3690
0
         abfd, (uint64_t) irel->r_offset, "R_V850_LONGCALL",
3691
0
         (uint64_t) irelcall->r_offset);
3692
0
      continue;
3693
0
    }
3694
3695
        /* Get the value of the symbol referred to by the reloc.  */
3696
0
        if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3697
0
    {
3698
0
      Elf_Internal_Sym *isym;
3699
0
      asection *sym_sec;
3700
3701
      /* A local symbol.  */
3702
0
      isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
3703
3704
0
      if (isym->st_shndx == SHN_UNDEF)
3705
0
        sym_sec = bfd_und_section_ptr;
3706
0
      else if (isym->st_shndx == SHN_ABS)
3707
0
        sym_sec = bfd_abs_section_ptr;
3708
0
      else if (isym->st_shndx == SHN_COMMON)
3709
0
        sym_sec = bfd_com_section_ptr;
3710
0
      else
3711
0
        sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3712
0
      symval = (isym->st_value
3713
0
          + sym_sec->output_section->vma
3714
0
          + sym_sec->output_offset);
3715
0
    }
3716
0
        else
3717
0
    {
3718
0
      unsigned long indx;
3719
0
      struct elf_link_hash_entry *h;
3720
3721
      /* An external symbol.  */
3722
0
      indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info;
3723
0
      h = elf_sym_hashes (abfd)[indx];
3724
0
      BFD_ASSERT (h != NULL);
3725
3726
0
      if (   h->root.type != bfd_link_hash_defined
3727
0
          && h->root.type != bfd_link_hash_defweak)
3728
        /* This appears to be a reference to an undefined
3729
           symbol.  Just ignore it--it will be caught by the
3730
           regular reloc processing.  */
3731
0
        continue;
3732
3733
0
      symval = (h->root.u.def.value
3734
0
          + h->root.u.def.section->output_section->vma
3735
0
          + h->root.u.def.section->output_offset);
3736
0
    }
3737
3738
0
        addend = irel->r_addend;
3739
3740
0
        foff = (symval + addend
3741
0
          - (irel->r_offset
3742
0
       + sec->output_section->vma
3743
0
       + sec->output_offset
3744
0
       + 4));
3745
#ifdef DEBUG_RELAX
3746
        fprintf (stderr, "relax longcall r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
3747
           irel->r_offset,
3748
           (irel->r_offset
3749
      + sec->output_section->vma
3750
      + sec->output_offset),
3751
           symval, addend, foff);
3752
#endif
3753
3754
0
        if (foff < -0x100000 || foff >= 0x100000)
3755
    /* After all that work, we can't shorten this function call.  */
3756
0
    continue;
3757
3758
        /* For simplicity of coding, we are going to modify the section
3759
     contents, the section relocs, and the BFD symbol table.  We
3760
     must tell the rest of the code not to free up this
3761
     information.  It would be possible to instead create a table
3762
     of changes which have to be made, as is done in coff-mips.c;
3763
     that would be more work, but would require less memory when
3764
     the linker is run.  */
3765
0
        elf_section_data (sec)->relocs = internal_relocs;
3766
0
        elf_section_data (sec)->this_hdr.contents = contents;
3767
0
        symtab_hdr->contents = (bfd_byte *) isymbuf;
3768
3769
        /* Replace the long call with a jarl.  */
3770
0
        if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
3771
0
    irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_PCR22);
3772
0
        else
3773
0
    irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_22_PCREL);
3774
3775
0
        addend = 0;
3776
3777
0
        if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3778
    /* If this needs to be changed because of future relaxing,
3779
       it will be handled here like other internal IND12W
3780
       relocs.  */
3781
0
    bfd_put_32 (abfd,
3782
0
          0x00000780 | (JARL_R2 (insn[2])<<11) | ((addend << 16) & 0xffff) | ((addend >> 16) & 0xf),
3783
0
          contents + irel->r_offset);
3784
0
        else
3785
    /* We can't fully resolve this yet, because the external
3786
       symbol value may be changed by future relaxing.
3787
       We let the final link phase handle it.  */
3788
0
    bfd_put_32 (abfd, 0x00000780 | (JARL_R2 (insn[2])<<11),
3789
0
          contents + irel->r_offset);
3790
3791
0
        hi_irelfn->r_info =
3792
0
    ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
3793
0
        lo_irelfn->r_info =
3794
0
    ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
3795
0
        irelcall->r_info =
3796
0
    ELF32_R_INFO (ELF32_R_SYM (irelcall->r_info), R_V850_NONE);
3797
3798
0
        if (! v850_elf_relax_delete_bytes (abfd, sec,
3799
0
             irel->r_offset + 4, toaddr, 12))
3800
0
    goto error_return;
3801
3802
0
        align_pad_size += 12;
3803
0
      }
3804
0
    else if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)
3805
0
      {
3806
        /* Check code for -mlong-jumps output.  */
3807
0
        if (laddr + 10 <= (bfd_vma) sec->size)
3808
0
    {
3809
0
      insn[0] = bfd_get_16 (abfd, contents + laddr);
3810
0
      insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
3811
0
      insn[2] = bfd_get_16 (abfd, contents + laddr + 8);
3812
3813
0
      if ((insn[0] & MOVHI_MASK) != MOVHI
3814
0
           || MOVHI_R1 (insn[0]) != 0)
3815
0
        no_match = 0;
3816
3817
0
      if (no_match < 0
3818
0
          && ((insn[1] & MOVEA_MASK) != MOVEA
3819
0
         || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
3820
0
        no_match = 1;
3821
3822
0
      if (no_match < 0
3823
0
          && ((insn[2] & JMP_R_MASK) != JMP_R
3824
0
         || MOVEA_R2 (insn[1]) != JMP_R1 (insn[2])))
3825
0
        no_match = 2;
3826
0
    }
3827
0
        else
3828
0
    {
3829
0
      _bfd_error_handler
3830
        /* xgettext:c-format */
3831
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3832
0
           "unrecognized insns"),
3833
0
         abfd, (uint64_t) irel->r_offset, "R_V850_LONGJUMP");
3834
0
      continue;
3835
0
    }
3836
3837
0
        if (no_match >= 0)
3838
0
    {
3839
0
      _bfd_error_handler
3840
        /* xgettext:c-format */
3841
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3842
0
           "unrecognized insn %#x"),
3843
0
         abfd,
3844
0
         (uint64_t) (irel->r_offset + no_match),
3845
0
         "R_V850_LONGJUMP",
3846
0
         insn[no_match]);
3847
0
      continue;
3848
0
    }
3849
3850
        /* Get the reloc for the address from which the register is
3851
     being loaded.  This reloc will tell us which function is
3852
     actually being called.  */
3853
0
        for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
3854
0
    {
3855
0
      r_type = ELF32_R_TYPE (hi_irelfn->r_info);
3856
3857
0
      if (hi_irelfn->r_offset == laddr + 2
3858
0
          && ((r_type == (int) R_V850_HI16_S) || r_type == (int) R_V810_WHI1))
3859
0
        break;
3860
0
    }
3861
3862
0
        for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
3863
0
    {
3864
0
      r_type = ELF32_R_TYPE (lo_irelfn->r_info);
3865
3866
0
      if (lo_irelfn->r_offset == laddr + 6
3867
0
          && (r_type == (int) R_V850_LO16 || r_type == (int) R_V810_WLO))
3868
0
        break;
3869
0
    }
3870
3871
0
        if (   hi_irelfn == irelend
3872
0
      || lo_irelfn == irelend)
3873
0
    {
3874
0
      _bfd_error_handler
3875
        /* xgettext:c-format */
3876
0
        (_("%pB: %#" PRIx64 ": warning: %s points to "
3877
0
           "unrecognized reloc"),
3878
0
         abfd, (uint64_t) irel->r_offset, "R_V850_LONGJUMP");
3879
0
      continue;
3880
0
    }
3881
3882
        /* Get the value of the symbol referred to by the reloc.  */
3883
0
        if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3884
0
    {
3885
0
      Elf_Internal_Sym *  isym;
3886
0
      asection *        sym_sec;
3887
3888
      /* A local symbol.  */
3889
0
      isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
3890
3891
0
      if (isym->st_shndx == SHN_UNDEF)
3892
0
        sym_sec = bfd_und_section_ptr;
3893
0
      else if (isym->st_shndx == SHN_ABS)
3894
0
        sym_sec = bfd_abs_section_ptr;
3895
0
      else if (isym->st_shndx == SHN_COMMON)
3896
0
        sym_sec = bfd_com_section_ptr;
3897
0
      else
3898
0
        sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3899
0
      symval = (isym->st_value
3900
0
          + sym_sec->output_section->vma
3901
0
          + sym_sec->output_offset);
3902
#ifdef DEBUG_RELAX
3903
      {
3904
        char * name = bfd_elf_string_from_elf_section
3905
          (abfd, symtab_hdr->sh_link, isym->st_name);
3906
3907
        fprintf (stderr, "relax long jump local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
3908
           sym_sec->name, name, isym->st_name,
3909
           sym_sec->output_section->vma,
3910
           sym_sec->output_offset,
3911
           isym->st_value, irel->r_addend);
3912
      }
3913
#endif
3914
0
    }
3915
0
        else
3916
0
    {
3917
0
      unsigned long indx;
3918
0
      struct elf_link_hash_entry * h;
3919
3920
      /* An external symbol.  */
3921
0
      indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
3922
0
      h = elf_sym_hashes (abfd)[indx];
3923
0
      BFD_ASSERT (h != NULL);
3924
3925
0
      if (   h->root.type != bfd_link_hash_defined
3926
0
          && h->root.type != bfd_link_hash_defweak)
3927
        /* This appears to be a reference to an undefined
3928
           symbol.  Just ignore it--it will be caught by the
3929
           regular reloc processing.  */
3930
0
        continue;
3931
3932
0
      symval = (h->root.u.def.value
3933
0
          + h->root.u.def.section->output_section->vma
3934
0
          + h->root.u.def.section->output_offset);
3935
#ifdef DEBUG_RELAX
3936
      fprintf (stderr,
3937
         "relax longjump defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
3938
         sec->name, h->root.root.string, h->root.u.def.value,
3939
         sec->output_section->vma, sec->output_offset, irel->r_addend);
3940
#endif
3941
0
    }
3942
3943
0
        addend = irel->r_addend;
3944
3945
0
        foff = (symval + addend
3946
0
          - (irel->r_offset
3947
0
       + sec->output_section->vma
3948
0
       + sec->output_offset
3949
0
       + 4));
3950
#ifdef DEBUG_RELAX
3951
        fprintf (stderr, "relax longjump r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
3952
           irel->r_offset,
3953
           (irel->r_offset
3954
      + sec->output_section->vma
3955
      + sec->output_offset),
3956
           symval, addend, foff);
3957
#endif
3958
0
        if (foff < -0x100000 || foff >= 0x100000)
3959
    /* After all that work, we can't shorten this function call.  */
3960
0
    continue;
3961
3962
        /* For simplicity of coding, we are going to modify the section
3963
     contents, the section relocs, and the BFD symbol table.  We
3964
     must tell the rest of the code not to free up this
3965
     information.  It would be possible to instead create a table
3966
     of changes which have to be made, as is done in coff-mips.c;
3967
     that would be more work, but would require less memory when
3968
     the linker is run.  */
3969
0
        elf_section_data (sec)->relocs = internal_relocs;
3970
0
        elf_section_data (sec)->this_hdr.contents = contents;
3971
0
        symtab_hdr->contents = (bfd_byte *) isymbuf;
3972
3973
0
        if (foff < -0x100 || foff >= 0x100)
3974
0
    {
3975
      /* Replace the long jump with a jr.  */
3976
3977
0
      if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
3978
0
        irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_PCR22);
3979
0
      else
3980
0
        irel->r_info =
3981
0
          ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_22_PCREL);
3982
3983
0
      irel->r_addend = addend;
3984
0
      addend = 0;
3985
3986
0
      if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
3987
        /* If this needs to be changed because of future relaxing,
3988
           it will be handled here like other internal IND12W
3989
           relocs.  */
3990
0
        bfd_put_32 (abfd,
3991
0
        0x00000780 | ((addend << 15) & 0xffff0000) | ((addend >> 17) & 0xf),
3992
0
        contents + irel->r_offset);
3993
0
      else
3994
        /* We can't fully resolve this yet, because the external
3995
           symbol value may be changed by future relaxing.
3996
           We let the final link phase handle it.  */
3997
0
        bfd_put_32 (abfd, 0x00000780, contents + irel->r_offset);
3998
3999
0
      hi_irelfn->r_info =
4000
0
      ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
4001
0
      lo_irelfn->r_info =
4002
0
      ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
4003
0
      if (!v850_elf_relax_delete_bytes (abfd, sec,
4004
0
                irel->r_offset + 4, toaddr, 6))
4005
0
        goto error_return;
4006
4007
0
      align_pad_size += 6;
4008
0
    }
4009
0
        else
4010
0
    {
4011
      /* Replace the long jump with a br.  */
4012
4013
0
      if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
4014
0
        irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_PC9);
4015
0
      else
4016
0
        irel->r_info =
4017
0
          ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_9_PCREL);
4018
4019
0
      irel->r_addend = addend;
4020
0
      addend = 0;
4021
4022
0
      if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
4023
        /* If this needs to be changed because of future relaxing,
4024
           it will be handled here like other internal IND12W
4025
           relocs.  */
4026
0
        bfd_put_16 (abfd,
4027
0
        0x0585 | ((addend << 10) & 0xf800) | ((addend << 3) & 0x0070),
4028
0
        contents + irel->r_offset);
4029
0
      else
4030
        /* We can't fully resolve this yet, because the external
4031
           symbol value may be changed by future relaxing.
4032
           We let the final link phase handle it.  */
4033
0
        bfd_put_16 (abfd, 0x0585, contents + irel->r_offset);
4034
4035
0
      hi_irelfn->r_info =
4036
0
      ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
4037
0
      lo_irelfn->r_info =
4038
0
      ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
4039
0
      if (!v850_elf_relax_delete_bytes (abfd, sec,
4040
0
                irel->r_offset + 2, toaddr, 8))
4041
0
        goto error_return;
4042
4043
0
      align_pad_size += 8;
4044
0
    }
4045
0
      }
4046
0
  }
4047
4048
0
      irelalign = NULL;
4049
0
      for (irel = internal_relocs; irel < irelend; irel++)
4050
0
  {
4051
0
    if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
4052
0
        && irel->r_offset == toaddr)
4053
0
      {
4054
0
        irel->r_offset -= align_pad_size;
4055
4056
0
        if (irelalign == NULL || irelalign->r_addend > irel->r_addend)
4057
0
    irelalign = irel;
4058
0
      }
4059
0
  }
4060
4061
0
      addr = toaddr;
4062
0
    }
4063
4064
0
  if (!irelalign)
4065
0
    {
4066
#ifdef DEBUG_RELAX
4067
      fprintf (stderr, "relax pad %d shorten %d -> %d\n",
4068
         align_pad_size,
4069
         sec->size,
4070
         sec->size - align_pad_size);
4071
#endif
4072
0
      sec->size -= align_pad_size;
4073
0
    }
4074
4075
0
 finish:
4076
0
  if (elf_section_data (sec)->relocs != internal_relocs)
4077
0
    free (internal_relocs);
4078
4079
0
  if (elf_section_data (sec)->this_hdr.contents != (unsigned char *) contents)
4080
0
    free (contents);
4081
4082
0
  if (symtab_hdr->contents != (bfd_byte *) isymbuf)
4083
0
    free (isymbuf);
4084
4085
0
  return result;
4086
4087
0
 error_return:
4088
0
  result = false;
4089
0
  goto finish;
4090
0
}
4091
4092
static const struct bfd_elf_special_section v850_elf_special_sections[] =
4093
{
4094
  { STRING_COMMA_LEN (".call_table_data"), 0, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE) },
4095
  { STRING_COMMA_LEN (".call_table_text"), 0, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
4096
                 + SHF_EXECINSTR) },
4097
  { STRING_COMMA_LEN (".rosdata"),    -2, SHT_PROGBITS, (SHF_ALLOC
4098
                 + SHF_V850_GPREL) },
4099
  { STRING_COMMA_LEN (".rozdata"),    -2, SHT_PROGBITS, (SHF_ALLOC
4100
                 + SHF_V850_R0REL) },
4101
  { STRING_COMMA_LEN (".sbss"),     -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
4102
                 + SHF_V850_GPREL) },
4103
  { STRING_COMMA_LEN (".scommon"),    -2, SHT_V850_SCOMMON, (SHF_ALLOC + SHF_WRITE
4104
                 + SHF_V850_GPREL) },
4105
  { STRING_COMMA_LEN (".sdata"),    -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
4106
                 + SHF_V850_GPREL) },
4107
  { STRING_COMMA_LEN (".tbss"),     -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
4108
                 + SHF_V850_EPREL) },
4109
  { STRING_COMMA_LEN (".tcommon"),    -2, SHT_V850_TCOMMON, (SHF_ALLOC + SHF_WRITE
4110
                 + SHF_V850_R0REL) },
4111
  { STRING_COMMA_LEN (".tdata"),    -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
4112
                 + SHF_V850_EPREL) },
4113
  { STRING_COMMA_LEN (".zbss"),     -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
4114
                 + SHF_V850_R0REL) },
4115
  { STRING_COMMA_LEN (".zcommon"),    -2, SHT_V850_ZCOMMON, (SHF_ALLOC + SHF_WRITE
4116
                 + SHF_V850_R0REL) },
4117
  { STRING_COMMA_LEN (".zdata"),    -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
4118
                 + SHF_V850_R0REL) },
4119
  { NULL,         0,     0, 0,    0 }
4120
};
4121

4122
#define TARGET_LITTLE_SYM     v850_elf32_vec
4123
#define TARGET_LITTLE_NAME      "elf32-v850"
4124
#define ELF_ARCH        bfd_arch_v850
4125
#define ELF_MACHINE_CODE      EM_V850
4126
#define ELF_MACHINE_ALT1      EM_CYGNUS_V850
4127
#define ELF_MAXPAGESIZE       0x1000
4128
4129
#define elf_info_to_howto     v850_elf_info_to_howto_rela
4130
#define elf_info_to_howto_rel     v850_elf_info_to_howto_rel
4131
4132
#define elf_backend_check_relocs    v850_elf_check_relocs
4133
#define elf_backend_relocate_section    v850_elf_relocate_section
4134
#define elf_backend_object_p      v850_elf_object_p
4135
#define elf_backend_final_write_processing  v850_elf_final_write_processing
4136
#define elf_backend_section_from_bfd_section  v850_elf_section_from_bfd_section
4137
#define elf_backend_symbol_processing   v850_elf_symbol_processing
4138
#define elf_backend_add_symbol_hook   v850_elf_add_symbol_hook
4139
#define elf_backend_link_output_symbol_hook v850_elf_link_output_symbol_hook
4140
#define elf_backend_section_from_shdr   v850_elf_section_from_shdr
4141
#define elf_backend_fake_sections   v850_elf_fake_sections
4142
#define elf_backend_gc_mark_hook    v850_elf_gc_mark_hook
4143
#define elf_backend_special_sections    v850_elf_special_sections
4144
4145
#define elf_backend_can_gc_sections   1
4146
#define elf_backend_rela_normal     1
4147
4148
#define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
4149
#define bfd_elf32_bfd_is_target_special_symbol  v850_elf_is_target_special_symbol
4150
4151
#define bfd_elf32_bfd_reloc_type_lookup   v850_elf_reloc_type_lookup
4152
#define bfd_elf32_bfd_reloc_name_lookup   v850_elf_reloc_name_lookup
4153
#define bfd_elf32_bfd_merge_private_bfd_data  v850_elf_merge_private_bfd_data
4154
#define bfd_elf32_bfd_set_private_flags   v850_elf_set_private_flags
4155
#define bfd_elf32_bfd_print_private_bfd_data  v850_elf_print_private_bfd_data
4156
#define bfd_elf32_bfd_relax_section   v850_elf_relax_section
4157
4158
#define elf_symbol_leading_char     '_'
4159
4160
#undef  elf32_bed
4161
#define elf32_bed elf32_v850_bed
4162
4163
#include "elf32-target.h"
4164
4165
/* Map BFD reloc types to V800 ELF reloc types.  */
4166
4167
static const struct v850_elf_reloc_map v800_elf_reloc_map[] =
4168
{
4169
  { BFD_RELOC_NONE,         R_V810_NONE    },
4170
  { BFD_RELOC_8,          R_V810_BYTE    },
4171
  { BFD_RELOC_16,         R_V810_HWORD   },
4172
  { BFD_RELOC_32,         R_V810_WORD    },
4173
  { BFD_RELOC_LO16,         R_V810_WLO     },
4174
  { BFD_RELOC_HI16,         R_V810_WHI     },
4175
  { BFD_RELOC_HI16_S,         R_V810_WHI1    },
4176
  { BFD_RELOC_V850_32_PCREL,        R_V850_PC32    },
4177
  { BFD_RELOC_V850_22_PCREL,        R_V850_PCR22   },
4178
  { BFD_RELOC_V850_17_PCREL,        R_V850_PC17    },
4179
  { BFD_RELOC_V850_16_PCREL,        R_V850_PC16U   },
4180
  { BFD_RELOC_V850_9_PCREL,       R_V850_PC9     },
4181
  { BFD_RELOC_V850_LO16_S1,       R_V810_WLO_1   }, /* Or R_V850_HWLO or R_V850_HWLO_1.  */
4182
  { BFD_RELOC_V850_23,          R_V850_WLO23   },
4183
  { BFD_RELOC_V850_LO16_SPLIT_OFFSET, R_V850_BLO     },
4184
  { BFD_RELOC_V850_ZDA_16_16_OFFSET,  R_V810_HWORD   },
4185
  { BFD_RELOC_V850_TDA_16_16_OFFSET,  R_V810_HWORD   },
4186
  { BFD_RELOC_V850_SDA_16_16_OFFSET,  R_V810_HWORD   },
4187
  { BFD_RELOC_V850_SDA_15_16_OFFSET,  R_V810_GPWLO_1 }
4188
};
4189
4190
/* Map a bfd relocation into the appropriate howto structure.  */
4191
4192
static reloc_howto_type *
4193
v800_elf_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code)
4194
0
{
4195
0
  unsigned int i;
4196
4197
0
  BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_v850_rh850);
4198
4199
0
  for (i = ARRAY_SIZE (v800_elf_reloc_map); i --;)
4200
0
    if (v800_elf_reloc_map[i].bfd_reloc_val == code)
4201
0
      {
4202
0
  unsigned int elf_reloc_val = v800_elf_reloc_map[i].elf_reloc_val;
4203
0
  unsigned int idx = elf_reloc_val - R_V810_NONE;
4204
4205
0
  BFD_ASSERT (v800_elf_howto_table[idx].type == elf_reloc_val);
4206
4207
0
  return v800_elf_howto_table + idx;
4208
0
      }
4209
4210
#ifdef DEBUG
4211
  fprintf (stderr, "failed to find v800 equiv of bfd reloc code %d\n", code);
4212
#endif
4213
0
  return NULL;
4214
0
}
4215
4216
static reloc_howto_type *
4217
v800_elf_reloc_name_lookup (bfd * abfd, const char * r_name)
4218
0
{
4219
0
  unsigned int i;
4220
4221
0
  BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_v850_rh850);
4222
4223
0
  for (i = ARRAY_SIZE (v800_elf_howto_table); i--;)
4224
0
    if (v800_elf_howto_table[i].name != NULL
4225
0
  && strcasecmp (v800_elf_howto_table[i].name, r_name) == 0)
4226
0
      return v800_elf_howto_table + i;
4227
4228
0
  return NULL;
4229
0
}
4230
4231
4232
/* Set the howto pointer in CACHE_PTR for a V800 ELF reloc.  */
4233
4234
static bool
4235
v800_elf_info_to_howto (bfd *       abfd,
4236
      arelent *     cache_ptr,
4237
      Elf_Internal_Rela * dst)
4238
0
{
4239
0
  unsigned int r_type = ELF32_R_TYPE (dst->r_info);
4240
4241
0
  if (r_type == R_V800_NONE)
4242
0
    r_type = R_V810_NONE;
4243
4244
0
  if (bfd_get_arch (abfd) != bfd_arch_v850_rh850
4245
0
      || r_type >= (unsigned int) R_V800_max
4246
0
      || r_type < (unsigned int) R_V810_NONE
4247
0
      || (r_type - R_V810_NONE) >= ARRAY_SIZE (v800_elf_howto_table))
4248
0
    {
4249
      /* xgettext:c-format */
4250
0
      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
4251
0
        abfd, r_type);
4252
0
      bfd_set_error (bfd_error_bad_value);
4253
0
      return false;
4254
0
    }
4255
4256
0
  cache_ptr->howto = v800_elf_howto_table + (r_type - R_V810_NONE);
4257
0
  return true;
4258
0
}
4259

4260
#undef  TARGET_LITTLE_SYM
4261
#define TARGET_LITTLE_SYM     v800_elf32_vec
4262
#undef  TARGET_LITTLE_NAME
4263
#define TARGET_LITTLE_NAME      "elf32-v850-rh850"
4264
#undef  ELF_ARCH
4265
#define ELF_ARCH        bfd_arch_v850_rh850
4266
#undef  ELF_MACHINE_CODE
4267
#define ELF_MACHINE_CODE      EM_V800
4268
#undef  ELF_MACHINE_ALT1
4269
4270
#undef  elf32_bed
4271
#define elf32_bed elf32_v850_rh850_bed
4272
4273
#undef  elf_info_to_howto
4274
#define elf_info_to_howto     v800_elf_info_to_howto
4275
#undef  elf_info_to_howto_rel
4276
#define elf_info_to_howto_rel     NULL
4277
#undef  bfd_elf32_bfd_reloc_type_lookup
4278
#define bfd_elf32_bfd_reloc_type_lookup   v800_elf_reloc_type_lookup
4279
#undef  bfd_elf32_bfd_reloc_name_lookup
4280
#define bfd_elf32_bfd_reloc_name_lookup   v800_elf_reloc_name_lookup
4281
4282
#include "elf32-target.h"