1 /* Data structures and API for location specs in GDB.
2 Copyright (C) 2013-2024 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "gdbsupport/gdb_assert.h"
20 #include "gdbsupport/gdb-checked-static-cast.h"
25 #include "cli/cli-utils.h"
27 #include "cp-support.h"
33 explicit_to_string_internal (bool as_linespec
,
34 const explicit_location_spec
*explicit_loc
);
36 /* Return a xstrdup of STR if not NULL, otherwise return NULL. */
39 maybe_xstrdup (const char *str
)
41 return (str
!= nullptr ? xstrdup (str
) : nullptr);
44 probe_location_spec::probe_location_spec (std::string
&&probe
)
45 : location_spec (PROBE_LOCATION_SPEC
, std::move (probe
))
50 probe_location_spec::clone () const
52 return location_spec_up (new probe_location_spec (*this));
56 probe_location_spec::empty_p () const
61 std::string
probe_location_spec::compute_string () const
63 return std::move (m_as_string
);
66 /* A "normal" linespec. */
67 linespec_location_spec::linespec_location_spec
68 (const char **linespec
, symbol_name_match_type match_type_
)
69 : location_spec (LINESPEC_LOCATION_SPEC
),
70 match_type (match_type_
)
72 if (*linespec
!= NULL
)
75 const char *orig
= *linespec
;
77 linespec_lex_to_end (linespec
);
78 p
= remove_trailing_whitespace (orig
, *linespec
);
80 /* If there is no valid linespec then this will leave the
81 spec_string as nullptr. This behavior is relied on in the
82 breakpoint setting code, where spec_string being nullptr means
83 to use the default breakpoint location. */
85 spec_string
.reset (savestring (orig
, p
- orig
));
90 linespec_location_spec::clone () const
92 return location_spec_up (new linespec_location_spec (*this));
96 linespec_location_spec::empty_p () const
101 linespec_location_spec::linespec_location_spec
102 (const linespec_location_spec
&other
)
103 : location_spec (other
),
104 match_type (other
.match_type
),
105 spec_string (maybe_xstrdup (other
.spec_string
.get ()))
110 linespec_location_spec::compute_string () const
112 if (spec_string
!= nullptr)
114 if (match_type
== symbol_name_match_type::FULL
)
115 return std::string ("-qualified ") + spec_string
.get ();
117 return spec_string
.get ();
122 address_location_spec::address_location_spec (CORE_ADDR addr
,
123 const char *addr_string
,
125 : location_spec (ADDRESS_LOCATION_SPEC
),
128 if (addr_string
!= nullptr)
129 m_as_string
= std::string (addr_string
, addr_string_len
);
133 address_location_spec::clone () const
135 return location_spec_up (new address_location_spec (*this));
139 address_location_spec::empty_p () const
144 address_location_spec::address_location_spec
145 (const address_location_spec
&other
)
146 : location_spec (other
),
147 address (other
.address
)
152 address_location_spec::compute_string () const
154 const char *addr_string
= core_addr_to_string (address
);
155 return std::string ("*") + addr_string
;
158 explicit_location_spec::explicit_location_spec (const char *function_name
)
159 : location_spec (EXPLICIT_LOCATION_SPEC
),
160 function_name (maybe_xstrdup (function_name
))
164 explicit_location_spec::explicit_location_spec
165 (const explicit_location_spec
&other
)
166 : location_spec (other
),
167 source_filename (maybe_xstrdup (other
.source_filename
.get ())),
168 function_name (maybe_xstrdup (other
.function_name
.get ())),
169 func_name_match_type (other
.func_name_match_type
),
170 label_name (maybe_xstrdup (other
.label_name
.get ())),
171 line_offset (other
.line_offset
)
176 explicit_location_spec::clone () const
178 return location_spec_up (new explicit_location_spec (*this));
182 explicit_location_spec::empty_p () const
184 return (source_filename
== nullptr
185 && function_name
== nullptr
186 && label_name
== nullptr
187 && line_offset
.sign
== LINE_OFFSET_UNKNOWN
);
191 explicit_location_spec::compute_string () const
193 return explicit_to_string_internal (false, this);
196 /* See description in location.h. */
199 new_linespec_location_spec (const char **linespec
,
200 symbol_name_match_type match_type
)
202 return location_spec_up (new linespec_location_spec (linespec
,
206 /* See description in location.h. */
208 const linespec_location_spec
*
209 as_linespec_location_spec (const location_spec
*locspec
)
211 gdb_assert (locspec
->type () == LINESPEC_LOCATION_SPEC
);
212 return gdb::checked_static_cast
<const linespec_location_spec
*> (locspec
);
215 /* See description in location.h. */
218 new_address_location_spec (CORE_ADDR addr
, const char *addr_string
,
221 return location_spec_up (new address_location_spec (addr
, addr_string
,
225 /* See description in location.h. */
227 const address_location_spec
*
228 as_address_location_spec (const location_spec
*locspec
)
230 gdb_assert (locspec
->type () == ADDRESS_LOCATION_SPEC
);
231 return gdb::checked_static_cast
<const address_location_spec
*> (locspec
);
234 /* See description in location.h. */
237 new_probe_location_spec (std::string
&&probe
)
239 return location_spec_up (new probe_location_spec (std::move (probe
)));
242 /* See description in location.h. */
244 const probe_location_spec
*
245 as_probe_location_spec (const location_spec
*locspec
)
247 gdb_assert (locspec
->type () == PROBE_LOCATION_SPEC
);
248 return gdb::checked_static_cast
<const probe_location_spec
*> (locspec
);
251 /* See description in location.h. */
253 const explicit_location_spec
*
254 as_explicit_location_spec (const location_spec
*locspec
)
256 gdb_assert (locspec
->type () == EXPLICIT_LOCATION_SPEC
);
257 return gdb::checked_static_cast
<const explicit_location_spec
*> (locspec
);
260 /* See description in location.h. */
262 explicit_location_spec
*
263 as_explicit_location_spec (location_spec
*locspec
)
265 gdb_assert (locspec
->type () == EXPLICIT_LOCATION_SPEC
);
266 return gdb::checked_static_cast
<explicit_location_spec
*> (locspec
);
269 /* Return a string representation of the explicit location spec in
272 AS_LINESPEC is true if this string should be a linespec. Otherwise
273 it will be output in explicit form. */
276 explicit_to_string_internal (bool as_linespec
,
277 const explicit_location_spec
*explicit_loc
)
279 bool need_space
= false;
280 char space
= as_linespec
? ':' : ' ';
283 if (explicit_loc
->source_filename
!= NULL
)
286 buf
.puts ("-source ");
287 buf
.puts (explicit_loc
->source_filename
.get ());
291 if (explicit_loc
->function_name
!= NULL
)
295 if (explicit_loc
->func_name_match_type
== symbol_name_match_type::FULL
)
296 buf
.puts ("-qualified ");
298 buf
.puts ("-function ");
299 buf
.puts (explicit_loc
->function_name
.get ());
303 if (explicit_loc
->label_name
!= NULL
)
308 buf
.puts ("-label ");
309 buf
.puts (explicit_loc
->label_name
.get ());
313 if (explicit_loc
->line_offset
.sign
!= LINE_OFFSET_UNKNOWN
)
320 (explicit_loc
->line_offset
.sign
== LINE_OFFSET_NONE
? ""
321 : (explicit_loc
->line_offset
.sign
322 == LINE_OFFSET_PLUS
? "+" : "-")),
323 explicit_loc
->line_offset
.offset
);
326 return buf
.release ();
329 /* See description in location.h. */
332 explicit_location_spec::to_linespec () const
334 return explicit_to_string_internal (true, this);
337 /* Find an instance of the quote character C in the string S that is
338 outside of all single- and double-quoted strings (i.e., any quoting
342 find_end_quote (const char *s
, char end_quote_char
)
344 /* zero if we're not in quotes;
345 '"' if we're in a double-quoted string;
346 '\'' if we're in a single-quoted string. */
347 char nested_quote_char
= '\0';
349 for (const char *scan
= s
; *scan
!= '\0'; scan
++)
351 if (nested_quote_char
!= '\0')
353 if (*scan
== nested_quote_char
)
354 nested_quote_char
= '\0';
355 else if (scan
[0] == '\\' && *(scan
+ 1) != '\0')
358 else if (*scan
== end_quote_char
&& nested_quote_char
== '\0')
360 else if (*scan
== '"' || *scan
== '\'')
361 nested_quote_char
= *scan
;
367 /* A lexer for explicit location specs. This function will advance
368 INP past any strings that it lexes. Returns a malloc'd copy of the
369 lexed string or NULL if no lexing was done. */
371 static gdb::unique_xmalloc_ptr
<char>
372 explicit_location_spec_lex_one (const char **inp
,
373 const struct language_defn
*language
,
374 explicit_completion_info
*completion_info
)
376 const char *start
= *inp
;
381 /* If quoted, skip to the ending quote. */
382 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
384 if (completion_info
!= NULL
)
385 completion_info
->quoted_arg_start
= start
;
387 const char *end
= find_end_quote (start
+ 1, *start
);
391 if (completion_info
== NULL
)
392 error (_("Unmatched quote, %s."), start
);
394 end
= start
+ strlen (start
);
396 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
400 if (completion_info
!= NULL
)
401 completion_info
->quoted_arg_end
= end
;
403 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
407 /* If the input starts with '-' or '+', the string ends with the next
408 whitespace or comma. */
409 if (*start
== '-' || *start
== '+')
411 while (*inp
[0] != '\0' && *inp
[0] != ',' && !isspace (*inp
[0]))
416 /* Handle numbers first, stopping at the next whitespace or ','. */
417 while (isdigit (*inp
[0]))
419 if (*inp
[0] == '\0' || isspace (*inp
[0]) || *inp
[0] == ',')
420 return gdb::unique_xmalloc_ptr
<char> (savestring (start
,
423 /* Otherwise stop at the next occurrence of whitespace, '\0',
428 && !(isspace ((*inp
)[0])
429 || linespec_lexer_lex_keyword (&(*inp
)[1])))
431 /* Special case: C++ operator,. */
432 if (language
->la_language
== language_cplus
433 && startswith (*inp
, CP_OPERATOR_STR
))
434 (*inp
) += CP_OPERATOR_LEN
;
439 if (*inp
- start
> 0)
440 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
445 /* Return true if COMMA points past "operator". START is the start of
446 the line that COMMAND points to, hence when reading backwards, we
447 must not read any character before START. */
450 is_cp_operator (const char *start
, const char *comma
)
453 && (comma
- start
) >= CP_OPERATOR_LEN
)
455 const char *p
= comma
;
457 while (p
> start
&& isspace (p
[-1]))
459 if (p
- start
>= CP_OPERATOR_LEN
)
461 p
-= CP_OPERATOR_LEN
;
462 if (strncmp (p
, CP_OPERATOR_STR
, CP_OPERATOR_LEN
) == 0
464 || !(isalnum (p
[-1]) || p
[-1] == '_')))
473 /* When scanning the input string looking for the next explicit
474 location spec option/delimiter, we jump to the next option by looking
475 for ",", and "-". Such a character can also appear in C++ symbols
476 like "operator," and "operator-". So when we find such a
477 character, we call this function to check if we found such a
478 symbol, meaning we had a false positive for an option string. In
479 that case, we keep looking for the next delimiter, until we find
480 one that is not a false positive, or we reach end of string. FOUND
481 is the character that scanning found (either '-' or ','), and START
482 is the start of the line that FOUND points to, hence when reading
483 backwards, we must not read any character before START. Returns a
484 pointer to the next non-false-positive delimiter character, or NULL
485 if none was found. */
488 skip_op_false_positives (const char *start
, const char *found
)
490 while (found
!= NULL
&& is_cp_operator (start
, found
))
492 if (found
[0] == '-' && found
[1] == '-')
496 found
= find_toplevel_char (start
, *found
);
502 /* Assuming both FIRST and NEW_TOK point into the same string, return
503 the pointer that is closer to the start of the string. If FIRST is
504 NULL, returns NEW_TOK. If NEW_TOK is NULL, returns FIRST. */
507 first_of (const char *first
, const char *new_tok
)
511 else if (new_tok
!= NULL
&& new_tok
< first
)
517 /* A lexer for functions in explicit location specs. This function will
518 advance INP past a function until the next option, or until end of
519 string. Returns a malloc'd copy of the lexed string or NULL if no
522 static gdb::unique_xmalloc_ptr
<char>
523 explicit_location_spec_lex_one_function
525 const struct language_defn
*language
,
526 explicit_completion_info
*completion_info
)
528 const char *start
= *inp
;
533 /* If quoted, skip to the ending quote. */
534 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
536 char quote_char
= *start
;
538 /* If the input is not an Ada operator, skip to the matching
539 closing quote and return the string. */
540 if (!(language
->la_language
== language_ada
541 && quote_char
== '\"' && is_ada_operator (start
)))
543 if (completion_info
!= NULL
)
544 completion_info
->quoted_arg_start
= start
;
546 const char *end
= find_toplevel_char (start
+ 1, quote_char
);
550 if (completion_info
== NULL
)
551 error (_("Unmatched quote, %s."), start
);
553 end
= start
+ strlen (start
);
555 char *saved
= savestring (start
+ 1, *inp
- start
- 1);
556 return gdb::unique_xmalloc_ptr
<char> (saved
);
559 if (completion_info
!= NULL
)
560 completion_info
->quoted_arg_end
= end
;
562 char *saved
= savestring (start
+ 1, *inp
- start
- 2);
563 return gdb::unique_xmalloc_ptr
<char> (saved
);
567 const char *comma
= find_toplevel_char (start
, ',');
569 /* If we have "-function -myfunction", or perhaps better example,
570 "-function -[BasicClass doIt]" (objc selector), treat
571 "-myfunction" as the function name. I.e., skip the first char if
572 it is an hyphen. Don't skip the first char always, because we
573 may have C++ "operator<", and find_toplevel_char needs to see the
577 ? find_toplevel_char (start
+ 1, '-')
578 : find_toplevel_char (start
, '-'));
580 /* Check for C++ "operator," and "operator-". */
581 comma
= skip_op_false_positives (start
, comma
);
582 hyphen
= skip_op_false_positives (start
, hyphen
);
584 /* Pick the one that appears first. */
585 const char *end
= first_of (hyphen
, comma
);
587 /* See if a linespec keyword appears first. */
588 const char *s
= start
;
589 const char *ws
= find_toplevel_char (start
, ' ');
590 while (ws
!= NULL
&& linespec_lexer_lex_keyword (ws
+ 1) == NULL
)
593 ws
= find_toplevel_char (s
, ' ');
596 end
= first_of (end
, ws
+ 1);
598 /* If we don't have any terminator, then take the whole string. */
600 end
= start
+ strlen (start
);
602 /* Trim whitespace at the end. */
603 while (end
> start
&& end
[-1] == ' ')
608 if (*inp
- start
> 0)
609 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
614 /* See description in location.h. */
617 string_to_explicit_location_spec (const char **argp
,
618 const struct language_defn
*language
,
619 explicit_completion_info
*completion_info
)
621 /* It is assumed that input beginning with '-' and a non-digit
622 character is an explicit location. "-p" is reserved, though,
623 for probe locations. */
627 || !isalpha ((*argp
)[1])
628 || ((*argp
)[0] == '-' && (*argp
)[1] == 'p'))
631 std::unique_ptr
<explicit_location_spec
> locspec
632 (new explicit_location_spec ());
634 /* Process option/argument pairs. dprintf_command
635 requires that processing stop on ','. */
636 while ((*argp
)[0] != '\0' && (*argp
)[0] != ',')
641 /* Clear these on each iteration, since they should be filled
642 with info about the last option. */
643 if (completion_info
!= NULL
)
645 completion_info
->quoted_arg_start
= NULL
;
646 completion_info
->quoted_arg_end
= NULL
;
649 /* If *ARGP starts with a keyword, stop processing
651 if (linespec_lexer_lex_keyword (*argp
) != NULL
)
654 /* Mark the start of the string in case we need to rewind. */
657 if (completion_info
!= NULL
)
658 completion_info
->last_option
= start
;
660 /* Get the option string. */
661 gdb::unique_xmalloc_ptr
<char> opt
662 = explicit_location_spec_lex_one (argp
, language
, NULL
);
664 /* Use the length of the option to allow abbreviations. */
665 len
= strlen (opt
.get ());
667 /* Get the argument string. */
668 *argp
= skip_spaces (*argp
);
670 /* All options have a required argument. Checking for this
671 required argument is deferred until later. */
672 gdb::unique_xmalloc_ptr
<char> oarg
;
673 /* True if we have an argument. This is required because we'll
674 move from OARG before checking whether we have an
676 bool have_oarg
= false;
678 /* True if the option needs an argument. */
679 bool need_oarg
= false;
681 /* Convenience to consistently set both OARG/HAVE_OARG from
683 auto set_oarg
= [&] (gdb::unique_xmalloc_ptr
<char> arg
)
685 if (completion_info
!= NULL
)
687 /* We do this here because the set of options that take
688 arguments matches the set of explicit location
690 completion_info
->saw_explicit_location_spec_option
= true;
692 oarg
= std::move (arg
);
693 have_oarg
= oarg
!= NULL
;
697 if (strncmp (opt
.get (), "-source", len
) == 0)
699 set_oarg (explicit_location_spec_lex_one (argp
, language
,
701 locspec
->source_filename
= std::move (oarg
);
703 else if (strncmp (opt
.get (), "-function", len
) == 0)
705 set_oarg (explicit_location_spec_lex_one_function (argp
, language
,
707 locspec
->function_name
= std::move (oarg
);
709 else if (strncmp (opt
.get (), "-qualified", len
) == 0)
711 locspec
->func_name_match_type
= symbol_name_match_type::FULL
;
713 else if (strncmp (opt
.get (), "-line", len
) == 0)
715 set_oarg (explicit_location_spec_lex_one (argp
, language
, NULL
));
716 *argp
= skip_spaces (*argp
);
719 locspec
->line_offset
= linespec_parse_line_offset (oarg
.get ());
723 else if (strncmp (opt
.get (), "-label", len
) == 0)
725 set_oarg (explicit_location_spec_lex_one (argp
, language
,
727 locspec
->label_name
= std::move (oarg
);
729 /* Only emit an "invalid argument" error for options
730 that look like option strings. */
731 else if (opt
.get ()[0] == '-' && !isdigit (opt
.get ()[1]))
733 if (completion_info
== NULL
)
734 error (_("invalid explicit location argument, \"%s\""), opt
.get ());
738 /* End of the explicit location specification.
739 Stop parsing and return whatever explicit location was
745 *argp
= skip_spaces (*argp
);
747 /* It's a little lame to error after the fact, but in this
748 case, it provides a much better user experience to issue
749 the "invalid argument" error before any missing
751 if (need_oarg
&& !have_oarg
&& completion_info
== NULL
)
752 error (_("missing argument for \"%s\""), opt
.get ());
755 /* One special error check: If a source filename was given
756 without offset, function, or label, issue an error. */
757 if (locspec
->source_filename
!= NULL
758 && locspec
->function_name
== NULL
759 && locspec
->label_name
== NULL
760 && (locspec
->line_offset
.sign
== LINE_OFFSET_UNKNOWN
)
761 && completion_info
== NULL
)
763 error (_("Source filename requires function, label, or "
767 return location_spec_up (locspec
.release ());
770 /* See description in location.h. */
773 string_to_location_spec_basic (const char **stringp
,
774 const struct language_defn
*language
,
775 symbol_name_match_type match_type
)
777 location_spec_up locspec
;
780 /* Try the input as a probe spec. */
782 if (cs
!= NULL
&& probe_linespec_to_static_ops (&cs
) != NULL
)
784 locspec
= new_probe_location_spec (*stringp
);
785 *stringp
+= strlen (*stringp
);
789 /* Try an address location spec. */
790 if (*stringp
!= NULL
&& **stringp
== '*')
792 const char *arg
, *orig
;
795 orig
= arg
= *stringp
;
796 addr
= linespec_expression_to_pc (&arg
);
797 locspec
= new_address_location_spec (addr
, orig
, arg
- orig
);
798 *stringp
+= arg
- orig
;
802 /* Everything else is a linespec. */
803 locspec
= new_linespec_location_spec (stringp
, match_type
);
810 /* See description in location.h. */
813 string_to_location_spec (const char **stringp
,
814 const struct language_defn
*language
,
815 symbol_name_match_type match_type
)
817 const char *arg
, *orig
;
819 /* Try an explicit location spec. */
820 orig
= arg
= *stringp
;
821 location_spec_up locspec
822 = string_to_explicit_location_spec (&arg
, language
, NULL
);
823 if (locspec
!= nullptr)
825 /* It was a valid explicit location. Advance STRINGP to
827 *stringp
+= arg
- orig
;
829 /* If the user really specified a location spec, then we're
831 if (!locspec
->empty_p ())
834 /* Otherwise, the user _only_ specified optional flags like
835 "-qualified", otherwise string_to_explicit_location_spec
836 would have thrown an error. Save the flags for "basic"
837 linespec parsing below and discard the explicit location
839 explicit_location_spec
*xloc
840 = gdb::checked_static_cast
<explicit_location_spec
*> (locspec
.get ());
841 match_type
= xloc
->func_name_match_type
;
844 /* Everything else is a "basic" linespec, address, or probe location
846 return string_to_location_spec_basic (stringp
, language
, match_type
);