/* 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.
= Array of { short, asciz } entries, one for each imported function.
The `short' is the function's ordinal number.
- .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc). */
+ .idata$7 = dll name (eg: "kernel32.dll"). */
-/* 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 "bucomm.h"
#include "dlltool.h"
#include "safe-ctype.h"
+#include "coff-bfd.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. */
+#define bfd_get_errmsg() (bfd_errmsg (bfd_get_error ()))
/* Forward references. */
static char *look_for_prog (const char *, const char *, int);
#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
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;
typedef struct iheadt
{
- char *dllname; /* Name of dll file imported from. */
+ char * dllname; /* Name of dll file imported from. */
long nfuncs; /* Number of functions in list. */
struct ifunct *funchead; /* First function in list. */
struct ifunct *functail; /* Last function in list. */
(qv "ihead structure"). */
static iheadtype *import_list = NULL;
-
static char *as_name = NULL;
static char * as_flags = "";
-
static char *tmp_prefix;
-
static int no_idata4;
static int no_idata5;
static char *exp_name;
char * dllname;
struct dll_name_list_node_t * next;
} dll_name_list_node_type;
+
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
const char * symname;
bfd_boolean found;
} symname_search_data_type;
+
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
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
static const char *mname = "i386:x86-64";
#endif
-#ifdef DLLTOOL_DEFAULT_PPC
-static const char *mname = "ppc";
-#endif
-
#ifdef DLLTOOL_DEFAULT_SH
static const char *mname = "sh";
#endif
#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] */
0x00, 0x00, 0x00, 0x00 /* <address> */
};
-/* This is the glue sequence for PowerPC PE. There is a
- tocrel16-tocdefn reloc against the first instruction.
- We also need a IMGLUE reloc against the glue function
- to restore the toc saved by the third instruction in
- the glue. */
-static const unsigned char ppc_jtab[] =
-{
- 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
- /* Reloc TOCREL16 __imp_xxx */
- 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
- 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
- 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
- 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
- 0x20, 0x04, 0x80, 0x4E /* bctr */
-};
-
-#ifdef DLLTOOL_PPC
-/* The glue instruction, picks up the toc from the stw in
- the above code: "lwz r2,4(r1)". */
-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;
- const char *how_byte;
- const char *how_short;
- const char *how_long;
- const char *how_asciz;
- const char *how_comment;
- const char *how_jump;
- const char *how_global;
- const char *how_space;
- const char *how_align_short;
- const char *how_align_long;
- const char *how_default_as_switches;
- const char *how_bfd_target;
- enum bfd_architecture how_bfd_arch;
- const unsigned char *how_jtab;
- int how_jtab_size; /* Size of the jtab entry. */
- int how_jtab_roff; /* Offset into it for the ind 32 reloc into idata 5. */
- const unsigned char *how_dljtab;
- int how_dljtab_size; /* Size of the dljtab entry. */
- int how_dljtab_roff1; /* Offset for the ind 32 reloc into idata 5. */
- int how_dljtab_roff2; /* Offset for the ind 32 reloc into idata 5. */
- int how_dljtab_roff3; /* Offset for the ind 32 reloc into idata 5. */
- const char *trampoline;
- };
+{
+ const char *type;
+ const char *how_byte;
+ const char *how_short;
+ const char *how_long;
+ const char *how_asciz;
+ const char *how_comment;
+ const char *how_jump;
+ const char *how_global;
+ const char *how_space;
+ const char *how_align_short;
+ const char *how_align_long;
+ const char *how_default_as_switches;
+ const char *how_bfd_target;
+ enum bfd_architecture how_bfd_arch;
+ const unsigned char *how_jtab;
+ int how_jtab_size; /* Size of the jtab entry. */
+ int how_jtab_roff; /* Offset into it for the ind 32 reloc into idata 5. */
+ const unsigned char *how_dljtab;
+ int how_dljtab_size; /* Size of the dljtab entry. */
+ int how_dljtab_roff1; /* Offset for the ind 32 reloc into idata 5. */
+ int how_dljtab_roff2; /* Offset for the ind 32 reloc into idata 5. */
+ int how_dljtab_roff3; /* Offset for the ind 32 reloc into idata 5. */
+ const char *trampoline;
+};
static const struct mac
mtable[] =
}
,
{
-#define MPPC 2
- "ppc", ".byte", ".short", ".long", ".asciz", "#",
- "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
- "pe-powerpcle",bfd_arch_powerpc,
- ppc_jtab, sizeof (ppc_jtab), 0,
- 0, 0, 0, 0, 0, 0
- }
- ,
- {
-#define MTHUMB 3
+#define MTHUMB 2
"thumb", ".byte", ".short", ".long", ".asciz", "@",
"push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
0, 0, 0, 0, 0, 0
}
,
-#define MARM_INTERWORK 4
+#define MARM_INTERWORK 3
{
"arm_interwork", ".byte", ".short", ".long", ".asciz", "@",
"ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
}
,
{
-#define MMCORE_BE 5
+#define MMCORE_BE 4
"mcore-be", ".byte", ".short", ".long", ".asciz", "//",
"lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
".global", ".space", ".align\t2",".align\t4", "",
}
,
{
-#define MMCORE_LE 6
+#define MMCORE_LE 5
"mcore-le", ".byte", ".short", ".long", ".asciz", "//",
"lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
".global", ".space", ".align\t2",".align\t4", "-EL",
}
,
{
-#define MMCORE_ELF 7
+#define MMCORE_ELF 6
"mcore-elf-be", ".byte", ".short", ".long", ".asciz", "//",
"lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
".global", ".space", ".align\t2",".align\t4", "",
}
,
{
-#define MMCORE_ELF_LE 8
+#define MMCORE_ELF_LE 7
"mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//",
"lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
".global", ".space", ".align\t2",".align\t4", "-EL",
}
,
{
-#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 8
"arm-wince", ".byte", ".short", ".long", ".asciz", "@",
"ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
}
,
{
-#define MX86 11
+#define MX86 9
"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 }
dlist_type;
typedef struct export
- {
- const char *name;
- const char *internal_name;
- const char *import_name;
- int ordinal;
- int constant;
- int noname; /* Don't put name in image file. */
- int private; /* Don't put reference in import lib. */
- int data;
- int hint;
- int forward; /* Number of forward label, 0 means no forward. */
- struct export *next;
- }
+{
+ 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 data;
+ int forward; /* Number of forward label, 0 means no forward. */
+ struct export *next;
+}
export_type;
/* A list of symbols which we should not export. */
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);
}
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:
case MX86:
- case MPPC:
case MTHUMB:
case MARM_INTERWORK:
case MMCORE_BE:
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:
case MX86:
- case MPPC:
case MTHUMB:
case MARM_INTERWORK:
case MMCORE_BE:
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:
case MTHUMB:
case MARM_INTERWORK:
case MMCORE_BE:
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 "";
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;
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;
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;
}
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;
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;
}
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
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)
{
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);
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;
/* 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, '@'))
{
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
++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, '@'))
{
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);
}
}
}
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;
if (!f)
/* xgettext:c-format */
- fatal (_("Unable to open object file: %s"), filename);
+ fatal (_("Unable to open object file: %s: %s"), filename, bfd_get_errmsg ());
/* xgettext:c-format */
inform (_("Scanning object file %s"), 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
bfd_close (f);
}
-/**********************************************************************/
+\f
static void
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,
exp->noname ? "NONAME " : "",
exp->private ? "PRIVATE " : "",
exp->constant ? "CONSTANT" : "",
- exp->data ? "DATA" : "");
+ exp->data ? "DATA" : "",
+ exp->its_name ? " ==" : "",
+ exp->its_name ? exp->its_name : "");
}
}
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,
exp->ordinal,
exp->noname ? " NONAME" : "",
exp->private ? "PRIVATE " : "",
- exp->data ? " DATA" : "");
+ exp->data ? " DATA" : "",
+ exp->its_name ? " ==" : "",
+ exp->its_name ? exp->its_name : "");
}
}
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++;
}
{
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);
{
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);
}
}
-
/* 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;
-#ifndef DLLTOOL_PPC
+#define INIT_SEC_DATA(id, name, flags, align) \
+ { id, name, flags, align, NULL, NULL, NULL, 0, NULL }
#define TEXT 0
#define DATA 1
#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),
INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1)
};
-#else
-
-/* Sections numbered to make the order the same as other PowerPC NT
- compilers. This also keeps funny alignment thingies from happening. */
-#define TEXT 0
-#define PDATA 1
-#define RDATA 2
-#define IDATA5 3
-#define IDATA4 4
-#define IDATA6 5
-#define IDATA7 6
-#define DATA 7
-#define BSS 8
-
-#define NSECS 9
-
-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}
-};
-
-#endif
-
/* This is what we're trying to make. We generate the imp symbols with
both single and double underscores, for compatibility.
# Hint/Name table
.section .idata$6
ID2: .short 2
- .asciz "GetFileVersionInfoSizeW"
-
-
- For the PowerPC, here's the variation on the above scheme:
-
-# Rather than a simple "jmp *", the code to get to the dll function
-# looks like:
- .text
- lwz r11,[tocv]__imp_function_name(r2)
-# RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
- lwz r12,0(r11)
- stw r2,4(r1)
- mtctr r12
- lwz r2,4(r11)
- bctr */
+ .asciz "GetFileVersionInfoSizeW" */
static char *
make_label (const char *prefix, const char *name)
asymbol * iname_lab;
asymbol ** iname_lab_pp;
asymbol ** iname_pp;
-#ifdef DLLTOOL_PPC
- asymbol ** fn_pp;
- asymbol ** toc_pp;
-#define EXTRA 2
-#endif
#ifndef EXTRA
#define EXTRA 0
#endif
if (!abfd)
/* xgettext:c-format */
- fatal (_("bfd_open failed open stub file: %s"), outname);
+ fatal (_("bfd_open failed open stub file: %s: %s"),
+ outname, bfd_get_errmsg ());
/* xgettext:c-format */
inform (_("Creating stub file: %s"), outname);
sinfo *si = secdata + i;
if (si->id != i)
- abort();
+ 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;
{
exp_label = bfd_make_empty_symbol (abfd);
exp_label->name = make_imp_label ("", exp->name);
-
- /* On PowerPC, the function name points to a descriptor in
- the rdata section, the first element of which is a
- pointer to the code (..function_name), and the second
- points to the .toc. */
-#ifdef DLLTOOL_PPC
- if (machine == MPPC)
- exp_label->section = secdata[RDATA].sec;
- else
-#endif
- exp_label->section = secdata[TEXT].sec;
-
+ exp_label->section = secdata[TEXT].sec;
exp_label->flags = BSF_GLOBAL;
exp_label->value = 0;
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;
iname_lab_pp = ptrs + oidx;
ptrs[oidx++] = iname_lab;
-#ifdef DLLTOOL_PPC
- /* The symbol referring to the code (.text). */
- {
- asymbol *function_name;
-
- function_name = bfd_make_empty_symbol(abfd);
- function_name->name = make_label ("..", exp->name);
- function_name->section = secdata[TEXT].sec;
- function_name->flags = BSF_GLOBAL;
- function_name->value = 0;
-
- fn_pp = ptrs + oidx;
- ptrs[oidx++] = function_name;
- }
-
- /* The .toc symbol. */
- {
- asymbol *toc_symbol;
-
- toc_symbol = bfd_make_empty_symbol (abfd);
- toc_symbol->name = make_label (".", "toc");
- toc_symbol->section = (asection *)&bfd_und_section;
- toc_symbol->flags = BSF_GLOBAL;
- toc_symbol->value = 0;
-
- toc_pp = ptrs + oidx;
- ptrs[oidx++] = toc_symbol;
- }
-#endif
-
ptrs[oidx] = 0;
for (i = 0; i < NSECS; i++)
rpp[3] = 0;
}
- if (machine == MPPC)
- {
- rel->howto = bfd_reloc_type_lookup (abfd,
- BFD_RELOC_16_GOTOFF);
- rel->sym_ptr_ptr = iname_pp;
- }
- else if (machine == MX86)
+ if (machine == MX86)
{
rel->howto = bfd_reloc_type_lookup (abfd,
BFD_RELOC_32_PCREL);
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;
}
- /* else fall through */
+ /* Fall through. */
+
case IDATA4:
/* An idata$4 or idata$5 is one word long, and has an
rva to idata$6. */
{
si->data = xmalloc (4);
si->size = 4;
-
+
if (exp->noname)
{
si->data[0] = exp->ordinal ;
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:
sec->orelocation = rpp;
sec->reloc_count = 1;
break;
-
-#ifdef DLLTOOL_PPC
- case PDATA:
- {
- /* The .pdata section is 5 words long.
- Think of it as:
- struct
- {
- bfd_vma BeginAddress, [0x00]
- EndAddress, [0x04]
- ExceptionHandler, [0x08]
- HandlerData, [0x0c]
- PrologEndAddress; [0x10]
- }; */
-
- /* So this pdata section setups up this as a glue linkage to
- a dll routine. There are a number of house keeping things
- we need to do:
-
- 1. In the name of glue trickery, the ADDR32 relocs for 0,
- 4, and 0x10 are set to point to the same place:
- "..function_name".
- 2. There is one more reloc needed in the pdata section.
- The actual glue instruction to restore the toc on
- return is saved as the offset in an IMGLUE reloc.
- So we need a total of four relocs for this section.
-
- 3. Lastly, the HandlerData field is set to 0x03, to indicate
- that this is a glue routine. */
- 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);
-
- si->size = 4 * 5;
- si->data = xmalloc (si->size);
- memset (si->data, 0, si->size);
- rpp = xmalloc (sizeof (arelent *) * 5);
- rpp[0] = imglue = xmalloc (sizeof (arelent));
- rpp[1] = ba_rel = xmalloc (sizeof (arelent));
- rpp[2] = ea_rel = xmalloc (sizeof (arelent));
- rpp[3] = pea_rel = xmalloc (sizeof (arelent));
- rpp[4] = 0;
-
- /* Stick the toc reload instruction in the glue reloc. */
- bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
-
- imglue->addend = 0;
- imglue->howto = bfd_reloc_type_lookup (abfd,
- BFD_RELOC_32_GOTOFF);
- imglue->sym_ptr_ptr = fn_pp;
-
- ba_rel->address = 0;
- ba_rel->addend = 0;
- ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
- ba_rel->sym_ptr_ptr = fn_pp;
-
- bfd_put_32 (abfd, 0x18, si->data + 0x04);
- ea_rel->address = 4;
- ea_rel->addend = 0;
- ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
- ea_rel->sym_ptr_ptr = fn_pp;
-
- /* Mark it as glue. */
- bfd_put_32 (abfd, 0x03, si->data + 0x0c);
-
- /* Mark the prolog end address. */
- bfd_put_32 (abfd, 0x0D, si->data + 0x10);
- pea_rel->address = 0x10;
- pea_rel->addend = 0;
- pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
- pea_rel->sym_ptr_ptr = fn_pp;
-
- sec->orelocation = rpp;
- sec->reloc_count = 4;
- break;
- }
- case RDATA:
- /* Each external function in a PowerPC PE file has a two word
- descriptor consisting of:
- 1. The address of the code.
- 2. The address of the appropriate .toc
- We use relocs to build this. */
- si->size = 8;
- si->data = xmalloc (8);
- memset (si->data, 0, si->size);
-
- rpp = xmalloc (sizeof (arelent *) * 3);
- rpp[0] = rel = xmalloc (sizeof (arelent));
- rpp[1] = xmalloc (sizeof (arelent));
- rpp[2] = 0;
-
- rel->address = 0;
- rel->addend = 0;
- rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
- rel->sym_ptr_ptr = fn_pp;
-
- rel = rpp[1];
-
- rel->address = 4;
- rel->addend = 0;
- rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
- rel->sym_ptr_ptr = toc_pp;
-
- sec->orelocation = rpp;
- sec->reloc_count = 2;
- break;
-#endif /* DLLTOOL_PPC */
}
}
{
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. */
bfd_set_symtab (abfd, ptrs, oidx);
bfd_close (abfd);
abfd = bfd_openr (outname, HOW_BFD_READ_TARGET);
+ if (!abfd)
+ /* xgettext:c-format */
+ fatal (_("bfd_open failed reopen stub file: %s: %s"),
+ outname, bfd_get_errmsg ());
+
return abfd;
}
make_head (void)
{
FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
+ bfd *abfd;
if (f == NULL)
{
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");
assemble_file (TMP_HEAD_S, TMP_HEAD_O);
- return bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
+ abfd = bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
+ if (abfd == NULL)
+ /* xgettext:c-format */
+ 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;
}
bfd *
make_delay_head (void)
{
FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
+ bfd *abfd;
if (f == NULL)
{
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);
if (!no_idata5)
{
- fprintf (f, "\t.section\t.idata$5\n");\r
+ 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);
}
assemble_file (TMP_HEAD_S, TMP_HEAD_O);
- return bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
+ abfd = bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
+ if (abfd == NULL)
+ /* xgettext:c-format */
+ 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;
}
static bfd *
make_tail (void)
{
FILE *f = fopen (TMP_TAIL_S, FOPEN_WT);
+ bfd *abfd;
if (f == NULL)
{
return NULL;
}
+ temp_file_to_remove[TEMP_TAIL_FILE] = TMP_TAIL_S;
+
if (!no_idata4)
{
fprintf (f, "\t.section\t.idata$4\n");
fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
}
-#ifdef DLLTOOL_PPC
- /* Normally, we need to see a null descriptor built in idata$3 to
- act as the terminator for the list. The ideal way, I suppose,
- would be to mark this section as a comdat type 2 section, so
- only one would appear in the final .exe (if our linker supported
- comdat, that is) or cause it to be inserted by something else (say
- crt0). */
-
- fprintf (f, "\t.section\t.idata$3\n");
- fprintf (f, "\t%s\t0\n", ASM_LONG);
- fprintf (f, "\t%s\t0\n", ASM_LONG);
- fprintf (f, "\t%s\t0\n", ASM_LONG);
- fprintf (f, "\t%s\t0\n", ASM_LONG);
- fprintf (f, "\t%s\t0\n", ASM_LONG);
-#endif
-
-#ifdef DLLTOOL_PPC
- /* Other PowerPC NT compilers use idata$6 for the dllname, so I
- do too. Original, huh? */
- fprintf (f, "\t.section\t.idata$6\n");
-#else
fprintf (f, "\t.section\t.idata$7\n");
-#endif
-
fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
imp_name_lab, ASM_TEXT, dll_name);
assemble_file (TMP_TAIL_S, TMP_TAIL_O);
- return bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET);
+ abfd = bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET);
+ if (abfd == NULL)
+ /* xgettext:c-format */
+ 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;
}
static void
if (!outarch)
/* xgettext:c-format */
- fatal (_("Can't open .lib file: %s"), imp_name);
+ fatal (_("Can't create .lib file: %s: %s"),
+ imp_name, bfd_get_errmsg ());
/* 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;
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);
}
/* 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"));
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);
/* 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)
{
/* 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))
{
/* 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 *
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)
}
/* This is the main implementation for the --identify option.
- Given the name of an import library in identify_imp_name, first determine
- if the import library is a GNU binutils-style one (where the DLL name is
- stored in an .idata$7 (.idata$6 on PPC) section, or if it is a MS-style
- one (where the DLL name, along with much other data, is stored in the
- .idata$6 section). We determine the style of import library by searching
- for the DLL-structure symbol inserted by MS tools:
- __NULL_IMPORT_DESCRIPTOR.
+ Given the name of an import library in identify_imp_name, first
+ determine if the import library is a GNU binutils-style one (where
+ the DLL name is stored in an .idata$7 section), or if it is a
+ MS-style one (where the DLL name, along with much other data, is
+ stored in the .idata$6 section). We determine the style of import
+ library by searching for the DLL-structure symbol inserted by MS
+ tools: __NULL_IMPORT_DESCRIPTOR.
Once we know which section to search, evaluate each section for the
appropriate properties that indicate it may contain the name of the
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;
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)
- bfd_fatal (identify_imp_name);
+ /* xgettext:c-format */
+ fatal (_("Can't open .lib file: %s: %s"),
+ identify_imp_name, bfd_get_errmsg ());
if (! bfd_check_format (abfd, bfd_archive))
{
(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). */
+ By default, this is .idata$7 (.idata$6 if the import library is
+ ms-style). */
static bfd_boolean
identify_process_section_p (asection * section, bfd_boolean ms_style_implib)
{
- static const char * SECTION_NAME =
-#ifdef DLLTOOL_PPC
- /* dllname is stored in idata$6 on PPC */
- ".idata$6";
-#else
- ".idata$7";
-#endif
+ static const char * SECTION_NAME = ".idata$7";
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;
}
-/* If *section has contents and its name is .idata$7 (.data$6 on PPC or if
+/* If *section has contents and its name is .idata$7 (.idata$6 if
import lib ms-generated) -- and it satisfies several other constraints
-- then add the contents of the section to obj->list. */
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);
/* 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
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;
{
/* 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"));
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"));
}
fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name);
/* xgetext:c-format */
fprintf (file, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname);
- fprintf (file, _(" possible <machine>: arm[_interwork], i386, mcore[-elf]{-le|-be}, ppc, thumb\n"));
+ fprintf (file, _(" possible <machine>: arm[_interwork], i386, mcore[-elf]{-le|-be}, thumb\n"));
fprintf (file, _(" -e --output-exp <outname> Generate an export file.\n"));
fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n"));
fprintf (file, _(" -y --output-delaylib <outname> Create a delay-import library.\n"));
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)
if (mtable[machine].how_dljtab == 0)
{
- inform (_("Warning, machine type (%d) not supported for "\r
+ inform (_("Warning, machine type (%d) not supported for "
"delayimport."), machine);
}
else
/* Deduce the name of the program we are want to invoke.
PROG_NAME is the basic name of the program we want to run,
eg "as" or "ld". The catch is that we might want actually
- run "i386-pe-as" or "ppc-pe-ld".
+ run "i386-pe-as".
If argv[0] contains the full path, then try to find the program
in the same place, with and then without a target-like prefix.