display_debug_frames
* dwarf.c (display_debug_frames): Delete initial_length_size. Avoid pointer UB. Constrain data reads to length given in header. Sanity check cie header length. Only skip up to next FDE on finding augmentation data too long.
This commit is contained in:
parent
c93c4a8540
commit
5897a38984
2 changed files with 114 additions and 103 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2021-05-15 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* dwarf.c (display_debug_frames): Delete initial_length_size.
|
||||||
|
Avoid pointer UB. Constrain data reads to length given in header.
|
||||||
|
Sanity check cie header length. Only skip up to next FDE on
|
||||||
|
finding augmentation data too long.
|
||||||
|
|
||||||
2021-05-15 Alan Modra <amodra@gmail.com>
|
2021-05-15 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* dwarf.c (read_cie): Add more sanity checks to ensure data
|
* dwarf.c (read_cie): Add more sanity checks to ensure data
|
||||||
|
|
194
binutils/dwarf.c
194
binutils/dwarf.c
|
@ -8587,7 +8587,6 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
bfd_size_type augmentation_data_len = 0;
|
bfd_size_type augmentation_data_len = 0;
|
||||||
unsigned int encoded_ptr_size = saved_eh_addr_size;
|
unsigned int encoded_ptr_size = saved_eh_addr_size;
|
||||||
unsigned int offset_size;
|
unsigned int offset_size;
|
||||||
unsigned int initial_length_size;
|
|
||||||
bool all_nops;
|
bool all_nops;
|
||||||
static Frame_Chunk fde_fc;
|
static Frame_Chunk fde_fc;
|
||||||
|
|
||||||
|
@ -8612,24 +8611,21 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
{
|
{
|
||||||
SAFE_BYTE_GET_AND_INC (length, start, 8, end);
|
SAFE_BYTE_GET_AND_INC (length, start, 8, end);
|
||||||
offset_size = 8;
|
offset_size = 8;
|
||||||
initial_length_size = 12;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
offset_size = 4;
|
offset_size = 4;
|
||||||
initial_length_size = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
block_end = saved_start + length + initial_length_size;
|
if (length > (size_t) (end - start))
|
||||||
if (block_end > end || block_end < start)
|
|
||||||
{
|
{
|
||||||
warn ("Invalid length 0x%s in FDE at %#08lx\n",
|
warn ("Invalid length 0x%s in FDE at %#08lx\n",
|
||||||
dwarf_vmatoa_1 (NULL, length, offset_size),
|
dwarf_vmatoa_1 (NULL, length, offset_size),
|
||||||
(unsigned long) (saved_start - section_start));
|
(unsigned long) (saved_start - section_start));
|
||||||
block_end = end;
|
block_end = end;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
block_end = start + length;
|
||||||
|
|
||||||
SAFE_BYTE_GET_AND_INC (cie_id, start, offset_size, end);
|
SAFE_BYTE_GET_AND_INC (cie_id, start, offset_size, block_end);
|
||||||
|
|
||||||
if (is_eh ? (cie_id == 0) : ((offset_size == 4 && cie_id == DW_CIE_ID)
|
if (is_eh ? (cie_id == 0) : ((offset_size == 4 && cie_id == DW_CIE_ID)
|
||||||
|| (offset_size == 8 && cie_id == DW64_CIE_ID)))
|
|| (offset_size == 8 && cie_id == DW64_CIE_ID)))
|
||||||
|
@ -8637,7 +8633,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
int version;
|
int version;
|
||||||
unsigned int mreg;
|
unsigned int mreg;
|
||||||
|
|
||||||
start = read_cie (start, end, &cie, &version,
|
start = read_cie (start, block_end, &cie, &version,
|
||||||
&augmentation_data_len, &augmentation_data);
|
&augmentation_data_len, &augmentation_data);
|
||||||
/* PR 17512: file: 027-135133-0.005. */
|
/* PR 17512: file: 027-135133-0.005. */
|
||||||
if (cie == NULL)
|
if (cie == NULL)
|
||||||
|
@ -8725,11 +8721,13 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
SAFE_BYTE_GET_AND_INC (length, cie_scan, 8, end);
|
SAFE_BYTE_GET_AND_INC (length, cie_scan, 8, end);
|
||||||
off_size = 8;
|
off_size = 8;
|
||||||
}
|
}
|
||||||
if (length != 0)
|
if (length != 0 && length <= (size_t) (end - cie_scan))
|
||||||
{
|
{
|
||||||
dwarf_vma c_id;
|
dwarf_vma c_id;
|
||||||
|
unsigned char *cie_end = cie_scan + length;
|
||||||
|
|
||||||
SAFE_BYTE_GET_AND_INC (c_id, cie_scan, off_size, end);
|
SAFE_BYTE_GET_AND_INC (c_id, cie_scan, off_size,
|
||||||
|
cie_end);
|
||||||
if (is_eh
|
if (is_eh
|
||||||
? c_id == 0
|
? c_id == 0
|
||||||
: ((off_size == 4 && c_id == DW_CIE_ID)
|
: ((off_size == 4 && c_id == DW_CIE_ID)
|
||||||
|
@ -8738,7 +8736,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
int version;
|
int version;
|
||||||
unsigned int mreg;
|
unsigned int mreg;
|
||||||
|
|
||||||
read_cie (cie_scan, end, &cie, &version,
|
read_cie (cie_scan, cie_end, &cie, &version,
|
||||||
&augmentation_data_len, &augmentation_data);
|
&augmentation_data_len, &augmentation_data);
|
||||||
/* PR 17512: file: 3450-2098-0.004. */
|
/* PR 17512: file: 3450-2098-0.004. */
|
||||||
if (cie == NULL)
|
if (cie == NULL)
|
||||||
|
@ -8823,29 +8821,32 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
warn (_("Probably corrupt segment size: %d - using 4 instead\n"), fc->segment_size);
|
warn (_("Probably corrupt segment size: %d - using 4 instead\n"), fc->segment_size);
|
||||||
fc->segment_size = 4;
|
fc->segment_size = 4;
|
||||||
}
|
}
|
||||||
SAFE_BYTE_GET_AND_INC (segment_selector, start, fc->segment_size, end);
|
SAFE_BYTE_GET_AND_INC (segment_selector, start,
|
||||||
|
fc->segment_size, block_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
fc->pc_begin = get_encoded_value (&start, fc->fde_encoding, section, end);
|
fc->pc_begin = get_encoded_value (&start, fc->fde_encoding, section,
|
||||||
|
block_end);
|
||||||
|
|
||||||
/* FIXME: It appears that sometimes the final pc_range value is
|
/* FIXME: It appears that sometimes the final pc_range value is
|
||||||
encoded in less than encoded_ptr_size bytes. See the x86_64
|
encoded in less than encoded_ptr_size bytes. See the x86_64
|
||||||
run of the "objcopy on compressed debug sections" test for an
|
run of the "objcopy on compressed debug sections" test for an
|
||||||
example of this. */
|
example of this. */
|
||||||
SAFE_BYTE_GET_AND_INC (fc->pc_range, start, encoded_ptr_size, end);
|
SAFE_BYTE_GET_AND_INC (fc->pc_range, start, encoded_ptr_size,
|
||||||
|
block_end);
|
||||||
|
|
||||||
if (cie->augmentation[0] == 'z')
|
if (cie->augmentation[0] == 'z')
|
||||||
{
|
{
|
||||||
READ_ULEB (augmentation_data_len, start, end);
|
READ_ULEB (augmentation_data_len, start, block_end);
|
||||||
augmentation_data = start;
|
augmentation_data = start;
|
||||||
/* PR 17512 file: 722-8446-0.004 and PR 22386. */
|
/* PR 17512 file: 722-8446-0.004 and PR 22386. */
|
||||||
if (augmentation_data_len > (bfd_size_type) (end - start))
|
if (augmentation_data_len > (bfd_size_type) (block_end - start))
|
||||||
{
|
{
|
||||||
warn (_("Augmentation data too long: 0x%s, "
|
warn (_("Augmentation data too long: 0x%s, "
|
||||||
"expected at most %#lx\n"),
|
"expected at most %#lx\n"),
|
||||||
dwarf_vmatoa ("x", augmentation_data_len),
|
dwarf_vmatoa ("x", augmentation_data_len),
|
||||||
(unsigned long) (end - start));
|
(unsigned long) (block_end - start));
|
||||||
start = end;
|
start = block_end;
|
||||||
augmentation_data = NULL;
|
augmentation_data = NULL;
|
||||||
augmentation_data_len = 0;
|
augmentation_data_len = 0;
|
||||||
}
|
}
|
||||||
|
@ -8889,7 +8890,6 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
{
|
{
|
||||||
unsigned int reg, op, opa;
|
unsigned int reg, op, opa;
|
||||||
unsigned long temp;
|
unsigned long temp;
|
||||||
unsigned char * new_start;
|
|
||||||
|
|
||||||
op = *start++;
|
op = *start++;
|
||||||
opa = op & 0x3f;
|
opa = op & 0x3f;
|
||||||
|
@ -8903,7 +8903,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
case DW_CFA_advance_loc:
|
case DW_CFA_advance_loc:
|
||||||
break;
|
break;
|
||||||
case DW_CFA_offset:
|
case DW_CFA_offset:
|
||||||
SKIP_ULEB (start, end);
|
SKIP_ULEB (start, block_end);
|
||||||
if (frame_need_space (fc, opa) >= 0)
|
if (frame_need_space (fc, opa) >= 0)
|
||||||
fc->col_type[opa] = DW_CFA_undefined;
|
fc->col_type[opa] = DW_CFA_undefined;
|
||||||
break;
|
break;
|
||||||
|
@ -8912,105 +8912,111 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
fc->col_type[opa] = DW_CFA_undefined;
|
fc->col_type[opa] = DW_CFA_undefined;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_set_loc:
|
case DW_CFA_set_loc:
|
||||||
|
if ((size_t) (block_end - start) < encoded_ptr_size)
|
||||||
|
start = block_end;
|
||||||
|
else
|
||||||
start += encoded_ptr_size;
|
start += encoded_ptr_size;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_advance_loc1:
|
case DW_CFA_advance_loc1:
|
||||||
|
if ((size_t) (block_end - start) < 1)
|
||||||
|
start = block_end;
|
||||||
|
else
|
||||||
start += 1;
|
start += 1;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_advance_loc2:
|
case DW_CFA_advance_loc2:
|
||||||
|
if ((size_t) (block_end - start) < 2)
|
||||||
|
start = block_end;
|
||||||
|
else
|
||||||
start += 2;
|
start += 2;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_advance_loc4:
|
case DW_CFA_advance_loc4:
|
||||||
|
if ((size_t) (block_end - start) < 4)
|
||||||
|
start = block_end;
|
||||||
|
else
|
||||||
start += 4;
|
start += 4;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_offset_extended:
|
case DW_CFA_offset_extended:
|
||||||
case DW_CFA_val_offset:
|
case DW_CFA_val_offset:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
SKIP_ULEB (start, end);
|
SKIP_ULEB (start, block_end);
|
||||||
if (frame_need_space (fc, reg) >= 0)
|
if (frame_need_space (fc, reg) >= 0)
|
||||||
fc->col_type[reg] = DW_CFA_undefined;
|
fc->col_type[reg] = DW_CFA_undefined;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_restore_extended:
|
case DW_CFA_restore_extended:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
if (frame_need_space (fc, reg) >= 0)
|
if (frame_need_space (fc, reg) >= 0)
|
||||||
fc->col_type[reg] = DW_CFA_undefined;
|
fc->col_type[reg] = DW_CFA_undefined;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_undefined:
|
case DW_CFA_undefined:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
if (frame_need_space (fc, reg) >= 0)
|
if (frame_need_space (fc, reg) >= 0)
|
||||||
fc->col_type[reg] = DW_CFA_undefined;
|
fc->col_type[reg] = DW_CFA_undefined;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_same_value:
|
case DW_CFA_same_value:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
if (frame_need_space (fc, reg) >= 0)
|
if (frame_need_space (fc, reg) >= 0)
|
||||||
fc->col_type[reg] = DW_CFA_undefined;
|
fc->col_type[reg] = DW_CFA_undefined;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_register:
|
case DW_CFA_register:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
SKIP_ULEB (start, end);
|
SKIP_ULEB (start, block_end);
|
||||||
if (frame_need_space (fc, reg) >= 0)
|
if (frame_need_space (fc, reg) >= 0)
|
||||||
fc->col_type[reg] = DW_CFA_undefined;
|
fc->col_type[reg] = DW_CFA_undefined;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_def_cfa:
|
case DW_CFA_def_cfa:
|
||||||
SKIP_ULEB (start, end);
|
SKIP_ULEB (start, block_end);
|
||||||
SKIP_ULEB (start, end);
|
SKIP_ULEB (start, block_end);
|
||||||
break;
|
break;
|
||||||
case DW_CFA_def_cfa_register:
|
case DW_CFA_def_cfa_register:
|
||||||
SKIP_ULEB (start, end);
|
SKIP_ULEB (start, block_end);
|
||||||
break;
|
break;
|
||||||
case DW_CFA_def_cfa_offset:
|
case DW_CFA_def_cfa_offset:
|
||||||
SKIP_ULEB (start, end);
|
SKIP_ULEB (start, block_end);
|
||||||
break;
|
break;
|
||||||
case DW_CFA_def_cfa_expression:
|
case DW_CFA_def_cfa_expression:
|
||||||
READ_ULEB (temp, start, end);
|
READ_ULEB (temp, start, block_end);
|
||||||
new_start = start + temp;
|
if ((size_t) (block_end - start) < temp)
|
||||||
if (new_start < start)
|
|
||||||
{
|
|
||||||
warn (_("Corrupt CFA_def expression value: %lu\n"), temp);
|
|
||||||
start = block_end;
|
start = block_end;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
start = new_start;
|
start += temp;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_expression:
|
case DW_CFA_expression:
|
||||||
case DW_CFA_val_expression:
|
case DW_CFA_val_expression:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
READ_ULEB (temp, start, end);
|
READ_ULEB (temp, start, block_end);
|
||||||
new_start = start + temp;
|
if ((size_t) (block_end - start) < temp)
|
||||||
if (new_start < start)
|
|
||||||
{
|
|
||||||
/* PR 17512: file:306-192417-0.005. */
|
|
||||||
warn (_("Corrupt CFA expression value: %lu\n"), temp);
|
|
||||||
start = block_end;
|
start = block_end;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
start = new_start;
|
start += temp;
|
||||||
if (frame_need_space (fc, reg) >= 0)
|
if (frame_need_space (fc, reg) >= 0)
|
||||||
fc->col_type[reg] = DW_CFA_undefined;
|
fc->col_type[reg] = DW_CFA_undefined;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_offset_extended_sf:
|
case DW_CFA_offset_extended_sf:
|
||||||
case DW_CFA_val_offset_sf:
|
case DW_CFA_val_offset_sf:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
SKIP_SLEB (start, end);
|
SKIP_SLEB (start, block_end);
|
||||||
if (frame_need_space (fc, reg) >= 0)
|
if (frame_need_space (fc, reg) >= 0)
|
||||||
fc->col_type[reg] = DW_CFA_undefined;
|
fc->col_type[reg] = DW_CFA_undefined;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_def_cfa_sf:
|
case DW_CFA_def_cfa_sf:
|
||||||
SKIP_ULEB (start, end);
|
SKIP_ULEB (start, block_end);
|
||||||
SKIP_SLEB (start, end);
|
SKIP_SLEB (start, block_end);
|
||||||
break;
|
break;
|
||||||
case DW_CFA_def_cfa_offset_sf:
|
case DW_CFA_def_cfa_offset_sf:
|
||||||
SKIP_SLEB (start, end);
|
SKIP_SLEB (start, block_end);
|
||||||
break;
|
break;
|
||||||
case DW_CFA_MIPS_advance_loc8:
|
case DW_CFA_MIPS_advance_loc8:
|
||||||
|
if ((size_t) (block_end - start) < 8)
|
||||||
|
start = block_end;
|
||||||
|
else
|
||||||
start += 8;
|
start += 8;
|
||||||
break;
|
break;
|
||||||
case DW_CFA_GNU_args_size:
|
case DW_CFA_GNU_args_size:
|
||||||
SKIP_ULEB (start, end);
|
SKIP_ULEB (start, block_end);
|
||||||
break;
|
break;
|
||||||
case DW_CFA_GNU_negative_offset_extended:
|
case DW_CFA_GNU_negative_offset_extended:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
SKIP_ULEB (start, end);
|
SKIP_ULEB (start, block_end);
|
||||||
if (frame_need_space (fc, reg) >= 0)
|
if (frame_need_space (fc, reg) >= 0)
|
||||||
fc->col_type[reg] = DW_CFA_undefined;
|
fc->col_type[reg] = DW_CFA_undefined;
|
||||||
break;
|
break;
|
||||||
|
@ -9028,7 +9034,6 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
|
|
||||||
while (start < block_end)
|
while (start < block_end)
|
||||||
{
|
{
|
||||||
unsigned char * tmp;
|
|
||||||
unsigned op, opa;
|
unsigned op, opa;
|
||||||
unsigned long ul, roffs;
|
unsigned long ul, roffs;
|
||||||
/* Note: It is tempting to use an unsigned long for 'reg' but there
|
/* Note: It is tempting to use an unsigned long for 'reg' but there
|
||||||
|
@ -9066,7 +9071,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_offset:
|
case DW_CFA_offset:
|
||||||
READ_ULEB (roffs, start, end);
|
READ_ULEB (roffs, start, block_end);
|
||||||
if (opa >= (unsigned int) fc->ncols)
|
if (opa >= (unsigned int) fc->ncols)
|
||||||
reg_prefix = bad_reg;
|
reg_prefix = bad_reg;
|
||||||
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
||||||
|
@ -9104,7 +9109,8 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_set_loc:
|
case DW_CFA_set_loc:
|
||||||
vma = get_encoded_value (&start, fc->fde_encoding, section, block_end);
|
vma = get_encoded_value (&start, fc->fde_encoding, section,
|
||||||
|
block_end);
|
||||||
if (do_debug_frames_interp)
|
if (do_debug_frames_interp)
|
||||||
frame_display_row (fc, &need_col_headers, &max_regs);
|
frame_display_row (fc, &need_col_headers, &max_regs);
|
||||||
else
|
else
|
||||||
|
@ -9114,7 +9120,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_advance_loc1:
|
case DW_CFA_advance_loc1:
|
||||||
SAFE_BYTE_GET_AND_INC (ofs, start, 1, end);
|
SAFE_BYTE_GET_AND_INC (ofs, start, 1, block_end);
|
||||||
if (do_debug_frames_interp)
|
if (do_debug_frames_interp)
|
||||||
frame_display_row (fc, &need_col_headers, &max_regs);
|
frame_display_row (fc, &need_col_headers, &max_regs);
|
||||||
else
|
else
|
||||||
|
@ -9153,8 +9159,8 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_offset_extended:
|
case DW_CFA_offset_extended:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
READ_ULEB (roffs, start, end);
|
READ_ULEB (roffs, start, block_end);
|
||||||
if (reg >= (unsigned int) fc->ncols)
|
if (reg >= (unsigned int) fc->ncols)
|
||||||
reg_prefix = bad_reg;
|
reg_prefix = bad_reg;
|
||||||
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
||||||
|
@ -9169,8 +9175,8 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_val_offset:
|
case DW_CFA_val_offset:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
READ_ULEB (roffs, start, end);
|
READ_ULEB (roffs, start, block_end);
|
||||||
if (reg >= (unsigned int) fc->ncols)
|
if (reg >= (unsigned int) fc->ncols)
|
||||||
reg_prefix = bad_reg;
|
reg_prefix = bad_reg;
|
||||||
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
||||||
|
@ -9185,7 +9191,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_restore_extended:
|
case DW_CFA_restore_extended:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
if (reg >= (unsigned int) fc->ncols)
|
if (reg >= (unsigned int) fc->ncols)
|
||||||
reg_prefix = bad_reg;
|
reg_prefix = bad_reg;
|
||||||
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
||||||
|
@ -9207,7 +9213,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_undefined:
|
case DW_CFA_undefined:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
if (reg >= (unsigned int) fc->ncols)
|
if (reg >= (unsigned int) fc->ncols)
|
||||||
reg_prefix = bad_reg;
|
reg_prefix = bad_reg;
|
||||||
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
||||||
|
@ -9221,7 +9227,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_same_value:
|
case DW_CFA_same_value:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
if (reg >= (unsigned int) fc->ncols)
|
if (reg >= (unsigned int) fc->ncols)
|
||||||
reg_prefix = bad_reg;
|
reg_prefix = bad_reg;
|
||||||
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
||||||
|
@ -9235,8 +9241,8 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_register:
|
case DW_CFA_register:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
READ_ULEB (roffs, start, end);
|
READ_ULEB (roffs, start, block_end);
|
||||||
if (reg >= (unsigned int) fc->ncols)
|
if (reg >= (unsigned int) fc->ncols)
|
||||||
reg_prefix = bad_reg;
|
reg_prefix = bad_reg;
|
||||||
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
||||||
|
@ -9299,8 +9305,8 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_def_cfa:
|
case DW_CFA_def_cfa:
|
||||||
READ_ULEB (fc->cfa_reg, start, end);
|
READ_ULEB (fc->cfa_reg, start, block_end);
|
||||||
READ_ULEB (fc->cfa_offset, start, end);
|
READ_ULEB (fc->cfa_offset, start, block_end);
|
||||||
fc->cfa_exp = 0;
|
fc->cfa_exp = 0;
|
||||||
if (! do_debug_frames_interp)
|
if (! do_debug_frames_interp)
|
||||||
printf (" DW_CFA_def_cfa: %s ofs %d\n",
|
printf (" DW_CFA_def_cfa: %s ofs %d\n",
|
||||||
|
@ -9308,7 +9314,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_def_cfa_register:
|
case DW_CFA_def_cfa_register:
|
||||||
READ_ULEB (fc->cfa_reg, start, end);
|
READ_ULEB (fc->cfa_reg, start, block_end);
|
||||||
fc->cfa_exp = 0;
|
fc->cfa_exp = 0;
|
||||||
if (! do_debug_frames_interp)
|
if (! do_debug_frames_interp)
|
||||||
printf (" DW_CFA_def_cfa_register: %s\n",
|
printf (" DW_CFA_def_cfa_register: %s\n",
|
||||||
|
@ -9316,7 +9322,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_def_cfa_offset:
|
case DW_CFA_def_cfa_offset:
|
||||||
READ_ULEB (fc->cfa_offset, start, end);
|
READ_ULEB (fc->cfa_offset, start, block_end);
|
||||||
if (! do_debug_frames_interp)
|
if (! do_debug_frames_interp)
|
||||||
printf (" DW_CFA_def_cfa_offset: %d\n", (int) fc->cfa_offset);
|
printf (" DW_CFA_def_cfa_offset: %d\n", (int) fc->cfa_offset);
|
||||||
break;
|
break;
|
||||||
|
@ -9327,8 +9333,8 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_def_cfa_expression:
|
case DW_CFA_def_cfa_expression:
|
||||||
READ_ULEB (ul, start, end);
|
READ_ULEB (ul, start, block_end);
|
||||||
if (start >= block_end || ul > (unsigned long) (block_end - start))
|
if (ul > (size_t) (block_end - start))
|
||||||
{
|
{
|
||||||
printf (_(" DW_CFA_def_cfa_expression: <corrupt len %lu>\n"), ul);
|
printf (_(" DW_CFA_def_cfa_expression: <corrupt len %lu>\n"), ul);
|
||||||
break;
|
break;
|
||||||
|
@ -9345,14 +9351,13 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_expression:
|
case DW_CFA_expression:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
READ_ULEB (ul, start, end);
|
READ_ULEB (ul, start, block_end);
|
||||||
if (reg >= (unsigned int) fc->ncols)
|
if (reg >= (unsigned int) fc->ncols)
|
||||||
reg_prefix = bad_reg;
|
reg_prefix = bad_reg;
|
||||||
/* PR 17512: file: 069-133014-0.006. */
|
/* PR 17512: file: 069-133014-0.006. */
|
||||||
/* PR 17512: file: 98c02eb4. */
|
/* PR 17512: file: 98c02eb4. */
|
||||||
tmp = start + ul;
|
if (ul > (size_t) (block_end - start))
|
||||||
if (start >= block_end || tmp > block_end || tmp < start)
|
|
||||||
{
|
{
|
||||||
printf (_(" DW_CFA_expression: <corrupt len %lu>\n"), ul);
|
printf (_(" DW_CFA_expression: <corrupt len %lu>\n"), ul);
|
||||||
break;
|
break;
|
||||||
|
@ -9367,16 +9372,15 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
}
|
}
|
||||||
if (*reg_prefix == '\0')
|
if (*reg_prefix == '\0')
|
||||||
fc->col_type[reg] = DW_CFA_expression;
|
fc->col_type[reg] = DW_CFA_expression;
|
||||||
start = tmp;
|
start += ul;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_val_expression:
|
case DW_CFA_val_expression:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
READ_ULEB (ul, start, end);
|
READ_ULEB (ul, start, block_end);
|
||||||
if (reg >= (unsigned int) fc->ncols)
|
if (reg >= (unsigned int) fc->ncols)
|
||||||
reg_prefix = bad_reg;
|
reg_prefix = bad_reg;
|
||||||
tmp = start + ul;
|
if (ul > (size_t) (block_end - start))
|
||||||
if (start >= block_end || tmp > block_end || tmp < start)
|
|
||||||
{
|
{
|
||||||
printf (" DW_CFA_val_expression: <corrupt len %lu>\n", ul);
|
printf (" DW_CFA_val_expression: <corrupt len %lu>\n", ul);
|
||||||
break;
|
break;
|
||||||
|
@ -9391,12 +9395,12 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
}
|
}
|
||||||
if (*reg_prefix == '\0')
|
if (*reg_prefix == '\0')
|
||||||
fc->col_type[reg] = DW_CFA_val_expression;
|
fc->col_type[reg] = DW_CFA_val_expression;
|
||||||
start = tmp;
|
start += ul;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_offset_extended_sf:
|
case DW_CFA_offset_extended_sf:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
READ_SLEB (l, start, end);
|
READ_SLEB (l, start, block_end);
|
||||||
if (frame_need_space (fc, reg) < 0)
|
if (frame_need_space (fc, reg) < 0)
|
||||||
reg_prefix = bad_reg;
|
reg_prefix = bad_reg;
|
||||||
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
||||||
|
@ -9411,8 +9415,8 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_val_offset_sf:
|
case DW_CFA_val_offset_sf:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
READ_SLEB (l, start, end);
|
READ_SLEB (l, start, block_end);
|
||||||
if (frame_need_space (fc, reg) < 0)
|
if (frame_need_space (fc, reg) < 0)
|
||||||
reg_prefix = bad_reg;
|
reg_prefix = bad_reg;
|
||||||
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
if (! do_debug_frames_interp || *reg_prefix != '\0')
|
||||||
|
@ -9427,8 +9431,8 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_def_cfa_sf:
|
case DW_CFA_def_cfa_sf:
|
||||||
READ_ULEB (fc->cfa_reg, start, end);
|
READ_ULEB (fc->cfa_reg, start, block_end);
|
||||||
READ_ULEB (fc->cfa_offset, start, end);
|
READ_ULEB (fc->cfa_offset, start, block_end);
|
||||||
fc->cfa_offset = fc->cfa_offset * fc->data_factor;
|
fc->cfa_offset = fc->cfa_offset * fc->data_factor;
|
||||||
fc->cfa_exp = 0;
|
fc->cfa_exp = 0;
|
||||||
if (! do_debug_frames_interp)
|
if (! do_debug_frames_interp)
|
||||||
|
@ -9437,7 +9441,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_def_cfa_offset_sf:
|
case DW_CFA_def_cfa_offset_sf:
|
||||||
READ_ULEB (fc->cfa_offset, start, end);
|
READ_ULEB (fc->cfa_offset, start, block_end);
|
||||||
fc->cfa_offset *= fc->data_factor;
|
fc->cfa_offset *= fc->data_factor;
|
||||||
if (! do_debug_frames_interp)
|
if (! do_debug_frames_interp)
|
||||||
printf (" DW_CFA_def_cfa_offset_sf: %d\n", (int) fc->cfa_offset);
|
printf (" DW_CFA_def_cfa_offset_sf: %d\n", (int) fc->cfa_offset);
|
||||||
|
@ -9462,14 +9466,14 @@ display_debug_frames (struct dwarf_section *section,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_GNU_args_size:
|
case DW_CFA_GNU_args_size:
|
||||||
READ_ULEB (ul, start, end);
|
READ_ULEB (ul, start, block_end);
|
||||||
if (! do_debug_frames_interp)
|
if (! do_debug_frames_interp)
|
||||||
printf (" DW_CFA_GNU_args_size: %ld\n", ul);
|
printf (" DW_CFA_GNU_args_size: %ld\n", ul);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_GNU_negative_offset_extended:
|
case DW_CFA_GNU_negative_offset_extended:
|
||||||
READ_ULEB (reg, start, end);
|
READ_ULEB (reg, start, block_end);
|
||||||
READ_SLEB (l, start, end);
|
READ_SLEB (l, start, block_end);
|
||||||
l = - l;
|
l = - l;
|
||||||
if (frame_need_space (fc, reg) < 0)
|
if (frame_need_space (fc, reg) < 0)
|
||||||
reg_prefix = bad_reg;
|
reg_prefix = bad_reg;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue