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