gdb/gdbserver/
[deliverable/binutils-gdb.git] / ld / pe-dll.c
index fb94813a875dee3ec90937df4db4e0c4c05345db..21717fc5ce5823ffa0252decfb38bf1be188197d 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 Free Software Foundation, Inc.
+   2008, 2009, 2010 Free Software Foundation, Inc.
    Written by DJ Delorie <dj@cygnus.com>
 
    This file is part of the GNU Binutils.
@@ -158,6 +158,7 @@ int pe_dll_compat_implib = 0;
 int pe_dll_extra_pe_debug = 0;
 int pe_use_nul_prefixed_import_tables = 0;
 int pe_use_coff_long_section_names = -1;
+int pe_leading_underscore = -1;
 
 /* Static variables and types.  */
 
@@ -244,7 +245,9 @@ static const autofilter_entry_type autofilter_symbollist_i386[] =
 #define PE_ARCH_arm_epoc 5
 #define PE_ARCH_arm_wince 6
 
-static const pe_details_type pe_detail_list[] =
+/* Don't make it constant as underscore mode gets possibly overriden
+   by target or -(no-)leading-underscore option.  */
+static pe_details_type pe_detail_list[] =
 {
   {
 #ifdef pe_use_x86_64
@@ -410,6 +413,11 @@ pe_dll_id_target (const char *target)
     if (strcmp (pe_detail_list[i].target_name, target) == 0
        || strcmp (pe_detail_list[i].object_target, target) == 0)
       {
+       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);
        pe_details = pe_detail_list + i;
        return;
       }
@@ -1306,7 +1314,7 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
   for (bi = 0, b = info->input_bfds; b; bi++, b = b->link_next)
     {
       arelent **relocs;
-      int relsize, nrelocs, i;
+      int relsize, nrelocs;
 
       for (s = b->sections; s; s = s->next)
        {
@@ -1361,10 +1369,29 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
                  if (sym->flags == BSF_WEAK)
                    {
                      struct bfd_link_hash_entry *blhe
-                       = bfd_link_hash_lookup (info->hash, sym->name,
+                       = bfd_wrapped_link_hash_lookup (abfd, info, sym->name,
                                                FALSE, FALSE, FALSE);
-                     if (!blhe || blhe->type != bfd_link_hash_defined)
-                       continue;                     
+                     if (blhe && blhe->type == bfd_link_hash_undefweak)
+                       {
+                         /* Check aux sym and see if it is defined or not. */
+                         struct coff_link_hash_entry *h, *h2;
+                         h = (struct coff_link_hash_entry *)blhe;
+                         if (h->symbol_class != C_NT_WEAK || h->numaux != 1)
+                           continue;
+                         h2 = h->auxbfd->tdata.coff_obj_data->sym_hashes
+                                               [h->aux->x_sym.x_tagndx.l];
+                         /* We don't want a base reloc if the aux sym is not
+                            found, undefined, or if it is the constant ABS
+                            zero default value.  (We broaden that slightly by
+                            not testing the value, just the section; there's
+                            no reason we'd want a reference to any absolute
+                            address to get relocated during rebasing).  */
+                         if (!h2 || h2->root.type == bfd_link_hash_undefined
+                               || h2->root.u.def.section == &bfd_abs_section)
+                           continue;
+                       }
+                     else if (!blhe || blhe->type != bfd_link_hash_defined)
+                       continue;
                    }
 
                  sym_vma = (relocs[i]->addend
@@ -2077,8 +2104,9 @@ make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub)
   bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
 
   symptr = 0;
-  symtab = xmalloc (11 * sizeof (asymbol *));
-  tx  = quick_section (abfd, ".text",    SEC_CODE|SEC_HAS_CONTENTS, 2);
+  symtab = xmalloc (12 * sizeof (asymbol *));
+
+  tx  = quick_section (abfd, ".text", SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY, 2);
   id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
   id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
   id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
@@ -2127,6 +2155,9 @@ make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub)
 #ifdef pe_use_x86_64
          quick_reloc (abfd, 2, BFD_RELOC_32_PCREL, 2);
 #else
+         /* Mark this object as SAFESEH compatible.  */
+         quick_symbol (abfd, "", "@feat.00", "", bfd_abs_section_ptr,
+                       BSF_LOCAL, 1);
           quick_reloc (abfd, 2, BFD_RELOC_32, 2);
 #endif
          break;
@@ -2366,7 +2397,7 @@ make_import_fixup_mark (arelent *rel)
 static bfd *
 make_import_fixup_entry (const char *name,
                         const char *fixup_name,
-                        const char *dll_symname,
+                        const char *symname,
                         bfd *parent)
 {
   asection *id2;
@@ -2390,7 +2421,7 @@ make_import_fixup_entry (const char *name,
   id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2);
 
   quick_symbol (abfd, U ("_nm_thnk_"), name, "", UNDSEC, BSF_GLOBAL, 0);
-  quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
+  quick_symbol (abfd, U (""), symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
   /* For relocator v2 we have to use the .idata$5 element and not 
      fixup_name.  */
   if (link_info.pei386_runtime_pseudo_reloc == 2)
@@ -2574,7 +2605,7 @@ pe_create_import_fixup (arelent *rel, asection *s, bfd_vma addend)
   if (need_import_table == 1
       && (!name_thunk_sym || name_thunk_sym->type != bfd_link_hash_defined))
     {
-      bfd *b = make_singleton_name_thunk (name, link_info.output_bfd);
+      b = make_singleton_name_thunk (name, link_info.output_bfd);
       add_bfd_to_link (b, b->filename, &link_info);
 
       /* If we ever use autoimport, we have to cast text section writable.
@@ -2595,9 +2626,9 @@ pe_create_import_fixup (arelent *rel, asection *s, bfd_vma addend)
       && need_import_table == 1)
     {
       extern char * pe_data_import_dll;
-      char * dll_symname = pe_data_import_dll ? pe_data_import_dll : "unknown";
+      char * symname = pe_data_import_dll ? pe_data_import_dll : "unknown";
 
-      b = make_import_fixup_entry (name, fixup_name, dll_symname,
+      b = make_import_fixup_entry (name, fixup_name, symname,
                                   link_info.output_bfd);
       add_bfd_to_link (b, b->filename, &link_info);
     }
@@ -2793,7 +2824,7 @@ pe_find_cdecl_alias_match (char *name)
 }
 
 static void
-add_bfd_to_link (bfd *abfd, const char *name, struct bfd_link_info *link_info)
+add_bfd_to_link (bfd *abfd, const char *name, struct bfd_link_info *linfo)
 {
   lang_input_statement_type *fake_file;
 
@@ -2803,12 +2834,12 @@ add_bfd_to_link (bfd *abfd, const char *name, struct bfd_link_info *link_info)
   fake_file->the_bfd = abfd;
   ldlang_add_file (fake_file);
 
-  if (!bfd_link_add_symbols (abfd, link_info))
+  if (!bfd_link_add_symbols (abfd, linfo))
     einfo ("%Xaddsym %s: %E\n", name);
 }
 
 void
-pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *link_info)
+pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo)
 {
   def_file_module *module;
 
@@ -2850,7 +2881,7 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *link_info)
              sprintf (name, "%s%s",U (""),
                       pe_def_file->imports[i].internal_name);
 
-           blhe = bfd_link_hash_lookup (link_info->hash, name,
+           blhe = bfd_link_hash_lookup (linfo->hash, name,
                                         FALSE, FALSE, FALSE);
 
            /* Include the jump stub for <sym> only if the <sym>
@@ -2864,7 +2895,7 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *link_info)
                  sprintf (name, "%s%s%s", "__imp_", U (""),
                           pe_def_file->imports[i].internal_name);
 
-               blhe = bfd_link_hash_lookup (link_info->hash, name,
+               blhe = bfd_link_hash_lookup (linfo->hash, name,
                                             FALSE, FALSE, FALSE);
              }
            else
@@ -2887,7 +2918,7 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *link_info)
                if (!do_this_dll)
                  {
                    bfd *ar_head = make_head (output_bfd);
-                   add_bfd_to_link (ar_head, ar_head->filename, link_info);
+                   add_bfd_to_link (ar_head, ar_head->filename, linfo);
                    do_this_dll = 1;
                  }
                exp.internal_name = pe_def_file->imports[i].internal_name;
@@ -2900,13 +2931,13 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *link_info)
                exp.flag_data = pe_def_file->imports[i].data;
                exp.flag_noname = exp.name ? 0 : 1;
                one = make_one (&exp, output_bfd, (! exp.flag_data) && include_jmp_stub);
-               add_bfd_to_link (one, one->filename, link_info);
+               add_bfd_to_link (one, one->filename, linfo);
              }
          }
       if (do_this_dll)
        {
          bfd *ar_tail = make_tail (output_bfd);
-         add_bfd_to_link (ar_tail, ar_tail->filename, link_info);
+         add_bfd_to_link (ar_tail, ar_tail->filename, linfo);
        }
 
       free (dll_symname);
@@ -2955,7 +2986,7 @@ pe_implied_import_dll (const char *filename)
   unsigned char *expdata;
   char *erva;
   bfd_vma name_rvas, ordinals, nexp, ordbase;
-  const char *dll_name;
+  const char *dllname;
   /* Initialization with start > end guarantees that is_data
      will not be set by mistake, and avoids compiler warning.  */
   bfd_vma data_start = 1;
@@ -3094,15 +3125,15 @@ pe_implied_import_dll (const char *filename)
 
   /* Use internal dll name instead of filename
      to enable symbolic dll linking.  */
-  dll_name = erva + pe_as32 (expdata + 12);
+  dllname = erva + pe_as32 (expdata + 12);
 
   /* Check to see if the dll has already been added to
      the definition list and if so return without error.
      This avoids multiple symbol definitions.  */
-  if (def_get_module (pe_def_file, dll_name))
+  if (def_get_module (pe_def_file, dllname))
     {
       if (pe_dll_extra_pe_debug)
-       printf ("%s is already loaded\n", dll_name);
+       printf ("%s is already loaded\n", dllname);
       return TRUE;
     }
 
@@ -3128,13 +3159,13 @@ 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,
-                                    dll_name, i, 0, NULL);
+                                    dllname, i, 0, NULL);
          /* Mark symbol type.  */
          imp->data = is_data;
 
          if (pe_dll_extra_pe_debug)
            printf ("%s dll-name: %s sym: %s addr: 0x%lx %s\n",
-                   __FUNCTION__, dll_name, erva + name_rva,
+                   __FUNCTION__, dllname, erva + name_rva,
                    (unsigned long) func_rva, is_data ? "(data)" : "");
        }
     }
This page took 0.029185 seconds and 4 git commands to generate.