]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gas/dwarf2dbg.c
use XNEW and related macros more
[thirdparty/binutils-gdb.git] / gas / dwarf2dbg.c
index 5cc466237c84af22b3ccedd0f12fbf564e605aec..27b264634bcee2353eb347855c275db562c98da0 100644 (file)
@@ -1,5 +1,5 @@
 /* dwarf2dbg.c - DWARF2 debug support
-   Copyright (C) 1999-2014 Free Software Foundation, Inc.
+   Copyright (C) 1999-2016 Free Software Foundation, Inc.
    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
 
    This file is part of GAS, the GNU Assembler.
@@ -186,9 +186,6 @@ struct line_seg {
 
 /* Collects data for all line table entries during assembly.  */
 static struct line_seg *all_segs;
-/* Hash used to quickly lookup a segment by name, avoiding the need to search
-   through the all_segs list.  */
-static struct hash_control *all_segs_hash;
 static struct line_seg **last_seg_ptr;
 
 struct file_entry {
@@ -248,29 +245,21 @@ generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
 static struct line_subseg *
 get_line_subseg (segT seg, subsegT subseg, bfd_boolean create_p)
 {
-  static segT last_seg;
-  static subsegT last_subseg;
-  static struct line_subseg *last_line_subseg;
-
-  struct line_seg *s;
+  struct line_seg *s = seg_info (seg)->dwarf2_line_seg;
   struct line_subseg **pss, *lss;
 
-  if (seg == last_seg && subseg == last_subseg)
-    return last_line_subseg;
-
-  s = (struct line_seg *) hash_find (all_segs_hash, seg->name);
   if (s == NULL)
     {
       if (!create_p)
        return NULL;
 
-      s = (struct line_seg *) xmalloc (sizeof (*s));
+      s = XNEW (struct line_seg);
       s->next = NULL;
       s->seg = seg;
       s->head = NULL;
       *last_seg_ptr = s;
       last_seg_ptr = &s->next;
-      hash_insert (all_segs_hash, seg->name, s);
+      seg_info (seg)->dwarf2_line_seg = s;
     }
   gas_assert (seg == s->seg);
 
@@ -282,7 +271,7 @@ get_line_subseg (segT seg, subsegT subseg, bfd_boolean create_p)
        break;
     }
 
-  lss = (struct line_subseg *) xmalloc (sizeof (*lss));
+  lss = XNEW (struct line_subseg);
   lss->next = *pss;
   lss->subseg = subseg;
   lss->head = NULL;
@@ -291,10 +280,6 @@ get_line_subseg (segT seg, subsegT subseg, bfd_boolean create_p)
   *pss = lss;
 
  found_subseg:
-  last_seg = seg;
-  last_subseg = subseg;
-  last_line_subseg = lss;
-
   return lss;
 }
 
@@ -306,7 +291,7 @@ dwarf2_gen_line_info_1 (symbolS *label, struct dwarf2_line_info *loc)
   struct line_subseg *lss;
   struct line_entry *e;
 
-  e = (struct line_entry *) xmalloc (sizeof (*e));
+  e = XNEW (struct line_entry);
   e->next = NULL;
   e->label = label;
   e->loc = *loc;
@@ -365,8 +350,7 @@ dwarf2_where (struct dwarf2_line_info *line)
 {
   if (debug_type == DEBUG_DWARF2)
     {
-      char *filename;
-      as_where (&filename, &line->line);
+      const char *filename = as_where (&line->line);
       line->filenum = get_filenum (filename, 0);
       line->column = 0;
       line->flags = DWARF2_FLAG_IS_STMT;
@@ -528,8 +512,7 @@ get_filenum (const char *filename, unsigned int num)
          if (dir >= dirs_allocated)
            {
              dirs_allocated = dir + 32;
-             dirs = (char **)
-                    xrealloc (dirs, (dir + 32) * sizeof (const char *));
+             dirs = XRESIZEVEC (char *, dirs, dirs_allocated);
            }
 
          dirs[dir] = (char *) xmalloc (dir_len + 1);
@@ -559,8 +542,7 @@ get_filenum (const char *filename, unsigned int num)
       unsigned int old = files_allocated;
 
       files_allocated = i + 32;
-      files = (struct file_entry *)
-       xrealloc (files, (i + 32) * sizeof (struct file_entry));
+      files = XRESIZEVEC (struct file_entry, files, files_allocated);
 
       memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry));
     }
@@ -659,13 +641,14 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
        {
          size_t dir_len = strlen (dirs[files[filenum].dir]);
          size_t file_len = strlen (files[filenum].filename);
-         char *cp = (char *) alloca (dir_len + 1 + file_len + 1);
+         char *cp = (char *) xmalloc (dir_len + 1 + file_len + 1);
 
          memcpy (cp, dirs[files[filenum].dir], dir_len);
          INSERT_DIR_SEPARATOR (cp, dir_len);
          memcpy (cp + dir_len + 1, files[filenum].filename, file_len);
          cp[dir_len + file_len + 1] = '\0';
          listing_source_file (cp);
+         free (cp);
        }
       else
        listing_source_file (files[filenum].filename);
