]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/python/lib/gdb/command/xmethods.py
2 # Copyright 2013-2021 Free Software Foundation, Inc.
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 """GDB commands for working with xmethods."""
23 def validate_xm_regexp(part_name
, regexp
):
25 return re
.compile(regexp
)
27 raise SyntaxError("Invalid %s regexp: %s", part_name
, regexp
)
30 def parse_xm_command_args(arg
):
31 """Parses the arguments passed to a xmethod command.
34 arg: The argument string passed to a xmethod command.
37 A 3-tuple: (<locus matching regular expression>,
38 <matcher matching regular expression>,
39 <name matching regular experession>)
41 argv
= gdb
.string_to_argv(arg
)
44 raise SyntaxError("Too many arguments to command.")
46 matcher_name_regexp
= ""
49 locus_regexp
= argv
[0]
51 parts
= argv
[1].split(";", 1)
52 matcher_name_regexp
= parts
[0]
54 xm_name_regexp
= parts
[1]
56 name_re
= validate_xm_regexp("xmethod name", xm_name_regexp
)
59 return (validate_xm_regexp("locus", locus_regexp
),
60 validate_xm_regexp("matcher name", matcher_name_regexp
),
64 def get_global_method_matchers(locus_re
, matcher_re
):
65 """Returns a dict of matching globally registered xmethods.
68 locus_re: Even though only globally registered xmethods are
69 looked up, they will be looked up only if 'global' matches
71 matcher_re: The regular expression matching the names of xmethods.
74 A dict of matching globally registered xmethod matchers. The only
75 key in the dict will be 'global'.
78 xm_dict
= { locus_str
: [] }
79 if locus_re
.match("global"):
80 xm_dict
[locus_str
].extend(
81 [m
for m
in gdb
.xmethods
if matcher_re
.match(m
.name
)])
85 def get_method_matchers_in_loci(loci
, locus_re
, matcher_re
):
86 """Returns a dict of matching registered xmethods in the LOCI.
89 loci: The list of loci to lookup matching xmethods in.
90 locus_re: If a locus is an objfile, then xmethod matchers will be
91 looked up in it only if its filename matches the regular
92 expression LOCUS_RE. If a locus is the current progspace,
93 then xmethod matchers will be looked up in it only if the
94 string "progspace" matches LOCUS_RE.
95 matcher_re: The regular expression to match the xmethod matcher
99 A dict of matching xmethod matchers. The keys of the dict are the
100 filenames of the loci the xmethod matchers belong to.
104 if isinstance(locus
, gdb
.Progspace
):
105 if not locus_re
.match('progspace'):
107 locus_type
= "progspace"
109 if not locus_re
.match(locus
.filename
):
111 locus_type
= "objfile"
112 locus_str
= "%s %s" % (locus_type
, locus
.filename
)
113 xm_dict
[locus_str
] = [
114 m
for m
in locus
.xmethods
if matcher_re
.match(m
.name
)]
118 def print_xm_info(xm_dict
, name_re
):
119 """Print a dictionary of xmethods."""
120 def get_status_string(m
):
128 for locus_str
in xm_dict
:
129 if not xm_dict
[locus_str
]:
131 print ("Xmethods in %s:" % locus_str
)
132 for matcher
in xm_dict
[locus_str
]:
133 print (" %s%s" % (matcher
.name
, get_status_string(matcher
)))
134 if not matcher
.methods
:
136 for m
in matcher
.methods
:
137 if name_re
is None or name_re
.match(m
.name
):
138 print (" %s%s" % (m
.name
, get_status_string(m
)))
141 def set_xm_status1(xm_dict
, name_re
, status
):
142 """Set the status (enabled/disabled) of a dictionary of xmethods."""
143 for locus_str
, matchers
in xm_dict
.items():
144 for matcher
in matchers
:
146 # If the name regex is missing, then set the status of the
147 # matcher and move on.
148 matcher
.enabled
= status
150 if not matcher
.methods
:
151 # The methods attribute could be None. Move on.
153 for m
in matcher
.methods
:
154 if name_re
.match(m
.name
):
158 def set_xm_status(arg
, status
):
159 """Set the status (enabled/disabled) of xmethods matching ARG.
160 This is a helper function for enable/disable commands. ARG is the
161 argument string passed to the commands.
163 locus_re
, matcher_re
, name_re
= parse_xm_command_args(arg
)
164 set_xm_status1(get_global_method_matchers(locus_re
, matcher_re
), name_re
,
167 get_method_matchers_in_loci(
168 [gdb
.current_progspace()], locus_re
, matcher_re
),
172 get_method_matchers_in_loci(gdb
.objfiles(), locus_re
, matcher_re
),
177 class InfoXMethod(gdb
.Command
):
178 """GDB command to list registered xmethod matchers.
180 Usage: info xmethod [LOCUS-REGEXP [NAME-REGEXP]]
182 LOCUS-REGEXP is a regular expression matching the location of the
183 xmethod matchers. If it is omitted, all registered xmethod matchers
184 from all loci are listed. A locus could be 'global', a regular expression
185 matching the current program space's filename, or a regular expression
186 matching filenames of objfiles. Locus could be 'progspace' to specify that
187 only xmethods from the current progspace should be listed.
189 NAME-REGEXP is a regular expression matching the names of xmethod
190 matchers. If this omitted for a specified locus, then all registered
191 xmethods in the locus are listed. To list only a certain xmethods
192 managed by a single matcher, the name regexp can be specified as
193 matcher-name-regexp;xmethod-name-regexp."""
196 super(InfoXMethod
, self
).__init
__("info xmethod",
199 def invoke(self
, arg
, from_tty
):
200 locus_re
, matcher_re
, name_re
= parse_xm_command_args(arg
)
201 print_xm_info(get_global_method_matchers(locus_re
, matcher_re
),
204 get_method_matchers_in_loci(
205 [gdb
.current_progspace()], locus_re
, matcher_re
),
208 get_method_matchers_in_loci(gdb
.objfiles(), locus_re
, matcher_re
),
212 class EnableXMethod(gdb
.Command
):
213 """GDB command to enable a specified (group of) xmethod(s).
215 Usage: enable xmethod [LOCUS-REGEXP [NAME-REGEXP]]
217 LOCUS-REGEXP is a regular expression matching the location of the
218 xmethod matchers. If it is omitted, all registered xmethods matchers
219 from all loci are enabled. A locus could be 'global', a regular expression
220 matching the current program space's filename, or a regular expression
221 matching filenames of objfiles. Locus could be 'progspace' to specify that
222 only xmethods from the current progspace should be enabled.
224 NAME-REGEXP is a regular expression matching the names of xmethods
225 within a given locus. If this omitted for a specified locus, then all
226 registered xmethod matchers in the locus are enabled. To enable only
227 a certain xmethods managed by a single matcher, the name regexp can be
228 specified as matcher-name-regexp;xmethod-name-regexp."""
231 super(EnableXMethod
, self
).__init
__("enable xmethod",
234 def invoke(self
, arg
, from_tty
):
235 set_xm_status(arg
, True)
238 class DisableXMethod(gdb
.Command
):
239 """GDB command to disable a specified (group of) xmethod(s).
241 Usage: disable xmethod [LOCUS-REGEXP [NAME-REGEXP]]
243 LOCUS-REGEXP is a regular expression matching the location of the
244 xmethod matchers. If it is omitted, all registered xmethod matchers
245 from all loci are disabled. A locus could be 'global', a regular
246 expression matching the current program space's filename, or a regular
247 expression filenames of objfiles. Locus could be 'progspace' to specify
248 that only xmethods from the current progspace should be disabled.
250 NAME-REGEXP is a regular expression matching the names of xmethods
251 within a given locus. If this omitted for a specified locus, then all
252 registered xmethod matchers in the locus are disabled. To disable
253 only a certain xmethods managed by a single matcher, the name regexp
254 can be specified as matcher-name-regexp;xmethod-name-regexp."""
257 super(DisableXMethod
, self
).__init
__("disable xmethod",
260 def invoke(self
, arg
, from_tty
):
261 set_xm_status(arg
, False)
264 def register_xmethod_commands():
265 """Installs the xmethod commands."""
271 register_xmethod_commands()