* dwarf2-frame.c (struct dwarf2_cie): Make initial_instructions, end

"const gdb_byte *".
	(struct dwarf2_fde): Make instructions, end "const gdb_byte *".
	(execute_cfa_program): Update to match API of leb128 functions.
	(read_1_byte, read_4_bytes, read_8_bytes): Make buf parameter
	"const gdb_byte *".
	(read_unsigned_leb128, read_signed_leb128): Delete.
	(read_initial_length): Change type of buf argument to
	"const gdb_byte *".
	(read_encoded_value): Update to match API of leb128 functions.
	(decode_frame_entry): Change result to "const gdb_byte *", and
	similarly for "start" parameter.
	(decode_frame_entry_1): Ditto.  Use new leb128 reader functions.
	(dwarf2_build_frame_info): Change local frame_ptr to
	"const gdb_byte *".
	* dwarf2expr.c (safe_read_uleb128, safe_read_sleb128): Replaces
	read_uleb128, read_sleb128.  All callers updated.
	(safe_skip_leb128): New function.
	(dwarf_block_to_dwarf_reg): Update to match API of leb128 functions.
	Call gdb_read_uleb128, gdb_skip_leb128 instead of read_uleb128.
	(dwarf_block_to_dwarf_reg_deref): Update to match API of leb128
	functions.  Call gdb_read_uleb128, gdb_read_sleb128 instead of
	read_uleb128, read_sleb128.
	(dwarf_block_to_fb_offset, dwarf_block_to_sp_offset): Ditto.
	(execute_stack_op): Update to match API of leb128 functions.
	* dwarf2expr.h: #include "leb128.h".
	(read_uleb128, read_sleb128): Delete.
	(gdb_read_uleb128, gdb_read_sleb128, gdb_skip_leb128): New functions.
	(safe_read_uleb128, safe_read_sleb128, safe_skip_leb128): Declare.
	* dwarf2loc.c (debug_loc_kind): New enum.
	(decode_debug_loc_addresses): New function.
	(decode_debug_loc_dwo_addresses): New function.
	(dwarf2_find_location_expression): Rewrite.
	(dwarf2_compile_expr_to_ax): Update to match API of leb128 functions.
	(locexpr_describe_location_piece): Ditto.
	(disassemble_dwarf_expression): Ditto.
	(locexpr_describe_location_1): Ditto.
	(loclist_describe_location): Rewrite.
	* dwarf2loc.h (dwarf2_loclist_baton): New member "from_dwo".
	* dwarf2read.c (die_reader_specs): New member "buffer_end".
	(dwarf2_section_buffer_overflow_complaint): Renamed from
	dwarf2_macros_too_long_complaint.  All callers updated.
	(skip_leb128): Delete.
	(init_cu_die_reader): Initialize reader->buffer_end.
	(skip_one_die): Replace call to skip_leb128 with safe_skip_leb128.
	(skip_form_bytes): New arg buffer_end.  All callers updated.
	Replace call to skip_leb128 with gdb_skip_leb128.
	(skip_unknown_opcode): New arg mac_end.  All callers updated.
	(fill_in_loclist_baton): Initialize baton->from_dwo.
This commit is contained in:
Doug Evans
2012-05-22 18:45:22 +00:00
parent dfc8a1a285
commit f664829eae
7 changed files with 528 additions and 364 deletions

View File

