Back to index

cell-binutils  2.17cvs20070401
pe-dll.c
Go to the documentation of this file.
00001 /* Routines to help build PEI-format DLLs (Win32 etc)
00002    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
00003    Free Software Foundation, Inc.
00004    Written by DJ Delorie <dj@cygnus.com>
00005 
00006    This file is part of GLD, the Gnu Linker.
00007 
00008    GLD 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, or (at your option)
00011    any later version.
00012 
00013    GLD 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 GLD; see the file COPYING.  If not, write to the Free
00020    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00021    02110-1301, USA.  */
00022 
00023 #include "bfd.h"
00024 #include "sysdep.h"
00025 #include "bfdlink.h"
00026 #include "libiberty.h"
00027 #include "safe-ctype.h"
00028 
00029 #include <time.h>
00030 
00031 #include "ld.h"
00032 #include "ldexp.h"
00033 #include "ldlang.h"
00034 #include "ldwrite.h"
00035 #include "ldmisc.h"
00036 #include <ldgram.h>
00037 #include "ldmain.h"
00038 #include "ldfile.h"
00039 #include "ldemul.h"
00040 #include "coff/internal.h"
00041 #include "../bfd/libcoff.h"
00042 #include "deffile.h"
00043 #include "pe-dll.h"
00044 
00045 #ifdef pe_use_x86_64
00046 
00047 #define PE_IDATA4_SIZE      8
00048 #define PE_IDATA5_SIZE      8
00049 #include "pep-dll.h"
00050 #undef  AOUTSZ
00051 #define AOUTSZ              PEPAOUTSZ
00052 #define PEAOUTHDR    PEPAOUTHDR
00053 
00054 #else
00055 
00056 #include "pe-dll.h"
00057 
00058 #endif
00059 
00060 #ifndef PE_IDATA4_SIZE
00061 #define PE_IDATA4_SIZE      4
00062 #endif
00063 
00064 #ifndef PE_IDATA5_SIZE
00065 #define PE_IDATA5_SIZE      4
00066 #endif
00067 
00068 /*  This file turns a regular Windows PE image into a DLL.  Because of
00069     the complexity of this operation, it has been broken down into a
00070     number of separate modules which are all called by the main function
00071     at the end of this file.  This function is not re-entrant and is
00072     normally only called once, so static variables are used to reduce
00073     the number of parameters and return values required.
00074 
00075     See also: ld/emultempl/pe.em and ld/emultempl/pep.em.  */
00076 
00077 /*  Auto-import feature by Paul Sokolovsky
00078 
00079     Quick facts:
00080 
00081     1. With this feature on, DLL clients can import variables from DLL
00082     without any concern from their side (for example, without any source
00083     code modifications).
00084 
00085     2. This is done completely in bounds of the PE specification (to be fair,
00086     there's a place where it pokes nose out of, but in practice it works).
00087     So, resulting module can be used with any other PE compiler/linker.
00088 
00089     3. Auto-import is fully compatible with standard import method and they
00090     can be mixed together.
00091 
00092     4. Overheads: space: 8 bytes per imported symbol, plus 20 for each
00093     reference to it; load time: negligible; virtual/physical memory: should be
00094     less than effect of DLL relocation, and I sincerely hope it doesn't affect
00095     DLL sharability (too much).
00096 
00097     Idea
00098 
00099     The obvious and only way to get rid of dllimport insanity is to make client
00100     access variable directly in the DLL, bypassing extra dereference. I.e.,
00101     whenever client contains something like
00102 
00103     mov dll_var,%eax,
00104 
00105     address of dll_var in the command should be relocated to point into loaded
00106     DLL. The aim is to make OS loader do so, and than make ld help with that.
00107     Import section of PE made following way: there's a vector of structures
00108     each describing imports from particular DLL. Each such structure points
00109     to two other parallel vectors: one holding imported names, and one which
00110     will hold address of corresponding imported name. So, the solution is
00111     de-vectorize these structures, making import locations be sparse and
00112     pointing directly into code. Before continuing, it is worth a note that,
00113     while authors strives to make PE act ELF-like, there're some other people
00114     make ELF act PE-like: elfvector, ;-) .
00115 
00116     Implementation
00117 
00118     For each reference of data symbol to be imported from DLL (to set of which
00119     belong symbols with name <sym>, if __imp_<sym> is found in implib), the
00120     import fixup entry is generated. That entry is of type
00121     IMAGE_IMPORT_DESCRIPTOR and stored in .idata$2 subsection. Each
00122     fixup entry contains pointer to symbol's address within .text section
00123     (marked with __fuN_<sym> symbol, where N is integer), pointer to DLL name
00124     (so, DLL name is referenced by multiple entries), and pointer to symbol
00125     name thunk. Symbol name thunk is singleton vector (__nm_th_<symbol>)
00126     pointing to IMAGE_IMPORT_BY_NAME structure (__nm_<symbol>) directly
00127     containing imported name. Here comes that "on the edge" problem mentioned
00128     above: PE specification rambles that name vector (OriginalFirstThunk)
00129     should run in parallel with addresses vector (FirstThunk), i.e. that they
00130     should have same number of elements and terminated with zero. We violate
00131     this, since FirstThunk points directly into machine code. But in practice,
00132     OS loader implemented the sane way: it goes thru OriginalFirstThunk and
00133     puts addresses to FirstThunk, not something else. It once again should be
00134     noted that dll and symbol name structures are reused across fixup entries
00135     and should be there anyway to support standard import stuff, so sustained
00136     overhead is 20 bytes per reference. Other question is whether having several
00137     IMAGE_IMPORT_DESCRIPTORS for the same DLL is possible. Answer is yes, it is
00138     done even by native compiler/linker (libth32's functions are in fact reside
00139     in windows9x kernel32.dll, so if you use it, you have two
00140     IMAGE_IMPORT_DESCRIPTORS for kernel32.dll). Yet other question is whether
00141     referencing the same PE structures several times is valid. The answer is why
00142     not, prohibiting that (detecting violation) would require more work on
00143     behalf of loader than not doing it.
00144 
00145     See also: ld/emultempl/pe.em and ld/emultempl/pep.em.  */
00146 
00147 static void add_bfd_to_link (bfd *, const char *, struct bfd_link_info *);
00148 
00149 /* For emultempl/pe.em.  */
00150 
00151 def_file * pe_def_file = 0;
00152 int pe_dll_export_everything = 0;
00153 int pe_dll_do_default_excludes = 1;
00154 int pe_dll_kill_ats = 0;
00155 int pe_dll_stdcall_aliases = 0;
00156 int pe_dll_warn_dup_exports = 0;
00157 int pe_dll_compat_implib = 0;
00158 int pe_dll_extra_pe_debug = 0;
00159 
00160 /* Static variables and types.  */
00161 
00162 static bfd_vma image_base;
00163 static bfd *filler_bfd;
00164 static struct bfd_section *edata_s, *reloc_s;
00165 static unsigned char *edata_d, *reloc_d;
00166 static size_t edata_sz, reloc_sz;
00167 static int runtime_pseudo_relocs_created = 0;
00168 
00169 typedef struct
00170 {
00171   const char *name;
00172   int len;
00173 }
00174 autofilter_entry_type;
00175 
00176 typedef struct
00177 {
00178   const char *target_name;
00179   const char *object_target;
00180   unsigned int imagebase_reloc;
00181   int pe_arch;
00182   int bfd_arch;
00183   bfd_boolean underscored;
00184   const autofilter_entry_type* autofilter_symbollist; 
00185 }
00186 pe_details_type;
00187 
00188 static const autofilter_entry_type autofilter_symbollist_generic[] =
00189 {
00190   { STRING_COMMA_LEN (".text") },
00191   /* Entry point symbols.  */
00192   { STRING_COMMA_LEN ("DllMain") },
00193   { STRING_COMMA_LEN ("DllMainCRTStartup") },
00194   { STRING_COMMA_LEN ("_DllMainCRTStartup") },
00195   /* Runtime pseudo-reloc.  */
00196   { STRING_COMMA_LEN ("_pei386_runtime_relocator") },
00197   { STRING_COMMA_LEN ("do_pseudo_reloc") },
00198   { STRING_COMMA_LEN (NULL) }
00199 };
00200 
00201 static const autofilter_entry_type autofilter_symbollist_i386[] =
00202 {
00203   { STRING_COMMA_LEN (".text") },
00204   /* Entry point symbols, and entry hooks.  */
00205   { STRING_COMMA_LEN ("cygwin_crt0") },
00206   { STRING_COMMA_LEN ("DllMain@12") },
00207   { STRING_COMMA_LEN ("DllEntryPoint@0") },
00208   { STRING_COMMA_LEN ("DllMainCRTStartup@12") },
00209   { STRING_COMMA_LEN ("_cygwin_dll_entry@12") },
00210   { STRING_COMMA_LEN ("_cygwin_crt0_common@8") },
00211   { STRING_COMMA_LEN ("_cygwin_noncygwin_dll_entry@12") },
00212   { STRING_COMMA_LEN ("cygwin_attach_dll") },
00213   { STRING_COMMA_LEN ("cygwin_premain0") },
00214   { STRING_COMMA_LEN ("cygwin_premain1") },
00215   { STRING_COMMA_LEN ("cygwin_premain2") },
00216   { STRING_COMMA_LEN ("cygwin_premain3") },
00217   /* Runtime pseudo-reloc.  */
00218   { STRING_COMMA_LEN ("_pei386_runtime_relocator") },
00219   { STRING_COMMA_LEN ("do_pseudo_reloc") },
00220   /* Global vars that should not be exported.  */
00221   { STRING_COMMA_LEN ("impure_ptr") },
00222   { STRING_COMMA_LEN ("_impure_ptr") },
00223   { STRING_COMMA_LEN ("_fmode") },
00224   { STRING_COMMA_LEN ("environ") },
00225   { STRING_COMMA_LEN (NULL) }
00226 };
00227 
00228 #define PE_ARCH_i386  1
00229 #define PE_ARCH_sh    2
00230 #define PE_ARCH_mips  3
00231 #define PE_ARCH_arm   4
00232 #define PE_ARCH_arm_epoc 5
00233 #define PE_ARCH_arm_wince 6
00234 
00235 static const pe_details_type pe_detail_list[] =
00236 {
00237   {
00238 #ifdef pe_use_x86_64
00239     "pei-x86-64",
00240     "pe-x86-64",
00241     3 /* R_IMAGEBASE */,
00242 #else
00243     "pei-i386",
00244     "pe-i386",
00245     7 /* R_IMAGEBASE */,
00246 #endif
00247     PE_ARCH_i386,
00248     bfd_arch_i386,
00249     TRUE,
00250     autofilter_symbollist_i386
00251   },
00252   {
00253     "pei-shl",
00254     "pe-shl",
00255     16 /* R_SH_IMAGEBASE */,
00256     PE_ARCH_sh,
00257     bfd_arch_sh,
00258     TRUE,
00259     autofilter_symbollist_generic
00260   },
00261   {
00262     "pei-mips",
00263     "pe-mips",
00264     34 /* MIPS_R_RVA */,
00265     PE_ARCH_mips,
00266     bfd_arch_mips,
00267     FALSE,
00268     autofilter_symbollist_generic
00269   },
00270   {
00271     "pei-arm-little",
00272     "pe-arm-little",
00273     11 /* ARM_RVA32 */,
00274     PE_ARCH_arm,
00275     bfd_arch_arm,
00276     TRUE,
00277     autofilter_symbollist_generic
00278   },
00279   {
00280     "epoc-pei-arm-little",
00281     "epoc-pe-arm-little",
00282     11 /* ARM_RVA32 */,
00283     PE_ARCH_arm_epoc,
00284     bfd_arch_arm,
00285     FALSE,
00286     autofilter_symbollist_generic
00287   },
00288   {
00289     "pei-arm-wince-little",
00290     "pe-arm-wince-little",
00291     2,  /* ARM_RVA32 on Windows CE, see bfd/coff-arm.c.  */
00292     PE_ARCH_arm_wince,
00293     bfd_arch_arm,
00294     FALSE,
00295     autofilter_symbollist_generic
00296   },
00297   { NULL, NULL, 0, 0, 0, FALSE, NULL }
00298 };
00299 
00300 static const pe_details_type *pe_details;
00301 
00302 /* Do not specify library suffix explicitly, to allow for dllized versions.  */
00303 static const autofilter_entry_type autofilter_liblist[] =
00304 {
00305   { STRING_COMMA_LEN ("libcegcc") },
00306   { STRING_COMMA_LEN ("libcygwin") },
00307   { STRING_COMMA_LEN ("libgcc") },
00308   { STRING_COMMA_LEN ("libstdc++") },
00309   { STRING_COMMA_LEN ("libmingw32") },
00310   { STRING_COMMA_LEN ("libmingwex") },
00311   { STRING_COMMA_LEN ("libg2c") },
00312   { STRING_COMMA_LEN ("libsupc++") },
00313   { STRING_COMMA_LEN ("libobjc") },
00314   { STRING_COMMA_LEN ("libgcj") },
00315   { STRING_COMMA_LEN (NULL) }
00316 };
00317 
00318 static const autofilter_entry_type autofilter_objlist[] =
00319 {
00320   { STRING_COMMA_LEN ("crt0.o") },
00321   { STRING_COMMA_LEN ("crt1.o") },
00322   { STRING_COMMA_LEN ("crt2.o") },
00323   { STRING_COMMA_LEN ("dllcrt1.o") },
00324   { STRING_COMMA_LEN ("dllcrt2.o") },
00325   { STRING_COMMA_LEN ("gcrt0.o") },
00326   { STRING_COMMA_LEN ("gcrt1.o") },
00327   { STRING_COMMA_LEN ("gcrt2.o") },
00328   { STRING_COMMA_LEN ("crtbegin.o") },
00329   { STRING_COMMA_LEN ("crtend.o") },
00330   { STRING_COMMA_LEN (NULL) }
00331 };
00332 
00333 static const autofilter_entry_type autofilter_symbolprefixlist[] =
00334 {
00335   /* _imp_ is treated specially, as it is always underscored.  */
00336   /* { STRING_COMMA_LEN ("_imp_") },  */
00337   /* Don't export some c++ symbols.  */
00338   { STRING_COMMA_LEN ("__rtti_") },
00339   { STRING_COMMA_LEN ("__builtin_") },
00340   /* Don't re-export auto-imported symbols.  */
00341   { STRING_COMMA_LEN ("_nm_") },
00342   /* Don't export symbols specifying internal DLL layout.  */
00343   { STRING_COMMA_LEN ("_head_") },
00344   { STRING_COMMA_LEN (NULL) }
00345 };
00346 
00347 static const autofilter_entry_type autofilter_symbolsuffixlist[] =
00348 {
00349   { STRING_COMMA_LEN ("_iname") },
00350   { STRING_COMMA_LEN (NULL) }
00351 };
00352 
00353 #define U(str) (pe_details->underscored ? "_" str : str)
00354 
00355 void
00356 pe_dll_id_target (const char *target)
00357 {
00358   int i;
00359 
00360   for (i = 0; pe_detail_list[i].target_name; i++)
00361     if (strcmp (pe_detail_list[i].target_name, target) == 0
00362        || strcmp (pe_detail_list[i].object_target, target) == 0)
00363       {
00364        pe_details = pe_detail_list + i;
00365        return;
00366       }
00367   einfo (_("%XUnsupported PEI architecture: %s\n"), target);
00368   exit (1);
00369 }
00370 
00371 /* Helper functions for qsort.  Relocs must be sorted so that we can write
00372    them out by pages.  */
00373 
00374 typedef struct
00375   {
00376     bfd_vma vma;
00377     char type;
00378     short extra;
00379   }
00380 reloc_data_type;
00381 
00382 static int
00383 reloc_sort (const void *va, const void *vb)
00384 {
00385   bfd_vma a = ((const reloc_data_type *) va)->vma;
00386   bfd_vma b = ((const reloc_data_type *) vb)->vma;
00387 
00388   return (a > b) ? 1 : ((a < b) ? -1 : 0);
00389 }
00390 
00391 static int
00392 pe_export_sort (const void *va, const void *vb)
00393 {
00394   const def_file_export *a = va;
00395   const def_file_export *b = vb;
00396 
00397   return strcmp (a->name, b->name);
00398 }
00399 
00400 /* Read and process the .DEF file.  */
00401 
00402 /* These correspond to the entries in pe_def_file->exports[].  I use
00403    exported_symbol_sections[i] to tag whether or not the symbol was
00404    defined, since we can't export symbols we don't have.  */
00405 
00406 static bfd_vma *exported_symbol_offsets;
00407 static struct bfd_section **exported_symbol_sections;
00408 static int export_table_size;
00409 static int count_exported;
00410 static int count_exported_byname;
00411 static int count_with_ordinals;
00412 static const char *dll_name;
00413 static int min_ordinal, max_ordinal;
00414 static int *exported_symbols;
00415 
00416 typedef struct exclude_list_struct
00417   {
00418     char *string;
00419     struct exclude_list_struct *next;
00420     int type;
00421   }
00422 exclude_list_struct;
00423 
00424 static struct exclude_list_struct *excludes = 0;
00425 
00426 void
00427 pe_dll_add_excludes (const char *new_excludes, const int type)
00428 {
00429   char *local_copy;
00430   char *exclude_string;
00431 
00432   local_copy = xstrdup (new_excludes);
00433 
00434   exclude_string = strtok (local_copy, ",:");
00435   for (; exclude_string; exclude_string = strtok (NULL, ",:"))
00436     {
00437       struct exclude_list_struct *new_exclude;
00438 
00439       new_exclude = xmalloc (sizeof (struct exclude_list_struct));
00440       new_exclude->string = xmalloc (strlen (exclude_string) + 1);
00441       strcpy (new_exclude->string, exclude_string);
00442       new_exclude->type = type;
00443       new_exclude->next = excludes;
00444       excludes = new_exclude;
00445     }
00446 
00447   free (local_copy);
00448 }
00449 
00450 static bfd_boolean
00451 is_import (const char* n)
00452 {
00453   return (CONST_STRNEQ (n, "__imp_"));
00454 }
00455 
00456 /* abfd is a bfd containing n (or NULL)
00457    It can be used for contextual checks.  */
00458 
00459 static int
00460 auto_export (bfd *abfd, def_file *d, const char *n)
00461 {
00462   int i;
00463   struct exclude_list_struct *ex;
00464   const autofilter_entry_type *afptr;
00465   const char * libname = 0;
00466   if (abfd && abfd->my_archive)
00467     libname = lbasename (abfd->my_archive->filename);
00468 
00469   for (i = 0; i < d->num_exports; i++)
00470     if (strcmp (d->exports[i].name, n) == 0)
00471       return 0;
00472 
00473   if (pe_dll_do_default_excludes)
00474     {
00475       const char * p;
00476       int    len;
00477 
00478       if (pe_dll_extra_pe_debug)
00479        printf ("considering exporting: %s, abfd=%p, abfd->my_arc=%p\n",
00480               n, abfd, abfd->my_archive);
00481 
00482       /* First of all, make context checks:
00483         Don't export anything from standard libs.  */
00484       if (libname)
00485        {
00486          afptr = autofilter_liblist;
00487 
00488          while (afptr->name)
00489            {
00490              if (strncmp (libname, afptr->name, afptr->len) == 0 )
00491               return 0;
00492              afptr++;
00493            }
00494        }
00495 
00496       /* Next, exclude symbols from certain startup objects.  */
00497 
00498       if (abfd && (p = lbasename (abfd->filename)))
00499        {
00500          afptr = autofilter_objlist;
00501          while (afptr->name)
00502            {
00503              if (strcmp (p, afptr->name) == 0)
00504               return 0;
00505              afptr++;
00506            }
00507        }
00508 
00509       /* Don't try to blindly exclude all symbols
00510         that begin with '__'; this was tried and
00511         it is too restrictive.  Instead we have
00512         a target specific list to use:  */
00513       afptr = pe_details->autofilter_symbollist; 
00514 
00515       while (afptr->name)
00516        {
00517          if (strcmp (n, afptr->name) == 0)
00518            return 0;
00519 
00520          afptr++;
00521        }
00522 
00523       /* Next, exclude symbols starting with ...  */
00524       afptr = autofilter_symbolprefixlist;
00525       while (afptr->name)
00526        {
00527          if (strncmp (n, afptr->name, afptr->len) == 0)
00528            return 0;
00529 
00530          afptr++;
00531        }
00532 
00533       /* Finally, exclude symbols ending with ...  */
00534       len = strlen (n);
00535       afptr = autofilter_symbolsuffixlist;
00536       while (afptr->name)
00537        {
00538          if ((len >= afptr->len)
00539              /* Add 1 to insure match with trailing '\0'.  */
00540              && strncmp (n + len - afptr->len, afptr->name,
00541                        afptr->len + 1) == 0)
00542            return 0;
00543 
00544          afptr++;
00545        }
00546     }
00547 
00548   for (ex = excludes; ex; ex = ex->next)
00549     {
00550       if (ex->type == 1) /* exclude-libs */
00551        {
00552          if (libname
00553              && ((strcmp (libname, ex->string) == 0)
00554                  || (strcasecmp ("ALL", ex->string) == 0)))
00555            return 0;
00556        }
00557       else if (strcmp (n, ex->string) == 0)
00558        return 0;
00559     }
00560 
00561   return 1;
00562 }
00563 
00564 static void
00565 process_def_file (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
00566 {
00567   int i, j;
00568   struct bfd_link_hash_entry *blhe;
00569   bfd *b;
00570   struct bfd_section *s;
00571   def_file_export *e = 0;
00572 
00573   if (!pe_def_file)
00574     pe_def_file = def_file_empty ();
00575 
00576   /* First, run around to all the objects looking for the .drectve
00577      sections, and push those into the def file too.  */
00578   for (b = info->input_bfds; b; b = b->link_next)
00579     {
00580       s = bfd_get_section_by_name (b, ".drectve");
00581       if (s)
00582        {
00583          long size = s->size;
00584          char *buf = xmalloc (size);
00585 
00586          bfd_get_section_contents (b, s, buf, 0, size);
00587          def_file_add_directive (pe_def_file, buf, size);
00588          free (buf);
00589        }
00590     }
00591 
00592   /* If we are not building a DLL, when there are no exports
00593      we do not build an export table at all.  */
00594   if (!pe_dll_export_everything && pe_def_file->num_exports == 0
00595       && info->executable)
00596     return;
00597 
00598   /* Now, maybe export everything else the default way.  */
00599   if (pe_dll_export_everything || pe_def_file->num_exports == 0)
00600     {
00601       for (b = info->input_bfds; b; b = b->link_next)
00602        {
00603          asymbol **symbols;
00604          int nsyms, symsize;
00605 
00606          symsize = bfd_get_symtab_upper_bound (b);
00607          symbols = xmalloc (symsize);
00608          nsyms = bfd_canonicalize_symtab (b, symbols);
00609 
00610          for (j = 0; j < nsyms; j++)
00611            {
00612              /* We should export symbols which are either global or not
00613                anything at all.  (.bss data is the latter)
00614                We should not export undefined symbols.  */
00615              if (symbols[j]->section != &bfd_und_section
00616                 && ((symbols[j]->flags & BSF_GLOBAL)
00617                     || (symbols[j]->flags == BFD_FORT_COMM_DEFAULT_VALUE)))
00618               {
00619                 const char *sn = symbols[j]->name;
00620 
00621                 /* We should not re-export imported stuff.  */
00622                 {
00623                   char *name;
00624                   if (is_import (sn))
00625                        continue;
00626 
00627                   name = xmalloc (strlen ("__imp_") + strlen (sn) + 1);
00628                   sprintf (name, "%s%s", "__imp_", sn);
00629 
00630                   blhe = bfd_link_hash_lookup (info->hash, name,
00631                                            FALSE, FALSE, FALSE);
00632                   free (name);
00633 
00634                   if (blhe && blhe->type == bfd_link_hash_defined)
00635                     continue;
00636                 }
00637 
00638                 if (pe_details->underscored && *sn == '_')
00639                   sn++;
00640 
00641                 if (auto_export (b, pe_def_file, sn))
00642                   {
00643                     def_file_export *p;
00644                     p=def_file_add_export (pe_def_file, sn, 0, -1);
00645                     /* Fill data flag properly, from dlltool.c.  */
00646                     p->flag_data = !(symbols[j]->flags & BSF_FUNCTION);
00647                   }
00648               }
00649            }
00650        }
00651     }
00652 
00653 #undef NE
00654 #define NE pe_def_file->num_exports
00655 
00656   /* Canonicalize the export list.  */
00657   if (pe_dll_kill_ats)
00658     {
00659       for (i = 0; i < NE; i++)
00660        {
00661          if (strchr (pe_def_file->exports[i].name, '@'))
00662            {
00663              /* This will preserve internal_name, which may have been
00664                pointing to the same memory as name, or might not
00665                have.  */
00666              int lead_at = (*pe_def_file->exports[i].name == '@');
00667              char *tmp = xstrdup (pe_def_file->exports[i].name + lead_at);
00668              char *tmp_at = strchr (tmp, '@');
00669 
00670              if (tmp_at)
00671                *tmp_at = 0;
00672              else
00673                einfo (_("%XCannot export %s: invalid export name\n"),
00674                      pe_def_file->exports[i].name);
00675              pe_def_file->exports[i].name = tmp;
00676            }
00677        }
00678     }
00679 
00680   if (pe_dll_stdcall_aliases)
00681     {
00682       for (i = 0; i < NE; i++)
00683        {
00684          if (is_import (pe_def_file->exports[i].name))
00685            continue;
00686 
00687          if (strchr (pe_def_file->exports[i].name, '@'))
00688            {
00689              int lead_at = (*pe_def_file->exports[i].name == '@');
00690              char *tmp = xstrdup (pe_def_file->exports[i].name + lead_at);
00691 
00692              *(strchr (tmp, '@')) = 0;
00693              if (auto_export (NULL, pe_def_file, tmp))
00694               def_file_add_export (pe_def_file, tmp,
00695                                  pe_def_file->exports[i].internal_name,
00696                                  -1);
00697              else
00698               free (tmp);
00699            }
00700        }
00701     }
00702 
00703   /* Convenience, but watch out for it changing.  */
00704   e = pe_def_file->exports;
00705 
00706   exported_symbol_offsets = xmalloc (NE * sizeof (bfd_vma));
00707   exported_symbol_sections = xmalloc (NE * sizeof (struct bfd_section *));
00708 
00709   memset (exported_symbol_sections, 0, NE * sizeof (struct bfd_section *));
00710   max_ordinal = 0;
00711   min_ordinal = 65536;
00712   count_exported = 0;
00713   count_exported_byname = 0;
00714   count_with_ordinals = 0;
00715 
00716   qsort (pe_def_file->exports, NE, sizeof (pe_def_file->exports[0]),
00717         pe_export_sort);
00718   for (i = 0, j = 0; i < NE; i++)
00719     {
00720       if (i > 0 && strcmp (e[i].name, e[i - 1].name) == 0)
00721        {
00722          /* This is a duplicate.  */
00723          if (e[j - 1].ordinal != -1
00724              && e[i].ordinal != -1
00725              && e[j - 1].ordinal != e[i].ordinal)
00726            {
00727              if (pe_dll_warn_dup_exports)
00728               /* xgettext:c-format */
00729               einfo (_("%XError, duplicate EXPORT with ordinals: %s (%d vs %d)\n"),
00730                      e[j - 1].name, e[j - 1].ordinal, e[i].ordinal);
00731            }
00732          else
00733            {
00734              if (pe_dll_warn_dup_exports)
00735               /* xgettext:c-format */
00736               einfo (_("Warning, duplicate EXPORT: %s\n"),
00737                      e[j - 1].name);
00738            }
00739 
00740          if (e[i].ordinal != -1)
00741            e[j - 1].ordinal = e[i].ordinal;
00742          e[j - 1].flag_private |= e[i].flag_private;
00743          e[j - 1].flag_constant |= e[i].flag_constant;
00744          e[j - 1].flag_noname |= e[i].flag_noname;
00745          e[j - 1].flag_data |= e[i].flag_data;
00746        }
00747       else
00748        {
00749          if (i != j)
00750            e[j] = e[i];
00751          j++;
00752        }
00753     }
00754   pe_def_file->num_exports = j;    /* == NE */
00755 
00756   for (i = 0; i < NE; i++)
00757     {
00758       char *name;
00759 
00760       /* Check for forward exports */
00761       if (strchr (pe_def_file->exports[i].internal_name, '.'))
00762        {
00763          count_exported++;
00764          if (!pe_def_file->exports[i].flag_noname)
00765            count_exported_byname++;
00766 
00767          pe_def_file->exports[i].flag_forward = 1;
00768 
00769          if (pe_def_file->exports[i].ordinal != -1)
00770            {
00771              if (max_ordinal < pe_def_file->exports[i].ordinal)
00772               max_ordinal = pe_def_file->exports[i].ordinal;
00773              if (min_ordinal > pe_def_file->exports[i].ordinal)
00774               min_ordinal = pe_def_file->exports[i].ordinal;
00775              count_with_ordinals++;
00776            }
00777 
00778          continue;
00779        }
00780 
00781       name = xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2);
00782       if (pe_details->underscored
00783          && (*pe_def_file->exports[i].internal_name != '@'))
00784        {
00785          *name = '_';
00786          strcpy (name + 1, pe_def_file->exports[i].internal_name);
00787        }
00788       else
00789        strcpy (name, pe_def_file->exports[i].internal_name);
00790 
00791       blhe = bfd_link_hash_lookup (info->hash,
00792                                name,
00793                                FALSE, FALSE, TRUE);
00794 
00795       if (blhe
00796          && (blhe->type == bfd_link_hash_defined
00797              || (blhe->type == bfd_link_hash_common)))
00798        {
00799          count_exported++;
00800          if (!pe_def_file->exports[i].flag_noname)
00801            count_exported_byname++;
00802 
00803          /* Only fill in the sections. The actual offsets are computed
00804             in fill_exported_offsets() after common symbols are laid
00805             out.  */
00806          if (blhe->type == bfd_link_hash_defined)
00807            exported_symbol_sections[i] = blhe->u.def.section;
00808          else
00809            exported_symbol_sections[i] = blhe->u.c.p->section;
00810 
00811          if (pe_def_file->exports[i].ordinal != -1)
00812            {
00813              if (max_ordinal < pe_def_file->exports[i].ordinal)
00814               max_ordinal = pe_def_file->exports[i].ordinal;
00815              if (min_ordinal > pe_def_file->exports[i].ordinal)
00816               min_ordinal = pe_def_file->exports[i].ordinal;
00817              count_with_ordinals++;
00818            }
00819        }
00820       else if (blhe && blhe->type == bfd_link_hash_undefined)
00821        {
00822          /* xgettext:c-format */
00823          einfo (_("%XCannot export %s: symbol not defined\n"),
00824                pe_def_file->exports[i].internal_name);
00825        }
00826       else if (blhe)
00827        {
00828          /* xgettext:c-format */
00829          einfo (_("%XCannot export %s: symbol wrong type (%d vs %d)\n"),
00830                pe_def_file->exports[i].internal_name,
00831                blhe->type, bfd_link_hash_defined);
00832        }
00833       else
00834        {
00835          /* xgettext:c-format */
00836          einfo (_("%XCannot export %s: symbol not found\n"),
00837                pe_def_file->exports[i].internal_name);
00838        }
00839       free (name);
00840     }
00841 }
00842 
00843 /* Build the bfd that will contain .edata and .reloc sections.  */
00844 
00845 static void
00846 build_filler_bfd (int include_edata)
00847 {
00848   lang_input_statement_type *filler_file;
00849   filler_file = lang_add_input_file ("dll stuff",
00850                                  lang_input_file_is_fake_enum,
00851                                  NULL);
00852   filler_file->the_bfd = filler_bfd = bfd_create ("dll stuff", output_bfd);
00853   if (filler_bfd == NULL
00854       || !bfd_set_arch_mach (filler_bfd,
00855                           bfd_get_arch (output_bfd),
00856                           bfd_get_mach (output_bfd)))
00857     {
00858       einfo ("%X%P: can not create BFD: %E\n");
00859       return;
00860     }
00861 
00862   if (include_edata)
00863     {
00864       edata_s = bfd_make_section_old_way (filler_bfd, ".edata");
00865       if (edata_s == NULL
00866          || !bfd_set_section_flags (filler_bfd, edata_s,
00867                                  (SEC_HAS_CONTENTS
00868                                   | SEC_ALLOC
00869                                   | SEC_LOAD
00870                                   | SEC_KEEP
00871                                   | SEC_IN_MEMORY)))
00872        {
00873          einfo ("%X%P: can not create .edata section: %E\n");
00874          return;
00875        }
00876       bfd_set_section_size (filler_bfd, edata_s, edata_sz);
00877     }
00878 
00879   reloc_s = bfd_make_section_old_way (filler_bfd, ".reloc");
00880   if (reloc_s == NULL
00881       || !bfd_set_section_flags (filler_bfd, reloc_s,
00882                              (SEC_HAS_CONTENTS
00883                               | SEC_ALLOC
00884                               | SEC_LOAD
00885                               | SEC_KEEP
00886                               | SEC_IN_MEMORY)))
00887     {
00888       einfo ("%X%P: can not create .reloc section: %E\n");
00889       return;
00890     }
00891 
00892   bfd_set_section_size (filler_bfd, reloc_s, 0);
00893 
00894   ldlang_add_file (filler_file);
00895 }
00896 
00897 /* Gather all the exported symbols and build the .edata section.  */
00898 
00899 static void
00900 generate_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
00901 {
00902   int i, next_ordinal;
00903   int name_table_size = 0;
00904   const char *dlnp;
00905 
00906   /* First, we need to know how many exported symbols there are,
00907      and what the range of ordinals is.  */
00908   if (pe_def_file->name)
00909     dll_name = pe_def_file->name;
00910   else
00911     {
00912       dll_name = abfd->filename;
00913 
00914       for (dlnp = dll_name; *dlnp; dlnp++)
00915        if (*dlnp == '\\' || *dlnp == '/' || *dlnp == ':')
00916          dll_name = dlnp + 1;
00917     }
00918 
00919   if (count_with_ordinals && max_ordinal > count_exported)
00920     {
00921       if (min_ordinal > max_ordinal - count_exported + 1)
00922        min_ordinal = max_ordinal - count_exported + 1;
00923     }
00924   else
00925     {
00926       min_ordinal = 1;
00927       max_ordinal = count_exported;
00928     }
00929 
00930   export_table_size = max_ordinal - min_ordinal + 1;
00931   exported_symbols = xmalloc (export_table_size * sizeof (int));
00932   for (i = 0; i < export_table_size; i++)
00933     exported_symbols[i] = -1;
00934 
00935   /* Now we need to assign ordinals to those that don't have them.  */
00936   for (i = 0; i < NE; i++)
00937     {
00938       if (exported_symbol_sections[i] ||
00939           pe_def_file->exports[i].flag_forward)
00940        {
00941          if (pe_def_file->exports[i].ordinal != -1)
00942            {
00943              int ei = pe_def_file->exports[i].ordinal - min_ordinal;
00944              int pi = exported_symbols[ei];
00945 
00946              if (pi != -1)
00947               {
00948                 /* xgettext:c-format */
00949                 einfo (_("%XError, ordinal used twice: %d (%s vs %s)\n"),
00950                       pe_def_file->exports[i].ordinal,
00951                       pe_def_file->exports[i].name,
00952                       pe_def_file->exports[pi].name);
00953               }
00954              exported_symbols[ei] = i;
00955            }
00956          name_table_size += strlen (pe_def_file->exports[i].name) + 1;
00957        }
00958 
00959       /* Reserve space for the forward name. */
00960       if (pe_def_file->exports[i].flag_forward)
00961        {
00962          name_table_size += strlen (pe_def_file->exports[i].internal_name) + 1;
00963        }
00964     }
00965 
00966   next_ordinal = min_ordinal;
00967   for (i = 0; i < NE; i++)
00968     if ((exported_symbol_sections[i] ||
00969          pe_def_file->exports[i].flag_forward) &&
00970         pe_def_file->exports[i].ordinal == -1)
00971       {
00972        while (exported_symbols[next_ordinal - min_ordinal] != -1)
00973          next_ordinal++;
00974 
00975        exported_symbols[next_ordinal - min_ordinal] = i;
00976        pe_def_file->exports[i].ordinal = next_ordinal;
00977       }
00978 
00979   /* OK, now we can allocate some memory.  */
00980   edata_sz = (40                          /* directory */
00981              + 4 * export_table_size             /* addresses */
00982              + 4 * count_exported_byname  /* name ptrs */
00983              + 2 * count_exported_byname  /* ordinals */
00984              + name_table_size + strlen (dll_name) + 1);
00985 }
00986 
00987 /* Fill the exported symbol offsets. The preliminary work has already
00988    been done in process_def_file().  */
00989 
00990 static void
00991 fill_exported_offsets (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
00992 {
00993   int i;
00994   struct bfd_link_hash_entry *blhe;
00995 
00996   for (i = 0; i < pe_def_file->num_exports; i++)
00997     {
00998       char *name;
00999 
01000       name = xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2);
01001       if (pe_details->underscored
01002          && *pe_def_file->exports[i].internal_name != '@')
01003        {
01004          *name = '_';
01005          strcpy (name + 1, pe_def_file->exports[i].internal_name);
01006        }
01007       else
01008        strcpy (name, pe_def_file->exports[i].internal_name);
01009 
01010       blhe = bfd_link_hash_lookup (info->hash,
01011                                name,
01012                                FALSE, FALSE, TRUE);
01013 
01014       if (blhe && blhe->type == bfd_link_hash_defined)
01015        exported_symbol_offsets[i] = blhe->u.def.value;
01016 
01017       free (name);
01018     }
01019 }
01020 
01021 static void
01022 fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
01023 {
01024   int s, hint;
01025   unsigned char *edirectory;
01026   unsigned char *eaddresses;
01027   unsigned char *enameptrs;
01028   unsigned char *eordinals;
01029   char *enamestr;
01030   time_t now;
01031 
01032   time (&now);
01033 
01034   edata_d = xmalloc (edata_sz);
01035 
01036   /* Note use of array pointer math here.  */
01037   edirectory = edata_d;
01038   eaddresses = edata_d + 40;
01039   enameptrs = eaddresses + 4 * export_table_size;
01040   eordinals = enameptrs + 4 * count_exported_byname;
01041   enamestr = (char *) eordinals + 2 * count_exported_byname;
01042 
01043 #define ERVA(ptr) (((unsigned char *)(ptr) - edata_d) \
01044                  + edata_s->output_section->vma - image_base)
01045 
01046   memset (edata_d, 0, edata_sz);
01047   bfd_put_32 (abfd, now, edata_d + 4);
01048   if (pe_def_file->version_major != -1)
01049     {
01050       bfd_put_16 (abfd, pe_def_file->version_major, edata_d + 8);
01051       bfd_put_16 (abfd, pe_def_file->version_minor, edata_d + 10);
01052     }
01053 
01054   bfd_put_32 (abfd, ERVA (enamestr), edata_d + 12);
01055   strcpy (enamestr, dll_name);
01056   enamestr += strlen (enamestr) + 1;
01057   bfd_put_32 (abfd, min_ordinal, edata_d + 16);
01058   bfd_put_32 (abfd, export_table_size, edata_d + 20);
01059   bfd_put_32 (abfd, count_exported_byname, edata_d + 24);
01060   bfd_put_32 (abfd, ERVA (eaddresses), edata_d + 28);
01061   bfd_put_32 (abfd, ERVA (enameptrs), edata_d + 32);
01062   bfd_put_32 (abfd, ERVA (eordinals), edata_d + 36);
01063 
01064   fill_exported_offsets (abfd, info);
01065 
01066   /* Ok, now for the filling in part.
01067      Scan alphabetically - ie the ordering in the exports[] table,
01068      rather than by ordinal - the ordering in the exported_symbol[]
01069      table.  See dlltool.c and:
01070         http://sources.redhat.com/ml/binutils/2003-04/msg00379.html
01071      for more information.  */
01072   hint = 0;
01073   for (s = 0; s < NE; s++)
01074     {
01075       struct bfd_section *ssec = exported_symbol_sections[s];
01076       if (pe_def_file->exports[s].ordinal != -1 &&
01077           (pe_def_file->exports[s].flag_forward || ssec != NULL))
01078        {
01079          int ord = pe_def_file->exports[s].ordinal;
01080 
01081          if (pe_def_file->exports[s].flag_forward)
01082            {
01083              bfd_put_32 (abfd, ERVA (enamestr),
01084                         eaddresses + 4 * (ord - min_ordinal));
01085 
01086              strcpy (enamestr, pe_def_file->exports[s].internal_name);
01087              enamestr += strlen (pe_def_file->exports[s].internal_name) + 1;
01088            }
01089          else
01090            {
01091              unsigned long srva = (exported_symbol_offsets[s]
01092                                 + ssec->output_section->vma
01093                                 + ssec->output_offset);
01094 
01095              bfd_put_32 (abfd, srva - image_base,
01096                         eaddresses + 4 * (ord - min_ordinal));
01097            }
01098 
01099          if (!pe_def_file->exports[s].flag_noname)
01100            {
01101              char *ename = pe_def_file->exports[s].name;
01102 
01103              bfd_put_32 (abfd, ERVA (enamestr), enameptrs);
01104              enameptrs += 4;
01105              strcpy (enamestr, ename);
01106              enamestr += strlen (enamestr) + 1;
01107              bfd_put_16 (abfd, ord - min_ordinal, eordinals);
01108              eordinals += 2;
01109              pe_def_file->exports[s].hint = hint++;
01110            }
01111        }
01112     }
01113 }
01114 
01115 
01116 static struct bfd_section *current_sec;
01117 
01118 void
01119 pe_walk_relocs_of_symbol (struct bfd_link_info *info,
01120                        const char *name,
01121                        int (*cb) (arelent *, asection *))
01122 {
01123   bfd *b;
01124   asection *s;
01125 
01126   for (b = info->input_bfds; b; b = b->link_next)
01127     {
01128       asymbol **symbols;
01129       int nsyms, symsize;
01130 
01131       symsize = bfd_get_symtab_upper_bound (b);
01132       symbols = xmalloc (symsize);
01133       nsyms   = bfd_canonicalize_symtab (b, symbols);
01134 
01135       for (s = b->sections; s; s = s->next)
01136        {
01137          arelent **relocs;
01138          int relsize, nrelocs, i;
01139          int flags = bfd_get_section_flags (b, s);
01140 
01141          /* Skip discarded linkonce sections.  */
01142          if (flags & SEC_LINK_ONCE
01143              && s->output_section == bfd_abs_section_ptr)
01144            continue;
01145 
01146          current_sec = s;
01147 
01148          relsize = bfd_get_reloc_upper_bound (b, s);
01149          relocs = xmalloc (relsize);
01150          nrelocs = bfd_canonicalize_reloc (b, s, relocs, symbols);
01151 
01152          for (i = 0; i < nrelocs; i++)
01153            {
01154              struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
01155 
01156              if (!strcmp (name, sym->name))
01157               cb (relocs[i], s);
01158            }
01159 
01160          free (relocs);
01161 
01162          /* Warning: the allocated symbols are remembered in BFD and reused
01163             later, so don't free them! */
01164          /* free (symbols); */
01165        }
01166     }
01167 }
01168 
01169 /* Gather all the relocations and build the .reloc section.  */
01170 
01171 static void
01172 generate_reloc (bfd *abfd, struct bfd_link_info *info)
01173 {
01174 
01175   /* For .reloc stuff.  */
01176   reloc_data_type *reloc_data;
01177   int total_relocs = 0;
01178   int i;
01179   unsigned long sec_page = (unsigned long) -1;
01180   unsigned long page_ptr, page_count;
01181   int bi;
01182   bfd *b;
01183   struct bfd_section *s;
01184 
01185   total_relocs = 0;
01186   for (b = info->input_bfds; b; b = b->link_next)
01187     for (s = b->sections; s; s = s->next)
01188       total_relocs += s->reloc_count;
01189 
01190   reloc_data = xmalloc (total_relocs * sizeof (reloc_data_type));
01191 
01192   total_relocs = 0;
01193   bi = 0;
01194   for (bi = 0, b = info->input_bfds; b; bi++, b = b->link_next)
01195     {
01196       arelent **relocs;
01197       int relsize, nrelocs, i;
01198 
01199       for (s = b->sections; s; s = s->next)
01200        {
01201          unsigned long sec_vma = s->output_section->vma + s->output_offset;
01202          asymbol **symbols;
01203          int nsyms, symsize;
01204 
01205          /* If it's not loaded, we don't need to relocate it this way.  */
01206          if (!(s->output_section->flags & SEC_LOAD))
01207            continue;
01208 
01209          /* I don't know why there would be a reloc for these, but I've
01210             seen it happen - DJ  */
01211          if (s->output_section == &bfd_abs_section)
01212            continue;
01213 
01214          if (s->output_section->vma == 0)
01215            {
01216              /* Huh?  Shouldn't happen, but punt if it does.  */
01217              einfo ("DJ: zero vma section reloc detected: `%s' #%d f=%d\n",
01218                    s->output_section->name, s->output_section->index,
01219                    s->output_section->flags);
01220              continue;
01221            }
01222 
01223          symsize = bfd_get_symtab_upper_bound (b);
01224          symbols = xmalloc (symsize);
01225          nsyms = bfd_canonicalize_symtab (b, symbols);
01226 
01227          relsize = bfd_get_reloc_upper_bound (b, s);
01228          relocs = xmalloc (relsize);
01229          nrelocs = bfd_canonicalize_reloc (b, s, relocs, symbols);
01230 
01231          for (i = 0; i < nrelocs; i++)
01232            {
01233              if (pe_dll_extra_pe_debug)
01234               {
01235                 struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
01236                 printf ("rel: %s\n", sym->name);
01237               }
01238              if (!relocs[i]->howto->pc_relative
01239                 && relocs[i]->howto->type != pe_details->imagebase_reloc)
01240               {
01241                 bfd_vma sym_vma;
01242                 struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
01243 
01244                 sym_vma = (relocs[i]->addend
01245                           + sym->value
01246                           + sym->section->vma
01247                           + sym->section->output_offset
01248                           + sym->section->output_section->vma);
01249                 reloc_data[total_relocs].vma = sec_vma + relocs[i]->address;
01250 
01251 #define BITS_AND_SHIFT(bits, shift) (bits * 1000 | shift)
01252 
01253                 switch BITS_AND_SHIFT (relocs[i]->howto->bitsize,
01254                                     relocs[i]->howto->rightshift)
01255                   {
01256 #ifdef pe_use_x86_64
01257                   case BITS_AND_SHIFT (64, 0):
01258                     reloc_data[total_relocs].type = 10;
01259                     total_relocs++;
01260                     break;
01261 #endif
01262                   case BITS_AND_SHIFT (32, 0):
01263                     reloc_data[total_relocs].type = 3;
01264                     total_relocs++;
01265                     break;
01266                   case BITS_AND_SHIFT (16, 0):
01267                     reloc_data[total_relocs].type = 2;
01268                     total_relocs++;
01269                     break;
01270                   case BITS_AND_SHIFT (16, 16):
01271                     reloc_data[total_relocs].type = 4;
01272                     /* FIXME: we can't know the symbol's right value
01273                       yet, but we probably can safely assume that
01274                       CE will relocate us in 64k blocks, so leaving
01275                       it zero is safe.  */
01276                     reloc_data[total_relocs].extra = 0;
01277                     total_relocs++;
01278                     break;
01279                   case BITS_AND_SHIFT (26, 2):
01280                     reloc_data[total_relocs].type = 5;
01281                     total_relocs++;
01282                     break;
01283                   case BITS_AND_SHIFT (24, 2):
01284                     /* FIXME: 0 is ARM_26D, it is defined in bfd/coff-arm.c
01285                       Those ARM_xxx definitions should go in proper
01286                       header someday.  */
01287                     if (relocs[i]->howto->type == 0
01288                        /* Older GNU linkers used 5 instead of 0 for this reloc.  */
01289                        || relocs[i]->howto->type == 5)
01290                      /* This is an ARM_26D reloc, which is an ARM_26 reloc
01291                         that has already been fully processed during a
01292                         previous link stage, so ignore it here.  */
01293                      break;
01294                     /* Fall through.  */
01295                   default:
01296                     /* xgettext:c-format */
01297                     einfo (_("%XError: %d-bit reloc in dll\n"),
01298                           relocs[i]->howto->bitsize);
01299                     break;
01300                   }
01301               }
01302            }
01303          free (relocs);
01304          /* Warning: the allocated symbols are remembered in BFD and
01305             reused later, so don't free them!  */
01306        }
01307     }
01308 
01309   /* At this point, we have total_relocs relocation addresses in
01310      reloc_addresses, which are all suitable for the .reloc section.
01311      We must now create the new sections.  */
01312   qsort (reloc_data, total_relocs, sizeof (*reloc_data), reloc_sort);
01313 
01314   for (i = 0; i < total_relocs; i++)
01315     {
01316       unsigned long this_page = (reloc_data[i].vma >> 12);
01317 
01318       if (this_page != sec_page)
01319        {
01320          reloc_sz = (reloc_sz + 3) & ~3;  /* 4-byte align.  */
01321          reloc_sz += 8;
01322          sec_page = this_page;
01323        }
01324 
01325       reloc_sz += 2;
01326 
01327       if (reloc_data[i].type == 4)
01328        reloc_sz += 2;
01329     }
01330 
01331   reloc_sz = (reloc_sz + 3) & ~3;  /* 4-byte align.  */
01332   reloc_d = xmalloc (reloc_sz);
01333   sec_page = (unsigned long) -1;
01334   reloc_sz = 0;
01335   page_ptr = (unsigned long) -1;
01336   page_count = 0;
01337 
01338   for (i = 0; i < total_relocs; i++)
01339     {
01340       unsigned long rva = reloc_data[i].vma - image_base;
01341       unsigned long this_page = (rva & ~0xfff);
01342 
01343       if (this_page != sec_page)
01344        {
01345          while (reloc_sz & 3)
01346            reloc_d[reloc_sz++] = 0;
01347 
01348          if (page_ptr != (unsigned long) -1)
01349            bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4);
01350 
01351          bfd_put_32 (abfd, this_page, reloc_d + reloc_sz);
01352          page_ptr = reloc_sz;
01353          reloc_sz += 8;
01354          sec_page = this_page;
01355          page_count = 0;
01356        }
01357 
01358       bfd_put_16 (abfd, (rva & 0xfff) + (reloc_data[i].type << 12),
01359                 reloc_d + reloc_sz);
01360       reloc_sz += 2;
01361 
01362       if (reloc_data[i].type == 4)
01363        {
01364          bfd_put_16 (abfd, reloc_data[i].extra, reloc_d + reloc_sz);
01365          reloc_sz += 2;
01366        }
01367 
01368       page_count++;
01369     }
01370 
01371   while (reloc_sz & 3)
01372     reloc_d[reloc_sz++] = 0;
01373 
01374   if (page_ptr != (unsigned long) -1)
01375     bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4);
01376 
01377   while (reloc_sz < reloc_s->size)
01378     reloc_d[reloc_sz++] = 0;
01379 }
01380 
01381 /* Given the exiting def_file structure, print out a .DEF file that
01382    corresponds to it.  */
01383 
01384 static void
01385 quoteput (char *s, FILE *f, int needs_quotes)
01386 {
01387   char *cp;
01388 
01389   for (cp = s; *cp; cp++)
01390     if (*cp == '\''
01391        || *cp == '"'
01392        || *cp == '\\'
01393        || ISSPACE (*cp)
01394        || *cp == ','
01395        || *cp == ';')
01396       needs_quotes = 1;
01397 
01398   if (needs_quotes)
01399     {
01400       putc ('"', f);
01401 
01402       while (*s)
01403        {
01404          if (*s == '"' || *s == '\\')
01405            putc ('\\', f);
01406 
01407          putc (*s, f);
01408          s++;
01409        }
01410 
01411       putc ('"', f);
01412     }
01413   else
01414     fputs (s, f);
01415 }
01416 
01417 void
01418 pe_dll_generate_def_file (const char *pe_out_def_filename)
01419 {
01420   int i;
01421   FILE *out = fopen (pe_out_def_filename, "w");
01422 
01423   if (out == NULL)
01424     /* xgettext:c-format */
01425     einfo (_("%s: Can't open output def file %s\n"),
01426           program_name, pe_out_def_filename);
01427 
01428   if (pe_def_file)
01429     {
01430       if (pe_def_file->name)
01431        {
01432          if (pe_def_file->is_dll)
01433            fprintf (out, "LIBRARY ");
01434          else
01435            fprintf (out, "NAME ");
01436 
01437          quoteput (pe_def_file->name, out, 1);
01438 
01439          if (pe_data (output_bfd)->pe_opthdr.ImageBase)
01440            fprintf (out, " BASE=0x%lx",
01441                    (unsigned long) pe_data (output_bfd)->pe_opthdr.ImageBase);
01442          fprintf (out, "\n");
01443        }
01444 
01445       if (pe_def_file->description)
01446        {
01447          fprintf (out, "DESCRIPTION ");
01448          quoteput (pe_def_file->description, out, 1);
01449          fprintf (out, "\n");
01450        }
01451 
01452       if (pe_def_file->version_minor != -1)
01453        fprintf (out, "VERSION %d.%d\n", pe_def_file->version_major,
01454                pe_def_file->version_minor);
01455       else if (pe_def_file->version_major != -1)
01456        fprintf (out, "VERSION %d\n", pe_def_file->version_major);
01457 
01458       if (pe_def_file->stack_reserve != -1 || pe_def_file->heap_reserve != -1)
01459        fprintf (out, "\n");
01460 
01461       if (pe_def_file->stack_commit != -1)
01462        fprintf (out, "STACKSIZE 0x%x,0x%x\n",
01463                pe_def_file->stack_reserve, pe_def_file->stack_commit);
01464       else if (pe_def_file->stack_reserve != -1)
01465        fprintf (out, "STACKSIZE 0x%x\n", pe_def_file->stack_reserve);
01466 
01467       if (pe_def_file->heap_commit != -1)
01468        fprintf (out, "HEAPSIZE 0x%x,0x%x\n",
01469                pe_def_file->heap_reserve, pe_def_file->heap_commit);
01470       else if (pe_def_file->heap_reserve != -1)
01471        fprintf (out, "HEAPSIZE 0x%x\n", pe_def_file->heap_reserve);
01472 
01473       if (pe_def_file->num_section_defs > 0)
01474        {
01475          fprintf (out, "\nSECTIONS\n\n");
01476 
01477          for (i = 0; i < pe_def_file->num_section_defs; i++)
01478            {
01479              fprintf (out, "    ");
01480              quoteput (pe_def_file->section_defs[i].name, out, 0);
01481 
01482              if (pe_def_file->section_defs[i].class)
01483               {
01484                 fprintf (out, " CLASS ");
01485                 quoteput (pe_def_file->section_defs[i].class, out, 0);
01486               }
01487 
01488              if (pe_def_file->section_defs[i].flag_read)
01489               fprintf (out, " READ");
01490 
01491              if (pe_def_file->section_defs[i].flag_write)
01492               fprintf (out, " WRITE");
01493 
01494              if (pe_def_file->section_defs[i].flag_execute)
01495               fprintf (out, " EXECUTE");
01496 
01497              if (pe_def_file->section_defs[i].flag_shared)
01498               fprintf (out, " SHARED");
01499 
01500              fprintf (out, "\n");
01501            }
01502        }
01503 
01504       if (pe_def_file->num_exports > 0)
01505        {
01506          fprintf (out, "EXPORTS\n");
01507 
01508          for (i = 0; i < pe_def_file->num_exports; i++)
01509            {
01510              def_file_export *e = pe_def_file->exports + i;
01511              fprintf (out, "    ");
01512              quoteput (e->name, out, 0);
01513 
01514              if (e->internal_name && strcmp (e->internal_name, e->name))
01515               {
01516                 fprintf (out, " = ");
01517                 quoteput (e->internal_name, out, 0);
01518               }
01519 
01520              if (e->ordinal != -1)
01521               fprintf (out, " @%d", e->ordinal);
01522 
01523              if (e->flag_private)
01524               fprintf (out, " PRIVATE");
01525 
01526              if (e->flag_constant)
01527               fprintf (out, " CONSTANT");
01528 
01529              if (e->flag_noname)
01530               fprintf (out, " NONAME");
01531 
01532              if (e->flag_data)
01533               fprintf (out, " DATA");
01534 
01535              fprintf (out, "\n");
01536            }
01537        }
01538 
01539       if (pe_def_file->num_imports > 0)
01540        {
01541          fprintf (out, "\nIMPORTS\n\n");
01542 
01543          for (i = 0; i < pe_def_file->num_imports; i++)
01544            {
01545              def_file_import *im = pe_def_file->imports + i;
01546              fprintf (out, "    ");
01547 
01548              if (im->internal_name
01549                 && (!im->name || strcmp (im->internal_name, im->name)))
01550               {
01551                 quoteput (im->internal_name, out, 0);
01552                 fprintf (out, " = ");
01553               }
01554 
01555              quoteput (im->module->name, out, 0);
01556              fprintf (out, ".");
01557 
01558              if (im->name)
01559               quoteput (im->name, out, 0);
01560              else
01561               fprintf (out, "%d", im->ordinal);
01562 
01563              fprintf (out, "\n");
01564            }
01565        }
01566     }
01567   else
01568     fprintf (out, _("; no contents available\n"));
01569 
01570   if (fclose (out) == EOF)
01571     /* xgettext:c-format */
01572     einfo (_("%P: Error closing file `%s'\n"), pe_out_def_filename);
01573 }
01574 
01575 /* Generate the import library.  */
01576 
01577 static asymbol **symtab;
01578 static int symptr;
01579 static int tmp_seq;
01580 static const char *dll_filename;
01581 static char *dll_symname;
01582 
01583 #define UNDSEC (asection *) &bfd_und_section
01584 
01585 static asection *
01586 quick_section (bfd *abfd, const char *name, int flags, int align)
01587 {
01588   asection *sec;
01589   asymbol *sym;
01590 
01591   sec = bfd_make_section_old_way (abfd, name);
01592   bfd_set_section_flags (abfd, sec, flags | SEC_ALLOC | SEC_LOAD | SEC_KEEP);
01593   bfd_set_section_alignment (abfd, sec, align);
01594   /* Remember to undo this before trying to link internally!  */
01595   sec->output_section = sec;
01596 
01597   sym = bfd_make_empty_symbol (abfd);
01598   symtab[symptr++] = sym;
01599   sym->name = sec->name;
01600   sym->section = sec;
01601   sym->flags = BSF_LOCAL;
01602   sym->value = 0;
01603 
01604   return sec;
01605 }
01606 
01607 static void
01608 quick_symbol (bfd *abfd,
01609              const char *n1,
01610              const char *n2,
01611              const char *n3,
01612              asection *sec,
01613              int flags,
01614              int addr)
01615 {
01616   asymbol *sym;
01617   char *name = xmalloc (strlen (n1) + strlen (n2) + strlen (n3) + 1);
01618 
01619   strcpy (name, n1);
01620   strcat (name, n2);
01621   strcat (name, n3);
01622   sym = bfd_make_empty_symbol (abfd);
01623   sym->name = name;
01624   sym->section = sec;
01625   sym->flags = flags;
01626   sym->value = addr;
01627   symtab[symptr++] = sym;
01628 }
01629 
01630 static arelent *reltab = 0;
01631 static int relcount = 0, relsize = 0;
01632 
01633 static void
01634 quick_reloc (bfd *abfd, int address, int which_howto, int symidx)
01635 {
01636   if (relcount >= relsize - 1)
01637     {
01638       relsize += 10;
01639       if (reltab)
01640        reltab = xrealloc (reltab, relsize * sizeof (arelent));
01641       else
01642        reltab = xmalloc (relsize * sizeof (arelent));
01643     }
01644   reltab[relcount].address = address;
01645   reltab[relcount].addend = 0;
01646   reltab[relcount].howto = bfd_reloc_type_lookup (abfd, which_howto);
01647   reltab[relcount].sym_ptr_ptr = symtab + symidx;
01648   relcount++;
01649 }
01650 
01651 static void
01652 save_relocs (asection *sec)
01653 {
01654   int i;
01655 
01656   sec->relocation = reltab;
01657   sec->reloc_count = relcount;
01658   sec->orelocation = xmalloc ((relcount + 1) * sizeof (arelent *));
01659   for (i = 0; i < relcount; i++)
01660     sec->orelocation[i] = sec->relocation + i;
01661   sec->orelocation[relcount] = 0;
01662   sec->flags |= SEC_RELOC;
01663   reltab = 0;
01664   relcount = relsize = 0;
01665 }
01666 
01667 /*     .section      .idata$2
01668        .global              __head_my_dll
01669    __head_my_dll:
01670        .rva          hname
01671        .long         0
01672        .long         0
01673        .rva          __my_dll_iname
01674        .rva          fthunk
01675 
01676        .section      .idata$5
01677        .long         0
01678    fthunk:
01679 
01680        .section      .idata$4
01681        .long         0
01682    hname:                              */
01683 
01684 static bfd *
01685 make_head (bfd *parent)
01686 {
01687   asection *id2, *id5, *id4;
01688   unsigned char *d2, *d5, *d4;
01689   char *oname;
01690   bfd *abfd;
01691 
01692   oname = xmalloc (20);
01693   sprintf (oname, "d%06d.o", tmp_seq);
01694   tmp_seq++;
01695 
01696   abfd = bfd_create (oname, parent);
01697   bfd_find_target (pe_details->object_target, abfd);
01698   bfd_make_writable (abfd);
01699 
01700   bfd_set_format (abfd, bfd_object);
01701   bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
01702 
01703   symptr = 0;
01704   symtab = xmalloc (6 * sizeof (asymbol *));
01705   id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2);
01706   id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
01707   id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
01708   quick_symbol (abfd, U ("_head_"), dll_symname, "", id2, BSF_GLOBAL, 0);
01709   quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
01710 
01711   /* OK, pay attention here.  I got confused myself looking back at
01712      it.  We create a four-byte section to mark the beginning of the
01713      list, and we include an offset of 4 in the section, so that the
01714      pointer to the list points to the *end* of this section, which is
01715      the start of the list of sections from other objects.  */
01716 
01717   bfd_set_section_size (abfd, id2, 20);
01718   d2 = xmalloc (20);
01719   id2->contents = d2;
01720   memset (d2, 0, 20);
01721   d2[0] = d2[16] = 4; /* Reloc addend.  */
01722   quick_reloc (abfd,  0, BFD_RELOC_RVA, 2);
01723   quick_reloc (abfd, 12, BFD_RELOC_RVA, 4);
01724   quick_reloc (abfd, 16, BFD_RELOC_RVA, 1);
01725   save_relocs (id2);
01726 
01727   bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE);
01728   d5 = xmalloc (PE_IDATA5_SIZE);
01729   id5->contents = d5;
01730   memset (d5, 0, PE_IDATA5_SIZE);
01731 
01732   bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
01733   d4 = xmalloc (PE_IDATA4_SIZE);
01734   id4->contents = d4;
01735   memset (d4, 0, PE_IDATA4_SIZE);
01736 
01737   bfd_set_symtab (abfd, symtab, symptr);
01738 
01739   bfd_set_section_contents (abfd, id2, d2, 0, 20);
01740   bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE);
01741   bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
01742 
01743   bfd_make_readable (abfd);
01744   return abfd;
01745 }
01746 
01747 /*     .section      .idata$4
01748        .long         0
01749        [.long        0] for PE+
01750        .section      .idata$5
01751        .long         0
01752        [.long        0] for PE+
01753        .section      idata$7
01754        .global              __my_dll_iname
01755   __my_dll_iname:
01756        .asciz        "my.dll"       */
01757 
01758 static bfd *
01759 make_tail (bfd *parent)
01760 {
01761   asection *id4, *id5, *id7;
01762   unsigned char *d4, *d5, *d7;
01763   int len;
01764   char *oname;
01765   bfd *abfd;
01766 
01767   oname = xmalloc (20);
01768   sprintf (oname, "d%06d.o", tmp_seq);
01769   tmp_seq++;
01770 
01771   abfd = bfd_create (oname, parent);
01772   bfd_find_target (pe_details->object_target, abfd);
01773   bfd_make_writable (abfd);
01774 
01775   bfd_set_format (abfd, bfd_object);
01776   bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
01777 
01778   symptr = 0;
01779   symtab = xmalloc (5 * sizeof (asymbol *));
01780   id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
01781   id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
01782   id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
01783   quick_symbol (abfd, U (""), dll_symname, "_iname", id7, BSF_GLOBAL, 0);
01784 
01785   bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
01786   d4 = xmalloc (PE_IDATA4_SIZE);
01787   id4->contents = d4;
01788   memset (d4, 0, PE_IDATA4_SIZE);
01789 
01790   bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE);
01791   d5 = xmalloc (PE_IDATA5_SIZE);
01792   id5->contents = d5;
01793   memset (d5, 0, PE_IDATA5_SIZE);
01794 
01795   len = strlen (dll_filename) + 1;
01796   if (len & 1)
01797     len++;
01798   bfd_set_section_size (abfd, id7, len);
01799   d7 = xmalloc (len);
01800   id7->contents = d7;
01801   strcpy ((char *) d7, dll_filename);
01802   /* If len was odd, the above
01803      strcpy leaves behind an undefined byte. That is harmless,
01804      but we set it to 0 just so the binary dumps are pretty.  */
01805   d7[len - 1] = 0;
01806 
01807   bfd_set_symtab (abfd, symtab, symptr);
01808 
01809   bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
01810   bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE);
01811   bfd_set_section_contents (abfd, id7, d7, 0, len);
01812 
01813   bfd_make_readable (abfd);
01814   return abfd;
01815 }
01816 
01817 /*     .text
01818        .global              _function
01819        .global              ___imp_function
01820        .global              __imp__function
01821   _function:
01822        jmp           *__imp__function:
01823 
01824        .section      idata$7
01825        .long         __head_my_dll
01826 
01827        .section      .idata$5
01828   ___imp_function:
01829   __imp__function:
01830   iat?
01831        .section      .idata$4
01832   iat?
01833        .section      .idata$6
01834   ID<ordinal>:
01835        .short        <hint>
01836        .asciz        "function" xlate? (add underscore, kill at)  */
01837 
01838 static const unsigned char jmp_ix86_bytes[] =
01839 {
01840   0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
01841 };
01842 
01843 /* _function:
01844        mov.l  ip+8,r0
01845        mov.l  @r0,r0
01846        jmp    @r0
01847        nop
01848        .dw    __imp_function   */
01849 
01850 static const unsigned char jmp_sh_bytes[] =
01851 {
01852   0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00
01853 };
01854 
01855 /* _function:
01856        lui    $t0,<high:__imp_function>
01857        lw     $t0,<low:__imp_function>
01858        jr     $t0
01859        nop                              */
01860 
01861 static const unsigned char jmp_mips_bytes[] =
01862 {
01863   0x00, 0x00, 0x08, 0x3c,  0x00, 0x00, 0x08, 0x8d,
01864   0x08, 0x00, 0x00, 0x01,  0x00, 0x00, 0x00, 0x00
01865 };
01866 
01867 static const unsigned char jmp_arm_bytes[] =
01868 {
01869   0x00, 0xc0, 0x9f, 0xe5,   /* ldr  ip, [pc] */
01870   0x00, 0xf0, 0x9c, 0xe5,   /* ldr  pc, [ip] */
01871   0,    0,    0,    0
01872 };
01873 
01874 
01875 static bfd *
01876 make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub)
01877 {
01878   asection *tx, *id7, *id5, *id4, *id6;
01879   unsigned char *td = NULL, *d7, *d5, *d4, *d6 = NULL;
01880   int len;
01881   char *oname;
01882   bfd *abfd;
01883   const unsigned char *jmp_bytes = NULL;
01884   int jmp_byte_count = 0;
01885 
01886   /* Include the jump stub section only if it is needed. A jump
01887      stub is needed if the symbol being imported <sym> is a function
01888      symbol and there is at least one undefined reference to that
01889      symbol. In other words, if all the import references to <sym> are
01890      explicitly through _declspec(dllimport) then the jump stub is not
01891      needed.  */
01892   if (include_jmp_stub)
01893     {
01894       switch (pe_details->pe_arch)
01895        {
01896        case PE_ARCH_i386:
01897          jmp_bytes = jmp_ix86_bytes;
01898          jmp_byte_count = sizeof (jmp_ix86_bytes);
01899          break;
01900        case PE_ARCH_sh:
01901          jmp_bytes = jmp_sh_bytes;
01902          jmp_byte_count = sizeof (jmp_sh_bytes);
01903          break;
01904        case PE_ARCH_mips:
01905          jmp_bytes = jmp_mips_bytes;
01906          jmp_byte_count = sizeof (jmp_mips_bytes);
01907          break;
01908        case PE_ARCH_arm:
01909        case PE_ARCH_arm_epoc:
01910        case PE_ARCH_arm_wince:
01911          jmp_bytes = jmp_arm_bytes;
01912          jmp_byte_count = sizeof (jmp_arm_bytes);
01913          break;
01914        default:
01915          abort ();
01916        }
01917     }
01918 
01919   oname = xmalloc (20);
01920   sprintf (oname, "d%06d.o", tmp_seq);
01921   tmp_seq++;
01922 
01923   abfd = bfd_create (oname, parent);
01924   bfd_find_target (pe_details->object_target, abfd);
01925   bfd_make_writable (abfd);
01926 
01927   bfd_set_format (abfd, bfd_object);
01928   bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
01929 
01930   symptr = 0;
01931   symtab = xmalloc (11 * sizeof (asymbol *));
01932   tx  = quick_section (abfd, ".text",    SEC_CODE|SEC_HAS_CONTENTS, 2);
01933   id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
01934   id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
01935   id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
01936   id6 = quick_section (abfd, ".idata$6", SEC_HAS_CONTENTS, 2);
01937 
01938   if  (*exp->internal_name == '@')
01939     {
01940       quick_symbol (abfd, U ("_head_"), dll_symname, "", UNDSEC,
01941                   BSF_GLOBAL, 0);
01942       if (include_jmp_stub)
01943        quick_symbol (abfd, "", exp->internal_name, "", tx, BSF_GLOBAL, 0);
01944       quick_symbol (abfd, "__imp_", exp->internal_name, "", id5,
01945                   BSF_GLOBAL, 0);
01946       /* Fastcall applies only to functions,
01947         so no need for auto-import symbol.  */
01948     }
01949   else
01950     {
01951       quick_symbol (abfd, U ("_head_"), dll_symname, "", UNDSEC,
01952                   BSF_GLOBAL, 0);
01953       if (include_jmp_stub)
01954        quick_symbol (abfd, U (""), exp->internal_name, "", tx,
01955                     BSF_GLOBAL, 0);
01956       quick_symbol (abfd, "__imp_", U (""), exp->internal_name, id5,
01957                   BSF_GLOBAL, 0);
01958       /* Symbol to reference ord/name of imported
01959         data symbol, used to implement auto-import.  */
01960       if (exp->flag_data)
01961        quick_symbol (abfd, U ("_nm_"), U (""), exp->internal_name, id6,
01962                     BSF_GLOBAL,0);
01963     }
01964   if (pe_dll_compat_implib)
01965     quick_symbol (abfd, U ("__imp_"), exp->internal_name, "", id5,
01966                 BSF_GLOBAL, 0);
01967 
01968   if (include_jmp_stub)
01969     {
01970       bfd_set_section_size (abfd, tx, jmp_byte_count);
01971       td = xmalloc (jmp_byte_count);
01972       tx->contents = td;
01973       memcpy (td, jmp_bytes, jmp_byte_count);
01974 
01975       switch (pe_details->pe_arch)
01976        {
01977        case PE_ARCH_i386:
01978 #ifdef pe_use_x86_64
01979          quick_reloc (abfd, 2, BFD_RELOC_32_PCREL, 2);
01980 #else
01981           quick_reloc (abfd, 2, BFD_RELOC_32, 2);
01982 #endif
01983          break;
01984        case PE_ARCH_sh:
01985          quick_reloc (abfd, 8, BFD_RELOC_32, 2);
01986          break;
01987        case PE_ARCH_mips:
01988          quick_reloc (abfd, 0, BFD_RELOC_HI16_S, 2);
01989          quick_reloc (abfd, 0, BFD_RELOC_LO16, 0); /* MIPS_R_PAIR */
01990          quick_reloc (abfd, 4, BFD_RELOC_LO16, 2);
01991          break;
01992        case PE_ARCH_arm:
01993        case PE_ARCH_arm_epoc:
01994        case PE_ARCH_arm_wince:
01995          quick_reloc (abfd, 8, BFD_RELOC_32, 2);
01996          break;
01997        default:
01998          abort ();
01999        }
02000       save_relocs (tx);
02001     }
02002   else
02003     bfd_set_section_size (abfd, tx, 0);
02004 
02005   bfd_set_section_size (abfd, id7, 4);
02006   d7 = xmalloc (4);
02007   id7->contents = d7;
02008   memset (d7, 0, 4);
02009   quick_reloc (abfd, 0, BFD_RELOC_RVA, 5);
02010   save_relocs (id7);
02011 
02012   bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE);
02013   d5 = xmalloc (PE_IDATA5_SIZE);
02014   id5->contents = d5;
02015   memset (d5, 0, PE_IDATA5_SIZE);
02016 
02017   if (exp->flag_noname)
02018     {
02019       d5[0] = exp->ordinal;
02020       d5[1] = exp->ordinal >> 8;
02021       d5[PE_IDATA5_SIZE - 1] = 0x80;
02022     }
02023   else
02024     {
02025       quick_reloc (abfd, 0, BFD_RELOC_RVA, 4);
02026       save_relocs (id5);
02027     }
02028 
02029   bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
02030   d4 = xmalloc (PE_IDATA4_SIZE);
02031   id4->contents = d4;
02032   memset (d4, 0, PE_IDATA4_SIZE);
02033 
02034   if (exp->flag_noname)
02035     {
02036       d4[0] = exp->ordinal;
02037       d4[1] = exp->ordinal >> 8;
02038       d4[PE_IDATA4_SIZE - 1] = 0x80;
02039     }
02040   else
02041     {
02042       quick_reloc (abfd, 0, BFD_RELOC_RVA, 4);
02043       save_relocs (id4);
02044     }
02045 
02046   if (exp->flag_noname)
02047     {
02048       len = 0;
02049       bfd_set_section_size (abfd, id6, 0);
02050     }
02051   else
02052     {
02053       /* { short, asciz }  */
02054       len = 2 + strlen (exp->name) + 1;
02055       if (len & 1)
02056        len++;
02057       bfd_set_section_size (abfd, id6, len);
02058       d6 = xmalloc (len);
02059       id6->contents = d6;
02060       memset (d6, 0, len);
02061       d6[0] = exp->hint & 0xff;
02062       d6[1] = exp->hint >> 8;
02063       strcpy ((char *) d6 + 2, exp->name);
02064     }
02065 
02066   bfd_set_symtab (abfd, symtab, symptr);
02067 
02068   if (include_jmp_stub)
02069     bfd_set_section_contents (abfd, tx, td, 0, jmp_byte_count);
02070   bfd_set_section_contents (abfd, id7, d7, 0, 4);
02071   bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE);
02072   bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
02073   if (!exp->flag_noname)
02074     bfd_set_section_contents (abfd, id6, d6, 0, len);
02075 
02076   bfd_make_readable (abfd);
02077   return abfd;
02078 }
02079 
02080 static bfd *
02081 make_singleton_name_thunk (const char *import, bfd *parent)
02082 {
02083   /* Name thunks go to idata$4.  */
02084   asection *id4;
02085   unsigned char *d4;
02086   char *oname;
02087   bfd *abfd;
02088 
02089   oname = xmalloc (20);
02090   sprintf (oname, "nmth%06d.o", tmp_seq);
02091   tmp_seq++;
02092 
02093   abfd = bfd_create (oname, parent);
02094   bfd_find_target (pe_details->object_target, abfd);
02095   bfd_make_writable (abfd);
02096 
02097   bfd_set_format (abfd, bfd_object);
02098   bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
02099 
02100   symptr = 0;
02101   symtab = xmalloc (3 * sizeof (asymbol *));
02102   id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
02103   quick_symbol (abfd, U ("_nm_thnk_"), import, "", id4, BSF_GLOBAL, 0);
02104   quick_symbol (abfd, U ("_nm_"), import, "", UNDSEC, BSF_GLOBAL, 0);
02105 
02106   /* We need space for the real thunk and for the null terminator.  */
02107   bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE * 2);
02108   d4 = xmalloc (PE_IDATA4_SIZE * 2);
02109   id4->contents = d4;
02110   memset (d4, 0, PE_IDATA4_SIZE * 2);
02111   quick_reloc (abfd, 0, BFD_RELOC_RVA, 2);
02112   save_relocs (id4);
02113 
02114   bfd_set_symtab (abfd, symtab, symptr);
02115 
02116   bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE * 2);
02117 
02118   bfd_make_readable (abfd);
02119   return abfd;
02120 }
02121 
02122 static char *
02123 make_import_fixup_mark (arelent *rel)
02124 {
02125   /* We convert reloc to symbol, for later reference.  */
02126   static int counter;
02127   static char *fixup_name = NULL;
02128   static size_t buffer_len = 0;
02129 
02130   struct bfd_symbol *sym = *rel->sym_ptr_ptr;
02131 
02132   bfd *abfd = bfd_asymbol_bfd (sym);
02133   struct bfd_link_hash_entry *bh;
02134 
02135   if (!fixup_name)
02136     {
02137       fixup_name = xmalloc (384);
02138       buffer_len = 384;
02139     }
02140 
02141   if (strlen (sym->name) + 25 > buffer_len)
02142   /* Assume 25 chars for "__fu" + counter + "_".  If counter is
02143      bigger than 20 digits long, we've got worse problems than
02144      overflowing this buffer...  */
02145     {
02146       free (fixup_name);
02147       /* New buffer size is length of symbol, plus 25, but
02148         then rounded up to the nearest multiple of 128.  */
02149       buffer_len = ((strlen (sym->name) + 25) + 127) & ~127;
02150       fixup_name = xmalloc (buffer_len);
02151     }
02152 
02153   sprintf (fixup_name, "__fu%d_%s", counter++, sym->name);
02154 
02155   bh = NULL;
02156   bfd_coff_link_add_one_symbol (&link_info, abfd, fixup_name, BSF_GLOBAL,
02157                             current_sec, /* sym->section, */
02158                             rel->address, NULL, TRUE, FALSE, &bh);
02159 
02160   return fixup_name;
02161 }
02162 
02163 /*     .section      .idata$2
02164        .rva          __nm_thnk_SYM (singleton thunk with name of func)
02165        .long         0
02166        .long         0
02167        .rva          __my_dll_iname (name of dll)
02168        .rva          __fuNN_SYM (pointer to reference (address) in text)  */
02169 
02170 static bfd *
02171 make_import_fixup_entry (const char *name,
02172                       const char *fixup_name,
02173                       const char *dll_symname,
02174                       bfd *parent)
02175 {
02176   asection *id2;
02177   unsigned char *d2;
02178   char *oname;
02179   bfd *abfd;
02180 
02181   oname = xmalloc (20);
02182   sprintf (oname, "fu%06d.o", tmp_seq);
02183   tmp_seq++;
02184 
02185   abfd = bfd_create (oname, parent);
02186   bfd_find_target (pe_details->object_target, abfd);
02187   bfd_make_writable (abfd);
02188 
02189   bfd_set_format (abfd, bfd_object);
02190   bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
02191 
02192   symptr = 0;
02193   symtab = xmalloc (6 * sizeof (asymbol *));
02194   id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2);
02195 
02196   quick_symbol (abfd, U ("_nm_thnk_"), name, "", UNDSEC, BSF_GLOBAL, 0);
02197   quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
02198   quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
02199 
02200   bfd_set_section_size (abfd, id2, 20);
02201   d2 = xmalloc (20);
02202   id2->contents = d2;
02203   memset (d2, 0, 20);
02204 
02205   quick_reloc (abfd, 0, BFD_RELOC_RVA, 1);
02206   quick_reloc (abfd, 12, BFD_RELOC_RVA, 2);
02207   quick_reloc (abfd, 16, BFD_RELOC_RVA, 3);
02208   save_relocs (id2);
02209 
02210   bfd_set_symtab (abfd, symtab, symptr);
02211 
02212   bfd_set_section_contents (abfd, id2, d2, 0, 20);
02213 
02214   bfd_make_readable (abfd);
02215   return abfd;
02216 }
02217 
02218 /*     .section      .rdata_runtime_pseudo_reloc
02219        .long         addend
02220        .rva          __fuNN_SYM (pointer to reference (address) in text)  */
02221 
02222 static bfd *
02223 make_runtime_pseudo_reloc (const char *name ATTRIBUTE_UNUSED,
02224                         const char *fixup_name,
02225                         int addend,
02226                         bfd *parent)
02227 {
02228   asection *rt_rel;
02229   unsigned char *rt_rel_d;
02230   char *oname;
02231   bfd *abfd;
02232 
02233   oname = xmalloc (20);
02234   sprintf (oname, "rtr%06d.o", tmp_seq);
02235   tmp_seq++;
02236 
02237   abfd = bfd_create (oname, parent);
02238   bfd_find_target (pe_details->object_target, abfd);
02239   bfd_make_writable (abfd);
02240 
02241   bfd_set_format (abfd, bfd_object);
02242   bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
02243 
02244   symptr = 0;
02245   symtab = xmalloc (2 * sizeof (asymbol *));
02246   rt_rel = quick_section (abfd, ".rdata_runtime_pseudo_reloc",
02247                        SEC_HAS_CONTENTS, 2);
02248 
02249   quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
02250 
02251   bfd_set_section_size (abfd, rt_rel, 8);
02252   rt_rel_d = xmalloc (8);
02253   rt_rel->contents = rt_rel_d;
02254   memset (rt_rel_d, 0, 8);
02255   bfd_put_32 (abfd, addend, rt_rel_d);
02256 
02257   quick_reloc (abfd, 4, BFD_RELOC_RVA, 1);
02258   save_relocs (rt_rel);
02259 
02260   bfd_set_symtab (abfd, symtab, symptr);
02261 
02262   bfd_set_section_contents (abfd, rt_rel, rt_rel_d, 0, 8);
02263 
02264   bfd_make_readable (abfd);
02265   return abfd;
02266 }
02267 
02268 /*     .section      .rdata
02269        .rva          __pei386_runtime_relocator  */
02270 
02271 static bfd *
02272 pe_create_runtime_relocator_reference (bfd *parent)
02273 {
02274   asection *extern_rt_rel;
02275   unsigned char *extern_rt_rel_d;
02276   char *oname;
02277   bfd *abfd;
02278 
02279   oname = xmalloc (20);
02280   sprintf (oname, "ertr%06d.o", tmp_seq);
02281   tmp_seq++;
02282 
02283   abfd = bfd_create (oname, parent);
02284   bfd_find_target (pe_details->object_target, abfd);
02285   bfd_make_writable (abfd);
02286 
02287   bfd_set_format (abfd, bfd_object);
02288   bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
02289 
02290   symptr = 0;
02291   symtab = xmalloc (2 * sizeof (asymbol *));
02292   extern_rt_rel = quick_section (abfd, ".rdata", SEC_HAS_CONTENTS, 2);
02293 
02294   quick_symbol (abfd, "", U ("_pei386_runtime_relocator"), "", UNDSEC,
02295               BSF_NO_FLAGS, 0);
02296 
02297   bfd_set_section_size (abfd, extern_rt_rel, 4);
02298   extern_rt_rel_d = xmalloc (4);
02299   extern_rt_rel->contents = extern_rt_rel_d;
02300 
02301   quick_reloc (abfd, 0, BFD_RELOC_RVA, 1);
02302   save_relocs (extern_rt_rel);
02303 
02304   bfd_set_symtab (abfd, symtab, symptr);
02305 
02306   bfd_set_section_contents (abfd, extern_rt_rel, extern_rt_rel_d, 0, 4);
02307 
02308   bfd_make_readable (abfd);
02309   return abfd;
02310 }
02311 
02312 void
02313 pe_create_import_fixup (arelent *rel, asection *s, int addend)
02314 {
02315   char buf[300];
02316   struct bfd_symbol *sym = *rel->sym_ptr_ptr;
02317   struct bfd_link_hash_entry *name_thunk_sym;
02318   const char *name = sym->name;
02319   char *fixup_name = make_import_fixup_mark (rel);
02320   bfd *b;
02321 
02322   sprintf (buf, U ("_nm_thnk_%s"), name);
02323 
02324   name_thunk_sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);
02325 
02326   if (!name_thunk_sym || name_thunk_sym->type != bfd_link_hash_defined)
02327     {
02328       bfd *b = make_singleton_name_thunk (name, output_bfd);
02329       add_bfd_to_link (b, b->filename, &link_info);
02330 
02331       /* If we ever use autoimport, we have to cast text section writable.  */
02332       config.text_read_only = FALSE;
02333       output_bfd->flags &= ~WP_TEXT;   
02334     }
02335 
02336   if (addend == 0 || link_info.pei386_runtime_pseudo_reloc)
02337     {
02338       extern char * pe_data_import_dll;
02339       char * dll_symname = pe_data_import_dll ? pe_data_import_dll : "unknown";
02340 
02341       b = make_import_fixup_entry (name, fixup_name, dll_symname, output_bfd);
02342       add_bfd_to_link (b, b->filename, &link_info);
02343     }
02344 
02345   if (addend != 0)
02346     {
02347       if (link_info.pei386_runtime_pseudo_reloc)
02348        {
02349          if (pe_dll_extra_pe_debug)
02350            printf ("creating runtime pseudo-reloc entry for %s (addend=%d)\n",
02351                  fixup_name, addend);
02352          b = make_runtime_pseudo_reloc (name, fixup_name, addend, output_bfd);
02353          add_bfd_to_link (b, b->filename, &link_info);
02354 
02355          if (runtime_pseudo_relocs_created == 0)
02356            {
02357              b = pe_create_runtime_relocator_reference (output_bfd);
02358              add_bfd_to_link (b, b->filename, &link_info);
02359            }
02360          runtime_pseudo_relocs_created++;
02361        }
02362       else
02363        {
02364          einfo (_("%C: variable '%T' can't be auto-imported. Please read the documentation for ld's --enable-auto-import for details.\n"),
02365                s->owner, s, rel->address, sym->name);
02366          einfo ("%X");
02367        }
02368     }
02369 }
02370 
02371 
02372 void
02373 pe_dll_generate_implib (def_file *def, const char *impfilename)
02374 {
02375   int i;
02376   bfd *ar_head;
02377   bfd *ar_tail;
02378   bfd *outarch;
02379   bfd *head = 0;
02380 
02381   dll_filename = (def->name) ? def->name : dll_name;
02382   dll_symname = xstrdup (dll_filename);
02383   for (i = 0; dll_symname[i]; i++)
02384     if (!ISALNUM (dll_symname[i]))
02385       dll_symname[i] = '_';
02386 
02387   unlink_if_ordinary (impfilename);
02388 
02389   outarch = bfd_openw (impfilename, 0);
02390 
02391   if (!outarch)
02392     {
02393       /* xgettext:c-format */
02394       einfo (_("%XCan't open .lib file: %s\n"), impfilename);
02395       return;
02396     }
02397 
02398   /* xgettext:c-format */
02399   info_msg (_("Creating library file: %s\n"), impfilename);
02400  
02401   bfd_set_format (outarch, bfd_archive);
02402   outarch->has_armap = 1;
02403 
02404   /* Work out a reasonable size of things to put onto one line.  */
02405   ar_head = make_head (outarch);
02406 
02407   for (i = 0; i < def->num_exports; i++)
02408     {
02409       /* The import library doesn't know about the internal name.  */
02410       char *internal = def->exports[i].internal_name;
02411       bfd *n;
02412 
02413       /* Don't add PRIVATE entries to import lib.  */   
02414       if (pe_def_file->exports[i].flag_private)
02415        continue;
02416       def->exports[i].internal_name = def->exports[i].name;
02417       n = make_one (def->exports + i, outarch,
02418                   ! (def->exports + i)->flag_data);
02419       n->next = head;
02420       head = n;
02421       def->exports[i].internal_name = internal;
02422     }
02423 
02424   ar_tail = make_tail (outarch);
02425 
02426   if (ar_head == NULL || ar_tail == NULL)
02427     return;
02428 
02429   /* Now stick them all into the archive.  */
02430   ar_head->next = head;
02431   ar_tail->next = ar_head;
02432   head = ar_tail;
02433 
02434   if (! bfd_set_archive_head (outarch, head))
02435     einfo ("%Xbfd_set_archive_head: %E\n");
02436 
02437   if (! bfd_close (outarch))
02438     einfo ("%Xbfd_close %s: %E\n", impfilename);
02439 
02440   while (head != NULL)
02441     {
02442       bfd *n = head->next;
02443       bfd_close (head);
02444       head = n;
02445     }
02446 }
02447 
02448 static void
02449 add_bfd_to_link (bfd *abfd, const char *name, struct bfd_link_info *link_info)
02450 {
02451   lang_input_statement_type *fake_file;
02452 
02453   fake_file = lang_add_input_file (name,
02454                                lang_input_file_is_fake_enum,
02455                                NULL);
02456   fake_file->the_bfd = abfd;
02457   ldlang_add_file (fake_file);
02458 
02459   if (!bfd_link_add_symbols (abfd, link_info))
02460     einfo ("%Xaddsym %s: %E\n", name);
02461 }
02462 
02463 void
02464 pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *link_info)
02465 {
02466   def_file_module *module;
02467 
02468   pe_dll_id_target (bfd_get_target (output_bfd));
02469 
02470   if (!pe_def_file)
02471     return;
02472 
02473   for (module = pe_def_file->modules; module; module = module->next)
02474     {
02475       int i, do_this_dll;
02476 
02477       dll_filename = module->name;
02478       dll_symname = xstrdup (module->name);
02479       for (i = 0; dll_symname[i]; i++)
02480        if (!ISALNUM (dll_symname[i]))
02481          dll_symname[i] = '_';
02482 
02483       do_this_dll = 0;
02484 
02485       for (i = 0; i < pe_def_file->num_imports; i++)
02486        if (pe_def_file->imports[i].module == module)
02487          {
02488            def_file_export exp;
02489            struct bfd_link_hash_entry *blhe;
02490            int lead_at = (*pe_def_file->imports[i].internal_name == '@');
02491            /* See if we need this import.  */
02492            size_t len = strlen (pe_def_file->imports[i].internal_name);
02493            char *name = xmalloc (len + 2 + 6);
02494            bfd_boolean include_jmp_stub = FALSE;
02495 
02496            if (lead_at)
02497              sprintf (name, "%s",
02498                      pe_def_file->imports[i].internal_name);
02499            else
02500              sprintf (name, "%s%s",U (""),
02501                      pe_def_file->imports[i].internal_name);
02502 
02503            blhe = bfd_link_hash_lookup (link_info->hash, name,
02504                                     FALSE, FALSE, FALSE);
02505 
02506            /* Include the jump stub for <sym> only if the <sym>
02507               is undefined.  */
02508            if (!blhe || (blhe && blhe->type != bfd_link_hash_undefined))
02509              {
02510               if (lead_at)
02511                 sprintf (name, "%s%s", "__imp_", 
02512                         pe_def_file->imports[i].internal_name);
02513               else
02514                 sprintf (name, "%s%s%s", "__imp_", U (""),
02515                         pe_def_file->imports[i].internal_name);
02516 
02517               blhe = bfd_link_hash_lookup (link_info->hash, name,
02518                                         FALSE, FALSE, FALSE);
02519              }
02520            else
02521              include_jmp_stub = TRUE;
02522 
02523            free (name);
02524 
02525            if (blhe && blhe->type == bfd_link_hash_undefined)
02526              {
02527               bfd *one;
02528               /* We do.  */
02529               if (!do_this_dll)
02530                 {
02531                   bfd *ar_head = make_head (output_bfd);
02532                   add_bfd_to_link (ar_head, ar_head->filename, link_info);
02533                   do_this_dll = 1;
02534                 }
02535               exp.internal_name = pe_def_file->imports[i].internal_name;
02536               exp.name = pe_def_file->imports[i].name;
02537               exp.ordinal = pe_def_file->imports[i].ordinal;
02538               exp.hint = exp.ordinal >= 0 ? exp.ordinal : 0;
02539               exp.flag_private = 0;
02540               exp.flag_constant = 0;
02541               exp.flag_data = pe_def_file->imports[i].data;
02542               exp.flag_noname = exp.name ? 0 : 1;
02543               one = make_one (&exp, output_bfd, (! exp.flag_data) && include_jmp_stub);
02544               add_bfd_to_link (one, one->filename, link_info);
02545              }
02546          }
02547       if (do_this_dll)
02548        {
02549          bfd *ar_tail = make_tail (output_bfd);
02550          add_bfd_to_link (ar_tail, ar_tail->filename, link_info);
02551        }
02552 
02553       free (dll_symname);
02554     }
02555 }
02556 
02557 /* We were handed a *.DLL file.  Parse it and turn it into a set of
02558    IMPORTS directives in the def file.  Return TRUE if the file was
02559    handled, FALSE if not.  */
02560 
02561 static unsigned int
02562 pe_get16 (bfd *abfd, int where)
02563 {
02564   unsigned char b[2];
02565 
02566   bfd_seek (abfd, (file_ptr) where, SEEK_SET);
02567   bfd_bread (b, (bfd_size_type) 2, abfd);
02568   return b[0] + (b[1] << 8);
02569 }
02570 
02571 static unsigned int
02572 pe_get32 (bfd *abfd, int where)
02573 {
02574   unsigned char b[4];
02575 
02576   bfd_seek (abfd, (file_ptr) where, SEEK_SET);
02577   bfd_bread (b, (bfd_size_type) 4, abfd);
02578   return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
02579 }
02580 
02581 static unsigned int
02582 pe_as32 (void *ptr)
02583 {
02584   unsigned char *b = ptr;
02585 
02586   return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
02587 }
02588 
02589 bfd_boolean
02590 pe_implied_import_dll (const char *filename)
02591 {
02592   bfd *dll;
02593   unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
02594   unsigned long export_rva, export_size, nsections, secptr, expptr;
02595   unsigned long exp_funcbase;
02596   unsigned char *expdata;
02597   char *erva;
02598   unsigned long name_rvas, ordinals, nexp, ordbase;
02599   const char *dll_name;
02600   /* Initialization with start > end guarantees that is_data
02601      will not be set by mistake, and avoids compiler warning.  */
02602   unsigned long data_start = 1;
02603   unsigned long data_end = 0;
02604   unsigned long rdata_start = 1;
02605   unsigned long rdata_end = 0;
02606   unsigned long bss_start = 1;
02607   unsigned long bss_end = 0;
02608 
02609   /* No, I can't use bfd here.  kernel32.dll puts its export table in
02610      the middle of the .rdata section.  */
02611   dll = bfd_openr (filename, pe_details->target_name);
02612   if (!dll)
02613     {
02614       einfo ("%Xopen %s: %E\n", filename);
02615       return FALSE;
02616     }
02617 
02618   /* PEI dlls seem to be bfd_objects.  */
02619   if (!bfd_check_format (dll, bfd_object))
02620     {
02621       einfo ("%X%s: this doesn't appear to be a DLL\n", filename);
02622       return FALSE;
02623     }
02624 
02625   /* Get pe_header, optional header and numbers of export entries.  */
02626   pe_header_offset = pe_get32 (dll, 0x3c);
02627   opthdr_ofs = pe_header_offset + 4 + 20;
02628 #ifdef pe_use_x86_64
02629   num_entries = pe_get32 (dll, opthdr_ofs + 92 + 4 * 4); /*  & NumberOfRvaAndSizes.  */
02630 #else
02631   num_entries = pe_get32 (dll, opthdr_ofs + 92);
02632 #endif
02633 
02634   if (num_entries < 1) /* No exports.  */
02635     return FALSE;
02636 
02637 #ifdef pe_use_x86_64
02638   export_rva  = pe_get32 (dll, opthdr_ofs + 96 + 4 * 4);
02639   export_size = pe_get32 (dll, opthdr_ofs + 100 + 4 * 4);
02640 #else
02641   export_rva = pe_get32 (dll, opthdr_ofs + 96);
02642   export_size = pe_get32 (dll, opthdr_ofs + 100);
02643 #endif
02644   
02645   nsections = pe_get16 (dll, pe_header_offset + 4 + 2);
02646   secptr = (pe_header_offset + 4 + 20 +
02647            pe_get16 (dll, pe_header_offset + 4 + 16));
02648   expptr = 0;
02649 
02650   /* Get the rva and size of the export section.  */
02651   for (i = 0; i < nsections; i++)
02652     {
02653       char sname[8];
02654       unsigned long secptr1 = secptr + 40 * i;
02655       unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
02656       unsigned long vsize = pe_get32 (dll, secptr1 + 16);
02657       unsigned long fptr = pe_get32 (dll, secptr1 + 20);
02658 
02659       bfd_seek (dll, (file_ptr) secptr1, SEEK_SET);
02660       bfd_bread (sname, (bfd_size_type) 8, dll);
02661 
02662       if (vaddr <= export_rva && vaddr + vsize > export_rva)
02663        {
02664          expptr = fptr + (export_rva - vaddr);
02665          if (export_rva + export_size > vaddr + vsize)
02666            export_size = vsize - (export_rva - vaddr);
02667          break;
02668        }
02669     }
02670 
02671   /* Scan sections and store the base and size of the
02672      data and bss segments in data/base_start/end.  */
02673   for (i = 0; i < nsections; i++)
02674     {
02675       unsigned long secptr1 = secptr + 40 * i;
02676       unsigned long vsize = pe_get32 (dll, secptr1 + 8);
02677       unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
02678       unsigned long flags = pe_get32 (dll, secptr1 + 36);
02679       char sec_name[9];
02680 
02681       sec_name[8] = '\0';
02682       bfd_seek (dll, (file_ptr) secptr1 + 0, SEEK_SET);
02683       bfd_bread (sec_name, (bfd_size_type) 8, dll);
02684 
02685       if (strcmp(sec_name,".data") == 0)
02686        {
02687          data_start = vaddr;
02688          data_end = vaddr + vsize;
02689 
02690          if (pe_dll_extra_pe_debug)
02691            printf ("%s %s: 0x%08lx-0x%08lx (0x%08lx)\n",
02692                   __FUNCTION__, sec_name, vaddr, vaddr + vsize, flags);
02693        }
02694       else if (strcmp(sec_name,".rdata") == 0)
02695        {
02696          rdata_start = vaddr;
02697          rdata_end = vaddr + vsize;
02698 
02699          if (pe_dll_extra_pe_debug)
02700            printf ("%s %s: 0x%08lx-0x%08lx (0x%08lx)\n",
02701                   __FUNCTION__, sec_name, vaddr, vaddr + vsize, flags);
02702        }
02703       else if (strcmp (sec_name,".bss") == 0)
02704        {
02705          bss_start = vaddr;
02706          bss_end = vaddr + vsize;
02707 
02708          if (pe_dll_extra_pe_debug)
02709            printf ("%s %s: 0x%08lx-0x%08lx (0x%08lx)\n",
02710                   __FUNCTION__, sec_name, vaddr, vaddr + vsize, flags);
02711        }
02712     }
02713 
02714   expdata = xmalloc (export_size);
02715   bfd_seek (dll, (file_ptr) expptr, SEEK_SET);
02716   bfd_bread (expdata, (bfd_size_type) export_size, dll);
02717   erva = (char *) expdata - export_rva;
02718 
02719   if (pe_def_file == 0)
02720     pe_def_file = def_file_empty ();
02721 
02722   nexp = pe_as32 (expdata + 24);
02723   name_rvas = pe_as32 (expdata + 32);
02724   ordinals = pe_as32 (expdata + 36);
02725   ordbase = pe_as32 (expdata + 16);
02726   exp_funcbase = pe_as32 (expdata + 28);
02727 
02728   /* Use internal dll name instead of filename
02729      to enable symbolic dll linking.  */
02730   dll_name = erva + pe_as32 (expdata + 12);
02731 
02732   /* Check to see if the dll has already been added to
02733      the definition list and if so return without error.
02734      This avoids multiple symbol definitions.  */
02735   if (def_get_module (pe_def_file, dll_name))
02736     {
02737       if (pe_dll_extra_pe_debug)
02738        printf ("%s is already loaded\n", dll_name);
02739       return TRUE;
02740     }
02741 
02742   /* Iterate through the list of symbols.  */
02743   for (i = 0; i < nexp; i++)
02744     {
02745       /* Pointer to the names vector.  */
02746       unsigned long name_rva = pe_as32 (erva + name_rvas + i * 4);
02747       def_file_import *imp;
02748       /* Pointer to the function address vector.  */
02749       unsigned long func_rva = pe_as32 (erva + exp_funcbase + i * 4);
02750       int is_data = 0;
02751 
02752       /* Skip unwanted symbols, which are
02753         exported in buggy auto-import releases.  */
02754       if (! CONST_STRNEQ (erva + name_rva, "_nm_"))
02755        {
02756          /* is_data is true if the address is in the data, rdata or bss
02757             segment.  */
02758          is_data =
02759            (func_rva >= data_start && func_rva < data_end)
02760            || (func_rva >= rdata_start && func_rva < rdata_end)
02761            || (func_rva >= bss_start && func_rva < bss_end);
02762 
02763          imp = def_file_add_import (pe_def_file, erva + name_rva,
02764                                  dll_name, i, 0);
02765          /* Mark symbol type.  */
02766          imp->data = is_data;
02767 
02768          if (pe_dll_extra_pe_debug)
02769            printf ("%s dll-name: %s sym: %s addr: 0x%lx %s\n",
02770                   __FUNCTION__, dll_name, erva + name_rva,
02771                   func_rva, is_data ? "(data)" : "");
02772        }
02773     }
02774 
02775   return TRUE;
02776 }
02777 
02778 /* These are the main functions, called from the emulation.  The first
02779    is called after the bfds are read, so we can guess at how much space
02780    we need.  The second is called after everything is placed, so we
02781    can put the right values in place.  */
02782 
02783 void
02784 pe_dll_build_sections (bfd *abfd, struct bfd_link_info *info)
02785 {
02786   pe_dll_id_target (bfd_get_target (abfd));
02787   process_def_file (abfd, info);
02788 
02789   if (pe_def_file->num_exports == 0 && !info->shared)
02790     return;
02791 
02792   generate_edata (abfd, info);
02793   build_filler_bfd (1);
02794 }
02795 
02796 void
02797 pe_exe_build_sections (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
02798 {
02799   pe_dll_id_target (bfd_get_target (abfd));
02800   build_filler_bfd (0);
02801 }
02802 
02803 void
02804 pe_dll_fill_sections (bfd *abfd, struct bfd_link_info *info)
02805 {
02806   pe_dll_id_target (bfd_get_target (abfd));
02807   image_base = pe_data (abfd)->pe_opthdr.ImageBase;
02808 
02809   generate_reloc (abfd, info);
02810   if (reloc_sz > 0)
02811     {
02812       bfd_set_section_size (filler_bfd, reloc_s, reloc_sz);
02813 
02814       /* Resize the sections.  */
02815       lang_reset_memory_regions ();
02816       lang_size_sections (NULL, TRUE);
02817 
02818       /* Redo special stuff.  */
02819       ldemul_after_allocation ();
02820 
02821       /* Do the assignments again.  */
02822       lang_do_assignments ();
02823     }
02824 
02825   fill_edata (abfd, info);
02826 
02827   if (info->shared && !info->pie)
02828     pe_data (abfd)->dll = 1;
02829 
02830   edata_s->contents = edata_d;
02831   reloc_s->contents = reloc_d;
02832 }
02833 
02834 void
02835 pe_exe_fill_sections (bfd *abfd, struct bfd_link_info *info)
02836 {
02837   pe_dll_id_target (bfd_get_target (abfd));
02838   image_base = pe_data (abfd)->pe_opthdr.ImageBase;
02839 
02840   generate_reloc (abfd, info);
02841   if (reloc_sz > 0)
02842     {
02843       bfd_set_section_size (filler_bfd, reloc_s, reloc_sz);
02844 
02845       /* Resize the sections.  */
02846       lang_reset_memory_regions ();
02847       lang_size_sections (NULL, TRUE);
02848 
02849       /* Redo special stuff.  */
02850       ldemul_after_allocation ();
02851 
02852       /* Do the assignments again.  */
02853       lang_do_assignments ();
02854     }
02855   reloc_s->contents = reloc_d;
02856 }
02857 
02858 bfd_boolean
02859 pe_bfd_is_dll (bfd *abfd)
02860 {
02861   return (bfd_get_format (abfd) == bfd_object
02862           && obj_pe (abfd)
02863           && pe_data (abfd)->dll);
02864 }