diff options
author | Pedro Alves <palves@redhat.com> | 2018-06-07 17:27:48 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2018-06-07 18:58:04 +0100 |
commit | a1740ee1573d6e0e21692f815b322e3d062bbbee (patch) | |
tree | 5fe3095ee10694ef320ee64267840d1d2a7db816 /gdb/target.h | |
parent | d6ca69cddc3fc6ef61fdfe3c3803d13b0b4e13e9 (diff) | |
download | gdb-a1740ee1573d6e0e21692f815b322e3d062bbbee.zip gdb-a1740ee1573d6e0e21692f815b322e3d062bbbee.tar.gz gdb-a1740ee1573d6e0e21692f815b322e3d062bbbee.tar.bz2 |
Introduce class target_stack
Currently, the target stack is represented by a singly linked list,
with target_ops having a pointer to the target beneath. This poses a
problem for multi-process / multi-target debugging. In that case, we
will naturally want multiple instances of target stacks. E.g., one
stack for inferior 1 which is debugging a core file, and another
target stack for inferior 2 which is debugging a remote process. The
problem then is in finding a target's "beneath" target, if we consider
that for some target_ops types, we'll be sharing a single target_ops
instance between several inferiors. For example, so far, I found no
need to have multiple instances of the spu_multiarch_target /
exec_target / dummy_target targets.
Thus this patch, which changes the target stack representation to an
array of pointers. For now, there's still a single global instance of
this new target_stack class, though further down in the multi-target
work, each inferior will have its own instance.
gdb/ChangeLog:
2018-06-07 Pedro Alves <palves@redhat.com>
* target.h (target_ops) <beneath>: Now a method. All references
updated.
(class target_stack): New.
* target.c (g_target_stack): New.
(g_current_top_target): Delete.
(current_top_target): Get the top target out of g_target_stack.
(target_stack::push, target_stack::unpush): New.
(push_target, unpush_target): Reimplement.
(target_is_pushed): Reimplement in terms of g_target_stack.
(target_ops::beneath, target_stack::find_beneath): New.
Diffstat (limited to 'gdb/target.h')
-rw-r--r-- | gdb/target.h | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/gdb/target.h b/gdb/target.h index 9dd29a6..18c4a84 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -61,7 +61,11 @@ struct inferior; of variables any more (the file target is handling them and they never get to the process target). So when you push a file target, it goes into the file stratum, which is always below the process - stratum. */ + stratum. + + Note that rather than allow an empty stack, we always have the + dummy target at the bottom stratum, so we can call the target + methods without checking them. */ #include "target/target.h" #include "target/resume.h" @@ -425,7 +429,6 @@ struct target_info struct target_ops { /* To the target under this one. */ - target_ops *m_beneath; target_ops *beneath () const; /* Free resources associated with the target. Note that singleton @@ -1268,6 +1271,46 @@ extern void set_native_target (target_ops *target); NULL. */ extern target_ops *get_native_target (); +/* Type that manages a target stack. See description of target stacks + and strata at the top of the file. */ + +class target_stack +{ +public: + target_stack () = default; + DISABLE_COPY_AND_ASSIGN (target_stack); + + /* Push a new target into the stack of the existing target + accessors, possibly superseding some existing accessor. */ + void push (target_ops *t); + + /* Remove a target from the stack, wherever it may be. Return true + if it was removed, false otherwise. */ + bool unpush (target_ops *t); + + /* Returns true if T is pushed on the target stack. */ + bool is_pushed (target_ops *t) const + { return at (t->to_stratum) == t; } + + /* Return the target at STRATUM. */ + target_ops *at (strata stratum) const { return m_stack[stratum]; } + + /* Return the target at the top of the stack. */ + target_ops *top () const { return at (m_top); } + + /* Find the next target down the stack from the specified target. */ + target_ops *find_beneath (const target_ops *t) const; + +private: + /* The stratum of the top target. */ + enum strata m_top {}; + + /* The stack, represented as an array, with one slot per stratum. + If no target is pushed at some stratum, the corresponding slot is + null. */ + target_ops *m_stack[(int) debug_stratum + 1] {}; +}; + /* The ops structure for our "current" target process. This should never be NULL. If there is no target, it points to the dummy_target. */ |