~ubuntu-branches/ubuntu/utopic/binutils-arm64-cross/utopic

« back to all changes in this revision

Viewing changes to binutils-2.23.52.20130611/bfd/elf32-i860.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-06-20 17:38:09 UTC
  • Revision ID: package-import@ubuntu.com-20130620173809-app8lzgvymy5fg6c
Tags: 0.7
Build-depend on binutils-source (>= 2.23.52.20130620-1~).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Intel i860 specific support for 32-bit ELF.
 
2
   Copyright 1993, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
 
3
   2010, 2011, 2012
 
4
   Free Software Foundation, Inc.
 
5
 
 
6
   Full i860 support contributed by Jason Eckhardt <jle@cygnus.com>.
 
7
 
 
8
   This file is part of BFD, the Binary File Descriptor library.
 
9
 
 
10
   This program is free software; you can redistribute it and/or modify
 
11
   it under the terms of the GNU General Public License as published by
 
12
   the Free Software Foundation; either version 3 of the License, or
 
13
   (at your option) any later version.
 
14
 
 
15
   This program is distributed in the hope that it will be useful,
 
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
   GNU General Public License for more details.
 
19
 
 
20
   You should have received a copy of the GNU General Public License
 
21
   along with this program; if not, write to the Free Software
 
22
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
 
23
   MA 02110-1301, USA.  */
 
24
 
 
25
#include "sysdep.h"
 
26
#include "bfd.h"
 
27
#include "libbfd.h"
 
28
#include "elf-bfd.h"
 
29
#include "elf/i860.h"
 
30
 
 
31
/* special_function for R_860_PC26 relocation.  */
 
32
static bfd_reloc_status_type
 
33
i860_howto_pc26_reloc (bfd *abfd ATTRIBUTE_UNUSED,
 
34
                       arelent *reloc_entry,
 
35
                       asymbol *symbol,
 
36
                       void *data ATTRIBUTE_UNUSED,
 
37
                       asection *input_section,
 
38
                       bfd *output_bfd,
 
39
                       char **error_message ATTRIBUTE_UNUSED)
 
40
{
 
41
  bfd_vma insn;
 
42
  bfd_vma relocation;
 
43
  bfd_byte *addr;
 
44
 
 
45
  if (output_bfd != NULL
 
46
      && (symbol->flags & BSF_SECTION_SYM) == 0
 
47
      && (! reloc_entry->howto->partial_inplace
 
48
          || reloc_entry->addend == 0))
 
49
    {
 
50
      reloc_entry->address += input_section->output_offset;
 
51
      return bfd_reloc_ok;
 
52
    }
 
53
 
 
54
  /* Used elf32-mips.c as an example.  */
 
55
  if (bfd_is_und_section (symbol->section)
 
56
      && output_bfd == (bfd *) NULL)
 
57
    return bfd_reloc_undefined;
 
58
 
 
59
  if (bfd_is_com_section (symbol->section))
 
60
    relocation = 0;
 
61
  else
 
62
    relocation = symbol->value;
 
63
 
 
64
  relocation += symbol->section->output_section->vma;
 
65
  relocation += symbol->section->output_offset;
 
66
  relocation += reloc_entry->addend;
 
67
 
 
68
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
 
69
    return bfd_reloc_outofrange;
 
70
 
 
71
  /* Adjust for PC-relative relocation.  */
 
72
  relocation -= (input_section->output_section->vma
 
73
                 + input_section->output_offset
 
74
                 + reloc_entry->address
 
75
                 + 4);
 
76
 
 
77
  /* Check for target out of range.  */
 
78
  if ((bfd_signed_vma)relocation > (0x3ffffff << 2)
 
79
      || (bfd_signed_vma)relocation < (-0x4000000 << 2))
 
80
    return bfd_reloc_outofrange;
 
81
 
 
82
  addr = (bfd_byte *) data + reloc_entry->address;
 
83
  insn = bfd_get_32 (abfd, addr);
 
84
 
 
85
  relocation >>= reloc_entry->howto->rightshift;
 
86
  insn = (insn & ~reloc_entry->howto->dst_mask)
 
87
         | (relocation & reloc_entry->howto->dst_mask);
 
88
 
 
89
  bfd_put_32 (abfd, (bfd_vma) insn, addr);
 
90
 
 
91
  return bfd_reloc_ok;
 
92
}
 
93
 
 
94
/* special_function for R_860_PC16 relocation.  */
 
95
static bfd_reloc_status_type
 
96
i860_howto_pc16_reloc (bfd *abfd,
 
97
                       arelent *reloc_entry,
 
98
                       asymbol *symbol,
 
99
                       void *data,
 
100
                       asection *input_section,
 
101
                       bfd *output_bfd,
 
102
                       char **error_message ATTRIBUTE_UNUSED)
 
103
{
 
104
  bfd_vma insn;
 
105
  bfd_vma relocation;
 
106
  bfd_byte *addr;
 
107
 
 
108
  if (output_bfd != NULL
 
109
      && (symbol->flags & BSF_SECTION_SYM) == 0
 
110
      && (! reloc_entry->howto->partial_inplace
 
111
          || reloc_entry->addend == 0))
 
112
    {
 
113
      reloc_entry->address += input_section->output_offset;
 
114
      return bfd_reloc_ok;
 
115
    }
 
116
 
 
117
  /* Used elf32-mips.c as an example.  */
 
118
  if (bfd_is_und_section (symbol->section)
 
119
      && output_bfd == (bfd *) NULL)
 
120
    return bfd_reloc_undefined;
 
121
 
 
122
  if (bfd_is_com_section (symbol->section))
 
123
    relocation = 0;
 
124
  else
 
125
    relocation = symbol->value;
 
126
 
 
127
  relocation += symbol->section->output_section->vma;
 
128
  relocation += symbol->section->output_offset;
 
129
  relocation += reloc_entry->addend;
 
130
 
 
131
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
 
132
    return bfd_reloc_outofrange;
 
133
 
 
134
  /* Adjust for PC-relative relocation.  */
 
135
  relocation -= (input_section->output_section->vma
 
136
                 + input_section->output_offset
 
137
                 + reloc_entry->address
 
138
                 + 4);
 
139
 
 
140
  /* Check for target out of range.  */
 
141
  if ((bfd_signed_vma)relocation > (0x7fff << 2)
 
142
      || (bfd_signed_vma)relocation < (-0x8000 << 2))
 
143
    return bfd_reloc_outofrange;
 
144
 
 
145
  addr = (bfd_byte *) data + reloc_entry->address;
 
146
  insn = bfd_get_32 (abfd, addr);
 
147
 
 
148
  relocation >>= reloc_entry->howto->rightshift;
 
149
  relocation = (((relocation & 0xf800) << 5) | (relocation & 0x7ff))
 
150
               & reloc_entry->howto->dst_mask;
 
151
  insn = (insn & ~reloc_entry->howto->dst_mask) | relocation;
 
152
 
 
153
  bfd_put_32 (abfd, (bfd_vma) insn, addr);
 
154
 
 
155
  return bfd_reloc_ok;
 
156
}
 
157
 
 
158
/* special_function for R_860_HIGHADJ relocation.  */
 
