2000-06-18 H.J. Lu <hjl@gnu.org>
[external/binutils.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, 99, 2000
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
49 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
50 /* The page size is a guess based on ELF.  */
51
52 #define COFF_PAGE_SIZE 0x1000
53
54 /* For some reason when using i386 COFF the value stored in the .text
55    section for a reference to a common symbol is the value itself plus
56    any desired offset.  Ian Taylor, Cygnus Support.  */
57
58 /* If we are producing relocateable output, we need to do some
59    adjustments to the object file that are not done by the
60    bfd_perform_relocation function.  This function is called by every
61    reloc type to make any required adjustments.  */
62
63 static bfd_reloc_status_type
64 coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
65                  error_message)
66      bfd *abfd;
67      arelent *reloc_entry;
68      asymbol *symbol;
69      PTR data;
70      asection *input_section ATTRIBUTE_UNUSED;
71      bfd *output_bfd;
72      char **error_message ATTRIBUTE_UNUSED;
73 {
74   symvalue diff;
75
76 #ifndef COFF_WITH_PE
77   if (output_bfd == (bfd *) NULL)
78     return bfd_reloc_continue;
79 #endif
80
81   if (bfd_is_com_section (symbol->section))
82     {
83 #ifndef COFF_WITH_PE
84       /* We are relocating a common symbol.  The current value in the
85          object file is ORIG + OFFSET, where ORIG is the value of the
86          common symbol as seen by the object file when it was compiled
87          (this may be zero if the symbol was undefined) and OFFSET is
88          the offset into the common symbol (normally zero, but may be
89          non-zero when referring to a field in a common structure).
90          ORIG is the negative of reloc_entry->addend, which is set by
91          the CALC_ADDEND macro below.  We want to replace the value in
92          the object file with NEW + OFFSET, where NEW is the value of
93          the common symbol which we are going to put in the final
94          object file.  NEW is symbol->value.  */
95       diff = symbol->value + reloc_entry->addend;
96 #else
97       /* In PE mode, we do not offset the common symbol.  */
98       diff = reloc_entry->addend;
99 #endif
100     }
101   else
102     {
103       /* For some reason bfd_perform_relocation always effectively
104          ignores the addend for a COFF target when producing
105          relocateable output.  This seems to be always wrong for 386
106          COFF, so we handle the addend here instead.  */
107 #ifdef COFF_WITH_PE
108       if (output_bfd == (bfd *) NULL)
109         {
110           reloc_howto_type *howto = reloc_entry->howto;
111
112           /* Although PC relative relocations are very similar between
113              PE and non-PE formats, but they are off by 1 << howto->size
114              bytes. For the external relocation, PE is very different
115              from others. See md_apply_fix3 () in gas/config/tc-i386.c.
116              When we link PE and non-PE object files together to
117              generate a non-PE executable, we have to compensate it
118              here.  */
119           if (howto->pc_relative == true && howto->pcrel_offset == true)
120             diff = -(1 << howto->size);
121           else
122             diff = -reloc_entry->addend;
123         }
124       else
125 #endif
126         diff = reloc_entry->addend;
127     }
128
129 #ifdef COFF_WITH_PE
130   /* FIXME: How should this case be handled?  */
131   if (reloc_entry->howto->type == R_IMAGEBASE)
132     diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;
133 #endif
134
135 #define DOIT(x) \
136   x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
137
138     if (diff != 0)
139       {
140         reloc_howto_type *howto = reloc_entry->howto;
141         unsigned char *addr = (unsigned char *) data + reloc_entry->address;
142
143         switch (howto->size)
144           {
145           case 0:
146             {
147               char x = bfd_get_8 (abfd, addr);
148               DOIT (x);
149               bfd_put_8 (abfd, x, addr);
150             }
151             break;
152
153           case 1:
154             {
155               short x = bfd_get_16 (abfd, addr);
156               DOIT (x);
157               bfd_put_16 (abfd, x, addr);
158             }
159             break;
160
161           case 2:
162             {
163               long x = bfd_get_32 (abfd, addr);
164               DOIT (x);
165               bfd_put_32 (abfd, x, addr);
166             }
167             break;
168
169           default:
170             abort ();
171           }
172       }
173
174   /* Now let bfd_perform_relocation finish everything up.  */
175   return bfd_reloc_continue;
176 }
177
178 #ifdef COFF_WITH_PE
179
180 /* Return true if this relocation should appear in the output .reloc
181    section.  */
182
183 static boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
184
185 static boolean in_reloc_p (abfd, howto)
186      bfd *abfd ATTRIBUTE_UNUSED;
187      reloc_howto_type *howto;
188 {
189   return ! howto->pc_relative && howto->type != R_IMAGEBASE;
190 }
191
192 #endif /* COFF_WITH_PE */
193
194 #ifndef PCRELOFFSET
195 #define PCRELOFFSET false
196 #endif
197
198 static reloc_howto_type howto_table[] =
199 {
200   EMPTY_HOWTO (0),
201   EMPTY_HOWTO (1),
202   EMPTY_HOWTO (2),
203   EMPTY_HOWTO (3),
204   EMPTY_HOWTO (4),
205   EMPTY_HOWTO (5),
206   HOWTO (R_DIR32,               /* type */
207          0,                     /* rightshift */
208          2,                     /* size (0 = byte, 1 = short, 2 = long) */
209          32,                    /* bitsize */
210          false,                 /* pc_relative */
211          0,                     /* bitpos */
212          complain_overflow_bitfield, /* complain_on_overflow */
213          coff_i386_reloc,       /* special_function */
214          "dir32",               /* name */
215          true,                  /* partial_inplace */
216          0xffffffff,            /* src_mask */
217          0xffffffff,            /* dst_mask */
218          true),                 /* pcrel_offset */
219   /* PE IMAGE_REL_I386_DIR32NB relocation (7).  */
220   HOWTO (R_IMAGEBASE,           /* type */
221          0,                     /* rightshift */
222          2,                     /* size (0 = byte, 1 = short, 2 = long) */
223          32,                    /* bitsize */
224          false,                 /* pc_relative */
225          0,                     /* bitpos */
226          complain_overflow_bitfield, /* complain_on_overflow */
227          coff_i386_reloc,       /* special_function */
228          "rva32",               /* name */
229          true,                  /* partial_inplace */
230          0xffffffff,            /* src_mask */
231          0xffffffff,            /* dst_mask */
232          false),                /* pcrel_offset */
233   EMPTY_HOWTO (010),
234   EMPTY_HOWTO (011),
235   EMPTY_HOWTO (012),
236   EMPTY_HOWTO (013),
237   EMPTY_HOWTO (014),
238   EMPTY_HOWTO (015),
239   EMPTY_HOWTO (016),
240   /* Byte relocation (017).  */
241   HOWTO (R_RELBYTE,             /* type */
242          0,                     /* rightshift */
243          0,                     /* size (0 = byte, 1 = short, 2 = long) */
244          8,                     /* bitsize */
245          false,                 /* pc_relative */
246          0,                     /* bitpos */
247          complain_overflow_bitfield, /* complain_on_overflow */
248          coff_i386_reloc,       /* special_function */
249          "8",                   /* name */
250          true,                  /* partial_inplace */
251          0x000000ff,            /* src_mask */
252          0x000000ff,            /* dst_mask */
253          PCRELOFFSET),          /* pcrel_offset */
254   /* 16-bit word relocation (020).  */
255   HOWTO (R_RELWORD,             /* type */
256          0,                     /* rightshift */
257          1,                     /* size (0 = byte, 1 = short, 2 = long) */
258          16,                    /* bitsize */
259          false,                 /* pc_relative */
260          0,                     /* bitpos */
261          complain_overflow_bitfield, /* complain_on_overflow */
262          coff_i386_reloc,       /* special_function */
263          "16",                  /* name */
264          true,                  /* partial_inplace */
265          0x0000ffff,            /* src_mask */
266          0x0000ffff,            /* dst_mask */
267          PCRELOFFSET),          /* pcrel_offset */
268   /* 32-bit longword relocation (021).  */
269   HOWTO (R_RELLONG,             /* type */
270          0,                     /* rightshift */
271          2,                     /* size (0 = byte, 1 = short, 2 = long) */
272          32,                    /* bitsize */
273          false,                 /* pc_relative */
274          0,                     /* bitpos */
275          complain_overflow_bitfield, /* complain_on_overflow */
276          coff_i386_reloc,       /* special_function */
277          "32",                  /* name */
278          true,                  /* partial_inplace */
279          0xffffffff,            /* src_mask */
280          0xffffffff,            /* dst_mask */
281          PCRELOFFSET),          /* pcrel_offset */
282   /* Byte PC relative relocation (022).  */
283   HOWTO (R_PCRBYTE,             /* type */
284          0,                     /* rightshift */
285          0,                     /* size (0 = byte, 1 = short, 2 = long) */
286          8,                     /* bitsize */
287          true,                  /* pc_relative */
288          0,                     /* bitpos */
289          complain_overflow_signed, /* complain_on_overflow */
290          coff_i386_reloc,       /* special_function */
291          "DISP8",               /* name */
292          true,                  /* partial_inplace */
293          0x000000ff,            /* src_mask */
294          0x000000ff,            /* dst_mask */
295          PCRELOFFSET),          /* pcrel_offset */
296   /* 16-bit word PC relative relocation (023).  */
297   HOWTO (R_PCRWORD,             /* type */
298          0,                     /* rightshift */
299          1,                     /* size (0 = byte, 1 = short, 2 = long) */
300          16,                    /* bitsize */
301          true,                  /* pc_relative */
302          0,                     /* bitpos */
303          complain_overflow_signed, /* complain_on_overflow */
304          coff_i386_reloc,       /* special_function */
305          "DISP16",              /* name */
306          true,                  /* partial_inplace */
307          0x0000ffff,            /* src_mask */
308          0x0000ffff,            /* dst_mask */
309          PCRELOFFSET),          /* pcrel_offset */
310   /* 32-bit longword PC relative relocation (024).  */
311   HOWTO (R_PCRLONG,             /* type */
312          0,                     /* rightshift */
313          2,                     /* size (0 = byte, 1 = short, 2 = long) */
314          32,                    /* bitsize */
315          true,                  /* pc_relative */
316          0,                     /* bitpos */
317          complain_overflow_signed, /* complain_on_overflow */
318          coff_i386_reloc,       /* special_function */
319          "DISP32",              /* name */
320          true,                  /* partial_inplace */
321          0xffffffff,            /* src_mask */
322          0xffffffff,            /* dst_mask */
323          PCRELOFFSET)           /* pcrel_offset */
324 };
325
326 /* Turn a howto into a reloc  nunmber */
327
328 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
329 #define BADMAG(x) I386BADMAG(x)
330 #define I386 1                  /* Customize coffcode.h */
331
332 #define RTYPE2HOWTO(cache_ptr, dst)                                     \
333   ((cache_ptr)->howto =                                                 \
334    ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0])      \
335     ? howto_table + (dst)->r_type                                       \
336     : NULL))
337
338 /* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
339    library.  On some other COFF targets STYP_BSS is normally
340    STYP_NOLOAD.  */
341 #define BSS_NOLOAD_IS_SHARED_LIBRARY
342
343 /* Compute the addend of a reloc.  If the reloc is to a common symbol,
344    the object file contains the value of the common symbol.  By the
345    time this is called, the linker may be using a different symbol
346    from a different object file with a different value.  Therefore, we
347    hack wildly to locate the original symbol from this file so that we
348    can make the correct adjustment.  This macro sets coffsym to the
349    symbol from the original file, and uses it to set the addend value
350    correctly.  If this is not a common symbol, the usual addend
351    calculation is done, except that an additional tweak is needed for
352    PC relative relocs.
353    FIXME: This macro refers to symbols and asect; these are from the
354    calling function, not the macro arguments.  */
355
356 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)                \
357   {                                                             \
358     coff_symbol_type *coffsym = (coff_symbol_type *) NULL;      \
359     if (ptr && bfd_asymbol_bfd (ptr) != abfd)                   \
360       coffsym = (obj_symbols (abfd)                             \
361                  + (cache_ptr->sym_ptr_ptr - symbols));         \
362     else if (ptr)                                               \
363       coffsym = coff_symbol_from (abfd, ptr);                   \
364     if (coffsym != (coff_symbol_type *) NULL                    \
365         && coffsym->native->u.syment.n_scnum == 0)              \
366       cache_ptr->addend = - coffsym->native->u.syment.n_value;  \
367     else if (ptr && bfd_asymbol_bfd (ptr) == abfd               \
368              && ptr->section != (asection *) NULL)              \
369       cache_ptr->addend = - (ptr->section->vma + ptr->value);   \
370     else                                                        \
371       cache_ptr->addend = 0;                                    \
372     if (ptr && howto_table[reloc.r_type].pc_relative)           \
373       cache_ptr->addend += asect->vma;                          \
374   }
375
376 /* We use the special COFF backend linker.  For normal i386 COFF, we
377    can use the generic relocate_section routine.  For PE, we need our
378    own routine.  */
379
380 #ifndef COFF_WITH_PE
381
382 #define coff_relocate_section _bfd_coff_generic_relocate_section
383
384 #else /* COFF_WITH_PE */
385
386 /* The PE relocate section routine.  The only difference between this
387    and the regular routine is that we don't want to do anything for a
388    relocateable link.  */
389
390 static boolean coff_pe_i386_relocate_section
391   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
392            struct internal_reloc *, struct internal_syment *, asection **));
393
394 static boolean
395 coff_pe_i386_relocate_section (output_bfd, info, input_bfd,
396                                input_section, contents, relocs, syms,
397                                sections)
398      bfd *output_bfd;
399      struct bfd_link_info *info;
400      bfd *input_bfd;
401      asection *input_section;
402      bfd_byte *contents;
403      struct internal_reloc *relocs;
404      struct internal_syment *syms;
405      asection **sections;
406 {
407   if (info->relocateable)
408     return true;
409
410   return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
411                                              input_section, contents,
412                                              relocs, syms, sections);
413 }
414
415 #define coff_relocate_section coff_pe_i386_relocate_section
416
417 #endif /* COFF_WITH_PE */
418
419 /* Convert an rtype to howto for the COFF backend linker.  */
420
421 static reloc_howto_type *
422 coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
423      bfd *abfd ATTRIBUTE_UNUSED;
424      asection *sec;
425      struct internal_reloc *rel;
426      struct coff_link_hash_entry *h;
427      struct internal_syment *sym;
428      bfd_vma *addendp;
429 {
430   reloc_howto_type *howto;
431
432   if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0]))
433     {
434       bfd_set_error (bfd_error_bad_value);
435       return NULL;
436     }
437
438   howto = howto_table + rel->r_type;
439
440 #ifdef COFF_WITH_PE
441   /* Cancel out code in _bfd_coff_generic_relocate_section.  */
442   *addendp = 0;
443 #endif
444
445   if (howto->pc_relative)
446     *addendp += sec->vma;
447
448   if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
449     {
450       /* This is a common symbol.  The section contents include the
451          size (sym->n_value) as an addend.  The relocate_section
452          function will be adding in the final value of the symbol.  We
453          need to subtract out the current size in order to get the
454          correct result.  */
455
456       BFD_ASSERT (h != NULL);
457
458 #ifndef COFF_WITH_PE
459       /* I think we *do* want to bypass this.  If we don't, I have
460          seen some data parameters get the wrong relocation address.
461          If I link two versions with and without this section bypassed
462          and then do a binary comparison, the addresses which are
463          different can be looked up in the map.  The case in which
464          this section has been bypassed has addresses which correspond
465          to values I can find in the map.  */
466       *addendp -= sym->n_value;
467 #endif
468     }
469
470 #ifndef COFF_WITH_PE
471   /* If the output symbol is common (in which case this must be a
472      relocateable link), we need to add in the final size of the
473      common symbol.  */
474   if (h != NULL && h->root.type == bfd_link_hash_common)
475     *addendp += h->root.u.c.size;
476 #endif
477
478 #ifdef COFF_WITH_PE
479   if (howto->pc_relative)
480     {
481       *addendp -= 4;
482
483       /* If the symbol is defined, then the generic code is going to
484          add back the symbol value in order to cancel out an
485          adjustment it made to the addend.  However, we set the addend
486          to 0 at the start of this function.  We need to adjust here,
487          to avoid the adjustment the generic code will make.  FIXME:
488          This is getting a bit hackish.  */
489       if (sym != NULL && sym->n_scnum != 0)
490         *addendp -= sym->n_value;
491     }
492
493   if (rel->r_type == R_IMAGEBASE)
494     {
495       *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
496     }
497 #endif
498
499   return howto;
500 }
501
502 #define coff_bfd_reloc_type_lookup coff_i386_reloc_type_lookup
503
504 static reloc_howto_type *
505 coff_i386_reloc_type_lookup (abfd, code)
506      bfd *abfd ATTRIBUTE_UNUSED;
507      bfd_reloc_code_real_type code;
508 {
509   switch (code)
510     {
511     case BFD_RELOC_RVA:
512       return howto_table + R_IMAGEBASE;
513     case BFD_RELOC_32:
514       return howto_table + R_DIR32;
515     case BFD_RELOC_32_PCREL:
516       return howto_table + R_PCRLONG;
517     case BFD_RELOC_16:
518       return howto_table + R_RELWORD;
519     case BFD_RELOC_16_PCREL:
520       return howto_table + R_PCRWORD;
521     case BFD_RELOC_8:
522       return howto_table + R_RELBYTE;
523     case BFD_RELOC_8_PCREL:
524       return howto_table + R_PCRBYTE;
525     default:
526       BFD_FAIL ();
527       return 0;
528     }
529 }
530
531 #define coff_rtype_to_howto coff_i386_rtype_to_howto
532
533 #ifdef TARGET_UNDERSCORE
534
535 /* If i386 gcc uses underscores for symbol names, then it does not use
536    a leading dot for local labels, so if TARGET_UNDERSCORE is defined
537    we treat all symbols starting with L as local.  */
538
539 static boolean coff_i386_is_local_label_name PARAMS ((bfd *, const char *));
540
541 static boolean
542 coff_i386_is_local_label_name (abfd, name)
543      bfd *abfd;
544      const char *name;
545 {
546   if (name[0] == 'L')
547     return true;
548
549   return _bfd_coff_is_local_label_name (abfd, name);
550 }
551
552 #define coff_bfd_is_local_label_name coff_i386_is_local_label_name
553
554 #endif /* TARGET_UNDERSCORE */
555
556 #include "coffcode.h"
557
558 const bfd_target
559 #ifdef TARGET_SYM
560   TARGET_SYM =
561 #else
562   i386coff_vec =
563 #endif
564 {
565 #ifdef TARGET_NAME
566   TARGET_NAME,
567 #else
568   "coff-i386",                  /* name */
569 #endif
570   bfd_target_coff_flavour,
571   BFD_ENDIAN_LITTLE,            /* data byte order is little */
572   BFD_ENDIAN_LITTLE,            /* header byte order is little */
573
574   (HAS_RELOC | EXEC_P |         /* object flags */
575    HAS_LINENO | HAS_DEBUG |
576    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
577
578   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
579 #ifdef COFF_WITH_PE
580    | SEC_LINK_ONCE | SEC_LINK_DUPLICATES
581 #endif
582    | SEC_CODE | SEC_DATA),
583
584 #ifdef TARGET_UNDERSCORE
585   TARGET_UNDERSCORE,            /* leading underscore */
586 #else
587   0,                            /* leading underscore */
588 #endif
589   '/',                          /* ar_pad_char */
590   15,                           /* ar_max_namelen */
591
592   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
593      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
594      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
595   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
596      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
597      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
598
599 /* Note that we allow an object file to be treated as a core file as well. */
600     {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
601        bfd_generic_archive_p, coff_object_p},
602     {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
603        bfd_false},
604     {bfd_false, coff_write_object_contents, /* bfd_write_contents */
605        _bfd_write_archive_contents, bfd_false},
606
607      BFD_JUMP_TABLE_GENERIC (coff),
608      BFD_JUMP_TABLE_COPY (coff),
609      BFD_JUMP_TABLE_CORE (_bfd_nocore),
610      BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
611      BFD_JUMP_TABLE_SYMBOLS (coff),
612      BFD_JUMP_TABLE_RELOCS (coff),
613      BFD_JUMP_TABLE_WRITE (coff),
614      BFD_JUMP_TABLE_LINK (coff),
615      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
616
617   NULL,
618
619   COFF_SWAP_TABLE
620 };