handle location expressions in unwind info

Richard Henderson rth@twiddle.net
Sun May 4 00:22:00 GMT 2003


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 ----



More information about the Binutils mailing list