public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* --enable-auto-import extension
@ 2002-06-28  3:19 egor duda
  2002-06-28 18:08 ` Charles Wilson
  0 siblings, 1 reply; 15+ messages in thread
From: egor duda @ 2002-06-28  3:19 UTC (permalink / raw)
  To: cygwin-apps; +Cc: binutils

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

Hi!

Currently, --enable-auto-import feature of ld has a limitation of
not allowing importing dll data,  which resides at some offset
from exported symbol. This limitation is derived from limitation of
native win32 loader which can't handle such imports.

There're ways to work around such limitation, by changing code so that
it adds offset at runtime, but it won't work very well in case when
reference is in data segment. For instance, when g++ emits exception handling
information, it puts pointer to vtable+8bytes to data segment. If vtable
is imported from dll, application can't auto-import it, and have no
clean way to work around it.

Clean way to handle such situations (other than convincing
Microsoft to change a loader) is to add some runtime support for
non-zero-offset imports.

The idea is to add a vector of "cygwin internal pseudo-relocation"
entries to executable data section and to perform relocations of
appropriate data manually at program startup.

Attached is a proof-of-concept patch to ld and simple testcase.

If this idea is worthwhile, i think i should add more things to the
patch:
1. Make cygreloc generation conditional via --enable-cygwin-reloc or
something like that.
2. If linker creates at least one cygreloc entry, it should emit
reference to some external symbol, say 'cygwin_process_cygreloc' so
that if object contains non-empty cygreloc vector it'd be
guaranteed that it can't be linked with runtime without cygreloc
support.
3. Make relocations a bit more flexible by adding type and size
(possible 64-bit support?) 

Comments?

egor.            mailto:deo@logos-m.ru icq 5165414 fidonet 2:5020/496.19

[-- Attachment #2: crtest.c --]
[-- Type: application/octet-stream, Size: 856 bytes --]

#include <stdio.h>
#include <windows.h>

typedef struct
  {
    DWORD addend;
    DWORD target;
  }
cygwin_reloc;

extern cygwin_reloc __CYGWIN_RELOC_LIST__;
extern cygwin_reloc __CYGWIN_RELOC_LIST_END__;
extern void* _data_start__;
extern void* _image_base__;
extern int foobar[3];

void
perform_cygreloc (cygwin_reloc* start, cygwin_reloc* end)
{
  DWORD reloc_target;
  cygwin_reloc* r;
  for (r = start; r < end; r++)
    {
      printf ("ptr=%x, addend=%d\n", (long)r->target, r->addend);
      reloc_target = (DWORD) &_image_base__ + r->target;
      printf ("reloc target=%x\n", reloc_target);
      *((DWORD*) reloc_target) += r->addend;
    }
}

int
main ()
{
  perform_cygreloc (&__CYGWIN_RELOC_LIST__, &__CYGWIN_RELOC_LIST_END__);
  printf ("data=%d %d %d\n", foobar[0], foobar[1], foobar[2]);
  return 0;
}

[-- Attachment #3: crtest_dll.c --]
[-- Type: application/octet-stream, Size: 615 bytes --]

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <stdio.h>

#include <cygwin/cygwin_dll.h>

int foobar[3] = { 111, 222, 333 };

DECLARE_CYGWIN_DLL(DllMain)
BOOL APIENTRY
DllMain (
	 HINSTANCE hInst /* Library instance handle. */ ,
	 DWORD reason /* Reason this function is being called. */ ,
	 LPVOID reserved /* Not used. */)
{
  switch (reason)
    {
    case DLL_PROCESS_ATTACH:
      break;

    case DLL_PROCESS_DETACH:
      break;

    case DLL_THREAD_ATTACH:
      break;

    case DLL_THREAD_DETACH:
      break;
    }
  return TRUE;
}


[-- Attachment #4: ld.diff --]
[-- Type: application/octet-stream, Size: 4786 bytes --]

Index: pe-dll.c
===================================================================
RCS file: /cvs/uberbaum/ld/pe-dll.c,v
retrieving revision 1.41
diff -u -p -2 -r1.41 pe-dll.c
--- pe-dll.c	25 May 2002 20:39:25 -0000	1.41
+++ pe-dll.c	28 Jun 2002 09:11:56 -0000
@@ -302,4 +302,6 @@ static char *make_import_fixup_mark PARA
 static bfd *make_import_fixup_entry
   PARAMS ((const char *, const char *, const char *, bfd *));
+static bfd *make_cygreloc_fixup_entry
+  PARAMS ((const char *, const char *, int, bfd *));
 static unsigned int pe_get16 PARAMS ((bfd *, int));
 static unsigned int pe_get32 PARAMS ((bfd *, int));
@@ -2068,7 +2070,58 @@ make_import_fixup_entry (name, fixup_nam
 }
 
+/*	.section	.data_cygwin_reloc
+ 	.long		addend
+ 	.rva		__fuNN_SYM (pointer to reference (address) in text)  */
+
+static bfd *
+make_cygreloc_fixup_entry (name, fixup_name, addend, parent)
+     const char *name ATTRIBUTE_UNUSED;
+     const char *fixup_name;
+     int addend;
+     bfd *parent;
+{
+  asection *cygrel;
+  unsigned char *cygrel_d;
+  char *oname;
+  bfd *abfd;
+
+  oname = (char *) xmalloc (20);
+  sprintf (oname, "cr%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 *));
+  cygrel = quick_section (abfd, ".data_cygwin_reloc", SEC_HAS_CONTENTS, 2);
+
+  quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
+
+  bfd_set_section_size (abfd, cygrel, 8);
+  cygrel_d = (unsigned char *) xmalloc (8);
+  cygrel->contents = cygrel_d;
+  memset (cygrel_d, 0, 8);
+  bfd_put_32 (abfd, addend, cygrel_d);
+
+  quick_reloc (abfd, 4, BFD_RELOC_RVA, 1);
+  save_relocs (cygrel);
+
+  bfd_set_symtab (abfd, symtab, symptr);
+
+  bfd_set_section_contents (abfd, cygrel, cygrel_d, 0, 8);
+
+  bfd_make_readable (abfd);
+  return abfd;
+}
+
 void
-pe_create_import_fixup (rel)
+pe_create_import_fixup (rel, addend)
      arelent *rel;
+     int addend;
 {
   char buf[300];
@@ -2077,4 +2130,5 @@ pe_create_import_fixup (rel)
   const char *name = sym->name;
   char *fixup_name = make_import_fixup_mark (rel);
+  bfd *b;
 
   sprintf (buf, U ("_nm_thnk_%s"), name);
@@ -2095,8 +2149,16 @@ pe_create_import_fixup (rel)
     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);
+    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 (pe_dll_extra_pe_debug)
+        printf ("creating cygreloc entry for %s (addend=%d)\n",
+		fixup_name, addend);
+      b = make_cygreloc_fixup_entry (name, fixup_name, addend, output_bfd);
+      add_bfd_to_link (b, b->filename, &link_info);
+    }
 }
 
Index: pe-dll.h
===================================================================
RCS file: /cvs/uberbaum/ld/pe-dll.h,v
retrieving revision 1.8
diff -u -p -2 -r1.8 pe-dll.h
--- pe-dll.h	8 Jun 2002 07:39:45 -0000	1.8
+++ pe-dll.h	28 Jun 2002 09:11:56 -0000
@@ -51,4 +51,4 @@ extern void pe_walk_relocs_of_symbol PAR
 					      int (*cb) (arelent *, asection *)));
 
-extern void pe_create_import_fixup PARAMS ((arelent * rel));
+extern void pe_create_import_fixup PARAMS ((arelent * rel, int addend));
 #endif /* PE_DLL_H */
Index: emultempl/pe.em
===================================================================
RCS file: /cvs/uberbaum/ld/emultempl/pe.em,v
retrieving revision 1.64
diff -u -p -2 -r1.64 pe.em
--- emultempl/pe.em	7 Jun 2002 14:56:00 -0000	1.64
+++ emultempl/pe.em	28 Jun 2002 09:11:56 -0000
@@ -881,12 +881,5 @@ make_import_fixup (rel, s)
       }
 
-    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, addend);
   }
 
Index: scripttempl/pe.sc
===================================================================
RCS file: /cvs/uberbaum/ld/scripttempl/pe.sc,v
retrieving revision 1.5
diff -u -p -2 -r1.5 pe.sc
--- scripttempl/pe.sc	16 Jan 2002 01:48:43 -0000	1.5
+++ scripttempl/pe.sc	28 Jun 2002 09:11:57 -0000
@@ -76,4 +76,7 @@ SECTIONS
     *(.data)
     *(.data2)
+    ___CYGWIN_RELOC_LIST__ = .; __CYGWIN_RELOC_LIST__ = . ;
+    *(.data_cygwin_reloc)
+    ___CYGWIN_RELOC_LIST_END__ = .; __CYGWIN_RELOC_LIST_END__ = . ;
     ${R_DATA}
     ${RELOCATING+__data_end__ = . ;}

[-- Attachment #5: Makefile --]
[-- Type: application/octet-stream, Size: 534 bytes --]

CC=gcc
CFLAGS=-g3

DLL_LDFLAGS=-Wl,--export-all-symbols -Wl,--out-implib=libcrtest.dll.a
EXE_LDFLAGS=-Wl,--enable-auto-import -Wl,--enable-extra-pe-debug

all: crtest.exe crtest.dll

crtest_dll.o: crtest_dll.c
	$(CC) $(CFLAGS) -c $<

crtest.o: crtest.c
	$(CC) $(CFLAGS) -c $<

crtest.dll libcrtest.dll.a: crtest_dll.o
	$(CC) -shared -o crtest.dll $(DLL_LDFLAGS) $<

crtest.exe: crtest.o libcrtest.dll.a
	$(CC) -o crtest.exe crtest.o -L. -lcrtest.dll

.PHONY: clean

clean:
	rm -f *.o *.a crtest.exe crtest.dll

^ permalink raw reply	[flat|nested] 15+ messages in thread
* --enable-auto-import extension
@ 2002-11-11 18:01 Charles Wilson
  2002-11-14 10:07 ` Nick Clifton
  0 siblings, 1 reply; 15+ messages in thread
