/* 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, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 1995-2021 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"). */
#include "sysdep.h"
#include "bfd.h"
#include "bucomm.h"
#include "dlltool.h"
#include "safe-ctype.h"
+#include "coff-bfd.h"
#include <time.h>
#include <assert.h>
static char *imp_name;
static char *delayimp_name;
static char *identify_imp_name;
-static bfd_boolean identify_strict;
+static bool identify_strict;
/* Types used to implement a linked list of dllnames associated
with the specified import lib. Used by the identify_* code.
{
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;
+ const char *symname;
+ bool found;
} symname_search_data_type;
typedef struct identify_data_t
{
- dll_name_list_type * list;
- bfd_boolean ms_style_implib;
-} identify_data_type;
+ dll_name_list_type *list;
+ bool ms_style_implib;
+} identify_data_type;
static char *head_label;
/* TRUE if we should export all symbols. Otherwise, we only export
symbols listed in .drectve sections or in the def file. */
-static bfd_boolean export_all_symbols;
+static bool export_all_symbols;
/* TRUE if we should exclude the symbols in DEFAULT_EXCLUDES when
exporting all symbols. */
-static bfd_boolean do_default_excludes = TRUE;
+static bool do_default_excludes = true;
-static bfd_boolean use_nul_prefixed_import_tables = FALSE;
+static bool use_nul_prefixed_import_tables = false;
/* Default symbols to exclude when exporting all the symbols. */
static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr";
/* TRUE if we should add __imp_<SYMBOL> to import libraries for backward
compatibility to old Cygwin releases. */
-static bfd_boolean create_compat_implib;
+static bool create_compat_implib;
/* TRUE if we have to write PE+ import libraries. */
-static bfd_boolean create_for_pep;
+static bool create_for_pep;
static char *def_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
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
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"
+static const char i386_x64_trampoline[] =
+ "\tsubq $72, %%rsp\n"
+ "\t.seh_stackalloc 72\n"
+ "\t.seh_endprologue\n"
+ "\tmovq %%rcx, 64(%%rsp)\n"
+ "\tmovq %%rdx, 56(%%rsp)\n"
+ "\tmovq %%r8, 48(%%rsp)\n"
+ "\tmovq %%r9, 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"
+ "\tmovq 40(%%rsp), %%r9\n"
+ "\tmovq 48(%%rsp), %%r8\n"
+ "\tmovq 56(%%rsp), %%rdx\n"
+ "\tmovq 64(%%rsp), %%rcx\n"
+ "\taddq $72, %%rsp\n"
"\tjmp *%%rax\n";
struct mac
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. */
+ bool how_seh;
const char *trampoline;
};
".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
"pe-arm-little", bfd_arch_arm,
arm_jtab, sizeof (arm_jtab), 8,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, false, 0
}
,
{
"jmp *", ".global", ".space", ".align\t2",".align\t4", "",
"pe-i386",bfd_arch_i386,
i386_jtab, sizeof (i386_jtab), 2,
- i386_dljtab, sizeof (i386_dljtab), 2, 7, 12, i386_trampoline
+ i386_dljtab, sizeof (i386_dljtab), 2, 7, 12, false, i386_trampoline
}
,
{
-#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",
"pe-arm-little", bfd_arch_arm,
thumb_jtab, sizeof (thumb_jtab), 12,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, false, 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",
".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
"pe-arm-little", bfd_arch_arm,
arm_interwork_jtab, sizeof (arm_interwork_jtab), 12,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, false, 0
}
,
{
-#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", "",
"pe-mcore-big", bfd_arch_mcore,
mcore_be_jtab, sizeof (mcore_be_jtab), 8,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, false, 0
}
,
{
-#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",
"pe-mcore-little", bfd_arch_mcore,
mcore_le_jtab, sizeof (mcore_le_jtab), 8,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, false, 0
}
,
{
-#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", "",
"elf32-mcore-big", bfd_arch_mcore,
mcore_be_jtab, sizeof (mcore_be_jtab), 8,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, false, 0
}
,
{
-#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",
"elf32-mcore-little", bfd_arch_mcore,
mcore_le_jtab, sizeof (mcore_le_jtab), 8,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, false, 0
}
,
{
-#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",
"pe-arm-wince-little", bfd_arch_arm,
arm_jtab, sizeof (arm_jtab), 8,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, false, 0
}
,
{
-#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_x64_dljtab, sizeof (i386_x64_dljtab), 2, 9, 14, i386_x64_trampoline
+ i386_x64_dljtab, sizeof (i386_x64_dljtab), 2, 9, 14, true, 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 }
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
typedef struct dlist
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;
static void scan_drectve_symbols (bfd *);
static void scan_filtered_symbols (bfd *, void *, long, unsigned int);
static void add_excludes (const char *);
-static bfd_boolean match_exclude (const char *);
+static bool match_exclude (const char *);
static void set_default_excludes (void);
static long filter_symbols (bfd *, void *, long, unsigned int);
static void scan_all_symbols (bfd *);
static void identify_search_archive
(bfd *, void (*) (bfd *, bfd *, void *), void *);
static void identify_search_member (bfd *, bfd *, void *);
-static bfd_boolean identify_process_section_p (asection *, bfd_boolean);
+static bool identify_process_section_p (asection *, bool);
static void identify_search_section (bfd *, asection *, void *);
static void identify_member_contains_symname (bfd *, bfd *, void *);
}
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 *
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:
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:
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:
#define HOW_JTAB_ROFF2 (delay ? mtable[machine].how_dljtab_roff2 : 0)
#define HOW_JTAB_ROFF3 (delay ? mtable[machine].how_dljtab_roff3 : 0)
#define ASM_SWITCHES mtable[machine].how_default_as_switches
+#define HOW_SEH mtable[machine].how_seh
static char **oav;
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";
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);
+
+ free (buf);
}
void
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);
while (p < e)
{
if (p[0] == '-'
- && CONST_STRNEQ (p, "-export:"))
+ && startswith (p, "-export:"))
{
char * name;
char * c;
char *tag_start = ++p;
while (p < e && *p != ' ' && *p != '-')
p++;
- if (CONST_STRNEQ (tag_start, "data"))
+ if (startswith (tag_start, "data"))
flags &= ~BSF_FUNCTION;
}
asymbol *sym;
const char *symbol_name;
- sym = bfd_minisymbol_to_symbol (abfd, FALSE, from, store);
+ sym = bfd_minisymbol_to_symbol (abfd, false, from, store);
if (sym == NULL)
bfd_fatal (bfd_get_filename (abfd));
/* See if STRING is on the list of symbols to exclude. */
-static bfd_boolean
+static bool
match_exclude (const char *string)
{
struct string_list *excl_item;
for (excl_item = excludes; excl_item; excl_item = excl_item->next)
if (strcmp (string, excl_item->string) == 0)
- return TRUE;
- return FALSE;
+ return true;
+ return false;
}
/* Add the default list of symbols to exclude. */
int keep = 0;
asymbol *sym;
- sym = bfd_minisymbol_to_symbol (abfd, FALSE, (const void *) from, store);
+ sym = bfd_minisymbol_to_symbol (abfd, false, (const void *) from, store);
if (sym == NULL)
bfd_fatal (bfd_get_filename (abfd));
return;
}
- symcount = bfd_read_minisymbols (abfd, FALSE, &minisyms, &size);
+ symcount = bfd_read_minisymbols (abfd, false, &minisyms, &size);
if (symcount < 0)
bfd_fatal (bfd_get_filename (abfd));
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)
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"));
}
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 (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;
{
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_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 = bfd_und_section_ptr;
- 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);
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;
+ 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)
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. */
/* 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,"\t%s\t%s\n", ASM_GLOBAL, head_label);
+ if (HOW_SEH)
+ fprintf (f, "\t.seh_proc\t%s\n", head_label);
fprintf (f, "%s:\n", head_label);
fprintf (f, mtable[machine].trampoline, imp_name_lab);
+ if (HOW_SEH)
+ fprintf (f, "\t.seh_endproc\n");
/* Output the delay import descriptor */
fprintf (f, "\n%s DELAY_IMPORT_DESCRIPTOR\n", ASM_C);
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");
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);
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;
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"));
/* 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)
{
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)
search_data->symname,
strlen (search_data->symname)) == 0)
{
- search_data->found = TRUE;
+ search_data->found = true;
break;
}
}
}
/* 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;
/* Initialize identify_data. */
identify_data.list = dll_name_list_create ();
- identify_data.ms_style_implib = FALSE;
+ identify_data.ms_style_implib = false;
/* Initialize search_data. */
search_data.symname = "__NULL_IMPORT_DESCRIPTOR";
- search_data.found = FALSE;
+ 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)
identify_member_contains_symname,
(void *)(& search_data));
if (search_data.found)
- identify_data.ms_style_implib = TRUE;
-
+ 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 bool
+identify_process_section_p (asection * section, bool 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;
+ 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. */
bfd_byte *data = 0;
bfd_size_type datasize;
identify_data_type * identify_data = (identify_data_type *)obj;
- bfd_boolean ms_style = identify_data->ms_style_implib;
+ bool ms_style = identify_data->ms_style_implib;
if ((section->flags & SEC_HAS_CONTENTS) == 0)
return;
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
{
/* 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"));
program_name = av[0];
oav = av;
-#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+#ifdef HAVE_LC_MESSAGES
setlocale (LC_MESSAGES, "");
#endif
-#if defined (HAVE_SETLOCALE)
setlocale (LC_CTYPE, "");
-#endif
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)
switch (c)
{
case OPTION_EXPORT_ALL_SYMS:
- export_all_symbols = TRUE;
+ export_all_symbols = true;
break;
case OPTION_NO_EXPORT_ALL_SYMS:
- export_all_symbols = FALSE;
+ export_all_symbols = false;
break;
case OPTION_EXCLUDE_SYMS:
add_excludes (optarg);
break;
case OPTION_NO_DEFAULT_EXCLUDES:
- do_default_excludes = FALSE;
+ do_default_excludes = false;
break;
case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES:
- use_nul_prefixed_import_tables = TRUE;
+ use_nul_prefixed_import_tables = true;
break;
case OPTION_ADD_STDCALL_UNDERSCORE:
add_stdcall_underscore = 1;
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);
bfd_get_target_info (mtable[machine].how_bfd_target, NULL,
NULL, &u, NULL);
if (u != -1)
- leading_underscore = (u != 0 ? TRUE : FALSE);
+ leading_underscore = u != 0;
}
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);
symbols in the .drectve section. The default excludes are meant
to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
if (! export_all_symbols)
- do_default_excludes = FALSE;
+ do_default_excludes = false;
if (do_default_excludes)
set_default_excludes ();
/* 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.