159
static bfd_reloc_status_type
 
160
i860_howto_highadj_reloc (bfd *abfd,
 
161
                          arelent *reloc_entry,
 
162
                          asymbol *symbol,
 
163
                          void *data,
 
164
                          asection *input_section,
 
165
                          bfd *output_bfd,
 
166
                          char **error_message ATTRIBUTE_UNUSED)
 
167
{
 
168
  bfd_vma insn;
 
169
  bfd_vma relocation;
 
170
  bfd_byte *addr;
 
171
 
 
172
  if (output_bfd != NULL
 
173
      && (symbol->flags & BSF_SECTION_SYM) == 0
 
174
      && (! reloc_entry->howto->partial_inplace
 
175
          || reloc_entry->addend == 0))
 
176
    {
 
177
      reloc_entry->address += input_section->output_offset;
 
178
      return bfd_reloc_ok;
 
179
    }
 
180
 
 
181
  /* Used elf32-mips.c as an example.  */
 
182
  if (bfd_is_und_section (symbol->section)
 
183
      && output_bfd == (bfd *) NULL)
 
184
    return bfd_reloc_undefined;
 
185
 
 
186
  if (bfd_is_com_section (symbol->section))
 
187
    relocation = 0;
 
188
  else
 
189
    relocation = symbol->value;
 
190
 
 
191
  relocation += symbol->section->output_section->vma;
 
192
  relocation += symbol->section->output_offset;
 
193
  relocation += reloc_entry->addend;
 
194
  relocation += 0x8000;
 
195
 
 
196
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
 
197
    return bfd_reloc_outofrange;
 
198
 
 
199
  addr = (bfd_byte *) data + reloc_entry->address;
 
200
  insn = bfd_get_32 (abfd, addr);
 
201
 
 
202
  relocation = ((relocation >> 16) & 0xffff);
 
203
 
 
204
  insn = (insn & 0xffff0000) | relocation;
 
205
 
 
206
  bfd_put_32 (abfd, (bfd_vma) insn, addr);
 
207
 
 
208
  return bfd_reloc_ok;
 
209
}
 
210
 
 
211
/* special_function for R_860_SPLITn relocations.  */
 
212
static bfd_reloc_status_type
 
213
i860_howto_splitn_reloc (bfd *abfd,
 
214
                         arelent *reloc_entry,
 
215
                         asymbol *symbol,
 
216
                         void *data,
 
217
                         asection *input_section,
 
218
                         bfd *output_bfd,
 
219
                         char **error_message ATTRIBUTE_UNUSED)
 
220
{
 
221
  bfd_vma insn;
 
222
  bfd_vma relocation;
 
223
  bfd_byte *addr;
 
224
 
 
225
  if (output_bfd != NULL
 
226
      && (symbol->flags & BSF_SECTION_SYM) == 0
 
227
      && (! reloc_entry->howto->partial_inplace
 
228
          || reloc_entry->addend == 0))
 
229
    {
 
230
      reloc_entry->address += input_section->output_offset;
 
231
      return bfd_reloc_ok;
 
232
    }
 
233
 
 
234
  /* Used elf32-mips.c as an example.  */
 
235
  if (bfd_is_und_section (symbol->section)
 
236
      && output_bfd == (bfd *) NULL)
 
237
    return bfd_reloc_undefined;
 
238
 
 
239
  if (bfd_is_com_section (symbol->section))
 
240
    relocation = 0;
 
241
  else
 
242
    relocation = symbol->value;
 
243
 
 
244
  relocation += symbol->section->output_section->vma;
 
245
  relocation += symbol->section->output_offset;
 
246
  relocation += reloc_entry->addend;
 
247
 
 
248
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
 
249
    return bfd_reloc_outofrange;
 
250
 
 
251
  addr = (bfd_byte *) data + reloc_entry->address;
 
252
  insn = bfd_get_32 (abfd, addr);
 
253
 
 
254
  relocation = (((relocation & 0xf800) << 5) | (relocation & 0x7ff))
 
255
               & reloc_entry->howto->dst_mask;
 
256
  insn = (insn & ~reloc_entry->howto->dst_mask) | relocation;
 
257
 
 
258
  bfd_put_32 (abfd, (bfd_vma) insn, addr);
 
259
 
 
260
  return bfd_reloc_ok;
 
261
}
 
262
 
 
263
/* This howto table is preliminary.  */
 
264
static reloc_howto_type elf32_i860_howto_table [] =
 
