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

Subversion Repositories openrisc_me

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

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

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

powered by: WebSVN 2.1.0

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