This is the mail archive of the binutils@sources.redhat.com 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] Strip path components from internal dll name


Hello,

Using a path-qualified filename as the internal dll name in the
.idata{6|7} section of the tail onject of a dll import lib can cause
problems when freeing the library handle if the dll loads another dll
using a LoadLibrary() call. A somewhat complicated example of this is
given in the testcase accompanying this bug report to mingw:

https://sourceforge.net/tracker/?func=detail&atid=102435&aid=1047100&group_id=2435

I don't know if putting a path-qualified name in the .edata section could also
cause problems, but I have never seen a MS-linker built dll with such an internal name.  

The MS utilities avoid the import lib problem by disallowing pathnames
as a NAME or LIBRARY arg in a .def file. For example, with this def file

LIBRARY "c:/foo.dll"
EXPORTS
  foo

the comamnd 
lib /MACHINE:IX86 /DEF:foo.def

results in following:
foo.def : warning LNK4093: Drive/Directory component ignored in "LIBRARY" statement
   Creating library foo.lib and object foo.exp

The following patch does same for ld and dlltool.

When building a dll with ld --shared, the name of the image is
only specified in a def file, otherwise it is inferred from the basename of
the output dll or exe.  So there is only one place to warn the user
about stripping path components.  With dlltool, there are three places where
we could set dll_name:  with --dllname command line switch, with a def
file specification, or by inference from the name of an output .exp
file.  I have used lbasename in each of these three places separately,
to allow differentiation of warning messages.  Some of the common code
could be factored out a bit more.

While doing this I noticed that the variable d_name is assigned a value
but never actually used for anything, so I have removed it.

Danny

ld/ChangeLog

2005-01-16  Danny Smith  <dannysmith@users.sourceforge.net>

	* defilep.y (def_name, def_library): Combine into...
	(def_image_name): New function. Strip name to basename,
	with warning.

binutils/ChangeLog

2005-01-16  Danny Smith  <dannysmith@users.sourceforge.net>

	* dlltool.c (set_dll_name_from_def): New function. Strip name
	to basename, with warning.
	(def_name): Use it. 
	(def_library): Likwise.
	(main): Strip arg of --dllname to basename, with warning.
	Only use basename of exp_name when inferring dll_name.

	(d_name): Remove static variable, throughout.

