daily update
[deliverable/binutils-gdb.git] / gas / dwarf2dbg.c
index b27652c9f9df3550a245b815db5000eef9f97f30..0d5c072682c08c07dc3b142d12addfde5c075a15 100644 (file)
@@ -1,5 +1,5 @@
 /* dwarf2dbg.c - DWARF2 debug support
-   Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
 
    This file is part of GAS, the GNU Assembler.
 #endif
 #endif
 
+#include "dwarf2dbg.h"
+
+#ifndef DWARF2_FORMAT
+#define DWARF2_FORMAT() dwarf2_format_32bit
+#endif
+
 #ifdef BFD_ASSEMBLER
 
-#include "dwarf2dbg.h"
 #include "subsegs.h"
 
 #include "elf/dwarf2.h"
@@ -131,9 +136,9 @@ static struct file_entry *files;
 static unsigned int files_in_use;
 static unsigned int files_allocated;
 
-/* True when we've seen a .loc directive recently.  Used to avoid
+/* 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;
+static bfd_boolean loc_directive_seen;
 
 /* Current location as indicated by the most recent .loc directive.  */
 static struct dwarf2_line_info current;
@@ -298,7 +303,7 @@ dwarf2_emit_insn (size)
       /* Unless we generate DWARF2 debugging information for each
         assembler line, we only emit one line symbol for one LOC.  */
       if (debug_type != DEBUG_DWARF2)
-       loc_directive_seen = false;
+       loc_directive_seen = FALSE;
     }
   else if (debug_type != DEBUG_DWARF2)
     return;
@@ -430,7 +435,7 @@ dwarf2_directive_loc (dummy)
   current.column = column;
   current.flags = DWARF2_FLAG_BEGIN_STMT;
 
-  loc_directive_seen = true;
+  loc_directive_seen = TRUE;
 
 #ifndef NO_LISTING
   if (listing)
@@ -591,6 +596,26 @@ out_set_addr (seg, frag, ofs)
   emit_expr (&expr, sizeof_address);
 }
 
+#if DWARF2_LINE_MIN_INSN_LENGTH > 1
+static void scale_addr_delta PARAMS ((addressT *));
+
+static void
+scale_addr_delta (addr_delta)
+     addressT *addr_delta;
+{
+  static int printed_this = 0;
+  if (*addr_delta % DWARF2_LINE_MIN_INSN_LENGTH != 0)
+    {
+      if (!printed_this)
+       as_bad("unaligned opcodes detected in executable segment");
+      printed_this = 1;
+    }
+  *addr_delta /= DWARF2_LINE_MIN_INSN_LENGTH;
+}
+#else
+#define scale_addr_delta(A)
+#endif
+
 /* Encode a pair of line and address skips as efficiently as possible.
    Note that the line skip is signed, whereas the address skip is unsigned.
 
@@ -607,10 +632,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
-  assert (addr_delta % DWARF2_LINE_MIN_INSN_LENGTH == 0);
-  addr_delta /= DWARF2_LINE_MIN_INSN_LENGTH;
-#endif
+  scale_addr_delta (&addr_delta);
 
   /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence.
      We cannot use special opcodes here, since we want the end_sequence
@@ -673,11 +695,9 @@ 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
   /* 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;
-#endif
+  scale_addr_delta (&addr_delta);
+
   /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence.
      We cannot use special opcodes here, since we want the end_sequence
      to emit the matrix entry.  */
@@ -998,6 +1018,8 @@ out_debug_line (line_seg)
   symbolS *prologue_end;
   symbolS *line_end;
   struct line_seg *s;
+  enum dwarf2_format d2f;
+  int sizeof_offset;
 
   subseg_set (line_seg, 0);
 
@@ -1009,8 +1031,31 @@ out_debug_line (line_seg)
   expr.X_op = O_subtract;
   expr.X_add_symbol = line_end;
   expr.X_op_symbol = line_start;
-  expr.X_add_number = -4;
-  emit_expr (&expr, 4);
+
+  d2f = DWARF2_FORMAT ();
+  if (d2f == dwarf2_format_32bit)
+    {
+      expr.X_add_number = -4;
+      emit_expr (&expr, 4);
+      sizeof_offset = 4;
+    }
+  else if (d2f == dwarf2_format_64bit)
+    {
+      expr.X_add_number = -12;
+      out_four (-1);
+      emit_expr (&expr, 8);
+      sizeof_offset = 8;
+    }
+  else if (d2f == dwarf2_format_64bit_irix)
+    {
+      expr.X_add_number = -8;
+      emit_expr (&expr, 8);
+      sizeof_offset = 8;
+    }
+  else
+    {
+      as_fatal (_("internal error: unknown dwarf2 format"));
+    }
 
   /* Version.  */
   out_two (2);
