~ubuntu-branches/ubuntu/hoary/binutils/hoary

« back to all changes in this revision

Viewing changes to bfd/coff-i860.c

  • Committer: Bazaar Package Importer
  • Author(s): James Troup
  • Date: 2004-05-19 10:35:44 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040519103544-17h3o6e8pwndydrg
Tags: 2.14.90.0.7-8
debian/rules: don't use gcc-2.95 on m68k.  Thanks to Adam Conrad for
pointing this out.

Show diffs side-by-side

added added

removed removed

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