* linux-arm-low.c: Include <signal.h>.
[deliverable/binutils-gdb.git] / ld / pe-dll.c
index 60d36a455845a6019c5606d9d88b27cd53a47bdc..7848063f211dcdbee109b7d0379232171b5f934c 100644 (file)
@@ -1,6 +1,6 @@
 /* Routines to help build PEI-format DLLs (Win32 etc)
    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008, 2009, 2010 Free Software Foundation, Inc.
+   2008, 2009, 2010, 2011 Free Software Foundation, Inc.
    Written by DJ Delorie <dj@cygnus.com>
 
    This file is part of the GNU Binutils.
@@ -24,6 +24,7 @@
 #include "bfd.h"
 #include "bfdlink.h"
 #include "libiberty.h"
+#include "filenames.h"
 #include "safe-ctype.h"
 
 #include <time.h>
@@ -261,7 +262,11 @@ static pe_details_type pe_detail_list[] =
 #endif
     PE_ARCH_i386,
     bfd_arch_i386,
+#ifdef pe_use_x86_64
+    FALSE,
+#else
     TRUE,
+#endif
     autofilter_symbollist_i386
   },
   {
@@ -339,7 +344,7 @@ static const autofilter_entry_type autofilter_liblist[] =
   returning zero if so or -1 if not.  */
 static int libnamencmp (const char *libname, const autofilter_entry_type *afptr)
 {
-  if (strncmp (libname, afptr->name, afptr->len))
+  if (filename_ncmp (libname, afptr->name, afptr->len))
     return -1;
 
   libname += afptr->len;
@@ -416,9 +421,11 @@ pe_dll_id_target (const char *target)
        int u = pe_leading_underscore; /* Underscoring mode. -1 for use default.  */
        if (u == -1)
          bfd_get_target_info (target, NULL, NULL, &u, NULL);
-       if (u != -1)
-         pe_detail_list[i].underscored = (u != 0 ? TRUE : FALSE);
+       if (u == -1)
+         abort ();
+       pe_detail_list[i].underscored = (u != 0 ? TRUE : FALSE);
        pe_details = pe_detail_list + i;
+       pe_leading_underscore = (u != 0 ? 1 : 0);
        return;
       }
   einfo (_("%XUnsupported PEI architecture: %s\n"), target);
@@ -613,13 +620,13 @@ auto_export (bfd *abfd, def_file *d, const char *n)
       if (ex->type == EXCLUDELIBS)
        {
          if (libname
-             && ((strcmp (libname, ex->string) == 0)
+             && ((filename_cmp (libname, ex->string) == 0)
                   || (strcasecmp ("ALL", ex->string) == 0)))
            return 0;
        }
       else if (ex->type == EXCLUDEFORIMPLIB)
        {
-         if (strcmp (abfd->filename, ex->string) == 0)
+         if (filename_cmp (abfd->filename, ex->string) == 0)
            return 0;
        }
       else if (strcmp (n, ex->string) == 0)
@@ -711,14 +718,10 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
              bfd_boolean would_export = symbols[j]->section != &bfd_und_section
                      && ((symbols[j]->flags & BSF_GLOBAL)
                          || (symbols[j]->flags == 0));
-             if (lang_elf_version_info && would_export)
-               {
-                 bfd_boolean hide = 0;
-                 char ofs = pe_details->underscored && symbols[j]->name[0] == '_';
-                 (void) bfd_find_version_for_sym (lang_elf_version_info,
-                               symbols[j]->name + ofs, &hide);
-                 would_export = !hide;
-               }
+             if (link_info.version_info && would_export)
+                 would_export
+                   = !bfd_hide_sym_by_version (link_info.version_info,
+                                               symbols[j]->name);
              if (would_export)
                {
                  const char *sn = symbols[j]->name;
@@ -745,10 +748,13 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
 
                  if (auto_export (b, pe_def_file, sn))
                    {
+                     int is_dup = 0;
                      def_file_export *p;
-                     p=def_file_add_export (pe_def_file, sn, 0, -1, NULL);
+                     p = def_file_add_export (pe_def_file, sn, 0, -1,
+                                              NULL, &is_dup);
                      /* Fill data flag properly, from dlltool.c.  */
-                     p->flag_data = !(symbols[j]->flags & BSF_FUNCTION);
+                     if (!is_dup)
+                       p->flag_data = !(symbols[j]->flags & BSF_FUNCTION);
                    }
                }
            }
