diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/dwarf2/expr.c | 74 | ||||
-rw-r--r-- | gdb/dwarf2/expr.h | 31 | ||||
-rw-r--r-- | gdb/dwarf2/frame.c | 36 | ||||
-rw-r--r-- | gdb/dwarf2/loc.c | 55 |
4 files changed, 91 insertions, 105 deletions
diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index aa166b2..0e992c1 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "defs.h" +#include "block.h" #include "symtab.h" #include "gdbtypes.h" #include "value.h" @@ -56,6 +57,27 @@ dwarf_gdbarch_types_init (struct gdbarch *gdbarch) return types; } +/* Ensure that a FRAME is defined, throw an exception otherwise. */ + +static void +ensure_have_frame (frame_info *frame, const char *op_name) +{ + if (frame == nullptr) + throw_error (GENERIC_ERROR, + _("%s evaluation requires a frame."), op_name); +} + +/* See expr.h. */ + +CORE_ADDR +read_addr_from_reg (frame_info *frame, int reg) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + int regnum = dwarf_reg_to_regnum_or_error (gdbarch, reg); + + return address_from_register (regnum, frame); +} + /* Return the type used for DWARF operations where the type is unspecified in the DWARF spec. Only certain sizes are supported. */ @@ -133,6 +155,47 @@ dwarf_expr_context::fetch (int n) return stack[stack.size () - (1 + n)].value; } +/* See expr.h. */ + +struct value * +dwarf_expr_context::get_reg_value (struct type *type, int reg) +{ + ensure_have_frame (this->frame, "DW_OP_regval_type"); + + struct gdbarch *gdbarch = get_frame_arch (this->frame); + int regnum = dwarf_reg_to_regnum_or_error (gdbarch, reg); + + return value_from_register (type, regnum, this->frame); +} + +/* See expr.h. */ + +void +dwarf_expr_context::get_frame_base (const gdb_byte **start, + size_t * length) +{ + ensure_have_frame (this->frame, "DW_OP_fbreg"); + + const block *bl = get_frame_block (this->frame, NULL); + + if (bl == NULL) + error (_("frame address is not available.")); + + /* Use block_linkage_function, which returns a real (not inlined) + function, instead of get_frame_function, which may return an + inlined function. */ + symbol *framefunc = block_linkage_function (bl); + + /* If we found a frame-relative symbol then it was certainly within + some function associated with a frame. If we can't find the frame, + something has gone wrong. */ + gdb_assert (framefunc != NULL); + + func_get_frame_base_dwarf_block (framefunc, + get_frame_address_in_block (this->frame), + start, length); +} + /* Require that TYPE be an integral type; throw an exception if not. */ static void @@ -821,7 +884,9 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, case DW_OP_breg31: { op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); - result = this->read_addr_from_reg (op - DW_OP_breg0); + ensure_have_frame (this->frame, "DW_OP_breg"); + + result = read_addr_from_reg (this->frame, op - DW_OP_breg0); result += offset; result_val = value_from_ulongest (address_type, result); } @@ -830,7 +895,9 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, { op_ptr = safe_read_uleb128 (op_ptr, op_end, ®); op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); - result = this->read_addr_from_reg (reg); + ensure_have_frame (this->frame, "DW_OP_bregx"); + + result = read_addr_from_reg (this->frame, reg); result += offset; result_val = value_from_ulongest (address_type, result); } @@ -857,7 +924,8 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, if (this->location == DWARF_VALUE_MEMORY) result = fetch_address (0); else if (this->location == DWARF_VALUE_REGISTER) - result = this->read_addr_from_reg (value_as_long (fetch (0))); + result + = read_addr_from_reg (this->frame, value_as_long (fetch (0))); else error (_("Not implemented: computing frame " "base using explicit value operator")); diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h index 60021eb..b227690 100644 --- a/gdb/dwarf2/expr.h +++ b/gdb/dwarf2/expr.h @@ -186,24 +186,12 @@ struct dwarf_expr_context /* We evaluate the expression in the context of this objfile. */ dwarf2_per_objfile *per_objfile; - /* Return the value of register number REGNUM (a DWARF register number), - read as an address. */ - virtual CORE_ADDR read_addr_from_reg (int regnum) = 0; - - /* Return a value of type TYPE, stored in register number REGNUM - of the frame associated to the given BATON. - - REGNUM is a DWARF register number. */ - virtual struct value *get_reg_value (struct type *type, int regnum) = 0; + /* Frame information used for the evaluation. */ + frame_info *frame = nullptr; /* Read LENGTH bytes at ADDR into BUF. */ virtual void read_mem (gdb_byte *buf, CORE_ADDR addr, size_t length) = 0; - /* Return the location expression for the frame base attribute, in - START and LENGTH. The result must be live until the current - expression evaluation is complete. */ - virtual void get_frame_base (const gdb_byte **start, size_t *length) = 0; - /* Return the CFA for the frame. */ virtual CORE_ADDR get_frame_cfa () = 0; @@ -259,8 +247,23 @@ private: void add_piece (ULONGEST size, ULONGEST offset); void execute_stack_op (const gdb_byte *op_ptr, const gdb_byte *op_end); void pop (); + + /* Return a value of type TYPE, stored in register number REGNUM + in a current context. + + REGNUM is a DWARF register number. */ + struct value *get_reg_value (struct type *type, int regnum); + + /* Return the location expression for the frame base attribute, in + START and LENGTH. The result must be live until the current + expression evaluation is complete. */ + void get_frame_base (const gdb_byte **start, size_t *length); }; +/* Return the value of register number REG (a DWARF register number), + read as an address in a given FRAME. */ +CORE_ADDR read_addr_from_reg (frame_info *frame, int reg); + void dwarf_expr_require_composition (const gdb_byte *, const gdb_byte *, const char *); diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c index 8d24559..19915df 100644 --- a/gdb/dwarf2/frame.c +++ b/gdb/dwarf2/frame.c @@ -192,18 +192,6 @@ dwarf2_frame_state::dwarf2_frame_state (CORE_ADDR pc_, struct dwarf2_cie *cie) retaddr_column (cie->return_address_register) { } - - -/* Helper functions for execute_stack_op. */ - -static CORE_ADDR -read_addr_from_reg (struct frame_info *this_frame, int reg) -{ - struct gdbarch *gdbarch = get_frame_arch (this_frame); - int regnum = dwarf_reg_to_regnum_or_error (gdbarch, reg); - - return address_from_register (regnum, this_frame); -} /* Execute the required actions for both the DW_CFA_restore and DW_CFA_restore_extended instructions. */ @@ -244,31 +232,11 @@ public: : dwarf_expr_context (per_objfile) {} - struct frame_info *this_frame; - - CORE_ADDR read_addr_from_reg (int reg) override - { - return ::read_addr_from_reg (this_frame, reg); - } - - struct value *get_reg_value (struct type *type, int reg) override - { - struct gdbarch *gdbarch = get_frame_arch (this_frame); - int regnum = dwarf_reg_to_regnum_or_error (gdbarch, reg); - - return value_from_register (type, regnum, this_frame); - } - void read_mem (gdb_byte *buf, CORE_ADDR addr, size_t len) override { read_memory (addr, buf, len); } - void get_frame_base (const gdb_byte **start, size_t *length) override - { - invalid ("DW_OP_fbreg"); - } - void push_dwarf_reg_entry_value (enum call_site_parameter_kind kind, union call_site_parameter_u kind_u, int deref_size) override @@ -324,7 +292,7 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size, dwarf_expr_executor ctx (per_objfile); scoped_value_mark free_values; - ctx.this_frame = this_frame; + ctx.frame = this_frame; ctx.gdbarch = get_frame_arch (this_frame); ctx.addr_size = addr_size; ctx.ref_addr_size = -1; @@ -335,7 +303,7 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size, if (ctx.location == DWARF_VALUE_MEMORY) result = ctx.fetch_address (0); else if (ctx.location == DWARF_VALUE_REGISTER) - result = ctx.read_addr_from_reg (value_as_long (ctx.fetch (0))); + result = read_addr_from_reg (this_frame, value_as_long (ctx.fetch (0))); else { /* This is actually invalid DWARF, but if we ever do run across diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c index cf52b1e..d004ea5 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -696,7 +696,6 @@ public: : dwarf_expr_context (per_objfile) {} - struct frame_info *frame; struct dwarf2_per_cu_data *per_cu; CORE_ADDR obj_address; @@ -822,64 +821,12 @@ public: this->eval (data_src, size); } - /* Using the frame specified in BATON, find the location expression - describing the frame base. Return a pointer to it in START and - its length in LENGTH. */ - void get_frame_base (const gdb_byte **start, size_t * length) override - { - if (frame == nullptr) - error (_("frame address is not available.")); - - /* FIXME: cagney/2003-03-26: This code should be using - get_frame_base_address(), and then implement a dwarf2 specific - this_base method. */ - struct symbol *framefunc; - const struct block *bl = get_frame_block (frame, NULL); - - if (bl == NULL) - error (_("frame address is not available.")); - - /* Use block_linkage_function, which returns a real (not inlined) - function, instead of get_frame_function, which may return an - inlined function. */ - framefunc = block_linkage_function (bl); - - /* If we found a frame-relative symbol then it was certainly within - some function associated with a frame. If we can't find the frame, - something has gone wrong. */ - gdb_assert (framefunc != NULL); - - func_get_frame_base_dwarf_block (framefunc, - get_frame_address_in_block (frame), - start, length); - } - /* Read memory at ADDR (length LEN) into BUF. */ void read_mem (gdb_byte *buf, CORE_ADDR addr, size_t len) override { read_memory (addr, buf, len); } - - /* Using the frame specified in BATON, return the value of register - REGNUM, treated as a pointer. */ - CORE_ADDR read_addr_from_reg (int dwarf_regnum) override - { - struct gdbarch *gdbarch = get_frame_arch (frame); - int regnum = dwarf_reg_to_regnum_or_error (gdbarch, dwarf_regnum); - - return address_from_register (regnum, frame); - } - - /* Implement "get_reg_value" callback. */ - - struct value *get_reg_value (struct type *type, int dwarf_regnum) override - { - struct gdbarch *gdbarch = get_frame_arch (frame); - int regnum = dwarf_reg_to_regnum_or_error (gdbarch, dwarf_regnum); - - return value_from_register (type, regnum, frame); - } }; /* See dwarf2loc.h. */ @@ -2600,7 +2547,7 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton, case DWARF_VALUE_MEMORY: *valp = ctx.fetch_address (0); if (ctx.location == DWARF_VALUE_REGISTER) - *valp = ctx.read_addr_from_reg (*valp); + *valp = read_addr_from_reg (frame, *valp); return 1; case DWARF_VALUE_LITERAL: *valp = extract_signed_integer (ctx.data, ctx.len, |