public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: "Ralf Habacker" <Ralf.Habacker@freenet.de>
To: "Binutils" <binutils@sources.redhat.com>, "cygwin" <cygwin@cygwin.com>
Cc: "Kde-Cygwin" <kde-cygwin@kde.org>
Subject: [PATCH] gcc3/ld patch for direct-linking-to-dll and auto-import support
Date: Thu, 28 Aug 2003 20:24:00 -0000	[thread overview]
Message-ID: <004d01c36d9e$e7433e70$ca5e07d5@BRAMSCHE> (raw)

[-- 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/

             reply	other threads:[~2003-08-28 19:59 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-08-28 20:24 Ralf Habacker [this message]
2003-09-07 18:30 ` Nick Clifton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='004d01c36d9e$e7433e70$ca5e07d5@BRAMSCHE' \
    --to=ralf.habacker@freenet.de \
    --cc=binutils@sources.redhat.com \
    --cc=cygwin@cygwin.com \
    --cc=kde-cygwin@kde.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).