@@ -795,6 +801,7 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
 
          if (strchr (pe_def_file->exports[i].name, '@'))
            {
+             int is_dup = 1;
              int lead_at = (*pe_def_file->exports[i].name == '@');
              char *tmp = xstrdup (pe_def_file->exports[i].name + lead_at);
 
@@ -802,9 +809,9 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
              if (auto_export (NULL, pe_def_file, tmp))
                def_file_add_export (pe_def_file, tmp,
                                     pe_def_file->exports[i].internal_name,
-                                    -1, NULL);
-             else
-               free (tmp);
+                                    -1, NULL, &is_dup);
+             if (is_dup)
+               free (tmp);
            }
        }
     }
@@ -865,28 +872,6 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
   for (i = 0; i < NE; i++)
     {
       char *name;
-
-      /* Check for forward exports */
-      if (strchr (pe_def_file->exports[i].internal_name, '.'))
-       {
-         count_exported++;
-         if (!pe_def_file->exports[i].flag_noname)
-           count_exported_byname++;
-
-         pe_def_file->exports[i].flag_forward = 1;
-
-         if (pe_def_file->exports[i].ordinal != -1)
-           {
-             if (max_ordinal < pe_def_file->exports[i].ordinal)
-               max_ordinal = pe_def_file->exports[i].ordinal;
-             if (min_ordinal > pe_def_file->exports[i].ordinal)
-               min_ordinal = pe_def_file->exports[i].ordinal;
-             count_with_ordinals++;
-           }
-
-         continue;
-       }
-
       name = xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2);
       if (pe_details->underscored
          && (*pe_def_file->exports[i].internal_name != '@'))
@@ -917,6 +902,28 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
          else
            exported_symbol_sections[i] = blhe->u.c.p->section;
 
