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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [coff-i860.c] - Blame information for rev 146

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

Line No. Rev Author Line
1 14 khays
/* BFD back-end for Intel i860 COFF files.
2
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2002,
3
   2003, 2004, 2005, 2007, 2008, 2010, 2011  Free Software Foundation, Inc.
4
   Created mostly by substituting "860" for "386" in coff-i386.c
5
   Harry Dolan <dolan@ssd.intel.com>, October 1995
6
 
7
   This file is part of BFD, the Binary File Descriptor library.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program; if not, write to the Free Software
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22
   MA 02110-1301, USA.  */
23
 
24
#include "sysdep.h"
25
#include "bfd.h"
26
#include "libbfd.h"
27
 
28
#include "coff/i860.h"
29
 
30
#include "coff/internal.h"
31
 
32
#ifndef bfd_pe_print_pdata
33
#define bfd_pe_print_pdata      NULL
34
#endif
35
 
36
#include "libcoff.h"
37
 
38
 
39
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
40
/* The page size is a guess based on ELF.  */
41
 
42
#define COFF_PAGE_SIZE 0x1000
43
 
44
/* For some reason when using i860 COFF the value stored in the .text
45
   section for a reference to a common symbol is the value itself plus
46
   any desired offset.  Ian Taylor, Cygnus Support.  */
47
 
48
/* If we are producing relocatable output, we need to do some
49
   adjustments to the object file that are not done by the
50
   bfd_perform_relocation function.  This function is called by every
51
   reloc type to make any required adjustments.  */
52
 
53
static bfd_reloc_status_type
54
coff_i860_reloc (bfd *abfd,
55
                 arelent *reloc_entry,
56
                 asymbol *symbol,
57
                 void *data,
58
                 asection *input_section ATTRIBUTE_UNUSED,
59
                 bfd *output_bfd,
60
                 char **error_message ATTRIBUTE_UNUSED)
61
{
62
  symvalue diff;
63
 
64
  if (output_bfd == (bfd *) NULL)
65
    return bfd_reloc_continue;
66
 
67
  if (bfd_is_com_section (symbol->section))
68
    {
69
      /* We are relocating a common symbol.  The current value in the
70
         object file is ORIG + OFFSET, where ORIG is the value of the
71
         common symbol as seen by the object file when it was compiled
72
         (this may be zero if the symbol was undefined) and OFFSET is
73
         the offset into the common symbol (normally zero, but may be
74
         non-zero when referring to a field in a common structure).
75
         ORIG is the negative of reloc_entry->addend, which is set by
76
         the CALC_ADDEND macro below.  We want to replace the value in
77
         the object file with NEW + OFFSET, where NEW is the value of
78
         the common symbol which we are going to put in the final
79
         object file.  NEW is symbol->value.  */
80
      diff = symbol->value + reloc_entry->addend;
81
    }
82
  else
83
    {
84
      /* For some reason bfd_perform_relocation always effectively
85
         ignores the addend for a COFF target when producing
86
         relocatable output.  This seems to be always wrong for 860
87
         COFF, so we handle the addend here instead.  */
88
      diff = reloc_entry->addend;
89
    }
90
 
91
#define DOIT(x) \
92
  x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
93
 
94
    if (diff != 0)
95
      {
96
        reloc_howto_type *howto = reloc_entry->howto;
97
        unsigned char *addr = (unsigned char *) data + reloc_entry->address;
98
 
99
        switch (howto->size)
100
          {
101
          case 0:
102
            {
103
              char x = bfd_get_8 (abfd, addr);
104
              DOIT (x);
105
              bfd_put_8 (abfd, x, addr);
106
            }
107
            break;
108
 
109
          case 1:
110
            {
111
              short x = bfd_get_16 (abfd, addr);
112
              DOIT (x);
113
              bfd_put_16 (abfd, (bfd_vma) x, addr);
114
            }
115
            break;
116
 
117
          case 2:
118
            {
119
              long x = bfd_get_32 (abfd, addr);
120
              DOIT (x);
121
              bfd_put_32 (abfd, (bfd_vma) x, addr);
122
            }
123
            break;
124
 
125
          default:
126
            abort ();
127
          }
128
      }
129
 
130
  /* Now let bfd_perform_relocation finish everything up.  */
131
  return bfd_reloc_continue;
132
}
133
 
