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