Add --enable-auto-import extension.

This commit is contained in:
Nick Clifton
2002-11-14 18:03:17 +00:00
parent 2f62977e68
commit 2fa9fc65a5
8 changed files with 224 additions and 45 deletions

View File

@ -1,3 +1,8 @@
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> 2002-11-11 Svein E. Seldal <Svein.Seldal@solidas.com>
* opcode/tic4x.h: Added new opcodes and corrected some bugs. Add * opcode/tic4x.h: Added new opcodes and corrected some bugs. Add

View File

@ -340,6 +340,11 @@ struct bfd_link_info
is explicitly requested by the user, -1 if enabled by default. */ is explicitly requested by the user, -1 if enabled by default. */
int pei386_auto_import; 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 /* True if non-PLT relocs should be merged into one reloc section
and sorted so that relocs against the same symbol come together. */ and sorted so that relocs against the same symbol come together. */
boolean combreloc; boolean combreloc;

View File

@ -1,3 +1,19 @@
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> 2002-11-12 Earl Chew <earl_chew@agilent.com>
* ldlang.c (lang_add_section): Discard debugging sections that have * ldlang.c (lang_add_section): Discard debugging sections that have

View File

@ -12,19 +12,19 @@ cat >>e${EMULATION_NAME}.c <<EOF
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc. Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* For WINDOWS_NT */ /* For WINDOWS_NT */
/* The original file generated returned different default scripts depending /* The original file generated returned different default scripts depending
@ -174,6 +174,7 @@ gld_${EMULATION_NAME}_before_parse()
config.dynamic_link = true; config.dynamic_link = true;
config.has_shared = 1; config.has_shared = 1;
link_info.pei386_auto_import = -1; link_info.pei386_auto_import = -1;
link_info.pei386_runtime_pseudo_reloc = false;
#if (PE_DEF_SUBSYSTEM == 9) || (PE_DEF_SUBSYSTEM == 2) #if (PE_DEF_SUBSYSTEM == 9) || (PE_DEF_SUBSYSTEM == 2)
#if defined TARGET_IS_mipspe || defined TARGET_IS_armpe #if defined TARGET_IS_mipspe || defined TARGET_IS_armpe
@ -222,6 +223,10 @@ gld_${EMULATION_NAME}_before_parse()
#define OPTION_DLL_DISABLE_AUTO_IMPORT (OPTION_DLL_ENABLE_AUTO_IMPORT + 1) #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_ENABLE_EXTRA_PE_DEBUG (OPTION_DLL_DISABLE_AUTO_IMPORT + 1)
#define OPTION_EXCLUDE_LIBS (OPTION_ENABLE_EXTRA_PE_DEBUG + 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[] = { static struct option longopts[] = {
/* PE options */ /* PE options */
@ -263,6 +268,8 @@ static struct option longopts[] = {
{"enable-auto-import", no_argument, NULL, OPTION_DLL_ENABLE_AUTO_IMPORT}, {"enable-auto-import", no_argument, NULL, OPTION_DLL_ENABLE_AUTO_IMPORT},
{"disable-auto-import", no_argument, NULL, OPTION_DLL_DISABLE_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-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 #endif
{NULL, no_argument, NULL, 0} {NULL, no_argument, NULL, 0}
}; };
@ -352,6 +359,10 @@ gld_${EMULATION_NAME}_list_options (file)
fprintf (file, _(" --enable-auto-import Do sophistcated linking of _sym to \n\ fprintf (file, _(" --enable-auto-import Do sophistcated linking of _sym to \n\
__imp_sym for DATA references\n")); __imp_sym for DATA references\n"));
fprintf (file, _(" --disable-auto-import Do not auto-import DATA items from DLLs\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\ fprintf (file, _(" --enable-extra-pe-debug Enable verbose debug output when building\n\
or linking to DLLs (esp. auto-import)\n")); or linking to DLLs (esp. auto-import)\n"));
#endif #endif
@ -633,6 +644,12 @@ gld_${EMULATION_NAME}_parse_args(argc, argv)
case OPTION_DLL_DISABLE_AUTO_IMPORT: case OPTION_DLL_DISABLE_AUTO_IMPORT:
link_info.pei386_auto_import = 0; link_info.pei386_auto_import = 0;
break; 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: case OPTION_ENABLE_EXTRA_PE_DEBUG:
pe_dll_extra_pe_debug = 1; pe_dll_extra_pe_debug = 1;
break; break;
@ -877,14 +894,7 @@ make_import_fixup (rel, s)
einfo (_("%C: Cannot get section contents - auto-import exception\n"), einfo (_("%C: Cannot get section contents - auto-import exception\n"),
s->owner, s, rel->address); s->owner, s, rel->address);
if (addend == 0) pe_create_import_fixup (rel, s, addend);
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");
}
return 1; return 1;
} }

View File

