diff options
author | Doug Evans <dje@google.com> | 2012-05-22 18:45:22 +0000 |
---|---|---|
committer | Doug Evans <dje@google.com> | 2012-05-22 18:45:22 +0000 |
commit | f664829eae5325405ce4e7f064c7be02352ce1f6 (patch) | |
tree | 2cbd8db92d387d8f924b1c6f0fed4e2977ff7e22 | |
parent | dfc8a1a28522a59bb4d3fc39a843b32469c6f7d5 (diff) | |
download | gdb-f664829eae5325405ce4e7f064c7be02352ce1f6.zip gdb-f664829eae5325405ce4e7f064c7be02352ce1f6.tar.gz gdb-f664829eae5325405ce4e7f064c7be02352ce1f6.tar.bz2 |
* 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.
-rw-r--r-- | gdb/ChangeLog | 52 | ||||
-rw-r--r-- | gdb/dwarf2-frame.c | 224 | ||||
-rw-r--r-- | gdb/dwarf2expr.c | 168 | ||||
-rw-r--r-- | gdb/dwarf2expr.h | 54 | ||||
-rw-r--r-- | gdb/dwarf2loc.c | 337 | ||||
-rw-r--r-- | gdb/dwarf2loc.h | 4 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 57 |
7 files changed, 530 insertions, 366 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 90cc26c..98ffd2f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,55 @@ +2012-05-22 Doug Evans <dje@google.com> + + * 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. + 2012-05-22 Maciej W. Rozycki <macro@codesourcery.com> * mips-linux-nat.c (mips_linux_read_description): Use a more 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; diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c index 83d8e04..80c6e17 100644 --- a/gdb/dwarf2expr.c +++ b/gdb/dwarf2expr.c @@ -369,60 +369,36 @@ dwarf_expr_eval (struct dwarf_expr_context *ctx, const gdb_byte *addr, gdb_assert (ctx->recursion_depth == old_recursion_depth); } -/* Decode the unsigned LEB128 constant at BUF into the variable pointed to - by R, and return the new value of BUF. Verify that it doesn't extend - past BUF_END. R can be NULL, the constant is then only skipped. */ +/* Helper to read a uleb128 value or throw an error. */ const gdb_byte * -read_uleb128 (const gdb_byte *buf, const gdb_byte *buf_end, ULONGEST * r) +safe_read_uleb128 (const gdb_byte *buf, const gdb_byte *buf_end, + unsigned long long *r) { - unsigned shift = 0; - ULONGEST result = 0; - gdb_byte byte; - - while (1) - { - if (buf >= buf_end) - error (_("read_uleb128: Corrupted DWARF expression.")); - - byte = *buf++; - result |= ((ULONGEST) (byte & 0x7f)) << shift; - if ((byte & 0x80) == 0) - break; - shift += 7; - } - if (r) - *r = result; + buf = gdb_read_uleb128 (buf, buf_end, r); + if (buf == NULL) + error (_("DWARF expression error: ran off end of buffer reading uleb128 value")); return buf; } -/* Decode the signed LEB128 constant at BUF into the variable pointed to - by R, and return the new value of BUF. Verify that it doesn't extend - past BUF_END. R can be NULL, the constant is then only skipped. */ +/* Helper to read a sleb128 value or throw an error. */ const gdb_byte * -read_sleb128 (const gdb_byte *buf, const gdb_byte *buf_end, LONGEST * r) +safe_read_sleb128 (const gdb_byte *buf, const gdb_byte *buf_end, + long long *r) { - unsigned shift = 0; - LONGEST result = 0; - gdb_byte byte; - - while (1) - { - if (buf >= buf_end) - error (_("read_sleb128: Corrupted DWARF expression.")); - - byte = *buf++; - result |= ((ULONGEST) (byte & 0x7f)) << shift; - shift += 7; - if ((byte & 0x80) == 0) - break; - } - if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0) - result |= -(((LONGEST) 1) << shift); + buf = gdb_read_sleb128 (buf, buf_end, r); + if (buf == NULL) + error (_("DWARF expression error: ran off end of buffer reading sleb128 value")); + return buf; +} - if (r) - *r = result; +const gdb_byte * +safe_skip_leb128 (const gdb_byte *buf, const gdb_byte *buf_end) +{ + buf = gdb_skip_leb128 (buf, buf_end); + if (buf == NULL) + error (_("DWARF expression error: ran off end of buffer reading leb128 value")); return buf; } @@ -489,7 +465,7 @@ dwarf_get_base_type (struct dwarf_expr_context *ctx, cu_offset die, int size) int dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end) { - ULONGEST dwarf_reg; + unsigned long long dwarf_reg; if (buf_end <= buf) return -1; @@ -503,13 +479,19 @@ dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end) if (*buf == DW_OP_GNU_regval_type) { buf++; - buf = read_uleb128 (buf, buf_end, &dwarf_reg); - buf = read_uleb128 (buf, buf_end, NULL); + buf = gdb_read_uleb128 (buf, buf_end, &dwarf_reg); + if (buf == NULL) + return -1; + buf = gdb_skip_leb128 (buf, buf_end); + if (buf == NULL) + return -1; } else if (*buf == DW_OP_regx) { buf++; - buf = read_uleb128 (buf, buf_end, &dwarf_reg); + buf = gdb_read_uleb128 (buf, buf_end, &dwarf_reg); + if (buf == NULL) + return -1; } else return -1; @@ -527,31 +509,35 @@ int dwarf_block_to_dwarf_reg_deref (const gdb_byte *buf, const gdb_byte *buf_end, CORE_ADDR *deref_size_return) { - ULONGEST dwarf_reg; - LONGEST offset; + unsigned long long dwarf_reg; + long long offset; if (buf_end <= buf) return -1; + if (*buf >= DW_OP_breg0 && *buf <= DW_OP_breg31) { dwarf_reg = *buf - DW_OP_breg0; buf++; + if (buf >= buf_end) + return -1; } else if (*buf == DW_OP_bregx) { buf++; - buf = read_uleb128 (buf, buf_end, &dwarf_reg); + buf = gdb_read_uleb128 (buf, buf_end, &dwarf_reg); + if (buf == NULL) + return -1; if ((int) dwarf_reg != dwarf_reg) return -1; } else return -1; - buf = read_sleb128 (buf, buf_end, &offset); - if (offset != 0) + buf = gdb_read_sleb128 (buf, buf_end, &offset); + if (buf == NULL) return -1; - - if (buf >= buf_end) + if (offset != 0) return -1; if (*buf == DW_OP_deref) @@ -582,7 +568,7 @@ int dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end, CORE_ADDR *fb_offset_return) { - LONGEST fb_offset; + long long fb_offset; if (buf_end <= buf) return 0; @@ -591,7 +577,9 @@ dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end, return 0; buf++; - buf = read_sleb128 (buf, buf_end, &fb_offset); + buf = gdb_read_sleb128 (buf, buf_end, &fb_offset); + if (buf == NULL) + return 0; *fb_offset_return = fb_offset; if (buf != buf_end || fb_offset != (LONGEST) *fb_offset_return) return 0; @@ -607,8 +595,8 @@ int dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf, const gdb_byte *buf_end, CORE_ADDR *sp_offset_return) { - ULONGEST dwarf_reg; - LONGEST sp_offset; + unsigned long long dwarf_reg; + long long sp_offset; if (buf_end <= buf) return 0; @@ -622,14 +610,18 @@ dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf, if (*buf != DW_OP_bregx) return 0; buf++; - buf = read_uleb128 (buf, buf_end, &dwarf_reg); + buf = gdb_read_uleb128 (buf, buf_end, &dwarf_reg); + if (buf == NULL) + return 0; } if (gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_reg) != gdbarch_sp_regnum (gdbarch)) return 0; - buf = read_sleb128 (buf, buf_end, &sp_offset); + buf = gdb_read_sleb128 (buf, buf_end, &sp_offset); + if (buf == NULL) + return 0; *sp_offset_return = sp_offset; if (buf != buf_end || sp_offset != (LONGEST) *sp_offset_return) return 0; @@ -673,8 +665,8 @@ execute_stack_op (struct dwarf_expr_context *ctx, This is just an optimization, so it's always ok to punt and leave this as 0. */ int in_stack_memory = 0; - ULONGEST uoffset, reg; - LONGEST offset; + unsigned long long uoffset, reg; + long long offset; struct value *result_val = NULL; /* The DWARF expression might have a bug causing an infinite @@ -733,7 +725,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, break; case DW_OP_GNU_addr_index: - op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); result = (ctx->funcs->get_addr_index) (ctx->baton, uoffset); result_val = value_from_ulongest (address_type, result); break; @@ -779,12 +771,12 @@ execute_stack_op (struct dwarf_expr_context *ctx, op_ptr += 8; break; case DW_OP_constu: - op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); result = uoffset; result_val = value_from_ulongest (address_type, result); break; case DW_OP_consts: - op_ptr = read_sleb128 (op_ptr, op_end, &offset); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); result = offset; result_val = value_from_ulongest (address_type, result); break; @@ -837,7 +829,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, break; case DW_OP_regx: - op_ptr = read_uleb128 (op_ptr, op_end, ®); + op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx"); result = reg; @@ -847,9 +839,9 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_implicit_value: { - ULONGEST len; + unsigned long long len; - op_ptr = read_uleb128 (op_ptr, op_end, &len); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &len); if (op_ptr + len > op_end) error (_("DW_OP_implicit_value: too few bytes available.")); ctx->len = len; @@ -868,7 +860,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_GNU_implicit_pointer: { - LONGEST len; + long long len; if (ctx->ref_addr_size == -1) error (_("DWARF-2 expression error: DW_OP_GNU_implicit_pointer " @@ -880,7 +872,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, op_ptr += ctx->ref_addr_size; /* The byte offset into the data. */ - op_ptr = read_sleb128 (op_ptr, op_end, &len); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &len); result = (ULONGEST) len; result_val = value_from_ulongest (address_type, result); @@ -923,7 +915,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_breg30: case DW_OP_breg31: { - op_ptr = read_sleb128 (op_ptr, op_end, &offset); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); result = (ctx->funcs->read_reg) (ctx->baton, op - DW_OP_breg0); result += offset; result_val = value_from_ulongest (address_type, result); @@ -931,8 +923,8 @@ execute_stack_op (struct dwarf_expr_context *ctx, break; case DW_OP_bregx: { - op_ptr = read_uleb128 (op_ptr, op_end, ®); - op_ptr = read_sleb128 (op_ptr, op_end, &offset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); result = (ctx->funcs->read_reg) (ctx->baton, reg); result += offset; result_val = value_from_ulongest (address_type, result); @@ -944,7 +936,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, size_t datalen; unsigned int before_stack_len; - op_ptr = read_sleb128 (op_ptr, op_end, &offset); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); /* Rather than create a whole new context, we simply record the stack length before execution, then reset it afterwards, effectively erasing whatever the recursive @@ -1038,7 +1030,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, { cu_offset type_die; - op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); type_die.cu_off = uoffset; type = dwarf_get_base_type (ctx, type_die, 0); } @@ -1089,7 +1081,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_plus_uconst: dwarf_require_integral (value_type (result_val)); result = value_as_long (result_val); - op_ptr = read_uleb128 (op_ptr, op_end, ®); + op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); result += reg; result_val = value_from_ulongest (address_type, result); break; @@ -1299,10 +1291,10 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_piece: { - ULONGEST size; + unsigned long long size; /* Record the piece. */ - op_ptr = read_uleb128 (op_ptr, op_end, &size); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &size); add_piece (ctx, 8 * size, 0); /* Pop off the address/regnum, and reset the location @@ -1316,11 +1308,11 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_bit_piece: { - ULONGEST size, offset; + unsigned long long size, offset; /* Record the piece. */ - op_ptr = read_uleb128 (op_ptr, op_end, &size); - op_ptr = read_uleb128 (op_ptr, op_end, &offset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &size); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &offset); add_piece (ctx, size, offset); /* Pop off the address/regnum, and reset the location @@ -1362,11 +1354,11 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_GNU_entry_value: { - ULONGEST len; + unsigned long long len; int dwarf_reg; CORE_ADDR deref_size; - op_ptr = read_uleb128 (op_ptr, op_end, &len); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &len); if (op_ptr + len > op_end) error (_("DW_OP_GNU_entry_value: too few bytes available.")); @@ -1405,7 +1397,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, const gdb_byte *data; struct type *type; - op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); type_die.cu_off = uoffset; n = *op_ptr++; data = op_ptr; @@ -1421,8 +1413,8 @@ execute_stack_op (struct dwarf_expr_context *ctx, cu_offset type_die; struct type *type; - op_ptr = read_uleb128 (op_ptr, op_end, ®); - op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); type_die.cu_off = uoffset; type = dwarf_get_base_type (ctx, type_die, 0); @@ -1439,7 +1431,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, cu_offset type_die; struct type *type; - op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); type_die.cu_off = uoffset; if (type_die.cu_off == 0) diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h index 3699dbb..82a5a93 100644 --- a/gdb/dwarf2expr.h +++ b/gdb/dwarf2expr.h @@ -23,6 +23,8 @@ #if !defined (DWARF2EXPR_H) #define DWARF2EXPR_H +#include "leb128.h" + struct dwarf_expr_context; /* Offset relative to the start of its containing CU (compilation unit). */ @@ -273,12 +275,6 @@ struct value *dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n); CORE_ADDR dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n); int dwarf_expr_fetch_in_stack_memory (struct dwarf_expr_context *ctx, int n); - -const gdb_byte *read_uleb128 (const gdb_byte *buf, const gdb_byte *buf_end, - ULONGEST * r); -const gdb_byte *read_sleb128 (const gdb_byte *buf, const gdb_byte *buf_end, - LONGEST * r); - void dwarf_expr_require_composition (const gdb_byte *, const gdb_byte *, const char *); @@ -310,4 +306,50 @@ int dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf, const gdb_byte *buf_end, CORE_ADDR *sp_offset_return); +/* Wrappers around the leb128 reader routines to simplify them for our + purposes. */ + +static inline const gdb_byte * +gdb_read_uleb128 (const gdb_byte *buf, const gdb_byte *buf_end, + unsigned long long *r) +{ + size_t bytes_read = read_uleb128_to_ull (buf, buf_end, r); + + if (bytes_read == 0) + return NULL; + return buf + bytes_read; +} + +static inline const gdb_byte * +gdb_read_sleb128 (const gdb_byte *buf, const gdb_byte *buf_end, + long long *r) +{ + size_t bytes_read = read_sleb128_to_ll (buf, buf_end, r); + + if (bytes_read == 0) + return NULL; + return buf + bytes_read; +} + +static inline const gdb_byte * +gdb_skip_leb128 (const gdb_byte *buf, const gdb_byte *buf_end) +{ + size_t bytes_read = skip_leb128 (buf, buf_end); + + if (bytes_read == 0) + return NULL; + return buf + bytes_read; +} + +extern const gdb_byte *safe_read_uleb128 (const gdb_byte *buf, + const gdb_byte *buf_end, + unsigned long long *r); + +extern const gdb_byte *safe_read_sleb128 (const gdb_byte *buf, + const gdb_byte *buf_end, + long long *r); + +extern const gdb_byte *safe_skip_leb128 (const gdb_byte *buf, + const gdb_byte *buf_end); + #endif /* dwarf2expr.h */ diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index c251b70..9bd7741 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -58,6 +58,121 @@ static struct value *dwarf2_evaluate_loc_desc_full (struct type *type, struct dwarf2_per_cu_data *per_cu, LONGEST byte_offset); +/* Until these have formal names, we define these here. + ref: http://gcc.gnu.org/wiki/DebugFission + Each entry in .debug_loc.dwo begins with a byte that describes the entry, + and is then followed by data specific to that entry. */ + +enum debug_loc_kind +{ + /* Indicates the end of the list of entries. */ + DEBUG_LOC_END_OF_LIST = 0, + + /* This is followed by an unsigned LEB128 number that is an index into + .debug_addr and specifies the base address for all following entries. */ + DEBUG_LOC_BASE_ADDRESS = 1, + + /* This is followed by two unsigned LEB128 numbers that are indices into + .debug_addr and specify the beginning and ending addresses, and then + a normal location expression as in .debug_loc. */ + DEBUG_LOC_NORMAL = 2, + + /* An internal value indicating there is insufficient data. */ + DEBUG_LOC_BUFFER_OVERFLOW = -1, + + /* An internal value indicating an invalid kind of entry was found. */ + DEBUG_LOC_INVALID_ENTRY = -2 +}; + +/* Decode the addresses in a non-dwo .debug_loc entry. + A pointer to the next byte to examine is returned in *NEW_PTR. + The encoded low,high addresses are return in *LOW,*HIGH. + The result indicates the kind of entry found. */ + +static enum debug_loc_kind +decode_debug_loc_addresses (const gdb_byte *loc_ptr, const gdb_byte *buf_end, + const gdb_byte **new_ptr, + CORE_ADDR *low, CORE_ADDR *high, + enum bfd_endian byte_order, + unsigned int addr_size, + int signed_addr_p) +{ + CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); + + if (buf_end - loc_ptr < 2 * addr_size) + return DEBUG_LOC_BUFFER_OVERFLOW; + + if (signed_addr_p) + *low = extract_signed_integer (loc_ptr, addr_size, byte_order); + else + *low = extract_unsigned_integer (loc_ptr, addr_size, byte_order); + loc_ptr += addr_size; + + if (signed_addr_p) + *high = extract_signed_integer (loc_ptr, addr_size, byte_order); + else + *high = extract_unsigned_integer (loc_ptr, addr_size, byte_order); + loc_ptr += addr_size; + + *new_ptr = loc_ptr; + + /* A base-address-selection entry. */ + if ((*low & base_mask) == base_mask) + return DEBUG_LOC_BASE_ADDRESS; + + /* An end-of-list entry. */ + if (*low == 0 && *high == 0) + return DEBUG_LOC_END_OF_LIST; + + return DEBUG_LOC_NORMAL; +} + +/* Decode the addresses in .debug_loc.dwo entry. + A pointer to the next byte to examine is returned in *NEW_PTR. + The encoded low,high addresses are return in *LOW,*HIGH. + The result indicates the kind of entry found. */ + +static enum debug_loc_kind +decode_debug_loc_dwo_addresses (struct dwarf2_per_cu_data *per_cu, + const gdb_byte *loc_ptr, + const gdb_byte *buf_end, + const gdb_byte **new_ptr, + CORE_ADDR *low, CORE_ADDR *high) +{ + unsigned long long low_index, high_index; + + if (loc_ptr == buf_end) + return DEBUG_LOC_BUFFER_OVERFLOW; + + switch (*loc_ptr++) + { + case DEBUG_LOC_END_OF_LIST: + *new_ptr = loc_ptr; + return DEBUG_LOC_END_OF_LIST; + case DEBUG_LOC_BASE_ADDRESS: + *low = 0; + loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &high_index); + if (loc_ptr == NULL) + return DEBUG_LOC_BUFFER_OVERFLOW; + *high = dwarf2_read_addr_index (per_cu, high_index); + *new_ptr = loc_ptr; + return DEBUG_LOC_BASE_ADDRESS; + case DEBUG_LOC_NORMAL: + loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &low_index); + if (loc_ptr == NULL) + return DEBUG_LOC_BUFFER_OVERFLOW; + *low = dwarf2_read_addr_index (per_cu, low_index); + loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &high_index); + if (loc_ptr == NULL) + return DEBUG_LOC_BUFFER_OVERFLOW; + *high = dwarf2_read_addr_index (per_cu, high_index); + *new_ptr = loc_ptr; + return DEBUG_LOC_NORMAL; + default: + return DEBUG_LOC_INVALID_ENTRY; + } +} + /* A function for dealing with location lists. Given a symbol baton (BATON) and a pc value (PC), find the appropriate location expression, set *LOCEXPR_LENGTH, and return a pointer @@ -70,52 +185,52 @@ const gdb_byte * dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton, size_t *locexpr_length, CORE_ADDR pc) { - CORE_ADDR low, high; - const gdb_byte *loc_ptr, *buf_end; - int length; struct objfile *objfile = dwarf2_per_cu_objfile (baton->per_cu); struct gdbarch *gdbarch = get_objfile_arch (objfile); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); unsigned int addr_size = dwarf2_per_cu_addr_size (baton->per_cu); int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd); - CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); /* Adjust base_address for relocatable objects. */ CORE_ADDR base_offset = dwarf2_per_cu_text_offset (baton->per_cu); CORE_ADDR base_address = baton->base_address + base_offset; + const gdb_byte *loc_ptr, *buf_end; loc_ptr = baton->data; buf_end = baton->data + baton->size; while (1) { - if (buf_end - loc_ptr < 2 * addr_size) - error (_("dwarf2_find_location_expression: " - "Corrupted DWARF expression.")); - - if (signed_addr_p) - low = extract_signed_integer (loc_ptr, addr_size, byte_order); - else - low = extract_unsigned_integer (loc_ptr, addr_size, byte_order); - loc_ptr += addr_size; - - if (signed_addr_p) - high = extract_signed_integer (loc_ptr, addr_size, byte_order); + CORE_ADDR low = 0, high = 0; /* init for gcc -Wall */ + int length; + enum debug_loc_kind kind; + const gdb_byte *new_ptr = NULL; /* init for gcc -Wall */ + + if (baton->from_dwo) + kind = decode_debug_loc_dwo_addresses (baton->per_cu, + loc_ptr, buf_end, &new_ptr, + &low, &high); else - high = extract_unsigned_integer (loc_ptr, addr_size, byte_order); - loc_ptr += addr_size; - - /* A base-address-selection entry. */ - if ((low & base_mask) == base_mask) - { - base_address = high + base_offset; - continue; - } - - /* An end-of-list entry. */ - if (low == 0 && high == 0) + kind = decode_debug_loc_addresses (loc_ptr, buf_end, &new_ptr, + &low, &high, + byte_order, addr_size, + signed_addr_p); + loc_ptr = new_ptr; + switch (kind) { + case DEBUG_LOC_END_OF_LIST: *locexpr_length = 0; return NULL; + case DEBUG_LOC_BASE_ADDRESS: + base_address = high + base_offset; + continue; + case DEBUG_LOC_NORMAL: + break; + case DEBUG_LOC_BUFFER_OVERFLOW: + case DEBUG_LOC_INVALID_ENTRY: + error (_("dwarf2_find_location_expression: " + "Corrupted DWARF expression.")); + default: + gdb_assert_not_reached ("bad debug_loc_kind"); } /* Otherwise, a location expression entry. */ @@ -2451,8 +2566,8 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, while (op_ptr < op_end) { enum dwarf_location_atom op = *op_ptr; - ULONGEST uoffset, reg; - LONGEST offset; + unsigned long long uoffset, reg; + long long offset; int i; offsets[op_ptr - base] = expr->len; @@ -2556,11 +2671,11 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, op_ptr += 8; break; case DW_OP_constu: - op_ptr = read_uleb128 (op_ptr, op_end, &uoffset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); ax_const_l (expr, uoffset); break; case DW_OP_consts: - op_ptr = read_sleb128 (op_ptr, op_end, &offset); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); ax_const_l (expr, offset); break; @@ -2602,7 +2717,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, break; case DW_OP_regx: - op_ptr = read_uleb128 (op_ptr, op_end, ®); + op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx"); loc->u.reg = translate_register (arch, reg); loc->kind = axs_lvalue_register; @@ -2610,9 +2725,9 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, case DW_OP_implicit_value: { - ULONGEST len; + unsigned long long len; - op_ptr = read_uleb128 (op_ptr, op_end, &len); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &len); if (op_ptr + len > op_end) error (_("DW_OP_implicit_value: too few bytes available.")); if (len > sizeof (ULONGEST)) @@ -2666,7 +2781,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: - op_ptr = read_sleb128 (op_ptr, op_end, &offset); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); i = translate_register (arch, op - DW_OP_breg0); ax_reg (expr, i); if (offset != 0) @@ -2677,8 +2792,8 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, break; case DW_OP_bregx: { - op_ptr = read_uleb128 (op_ptr, op_end, ®); - op_ptr = read_sleb128 (op_ptr, op_end, &offset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); i = translate_register (arch, reg); ax_reg (expr, i); if (offset != 0) @@ -2709,7 +2824,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, dwarf_expr_frame_base_1 (framefunc, expr->scope, &datastart, &datalen); - op_ptr = read_sleb128 (op_ptr, op_end, &offset); + op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size, datastart, datastart + datalen, per_cu); @@ -2810,7 +2925,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, break; case DW_OP_plus_uconst: - op_ptr = read_uleb128 (op_ptr, op_end, ®); + op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); /* It would be really weird to emit `DW_OP_plus_uconst 0', but we micro-optimize anyhow. */ if (reg != 0) @@ -2960,20 +3075,20 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, case DW_OP_piece: case DW_OP_bit_piece: { - ULONGEST size, offset; + unsigned long long size, offset; if (op_ptr - 1 == previous_piece) error (_("Cannot translate empty pieces to agent expressions")); previous_piece = op_ptr - 1; - op_ptr = read_uleb128 (op_ptr, op_end, &size); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &size); if (op == DW_OP_piece) { size *= 8; offset = 0; } else - op_ptr = read_uleb128 (op_ptr, op_end, &offset); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &offset); if (bits_collected + size > 8 * sizeof (LONGEST)) error (_("Expression pieces exceed word size")); @@ -3133,7 +3248,8 @@ locexpr_regname (struct gdbarch *gdbarch, int dwarf_regnum) /* Nicely describe a single piece of a location, returning an updated position in the bytecode sequence. This function cannot recognize all locations; if a location is not recognized, it simply returns - DATA. */ + DATA. If there is an error during reading, e.g. we run off the end + of the buffer, an error is thrown. */ static const gdb_byte * locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, @@ -3151,9 +3267,9 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, } else if (data[0] == DW_OP_regx) { - ULONGEST reg; + unsigned long long reg; - data = read_uleb128 (data + 1, end, ®); + data = safe_read_uleb128 (data + 1, end, ®); fprintf_filtered (stream, _("a variable in $%s"), locexpr_regname (gdbarch, reg)); } @@ -3162,12 +3278,12 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, struct block *b; struct symbol *framefunc; int frame_reg = 0; - LONGEST frame_offset; + long long frame_offset; const gdb_byte *base_data, *new_data, *save_data = data; size_t base_size; - LONGEST base_offset = 0; + long long base_offset = 0; - new_data = read_sleb128 (data + 1, end, &frame_offset); + new_data = safe_read_sleb128 (data + 1, end, &frame_offset); if (!piece_end_p (new_data, end)) return data; data = new_data; @@ -3191,8 +3307,8 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, const gdb_byte *buf_end; frame_reg = base_data[0] - DW_OP_breg0; - buf_end = read_sleb128 (base_data + 1, - base_data + base_size, &base_offset); + buf_end = safe_read_sleb128 (base_data + 1, base_data + base_size, + &base_offset); if (buf_end != base_data + base_size) error (_("Unexpected opcode after " "DW_OP_breg%u for symbol \"%s\"."), @@ -3219,9 +3335,9 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, else if (data[0] >= DW_OP_breg0 && data[0] <= DW_OP_breg31 && piece_end_p (data, end)) { - LONGEST offset; + long long offset; - data = read_sleb128 (data + 1, end, &offset); + data = safe_read_sleb128 (data + 1, end, &offset); fprintf_filtered (stream, _("a variable at offset %s from base reg $%s"), @@ -3276,7 +3392,9 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, /* Disassemble an expression, stopping at the end of a piece or at the end of the expression. Returns a pointer to the next unread byte in the input expression. If ALL is nonzero, then this function - will keep going until it reaches the end of the expression. */ + will keep going until it reaches the end of the expression. + If there is an error during reading, e.g. we run off the end + of the buffer, an error is thrown. */ static const gdb_byte * disassemble_dwarf_expression (struct ui_file *stream, @@ -3291,8 +3409,8 @@ disassemble_dwarf_expression (struct ui_file *stream, || (data[0] != DW_OP_piece && data[0] != DW_OP_bit_piece))) { enum dwarf_location_atom op = *data++; - ULONGEST ul; - LONGEST l; + unsigned long long ul; + long long l; const char *name; name = get_DW_OP_name (op); @@ -3353,11 +3471,11 @@ disassemble_dwarf_expression (struct ui_file *stream, fprintf_filtered (stream, " %s", plongest (l)); break; case DW_OP_constu: - data = read_uleb128 (data, end, &ul); + data = safe_read_uleb128 (data, end, &ul); fprintf_filtered (stream, " %s", pulongest (ul)); break; case DW_OP_consts: - data = read_sleb128 (data, end, &l); + data = safe_read_sleb128 (data, end, &l); fprintf_filtered (stream, " %s", plongest (l)); break; @@ -3398,13 +3516,13 @@ disassemble_dwarf_expression (struct ui_file *stream, break; case DW_OP_regx: - data = read_uleb128 (data, end, &ul); + data = safe_read_uleb128 (data, end, &ul); fprintf_filtered (stream, " %s [$%s]", pulongest (ul), locexpr_regname (arch, (int) ul)); break; case DW_OP_implicit_value: - data = read_uleb128 (data, end, &ul); + data = safe_read_uleb128 (data, end, &ul); data += ul; fprintf_filtered (stream, " %s", pulongest (ul)); break; @@ -3441,14 +3559,14 @@ disassemble_dwarf_expression (struct ui_file *stream, case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: - data = read_sleb128 (data, end, &l); + data = safe_read_sleb128 (data, end, &l); fprintf_filtered (stream, " %s [$%s]", plongest (l), locexpr_regname (arch, op - DW_OP_breg0)); break; case DW_OP_bregx: - data = read_uleb128 (data, end, &ul); - data = read_sleb128 (data, end, &l); + data = safe_read_uleb128 (data, end, &ul); + data = safe_read_sleb128 (data, end, &l); fprintf_filtered (stream, " register %s [$%s] offset %s", pulongest (ul), locexpr_regname (arch, (int) ul), @@ -3456,7 +3574,7 @@ disassemble_dwarf_expression (struct ui_file *stream, break; case DW_OP_fbreg: - data = read_sleb128 (data, end, &l); + data = safe_read_sleb128 (data, end, &l); fprintf_filtered (stream, " %s", plongest (l)); break; @@ -3468,7 +3586,7 @@ disassemble_dwarf_expression (struct ui_file *stream, break; case DW_OP_plus_uconst: - data = read_uleb128 (data, end, &ul); + data = safe_read_uleb128 (data, end, &ul); fprintf_filtered (stream, " %s", pulongest (ul)); break; @@ -3506,16 +3624,16 @@ disassemble_dwarf_expression (struct ui_file *stream, break; case DW_OP_piece: - data = read_uleb128 (data, end, &ul); + data = safe_read_uleb128 (data, end, &ul); fprintf_filtered (stream, " %s (bytes)", pulongest (ul)); break; case DW_OP_bit_piece: { - ULONGEST offset; + unsigned long long offset; - data = read_uleb128 (data, end, &ul); - data = read_uleb128 (data, end, &offset); + data = safe_read_uleb128 (data, end, &ul); + data = safe_read_uleb128 (data, end, &offset); fprintf_filtered (stream, " size %s offset %s (bits)", pulongest (ul), pulongest (offset)); } @@ -3527,7 +3645,7 @@ disassemble_dwarf_expression (struct ui_file *stream, gdbarch_byte_order (arch)); data += offset_size; - data = read_sleb128 (data, end, &l); + data = safe_read_sleb128 (data, end, &l); fprintf_filtered (stream, " DIE %s offset %s", phex_nz (ul, offset_size), @@ -3541,7 +3659,7 @@ disassemble_dwarf_expression (struct ui_file *stream, cu_offset offset; struct type *type; - data = read_uleb128 (data, end, &ul); + data = safe_read_uleb128 (data, end, &ul); offset.cu_off = ul; type = dwarf2_get_die_type (offset, per_cu); fprintf_filtered (stream, "<"); @@ -3556,7 +3674,7 @@ disassemble_dwarf_expression (struct ui_file *stream, cu_offset type_die; struct type *type; - data = read_uleb128 (data, end, &ul); + data = safe_read_uleb128 (data, end, &ul); type_die.cu_off = ul; type = dwarf2_get_die_type (type_die, per_cu); fprintf_filtered (stream, "<"); @@ -3567,12 +3685,12 @@ disassemble_dwarf_expression (struct ui_file *stream, case DW_OP_GNU_regval_type: { - ULONGEST reg; + unsigned long long reg; cu_offset type_die; struct type *type; - data = read_uleb128 (data, end, ®); - data = read_uleb128 (data, end, &ul); + data = safe_read_uleb128 (data, end, ®); + data = safe_read_uleb128 (data, end, &ul); type_die.cu_off = ul; type = dwarf2_get_die_type (type_die, per_cu); @@ -3589,7 +3707,7 @@ disassemble_dwarf_expression (struct ui_file *stream, { cu_offset type_die; - data = read_uleb128 (data, end, &ul); + data = safe_read_uleb128 (data, end, &ul); type_die.cu_off = ul; if (type_die.cu_off == 0) @@ -3607,7 +3725,7 @@ disassemble_dwarf_expression (struct ui_file *stream, break; case DW_OP_GNU_entry_value: - data = read_uleb128 (data, end, &ul); + data = safe_read_uleb128 (data, end, &ul); fputc_filtered ('\n', stream); disassemble_dwarf_expression (stream, arch, addr_size, offset_size, start, data, data + ul, indent + 2, @@ -3676,9 +3794,9 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr, fprintf_filtered (stream, " "); if (data[0] == DW_OP_piece) { - ULONGEST bytes; + unsigned long long bytes; - data = read_uleb128 (data + 1, end, &bytes); + data = safe_read_uleb128 (data + 1, end, &bytes); if (empty) fprintf_filtered (stream, _("an empty %s-byte piece"), @@ -3689,10 +3807,10 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr, } else if (data[0] == DW_OP_bit_piece) { - ULONGEST bits, offset; + unsigned long long bits, offset; - data = read_uleb128 (data + 1, end, &bits); - data = read_uleb128 (data, end, &offset); + data = safe_read_uleb128 (data + 1, end, &bits); + data = safe_read_uleb128 (data, end, &offset); if (empty) fprintf_filtered (stream, @@ -3832,19 +3950,18 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr, struct ui_file *stream) { struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); - CORE_ADDR low, high; const gdb_byte *loc_ptr, *buf_end; - int length, first = 1; + int first = 1; struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu); struct gdbarch *gdbarch = get_objfile_arch (objfile); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); unsigned int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu); int offset_size = dwarf2_per_cu_offset_size (dlbaton->per_cu); int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd); - CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); /* Adjust base_address for relocatable objects. */ CORE_ADDR base_offset = dwarf2_per_cu_text_offset (dlbaton->per_cu); CORE_ADDR base_address = dlbaton->base_address + base_offset; + int done = 0; loc_ptr = dlbaton->data; buf_end = dlbaton->data + dlbaton->size; @@ -3852,37 +3969,43 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr, fprintf_filtered (stream, _("multi-location:\n")); /* Iterate through locations until we run out. */ - while (1) + while (!done) { - if (buf_end - loc_ptr < 2 * addr_size) - error (_("Corrupted DWARF expression for symbol \"%s\"."), - SYMBOL_PRINT_NAME (symbol)); - - if (signed_addr_p) - low = extract_signed_integer (loc_ptr, addr_size, byte_order); - else - low = extract_unsigned_integer (loc_ptr, addr_size, byte_order); - loc_ptr += addr_size; - - if (signed_addr_p) - high = extract_signed_integer (loc_ptr, addr_size, byte_order); + CORE_ADDR low = 0, high = 0; /* init for gcc -Wall */ + int length; + enum debug_loc_kind kind; + const gdb_byte *new_ptr = NULL; /* init for gcc -Wall */ + + if (dlbaton->from_dwo) + kind = decode_debug_loc_dwo_addresses (dlbaton->per_cu, + loc_ptr, buf_end, &new_ptr, + &low, &high); else - high = extract_unsigned_integer (loc_ptr, addr_size, byte_order); - loc_ptr += addr_size; - - /* A base-address-selection entry. */ - if ((low & base_mask) == base_mask) + kind = decode_debug_loc_addresses (loc_ptr, buf_end, &new_ptr, + &low, &high, + byte_order, addr_size, + signed_addr_p); + loc_ptr = new_ptr; + switch (kind) { + case DEBUG_LOC_END_OF_LIST: + done = 1; + continue; + case DEBUG_LOC_BASE_ADDRESS: base_address = high + base_offset; fprintf_filtered (stream, _(" Base address %s"), paddress (gdbarch, base_address)); continue; + case DEBUG_LOC_NORMAL: + break; + case DEBUG_LOC_BUFFER_OVERFLOW: + case DEBUG_LOC_INVALID_ENTRY: + error (_("Corrupted DWARF expression for symbol \"%s\"."), + SYMBOL_PRINT_NAME (symbol)); + default: + gdb_assert_not_reached ("bad debug_loc_kind"); } - /* An end-of-list entry. */ - if (low == 0 && high == 0) - break; - /* Otherwise, a location expression entry. */ low += base_address; high += base_address; diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h index 370402e..e9d06a3 100644 --- a/gdb/dwarf2loc.h +++ b/gdb/dwarf2loc.h @@ -119,6 +119,10 @@ struct dwarf2_loclist_baton /* The compilation unit containing the symbol whose location we're computing. */ struct dwarf2_per_cu_data *per_cu; + + /* Non-zero if the location list lives in .debug_loc.dwo. + The format of entries in this section are different. */ + unsigned char from_dwo; }; extern const struct symbol_computed_ops dwarf2_locexpr_funcs; diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 6ddf236..b590134 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -606,6 +606,9 @@ struct die_reader_specs /* die_section->buffer. */ gdb_byte *buffer; + + /* The end of the buffer. */ + const gdb_byte *buffer_end; }; /* Type of function passed to init_cutu_and_read_dies, et.al. */ @@ -968,11 +971,13 @@ dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2, } static void -dwarf2_macros_too_long_complaint (struct dwarf2_section_info *section) +dwarf2_section_buffer_overflow_complaint (struct dwarf2_section_info *section) { complaint (&symfile_complaints, - _("macro info runs off end of `%s' section"), - section->asection->name); + _("debug info runs off end of %s section" + " [in module %s]"), + section->asection->name, + bfd_get_filename (section->asection->owner)); } static void @@ -1104,8 +1109,6 @@ static CORE_ADDR read_addr_index_from_leb128 (struct dwarf2_cu *, gdb_byte *, static char *read_str_index (const struct die_reader_specs *reader, struct dwarf2_cu *cu, ULONGEST str_index); -static gdb_byte *skip_leb128 (bfd *, gdb_byte *); - static void set_cu_language (unsigned int, struct dwarf2_cu *); static struct attribute *dwarf2_attr (struct die_info *, unsigned int, @@ -3656,6 +3659,7 @@ init_cu_die_reader (struct die_reader_specs *reader, reader->dwo_file = dwo_file; reader->die_section = section; reader->buffer = section->buffer; + reader->buffer_end = section->buffer + section->size; } /* Find the base address of the compilation unit for range lists and @@ -5034,6 +5038,8 @@ skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr, bfd *abfd = reader->abfd; struct dwarf2_cu *cu = reader->cu; gdb_byte *buffer = reader->buffer; + const gdb_byte *buffer_end = reader->buffer_end; + gdb_byte *start_info_ptr = info_ptr; unsigned int form, i; for (i = 0; i < abbrev->num_attrs; i++) @@ -5112,7 +5118,7 @@ skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr, case DW_FORM_ref_udata: case DW_FORM_GNU_addr_index: case DW_FORM_GNU_str_index: - info_ptr = skip_leb128 (abfd, info_ptr); + info_ptr = (gdb_byte *) safe_skip_leb128 (info_ptr, buffer_end); break; case DW_FORM_indirect: form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); @@ -12273,22 +12279,6 @@ read_str_index (const struct die_reader_specs *reader, return (char *) (sections->str.buffer + str_offset); } -/* Return a pointer to just past the end of an LEB128 number in BUF. */ - -static gdb_byte * -skip_leb128 (bfd *abfd, gdb_byte *buf) -{ - int byte; - - while (1) - { - byte = bfd_get_8 (abfd, buf); - buf++; - if ((byte & 128) == 0) - return buf; - } -} - /* Return the length of an LEB128 number in BUF. */ static int @@ -15783,7 +15773,7 @@ parse_macro_definition (struct macro_source_file *file, int line, Returns the new pointer. */ static gdb_byte * -skip_form_bytes (bfd *abfd, gdb_byte *bytes, +skip_form_bytes (bfd *abfd, gdb_byte *bytes, gdb_byte *buffer_end, enum dwarf_form form, unsigned int offset_size, struct dwarf2_section_info *section) @@ -15838,7 +15828,12 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes, case DW_FORM_udata: case DW_FORM_GNU_addr_index: case DW_FORM_GNU_str_index: - bytes = skip_leb128 (abfd, bytes); + bytes = (gdb_byte *) gdb_skip_leb128 (bytes, buffer_end); + if (bytes == NULL) + { + dwarf2_section_buffer_overflow_complaint (section); + return NULL; + } break; default: @@ -15862,7 +15857,7 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes, static gdb_byte * skip_unknown_opcode (unsigned int opcode, gdb_byte **opcode_definitions, - gdb_byte *mac_ptr, + gdb_byte *mac_ptr, gdb_byte *mac_end, bfd *abfd, unsigned int offset_size, struct dwarf2_section_info *section) @@ -15885,7 +15880,8 @@ skip_unknown_opcode (unsigned int opcode, for (i = 0; i < arg; ++i) { - mac_ptr = skip_form_bytes (abfd, mac_ptr, defn[i], offset_size, section); + mac_ptr = skip_form_bytes (abfd, mac_ptr, mac_end, defn[i], offset_size, + section); if (mac_ptr == NULL) { /* skip_form_bytes already issued the complaint. */ @@ -15996,7 +15992,7 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, /* Do we at least have room for a macinfo type byte? */ if (mac_ptr >= mac_end) { - dwarf2_macros_too_long_complaint (section); + dwarf2_section_buffer_overflow_complaint (section); break; } @@ -16123,7 +16119,7 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, /* Do we at least have room for a macinfo type byte? */ if (mac_ptr >= mac_end) { - dwarf2_macros_too_long_complaint (section); + dwarf2_section_buffer_overflow_complaint (section); return; } @@ -16191,7 +16187,7 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, default: mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions, - mac_ptr, abfd, offset_size, + mac_ptr, mac_end, abfd, offset_size, section); if (mac_ptr == NULL) return; @@ -16334,7 +16330,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, default: mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions, - mac_ptr, abfd, offset_size, + mac_ptr, mac_end, abfd, offset_size, section); if (mac_ptr == NULL) return; @@ -16450,6 +16446,7 @@ fill_in_loclist_baton (struct dwarf2_cu *cu, baton->size = section->size - DW_UNSND (attr); baton->data = section->buffer + DW_UNSND (attr); baton->base_address = cu->base_address; + baton->from_dwo = cu->dwo_unit != NULL; } static void |