+2002-11-14 Egor Duda <deo@logos-m.ru>
+
+ * bfdlink.h (struct bfd_link_info): Add new boolean
+ field pei386_runtime_pseudo_reloc.
+
2002-11-11 Svein E. Seldal <Svein.Seldal@solidas.com>
* opcode/tic4x.h: Added new opcodes and corrected some bugs. Add
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;
+2002-11-14 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-11-12 Earl Chew <earl_chew@agilent.com>
* ldlang.c (lang_add_section): Discard debugging sections that have
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* For WINDOWS_NT */
/* The original file generated returned different default scripts depending
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
#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 */
{"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}
};
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
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;
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;
}
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.
+
+A 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:
@{ 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
@}
@end example
-A third way to avoid this problem is to re-code your
+A fourth 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).
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. This is the default.
+
@kindex --enable-extra-pe-debug
@item --enable-extra-pe-debug
Show additional debug info related to auto-import symbol thunking.
Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com
-This file is part of GLD, the Gnu Linker.
+ This file is part of GLD, the Gnu Linker.
-GLD is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+ GLD is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
-GLD is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GLD is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with GLD; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GLD; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
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;
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
{
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 *));
static unsigned int pe_get16 PARAMS ((bfd *, int));
static unsigned int pe_get32 PARAMS ((bfd *, int));
static unsigned int pe_as32 PARAMS ((void *));
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);
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");
+ }
+ }
}
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 *, int));
#endif /* PE_DLL_H */