delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-developers/2001/06/10/21:24:53

Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-developers-subscribe AT sources DOT redhat DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin-developers/>
List-Post: <mailto:cygwin-developers AT sources DOT redhat DOT com>
List-Help: <mailto:cygwin-developers-help AT sources DOT redhat DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-developers-owner AT sources DOT redhat DOT com
Delivered-To: mailing list cygwin-developers AT sources DOT redhat DOT com
Message-ID: <02f501c0f215$669a30f0$0200a8c0@lifelesswks>
From: "Robert Collins" <robert DOT collins AT itdomain DOT com DOT au>
To: <cygwin-developers AT cygwin DOT com>
References: <001f01c0f0e6$72b8ec80$0200a8c0 AT lifelesswks> <20010610004015 DOT D29231 AT redhat DOT com> <23114413578 DOT 20010610185633 AT logos-m DOT ru> <20010610120846 DOT B5292 AT redhat DOT com> <027801c0f210$d1e7c5c0$0200a8c0 AT lifelesswks> <20010610211823 DOT A9379 AT redhat DOT com>
Subject: Re: dll base address - patch with description attached
Date: Mon, 11 Jun 2001 11:25:28 +1000
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.50.4133.2400
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400
X-OriginalArrivalTime: 11 Jun 2001 01:15:23.0301 (UTC) FILETIME=[FD387550:01C0F213]

This is a multi-part message in MIME format.

------=_NextPart_000_02F2_01C0F269.37B6AB20
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

----- Original Message -----
From: "Christopher Faylor" <cgf AT redhat DOT com>
To: <cygwin-developers AT cygwin DOT com>
Sent: Monday, June 11, 2001 11:18 AM
Subject: Re: dll base address

> If someone has a patch that applies cleanly to the current CVS sources
> and a writeup of how auto-import works, I'd like to revisit it again.
> I'm not binutils maintainer, however.

I've attached a diff file for the patch. I don't know if it applies
cleanly...

It does have a description by Paul of what the auto-import does.

Rob

------=_NextPart_000_02F2_01C0F269.37B6AB20
Content-Type: application/octet-stream;
	name="ld-2.11-auto-import-20010504.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="ld-2.11-auto-import-20010504.diff"

diff -uwr org/bfd/cofflink.c src/bfd/cofflink.c=0A=
--- org/bfd/cofflink.c	Fri Apr 27 12:57:43 2001=0A=
+++ src/bfd/cofflink.c	Fri Apr 27 13:51:28 2001=0A=
@@ -27,6 +27,9 @@=0A=
 #include "coff/internal.h"=0A=
 #include "libcoff.h"=0A=
 =0A=
+/* Setting this to 0 disables PE autoimport support */=0A=
+int pe_dll_auto_import=3D1;=0A=
+=0A=
 static boolean coff_link_add_object_symbols=0A=
   PARAMS ((bfd *, struct bfd_link_info *));=0A=
 static boolean coff_link_check_archive_element=0A=
@@ -276,6 +279,14 @@=0A=
 	    return false;=0A=
 	  h =3D bfd_link_hash_lookup (info->hash, name, false, false, true);=0A=
 =0A=
+          /*PS*/=0A=
+          if (!h && pe_dll_auto_import)=0A=
+            {=0A=
+              if (!strncmp(name,"__imp_",6))=0A=
+              {=0A=
+                h =3D bfd_link_hash_lookup (info->hash, name+6, false, =
false, true);=0A=
+              }=0A=
+            }=0A=
 	  /* We are only interested in symbols that are currently=0A=
 	     undefined.  If a symbol is currently known to be common,=0A=
 	     COFF linkers do not bring in an object file which defines=0A=
diff -uwr org/bfd/linker.c src/bfd/linker.c=0A=
--- org/bfd/linker.c	Fri Apr 27 12:58:12 2001=0A=
+++ src/bfd/linker.c	Fri Apr 27 13:54:54 2001=0A=
@@ -1003,10 +1003,22 @@=0A=
       arh =3D archive_hash_lookup (&arsym_hash, h->root.string, false, =
false);=0A=
       if (arh =3D=3D (struct archive_hash_entry *) NULL)=0A=
 	{=0A=
+         /* If we haven't found very symbol, let's look for its=0A=
+            import thunk */=0A=
+         extern int pe_dll_auto_import;=0A=
+=0A=
+          if (pe_dll_auto_import)=0A=
+            {=0A=
+              char *buf=3Dalloca(strlen(h->root.string)+10);=0A=
+              sprintf(buf,"__imp_%s",h->root.string);=0A=
+              arh =3D archive_hash_lookup (&arsym_hash, buf, false, =
false);=0A=
+            }=0A=
+          if (arh =3D=3D (struct archive_hash_entry *) NULL)=0A=
+    	  {=0A=
 	  pundef =3D &(*pundef)->next;=0A=
 	  continue;=0A=
 	}=0A=
-=0A=
+      }=0A=
       /* Look at all the objects which define this symbol.  */=0A=
       for (l =3D arh->defs; l !=3D (struct archive_list *) NULL; l =3D =
l->next)=0A=
 	{=0A=
diff -uwr org/ld/emultempl/pe.em src/ld/emultempl/pe.em=0A=
--- org/ld/emultempl/pe.em	Tue Dec 26 20:55:30 2000=0A=
+++ src/ld/emultempl/pe.em	Fri Apr 27 14:10:11 2001=0A=
@@ -118,7 +118,7 @@=0A=
 static int pe_enable_stdcall_fixup =3D -1; /* 0=3Ddisable 1=3Denable */=0A=
 static char *pe_out_def_filename =3D NULL;=0A=
 static char *pe_implib_filename =3D NULL;=0A=
-static int pe_enable_auto_image_base =3D 0;=0A=
+static int pe_enable_auto_image_base =3D 1;=0A=
 static char *pe_dll_search_prefix =3D NULL;=0A=
 #endif=0A=
 =0A=
@@ -130,6 +130,7 @@=0A=
   output_filename =3D "${EXECUTABLE_NAME:-a.exe}";=0A=
   ldfile_output_architecture =3D bfd_arch_${ARCH};=0A=
 #ifdef DLL_SUPPORT=0A=
+  config.dynamic_link =3D true;=0A=
   config.has_shared =3D 1;=0A=
 =0A=
 #if (PE_DEF_SUBSYSTEM =3D=3D 9) || (PE_DEF_SUBSYSTEM =3D=3D 2)=0A=
@@ -175,6 +176,8 @@=0A=
 #define OPTION_DISABLE_AUTO_IMAGE_BASE	(OPTION_ENABLE_AUTO_IMAGE_BASE + =
1)=0A=
 #define OPTION_DLL_SEARCH_PREFIX	(OPTION_DISABLE_AUTO_IMAGE_BASE + 1)=0A=
 #define OPTION_NO_DEFAULT_EXCLUDES	(OPTION_DLL_SEARCH_PREFIX + 1)=0A=
+#define OPTION_DLL_DISABLE_AUTO_IMPORT	(OPTION_NO_DEFAULT_EXCLUDES + 1)=0A=
+#define OPTION_DLL_ENABLE_GORY_DEBUG	(OPTION_DLL_DISABLE_AUTO_IMPORT + =
1)=0A=
 =0A=
 static struct option longopts[] =3D {=0A=
   /* PE options */=0A=
@@ -212,6 +215,8 @@=0A=
   {"disable-auto-image-base", no_argument, NULL, =
OPTION_DISABLE_AUTO_IMAGE_BASE},=0A=
   {"dll-search-prefix", required_argument, NULL, =
OPTION_DLL_SEARCH_PREFIX},=0A=
   {"no-default-excludes", no_argument, NULL, =
OPTION_NO_DEFAULT_EXCLUDES},=0A=
+  {"disable-auto-import", no_argument, NULL, =
OPTION_DLL_DISABLE_AUTO_IMPORT},=0A=
+  {"enable-gory-debug", no_argument, NULL, =
OPTION_DLL_ENABLE_GORY_DEBUG},=0A=
 #endif=0A=
   {NULL, no_argument, NULL, 0}=0A=
 };=0A=
