This is the mail archive of the gdb-prs@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

pending/1259: [RFA] maint info dwarf2-cfi


>Number:         1259
>Category:       pending
>Synopsis:       [RFA] maint info dwarf2-cfi
>Confidential:   yes
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          change-request
>Submitter-Id:   unknown
>Arrival-Date:   Wed Jun 25 21:48:01 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        
>Organization:
>Environment:
>Description:
 This is a multi-part message in MIME format.
 --------------010504080408010803050903
 Content-Type: text/plain; charset=us-ascii; format=flowed
 Content-Transfer-Encoding: 7bit
 
 Hi,
 once again a patch that adds 'maint info dwarf2-cfi' command.
 I modified it for the mainline and incorporated all the requests that 
 appeared on the list last time I sent it, i.e.
 - the command is 'maint info dwarf2-cfi', not 'maint print dwarf2-cfi'
 - the exported function starts with dwarf2_frame_
 - self-desctiption is more verbose
 
 OK to commit now?
 
 Michal Ludvig
 
 --------------010504080408010803050903
 Content-Type: text/plain;
  name="infocfi-1.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="infocfi-1.diff"
 
 2003-06-05  Michal Ludvig  <mludvig@suse.cz>
 
 	* dwarf2-frame.h (dwarf2_frame_cmd_info_cfi): New prototype.
 	* dwarf2-frame.c (decode_cfa_instruction): New function.
 	(print_cfa_program): Ditto.
 	(dwarf2_frame_cmd_info_cfi): Ditto.
 	* maint.c (maintenance_info_dwarf2_cfi): New function.
 	(_initialize_maint_cmds): Add command info dwarf2-cfi.
 	* doc/gdb.texinfo: Document "maint info dwarf2-cfi" command.
 
 Index: dwarf2-frame.c
 ===================================================================
 RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v
 retrieving revision 1.5
 diff -u -p -r1.5 dwarf2-frame.c
 --- dwarf2-frame.c	4 Jun 2003 21:03:23 -0000	1.5
 +++ dwarf2-frame.c	5 Jun 2003 12:06:45 -0000
 @@ -1302,3 +1302,244 @@ dwarf2_build_frame_info (struct objfile 
  	frame_ptr = decode_frame_entry (&unit, frame_ptr, 0);
      }
  }
 +
 +/* Make strings from CFA instructions.  */
 +
 +static int
 +decode_cfa_instruction (char *buf, unsigned long buf_length,
 +			unsigned char *insn_start, unsigned char *insn_end,
 +			struct dwarf2_cie *cie)
 +{
 +  unsigned char *insn_ptr = insn_start;
 +  unsigned char insn = *insn_ptr++;
 +  int bytes_read;
 +  ULONGEST utmp, reg;
 +  LONGEST offset;
 +  CORE_ADDR pc;
 +
 +  if ((insn & 0xc0) == DW_CFA_advance_loc)
 +    snprintf (buf, buf_length, "DW_CFA_advance_loc(%llu)", 
 +		     (insn & 0x3f) * cie->code_alignment_factor);
 +  else if ((insn & 0xc0) == DW_CFA_offset)
 +    {
 +      reg = insn & 0x3f;
 +      insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
 +      offset = utmp * cie->data_alignment_factor;
 +      snprintf (buf, buf_length, "DW_CFA_offset(%lld, r%llu)",
 +		offset, reg);
 +    }
 +  else if ((insn & 0xc0) == DW_CFA_restore)
 +    {
 +      reg = insn & 0x3f;
 +      snprintf (buf, buf_length, "DW_CFA_restore(r%llu)", reg);
 +    }
 +  else
 +    {
 +      switch (insn)
 +	{
 +	case DW_CFA_set_loc:
 +	  pc = dwarf2_read_address (insn_ptr, insn_end, &bytes_read);
 +	  insn_ptr += bytes_read;
 +	  snprintf (buf, buf_length, "DW_CFA_set_loc(0x%llx)", pc);
 +	  break;
 +
 +	case DW_CFA_advance_loc1:
 +	  utmp = extract_unsigned_integer (insn_ptr, 1);
 +	  pc = utmp * cie->code_alignment_factor;
 +	  insn_ptr++;
 +	  snprintf (buf, buf_length, "DW_CFA_advance_loc1(0x%llx)", pc);
 +	  break;
 +
 +	case DW_CFA_advance_loc2:
 +	  utmp = extract_unsigned_integer (insn_ptr, 2);
 +	  pc = utmp * cie->code_alignment_factor;
 +	  insn_ptr += 2;
 +	  snprintf (buf, buf_length, "DW_CFA_advance_loc2(0x%llx)", pc);
 +	  break;
 +
 +	case DW_CFA_advance_loc4:
 +	  utmp = extract_unsigned_integer (insn_ptr, 4);
 +	  pc = utmp * cie->code_alignment_factor;
 +	  insn_ptr += 4;
 +	  snprintf (buf, buf_length, "DW_CFA_advance_loc4(0x%llx)", pc);
 +	  break;
 +
 +	case DW_CFA_offset_extended:
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
 +	  offset = utmp * cie->data_alignment_factor;
 +	  snprintf (buf, buf_length,
 +		    "DW_CFA_offset_extended(%lld, r%llu)", offset, reg);
 +	  break;
 +
 +	case DW_CFA_restore_extended:
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
 +	  snprintf (buf, buf_length, "DW_CFA_restore_extended(r%llu)",
 +		    reg);
 +	  break;
 +
 +	case DW_CFA_undefined:
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
 +	  snprintf (buf, buf_length, "DW_CFA_undefined(r%llu)", reg);
 +	  break;
 +
 +	case DW_CFA_same_value:
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
 +	  snprintf (buf, buf_length, "DW_CFA_same_value(r%llu)", reg);
 +	  break;
 +
 +	case DW_CFA_register:
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
 +	  snprintf (buf, buf_length, "DW_CFA_register(r%llu, r%llu)",
 +		    reg, utmp);
 +	  break;
 +
 +	case DW_CFA_remember_state:
 +	  snprintf (buf, buf_length, "DW_CFA_remember_state");
 +	  break;
 +
 +	case DW_CFA_restore_state:
 +	  snprintf (buf, buf_length, "DW_CFA_restore_state");
 +	  break;
 +
 +	case DW_CFA_def_cfa:
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
 +	  snprintf (buf, buf_length, "DW_CFA_def_cfa(r%llu, %lld)",
 +		    reg, utmp);
 +	  break;
 +
 +	case DW_CFA_def_cfa_register:
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
 +	  snprintf (buf, buf_length, "DW_CFA_def_cfa_register(r%llu)",
 +		    reg);
 +	  break;
 +
 +	case DW_CFA_def_cfa_offset:
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
 +	  snprintf (buf, buf_length, "DW_CFA_def_cfa_offset(%lld)",
 +		    utmp);
 +	  break;
 +
 +	case DW_CFA_def_cfa_expression:
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
 +	  insn_ptr += utmp;
 +	  snprintf (buf, buf_length, "DW_CFA_def_cfa_expression(%llu)",
 +		    utmp);
 +	  break;
 +
 +	case DW_CFA_expression:
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
 +	  insn_ptr += utmp;
 +	  snprintf (buf, buf_length, "DW_CFA_expression(r%llu, %lld)",
 +		    reg, utmp);
 +	  break;
 +
 +	case DW_CFA_nop:
 +	  snprintf (buf, buf_length, "DW_CFA_nop");
 +	  break;
 +
 +	case DW_CFA_GNU_args_size:
 +	  insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
 +	  snprintf (buf, buf_length, "DW_CFA_GNU_args_size(%llu)",
 +		    utmp);
 +	  break;
 +
 +	default:
 +	  snprintf (buf, buf_length, "DW_CFA_<unknown> (0x%x)", insn);
 +	}
 +    }
 +
 +  return insn_ptr - insn_start;
 +}
 +
 +static void
 +print_cfa_program (unsigned char *insn_start, unsigned char *insn_end,
 +		   struct dwarf2_cie *cie)
 +{
 +  char string[100];
 +  int bytes_used;
 +  
 +  while (insn_start < insn_end)
 +    {
 +      bytes_used = decode_cfa_instruction (string, sizeof (string),
 +					    insn_start, insn_end,
 +					    cie);
 +      insn_start += bytes_used;
 +      printf_filtered ("\t%s\n", string);
 +    }
 +}
 +
 +/* Interactive interface.  */
 +
 +void
 +dwarf2_frame_cmd_info_cfi (CORE_ADDR addr)
 +{
 +  CORE_ADDR low, high;
 +  unsigned long data_length;
 +  struct dwarf2_fde *fde;
 +  char *name;
 +  int i;
 +
 +  printf_filtered ("Searching CFI for address 0x%llx...\n", addr);
 +  
 +  if (find_pc_partial_function (addr, &name, &low, &high))
 +    printf_filtered ("Belongs to function '%s' (0x%llx..0x%llx).\n",
 +		     name, low, high);
 +  
 +  fde = dwarf2_frame_find_fde (&addr);
 +  if (! fde)
 +  {
 +    printf_filtered ("CFI entry not found.\n");
 +    return;
 +  }
 +
 +  /* Print out CIE.  */
 +  data_length = fde->cie->end - fde->cie->initial_instructions;
 +  printf_filtered ("CIE:\n");
 +  printf_filtered ("\toffset = %llx\n"
 +		   "\tcode_align = %llu, data_align = %lld, ra_column = 0x%llx\n"
 +		   "\tdata_length = %lu\n\t",
 +		   fde->cie->cie_pointer,
 +		   fde->cie->code_alignment_factor, 
 +		   fde->cie->data_alignment_factor,
 +		   fde->cie->return_address_register,
 +		   data_length);
 +  
 +  printf_filtered ("raw data:\n\t\t");
 +  for (i = 0; i < data_length; i++)
 +  {
 +    printf_filtered ("0x%02x ", fde->cie->initial_instructions[i] & 0xff);
 +    if ((i + 1) % 8 == 0)
 +      printf_filtered ("\n\t\t");
 +    else if ((i + 1) % 4 == 0)
 +      printf_filtered ("  ");
 +  }
 +  if (i % 8)
 +    printf_filtered ("\n");
 +  print_cfa_program (fde->cie->initial_instructions, fde->cie->end, fde->cie);
 +  
 +  /* Print out FDE.  */
 +  data_length = fde->end - fde->instructions;
 +  printf_filtered ("FDE:\n");
 +  printf_filtered ("\tlocation = 0x%llx..0x%llx (size = %lld)\n"
 +		   "\tdata_length = %lu\n\t",
 +		   fde->initial_location,
 +		   (fde->initial_location + fde->address_range),
 +		   fde->address_range, data_length);
 +
 +  printf_filtered ("raw data:\n\t\t");
 +  for (i = 0; i < data_length; i++)
 +  {
 +    printf_filtered ("0x%02x ", fde->instructions[i] & 0xff);
 +    if ((i + 1) % 8 == 0)
 +      printf_filtered ("\n%s", i + 1 < data_length ? "\t\t" : "");
 +    else if ((i + 1) % 4 == 0)
 +      printf_filtered ("  ");
 +  }
 +  if (i % 8)
 +    printf_filtered ("\n");
 +  print_cfa_program (fde->instructions, fde->end, fde->cie);
 +}
 Index: dwarf2-frame.h
 ===================================================================
 RCS file: /cvs/src/src/gdb/dwarf2-frame.h,v
 retrieving revision 1.1
 diff -u -p -r1.1 dwarf2-frame.h
 --- dwarf2-frame.h	31 May 2003 19:18:05 -0000	1.1
 +++ dwarf2-frame.h	5 Jun 2003 12:06:45 -0000
 @@ -40,4 +40,7 @@ const struct frame_base *dwarf2_frame_ba
  
  void dwarf2_frame_build_info (struct objfile *objfile);
  
 +/* Find and print CFI for a given addr.  */
 +void dwarf2_frame_cmd_info_cfi (CORE_ADDR addr);
 +
  #endif /* dwarf2-frame.h */
 Index: maint.c
 ===================================================================
 RCS file: /cvs/src/src/gdb/maint.c,v
 retrieving revision 1.38
 diff -u -p -r1.38 maint.c
 --- maint.c	7 May 2003 21:42:47 -0000	1.38
 +++ maint.c	5 Jun 2003 12:06:45 -0000
 @@ -35,6 +35,7 @@
  #include "symfile.h"
  #include "objfiles.h"
  #include "value.h"
 +#include "dwarf2-frame.h"
  
  #include "cli/cli-decode.h"
  
 @@ -399,6 +400,18 @@ maintenance_info_sections (char *arg, in
      }
  }
  
 +void
 +maintenance_info_dwarf2_cfi (char *args, int from_tty)
 +{
 +  CORE_ADDR addr;
 +  
 +  if (! args)
 +    error_no_arg ("address");
 +
 +  addr = parse_and_eval_address (args);
 +  dwarf2_frame_cmd_info_cfi (addr);
 +}
 +
  /* ARGSUSED */
  void
  maintenance_print_statistics (char *args, int from_tty)
 @@ -809,6 +822,13 @@ If a SOURCE file is specified, dump only
    add_cmd ("objfiles", class_maintenance, maintenance_print_objfiles,
  	   "Print dump of current object file definitions.",
  	   &maintenanceprintlist);
 +
 +  add_cmd ("dwarf2-cfi", class_maintenance, maintenance_info_dwarf2_cfi,
 +	   "Find and print CFI for a given function.\n"
 +	   "CFI stands for Call Frame Information which is a format\n"
 +	   "of encoding information that could be used for doing\n"
 +	   "a stack backtrace.\n",
 +	   &maintenanceinfolist);
  
    add_cmd ("symtabs", class_maintenance, maintenance_info_symtabs,
  	   "List the full symbol tables for all object files.\n\
 Index: doc/gdb.texinfo
 ===================================================================
 RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
 retrieving revision 1.162
 diff -u -p -r1.162 gdb.texinfo
 --- doc/gdb.texinfo	8 May 2003 21:33:49 -0000	1.162
 +++ doc/gdb.texinfo	5 Jun 2003 12:06:53 -0000
 @@ -19386,6 +19386,46 @@ The program being debugged stopped while
  
  Takes an optional file parameter.
  
 +@kindex maint info dwarf2-cfi
 +@item maint info dwarf2-cfi
 +
 +Print Call Frame Information (CFI) found by @value{GDBN} 
 +for a given address.
 +
 +@smallexample
 +(gdb) @kbd{maintenance info dwarf2-cfi main}
 +Searching CFI for address 0x40038b38...
 +Belongs to function 'main' (0x40038b38..0x40038b82).
 +CIE:
 +        offset = 18
 +        code_align = 1, data_align = -8, ra_column = 0x10
 +        data_length = 11
 +        raw data:
 +                0x0c 0x07 0x08 0x90   0x01 0x00 0x00 0x00 
 +                0x00 0x00 0x00 
 +        DW_CFA_def_cfa(r7, 8)
 +        DW_CFA_offset(-8, r16)
 +        DW_CFA_nop
 +        DW_CFA_nop
 +        DW_CFA_nop
 +        DW_CFA_nop
 +        DW_CFA_nop
 +        DW_CFA_nop
 +FDE:
 +        location = 0x40038b38..0x40038b82 (size = 74)
 +        data_length = 8
 +        raw data:
 +                0x41 0x0e 0x10 0x86   0x02 0x43 0x0d 0x06 
 +        DW_CFA_advance_loc(1)
 +        DW_CFA_def_cfa_offset(16)
 +        DW_CFA_offset(-16, r6)
 +        DW_CFA_advance_loc(3)
 +        DW_CFA_def_cfa_register(r6)
 +(gdb)
 +@end smallexample
 +
 +Takes an address or a function name as an argument.
 +
  @kindex maint print registers
  @kindex maint print raw-registers
  @kindex maint print cooked-registers
 
 --------------010504080408010803050903--
 
 
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:


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