Explicit locations: introduce probe locations
[deliverable/binutils-gdb.git] / gdb / location.c
index 44f3dc6e7a6eb549f5fd6632116d5b304282e3df..fd35c48541a3e852099c115657a100853fa36526 100644 (file)
@@ -45,6 +45,11 @@ struct event_location
        probes.  */
     char *addr_string;
 #define EL_LINESPEC(PTR) ((PTR)->u.addr_string)
+#define EL_PROBE(PTR) ((PTR)->u.addr_string)
+
+    /* An address in the inferior.  */
+    CORE_ADDR address;
+#define EL_ADDRESS(PTR) (PTR)->u.address
   } u;
 
   /* Cached string representation of this location.  This is used, e.g., to
@@ -94,6 +99,51 @@ get_linespec_location (const struct event_location *location)
 
 /* See description in location.h.  */
 
+struct event_location *
+new_address_location (CORE_ADDR addr)
+{
+  struct event_location *location;
+
+  location = XCNEW (struct event_location);
+  EL_TYPE (location) = ADDRESS_LOCATION;
+  EL_ADDRESS (location) = addr;
+  return location;
+}
+
+/* See description in location.h.  */
+
+CORE_ADDR
+get_address_location (const struct event_location *location)
+{
+  gdb_assert (EL_TYPE (location) == ADDRESS_LOCATION);
+  return EL_ADDRESS (location);
+}
+
+/* See description in location.h.  */
+
+struct event_location *
+new_probe_location (const char *probe)
+{
+  struct event_location *location;
+
+  location = XCNEW (struct event_location);
+  EL_TYPE (location) = PROBE_LOCATION;
+  if (probe != NULL)
+    EL_PROBE (location) = xstrdup (probe);
+  return location;
+}
+
+/* See description in location.h.  */
+
+const char *
+get_probe_location (const struct event_location *location)
+{
+  gdb_assert (EL_TYPE (location) == PROBE_LOCATION);
+  return EL_PROBE (location);
+}
+
+/* See description in location.h.  */
+
 struct event_location *
 copy_event_location (const struct event_location *src)
 {
@@ -111,6 +161,15 @@ copy_event_location (const struct event_location *src)
        EL_LINESPEC (dst) = xstrdup (EL_LINESPEC (src));
       break;
 
+    case ADDRESS_LOCATION:
+      EL_ADDRESS (dst) = EL_ADDRESS (src);
+      break;
+
+    case PROBE_LOCATION:
+      if (EL_PROBE (src) != NULL)
+       EL_PROBE (dst) = xstrdup (EL_PROBE (src));
+      break;
+
     default:
       gdb_assert_not_reached ("unknown event location type");
     }
@@ -151,6 +210,14 @@ delete_event_location (struct event_location *location)
          xfree (EL_LINESPEC (location));
          break;
 
+       case ADDRESS_LOCATION:
+         /* Nothing to do.  */
+         break;
+
+       case PROBE_LOCATION:
+         xfree (EL_PROBE (location));
+         break;
+
        default:
          gdb_assert_not_reached ("unknown event location type");
        }
@@ -173,6 +240,16 @@ event_location_to_string (struct event_location *location)
            EL_STRING (location) = xstrdup (EL_LINESPEC (location));
          break;
 
+       case ADDRESS_LOCATION:
+         EL_STRING (location)
+           = xstrprintf ("*%s",
+                         core_addr_to_string (EL_ADDRESS (location)));
+         break;
+
+       case PROBE_LOCATION:
+         EL_STRING (location) = xstrdup (EL_PROBE (location));
+         break;
+
        default:
          gdb_assert_not_reached ("unknown event location type");
        }
@@ -189,7 +266,35 @@ string_to_event_location (char **stringp,
 {
   struct event_location *location;
 
-  location = new_linespec_location (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
+    {
+      const char *cs;
+
+      /* Next, try the input as a probe spec.  */
+      cs = *stringp;
+      if (cs != NULL && probe_linespec_to_ops (&cs) != NULL)
+       {
+         location = new_probe_location (*stringp);
+         *stringp += strlen (*stringp);
+       }
+      else
+       {
+         /* Everything else is a linespec.  */
+         location = new_linespec_location (stringp);
+       }
+    }
+
   return location;
 }
 
@@ -204,6 +309,12 @@ event_location_empty_p (const struct event_location *location)
       /* Linespecs are never "empty."  (NULL is a valid linespec)  */
       return 0;
 
+    case ADDRESS_LOCATION:
+      return 0;
+
+    case PROBE_LOCATION:
+      return EL_PROBE (location) == NULL;
+
     default:
       gdb_assert_not_reached ("unknown event location type");
     }
This page took 0.029972 seconds and 4 git commands to generate.