2009-03-19 H.J. Lu <hongjiu.lu@intel.com>

* dwarf.c (dwarf_regnames): Moved before frame_need_space.
	(dwarf_regnames_count): Likewise.
	(frame_need_space): Return int.
	(display_debug_frames): Check invalid registers.
This commit is contained in:
H.J. Lu 2009-03-20 00:05:37 +00:00
parent e00e5ec5a1
commit 665ce1f675
2 changed files with 177 additions and 90 deletions

View File

@ -1,3 +1,10 @@
2009-03-19 H.J. Lu <hongjiu.lu@intel.com>
* dwarf.c (dwarf_regnames): Moved before frame_need_space.
(dwarf_regnames_count): Likewise.
(frame_need_space): Return int.
(display_debug_frames): Check invalid registers.
2009-03-19 H.J. Lu <hongjiu.lu@intel.com>
* readelf.c (debug_apply_relocations): Check relocations

View File

@ -3621,17 +3621,27 @@ typedef struct Frame_Chunk
}
Frame_Chunk;
static const char *const *dwarf_regnames;
static unsigned int dwarf_regnames_count;
/* A marker for a col_type that means this column was never referenced
in the frame info. */
#define DW_CFA_unreferenced (-1)
static void
frame_need_space (Frame_Chunk *fc, int reg)
/* Return 0 if not more space is needed, 1 if more space is needed,
-1 for invalid reg. */
static int
frame_need_space (Frame_Chunk *fc, unsigned int reg)
{
int prev = fc->ncols;
if (reg < fc->ncols)
return;
if (reg < (unsigned int) fc->ncols)
return 0;
if (dwarf_regnames_count
&& reg > dwarf_regnames_count)
return -1;
fc->ncols = reg + 1;
fc->col_type = xcrealloc (fc->col_type, fc->ncols, sizeof (short int));
@ -3643,6 +3653,7 @@ frame_need_space (Frame_Chunk *fc, int reg)
fc->col_offset[prev] = 0;
prev++;
}
return 1;
}
static const char *const dwarf_regnames_i386[] =
@ -3684,9 +3695,6 @@ static const char *const dwarf_regnames_x86_64[] =
"mxcsr", "fcw", "fsw"
};
static const char *const *dwarf_regnames;
static unsigned int dwarf_regnames_count;
void
init_dwarf_regnames (unsigned int e_machine)
{
@ -3816,6 +3824,7 @@ display_debug_frames (struct dwarf_section *section,
int is_eh = strcmp (section->name, ".eh_frame") == 0;
unsigned int length_return;
int max_regs = 0;
const char *bad_reg = _("bad register: ");
printf (_("Contents of the %s section:\n"), section->name);
@ -4089,12 +4098,12 @@ display_debug_frames (struct dwarf_section *section,
break;
case DW_CFA_offset:
LEB ();
frame_need_space (fc, opa);
fc->col_type[opa] = DW_CFA_undefined;
if (frame_need_space (fc, opa) >= 0)
fc->col_type[opa] = DW_CFA_undefined;
break;
case DW_CFA_restore:
frame_need_space (fc, opa);
fc->col_type[opa] = DW_CFA_undefined;
if (frame_need_space (fc, opa) >= 0)
fc->col_type[opa] = DW_CFA_undefined;
break;
case DW_CFA_set_loc:
start += encoded_ptr_size;
@ -4111,28 +4120,29 @@ display_debug_frames (struct dwarf_section *section,
case DW_CFA_offset_extended:
case DW_CFA_val_offset:
reg = LEB (); LEB ();
frame_need_space (fc, reg);
fc->col_type[reg] = DW_CFA_undefined;
if (frame_need_space (fc, reg) >= 0)
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;
if (frame_need_space (fc, reg) >= 0)
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;
if (frame_need_space (fc, reg) >= 0)
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;
if (frame_need_space (fc, reg) >= 0)
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;
if (frame_need_space (fc, reg) >= 0)
fc->col_type[reg] = DW_CFA_undefined;
break;
case DW_CFA_def_cfa:
LEB (); LEB ();
@ -4152,14 +4162,14 @@ display_debug_frames (struct dwarf_section *section,
reg = LEB ();
tmp = LEB ();
start += tmp;
frame_need_space (fc, reg);
fc->col_type[reg] = DW_CFA_undefined;
if (frame_need_space (fc, reg) >= 0)
fc->col_type[reg] = DW_CFA_undefined;
break;
case DW_CFA_offset_extended_sf:
case DW_CFA_val_offset_sf:
reg = LEB (); SLEB ();
frame_need_space (fc, reg);
fc->col_type[reg] = DW_CFA_undefined;
if (frame_need_space (fc, reg) >= 0)
fc->col_type[reg] = DW_CFA_undefined;
break;
case DW_CFA_def_cfa_sf:
LEB (); SLEB ();
@ -4175,9 +4185,9 @@ display_debug_frames (struct dwarf_section *section,
break;
case DW_CFA_GNU_negative_offset_extended:
reg = LEB (); LEB ();
frame_need_space (fc, reg);
fc->col_type[reg] = DW_CFA_undefined;
if (frame_need_space (fc, reg) >= 0)
fc->col_type[reg] = DW_CFA_undefined;
break;
default:
break;
}
@ -4194,6 +4204,7 @@ display_debug_frames (struct dwarf_section *section,
unsigned long ul, reg, roffs;
long l, ofs;
dwarf_vma vma;
const char *reg_prefix = "";
op = *start++;
opa = op & 0x3f;
@ -4216,18 +4227,31 @@ display_debug_frames (struct dwarf_section *section,
case DW_CFA_offset:
roffs = LEB ();
if (! do_debug_frames_interp)
printf (" DW_CFA_offset: %s at cfa%+ld\n",
regname (opa, 0), roffs * fc->data_factor);
fc->col_type[opa] = DW_CFA_offset;
fc->col_offset[opa] = roffs * fc->data_factor;
if (opa >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
printf (" DW_CFA_offset: %s%s at cfa%+ld\n",
reg_prefix, regname (opa, 0),
roffs * fc->data_factor);
if (*reg_prefix == '\0')
{
fc->col_type[opa] = DW_CFA_offset;
fc->col_offset[opa] = roffs * fc->data_factor;
}
break;
case DW_CFA_restore:
if (! do_debug_frames_interp)
printf (" DW_CFA_restore: %s\n", regname (opa, 0));
fc->col_type[opa] = cie->col_type[opa];
fc->col_offset[opa] = cie->col_offset[opa];
if (opa >= (unsigned int) cie->ncols
|| opa >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
printf (" DW_CFA_restore: %s%s\n",
reg_prefix, regname (opa, 0));
if (*reg_prefix == '\0')
{
fc->col_type[opa] = cie->col_type[opa];
fc->col_offset[opa] = cie->col_offset[opa];
}
break;
case DW_CFA_set_loc:
@ -4278,59 +4302,94 @@ display_debug_frames (struct dwarf_section *section,
case DW_CFA_offset_extended:
reg = LEB ();
roffs = LEB ();
if (! do_debug_frames_interp)
printf (" DW_CFA_offset_extended: %s at cfa%+ld\n",
regname (reg, 0), roffs * fc->data_factor);
fc->col_type[reg] = DW_CFA_offset;
fc->col_offset[reg] = roffs * fc->data_factor;
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
printf (" DW_CFA_offset_extended: %s%s at cfa%+ld\n",
reg_prefix, regname (reg, 0),
roffs * fc->data_factor);
if (*reg_prefix == '\0')
{
fc->col_type[reg] = DW_CFA_offset;
fc->col_offset[reg] = roffs * fc->data_factor;
}
break;
case DW_CFA_val_offset:
reg = LEB ();
roffs = LEB ();
if (! do_debug_frames_interp)
printf (" DW_CFA_val_offset: %s at cfa%+ld\n",
regname (reg, 0), roffs * fc->data_factor);
fc->col_type[reg] = DW_CFA_val_offset;
fc->col_offset[reg] = roffs * fc->data_factor;
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
printf (" DW_CFA_val_offset: %s%s at cfa%+ld\n",
reg_prefix, regname (reg, 0),
roffs * fc->data_factor);
if (*reg_prefix == '\0')
{
fc->col_type[reg] = DW_CFA_val_offset;
fc->col_offset[reg] = roffs * fc->data_factor;
}
break;
case DW_CFA_restore_extended:
reg = LEB ();
if (! do_debug_frames_interp)
printf (" DW_CFA_restore_extended: %s\n",
regname (reg, 0));
fc->col_type[reg] = cie->col_type[reg];
fc->col_offset[reg] = cie->col_offset[reg];
if (reg >= (unsigned int) cie->ncols
|| reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
printf (" DW_CFA_restore_extended: %s%s\n",
reg_prefix, regname (reg, 0));
if (*reg_prefix == '\0')
{
fc->col_type[reg] = cie->col_type[reg];
fc->col_offset[reg] = cie->col_offset[reg];
}
break;
case DW_CFA_undefined:
reg = LEB ();
if (! do_debug_frames_interp)
printf (" DW_CFA_undefined: %s\n", regname (reg, 0));
fc->col_type[reg] = DW_CFA_undefined;
fc->col_offset[reg] = 0;
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
printf (" DW_CFA_undefined: %s%s\n",
reg_prefix, regname (reg, 0));
if (*reg_prefix == '\0')
{
fc->col_type[reg] = DW_CFA_undefined;
fc->col_offset[reg] = 0;
}
break;
case DW_CFA_same_value:
reg = LEB ();
if (! do_debug_frames_interp)
printf (" DW_CFA_same_value: %s\n", regname (reg, 0));
fc->col_type[reg] = DW_CFA_same_value;
fc->col_offset[reg] = 0;
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
printf (" DW_CFA_same_value: %s%s\n",
reg_prefix, regname (reg, 0));
if (*reg_prefix == '\0')
{
fc->col_type[reg] = DW_CFA_same_value;
fc->col_offset[reg] = 0;
}
break;
case DW_CFA_register:
reg = LEB ();
roffs = LEB ();
if (! do_debug_frames_interp)
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
{
printf (" DW_CFA_register: %s in ",
regname (reg, 0));
printf (" DW_CFA_register: %s%s in ",
reg_prefix, regname (reg, 0));
puts (regname (roffs, 0));
}
fc->col_type[reg] = DW_CFA_register;
fc->col_offset[reg] = roffs;
if (*reg_prefix == '\0')
{
fc->col_type[reg] = DW_CFA_register;
fc->col_offset[reg] = roffs;
}
break;
case DW_CFA_remember_state:
@ -4409,53 +4468,69 @@ display_debug_frames (struct dwarf_section *section,
case DW_CFA_expression:
reg = LEB ();
ul = LEB ();
if (! do_debug_frames_interp)
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
{
printf (" DW_CFA_expression: %s (",
regname (reg, 0));
printf (" DW_CFA_expression: %s%s (",
reg_prefix, regname (reg, 0));
decode_location_expression (start, eh_addr_size,
ul, 0, section);
printf (")\n");
}
fc->col_type[reg] = DW_CFA_expression;
if (*reg_prefix == '\0')
fc->col_type[reg] = DW_CFA_expression;
start += ul;
break;
case DW_CFA_val_expression:
reg = LEB ();
ul = LEB ();
if (! do_debug_frames_interp)
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
{
printf (" DW_CFA_val_expression: %s (",
regname (reg, 0));
printf (" DW_CFA_val_expression: %s%s (",
reg_prefix, regname (reg, 0));
decode_location_expression (start, eh_addr_size, ul, 0,
section);
printf (")\n");
}
fc->col_type[reg] = DW_CFA_val_expression;
if (*reg_prefix == '\0')
fc->col_type[reg] = DW_CFA_val_expression;
start += ul;
break;
case DW_CFA_offset_extended_sf:
reg = LEB ();
l = SLEB ();
frame_need_space (fc, reg);
if (! do_debug_frames_interp)
printf (" DW_CFA_offset_extended_sf: %s at cfa%+ld\n",
regname (reg, 0), l * fc->data_factor);
fc->col_type[reg] = DW_CFA_offset;
fc->col_offset[reg] = l * fc->data_factor;
if (frame_need_space (fc, reg) < 0)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
printf (" DW_CFA_offset_extended_sf: %s%s at cfa%+ld\n",
reg_prefix, regname (reg, 0),
l * fc->data_factor);
if (*reg_prefix == '\0')
{
fc->col_type[reg] = DW_CFA_offset;
fc->col_offset[reg] = l * fc->data_factor;
}
break;
case DW_CFA_val_offset_sf:
reg = LEB ();
l = SLEB ();
frame_need_space (fc, reg);
if (! do_debug_frames_interp)
printf (" DW_CFA_val_offset_sf: %s at cfa%+ld\n",
regname (reg, 0), l * fc->data_factor);
fc->col_type[reg] = DW_CFA_val_offset;
fc->col_offset[reg] = l * fc->data_factor;
if (frame_need_space (fc, reg) < 0)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
printf (" DW_CFA_val_offset_sf: %s%s at cfa%+ld\n",
reg_prefix, regname (reg, 0),
l * fc->data_factor);
if (*reg_prefix == '\0')
{
fc->col_type[reg] = DW_CFA_val_offset;
fc->col_offset[reg] = l * fc->data_factor;
}
break;
case DW_CFA_def_cfa_sf:
@ -4500,12 +4575,17 @@ display_debug_frames (struct dwarf_section *section,
case DW_CFA_GNU_negative_offset_extended:
reg = LEB ();
l = - LEB ();
frame_need_space (fc, reg);
if (! do_debug_frames_interp)
printf (" DW_CFA_GNU_negative_offset_extended: %s at cfa%+ld\n",
regname (reg, 0), l * fc->data_factor);
fc->col_type[reg] = DW_CFA_offset;
fc->col_offset[reg] = l * fc->data_factor;
if (frame_need_space (fc, reg) < 0)
reg_prefix = bad_reg;
if (! do_debug_frames_interp || *reg_prefix != '\0')
printf (" DW_CFA_GNU_negative_offset_extended: %s%s at cfa%+ld\n",
reg_prefix, regname (reg, 0),
l * fc->data_factor);
if (*reg_prefix == '\0')
{
fc->col_type[reg] = DW_CFA_offset;
fc->col_offset[reg] = l * fc->data_factor;
}
break;
default: