This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[patch] readelf.c - dump .eh_frame sections



This dumps the .debug_frame and .eh_frame sections in tables, just
like the documentation's pictures.  OK to apply?

2000-11-27  DJ Delorie  <dj@redhat.com>

	* readelf.c (usage): Add -wf (--debug-dump=frames) option.
	(parse_args): Support -wf option.
	(process_section_headers): Ditto.
	(debug_displays): Ditto.
	(display_debug_frames): New, dump *_frame sections.
	(frame_need_space): Support for above.
	(frame_display_row): Ditto.
	* binutils.texi: Document it.

Index: binutils.texi
===================================================================
RCS file: /cvs/src/src/binutils/binutils.texi,v
retrieving revision 1.28
diff -p -3 -r1.28 binutils.texi
*** binutils.texi	2000/11/06 20:26:50	1.28
--- binutils.texi	2000/11/27 20:39:19
*************** readelf [ -a | --all ] 
*** 2478,2484 ****
          [ -V | --version-info]
          [ -D | --use-dynamic]
          [ -x <number> | --hex-dump=<number>]
!         [ -w[liapr] | --debug-dump[=info,=line,=abbrev,=pubnames,=ranges]]
          [      --histogram]
          [ -v | --version]
          [ -H | --help]
--- 2478,2484 ----
          [ -V | --version-info]
          [ -D | --use-dynamic]
          [ -x <number> | --hex-dump=<number>]
!         [ -w[liaprf] | --debug-dump[=info,=line,=abbrev,=pubnames,=ranges,=frames]]
          [      --histogram]
          [ -v | --version]
          [ -H | --help]
*************** symbols section.
*** 2566,2573 ****
  @itemx --hex-dump=<number>
  Displays the contents of the indicated section as a hexadecimal dump.
  
! @item -w[liapr]
! @itemx --debug-dump[=line,=info,=abbrev,=pubnames,=ranges]
  Displays the contents of the debug sections in the file, if any are
  present.  If one of the optional letters or words follows the switch
  then only data found in those specific sections will be dumped.
--- 2566,2573 ----
  @itemx --hex-dump=<number>
  Displays the contents of the indicated section as a hexadecimal dump.
  
! @item -w[liaprf]
! @itemx --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=frames]
  Displays the contents of the debug sections in the file, if any are
  present.  If one of the optional letters or words follows the switch
  then only data found in those specific sections will be dumped.
Index: readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.74
diff -p -3 -r1.74 readelf.c
*** readelf.c	2000/11/22 23:49:39	1.74
--- readelf.c	2000/11/27 20:39:30
*************** int                     do_debug_abbrevs
*** 113,118 ****
--- 113,119 ----
  int                     do_debug_lines;
  int                     do_debug_pubnames;
  int                     do_debug_aranges;
+ int                     do_debug_frames;
  int                     do_arch;
  int                     do_notes;
  int			is_32bit_elf;
*************** static int                display_debug_
*** 197,202 ****
--- 198,204 ----
  static int                display_debug_lines         PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
  static int                display_debug_abbrev        PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
  static int                display_debug_aranges       PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+ static int                display_debug_frames        PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
  static unsigned char *    process_abbrev_section      PARAMS ((unsigned char *, unsigned char *));
  static unsigned long      read_leb128                 PARAMS ((unsigned char *, int *, int));
  static int                process_extended_line_op    PARAMS ((unsigned char *, int, int));
*************** usage ()
*** 1844,1850 ****
    fprintf (stdout, _("  -D or --use-dynamic       Use the dynamic section info when displaying symbols\n"));
    fprintf (stdout, _("  -x <number> or --hex-dump=<number>\n"));
    fprintf (stdout, _("                            Dump the contents of section <number>\n"));
!   fprintf (stdout, _("  -w[liapr] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges]\n"));
    fprintf (stdout, _("                            Display the contents of DWARF2 debug sections\n"));
  #ifdef SUPPORT_DISASSEMBLY
    fprintf (stdout, _("  -i <number> or --instruction-dump=<number>\n"));
--- 1846,1852 ----
    fprintf (stdout, _("  -D or --use-dynamic       Use the dynamic section info when displaying symbols\n"));
    fprintf (stdout, _("  -x <number> or --hex-dump=<number>\n"));
    fprintf (stdout, _("                            Dump the contents of section <number>\n"));
!   fprintf (stdout, _("  -w[liaprf] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=frames]\n"));
    fprintf (stdout, _("                            Display the contents of DWARF2 debug sections\n"));
  #ifdef SUPPORT_DISASSEMBLY
    fprintf (stdout, _("  -i <number> or --instruction-dump=<number>\n"));
*************** parse_args (argc, argv)
*** 2004,2009 ****
--- 2006,2016 ----
  		  do_debug_aranges = 1;
  		  break;
  
+ 		case 'f':
+ 		case 'F':
+ 		  do_debug_frames = 1;
+ 		  break;
+ 
  		default:
  		  warn (_("Unrecognised debug option '%s'\n"), optarg);
  		  break;
*************** process_section_headers (file)
*** 2732,2738 ****
  			  dynamic_strings, char *, "dynamic strings");
  	}
        else if ((do_debugging || do_debug_info || do_debug_abbrevs
! 		|| do_debug_lines || do_debug_pubnames || do_debug_aranges)
  	       && strncmp (name, ".debug_", 7) == 0)
  	{
  	  name += 7;
--- 2739,2745 ----
  			  dynamic_strings, char *, "dynamic strings");
  	}
        else if ((do_debugging || do_debug_info || do_debug_abbrevs
! 		|| do_debug_lines || do_debug_pubnames || do_debug_aranges || do_debug_frames)
  	       && strncmp (name, ".debug_", 7) == 0)
  	{
  	  name += 7;
*************** process_section_headers (file)
*** 2743,2751 ****
--- 2750,2761 ----
  	      || (do_debug_lines    && (strcmp (name, "line") == 0))
  	      || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
  	      || (do_debug_aranges  && (strcmp (name, "aranges") == 0))
+ 	      || (do_debug_frames   && (strcmp (name, "frame") == 0))
  	      )
  	    request_dump (i, DEBUG_DUMP);
  	}
+       else if (do_debug_frames && strcmp (name, ".eh_frame") == 0)
+ 	request_dump (i, DEBUG_DUMP);
      }
  
    if (! do_sections)
*************** display_debug_aranges (section, start, f
*** 6471,6476 ****
--- 6481,6948 ----
    return 1;
  }
  
+ typedef struct Frame_Chunk
+ {
+   struct Frame_Chunk *next;
+   unsigned char *chunk_start;
+   int ncols;
+   /* DW_CFA_{undefined,same_value,offset,register} */
+   unsigned char *col_type;
+   int *col_offset;
+   char *augmentation;
+   unsigned int code_factor, data_factor;
+   unsigned long pc_begin, pc_range;
+   int cfa_reg, cfa_offset, ra;
+ }
+ Frame_Chunk;
+ 
+ static void
+ frame_need_space (Frame_Chunk *fc, int reg)
+ {
+   int prev = fc->ncols;
+   if (reg < fc->ncols)
+     return;
+   fc->ncols = reg + 1;
+   fc->col_type = (unsigned char *) xrealloc (fc->col_type,
+ 					     fc->ncols * sizeof (unsigned char));
+   fc->col_offset = (int *) xrealloc (fc->col_offset,
+ 				     fc->ncols * sizeof (int));
+ 
+   while (prev < fc->ncols)
+     {
+       fc->col_type[prev] = DW_CFA_undefined;
+       fc->col_offset[prev] = 0;
+       prev++;
+     }
+ }
+ 
+ static void
+ frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
+ {
+   int r;
+   char tmp[100];
+   if (*max_regs < fc->ncols)
+     *max_regs = fc->ncols;
+   if (*need_col_headers)
+     {
+       *need_col_headers = 0;
+       printf ("   LOC   CFA      ");
+       for (r=0; r<*max_regs; r++)
+ 	if (r == fc->ra)
+ 	  printf ("ra   ");
+ 	else
+ 	  printf ("r%-4d", r);
+       printf ("\n");
+     }
+   printf ("%08x ", (unsigned int) fc->pc_begin);
+   sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
+   printf ("%-8s ", tmp);
+   for (r=0; r<fc->ncols; r++)
+     {
+       switch (fc->col_type[r])
+ 	{
+ 	case DW_CFA_undefined:
+ 	  strcpy (tmp, "u");
+ 	  break;
+ 	case DW_CFA_same_value:
+ 	  strcpy (tmp, "u");
+ 	  break;
+ 	case DW_CFA_offset:
+ 	  sprintf (tmp, "c%+d", fc->col_offset[r]);
+ 	  break;
+ 	case DW_CFA_register:
+ 	  sprintf (tmp, "r%d", fc->col_offset[r]);
+ 	  break;
+ 	default:
+ 	  strcpy (tmp, "n/a");
+ 	  break;
+ 	}
+       printf ("%-5s", tmp);
+     }
+   printf ("\n");
+ }
+ 
+ #define GET(N)	byte_get (start, N); start += N
+ #define LEB()	read_leb128 (start, &length_return, 0); start += length_return
+ #define SLEB()	read_leb128 (start, &length_return, 1); start += length_return
+ 
+ static int
+ display_debug_frames (section, start, file)
+      Elf32_Internal_Shdr * section;
+      unsigned char *       start;
+      FILE *                file ATTRIBUTE_UNUSED;
+ {
+   unsigned char * end = start + section->sh_size;
+   unsigned char *section_start = start;
+   Frame_Chunk *chunks = 0;
+   Frame_Chunk *remembered_state = 0, *rs;
+   int is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
+   int length_return;
+   int max_regs = 0;
+ 
+   printf (_("The section %s contains:\n"), SECTION_NAME (section));
+ 
+   while (start < end)
+     {
+       unsigned char *saved_start, *block_end;
+       unsigned long length, cie_id;
+       Frame_Chunk *fc, *cie;
+       int need_col_headers = 1;
+ 
+       saved_start = start;
+       length = byte_get (start, 4); start += 4;
+ 
+       if (length == 0)
+ 	return 1;
+ 
+       block_end = saved_start + length + 4;
+       cie_id = byte_get (start, 4); start += 4;
+ 
+       printf ("\n%08x %08lx %08lx ", saved_start - section_start, length, cie_id);
+ 
+       if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
+ 	{
+ 	  fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
+ 	  memset (fc, 0, sizeof (Frame_Chunk));
+ 
+ 	  fc->next = chunks;
+ 	  chunks = fc;
+ 	  fc->chunk_start = saved_start;
+ 	  fc->ncols = 0;
+ 	  fc->col_type = (unsigned char *) xmalloc (sizeof (unsigned char));
+ 	  fc->col_offset = (int *) xmalloc (sizeof (int));
+ 	  frame_need_space (fc, max_regs-1);
+ 
+ 	  start ++; /* version */
+ 	  fc->augmentation = start;
+ 	  while (*start) start++; start++; /* skip past NUL */
+ 	  if (fc->augmentation[0] == 'z')
+ 	    {
+ 	      int xtra;
+ 	      fc->code_factor = LEB ();
+ 	      fc->data_factor = SLEB ();
+ 	      fc->ra = byte_get (start, 1); start += 1;
+ 	      xtra = LEB ();
+ 	      printf ("skipping %d extra bytes\n", xtra);
+ 	      start += xtra;
+ 	    }
+ 	  else if (strcmp (fc->augmentation, "eh") == 0)
+ 	    {
+ 	      start += 4;
+ 	      fc->code_factor = LEB ();
+ 	      fc->data_factor = SLEB ();
+ 	      fc->ra = byte_get (start, 1); start += 1;
+ 	    }
+ 	  else
+ 	    {
+ 	      fc->code_factor = LEB ();
+ 	      fc->data_factor = SLEB ();
+ 	      fc->ra = byte_get (start, 1); start += 1;
+ 	    }
+ 	  cie = fc;
+ 	  printf ("CIE \"%s\" cf=%d df=%d ra=%d\n",
+ 		  fc->augmentation, fc->code_factor, fc->data_factor, fc->ra);
+ 
+ 	  frame_need_space (fc, fc->ra);
+ 	}
+       else
+ 	{
+ 	  unsigned char *look_for;
+ 	  static Frame_Chunk fde_fc;
+ 	  fc = &fde_fc;
+ 	  memset (fc, 0, sizeof (Frame_Chunk));
+ 
+ 	  look_for = is_eh ? start-4-cie_id : (unsigned char *) cie_id;
+ 
+ 	  fc->pc_begin = byte_get (start, 4); start += 4;
+ 	  fc->pc_range = byte_get (start, 4); start += 4;
+ 
+ 	  for (cie=chunks; cie && (cie->chunk_start != look_for); cie = cie->next);
+ 	  if (!cie)
+ 	    {
+ 	      /* printf ("Invalid CIE pointer %08x in FDE at %08x\n", cie_id, saved_start); */
+ 	      start = block_end;
+ 	      fc->ncols = 0;
+ 	      fc->col_type = (unsigned char *) xmalloc (sizeof (unsigned char));
+ 	      fc->col_offset = (int *) xmalloc (sizeof (int));
+ 	      frame_need_space (fc, max_regs-1);
+ 	      cie = fc;
+ 	      fc->augmentation = "";
+ 	    }
+ 	  else
+ 	    {
+ 	      fc->ncols = cie->ncols;
+ 	      fc->col_type = (unsigned char *) xmalloc (fc->ncols * sizeof (unsigned char));
+ 	      fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
+ 	      memcpy (fc->col_type, cie->col_type, fc->ncols);
+ 	      memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
+ 	      fc->augmentation = cie->augmentation;
+ 	      fc->code_factor = cie->code_factor;
+ 	      fc->data_factor = cie->data_factor;
+ 	      fc->cfa_reg = cie->cfa_reg;
+ 	      fc->cfa_offset = cie->cfa_offset;
+ 	      fc->ra = cie->ra;
+ 	      frame_need_space (fc, max_regs-1);
+ 	    }
+ 
+ 	  if (cie->augmentation[0] == 'z')
+ 	    {
+ 	      unsigned long l = LEB ();
+ 	      start += l;
+ 	    }
+ 
+ 	  printf ("FDE cie=%08x pc=%08lx..%08lx\n",
+ 		  cie->chunk_start-section_start, fc->pc_begin,
+ 		  fc->pc_begin + fc->pc_range);
+ 	}
+ 
+       /* At this point, fc is the current chunk, cie (if any) is set, and we're
+ 	 about to interpret instructions for the chunk.  */
+ 
+       /* This exists for readelf maintainers.  */
+ #define FDEBUG 0
+ 
+       while (start < block_end)
+ 	{
+ 	  unsigned op, opa;
+ 	  unsigned long ul, reg, roffs;
+ 	  long l, ofs;
+ 	  bfd_vma vma;
+ 
+ 	  op = * start ++;
+ 	  opa = op & 0x3f;
+ 	  if (op & 0xc0)
+ 	    op &= 0xc0;
+ 
+ 	  switch (op)
+ 	    {
+ 	    case DW_CFA_advance_loc:
+ 	      frame_display_row (fc, &need_col_headers, &max_regs);
+ #if FDEBUG
+ 	      printf ("  DW_CFA_advance_loc: %08x = %08x + %d*%d\n",
+ 		      fc->pc_begin + opa * fc->code_factor, fc->pc_begin, opa, fc->code_factor);
+ #endif
+ 	      fc->pc_begin += opa * fc->code_factor;
+ 	      break;
+ 
+ 	    case DW_CFA_offset:
+ 	      frame_need_space (fc, opa);
+ 	      roffs = LEB ();
+ #if FDEBUG
+ 	      printf ("  DW_CFA_offset: r%d = cfa[%d*%d]\n", opa, roffs, fc->data_factor);
+ #endif
+ 	      fc->col_type[opa] = DW_CFA_offset;
+ 	      fc->col_offset[opa] = roffs * fc->data_factor;
+ 	      break;
+ 
+ 	    case DW_CFA_restore:
+ 	      frame_need_space (fc, opa);
+ #if FDEBUG
+ 	      printf ("  DW_CFA_restore: r%d\n", opa);
+ #endif
+ 	      fc->col_type[opa] = cie->col_type[opa];
+ 	      fc->col_offset[opa] = cie->col_offset[opa];
+ 	      break;
+ 
+ 	    case DW_CFA_set_loc:
+ 	      frame_display_row (fc, &need_col_headers, &max_regs);
+ 	      vma = byte_get (start, sizeof (vma)); start += sizeof (vma);
+ #if FDEBUG
+ 	      printf ("  DW_CFA_set_loc: %08x\n", vma);
+ #endif
+ 	      fc->pc_begin = vma;
+ 	      break;
+ 
+ 	    case DW_CFA_advance_loc1:
+ 	      frame_display_row (fc, &need_col_headers, &max_regs);
+ 	      ofs = byte_get (start, 1); start += 1;
+ #if FDEBUG
+ 	      printf ("  DW_CFA_advance_loc1: %08x = %08x + %d*%d\n",
+ 		      fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
+ #endif
+ 	      fc->pc_begin += ofs * fc->code_factor;
+ 	      break;
+ 
+ 	    case DW_CFA_advance_loc2:
+ 	      frame_display_row (fc, &need_col_headers, &max_regs);
+ 	      ofs = byte_get (start, 2); start += 2;
+ #if FDEBUG
+ 	      printf ("  DW_CFA_advance_loc2: %08x = %08x + %d*%d\n",
+ 		      fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
+ #endif
+ 	      fc->pc_begin += ofs * fc->code_factor;
+ 	      break;
+ 
+ 	    case DW_CFA_advance_loc4:
+ 	      frame_display_row (fc, &need_col_headers, &max_regs);
+ 	      ofs = byte_get (start, 4); start += 4;
+ #if FDEBUG
+ 	      printf ("  DW_CFA_advance_loc4: %08x = %08x + %d*%d\n",
+ 		      fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
+ #endif
+ 	      fc->pc_begin += ofs * fc->code_factor;
+ 	      break;
+ 
+ 	    case DW_CFA_offset_extended:
+ 	      reg = LEB ();
+ 	      roffs = LEB ();
+ 	      frame_need_space (fc, reg);
+ #if FDEBUG
+ 	      printf ("  DW_CFA_offset_extended: r%d = cfa[%d*%d]\n", reg, roffs, fc->data_factor);
+ #endif
+ 	      fc->col_type[reg] = DW_CFA_offset;
+ 	      fc->col_offset[reg] = roffs * fc->data_factor;
+ 	      break;
+ 
+ 	    case DW_CFA_restore_extended:
+ 	      reg = LEB ();
+ 	      frame_need_space (fc, reg);
+ #if FDEBUG
+ 	      printf ("  DW_CFA_restore_extended: r%d\n", reg);
+ #endif
+ 	      fc->col_type[reg] = cie->col_type[reg];
+ 	      fc->col_offset[reg] = cie->col_offset[reg];
+ 	      break;
+ 
+ 	    case DW_CFA_undefined:
+ 	      reg = LEB ();
+ 	      frame_need_space (fc, reg);
+ #if FDEBUG
+ 	      printf ("  DW_CFA_undefined: r%d\n", reg);
+ #endif
+ 	      fc->col_type[reg] = DW_CFA_undefined;
+ 	      fc->col_offset[reg] = 0;
+ 	      break;
+ 
+ 	    case DW_CFA_same_value:
+ 	      reg = LEB ();
+ 	      frame_need_space (fc, reg);
+ #if FDEBUG
+ 	      printf ("  DW_CFA_same_value: r%d\n", reg);
+ #endif
+ 	      fc->col_type[reg] = DW_CFA_same_value;
+ 	      fc->col_offset[reg] = 0;
+ 	      break;
+ 
+ 	    case DW_CFA_register:
+ 	      reg = LEB ();
+ 	      roffs = LEB ();
+ 	      frame_need_space (fc, reg);
+ #if FDEBUG
+ 	      printf ("  DW_CFA_ame_value: r%d\n", reg);
+ #endif
+ 	      fc->col_type[reg] = DW_CFA_register;
+ 	      fc->col_offset[reg] = roffs;
+ 	      break;
+ 
+ 	    case DW_CFA_remember_state:
+ #if FDEBUG
+ 	      printf ("  DW_CFA_remember_state\n");
+ #endif
+ 	      rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
+ 	      rs->ncols = fc->ncols;
+ 	      rs->col_type = (unsigned char *) xmalloc (rs->ncols);
+ 	      rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
+ 	      memcpy (rs->col_type, fc->col_type, rs->ncols);
+ 	      memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
+ 	      rs->next = remembered_state;
+ 	      remembered_state = rs;
+ 	      break;
+ 
+ 	    case DW_CFA_restore_state:
+ #if FDEBUG
+ 	      printf ("  DW_CFA_restore_state\n");
+ #endif
+ 	      rs = remembered_state;
+ 	      remembered_state = rs->next;
+ 	      frame_need_space (fc, rs->ncols-1);
+ 	      memcpy (fc->col_type, rs->col_type, rs->ncols);
+ 	      memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
+ 	      free (rs->col_type);
+ 	      free (rs->col_offset);
+ 	      free (rs);
+ 	      break;
+ 
+ 	    case DW_CFA_def_cfa:
+ 	      fc->cfa_reg = LEB ();
+ 	      fc->cfa_offset = LEB ();
+ #if FDEBUG
+ 	      printf ("  DW_CFA_def_cfa: reg %d ofs %d\n", fc->cfa_reg, fc->cfa_offset);
+ #endif
+ 	      break;
+ 
+ 	    case DW_CFA_def_cfa_register:
+ 	      fc->cfa_reg = LEB ();
+ #if FDEBUG
+ 	      printf ("  DW_CFA_def_cfa_reg: %d\n", fc->cfa_reg);
+ #endif
+ 	      break;
+ 
+ 	    case DW_CFA_def_cfa_offset:
+ 	      fc->cfa_offset = LEB ();
+ #if FDEBUG
+ 	      printf ("  DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
+ #endif
+ 	      break;
+ 
+ 	    case DW_CFA_nop:
+ #if FDEBUG
+ 	      printf ("  DW_CFA_nop\n");
+ #endif
+ 	      break;
+ 
+ #ifndef DW_CFA_GNU_window_save
+ #define DW_CFA_GNU_window_save 0x2d
+ #endif
+ 	    case DW_CFA_GNU_window_save:
+ #if FDEBUG
+ 	      printf ("  DW_CFA_GNU_window_save\n");
+ #endif
+ 	      break;
+ 
+ #ifndef DW_CFA_GNU_args_size
+ #define DW_CFA_GNU_args_size 0x2e
+ #endif
+ 	    case DW_CFA_GNU_args_size:
+ 	      ul = LEB ();
+ #if FDEBUG
+ 	      printf ("  DW_CFA_GNU_args_size: %d\n", ul);
+ #endif
+ 	      break;
+ 
+ #ifndef DW_CFA_GNU_negative_offset_extended
+ #define DW_CFA_GNU_negative_offset_extended 0x2f
+ #endif
+ 	    case DW_CFA_GNU_negative_offset_extended:
+ 	      reg = LEB ();
+ 	      l = - LEB ();
+ 	      frame_need_space (fc, reg);
+ #if FDEBUG
+ 	      printf ("  DW_CFA_GNU_negative_offset_extended: r%d = cfa[%d*%d]\n", reg, l, fc->data_factor);
+ #endif
+ 	      fc->col_type[reg] = DW_CFA_offset;
+ 	      fc->col_offset[reg] = l * fc->data_factor;
+ 	      break;
+ 
+ 	    default:
+ 	      fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
+ 	      start = block_end;
+ 	    }
+ 	}
+ 
+       frame_display_row (fc, &need_col_headers, &max_regs);
+ 
+       start = block_end;
+     }
+ 
+   printf ("\n");
+ 
+   return 1;
+ }
+ 
+ #undef GET
+ #undef LEB
+ #undef SLEB
  
  static int
  display_debug_not_supported (section, start, file)
*************** debug_displays[] =
*** 6518,6523 ****
--- 6990,6997 ----
    { ".debug_line",        display_debug_lines, NULL },
    { ".debug_aranges",     display_debug_aranges, NULL },
    { ".debug_pubnames",    display_debug_pubnames, NULL },
+   { ".debug_frame",       display_debug_frames, NULL },
+   { ".eh_frame",          display_debug_frames, NULL },
    { ".debug_macinfo",     display_debug_not_supported, NULL },
    { ".debug_frame",       display_debug_not_supported, NULL },
    { ".debug_str",         display_debug_not_supported, NULL },

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]