summaryrefslogtreecommitdiffstats
path: root/contrib/gdb
diff options
context:
space:
mode:
authorsbruno <sbruno@FreeBSD.org>2015-05-17 15:49:38 +0000
committersbruno <sbruno@FreeBSD.org>2015-05-17 15:49:38 +0000
commitd177e521098a79866164f04c9c5f238c97562ed3 (patch)
tree6b3cd88ee5d6704b2e27378099504a98ac28600f /contrib/gdb
parenta416f5f99655bc262224191178e0c9da76c5632b (diff)
downloadFreeBSD-src-d177e521098a79866164f04c9c5f238c97562ed3.zip
FreeBSD-src-d177e521098a79866164f04c9c5f238c97562ed3.tar.gz
Update intree gdb/kgdb to handle 2 dwarf types:
DW_OP_GNU_uninit DW_OP_piece This squashes the warnings about type 0x93 not known in kgdb when opening a kernel crash dump. Upstream refs: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=87808bd699575a850139a1f916512ab7a47fd496 https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=42be36b328ae784ae6981da7c7cab95b67ed7737 https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=23572ecadc89af384c1804ad7692f32c55fbfc80 Differential Revision: https://reviews.freebsd.org/D2534 Reviewed by: emaste, jhb, davide
Diffstat (limited to 'contrib/gdb')
-rw-r--r--contrib/gdb/gdb/c-valprint.c4
-rw-r--r--contrib/gdb/gdb/dwarf2expr.c60
-rw-r--r--contrib/gdb/gdb/dwarf2expr.h45
-rw-r--r--contrib/gdb/gdb/dwarf2loc.c41
-rw-r--r--contrib/gdb/gdb/dwarf2read.c5
-rw-r--r--contrib/gdb/gdb/value.h3
-rw-r--r--contrib/gdb/gdb/values.c17
7 files changed, 171 insertions, 4 deletions
diff --git a/contrib/gdb/gdb/c-valprint.c b/contrib/gdb/gdb/c-valprint.c
index 999aa82..913793a 100644
--- a/contrib/gdb/gdb/c-valprint.c
+++ b/contrib/gdb/gdb/c-valprint.c
@@ -559,6 +559,10 @@ c_value_print (struct value *val, struct ui_file *stream, int format,
fprintf_filtered (stream, ") ");
}
}
+
+ if (!value_initialized (val))
+ fprintf_filtered (stream, " [uninitialized] ");
+
if (objectprint && (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_CLASS))
{
/* Attempt to determine real type of object */
diff --git a/contrib/gdb/gdb/dwarf2expr.c b/contrib/gdb/gdb/dwarf2expr.c
index 294afa0..c7ae563 100644
--- a/contrib/gdb/gdb/dwarf2expr.c
+++ b/contrib/gdb/gdb/dwarf2expr.c
@@ -42,6 +42,8 @@ new_dwarf_expr_context (void)
retval->stack_len = 0;
retval->stack_allocated = 10;
retval->stack = xmalloc (retval->stack_allocated * sizeof (CORE_ADDR));
+ retval->num_pieces = 0;
+ retval->pieces = 0;
return retval;
}
@@ -51,6 +53,7 @@ void
free_dwarf_expr_context (struct dwarf_expr_context *ctx)
{
xfree (ctx->stack);
+ xfree (ctx->pieces);
xfree (ctx);
}
@@ -100,6 +103,29 @@ dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
}
+/* Add a new piece to CTX's piece list. */
+static void
+add_piece (struct dwarf_expr_context *ctx,
+ int in_reg, CORE_ADDR value, ULONGEST size)
+{
+ struct dwarf_expr_piece *p;
+
+ ctx->num_pieces++;
+
+ if (ctx->pieces)
+ ctx->pieces = xrealloc (ctx->pieces,
+ (ctx->num_pieces
+ * sizeof (struct dwarf_expr_piece)));
+ else
+ ctx->pieces = xmalloc (ctx->num_pieces
+ * sizeof (struct dwarf_expr_piece));
+
+ p = &ctx->pieces[ctx->num_pieces - 1];
+ p->in_reg = in_reg;
+ p->value = value;
+ p->size = size;
+}
+
/* Evaluate the expression at ADDR (LEN bytes long) using the context
CTX. */
@@ -230,6 +256,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
unsigned char *op_end)
{
ctx->in_reg = 0;
+ ctx->initialized = 1; /* Default is initialized. */
while (op_ptr < op_end)
{
@@ -356,9 +383,12 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
case DW_OP_reg29:
case DW_OP_reg30:
case DW_OP_reg31:
- if (op_ptr != op_end && *op_ptr != DW_OP_piece)
- error ("DWARF-2 expression error: DW_OP_reg operations must be "
- "used either alone or in conjuction with DW_OP_piece.");
+ if (op_ptr != op_end
+ && *op_ptr != DW_OP_piece
+ && *op_ptr != DW_OP_bit_piece
+ && *op_ptr != DW_OP_GNU_uninit)
+ error (_("DWARF-2 expression error: DW_OP_reg operations must be "
+ "used either alone or in conjuction with DW_OP_piece."));
result = op - DW_OP_reg0;
ctx->in_reg = 1;
@@ -661,6 +691,30 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
case DW_OP_nop:
goto no_push;
+ case DW_OP_piece:
+ {
+ ULONGEST size;
+ CORE_ADDR addr_or_regnum;
+
+ /* Record the piece. */
+ op_ptr = read_uleb128 (op_ptr, op_end, &size);
+ addr_or_regnum = dwarf_expr_fetch (ctx, 0);
+ add_piece (ctx, ctx->in_reg, addr_or_regnum, size);
+
+ /* Pop off the address/regnum, and clear the in_reg flag. */
+ dwarf_expr_pop (ctx);
+ ctx->in_reg = 0;
+ }
+ goto no_push;
+
+ case DW_OP_GNU_uninit:
+ if (op_ptr != op_end)
+ error (_("DWARF-2 expression error: DW_OP_GNU_unint must always "
+ "be the very last op."));
+
+ ctx->initialized = 0;
+ goto no_push;
+
default:
error ("Unhandled dwarf expression opcode 0x%x", op);
}
diff --git a/contrib/gdb/gdb/dwarf2expr.h b/contrib/gdb/gdb/dwarf2expr.h
index 0a60edb..1892c90 100644
--- a/contrib/gdb/gdb/dwarf2expr.h
+++ b/contrib/gdb/gdb/dwarf2expr.h
@@ -74,6 +74,51 @@ struct dwarf_expr_context
/* Non-zero if the result is in a register. The register number
will be on the expression stack. */
int in_reg;
+ /* Initialization status of variable: Non-zero if variable has been
+ initialized; zero otherwise. */
+ int initialized;
+
+ /* An array of pieces. PIECES points to its first element;
+ NUM_PIECES is its length.
+
+ Each time DW_OP_piece is executed, we add a new element to the
+ end of this array, recording the current top of the stack, the
+ current in_reg flag, and the size given as the operand to
+ DW_OP_piece. We then pop the top value from the stack, clear the
+ in_reg flag, and resume evaluation.
+
+ The Dwarf spec doesn't say whether DW_OP_piece pops the top value
+ from the stack. We do, ensuring that clients of this interface
+ expecting to see a value left on the top of the stack (say, code
+ evaluating frame base expressions or CFA's specified with
+ DW_CFA_def_cfa_expression) will get an error if the expression
+ actually marks all the values it computes as pieces.
+
+ If an expression never uses DW_OP_piece, num_pieces will be zero.
+ (It would be nice to present these cases as expressions yielding
+ a single piece, with in_reg clear, so that callers need not
+ distinguish between the no-DW_OP_piece and one-DW_OP_piece cases.
+ But expressions with no DW_OP_piece operations have no value to
+ place in a piece's 'size' field; the size comes from the
+ surrounding data. So the two cases need to be handled
+ separately.) */
+ int num_pieces;
+ struct dwarf_expr_piece *pieces;
+};
+
+/* A piece of an object, as recorded by DW_OP_piece or DW_OP_bit_piece. */
+struct dwarf_expr_piece
+{
+ /* If IN_REG is zero, then the piece is in memory, and VALUE is its address.
+ If IN_REG is non-zero, then the piece is in a register, and VALUE
+ is the register number. */
+ int in_reg;
+
+ /* This piece's address or register number. */
+ CORE_ADDR value;
+
+ /* The length of the piece, in bytes. */
+ ULONGEST size;
};
struct dwarf_expr_context *new_dwarf_expr_context (void);
diff --git a/contrib/gdb/gdb/dwarf2loc.c b/contrib/gdb/gdb/dwarf2loc.c
index 208e9d1..c81d46f 100644
--- a/contrib/gdb/gdb/dwarf2loc.c
+++ b/contrib/gdb/gdb/dwarf2loc.c
@@ -206,6 +206,7 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
struct objfile *objfile)
{
CORE_ADDR result;
+ struct gdbarch *arch = get_frame_arch (frame);
struct value *retval;
struct dwarf_expr_baton baton;
struct dwarf_expr_context *ctx;
@@ -230,7 +231,32 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
dwarf_expr_eval (ctx, data, size);
result = dwarf_expr_fetch (ctx, 0);
- if (ctx->in_reg)
+ if (ctx->num_pieces > 0)
+ {
+ int i;
+ long offset = 0;
+ bfd_byte *contents;
+
+ retval = allocate_value (SYMBOL_TYPE (var));
+ contents = VALUE_CONTENTS_RAW (retval);
+ for (i = 0; i < ctx->num_pieces; i++)
+ {
+ struct dwarf_expr_piece *p = &ctx->pieces[i];
+ if (p->in_reg)
+ {
+ bfd_byte regval[MAX_REGISTER_SIZE];
+ int gdb_regnum = DWARF2_REG_TO_REGNUM (p->value);
+ get_frame_register (frame, gdb_regnum, regval);
+ memcpy (contents + offset, regval, p->size);
+ }
+ else /* In memory? */
+ {
+ read_memory (p->value, contents + offset, p->size);
+ }
+ offset += p->size;
+ }
+ }
+ else if (ctx->in_reg)
{
int regnum = DWARF2_REG_TO_REGNUM (result);
retval = value_from_register (SYMBOL_TYPE (var), regnum, frame);
@@ -245,6 +271,8 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
VALUE_ADDRESS (retval) = result;
}
+ set_value_initialized (retval, ctx->initialized);
+
free_dwarf_expr_context (ctx);
return retval;
@@ -322,6 +350,17 @@ dwarf2_loc_desc_needs_frame (unsigned char *data, unsigned short size)
in_reg = ctx->in_reg;
+ if (ctx->num_pieces > 0)
+ {
+ int i;
+
+ /* If the location has several pieces, and any of them are in
+ registers, then we will need a frame to fetch them from. */
+ for (i = 0; i < ctx->num_pieces; i++)
+ if (ctx->pieces[i].in_reg)
+ in_reg = 1;
+ }
+
free_dwarf_expr_context (ctx);
return baton.needs_frame || in_reg;
diff --git a/contrib/gdb/gdb/dwarf2read.c b/contrib/gdb/gdb/dwarf2read.c
index 852172b..d3dd560 100644
--- a/contrib/gdb/gdb/dwarf2read.c
+++ b/contrib/gdb/gdb/dwarf2read.c
@@ -7110,6 +7110,8 @@ dwarf_stack_op_name (unsigned op)
/* GNU extensions. */
case DW_OP_GNU_push_tls_address:
return "DW_OP_GNU_push_tls_address";
+ case DW_OP_GNU_uninit:
+ return "DW_OP_GNU_uninit";
default:
return "OP_<unknown>";
}
@@ -7634,6 +7636,9 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
dwarf2_complex_location_expr_complaint ();
break;
+ case DW_OP_GNU_uninit:
+ break;
+
default:
complaint (&symfile_complaints, "unsupported stack op: '%s'",
dwarf_stack_op_name (op));
diff --git a/contrib/gdb/gdb/value.h b/contrib/gdb/gdb/value.h
index a01b438..9e547a3 100644
--- a/contrib/gdb/gdb/value.h
+++ b/contrib/gdb/gdb/value.h
@@ -165,6 +165,9 @@ struct value
/* The BFD section associated with this value. */
asection *bfd_section;
+ /* If value is a variable, is it initialized or not. */
+ int initialized;
+
/* Actual contents of the value. For use of this value; setting
it uses the stuff above. Not valid if lazy is nonzero.
Target byte-order. We force it to be aligned properly for any
diff --git a/contrib/gdb/gdb/values.c b/contrib/gdb/gdb/values.c
index 87baf21..32e4b25 100644
--- a/contrib/gdb/gdb/values.c
+++ b/contrib/gdb/gdb/values.c
@@ -101,6 +101,7 @@ allocate_value (struct type *type)
VALUE_EMBEDDED_OFFSET (val) = 0;
VALUE_POINTED_TO_OFFSET (val) = 0;
val->modifiable = 1;
+ val->initialized = 1; /* Default to initialized. */
return val;
}
@@ -1311,6 +1312,22 @@ using_struct_return (struct type *value_type, int gcc_p)
== RETURN_VALUE_STRUCT_CONVENTION);
}
+/* Set the initialized field in a value struct. */
+
+void
+set_value_initialized (struct value *val, int status)
+{
+ val->initialized = status;
+}
+
+/* Return the initialized field in a value struct. */
+
+int
+value_initialized (struct value *val)
+{
+ return val->initialized;
+}
+
void
_initialize_values (void)
{
OpenPOWER on IntegriCloud