Coverage Report

Created: 2025-06-24 06:45

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