Esempio n. 1
0
static int
is_unlimited_literal (const char *arg)
{
  size_t len = sizeof ("unlimited") - 1;

  arg = skip_spaces_const (arg);

  return (strncmp (arg, "unlimited", len) == 0
	  && (isspace (arg[len]) || arg[len] == '\0'));
}
Esempio n. 2
0
int
get_number_or_range (struct get_number_or_range_state *state)
{
  if (*state->string != '-')
    {
      /* Default case: state->string is pointing either to a solo
	 number, or to the first number of a range.  */
      state->last_retval = get_number_trailer (&state->string, '-');
      if (*state->string == '-')
	{
	  const char **temp;

	  /* This is the start of a range (<number1> - <number2>).
	     Skip the '-', parse and remember the second number,
	     and also remember the end of the final token.  */

	  temp = &state->end_ptr; 
	  state->end_ptr = skip_spaces_const (state->string + 1);
	  state->end_value = get_number_const (temp);
	  if (state->end_value < state->last_retval) 
	    {
	      error (_("inverted range"));
	    }
	  else if (state->end_value == state->last_retval)
	    {
	      /* Degenerate range (number1 == number2).  Advance the
		 token pointer so that the range will be treated as a
		 single number.  */ 
	      state->string = state->end_ptr;
	    }
	  else
	    state->in_range = 1;
	}
    }
  else if (! state->in_range)
    error (_("negative value"));
  else
    {
      /* state->string points to the '-' that betokens a range.  All
	 number-parsing has already been done.  Return the next
	 integer value (one greater than the saved previous value).
	 Do not advance the token pointer until the end of range
	 is reached.  */

      if (++state->last_retval == state->end_value)
	{
	  /* End of range reached; advance token pointer.  */
	  state->string = state->end_ptr;
	  state->in_range = 0;
	}
    }
  state->finished = *state->string == '\0';
  return state->last_retval;
}
Esempio n. 3
0
char *
extract_arg_const (const char **arg)
{
  const char *result;

  if (!*arg)
    return NULL;

  /* Find the start of the argument.  */
  *arg = skip_spaces_const (*arg);
  if (!**arg)
    return NULL;
  result = *arg;

  /* Find the end of the argument.  */
  *arg = skip_to_space_const (*arg + 1);

  if (result == *arg)
    return NULL;

  return savestring (result, *arg - result);
}
Esempio n. 4
0
event_location_up
string_to_explicit_location (const char **argp,
			     const struct language_defn *language,
			     int dont_throw)
{
  event_location_up location;

  /* It is assumed that input beginning with '-' and a non-digit
     character is an explicit location.  "-p" is reserved, though,
     for probe locations.  */
  if (argp == NULL
      || *argp == NULL
      || *argp[0] != '-'
      || !isalpha ((*argp)[1])
      || ((*argp)[0] == '-' && (*argp)[1] == 'p'))
    return NULL;

  location = new_explicit_location (NULL);

  /* Process option/argument pairs.  dprintf_command
     requires that processing stop on ','.  */
  while ((*argp)[0] != '\0' && (*argp)[0] != ',')
    {
      int len;
      const char *start;

      /* If *ARGP starts with a keyword, stop processing
	 options.  */
      if (linespec_lexer_lex_keyword (*argp) != NULL)
	break;

      /* Mark the start of the string in case we need to rewind.  */
      start = *argp;

      /* Get the option string.  */
      gdb::unique_xmalloc_ptr<char> opt
	= explicit_location_lex_one (argp, language);

      *argp = skip_spaces_const (*argp);

      /* Get the argument string.  */
      gdb::unique_xmalloc_ptr<char> oarg
	= explicit_location_lex_one (argp, language);
      bool have_oarg = oarg != NULL;
      *argp = skip_spaces_const (*argp);

      /* Use the length of the option to allow abbreviations.  */
      len = strlen (opt.get ());

      /* All options have a required argument.  Checking for this required
	 argument is deferred until later.  */
      if (strncmp (opt.get (), "-source", len) == 0)
	EL_EXPLICIT (location)->source_filename = oarg.release ();
      else if (strncmp (opt.get (), "-function", len) == 0)
	EL_EXPLICIT (location)->function_name = oarg.release ();
      else if (strncmp (opt.get (), "-line", len) == 0)
	{
	  if (have_oarg)
	    EL_EXPLICIT (location)->line_offset
	      = linespec_parse_line_offset (oarg.get ());
	}
      else if (strncmp (opt.get (), "-label", len) == 0)
	EL_EXPLICIT (location)->label_name = oarg.release ();
      /* Only emit an "invalid argument" error for options
	 that look like option strings.  */
      else if (opt.get ()[0] == '-' && !isdigit (opt.get ()[1]))
	{
	  if (!dont_throw)
	    error (_("invalid explicit location argument, \"%s\""), opt.get ());
	}
      else
	{
	  /* End of the explicit location specification.
	     Stop parsing and return whatever explicit location was
	     parsed.  */
	  *argp = start;
	  return location;
	}

      /* It's a little lame to error after the fact, but in this
	 case, it provides a much better user experience to issue
	 the "invalid argument" error before any missing
	 argument error.  */
      if (!have_oarg && !dont_throw)
	error (_("missing argument for \"%s\""), opt.get ());
    }

  /* One special error check:  If a source filename was given
     without offset, function, or label, issue an error.  */
  if (EL_EXPLICIT (location)->source_filename != NULL
      && EL_EXPLICIT (location)->function_name == NULL
      && EL_EXPLICIT (location)->label_name == NULL
      && (EL_EXPLICIT (location)->line_offset.sign == LINE_OFFSET_UNKNOWN)
      && !dont_throw)
    {
      error (_("Source filename requires function, label, or "
	       "line offset."));
    }

  return location;
}
Esempio n. 5
0
static int
aarch64_stap_parse_special_token (struct gdbarch *gdbarch,
				  struct stap_parse_info *p)
{
  if (*p->arg == '[')
    {
      /* Temporary holder for lookahead.  */
      const char *tmp = p->arg;
      char *endp;
      /* Used to save the register name.  */
      const char *start;
      char *regname;
      int len;
      int got_minus = 0;
      long displacement;
      struct stoken str;

      ++tmp;
      start = tmp;

      /* Register name.  */
      while (isalnum (*tmp))
	++tmp;

      if (*tmp != ',')
	return 0;

      len = tmp - start;
      regname = (char *) alloca (len + 2);

      strncpy (regname, start, len);
      regname[len] = '\0';

      if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
	error (_("Invalid register name `%s' on expression `%s'."),
	       regname, p->saved_arg);

      ++tmp;
      tmp = skip_spaces_const (tmp);
      /* Now we expect a number.  It can begin with '#' or simply
	 a digit.  */
      if (*tmp == '#')
	++tmp;

      if (*tmp == '-')
	{
	  ++tmp;
	  got_minus = 1;
	}
      else if (*tmp == '+')
	++tmp;

      if (!isdigit (*tmp))
	return 0;

      displacement = strtol (tmp, &endp, 10);
      tmp = endp;

      /* Skipping last `]'.  */
      if (*tmp++ != ']')
	return 0;

      /* The displacement.  */
      write_exp_elt_opcode (&p->pstate, OP_LONG);
      write_exp_elt_type (&p->pstate, builtin_type (gdbarch)->builtin_long);
      write_exp_elt_longcst (&p->pstate, displacement);
      write_exp_elt_opcode (&p->pstate, OP_LONG);
      if (got_minus)
	write_exp_elt_opcode (&p->pstate, UNOP_NEG);

      /* The register name.  */
      write_exp_elt_opcode (&p->pstate, OP_REGISTER);
      str.ptr = regname;
      str.length = len;
      write_exp_string (&p->pstate, str);
      write_exp_elt_opcode (&p->pstate, OP_REGISTER);

      write_exp_elt_opcode (&p->pstate, BINOP_ADD);

      /* Casting to the expected type.  */
      write_exp_elt_opcode (&p->pstate, UNOP_CAST);
      write_exp_elt_type (&p->pstate, lookup_pointer_type (p->arg_type));
      write_exp_elt_opcode (&p->pstate, UNOP_CAST);

      write_exp_elt_opcode (&p->pstate, UNOP_IND);

      p->arg = tmp;
    }
  else
    return 0;

