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

* Re: --enable-auto-import extension
  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-07 18:20   ` David A. Cobb
  0 siblings, 2 replies; 15+ messages in thread
From: Charles Wilson @ 2002-06-28 18:08 UTC (permalink / raw)
  To: egor duda; +Cc: cygwin-apps

First: Woo Hoo!  Thanks for looking in to this problem Egor!!

egor duda wrote:


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


But why is this cygwin-specific?  It seems that it's equally applicable 
to mingw (e.g. native) DLLs, just as mingw's gcc can use the current 
auto-import feature, even though MSVC can't understand or use it...


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


Tested, and works:

$ ./crtest
ptr=1125, addend=8
reloc target=401125
ptr=112b, addend=4
reloc target=40112b
data=111 222 333


> If this idea is worthwhile, i think i should add more things to the
> patch:


Absolutely.  Of course, it would still need to be *rigorously* tested to 
insure that
   a) DLLs built this way could still be linked-to by "regular" code 
that doesn't violate the current limitations.  (e.g. suppose I as the 
cygintl-2.dll maintainer built the next cygintl-2.dll using this spiffy 
new ld.exe; so now, cygintl-2.dll has the extra reloc table.

Q1: will existing code that relied on the OLD cygintl-2.dll (without the 
additional reloc table) and does NOT try to access data-with-addend, 
STILL work if I drop in the new DLL?  [e.g. runtime backwards compat]

Q2: Could I relink old code (that again, does NOT try to access 
data-with-addend) to the new DLL using an OLD ld.exe?  (e.g. an enduser 
of cygintl-2.dll who hasn't updated their binutils)  [e.g linktime 
backwards compat]

Q3: Is the new DLL usable by windows tools, provided a suitable import 
library is generated? (I'm thinking here of mingw folks who build DLLs 
and implibs for use by others with MSVC -- granted, MSVC can't use 
auto-import at all, much less your extention.  But the same linker will 
be used even to build "regular" DLLs...we can't break that.)


> 1. Make cygreloc generation conditional via --enable-cygwin-reloc or
> something like that.


At first, yes, it does need to be conditional -- and default to OFF, 
probably...

And, it should probably not be "cygwin" specific.  --enable-data-reloc?


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


Okay, that takes care of "new style" exe accidentally linking at runtime 
to "old style" DLL.  Still, that leaves compatibility questions about
   existing "old style" EXE ---> "new style" DLL
   linking a "new" old style EXE using the old linker ---> against a 
"new style" DLL

This chunk of code (in pe-dll.c)

+      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);

doesn't seem to get called in your example -- but it should, if I 
understand correctly...What's the deal?

Anyway, because I can't see any "creating cygreloc entry..." debug 
messages, I'm not quite sure exactly where the cygreloc vector GOES -- 
into the client .o, or into the DLL.  I had assumed the DLL, but your 
point #2 above confuses that issue for me...
(cygreloc --> addend_reloc?)


> 3. Make relocations a bit more flexible by adding type and size
> (possible 64-bit support?) 


I dunno -- that's a tall order.  This addend-offset problem affects 
structs and arrays -- which come in all SORTS of specific types with 
different field orders and sizes.  Also, what about recursive offsets?

bob = a[2].foo.bar[3].baz ?

Granted, fixing 64 bit types (long long), simple arrays, and simple 
structs will go a LONG way to solving the problem in practical terms -- 
but until EVERY case is covered, we still need to detect the failure 
cases and warn at link time (not runtime).

> Comments?

Nice work so far, but it'll need LOTS of testing and verification, as 
you can well imagine.  Unfortunately, my time will be VERY VERY limited 
over the next six weeks to help with this sort of thing -- or for any 
cygwin-related stuff.  Thesis Defense approaches...

--Chuck

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

* Re: --enable-auto-import extension
  2002-06-28 18:08 ` Charles Wilson
@ 2002-06-30 23:47   ` egor duda
  2002-07-01 14:28     ` Charles Wilson
  2002-07-07 18:20   ` David A. Cobb
  1 sibling, 1 reply; 15+ messages in thread
From: egor duda @ 2002-06-30 23:47 UTC (permalink / raw)
  To: Charles Wilson; +Cc: binutils, cygwin-apps

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

Hi!

Saturday, 29 June, 2002 Charles Wilson cwilson@ece.gatech.edu wrote:

CW> egor duda wrote:

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

CW> But why is this cygwin-specific?  It seems that it's equally applicable 
CW> to mingw (e.g. native) DLLs, just as mingw's gcc can use the current 
CW> auto-import feature, even though MSVC can't understand or use it...

Well, of course it shouldn't be. I was thinking in terms of cygwin,
and, lacking better name, called it "cygwin blah-blah". But
suggestions for more generic name are welcome.

>> If this idea is worthwhile, i think i should add more things to the
>> patch:

CW> Absolutely.  Of course, it would still need to be *rigorously* tested to 
CW> insure that
CW>    a) DLLs built this way could still be linked-to by "regular" code 
CW> that doesn't violate the current limitations.  (e.g. suppose I as the 
CW> cygintl-2.dll maintainer built the next cygintl-2.dll using this spiffy 
CW> new ld.exe; so now, cygintl-2.dll has the extra reloc table.

CW> Q1: will existing code that relied on the OLD cygintl-2.dll (without the
CW> additional reloc table) and does NOT try to access data-with-addend, 
CW> STILL work if I drop in the new DLL?  [e.g. runtime backwards compat]

DLL is not changed in any way! Changes are made in _client_ code. So,
cygintl-*.dll stays as it was, and exports exactly the same symbols as
before. It should be, i believe, byte-to-byte identical to the dll
built with old ld.

CW> Q2: Could I relink old code (that again, does NOT try to access 
CW> data-with-addend) to the new DLL using an OLD ld.exe?  (e.g. an enduser 
CW> of cygintl-2.dll who hasn't updated their binutils)  [e.g linktime 
CW> backwards compat]

If client has no relocations with non-zero addend, i.e. it was
"auto-import-compatible", then nothing changes too. If your old code
could be linked with --enable-auto-import, then my added code is never
called.

CW> Q3: Is the new DLL usable by windows tools, provided a suitable import 
CW> library is generated? (I'm thinking here of mingw folks who build DLLs 
CW> and implibs for use by others with MSVC -- granted, MSVC can't use 
CW> auto-import at all, much less your extention.  But the same linker will 
CW> be used even to build "regular" DLLs...we can't break that.)

DLL is not changing.

>> 1. Make cygreloc generation conditional via --enable-cygwin-reloc or
>> something like that.


CW> At first, yes, it does need to be conditional -- and default to OFF, 
CW> probably...

CW> And, it should probably not be "cygwin" specific.  --enable-data-reloc?

Actually, it's not necessarily data reloc, though with probability of
99%+ it probably-is. Maybe '--enable-runtime-reloc'?

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

CW> Okay, that takes care of "new style" exe accidentally linking at runtime 
CW> to "old style" DLL.  Still, that leaves compatibility questions about
CW>    existing "old style" EXE ---> "new style" DLL
CW>    linking a "new" old style EXE using the old linker ---> against a 
CW> "new style" DLL

There's no problem. See above.

CW> This chunk of code (in pe-dll.c)

CW> +      if (pe_dll_extra_pe_debug)
CW> +        printf ("creating cygreloc entry for %s (addend=%d)\n",
CW> +               fixup_name, addend);
CW> +      b = make_cygreloc_fixup_entry (name, fixup_name, addend, output_bfd);
CW> +      add_bfd_to_link (b, b->filename, &link_info);

CW> doesn't seem to get called in your example -- but it should, if I 
CW> understand correctly...What's the deal?

Hmm. It should be called, and it called in my case. The resulting
crtest.exe should contain ".data_cygwin_reloc" string. Ah, i see. I
haven't added $(EXE_LDFLAGS) when linking final .exe. Fixed.

CW> Anyway, because I can't see any "creating cygreloc entry..." debug
CW> messages, I'm not quite sure exactly where the cygreloc vector GOES -- 
CW> into the client .o, or into the DLL.  I had assumed the DLL, but your 
CW> point #2 above confuses that issue for me...
(cygreloc -->> addend_reloc?)

It goes to client.

>> 3. Make relocations a bit more flexible by adding type and size
>> (possible 64-bit support?) 


CW> I dunno -- that's a tall order.  This addend-offset problem affects 
CW> structs and arrays -- which come in all SORTS of specific types with 
CW> different field orders and sizes.  Also, what about recursive offsets?

CW> bob = a[2].foo.bar[3].baz ?

Such things are handled by compiler. As far as i understand, all
relocations in coff files are 1) "linear" (base+addend), 2)
independent (i.e. order in which you make them doesn't matter).
I've attached a modified test to demonstrate this.

CW> Granted, fixing 64 bit types (long long), simple arrays, and simple 
CW> structs will go a LONG way to solving the problem in practical terms -- 
CW> but until EVERY case is covered, we still need to detect the failure 
CW> cases and warn at link time (not runtime).

What i was talking about is 64-bit versions of windows where addresses
(and so base symbol values and addends are 64-bit). Or if we want to
add some other types of relocations. Adding type field will make it
possible to add extensions to this feature.

>> Comments?

CW> Nice work so far, but it'll need LOTS of testing and verification, as 
CW> you can well imagine.  Unfortunately, my time will be VERY VERY limited 
CW> over the next six weeks to help with this sort of thing -- or for any 
CW> cygwin-related stuff.  Thesis Defense approaches...

Of course. Luckily, all we have to check is that it doesn't change
binaries for existing code, and then check clients one-by-one.

Egor.            mailto:deo@logos-m.ru ICQ 5165414 FidoNet 2:5020/496.19

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

#include "crtest.h"

#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 %c\n", foo[0].x, foo[1].y[2], foo[1].z[1]);
  return 0;
}

[-- Attachment #3: crtest.h --]
[-- Type: application/octet-stream, Size: 92 bytes --]

typedef struct
  {
    int x;
    int y[3];
    char z[3];
  }
foo_t;

extern foo_t foo[2];

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

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

#include <cygwin/cygwin_dll.h>

#include "crtest.h"

foo_t foo[2] = { {1, {11, 12, 13}, {'a', 'b', 'c'}},
                 {2, {21, 22, 23}, {'d', 'e', 'f'}}};

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 #5: Makefile --]
[-- Type: application/octet-stream, Size: 529 bytes --]

CC=gcc
CFLAGS=-g3 -I.

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) $(EXE_LDFLAGS) -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

* Re: --enable-auto-import extension
  2002-06-30 23:47   ` egor duda
@ 2002-07-01 14:28     ` Charles Wilson
  2002-07-02  8:39       ` egor duda
  0 siblings, 1 reply; 15+ messages in thread
From: Charles Wilson @ 2002-07-01 14:28 UTC (permalink / raw)
  To: egor duda; +Cc: cygwin-apps

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

