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

Subversion Repositories openrisc_me

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

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

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

powered by: WebSVN 2.1.0

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