OSDN Git Service

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