This is the mail archive of the cygwin-apps@cygwin.com mailing list for the Cygwin 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]

--enable-auto-import extension


This is an update of Egor Duda's original version. I have made no substantive changes, except
1) remove the "minimal" portion which has already been accepted into CVS as an interim measure (August 2002) while we were waiting for Egor's copyright assignment for binutils to get in to FSF.
2) minor formatting changes so that it applies cleanly against current CVS.

I've tested the result, and it works as advertised -- and just as well as it did back in June/July when we went thru this the FIRST time. Please apply. The concept has already been approved for incorporation; we were just waiting for Egor's assignment. Which I devoutly hope has made it in sometime in the past five months.

In
http://sources.redhat.com/ml/binutils/2002-08/msg00548.html
cgf recommended that:

If Nick can verify your assignment status, then I'd like to suggest that
your original patch just be checked in.

And again here, cgf wrote:
http://sources.redhat.com/ml/binutils/2002-08/msg00286.html

What's the status of this change?  I'd vote for including it in ld
iff it is only invoked when the option is specifically used.  Then
we can add the appropriate changes to cygwin, make a new release, and
then make a binutils release as well.

The condition cgf specified is obeyed by the attached patch (with the exception of the "minimal" portion which has already been accepted into CVS, and which cannot be conditionalized in that manner.)



The "original patch" as modified by subsequent discussion is here:
http://sources.redhat.com/ml/binutils/2002-07/msg00035.html

Although it was first proposed here:

http://sources.redhat.com/ml/binutils/2002-06/msg00757.html

Since my changes were minimal, the "ownership" of this patch is still Egor. (If it matters, I have an assignment on file already).

--Chuck


2002-07-01  Egor Duda  <deo@logos-m.ru>

	* ldmain.c (main): Make runtime relocs disabled by default. Remove
	assignment which has no effect.
	* pe-dll.h (pe_create_import_fixup): Change prototype.
	* pe-dll.c (make_runtime_pseudo_reloc): New function.
	(pe_create_runtime_relocator_reference): Ditto.
	(pe_create_import_fixup): Handle relocations with non-zero addends.
	* emultempl/pe.em: Add options --enable-runtime-pseudo-reloc and
	--disable-runtime-pseudo-reloc.
	(make_import_fixup): Handle relocations with non-zero addends. Create
	an external reference to _pei386_runtime_relocator symbol if at least
	one pseudo reloc was created.
	* ld.texinfo: Document --enable-runtime-pseudo-reloc and
	--disable-runtime-pseudo-reloc options.
2002-07-01  Egor Duda  <deo@logos-m.ru>

	* bfdlink.h (struct bfd_link_info): Add new boolean
	field pei386_runtime_pseudo_reloc.
Index: bfdlink.h
===================================================================
RCS file: /cvs/src/src/include/bfdlink.h,v
retrieving revision 1.22
diff -u -r1.22 bfdlink.h
--- bfdlink.h	8 Aug 2002 03:50:17 -0000	1.22
+++ bfdlink.h	7 Nov 2002 21:51:42 -0000
@@ -340,6 +340,11 @@
      is explicitly requested by the user, -1 if enabled by default.  */
   int pei386_auto_import;
 
+  /* Non-zero if runtime relocs for DATA items with non-zero addends
+     in pei386 DLLs should be generated.  Set to 1 if this feature
+     is explicitly requested by the user, -1 if enabled by default.  */
+  int pei386_runtime_pseudo_reloc;
+
   /* True if non-PLT relocs should be merged into one reloc section
      and sorted so that relocs against the same symbol come together.  */
   boolean combreloc;
? ldint.info
Index: ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.74
diff -u -r1.74 ld.texinfo
--- ld.texinfo	23 Oct 2002 13:24:10 -0000	1.74
+++ ld.texinfo	7 Nov 2002 21:48:39 -0000
@@ -1808,7 +1808,11 @@
 There are several ways to address this difficulty, regardless of the
 data type of the exported variable:
 
-One solution is to force one of the 'constants' to be a variable -- 
+One way is to use --enable-runtime-pseudo-reloc switch. This leaves the task
+of adjusting references in your client code for runtime environment, so
+this method works only when runtime environtment supports this feature.
+
+Second solution is to force one of the 'constants' to be a variable -- 
 that is, unknown and un-optimizable at compile time.  For arrays, 
 there are two possibilities: a) make the indexee (the array's address) 
 a variable, or b) make the 'constant' index a variable.  Thus:
@@ -1844,7 +1848,7 @@
   @{ volatile long long * local_ll=&extern_ll; *local_ll @}
 @end example
 
