Back to index

cell-binutils  2.17cvs20070401
coff-i386.c
Go to the documentation of this file.
00001 /* BFD back-end for Intel 386 COFF files.
00002    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
00003    2000, 2001, 2002, 2003, 2004, 2007
00004    Free Software Foundation, Inc.
00005    Written by Cygnus Support.
00006 
00007    This file is part of BFD, the Binary File Descriptor library.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00022 
00023 #include "bfd.h"
00024 #include "sysdep.h"
00025 #include "libbfd.h"
00026 
00027 #include "coff/i386.h"
00028 
00029 #include "coff/internal.h"
00030 
00031 #ifdef COFF_WITH_PE
00032 #include "coff/pe.h"
00033 #endif
00034 
00035 #ifdef COFF_GO32_EXE
00036 #include "coff/go32exe.h"
00037 #endif
00038 
00039 #include "libcoff.h"
00040 
00041 static bfd_reloc_status_type coff_i386_reloc
00042   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00043 static reloc_howto_type *coff_i386_rtype_to_howto
00044   PARAMS ((bfd *, asection *, struct internal_reloc *,
00045           struct coff_link_hash_entry *, struct internal_syment *,
00046           bfd_vma *));
00047 static reloc_howto_type *coff_i386_reloc_type_lookup
00048   PARAMS ((bfd *, bfd_reloc_code_real_type));
00049 
00050 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
00051 /* The page size is a guess based on ELF.  */
00052 
00053 #define COFF_PAGE_SIZE 0x1000
00054 
00055 /* For some reason when using i386 COFF the value stored in the .text
00056    section for a reference to a common symbol is the value itself plus
00057    any desired offset.  Ian Taylor, Cygnus Support.  */
00058 
00059 /* If we are producing relocatable output, we need to do some
00060    adjustments to the object file that are not done by the
00061    bfd_perform_relocation function.  This function is called by every
00062    reloc type to make any required adjustments.  */
00063 
00064 static bfd_reloc_status_type
00065 coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
00066                error_message)
00067      bfd *abfd;
00068      arelent *reloc_entry;
00069      asymbol *symbol;
00070      PTR data;
00071      asection *input_section ATTRIBUTE_UNUSED;
00072      bfd *output_bfd;
00073      char **error_message ATTRIBUTE_UNUSED;
00074 {
00075   symvalue diff;
00076 
00077 #ifndef COFF_WITH_PE
00078   if (output_bfd == (bfd *) NULL)
00079     return bfd_reloc_continue;
00080 #endif
00081 
00082   if (bfd_is_com_section (symbol->section))
00083     {
00084 #ifndef COFF_WITH_PE
00085       /* We are relocating a common symbol.  The current value in the
00086         object file is ORIG + OFFSET, where ORIG is the value of the
00087         common symbol as seen by the object file when it was compiled
00088         (this may be zero if the symbol was undefined) and OFFSET is
00089         the offset into the common symbol (normally zero, but may be
00090         non-zero when referring to a field in a common structure).
00091         ORIG is the negative of reloc_entry->addend, which is set by
00092         the CALC_ADDEND macro below.  We want to replace the value in
00093         the object file with NEW + OFFSET, where NEW is the value of
00094         the common symbol which we are going to put in the final
00095         object file.  NEW is symbol->value.  */
00096       diff = symbol->value + reloc_entry->addend;
00097 #else
00098       /* In PE mode, we do not offset the common symbol.  */
00099       diff = reloc_entry->addend;
00100 #endif
00101     }
00102   else
00103     {
00104       /* For some reason bfd_perform_relocation always effectively
00105         ignores the addend for a COFF target when producing
00106         relocatable output.  This seems to be always wrong for 386
00107         COFF, so we handle the addend here instead.  */
00108 #ifdef COFF_WITH_PE
00109       if (output_bfd == (bfd *) NULL)
00110        {
00111          reloc_howto_type *howto = reloc_entry->howto;
00112 
00113          /* Although PC relative relocations are very similar between
00114             PE and non-PE formats, but they are off by 1 << howto->size
00115             bytes. For the external relocation, PE is very different
00116             from others. See md_apply_fix3 () in gas/config/tc-i386.c.
00117             When we link PE and non-PE object files together to
00118             generate a non-PE executable, we have to compensate it
00119             here.  */
00120          if (howto->pc_relative && howto->pcrel_offset)
00121            diff = -(1 << howto->size);
00122          else if (symbol->flags & BSF_WEAK)
00123            diff = reloc_entry->addend - symbol->value;
00124          else
00125            diff = -reloc_entry->addend;
00126        }
00127       else
00128 #endif
00129        diff = reloc_entry->addend;
00130     }
00131 
00132 #ifdef COFF_WITH_PE
00133   /* FIXME: How should this case be handled?  */
00134   if (reloc_entry->howto->type == R_IMAGEBASE
00135       && output_bfd != NULL
00136       && bfd_get_flavour(output_bfd) == bfd_target_coff_flavour)
00137     diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;
00138 #endif
00139 
00140 #define DOIT(x) \
00141   x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
00142 
00143     if (diff != 0)
00144       {
00145        reloc_howto_type *howto = reloc_entry->howto;
00146        unsigned char *addr = (unsigned char *) data + reloc_entry->address;
00147 
00148        switch (howto->size)
00149          {
00150          case 0:
00151            {
00152              char x = bfd_get_8 (abfd, addr);
00153              DOIT (x);
00154              bfd_put_8 (abfd, x, addr);
00155            }
00156            break;
00157 
00158          case 1:
00159            {
00160              short x = bfd_get_16 (abfd, addr);
00161              DOIT (x);
00162              bfd_put_16 (abfd, (bfd_vma) x, addr);
00163            }
00164            break;
00165 
00166          case 2:
00167            {
00168              long x = bfd_get_32 (abfd, addr);
00169              DOIT (x);
00170              bfd_put_32 (abfd, (bfd_vma) x, addr);
00171            }
00172            break;
00173 
00174          default:
00175            abort ();
00176          }
00177       }
00178 
00179   /* Now let bfd_perform_relocation finish everything up.  */
00180   return bfd_reloc_continue;
00181 }
00182 
00183 #ifdef COFF_WITH_PE
00184 /* Return TRUE if this relocation should appear in the output .reloc
00185    section.  */
00186 
00187 static bfd_boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
00188 
00189 static bfd_boolean in_reloc_p (abfd, howto)
00190      bfd * abfd ATTRIBUTE_UNUSED;
00191      reloc_howto_type *howto;
00192 {
00193   return ! howto->pc_relative && howto->type != R_IMAGEBASE;
00194 }
00195 #endif /* COFF_WITH_PE */
00196 
00197 #ifndef PCRELOFFSET
00198 #define PCRELOFFSET FALSE
00199 #endif
00200 
00201 static reloc_howto_type howto_table[] =
00202 {
00203   EMPTY_HOWTO (0),
00204   EMPTY_HOWTO (1),
00205   EMPTY_HOWTO (2),
00206   EMPTY_HOWTO (3),
00207   EMPTY_HOWTO (4),
00208   EMPTY_HOWTO (5),
00209   HOWTO (R_DIR32,           /* type */
00210         0,                  /* rightshift */
00211         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00212         32,                 /* bitsize */
00213         FALSE,                     /* pc_relative */
00214         0,                  /* bitpos */
00215         complain_overflow_bitfield, /* complain_on_overflow */
00216         coff_i386_reloc,    /* special_function */
00217         "dir32",            /* name */
00218         TRUE,               /* partial_inplace */
00219         0xffffffff,         /* src_mask */
00220         0xffffffff,         /* dst_mask */
00221         TRUE),                     /* pcrel_offset */
00222   /* PE IMAGE_REL_I386_DIR32NB relocation (7).   */
00223   HOWTO (R_IMAGEBASE,              /* type */
00224         0,                  /* rightshift */
00225         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00226         32,                 /* bitsize */
00227         FALSE,                     /* pc_relative */
00228         0,                  /* bitpos */
00229         complain_overflow_bitfield, /* complain_on_overflow */
00230         coff_i386_reloc,    /* special_function */
00231         "rva32",            /* name */
00232         TRUE,               /* partial_inplace */
00233         0xffffffff,         /* src_mask */
00234         0xffffffff,         /* dst_mask */
00235         FALSE),             /* pcrel_offset */
00236   EMPTY_HOWTO (010),
00237   EMPTY_HOWTO (011),
00238   EMPTY_HOWTO (012),
00239 #ifdef COFF_WITH_PE
00240   /* 32-bit longword section relative relocation (013).  */
00241   HOWTO (R_SECREL32,        /* type */
00242         0,                  /* rightshift */
00243         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00244         32,                 /* bitsize */
00245         FALSE,                     /* pc_relative */
00246         0,                  /* bitpos */
00247         complain_overflow_bitfield, /* complain_on_overflow */
00248         coff_i386_reloc,    /* special_function */
00249         "secrel32",         /* name */
00250         TRUE,               /* partial_inplace */
00251         0xffffffff,         /* src_mask */
00252         0xffffffff,         /* dst_mask */
00253         TRUE),                     /* pcrel_offset */
00254 #else
00255   EMPTY_HOWTO (013),
00256 #endif
00257   EMPTY_HOWTO (014),
00258   EMPTY_HOWTO (015),
00259   EMPTY_HOWTO (016),
00260   /* Byte relocation (017).  */
00261   HOWTO (R_RELBYTE,         /* type */
00262         0,                  /* rightshift */
00263         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00264         8,                  /* bitsize */
00265         FALSE,                     /* pc_relative */
00266         0,                  /* bitpos */
00267         complain_overflow_bitfield, /* complain_on_overflow */
00268         coff_i386_reloc,    /* special_function */
00269         "8",                /* name */
00270         TRUE,               /* partial_inplace */
00271         0x000000ff,         /* src_mask */
00272         0x000000ff,         /* dst_mask */
00273         PCRELOFFSET),              /* pcrel_offset */
00274   /* 16-bit word relocation (020).  */
00275   HOWTO (R_RELWORD,         /* type */
00276         0,                  /* rightshift */
00277         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00278         16,                 /* bitsize */
00279         FALSE,                     /* pc_relative */
00280         0,                  /* bitpos */
00281         complain_overflow_bitfield, /* complain_on_overflow */
00282         coff_i386_reloc,    /* special_function */
00283         "16",               /* name */
00284         TRUE,               /* partial_inplace */
00285         0x0000ffff,         /* src_mask */
00286         0x0000ffff,         /* dst_mask */
00287         PCRELOFFSET),              /* pcrel_offset */
00288   /* 32-bit longword relocation (021).    */
00289   HOWTO (R_RELLONG,         /* type */
00290         0,                  /* rightshift */
00291         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00292         32,                 /* bitsize */
00293         FALSE,                     /* pc_relative */
00294         0,                  /* bitpos */
00295         complain_overflow_bitfield, /* complain_on_overflow */
00296         coff_i386_reloc,    /* special_function */
00297         "32",               /* name */
00298         TRUE,               /* partial_inplace */
00299         0xffffffff,         /* src_mask */
00300         0xffffffff,         /* dst_mask */
00301         PCRELOFFSET),              /* pcrel_offset */
00302   /* Byte PC relative relocation (022).    */
00303   HOWTO (R_PCRBYTE,         /* type */
00304         0,                  /* rightshift */
00305         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00306         8,                  /* bitsize */
00307         TRUE,               /* pc_relative */
00308         0,                  /* bitpos */
00309         complain_overflow_signed, /* complain_on_overflow */
00310         coff_i386_reloc,    /* special_function */
00311         "DISP8",            /* name */
00312         TRUE,               /* partial_inplace */
00313         0x000000ff,         /* src_mask */
00314         0x000000ff,         /* dst_mask */
00315         PCRELOFFSET),              /* pcrel_offset */
00316   /* 16-bit word PC relative relocation (023).   */
00317   HOWTO (R_PCRWORD,         /* type */
00318         0,                  /* rightshift */
00319         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00320         16,                 /* bitsize */
00321         TRUE,               /* pc_relative */
00322         0,                  /* bitpos */
00323         complain_overflow_signed, /* complain_on_overflow */
00324         coff_i386_reloc,    /* special_function */
00325         "DISP16",           /* name */
00326         TRUE,               /* partial_inplace */
00327         0x0000ffff,         /* src_mask */
00328         0x0000ffff,         /* dst_mask */
00329         PCRELOFFSET),              /* pcrel_offset */
00330   /* 32-bit longword PC relative relocation (024).  */
00331   HOWTO (R_PCRLONG,         /* type */
00332         0,                  /* rightshift */
00333         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00334         32,                 /* bitsize */
00335         TRUE,               /* pc_relative */
00336         0,                  /* bitpos */
00337         complain_overflow_signed, /* complain_on_overflow */
00338         coff_i386_reloc,    /* special_function */
00339         "DISP32",           /* name */
00340         TRUE,               /* partial_inplace */
00341         0xffffffff,         /* src_mask */
00342         0xffffffff,         /* dst_mask */
00343         PCRELOFFSET)        /* pcrel_offset */
00344 };
00345 
00346 /* Turn a howto into a reloc  nunmber */
00347 
00348 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
00349 #define BADMAG(x) I386BADMAG(x)
00350 #define I386 1                     /* Customize coffcode.h */
00351 
00352 #define RTYPE2HOWTO(cache_ptr, dst)                                   \
00353   ((cache_ptr)->howto =                                               \
00354    ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0])    \
00355     ? howto_table + (dst)->r_type                              \
00356     : NULL))
00357 
00358 /* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
00359    library.  On some other COFF targets STYP_BSS is normally
00360    STYP_NOLOAD.  */
00361 #define BSS_NOLOAD_IS_SHARED_LIBRARY
00362 
00363 /* Compute the addend of a reloc.  If the reloc is to a common symbol,
00364    the object file contains the value of the common symbol.  By the
00365    time this is called, the linker may be using a different symbol
00366    from a different object file with a different value.  Therefore, we
00367    hack wildly to locate the original symbol from this file so that we
00368    can make the correct adjustment.  This macro sets coffsym to the
00369    symbol from the original file, and uses it to set the addend value
00370    correctly.  If this is not a common symbol, the usual addend
00371    calculation is done, except that an additional tweak is needed for
00372    PC relative relocs.
00373    FIXME: This macro refers to symbols and asect; these are from the
00374    calling function, not the macro arguments.  */
00375 
00376 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)        \
00377   {                                                     \
00378     coff_symbol_type *coffsym = (coff_symbol_type *) NULL;     \
00379     if (ptr && bfd_asymbol_bfd (ptr) != abfd)                  \
00380       coffsym = (obj_symbols (abfd)                            \
00381                 + (cache_ptr->sym_ptr_ptr - symbols));         \
00382     else if (ptr)                                       \
00383       coffsym = coff_symbol_from (abfd, ptr);                  \
00384     if (coffsym != (coff_symbol_type *) NULL                   \
00385        && coffsym->native->u.syment.n_scnum == 0)              \
00386       cache_ptr->addend = - coffsym->native->u.syment.n_value; \
00387     else if (ptr && bfd_asymbol_bfd (ptr) == abfd              \
00388             && ptr->section != (asection *) NULL)              \
00389       cache_ptr->addend = - (ptr->section->vma + ptr->value);  \
00390     else                                                \
00391       cache_ptr->addend = 0;                                   \
00392     if (ptr && howto_table[reloc.r_type].pc_relative)          \
00393       cache_ptr->addend += asect->vma;                         \
00394   }
00395 
00396 /* We use the special COFF backend linker.  For normal i386 COFF, we
00397    can use the generic relocate_section routine.  For PE, we need our
00398    own routine.  */
00399 
00400 #ifndef COFF_WITH_PE
00401 
00402 #define coff_relocate_section _bfd_coff_generic_relocate_section
00403 
00404 #else /* COFF_WITH_PE */
00405 
00406 /* The PE relocate section routine.  The only difference between this
00407    and the regular routine is that we don't want to do anything for a
00408    relocatable link.  */
00409 
00410 static bfd_boolean coff_pe_i386_relocate_section
00411   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
00412           struct internal_reloc *, struct internal_syment *, asection **));
00413 
00414 static bfd_boolean
00415 coff_pe_i386_relocate_section (output_bfd, info, input_bfd,
00416                             input_section, contents, relocs, syms,
00417                             sections)
00418      bfd *output_bfd;
00419      struct bfd_link_info *info;
00420      bfd *input_bfd;
00421      asection *input_section;
00422      bfd_byte *contents;
00423      struct internal_reloc *relocs;
00424      struct internal_syment *syms;
00425      asection **sections;
00426 {
00427   if (info->relocatable)
00428     return TRUE;
00429 
00430   return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
00431                                         input_section, contents,
00432                                         relocs, syms, sections);
00433 }
00434 
00435 #define coff_relocate_section coff_pe_i386_relocate_section
00436 
00437 #endif /* COFF_WITH_PE */
00438 
00439 /* Convert an rtype to howto for the COFF backend linker.  */
00440 
00441 static reloc_howto_type *
00442 coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
00443      bfd *abfd ATTRIBUTE_UNUSED;
00444      asection *sec;
00445      struct internal_reloc *rel;
00446      struct coff_link_hash_entry *h;
00447      struct internal_syment *sym;
00448      bfd_vma *addendp;
00449 {
00450   reloc_howto_type *howto;
00451 
00452   if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0]))
00453     {
00454       bfd_set_error (bfd_error_bad_value);
00455       return NULL;
00456     }
00457 
00458   howto = howto_table + rel->r_type;
00459 
00460 #ifdef COFF_WITH_PE
00461   /* Cancel out code in _bfd_coff_generic_relocate_section.  */
00462   *addendp = 0;
00463 #endif
00464 
00465   if (howto->pc_relative)
00466     *addendp += sec->vma;
00467 
00468   if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
00469     {
00470       /* This is a common symbol.  The section contents include the
00471         size (sym->n_value) as an addend.  The relocate_section
00472         function will be adding in the final value of the symbol.  We
00473         need to subtract out the current size in order to get the
00474         correct result.  */
00475 
00476       BFD_ASSERT (h != NULL);
00477 
00478 #ifndef COFF_WITH_PE
00479       /* I think we *do* want to bypass this.  If we don't, I have
00480         seen some data parameters get the wrong relocation address.
00481         If I link two versions with and without this section bypassed
00482         and then do a binary comparison, the addresses which are
00483         different can be looked up in the map.  The case in which
00484         this section has been bypassed has addresses which correspond
00485         to values I can find in the map.  */
00486       *addendp -= sym->n_value;
00487 #endif
00488     }
00489 
00490 #ifndef COFF_WITH_PE
00491   /* If the output symbol is common (in which case this must be a
00492      relocatable link), we need to add in the final size of the
00493      common symbol.  */
00494   if (h != NULL && h->root.type == bfd_link_hash_common)
00495     *addendp += h->root.u.c.size;
00496 #endif
00497 
00498 #ifdef COFF_WITH_PE
00499   if (howto->pc_relative)
00500     {
00501       *addendp -= 4;
00502 
00503       /* If the symbol is defined, then the generic code is going to
00504          add back the symbol value in order to cancel out an
00505          adjustment it made to the addend.  However, we set the addend
00506          to 0 at the start of this function.  We need to adjust here,
00507          to avoid the adjustment the generic code will make.  FIXME:
00508          This is getting a bit hackish.  */
00509       if (sym != NULL && sym->n_scnum != 0)
00510        *addendp -= sym->n_value;
00511     }
00512 
00513   if (rel->r_type == R_IMAGEBASE
00514       && (bfd_get_flavour(sec->output_section->owner)
00515          == bfd_target_coff_flavour))
00516     {
00517       *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
00518     }
00519 
00520   if (rel->r_type == R_SECREL32)
00521     {
00522       bfd_vma osect_vma;
00523 
00524       if (h && (h->type == bfd_link_hash_defined
00525               || h->type == bfd_link_hash_defweak))
00526        osect_vma = h->root.u.def.section->output_section->vma;
00527       else
00528        {
00529          asection *sec;
00530          int i;
00531 
00532          /* Sigh, the only way to get the section to offset against
00533             is to find it the hard way.  */
00534 
00535          for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++)
00536            sec = sec->next;
00537 
00538          osect_vma = sec->output_section->vma;
00539        }
00540 
00541       *addendp -= osect_vma;
00542     }
00543 #endif
00544 
00545   return howto;
00546 }
00547 
00548 #define coff_bfd_reloc_type_lookup coff_i386_reloc_type_lookup
00549 #define coff_bfd_reloc_name_lookup coff_i386_reloc_name_lookup
00550 
00551 static reloc_howto_type *
00552 coff_i386_reloc_type_lookup (abfd, code)
00553      bfd *abfd ATTRIBUTE_UNUSED;
00554      bfd_reloc_code_real_type code;
00555 {
00556   switch (code)
00557     {
00558     case BFD_RELOC_RVA:
00559       return howto_table + R_IMAGEBASE;
00560     case BFD_RELOC_32:
00561       return howto_table + R_DIR32;
00562     case BFD_RELOC_32_PCREL:
00563       return howto_table + R_PCRLONG;
00564     case BFD_RELOC_16:
00565       return howto_table + R_RELWORD;
00566     case BFD_RELOC_16_PCREL:
00567       return howto_table + R_PCRWORD;
00568     case BFD_RELOC_8:
00569       return howto_table + R_RELBYTE;
00570     case BFD_RELOC_8_PCREL:
00571       return howto_table + R_PCRBYTE;
00572 #ifdef COFF_WITH_PE
00573     case BFD_RELOC_32_SECREL:
00574       return howto_table + R_SECREL32;
00575 #endif
00576     default:
00577       BFD_FAIL ();
00578       return 0;
00579     }
00580 }
00581 
00582 static reloc_howto_type *
00583 coff_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00584                           const char *r_name)
00585 {
00586   unsigned int i;
00587 
00588   for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
00589     if (howto_table[i].name != NULL
00590        && strcasecmp (howto_table[i].name, r_name) == 0)
00591       return &howto_table[i];
00592 
00593   return NULL;
00594 }
00595 
00596 #define coff_rtype_to_howto coff_i386_rtype_to_howto
00597 
00598 #ifdef TARGET_UNDERSCORE
00599 
00600 /* If i386 gcc uses underscores for symbol names, then it does not use
00601    a leading dot for local labels, so if TARGET_UNDERSCORE is defined
00602    we treat all symbols starting with L as local.  */
00603 
00604 static bfd_boolean coff_i386_is_local_label_name
00605   PARAMS ((bfd *, const char *));
00606 
00607 static bfd_boolean
00608 coff_i386_is_local_label_name (abfd, name)
00609      bfd *abfd;
00610      const char *name;
00611 {
00612   if (name[0] == 'L')
00613     return TRUE;
00614 
00615   return _bfd_coff_is_local_label_name (abfd, name);
00616 }
00617 
00618 #define coff_bfd_is_local_label_name coff_i386_is_local_label_name
00619 
00620 #endif /* TARGET_UNDERSCORE */
00621 
00622 #include "coffcode.h"
00623 
00624 const bfd_target
00625 #ifdef TARGET_SYM
00626   TARGET_SYM =
00627 #else
00628   i386coff_vec =
00629 #endif
00630 {
00631 #ifdef TARGET_NAME
00632   TARGET_NAME,
00633 #else
00634   "coff-i386",                     /* name */
00635 #endif
00636   bfd_target_coff_flavour,
00637   BFD_ENDIAN_LITTLE,        /* data byte order is little */
00638   BFD_ENDIAN_LITTLE,        /* header byte order is little */
00639 
00640   (HAS_RELOC | EXEC_P |            /* object flags */
00641    HAS_LINENO | HAS_DEBUG |
00642    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
00643 
00644   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
00645 #ifdef COFF_WITH_PE
00646    | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY
00647 #endif
00648    | SEC_CODE | SEC_DATA),
00649 
00650 #ifdef TARGET_UNDERSCORE
00651   TARGET_UNDERSCORE,        /* leading underscore */
00652 #else
00653   0,                        /* leading underscore */
00654 #endif
00655   '/',                      /* ar_pad_char */
00656   15,                       /* ar_max_namelen */
00657 
00658   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
00659      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
00660      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
00661   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
00662      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
00663      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
00664 
00665 /* Note that we allow an object file to be treated as a core file as well.  */
00666     {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
00667        bfd_generic_archive_p, coff_object_p},
00668     {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
00669        bfd_false},
00670     {bfd_false, coff_write_object_contents, /* bfd_write_contents */
00671        _bfd_write_archive_contents, bfd_false},
00672 
00673      BFD_JUMP_TABLE_GENERIC (coff),
00674      BFD_JUMP_TABLE_COPY (coff),
00675      BFD_JUMP_TABLE_CORE (_bfd_nocore),
00676      BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
00677      BFD_JUMP_TABLE_SYMBOLS (coff),
00678      BFD_JUMP_TABLE_RELOCS (coff),
00679      BFD_JUMP_TABLE_WRITE (coff),
00680      BFD_JUMP_TABLE_LINK (coff),
00681      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
00682 
00683   NULL,
00684 
00685   COFF_SWAP_TABLE
00686 };