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;
#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[] =
{
{"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}
};
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
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;
}
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)
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
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"));
+ }
+ }
}
}
}
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)
def_file_parse (entry->filename, pe_def_file);
if (pe_def_file)
{
+ int i, buflen=0, len;
+ char *buf;
+ for (i=0; i<pe_def_file->num_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; i<pe_def_file->num_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;
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 */
}
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
}
/************************************************************************
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)
{