-A second method of dealing with this difficulty is to abandon
+A third method of dealing with this difficulty is to abandon
 'auto-import' for the offending symbol and mark it with 
 @code{__declspec(dllimport)}.  However, in practice that
 requires using compile-time #defines to indicate whether you are
@@ -1895,7 +1899,7 @@
 @}
 @end example
 
-A third way to avoid this problem is to re-code your 
+A fouth way to avoid this problem is to re-code your 
 library to use a functional interface rather than a data interface
 for the offending variables (e.g. set_foo() and get_foo() accessor
 functions).
@@ -1904,6 +1908,17 @@
 @item --disable-auto-import
 Do not attempt to do sophisticalted linking of @code{_symbol} to 
 @code{__imp__symbol} for DATA imports from DLLs.
+
+@kindex --enable-runtime-pseudo-reloc
+@item --enable-runtime-pseudo-reloc
+If your code contains expressions described in --enable-auto-import section,
+that is, DATA imports from DLL with non-zero offset, this switch will create
+a vector of 'runtime pseudo relocations' which can be used by runtime
+environment to adjust references to such data in your client code. 
+
+@kindex --disable-runtime-pseudo-reloc
+@item --disable-runtime-pseudo-reloc
+Do not create pseudo relocations for non-zero offset DATA imports from DLLs.
 
 @kindex --enable-extra-pe-debug
 @item --enable-extra-pe-debug
Index: ldmain.c
===================================================================
RCS file: /cvs/src/src/ld/ldmain.c,v
retrieving revision 1.52
diff -u -r1.52 ldmain.c
--- ldmain.c	30 Oct 2002 03:57:38 -0000	1.52
+++ ldmain.c	7 Nov 2002 21:48:47 -0000
@@ -261,8 +261,8 @@
   link_info.eh_frame_hdr = false;
   link_info.flags = (bfd_vma) 0;
   link_info.flags_1 = (bfd_vma) 0;
-  link_info.pei386_auto_import = false;
   link_info.pei386_auto_import = -1;
+  link_info.pei386_runtime_pseudo_reloc = false;
   link_info.combreloc = true;
   link_info.spare_dynamic_tags = 5;
   link_info.common_skip_ar_aymbols = bfd_link_common_skip_none;
Index: pe-dll.c
===================================================================
RCS file: /cvs/src/src/ld/pe-dll.c,v
retrieving revision 1.45
diff -u -r1.45 pe-dll.c
--- pe-dll.c	6 Nov 2002 19:36:20 -0000	1.45
+++ pe-dll.c	7 Nov 2002 21:49:01 -0000
@@ -141,6 +141,7 @@
 static struct sec *edata_s, *reloc_s;
 static unsigned char *edata_d, *reloc_d;
 static size_t edata_sz, reloc_sz;
+static int runtime_pseudo_relocs_created = 0;
 
 typedef struct
   {
@@ -303,6 +304,10 @@
 static char *make_import_fixup_mark PARAMS ((arelent *));
 static bfd *make_import_fixup_entry
   PARAMS ((const char *, const char *, const char *, bfd *));
+static bfd *make_runtime_pseudo_reloc
+  PARAMS ((const char *, const char *, int, bfd *));
+static bfd *pe_create_runtime_relocator_reference
+  PARAMS ((bfd *parent));
 static unsigned int pe_get16 PARAMS ((bfd *, int));
 static unsigned int pe_get32 PARAMS ((bfd *, int));
 static unsigned int pe_as32 PARAMS ((void *));
@@ -2092,15 +2097,112 @@
   return abfd;
 }
 