@@ -297,6 +302,8 @@=0A=
   fprintf (file, _("  --dll-search-prefix=3D<string>       When linking =
dynamically to a dll witout an\n"));=0A=
   fprintf (file, _("                                       importlib, =
use <string><basename>.dll \n"));=0A=
   fprintf (file, _("                                       in =
preference to lib<basename>.dll \n"));=0A=
+  fprintf (file, _("  --disable-auto-import              Do not do =
sophistcated linking of _sym to \n"));=0A=
+  fprintf (file, _("                                       __imp_sym =
for DATA references\n"));=0A=
 #endif=0A=
 }=0A=
 =0A=
@@ -567,6 +574,12 @@=0A=
     case OPTION_NO_DEFAULT_EXCLUDES:=0A=
       pe_dll_do_default_excludes =3D 0;=0A=
       break;=0A=
+    case OPTION_DLL_DISABLE_AUTO_IMPORT:=0A=
+      pe_dll_auto_import =3D 0;=0A=
+      break;=0A=
+    case OPTION_DLL_ENABLE_GORY_DEBUG:=0A=
+      pe_dll_gory_debug =3D 1;=0A=
+      break;=0A=
 #endif=0A=
     }=0A=
   return 1;=0A=
@@ -717,6 +730,8 @@=0A=
   static int gave_warning_message =3D 0;=0A=
   struct bfd_link_hash_entry *undef, *sym;=0A=
   char *at;=0A=
+  if (pe_dll_gory_debug) printf(__FUNCTION__"\n");=0A=
+=0A=
   for (undef =3D link_info.hash->undefs; undef; undef=3Dundef->next)=0A=
     if (undef->type =3D=3D bfd_link_hash_undefined)=0A=
     {=0A=
@@ -775,11 +790,101 @@=0A=
       }=0A=
     }=0A=
 }=0A=
+=0A=
+static int=0A=
+make_import_fixup (rel)=0A=
+  arelent *rel;=0A=
+{=0A=
+  struct symbol_cache_entry *sym =3D *rel->sym_ptr_ptr;=0A=
+//  bfd *b;=0A=
+=0A=
+  if (pe_dll_gory_debug) printf("arelent: %s@%#x: =
add=3D%li\n",sym->name,(int)rel->address,rel->addend);=0A=
+  pe_create_import_fixup(rel);=0A=
+  return 1;=0A=
+}=0A=
+=0A=
+char *data_import_dll;=0A=
+=0A=
+static void=0A=
+pe_find_data_imports ()=0A=
+{=0A=
+  struct bfd_link_hash_entry *undef, *sym;=0A=
+  for (undef =3D link_info.hash->undefs; undef; undef=3Dundef->next)=0A=
+    if (undef->type =3D=3D bfd_link_hash_undefined)=0A=
+    {=0A=
+      /* C++ symbols are *long* */=0A=
+      char buf[4096];=0A=
+if (pe_dll_gory_debug) printf(__FUNCTION__":%s\n",undef->root.string);=0A=
+      sprintf(buf,"__imp_%s",undef->root.string);=0A=
+=0A=
+	sym =3D bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);=0A=
+	if (sym && sym->type =3D=3D bfd_link_hash_defined)=0A=
+	{=0A=
+          einfo (_("Warning: resolving %s by linking to %s =
(auto-import)\n"),=0A=
+    	     undef->root.string, buf);=0A=
+=0A=
+          {=0A=
+            bfd *b=3Dsym->u.def.section->owner;=0A=
+            asymbol **symbols;=0A=
+            int nsyms, symsize, i;=0A=
+     =0A=
+            symsize =3D bfd_get_symtab_upper_bound (b);=0A=
+            symbols =3D (asymbol **) xmalloc (symsize);=0A=
+            nsyms =3D bfd_canonicalize_symtab (b, symbols);=0A=
+=0A=
+            for (i =3D 0; i < nsyms; i++)=0A=
+	    {=0A=
+              if =
(memcmp(symbols[i]->name,"__head_",sizeof("__head_")-1))=0A=
+              	continue;=0A=
+if (pe_dll_gory_debug) printf("->%s\n",symbols[i]->name);=0A=
+              =
data_import_dll=3D(char*)(symbols[i]->name+sizeof("__head_")-1);=0A=
+              break;=0A=
+            }=0A=
+          }=0A=
+=0A=
+=0A=
+          pe_walk_relocs_of_symbol(&link_info, undef->root.string, =
make_import_fixup);=0A=
+=0A=
+          /* let's differentiate it somehow from defined */=0A=
+	  undef->type =3D bfd_link_hash_defweak;=0A=
+          /* we replace original name with __imp_ prefixed, this=0A=
+          1) may trash memory 2) leads to duplicate symbol generation.=0A=
+          Still, IMHO it's better than having name poluted. */=0A=
+	  undef->root.string =3D sym->root.string;=0A=
+	  undef->u.def.value =3D sym->u.def.value;=0A=
+	  undef->u.def.section =3D sym->u.def.section;=0A=
+      }=0A=
+    }=0A=
+}=0A=
 #endif /* DLL_SUPPORT */=0A=
 =0A=
+static boolean=0A=
+pr_sym (h, string)=0A=
+  struct bfd_hash_entry *h;=0A=
+  PTR string;=0A=
+{=0A=
+if (pe_dll_gory_debug) printf("+%s\n",h->string);=0A=
+  return true;=0A=
+}=0A=
+=0A=
+=0A=
 static void=0A=
 gld_${EMULATION_NAME}_after_open ()=0A=
 {=0A=
+=0A=
+if (pe_dll_gory_debug) =0A=
+{=0A=
+  bfd *a;=0A=
+  struct bfd_link_hash_entry *sym;=0A=
+  printf(__FUNCTION__"()\n");=0A=
+=0A=
+  for (sym =3D link_info.hash->undefs; sym; sym=3Dsym->next)=0A=
+    printf("-%s\n",sym->root.string);=0A=
+  bfd_hash_traverse(&link_info.hash->table,pr_sym,NULL);=0A=
+=0A=
+  for (a=3Dlink_info.input_bfds; a; a=3Da->link_next)=0A=
+    printf("*%s\n",a->filename);=0A=
+}=0A=
   /* Pass the wacky PE command line options into the output bfd.=0A=
      FIXME: This should be done via a function, rather than by=0A=
      including an internal BFD header.  */=0A=
@@ -794,6 +899,8 @@=0A=
   if (pe_enable_stdcall_fixup) /* -1=3Dwarn or 1=3Ddisable */=0A=
     pe_fixup_stdcalls ();=0A=
 =0A=
+  pe_find_data_imports (output_bfd, &link_info);=0A=
+=0A=
   pe_process_import_defs(output_bfd, &link_info);=0A=
   if (link_info.shared)=0A=
     pe_dll_build_sections (output_bfd, &link_info);=0A=
@@ -1235,6 +1342,16 @@=0A=
   if (pe_out_def_filename)=0A=
     pe_dll_generate_def_file (pe_out_def_filename);=0A=
 #endif /* DLL_SUPPORT */=0A=
+=0A=
+/* I don't know which bugger sets .idata as code */=0A=
+  {=0A=
+    asection *asec =3D bfd_get_section_by_name (output_bfd, ".idata");=0A=
+    if (asec)=0A=
+      {=0A=
+          asec->flags &=3D ~SEC_CODE;=0A=
+          asec->flags |=3D SEC_DATA;=0A=
+      }=0A=
+  }=0A=
 }=0A=
 =0A=
diff -uwr org/ld/ldlang.c src/ld/ldlang.c=0A=
--- org/ld/ldlang.c	Thu Jan 25 02:31:42 2001=0A=
+++ src/ld/ldlang.c	Fri Apr 27 17:12:35 2001=0A=
@@ -1432,6 +1432,10 @@=0A=
       bfd_error_type err;=0A=
       lang_statement_list_type *hold;=0A=
 =0A=
+      /* See if the emulation has some special knowledge.  */=0A=
+      if (ldemul_unrecognized_file (entry))=0A=
+  	return;=0A=
+=0A=
       err =3D bfd_get_error ();=0A=
       if (err =3D=3D bfd_error_file_ambiguously_recognized)=0A=
 	{=0A=
@@ -1450,11 +1454,6 @@=0A=
       bfd_close (entry->the_bfd);=0A=
       entry->the_bfd =3D NULL;=0A=
 =0A=
-      /* See if the emulation has some special knowledge.  */=0A=
-=0A=
-      if (ldemul_unrecognized_file (entry))=0A=
-	return;=0A=
-=0A=
       /* Try to interpret the file as a linker script.  */=0A=
 =0A=
       ldfile_open_command_file (entry->filename);=0A=
diff -uwr org/ld/pe-dll.c src/ld/pe-dll.c=0A=
--- org/ld/pe-dll.c	Tue Oct 10 03:28:01 2000=0A=
+++ src/ld/pe-dll.c	Fri Apr 27 17:25:45 2001=0A=
@@ -54,6 +54,84 @@=0A=
 =0A=
  =
************************************************************************/=0A=
 =0A=
+/***********************************************************************=
*=0A=
+=0A=
+ Auto-import feature by Paul Sokolovsky=0A=
+=0A=
+ Quick facts:=0A=
+=0A=
+ 1. With this feature on, DLL clients can import variables from DLL=0A=
+ without any concern from their side (for example, without any source=0A=
+ code modifications).=0A=
+=0A=
+ 2. This is done completely in bounds of the PE specification (to be =
fair,=0A=
+ there's a place where it pokes nose out of, but in practise it works).=0A=
+ So, resulting module can be used with any other PE compiler/linker.=0A=
+=0A=
+ 3. Auto-import is fully compatible with standard import method and they=0A=
+ can be mixed together.=0A=
+=0A=
+ 4. Overheads: space: 8 bytes per imported symbol, plus 20 for each=0A=
+ reference to it; load time: negligible; virtual/physical memory: =
should be=0A=
+ less than effect of DLL relocation, and I sincerely hope it doesn't =
affect=0A=
+ DLL sharability (too much).=0A=
+=0A=
+ Idea=0A=
+=0A=
+ The obvious and only way to get rid of dllimport insanity is to make =
client=0A=
+ access variable directly in the DLL, bypassing extra dereference. I.e.,=0A=
+ whenever client contains someting like=0A=
+=0A=
+ mov dll_var,%eax,=0A=
+=0A=
+ address of dll_var in the command should be relocated to point into =
loaded=0A=
+ DLL. The aim is to make OS loader do so, and than make ld help with =
that.=0A=
+ Import section of PE made following way: there's a vector of structures=0A=
+ each describing imports from particular DLL. Each such structure points=0A=
+ to two other parellel vectors: one holding imported names, and one =
which=0A=
+ will hold address of corresponding imported name. So, the solution is=0A=
+ de-vectorize these structures, making import locations be sparse and=0A=
+ pointing directly into code. Before continuing, it is worth a note =
that,=0A=
+ while authors strives to make PE act ELF-like, there're some other =
people=0A=
+ make ELF act PE-like: elfvector, ;-) .=0A=
+=0A=
+ Implementation=0A=
+=0A=
+ For each reference of data symbol to be imported from DLL (to set of =
which=0A=
+ belong symbols with name <sym>, if __imp_<sym> is found in implib), the=0A=
+ import fixup entry is generated. That entry is of type=0A=
+ IMAGE_IMPORT_DESCRIPTOR and stored in .idata$3 subsection. Each=0A=
+ fixup entry contains pointer to symbol's address within .text section=0A=
+ (marked with __fuN_<sym> symbol, where N is integer), pointer to DLL =
name=0A=
+ (so, DLL name is referenced by multiple entries), and pointer to symbol=0A=
+ name thunk. Symbol name thunk is singleton vector (__nm_th_<symbol>)=0A=
+ pointing to IMAGE_IMPORT_BY_NAME structure (__nm_<symbol>) directly=0A=
+ containing imported name. Here comes that "om the edge" problem =
mentioned=0A=
+ above: PE specification rambles that name vector (OriginalFirstThunk)=0A=
+ should run in parallel with addresses vector (FirstThunk), i.e. that =
they=0A=
+ should have same number of elements and terminated with zero. We =
violate=0A=
+ this, since FirstThunk points directly into machine code. But in =
practise,=0A=
+ OS loader implemented the sane way: it goes thru OriginalFirstThunk and=0A=
+ puts addresses to FirstThunk, not something else. It once again should =
be=0A=
+ noted that dll and symbol name structures are reused across fixup =
entries=0A=
+ and should be there anyway to support standard import stuff, so =
sustained=0A=
+ overhead is 20 bytes per reference. Other question is whether having =
several=0A=
+ IMAGE_IMPORT_DESCRIPTORS for the same DLL is possible. Answer is yes, =
it is=0A=
+ done even by native compiler/linker (libth32's functions are in fact =
reside=0A=
+ in windows9x kernel32.dll, so if you use it, you have two=0A=
+ IMAGE_IMPORT_DESCRIPTORS for kernel32.dll). Yet other question is =
whether=0A=
+ referencing the same PE structures several times is valid. The answer =
is why=0A=
+ not, prohibitting that (detecting violation) would require more work on=0A=
+ behalf of loader than not doing it.=0A=
+=0A=
+=0A=
+ See also: ld/emultempl/pe.em=0A=
+=0A=
+ =
************************************************************************/=0A=
+=0A=
+void=0A=
+add_bfd_to_link (bfd *abfd, CONST char *name, struct bfd_link_info =
*link_info);=0A=
+=0A=
 /* for emultempl/pe.em */=0A=
 =0A=
 def_file *pe_def_file =3D 0;=0A=
@@ -63,6 +141,7 @@=0A=
 int pe_dll_stdcall_aliases =3D 0;=0A=
 int pe_dll_warn_dup_exports =3D 0;=0A=
 int pe_dll_compat_implib =3D 0;=0A=
+int pe_dll_gory_debug =3D 0;=0A=
 =0A=
 =
/************************************************************************=0A=
 =0A=
@@ -231,24 +310,79 @@=0A=
   free (local_copy);=0A=
 }=0A=
 =0A=
+/*=0A=
+   abfd is a bfd containing n (or NULL)=0A=
+   It can be used for contextual checks.=0A=
+*/=0A=
 static int=0A=
-auto_export (d, n)=0A=
+auto_export (abfd, d, n)=0A=
+     bfd *abfd;=0A=
      def_file *d;=0A=
      const char *n;=0A=
 {=0A=
   int i;=0A=
   struct exclude_list_struct *ex;=0A=
+=0A=
+  /* we should not re-export imported stuff */=0A=
+  if (strncmp (n, "_imp__",6) =3D=3D 0)=0A=
+    return 0;=0A=
+=0A=
   for (i =3D 0; i < d->num_exports; i++)=0A=
     if (strcmp (d->exports[i].name, n) =3D=3D 0)=0A=
       return 0;=0A=
   if (pe_dll_do_default_excludes)=0A=
     {=0A=
+if (pe_dll_gory_debug) printf("considering exporting: %s "=0A=
+	"abfd=3D%x, abfd->my_arc=3D%x\n",n,abfd,abfd->my_archive);=0A=
+      /* First of all, make context checks:=0A=
+         Don't export anything from libgcc */=0A=
+=0A=
+      if (abfd=0A=
+          && abfd->my_archive)=0A=
+        {=0A=
+          /* Do not specify suffix explicitly, to allow for dllized =
versions */=0A=
+          if (strstr(abfd->my_archive->filename,"libgcc.")) return 0;=0A=
+          if (strstr(abfd->my_archive->filename,"libstdc++.")) return 0;=0A=
+          if (strstr(abfd->my_archive->filename,"libmingw32.")) return =
0;=0A=
+        }=0A=
+=0A=
+      {=0A=
+        /* skip .*crt\d\.o */=0A=
+        char *p;=0A=
+        if (abfd=0A=
+            && (p=3Dstrstr(abfd->filename,"crt"))=0A=
+            && (isdigit(p[3]) && p[4]=3D=3D'.' && p[5]=3D=3D'o' && =
p[6]=3D=3D0)) return 0;=0A=
+      }=0A=
+=0A=
+#if 0=0A=
+      /* Don't export any 'reserved' symbols */=0A=
+      if (*n && *n=3D=3D'_' && n[1]=3D=3D'_') return 0;=0A=
+#endif=0A=
+=0A=
       if (strcmp (n, "DllMain AT 12") =3D=3D 0)=0A=
 	return 0;=0A=
       if (strcmp (n, "DllEntryPoint AT 0") =3D=3D 0)=0A=
 	return 0;=0A=
+      if (strcmp (n, "DllMainCRTStartup AT 12") =3D=3D 0)=0A=
+	return 0;=0A=
       if (strcmp (n, "impure_ptr") =3D=3D 0)=0A=
 	return 0;=0A=
+=0A=
+      if (strncmp (n, "__rtti_", 7) =3D=3D 0)=0A=
+	return 0;=0A=
+      if (strncmp (n, "__builtin_", 10) =3D=3D 0)=0A=
+	return 0;=0A=
+=0A=
+      /* Don't export symbols for specifying DLL's internal layout */=0A=
+=0A=
+      if (strncmp (n, "_head_", 6) =3D=3D 0)=0A=
+	return 0;=0A=
+=0A=
+      {=0A=
+        int len =3D strlen(n);=0A=
+        if (len>6 && strncmp (n + len - 6, "_iname", 7) =3D=3D 0)=0A=
+	  return 0;=0A=
+      }=0A=
     }=0A=
   for (ex =3D excludes; ex; ex =3D ex->next)=0A=
     if (strcmp (n, ex->string) =3D=3D 0)=0A=
@@ -302,14 +436,29 @@=0A=
 	  for (j =3D 0; j < nsyms; j++)=0A=
 	    {=0A=
 	      /* We should export symbols which are either global or not=0A=
-	         anything at all.  (.bss data is the latter)  */=0A=
-	      if ((symbols[j]->flags & BSF_GLOBAL)=0A=
-		  || (symbols[j]->flags =3D=3D BSF_NO_FLAGS))=0A=
+	         anything at all.  (.bss data is the latter)=0A=
+                 We should not export undefined symbols=0A=
+              */=0A=
+	      if (symbols[j]->section!=3D&bfd_und_section=0A=
+                  && ((symbols[j]->flags & BSF_GLOBAL)=0A=
+		      || (symbols[j]->flags =3D=3D BFD_FORT_COMM_DEFAULT_VALUE)))=0A=
 		{=0A=
 		  const char *sn =3D symbols[j]->name;=0A=
+=0A=
+                  /* we should not re-export imported stuff */=0A=
+                  {=0A=
+                    char *name =3D (char *) xmalloc (strlen (sn) + 2 + =
6);=0A=
+                    sprintf (name, "%s%s", U("_imp_"), sn);=0A=
+                    blhe =3D bfd_link_hash_lookup (info->hash, name,=0A=
+                        			 false, false, false);=0A=
+                    free (name);=0A=
+=0A=
+                    if (blhe && blhe->type =3D=3D =
bfd_link_hash_defined) continue;=0A=
+                  }=0A=
+=0A=
 		  if (*sn =3D=3D '_')=0A=
 		    sn++;=0A=
-		  if (auto_export (pe_def_file, sn))=0A=
+		  if (auto_export (b, pe_def_file, sn))=0A=
                     {=0A=
                       def_file_export *p;=0A=
                       p=3Ddef_file_add_export (pe_def_file, sn, 0, -1);=0A=
@@ -350,7 +499,7 @@=0A=
 	    {=0A=
 	      char *tmp =3D xstrdup (pe_def_file->exports[i].name);=0A=
 	      *(strchr (tmp, '@')) =3D 0;=0A=
-	      if (auto_export (pe_def_file, tmp))=0A=
+	      if (auto_export (NULL, pe_def_file, tmp))=0A=
 		def_file_add_export (pe_def_file, tmp,=0A=
 				     pe_def_file->exports[i].internal_name, -1);=0A=
 	      else=0A=
@@ -731,6 +880,52 @@=0A=
     }=0A=
 }=0A=
 =0A=
+=0A=
+static struct sec *current_sec;=0A=
+=0A=
+void=0A=
+pe_walk_relocs_of_symbol (info, name, cb)=0A=
+     struct bfd_link_info *info;=0A=
+     CONST char *name;=0A=
+     int (*cb)(arelent*);=0A=
+{=0A=
+  bfd *b;=0A=
+  struct sec *s;=0A=
+=0A=
+  for (b =3D info->input_bfds; b; b =3D b->link_next)=0A=
+    {=0A=
+      arelent **relocs;=0A=
+      int relsize, nrelocs, i;=0A=
+=0A=
+      for (s =3D b->sections; s; s =3D s->next)=0A=
+	{=0A=
+	  asymbol **symbols;=0A=
+	  int nsyms, symsize;=0A=
+=0A=
+          current_sec=3Ds;=0A=
+=0A=
+	  symsize =3D bfd_get_symtab_upper_bound (b);=0A=
+	  symbols =3D (asymbol **) xmalloc (symsize);=0A=
+	  nsyms =3D bfd_canonicalize_symtab (b, symbols);=0A=
+=0A=
+	  relsize =3D bfd_get_reloc_upper_bound (b, s);=0A=
+	  relocs =3D (arelent **) xmalloc ((size_t) relsize);=0A=
+	  nrelocs =3D bfd_canonicalize_reloc (b, s, relocs, symbols);=0A=
+=0A=
+	  for (i =3D 0; i < nrelocs; i++)=0A=
+	    {=0A=
+              struct symbol_cache_entry *sym =3D =
*relocs[i]->sym_ptr_ptr;=0A=
+              if (!strcmp(name,sym->name)) cb(relocs[i]);=0A=
+	    }=0A=
+	  free (relocs);=0A=
+	  /* Warning: the allocated symbols are remembered in BFD and reused=0A=
+	     later, so don't free them! */=0A=
+	  /* free (symbols); */=0A=
+	}=0A=
+    }=0A=
+=0A=
+}=0A=
+=0A=
 =
/************************************************************************=0A=
 =0A=
  Gather all the relocations and build the .reloc section=0A=
@@ -801,6 +996,10 @@=0A=
 =0A=
 	  for (i =3D 0; i < nrelocs; i++)=0A=
 	    {=0A=
+if (pe_dll_gory_debug) {=0A=
+struct symbol_cache_entry *sym =3D *relocs[i]->sym_ptr_ptr;=0A=
+printf("rel: %s\n",sym->name);=0A=
+}=0A=
 	      if (!relocs[i]->howto->pc_relative=0A=
 		  && relocs[i]->howto->type !=3D pe_details->imagebase_reloc)=0A=
 		{=0A=
@@ -902,6 +902,13 @@=0A=
          asymbol **symbols;=0A=
          int nsyms, symsize;=0A=
=0A=
+          int flags =3D bfd_get_section_flags (b, s);=0A=
+=0A=
+          /* Skip discarded linkonce sections */=0A=
+          if (flags & SEC_LINK_ONCE=0A=
+              && s->output_section =3D=3D bfd_abs_section_ptr)=0A=
+            continue;=0A=
+=0A=
           current_sec=3Ds;=0A=
=0A=
          symsize =3D bfd_get_symtab_upper_bound (b);=0A=
@@ -1039,7 +1238,7 @@=0A=
 =0A=
       if (pe_def_file->num_exports > 0)=0A=
 	{=0A=
-	  fprintf (out, "\nEXPORTS\n\n");=0A=
+	  fprintf (out, "EXPORTS\n");=0A=
 	  for (i =3D 0; i < pe_def_file->num_exports; i++)=0A=
 	    {=0A=
 	      def_file_export *e =3D pe_def_file->exports + i;=0A=
@@ -1445,7 +1644,7 @@=0A=
   bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);=0A=
 =0A=
   symptr =3D 0;=0A=
-  symtab =3D (asymbol **) xmalloc (10 * sizeof (asymbol *));=0A=
+  symtab =3D (asymbol **) xmalloc (11 * sizeof (asymbol *));=0A=
   tx  =3D quick_section (abfd, ".text",    SEC_CODE|SEC_HAS_CONTENTS, =
2);=0A=
   id7 =3D quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);=0A=
   id5 =3D quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);=0A=
@@ -1455,6 +1654,9 @@=0A=
     quick_symbol (abfd, U (""), exp->internal_name, "", tx, BSF_GLOBAL, =
0);=0A=
   quick_symbol (abfd, U ("_head_"), dll_symname, "", UNDSEC, =
BSF_GLOBAL, 0);=0A=
   quick_symbol (abfd, U ("_imp__"), exp->internal_name, "", id5, =
BSF_GLOBAL, 0);=0A=
+  /* symbol to reference ord/name of imported symbol, used to implement=0A=
+     auto-import */=0A=
+  quick_symbol (abfd, U("_nm__"), exp->internal_name, "", id6, =
BSF_GLOBAL, 0);=0A=
   if (pe_dll_compat_implib)=0A=
     quick_symbol (abfd, U ("__imp_"), exp->internal_name, "",=0A=
 		  id5, BSF_GLOBAL, 0);=0A=
@@ -1553,6 +1755,175 @@=0A=
   return abfd;=0A=
 }=0A=
 =0A=
+static bfd *=0A=
+make_singleton_name_thunk (import, parent)=0A=
+     char *import;=0A=
+     bfd *parent;=0A=
+{=0A=
+  /* name thunks go to idata$4 */=0A=
+=0A=
+  asection *id4;=0A=
+  unsigned char *d4;=0A=
+  char *oname;=0A=
+  bfd *abfd;=0A=
+=0A=
+  oname =3D (char *) xmalloc (20);=0A=
+  sprintf (oname, "nmth%06d.o", tmp_seq);=0A=
+  tmp_seq++;=0A=
+=0A=
+  abfd =3D bfd_create (oname, parent);=0A=
+  bfd_find_target (pe_details->object_target, abfd);=0A=
+  bfd_make_writable (abfd);=0A=
+=0A=
+  bfd_set_format (abfd, bfd_object);=0A=
+  bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);=0A=
+=0A=
+  symptr =3D 0;=0A=
+  symtab =3D (asymbol **) xmalloc (3 * sizeof (asymbol *));=0A=
+  id4 =3D quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);=0A=
+  quick_symbol (abfd, U("_nm_thnk_"), import, "", id4, BSF_GLOBAL, 0);=0A=
+  quick_symbol (abfd, U("_nm_"), import, "", UNDSEC, BSF_GLOBAL, 0);=0A=
+=0A=
+  bfd_set_section_size (abfd, id4, 8);=0A=
+  d4 =3D (unsigned char *) xmalloc (4);=0A=
+  id4->contents =3D d4;=0A=
+  memset (d4, 0, 8);=0A=
+  quick_reloc (abfd, 0, BFD_RELOC_RVA, 2);=0A=
+  save_relocs (id4);=0A=
+=0A=
+  bfd_set_symtab (abfd, symtab, symptr);=0A=
+=0A=
+  bfd_set_section_contents (abfd, id4, d4, 0, 8);=0A=
+=0A=
+  bfd_make_readable (abfd);=0A=
+  return abfd;=0A=
+}=0A=
+=0A=
+char *=0A=
+make_import_fixup_mark (rel)=0A=
+     arelent *rel;=0A=
+{=0A=
+  /* we convert reloc to symbol, for later reference */=0A=
+  static int counter;=0A=
+  static char fixup_name[300];=0A=
+=0A=
+  struct symbol_cache_entry *sym =3D *rel->sym_ptr_ptr;=0A=
+=0A=
+  bfd *abfd=3Dbfd_asymbol_bfd(sym);=0A=
+  struct coff_link_hash_entry *myh=3DNULL;=0A=
+=0A=
+  sprintf(fixup_name,"__fu%d_%s",counter++,sym->name);=0A=
+  bfd_coff_link_add_one_symbol(&link_info,=0A=
+                                   abfd,=0A=
+                                   fixup_name,=0A=
+                                   BSF_GLOBAL,=0A=
+                                   current_sec, //sym->section,=0A=
+                                   rel->address,=0A=
+                                   NULL,=0A=
+                                   true,=0A=
+                                   false,=0A=
+                                   (struct bfd_link_hash_entry **) =
&myh);=0A=
+=0A=
+/*printf("type:%d\n",myh->type);=0A=
+printf("%s\n",myh->root.u.def.section->name);=0A=
+*/=0A=
+  return fixup_name;=0A=
+}=0A=
+=0A=
+=0A=
+/*=0A=
+ *	.section	.idata$3=0A=
+ *	.rva		__nm_thnk_SYM (singleton thunk with name of func)=0A=
+ *	.long		0=0A=
+ *	.long		0=0A=
+ *	.rva		__my_dll_iname (name of dll)=0A=
+ *	.rva		__fuNN_SYM (pointer to reference (address) in text)=0A=
+ *=0A=
+ */=0A=
+=0A=
+static bfd *=0A=
+make_import_fixup_entry (name,fixup_name,dll_symname,parent)=0A=
+     char *name;=0A=
+     char *fixup_name;=0A=
+     char *dll_symname;=0A=
+     bfd *parent;=0A=
+{=0A=
+  asection *id3;=0A=
+  unsigned char *d3;=0A=
+  char *oname;=0A=
+  bfd *abfd;=0A=
+=0A=
+  oname =3D (char *) xmalloc (20);=0A=
+  sprintf (oname, "fu%06d.o", tmp_seq);=0A=
+  tmp_seq++;=0A=
+=0A=
+  abfd =3D bfd_create (oname, parent);=0A=
+  bfd_find_target (pe_details->object_target, abfd);=0A=
+  bfd_make_writable (abfd);=0A=
+=0A=
+  bfd_set_format (abfd, bfd_object);=0A=
+  bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);=0A=
+=0A=
+  symptr =3D 0;=0A=
+  symtab =3D (asymbol **) xmalloc (6 * sizeof (asymbol *));=0A=
+  id3 =3D quick_section (abfd, ".idata$3", SEC_HAS_CONTENTS, 2);=0A=
+//  quick_symbol (abfd, U("_head_"), dll_symname, "", id2, BSF_GLOBAL, =
0);=0A=
+=0A=
+  quick_symbol (abfd, U("_nm_thnk_"), name, "", UNDSEC, BSF_GLOBAL, 0);=0A=
+  quick_symbol (abfd, U(""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, =
0);=0A=
+  quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);=0A=
+=0A=
+  bfd_set_section_size (abfd, id3, 20);=0A=
+  d3 =3D (unsigned char *) xmalloc (20);=0A=
+  id3->contents =3D d3;=0A=
+  memset (d3, 0, 20);=0A=
+=0A=
+  quick_reloc (abfd,  0, BFD_RELOC_RVA, 1);=0A=
+  quick_reloc (abfd, 12, BFD_RELOC_RVA, 2);=0A=
+  quick_reloc (abfd, 16, BFD_RELOC_RVA, 3);=0A=
+  save_relocs (id3);=0A=
+=0A=
+  bfd_set_symtab (abfd, symtab, symptr);=0A=
+=0A=
+  bfd_set_section_contents (abfd, id3, d3, 0, 20);=0A=
+=0A=
+  bfd_make_readable (abfd);=0A=
+  return abfd;=0A=
+}=0A=
+=0A=
+void=0A=
+pe_create_import_fixup (rel)=0A=
+     arelent *rel;=0A=
+{=0A=
+  char buf[300];=0A=
+  struct symbol_cache_entry *sym =3D *rel->sym_ptr_ptr;=0A=
+  struct bfd_link_hash_entry *name_thunk_sym;=0A=
+  CONST char *name =3D sym->name;=0A=
+  char *fixup_name =3D make_import_fixup_mark(rel);=0A=
+=0A=
+  sprintf(buf,U("_nm_thnk_%s"),name);=0A=
+=0A=
+  name_thunk_sym =3D=0A=
+           bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);=0A=
+=0A=
+  if (!name_thunk_sym || name_thunk_sym->type !=3D =
bfd_link_hash_defined)=0A=
+  {=0A=
+    bfd *b=3Dmake_singleton_name_thunk (name, output_bfd);=0A=
+    add_bfd_to_link (b, b->filename, &link_info);=0A=
+=0A=
+    /* If we ever use autoimport, we have to cast text section writable =
*/=0A=
+    config.text_read_only=3Dfalse;=0A=
+  }=0A=
+=0A=
+  {=0A=
+    extern char *data_import_dll;=0A=
+    bfd *b=3Dmake_import_fixup_entry =
(name,fixup_name,data_import_dll,output_bfd);=0A=
+    add_bfd_to_link (b, b->filename, &link_info);=0A=
+  }=0A=
+=0A=
+}=0A=
+=0A=
+=0A=
 void=0A=
 pe_dll_generate_implib (def, impfilename)=0A=
      def_file *def;=0A=
@@ -1628,10 +1999,10 @@=0A=
     }=0A=
 }=0A=
 =0A=
-static void=0A=
+void=0A=
 add_bfd_to_link (abfd, name, link_info)=0A=
      bfd *abfd;=0A=
-     char *name;=0A=
+     CONST char *name;=0A=
      struct bfd_link_info *link_info;=0A=
 {=0A=
   lang_input_statement_type *fake_file;=0A=
diff -uwr org/ld/pe-dll.h src/ld/pe-dll.h=0A=
--- org/ld/pe-dll.h	Tue Jan  4 23:44:03 2000=0A=
+++ src/ld/pe-dll.h	Fri Apr 27 17:25:53 2001=0A=
@@ -33,6 +33,10 @@=0A=
 extern int pe_dll_stdcall_aliases;=0A=
 extern int pe_dll_warn_dup_exports;=0A=
 extern int pe_dll_compat_implib;=0A=
+/* This resides in bfd */=0A=
+//_BFD_IMPORT =0A=
+extern int pe_dll_auto_import;=0A=
+extern int pe_dll_gory_debug;=0A=
 =0A=
 extern void pe_dll_id_target PARAMS ((const char *));=0A=
 extern void pe_dll_add_excludes PARAMS ((const char *));=0A=
@@ -45,4 +49,9 @@=0A=
 extern void pe_dll_fill_sections PARAMS ((bfd *, struct bfd_link_info =
*));=0A=
 extern void pe_exe_fill_sections PARAMS ((bfd *, struct bfd_link_info =
*));=0A=
 =0A=
+extern void pe_walk_relocs_of_symbol PARAMS ((struct bfd_link_info =
*info,=0A=
+                                              CONST char *name,=0A=
+                                              int (*cb)(arelent*)));=0A=
+=0A=
+extern void pe_create_import_fixup PARAMS ((arelent *rel));=0A=
 #endif /* PE_DLL_H */=0A=

------=_NextPart_000_02F2_01C0F269.37B6AB20--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019