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