Index: ld.texinfo =================================================================== RCS file: /cvs/uberbaum/ld/ld.texinfo,v retrieving revision 1.70 diff -u -p -2 -r1.70 ld.texinfo --- ld.texinfo 20 Jun 2002 14:44:10 -0000 1.70 +++ ld.texinfo 2 Jul 2002 11:37:31 -0000 @@ -1794,5 +1794,9 @@ There are several ways to address this d 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. + +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) @@ -1830,5 +1834,5 @@ extern_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 @@ -1881,5 +1885,5 @@ void main(int argc, char **argv)@{ @end example -A third way to avoid this problem is to re-code your +A fouth 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 @@ -1890,4 +1894,15 @@ 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. @kindex --enable-extra-pe-debug Index: ldmain.c =================================================================== RCS file: /cvs/uberbaum/ld/ldmain.c,v retrieving revision 1.49 diff -u -p -2 -r1.49 ldmain.c --- ldmain.c 1 Jul 2002 08:07:29 -0000 1.49 +++ ldmain.c 2 Jul 2002 11:37:32 -0000 @@ -261,6 +261,6 @@ main (argc, argv) 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; Index: pe-dll.c =================================================================== RCS file: /cvs/uberbaum/ld/pe-dll.c,v retrieving revision 1.41 diff -u -p -2 -r1.41 pe-dll.c --- pe-dll.c 25 May 2002 20:39:25 -0000 1.41 +++ pe-dll.c 2 Jul 2002 11:37:32 -0000 @@ -142,4 +142,5 @@ 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 @@ -302,4 +303,8 @@ static char *make_import_fixup_mark PARA 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 *parent)); static unsigned int pe_get16 PARAMS ((bfd *, int)); static unsigned int pe_get32 PARAMS ((bfd *, int)); @@ -2068,7 +2073,103 @@ make_import_fixup_entry (name, fixup_nam } +/* .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]; @@ -2077,4 +2178,5 @@ pe_create_import_fixup (rel) const char *name = sym->name; char *fixup_name = make_import_fixup_mark (rel); + bfd *b; sprintf (buf, U ("_nm_thnk_%s"), name); @@ -2091,12 +2193,36 @@ pe_create_import_fixup (rel) } - { - 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"); + } + } } Index: pe-dll.h =================================================================== RCS file: /cvs/uberbaum/ld/pe-dll.h,v retrieving revision 1.8 diff -u -p -2 -r1.8 pe-dll.h --- pe-dll.h 8 Jun 2002 07:39:45 -0000 1.8 +++ pe-dll.h 2 Jul 2002 11:37:32 -0000 @@ -51,4 +51,4 @@ extern void pe_walk_relocs_of_symbol PAR int (*cb) (arelent *, asection *))); -extern void pe_create_import_fixup PARAMS ((arelent * rel)); +extern void pe_create_import_fixup PARAMS ((arelent * rel, asection * s, int addend)); #endif /* PE_DLL_H */ Index: emultempl/pe.em =================================================================== RCS file: /cvs/uberbaum/ld/emultempl/pe.em,v retrieving revision 1.65 diff -u -p -2 -r1.65 pe.em --- emultempl/pe.em 1 Jul 2002 08:07:31 -0000 1.65 +++ emultempl/pe.em 2 Jul 2002 11:37:37 -0000 @@ -175,4 +175,5 @@ gld_${EMULATION_NAME}_before_parse() 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) @@ -223,4 +224,8 @@ gld_${EMULATION_NAME}_before_parse() #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[] = { @@ -264,4 +269,6 @@ static struct option longopts[] = { {"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} @@ -353,4 +360,8 @@ gld_${EMULATION_NAME}_list_options (file __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")); @@ -634,4 +645,10 @@ gld_${EMULATION_NAME}_parse_args(argc, a 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; @@ -881,12 +898,5 @@ make_import_fixup (rel, s) } - 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); } Index: scripttempl/pe.sc =================================================================== RCS file: /cvs/uberbaum/ld/scripttempl/pe.sc,v retrieving revision 1.5 diff -u -p -2 -r1.5 pe.sc --- scripttempl/pe.sc 16 Jan 2002 01:48:43 -0000 1.5 +++ scripttempl/pe.sc 2 Jul 2002 11:37:37 -0000 @@ -86,4 +86,7 @@ SECTIONS ${R_RDATA} *(.eh_frame) + ___RUNTIME_PSEUDO_RELOC_LIST__ = .; __RUNTIME_PSEUDO_RELOC_LIST__ = . ; + *(.rdata_runtime_pseudo_reloc) + ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; __RUNTIME_PSEUDO_RELOC_LIST_END__ = . ; }