|
|
@ -6501,8 +6501,8 @@ typedef struct Frame_Chunk |
|
|
struct Frame_Chunk *next; |
|
|
struct Frame_Chunk *next; |
|
|
unsigned char *chunk_start; |
|
|
unsigned char *chunk_start; |
|
|
int ncols; |
|
|
int ncols; |
|
|
/* DW_CFA_{undefined,same_value,offset,register} */ |
|
|
/* DW_CFA_{undefined,same_value,offset,register,unreferenced} */ |
|
|
unsigned char *col_type; |
|
|
short int *col_type; |
|
|
int *col_offset; |
|
|
int *col_offset; |
|
|
char *augmentation; |
|
|
char *augmentation; |
|
|
unsigned int code_factor; |
|
|
unsigned int code_factor; |
|
|
@ -6515,6 +6515,10 @@ typedef struct Frame_Chunk |
|
|
} |
|
|
} |
|
|
Frame_Chunk; |
|
|
Frame_Chunk; |
|
|
|
|
|
|
|
|
|
|
|
/* A marker for a col_type that means this column was never referenced
|
|
|
|
|
|
in the frame info. */ |
|
|
|
|
|
#define DW_CFA_unreferenced (-1) |
|
|
|
|
|
|
|
|
static void |
|
|
static void |
|
|
frame_need_space (fc, reg) |
|
|
frame_need_space (fc, reg) |
|
|
Frame_Chunk *fc; |
|
|
Frame_Chunk *fc; |
|
|
@ -6525,14 +6529,14 @@ frame_need_space (fc, reg) |
|
|
if (reg < fc->ncols) |
|
|
if (reg < fc->ncols) |
|
|
return; |
|
|
return; |
|
|
fc->ncols = reg + 1; |
|
|
fc->ncols = reg + 1; |
|
|
fc->col_type = (unsigned char *) xrealloc (fc->col_type, |
|
|
fc->col_type = (short int *) xrealloc (fc->col_type, |
|
|
fc->ncols * sizeof (unsigned char)); |
|
|
fc->ncols * sizeof (short int)); |
|
|
fc->col_offset = (int *) xrealloc (fc->col_offset, |
|
|
fc->col_offset = (int *) xrealloc (fc->col_offset, |
|
|
fc->ncols * sizeof (int)); |
|
|
fc->ncols * sizeof (int)); |
|
|
|
|
|
|
|
|
while (prev < fc->ncols) |
|
|
while (prev < fc->ncols) |
|
|
{ |
|
|
{ |
|
|
fc->col_type[prev] = DW_CFA_undefined; |
|
|
fc->col_type[prev] = DW_CFA_unreferenced; |
|
|
fc->col_offset[prev] = 0; |
|
|
fc->col_offset[prev] = 0; |
|
|
prev++; |
|
|
prev++; |
|
|
} |
|
|
} |
|
|
@ -6554,10 +6558,13 @@ frame_display_row (fc, need_col_headers, max_regs) |
|
|
*need_col_headers = 0; |
|
|
*need_col_headers = 0; |
|
|
printf (" LOC CFA "); |
|
|
printf (" LOC CFA "); |
|
|
for (r=0; r<*max_regs; r++) |
|
|
for (r=0; r<*max_regs; r++) |
|
|
if (r == fc->ra) |
|
|
if (fc->col_type[r] != DW_CFA_unreferenced) |
|
|
printf ("ra "); |
|
|
{ |
|
|
else |
|
|
if (r == fc->ra) |
|
|
printf ("r%-4d", r); |
|
|
printf ("ra "); |
|
|
|
|
|
else |
|
|
|
|
|
printf ("r%-4d", r); |
|
|
|
|
|
} |
|
|
printf ("\n"); |
|
|
printf ("\n"); |
|
|
} |
|
|
} |
|
|
printf ("%08x ", (unsigned int) fc->pc_begin); |
|
|
printf ("%08x ", (unsigned int) fc->pc_begin); |
|
|
@ -6565,25 +6572,28 @@ frame_display_row (fc, need_col_headers, max_regs) |
|
|
printf ("%-8s ", tmp); |
|
|
printf ("%-8s ", tmp); |
|
|
for (r=0; r<fc->ncols; r++) |
|
|
for (r=0; r<fc->ncols; r++) |
|
|
{ |
|
|
{ |
|
|
switch (fc->col_type[r]) |
|
|
if (fc->col_type[r] != DW_CFA_unreferenced) |
|
|
{ |
|
|
{ |
|
|
case DW_CFA_undefined: |
|
|
switch (fc->col_type[r]) |
|
|
strcpy (tmp, "u"); |
|
|
{ |
|
|
break; |
|
|
case DW_CFA_undefined: |
|
|
case DW_CFA_same_value: |
|
|
strcpy (tmp, "u"); |
|
|
strcpy (tmp, "s"); |
|
|
break; |
|
|
break; |
|
|
case DW_CFA_same_value: |
|
|
case DW_CFA_offset: |
|
|
strcpy (tmp, "s"); |
|
|
sprintf (tmp, "c%+d", fc->col_offset[r]); |
|
|
break; |
|
|
break; |
|
|
case DW_CFA_offset: |
|
|
case DW_CFA_register: |
|
|
sprintf (tmp, "c%+d", fc->col_offset[r]); |
|
|
sprintf (tmp, "r%d", fc->col_offset[r]); |
|
|
break; |
|
|
break; |
|
|
case DW_CFA_register: |
|
|
default: |
|
|
sprintf (tmp, "r%d", fc->col_offset[r]); |
|
|
strcpy (tmp, "n/a"); |
|
|
break; |
|
|
break; |
|
|
default: |
|
|
|
|
|
strcpy (tmp, "n/a"); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
printf ("%-5s", tmp); |
|
|
} |
|
|
} |
|
|
printf ("%-5s", tmp); |
|
|
|
|
|
} |
|
|
} |
|
|
printf ("\n"); |
|
|
printf ("\n"); |
|
|
} |
|
|
} |
|
|
@ -6635,7 +6645,7 @@ display_debug_frames (section, start, file) |
|
|
chunks = fc; |
|
|
chunks = fc; |
|
|
fc->chunk_start = saved_start; |
|
|
fc->chunk_start = saved_start; |
|
|
fc->ncols = 0; |
|
|
fc->ncols = 0; |
|
|
fc->col_type = (unsigned char *) xmalloc (sizeof (unsigned char)); |
|
|
fc->col_type = (short int *) xmalloc (sizeof (short int)); |
|
|
fc->col_offset = (int *) xmalloc (sizeof (int)); |
|
|
fc->col_offset = (int *) xmalloc (sizeof (int)); |
|
|
frame_need_space (fc, max_regs-1); |
|
|
frame_need_space (fc, max_regs-1); |
|
|
|
|
|
|
|
|
@ -6689,7 +6699,7 @@ display_debug_frames (section, start, file) |
|
|
warn ("Invalid CIE pointer %08x in FDE at %08x\n", cie_id, saved_start); |
|
|
warn ("Invalid CIE pointer %08x in FDE at %08x\n", cie_id, saved_start); |
|
|
start = block_end; |
|
|
start = block_end; |
|
|
fc->ncols = 0; |
|
|
fc->ncols = 0; |
|
|
fc->col_type = (unsigned char *) xmalloc (sizeof (unsigned char)); |
|
|
fc->col_type = (short int *) xmalloc (sizeof (short int)); |
|
|
fc->col_offset = (int *) xmalloc (sizeof (int)); |
|
|
fc->col_offset = (int *) xmalloc (sizeof (int)); |
|
|
frame_need_space (fc, max_regs-1); |
|
|
frame_need_space (fc, max_regs-1); |
|
|
cie = fc; |
|
|
cie = fc; |
|
|
@ -6698,9 +6708,9 @@ display_debug_frames (section, start, file) |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
fc->ncols = cie->ncols; |
|
|
fc->ncols = cie->ncols; |
|
|
fc->col_type = (unsigned char *) xmalloc (fc->ncols * sizeof (unsigned char)); |
|
|
fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int)); |
|
|
fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int)); |
|
|
fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int)); |
|
|
memcpy (fc->col_type, cie->col_type, fc->ncols); |
|
|
memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int)); |
|
|
memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int)); |
|
|
memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int)); |
|
|
fc->augmentation = cie->augmentation; |
|
|
fc->augmentation = cie->augmentation; |
|
|
fc->code_factor = cie->code_factor; |
|
|
fc->code_factor = cie->code_factor; |
|
|
@ -6728,6 +6738,107 @@ display_debug_frames (section, start, file) |
|
|
/* This exists for readelf maintainers. */ |
|
|
/* This exists for readelf maintainers. */ |
|
|
#define FDEBUG 0 |
|
|
#define FDEBUG 0 |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
/* Start by making a pass over the chunk, allocating storage
|
|
|
|
|
|
and taking note of what registers are used. */ |
|
|
|
|
|
|
|
|
|
|
|
unsigned char *tmp = start; |
|
|
|
|
|
while (start < block_end) |
|
|
|
|
|
{ |
|
|
|
|
|
unsigned op, opa; |
|
|
|
|
|
unsigned long reg; |
|
|
|
|
|
bfd_vma vma; |
|
|
|
|
|
|
|
|
|
|
|
op = *start++; |
|
|
|
|
|
opa = op & 0x3f; |
|
|
|
|
|
if (op & 0xc0) |
|
|
|
|
|
op &= 0xc0; |
|
|
|
|
|
|
|
|
|
|
|
/* Warning: if you add any more cases to this switch, be
|
|
|
|
|
|
sure to add them to the corresponding switch below. */ |
|
|
|
|
|
switch (op) |
|
|
|
|
|
{ |
|
|
|
|
|
case DW_CFA_advance_loc: |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_offset: |
|
|
|
|
|
LEB (); |
|
|
|
|
|
frame_need_space (fc, opa); |
|
|
|
|
|
fc->col_type[opa] = DW_CFA_undefined; |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_restore: |
|
|
|
|
|
frame_need_space (fc, opa); |
|
|
|
|
|
fc->col_type[opa] = DW_CFA_undefined; |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_set_loc: |
|
|
|
|
|
start += sizeof (vma); |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_advance_loc1: |
|
|
|
|
|
start += 1; |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_advance_loc2: |
|
|
|
|
|
start += 2; |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_advance_loc4: |
|
|
|
|
|
start += 4; |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_offset_extended: |
|
|
|
|
|
reg = LEB (); LEB (); |
|
|
|
|
|
frame_need_space (fc, reg); |
|
|
|
|
|
fc->col_type[reg] = DW_CFA_undefined; |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_restore_extended: |
|
|
|
|
|
reg = LEB (); |
|
|
|
|
|
frame_need_space (fc, reg); |
|
|
|
|
|
fc->col_type[reg] = DW_CFA_undefined; |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_undefined: |
|
|
|
|
|
reg = LEB (); |
|
|
|
|
|
frame_need_space (fc, reg); |
|
|
|
|
|
fc->col_type[reg] = DW_CFA_undefined; |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_same_value: |
|
|
|
|
|
reg = LEB (); |
|
|
|
|
|
frame_need_space (fc, reg); |
|
|
|
|
|
fc->col_type[reg] = DW_CFA_undefined; |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_register: |
|
|
|
|
|
reg = LEB (); LEB (); |
|
|
|
|
|
frame_need_space (fc, reg); |
|
|
|
|
|
fc->col_type[reg] = DW_CFA_undefined; |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_def_cfa: |
|
|
|
|
|
LEB (); LEB (); |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_def_cfa_register: |
|
|
|
|
|
LEB (); |
|
|
|
|
|
break; |
|
|
|
|
|
case DW_CFA_def_cfa_offset: |
|
|
|
|
|
LEB (); |
|
|
|
|
|
break; |
|
|
|
|
|
#ifndef DW_CFA_GNU_args_size |
|
|
|
|
|
#define DW_CFA_GNU_args_size 0x2e |
|
|
|
|
|
#endif |
|
|
|
|
|
case DW_CFA_GNU_args_size: |
|
|
|
|
|
LEB (); |
|
|
|
|
|
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 (); LEB (); |
|
|
|
|
|
frame_need_space (fc, reg); |
|
|
|
|
|
fc->col_type[reg] = DW_CFA_undefined; |
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
start = tmp; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Now we know what registers are used, make a second pass over
|
|
|
|
|
|
the chunk, this time actually printing out the info. */ |
|
|
|
|
|
|
|
|
while (start < block_end) |
|
|
while (start < block_end) |
|
|
{ |
|
|
{ |
|
|
unsigned op, opa; |
|
|
unsigned op, opa; |
|
|
@ -6740,6 +6851,8 @@ display_debug_frames (section, start, file) |
|
|
if (op & 0xc0) |
|
|
if (op & 0xc0) |
|
|
op &= 0xc0; |
|
|
op &= 0xc0; |
|
|
|
|
|
|
|
|
|
|
|
/* Warning: if you add any more cases to this switch, be
|
|
|
|
|
|
sure to add them to the corresponding switch above. */ |
|
|
switch (op) |
|
|
switch (op) |
|
|
{ |
|
|
{ |
|
|
case DW_CFA_advance_loc: |
|
|
case DW_CFA_advance_loc: |
|
|
@ -6752,7 +6865,6 @@ display_debug_frames (section, start, file) |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case DW_CFA_offset: |
|
|
case DW_CFA_offset: |
|
|
frame_need_space (fc, opa); |
|
|
|
|
|
roffs = LEB (); |
|
|
roffs = LEB (); |
|
|
#if FDEBUG |
|
|
#if FDEBUG |
|
|
printf (" DW_CFA_offset: r%d = cfa[%d*%d]\n", opa, roffs, fc->data_factor); |
|
|
printf (" DW_CFA_offset: r%d = cfa[%d*%d]\n", opa, roffs, fc->data_factor); |
|
|
@ -6762,7 +6874,6 @@ display_debug_frames (section, start, file) |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case DW_CFA_restore: |
|
|
case DW_CFA_restore: |
|
|
frame_need_space (fc, opa); |
|
|
|
|
|
#if FDEBUG |
|
|
#if FDEBUG |
|
|
printf (" DW_CFA_restore: r%d\n", opa); |
|
|
printf (" DW_CFA_restore: r%d\n", opa); |
|
|
#endif |
|
|
#endif |
|
|
@ -6812,7 +6923,6 @@ display_debug_frames (section, start, file) |
|
|
case DW_CFA_offset_extended: |
|
|
case DW_CFA_offset_extended: |
|
|
reg = LEB (); |
|
|
reg = LEB (); |
|
|
roffs = LEB (); |
|
|
roffs = LEB (); |
|
|
frame_need_space (fc, reg); |
|
|
|
|
|
#if FDEBUG |
|
|
#if FDEBUG |
|
|
printf (" DW_CFA_offset_extended: r%d = cfa[%d*%d]\n", reg, roffs, fc->data_factor); |
|
|
printf (" DW_CFA_offset_extended: r%d = cfa[%d*%d]\n", reg, roffs, fc->data_factor); |
|
|
#endif |
|
|
#endif |
|
|
@ -6822,7 +6932,6 @@ display_debug_frames (section, start, file) |
|
|
|
|
|
|
|
|
case DW_CFA_restore_extended: |
|
|
case DW_CFA_restore_extended: |
|
|
reg = LEB (); |
|
|
reg = LEB (); |
|
|
frame_need_space (fc, reg); |
|
|
|
|
|
#if FDEBUG |
|
|
#if FDEBUG |
|
|
printf (" DW_CFA_restore_extended: r%d\n", reg); |
|
|
printf (" DW_CFA_restore_extended: r%d\n", reg); |
|
|
#endif |
|
|
#endif |
|
|
@ -6832,7 +6941,6 @@ display_debug_frames (section, start, file) |
|
|
|
|
|
|
|
|
case DW_CFA_undefined: |
|
|
case DW_CFA_undefined: |
|
|
reg = LEB (); |
|
|
reg = LEB (); |
|
|
frame_need_space (fc, reg); |
|
|
|
|
|
#if FDEBUG |
|
|
#if FDEBUG |
|
|
printf (" DW_CFA_undefined: r%d\n", reg); |
|
|
printf (" DW_CFA_undefined: r%d\n", reg); |
|
|
#endif |
|
|
#endif |
|
|
@ -6842,7 +6950,6 @@ display_debug_frames (section, start, file) |
|
|
|
|
|
|
|
|
case DW_CFA_same_value: |
|
|
case DW_CFA_same_value: |
|
|
reg = LEB (); |
|
|
reg = LEB (); |
|
|
frame_need_space (fc, reg); |
|
|
|
|
|
#if FDEBUG |
|
|
#if FDEBUG |
|
|
printf (" DW_CFA_same_value: r%d\n", reg); |
|
|
printf (" DW_CFA_same_value: r%d\n", reg); |
|
|
#endif |
|
|
#endif |
|
|
@ -6853,9 +6960,8 @@ display_debug_frames (section, start, file) |
|
|
case DW_CFA_register: |
|
|
case DW_CFA_register: |
|
|
reg = LEB (); |
|
|
reg = LEB (); |
|
|
roffs = LEB (); |
|
|
roffs = LEB (); |
|
|
frame_need_space (fc, reg); |
|
|
|
|
|
#if FDEBUG |
|
|
#if FDEBUG |
|
|
printf (" DW_CFA_ame_value: r%d\n", reg); |
|
|
printf (" DW_CFA_register: r%d\n", reg); |
|
|
#endif |
|
|
#endif |
|
|
fc->col_type[reg] = DW_CFA_register; |
|
|
fc->col_type[reg] = DW_CFA_register; |
|
|
fc->col_offset[reg] = roffs; |
|
|
fc->col_offset[reg] = roffs; |
|
|
@ -6867,7 +6973,7 @@ display_debug_frames (section, start, file) |
|
|
#endif |
|
|
#endif |
|
|
rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk)); |
|
|
rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk)); |
|
|
rs->ncols = fc->ncols; |
|
|
rs->ncols = fc->ncols; |
|
|
rs->col_type = (unsigned char *) xmalloc (rs->ncols); |
|
|
rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int)); |
|
|
rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int)); |
|
|
rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int)); |
|
|
memcpy (rs->col_type, fc->col_type, rs->ncols); |
|
|
memcpy (rs->col_type, fc->col_type, rs->ncols); |
|
|
memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int)); |
|
|
memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int)); |
|
|
|