[ bfd/ChangeLog ]
[deliverable/binutils-gdb.git] / bfd / pe-mips.c
CommitLineData
17505c5c 1/* BFD back-end for MIPS PE COFF files.
7898deda 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
1049f94e 3 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
17505c5c
NC
4 Modified from coff-i386.c by DJ Delorie, dj@cygnus.com
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
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
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22#define COFF_WITH_PE
23#define COFF_LONG_SECTION_NAMES
b34976b6 24#define PCRELOFFSET TRUE
17505c5c
NC
25
26#include "bfd.h"
27#include "sysdep.h"
28#include "libbfd.h"
29
30#include "coff/mipspe.h"
31
32#include "coff/internal.h"
33
34#include "coff/pe.h"
35
36#include "libcoff.h"
37
892339ee 38static bfd_reloc_status_type coff_mips_reloc
17505c5c
NC
39 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
40static reloc_howto_type *coff_mips_rtype_to_howto
41 PARAMS ((bfd *, asection *, struct internal_reloc *,
42 struct coff_link_hash_entry *, struct internal_syment *,
17505c5c 43 bfd_vma *));
42ef282f 44
b34976b6
AM
45static bfd_boolean in_reloc_p
46 PARAMS ((bfd *, reloc_howto_type *));
47static reloc_howto_type * coff_mips_reloc_type_lookup
48 PARAMS ((bfd *, bfd_reloc_code_real_type));
49static void mips_swap_reloc_in
50 PARAMS ((bfd *, PTR, PTR));
51static unsigned int mips_swap_reloc_out
52 PARAMS ((bfd *, PTR, PTR));
53static bfd_boolean coff_pe_mips_relocate_section
42ef282f
NC
54 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
55 struct internal_reloc *, struct internal_syment *, asection **));
56
17505c5c
NC
57#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
58/* The page size is a guess based on ELF. */
59
60#define COFF_PAGE_SIZE 0x1000
61
62/* For some reason when using mips COFF the value stored in the .text
63 section for a reference to a common symbol is the value itself plus
64 any desired offset. Ian Taylor, Cygnus Support. */
65
1049f94e 66/* If we are producing relocatable output, we need to do some
17505c5c
NC
67 adjustments to the object file that are not done by the
68 bfd_perform_relocation function. This function is called by every
69 reloc type to make any required adjustments. */
70
71static bfd_reloc_status_type
72coff_mips_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
73 error_message)
74 bfd *abfd;
75 arelent *reloc_entry;
76 asymbol *symbol;
77 PTR data;
86033394 78 asection *input_section ATTRIBUTE_UNUSED;
17505c5c 79 bfd *output_bfd;
86033394 80 char **error_message ATTRIBUTE_UNUSED;
17505c5c
NC
81{
82 symvalue diff;
83
84 if (output_bfd == (bfd *) NULL)
85 return bfd_reloc_continue;
86
87 if (bfd_is_com_section (symbol->section))
88 {
89#ifndef COFF_WITH_PE
90 /* We are relocating a common symbol. The current value in the
91 object file is ORIG + OFFSET, where ORIG is the value of the
92 common symbol as seen by the object file when it was compiled
93 (this may be zero if the symbol was undefined) and OFFSET is
94 the offset into the common symbol (normally zero, but may be
95 non-zero when referring to a field in a common structure).
96 ORIG is the negative of reloc_entry->addend, which is set by
97 the CALC_ADDEND macro below. We want to replace the value in
98 the object file with NEW + OFFSET, where NEW is the value of
99 the common symbol which we are going to put in the final
100 object file. NEW is symbol->value. */
101 diff = symbol->value + reloc_entry->addend;
102#else
103 /* In PE mode, we do not offset the common symbol. */
104 diff = reloc_entry->addend;
105#endif
106 }
107 else
108 {
109 /* For some reason bfd_perform_relocation always effectively
110 ignores the addend for a COFF target when producing
1049f94e 111 relocatable output. This seems to be always wrong for 386
17505c5c
NC
112 COFF, so we handle the addend here instead. */
113 diff = reloc_entry->addend;
114 }
115
116#ifdef COFF_WITH_PE
117#if 0
118 /* dj - handle it like any other reloc? */
119 /* FIXME: How should this case be handled? */
120 if (reloc_entry->howto->type == MIPS_R_RVA && diff != 0)
121 abort ();
122#endif
123#endif
124
125#define DOIT(x) \
126 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + (diff >> howto->rightshift)) & howto->dst_mask))
127
128 if (diff != 0)
129 {
130 reloc_howto_type *howto = reloc_entry->howto;
131 unsigned char *addr = (unsigned char *) data + reloc_entry->address;
132
133 switch (howto->size)
134 {
135 case 0:
136 {
137 char x = bfd_get_8 (abfd, addr);
138 DOIT (x);
139 bfd_put_8 (abfd, x, addr);
140 }
141 break;
142
143 case 1:
144 {
145 short x = bfd_get_16 (abfd, addr);
146 DOIT (x);
dc810e39 147 bfd_put_16 (abfd, (bfd_vma) x, addr);
17505c5c
NC
148 }
149 break;
150
151 case 2:
152 {
153 long x = bfd_get_32 (abfd, addr);
154 DOIT (x);
dc810e39 155 bfd_put_32 (abfd, (bfd_vma) x, addr);
17505c5c
NC
156 }
157 break;
158
159 default:
160 abort ();
161 }
162 }
163
164 /* Now let bfd_perform_relocation finish everything up. */
165 return bfd_reloc_continue;
166}
167
168#ifdef COFF_WITH_PE
b34976b6 169/* Return TRUE if this relocation should
892339ee 170 appear in the output .reloc section. */
17505c5c 171
b34976b6 172static bfd_boolean
42ef282f 173in_reloc_p (abfd, howto)
86033394 174 bfd * abfd ATTRIBUTE_UNUSED;
17505c5c
NC
175 reloc_howto_type *howto;
176{
177 return ! howto->pc_relative && howto->type != MIPS_R_RVA;
892339ee 178}
17505c5c
NC
179#endif
180
181#ifndef PCRELOFFSET
b34976b6 182#define PCRELOFFSET FALSE
17505c5c
NC
183#endif
184
892339ee 185static reloc_howto_type howto_table[] =
17505c5c
NC
186{
187 /* Reloc type 0 is ignored. The reloc reading code ensures that
188 this is a reference to the .abs section, which will cause
189 bfd_perform_relocation to do nothing. */
190 HOWTO (MIPS_R_ABSOLUTE, /* type */
191 0, /* rightshift */
192 0, /* size (0 = byte, 1 = short, 2 = long) */
193 8, /* bitsize */
b34976b6 194 FALSE, /* pc_relative */
17505c5c
NC
195 0, /* bitpos */
196 complain_overflow_dont, /* complain_on_overflow */
197 0, /* special_function */
198 "IGNORE", /* name */
b34976b6 199 FALSE, /* partial_inplace */
17505c5c
NC
200 0, /* src_mask */
201 0, /* dst_mask */
b34976b6 202 FALSE), /* pcrel_offset */
17505c5c
NC
203
204 /* A 16 bit reference to a symbol, normally from a data section. */
205 HOWTO (MIPS_R_REFHALF, /* type */
206 0, /* rightshift */
207 1, /* size (0 = byte, 1 = short, 2 = long) */
208 16, /* bitsize */
b34976b6 209 FALSE, /* pc_relative */
17505c5c
NC
210 0, /* bitpos */
211 complain_overflow_bitfield, /* complain_on_overflow */
212 coff_mips_reloc, /* special_function */
213 "REFHALF", /* name */
b34976b6 214 TRUE, /* partial_inplace */
17505c5c
NC
215 0xffff, /* src_mask */
216 0xffff, /* dst_mask */
b34976b6 217 FALSE), /* pcrel_offset */
17505c5c
NC
218
219 /* A 32 bit reference to a symbol, normally from a data section. */
220 HOWTO (MIPS_R_REFWORD, /* type */
221 0, /* rightshift */
222 2, /* size (0 = byte, 1 = short, 2 = long) */
223 32, /* bitsize */
b34976b6 224 FALSE, /* pc_relative */
17505c5c
NC
225 0, /* bitpos */
226 complain_overflow_bitfield, /* complain_on_overflow */
227 coff_mips_reloc, /* special_function */
228 "REFWORD", /* name */
b34976b6 229 TRUE, /* partial_inplace */
17505c5c
NC
230 0xffffffff, /* src_mask */
231 0xffffffff, /* dst_mask */
b34976b6 232 FALSE), /* pcrel_offset */
17505c5c
NC
233
234 /* A 26 bit absolute jump address. */
235 HOWTO (MIPS_R_JMPADDR, /* type */
236 2, /* rightshift */
237 2, /* size (0 = byte, 1 = short, 2 = long) */
238 26, /* bitsize */
b34976b6 239 FALSE, /* pc_relative */
17505c5c
NC
240 0, /* bitpos */
241 complain_overflow_dont, /* complain_on_overflow */
242 /* This needs complex overflow
243 detection, because the upper four
244 bits must match the PC. */
245 coff_mips_reloc, /* special_function */
246 "JMPADDR", /* name */
b34976b6 247 TRUE, /* partial_inplace */
17505c5c
NC
248 0x3ffffff, /* src_mask */
249 0x3ffffff, /* dst_mask */
b34976b6 250 FALSE), /* pcrel_offset */
17505c5c
NC
251
252 /* The high 16 bits of a symbol value. Handled by the function
253 mips_refhi_reloc. */
254 HOWTO (MIPS_R_REFHI, /* type */
255 16, /* rightshift */
256 2, /* size (0 = byte, 1 = short, 2 = long) */
257 16, /* bitsize */
b34976b6 258 FALSE, /* pc_relative */
17505c5c
NC
259 0, /* bitpos */
260 complain_overflow_bitfield, /* complain_on_overflow */
261 coff_mips_reloc, /* special_function */
262 "REFHI", /* name */
b34976b6 263 TRUE, /* partial_inplace */
17505c5c
NC
264 0xffff, /* src_mask */
265 0xffff, /* dst_mask */
b34976b6 266 FALSE), /* pcrel_offset */
17505c5c
NC
267
268 /* The low 16 bits of a symbol value. */
269 HOWTO (MIPS_R_REFLO, /* type */
270 0, /* rightshift */
271 2, /* size (0 = byte, 1 = short, 2 = long) */
272 16, /* bitsize */
b34976b6 273 FALSE, /* pc_relative */
17505c5c
NC
274 0, /* bitpos */
275 complain_overflow_dont, /* complain_on_overflow */
276 coff_mips_reloc, /* special_function */
277 "REFLO", /* name */
b34976b6 278 TRUE, /* partial_inplace */
17505c5c
NC
279 0xffff, /* src_mask */
280 0xffff, /* dst_mask */
b34976b6 281 FALSE), /* pcrel_offset */
17505c5c
NC
282
283 /* A reference to an offset from the gp register. Handled by the
284 function mips_gprel_reloc. */
285 HOWTO (MIPS_R_GPREL, /* type */
286 0, /* rightshift */
287 2, /* size (0 = byte, 1 = short, 2 = long) */
288 16, /* bitsize */
b34976b6 289 FALSE, /* pc_relative */
17505c5c
NC
290 0, /* bitpos */
291 complain_overflow_signed, /* complain_on_overflow */
292 coff_mips_reloc, /* special_function */
293 "GPREL", /* name */
b34976b6 294 TRUE, /* partial_inplace */
17505c5c
NC
295 0xffff, /* src_mask */
296 0xffff, /* dst_mask */
b34976b6 297 FALSE), /* pcrel_offset */
17505c5c
NC
298
299 /* A reference to a literal using an offset from the gp register.
300 Handled by the function mips_gprel_reloc. */
301 HOWTO (MIPS_R_LITERAL, /* type */
302 0, /* rightshift */
303 2, /* size (0 = byte, 1 = short, 2 = long) */
304 16, /* bitsize */
b34976b6 305 FALSE, /* pc_relative */
17505c5c
NC
306 0, /* bitpos */
307 complain_overflow_signed, /* complain_on_overflow */
308 coff_mips_reloc, /* special_function */
309 "LITERAL", /* name */
b34976b6 310 TRUE, /* partial_inplace */
17505c5c
NC
311 0xffff, /* src_mask */
312 0xffff, /* dst_mask */
b34976b6 313 FALSE), /* pcrel_offset */
17505c5c 314
86033394
NC
315 EMPTY_HOWTO (8),
316 EMPTY_HOWTO (9),
317 EMPTY_HOWTO (10),
318 EMPTY_HOWTO (11),
319 EMPTY_HOWTO (12),
320 EMPTY_HOWTO (13),
321 EMPTY_HOWTO (14),
322 EMPTY_HOWTO (15),
323 EMPTY_HOWTO (16),
324 EMPTY_HOWTO (17),
325 EMPTY_HOWTO (18),
326 EMPTY_HOWTO (19),
327 EMPTY_HOWTO (20),
328 EMPTY_HOWTO (21),
329 EMPTY_HOWTO (22),
330 EMPTY_HOWTO (23),
331 EMPTY_HOWTO (24),
332 EMPTY_HOWTO (25),
333 EMPTY_HOWTO (26),
334 EMPTY_HOWTO (27),
335 EMPTY_HOWTO (28),
336 EMPTY_HOWTO (29),
337 EMPTY_HOWTO (30),
338 EMPTY_HOWTO (31),
339 EMPTY_HOWTO (32),
340 EMPTY_HOWTO (33),
892339ee
KH
341 HOWTO (MIPS_R_RVA, /* type */
342 0, /* rightshift */
343 2, /* size (0 = byte, 1 = short, 2 = long) */
344 32, /* bitsize */
b34976b6 345 FALSE, /* pc_relative */
892339ee 346 0, /* bitpos */
17505c5c 347 complain_overflow_bitfield, /* complain_on_overflow */
892339ee
KH
348 coff_mips_reloc, /* special_function */
349 "rva32", /* name */
b34976b6 350 TRUE, /* partial_inplace */
892339ee
KH
351 0xffffffff, /* src_mask */
352 0xffffffff, /* dst_mask */
b34976b6 353 FALSE), /* pcrel_offset */
86033394
NC
354 EMPTY_HOWTO (35),
355 EMPTY_HOWTO (36),
892339ee
KH
356 HOWTO (MIPS_R_PAIR, /* type */
357 0, /* rightshift */
358 2, /* size (0 = byte, 1 = short, 2 = long) */
359 32, /* bitsize */
b34976b6 360 FALSE, /* pc_relative */
892339ee 361 0, /* bitpos */
17505c5c 362 complain_overflow_bitfield, /* complain_on_overflow */
892339ee
KH
363 coff_mips_reloc, /* special_function */
364 "PAIR", /* name */
b34976b6 365 TRUE, /* partial_inplace */
892339ee
KH
366 0xffffffff, /* src_mask */
367 0xffffffff, /* dst_mask */
b34976b6 368 FALSE), /* pcrel_offset */
17505c5c
NC
369};
370
371/* Turn a howto into a reloc nunmber */
372
373#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
374#define BADMAG(x) MIPSBADMAG(x)
375#define MIPS 1 /* Customize coffcode.h */
376
377#define RTYPE2HOWTO(cache_ptr, dst) \
378 (cache_ptr)->howto = howto_table + (dst)->r_type;
379
380/* Compute the addend of a reloc. If the reloc is to a common symbol,
381 the object file contains the value of the common symbol. By the
382 time this is called, the linker may be using a different symbol
383 from a different object file with a different value. Therefore, we
384 hack wildly to locate the original symbol from this file so that we
385 can make the correct adjustment. This macro sets coffsym to the
386 symbol from the original file, and uses it to set the addend value
387 correctly. If this is not a common symbol, the usual addend
388 calculation is done, except that an additional tweak is needed for
389 PC relative relocs.
390 FIXME: This macro refers to symbols and asect; these are from the
391 calling function, not the macro arguments. */
392
393#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
394 { \
395 coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
396 if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
397 coffsym = (obj_symbols (abfd) \
398 + (cache_ptr->sym_ptr_ptr - symbols)); \
399 else if (ptr) \
400 coffsym = coff_symbol_from (abfd, ptr); \
401 if (coffsym != (coff_symbol_type *) NULL \
402 && coffsym->native->u.syment.n_scnum == 0) \
403 cache_ptr->addend = - coffsym->native->u.syment.n_value; \
404 else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
405 && ptr->section != (asection *) NULL) \
406 cache_ptr->addend = - (ptr->section->vma + ptr->value); \
407 else \
408 cache_ptr->addend = 0; \
409 if (ptr && howto_table[reloc.r_type].pc_relative) \
410 cache_ptr->addend += asect->vma; \
411 }
412
17505c5c
NC
413/* Convert an rtype to howto for the COFF backend linker. */
414
415static reloc_howto_type *
416coff_mips_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
86033394 417 bfd *abfd ATTRIBUTE_UNUSED;
17505c5c
NC
418 asection *sec;
419 struct internal_reloc *rel;
420 struct coff_link_hash_entry *h;
421 struct internal_syment *sym;
422 bfd_vma *addendp;
423{
424
425 reloc_howto_type *howto;
426
427 howto = howto_table + rel->r_type;
428
429#ifdef COFF_WITH_PE
430 *addendp = 0;
431#endif
432
433 if (howto->pc_relative)
434 *addendp += sec->vma;
435
436 if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
437 {
438 /* This is a common symbol. The section contents include the
439 size (sym->n_value) as an addend. The relocate_section
440 function will be adding in the final value of the symbol. We
441 need to subtract out the current size in order to get the
442 correct result. */
892339ee 443
17505c5c
NC
444 BFD_ASSERT (h != NULL);
445
446#ifndef COFF_WITH_PE
447 /* I think we *do* want to bypass this. If we don't, I have
448 seen some data parameters get the wrong relocation address.
449 If I link two versions with and without this section bypassed
450 and then do a binary comparison, the addresses which are
451 different can be looked up in the map. The case in which
452 this section has been bypassed has addresses which correspond
453 to values I can find in the map. */
454 *addendp -= sym->n_value;
455#endif
456 }
457
458#ifndef COFF_WITH_PE
459 /* If the output symbol is common (in which case this must be a
1049f94e 460 relocatable link), we need to add in the final size of the
17505c5c 461 common symbol. */
892339ee 462 if (h != NULL && h->root.type == bfd_link_hash_common)
17505c5c
NC
463 *addendp += h->root.u.c.size;
464#endif
465
466#ifdef COFF_WITH_PE
467 if (howto->pc_relative)
468 {
469 *addendp -= 4;
470
471 /* If the symbol is defined, then the generic code is going to
472 add back the symbol value in order to cancel out an
473 adjustment it made to the addend. However, we set the addend
474 to 0 at the start of this function. We need to adjust here,
475 to avoid the adjustment the generic code will make. FIXME:
476 This is getting a bit hackish. */
477 if (sym != NULL && sym->n_scnum != 0)
478 *addendp -= sym->n_value;
479 }
480
481 if (rel->r_type == MIPS_R_RVA)
482 {
483 *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
484 }
485#endif
486
487 return howto;
488}
489
490#define coff_rtype_to_howto coff_mips_rtype_to_howto
491
17505c5c
NC
492#define coff_bfd_reloc_type_lookup coff_mips_reloc_type_lookup
493
17505c5c
NC
494/* Get the howto structure for a generic reloc type. */
495
496static reloc_howto_type *
497coff_mips_reloc_type_lookup (abfd, code)
86033394 498 bfd *abfd ATTRIBUTE_UNUSED;
17505c5c
NC
499 bfd_reloc_code_real_type code;
500{
501 int mips_type;
502
503 switch (code)
504 {
505 case BFD_RELOC_16:
506 mips_type = MIPS_R_REFHALF;
507 break;
508 case BFD_RELOC_32:
509 case BFD_RELOC_CTOR:
510 mips_type = MIPS_R_REFWORD;
511 break;
512 case BFD_RELOC_MIPS_JMP:
513 mips_type = MIPS_R_JMPADDR;
514 break;
515 case BFD_RELOC_HI16_S:
516 mips_type = MIPS_R_REFHI;
517 break;
518 case BFD_RELOC_LO16:
519 mips_type = MIPS_R_REFLO;
520 break;
cdf6fd85 521 case BFD_RELOC_GPREL16:
17505c5c
NC
522 mips_type = MIPS_R_GPREL;
523 break;
524 case BFD_RELOC_MIPS_LITERAL:
525 mips_type = MIPS_R_LITERAL;
526 break;
17505c5c
NC
527 case BFD_RELOC_RVA:
528 mips_type = MIPS_R_RVA;
529 break;
530 default:
531 return (reloc_howto_type *) NULL;
532 }
533
534 return &howto_table[mips_type];
535}
536
537static void
538mips_swap_reloc_in (abfd, src, dst)
539 bfd *abfd;
540 PTR src;
541 PTR dst;
542{
543 static struct internal_reloc pair_prev;
544 RELOC *reloc_src = (RELOC *) src;
545 struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
546
dc810e39
AM
547 reloc_dst->r_vaddr = H_GET_32 (abfd, reloc_src->r_vaddr);
548 reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
549 reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type);
17505c5c
NC
550 reloc_dst->r_size = 0;
551 reloc_dst->r_extern = 0;
552 reloc_dst->r_offset = 0;
553
554 switch (reloc_dst->r_type)
555 {
556 case MIPS_R_REFHI:
557 pair_prev = *reloc_dst;
558 break;
559 case MIPS_R_PAIR:
560 reloc_dst->r_offset = reloc_dst->r_symndx;
561 if (reloc_dst->r_offset & 0x8000)
562 reloc_dst->r_offset -= 0x10000;
892339ee 563 /*printf ("dj: pair offset is %08x\n", reloc_dst->r_offset);*/
17505c5c
NC
564 reloc_dst->r_symndx = pair_prev.r_symndx;
565 break;
566 }
567}
568
569static unsigned int
570mips_swap_reloc_out (abfd, src, dst)
571 bfd *abfd;
572 PTR src;
573 PTR dst;
574{
575 static int prev_offset = 1;
576 static bfd_vma prev_addr = 0;
577 struct internal_reloc *reloc_src = (struct internal_reloc *)src;
578 struct external_reloc *reloc_dst = (struct external_reloc *)dst;
579
580 switch (reloc_src->r_type)
581 {
582 case MIPS_R_REFHI:
583 prev_addr = reloc_src->r_vaddr;
584 prev_offset = reloc_src->r_offset;
585 break;
586 case MIPS_R_REFLO:
587 if (reloc_src->r_vaddr == prev_addr)
588 {
589 /* FIXME: only slightly hackish. If we see a REFLO pointing to
590 the same address as a REFHI, we assume this is the matching
591 PAIR reloc and output it accordingly. The symndx is really
592 the low 16 bits of the addend */
dc810e39
AM
593 H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
594 H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
595 H_PUT_16 (abfd, MIPS_R_PAIR, reloc_dst->r_type);
17505c5c
NC
596 return RELSZ;
597 }
598 break;
599 }
600
dc810e39
AM
601 H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
602 H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
17505c5c 603
dc810e39 604 H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
17505c5c
NC
605 return RELSZ;
606}
607
608#define coff_swap_reloc_in mips_swap_reloc_in
609#define coff_swap_reloc_out mips_swap_reloc_out
610#define NO_COFF_RELOCS
611
b34976b6 612static bfd_boolean
17505c5c
NC
613coff_pe_mips_relocate_section (output_bfd, info, input_bfd,
614 input_section, contents, relocs, syms,
615 sections)
616 bfd *output_bfd;
617 struct bfd_link_info *info;
618 bfd *input_bfd;
619 asection *input_section;
620 bfd_byte *contents;
621 struct internal_reloc *relocs;
622 struct internal_syment *syms;
623 asection **sections;
624{
17505c5c 625 bfd_vma gp;
b34976b6 626 bfd_boolean gp_undefined;
17505c5c 627 size_t adjust;
17505c5c
NC
628 struct internal_reloc *rel;
629 struct internal_reloc *rel_end;
630 unsigned int i;
b34976b6 631 bfd_boolean got_lo;
17505c5c 632
1049f94e 633 if (info->relocatable)
17505c5c 634 {
892339ee 635 (*_bfd_error_handler) (_("\
17505c5c 636%s: `ld -r' not supported with PE MIPS objects\n"),
8f615d07 637 bfd_archive_filename (input_bfd));
17505c5c 638 bfd_set_error (bfd_error_bad_value);
b34976b6 639 return FALSE;
17505c5c
NC
640 }
641
642 BFD_ASSERT (input_bfd->xvec->byteorder
643 == output_bfd->xvec->byteorder);
644
645#if 0
892339ee 646 printf ("dj: relocate %s(%s) %08x\n",
17505c5c
NC
647 input_bfd->filename, input_section->name,
648 input_section->output_section->vma + input_section->output_offset);
649#endif
650
651 gp = _bfd_get_gp_value (output_bfd);
652 if (gp == 0)
b34976b6 653 gp_undefined = TRUE;
17505c5c 654 else
b34976b6 655 gp_undefined = FALSE;
17505c5c 656
b34976b6 657 got_lo = FALSE;
17505c5c
NC
658
659 adjust = 0;
660
661 rel = relocs;
662 rel_end = rel + input_section->reloc_count;
663 for (i = 0; rel < rel_end; rel++, i++)
664 {
665 long symndx;
666 struct coff_link_hash_entry *h;
667 struct internal_syment *sym;
668 bfd_vma addend = 0;
669 bfd_vma val, tmp, targ, src, low;
670 reloc_howto_type *howto;
17505c5c
NC
671 unsigned char *mem = contents + rel->r_vaddr;
672
673 symndx = rel->r_symndx;
674
675 if (symndx == -1)
676 {
677 h = NULL;
678 sym = NULL;
679 }
680 else
892339ee 681 {
17505c5c
NC
682 h = obj_coff_sym_hashes (input_bfd)[symndx];
683 sym = syms + symndx;
684 }
685
686 /* COFF treats common symbols in one of two ways. Either the
687 size of the symbol is included in the section contents, or it
688 is not. We assume that the size is not included, and force
689 the rtype_to_howto function to adjust the addend as needed. */
690
691 if (sym != NULL && sym->n_scnum != 0)
692 addend = - sym->n_value;
693 else
694 addend = 0;
695
17505c5c
NC
696 howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
697 sym, &addend);
698 if (howto == NULL)
b34976b6 699 return FALSE;
17505c5c 700
1049f94e 701 /* If we are doing a relocatable link, then we can just ignore
17505c5c 702 a PC relative reloc that is pcrel_offset. It will already
1049f94e 703 have the correct value. If this is not a relocatable link,
17505c5c
NC
704 then we should ignore the symbol value. */
705 if (howto->pc_relative && howto->pcrel_offset)
706 {
1049f94e 707 if (info->relocatable)
17505c5c
NC
708 continue;
709 if (sym != NULL && sym->n_scnum != 0)
710 addend += sym->n_value;
711 }
712
713 val = 0;
714
715 if (h == NULL)
716 {
717 asection *sec;
718
719 if (symndx == -1)
720 {
721 sec = bfd_abs_section_ptr;
722 val = 0;
723 }
724 else
725 {
726 sec = sections[symndx];
727 val = (sec->output_section->vma
728 + sec->output_offset
729 + sym->n_value);
730 if (! obj_pe (input_bfd))
731 val -= sec->vma;
732 }
733 }
734 else
735 {
736 if (h->root.type == bfd_link_hash_defined
737 || h->root.type == bfd_link_hash_defweak)
738 {
739 asection *sec;
740
741 sec = h->root.u.def.section;
742 val = (h->root.u.def.value
743 + sec->output_section->vma
744 + sec->output_offset);
745 }
746
1049f94e 747 else if (! info->relocatable)
17505c5c
NC
748 {
749 if (! ((*info->callbacks->undefined_symbol)
750 (info, h->root.root.string, input_bfd, input_section,
b34976b6
AM
751 rel->r_vaddr - input_section->vma, TRUE)))
752 return FALSE;
17505c5c
NC
753 }
754 }
755
756 src = rel->r_vaddr + input_section->output_section->vma
757 + input_section->output_offset;
758#if 0
892339ee 759 printf ("dj: reloc %02x %-8s a=%08x/%08x(%08x) v=%08x+%08x %s\n",
17505c5c
NC
760 rel->r_type, howto_table[rel->r_type].name,
761 src, rel->r_vaddr, *(unsigned long *)mem, val, rel->r_offset,
762 h?h->root.root.string:"(none)");
763#endif
764
765 /* OK, at this point the following variables are set up:
766 src = VMA of the memory we're fixing up
767 mem = pointer to memory we're fixing up
768 val = VMA of what we need to refer to
769 */
770
892339ee 771#define UI(x) (*_bfd_error_handler) (_("%s: unimplemented %s\n"), \
8f615d07 772 bfd_archive_filename (input_bfd), x); \
17505c5c
NC
773 bfd_set_error (bfd_error_bad_value);
774
775 switch (rel->r_type)
776 {
777 case MIPS_R_ABSOLUTE:
778 /* ignore these */
779 break;
780
781 case MIPS_R_REFHALF:
782 UI("refhalf");
783 break;
784
785 case MIPS_R_REFWORD:
786 tmp = bfd_get_32(input_bfd, mem);
892339ee 787 /* printf ("refword: src=%08x targ=%08x+%08x\n", src, tmp, val); */
17505c5c
NC
788 tmp += val;
789 bfd_put_32(input_bfd, tmp, mem);
790 break;
791
792 case MIPS_R_JMPADDR:
793 tmp = bfd_get_32(input_bfd, mem);
794 targ = val + (tmp&0x03ffffff)*4;
86033394 795 if ((src & 0xf0000000) != (targ & 0xf0000000))
17505c5c 796 {
892339ee 797 (*_bfd_error_handler) (_("%s: jump too far away\n"),
8f615d07 798 bfd_archive_filename (input_bfd));
17505c5c 799 bfd_set_error (bfd_error_bad_value);
b34976b6 800 return FALSE;
17505c5c
NC
801 }
802 tmp &= 0xfc000000;
803 tmp |= (targ/4) & 0x3ffffff;
804 bfd_put_32(input_bfd, tmp, mem);
805 break;
806
807 case MIPS_R_REFHI:
808 tmp = bfd_get_32(input_bfd, mem);
809 switch (rel[1].r_type)
810 {
811 case MIPS_R_PAIR:
812 /* MS PE object */
813 targ = val + rel[1].r_offset + ((tmp & 0xffff) << 16);
814 break;
815 case MIPS_R_REFLO:
816 /* GNU COFF object */
817 low = bfd_get_32(input_bfd, contents + rel[1].r_vaddr);
818 low &= 0xffff;
819 if (low & 0x8000)
820 low -= 0x10000;
821 targ = val + low + ((tmp & 0xffff) << 16);
822 break;
823 default:
892339ee 824 (*_bfd_error_handler) (_("%s: bad pair/reflo after refhi\n"),
8f615d07 825 bfd_archive_filename (input_bfd));
17505c5c 826 bfd_set_error (bfd_error_bad_value);
b34976b6 827 return FALSE;
17505c5c
NC
828 }
829 tmp &= 0xffff0000;
830 tmp |= (targ >> 16) & 0xffff;
831 bfd_put_32(input_bfd, tmp, mem);
832 break;
833
834 case MIPS_R_REFLO:
835 tmp = bfd_get_32(input_bfd, mem);
836 targ = val + (tmp & 0xffff);
892339ee 837 /* printf ("refword: src=%08x targ=%08x\n", src, targ); */
17505c5c
NC
838 tmp &= 0xffff0000;
839 tmp |= targ & 0xffff;
840 bfd_put_32(input_bfd, tmp, mem);
841 break;
842
843 case MIPS_R_GPREL:
844 case MIPS_R_LITERAL:
845 UI("gprel");
846 break;
847
848 case MIPS_R_SECTION:
849 UI("section");
850 break;
851
852 case MIPS_R_SECREL:
853 UI("secrel");
854 break;
855
856 case MIPS_R_SECRELLO:
857 UI("secrello");
858 break;
859
860 case MIPS_R_SECRELHI:
861 UI("secrelhi");
862 break;
863
864 case MIPS_R_RVA:
865 tmp = bfd_get_32 (input_bfd, mem);
892339ee 866 /* printf ("rva: src=%08x targ=%08x+%08x\n", src, tmp, val); */
17505c5c 867 tmp += val
86033394 868 - pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase;
17505c5c
NC
869 bfd_put_32 (input_bfd, tmp, mem);
870 break;
871
872 case MIPS_R_PAIR:
873 /* ignore these */
874 break;
875 }
876 }
877
b34976b6 878 return TRUE;
17505c5c
NC
879}
880
881#define coff_relocate_section coff_pe_mips_relocate_section
882
883#ifdef TARGET_UNDERSCORE
884
885/* If mips gcc uses underscores for symbol names, then it does not use
886 a leading dot for local labels, so if TARGET_UNDERSCORE is defined
887 we treat all symbols starting with L as local. */
888
b34976b6
AM
889static bfd_boolean coff_mips_is_local_label_name
890 PARAMS ((bfd *, const char *));
17505c5c 891
b34976b6 892static bfd_boolean
17505c5c
NC
893coff_mips_is_local_label_name (abfd, name)
894 bfd *abfd;
895 const char *name;
896{
897 if (name[0] == 'L')
b34976b6 898 return TRUE;
17505c5c
NC
899
900 return _bfd_coff_is_local_label_name (abfd, name);
901}
902
903#define coff_bfd_is_local_label_name coff_mips_is_local_label_name
904
905#endif /* TARGET_UNDERSCORE */
906
907#define COFF_NO_HACK_SCNHDR_SIZE
908
909#include "coffcode.h"
910
911const bfd_target
912#ifdef TARGET_SYM
913 TARGET_SYM =
914#else
915 mipslpe_vec =
916#endif
917{
918#ifdef TARGET_NAME
919 TARGET_NAME,
920#else
921 "pe-mips", /* name */
922#endif
923 bfd_target_coff_flavour,
924 BFD_ENDIAN_LITTLE, /* data byte order is little */
925 BFD_ENDIAN_LITTLE, /* header byte order is little */
926
927 (HAS_RELOC | EXEC_P | /* object flags */
928 HAS_LINENO | HAS_DEBUG |
929 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
930
931#ifndef COFF_WITH_PE
932 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
933 | SEC_CODE | SEC_DATA),
934#else
935 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
936 | SEC_CODE | SEC_DATA
937 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
938#endif
939
940#ifdef TARGET_UNDERSCORE
941 TARGET_UNDERSCORE, /* leading underscore */
942#else
943 0, /* leading underscore */
944#endif
945 '/', /* ar_pad_char */
946 15, /* ar_max_namelen */
947
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, /* data */
951 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
952 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
953 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
954
892339ee 955/* Note that we allow an object file to be treated as a core file as well. */
17505c5c
NC
956 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
957 bfd_generic_archive_p, coff_object_p},
958 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
959 bfd_false},
960 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
961 _bfd_write_archive_contents, bfd_false},
962
963 BFD_JUMP_TABLE_GENERIC (coff),
964 BFD_JUMP_TABLE_COPY (coff),
965 BFD_JUMP_TABLE_CORE (_bfd_nocore),
966 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
967 BFD_JUMP_TABLE_SYMBOLS (coff),
968 BFD_JUMP_TABLE_RELOCS (coff),
969 BFD_JUMP_TABLE_WRITE (coff),
970 BFD_JUMP_TABLE_LINK (coff),
971 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
972
973 NULL,
892339ee 974
17505c5c
NC
975 COFF_SWAP_TABLE
976};
This page took 0.317707 seconds and 4 git commands to generate.