static struct file_entry *files;
 static unsigned int files_in_use;
 static unsigned int files_allocated;
-static unsigned int num_of_auto_assigned;
 
 /* Table of directories used by .debug_line.  */
 static char **       dirs = NULL;
 {
   1, 1, 0, 0,
   DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0,
-  0, NULL
+  0, { NULL }
 };
 
 /* This symbol is used to recognize view number forced resets in loc
   /* First, compute !(E->label > P->label), to tell whether or not
      we're to reset the view number.  If we can't resolve it to a
      constant, keep it symbolic.  */
-  if (!p || (e->loc.view == force_reset_view && force_reset_view))
+  if (!p || (e->loc.u.view == force_reset_view && force_reset_view))
     {
       viewx.X_op = O_constant;
       viewx.X_add_number = 0;
        }
     }
 
-  if (S_IS_DEFINED (e->loc.view) && symbol_constant_p (e->loc.view))
+  if (S_IS_DEFINED (e->loc.u.view) && symbol_constant_p (e->loc.u.view))
     {
-      expressionS *value = symbol_get_value_expression (e->loc.view);
+      expressionS *value = symbol_get_value_expression (e->loc.u.view);
       /* We can't compare the view numbers at this point, because in
         VIEWX we've only determined whether we're to reset it so
         far.  */
     {
       expressionS incv;
 
-      if (!p->loc.view)
+      if (!p->loc.u.view)
        {
-         p->loc.view = symbol_temp_make ();
-         gas_assert (!S_IS_DEFINED (p->loc.view));
+         p->loc.u.view = symbol_temp_make ();
+         gas_assert (!S_IS_DEFINED (p->loc.u.view));
        }
 
       memset (&incv, 0, sizeof (incv));
       incv.X_unsigned = 1;
       incv.X_op = O_symbol;
-      incv.X_add_symbol = p->loc.view;
+      incv.X_add_symbol = p->loc.u.view;
       incv.X_add_number = 1;
 
       if (viewx.X_op == O_constant)
        }
     }
 
-  if (!S_IS_DEFINED (e->loc.view))
+  if (!S_IS_DEFINED (e->loc.u.view))
     {
-      symbol_set_value_expression (e->loc.view, &viewx);
-      S_SET_SEGMENT (e->loc.view, expr_section);
-      symbol_set_frag (e->loc.view, &zero_address_frag);
+      symbol_set_value_expression (e->loc.u.view, &viewx);
+      S_SET_SEGMENT (e->loc.u.view, expr_section);
+      symbol_set_frag (e->loc.u.view, &zero_address_frag);
     }
 
   /* Define and attempt to simplify any earlier views needed to
      compute E's.  */
-  if (h && p && p->loc.view && !S_IS_DEFINED (p->loc.view))
+  if (h && p && p->loc.u.view && !S_IS_DEFINED (p->loc.u.view))
     {
       struct line_entry *h2;
       /* Reverse the list to avoid quadratic behavior going backwards
            break;
          set_or_check_view (r, r->next, NULL);
        }
-      while (r->next && r->next->loc.view && !S_IS_DEFINED (r->next->loc.view)
+      while (r->next
+            && r->next->loc.u.view
+            && !S_IS_DEFINED (r->next->loc.u.view)
             && (r = r->next));
 
       /* Unreverse the list, so that we can go forward again.  */
             view of the previous subsegment.  */
          if (r == h)
            continue;
-         gas_assert (S_IS_DEFINED (r->loc.view));
-         resolve_expression (symbol_get_value_expression (r->loc.view));
+         gas_assert (S_IS_DEFINED (r->loc.u.view));
+         resolve_expression (symbol_get_value_expression (r->loc.u.view));
        }
       while (r != p && (r = r->next));
 
       /* Now that we've defined and computed all earlier views that might
         be needed to compute E's, attempt to simplify it.  */
-      resolve_expression (symbol_get_value_expression (e->loc.view));
+      resolve_expression (symbol_get_value_expression (e->loc.u.view));
     }
 }
 
 
   /* Subseg heads are chained to previous subsegs in
      dwarf2_finish.  */
