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