Back to index

cell-binutils  2.17cvs20070401
peXXigen.c
Go to the documentation of this file.
00001 /* Support for the generic parts of PE/PEI; the common executable parts.
00002    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
00003    2005, 2006 Free Software Foundation, Inc.
00004    Written by Cygnus Solutions.
00005 
00006    This file is part of BFD, the Binary File Descriptor library.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00021 
00022 /* Most of this hacked by Steve Chamberlain <sac@cygnus.com>.
00023 
00024    PE/PEI rearrangement (and code added): Donn Terry
00025                                      Softway Systems, Inc.  */
00026 
00027 /* Hey look, some documentation [and in a place you expect to find it]!
00028 
00029    The main reference for the pei format is "Microsoft Portable Executable
00030    and Common Object File Format Specification 4.1".  Get it if you need to
00031    do some serious hacking on this code.
00032 
00033    Another reference:
00034    "Peering Inside the PE: A Tour of the Win32 Portable Executable
00035    File Format", MSJ 1994, Volume 9.
00036 
00037    The *sole* difference between the pe format and the pei format is that the
00038    latter has an MSDOS 2.0 .exe header on the front that prints the message
00039    "This app must be run under Windows." (or some such).
00040    (FIXME: Whether that statement is *really* true or not is unknown.
00041    Are there more subtle differences between pe and pei formats?
00042    For now assume there aren't.  If you find one, then for God sakes
00043    document it here!)
00044 
00045    The Microsoft docs use the word "image" instead of "executable" because
00046    the former can also refer to a DLL (shared library).  Confusion can arise
00047    because the `i' in `pei' also refers to "image".  The `pe' format can
00048    also create images (i.e. executables), it's just that to run on a win32
00049    system you need to use the pei format.
00050 
00051    FIXME: Please add more docs here so the next poor fool that has to hack
00052    on this code has a chance of getting something accomplished without
00053    wasting too much time.  */
00054 
00055 /* This expands into COFF_WITH_pe, COFF_WITH_pep, or COFF_WITH_pex64
00056    depending on whether we're compiling for straight PE or PE+.  */
00057 #define COFF_WITH_XX
00058 
00059 #include "bfd.h"
00060 #include "sysdep.h"
00061 #include "libbfd.h"
00062 #include "coff/internal.h"
00063 
00064 /* NOTE: it's strange to be including an architecture specific header
00065    in what's supposed to be general (to PE/PEI) code.  However, that's
00066    where the definitions are, and they don't vary per architecture
00067    within PE/PEI, so we get them from there.  FIXME: The lack of
00068    variance is an assumption which may prove to be incorrect if new
00069    PE/PEI targets are created.  */
00070 #if defined COFF_WITH_pex64
00071 # include "coff/x86_64.h"
00072 #elif defined COFF_WITH_pep
00073 # include "coff/ia64.h"
00074 #else
00075 # include "coff/i386.h"
00076 #endif
00077 
00078 #include "coff/pe.h"
00079 #include "libcoff.h"
00080 #include "libpei.h"
00081 
00082 #if defined COFF_WITH_pep || defined COFF_WITH_pex64
00083 # undef AOUTSZ
00084 # define AOUTSZ             PEPAOUTSZ
00085 # define PEAOUTHDR   PEPAOUTHDR
00086 #endif
00087 
00088 /* FIXME: This file has various tests of POWERPC_LE_PE.  Those tests
00089    worked when the code was in peicode.h, but no longer work now that
00090    the code is in peigen.c.  PowerPC NT is said to be dead.  If
00091    anybody wants to revive the code, you will have to figure out how
00092    to handle those issues.  */
00093 
00094 void
00095 _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
00096 {
00097   SYMENT *ext = (SYMENT *) ext1;
00098   struct internal_syment *in = (struct internal_syment *) in1;
00099 
00100   if (ext->e.e_name[0] == 0)
00101     {
00102       in->_n._n_n._n_zeroes = 0;
00103       in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
00104     }
00105   else
00106     memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
00107 
00108   in->n_value = H_GET_32 (abfd, ext->e_value);
00109   in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
00110 
00111   if (sizeof (ext->e_type) == 2)
00112     in->n_type = H_GET_16 (abfd, ext->e_type);
00113   else
00114     in->n_type = H_GET_32 (abfd, ext->e_type);
00115 
00116   in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
00117   in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
00118 
00119 #ifndef STRICT_PE_FORMAT
00120   /* This is for Gnu-created DLLs.  */
00121 
00122   /* The section symbols for the .idata$ sections have class 0x68
00123      (C_SECTION), which MS documentation indicates is a section
00124      symbol.  Unfortunately, the value field in the symbol is simply a
00125      copy of the .idata section's flags rather than something useful.
00126      When these symbols are encountered, change the value to 0 so that
00127      they will be handled somewhat correctly in the bfd code.  */
00128   if (in->n_sclass == C_SECTION)
00129     {
00130       in->n_value = 0x0;
00131 
00132       /* Create synthetic empty sections as needed.  DJ */
00133       if (in->n_scnum == 0)
00134        {
00135          asection *sec;
00136 
00137          for (sec = abfd->sections; sec; sec = sec->next)
00138            {
00139              if (strcmp (sec->name, in->n_name) == 0)
00140               {
00141                 in->n_scnum = sec->target_index;
00142                 break;
00143               }
00144            }
00145        }
00146 
00147       if (in->n_scnum == 0)
00148        {
00149          int unused_section_number = 0;
00150          asection *sec;
00151          char *name;
00152          flagword flags;
00153 
00154          for (sec = abfd->sections; sec; sec = sec->next)
00155            if (unused_section_number <= sec->target_index)
00156              unused_section_number = sec->target_index + 1;
00157 
00158          name = bfd_alloc (abfd, (bfd_size_type) strlen (in->n_name) + 10);
00159          if (name == NULL)
00160            return;
00161          strcpy (name, in->n_name);
00162          flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
00163          sec = bfd_make_section_anyway_with_flags (abfd, name, flags);
00164 
00165          sec->vma = 0;
00166          sec->lma = 0;
00167          sec->size = 0;
00168          sec->filepos = 0;
00169          sec->rel_filepos = 0;
00170          sec->reloc_count = 0;
00171          sec->line_filepos = 0;
00172          sec->lineno_count = 0;
00173          sec->userdata = NULL;
00174          sec->next = NULL;
00175          sec->alignment_power = 2;
00176 
00177          sec->target_index = unused_section_number;
00178 
00179          in->n_scnum = unused_section_number;
00180        }
00181       in->n_sclass = C_STAT;
00182     }
00183 #endif
00184 
00185 #ifdef coff_swap_sym_in_hook
00186   /* This won't work in peigen.c, but since it's for PPC PE, it's not
00187      worth fixing.  */
00188   coff_swap_sym_in_hook (abfd, ext1, in1);
00189 #endif
00190 }
00191 
00192 unsigned int
00193 _bfd_XXi_swap_sym_out (bfd * abfd, void * inp, void * extp)
00194 {
00195   struct internal_syment *in = (struct internal_syment *) inp;
00196   SYMENT *ext = (SYMENT *) extp;
00197 
00198   if (in->_n._n_name[0] == 0)
00199     {
00200       H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
00201       H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
00202     }
00203   else
00204     memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
00205 
00206   H_PUT_32 (abfd, in->n_value, ext->e_value);
00207   H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
00208 
00209   if (sizeof (ext->e_type) == 2)
00210     H_PUT_16 (abfd, in->n_type, ext->e_type);
00211   else
00212     H_PUT_32 (abfd, in->n_type, ext->e_type);
00213 
00214   H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
00215   H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
00216 
00217   return SYMESZ;
00218 }
00219 
00220 void
00221 _bfd_XXi_swap_aux_in (bfd * abfd,
00222                     void *  ext1,
00223                     int       type,
00224                     int       class,
00225                     int     indx ATTRIBUTE_UNUSED,
00226                     int     numaux ATTRIBUTE_UNUSED,
00227                     void *  in1)
00228 {
00229   AUXENT *ext = (AUXENT *) ext1;
00230   union internal_auxent *in = (union internal_auxent *) in1;
00231 
00232   switch (class)
00233     {
00234     case C_FILE:
00235       if (ext->x_file.x_fname[0] == 0)
00236        {
00237          in->x_file.x_n.x_zeroes = 0;
00238          in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
00239        }
00240       else
00241        memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
00242       return;
00243 
00244     case C_STAT:
00245     case C_LEAFSTAT:
00246     case C_HIDDEN:
00247       if (type == T_NULL)
00248        {
00249          in->x_scn.x_scnlen = GET_SCN_SCNLEN (abfd, ext);
00250          in->x_scn.x_nreloc = GET_SCN_NRELOC (abfd, ext);
00251          in->x_scn.x_nlinno = GET_SCN_NLINNO (abfd, ext);
00252          in->x_scn.x_checksum = H_GET_32 (abfd, ext->x_scn.x_checksum);
00253          in->x_scn.x_associated = H_GET_16 (abfd, ext->x_scn.x_associated);
00254          in->x_scn.x_comdat = H_GET_8 (abfd, ext->x_scn.x_comdat);
00255          return;
00256        }
00257       break;
00258     }
00259 
00260   in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
00261   in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
00262 
00263   if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
00264     {
00265       in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
00266       in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
00267     }
00268   else
00269     {
00270       in->x_sym.x_fcnary.x_ary.x_dimen[0] =
00271        H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
00272       in->x_sym.x_fcnary.x_ary.x_dimen[1] =
00273        H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
00274       in->x_sym.x_fcnary.x_ary.x_dimen[2] =
00275        H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
00276       in->x_sym.x_fcnary.x_ary.x_dimen[3] =
00277        H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
00278     }
00279 
00280   if (ISFCN (type))
00281     {
00282       in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
00283     }
00284   else
00285     {
00286       in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO (abfd, ext);
00287       in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE (abfd, ext);
00288     }
00289 }
00290 
00291 unsigned int
00292 _bfd_XXi_swap_aux_out (bfd *  abfd,
00293                      void * inp,
00294                      int    type,
00295                      int    class,
00296                      int    indx ATTRIBUTE_UNUSED,
00297                      int    numaux ATTRIBUTE_UNUSED,
00298                      void * extp)
00299 {
00300   union internal_auxent *in = (union internal_auxent *) inp;
00301   AUXENT *ext = (AUXENT *) extp;
00302 
00303   memset (ext, 0, AUXESZ);
00304 
00305   switch (class)
00306     {
00307     case C_FILE:
00308       if (in->x_file.x_fname[0] == 0)
00309        {
00310          H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
00311          H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
00312        }
00313       else
00314        memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
00315 
00316       return AUXESZ;
00317 
00318     case C_STAT:
00319     case C_LEAFSTAT:
00320     case C_HIDDEN:
00321       if (type == T_NULL)
00322        {
00323          PUT_SCN_SCNLEN (abfd, in->x_scn.x_scnlen, ext);
00324          PUT_SCN_NRELOC (abfd, in->x_scn.x_nreloc, ext);
00325          PUT_SCN_NLINNO (abfd, in->x_scn.x_nlinno, ext);
00326          H_PUT_32 (abfd, in->x_scn.x_checksum, ext->x_scn.x_checksum);
00327          H_PUT_16 (abfd, in->x_scn.x_associated, ext->x_scn.x_associated);
00328          H_PUT_8 (abfd, in->x_scn.x_comdat, ext->x_scn.x_comdat);
00329          return AUXESZ;
00330        }
00331       break;
00332     }
00333 
00334   H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
00335   H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
00336 
00337   if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
00338     {
00339       PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,  ext);
00340       PUT_FCN_ENDNDX  (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
00341     }
00342   else
00343     {
00344       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
00345               ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
00346       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
00347               ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
00348       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
00349               ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
00350       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
00351               ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
00352     }
00353 
00354   if (ISFCN (type))
00355     H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
00356   else
00357     {
00358       PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
00359       PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
00360     }
00361 
00362   return AUXESZ;
00363 }
00364 
00365 void
00366 _bfd_XXi_swap_lineno_in (bfd * abfd, void * ext1, void * in1)
00367 {
00368   LINENO *ext = (LINENO *) ext1;
00369   struct internal_lineno *in = (struct internal_lineno *) in1;
00370 
00371   in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
00372   in->l_lnno = GET_LINENO_LNNO (abfd, ext);
00373 }
00374 
00375 unsigned int
00376 _bfd_XXi_swap_lineno_out (bfd * abfd, void * inp, void * outp)
00377 {
00378   struct internal_lineno *in = (struct internal_lineno *) inp;
00379   struct external_lineno *ext = (struct external_lineno *) outp;
00380   H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
00381 
00382   PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
00383   return LINESZ;
00384 }
00385 
00386 void
00387 _bfd_XXi_swap_aouthdr_in (bfd * abfd,
00388                        void * aouthdr_ext1,
00389                        void * aouthdr_int1)
00390 {
00391   PEAOUTHDR * src = (PEAOUTHDR *) aouthdr_ext1;
00392   AOUTHDR * aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
00393   struct internal_aouthdr *aouthdr_int
00394     = (struct internal_aouthdr *) aouthdr_int1;
00395   struct internal_extra_pe_aouthdr *a = &aouthdr_int->pe;
00396 
00397   aouthdr_int->magic = H_GET_16 (abfd, aouthdr_ext->magic);
00398   aouthdr_int->vstamp = H_GET_16 (abfd, aouthdr_ext->vstamp);
00399   aouthdr_int->tsize = GET_AOUTHDR_TSIZE (abfd, aouthdr_ext->tsize);
00400   aouthdr_int->dsize = GET_AOUTHDR_DSIZE (abfd, aouthdr_ext->dsize);
00401   aouthdr_int->bsize = GET_AOUTHDR_BSIZE (abfd, aouthdr_ext->bsize);
00402   aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
00403   aouthdr_int->text_start =
00404     GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
00405 #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
00406   /* PE32+ does not have data_start member!  */
00407   aouthdr_int->data_start =
00408     GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
00409   a->BaseOfData = aouthdr_int->data_start;
00410 #endif
00411 
00412   a->Magic = aouthdr_int->magic;
00413   a->MajorLinkerVersion = H_GET_8 (abfd, aouthdr_ext->vstamp);
00414   a->MinorLinkerVersion = H_GET_8 (abfd, aouthdr_ext->vstamp + 1);
00415   a->SizeOfCode = aouthdr_int->tsize ;
00416   a->SizeOfInitializedData = aouthdr_int->dsize ;
00417   a->SizeOfUninitializedData = aouthdr_int->bsize ;
00418   a->AddressOfEntryPoint = aouthdr_int->entry;
00419   a->BaseOfCode = aouthdr_int->text_start;
00420   a->ImageBase = GET_OPTHDR_IMAGE_BASE (abfd, src->ImageBase);
00421   a->SectionAlignment = H_GET_32 (abfd, src->SectionAlignment);
00422   a->FileAlignment = H_GET_32 (abfd, src->FileAlignment);
00423   a->MajorOperatingSystemVersion =
00424     H_GET_16 (abfd, src->MajorOperatingSystemVersion);
00425   a->MinorOperatingSystemVersion =
00426     H_GET_16 (abfd, src->MinorOperatingSystemVersion);
00427   a->MajorImageVersion = H_GET_16 (abfd, src->MajorImageVersion);
00428   a->MinorImageVersion = H_GET_16 (abfd, src->MinorImageVersion);
00429   a->MajorSubsystemVersion = H_GET_16 (abfd, src->MajorSubsystemVersion);
00430   a->MinorSubsystemVersion = H_GET_16 (abfd, src->MinorSubsystemVersion);
00431   a->Reserved1 = H_GET_32 (abfd, src->Reserved1);
00432   a->SizeOfImage = H_GET_32 (abfd, src->SizeOfImage);
00433   a->SizeOfHeaders = H_GET_32 (abfd, src->SizeOfHeaders);
00434   a->CheckSum = H_GET_32 (abfd, src->CheckSum);
00435   a->Subsystem = H_GET_16 (abfd, src->Subsystem);
00436   a->DllCharacteristics = H_GET_16 (abfd, src->DllCharacteristics);
00437   a->SizeOfStackReserve =
00438     GET_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, src->SizeOfStackReserve);
00439   a->SizeOfStackCommit =
00440     GET_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, src->SizeOfStackCommit);
00441   a->SizeOfHeapReserve =
00442     GET_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, src->SizeOfHeapReserve);
00443   a->SizeOfHeapCommit =
00444     GET_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, src->SizeOfHeapCommit);
00445   a->LoaderFlags = H_GET_32 (abfd, src->LoaderFlags);
00446   a->NumberOfRvaAndSizes = H_GET_32 (abfd, src->NumberOfRvaAndSizes);
00447 
00448   {
00449     int idx;
00450 
00451     for (idx = 0; idx < 16; idx++)
00452       {
00453         /* If data directory is empty, rva also should be 0.  */
00454        int size =
00455          H_GET_32 (abfd, src->DataDirectory[idx][1]);
00456 
00457        a->DataDirectory[idx].Size = size;
00458 
00459        if (size)
00460          a->DataDirectory[idx].VirtualAddress =
00461            H_GET_32 (abfd, src->DataDirectory[idx][0]);
00462        else
00463          a->DataDirectory[idx].VirtualAddress = 0;
00464       }
00465   }
00466 
00467   if (aouthdr_int->entry)
00468     {
00469       aouthdr_int->entry += a->ImageBase;
00470 #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
00471       aouthdr_int->entry &= 0xffffffff;
00472 #endif
00473     }
00474 
00475   if (aouthdr_int->tsize)
00476     {
00477       aouthdr_int->text_start += a->ImageBase;
00478 #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
00479       aouthdr_int->text_start &= 0xffffffff;
00480 #endif
00481     }
00482 
00483 #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
00484   /* PE32+ does not have data_start member!  */
00485   if (aouthdr_int->dsize)
00486     {
00487       aouthdr_int->data_start += a->ImageBase;
00488       aouthdr_int->data_start &= 0xffffffff;
00489     }
00490 #endif
00491 
00492 #ifdef POWERPC_LE_PE
00493   /* These three fields are normally set up by ppc_relocate_section.
00494      In the case of reading a file in, we can pick them up from the
00495      DataDirectory.  */
00496   first_thunk_address = a->DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress;
00497   thunk_size = a->DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size;
00498   import_table_size = a->DataDirectory[PE_IMPORT_TABLE].Size;
00499 #endif
00500 }
00501 
00502 /* A support function for below.  */
00503 
00504 static void
00505 add_data_entry (bfd * abfd,
00506               struct internal_extra_pe_aouthdr *aout,
00507               int idx,
00508               char *name,
00509               bfd_vma base)
00510 {
00511   asection *sec = bfd_get_section_by_name (abfd, name);
00512 
00513   /* Add import directory information if it exists.  */
00514   if ((sec != NULL)
00515       && (coff_section_data (abfd, sec) != NULL)
00516       && (pei_section_data (abfd, sec) != NULL))
00517     {
00518       /* If data directory is empty, rva also should be 0.  */
00519       int size = pei_section_data (abfd, sec)->virt_size;
00520       aout->DataDirectory[idx].Size = size;
00521 
00522       if (size)
00523        {
00524          aout->DataDirectory[idx].VirtualAddress =
00525            (sec->vma - base) & 0xffffffff;
00526          sec->flags |= SEC_DATA;
00527        }
00528     }
00529 }
00530 
00531 unsigned int
00532 _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
00533 {
00534   struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *) in;
00535   pe_data_type *pe = pe_data (abfd);
00536   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
00537   PEAOUTHDR *aouthdr_out = (PEAOUTHDR *) out;
00538   bfd_vma sa, fa, ib;
00539   IMAGE_DATA_DIRECTORY idata2, idata5, tls;
00540   
00541   if (pe->force_minimum_alignment)
00542     {
00543       if (!extra->FileAlignment)
00544        extra->FileAlignment = PE_DEF_FILE_ALIGNMENT;
00545       if (!extra->SectionAlignment)
00546        extra->SectionAlignment = PE_DEF_SECTION_ALIGNMENT;
00547     }
00548 
00549   if (extra->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN)
00550     extra->Subsystem = pe->target_subsystem;
00551 
00552   sa = extra->SectionAlignment;
00553   fa = extra->FileAlignment;
00554   ib = extra->ImageBase;
00555 
00556   idata2 = pe->pe_opthdr.DataDirectory[PE_IMPORT_TABLE];
00557   idata5 = pe->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE];
00558   tls = pe->pe_opthdr.DataDirectory[PE_TLS_TABLE];
00559   
00560   if (aouthdr_in->tsize)
00561     {
00562       aouthdr_in->text_start -= ib;
00563 #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
00564       aouthdr_in->text_start &= 0xffffffff;
00565 #endif
00566     }
00567 
00568   if (aouthdr_in->dsize)
00569     {
00570       aouthdr_in->data_start -= ib;
00571 #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
00572       aouthdr_in->data_start &= 0xffffffff;
00573 #endif
00574     }
00575 
00576   if (aouthdr_in->entry)
00577     {
00578       aouthdr_in->entry -= ib;
00579 #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
00580       aouthdr_in->entry &= 0xffffffff;
00581 #endif
00582     }
00583 
00584 #define FA(x) (((x) + fa -1 ) & (- fa))
00585 #define SA(x) (((x) + sa -1 ) & (- sa))
00586 
00587   /* We like to have the sizes aligned.  */
00588   aouthdr_in->bsize = FA (aouthdr_in->bsize);
00589 
00590   extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
00591 
00592   /* First null out all data directory entries.  */
00593   memset (extra->DataDirectory, 0, sizeof (extra->DataDirectory));
00594 
00595   add_data_entry (abfd, extra, 0, ".edata", ib);
00596   add_data_entry (abfd, extra, 2, ".rsrc", ib);
00597   add_data_entry (abfd, extra, 3, ".pdata", ib);
00598 
00599   /* In theory we do not need to call add_data_entry for .idata$2 or
00600      .idata$5.  It will be done in bfd_coff_final_link where all the
00601      required information is available.  If however, we are not going
00602      to perform a final link, eg because we have been invoked by objcopy
00603      or strip, then we need to make sure that these Data Directory
00604      entries are initialised properly.
00605 
00606      So - we copy the input values into the output values, and then, if
00607      a final link is going to be performed, it can overwrite them.  */
00608   extra->DataDirectory[PE_IMPORT_TABLE]  = idata2;
00609   extra->DataDirectory[PE_IMPORT_ADDRESS_TABLE] = idata5;
00610   extra->DataDirectory[PE_TLS_TABLE] = tls;
00611 
00612   if (extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress == 0)
00613     /* Until other .idata fixes are made (pending patch), the entry for
00614        .idata is needed for backwards compatibility.  FIXME.  */
00615     add_data_entry (abfd, extra, 1, ".idata", ib);
00616     
00617   /* For some reason, the virtual size (which is what's set by
00618      add_data_entry) for .reloc is not the same as the size recorded
00619      in this slot by MSVC; it doesn't seem to cause problems (so far),
00620      but since it's the best we've got, use it.  It does do the right
00621      thing for .pdata.  */
00622   if (pe->has_reloc_section)
00623     add_data_entry (abfd, extra, 5, ".reloc", ib);
00624 
00625   {
00626     asection *sec;
00627     bfd_vma hsize = 0;
00628     bfd_vma dsize = 0;
00629     bfd_vma isize = 0;
00630     bfd_vma tsize = 0;
00631 
00632     for (sec = abfd->sections; sec; sec = sec->next)
00633       {
00634        int rounded = FA (sec->size);
00635 
00636        /* The first non-zero section filepos is the header size.
00637           Sections without contents will have a filepos of 0.  */
00638        if (hsize == 0)
00639          hsize = sec->filepos;
00640        if (sec->flags & SEC_DATA)
00641          dsize += rounded;
00642        if (sec->flags & SEC_CODE)
00643          tsize += rounded;
00644        /* The image size is the total VIRTUAL size (which is what is
00645           in the virt_size field).  Files have been seen (from MSVC
00646           5.0 link.exe) where the file size of the .data segment is
00647           quite small compared to the virtual size.  Without this
00648           fix, strip munges the file.
00649 
00650           FIXME: We need to handle holes between sections, which may
00651           happpen when we covert from another format.  We just use
00652           the virtual address and virtual size of the last section
00653           for the image size.  */
00654        if (coff_section_data (abfd, sec) != NULL
00655            && pei_section_data (abfd, sec) != NULL)
00656          isize = (sec->vma - extra->ImageBase
00657                  + SA (FA (pei_section_data (abfd, sec)->virt_size)));
00658       }
00659 
00660     aouthdr_in->dsize = dsize;
00661     aouthdr_in->tsize = tsize;
00662     extra->SizeOfHeaders = hsize;
00663     extra->SizeOfImage = isize;
00664   }
00665 
00666   H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->standard.magic);
00667 
00668 #define LINKER_VERSION 256 /* That is, 2.56 */
00669 
00670   /* This piece of magic sets the "linker version" field to
00671      LINKER_VERSION.  */
00672   H_PUT_16 (abfd, (LINKER_VERSION / 100 + (LINKER_VERSION % 100) * 256),
00673            aouthdr_out->standard.vstamp);
00674 
00675   PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->standard.tsize);
00676   PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->standard.dsize);
00677   PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, aouthdr_out->standard.bsize);
00678   PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, aouthdr_out->standard.entry);
00679   PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
00680                        aouthdr_out->standard.text_start);
00681 
00682 #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
00683   /* PE32+ does not have data_start member!  */
00684   PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
00685                        aouthdr_out->standard.data_start);
00686 #endif
00687 
00688   PUT_OPTHDR_IMAGE_BASE (abfd, extra->ImageBase, aouthdr_out->ImageBase);
00689   H_PUT_32 (abfd, extra->SectionAlignment, aouthdr_out->SectionAlignment);
00690   H_PUT_32 (abfd, extra->FileAlignment, aouthdr_out->FileAlignment);
00691   H_PUT_16 (abfd, extra->MajorOperatingSystemVersion,
00692            aouthdr_out->MajorOperatingSystemVersion);
00693   H_PUT_16 (abfd, extra->MinorOperatingSystemVersion,
00694            aouthdr_out->MinorOperatingSystemVersion);
00695   H_PUT_16 (abfd, extra->MajorImageVersion, aouthdr_out->MajorImageVersion);
00696   H_PUT_16 (abfd, extra->MinorImageVersion, aouthdr_out->MinorImageVersion);
00697   H_PUT_16 (abfd, extra->MajorSubsystemVersion,
00698            aouthdr_out->MajorSubsystemVersion);
00699   H_PUT_16 (abfd, extra->MinorSubsystemVersion,
00700            aouthdr_out->MinorSubsystemVersion);
00701   H_PUT_32 (abfd, extra->Reserved1, aouthdr_out->Reserved1);
00702   H_PUT_32 (abfd, extra->SizeOfImage, aouthdr_out->SizeOfImage);
00703   H_PUT_32 (abfd, extra->SizeOfHeaders, aouthdr_out->SizeOfHeaders);
00704   H_PUT_32 (abfd, extra->CheckSum, aouthdr_out->CheckSum);
00705   H_PUT_16 (abfd, extra->Subsystem, aouthdr_out->Subsystem);
00706   H_PUT_16 (abfd, extra->DllCharacteristics, aouthdr_out->DllCharacteristics);
00707   PUT_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, extra->SizeOfStackReserve,
00708                                 aouthdr_out->SizeOfStackReserve);
00709   PUT_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, extra->SizeOfStackCommit,
00710                                aouthdr_out->SizeOfStackCommit);
00711   PUT_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, extra->SizeOfHeapReserve,
00712                                aouthdr_out->SizeOfHeapReserve);
00713   PUT_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, extra->SizeOfHeapCommit,
00714                               aouthdr_out->SizeOfHeapCommit);
00715   H_PUT_32 (abfd, extra->LoaderFlags, aouthdr_out->LoaderFlags);
00716   H_PUT_32 (abfd, extra->NumberOfRvaAndSizes,
00717            aouthdr_out->NumberOfRvaAndSizes);
00718   {
00719     int idx;
00720 
00721     for (idx = 0; idx < 16; idx++)
00722       {
00723        H_PUT_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
00724                 aouthdr_out->DataDirectory[idx][0]);
00725        H_PUT_32 (abfd, extra->DataDirectory[idx].Size,
00726                 aouthdr_out->DataDirectory[idx][1]);
00727       }
00728   }
00729 
00730   return AOUTSZ;
00731 }
00732 
00733 unsigned int
00734 _bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
00735 {
00736   int idx;
00737   struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
00738   struct external_PEI_filehdr *filehdr_out = (struct external_PEI_filehdr *) out;
00739 
00740   if (pe_data (abfd)->has_reloc_section)
00741     filehdr_in->f_flags &= ~F_RELFLG;
00742 
00743   if (pe_data (abfd)->dll)
00744     filehdr_in->f_flags |= F_DLL;
00745 
00746   filehdr_in->pe.e_magic    = DOSMAGIC;
00747   filehdr_in->pe.e_cblp     = 0x90;
00748   filehdr_in->pe.e_cp       = 0x3;
00749   filehdr_in->pe.e_crlc     = 0x0;
00750   filehdr_in->pe.e_cparhdr  = 0x4;
00751   filehdr_in->pe.e_minalloc = 0x0;
00752   filehdr_in->pe.e_maxalloc = 0xffff;
00753   filehdr_in->pe.e_ss       = 0x0;
00754   filehdr_in->pe.e_sp       = 0xb8;
00755   filehdr_in->pe.e_csum     = 0x0;
00756   filehdr_in->pe.e_ip       = 0x0;
00757   filehdr_in->pe.e_cs       = 0x0;
00758   filehdr_in->pe.e_lfarlc   = 0x40;
00759   filehdr_in->pe.e_ovno     = 0x0;
00760 
00761   for (idx = 0; idx < 4; idx++)
00762     filehdr_in->pe.e_res[idx] = 0x0;
00763 
00764   filehdr_in->pe.e_oemid   = 0x0;
00765   filehdr_in->pe.e_oeminfo = 0x0;
00766 
00767   for (idx = 0; idx < 10; idx++)
00768     filehdr_in->pe.e_res2[idx] = 0x0;
00769 
00770   filehdr_in->pe.e_lfanew = 0x80;
00771 
00772   /* This next collection of data are mostly just characters.  It
00773      appears to be constant within the headers put on NT exes.  */
00774   filehdr_in->pe.dos_message[0]  = 0x0eba1f0e;
00775   filehdr_in->pe.dos_message[1]  = 0xcd09b400;
00776   filehdr_in->pe.dos_message[2]  = 0x4c01b821;
00777   filehdr_in->pe.dos_message[3]  = 0x685421cd;
00778   filehdr_in->pe.dos_message[4]  = 0x70207369;
00779   filehdr_in->pe.dos_message[5]  = 0x72676f72;
00780   filehdr_in->pe.dos_message[6]  = 0x63206d61;
00781   filehdr_in->pe.dos_message[7]  = 0x6f6e6e61;
00782   filehdr_in->pe.dos_message[8]  = 0x65622074;
00783   filehdr_in->pe.dos_message[9]  = 0x6e757220;
00784   filehdr_in->pe.dos_message[10] = 0x206e6920;
00785   filehdr_in->pe.dos_message[11] = 0x20534f44;
00786   filehdr_in->pe.dos_message[12] = 0x65646f6d;
00787   filehdr_in->pe.dos_message[13] = 0x0a0d0d2e;
00788   filehdr_in->pe.dos_message[14] = 0x24;
00789   filehdr_in->pe.dos_message[15] = 0x0;
00790   filehdr_in->pe.nt_signature = NT_SIGNATURE;
00791 
00792   H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
00793   H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
00794 
00795   H_PUT_32 (abfd, time (0), filehdr_out->f_timdat);
00796   PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
00797                     filehdr_out->f_symptr);
00798   H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
00799   H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
00800   H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
00801 
00802   /* Put in extra dos header stuff.  This data remains essentially
00803      constant, it just has to be tacked on to the beginning of all exes
00804      for NT.  */
00805   H_PUT_16 (abfd, filehdr_in->pe.e_magic, filehdr_out->e_magic);
00806   H_PUT_16 (abfd, filehdr_in->pe.e_cblp, filehdr_out->e_cblp);
00807   H_PUT_16 (abfd, filehdr_in->pe.e_cp, filehdr_out->e_cp);
00808   H_PUT_16 (abfd, filehdr_in->pe.e_crlc, filehdr_out->e_crlc);
00809   H_PUT_16 (abfd, filehdr_in->pe.e_cparhdr, filehdr_out->e_cparhdr);
00810   H_PUT_16 (abfd, filehdr_in->pe.e_minalloc, filehdr_out->e_minalloc);
00811   H_PUT_16 (abfd, filehdr_in->pe.e_maxalloc, filehdr_out->e_maxalloc);
00812   H_PUT_16 (abfd, filehdr_in->pe.e_ss, filehdr_out->e_ss);
00813   H_PUT_16 (abfd, filehdr_in->pe.e_sp, filehdr_out->e_sp);
00814   H_PUT_16 (abfd, filehdr_in->pe.e_csum, filehdr_out->e_csum);
00815   H_PUT_16 (abfd, filehdr_in->pe.e_ip, filehdr_out->e_ip);
00816   H_PUT_16 (abfd, filehdr_in->pe.e_cs, filehdr_out->e_cs);
00817   H_PUT_16 (abfd, filehdr_in->pe.e_lfarlc, filehdr_out->e_lfarlc);
00818   H_PUT_16 (abfd, filehdr_in->pe.e_ovno, filehdr_out->e_ovno);
00819 
00820   for (idx = 0; idx < 4; idx++)
00821     H_PUT_16 (abfd, filehdr_in->pe.e_res[idx], filehdr_out->e_res[idx]);
00822 
00823   H_PUT_16 (abfd, filehdr_in->pe.e_oemid, filehdr_out->e_oemid);
00824   H_PUT_16 (abfd, filehdr_in->pe.e_oeminfo, filehdr_out->e_oeminfo);
00825 
00826   for (idx = 0; idx < 10; idx++)
00827     H_PUT_16 (abfd, filehdr_in->pe.e_res2[idx], filehdr_out->e_res2[idx]);
00828 
00829   H_PUT_32 (abfd, filehdr_in->pe.e_lfanew, filehdr_out->e_lfanew);
00830 
00831   for (idx = 0; idx < 16; idx++)
00832     H_PUT_32 (abfd, filehdr_in->pe.dos_message[idx],
00833              filehdr_out->dos_message[idx]);
00834 
00835   /* Also put in the NT signature.  */
00836   H_PUT_32 (abfd, filehdr_in->pe.nt_signature, filehdr_out->nt_signature);
00837 
00838   return FILHSZ;
00839 }
00840 
00841 unsigned int
00842 _bfd_XX_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
00843 {
00844   struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
00845   FILHDR *filehdr_out = (FILHDR *) out;
00846 
00847   H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
00848   H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
00849   H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->f_timdat);
00850   PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, filehdr_out->f_symptr);
00851   H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
00852   H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
00853   H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
00854 
00855   return FILHSZ;
00856 }
00857 
00858 unsigned int
00859 _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
00860 {
00861   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
00862   SCNHDR *scnhdr_ext = (SCNHDR *) out;
00863   unsigned int ret = SCNHSZ;
00864   bfd_vma ps;
00865   bfd_vma ss;
00866 
00867   memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
00868 
00869   PUT_SCNHDR_VADDR (abfd,
00870                   ((scnhdr_int->s_vaddr
00871                     - pe_data (abfd)->pe_opthdr.ImageBase)
00872                    & 0xffffffff),
00873                   scnhdr_ext->s_vaddr);
00874 
00875   /* NT wants the size data to be rounded up to the next
00876      NT_FILE_ALIGNMENT, but zero if it has no content (as in .bss,
00877      sometimes).  */
00878   if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
00879     {
00880       if (bfd_pe_executable_p (abfd))
00881        {
00882          ps = scnhdr_int->s_size;
00883          ss = 0;
00884        }
00885       else
00886        {
00887          ps = 0;
00888          ss = scnhdr_int->s_size;
00889        }
00890     }
00891   else
00892     {
00893       if (bfd_pe_executable_p (abfd))
00894        ps = scnhdr_int->s_paddr;
00895       else
00896        ps = 0;
00897 
00898       ss = scnhdr_int->s_size;
00899     }
00900 
00901   PUT_SCNHDR_SIZE (abfd, ss,
00902                  scnhdr_ext->s_size);
00903 
00904   /* s_paddr in PE is really the virtual size.  */
00905   PUT_SCNHDR_PADDR (abfd, ps, scnhdr_ext->s_paddr);
00906 
00907   PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
00908                    scnhdr_ext->s_scnptr);
00909   PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
00910                    scnhdr_ext->s_relptr);
00911   PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
00912                     scnhdr_ext->s_lnnoptr);
00913 
00914   {
00915     /* Extra flags must be set when dealing with PE.  All sections should also
00916        have the IMAGE_SCN_MEM_READ (0x40000000) flag set.  In addition, the
00917        .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
00918        sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
00919        (this is especially important when dealing with the .idata section since
00920        the addresses for routines from .dlls must be overwritten).  If .reloc
00921        section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
00922        (0x02000000).  Also, the resource data should also be read and
00923        writable.  */
00924 
00925     /* FIXME: Alignment is also encoded in this field, at least on PPC and 
00926        ARM-WINCE.  Although - how do we get the original alignment field
00927        back ?  */
00928 
00929     typedef struct
00930     {
00931       const char *   section_name;
00932       unsigned long  must_have;
00933     }
00934     pe_required_section_flags;
00935     
00936     pe_required_section_flags known_sections [] =
00937       {
00938        { ".arch",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_ALIGN_8BYTES },
00939        { ".bss",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
00940        { ".data",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
00941        { ".edata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
00942        { ".idata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
00943        { ".pdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
00944        { ".rdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
00945        { ".reloc", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE },
00946        { ".rsrc",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
00947        { ".text" , IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE },
00948        { ".tls",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
00949        { ".xdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
00950        { NULL, 0}
00951       };
00952 
00953     pe_required_section_flags * p;
00954 
00955     /* We have defaulted to adding the IMAGE_SCN_MEM_WRITE flag, but now
00956        we know exactly what this specific section wants so we remove it
00957        and then allow the must_have field to add it back in if necessary.
00958        However, we don't remove IMAGE_SCN_MEM_WRITE flag from .text if the
00959        default WP_TEXT file flag has been cleared.  WP_TEXT may be cleared
00960        by ld --enable-auto-import (if auto-import is actually needed),
00961        by ld --omagic, or by obcopy --writable-text.  */
00962 
00963     for (p = known_sections; p->section_name; p++)
00964       if (strcmp (scnhdr_int->s_name, p->section_name) == 0)
00965        {
00966          if (strcmp (scnhdr_int->s_name, ".text")
00967              || (bfd_get_file_flags (abfd) & WP_TEXT))
00968            scnhdr_int->s_flags &= ~IMAGE_SCN_MEM_WRITE;
00969          scnhdr_int->s_flags |= p->must_have;
00970          break;
00971        }
00972 
00973     H_PUT_32 (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
00974   }
00975 
00976   if (coff_data (abfd)->link_info
00977       && ! coff_data (abfd)->link_info->relocatable
00978       && ! coff_data (abfd)->link_info->shared
00979       && strcmp (scnhdr_int->s_name, ".text") == 0)
00980     {
00981       /* By inference from looking at MS output, the 32 bit field
00982         which is the combination of the number_of_relocs and
00983         number_of_linenos is used for the line number count in
00984         executables.  A 16-bit field won't do for cc1.  The MS
00985         document says that the number of relocs is zero for
00986         executables, but the 17-th bit has been observed to be there.
00987         Overflow is not an issue: a 4G-line program will overflow a
00988         bunch of other fields long before this!  */
00989       H_PUT_16 (abfd, (scnhdr_int->s_nlnno & 0xffff), scnhdr_ext->s_nlnno);
00990       H_PUT_16 (abfd, (scnhdr_int->s_nlnno >> 16), scnhdr_ext->s_nreloc);
00991     }
00992   else
00993     {
00994       if (scnhdr_int->s_nlnno <= 0xffff)
00995        H_PUT_16 (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
00996       else
00997        {
00998          (*_bfd_error_handler) (_("%s: line number overflow: 0x%lx > 0xffff"),
00999                              bfd_get_filename (abfd),
01000                              scnhdr_int->s_nlnno);
01001          bfd_set_error (bfd_error_file_truncated);
01002          H_PUT_16 (abfd, 0xffff, scnhdr_ext->s_nlnno);
01003          ret = 0;
01004        }
01005 
01006       /* Although we could encode 0xffff relocs here, we do not, to be
01007          consistent with other parts of bfd. Also it lets us warn, as
01008          we should never see 0xffff here w/o having the overflow flag
01009          set.  */
01010       if (scnhdr_int->s_nreloc < 0xffff)
01011        H_PUT_16 (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
01012       else
01013        {
01014          /* PE can deal with large #s of relocs, but not here.  */
01015          H_PUT_16 (abfd, 0xffff, scnhdr_ext->s_nreloc);
01016          scnhdr_int->s_flags |= IMAGE_SCN_LNK_NRELOC_OVFL;
01017          H_PUT_32 (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
01018        }
01019     }
01020   return ret;
01021 }
01022 
01023 static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
01024 {
01025   N_("Export Directory [.edata (or where ever we found it)]"),
01026   N_("Import Directory [parts of .idata]"),
01027   N_("Resource Directory [.rsrc]"),
01028   N_("Exception Directory [.pdata]"),
01029   N_("Security Directory"),
01030   N_("Base Relocation Directory [.reloc]"),
01031   N_("Debug Directory"),
01032   N_("Description Directory"),
01033   N_("Special Directory"),
01034   N_("Thread Storage Directory [.tls]"),
01035   N_("Load Configuration Directory"),
01036   N_("Bound Import Directory"),
01037   N_("Import Address Table Directory"),
01038   N_("Delay Import Directory"),
01039   N_("CLR Runtime Header"),
01040   N_("Reserved")
01041 };
01042 
01043 #ifdef POWERPC_LE_PE
01044 /* The code for the PPC really falls in the "architecture dependent"
01045    category.  However, it's not clear that anyone will ever care, so
01046    we're ignoring the issue for now; if/when PPC matters, some of this
01047    may need to go into peicode.h, or arguments passed to enable the
01048    PPC- specific code.  */
01049 #endif
01050 
01051 static bfd_boolean
01052 pe_print_idata (bfd * abfd, void * vfile)
01053 {
01054   FILE *file = (FILE *) vfile;
01055   bfd_byte *data;
01056   asection *section;
01057   bfd_signed_vma adj;
01058 
01059 #ifdef POWERPC_LE_PE
01060   asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
01061 #endif
01062 
01063   bfd_size_type datasize = 0;
01064   bfd_size_type dataoff;
01065   bfd_size_type i;
01066   int onaline = 20;
01067 
01068   pe_data_type *pe = pe_data (abfd);
01069   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
01070 
01071   bfd_vma addr;
01072 
01073   addr = extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress;
01074 
01075   if (addr == 0 && extra->DataDirectory[PE_IMPORT_TABLE].Size == 0)
01076     {
01077       /* Maybe the extra header isn't there.  Look for the section.  */
01078       section = bfd_get_section_by_name (abfd, ".idata");
01079       if (section == NULL)
01080        return TRUE;
01081 
01082       addr = section->vma;
01083       datasize = section->size;
01084       if (datasize == 0)
01085        return TRUE;
01086     }
01087   else
01088     {
01089       addr += extra->ImageBase;
01090       for (section = abfd->sections; section != NULL; section = section->next)
01091        {
01092          datasize = section->size;
01093          if (addr >= section->vma && addr < section->vma + datasize)
01094            break;
01095        }
01096 
01097       if (section == NULL)
01098        {
01099          fprintf (file,
01100                  _("\nThere is an import table, but the section containing it could not be found\n"));
01101          return TRUE;
01102        }
01103     }
01104 
01105   fprintf (file, _("\nThere is an import table in %s at 0x%lx\n"),
01106           section->name, (unsigned long) addr);
01107 
01108   dataoff = addr - section->vma;
01109   datasize -= dataoff;
01110 
01111 #ifdef POWERPC_LE_PE
01112   if (rel_section != 0 && rel_section->size != 0)
01113     {
01114       /* The toc address can be found by taking the starting address,
01115         which on the PPC locates a function descriptor. The
01116         descriptor consists of the function code starting address
01117         followed by the address of the toc. The starting address we
01118         get from the bfd, and the descriptor is supposed to be in the
01119         .reldata section.  */
01120 
01121       bfd_vma loadable_toc_address;
01122       bfd_vma toc_address;
01123       bfd_vma start_address;
01124       bfd_byte *data;
01125       bfd_vma offset;
01126 
01127       if (!bfd_malloc_and_get_section (abfd, rel_section, &data))
01128        {
01129          if (data != NULL)
01130            free (data);
01131          return FALSE;
01132        }
01133 
01134       offset = abfd->start_address - rel_section->vma;
01135 
01136       if (offset >= rel_section->size || offset + 8 > rel_section->size)
01137         {
01138           if (data != NULL)
01139             free (data);
01140           return FALSE;
01141         }
01142 
01143       start_address = bfd_get_32 (abfd, data + offset);
01144       loadable_toc_address = bfd_get_32 (abfd, data + offset + 4);
01145       toc_address = loadable_toc_address - 32768;
01146 
01147       fprintf (file,
01148               _("\nFunction descriptor located at the start address: %04lx\n"),
01149               (unsigned long int) (abfd->start_address));
01150       fprintf (file,
01151               _("\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"),
01152               start_address, loadable_toc_address, toc_address);
01153       if (data != NULL)
01154        free (data);
01155     }
01156   else
01157     {
01158       fprintf (file,
01159               _("\nNo reldata section! Function descriptor not decoded.\n"));
01160     }
01161 #endif
01162 
01163   fprintf (file,
01164           _("\nThe Import Tables (interpreted %s section contents)\n"),
01165           section->name);
01166   fprintf (file,
01167           _("\
01168  vma:            Hint    Time      Forward  DLL       First\n\
01169                  Table   Stamp     Chain    Name      Thunk\n"));
01170 
01171   /* Read the whole section.  Some of the fields might be before dataoff.  */
01172   if (!bfd_malloc_and_get_section (abfd, section, &data))
01173     {
01174       if (data != NULL)
01175        free (data);
01176       return FALSE;
01177     }
01178 
01179   adj = section->vma - extra->ImageBase;
01180 
01181   /* Print all image import descriptors.  */
01182   for (i = 0; i < datasize; i += onaline)
01183     {
01184       bfd_vma hint_addr;
01185       bfd_vma time_stamp;
01186       bfd_vma forward_chain;
01187       bfd_vma dll_name;
01188       bfd_vma first_thunk;
01189       int idx = 0;
01190       bfd_size_type j;
01191       char *dll;
01192 
01193       /* Print (i + extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress).  */
01194       fprintf (file, " %08lx\t", (unsigned long) (i + adj + dataoff));
01195       hint_addr = bfd_get_32 (abfd, data + i + dataoff);
01196       time_stamp = bfd_get_32 (abfd, data + i + 4 + dataoff);
01197       forward_chain = bfd_get_32 (abfd, data + i + 8 + dataoff);
01198       dll_name = bfd_get_32 (abfd, data + i + 12 + dataoff);
01199       first_thunk = bfd_get_32 (abfd, data + i + 16 + dataoff);
01200 
01201       fprintf (file, "%08lx %08lx %08lx %08lx %08lx\n",
01202               (unsigned long) hint_addr,
01203               (unsigned long) time_stamp,
01204               (unsigned long) forward_chain,
01205               (unsigned long) dll_name,
01206               (unsigned long) first_thunk);
01207 
01208       if (hint_addr == 0 && first_thunk == 0)
01209        break;
01210 
01211       if (dll_name - adj >= section->size)
01212         break;
01213 
01214       dll = (char *) data + dll_name - adj;
01215       fprintf (file, _("\n\tDLL Name: %s\n"), dll);
01216 
01217       if (hint_addr != 0)
01218        {
01219          bfd_byte *ft_data;
01220          asection *ft_section;
01221          bfd_vma ft_addr;
01222          bfd_size_type ft_datasize;
01223          int ft_idx;
01224          int ft_allocated = 0;
01225 
01226          fprintf (file, _("\tvma:  Hint/Ord Member-Name Bound-To\n"));
01227 
01228          idx = hint_addr - adj;
01229          
01230          ft_addr = first_thunk + extra->ImageBase;
01231          ft_data = data;
01232          ft_idx = first_thunk - adj;
01233          ft_allocated = 0; 
01234 
01235          if (first_thunk != hint_addr)
01236            {
01237              /* Find the section which contains the first thunk.  */
01238              for (ft_section = abfd->sections;
01239                  ft_section != NULL;
01240                  ft_section = ft_section->next)
01241               {
01242                 ft_datasize = ft_section->size;
01243                 if (ft_addr >= ft_section->vma
01244                     && ft_addr < ft_section->vma + ft_datasize)
01245                   break;
01246               }
01247 
01248              if (ft_section == NULL)
01249               {
01250                 fprintf (file,
01251                      _("\nThere is a first thunk, but the section containing it could not be found\n"));
01252                 continue;
01253               }
01254 
01255              /* Now check to see if this section is the same as our current
01256                section.  If it is not then we will have to load its data in.  */
01257              if (ft_section == section)
01258               {
01259                 ft_data = data;
01260                 ft_idx = first_thunk - adj;
01261               }
01262              else
01263               {
01264                 ft_idx = first_thunk - (ft_section->vma - extra->ImageBase);
01265                 ft_data = bfd_malloc (datasize);
01266                 if (ft_data == NULL)
01267                   continue;
01268 
01269                 /* Read datasize bfd_bytes starting at offset ft_idx.  */
01270                 if (! bfd_get_section_contents
01271                     (abfd, ft_section, ft_data, (bfd_vma) ft_idx, datasize))
01272                   {
01273                     free (ft_data);
01274                     continue;
01275                   }
01276 
01277                 ft_idx = 0;
01278                 ft_allocated = 1;
01279               }
01280            }
01281 
01282          /* Print HintName vector entries.  */
01283 #ifdef COFF_WITH_pex64
01284          for (j = 0; j < datasize; j += 8)
01285            {
01286              unsigned long member = bfd_get_32 (abfd, data + idx + j);
01287              unsigned long member_high = bfd_get_32 (abfd, data + idx + j + 4);
01288 
01289              if (!member && !member_high)
01290               break;
01291 
01292              if (member_high & 0x80000000)
01293               fprintf (file, "\t%lx%08lx\t %4lx%08lx  <none>",
01294                       member_high,member, member_high & 0x7fffffff, member);
01295              else
01296               {
01297                 int ordinal;
01298                 char *member_name;
01299 
01300                 ordinal = bfd_get_16 (abfd, data + member - adj);
01301                 member_name = (char *) data + member - adj + 2;
01302                 fprintf (file, "\t%04lx\t %4d  %s",member, ordinal, member_name);
01303               }
01304 
01305              /* If the time stamp is not zero, the import address
01306                table holds actual addresses.  */
01307              if (time_stamp != 0
01308                 && first_thunk != 0
01309                 && first_thunk != hint_addr)
01310               fprintf (file, "\t%04lx",
01311                       (long) bfd_get_32 (abfd, ft_data + ft_idx + j));
01312              fprintf (file, "\n");
01313            }
01314 #else
01315          for (j = 0; j < datasize; j += 4)
01316            {
01317              unsigned long member = bfd_get_32 (abfd, data + idx + j);
01318 
01319              /* Print single IMAGE_IMPORT_BY_NAME vector.  */ 
01320              if (member == 0)
01321               break;
01322 
01323              if (member & 0x80000000)
01324               fprintf (file, "\t%04lx\t %4lu  <none>",
01325                       member, member & 0x7fffffff);
01326              else
01327               {
01328                 int ordinal;
01329                 char *member_name;
01330 
01331                 ordinal = bfd_get_16 (abfd, data + member - adj);
01332                 member_name = (char *) data + member - adj + 2;
01333                 fprintf (file, "\t%04lx\t %4d  %s",
01334                         member, ordinal, member_name);
01335               }
01336 
01337              /* If the time stamp is not zero, the import address
01338                table holds actual addresses.  */
01339              if (time_stamp != 0
01340                 && first_thunk != 0
01341                 && first_thunk != hint_addr)
01342               fprintf (file, "\t%04lx",
01343                       (long) bfd_get_32 (abfd, ft_data + ft_idx + j));
01344 
01345              fprintf (file, "\n");
01346            }
01347 #endif
01348          if (ft_allocated)
01349            free (ft_data);
01350        }
01351 
01352       fprintf (file, "\n");
01353     }
01354 
01355   free (data);
01356 
01357   return TRUE;
01358 }
01359 
01360 static bfd_boolean
01361 pe_print_edata (bfd * abfd, void * vfile)
01362 {
01363   FILE *file = (FILE *) vfile;
01364   bfd_byte *data;
01365   asection *section;
01366   bfd_size_type datasize = 0;
01367   bfd_size_type dataoff;
01368   bfd_size_type i;
01369   bfd_signed_vma adj;
01370   struct EDT_type
01371   {
01372     long export_flags;          /* Reserved - should be zero.  */
01373     long time_stamp;
01374     short major_ver;
01375     short minor_ver;
01376     bfd_vma name;               /* RVA - relative to image base.  */
01377     long base;                  /* Ordinal base.  */
01378     unsigned long num_functions;/* Number in the export address table.  */
01379     unsigned long num_names;    /* Number in the name pointer table.  */
01380     bfd_vma eat_addr;              /* RVA to the export address table.  */
01381     bfd_vma npt_addr;              /* RVA to the Export Name Pointer Table.  */
01382     bfd_vma ot_addr;        /* RVA to the Ordinal Table.  */
01383   } edt;
01384 
01385   pe_data_type *pe = pe_data (abfd);
01386   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
01387 
01388   bfd_vma addr;
01389 
01390   addr = extra->DataDirectory[PE_EXPORT_TABLE].VirtualAddress;
01391 
01392   if (addr == 0 && extra->DataDirectory[PE_EXPORT_TABLE].Size == 0)
01393     {
01394       /* Maybe the extra header isn't there.  Look for the section.  */
01395       section = bfd_get_section_by_name (abfd, ".edata");
01396       if (section == NULL)
01397        return TRUE;
01398 
01399       addr = section->vma;
01400       dataoff = 0;
01401       datasize = section->size;
01402       if (datasize == 0)
01403        return TRUE;
01404     }
01405   else
01406     {
01407       addr += extra->ImageBase;
01408 
01409       for (section = abfd->sections; section != NULL; section = section->next)
01410        if (addr >= section->vma && addr < section->vma + section->size)
01411          break;
01412 
01413       if (section == NULL)
01414        {
01415          fprintf (file,
01416                  _("\nThere is an export table, but the section containing it could not be found\n"));
01417          return TRUE;
01418        }
01419 
01420       dataoff = addr - section->vma;
01421       datasize = extra->DataDirectory[PE_EXPORT_TABLE].Size;
01422       if (datasize > section->size - dataoff)
01423        {
01424          fprintf (file,
01425                  _("\nThere is an export table in %s, but it does not fit into that section\n"),
01426                  section->name);
01427          return TRUE;
01428        }
01429     }
01430 
01431   fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"),
01432           section->name, (unsigned long) addr);
01433 
01434   data = bfd_malloc (datasize);
01435   if (data == NULL)
01436     return FALSE;
01437 
01438   if (! bfd_get_section_contents (abfd, section, data,
01439                               (file_ptr) dataoff, datasize))
01440     return FALSE;
01441 
01442   /* Go get Export Directory Table.  */
01443   edt.export_flags   = bfd_get_32 (abfd, data +  0);
01444   edt.time_stamp     = bfd_get_32 (abfd, data +  4);
01445   edt.major_ver      = bfd_get_16 (abfd, data +  8);
01446   edt.minor_ver      = bfd_get_16 (abfd, data + 10);
01447   edt.name           = bfd_get_32 (abfd, data + 12);
01448   edt.base           = bfd_get_32 (abfd, data + 16);
01449   edt.num_functions  = bfd_get_32 (abfd, data + 20);
01450   edt.num_names      = bfd_get_32 (abfd, data + 24);
01451   edt.eat_addr       = bfd_get_32 (abfd, data + 28);
01452   edt.npt_addr       = bfd_get_32 (abfd, data + 32);
01453   edt.ot_addr        = bfd_get_32 (abfd, data + 36);
01454 
01455   adj = section->vma - extra->ImageBase + dataoff;
01456 
01457   /* Dump the EDT first.  */
01458   fprintf (file,
01459           _("\nThe Export Tables (interpreted %s section contents)\n\n"),
01460           section->name);
01461 
01462   fprintf (file,
01463           _("Export Flags \t\t\t%lx\n"), (unsigned long) edt.export_flags);
01464 
01465   fprintf (file,
01466           _("Time/Date stamp \t\t%lx\n"), (unsigned long) edt.time_stamp);
01467 
01468   fprintf (file,
01469           _("Major/Minor \t\t\t%d/%d\n"), edt.major_ver, edt.minor_ver);
01470 
01471   fprintf (file,
01472           _("Name \t\t\t\t"));
01473   fprintf_vma (file, edt.name);
01474   fprintf (file,
01475           " %s\n", data + edt.name - adj);
01476 
01477   fprintf (file,
01478           _("Ordinal Base \t\t\t%ld\n"), edt.base);
01479 
01480   fprintf (file,
01481           _("Number in:\n"));
01482 
01483   fprintf (file,
01484           _("\tExport Address Table \t\t%08lx\n"),
01485           edt.num_functions);
01486 
01487   fprintf (file,
01488           _("\t[Name Pointer/Ordinal] Table\t%08lx\n"), edt.num_names);
01489 
01490   fprintf (file,
01491           _("Table Addresses\n"));
01492 
01493   fprintf (file,
01494           _("\tExport Address Table \t\t"));
01495   fprintf_vma (file, edt.eat_addr);
01496   fprintf (file, "\n");
01497 
01498   fprintf (file,
01499           _("\tName Pointer Table \t\t"));
01500   fprintf_vma (file, edt.npt_addr);
01501   fprintf (file, "\n");
01502 
01503   fprintf (file,
01504           _("\tOrdinal Table \t\t\t"));
01505   fprintf_vma (file, edt.ot_addr);
01506   fprintf (file, "\n");
01507 
01508   /* The next table to find is the Export Address Table. It's basically
01509      a list of pointers that either locate a function in this dll, or
01510      forward the call to another dll. Something like:
01511       typedef union
01512       {
01513         long export_rva;
01514         long forwarder_rva;
01515       } export_address_table_entry;  */
01516 
01517   fprintf (file,
01518          _("\nExport Address Table -- Ordinal Base %ld\n"),
01519          edt.base);
01520 
01521   for (i = 0; i < edt.num_functions; ++i)
01522     {
01523       bfd_vma eat_member = bfd_get_32 (abfd,
01524                                    data + edt.eat_addr + (i * 4) - adj);
01525       if (eat_member == 0)
01526        continue;
01527 
01528       if (eat_member - adj <= datasize)
01529        {
01530          /* This rva is to a name (forwarding function) in our section.  */
01531          /* Should locate a function descriptor.  */
01532          fprintf (file,
01533                  "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
01534                  (long) i,
01535                  (long) (i + edt.base),
01536                  (unsigned long) eat_member,
01537                  _("Forwarder RVA"),
01538                  data + eat_member - adj);
01539        }
01540       else
01541        {
01542          /* Should locate a function descriptor in the reldata section.  */
01543          fprintf (file,
01544                  "\t[%4ld] +base[%4ld] %04lx %s\n",
01545                  (long) i,
01546                  (long) (i + edt.base),
01547                  (unsigned long) eat_member,
01548                  _("Export RVA"));
01549        }
01550     }
01551 
01552   /* The Export Name Pointer Table is paired with the Export Ordinal Table.  */
01553   /* Dump them in parallel for clarity.  */
01554   fprintf (file,
01555           _("\n[Ordinal/Name Pointer] Table\n"));
01556 
01557   for (i = 0; i < edt.num_names; ++i)
01558     {
01559       bfd_vma name_ptr = bfd_get_32 (abfd,
01560                                 data +
01561                                 edt.npt_addr
01562                                 + (i*4) - adj);
01563 
01564       char *name = (char *) data + name_ptr - adj;
01565 
01566       bfd_vma ord = bfd_get_16 (abfd,
01567                                 data +
01568                                 edt.ot_addr
01569                                 + (i*2) - adj);
01570       fprintf (file,
01571              "\t[%4ld] %s\n", (long) ord, name);
01572     }
01573 
01574   free (data);
01575 
01576   return TRUE;
01577 }
01578 
01579 /* This really is architecture dependent.  On IA-64, a .pdata entry
01580    consists of three dwords containing relative virtual addresses that
01581    specify the start and end address of the code range the entry
01582    covers and the address of the corresponding unwind info data.  */
01583 
01584 static bfd_boolean
01585 pe_print_pdata (bfd * abfd, void * vfile)
01586 {
01587 #if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
01588 # define PDATA_ROW_SIZE     (3 * 8)
01589 #else
01590 # define PDATA_ROW_SIZE     (5 * 4)
01591 #endif
01592   FILE *file = (FILE *) vfile;
01593   bfd_byte *data = 0;
01594   asection *section = bfd_get_section_by_name (abfd, ".pdata");
01595   bfd_size_type datasize = 0;
01596   bfd_size_type i;
01597   bfd_size_type start, stop;
01598   int onaline = PDATA_ROW_SIZE;
01599 
01600   if (section == NULL
01601       || coff_section_data (abfd, section) == NULL
01602       || pei_section_data (abfd, section) == NULL)
01603     return TRUE;
01604 
01605   stop = pei_section_data (abfd, section)->virt_size;
01606   if ((stop % onaline) != 0)
01607     fprintf (file,
01608             _("Warning, .pdata section size (%ld) is not a multiple of %d\n"),
01609             (long) stop, onaline);
01610 
01611   fprintf (file,
01612           _("\nThe Function Table (interpreted .pdata section contents)\n"));
01613 #if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
01614   fprintf (file,
01615           _(" vma:\t\t\tBegin Address    End Address      Unwind Info\n"));
01616 #else
01617   fprintf (file, _("\
01618  vma:\t\tBegin    End      EH       EH       PrologEnd  Exception\n\
01619      \t\tAddress  Address  Handler  Data     Address    Mask\n"));
01620 #endif
01621 
01622   datasize = section->size;
01623   if (datasize == 0)
01624     return TRUE;
01625 
01626   if (! bfd_malloc_and_get_section (abfd, section, &data))
01627     {
01628       if (data != NULL)
01629        free (data);
01630       return FALSE;
01631     }
01632 
01633   start = 0;
01634 
01635   for (i = start; i < stop; i += onaline)
01636     {
01637       bfd_vma begin_addr;
01638       bfd_vma end_addr;
01639       bfd_vma eh_handler;
01640       bfd_vma eh_data;
01641       bfd_vma prolog_end_addr;
01642       int em_data;
01643 
01644       if (i + PDATA_ROW_SIZE > stop)
01645        break;
01646 
01647       begin_addr      = GET_PDATA_ENTRY (abfd, data + i     );
01648       end_addr        = GET_PDATA_ENTRY (abfd, data + i +  4);
01649       eh_handler      = GET_PDATA_ENTRY (abfd, data + i +  8);
01650       eh_data         = GET_PDATA_ENTRY (abfd, data + i + 12);
01651       prolog_end_addr = GET_PDATA_ENTRY (abfd, data + i + 16);
01652 
01653       if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
01654          && eh_data == 0 && prolog_end_addr == 0)
01655        /* We are probably into the padding of the section now.  */
01656        break;
01657 
01658       em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
01659       eh_handler &= ~(bfd_vma) 0x3;
01660       prolog_end_addr &= ~(bfd_vma) 0x3;
01661 
01662       fputc (' ', file);
01663       fprintf_vma (file, i + section->vma); fputc ('\t', file);
01664       fprintf_vma (file, begin_addr); fputc (' ', file);
01665       fprintf_vma (file, end_addr); fputc (' ', file);
01666       fprintf_vma (file, eh_handler);
01667 #if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
01668       fputc (' ', file);
01669       fprintf_vma (file, eh_data); fputc (' ', file);
01670       fprintf_vma (file, prolog_end_addr);
01671       fprintf (file, "   %x", em_data);
01672 #endif
01673 
01674 #ifdef POWERPC_LE_PE
01675       if (eh_handler == 0 && eh_data != 0)
01676        {
01677          /* Special bits here, although the meaning may be a little
01678             mysterious. The only one I know for sure is 0x03
01679             Code Significance
01680             0x00 None
01681             0x01 Register Save Millicode
01682             0x02 Register Restore Millicode
01683             0x03 Glue Code Sequence.  */
01684          switch (eh_data)
01685            {
01686            case 0x01:
01687              fprintf (file, _(" Register save millicode"));
01688              break;
01689            case 0x02:
01690              fprintf (file, _(" Register restore millicode"));
01691              break;
01692            case 0x03:
01693              fprintf (file, _(" Glue code sequence"));
01694              break;
01695            default:
01696              break;
01697            }
01698        }
01699 #endif
01700       fprintf (file, "\n");
01701     }
01702 
01703   free (data);
01704 
01705   return TRUE;
01706 }
01707 
01708 #define IMAGE_REL_BASED_HIGHADJ 4
01709 static const char * const tbl[] =
01710 {
01711   "ABSOLUTE",
01712   "HIGH",
01713   "LOW",
01714   "HIGHLOW",
01715   "HIGHADJ",
01716   "MIPS_JMPADDR",
01717   "SECTION",
01718   "REL32",
01719   "RESERVED1",
01720   "MIPS_JMPADDR16",
01721   "DIR64",
01722   "HIGH3ADJ",
01723   "UNKNOWN",   /* MUST be last.  */
01724 };
01725 
01726 static bfd_boolean
01727 pe_print_reloc (bfd * abfd, void * vfile)
01728 {
01729   FILE *file = (FILE *) vfile;
01730   bfd_byte *data = 0;
01731   asection *section = bfd_get_section_by_name (abfd, ".reloc");
01732   bfd_size_type datasize;
01733   bfd_size_type i;
01734   bfd_size_type start, stop;
01735 
01736   if (section == NULL)
01737     return TRUE;
01738 
01739   if (section->size == 0)
01740     return TRUE;
01741 
01742   fprintf (file,
01743           _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n"));
01744 
01745   datasize = section->size;
01746   if (! bfd_malloc_and_get_section (abfd, section, &data))
01747     {
01748       if (data != NULL)
01749        free (data);
01750       return FALSE;
01751     }
01752 
01753   start = 0;
01754 
01755   stop = section->size;
01756 
01757   for (i = start; i < stop;)
01758     {
01759       int j;
01760       bfd_vma virtual_address;
01761       long number, size;
01762 
01763       /* The .reloc section is a sequence of blocks, with a header consisting
01764         of two 32 bit quantities, followed by a number of 16 bit entries.  */
01765       virtual_address = bfd_get_32 (abfd, data+i);
01766       size = bfd_get_32 (abfd, data+i+4);
01767       number = (size - 8) / 2;
01768 
01769       if (size == 0)
01770        break;
01771 
01772       fprintf (file,
01773               _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
01774               (unsigned long) virtual_address, size, size, number);
01775 
01776       for (j = 0; j < number; ++j)
01777        {
01778          unsigned short e = bfd_get_16 (abfd, data + i + 8 + j * 2);
01779          unsigned int t = (e & 0xF000) >> 12;
01780          int off = e & 0x0FFF;
01781 
01782          if (t >= sizeof (tbl) / sizeof (tbl[0]))
01783            t = (sizeof (tbl) / sizeof (tbl[0])) - 1;
01784 
01785          fprintf (file,
01786                  _("\treloc %4d offset %4x [%4lx] %s"),
01787                  j, off, (long) (off + virtual_address), tbl[t]);
01788 
01789          /* HIGHADJ takes an argument, - the next record *is* the
01790             low 16 bits of addend.  */
01791          if (t == IMAGE_REL_BASED_HIGHADJ)
01792            {
01793              fprintf (file, " (%4x)",
01794                      ((unsigned int)
01795                      bfd_get_16 (abfd, data + i + 8 + j * 2 + 2)));
01796              j++;
01797            }
01798 
01799          fprintf (file, "\n");
01800        }
01801 
01802       i += size;
01803     }
01804 
01805   free (data);
01806 
01807   return TRUE;
01808 }
01809 
01810 /* Print out the program headers.  */
01811 
01812 bfd_boolean
01813 _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
01814 {
01815   FILE *file = (FILE *) vfile;
01816   int j;
01817   pe_data_type *pe = pe_data (abfd);
01818   struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
01819   const char *subsystem_name = NULL;
01820   const char *name;
01821 
01822   /* The MS dumpbin program reportedly ands with 0xff0f before
01823      printing the characteristics field.  Not sure why.  No reason to
01824      emulate it here.  */
01825   fprintf (file, _("\nCharacteristics 0x%x\n"), pe->real_flags);
01826 #undef PF
01827 #define PF(x, y) if (pe->real_flags & x) { fprintf (file, "\t%s\n", y); }
01828   PF (IMAGE_FILE_RELOCS_STRIPPED, "relocations stripped");
01829   PF (IMAGE_FILE_EXECUTABLE_IMAGE, "executable");
01830   PF (IMAGE_FILE_LINE_NUMS_STRIPPED, "line numbers stripped");
01831   PF (IMAGE_FILE_LOCAL_SYMS_STRIPPED, "symbols stripped");
01832   PF (IMAGE_FILE_LARGE_ADDRESS_AWARE, "large address aware");
01833   PF (IMAGE_FILE_BYTES_REVERSED_LO, "little endian");
01834   PF (IMAGE_FILE_32BIT_MACHINE, "32 bit words");
01835   PF (IMAGE_FILE_DEBUG_STRIPPED, "debugging information removed");
01836   PF (IMAGE_FILE_SYSTEM, "system file");
01837   PF (IMAGE_FILE_DLL, "DLL");
01838   PF (IMAGE_FILE_BYTES_REVERSED_HI, "big endian");
01839 #undef PF
01840 
01841   /* ctime implies '\n'.  */
01842   {
01843     time_t t = pe->coff.timestamp;
01844     fprintf (file, "\nTime/Date\t\t%s", ctime (&t));
01845   }
01846 
01847 #ifndef IMAGE_NT_OPTIONAL_HDR_MAGIC
01848 # define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
01849 #endif
01850 #ifndef IMAGE_NT_OPTIONAL_HDR64_MAGIC
01851 # define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
01852 #endif
01853 #ifndef IMAGE_NT_OPTIONAL_HDRROM_MAGIC
01854 # define IMAGE_NT_OPTIONAL_HDRROM_MAGIC 0x107
01855 #endif
01856 
01857   switch (i->Magic)
01858     {
01859     case IMAGE_NT_OPTIONAL_HDR_MAGIC:
01860       name = "PE32";
01861       break;
01862     case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
01863       name = "PE32+";
01864       break;
01865     case IMAGE_NT_OPTIONAL_HDRROM_MAGIC:
01866       name = "ROM";
01867       break;
01868     default:
01869       name = NULL;
01870       break;
01871     }
01872   fprintf (file, "Magic\t\t\t%04x", i->Magic);
01873   if (name)
01874     fprintf (file, "\t(%s)",name);
01875   fprintf (file, "\nMajorLinkerVersion\t%d\n", i->MajorLinkerVersion);
01876   fprintf (file, "MinorLinkerVersion\t%d\n", i->MinorLinkerVersion);
01877   fprintf (file, "SizeOfCode\t\t%08lx\n", i->SizeOfCode);
01878   fprintf (file, "SizeOfInitializedData\t%08lx\n",
01879           i->SizeOfInitializedData);
01880   fprintf (file, "SizeOfUninitializedData\t%08lx\n",
01881           i->SizeOfUninitializedData);
01882   fprintf (file, "AddressOfEntryPoint\t");
01883   fprintf_vma (file, i->AddressOfEntryPoint);
01884   fprintf (file, "\nBaseOfCode\t\t");
01885   fprintf_vma (file, i->BaseOfCode);
01886 #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
01887   /* PE32+ does not have BaseOfData member!  */
01888   fprintf (file, "\nBaseOfData\t\t");
01889   fprintf_vma (file, i->BaseOfData);
01890 #endif
01891 
01892   fprintf (file, "\nImageBase\t\t");
01893   fprintf_vma (file, i->ImageBase);
01894   fprintf (file, "\nSectionAlignment\t");
01895   fprintf_vma (file, i->SectionAlignment);
01896   fprintf (file, "\nFileAlignment\t\t");
01897   fprintf_vma (file, i->FileAlignment);
01898   fprintf (file, "\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
01899   fprintf (file, "MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
01900   fprintf (file, "MajorImageVersion\t%d\n", i->MajorImageVersion);
01901   fprintf (file, "MinorImageVersion\t%d\n", i->MinorImageVersion);
01902   fprintf (file, "MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
01903   fprintf (file, "MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
01904   fprintf (file, "Win32Version\t\t%08lx\n", i->Reserved1);
01905   fprintf (file, "SizeOfImage\t\t%08lx\n", i->SizeOfImage);
01906   fprintf (file, "SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
01907   fprintf (file, "CheckSum\t\t%08lx\n", i->CheckSum);
01908 
01909   switch (i->Subsystem)
01910     {
01911     case IMAGE_SUBSYSTEM_UNKNOWN:
01912       subsystem_name = "unspecified";
01913       break;
01914     case IMAGE_SUBSYSTEM_NATIVE:
01915       subsystem_name = "NT native";
01916       break;
01917     case IMAGE_SUBSYSTEM_WINDOWS_GUI:
01918       subsystem_name = "Windows GUI";
01919       break;
01920     case IMAGE_SUBSYSTEM_WINDOWS_CUI:
01921       subsystem_name = "Windows CUI";
01922       break;
01923     case IMAGE_SUBSYSTEM_POSIX_CUI:
01924       subsystem_name = "POSIX CUI";
01925       break;
01926     case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
01927       subsystem_name = "Wince CUI";
01928       break;
01929     case IMAGE_SUBSYSTEM_EFI_APPLICATION:
01930       subsystem_name = "EFI application";
01931       break;
01932     case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
01933       subsystem_name = "EFI boot service driver";
01934       break;
01935     case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
01936       subsystem_name = "EFI runtime driver";
01937       break;
01938     // These are from revision 8.0 of the MS PE/COFF spec
01939     case IMAGE_SUBSYSTEM_EFI_ROM:
01940       subsystem_name = "EFI ROM";
01941       break;
01942     case IMAGE_SUBSYSTEM_XBOX:
01943       subsystem_name = "XBOX";
01944       break;
01945     // Added default case for clarity - subsystem_name is NULL anyway.
01946     default:
01947       subsystem_name = NULL;
01948     }
01949 
01950   fprintf (file, "Subsystem\t\t%08x", i->Subsystem);
01951   if (subsystem_name)
01952     fprintf (file, "\t(%s)", subsystem_name);
01953   fprintf (file, "\nDllCharacteristics\t%08x\n", i->DllCharacteristics);
01954   fprintf (file, "SizeOfStackReserve\t");
01955   fprintf_vma (file, i->SizeOfStackReserve);
01956   fprintf (file, "\nSizeOfStackCommit\t");
01957   fprintf_vma (file, i->SizeOfStackCommit);
01958   fprintf (file, "\nSizeOfHeapReserve\t");
01959   fprintf_vma (file, i->SizeOfHeapReserve);
01960   fprintf (file, "\nSizeOfHeapCommit\t");
01961   fprintf_vma (file, i->SizeOfHeapCommit);
01962   fprintf (file, "\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
01963   fprintf (file, "NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
01964 
01965   fprintf (file, "\nThe Data Directory\n");
01966   for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
01967     {
01968       fprintf (file, "Entry %1x ", j);
01969       fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
01970       fprintf (file, " %08lx ", i->DataDirectory[j].Size);
01971       fprintf (file, "%s\n", dir_names[j]);
01972     }
01973 
01974   pe_print_idata (abfd, vfile);
01975   pe_print_edata (abfd, vfile);
01976   pe_print_pdata (abfd, vfile);
01977   pe_print_reloc (abfd, vfile);
01978 
01979   return TRUE;
01980 }
01981 
01982 /* Copy any private info we understand from the input bfd
01983    to the output bfd.  */
01984 
01985 bfd_boolean
01986 _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
01987 {
01988   /* One day we may try to grok other private data.  */
01989   if (ibfd->xvec->flavour != bfd_target_coff_flavour
01990       || obfd->xvec->flavour != bfd_target_coff_flavour)
01991     return TRUE;
01992 
01993   pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
01994   pe_data (obfd)->dll = pe_data (ibfd)->dll;
01995 
01996   /* For strip: if we removed .reloc, we'll make a real mess of things
01997      if we don't remove this entry as well.  */
01998   if (! pe_data (obfd)->has_reloc_section)
01999     {
02000       pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].VirtualAddress = 0;
02001       pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].Size = 0;
02002     }
02003   return TRUE;
02004 }
02005 
02006 /* Copy private section data.  */
02007 
02008 bfd_boolean
02009 _bfd_XX_bfd_copy_private_section_data (bfd *ibfd,
02010                                    asection *isec,
02011                                    bfd *obfd,
02012                                    asection *osec)
02013 {
02014   if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour
02015       || bfd_get_flavour (obfd) != bfd_target_coff_flavour)
02016     return TRUE;
02017 
02018   if (coff_section_data (ibfd, isec) != NULL
02019       && pei_section_data (ibfd, isec) != NULL)
02020     {
02021       if (coff_section_data (obfd, osec) == NULL)
02022        {
02023          bfd_size_type amt = sizeof (struct coff_section_tdata);
02024          osec->used_by_bfd = bfd_zalloc (obfd, amt);
02025          if (osec->used_by_bfd == NULL)
02026            return FALSE;
02027        }
02028 
02029       if (pei_section_data (obfd, osec) == NULL)
02030        {
02031          bfd_size_type amt = sizeof (struct pei_section_tdata);
02032          coff_section_data (obfd, osec)->tdata = bfd_zalloc (obfd, amt);
02033          if (coff_section_data (obfd, osec)->tdata == NULL)
02034            return FALSE;
02035        }
02036 
02037       pei_section_data (obfd, osec)->virt_size =
02038        pei_section_data (ibfd, isec)->virt_size;
02039       pei_section_data (obfd, osec)->pe_flags =
02040        pei_section_data (ibfd, isec)->pe_flags;
02041     }
02042 
02043   return TRUE;
02044 }
02045 
02046 void
02047 _bfd_XX_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret)
02048 {
02049   coff_get_symbol_info (abfd, symbol, ret);
02050 }
02051 
02052 /* Handle the .idata section and other things that need symbol table
02053    access.  */
02054 
02055 bfd_boolean
02056 _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
02057 {
02058   struct coff_link_hash_entry *h1;
02059   struct bfd_link_info *info = pfinfo->info;
02060   bfd_boolean result = TRUE;
02061 
02062   /* There are a few fields that need to be filled in now while we
02063      have symbol table access.
02064 
02065      The .idata subsections aren't directly available as sections, but
02066      they are in the symbol table, so get them from there.  */
02067 
02068   /* The import directory.  This is the address of .idata$2, with size
02069      of .idata$2 + .idata$3.  */
02070   h1 = coff_link_hash_lookup (coff_hash_table (info),
02071                            ".idata$2", FALSE, FALSE, TRUE);
02072   if (h1 != NULL)
02073     {
02074       /* PR ld/2729: We cannot rely upon all the output sections having been 
02075         created properly, so check before referencing them.  Issue a warning
02076         message for any sections tht could not be found.  */
02077       if (h1->root.u.def.section != NULL
02078          && h1->root.u.def.section->output_section != NULL)
02079        pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress =
02080          (h1->root.u.def.value
02081           + h1->root.u.def.section->output_section->vma
02082           + h1->root.u.def.section->output_offset);
02083       else
02084        {
02085          _bfd_error_handler
02086            (_("%B: unable to fill in DataDictionary[1] because .idata$2 is missing"), 
02087             abfd);
02088          result = FALSE;
02089        }
02090 
02091       h1 = coff_link_hash_lookup (coff_hash_table (info),
02092                               ".idata$4", FALSE, FALSE, TRUE);
02093       if (h1 != NULL
02094          && h1->root.u.def.section != NULL
02095          && h1->root.u.def.section->output_section != NULL)
02096        pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].Size =
02097          ((h1->root.u.def.value
02098            + h1->root.u.def.section->output_section->vma
02099            + h1->root.u.def.section->output_offset)
02100           - pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress);
02101       else
02102        {
02103          _bfd_error_handler
02104            (_("%B: unable to fill in DataDictionary[1] because .idata$4 is missing"), 
02105             abfd);
02106          result = FALSE;
02107        }
02108 
02109       /* The import address table.  This is the size/address of
02110          .idata$5.  */
02111       h1 = coff_link_hash_lookup (coff_hash_table (info),
02112                               ".idata$5", FALSE, FALSE, TRUE);
02113       if (h1 != NULL
02114          && h1->root.u.def.section != NULL
02115          && h1->root.u.def.section->output_section != NULL)
02116        pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress =
02117          (h1->root.u.def.value
02118           + h1->root.u.def.section->output_section->vma
02119           + h1->root.u.def.section->output_offset);
02120       else
02121        {
02122          _bfd_error_handler
02123            (_("%B: unable to fill in DataDictionary[12] because .idata$5 is missing"), 
02124             abfd);
02125          result = FALSE;
02126        }
02127 
02128       h1 = coff_link_hash_lookup (coff_hash_table (info),
02129                               ".idata$6", FALSE, FALSE, TRUE);
02130       if (h1 != NULL
02131          && h1->root.u.def.section != NULL
02132          && h1->root.u.def.section->output_section != NULL)
02133        pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size =
02134          ((h1->root.u.def.value
02135            + h1->root.u.def.section->output_section->vma
02136            + h1->root.u.def.section->output_offset)
02137           - pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress);      
02138       else
02139        {
02140          _bfd_error_handler
02141            (_("%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"), 
02142             abfd);
02143          result = FALSE;
02144        }
02145     }
02146 
02147   h1 = coff_link_hash_lookup (coff_hash_table (info),
02148                            "__tls_used", FALSE, FALSE, TRUE);
02149   if (h1 != NULL)
02150     {
02151       if (h1->root.u.def.section != NULL
02152          && h1->root.u.def.section->output_section != NULL)
02153        pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].VirtualAddress =
02154          (h1->root.u.def.value
02155           + h1->root.u.def.section->output_section->vma
02156           + h1->root.u.def.section->output_offset
02157           - pe_data (abfd)->pe_opthdr.ImageBase);
02158       else
02159        {
02160          _bfd_error_handler
02161            (_("%B: unable to fill in DataDictionary[9] because __tls_used is missing"), 
02162             abfd);
02163          result = FALSE;
02164        }
02165 
02166       pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18;
02167     }
02168 
02169   /* If we couldn't find idata$2, we either have an excessively
02170      trivial program or are in DEEP trouble; we have to assume trivial
02171      program....  */
02172   return result;
02173 }