* [RFA] fetch result of locdesc expressions as integer (not address)
@ 2011-10-03 21:10 Joel Brobecker
2011-10-04 17:16 ` Tom Tromey
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Joel Brobecker @ 2011-10-03 21:10 UTC (permalink / raw)
To: gdb-patches; +Cc: Joel Brobecker, Jan Kratochvil
This is a problem that showed up on AVR as well. The debugger
crashes while trying to print the contents of any struct value.
I was able to reduce the testcase as follow:
% cat foo.c
struct blob
{
int a;
int b;
};
struct blob global_blob = {1234, 5678};
int
main (void)
{
global_blob.a++; /* Stop here */
return 0;
}
To reproduce:
% gdb foo
(gdb) target sim
(gdb) load foo
(gdb) start
Starting program: /[...]/foo
Temporary breakpoint 1, main () at foo.c:13
13 global_blob.a++;
(gdb) p global_blob
[SEGV]
The problem is that the debugger is treating the result of
the DWARF location expressions as addresses, whereas this is
just an offset in this case. I think that this was an unintentional
side-effect of simplifying the code that fetches the result
from the DWARF expression computation stack. We had a bit of
code that used to fetch it, and turn it into a struct value.
And we replaced it by one call to a function that seemed to
be doing the same: dwarf_expr_fetch_address. The problem is
that dwarf_expr_fetch_address treats the result as an address,
and thus applies the integer_to_address gdbarch method. We do
not want that for struct field offsets...
gdb/ChangeLog:
* dwarf2read.c (decode_locdesc): Fetch the result of
the expression evaluation as an integer rather than
an address.
Tested on x86_64-linux, no regression.
Is that OK?
Thanks,
--
Joel
---
gdb/dwarf2read.c | 14 +++++++++++++-
1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index fc6a4d5..6f768a4 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14175,7 +14175,19 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
case DWARF_VALUE_MEMORY:
case DWARF_VALUE_STACK:
{
- CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0);
+ /* Fetch the result of the expression as an integer,
+ not as an address. We don't know whether it is an
+ address or not; for instance, it could be an expression
+ that returns the offset of a field inside a struct.
+ If we were to fetch the result as an address, we would
+ end up applying the integer_to_address gdbarch method.
+ That would be wrong in the case of an offset. */
+ struct value *val = dwarf_expr_fetch (ctx, 0);
+ enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch);
+ CORE_ADDR address =
+ extract_unsigned_integer (value_contents (val),
+ TYPE_LENGTH (value_type (val)),
+ byte_order);
do_cleanups (old_chain);
return address;
--
1.7.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFA] fetch result of locdesc expressions as integer (not address)
2011-10-03 21:10 [RFA] fetch result of locdesc expressions as integer (not address) Joel Brobecker
@ 2011-10-04 17:16 ` Tom Tromey
2011-10-04 19:32 ` Ulrich Weigand
2011-10-09 16:35 ` [patch#2] " Jan Kratochvil
2 siblings, 0 replies; 11+ messages in thread
From: Tom Tromey @ 2011-10-04 17:16 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches, Jan Kratochvil
>>>>> "Joel" == Joel Brobecker <brobecker@adacore.com> writes:
Joel> The problem is that the debugger is treating the result of
Joel> the DWARF location expressions as addresses, whereas this is
Joel> just an offset in this case. I think that this was an unintentional
Joel> side-effect of simplifying the code that fetches the result
Joel> from the DWARF expression computation stack. We had a bit of
Joel> code that used to fetch it, and turn it into a struct value.
Joel> And we replaced it by one call to a function that seemed to
Joel> be doing the same: dwarf_expr_fetch_address. The problem is
Joel> that dwarf_expr_fetch_address treats the result as an address,
Joel> and thus applies the integer_to_address gdbarch method. We do
Joel> not want that for struct field offsets...
dwarf_expr_fetch_address also calls dwarf_require_integral, which seems
like a good defensive thing to do in the replacement code.
I think the patch makes sense, but I'd like Jan to weigh in.
Tom
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFA] fetch result of locdesc expressions as integer (not address)
2011-10-03 21:10 [RFA] fetch result of locdesc expressions as integer (not address) Joel Brobecker
2011-10-04 17:16 ` Tom Tromey
@ 2011-10-04 19:32 ` Ulrich Weigand
2011-10-04 19:38 ` Joel Brobecker
2011-10-09 16:35 ` [patch#2] " Jan Kratochvil
2 siblings, 1 reply; 11+ messages in thread
From: Ulrich Weigand @ 2011-10-04 19:32 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches, Joel Brobecker, Jan Kratochvil
Joel Brobecker wrote:
> The problem is that the debugger is treating the result of
> the DWARF location expressions as addresses, whereas this is
> just an offset in this case. I think that this was an unintentional
> side-effect of simplifying the code that fetches the result
> from the DWARF expression computation stack. We had a bit of
> code that used to fetch it, and turn it into a struct value.
> And we replaced it by one call to a function that seemed to
> be doing the same: dwarf_expr_fetch_address. The problem is
> that dwarf_expr_fetch_address treats the result as an address,
> and thus applies the integer_to_address gdbarch method. We do
> not want that for struct field offsets...
>
> gdb/ChangeLog:
>
> * dwarf2read.c (decode_locdesc): Fetch the result of
> the expression evaluation as an integer rather than
> an address.
It seems the problem is a bit more complex: different callers
of decode_locdesc have different expectations. As the comment
before the routine says:
NOTE drow/2003-11-18: This function is called in two situations
now: for the address of static or global variables (partial symbols
only) and for offsets into structures which are expected to be
(more or less) constant.
In the first of these situations, dwarf_expr_fetch_address is
probably required on some architectures. Of course, in the
second situation (which is the one you ran into), we need to
treat the result as integer instead of address ...
Maybe we ought to have two routines (or a parameter) here.
[ In any case, from a quick look at the callers, some of those
really want to evaluate DWARF expressions only, not generic
location descriptions. But this distinction is mostly ignored
in the rest of our DWARF code as well ... that should probably
be cleaned up at some point. ]
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFA] fetch result of locdesc expressions as integer (not address)
2011-10-04 19:32 ` Ulrich Weigand
@ 2011-10-04 19:38 ` Joel Brobecker
2011-10-04 23:06 ` Ulrich Weigand
0 siblings, 1 reply; 11+ messages in thread
From: Joel Brobecker @ 2011-10-04 19:38 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches, Jan Kratochvil
> It seems the problem is a bit more complex: different callers
> of decode_locdesc have different expectations. As the comment
> before the routine says:
>
> NOTE drow/2003-11-18: This function is called in two situations
> now: for the address of static or global variables (partial symbols
> only) and for offsets into structures which are expected to be
> (more or less) constant.
That's true, but my interpretation was the callers of decode_locdesc
should know which they expect it to me, and thus know to apply
the integer_to_address correction.
> Maybe we ought to have two routines (or a parameter) here.
I think this is a good idea. But that's a bit beyond this patch.
We could add an extra routine, and implement the two using
a parameter. And then slowly transition all the callers that
read this as an address to use the new one.
--
Joel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFA] fetch result of locdesc expressions as integer (not address)
2011-10-04 19:38 ` Joel Brobecker
@ 2011-10-04 23:06 ` Ulrich Weigand
2011-10-05 1:09 ` Joel Brobecker
0 siblings, 1 reply; 11+ messages in thread
From: Ulrich Weigand @ 2011-10-04 23:06 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches, Jan Kratochvil
Joel Brobecker wrote:
> > It seems the problem is a bit more complex: different callers
> > of decode_locdesc have different expectations. As the comment
> > before the routine says:
> >
> > NOTE drow/2003-11-18: This function is called in two situations
> > now: for the address of static or global variables (partial symbols
> > only) and for offsets into structures which are expected to be
> > (more or less) constant.
>
> That's true, but my interpretation was the callers of decode_locdesc
> should know which they expect it to me, and thus know to apply
> the integer_to_address correction.
Well, maybe they should, but right now they don't, and neither does
your patch add any such correction. The point I was trying to make
is that therefore, your patch as it is, while fixing one class of
bugs on some targets, may simultaneously introduce a different class
of bugs on other targets. I'm not sure this is a good idea ...
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFA] fetch result of locdesc expressions as integer (not address)
2011-10-04 23:06 ` Ulrich Weigand
@ 2011-10-05 1:09 ` Joel Brobecker
2011-10-05 12:30 ` Ulrich Weigand
0 siblings, 1 reply; 11+ messages in thread
From: Joel Brobecker @ 2011-10-05 1:09 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches, Jan Kratochvil
> Well, maybe they should, but right now they don't, and neither does
> your patch add any such correction. The point I was trying to make
> is that therefore, your patch as it is, while fixing one class of
> bugs on some targets, may simultaneously introduce a different class
> of bugs on other targets. I'm not sure this is a good idea ...
I understand, but I'm just restoring the previous behavior which,
I believe was changed unintentionally. It's working fine for instance
on AVR, where the distinction makes a difference, so we're not doing
so bad. Additionally, I tested this patch against the testsuite
which does include a test for the problem that Jan wanted to fix.
BTW: Perhaps part of the reason why it is working OK right now
is that we do the integer-to-address adjustment only for
certain type codes. See value_as_address:
if (TYPE_CODE (value_type (val)) != TYPE_CODE_PTR
&& TYPE_CODE (value_type (val)) != TYPE_CODE_REF
&& gdbarch_integer_to_address_p (gdbarch))
return gdbarch_integer_to_address (gdbarch, value_type (val),
value_contents (val));
--
Joel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFA] fetch result of locdesc expressions as integer (not address)
2011-10-05 1:09 ` Joel Brobecker
@ 2011-10-05 12:30 ` Ulrich Weigand
0 siblings, 0 replies; 11+ messages in thread
From: Ulrich Weigand @ 2011-10-05 12:30 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches, Jan Kratochvil
Joel Brobecker wrote:
> > Well, maybe they should, but right now they don't, and neither does
> > your patch add any such correction. The point I was trying to make
> > is that therefore, your patch as it is, while fixing one class of
> > bugs on some targets, may simultaneously introduce a different class
> > of bugs on other targets. I'm not sure this is a good idea ...
>
> I understand, but I'm just restoring the previous behavior which,
> I believe was changed unintentionally.
Well, there *is* a change compared to the previous behavior (i.e. before
Jan's patch: http://sourceware.org/ml/gdb-patches/2011-07/msg00762.html).
Consider the typical case for DW_AT_location for a global variable:
just a single DW_OP_addr statement. This used to be handled previously
via a call to read_address. Note that read_address attempts to perform
target-specific conversions on the address, in particular it will be
sign-extended if required.
The dwarf_expr_eval machinery, on the other hand, does not use read_address
or otherwise attempt to sign-extend DW_OP_addr addresses. The thought here
is that performing that step at this point is premature, since subsequent
DWARF operations (e.g. to enforce alignment) may destroy the effect of such
extensions. Instead, the sign-extension is performed at the very end of
expression evaluation, via the architecture's integer_to_address routine,
if required.
So for example on mips, before Jan's patch, the address of a global variable
would have been sign-extended (in read_address); after Jan's patch, it would
*still* have been sign-extended (via integer_to_address); but after your
patch, it will no longer be.
> It's working fine for instance
> on AVR, where the distinction makes a difference, so we're not doing
> so bad. Additionally, I tested this patch against the testsuite
> which does include a test for the problem that Jan wanted to fix.
Hmm, looking into this a bit more, I think I understand why this change
doesn't affect testing. The only caller of decode_locdesc that actually
expects to handle full location descriptions returning an address is
add_partial_symbol when handling a DW_TAG_variable. However, the address
of a *partial* symbol for a *variable* (as opposed to a function) doesn't
appear to be used for anything; and in fact there is even a comment to
that effect ...
Given that, I withdraw my objection to the patch. It would still be
preferable IMO to no longer call decode_locdesc from add_partial_symbol
(but instead just handle those cases that this routine cares about,
along the lines of what var_decode_location does). But that can then
be a follow-on patch.
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 11+ messages in thread
* [patch#2] fetch result of locdesc expressions as integer (not address)
2011-10-03 21:10 [RFA] fetch result of locdesc expressions as integer (not address) Joel Brobecker
2011-10-04 17:16 ` Tom Tromey
2011-10-04 19:32 ` Ulrich Weigand
@ 2011-10-09 16:35 ` Jan Kratochvil
2011-10-17 1:56 ` Joel Brobecker
2 siblings, 1 reply; 11+ messages in thread
From: Jan Kratochvil @ 2011-10-09 16:35 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches, Ulrich Weigand
On Mon, 03 Oct 2011 23:10:14 +0200, Joel Brobecker wrote:
> The problem is that the debugger is treating the result of
> the DWARF location expressions as addresses, whereas this is
> just an offset in this case.
It is not an offset, the problem is it really is an address.
DWARF-4:
# The beginning address is pushed on the DWARF stack before the location
# description is evaluated; the result of the evaluation is the base address
# of the member entry.
Both former and current FSF GDB pushes bogus address 0 first simulating base
address of the struct.
- stack[stacki] = 0;
- stack[++stacki] = 0;
+ /* DW_AT_data_member_location expects the structure address to be pushed on
+ the stack. Simulate the offset by address 0. */
+ dwarf_expr_push_address (ctx, 0, 0);
Proposing to revert the patch of mine breaking it:
[patch 2/2] Fix decode_locdesc for gcc-4.7.x optimized DWARF
http://sourceware.org/ml/gdb-patches/2011-07/msg00762.html
49c026948157691b949769c8c3365d18cf74b319
It was there for DWARF-2 compatibility with GCC-4.7.x. It is unrelated to
DWARF-3+ as those use DW_FORM_udata as `constant' DWARF class is already
supported for DW_AT_data_member_location there). Jakub removed this temporary
GCC-4.7.x optimization - it is in fact not useful, it is only incompatible:
commit 946090338c2fdde793f035832d0b7544ed541132
Author: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Thu Jul 28 16:23:20 2011 +0000
* dwarf2out.c (resolve_addr): For -gdwarf-2 don't
optimize DW_AT_data_member_location containing just
DW_OP_plus_uconst.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@176878 138bc75d-0d04-0410-961f-82ee72b054a4
While trying to fix it I faced for example the exception for address 0 - isn't
it broken for AVR? Isn't SRAM address 0 a valid address?
static CORE_ADDR
avr_make_saddr (CORE_ADDR x)
{
/* Return 0 for NULL. */
if (x == 0)
return 0;
return ((x) | AVR_SMEM_START);
}
Unfortunately I cannot argue about AVR arch issues. Joel, do you run the
testsuite with iron AVR or is it OK to run it some way with sim/avr/ ?
I was trying to clean up the DWARF expression vs. location issues Ulrich
noted. The problem is the combination of (a) the AVR address 0 hack above and
(b) inability of GDB to do proper dynamic type with DWARF block as its dynamic
DW_AT_data_member_location attribute (easy - although not present there - with
archer-jankratochvil-vla) leading to more and more hacks.
There is a similar expression vs. location issue in the entryval patchset:
+ /* DW_AT_GNU_call_site_target is a DWARF expression, not a DWARF
+ location. */
+ if (VALUE_LVAL (val) == lval_memory)
+ return value_address (val);
+ else
+ return value_as_address (val);
just fortunately as the result is always address it should get IMO converted
right in both cases.
BTW I also tried to fix the crash - to report an error instead - but that is
not much possible unless the printing gets converted to `struct value'
compliant one. Currently it can address at least the virtual method table
content while still referencing the original value so there is no way to check
the boundaries.
It is a miracle GDB worked but if everyone was happy with the former state why
not to use it. When archer-jankratochvil-vla gets merged in some form
(reworked from scratch or at least significantly) - which needs to happen some
day anyway - I will happily reapply this reverted patch.
No regressions on {x86_64,x86_64-m32,i686}-fedora16pre-linux-gnu.
Sorry,
Jan
gdb/
2011-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
Revert:
2011-07-27 Jan Kratochvil <jan.kratochvil@redhat.com>
* dwarf2expr.c (ctx_no_read_reg): New function.
* dwarf2expr.h (ctx_no_read_reg): New declaration.
* dwarf2read.c (read_2_signed_bytes, read_4_signed_bytes): Remove.
(decode_locdesc_read_mem, decode_locdesc_ctx_funcs): New.
(decode_locdesc): Replace by a caller of dwarf_expr_eval.
gdb/testsuite/
2011-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.dwarf2/dw2-simple-locdesc.exp (p &s.shl): KFAIL it.
Revert the part of:
2011-07-27 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.dwarf2/dw2-stack-boundary.exp (check partial symtab errors):
Change the expected string.
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -1280,14 +1280,6 @@ abort_expression:
gdb_assert (ctx->recursion_depth >= 0);
}
-/* Stub dwarf_expr_context_funcs.read_reg implementation. */
-
-CORE_ADDR
-ctx_no_read_reg (void *baton, int regnum)
-{
- error (_("Registers access is invalid in this context"));
-}
-
/* Stub dwarf_expr_context_funcs.get_frame_base implementation. */
void
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -255,7 +255,6 @@ void dwarf_expr_require_composition (const gdb_byte *, const gdb_byte *,
/* Stub dwarf_expr_context_funcs implementations. */
-CORE_ADDR ctx_no_read_reg (void *baton, int regnum);
void ctx_no_get_frame_base (void *baton, const gdb_byte **start,
size_t *length);
CORE_ADDR ctx_no_get_frame_cfa (void *baton);
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -10015,12 +10015,24 @@ read_2_bytes (bfd *abfd, gdb_byte *buf)
return bfd_get_16 (abfd, buf);
}
+static int
+read_2_signed_bytes (bfd *abfd, gdb_byte *buf)
+{
+ return bfd_get_signed_16 (abfd, buf);
+}
+
static unsigned int
read_4_bytes (bfd *abfd, gdb_byte *buf)
{
return bfd_get_32 (abfd, buf);
}
+static int
+read_4_signed_bytes (bfd *abfd, gdb_byte *buf)
+{
+ return bfd_get_signed_32 (abfd, buf);
+}
+
static ULONGEST
read_8_bytes (bfd *abfd, gdb_byte *buf)
{
@@ -14084,37 +14096,6 @@ read_signatured_type (struct objfile *objfile,
dwarf2_per_objfile->read_in_chain = &type_sig->per_cu;
}
-/* Workaround as dwarf_expr_context_funcs.read_mem implementation before
- a proper runtime DWARF expressions evaluator gets implemented.
- Otherwise gnuv3_baseclass_offset would error by:
- Expected a negative vbase offset (old compiler?) */
-
-static void
-decode_locdesc_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr,
- size_t length)
-{
- struct dwarf_expr_context *ctx = baton;
- struct gdbarch *gdbarch = ctx->gdbarch;
- struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
-
- memset (buf, 0, length);
-
- if (TYPE_LENGTH (ptr_type) == length)
- store_typed_address (buf, ptr_type, addr);
-}
-
-static const struct dwarf_expr_context_funcs decode_locdesc_ctx_funcs =
-{
- ctx_no_read_reg,
- decode_locdesc_read_mem,
- ctx_no_get_frame_base,
- ctx_no_get_frame_cfa,
- ctx_no_get_frame_pc,
- ctx_no_get_tls_address,
- ctx_no_dwarf_call,
- ctx_no_get_base_type
-};
-
/* Decode simple location descriptions.
Given a pointer to a dwarf block that defines a location, compute
the location and return the value.
@@ -14132,59 +14113,235 @@ static const struct dwarf_expr_context_funcs decode_locdesc_ctx_funcs =
object is optimized out. The return value is 0 for that case.
FIXME drow/2003-11-16: No callers check for this case any more; soon all
callers will only want a very basic result and this can become a
- complaint. */
+ complaint.
+
+ Note that stack[0] is unused except as a default error return. */
static CORE_ADDR
decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- struct dwarf_expr_context *ctx;
- struct cleanup *old_chain;
- volatile struct gdb_exception ex;
+ int i;
+ int size = blk->size;
+ gdb_byte *data = blk->data;
+ CORE_ADDR stack[64];
+ int stacki;
+ unsigned int bytes_read, unsnd;
+ gdb_byte op;
- ctx = new_dwarf_expr_context ();
- old_chain = make_cleanup_free_dwarf_expr_context (ctx);
- make_cleanup_value_free_to_mark (value_mark ());
+ i = 0;
+ stacki = 0;
+ stack[stacki] = 0;
+ stack[++stacki] = 0;
- ctx->gdbarch = get_objfile_arch (objfile);
- ctx->addr_size = cu->header.addr_size;
- ctx->offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- ctx->baton = ctx;
- ctx->funcs = &decode_locdesc_ctx_funcs;
+ while (i < size)
+ {
+ op = data[i++];
+ switch (op)
+ {
+ case DW_OP_lit0:
+ case DW_OP_lit1:
+ case DW_OP_lit2:
+ case DW_OP_lit3:
+ case DW_OP_lit4:
+ case DW_OP_lit5:
+ case DW_OP_lit6:
+ case DW_OP_lit7:
+ case DW_OP_lit8:
+ case DW_OP_lit9:
+ case DW_OP_lit10:
+ case DW_OP_lit11:
+ case DW_OP_lit12:
+ case DW_OP_lit13:
+ case DW_OP_lit14:
+ case DW_OP_lit15:
+ case DW_OP_lit16:
+ case DW_OP_lit17:
+ case DW_OP_lit18:
+ case DW_OP_lit19:
+ case DW_OP_lit20:
+ case DW_OP_lit21:
+ case DW_OP_lit22:
+ case DW_OP_lit23:
+ case DW_OP_lit24:
+ case DW_OP_lit25:
+ case DW_OP_lit26:
+ case DW_OP_lit27:
+ case DW_OP_lit28:
+ case DW_OP_lit29:
+ case DW_OP_lit30:
+ case DW_OP_lit31:
+ stack[++stacki] = op - DW_OP_lit0;
+ break;
- /* DW_AT_data_member_location expects the structure address to be pushed on
- the stack. Simulate the offset by address 0. */
- dwarf_expr_push_address (ctx, 0, 0);
+ case DW_OP_reg0:
+ case DW_OP_reg1:
+ case DW_OP_reg2:
+ case DW_OP_reg3:
+ case DW_OP_reg4:
+ case DW_OP_reg5:
+ case DW_OP_reg6:
+ case DW_OP_reg7:
+ case DW_OP_reg8:
+ case DW_OP_reg9:
+ case DW_OP_reg10:
+ case DW_OP_reg11:
+ case DW_OP_reg12:
+ case DW_OP_reg13:
+ case DW_OP_reg14:
+ case DW_OP_reg15:
+ case DW_OP_reg16:
+ case DW_OP_reg17:
+ case DW_OP_reg18:
+ case DW_OP_reg19:
+ case DW_OP_reg20:
+ case DW_OP_reg21:
+ case DW_OP_reg22:
+ case DW_OP_reg23:
+ case DW_OP_reg24:
+ case DW_OP_reg25:
+ case DW_OP_reg26:
+ case DW_OP_reg27:
+ case DW_OP_reg28:
+ case DW_OP_reg29:
+ case DW_OP_reg30:
+ case DW_OP_reg31:
+ stack[++stacki] = op - DW_OP_reg0;
+ if (i < size)
+ dwarf2_complex_location_expr_complaint ();
+ break;
- TRY_CATCH (ex, RETURN_MASK_ERROR)
- {
- dwarf_expr_eval (ctx, blk->data, blk->size);
- }
- if (ex.reason < 0)
- {
- if (ex.message)
- complaint (&symfile_complaints, "%s", ex.message);
- }
- else if (ctx->num_pieces == 0)
- switch (ctx->location)
- {
- /* The returned number will be bogus, just do not complain for locations
- in global registers - it is here only a partial symbol address. */
- case DWARF_VALUE_REGISTER:
+ case DW_OP_regx:
+ unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ stack[++stacki] = unsnd;
+ if (i < size)
+ dwarf2_complex_location_expr_complaint ();
+ break;
- case DWARF_VALUE_MEMORY:
- case DWARF_VALUE_STACK:
- {
- CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0);
+ case DW_OP_addr:
+ stack[++stacki] = read_address (objfile->obfd, &data[i],
+ cu, &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_const1u:
+ stack[++stacki] = read_1_byte (objfile->obfd, &data[i]);
+ i += 1;
+ break;
+
+ case DW_OP_const1s:
+ stack[++stacki] = read_1_signed_byte (objfile->obfd, &data[i]);
+ i += 1;
+ break;
+
+ case DW_OP_const2u:
+ stack[++stacki] = read_2_bytes (objfile->obfd, &data[i]);
+ i += 2;
+ break;
+
+ case DW_OP_const2s:
+ stack[++stacki] = read_2_signed_bytes (objfile->obfd, &data[i]);
+ i += 2;
+ break;
- do_cleanups (old_chain);
- return address;
+ case DW_OP_const4u:
+ stack[++stacki] = read_4_bytes (objfile->obfd, &data[i]);
+ i += 4;
+ break;
+
+ case DW_OP_const4s:
+ stack[++stacki] = read_4_signed_bytes (objfile->obfd, &data[i]);
+ i += 4;
+ break;
+
+ case DW_OP_constu:
+ stack[++stacki] = read_unsigned_leb128 (NULL, (data + i),
+ &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_consts:
+ stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_dup:
+ stack[stacki + 1] = stack[stacki];
+ stacki++;
+ break;
+
+ case DW_OP_plus:
+ stack[stacki - 1] += stack[stacki];
+ stacki--;
+ break;
+
+ case DW_OP_plus_uconst:
+ stack[stacki] += read_unsigned_leb128 (NULL, (data + i),
+ &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_minus:
+ stack[stacki - 1] -= stack[stacki];
+ stacki--;
+ break;
+
+ case DW_OP_deref:
+ /* If we're not the last op, then we definitely can't encode
+ this using GDB's address_class enum. This is valid for partial
+ global symbols, although the variable's address will be bogus
+ in the psymtab. */
+ if (i < size)
+ dwarf2_complex_location_expr_complaint ();
+ break;
+
+ case DW_OP_GNU_push_tls_address:
+ /* The top of the stack has the offset from the beginning
+ of the thread control block at which the variable is located. */
+ /* Nothing should follow this operator, so the top of stack would
+ be returned. */
+ /* This is valid for partial global symbols, but the variable's
+ address will be bogus in the psymtab. */
+ if (i < size)
+ dwarf2_complex_location_expr_complaint ();
+ break;
+
+ case DW_OP_GNU_uninit:
+ break;
+
+ default:
+ {
+ const char *name = dwarf_stack_op_name (op);
+
+ if (name)
+ complaint (&symfile_complaints, _("unsupported stack op: '%s'"),
+ name);
+ else
+ complaint (&symfile_complaints, _("unsupported stack op: '%02x'"),
+ op);
+ }
+
+ return (stack[stacki]);
}
- }
- do_cleanups (old_chain);
- dwarf2_complex_location_expr_complaint ();
- return 0;
+ /* Enforce maximum stack depth of SIZE-1 to avoid writing
+ outside of the allocated space. Also enforce minimum>0. */
+ if (stacki >= ARRAY_SIZE (stack) - 1)
+ {
+ complaint (&symfile_complaints,
+ _("location description stack overflow"));
+ return 0;
+ }
+
+ if (stacki <= 0)
+ {
+ complaint (&symfile_complaints,
+ _("location description stack underflow"));
+ return 0;
+ }
+ }
+ return (stack[stacki]);
}
/* memory allocation interface */
--- a/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.exp
@@ -32,7 +32,15 @@ clean_restart $executable
# Re: [patch 2/2] Fix decode_locdesc for gcc-4.7.x optimized DWARF
# http://sourceware.org/ml/gdb-patches/2011-07/msg00766.html
-gdb_test "p &s.shl" { = \(int \*\) 0x1000000}
+set test "p &s.shl"
+gdb_test_multiple $test $test {
+ -re " = \\(int \\*\\) 0x1000000\r\n$gdb_prompt $" {
+ pass $test
+ }
+ -re " = \\(int \\*\\) 0x14\r\n$gdb_prompt $" {
+ kfail "gdb/9999" $test
+ }
+}
# Re: RFC: fix DW_AT_data_member_location buglet
# http://sourceware.org/ml/gdb-patches/2011-05/msg00291.html
--- a/gdb/testsuite/gdb.dwarf2/dw2-stack-boundary.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-stack-boundary.exp
@@ -41,7 +41,7 @@ if [is_remote host] {
}
}
gdb_test_no_output "set complaints 100"
-gdb_test "file $binfile" {Reading symbols from .*\.\.\.Asked for position 0 of stack, stack only has 0 elements on it\..*\.\.\.done\.} "check partial symtab errors"
+gdb_test "file $binfile" {Reading symbols from .*\.\.\.location description stack underflow\.\.\.location description stack overflow\.\.\.done\.} "check partial symtab errors"
gdb_test "p underflow" {Asked for position 0 of stack, stack only has 0 elements on it\.}
gdb_test "p overflow" " = 2"
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [patch#2] fetch result of locdesc expressions as integer (not address)
2011-10-09 16:35 ` [patch#2] " Jan Kratochvil
@ 2011-10-17 1:56 ` Joel Brobecker
2011-10-17 7:59 ` Tristan Gingold
0 siblings, 1 reply; 11+ messages in thread
From: Joel Brobecker @ 2011-10-17 1:56 UTC (permalink / raw)
To: Jan Kratochvil, Tristan Gingold; +Cc: gdb-patches, Ulrich Weigand
> It is not an offset, the problem is it really is an address.
>
> DWARF-4:
> # The beginning address is pushed on the DWARF stack before the location
> # description is evaluated; the result of the evaluation is the base address
> # of the member entry.
Ah - I missed that part of the standard, and that helps understand
the command that pushes the null address indeed.
> Both former and current FSF GDB pushes bogus address 0 first
> simulating base address of the struct.
> - stack[stacki] = 0;
> - stack[++stacki] = 0;
> + /* DW_AT_data_member_location expects the structure address to be pushed on
> + the stack. Simulate the offset by address 0. */
> + dwarf_expr_push_address (ctx, 0, 0);
What we could perhaps try is to push 'integer-to-address(0)', rather
than zero itself. Then, if we want the offset, then subtract that
same integer-to-address(0) value from the result.
> While trying to fix it I faced for example the exception for address 0 - isn't
> it broken for AVR? Isn't SRAM address 0 a valid address?
> static CORE_ADDR
> avr_make_saddr (CORE_ADDR x)
> {
> /* Return 0 for NULL. */
> if (x == 0)
> return 0;
>
> return ((x) | AVR_SMEM_START);
> }
> Unfortunately I cannot argue about AVR arch issues.
Me neither, and the documentations I have been able to find wheren't
very clear or complete. I suspect that this is because it's not
typical CPU, but rather a micro controler. I'm copying Tristan
who knows this architecture better.
> Joel, do you run the testsuite with iron AVR or is it OK to run it
> some way with sim/avr/ ?
We run our testsuite with the GDB simulator. For the official testsuite,
there should be a way to do it, and I have an email from Kevin that
should put me on the track, but for now, we have never really done it.
> gdb/
> 2011-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
>
> Revert:
> 2011-07-27 Jan Kratochvil <jan.kratochvil@redhat.com>
> * dwarf2expr.c (ctx_no_read_reg): New function.
> * dwarf2expr.h (ctx_no_read_reg): New declaration.
> * dwarf2read.c (read_2_signed_bytes, read_4_signed_bytes): Remove.
> (decode_locdesc_read_mem, decode_locdesc_ctx_funcs): New.
> (decode_locdesc): Replace by a caller of dwarf_expr_eval.
>
> gdb/testsuite/
> 2011-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
>
> * gdb.dwarf2/dw2-simple-locdesc.exp (p &s.shl): KFAIL it.
> Revert the part of:
> 2011-07-27 Jan Kratochvil <jan.kratochvil@redhat.com>
> * gdb.dwarf2/dw2-stack-boundary.exp (check partial symtab errors):
> Change the expected string.
Based on the reasons you provided, it seems indeed that this patch
is no longer really necessary. On the other hand, you are right
to say that it's a bit of a miracle that things are working so far.
--
Joel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [patch#2] fetch result of locdesc expressions as integer (not address)
2011-10-17 1:56 ` Joel Brobecker
@ 2011-10-17 7:59 ` Tristan Gingold
2011-10-17 13:22 ` [commit] " Jan Kratochvil
0 siblings, 1 reply; 11+ messages in thread
From: Tristan Gingold @ 2011-10-17 7:59 UTC (permalink / raw)
To: Joel Brobecker; +Cc: Jan Kratochvil, gdb-patches, Ulrich Weigand
On Oct 17, 2011, at 1:32 AM, Joel Brobecker wrote:
>> It is not an offset, the problem is it really is an address.
>>
>> DWARF-4:
>> # The beginning address is pushed on the DWARF stack before the location
>> # description is evaluated; the result of the evaluation is the base address
>> # of the member entry.
>
> Ah - I missed that part of the standard, and that helps understand
> the command that pushes the null address indeed.
>
>> Both former and current FSF GDB pushes bogus address 0 first
>> simulating base address of the struct.
>> - stack[stacki] = 0;
>> - stack[++stacki] = 0;
>> + /* DW_AT_data_member_location expects the structure address to be pushed on
>> + the stack. Simulate the offset by address 0. */
>> + dwarf_expr_push_address (ctx, 0, 0);
>
> What we could perhaps try is to push 'integer-to-address(0)', rather
> than zero itself. Then, if we want the offset, then subtract that
> same integer-to-address(0) value from the result.
>
>> While trying to fix it I faced for example the exception for address 0 - isn't
>> it broken for AVR? Isn't SRAM address 0 a valid address?
>> static CORE_ADDR
>> avr_make_saddr (CORE_ADDR x)
>> {
>> /* Return 0 for NULL. */
>> if (x == 0)
>> return 0;
>>
>> return ((x) | AVR_SMEM_START);
>> }
>> Unfortunately I cannot argue about AVR arch issues.
>
> Me neither, and the documentations I have been able to find wheren't
> very clear or complete. I suspect that this is because it's not
> typical CPU, but rather a micro controler. I'm copying Tristan
> who knows this architecture better.
SRAM address 0 is valid, but if you convert NULL to a non-0 value, many things get broken!
Tristan.
>
>> Joel, do you run the testsuite with iron AVR or is it OK to run it
>> some way with sim/avr/ ?
>
> We run our testsuite with the GDB simulator. For the official testsuite,
> there should be a way to do it, and I have an email from Kevin that
> should put me on the track, but for now, we have never really done it.
>
>> gdb/
>> 2011-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
>>
>> Revert:
>> 2011-07-27 Jan Kratochvil <jan.kratochvil@redhat.com>
>> * dwarf2expr.c (ctx_no_read_reg): New function.
>> * dwarf2expr.h (ctx_no_read_reg): New declaration.
>> * dwarf2read.c (read_2_signed_bytes, read_4_signed_bytes): Remove.
>> (decode_locdesc_read_mem, decode_locdesc_ctx_funcs): New.
>> (decode_locdesc): Replace by a caller of dwarf_expr_eval.
>>
>> gdb/testsuite/
>> 2011-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
>>
>> * gdb.dwarf2/dw2-simple-locdesc.exp (p &s.shl): KFAIL it.
>> Revert the part of:
>> 2011-07-27 Jan Kratochvil <jan.kratochvil@redhat.com>
>> * gdb.dwarf2/dw2-stack-boundary.exp (check partial symtab errors):
>> Change the expected string.
>
> Based on the reasons you provided, it seems indeed that this patch
> is no longer really necessary. On the other hand, you are right
> to say that it's a bit of a miracle that things are working so far.
>
> --
> Joel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [commit] [patch#2] fetch result of locdesc expressions as integer (not address)
2011-10-17 7:59 ` Tristan Gingold
@ 2011-10-17 13:22 ` Jan Kratochvil
0 siblings, 0 replies; 11+ messages in thread
From: Jan Kratochvil @ 2011-10-17 13:22 UTC (permalink / raw)
To: Tristan Gingold; +Cc: Joel Brobecker, gdb-patches, Ulrich Weigand
On Mon, 17 Oct 2011 09:13:00 +0200, Tristan Gingold wrote:
> On Oct 17, 2011, at 1:32 AM, Joel Brobecker wrote:
> > What we could perhaps try is to push 'integer-to-address(0)', rather
> > than zero itself. Then, if we want the offset, then subtract that
> > same integer-to-address(0) value from the result.
+
> SRAM address 0 is valid, but if you convert NULL to a non-0 value, many
> things get broken!
You can see the Joel's idea does not work due to it. The very first field
stays at 0 while every other field gets shifted by 0x800000.
I believe the NULL exception should be in specific cases at the callers.
One would have to create some 0xdeadf00d artificial address as the base struct
address but I do not think one can create arbitrary addresses as on gdbarches
it may not be a valid address.
Just there is no real reason to keep the patch in place now, I should review
it after some form of archer-jankratochvil-vla gets in.
Filed a new KFAIL-tracker:
Support DW_AT_location complex DWARF expressions
http://sourceware.org/bugzilla/show_bug.cgi?id=13307
and checked in the reversion.
Sorry,
Jan
http://sourceware.org/ml/gdb-cvs/2011-10/msg00132.html
--- src/gdb/ChangeLog 2011/10/16 19:40:36 1.13439
+++ src/gdb/ChangeLog 2011/10/17 12:57:13 1.13440
@@ -1,3 +1,13 @@
+2011-10-17 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ Revert:
+ 2011-07-27 Jan Kratochvil <jan.kratochvil@redhat.com>
+ * dwarf2expr.c (ctx_no_read_reg): New function.
+ * dwarf2expr.h (ctx_no_read_reg): New declaration.
+ * dwarf2read.c (read_2_signed_bytes, read_4_signed_bytes): Remove.
+ (decode_locdesc_read_mem, decode_locdesc_ctx_funcs): New.
+ (decode_locdesc): Replace by a caller of dwarf_expr_eval.
+
2011-10-16 Doug Evans <dje@google.com>
* NEWS: Document python gdb.printing.register_pretty_printer's new
--- src/gdb/testsuite/ChangeLog 2011/10/16 08:42:02 1.2899
+++ src/gdb/testsuite/ChangeLog 2011/10/17 12:57:15 1.2900
@@ -1,3 +1,11 @@
+2011-10-17 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * gdb.dwarf2/dw2-simple-locdesc.exp (p &s.shl): KFAIL it.
+ Revert the part of:
+ 2011-07-27 Jan Kratochvil <jan.kratochvil@redhat.com>
+ * gdb.dwarf2/dw2-stack-boundary.exp (check partial symtab errors):
+ Change the expected string.
+
2011-10-16 Jan Kratochvil <jan.kratochvil@redhat.com>
Fix results with system glibc debug info installed.
--- src/gdb/dwarf2expr.c 2011/10/09 19:43:40 1.76
+++ src/gdb/dwarf2expr.c 2011/10/17 12:57:14 1.77
@@ -1471,14 +1471,6 @@
gdb_assert (ctx->recursion_depth >= 0);
}
-/* Stub dwarf_expr_context_funcs.read_reg implementation. */
-
-CORE_ADDR
-ctx_no_read_reg (void *baton, int regnum)
-{
- error (_("Registers access is invalid in this context"));
-}
-
/* Stub dwarf_expr_context_funcs.get_frame_base implementation. */
void
--- src/gdb/dwarf2expr.h 2011/10/09 19:43:40 1.41
+++ src/gdb/dwarf2expr.h 2011/10/17 12:57:14 1.42
@@ -270,7 +270,6 @@
/* Stub dwarf_expr_context_funcs implementations. */
-CORE_ADDR ctx_no_read_reg (void *baton, int regnum);
void ctx_no_get_frame_base (void *baton, const gdb_byte **start,
size_t *length);
CORE_ADDR ctx_no_get_frame_cfa (void *baton);
--- src/gdb/dwarf2read.c 2011/10/13 09:36:47 1.573
+++ src/gdb/dwarf2read.c 2011/10/17 12:57:14 1.574
@@ -10297,12 +10297,24 @@
return bfd_get_16 (abfd, buf);
}
+static int
+read_2_signed_bytes (bfd *abfd, gdb_byte *buf)
+{
+ return bfd_get_signed_16 (abfd, buf);
+}
+
static unsigned int
read_4_bytes (bfd *abfd, gdb_byte *buf)
{
return bfd_get_32 (abfd, buf);
}
+static int
+read_4_signed_bytes (bfd *abfd, gdb_byte *buf)
+{
+ return bfd_get_signed_32 (abfd, buf);
+}
+
static ULONGEST
read_8_bytes (bfd *abfd, gdb_byte *buf)
{
@@ -14419,37 +14431,6 @@
dwarf2_per_objfile->read_in_chain = &type_sig->per_cu;
}
-/* Workaround as dwarf_expr_context_funcs.read_mem implementation before
- a proper runtime DWARF expressions evaluator gets implemented.
- Otherwise gnuv3_baseclass_offset would error by:
- Expected a negative vbase offset (old compiler?) */
-
-static void
-decode_locdesc_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr,
- size_t length)
-{
- struct dwarf_expr_context *ctx = baton;
- struct gdbarch *gdbarch = ctx->gdbarch;
- struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
-
- memset (buf, 0, length);
-
- if (TYPE_LENGTH (ptr_type) == length)
- store_typed_address (buf, ptr_type, addr);
-}
-
-static const struct dwarf_expr_context_funcs decode_locdesc_ctx_funcs =
-{
- ctx_no_read_reg,
- decode_locdesc_read_mem,
- ctx_no_get_frame_base,
- ctx_no_get_frame_cfa,
- ctx_no_get_frame_pc,
- ctx_no_get_tls_address,
- ctx_no_dwarf_call,
- ctx_no_get_base_type
-};
-
/* Decode simple location descriptions.
Given a pointer to a dwarf block that defines a location, compute
the location and return the value.
@@ -14467,60 +14448,235 @@
object is optimized out. The return value is 0 for that case.
FIXME drow/2003-11-16: No callers check for this case any more; soon all
callers will only want a very basic result and this can become a
- complaint. */
+ complaint.
+
+ Note that stack[0] is unused except as a default error return. */
static CORE_ADDR
decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- struct dwarf_expr_context *ctx;
- struct cleanup *old_chain;
- volatile struct gdb_exception ex;
+ int i;
+ int size = blk->size;
+ gdb_byte *data = blk->data;
+ CORE_ADDR stack[64];
+ int stacki;
+ unsigned int bytes_read, unsnd;
+ gdb_byte op;
- ctx = new_dwarf_expr_context ();
- old_chain = make_cleanup_free_dwarf_expr_context (ctx);
- make_cleanup_value_free_to_mark (value_mark ());
+ i = 0;
+ stacki = 0;
+ stack[stacki] = 0;
+ stack[++stacki] = 0;
- ctx->gdbarch = get_objfile_arch (objfile);
- ctx->addr_size = cu->header.addr_size;
- ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (cu->per_cu);
- ctx->offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- ctx->baton = ctx;
- ctx->funcs = &decode_locdesc_ctx_funcs;
+ while (i < size)
+ {
+ op = data[i++];
+ switch (op)
+ {
+ case DW_OP_lit0:
+ case DW_OP_lit1:
+ case DW_OP_lit2:
+ case DW_OP_lit3:
+ case DW_OP_lit4:
+ case DW_OP_lit5:
+ case DW_OP_lit6:
+ case DW_OP_lit7:
+ case DW_OP_lit8:
+ case DW_OP_lit9:
+ case DW_OP_lit10:
+ case DW_OP_lit11:
+ case DW_OP_lit12:
+ case DW_OP_lit13:
+ case DW_OP_lit14:
+ case DW_OP_lit15:
+ case DW_OP_lit16:
+ case DW_OP_lit17:
+ case DW_OP_lit18:
+ case DW_OP_lit19:
+ case DW_OP_lit20:
+ case DW_OP_lit21:
+ case DW_OP_lit22:
+ case DW_OP_lit23:
+ case DW_OP_lit24:
+ case DW_OP_lit25:
+ case DW_OP_lit26:
+ case DW_OP_lit27:
+ case DW_OP_lit28:
+ case DW_OP_lit29:
+ case DW_OP_lit30:
+ case DW_OP_lit31:
+ stack[++stacki] = op - DW_OP_lit0;
+ break;
+
+ case DW_OP_reg0:
+ case DW_OP_reg1:
+ case DW_OP_reg2:
+ case DW_OP_reg3:
+ case DW_OP_reg4:
+ case DW_OP_reg5:
+ case DW_OP_reg6:
+ case DW_OP_reg7:
+ case DW_OP_reg8:
+ case DW_OP_reg9:
+ case DW_OP_reg10:
+ case DW_OP_reg11:
+ case DW_OP_reg12:
+ case DW_OP_reg13:
+ case DW_OP_reg14:
+ case DW_OP_reg15:
+ case DW_OP_reg16:
+ case DW_OP_reg17:
+ case DW_OP_reg18:
+ case DW_OP_reg19:
+ case DW_OP_reg20:
+ case DW_OP_reg21:
+ case DW_OP_reg22:
+ case DW_OP_reg23:
+ case DW_OP_reg24:
+ case DW_OP_reg25:
+ case DW_OP_reg26:
+ case DW_OP_reg27:
+ case DW_OP_reg28:
+ case DW_OP_reg29:
+ case DW_OP_reg30:
+ case DW_OP_reg31:
+ stack[++stacki] = op - DW_OP_reg0;
+ if (i < size)
+ dwarf2_complex_location_expr_complaint ();
+ break;
+
+ case DW_OP_regx:
+ unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ stack[++stacki] = unsnd;
+ if (i < size)
+ dwarf2_complex_location_expr_complaint ();
+ break;
+
+ case DW_OP_addr:
+ stack[++stacki] = read_address (objfile->obfd, &data[i],
+ cu, &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_const1u:
+ stack[++stacki] = read_1_byte (objfile->obfd, &data[i]);
+ i += 1;
+ break;
+
+ case DW_OP_const1s:
+ stack[++stacki] = read_1_signed_byte (objfile->obfd, &data[i]);
+ i += 1;
+ break;
+
+ case DW_OP_const2u:
+ stack[++stacki] = read_2_bytes (objfile->obfd, &data[i]);
+ i += 2;
+ break;
+
+ case DW_OP_const2s:
+ stack[++stacki] = read_2_signed_bytes (objfile->obfd, &data[i]);
+ i += 2;
+ break;
+
+ case DW_OP_const4u:
+ stack[++stacki] = read_4_bytes (objfile->obfd, &data[i]);
+ i += 4;
+ break;
+
+ case DW_OP_const4s:
+ stack[++stacki] = read_4_signed_bytes (objfile->obfd, &data[i]);
+ i += 4;
+ break;
+
+ case DW_OP_constu:
+ stack[++stacki] = read_unsigned_leb128 (NULL, (data + i),
+ &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_consts:
+ stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_dup:
+ stack[stacki + 1] = stack[stacki];
+ stacki++;
+ break;
+
+ case DW_OP_plus:
+ stack[stacki - 1] += stack[stacki];
+ stacki--;
+ break;
+
+ case DW_OP_plus_uconst:
+ stack[stacki] += read_unsigned_leb128 (NULL, (data + i),
+ &bytes_read);
+ i += bytes_read;
+ break;
+
+ case DW_OP_minus:
+ stack[stacki - 1] -= stack[stacki];
+ stacki--;
+ break;
+
+ case DW_OP_deref:
+ /* If we're not the last op, then we definitely can't encode
+ this using GDB's address_class enum. This is valid for partial
+ global symbols, although the variable's address will be bogus
+ in the psymtab. */
+ if (i < size)
+ dwarf2_complex_location_expr_complaint ();
+ break;
+
+ case DW_OP_GNU_push_tls_address:
+ /* The top of the stack has the offset from the beginning
+ of the thread control block at which the variable is located. */
+ /* Nothing should follow this operator, so the top of stack would
+ be returned. */
+ /* This is valid for partial global symbols, but the variable's
+ address will be bogus in the psymtab. */
+ if (i < size)
+ dwarf2_complex_location_expr_complaint ();
+ break;
- /* DW_AT_data_member_location expects the structure address to be pushed on
- the stack. Simulate the offset by address 0. */
- dwarf_expr_push_address (ctx, 0, 0);
+ case DW_OP_GNU_uninit:
+ break;
- TRY_CATCH (ex, RETURN_MASK_ERROR)
- {
- dwarf_expr_eval (ctx, blk->data, blk->size);
- }
- if (ex.reason < 0)
- {
- if (ex.message)
- complaint (&symfile_complaints, "%s", ex.message);
- }
- else if (ctx->num_pieces == 0)
- switch (ctx->location)
- {
- /* The returned number will be bogus, just do not complain for locations
- in global registers - it is here only a partial symbol address. */
- case DWARF_VALUE_REGISTER:
+ default:
+ {
+ const char *name = dwarf_stack_op_name (op);
- case DWARF_VALUE_MEMORY:
- case DWARF_VALUE_STACK:
- {
- CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0);
+ if (name)
+ complaint (&symfile_complaints, _("unsupported stack op: '%s'"),
+ name);
+ else
+ complaint (&symfile_complaints, _("unsupported stack op: '%02x'"),
+ op);
+ }
- do_cleanups (old_chain);
- return address;
+ return (stack[stacki]);
}
- }
- do_cleanups (old_chain);
- dwarf2_complex_location_expr_complaint ();
- return 0;
+ /* Enforce maximum stack depth of SIZE-1 to avoid writing
+ outside of the allocated space. Also enforce minimum>0. */
+ if (stacki >= ARRAY_SIZE (stack) - 1)
+ {
+ complaint (&symfile_complaints,
+ _("location description stack overflow"));
+ return 0;
+ }
+
+ if (stacki <= 0)
+ {
+ complaint (&symfile_complaints,
+ _("location description stack underflow"));
+ return 0;
+ }
+ }
+ return (stack[stacki]);
}
/* memory allocation interface */
--- src/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.exp 2011/07/27 21:18:40 1.2
+++ src/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.exp 2011/10/17 12:57:15 1.3
@@ -32,7 +32,15 @@
# Re: [patch 2/2] Fix decode_locdesc for gcc-4.7.x optimized DWARF
# http://sourceware.org/ml/gdb-patches/2011-07/msg00766.html
-gdb_test "p &s.shl" { = \(int \*\) 0x1000000}
+set test "p &s.shl"
+gdb_test_multiple $test $test {
+ -re " = \\(int \\*\\) 0x1000000\r\n$gdb_prompt $" {
+ pass $test
+ }
+ -re " = \\(int \\*\\) 0x14\r\n$gdb_prompt $" {
+ kfail "symtab/13307" $test
+ }
+}
# Re: RFC: fix DW_AT_data_member_location buglet
# http://sourceware.org/ml/gdb-patches/2011-05/msg00291.html
--- src/gdb/testsuite/gdb.dwarf2/dw2-stack-boundary.exp 2011/07/27 17:08:06 1.4
+++ src/gdb/testsuite/gdb.dwarf2/dw2-stack-boundary.exp 2011/10/17 12:57:15 1.5
@@ -41,7 +41,7 @@
}
}
gdb_test_no_output "set complaints 100"
-gdb_test "file $binfile" {Reading symbols from .*\.\.\.Asked for position 0 of stack, stack only has 0 elements on it\..*\.\.\.done\.} "check partial symtab errors"
+gdb_test "file $binfile" {Reading symbols from .*\.\.\.location description stack underflow\.\.\.location description stack overflow\.\.\.done\.} "check partial symtab errors"
gdb_test "p underflow" {Asked for position 0 of stack, stack only has 0 elements on it\.}
gdb_test "p overflow" " = 2"
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2011-10-17 13:00 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-03 21:10 [RFA] fetch result of locdesc expressions as integer (not address) Joel Brobecker
2011-10-04 17:16 ` Tom Tromey
2011-10-04 19:32 ` Ulrich Weigand
2011-10-04 19:38 ` Joel Brobecker
2011-10-04 23:06 ` Ulrich Weigand
2011-10-05 1:09 ` Joel Brobecker
2011-10-05 12:30 ` Ulrich Weigand
2011-10-09 16:35 ` [patch#2] " Jan Kratochvil
2011-10-17 1:56 ` Joel Brobecker
2011-10-17 7:59 ` Tristan Gingold
2011-10-17 13:22 ` [commit] " Jan Kratochvil
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox