2007-08-24 Joseph Myers <joseph@codesourcery.com>
[deliverable/binutils-gdb.git] / bfd / coff-i860.c
CommitLineData
c28b1c28 1/* BFD back-end for Intel i860 COFF files.
d003868e 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2002,
157090f7 3 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
252b5132
RH
4 Created mostly by substituting "860" for "386" in coff-i386.c
5 Harry Dolan <dolan@ssd.intel.com>, October 1995
6
cd123cb7 7 This file is part of BFD, the Binary File Descriptor library.
252b5132 8
cd123cb7
NC
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.
252b5132 13
cd123cb7
NC
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.
252b5132 18
cd123cb7
NC
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. */
252b5132 23
252b5132 24#include "sysdep.h"
3db64b00 25#include "bfd.h"
252b5132
RH
26#include "libbfd.h"
27
28#include "coff/i860.h"
29
30#include "coff/internal.h"
31
32#include "libcoff.h"
33
252b5132
RH
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
1049f94e 44/* If we are producing relocatable output, we need to do some
252b5132
RH
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
49static bfd_reloc_status_type
a62d170c
JE
50coff_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)
252b5132
RH
57{
58 symvalue diff;
59
60 if (output_bfd == (bfd *) NULL)
61 return bfd_reloc_continue;
62
252b5132
RH
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
1049f94e 82 relocatable output. This seems to be always wrong for 860
252b5132
RH
83 COFF, so we handle the addend here instead. */
84 diff = reloc_entry->addend;
85 }
86
252b5132
RH
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);
dc810e39 109 bfd_put_16 (abfd, (bfd_vma) x, addr);
252b5132
RH
110 }
111 break;
112
113 case 2:
114 {
115 long x = bfd_get_32 (abfd, addr);
116 DOIT (x);
dc810e39 117 bfd_put_32 (abfd, (bfd_vma) x, addr);
252b5132
RH
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
c28b1c28
JE
130/* This is just a temporary measure until we teach bfd to generate
131 these relocations. */
132
133static bfd_reloc_status_type
134coff_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);
1a101a42 144 return bfd_reloc_notsupported;
c28b1c28
JE
145}
146
252b5132 147#ifndef PCRELOFFSET
b34976b6 148#define PCRELOFFSET FALSE
252b5132
RH
149#endif
150
5fcfd273 151static reloc_howto_type howto_table[] =
252b5132 152{
5f771d47
ILT
153 EMPTY_HOWTO (0),
154 EMPTY_HOWTO (1),
155 EMPTY_HOWTO (2),
156 EMPTY_HOWTO (3),
157 EMPTY_HOWTO (4),
158 EMPTY_HOWTO (5),
5fcfd273
KH
159 HOWTO (R_DIR32, /* type */
160 0, /* rightshift */
161 2, /* size (0 = byte, 1 = short, 2 = long) */
162 32, /* bitsize */
b34976b6 163 FALSE, /* pc_relative */
5fcfd273 164 0, /* bitpos */
252b5132 165 complain_overflow_bitfield, /* complain_on_overflow */
5fcfd273
KH
166 coff_i860_reloc, /* special_function */
167 "dir32", /* name */
b34976b6 168 TRUE, /* partial_inplace */
5fcfd273
KH
169 0xffffffff, /* src_mask */
170 0xffffffff, /* dst_mask */
b34976b6 171 TRUE), /* pcrel_offset */
252b5132 172 /* {7}, */
5fcfd273
KH
173 HOWTO (R_IMAGEBASE, /* type */
174 0, /* rightshift */
175 2, /* size (0 = byte, 1 = short, 2 = long) */
176 32, /* bitsize */
b34976b6 177 FALSE, /* pc_relative */
5fcfd273 178 0, /* bitpos */
252b5132 179 complain_overflow_bitfield, /* complain_on_overflow */
5fcfd273
KH
180 coff_i860_reloc, /* special_function */
181 "rva32", /* name */
b34976b6 182 TRUE, /* partial_inplace */
5fcfd273
KH
183 0xffffffff, /* src_mask */
184 0xffffffff, /* dst_mask */
b34976b6 185 FALSE), /* pcrel_offset */
5f771d47
ILT
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),
5fcfd273
KH
193 HOWTO (R_RELBYTE, /* type */
194 0, /* rightshift */
195 0, /* size (0 = byte, 1 = short, 2 = long) */
196 8, /* bitsize */
b34976b6 197 FALSE, /* pc_relative */
5fcfd273 198 0, /* bitpos */
252b5132 199 complain_overflow_bitfield, /* complain_on_overflow */
5fcfd273
KH
200 coff_i860_reloc, /* special_function */
201 "8", /* name */
b34976b6 202 TRUE, /* partial_inplace */
5fcfd273
KH
203 0x000000ff, /* src_mask */
204 0x000000ff, /* dst_mask */
252b5132 205 PCRELOFFSET), /* pcrel_offset */
5fcfd273
KH
206 HOWTO (R_RELWORD, /* type */
207 0, /* rightshift */
208 1, /* size (0 = byte, 1 = short, 2 = long) */
209 16, /* bitsize */
b34976b6 210 FALSE, /* pc_relative */
5fcfd273 211 0, /* bitpos */
252b5132 212 complain_overflow_bitfield, /* complain_on_overflow */
5fcfd273
KH
213 coff_i860_reloc, /* special_function */
214 "16", /* name */
b34976b6 215 TRUE, /* partial_inplace */
5fcfd273
KH
216 0x0000ffff, /* src_mask */
217 0x0000ffff, /* dst_mask */
252b5132 218 PCRELOFFSET), /* pcrel_offset */
5fcfd273
KH
219 HOWTO (R_RELLONG, /* type */
220 0, /* rightshift */
221 2, /* size (0 = byte, 1 = short, 2 = long) */
222 32, /* bitsize */
b34976b6 223 FALSE, /* pc_relative */
5fcfd273 224 0, /* bitpos */
252b5132 225 complain_overflow_bitfield, /* complain_on_overflow */
5fcfd273
KH
226 coff_i860_reloc, /* special_function */
227 "32", /* name */
b34976b6 228 TRUE, /* partial_inplace */
5fcfd273
KH
229 0xffffffff, /* src_mask */
230 0xffffffff, /* dst_mask */
252b5132 231 PCRELOFFSET), /* pcrel_offset */
5fcfd273
KH
232 HOWTO (R_PCRBYTE, /* type */
233 0, /* rightshift */
234 0, /* size (0 = byte, 1 = short, 2 = long) */
235 8, /* bitsize */
b34976b6 236 TRUE, /* pc_relative */
5fcfd273 237 0, /* bitpos */
252b5132 238 complain_overflow_signed, /* complain_on_overflow */
5fcfd273
KH
239 coff_i860_reloc, /* special_function */
240 "DISP8", /* name */
b34976b6 241 TRUE, /* partial_inplace */
5fcfd273
KH
242 0x000000ff, /* src_mask */
243 0x000000ff, /* dst_mask */
252b5132 244 PCRELOFFSET), /* pcrel_offset */
5fcfd273
KH
245 HOWTO (R_PCRWORD, /* type */
246 0, /* rightshift */
247 1, /* size (0 = byte, 1 = short, 2 = long) */
248 16, /* bitsize */
b34976b6 249 TRUE, /* pc_relative */
5fcfd273 250 0, /* bitpos */
252b5132 251 complain_overflow_signed, /* complain_on_overflow */
5fcfd273
KH
252 coff_i860_reloc, /* special_function */
253 "DISP16", /* name */
b34976b6 254 TRUE, /* partial_inplace */
5fcfd273
KH
255 0x0000ffff, /* src_mask */
256 0x0000ffff, /* dst_mask */
252b5132 257 PCRELOFFSET), /* pcrel_offset */
5fcfd273
KH
258 HOWTO (R_PCRLONG, /* type */
259 0, /* rightshift */
260 2, /* size (0 = byte, 1 = short, 2 = long) */
261 32, /* bitsize */
b34976b6 262 TRUE, /* pc_relative */
5fcfd273 263 0, /* bitpos */
252b5132 264 complain_overflow_signed, /* complain_on_overflow */
5fcfd273
KH
265 coff_i860_reloc, /* special_function */
266 "DISP32", /* name */
b34976b6 267 TRUE, /* partial_inplace */
5fcfd273
KH
268 0xffffffff, /* src_mask */
269 0xffffffff, /* dst_mask */
c28b1c28
JE
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 */
252b5132
RH
435};
436
c28b1c28 437/* Turn a howto into a reloc number. */
252b5132
RH
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
c28b1c28
JE
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))
252b5132
RH
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
6d1227b8 467#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)
252b5132
RH
468
469/* We use the special COFF backend linker. */
470#define coff_relocate_section _bfd_coff_generic_relocate_section
471
472static reloc_howto_type *
a62d170c
JE
473coff_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)
252b5132
RH
479{
480
481 reloc_howto_type *howto;
482
c28b1c28
JE
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
252b5132
RH
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. */
252b5132 501
5fcfd273 502 BFD_ASSERT (h != NULL);
252b5132
RH
503
504 /* I think we *do* want to bypass this. If we don't, I have seen some data
5c4491d3 505 parameters get the wrong relocation address. If I link two versions
252b5132 506 with and without this section bypassed and then do a binary comparison,
5fcfd273 507 the addresses which are different can be looked up in the map. The
252b5132 508 case in which this section has been bypassed has addresses which correspond
917583ad 509 to values I can find in the map. */
252b5132
RH
510 *addendp -= sym->n_value;
511 }
512
513 /* If the output symbol is common (in which case this must be a
1049f94e 514 relocatable link), we need to add in the final size of the
252b5132 515 common symbol. */
5fcfd273 516 if (h != NULL && h->root.type == bfd_link_hash_common)
252b5132
RH
517 *addendp += h->root.u.c.size;
518
519 return howto;
520}
521
c28b1c28
JE
522static reloc_howto_type *
523coff_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
157090f7
AM
559static reloc_howto_type *
560coff_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
c28b1c28
JE
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
577static void
578i860_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)
d003868e
AM
601 (_("%B: warning: illegal symbol index %ld in relocs"),
602 abfd, dst->r_symndx);
c28b1c28
JE
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\f
636#define coff_rtype_to_howto coff_i860_rtype_to_howto
637#define coff_bfd_reloc_type_lookup coff_i860_reloc_type_lookup
157090f7 638#define coff_bfd_reloc_name_lookup coff_i860_reloc_name_lookup
c28b1c28
JE
639
640#define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \
641 i860_reloc_processing (relent, reloc, symbols, abfd, section)
252b5132
RH
642
643#include "coffcode.h"
644
645static const bfd_target *
a62d170c 646i3coff_object_p(bfd *a)
252b5132 647{
917583ad 648 return coff_object_p (a);
252b5132
RH
649}
650
651const 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
5fcfd273 683/* Note that we allow an object file to be treated as a core file as well. */
252b5132
RH
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
c3c89269 701 NULL,
5fcfd273 702
c3c89269 703 COFF_SWAP_TABLE
252b5132 704};
This page took 0.371852 seconds and 4 git commands to generate.