134
/* This is just a temporary measure until we teach bfd to generate
135
   these relocations.  */
136
 
137
static bfd_reloc_status_type
138
coff_i860_reloc_nyi (bfd *abfd ATTRIBUTE_UNUSED,
139
                     arelent *reloc_entry,
140
                     asymbol *symbol ATTRIBUTE_UNUSED,
141
                     void *data ATTRIBUTE_UNUSED,
142
                     asection *input_section ATTRIBUTE_UNUSED,
143
                     bfd *output_bfd ATTRIBUTE_UNUSED,
144
                     char **error_message ATTRIBUTE_UNUSED)
145
{
146
  reloc_howto_type *howto = reloc_entry->howto;
147
  (*_bfd_error_handler) (_("relocation `%s' not yet implemented"), howto->name);
148
  return bfd_reloc_notsupported;
149
}
150
 
151
#ifndef PCRELOFFSET
152
#define PCRELOFFSET FALSE
153
#endif
154
 
155
static reloc_howto_type howto_table[] =
156
{
157
  EMPTY_HOWTO (0),
158
  EMPTY_HOWTO (1),
159
  EMPTY_HOWTO (2),
160
  EMPTY_HOWTO (3),
161
  EMPTY_HOWTO (4),
162
  EMPTY_HOWTO (5),
163
  HOWTO (R_DIR32,               /* type */
164
         0,                      /* rightshift */
165
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
166
         32,                    /* bitsize */
167
         FALSE,                 /* pc_relative */
168
         0,                      /* bitpos */
169
         complain_overflow_bitfield, /* complain_on_overflow */
170
         coff_i860_reloc,       /* special_function */
171
         "dir32",               /* name */
172
         TRUE,                  /* partial_inplace */
173
         0xffffffff,            /* src_mask */
174
         0xffffffff,            /* dst_mask */
175
         TRUE),                /* pcrel_offset */
176
  /* {7}, */
177
  HOWTO (R_IMAGEBASE,            /* type */
178
         0,                      /* rightshift */
179
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
180
         32,                    /* bitsize */
181
         FALSE,                 /* pc_relative */
182
         0,                      /* bitpos */
183
         complain_overflow_bitfield, /* complain_on_overflow */
184
         coff_i860_reloc,       /* special_function */
185
         "rva32",                  /* name */
186
         TRUE,                  /* partial_inplace */
187
         0xffffffff,            /* src_mask */
188
         0xffffffff,            /* dst_mask */
189
         FALSE),                /* pcrel_offset */
190
  EMPTY_HOWTO (010),
191
  EMPTY_HOWTO (011),
192
  EMPTY_HOWTO (012),
193
  EMPTY_HOWTO (013),
194
  EMPTY_HOWTO (014),
195
  EMPTY_HOWTO (015),
196
  EMPTY_HOWTO (016),
197
  HOWTO (R_RELBYTE,             /* type */
198
         0,                      /* rightshift */
199
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
200
         8,                     /* bitsize */
201
         FALSE,                 /* pc_relative */
202
         0,                      /* bitpos */
203
         complain_overflow_bitfield, /* complain_on_overflow */
204
         coff_i860_reloc,       /* special_function */
205
         "8",                   /* name */
206
         TRUE,                  /* partial_inplace */
207
         0x000000ff,            /* src_mask */
208
         0x000000ff,            /* dst_mask */
209
         PCRELOFFSET),          /* pcrel_offset */
210
  HOWTO (R_RELWORD,             /* type */
211
         0,                      /* rightshift */
212
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
213
         16,                    /* bitsize */
214
         FALSE,                 /* pc_relative */
215
         0,                      /* bitpos */
216
         complain_overflow_bitfield, /* complain_on_overflow */
217
         coff_i860_reloc,       /* special_function */
218
         "16",                  /* name */
219
         TRUE,                  /* partial_inplace */
220
         0x0000ffff,            /* src_mask */
221
         0x0000ffff,            /* dst_mask */
222
         PCRELOFFSET),          /* pcrel_offset */
223
  HOWTO (R_RELLONG,             /* type */
224
         0,                      /* rightshift */
225
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
226
         32,                    /* bitsize */
227
         FALSE,                 /* pc_relative */
228
         0,                      /* bitpos */
229
         complain_overflow_bitfield, /* complain_on_overflow */
230
         coff_i860_reloc,       /* special_function */
231
         "32",                  /* name */
232
         TRUE,                  /* partial_inplace */
233
         0xffffffff,            /* src_mask */
234
         0xffffffff,            /* dst_mask */
235
         PCRELOFFSET),          /* pcrel_offset */
236
  HOWTO (R_PCRBYTE,             /* type */
237
         0,                      /* rightshift */
238
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
239
         8,                     /* bitsize */
240
         TRUE,                  /* pc_relative */
241
         0,                      /* bitpos */
242
         complain_overflow_signed, /* complain_on_overflow */
243
         coff_i860_reloc,       /* special_function */
244
         "DISP8",               /* name */
245
         TRUE,                  /* partial_inplace */
246
         0x000000ff,            /* src_mask */
247
         0x000000ff,            /* dst_mask */
248
         PCRELOFFSET),          /* pcrel_offset */
249
  HOWTO (R_PCRWORD,             /* type */
250
         0,                      /* rightshift */
251
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
252
         16,                    /* bitsize */
253
         TRUE,                  /* pc_relative */
254
         0,                      /* bitpos */
255
         complain_overflow_signed, /* complain_on_overflow */
256
         coff_i860_reloc,       /* special_function */
257
         "DISP16",              /* name */
258
         TRUE,                  /* partial_inplace */
259
         0x0000ffff,            /* src_mask */
260
         0x0000ffff,            /* dst_mask */
261
         PCRELOFFSET),          /* pcrel_offset */
262
  HOWTO (R_PCRLONG,             /* type */
263
         0,                      /* rightshift */
264
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
265
         32,                    /* bitsize */
266
         TRUE,                  /* pc_relative */
267
         0,                      /* bitpos */
268
         complain_overflow_signed, /* complain_on_overflow */
269
         coff_i860_reloc,       /* special_function */
270
         "DISP32",              /* name */
271
         TRUE,                  /* partial_inplace */
272
         0xffffffff,            /* src_mask */
273
         0xffffffff,            /* dst_mask */
274
         PCRELOFFSET),          /* pcrel_offset */
275
  EMPTY_HOWTO (0x15),
276
  EMPTY_HOWTO (0x16),
277
  EMPTY_HOWTO (0x17),
278
  EMPTY_HOWTO (0x18),
279
  EMPTY_HOWTO (0x19),
280
  EMPTY_HOWTO (0x1a),
281
  EMPTY_HOWTO (0x1b),
282
  HOWTO (COFF860_R_PAIR,        /* type */
283
         0,                      /* rightshift */
284
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
285
         16,                    /* bitsize */
286
         FALSE,                 /* pc_relative */
287
         0,                      /* bitpos */
288
         complain_overflow_dont, /* complain_on_overflow */
289
         coff_i860_reloc_nyi,   /* special_function */
290
         "PAIR",                /* name */
291
         FALSE,                 /* partial_inplace */
292
         0xffff,                /* src_mask */
293
         0xffff,                /* dst_mask */
294
         FALSE),                /* pcrel_offset */
295
  EMPTY_HOWTO (0x1d),
296
  HOWTO (COFF860_R_HIGH,        /* type */
297
         16,                    /* rightshift */
298
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
299
         16,                    /* bitsize */
300
         FALSE,                 /* pc_relative */
301
         0,                      /* bitpos */
302
         complain_overflow_dont, /* complain_on_overflow */
303
         coff_i860_reloc,       /* special_function */
304
         "HIGH",                /* name */
305
         FALSE,                 /* partial_inplace */
306
         0xffff,                /* src_mask */
307
         0xffff,                /* dst_mask */
308
         FALSE),                /* pcrel_offset */
309
  HOWTO (COFF860_R_LOW0,        /* type */
310
         0,                      /* rightshift */
311
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
312
         16,                    /* bitsize */
313
         FALSE,                 /* pc_relative */
314
         0,                      /* bitpos */
315
         complain_overflow_dont, /* complain_on_overflow */
316
         coff_i860_reloc,       /* special_function */
317
         "LOW0",                /* name */
318
         FALSE,                 /* partial_inplace */
319
         0xffff,                /* src_mask */
320
         0xffff,                /* dst_mask */
321
         FALSE),                /* pcrel_offset */
322
  HOWTO (COFF860_R_LOW1,        /* type */
323
         0,                      /* rightshift */
324
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
325
         16,                    /* bitsize */
326
         FALSE,                 /* pc_relative */
327
         0,                      /* bitpos */
328
         complain_overflow_dont, /* complain_on_overflow */
329
         coff_i860_reloc,       /* special_function */
330
         "LOW1",                /* name */
331
         FALSE,                 /* partial_inplace */
332
         0xfffe,                /* src_mask */
333
         0xfffe,                /* dst_mask */
334
         FALSE),                /* pcrel_offset */
335
  HOWTO (COFF860_R_LOW2,        /* type */
336
         0,                      /* rightshift */
337
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
338
         16,                    /* bitsize */
339
         FALSE,                 /* pc_relative */
340
         0,                      /* bitpos */
341
         complain_overflow_dont, /* complain_on_overflow */
342
         coff_i860_reloc,       /* special_function */
343
         "LOW2",                /* name */
344
         FALSE,                 /* partial_inplace */
345
         0xfffc,                /* src_mask */
346
         0xfffc,                /* dst_mask */
347
         FALSE),                /* pcrel_offset */
348
  HOWTO (COFF860_R_LOW3,        /* type */
349
         0,                      /* rightshift */
350
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
351
         16,                    /* bitsize */
352
         FALSE,                 /* pc_relative */
353
         0,                      /* bitpos */
354
         complain_overflow_dont, /* complain_on_overflow */
355
         coff_i860_reloc,       /* special_function */
356
         "LOW3",                /* name */
357
         FALSE,                 /* partial_inplace */
358
         0xfff8,                /* src_mask */
359
         0xfff8,                /* dst_mask */
360
         FALSE),                /* pcrel_offset */
361
  HOWTO (COFF860_R_LOW4,        /* type */
362
         0,                      /* rightshift */
363
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
364
         16,                    /* bitsize */
365
         FALSE,                 /* pc_relative */
366
         0,                      /* bitpos */
367
         complain_overflow_dont, /* complain_on_overflow */
368
         coff_i860_reloc,       /* special_function */
369
         "LOW4",                /* name */
370
         FALSE,                 /* partial_inplace */
371
         0xfff0,                /* src_mask */
372
         0xfff0,                /* dst_mask */
373
         FALSE),                /* pcrel_offset */
374
  HOWTO (COFF860_R_SPLIT0,      /* type */
375
         0,                      /* rightshift */
376
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
377
         16,                    /* bitsize */
378
         FALSE,                 /* pc_relative */
379
         0,                      /* bitpos */
380
         complain_overflow_dont, /* complain_on_overflow */
381
         coff_i860_reloc_nyi,   /* special_function */
382
         "SPLIT0",              /* name */
383
         FALSE,                 /* partial_inplace */
384
         0x1f07ff,              /* src_mask */
385
         0x1f07ff,              /* dst_mask */
386
         FALSE),                /* pcrel_offset */
387
  HOWTO (COFF860_R_SPLIT1,      /* type */
388
         0,                      /* rightshift */
389
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
390
         16,                    /* bitsize */
391
         FALSE,                 /* pc_relative */
392
         0,                      /* bitpos */
393
         complain_overflow_dont, /* complain_on_overflow */
394
         coff_i860_reloc_nyi,   /* special_function */
395
         "SPLIT1",              /* name */
396
         FALSE,                 /* partial_inplace */
397
         0x1f07fe,              /* src_mask */
398
         0x1f07fe,              /* dst_mask */
399
         FALSE),                /* pcrel_offset */
400
  HOWTO (COFF860_R_SPLIT2,      /* type */
401
         0,                      /* rightshift */
402
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
403
         16,                    /* bitsize */
404
         FALSE,                 /* pc_relative */
405
         0,                      /* bitpos */
406
         complain_overflow_dont, /* complain_on_overflow */
407
         coff_i860_reloc_nyi,   /* special_function */
408
         "SPLIT2",              /* name */
409
         FALSE,                 /* partial_inplace */
410
         0x1f07fc,              /* src_mask */
411
         0x1f07fc,              /* dst_mask */
412
         FALSE),                /* pcrel_offset */
413
  HOWTO (COFF860_R_HIGHADJ,     /* type */
414
         0,                      /* rightshift */
415
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
416
         16,                    /* bitsize */
417
         FALSE,                 /* pc_relative */
418
         0,                      /* bitpos */
419
         complain_overflow_dont, /* complain_on_overflow */
420
         coff_i860_reloc_nyi,   /* special_function */
421
         "HIGHADJ",             /* name */
422
         FALSE,                 /* partial_inplace */
423
         0xffff,                /* src_mask */
424
         0xffff,                /* dst_mask */
425
         FALSE),                /* pcrel_offset */
426
  HOWTO (COFF860_R_BRADDR,      /* type */
427
         2,                     /* rightshift */
428
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
429
         26,                    /* bitsize */
430
         TRUE,                  /* pc_relative */
431
         0,                      /* bitpos */
432
         complain_overflow_bitfield, /* complain_on_overflow */
433
         coff_i860_reloc_nyi,   /* special_function */
434
         "BRADDR",              /* name */
435
         FALSE,                 /* partial_inplace */
436
         0x3ffffff,             /* src_mask */
437
         0x3ffffff,             /* dst_mask */
438
         TRUE)                  /* pcrel_offset */
439
};
440
 