+/*	.section	.rdata_runtime_pseudo_reloc
+ 	.long		addend
+ 	.rva		__fuNN_SYM (pointer to reference (address) in text)  */
+
+static bfd *
+make_runtime_pseudo_reloc (name, fixup_name, addend, parent)
+     const char *name ATTRIBUTE_UNUSED;
+     const char *fixup_name;
+     int addend;
+     bfd *parent;
+{
+  asection *rt_rel;
+  unsigned char *rt_rel_d;
+  char *oname;
+  bfd *abfd;
+
+  oname = (char *) xmalloc (20);
+  sprintf (oname, "rtr%06d.o", tmp_seq);
+  tmp_seq++;
+
+  abfd = bfd_create (oname, parent);
+  bfd_find_target (pe_details->object_target, abfd);
+  bfd_make_writable (abfd);
+
+  bfd_set_format (abfd, bfd_object);
+  bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
+
+  symptr = 0;
+  symtab = (asymbol **) xmalloc (2 * sizeof (asymbol *));
+  rt_rel = quick_section (abfd, ".rdata_runtime_pseudo_reloc", SEC_HAS_CONTENTS, 2);
+
+  quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
+
+  bfd_set_section_size (abfd, rt_rel, 8);
+  rt_rel_d = (unsigned char *) xmalloc (8);
+  rt_rel->contents = rt_rel_d;
+  memset (rt_rel_d, 0, 8);
+  bfd_put_32 (abfd, addend, rt_rel_d);
+
+  quick_reloc (abfd, 4, BFD_RELOC_RVA, 1);
+  save_relocs (rt_rel);
+
+  bfd_set_symtab (abfd, symtab, symptr);
+
+  bfd_set_section_contents (abfd, rt_rel, rt_rel_d, 0, 8);
+
+  bfd_make_readable (abfd);
+  return abfd;
+}
+
+/*	.section	.rdata
+ 	.rva		__pei386_runtime_relocator */
+
+static bfd *
+pe_create_runtime_relocator_reference (parent)
+     bfd *parent;
+{
+  asection *extern_rt_rel;
+  unsigned char *extern_rt_rel_d;
+  char *oname;
+  bfd *abfd;
+
+  oname = (char *) xmalloc (20);
+  sprintf (oname, "ertr%06d.o", tmp_seq);
+  tmp_seq++;
+
+  abfd = bfd_create (oname, parent);
+  bfd_find_target (pe_details->object_target, abfd);
+  bfd_make_writable (abfd);
+
+  bfd_set_format (abfd, bfd_object);
+  bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
+
+  symptr = 0;
+  symtab = (asymbol **) xmalloc (2 * sizeof (asymbol *));
+  extern_rt_rel = quick_section (abfd, ".rdata", SEC_HAS_CONTENTS, 2);
+
+  quick_symbol (abfd, "", "__pei386_runtime_relocator", "", UNDSEC, BSF_NO_FLAGS, 0);
+
+  bfd_set_section_size (abfd, extern_rt_rel, 4);
+  extern_rt_rel_d = (unsigned char *) xmalloc (4);
+  extern_rt_rel->contents = extern_rt_rel_d;
+
+  quick_reloc (abfd, 0, BFD_RELOC_RVA, 1);
+  save_relocs (extern_rt_rel);
+
+  bfd_set_symtab (abfd, symtab, symptr);
+
+  bfd_set_section_contents (abfd, extern_rt_rel, extern_rt_rel_d, 0, 4);
+
+  bfd_make_readable (abfd);
+  return abfd;
+}
+
 void
-pe_create_import_fixup (rel)
+pe_create_import_fixup (rel, s, addend)
      arelent *rel;
+     asection *s;
+     int addend;
 {
   char buf[300];
   struct symbol_cache_entry *sym = *rel->sym_ptr_ptr;
   struct bfd_link_hash_entry *name_thunk_sym;
   const char *name = sym->name;
   char *fixup_name = make_import_fixup_mark (rel);
+  bfd *b;
 
   sprintf (buf, U ("_nm_thnk_%s"), name);
 
@@ -2115,14 +2217,38 @@
       config.text_read_only = false;
     }
 
-  {
-    extern char * pe_data_import_dll;
-    char * dll_symname = pe_data_import_dll ? pe_data_import_dll : "unknown";
+  if (addend == 0 || link_info.pei386_runtime_pseudo_reloc)
+    {
+      extern char * pe_data_import_dll;
+      char * dll_symname = pe_data_import_dll ? pe_data_import_dll : "unknown";
 
-    bfd *b = make_import_fixup_entry (name, fixup_name, dll_symname,
-				      output_bfd);
-    add_bfd_to_link (b, b->filename, &link_info);
-  }
+      b = make_import_fixup_entry (name, fixup_name, dll_symname, output_bfd);
+      add_bfd_to_link (b, b->filename, &link_info);
+    }
+
+  if (addend != 0)
+    {
+      if (link_info.pei386_runtime_pseudo_reloc)
+	{
+	  if (pe_dll_extra_pe_debug)
+	    printf ("creating runtime pseudo-reloc entry for %s (addend=%d)\n",
+		   fixup_name, addend);
+	  b = make_runtime_pseudo_reloc (name, fixup_name, addend, output_bfd);
+	  add_bfd_to_link (b, b->filename, &link_info);
+	  if (runtime_pseudo_relocs_created == 0)
+	    {
+	      b = pe_create_runtime_relocator_reference (output_bfd);
+	      add_bfd_to_link (b, b->filename, &link_info);
+	    }
+	  runtime_pseudo_relocs_created++;
+	} 
+      else
+	{
+	  einfo (_("%C: variable '%T' can't be auto-imported. Please read the documentation for ld's --enable-auto-import for details.\n"),
+		 s->owner, s, rel->address, sym->name);
+	  einfo ("%X");
+	}
+    }
 }
 
 
