diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2010-06-25 13:00:33 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@de.ibm.com> | 2010-06-25 13:00:33 +0000 |
commit | f2c7657e9a0e18772ce4b0a95afd2b6546152b78 (patch) | |
tree | a7af9795f2e7daa59d8e72d016040c1a294b7aee /gdb | |
parent | b1d61bc9d188010bf897f8155a76fb76ab99775f (diff) | |
download | gdb-f2c7657e9a0e18772ce4b0a95afd2b6546152b78.zip gdb-f2c7657e9a0e18772ce4b0a95afd2b6546152b78.tar.gz gdb-f2c7657e9a0e18772ce4b0a95afd2b6546152b78.tar.bz2 |
ChangeLog:
* dwarf2expr.h (struct dwarf_value_location): Use ULONGEST as type
of stack values.
(struct dwarf_expr_piece): Rename "expr" member to "mem". Add new
"value" member.
(dwarf_expr_push): Change input type to ULONGEST.
(dwarf_expr_fetch): Change return type to ULONGEST.
(dwarf_expr_fetch_address): Add prototype.
(dwarf2_read_address): Remove prototype.
* dwarf2expr.c (dwarf_expr_push): Use ULONGEST as type of stack values.
Truncate stack values to ctx->addr_size bytes.
(dwarf_expr_fetch): Change return value to ULONGEST.
(dwarf_expr_fetch_address): New function.
(add_piece): Use dwarf_expr_fetch_address instead of dwarf_expr_fetch
when appropriate. Update for struct dwarf_expr_piece changes.
(dwarf2_read_address): Remove.
(unsigned_address_type): Remove.
(signed_address_type): Remove.
(execute_stack_op): Use dwarf_expr_fetch_address instead of
dwarf_expr_fetch when appropriate. Use ULONGEST as type of stack
values. Perform operations on ULONGEST instead of on GDB values,
sign-extending from ctx->addr_size bytes as needed. Read DW_OP_addr
values and DW_OP_deref results as unsigned integers.
* dwarf2loc.c (read_pieced_value): Update for struct dwarf_expr_piece
changes.
(write_pieced_value): Likewise.
(dwarf2_evaluate_loc_desc): Use dwarf_expr_fetch_address instead of
dwarf_expr_fetch when appropriate.
(compile_dwarf_to_ax): Read DW_OP_addr values as unsigned integers.
* dwarf2-frame.c (execute_stack_op): Use dwarf_expr_fetch_address
instead of dwarf_expr_fetch when appropriate.
testsuite/ChangeLog:
* gdb.cell/dwarfaddr.exp: New file.
* gdb.cell/dwarfaddr.S: New file.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 33 | ||||
-rw-r--r-- | gdb/dwarf2-frame.c | 9 | ||||
-rw-r--r-- | gdb/dwarf2expr.c | 258 | ||||
-rw-r--r-- | gdb/dwarf2expr.h | 23 | ||||
-rw-r--r-- | gdb/dwarf2loc.c | 36 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cell/dwarfaddr.S | 190 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cell/dwarfaddr.exp | 53 |
8 files changed, 418 insertions, 189 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a644848..53c6145 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,36 @@ +2010-06-25 Ulrich Weigand <uweigand@de.ibm.com> + + * dwarf2expr.h (struct dwarf_value_location): Use ULONGEST as type + of stack values. + (struct dwarf_expr_piece): Rename "expr" member to "mem". Add new + "value" member. + (dwarf_expr_push): Change input type to ULONGEST. + (dwarf_expr_fetch): Change return type to ULONGEST. + (dwarf_expr_fetch_address): Add prototype. + (dwarf2_read_address): Remove prototype. + * dwarf2expr.c (dwarf_expr_push): Use ULONGEST as type of stack values. + Truncate stack values to ctx->addr_size bytes. + (dwarf_expr_fetch): Change return value to ULONGEST. + (dwarf_expr_fetch_address): New function. + (add_piece): Use dwarf_expr_fetch_address instead of dwarf_expr_fetch + when appropriate. Update for struct dwarf_expr_piece changes. + (dwarf2_read_address): Remove. + (unsigned_address_type): Remove. + (signed_address_type): Remove. + (execute_stack_op): Use dwarf_expr_fetch_address instead of + dwarf_expr_fetch when appropriate. Use ULONGEST as type of stack + values. Perform operations on ULONGEST instead of on GDB values, + sign-extending from ctx->addr_size bytes as needed. Read DW_OP_addr + values and DW_OP_deref results as unsigned integers. + * dwarf2loc.c (read_pieced_value): Update for struct dwarf_expr_piece + changes. + (write_pieced_value): Likewise. + (dwarf2_evaluate_loc_desc): Use dwarf_expr_fetch_address instead of + dwarf_expr_fetch when appropriate. + (compile_dwarf_to_ax): Read DW_OP_addr values as unsigned integers. + * dwarf2-frame.c (execute_stack_op): Use dwarf_expr_fetch_address + instead of dwarf_expr_fetch when appropriate. + 2010-06-25 Pierre Muller <muller@ics.u-strasbg.fr> * c-typeprint.c (c_print_typedef): Append new type name for typedefs. diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index 68793cd..9576341 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -391,11 +391,12 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size, dwarf_expr_push (ctx, initial, initial_in_stack_memory); dwarf_expr_eval (ctx, exp, len); - result = dwarf_expr_fetch (ctx, 0); - if (ctx->location == DWARF_VALUE_REGISTER) - result = read_reg (this_frame, result); - else if (ctx->location != DWARF_VALUE_MEMORY) + if (ctx->location == DWARF_VALUE_MEMORY) + result = dwarf_expr_fetch_address (ctx, 0); + else if (ctx->location == DWARF_VALUE_REGISTER) + result = read_reg (this_frame, dwarf_expr_fetch (ctx, 0)); + else { /* This is actually invalid DWARF, but if we ever do run across it somehow, we might as well support it. So, instead, report diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c index 0dc0aaf..c11c410 100644 --- a/gdb/dwarf2expr.c +++ b/gdb/dwarf2expr.c @@ -33,7 +33,6 @@ static void execute_stack_op (struct dwarf_expr_context *, const gdb_byte *, const gdb_byte *); -static struct type *unsigned_address_type (struct gdbarch *, int); /* Create a new context for the expression evaluator. */ @@ -98,11 +97,16 @@ dwarf_expr_grow_stack (struct dwarf_expr_context *ctx, size_t need) /* Push VALUE onto CTX's stack. */ void -dwarf_expr_push (struct dwarf_expr_context *ctx, CORE_ADDR value, +dwarf_expr_push (struct dwarf_expr_context *ctx, ULONGEST value, int in_stack_memory) { struct dwarf_stack_value *v; + /* We keep all stack elements within the range defined by the + DWARF address size. */ + if (ctx->addr_size < sizeof (ULONGEST)) + value &= ((ULONGEST) 1 << (ctx->addr_size * HOST_CHAR_BIT)) - 1; + dwarf_expr_grow_stack (ctx, 1); v = &ctx->stack[ctx->stack_len++]; v->value = value; @@ -121,7 +125,7 @@ dwarf_expr_pop (struct dwarf_expr_context *ctx) /* Retrieve the N'th item on CTX's stack. */ -CORE_ADDR +ULONGEST dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n) { if (ctx->stack_len <= n) @@ -131,6 +135,48 @@ dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n) } +/* Retrieve the N'th item on CTX's stack, converted to an address. */ + +CORE_ADDR +dwarf_expr_fetch_address (struct dwarf_expr_context *ctx, int n) +{ + ULONGEST result = dwarf_expr_fetch (ctx, n); + + /* For most architectures, calling extract_unsigned_integer() alone + is sufficient for extracting an address. However, some + architectures (e.g. MIPS) use signed addresses and using + extract_unsigned_integer() will not produce a correct + result. Make sure we invoke gdbarch_integer_to_address() + for those architectures which require it. */ + if (gdbarch_integer_to_address_p (ctx->gdbarch)) + { + enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch); + gdb_byte *buf = alloca (ctx->addr_size); + struct type *int_type; + + switch (ctx->addr_size) + { + case 2: + int_type = builtin_type (ctx->gdbarch)->builtin_uint16; + break; + case 4: + int_type = builtin_type (ctx->gdbarch)->builtin_uint32; + break; + case 8: + int_type = builtin_type (ctx->gdbarch)->builtin_uint64; + break; + default: + internal_error (__FILE__, __LINE__, + _("Unsupported address size.\n")); + } + + store_unsigned_integer (buf, ctx->addr_size, byte_order, result); + return gdbarch_integer_to_address (ctx->gdbarch, int_type, buf); + } + + return (CORE_ADDR) result; +} + /* Retrieve the in_stack_memory flag of the N'th item on CTX's stack. */ int @@ -182,10 +228,14 @@ add_piece (struct dwarf_expr_context *ctx, ULONGEST size, ULONGEST offset) cases in the evaluator. */ ctx->location = DWARF_VALUE_OPTIMIZED_OUT; } + else if (p->location == DWARF_VALUE_MEMORY) + { + p->v.mem.addr = dwarf_expr_fetch_address (ctx, 0); + p->v.mem.in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0); + } else { - p->v.expr.value = dwarf_expr_fetch (ctx, 0); - p->v.expr.in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0); + p->v.value = dwarf_expr_fetch (ctx, 0); } } @@ -259,76 +309,6 @@ read_sleb128 (const gdb_byte *buf, const gdb_byte *buf_end, LONGEST * r) *r = result; return buf; } - -/* Read an address of size ADDR_SIZE from BUF, and verify that it - doesn't extend past BUF_END. */ - -CORE_ADDR -dwarf2_read_address (struct gdbarch *gdbarch, const gdb_byte *buf, - const gdb_byte *buf_end, int addr_size) -{ - enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - - if (buf_end - buf < addr_size) - error (_("dwarf2_read_address: Corrupted DWARF expression.")); - - /* For most architectures, calling extract_unsigned_integer() alone - is sufficient for extracting an address. However, some - architectures (e.g. MIPS) use signed addresses and using - extract_unsigned_integer() will not produce a correct - result. Make sure we invoke gdbarch_integer_to_address() - for those architectures which require it. - - The use of `unsigned_address_type' in the code below refers to - the type of buf and has no bearing on the signedness of the - address being returned. */ - - if (gdbarch_integer_to_address_p (gdbarch)) - return gdbarch_integer_to_address - (gdbarch, unsigned_address_type (gdbarch, addr_size), buf); - - return extract_unsigned_integer (buf, addr_size, byte_order); -} - -/* Return the type of an address of size ADDR_SIZE, - for unsigned arithmetic. */ - -static struct type * -unsigned_address_type (struct gdbarch *gdbarch, int addr_size) -{ - switch (addr_size) - { - case 2: - return builtin_type (gdbarch)->builtin_uint16; - case 4: - return builtin_type (gdbarch)->builtin_uint32; - case 8: - return builtin_type (gdbarch)->builtin_uint64; - default: - internal_error (__FILE__, __LINE__, - _("Unsupported address size.\n")); - } -} - -/* Return the type of an address of size ADDR_SIZE, - for signed arithmetic. */ - -static struct type * -signed_address_type (struct gdbarch *gdbarch, int addr_size) -{ - switch (addr_size) - { - case 2: - return builtin_type (gdbarch)->builtin_int16; - case 4: - return builtin_type (gdbarch)->builtin_int32; - case 8: - return builtin_type (gdbarch)->builtin_int64; - default: - internal_error (__FILE__, __LINE__, - _("Unsupported address size.\n")); - } -} /* Check that the current operator is either at the end of an @@ -355,6 +335,9 @@ static void execute_stack_op (struct dwarf_expr_context *ctx, const gdb_byte *op_ptr, const gdb_byte *op_end) { + #define sign_ext(x) ((LONGEST) (((x) ^ sign_bit) - sign_bit)) + ULONGEST sign_bit = (ctx->addr_size >= sizeof (ULONGEST) ? 0 + : ((ULONGEST) 1) << (ctx->addr_size * 8 - 1)); enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch); ctx->location = DWARF_VALUE_MEMORY; @@ -368,7 +351,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, while (op_ptr < op_end) { enum dwarf_location_atom op = *op_ptr++; - CORE_ADDR result; + ULONGEST result; /* Assume the value is not in stack memory. Code that knows otherwise sets this to 1. Some arithmetic on stack addresses can probably be assumed to still @@ -417,8 +400,8 @@ execute_stack_op (struct dwarf_expr_context *ctx, break; case DW_OP_addr: - result = dwarf2_read_address (ctx->gdbarch, - op_ptr, op_end, ctx->addr_size); + result = extract_unsigned_integer (op_ptr, + ctx->addr_size, byte_order); op_ptr += ctx->addr_size; break; @@ -601,12 +584,12 @@ execute_stack_op (struct dwarf_expr_context *ctx, specific this_base method. */ (ctx->get_frame_base) (ctx->baton, &datastart, &datalen); dwarf_expr_eval (ctx, datastart, datalen); - if (ctx->location == DWARF_VALUE_LITERAL - || ctx->location == DWARF_VALUE_STACK) + if (ctx->location == DWARF_VALUE_MEMORY) + result = dwarf_expr_fetch_address (ctx, 0); + else if (ctx->location == DWARF_VALUE_REGISTER) + result = (ctx->read_reg) (ctx->baton, dwarf_expr_fetch (ctx, 0)); + else error (_("Not implemented: computing frame base using explicit value operator")); - result = dwarf_expr_fetch (ctx, 0); - if (ctx->location == DWARF_VALUE_REGISTER) - result = (ctx->read_reg) (ctx->baton, result); result = result + offset; in_stack_memory = 1; ctx->stack_len = before_stack_len; @@ -666,6 +649,17 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_deref: case DW_OP_deref_size: + { + int addr_size = (op == DW_OP_deref ? ctx->addr_size : *op_ptr++); + gdb_byte *buf = alloca (addr_size); + CORE_ADDR addr = dwarf_expr_fetch_address (ctx, 0); + dwarf_expr_pop (ctx); + + (ctx->read_mem) (ctx->baton, buf, addr, addr_size); + result = extract_unsigned_integer (buf, addr_size, byte_order); + break; + } + case DW_OP_abs: case DW_OP_neg: case DW_OP_not: @@ -676,31 +670,8 @@ execute_stack_op (struct dwarf_expr_context *ctx, switch (op) { - case DW_OP_deref: - { - gdb_byte *buf = alloca (ctx->addr_size); - - (ctx->read_mem) (ctx->baton, buf, result, ctx->addr_size); - result = dwarf2_read_address (ctx->gdbarch, - buf, buf + ctx->addr_size, - ctx->addr_size); - } - break; - - case DW_OP_deref_size: - { - int addr_size = *op_ptr++; - gdb_byte *buf = alloca (addr_size); - - (ctx->read_mem) (ctx->baton, buf, result, addr_size); - result = dwarf2_read_address (ctx->gdbarch, - buf, buf + addr_size, - addr_size); - } - break; - case DW_OP_abs: - if ((signed int) result < 0) + if (sign_ext (result) < 0) result = -result; break; case DW_OP_neg: @@ -734,12 +705,8 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_gt: case DW_OP_ne: { - /* Binary operations. Use the value engine to do computations in - the right width. */ - CORE_ADDR first, second; - enum exp_opcode binop; - struct value *val1 = NULL, *val2 = NULL; - struct type *stype, *utype; + /* Binary operations. */ + ULONGEST first, second; second = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); @@ -747,89 +714,67 @@ execute_stack_op (struct dwarf_expr_context *ctx, first = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); - utype = unsigned_address_type (ctx->gdbarch, ctx->addr_size); - stype = signed_address_type (ctx->gdbarch, ctx->addr_size); - switch (op) { case DW_OP_and: - binop = BINOP_BITWISE_AND; + result = first & second; break; case DW_OP_div: - binop = BINOP_DIV; - val1 = value_from_longest (stype, first); - val2 = value_from_longest (stype, second); + if (!second) + error (_("Division by zero")); + result = sign_ext (first) / sign_ext (second); break; case DW_OP_minus: - binop = BINOP_SUB; + result = first - second; break; case DW_OP_mod: - binop = BINOP_MOD; + if (!second) + error (_("Division by zero")); + result = first % second; break; case DW_OP_mul: - binop = BINOP_MUL; + result = first * second; break; case DW_OP_or: - binop = BINOP_BITWISE_IOR; + result = first | second; break; case DW_OP_plus: - binop = BINOP_ADD; + result = first + second; break; case DW_OP_shl: - binop = BINOP_LSH; + result = first << second; break; case DW_OP_shr: - binop = BINOP_RSH; + result = first >> second; break; case DW_OP_shra: - binop = BINOP_RSH; - val1 = value_from_longest (stype, first); + result = sign_ext (first) >> second; break; case DW_OP_xor: - binop = BINOP_BITWISE_XOR; + result = first ^ second; break; case DW_OP_le: - binop = BINOP_LEQ; - val1 = value_from_longest (stype, first); - val2 = value_from_longest (stype, second); + result = sign_ext (first) <= sign_ext (second); break; case DW_OP_ge: - binop = BINOP_GEQ; - val1 = value_from_longest (stype, first); - val2 = value_from_longest (stype, second); + result = sign_ext (first) >= sign_ext (second); break; case DW_OP_eq: - binop = BINOP_EQUAL; - val1 = value_from_longest (stype, first); - val2 = value_from_longest (stype, second); + result = sign_ext (first) == sign_ext (second); break; case DW_OP_lt: - binop = BINOP_LESS; - val1 = value_from_longest (stype, first); - val2 = value_from_longest (stype, second); + result = sign_ext (first) < sign_ext (second); break; case DW_OP_gt: - binop = BINOP_GTR; - val1 = value_from_longest (stype, first); - val2 = value_from_longest (stype, second); + result = sign_ext (first) > sign_ext (second); break; case DW_OP_ne: - binop = BINOP_NOTEQUAL; - val1 = value_from_longest (stype, first); - val2 = value_from_longest (stype, second); + result = sign_ext (first) != sign_ext (second); break; default: internal_error (__FILE__, __LINE__, _("Can't be reached.")); } - - /* We use unsigned operands by default. */ - if (val1 == NULL) - val1 = value_from_longest (utype, first); - if (val2 == NULL) - val2 = value_from_longest (utype, second); - - result = value_as_long (value_binop (val1, val2, binop)); } break; @@ -935,4 +880,5 @@ execute_stack_op (struct dwarf_expr_context *ctx, ctx->recursion_depth--; gdb_assert (ctx->recursion_depth >= 0); + #undef sign_ext } diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h index 727e557..31381c0 100644 --- a/gdb/dwarf2expr.h +++ b/gdb/dwarf2expr.h @@ -48,7 +48,7 @@ enum dwarf_value_location struct dwarf_stack_value { - CORE_ADDR value; + ULONGEST value; /* Non-zero if the piece is in memory and is known to be on the program's stack. It is always ok to set this to zero. @@ -163,17 +163,21 @@ struct dwarf_expr_piece { struct { - /* This piece's address or register number. */ - CORE_ADDR value; + /* This piece's address, for DWARF_VALUE_MEMORY pieces. */ + CORE_ADDR addr; /* Non-zero if the piece is known to be in memory and on the program's stack. */ int in_stack_memory; - } expr; + } mem; + + /* The piece's register number or literal value, for + DWARF_VALUE_REGISTER or DWARF_VALUE_STACK pieces. */ + ULONGEST value; struct { - /* A pointer to the data making up this piece, for literal - pieces. */ + /* A pointer to the data making up this piece, + for DWARF_VALUE_LITERAL pieces. */ const gdb_byte *data; /* The length of the available data. */ ULONGEST length; @@ -191,12 +195,13 @@ void free_dwarf_expr_context (struct dwarf_expr_context *ctx); struct cleanup * make_cleanup_free_dwarf_expr_context (struct dwarf_expr_context *ctx); -void dwarf_expr_push (struct dwarf_expr_context *ctx, CORE_ADDR value, +void dwarf_expr_push (struct dwarf_expr_context *ctx, ULONGEST value, int in_stack_memory); void dwarf_expr_pop (struct dwarf_expr_context *ctx); void dwarf_expr_eval (struct dwarf_expr_context *ctx, const gdb_byte *addr, size_t len); -CORE_ADDR dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n); +ULONGEST 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); @@ -204,8 +209,6 @@ 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); -CORE_ADDR dwarf2_read_address (struct gdbarch *gdbarch, const gdb_byte *buf, - const gdb_byte *buf_end, int addr_size); const char *dwarf_stack_op_name (unsigned int, int); diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 46007c2..1965022 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -548,8 +548,7 @@ read_pieced_value (struct value *v) case DWARF_VALUE_REGISTER: { struct gdbarch *arch = get_frame_arch (frame); - int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, - p->v.expr.value); + int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value); int reg_offset = source_offset; if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG @@ -570,16 +569,16 @@ read_pieced_value (struct value *v) else { error (_("Unable to access DWARF register number %s"), - paddress (arch, p->v.expr.value)); + paddress (arch, p->v.value)); } } break; case DWARF_VALUE_MEMORY: - if (p->v.expr.in_stack_memory) - read_stack (p->v.expr.value + source_offset, buffer, this_size); + if (p->v.mem.in_stack_memory) + read_stack (p->v.mem.addr + source_offset, buffer, this_size); else - read_memory (p->v.expr.value + source_offset, buffer, this_size); + read_memory (p->v.mem.addr + source_offset, buffer, this_size); break; case DWARF_VALUE_STACK: @@ -598,14 +597,14 @@ read_pieced_value (struct value *v) else if (source_offset == 0) store_unsigned_integer (buffer, n, gdbarch_byte_order (gdbarch), - p->v.expr.value); + p->v.value); else { gdb_byte bytes[sizeof (ULONGEST)]; store_unsigned_integer (bytes, n + source_offset, gdbarch_byte_order (gdbarch), - p->v.expr.value); + p->v.value); memcpy (buffer, bytes + source_offset, n); } } @@ -730,7 +729,7 @@ write_pieced_value (struct value *to, struct value *from) case DWARF_VALUE_REGISTER: { struct gdbarch *arch = get_frame_arch (frame); - int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.expr.value); + int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value); int reg_offset = dest_offset; if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG @@ -756,7 +755,7 @@ write_pieced_value (struct value *to, struct value *from) else { error (_("Unable to write to DWARF register number %s"), - paddress (arch, p->v.expr.value)); + paddress (arch, p->v.value)); } } break; @@ -765,8 +764,8 @@ write_pieced_value (struct value *to, struct value *from) { /* Only the first and last bytes can possibly have any bits reused. */ - read_memory (p->v.expr.value + dest_offset, buffer, 1); - read_memory (p->v.expr.value + dest_offset + this_size - 1, + read_memory (p->v.mem.addr + dest_offset, buffer, 1); + read_memory (p->v.mem.addr + dest_offset + this_size - 1, buffer + this_size - 1, 1); copy_bitwise (buffer, dest_offset_bits, contents, source_offset_bits, @@ -774,7 +773,7 @@ write_pieced_value (struct value *to, struct value *from) bits_big_endian); } - write_memory (p->v.expr.value + dest_offset, + write_memory (p->v.mem.addr + dest_offset, source_buffer, this_size); break; default: @@ -935,7 +934,7 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame, case DWARF_VALUE_REGISTER: { struct gdbarch *arch = get_frame_arch (frame); - CORE_ADDR dwarf_regnum = dwarf_expr_fetch (ctx, 0); + ULONGEST dwarf_regnum = dwarf_expr_fetch (ctx, 0); int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum); if (gdb_regnum != -1) @@ -948,7 +947,7 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame, case DWARF_VALUE_MEMORY: { - CORE_ADDR address = dwarf_expr_fetch (ctx, 0); + CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0); int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0); retval = allocate_value (type); @@ -962,7 +961,7 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame, case DWARF_VALUE_STACK: { - ULONGEST value = (ULONGEST) dwarf_expr_fetch (ctx, 0); + ULONGEST value = dwarf_expr_fetch (ctx, 0); bfd_byte *contents; size_t n = ctx->addr_size; @@ -1233,7 +1232,6 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc, while (op_ptr < op_end) { enum dwarf_location_atom op = *op_ptr; - CORE_ADDR result; ULONGEST uoffset, reg; LONGEST offset; int i; @@ -1295,8 +1293,8 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc, break; case DW_OP_addr: - result = dwarf2_read_address (arch, op_ptr, op_end, addr_size); - ax_const_l (expr, result); + ax_const_l (expr, extract_unsigned_integer (op_ptr, + addr_size, byte_order)); op_ptr += addr_size; break; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index f56a2a7..733d50b 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-06-25 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * gdb.cell/dwarfaddr.exp: New file. + * gdb.cell/dwarfaddr.S: New file. + 2010-06-24 Jan Kratochvil <jan.kratochvil@redhat.com> Test PR 9436. diff --git a/gdb/testsuite/gdb.cell/dwarfaddr.S b/gdb/testsuite/gdb.cell/dwarfaddr.S new file mode 100644 index 0000000..9ba9451 --- /dev/null +++ b/gdb/testsuite/gdb.cell/dwarfaddr.S @@ -0,0 +1,190 @@ +/* Copyright 2010 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + This file is part of the gdb testsuite. + + Contributed by Ulrich Weigand <uweigand@de.ibm.com>. + Tests for SPU addresses resulting from complex DWARF expressions. */ + + .text +main: +.Ltext_s: +.LFB1: + stqd $1,-240($1) + ai $1,$1,-240 + ai $2,$1,32 + ai $2,$2,127 + il $3,127 + andc $3,$2,$3 + il $2,1 + lqd $4,0($3) + cwd $5,0($3) + shufb $2,$2,$4,$5 + stqd $2,0($3) + lqd $1,0($1) + bi $0 +.LFE1: + .global main + .type main,@function + .size main,.LFE1-.LFB1 +.Ltext_e: + + .section .debug_info,"",@progbits +.Ldebug_info_s: + .int .debug_info_size-4 + .short 0x2 + .int .Ldebug_abbrev_s + .byte 0x4 +.Ldie0: + .uleb128 0x1 + .string "test.c" + .int .Ltext_s + .int .Ltext_e + .byte 0x1 +.Ldie1: + .uleb128 0x2 + .string "int" + .byte 0x4 + .byte 0x5 +.Ldie2: + .uleb128 0x3 + .int .Ldie4-.Ldebug_info_s + .int .Ldie1-.Ldebug_info_s +.Ldie3: + .uleb128 0x4 + .byte 0 + .byte 0xf + .uleb128 0 +.Ldie4: + .uleb128 0x5 + .string "main" + .int .LFB1 + .int .LFE1 + .byte 0x1 + .byte 0x1 + .byte 0x3 + .byte 0x1 + .byte 0x1 + .byte 0x51 +.Ldie5: + .uleb128 0x6 + .byte 0xe + .byte 0x91 + .sleb128 0x20 + .byte 0xd + .int 0x7f + .byte 0x22 + .byte 0xd + .int 0xffffff80 + .byte 0x1a + .string "x" + .byte 0x1 + .byte 0 + .int .Ldie2-.Ldebug_info_s + .uleb128 0 + .uleb128 0 +.Ldebug_info_e: + .set .debug_info_size,.Ldebug_info_e-.Ldebug_info_s + + + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev_s: + .uleb128 0x1 + .uleb128 0x11 + .byte 0x1 + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x11 + .uleb128 0x1 + .uleb128 0x12 + .uleb128 0x1 + .uleb128 0x13 + .uleb128 0xb + .uleb128 0 + .uleb128 0 + + .uleb128 0x2 + .uleb128 0x24 + .byte 0 + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0xb + .uleb128 0xb + .uleb128 0x3e + .uleb128 0xb + .uleb128 0 + .uleb128 0 + + .uleb128 0x3 + .uleb128 0x1 + .byte 0x1 + .uleb128 0x1 + .uleb128 0x13 + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0 + .uleb128 0 + + .uleb128 0x4 + .uleb128 0x21 + .byte 0 + .uleb128 0x22 + .uleb128 0xb + .uleb128 0x2f + .uleb128 0xb + .uleb128 0 + .uleb128 0 + + .uleb128 0x5 + .uleb128 0x2e + .byte 0x1 + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x11 + .uleb128 0x1 + .uleb128 0x12 + .uleb128 0x1 + .uleb128 0x27 + .uleb128 0xc + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x3f + .uleb128 0xc + .uleb128 0x40 + .uleb128 0xa + .uleb128 0 + .uleb128 0 + + .uleb128 0x6 + .uleb128 0x34 + .byte 0 + .uleb128 0x2 + .uleb128 0xa + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0 + .uleb128 0 + .uleb128 0 +.Ldebug_abbrev_e: + .set .debug_abbrev_size,.Ldebug_abbrev_e-.Ldebug_abbrev_s + diff --git a/gdb/testsuite/gdb.cell/dwarfaddr.exp b/gdb/testsuite/gdb.cell/dwarfaddr.exp new file mode 100644 index 0000000..e569474 --- /dev/null +++ b/gdb/testsuite/gdb.cell/dwarfaddr.exp @@ -0,0 +1,53 @@ +# Copyright 2010 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# This file is part of the gdb testsuite. +# +# Contributed by Ulrich Weigand <uweigand@de.ibm.com>. +# Tests for SPU addresses resulting from complex DWARF expressions. + +load_lib cell.exp + +set testfile "dwarfaddr" +set srcfile ${srcdir}/${subdir}/${testfile}.S +set binary ${objdir}/${subdir}/${testfile} + +if {[skip_cell_tests]} { + return 0 +} + +# Compile SPU binary. +if { [gdb_compile_cell_spu $srcfile $binary executable {debug}] != "" } { + unsupported "Compiling spu binary failed." + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binary} + +if ![runto_main] then { + fail "Can't run to main" + return 0 +} + +gdb_test "print x" " = \\{0 <repeats 16 times>\\}" "print x" +gdb_test "print &x" " = \\(int \\(\\*\\)\\\[16\\\]\\) 0x\[0-9a-f\]*" "print &x" +gdb_test "info address x" "Symbol \"x\" is a complex DWARF expression.*DW_OP_and\[\r\n\]+\." "info address x" + +gdb_exit + +return 0 |