aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r--gdb/dwarf2/expr.c78
-rw-r--r--gdb/dwarf2/loc.c2
2 files changed, 80 insertions, 0 deletions
diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index 66bb8dd..c9c8f3a 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -2837,6 +2837,21 @@ private:
void create_select_composite (const loc_offset &piece_size,
ULONGEST pieces_count);
+ /* It pops two stack entries. First must be a location description
+ that represents the overlay location description. The Second
+ must be a location description that represents the base location
+ description. The OVERLAY_SIZE represents the size of the overlay
+ piece of the composite and the OVERLAY_OFFSET represent a starting
+ point of the overlay from the base location.
+
+ A complete composite location description created with parts from
+ base location description, overlayed by the overlay location
+ description, starting from the overlay offset, ending at
+ a sum of the overlay offset and overlay size, is pushed
+ on top of the DWARF stack. */
+ void create_overlay_composite (loc_offset overlay_size,
+ loc_offset overlay_offset);
+
/* The engine for the expression evaluator. Using the context in this
object, evaluate the expression between OP_PTR and OP_END. */
void execute_stack_op (const gdb_byte *op_ptr, const gdb_byte *op_end);
@@ -3279,6 +3294,38 @@ dwarf_expr_context::create_select_composite (const loc_offset &piece_size,
}
void
+dwarf_expr_context::create_overlay_composite (loc_offset overlay_size,
+ loc_offset overlay_offset)
+{
+ gdbarch *arch = this->m_per_objfile->objfile->arch ();
+
+ if (stack_empty_p ())
+ ill_formed_expression ();
+
+ dwarf_location_up overlay = to_location (pop (), arch);
+
+ if (stack_empty_p ())
+ ill_formed_expression ();
+
+ dwarf_location_up base = to_location (pop (), arch);
+
+ std::unique_ptr<dwarf_composite> composite
+ = make_unique<dwarf_composite> (arch, this->m_per_cu);
+
+ composite->add_piece (std::move (base->slice (0, overlay_offset)),
+ overlay_offset);
+ composite->add_piece (std::move (overlay), overlay_size);
+
+ loc_offset end_offset = overlay_offset + overlay_size;
+ loc_offset end_size = base->size () - end_offset;
+
+ composite->add_piece
+ (std::move (base->slice (end_offset, end_size)), end_size);
+ composite->set_completed (true);
+ push (std::move (composite));
+}
+
+void
dwarf_expr_context::eval (const gdb_byte *addr, size_t len)
{
int old_recursion_depth = this->m_recursion_depth;
@@ -4540,6 +4587,37 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
break;
}
+ case DW_OP_LLVM_overlay:
+ case DW_OP_LLVM_bit_overlay:
+ {
+ if (stack_empty_p ())
+ ill_formed_expression ();
+
+ dwarf_value_up overlay_size_val
+ = to_value (pop (), address_type);
+ dwarf_require_integral (overlay_size_val->type ());
+ LONGEST overlay_size = overlay_size_val->to_long ();
+
+ if (stack_empty_p () || overlay_size < 0)
+ ill_formed_expression ();
+
+ dwarf_value_up overlay_offset_val
+ = to_value (pop (), address_type);
+ dwarf_require_integral (overlay_offset_val->type ());
+ LONGEST overlay_offset = overlay_offset_val->to_long ();
+
+ if (overlay_offset < 0)
+ ill_formed_expression ();
+
+ if (op == DW_OP_LLVM_overlay)
+ create_overlay_composite ({(ULONGEST) overlay_size, 0},
+ {(ULONGEST) overlay_offset, 0});
+ else
+ create_overlay_composite ((ULONGEST) overlay_size,
+ (ULONGEST) overlay_offset);
+ break;
+ }
+
default:
error (_("Unhandled dwarf expression opcode 0x%x"), op);
}
diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index 071baad..c7aa8de 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -1928,6 +1928,8 @@ dwarf2_get_symbol_read_needs (gdb::array_view<const gdb_byte> expr,
case DW_OP_LLVM_bit_offset:
case DW_OP_LLVM_undefined:
case DW_OP_LLVM_piece_end:
+ case DW_OP_LLVM_overlay:
+ case DW_OP_LLVM_bit_overlay:
break;
case DW_OP_form_tls_address: