+ assemble_file (TMP_TAIL_S, TMP_TAIL_O);
+
+ 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 ());
+
+ return abfd;
+}
+
+static void
+gen_lib_file (int delay)
+{
+ int i;
+ export_type *exp;
+ bfd *ar_head;
+ bfd *ar_tail;
+ bfd *outarch;
+ bfd * head = 0;
+
+ unlink (imp_name);
+
+ outarch = bfd_openw (imp_name, HOW_BFD_WRITE_TARGET);
+
+ if (!outarch)
+ /* xgettext:c-format */
+ fatal (_("Can't create .lib file: %s: %s"),
+ imp_name, bfd_get_errmsg ());
+
+ /* xgettext:c-format */
+ inform (_("Creating library file: %s"), imp_name);
+
+ bfd_set_format (outarch, bfd_archive);
+ outarch->has_armap = 1;
+ outarch->is_thin_archive = 0;
+
+ /* Work out a reasonable size of things to put onto one line. */
+ if (delay)
+ {
+ ar_head = make_delay_head ();
+ }
+ else
+ {
+ ar_head = make_head ();
+ }
+ ar_tail = make_tail();
+
+ if (ar_head == NULL || ar_tail == NULL)
+ return;
+
+ for (i = 0; (exp = d_exports_lexically[i]); i++)
+ {
+ bfd *n;
+ /* Don't add PRIVATE entries to import lib. */
+ if (exp->private)
+ continue;
+ n = make_one_lib_file (exp, i, delay);
+ n->archive_next = head;
+ head = n;
+ if (ext_prefix_alias)
+ {
+ export_type alias_exp;
+
+ 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);
+ n->archive_next = head;
+ head = n;
+ }
+ }
+
+ /* Now stick them all into the archive. */
+ ar_head->archive_next = head;
+ ar_tail->archive_next = ar_head;
+ head = ar_tail;
+
+ if (! bfd_set_archive_head (outarch, head))
+ bfd_fatal ("bfd_set_archive_head");
+
+ if (! bfd_close (outarch))
+ bfd_fatal (imp_name);
+
+ while (head != NULL)
+ {
+ bfd *n = head->archive_next;
+ bfd_close (head);
+ head = n;
+ }
+
+ /* Delete all the temp files. */
+ if (dontdeltemps == 0)
+ {
+ unlink (TMP_HEAD_O);
+ unlink (TMP_HEAD_S);
+ unlink (TMP_TAIL_O);
+ unlink (TMP_TAIL_S);
+ }
+
+ if (dontdeltemps < 2)
+ {
+ char *name;
+
+ name = (char *) alloca (strlen (TMP_STUB) + 10);
+ for (i = 0; (exp = d_exports_lexically[i]); i++)
+ {
+ /* Don't delete non-existent stubs for PRIVATE entries. */
+ if (exp->private)
+ continue;
+ sprintf (name, "%s%05d.o", TMP_STUB, i);
+ if (unlink (name) < 0)
+ /* xgettext:c-format */
+ non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
+ if (ext_prefix_alias)
+ {
+ sprintf (name, "%s%05d.o", TMP_STUB, i + PREFIX_ALIAS_BASE);
+ if (unlink (name) < 0)
+ /* xgettext:c-format */
+ non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
+ }
+ }
+ }
+
+ inform (_("Created lib file"));
+}
+
+/* Append a copy of data (cast to char *) to list. */
+
+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. */
+ entry = ((dll_name_list_node_type *)
+ xmalloc (sizeof (dll_name_list_node_type)));
+
+ /* Initialize its values. */
+ entry->dllname = xstrdup ((char *) data);
+ entry->next = NULL;
+
+ /* Add to tail, and move tail. */
+ list->tail->next = entry;
+ list->tail = entry;
+}
+
+/* Count the number of entries in list. */
+
+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;
+
+ p = list->head;
+
+ while (p && p->next)
+ {
+ count++;
+ p = p->next;
+ }
+ return count;
+}
+
+/* Print each entry in list to stdout. */
+
+static void
+dll_name_list_print (dll_name_list_type * list)
+{
+ dll_name_list_node_type * p;
+
+ /* Error checking. */
+ if (! list || ! list->head)
+ return;
+
+ p = list->head;
+
+ while (p && p->next && p->next->dllname && *(p->next->dllname))
+ {
+ printf ("%s\n", p->next->dllname);
+ p = p->next;
+ }
+}
+
+/* Free all entries in list, and list itself. */
+
+static void
+dll_name_list_free (dll_name_list_type * list)
+{
+ if (list)
+ {
+ dll_name_list_free_contents (list->head);
+ list->head = NULL;
+ list->tail = NULL;
+ free (list);
+ }
+}
+
+/* Recursive function to free all nodes entry->next->next...
+ as well as entry itself. */
+
+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;
+ }
+ 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
+ the list. */
+
+static dll_name_list_type *
+dll_name_list_create (void)
+{
+ /* Allocate list. */
+ dll_name_list_type * list = xmalloc (sizeof (dll_name_list_type));
+
+ /* Allocate and initialize sentinel node. */
+ list->head = xmalloc (sizeof (dll_name_list_node_type));
+ list->head->dllname = NULL;
+ list->head->next = NULL;