441
/* Turn a howto into a reloc number.  */
442
 
443
#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
444
#define BADMAG(x) I860BADMAG(x)
445
#define I860 1                  /* Customize coffcode.h */
446
 
447
#define RTYPE2HOWTO(cache_ptr, dst)                                     \
448
  ((cache_ptr)->howto =                                                 \
449
   ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0])       \
450
    ? howto_table + (dst)->r_type                                       \
451
    : NULL))
452
 
453
/* For 860 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
454
   library.  On some other COFF targets STYP_BSS is normally
455
   STYP_NOLOAD.  */
456
#define BSS_NOLOAD_IS_SHARED_LIBRARY
457
 
458
/* Compute the addend of a reloc.  If the reloc is to a common symbol,
459
   the object file contains the value of the common symbol.  By the
460
   time this is called, the linker may be using a different symbol
461
   from a different object file with a different value.  Therefore, we
462
   hack wildly to locate the original symbol from this file so that we
463
   can make the correct adjustment.  This macro sets coffsym to the
464
   symbol from the original file, and uses it to set the addend value
465
   correctly.  If this is not a common symbol, the usual addend
466
   calculation is done, except that an additional tweak is needed for
467
   PC relative relocs.
468
   FIXME: This macro refers to symbols and asect; these are from the
469
   calling function, not the macro arguments.  */
