mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 10:35:12 +08:00
221 lines
5.1 KiB
C
221 lines
5.1 KiB
C
|
/* 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 <http://www.gnu.org/licenses/>. */
|
||
|
|
||
|
#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 <ctype.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
/* 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);
|
||
|
}
|