/* 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-2016 Free Software Foundation, Inc.
This file is part of GNU Binutils.
.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"
#include "safe-ctype.h"
#include <time.h>
-#include <sys/stat.h>
-#include <stdarg.h>
#include <assert.h>
#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. */
#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
{
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
{
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
#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
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] */
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"
"\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;
"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 }
}
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:
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:
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:
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 "";
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";
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)
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);
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;
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 = xmalloc (sizeof (iheadtype));
- q->dllname = xstrdup (dll_name);
+ q->dllname = xstrdup (dllname);
q->nfuncs = 1;
q->funchead = xmalloc (sizeof (ifunctype));
q->functail = q->funchead;
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;
}
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
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;
if (*s == ' ')
i++;
i++;
- argv = alloca (sizeof (char *) * (i + 3));
+ argv = xmalloc (sizeof (char *) * (i + 3));
i = 0;
argv[i++] = what;
s = 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)
{
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;
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;
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
{
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
/* 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);
}
}
-
/* Add to the output file a way of getting to the exported names
without using the import library. */
if (add_indirect)
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);
}
}
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;
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"));
}
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);
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
#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),
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
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;
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;
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;
}
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);
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;
{
si->data = xmalloc (4);
si->size = 4;
-
+
if (exp->noname)
{
si->data[0] = exp->ordinal ;
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)
/* xgettext:c-format */
fatal (_("bfd_open failed reopen stub file: %s: %s"),
outname, bfd_get_errmsg ());
-
+
return abfd;
}
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");
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;
}
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");
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);
{
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);
}
{
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);
}
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;
}
return NULL;
}
+ temp_file_to_remove[TEMP_TAIL_FILE] = TMP_TAIL_S;
+
if (!no_idata4)
{
fprintf (f, "\t.section\t.idata$4\n");
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;
}
/* 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;
}
/* 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. */
non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
}
}
+ free (name);
}
inform (_("Created lib file"));
/* 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;
/* 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;
/* 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)
/* 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 *
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)
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;
(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);
fatal (_("%s is not a library"), identify_imp_name);
}
-
+
/* Now search for the dll name. */
identify_search_archive (abfd,
identify_search_member,
/* 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)
{
}
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;
}
}
/* Call the identify_search_section() function for each section of this
- archive member. */
+ archive member. */
static void
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)
".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;
/* 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
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 @<n> from exported names.\n"));
fprintf (file, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
fprintf (file, _(" -p --ext-prefix-alias <prefix> Add aliases with <prefix>.\n"));
#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[] =
{
{"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'},
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)
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;
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);
/* 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)