* breakpoint.c, breakpoint.h (breakpoint_init_inferior): New function
[deliverable/binutils-gdb.git] / bfd / coff-mips.c
CommitLineData
1f29e30b 1/* BFD back-end for MIPS Extended-Coff files.
f6409552 2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
8fa0d3a0 3 Original version by Per Bothner.
f6409552 4 Full support added by Ian Lance Taylor, ian@cygnus.com.
1327fb29 5
68b70212 6This file is part of BFD, the Binary File Descriptor library.
23b0b558 7
68b70212 8This program is free software; you can redistribute it and/or modify
23b0b558 9it under the terms of the GNU General Public License as published by
68b70212
JG
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
23b0b558 12
68b70212 13This program is distributed in the hope that it will be useful,
23b0b558
JG
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
68b70212
JG
19along with this program; if not, write to the Free Software
20Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
1327fb29 21
23b0b558 22#include "bfd.h"
dd4646ca 23#include "sysdep.h"
1327fb29 24#include "libbfd.h"
8fa0d3a0 25#include "seclet.h"
dae31cf5
ILT
26#include "coff/internal.h"
27#include "coff/sym.h"
28#include "coff/symconst.h"
29#include "coff/ecoff.h"
30#include "coff/mips.h"
31#include "libcoff.h"
32#include "libecoff.h"
33\f
34/* Prototypes for static functions. */
c3fe0c41 35
dae31cf5
ILT
36static boolean mips_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr));
37static PTR mips_ecoff_mkobject_hook PARAMS ((bfd *abfd, PTR filehdr,
38 PTR aouthdr));
39static void mips_ecoff_swap_reloc_in PARAMS ((bfd *, PTR,
40 struct internal_reloc *));
41static void mips_ecoff_swap_reloc_out PARAMS ((bfd *,
42 const struct internal_reloc *,
43 PTR));
23f44e6f
ILT
44static bfd_reloc_status_type mips_generic_reloc PARAMS ((bfd *abfd,
45 arelent *reloc,
46 asymbol *symbol,
47 PTR data,
48 asection *section,
49 bfd *output_bfd));
50static bfd_reloc_status_type mips_refhi_reloc PARAMS ((bfd *abfd,
51 arelent *reloc,
52 asymbol *symbol,
53 PTR data,
54 asection *section,
55 bfd *output_bfd));
56static bfd_reloc_status_type mips_reflo_reloc PARAMS ((bfd *abfd,
57 arelent *reloc,
58 asymbol *symbol,
59 PTR data,
60 asection *section,
61 bfd *output_bfd));
62static bfd_reloc_status_type mips_gprel_reloc PARAMS ((bfd *abfd,
63 arelent *reloc,
64 asymbol *symbol,
65 PTR data,
66 asection *section,
67 bfd *output_bfd));
dae31cf5 68\f
dae31cf5
ILT
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.
8fa0d3a0 74
dae31cf5 75 Get the generic COFF swapping routines, except for the reloc,
23f44e6f 76 symbol, and lineno ones. Give them ECOFF names. */
dae31cf5
ILT
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"
8fa0d3a0 88
dae31cf5
ILT
89/* Get the ECOFF swapping routines. */
90#define ECOFF_32
91#include "ecoffswap.h"
92\f
23f44e6f 93/* How to process the various relocs types. */
dae31cf5 94
23f44e6f 95static reloc_howto_type mips_howto_table[] =
dae31cf5 96{
23f44e6f
ILT
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 */
104 false, /* pc_relative */
105 0, /* bitpos */
106 complain_overflow_dont, /* complain_on_overflow */
107 0, /* special_function */
108 "IGNORE", /* name */
109 false, /* partial_inplace */
110 0, /* src_mask */
111 0, /* dst_mask */
112 false), /* pcrel_offset */
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 */
119 false, /* pc_relative */
120 0, /* bitpos */
121 complain_overflow_bitfield, /* complain_on_overflow */
122 mips_generic_reloc, /* special_function */
123 "REFHALF", /* name */
124 true, /* partial_inplace */
125 0xffff, /* src_mask */
126 0xffff, /* dst_mask */
127 false), /* pcrel_offset */
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 */
134 false, /* pc_relative */
135 0, /* bitpos */
136 complain_overflow_bitfield, /* complain_on_overflow */
137 mips_generic_reloc, /* special_function */
138 "REFWORD", /* name */
139 true, /* partial_inplace */
140 0xffffffff, /* src_mask */
141 0xffffffff, /* dst_mask */
142 false), /* pcrel_offset */
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 */
149 false, /* pc_relative */
150 0, /* bitpos */
151 complain_overflow_bitfield, /* complain_on_overflow */
152 mips_generic_reloc, /* special_function */
153 "JMPADDR", /* name */
154 true, /* partial_inplace */
155 0x3ffffff, /* src_mask */
156 0x3ffffff, /* dst_mask */
157 false), /* pcrel_offset */
158
159 /* The high 16 bits of a symbol value. Handled by the function
160 mips_refhi_reloc. */
161 HOWTO (MIPS_R_REFHI, /* type */
162 16, /* rightshift */
163 2, /* size (0 = byte, 1 = short, 2 = long) */
164 16, /* bitsize */
165 false, /* pc_relative */
166 0, /* bitpos */
167 complain_overflow_bitfield, /* complain_on_overflow */
168 mips_refhi_reloc, /* special_function */
169 "REFHI", /* name */
170 true, /* partial_inplace */
171 0xffff, /* src_mask */
172 0xffff, /* dst_mask */
173 false), /* pcrel_offset */
174
175 /* The low 16 bits of a symbol value. */
176 HOWTO (MIPS_R_REFLO, /* type */
177 0, /* rightshift */
178 2, /* size (0 = byte, 1 = short, 2 = long) */
179 16, /* bitsize */
180 false, /* pc_relative */
181 0, /* bitpos */
182 complain_overflow_dont, /* complain_on_overflow */
183 mips_reflo_reloc, /* special_function */
184 "REFLO", /* name */
185 true, /* partial_inplace */
186 0xffff, /* src_mask */
187 0xffff, /* dst_mask */
188 false), /* pcrel_offset */
189
190 /* A reference to an offset from the gp register. Handled by the
191 function mips_gprel_reloc. */
192 HOWTO (MIPS_R_GPREL, /* type */
193 0, /* rightshift */
194 2, /* size (0 = byte, 1 = short, 2 = long) */
195 16, /* bitsize */
196 false, /* pc_relative */
197 0, /* bitpos */
198 complain_overflow_signed, /* complain_on_overflow */
199 mips_gprel_reloc, /* special_function */
200 "GPREL", /* name */
201 true, /* partial_inplace */
202 0xffff, /* src_mask */
203 0xffff, /* dst_mask */
204 false), /* pcrel_offset */
205
206 /* A reference to a literal using an offset from the gp register.
207 Handled by the function mips_gprel_reloc. */
208 HOWTO (MIPS_R_LITERAL, /* type */
209 0, /* rightshift */
210 2, /* size (0 = byte, 1 = short, 2 = long) */
211 16, /* bitsize */
212 false, /* pc_relative */
213 0, /* bitpos */
214 complain_overflow_signed, /* complain_on_overflow */
215 mips_gprel_reloc, /* special_function */
216 "LITERAL", /* name */
217 true, /* partial_inplace */
218 0xffff, /* src_mask */
219 0xffff, /* dst_mask */
220 false) /* pcrel_offset */
dae31cf5 221};
23f44e6f
ILT
222
223#define MIPS_HOWTO_COUNT \
224 (sizeof mips_howto_table / sizeof mips_howto_table[0])
dae31cf5
ILT
225\f
226/* See whether the magic number matches. */
8fa0d3a0 227
dae31cf5
ILT
228static boolean
229mips_ecoff_bad_format_hook (abfd, filehdr)
230 bfd *abfd;
231 PTR filehdr;
232{
233 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
8fa0d3a0 234
dae31cf5 235 if (MIPS_ECOFF_BADMAG (*internal_f))
8fa0d3a0
ILT
236 return false;
237
8fa0d3a0
ILT
238 return true;
239}
c3fe0c41 240
dae31cf5 241/* Create the MIPS ECOFF backend specific information. */
c3fe0c41 242
dae31cf5
ILT
243static PTR
244mips_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
f6409552 245 bfd *abfd;
dae31cf5
ILT
246 PTR filehdr;
247 PTR aouthdr;
c3fe0c41 248{
dae31cf5
ILT
249 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
250 struct internal_aouthdr *internal_a = (struct internal_aouthdr *) aouthdr;
251 ecoff_data_type *ecoff;
c3fe0c41 252
23f44e6f 253 if (ecoff_mkobject (abfd) == false)
dae31cf5 254 return NULL;
c3fe0c41 255
dae31cf5
ILT
256 ecoff = ecoff_data (abfd);
257 ecoff->gp_size = 8;
258 ecoff->sym_filepos = internal_f->f_symptr;
23ba15b7 259
dae31cf5 260 if (internal_a != (struct internal_aouthdr *) NULL)
c3fe0c41 261 {
dae31cf5 262 int i;
23ba15b7 263
dae31cf5
ILT
264 ecoff->text_start = internal_a->text_start;
265 ecoff->text_end = internal_a->text_start + internal_a->tsize;
266 ecoff->gp = internal_a->gp_value;
267 ecoff->gprmask = internal_a->gprmask;
268 for (i = 0; i < 4; i++)
269 ecoff->cprmask[i] = internal_a->cprmask[i];
270 if (internal_a->magic == ECOFF_AOUT_ZMAGIC)
271 abfd->flags |= D_PAGED;
c3fe0c41
ILT
272 }
273
dae31cf5
ILT
274 return (PTR) ecoff;
275}
276\f
277/* Reloc handling. MIPS ECOFF relocs are packed into 8 bytes in
278 external form. They use a bit which indicates whether the symbol
279 is external. */
23ba15b7 280
dae31cf5 281/* Swap a reloc in. */
23ba15b7 282
dae31cf5
ILT
283static void
284mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
285 bfd *abfd;
286 PTR ext_ptr;
287 struct internal_reloc *intern;
288{
289 const RELOC *ext = (RELOC *) ext_ptr;
23ba15b7 290
dae31cf5
ILT
291 intern->r_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_vaddr);
292 if (abfd->xvec->header_byteorder_big_p != false)
293 {
294 intern->r_symndx = (((int) ext->r_bits[0]
295 << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
296 | ((int) ext->r_bits[1]
297 << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
298 | ((int) ext->r_bits[2]
299 << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
300 intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
301 >> RELOC_BITS3_TYPE_SH_BIG);
302 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
23ba15b7 303 }
dae31cf5 304 else
23ba15b7 305 {
dae31cf5
ILT
306 intern->r_symndx = (((int) ext->r_bits[0]
307 << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
308 | ((int) ext->r_bits[1]
309 << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
310 | ((int) ext->r_bits[2]
311 << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
312 intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
313 >> RELOC_BITS3_TYPE_SH_LITTLE);
314 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
23ba15b7 315 }
c3fe0c41
ILT
316}
317
dae31cf5 318/* Swap a reloc out. */
c3fe0c41 319
dae31cf5
ILT
320static void
321mips_ecoff_swap_reloc_out (abfd, intern, dst)
f6409552 322 bfd *abfd;
dae31cf5
ILT
323 const struct internal_reloc *intern;
324 PTR dst;
c3fe0c41 325{
dae31cf5 326 RELOC *ext = (RELOC *) dst;
c3fe0c41 327
dae31cf5
ILT
328 bfd_h_put_32 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr);
329 if (abfd->xvec->header_byteorder_big_p != false)
c3fe0c41 330 {
dae31cf5
ILT
331 ext->r_bits[0] = intern->r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
332 ext->r_bits[1] = intern->r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
333 ext->r_bits[2] = intern->r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
334 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
335 & RELOC_BITS3_TYPE_BIG)
336 | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
c3fe0c41 337 }
dae31cf5 338 else
c3fe0c41 339 {
dae31cf5
ILT
340 ext->r_bits[0] = intern->r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
341 ext->r_bits[1] = intern->r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
342 ext->r_bits[2] = intern->r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
343 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
344 & RELOC_BITS3_TYPE_LITTLE)
345 | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
c3fe0c41 346 }
c3fe0c41 347}
23f44e6f
ILT
348
349/* Finish canonicalizing a reloc. Part of this is generic to all
350 ECOFF targets, and that part is in ecoff.c. The rest is done in
351 this backend routine. It must fill in the howto field. */
352
353static void
354mips_finish_reloc (abfd, intern, rptr)
355 bfd *abfd;
356 struct internal_reloc *intern;
357 arelent *rptr;
358{
359 if (intern->r_type > MIPS_R_LITERAL)
360 abort ();
361
362 if (! intern->r_extern
363 && (intern->r_type == MIPS_R_GPREL
364 || intern->r_type == MIPS_R_LITERAL))
365 rptr->addend += ecoff_data (abfd)->gp;
366
367 /* If the type is MIPS_R_IGNORE, make sure this is a reference to
368 the absolute section so that the reloc is ignored. */
369 if (intern->r_type == MIPS_R_IGNORE)
370 rptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
371
372 rptr->howto = &mips_howto_table[intern->r_type];
373}
374
375/* ECOFF relocs are either against external symbols, or against
376 sections. If we are producing relocateable output, and the reloc
377 is against an external symbol, and nothing has given us any
378 additional addend, the resulting reloc will also be against the
379 same symbol. In such a case, we don't want to change anything
380 about the way the reloc is handled, since it will all be done at
381 final link time. Rather than put special case code into
382 bfd_perform_relocation, all the reloc types use this howto
383 function. It just short circuits the reloc if producing
384 relocateable output against an external symbol. */
385
386static bfd_reloc_status_type
387mips_generic_reloc (abfd,
388 reloc_entry,
389 symbol,
390 data,
391 input_section,
392 output_bfd)
393 bfd *abfd;
394 arelent *reloc_entry;
395 asymbol *symbol;
396 PTR data;
397 asection *input_section;
398 bfd *output_bfd;
399{
400 if (output_bfd != (bfd *) NULL
401 && (symbol->flags & BSF_SECTION_SYM) == 0
402 && reloc_entry->addend == 0)
403 {
404 reloc_entry->address += input_section->output_offset;
405 return bfd_reloc_ok;
406 }
407
408 return bfd_reloc_continue;
409}
410
411/* Do a REFHI relocation. This has to be done in combination with a
412 REFLO reloc, because there is a carry from the REFLO to the REFHI.
413 Here we just save the information we need; we do the actual
414 relocation when we see the REFLO. MIPS ECOFF requires that the
415 REFLO immediately follow the REFHI, so this ought to work. */
416
417static bfd_byte *mips_refhi_addr;
418static bfd_vma mips_refhi_addend;
419
420static bfd_reloc_status_type
421mips_refhi_reloc (abfd,
422 reloc_entry,
423 symbol,
424 data,
425 input_section,
426 output_bfd)
427 bfd *abfd;
428 arelent *reloc_entry;
429 asymbol *symbol;
430 PTR data;
431 asection *input_section;
432 bfd *output_bfd;
433{
434 bfd_reloc_status_type ret;
435 bfd_vma relocation;
436
437 /* If we're relocating, and this an external symbol, we don't want
438 to change anything. */
439 if (output_bfd != (bfd *) NULL
440 && (symbol->flags & BSF_SECTION_SYM) == 0
441 && reloc_entry->addend == 0)
442 {
443 reloc_entry->address += input_section->output_offset;
444 return bfd_reloc_ok;
445 }
446
447 ret = bfd_reloc_ok;
448 if (symbol->section == &bfd_und_section
449 && output_bfd == (bfd *) NULL)
450 ret = bfd_reloc_undefined;
451
452 if (bfd_is_com_section (symbol->section))
453 relocation = 0;
454 else
455 relocation = symbol->value;
456
457 relocation += symbol->section->output_section->vma;
458 relocation += symbol->section->output_offset;
459 relocation += reloc_entry->addend;
460
461 if (reloc_entry->address > input_section->_cooked_size)
462 return bfd_reloc_outofrange;
463
464 /* Save the information, and let REFLO do the actual relocation. */
465 mips_refhi_addr = (bfd_byte *) data + reloc_entry->address;
466 mips_refhi_addend = relocation;
467
468 if (output_bfd != (bfd *) NULL)
469 reloc_entry->address += input_section->output_offset;
470
471 return ret;
472}
473
474/* Do a REFLO relocation. This is a straightforward 16 bit inplace
475 relocation; this function exists in order to do the REFHI
476 relocation described above. */
477
478static bfd_reloc_status_type
479mips_reflo_reloc (abfd,
480 reloc_entry,
481 symbol,
482 data,
483 input_section,
484 output_bfd)
485 bfd *abfd;
486 arelent *reloc_entry;
487 asymbol *symbol;
488 PTR data;
489 asection *input_section;
490 bfd *output_bfd;
491{
492 if (mips_refhi_addr != (bfd_byte *) NULL)
493 {
494 unsigned long insn;
495 unsigned long val;
496 unsigned long vallo;
497
498 /* Do the REFHI relocation. Note that we actually don't need to
499 know anything about the REFLO itself, except where to find
500 the low 16 bits of the addend needed by the REFHI. */
501 insn = bfd_get_32 (abfd, mips_refhi_addr);
502 vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
503 & 0xffff);
504 val = ((insn & 0xffff) << 16) + vallo;
505 val += mips_refhi_addend;
506
507 /* The low order 16 bits are always treated as a signed value.
508 Therefore, a negative value in the low order bits requires an
509 adjustment in the high order bits. We need to make this
510 adjustment in two ways: once for the bits we took from the
511 data, and once for the bits we are putting back in to the
512 data. */
513 if ((vallo & 0x8000) != 0)
514 val -= 0x10000;
515 if ((val & 0x8000) != 0)
516 val += 0x10000;
517
518 insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
519 bfd_put_32 (abfd, insn, mips_refhi_addr);
520
521 mips_refhi_addr = (bfd_byte *) NULL;
522 }
523
524 /* Now do the REFLO reloc in the usual way. */
525 return mips_generic_reloc (abfd, reloc_entry, symbol, data,
526 input_section, output_bfd);
527}
528
529/* Do a GPREL relocation. This is a 16 bit value which must become
530 the offset from the gp register. */
531
532static bfd_reloc_status_type
533mips_gprel_reloc (abfd,
534 reloc_entry,
535 symbol,
536 data,
537 input_section,
538 output_bfd)
539 bfd *abfd;
540 arelent *reloc_entry;
541 asymbol *symbol;
542 PTR data;
543 asection *input_section;
544 bfd *output_bfd;
545{
546 boolean relocateable;
547 bfd_vma relocation;
548 unsigned long val;
549 unsigned long insn;
550
551 /* If we're relocating, and this is an external symbol with no
552 addend, we don't want to change anything. We will only have an
553 addend if this is a newly created reloc, not read from an ECOFF
554 file. */
555 if (output_bfd != (bfd *) NULL
556 && (symbol->flags & BSF_SECTION_SYM) == 0
557 && reloc_entry->addend == 0)
558 {
559 reloc_entry->address += input_section->output_offset;
560 return bfd_reloc_ok;
561 }
562
563 if (output_bfd != (bfd *) NULL)
564 relocateable = true;
565 else
566 {
567 relocateable = false;
568 output_bfd = symbol->section->output_section->owner;
569 }
570
571 if (symbol->section == &bfd_und_section
572 && relocateable == false)
573 return bfd_reloc_undefined;
574
575 /* We have to figure out the gp value, so that we can adjust the
576 symbol value correctly. We look up the symbol _gp in the output
577 BFD. If we can't find it, we're stuck. We cache it in the ECOFF
578 target data. We don't need to adjust the symbol value for an
579 external symbol if we are producing relocateable output. */
580 if (ecoff_data (output_bfd)->gp == 0
581 && (relocateable == false
582 || (symbol->flags & BSF_SECTION_SYM) != 0))
583 {
584 if (relocateable != false)
585 {
586 /* Make up a value. */
587 ecoff_data (output_bfd)->gp =
588 symbol->section->output_section->vma + 0x4000;
589 }
590 else
591 {
592 unsigned int count;
593 asymbol **sym;
594 unsigned int i;
595
596 count = bfd_get_symcount (output_bfd);
597 sym = bfd_get_outsymbols (output_bfd);
598
599 if (sym == (asymbol **) NULL)
600 i = count;
601 else
602 {
603 for (i = 0; i < count; i++, sym++)
604 {
605 register CONST char *name;
606
607 name = bfd_asymbol_name (*sym);
608 if (*name == '_' && strcmp (name, "_gp") == 0)
609 {
610 ecoff_data (output_bfd)->gp = bfd_asymbol_value (*sym);
611 break;
612 }
613 }
614 }
615
616 if (i >= count)
617 {
618 /* Only get the error once. */
619 ecoff_data (output_bfd)->gp = 4;
620 /* FIXME: How can we get the program name here? */
621 fprintf (stderr,
622 "GP relative relocation when _gp not defined\n");
623 return bfd_reloc_dangerous;
624 }
625 }
626 }
627
628 if (bfd_is_com_section (symbol->section))
629 relocation = 0;
630 else
631 relocation = symbol->value;
632
633 relocation += symbol->section->output_section->vma;
634 relocation += symbol->section->output_offset;
635
636 if (reloc_entry->address > input_section->_cooked_size)
637 return bfd_reloc_outofrange;
638
639 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
640
641 /* Set val to the offset into the section or symbol. */
642 val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
643 if (val & 0x8000)
644 val -= 0x10000;
645
646 /* Adjust val for the final section location and GP value. If we
647 are producing relocateable output, we don't want to do this for
648 an external symbol. */
649 if (relocateable == false
650 || (symbol->flags & BSF_SECTION_SYM) != 0)
651 val += relocation - ecoff_data (output_bfd)->gp;
652
653 insn = (insn &~ 0xffff) | (val & 0xffff);
654 bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
655
656 if (relocateable != false)
657 reloc_entry->address += input_section->output_offset;
658
659 /* Make sure it fit in 16 bits. */
660 if (val >= 0x8000 && val < 0xffff8000)
661 return bfd_reloc_outofrange;
662
663 return bfd_reloc_ok;
664}
665
666/* Get the howto structure for a generic reloc type. */
667
668static CONST struct reloc_howto_struct *
669mips_bfd_reloc_type_lookup (abfd, code)
670 bfd *abfd;
671 bfd_reloc_code_real_type code;
672{
673 int mips_type;
674
675 switch (code)
676 {
677 case BFD_RELOC_16:
678 mips_type = MIPS_R_REFHALF;
679 break;
680 case BFD_RELOC_32:
681 mips_type = MIPS_R_REFWORD;
682 break;
683 case BFD_RELOC_MIPS_JMP:
684 mips_type = MIPS_R_JMPADDR;
685 break;
686 case BFD_RELOC_HI16_S:
687 mips_type = MIPS_R_REFHI;
688 break;
689 case BFD_RELOC_LO16:
690 mips_type = MIPS_R_REFLO;
691 break;
692 case BFD_RELOC_MIPS_GPREL:
693 mips_type = MIPS_R_GPREL;
694 break;
695 default:
696 return (CONST struct reloc_howto_struct *) NULL;
697 }
698
699 return &mips_howto_table[mips_type];
700}
c3fe0c41 701\f
de17306e
ILT
702#ifdef HOST_IRIX4
703
704#include <core.out.h>
705
706struct sgi_core_struct
707{
708 int sig;
709 char cmd[CORE_NAMESIZE];
710};
711
712#define core_hdr(bfd) ((bfd)->tdata.sgi_core_data)
713#define core_signal(bfd) (core_hdr(bfd)->sig)
714#define core_command(bfd) (core_hdr(bfd)->cmd)
715
716static asection *
717make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
718 bfd *abfd;
719 CONST char *name;
720 flagword flags;
721 bfd_size_type _raw_size;
722 bfd_vma vma;
723 file_ptr filepos;
724{
725 asection *asect;
726
727 asect = bfd_make_section (abfd, name);
728 if (!asect)
729 return NULL;
730
731 asect->flags = flags;
732 asect->_raw_size = _raw_size;
733 asect->vma = vma;
734 asect->filepos = filepos;
735 asect->alignment_power = 4;
736
737 return asect;
738}
739
740static bfd_target *
741ecoff_core_file_p (abfd)
742 bfd *abfd;
743{
744 int val;
745 int i;
746 char *secname;
747 struct coreout coreout;
748 struct idesc *idg, *idf, *ids;
749
750 val = bfd_read ((PTR)&coreout, 1, sizeof coreout, abfd);
751 if (val != sizeof coreout)
752 return 0;
753
754 if (coreout.c_magic != CORE_MAGIC
755 || coreout.c_version != CORE_VERSION1)
756 return 0;
757
758 core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, sizeof (struct sgi_core_struct));
759 if (!core_hdr (abfd))
760 return NULL;
761
762 strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE);
763 core_signal (abfd) = coreout.c_sigcause;
764
765 bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET);
766
767 for (i = 0; i < coreout.c_nvmap; i++)
768 {
769 struct vmap vmap;
770
771 val = bfd_read ((PTR)&vmap, 1, sizeof vmap, abfd);
772 if (val != sizeof vmap)
773 break;
774
775 switch (vmap.v_type)
776 {
777 case VDATA:
778 secname = ".data";
779 break;
780 case VSTACK:
781 secname = ".stack";
782 break;
783 default:
784 continue;
785 }
786
787 if (!make_bfd_asection (abfd, secname,
788 SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
789 vmap.v_len,
790 vmap.v_vaddr,
791 vmap.v_offset,
792 2))
793 return NULL;
794 }
795
796 /* Make sure that the regs are contiguous within the core file. */
797
798 idg = &coreout.c_idesc[I_GPREGS];
799 idf = &coreout.c_idesc[I_FPREGS];
800 ids = &coreout.c_idesc[I_SPECREGS];
801
802 if (idg->i_offset + idg->i_len != idf->i_offset
803 || idf->i_offset + idf->i_len != ids->i_offset)
804 return 0; /* Can't deal with non-contig regs */
805
806 bfd_seek (abfd, idg->i_offset, SEEK_SET);
807
808 make_bfd_asection (abfd, ".reg",
809 SEC_ALLOC+SEC_HAS_CONTENTS,
810 idg->i_len + idf->i_len + ids->i_len,
811 0,
812 idg->i_offset);
813
814 /* OK, we believe you. You're a core file (sure, sure). */
815
816 return abfd->xvec;
817}
818
819static char *
820ecoff_core_file_failing_command (abfd)
821 bfd *abfd;
822{
823 return core_command (abfd);
824}
825
826static int
827ecoff_core_file_failing_signal (abfd)
828 bfd *abfd;
829{
830 return core_signal (abfd);
831}
832
833static boolean
834ecoff_core_file_matches_executable_p (core_bfd, exec_bfd)
835 bfd *core_bfd, *exec_bfd;
836{
837 return true; /* XXX - FIXME */
838}
839#else /* not def HOST_IRIX4 */
840#define ecoff_core_file_p _bfd_dummy_target
841#define ecoff_core_file_failing_command _bfd_dummy_core_file_failing_command
842#define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
843#define ecoff_core_file_matches_executable_p \
844 _bfd_dummy_core_file_matches_executable_p
845#endif
846\f
23f44e6f
ILT
847/* This is the ECOFF backend structure. The backend field of the
848 target vector points to this. */
849
850static const struct ecoff_backend_data mips_ecoff_backend_data =
851{
852 /* COFF backend structure. */
853 {
854 (void (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_in */
855 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
856 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
857 (unsigned (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_out */
858 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
859 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
860 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
861 mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
862 mips_ecoff_swap_scnhdr_out,
863 FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, true,
864 mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
865 mips_ecoff_swap_scnhdr_in, mips_ecoff_bad_format_hook,
866 ecoff_set_arch_mach_hook, mips_ecoff_mkobject_hook,
867 ecoff_styp_to_sec_flags, ecoff_make_section_hook, ecoff_set_alignment_hook,
868 ecoff_slurp_symbol_table, NULL, NULL
869 },
870 /* Supported architecture. */
871 bfd_arch_mips,
872 /* Big endian magic number. */
873 MIPS_MAGIC_BIG,
874 /* Little endian magic number. */
875 MIPS_MAGIC_LITTLE,
876 /* Symbol table magic number. */
877 magicSym,
878 /* Initial portion of armap string. */
879 "__________",
880 /* Alignment of debugging information. E.g., 4. */
881 4,
882 /* The page boundary used to align sections in a demand-paged
883 executable file. E.g., 0x1000. */
884 0x1000,
885 /* Bitsize of constructor entries. */
886 32,
887 /* Reloc to use for constructor entries. */
888 &mips_howto_table[MIPS_R_REFWORD],
889 /* Sizes of external symbolic information. */
890 sizeof (struct hdr_ext),
891 sizeof (struct dnr_ext),
892 sizeof (struct pdr_ext),
893 sizeof (struct sym_ext),
894 sizeof (struct opt_ext),
895 sizeof (struct fdr_ext),
896 sizeof (struct rfd_ext),
897 sizeof (struct ext_ext),
898 /* Functions to swap in external symbolic data. */
899 ecoff_swap_hdr_in,
900 ecoff_swap_dnr_in,
901 ecoff_swap_pdr_in,
902 ecoff_swap_sym_in,
903 ecoff_swap_opt_in,
904 ecoff_swap_fdr_in,
905 ecoff_swap_rfd_in,
906 ecoff_swap_ext_in,
907 /* Functions to swap out external symbolic data. */
908 ecoff_swap_hdr_out,
909 ecoff_swap_dnr_out,
910 ecoff_swap_pdr_out,
911 ecoff_swap_sym_out,
912 ecoff_swap_opt_out,
913 ecoff_swap_fdr_out,
914 ecoff_swap_rfd_out,
915 ecoff_swap_ext_out,
916 /* External reloc size. */
917 RELSZ,
918 /* Reloc swapping functions. */
919 mips_ecoff_swap_reloc_in,
920 mips_ecoff_swap_reloc_out,
921 /* Backend reloc tweaking. */
922 mips_finish_reloc
515c4292
ILT
923};
924
23f44e6f
ILT
925/* Looking up a reloc type is MIPS specific. */
926#define ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
927
1327fb29 928bfd_target ecoff_little_vec =
294eaca4
SC
929{
930 "ecoff-littlemips", /* name */
515c4292 931 bfd_target_ecoff_flavour,
294eaca4
SC
932 false, /* data byte order is little */
933 false, /* header byte order is little */
934
935 (HAS_RELOC | EXEC_P | /* object flags */
936 HAS_LINENO | HAS_DEBUG |
de17306e 937 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
294eaca4
SC
938
939 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect
940 flags */
941 0, /* leading underscore */
de17306e 942 ' ', /* ar_pad_char */
294eaca4 943 15, /* ar_max_namelen */
de17306e 944 4, /* minimum alignment power */
23f44e6f
ILT
945 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
946 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
947 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
948 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
949 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
950 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
294eaca4 951
515c4292 952 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
c3fe0c41 953 ecoff_archive_p, _bfd_dummy_target},
23f44e6f 954 {bfd_false, ecoff_mkobject, /* bfd_set_format */
dae31cf5 955 _bfd_generic_mkarchive, bfd_false},
c3fe0c41
ILT
956 {bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
957 _bfd_write_archive_contents, bfd_false},
515c4292 958 JUMP_TABLE (ecoff),
23f44e6f 959 (PTR) &mips_ecoff_backend_data
515c4292 960};
1327fb29
SC
961
962bfd_target ecoff_big_vec =
294eaca4
SC
963{
964 "ecoff-bigmips", /* name */
515c4292 965 bfd_target_ecoff_flavour,
294eaca4
SC
966 true, /* data byte order is big */
967 true, /* header byte order is big */
968
969 (HAS_RELOC | EXEC_P | /* object flags */
970 HAS_LINENO | HAS_DEBUG |
de17306e 971 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
294eaca4
SC
972
973 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect flags */
974 0, /* leading underscore */
975 ' ', /* ar_pad_char */
de17306e
ILT
976 15, /* ar_max_namelen */
977 4, /* minimum alignment power */
23f44e6f
ILT
978 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
979 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
980 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
981 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
982 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
983 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
294eaca4 984 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
de17306e 985 ecoff_archive_p, ecoff_core_file_p},
23f44e6f 986 {bfd_false, ecoff_mkobject, /* bfd_set_format */
dae31cf5 987 _bfd_generic_mkarchive, bfd_false},
515c4292 988 {bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
c3fe0c41 989 _bfd_write_archive_contents, bfd_false},
515c4292 990 JUMP_TABLE(ecoff),
23f44e6f 991 (PTR) &mips_ecoff_backend_data
515c4292
ILT
992 /* Note that there is another bfd_target just above this one. If
993 you are adding initializers here, you should be adding them there
994 as well. */
995};
This page took 0.132432 seconds and 4 git commands to generate.