/* dlltool.c -- tool to generate stuff for PE style DLLs
- Copyright (C) 1995-2015 Free Software Foundation, Inc.
+ Copyright (C) 1995-2016 Free Software Foundation, Inc.
This file is part of GNU Binutils.
{
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;
#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
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[] =
+static const char i386_x64_trampoline[] =
"\tpushq %%rcx\n"
"\tpushq %%rdx\n"
"\tpushq %%r8\n"
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);
+
+ if (buf)
+ 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)
{
{
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"));
}
{
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");
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
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)
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);
{
/* 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);