@ -1808,7 +1808,11 @@ the warning, and exit.
There are several ways to address this difficulty, regardless of the There are several ways to address this difficulty, regardless of the
data type of the exported variable: 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, that is, unknown and un-optimizable at compile time. For arrays,
there are two possibilities: a) make the indexee (the array's address) there are two possibilities: a) make the indexee (the array's address)
a variable, or b) make the 'constant' index a variable. Thus: a variable, or b) make the 'constant' index a variable. Thus:
@ -1844,7 +1848,7 @@ extern_ll -->
@{ volatile long long * local_ll=&extern_ll; *local_ll @} @{ volatile long long * local_ll=&extern_ll; *local_ll @}
@end example @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 'auto-import' for the offending symbol and mark it with
@code{__declspec(dllimport)}. However, in practice that @code{__declspec(dllimport)}. However, in practice that
requires using compile-time #defines to indicate whether you are requires using compile-time #defines to indicate whether you are
@ -1895,7 +1899,7 @@ void main(int argc, char **argv)@{
@} @}
@end example @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 library to use a functional interface rather than a data interface
for the offending variables (e.g. set_foo() and get_foo() accessor for the offending variables (e.g. set_foo() and get_foo() accessor
functions). functions).
@ -1905,6 +1909,18 @@ functions).
Do not attempt to do sophisticalted linking of @code{_symbol} to Do not attempt to do sophisticalted linking of @code{_symbol} to
@code{__imp__symbol} for DATA imports from DLLs. @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 @kindex --enable-extra-pe-debug
@item --enable-extra-pe-debug @item --enable-extra-pe-debug
Show additional debug info related to auto-import symbol thunking. Show additional debug info related to auto-import symbol thunking.

View File

@ -4,22 +4,22 @@
Free Software Foundation, Inc. Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com 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 GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
GLD is distributed in the hope that it will be useful, GLD is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License 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 along with GLD; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */ 02111-1307, USA. */
#include "bfd.h" #include "bfd.h"
#include "sysdep.h" #include "sysdep.h"
@ -261,8 +261,8 @@ main (argc, argv)
link_info.eh_frame_hdr = false; link_info.eh_frame_hdr = false;
link_info.flags = (bfd_vma) 0; link_info.flags = (bfd_vma) 0;
link_info.flags_1 = (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_auto_import = -1;
link_info.pei386_runtime_pseudo_reloc = false;
link_info.combreloc = true; link_info.combreloc = true;
link_info.spare_dynamic_tags = 5; link_info.spare_dynamic_tags = 5;
link_info.common_skip_ar_aymbols = bfd_link_common_skip_none; link_info.common_skip_ar_aymbols = bfd_link_common_skip_none;

View File

@ -141,6 +141,7 @@ static bfd *filler_bfd;
static struct sec *edata_s, *reloc_s; static struct sec *edata_s, *reloc_s;
static unsigned char *edata_d, *reloc_d; static unsigned char *edata_d, *reloc_d;
static size_t edata_sz, reloc_sz; static size_t edata_sz, reloc_sz;
static int runtime_pseudo_relocs_created = 0;
typedef struct typedef struct
{ {
@ -305,6 +306,10 @@ static bfd *make_singleton_name_thunk PARAMS ((const char *, bfd *));
static char *make_import_fixup_mark PARAMS ((arelent *)); static char *make_import_fixup_mark PARAMS ((arelent *));
static bfd *make_import_fixup_entry static bfd *make_import_fixup_entry
PARAMS ((const char *, const char *, const char *, bfd *)); 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_get16 PARAMS ((bfd *, int));
static unsigned int pe_get32 PARAMS ((bfd *, int)); static unsigned int pe_get32 PARAMS ((bfd *, int));
static unsigned int pe_as32 PARAMS ((void *)); static unsigned int pe_as32 PARAMS ((void *));
@ -2094,15 +2099,112 @@ make_import_fixup_entry (name, fixup_name, dll_symname, parent)
return abfd; 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 void
pe_create_import_fixup (rel) pe_create_import_fixup (rel, s, addend)
arelent *rel; arelent *rel;
asection *s;
int addend;
{ {
char buf[300]; char buf[300];
struct symbol_cache_entry *sym = *rel->sym_ptr_ptr; struct symbol_cache_entry *sym = *rel->sym_ptr_ptr;
struct bfd_link_hash_entry *name_thunk_sym; struct bfd_link_hash_entry *name_thunk_sym;
const char *name = sym->name; const char *name = sym->name;
char *fixup_name = make_import_fixup_mark (rel); char *fixup_name = make_import_fixup_mark (rel);
bfd *b;
sprintf (buf, U ("_nm_thnk_%s"), name); sprintf (buf, U ("_nm_thnk_%s"), name);
@ -2117,14 +2219,39 @@ pe_create_import_fixup (rel)
config.text_read_only = false; config.text_read_only = false;
} }
{ 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"; 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, b = make_import_fixup_entry (name, fixup_name, dll_symname, output_bfd);
output_bfd); add_bfd_to_link (b, b->filename, &link_info);
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");
}
}
} }

View File

@ -50,5 +50,5 @@ extern void pe_walk_relocs_of_symbol PARAMS ((struct bfd_link_info * info,
const char *name, const char *name,
int (*cb) (arelent *, asection *))); 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 */ #endif /* PE_DLL_H */