PR27647 PowerPC extended conditional branch mnemonics
[binutils-gdb.git] / gas / dwarf2dbg.c
index 4e03c637d765978ddf1dbea8238b5d949321bcce..85db0bef230a13125ed75d1567ba706fa1bd3df0 100644 (file)
@@ -1,5 +1,5 @@
 /* dwarf2dbg.c - DWARF2 debug support
-   Copyright (C) 1999-2020 Free Software Foundation, Inc.
+   Copyright (C) 1999-2021 Free Software Foundation, Inc.
    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
 
    This file is part of GAS, the GNU Assembler.
@@ -504,6 +504,21 @@ dwarf2_gen_line_info_1 (symbolS *label, struct dwarf2_line_info *loc)
 {
   struct line_subseg *lss;
   struct line_entry *e;
+  flagword need_flags = SEC_LOAD | SEC_CODE;
+
+  /* PR 26850: Do not record LOCs in non-executable or non-loaded
+     sections.  SEC_ALLOC isn't tested for non-ELF because obj-coff.c
+     obj_coff_section is careless in setting SEC_ALLOC.  */
+  if (IS_ELF)
+    need_flags |= SEC_ALLOC;
+  if ((now_seg->flags & need_flags) != need_flags)
+    {
+      /* FIXME: Add code to suppress multiple warnings ?  */
+      if (debug_type != DEBUG_DWARF2)
+       as_warn ("dwarf line number information for %s ignored",
+                segment_name (now_seg));
+      return;
+    }
 
   e = XNEW (struct line_entry);
   e->next = NULL;
@@ -536,8 +551,13 @@ dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc)
   /* Early out for as-yet incomplete location information.  */
   if (loc->line == 0)
     return;
-  if (loc->filenum == 0 && DWARF2_LINE_VERSION < 5)
-    return;
+  if (loc->filenum == 0)
+    {
+      if (dwarf_level < 5)
+       dwarf_level = 5;
+      if (DWARF2_LINE_VERSION < 5)
+       return;
+    }
 
   /* Don't emit sequences of line symbols for the same line when the
      symbols apply to assembler code.  It is necessary to emit
@@ -749,7 +769,7 @@ allocate_filename_to_slot (const char *  dirname,
     {
       const char * dir = NULL;
 
-      if (dirs)
+      if (dirs != NULL)
        dir = dirs[files[num].dir];
 
       if (with_md5
@@ -767,7 +787,15 @@ allocate_filename_to_slot (const char *  dirname,
          /* If the filenames match, but the directory table entry was
             empty, then fill it with the provided directory name.  */
          if (dir == NULL)
-           dirs[files[num].dir] = xmemdup0 (dirname, strlen (dirname));
+           {
+             if (dirs == NULL)
+               {
+                 dirs_allocated = files[num].dir + 32;
+                 dirs = XCNEWVEC (char *, dirs_allocated);
+               }
+             
+             dirs[files[num].dir] = xmemdup0 (dirname, strlen (dirname));
+           }
            
          return TRUE;
        }
@@ -784,10 +812,18 @@ allocate_filename_to_slot (const char *  dirname,
          file = get_basename (filename);
          if (filename_cmp (file, files[num].filename) == 0)
            {
+             /* The filenames match, but the directory table entry is empty.
+                Fill it with the provided directory name.  */
              if (file > filename)
-               /* The filenames match, but the directory table entry is empty.
-                  Fill it with the provided directory name.  */
-               dirs[files[num].dir] = xmemdup0 (filename, file - filename);
+               {
+                 if (dirs == NULL)
+                   {
+                     dirs_allocated = files[num].dir + 32;
+                     dirs = XCNEWVEC (char *, dirs_allocated);
+                   }
+
+                 dirs[files[num].dir] = xmemdup0 (filename, file - filename);
+               }
              return TRUE;
            }
        }
@@ -1028,11 +1064,16 @@ dwarf2_directive_filename (void)
 
   num = get_absolute_expression ();
 
-  if ((offsetT) num < 1 && DWARF2_LINE_VERSION < 5)
+  if ((offsetT) num < 1)
     {
-      as_bad (_("file number less than one"));
-      ignore_rest_of_line ();
-      return NULL;
+      if (num == 0 && dwarf_level < 5)
+       dwarf_level = 5;
+      if ((offsetT) num < 0 || DWARF2_LINE_VERSION < 5)
+       {
+         as_bad (_("file number less than one"));
+         ignore_rest_of_line ();
+         return NULL;
+       }
     }
 
   /* FIXME: Should we allow ".file <N>\n" as an expression meaning
@@ -1127,14 +1168,16 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
 
   if (filenum < 1)
     {
-      if (filenum != 0 || DWARF2_LINE_VERSION < 5)
+      if (filenum == 0 && dwarf_level < 5)
+       dwarf_level = 5;
+      if (filenum < 0 || DWARF2_LINE_VERSION < 5)
        {
          as_bad (_("file number less than one"));
          return;
        }
     }
 
-  if (filenum >= (int) files_in_use || files[filenum].filename == NULL)
+  if ((valueT) filenum >= files_in_use || files[filenum].filename == NULL)
     {
       as_bad (_("unassigned file number %ld"), (long) filenum);
       return;
@@ -2341,11 +2384,10 @@ out_debug_line (segT line_seg)
 
   /* For each section, emit a statement program.  */
   for (s = all_segs; s; s = s->next)
+    /* Paranoia - this check should have already have
+       been handled in dwarf2_gen_line_info_1().  */
     if (SEG_NORMAL (s->seg))
       process_entries (s->seg, s->head->head);
-    else
-      as_warn ("dwarf line number information for %s ignored",
-              segment_name (s->seg));
 
   if (flag_dwarf_sections)
     /* We have to switch to the special .debug_line_end section
@@ -2740,7 +2782,6 @@ dwarf2_init (void)
     flag_dwarf_cie_version = 1;
 }
 
-
 /* Finish the dwarf2 debug sections.  We emit .debug.line if there
    were any .file/.loc directives, or --gdwarf2 was given, and if the
    file has a non-empty .debug_info section and an empty .debug_line