From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15646 invoked by alias); 8 May 2014 18:02:50 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 15634 invoked by uid 89); 8 May 2014 18:02:50 -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 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; Thu, 08 May 2014 18:02:48 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s48I2lOb020236 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 8 May 2014 14:02:47 -0400 Received: from valrhona.uglyboxes.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s48I2k8W020382 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Thu, 8 May 2014 14:02:47 -0400 Message-ID: <536BC6C6.6040501@redhat.com> Date: Thu, 08 May 2014 18:02:00 -0000 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: [RFA 6/9] Explicit locations v2 - Add explicit locations Content-Type: multipart/mixed; boundary="------------050400020007010509020707" X-IsSubscribed: yes X-SW-Source: 2014-05/txt/msg00090.txt.bz2 This is a multi-part message in MIME format. --------------050400020007010509020707 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 2014 Hi, This patch finally introduces new features/functionality by adding support for explicit locations. Explicit locations are introduced internally only in this patch. Users cannot do anything with them until the next patch. Like the previous two patches introducing new location types, this patch also converts any existing hard-coded linespec locations into explicit form. Keith ChangeLog 2014-05-08 Keith Seitz * breakpoint.c (create_overlay_breakpoint): Convert linespec into explicit location. (create_longjmp_master_breakpoint): Likewise. (create_std_terminate_master_breakpoint): Likewise. (create_exception_master_breakpoint): Likewise. (create_breakpoint): Update the SAVE_SPEC for explicit locations. (update_static_tracepoint): Convert linespec into explicit location. (location_to_sals): Save the SAVE_SPEC for pending breakpoints which were resolved. * linespec.c (enum offset_relative_sign): Move to location.h. (struct line_offset): Likewise. (undefined_label_error): New function. (source_file_not_found_error): New function. (linespec_parse_basic): Use undefined_label_error. (canonicalize_linespec): Convert canonical linespec into explicit location. (convert_explicit_location_to_sals): New function. (event_location_to_sals): Handle explicit locations. (symtabs_from_filename): Use source_file_not_found_error. * location.c (initialize_explicit_location): New function. (initialize_event_location): Initialize explicit locations. (copy_event_location): Handle explicit locations. (delete_event_location): Likewise. (event_location_to_string): Likewise. (event_location_empty_p): Likewise. * location.h (enum offset_relative_sign): Move here from linespec.h. (struct line_offset): Likewise. (enum event_location_type): Add EVENT_LOCATION_EXPLICIT. (struct explicit_location): New structure. (struct event_location.u) : New member. (EVENT_LOCATION_EXPLICIT): Define accessor macro. (initialize_explicit_location): Declare. --------------050400020007010509020707 Content-Type: text/x-patch; name="explicit-explicit-locations.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="explicit-explicit-locations.patch" Content-length: 17628 diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index fdf7c10..74c40a4 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -3305,8 +3305,9 @@ create_overlay_event_breakpoint (void) b = create_internal_breakpoint (get_objfile_arch (objfile), addr, bp_overlay_event, &internal_breakpoint_ops); - b->location = new_event_location (EVENT_LOCATION_LINESPEC); - EVENT_LOCATION_LINESPEC (b->location) = xstrdup (func_name); + b->location = new_event_location (EVENT_LOCATION_EXPLICIT); + EVENT_LOCATION_EXPLICIT (b->location)->function_name + = xstrdup (func_name); if (overlay_debugging == ovly_auto) { @@ -3426,8 +3427,9 @@ create_longjmp_master_breakpoint (void) addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]); b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master, &internal_breakpoint_ops); - b->location = new_event_location (EVENT_LOCATION_LINESPEC); - EVENT_LOCATION_LINESPEC (b->location) = xstrdup (func_name); + b->location = new_event_location (EVENT_LOCATION_EXPLICIT); + EVENT_LOCATION_EXPLICIT (b->location)->function_name + = xstrdup (func_name); b->enable_state = bp_disabled; } } @@ -3483,8 +3485,9 @@ create_std_terminate_master_breakpoint (void) b = create_internal_breakpoint (get_objfile_arch (objfile), addr, bp_std_terminate_master, &internal_breakpoint_ops); - b->location = new_event_location (EVENT_LOCATION_LINESPEC); - EVENT_LOCATION_LINESPEC (b->location) = xstrdup (func_name); + b->location = new_event_location (EVENT_LOCATION_EXPLICIT); + EVENT_LOCATION_EXPLICIT (b->location)->function_name + = xstrdup (func_name); b->enable_state = bp_disabled; } } @@ -3589,8 +3592,9 @@ create_exception_master_breakpoint (void) ¤t_target); b = create_internal_breakpoint (gdbarch, addr, bp_exception_master, &internal_breakpoint_ops); - b->location = new_event_location (EVENT_LOCATION_LINESPEC); - EVENT_LOCATION_LINESPEC (b->location) = xstrdup (func_name); + b->location = new_event_location (EVENT_LOCATION_EXPLICIT); + EVENT_LOCATION_EXPLICIT (b->location)->function_name + = xstrdup (func_name); b->enable_state = bp_disabled; } @@ -10015,7 +10019,17 @@ create_breakpoint (struct gdbarch *gdbarch, /* If the location has a string representation, save it to the breakpoint's location save spec, since this may be used to save the breakpoint to a file. */ - if (EVENT_LOCATION_SAVE_SPEC (b->location) == NULL + if (EVENT_LOCATION_TYPE (b->location) == EVENT_LOCATION_EXPLICIT) + { + char *old = EVENT_LOCATION_SAVE_SPEC (b->location); + + EVENT_LOCATION_SAVE_SPEC (b->location) + = xstrprintf ("%s%s%s", old, + (extra_string == NULL ? "" : " "), + (extra_string == NULL ? "" : extra_string)); + xfree (old); + } + else if (EVENT_LOCATION_SAVE_SPEC (b->location) == NULL && event_location_to_string (b->location) != NULL) { EVENT_LOCATION_SAVE_SPEC (b->location) @@ -14272,11 +14286,11 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal) b->loc->symtab = sym != NULL ? sal2.symtab : NULL; delete_event_location (b->location); - b->location = new_event_location (EVENT_LOCATION_LINESPEC); - EVENT_LOCATION_LINESPEC (b->location) - = xstrprintf ("%s:%d", - symtab_to_filename_for_display (sal2.symtab), - b->loc->line_number); + b->location = new_event_location (EVENT_LOCATION_EXPLICIT); + EVENT_LOCATION_EXPLICIT (b->location)->source_filename + = xstrdup (symtab_to_filename_for_display (sal2.symtab)); + EVENT_LOCATION_EXPLICIT (b->location)->line_offset.offset + = b->loc->line_number; /* Might be nice to check if function changed, and warn if so. */ @@ -14528,7 +14542,14 @@ location_to_sals (struct breakpoint *b, struct event_location *location, char *p, *str; char *old = EVENT_LOCATION_SAVE_SPEC (location); - len = orig - prev; + if (EVENT_LOCATION_TYPE (location) == EVENT_LOCATION_EXPLICIT) + { + len = strlen (prev); + if (s != NULL) + len -= strlen (s); + } + else + len = orig - prev; str = savestring (prev, len); p = remove_trailing_whitespace (str, str + len); diff --git a/gdb/linespec.c b/gdb/linespec.c index 069aab6..600773c 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -66,31 +66,6 @@ typedef struct bound_minimal_symbol bound_minimal_symbol_d; DEF_VEC_O (bound_minimal_symbol_d); -/* An enumeration of possible signs for a line offset. */ -enum offset_relative_sign -{ - /* No sign */ - LINE_OFFSET_NONE, - - /* A plus sign ("+") */ - LINE_OFFSET_PLUS, - - /* A minus sign ("-") */ - LINE_OFFSET_MINUS, - - /* A special "sign" for unspecified offset. */ - LINE_OFFSET_UNKNOWN -}; - -/* A line offset in a linespec. */ - -struct line_offset -{ - /* Line offset and any specified sign. */ - int offset; - enum offset_relative_sign sign; -}; - /* A linespec. Elements of this structure are filled in by a parser (either parse_linespec or some other function). The structure is then converted into SALs by convert_linespec_to_sals. */ @@ -1550,6 +1525,29 @@ unexpected_linespec_error (linespec_parser *parser) token_type_strings[token.type]); } +/* Throw an undefined label error. */ + +static void ATTRIBUTE_NORETURN +undefined_label_error (const char *function, const char *label) +{ + if (function != NULL) + throw_error (NOT_FOUND_ERROR, + _("No label \"%s\" defined in function \"%s\"."), + label, function); + else + throw_error (NOT_FOUND_ERROR, + _("No label \"%s\" defined in current function."), + label); +} + +/* Throw a source file not found error. */ + +static void ATTRIBUTE_NORETURN +source_file_not_found_error (const char *name) +{ + throw_error (NOT_FOUND_ERROR, _("No source file named %s."), name); +} + /* Parse and return a line offset in STRING. */ static struct line_offset @@ -1724,9 +1722,8 @@ linespec_parse_basic (linespec_parser *parser) else { /* We don't know what it was, but it isn't a label. */ - throw_error (NOT_FOUND_ERROR, - _("No label \"%s\" defined in function \"%s\"."), - name, PARSER_RESULT (parser)->function_name); + undefined_label_error (PARSER_RESULT (parser)->function_name, + name); } /* Check for a line offset. */ @@ -1782,17 +1779,22 @@ canonicalize_linespec (struct linespec_state *state, linespec_p ls) else { struct ui_file *buf; + struct explicit_location *explicit; int need_colon = 0; buf = mem_fileopen (); + /* Convert any LINESPEC into EXPLICIT form so that the + parsing that was just done does not need to be repeated. */ state->canonical->location - = new_event_location (EVENT_LOCATION_LINESPEC); + = new_event_location (EVENT_LOCATION_EXPLICIT); + explicit = EVENT_LOCATION_EXPLICIT (state->canonical->location); if (ls->source_filename) { fputs_unfiltered (ls->source_filename, buf); need_colon = 1; + explicit->source_filename = xstrdup (ls->source_filename); } if (ls->function_name) @@ -1801,6 +1803,7 @@ canonicalize_linespec (struct linespec_state *state, linespec_p ls) fputc_unfiltered (':', buf); fputs_unfiltered (ls->function_name, buf); need_colon = 1; + explicit->function_name = xstrdup (ls->function_name); } if (ls->label_name) @@ -1819,11 +1822,13 @@ canonicalize_linespec (struct linespec_state *state, linespec_p ls) s = VEC_index (symbolp, ls->labels.function_symbols, 0); fputs_unfiltered (SYMBOL_NATURAL_NAME (s), buf); fputc_unfiltered (':', buf); + explicit->function_name = xstrdup (SYMBOL_NATURAL_NAME (s)); } fputs_unfiltered (ls->label_name, buf); need_colon = 1; state->canonical->special_display = 1; + explicit->label_name = xstrdup (ls->label_name); } if (ls->line_offset.sign != LINE_OFFSET_UNKNOWN) @@ -1835,12 +1840,11 @@ canonicalize_linespec (struct linespec_state *state, linespec_p ls) : (ls->line_offset.sign == LINE_OFFSET_PLUS ? "+" : "-")), ls->line_offset.offset); + explicit->line_offset = ls->line_offset; } - EVENT_LOCATION_LINESPEC (state->canonical->location) - = ui_file_xstrdup (buf, NULL); EVENT_LOCATION_SAVE_SPEC (state->canonical->location) - = xstrdup (EVENT_LOCATION_LINESPEC (state->canonical->location)); + = ui_file_xstrdup (buf, NULL); ui_file_delete (buf); } } @@ -2126,6 +2130,72 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) return sals; } +/* Convert the explicit location EXPLICIT into SaLs. */ + +static struct symtabs_and_lines +convert_explicit_location_to_sals (struct linespec_state *self, + linespec_p result, + struct explicit_location *explicit) +{ + VEC (symbolp) *symbols, *labels; + VEC (bound_minimal_symbol_d) *minimal_symbols; + + if (explicit->source_filename != NULL) + { + volatile struct gdb_exception except; + + TRY_CATCH (except, RETURN_MASK_ERROR) + { + result->file_symtabs + = symtabs_from_filename (explicit->source_filename); + } + + if (except.reason < 0 || result->file_symtabs == NULL) + source_file_not_found_error (explicit->source_filename); + + result->source_filename = xstrdup (explicit->source_filename); + } + else + { + /* A NULL entry means to use the default symtab. */ + VEC_safe_push (symtab_ptr, result->file_symtabs, NULL); + } + + if (explicit->function_name != NULL) + { + find_linespec_symbols (self, result->file_symtabs, + explicit->function_name, &symbols, + &minimal_symbols); + + if (symbols == NULL && minimal_symbols == NULL) + symbol_not_found_error (explicit->function_name, + result->source_filename); + + result->function_name = xstrdup (explicit->function_name); + result->function_symbols = symbols; + result->minimal_symbols = minimal_symbols; + } + + if (explicit->label_name != NULL) + { + symbols = NULL; + labels = find_label_symbols (self, result->function_symbols, + &symbols, explicit->label_name); + + if (labels == NULL) + undefined_label_error (result->function_name, explicit->label_name); + + result->label_name = xstrdup (explicit->label_name); + result->labels.label_symbols = labels; + result->labels.function_symbols = symbols; + } + + if (explicit->line_offset.sign != LINE_OFFSET_UNKNOWN) + result->line_offset = explicit->line_offset; + + return convert_linespec_to_sals (self, result); +} + /* Parse a string that specifies a linespec. Pass the address of a char * variable; that variable will be advanced over the characters actually parsed. @@ -2457,6 +2527,13 @@ event_location_to_sals (linespec_parser *parser, EVENT_LOCATION_ADDRESS (location)); break; + case EVENT_LOCATION_EXPLICIT: + result + = convert_explicit_location_to_sals (PARSER_STATE (parser), + PARSER_RESULT (parser), + EVENT_LOCATION_EXPLICIT (location)); + break; + case EVENT_LOCATION_PROBE: /* Probes are handled by their own decoders. */ gdb_assert_not_reached ("attempt to decode probe location"); @@ -3122,7 +3199,7 @@ symtabs_from_filename (const char *filename) throw_error (NOT_FOUND_ERROR, _("No symbol table is loaded. " "Use the \"file\" command.")); - throw_error (NOT_FOUND_ERROR, _("No source file named %s."), filename); + source_file_not_found_error (filename); } return result; diff --git a/gdb/location.c b/gdb/location.c index a64d37c..f52026a 100644 --- a/gdb/location.c +++ b/gdb/location.c @@ -28,6 +28,15 @@ #include #include +/* Initialize the given explicit location. */ + +void +initialize_explicit_location (struct explicit_location *explicit) +{ + memset (explicit, 0, sizeof (struct explicit_location)); + explicit->line_offset.sign = LINE_OFFSET_UNKNOWN; +} + /* Initialize the given LOCATION. */ void @@ -36,6 +45,8 @@ initialize_event_location (struct event_location *location, { memset (location, 0, sizeof (struct event_location)); EVENT_LOCATION_TYPE (location) = type; + if (type == EVENT_LOCATION_EXPLICIT) + initialize_explicit_location (EVENT_LOCATION_EXPLICIT (location)); } /* Create a new location with the given TYPE. */ @@ -72,6 +83,24 @@ copy_event_location (const struct event_location *src) EVENT_LOCATION_ADDRESS (dst) = EVENT_LOCATION_ADDRESS (src); break; + case EVENT_LOCATION_EXPLICIT: + if (EVENT_LOCATION_EXPLICIT (src)->source_filename != NULL) + EVENT_LOCATION_EXPLICIT (dst)->source_filename + = xstrdup (EVENT_LOCATION_EXPLICIT (src)->source_filename); + + if (EVENT_LOCATION_EXPLICIT (src)->function_name != NULL) + EVENT_LOCATION_EXPLICIT (dst)->function_name + = xstrdup (EVENT_LOCATION_EXPLICIT (src)->function_name); + + if (EVENT_LOCATION_EXPLICIT (src)->label_name != NULL) + EVENT_LOCATION_EXPLICIT (dst)->label_name + = xstrdup (EVENT_LOCATION_EXPLICIT (src)->label_name); + + EVENT_LOCATION_EXPLICIT (dst)->line_offset + = EVENT_LOCATION_EXPLICIT (src)->line_offset; + break; + + case EVENT_LOCATION_PROBE: EVENT_LOCATION_PROBE (dst) = xstrdup (EVENT_LOCATION_PROBE (src)); break; @@ -105,6 +134,12 @@ delete_event_location (void *data) /* Nothing to do. */ break; + case EVENT_LOCATION_EXPLICIT: + xfree (EVENT_LOCATION_EXPLICIT (location)->source_filename); + xfree (EVENT_LOCATION_EXPLICIT (location)->function_name); + xfree (EVENT_LOCATION_EXPLICIT (location)->label_name); + break; + case EVENT_LOCATION_PROBE: xfree (EVENT_LOCATION_PROBE (location)); break; @@ -133,6 +168,7 @@ event_location_to_string (const struct event_location *location) break; case EVENT_LOCATION_ADDRESS: + case EVENT_LOCATION_EXPLICIT: result = EVENT_LOCATION_SAVE_SPEC (location); break; @@ -211,6 +247,14 @@ event_location_empty_p (const struct event_location *location) case EVENT_LOCATION_ADDRESS: return 0; + case EVENT_LOCATION_EXPLICIT: + return (EVENT_LOCATION_EXPLICIT (location) == NULL + || (EVENT_LOCATION_EXPLICIT (location)->source_filename == NULL + && EVENT_LOCATION_EXPLICIT (location)->function_name == NULL + && EVENT_LOCATION_EXPLICIT (location)->label_name == NULL + && (EVENT_LOCATION_EXPLICIT (location)->line_offset.sign + == LINE_OFFSET_UNKNOWN))); + case EVENT_LOCATION_PROBE: return EVENT_LOCATION_PROBE (location) == NULL; diff --git a/gdb/location.h b/gdb/location.h index b207c87..0d3400a 100644 --- a/gdb/location.h +++ b/gdb/location.h @@ -21,6 +21,32 @@ struct language_defn; +/* An enumeration of possible signs for a line offset. */ + +enum offset_relative_sign +{ + /* No sign */ + LINE_OFFSET_NONE, + + /* A plus sign ("+") */ + LINE_OFFSET_PLUS, + + /* A minus sign ("-") */ + LINE_OFFSET_MINUS, + + /* A special "sign" for unspecified offset. */ + LINE_OFFSET_UNKNOWN +}; + +/* A line offset in a location. */ + +struct line_offset +{ + /* Line offset and any specified sign. */ + int offset; + enum offset_relative_sign sign; +}; + /* An enumeration of the various ways to specify a stop event location (used with create_breakpoint). */ @@ -32,10 +58,35 @@ enum event_location_type /* An address in the inferior. */ EVENT_LOCATION_ADDRESS, + /* An explicit location. */ + EVENT_LOCATION_EXPLICIT, + /* A probe location. */ EVENT_LOCATION_PROBE }; +/* An explicit location. This structure is used to bypass the + parsing done on linespecs. It still has the same requirements + as linespecs, though. For example, source_filename requires + at least one other field. */ + +struct explicit_location +{ + /* The source filename. Malloc'd. */ + char *source_filename; + + /* The function name. Malloc'd. */ + char *function_name; + + /* The name of a label. Malloc'd. */ + char *label_name; + + /* A line offset relative to the start of the symbol + identified by the above fields or the current symtab + if the other fields are NULL. */ + struct line_offset line_offset; +}; + /* An event location used to set a stop event in the inferior. This structure is an amalgam of the various ways to specify a where a stop event should be set. */ @@ -58,6 +109,10 @@ struct event_location /* An address in the inferior. */ CORE_ADDR address; #define EVENT_LOCATION_ADDRESS(S) ((S)->u.address) + + /* An explicit location. */ + struct explicit_location explicit; +#define EVENT_LOCATION_EXPLICIT(S) (&((S)->u.explicit)) } u; /* A string representation of how this location may be @@ -92,6 +147,10 @@ extern struct event_location * extern void initialize_event_location (struct event_location *location, enum event_location_type type); +/* Initialize the given explicit location. */ + +extern void initialize_explicit_location (struct explicit_location *explicit); + /* Attempt to convert the input string in *ARGP into an event location. ARGP is advanced past any processed input. Returns a event_location (malloc'd) if an event location was successfully found in *ARGP, --------------050400020007010509020707--