* targets.c (bfd_target): Rearranged fields in target vector.
[deliverable/binutils-gdb.git] / bfd / coff-mips.c
CommitLineData
1f29e30b 1/* BFD back-end for MIPS Extended-Coff files.
f6409552 2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
8fa0d3a0 3 Original version by Per Bothner.
f6409552 4 Full support added by Ian Lance Taylor, ian@cygnus.com.
1327fb29 5
68b70212 6This file is part of BFD, the Binary File Descriptor library.
23b0b558 7
68b70212 8This program is free software; you can redistribute it and/or modify
23b0b558 9it under the terms of the GNU General Public License as published by
68b70212
JG
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
23b0b558 12
68b70212 13This program is distributed in the hope that it will be useful,
23b0b558
JG
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
68b70212
JG
19along with this program; if not, write to the Free Software
20Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
1327fb29 21
23b0b558 22#include "bfd.h"
dd4646ca 23#include "sysdep.h"
4991ebb9 24#include "bfdlink.h"
1327fb29 25#include "libbfd.h"
dae31cf5
ILT
26#include "coff/internal.h"
27#include "coff/sym.h"
28#include "coff/symconst.h"
29#include "coff/ecoff.h"
30#include "coff/mips.h"
31#include "libcoff.h"
32#include "libecoff.h"
33\f
34/* Prototypes for static functions. */
c3fe0c41 35
dae31cf5 36static boolean mips_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr));
dae31cf5
ILT
37static void mips_ecoff_swap_reloc_in PARAMS ((bfd *, PTR,
38 struct internal_reloc *));
39static void mips_ecoff_swap_reloc_out PARAMS ((bfd *,
40 const struct internal_reloc *,
41 PTR));
5fa2aaa2
ILT
42static void mips_adjust_reloc_in PARAMS ((bfd *,
43 const struct internal_reloc *,
44 arelent *));
45static void mips_adjust_reloc_out PARAMS ((bfd *, const arelent *,
46 struct internal_reloc *));
23f44e6f
ILT
47static bfd_reloc_status_type mips_generic_reloc PARAMS ((bfd *abfd,
48 arelent *reloc,
49 asymbol *symbol,
50 PTR data,
51 asection *section,
4991ebb9
ILT
52 bfd *output_bfd,
53 char **error));
23f44e6f
ILT
54static bfd_reloc_status_type mips_refhi_reloc PARAMS ((bfd *abfd,
55 arelent *reloc,
56 asymbol *symbol,
57 PTR data,
58 asection *section,
4991ebb9
ILT
59 bfd *output_bfd,
60 char **error));
23f44e6f
ILT
61static bfd_reloc_status_type mips_reflo_reloc PARAMS ((bfd *abfd,
62 arelent *reloc,
63 asymbol *symbol,
64 PTR data,
65 asection *section,
4991ebb9
ILT
66 bfd *output_bfd,
67 char **error));
23f44e6f
ILT
68static bfd_reloc_status_type mips_gprel_reloc PARAMS ((bfd *abfd,
69 arelent *reloc,
70 asymbol *symbol,
71 PTR data,
72 asection *section,
4991ebb9
ILT
73 bfd *output_bfd,
74 char **error));
75static void mips_relocate_refhi PARAMS ((struct internal_reloc *refhi,
76 struct internal_reloc *reflo,
77 bfd *input_bfd,
78 asection *input_section,
79 bfd_byte *contents,
a3a33af3 80 size_t adjust,
4991ebb9
ILT
81 bfd_vma relocation));
82static boolean mips_relocate_section PARAMS ((bfd *, struct bfd_link_info *,
83 bfd *, asection *,
84 bfd_byte *, PTR));
a3a33af3
ILT
85static boolean mips_relax_section PARAMS ((bfd *, asection *,
86 struct bfd_link_info *,
87 boolean *));
88static boolean mips_relax_pcrel16 PARAMS ((struct bfd_link_info *, bfd *,
89 asection *,
90 struct ecoff_link_hash_entry *,
91 bfd_byte *, bfd_vma));
dae31cf5 92\f
dae31cf5
ILT
93/* ECOFF has COFF sections, but the debugging information is stored in
94 a completely different format. ECOFF targets use some of the
95 swapping routines from coffswap.h, and some of the generic COFF
96 routines in coffgen.c, but, unlike the real COFF targets, do not
97 use coffcode.h itself.
8fa0d3a0 98
dae31cf5 99 Get the generic COFF swapping routines, except for the reloc,
23f44e6f 100 symbol, and lineno ones. Give them ECOFF names. */
dae31cf5
ILT
101#define MIPSECOFF
102#define NO_COFF_RELOCS
103#define NO_COFF_SYMBOLS
104#define NO_COFF_LINENOS
105#define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in
106#define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out
107#define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in
108#define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out
109#define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in
110#define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out
111#include "coffswap.h"
8fa0d3a0 112
dae31cf5
ILT
113/* Get the ECOFF swapping routines. */
114#define ECOFF_32
115#include "ecoffswap.h"
116\f
23f44e6f 117/* How to process the various relocs types. */
dae31cf5 118
23f44e6f 119static reloc_howto_type mips_howto_table[] =
dae31cf5 120{
23f44e6f
ILT
121 /* Reloc type 0 is ignored. The reloc reading code ensures that
122 this is a reference to the .abs section, which will cause
123 bfd_perform_relocation to do nothing. */
124 HOWTO (MIPS_R_IGNORE, /* type */
125 0, /* rightshift */
126 0, /* size (0 = byte, 1 = short, 2 = long) */
127 8, /* bitsize */
128 false, /* pc_relative */
129 0, /* bitpos */
130 complain_overflow_dont, /* complain_on_overflow */
131 0, /* special_function */
132 "IGNORE", /* name */
133 false, /* partial_inplace */
134 0, /* src_mask */
135 0, /* dst_mask */
136 false), /* pcrel_offset */
137
138 /* A 16 bit reference to a symbol, normally from a data section. */
139 HOWTO (MIPS_R_REFHALF, /* type */
140 0, /* rightshift */
141 1, /* size (0 = byte, 1 = short, 2 = long) */
142 16, /* bitsize */
143 false, /* pc_relative */
144 0, /* bitpos */
145 complain_overflow_bitfield, /* complain_on_overflow */
146 mips_generic_reloc, /* special_function */
147 "REFHALF", /* name */
148 true, /* partial_inplace */
149 0xffff, /* src_mask */
150 0xffff, /* dst_mask */
151 false), /* pcrel_offset */
152
153 /* A 32 bit reference to a symbol, normally from a data section. */
154 HOWTO (MIPS_R_REFWORD, /* type */
155 0, /* rightshift */
156 2, /* size (0 = byte, 1 = short, 2 = long) */
157 32, /* bitsize */
158 false, /* pc_relative */
159 0, /* bitpos */
160 complain_overflow_bitfield, /* complain_on_overflow */
161 mips_generic_reloc, /* special_function */
162 "REFWORD", /* name */
163 true, /* partial_inplace */
164 0xffffffff, /* src_mask */
165 0xffffffff, /* dst_mask */
166 false), /* pcrel_offset */
167
168 /* A 26 bit absolute jump address. */
169 HOWTO (MIPS_R_JMPADDR, /* type */
170 2, /* rightshift */
171 2, /* size (0 = byte, 1 = short, 2 = long) */
172 26, /* bitsize */
173 false, /* pc_relative */
174 0, /* bitpos */
5fa2aaa2
ILT
175 complain_overflow_dont, /* complain_on_overflow */
176 /* This needs complex overflow
177 detection, because the upper four
178 bits must match the PC. */
23f44e6f
ILT
179 mips_generic_reloc, /* special_function */
180 "JMPADDR", /* name */
181 true, /* partial_inplace */
182 0x3ffffff, /* src_mask */
183 0x3ffffff, /* dst_mask */
184 false), /* pcrel_offset */
185
186 /* The high 16 bits of a symbol value. Handled by the function
187 mips_refhi_reloc. */
188 HOWTO (MIPS_R_REFHI, /* type */
189 16, /* rightshift */
190 2, /* size (0 = byte, 1 = short, 2 = long) */
191 16, /* bitsize */
192 false, /* pc_relative */
193 0, /* bitpos */
194 complain_overflow_bitfield, /* complain_on_overflow */
195 mips_refhi_reloc, /* special_function */
196 "REFHI", /* name */
197 true, /* partial_inplace */
198 0xffff, /* src_mask */
199 0xffff, /* dst_mask */
200 false), /* pcrel_offset */
201
202 /* The low 16 bits of a symbol value. */
203 HOWTO (MIPS_R_REFLO, /* type */
204 0, /* rightshift */
205 2, /* size (0 = byte, 1 = short, 2 = long) */
206 16, /* bitsize */
207 false, /* pc_relative */
208 0, /* bitpos */
209 complain_overflow_dont, /* complain_on_overflow */
210 mips_reflo_reloc, /* special_function */
211 "REFLO", /* name */
212 true, /* partial_inplace */
213 0xffff, /* src_mask */
214 0xffff, /* dst_mask */
215 false), /* pcrel_offset */
216
217 /* A reference to an offset from the gp register. Handled by the
218 function mips_gprel_reloc. */
219 HOWTO (MIPS_R_GPREL, /* type */
220 0, /* rightshift */
221 2, /* size (0 = byte, 1 = short, 2 = long) */
222 16, /* bitsize */
223 false, /* pc_relative */
224 0, /* bitpos */
225 complain_overflow_signed, /* complain_on_overflow */
226 mips_gprel_reloc, /* special_function */
227 "GPREL", /* name */
228 true, /* partial_inplace */
229 0xffff, /* src_mask */
230 0xffff, /* dst_mask */
231 false), /* pcrel_offset */
232
233 /* A reference to a literal using an offset from the gp register.
234 Handled by the function mips_gprel_reloc. */
235 HOWTO (MIPS_R_LITERAL, /* type */
236 0, /* rightshift */
237 2, /* size (0 = byte, 1 = short, 2 = long) */
238 16, /* bitsize */
239 false, /* pc_relative */
240 0, /* bitpos */
241 complain_overflow_signed, /* complain_on_overflow */
242 mips_gprel_reloc, /* special_function */
243 "LITERAL", /* name */
244 true, /* partial_inplace */
245 0xffff, /* src_mask */
246 0xffff, /* dst_mask */
a3a33af3
ILT
247 false), /* pcrel_offset */
248
249 /* This reloc is a Cygnus extension used when generating position
250 independent code for embedded systems. It represents a 16 bit PC
251 relative reloc rightshifted twice as used in the MIPS branch
252 instructions. */
253 HOWTO (MIPS_R_PCREL16, /* type */
254 2, /* rightshift */
255 2, /* size (0 = byte, 1 = short, 2 = long) */
256 16, /* bitsize */
257 true, /* pc_relative */
258 0, /* bitpos */
259 complain_overflow_signed, /* complain_on_overflow */
260 mips_generic_reloc, /* special_function */
261 "PCREL16", /* name */
262 true, /* partial_inplace */
263 0xffff, /* src_mask */
264 0xffff, /* dst_mask */
265 true) /* pcrel_offset */
dae31cf5 266};
23f44e6f
ILT
267
268#define MIPS_HOWTO_COUNT \
269 (sizeof mips_howto_table / sizeof mips_howto_table[0])
a3a33af3
ILT
270
271/* When the linker is doing relaxing, it may change a external PCREL16
272 reloc. This typically represents an instruction like
273 bal foo
274 We change it to
275 .set noreorder
276 bal $L1
277 lui $at,%hi(foo - $L1)
278 $L1:
279 addiu $at,%lo(foo - $L1)
280 addu $at,$at,$31
281 jalr $at
282 PCREL16_EXPANSION_ADJUSTMENT is the number of bytes this changes the
283 instruction by. */
284
285#define PCREL16_EXPANSION_ADJUSTMENT (4 * 4)
dae31cf5
ILT
286\f
287/* See whether the magic number matches. */
8fa0d3a0 288
dae31cf5
ILT
289static boolean
290mips_ecoff_bad_format_hook (abfd, filehdr)
291 bfd *abfd;
292 PTR filehdr;
293{
294 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
8fa0d3a0 295
5fa2aaa2
ILT
296 switch (internal_f->f_magic)
297 {
298 case MIPS_MAGIC_1:
299 /* I don't know what endianness this implies. */
300 return true;
c3fe0c41 301
5fa2aaa2
ILT
302 case MIPS_MAGIC_BIG:
303 case MIPS_MAGIC_BIG2:
304 case MIPS_MAGIC_BIG3:
305 return abfd->xvec->byteorder_big_p;
c3fe0c41 306
5fa2aaa2
ILT
307 case MIPS_MAGIC_LITTLE:
308 case MIPS_MAGIC_LITTLE2:
309 case MIPS_MAGIC_LITTLE3:
310 return abfd->xvec->byteorder_big_p == false;
23ba15b7 311
5fa2aaa2
ILT
312 default:
313 return false;
c3fe0c41 314 }
dae31cf5
ILT
315}
316\f
317/* Reloc handling. MIPS ECOFF relocs are packed into 8 bytes in
318 external form. They use a bit which indicates whether the symbol
319 is external. */
23ba15b7 320
dae31cf5 321/* Swap a reloc in. */
23ba15b7 322
dae31cf5
ILT
323static void
324mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
325 bfd *abfd;
326 PTR ext_ptr;
327 struct internal_reloc *intern;
328{
329 const RELOC *ext = (RELOC *) ext_ptr;
23ba15b7 330
dae31cf5
ILT
331 intern->r_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_vaddr);
332 if (abfd->xvec->header_byteorder_big_p != false)
333 {
334 intern->r_symndx = (((int) ext->r_bits[0]
335 << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
336 | ((int) ext->r_bits[1]
337 << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
338 | ((int) ext->r_bits[2]
339 << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
340 intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
341 >> RELOC_BITS3_TYPE_SH_BIG);
342 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
23ba15b7 343 }
dae31cf5 344 else
23ba15b7 345 {
dae31cf5
ILT
346 intern->r_symndx = (((int) ext->r_bits[0]
347 << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
348 | ((int) ext->r_bits[1]
349 << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
350 | ((int) ext->r_bits[2]
351 << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
352 intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
353 >> RELOC_BITS3_TYPE_SH_LITTLE);
354 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
23ba15b7 355 }
c3fe0c41
ILT
356}
357
dae31cf5 358/* Swap a reloc out. */
c3fe0c41 359
dae31cf5
ILT
360static void
361mips_ecoff_swap_reloc_out (abfd, intern, dst)
f6409552 362 bfd *abfd;
dae31cf5
ILT
363 const struct internal_reloc *intern;
364 PTR dst;
c3fe0c41 365{
dae31cf5 366 RELOC *ext = (RELOC *) dst;
c3fe0c41 367
5fa2aaa2
ILT
368 BFD_ASSERT (intern->r_extern
369 || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
370
dae31cf5
ILT
371 bfd_h_put_32 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr);
372 if (abfd->xvec->header_byteorder_big_p != false)
c3fe0c41 373 {
dae31cf5
ILT
374 ext->r_bits[0] = intern->r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
375 ext->r_bits[1] = intern->r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
376 ext->r_bits[2] = intern->r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
377 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
378 & RELOC_BITS3_TYPE_BIG)
379 | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
c3fe0c41 380 }
dae31cf5 381 else
c3fe0c41 382 {
dae31cf5
ILT
383 ext->r_bits[0] = intern->r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
384 ext->r_bits[1] = intern->r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
385 ext->r_bits[2] = intern->r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
386 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
387 & RELOC_BITS3_TYPE_LITTLE)
388 | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
c3fe0c41 389 }
c3fe0c41 390}
23f44e6f
ILT
391
392/* Finish canonicalizing a reloc. Part of this is generic to all
393 ECOFF targets, and that part is in ecoff.c. The rest is done in
394 this backend routine. It must fill in the howto field. */
395
396static void
5fa2aaa2 397mips_adjust_reloc_in (abfd, intern, rptr)
23f44e6f 398 bfd *abfd;
5fa2aaa2 399 const struct internal_reloc *intern;
23f44e6f
ILT
400 arelent *rptr;
401{
a3a33af3 402 if (intern->r_type > MIPS_R_PCREL16)
23f44e6f
ILT
403 abort ();
404
405 if (! intern->r_extern
406 && (intern->r_type == MIPS_R_GPREL
407 || intern->r_type == MIPS_R_LITERAL))
408 rptr->addend += ecoff_data (abfd)->gp;
409
410 /* If the type is MIPS_R_IGNORE, make sure this is a reference to
411 the absolute section so that the reloc is ignored. */
412 if (intern->r_type == MIPS_R_IGNORE)
413 rptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
414
415 rptr->howto = &mips_howto_table[intern->r_type];
416}
417
5fa2aaa2
ILT
418/* Make any adjustments needed to a reloc before writing it out. None
419 are needed for MIPS. */
420
421static void
4991ebb9 422mips_adjust_reloc_out (abfd, rel, intern)
5fa2aaa2
ILT
423 bfd *abfd;
424 const arelent *rel;
425 struct internal_reloc *intern;
426{
427}
428
23f44e6f
ILT
429/* ECOFF relocs are either against external symbols, or against
430 sections. If we are producing relocateable output, and the reloc
431 is against an external symbol, and nothing has given us any
432 additional addend, the resulting reloc will also be against the
433 same symbol. In such a case, we don't want to change anything
434 about the way the reloc is handled, since it will all be done at
435 final link time. Rather than put special case code into
436 bfd_perform_relocation, all the reloc types use this howto
437 function. It just short circuits the reloc if producing
438 relocateable output against an external symbol. */
439
440static bfd_reloc_status_type
441mips_generic_reloc (abfd,
442 reloc_entry,
443 symbol,
444 data,
445 input_section,
4991ebb9
ILT
446 output_bfd,
447 error_message)
23f44e6f
ILT
448 bfd *abfd;
449 arelent *reloc_entry;
450 asymbol *symbol;
451 PTR data;
452 asection *input_section;
453 bfd *output_bfd;
4991ebb9 454 char **error_message;
23f44e6f
ILT
455{
456 if (output_bfd != (bfd *) NULL
457 && (symbol->flags & BSF_SECTION_SYM) == 0
458 && reloc_entry->addend == 0)
459 {
460 reloc_entry->address += input_section->output_offset;
461 return bfd_reloc_ok;
462 }
463
464 return bfd_reloc_continue;
465}
466
467/* Do a REFHI relocation. This has to be done in combination with a
468 REFLO reloc, because there is a carry from the REFLO to the REFHI.
469 Here we just save the information we need; we do the actual
470 relocation when we see the REFLO. MIPS ECOFF requires that the
471 REFLO immediately follow the REFHI, so this ought to work. */
472
473static bfd_byte *mips_refhi_addr;
474static bfd_vma mips_refhi_addend;
475
476static bfd_reloc_status_type
477mips_refhi_reloc (abfd,
478 reloc_entry,
479 symbol,
480 data,
481 input_section,
4991ebb9
ILT
482 output_bfd,
483 error_message)
23f44e6f
ILT
484 bfd *abfd;
485 arelent *reloc_entry;
486 asymbol *symbol;
487 PTR data;
488 asection *input_section;
489 bfd *output_bfd;
4991ebb9 490 char **error_message;
23f44e6f
ILT
491{
492 bfd_reloc_status_type ret;
493 bfd_vma relocation;
494
495 /* If we're relocating, and this an external symbol, we don't want
496 to change anything. */
497 if (output_bfd != (bfd *) NULL
498 && (symbol->flags & BSF_SECTION_SYM) == 0
499 && reloc_entry->addend == 0)
500 {
501 reloc_entry->address += input_section->output_offset;
502 return bfd_reloc_ok;
503 }
504
505 ret = bfd_reloc_ok;
506 if (symbol->section == &bfd_und_section
507 && output_bfd == (bfd *) NULL)
508 ret = bfd_reloc_undefined;
509
510 if (bfd_is_com_section (symbol->section))
511 relocation = 0;
512 else
513 relocation = symbol->value;
514
515 relocation += symbol->section->output_section->vma;
516 relocation += symbol->section->output_offset;
517 relocation += reloc_entry->addend;
518
519 if (reloc_entry->address > input_section->_cooked_size)
520 return bfd_reloc_outofrange;
521
522 /* Save the information, and let REFLO do the actual relocation. */
523 mips_refhi_addr = (bfd_byte *) data + reloc_entry->address;
524 mips_refhi_addend = relocation;
525
526 if (output_bfd != (bfd *) NULL)
527 reloc_entry->address += input_section->output_offset;
528
529 return ret;
530}
531
532/* Do a REFLO relocation. This is a straightforward 16 bit inplace
533 relocation; this function exists in order to do the REFHI
534 relocation described above. */
535
536static bfd_reloc_status_type
537mips_reflo_reloc (abfd,
538 reloc_entry,
539 symbol,
540 data,
541 input_section,
4991ebb9
ILT
542 output_bfd,
543 error_message)
23f44e6f
ILT
544 bfd *abfd;
545 arelent *reloc_entry;
546 asymbol *symbol;
547 PTR data;
548 asection *input_section;
549 bfd *output_bfd;
4991ebb9 550 char **error_message;
23f44e6f
ILT
551{
552 if (mips_refhi_addr != (bfd_byte *) NULL)
553 {
554 unsigned long insn;
555 unsigned long val;
556 unsigned long vallo;
557
558 /* Do the REFHI relocation. Note that we actually don't need to
559 know anything about the REFLO itself, except where to find
560 the low 16 bits of the addend needed by the REFHI. */
561 insn = bfd_get_32 (abfd, mips_refhi_addr);
562 vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
563 & 0xffff);
564 val = ((insn & 0xffff) << 16) + vallo;
565 val += mips_refhi_addend;
566
567 /* The low order 16 bits are always treated as a signed value.
568 Therefore, a negative value in the low order bits requires an
569 adjustment in the high order bits. We need to make this
570 adjustment in two ways: once for the bits we took from the
571 data, and once for the bits we are putting back in to the
572 data. */
573 if ((vallo & 0x8000) != 0)
574 val -= 0x10000;
575 if ((val & 0x8000) != 0)
576 val += 0x10000;
577
578 insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
579 bfd_put_32 (abfd, insn, mips_refhi_addr);
580
581 mips_refhi_addr = (bfd_byte *) NULL;
582 }
583
584 /* Now do the REFLO reloc in the usual way. */
585 return mips_generic_reloc (abfd, reloc_entry, symbol, data,
4991ebb9 586 input_section, output_bfd, error_message);
23f44e6f
ILT
587}
588
589/* Do a GPREL relocation. This is a 16 bit value which must become
590 the offset from the gp register. */
591
592static bfd_reloc_status_type
593mips_gprel_reloc (abfd,
4991ebb9
ILT
594 reloc_entry,
595 symbol,
596 data,
597 input_section,
598 output_bfd,
599 error_message)
23f44e6f
ILT
600 bfd *abfd;
601 arelent *reloc_entry;
602 asymbol *symbol;
603 PTR data;
604 asection *input_section;
605 bfd *output_bfd;
4991ebb9 606 char **error_message;
23f44e6f
ILT
607{
608 boolean relocateable;
609 bfd_vma relocation;
610 unsigned long val;
611 unsigned long insn;
612
613 /* If we're relocating, and this is an external symbol with no
614 addend, we don't want to change anything. We will only have an
615 addend if this is a newly created reloc, not read from an ECOFF
616 file. */
617 if (output_bfd != (bfd *) NULL
618 && (symbol->flags & BSF_SECTION_SYM) == 0
619 && reloc_entry->addend == 0)
620 {
621 reloc_entry->address += input_section->output_offset;
622 return bfd_reloc_ok;
623 }
624
625 if (output_bfd != (bfd *) NULL)
626 relocateable = true;
627 else
628 {
629 relocateable = false;
630 output_bfd = symbol->section->output_section->owner;
631 }
632
633 if (symbol->section == &bfd_und_section
634 && relocateable == false)
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 relocateable output. */
642 if (ecoff_data (output_bfd)->gp == 0
643 && (relocateable == false
644 || (symbol->flags & BSF_SECTION_SYM) != 0))
645 {
646 if (relocateable != false)
647 {
648 /* Make up a value. */
649 ecoff_data (output_bfd)->gp =
650 symbol->section->output_section->vma + 0x4000;
651 }
652 else
653 {
654 unsigned int count;
655 asymbol **sym;
656 unsigned int i;
657
658 count = bfd_get_symcount (output_bfd);
659 sym = bfd_get_outsymbols (output_bfd);
660
661 if (sym == (asymbol **) NULL)
662 i = count;
663 else
664 {
665 for (i = 0; i < count; i++, sym++)
666 {
667 register CONST char *name;
668
669 name = bfd_asymbol_name (*sym);
670 if (*name == '_' && strcmp (name, "_gp") == 0)
671 {
672 ecoff_data (output_bfd)->gp = bfd_asymbol_value (*sym);
673 break;
674 }
675 }
676 }
677
678 if (i >= count)
679 {
680 /* Only get the error once. */
681 ecoff_data (output_bfd)->gp = 4;
4991ebb9
ILT
682 *error_message =
683 (char *) "GP relative relocation when _gp not defined";
23f44e6f
ILT
684 return bfd_reloc_dangerous;
685 }
686 }
687 }
688
689 if (bfd_is_com_section (symbol->section))
690 relocation = 0;
691 else
692 relocation = symbol->value;
693
694 relocation += symbol->section->output_section->vma;
695 relocation += symbol->section->output_offset;
696
697 if (reloc_entry->address > input_section->_cooked_size)
698 return bfd_reloc_outofrange;
699
700 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
701
702 /* Set val to the offset into the section or symbol. */
703 val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
704 if (val & 0x8000)
705 val -= 0x10000;
706
707 /* Adjust val for the final section location and GP value. If we
708 are producing relocateable output, we don't want to do this for
709 an external symbol. */
710 if (relocateable == false
711 || (symbol->flags & BSF_SECTION_SYM) != 0)
712 val += relocation - ecoff_data (output_bfd)->gp;
713
714 insn = (insn &~ 0xffff) | (val & 0xffff);
715 bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
716
717 if (relocateable != false)
718 reloc_entry->address += input_section->output_offset;
719
720 /* Make sure it fit in 16 bits. */
721 if (val >= 0x8000 && val < 0xffff8000)
4991ebb9 722 return bfd_reloc_overflow;
23f44e6f
ILT
723
724 return bfd_reloc_ok;
725}
726
727/* Get the howto structure for a generic reloc type. */
728
729static CONST struct reloc_howto_struct *
730mips_bfd_reloc_type_lookup (abfd, code)
731 bfd *abfd;
732 bfd_reloc_code_real_type code;
733{
734 int mips_type;
735
736 switch (code)
737 {
738 case BFD_RELOC_16:
739 mips_type = MIPS_R_REFHALF;
740 break;
741 case BFD_RELOC_32:
f1cca647 742 case BFD_RELOC_CTOR:
23f44e6f
ILT
743 mips_type = MIPS_R_REFWORD;
744 break;
745 case BFD_RELOC_MIPS_JMP:
746 mips_type = MIPS_R_JMPADDR;
747 break;
748 case BFD_RELOC_HI16_S:
749 mips_type = MIPS_R_REFHI;
750 break;
751 case BFD_RELOC_LO16:
752 mips_type = MIPS_R_REFLO;
753 break;
754 case BFD_RELOC_MIPS_GPREL:
755 mips_type = MIPS_R_GPREL;
756 break;
4991ebb9
ILT
757 case BFD_RELOC_MIPS_LITERAL:
758 mips_type = MIPS_R_LITERAL;
759 break;
a3a33af3
ILT
760 case BFD_RELOC_16_PCREL_S2:
761 mips_type = MIPS_R_PCREL16;
762 break;
23f44e6f
ILT
763 default:
764 return (CONST struct reloc_howto_struct *) NULL;
765 }
766
767 return &mips_howto_table[mips_type];
768}
c3fe0c41 769\f
4991ebb9
ILT
770/* A helper routine for mips_relocate_section which handles the REFHI
771 relocation. The REFHI relocation must be followed by a REFLO
772 relocation, and the addend used is formed from the addends of both
773 instructions. */
de17306e 774
4991ebb9
ILT
775static void
776mips_relocate_refhi (refhi, reflo, input_bfd, input_section, contents,
a3a33af3 777 adjust, relocation)
4991ebb9
ILT
778 struct internal_reloc *refhi;
779 struct internal_reloc *reflo;
780 bfd *input_bfd;
781 asection *input_section;
782 bfd_byte *contents;
a3a33af3 783 size_t adjust;
4991ebb9 784 bfd_vma relocation;
de17306e 785{
4991ebb9
ILT
786 unsigned long insn;
787 unsigned long val;
788 unsigned long vallo;
789
790 insn = bfd_get_32 (input_bfd,
a3a33af3 791 contents + adjust + refhi->r_vaddr - input_section->vma);
4991ebb9 792 vallo = (bfd_get_32 (input_bfd,
a3a33af3 793 contents + adjust + reflo->r_vaddr - input_section->vma)
4991ebb9
ILT
794 & 0xffff);
795 val = ((insn & 0xffff) << 16) + vallo;
796 val += relocation;
797
798 /* The low order 16 bits are always treated as a signed value.
799 Therefore, a negative value in the low order bits requires an
800 adjustment in the high order bits. We need to make this
801 adjustment in two ways: once for the bits we took from the data,
802 and once for the bits we are putting back in to the data. */
803 if ((vallo & 0x8000) != 0)
804 val -= 0x10000;
805 if ((val & 0x8000) != 0)
806 val += 0x10000;
de17306e 807
4991ebb9
ILT
808 insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
809 bfd_put_32 (input_bfd, (bfd_vma) insn,
a3a33af3 810 contents + adjust + refhi->r_vaddr - input_section->vma);
4991ebb9 811}
de17306e 812
4991ebb9 813/* Relocate a section while linking a MIPS ECOFF file. */
de17306e 814
4991ebb9
ILT
815static boolean
816mips_relocate_section (output_bfd, info, input_bfd, input_section,
817 contents, external_relocs)
818 bfd *output_bfd;
819 struct bfd_link_info *info;
820 bfd *input_bfd;
821 asection *input_section;
822 bfd_byte *contents;
823 PTR external_relocs;
824{
825 asection **symndx_to_section;
826 struct ecoff_link_hash_entry **sym_hashes;
827 bfd_vma gp;
828 boolean gp_undefined;
a3a33af3
ILT
829 size_t adjust;
830 long *offsets;
4991ebb9
ILT
831 struct external_reloc *ext_rel;
832 struct external_reloc *ext_rel_end;
a3a33af3 833 unsigned int i;
4991ebb9 834 boolean got_reflo;
a3a33af3 835 struct internal_reloc reflo_int_rel;
4991ebb9
ILT
836
837 BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
838 == output_bfd->xvec->header_byteorder_big_p);
839
840 /* We keep a table mapping the symndx found in an internal reloc to
841 the appropriate section. This is faster than looking up the
842 section by name each time. */
843 symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
844 if (symndx_to_section == (asection **) NULL)
845 {
846 symndx_to_section = ((asection **)
847 bfd_alloc (input_bfd,
848 (NUM_RELOC_SECTIONS
849 * sizeof (asection *))));
9783e04a
DM
850 if (!symndx_to_section)
851 {
f1cca647 852 bfd_set_error (bfd_error_no_memory);
9783e04a
DM
853 return false;
854 }
4991ebb9
ILT
855
856 symndx_to_section[RELOC_SECTION_NONE] = NULL;
857 symndx_to_section[RELOC_SECTION_TEXT] =
858 bfd_get_section_by_name (input_bfd, ".text");
859 symndx_to_section[RELOC_SECTION_RDATA] =
860 bfd_get_section_by_name (input_bfd, ".rdata");
861 symndx_to_section[RELOC_SECTION_DATA] =
862 bfd_get_section_by_name (input_bfd, ".data");
863 symndx_to_section[RELOC_SECTION_SDATA] =
864 bfd_get_section_by_name (input_bfd, ".sdata");
865 symndx_to_section[RELOC_SECTION_SBSS] =
866 bfd_get_section_by_name (input_bfd, ".sbss");
867 symndx_to_section[RELOC_SECTION_BSS] =
868 bfd_get_section_by_name (input_bfd, ".bss");
869 symndx_to_section[RELOC_SECTION_INIT] =
870 bfd_get_section_by_name (input_bfd, ".init");
871 symndx_to_section[RELOC_SECTION_LIT8] =
872 bfd_get_section_by_name (input_bfd, ".lit8");
873 symndx_to_section[RELOC_SECTION_LIT4] =
874 bfd_get_section_by_name (input_bfd, ".lit4");
875 symndx_to_section[RELOC_SECTION_XDATA] = NULL;
876 symndx_to_section[RELOC_SECTION_PDATA] = NULL;
877 symndx_to_section[RELOC_SECTION_FINI] =
878 bfd_get_section_by_name (input_bfd, ".fini");
879 symndx_to_section[RELOC_SECTION_LITA] = NULL;
880 symndx_to_section[RELOC_SECTION_ABS] = NULL;
881
882 ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
883 }
de17306e 884
4991ebb9 885 sym_hashes = ecoff_data (input_bfd)->sym_hashes;
de17306e 886
4991ebb9
ILT
887 gp = ecoff_data (output_bfd)->gp;
888 if (gp == 0)
889 gp_undefined = true;
890 else
891 gp_undefined = false;
de17306e 892
4991ebb9 893 got_reflo = false;
de17306e 894
a3a33af3
ILT
895 adjust = 0;
896
897 if (ecoff_section_data (input_bfd, input_section) == NULL)
898 offsets = NULL;
899 else
900 offsets = ecoff_section_data (input_bfd, input_section)->offsets;
901
4991ebb9
ILT
902 ext_rel = (struct external_reloc *) external_relocs;
903 ext_rel_end = ext_rel + input_section->reloc_count;
a3a33af3 904 for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
4991ebb9
ILT
905 {
906 struct internal_reloc int_rel;
4991ebb9
ILT
907 bfd_vma addend;
908 reloc_howto_type *howto;
909 struct ecoff_link_hash_entry *h = NULL;
910 asection *s = NULL;
911 bfd_vma relocation;
912 bfd_reloc_status_type r;
913
914 if (! got_reflo)
915 mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
916 else
917 {
918 int_rel = reflo_int_rel;
919 got_reflo = false;
920 }
de17306e 921
4991ebb9
ILT
922 BFD_ASSERT (int_rel.r_type
923 < sizeof mips_howto_table / sizeof mips_howto_table[0]);
de17306e 924
4991ebb9
ILT
925 /* The REFHI reloc requires special handling. It must be
926 followed by a REFLO reloc, and the addend is formed from both
927 fields. */
928 if (int_rel.r_type == MIPS_R_REFHI)
929 {
930 BFD_ASSERT ((ext_rel + 1) < ext_rel_end);
931 mips_ecoff_swap_reloc_in (input_bfd, (PTR) (ext_rel + 1),
932 &reflo_int_rel);
933 BFD_ASSERT (reflo_int_rel.r_type == MIPS_R_REFLO
934 && int_rel.r_extern == reflo_int_rel.r_extern
935 && int_rel.r_symndx == reflo_int_rel.r_symndx);
936 got_reflo = true;
937 }
de17306e 938
4991ebb9 939 howto = &mips_howto_table[int_rel.r_type];
de17306e 940
4991ebb9
ILT
941 if (int_rel.r_extern)
942 {
943 h = sym_hashes[int_rel.r_symndx];
944 /* If h is NULL, that means that there is a reloc against an
945 external symbol which we thought was just a debugging
946 symbol. This should not happen. */
947 if (h == (struct ecoff_link_hash_entry *) NULL)
948 abort ();
949 }
950 else
951 {
952 if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
953 s = NULL;
954 else
955 s = symndx_to_section[int_rel.r_symndx];
de17306e 956
4991ebb9
ILT
957 if (s == (asection *) NULL)
958 abort ();
959 }
de17306e 960
4991ebb9
ILT
961 /* The GPREL reloc uses an addend: the difference in the GP
962 values. */
f1cca647
ILT
963 if (int_rel.r_type != MIPS_R_GPREL
964 && int_rel.r_type != MIPS_R_LITERAL)
4991ebb9
ILT
965 addend = 0;
966 else
de17306e 967 {
4991ebb9
ILT
968 if (gp_undefined)
969 {
970 if (! ((*info->callbacks->reloc_dangerous)
971 (info, "GP relative relocation when GP not defined",
972 input_bfd, input_section,
973 int_rel.r_vaddr - input_section->vma)))
974 return false;
975 /* Only give the error once per link. */
976 ecoff_data (output_bfd)->gp = gp = 4;
977 gp_undefined = false;
978 }
979 if (! int_rel.r_extern)
980 {
981 /* This is a relocation against a section. The current
982 addend in the instruction is the difference between
983 INPUT_SECTION->vma and the GP value of INPUT_BFD. We
984 must change this to be the difference between the
985 final definition (which will end up in RELOCATION)
986 and the GP value of OUTPUT_BFD (which is in GP). */
987 addend = ecoff_data (input_bfd)->gp - gp;
988 }
989 else if (! info->relocateable
990 || h->root.type == bfd_link_hash_defined)
991 {
992 /* This is a relocation against an undefined or common
993 symbol. The current addend in the instruction is
994 simply the desired offset into the symbol (normally
995 zero). We are going to change this into a relocation
996 against a defined symbol, so we want the instruction
997 to hold the difference between the final definition
998 of the symbol (which will end up in RELOCATION) and
999 the GP value of OUTPUT_BFD (which is in GP). */
1000 addend = - gp;
1001 }
1002 else
1003 {
1004 /* This is a relocation against an undefined or common
1005 symbol. The current addend in the instruction is
1006 simply the desired offset into the symbol (normally
1007 zero). We are generating relocateable output, and we
1008 aren't going to define this symbol, so we just leave
1009 the instruction alone. */
1010 addend = 0;
1011 }
de17306e
ILT
1012 }
1013
a3a33af3
ILT
1014 /* If we are relaxing, mips_relax_section may have set
1015 offsets[i] to some value. A value of 1 means we must expand
1016 a PC relative branch into a multi-instruction of sequence,
1017 and any other value is an addend. */
1018 if (offsets != NULL
1019 && offsets[i] != 0)
1020 {
1021 BFD_ASSERT (! info->relocateable);
1022 BFD_ASSERT (int_rel.r_type == MIPS_R_PCREL16);
1023 if (offsets[i] != 1)
1024 {
1025 BFD_ASSERT (! int_rel.r_extern);
1026 addend += offsets[i];
1027 }
1028 else
1029 {
1030 bfd_byte *here;
1031
1032 BFD_ASSERT (int_rel.r_extern);
1033
1034 /* Move the rest of the instructions up. */
1035 here = (contents
1036 + adjust
1037 + int_rel.r_vaddr
1038 - input_section->vma);
1039 memmove (here + PCREL16_EXPANSION_ADJUSTMENT, here,
1040 (input_section->_raw_size
1041 - (int_rel.r_vaddr - input_section->vma)));
1042
1043 /* Generate the new instructions. */
1044 if (! mips_relax_pcrel16 (info, input_bfd, input_section,
1045 h, here,
1046 (input_section->output_section->vma
1047 + input_section->output_offset
1048 + (int_rel.r_vaddr
1049 - input_section->vma)
1050 + adjust)))
1051 return false;
1052
1053 /* We must adjust everything else up a notch. */
1054 adjust += PCREL16_EXPANSION_ADJUSTMENT;
1055
1056 /* mips_relax_pcrel16 handles all the details of this
1057 relocation. */
1058 continue;
1059 }
1060 }
1061
4991ebb9
ILT
1062 if (info->relocateable)
1063 {
1064 /* We are generating relocateable output, and must convert
1065 the existing reloc. */
1066 if (int_rel.r_extern)
1067 {
1068 if (h->root.type == bfd_link_hash_defined)
1069 {
4991ebb9 1070 const char *name;
de17306e 1071
4991ebb9
ILT
1072 /* This symbol is defined in the output. Convert
1073 the reloc from being against the symbol to being
1074 against the section. */
de17306e 1075
4991ebb9
ILT
1076 /* Clear the r_extern bit. */
1077 int_rel.r_extern = 0;
de17306e 1078
4991ebb9 1079 /* Compute a new r_symndx value. */
a3a33af3 1080 s = h->root.u.def.section;
4991ebb9 1081 name = bfd_get_section_name (output_bfd,
a3a33af3 1082 s->output_section);
de17306e 1083
4991ebb9
ILT
1084 int_rel.r_symndx = -1;
1085 switch (name[1])
1086 {
1087 case 'b':
1088 if (strcmp (name, ".bss") == 0)
1089 int_rel.r_symndx = RELOC_SECTION_BSS;
1090 break;
1091 case 'd':
1092 if (strcmp (name, ".data") == 0)
1093 int_rel.r_symndx = RELOC_SECTION_DATA;
1094 break;
1095 case 'f':
1096 if (strcmp (name, ".fini") == 0)
1097 int_rel.r_symndx = RELOC_SECTION_FINI;
1098 break;
1099 case 'i':
1100 if (strcmp (name, ".init") == 0)
1101 int_rel.r_symndx = RELOC_SECTION_INIT;
1102 break;
1103 case 'l':
1104 if (strcmp (name, ".lit8") == 0)
1105 int_rel.r_symndx = RELOC_SECTION_LIT8;
1106 else if (strcmp (name, ".lit4") == 0)
1107 int_rel.r_symndx = RELOC_SECTION_LIT4;
1108 break;
1109 case 'r':
1110 if (strcmp (name, ".rdata") == 0)
1111 int_rel.r_symndx = RELOC_SECTION_RDATA;
1112 break;
1113 case 's':
1114 if (strcmp (name, ".sdata") == 0)
1115 int_rel.r_symndx = RELOC_SECTION_SDATA;
1116 else if (strcmp (name, ".sbss") == 0)
1117 int_rel.r_symndx = RELOC_SECTION_SBSS;
1118 break;
1119 case 't':
1120 if (strcmp (name, ".text") == 0)
1121 int_rel.r_symndx = RELOC_SECTION_TEXT;
1122 break;
1123 }
1124
1125 if (int_rel.r_symndx == -1)
1126 abort ();
1127
1128 /* Add the section VMA and the symbol value. */
1129 relocation = (h->root.u.def.value
a3a33af3
ILT
1130 + s->output_section->vma
1131 + s->output_offset);
1132
1133 /* For a PC relative relocation, the object file
1134 currently holds just the addend. We must adjust
1135 by the address to get the right value. */
1136 if (howto->pc_relative)
1137 relocation -= int_rel.r_vaddr - input_section->vma;
1138
1139 h = NULL;
4991ebb9
ILT
1140 }
1141 else
1142 {
1143 /* Change the symndx value to the right one for the
1144 output BFD. */
1145 int_rel.r_symndx = h->indx;
1146 if (int_rel.r_symndx == -1)
1147 {
1148 /* This symbol is not being written out. */
1149 if (! ((*info->callbacks->unattached_reloc)
1150 (info, h->root.root.string, input_bfd,
1151 input_section,
1152 int_rel.r_vaddr - input_section->vma)))
1153 return false;
1154 int_rel.r_symndx = 0;
1155 }
1156 relocation = 0;
1157 }
1158 }
1159 else
1160 {
1161 /* This is a relocation against a section. Adjust the
1162 value by the amount the section moved. */
1163 relocation = (s->output_section->vma
1164 + s->output_offset
1165 - s->vma);
1166 }
de17306e 1167
4991ebb9 1168 relocation += addend;
de17306e 1169
a3a33af3
ILT
1170 /* Adjust a PC relative relocation by removing the reference
1171 to the original address in the section and including the
1172 reference to the new address. */
1173 if (howto->pc_relative)
1174 relocation -= (input_section->output_section->vma
1175 + input_section->output_offset
1176 - input_section->vma);
1177
4991ebb9
ILT
1178 /* Adjust the contents. */
1179 if (relocation == 0)
1180 r = bfd_reloc_ok;
1181 else
1182 {
1183 if (int_rel.r_type != MIPS_R_REFHI)
1184 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1185 (contents
a3a33af3 1186 + adjust
4991ebb9
ILT
1187 + int_rel.r_vaddr
1188 - input_section->vma));
1189 else
1190 {
1191 mips_relocate_refhi (&int_rel, &reflo_int_rel,
1192 input_bfd, input_section, contents,
a3a33af3 1193 adjust, relocation);
4991ebb9
ILT
1194 r = bfd_reloc_ok;
1195 }
1196 }
de17306e 1197
4991ebb9
ILT
1198 /* Adjust the reloc address. */
1199 int_rel.r_vaddr += (input_section->output_section->vma
1200 + input_section->output_offset
1201 - input_section->vma);
de17306e 1202
4991ebb9
ILT
1203 /* Save the changed reloc information. */
1204 mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
1205 }
1206 else
1207 {
1208 /* We are producing a final executable. */
1209 if (int_rel.r_extern)
1210 {
1211 /* This is a reloc against a symbol. */
1212 if (h->root.type == bfd_link_hash_defined)
1213 {
1214 asection *hsec;
de17306e 1215
4991ebb9
ILT
1216 hsec = h->root.u.def.section;
1217 relocation = (h->root.u.def.value
1218 + hsec->output_section->vma
1219 + hsec->output_offset);
1220 }
1221 else
1222 {
1223 if (! ((*info->callbacks->undefined_symbol)
1224 (info, h->root.root.string, input_bfd,
1225 input_section,
1226 int_rel.r_vaddr - input_section->vma)))
1227 return false;
1228 relocation = 0;
1229 }
1230 }
1231 else
1232 {
1233 /* This is a reloc against a section. */
1234 relocation = (s->output_section->vma
1235 + s->output_offset
1236 - s->vma);
1237
a3a33af3
ILT
1238 /* A PC relative reloc is already correct in the object
1239 file. Make it look like a pcrel_offset relocation by
1240 adding in the start address. */
4991ebb9 1241 if (howto->pc_relative)
a3a33af3 1242 relocation += int_rel.r_vaddr + adjust;
4991ebb9 1243 }
de17306e 1244
4991ebb9
ILT
1245 if (int_rel.r_type != MIPS_R_REFHI)
1246 r = _bfd_final_link_relocate (howto,
1247 input_bfd,
1248 input_section,
1249 contents,
a3a33af3
ILT
1250 (int_rel.r_vaddr
1251 - input_section->vma
1252 + adjust),
4991ebb9
ILT
1253 relocation,
1254 addend);
1255 else
1256 {
1257 mips_relocate_refhi (&int_rel, &reflo_int_rel, input_bfd,
a3a33af3
ILT
1258 input_section, contents, adjust,
1259 relocation);
4991ebb9
ILT
1260 r = bfd_reloc_ok;
1261 }
1262 }
1263
1264 if (r != bfd_reloc_ok)
1265 {
1266 switch (r)
1267 {
1268 default:
1269 case bfd_reloc_outofrange:
1270 abort ();
1271 case bfd_reloc_overflow:
1272 {
1273 const char *name;
1274
1275 if (int_rel.r_extern)
1276 name = h->root.root.string;
1277 else
1278 name = bfd_section_name (input_bfd, s);
1279 if (! ((*info->callbacks->reloc_overflow)
1280 (info, name, howto->name, (bfd_vma) 0,
1281 input_bfd, input_section,
1282 int_rel.r_vaddr - input_section->vma)))
1283 return false;
1284 }
1285 break;
1286 }
1287 }
1288 }
1289
1290 return true;
de17306e 1291}
de17306e 1292\f
a3a33af3
ILT
1293/* Relax a section when linking a MIPS ECOFF file. This is used for
1294 embedded PIC code, which always uses PC relative branches which
1295 only have an 18 bit range on MIPS. If a branch is not in range, we
1296 generate a long instruction sequence to compensate. Each time we
1297 find a branch to expand, we have to check all the others again to
1298 make sure they are still in range. This is slow, but it only has
1299 to be done when -relax is passed to the linker.
1300
1301 This routine figures out which branches need to expand; the actual
1302 expansion is done in mips_relocate_section when the section
1303 contents are relocated. The information is stored in the offsets
1304 field of the ecoff_section_tdata structure. An offset of 1 means
1305 that the branch must be expanded into a multi-instruction PC
1306 relative branch (such an offset will only occur for a PC relative
1307 branch to an external symbol). Any other offset must be a multiple
1308 of four, and is the amount to change the branch by (such an offset
1309 will only occur for a PC relative branch within the same section).
1310
1311 We do not modify the section relocs or contents themselves so that
1312 if memory usage becomes an issue we can discard them and read them
1313 again. The only information we must save in memory between this
1314 routine and the mips_relocate_section routine is the table of
1315 offsets. */
1316
1317static boolean
1318mips_relax_section (abfd, sec, info, again)
1319 bfd *abfd;
1320 asection *sec;
1321 struct bfd_link_info *info;
1322 boolean *again;
1323{
1324 struct ecoff_section_tdata *section_tdata;
1325 bfd_byte *contents = NULL;
1326 long *offsets;
1327 struct external_reloc *ext_rel;
1328 struct external_reloc *ext_rel_end;
1329 unsigned int i;
1330
1331 /* Assume we are not going to need another pass. */
1332 *again = false;
1333
1334 /* If we are not generating an ECOFF file, this is much too
1335 confusing to deal with. */
1336 if (info->hash->creator->flavour != bfd_get_flavour (abfd))
1337 return true;
1338
1339 /* If there are no relocs, there is nothing to do. */
1340 if (sec->reloc_count == 0)
1341 return true;
1342
1343 /* We are only interested in PC relative relocs, and why would there
1344 ever be one from anything but the .text section? */
1345 if (strcmp (bfd_get_section_name (abfd, sec), ".text") != 0)
1346 return true;
1347
1348 /* Read in the relocs, if we haven't already got them. */
1349 section_tdata = ecoff_section_data (abfd, sec);
1350 if (section_tdata == (struct ecoff_section_tdata *) NULL)
1351 {
1352 bfd_size_type external_reloc_size;
1353 bfd_size_type external_relocs_size;
1354
1355 sec->used_by_bfd =
1356 (PTR) bfd_alloc_by_size_t (abfd, sizeof (struct ecoff_section_tdata));
1357 if (sec->used_by_bfd == NULL)
1358 {
1359 bfd_set_error (bfd_error_no_memory);
1360 goto error_return;
1361 }
1362
1363 section_tdata = ecoff_section_data (abfd, sec);
1364 section_tdata->contents = NULL;
1365 section_tdata->offsets = NULL;
1366
1367 external_reloc_size = ecoff_backend (abfd)->external_reloc_size;
1368 external_relocs_size = external_reloc_size * sec->reloc_count;
1369
1370 section_tdata->external_relocs =
1371 (PTR) bfd_alloc (abfd, external_relocs_size);
1372 if (section_tdata->external_relocs == NULL && external_relocs_size != 0)
1373 {
1374 bfd_set_error (bfd_error_no_memory);
1375 goto error_return;
1376 }
1377
1378 if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
1379 || (bfd_read (section_tdata->external_relocs, 1,
1380 external_relocs_size, abfd)
1381 != external_relocs_size))
1382 goto error_return;
1383
1384 /* We must initialize _cooked_size only the first time we are
1385 called. */
1386 sec->_cooked_size = sec->_raw_size;
1387 }
1388
1389 contents = section_tdata->contents;
1390 offsets = section_tdata->offsets;
1391
1392 /* Look for any external PC relative relocs. Internal PC relative
1393 relocs are already correct in the object file, so they certainly
1394 can not overflow. */
1395 ext_rel = (struct external_reloc *) section_tdata->external_relocs;
1396 ext_rel_end = ext_rel + sec->reloc_count;
1397 for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
1398 {
1399 struct internal_reloc int_rel;
1400 struct ecoff_link_hash_entry *h;
1401 asection *hsec;
1402 bfd_signed_vma relocation;
1403 struct external_reloc *adj_ext_rel;
1404 unsigned int adj_i;
1405 unsigned long ext_count;
1406 struct ecoff_link_hash_entry **adj_h_ptr;
1407 struct ecoff_link_hash_entry **adj_h_ptr_end;
1408 struct ecoff_value_adjust *adjust;
1409
1410 /* If we have already expanded this reloc, we certainly don't
1411 need to do it again. */
1412 if (offsets != (long *) NULL && offsets[i] == 1)
1413 continue;
1414
1415 /* Quickly check that this reloc is external PCREL16. */
1416 if (abfd->xvec->header_byteorder_big_p)
1417 {
1418 if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_BIG) == 0
1419 || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_BIG)
1420 >> RELOC_BITS3_TYPE_SH_BIG)
1421 != MIPS_R_PCREL16))
1422 continue;
1423 }
1424 else
1425 {
1426 if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) == 0
1427 || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
1428 >> RELOC_BITS3_TYPE_SH_LITTLE)
1429 != MIPS_R_PCREL16))
1430 continue;
1431 }
1432
1433 mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel);
1434
1435 h = ecoff_data (abfd)->sym_hashes[int_rel.r_symndx];
1436 if (h == (struct ecoff_link_hash_entry *) NULL)
1437 abort ();
1438
1439 if (h->root.type != bfd_link_hash_defined)
1440 {
1441 /* Just ignore undefined symbols. These will presumably
1442 generate an error later in the link. */
1443 continue;
1444 }
1445
1446 /* Get the value of the symbol. */
1447 hsec = h->root.u.def.section;
1448 relocation = (h->root.u.def.value
1449 + hsec->output_section->vma
1450 + hsec->output_offset);
1451
1452 /* Subtract out the current address. */
1453 relocation -= (sec->output_section->vma
1454 + sec->output_offset
1455 + (int_rel.r_vaddr - sec->vma));
1456
1457 /* The addend is stored in the object file. In the normal case
1458 of ``bal symbol'', the addend will be -4. It will only be
1459 different in the case of ``bal symbol+constant''. To avoid
1460 always reading in the section contents, we don't check the
1461 addend in the object file (we could easily check the contents
1462 if we happen to have already read them in, but I fear that
1463 this could be confusing). This means we will screw up if
1464 there is a branch to a symbol that is in range, but added to
1465 a constant which puts it out of range; in such a case the
1466 link will fail with a reloc overflow error. Since the
1467 compiler will never generate such code, it should be easy
1468 enough to work around it by changing the assembly code in the
1469 source file. */
1470 relocation -= 4;
1471
1472 /* Now RELOCATION is the number we want to put in the object
1473 file. See whether it fits. */
1474 if (relocation >= -0x20000 && relocation < 0x20000)
1475 continue;
1476
1477 /* Now that we know this reloc needs work, which will rarely
1478 happen, go ahead and grab the section contents. */
1479 if (contents == (bfd_byte *) NULL)
1480 {
1481 if (info->keep_memory)
1482 contents = (bfd_byte *) bfd_alloc (abfd, sec->_raw_size);
1483 else
1484 contents = (bfd_byte *) malloc (sec->_raw_size);
1485 if (contents == (bfd_byte *) NULL)
1486 {
1487 bfd_set_error (bfd_error_no_memory);
1488 goto error_return;
1489 }
1490 if (! bfd_get_section_contents (abfd, sec, (PTR) contents,
1491 (file_ptr) 0, sec->_raw_size))
1492 goto error_return;
1493 if (info->keep_memory)
1494 section_tdata->contents = contents;
1495 }
1496
1497 /* We only support changing the bal instruction. It would be
1498 possible to handle other PC relative branches, but some of
1499 them (the conditional branches) would require a different
1500 length instruction sequence which would complicate both this
1501 routine and mips_relax_pcrel16. It could be written if
1502 somebody felt it were important. Ignoring this reloc will
1503 presumably cause a reloc overflow error later on. */
1504 if (bfd_get_32 (abfd, contents + int_rel.r_vaddr - sec->vma)
1505 != 0x0411ffff) /* bgezal $0,. == bal . */
1506 continue;
1507
1508 /* Bother. We need to expand this reloc, and we will need to
1509 make another relaxation pass since this change may put other
1510 relocs out of range. We need to examine the local branches
1511 and we need to allocate memory to hold the offsets we must
1512 add to them. We also need to adjust the values of all
1513 symbols in the object file following this location. */
1514
1515 sec->_cooked_size += PCREL16_EXPANSION_ADJUSTMENT;
1516 *again = true;
1517
1518 if (offsets == (long *) NULL)
1519 {
1520 size_t size;
1521
1522 size = sec->reloc_count * sizeof (long);
1523 offsets = (long *) bfd_alloc_by_size_t (abfd, size);
1524 if (offsets == (long *) NULL)
1525 {
1526 bfd_set_error (bfd_error_no_memory);
1527 goto error_return;
1528 }
1529 memset (offsets, 0, size);
1530 section_tdata->offsets = offsets;
1531 }
1532
1533 offsets[i] = 1;
1534
1535 /* Now look for all PC relative branches that cross this reloc
1536 and adjust their offsets. We will turn the single branch
1537 instruction into a four instruction sequence. In this loop
1538 we are only interested in local PC relative branches. */
1539 adj_ext_rel = (struct external_reloc *) section_tdata->external_relocs;
1540 for (adj_i = 0; adj_ext_rel < ext_rel_end; adj_ext_rel++, adj_i++)
1541 {
1542 struct internal_reloc adj_int_rel;
1543 unsigned long insn;
1544 bfd_vma dst;
1545
1546 /* Quickly check that this reloc is internal PCREL16. */
1547 if (abfd->xvec->header_byteorder_big_p)
1548 {
1549 if ((adj_ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0
1550 || (((adj_ext_rel->r_bits[3] & RELOC_BITS3_TYPE_BIG)
1551 >> RELOC_BITS3_TYPE_SH_BIG)
1552 != MIPS_R_PCREL16))
1553 continue;
1554 }
1555 else
1556 {
1557 if ((adj_ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0
1558 || (((adj_ext_rel->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
1559 >> RELOC_BITS3_TYPE_SH_LITTLE)
1560 != MIPS_R_PCREL16))
1561 continue;
1562 }
1563
1564 mips_ecoff_swap_reloc_in (abfd, (PTR) adj_ext_rel, &adj_int_rel);
1565
1566 /* We are only interested in a PC relative reloc within this
1567 section. FIXME: Cross section PC relative relocs may not
1568 be handled correctly; does anybody care? */
1569 if (adj_int_rel.r_symndx != RELOC_SECTION_TEXT)
1570 continue;
1571
1572 /* Fetch the branch instruction. */
1573 insn = bfd_get_32 (abfd, contents + adj_int_rel.r_vaddr - sec->vma);
1574
1575 /* Work out the destination address. */
1576 dst = (insn & 0xffff) << 2;
1577 if ((dst & 0x20000) != 0)
1578 dst -= 0x40000;
1579 dst += adj_int_rel.r_vaddr + 4;
1580
1581 /* If this branch crosses the branch we just decided to
1582 expand, adjust the offset appropriately. */
1583 if (adj_int_rel.r_vaddr < int_rel.r_vaddr
1584 && dst > int_rel.r_vaddr)
1585 offsets[adj_i] += PCREL16_EXPANSION_ADJUSTMENT;
1586 else if (adj_int_rel.r_vaddr > int_rel.r_vaddr
1587 && dst <= int_rel.r_vaddr)
1588 offsets[adj_i] -= PCREL16_EXPANSION_ADJUSTMENT;
1589 }
1590
1591 /* Find all symbols in this section defined by this object file
1592 and adjust their values. Note that we decide whether to
1593 adjust the value based on the value stored in the ECOFF EXTR
1594 structure, because the value stored in the hash table may
1595 have been changed by an earlier expanded reloc and thus may
1596 no longer correctly indicate whether the symbol is before or
1597 after the expanded reloc. */
1598 ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax;
1599 adj_h_ptr = ecoff_data (abfd)->sym_hashes;
1600 adj_h_ptr_end = adj_h_ptr + ext_count;
1601 for (; adj_h_ptr < adj_h_ptr_end; adj_h_ptr++)
1602 {
1603 struct ecoff_link_hash_entry *adj_h;
1604
1605 adj_h = *adj_h_ptr;
1606 if (adj_h != (struct ecoff_link_hash_entry *) NULL
1607 && adj_h->root.type == bfd_link_hash_defined
1608 && adj_h->root.u.def.section == sec
1609 && adj_h->esym.asym.value > int_rel.r_vaddr)
1610 adj_h->root.u.def.value += PCREL16_EXPANSION_ADJUSTMENT;
1611 }
1612
1613 /* Add an entry to the symbol value adjust list. This is used
1614 by bfd_ecoff_debug_accumulate to adjust the values of
1615 internal symbols and FDR's. */
1616 adjust = ((struct ecoff_value_adjust *)
1617 bfd_alloc (abfd, sizeof (struct ecoff_value_adjust)));
1618 if (adjust == (struct ecoff_value_adjust *) NULL)
1619 {
1620 bfd_set_error (bfd_error_no_memory);
1621 goto error_return;
1622 }
1623
1624 adjust->start = int_rel.r_vaddr;
1625 adjust->end = sec->vma + sec->_raw_size;
1626 adjust->adjust = PCREL16_EXPANSION_ADJUSTMENT;
1627
1628 adjust->next = ecoff_data (abfd)->debug_info.adjust;
1629 ecoff_data (abfd)->debug_info.adjust = adjust;
1630 }
1631
1632 if (contents != (bfd_byte *) NULL && ! info->keep_memory)
1633 free (contents);
1634
1635 return true;
1636
1637 error_return:
1638 if (contents != (bfd_byte *) NULL && ! info->keep_memory)
1639 free (contents);
1640 return false;
1641}
1642
1643/* This routine is called from mips_relocate_section when a PC
1644 relative reloc must be expanded into the five instruction sequence.
1645 It handles all the details of the expansion, including resolving
1646 the reloc. */
1647
1648static boolean
1649mips_relax_pcrel16 (info, input_bfd, input_section, h, location, address)
1650 struct bfd_link_info *info;
1651 bfd *input_bfd;
1652 asection *input_section;
1653 struct ecoff_link_hash_entry *h;
1654 bfd_byte *location;
1655 bfd_vma address;
1656{
1657 bfd_vma relocation;
1658
1659 /* 0x0411ffff is bgezal $0,. == bal . */
1660 BFD_ASSERT (bfd_get_32 (input_bfd, location) == 0x0411ffff);
1661
1662 /* We need to compute the distance between the symbol and the
1663 current address plus eight. */
1664 relocation = (h->root.u.def.value
1665 + h->root.u.def.section->output_section->vma
1666 + h->root.u.def.section->output_offset);
1667 relocation -= address + 8;
1668
1669 /* If the lower half is negative, increment the upper 16 half. */
1670 if ((relocation & 0x8000) != 0)
1671 relocation += 0x10000;
1672
1673 bfd_put_32 (input_bfd, 0x04110001, location); /* bal .+8 */
1674 bfd_put_32 (input_bfd,
1675 0x3c010000 | ((relocation >> 16) & 0xffff), /* lui $at,XX */
1676 location + 4);
1677 bfd_put_32 (input_bfd,
1678 0x24210000 | (relocation & 0xffff), /* addiu $at,$at,XX */
1679 location + 8);
1680 bfd_put_32 (input_bfd, 0x003f0821, location + 12); /* addu $at,$at,$ra */
1681 bfd_put_32 (input_bfd, 0x0020f809, location + 16); /* jalr $at */
1682
1683 return true;
1684}
1685\f
23f44e6f
ILT
1686/* This is the ECOFF backend structure. The backend field of the
1687 target vector points to this. */
1688
1689static const struct ecoff_backend_data mips_ecoff_backend_data =
1690{
1691 /* COFF backend structure. */
1692 {
9783e04a 1693 (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
23f44e6f
ILT
1694 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
1695 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
9783e04a 1696 (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
23f44e6f
ILT
1697 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
1698 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
1699 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
1700 mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
1701 mips_ecoff_swap_scnhdr_out,
1702 FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, true,
1703 mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
1704 mips_ecoff_swap_scnhdr_in, mips_ecoff_bad_format_hook,
5fa2aaa2 1705 ecoff_set_arch_mach_hook, ecoff_mkobject_hook,
23f44e6f
ILT
1706 ecoff_styp_to_sec_flags, ecoff_make_section_hook, ecoff_set_alignment_hook,
1707 ecoff_slurp_symbol_table, NULL, NULL
1708 },
1709 /* Supported architecture. */
1710 bfd_arch_mips,
23f44e6f
ILT
1711 /* Initial portion of armap string. */
1712 "__________",
23f44e6f
ILT
1713 /* The page boundary used to align sections in a demand-paged
1714 executable file. E.g., 0x1000. */
1715 0x1000,
5fa2aaa2
ILT
1716 /* True if the .rdata section is part of the text segment, as on the
1717 Alpha. False if .rdata is part of the data segment, as on the
1718 MIPS. */
1719 false,
23f44e6f
ILT
1720 /* Bitsize of constructor entries. */
1721 32,
1722 /* Reloc to use for constructor entries. */
1723 &mips_howto_table[MIPS_R_REFWORD],
4991ebb9
ILT
1724 {
1725 /* Symbol table magic number. */
1726 magicSym,
1727 /* Alignment of debugging information. E.g., 4. */
1728 4,
1729 /* Sizes of external symbolic information. */
1730 sizeof (struct hdr_ext),
1731 sizeof (struct dnr_ext),
1732 sizeof (struct pdr_ext),
1733 sizeof (struct sym_ext),
1734 sizeof (struct opt_ext),
1735 sizeof (struct fdr_ext),
1736 sizeof (struct rfd_ext),
1737 sizeof (struct ext_ext),
1738 /* Functions to swap in external symbolic data. */
1739 ecoff_swap_hdr_in,
1740 ecoff_swap_dnr_in,
1741 ecoff_swap_pdr_in,
1742 ecoff_swap_sym_in,
1743 ecoff_swap_opt_in,
1744 ecoff_swap_fdr_in,
1745 ecoff_swap_rfd_in,
1746 ecoff_swap_ext_in,
1747 /* Functions to swap out external symbolic data. */
1748 ecoff_swap_hdr_out,
1749 ecoff_swap_dnr_out,
1750 ecoff_swap_pdr_out,
1751 ecoff_swap_sym_out,
1752 ecoff_swap_opt_out,
1753 ecoff_swap_fdr_out,
1754 ecoff_swap_rfd_out,
1755 ecoff_swap_ext_out
1756 },
23f44e6f
ILT
1757 /* External reloc size. */
1758 RELSZ,
1759 /* Reloc swapping functions. */
1760 mips_ecoff_swap_reloc_in,
1761 mips_ecoff_swap_reloc_out,
1762 /* Backend reloc tweaking. */
5fa2aaa2 1763 mips_adjust_reloc_in,
4991ebb9
ILT
1764 mips_adjust_reloc_out,
1765 /* Relocate section contents while linking. */
1766 mips_relocate_section
515c4292
ILT
1767};
1768
23f44e6f
ILT
1769/* Looking up a reloc type is MIPS specific. */
1770#define ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
1771
5fa2aaa2
ILT
1772/* Getting relocated section contents is generic. */
1773#define ecoff_bfd_get_relocated_section_contents \
1774 bfd_generic_get_relocated_section_contents
1775
a3a33af3
ILT
1776/* Relaxing sections is MIPS specific. */
1777#define ecoff_bfd_relax_section mips_relax_section
1778
1327fb29 1779bfd_target ecoff_little_vec =
294eaca4
SC
1780{
1781 "ecoff-littlemips", /* name */
515c4292 1782 bfd_target_ecoff_flavour,
294eaca4
SC
1783 false, /* data byte order is little */
1784 false, /* header byte order is little */
1785
1786 (HAS_RELOC | EXEC_P | /* object flags */
1787 HAS_LINENO | HAS_DEBUG |
4991ebb9 1788 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
294eaca4
SC
1789
1790 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect
1791 flags */
1792 0, /* leading underscore */
de17306e 1793 ' ', /* ar_pad_char */
294eaca4 1794 15, /* ar_max_namelen */
de17306e 1795 4, /* minimum alignment power */
23f44e6f
ILT
1796 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1797 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1798 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1799 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1800 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1801 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
294eaca4 1802
515c4292 1803 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
c3fe0c41 1804 ecoff_archive_p, _bfd_dummy_target},
23f44e6f 1805 {bfd_false, ecoff_mkobject, /* bfd_set_format */
dae31cf5 1806 _bfd_generic_mkarchive, bfd_false},
c3fe0c41
ILT
1807 {bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
1808 _bfd_write_archive_contents, bfd_false},
6812b607
ILT
1809
1810 BFD_JUMP_TABLE_GENERIC (ecoff),
1811 BFD_JUMP_TABLE_COPY (ecoff),
1812 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1813 BFD_JUMP_TABLE_ARCHIVE (ecoff),
1814 BFD_JUMP_TABLE_SYMBOLS (ecoff),
1815 BFD_JUMP_TABLE_RELOCS (ecoff),
1816 BFD_JUMP_TABLE_WRITE (ecoff),
1817 BFD_JUMP_TABLE_LINK (ecoff),
1818
23f44e6f 1819 (PTR) &mips_ecoff_backend_data
515c4292 1820};
1327fb29
SC
1821
1822bfd_target ecoff_big_vec =
294eaca4
SC
1823{
1824 "ecoff-bigmips", /* name */
515c4292 1825 bfd_target_ecoff_flavour,
294eaca4
SC
1826 true, /* data byte order is big */
1827 true, /* header byte order is big */
1828
1829 (HAS_RELOC | EXEC_P | /* object flags */
1830 HAS_LINENO | HAS_DEBUG |
4991ebb9 1831 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
294eaca4
SC
1832
1833 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect flags */
1834 0, /* leading underscore */
1835 ' ', /* ar_pad_char */
de17306e
ILT
1836 15, /* ar_max_namelen */
1837 4, /* minimum alignment power */
23f44e6f
ILT
1838 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1839 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1840 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1841 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1842 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1843 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
294eaca4 1844 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
6812b607 1845 ecoff_archive_p, _bfd_dummy_target},
23f44e6f 1846 {bfd_false, ecoff_mkobject, /* bfd_set_format */
dae31cf5 1847 _bfd_generic_mkarchive, bfd_false},
515c4292 1848 {bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
c3fe0c41 1849 _bfd_write_archive_contents, bfd_false},
6812b607
ILT
1850
1851 BFD_JUMP_TABLE_GENERIC (ecoff),
1852 BFD_JUMP_TABLE_COPY (ecoff),
1853 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1854 BFD_JUMP_TABLE_ARCHIVE (ecoff),
1855 BFD_JUMP_TABLE_SYMBOLS (ecoff),
1856 BFD_JUMP_TABLE_RELOCS (ecoff),
1857 BFD_JUMP_TABLE_WRITE (ecoff),
1858 BFD_JUMP_TABLE_LINK (ecoff),
1859
23f44e6f 1860 (PTR) &mips_ecoff_backend_data
515c4292 1861};
This page took 0.210926 seconds and 4 git commands to generate.