mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 02:24:46 +08:00
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:
parent
cedacdc05a
commit
0d888aac30
19
ld/ChangeLog
19
ld/ChangeLog
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
10
ld/pe-dll.c
10
ld/pe-dll.c
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user