* pe-dll.c (process_def_file): properly note undefined exported
authorDJ Delorie <dj@redhat.com>
Tue, 10 Nov 1998 22:57:13 +0000 (22:57 +0000)
committerDJ Delorie <dj@redhat.com>
Tue, 10 Nov 1998 22:57:13 +0000 (22:57 +0000)
  symbols, clean up old code.
(pe_dll_generate_def_file): don't crash if pe_def_file is NULL
* emultempl/pe.em (gld_i386_parse_args): add
  (en/dis)able-stdcall-fixups
(pe_fixup_stdcalls): warn about stdcall fixups
(gld_i386_unrecognized_file): make exported symbols undefs so that
  archive members get pulled in

ld/ChangeLog
ld/emultempl/pe.em
ld/pe-dll.c

index ca69682a58dfeca7f158b8d8555976f92ba74331..57c4cd1729cafe91c52f88436e9ed7fb7c7a35e6 100644 (file)
@@ -1,3 +1,14 @@
+Tue Nov 10 17:53:17 1998  DJ Delorie  <dj@cygnus.com>
+
+       * pe-dll.c (process_def_file): properly note undefined exported
+       symbols, clean up old code.
+       (pe_dll_generate_def_file): don't crash if pe_def_file is NULL
+       * emultempl/pe.em (gld_i386_parse_args): add
+       (en/dis)able-stdcall-fixups
+       (pe_fixup_stdcalls): warn about stdcall fixups
+       (gld_i386_unrecognized_file): make exported symbols undefs so that
+       archive members get pulled in
+
 Tue Nov 10 14:50:51 1998  Catherine Moore  <clm@cygnus.com>
 
         * scripttempl/elfd10v.sc: Add KEEP attribute to .init,
index dafd7eeff8b5f64268ab8721330d1f6873123047..34f6f7ae1f15492304b663a66a4c463ebd5f3edb 100644 (file)
@@ -69,6 +69,7 @@ int pe_dll_export_everything = 0;
 int pe_dll_do_default_excludes = 1;
 int pe_dll_kill_ats = 0;
 int pe_dll_stdcall_aliases = 0;
+int pe_enable_stdcall_fixup = -1; /* 0=disable 1=enable */
 
 extern const char *output_filename;
 
@@ -105,6 +106,8 @@ gld_${EMULATION_NAME}_before_parse()
 #define OPTION_EXCLUDE_SYMBOLS         (OPTION_EXPORT_ALL + 1)
 #define OPTION_KILL_ATS                        (OPTION_EXCLUDE_SYMBOLS + 1)
 #define OPTION_STDCALL_ALIASES         (OPTION_KILL_ATS + 1)
+#define OPTION_ENABLE_STDCALL_FIXUP    (OPTION_STDCALL_ALIASES + 1)
+#define OPTION_DISABLE_STDCALL_FIXUP   (OPTION_ENABLE_STDCALL_FIXUP + 1)
 
 static struct option longopts[] =
 {
@@ -132,6 +135,8 @@ static struct option longopts[] =
   {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMBOLS},
   {"kill-at", no_argument, NULL, OPTION_KILL_ATS},
   {"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES},
+  {"enable-stdcall-fixup", no_argument, NULL, OPTION_ENABLE_STDCALL_FIXUP},
+  {"disable-stdcall-fixup", no_argument, NULL, OPTION_DISABLE_STDCALL_FIXUP},
   {NULL, no_argument, NULL, 0}
 };
 
@@ -198,6 +203,8 @@ gld_${EMULATION_NAME}_list_options (file)
   fprintf (file, _("  --exclude-symbols sym,sym,...      Exclude symbols from automatic export\n"));
   fprintf (file, _("  --kill-at                          Remove @nn from exported symbols\n"));
   fprintf (file, _("  --add-stdcall-alias                Export symbols with and without @nn\n"));
+  fprintf (file, _("  --enable-stdcall-fixup             Link _sym to _sym@nn without warnings\n"));
+  fprintf (file, _("  --disable-stdcall-fixup            Don't link _sym to _sym@nn\n"));
 }
 
 static void
@@ -411,6 +418,12 @@ gld_${EMULATION_NAME}_parse_args(argc, argv)
     case OPTION_STDCALL_ALIASES:
       pe_dll_stdcall_aliases = 1;
       break;
+    case OPTION_ENABLE_STDCALL_FIXUP:
+      pe_enable_stdcall_fixup = 1;
+      break;
+    case OPTION_DISABLE_STDCALL_FIXUP:
+      pe_enable_stdcall_fixup = 0;
+      break;
     }
   return 1;
 }