265
{
 
266
  /* This relocation does nothing.  */
 
267
  HOWTO (R_860_NONE,            /* type */
 
268
         0,                     /* rightshift */
 
269
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
270
         32,                    /* bitsize */
 
271
         FALSE,                 /* pc_relative */
 
272
         0,                     /* bitpos */
 
273
         complain_overflow_bitfield, /* complain_on_overflow */
 
274
         bfd_elf_generic_reloc, /* special_function */
 
275
         "R_860_NONE",          /* name */
 
276
         FALSE,                 /* partial_inplace */
 
277
         0,                     /* src_mask */
 
278
         0,                     /* dst_mask */
 
279
         FALSE),                /* pcrel_offset */
 
280
 
 
281
  /* A 32-bit absolute relocation.  */
 
282
  HOWTO (R_860_32,              /* type */
 
283
         0,                     /* rightshift */
 
284
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
285
         32,                    /* bitsize */
 
286
         FALSE,                 /* pc_relative */
 
287
         0,                     /* bitpos */
 
288
         complain_overflow_bitfield, /* complain_on_overflow */
 
289
         bfd_elf_generic_reloc, /* special_function */
 
290
         "R_860_32",            /* name */
 
291
         FALSE,                 /* partial_inplace */
 
292
         0xffffffff,            /* src_mask */
 
293
         0xffffffff,            /* dst_mask */
 
294
         FALSE),                /* pcrel_offset */
 
295
 
 
296
  HOWTO (R_860_COPY,            /* type */
 
297
         0,                     /* rightshift */
 
298
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
299
         32,                    /* bitsize */
 
300
         FALSE,                 /* pc_relative */
 
301
         0,                     /* bitpos */
 
302
         complain_overflow_bitfield, /* complain_on_overflow */
 
303
         bfd_elf_generic_reloc, /* special_function */
 
304
         "R_860_COPY",          /* name */
 
305
         TRUE,                  /* partial_inplace */
 
306
         0xffffffff,            /* src_mask */
 
307
         0xffffffff,            /* dst_mask */
 
308
         FALSE),                /* pcrel_offset */
 
309
 
 
310
  HOWTO (R_860_GLOB_DAT,        /* type */
 
311
         0,                     /* rightshift */
 
312
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
313
         32,                    /* bitsize */
 
314
         FALSE,                 /* pc_relative */
 
315
         0,                     /* bitpos */
 
316
         complain_overflow_bitfield, /* complain_on_overflow */
 
317
         bfd_elf_generic_reloc, /* special_function */
 
318
         "R_860_GLOB_DAT",      /* name */
 
319
         TRUE,                  /* partial_inplace */
 
320
         0xffffffff,            /* src_mask */
 
321
         0xffffffff,            /* dst_mask */
 
322
         FALSE),                /* pcrel_offset */
 
323
 
 
324
  HOWTO (R_860_JUMP_SLOT,       /* type */
 
325
         0,                     /* rightshift */
 
326
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
327
         32,                    /* bitsize */
 
328
         FALSE,                 /* pc_relative */
 
329
         0,                     /* bitpos */
 
330
         complain_overflow_bitfield, /* complain_on_overflow */
 
331
         bfd_elf_generic_reloc, /* special_function */
 
332
         "R_860_JUMP_SLOT",     /* name */
 
333
         TRUE,                  /* partial_inplace */
 
334
         0xffffffff,            /* src_mask */
 
335
         0xffffffff,            /* dst_mask */
 
336
         FALSE),                /* pcrel_offset */
 
337
 
 
338
  HOWTO (R_860_RELATIVE,        /* type */
 
339
         0,                     /* rightshift */
 
340
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
341
         32,                    /* bitsize */
 
342
         FALSE,                 /* pc_relative */
 
343
         0,                     /* bitpos */
 
344
         complain_overflow_bitfield, /* complain_on_overflow */
 
345
         bfd_elf_generic_reloc, /* special_function */
 
346
         "R_860_RELATIVE",      /* name */
 
347
         TRUE,                  /* partial_inplace */
 
348
         0xffffffff,            /* src_mask */
 
349
         0xffffffff,            /* dst_mask */
 
350
         FALSE),                /* pcrel_offset */
 
351
 
 
352
  /* A 26-bit PC-relative relocation.  */
 
353
  HOWTO (R_860_PC26,            /* type */
 
354
         2,                     /* rightshift */
 
355
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
356
         26,                    /* bitsize */
 
357
         TRUE,                  /* pc_relative */
 
358
         0,                     /* bitpos */
 
359
         complain_overflow_bitfield, /* complain_on_overflow */
 
360
         i860_howto_pc26_reloc, /* special_function */
 
361
         "R_860_PC26",          /* name */
 
362
         FALSE,                 /* partial_inplace */
 
363
         0x3ffffff,             /* src_mask */
 
364
         0x3ffffff,             /* dst_mask */
 
365
         TRUE),                 /* pcrel_offset */
 
366
 
 
367
  HOWTO (R_860_PLT26,           /* type */
 
368
         0,                     /* rightshift */
 
369
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
370
         26,                    /* bitsize */
 
371
         TRUE,                  /* pc_relative */
 
372
         0,                     /* bitpos */
 
373
         complain_overflow_bitfield, /* complain_on_overflow */
 
374
         bfd_elf_generic_reloc, /* special_function */
 
375
         "R_860_PLT26",         /* name */
 
376
         TRUE,                  /* partial_inplace */
 
377
         0xffffffff,            /* src_mask */
 
378
         0xffffffff,            /* dst_mask */
 
379
         TRUE),                 /* pcrel_offset */
 
380
 
 
381
  /* A 16-bit PC-relative relocation.  */
 
382
  HOWTO (R_860_PC16,            /* type */
 
383
         2,                     /* rightshift */
 
384
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
385
         16,                    /* bitsize */
 
386
         TRUE,                  /* pc_relative */
 
387
         0,                     /* bitpos */
 
388
         complain_overflow_bitfield, /* complain_on_overflow */
 
389
         i860_howto_pc16_reloc, /* special_function */
 
390
         "R_860_PC16",          /* name */
 
391
         FALSE,                 /* partial_inplace */
 
392
         0x1f07ff,              /* src_mask */
 
393
         0x1f07ff,              /* dst_mask */
 
394
         TRUE),                 /* pcrel_offset */
 
395
 
 
396
  HOWTO (R_860_LOW0,            /* type */
 
397
         0,                     /* rightshift */
 
398
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
399
         16,                    /* bitsize */
 
400
         FALSE,                 /* pc_relative */
 
401
         0,                     /* bitpos */
 
402
         complain_overflow_dont, /* complain_on_overflow */
 
403
         bfd_elf_generic_reloc, /* special_function */
 
404
         "R_860_LOW0",          /* name */
 
405
         FALSE,                 /* partial_inplace */
 
406
         0xffff,                /* src_mask */
 
407
         0xffff,                /* dst_mask */
 
408
         FALSE),                /* pcrel_offset */
 
409
 
 
410
  HOWTO (R_860_SPLIT0,          /* type */
 
411
         0,                     /* rightshift */
 
412
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
413
         16,                    /* bitsize */
 
414
         FALSE,                 /* pc_relative */
 
415
         0,                     /* bitpos */
 
416
         complain_overflow_dont, /* complain_on_overflow */
 
417
         i860_howto_splitn_reloc, /* special_function */
 
418
         "R_860_SPLIT0",        /* name */
 
419
         FALSE,                 /* partial_inplace */
 
420
         0x1f07ff,              /* src_mask */
 
421
         0x1f07ff,              /* dst_mask */
 
422
         FALSE),                /* pcrel_offset */
 
423
 
 
424
  HOWTO (R_860_LOW1,            /* type */
 
425
         0,                     /* rightshift */
 
426
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
427
         16,                    /* bitsize */
 
428
         FALSE,                 /* pc_relative */
 
429
         0,                     /* bitpos */
 
430
         complain_overflow_dont, /* complain_on_overflow */
 
431
         bfd_elf_generic_reloc, /* special_function */
 
432
         "R_860_LOW1",          /* name */
 
433
         FALSE,                 /* partial_inplace */
 
434
         0xfffe,                /* src_mask */
 
435
         0xfffe,                /* dst_mask */
 
436
         FALSE),                /* pcrel_offset */
 
437
 
 
438
  HOWTO (R_860_SPLIT1,          /* type */
 
439
         0,                     /* rightshift */
 
440
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
441
         16,                    /* bitsize */
 
442
         FALSE,                 /* pc_relative */
 
443
         0,                     /* bitpos */
 
444
         complain_overflow_dont, /* complain_on_overflow */
 
445
         i860_howto_splitn_reloc, /* special_function */
 
446
         "R_860_SPLIT1",        /* name */
 
447
         FALSE,                 /* partial_inplace */
 
448
         0x1f07fe,              /* src_mask */
 
449
         0x1f07fe,              /* dst_mask */
 
450
         FALSE),                /* pcrel_offset */
 
451
 
 
452
  HOWTO (R_860_LOW2,            /* type */
 
453
         0,                     /* rightshift */
 
454
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
455
         16,                    /* bitsize */
 
456
         FALSE,                 /* pc_relative */
 
457
         0,                     /* bitpos */
 
458
         complain_overflow_dont, /* complain_on_overflow */
 
459
         bfd_elf_generic_reloc, /* special_function */
 
460
         "R_860_LOW2",          /* name */
 
461
         FALSE,                 /* partial_inplace */
 
462
         0xfffc,                /* src_mask */
 
463
         0xfffc,                /* dst_mask */
 
464
         FALSE),                /* pcrel_offset */
 
465
 
 
466
  HOWTO (R_860_SPLIT2,          /* type */
 
467
         0,                     /* rightshift */
 
468
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
469
         16,                    /* bitsize */
 
470
         FALSE,                 /* pc_relative */
 
471
         0,                     /* bitpos */
 
472
         complain_overflow_dont, /* complain_on_overflow */
 
473
         i860_howto_splitn_reloc, /* special_function */
 
474
         "R_860_SPLIT2",        /* name */
 
475
         FALSE,                 /* partial_inplace */
 
476
         0x1f07fc,              /* src_mask */
 
477
         0x1f07fc,              /* dst_mask */
 
478
         FALSE),                /* pcrel_offset */
 
479
 
 
480
  HOWTO (R_860_LOW3,            /* type */
 
481
         0,                     /* rightshift */
 
482
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
483
         16,                    /* bitsize */
 
484
         FALSE,                 /* pc_relative */
 
485
         0,                     /* bitpos */
 
486
         complain_overflow_dont, /* complain_on_overflow */
 
487
         bfd_elf_generic_reloc, /* special_function */
 
488
         "R_860_LOW3",          /* name */
 
489
         FALSE,                 /* partial_inplace */
 
490
         0xfff8,                /* src_mask */
 
491
         0xfff8,                /* dst_mask */
 
492
         FALSE),                /* pcrel_offset */
 
493
 
 
494
  HOWTO (R_860_LOGOT0,          /* type */
 
495
         0,                     /* rightshift */
 
496
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
497
         16,                    /* bitsize */
 
498
         FALSE,                 /* pc_relative */
 
499
         0,                     /* bitpos */
 
500
         complain_overflow_dont, /* complain_on_overflow */
 
501
         bfd_elf_generic_reloc, /* special_function */
 
502
         "R_860_LOGOT0",        /* name */
 
503
         FALSE,                 /* partial_inplace */
 
504
         0,                     /* src_mask */
 
505
         0xffff,                /* dst_mask */
 
506
         TRUE),                 /* pcrel_offset */
 
507
 
 
508
  HOWTO (R_860_SPGOT0,          /* type */
 
509
         0,                     /* rightshift */
 
510
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
511
         16,                    /* bitsize */
 
512
         FALSE,                 /* pc_relative */
 
513
         0,                     /* bitpos */
 
514
         complain_overflow_dont, /* complain_on_overflow */
 
515
         bfd_elf_generic_reloc, /* special_function */
 
516
         "R_860_SPGOT0",        /* name */
 
517
         FALSE,                 /* partial_inplace */
 
518
         0,                     /* src_mask */
 
519
         0xffff,                /* dst_mask */
 
520
         TRUE),                 /* pcrel_offset */
 
521
 
 
522
  HOWTO (R_860_LOGOT1,          /* type */
 
523
         0,                     /* rightshift */
 
524
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
525
         16,                    /* bitsize */
 
526
         FALSE,                 /* pc_relative */
 
527
         0,                     /* bitpos */
 
528
         complain_overflow_dont, /* complain_on_overflow */
 
529
         bfd_elf_generic_reloc, /* special_function */
 
530
         "R_860_LOGOT1",        /* name */
 
531
         FALSE,                 /* partial_inplace */
 
532
         0,                     /* src_mask */
 
533
         0xffff,                /* dst_mask */
 
534
         TRUE),                 /* pcrel_offset */
 
535
 
 
536
  HOWTO (R_860_SPGOT1,          /* type */
 
537
         0,                     /* rightshift */
 
538
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
539
         16,                    /* bitsize */
 
540
         FALSE,                 /* pc_relative */
 
541
         0,                     /* bitpos */
 
542
         complain_overflow_dont, /* complain_on_overflow */
 
543
         bfd_elf_generic_reloc, /* special_function */
 
544
         "R_860_SPGOT1",        /* name */
 
545
         FALSE,                 /* partial_inplace */
 
546
         0,                     /* src_mask */
 
547
         0xffff,                /* dst_mask */
 
548
         TRUE),                 /* pcrel_offset */
 
549
 
 
550
  HOWTO (R_860_LOGOTOFF0,        /* type */
 
551
         0,                     /* rightshift */
 
552
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
553
         32,                    /* bitsize */
 
554
         FALSE,                 /* pc_relative */
 
555
         0,                     /* bitpos */
 
556
         complain_overflow_dont, /* complain_on_overflow */
 
557
         bfd_elf_generic_reloc, /* special_function */
 
558
         "R_860_LOGOTOFF0",     /* name */
 
559
         TRUE,                  /* partial_inplace */
 
560
         0xffffffff,            /* src_mask */
 
561
         0xffffffff,            /* dst_mask */
 
562
         FALSE),                /* pcrel_offset */
 
563
 
 
564
  HOWTO (R_860_SPGOTOFF0,        /* type */
 
565
         0,                     /* rightshift */
 
566
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
567
         32,                    /* bitsize */
 
568
         FALSE,                 /* pc_relative */
 
569
         0,                     /* bitpos */
 
570
         complain_overflow_dont, /* complain_on_overflow */
 
571
         bfd_elf_generic_reloc, /* special_function */
 
572
         "R_860_SPGOTOFF0",     /* name */
 
573
         TRUE,                  /* partial_inplace */
 
574
         0xffffffff,            /* src_mask */
 
575
         0xffffffff,            /* dst_mask */
 
576
         FALSE),                /* pcrel_offset */
 
577
 
 
578
  HOWTO (R_860_LOGOTOFF1,        /* type */
 
579
         0,                     /* rightshift */
 
580
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
581
         32,                    /* bitsize */
 
582
         FALSE,                 /* pc_relative */
 
583
         0,                     /* bitpos */
 
584
         complain_overflow_dont, /* complain_on_overflow */
 
585
         bfd_elf_generic_reloc, /* special_function */
 
586
         "R_860_LOGOTOFF1",     /* name */
 
587
         TRUE,                  /* partial_inplace */
 
588
         0xffffffff,            /* src_mask */
 
589
         0xffffffff,            /* dst_mask */
 
590
         FALSE),                /* pcrel_offset */
 
591
 
 
592
  HOWTO (R_860_SPGOTOFF1,       /* type */
 
593
         0,                     /* rightshift */
 
594
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
595
         32,                    /* bitsize */
 
596
         FALSE,                 /* pc_relative */
 
597
         0,                     /* bitpos */
 
598
         complain_overflow_dont, /* complain_on_overflow */
 
599
         bfd_elf_generic_reloc, /* special_function */
 
600
         "R_860_SPGOTOFF1",     /* name */
 
601
         TRUE,                  /* partial_inplace */
 
602
         0xffffffff,            /* src_mask */
 
603
         0xffffffff,            /* dst_mask */
 
604
         FALSE),                /* pcrel_offset */
 
605
 
 
606
  HOWTO (R_860_LOGOTOFF2,        /* type */
 
607
         0,                     /* rightshift */
 
608
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
609
         32,                    /* bitsize */
 
610
         FALSE,                 /* pc_relative */
 
611
         0,                     /* bitpos */
 
612
         complain_overflow_dont, /* complain_on_overflow */
 
613
         bfd_elf_generic_reloc, /* special_function */
 
614
         "R_860_LOGOTOFF2",     /* name */
 
615
         TRUE,                  /* partial_inplace */
 
616
         0xffffffff,            /* src_mask */
 
617
         0xffffffff,            /* dst_mask */
 
618
         FALSE),                /* pcrel_offset */
 
619
 
 
620
  HOWTO (R_860_LOGOTOFF3,        /* type */
 
621
         0,                     /* rightshift */
 
622
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
623
         32,                    /* bitsize */
 
624
         FALSE,                 /* pc_relative */
 
625
         0,                     /* bitpos */
 
626
         complain_overflow_dont, /* complain_on_overflow */
 
627
         bfd_elf_generic_reloc, /* special_function */
 
628
         "R_860_LOGOTOFF3",     /* name */
 
629
         TRUE,                  /* partial_inplace */
 
630
         0xffffffff,            /* src_mask */
 
631
         0xffffffff,            /* dst_mask */
 
632
         FALSE),                /* pcrel_offset */
 
633
 
 
634
  HOWTO (R_860_LOPC,            /* type */
 
635
         0,                     /* rightshift */
 
636
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
637
         16,                    /* bitsize */
 
638
         TRUE,                  /* pc_relative */
 
639
         0,                     /* bitpos */
 
640
         complain_overflow_bitfield, /* complain_on_overflow */
 
641
         bfd_elf_generic_reloc, /* special_function */
 
642
         "R_860_LOPC",          /* name */
 
643
         FALSE,                 /* partial_inplace */
 
644
         0xffff,                /* src_mask */
 
645
         0xffff,                /* dst_mask */
 
646
         TRUE),                 /* pcrel_offset */
 
647
 
 
648
  HOWTO (R_860_HIGHADJ,         /* type */
 
649
         0,                     /* rightshift */
 
650
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
651
         16,                    /* bitsize */
 
652
         FALSE,                 /* pc_relative */
 
653
         0,                     /* bitpos */
 
654
         complain_overflow_dont, /* complain_on_overflow */
 
655
         i860_howto_highadj_reloc, /* special_function */
 
656
         "R_860_HIGHADJ",       /* name */
 
657
         FALSE,                 /* partial_inplace */
 
658
         0xffff,                /* src_mask */
 
659
         0xffff,                /* dst_mask */
 
660
         FALSE),                /* pcrel_offset */
 
661
 
 
662
  HOWTO (R_860_HAGOT,           /* type */
 
663
         0,                     /* rightshift */
 
664
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
665
         16,                    /* bitsize */
 
666
         FALSE,                 /* pc_relative */
 
667
         0,                     /* bitpos */
 
668
         complain_overflow_dont, /* complain_on_overflow */
 
669
         bfd_elf_generic_reloc, /* special_function */
 
670
         "R_860_HAGOT",         /* name */
 
671
         FALSE,                 /* partial_inplace */
 
672
         0,                     /* src_mask */
 
673
         0xffff,                /* dst_mask */
 
674
         TRUE),                 /* pcrel_offset */
 
675
 
 
676
  HOWTO (R_860_HAGOTOFF,        /* type */
 
677
         0,                     /* rightshift */
 
678
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
679
         32,                    /* bitsize */
 
680
         FALSE,                 /* pc_relative */
 
681
         0,                     /* bitpos */
 
682
         complain_overflow_dont, /* complain_on_overflow */
 
683
         bfd_elf_generic_reloc, /* special_function */
 
684
         "R_860_HAGOTOFF",      /* name */
 
685
         TRUE,                  /* partial_inplace */
 
686
         0xffffffff,            /* src_mask */
 
687
         0xffffffff,            /* dst_mask */
 
688
         FALSE),                /* pcrel_offset */
 
689
 
 
690
  HOWTO (R_860_HAPC,            /* type */
 
691
         0,                     /* rightshift */
 
692
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
693
         16,                    /* bitsize */
 
694
         TRUE,                  /* pc_relative */
 
695
         0,                     /* bitpos */
 
696
         complain_overflow_bitfield, /* complain_on_overflow */
 
697
         bfd_elf_generic_reloc, /* special_function */
 
698
         "R_860_HAPC",          /* name */
 
699
         FALSE,                 /* partial_inplace */
 
700
         0xffff,                /* src_mask */
 
701
         0xffff,                /* dst_mask */
 
702
         TRUE),                 /* pcrel_offset */
 
703
 
 
704
  HOWTO (R_860_HIGH,            /* type */
 
705
         16,                    /* rightshift */
 
706
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
707
         16,                    /* bitsize */
 
708
         FALSE,                 /* pc_relative */
 
709
         0,                     /* bitpos */
 
710
         complain_overflow_dont, /* complain_on_overflow */
 
711
         bfd_elf_generic_reloc, /* special_function */
 
712
         "R_860_HIGH",          /* name */
 
713
         FALSE,                 /* partial_inplace */
 
714
         0xffff,                /* src_mask */
 
715
         0xffff,                /* dst_mask */
 
716
         FALSE),                /* pcrel_offset */
 
717
 
 
718
  HOWTO (R_860_HIGOT,           /* type */
 
719
         0,                     /* rightshift */
 
720
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
721
         16,                    /* bitsize */
 
722
         FALSE,                 /* pc_relative */
 
723
         0,                     /* bitpos */
 
724
         complain_overflow_dont, /* complain_on_overflow */
 
725
         bfd_elf_generic_reloc, /* special_function */
 
726
         "R_860_HIGOT",         /* name */
 
727
         FALSE,                 /* partial_inplace */
 
728
         0,                     /* src_mask */
 
729
         0xffff,                /* dst_mask */
 
730
         TRUE),                 /* pcrel_offset */
 
731
 
 
732
  HOWTO (R_860_HIGOTOFF,        /* type */
 
733
         0,                     /* rightshift */
 
734
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
735
         32,                    /* bitsize */
 
736
         FALSE,                 /* pc_relative */
 
737
         0,                     /* bitpos */
 
738
         complain_overflow_dont, /* complain_on_overflow */
 
739
         bfd_elf_generic_reloc, /* special_function */
 
740
         "R_860_HIGOTOFF",      /* name */
 
741
         TRUE,                  /* partial_inplace */
 
742
         0xffffffff,            /* src_mask */
 
743
         0xffffffff,            /* dst_mask */
 
744
         FALSE),                /* pcrel_offset */
 
745
};
 
