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]
Other format: [Raw text]

handle location expressions in unwind info


Isn't terribly useful in the interpreted case, as we just
print "exp", but for raw output case you now get to see
all the codes involved.


r~


        * readelf.c (struct Frame_Chunk): Add cfa_exp.
        (frame_display_row): Just print "exp" for cfa or register
        defined by a location expression.
        (display_debug_frames): Handle DW_CFA_def_cfa_expression,
        DW_CFA_expression, DW_CFA_MIPS_advance_loc8.

Index: readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.204
diff -c -p -d -r1.204 readelf.c
*** readelf.c	23 Apr 2003 21:09:03 -0000	1.204
--- readelf.c	4 May 2003 00:17:07 -0000
*************** typedef struct Frame_Chunk
*** 8657,8662 ****
--- 8657,8663 ----
    int cfa_offset;
    int ra;
    unsigned char fde_encoding;
+   unsigned char cfa_exp;
  }
  Frame_Chunk;
  
*************** frame_display_row (fc, need_col_headers,
*** 8723,8729 ****
      }
  
    printf ("%08lx ", fc->pc_begin);
!   sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
    printf ("%-8s ", tmp);
  
    for (r = 0; r < fc->ncols; r++)
--- 8724,8733 ----
      }
  
    printf ("%08lx ", fc->pc_begin);
!   if (fc->cfa_exp)
!     strcpy (tmp, "exp");
!   else
!     sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
    printf ("%-8s ", tmp);
  
    for (r = 0; r < fc->ncols; r++)
*************** frame_display_row (fc, need_col_headers,
*** 8744,8749 ****
--- 8748,8756 ----
  	    case DW_CFA_register:
  	      sprintf (tmp, "r%d", fc->col_offset[r]);
  	      break;
+ 	    case DW_CFA_expression:
+ 	      strcpy (tmp, "exp");
+ 	      break;
  	    default:
  	      strcpy (tmp, "n/a");
  	      break;
*************** display_debug_frames (section, start, fi
*** 9014,9020 ****
  	  while (start < block_end)
  	    {
  	      unsigned op, opa;
! 	      unsigned long reg;
  
  	      op = *start++;
  	      opa = op & 0x3f;
--- 9021,9027 ----
  	  while (start < block_end)
  	    {
  	      unsigned op, opa;
! 	      unsigned long reg, tmp;
  
  	      op = *start++;
  	      opa = op & 0x3f;
*************** display_debug_frames (section, start, fi
*** 9082,9087 ****
--- 9089,9105 ----
  		case DW_CFA_def_cfa_offset:
  		  LEB ();
  		  break;
+ 		case DW_CFA_def_cfa_expression:
+ 		  tmp = LEB ();
+ 		  start += tmp;
+ 		  break;
+ 		case DW_CFA_expression:
+ 		  reg = LEB ();
+ 		  tmp = LEB ();
+ 		  start += tmp;
+ 		  frame_need_space (fc, reg);
+ 		  fc->col_type[reg] = DW_CFA_undefined;
+ 		  break;
  		case DW_CFA_offset_extended_sf:
  		  reg = LEB (); SLEB ();
  		  frame_need_space (fc, reg);
*************** display_debug_frames (section, start, fi
*** 9093,9098 ****
--- 9111,9119 ----
  		case DW_CFA_def_cfa_offset_sf:
  		  SLEB ();
  		  break;
+ 		case DW_CFA_MIPS_advance_loc8:
+ 		  start += 8;
+ 		  break;
  		case DW_CFA_GNU_args_size:
  		  LEB ();
  		  break;
*************** display_debug_frames (section, start, fi
*** 9270,9275 ****
--- 9291,9297 ----
  	    case DW_CFA_def_cfa:
  	      fc->cfa_reg = LEB ();
  	      fc->cfa_offset = LEB ();
+ 	      fc->cfa_exp = 0;
  	      if (! do_debug_frames_interp)
  		printf ("  DW_CFA_def_cfa: r%d ofs %d\n",
  			fc->cfa_reg, fc->cfa_offset);
*************** display_debug_frames (section, start, fi
*** 9277,9282 ****
--- 9299,9305 ----
  
  	    case DW_CFA_def_cfa_register:
  	      fc->cfa_reg = LEB ();
+ 	      fc->cfa_exp = 0;
  	      if (! do_debug_frames_interp)
  		printf ("  DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
  	      break;
*************** display_debug_frames (section, start, fi
*** 9292,9297 ****
--- 9315,9345 ----
  		printf ("  DW_CFA_nop\n");
  	      break;
  
+ 	    case DW_CFA_def_cfa_expression:
+ 	      ul = LEB ();
+ 	      if (! do_debug_frames_interp)
+ 		{
+ 		  printf ("  DW_CFA_def_cfa_expression (");
+ 		  decode_location_expression (start, addr_size, ul);
+ 		  printf (")\n");
+ 		}
+ 	      fc->cfa_exp = 1;
+ 	      start += ul;
+ 	      break;
+ 
+ 	    case DW_CFA_expression:
+ 	      reg = LEB ();
+ 	      ul = LEB ();
+ 	      if (! do_debug_frames_interp)
+ 		{
+ 		  printf ("  DW_CFA_expression: r%ld (", reg);
+ 		  decode_location_expression (start, addr_size, ul);
+ 		  printf (")\n");
+ 		}
+ 	      fc->col_type[reg] = DW_CFA_expression;
+ 	      start += ul;
+ 	      break;
+ 
  	    case DW_CFA_offset_extended_sf:
  	      reg = LEB ();
  	      l = SLEB ();
*************** display_debug_frames (section, start, fi
*** 9306,9311 ****
--- 9354,9360 ----
  	    case DW_CFA_def_cfa_sf:
  	      fc->cfa_reg = LEB ();
  	      fc->cfa_offset = SLEB ();
+ 	      fc->cfa_exp = 0;
  	      if (! do_debug_frames_interp)
  		printf ("  DW_CFA_def_cfa_sf: r%d ofs %d\n",
  			fc->cfa_reg, fc->cfa_offset);
*************** display_debug_frames (section, start, fi
*** 9317,9322 ****
--- 9366,9382 ----
  		printf ("  DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
  	      break;
  
+ 	    case DW_CFA_MIPS_advance_loc8:
+ 	      ofs = byte_get (start, 8); start += 8;
+ 	      if (do_debug_frames_interp)
+ 		frame_display_row (fc, &need_col_headers, &max_regs);
+ 	      else
+ 		printf ("  DW_CFA_MIPS_advance_loc8: %ld to %08lx\n",
+ 			ofs * fc->code_factor,
+ 			fc->pc_begin + ofs * fc->code_factor);
+ 	      fc->pc_begin += ofs * fc->code_factor;
+ 	      break;
+ 
  	    case DW_CFA_GNU_window_save:
  	      if (! do_debug_frames_interp)
  		printf ("  DW_CFA_GNU_window_save\n");
*************** display_debug_frames (section, start, fi
*** 9337,9353 ****
  			reg, l * fc->data_factor);
  	      fc->col_type[reg] = DW_CFA_offset;
  	      fc->col_offset[reg] = l * fc->data_factor;
- 	      break;
- 
- 	    /* FIXME: How do we handle these? */
- 	    case DW_CFA_def_cfa_expression:
- 	      fprintf (stderr, "unsupported DW_CFA_def_cfa_expression\n");
- 	      start = block_end;
- 	      break;
- 
- 	    case DW_CFA_expression:
- 	      fprintf (stderr, "unsupported DW_CFA_expression\n");
- 	      start = block_end;
  	      break;
  
  	    default:
--- 9397,9402 ----


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