* readelf.c (struct Frame_Chunk): Add cfa_exp.
authorRichard Henderson <rth@redhat.com>
Sun, 4 May 2003 00:20:43 +0000 (00:20 +0000)
committerRichard Henderson <rth@redhat.com>
Sun, 4 May 2003 00:20:43 +0000 (00:20 +0000)
        (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.

binutils/ChangeLog
binutils/readelf.c

index 807421d..a12edf0 100644 (file)
@@ -1,3 +1,11 @@
+2003-05-03  Richard Henderson  <rth@redhat.com>
+
+       * 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.
+
 2003-04-30  H.J. Lu <hjl@gnu.org>
 
        * objdump.c (only): Change it to char **.
index 790a609..1a50541 100644 (file)
@@ -8657,6 +8657,7 @@ typedef struct Frame_Chunk
   int cfa_offset;
   int ra;
   unsigned char fde_encoding;
+  unsigned char cfa_exp;
 }
 Frame_Chunk;
 
@@ -8723,7 +8724,10 @@ frame_display_row (fc, need_col_headers, max_regs)
     }
 
   printf ("%08lx ", fc->pc_begin);
-  sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
+  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++)
@@ -8744,6 +8748,9 @@ frame_display_row (fc, need_col_headers, max_regs)
            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;
@@ -9014,7 +9021,7 @@ display_debug_frames (section, start, file)
          while (start < block_end)
            {
              unsigned op, opa;
-             unsigned long reg;
+             unsigned long reg, tmp;
 
              op = *start++;
              opa = op & 0x3f;
@@ -9082,6 +9089,17 @@ display_debug_frames (section, start, file)
                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);
@@ -9093,6 +9111,9 @@ display_debug_frames (section, start, file)
                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;
@@ -9270,6 +9291,7 @@ display_debug_frames (section, start, file)
            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);
@@ -9277,6 +9299,7 @@ display_debug_frames (section, start, file)
 
            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;
@@ -9292,6 +9315,31 @@ display_debug_frames (section, start, file)
                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 ();
@@ -9306,6 +9354,7 @@ display_debug_frames (section, start, file)
            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);
@@ -9317,6 +9366,17 @@ display_debug_frames (section, start, file)
                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");
@@ -9339,17 +9399,6 @@ display_debug_frames (section, start, file)
              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:
              fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
              start = block_end;