]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
add to_identity
authorPaul Koning <paul_koning@dell.com>
Wed, 14 Oct 2015 20:03:09 +0000 (16:03 -0400)
committerPaul Koning <paul_koning@dell.com>
Wed, 14 Oct 2015 20:03:09 +0000 (16:03 -0400)
Right now a target_ops has an odd sense of identity.

Most times some identity is needed, a pointer to a static object is
passed in.  For example, calls to unpush_target generally work like
this:

    unpush_target (&exec_ops);

Conceptually this is a kind of "instanceof" checking.

Now, consider this with "to_xclose" targets.  In this case the
target_ops is allocated on the heap and there's no good way to talk
about the identity.  Code could remember the pointer, of course, but
this usually just begs the question.

For example in a to_open implementation it is reasonably normal to
check target_is_pushed and then do nothing if the target is pushed.
However, there's no reasonable way way to do this with a to_xclose
target.

This patch introduces a to_identity field that just points to the
"prototype" implementation of a target_ops.  This lets us convert
targets to to_xclose without difficulty.

2014-07-29  Tom Tromey  <tromey@redhat.com>

* bfd-target.c (target_bfd_reopen): Set to_identity.
* target.c (complete_target_initialization): Set to_identity.
(unpush_target): Check to_identity.  Call target_close on the real
target.
(target_is_pushed): Check to_identity.
* target.h (struct target_ops) <to_identity>: New field.

gdb/bfd-target.c
gdb/target.c
gdb/target.h

index ee93c3bb242d2f5c23ad48d9670a4823d526a4a2..8a37696baeadee42154319711d6b9ccebfaeda12 100644 (file)
@@ -98,6 +98,7 @@ target_bfd_reopen (struct bfd *abfd)
   t->to_xclose = target_bfd_xclose;
   t->to_data = data;
   t->to_magic = OPS_MAGIC;
+  t->to_identity = t;
 
   return t;
 }
index b8b1e9b4b0346cf864d24aa41383e2492c8efc6d..1a3d41777ab9da4a27dd7cb8d9d701ba56d07ab9 100644 (file)
@@ -339,6 +339,8 @@ complete_target_initialization (struct target_ops *t)
   gdb_assert (t->to_can_run == NULL || (t->to_can_async_p != NULL
                                        && t->to_supports_non_stop != NULL));
 
+  t->to_identity = t;
+
   install_delegators (t);
 }
 
@@ -722,7 +724,7 @@ unpush_target (struct target_ops *t)
 
   for (cur = &target_stack; (*cur) != NULL; cur = &(*cur)->beneath)
     {
-      if ((*cur) == t)
+      if ((*cur) == t || (*cur)->to_identity == t)
        break;
     }
 
@@ -741,7 +743,7 @@ unpush_target (struct target_ops *t)
   /* Finally close the target.  Note we do this after unchaining, so
      any target method calls from within the target_close
      implementation don't end up in T anymore.  */
-  target_close (t);
+  target_close (tmp);
 
   return 1;
 }
@@ -788,7 +790,7 @@ target_is_pushed (struct target_ops *t)
     }
 
   for (cur = target_stack; cur != NULL; cur = cur->beneath)
-    if (cur == t)
+    if (cur == t || cur->to_identity == t)
       return 1;
 
   return 0;
index 2b2db4599ce01719d174cfb4cdb8a52fcc8d32d6..804b5791cfe707e9f4df1e2d59dba6cf833fcd3f 100644 (file)
@@ -1241,6 +1241,12 @@ struct target_ops
     void (*to_done_generating_core) (struct target_ops *)
       TARGET_DEFAULT_IGNORE ();
 
+    /* This points to an "original" target_ops from which a particular
+       instance may have been cloned.  This is useful if a to_xclose
+       target clones some other target_ops, but still wants to call
+       target_is_pushed or unpush_target.  */
+    struct target_ops *to_identity;
+
     int to_magic;
     /* Need sub-structure for target machine related rather than comm related?
      */