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