@@ -1020,7 +1065,7 @@ out_debug_line (line_seg)
   expr.X_add_symbol = prologue_end;
   expr.X_op_symbol = line_start;
   expr.X_add_number = - (4 + 2 + 4);
-  emit_expr (&expr, 4);
+  emit_expr (&expr, sizeof_offset);
 
   /* Parameters of the state machine.  */
   out_byte (DWARF2_LINE_MIN_INSN_LENGTH);
@@ -1148,6 +1193,7 @@ out_debug_abbrev (abbrev_seg)
       out_abbrev (DW_AT_low_pc, DW_FORM_addr);
       out_abbrev (DW_AT_high_pc, DW_FORM_addr);
     }
+  out_abbrev (DW_AT_name, DW_FORM_string);
   out_abbrev (DW_AT_comp_dir, DW_FORM_string);
   out_abbrev (DW_AT_producer, DW_FORM_string);
   out_abbrev (DW_AT_language, DW_FORM_data2);
@@ -1172,6 +1218,8 @@ out_debug_info (info_seg, abbrev_seg, line_seg)
   symbolS *info_end;
   char *p;
   int len;
+  enum dwarf2_format d2f;
+  int sizeof_offset;
 
   subseg_set (info_seg, 0);
 
@@ -1182,8 +1230,31 @@ out_debug_info (info_seg, abbrev_seg, line_seg)
   expr.X_op = O_subtract;
   expr.X_add_symbol = info_end;
   expr.X_op_symbol = info_start;
-  expr.X_add_number = -4;
-  emit_expr (&expr, 4);
+
+  d2f = DWARF2_FORMAT ();
+  if (d2f == dwarf2_format_32bit)
+    {
+      expr.X_add_number = -4;
+      emit_expr (&expr, 4);
+      sizeof_offset = 4;
+    }
+  else if (d2f == dwarf2_format_64bit)
+    {
+      expr.X_add_number = -12;
+      out_four (-1);
+      emit_expr (&expr, 8);
+      sizeof_offset = 8;
+    }
+  else if (d2f == dwarf2_format_64bit_irix)
+    {
+      expr.X_add_number = -8;
+      emit_expr (&expr, 8);
+      sizeof_offset = 8;
+    }
+  else
+    {
+      as_fatal (_("internal error: unknown dwarf2 format"));
+    }
 
   /* DWARF version.  */
   out_two (2);
@@ -1192,7 +1263,7 @@ out_debug_info (info_seg, abbrev_seg, line_seg)
   expr.X_op = O_symbol;
   expr.X_add_symbol = section_symbol (abbrev_seg);
   expr.X_add_number = 0;
-  emit_expr (&expr, 4);
+  emit_expr (&expr, sizeof_offset);
 
   /* Target address size.  */
   out_byte (sizeof_address);
@@ -1223,6 +1294,16 @@ out_debug_info (info_seg, abbrev_seg, line_seg)
       emit_expr (&expr, sizeof_address);
     }
 
+  /* DW_AT_name.  We don't have the actual file name that was present
+     on the command line, so assume files[1] is the main input file.
+     We're not supposed to get called unless at least one line number
+     entry was emitted, so this should always be defined.  */
+  if (!files || files_in_use < 1)
+    abort ();
+  len = strlen (files[1].filename) + 1;
+  p = frag_more (len);
+  memcpy (p, files[1].filename, len);
+
   /* DW_AT_comp_dir */
   comp_dir = getpwd ();
   len = strlen (comp_dir) + 1;
@@ -1248,8 +1329,15 @@ dwarf2_finish ()
   segT line_seg;
   struct line_seg *s;
 
-  /* If no debug information was recorded, nothing to do.  */
-  if (all_segs == NULL && files_in_use <= 1)
+  /* We don't need to do anything unless:
+     - Some debug information was recorded via .file/.loc
+     - or, we are generating DWARF2 information ourself (--gdwarf2)
+     - or, there is a user-provided .debug_info section which could
+       reference the file table in the .debug_line section we generate
+       below.  */
+  if (all_segs == NULL
+      && debug_type != DEBUG_DWARF2
+      && bfd_get_section_by_name (stdoutput, ".debug_info") == NULL)
     return;
 
   /* Calculate the size of an address for the target machine.  */
@@ -1333,11 +1421,12 @@ dwarf2_emit_insn (size)
 {
 }
 
-void
+char *
 dwarf2_directive_file (dummy)
      int dummy ATTRIBUTE_UNUSED;
 {
   s_app_file (0);
+  return NULL;
 }
 
 void
This page took 0.034669 seconds and 4 git commands to generate.