From c7c1b3e998a77eb077ac3c08c88a97d2e11dfef0 Mon Sep 17 00:00:00 2001 From: Keith Seitz Date: Tue, 11 Aug 2015 17:09:35 -0700 Subject: Explicit locations: introduce new struct event_location-based API This patch introduces the new breakpoint/"linespec" API based on a new struct event_location. This API currently only supports traditional linespecs, maintaining the status quo of the code base. Future patches will add additional functionality for other location types such as address locations. gdb/ChangeLog: * Makefile.in (SFILES): Add location.c. (HFILES_NO_SRCDIR): Add location.h. (COMMON_OBS): Add location.o. * linespec.c (linespec_lex_to_end): New function. * linespec.h (linespec_lex_to_end): Declare. * location.c: New file. * location.h: New file. --- gdb/location.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 gdb/location.c (limited to 'gdb/location.c') diff --git a/gdb/location.c b/gdb/location.c new file mode 100644 index 0000000..44f3dc6 --- /dev/null +++ b/gdb/location.c @@ -0,0 +1,220 @@ +/* Data structures and API for event locations in GDB. + Copyright (C) 2013-2015 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "gdb_assert.h" +#include "location.h" +#include "symtab.h" +#include "language.h" +#include "linespec.h" +#include "cli/cli-utils.h" +#include "probe.h" + +#include +#include + +/* An event location used to set a stop event in the inferior. + This structure is an amalgam of the various ways + to specify where a stop event should be set. */ + +struct event_location +{ + /* The type of this breakpoint specification. */ + enum event_location_type type; +#define EL_TYPE(PTR) (PTR)->type + + union + { + /* A generic "this is a string specification" for a location. + This representation is used by both "normal" linespecs and + probes. */ + char *addr_string; +#define EL_LINESPEC(PTR) ((PTR)->u.addr_string) + } u; + + /* Cached string representation of this location. This is used, e.g., to + save stop event locations to file. Malloc'd. */ + char *as_string; +#define EL_STRING(PTR) ((PTR)->as_string) +}; + +/* See description in location.h. */ + +enum event_location_type +event_location_type (const struct event_location *location) +{ + return EL_TYPE (location); +} + +/* See description in location.h. */ + +struct event_location * +new_linespec_location (char **linespec) +{ + struct event_location *location; + + location = XCNEW (struct event_location); + EL_TYPE (location) = LINESPEC_LOCATION; + if (*linespec != NULL) + { + char *p; + char *orig = *linespec; + + linespec_lex_to_end (linespec); + p = remove_trailing_whitespace (orig, *linespec); + if ((p - orig) > 0) + EL_LINESPEC (location) = savestring (orig, p - orig); + } + return location; +} + +/* See description in location.h. */ + +const char * +get_linespec_location (const struct event_location *location) +{ + gdb_assert (EL_TYPE (location) == LINESPEC_LOCATION); + return EL_LINESPEC (location); +} + +/* See description in location.h. */ + +struct event_location * +copy_event_location (const struct event_location *src) +{ + struct event_location *dst; + + dst = XCNEW (struct event_location); + EL_TYPE (dst) = EL_TYPE (src); + if (EL_STRING (src) != NULL) + EL_STRING (dst) = xstrdup (EL_STRING (src)); + + switch (EL_TYPE (src)) + { + case LINESPEC_LOCATION: + if (EL_LINESPEC (src) != NULL) + EL_LINESPEC (dst) = xstrdup (EL_LINESPEC (src)); + break; + + default: + gdb_assert_not_reached ("unknown event location type"); + } + + return dst; +} + +/* A cleanup function for struct event_location. */ + +static void +delete_event_location_cleanup (void *data) +{ + struct event_location *location = (struct event_location *) data; + + delete_event_location (location); +} + +/* See description in location.h. */ + +struct cleanup * +make_cleanup_delete_event_location (struct event_location *location) +{ + return make_cleanup (delete_event_location_cleanup, location); +} + +/* See description in location.h. */ + +void +delete_event_location (struct event_location *location) +{ + if (location != NULL) + { + xfree (EL_STRING (location)); + + switch (EL_TYPE (location)) + { + case LINESPEC_LOCATION: + xfree (EL_LINESPEC (location)); + break; + + default: + gdb_assert_not_reached ("unknown event location type"); + } + + xfree (location); + } +} + +/* See description in location.h. */ + +const char * +event_location_to_string (struct event_location *location) +{ + if (EL_STRING (location) == NULL) + { + switch (EL_TYPE (location)) + { + case LINESPEC_LOCATION: + if (EL_LINESPEC (location) != NULL) + EL_STRING (location) = xstrdup (EL_LINESPEC (location)); + break; + + default: + gdb_assert_not_reached ("unknown event location type"); + } + } + + return EL_STRING (location); +} + +/* See description in location.h. */ + +struct event_location * +string_to_event_location (char **stringp, + const struct language_defn *language) +{ + struct event_location *location; + + location = new_linespec_location (stringp); + return location; +} + +/* See description in location.h. */ + +int +event_location_empty_p (const struct event_location *location) +{ + switch (EL_TYPE (location)) + { + case LINESPEC_LOCATION: + /* Linespecs are never "empty." (NULL is a valid linespec) */ + return 0; + + default: + gdb_assert_not_reached ("unknown event location type"); + } +} + +/* See description in location.h. */ + +void +set_event_location_string (struct event_location *location, + const char *string) +{ + xfree (EL_STRING (location)); + EL_STRING (location) = string == NULL ? NULL : xstrdup (string); +} -- cgit v1.1