746
 
 
747
static unsigned char elf_code_to_howto_index[R_860_max + 1];
 
748
 
 
749
static reloc_howto_type *
 
750
lookup_howto (unsigned int rtype)
 
751
{
 
752
  static int initialized = 0;
 
753
  int i;
 
754
  int howto_tbl_size = (int) (sizeof (elf32_i860_howto_table)
 
755
                        / sizeof (elf32_i860_howto_table[0]));
 
756
 
 
757
  if (! initialized)
 
758
    {
 
759
      initialized = 1;
 
760
      memset (elf_code_to_howto_index, 0xff,
 
761
              sizeof (elf_code_to_howto_index));
 
762
      for (i = 0; i < howto_tbl_size; i++)
 
763
        elf_code_to_howto_index[elf32_i860_howto_table[i].type] = i;
 
764
    }
 
765
 
 
766
  BFD_ASSERT (rtype <= R_860_max);
 
767
  i = elf_code_to_howto_index[rtype];
 
768
  if (i >= howto_tbl_size)
 
769
    return 0;
 
770
  return elf32_i860_howto_table + i;
 
771
}
 
772
 
 
773
/* Given a BFD reloc, return the matching HOWTO structure.  */
 
774
static reloc_howto_type *
 
775
elf32_i860_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 
776
                              bfd_reloc_code_real_type code)
 