Index: pe-dll.h
===================================================================
RCS file: /cvs/src/src/ld/pe-dll.h,v
retrieving revision 1.8
diff -u -r1.8 pe-dll.h
--- pe-dll.h	8 Jun 2002 07:39:45 -0000	1.8
+++ pe-dll.h	7 Nov 2002 21:49:01 -0000
@@ -50,5 +50,5 @@
 					      const char *name,
 					      int (*cb) (arelent *, asection *)));
 
-extern void pe_create_import_fixup PARAMS ((arelent * rel));
+extern void pe_create_import_fixup PARAMS ((arelent * rel, asection * s, int addend));
 #endif /* PE_DLL_H */
Index: emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.68
diff -u -r1.68 pe.em
--- emultempl/pe.em	6 Nov 2002 19:36:20 -0000	1.68
+++ emultempl/pe.em	7 Nov 2002 21:49:16 -0000
@@ -174,6 +174,7 @@
   config.dynamic_link = true;
   config.has_shared = 1;
   link_info.pei386_auto_import = -1;
+  link_info.pei386_runtime_pseudo_reloc = false;
 
 #if (PE_DEF_SUBSYSTEM == 9) || (PE_DEF_SUBSYSTEM == 2)
 #if defined TARGET_IS_mipspe || defined TARGET_IS_armpe
@@ -222,6 +223,10 @@
 #define OPTION_DLL_DISABLE_AUTO_IMPORT	(OPTION_DLL_ENABLE_AUTO_IMPORT + 1)
 #define OPTION_ENABLE_EXTRA_PE_DEBUG	(OPTION_DLL_DISABLE_AUTO_IMPORT + 1)
 #define OPTION_EXCLUDE_LIBS		(OPTION_ENABLE_EXTRA_PE_DEBUG + 1)
+#define OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC	\
+				(OPTION_EXCLUDE_LIBS + 1)
+#define OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC	\
+				(OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC + 1)
 
 static struct option longopts[] = {
   /* PE options */
@@ -263,6 +268,8 @@
   {"enable-auto-import", no_argument, NULL, OPTION_DLL_ENABLE_AUTO_IMPORT},
   {"disable-auto-import", no_argument, NULL, OPTION_DLL_DISABLE_AUTO_IMPORT},
   {"enable-extra-pe-debug", no_argument, NULL, OPTION_ENABLE_EXTRA_PE_DEBUG},
+  {"enable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC},
+  {"disable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC},
 #endif
   {NULL, no_argument, NULL, 0}
 };
@@ -352,6 +359,10 @@
   fprintf (file, _("  --enable-auto-import               Do sophistcated linking of _sym to \n\
                                        __imp_sym for DATA references\n"));
   fprintf (file, _("  --disable-auto-import              Do not auto-import DATA items from DLLs\n"));
+  fprintf (file, _("  --enable-runtime-pseudo-reloc      Work around auto-import limitations by\n\
+                                       adding pseudo-relocations resolved at runtime.\n"));
+  fprintf (file, _("  --disable-runtime-pseudo-reloc     Do not add runtime pseudo-relocations for\n\
+                                       auto-imported DATA.\n"));
   fprintf (file, _("  --enable-extra-pe-debug            Enable verbose debug output when building\n\
                                        or linking to DLLs (esp. auto-import)\n"));
 #endif
@@ -633,6 +644,12 @@
     case OPTION_DLL_DISABLE_AUTO_IMPORT:
       link_info.pei386_auto_import = 0;
       break;
+    case OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC:
+      link_info.pei386_runtime_pseudo_reloc = 1;
+      break;
+    case OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC:
+      link_info.pei386_runtime_pseudo_reloc = 0;
+      break;
     case OPTION_ENABLE_EXTRA_PE_DEBUG:
       pe_dll_extra_pe_debug = 1;
       break;
@@ -877,15 +894,7 @@
     einfo (_("%C: Cannot get section contents - auto-import exception\n"),
 	   s->owner, s, rel->address);
 
-  if (addend == 0)
-    pe_create_import_fixup (rel);
-  else
-    {
-      einfo (_("%C: variable '%T' can't be auto-imported. Please read the documentation for ld's --enable-auto-import for details.\n"),
-	     s->owner, s, rel->address, sym->name);
-      einfo ("%X");
-    }
-
+  pe_create_import_fixup (rel, s, addend);
   return 1;
 }
 

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