470
 
471
#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)
472
 
473
/* We use the special COFF backend linker.  */
474
#define coff_relocate_section _bfd_coff_generic_relocate_section
475
 
476
static reloc_howto_type *
477
coff_i860_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
478
                          asection *sec,
479
                          struct internal_reloc *rel,
480
                          struct coff_link_hash_entry *h,
481
                          struct internal_syment *sym,
482
                          bfd_vma *addendp)
483
{
484
 
485
  reloc_howto_type *howto;
486
 
487
  if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0]))
488
    {
489
      bfd_set_error (bfd_error_bad_value);
490
      return NULL;
491
    }
492
 
493
  howto = howto_table + rel->r_type;
494
 
495
  if (howto->pc_relative)
496
    *addendp += sec->vma;
497
 
498
  if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
499
    {
500
      /* This is a common symbol.  The section contents include the
501
         size (sym->n_value) as an addend.  The relocate_section
502
         function will be adding in the final value of the symbol.  We
503
         need to subtract out the current size in order to get the
504
         correct result.  */
505
 
506
      BFD_ASSERT (h != NULL);
507
 
508
      /* I think we *do* want to bypass this.  If we don't, I have seen some data
509
         parameters get the wrong relocation address.  If I link two versions
510
         with and without this section bypassed and then do a binary comparison,
511
         the addresses which are different can be looked up in the map.  The
512
         case in which this section has been bypassed has addresses which correspond
513
         to values I can find in the map.  */
514
      *addendp -= sym->n_value;
515
    }
