* config/tc-mips.c (support_64bit_objects): Define for OBJ_ELF only.
[deliverable/binutils-gdb.git] / gas / dwarf2dbg.c
index 2d733d4b65887e049e8c8ec094e65580d405ca4c..55a5205fac0aa21fd6aa130a75689d126844a8bc 100644 (file)
@@ -1,5 +1,5 @@
 /* dwarf2dbg.c - DWARF2 debug support
-   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+   Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
 
    This file is part of GAS, the GNU Assembler.
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
 #else
-#define INT_MAX (int) (((unsigned)(-1)) >> 1)
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifndef INT_MAX
+#define INT_MAX (int) (((unsigned) (-1)) >> 1)
+#endif
 #endif
 
 #ifdef BFD_ASSEMBLER
 /* The maximum address skip amount that can be encoded with a special op.  */
 #define MAX_SPECIAL_ADDR_DELTA         SPECIAL_ADDR(255)
 
-
-struct line_entry
-{
+struct line_entry {
   struct line_entry *next;
   fragS *frag;
   addressT frag_ofs;
   struct dwarf2_line_info loc;
 };
 
-struct line_subseg
-{
+struct line_subseg {
   struct line_subseg *next;
   subsegT subseg;
   struct line_entry *head;
   struct line_entry **ptail;
 };
 
-struct line_seg
-{
+struct line_seg {
   struct line_seg *next;
   segT seg;
   struct line_subseg *head;
@@ -120,8 +121,7 @@ struct line_seg
 /* Collects data for all line table entries during assembly.  */
 static struct line_seg *all_segs;
 
-struct file_entry
-{
+struct file_entry {
   char *filename;
   unsigned int dir;
 };
@@ -131,11 +131,6 @@ static struct file_entry *files;
 static unsigned int files_in_use;
 static unsigned int files_allocated;
 
-/* Correlate file numbers as given by the user in .file/.loc directives
-   with the file numbers used in the output debug info.  */
-static unsigned int *user_filenum;
-static unsigned int user_filenum_allocated;
-
 /* True when we've seen a .loc directive recently.  Used to avoid
    doing work when there's nothing to do.  */
 static boolean loc_directive_seen;
@@ -192,7 +187,7 @@ get_line_subseg (seg, subseg)
   if (seg == last_seg && subseg == last_subseg)
     return last_line_subseg;
 
-  for (s = all_segs; s ; s = s->next)  
+  for (s = all_segs; s; s = s->next)
     if (s->seg == seg)
       goto found_seg;
 
@@ -206,7 +201,7 @@ get_line_subseg (seg, subseg)
   for (pss = &s->head; (ss = *pss) != NULL ; pss = &ss->next)
     {
       if (ss->subseg == subseg)
-        goto found_subseg;
+       goto found_subseg;
       if (ss->subseg > subseg)
        break;
     }
@@ -281,7 +276,7 @@ dwarf2_emit_insn (size)
   if (debug_type != DEBUG_DWARF2 && ! loc_directive_seen)
     return;
   loc_directive_seen = false;
-     
+
   dwarf2_where (&loc);
   dwarf2_gen_line_info (frag_now_fix () - size, &loc);
 }
@@ -305,12 +300,16 @@ get_filenum (filename)
 
   if (i >= files_allocated)
     {
+      unsigned int old = files_allocated;
+
       files_allocated = i + 32;
       files = (struct file_entry *)
-       xrealloc (files, (i + 32) * sizeof(struct file_entry));
+       xrealloc (files, (i + 32) * sizeof (struct file_entry));
+
+      memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry));
     }
 
-  files[i].filename = xstrdup(filename);
+  files[i].filename = xstrdup (filename);
   files[i].dir = 0;
   files_in_use = i + 1;
   last_used = i;
@@ -325,7 +324,7 @@ dwarf2_directive_file (dummy)
      int dummy ATTRIBUTE_UNUSED;
 {
   offsetT num;
-  const char *filename;
+  char *filename;
   int filename_len;
 
   /* Continue to accept a bare string and pass it off.  */
@@ -340,25 +339,33 @@ dwarf2_directive_file (dummy)
   filename = demand_copy_C_string (&filename_len);
   demand_empty_rest_of_line ();
 
-  if (num < 0)
+  if (num < 1)
+    {
+      as_bad (_("file number less than one"));
+      return;
+    }
+
+  if (num < (int) files_in_use && files[num].filename != 0)
     {
-      as_bad (_("File number less than zero"));
+      as_bad (_("file number %ld already allocated"), (long) num);
       return;
     }
 
-  if (num >= (int) user_filenum_allocated)
+  if (num >= (int) files_allocated)
     {
-      unsigned int old = user_filenum_allocated;
+      unsigned int old = files_allocated;
 
-      user_filenum_allocated = num + 16;
-      user_filenum = (unsigned int *)
-       xrealloc (user_filenum, (num + 16) * sizeof (unsigned int));
+      files_allocated = num + 16;
+      files = (struct file_entry *)
+       xrealloc (files, (num + 16) * sizeof (struct file_entry));
 
       /* Zero the new memory.  */
-      memset (user_filenum + old, 0, (num + 16 - old) * sizeof(unsigned int));
+      memset (files + old, 0, (num + 16 - old) * sizeof (struct file_entry));
     }
 
-  user_filenum[num] = get_filenum (filename);
+  files[num].filename = filename;
+  files[num].dir = 0;
+  files_in_use = num + 1;
 }
 
 void
@@ -374,19 +381,18 @@ dwarf2_directive_loc (dummy)
   column = get_absolute_expression ();
   demand_empty_rest_of_line ();
 
-  if (filenum < 0)
+  if (filenum < 1)
     {
-      as_bad (_("File number less than zero"));
+      as_bad (_("file number less than one"));
       return;
     }
-  if (filenum >= (int) user_filenum_allocated
-      || user_filenum[filenum] == 0)
+  if (filenum >= (int) files_in_use || files[filenum].filename == 0)
     {
-      as_bad (_("Unassigned file number %ld"), (long) filenum);
+      as_bad (_("unassigned file number %ld"), (long) filenum);
       return;
     }
 
-  current.filenum = user_filenum[filenum];
+  current.filenum = filenum;
   current.line = line;
   current.column = column;
   current.flags = DWARF2_FLAG_BEGIN_STMT;
@@ -398,7 +404,6 @@ dwarf2_directive_loc (dummy)
     listing_source_line (line);
 #endif
 }
-
 \f
 static struct frag *
 first_frag_for_seg (seg)
@@ -406,7 +411,7 @@ first_frag_for_seg (seg)
 {
   frchainS *f, *first = NULL;
 
-  for (f = frchain_root; f ; f = f->frch_next)
+  for (f = frchain_root; f; f = f->frch_next)
     if (f->frch_seg == seg
        && (! first || first->frch_subseg > f->frch_subseg))
       first = f;
@@ -420,7 +425,7 @@ last_frag_for_seg (seg)
 {
   frchainS *f, *last = NULL;
 
-  for (f = frchain_root; f ; f = f->frch_next)
+  for (f = frchain_root; f; f = f->frch_next)
     if (f->frch_seg == seg
        && (! last || last->frch_subseg < f->frch_subseg))
       last= f;
@@ -516,7 +521,7 @@ get_frag_fix (frag)
   /* If a fragment is the last in the chain, special measures must be
      taken to find its size before relaxation, since it may be pending
      on some subsegment chain.  */
-  for (fr = frchain_root; fr ; fr = fr->frch_next)
+  for (fr = frchain_root; fr; fr = fr->frch_next)
     if (fr->frch_last == frag)
       {
        return ((char *) obstack_next_free (&fr->frch_obstack)
@@ -565,7 +570,7 @@ size_inc_line_addr (line_delta, addr_delta)
   int len = 0;
 
   /* Scale the address delta by the minimum instruction length.  */
-#if DWARF2_LINE_MIN_INSN_LENGTH > 1  
+#if DWARF2_LINE_MIN_INSN_LENGTH > 1
   assert (addr_delta % DWARF2_LINE_MIN_INSN_LENGTH == 0);
   addr_delta /= DWARF2_LINE_MIN_INSN_LENGTH;
 #endif
@@ -631,7 +636,7 @@ emit_inc_line_addr (line_delta, addr_delta, p, len)
   int need_copy = 0;
   char *end = p + len;
 
-#if DWARF2_LINE_MIN_INSN_LENGTH > 1  
+#if DWARF2_LINE_MIN_INSN_LENGTH > 1
   /* Scale the address delta by the minimum instruction length.  */
   assert (addr_delta % DWARF2_LINE_MIN_INSN_LENGTH == 0);
   addr_delta /= DWARF2_LINE_MIN_INSN_LENGTH;
@@ -767,7 +772,7 @@ dwarf2dbg_estimate_size_before_relax (frag)
   offsetT addr_delta;
   int size;
 
-  addr_delta = resolve_symbol_value (frag->fr_symbol, 0);
+  addr_delta = resolve_symbol_value (frag->fr_symbol);
   size = size_inc_line_addr (frag->fr_offset, addr_delta);
 
   frag->fr_subtype = size;
@@ -787,7 +792,7 @@ dwarf2dbg_relax_frag (frag)
 
   old_size = frag->fr_subtype;
   new_size = dwarf2dbg_estimate_size_before_relax (frag);
-  
+
   return new_size - old_size;
 }
 
@@ -801,14 +806,14 @@ dwarf2dbg_convert_frag (frag)
 {
   offsetT addr_diff;
 
-  addr_diff = resolve_symbol_value (frag->fr_symbol, 1);
+  addr_diff = resolve_symbol_value (frag->fr_symbol);
 
   /* fr_var carries the max_chars that we created the fragment with.
      fr_subtype carries the current expected length.  We must, of
      course, have allocated enough memory earlier.  */
   assert (frag->fr_var >= (int) frag->fr_subtype);
 
-  emit_inc_line_addr (frag->fr_offset, addr_diff, 
+  emit_inc_line_addr (frag->fr_offset, addr_diff,
                      frag->fr_literal + frag->fr_fix, frag->fr_subtype);
 
   frag->fr_fix += frag->fr_subtype;
@@ -868,7 +873,11 @@ process_entries (seg, e)
          changed = 1;
        }
 
-      if (line != e->loc.line || changed)
+      /* Don't try to optimize away redundant entries; gdb wants two
+        entries for a function where the code starts on the same line as
+        the {, and there's no way to identify that case here.  Trust gcc
+        to optimize appropriately.  */
+      if (1 /* line != e->loc.line || changed */)
        {
          int line_delta = e->loc.line - line;
          if (frag == NULL)
@@ -904,7 +913,7 @@ process_entries (seg, e)
   if (frag == last_frag)
     out_inc_line_addr (INT_MAX, last_frag_ofs - frag_ofs);
   else
-    relax_inc_line_addr (INT_MAX, seg, last_frag, last_frag_ofs, 
+    relax_inc_line_addr (INT_MAX, seg, last_frag, last_frag_ofs,
                         frag, frag_ofs);
 }
 
@@ -922,6 +931,12 @@ out_file_list ()
 
   for (i = 1; i < files_in_use; ++i)
     {
+      if (files[i].filename == NULL)
+       {
+         as_bad (_("unassigned file number %ld"), (long) i);
+         continue;
+       }
+
       size = strlen (files[i].filename) + 1;
       cp = frag_more (size);
       memcpy (cp, files[i].filename, size);
@@ -993,7 +1008,7 @@ out_debug_line (line_seg)
   set_symbol_value_now (prologue_end);
 
   /* For each section, emit a statement program.  */
-  for (s = all_segs; s ; s = s->next)
+  for (s = all_segs; s; s = s->next)
     process_entries (s->seg, s->head->head);
 
   set_symbol_value_now (line_end);
@@ -1014,15 +1029,15 @@ out_debug_aranges (aranges_seg, info_seg)
 
   size = 4 + 2 + 4 + 1 + 1;
 
-  skip = 2*addr_size - (size & (2*addr_size - 1));
-  if (skip == 2*addr_size)
+  skip = 2 * addr_size - (size & (2 * addr_size - 1));
+  if (skip == 2 * addr_size)
     skip = 0;
   size += skip;
 
-  for (s = all_segs; s ; s = s->next)
-    size += 2*addr_size;
+  for (s = all_segs; s; s = s->next)
+    size += 2 * addr_size;
 
-  size += 2*addr_size;
+  size += 2 * addr_size;
 
   subseg_set (aranges_seg, 0);
 
@@ -1046,9 +1061,9 @@ out_debug_aranges (aranges_seg, info_seg)
 
   /* Align the header.  */
   if (skip)
-    frag_align (ffs (2*addr_size) - 1, 0, 0);
+    frag_align (ffs (2 * addr_size) - 1, 0, 0);
 
-  for (s = all_segs; s ; s = s->next)
+  for (s = all_segs; s; s = s->next)
     {
       fragS *frag;
       symbolS *beg, *end;
@@ -1100,6 +1115,9 @@ out_debug_abbrev (abbrev_seg)
   out_abbrev (DW_AT_producer, DW_FORM_string);
   out_abbrev (DW_AT_language, DW_FORM_data2);
   out_abbrev (0, 0);
+
+  /* Terminate the abbreviations for this compilation unit.  */
+  out_byte (0);
 }
 
 /* Emit a description of this compilation unit for .debug_info.  */
@@ -1120,7 +1138,7 @@ out_debug_info (info_seg, abbrev_seg, line_seg)
 
   subseg_set (info_seg, 0);
 
-  info_start = symbol_new_now();
+  info_start = symbol_new_now ();
   info_end = symbol_make (fake_label_name);
 
   /* Compilation Unit length.  */
@@ -1194,25 +1212,18 @@ dwarf2_finish ()
   struct line_seg *s;
 
   /* If no debug information was recorded, nothing to do.  */
-  if (all_segs == NULL)
+  if (all_segs == NULL && files_in_use <= 1)
     return;
 
   /* Calculate the size of an address for the target machine.  */
-#ifdef BFD_ASSEMBLER
   sizeof_address = bfd_arch_bits_per_address (stdoutput) / 8;
-#else
-  /* FIXME.  */
-  sizeof_address = 4;
-#endif
 
   /* Create and switch to the line number section.  */
   line_seg = subseg_new (".debug_line", 0);
-#ifdef BFD_ASSEMBLER
   bfd_set_section_flags (stdoutput, line_seg, SEC_READONLY);
-#endif
 
   /* For each subsection, chain the debug entries together.  */
-  for (s = all_segs; s ; s = s->next)
+  for (s = all_segs; s; s = s->next)
     {
       struct line_subseg *ss = s->head;
       struct line_entry **ptail = ss->ptail;
@@ -1228,7 +1239,7 @@ dwarf2_finish ()
 
   /* If this is assembler generated line info, we need .debug_info
      and .debug_abbrev sections as well.  */
-  if (debug_type == DEBUG_DWARF2)
+  if (all_segs != NULL && debug_type == DEBUG_DWARF2)
     {
       segT abbrev_seg;
       segT info_seg;
@@ -1238,13 +1249,11 @@ dwarf2_finish ()
       abbrev_seg = subseg_new (".debug_abbrev", 0);
       aranges_seg = subseg_new (".debug_aranges", 0);
 
-#ifdef BFD_ASSEMBLER
       bfd_set_section_flags (stdoutput, info_seg, SEC_READONLY);
       bfd_set_section_flags (stdoutput, abbrev_seg, SEC_READONLY);
       bfd_set_section_flags (stdoutput, aranges_seg, SEC_READONLY);
-#endif
 
-      record_alignment (aranges_seg, ffs (2*sizeof_address) - 1);
+      record_alignment (aranges_seg, ffs (2 * sizeof_address) - 1);
 
       out_debug_aranges (aranges_seg, info_seg);
       out_debug_abbrev (abbrev_seg);
@@ -1291,7 +1300,7 @@ void
 dwarf2_directive_file (dummy)
      int dummy ATTRIBUTE_UNUSED;
 {
-  as_fatal (_("dwarf2 is not supported for this object file format"));
+  s_app_file (0);
 }
 
 void
This page took 0.029331 seconds and 4 git commands to generate.