-  if (loc->view && lss->head)
-    set_or_check_view (e,
-                      (struct line_entry *)lss->ptail,
-                      lss->head);
+  if (loc->filenum != -1u && loc->u.view && lss->head)
+    set_or_check_view (e, (struct line_entry *) lss->ptail, lss->head);
 
   *lss->ptail = e;
   lss->ptail = &e->next;
 void
 dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc)
 {
-  static unsigned int line = -1;
-  static unsigned int filenum = -1;
-
   symbolS *sym;
 
   /* Early out for as-yet incomplete location information.  */
      symbols apply to assembler code.  It is necessary to emit
      duplicate line symbols when a compiler asks for them, because GDB
      uses them to determine the end of the prologue.  */
-  if (debug_type == DEBUG_DWARF2
-      && line == loc->line && filenum == loc->filenum)
-    return;
+  if (debug_type == DEBUG_DWARF2)
+    {
+      static unsigned int line = -1;
+      static const char *filename = NULL;
+
+      if (line == loc->line)
+       {
+         if (filename == loc->u.filename)
+           return;
+         if (filename_cmp (filename, loc->u.filename) == 0)
+           {
+             filename = loc->u.filename;
+             return;
+           }
+       }
 
-  line = loc->line;
-  filenum = loc->filenum;
+      line = loc->line;
+      filename = loc->u.filename;
+    }
 
   if (linkrelax)
     {
-      char name[120];
+      static int label_num = 0;
+      char name[32];
 
       /* Use a non-fake name for the line number location,
         so that it can be referred to by relocations.  */
-      sprintf (name, ".Loc.%u.%u", line, filenum);
+      sprintf (name, ".Loc.%u", label_num);
+      label_num++;
       sym = symbol_new (name, now_seg, frag_now, ofs);
     }
   else
        {
          const char * pwd = file0_dirname ? file0_dirname : getpwd ();
 
-         if (dwarf_level >= 5 && strcmp (dirname, pwd) != 0)
+         if (dwarf_level >= 5 && filename_cmp (dirname, pwd) != 0)
            {
-             /* In DWARF-5 the 0 entry in the directory table is expected to be
-                the same as the DW_AT_comp_dir (which is set to the current build
-                directory).  Since we are about to create a directory entry that
-                is not the same, allocate the current directory first.
-                FIXME: Alternatively we could generate an error message here.  */
+             /* In DWARF-5 the 0 entry in the directory table is
+                expected to be the same as the DW_AT_comp_dir (which
+                is set to the current build directory).  Since we are
+                about to create a directory entry that is not the
+                same, allocate the current directory first.
+                FIXME: Alternatively we could generate an error
+                message here.  */
              (void) get_directory_table_entry (pwd, NULL, strlen (pwd),
                                                true);
              d = 1;
   if (!assign_file_to_slot (i, file, dir))
     return -1;
 
-  num_of_auto_assigned++;
-
   last_used = i;
   last_used_dir_len = dir_len;
 
   return i;
 }
 
+/* Run through the list of line entries starting at E, allocating
+   file entries for gas generated debug.  */
+
+static void
+do_allocate_filenum (struct line_entry *e)
+{
+  do
+    {
+      if (e->loc.filenum == -1u)
+       {
+         e->loc.filenum = allocate_filenum (e->loc.u.filename);
+         e->loc.u.view = NULL;
+       }
+      e = e->next;
+    }
+  while (e);
+}
+
 /* Allocate slot NUM in the .debug_line file table to FILENAME.
    If DIRNAME is not NULL or there is a directory component to FILENAME
    then this will be stored in the directory table, if not already present.
 {
   if (debug_type == DEBUG_DWARF2)
     {
-      const char *filename;
-
-      memset (line, 0, sizeof (*line));
-      filename = as_where (&line->line);
-      line->filenum = allocate_filenum (filename);
-      /* FIXME: We should check the return value from allocate_filenum.  */
+      line->u.filename = as_where (&line->line);
+      line->filenum = -1u;
       line->column = 0;
       line->flags = DWARF2_FLAG_IS_STMT;
       line->isa = current.isa;
       line->discriminator = current.discriminator;
-      line->view = NULL;
     }
   else
     *line = current;
                     | DWARF2_FLAG_PROLOGUE_END
                     | DWARF2_FLAG_EPILOGUE_BEGIN);
   current.discriminator = 0;
-  current.view = NULL;
+  current.u.view = NULL;
 }
 
 /* Called for each (preferably code) label.  If dwarf2_loc_mark_labels
   char *filename;
   const char * dirname = NULL;
   int filename_len;
-  unsigned int i;
 
   /* Continue to accept a bare string and pass it off.  */
   SKIP_WHITESPACE ();
       return NULL;
     }
 
-  if (num_of_auto_assigned)
-    {
-      /* Clear slots auto-assigned before the first .file <NUMBER>
-        directive was seen.  */
-      if (files_in_use != (num_of_auto_assigned + 1))
-       abort ();
-      for (i = 1; i < files_in_use; i++)
-       files[i].filename = NULL;
-      files_in_use = 0;
-      num_of_auto_assigned = 0;
-    }
-
   if (! allocate_filename_to_slot (dirname, filename, (unsigned int) num,
                                   with_md5))
     return NULL;
       return;
     }
 
+  /* debug_type will be turned off by dwarf2_directive_filename, and
+     if we don't have a dwarf style .file then files_in_use will be
+     zero and the above error will trigger.  */
+  gas_assert (debug_type == DEBUG_NONE);
+
   current.filenum = filenum;
   current.line = line;
   current.discriminator = 0;
              S_SET_VALUE (sym, 0);
              symbol_set_frag (sym, &zero_address_frag);
            }
-         current.view = sym;
+         current.u.view = sym;
        }
       else
        {
 
   demand_empty_rest_of_line ();
   dwarf2_any_loc_directive_seen = dwarf2_loc_directive_seen = true;
-  debug_type = DEBUG_NONE;
 
   /* If we were given a view id, emit the row right away.  */
-  if (current.view)
+  if (current.u.view)
     dwarf2_emit_insn (0);
 }
 
       frag_ofs = S_GET_VALUE (lab);
 
       if (last_frag == NULL
-         || (e->loc.view == force_reset_view && force_reset_view
+         || (e->loc.u.view == force_reset_view && force_reset_view
              /* If we're going to reset the view, but we know we're
                 advancing the PC, we don't have to force with
                 set_address.  We know we do when we're at the same
       struct line_subseg *lss = s->head;
       struct line_entry **ptail = lss->ptail;
 
+      if (lss->head && SEG_NORMAL (s->seg))
+       do_allocate_filenum (lss->head);
+
       /* Reset the initial view of the first subsection of the
         section.  */
-      if (lss->head && lss->head->loc.view)
+      if (lss->head && lss->head->loc.u.view)
        set_or_check_view (lss->head, NULL, NULL);
 
       while ((lss = lss->next) != NULL)
        {
          /* Link the first view of subsequent subsections to the
             previous view.  */
-         if (lss->head && lss->head->loc.view)
+         if (lss->head && lss->head->loc.u.view)
            set_or_check_view (lss->head,
                               !s->head ? NULL : (struct line_entry *)ptail,
                               s->head ? s->head->head : NULL);