OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf32-v850.c] - Blame information for rev 178

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.