From: Charles Wilson @ 2002-11-11 18:01 UTC (permalink / raw)
  To: binutils; +Cc: deo, cygwin-apps

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

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



[-- Attachment #2: ld.ChangeLog --]
[-- Type: text/plain, Size: 742 bytes --]

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.

[-- Attachment #3: include.ChangeLog --]
[-- Type: text/plain, Size: 130 bytes --]

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

	* bfdlink.h (struct bfd_link_info): Add new boolean
	field pei386_runtime_pseudo_reloc.

[-- Attachment #4: include.diff --]
[-- Type: text/plain, Size: 801 bytes --]

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;

[-- Attachment #5: ld.diff --]
[-- Type: text/plain, Size: 12323 bytes --]

? 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;
 }
 

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

end of thread, other threads:[~2002-11-15 13:35 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-06-28  3:19 --enable-auto-import extension egor duda
2002-06-28 18:08 ` Charles Wilson
2002-06-30 23:47   ` egor duda
2002-07-01 14:28     ` Charles Wilson
2002-07-02  8:39       ` egor duda
2002-07-02  9:31         ` Christopher Faylor
2002-07-03  2:21         ` egor duda
2002-07-03 12:05         ` Charles Wilson
2002-07-04  3:43           ` egor duda
2002-08-15 10:49             ` Christopher Faylor
2002-08-15 23:21               ` egor duda
2002-07-07 18:20   ` David A. Cobb
2002-11-11 18:01 Charles Wilson
2002-11-14 10:07 ` Nick Clifton
2002-11-15  5:35   ` egor duda

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).