+         if (pe_def_file->exports[i].ordinal != -1)
+           {
+             if (max_ordinal < pe_def_file->exports[i].ordinal)
+               max_ordinal = pe_def_file->exports[i].ordinal;
+             if (min_ordinal > pe_def_file->exports[i].ordinal)
+               min_ordinal = pe_def_file->exports[i].ordinal;
+             count_with_ordinals++;
+           }
+       }
+      /* Check for forward exports.  These are indicated in DEF files by an
+         export directive of the form NAME1 = MODULE-NAME.EXTERNAL-NAME
+        but we must take care not to be fooled when the user wants to export
+        a symbol that actually really has a dot in it, so we only check
+        for them here, after real defined symbols have already been matched.  */
+      else if (strchr (pe_def_file->exports[i].internal_name, '.'))
+       {
+         count_exported++;
+         if (!pe_def_file->exports[i].flag_noname)
+           count_exported_byname++;
+
+         pe_def_file->exports[i].flag_forward = 1;
+
          if (pe_def_file->exports[i].ordinal != -1)
            {
              if (max_ordinal < pe_def_file->exports[i].ordinal)
@@ -1148,7 +1155,7 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
 
   /* Note use of array pointer math here.  */
   edirectory = edata_d;
-  eaddresses = edata_d + 40;
+  eaddresses = edirectory + 40;
   enameptrs = eaddresses + 4 * export_table_size;
   eordinals = enameptrs + 4 * count_exported_byname;
   enamestr = (char *) eordinals + 2 * count_exported_byname;
@@ -1241,7 +1248,6 @@ pe_walk_relocs_of_symbol (struct bfd_link_info *info,
   for (b = info->input_bfds; b; b = b->link_next)
     {
       asymbol **symbols;
-      int nsyms;
 
       if (!bfd_generic_link_read_symbols (b))
        {
@@ -1250,7 +1256,6 @@ pe_walk_relocs_of_symbol (struct bfd_link_info *info,
        }
 
       symbols = bfd_get_outsymbols (b);
-      nsyms = bfd_get_symcount (b);
 
       for (s = b->sections; s; s = s->next)
        {
@@ -1320,7 +1325,6 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
        {
          bfd_vma sec_vma = s->output_section->vma + s->output_offset;
          asymbol **symbols;
-         int nsyms;
 
          /* If it's not loaded, we don't need to relocate it this way.  */
          if (!(s->output_section->flags & SEC_LOAD))
@@ -1347,7 +1351,6 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
            }
 
          symbols = bfd_get_outsymbols (b);
-         nsyms = bfd_get_symcount (b);
          relsize = bfd_get_reloc_upper_bound (b, s);
          relocs = xmalloc (relsize);
          nrelocs = bfd_canonicalize_reloc (b, s, relocs, symbols);
@@ -1362,7 +1365,6 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
              if (!relocs[i]->howto->pc_relative
                  && relocs[i]->howto->type != pe_details->imagebase_reloc)
                {
-                 bfd_vma sym_vma;
                  struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
 
                  /* Don't create relocs for undefined weak symbols.  */
@@ -1394,11 +1396,6 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
                        continue;
                    }
 
-                 sym_vma = (relocs[i]->addend
-                            + sym->value
-                            + sym->section->vma
-                            + sym->section->output_offset
-                            + sym->section->output_section->vma);
                  reloc_data[total_relocs].vma = sec_vma + relocs[i]->address;
 
 #define BITS_AND_SHIFT(bits, shift) (bits * 1000 | shift)
@@ -2706,7 +2703,7 @@ pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_
        {
          if (ex->type != EXCLUDEFORIMPLIB)
            continue;
-         found = (strcmp (ex->string, ibfd->filename) == 0);
+         found = (filename_cmp (ex->string, ibfd->filename) == 0);
        }
       /* If it matched, we must open a fresh BFD for it (the original
         input BFD is still needed for the DLL's final link) and add
@@ -2736,7 +2733,7 @@ pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_
              newbfd = NULL;
              while ((newbfd = bfd_openr_next_archived_file (arbfd, newbfd)) != 0)
                {
-                 if (strcmp (newbfd->filename, ibfd->filename) == 0)
+                 if (filename_cmp (newbfd->filename, ibfd->filename) == 0)
                    break;
                }
              if (!newbfd)
@@ -2986,7 +2983,7 @@ pe_implied_import_dll (const char *filename)
   bfd_vma exp_funcbase;
   unsigned char *expdata;
   char *erva;
-  bfd_vma name_rvas, ordinals, nexp, ordbase;
+  bfd_vma name_rvas, nexp;
   const char *dllname;
   /* Initialization with start > end guarantees that is_data
      will not be set by mistake, and avoids compiler warning.  */
@@ -3120,8 +3117,6 @@ pe_implied_import_dll (const char *filename)
 
   nexp = pe_as32 (expdata + 24);
   name_rvas = pe_as32 (expdata + 32);
-  ordinals = pe_as32 (expdata + 36);
-  ordbase = pe_as32 (expdata + 16);
   exp_funcbase = pe_as32 (expdata + 28);
 
   /* Use internal dll name instead of filename
@@ -3152,6 +3147,7 @@ pe_implied_import_dll (const char *filename)
         exported in buggy auto-import releases.  */
       if (! CONST_STRNEQ (erva + name_rva, "__nm_"))
        {
+         int is_dup = 0;
          /* is_data is true if the address is in the data, rdata or bss
             segment.  */
          is_data =
@@ -3160,9 +3156,10 @@ pe_implied_import_dll (const char *filename)
            || (func_rva >= bss_start && func_rva < bss_end);
 
          imp = def_file_add_import (pe_def_file, erva + name_rva,
-                                    dllname, i, 0, NULL);
+                                    dllname, i, 0, NULL, &is_dup);
          /* Mark symbol type.  */
-         imp->data = is_data;
+         if (!is_dup)
+           imp->data = is_data;
 
          if (pe_dll_extra_pe_debug)
            printf ("%s dll-name: %s sym: %s addr: 0x%lx %s\n",
@@ -3232,7 +3229,7 @@ pe_dll_fill_sections (bfd *abfd, struct bfd_link_info *info)
       ldemul_after_allocation ();
 
       /* Do the assignments again.  */
-      lang_do_assignments ();
+      lang_do_assignments (lang_final_phase_enum);
     }
 
   fill_edata (abfd, info);
@@ -3264,7 +3261,7 @@ pe_exe_fill_sections (bfd *abfd, struct bfd_link_info *info)
       ldemul_after_allocation ();
 
       /* Do the assignments again.  */
-      lang_do_assignments ();
+      lang_do_assignments (lang_final_phase_enum);
     }
   reloc_s->contents = reloc_d;
 }
This page took 0.027056 seconds and 4 git commands to generate.