coff-mips.c revision 1.1 1 /* BFD back-end for MIPS Extended-Coff files.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2011, 2012
4 Free Software Foundation, Inc.
5 Original version by Per Bothner.
6 Full support added by Ian Lance Taylor, ian (at) cygnus.com.
7
8 This file is part of BFD, the Binary File Descriptor library.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
24
25 #include "sysdep.h"
26 #include "bfd.h"
27 #include "bfdlink.h"
28 #include "libbfd.h"
29 #include "coff/internal.h"
30 #include "coff/sym.h"
31 #include "coff/symconst.h"
32 #include "coff/ecoff.h"
33 #include "coff/mips.h"
34 #include "libcoff.h"
35 #include "libecoff.h"
36
37 /* Prototypes for static functions. */
39 static bfd_reloc_status_type
40 mips_generic_reloc
41 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
42 static bfd_reloc_status_type
43 mips_refhi_reloc
44 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
45 static bfd_reloc_status_type
46 mips_reflo_reloc
47 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
48 static bfd_reloc_status_type
49 mips_gprel_reloc
50 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
51
52
53 /* ECOFF has COFF sections, but the debugging information is stored in
55 a completely different format. ECOFF targets use some of the
56 swapping routines from coffswap.h, and some of the generic COFF
57 routines in coffgen.c, but, unlike the real COFF targets, do not
58 use coffcode.h itself.
59
60 Get the generic COFF swapping routines, except for the reloc,
61 symbol, and lineno ones. Give them ECOFF names. */
62 #define MIPSECOFF
63 #define NO_COFF_RELOCS
64 #define NO_COFF_SYMBOLS
65 #define NO_COFF_LINENOS
66 #define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in
67 #define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out
68 #define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in
69 #define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out
70 #define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in
71 #define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out
72
73 #include "coffswap.h"
74
75 /* Get the ECOFF swapping routines. */
76 #define ECOFF_32
77 #include "ecoffswap.h"
78
79 /* How to process the various relocs types. */
81
82 static reloc_howto_type mips_howto_table[] =
83 {
84 /* Reloc type 0 is ignored. The reloc reading code ensures that
85 this is a reference to the .abs section, which will cause
86 bfd_perform_relocation to do nothing. */
87 HOWTO (MIPS_R_IGNORE, /* type */
88 0, /* rightshift */
89 0, /* size (0 = byte, 1 = short, 2 = long) */
90 8, /* bitsize */
91 FALSE, /* pc_relative */
92 0, /* bitpos */
93 complain_overflow_dont, /* complain_on_overflow */
94 0, /* special_function */
95 "IGNORE", /* name */
96 FALSE, /* partial_inplace */
97 0, /* src_mask */
98 0, /* dst_mask */
99 FALSE), /* pcrel_offset */
100
101 /* A 16 bit reference to a symbol, normally from a data section. */
102 HOWTO (MIPS_R_REFHALF, /* type */
103 0, /* rightshift */
104 1, /* size (0 = byte, 1 = short, 2 = long) */
105 16, /* bitsize */
106 FALSE, /* pc_relative */
107 0, /* bitpos */
108 complain_overflow_bitfield, /* complain_on_overflow */
109 mips_generic_reloc, /* special_function */
110 "REFHALF", /* name */
111 TRUE, /* partial_inplace */
112 0xffff, /* src_mask */
113 0xffff, /* dst_mask */
114 FALSE), /* pcrel_offset */
115
116 /* A 32 bit reference to a symbol, normally from a data section. */
117 HOWTO (MIPS_R_REFWORD, /* type */
118 0, /* rightshift */
119 2, /* size (0 = byte, 1 = short, 2 = long) */
120 32, /* bitsize */
121 FALSE, /* pc_relative */
122 0, /* bitpos */
123 complain_overflow_bitfield, /* complain_on_overflow */
124 mips_generic_reloc, /* special_function */
125 "REFWORD", /* name */
126 TRUE, /* partial_inplace */
127 0xffffffff, /* src_mask */
128 0xffffffff, /* dst_mask */
129 FALSE), /* pcrel_offset */
130
131 /* A 26 bit absolute jump address. */
132 HOWTO (MIPS_R_JMPADDR, /* type */
133 2, /* rightshift */
134 2, /* size (0 = byte, 1 = short, 2 = long) */
135 26, /* bitsize */
136 FALSE, /* pc_relative */
137 0, /* bitpos */
138 complain_overflow_dont, /* complain_on_overflow */
139 /* This needs complex overflow
140 detection, because the upper four
141 bits must match the PC. */
142 mips_generic_reloc, /* special_function */
143 "JMPADDR", /* name */
144 TRUE, /* partial_inplace */
145 0x3ffffff, /* src_mask */
146 0x3ffffff, /* dst_mask */
147 FALSE), /* pcrel_offset */
148
149 /* The high 16 bits of a symbol value. Handled by the function
150 mips_refhi_reloc. */
151 HOWTO (MIPS_R_REFHI, /* type */
152 16, /* rightshift */
153 2, /* size (0 = byte, 1 = short, 2 = long) */
154 16, /* bitsize */
155 FALSE, /* pc_relative */
156 0, /* bitpos */
157 complain_overflow_bitfield, /* complain_on_overflow */
158 mips_refhi_reloc, /* special_function */
159 "REFHI", /* name */
160 TRUE, /* partial_inplace */
161 0xffff, /* src_mask */
162 0xffff, /* dst_mask */
163 FALSE), /* pcrel_offset */
164
165 /* The low 16 bits of a symbol value. */
166 HOWTO (MIPS_R_REFLO, /* type */
167 0, /* rightshift */
168 2, /* size (0 = byte, 1 = short, 2 = long) */
169 16, /* bitsize */
170 FALSE, /* pc_relative */
171 0, /* bitpos */
172 complain_overflow_dont, /* complain_on_overflow */
173 mips_reflo_reloc, /* special_function */
174 "REFLO", /* name */
175 TRUE, /* partial_inplace */
176 0xffff, /* src_mask */
177 0xffff, /* dst_mask */
178 FALSE), /* pcrel_offset */
179
180 /* A reference to an offset from the gp register. Handled by the
181 function mips_gprel_reloc. */
182 HOWTO (MIPS_R_GPREL, /* type */
183 0, /* rightshift */
184 2, /* size (0 = byte, 1 = short, 2 = long) */
185 16, /* bitsize */
186 FALSE, /* pc_relative */
187 0, /* bitpos */
188 complain_overflow_signed, /* complain_on_overflow */
189 mips_gprel_reloc, /* special_function */
190 "GPREL", /* name */
191 TRUE, /* partial_inplace */
192 0xffff, /* src_mask */
193 0xffff, /* dst_mask */
194 FALSE), /* pcrel_offset */
195
196 /* A reference to a literal using an offset from the gp register.
197 Handled by the function mips_gprel_reloc. */
198 HOWTO (MIPS_R_LITERAL, /* type */
199 0, /* rightshift */
200 2, /* size (0 = byte, 1 = short, 2 = long) */
201 16, /* bitsize */
202 FALSE, /* pc_relative */
203 0, /* bitpos */
204 complain_overflow_signed, /* complain_on_overflow */
205 mips_gprel_reloc, /* special_function */
206 "LITERAL", /* name */
207 TRUE, /* partial_inplace */
208 0xffff, /* src_mask */
209 0xffff, /* dst_mask */
210 FALSE), /* pcrel_offset */
211
212 EMPTY_HOWTO (8),
213 EMPTY_HOWTO (9),
214 EMPTY_HOWTO (10),
215 EMPTY_HOWTO (11),
216
217 /* FIXME: This relocation is used (internally only) to represent branches
218 when assembling. It should never appear in output files, and
219 be removed. (It used to be used for embedded-PIC support.) */
220 HOWTO (MIPS_R_PCREL16, /* type */
221 2, /* rightshift */
222 2, /* size (0 = byte, 1 = short, 2 = long) */
223 16, /* bitsize */
224 TRUE, /* pc_relative */
225 0, /* bitpos */
226 complain_overflow_signed, /* complain_on_overflow */
227 mips_generic_reloc, /* special_function */
228 "PCREL16", /* name */
229 TRUE, /* partial_inplace */
230 0xffff, /* src_mask */
231 0xffff, /* dst_mask */
232 TRUE), /* pcrel_offset */
233 };
234
235 #define MIPS_HOWTO_COUNT \
236 (sizeof mips_howto_table / sizeof mips_howto_table[0])
237
238 /* See whether the magic number matches. */
240
241 static bfd_boolean
242 mips_ecoff_bad_format_hook (bfd * abfd, void * filehdr)
243 {
244 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
245
246 switch (internal_f->f_magic)
247 {
248 case MIPS_MAGIC_1:
249 /* I don't know what endianness this implies. */
250 return TRUE;
251
252 case MIPS_MAGIC_BIG:
253 case MIPS_MAGIC_BIG2:
254 case MIPS_MAGIC_BIG3:
255 return bfd_big_endian (abfd);
256
257 case MIPS_MAGIC_LITTLE:
258 case MIPS_MAGIC_LITTLE2:
259 case MIPS_MAGIC_LITTLE3:
260 return bfd_little_endian (abfd);
261
262 default:
263 return FALSE;
264 }
265 }
266
267 /* Reloc handling. MIPS ECOFF relocs are packed into 8 bytes in
269 external form. They use a bit which indicates whether the symbol
270 is external. */
271
272 /* Swap a reloc in. */
273
274 static void
275 mips_ecoff_swap_reloc_in (bfd * abfd,
276 void * ext_ptr,
277 struct internal_reloc *intern)
278 {
279 const RELOC *ext = (RELOC *) ext_ptr;
280
281 intern->r_vaddr = H_GET_32 (abfd, ext->r_vaddr);
282 if (bfd_header_big_endian (abfd))
283 {
284 intern->r_symndx = (((int) ext->r_bits[0]
285 << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
286 | ((int) ext->r_bits[1]
287 << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
288 | ((int) ext->r_bits[2]
289 << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
290 intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
291 >> RELOC_BITS3_TYPE_SH_BIG);
292 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
293 }
294 else
295 {
296 intern->r_symndx = (((int) ext->r_bits[0]
297 << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
298 | ((int) ext->r_bits[1]
299 << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
300 | ((int) ext->r_bits[2]
301 << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
302 intern->r_type = (((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
303 >> RELOC_BITS3_TYPE_SH_LITTLE)
304 | ((ext->r_bits[3] & RELOC_BITS3_TYPEHI_LITTLE)
305 << RELOC_BITS3_TYPEHI_SH_LITTLE));
306 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
307 }
308 }
309
310 /* Swap a reloc out. */
311
312 static void
313 mips_ecoff_swap_reloc_out (bfd * abfd,
314 const struct internal_reloc * intern,
315 void * dst)
316 {
317 RELOC *ext = (RELOC *) dst;
318 long r_symndx;
319
320 BFD_ASSERT (intern->r_extern
321 || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
322
323 r_symndx = intern->r_symndx;
324
325 H_PUT_32 (abfd, intern->r_vaddr, ext->r_vaddr);
326 if (bfd_header_big_endian (abfd))
327 {
328 ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
329 ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
330 ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
331 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
332 & RELOC_BITS3_TYPE_BIG)
333 | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
334 }
335 else
336 {
337 ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
338 ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
339 ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
340 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
341 & RELOC_BITS3_TYPE_LITTLE)
342 | ((intern->r_type >> RELOC_BITS3_TYPEHI_SH_LITTLE
343 & RELOC_BITS3_TYPEHI_LITTLE))
344 | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
345 }
346 }
347
348 /* Finish canonicalizing a reloc. Part of this is generic to all
349 ECOFF targets, and that part is in ecoff.c. The rest is done in
350 this backend routine. It must fill in the howto field. */
351
352 static void
353 mips_adjust_reloc_in (bfd *abfd,
354 const struct internal_reloc *intern,
355 arelent *rptr)
356 {
357 if (intern->r_type > MIPS_R_PCREL16)
358 abort ();
359
360 if (! intern->r_extern
361 && (intern->r_type == MIPS_R_GPREL
362 || intern->r_type == MIPS_R_LITERAL))
363 rptr->addend += ecoff_data (abfd)->gp;
364
365 /* If the type is MIPS_R_IGNORE, make sure this is a reference to
366 the absolute section so that the reloc is ignored. */
367 if (intern->r_type == MIPS_R_IGNORE)
368 rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
369
370 rptr->howto = &mips_howto_table[intern->r_type];
371 }
372
373 /* Make any adjustments needed to a reloc before writing it out. None
374 are needed for MIPS. */
375
376 static void
377 mips_adjust_reloc_out (bfd *abfd ATTRIBUTE_UNUSED,
378 const arelent *rel ATTRIBUTE_UNUSED,
379 struct internal_reloc *intern ATTRIBUTE_UNUSED)
380 {
381 }
382
383 /* ECOFF relocs are either against external symbols, or against
384 sections. If we are producing relocatable output, and the reloc
385 is against an external symbol, and nothing has given us any
386 additional addend, the resulting reloc will also be against the
387 same symbol. In such a case, we don't want to change anything
388 about the way the reloc is handled, since it will all be done at
389 final link time. Rather than put special case code into
390 bfd_perform_relocation, all the reloc types use this howto
391 function. It just short circuits the reloc if producing
392 relocatable output against an external symbol. */
393
394 static bfd_reloc_status_type
395 mips_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
396 arelent *reloc_entry,
397 asymbol *symbol,
398 void * data ATTRIBUTE_UNUSED,
399 asection *input_section,
400 bfd *output_bfd,
401 char **error_message ATTRIBUTE_UNUSED)
402 {
403 if (output_bfd != (bfd *) NULL
404 && (symbol->flags & BSF_SECTION_SYM) == 0
405 && reloc_entry->addend == 0)
406 {
407 reloc_entry->address += input_section->output_offset;
408 return bfd_reloc_ok;
409 }
410
411 return bfd_reloc_continue;
412 }
413
414 /* Do a REFHI relocation. This has to be done in combination with a
415 REFLO reloc, because there is a carry from the REFLO to the REFHI.
416 Here we just save the information we need; we do the actual
417 relocation when we see the REFLO. MIPS ECOFF requires that the
418 REFLO immediately follow the REFHI. As a GNU extension, we permit
419 an arbitrary number of HI relocs to be associated with a single LO
420 reloc. This extension permits gcc to output the HI and LO relocs
421 itself. */
422
423 struct mips_hi
424 {
425 struct mips_hi *next;
426 bfd_byte *addr;
427 bfd_vma addend;
428 };
429
430 /* FIXME: This should not be a static variable. */
431
432 static struct mips_hi *mips_refhi_list;
433
434 static bfd_reloc_status_type
435 mips_refhi_reloc (bfd *abfd ATTRIBUTE_UNUSED,
436 arelent *reloc_entry,
437 asymbol *symbol,
438 void * data,
439 asection *input_section,
440 bfd *output_bfd,
441 char **error_message ATTRIBUTE_UNUSED)
442 {
443 bfd_reloc_status_type ret;
444 bfd_vma relocation;
445 struct mips_hi *n;
446
447 /* If we're relocating, and this an external symbol, we don't want
448 to change anything. */
449 if (output_bfd != (bfd *) NULL
450 && (symbol->flags & BSF_SECTION_SYM) == 0
451 && reloc_entry->addend == 0)
452 {
453 reloc_entry->address += input_section->output_offset;
454 return bfd_reloc_ok;
455 }
456
457 ret = bfd_reloc_ok;
458 if (bfd_is_und_section (symbol->section)
459 && output_bfd == (bfd *) NULL)
460 ret = bfd_reloc_undefined;
461
462 if (bfd_is_com_section (symbol->section))
463 relocation = 0;
464 else
465 relocation = symbol->value;
466
467 relocation += symbol->section->output_section->vma;
468 relocation += symbol->section->output_offset;
469 relocation += reloc_entry->addend;
470
471 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
472 return bfd_reloc_outofrange;
473
474 /* Save the information, and let REFLO do the actual relocation. */
475 n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n);
476 if (n == NULL)
477 return bfd_reloc_outofrange;
478 n->addr = (bfd_byte *) data + reloc_entry->address;
479 n->addend = relocation;
480 n->next = mips_refhi_list;
481 mips_refhi_list = n;
482
483 if (output_bfd != (bfd *) NULL)
484 reloc_entry->address += input_section->output_offset;
485
486 return ret;
487 }
488
489 /* Do a REFLO relocation. This is a straightforward 16 bit inplace
490 relocation; this function exists in order to do the REFHI
491 relocation described above. */
492
493 static bfd_reloc_status_type
494 mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED,
495 arelent *reloc_entry,
496 asymbol *symbol,
497 void * data,
498 asection *input_section,
499 bfd *output_bfd,
500 char **error_message ATTRIBUTE_UNUSED)
501 {
502 if (mips_refhi_list != NULL)
503 {
504 struct mips_hi *l;
505
506 l = mips_refhi_list;
507 while (l != NULL)
508 {
509 unsigned long insn;
510 unsigned long val;
511 unsigned long vallo;
512 struct mips_hi *next;
513
514 /* Do the REFHI relocation. Note that we actually don't
515 need to know anything about the REFLO itself, except
516 where to find the low 16 bits of the addend needed by the
517 REFHI. */
518 insn = bfd_get_32 (abfd, l->addr);
519 vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
520 & 0xffff);
521 val = ((insn & 0xffff) << 16) + vallo;
522 val += l->addend;
523
524 /* The low order 16 bits are always treated as a signed
525 value. Therefore, a negative value in the low order bits
526 requires an adjustment in the high order bits. We need
527 to make this adjustment in two ways: once for the bits we
528 took from the data, and once for the bits we are putting
529 back in to the data. */
530 if ((vallo & 0x8000) != 0)
531 val -= 0x10000;
532 if ((val & 0x8000) != 0)
533 val += 0x10000;
534
535 insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
536 bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
537
538 next = l->next;
539 free (l);
540 l = next;
541 }
542
543 mips_refhi_list = NULL;
544 }
545
546 /* Now do the REFLO reloc in the usual way. */
547 return mips_generic_reloc (abfd, reloc_entry, symbol, data,
548 input_section, output_bfd, error_message);
549 }
550
551 /* Do a GPREL relocation. This is a 16 bit value which must become
552 the offset from the gp register. */
553
554 static bfd_reloc_status_type
555 mips_gprel_reloc (bfd *abfd ATTRIBUTE_UNUSED,
556 arelent *reloc_entry,
557 asymbol *symbol,
558 void * data,
559 asection *input_section,
560 bfd *output_bfd,
561 char **error_message ATTRIBUTE_UNUSED)
562 {
563 bfd_boolean relocatable;
564 bfd_vma gp;
565 bfd_vma relocation;
566 unsigned long val;
567 unsigned long insn;
568
569 /* If we're relocating, and this is an external symbol with no
570 addend, we don't want to change anything. We will only have an
571 addend if this is a newly created reloc, not read from an ECOFF
572 file. */
573 if (output_bfd != (bfd *) NULL
574 && (symbol->flags & BSF_SECTION_SYM) == 0
575 && reloc_entry->addend == 0)
576 {
577 reloc_entry->address += input_section->output_offset;
578 return bfd_reloc_ok;
579 }
580
581 if (output_bfd != (bfd *) NULL)
582 relocatable = TRUE;
583 else
584 {
585 relocatable = FALSE;
586 output_bfd = symbol->section->output_section->owner;
587 }
588
589 if (bfd_is_und_section (symbol->section) && ! relocatable)
590 return bfd_reloc_undefined;
591
592 /* We have to figure out the gp value, so that we can adjust the
593 symbol value correctly. We look up the symbol _gp in the output
594 BFD. If we can't find it, we're stuck. We cache it in the ECOFF
595 target data. We don't need to adjust the symbol value for an
596 external symbol if we are producing relocatable output. */
597 gp = _bfd_get_gp_value (output_bfd);
598 if (gp == 0
599 && (! relocatable
600 || (symbol->flags & BSF_SECTION_SYM) != 0))
601 {
602 if (relocatable)
603 {
604 /* Make up a value. */
605 gp = symbol->section->output_section->vma + 0x4000;
606 _bfd_set_gp_value (output_bfd, gp);
607 }
608 else
609 {
610 unsigned int count;
611 asymbol **sym;
612 unsigned int i;
613
614 count = bfd_get_symcount (output_bfd);
615 sym = bfd_get_outsymbols (output_bfd);
616
617 if (sym == (asymbol **) NULL)
618 i = count;
619 else
620 {
621 for (i = 0; i < count; i++, sym++)
622 {
623 register const char *name;
624
625 name = bfd_asymbol_name (*sym);
626 if (*name == '_' && strcmp (name, "_gp") == 0)
627 {
628 gp = bfd_asymbol_value (*sym);
629 _bfd_set_gp_value (output_bfd, gp);
630 break;
631 }
632 }
633 }
634
635 if (i >= count)
636 {
637 /* Only get the error once. */
638 gp = 4;
639 _bfd_set_gp_value (output_bfd, gp);
640 *error_message =
641 (char *) _("GP relative relocation when _gp not defined");
642 return bfd_reloc_dangerous;
643 }
644 }
645 }
646
647 if (bfd_is_com_section (symbol->section))
648 relocation = 0;
649 else
650 relocation = symbol->value;
651
652 relocation += symbol->section->output_section->vma;
653 relocation += symbol->section->output_offset;
654
655 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
656 return bfd_reloc_outofrange;
657
658 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
659
660 /* Set val to the offset into the section or symbol. */
661 val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
662 if (val & 0x8000)
663 val -= 0x10000;
664
665 /* Adjust val for the final section location and GP value. If we
666 are producing relocatable output, we don't want to do this for
667 an external symbol. */
668 if (! relocatable
669 || (symbol->flags & BSF_SECTION_SYM) != 0)
670 val += relocation - gp;
671
672 insn = (insn &~ (unsigned) 0xffff) | (val & 0xffff);
673 bfd_put_32 (abfd, (bfd_vma) insn, (bfd_byte *) data + reloc_entry->address);
674
675 if (relocatable)
676 reloc_entry->address += input_section->output_offset;
677
678 /* Make sure it fit in 16 bits. */
679 if ((long) val >= 0x8000 || (long) val < -0x8000)
680 return bfd_reloc_overflow;
681
682 return bfd_reloc_ok;
683 }
684
685 /* Get the howto structure for a generic reloc type. */
686
687 static reloc_howto_type *
688 mips_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
689 bfd_reloc_code_real_type code)
690 {
691 int mips_type;
692
693 switch (code)
694 {
695 case BFD_RELOC_16:
696 mips_type = MIPS_R_REFHALF;
697 break;
698 case BFD_RELOC_32:
699 case BFD_RELOC_CTOR:
700 mips_type = MIPS_R_REFWORD;
701 break;
702 case BFD_RELOC_MIPS_JMP:
703 mips_type = MIPS_R_JMPADDR;
704 break;
705 case BFD_RELOC_HI16_S:
706 mips_type = MIPS_R_REFHI;
707 break;
708 case BFD_RELOC_LO16:
709 mips_type = MIPS_R_REFLO;
710 break;
711 case BFD_RELOC_GPREL16:
712 mips_type = MIPS_R_GPREL;
713 break;
714 case BFD_RELOC_MIPS_LITERAL:
715 mips_type = MIPS_R_LITERAL;
716 break;
717 case BFD_RELOC_16_PCREL_S2:
718 mips_type = MIPS_R_PCREL16;
719 break;
720 default:
721 return (reloc_howto_type *) NULL;
722 }
723
724 return &mips_howto_table[mips_type];
725 }
726
727 static reloc_howto_type *
728 mips_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
729 const char *r_name)
730 {
731 unsigned int i;
732
733 for (i = 0;
734 i < sizeof (mips_howto_table) / sizeof (mips_howto_table[0]);
735 i++)
736 if (mips_howto_table[i].name != NULL
737 && strcasecmp (mips_howto_table[i].name, r_name) == 0)
738 return &mips_howto_table[i];
739
740 return NULL;
741 }
742
743 /* A helper routine for mips_relocate_section which handles the REFHI
745 relocations. The REFHI relocation must be followed by a REFLO
746 relocation, and the addend used is formed from the addends of both
747 instructions. */
748
749 static void
750 mips_relocate_hi (struct internal_reloc *refhi,
751 struct internal_reloc *reflo,
752 bfd *input_bfd,
753 asection *input_section,
754 bfd_byte *contents,
755 bfd_vma relocation)
756 {
757 unsigned long insn;
758 unsigned long val;
759 unsigned long vallo;
760
761 if (refhi == NULL)
762 return;
763
764 insn = bfd_get_32 (input_bfd,
765 contents + refhi->r_vaddr - input_section->vma);
766 if (reflo == NULL)
767 vallo = 0;
768 else
769 vallo = (bfd_get_32 (input_bfd,
770 contents + reflo->r_vaddr - input_section->vma)
771 & 0xffff);
772
773 val = ((insn & 0xffff) << 16) + vallo;
774 val += relocation;
775
776 /* The low order 16 bits are always treated as a signed value.
777 Therefore, a negative value in the low order bits requires an
778 adjustment in the high order bits. We need to make this
779 adjustment in two ways: once for the bits we took from the data,
780 and once for the bits we are putting back in to the data. */
781 if ((vallo & 0x8000) != 0)
782 val -= 0x10000;
783
784 if ((val & 0x8000) != 0)
785 val += 0x10000;
786
787 insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
788 bfd_put_32 (input_bfd, (bfd_vma) insn,
789 contents + refhi->r_vaddr - input_section->vma);
790 }
791
792 /* Relocate a section while linking a MIPS ECOFF file. */
793
794 static bfd_boolean
795 mips_relocate_section (bfd *output_bfd,
796 struct bfd_link_info *info,
797 bfd *input_bfd,
798 asection *input_section,
799 bfd_byte *contents,
800 void * external_relocs)
801 {
802 asection **symndx_to_section;
803 struct ecoff_link_hash_entry **sym_hashes;
804 bfd_vma gp;
805 bfd_boolean gp_undefined;
806 struct external_reloc *ext_rel;
807 struct external_reloc *ext_rel_end;
808 unsigned int i;
809 bfd_boolean got_lo;
810 struct internal_reloc lo_int_rel;
811 bfd_size_type amt;
812
813 BFD_ASSERT (input_bfd->xvec->byteorder
814 == output_bfd->xvec->byteorder);
815
816 /* We keep a table mapping the symndx found in an internal reloc to
817 the appropriate section. This is faster than looking up the
818 section by name each time. */
819 symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
820 if (symndx_to_section == (asection **) NULL)
821 {
822 amt = NUM_RELOC_SECTIONS * sizeof (asection *);
823 symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
824 if (!symndx_to_section)
825 return FALSE;
826
827 symndx_to_section[RELOC_SECTION_NONE] = NULL;
828 symndx_to_section[RELOC_SECTION_TEXT] =
829 bfd_get_section_by_name (input_bfd, ".text");
830 symndx_to_section[RELOC_SECTION_RDATA] =
831 bfd_get_section_by_name (input_bfd, ".rdata");
832 symndx_to_section[RELOC_SECTION_DATA] =
833 bfd_get_section_by_name (input_bfd, ".data");
834 symndx_to_section[RELOC_SECTION_SDATA] =
835 bfd_get_section_by_name (input_bfd, ".sdata");
836 symndx_to_section[RELOC_SECTION_SBSS] =
837 bfd_get_section_by_name (input_bfd, ".sbss");
838 symndx_to_section[RELOC_SECTION_BSS] =
839 bfd_get_section_by_name (input_bfd, ".bss");
840 symndx_to_section[RELOC_SECTION_INIT] =
841 bfd_get_section_by_name (input_bfd, ".init");
842 symndx_to_section[RELOC_SECTION_LIT8] =
843 bfd_get_section_by_name (input_bfd, ".lit8");
844 symndx_to_section[RELOC_SECTION_LIT4] =
845 bfd_get_section_by_name (input_bfd, ".lit4");
846 symndx_to_section[RELOC_SECTION_XDATA] = NULL;
847 symndx_to_section[RELOC_SECTION_PDATA] = NULL;
848 symndx_to_section[RELOC_SECTION_FINI] =
849 bfd_get_section_by_name (input_bfd, ".fini");
850 symndx_to_section[RELOC_SECTION_LITA] = NULL;
851 symndx_to_section[RELOC_SECTION_ABS] = NULL;
852
853 ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
854 }
855
856 sym_hashes = ecoff_data (input_bfd)->sym_hashes;
857
858 gp = _bfd_get_gp_value (output_bfd);
859 if (gp == 0)
860 gp_undefined = TRUE;
861 else
862 gp_undefined = FALSE;
863
864 got_lo = FALSE;
865
866 ext_rel = (struct external_reloc *) external_relocs;
867 ext_rel_end = ext_rel + input_section->reloc_count;
868 for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
869 {
870 struct internal_reloc int_rel;
871 bfd_boolean use_lo = FALSE;
872 bfd_vma addend;
873 reloc_howto_type *howto;
874 struct ecoff_link_hash_entry *h = NULL;
875 asection *s = NULL;
876 bfd_vma relocation;
877 bfd_reloc_status_type r;
878
879 if (! got_lo)
880 mips_ecoff_swap_reloc_in (input_bfd, ext_rel, &int_rel);
881 else
882 {
883 int_rel = lo_int_rel;
884 got_lo = FALSE;
885 }
886
887 BFD_ASSERT (int_rel.r_type
888 < sizeof mips_howto_table / sizeof mips_howto_table[0]);
889
890 /* The REFHI reloc requires special handling. It must be followed
891 by a REFLO reloc, and the addend is formed from both relocs. */
892 if (int_rel.r_type == MIPS_R_REFHI)
893 {
894 struct external_reloc *lo_ext_rel;
895
896 /* As a GNU extension, permit an arbitrary number of REFHI
897 relocs before the REFLO reloc. This permits gcc to emit
898 the HI and LO relocs itself. */
899 for (lo_ext_rel = ext_rel + 1;
900 lo_ext_rel < ext_rel_end;
901 lo_ext_rel++)
902 {
903 mips_ecoff_swap_reloc_in (input_bfd, lo_ext_rel,
904 &lo_int_rel);
905 if (lo_int_rel.r_type != int_rel.r_type)
906 break;
907 }
908
909 if (lo_ext_rel < ext_rel_end
910 && lo_int_rel.r_type == MIPS_R_REFLO
911 && int_rel.r_extern == lo_int_rel.r_extern
912 && int_rel.r_symndx == lo_int_rel.r_symndx)
913 {
914 use_lo = TRUE;
915 if (lo_ext_rel == ext_rel + 1)
916 got_lo = TRUE;
917 }
918 }
919
920 howto = &mips_howto_table[int_rel.r_type];
921
922 if (int_rel.r_extern)
923 {
924 h = sym_hashes[int_rel.r_symndx];
925 /* If h is NULL, that means that there is a reloc against an
926 external symbol which we thought was just a debugging
927 symbol. This should not happen. */
928 if (h == (struct ecoff_link_hash_entry *) NULL)
929 abort ();
930 }
931 else
932 {
933 if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
934 s = NULL;
935 else
936 s = symndx_to_section[int_rel.r_symndx];
937
938 if (s == (asection *) NULL)
939 abort ();
940 }
941
942 /* The GPREL reloc uses an addend: the difference in the GP
943 values. */
944 if (int_rel.r_type != MIPS_R_GPREL
945 && int_rel.r_type != MIPS_R_LITERAL)
946 addend = 0;
947 else
948 {
949 if (gp_undefined)
950 {
951 if (! ((*info->callbacks->reloc_dangerous)
952 (info, _("GP relative relocation used when GP not defined"),
953 input_bfd, input_section,
954 int_rel.r_vaddr - input_section->vma)))
955 return FALSE;
956 /* Only give the error once per link. */
957 gp = 4;
958 _bfd_set_gp_value (output_bfd, gp);
959 gp_undefined = FALSE;
960 }
961 if (! int_rel.r_extern)
962 {
963 /* This is a relocation against a section. The current
964 addend in the instruction is the difference between
965 INPUT_SECTION->vma and the GP value of INPUT_BFD. We
966 must change this to be the difference between the
967 final definition (which will end up in RELOCATION)
968 and the GP value of OUTPUT_BFD (which is in GP). */
969 addend = ecoff_data (input_bfd)->gp - gp;
970 }
971 else if (! info->relocatable
972 || h->root.type == bfd_link_hash_defined
973 || h->root.type == bfd_link_hash_defweak)
974 {
975 /* This is a relocation against a defined symbol. The
976 current addend in the instruction is simply the
977 desired offset into the symbol (normally zero). We
978 are going to change this into a relocation against a
979 defined symbol, so we want the instruction to hold
980 the difference between the final definition of the
981 symbol (which will end up in RELOCATION) and the GP
982 value of OUTPUT_BFD (which is in GP). */
983 addend = - gp;
984 }
985 else
986 {
987 /* This is a relocation against an undefined or common
988 symbol. The current addend in the instruction is
989 simply the desired offset into the symbol (normally
990 zero). We are generating relocatable output, and we
991 aren't going to define this symbol, so we just leave
992 the instruction alone. */
993 addend = 0;
994 }
995 }
996
997 if (info->relocatable)
998 {
999 /* We are generating relocatable output, and must convert
1000 the existing reloc. */
1001 if (int_rel.r_extern)
1002 {
1003 if ((h->root.type == bfd_link_hash_defined
1004 || h->root.type == bfd_link_hash_defweak)
1005 && ! bfd_is_abs_section (h->root.u.def.section))
1006 {
1007 const char *name;
1008
1009 /* This symbol is defined in the output. Convert
1010 the reloc from being against the symbol to being
1011 against the section. */
1012
1013 /* Clear the r_extern bit. */
1014 int_rel.r_extern = 0;
1015
1016 /* Compute a new r_symndx value. */
1017 s = h->root.u.def.section;
1018 name = bfd_get_section_name (output_bfd,
1019 s->output_section);
1020
1021 int_rel.r_symndx = -1;
1022 switch (name[1])
1023 {
1024 case 'b':
1025 if (strcmp (name, ".bss") == 0)
1026 int_rel.r_symndx = RELOC_SECTION_BSS;
1027 break;
1028 case 'd':
1029 if (strcmp (name, ".data") == 0)
1030 int_rel.r_symndx = RELOC_SECTION_DATA;
1031 break;
1032 case 'f':
1033 if (strcmp (name, ".fini") == 0)
1034 int_rel.r_symndx = RELOC_SECTION_FINI;
1035 break;
1036 case 'i':
1037 if (strcmp (name, ".init") == 0)
1038 int_rel.r_symndx = RELOC_SECTION_INIT;
1039 break;
1040 case 'l':
1041 if (strcmp (name, ".lit8") == 0)
1042 int_rel.r_symndx = RELOC_SECTION_LIT8;
1043 else if (strcmp (name, ".lit4") == 0)
1044 int_rel.r_symndx = RELOC_SECTION_LIT4;
1045 break;
1046 case 'r':
1047 if (strcmp (name, ".rdata") == 0)
1048 int_rel.r_symndx = RELOC_SECTION_RDATA;
1049 break;
1050 case 's':
1051 if (strcmp (name, ".sdata") == 0)
1052 int_rel.r_symndx = RELOC_SECTION_SDATA;
1053 else if (strcmp (name, ".sbss") == 0)
1054 int_rel.r_symndx = RELOC_SECTION_SBSS;
1055 break;
1056 case 't':
1057 if (strcmp (name, ".text") == 0)
1058 int_rel.r_symndx = RELOC_SECTION_TEXT;
1059 break;
1060 }
1061
1062 if (int_rel.r_symndx == -1)
1063 abort ();
1064
1065 /* Add the section VMA and the symbol value. */
1066 relocation = (h->root.u.def.value
1067 + s->output_section->vma
1068 + s->output_offset);
1069
1070 /* For a PC relative relocation, the object file
1071 currently holds just the addend. We must adjust
1072 by the address to get the right value. */
1073 if (howto->pc_relative)
1074 relocation -= int_rel.r_vaddr - input_section->vma;
1075
1076 h = NULL;
1077 }
1078 else
1079 {
1080 /* Change the symndx value to the right one for the
1081 output BFD. */
1082 int_rel.r_symndx = h->indx;
1083 if (int_rel.r_symndx == -1)
1084 {
1085 /* This symbol is not being written out. */
1086 if (! ((*info->callbacks->unattached_reloc)
1087 (info, h->root.root.string, input_bfd,
1088 input_section,
1089 int_rel.r_vaddr - input_section->vma)))
1090 return FALSE;
1091 int_rel.r_symndx = 0;
1092 }
1093 relocation = 0;
1094 }
1095 }
1096 else
1097 {
1098 /* This is a relocation against a section. Adjust the
1099 value by the amount the section moved. */
1100 relocation = (s->output_section->vma
1101 + s->output_offset
1102 - s->vma);
1103 }
1104
1105 relocation += addend;
1106 addend = 0;
1107
1108 /* Adjust a PC relative relocation by removing the reference
1109 to the original address in the section and including the
1110 reference to the new address. */
1111 if (howto->pc_relative)
1112 relocation -= (input_section->output_section->vma
1113 + input_section->output_offset
1114 - input_section->vma);
1115
1116 /* Adjust the contents. */
1117 if (relocation == 0)
1118 r = bfd_reloc_ok;
1119 else
1120 {
1121 if (int_rel.r_type != MIPS_R_REFHI)
1122 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1123 (contents
1124 + int_rel.r_vaddr
1125 - input_section->vma));
1126 else
1127 {
1128 mips_relocate_hi (&int_rel,
1129 use_lo ? &lo_int_rel : NULL,
1130 input_bfd, input_section, contents,
1131 relocation);
1132 r = bfd_reloc_ok;
1133 }
1134 }
1135
1136 /* Adjust the reloc address. */
1137 int_rel.r_vaddr += (input_section->output_section->vma
1138 + input_section->output_offset
1139 - input_section->vma);
1140
1141 /* Save the changed reloc information. */
1142 mips_ecoff_swap_reloc_out (input_bfd, &int_rel, ext_rel);
1143 }
1144 else
1145 {
1146 /* We are producing a final executable. */
1147 if (int_rel.r_extern)
1148 {
1149 /* This is a reloc against a symbol. */
1150 if (h->root.type == bfd_link_hash_defined
1151 || h->root.type == bfd_link_hash_defweak)
1152 {
1153 asection *hsec;
1154
1155 hsec = h->root.u.def.section;
1156 relocation = (h->root.u.def.value
1157 + hsec->output_section->vma
1158 + hsec->output_offset);
1159 }
1160 else
1161 {
1162 if (! ((*info->callbacks->undefined_symbol)
1163 (info, h->root.root.string, input_bfd,
1164 input_section,
1165 int_rel.r_vaddr - input_section->vma, TRUE)))
1166 return FALSE;
1167 relocation = 0;
1168 }
1169 }
1170 else
1171 {
1172 /* This is a reloc against a section. */
1173 relocation = (s->output_section->vma
1174 + s->output_offset
1175 - s->vma);
1176
1177 /* A PC relative reloc is already correct in the object
1178 file. Make it look like a pcrel_offset relocation by
1179 adding in the start address. */
1180 if (howto->pc_relative)
1181 relocation += int_rel.r_vaddr;
1182 }
1183
1184 if (int_rel.r_type != MIPS_R_REFHI)
1185 r = _bfd_final_link_relocate (howto,
1186 input_bfd,
1187 input_section,
1188 contents,
1189 (int_rel.r_vaddr
1190 - input_section->vma),
1191 relocation,
1192 addend);
1193 else
1194 {
1195 mips_relocate_hi (&int_rel,
1196 use_lo ? &lo_int_rel : NULL,
1197 input_bfd, input_section, contents,
1198 relocation);
1199 r = bfd_reloc_ok;
1200 }
1201 }
1202
1203 /* MIPS_R_JMPADDR requires peculiar overflow detection. The
1204 instruction provides a 28 bit address (the two lower bits are
1205 implicit zeroes) which is combined with the upper four bits
1206 of the instruction address. */
1207 if (r == bfd_reloc_ok
1208 && int_rel.r_type == MIPS_R_JMPADDR
1209 && (((relocation
1210 + addend
1211 + (int_rel.r_extern ? 0 : s->vma))
1212 & 0xf0000000)
1213 != ((input_section->output_section->vma
1214 + input_section->output_offset
1215 + (int_rel.r_vaddr - input_section->vma))
1216 & 0xf0000000)))
1217 r = bfd_reloc_overflow;
1218
1219 if (r != bfd_reloc_ok)
1220 {
1221 switch (r)
1222 {
1223 default:
1224 case bfd_reloc_outofrange:
1225 abort ();
1226 case bfd_reloc_overflow:
1227 {
1228 const char *name;
1229
1230 if (int_rel.r_extern)
1231 name = NULL;
1232 else
1233 name = bfd_section_name (input_bfd, s);
1234 if (! ((*info->callbacks->reloc_overflow)
1235 (info, (h ? &h->root : NULL), name, howto->name,
1236 (bfd_vma) 0, input_bfd, input_section,
1237 int_rel.r_vaddr - input_section->vma)))
1238 return FALSE;
1239 }
1240 break;
1241 }
1242 }
1243 }
1244
1245 return TRUE;
1246 }
1247
1248 /* This is the ECOFF backend structure. The backend field of the
1250 target vector points to this. */
1251
1252 static const struct ecoff_backend_data mips_ecoff_backend_data =
1253 {
1254 /* COFF backend structure. */
1255 {
1256 (void (*) (bfd *,void *,int,int,int,int,void *)) bfd_void, /* aux_in */
1257 (void (*) (bfd *,void *,void *)) bfd_void, /* sym_in */
1258 (void (*) (bfd *,void *,void *)) bfd_void, /* lineno_in */
1259 (unsigned (*) (bfd *,void *,int,int,int,int,void *)) bfd_void,/*aux_out*/
1260 (unsigned (*) (bfd *,void *,void *)) bfd_void, /* sym_out */
1261 (unsigned (*) (bfd *,void *,void *)) bfd_void, /* lineno_out */
1262 (unsigned (*) (bfd *,void *,void *)) bfd_void, /* reloc_out */
1263 mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
1264 mips_ecoff_swap_scnhdr_out,
1265 FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE,
1266 ECOFF_NO_LONG_SECTION_NAMES, 4, FALSE, 2,
1267 mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
1268 mips_ecoff_swap_scnhdr_in, NULL,
1269 mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
1270 _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
1271 _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
1272 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1273 NULL, NULL, NULL
1274 },
1275 /* Supported architecture. */
1276 bfd_arch_mips,
1277 /* Initial portion of armap string. */
1278 "__________",
1279 /* The page boundary used to align sections in a demand-paged
1280 executable file. E.g., 0x1000. */
1281 0x1000,
1282 /* TRUE if the .rdata section is part of the text segment, as on the
1283 Alpha. FALSE if .rdata is part of the data segment, as on the
1284 MIPS. */
1285 FALSE,
1286 /* Bitsize of constructor entries. */
1287 32,
1288 /* Reloc to use for constructor entries. */
1289 &mips_howto_table[MIPS_R_REFWORD],
1290 {
1291 /* Symbol table magic number. */
1292 magicSym,
1293 /* Alignment of debugging information. E.g., 4. */
1294 4,
1295 /* Sizes of external symbolic information. */
1296 sizeof (struct hdr_ext),
1297 sizeof (struct dnr_ext),
1298 sizeof (struct pdr_ext),
1299 sizeof (struct sym_ext),
1300 sizeof (struct opt_ext),
1301 sizeof (struct fdr_ext),
1302 sizeof (struct rfd_ext),
1303 sizeof (struct ext_ext),
1304 /* Functions to swap in external symbolic data. */
1305 ecoff_swap_hdr_in,
1306 ecoff_swap_dnr_in,
1307 ecoff_swap_pdr_in,
1308 ecoff_swap_sym_in,
1309 ecoff_swap_opt_in,
1310 ecoff_swap_fdr_in,
1311 ecoff_swap_rfd_in,
1312 ecoff_swap_ext_in,
1313 _bfd_ecoff_swap_tir_in,
1314 _bfd_ecoff_swap_rndx_in,
1315 /* Functions to swap out external symbolic data. */
1316 ecoff_swap_hdr_out,
1317 ecoff_swap_dnr_out,
1318 ecoff_swap_pdr_out,
1319 ecoff_swap_sym_out,
1320 ecoff_swap_opt_out,
1321 ecoff_swap_fdr_out,
1322 ecoff_swap_rfd_out,
1323 ecoff_swap_ext_out,
1324 _bfd_ecoff_swap_tir_out,
1325 _bfd_ecoff_swap_rndx_out,
1326 /* Function to read in symbolic data. */
1327 _bfd_ecoff_slurp_symbolic_info
1328 },
1329 /* External reloc size. */
1330 RELSZ,
1331 /* Reloc swapping functions. */
1332 mips_ecoff_swap_reloc_in,
1333 mips_ecoff_swap_reloc_out,
1334 /* Backend reloc tweaking. */
1335 mips_adjust_reloc_in,
1336 mips_adjust_reloc_out,
1337 /* Relocate section contents while linking. */
1338 mips_relocate_section,
1339 /* Do final adjustments to filehdr and aouthdr. */
1340 NULL,
1341 /* Read an element from an archive at a given file position. */
1342 _bfd_get_elt_at_filepos
1343 };
1344
1345 /* Looking up a reloc type is MIPS specific. */
1346 #define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
1347 #define _bfd_ecoff_bfd_reloc_name_lookup mips_bfd_reloc_name_lookup
1348
1349 /* Getting relocated section contents is generic. */
1350 #define _bfd_ecoff_bfd_get_relocated_section_contents \
1351 bfd_generic_get_relocated_section_contents
1352
1353 /* Handling file windows is generic. */
1354 #define _bfd_ecoff_get_section_contents_in_window \
1355 _bfd_generic_get_section_contents_in_window
1356
1357 /* Relaxing sections is MIPS specific. */
1358 #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
1359
1360 /* GC of sections is not done. */
1361 #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
1362
1363 /* Input section flags is not implemented. */
1364 #define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
1365
1366 /* Merging of sections is not done. */
1367 #define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
1368
1369 #define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
1370 #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
1371 #define _bfd_ecoff_section_already_linked \
1372 _bfd_coff_section_already_linked
1373 #define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol
1374
1375 extern const bfd_target ecoff_big_vec;
1376
1377 const bfd_target ecoff_little_vec =
1378 {
1379 "ecoff-littlemips", /* name */
1380 bfd_target_ecoff_flavour,
1381 BFD_ENDIAN_LITTLE, /* data byte order is little */
1382 BFD_ENDIAN_LITTLE, /* header byte order is little */
1383
1384 (HAS_RELOC | EXEC_P | /* object flags */
1385 HAS_LINENO | HAS_DEBUG |
1386 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1387
1388 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1389 0, /* leading underscore */
1390 ' ', /* ar_pad_char */
1391 15, /* ar_max_namelen */
1392 0, /* match priority. */
1393 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1394 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1395 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1396 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1397 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1398 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
1399
1400 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1401 bfd_generic_archive_p, _bfd_dummy_target},
1402 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
1403 _bfd_generic_mkarchive, bfd_false},
1404 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1405 _bfd_write_archive_contents, bfd_false},
1406
1407 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1408 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1409 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1410 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1411 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1412 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1413 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1414 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1415 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1416
1417 & ecoff_big_vec,
1418
1419 & mips_ecoff_backend_data
1420 };
1421
1422 const bfd_target ecoff_big_vec =
1423 {
1424 "ecoff-bigmips", /* name */
1425 bfd_target_ecoff_flavour,
1426 BFD_ENDIAN_BIG, /* data byte order is big */
1427 BFD_ENDIAN_BIG, /* header byte order is big */
1428
1429 (HAS_RELOC | EXEC_P | /* object flags */
1430 HAS_LINENO | HAS_DEBUG |
1431 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1432
1433 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1434 0, /* leading underscore */
1435 ' ', /* ar_pad_char */
1436 15, /* ar_max_namelen */
1437 0, /* match priority. */
1438 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1439 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1440 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1441 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1442 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1443 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1444 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1445 bfd_generic_archive_p, _bfd_dummy_target},
1446 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
1447 _bfd_generic_mkarchive, bfd_false},
1448 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1449 _bfd_write_archive_contents, bfd_false},
1450
1451 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1452 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1453 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1454 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1455 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1456 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1457 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1458 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1459 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1460
1461 & ecoff_little_vec,
1462
1463 & mips_ecoff_backend_data
1464 };
1465
1466 const bfd_target ecoff_biglittle_vec =
1467 {
1468 "ecoff-biglittlemips", /* name */
1469 bfd_target_ecoff_flavour,
1470 BFD_ENDIAN_LITTLE, /* data byte order is little */
1471 BFD_ENDIAN_BIG, /* header byte order is big */
1472
1473 (HAS_RELOC | EXEC_P | /* object flags */
1474 HAS_LINENO | HAS_DEBUG |
1475 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1476
1477 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1478 0, /* leading underscore */
1479 ' ', /* ar_pad_char */
1480 15, /* ar_max_namelen */
1481 0, /* match priority. */
1482 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1483 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1484 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1485 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1486 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1487 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1488
1489 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1490 bfd_generic_archive_p, _bfd_dummy_target},
1491 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
1492 _bfd_generic_mkarchive, bfd_false},
1493 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1494 _bfd_write_archive_contents, bfd_false},
1495
1496 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1497 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1498 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1499 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1500 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1501 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1502 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1503 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1504 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1505
1506 NULL,
1507
1508 & mips_ecoff_backend_data
1509 };
1510