Fix typo.
[deliverable/binutils-gdb.git] / ld / pe-dll.c
index cc69474d203d272f855e235d49b28fa2d1b6f780..81834ec4c95ecd0013ea574956e322f3a7c99c4f 100644 (file)
@@ -1,5 +1,6 @@
 /* Routines to help build PEI-format DLLs (Win32 etc)
-   Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Free Software Foundation, Inc.
    Written by DJ Delorie <dj@cygnus.com>
 
    This file is part of GLD, the Gnu Linker.
@@ -137,7 +138,7 @@ int pe_dll_extra_pe_debug = 0;
 
 static bfd_vma image_base;
 static bfd *filler_bfd;
-static struct sec *edata_s, *reloc_s;
+static struct bfd_section *edata_s, *reloc_s;
 static unsigned char *edata_d, *reloc_d;
 static size_t edata_sz, reloc_sz;
 static int runtime_pseudo_relocs_created = 0;
@@ -339,7 +340,7 @@ pe_export_sort (const void *va, const void *vb)
    defined, since we can't export symbols we don't have.  */
 
 static bfd_vma *exported_symbol_offsets;
-static struct sec **exported_symbol_sections;
+static struct bfd_section **exported_symbol_sections;
 static int export_table_size;
 static int count_exported;
 static int count_exported_byname;
@@ -397,7 +398,7 @@ auto_export (bfd *abfd, def_file *d, const char *n)
     libname = lbasename (abfd->my_archive->filename);
 
   /* We should not re-export imported stuff.  */
-  if (strncmp (n, "_imp__", 6) == 0)
+  if (strncmp (n, "_imp_", 5) == 0)
     return 0;
 
   for (i = 0; i < d->num_exports; i++)