777
{
 
778
  unsigned int rtype;
 
779
 
 
780
  switch (code)
 
781
    {
 
782
    case BFD_RELOC_NONE:
 
783
      rtype = R_860_NONE;
 
784
      break;
 
785
    case BFD_RELOC_32:
 
786
      rtype = R_860_32;
 
787
      break;
 
788
    case BFD_RELOC_860_COPY:
 
789
      rtype = R_860_COPY;
 
790
      break;
 
791
    case BFD_RELOC_860_GLOB_DAT:
 
792
      rtype = R_860_GLOB_DAT;
 
793
      break;
 
794
    case BFD_RELOC_860_JUMP_SLOT:
 
795
      rtype = R_860_JUMP_SLOT;
 
796
      break;
 
797
    case BFD_RELOC_860_RELATIVE:
 
798
      rtype = R_860_RELATIVE;
 
799
      break;
 
800
    case BFD_RELOC_860_PC26:
 
801
      rtype = R_860_PC26;
 
802
      break;
 
803
    case BFD_RELOC_860_PLT26:
 
804
      rtype = R_860_PLT26;
 
805
      break;
 
806
    case BFD_RELOC_860_PC16:
 
807
      rtype = R_860_PC16;
 
808
      break;
 
809
    case BFD_RELOC_860_LOW0:
 
810
      rtype = R_860_LOW0;
 
811
      break;
 
812
    case BFD_RELOC_860_SPLIT0:
 
813
      rtype = R_860_SPLIT0;
 
814
      break;
 
815
    case BFD_RELOC_860_LOW1:
 
816
      rtype = R_860_LOW1;
 
817
      break;
 
818
    case BFD_RELOC_860_SPLIT1:
 
819
      rtype = R_860_SPLIT1;
 
820
      break;
 
821
    case BFD_RELOC_860_LOW2:
 
822
      rtype = R_860_LOW2;
 
823
      break;
 
824
    case BFD_RELOC_860_SPLIT2:
 
825
      rtype = R_860_SPLIT2;
 
826
      break;
 
827
    case BFD_RELOC_860_LOW3:
 
828
      rtype = R_860_LOW3;
 
829
      break;
 
830
    case BFD_RELOC_860_LOGOT0:
 
831
      rtype = R_860_LOGOT0;
 
832
      break;
 
833
    case BFD_RELOC_860_SPGOT0:
 
834
      rtype = R_860_SPGOT0;
 
835
      break;
 
836
    case BFD_RELOC_860_LOGOT1:
 
837
      rtype = R_860_LOGOT1;
 
838
      break;
 
839
    case BFD_RELOC_860_SPGOT1:
 
840
      rtype = R_860_SPGOT1;
 
841
      break;
 
842
    case BFD_RELOC_860_LOGOTOFF0:
 
843
      rtype = R_860_LOGOTOFF0;
 
844
      break;
 
845
    case BFD_RELOC_860_SPGOTOFF0:
 
846
      rtype = R_860_SPGOTOFF0;
 
847
      break;
 
848
    case BFD_RELOC_860_LOGOTOFF1:
 
849
      rtype = R_860_LOGOTOFF1;
 
850
      break;
 
851
    case BFD_RELOC_860_SPGOTOFF1:
 
852
      rtype = R_860_SPGOTOFF1;
 
853
      break;
 
854
    case BFD_RELOC_860_LOGOTOFF2:
 
855
      rtype = R_860_LOGOTOFF2;
 
856
      break;
 
857
    case BFD_RELOC_860_LOGOTOFF3:
 
858
      rtype = R_860_LOGOTOFF3;
 
859
      break;
 
860
    case BFD_RELOC_860_LOPC:
 
861
      rtype = R_860_LOPC;
 
862
      break;
 
863
    case BFD_RELOC_860_HIGHADJ:
 
864
      rtype = R_860_HIGHADJ;
 
865
      break;
 
866
    case BFD_RELOC_860_HAGOT:
 
867
      rtype = R_860_HAGOT;
 
868
      break;
 
869
    case BFD_RELOC_860_HAGOTOFF:
 
870
      rtype = R_860_HAGOTOFF;
 
871
      break;
 
872
    case BFD_RELOC_860_HAPC:
 
873
      rtype = R_860_HAPC;
 
874
      break;
 
875
    case BFD_RELOC_860_HIGH:
 
876
      rtype = R_860_HIGH;
 
877
      break;
 
878
    case BFD_RELOC_860_HIGOT:
 
879
      rtype = R_860_HIGOT;
 
880
      break;
 
881
    case BFD_RELOC_860_HIGOTOFF:
 
882
      rtype = R_860_HIGOTOFF;
 
883
      break;
 
884
    default:
 
885
      rtype = 0;
 
886
      break;
 
887
    }
 
888
  return lookup_howto (rtype);
 
889
}
 
