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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [bfd/] [coff-i860.c] - Blame information for rev 816

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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