516
 
517
  /* If the output symbol is common (in which case this must be a
518
     relocatable link), we need to add in the final size of the
519
     common symbol.  */
520
  if (h != NULL && h->root.type == bfd_link_hash_common)
521
    *addendp += h->root.u.c.size;
522
 
523
  return howto;
524
}
525
 
526
static reloc_howto_type *
527
coff_i860_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
528
                             bfd_reloc_code_real_type code)
529
{
530
  switch (code)
531
    {
532
    case BFD_RELOC_32:
533
      return howto_table + R_DIR32;
534
    case BFD_RELOC_860_PC26:
535
      return howto_table + COFF860_R_BRADDR;
536
    case BFD_RELOC_860_PC16:
537
      /* ??? How to handle PC16 for COFF?  SPLIT0 is close for now.  */
538
      return howto_table + COFF860_R_SPLIT0;
539
    case BFD_RELOC_860_LOW0:
540
      return howto_table + COFF860_R_LOW0;
541
    case BFD_RELOC_860_SPLIT0:
542
      return howto_table + COFF860_R_SPLIT0;
543
    case BFD_RELOC_860_LOW1:
544
      return howto_table + COFF860_R_LOW1;
545
    case BFD_RELOC_860_SPLIT1:
546
      return howto_table + COFF860_R_SPLIT1;
547
    case BFD_RELOC_860_LOW2:
548
      return howto_table + COFF860_R_LOW2;
549
    case BFD_RELOC_860_SPLIT2:
550
      return howto_table + COFF860_R_SPLIT2;
551
    case BFD_RELOC_860_LOW3:
552
      return howto_table + COFF860_R_LOW3;
553
    case BFD_RELOC_860_HIGHADJ:
554
      return howto_table + COFF860_R_HIGHADJ;
555
    case BFD_RELOC_860_HIGH:
556
      return howto_table + COFF860_R_HIGH;
557
    default:
558
      BFD_FAIL ();
559
      return 0;
560
    }
561
}
562
 