890
 
 
891
static reloc_howto_type *
 
892
elf32_i860_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 
893
                              const char *r_name)
 
894
{
 
895
  unsigned int i;
 
896
 
 
897
  for (i = 0;
 
898
       i < (sizeof (elf32_i860_howto_table)
 
899
            / sizeof (elf32_i860_howto_table[0]));
 
900
       i++)
 
901
    if (elf32_i860_howto_table[i].name != NULL
 
902
        && strcasecmp (elf32_i860_howto_table[i].name, r_name) == 0)
 
903
      return &elf32_i860_howto_table[i];
 
904
 
 
905
  return NULL;
 
906
}
 
907
 
 
908
/* Given a ELF reloc, return the matching HOWTO structure.  */
 
909
static void
 
910
elf32_i860_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
 
911
                               arelent *bfd_reloc,
 
912
                               Elf_Internal_Rela *elf_reloc)
 
913
{
 
914
  bfd_reloc->howto
 
915
    = lookup_howto ((unsigned) ELF32_R_TYPE (elf_reloc->r_info));
 
916
}
 
917
 
 
918
/* Specialized relocation handler for R_860_SPLITn.  These relocations
 
919
   involves a 16-bit field that is split into two contiguous parts.  */
 
920
static bfd_reloc_status_type
 
921
elf32_i860_relocate_splitn (bfd *input_bfd,
 
922
                            Elf_Internal_Rela *rello,
 
923
                            bfd_byte *contents,
 
924
                            bfd_vma value)
 
925
{
 
926
  bfd_vma insn;
 
927
  reloc_howto_type *howto;
 
928
  howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
 
929
  insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
 
930
 
 
931
  /* Relocate.  */
 
932
  value += rello->r_addend;
 
933
 
 
934
  /* Separate the fields and insert.  */
 
935
  value = (((value & 0xf800) << 5) | (value & 0x7ff)) & howto->dst_mask;
 
936
  insn = (insn & ~howto->dst_mask) | value;
 
937
 
 
938
  bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
 
939
  return bfd_reloc_ok;
 
940
}
 
