public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* [PATCH] gcc3/ld patch for direct-linking-to-dll and auto-import support
@ 2003-08-28 20:24 Ralf Habacker
  2003-09-07 18:30 ` Nick Clifton
  0 siblings, 1 reply; 2+ messages in thread
From: Ralf Habacker @ 2003-08-28 20:24 UTC (permalink / raw)
  To: Binutils, cygwin; +Cc: Kde-Cygwin

[-- Attachment #1: Type: text/plain, Size: 548 bytes --]

Hi

while compiling trolltechs qt/xfree library with gcc3 (3.2x) on cygwin I
recognized, that the auto-import stuff in combination of recent ld does not work
in case of const variables in a dll when using direct linking to a dll, because
gcc put those variables into a readonly, that means the .text section.

The patch and a testcase is appended. A documentation could be found in the
patch file.

A binary update (only containing ld) could be found here:

http://kde-cygwin.sourceforge.net/snapshots/ld-gcc3-const-var-patch.tar.bz2


Cheers
Ralf

[-- Attachment #2: ld-gcc3-const-var-patch-testcase.tar.bz2 --]
[-- Type: application/octet-stream, Size: 882 bytes --]

[-- Attachment #3: ld-gcc3-const-var-patch.patch --]
[-- Type: application/octet-stream, Size: 6760 bytes --]

Index: pe-dll.c
===================================================================
RCS file: /cvs/src/src/ld/pe-dll.c,v
retrieving revision 1.60
diff -u -3 -p -B -r1.60 pe-dll.c
--- pe-dll.c	17 Jul 2003 15:47:49 -0000	1.60
+++ pe-dll.c	28 Aug 2003 19:45:39 -0000
@@ -120,6 +120,44 @@
 
     See also: ld/emultempl/pe.em.  */
 
+/*  gcc3 support for direct-linking-to-dll and auto-import 
+    
+    Background:
+    
+    gcc2/3 stores regular initialized variables in the .data and uninitialized 
+    variables in the .bss section. While gcc2 stores constant variables also in 
+    the .data section, gcc3 stores constant variables in the .text section. 
+    
+    This is no problem when using import libraries, but using the direct-linking-
+    to-dll feature with gcc3 compiled sources let the auto-import stuff fail because 
+    data variables are only expected to be in the .data section, which results in 
+    not auto-imported data variables; they are linked as functions and this results 
+    in runtime segfaults.
+    
+    How it works: 
+    
+    The gcc3 support for direct-linking-to-dll and auto-import remove this 
+    limitation in two steps: 
+    1. On linking a dll exported constant variables are prefixed with a string
+       (CONST_KEY), which could not be emulated by regular c++ symbols to avoid 
+       unwanted triggering of the auto-import stuff. 
+    2. On linking a dll or application with another dll containing exported const 
+       symbols ld searches for such prefixed symbols and auto-import this symbols 
+       like regular data symbols.
+        
+    Example: 
+      const int constvar = 2;    						=>  .const$constvar 
+    	
+    	class test {
+    		static const int staticconstvar; 		=> .const$_ZN4test14staticconstvarE
+    	}
+*/ 
+   	
+/* name prefix for gcc3 direct-linking-to-dll and auto-import support */
+#define CONST_KEY ".const$"
+#define CONST_KEY_SIZE 7
+
+
 static void add_bfd_to_link (bfd *, const char *, struct bfd_link_info *);
 
 /* For emultempl/pe.em.  */
@@ -536,11 +574,13 @@ process_def_file (bfd *abfd ATTRIBUTE_UN
 	{
 	  asymbol **symbols;
 	  int nsyms, symsize;
+		asection *section_text;
 
 	  symsize = bfd_get_symtab_upper_bound (b);
 	  symbols = xmalloc (symsize);
 	  nsyms = bfd_canonicalize_symtab (b, symbols);
-
+		section_text = bfd_get_section_by_name (b, ".text"); 
+		
 	  for (j = 0; j < nsyms; j++)
 	    {
 	      /* We should export symbols which are either global or not
@@ -571,9 +611,25 @@ process_def_file (bfd *abfd ATTRIBUTE_UN
 		  if (auto_export (b, pe_def_file, sn))
 		    {
 		      def_file_export *p;
-		      p=def_file_add_export (pe_def_file, sn, 0, -1);
-		      /* Fill data flag properly, from dlltool.c.  */
-		      p->flag_data = !(symbols[j]->flags & BSF_FUNCTION);
+
+					/* prefix CONST_KEY to symbolname in case of data symbols 
+						 pointing to the text segment (const vars) to support auto-import */ 
+		      if (!(symbols[j]->flags & BSF_FUNCTION) && 
+		      				symbols[j]->section == section_text) 
+		      {
+						char *prefix = CONST_KEY; 
+						char *tmp = xmalloc (strlen(sn) + strlen(prefix) + 1);
+						strcpy(tmp,prefix); 
+						strcat(tmp,sn);
+						p=def_file_add_export (pe_def_file, tmp, sn, -1);
+						p->flag_data = 1; 
+					}
+					else 
+					{
+						p=def_file_add_export (pe_def_file, sn, 0, -1);
+			      /* Fill data flag properly, from dlltool.c.  */
+			      p->flag_data = !(symbols[j]->flags & BSF_FUNCTION);
+					}
 		    }
 		}
 	    }
@@ -2246,17 +2303,23 @@ pe_dll_generate_implib (def_file *def, c
 
   for (i = 0; i < def->num_exports; i++)
     {
-      /* The import library doesn't know about the internal name.  */
-      char *internal = def->exports[i].internal_name;
       bfd *n;
-
-      def->exports[i].internal_name = def->exports[i].name;
-      n = make_one (def->exports + i, outarch);
-      n->next = head;
-      head = n;
-      def->exports[i].internal_name = internal;
-    }
-
+      /* the prefix CONST_KEY used for const var symbols must not be put into the import library */ 
+      if (strncmp(def->exports[i].name,CONST_KEY,CONST_KEY_SIZE) == 0) {
+        char *external = def->exports[i].name;
+        def->exports[i].name = def->exports[i].internal_name;
+        n = make_one (def->exports + i, outarch);
+        def->exports[i].name = external;
+      } else {
+      /* The import library doesn't know about the internal name.  */
+        char *internal = def->exports[i].internal_name;
+        def->exports[i].internal_name = def->exports[i].name;
+        n = make_one (def->exports + i, outarch);
+        def->exports[i].internal_name = internal;
+      }
+    n->next = head;
+    head = n;
+  }
   ar_tail = make_tail (outarch);
 
   if (ar_head == NULL || ar_tail == NULL)
@@ -2567,26 +2630,32 @@ pe_implied_import_dll (const char *filen
       def_file_import *imp;
       /* Pointer to the function address vector.  */
       unsigned long func_rva = pe_as32 (erva + exp_funcbase + i * 4);
-      int is_data = 0;
+      char *sym_name = erva + name_rva;
 
       /* Skip unwanted symbols, which are
 	 exported in buggy auto-import releases.  */
-      if (strncmp (erva + name_rva, "_nm_", 4) != 0)
+      if (strncmp (sym_name, "_nm_", 4) != 0)
  	{
- 	  /* is_data is true if the address is in the data or bss segment.  */
- 	  is_data =
-	    (func_rva >= data_start && func_rva < data_end)
-	    || (func_rva >= bss_start && func_rva < bss_end);
-
-	  imp = def_file_add_import (pe_def_file, erva + name_rva,
+				/* handle const var auto-importing with direct linking to dll */ 
+				if (strncmp (sym_name, CONST_KEY, CONST_KEY_SIZE) == 0 ) 
+				{
+				 	imp = def_file_add_import (pe_def_file, sym_name, 
+				 	   dll_name, i, sym_name+CONST_KEY_SIZE);
+	 		  	imp->data = 1;
+			  }
+				else 
+				{
+			  	imp = def_file_add_import (pe_def_file, sym_name,
 				     dll_name, i, 0);
- 	  /* 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,
-		    func_rva, is_data ? "(data)" : "");
+			 	  /* symbol is data if the address is in the data or bss segment.  */
+			 	  imp->data =
+				    (func_rva >= data_start && func_rva < data_end)
+				    || (func_rva >= bss_start && func_rva < bss_end);
+				}
+		  if (pe_dll_extra_pe_debug)
+		  printf ("%s dll-name: %s sym: %s addr: 0x%lx %s\n",
+		    __FUNCTION__, dll_name, sym_name,
+		    func_rva, imp->data ? "(data)" : "");
  	}
     }
 


[-- Attachment #4: Type: text/plain, Size: 218 bytes --]

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] gcc3/ld patch for direct-linking-to-dll and auto-import support
  2003-08-28 20:24 [PATCH] gcc3/ld patch for direct-linking-to-dll and auto-import support Ralf Habacker
@ 2003-09-07 18:30 ` Nick Clifton
  0 siblings, 0 replies; 2+ messages in thread
