merge from gcc
[binutils.git] / bfd / coff-mips.c
blobd6d82184234708b7f46311bf7a63e31eae3fed17
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
4 Free Software Foundation, Inc.
5 Original version by Per Bothner.
6 Full support added by Ian Lance Taylor, ian@cygnus.com.
8 This file is part of BFD, the Binary File Descriptor library.
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 2 of the License, or
13 (at your option) any later version.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 #include "bfd.h"
25 #include "sysdep.h"
26 #include "bfdlink.h"
27 #include "libbfd.h"
28 #include "coff/internal.h"
29 #include "coff/sym.h"
30 #include "coff/symconst.h"
31 #include "coff/ecoff.h"
32 #include "coff/mips.h"
33 #include "libcoff.h"
34 #include "libecoff.h"
36 /* Prototypes for static functions. */
38 static bfd_boolean mips_ecoff_bad_format_hook
39 PARAMS ((bfd *abfd, PTR filehdr));
40 static void mips_ecoff_swap_reloc_in
41 PARAMS ((bfd *, PTR, struct internal_reloc *));
42 static void mips_ecoff_swap_reloc_out
43 PARAMS ((bfd *, const struct internal_reloc *, PTR));
44 static void mips_adjust_reloc_in
45 PARAMS ((bfd *, const struct internal_reloc *, arelent *));
46 static void mips_adjust_reloc_out
47 PARAMS ((bfd *, const arelent *, struct internal_reloc *));
48 static bfd_reloc_status_type mips_generic_reloc
49 PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
50 asection *section, bfd *output_bfd, char **error));
51 static bfd_reloc_status_type mips_refhi_reloc
52 PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
53 asection *section, bfd *output_bfd, char **error));
54 static bfd_reloc_status_type mips_reflo_reloc
55 PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
56 asection *section, bfd *output_bfd, char **error));
57 static bfd_reloc_status_type mips_gprel_reloc
58 PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
59 asection *section, bfd *output_bfd, char **error));
60 static bfd_reloc_status_type mips_relhi_reloc
61 PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
62 asection *section, bfd *output_bfd, char **error));
63 static bfd_reloc_status_type mips_rello_reloc
64 PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
65 asection *section, bfd *output_bfd, char **error));
66 static bfd_reloc_status_type mips_switch_reloc
67 PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
68 asection *section, bfd *output_bfd, char **error));
69 static void mips_relocate_hi
70 PARAMS ((struct internal_reloc *refhi, struct internal_reloc *reflo,
71 bfd *input_bfd, asection *input_section, bfd_byte *contents,
72 size_t adjust, bfd_vma relocation, bfd_boolean pcrel));
73 static bfd_boolean mips_relocate_section
74 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, PTR));
75 static bfd_boolean mips_read_relocs
76 PARAMS ((bfd *, asection *));
77 static bfd_boolean mips_relax_section
78 PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
79 static bfd_boolean mips_relax_pcrel16
80 PARAMS ((struct bfd_link_info *, bfd *, asection *,
81 struct ecoff_link_hash_entry *, bfd_byte *, bfd_vma));
82 static reloc_howto_type *mips_bfd_reloc_type_lookup
83 PARAMS ((bfd *, bfd_reloc_code_real_type));
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.
91 Get the generic COFF swapping routines, except for the reloc,
92 symbol, and lineno ones. Give them ECOFF names. */
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"
105 /* Get the ECOFF swapping routines. */
106 #define ECOFF_32
107 #include "ecoffswap.h"
109 /* How to process the various relocs types. */
111 static reloc_howto_type mips_howto_table[] =
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 */
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 */
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 */
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 */
167 complain_overflow_dont, /* complain_on_overflow */
168 /* This needs complex overflow
169 detection, because the upper four
170 bits must match the PC. */
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 */
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 */
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 */
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 */
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 */
241 EMPTY_HOWTO (8),
242 EMPTY_HOWTO (9),
243 EMPTY_HOWTO (10),
244 EMPTY_HOWTO (11),
246 /* This reloc is a Cygnus extension used when generating position
247 independent code for embedded systems. It represents a 16 bit PC
248 relative reloc rightshifted twice as used in the MIPS branch
249 instructions. */
250 HOWTO (MIPS_R_PCREL16, /* type */
251 2, /* rightshift */
252 2, /* size (0 = byte, 1 = short, 2 = long) */
253 16, /* bitsize */
254 TRUE, /* pc_relative */
255 0, /* bitpos */
256 complain_overflow_signed, /* complain_on_overflow */
257 mips_generic_reloc, /* special_function */
258 "PCREL16", /* name */
259 TRUE, /* partial_inplace */
260 0xffff, /* src_mask */
261 0xffff, /* dst_mask */
262 TRUE), /* pcrel_offset */
264 /* This reloc is a Cygnus extension used when generating position
265 independent code for embedded systems. It represents the high 16
266 bits of a PC relative reloc. The next reloc must be
267 MIPS_R_RELLO, and the addend is formed from the addends of the
268 two instructions, just as in MIPS_R_REFHI and MIPS_R_REFLO. The
269 final value is actually PC relative to the location of the
270 MIPS_R_RELLO reloc, not the MIPS_R_RELHI reloc. */
271 HOWTO (MIPS_R_RELHI, /* type */
272 16, /* rightshift */
273 2, /* size (0 = byte, 1 = short, 2 = long) */
274 16, /* bitsize */
275 TRUE, /* pc_relative */
276 0, /* bitpos */
277 complain_overflow_bitfield, /* complain_on_overflow */
278 mips_relhi_reloc, /* special_function */
279 "RELHI", /* name */
280 TRUE, /* partial_inplace */
281 0xffff, /* src_mask */
282 0xffff, /* dst_mask */
283 TRUE), /* pcrel_offset */
285 /* This reloc is a Cygnus extension used when generating position
286 independent code for embedded systems. It represents the low 16
287 bits of a PC relative reloc. */
288 HOWTO (MIPS_R_RELLO, /* type */
289 0, /* rightshift */
290 2, /* size (0 = byte, 1 = short, 2 = long) */
291 16, /* bitsize */
292 TRUE, /* pc_relative */
293 0, /* bitpos */
294 complain_overflow_dont, /* complain_on_overflow */
295 mips_rello_reloc, /* special_function */
296 "RELLO", /* name */
297 TRUE, /* partial_inplace */
298 0xffff, /* src_mask */
299 0xffff, /* dst_mask */
300 TRUE), /* pcrel_offset */
302 EMPTY_HOWTO (15),
303 EMPTY_HOWTO (16),
304 EMPTY_HOWTO (17),
305 EMPTY_HOWTO (18),
306 EMPTY_HOWTO (19),
307 EMPTY_HOWTO (20),
308 EMPTY_HOWTO (21),
310 /* This reloc is a Cygnus extension used when generating position
311 independent code for embedded systems. It represents an entry in
312 a switch table, which is the difference between two symbols in
313 the .text section. The symndx is actually the offset from the
314 reloc address to the subtrahend. See include/coff/mips.h for
315 more details. */
316 HOWTO (MIPS_R_SWITCH, /* type */
317 0, /* rightshift */
318 2, /* size (0 = byte, 1 = short, 2 = long) */
319 32, /* bitsize */
320 TRUE, /* pc_relative */
321 0, /* bitpos */
322 complain_overflow_dont, /* complain_on_overflow */
323 mips_switch_reloc, /* special_function */
324 "SWITCH", /* name */
325 TRUE, /* partial_inplace */
326 0xffffffff, /* src_mask */
327 0xffffffff, /* dst_mask */
328 TRUE) /* pcrel_offset */
331 #define MIPS_HOWTO_COUNT \
332 (sizeof mips_howto_table / sizeof mips_howto_table[0])
334 /* When the linker is doing relaxing, it may change an external PCREL16
335 reloc. This typically represents an instruction like
336 bal foo
337 We change it to
338 .set noreorder
339 bal $L1
340 lui $at,%hi(foo - $L1)
341 $L1:
342 addiu $at,%lo(foo - $L1)
343 addu $at,$at,$31
344 jalr $at
345 PCREL16_EXPANSION_ADJUSTMENT is the number of bytes this changes the
346 instruction by. */
348 #define PCREL16_EXPANSION_ADJUSTMENT (4 * 4)
350 /* See whether the magic number matches. */
352 static bfd_boolean
353 mips_ecoff_bad_format_hook (abfd, filehdr)
354 bfd *abfd;
355 PTR filehdr;
357 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
359 switch (internal_f->f_magic)
361 case MIPS_MAGIC_1:
362 /* I don't know what endianness this implies. */
363 return TRUE;
365 case MIPS_MAGIC_BIG:
366 case MIPS_MAGIC_BIG2:
367 case MIPS_MAGIC_BIG3:
368 return bfd_big_endian (abfd);
370 case MIPS_MAGIC_LITTLE:
371 case MIPS_MAGIC_LITTLE2:
372 case MIPS_MAGIC_LITTLE3:
373 return bfd_little_endian (abfd);
375 default:
376 return FALSE;
380 /* Reloc handling. MIPS ECOFF relocs are packed into 8 bytes in
381 external form. They use a bit which indicates whether the symbol
382 is external. */
384 /* Swap a reloc in. */
386 static void
387 mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
388 bfd *abfd;
389 PTR ext_ptr;
390 struct internal_reloc *intern;
392 const RELOC *ext = (RELOC *) ext_ptr;
394 intern->r_vaddr = H_GET_32 (abfd, ext->r_vaddr);
395 if (bfd_header_big_endian (abfd))
397 intern->r_symndx = (((int) ext->r_bits[0]
398 << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
399 | ((int) ext->r_bits[1]
400 << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
401 | ((int) ext->r_bits[2]
402 << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
403 intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
404 >> RELOC_BITS3_TYPE_SH_BIG);
405 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
407 else
409 intern->r_symndx = (((int) ext->r_bits[0]
410 << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
411 | ((int) ext->r_bits[1]
412 << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
413 | ((int) ext->r_bits[2]
414 << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
415 intern->r_type = (((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
416 >> RELOC_BITS3_TYPE_SH_LITTLE)
417 | ((ext->r_bits[3] & RELOC_BITS3_TYPEHI_LITTLE)
418 << RELOC_BITS3_TYPEHI_SH_LITTLE));
419 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
422 /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
423 MIPS_R_RELLO reloc, r_symndx is actually the offset from the
424 reloc address to the base of the difference (see
425 include/coff/mips.h for more details). We copy symndx into the
426 r_offset field so as not to confuse ecoff_slurp_reloc_table in
427 ecoff.c. In adjust_reloc_in we then copy r_offset into the reloc
428 addend. */
429 if (intern->r_type == MIPS_R_SWITCH
430 || (! intern->r_extern
431 && (intern->r_type == MIPS_R_RELLO
432 || intern->r_type == MIPS_R_RELHI)))
434 BFD_ASSERT (! intern->r_extern);
435 intern->r_offset = intern->r_symndx;
436 if (intern->r_offset & 0x800000)
437 intern->r_offset -= 0x1000000;
438 intern->r_symndx = RELOC_SECTION_TEXT;
442 /* Swap a reloc out. */
444 static void
445 mips_ecoff_swap_reloc_out (abfd, intern, dst)
446 bfd *abfd;
447 const struct internal_reloc *intern;
448 PTR dst;
450 RELOC *ext = (RELOC *) dst;
451 long r_symndx;
453 BFD_ASSERT (intern->r_extern
454 || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
456 /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELLO or
457 MIPS_R_RELHI reloc, we actually want to write the contents of
458 r_offset out as the symbol index. This undoes the change made by
459 mips_ecoff_swap_reloc_in. */
460 if (intern->r_type != MIPS_R_SWITCH
461 && (intern->r_extern
462 || (intern->r_type != MIPS_R_RELHI
463 && intern->r_type != MIPS_R_RELLO)))
464 r_symndx = intern->r_symndx;
465 else
467 BFD_ASSERT (intern->r_symndx == RELOC_SECTION_TEXT);
468 r_symndx = intern->r_offset & 0xffffff;
471 H_PUT_32 (abfd, intern->r_vaddr, ext->r_vaddr);
472 if (bfd_header_big_endian (abfd))
474 ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
475 ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
476 ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
477 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
478 & RELOC_BITS3_TYPE_BIG)
479 | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
481 else
483 ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
484 ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
485 ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
486 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
487 & RELOC_BITS3_TYPE_LITTLE)
488 | ((intern->r_type >> RELOC_BITS3_TYPEHI_SH_LITTLE
489 & RELOC_BITS3_TYPEHI_LITTLE))
490 | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
494 /* Finish canonicalizing a reloc. Part of this is generic to all
495 ECOFF targets, and that part is in ecoff.c. The rest is done in
496 this backend routine. It must fill in the howto field. */
498 static void
499 mips_adjust_reloc_in (abfd, intern, rptr)
500 bfd *abfd;
501 const struct internal_reloc *intern;
502 arelent *rptr;
504 if (intern->r_type > MIPS_R_SWITCH)
505 abort ();
507 if (! intern->r_extern
508 && (intern->r_type == MIPS_R_GPREL
509 || intern->r_type == MIPS_R_LITERAL))
510 rptr->addend += ecoff_data (abfd)->gp;
512 /* If the type is MIPS_R_IGNORE, make sure this is a reference to
513 the absolute section so that the reloc is ignored. */
514 if (intern->r_type == MIPS_R_IGNORE)
515 rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
517 /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
518 MIPS_R_RELLO reloc, we want the addend field of the BFD relocto
519 hold the value which was originally in the symndx field of the
520 internal MIPS ECOFF reloc. This value was copied into
521 intern->r_offset by mips_swap_reloc_in, and here we copy it into
522 the addend field. */
523 if (intern->r_type == MIPS_R_SWITCH
524 || (! intern->r_extern
525 && (intern->r_type == MIPS_R_RELHI
526 || intern->r_type == MIPS_R_RELLO)))
527 rptr->addend = intern->r_offset;
529 rptr->howto = &mips_howto_table[intern->r_type];
532 /* Make any adjustments needed to a reloc before writing it out. None
533 are needed for MIPS. */
535 static void
536 mips_adjust_reloc_out (abfd, rel, intern)
537 bfd *abfd ATTRIBUTE_UNUSED;
538 const arelent *rel;
539 struct internal_reloc *intern;
541 /* For a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
542 MIPS_R_RELLO reloc, we must copy rel->addend into
543 intern->r_offset. This will then be written out as the symbol
544 index by mips_ecoff_swap_reloc_out. This operation parallels the
545 action of mips_adjust_reloc_in. */
546 if (intern->r_type == MIPS_R_SWITCH
547 || (! intern->r_extern
548 && (intern->r_type == MIPS_R_RELHI
549 || intern->r_type == MIPS_R_RELLO)))
550 intern->r_offset = rel->addend;
553 /* ECOFF relocs are either against external symbols, or against
554 sections. If we are producing relocatable output, and the reloc
555 is against an external symbol, and nothing has given us any
556 additional addend, the resulting reloc will also be against the
557 same symbol. In such a case, we don't want to change anything
558 about the way the reloc is handled, since it will all be done at
559 final link time. Rather than put special case code into
560 bfd_perform_relocation, all the reloc types use this howto
561 function. It just short circuits the reloc if producing
562 relocatable output against an external symbol. */
564 static bfd_reloc_status_type
565 mips_generic_reloc (abfd,
566 reloc_entry,
567 symbol,
568 data,
569 input_section,
570 output_bfd,
571 error_message)
572 bfd *abfd ATTRIBUTE_UNUSED;
573 arelent *reloc_entry;
574 asymbol *symbol;
575 PTR data ATTRIBUTE_UNUSED;
576 asection *input_section;
577 bfd *output_bfd;
578 char **error_message ATTRIBUTE_UNUSED;
580 if (output_bfd != (bfd *) NULL
581 && (symbol->flags & BSF_SECTION_SYM) == 0
582 && reloc_entry->addend == 0)
584 reloc_entry->address += input_section->output_offset;
585 return bfd_reloc_ok;
588 return bfd_reloc_continue;
591 /* Do a REFHI relocation. This has to be done in combination with a
592 REFLO reloc, because there is a carry from the REFLO to the REFHI.
593 Here we just save the information we need; we do the actual
594 relocation when we see the REFLO. MIPS ECOFF requires that the
595 REFLO immediately follow the REFHI. As a GNU extension, we permit
596 an arbitrary number of HI relocs to be associated with a single LO
597 reloc. This extension permits gcc to output the HI and LO relocs
598 itself. */
600 struct mips_hi
602 struct mips_hi *next;
603 bfd_byte *addr;
604 bfd_vma addend;
607 /* FIXME: This should not be a static variable. */
609 static struct mips_hi *mips_refhi_list;
611 static bfd_reloc_status_type
612 mips_refhi_reloc (abfd,
613 reloc_entry,
614 symbol,
615 data,
616 input_section,
617 output_bfd,
618 error_message)
619 bfd *abfd ATTRIBUTE_UNUSED;
620 arelent *reloc_entry;
621 asymbol *symbol;
622 PTR data;
623 asection *input_section;
624 bfd *output_bfd;
625 char **error_message ATTRIBUTE_UNUSED;
627 bfd_reloc_status_type ret;
628 bfd_vma relocation;
629 struct mips_hi *n;
631 /* If we're relocating, and this an external symbol, we don't want
632 to change anything. */
633 if (output_bfd != (bfd *) NULL
634 && (symbol->flags & BSF_SECTION_SYM) == 0
635 && reloc_entry->addend == 0)
637 reloc_entry->address += input_section->output_offset;
638 return bfd_reloc_ok;
641 ret = bfd_reloc_ok;
642 if (bfd_is_und_section (symbol->section)
643 && output_bfd == (bfd *) NULL)
644 ret = bfd_reloc_undefined;
646 if (bfd_is_com_section (symbol->section))
647 relocation = 0;
648 else
649 relocation = symbol->value;
651 relocation += symbol->section->output_section->vma;
652 relocation += symbol->section->output_offset;
653 relocation += reloc_entry->addend;
655 if (reloc_entry->address > input_section->_cooked_size)
656 return bfd_reloc_outofrange;
658 /* Save the information, and let REFLO do the actual relocation. */
659 n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n);
660 if (n == NULL)
661 return bfd_reloc_outofrange;
662 n->addr = (bfd_byte *) data + reloc_entry->address;
663 n->addend = relocation;
664 n->next = mips_refhi_list;
665 mips_refhi_list = n;
667 if (output_bfd != (bfd *) NULL)
668 reloc_entry->address += input_section->output_offset;
670 return ret;
673 /* Do a REFLO relocation. This is a straightforward 16 bit inplace
674 relocation; this function exists in order to do the REFHI
675 relocation described above. */
677 static bfd_reloc_status_type
678 mips_reflo_reloc (abfd,
679 reloc_entry,
680 symbol,
681 data,
682 input_section,
683 output_bfd,
684 error_message)
685 bfd *abfd;
686 arelent *reloc_entry;
687 asymbol *symbol;
688 PTR data;
689 asection *input_section;
690 bfd *output_bfd;
691 char **error_message;
693 if (mips_refhi_list != NULL)
695 struct mips_hi *l;
697 l = mips_refhi_list;
698 while (l != NULL)
700 unsigned long insn;
701 unsigned long val;
702 unsigned long vallo;
703 struct mips_hi *next;
705 /* Do the REFHI relocation. Note that we actually don't
706 need to know anything about the REFLO itself, except
707 where to find the low 16 bits of the addend needed by the
708 REFHI. */
709 insn = bfd_get_32 (abfd, l->addr);
710 vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
711 & 0xffff);
712 val = ((insn & 0xffff) << 16) + vallo;
713 val += l->addend;
715 /* The low order 16 bits are always treated as a signed
716 value. Therefore, a negative value in the low order bits
717 requires an adjustment in the high order bits. We need
718 to make this adjustment in two ways: once for the bits we
719 took from the data, and once for the bits we are putting
720 back in to the data. */
721 if ((vallo & 0x8000) != 0)
722 val -= 0x10000;
723 if ((val & 0x8000) != 0)
724 val += 0x10000;
726 insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
727 bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
729 next = l->next;
730 free (l);
731 l = next;
734 mips_refhi_list = NULL;
737 /* Now do the REFLO reloc in the usual way. */
738 return mips_generic_reloc (abfd, reloc_entry, symbol, data,
739 input_section, output_bfd, error_message);
742 /* Do a GPREL relocation. This is a 16 bit value which must become
743 the offset from the gp register. */
745 static bfd_reloc_status_type
746 mips_gprel_reloc (abfd,
747 reloc_entry,
748 symbol,
749 data,
750 input_section,
751 output_bfd,
752 error_message)
753 bfd *abfd;
754 arelent *reloc_entry;
755 asymbol *symbol;
756 PTR data;
757 asection *input_section;
758 bfd *output_bfd;
759 char **error_message;
761 bfd_boolean relocatable;
762 bfd_vma gp;
763 bfd_vma relocation;
764 unsigned long val;
765 unsigned long insn;
767 /* If we're relocating, and this is an external symbol with no
768 addend, we don't want to change anything. We will only have an
769 addend if this is a newly created reloc, not read from an ECOFF
770 file. */
771 if (output_bfd != (bfd *) NULL
772 && (symbol->flags & BSF_SECTION_SYM) == 0
773 && reloc_entry->addend == 0)
775 reloc_entry->address += input_section->output_offset;
776 return bfd_reloc_ok;
779 if (output_bfd != (bfd *) NULL)
780 relocatable = TRUE;
781 else
783 relocatable = FALSE;
784 output_bfd = symbol->section->output_section->owner;
787 if (bfd_is_und_section (symbol->section) && ! relocatable)
788 return bfd_reloc_undefined;
790 /* We have to figure out the gp value, so that we can adjust the
791 symbol value correctly. We look up the symbol _gp in the output
792 BFD. If we can't find it, we're stuck. We cache it in the ECOFF
793 target data. We don't need to adjust the symbol value for an
794 external symbol if we are producing relocatable output. */
795 gp = _bfd_get_gp_value (output_bfd);
796 if (gp == 0
797 && (! relocatable
798 || (symbol->flags & BSF_SECTION_SYM) != 0))
800 if (relocatable)
802 /* Make up a value. */
803 gp = symbol->section->output_section->vma + 0x4000;
804 _bfd_set_gp_value (output_bfd, gp);
806 else
808 unsigned int count;
809 asymbol **sym;
810 unsigned int i;
812 count = bfd_get_symcount (output_bfd);
813 sym = bfd_get_outsymbols (output_bfd);
815 if (sym == (asymbol **) NULL)
816 i = count;
817 else
819 for (i = 0; i < count; i++, sym++)
821 register const char *name;
823 name = bfd_asymbol_name (*sym);
824 if (*name == '_' && strcmp (name, "_gp") == 0)
826 gp = bfd_asymbol_value (*sym);
827 _bfd_set_gp_value (output_bfd, gp);
828 break;
833 if (i >= count)
835 /* Only get the error once. */
836 gp = 4;
837 _bfd_set_gp_value (output_bfd, gp);
838 *error_message =
839 (char *) _("GP relative relocation when _gp not defined");
840 return bfd_reloc_dangerous;
845 if (bfd_is_com_section (symbol->section))
846 relocation = 0;
847 else
848 relocation = symbol->value;
850 relocation += symbol->section->output_section->vma;
851 relocation += symbol->section->output_offset;
853 if (reloc_entry->address > input_section->_cooked_size)
854 return bfd_reloc_outofrange;
856 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
858 /* Set val to the offset into the section or symbol. */
859 val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
860 if (val & 0x8000)
861 val -= 0x10000;
863 /* Adjust val for the final section location and GP value. If we
864 are producing relocatable output, we don't want to do this for
865 an external symbol. */
866 if (! relocatable
867 || (symbol->flags & BSF_SECTION_SYM) != 0)
868 val += relocation - gp;
870 insn = (insn &~ (unsigned) 0xffff) | (val & 0xffff);
871 bfd_put_32 (abfd, (bfd_vma) insn, (bfd_byte *) data + reloc_entry->address);
873 if (relocatable)
874 reloc_entry->address += input_section->output_offset;
876 /* Make sure it fit in 16 bits. */
877 if ((long) val >= 0x8000 || (long) val < -0x8000)
878 return bfd_reloc_overflow;
880 return bfd_reloc_ok;
883 /* Do a RELHI relocation. We do this in conjunction with a RELLO
884 reloc, just as REFHI and REFLO are done together. RELHI and RELLO
885 are Cygnus extensions used when generating position independent
886 code for embedded systems. */
888 /* FIXME: This should not be a static variable. */
890 static struct mips_hi *mips_relhi_list;
892 static bfd_reloc_status_type
893 mips_relhi_reloc (abfd,
894 reloc_entry,
895 symbol,
896 data,
897 input_section,
898 output_bfd,
899 error_message)
900 bfd *abfd ATTRIBUTE_UNUSED;
901 arelent *reloc_entry;
902 asymbol *symbol;
903 PTR data;
904 asection *input_section;
905 bfd *output_bfd;
906 char **error_message ATTRIBUTE_UNUSED;
908 bfd_reloc_status_type ret;
909 bfd_vma relocation;
910 struct mips_hi *n;
912 /* If this is a reloc against a section symbol, then it is correct
913 in the object file. The only time we want to change this case is
914 when we are relaxing, and that is handled entirely by
915 mips_relocate_section and never calls this function. */
916 if ((symbol->flags & BSF_SECTION_SYM) != 0)
918 if (output_bfd != (bfd *) NULL)
919 reloc_entry->address += input_section->output_offset;
920 return bfd_reloc_ok;
923 /* This is an external symbol. If we're relocating, we don't want
924 to change anything. */
925 if (output_bfd != (bfd *) NULL)
927 reloc_entry->address += input_section->output_offset;
928 return bfd_reloc_ok;
931 ret = bfd_reloc_ok;
932 if (bfd_is_und_section (symbol->section)
933 && output_bfd == (bfd *) NULL)
934 ret = bfd_reloc_undefined;
936 if (bfd_is_com_section (symbol->section))
937 relocation = 0;
938 else
939 relocation = symbol->value;
941 relocation += symbol->section->output_section->vma;
942 relocation += symbol->section->output_offset;
943 relocation += reloc_entry->addend;
945 if (reloc_entry->address > input_section->_cooked_size)
946 return bfd_reloc_outofrange;
948 /* Save the information, and let RELLO do the actual relocation. */
949 n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n);
950 if (n == NULL)
951 return bfd_reloc_outofrange;
952 n->addr = (bfd_byte *) data + reloc_entry->address;
953 n->addend = relocation;
954 n->next = mips_relhi_list;
955 mips_relhi_list = n;
957 if (output_bfd != (bfd *) NULL)
958 reloc_entry->address += input_section->output_offset;
960 return ret;
963 /* Do a RELLO relocation. This is a straightforward 16 bit PC
964 relative relocation; this function exists in order to do the RELHI
965 relocation described above. */
967 static bfd_reloc_status_type
968 mips_rello_reloc (abfd,
969 reloc_entry,
970 symbol,
971 data,
972 input_section,
973 output_bfd,
974 error_message)
975 bfd *abfd;
976 arelent *reloc_entry;
977 asymbol *symbol;
978 PTR data;
979 asection *input_section;
980 bfd *output_bfd;
981 char **error_message;
983 if (mips_relhi_list != NULL)
985 struct mips_hi *l;
987 l = mips_relhi_list;
988 while (l != NULL)
990 unsigned long insn;
991 unsigned long val;
992 unsigned long vallo;
993 struct mips_hi *next;
995 /* Do the RELHI relocation. Note that we actually don't
996 need to know anything about the RELLO itself, except
997 where to find the low 16 bits of the addend needed by the
998 RELHI. */
999 insn = bfd_get_32 (abfd, l->addr);
1000 vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
1001 & 0xffff);
1002 val = ((insn & 0xffff) << 16) + vallo;
1003 val += l->addend;
1005 /* If the symbol is defined, make val PC relative. If the
1006 symbol is not defined we don't want to do this, because
1007 we don't want the value in the object file to incorporate
1008 the address of the reloc. */
1009 if (! bfd_is_und_section (bfd_get_section (symbol))
1010 && ! bfd_is_com_section (bfd_get_section (symbol)))
1011 val -= (input_section->output_section->vma
1012 + input_section->output_offset
1013 + reloc_entry->address);
1015 /* The low order 16 bits are always treated as a signed
1016 value. Therefore, a negative value in the low order bits
1017 requires an adjustment in the high order bits. We need
1018 to make this adjustment in two ways: once for the bits we
1019 took from the data, and once for the bits we are putting
1020 back in to the data. */
1021 if ((vallo & 0x8000) != 0)
1022 val -= 0x10000;
1023 if ((val & 0x8000) != 0)
1024 val += 0x10000;
1026 insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
1027 bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
1029 next = l->next;
1030 free (l);
1031 l = next;
1034 mips_relhi_list = NULL;
1037 /* If this is a reloc against a section symbol, then it is correct
1038 in the object file. The only time we want to change this case is
1039 when we are relaxing, and that is handled entirely by
1040 mips_relocate_section and never calls this function. */
1041 if ((symbol->flags & BSF_SECTION_SYM) != 0)
1043 if (output_bfd != (bfd *) NULL)
1044 reloc_entry->address += input_section->output_offset;
1045 return bfd_reloc_ok;
1048 /* bfd_perform_relocation does not handle pcrel_offset relocations
1049 correctly when generating a relocatable file, so handle them
1050 directly here. */
1051 if (output_bfd != (bfd *) NULL)
1053 reloc_entry->address += input_section->output_offset;
1054 return bfd_reloc_ok;
1057 /* Now do the RELLO reloc in the usual way. */
1058 return mips_generic_reloc (abfd, reloc_entry, symbol, data,
1059 input_section, output_bfd, error_message);
1062 /* This is the special function for the MIPS_R_SWITCH reloc. This
1063 special reloc is normally correct in the object file, and only
1064 requires special handling when relaxing. We don't want
1065 bfd_perform_relocation to tamper with it at all. */
1067 static bfd_reloc_status_type
1068 mips_switch_reloc (abfd,
1069 reloc_entry,
1070 symbol,
1071 data,
1072 input_section,
1073 output_bfd,
1074 error_message)
1075 bfd *abfd ATTRIBUTE_UNUSED;
1076 arelent *reloc_entry ATTRIBUTE_UNUSED;
1077 asymbol *symbol ATTRIBUTE_UNUSED;
1078 PTR data ATTRIBUTE_UNUSED;
1079 asection *input_section ATTRIBUTE_UNUSED;
1080 bfd *output_bfd ATTRIBUTE_UNUSED;
1081 char **error_message ATTRIBUTE_UNUSED;
1083 return bfd_reloc_ok;
1086 /* Get the howto structure for a generic reloc type. */
1088 static reloc_howto_type *
1089 mips_bfd_reloc_type_lookup (abfd, code)
1090 bfd *abfd ATTRIBUTE_UNUSED;
1091 bfd_reloc_code_real_type code;
1093 int mips_type;
1095 switch (code)
1097 case BFD_RELOC_16:
1098 mips_type = MIPS_R_REFHALF;
1099 break;
1100 case BFD_RELOC_32:
1101 case BFD_RELOC_CTOR:
1102 mips_type = MIPS_R_REFWORD;
1103 break;
1104 case BFD_RELOC_MIPS_JMP:
1105 mips_type = MIPS_R_JMPADDR;
1106 break;
1107 case BFD_RELOC_HI16_S:
1108 mips_type = MIPS_R_REFHI;
1109 break;
1110 case BFD_RELOC_LO16:
1111 mips_type = MIPS_R_REFLO;
1112 break;
1113 case BFD_RELOC_GPREL16:
1114 mips_type = MIPS_R_GPREL;
1115 break;
1116 case BFD_RELOC_MIPS_LITERAL:
1117 mips_type = MIPS_R_LITERAL;
1118 break;
1119 case BFD_RELOC_16_PCREL_S2:
1120 mips_type = MIPS_R_PCREL16;
1121 break;
1122 case BFD_RELOC_PCREL_HI16_S:
1123 mips_type = MIPS_R_RELHI;
1124 break;
1125 case BFD_RELOC_PCREL_LO16:
1126 mips_type = MIPS_R_RELLO;
1127 break;
1128 case BFD_RELOC_GPREL32:
1129 mips_type = MIPS_R_SWITCH;
1130 break;
1131 default:
1132 return (reloc_howto_type *) NULL;
1135 return &mips_howto_table[mips_type];
1138 /* A helper routine for mips_relocate_section which handles the REFHI
1139 and RELHI relocations. The REFHI relocation must be followed by a
1140 REFLO relocation (and RELHI by a RELLO), and the addend used is
1141 formed from the addends of both instructions. */
1143 static void
1144 mips_relocate_hi (refhi, reflo, input_bfd, input_section, contents, adjust,
1145 relocation, pcrel)
1146 struct internal_reloc *refhi;
1147 struct internal_reloc *reflo;
1148 bfd *input_bfd;
1149 asection *input_section;
1150 bfd_byte *contents;
1151 size_t adjust;
1152 bfd_vma relocation;
1153 bfd_boolean pcrel;
1155 unsigned long insn;
1156 unsigned long val;
1157 unsigned long vallo;
1159 if (refhi == NULL)
1160 return;
1162 insn = bfd_get_32 (input_bfd,
1163 contents + adjust + refhi->r_vaddr - input_section->vma);
1164 if (reflo == NULL)
1165 vallo = 0;
1166 else
1167 vallo = (bfd_get_32 (input_bfd,
1168 contents + adjust + reflo->r_vaddr - input_section->vma)
1169 & 0xffff);
1171 val = ((insn & 0xffff) << 16) + vallo;
1172 val += relocation;
1174 /* The low order 16 bits are always treated as a signed value.
1175 Therefore, a negative value in the low order bits requires an
1176 adjustment in the high order bits. We need to make this
1177 adjustment in two ways: once for the bits we took from the data,
1178 and once for the bits we are putting back in to the data. */
1179 if ((vallo & 0x8000) != 0)
1180 val -= 0x10000;
1182 if (pcrel)
1183 val -= (input_section->output_section->vma
1184 + input_section->output_offset
1185 + (reflo->r_vaddr - input_section->vma + adjust));
1187 if ((val & 0x8000) != 0)
1188 val += 0x10000;
1190 insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
1191 bfd_put_32 (input_bfd, (bfd_vma) insn,
1192 contents + adjust + refhi->r_vaddr - input_section->vma);
1195 /* Relocate a section while linking a MIPS ECOFF file. */
1197 static bfd_boolean
1198 mips_relocate_section (output_bfd, info, input_bfd, input_section,
1199 contents, external_relocs)
1200 bfd *output_bfd;
1201 struct bfd_link_info *info;
1202 bfd *input_bfd;
1203 asection *input_section;
1204 bfd_byte *contents;
1205 PTR external_relocs;
1207 asection **symndx_to_section;
1208 struct ecoff_link_hash_entry **sym_hashes;
1209 bfd_vma gp;
1210 bfd_boolean gp_undefined;
1211 size_t adjust;
1212 long *offsets;
1213 struct external_reloc *ext_rel;
1214 struct external_reloc *ext_rel_end;
1215 unsigned int i;
1216 bfd_boolean got_lo;
1217 struct internal_reloc lo_int_rel;
1218 bfd_size_type amt;
1220 BFD_ASSERT (input_bfd->xvec->byteorder
1221 == output_bfd->xvec->byteorder);
1223 /* We keep a table mapping the symndx found in an internal reloc to
1224 the appropriate section. This is faster than looking up the
1225 section by name each time. */
1226 symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
1227 if (symndx_to_section == (asection **) NULL)
1229 amt = NUM_RELOC_SECTIONS * sizeof (asection *);
1230 symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
1231 if (!symndx_to_section)
1232 return FALSE;
1234 symndx_to_section[RELOC_SECTION_NONE] = NULL;
1235 symndx_to_section[RELOC_SECTION_TEXT] =
1236 bfd_get_section_by_name (input_bfd, ".text");
1237 symndx_to_section[RELOC_SECTION_RDATA] =
1238 bfd_get_section_by_name (input_bfd, ".rdata");
1239 symndx_to_section[RELOC_SECTION_DATA] =
1240 bfd_get_section_by_name (input_bfd, ".data");
1241 symndx_to_section[RELOC_SECTION_SDATA] =
1242 bfd_get_section_by_name (input_bfd, ".sdata");
1243 symndx_to_section[RELOC_SECTION_SBSS] =
1244 bfd_get_section_by_name (input_bfd, ".sbss");
1245 symndx_to_section[RELOC_SECTION_BSS] =
1246 bfd_get_section_by_name (input_bfd, ".bss");
1247 symndx_to_section[RELOC_SECTION_INIT] =
1248 bfd_get_section_by_name (input_bfd, ".init");
1249 symndx_to_section[RELOC_SECTION_LIT8] =
1250 bfd_get_section_by_name (input_bfd, ".lit8");
1251 symndx_to_section[RELOC_SECTION_LIT4] =
1252 bfd_get_section_by_name (input_bfd, ".lit4");
1253 symndx_to_section[RELOC_SECTION_XDATA] = NULL;
1254 symndx_to_section[RELOC_SECTION_PDATA] = NULL;
1255 symndx_to_section[RELOC_SECTION_FINI] =
1256 bfd_get_section_by_name (input_bfd, ".fini");
1257 symndx_to_section[RELOC_SECTION_LITA] = NULL;
1258 symndx_to_section[RELOC_SECTION_ABS] = NULL;
1260 ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
1263 sym_hashes = ecoff_data (input_bfd)->sym_hashes;
1265 gp = _bfd_get_gp_value (output_bfd);
1266 if (gp == 0)
1267 gp_undefined = TRUE;
1268 else
1269 gp_undefined = FALSE;
1271 got_lo = FALSE;
1273 adjust = 0;
1275 if (ecoff_section_data (input_bfd, input_section) == NULL)
1276 offsets = NULL;
1277 else
1278 offsets = ecoff_section_data (input_bfd, input_section)->offsets;
1280 ext_rel = (struct external_reloc *) external_relocs;
1281 ext_rel_end = ext_rel + input_section->reloc_count;
1282 for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
1284 struct internal_reloc int_rel;
1285 bfd_boolean use_lo = FALSE;
1286 bfd_vma addend;
1287 reloc_howto_type *howto;
1288 struct ecoff_link_hash_entry *h = NULL;
1289 asection *s = NULL;
1290 bfd_vma relocation;
1291 bfd_reloc_status_type r;
1293 if (! got_lo)
1294 mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
1295 else
1297 int_rel = lo_int_rel;
1298 got_lo = FALSE;
1301 BFD_ASSERT (int_rel.r_type
1302 < sizeof mips_howto_table / sizeof mips_howto_table[0]);
1304 /* The REFHI and RELHI relocs requires special handling. they
1305 must be followed by a REFLO or RELLO reloc, respectively, and
1306 the addend is formed from both relocs. */
1307 if (int_rel.r_type == MIPS_R_REFHI
1308 || int_rel.r_type == MIPS_R_RELHI)
1310 struct external_reloc *lo_ext_rel;
1312 /* As a GNU extension, permit an arbitrary number of REFHI
1313 or RELHI relocs before the REFLO or RELLO reloc. This
1314 permits gcc to emit the HI and LO relocs itself. */
1315 for (lo_ext_rel = ext_rel + 1;
1316 lo_ext_rel < ext_rel_end;
1317 lo_ext_rel++)
1319 mips_ecoff_swap_reloc_in (input_bfd, (PTR) lo_ext_rel,
1320 &lo_int_rel);
1321 if (lo_int_rel.r_type != int_rel.r_type)
1322 break;
1325 if (lo_ext_rel < ext_rel_end
1326 && (lo_int_rel.r_type
1327 == (int_rel.r_type == MIPS_R_REFHI
1328 ? MIPS_R_REFLO
1329 : MIPS_R_RELLO))
1330 && int_rel.r_extern == lo_int_rel.r_extern
1331 && int_rel.r_symndx == lo_int_rel.r_symndx)
1333 use_lo = TRUE;
1334 if (lo_ext_rel == ext_rel + 1)
1335 got_lo = TRUE;
1339 howto = &mips_howto_table[int_rel.r_type];
1341 /* The SWITCH reloc must be handled specially. This reloc is
1342 marks the location of a difference between two portions of an
1343 object file. The symbol index does not reference a symbol,
1344 but is actually the offset from the reloc to the subtrahend
1345 of the difference. This reloc is correct in the object file,
1346 and needs no further adjustment, unless we are relaxing. If
1347 we are relaxing, we may have to add in an offset. Since no
1348 symbols are involved in this reloc, we handle it completely
1349 here. */
1350 if (int_rel.r_type == MIPS_R_SWITCH)
1352 if (offsets != NULL
1353 && offsets[i] != 0)
1355 r = _bfd_relocate_contents (howto, input_bfd,
1356 (bfd_vma) offsets[i],
1357 (contents
1358 + adjust
1359 + int_rel.r_vaddr
1360 - input_section->vma));
1361 BFD_ASSERT (r == bfd_reloc_ok);
1364 continue;
1367 if (int_rel.r_extern)
1369 h = sym_hashes[int_rel.r_symndx];
1370 /* If h is NULL, that means that there is a reloc against an
1371 external symbol which we thought was just a debugging
1372 symbol. This should not happen. */
1373 if (h == (struct ecoff_link_hash_entry *) NULL)
1374 abort ();
1376 else
1378 if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
1379 s = NULL;
1380 else
1381 s = symndx_to_section[int_rel.r_symndx];
1383 if (s == (asection *) NULL)
1384 abort ();
1387 /* The GPREL reloc uses an addend: the difference in the GP
1388 values. */
1389 if (int_rel.r_type != MIPS_R_GPREL
1390 && int_rel.r_type != MIPS_R_LITERAL)
1391 addend = 0;
1392 else
1394 if (gp_undefined)
1396 if (! ((*info->callbacks->reloc_dangerous)
1397 (info, _("GP relative relocation used when GP not defined"),
1398 input_bfd, input_section,
1399 int_rel.r_vaddr - input_section->vma)))
1400 return FALSE;
1401 /* Only give the error once per link. */
1402 gp = 4;
1403 _bfd_set_gp_value (output_bfd, gp);
1404 gp_undefined = FALSE;
1406 if (! int_rel.r_extern)
1408 /* This is a relocation against a section. The current
1409 addend in the instruction is the difference between
1410 INPUT_SECTION->vma and the GP value of INPUT_BFD. We
1411 must change this to be the difference between the
1412 final definition (which will end up in RELOCATION)
1413 and the GP value of OUTPUT_BFD (which is in GP). */
1414 addend = ecoff_data (input_bfd)->gp - gp;
1416 else if (! info->relocatable
1417 || h->root.type == bfd_link_hash_defined
1418 || h->root.type == bfd_link_hash_defweak)
1420 /* This is a relocation against a defined symbol. The
1421 current addend in the instruction is simply the
1422 desired offset into the symbol (normally zero). We
1423 are going to change this into a relocation against a
1424 defined symbol, so we want the instruction to hold
1425 the difference between the final definition of the
1426 symbol (which will end up in RELOCATION) and the GP
1427 value of OUTPUT_BFD (which is in GP). */
1428 addend = - gp;
1430 else
1432 /* This is a relocation against an undefined or common
1433 symbol. The current addend in the instruction is
1434 simply the desired offset into the symbol (normally
1435 zero). We are generating relocatable output, and we
1436 aren't going to define this symbol, so we just leave
1437 the instruction alone. */
1438 addend = 0;
1442 /* If we are relaxing, mips_relax_section may have set
1443 offsets[i] to some value. A value of 1 means we must expand
1444 a PC relative branch into a multi-instruction of sequence,
1445 and any other value is an addend. */
1446 if (offsets != NULL
1447 && offsets[i] != 0)
1449 BFD_ASSERT (! info->relocatable);
1450 BFD_ASSERT (int_rel.r_type == MIPS_R_PCREL16
1451 || int_rel.r_type == MIPS_R_RELHI
1452 || int_rel.r_type == MIPS_R_RELLO);
1453 if (offsets[i] != 1)
1454 addend += offsets[i];
1455 else
1457 bfd_byte *here;
1459 BFD_ASSERT (int_rel.r_extern
1460 && int_rel.r_type == MIPS_R_PCREL16);
1462 /* Move the rest of the instructions up. */
1463 here = (contents
1464 + adjust
1465 + int_rel.r_vaddr
1466 - input_section->vma);
1467 memmove (here + PCREL16_EXPANSION_ADJUSTMENT, here,
1468 (size_t) (input_section->_raw_size
1469 - (int_rel.r_vaddr - input_section->vma)));
1471 /* Generate the new instructions. */
1472 if (! mips_relax_pcrel16 (info, input_bfd, input_section,
1473 h, here,
1474 (input_section->output_section->vma
1475 + input_section->output_offset
1476 + (int_rel.r_vaddr
1477 - input_section->vma)
1478 + adjust)))
1479 return FALSE;
1481 /* We must adjust everything else up a notch. */
1482 adjust += PCREL16_EXPANSION_ADJUSTMENT;
1484 /* mips_relax_pcrel16 handles all the details of this
1485 relocation. */
1486 continue;
1490 /* If we are relaxing, and this is a reloc against the .text
1491 segment, we may need to adjust it if some branches have been
1492 expanded. The reloc types which are likely to occur in the
1493 .text section are handled efficiently by mips_relax_section,
1494 and thus do not need to be handled here. */
1495 if (ecoff_data (input_bfd)->debug_info.adjust != NULL
1496 && ! int_rel.r_extern
1497 && int_rel.r_symndx == RELOC_SECTION_TEXT
1498 && (strcmp (bfd_get_section_name (input_bfd, input_section),
1499 ".text") != 0
1500 || (int_rel.r_type != MIPS_R_PCREL16
1501 && int_rel.r_type != MIPS_R_SWITCH
1502 && int_rel.r_type != MIPS_R_RELHI
1503 && int_rel.r_type != MIPS_R_RELLO)))
1505 bfd_vma adr;
1506 struct ecoff_value_adjust *a;
1508 /* We need to get the addend so that we know whether we need
1509 to adjust the address. */
1510 BFD_ASSERT (int_rel.r_type == MIPS_R_REFWORD);
1512 adr = bfd_get_32 (input_bfd,
1513 (contents
1514 + adjust
1515 + int_rel.r_vaddr
1516 - input_section->vma));
1518 for (a = ecoff_data (input_bfd)->debug_info.adjust;
1519 a != (struct ecoff_value_adjust *) NULL;
1520 a = a->next)
1522 if (adr >= a->start && adr < a->end)
1523 addend += a->adjust;
1527 if (info->relocatable)
1529 /* We are generating relocatable output, and must convert
1530 the existing reloc. */
1531 if (int_rel.r_extern)
1533 if ((h->root.type == bfd_link_hash_defined
1534 || h->root.type == bfd_link_hash_defweak)
1535 && ! bfd_is_abs_section (h->root.u.def.section))
1537 const char *name;
1539 /* This symbol is defined in the output. Convert
1540 the reloc from being against the symbol to being
1541 against the section. */
1543 /* Clear the r_extern bit. */
1544 int_rel.r_extern = 0;
1546 /* Compute a new r_symndx value. */
1547 s = h->root.u.def.section;
1548 name = bfd_get_section_name (output_bfd,
1549 s->output_section);
1551 int_rel.r_symndx = -1;
1552 switch (name[1])
1554 case 'b':
1555 if (strcmp (name, ".bss") == 0)
1556 int_rel.r_symndx = RELOC_SECTION_BSS;
1557 break;
1558 case 'd':
1559 if (strcmp (name, ".data") == 0)
1560 int_rel.r_symndx = RELOC_SECTION_DATA;
1561 break;
1562 case 'f':
1563 if (strcmp (name, ".fini") == 0)
1564 int_rel.r_symndx = RELOC_SECTION_FINI;
1565 break;
1566 case 'i':
1567 if (strcmp (name, ".init") == 0)
1568 int_rel.r_symndx = RELOC_SECTION_INIT;
1569 break;
1570 case 'l':
1571 if (strcmp (name, ".lit8") == 0)
1572 int_rel.r_symndx = RELOC_SECTION_LIT8;
1573 else if (strcmp (name, ".lit4") == 0)
1574 int_rel.r_symndx = RELOC_SECTION_LIT4;
1575 break;
1576 case 'r':
1577 if (strcmp (name, ".rdata") == 0)
1578 int_rel.r_symndx = RELOC_SECTION_RDATA;
1579 break;
1580 case 's':
1581 if (strcmp (name, ".sdata") == 0)
1582 int_rel.r_symndx = RELOC_SECTION_SDATA;
1583 else if (strcmp (name, ".sbss") == 0)
1584 int_rel.r_symndx = RELOC_SECTION_SBSS;
1585 break;
1586 case 't':
1587 if (strcmp (name, ".text") == 0)
1588 int_rel.r_symndx = RELOC_SECTION_TEXT;
1589 break;
1592 if (int_rel.r_symndx == -1)
1593 abort ();
1595 /* Add the section VMA and the symbol value. */
1596 relocation = (h->root.u.def.value
1597 + s->output_section->vma
1598 + s->output_offset);
1600 /* For a PC relative relocation, the object file
1601 currently holds just the addend. We must adjust
1602 by the address to get the right value. */
1603 if (howto->pc_relative)
1605 relocation -= int_rel.r_vaddr - input_section->vma;
1607 /* If we are converting a RELHI or RELLO reloc
1608 from being against an external symbol to
1609 being against a section, we must put a
1610 special value into the r_offset field. This
1611 value is the old addend. The r_offset for
1612 both the RELHI and RELLO relocs are the same,
1613 and we set both when we see RELHI. */
1614 if (int_rel.r_type == MIPS_R_RELHI)
1616 long addhi, addlo;
1618 addhi = bfd_get_32 (input_bfd,
1619 (contents
1620 + adjust
1621 + int_rel.r_vaddr
1622 - input_section->vma));
1623 addhi &= 0xffff;
1624 if (addhi & 0x8000)
1625 addhi -= 0x10000;
1626 addhi <<= 16;
1628 if (! use_lo)
1629 addlo = 0;
1630 else
1632 addlo = bfd_get_32 (input_bfd,
1633 (contents
1634 + adjust
1635 + lo_int_rel.r_vaddr
1636 - input_section->vma));
1637 addlo &= 0xffff;
1638 if (addlo & 0x8000)
1639 addlo -= 0x10000;
1641 lo_int_rel.r_offset = addhi + addlo;
1644 int_rel.r_offset = addhi + addlo;
1648 h = NULL;
1650 else
1652 /* Change the symndx value to the right one for the
1653 output BFD. */
1654 int_rel.r_symndx = h->indx;
1655 if (int_rel.r_symndx == -1)
1657 /* This symbol is not being written out. */
1658 if (! ((*info->callbacks->unattached_reloc)
1659 (info, h->root.root.string, input_bfd,
1660 input_section,
1661 int_rel.r_vaddr - input_section->vma)))
1662 return FALSE;
1663 int_rel.r_symndx = 0;
1665 relocation = 0;
1668 else
1670 /* This is a relocation against a section. Adjust the
1671 value by the amount the section moved. */
1672 relocation = (s->output_section->vma
1673 + s->output_offset
1674 - s->vma);
1677 relocation += addend;
1678 addend = 0;
1680 /* Adjust a PC relative relocation by removing the reference
1681 to the original address in the section and including the
1682 reference to the new address. However, external RELHI
1683 and RELLO relocs are PC relative, but don't include any
1684 reference to the address. The addend is merely an
1685 addend. */
1686 if (howto->pc_relative
1687 && (! int_rel.r_extern
1688 || (int_rel.r_type != MIPS_R_RELHI
1689 && int_rel.r_type != MIPS_R_RELLO)))
1690 relocation -= (input_section->output_section->vma
1691 + input_section->output_offset
1692 - input_section->vma);
1694 /* Adjust the contents. */
1695 if (relocation == 0)
1696 r = bfd_reloc_ok;
1697 else
1699 if (int_rel.r_type != MIPS_R_REFHI
1700 && int_rel.r_type != MIPS_R_RELHI)
1701 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1702 (contents
1703 + adjust
1704 + int_rel.r_vaddr
1705 - input_section->vma));
1706 else
1708 mips_relocate_hi (&int_rel,
1709 use_lo ? &lo_int_rel : NULL,
1710 input_bfd, input_section, contents,
1711 adjust, relocation,
1712 int_rel.r_type == MIPS_R_RELHI);
1713 r = bfd_reloc_ok;
1717 /* Adjust the reloc address. */
1718 int_rel.r_vaddr += (input_section->output_section->vma
1719 + input_section->output_offset
1720 - input_section->vma);
1722 /* Save the changed reloc information. */
1723 mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
1725 else
1727 /* We are producing a final executable. */
1728 if (int_rel.r_extern)
1730 /* This is a reloc against a symbol. */
1731 if (h->root.type == bfd_link_hash_defined
1732 || h->root.type == bfd_link_hash_defweak)
1734 asection *hsec;
1736 hsec = h->root.u.def.section;
1737 relocation = (h->root.u.def.value
1738 + hsec->output_section->vma
1739 + hsec->output_offset);
1741 else
1743 if (! ((*info->callbacks->undefined_symbol)
1744 (info, h->root.root.string, input_bfd,
1745 input_section,
1746 int_rel.r_vaddr - input_section->vma, TRUE)))
1747 return FALSE;
1748 relocation = 0;
1751 else
1753 /* This is a reloc against a section. */
1754 relocation = (s->output_section->vma
1755 + s->output_offset
1756 - s->vma);
1758 /* A PC relative reloc is already correct in the object
1759 file. Make it look like a pcrel_offset relocation by
1760 adding in the start address. */
1761 if (howto->pc_relative)
1763 if (int_rel.r_type != MIPS_R_RELHI || ! use_lo)
1764 relocation += int_rel.r_vaddr + adjust;
1765 else
1766 relocation += lo_int_rel.r_vaddr + adjust;
1770 if (int_rel.r_type != MIPS_R_REFHI
1771 && int_rel.r_type != MIPS_R_RELHI)
1772 r = _bfd_final_link_relocate (howto,
1773 input_bfd,
1774 input_section,
1775 contents,
1776 (int_rel.r_vaddr
1777 - input_section->vma
1778 + adjust),
1779 relocation,
1780 addend);
1781 else
1783 mips_relocate_hi (&int_rel,
1784 use_lo ? &lo_int_rel : NULL,
1785 input_bfd, input_section, contents, adjust,
1786 relocation,
1787 int_rel.r_type == MIPS_R_RELHI);
1788 r = bfd_reloc_ok;
1792 /* MIPS_R_JMPADDR requires peculiar overflow detection. The
1793 instruction provides a 28 bit address (the two lower bits are
1794 implicit zeroes) which is combined with the upper four bits
1795 of the instruction address. */
1796 if (r == bfd_reloc_ok
1797 && int_rel.r_type == MIPS_R_JMPADDR
1798 && (((relocation
1799 + addend
1800 + (int_rel.r_extern ? 0 : s->vma))
1801 & 0xf0000000)
1802 != ((input_section->output_section->vma
1803 + input_section->output_offset
1804 + (int_rel.r_vaddr - input_section->vma)
1805 + adjust)
1806 & 0xf0000000)))
1807 r = bfd_reloc_overflow;
1809 if (r != bfd_reloc_ok)
1811 switch (r)
1813 default:
1814 case bfd_reloc_outofrange:
1815 abort ();
1816 case bfd_reloc_overflow:
1818 const char *name;
1820 if (int_rel.r_extern)
1821 name = h->root.root.string;
1822 else
1823 name = bfd_section_name (input_bfd, s);
1824 if (! ((*info->callbacks->reloc_overflow)
1825 (info, name, howto->name, (bfd_vma) 0,
1826 input_bfd, input_section,
1827 int_rel.r_vaddr - input_section->vma)))
1828 return FALSE;
1830 break;
1835 return TRUE;
1838 /* Read in the relocs for a section. */
1840 static bfd_boolean
1841 mips_read_relocs (abfd, sec)
1842 bfd *abfd;
1843 asection *sec;
1845 struct ecoff_section_tdata *section_tdata;
1846 bfd_size_type amt;
1848 section_tdata = ecoff_section_data (abfd, sec);
1849 if (section_tdata == (struct ecoff_section_tdata *) NULL)
1851 amt = sizeof (struct ecoff_section_tdata);
1852 sec->used_by_bfd = (PTR) bfd_alloc (abfd, amt);
1853 if (sec->used_by_bfd == NULL)
1854 return FALSE;
1856 section_tdata = ecoff_section_data (abfd, sec);
1857 section_tdata->external_relocs = NULL;
1858 section_tdata->contents = NULL;
1859 section_tdata->offsets = NULL;
1862 if (section_tdata->external_relocs == NULL)
1864 amt = ecoff_backend (abfd)->external_reloc_size;
1865 amt *= sec->reloc_count;
1866 section_tdata->external_relocs = (PTR) bfd_alloc (abfd, amt);
1867 if (section_tdata->external_relocs == NULL && amt != 0)
1868 return FALSE;
1870 if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
1871 || bfd_bread (section_tdata->external_relocs, amt, abfd) != amt)
1872 return FALSE;
1875 return TRUE;
1878 /* Relax a section when linking a MIPS ECOFF file. This is used for
1879 embedded PIC code, which always uses PC relative branches which
1880 only have an 18 bit range on MIPS. If a branch is not in range, we
1881 generate a long instruction sequence to compensate. Each time we
1882 find a branch to expand, we have to check all the others again to
1883 make sure they are still in range. This is slow, but it only has
1884 to be done when -relax is passed to the linker.
1886 This routine figures out which branches need to expand; the actual
1887 expansion is done in mips_relocate_section when the section
1888 contents are relocated. The information is stored in the offsets
1889 field of the ecoff_section_tdata structure. An offset of 1 means
1890 that the branch must be expanded into a multi-instruction PC
1891 relative branch (such an offset will only occur for a PC relative
1892 branch to an external symbol). Any other offset must be a multiple
1893 of four, and is the amount to change the branch by (such an offset
1894 will only occur for a PC relative branch within the same section).
1896 We do not modify the section relocs or contents themselves so that
1897 if memory usage becomes an issue we can discard them and read them
1898 again. The only information we must save in memory between this
1899 routine and the mips_relocate_section routine is the table of
1900 offsets. */
1902 static bfd_boolean
1903 mips_relax_section (abfd, sec, info, again)
1904 bfd *abfd;
1905 asection *sec;
1906 struct bfd_link_info *info;
1907 bfd_boolean *again;
1909 struct ecoff_section_tdata *section_tdata;
1910 bfd_byte *contents = NULL;
1911 long *offsets;
1912 struct external_reloc *ext_rel;
1913 struct external_reloc *ext_rel_end;
1914 unsigned int i;
1916 /* Assume we are not going to need another pass. */
1917 *again = FALSE;
1919 /* If we are not generating an ECOFF file, this is much too
1920 confusing to deal with. */
1921 if (info->hash->creator->flavour != bfd_get_flavour (abfd))
1922 return TRUE;
1924 /* If there are no relocs, there is nothing to do. */
1925 if (sec->reloc_count == 0)
1926 return TRUE;
1928 /* We are only interested in PC relative relocs, and why would there
1929 ever be one from anything but the .text section? */
1930 if (strcmp (bfd_get_section_name (abfd, sec), ".text") != 0)
1931 return TRUE;
1933 /* Read in the relocs, if we haven't already got them. */
1934 section_tdata = ecoff_section_data (abfd, sec);
1935 if (section_tdata == (struct ecoff_section_tdata *) NULL
1936 || section_tdata->external_relocs == NULL)
1938 if (! mips_read_relocs (abfd, sec))
1939 goto error_return;
1940 section_tdata = ecoff_section_data (abfd, sec);
1943 if (sec->_cooked_size == 0)
1945 /* We must initialize _cooked_size only the first time we are
1946 called. */
1947 sec->_cooked_size = sec->_raw_size;
1950 contents = section_tdata->contents;
1951 offsets = section_tdata->offsets;
1953 /* Look for any external PC relative relocs. Internal PC relative
1954 relocs are already correct in the object file, so they certainly
1955 can not overflow. */
1956 ext_rel = (struct external_reloc *) section_tdata->external_relocs;
1957 ext_rel_end = ext_rel + sec->reloc_count;
1958 for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
1960 struct internal_reloc int_rel;
1961 struct ecoff_link_hash_entry *h;
1962 asection *hsec;
1963 bfd_signed_vma relocation;
1964 struct external_reloc *adj_ext_rel;
1965 unsigned int adj_i;
1966 unsigned long ext_count;
1967 struct ecoff_link_hash_entry **adj_h_ptr;
1968 struct ecoff_link_hash_entry **adj_h_ptr_end;
1969 struct ecoff_value_adjust *adjust;
1970 bfd_size_type amt;
1972 /* If we have already expanded this reloc, we certainly don't
1973 need to do it again. */
1974 if (offsets != (long *) NULL && offsets[i] == 1)
1975 continue;
1977 /* Quickly check that this reloc is external PCREL16. */
1978 if (bfd_header_big_endian (abfd))
1980 if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_BIG) == 0
1981 || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_BIG)
1982 >> RELOC_BITS3_TYPE_SH_BIG)
1983 != MIPS_R_PCREL16))
1984 continue;
1986 else
1988 if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) == 0
1989 || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
1990 >> RELOC_BITS3_TYPE_SH_LITTLE)
1991 != MIPS_R_PCREL16))
1992 continue;
1995 mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel);
1997 h = ecoff_data (abfd)->sym_hashes[int_rel.r_symndx];
1998 if (h == (struct ecoff_link_hash_entry *) NULL)
1999 abort ();
2001 if (h->root.type != bfd_link_hash_defined
2002 && h->root.type != bfd_link_hash_defweak)
2004 /* Just ignore undefined symbols. These will presumably
2005 generate an error later in the link. */
2006 continue;
2009 /* Get the value of the symbol. */
2010 hsec = h->root.u.def.section;
2011 relocation = (h->root.u.def.value
2012 + hsec->output_section->vma
2013 + hsec->output_offset);
2015 /* Subtract out the current address. */
2016 relocation -= (sec->output_section->vma
2017 + sec->output_offset
2018 + (int_rel.r_vaddr - sec->vma));
2020 /* The addend is stored in the object file. In the normal case
2021 of ``bal symbol'', the addend will be -4. It will only be
2022 different in the case of ``bal symbol+constant''. To avoid
2023 always reading in the section contents, we don't check the
2024 addend in the object file (we could easily check the contents
2025 if we happen to have already read them in, but I fear that
2026 this could be confusing). This means we will screw up if
2027 there is a branch to a symbol that is in range, but added to
2028 a constant which puts it out of range; in such a case the
2029 link will fail with a reloc overflow error. Since the
2030 compiler will never generate such code, it should be easy
2031 enough to work around it by changing the assembly code in the
2032 source file. */
2033 relocation -= 4;
2035 /* Now RELOCATION is the number we want to put in the object
2036 file. See whether it fits. */
2037 if (relocation >= -0x20000 && relocation < 0x20000)
2038 continue;
2040 /* Now that we know this reloc needs work, which will rarely
2041 happen, go ahead and grab the section contents. */
2042 if (contents == (bfd_byte *) NULL)
2044 if (info->keep_memory)
2045 contents = (bfd_byte *) bfd_alloc (abfd, sec->_raw_size);
2046 else
2047 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
2048 if (contents == (bfd_byte *) NULL)
2049 goto error_return;
2050 if (! bfd_get_section_contents (abfd, sec, (PTR) contents,
2051 (file_ptr) 0, sec->_raw_size))
2052 goto error_return;
2053 if (info->keep_memory)
2054 section_tdata->contents = contents;
2057 /* We only support changing the bal instruction. It would be
2058 possible to handle other PC relative branches, but some of
2059 them (the conditional branches) would require a different
2060 length instruction sequence which would complicate both this
2061 routine and mips_relax_pcrel16. It could be written if
2062 somebody felt it were important. Ignoring this reloc will
2063 presumably cause a reloc overflow error later on. */
2064 if (bfd_get_32 (abfd, contents + int_rel.r_vaddr - sec->vma)
2065 != 0x0411ffff) /* bgezal $0,. == bal . */
2066 continue;
2068 /* Bother. We need to expand this reloc, and we will need to
2069 make another relaxation pass since this change may put other
2070 relocs out of range. We need to examine the local branches
2071 and we need to allocate memory to hold the offsets we must
2072 add to them. We also need to adjust the values of all
2073 symbols in the object file following this location. */
2075 sec->_cooked_size += PCREL16_EXPANSION_ADJUSTMENT;
2076 *again = TRUE;
2078 if (offsets == (long *) NULL)
2080 bfd_size_type size;
2082 size = (bfd_size_type) sec->reloc_count * sizeof (long);
2083 offsets = (long *) bfd_zalloc (abfd, size);
2084 if (offsets == (long *) NULL)
2085 goto error_return;
2086 section_tdata->offsets = offsets;
2089 offsets[i] = 1;
2091 /* Now look for all PC relative references that cross this reloc
2092 and adjust their offsets. */
2093 adj_ext_rel = (struct external_reloc *) section_tdata->external_relocs;
2094 for (adj_i = 0; adj_ext_rel < ext_rel_end; adj_ext_rel++, adj_i++)
2096 struct internal_reloc adj_int_rel;
2097 bfd_vma start, stop;
2098 int change;
2100 mips_ecoff_swap_reloc_in (abfd, (PTR) adj_ext_rel, &adj_int_rel);
2102 if (adj_int_rel.r_type == MIPS_R_PCREL16)
2104 unsigned long insn;
2106 /* We only care about local references. External ones
2107 will be relocated correctly anyhow. */
2108 if (adj_int_rel.r_extern)
2109 continue;
2111 /* We are only interested in a PC relative reloc within
2112 this section. FIXME: Cross section PC relative
2113 relocs may not be handled correctly; does anybody
2114 care? */
2115 if (adj_int_rel.r_symndx != RELOC_SECTION_TEXT)
2116 continue;
2118 start = adj_int_rel.r_vaddr;
2120 insn = bfd_get_32 (abfd,
2121 contents + adj_int_rel.r_vaddr - sec->vma);
2123 stop = (insn & 0xffff) << 2;
2124 if ((stop & 0x20000) != 0)
2125 stop -= 0x40000;
2126 stop += adj_int_rel.r_vaddr + 4;
2128 else if (adj_int_rel.r_type == MIPS_R_RELHI)
2130 struct internal_reloc rello;
2131 long addhi, addlo;
2133 /* The next reloc must be MIPS_R_RELLO, and we handle
2134 them together. */
2135 BFD_ASSERT (adj_ext_rel + 1 < ext_rel_end);
2137 mips_ecoff_swap_reloc_in (abfd, (PTR) (adj_ext_rel + 1), &rello);
2139 BFD_ASSERT (rello.r_type == MIPS_R_RELLO);
2141 addhi = bfd_get_32 (abfd,
2142 contents + adj_int_rel.r_vaddr - sec->vma);
2143 addhi &= 0xffff;
2144 if (addhi & 0x8000)
2145 addhi -= 0x10000;
2146 addhi <<= 16;
2148 addlo = bfd_get_32 (abfd, contents + rello.r_vaddr - sec->vma);
2149 addlo &= 0xffff;
2150 if (addlo & 0x8000)
2151 addlo -= 0x10000;
2153 if (adj_int_rel.r_extern)
2155 /* The value we want here is
2156 sym - RELLOaddr + addend
2157 which we can express as
2158 sym - (RELLOaddr - addend)
2159 Therefore if we are expanding the area between
2160 RELLOaddr and RELLOaddr - addend we must adjust
2161 the addend. This is admittedly ambiguous, since
2162 we might mean (sym + addend) - RELLOaddr, but in
2163 practice we don't, and there is no way to handle
2164 that case correctly since at this point we have
2165 no idea whether any reloc is being expanded
2166 between sym and sym + addend. */
2167 start = rello.r_vaddr - (addhi + addlo);
2168 stop = rello.r_vaddr;
2170 else
2172 /* An internal RELHI/RELLO pair represents the
2173 difference between two addresses, $LC0 - foo.
2174 The symndx value is actually the difference
2175 between the reloc address and $LC0. This lets us
2176 compute $LC0, and, by considering the addend,
2177 foo. If the reloc we are expanding falls between
2178 those two relocs, we must adjust the addend. At
2179 this point, the symndx value is actually in the
2180 r_offset field, where it was put by
2181 mips_ecoff_swap_reloc_in. */
2182 start = rello.r_vaddr - adj_int_rel.r_offset;
2183 stop = start + addhi + addlo;
2186 else if (adj_int_rel.r_type == MIPS_R_SWITCH)
2188 /* A MIPS_R_SWITCH reloc represents a word of the form
2189 .word $L3-$LS12
2190 The value in the object file is correct, assuming the
2191 original value of $L3. The symndx value is actually
2192 the difference between the reloc address and $LS12.
2193 This lets us compute the original value of $LS12 as
2194 vaddr - symndx
2195 and the original value of $L3 as
2196 vaddr - symndx + addend
2197 where addend is the value from the object file. At
2198 this point, the symndx value is actually found in the
2199 r_offset field, since it was moved by
2200 mips_ecoff_swap_reloc_in. */
2201 start = adj_int_rel.r_vaddr - adj_int_rel.r_offset;
2202 stop = start + bfd_get_32 (abfd,
2203 (contents
2204 + adj_int_rel.r_vaddr
2205 - sec->vma));
2207 else
2208 continue;
2210 /* If the range expressed by this reloc, which is the
2211 distance between START and STOP crosses the reloc we are
2212 expanding, we must adjust the offset. The sign of the
2213 adjustment depends upon the direction in which the range
2214 crosses the reloc being expanded. */
2215 if (start <= int_rel.r_vaddr && stop > int_rel.r_vaddr)
2216 change = PCREL16_EXPANSION_ADJUSTMENT;
2217 else if (start > int_rel.r_vaddr && stop <= int_rel.r_vaddr)
2218 change = - PCREL16_EXPANSION_ADJUSTMENT;
2219 else
2220 change = 0;
2222 offsets[adj_i] += change;
2224 if (adj_int_rel.r_type == MIPS_R_RELHI)
2226 adj_ext_rel++;
2227 adj_i++;
2228 offsets[adj_i] += change;
2232 /* Find all symbols in this section defined by this object file
2233 and adjust their values. Note that we decide whether to
2234 adjust the value based on the value stored in the ECOFF EXTR
2235 structure, because the value stored in the hash table may
2236 have been changed by an earlier expanded reloc and thus may
2237 no longer correctly indicate whether the symbol is before or
2238 after the expanded reloc. */
2239 ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax;
2240 adj_h_ptr = ecoff_data (abfd)->sym_hashes;
2241 adj_h_ptr_end = adj_h_ptr + ext_count;
2242 for (; adj_h_ptr < adj_h_ptr_end; adj_h_ptr++)
2244 struct ecoff_link_hash_entry *adj_h;
2246 adj_h = *adj_h_ptr;
2247 if (adj_h != (struct ecoff_link_hash_entry *) NULL
2248 && (adj_h->root.type == bfd_link_hash_defined
2249 || adj_h->root.type == bfd_link_hash_defweak)
2250 && adj_h->root.u.def.section == sec
2251 && adj_h->esym.asym.value > int_rel.r_vaddr)
2252 adj_h->root.u.def.value += PCREL16_EXPANSION_ADJUSTMENT;
2255 /* Add an entry to the symbol value adjust list. This is used
2256 by bfd_ecoff_debug_accumulate to adjust the values of
2257 internal symbols and FDR's. */
2258 amt = sizeof (struct ecoff_value_adjust);
2259 adjust = (struct ecoff_value_adjust *) bfd_alloc (abfd, amt);
2260 if (adjust == (struct ecoff_value_adjust *) NULL)
2261 goto error_return;
2263 adjust->start = int_rel.r_vaddr;
2264 adjust->end = sec->vma + sec->_raw_size;
2265 adjust->adjust = PCREL16_EXPANSION_ADJUSTMENT;
2267 adjust->next = ecoff_data (abfd)->debug_info.adjust;
2268 ecoff_data (abfd)->debug_info.adjust = adjust;
2271 if (contents != (bfd_byte *) NULL && ! info->keep_memory)
2272 free (contents);
2274 return TRUE;
2276 error_return:
2277 if (contents != (bfd_byte *) NULL && ! info->keep_memory)
2278 free (contents);
2279 return FALSE;
2282 /* This routine is called from mips_relocate_section when a PC
2283 relative reloc must be expanded into the five instruction sequence.
2284 It handles all the details of the expansion, including resolving
2285 the reloc. */
2287 static bfd_boolean
2288 mips_relax_pcrel16 (info, input_bfd, input_section, h, location, address)
2289 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2290 bfd *input_bfd;
2291 asection *input_section ATTRIBUTE_UNUSED;
2292 struct ecoff_link_hash_entry *h;
2293 bfd_byte *location;
2294 bfd_vma address;
2296 bfd_vma relocation;
2298 /* 0x0411ffff is bgezal $0,. == bal . */
2299 BFD_ASSERT (bfd_get_32 (input_bfd, location) == 0x0411ffff);
2301 /* We need to compute the distance between the symbol and the
2302 current address plus eight. */
2303 relocation = (h->root.u.def.value
2304 + h->root.u.def.section->output_section->vma
2305 + h->root.u.def.section->output_offset);
2306 relocation -= address + 8;
2308 /* If the lower half is negative, increment the upper 16 half. */
2309 if ((relocation & 0x8000) != 0)
2310 relocation += 0x10000;
2312 bfd_put_32 (input_bfd, (bfd_vma) 0x04110001, location); /* bal .+8 */
2313 bfd_put_32 (input_bfd,
2314 0x3c010000 | ((relocation >> 16) & 0xffff), /* lui $at,XX */
2315 location + 4);
2316 bfd_put_32 (input_bfd,
2317 0x24210000 | (relocation & 0xffff), /* addiu $at,$at,XX */
2318 location + 8);
2319 bfd_put_32 (input_bfd,
2320 (bfd_vma) 0x003f0821, location + 12); /* addu $at,$at,$ra */
2321 bfd_put_32 (input_bfd,
2322 (bfd_vma) 0x0020f809, location + 16); /* jalr $at */
2324 return TRUE;
2327 /* Given a .sdata section and a .rel.sdata in-memory section, store
2328 relocation information into the .rel.sdata section which can be
2329 used at runtime to relocate the section. This is called by the
2330 linker when the --embedded-relocs switch is used. This is called
2331 after the add_symbols entry point has been called for all the
2332 objects, and before the final_link entry point is called. This
2333 function presumes that the object was compiled using
2334 -membedded-pic. */
2336 bfd_boolean
2337 bfd_mips_ecoff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
2338 bfd *abfd;
2339 struct bfd_link_info *info;
2340 asection *datasec;
2341 asection *relsec;
2342 char **errmsg;
2344 struct ecoff_link_hash_entry **sym_hashes;
2345 struct ecoff_section_tdata *section_tdata;
2346 struct external_reloc *ext_rel;
2347 struct external_reloc *ext_rel_end;
2348 bfd_byte *p;
2349 bfd_size_type amt;
2351 BFD_ASSERT (! info->relocatable);
2353 *errmsg = NULL;
2355 if (datasec->reloc_count == 0)
2356 return TRUE;
2358 sym_hashes = ecoff_data (abfd)->sym_hashes;
2360 if (! mips_read_relocs (abfd, datasec))
2361 return FALSE;
2363 amt = (bfd_size_type) datasec->reloc_count * 4;
2364 relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
2365 if (relsec->contents == NULL)
2366 return FALSE;
2368 p = relsec->contents;
2370 section_tdata = ecoff_section_data (abfd, datasec);
2371 ext_rel = (struct external_reloc *) section_tdata->external_relocs;
2372 ext_rel_end = ext_rel + datasec->reloc_count;
2373 for (; ext_rel < ext_rel_end; ext_rel++, p += 4)
2375 struct internal_reloc int_rel;
2376 bfd_boolean text_relative;
2378 mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel);
2380 /* We are going to write a four byte word into the runtime reloc
2381 section. The word will be the address in the data section
2382 which must be relocated. This must be on a word boundary,
2383 which means the lower two bits must be zero. We use the
2384 least significant bit to indicate how the value in the data
2385 section must be relocated. A 0 means that the value is
2386 relative to the text section, while a 1 indicates that the
2387 value is relative to the data section. Given that we are
2388 assuming the code was compiled using -membedded-pic, there
2389 should not be any other possibilities. */
2391 /* We can only relocate REFWORD relocs at run time. */
2392 if (int_rel.r_type != MIPS_R_REFWORD)
2394 *errmsg = _("unsupported reloc type");
2395 bfd_set_error (bfd_error_bad_value);
2396 return FALSE;
2399 if (int_rel.r_extern)
2401 struct ecoff_link_hash_entry *h;
2403 h = sym_hashes[int_rel.r_symndx];
2404 /* If h is NULL, that means that there is a reloc against an
2405 external symbol which we thought was just a debugging
2406 symbol. This should not happen. */
2407 if (h == (struct ecoff_link_hash_entry *) NULL)
2408 abort ();
2409 if ((h->root.type == bfd_link_hash_defined
2410 || h->root.type == bfd_link_hash_defweak)
2411 && (h->root.u.def.section->flags & SEC_CODE) != 0)
2412 text_relative = TRUE;
2413 else
2414 text_relative = FALSE;
2416 else
2418 switch (int_rel.r_symndx)
2420 case RELOC_SECTION_TEXT:
2421 text_relative = TRUE;
2422 break;
2423 case RELOC_SECTION_SDATA:
2424 case RELOC_SECTION_SBSS:
2425 case RELOC_SECTION_LIT8:
2426 text_relative = FALSE;
2427 break;
2428 default:
2429 /* No other sections should appear in -membedded-pic
2430 code. */
2431 *errmsg = _("reloc against unsupported section");
2432 bfd_set_error (bfd_error_bad_value);
2433 return FALSE;
2437 if ((int_rel.r_offset & 3) != 0)
2439 *errmsg = _("reloc not properly aligned");
2440 bfd_set_error (bfd_error_bad_value);
2441 return FALSE;
2444 bfd_put_32 (abfd,
2445 (int_rel.r_vaddr - datasec->vma + datasec->output_offset
2446 + (text_relative ? 0 : 1)),
2450 return TRUE;
2453 /* This is the ECOFF backend structure. The backend field of the
2454 target vector points to this. */
2456 static const struct ecoff_backend_data mips_ecoff_backend_data =
2458 /* COFF backend structure. */
2460 (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
2461 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
2462 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
2463 (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
2464 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
2465 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
2466 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
2467 mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
2468 mips_ecoff_swap_scnhdr_out,
2469 FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE, FALSE, 4, FALSE, 2,
2470 mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
2471 mips_ecoff_swap_scnhdr_in, NULL,
2472 mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
2473 _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
2474 _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
2475 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2476 NULL, NULL
2478 /* Supported architecture. */
2479 bfd_arch_mips,
2480 /* Initial portion of armap string. */
2481 "__________",
2482 /* The page boundary used to align sections in a demand-paged
2483 executable file. E.g., 0x1000. */
2484 0x1000,
2485 /* TRUE if the .rdata section is part of the text segment, as on the
2486 Alpha. FALSE if .rdata is part of the data segment, as on the
2487 MIPS. */
2488 FALSE,
2489 /* Bitsize of constructor entries. */
2491 /* Reloc to use for constructor entries. */
2492 &mips_howto_table[MIPS_R_REFWORD],
2494 /* Symbol table magic number. */
2495 magicSym,
2496 /* Alignment of debugging information. E.g., 4. */
2498 /* Sizes of external symbolic information. */
2499 sizeof (struct hdr_ext),
2500 sizeof (struct dnr_ext),
2501 sizeof (struct pdr_ext),
2502 sizeof (struct sym_ext),
2503 sizeof (struct opt_ext),
2504 sizeof (struct fdr_ext),
2505 sizeof (struct rfd_ext),
2506 sizeof (struct ext_ext),
2507 /* Functions to swap in external symbolic data. */
2508 ecoff_swap_hdr_in,
2509 ecoff_swap_dnr_in,
2510 ecoff_swap_pdr_in,
2511 ecoff_swap_sym_in,
2512 ecoff_swap_opt_in,
2513 ecoff_swap_fdr_in,
2514 ecoff_swap_rfd_in,
2515 ecoff_swap_ext_in,
2516 _bfd_ecoff_swap_tir_in,
2517 _bfd_ecoff_swap_rndx_in,
2518 /* Functions to swap out external symbolic data. */
2519 ecoff_swap_hdr_out,
2520 ecoff_swap_dnr_out,
2521 ecoff_swap_pdr_out,
2522 ecoff_swap_sym_out,
2523 ecoff_swap_opt_out,
2524 ecoff_swap_fdr_out,
2525 ecoff_swap_rfd_out,
2526 ecoff_swap_ext_out,
2527 _bfd_ecoff_swap_tir_out,
2528 _bfd_ecoff_swap_rndx_out,
2529 /* Function to read in symbolic data. */
2530 _bfd_ecoff_slurp_symbolic_info
2532 /* External reloc size. */
2533 RELSZ,
2534 /* Reloc swapping functions. */
2535 mips_ecoff_swap_reloc_in,
2536 mips_ecoff_swap_reloc_out,
2537 /* Backend reloc tweaking. */
2538 mips_adjust_reloc_in,
2539 mips_adjust_reloc_out,
2540 /* Relocate section contents while linking. */
2541 mips_relocate_section,
2542 /* Do final adjustments to filehdr and aouthdr. */
2543 NULL,
2544 /* Read an element from an archive at a given file position. */
2545 _bfd_get_elt_at_filepos
2548 /* Looking up a reloc type is MIPS specific. */
2549 #define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
2551 /* Getting relocated section contents is generic. */
2552 #define _bfd_ecoff_bfd_get_relocated_section_contents \
2553 bfd_generic_get_relocated_section_contents
2555 /* Handling file windows is generic. */
2556 #define _bfd_ecoff_get_section_contents_in_window \
2557 _bfd_generic_get_section_contents_in_window
2559 /* Relaxing sections is MIPS specific. */
2560 #define _bfd_ecoff_bfd_relax_section mips_relax_section
2562 /* GC of sections is not done. */
2563 #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
2565 /* Merging of sections is not done. */
2566 #define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
2568 #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
2570 extern const bfd_target ecoff_big_vec;
2572 const bfd_target ecoff_little_vec =
2574 "ecoff-littlemips", /* name */
2575 bfd_target_ecoff_flavour,
2576 BFD_ENDIAN_LITTLE, /* data byte order is little */
2577 BFD_ENDIAN_LITTLE, /* header byte order is little */
2579 (HAS_RELOC | EXEC_P | /* object flags */
2580 HAS_LINENO | HAS_DEBUG |
2581 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
2583 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
2584 0, /* leading underscore */
2585 ' ', /* ar_pad_char */
2586 15, /* ar_max_namelen */
2587 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2588 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2589 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
2590 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2591 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2592 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
2594 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
2595 _bfd_ecoff_archive_p, _bfd_dummy_target},
2596 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
2597 _bfd_generic_mkarchive, bfd_false},
2598 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
2599 _bfd_write_archive_contents, bfd_false},
2601 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
2602 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
2603 BFD_JUMP_TABLE_CORE (_bfd_nocore),
2604 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
2605 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
2606 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
2607 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
2608 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
2609 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2611 & ecoff_big_vec,
2613 (PTR) &mips_ecoff_backend_data
2616 const bfd_target ecoff_big_vec =
2618 "ecoff-bigmips", /* name */
2619 bfd_target_ecoff_flavour,
2620 BFD_ENDIAN_BIG, /* data byte order is big */
2621 BFD_ENDIAN_BIG, /* header byte order is big */
2623 (HAS_RELOC | EXEC_P | /* object flags */
2624 HAS_LINENO | HAS_DEBUG |
2625 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
2627 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
2628 0, /* leading underscore */
2629 ' ', /* ar_pad_char */
2630 15, /* ar_max_namelen */
2631 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2632 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2633 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
2634 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2635 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2636 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
2637 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
2638 _bfd_ecoff_archive_p, _bfd_dummy_target},
2639 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
2640 _bfd_generic_mkarchive, bfd_false},
2641 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
2642 _bfd_write_archive_contents, bfd_false},
2644 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
2645 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
2646 BFD_JUMP_TABLE_CORE (_bfd_nocore),
2647 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
2648 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
2649 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
2650 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
2651 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
2652 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2654 & ecoff_little_vec,
2656 (PTR) &mips_ecoff_backend_data
2659 const bfd_target ecoff_biglittle_vec =
2661 "ecoff-biglittlemips", /* name */
2662 bfd_target_ecoff_flavour,
2663 BFD_ENDIAN_LITTLE, /* data byte order is little */
2664 BFD_ENDIAN_BIG, /* header byte order is big */
2666 (HAS_RELOC | EXEC_P | /* object flags */
2667 HAS_LINENO | HAS_DEBUG |
2668 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
2670 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
2671 0, /* leading underscore */
2672 ' ', /* ar_pad_char */
2673 15, /* ar_max_namelen */
2674 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2675 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2676 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
2677 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2678 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2679 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
2681 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
2682 _bfd_ecoff_archive_p, _bfd_dummy_target},
2683 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
2684 _bfd_generic_mkarchive, bfd_false},
2685 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
2686 _bfd_write_archive_contents, bfd_false},
2688 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
2689 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
2690 BFD_JUMP_TABLE_CORE (_bfd_nocore),
2691 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
2692 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
2693 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
2694 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
2695 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
2696 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2698 NULL,
2700 (PTR) &mips_ecoff_backend_data