* [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect
@ 2011-02-07 14:35 Pedro Alves
2011-02-14 12:01 ` Jan Kratochvil
0 siblings, 1 reply; 13+ messages in thread
From: Pedro Alves @ 2011-02-07 14:35 UTC (permalink / raw)
To: gdb-patches
While writing a test for a rtti related patch, I noticed that
the test was failing because somehow, GDB was managing to print
a pointer's value, although the tracepoint wasn't told to collect
it. The reason the pointer was being collected, turned out to
be that when GDB is encoding the tracepoint actions, it merges
overlapping and adjacent ranges that should be collected into
a single memory collection request (fine), but, it also
merges ranges if the hole between them is narrower than
or equal to MAX_REGISTER_SIZE. E.g., if the tracepoint's
actions wants to collect both:
[0x10000, 0x10004) and [0x10004, 0x10008),
then GDB merges the actions into a single collect memory
action like:
[0x10000, 0x10008)
That's fine. But if the tracepoint wants to
collect
[0x10000, 0x10004) and [0x10008, 0x10010),
then GDB still merges these into
[0x10000, 0x10010)
thus collecting [0x10004, 0x10008) as well.
My guess is that this was an attempt at minimizing trace
buffer overhead on the target side. But, this is bogus
for several reasons:
- MAX_REGISTER_SIZE is really a wrong constant for this.
GDB's internal maximum register size supported is really
unrelated to this. It has been recently bumped to 64
recently. That's a lot of waste in the trace buffer.
Obviously, we could come up with our own constant for
this, but,
- An optimization like this is really the target's business
to do, because only the target knows its trace buffer's
layout, and what is the gap width where merging becomes
beneficial.
- Collecting memory mapped registers come to mind, where
reading more than you've asked for is a bad idea.
- Given the agent expression generator's status quo, you
only get memory range actions on the target if you collect
globals anyway. Anything else, the agent expression
generator outputs a trace agent expression. E.g.,
(gdb) maint agent struct_b.ef
Scope: 0x400711
Reg mask: 00
0 const32 6295936
5 const8 4
7 add
8 const8 4
10 trace
11 end
(gdb) maint agent struct_b.d
Scope: 0x400711
Reg mask: 00
0 const32 6295936
5 const8 4
7 trace
8 end
(gdb) maint agent tarray [1].b
Scope: 0x400711
Reg mask: 00
0 const32 6295840
5 const8 1
7 const8 8
9 mul
10 add
11 zero_ext 64
13 const8 4
15 add
16 const8 4
18 trace
19 end
These encode as an 'X' action. Notice how we always output
base + arithmetic, even if the offsets are constants. With this,
it's doubtful that the "optimization" has ever payed off.
- It may be that this was added as a means of avoiding confusion
between 0 (not collected), and 0 (really 0), when collecting
only a few fields of a structure or array, but per the point
above, that can't really have ever worked.
For these reasons, I'm removing the heuristic from GDB.
--
Pedro Alves
2011-02-07 Pedro Alves <pedro@codesourcery.com>
gdb/testuite/
* gdb.trace/unavailable.cc (a, b, c): New globals.
(main): Set and clear them.
* gdb.trace/unavailable.exp (gdb_collect_globals_test): Collect
`a' and `c', and check that `b' isn't collected, although `a' and
`c' are.
gdb/
* tracepoint.c (memrange_sortmerge): Don't merge ranges that are
almost but not quite adjacent.
---
gdb/testsuite/gdb.trace/unavailable.cc | 22 ++++++++++++++++++++++
gdb/testsuite/gdb.trace/unavailable.exp | 12 ++++++++++++
gdb/tracepoint.c | 11 +++++------
3 files changed, 39 insertions(+), 6 deletions(-)
Index: src/gdb/testsuite/gdb.trace/unavailable.cc
===================================================================
--- src.orig/gdb/testsuite/gdb.trace/unavailable.cc 2011-02-07 13:24:23.726706003 +0000
+++ src/gdb/testsuite/gdb.trace/unavailable.cc 2011-02-07 13:27:53.276706002 +0000
@@ -71,6 +71,25 @@ struct tuple
struct tuple tarray[8];
+/* Test for overcollection. GDB used to merge memory ranges to
+ collect if they were close enough --- say, collect `a' and 'c'
+ below, and you'd get 'b' as well. This had been presumably done to
+ cater for some target's inefficient trace buffer layout, but it is
+ really not GDB's business to assume how the target manages its
+ buffer. If the target wants to overcollect, that's okay, since it
+ knows what is and what isn't safe to touch (think memory mapped
+ registers), and knows it's buffer layout.
+
+ The test assumes these three variables are laid out consecutively
+ in memory. Unfortunately, we can't use an array instead, since the
+ agent expression generator does not even do constant folding,
+ meaning that anything that's more complicated than collecting a
+ global will generate an agent expression action to evaluate on the
+ target, instead of a simple "collect memory" action. */
+int a;
+int b;
+int c;
+
/* Random tests. */
struct StructA
@@ -185,6 +204,7 @@ main (int argc, char **argv, char **envp
memcpy (g_string_unavail, g_const_string, sizeof (g_const_string));
memcpy (g_string_partial, g_const_string, sizeof (g_const_string));
g_string_p = g_const_string;
+ a = 1; b = 2; c = 3;
/* Call test functions, so they can be traced and data collected. */
i = 0;
@@ -212,6 +232,8 @@ main (int argc, char **argv, char **envp
memset (g_string_partial, 0, sizeof (g_string_partial));
g_string_p = NULL;
+ a = b = c = 0;
+
g_int = 0;
g_structref.clear ();
Index: src/gdb/testsuite/gdb.trace/unavailable.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.trace/unavailable.exp 2011-02-07 13:24:23.726706003 +0000
+++ src/gdb/testsuite/gdb.trace/unavailable.exp 2011-02-07 13:27:53.276706002 +0000
@@ -92,6 +92,9 @@ proc gdb_collect_globals_test { } {
"collect struct_b.struct_a.array\[2\]" "^$" \
"collect struct_b.struct_a.array\[100\]" "^$" \
\
+ "collect a" "^$" \
+ "collect c" "^$" \
+ \
"collect tarray\[0\].a" "^$" \
"collect tarray\[1\].a" "^$" \
"collect tarray\[3\].a" "^$" \
@@ -145,6 +148,15 @@ proc gdb_collect_globals_test { } {
gdb_test "print /x struct_b.struct_a.array\[2\]" " = 0xaaaaaaaa"
+ # Check the target doesn't overcollect. GDB used to merge memory
+ # ranges to collect if they were close enough (collecting the hole
+ # as well), but does not do that anymore. It's plausible that a
+ # target may do this on its end, but as of this writing, no known
+ # target does it.
+ gdb_test "print {a, b, c}" \
+ " = \\{1, <unavailable>, 3\\}" \
+ "No overcollect of almost but not quite adjacent memory ranges"
+
# Check <unavailable> isn't confused with 0 in array element repetitions
gdb_test_no_output "set print repeat 1"
Index: src/gdb/tracepoint.c
===================================================================
--- src.orig/gdb/tracepoint.c 2011-02-07 13:17:26.276706003 +0000
+++ src/gdb/tracepoint.c 2011-02-07 13:27:53.276706002 +0000
@@ -841,13 +841,12 @@ memrange_sortmerge (struct collection_li
{
for (a = 0, b = 1; b < memranges->next_memrange; b++)
{
- if (memranges->list[a].type == memranges->list[b].type &&
- memranges->list[b].start - memranges->list[a].end <=
- MAX_REGISTER_SIZE)
+ /* If memrange b overlaps or is adjacent to memrange a,
+ merge them. */
+ if (memranges->list[a].type == memranges->list[b].type
+ && memranges->list[b].start <= memranges->list[a].end)
{
- /* memrange b starts before memrange a ends; merge them. */
- if (memranges->list[b].end > memranges->list[a].end)
- memranges->list[a].end = memranges->list[b].end;
+ memranges->list[a].end = memranges->list[b].end;
continue; /* next b, same a */
}
a++; /* next a */
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect 2011-02-07 14:35 [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect Pedro Alves @ 2011-02-14 12:01 ` Jan Kratochvil 2011-02-16 13:10 ` Pedro Alves 0 siblings, 1 reply; 13+ messages in thread From: Jan Kratochvil @ 2011-02-14 12:01 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches On Mon, 07 Feb 2011 15:35:20 +0100, Pedro Alves wrote: > --- src.orig/gdb/tracepoint.c 2011-02-07 13:17:26.276706003 +0000 > +++ src/gdb/tracepoint.c 2011-02-07 13:27:53.276706002 +0000 > @@ -841,13 +841,12 @@ memrange_sortmerge (struct collection_li > { > for (a = 0, b = 1; b < memranges->next_memrange; b++) > { > - if (memranges->list[a].type == memranges->list[b].type && > - memranges->list[b].start - memranges->list[a].end <= > - MAX_REGISTER_SIZE) > + /* If memrange b overlaps or is adjacent to memrange a, > + merge them. */ > + if (memranges->list[a].type == memranges->list[b].type > + && memranges->list[b].start <= memranges->list[a].end) > { > - /* memrange b starts before memrange a ends; merge them. */ > - if (memranges->list[b].end > memranges->list[a].end) > - memranges->list[a].end = memranges->list[b].end; > + memranges->list[a].end = memranges->list[b].end; > continue; /* next b, same a */ > } > a++; /* next a */ It is an unrelated issue to this patch but this function is not a general normalizer for overlapping ranges, with bug(s) similar to normalize_mem_ranges. But maybe it does not have to be so general, all the possible contents of the tracing protocol are unknown to me. Thanks, Jan ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect 2011-02-14 12:01 ` Jan Kratochvil @ 2011-02-16 13:10 ` Pedro Alves 2011-02-16 18:00 ` Tom Tromey 0 siblings, 1 reply; 13+ messages in thread From: Pedro Alves @ 2011-02-16 13:10 UTC (permalink / raw) To: gdb-patches; +Cc: Jan Kratochvil On Monday 14 February 2011 12:01:16, Jan Kratochvil wrote: > On Mon, 07 Feb 2011 15:35:20 +0100, Pedro Alves wrote: > > --- src.orig/gdb/tracepoint.c 2011-02-07 13:17:26.276706003 +0000 > > +++ src/gdb/tracepoint.c 2011-02-07 13:27:53.276706002 +0000 > > @@ -841,13 +841,12 @@ memrange_sortmerge (struct collection_li > > { > > for (a = 0, b = 1; b < memranges->next_memrange; b++) > > { > > - if (memranges->list[a].type == memranges->list[b].type && > > - memranges->list[b].start - memranges->list[a].end <= > > - MAX_REGISTER_SIZE) > > + /* If memrange b overlaps or is adjacent to memrange a, > > + merge them. */ > > + if (memranges->list[a].type == memranges->list[b].type > > + && memranges->list[b].start <= memranges->list[a].end) > > { > > - /* memrange b starts before memrange a ends; merge them. */ > > - if (memranges->list[b].end > memranges->list[a].end) > > - memranges->list[a].end = memranges->list[b].end; > > + memranges->list[a].end = memranges->list[b].end; > > continue; /* next b, same a */ > > } > > a++; /* next a */ > > It is an unrelated issue to this patch but this function is not a general > normalizer for overlapping ranges, with bug(s) similar to > normalize_mem_ranges. But maybe it does not have to be so general, all the > possible contents of the tracing protocol are unknown to me. Whoops, nice catch. It can happen. E.g., actions >collect {char[64]}0x400640 >collect {char[32]}0x400640 end we'd tell the target to collect [0x400640, 0x400640+32) instead of [0x400640, 0x400640+64). While writting the test in the patch below I tripped on an internal error: >collect {int [4]}globalarr2 ../../src/gdb/ax-gdb.c:2053: internal-error: gen_expr: OP_MEMVAL operand isn't an rvalue??? A problem internal to GDB has been detected, further debugging may prove unreliable. ... bah. I applied the patch below. The test fails without the fix. Thanks! -- Pedro Alves 2011-02-16 Pedro Alves <pedro@codesourcery.com> Jan Kratochvil <jan.kratochvil@redhat.com> gdb/ * tracepoint.c (memrange_sortmerge): Fix list A's end calculation. 2011-02-16 Pedro Alves <pedro@codesourcery.com> gdb/testsuite/ * collection.c (globalarr2): New global. (main): Initialize it before collecting, and and clear it afterwards. * collection.exp (gdb_collect_globals_test): Test collecting overlapping memory ranges. --- gdb/testsuite/gdb.trace/collection.c | 6 ++++++ gdb/testsuite/gdb.trace/collection.exp | 24 +++++++++++++++++++++++- gdb/tracepoint.c | 3 ++- 3 files changed, 31 insertions(+), 2 deletions(-) Index: src/gdb/testsuite/gdb.trace/collection.c =================================================================== --- src.orig/gdb/testsuite/gdb.trace/collection.c 2011-02-16 12:48:45.436002004 +0000 +++ src/gdb/testsuite/gdb.trace/collection.c 2011-02-16 12:49:02.446001996 +0000 @@ -26,6 +26,7 @@ double globald; test_struct globalstruct; test_struct *globalp; int globalarr[16]; +int globalarr2[4]; struct global_pieces { unsigned int a; @@ -237,6 +238,9 @@ main (argc, argv, envp) for (i = 0; i < 15; i++) globalarr[i] = i; + for (i = 0; i < 4; i++) + globalarr2[i] = i; + mystruct.memberc = 101; mystruct.memberi = 102; mystruct.memberf = 103.3; @@ -283,6 +287,8 @@ main (argc, argv, envp) globalp = 0; for (i = 0; i < 15; i++) globalarr[i] = 0; + for (i = 0; i < 4; i++) + globalarr2[i] = 0; end (); return 0; Index: src/gdb/testsuite/gdb.trace/collection.exp =================================================================== --- src.orig/gdb/testsuite/gdb.trace/collection.exp 2011-02-16 12:48:45.436002004 +0000 +++ src/gdb/testsuite/gdb.trace/collection.exp 2011-02-16 12:49:02.446001996 +0000 @@ -457,13 +457,29 @@ proc gdb_collect_globals_test { } { } } + # Use use this to test collecting overlapping memory ranges + # (making use of UNOP_MEMVAL, as objects don't usually overlap + # other objects). Note that globalarr2 should not be collected in + # any other way so that a regression test below can be effective. + + set globalarr2_addr "" + set test "get address of globalarr2" + gdb_test_multiple "p /x &globalarr2" $test { + -re " = (0x\[0-9a-f\]+)\r\n$gdb_prompt $" { + set globalarr2_addr $expect_out(1,string) + pass $test + } + } + gdb_test "trace $testline" \ "Tracepoint \[0-9\]+ at .*" \ "collect globals: set tracepoint" gdb_trace_setactions "collect globals: define actions" \ "" \ "collect globalc, globali, globalf, globald" "^$" \ - "collect globalstruct, globalp, globalarr" "^$" + "collect globalstruct, globalp, globalarr" "^$" \ + "collect \{int \[4\]\}$globalarr2_addr" "^$" \ + "collect \{int \[2\]\}$globalarr2_addr" "^$" # Begin the test. run_trace_experiment "globals" globals_test_func @@ -508,6 +524,12 @@ proc gdb_collect_globals_test { } { "\\$\[0-9\]+ = 3$cr" \ "collect globals: collected global array element #3" + # Check that we didn't mess up sort&merging memory ranges to + # collect. + gdb_test "print globalarr2" \ + "\\$\[0-9\]+ = \\{0, 1, 2, 3\\}$cr" \ + "collect globals: collected global array 2" + gdb_test "tfind none" \ "#0 end .*" \ "collect globals: cease trace debugging" Index: src/gdb/tracepoint.c =================================================================== --- src.orig/gdb/tracepoint.c 2011-02-16 12:51:44.000000000 +0000 +++ src/gdb/tracepoint.c 2011-02-16 12:51:54.236001996 +0000 @@ -846,7 +846,8 @@ memrange_sortmerge (struct collection_li if (memranges->list[a].type == memranges->list[b].type && memranges->list[b].start <= memranges->list[a].end) { - memranges->list[a].end = memranges->list[b].end; + if (memranges->list[b].end > memranges->list[a].end) + memranges->list[a].end = memranges->list[b].end; continue; /* next b, same a */ } a++; /* next a */ ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect 2011-02-16 13:10 ` Pedro Alves @ 2011-02-16 18:00 ` Tom Tromey 2011-02-16 18:03 ` Pedro Alves 2011-02-16 18:09 ` Tom Tromey 0 siblings, 2 replies; 13+ messages in thread From: Tom Tromey @ 2011-02-16 18:00 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches, Jan Kratochvil >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes: Pedro> While writting the test in the patch below I tripped Pedro> on an internal error: >> collect {int [4]}globalarr2 Pedro> ../../src/gdb/ax-gdb.c:2053: internal-error: gen_expr: OP_MEMVAL operand isn't an rvalue??? Pedro> A problem internal to GDB has been detected, Pedro> further debugging may prove unreliable. Pedro> ... bah. I think that code is just confused. Even the comment says so :-) Could you try the appended? I'm not totally sure about it; maybe for the axs_lvalue_memory case we should be calling gen_address_of. I can't really test it here, since newer versions of GCC confuse AX generation :-(. That is, I get this a lot when running collection.exp: DWARF operator DW_OP_call_frame_cfa cannot be translated to an agent expression This seems pretty important to fix. Tom diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index 2908431..d1736e1 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -2044,14 +2044,13 @@ gen_expr (struct expression *exp, union exp_element **pc, (*pc) += 3; gen_expr (exp, pc, ax, value); - /* I'm not sure I understand UNOP_MEMVAL entirely. I think - it's just a hack for dealing with minsyms; you take some - integer constant, pretend it's the address of an lvalue of - the given type, and dereference it. */ - if (value->kind != axs_rvalue) - /* This would be weird. */ - internal_error (__FILE__, __LINE__, - _("gen_expr: OP_MEMVAL operand isn't an rvalue???")); + + /* If we have an axs_rvalue or an axs_lvalue_memory, then we + already have the right value on the stack. For + axs_lvalue_register, we must convert. */ + if (value->kind == axs_lvalue_register) + require_rvalue (ax, value); + value->type = type; value->kind = axs_lvalue_memory; } ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect 2011-02-16 18:00 ` Tom Tromey @ 2011-02-16 18:03 ` Pedro Alves 2011-02-16 18:07 ` Tom Tromey 2011-02-16 18:09 ` Tom Tromey 1 sibling, 1 reply; 13+ messages in thread From: Pedro Alves @ 2011-02-16 18:03 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches, Jan Kratochvil On Wednesday 16 February 2011 16:49:26, Tom Tromey wrote: > >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes: > > Pedro> While writting the test in the patch below I tripped > Pedro> on an internal error: > >> collect {int [4]}globalarr2 > Pedro> ../../src/gdb/ax-gdb.c:2053: internal-error: gen_expr: OP_MEMVAL operand isn't an rvalue??? > Pedro> A problem internal to GDB has been detected, > Pedro> further debugging may prove unreliable. > Pedro> ... bah. > > I think that code is just confused. Even the comment says so :-) > > Could you try the appended? I'm not totally sure about it; maybe for > the axs_lvalue_memory case we should be calling gen_address_of. Thanks! Looks, works and test fine. We get the same ax, whether we take the address of the address expression or not: (gdb) maintenance agent {int [4]} globalarr3 Scope: 0x40091d Reg mask: 00 0 const32 6299952 5 const8 16 7 trace 8 end (gdb) maintenance agent {int [4]} &globalarr3 Scope: 0x40091d Reg mask: 00 0 const32 6299952 5 const8 16 7 trace 8 end Which is the same behavior of printing: (gdb) p {int [4]} &globalarr3 $1 = {3, 2, 1, 0} (gdb) p {int [4]} globalarr3 $2 = {3, 2, 1, 0} The ax also looks fine with registers ax values: (gdb) maintenance agent {int [4]} $rip Scope: 0x40091d Reg mask: 00 00 01 0 reg 16 3 zero_ext 64 5 const8 16 7 trace 8 end > I can't really test it here, since newer versions of GCC confuse AX > generation :-(. That is, I get this a lot when running collection.exp: > > DWARF operator DW_OP_call_frame_cfa cannot be translated to an agent expression > > This seems pretty important to fix. Bummer. Yeah. I've added a simple testcase. I didn't try cooking up a variant for the axs_lval_register path. I also wrote a ChangeLog entry. Shall I go ahead and commit this? -- Pedro Alves 2011-02-16 Tom Tromey <tromey@redhat.com> gdb/ * ax-gdb.c.c (gen_expr) <UNOP_MEMVAL>: Handle value kinds other than axs_rvalue. 2011-02-16 Pedro Alves <pedro@codesourcery.com> gdb/testsuite/ * collection.c (globalarr3): New global. (main): Initialize it before collecting, and and clear it afterwards. * collection.exp (gdb_collect_globals_test): Test collecting with '{type} addr', where the addr expression is not an rvalue. --- gdb/ax-gdb.c | 15 +++++++-------- gdb/testsuite/gdb.trace/collection.c | 6 ++++++ gdb/testsuite/gdb.trace/collection.exp | 11 ++++++++++- 3 files changed, 23 insertions(+), 9 deletions(-) Index: src/gdb/ax-gdb.c =================================================================== --- src.orig/gdb/ax-gdb.c 2011-01-13 15:07:17.386075004 +0000 +++ src/gdb/ax-gdb.c 2011-02-16 17:05:25.816002008 +0000 @@ -2044,14 +2044,13 @@ gen_expr (struct expression *exp, union (*pc) += 3; gen_expr (exp, pc, ax, value); - /* I'm not sure I understand UNOP_MEMVAL entirely. I think - it's just a hack for dealing with minsyms; you take some - integer constant, pretend it's the address of an lvalue of - the given type, and dereference it. */ - if (value->kind != axs_rvalue) - /* This would be weird. */ - internal_error (__FILE__, __LINE__, - _("gen_expr: OP_MEMVAL operand isn't an rvalue???")); + + /* If we have an axs_rvalue or an axs_lvalue_memory, then we + already have the right value on the stack. For + axs_lvalue_register, we must convert. */ + if (value->kind == axs_lvalue_register) + require_rvalue (ax, value); + value->type = type; value->kind = axs_lvalue_memory; } Index: src/gdb/testsuite/gdb.trace/collection.c =================================================================== --- src.orig/gdb/testsuite/gdb.trace/collection.c 2011-02-16 12:49:02.000000000 +0000 +++ src/gdb/testsuite/gdb.trace/collection.c 2011-02-16 17:41:25.426002003 +0000 @@ -27,6 +27,7 @@ test_struct globalstruct; test_struct *globalp; int globalarr[16]; int globalarr2[4]; +int globalarr3[4]; struct global_pieces { unsigned int a; @@ -241,6 +242,9 @@ main (argc, argv, envp) for (i = 0; i < 4; i++) globalarr2[i] = i; + for (i = 0; i < 4; i++) + globalarr3[3 - i] = i; + mystruct.memberc = 101; mystruct.memberi = 102; mystruct.memberf = 103.3; @@ -289,6 +293,8 @@ main (argc, argv, envp) globalarr[i] = 0; for (i = 0; i < 4; i++) globalarr2[i] = 0; + for (i = 0; i < 4; i++) + globalarr3[i] = 0; end (); return 0; Index: src/gdb/testsuite/gdb.trace/collection.exp =================================================================== --- src.orig/gdb/testsuite/gdb.trace/collection.exp 2011-02-16 12:49:02.000000000 +0000 +++ src/gdb/testsuite/gdb.trace/collection.exp 2011-02-16 17:49:45.276001996 +0000 @@ -479,7 +479,8 @@ proc gdb_collect_globals_test { } { "collect globalc, globali, globalf, globald" "^$" \ "collect globalstruct, globalp, globalarr" "^$" \ "collect \{int \[4\]\}$globalarr2_addr" "^$" \ - "collect \{int \[2\]\}$globalarr2_addr" "^$" + "collect \{int \[2\]\}$globalarr2_addr" "^$" \ + "collect \{int \[4\]\}globalarr3" "^$" # Begin the test. run_trace_experiment "globals" globals_test_func @@ -530,6 +531,14 @@ proc gdb_collect_globals_test { } { "\\$\[0-9\]+ = \\{0, 1, 2, 3\\}$cr" \ "collect globals: collected global array 2" + # GDB would internal error collecting UNOP_MEMVAL's whose address + # expression wasn't an rvalue (that's regtested in the + # corresponding 'collect' action above). This just double checks + # we actually did collect what we wanted. + gdb_test "print globalarr3" \ + "\\$\[0-9\]+ = \\{3, 2, 1, 0\\}$cr" \ + "collect globals: collected global array 3" + gdb_test "tfind none" \ "#0 end .*" \ "collect globals: cease trace debugging" ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect 2011-02-16 18:03 ` Pedro Alves @ 2011-02-16 18:07 ` Tom Tromey 2011-02-16 18:09 ` Pedro Alves 0 siblings, 1 reply; 13+ messages in thread From: Tom Tromey @ 2011-02-16 18:07 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches, Jan Kratochvil >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes: Pedro> I also wrote a ChangeLog entry. Shall I go ahead and Pedro> commit this? Yes, thank you. Tom ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect 2011-02-16 18:07 ` Tom Tromey @ 2011-02-16 18:09 ` Pedro Alves 0 siblings, 0 replies; 13+ messages in thread From: Pedro Alves @ 2011-02-16 18:09 UTC (permalink / raw) To: gdb-patches; +Cc: Tom Tromey, Jan Kratochvil On Wednesday 16 February 2011 18:02:59, Tom Tromey wrote: > >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes: > > Pedro> I also wrote a ChangeLog entry. Shall I go ahead and > Pedro> commit this? > > Yes, thank you. Done. Thanks again. -- Pedro Alves ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect 2011-02-16 18:00 ` Tom Tromey 2011-02-16 18:03 ` Pedro Alves @ 2011-02-16 18:09 ` Tom Tromey 2011-02-16 21:01 ` FYI: handle DW_OP_call_frame_cfa in AX compiler (Was: [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect) Tom Tromey 1 sibling, 1 reply; 13+ messages in thread From: Tom Tromey @ 2011-02-16 18:09 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches, Jan Kratochvil Tom> DWARF operator DW_OP_call_frame_cfa cannot be translated to an agent expression Tom> This seems pretty important to fix. I'm looking at it. I think I see how it can be done. Tom ^ permalink raw reply [flat|nested] 13+ messages in thread
* FYI: handle DW_OP_call_frame_cfa in AX compiler (Was: [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect) 2011-02-16 18:09 ` Tom Tromey @ 2011-02-16 21:01 ` Tom Tromey 2011-02-16 21:31 ` FYI: handle DW_OP_call_frame_cfa in AX compiler Pedro Alves 0 siblings, 1 reply; 13+ messages in thread From: Tom Tromey @ 2011-02-16 21:01 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches, Jan Kratochvil Here is a patch to implement compilation of DW_OP_call_frame_cfa to agent expressions. Let me know what you think. It at least let collection.exp run here. I'll do a full regression test against gdbserver sometime soon. Tom 2011-02-16 Tom Tromey <tromey@redhat.com> * dwarf2loc.c (compile_dwarf_to_ax) <DW_OP_call_frame_cfa>: Use dwarf2_compile_cfa_to_ax. * dwarf2-frame.h (dwarf2_compile_ftype): New typedef. (dwarf2_compile_cfa_to_ax): Declare. * dwarf2-frame.c: Include ax.h. (execute_cfa_program): Remove 'this_frame' argument; 'gdbarch' and 'pc'. (dwarf2_compile_cfa_to_ax): New function. (dwarf2_frame_cache): Update. diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index 48f47af..014da44 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -38,6 +38,7 @@ #include "complaints.h" #include "dwarf2-frame.h" +#include "ax.h" struct comp_unit; @@ -428,13 +429,11 @@ Not implemented: computing unwound register using explicit value operator")); static void execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr, - const gdb_byte *insn_end, struct frame_info *this_frame, - struct dwarf2_frame_state *fs) + const gdb_byte *insn_end, struct gdbarch *gdbarch, + CORE_ADDR pc, struct dwarf2_frame_state *fs) { int eh_frame_p = fde->eh_frame_p; - CORE_ADDR pc = get_frame_pc (this_frame); int bytes_read; - struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); while (insn_ptr < insn_end && fs->pc <= pc) @@ -902,6 +901,85 @@ dwarf2_frame_find_quirks (struct dwarf2_frame_state *fs, } \f +void +dwarf2_compile_cfa_to_ax (struct agent_expr *expr, struct axs_value *loc, + struct gdbarch *gdbarch, + CORE_ADDR pc, + dwarf2_compile_ftype compile, + struct dwarf2_per_cu_data *data) +{ + const int num_regs = gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch); + struct dwarf2_fde *fde; + CORE_ADDR text_offset, cfa; + struct dwarf2_frame_state fs; + int addr_size; + + memset (&fs, 0, sizeof (struct dwarf2_frame_state)); + + fs.pc = pc; + + /* Find the correct FDE. */ + fde = dwarf2_frame_find_fde (&fs.pc, &text_offset); + if (fde == NULL) + error (_("Could not compute CFA; needed to translate this expression")); + + /* Extract any interesting information from the CIE. */ + fs.data_align = fde->cie->data_alignment_factor; + fs.code_align = fde->cie->code_alignment_factor; + fs.retaddr_column = fde->cie->return_address_register; + addr_size = fde->cie->addr_size; + + /* Check for "quirks" - known bugs in producers. */ + dwarf2_frame_find_quirks (&fs, fde); + + /* First decode all the insns in the CIE. */ + execute_cfa_program (fde, fde->cie->initial_instructions, + fde->cie->end, gdbarch, pc, &fs); + + /* Save the initialized register set. */ + fs.initial = fs.regs; + fs.initial.reg = dwarf2_frame_state_copy_regs (&fs.regs); + + /* Then decode the insns in the FDE up to our target PC. */ + execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, pc, &fs); + + /* Calculate the CFA. */ + switch (fs.regs.cfa_how) + { + case CFA_REG_OFFSET: + { + int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, fs.regs.cfa_reg); + + if (regnum == -1) + error (_("Unable to access DWARF register number %d"), + (int) fs.regs.cfa_reg); /* FIXME */ + ax_reg (expr, regnum); + + if (fs.regs.cfa_offset != 0) + { + if (fs.armcc_cfa_offsets_reversed) + ax_const_l (expr, - fs.regs.cfa_offset); + else + ax_const_l (expr, fs.regs.cfa_offset); + ax_simple (expr, aop_add); + } + } + break; + + case CFA_EXP: + ax_const_l (expr, text_offset); + (*compile) (expr, loc, gdbarch, addr_size, + fs.regs.cfa_exp, fs.regs.cfa_exp + fs.regs.cfa_exp_len, + data); + break; + + default: + internal_error (__FILE__, __LINE__, _("Unknown CFA rule.")); + } +} + +\f struct dwarf2_frame_cache { /* DWARF Call Frame Address. */ @@ -979,14 +1057,15 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) /* First decode all the insns in the CIE. */ execute_cfa_program (fde, fde->cie->initial_instructions, - fde->cie->end, this_frame, fs); + fde->cie->end, gdbarch, get_frame_pc (this_frame), fs); /* Save the initialized register set. */ fs->initial = fs->regs; fs->initial.reg = dwarf2_frame_state_copy_regs (&fs->regs); /* Then decode the insns in the FDE up to our target PC. */ - execute_cfa_program (fde, fde->instructions, fde->end, this_frame, fs); + execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, + get_frame_pc (this_frame), fs); /* Calculate the CFA. */ switch (fs->regs.cfa_how) diff --git a/gdb/dwarf2-frame.h b/gdb/dwarf2-frame.h index bf7134d..e8a3e85 100644 --- a/gdb/dwarf2-frame.h +++ b/gdb/dwarf2-frame.h @@ -26,6 +26,9 @@ struct gdbarch; struct objfile; struct frame_info; +struct dwarf2_per_cu_data; +struct agent_expr; +struct axs_value; /* Register rule. */ @@ -118,4 +121,26 @@ extern const struct frame_base * CORE_ADDR dwarf2_frame_cfa (struct frame_info *this_frame); +/* Type of the compilation function for dwarf2_compile_cfa_to_ax. */ + +typedef void (*dwarf2_compile_ftype) (struct agent_expr *expr, + struct axs_value *loc, + struct gdbarch *arch, + unsigned int addr_size, + const gdb_byte *op_ptr, + const gdb_byte *op_end, + struct dwarf2_per_cu_data *data); + +/* Update the agent expression EXPR with code to compute the CFA for a + frame at PC. GDBARCH is the frame architecture. The COMPILE + function can be used to compile a location expression into EXPR. + DATA is passed to COMPILE if needed. */ + +extern void dwarf2_compile_cfa_to_ax (struct agent_expr *expr, + struct axs_value *loc, + struct gdbarch *gdbarch, + CORE_ADDR pc, + dwarf2_compile_ftype compile, + struct dwarf2_per_cu_data *data); + #endif /* dwarf2-frame.h */ diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index ac786e4..8840a81 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -1926,7 +1926,9 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc, break; case DW_OP_call_frame_cfa: - unimplemented (op); + dwarf2_compile_cfa_to_ax (expr, loc, arch, expr->scope, + compile_dwarf_to_ax, per_cu); + loc->kind = axs_lvalue_memory; break; case DW_OP_GNU_push_tls_address: ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: FYI: handle DW_OP_call_frame_cfa in AX compiler 2011-02-16 21:01 ` FYI: handle DW_OP_call_frame_cfa in AX compiler (Was: [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect) Tom Tromey @ 2011-02-16 21:31 ` Pedro Alves 2011-02-16 21:40 ` Tom Tromey 0 siblings, 1 reply; 13+ messages in thread From: Pedro Alves @ 2011-02-16 21:31 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches, Jan Kratochvil On Wednesday 16 February 2011 20:18:34, Tom Tromey wrote: > Here is a patch to implement compilation of DW_OP_call_frame_cfa to > agent expressions. > > Let me know what you think. Looks good to me. Thanks for doing this. OOC, why the dwarf2_compile_ftype abstraction? Are you working on other changes where you'll pass down something else? > It at least let collection.exp run here. I'll do a full regression test > against gdbserver sometime soon. FYI, I often do "--directory=gdb.trace" when I want a quicker sanity check than a full testrun. Nothing outside that directory generates/uses axs currently. > + ax_const_l (expr, - fs.regs.cfa_offset); No space after `-'. -- Pedro Alves ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: FYI: handle DW_OP_call_frame_cfa in AX compiler 2011-02-16 21:31 ` FYI: handle DW_OP_call_frame_cfa in AX compiler Pedro Alves @ 2011-02-16 21:40 ` Tom Tromey 2011-02-16 23:27 ` Pedro Alves 0 siblings, 1 reply; 13+ messages in thread From: Tom Tromey @ 2011-02-16 21:40 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches, Jan Kratochvil >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes: Pedro> OOC, why the dwarf2_compile_ftype abstraction? Are you working Pedro> on other changes where you'll pass down something else? Nope, I just didn't want to make compile_dwarf_to_ax public. Maybe it is better to just do that. What do you think? >> + ax_const_l (expr, - fs.regs.cfa_offset); Pedro> No space after `-'. Thanks, I will fix it. Tom ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: FYI: handle DW_OP_call_frame_cfa in AX compiler 2011-02-16 21:40 ` Tom Tromey @ 2011-02-16 23:27 ` Pedro Alves 2011-02-17 16:24 ` Tom Tromey 0 siblings, 1 reply; 13+ messages in thread From: Pedro Alves @ 2011-02-16 23:27 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches, Jan Kratochvil On Wednesday 16 February 2011 21:40:04, Tom Tromey wrote: > >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes: > > Pedro> OOC, why the dwarf2_compile_ftype abstraction? Are you working > Pedro> on other changes where you'll pass down something else? > > Nope, I just didn't want to make compile_dwarf_to_ax public. > Maybe it is better to just do that. > What do you think? IMO, that'd be better. Stops everyone else reading the code from asking that same question in their minds. :-) -- Pedro Alves ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: FYI: handle DW_OP_call_frame_cfa in AX compiler 2011-02-16 23:27 ` Pedro Alves @ 2011-02-17 16:24 ` Tom Tromey 0 siblings, 0 replies; 13+ messages in thread From: Tom Tromey @ 2011-02-17 16:24 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches, Jan Kratochvil Pedro> IMO, that'd be better. Stops everyone else reading the code Pedro> from asking that same question in their minds. :-) Ok, I made this change. The results from gdb.trace are very good now: # of expected passes 822 # of expected failures 16 So, I am committing the appended. Tom 2011-02-17 Tom Tromey <tromey@redhat.com> * dwarf2loc.h (dwarf2_compile_expr_to_ax): Declare. * dwarf2loc.c (dwarf2_compile_expr_to_ax): Rename from compile_dwarf_to_ax. No longer static. Call dwarf2_compile_cfa_to_ax. (locexpr_tracepoint_var_ref): Update. (loclist_tracepoint_var_ref): Update. * dwarf2-frame.h (dwarf2_compile_cfa_to_ax): Declare. * dwarf2-frame.c (execute_cfa_program): Remove 'this_frame' argument; add 'gdbarch' and 'pc'. (dwarf2_compile_cfa_to_ax): New function. (dwarf2_frame_cache): Update. Index: dwarf2-frame.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v retrieving revision 1.119 diff -u -r1.119 dwarf2-frame.c --- dwarf2-frame.c 7 Jan 2011 19:36:16 -0000 1.119 +++ dwarf2-frame.c 17 Feb 2011 16:16:18 -0000 @@ -38,6 +38,8 @@ #include "complaints.h" #include "dwarf2-frame.h" +#include "ax.h" +#include "dwarf2loc.h" struct comp_unit; @@ -428,13 +430,11 @@ static void execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr, - const gdb_byte *insn_end, struct frame_info *this_frame, - struct dwarf2_frame_state *fs) + const gdb_byte *insn_end, struct gdbarch *gdbarch, + CORE_ADDR pc, struct dwarf2_frame_state *fs) { int eh_frame_p = fde->eh_frame_p; - CORE_ADDR pc = get_frame_pc (this_frame); int bytes_read; - struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); while (insn_ptr < insn_end && fs->pc <= pc) @@ -902,6 +902,85 @@ } \f +void +dwarf2_compile_cfa_to_ax (struct agent_expr *expr, struct axs_value *loc, + struct gdbarch *gdbarch, + CORE_ADDR pc, + struct dwarf2_per_cu_data *data) +{ + const int num_regs = gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch); + struct dwarf2_fde *fde; + CORE_ADDR text_offset, cfa; + struct dwarf2_frame_state fs; + int addr_size; + + memset (&fs, 0, sizeof (struct dwarf2_frame_state)); + + fs.pc = pc; + + /* Find the correct FDE. */ + fde = dwarf2_frame_find_fde (&fs.pc, &text_offset); + if (fde == NULL) + error (_("Could not compute CFA; needed to translate this expression")); + + /* Extract any interesting information from the CIE. */ + fs.data_align = fde->cie->data_alignment_factor; + fs.code_align = fde->cie->code_alignment_factor; + fs.retaddr_column = fde->cie->return_address_register; + addr_size = fde->cie->addr_size; + + /* Check for "quirks" - known bugs in producers. */ + dwarf2_frame_find_quirks (&fs, fde); + + /* First decode all the insns in the CIE. */ + execute_cfa_program (fde, fde->cie->initial_instructions, + fde->cie->end, gdbarch, pc, &fs); + + /* Save the initialized register set. */ + fs.initial = fs.regs; + fs.initial.reg = dwarf2_frame_state_copy_regs (&fs.regs); + + /* Then decode the insns in the FDE up to our target PC. */ + execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, pc, &fs); + + /* Calculate the CFA. */ + switch (fs.regs.cfa_how) + { + case CFA_REG_OFFSET: + { + int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, fs.regs.cfa_reg); + + if (regnum == -1) + error (_("Unable to access DWARF register number %d"), + (int) fs.regs.cfa_reg); /* FIXME */ + ax_reg (expr, regnum); + + if (fs.regs.cfa_offset != 0) + { + if (fs.armcc_cfa_offsets_reversed) + ax_const_l (expr, -fs.regs.cfa_offset); + else + ax_const_l (expr, fs.regs.cfa_offset); + ax_simple (expr, aop_add); + } + } + break; + + case CFA_EXP: + ax_const_l (expr, text_offset); + dwarf2_compile_expr_to_ax (expr, loc, gdbarch, addr_size, + fs.regs.cfa_exp, + fs.regs.cfa_exp + fs.regs.cfa_exp_len, + data); + break; + + default: + internal_error (__FILE__, __LINE__, _("Unknown CFA rule.")); + } +} + +\f struct dwarf2_frame_cache { /* DWARF Call Frame Address. */ @@ -979,14 +1058,15 @@ /* First decode all the insns in the CIE. */ execute_cfa_program (fde, fde->cie->initial_instructions, - fde->cie->end, this_frame, fs); + fde->cie->end, gdbarch, get_frame_pc (this_frame), fs); /* Save the initialized register set. */ fs->initial = fs->regs; fs->initial.reg = dwarf2_frame_state_copy_regs (&fs->regs); /* Then decode the insns in the FDE up to our target PC. */ - execute_cfa_program (fde, fde->instructions, fde->end, this_frame, fs); + execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, + get_frame_pc (this_frame), fs); /* Calculate the CFA. */ switch (fs->regs.cfa_how) Index: dwarf2-frame.h =================================================================== RCS file: /cvs/src/src/gdb/dwarf2-frame.h,v retrieving revision 1.25 diff -u -r1.25 dwarf2-frame.h --- dwarf2-frame.h 1 Jan 2011 15:33:02 -0000 1.25 +++ dwarf2-frame.h 17 Feb 2011 16:16:18 -0000 @@ -26,6 +26,9 @@ struct gdbarch; struct objfile; struct frame_info; +struct dwarf2_per_cu_data; +struct agent_expr; +struct axs_value; /* Register rule. */ @@ -118,4 +121,15 @@ CORE_ADDR dwarf2_frame_cfa (struct frame_info *this_frame); +/* Update the agent expression EXPR with code to compute the CFA for a + frame at PC. GDBARCH is the architecture of the function at PC. + This function may call dwarf2_compile_expr_to_ax; DATA is passed + through to that function if needed. */ + +extern void dwarf2_compile_cfa_to_ax (struct agent_expr *expr, + struct axs_value *loc, + struct gdbarch *gdbarch, + CORE_ADDR pc, + struct dwarf2_per_cu_data *data); + #endif /* dwarf2-frame.h */ Index: dwarf2loc.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2loc.c,v retrieving revision 1.106 diff -u -r1.106 dwarf2loc.c --- dwarf2loc.c 16 Feb 2011 21:45:38 -0000 1.106 +++ dwarf2loc.c 17 Feb 2011 16:16:19 -0000 @@ -1426,11 +1426,11 @@ example, if the expression cannot be compiled, or if the expression is invalid. */ -static void -compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc, - struct gdbarch *arch, unsigned int addr_size, - const gdb_byte *op_ptr, const gdb_byte *op_end, - struct dwarf2_per_cu_data *per_cu) +void +dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, + struct gdbarch *arch, unsigned int addr_size, + const gdb_byte *op_ptr, const gdb_byte *op_end, + struct dwarf2_per_cu_data *per_cu) { struct cleanup *cleanups; int i, *offsets; @@ -1717,8 +1717,8 @@ &datastart, &datalen); op_ptr = read_sleb128 (op_ptr, op_end, &offset); - compile_dwarf_to_ax (expr, loc, arch, addr_size, datastart, - datastart + datalen, per_cu); + dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size, datastart, + datastart + datalen, per_cu); if (offset != 0) { @@ -1955,7 +1955,8 @@ break; case DW_OP_call_frame_cfa: - unimplemented (op); + dwarf2_compile_cfa_to_ax (expr, loc, arch, expr->scope, per_cu); + loc->kind = axs_lvalue_memory; break; case DW_OP_GNU_push_tls_address: @@ -2069,9 +2070,9 @@ /* DW_OP_call_ref is currently not supported. */ gdb_assert (block.per_cu == per_cu); - compile_dwarf_to_ax (expr, loc, arch, addr_size, - block.data, block.data + block.size, - per_cu); + dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size, + block.data, block.data + block.size, + per_cu); } break; @@ -2673,9 +2674,9 @@ if (dlbaton->data == NULL || dlbaton->size == 0) value->optimized_out = 1; else - compile_dwarf_to_ax (ax, value, gdbarch, addr_size, - dlbaton->data, dlbaton->data + dlbaton->size, - dlbaton->per_cu); + dwarf2_compile_expr_to_ax (ax, value, gdbarch, addr_size, + dlbaton->data, dlbaton->data + dlbaton->size, + dlbaton->per_cu); } /* The set of location functions used with the DWARF-2 expression @@ -2826,8 +2827,8 @@ if (data == NULL || size == 0) value->optimized_out = 1; else - compile_dwarf_to_ax (ax, value, gdbarch, addr_size, data, data + size, - dlbaton->per_cu); + dwarf2_compile_expr_to_ax (ax, value, gdbarch, addr_size, data, data + size, + dlbaton->per_cu); } /* The set of location functions used with the DWARF-2 expression Index: dwarf2loc.h =================================================================== RCS file: /cvs/src/src/gdb/dwarf2loc.h,v retrieving revision 1.21 diff -u -r1.21 dwarf2loc.h --- dwarf2loc.h 1 Jan 2011 15:33:02 -0000 1.21 +++ dwarf2loc.h 17 Feb 2011 16:16:20 -0000 @@ -25,6 +25,8 @@ struct objfile; struct dwarf2_per_cu_data; struct dwarf2_loclist_baton; +struct agent_expr; +struct axs_value; /* This header is private to the DWARF-2 reader. It is shared between dwarf2read.c and dwarf2loc.c. */ @@ -106,4 +108,25 @@ extern const struct symbol_computed_ops dwarf2_locexpr_funcs; extern const struct symbol_computed_ops dwarf2_loclist_funcs; +/* Compile a DWARF location expression to an agent expression. + + EXPR is the agent expression we are building. + LOC is the agent value we modify. + ARCH is the architecture. + ADDR_SIZE is the size of addresses, in bytes. + OP_PTR is the start of the location expression. + OP_END is one past the last byte of the location expression. + + This will throw an exception for various kinds of errors -- for + example, if the expression cannot be compiled, or if the expression + is invalid. */ + +extern void dwarf2_compile_expr_to_ax (struct agent_expr *expr, + struct axs_value *loc, + struct gdbarch *arch, + unsigned int addr_size, + const gdb_byte *op_ptr, + const gdb_byte *op_end, + struct dwarf2_per_cu_data *per_cu); + #endif /* dwarf2loc.h */ ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2011-02-17 16:20 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-02-07 14:35 [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect Pedro Alves 2011-02-14 12:01 ` Jan Kratochvil 2011-02-16 13:10 ` Pedro Alves 2011-02-16 18:00 ` Tom Tromey 2011-02-16 18:03 ` Pedro Alves 2011-02-16 18:07 ` Tom Tromey 2011-02-16 18:09 ` Pedro Alves 2011-02-16 18:09 ` Tom Tromey 2011-02-16 21:01 ` FYI: handle DW_OP_call_frame_cfa in AX compiler (Was: [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect) Tom Tromey 2011-02-16 21:31 ` FYI: handle DW_OP_call_frame_cfa in AX compiler Pedro Alves 2011-02-16 21:40 ` Tom Tromey 2011-02-16 23:27 ` Pedro Alves 2011-02-17 16:24 ` Tom Tromey
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox