diff options
Diffstat (limited to 'gdb/dwarf2-frame.c')
-rw-r--r-- | gdb/dwarf2-frame.c | 224 |
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, ®); + insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); 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, ®); + insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); dwarf2_restore_rule (gdbarch, reg, fs, eh_frame_p); break; case DW_CFA_undefined: - insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); 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, ®); + insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); 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, ®); + insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); 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, ®); + 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, ®); + 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, ®); + insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); 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, ®); + insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); 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, ®); + insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); 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, ®); + insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); 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, ®); + insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); 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, ®); + 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, ®); + insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); 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; |