@@ -516,6 +529,7 @@ pe_undef_cdecl_match (h, string)
 static void
 pe_fixup_stdcalls ()
 {
+  static int gave_warning_message = 0;
   struct bfd_link_hash_entry *undef, *sym;
   char *at;
   for (undef = link_info.hash->undefs; undef; undef=undef->next)
@@ -535,6 +549,17 @@ pe_fixup_stdcalls ()
          undef->type = bfd_link_hash_defined;
          undef->u.def.value = sym->u.def.value;
          undef->u.def.section = sym->u.def.section;
+         if (pe_enable_stdcall_fixup == -1)
+           {
+             einfo (_("Warning: resolving %s by linking to %s\n"),
+                    undef->root.string, cname);
+             if (! gave_warning_message)
+               {
+                 gave_warning_message = 1;
+                 einfo(_("Use --enable-stdcall-fixup to disable these warnings\n"));
+                 einfo(_("Use --disable-stdcall-fixup to disable these fixups\n"));
+               }
+           }
        }
       }
       else
@@ -550,6 +575,17 @@ pe_fixup_stdcalls ()
          undef->type = bfd_link_hash_defined;
          undef->u.def.value = sym->u.def.value;
          undef->u.def.section = sym->u.def.section;
+         if (pe_enable_stdcall_fixup == -1)
+           {
+             einfo (_("Warning: resolving %s by linking to %s\n"),
+                    undef->root.string, sym->root.string);
+             if (! gave_warning_message)
+               {
+                 gave_warning_message = 1;
+                 einfo(_("Use --enable-stdcall-fixup to disable these warnings\n"));
+                 einfo(_("Use --disable-stdcall-fixup to disable these fixups\n"));
+               }
+           }
        }
       }
     }
@@ -568,7 +604,8 @@ gld_${EMULATION_NAME}_after_open ()
   pe_data (output_bfd)->pe_opthdr = pe;
   pe_data (output_bfd)->dll = init[DLLOFF].value;
 
-  pe_fixup_stdcalls ();
+  if (pe_enable_stdcall_fixup) /* -1=warn or 1=disable */
+    pe_fixup_stdcalls ();
 
 #ifdef TARGET_IS_i386pe
   if (link_info.shared)
@@ -660,6 +697,32 @@ gld_${EMULATION_NAME}_unrecognized_file(entry)
     def_file_parse (entry->filename, pe_def_file);
     if (pe_def_file)
     {
+      int i, buflen=0, len;
+      char *buf;
+      for (i=0; i<pe_def_file->num_exports; i++)
+       {
+         len = strlen(pe_def_file->exports[i].internal_name);
+         if (buflen < len+2)
+           buflen = len+2;
+       }
+      buf = (char *) xmalloc (buflen);
+      for (i=0; i<pe_def_file->num_exports; i++)
+       {
+         struct bfd_link_hash_entry *h;
+         sprintf(buf, "_%s", pe_def_file->exports[i].internal_name);
+
+         h = bfd_link_hash_lookup (link_info.hash, buf, true, true, true);
+         if (h == (struct bfd_link_hash_entry *) NULL)
+           einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
+         if (h->type == bfd_link_hash_new)
+           {
+             h->type = bfd_link_hash_undefined;
+             h->u.undef.abfd = NULL;
+             bfd_link_add_undef (link_info.hash, h);
+           }
+       }
+      free (buf);
+
       /* def_file_print (stdout, pe_def_file); */
       if (pe_def_file->is_dll == 1)
        link_info.shared = 1;
index d2f77f33176eabceeedbec93eddf4a8f80ae9a4c..25ea4e3de667dc20a536fb35d79872768f22ea4c 100644 (file)
@@ -342,12 +342,19 @@ process_def_file (abfd, info)
              count_with_ordinals++;
            }
        }
-      else if (blhe)
+      else if (blhe && blhe->type == bfd_link_hash_undefined)
        {
          /* xgettext:c-format */
-         einfo (_("%XCannot export %s: symbol wrong type\n"),
+         einfo (_("%XCannot export %s: symbol not defined\n"),
                 pe_def_file->exports[i].internal_name);
        }
+      else if (blhe)
+       {
+         /* xgettext:c-format */
+         einfo (_("%XCannot export %s: symbol wrong type (%d vs %d)\n"),
+                pe_def_file->exports[i].internal_name,
+                blhe->type, bfd_link_hash_defined);
+       }
       else
        {
          /* xgettext:c-format */
@@ -356,19 +363,6 @@ process_def_file (abfd, info)
        }
       free(name);
     }
