2001-08-02 Charles Wilson <cwilson@ece.gatech.edu>
* ldmain.c (main): initialize link_info.pei386_auto_import * pe-dll.c: new tables for auto-export filtering (auto_export): change API, pass abfd for contextual filtering. Loop thru tables of excluded symbols instead of comparing "by hand". 2001-08-02 Paul Sokolovsky <paul.sokolovsky@technologist.com> * pe-dll.c: new variable pe_dll_enable_extra_debug. New static variable current_sec (static struct sec *). Add forward declaration for add_bfd_to_link. (process_def_file): Don't export undefined symbols. Do not export symbols starting with "_imp__". Call auto_export() with new API. (pe_walk_relocs_of_symbol): New function. (generate_reloc): add optional extra debugging (pe_dll_generate_def_file): eliminate extraneous initial blank line in output (make_one): enlarge symtab to make room for __nm__ symbols (DATA auto-import support). (make_singleton_name_thunk): New function. (make_import_fixup_mark): New function. (make_import_fixup_entry): New function. (pe_create_import_fixup): New function. (add_bfd_to_link): Specify that 'name' argument is a CONST char *. * pe-dll.h: declare new variable pe_dll_extra_pe_debug; declare new functions pe_walk_relocs_of_symbol and pe_create_import_fixup. * emultempl/pe.em: add new options --enable-auto-import, --disable-auto-import, and --enable-extra-pe-debug. (make_import_fixup): New function. (pe_find_data_imports): New function. (pr_sym): New function. (gld_${EMULATION_NAME}_after_open): Add optional extra pe debugging. Call pe_find_data_imports. Mark .idata as DATA, not CODE. 2001-08-02 Charles Wilson <cwilson@ece.gatech.edu> * ld.texinfo: add additional documentation for --export-all-symbols. Document --out-implib, --enable-auto-image-base, --disable-auto-image-base, --dll-search-prefix, --enable-auto-import, and --disable-auto-import. * ldint.texinfo: Add detailed documentation on auto-import implementation.
This commit is contained in:
parent
a5cedf2f04
commit
decc363800
1 changed files with 156 additions and 5 deletions
|
@ -146,7 +146,9 @@ gld_${EMULATION_NAME}_before_parse()
|
|||
ldfile_output_architecture = bfd_arch_${ARCH};
|
||||
output_filename = "${EXECUTABLE_NAME:-a.exe}";
|
||||
#ifdef DLL_SUPPORT
|
||||
config.dynamic_link = true;
|
||||
config.has_shared = 1;
|
||||
/* link_info.pei386_auto_import = true; */
|
||||
|
||||
#if (PE_DEF_SUBSYSTEM == 9) || (PE_DEF_SUBSYSTEM == 2)
|
||||
#if defined TARGET_IS_mipspe || defined TARGET_IS_armpe
|
||||
|
@ -191,6 +193,9 @@ gld_${EMULATION_NAME}_before_parse()
|
|||
#define OPTION_DISABLE_AUTO_IMAGE_BASE (OPTION_ENABLE_AUTO_IMAGE_BASE + 1)
|
||||
#define OPTION_DLL_SEARCH_PREFIX (OPTION_DISABLE_AUTO_IMAGE_BASE + 1)
|
||||
#define OPTION_NO_DEFAULT_EXCLUDES (OPTION_DLL_SEARCH_PREFIX + 1)
|
||||
#define OPTION_DLL_ENABLE_AUTO_IMPORT (OPTION_NO_DEFAULT_EXCLUDES + 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)
|
||||
|
||||
static struct option longopts[] = {
|
||||
/* PE options */
|
||||
|
@ -228,6 +233,9 @@ static struct option longopts[] = {
|
|||
{"disable-auto-image-base", no_argument, NULL, OPTION_DISABLE_AUTO_IMAGE_BASE},
|
||||
{"dll-search-prefix", required_argument, NULL, OPTION_DLL_SEARCH_PREFIX},
|
||||
{"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
|
||||
{"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},
|
||||
#endif
|
||||
{NULL, no_argument, NULL, 0}
|
||||
};
|
||||
|
@ -313,6 +321,11 @@ gld_${EMULATION_NAME}_list_options (file)
|
|||
fprintf (file, _(" --dll-search-prefix=<string> When linking dynamically to a dll witout an\n"));
|
||||
fprintf (file, _(" importlib, use <string><basename>.dll \n"));
|
||||
fprintf (file, _(" in preference to lib<basename>.dll \n"));
|
||||
fprintf (file, _(" --enable-auto-import Do sophistcated linking of _sym to \n"));
|
||||
fprintf (file, _(" __imp_sym for DATA references\n"));
|
||||
fprintf (file, _(" --disable-auto-import Do not auto-import DATA items from DLLs\n"));
|
||||
fprintf (file, _(" --enable-extra-pe-debug Enable verbose debug output when building\n"));
|
||||
fprintf (file, _(" or linking to DLLs (esp. auto-import)\n"));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -583,6 +596,15 @@ gld_${EMULATION_NAME}_parse_args(argc, argv)
|
|||
case OPTION_NO_DEFAULT_EXCLUDES:
|
||||
pe_dll_do_default_excludes = 0;
|
||||
break;
|
||||
case OPTION_DLL_ENABLE_AUTO_IMPORT:
|
||||
link_info.pei386_auto_import = true;
|
||||
break;
|
||||
case OPTION_DLL_DISABLE_AUTO_IMPORT:
|
||||
link_info.pei386_auto_import = false;
|
||||
break;
|
||||
case OPTION_ENABLE_EXTRA_PE_DEBUG:
|
||||
pe_dll_extra_pe_debug = 1;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
|
@ -716,7 +738,8 @@ pe_undef_cdecl_match (h, string)
|
|||
struct bfd_link_hash_entry *h;
|
||||
PTR string;
|
||||
{
|
||||
int sl = strlen (string);
|
||||
int sl;
|
||||
sl = strlen (string); /* silence compiler warning */
|
||||
if (h->type == bfd_link_hash_defined
|
||||
&& strncmp (h->root.string, string, sl) == 0
|
||||
&& h->root.string[sl] == '@')
|
||||
|
@ -733,6 +756,11 @@ pe_fixup_stdcalls ()
|
|||
static int gave_warning_message = 0;
|
||||
struct bfd_link_hash_entry *undef, *sym;
|
||||
char *at;
|
||||
if (pe_dll_extra_pe_debug)
|
||||
{
|
||||
printf ("%s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
for (undef = link_info.hash->undefs; undef; undef=undef->next)
|
||||
if (undef->type == bfd_link_hash_undefined)
|
||||
{
|
||||
|
@ -791,11 +819,122 @@ pe_fixup_stdcalls ()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
make_import_fixup (rel)
|
||||
arelent *rel;
|
||||
{
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *pe_data_import_dll;
|
||||
|
||||
static void
|
||||
pe_find_data_imports ()
|
||||
{
|
||||
struct bfd_link_hash_entry *undef, *sym;
|
||||
for (undef = link_info.hash->undefs; undef; undef=undef->next)
|
||||
{
|
||||
if (undef->type == bfd_link_hash_undefined)
|
||||
{
|
||||
/* C++ symbols are *long* */
|
||||
char buf[4096];
|
||||
if (pe_dll_extra_pe_debug)
|
||||
{
|
||||
printf ("%s:%s\n", __FUNCTION__, undef->root.string);
|
||||
}
|
||||
sprintf (buf, "__imp_%s", undef->root.string);
|
||||
|
||||
sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);
|
||||
if (sym && sym->type == bfd_link_hash_defined)
|
||||
{
|
||||
einfo (_("Warning: resolving %s by linking to %s (auto-import)\n"),
|
||||
undef->root.string, buf);
|
||||
{
|
||||
bfd *b = sym->u.def.section->owner;
|
||||
asymbol **symbols;
|
||||
int nsyms, symsize, i;
|
||||
|
||||
symsize = bfd_get_symtab_upper_bound (b);
|
||||
symbols = (asymbol **) xmalloc (symsize);
|
||||
nsyms = bfd_canonicalize_symtab (b, symbols);
|
||||
|
||||
for (i = 0; i < nsyms; i++)
|
||||
{
|
||||
if (memcmp(symbols[i]->name, "__head_",
|
||||
sizeof ("__head_") - 1))
|
||||
continue;
|
||||
if (pe_dll_extra_pe_debug)
|
||||
{
|
||||
printf ("->%s\n", symbols[i]->name);
|
||||
}
|
||||
pe_data_import_dll = (char*) (symbols[i]->name +
|
||||
sizeof ("__head_") - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pe_walk_relocs_of_symbol (&link_info, undef->root.string,
|
||||
make_import_fixup);
|
||||
|
||||
/* let's differentiate it somehow from defined */
|
||||
undef->type = bfd_link_hash_defweak;
|
||||
/* we replace original name with __imp_ prefixed, this
|
||||
1) may trash memory 2) leads to duplicate symbol generation.
|
||||
Still, IMHO it's better than having name poluted. */
|
||||
undef->root.string = sym->root.string;
|
||||
undef->u.def.value = sym->u.def.value;
|
||||
undef->u.def.section = sym->u.def.section;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* DLL_SUPPORT */
|
||||
|
||||
static boolean
|
||||
pr_sym (h, string)
|
||||
struct bfd_hash_entry *h;
|
||||
PTR string;
|
||||
{
|
||||
if (pe_dll_extra_pe_debug)
|
||||
{
|
||||
printf("+%s\n",h->string);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gld_${EMULATION_NAME}_after_open ()
|
||||
{
|
||||
|
||||
if (pe_dll_extra_pe_debug)
|
||||
{
|
||||
bfd *a;
|
||||
struct bfd_link_hash_entry *sym;
|
||||
printf ("%s()\n", __FUNCTION__);
|
||||
|
||||
for (sym = link_info.hash->undefs; sym; sym=sym->next)
|
||||
printf ("-%s\n", sym->root.string);
|
||||
bfd_hash_traverse (&link_info.hash->table, pr_sym,NULL);
|
||||
|
||||
for (a = link_info.input_bfds; a; a = a->link_next)
|
||||
{
|
||||
printf("*%s\n",a->filename);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass the wacky PE command line options into the output bfd.
|
||||
FIXME: This should be done via a function, rather than by
|
||||
including an internal BFD header. */
|
||||
|
@ -810,6 +949,8 @@ gld_${EMULATION_NAME}_after_open ()
|
|||
if (pe_enable_stdcall_fixup) /* -1=warn or 1=disable */
|
||||
pe_fixup_stdcalls ();
|
||||
|
||||
pe_find_data_imports (output_bfd, &link_info);
|
||||
|
||||
pe_process_import_defs(output_bfd, &link_info);
|
||||
if (link_info.shared)
|
||||
pe_dll_build_sections (output_bfd, &link_info);
|
||||
|
@ -1251,6 +1392,16 @@ gld_${EMULATION_NAME}_finish ()
|
|||
if (pe_out_def_filename)
|
||||
pe_dll_generate_def_file (pe_out_def_filename);
|
||||
#endif /* DLL_SUPPORT */
|
||||
|
||||
/* I don't know where .idata gets set as code, but it shouldn't be */
|
||||
{
|
||||
asection *asec = bfd_get_section_by_name (output_bfd, ".idata");
|
||||
if (asec)
|
||||
{
|
||||
asec->flags &= ~SEC_CODE;
|
||||
asec->flags |= SEC_DATA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue