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