@@ -685,8 +668,7 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
       char *p, c;
       offsetT value;
 
-      p = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (& p);
 
       if (strcmp (p, "basic_block") == 0)
        {
@@ -705,7 +687,7 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
        }
       else if (strcmp (p, "is_stmt") == 0)
        {
-         *input_line_pointer = c;
+         (void) restore_line_pointer (c);
          value = get_absolute_expression ();
          if (value == 0)
            current.flags &= ~DWARF2_FLAG_IS_STMT;
@@ -719,7 +701,7 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
        }
       else if (strcmp (p, "isa") == 0)
        {
-         *input_line_pointer = c;
+         (void) restore_line_pointer (c);
          value = get_absolute_expression ();
          if (value >= 0)
            current.isa = value;
@@ -731,7 +713,7 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
        }
       else if (strcmp (p, "discriminator") == 0)
        {
-         *input_line_pointer = c;
+         (void) restore_line_pointer (c);
          value = get_absolute_expression ();
          if (value >= 0)
            current.discriminator = value;
@@ -744,11 +726,11 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
       else
        {
          as_bad (_("unknown .loc sub-directive `%s'"), p);
-         *input_line_pointer = c;
+         (void) restore_line_pointer (c);
          return;
        }
 
-      SKIP_WHITESPACE ();
+      SKIP_WHITESPACE_AFTER_NAME ();
     }
 
   demand_empty_rest_of_line ();
@@ -1311,7 +1293,7 @@ process_entries (segT seg, struct line_entry *e)
         section, as well as our sub-sections, and we have to ensure
         that all of the sub-sections are merged into a proper
         .debug_line section before a debugger sees them.  */
-        
+
       sec_name = bfd_get_section_name (stdoutput, seg);
       if (strcmp (sec_name, ".text") != 0)
        {
@@ -1473,7 +1455,8 @@ out_file_list (void)
 
 /* Switch to SEC and output a header length field.  Return the size of
    offsets used in SEC.  The caller must set EXPR->X_add_symbol value
-   to the end of the section.  */
+   to the end of the section.  EXPR->X_add_number will be set to the
+   negative size of the header.  */
 
 static int
 out_header (asection *sec, expressionS *exp)
@@ -1482,8 +1465,21 @@ out_header (asection *sec, expressionS *exp)
   symbolS *end_sym;
 
   subseg_set (sec, 0);
-  start_sym = symbol_temp_new_now ();
-  end_sym = symbol_temp_make ();
+
+  if (flag_dwarf_sections)
+    {
+      /* If we are going to put the start and end symbols in different
+        sections, then we need real symbols, not just fake, local ones.  */
+      frag_now_fix ();
+      start_sym = symbol_make (".Ldebug_line_start");
+      end_sym = symbol_make (".Ldebug_line_end");
+      symbol_set_value_now (start_sym);
+    }
+  else
+    {
+      start_sym = symbol_temp_new_now ();
+      end_sym = symbol_temp_make ();
+    }
 
   /* Total length of the information.  */
   exp->X_op = O_subtract;
@@ -1640,6 +1636,7 @@ static void
 out_debug_aranges (segT aranges_seg, segT info_seg)
 {
   unsigned int addr_size = sizeof_address;
+  offsetT size;
   struct line_seg *s;
   expressionS exp;
   symbolS *aranges_end;
@@ -1648,21 +1645,27 @@ out_debug_aranges (segT aranges_seg, segT info_seg)
 
   sizeof_offset = out_header (aranges_seg, &exp);
   aranges_end = exp.X_add_symbol;
+  size = -exp.X_add_number;
 
   /* Version.  */
   out_two (DWARF2_ARANGES_VERSION);
+  size += 2;
 
   /* Offset to .debug_info.  */
   TC_DWARF2_EMIT_OFFSET (section_symbol (info_seg), sizeof_offset);
+  size += sizeof_offset;
 
   /* Size of an address (offset portion).  */
   out_byte (addr_size);
+  size++;
 
   /* Size of a segment descriptor.  */
   out_byte (0);
+  size++;
 
   /* Align the header.  */
-  frag_align (ffs (2 * addr_size) - 1, 0, 0);
+  while ((size++ % (2 * addr_size)) > 0)
+    out_byte (0);
 
   for (s = all_segs; s; s = s->next)
     {
@@ -1847,7 +1850,6 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT ranges_seg)
 void
 dwarf2_init (void)
 {
-  all_segs_hash = hash_new ();
   last_seg_ptr = &all_segs;
 }