From 36b11add17bf287b541a107ee64f7e313e77092f Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Sun, 9 Oct 2011 19:41:17 +0000 Subject: [PATCH] gdb/ Support @entry in input expressions. * c-exp.y (ENTRY, unknown_cpp_name): New. (exp: UNKNOWN_CPP_NAME): Change to `exp: unknown_cpp_name'. (unknown_cpp_name: UNKNOWN_CPP_NAME, unknown_cpp_name: ENTRY) (variable: name_not_typename '@' ENTRY, name: ENTRY) (name_not_typename: ENTRY): New. (yylex): Recognize ENTRY. * eval.c (evaluate_subexp_standard): Support also OP_VAR_ENTRY_VALUE. * expprint.c (print_subexp_standard, dump_subexp_body_standard): Likewise. * parse.c (operator_length_standard): Likewise. * std-operator.def: New operator OP_VAR_ENTRY_VALUE. gdb/doc/ Support @entry in input expressions. * gdb.texinfo (Variables): Describe @entry names suffix. (Print Settings): Add anchor for `set print entry-values'. gdb/testsuite/ Support @entry in input expressions. * gdb.arch/amd64-entry-value.exp (entry: p i@entry, entry: p j@entry) (entry_stack: p s1@entry, entry_stack: p s2@entry) (entry_stack: p d9@entry, entry_stack: p da@entry, tailcall: p i@entry) (tailcall: p j@entry): New tests. * gdb.cp/koenig.cc (A::entry): New function. (main): Call it. * gdb.cp/koenig.exp (p entry (c)): New test. --- gdb/ChangeLog | 15 +++++++++ gdb/c-exp.y | 32 +++++++++++++++++++- gdb/doc/ChangeLog | 6 ++++ gdb/doc/gdb.texinfo | 18 +++++++++++ gdb/eval.c | 21 +++++++++++++ gdb/expprint.c | 17 +++++++++++ gdb/parse.c | 1 + gdb/std-operator.def | 6 ++++ gdb/testsuite/ChangeLog | 11 +++++++ gdb/testsuite/gdb.arch/amd64-entry-value.exp | 8 +++++ gdb/testsuite/gdb.cp/koenig.cc | 6 ++++ gdb/testsuite/gdb.cp/koenig.exp | 3 ++ 12 files changed, 143 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 63e37e2c283..5d1339e3d80 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,18 @@ +2011-10-09 Jan Kratochvil + + Support @entry in input expressions. + * c-exp.y (ENTRY, unknown_cpp_name): New. + (exp: UNKNOWN_CPP_NAME): Change to `exp: unknown_cpp_name'. + (unknown_cpp_name: UNKNOWN_CPP_NAME, unknown_cpp_name: ENTRY) + (variable: name_not_typename '@' ENTRY, name: ENTRY) + (name_not_typename: ENTRY): New. + (yylex): Recognize ENTRY. + * eval.c (evaluate_subexp_standard): Support also OP_VAR_ENTRY_VALUE. + * expprint.c (print_subexp_standard, dump_subexp_body_standard): + Likewise. + * parse.c (operator_length_standard): Likewise. + * std-operator.def: New operator OP_VAR_ENTRY_VALUE. + 2011-10-09 Jan Kratochvil Display referenced values in backtraces. diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 94d07370738..5cc1e9614e9 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -186,6 +186,7 @@ static struct stoken operator_stoken (const char *); %token STRING %token CHAR %token NAME /* BLOCKNAME defined below to give it higher precedence. */ +%token ENTRY %token UNKNOWN_CPP_NAME %token COMPLETE %token TYPENAME @@ -194,6 +195,9 @@ static struct stoken operator_stoken (const char *); %type name_not_typename %type typename +/* It is UNKNOWN_CPP_NAME or ENTRY, depending on the context. */ +%type unknown_cpp_name + /* A NAME_OR_INT is a symbol which is not known in the symbol table, but which would parse as a valid number in the current input radix. E.g. "c" when input_radix==16. Depending on the parse, it will be @@ -392,7 +396,7 @@ exp : exp '(' write_exp_elt_opcode (OP_FUNCALL); } ; -exp : UNKNOWN_CPP_NAME '(' +exp : unknown_cpp_name '(' { /* This could potentially be a an argument defined lookup function (Koenig). */ @@ -415,6 +419,10 @@ exp : UNKNOWN_CPP_NAME '(' } ; +unknown_cpp_name : UNKNOWN_CPP_NAME + | ENTRY + ; + lcurly : '{' { start_arglist (); } ; @@ -756,6 +764,21 @@ block : block COLONCOLON name $$ = SYMBOL_BLOCK_VALUE (tem); } ; +variable: name_not_typename '@' ENTRY + { struct symbol *sym = $1.sym; + + if (sym == NULL || !SYMBOL_IS_ARGUMENT (sym) + || !symbol_read_needs_frame (sym)) + error (_("@entry can be used only for function " + "parameters, not for \"%s\""), + copy_name ($1.stoken)); + + write_exp_elt_opcode (OP_VAR_ENTRY_VALUE); + write_exp_elt_sym (sym); + write_exp_elt_opcode (OP_VAR_ENTRY_VALUE); + } + ; + variable: block COLONCOLON name { struct symbol *sym; sym = lookup_symbol (copy_name ($3), $1, @@ -1317,11 +1340,13 @@ name : NAME { $$ = $1.stoken; } | TYPENAME { $$ = $1.stoken; } | NAME_OR_INT { $$ = $1.stoken; } | UNKNOWN_CPP_NAME { $$ = $1.stoken; } + | ENTRY { $$ = $1.stoken; } | operator { $$ = $1; } ; name_not_typename : NAME | BLOCKNAME + | ENTRY /* These would be useful if name_not_typename was useful, but it is just a fake for "variable", so these cause reduce/reduce conflicts because the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable, @@ -2525,6 +2550,11 @@ yylex (void) current.token = lex_one_token (); if (current.token == NAME) current.token = classify_name (expression_context_block); + if ((current.token == NAME || current.token == UNKNOWN_CPP_NAME) + && yylval.sval.length == strlen ("entry") + && strncmp (yylval.sval.ptr, "entry", strlen ("entry")) == 0) + current.token = ENTRY; + if (parse_language->la_language != language_cplus || (current.token != TYPENAME && current.token != COLONCOLON)) return current.token; diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 7763cce5060..808cf212b76 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,9 @@ +2011-10-09 Jan Kratochvil + + Support @entry in input expressions. + * gdb.texinfo (Variables): Describe @entry names suffix. + (Print Settings): Add anchor for `set print entry-values'. + 2011-10-09 Jan Kratochvil Eli Zaretskii diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 9de96c1c9ae..1ea2ba39fb0 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -7277,6 +7277,23 @@ If you ask to print an object whose contents are unknown to by the debug information, @value{GDBN} will say @samp{}. @xref{Symbols, incomplete type}, for more about this. +If you append @kbd{@@entry} string to a function parameter name you get its +value at the time the function got called. If the value is not available an +error message is printed. Entry values are available only with some compilers. +Entry values are normally also printed at the function parameter list according +to @ref{set print entry-values}. + +@smallexample +Breakpoint 1, d (i=30) at gdb.base/entry-value.c:29 +29 i++; +(gdb) next +30 e (i); +(gdb) print i +$1 = 31 +(gdb) print i@@entry +$2 = 30 +@end smallexample + Strings are identified as arrays of @code{char} values without specified signedness. Arrays of either @code{signed char} or @code{unsigned char} get printed as arrays of 1 byte sized integers. @code{-fsigned-char} or @@ -7941,6 +7958,7 @@ thus speeding up the display of each Ada frame. @item show print frame-arguments Show how the value of arguments should be displayed when printing a frame. +@anchor{set print entry-values} @item set print entry-values @var{value} @kindex set print entry-values Set printing of frame argument values at function entry. In some cases diff --git a/gdb/eval.c b/gdb/eval.c index af225c4670a..09564498975 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -860,6 +860,27 @@ evaluate_subexp_standard (struct type *expect_type, return ret; } + case OP_VAR_ENTRY_VALUE: + (*pos) += 2; + if (noside == EVAL_SKIP) + goto nosideret; + + { + struct symbol *sym = exp->elts[pc + 1].symbol; + struct frame_info *frame; + + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (SYMBOL_TYPE (sym), not_lval); + + if (SYMBOL_CLASS (sym) != LOC_COMPUTED + || SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry == NULL) + error (_("Symbol \"%s\" does not have any specific entry value"), + SYMBOL_PRINT_NAME (sym)); + + frame = get_selected_frame (NULL); + return SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry (sym, frame); + } + case OP_LAST: (*pos) += 2; return diff --git a/gdb/expprint.c b/gdb/expprint.c index 2b6e4160676..0e0f1c37034 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -135,6 +135,16 @@ print_subexp_standard (struct expression *exp, int *pos, } return; + case OP_VAR_ENTRY_VALUE: + { + struct block *b; + + (*pos) += 2; + fprintf_filtered (stream, "%s@entry", + SYMBOL_PRINT_NAME (exp->elts[pc + 1].symbol)); + } + return; + case OP_LAST: (*pos) += 2; fprintf_filtered (stream, "$%d", @@ -853,6 +863,13 @@ dump_subexp_body_standard (struct expression *exp, SYMBOL_PRINT_NAME (exp->elts[elt + 1].symbol)); elt += 3; break; + case OP_VAR_ENTRY_VALUE: + fprintf_filtered (stream, "Entry value of symbol @"); + gdb_print_host_address (exp->elts[elt].symbol, stream); + fprintf_filtered (stream, " (%s)", + SYMBOL_PRINT_NAME (exp->elts[elt].symbol)); + elt += 2; + break; case OP_LAST: fprintf_filtered (stream, "History element %ld", (long) exp->elts[elt].longconst); diff --git a/gdb/parse.c b/gdb/parse.c index bb6e0e656aa..7d157fe99b3 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -853,6 +853,7 @@ operator_length_standard (const struct expression *expr, int endpos, case OP_BOOL: case OP_LAST: case OP_INTERNALVAR: + case OP_VAR_ENTRY_VALUE: oplen = 3; break; diff --git a/gdb/std-operator.def b/gdb/std-operator.def index 2c771415b78..3b6b0ae6050 100644 --- a/gdb/std-operator.def +++ b/gdb/std-operator.def @@ -139,6 +139,12 @@ OP (OP_DOUBLE) use the selected frame. */ OP (OP_VAR_VALUE) +/* OP_VAR_ENTRY_VALUE takes one struct symbol * in the following element, + followed by another OP_VAR_ENTRY_VALUE, making three exp_elements. + somename@entry may mean parameter value as present at the entry of the + current function. Implemented via DW_OP_GNU_entry_value. */ +OP (OP_VAR_ENTRY_VALUE) + /* OP_LAST is followed by an integer in the next exp_element. The integer is zero for the last value printed, or it is the absolute number of a history element. diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 74826cfbb48..e3df529a845 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2011-10-09 Jan Kratochvil + + Support @entry in input expressions. + * gdb.arch/amd64-entry-value.exp (entry: p i@entry, entry: p j@entry) + (entry_stack: p s1@entry, entry_stack: p s2@entry) + (entry_stack: p d9@entry, entry_stack: p da@entry, tailcall: p i@entry) + (tailcall: p j@entry): New tests. + * gdb.cp/koenig.cc (A::entry): New function. + (main): Call it. + * gdb.cp/koenig.exp (p entry (c)): New test. + 2011-10-09 Jan Kratochvil Display @entry parameter values (without references). diff --git a/gdb/testsuite/gdb.arch/amd64-entry-value.exp b/gdb/testsuite/gdb.arch/amd64-entry-value.exp index fcccdd8701d..10a82ab6820 100644 --- a/gdb/testsuite/gdb.arch/amd64-entry-value.exp +++ b/gdb/testsuite/gdb.arch/amd64-entry-value.exp @@ -51,7 +51,9 @@ gdb_continue_to_breakpoint "entry: breakhere" gdb_test "bt" "^bt\r\n#0 +d *\\(i=31, i@entry=30, j=31\\.5, j@entry=30\\.5\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in main .*" \ "entry: bt" gdb_test "p i" " = 31" "entry: p i" +gdb_test "p i@entry" " = 30" "entry: p i@entry" gdb_test "p j" { = 31\.5} "entry: p j" +gdb_test "p j@entry" { = 30\.5} "entry: p j@entry" # Test @entry values when parameter in function is locexpr (and not loclist). @@ -76,9 +78,13 @@ gdb_test "bt" "^bt\r\n#0 +stacktest *\\(r1=r1@entry=1, r2=r2@entry=2, \[^\r\n\]+ "entry_stack: bt" gdb_test "p s1" " = 3" "entry_stack: p s1" +gdb_test "p s1@entry" " = 11" "entry_stack: p s1@entry" gdb_test "p s2" " = 4" "entry_stack: p s2" +gdb_test "p s2@entry" " = 12" "entry_stack: p s2@entry" gdb_test "p d9" " = 3\\.5" "entry_stack: p d9" +gdb_test "p d9@entry" " = 11\\.5" "entry_stack: p d9@entry" gdb_test "p da" " = 4\\.5" "entry_stack: p da" +gdb_test "p da@entry" " = 12\\.5" "entry_stack: p da@entry" # Test various kinds of `set print entry-values'. @@ -159,7 +165,9 @@ gdb_continue_to_breakpoint "tailcall: breakhere" gdb_test "bt" "^bt\r\n#0 +d *\\(i=71, i@entry=70, j=73\\.5, j@entry=72\\.5\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in c \\(i=i@entry=7, j=j@entry=7\\.25\\) \[^\r\n\]*\r\n#2 +0x\[0-9a-f\]+ in b \\(i=i@entry=5, j=j@entry=5\\.25\\) \[^\r\n\]*\r\n#3 +0x\[0-9a-f\]+ in main \[^\r\n\]*" \ "tailcall: bt" gdb_test "p i" " = 71" "tailcall: p i" +gdb_test "p i@entry" " = 70" "tailcall: p i@entry" gdb_test "p j" " = 73\\.5" "tailcall: p j" +gdb_test "p j@entry" " = 72\\.5" "tailcall: p j@entry" # Test $sp simulation for tail call frames. #gdb_test {p/x $sp} " = 0x.*" diff --git a/gdb/testsuite/gdb.cp/koenig.cc b/gdb/testsuite/gdb.cp/koenig.cc index e2190f1c6c7..01e2637cfbd 100644 --- a/gdb/testsuite/gdb.cp/koenig.cc +++ b/gdb/testsuite/gdb.cp/koenig.cc @@ -24,6 +24,11 @@ namespace A return 33; } + int + entry (C c) + { + return 44; + } } struct B @@ -245,6 +250,7 @@ main () A::first (c); first (0, c); second (0, 0, c, 0, 0); + entry (c); A::first (b.c); E::O eo; diff --git a/gdb/testsuite/gdb.cp/koenig.exp b/gdb/testsuite/gdb.cp/koenig.exp index 7d5e5ab74fe..6ee35622169 100644 --- a/gdb/testsuite/gdb.cp/koenig.exp +++ b/gdb/testsuite/gdb.cp/koenig.exp @@ -33,6 +33,9 @@ gdb_test "p first(c)" "= 11" # the qualifying parameter gdb_test "p second(0,0,c,0,0)" "= 33" +# Test the name "entry" being used for `variablename@entry' entry values. +gdb_test "p entry (c)" " = 44" + # Test that koenig lookup finds correct function # even if it is overloaded gdb_test "p first(0,c)" "= 22" -- 2.39.2