563
static reloc_howto_type *
564
coff_i860_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
565
                             const char *r_name)
566
{
567
  unsigned int i;
568
 
569
  for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
570
    if (howto_table[i].name != NULL
571
        && strcasecmp (howto_table[i].name, r_name) == 0)
572
      return &howto_table[i];
573
 
574
  return NULL;
575
}
576
 
577
/* This is called from coff_slurp_reloc_table for each relocation
578
   entry.  This special handling is due to the `PAIR' relocation
579
   which has a different meaning for the `r_symndx' field.  */
580
 
581
static void
582
i860_reloc_processing (arelent *cache_ptr, struct internal_reloc *dst,
583
                       asymbol **symbols, bfd *abfd, asection *asect)
584
{
585
  if (dst->r_type == COFF860_R_PAIR)
586
    {
587
      /* Handle the PAIR relocation specially.  */
588
      cache_ptr->howto = howto_table + dst->r_type;
589
      cache_ptr->address = dst->r_vaddr;
590
      cache_ptr->addend = dst->r_symndx;
591
      cache_ptr->sym_ptr_ptr= bfd_abs_section_ptr->symbol_ptr_ptr;
592
    }
593
  else
594
    {
595
      /* For every other relocation, do exactly what coff_slurp_reloc_table
596
         would do (which this code is taken directly from).  */
597
      asymbol *ptr = NULL;
598
      cache_ptr->address = dst->r_vaddr;
599
 
600
      if (dst->r_symndx != -1)
601
        {
602
          if (dst->r_symndx < 0 || dst->r_symndx >= obj_conv_table_size (abfd))
603
            {
604
              (*_bfd_error_handler)
605
                (_("%B: warning: illegal symbol index %ld in relocs"),
606
                 abfd, dst->r_symndx);
607
              cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
608
              ptr = NULL;
609
            }
610
          else
611
            {
612
              cache_ptr->sym_ptr_ptr = (symbols
613
                                        + obj_convert (abfd)[dst->r_symndx]);
614
              ptr = *(cache_ptr->sym_ptr_ptr);
615
            }
616
        }
617
      else
618
        {
619
          cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
620
          ptr = NULL;
621
        }
622
 
623
      /* The symbols definitions that we have read in have been
624
         relocated as if their sections started at 0. But the offsets
625
         refering to the symbols in the raw data have not been
626
         modified, so we have to have a negative addend to compensate.
627
 
628
         Note that symbols which used to be common must be left alone.  */
629
 
630
      /* Calculate any reloc addend by looking at the symbol.  */
631
      CALC_ADDEND (abfd, ptr, (*dst), cache_ptr);
632
      (void) ptr;
633
 
634
      cache_ptr->address -= asect->vma;
635
 
636
      /* Fill in the cache_ptr->howto field from dst->r_type.  */
637
      RTYPE2HOWTO (cache_ptr, dst);
638
    }
639
}
640
 