  return 1;
}
Esempio n. 6
0
struct serial *
serial_open (const char *name)
{
  struct serial *scb;
  const struct serial_ops *ops;
  const char *open_name = name;

  if (strcmp (name, "pc") == 0)
    ops = serial_interface_lookup ("pc");
  else if (startswith (name, "lpt"))
    ops = serial_interface_lookup ("parallel");
  else if (startswith (name, "|"))
    {
      ops = serial_interface_lookup ("pipe");
      /* Discard ``|'' and any space before the command itself.  */
      ++open_name;
      open_name = skip_spaces_const (open_name);
    }
  /* Check for a colon, suggesting an IP address/port pair.
     Do this *after* checking for all the interesting prefixes.  We
     don't want to constrain the syntax of what can follow them.  */
  else if (strchr (name, ':'))
    ops = serial_interface_lookup ("tcp");
  else
    ops = serial_interface_lookup ("hardwire");

  if (!ops)
    return NULL;

  scb = XNEW (struct serial);

  scb->ops = ops;

  scb->bufcnt = 0;
  scb->bufp = scb->buf;
  scb->error_fd = -1;
  scb->refcnt = 1;

  /* `...->open (...)' would get expanded by the open(2) syscall macro.  */
  if ((*scb->ops->open) (scb, open_name))
    {
      xfree (scb);
      return NULL;
    }

  scb->name = xstrdup (name);
  scb->next = scb_base;
  scb->debug_p = 0;
  scb->async_state = 0;
  scb->async_handler = NULL;
  scb->async_context = NULL;
  scb_base = scb;

  if (serial_logfile != NULL)
    {
      serial_logfp = gdb_fopen (serial_logfile, "w");
      if (serial_logfp == NULL)
	perror_with_name (serial_logfile);
    }

  return scb;
}
Esempio n. 7
0
static int
arm_stap_parse_special_token (struct gdbarch *gdbarch,
			      struct stap_parse_info *p)
{
  if (*p->arg == '[')
    {
      /* Temporary holder for lookahead.  */
      const char *tmp = p->arg;
      char *endp;
      /* Used to save the register name.  */
      const char *start;
      char *regname;
      int len, offset;
      int got_minus = 0;
      long displacement;
      struct stoken str;

      ++tmp;
      start = tmp;

      /* Register name.  */
      while (isalnum (*tmp))
	++tmp;

      if (*tmp != ',')
	return 0;

      len = tmp - start;
      regname = alloca (len + 2);

      offset = 0;
      if (isdigit (*start))
	{
	  /* If we are dealing with a register whose name begins with a
	     digit, it means we should prefix the name with the letter
	     `r', because GDB expects this name pattern.  Otherwise (e.g.,
	     we are dealing with the register `fp'), we don't need to
	     add such a prefix.  */
	  regname[0] = 'r';
	  offset = 1;
	}

      strncpy (regname + offset, start, len);
      len += offset;
      regname[len] = '\0';

      if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
	error (_("Invalid register name `%s' on expression `%s'."),
	       regname, p->saved_arg);

      ++tmp;
      tmp = skip_spaces_const (tmp);
      if (*tmp++ != '#')
	return 0;

      if (*tmp == '-')
	{
	  ++tmp;
	  got_minus = 1;
	}

      displacement = strtol (tmp, &endp, 10);
      tmp = endp;

      /* Skipping last `]'.  */
      if (*tmp++ != ']')
	return 0;

      /* The displacement.  */
      write_exp_elt_opcode (OP_LONG);
      write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
      write_exp_elt_longcst (displacement);
      write_exp_elt_opcode (OP_LONG);
      if (got_minus)
	write_exp_elt_opcode (UNOP_NEG);

      /* The register name.  */
      write_exp_elt_opcode (OP_REGISTER);
      str.ptr = regname;
      str.length = len;
      write_exp_string (str);
      write_exp_elt_opcode (OP_REGISTER);

      write_exp_elt_opcode (BINOP_ADD);

      /* Casting to the expected type.  */
      write_exp_elt_opcode (UNOP_CAST);
      write_exp_elt_type (lookup_pointer_type (p->arg_type));
      write_exp_elt_opcode (UNOP_CAST);

      write_exp_elt_opcode (UNOP_IND);

      p->arg = tmp;
    }
  else
    return 0;