Index: src/ld/deffilep.y
===================================================================
RCS file: /cvs/src/src/ld/deffilep.y,v
retrieving revision 1.17
diff -c -3 -p -r1.17 deffilep.y
*** src/ld/deffilep.y	19 Oct 2003 15:21:31 -0000	1.17
--- src/ld/deffilep.y	15 Jan 2005 08:19:10 -0000
*************** static void def_exports (const char *, c
*** 83,90 ****
  static void def_heapsize (int, int);
  static void def_import (const char *, const char *, const char *, const char *,
  			int);
! static void def_library (const char *, int);
! static void def_name (const char *, int);
  static void def_section (const char *, int);
  static void def_section_alt (const char *, const char *);
  static void def_stacksize (int, int);
--- 83,89 ----
  static void def_heapsize (int, int);
  static void def_import (const char *, const char *, const char *, const char *,
  			int);
! static void def_image_name (const char *, int, int);
  static void def_section (const char *, int);
  static void def_section_alt (const char *, const char *);
  static void def_stacksize (int, int);
*************** start: start command
*** 122,129 ****
  	;
  
  command: 
! 		NAME opt_name opt_base { def_name ($2, $3); }
! 	|	LIBRARY opt_name opt_base { def_library ($2, $3); }
  	|	DESCRIPTION ID { def_description ($2);}
  	|	STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
  	|	HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
--- 121,128 ----
  	;
  
  command: 
! 		NAME opt_name opt_base { def_image_name ($2, $3, 0); }
! 	|	LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
  	|	DESCRIPTION ID { def_description ($2);}
  	|	STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
  	|	HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
*************** def_file_add_directive (def_file *my_def
*** 647,669 ****
  /* Parser Callbacks.  */
  
  static void
! def_name (const char *name, int base)
  {
    if (def->name)
      free (def->name);
!   def->name = xstrdup (name);
    def->base_address = base;
!   def->is_dll = 0;
! }
! 
! static void
! def_library (const char *name, int base)
! {
!   if (def->name)
!     free (def->name);
!   def->name = xstrdup (name);
!   def->base_address = base;
!   def->is_dll = 1;
  }
  
  static void
--- 646,662 ----
  /* Parser Callbacks.  */
  
  static void
! def_image_name (const char *name, int base, int is_dll)
  {
+   const char* image_name = lbasename (name);
+   if (image_name != name)
+     einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
+ 	  def_filename, linenumber, is_dll ? "LIBRARY" : "NAME", name);
    if (def->name)
      free (def->name);
!   def->name = xstrdup (image_name);
    def->base_address = base;
!   def->is_dll = is_dll;
  }
  
  static void
Index: src/ld/deffilep.y
===================================================================
RCS file: /cvs/src/src/ld/deffilep.y,v
retrieving revision 1.17
diff -c -3 -p -r1.17 deffilep.y
*** src/ld/deffilep.y	19 Oct 2003 15:21:31 -0000	1.17
--- src/ld/deffilep.y	15 Jan 2005 08:29:49 -0000
*************** static void def_exports (const char *, c
*** 83,90 ****
  static void def_heapsize (int, int);
  static void def_import (const char *, const char *, const char *, const char *,
  			int);
! static void def_library (const char *, int);
! static void def_name (const char *, int);
  static void def_section (const char *, int);
  static void def_section_alt (const char *, const char *);
  static void def_stacksize (int, int);
--- 83,89 ----
  static void def_heapsize (int, int);
  static void def_import (const char *, const char *, const char *, const char *,
  			int);
! static void def_image_name (const char *, int, int);
  static void def_section (const char *, int);
  static void def_section_alt (const char *, const char *);
  static void def_stacksize (int, int);
*************** start: start command
*** 122,129 ****
  	;
  
  command: 
! 		NAME opt_name opt_base { def_name ($2, $3); }
! 	|	LIBRARY opt_name opt_base { def_library ($2, $3); }
  	|	DESCRIPTION ID { def_description ($2);}
  	|	STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
  	|	HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
--- 121,128 ----
  	;
  
  command: 
! 		NAME opt_name opt_base { def_image_name ($2, $3, 0); }
! 	|	LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
  	|	DESCRIPTION ID { def_description ($2);}
  	|	STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
  	|	HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
*************** def_file_add_directive (def_file *my_def
*** 647,669 ****
  /* Parser Callbacks.  */
  
  static void
! def_name (const char *name, int base)
  {
    if (def->name)
      free (def->name);
!   def->name = xstrdup (name);
    def->base_address = base;
!   def->is_dll = 0;
! }
! 
! static void
! def_library (const char *name, int base)
! {
!   if (def->name)
!     free (def->name);
!   def->name = xstrdup (name);
!   def->base_address = base;
!   def->is_dll = 1;
  }
  
  static void
--- 646,662 ----
  /* Parser Callbacks.  */
  
  static void
! def_image_name (const char *name, int base, int is_dll)
  {
+   const char* image_name = lbasename (name);
+   if (image_name != name)
+     einfo ("%s:%d: Warning: path components stripped from %s '%s'\n",
+ 	  def_filename, linenumber, is_dll ? "LIBRARY" : "NAME", name);
    if (def->name)
      free (def->name);
!   def->name = xstrdup (image_name);
    def->base_address = base;
!   def->is_dll = is_dll;
  }
  
  static void
Index: src/binutils/dlltool.c
===================================================================
RCS file: /cvs/src/src/binutils/dlltool.c,v
retrieving revision 1.56
diff -c -3 -p -r1.56 dlltool.c
*** src/binutils/dlltool.c	6 Dec 2004 05:45:27 -0000	1.56
--- src/binutils/dlltool.c	15 Jan 2005 07:35:13 -0000
*************** static int alphafunc (const void *, cons
*** 713,718 ****
--- 713,719 ----
  static void mangle_defs (void);
  static void usage (FILE *, int);
  static void inform (const char *, ...);
+ static void set_dll_name_from_def (const char *);
  
  static char *
  prefix_encode (char *start, unsigned code)
*************** process_def_file (const char *name)
*** 877,883 ****
  
  /* Communications with the parser.  */
  
- static const char *d_name;	/* Arg to NAME or LIBRARY.  */
  static int d_nfuncs;		/* Number of functions exported.  */
  static int d_named_nfuncs;	/* Number of named functions exported.  */
  static int d_low_ord;		/* Lowest ordinal index.  */
--- 878,883 ----
*************** def_exports (const char *name, const cha
*** 925,930 ****
--- 925,940 ----
      p->forward = 0; /* no forward */
  }
  
+ static void
+ set_dll_name_from_def (const char * name)
+ {
+   const char* image_basename = lbasename (name);
+   if (image_basename != name)
+     non_fatal (_("%s: Path components stripped from image name, '%s'."),
+ 	      def_file, name);
+   dll_name = xstrdup (image_basename);
+ }
+ 
  void
  def_name (const char *name, int base)
  {
*************** def_name (const char *name, int base)
*** 934,944 ****
    if (d_is_dll)
      non_fatal (_("Can't have LIBRARY and NAME"));
  
-   d_name = name;
    /* If --dllname not provided, use the one in the DEF file.
       FIXME: Is this appropriate for executables?  */
    if (! dll_name)
!     dll_name = xstrdup (name);
    d_is_exe = 1;
  }
  
--- 944,953 ----
    if (d_is_dll)
      non_fatal (_("Can't have LIBRARY and NAME"));
  
    /* If --dllname not provided, use the one in the DEF file.
       FIXME: Is this appropriate for executables?  */
    if (! dll_name)
!     set_dll_name_from_def (name);
    d_is_exe = 1;
  }
  
*************** def_library (const char *name, int base)
*** 951,960 ****
    if (d_is_exe)
      non_fatal (_("Can't have LIBRARY and NAME"));
  
-   d_name = name;
    /* If --dllname not provided, use the one in the DEF file.  */
    if (! dll_name)
!     dll_name = xstrdup (name);
    d_is_dll = 1;
  }
  
--- 960,968 ----
    if (d_is_exe)
      non_fatal (_("Can't have LIBRARY and NAME"));
  
    /* If --dllname not provided, use the one in the DEF file.  */
    if (! dll_name)
!     set_dll_name_from_def (name);
    d_is_dll = 1;
  }
  
*************** main (int ac, char **av)
*** 3289,3295 ****
  	  output_def = fopen (optarg, FOPEN_WT);
  	  break;
  	case 'D':
! 	  dll_name = optarg;
  	  break;
  	case 'l':
  	  imp_name = optarg;
--- 3297,3306 ----
  	  output_def = fopen (optarg, FOPEN_WT);
  	  break;
  	case 'D':
! 	  dll_name = (char*) lbasename (optarg);
! 	  if (dll_name != optarg)
! 	    non_fatal (_("Path components stripped from dllname, '%s'."),
! 	      		 optarg);
  	  break;
  	case 'l':
  	  imp_name = optarg;
*************** main (int ac, char **av)
*** 3371,3379 ****
  
    if (!dll_name && exp_name)
      {
!       int len = strlen (exp_name) + 5;
        dll_name = xmalloc (len);
!       strcpy (dll_name, exp_name);
        strcat (dll_name, ".dll");
      }
  
--- 3382,3394 ----
  
    if (!dll_name && exp_name)
      {
!       /* If we are inferring dll_name from exp_name,
!          strip off any path components, without emitting
!          a warning.  */  
!       const char* exp_basename = lbasename (exp_name); 
!       const int len = strlen (exp_basename) + 5;
        dll_name = xmalloc (len);
!       strcpy (dll_name, exp_basename);
        strcat (dll_name, ".dll");
      }
  

Find local movie times and trailers on Yahoo! Movies.
http://au.movies.yahoo.com


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