egor duda wrote


> CW> But why is this cygwin-specific?  It seems that it's equally applicable 
> CW> to mingw (e.g. native) DLLs, just as mingw's gcc can use the current 
> CW> auto-import feature, even though MSVC can't understand or use it...
> 
> Well, of course it shouldn't be. I was thinking in terms of cygwin,
> and, lacking better name, called it "cygwin blah-blah". But
> suggestions for more generic name are welcome.


"cygwin internal pseudo-relocation"
-->
"pei386 runtime pseudo-relocation" ?

I think "pseudo-relocation" is an apt term to describe what your patch 
does.  Instead of marking the location of the "object" in memory, and 
expecting the runtime loader to (a) update that to the REAL location in 
memory and THEN (b) tack on an additional addend, you (a) create a 
pseudo-object at the memory location "object location + addend" and (b) 
let the windows runtime loader perform addend-less relocation on the 
psuedo-object.

So, it's runtime pseudo-relocation.  Sorta.

> DLL is not changed in any way! Changes are made in _client_ code. So,
> cygintl-*.dll stays as it was, and exports exactly the same symbols as
> before. It should be, i believe, byte-to-byte identical to the dll
> built with old ld.


I see that now.


> If client has no relocations with non-zero addend, i.e. it was
> "auto-import-compatible", then nothing changes too. If your old code
> could be linked with --enable-auto-import, then my added code is never
> called.


Yep.  (not tested, but seems obvious now from the code)