  return 1;
}
Esempio n. 8
0
int
get_number_trailer (const char **pp, int trailer)
{
  int retval = 0;	/* default */
  const char *p = *pp;

  if (*p == '$')
    {
      struct value *val = value_from_history_ref (p, &p);

      if (val)	/* Value history reference */
	{
	  if (TYPE_CODE (value_type (val)) == TYPE_CODE_INT)
	    retval = value_as_long (val);
	  else
	    {
	      printf_filtered (_("History value must have integer type.\n"));
	      retval = 0;
	    }
	}
      else	/* Convenience variable */
	{
	  /* Internal variable.  Make a copy of the name, so we can
	     null-terminate it to pass to lookup_internalvar().  */
	  char *varname;
	  const char *start = ++p;
	  LONGEST val;

	  while (isalnum (*p) || *p == '_')
	    p++;
	  varname = (char *) alloca (p - start + 1);
	  strncpy (varname, start, p - start);
	  varname[p - start] = '\0';
	  if (get_internalvar_integer (lookup_internalvar (varname), &val))
	    retval = (int) val;
	  else
	    {
	      printf_filtered (_("Convenience variable must "
				 "have integer value.\n"));
	      retval = 0;
	    }
	}
    }
  else
    {
      if (*p == '-')
	++p;
      while (*p >= '0' && *p <= '9')
	++p;
      if (p == *pp)
	/* There is no number here.  (e.g. "cond a == b").  */
	{
	  /* Skip non-numeric token.  */
	  while (*p && !isspace((int) *p))
	    ++p;
	  /* Return zero, which caller must interpret as error.  */
	  retval = 0;
	}
      else
	retval = atoi (*pp);
    }
  if (!(isspace (*p) || *p == '\0' || *p == trailer))
    {
      /* Trailing junk: return 0 and let caller print error msg.  */
      while (!(isspace (*p) || *p == '\0' || *p == trailer))
	++p;
      retval = 0;
    }
  p = skip_spaces_const (p);
  *pp = p;
  return retval;
}
Esempio n. 9
0
static int
get_tid_or_range (struct tid_range_parser *parser, int *inf_num,
		  int *thr_start, int *thr_end)
{
  if (parser->state == TID_RANGE_STATE_INFERIOR)
    {
      const char *p;
      const char *space;

      space = skip_to_space (parser->string);

      p = parser->string;
      while (p < space && *p != '.')
	p++;
      if (p < space)
	{
	  const char *dot = p;

	  /* Parse number to the left of the dot.  */
	  p = parser->string;
	  parser->inf_num
	    = get_positive_number_trailer (&p, '.', parser->string);
	  if (parser->inf_num == 0)
	    return 0;

	  parser->qualified = 1;
	  p = dot + 1;

	  if (isspace (*p))
	    return 0;
	}
      else
	{
	  parser->inf_num = parser->default_inferior;
	  parser->qualified = 0;
	  p = parser->string;
	}

      init_number_or_range (&parser->range_parser, p);
      if (p[0] == '*' && (p[1] == '\0' || isspace (p[1])))
	{
	  /* Setup the number range parser to return numbers in the
	     whole [1,INT_MAX] range.  */
	  number_range_setup_range (&parser->range_parser, 1, INT_MAX,
				    skip_spaces_const (p + 1));
	  parser->state = TID_RANGE_STATE_STAR_RANGE;
	}
      else
	parser->state = TID_RANGE_STATE_THREAD_RANGE;
    }

  *inf_num = parser->inf_num;
  *thr_start = get_number_or_range (&parser->range_parser);
  if (*thr_start < 0)
    error (_("negative value: %s"), parser->string);
  if (*thr_start == 0)
    {
      parser->state = TID_RANGE_STATE_INFERIOR;
      return 0;
    }

  /* If we successfully parsed a thread number or finished parsing a
     thread range, switch back to assuming the next TID is
     inferior-qualified.  */
  if (parser->range_parser.end_ptr == NULL
      || parser->range_parser.string == parser->range_parser.end_ptr)
    {
      parser->state = TID_RANGE_STATE_INFERIOR;
      parser->string = parser->range_parser.string;

      if (thr_end != NULL)
	*thr_end = *thr_start;
    }

  /* If we're midway through a range, and the caller wants the end
     value, return it and skip to the end of the range.  */
  if (thr_end != NULL
      && (parser->state == TID_RANGE_STATE_THREAD_RANGE
	  || parser->state == TID_RANGE_STATE_STAR_RANGE))
    {
      *thr_end = parser->range_parser.end_value;
      tid_range_parser_skip (parser);
    }

  return (*inf_num != 0 && *thr_start != 0);
}
Esempio n. 10
0
static void
parse_find_args (char *args, ULONGEST *max_countp,
		 gdb_byte **pattern_bufp, ULONGEST *pattern_lenp,
		 CORE_ADDR *start_addrp, ULONGEST *search_space_lenp,
		 bfd_boolean big_p)
{
  /* Default to using the specified type.  */
  char size = '\0';
  ULONGEST max_count = ~(ULONGEST) 0;
  /* Buffer to hold the search pattern.  */
  gdb_byte *pattern_buf;
  /* Current size of search pattern buffer.
     We realloc space as needed.  */
#define INITIAL_PATTERN_BUF_SIZE 100
  ULONGEST pattern_buf_size = INITIAL_PATTERN_BUF_SIZE;
  /* Pointer to one past the last in-use part of pattern_buf.  */
  gdb_byte *pattern_buf_end;
  ULONGEST pattern_len;
  CORE_ADDR start_addr;
  ULONGEST search_space_len;
  const char *s = args;
  struct cleanup *old_cleanups;
  struct value *v;

  if (args == NULL)
    error (_("Missing search parameters."));

  pattern_buf = xmalloc (pattern_buf_size);
  pattern_buf_end = pattern_buf;
  old_cleanups = make_cleanup (free_current_contents, &pattern_buf);

  /* Get search granularity and/or max count if specified.
     They may be specified in either order, together or separately.  */

  while (*s == '/')
    {
      ++s;

      while (*s != '\0' && *s != '/' && !isspace (*s))
	{
	  if (isdigit (*s))
	    {
	      max_count = atoi (s);
	      while (isdigit (*s))
		++s;
	      continue;
	    }

	  switch (*s)
	    {
	    case 'b':
	    case 'h':
	    case 'w':
	    case 'g':
	      size = *s++;
	      break;
	    default:
	      error (_("Invalid size granularity."));
	    }
	}

      s = skip_spaces_const (s);
    }

  /* Get the search range.  */

  v = parse_to_comma_and_eval (&s);
  start_addr = value_as_address (v);

  if (*s == ',')
    ++s;
  s = skip_spaces_const (s);

  if (*s == '+')
    {
      LONGEST len;

      ++s;
      v = parse_to_comma_and_eval (&s);
      len = value_as_long (v);
      if (len == 0)
	{
	  do_cleanups (old_cleanups);
	  printf_filtered (_("Empty search range.\n"));
	  return;
	}
      if (len < 0)
	error (_("Invalid length."));
      /* Watch for overflows.  */
      if (len > CORE_ADDR_MAX
	  || (start_addr + len - 1) < start_addr)
	error (_("Search space too large."));
      search_space_len = len;
    }
  else
    {
      CORE_ADDR end_addr;

      v = parse_to_comma_and_eval (&s);
      end_addr = value_as_address (v);
      if (start_addr > end_addr)
	error (_("Invalid search space, end precedes start."));
      search_space_len = end_addr - start_addr + 1;
      /* We don't support searching all of memory
	 (i.e. start=0, end = 0xff..ff).
	 Bail to avoid overflows later on.  */
      if (search_space_len == 0)
	error (_("Overflow in address range "
		 "computation, choose smaller range."));
    }

  if (*s == ',')
    ++s;

  /* Fetch the search string.  */

  while (*s != '\0')
    {
      LONGEST x;
      struct type *t;
      ULONGEST pattern_buf_size_need;

      s = skip_spaces_const (s);

      v = parse_to_comma_and_eval (&s);
      t = value_type (v);

      /* Keep it simple and assume size == 'g' when watching for when we
	 need to grow the pattern buf.  */
      pattern_buf_size_need = (pattern_buf_end - pattern_buf
			       + max (TYPE_LENGTH (t), sizeof (int64_t)));
      if (pattern_buf_size_need > pattern_buf_size)
	{
	  size_t current_offset = pattern_buf_end - pattern_buf;

	  pattern_buf_size = pattern_buf_size_need * 2;
	  pattern_buf = xrealloc (pattern_buf, pattern_buf_size);
	  pattern_buf_end = pattern_buf + current_offset;
	}

      if (size != '\0')
	{
	  x = value_as_long (v);
	  switch (size)
	    {
	    case 'b':
	      *pattern_buf_end++ = x;
	      break;
	    case 'h':
	      put_bits (x, pattern_buf_end, 16, big_p);
	      pattern_buf_end += sizeof (int16_t);
	      break;
	    case 'w':
	      put_bits (x, pattern_buf_end, 32, big_p);
	      pattern_buf_end += sizeof (int32_t);
	      break;
	    case 'g':
	      put_bits (x, pattern_buf_end, 64, big_p);
	      pattern_buf_end += sizeof (int64_t);
	      break;
	    }
	}
      else
	{
	  memcpy (pattern_buf_end, value_contents (v), TYPE_LENGTH (t));
	  pattern_buf_end += TYPE_LENGTH (t);
	}

      if (*s == ',')
	++s;
      s = skip_spaces_const (s);
    }

  if (pattern_buf_end == pattern_buf)
    error (_("Missing search pattern."));

  pattern_len = pattern_buf_end - pattern_buf;

  if (search_space_len < pattern_len)
    error (_("Search space too small to contain pattern."));

  *max_countp = max_count;
  *pattern_bufp = pattern_buf;
  *pattern_lenp = pattern_len;
  *start_addrp = start_addr;
  *search_space_lenp = search_space_len;

  /* We successfully parsed the arguments, leave the freeing of PATTERN_BUF
     to the caller now.  */
  discard_cleanups (old_cleanups);
}