Move PE format object file detection code into common place.
[deliverable/binutils-gdb.git] / bfd / coff-i386.c
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.
5
6 This file is part of BFD, the Binary File Descriptor library.
7
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.
12
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.
17
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. */
21
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25
26 #include "coff/i386.h"
27
28 #include "coff/internal.h"
29
30 #ifdef COFF_WITH_PE
31 #include "coff/pe.h"
32 #endif
33
34 #ifdef COFF_GO32_EXE
35 #include "coff/go32exe.h"
36 #endif
37
38 #include "libcoff.h"
39
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 *,
45 bfd_vma *));
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 *));
49
50 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
51 /* The page size is a guess based on ELF. */
52
53 #define COFF_PAGE_SIZE 0x1000
54
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. */
58
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. */
63
64 static bfd_reloc_status_type
65 coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
66 error_message)
67 bfd *abfd;
68 arelent *reloc_entry;
69 asymbol *symbol;
70 PTR data;
71 asection *input_section ATTRIBUTE_UNUSED;
72 bfd *output_bfd;
73 char **error_message ATTRIBUTE_UNUSED;
74 {
75 symvalue diff;
76
77 if (output_bfd == (bfd *) NULL)
78 return bfd_reloc_continue;
79
80 if (bfd_is_com_section (symbol->section))
81 {
82 #ifndef COFF_WITH_PE
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;
95 #else
96 /* In PE mode, we do not offset the common symbol. */
97 diff = reloc_entry->addend;
98 #endif
99 }
100 else
101 {
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;
107 }
108
109 #ifdef COFF_WITH_PE
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;
113 #endif
114
115 #define DOIT(x) \
116 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
117
118 if (diff != 0)
119 {
120 reloc_howto_type *howto = reloc_entry->howto;
121 unsigned char *addr = (unsigned char *) data + reloc_entry->address;
122
123 switch (howto->size)
124 {
125 case 0:
126 {
127 char x = bfd_get_8 (abfd, addr);
128 DOIT (x);
129 bfd_put_8 (abfd, x, addr);
130 }
131 break;
132
133 case 1:
134 {
135 short x = bfd_get_16 (abfd, addr);
136 DOIT (x);
137 bfd_put_16 (abfd, x, addr);
138 }
139 break;
140
141 case 2:
142 {
143 long x = bfd_get_32 (abfd, addr);
144 DOIT (x);
145 bfd_put_32 (abfd, x, addr);
146 }
147 break;
148
149 default:
150 abort ();
151 }
152 }
153
154 /* Now let bfd_perform_relocation finish everything up. */
155 return bfd_reloc_continue;
156 }
157
158 #ifdef COFF_WITH_PE
159
160 /* Return true if this relocation should appear in the output .reloc
161 section. */
162
163 static boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
164
165 static boolean in_reloc_p (abfd, howto)
166 bfd *abfd ATTRIBUTE_UNUSED;
167 reloc_howto_type *howto;
168 {
169 return ! howto->pc_relative && howto->type != R_IMAGEBASE;
170 }
171
172 #endif /* COFF_WITH_PE */
173
174 #ifndef PCRELOFFSET
175 #define PCRELOFFSET false
176 #endif
177
178 static reloc_howto_type howto_table[] =
179 {
180 EMPTY_HOWTO (0),
181 EMPTY_HOWTO (1),
182 EMPTY_HOWTO (2),
183 EMPTY_HOWTO (3),
184 EMPTY_HOWTO (4),
185 EMPTY_HOWTO (5),
186 HOWTO (R_DIR32, /* type */
187 0, /* rightshift */
188 2, /* size (0 = byte, 1 = short, 2 = long) */
189 32, /* bitsize */
190 false, /* pc_relative */
191 0, /* bitpos */
192 complain_overflow_bitfield, /* complain_on_overflow */
193 coff_i386_reloc, /* special_function */
194 "dir32", /* name */
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 */
201 0, /* rightshift */
202 2, /* size (0 = byte, 1 = short, 2 = long) */
203 32, /* bitsize */
204 false, /* pc_relative */
205 0, /* bitpos */
206 complain_overflow_bitfield, /* complain_on_overflow */
207 coff_i386_reloc, /* special_function */
208 "rva32", /* name */
209 true, /* partial_inplace */
210 0xffffffff, /* src_mask */
211 0xffffffff, /* dst_mask */
212 false), /* pcrel_offset */
213 EMPTY_HOWTO (010),
214 EMPTY_HOWTO (011),
215 EMPTY_HOWTO (012),
216 EMPTY_HOWTO (013),
217 EMPTY_HOWTO (014),
218 EMPTY_HOWTO (015),
219 EMPTY_HOWTO (016),
220 /* Byte relocation (017). */
221 HOWTO (R_RELBYTE, /* type */
222 0, /* rightshift */
223 0, /* size (0 = byte, 1 = short, 2 = long) */
224 8, /* bitsize */
225 false, /* pc_relative */
226 0, /* bitpos */
227 complain_overflow_bitfield, /* complain_on_overflow */
228 coff_i386_reloc, /* special_function */
229 "8", /* name */
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 */
236 0, /* rightshift */
237 1, /* size (0 = byte, 1 = short, 2 = long) */
238 16, /* bitsize */
239 false, /* pc_relative */
240 0, /* bitpos */
241 complain_overflow_bitfield, /* complain_on_overflow */
242 coff_i386_reloc, /* special_function */
243 "16", /* name */
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 */
250 0, /* rightshift */
251 2, /* size (0 = byte, 1 = short, 2 = long) */
252 32, /* bitsize */
253 false, /* pc_relative */
254 0, /* bitpos */
255 complain_overflow_bitfield, /* complain_on_overflow */
256 coff_i386_reloc, /* special_function */
257 "32", /* name */
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 */
264 0, /* rightshift */
265 0, /* size (0 = byte, 1 = short, 2 = long) */
266 8, /* bitsize */
267 true, /* pc_relative */
268 0, /* bitpos */
269 complain_overflow_signed, /* complain_on_overflow */
270 coff_i386_reloc, /* special_function */
271 "DISP8", /* name */
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 */
278 0, /* rightshift */
279 1, /* size (0 = byte, 1 = short, 2 = long) */
280 16, /* bitsize */
281 true, /* pc_relative */
282 0, /* bitpos */
283 complain_overflow_signed, /* complain_on_overflow */
284 coff_i386_reloc, /* special_function */
285 "DISP16", /* name */
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 */
292 0, /* rightshift */
293 2, /* size (0 = byte, 1 = short, 2 = long) */
294 32, /* bitsize */
295 true, /* pc_relative */
296 0, /* bitpos */
297 complain_overflow_signed, /* complain_on_overflow */
298 coff_i386_reloc, /* special_function */
299 "DISP32", /* name */
300 true, /* partial_inplace */
301 0xffffffff, /* src_mask */
302 0xffffffff, /* dst_mask */
303 PCRELOFFSET) /* pcrel_offset */
304 };
305
306 /* Turn a howto into a reloc nunmber */
307
308 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
309 #define BADMAG(x) I386BADMAG(x)
310 #define I386 1 /* Customize coffcode.h */
311
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 \
316 : NULL))
317
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
320 STYP_NOLOAD. */
321 #define BSS_NOLOAD_IS_SHARED_LIBRARY
322
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
332 PC relative relocs.
333 FIXME: This macro refers to symbols and asect; these are from the
334 calling function, not the macro arguments. */
335
336 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
337 { \
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)); \
342 else if (ptr) \
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); \
350 else \
351 cache_ptr->addend = 0; \
352 if (ptr && howto_table[reloc.r_type].pc_relative) \
353 cache_ptr->addend += asect->vma; \
354 }
355
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
358 own routine. */
359
360 #ifndef COFF_WITH_PE
361
362 #define coff_relocate_section _bfd_coff_generic_relocate_section
363
364 #else /* COFF_WITH_PE */
365
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. */
369
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 **));
373
374 static boolean
375 coff_pe_i386_relocate_section (output_bfd, info, input_bfd,
376 input_section, contents, relocs, syms,
377 sections)
378 bfd *output_bfd;
379 struct bfd_link_info *info;
380 bfd *input_bfd;
381 asection *input_section;
382 bfd_byte *contents;
383 struct internal_reloc *relocs;
384 struct internal_syment *syms;
385 asection **sections;
386 {
387 if (info->relocateable)
388 return true;
389
390 return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
391 input_section, contents,
392 relocs, syms, sections);
393 }
394
395 #define coff_relocate_section coff_pe_i386_relocate_section
396
397 #endif /* COFF_WITH_PE */
398
399 /* Convert an rtype to howto for the COFF backend linker. */
400
401 static reloc_howto_type *
402 coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
403 bfd *abfd ATTRIBUTE_UNUSED;
404 asection *sec;
405 struct internal_reloc *rel;
406 struct coff_link_hash_entry *h;
407 struct internal_syment *sym;
408 bfd_vma *addendp;
409 {
410 reloc_howto_type *howto;
411
412 if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0]))
413 {
414 bfd_set_error (bfd_error_bad_value);
415 return NULL;
416 }
417
418 howto = howto_table + rel->r_type;
419
420 #ifdef COFF_WITH_PE
421 /* Cancel out code in _bfd_coff_generic_relocate_section. */
422 *addendp = 0;
423 #endif
424
425 if (howto->pc_relative)
426 *addendp += sec->vma;
427
428 if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
429 {
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
434 correct result. */
435
436 BFD_ASSERT (h != NULL);
437
438 #ifndef COFF_WITH_PE
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;
447 #endif
448 }
449
450 #ifndef COFF_WITH_PE
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
453 common symbol. */
454 if (h != NULL && h->root.type == bfd_link_hash_common)
455 *addendp += h->root.u.c.size;
456 #endif
457
458 #ifdef COFF_WITH_PE
459 if (howto->pc_relative)
460 {
461 *addendp -= 4;
462
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;
471 }
472
473 if (rel->r_type == R_IMAGEBASE)
474 {
475 *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
476 }
477 #endif
478
479 return howto;
480 }
481
482 #define coff_bfd_reloc_type_lookup coff_i386_reloc_type_lookup
483
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;
488 {
489 switch (code)
490 {
491 case BFD_RELOC_RVA:
492 return howto_table + R_IMAGEBASE;
493 case BFD_RELOC_32:
494 return howto_table + R_DIR32;
495 case BFD_RELOC_32_PCREL:
496 return howto_table + R_PCRLONG;
497 case BFD_RELOC_16:
498 return howto_table + R_RELWORD;
499 case BFD_RELOC_16_PCREL:
500 return howto_table + R_PCRWORD;
501 case BFD_RELOC_8:
502 return howto_table + R_RELBYTE;
503 case BFD_RELOC_8_PCREL:
504 return howto_table + R_PCRBYTE;
505 default:
506 BFD_FAIL ();
507 return 0;
508 }
509 }
510
511 #define coff_rtype_to_howto coff_i386_rtype_to_howto
512
513 #ifdef TARGET_UNDERSCORE
514
515 /* If i386 gcc uses underscores for symbol names, then it does not use
516 a leading dot for local labels, so if TARGET_UNDERSCORE is defined
517 we treat all symbols starting with L as local. */
518
519 static boolean coff_i386_is_local_label_name PARAMS ((bfd *, const char *));
520
521 static boolean
522 coff_i386_is_local_label_name (abfd, name)
523 bfd *abfd;
524 const char *name;
525 {
526 if (name[0] == 'L')
527 return true;
528
529 return _bfd_coff_is_local_label_name (abfd, name);
530 }
531
532 #define coff_bfd_is_local_label_name coff_i386_is_local_label_name
533
534 #endif /* TARGET_UNDERSCORE */
535
536 #include "coffcode.h"
537
538 const bfd_target
539 #ifdef TARGET_SYM
540 TARGET_SYM =
541 #else
542 i386coff_vec =
543 #endif
544 {
545 #ifdef TARGET_NAME
546 TARGET_NAME,
547 #else
548 "coff-i386", /* name */
549 #endif
550 bfd_target_coff_flavour,
551 BFD_ENDIAN_LITTLE, /* data byte order is little */
552 BFD_ENDIAN_LITTLE, /* header byte order is little */
553
554 (HAS_RELOC | EXEC_P | /* object flags */
555 HAS_LINENO | HAS_DEBUG |
556 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
557
558 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
559 #ifdef COFF_WITH_PE
560 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES
561 #endif
562 | SEC_CODE | SEC_DATA),
563
564 #ifdef TARGET_UNDERSCORE
565 TARGET_UNDERSCORE, /* leading underscore */
566 #else
567 0, /* leading underscore */
568 #endif
569 '/', /* ar_pad_char */
570 15, /* ar_max_namelen */
571
572 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
573 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
574 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
575 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
576 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
577 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
578
579 /* Note that we allow an object file to be treated as a core file as well. */
580 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
581 bfd_generic_archive_p, coff_object_p},
582 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
583 bfd_false},
584 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
585 _bfd_write_archive_contents, bfd_false},
586
587 BFD_JUMP_TABLE_GENERIC (coff),
588 BFD_JUMP_TABLE_COPY (coff),
589 BFD_JUMP_TABLE_CORE (_bfd_nocore),
590 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
591 BFD_JUMP_TABLE_SYMBOLS (coff),
592 BFD_JUMP_TABLE_RELOCS (coff),
593 BFD_JUMP_TABLE_WRITE (coff),
594 BFD_JUMP_TABLE_LINK (coff),
595 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
596
597 NULL,
598
599 COFF_SWAP_TABLE
600 };
This page took 0.042021 seconds and 5 git commands to generate.