From patchwork Fri May 30 18:18:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Seitz X-Patchwork-Id: 1212 Received: (qmail 22853 invoked by alias); 30 May 2014 18:18:47 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 22840 invoked by uid 89); 30 May 2014 18:18:46 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL, BAYES_00, KAM_STOCKGEN, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS, T_FILL_THIS_FORM_SHORT autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 30 May 2014 18:18:44 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s4UIIgTe018316 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 30 May 2014 14:18:43 -0400 Received: from valrhona.uglyboxes.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s4UIIfTO027892 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Fri, 30 May 2014 14:18:42 -0400 Message-ID: <5388CB81.4030409@redhat.com> Date: Fri, 30 May 2014 11:18:41 -0700 From: Keith Seitz User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 MIME-Version: 1.0 To: "gdb-patches@sourceware.org ml" Subject: Re: [RFA 4/9] Explicit locations v2 - Add address locations References: <536BC678.1010309@redhat.com> In-Reply-To: <536BC678.1010309@redhat.com> X-IsSubscribed: yes This is an update of this patch based on changes from reviews of previous patches. Keith Changes since last version: - remove SAVE_SPEC stuff - canonicalize_linespec: remove expression stuff - ditto convert_linespec_to_sals - event_location_to_string_const: compute return value (aka remove SAVE_SPEC) - new_address_location ChangeLog 2014-05-29 Keith Seitz * breakpoint.c (create_thread_event_breakpoint): Convert linespec to address location. (init_breakpoint_sal): Likewise. * linespec.c (canonicalize_linespec): Do not handle address locations here. (convert_address_location_to_sals): New function; contents moved from ... (convert_linespc_to_sals): ... here. (parse_linespec): Remove address locations from linespec grammar. Remove handling of address locations. (event_location_to_sals): Handle ADDRESS_LOCATION. (linespec_expression_to_pc): Export. * linespec.h (linespec_expression_to_pc): Add declaration. * location.c (copy_event_location): Handle address locations. (delete_event_location): Likewise. (event_location_to_string): Likewise. (string_to_event_location): Likewise. (event_location_empty_p): Likewise. * location.h (enum event_location_type): Add EVENT_LOCATION_ADDRESS. (struct event_location.u)
: New member. (ADDRESS_LOCATION): Define accessor macro. * python/py-finishbreakpoint.c (bpfinishpy_init): Remove local variable `finish_pc'. Convert linespec to address location. * spu-tdep.c (spu_catch_start): Convert linespec to address location. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index c4727da..ef60f44 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -7538,9 +7538,7 @@ create_thread_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address) b->enable_state = bp_enabled; /* location has to be used or breakpoint_re_set will delete me. */ - b->location = new_linespec_location (NULL); - EVENT_LOCATION_LINESPEC (b->location) - = xstrprintf ("*%s", paddress (b->loc->gdbarch, b->loc->address)); + b->location = new_address_location (b->loc->address); update_global_location_list_nothrow (1); @@ -9423,11 +9421,7 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch, if (location != NULL) b->location = location; else - { - b->location = new_linespec_location (NULL); - EVENT_LOCATION_LINESPEC (b->location) - = xstrprintf ("*%s", paddress (b->loc->gdbarch, b->loc->address)); - } + b->location = new_address_location (b->loc->address); b->filter = filter; } diff --git a/gdb/linespec.c b/gdb/linespec.c index 92482b4..8ea0c7b 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -317,7 +317,7 @@ static void iterate_over_file_blocks (struct symtab *symtab, static void initialize_defaults (struct symtab **default_symtab, int *default_line); -static CORE_ADDR linespec_expression_to_pc (const char **exp_ptr); +CORE_ADDR linespec_expression_to_pc (const char **exp_ptr); static struct symtabs_and_lines decode_objc (struct linespec_state *self, linespec_p ls, @@ -1766,77 +1766,68 @@ linespec_parse_basic (linespec_parser *parser) static void canonicalize_linespec (struct linespec_state *state, linespec_p ls) { + struct ui_file *buf; + int need_colon = 0; + /* If canonicalization was not requested, no need to do anything. */ if (!state->canonical) return; - /* Shortcut expressions, which can only appear by themselves. */ - if (ls->expression != NULL) - { - state->canonical->location - = new_linespec_location (ls->expression); - } - else - { - struct ui_file *buf; - int need_colon = 0; + buf = mem_fileopen (); - buf = mem_fileopen (); + state->canonical->location = new_linespec_location (NULL); - state->canonical->location = new_linespec_location (NULL); + if (ls->source_filename) + { + fputs_unfiltered (ls->source_filename, buf); + need_colon = 1; + } - if (ls->source_filename) - { - fputs_unfiltered (ls->source_filename, buf); - need_colon = 1; - } + if (ls->function_name) + { + if (need_colon) + fputc_unfiltered (':', buf); + fputs_unfiltered (ls->function_name, buf); + need_colon = 1; + } - if (ls->function_name) - { - if (need_colon) - fputc_unfiltered (':', buf); - fputs_unfiltered (ls->function_name, buf); - need_colon = 1; - } + if (ls->label_name) + { + if (need_colon) + fputc_unfiltered (':', buf); - if (ls->label_name) + if (ls->function_name == NULL) { - if (need_colon) - fputc_unfiltered (':', buf); - - if (ls->function_name == NULL) - { - struct symbol *s; - - /* No function was specified, so add the symbol name. */ - gdb_assert (ls->labels.function_symbols != NULL - && (VEC_length (symbolp, ls->labels.function_symbols) - == 1)); - s = VEC_index (symbolp, ls->labels.function_symbols, 0); - fputs_unfiltered (SYMBOL_NATURAL_NAME (s), buf); - fputc_unfiltered (':', buf); - } - - fputs_unfiltered (ls->label_name, buf); - need_colon = 1; - state->canonical->special_display = 1; + struct symbol *s; + + /* No function was specified, so add the symbol name. */ + gdb_assert (ls->labels.function_symbols != NULL + && (VEC_length (symbolp, ls->labels.function_symbols) + == 1)); + s = VEC_index (symbolp, ls->labels.function_symbols, 0); + fputs_unfiltered (SYMBOL_NATURAL_NAME (s), buf); + fputc_unfiltered (':', buf); } - if (ls->line_offset.sign != LINE_OFFSET_UNKNOWN) - { - if (need_colon) - fputc_unfiltered (':', buf); - fprintf_filtered (buf, "%s%d", - (ls->line_offset.sign == LINE_OFFSET_NONE ? "" - : (ls->line_offset.sign - == LINE_OFFSET_PLUS ? "+" : "-")), - ls->line_offset.offset); - } + fputs_unfiltered (ls->label_name, buf); + need_colon = 1; + state->canonical->special_display = 1; + } - EVENT_LOCATION_LINESPEC (state->canonical->location) - = ui_file_xstrdup (buf, NULL); - ui_file_delete (buf); + if (ls->line_offset.sign != LINE_OFFSET_UNKNOWN) + { + if (need_colon) + fputc_unfiltered (':', buf); + fprintf_filtered (buf, "%s%d", + (ls->line_offset.sign == LINE_OFFSET_NONE ? "" + : (ls->line_offset.sign + == LINE_OFFSET_PLUS ? "+" : "-")), + ls->line_offset.offset); } + + EVENT_LOCATION_LINESPEC (state->canonical->location) + = ui_file_xstrdup (buf, NULL); + ui_file_delete (buf); } /* Given a line offset in LS, construct the relevant SALs. */ @@ -1990,6 +1981,27 @@ create_sals_line_offset (struct linespec_state *self, return values; } +/* Convert the given ADDRESS into SaLs. */ + +static struct symtabs_and_lines +convert_address_location_to_sals (struct linespec_state *self, + CORE_ADDR address) +{ + struct symtab_and_line sal; + struct symtabs_and_lines sals = {NULL, 0}; + + sal = find_pc_line (address, 0); + sal.pc = address; + sal.section = find_pc_overlay (address); + sal.explicit_pc = 1; + add_sal_to_sals (self, &sals, &sal, core_addr_to_string (address), 1); + + if (self->canonical != NULL) + self->canonical->location = new_address_location (address); + + return sals; +} + /* Create and return SALs from the linespec LS. */ static struct symtabs_and_lines @@ -1997,18 +2009,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) { struct symtabs_and_lines sals = {NULL, 0}; - if (ls->expression != NULL) - { - struct symtab_and_line sal; - - /* We have an expression. No other attribute is allowed. */ - sal = find_pc_line (ls->expr_pc, 0); - sal.pc = ls->expr_pc; - sal.section = find_pc_overlay (ls->expr_pc); - sal.explicit_pc = 1; - add_sal_to_sals (state, &sals, &sal, ls->expression, 1); - } - else if (ls->labels.label_symbols != NULL) + if (ls->labels.label_symbols != NULL) { /* We have just a bunch of functions/methods or labels. */ int i; @@ -2108,8 +2109,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) The basic grammar of linespecs: - linespec -> expr_spec | var_spec | basic_spec - expr_spec -> '*' STRING + linespec -> var_spec | basic_spec var_spec -> '$' (STRING | NUMBER) basic_spec -> file_offset_spec | function_spec | label_spec @@ -2205,33 +2205,7 @@ parse_linespec (linespec_parser *parser, const char **argptr) token = linespec_lexer_lex_one (parser); /* It must be either LSTOKEN_STRING or LSTOKEN_NUMBER. */ - if (token.type == LSTOKEN_STRING && *LS_TOKEN_STOKEN (token).ptr == '*') - { - char *expr; - const char *copy; - - /* User specified an expression, *EXPR. */ - copy = expr = copy_token_string (token); - cleanup = make_cleanup (xfree, expr); - PARSER_RESULT (parser)->expr_pc = linespec_expression_to_pc (©); - discard_cleanups (cleanup); - PARSER_RESULT (parser)->expression = expr; - - /* This is a little hacky/tricky. If linespec_expression_to_pc - did not evaluate the entire token, then we must find the - string COPY inside the original token buffer. */ - if (*copy != '\0') - { - PARSER_STREAM (parser) = strstr (parser->lexer.saved_arg, copy); - gdb_assert (PARSER_STREAM (parser) != NULL); - } - - /* Consume the token. */ - linespec_lexer_consume_token (parser); - - goto convert_to_sals; - } - else if (token.type == LSTOKEN_STRING && *LS_TOKEN_STOKEN (token).ptr == '$') + if (token.type == LSTOKEN_STRING && *LS_TOKEN_STOKEN (token).ptr == '$') { char *var; @@ -2453,6 +2427,12 @@ event_location_to_sals (linespec_parser *parser, } break; + case ADDRESS_LOCATION: + result + = convert_address_location_to_sals (PARSER_STATE (parser), + EVENT_LOCATION_ADDRESS (location)); + break; + default: gdb_assert_not_reached ("unhandled event location type"); } @@ -2647,7 +2627,7 @@ initialize_defaults (struct symtab **default_symtab, int *default_line) /* Evaluate the expression pointed to by EXP_PTR into a CORE_ADDR, advancing EXP_PTR past any parsed text. */ -static CORE_ADDR +CORE_ADDR linespec_expression_to_pc (const char **exp_ptr) { if (current_program_space->executing_startup) diff --git a/gdb/linespec.h b/gdb/linespec.h index 658f2a1..df5820a 100644 --- a/gdb/linespec.h +++ b/gdb/linespec.h @@ -152,4 +152,8 @@ extern struct symtabs_and_lines decode_line_with_current_source (char *, int); extern struct symtabs_and_lines decode_line_with_last_displayed (char *, int); +/* Evaluate the expression pointed to by EXP_PTR into a CORE_ADDR, + advancing EXP_PTR past any parsed text. */ + +extern CORE_ADDR linespec_expression_to_pc (const char **exp_ptr); #endif /* defined (LINESPEC_H) */ diff --git a/gdb/location.c b/gdb/location.c index 57900bf..3c430db 100644 --- a/gdb/location.c +++ b/gdb/location.c @@ -53,6 +53,20 @@ new_linespec_location (const char *linespec) return location; } +/* Create a new address location. The return result is malloc'd + and should be freed with delete_event_location. */ + +struct event_location * +new_address_location (CORE_ADDR addr) +{ + struct event_location *location; + + location = XNEW (struct event_location); + initialize_event_location (location, ADDRESS_LOCATION); + EVENT_LOCATION_ADDRESS (location) = addr; + return location; +} + /* Return a copy of the given SRC location. */ struct event_location * @@ -71,6 +85,10 @@ copy_event_location (const struct event_location *src) EVENT_LOCATION_LINESPEC (dst) = xstrdup (EVENT_LOCATION_LINESPEC (src)); break; + case ADDRESS_LOCATION: + EVENT_LOCATION_ADDRESS (dst) = EVENT_LOCATION_ADDRESS (src); + break; + default: gdb_assert_not_reached ("unknown event location type"); } @@ -111,6 +129,10 @@ delete_event_location (struct event_location *location) xfree (EVENT_LOCATION_LINESPEC (location)); break; + case ADDRESS_LOCATION: + /* Nothing to do. */ + break; + default: gdb_assert_not_reached ("unknown event location type"); } @@ -138,6 +160,12 @@ event_location_to_string_const (const struct event_location *location) result = xstrdup (EVENT_LOCATION_LINESPEC (location)); break; + case ADDRESS_LOCATION: + result + = xstrprintf ("*%s", + core_addr_to_string (EVENT_LOCATION_ADDRESS (location))); + break; + default: gdb_assert_not_reached ("unknown event location type"); } @@ -171,9 +199,24 @@ string_to_event_location (char **stringp, { struct event_location *location; - location = new_linespec_location (*stringp); - if (*stringp != NULL) - *stringp += strlen (*stringp); + /* First, check if the string is an address location. */ + if (*stringp != NULL && **stringp == '*') + { + const char *arg, *orig; + CORE_ADDR addr; + + orig = arg = *stringp; + addr = linespec_expression_to_pc (&arg); + location = new_address_location (addr); + *stringp += arg - orig; + } + else + { + /* Everything else is a linespec. */ + location = new_linespec_location (*stringp); + if (*stringp != NULL) + *stringp += strlen (*stringp); + } return location; } @@ -188,6 +231,9 @@ event_location_empty_p (const struct event_location *location) case LINESPEC_LOCATION: return EVENT_LOCATION_LINESPEC (location) == NULL; + case ADDRESS_LOCATION: + return 0; + default: gdb_assert_not_reached ("unknown event location type"); } diff --git a/gdb/location.h b/gdb/location.h index 418e271..1daefb6 100644 --- a/gdb/location.h +++ b/gdb/location.h @@ -27,7 +27,10 @@ struct language_defn; enum event_location_type { /* A traditional linespec. */ - LINESPEC_LOCATION + LINESPEC_LOCATION, + + /* An address in the inferior. */ + ADDRESS_LOCATION }; /* An event location used to set a stop event in the inferior. @@ -47,6 +50,10 @@ struct event_location probes. */ char *addr_string; #define EVENT_LOCATION_LINESPEC(S) ((S)->u.addr_string) + + /* An address in the inferior. */ + CORE_ADDR address; +#define EVENT_LOCATION_ADDRESS(S) ((S)->u.address) } u; /* Cached string representation of this location. This is used to @@ -85,6 +92,12 @@ extern struct cleanup * extern struct event_location * new_linespec_location (const char *linespec); +/* Create a new address location. The return result is malloc'd + and should be freed with delete_event_location. */ + +extern struct event_location * + new_address_location (CORE_ADDR addr); + /* Return a copy of the given SRC location. */ extern struct event_location * diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c index c29037a..c97bb0a 100644 --- a/gdb/python/py-finishbreakpoint.c +++ b/gdb/python/py-finishbreakpoint.c @@ -167,9 +167,8 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs) struct frame_id frame_id; PyObject *internal = NULL; int internal_bp = 0; - CORE_ADDR finish_pc, pc; + CORE_ADDR pc; volatile struct gdb_exception except; - char small_buf[100]; struct symbol *function; if (!PyArg_ParseTupleAndKeywords (args, kwargs, "|OO", keywords, @@ -291,10 +290,8 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs) struct event_location location; /* Set a breakpoint on the return address. */ - initialize_event_location (&location, LINESPEC_LOCATION); - finish_pc = get_frame_pc (prev_frame); - xsnprintf (small_buf, sizeof (small_buf), "*%s", hex_string (finish_pc)); - EVENT_LOCATION_LINESPEC (&location) = small_buf; + initialize_event_location (&location, ADDRESS_LOCATION); + EVENT_LOCATION_ADDRESS (&location) = get_frame_pc (prev_frame); create_breakpoint (python_gdbarch, &location, NULL, thread, NULL, 0, diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c index fcfe066..4ff742f 100644 --- a/gdb/spu-tdep.c +++ b/gdb/spu-tdep.c @@ -2001,8 +2001,8 @@ spu_catch_start (struct objfile *objfile) /* Use a numerical address for the set_breakpoint command to avoid having the breakpoint re-set incorrectly. */ - initialize_event_location (&location, LINESPEC_LOCATION); - EVENT_LOCATION_LINESPEC (&location) = xstrdup (core_addr_to_string (pc)); + initialize_event_location (&location, ADDRESS_LOCATION); + EVENT_LOCATION_ADDRESS (&location) = pc; create_breakpoint (get_objfile_arch (objfile), &location, NULL /* cond_string */, -1 /* thread */, NULL /* extra_string */,