-
-#if 0
-  /* For now, just export all global functions.  Read DEF files later */
-  for (i = 0; i < num_input_bfds; i++)
-    {
-      for (j = 0; j < symtab[i].nsyms; j++)
-       {
-         if ((symtab[i].symbols[j]->flags & (BSF_FUNCTION | BSF_GLOBAL))
-             == (BSF_FUNCTION | BSF_GLOBAL))
-           symtab[i].exported[j] = 1;
-       }
-    }
-#endif
 }
 
 /************************************************************************
@@ -755,119 +749,124 @@ pe_dll_generate_def_file (pe_out_def_filename)
             program_name, pe_out_def_filename);
     }
 
-  if (pe_def_file->name)
+  if (pe_def_file)
     {
-      if (pe_def_file->is_dll)
-       fprintf (out, "LIBRARY ");
-      else
-       fprintf (out, "NAME ");
-      quoteput (pe_def_file->name, out, 1);
-      if (pe_def_file->base_address != (bfd_vma) (-1))
-       fprintf (out, " BASE=0x%x", pe_def_file->base_address);
-      fprintf (out, "\n");
-    }
+      if (pe_def_file->name)
+       {
+         if (pe_def_file->is_dll)
+           fprintf (out, "LIBRARY ");
+         else
+           fprintf (out, "NAME ");
+         quoteput (pe_def_file->name, out, 1);
+         if (pe_def_file->base_address != (bfd_vma) (-1))
+           fprintf (out, " BASE=0x%x", pe_def_file->base_address);
+         fprintf (out, "\n");
+       }
 
-  if (pe_def_file->description)
-    {
-      fprintf (out, "DESCRIPTION ");
-      quoteput (pe_def_file->description, out, 1);
-      fprintf (out, "\n");
-    }
+      if (pe_def_file->description)
+       {
+         fprintf (out, "DESCRIPTION ");
+         quoteput (pe_def_file->description, out, 1);
+         fprintf (out, "\n");
+       }
 
-  if (pe_def_file->version_minor)
-    fprintf (out, "VERSION %d.%d\n", pe_def_file->version_major,
-            pe_def_file->version_minor);
-  else
-    fprintf (out, "VERSION %d\n", pe_def_file->version_major);
-
-  if (pe_def_file->stack_reserve != -1 || pe_def_file->heap_reserve != -1)
-    fprintf (out, "\n");
-
-  if (pe_def_file->stack_commit != -1)
-    fprintf (out, "STACKSIZE 0x%x,0x%x\n",
-            pe_def_file->stack_reserve, pe_def_file->stack_commit);
-  else if (pe_def_file->stack_reserve != -1)
-    fprintf (out, "STACKSIZE 0x%x\n", pe_def_file->stack_reserve);
-  if (pe_def_file->heap_commit != -1)
-    fprintf (out, "HEAPSIZE 0x%x,0x%x\n",
-            pe_def_file->heap_reserve, pe_def_file->heap_commit);
-  else if (pe_def_file->heap_reserve != -1)
-    fprintf (out, "HEAPSIZE 0x%x\n", pe_def_file->heap_reserve);
-
-  if (pe_def_file->num_section_defs > 0)
-    {
-      fprintf (out, "\nSECTIONS\n\n");
-      for (i = 0; i < pe_def_file->num_section_defs; i++)
+      if (pe_def_file->version_minor)
+       fprintf (out, "VERSION %d.%d\n", pe_def_file->version_major,
+                pe_def_file->version_minor);
+      else
+       fprintf (out, "VERSION %d\n", pe_def_file->version_major);
+
+      if (pe_def_file->stack_reserve != -1 || pe_def_file->heap_reserve != -1)
+       fprintf (out, "\n");
+
+      if (pe_def_file->stack_commit != -1)
+       fprintf (out, "STACKSIZE 0x%x,0x%x\n",
+                pe_def_file->stack_reserve, pe_def_file->stack_commit);
+      else if (pe_def_file->stack_reserve != -1)
+       fprintf (out, "STACKSIZE 0x%x\n", pe_def_file->stack_reserve);
+      if (pe_def_file->heap_commit != -1)
+       fprintf (out, "HEAPSIZE 0x%x,0x%x\n",
+                pe_def_file->heap_reserve, pe_def_file->heap_commit);
+      else if (pe_def_file->heap_reserve != -1)
+       fprintf (out, "HEAPSIZE 0x%x\n", pe_def_file->heap_reserve);
+
+      if (pe_def_file->num_section_defs > 0)
        {
-         fprintf (out, "    ");
-         quoteput (pe_def_file->section_defs[i].name, out, 0);
-         if (pe_def_file->section_defs[i].class)
+         fprintf (out, "\nSECTIONS\n\n");
+         for (i = 0; i < pe_def_file->num_section_defs; i++)
            {
-             fprintf (out, " CLASS ");
-             quoteput (pe_def_file->section_defs[i].class, out, 0);
+             fprintf (out, "    ");
+             quoteput (pe_def_file->section_defs[i].name, out, 0);
+             if (pe_def_file->section_defs[i].class)
+               {
+                 fprintf (out, " CLASS ");
+                 quoteput (pe_def_file->section_defs[i].class, out, 0);
+               }
+             if (pe_def_file->section_defs[i].flag_read)
+               fprintf (out, " READ");
+             if (pe_def_file->section_defs[i].flag_write)
+               fprintf (out, " WRITE");
+             if (pe_def_file->section_defs[i].flag_execute)
+               fprintf (out, " EXECUTE");
+             if (pe_def_file->section_defs[i].flag_shared)
+               fprintf (out, " SHARED");
+             fprintf (out, "\n");
            }
-         if (pe_def_file->section_defs[i].flag_read)
-           fprintf (out, " READ");
-         if (pe_def_file->section_defs[i].flag_write)
-           fprintf (out, " WRITE");
-         if (pe_def_file->section_defs[i].flag_execute)
-           fprintf (out, " EXECUTE");
-         if (pe_def_file->section_defs[i].flag_shared)
-           fprintf (out, " SHARED");
-         fprintf (out, "\n");
        }
-    }
 
-  if (pe_def_file->num_exports > 0)
-    {
-      fprintf (out, "\nEXPORTS\n\n");
-      for (i = 0; i < pe_def_file->num_exports; i++)
+      if (pe_def_file->num_exports > 0)
        {
-         def_file_export *e = pe_def_file->exports + i;
-         fprintf (out, "    ");
-         quoteput (e->name, out, 0);
-         if (e->internal_name && strcmp (e->internal_name, e->name))
+         fprintf (out, "\nEXPORTS\n\n");
+         for (i = 0; i < pe_def_file->num_exports; i++)
            {
-             fprintf (out, " = ");
-             quoteput (e->internal_name, out, 0);
+             def_file_export *e = pe_def_file->exports + i;
+             fprintf (out, "    ");
+             quoteput (e->name, out, 0);
+             if (e->internal_name && strcmp (e->internal_name, e->name))
+               {
+                 fprintf (out, " = ");
+                 quoteput (e->internal_name, out, 0);
+               }
+             if (e->ordinal != -1)
+               fprintf (out, " @%d", e->ordinal);
+             if (e->flag_private)
+               fprintf (out, " PRIVATE");
+             if (e->flag_constant)
+               fprintf (out, " CONSTANT");
+             if (e->flag_noname)
+               fprintf (out, " NONAME");
+             if (e->flag_data)
+               fprintf (out, " DATA");
+
+             fprintf (out, "\n");
            }
-         if (e->ordinal != -1)
-           fprintf (out, " @%d", e->ordinal);
-         if (e->flag_private)
-           fprintf (out, " PRIVATE");
-         if (e->flag_constant)
-           fprintf (out, " CONSTANT");
-         if (e->flag_noname)
-           fprintf (out, " NONAME");
-         if (e->flag_data)
-           fprintf (out, " DATA");
-
-         fprintf (out, "\n");
        }
-    }
 
-  if (pe_def_file->num_imports > 0)
-    {
-      fprintf (out, "\nIMPORTS\n\n");
-      for (i = 0; i < pe_def_file->num_imports; i++)
+      if (pe_def_file->num_imports > 0)
        {
-         def_file_import *im = pe_def_file->imports + i;
-         fprintf (out, "    ");
-         if (im->internal_name
-             && (!im->name || strcmp (im->internal_name, im->name)))
+         fprintf (out, "\nIMPORTS\n\n");
+         for (i = 0; i < pe_def_file->num_imports; i++)
            {
-             quoteput (im->internal_name, out, 0);
-             fprintf (out, " = ");
+             def_file_import *im = pe_def_file->imports + i;
+             fprintf (out, "    ");
+             if (im->internal_name
+                 && (!im->name || strcmp (im->internal_name, im->name)))
+               {
+                 quoteput (im->internal_name, out, 0);
+                 fprintf (out, " = ");
+               }
+             quoteput (im->module->name, out, 0);
+             fprintf (out, ".");
+             if (im->name)
+               quoteput (im->name, out, 0);
+             else
+               fprintf (out, "%d", im->ordinal);
+             fprintf (out, "\n");
            }
-         quoteput (im->module->name, out, 0);
-         fprintf (out, ".");
-         if (im->name)
-           quoteput (im->name, out, 0);
-         else
-           fprintf (out, "%d", im->ordinal);
-         fprintf (out, "\n");
        }
     }
+  else
+    fprintf (out, _("; no contents available\n"));
 
   if (fclose (out) == EOF)
     {