> CW> Q3: Is the new DLL usable by windows tools, provided a suitable import 
> CW> library is generated? (I'm thinking here of mingw folks who build DLLs 
> CW> and implibs for use by others with MSVC -- granted, MSVC can't use 
> CW> auto-import at all, much less your extention.  But the same linker will 
> CW> be used even to build "regular" DLLs...we can't break that.)
> 
> DLL is not changing.


Yep.


>>>1. Make cygreloc generation conditional via --enable-cygwin-reloc or
>>>something like that.
>>>
> 
> 
> CW> At first, yes, it does need to be conditional -- and default to OFF, 
> CW> probably...
> 
> CW> And, it should probably not be "cygwin" specific.  --enable-data-reloc?
> 
> Actually, it's not necessarily data reloc, though with probability of
> 99%+ it probably-is. Maybe '--enable-runtime-reloc'?


I like 'pseudo' so much (even if I have to check e/u u/e every time) 
that I'd prefer:

'--enable-runtime-pseudo-reloc'


> CW> (cygreloc -->> addend_reloc?)
> 
> It goes to client.


Yes, I see.  (cygreloc --> pei386_pseudo_reloc?  more typing, but more 
accurate, and general)


> Such things are handled by compiler. As far as i understand, all
> relocations in coff files are 1) "linear" (base+addend), 2)
> independent (i.e. order in which you make them doesn't matter).
> I've attached a modified test to demonstrate this.


Verified.  Thx.


> What i was talking about is 64-bit versions of windows where addresses
> (and so base symbol values and addends are 64-bit). Or if we want to
> add some other types of relocations. Adding type field will make it
> possible to add extensions to this feature.


</sheepish> Yeah.  What he said.  <I'll be over here....>

> Of course. Luckily, all we have to check is that it doesn't change
> binaries for existing code, 


Hard to do, really -- DLLs get a timestamp in their header, so even 
under ideal conditions you can't do a simple diff on two DLLs...I 
suppose you could make sure that two DLLs differ ONLY in "unimportant" 
ways, like timestamp.

> and then check clients one-by-one.


That's a long term effort. <g>

BTW, the example code you sent is needlessly complex; you don't need a 
special DLLMain() function.  Also, ld will automatically hunt for 
"libfoo.dll.a" if you give it a "-lfoo" flag -- there's no need for 
"-lfoo.dll".

See attached patch -- works fine here, with your modified ld.

--Chuck

[-- Attachment #2: egor_simplify.patch --]
[-- Type: text/plain, Size: 1303 bytes --]

diff -u egor2/Makefile egor2-new/Makefile
--- egor2/Makefile	2002-07-01 17:05:59.000000000 -0400
+++ egor2-new/Makefile	2002-07-01 17:05:35.000000000 -0400
@@ -16,7 +16,7 @@
 	$(CC) -shared -o crtest.dll $(DLL_LDFLAGS) $<
 
 crtest.exe: crtest.o libcrtest.dll.a
-	$(CC) $(EXE_LDFLAGS) -o crtest.exe crtest.o -L. -lcrtest.dll
+	$(CC) $(EXE_LDFLAGS) -o crtest.exe crtest.o -L. -lcrtest
 
 .PHONY: clean
 
diff -u egor2/crtest_dll.c egor2-new/crtest_dll.c
--- egor2/crtest_dll.c	2002-07-01 17:05:59.000000000 -0400
+++ egor2-new/crtest_dll.c	2002-07-01 17:05:35.000000000 -0400
@@ -1,36 +1,4 @@
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-#include <stdio.h>
-
-#include <cygwin/cygwin_dll.h>
-
 #include "crtest.h"
 
 foo_t foo[2] = { {1, {11, 12, 13}, {'a', 'b', 'c'}},
                  {2, {21, 22, 23}, {'d', 'e', 'f'}}};
-
-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;
-}
-

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

* Re: --enable-auto-import extension
  2002-07-01 14:28     ` Charles Wilson
@ 2002-07-02  8:39       ` egor duda
  2002-07-02  9:31         ` Christopher Faylor
                           ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: egor duda @ 2002-07-02  8:39 UTC (permalink / raw)
  To: binutils; +Cc: Charles Wilson, cygwin-apps

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

Hi!

Tuesday, 02 July, 2002 Charles Wilson cwilson@ece.gatech.edu wrote:

>> What i was talking about is 64-bit versions of windows where addresses
>> (and so base symbol values and addends are 64-bit). Or if we want to
>> add some other types of relocations. Adding type field will make it
>> possible to add extensions to this feature.

CW> </sheepish> Yeah.  What he said.  <I'll be over here....>

Well, after thinking twice about it i concluded that such flexibility
may be not that good after all. Sure, it allows adding extensions, but
make it hard to check at link-time if runtime support for those
extensions is present. So i think we can stay with simple format of
pseudo relocations for now.

>> Of course. Luckily, all we have to check is that it doesn't change
>> binaries for existing code, 

CW> Hard to do, really -- DLLs get a timestamp in their header, so even 
CW> under ideal conditions you can't do a simple diff on two DLLs...I 
CW> suppose you could make sure that two DLLs differ ONLY in "unimportant" 
CW> ways, like timestamp.

Someone suggested that one can do 'cmp -i 150 old.dll new.dll', or
whatever offset timestamp is located at.

Ok, i've finalized patch and test. I suppose i have a copyright
assignment with FSF for this changes to get incorporated into official
sources. As far as i understand, i have to get an assignment form from
binutils maintainer, right? 

Egor.            mailto:deo@logos-m.ru ICQ 5165414 FidoNet 2:5020/496.19

[-- Attachment #2: include.ChangeLog --]
[-- Type: application/octet-stream, 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 #3: include.diff --]
[-- Type: application/octet-stream, Size: 733 bytes --]

Index: bfdlink.h
===================================================================
RCS file: /cvs/uberbaum/include/bfdlink.h,v
retrieving revision 1.20
diff -u -p -2 -r1.20 bfdlink.h
--- bfdlink.h	1 Jul 2002 08:04:47 -0000	1.20
+++ bfdlink.h	2 Jul 2002 07:47:09 -0000
@@ -330,4 +330,9 @@ struct bfd_link_info
   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.  */

[-- Attachment #4: ld.ChangeLog --]
[-- Type: application/octet-stream, Size: 854 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.
	* scripttempl/pe.sc: Handle .rdata_runtime_pseudo_reloc sections.
	Add symbols for application to access them.
	* ld.texinfo: Document --enable-runtime-pseudo-reloc and
	--disable-runtime-pseudo-reloc options.

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

Index: ld.texinfo
===================================================================
RCS file: /cvs/uberbaum/ld/ld.texinfo,v
retrieving revision 1.70
diff -u -p -2 -r1.70 ld.texinfo
--- ld.texinfo	20 Jun 2002 14:44:10 -0000	1.70
+++ ld.texinfo	2 Jul 2002 11:37:31 -0000
@@ -1794,5 +1794,9 @@ There are several ways to address this d
 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) 
@@ -1830,5 +1834,5 @@ extern_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
@@ -1881,5 +1885,5 @@ void main(int argc, char **argv)@{
 @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
@@ -1890,4 +1894,15 @@ functions).
 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
Index: ldmain.c
===================================================================
RCS file: /cvs/uberbaum/ld/ldmain.c,v
retrieving revision 1.49
diff -u -p -2 -r1.49 ldmain.c
--- ldmain.c	1 Jul 2002 08:07:29 -0000	1.49
+++ ldmain.c	2 Jul 2002 11:37:32 -0000
@@ -261,6 +261,6 @@ main (argc, argv)
   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;
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	2 Jul 2002 11:37:32 -0000
@@ -142,4 +142,5 @@ 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
@@ -302,4 +303,8 @@ static char *make_import_fixup_mark PARA
 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));
@@ -2068,7 +2073,103 @@ make_import_fixup_entry (name, fixup_nam
 }
 
+/*	.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];
@@ -2077,4 +2178,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);
@@ -2091,12 +2193,36 @@ pe_create_import_fixup (rel)
     }
 
-  {
-    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/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	2 Jul 2002 11:37:32 -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, asection * s, int addend));
 #endif /* PE_DLL_H */
Index: emultempl/pe.em
===================================================================
RCS file: /cvs/uberbaum/ld/emultempl/pe.em,v
retrieving revision 1.65
diff -u -p -2 -r1.65 pe.em
--- emultempl/pe.em	1 Jul 2002 08:07:31 -0000	1.65
+++ emultempl/pe.em	2 Jul 2002 11:37:37 -0000
@@ -175,4 +175,5 @@ gld_${EMULATION_NAME}_before_parse()
   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)
@@ -223,4 +224,8 @@ gld_${EMULATION_NAME}_before_parse()
 #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[] = {
@@ -264,4 +269,6 @@ static struct option longopts[] = {
   {"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}
@@ -353,4 +360,8 @@ gld_${EMULATION_NAME}_list_options (file
                                        __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"));
@@ -634,4 +645,10 @@ gld_${EMULATION_NAME}_parse_args(argc, a
       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;
@@ -881,12 +898,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, s, 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	2 Jul 2002 11:37:37 -0000
@@ -86,4 +86,7 @@ SECTIONS
     ${R_RDATA}
     *(.eh_frame)
+    ___RUNTIME_PSEUDO_RELOC_LIST__ = .; __RUNTIME_PSEUDO_RELOC_LIST__ = . ;
+    *(.rdata_runtime_pseudo_reloc)
+    ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; __RUNTIME_PSEUDO_RELOC_LIST_END__ = . ;
   }
 

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

#include <stdio.h>
#include <stdlib.h>
#include "crtest.h"

#if defined(__CYGWIN__)
#  define HAVE_FORK
#endif

#if !defined(RUNTIME_PSEUDO_RELOC_SUPPORT)
#include <windows.h>
typedef struct
  {
    DWORD addend;
    DWORD target;
  }
runtime_pseudo_reloc;

extern runtime_pseudo_reloc __RUNTIME_PSEUDO_RELOC_LIST__;
extern runtime_pseudo_reloc __RUNTIME_PSEUDO_RELOC_LIST_END__;
extern void* _data_start__;
extern void* _image_base__;

void
_pei386_runtime_relocator (runtime_pseudo_reloc* start, runtime_pseudo_reloc* end)
{
  DWORD reloc_target;
  runtime_pseudo_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;
    }
}
#endif

void
print_data ()
{
  printf ("data=%d %d %c\n", foo[0].x, foo[1].y[2], foo[1].z[1]);
}

int
main ()
{
  int pid;
#if !defined(RUNTIME_PSEUDO_RELOC_SUPPORT)
  _pei386_runtime_relocator (&__RUNTIME_PSEUDO_RELOC_LIST__,
                             &__RUNTIME_PSEUDO_RELOC_LIST_END__);
#endif
#if defined(RUNTIME_PSEUDO_RELOC_SUPPORT) && defined(HAVE_FORK)
  switch (pid = fork ())
    {
    case -1:
      perror ("fork");
      break;
    case 0:
      printf ("child: ");
      print_data ();
      break;
    default:
      wait (NULL);
      printf ("parent: ");
      print_data ();
      break;
    }
#else
  print_data ();
#endif
  return 0;
}

[-- Attachment #7: crtest.h --]
[-- Type: application/octet-stream, Size: 92 bytes --]

typedef struct
  {
    int x;
    int y[3];
    char z[3];
  }
foo_t;

extern foo_t foo[2];

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

#include "crtest.h"

foo_t foo[2] = { {1, {11, 12, 13}, {'a', 'b', 'c'}},
                 {2, {21, 22, 23}, {'d', 'e', 'f'}}};

[-- Attachment #9: Makefile --]
[-- Type: application/octet-stream, Size: 867 bytes --]

# mingw
# CC=gcc -mno-cygwin
# CFLAGS=-g3 -I . -DNO_RUNTIME_PSEUDO_RELOC_SUPPORT

# cygwin w/o runtime pseudo reloc support
CC=gcc
CFLAGS=-g3 -I . -DNO_RUNTIME_PSEUDO_RELOC_SUPPORT

# cygwin with runtime pseudo reloc support
# CC=gcc
# CFLAGS=-g3 -I . -DRUNTIME_PSEUDO_RELOC_SUPPORT

DLL_LDFLAGS=-Wl,--export-all-symbols -Wl,--out-implib=libcrtest.dll.a
EXE_LDFLAGS=-Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc
# DEBUG_LDFLAGS=-Wl,--enable-extra-pe-debug -Wl,--verbose

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) $(EXE_LDFLAGS) $(DEBUG_LDFLAGS) -o crtest.exe crtest.o -L. -lcrtest

.PHONY: clean

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

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

* Re: --enable-auto-import extension
  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
  2 siblings, 0 replies; 15+ messages in thread
From: Christopher Faylor @ 2002-07-02  9:31 UTC (permalink / raw)
  To: binutils, cygwin-apps; +Cc: cygwin-apps

On Tue, Jul 02, 2002 at 07:36:14PM +0400, egor duda wrote:
>Ok, i've finalized patch and test. I suppose i have a copyright
>assignment with FSF for this changes to get incorporated into official
>sources. As far as i understand, i have to get an assignment form from
>binutils maintainer, right? 

Correct.

cgf

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

* Re: --enable-auto-import extension
  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
  2 siblings, 0 replies; 15+ messages in thread
From: egor duda @ 2002-07-03  2:21 UTC (permalink / raw)
  To: egor duda

Hi!

Tuesday, 02 July, 2002 egor duda deo@logos-m.ru wrote:

ed> Ok, i've finalized patch and test. I suppose i have    a copyright
                                                       ^^^ to sign
ed> assignment with FSF for this changes to get incorporated into official
ed> sources. As far as i understand, i have to get an assignment form from
ed> binutils maintainer, right? 

Egor.            mailto:deo@logos-m.ru ICQ 5165414 FidoNet 2:5020/496.19

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

* Re: --enable-auto-import extension
  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
  2 siblings, 1 reply; 15+ messages in thread
From: Charles Wilson @ 2002-07-03 12:05 UTC (permalink / raw)
  To: egor duda; +Cc: cygwin-apps

egor duda wrote:


> Someone suggested that one can do 'cmp -i 150 old.dll new.dll', or
> whatever offset timestamp is located at.
> 
> Ok, i've finalized patch and test. I suppose i have a copyright
> assignment with FSF for this changes to get incorporated into official
> sources. As far as i understand, i have to get an assignment form from
> binutils maintainer, right? 


The new version looks good to me; I built and ran your test without 
problems.  I do have a suggestion for later, when 
--enable-runtime-pseudo-reloc is made the default: in pe-dll.c (around 
line 2209) change

if (pe_dll_extra_pe_debug)
   printf ("creating runtime pseudo-reloc entry for %s (addend=%d)\n",
      fixup_name, addend);

to

if (link_info.pei386_runtime_pseudo_reloc == -1)
   info_msg (_("creating runtime pseudo-reloc entry for %s (addend=%d)\n"),
      fixup_name, addend);

So that if pseudo_reloc is implicitly enabled, print messages for each 
psuedo-reloc entry (but not all that other pe_dll_extra_pe_debug stuff). 
  It's not a warning, but its info the user probably needs to know if he 
didn't explicitly say "--enable-runtime-pseudo-reloc".

But that's not important until AFTER pseudo-reloc is made the default.

The business with fork() and -DNO_RUNTIME_PSEUDO_RELOC_SUPPORT stuff in 
your example is a bit confusing -- do you have some pending patches to 
cygwin1.dll?

--Chuck


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

* Re: --enable-auto-import extension
  2002-07-03 12:05         ` Charles Wilson
@ 2002-07-04  3:43           ` egor duda
  2002-08-15 10:49             ` Christopher Faylor
  0 siblings, 1 reply; 15+ messages in thread
From: egor duda @ 2002-07-04  3:43 UTC (permalink / raw)
  To: Charles Wilson; +Cc: binutils, cygwin-apps

Hi!

Wednesday, 03 July, 2002 Charles Wilson cwilson@ece.gatech.edu wrote:

CW> The new version looks good to me; I built and ran your test without
CW> problems.  I do have a suggestion for later, when 
CW> --enable-runtime-pseudo-reloc is made the default: in pe-dll.c (around 
CW> line 2209) change

CW> if (pe_dll_extra_pe_debug)
CW>    printf ("creating runtime pseudo-reloc entry for %s (addend=%d)\n",
CW>       fixup_name, addend);

CW> to

CW> if (link_info.pei386_runtime_pseudo_reloc == -1)
CW>    info_msg (_("creating runtime pseudo-reloc entry for %s (addend=%d)\n"),
CW>       fixup_name, addend);

CW> So that if pseudo_reloc is implicitly enabled, print messages for each 
CW> psuedo-reloc entry (but not all that other pe_dll_extra_pe_debug stuff). 
CW>   It's not a warning, but its info the user probably needs to know if he 
CW> didn't explicitly say "--enable-runtime-pseudo-reloc".

Agreed.

CW> The business with fork() and -DNO_RUNTIME_PSEUDO_RELOC_SUPPORT stuff in
CW> your example is a bit confusing -- do you have some pending
CW> patches to cygwin1.dll? 

Yes, i've sent them yesterday to cygwin-patches@. Of course, they
should be added after new binutils package (in which ld exports
___RUNTIME_PSEUDO_RELOC_LIST__ and ___RUNTIME_PSEUDO_RELOC_LIST_END__)
is released.

Or we can only export them in pe.sc for now, and go ahead with cygwin
(and mingw, if anybody's interested) change. It'd just have no effect
until full ld patch is applied.

Egor.            mailto:deo@logos-m.ru ICQ 5165414 FidoNet 2:5020/496.19

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

* Re: --enable-auto-import extension
  2002-06-28 18:08 ` Charles Wilson
  2002-06-30 23:47   ` egor duda
@ 2002-07-07 18:20   ` David A. Cobb
  1 sibling, 0 replies; 15+ messages in thread
From: David A. Cobb @ 2002-07-07 18:20 UTC (permalink / raw)
  To: Charles Wilson; +Cc: egor duda, cygwin-apps

An (obviously untimely) thought.  Would not this technique offer a 
solution to the deficiency that a Windoze "shared object" (.dll) cannot 
reference symbols in the .EXE that loads it?  It's a thought -- the 
linker(?) [or lib-tool] could generate some sort of standard thunk in 
the DLL identifying "Undefined" symbols which the calling program could 
plug in at runtime [invisibly to the user, of course, as part of the 
dll-load, lib-init processing].  It should not even be horribly slower 
initiating, because it is simply shifting into the application itself 
the same work done by a X-Nix loader that the Win loader can't do.

I'll also second Chuck's WooHoo!

Charles Wilson wrote:

> First: Woo Hoo!  Thanks for looking in to this problem Egor!!
>
> egor duda wrote:
>
>
>> 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.
>
>
>
> But why is this cygwin-specific?  It seems that it's equally 
> applicable to mingw (e.g. native) DLLs, just as mingw's gcc can use 
> the current auto-import feature, even though MSVC can't understand or 
> use it...
>
>
>> Attached is a proof-of-concept patch to ld and simple testcase.
>
>
>
> Tested, and works:
>
> $ ./crtest
> ptr=1125, addend=8
> reloc target=401125
> ptr=112b, addend=4
> reloc target=40112b
> data=111 222 333
>
>
>> If this idea is worthwhile, i think i should add more things to the
>> patch:
>
>
>
> Absolutely.  Of course, it would still need to be *rigorously* tested 
> to insure that
>   a) DLLs built this way could still be linked-to by "regular" code 
> that doesn't violate the current limitations.  (e.g. suppose I as the 
> cygintl-2.dll maintainer built the next cygintl-2.dll using this 
> spiffy new ld.exe; so now, cygintl-2.dll has the extra reloc table.
>
> Q1: will existing code that relied on the OLD cygintl-2.dll (without 
> the additional reloc table) and does NOT try to access 
> data-with-addend, STILL work if I drop in the new DLL?  [e.g. runtime 
> backwards compat]
>
> Q2: Could I relink old code (that again, does NOT try to access 
> data-with-addend) to the new DLL using an OLD ld.exe?  (e.g. an 
> enduser of cygintl-2.dll who hasn't updated their binutils)  [e.g 
> linktime backwards compat]
>
> Q3: Is the new DLL usable by windows tools, provided a suitable import 
> library is generated? (I'm thinking here of mingw folks who build DLLs 
> and implibs for use by others with MSVC -- granted, MSVC can't use 
> auto-import at all, much less your extention.  But the same linker 
> will be used even to build "regular" DLLs...we can't break that.)
>
>
>> 1. Make cygreloc generation conditional via --enable-cygwin-reloc or
>> something like that.
>
>
>
> At first, yes, it does need to be conditional -- and default to OFF, 
> probably...
>
> And, it should probably not be "cygwin" specific.  --enable-data-reloc?
>
>
>> 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.
>
>
>
> Okay, that takes care of "new style" exe accidentally linking at 
> runtime to "old style" DLL.  Still, that leaves compatibility 
> questions about
>   existing "old style" EXE ---> "new style" DLL
>   linking a "new" old style EXE using the old linker ---> against a 
> "new style" DLL
>
> This chunk of code (in pe-dll.c)
>
> +      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);
>
> doesn't seem to get called in your example -- but it should, if I 
> understand correctly...What's the deal?
>
> Anyway, because I can't see any "creating cygreloc entry..." debug 
> messages, I'm not quite sure exactly where the cygreloc vector GOES -- 
> into the client .o, or into the DLL.  I had assumed the DLL, but your 
> point #2 above confuses that issue for me...
> (cygreloc --> addend_reloc?)
>
>
>> 3. Make relocations a bit more flexible by adding type and size
>> (possible 64-bit support?) 
>
>
>
> I dunno -- that's a tall order.  This addend-offset problem affects 
> structs and arrays -- which come in all SORTS of specific types with 
> different field orders and sizes.  Also, what about recursive offsets?
>
> bob = a[2].foo.bar[3].baz ?
>
> Granted, fixing 64 bit types (long long), simple arrays, and simple 
> structs will go a LONG way to solving the problem in practical terms 
> -- but until EVERY case is covered, we still need to detect the 
> failure cases and warn at link time (not runtime).
>
>> Comments?
>
>
> Nice work so far, but it'll need LOTS of testing and verification, as 
> you can well imagine.  Unfortunately, my time will be VERY VERY 
> limited over the next six weeks to help with this sort of thing -- or 
> for any cygwin-related stuff.  Thesis Defense approaches...
>
> --Chuck
>
>

-- 
David A. Cobb, Software Engineer, Public Access Advocate
"By God's Grace I am a Christian man, by my actions a great sinner." -- The Way of a Pilgrim; R. M. French, tr.
Life is too short to tolerate crappy software.
.


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

* Re: --enable-auto-import extension
  2002-07-04  3:43           ` egor duda
@ 2002-08-15 10:49             ` Christopher Faylor
  2002-08-15 23:21               ` egor duda
  0 siblings, 1 reply; 15+ messages in thread
From: Christopher Faylor @ 2002-08-15 10:49 UTC (permalink / raw)
  To: binutils, cygwin-apps

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.

cgf

On Thu, Jul 04, 2002 at 11:19:27AM +0400, egor duda wrote:
>Hi!
>
>Wednesday, 03 July, 2002 Charles Wilson cwilson@ece.gatech.edu wrote:
>
>CW> The new version looks good to me; I built and ran your test without
>CW> problems.  I do have a suggestion for later, when 
>CW> --enable-runtime-pseudo-reloc is made the default: in pe-dll.c (around 
>CW> line 2209) change
>
>CW> if (pe_dll_extra_pe_debug)
>CW>    printf ("creating runtime pseudo-reloc entry for %s (addend=%d)\n",
>CW>       fixup_name, addend);
>
>CW> to
>
>CW> if (link_info.pei386_runtime_pseudo_reloc == -1)
>CW>    info_msg (_("creating runtime pseudo-reloc entry for %s (addend=%d)\n"),
>CW>       fixup_name, addend);
>
>CW> So that if pseudo_reloc is implicitly enabled, print messages for each 
>CW> psuedo-reloc entry (but not all that other pe_dll_extra_pe_debug stuff). 
>CW>   It's not a warning, but its info the user probably needs to know if he 
>CW> didn't explicitly say "--enable-runtime-pseudo-reloc".
>
>Agreed.
>
>CW> The business with fork() and -DNO_RUNTIME_PSEUDO_RELOC_SUPPORT stuff in
>CW> your example is a bit confusing -- do you have some pending
>CW> patches to cygwin1.dll? 
>
>Yes, i've sent them yesterday to cygwin-patches@. Of course, they
>should be added after new binutils package (in which ld exports
>___RUNTIME_PSEUDO_RELOC_LIST__ and ___RUNTIME_PSEUDO_RELOC_LIST_END__)
>is released.
>
>Or we can only export them in pe.sc for now, and go ahead with cygwin
>(and mingw, if anybody's interested) change. It'd just have no effect
>until full ld patch is applied.
>
>Egor.            mailto:deo@logos-m.ru ICQ 5165414 FidoNet 2:5020/496.19

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

* Re: --enable-auto-import extension
  2002-08-15 10:49             ` Christopher Faylor
@ 2002-08-15 23:21               ` egor duda
  0 siblings, 0 replies; 15+ messages in thread
From: egor duda @ 2002-08-15 23:21 UTC (permalink / raw)
  To: Christopher Faylor; +Cc: binutils

Hi!

Thursday, 15 August, 2002 Christopher Faylor cgf@redhat.com wrote:

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

I've snailed a copyright assignment by air mail a couple of weeks ago,
but probably it haven't been delivered yet.

I think now we can do the following:

>>should be added after new binutils package (in which ld exports
>>___RUNTIME_PSEUDO_RELOC_LIST__ and ___RUNTIME_PSEUDO_RELOC_LIST_END__)
>>is released.
>>Or we can only export them in pe.sc for now, and go ahead with cygwin
>>(and mingw, if anybody's interested) change. It'd just have no effect
>>until full ld patch is applied.

it's trivial (i hope) change to binutils and i already have an assignment
with cygwin.

In a discussion in cygwin-patches@ you proposed to move call to
_pei386_runtime_relocator from crt0.o to cygwin1.dll. I did it, but
haven't tested it yet in case when pseudo-relocs are present in dll,
not exe file.

CF> On Thu, Jul 04, 2002 at 11:19:27AM +0400, egor duda wrote:
>>Wednesday, 03 July, 2002 Charles Wilson cwilson@ece.gatech.edu wrote:
>>
>>CW> The new version looks good to me; I built and ran your test without
>>CW> problems.  I do have a suggestion for later, when 
>>CW> --enable-runtime-pseudo-reloc is made the default: in pe-dll.c (around 
>>CW> line 2209) change
>>
>>CW> if (pe_dll_extra_pe_debug)
>>CW>    printf ("creating runtime pseudo-reloc entry for %s (addend=%d)\n",
>>CW>       fixup_name, addend);
>>
>>CW> to
>>
>>CW> if (link_info.pei386_runtime_pseudo_reloc == -1)
>>CW>    info_msg (_("creating runtime pseudo-reloc entry for %s (addend=%d)\n"),
>>CW>       fixup_name, addend);
>>
>>CW> So that if pseudo_reloc is implicitly enabled, print messages for each 
>>CW> psuedo-reloc entry (but not all that other pe_dll_extra_pe_debug stuff). 
>>CW>   It's not a warning, but its info the user probably needs to know if he 
>>CW> didn't explicitly say "--enable-runtime-pseudo-reloc".
>>
>>Agreed.
>>
>>CW> The business with fork() and -DNO_RUNTIME_PSEUDO_RELOC_SUPPORT stuff in
>>CW> your example is a bit confusing -- do you have some pending
>>CW> patches to cygwin1.dll? 
>>
>>Yes, i've sent them yesterday to cygwin-patches@. Of course, they
>>should be added after new binutils package (in which ld exports
>>___RUNTIME_PSEUDO_RELOC_LIST__ and ___RUNTIME_PSEUDO_RELOC_LIST_END__)
>>is released.
>>
>>Or we can only export them in pe.sc for now, and go ahead with cygwin
>>(and mingw, if anybody's interested) change. It'd just have no effect
>>until full ld patch is applied.

Egor.            mailto:deo@logos-m.ru ICQ 5165414 FidoNet 2:5020/496.19

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

* Re: --enable-auto-import extension
  2002-11-14 10:07 ` Nick Clifton
@ 2002-11-15  5:35   ` egor duda
  0 siblings, 0 replies; 15+ messages in thread
From: egor duda @ 2002-11-15  5:35 UTC (permalink / raw)
  To: Nick Clifton; +Cc: cwilson, binutils, cygwin-apps

Hi!

Thursday, 14 November, 2002 Nick Clifton nickc@redhat.com wrote:

NC> Hi Charles, Hi Egor,

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

NC> Approved and applied.  [Sorry for the long delay].

NC> Note: The cygwin targeted ports (eg i686-pc-cygwin) are currently
NC> showing three unexpected failures in the GAS testsuite:

NC>   FAIL: i386 abs reloc
NC>   FAIL: i386 pcrel reloc
NC>   FAIL: i386 sub

NC> Which their non-PE cousins do not.  I would appreciate it if you could
NC> spare a few moments to investigate this.

First of all, thanks, Charles, for fixing spelling and formatting
errors, and pushing the patch through. I'm to revive a discussion
about runtime part of changes in cygwin-apps@ after weekend.

As for gas testsuite failures, i suppose they have nothing to do with
this patch. I've just reverted the patch but failures persist. I'll
try to track them down further, but i highly doubt that adding a field
to 'struct bfd_link_info', which is the only thing in the patch which
may affect gas, could lead to reloc failures in gas testsuite.

Egor.            mailto:deo@logos-m.ru ICQ 5165414 FidoNet 2:5020/496.19

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

* Re: --enable-auto-import extension
  2002-11-11 18:01 Charles Wilson
@ 2002-11-14 10:07 ` Nick Clifton
  2002-11-15  5:35   ` egor duda
  0 siblings, 1 reply; 15+ messages in thread
From: Nick Clifton @ 2002-11-14 10:07 UTC (permalink / raw)
  To: cwilson, deo; +Cc: binutils, cygwin-apps

Hi Charles, Hi Egor,

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

Approved and applied.  [Sorry for the long delay].

Note: The cygwin targeted ports (eg i686-pc-cygwin) are currently
showing three unexpected failures in the GAS testsuite:

  FAIL: i386 abs reloc
  FAIL: i386 pcrel reloc
  FAIL: i386 sub

Which their non-PE cousins do not.  I would appreciate it if you could
spare a few moments to investigate this.

Cheers
	Nick

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