From e2586bc8ded37d6f48a23c21e9e3833dc0f66ad6 Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Tue, 10 Nov 1998 22:57:13 +0000 Subject: [PATCH] * pe-dll.c (process_def_file): properly note undefined exported symbols, clean up old code. (pe_dll_generate_def_file): don't crash if pe_def_file is NULL * emultempl/pe.em (gld_i386_parse_args): add (en/dis)able-stdcall-fixups (pe_fixup_stdcalls): warn about stdcall fixups (gld_i386_unrecognized_file): make exported symbols undefs so that archive members get pulled in --- ld/ChangeLog | 11 +++ ld/emultempl/pe.em | 65 +++++++++++++- ld/pe-dll.c | 219 ++++++++++++++++++++++----------------------- 3 files changed, 184 insertions(+), 111 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index ca69682a58d..57c4cd1729c 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,14 @@ +Tue Nov 10 17:53:17 1998 DJ Delorie + + * pe-dll.c (process_def_file): properly note undefined exported + symbols, clean up old code. + (pe_dll_generate_def_file): don't crash if pe_def_file is NULL + * emultempl/pe.em (gld_i386_parse_args): add + (en/dis)able-stdcall-fixups + (pe_fixup_stdcalls): warn about stdcall fixups + (gld_i386_unrecognized_file): make exported symbols undefs so that + archive members get pulled in + Tue Nov 10 14:50:51 1998 Catherine Moore * scripttempl/elfd10v.sc: Add KEEP attribute to .init, diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index dafd7eeff8b..34f6f7ae1f1 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -69,6 +69,7 @@ int pe_dll_export_everything = 0; int pe_dll_do_default_excludes = 1; int pe_dll_kill_ats = 0; int pe_dll_stdcall_aliases = 0; +int pe_enable_stdcall_fixup = -1; /* 0=disable 1=enable */ extern const char *output_filename; @@ -105,6 +106,8 @@ gld_${EMULATION_NAME}_before_parse() #define OPTION_EXCLUDE_SYMBOLS (OPTION_EXPORT_ALL + 1) #define OPTION_KILL_ATS (OPTION_EXCLUDE_SYMBOLS + 1) #define OPTION_STDCALL_ALIASES (OPTION_KILL_ATS + 1) +#define OPTION_ENABLE_STDCALL_FIXUP (OPTION_STDCALL_ALIASES + 1) +#define OPTION_DISABLE_STDCALL_FIXUP (OPTION_ENABLE_STDCALL_FIXUP + 1) static struct option longopts[] = { @@ -132,6 +135,8 @@ static struct option longopts[] = {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMBOLS}, {"kill-at", no_argument, NULL, OPTION_KILL_ATS}, {"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES}, + {"enable-stdcall-fixup", no_argument, NULL, OPTION_ENABLE_STDCALL_FIXUP}, + {"disable-stdcall-fixup", no_argument, NULL, OPTION_DISABLE_STDCALL_FIXUP}, {NULL, no_argument, NULL, 0} }; @@ -198,6 +203,8 @@ gld_${EMULATION_NAME}_list_options (file) fprintf (file, _(" --exclude-symbols sym,sym,... Exclude symbols from automatic export\n")); fprintf (file, _(" --kill-at Remove @nn from exported symbols\n")); fprintf (file, _(" --add-stdcall-alias Export symbols with and without @nn\n")); + fprintf (file, _(" --enable-stdcall-fixup Link _sym to _sym@nn without warnings\n")); + fprintf (file, _(" --disable-stdcall-fixup Don't link _sym to _sym@nn\n")); } static void @@ -411,6 +418,12 @@ gld_${EMULATION_NAME}_parse_args(argc, argv) case OPTION_STDCALL_ALIASES: pe_dll_stdcall_aliases = 1; break; + case OPTION_ENABLE_STDCALL_FIXUP: + pe_enable_stdcall_fixup = 1; + break; + case OPTION_DISABLE_STDCALL_FIXUP: + pe_enable_stdcall_fixup = 0; + break; } return 1; } @@ -516,6 +529,7 @@ pe_undef_cdecl_match (h, string) static void pe_fixup_stdcalls () { + static int gave_warning_message = 0; struct bfd_link_hash_entry *undef, *sym; char *at; for (undef = link_info.hash->undefs; undef; undef=undef->next) @@ -535,6 +549,17 @@ pe_fixup_stdcalls () undef->type = bfd_link_hash_defined; undef->u.def.value = sym->u.def.value; undef->u.def.section = sym->u.def.section; + if (pe_enable_stdcall_fixup == -1) + { + einfo (_("Warning: resolving %s by linking to %s\n"), + undef->root.string, cname); + if (! gave_warning_message) + { + gave_warning_message = 1; + einfo(_("Use --enable-stdcall-fixup to disable these warnings\n")); + einfo(_("Use --disable-stdcall-fixup to disable these fixups\n")); + } + } } } else @@ -550,6 +575,17 @@ pe_fixup_stdcalls () undef->type = bfd_link_hash_defined; undef->u.def.value = sym->u.def.value; undef->u.def.section = sym->u.def.section; + if (pe_enable_stdcall_fixup == -1) + { + einfo (_("Warning: resolving %s by linking to %s\n"), + undef->root.string, sym->root.string); + if (! gave_warning_message) + { + gave_warning_message = 1; + einfo(_("Use --enable-stdcall-fixup to disable these warnings\n")); + einfo(_("Use --disable-stdcall-fixup to disable these fixups\n")); + } + } } } } @@ -568,7 +604,8 @@ gld_${EMULATION_NAME}_after_open () pe_data (output_bfd)->pe_opthdr = pe; pe_data (output_bfd)->dll = init[DLLOFF].value; - pe_fixup_stdcalls (); + if (pe_enable_stdcall_fixup) /* -1=warn or 1=disable */ + pe_fixup_stdcalls (); #ifdef TARGET_IS_i386pe if (link_info.shared) @@ -660,6 +697,32 @@ gld_${EMULATION_NAME}_unrecognized_file(entry) def_file_parse (entry->filename, pe_def_file); if (pe_def_file) { + int i, buflen=0, len; + char *buf; + for (i=0; inum_exports; i++) + { + len = strlen(pe_def_file->exports[i].internal_name); + if (buflen < len+2) + buflen = len+2; + } + buf = (char *) xmalloc (buflen); + for (i=0; inum_exports; i++) + { + struct bfd_link_hash_entry *h; + sprintf(buf, "_%s", pe_def_file->exports[i].internal_name); + + h = bfd_link_hash_lookup (link_info.hash, buf, true, true, true); + if (h == (struct bfd_link_hash_entry *) NULL) + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); + if (h->type == bfd_link_hash_new) + { + h->type = bfd_link_hash_undefined; + h->u.undef.abfd = NULL; + bfd_link_add_undef (link_info.hash, h); + } + } + free (buf); + /* def_file_print (stdout, pe_def_file); */ if (pe_def_file->is_dll == 1) link_info.shared = 1; diff --git a/ld/pe-dll.c b/ld/pe-dll.c index d2f77f33176..25ea4e3de66 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -342,12 +342,19 @@ process_def_file (abfd, info) count_with_ordinals++; } } - else if (blhe) + else if (blhe && blhe->type == bfd_link_hash_undefined) { /* xgettext:c-format */ - einfo (_("%XCannot export %s: symbol wrong type\n"), + einfo (_("%XCannot export %s: symbol not defined\n"), pe_def_file->exports[i].internal_name); } + else if (blhe) + { + /* xgettext:c-format */ + einfo (_("%XCannot export %s: symbol wrong type (%d vs %d)\n"), + pe_def_file->exports[i].internal_name, + blhe->type, bfd_link_hash_defined); + } else { /* xgettext:c-format */ @@ -356,19 +363,6 @@ process_def_file (abfd, info) } free(name); } - -#if 0 - /* For now, just export all global functions. Read DEF files later */ - for (i = 0; i < num_input_bfds; i++) - { - for (j = 0; j < symtab[i].nsyms; j++) - { - if ((symtab[i].symbols[j]->flags & (BSF_FUNCTION | BSF_GLOBAL)) - == (BSF_FUNCTION | BSF_GLOBAL)) - symtab[i].exported[j] = 1; - } - } -#endif } /************************************************************************ @@ -755,119 +749,124 @@ pe_dll_generate_def_file (pe_out_def_filename) program_name, pe_out_def_filename); } - if (pe_def_file->name) + if (pe_def_file) { - if (pe_def_file->is_dll) - fprintf (out, "LIBRARY "); - else - fprintf (out, "NAME "); - quoteput (pe_def_file->name, out, 1); - if (pe_def_file->base_address != (bfd_vma) (-1)) - fprintf (out, " BASE=0x%x", pe_def_file->base_address); - fprintf (out, "\n"); - } + if (pe_def_file->name) + { + if (pe_def_file->is_dll) + fprintf (out, "LIBRARY "); + else + fprintf (out, "NAME "); + quoteput (pe_def_file->name, out, 1); + if (pe_def_file->base_address != (bfd_vma) (-1)) + fprintf (out, " BASE=0x%x", pe_def_file->base_address); + fprintf (out, "\n"); + } - if (pe_def_file->description) - { - fprintf (out, "DESCRIPTION "); - quoteput (pe_def_file->description, out, 1); - fprintf (out, "\n"); - } + if (pe_def_file->description) + { + fprintf (out, "DESCRIPTION "); + quoteput (pe_def_file->description, out, 1); + fprintf (out, "\n"); + } - if (pe_def_file->version_minor) - fprintf (out, "VERSION %d.%d\n", pe_def_file->version_major, - pe_def_file->version_minor); - else - fprintf (out, "VERSION %d\n", pe_def_file->version_major); - - if (pe_def_file->stack_reserve != -1 || pe_def_file->heap_reserve != -1) - fprintf (out, "\n"); - - if (pe_def_file->stack_commit != -1) - fprintf (out, "STACKSIZE 0x%x,0x%x\n", - pe_def_file->stack_reserve, pe_def_file->stack_commit); - else if (pe_def_file->stack_reserve != -1) - fprintf (out, "STACKSIZE 0x%x\n", pe_def_file->stack_reserve); - if (pe_def_file->heap_commit != -1) - fprintf (out, "HEAPSIZE 0x%x,0x%x\n", - pe_def_file->heap_reserve, pe_def_file->heap_commit); - else if (pe_def_file->heap_reserve != -1) - fprintf (out, "HEAPSIZE 0x%x\n", pe_def_file->heap_reserve); - - if (pe_def_file->num_section_defs > 0) - { - fprintf (out, "\nSECTIONS\n\n"); - for (i = 0; i < pe_def_file->num_section_defs; i++) + if (pe_def_file->version_minor) + fprintf (out, "VERSION %d.%d\n", pe_def_file->version_major, + pe_def_file->version_minor); + else + fprintf (out, "VERSION %d\n", pe_def_file->version_major); + + if (pe_def_file->stack_reserve != -1 || pe_def_file->heap_reserve != -1) + fprintf (out, "\n"); + + if (pe_def_file->stack_commit != -1) + fprintf (out, "STACKSIZE 0x%x,0x%x\n", + pe_def_file->stack_reserve, pe_def_file->stack_commit); + else if (pe_def_file->stack_reserve != -1) + fprintf (out, "STACKSIZE 0x%x\n", pe_def_file->stack_reserve); + if (pe_def_file->heap_commit != -1) + fprintf (out, "HEAPSIZE 0x%x,0x%x\n", + pe_def_file->heap_reserve, pe_def_file->heap_commit); + else if (pe_def_file->heap_reserve != -1) + fprintf (out, "HEAPSIZE 0x%x\n", pe_def_file->heap_reserve); + + if (pe_def_file->num_section_defs > 0) { - fprintf (out, " "); - quoteput (pe_def_file->section_defs[i].name, out, 0); - if (pe_def_file->section_defs[i].class) + fprintf (out, "\nSECTIONS\n\n"); + for (i = 0; i < pe_def_file->num_section_defs; i++) { - fprintf (out, " CLASS "); - quoteput (pe_def_file->section_defs[i].class, out, 0); + fprintf (out, " "); + quoteput (pe_def_file->section_defs[i].name, out, 0); + if (pe_def_file->section_defs[i].class) + { + fprintf (out, " CLASS "); + quoteput (pe_def_file->section_defs[i].class, out, 0); + } + if (pe_def_file->section_defs[i].flag_read) + fprintf (out, " READ"); + if (pe_def_file->section_defs[i].flag_write) + fprintf (out, " WRITE"); + if (pe_def_file->section_defs[i].flag_execute) + fprintf (out, " EXECUTE"); + if (pe_def_file->section_defs[i].flag_shared) + fprintf (out, " SHARED"); + fprintf (out, "\n"); } - if (pe_def_file->section_defs[i].flag_read) - fprintf (out, " READ"); - if (pe_def_file->section_defs[i].flag_write) - fprintf (out, " WRITE"); - if (pe_def_file->section_defs[i].flag_execute) - fprintf (out, " EXECUTE"); - if (pe_def_file->section_defs[i].flag_shared) - fprintf (out, " SHARED"); - fprintf (out, "\n"); } - } - if (pe_def_file->num_exports > 0) - { - fprintf (out, "\nEXPORTS\n\n"); - for (i = 0; i < pe_def_file->num_exports; i++) + if (pe_def_file->num_exports > 0) { - def_file_export *e = pe_def_file->exports + i; - fprintf (out, " "); - quoteput (e->name, out, 0); - if (e->internal_name && strcmp (e->internal_name, e->name)) + fprintf (out, "\nEXPORTS\n\n"); + for (i = 0; i < pe_def_file->num_exports; i++) { - fprintf (out, " = "); - quoteput (e->internal_name, out, 0); + def_file_export *e = pe_def_file->exports + i; + fprintf (out, " "); + quoteput (e->name, out, 0); + if (e->internal_name && strcmp (e->internal_name, e->name)) + { + fprintf (out, " = "); + quoteput (e->internal_name, out, 0); + } + if (e->ordinal != -1) + fprintf (out, " @%d", e->ordinal); + if (e->flag_private) + fprintf (out, " PRIVATE"); + if (e->flag_constant) + fprintf (out, " CONSTANT"); + if (e->flag_noname) + fprintf (out, " NONAME"); + if (e->flag_data) + fprintf (out, " DATA"); + + fprintf (out, "\n"); } - if (e->ordinal != -1) - fprintf (out, " @%d", e->ordinal); - if (e->flag_private) - fprintf (out, " PRIVATE"); - if (e->flag_constant) - fprintf (out, " CONSTANT"); - if (e->flag_noname) - fprintf (out, " NONAME"); - if (e->flag_data) - fprintf (out, " DATA"); - - fprintf (out, "\n"); } - } - if (pe_def_file->num_imports > 0) - { - fprintf (out, "\nIMPORTS\n\n"); - for (i = 0; i < pe_def_file->num_imports; i++) + if (pe_def_file->num_imports > 0) { - def_file_import *im = pe_def_file->imports + i; - fprintf (out, " "); - if (im->internal_name - && (!im->name || strcmp (im->internal_name, im->name))) + fprintf (out, "\nIMPORTS\n\n"); + for (i = 0; i < pe_def_file->num_imports; i++) { - quoteput (im->internal_name, out, 0); - fprintf (out, " = "); + def_file_import *im = pe_def_file->imports + i; + fprintf (out, " "); + if (im->internal_name + && (!im->name || strcmp (im->internal_name, im->name))) + { + quoteput (im->internal_name, out, 0); + fprintf (out, " = "); + } + quoteput (im->module->name, out, 0); + fprintf (out, "."); + if (im->name) + quoteput (im->name, out, 0); + else + fprintf (out, "%d", im->ordinal); + fprintf (out, "\n"); } - quoteput (im->module->name, out, 0); - fprintf (out, "."); - if (im->name) - quoteput (im->name, out, 0); - else - fprintf (out, "%d", im->ordinal); - fprintf (out, "\n"); } } + else + fprintf (out, _("; no contents available\n")); if (fclose (out) == EOF) { -- 2.30.2