OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [bfd/] [elf32-v850.c] - Blame information for rev 501

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

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

powered by: WebSVN 2.1.0

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