@@ -68,8 +68,8 @@ struct dwarf2_cie
ULONGEST return_address_register;
/* Instruction sequence to initialize a register set. */
gdb_byte *initial_instructions;
gdb_byte *end;
const gdb_byte *initial_instructions;
const gdb_byte *end;
/* Saved augmentation, in case it's needed later. */
char *augmentation;
@@ -116,8 +116,8 @@ struct dwarf2_fde
CORE_ADDR address_range;
/* Instruction sequence. */
gdb_byte *instructions;
gdb_byte *end;
const gdb_byte *instructions;
const gdb_byte *end;
/* True if this FDE is read from a .eh_frame instead of a .debug_frame
section. */
@@ -416,8 +416,8 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr,
while (insn_ptr < insn_end && fs->pc <= pc)
{
gdb_byte insn = *insn_ptr++;
ULONGEST utmp, reg;
LONGEST offset;
unsigned long long utmp, reg;
long long offset;
if ((insn & 0xc0) == DW_CFA_advance_loc)
fs->pc += (insn & 0x3f) * fs->code_align;
@@ -425,7 +425,7 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr,
{
reg = insn & 0x3f;
reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
offset = utmp * fs->data_align;
dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET;
@@ -467,9 +467,9 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr,
break;
case DW_CFA_offset_extended:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
offset = utmp * fs->data_align;
dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET;
@@ -477,28 +477,28 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr,
break;
case DW_CFA_restore_extended:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
dwarf2_restore_rule (gdbarch, reg, fs, eh_frame_p);
break;
case DW_CFA_undefined:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
fs->regs.reg[reg].how = DWARF2_FRAME_REG_UNDEFINED;
break;
case DW_CFA_same_value:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAME_VALUE;
break;
case DW_CFA_register:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
utmp = dwarf2_frame_adjust_regnum (gdbarch, utmp, eh_frame_p);
dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_REG;
@@ -536,8 +536,9 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"),
break;
case DW_CFA_def_cfa:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->regs.cfa_reg);
insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
fs->regs.cfa_reg = reg;
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
if (fs->armcc_cfa_offsets_sf)
utmp *= fs->data_align;
@@ -547,15 +548,14 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"),
break;
case DW_CFA_def_cfa_register:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->regs.cfa_reg);
fs->regs.cfa_reg = dwarf2_frame_adjust_regnum (gdbarch,
fs->regs.cfa_reg,
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
fs->regs.cfa_reg = dwarf2_frame_adjust_regnum (gdbarch, reg,
eh_frame_p);
fs->regs.cfa_how = CFA_REG_OFFSET;
break;
case DW_CFA_def_cfa_offset:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
if (fs->armcc_cfa_offsets_sf)
utmp *= fs->data_align;
@@ -568,18 +568,18 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"),
break;
case DW_CFA_def_cfa_expression:
insn_ptr = read_uleb128 (insn_ptr, insn_end,
&fs->regs.cfa_exp_len);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
fs->regs.cfa_exp_len = utmp;
fs->regs.cfa_exp = insn_ptr;
fs->regs.cfa_how = CFA_EXP;
insn_ptr += fs->regs.cfa_exp_len;
break;
case DW_CFA_expression:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
fs->regs.reg[reg].loc.exp = insn_ptr;
fs->regs.reg[reg].exp_len = utmp;
fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_EXP;
@@ -587,9 +587,9 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"),
break;
case DW_CFA_offset_extended_sf:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset);
insn_ptr = safe_read_sleb128 (insn_ptr, insn_end, &offset);
offset *= fs->data_align;
dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET;
@@ -597,27 +597,27 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"),
break;
case DW_CFA_val_offset:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
offset = utmp * fs->data_align;
fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_OFFSET;
fs->regs.reg[reg].loc.offset = offset;
break;
case DW_CFA_val_offset_sf:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset);
insn_ptr = safe_read_sleb128 (insn_ptr, insn_end, &offset);
offset *= fs->data_align;
fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_OFFSET;
fs->regs.reg[reg].loc.offset = offset;
break;
case DW_CFA_val_expression:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
fs->regs.reg[reg].loc.exp = insn_ptr;
fs->regs.reg[reg].exp_len = utmp;
fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_EXP;
@@ -625,17 +625,16 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"),
break;
case DW_CFA_def_cfa_sf:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->regs.cfa_reg);
fs->regs.cfa_reg = dwarf2_frame_adjust_regnum (gdbarch,
fs->regs.cfa_reg,
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
fs->regs.cfa_reg = dwarf2_frame_adjust_regnum (gdbarch, reg,
eh_frame_p);
insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset);
insn_ptr = safe_read_sleb128 (insn_ptr, insn_end, &offset);
fs->regs.cfa_offset = offset * fs->data_align;
fs->regs.cfa_how = CFA_REG_OFFSET;
break;
case DW_CFA_def_cfa_offset_sf:
insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset);
insn_ptr = safe_read_sleb128 (insn_ptr, insn_end, &offset);
fs->regs.cfa_offset = offset * fs->data_align;
/* cfa_how deliberately not set. */
break;
@@ -667,13 +666,13 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"),
case DW_CFA_GNU_args_size:
/* Ignored. */
insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
break;
case DW_CFA_GNU_negative_offset_extended:
insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
insn_ptr = read_uleb128 (insn_ptr, insn_end, &offset);
insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &offset);
offset *= fs->data_align;
dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET;
@@ -1501,82 +1500,26 @@ dwarf2_frame_cfa (struct frame_info *this_frame)
const struct objfile_data *dwarf2_frame_objfile_data;
static unsigned int
read_1_byte (bfd *abfd, gdb_byte *buf)
read_1_byte (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_8 (abfd, buf);
}
static unsigned int
read_4_bytes (bfd *abfd, gdb_byte *buf)
read_4_bytes (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_32 (abfd, buf);
}
static ULONGEST
read_8_bytes (bfd *abfd, gdb_byte *buf)
read_8_bytes (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_64 (abfd, buf);
}
static ULONGEST
read_unsigned_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
{
ULONGEST result;
unsigned int num_read;
int shift;
gdb_byte byte;
result = 0;
shift = 0;
num_read = 0;
do
{
byte = bfd_get_8 (abfd, (bfd_byte *) buf);
buf++;
num_read++;
result |= ((byte & 0x7f) << shift);
shift += 7;
}
while (byte & 0x80);
*bytes_read_ptr = num_read;
return result;
}
static LONGEST
read_signed_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
{
LONGEST result;
int shift;
unsigned int num_read;
gdb_byte byte;
result = 0;
shift = 0;
num_read = 0;
do
{
byte = bfd_get_8 (abfd, (bfd_byte *) buf);
buf++;
num_read++;
result |= ((byte & 0x7f) << shift);
shift += 7;
}
while (byte & 0x80);
if (shift < 8 * sizeof (result) && (byte & 0x40))
result |= -(((LONGEST)1) << shift);
*bytes_read_ptr = num_read;
return result;
}
static ULONGEST
read_initial_length (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
read_initial_length (bfd *abfd, const gdb_byte *buf,
unsigned int *bytes_read_ptr)
{
LONGEST result;
@@ -1685,10 +1628,10 @@ read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
{
case DW_EH_PE_uleb128:
{
ULONGEST value;
unsigned long long value;
const gdb_byte *end_buf = buf + (sizeof (value) + 1) * 8 / 7;
*bytes_read_ptr += read_uleb128 (buf, end_buf, &value) - buf;
*bytes_read_ptr += safe_read_uleb128 (buf, end_buf, &value) - buf;
return base + value;
}
case DW_EH_PE_udata2:
@@ -1702,10 +1645,10 @@ read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
return (base + bfd_get_64 (unit->abfd, (bfd_byte *) buf));
case DW_EH_PE_sleb128:
{
LONGEST value;
long long value;
const gdb_byte *end_buf = buf + (sizeof (value) + 1) * 8 / 7;
*bytes_read_ptr += read_sleb128 (buf, end_buf, &value) - buf;
*bytes_read_ptr += safe_read_sleb128 (buf, end_buf, &value) - buf;
return base + value;
}
case DW_EH_PE_sdata2:
@@ -1863,28 +1806,32 @@ enum eh_frame_type
EH_CIE_OR_FDE_TYPE_ID = EH_CIE_TYPE_ID | EH_FDE_TYPE_ID
};
static gdb_byte *decode_frame_entry (struct comp_unit *unit, gdb_byte *start,
int eh_frame_p,
struct dwarf2_cie_table *cie_table,
struct dwarf2_fde_table *fde_table,
enum eh_frame_type entry_type);
static const gdb_byte *decode_frame_entry (struct comp_unit *unit,
const gdb_byte *start,
int eh_frame_p,
struct dwarf2_cie_table *cie_table,
struct dwarf2_fde_table *fde_table,
enum eh_frame_type entry_type);
/* Decode the next CIE or FDE, entry_type specifies the expected type.
Return NULL if invalid input, otherwise the next byte to be processed. */
static gdb_byte *
decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p,
static const gdb_byte *
decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start,
int eh_frame_p,
struct dwarf2_cie_table *cie_table,
struct dwarf2_fde_table *fde_table,
enum eh_frame_type entry_type)
{
struct gdbarch *gdbarch = get_objfile_arch (unit->objfile);
gdb_byte *buf, *end;
const gdb_byte *buf, *end;
LONGEST length;
unsigned int bytes_read;
int dwarf64_p;
ULONGEST cie_id;
ULONGEST cie_pointer;
long long sleb128;
unsigned long long uleb128;
buf = start;
length = read_initial_length (unit->abfd, buf, &bytes_read);
@@ -2000,37 +1947,41 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p,
else
cie->ptr_size = cie->addr_size;
cie->code_alignment_factor =
read_unsigned_leb128 (unit->abfd, buf, &bytes_read);
buf += bytes_read;
buf = gdb_read_uleb128 (buf, end, &uleb128);
if (buf == NULL)
return NULL;
cie->code_alignment_factor = uleb128;
cie->data_alignment_factor =
read_signed_leb128 (unit->abfd, buf, &bytes_read);
buf += bytes_read;
buf = gdb_read_sleb128 (buf, end, &sleb128);
if (buf == NULL)
return NULL;
cie->data_alignment_factor = sleb128;
if (cie_version == 1)
{
cie->return_address_register = read_1_byte (unit->abfd, buf);
bytes_read = 1;
++buf;
}
else
cie->return_address_register = read_unsigned_leb128 (unit->abfd, buf,
&bytes_read);
{
buf = gdb_read_uleb128 (buf, end, &uleb128);
if (buf == NULL)
return NULL;
cie->return_address_register = uleb128;
}
cie->return_address_register
= dwarf2_frame_adjust_regnum (gdbarch,
cie->return_address_register,
eh_frame_p);
buf += bytes_read;
cie->saw_z_augmentation = (*augmentation == 'z');
if (cie->saw_z_augmentation)
{
ULONGEST length;
unsigned long long length;
length = read_unsigned_leb128 (unit->abfd, buf, &bytes_read);
buf += bytes_read;
if (buf > end)
buf = gdb_read_uleb128 (buf, end, &length);
if (buf == NULL)
return NULL;
cie->initial_instructions = buf + length;
augmentation++;
@@ -2144,10 +2095,12 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p,
can skip the whole thing. */
if (fde->cie->saw_z_augmentation)
{
ULONGEST length;
unsigned long long length;
length = read_unsigned_leb128 (unit->abfd, buf, &bytes_read);
buf += bytes_read + length;
buf = gdb_read_uleb128 (buf, end, &length);
if (buf == NULL)
return NULL;
buf += length;
if (buf > end)
return NULL;
}
@@ -2166,14 +2119,15 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p,
/* Read a CIE or FDE in BUF and decode it. Entry_type specifies whether we
expect an FDE or a CIE. */
static gdb_byte *
decode_frame_entry (struct comp_unit *unit, gdb_byte *start, int eh_frame_p,
static const gdb_byte *
decode_frame_entry (struct comp_unit *unit, const gdb_byte *start,
int eh_frame_p,
struct dwarf2_cie_table *cie_table,
struct dwarf2_fde_table *fde_table,
enum eh_frame_type entry_type)
{
enum { NONE, ALIGN4, ALIGN8, FAIL } workaround = NONE;
gdb_byte *ret;
const gdb_byte *ret;
ptrdiff_t start_offset;
while (1)
@@ -2285,7 +2239,7 @@ void
dwarf2_build_frame_info (struct objfile *objfile)
{
struct comp_unit *unit;
gdb_byte *frame_ptr;
const gdb_byte *frame_ptr;
struct dwarf2_cie_table cie_table;
struct dwarf2_fde_table fde_table;
struct dwarf2_fde_table *fde_table2;