1 /* BFD back-end for Intel 386 COFF files.
2 Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
3 Free Software Foundation, Inc.
4 Written by Cygnus Support.
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
26 #include "coff/i386.h"
28 #include "coff/internal.h"
35 #include "coff/go32exe.h"
40 static bfd_reloc_status_type coff_i386_reloc
41 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
42 static reloc_howto_type *coff_i386_rtype_to_howto
43 PARAMS ((bfd *, asection *, struct internal_reloc *,
44 struct coff_link_hash_entry *, struct internal_syment *,
46 static reloc_howto_type *coff_i386_reloc_type_lookup
47 PARAMS ((bfd *, bfd_reloc_code_real_type));
48 static const bfd_target *i3coff_object_p PARAMS ((bfd *));
50 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
51 /* The page size is a guess based on ELF. */
53 #define COFF_PAGE_SIZE 0x1000
55 /* For some reason when using i386 COFF the value stored in the .text
56 section for a reference to a common symbol is the value itself plus
57 any desired offset. Ian Taylor, Cygnus Support. */
59 /* If we are producing relocateable output, we need to do some
60 adjustments to the object file that are not done by the
61 bfd_perform_relocation function. This function is called by every
62 reloc type to make any required adjustments. */
64 static bfd_reloc_status_type
65 coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
71 asection *input_section ATTRIBUTE_UNUSED;
73 char **error_message ATTRIBUTE_UNUSED;
77 if (output_bfd == (bfd *) NULL)
78 return bfd_reloc_continue;
80 if (bfd_is_com_section (symbol->section))
83 /* We are relocating a common symbol. The current value in the
84 object file is ORIG + OFFSET, where ORIG is the value of the
85 common symbol as seen by the object file when it was compiled
86 (this may be zero if the symbol was undefined) and OFFSET is
87 the offset into the common symbol (normally zero, but may be
88 non-zero when referring to a field in a common structure).
89 ORIG is the negative of reloc_entry->addend, which is set by
90 the CALC_ADDEND macro below. We want to replace the value in
91 the object file with NEW + OFFSET, where NEW is the value of
92 the common symbol which we are going to put in the final
93 object file. NEW is symbol->value. */
94 diff = symbol->value + reloc_entry->addend;
96 /* In PE mode, we do not offset the common symbol. */
97 diff = reloc_entry->addend;
102 /* For some reason bfd_perform_relocation always effectively
103 ignores the addend for a COFF target when producing
104 relocateable output. This seems to be always wrong for 386
105 COFF, so we handle the addend here instead. */
106 diff = reloc_entry->addend;
110 /* FIXME: How should this case be handled? */
111 if (reloc_entry->howto->type == R_IMAGEBASE)
112 diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;
116 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
120 reloc_howto_type *howto = reloc_entry->howto;
121 unsigned char *addr = (unsigned char *) data + reloc_entry->address;
127 char x = bfd_get_8 (abfd, addr);
129 bfd_put_8 (abfd, x, addr);
135 short x = bfd_get_16 (abfd, addr);
137 bfd_put_16 (abfd, x, addr);
143 long x = bfd_get_32 (abfd, addr);
145 bfd_put_32 (abfd, x, addr);
154 /* Now let bfd_perform_relocation finish everything up. */
155 return bfd_reloc_continue;
160 /* Return true if this relocation should appear in the output .reloc
163 static boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
165 static boolean in_reloc_p (abfd, howto)
166 bfd *abfd ATTRIBUTE_UNUSED;
167 reloc_howto_type *howto;
169 return ! howto->pc_relative && howto->type != R_IMAGEBASE;
172 #endif /* COFF_WITH_PE */
175 #define PCRELOFFSET false
178 static reloc_howto_type howto_table[] =
186 HOWTO (R_DIR32, /* type */
188 2, /* size (0 = byte, 1 = short, 2 = long) */
190 false, /* pc_relative */
192 complain_overflow_bitfield, /* complain_on_overflow */
193 coff_i386_reloc, /* special_function */
195 true, /* partial_inplace */
196 0xffffffff, /* src_mask */
197 0xffffffff, /* dst_mask */
198 true), /* pcrel_offset */
199 /* PE IMAGE_REL_I386_DIR32NB relocation (7). */
200 HOWTO (R_IMAGEBASE, /* type */
202 2, /* size (0 = byte, 1 = short, 2 = long) */
204 false, /* pc_relative */
206 complain_overflow_bitfield, /* complain_on_overflow */
207 coff_i386_reloc, /* special_function */
209 true, /* partial_inplace */
210 0xffffffff, /* src_mask */
211 0xffffffff, /* dst_mask */
212 false), /* pcrel_offset */
220 /* Byte relocation (017). */
221 HOWTO (R_RELBYTE, /* type */
223 0, /* size (0 = byte, 1 = short, 2 = long) */
225 false, /* pc_relative */
227 complain_overflow_bitfield, /* complain_on_overflow */
228 coff_i386_reloc, /* special_function */
230 true, /* partial_inplace */
231 0x000000ff, /* src_mask */
232 0x000000ff, /* dst_mask */
233 PCRELOFFSET), /* pcrel_offset */
234 /* 16-bit word relocation (020). */
235 HOWTO (R_RELWORD, /* type */
237 1, /* size (0 = byte, 1 = short, 2 = long) */
239 false, /* pc_relative */
241 complain_overflow_bitfield, /* complain_on_overflow */
242 coff_i386_reloc, /* special_function */
244 true, /* partial_inplace */
245 0x0000ffff, /* src_mask */
246 0x0000ffff, /* dst_mask */
247 PCRELOFFSET), /* pcrel_offset */
248 /* 32-bit longword relocation (021). */
249 HOWTO (R_RELLONG, /* type */
251 2, /* size (0 = byte, 1 = short, 2 = long) */
253 false, /* pc_relative */
255 complain_overflow_bitfield, /* complain_on_overflow */
256 coff_i386_reloc, /* special_function */
258 true, /* partial_inplace */
259 0xffffffff, /* src_mask */
260 0xffffffff, /* dst_mask */
261 PCRELOFFSET), /* pcrel_offset */
262 /* Byte PC relative relocation (022). */
263 HOWTO (R_PCRBYTE, /* type */
265 0, /* size (0 = byte, 1 = short, 2 = long) */
267 true, /* pc_relative */
269 complain_overflow_signed, /* complain_on_overflow */
270 coff_i386_reloc, /* special_function */
272 true, /* partial_inplace */
273 0x000000ff, /* src_mask */
274 0x000000ff, /* dst_mask */
275 PCRELOFFSET), /* pcrel_offset */
276 /* 16-bit word PC relative relocation (023). */
277 HOWTO (R_PCRWORD, /* type */
279 1, /* size (0 = byte, 1 = short, 2 = long) */
281 true, /* pc_relative */
283 complain_overflow_signed, /* complain_on_overflow */
284 coff_i386_reloc, /* special_function */
286 true, /* partial_inplace */
287 0x0000ffff, /* src_mask */
288 0x0000ffff, /* dst_mask */
289 PCRELOFFSET), /* pcrel_offset */
290 /* 32-bit longword PC relative relocation (024). */
291 HOWTO (R_PCRLONG, /* type */
293 2, /* size (0 = byte, 1 = short, 2 = long) */
295 true, /* pc_relative */
297 complain_overflow_signed, /* complain_on_overflow */
298 coff_i386_reloc, /* special_function */
300 true, /* partial_inplace */
301 0xffffffff, /* src_mask */
302 0xffffffff, /* dst_mask */
303 PCRELOFFSET) /* pcrel_offset */
306 /* Turn a howto into a reloc nunmber */
308 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
309 #define BADMAG(x) I386BADMAG(x)
310 #define I386 1 /* Customize coffcode.h */
312 #define RTYPE2HOWTO(cache_ptr, dst) \
313 ((cache_ptr)->howto = \
314 ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0]) \
315 ? howto_table + (dst)->r_type \
318 /* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
319 library. On some other COFF targets STYP_BSS is normally
321 #define BSS_NOLOAD_IS_SHARED_LIBRARY
323 /* Compute the addend of a reloc. If the reloc is to a common symbol,
324 the object file contains the value of the common symbol. By the
325 time this is called, the linker may be using a different symbol
326 from a different object file with a different value. Therefore, we
327 hack wildly to locate the original symbol from this file so that we
328 can make the correct adjustment. This macro sets coffsym to the
329 symbol from the original file, and uses it to set the addend value
330 correctly. If this is not a common symbol, the usual addend
331 calculation is done, except that an additional tweak is needed for
333 FIXME: This macro refers to symbols and asect; these are from the
334 calling function, not the macro arguments. */
336 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
338 coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
339 if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
340 coffsym = (obj_symbols (abfd) \
341 + (cache_ptr->sym_ptr_ptr - symbols)); \
343 coffsym = coff_symbol_from (abfd, ptr); \
344 if (coffsym != (coff_symbol_type *) NULL \
345 && coffsym->native->u.syment.n_scnum == 0) \
346 cache_ptr->addend = - coffsym->native->u.syment.n_value; \
347 else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
348 && ptr->section != (asection *) NULL) \
349 cache_ptr->addend = - (ptr->section->vma + ptr->value); \
351 cache_ptr->addend = 0; \
352 if (ptr && howto_table[reloc.r_type].pc_relative) \
353 cache_ptr->addend += asect->vma; \
356 /* We use the special COFF backend linker. For normal i386 COFF, we
357 can use the generic relocate_section routine. For PE, we need our
362 #define coff_relocate_section _bfd_coff_generic_relocate_section
364 #else /* COFF_WITH_PE */
366 /* The PE relocate section routine. The only difference between this
367 and the regular routine is that we don't want to do anything for a
368 relocateable link. */
370 static boolean coff_pe_i386_relocate_section
371 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
372 struct internal_reloc *, struct internal_syment *, asection **));
375 coff_pe_i386_relocate_section (output_bfd, info, input_bfd,
376 input_section, contents, relocs, syms,
379 struct bfd_link_info *info;
381 asection *input_section;
383 struct internal_reloc *relocs;
384 struct internal_syment *syms;
387 if (info->relocateable)
390 return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
391 input_section, contents,
392 relocs, syms, sections);
395 #define coff_relocate_section coff_pe_i386_relocate_section
397 #endif /* COFF_WITH_PE */
399 /* Convert an rtype to howto for the COFF backend linker. */
401 static reloc_howto_type *
402 coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
403 bfd *abfd ATTRIBUTE_UNUSED;
405 struct internal_reloc *rel;
406 struct coff_link_hash_entry *h;
407 struct internal_syment *sym;
410 reloc_howto_type *howto;
412 if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0]))
414 bfd_set_error (bfd_error_bad_value);
418 howto = howto_table + rel->r_type;
421 /* Cancel out code in _bfd_coff_generic_relocate_section. */
425 if (howto->pc_relative)
426 *addendp += sec->vma;
428 if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
430 /* This is a common symbol. The section contents include the
431 size (sym->n_value) as an addend. The relocate_section
432 function will be adding in the final value of the symbol. We
433 need to subtract out the current size in order to get the
436 BFD_ASSERT (h != NULL);
439 /* I think we *do* want to bypass this. If we don't, I have
440 seen some data parameters get the wrong relocation address.
441 If I link two versions with and without this section bypassed
442 and then do a binary comparison, the addresses which are
443 different can be looked up in the map. The case in which
444 this section has been bypassed has addresses which correspond
445 to values I can find in the map. */
446 *addendp -= sym->n_value;
451 /* If the output symbol is common (in which case this must be a
452 relocateable link), we need to add in the final size of the
454 if (h != NULL && h->root.type == bfd_link_hash_common)
455 *addendp += h->root.u.c.size;
459 if (howto->pc_relative)
463 /* If the symbol is defined, then the generic code is going to
464 add back the symbol value in order to cancel out an
465 adjustment it made to the addend. However, we set the addend
466 to 0 at the start of this function. We need to adjust here,
467 to avoid the adjustment the generic code will make. FIXME:
468 This is getting a bit hackish. */
469 if (sym != NULL && sym->n_scnum != 0)
470 *addendp -= sym->n_value;
473 if (rel->r_type == R_IMAGEBASE)
475 *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
482 #define coff_bfd_reloc_type_lookup coff_i386_reloc_type_lookup
484 static reloc_howto_type *
485 coff_i386_reloc_type_lookup (abfd, code)
486 bfd *abfd ATTRIBUTE_UNUSED;
487 bfd_reloc_code_real_type code;
492 return howto_table +R_IMAGEBASE;
494 return howto_table + R_DIR32;
495 case BFD_RELOC_32_PCREL:
496 return howto_table + R_PCRLONG;
503 #define coff_rtype_to_howto coff_i386_rtype_to_howto
505 #ifdef TARGET_UNDERSCORE
507 /* If i386 gcc uses underscores for symbol names, then it does not use
508 a leading dot for local labels, so if TARGET_UNDERSCORE is defined
509 we treat all symbols starting with L as local. */
511 static boolean coff_i386_is_local_label_name PARAMS ((bfd *, const char *));
514 coff_i386_is_local_label_name (abfd, name)
521 return _bfd_coff_is_local_label_name (abfd, name);
524 #define coff_bfd_is_local_label_name coff_i386_is_local_label_name
526 #endif /* TARGET_UNDERSCORE */
528 #include "coffcode.h"
530 static const bfd_target *
531 i3coff_object_p (abfd)
534 #ifdef COFF_IMAGE_WITH_PE
535 /* We need to hack badly to handle a PE image correctly. In PE
536 images created by the GNU linker, the offset to the COFF header
537 is always the size. However, this is not the case in images
538 generated by other PE linkers. The PE format stores a four byte
539 offset to the PE signature just before the COFF header at
540 location 0x3c of the file. We pick up that offset, verify that
541 the PE signature is there, and then set ourselves up to read in
544 bfd_byte ext_offset[4];
546 bfd_byte ext_signature[4];
547 unsigned long signature;
549 if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0
550 || bfd_read (ext_offset, 1, 4, abfd) != 4)
552 if (bfd_get_error () != bfd_error_system_call)
553 bfd_set_error (bfd_error_wrong_format);
556 offset = bfd_h_get_32 (abfd, ext_offset);
557 if (bfd_seek (abfd, offset, SEEK_SET) != 0
558 || bfd_read (ext_signature, 1, 4, abfd) != 4)
560 if (bfd_get_error () != bfd_error_system_call)
561 bfd_set_error (bfd_error_wrong_format);
564 signature = bfd_h_get_32 (abfd, ext_signature);
566 if (signature != 0x4550)
568 bfd_set_error (bfd_error_wrong_format);
572 /* Here is the hack. coff_object_p wants to read filhsz bytes to
573 pick up the COFF header. We adjust so that that will work. 20
574 is the size of the i386 COFF filehdr. */
578 - bfd_coff_filhsz (abfd)
583 if (bfd_get_error () != bfd_error_system_call)
584 bfd_set_error (bfd_error_wrong_format);
590 return coff_object_p (abfd);
603 "coff-i386", /* name */
605 bfd_target_coff_flavour,
606 BFD_ENDIAN_LITTLE, /* data byte order is little */
607 BFD_ENDIAN_LITTLE, /* header byte order is little */
609 (HAS_RELOC | EXEC_P | /* object flags */
610 HAS_LINENO | HAS_DEBUG |
611 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
613 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
615 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES
617 | SEC_CODE | SEC_DATA),
619 #ifdef TARGET_UNDERSCORE
620 TARGET_UNDERSCORE, /* leading underscore */
622 0, /* leading underscore */
624 '/', /* ar_pad_char */
625 15, /* ar_max_namelen */
627 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
628 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
629 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
630 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
631 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
632 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
634 /* Note that we allow an object file to be treated as a core file as well. */
635 {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */
636 bfd_generic_archive_p, i3coff_object_p},
637 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
639 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
640 _bfd_write_archive_contents, bfd_false},
642 BFD_JUMP_TABLE_GENERIC (coff),
643 BFD_JUMP_TABLE_COPY (coff),
644 BFD_JUMP_TABLE_CORE (_bfd_nocore),
645 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
646 BFD_JUMP_TABLE_SYMBOLS (coff),
647 BFD_JUMP_TABLE_RELOCS (coff),
648 BFD_JUMP_TABLE_WRITE (coff),
649 BFD_JUMP_TABLE_LINK (coff),
650 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),