aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2-frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2-frame.c')
-rw-r--r--gdb/dwarf2-frame.c224
1 files changed, 89 insertions, 135 deletions
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index 670e26f..96fa451 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -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;