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