Don't allow non-stack memory writes in the prologue for nios2.
[deliverable/binutils-gdb.git] / gdb / linespec.c
index 9ec4a5eb87ff42a806274bd66a2ef58021bb91f1..81f526d6f6b1428ad405c9796d2d8bdb57e9cf2a 100644 (file)
@@ -246,6 +246,7 @@ typedef enum ls_token_type linespec_token_type;
 /* List of keywords  */
 
 static const char * const linespec_keywords[] = { "if", "thread", "task" };
+#define IF_KEYWORD_INDEX 0
 
 /* A token of the linespec lexer  */
 
@@ -290,11 +291,6 @@ struct ls_parser
   /* Is the entire linespec quote-enclosed?  */
   int is_quote_enclosed;
 
-  /* Is a keyword syntactically valid at this point?
-     In, e.g., "break thread thread 1", the leading "keyword" must not
-     be interpreted as such.  */
-  int keyword_ok;
-
   /* The state of the parse.  */
   struct linespec_state state;
 #define PARSER_STATE(PPTR) (&(PPTR)->state)
@@ -418,10 +414,9 @@ linespec_lexer_lex_number (linespec_parser *parser, linespec_token *tokenp)
   return 1;
 }
 
-/* Does P represent one of the keywords?  If so, return
-   the keyword.  If not, return NULL.  */
+/* See linespec.h.  */
 
-static const char *
+const char *
 linespec_lexer_lex_keyword (const char *p)
 {
   int i;
@@ -433,11 +428,34 @@ linespec_lexer_lex_keyword (const char *p)
          int len = strlen (linespec_keywords[i]);
 
          /* If P begins with one of the keywords and the next
-            character is not a valid identifier character,
-            we have found a keyword.  */
+            character is whitespace, we may have found a keyword.
+            It is only a keyword if it is not followed by another
+            keyword.  */
          if (strncmp (p, linespec_keywords[i], len) == 0
-             && !(isalnum (p[len]) || p[len] == '_'))
-           return linespec_keywords[i];
+             && isspace (p[len]))
+           {
+             int j;
+
+             /* Special case: "if" ALWAYS stops the lexer, since it
+                is not possible to predict what is going to appear in
+                the condition, which can only be parsed after SaLs have
+                been found.  */
+             if (i != IF_KEYWORD_INDEX)
+               {
+                 p += len;
+                 p = skip_spaces_const (p);
+                 for (j = 0; j < ARRAY_SIZE (linespec_keywords); ++j)
+                   {
+                     int nextlen = strlen (linespec_keywords[j]);
+
+                     if (strncmp (p, linespec_keywords[j], nextlen) == 0
+                         && isspace (p[nextlen]))
+                       return NULL;
+                   }
+               }
+
+             return linespec_keywords[i];
+           }
        }
     }
 
@@ -734,13 +752,16 @@ linespec_lexer_lex_one (linespec_parser *parser)
       PARSER_STREAM (parser) = skip_spaces_const (PARSER_STREAM (parser));
 
       /* Check for a keyword, they end the linespec.  */
-      keyword = NULL;
-      if (parser->keyword_ok)
-       keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser));
+      keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser));
       if (keyword != NULL)
        {
          parser->lexer.current.type = LSTOKEN_KEYWORD;
          LS_TOKEN_KEYWORD (parser->lexer.current) = keyword;
+         /* We do not advance the stream here intentionally:
+            we would like lexing to stop when a keyword is seen.
+
+            PARSER_STREAM (parser) +=  strlen (keyword);  */
+
          return parser->lexer.current;
        }
 
@@ -1108,7 +1129,7 @@ find_methods (struct type *t, const char *name,
     {
       int method_counter;
 
-      CHECK_TYPEDEF (t);
+      t = check_typedef (t);
 
       /* Loop over each method name.  At this level, all overloads of a name
          are counted as a single name.  There is an inner loop which loops over
@@ -2175,10 +2196,6 @@ parse_linespec (linespec_parser *parser, const char **argptr)
        }
     }
 
-  /* A keyword at the start cannot be interpreted as such.
-     Consider "b thread thread 42".  */
-  parser->keyword_ok = 0;
-
   parser->lexer.saved_arg = *argptr;
   parser->lexer.stream = argptr;
 
@@ -2250,9 +2267,6 @@ parse_linespec (linespec_parser *parser, const char **argptr)
   else if (token.type != LSTOKEN_STRING && token.type != LSTOKEN_NUMBER)
     unexpected_linespec_error (parser);
 
-  /* Now we can recognize keywords.  */
-  parser->keyword_ok = 1;
-
   /* Shortcut: If the next token is not LSTOKEN_COLON, we know that
      this token cannot represent a filename.  */
   token = linespec_lexer_peek_token (parser);
@@ -2703,7 +2717,7 @@ collect_one_symbol (struct symbol *sym, void *d)
     return 1; /* Continue iterating.  */
 
   t = SYMBOL_TYPE (sym);
-  CHECK_TYPEDEF (t);
+  t = check_typedef (t);
   if (TYPE_CODE (t) != TYPE_CODE_STRUCT
       && TYPE_CODE (t) != TYPE_CODE_UNION
       && TYPE_CODE (t) != TYPE_CODE_NAMESPACE)
@@ -3418,7 +3432,9 @@ collect_symbols (struct symbol *sym, void *data)
 }
 
 /* We've found a minimal symbol MSYMBOL in OBJFILE to associate with our
-   linespec; return the SAL in RESULT.  */
+   linespec; return the SAL in RESULT.  This function should return SALs
+   matching those from find_function_start_sal, otherwise false
+   multiple-locations breakpoints could be placed.  */
 
 static void
 minsym_found (struct linespec_state *self, struct objfile *objfile,
@@ -3440,7 +3456,23 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
     sal = find_pc_sect_line (pc, NULL, 0);
 
   if (self->funfirstline)
-    skip_prologue_sal (&sal);
+    {
+      if (sal.symtab != NULL
+         && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab))
+             || SYMTAB_LANGUAGE (sal.symtab) == language_asm))
+       {
+         /* If gdbarch_convert_from_func_ptr_addr does not apply then
+            sal.SECTION, sal.LINE&co. will stay correct from above.
+            If gdbarch_convert_from_func_ptr_addr applies then
+            sal.SECTION is cleared from above and sal.LINE&co. will
+            stay correct from the last find_pc_sect_line above.  */
+         sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
+         sal.pc = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc,
+                                                      &current_target);
+       }
+      else
+       skip_prologue_sal (&sal);
+    }
 
   if (maybe_add_address (self->addr_set, objfile->pspace, sal.pc))
     add_sal_to_sals (self, result, &sal, MSYMBOL_NATURAL_NAME (msymbol), 0);
This page took 0.026541 seconds and 4 git commands to generate.