2001-09-12 Paul Sokolovsky <Paul.Sokolovsky@technologist.com>

* emultempl/pe.em(make_import_fixup): change signature to
        take asection as well as arelec; we need this for proper
        error reporting.  Only call pe_create_import_fixup() if
        there is no attempt to add a constant addend to the reloc;
        otherwise, report error condition.
        * pe-dll.c(pe_walk_relocs_of_symbol): change signature,
        since final argument is a pointer to make_import_fixup().
        Change call to cb() to match make_import_fixup() signature.
        (make_import_fixup_mark): make buffer_len unsigned.
        * pe-dll.h: change signature of pe_walk_relocs_of_symbol.
2001-09-12  Charles Wilson  <cwilson@ece.gatech.edu>
        * ld.texinfo: add verbose documentation for auto-import
        direct-addressing workaround, to compliment the terse
        error message.
This commit is contained in:
Charles Wilson 2001-09-12 15:58:10 +00:00
parent cedacdc05a
commit 0d888aac30
5 changed files with 143 additions and 14 deletions

View File

@ -1,3 +1,22 @@
2001-09-12 Paul Sokolovsky <Paul.Sokolovsky@technologist.com>
* emultempl/pe.em(make_import_fixup): change signature to
take asection as well as arelec; we need this for proper
error reporting. Only call pe_create_import_fixup() if
there is no attempt to add a constant addend to the reloc;
otherwise, report error condition.
* pe-dll.c(pe_walk_relocs_of_symbol): change signature,
since final argument is a pointer to make_import_fixup().
Change call to cb() to match make_import_fixup() signature.
(make_import_fixup_mark): make buffer_len unsigned.
* pe-dll.h: change signature of pe_walk_relocs_of_symbol.
2001-09-12 Charles Wilson <cwilson@ece.gatech.edu>
* ld.texinfo: add verbose documentation for auto-import
direct-addressing workaround, to compliment the terse
error message.
2001-09-12 Andrew MacLeod <amacleod@redhat.com>
* scripttempl/v850.sc: Add gcc_except_table sections.

View File

@ -127,7 +127,7 @@ static void set_pe_stack_heap PARAMS ((char *, char *));
static boolean pe_undef_cdecl_match
PARAMS ((struct bfd_link_hash_entry *, PTR));
static void pe_fixup_stdcalls PARAMS ((void));
static int make_import_fixup PARAMS ((arelent *));
static int make_import_fixup PARAMS ((arelent *, asection *));
static void pe_find_data_imports PARAMS ((void));
#endif
@ -845,20 +845,36 @@ pe_fixup_stdcalls ()
}
static int
make_import_fixup (rel)
make_import_fixup (rel, s)
arelent *rel;
asection *s;
{
struct symbol_cache_entry *sym = *rel->sym_ptr_ptr;
/*
bfd *b;
*/
if (pe_dll_extra_pe_debug)
{
printf ("arelent: %s@%#x: add=%li\n", sym->name,
(int) rel->address, rel->addend);
}
pe_create_import_fixup (rel);
{
int addend = 0;
if (!bfd_get_section_contents(s->owner, s, &addend, rel->address, sizeof(addend)))
{
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");
}
}
return 1;
}

View File

