X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fdlltool.c;h=d22ff54e098a19551ebab7ba8e2a02cf18002c00;hb=0ac553107c601cc9c4c340338e0fc7e0ce8375cc;hp=759961e3d9cad3fe37ece539edaba6d99702a34d;hpb=dec872897c87f1a508b9ccb18d2f2c924a392f6e;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/dlltool.c b/binutils/dlltool.c index 759961e3d9..d22ff54e09 100644 --- a/binutils/dlltool.c +++ b/binutils/dlltool.c @@ -1,6 +1,5 @@ /* dlltool.c -- tool to generate stuff for PE style DLLs - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 1995-2020 Free Software Foundation, Inc. This file is part of GNU Binutils. @@ -232,18 +231,6 @@ .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc). */ -/* AIX requires this to be the first thing in the file. */ -#ifndef __GNUC__ -# ifdef _AIX - #pragma alloca -#endif -#endif - -#define show_allnames 0 - -#define PAGE_SIZE ((bfd_vma) 4096) -#define PAGE_MASK ((bfd_vma) (-4096)) - #include "sysdep.h" #include "bfd.h" #include "libiberty.h" @@ -253,21 +240,31 @@ #include "bucomm.h" #include "dlltool.h" #include "safe-ctype.h" +#include "coff-bfd.h" #include -#include -#include #include #ifdef DLLTOOL_ARM #include "coff/arm.h" #include "coff/internal.h" #endif -#ifdef DLLTOOL_MX86_64 +#ifdef DLLTOOL_DEFAULT_MX86_64 #include "coff/x86_64.h" #endif +#ifdef DLLTOOL_DEFAULT_I386 +#include "coff/i386.h" +#endif + +#ifndef COFF_PAGE_SIZE +#define COFF_PAGE_SIZE ((bfd_vma) 4096) +#endif + +#ifndef PAGE_MASK +#define PAGE_MASK ((bfd_vma) (- COFF_PAGE_SIZE)) +#endif -/* get current BFD error message */ +/* Get current BFD error message. */ #define bfd_get_errmsg() (bfd_errmsg (bfd_get_error ())) /* Forward references. */ @@ -311,6 +308,8 @@ static void mcore_elf_gen_out_file (void); #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */ #endif /* ! HAVE_SYS_WAIT_H */ +#define show_allnames 0 + /* ifunc and ihead data structures: ttk@cygnus.com 1997 When IMPORT declarations are encountered in a .def file the @@ -329,6 +328,7 @@ static void mcore_elf_gen_out_file (void); typedef struct ifunct { char * name; /* Name of function being imported. */ + char * its_name; /* Optional import table symbol name. */ int ord; /* Two-byte ordinal value associated with function. */ struct ifunct *next; } ifunctype; @@ -371,7 +371,7 @@ typedef struct dll_name_list_t { dll_name_list_node_type * head; dll_name_list_node_type * tail; -} dll_name_list_type; +} dll_name_list_type; /* Types used to pass data to iterator functions. */ typedef struct symname_search_data_t @@ -384,15 +384,21 @@ typedef struct identify_data_t { dll_name_list_type * list; bfd_boolean ms_style_implib; -} identify_data_type; +} identify_data_type; static char *head_label; static char *imp_name_lab; static char *dll_name; +static int dll_name_set_by_exp_name; static int add_indirect = 0; static int add_underscore = 0; static int add_stdcall_underscore = 0; +/* This variable can hold three different values. The value + -1 (default) means that default underscoring should be used, + zero means that no underscoring should be done, and one + indicates that underscoring should be done. */ +static int leading_underscore = -1; static int dontdeltemps = 0; /* TRUE if we should export all symbols. Otherwise, we only export @@ -431,10 +437,6 @@ static FILE *base_file; static const char *mname = "arm"; #endif -#ifdef DLLTOOL_DEFAULT_ARM_EPOC -static const char *mname = "arm-epoc"; -#endif - #ifdef DLLTOOL_DEFAULT_ARM_WINCE static const char *mname = "arm-wince"; #endif @@ -477,7 +479,7 @@ static char * mcore_elf_linker_flags = NULL; #endif /* What's the right name for this ? */ -#define PATHMAX 250 +#define PATHMAX 250 /* External name alias numbering starts here. */ #define PREFIX_ALIAS_BASE 20000 @@ -509,6 +511,14 @@ static const unsigned char i386_dljtab[] = 0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */ }; +static const unsigned char i386_x64_dljtab[] = +{ + 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */ + 0x48, 0x8d, 0x05, /* leaq rax, (__imp__function) */ + 0x00, 0x00, 0x00, 0x00, + 0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */ +}; + static const unsigned char arm_jtab[] = { 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */ @@ -575,7 +585,7 @@ static const unsigned char ppc_jtab[] = static bfd_vma ppc_glue_insn = 0x80410004; #endif -static const char i386_trampoline[] = +static const char i386_trampoline[] = "\tpushl %%ecx\n" "\tpushl %%edx\n" "\tpushl %%eax\n" @@ -585,6 +595,22 @@ static const char i386_trampoline[] = "\tpopl %%ecx\n" "\tjmp *%%eax\n"; +static const char i386_x64_trampoline[] = + "\tpushq %%rcx\n" + "\tpushq %%rdx\n" + "\tpushq %%r8\n" + "\tpushq %%r9\n" + "\tsubq $40, %%rsp\n" + "\tmovq %%rax, %%rdx\n" + "\tleaq __DELAY_IMPORT_DESCRIPTOR_%s(%%rip), %%rcx\n" + "\tcall __delayLoadHelper2\n" + "\taddq $40, %%rsp\n" + "\tpopq %%r9\n" + "\tpopq %%r8\n" + "\tpopq %%rdx\n" + "\tpopq %%rcx\n" + "\tjmp *%%rax\n"; + struct mac { const char *type; @@ -704,17 +730,7 @@ mtable[] = } , { -#define MARM_EPOC 9 - "arm-epoc", ".byte", ".short", ".long", ".asciz", "@", - "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long", - ".global", ".space", ".align\t2",".align\t4", "", - "epoc-pe-arm-little", bfd_arch_arm, - arm_jtab, sizeof (arm_jtab), 8, - 0, 0, 0, 0, 0, 0 - } - , - { -#define MARM_WINCE 10 +#define MARM_WINCE 9 "arm-wince", ".byte", ".short", ".long", ".asciz", "@", "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long", ".global", ".space", ".align\t2",".align\t4", "-mapcs-32", @@ -724,12 +740,12 @@ mtable[] = } , { -#define MX86 11 +#define MX86 10 "i386:x86-64", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4", "", "pe-x86-64",bfd_arch_i386, i386_jtab, sizeof (i386_jtab), 2, - i386_dljtab, sizeof (i386_dljtab), 2, 7, 12, i386_trampoline + i386_x64_dljtab, sizeof (i386_x64_dljtab), 2, 9, 14, i386_x64_trampoline } , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } @@ -747,13 +763,13 @@ typedef struct export const char *name; const char *internal_name; const char *import_name; + const char *its_name; int ordinal; int constant; int noname; /* Don't put name in image file. */ - int private; /* Don't put reference in import lib. */ + int private; /* Don't put reference in import lib. */ int data; - int hint; - int forward; /* Number of forward label, 0 means no forward. */ + int forward; /* Number of forward label, 0 means no forward. */ struct export *next; } export_type; @@ -773,7 +789,7 @@ static const char *rvabefore (int); static const char *asm_prefix (int, const char *); static void process_def_file (const char *); static void new_directive (char *); -static void append_import (const char *, const char *, int); +static void append_import (const char *, const char *, int, const char *); static void run (const char *, char *); static void scan_drectve_symbols (bfd *); static void scan_filtered_symbols (bfd *, void *, long, unsigned int); @@ -850,23 +866,24 @@ dlltmp (char **buf, const char *fmt) } static void -inform VPARAMS ((const char * message, ...)) +inform (const char * message, ...) { - VA_OPEN (args, message); - VA_FIXEDARG (args, const char *, message); + va_list args; + + va_start (args, message); if (!verbose) return; report (message, args); - VA_CLOSE (args); + va_end (args); } static const char * -rvaafter (int machine) +rvaafter (int mach) { - switch (machine) + switch (mach) { case MARM: case M386: @@ -878,21 +895,20 @@ rvaafter (int machine) case MMCORE_LE: case MMCORE_ELF: case MMCORE_ELF_LE: - case MARM_EPOC: case MARM_WINCE: break; default: /* xgettext:c-format */ - fatal (_("Internal error: Unknown machine type: %d"), machine); + fatal (_("Internal error: Unknown machine type: %d"), mach); break; } return ""; } static const char * -rvabefore (int machine) +rvabefore (int mach) { - switch (machine) + switch (mach) { case MARM: case M386: @@ -904,21 +920,20 @@ rvabefore (int machine) case MMCORE_LE: case MMCORE_ELF: case MMCORE_ELF_LE: - case MARM_EPOC: case MARM_WINCE: return ".rva\t"; default: /* xgettext:c-format */ - fatal (_("Internal error: Unknown machine type: %d"), machine); + fatal (_("Internal error: Unknown machine type: %d"), mach); break; } return ""; } static const char * -asm_prefix (int machine, const char *name) +asm_prefix (int mach, const char *name) { - switch (machine) + switch (mach) { case MARM: case MPPC: @@ -928,19 +943,18 @@ asm_prefix (int machine, const char *name) case MMCORE_LE: case MMCORE_ELF: case MMCORE_ELF_LE: - case MARM_EPOC: case MARM_WINCE: break; case M386: case MX86: /* Symbol names starting with ? do not have a leading underscore. */ - if (name && *name == '?') + if ((name && *name == '?') || leading_underscore == 0) break; else return "_"; default: /* xgettext:c-format */ - fatal (_("Internal error: Unknown machine type: %d"), machine); + fatal (_("Internal error: Unknown machine type: %d"), mach); break; } return ""; @@ -1021,12 +1035,14 @@ yyerror (const char * err ATTRIBUTE_UNUSED) void def_exports (const char *name, const char *internal_name, int ordinal, - int noname, int constant, int data, int private) + int noname, int constant, int data, int private, + const char *its_name) { struct export *p = (struct export *) xmalloc (sizeof (*p)); p->name = name; p->internal_name = internal_name ? internal_name : name; + p->its_name = its_name; p->import_name = name; p->ordinal = ordinal; p->constant = constant; @@ -1051,7 +1067,7 @@ set_dll_name_from_def (const char *name, char is_dll) if (image_basename != name) non_fatal (_("%s: Path components stripped from image name, '%s'."), def_file, name); - /* Append the default suffix, if none specified. */ + /* Append the default suffix, if none specified. */ if (strchr (image_basename, '.') == 0) { const char * suffix = is_dll ? ".dll" : ".exe"; @@ -1072,6 +1088,11 @@ def_name (const char *name, int base) if (d_is_dll) non_fatal (_("Can't have LIBRARY and NAME")); + if (dll_name_set_by_exp_name && name && *name != 0) + { + dll_name = NULL; + dll_name_set_by_exp_name = 0; + } /* If --dllname not provided, use the one in the DEF file. FIXME: Is this appropriate for executables? */ if (!dll_name) @@ -1088,6 +1109,12 @@ def_library (const char *name, int base) if (d_is_exe) non_fatal (_("Can't have LIBRARY and NAME")); + if (dll_name_set_by_exp_name && name && *name != 0) + { + dll_name = NULL; + dll_name_set_by_exp_name = 0; + } + /* If --dllname not provided, use the one in the DEF file. */ if (!dll_name) set_dll_name_from_def (name, 1); @@ -1138,20 +1165,22 @@ def_stacksize (int reserve, int commit) import_list. It is used by def_import. */ static void -append_import (const char *symbol_name, const char *dll_name, int func_ordinal) +append_import (const char *symbol_name, const char *dllname, int func_ordinal, + const char *its_name) { iheadtype **pq; iheadtype *q; for (pq = &import_list; *pq != NULL; pq = &(*pq)->next) { - if (strcmp ((*pq)->dllname, dll_name) == 0) + if (strcmp ((*pq)->dllname, dllname) == 0) { q = *pq; q->functail->next = xmalloc (sizeof (ifunctype)); q->functail = q->functail->next; q->functail->ord = func_ordinal; q->functail->name = xstrdup (symbol_name); + q->functail->its_name = (its_name ? xstrdup (its_name) : NULL); q->functail->next = NULL; q->nfuncs++; return; @@ -1159,12 +1188,13 @@ append_import (const char *symbol_name, const char *dll_name, int func_ordinal) } q = xmalloc (sizeof (iheadtype)); - q->dllname = xstrdup (dll_name); + q->dllname = xstrdup (dllname); q->nfuncs = 1; q->funchead = xmalloc (sizeof (ifunctype)); q->functail = q->funchead; q->next = NULL; q->functail->name = xstrdup (symbol_name); + q->functail->its_name = (its_name ? xstrdup (its_name) : NULL); q->functail->ord = func_ordinal; q->functail->next = NULL; @@ -1203,10 +1233,10 @@ append_import (const char *symbol_name, const char *dll_name, int func_ordinal) void def_import (const char *app_name, const char *module, const char *dllext, - const char *entry, int ord_val) + const char *entry, int ord_val, const char *its_name) { const char *application_name; - char *buf; + char *buf = NULL; if (entry != NULL) application_name = entry; @@ -1219,19 +1249,17 @@ def_import (const char *app_name, const char *module, const char *dllext, } if (dllext != NULL) - { - buf = (char *) alloca (strlen (module) + strlen (dllext) + 2); - sprintf (buf, "%s.%s", module, dllext); - module = buf; - } + module = buf = concat (module, ".", dllext, NULL); + + append_import (application_name, module, ord_val, its_name); - append_import (application_name, module, ord_val); + free (buf); } void def_version (int major, int minor) { - printf ("VERSION %d.%d\n", major, minor); + printf (_("VERSION %d.%d\n"), major, minor); } void @@ -1279,7 +1307,7 @@ run (const char *what, char *args) char *errmsg_fmt, *errmsg_arg; char *temp_base = choose_temp_base (); - inform ("run: %s %s", what, args); + inform (_("run: %s %s"), what, args); /* Count the args */ i = 0; @@ -1287,7 +1315,7 @@ run (const char *what, char *args) if (*s == ' ') i++; i++; - argv = alloca (sizeof (char *) * (i + 3)); + argv = xmalloc (sizeof (char *) * (i + 3)); i = 0; argv[i++] = what; s = args; @@ -1306,6 +1334,7 @@ run (const char *what, char *args) pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base, &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH); + free (argv); if (pid == -1) { @@ -1355,7 +1384,7 @@ scan_drectve_symbols (bfd *abfd) if (s == NULL) return; - size = bfd_get_section_size (s); + size = bfd_section_size (s); buf = xmalloc (size); bfd_get_section_contents (abfd, s, buf, 0, size); @@ -1379,12 +1408,26 @@ scan_drectve_symbols (bfd *abfd) flagword flags = BSF_FUNCTION; p += 8; - name = p; - while (p < e && *p != ',' && *p != ' ' && *p != '-') - p++; + /* Do we have a quoted export? */ + if (*p == '"') + { + p++; + name = p; + while (p < e && *p != '"') + ++p; + } + else + { + name = p; + while (p < e && *p != ',' && *p != ' ' && *p != '-') + p++; + } c = xmalloc (p - name + 1); memcpy (c, name, p - name); c[p - name] = 0; + /* Advance over trailing quote. */ + if (p < e && *p == '"') + ++p; if (p < e && *p == ',') /* found type tag. */ { char *tag_start = ++p; @@ -1397,7 +1440,7 @@ scan_drectve_symbols (bfd *abfd) /* FIXME: The 5th arg is for the `constant' field. What should it be? Not that it matters since it's not currently useful. */ - def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION), 0); + def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION), 0, NULL); if (add_stdcall_alias && strchr (c, '@')) { @@ -1406,7 +1449,7 @@ scan_drectve_symbols (bfd *abfd) char *atsym = strchr (exported_name, '@'); *atsym = '\0'; /* Note: stdcall alias symbols can never be data. */ - def_exports (exported_name, xstrdup (c), -1, 0, 0, 0, 0); + def_exports (exported_name, xstrdup (c), -1, 0, 0, 0, 0, NULL); } } else @@ -1445,7 +1488,7 @@ scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount, ++symbol_name; def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, - ! (sym->flags & BSF_FUNCTION), 0); + ! (sym->flags & BSF_FUNCTION), 0, NULL); if (add_stdcall_alias && strchr (symbol_name, '@')) { @@ -1454,7 +1497,7 @@ scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount, char *atsym = strchr (exported_name, '@'); *atsym = '\0'; /* Note: stdcall alias symbols can never be data. */ - def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0, 0); + def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0, 0, NULL); } } } @@ -1481,7 +1524,8 @@ add_excludes (const char *new_excludes) if (*exclude_string == '@') sprintf (new_exclude->string, "%s", exclude_string); else - sprintf (new_exclude->string, "_%s", exclude_string); + sprintf (new_exclude->string, "%s%s", (!leading_underscore ? "" : "_"), + exclude_string); new_exclude->next = excludes; excludes = new_exclude; @@ -1632,10 +1676,15 @@ scan_obj_file (const char *filename) bfd *arfile = bfd_openr_next_archived_file (f, 0); while (arfile) { + bfd *next; if (bfd_check_format (arfile, bfd_object)) scan_open_obj_file (arfile); + next = bfd_openr_next_archived_file (f, arfile); bfd_close (arfile); - arfile = bfd_openr_next_archived_file (f, arfile); + /* PR 17512: file: 58715298. */ + if (next == arfile) + break; + arfile = next; } #ifdef DLLTOOL_MCORE_ELF @@ -1669,7 +1718,7 @@ dump_def_info (FILE *f) fprintf (f, "\n"); for (i = 0, exp = d_exports; exp; i++, exp = exp->next) { - fprintf (f, "%s %d = %s %s @ %d %s%s%s%s\n", + fprintf (f, "%s %d = %s %s @ %d %s%s%s%s%s%s\n", ASM_C, i, exp->name, @@ -1678,7 +1727,9 @@ dump_def_info (FILE *f) exp->noname ? "NONAME " : "", exp->private ? "PRIVATE " : "", exp->constant ? "CONSTANT" : "", - exp->data ? "DATA" : ""); + exp->data ? "DATA" : "", + exp->its_name ? " ==" : "", + exp->its_name ? exp->its_name : ""); } } @@ -1761,20 +1812,22 @@ gen_def_file (void) if (strcmp (exp->name, exp->internal_name) == 0) { - fprintf (output_def, "\t%s%s%s @ %d%s%s%s\n", + fprintf (output_def, "\t%s%s%s @ %d%s%s%s%s%s\n", quote, exp->name, quote, exp->ordinal, exp->noname ? " NONAME" : "", exp->private ? "PRIVATE " : "", - exp->data ? " DATA" : ""); + exp->data ? " DATA" : "", + exp->its_name ? " ==" : "", + exp->its_name ? exp->its_name : ""); } else { char * quote1 = strchr (exp->internal_name, '.') ? "\"" : ""; /* char *alias = */ - fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s\n", + fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s%s%s\n", quote, exp->name, quote, @@ -1784,7 +1837,9 @@ gen_def_file (void) exp->ordinal, exp->noname ? " NONAME" : "", exp->private ? "PRIVATE " : "", - exp->data ? " DATA" : ""); + exp->data ? " DATA" : "", + exp->its_name ? " ==" : "", + exp->its_name ? exp->its_name : ""); } } @@ -1888,7 +1943,8 @@ generate_idata_ofile (FILE *filvar) fprintf (filvar,"funcptr%d_%d:\n", headindex, funcindex); fprintf (filvar,"\t%s\t%d\n", ASM_SHORT, ((funcptr->ord) & 0xFFFF)); - fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, funcptr->name); + fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, + (funcptr->its_name ? funcptr->its_name : funcptr->name)); fprintf (filvar,"\t%s\t0\n", ASM_BYTE); funcindex++; } @@ -1912,12 +1968,38 @@ assemble_file (const char * source, const char * dest) { char * cmd; - cmd = (char *) alloca (strlen (ASM_SWITCHES) + strlen (as_flags) - + strlen (source) + strlen (dest) + 50); + cmd = xmalloc (strlen (ASM_SWITCHES) + strlen (as_flags) + + strlen (source) + strlen (dest) + 50); sprintf (cmd, "%s %s -o %s %s", ASM_SWITCHES, as_flags, dest, source); run (as_name, cmd); + free (cmd); +} + +static const char * temp_file_to_remove[5]; +#define TEMP_EXPORT_FILE 0 +#define TEMP_HEAD_FILE 1 +#define TEMP_TAIL_FILE 2 +#define TEMP_HEAD_O_FILE 3 +#define TEMP_TAIL_O_FILE 4 + +static void +unlink_temp_files (void) +{ + unsigned i; + + if (dontdeltemps > 0) + return; + + for (i = 0; i < ARRAY_SIZE (temp_file_to_remove); i++) + { + if (temp_file_to_remove[i]) + { + unlink (temp_file_to_remove[i]); + temp_file_to_remove[i] = NULL; + } + } } static void @@ -1936,6 +2018,8 @@ gen_exp_file (void) /* xgettext:c-format */ fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM); + temp_file_to_remove[TEMP_EXPORT_FILE] = TMP_ASM; + /* xgettext:c-format */ inform (_("Opened temporary file: %s"), TMP_ASM); @@ -2023,7 +2107,8 @@ gen_exp_file (void) { if (!exp->noname || show_allnames) fprintf (f, "n%d: %s \"%s\"\n", - exp->ordinal, ASM_TEXT, xlate (exp->name)); + exp->ordinal, ASM_TEXT, + (exp->its_name ? exp->its_name : xlate (exp->name))); if (exp->forward != 0) fprintf (f, "f%d: %s \"%s\"\n", exp->forward, ASM_TEXT, exp->internal_name); @@ -2071,7 +2156,6 @@ gen_exp_file (void) } } - /* Add to the output file a way of getting to the exported names without using the import library. */ if (add_indirect) @@ -2085,10 +2169,11 @@ gen_exp_file (void) cygwin releases. */ if (create_compat_implib) fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name); - fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name); + fprintf (f, "\t%s\t_imp_%s%s\n", ASM_GLOBAL, + (!leading_underscore ? "" : "_"), exp->name); if (create_compat_implib) fprintf (f, "__imp_%s:\n", exp->name); - fprintf (f, "_imp__%s:\n", exp->name); + fprintf (f, "_imp_%s%s:\n", (!leading_underscore ? "" : "_"), exp->name); fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name); } } @@ -2097,7 +2182,7 @@ gen_exp_file (void) if (base_file) { bfd_vma addr; - bfd_vma need[PAGE_SIZE]; + bfd_vma need[COFF_PAGE_SIZE]; bfd_vma page_addr; bfd_size_type numbytes; int num_entries; @@ -2158,7 +2243,10 @@ gen_exp_file (void) assemble_file (TMP_ASM, exp_name); if (dontdeltemps == 0) - unlink (TMP_ASM); + { + temp_file_to_remove[TEMP_EXPORT_FILE] = NULL; + unlink (TMP_ASM); + } inform (_("Generated exports file")); } @@ -2167,10 +2255,10 @@ static const char * xlate (const char *name) { int lead_at = (*name == '@'); + int is_stdcall = (!lead_at && strchr (name, '@') != NULL); if (!lead_at && (add_underscore - || (add_stdcall_underscore - && strchr (name, '@')))) + || (add_stdcall_underscore && is_stdcall))) { char *copy = xmalloc (strlen (name) + 2); @@ -2205,6 +2293,9 @@ typedef struct unsigned char *data; } sinfo; +#define INIT_SEC_DATA(id, name, flags, align) \ + { id, name, flags, align, NULL, NULL, NULL, 0, NULL } + #ifndef DLLTOOL_PPC #define TEXT 0 @@ -2222,8 +2313,6 @@ typedef struct #define DATA_SEC_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA) #define BSS_SEC_FLAGS SEC_ALLOC -#define INIT_SEC_DATA(id, name, flags, align) \ - { id, name, flags, align, NULL, NULL, NULL, 0, NULL } static sinfo secdata[NSECS] = { INIT_SEC_DATA (TEXT, ".text", TEXT_SEC_FLAGS, 2), @@ -2253,15 +2342,15 @@ static sinfo secdata[NSECS] = static sinfo secdata[NSECS] = { - { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3}, - { PDATA, ".pdata", SEC_HAS_CONTENTS, 2}, - { RDATA, ".reldata", SEC_HAS_CONTENTS, 2}, - { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2}, - { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2}, - { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1}, - { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2}, - { DATA, ".data", SEC_DATA, 2}, - { BSS, ".bss", 0, 2} + INIT_SEC_DATA (TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3), + INIT_SEC_DATA (PDATA, ".pdata", SEC_HAS_CONTENTS, 2), + INIT_SEC_DATA (RDATA, ".reldata", SEC_HAS_CONTENTS, 2), + INIT_SEC_DATA (IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2), + INIT_SEC_DATA (IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2), + INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1), + INIT_SEC_DATA (IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2), + INIT_SEC_DATA (DATA, ".data", SEC_DATA, 2), + INIT_SEC_DATA (BSS, ".bss", 0, 2) }; #endif @@ -2393,11 +2482,9 @@ make_one_lib_file (export_type *exp, int i, int delay) if (si->id != i) abort (); si->sec = bfd_make_section_old_way (abfd, si->name); - bfd_set_section_flags (abfd, - si->sec, - si->flags & applicable); + bfd_set_section_flags (si->sec, si->flags & applicable); - bfd_set_section_alignment(abfd, si->sec, si->align); + bfd_set_section_alignment (si->sec, si->align); si->sec->output_section = si->sec; si->sym = bfd_make_empty_symbol(abfd); si->sym->name = si->sec->name; @@ -2459,7 +2546,7 @@ make_one_lib_file (export_type *exp, int i, int delay) iname_lab = bfd_make_empty_symbol (abfd); iname_lab->name = head_label; - iname_lab->section = (asection *) &bfd_und_section; + iname_lab->section = bfd_und_section_ptr; iname_lab->flags = 0; iname_lab->value = 0; @@ -2492,7 +2579,7 @@ make_one_lib_file (export_type *exp, int i, int delay) toc_symbol = bfd_make_empty_symbol (abfd); toc_symbol->name = make_label (".", "toc"); - toc_symbol->section = (asection *)&bfd_und_section; + toc_symbol->section = bfd_und_section_ptr; toc_symbol->flags = BSF_GLOBAL; toc_symbol->value = 0; @@ -2562,9 +2649,14 @@ make_one_lib_file (export_type *exp, int i, int delay) if (delay) { - rel2->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); + if (machine == MX86) + rel2->howto = bfd_reloc_type_lookup (abfd, + BFD_RELOC_32_PCREL); + else + rel2->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); rel2->sym_ptr_ptr = rel->sym_ptr_ptr; - rel3->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32_PCREL); + rel3->howto = bfd_reloc_type_lookup (abfd, + BFD_RELOC_32_PCREL); rel3->sym_ptr_ptr = iname_lab_pp; } @@ -2576,10 +2668,11 @@ make_one_lib_file (export_type *exp, int i, int delay) case IDATA5: if (delay) { - si->data = xmalloc (4); - si->size = 4; + si->size = create_for_pep ? 8 : 4; + si->data = xmalloc (si->size); sec->reloc_count = 1; memset (si->data, 0, si->size); + /* Point after jmp [__imp_...] instruction. */ si->data[0] = 6; rel = xmalloc (sizeof (arelent)); rpp = xmalloc (sizeof (arelent *) * 2); @@ -2587,12 +2680,16 @@ make_one_lib_file (export_type *exp, int i, int delay) rpp[1] = 0; rel->address = 0; rel->addend = 0; - rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); + if (create_for_pep) + rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_64); + else + rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); rel->sym_ptr_ptr = secdata[TEXT].sympp; sec->orelocation = rpp; break; } - /* else fall through */ + /* Fall through. */ + case IDATA4: /* An idata$4 or idata$5 is one word long, and has an rva to idata$6. */ @@ -2631,7 +2728,7 @@ make_one_lib_file (export_type *exp, int i, int delay) { si->data = xmalloc (4); si->size = 4; - + if (exp->noname) { si->data[0] = exp->ordinal ; @@ -2659,15 +2756,20 @@ make_one_lib_file (export_type *exp, int i, int delay) case IDATA6: if (!exp->noname) { - /* This used to add 1 to exp->hint. I don't know - why it did that, and it does not match what I see - in programs compiled with the MS tools. */ - int idx = exp->hint; - si->size = strlen (xlate (exp->import_name)) + 3; + int idx = exp->ordinal; + + if (exp->its_name) + si->size = strlen (exp->its_name) + 3; + else + si->size = strlen (xlate (exp->import_name)) + 3; si->data = xmalloc (si->size); + memset (si->data, 0, si->size); si->data[0] = idx & 0xff; si->data[1] = idx >> 8; - strcpy ((char *) si->data + 2, xlate (exp->import_name)); + if (exp->its_name) + strcpy ((char *) si->data + 2, exp->its_name); + else + strcpy ((char *) si->data + 2, xlate (exp->import_name)); } break; case IDATA7: @@ -2718,7 +2820,7 @@ make_one_lib_file (export_type *exp, int i, int delay) arelent *imglue, *ba_rel, *ea_rel, *pea_rel; /* Alignment must be set to 2**2 or you get extra stuff. */ - bfd_set_section_alignment(abfd, sec, 2); + bfd_set_section_alignment (sec, 2); si->size = 4 * 5; si->data = xmalloc (si->size); @@ -2804,8 +2906,8 @@ make_one_lib_file (export_type *exp, int i, int delay) { sinfo *si = secdata + i; - bfd_set_section_size (abfd, si->sec, si->size); - bfd_set_section_vma (abfd, si->sec, vma); + bfd_set_section_size (si->sec, si->size); + bfd_set_section_vma (si->sec, vma); } } /* Write them out. */ @@ -2831,7 +2933,7 @@ make_one_lib_file (export_type *exp, int i, int delay) /* xgettext:c-format */ fatal (_("bfd_open failed reopen stub file: %s: %s"), outname, bfd_get_errmsg ()); - + return abfd; } @@ -2847,6 +2949,8 @@ make_head (void) return NULL; } + temp_file_to_remove[TEMP_HEAD_FILE] = TMP_HEAD_S; + fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C); fprintf (f, "\t.section\t.idata$2\n"); @@ -2908,6 +3012,7 @@ make_head (void) fatal (_("failed to open temporary head file: %s: %s"), TMP_HEAD_O, bfd_get_errmsg ()); + temp_file_to_remove[TEMP_HEAD_O_FILE] = TMP_HEAD_O; return abfd; } @@ -2923,6 +3028,8 @@ make_delay_head (void) return NULL; } + temp_file_to_remove[TEMP_HEAD_FILE] = TMP_HEAD_S; + /* Output the __tailMerge__xxx function */ fprintf (f, "%s Import trampoline\n", ASM_C); fprintf (f, "\t.section\t.text\n"); @@ -2952,19 +3059,20 @@ make_delay_head (void) fprintf (f, "\n.section .data\n"); fprintf (f, "__DLL_HANDLE_%s:\n", imp_name_lab); fprintf (f, "\t%s\t0\t%s Handle\n", ASM_LONG, ASM_C); + if (create_for_pep) + fprintf (f, "\t%s\t0\n", ASM_LONG); fprintf (f, "\n"); fprintf (f, "%sStuff for compatibility\n", ASM_C); if (!no_idata5) { - fprintf (f, "\t.section\t.idata$5\n"); + fprintf (f, "\t.section\t.idata$5\n"); /* NULL terminating list. */ -#ifdef DLLTOOL_MX86_64 - fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); -#else - fprintf (f,"\t%s\t0\n", ASM_LONG); -#endif + if (create_for_pep) + fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); + else + fprintf (f,"\t%s\t0\n", ASM_LONG); fprintf (f, "__IAT_%s:\n", imp_name_lab); } @@ -2972,6 +3080,8 @@ make_delay_head (void) { fprintf (f, "\t.section\t.idata$4\n"); fprintf (f, "\t%s\t0\n", ASM_LONG); + if (create_for_pep) + fprintf (f, "\t%s\t0\n", ASM_LONG); fprintf (f, "\t.section\t.idata$4\n"); fprintf (f, "__INT_%s:\n", imp_name_lab); } @@ -2988,6 +3098,7 @@ make_delay_head (void) fatal (_("failed to open temporary head file: %s: %s"), TMP_HEAD_O, bfd_get_errmsg ()); + temp_file_to_remove[TEMP_HEAD_O_FILE] = TMP_HEAD_O; return abfd; } @@ -3003,6 +3114,8 @@ make_tail (void) return NULL; } + temp_file_to_remove[TEMP_TAIL_FILE] = TMP_TAIL_S; + if (!no_idata4) { fprintf (f, "\t.section\t.idata$4\n"); @@ -3059,6 +3172,7 @@ make_tail (void) fatal (_("failed to open temporary tail file: %s: %s"), TMP_TAIL_O, bfd_get_errmsg ()); + temp_file_to_remove[TEMP_TAIL_O_FILE] = TMP_TAIL_O; return abfd; } @@ -3084,6 +3198,8 @@ gen_lib_file (int delay) /* xgettext:c-format */ inform (_("Creating library file: %s"), imp_name); + xatexit (unlink_temp_files); + bfd_set_format (outarch, bfd_archive); outarch->has_armap = 1; outarch->is_thin_archive = 0; @@ -3118,13 +3234,13 @@ gen_lib_file (int delay) assert (i < PREFIX_ALIAS_BASE); alias_exp.name = make_imp_label (ext_prefix_alias, exp->name); alias_exp.internal_name = exp->internal_name; + alias_exp.its_name = exp->its_name; alias_exp.import_name = exp->name; alias_exp.ordinal = exp->ordinal; alias_exp.constant = exp->constant; alias_exp.noname = exp->noname; alias_exp.private = exp->private; alias_exp.data = exp->data; - alias_exp.hint = exp->hint; alias_exp.forward = exp->forward; alias_exp.next = exp->next; n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE, delay); @@ -3152,19 +3268,13 @@ gen_lib_file (int delay) } /* Delete all the temp files. */ - if (dontdeltemps == 0) - { - unlink (TMP_HEAD_O); - unlink (TMP_HEAD_S); - unlink (TMP_TAIL_O); - unlink (TMP_TAIL_S); - } + unlink_temp_files (); if (dontdeltemps < 2) { char *name; - name = (char *) alloca (strlen (TMP_STUB) + 10); + name = xmalloc (strlen (TMP_STUB) + 10); for (i = 0; (exp = d_exports_lexically[i]); i++) { /* Don't delete non-existent stubs for PRIVATE entries. */ @@ -3182,6 +3292,7 @@ gen_lib_file (int delay) non_fatal (_("cannot delete %s: %s"), name, strerror (errno)); } } + free (name); } inform (_("Created lib file")); @@ -3192,13 +3303,15 @@ gen_lib_file (int delay) static void dll_name_list_append (dll_name_list_type * list, bfd_byte * data) { + dll_name_list_node_type * entry; + /* Error checking. */ if (! list || ! list->tail) return; /* Allocate new node. */ - dll_name_list_node_type * entry = - (dll_name_list_node_type *) xmalloc (sizeof (dll_name_list_node_type)); + entry = ((dll_name_list_node_type *) + xmalloc (sizeof (dll_name_list_node_type))); /* Initialize its values. */ entry->dllname = xstrdup ((char *) data); @@ -3211,15 +3324,17 @@ dll_name_list_append (dll_name_list_type * list, bfd_byte * data) /* Count the number of entries in list. */ -static int +static int dll_name_list_count (dll_name_list_type * list) { + dll_name_list_node_type * p; + int count = 0; + /* Error checking. */ if (! list || ! list->head) return 0; - int count = 0; - dll_name_list_node_type * p = list->head; + p = list->head; while (p && p->next) { @@ -3231,14 +3346,16 @@ dll_name_list_count (dll_name_list_type * list) /* Print each entry in list to stdout. */ -static void +static void dll_name_list_print (dll_name_list_type * list) { + dll_name_list_node_type * p; + /* Error checking. */ if (! list || ! list->head) return; - dll_name_list_node_type * p = list->head; + p = list->head; while (p && p->next && p->next->dllname && *(p->next->dllname)) { @@ -3264,28 +3381,21 @@ dll_name_list_free (dll_name_list_type * list) /* Recursive function to free all nodes entry->next->next... as well as entry itself. */ -static void +static void dll_name_list_free_contents (dll_name_list_node_type * entry) { if (entry) { if (entry->next) - { - dll_name_list_free_contents (entry->next); - entry->next = NULL; - } - if (entry->dllname) - { - free (entry->dllname); - entry->dllname = NULL; - } + dll_name_list_free_contents (entry->next); + free (entry->dllname); free (entry); } } /* Allocate and initialize a dll_name_list_type object, including its sentinel node. Caller is responsible - for calling dll_name_list_free when finished with + for calling dll_name_list_free when finished with the list. */ static dll_name_list_type * @@ -3309,9 +3419,9 @@ dll_name_list_create (void) OBJ (where obj is cast to const char *). If found, set global variable identify_member_contains_symname_result TRUE. It is the caller's responsibility to set the result variable FALSE before iterating with - this function. */ + this function. */ -static void +static void identify_member_contains_symname (bfd * abfd, bfd * archive_bfd ATTRIBUTE_UNUSED, void * obj) @@ -3367,9 +3477,9 @@ identify_member_contains_symname (bfd * abfd, of all sections which meet the criteria to a linked list of dll names. Finally, print them all to stdout. (If --identify-strict, an error is - reported if more than one match was found). */ + reported if more than one match was found). */ -static void +static void identify_dll_for_implib (void) { bfd * abfd = NULL; @@ -3385,7 +3495,8 @@ identify_dll_for_implib (void) search_data.symname = "__NULL_IMPORT_DESCRIPTOR"; search_data.found = FALSE; - bfd_init (); + if (bfd_init () != BFD_INIT_MAGIC) + fatal (_("fatal error: libbfd ABI mismatch")); abfd = bfd_openr (identify_imp_name, 0); if (abfd == NULL) @@ -3407,7 +3518,7 @@ identify_dll_for_implib (void) (void *)(& search_data)); if (search_data.found) identify_data.ms_style_implib = TRUE; - + /* Rewind the bfd. */ if (! bfd_close (abfd)) bfd_fatal (identify_imp_name); @@ -3422,7 +3533,7 @@ identify_dll_for_implib (void) fatal (_("%s is not a library"), identify_imp_name); } - + /* Now search for the dll name. */ identify_search_archive (abfd, identify_search_member, @@ -3456,10 +3567,10 @@ identify_dll_for_implib (void) /* Loop over all members of the archive, applying the supplied function to each member that is a bfd_object. The function will be called as if: - func (member_bfd, abfd, user_storage) */ + func (member_bfd, abfd, user_storage) */ static void -identify_search_archive (bfd * abfd, +identify_search_archive (bfd * abfd, void (* operation) (bfd *, bfd *, void *), void * user_storage) { @@ -3487,7 +3598,15 @@ identify_search_archive (bfd * abfd, } if (last_arfile != NULL) - bfd_close (last_arfile); + { + bfd_close (last_arfile); + /* PR 17512: file: 8b2168d4. */ + if (last_arfile == arfile) + { + last_arfile = NULL; + break; + } + } last_arfile = arfile; } @@ -3499,7 +3618,7 @@ identify_search_archive (bfd * abfd, } /* Call the identify_search_section() function for each section of this - archive member. */ + archive member. */ static void identify_search_member (bfd *abfd, @@ -3511,7 +3630,7 @@ identify_search_member (bfd *abfd, /* This predicate returns true if section->name matches the desired value. By default, this is .idata$7 (.idata$6 on PPC, or if the import - library is ms-style). */ + library is ms-style). */ static bfd_boolean identify_process_section_p (asection * section, bfd_boolean ms_style_implib) @@ -3524,10 +3643,10 @@ identify_process_section_p (asection * section, bfd_boolean ms_style_implib) ".idata$7"; #endif static const char * MS_SECTION_NAME = ".idata$6"; - + const char * section_name = (ms_style_implib ? MS_SECTION_NAME : SECTION_NAME); - + if (strcmp (section_name, section->name) == 0) return TRUE; return FALSE; @@ -3563,7 +3682,7 @@ identify_search_section (bfd * abfd, asection * section, void * obj) if (ms_style && ((section->flags & SEC_DATA) == 0)) return; - if ((datasize = bfd_section_size (abfd, section)) == 0) + if ((datasize = bfd_section_size (section)) == 0) return; data = (bfd_byte *) xmalloc (datasize + 1); @@ -3574,7 +3693,7 @@ identify_search_section (bfd * abfd, asection * section, void * obj) /* Use a heuristic to determine if data is a dll name. Possible to defeat this if (a) the library has MANY - (more than 0x302f) imports, (b) it is an ms-style + (more than 0x302f) imports, (b) it is an ms-style import library, but (c) it is buggy, in that the SEC_DATA flag is set on the "wrong" sections. This heuristic might also fail to record a valid dll name if the dllname uses @@ -3620,7 +3739,10 @@ nfunc (const void *a, const void *b) export_type *bp = *(export_type **) b; const char *an = ap->name; const char *bn = bp->name; - + if (ap->its_name) + an = ap->its_name; + if (bp->its_name) + an = bp->its_name; if (killat) { an = (an[0] == '@') ? an + 1 : an; @@ -3776,10 +3898,8 @@ mangle_defs (void) { /* First work out the minimum ordinal chosen. */ export_type *exp; - - int i; - int hint = 0; export_type **d_export_vec = xmalloc (sizeof (export_type *) * d_nfuncs); + int i; inform (_("Processing definitions")); @@ -3808,11 +3928,6 @@ mangle_defs (void) qsort (d_exports_lexically, i, sizeof (export_type *), nfunc); - /* Fill exp entries with their hint values. */ - for (i = 0; i < d_nfuncs; i++) - if (!d_exports_lexically[i]->noname || show_allnames) - d_exports_lexically[i]->hint = hint++; - inform (_("Processed definitions")); } @@ -3841,6 +3956,8 @@ usage (FILE *file, int status) fprintf (file, _(" --use-nul-prefixed-import-tables Use zero prefixed idata$4 and idata$5.\n")); fprintf (file, _(" -U --add-underscore Add underscores to all symbols in interface library.\n")); fprintf (file, _(" --add-stdcall-underscore Add underscores to stdcall symbols in interface library.\n")); + fprintf (file, _(" --no-leading-underscore All symbols shouldn't be prefixed by an underscore.\n")); + fprintf (file, _(" --leading-underscore All symbols should be prefixed by an underscore.\n")); fprintf (file, _(" -k --kill-at Kill @ from exported names.\n")); fprintf (file, _(" -A --add-stdcall-alias Add aliases without @.\n")); fprintf (file, _(" -p --ext-prefix-alias Add aliases with .\n")); @@ -3873,6 +3990,8 @@ usage (FILE *file, int status) #define OPTION_USE_NUL_PREFIXED_IMPORT_TABLES \ (OPTION_ADD_STDCALL_UNDERSCORE + 1) #define OPTION_IDENTIFY_STRICT (OPTION_USE_NUL_PREFIXED_IMPORT_TABLES + 1) +#define OPTION_NO_LEADING_UNDERSCORE (OPTION_IDENTIFY_STRICT + 1) +#define OPTION_LEADING_UNDERSCORE (OPTION_NO_LEADING_UNDERSCORE + 1) static const struct option long_options[] = { @@ -3893,6 +4012,8 @@ static const struct option long_options[] = {"input-def", required_argument, NULL, 'd'}, {"add-underscore", no_argument, NULL, 'U'}, {"add-stdcall-underscore", no_argument, NULL, OPTION_ADD_STDCALL_UNDERSCORE}, + {"no-leading-underscore", no_argument, NULL, OPTION_NO_LEADING_UNDERSCORE}, + {"leading-underscore", no_argument, NULL, OPTION_LEADING_UNDERSCORE}, {"kill-at", no_argument, NULL, 'k'}, {"add-stdcall-alias", no_argument, NULL, 'A'}, {"ext-prefix-alias", required_argument, NULL, 'p'}, @@ -3933,13 +4054,14 @@ main (int ac, char **av) bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); + bfd_set_error_program_name (program_name); expandargv (&ac, &av); while ((c = getopt_long (ac, av, #ifdef DLLTOOL_MCORE_ELF - "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHhM:L:F:", + "m:e:l:aD:d:z:b:xp:cCuUkAS:t:f:nI:vVHhM:L:F:", #else - "m:e:l:y:aD:d:z:b:xp:cCuUkAS:f:nI:vVHh", + "m:e:l:y:aD:d:z:b:xp:cCuUkAS:t:f:nI:vVHh", #endif long_options, 0)) != EOF) @@ -3964,6 +4086,12 @@ main (int ac, char **av) case OPTION_ADD_STDCALL_UNDERSCORE: add_stdcall_underscore = 1; break; + case OPTION_NO_LEADING_UNDERSCORE: + leading_underscore = 0; + break; + case OPTION_LEADING_UNDERSCORE: + leading_underscore = 1; + break; case OPTION_IDENTIFY_STRICT: identify_strict = 1; break; @@ -3991,6 +4119,9 @@ main (int ac, char **av) break; case 'z': output_def = fopen (optarg, FOPEN_WT); + if (!output_def) + /* xgettext:c-format */ + fatal (_("Unable to open def-file: %s"), optarg); break; case 'D': dll_name = (char*) lbasename (optarg); @@ -4085,16 +4216,27 @@ main (int ac, char **av) /* Check if we generated PE+. */ create_for_pep = strcmp (mname, "i386:x86-64") == 0; + { + /* Check the default underscore */ + int u = leading_underscore; /* Underscoring mode. -1 for use default. */ + if (u == -1) + bfd_get_target_info (mtable[machine].how_bfd_target, NULL, + NULL, &u, NULL); + if (u != -1) + leading_underscore = (u != 0 ? TRUE : FALSE); + } + if (!dll_name && exp_name) { /* If we are inferring dll_name from exp_name, strip off any path components, without emitting - a warning. */ - const char* exp_basename = lbasename (exp_name); + a warning. */ + const char* exp_basename = lbasename (exp_name); const int len = strlen (exp_basename) + 5; dll_name = xmalloc (len); strcpy (dll_name, exp_basename); strcat (dll_name, ".dll"); + dll_name_set_by_exp_name = 1; } if (as_name == NULL) @@ -4147,7 +4289,7 @@ main (int ac, char **av) if (mtable[machine].how_dljtab == 0) { - inform (_("Warning, machine type (%d) not supported for " + inform (_("Warning, machine type (%d) not supported for " "delayimport."), machine); } else