X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fdlltool.c;h=6c4737e7095045545b641be7070a9fac714c9a44;hb=f76d79580efea856298d9e5b9a91746be875f1b1;hp=4c9d2ecc396a2277e735288d75434eb304de16ba;hpb=bf201fddaaaae8fbd048f6d58b315080f5069b9f;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/dlltool.c b/binutils/dlltool.c index 4c9d2ecc39..6c4737e709 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-2019 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 -/* get current BFD error message */ +#ifndef PAGE_MASK +#define PAGE_MASK ((bfd_vma) (- COFF_PAGE_SIZE)) +#endif + +/* 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 @@ -372,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 @@ -385,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 @@ -432,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 @@ -478,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 @@ -510,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] */ @@ -576,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" @@ -586,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; @@ -705,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", @@ -725,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 } @@ -752,10 +767,9 @@ typedef struct export 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; @@ -852,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: @@ -880,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: @@ -906,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: @@ -930,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 ""; @@ -1055,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"; @@ -1076,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) @@ -1092,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); @@ -1142,7 +1165,7 @@ 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; @@ -1150,7 +1173,7 @@ append_import (const char *symbol_name, const char *dll_name, int func_ordinal, 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)); @@ -1165,7 +1188,7 @@ 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; @@ -1213,7 +1236,7 @@ def_import (const char *app_name, const char *module, const char *dllext, 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; @@ -1226,19 +1249,18 @@ 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); + + if (buf) + free (buf); } void def_version (int major, int minor) { - printf ("VERSION %d.%d\n", major, minor); + printf (_("VERSION %d.%d\n"), major, minor); } void @@ -1286,7 +1308,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; @@ -1294,7 +1316,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; @@ -1313,6 +1335,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) { @@ -1362,7 +1385,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); @@ -1386,12 +1409,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; @@ -1488,7 +1525,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; @@ -1639,10 +1677,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 @@ -1926,12 +1969,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 @@ -1950,6 +2019,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); @@ -2086,7 +2157,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) @@ -2100,10 +2170,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); } } @@ -2112,7 +2183,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; @@ -2173,7 +2244,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")); } @@ -2182,10 +2256,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); @@ -2220,6 +2294,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 @@ -2237,8 +2314,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), @@ -2268,15 +2343,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 @@ -2408,11 +2483,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; @@ -2474,7 +2547,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; @@ -2507,7 +2580,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; @@ -2577,9 +2650,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; } @@ -2591,10 +2669,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); @@ -2602,12 +2681,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. */ @@ -2646,7 +2729,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 ; @@ -2674,15 +2757,14 @@ 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; + 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; if (exp->its_name) @@ -2739,7 +2821,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); @@ -2825,8 +2907,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. */ @@ -2852,7 +2934,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; } @@ -2868,6 +2950,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"); @@ -2929,6 +3013,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; } @@ -2944,6 +3029,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"); @@ -2973,6 +3060,8 @@ 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); @@ -2981,11 +3070,10 @@ make_delay_head (void) { 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); } @@ -2993,6 +3081,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); } @@ -3009,6 +3099,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; } @@ -3024,6 +3115,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"); @@ -3080,6 +3173,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; } @@ -3105,6 +3199,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; @@ -3146,7 +3242,6 @@ gen_lib_file (int delay) 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); @@ -3174,19 +3269,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. */ @@ -3204,6 +3293,7 @@ gen_lib_file (int delay) non_fatal (_("cannot delete %s: %s"), name, strerror (errno)); } } + free (name); } inform (_("Created lib file")); @@ -3235,7 +3325,7 @@ 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; @@ -3257,7 +3347,7 @@ 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; @@ -3292,7 +3382,7 @@ 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) @@ -3313,7 +3403,7 @@ dll_name_list_free_contents (dll_name_list_node_type * 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 * @@ -3337,9 +3427,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) @@ -3395,9 +3485,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; @@ -3413,7 +3503,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) @@ -3435,7 +3526,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); @@ -3450,7 +3541,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, @@ -3484,10 +3575,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) { @@ -3515,7 +3606,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; } @@ -3527,7 +3626,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, @@ -3539,7 +3638,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) @@ -3552,10 +3651,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; @@ -3591,7 +3690,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); @@ -3602,7 +3701,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 @@ -3807,10 +3906,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")); @@ -3839,11 +3936,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")); } @@ -3872,6 +3964,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")); @@ -3904,6 +3998,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[] = { @@ -3924,6 +4020,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'}, @@ -3964,13 +4062,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) @@ -3995,6 +4094,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; @@ -4022,6 +4127,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); @@ -4116,16 +4224,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)