From: Nick Clifton @ 2003-09-07 18:30 UTC (permalink / raw)
  To: Ralf.Habacker; +Cc: binutils, cygwin, kde-cygwin

Hi Ralf,

> while compiling trolltechs qt/xfree library with gcc3 (3.2x) on
> cygwin I recognized, that the auto-import stuff in combination of
> recent ld does not work in case of const variables in a dll when
> using direct linking to a dll, because gcc put those variables into
> a readonly, that means the .text section.
>
> The patch and a testcase is appended. A documentation could be found
> in the patch file.

Are you sure that the current linker does not work ?

When I tried it, using the test case you supplied, but without the
patch applied, I got this:

  % make
  ../gcc/g++ -B ../gcc/ -g  -save-temps -c -o dll.o dll.cc
  ../gcc/g++ -B ../gcc/ -g  --shared -L ../i686-pc-cygwin/newlib -L ../i686-pc-cygwin/libstdc++-v3/src/.libs dll.o -o dll.dll
  ../gcc/g++ -B ../gcc/ -g  -save-temps -c -o client.o client.cc
  ../gcc/g++ -B ../gcc/ -g  -o client client.o -L ../i686-pc-cygwin/newlib -L ../i686-pc-cygwin/libstdc++-v3/src/.libs -L. -ldll
  Info: resolving _var by linking to __imp__var (auto-import)
  Info: resolving test::var      by linking to __imp___ZN4test3varE (auto-import)

Cheers
        Nick
        


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2003-09-07 18:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-28 20:24 [PATCH] gcc3/ld patch for direct-linking-to-dll and auto-import support Ralf Habacker
2003-09-07 18:30 ` Nick Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).