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