941
 
 
942
/* Specialized relocation handler for R_860_PC16.  This relocation
 
943
   involves a 16-bit, PC-relative field that is split into two contiguous
 
944
   parts.  */
 
945
static bfd_reloc_status_type
 
946
elf32_i860_relocate_pc16 (bfd *input_bfd,
 
947
                          asection *input_section,
 
948
                          Elf_Internal_Rela *rello,
 
949
                          bfd_byte *contents,
 
950
                          bfd_vma value)
 
951
{
 
952
  bfd_vma insn;
 
953
  reloc_howto_type *howto;
 
954
  howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
 
955
  insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
 
956
 
 
957
  /* Adjust for PC-relative relocation.  */
 
958
  value -= (input_section->output_section->vma
 
959
            + input_section->output_offset);
 
960
  value -= rello->r_offset;
 
961
 
 
962
  /* Relocate.  */
 
963
  value += rello->r_addend;
 
964
 
 
965
  /* Adjust the value by 4, then separate the fields and insert.  */
 
966
  value = (value - 4) >> howto->rightshift;
 
967
  value = (((value & 0xf800) << 5) | (value & 0x7ff)) & howto->dst_mask;
 
968
  insn = (insn & ~howto->dst_mask) | value;
 
969
 
 
970
  bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
 
971
  return bfd_reloc_ok;
 
972
 
 
973
}
 
974
 
 
975
/* Specialized relocation handler for R_860_PC26.  This relocation
 
976
   involves a 26-bit, PC-relative field which must be adjusted by 4.  */
 
977
static bfd_reloc_status_type
 
978
elf32_i860_relocate_pc26 (bfd *input_bfd,
 
979
                          asection *input_section,
 
980
                          Elf_Internal_Rela *rello,
 
981
                          bfd_byte *contents,
 
982
                          bfd_vma value)
 
983
{
 
984
  bfd_vma insn;
 
985
  reloc_howto_type *howto;
 
986
  howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
 
987
  insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
 
988
 
 
989
  /* Adjust for PC-relative relocation.  */
 
990
  value -= (input_section->output_section->vma
 
991
            + input_section->output_offset);
 
992
  value -= rello->r_offset;
 
993
 
 
994
  /* Relocate.  */
 
995
  value += rello->r_addend;
 
996
 
 
997
  /* Adjust value by 4 and insert the field.  */
 
998
  value = ((value - 4) >> howto->rightshift) & howto->dst_mask;
 
999
  insn = (insn & ~howto->dst_mask) | value;
 
1000
 
 
1001
  bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
 
1002
  return bfd_reloc_ok;
 
1003
 
 
1004
}
 
1005
 
 
1006
/* Specialized relocation handler for R_860_HIGHADJ.  */
 
1007
static bfd_reloc_status_type
 
1008
elf32_i860_relocate_highadj (bfd *input_bfd,
 
1009
                             Elf_Internal_Rela *rel,
 
1010
                             bfd_byte *contents,
 
1011
                             bfd_vma value)
 
1012
{
 
1013
  bfd_vma insn;
 
1014
 
 
1015
  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
 
1016
 
 
1017
  value += rel->r_addend;
 
1018
  value += 0x8000;
 
1019
  value = ((value >> 16) & 0xffff);
 
1020
 
 
1021
  insn = (insn & 0xffff0000) | value;
 
1022
 
 
1023
  bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
 
1024
  return bfd_reloc_ok;
 
1025
}
 
1026
 
 
1027
/* Perform a single relocation.  By default we use the standard BFD
 
1028
   routines. However, we handle some specially.  */
 
1029
static bfd_reloc_status_type
 
1030
i860_final_link_relocate (reloc_howto_type *howto,
 
1031
                          bfd *input_bfd,
 
1032
                          asection *input_section,
 
1033
                          bfd_byte *contents,
 
1034
                          Elf_Internal_Rela *rel,
 
1035
                          bfd_vma relocation)
 
1036
{
 
1037
  return _bfd_final_link_relocate (howto, input_bfd, input_section,
 
1038
                                   contents, rel->r_offset, relocation,
 
1039
                                   rel->r_addend);
 
1040
}
 
1041
 
 
1042
/* Relocate an i860 ELF section.
 
1043
 
 
1044
   This is boiler-plate code copied from fr30.
 
1045
 
 
1046
   The RELOCATE_SECTION function is called by the new ELF backend linker
 
1047
   to handle the relocations for a section.
 
1048
 
 
1049
   The relocs are always passed as Rela structures; if the section
 
1050
   actually uses Rel structures, the r_addend field will always be
 
1051
   zero.
 
1052
 
 
1053
   This function is responsible for adjusting the section contents as
 
1054
   necessary, and (if using Rela relocs and generating a relocatable
 
1055
   output file) adjusting the reloc addend as necessary.
 
1056
 
 
1057
   This function does not have to worry about setting the reloc
 
1058
   address or the reloc symbol index.
 
1059
 
 
1060
   LOCAL_SYMS is a pointer to the swapped in local symbols.
 
1061
 
 
1062
   LOCAL_SECTIONS is an array giving the section in the input file
 
1063
   corresponding to the st_shndx field of each local symbol.
 
1064
 
 
1065
   The global hash table entry for the global symbols can be found
 
1066
   via elf_sym_hashes (input_bfd).
 
1067
 
 
1068
   When generating relocatable output, this function must handle
 
1069
   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
 
1070
   going to be the section symbol corresponding to the output
 
1071
   section, which means that the addend must be adjusted
 
1072
   accordingly.  */
 
1073
static bfd_boolean
 
1074
elf32_i860_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
 
1075
                             struct bfd_link_info *info,
 
1076
                             bfd *input_bfd,
 
1077
                             asection *input_section,
 
1078
                             bfd_byte *contents,
 
1079
                             Elf_Internal_Rela *relocs,
 
1080
                             Elf_Internal_Sym *local_syms,
 
1081
                             asection **local_sections)
 
1082
{
 
1083
  Elf_Internal_Shdr *symtab_hdr;
 
1084
  struct elf_link_hash_entry **sym_hashes;
 
1085
  Elf_Internal_Rela *rel;
 
1086
  Elf_Internal_Rela *relend;
 
1087
 
 
1088
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
 
1089
  sym_hashes = elf_sym_hashes (input_bfd);
 
1090
  relend     = relocs + input_section->reloc_count;
 
1091
 
 
1092
  for (rel = relocs; rel < relend; rel ++)
 
1093
    {
 
1094
      reloc_howto_type *           howto;
 
1095
      unsigned long                r_symndx;
 
1096
      Elf_Internal_Sym *           sym;
 
1097
      asection *                   sec;
 
1098
      struct elf_link_hash_entry * h;
 
1099
      bfd_vma                      relocation;
 
1100
      bfd_reloc_status_type        r;
 
1101
      const char *                 name = NULL;
 
1102
      int                          r_type;
 
1103
 
 
1104
      r_type = ELF32_R_TYPE (rel->r_info);
 
1105
      r_symndx = ELF32_R_SYM (rel->r_info);
 
1106
 
 
1107
      howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info));
 