@@ -501,7 +502,7 @@ process_def_file (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
   int i, j;
   struct bfd_link_hash_entry *blhe;
   bfd *b;
-  struct sec *s;
+  struct bfd_section *s;
   def_file_export *e = 0;
 
   if (!pe_def_file)
@@ -514,7 +515,7 @@ process_def_file (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
       s = bfd_get_section_by_name (b, ".drectve");
       if (s)
        {
-         int size = bfd_get_section_size_before_reloc (s);
+         long size = s->size;
          char *buf = xmalloc (size);
 
          bfd_get_section_contents (b, s, buf, 0, size);
@@ -526,7 +527,7 @@ process_def_file (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
   /* If we are not building a DLL, when there are no exports
      we do not build an export table at all.  */
   if (!pe_dll_export_everything && pe_def_file->num_exports == 0
-      && !info->shared)
+      && info->executable)
     return;
 
   /* Now, maybe export everything else the default way.  */
@@ -626,9 +627,9 @@ process_def_file (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
   e = pe_def_file->exports;
 
   exported_symbol_offsets = xmalloc (NE * sizeof (bfd_vma));
-  exported_symbol_sections = xmalloc (NE * sizeof (struct sec *));
+  exported_symbol_sections = xmalloc (NE * sizeof (struct bfd_section *));
 
-  memset (exported_symbol_sections, 0, NE * sizeof (struct sec *));
+  memset (exported_symbol_sections, 0, NE * sizeof (struct bfd_section *));
   max_ordinal = 0;
   min_ordinal = 65536;
   count_exported = 0;
@@ -916,10 +917,10 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
   int s, hint;
   unsigned char *edirectory;
-  unsigned long *eaddresses;
-  unsigned long *enameptrs;
-  unsigned short *eordinals;
-  unsigned char *enamestr;
+  unsigned char *eaddresses;
+  unsigned char *enameptrs;
+  unsigned char *eordinals;
+  char *enamestr;
   time_t now;
 
   time (&now);
@@ -928,10 +929,10 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
 
   /* Note use of array pointer math here.  */
   edirectory = edata_d;
-  eaddresses = (unsigned long *) (edata_d + 40);
-  enameptrs = eaddresses + export_table_size;
-  eordinals = (unsigned short *) (enameptrs + count_exported_byname);
-  enamestr = (char *) (eordinals + count_exported_byname);
+  eaddresses = edata_d + 40;
+  enameptrs = eaddresses + 4 * export_table_size;
+  eordinals = enameptrs + 4 * count_exported_byname;
+  enamestr = (char *) eordinals + 2 * count_exported_byname;
 
 #define ERVA(ptr) (((unsigned char *)(ptr) - edata_d) \
                   + edata_s->output_section->vma - image_base)
@@ -965,27 +966,27 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
   hint = 0;
   for (s = 0; s < NE; s++)
     {
-      if (pe_def_file->exports[s].ordinal != -1)
+      struct bfd_section *ssec = exported_symbol_sections[s];
+      if (ssec && pe_def_file->exports[s].ordinal != -1)
        {
-         struct sec *ssec = exported_symbol_sections[s];
          unsigned long srva = (exported_symbol_offsets[s]
                                + ssec->output_section->vma
                                + ssec->output_offset);
          int ord = pe_def_file->exports[s].ordinal;
 
          bfd_put_32 (abfd, srva - image_base,
-                     (void *) (eaddresses + ord - min_ordinal));
+                     eaddresses + 4 * (ord - min_ordinal));
 
          if (!pe_def_file->exports[s].flag_noname)
            {
              char *ename = pe_def_file->exports[s].name;
 
-             bfd_put_32 (abfd, ERVA (enamestr), (void *) enameptrs);
-             enameptrs++;
+             bfd_put_32 (abfd, ERVA (enamestr), enameptrs);
+             enameptrs += 4;
              strcpy (enamestr, ename);
              enamestr += strlen (enamestr) + 1;
-             bfd_put_16 (abfd, ord - min_ordinal, (void *) eordinals);
-             eordinals++;
+             bfd_put_16 (abfd, ord - min_ordinal, eordinals);
+             eordinals += 2;
              pe_def_file->exports[s].hint = hint++;
            }
        }
@@ -993,7 +994,7 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
 }
 
 
-static struct sec *current_sec;
+static struct bfd_section *current_sec;
 
 void
 pe_walk_relocs_of_symbol (struct bfd_link_info *info,
@@ -1031,7 +1032,7 @@ pe_walk_relocs_of_symbol (struct bfd_link_info *info,
 
          for (i = 0; i < nrelocs; i++)
            {
-             struct symbol_cache_entry *sym = *relocs[i]->sym_ptr_ptr;
+             struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
 
              if (!strcmp (name, sym->name))
                cb (relocs[i], s);
@@ -1060,7 +1061,7 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
   unsigned long page_ptr, page_count;
   int bi;
   bfd *b;
-  struct sec *s;
+  struct bfd_section *s;
 
   total_relocs = 0;
   for (b = info->input_bfds; b; b = b->link_next)
@@ -1112,14 +1113,14 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
            {
              if (pe_dll_extra_pe_debug)
                {
-                 struct symbol_cache_entry *sym = *relocs[i]->sym_ptr_ptr;
+                 struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
                  printf ("rel: %s\n", sym->name);
                }
              if (!relocs[i]->howto->pc_relative
                  && relocs[i]->howto->type != pe_details->imagebase_reloc)
                {
                  bfd_vma sym_vma;
-                 struct symbol_cache_entry *sym = *relocs[i]->sym_ptr_ptr;
+                 struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
 
                  sym_vma = (relocs[i]->addend
                             + sym->value
@@ -1155,7 +1156,12 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
                      total_relocs++;
                      break;
                    case BITS_AND_SHIFT (24, 2):
-                     if (relocs[i]->howto->type == 5)
+                     /* FIXME: 0 is ARM_26D, it is defined in bfd/coff-arm.c
+                        Those ARM_xxx definitions should go in proper
+                        header someday.  */
+                     if (relocs[i]->howto->type == 0
+                         /* Older GNU linkers used 5 instead of 0 for this reloc.  */
+                         || relocs[i]->howto->type == 5)
                        /* This is an ARM_26D reloc, which is an ARM_26 reloc
                           that has already been fully processed during a
                           previous link stage, so ignore it here.  */
@@ -1172,9 +1178,6 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
          free (relocs);
          /* Warning: the allocated symbols are remembered in BFD and
             reused later, so don't free them!  */
-#if 0
-         free (symbol);
-#endif
        }
     }
 
@@ -1246,7 +1249,7 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
   if (page_ptr != (unsigned long) -1)
     bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4);
 
-  while (reloc_sz < reloc_s->_raw_size)
+  while (reloc_sz < reloc_s->size)
     reloc_d[reloc_sz++] = 0;
 }
 
@@ -1668,7 +1671,7 @@ make_tail (bfd *parent)
   bfd_set_section_size (abfd, id7, len);
   d7 = xmalloc (len);
   id7->contents = d7;
-  strcpy (d7, dll_filename);
+  strcpy ((char *) d7, dll_filename);
 
   bfd_set_symtab (abfd, symtab, symptr);
 
@@ -1891,7 +1894,7 @@ make_one (def_file_export *exp, bfd *parent)
       memset (d6, 0, len);
       d6[0] = exp->hint & 0xff;
       d6[1] = exp->hint >> 8;
-      strcpy (d6 + 2, exp->name);
+      strcpy ((char *) d6 + 2, exp->name);
     }
 
   bfd_set_symtab (abfd, symtab, symptr);
@@ -1956,7 +1959,7 @@ make_import_fixup_mark (arelent *rel)
   static char *fixup_name = NULL;
   static size_t buffer_len = 0;
 
-  struct symbol_cache_entry *sym = *rel->sym_ptr_ptr;
+  struct bfd_symbol *sym = *rel->sym_ptr_ptr;
 
   bfd *abfd = bfd_asymbol_bfd (sym);
   struct bfd_link_hash_entry *bh;
@@ -2031,9 +2034,6 @@ make_import_fixup_entry (const char *name,
   symtab = xmalloc (6 * sizeof (asymbol *));
   id3 = quick_section (abfd, ".idata$3", SEC_HAS_CONTENTS, 2);
 
-#if 0
-  quick_symbol (abfd, U ("_head_"), dll_symname, "", id2, BSF_GLOBAL, 0);
-#endif
   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, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
@@ -2154,7 +2154,7 @@ void
 pe_create_import_fixup (arelent *rel, asection *s, int addend)
 {
   char buf[300];
-  struct symbol_cache_entry *sym = *rel->sym_ptr_ptr;
+  struct bfd_symbol *sym = *rel->sym_ptr_ptr;
   struct bfd_link_hash_entry *name_thunk_sym;
   const char *name = sym->name;
   char *fixup_name = make_import_fixup_mark (rel);
@@ -2171,6 +2171,7 @@ pe_create_import_fixup (arelent *rel, asection *s, int addend)
 
       /* If we ever use autoimport, we have to cast text section writable.  */
       config.text_read_only = FALSE;
+      output_bfd->flags &= ~WP_TEXT;   
     }
 
   if (addend == 0 || link_info.pei386_runtime_pseudo_reloc)
@@ -2224,7 +2225,7 @@ pe_dll_generate_implib (def_file *def, const char *impfilename)
     if (!ISALNUM (dll_symname[i]))
       dll_symname[i] = '_';
 
-  unlink (impfilename);
+  unlink_if_ordinary (impfilename);
 
   outarch = bfd_openw (impfilename, 0);
 
@@ -2250,6 +2251,9 @@ pe_dll_generate_implib (def_file *def, const char *impfilename)
       char *internal = def->exports[i].internal_name;
       bfd *n;
 
+      /* Don't add PRIVATE entries to import lib.  */  
+      if (pe_def_file->exports[i].flag_private)
+       continue;
       def->exports[i].internal_name = def->exports[i].name;
       n = make_one (def->exports + i, outarch);
       n->next = head;
@@ -2408,18 +2412,6 @@ pe_get32 (bfd *abfd, int where)
   return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
 }
 
-#if 0 /* This is not currently used.  */
-
-static unsigned int
-pe_as16 (void *ptr)
-{
-  unsigned char *b = ptr;
-
-  return b[0] + (b[1] << 8);
-}
-
-#endif
-
 static unsigned int
 pe_as32 (void *ptr)
 {
@@ -2435,15 +2427,18 @@ pe_implied_import_dll (const char *filename)
   unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
   unsigned long export_rva, export_size, nsections, secptr, expptr;
   unsigned long exp_funcbase;
-  unsigned char *expdata, *erva;
+  unsigned char *expdata;
+  char *erva;
   unsigned long name_rvas, ordinals, nexp, ordbase;
   const char *dll_name;
   /* Initialization with start > end guarantees that is_data
      will not be set by mistake, and avoids compiler warning.  */
   unsigned long data_start = 1;
-  unsigned long data_end   = 0;
-  unsigned long bss_start  = 1;
-  unsigned long bss_end    = 0;
+  unsigned long data_end = 0;
+  unsigned long rdata_start = 1;
+  unsigned long rdata_end = 0;
+  unsigned long bss_start = 1;
+  unsigned long bss_end = 0;
 
   /* No, I can't use bfd here.  kernel32.dll puts its export table in
      the middle of the .rdata section.  */
@@ -2516,6 +2511,15 @@ pe_implied_import_dll (const char *filename)
          data_start = vaddr;
          data_end = vaddr + vsize;
 
+         if (pe_dll_extra_pe_debug)
+           printf ("%s %s: 0x%08lx-0x%08lx (0x%08lx)\n",
+                   __FUNCTION__, sec_name, vaddr, vaddr + vsize, flags);
+       }
+      else if (strcmp(sec_name,".rdata") == 0)
+       {
+         rdata_start = vaddr;
+         rdata_end = vaddr + vsize;
+
          if (pe_dll_extra_pe_debug)
            printf ("%s %s: 0x%08lx-0x%08lx (0x%08lx)\n",
                    __FUNCTION__, sec_name, vaddr, vaddr + vsize, flags);
@@ -2534,7 +2538,7 @@ pe_implied_import_dll (const char *filename)
   expdata = xmalloc (export_size);
   bfd_seek (dll, (file_ptr) expptr, SEEK_SET);
   bfd_bread (expdata, (bfd_size_type) export_size, dll);
-  erva = expdata - export_rva;
+  erva = (char *) expdata - export_rva;
 
   if (pe_def_file == 0)
     pe_def_file = def_file_empty ();
@@ -2547,7 +2551,7 @@ pe_implied_import_dll (const char *filename)
 
   /* Use internal dll name instead of filename
      to enable symbolic dll linking.  */
-  dll_name = pe_as32 (expdata + 12) + erva;
+  dll_name = 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.
@@ -2573,9 +2577,11 @@ pe_implied_import_dll (const char *filename)
         exported in buggy auto-import releases.  */
       if (strncmp (erva + name_rva, "_nm_", 4) != 0)
        {
-         /* is_data is true if the address is in the data or bss segment.  */
+         /* is_data is true if the address is in the data, rdata or bss
+            segment.  */
          is_data =
            (func_rva >= data_start && func_rva < data_end)
+           || (func_rva >= rdata_start && func_rva < rdata_end)
            || (func_rva >= bss_start && func_rva < bss_end);
 
          imp = def_file_add_import (pe_def_file, erva + name_rva,
@@ -2642,7 +2648,7 @@ pe_dll_fill_sections (bfd *abfd, struct bfd_link_info *info)
 
   fill_edata (abfd, info);
 
-  if (info->shared)
+  if (info->shared && !info->pie)
     pe_data (abfd)->dll = 1;
 
   edata_s->contents = edata_d;
This page took 0.029356 seconds and 4 git commands to generate.