This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] Add --identify option to dlltool


To solve a problem with libtool on cygwin (dlpreopen), I needed a
mechanism to determine the DLL associated with a specified import
library. I was surprised to discover that there does not seem to be an
easy way to do this, so I added the functionality to dlltool.

$ dlltool --identify /usr/lib/libz.dll.a
cygz.dll

$ dlltool.exe --identify /usr/lib/mingw/libz.dll.a
mgwz.dll

--
Chuck
2008-11-08  Charles Wilson  <...>

	Add --identify option to dlltool.

	* binutils/dlltool.c: Added new global variables
	identify_imp_name and identify_dll_name.
	(identify_dll_for_implib, identify_search_archive,
	identify_search_member, identify_process_section_p,
	identify_search_section): New functions.
	(usage): Added --identify.
	(long_options): Ditto.
	(main): Handle --identify option.

Index: binutils/dlltool.c
===================================================================
RCS file: /cvs/src/src/binutils/dlltool.c,v
retrieving revision 1.83
diff -u -r1.83 dlltool.c
--- binutils/dlltool.c	9 Oct 2008 09:00:08 -0000	1.83
+++ binutils/dlltool.c	8 Nov 2008 05:18:41 -0000
@@ -352,6 +352,8 @@
 static int no_idata5;
 static char *exp_name;
 static char *imp_name;
+static char *identify_imp_name;
+static char *identify_dll_name;
 static char *head_label;
 static char *imp_name_lab;
 static char *dll_name;
@@ -724,6 +726,11 @@
 static bfd *make_head (void);
 static bfd *make_tail (void);
 static void gen_lib_file (void);
+static void identify_dll_for_implib (void);
+static void identify_search_archive (bfd*);
+static void identify_search_member (bfd*, bfd*);
+static bfd_boolean identify_process_section_p (asection *);
+static void identify_search_section (bfd *, asection *, void *);
 static int pfunc (const void *, const void *);
 static int nfunc (const void *, const void *);
 static void remove_null_names (export_type **);
@@ -2918,6 +2925,133 @@
   inform (_("Created lib file"));
 }
 
+static void
+identify_dll_for_implib (void)
+{
+  bfd* abfd = NULL;
+
+  bfd_init ();
+
+  abfd = bfd_openr (identify_imp_name, 0);
+  if (abfd == NULL)
+    {
+      bfd_fatal (identify_imp_name);
+    }
+  if (!bfd_check_format (abfd, bfd_archive))
+    {
+      if (!bfd_close (abfd))
+        bfd_fatal (identify_imp_name);
+
+      fatal ("%s is not a library.", identify_imp_name);
+    }
+
+  identify_search_archive (abfd);
+
+  if (!bfd_close (abfd))
+    bfd_fatal (identify_imp_name);
+
+  if (identify_dll_name && *identify_dll_name)
+    {
+      printf ("%s\n",identify_dll_name);
+      free (identify_dll_name);
+      identify_dll_name = NULL;
+    }
+  else
+    {
+      fatal ("Unable to determine dll name for %s (not an import library?)", identify_imp_name);
+    }
+}
+
+static void
+identify_search_archive (bfd* abfd)
+{
+  bfd *arfile = NULL;
+  bfd *last_arfile = NULL;
+  char **matching;
+
+  while (identify_dll_name == NULL)
+    {
+      arfile = bfd_openr_next_archived_file (abfd, arfile);
+
+      if (arfile == NULL)
+        {
+          if (bfd_get_error () != bfd_error_no_more_archived_files)
+            bfd_fatal (bfd_get_filename (abfd));
+          break;
+        }
+      if (bfd_check_format_matches (arfile, bfd_object, &matching))
+        {
+          identify_search_member (arfile, abfd);
+        }
+      else
+        {
+          bfd_nonfatal (bfd_get_filename (arfile));
+          free (matching);
+        }
+      if (last_arfile != NULL)
+        {
+          bfd_close (last_arfile);
+        }
+      last_arfile = arfile;
+    }
+
+  if (last_arfile != NULL)
+    {
+      bfd_close (last_arfile);
+    }
+}
+
+static void
+identify_search_member (bfd* abfd, bfd* archive_bfd ATTRIBUTE_UNUSED)
+{
+  bfd_map_over_sections (abfd, identify_search_section, NULL);
+}
+
+static bfd_boolean
+identify_process_section_p (asection * section)
+{
+  static const char * SECTION_NAME =
+#ifdef DLLTOOL_PPC
+  /* dllname is stored in idata$6 on PPC */
+  ".idata$6";
+#else
+  ".idata$7";
+#endif
+
+  if (strcmp (SECTION_NAME, section->name) == 0)
+    return TRUE;
+  return FALSE;
+}
+
+static void
+identify_search_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
+{
+  bfd_byte *data = 0;
+  bfd_size_type datasize;
+
+  if ((section->flags & SEC_HAS_CONTENTS) == 0)
+    return;
+
+  if (! identify_process_section_p (section))
+    return;
+
+  if ((datasize = bfd_section_size (abfd, section)) == 0)
+    return;
+
+  data = (bfd_byte*) xmalloc (datasize);
+  data[0] = '\0';
+
+  bfd_get_section_contents (abfd, section, data, 0, datasize);
+
+  if (data[0] != '\0')
+    {
+      free (identify_dll_name);
+      identify_dll_name = (char*) xstrdup (data);
+    }
+
+  free (data);
+}
+
 /* Run through the information gathered from the .o files and the
    .def file and work out the best stuff.  */
 
@@ -3171,6 +3305,7 @@
   fprintf (file, _("   -C --compat-implib        Create backward compatible import library.\n"));
   fprintf (file, _("   -n --no-delete            Keep temp files (repeat for extra preservation).\n"));
   fprintf (file, _("   -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n"));
+  fprintf (file, _("   -I --identify <implib>    Report the name of the DLL associated with <implib>.\n"));
   fprintf (file, _("   -v --verbose              Be verbose.\n"));
   fprintf (file, _("   -V --version              Display the program version.\n"));
   fprintf (file, _("   -h --help                 Display this information.\n"));
@@ -3211,6 +3346,7 @@
   {"kill-at", no_argument, NULL, 'k'},
   {"add-stdcall-alias", no_argument, NULL, 'A'},
   {"ext-prefix-alias", required_argument, NULL, 'p'},
+  {"identify", required_argument, NULL, 'I'},
   {"verbose", no_argument, NULL, 'v'},
   {"version", no_argument, NULL, 'V'},
   {"help", no_argument, NULL, 'h'},
@@ -3249,9 +3385,9 @@
 
   while ((c = getopt_long (ac, av,
 #ifdef DLLTOOL_MCORE_ELF
-			   "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nvVHhM:L:F:",
+			   "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHhM:L:F:",
 #else
-			   "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nvVHh",
+			   "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHh",
 #endif
 			   long_options, 0))
 	 != EOF)
@@ -3317,6 +3453,9 @@
 	case 'm':
 	  mname = optarg;
 	  break;
+	case 'I':
+	  identify_imp_name = optarg;
+	  break;
 	case 'v':
 	  verbose = 1;
 	  break;
@@ -3440,6 +3579,11 @@
   if (output_def)
     gen_def_file ();
 
+  if (identify_imp_name)
+    {
+      identify_dll_for_implib ();
+    }
+
 #ifdef DLLTOOL_MCORE_ELF
   if (mcore_elf_out_file)
     mcore_elf_gen_out_file ();

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]