1108
      h     = NULL;
 
1109
      sym   = NULL;
 
1110
      sec   = NULL;
 
1111
 
 
1112
      if (r_symndx < symtab_hdr->sh_info)
 
1113
        {
 
1114
          sym = local_syms + r_symndx;
 
1115
          sec = local_sections [r_symndx];
 
1116
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
 
1117
 
 
1118
          name = bfd_elf_string_from_elf_section
 
1119
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
 
1120
          name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
 
1121
        }
 
1122
      else
 
1123
        {
 
1124
          bfd_boolean unresolved_reloc, warned;
 
1125
 
 
1126
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
 
1127
                                   r_symndx, symtab_hdr, sym_hashes,
 
1128
                                   h, sec, relocation,
 
1129
                                   unresolved_reloc, warned);
 
1130
        }
 
1131
 
 
1132
      if (sec != NULL && discarded_section (sec))
 
1133
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
 
1134
                                         rel, 1, relend, howto, 0, contents);
 
1135
 
 
1136
      if (info->relocatable)
 
1137
        continue;
 
1138
 
 
1139
      switch (r_type)
 
1140
        {
 
1141
        default:
 
1142
          r = i860_final_link_relocate (howto, input_bfd, input_section,
 
1143
                                        contents, rel, relocation);
 
1144
          break;
 
1145
 
 
1146
        case R_860_HIGHADJ:
 
1147
          r = elf32_i860_relocate_highadj (input_bfd, rel, contents,
 
1148
                                           relocation);
 
1149
          break;
 
1150
 
 
1151
        case R_860_PC16:
 
1152
          r = elf32_i860_relocate_pc16 (input_bfd, input_section, rel,
 
1153
                                        contents, relocation);
 
1154
          break;
 
1155
 
 
1156
        case R_860_PC26:
 
1157
          r = elf32_i860_relocate_pc26 (input_bfd, input_section, rel,
 
1158
                                        contents, relocation);
 
1159
          break;
 
1160
 
 
1161
        case R_860_SPLIT0:
 
1162
        case R_860_SPLIT1:
 
1163
        case R_860_SPLIT2:
 
1164
          r = elf32_i860_relocate_splitn (input_bfd, rel, contents,
 
1165
                                          relocation);
 
1166
          break;
 
1167
 
 
1168
        /* We do not yet handle GOT/PLT/Dynamic relocations.  */
 
1169
        case R_860_COPY:
 
1170
        case R_860_GLOB_DAT:
 
1171
        case R_860_JUMP_SLOT:
 
1172
        case R_860_RELATIVE:
 
1173
        case R_860_PLT26:
 
1174
        case R_860_LOGOT0:
 
1175
        case R_860_SPGOT0:
 
1176
        case R_860_LOGOT1:
 
1177
        case R_860_SPGOT1:
 
1178
        case R_860_LOGOTOFF0:
 
1179
        case R_860_SPGOTOFF0:
 
1180
        case R_860_LOGOTOFF1:
 
1181
        case R_860_SPGOTOFF1:
 
1182
        case R_860_LOGOTOFF2:
 
1183
        case R_860_LOGOTOFF3:
 
1184
        case R_860_LOPC:
 
1185
        case R_860_HAGOT:
 
1186
        case R_860_HAGOTOFF:
 
1187
        case R_860_HAPC:
 
1188
        case R_860_HIGOT:
 
1189
        case R_860_HIGOTOFF:
 
1190
          r = bfd_reloc_notsupported;
 
1191
          break;
 
1192
        }
 
1193
 
 
1194
      if (r != bfd_reloc_ok)
 
1195
        {
 
1196
          const char * msg = (const char *) NULL;
 
1197
 
 
1198
          switch (r)
 
1199
            {
 
1200
            case bfd_reloc_overflow:
 
1201
              r = info->callbacks->reloc_overflow
 
1202
                (info, (h ? &h->root : NULL), name, howto->name,
 
1203
                 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
 
1204
              break;
 
1205
 
 
1206
            case bfd_reloc_undefined:
 
1207
              r = info->callbacks->undefined_symbol
 
1208
                (info, name, input_bfd, input_section, rel->r_offset, TRUE);
 
1209
              break;
 
1210
 
 
1211
            case bfd_reloc_outofrange:
 
1212
              msg = _("internal error: out of range error");
 
1213
              break;
 
1214
 
 
1215
            case bfd_reloc_notsupported:
 
1216
              msg = _("internal error: unsupported relocation error");
 
1217
              break;
 
1218
 
 
1219
            case bfd_reloc_dangerous:
 
1220
              msg = _("internal error: dangerous relocation");
 
1221
              break;
 
1222
 
 
1223
            default:
 
1224
              msg = _("internal error: unknown error");
 
1225
              break;
 
1226
            }
 
1227
 
 
1228
          if (msg)
 
1229
            r = info->callbacks->warning
 
1230
              (info, msg, name, input_bfd, input_section, rel->r_offset);
 
1231
 
 
1232
          if (! r)
 
1233
            return FALSE;
 
1234
        }
 
1235
    }
 
1236
 
 
1237
  return TRUE;
 
1238
}
 
1239
 
 
1240
/* Return whether a symbol name implies a local label.  SVR4/860 compilers
 
1241
   generate labels of the form ".ep.function_name" to denote the end of a
 
1242
   function prolog. These should be local.
 
1243
   ??? Do any other SVR4 compilers have this convention? If so, this should
 
1244
   be added to the generic routine.  */
 
1245
static bfd_boolean
 
1246
elf32_i860_is_local_label_name (bfd *abfd, const char *name)
 
1247
{
 
1248
  if (name[0] == '.' && name[1] == 'e' && name[2] == 'p' && name[3] == '.')
 
1249
    return TRUE;
 
1250
 
 
1251
  return _bfd_elf_is_local_label_name (abfd, name);
 
1252
}
 
1253
 
 
1254
#define TARGET_BIG_SYM          bfd_elf32_i860_vec
 
1255
#define TARGET_BIG_NAME         "elf32-i860"
 
1256
#define TARGET_LITTLE_SYM       bfd_elf32_i860_little_vec
 
1257
#define TARGET_LITTLE_NAME      "elf32-i860-little"
 
1258
#define ELF_ARCH                bfd_arch_i860
 
1259
#define ELF_MACHINE_CODE        EM_860
 
1260
#define ELF_MAXPAGESIZE         4096
 
1261
 
 
1262
#define elf_backend_rela_normal                 1
 
1263
#define elf_info_to_howto_rel                   NULL
 
1264
#define elf_info_to_howto                       elf32_i860_info_to_howto_rela
 
1265
#define elf_backend_relocate_section            elf32_i860_relocate_section
 
1266
#define bfd_elf32_bfd_reloc_type_lookup         elf32_i860_reloc_type_lookup
 
1267
#define bfd_elf32_bfd_reloc_name_lookup elf32_i860_reloc_name_lookup
 
1268
#define bfd_elf32_bfd_is_local_label_name       elf32_i860_is_local_label_name
 
1269
 
 
1270
#include "elf32-target.h"