@ -1726,9 +1726,103 @@ uwin, pw, etc. For instance, cygwin DLLs typically use
@kindex --enable-auto-import
@item --enable-auto-import
Do sophisticalted linking of @code{_symbol} to @code{__imp__symbol} for
Do sophisticated linking of @code{_symbol} to @code{__imp__symbol} for
DATA imports from DLLs, and create the necessary thunking symbols when
building the DLLs with those DATA exports.
building the DLLs with those DATA exports. This generally will 'just
work' -- but sometimes you may see this message:
"variable '<var>' can't be auto-imported. Please read the
documentation for ld's @code{--enable-auto-import} for details."
This message occurs when some (sub)expression accesses an address
ultimately given by the sum of two constants (Win32 import tables only
allow one). Instances where this may occur include accesses to member
fields of struct variables imported from a DLL, as well as using a
constant index into an array variable imported from a DLL. There are
several ways to address this difficulty.
One 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:
@example
extern type extern_array[];
extern_array[1] -->
@{ volatile type *t=extern_array; t[1] @}
@end example
or
@example
extern type extern_array[];
extern_array[1] -->
@{ volatile int t=1; extern_array[t] @}
@end example
For structs, the only option is to make the struct itself variable:
@example
extern struct s extern_struct;
extern_struct.field -->
@{ volatile struct s *t=&extern_struct; t->field @}
@end example
A second 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
building a DLL, building client code that will link to the DLL, or
merely building/linking to a static library. In making the choice
between the various methods of resolving the 'direct address with
constant offset' problem, you should consider typical real-world usage:
Original:
@example
--foo.h
extern int arr[];
--foo.c
#include "foo.h"
void main(int argc, char **argv)@{
printf("%d\n",arr[1]);
@}
@end example
Solution 1:
@example
--foo.h
extern int arr[];
--foo.c
#include "foo.h"
void main(int argc, char **argv)@{
/* This workaround is for win32 and cygwin; do not "optimize" */
volatile int *parr = arr;
printf("%d\n",parr[1]);
@}
@end example
Solution 2:
@example
--foo.h
/* Note: auto-export is assumed (no __declspec(dllexport)) */
#if (defined(_WIN32) || defined(__CYGWIN__)) && \
!(defined(FOO_BUILD_DLL) || defined(FOO_STATIC))
#define FOO_IMPORT __declspec(dllimport)
#else
#define FOO_IMPORT
#endif
extern FOO_IMPORT int arr[];
--foo.c
#include "foo.h"
void main(int argc, char **argv)@{
printf("%d\n",arr[1]);
@}
@end example
A third 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).
@kindex --disable-auto-import
@item --disable-auto-import

View File

@ -982,10 +982,10 @@ void
pe_walk_relocs_of_symbol (info, name, cb)
struct bfd_link_info *info;
CONST char *name;
int (*cb) (arelent *);
int (*cb) (arelent *, asection *);
{
bfd *b;
struct sec *s;
asection *s;
for (b = info->input_bfds; b; b = b->link_next)
{
@ -1003,7 +1003,7 @@ pe_walk_relocs_of_symbol (info, name, cb)
&& s->output_section == bfd_abs_section_ptr)
continue;
current_sec=s;
current_sec = s;
symsize = bfd_get_symtab_upper_bound (b);
symbols = (asymbol **) xmalloc (symsize);
@ -1016,7 +1016,7 @@ pe_walk_relocs_of_symbol (info, name, cb)
for (i = 0; i < nrelocs; i++)
{
struct symbol_cache_entry *sym = *relocs[i]->sym_ptr_ptr;
if (!strcmp(name,sym->name)) cb(relocs[i]);
if (!strcmp(name,sym->name)) cb(relocs[i], s);
}
free (relocs);
/* Warning: the allocated symbols are remembered in BFD and reused
@ -1908,7 +1908,7 @@ make_import_fixup_mark (rel)
/* we convert reloc to symbol, for later reference */
static int counter;
static char *fixup_name = NULL;
static int buffer_len = 0;
static unsigned int buffer_len = 0;
struct symbol_cache_entry *sym = *rel->sym_ptr_ptr;

View File

@ -48,7 +48,7 @@ extern void pe_exe_fill_sections PARAMS ((bfd *, struct bfd_link_info *));
extern void pe_walk_relocs_of_symbol PARAMS ((struct bfd_link_info * info,
CONST char *name,
int (*cb) (arelent *)));
int (*cb) (arelent *, asection *)));
extern void pe_create_import_fixup PARAMS ((arelent * rel));
#endif /* PE_DLL_H */