641
#define coff_rtype_to_howto             coff_i860_rtype_to_howto
642
#define coff_bfd_reloc_type_lookup      coff_i860_reloc_type_lookup
643
#define coff_bfd_reloc_name_lookup coff_i860_reloc_name_lookup
644
 
645
#define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \
646
  i860_reloc_processing (relent, reloc, symbols, abfd, section)
647
 
648
#include "coffcode.h"
649
 
650
static const bfd_target *
651
i3coff_object_p(bfd *a)
652
{
653
  return coff_object_p (a);
654
}
655
 
656
const bfd_target
657
#ifdef TARGET_SYM
658
  TARGET_SYM =
659
#else
660
  i860coff_vec =
661
#endif
662
{
663
#ifdef TARGET_NAME
664
  TARGET_NAME,
665
#else
666
  "coff-i860",                  /* name */
667
#endif
668
  bfd_target_coff_flavour,
669
  BFD_ENDIAN_LITTLE,            /* data byte order is little */
670
  BFD_ENDIAN_LITTLE,            /* header byte order is little */
671
 
672
  (HAS_RELOC | EXEC_P |         /* object flags */
673
   HAS_LINENO | HAS_DEBUG |
674
   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
675
 
676
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
677
  '_',                          /* leading underscore */
678
  '/',                          /* ar_pad_char */
679
  15,                           /* ar_max_namelen */
680
 
681
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
682
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
683
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
684
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
685
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
686
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
687
 
688
/* Note that we allow an object file to be treated as a core file as well.  */
689
    {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */
690
       bfd_generic_archive_p, i3coff_object_p},
691
    {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
692
       bfd_false},
693
    {bfd_false, coff_write_object_contents, /* bfd_write_contents */
694
       _bfd_write_archive_contents, bfd_false},
695
 
696
     BFD_JUMP_TABLE_GENERIC (coff),
697
     BFD_JUMP_TABLE_COPY (coff),
698
     BFD_JUMP_TABLE_CORE (_bfd_nocore),
699
     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
700
     BFD_JUMP_TABLE_SYMBOLS (coff),
701
     BFD_JUMP_TABLE_RELOCS (coff),
702
     BFD_JUMP_TABLE_WRITE (coff),
703
     BFD_JUMP_TABLE_LINK (coff),
704
     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
705
 
706
  NULL,
707
 
708
  COFF_SWAP_TABLE
709
};

powered by: WebSVN 2.1.0

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