예제 #1
0
psim_tree(void)
{
    device *root = tree_parse(NULL, "core");
    tree_parse(root, "/aliases");
    tree_parse(root, "/options");
    tree_parse(root, "/chosen");
    tree_parse(root, "/packages");
    tree_parse(root, "/cpus");
    tree_parse(root, "/openprom");
    tree_parse(root, "/openprom/init");
    tree_parse(root, "/openprom/trace");
    tree_parse(root, "/openprom/options");
    return root;
}
예제 #2
0
파일: emul_generic.c 프로젝트: 5kg/gdb
INLINE_EMUL_GENERIC void
emul_add_tree_hardware(device *root)
{
  int i;
  int nr_cpus = tree_find_integer_property(root, "/openprom/options/smp");

  /* sanity check the number of processors */
  if (nr_cpus > MAX_NR_PROCESSORS)
    error("Specified number of processors (%d) exceeds the number configured (%d).\n",
	  nr_cpus, MAX_NR_PROCESSORS);

  /* set the number of address cells (1 or 2) */
  tree_parse(root, "#address-cells %d", WITH_TARGET_WORD_BITSIZE / 32);

  /* add some memory */
  if (tree_find_device(root, "/memory") == NULL) {
    unsigned_word memory_size =
      tree_find_integer_property(root, "/openprom/options/oea-memory-size");
    const unsigned_word avail_start = 0x3000;
    tree_parse(root, "/memory@0/reg 0x0 0x%lx",
	       (unsigned long)memory_size);
    /* reserve the first 0x3000 for the PowerPC interrupt table */
    tree_parse(root, "/memory@0/available 0x%lx  0x%lx",
	       (unsigned long)avail_start,
	       (unsigned long)memory_size - avail_start);
  }

  /* our processors */
  for (i = 0; i < nr_cpus; i++) {
    tree_parse(root, "/cpus/cpu@%d/cpu-nr %d", i, i);
  }

  /* the debugging pal - hide it in the openprom and don't attach it
     to any bus */
  tree_parse(root, "/openprom/pal");

  /* chosen etc */
  tree_parse(root, "/chosen/stdin */openprom/pal");
  tree_parse(root, "/chosen/stdout !/chosen/stdin");
  tree_parse(root, "/chosen/memory */memory");
}
예제 #3
0
static void
create_ppc_chirp_bootargs(device *me,
			  char **argv)
{
  /* concat the arguments */
  char args[1024];
  char **chp = argv + 1;
  args[0] = '\0';
  while (*chp != NULL) {
    if (strlen(args) > 0)
      strcat(args, " ");
    if (strlen(args) + strlen(*chp) >= sizeof(args))
      device_error(me, "buffer overflow");
    strcat(args, *chp);
    chp++;
  }

  /* set the arguments property */
  tree_parse(me, "/chosen/bootargs \"%s", args);
}
예제 #4
0
파일: emul_netbsd.c 프로젝트: 5kg/gdb
static os_emul_data *
emul_netbsd_create(device *root,
		   bfd *image,
		   const char *name)
{
  unsigned_word top_of_stack;
  unsigned stack_size;
  int elf_binary;
  os_emul_data *bsd_data;
  device *vm;
  char *filename;

  /* check that this emulation is really for us */
  if (name != NULL && strcmp(name, "netbsd") != 0)
    return NULL;
  if (image == NULL)
    return NULL;


  /* merge any emulation specific entries into the device tree */

  /* establish a few defaults */
  if (image->xvec->flavour == bfd_target_elf_flavour) {
    elf_binary = 1;
    top_of_stack = 0xe0000000;
    stack_size =   0x00100000;
  }
  else {
    elf_binary = 0;
    top_of_stack = 0x20000000;
    stack_size =   0x00100000;
  }

  /* options */
  emul_add_tree_options(root, image, "netbsd",
			(WITH_ENVIRONMENT == USER_ENVIRONMENT
			 ? "user" : "virtual"),
			0 /*oea-interrupt-prefix*/);

  /* virtual memory - handles growth of stack/heap */
  vm = tree_parse(root, "/openprom/vm");
  tree_parse(vm, "./stack-base 0x%lx",
	     (unsigned long)(top_of_stack - stack_size));
  tree_parse(vm, "./nr-bytes 0x%x", stack_size);

  filename = tree_quote_property (bfd_get_filename(image));
  tree_parse(root, "/openprom/vm/map-binary/file-name %s",
	     filename);
  free (filename);

  /* finish the init */
  tree_parse(root, "/openprom/init/register/pc 0x%lx",
	     (unsigned long)bfd_get_start_address(image));
  tree_parse(root, "/openprom/init/register/sp 0x%lx",
	     (unsigned long)top_of_stack);
  tree_parse(root, "/openprom/init/register/msr 0x%x",
	     ((tree_find_boolean_property(root, "/options/little-endian?")
	       ? msr_little_endian_mode
	       : 0)
	      | (tree_find_boolean_property(root, "/openprom/options/floating-point?")
		 ? (msr_floating_point_available
		    | msr_floating_point_exception_mode_0
		    | msr_floating_point_exception_mode_1)
		 : 0)));
  tree_parse(root, "/openprom/init/stack/stack-type %s",
	     (elf_binary ? "ppc-elf" : "ppc-xcoff"));

  /* finally our emulation data */
  bsd_data = ZALLOC(os_emul_data);
  bsd_data->vm = vm;
  bsd_data->syscalls = &emul_netbsd_syscalls;
  return bsd_data;
}
예제 #5
0
/*
 * parse a buffer.
 *
 * NOTE: parse() should not be called recusively by any other functions!
 */
int parse(aClient *cptr, char *pbuffer, char *bufend)
{
  aClient *from = cptr;
  char  *ch;
  char  *s;
  size_t i;
  char* numeric = 0;
  unsigned int paramcount;
  struct Message *mptr;

  Debug((DEBUG_DEBUG, "Parsing %s: %s",
         get_client_name(cptr, TRUE), pbuffer));

  if (IsDead(cptr))
    return -1;

  s = sender;
  *s = '\0';

  for (ch = pbuffer; *ch == ' '; ch++)   /* skip spaces */
    /* null statement */ ;

  para[0] = from->name;
  if (*ch == ':')
    {
      ch++;

      /*
      ** Copy the prefix to 'sender' assuming it terminates
      ** with SPACE (or NULL, which is an error, though).
      */
      for (i = 0; *ch && *ch != ' '; i++ )
	{
	  if (i < (sizeof(sender)-1))
	    *s++ = *ch; /* leave room for NULL */
	  ch++;
	}
      *s = '\0';
      i = 0;

      /*
      ** Actually, only messages coming from servers can have
      ** the prefix--prefix silently ignored, if coming from
      ** a user client...
      **
      ** ...sigh, the current release "v2.2PL1" generates also
      ** null prefixes, at least to NOTIFY messages (e.g. it
      ** puts "sptr->nickname" as prefix from server structures
      ** where it's null--the following will handle this case
      ** as "no prefix" at all --msa  (": NOTICE nick ...")
      */
      if (*sender && IsServer(cptr))
        {
          from = find_client(sender, (aClient *) NULL);
          if (!from || !match(from->name, sender))
            from = find_server(sender);

          para[0] = sender;
          
          /* Hmm! If the client corresponding to the
           * prefix is not found--what is the correct
           * action??? Now, I will ignore the message
           * (old IRC just let it through as if the
           * prefix just wasn't there...) --msa
           */
          if (!from)
            {
	      sendto_ops_flag_butone(cptr, UMODE_DEBUG, "Unknown prefix (%s) from (%s)",
				     sender, cptr->name);
              Debug((DEBUG_ERROR, "Unknown prefix (%s)(%s) from (%s)",
                     sender, pbuffer, cptr->name));
              ServerStats->is_unpf++;

              remove_unknown(cptr, sender, pbuffer);

              return -1;
            }
          if (from->from != cptr)
            {
              ServerStats->is_wrdi++;
              Debug((DEBUG_ERROR, "Message (%s) coming from (%s)",
                     buffer, cptr->name));
	      sendto_ops_flag_butone(cptr, UMODE_DEBUG, "Message coming from (%s), but %s is at %s",
				     cptr->name, from->name, from->from->name);

              return cancel_clients(cptr, from, pbuffer);
            }
        }
      while (*ch == ' ')
        ch++;
    }

  if (*ch == '\0')
    {
      ServerStats->is_empt++;
      Debug((DEBUG_NOTICE, "Empty message from host %s:%s",
             cptr->name, from->name));
      if (IsServer(cptr))
	sendto_ops_flag_butone(cptr, UMODE_DEBUG, "Empty message from %s:%s",
			       cptr->name, from->name);
      return(-1);
    }

  /*
  ** Extract the command code from the packet.  Point s to the end
  ** of the command code and calculate the length using pointer
  ** arithmetic.  Note: only need length for numerics and *all*
  ** numerics must have parameters and thus a space after the command
  ** code. -avalon
  *
  * ummm???? - Dianora
  */

  if( *(ch + 3) == ' ' && /* ok, lets see if its a possible numeric.. */
      IsDigit(*ch) && IsDigit(*(ch + 1)) && IsDigit(*(ch + 2)) )
    {
      mptr = (struct Message *)NULL;
      numeric = ch;
      paramcount = MAXPARA;
      ServerStats->is_num++;
      s = ch + 3;       /* I know this is ' ' from above if */
      *s++ = '\0';      /* blow away the ' ', and point s to next part */
    }
  else
    {
      s = strchr(ch, ' ');      /* moved from above,now need it here */
      if (s)
        *s++ = '\0';

      mptr = tree_parse(ch);

      if (!mptr || !mptr->cmd)
        {
          /*
           * Note: Give error message *only* to recognized
           * persons. It's a nightmare situation to have
           * two programs sending "Unknown command"'s or
           * equivalent to each other at full blast....
           * If it has got to person state, it at least
           * seems to be well behaving. Perhaps this message
           * should never be generated, though...  --msa
           * Hm, when is the buffer empty -- if a command
           * code has been found ?? -Armin
	   *
	   * Same thing goes for remote commands. If their local
	   * server accepted it, then we should not be sending
	   * a warning message.
	   */
          if (pbuffer[0] != '\0')
            {
              if (IsPerson(from) && MyClient(from))
                sendto_one(from,
                           ":%s %d %s %s :Unknown command",
                           me.name, ERR_UNKNOWNCOMMAND,
                           from->name, ch);
              Debug((DEBUG_ERROR,"Unknown (%s) from %s",
                     ch, get_client_name(cptr, TRUE)));
            }
          ServerStats->is_unco++;
          return(-1);
        }

      paramcount = mptr->parameters;
      i = bufend - ((s) ? s : ch);
      mptr->bytes += i;

      /* Allow only 1 msg per 2 seconds
       * (on average) to prevent dumping.
       * to keep the response rate up,
       * bursts of up to 5 msgs are allowed
       * -SRB
       * Opers can send 1 msg per second, burst of ~20
       * -Taner
       */
      if ((mptr->flags & 1) && !(IsServer(cptr)))
        {
#ifdef NO_OPER_FLOOD
#ifndef TRUE_NO_OPER_FLOOD
	  /* note: both have to be defined for the real no-flood */
          if (NoFloodProtection(cptr))
            /* "randomly" (weighted) increase the since */
            cptr->since += (cptr->receiveM % 5) ? 1 : 0;
          else
#else
          if (!NoFloodProtection(cptr))
#endif
#endif
            cptr->since += (2 + i / 120);
        }
    }
  /*
  ** Must the following loop really be so devious? On
  ** surface it splits the message to parameters from
  ** blank spaces. But, if paramcount has been reached,
  ** the rest of the message goes into this last parameter
  ** (about same effect as ":" has...) --msa
  */

  /* Note initially true: s==NULL || *(s-1) == '\0' !! */

  /* ZZZ hmmmmmmmm whats this then? */
#if 0
  if (me.user)
    para[0] = sender;
#endif

  i = 1;

  if (s)
    {
      if (paramcount > MAXPARA)
        paramcount = MAXPARA;

      for (;;)
        {
	  while(*s == ' ')	/* tabs are not considered space */
	    *s++ = '\0';

          if(!*s)
            break;

          if (*s == ':')
            {
              /*
              ** The rest is single parameter--can
              ** include blanks also.
              */
              para[i++] = s + 1;
              break;
            }
	  else
	    {
	      para[i++] = s;
              if (i > paramcount)
                {
                  break;
                }
              /* scan for end of string, either ' ' or '\0' */
              while (IsNonEOS(*s))
                s++;
	    }
        }
    }

  para[i] = NULL;
  if (mptr == (struct Message *)NULL)
    return (do_numeric(numeric, cptr, from, i, para));

  mptr->count++;

  /* patch to avoid server flooding from unregistered connects */
  /* check allow_unregistered_use flag I've set up instead of function
     comparing *yech* - Dianora */

  if (!IsRegistered(cptr) && !mptr->allow_unregistered_use )
    {
      /* if its from a possible server connection
       * ignore it.. more than likely its a header thats sneaked through
       */

      if(IsHandshake(cptr) || IsConnecting(cptr) || IsServer(cptr))
        return -1;

      sendto_one(from,
                 ":%s %d %s %s :Register first.",
                 me.name, ERR_NOTREGISTERED,
                 BadPtr(from->name) ? "*" : from->name, ch);
      return -1;
    }

  /* Silently drop the messages that can't be used in the honeypot */
  if (IsHoneypot(cptr) && !mptr->allow_honeypot)
    return -1;

  /* Again, instead of function address comparing, see if
   * this function resets idle time as given from mptr
   * if IDLE_FROM_MSG is undefined, the sense of the flag is reversed.
   * i.e. if the flag is 0, then reset idle time, otherwise don't reset it.
   *
   * - Dianora
   */

  if (IsRegisteredUser(from) && mptr->reset_idle)
    {
      /* If a local registered user, propagate anti-idle updates as needed */
      if (MyClient(from) && from->user && ((from->user->last_sent + MAX_IDLE_DESYNC) < CurrentTime))
	{
#if 0
	  /* Note the misnamed message, this indicates that they are NOT idle */
#ifdef HAVE_LONG_LONG
	  sendto_serv_butone(NULL, ":%s IDLE %s %.1lld", cptr->name, from->name, (long long)CurrentTime);
#else
	  sendto_serv_butone(NULL, ":%s IDLE %s %.1ld", cptr->name, from->name, (long)CurrentTime);
#endif
#endif
	  from->user->last_sent = CurrentTime;
	}
      from->user->last = CurrentTime;
    }

  /* don't allow other commands while a list is blocked. since we treat
     them specially with respect to sendq. */
  if ((IsDoingList(cptr)) && (*mptr->func != m_list))
      return -1;
  return (*mptr->func)(cptr, from, i, para);
}
예제 #6
0
int parse(aClient *cptr, char *buffer, char *bufend)
{
    aClient *from = cptr;
    char *ch, *s;
    int i, numeric = 0, paramcount;
    struct Message *mptr;

#ifdef DUMP_DEBUG
    if(dumpfp!=NULL) 
    {
	fprintf(dumpfp, "<- %s: %s\n", (cptr->name ? cptr->name : "*"),
		buffer);
	fflush(dumpfp);
    }
#endif
    Debug((DEBUG_DEBUG, "Parsing %s: %s", get_client_name(cptr, TRUE),
	   buffer));
    
    if (IsDead(cptr))
	return -1;
    
    s = sender;
    *s = '\0';
    
    for (ch = buffer; *ch == ' '; ch++);	/* skip spaces */
    
    para[0] = from->name;
    if (*ch == ':') 
    {
	/*
	 * Copy the prefix to 'sender' assuming it terminates with
	 * SPACE (or NULL, which is an error, though).
	 */
	
	for (++ch; *ch && *ch != ' '; ++ch)
	    if (s < (sender + HOSTLEN))
		*s++ = *ch;		
	*s = '\0';
	
	/*
	 * Actually, only messages coming from servers can have the
	 * prefix--prefix silently ignored, if coming from a user
	 * client...
	 * 
	 * ...sigh, the current release "v2.2PL1" generates also null
	 * prefixes, at least to NOTIFY messages (e.g. it puts
	 * "sptr->nickname" as prefix from server structures where it's
	 * null--the following will handle this case as "no prefix" at
	 * all --msa  (": NOTICE nick ...")
	 */
	
	if (*sender && IsServer(cptr)) 
	{
	    from = find_client(sender, (aClient *) NULL);

	    /*
	     * okay, this doesn't seem to do much here.
	     * from->name _MUST_ be equal to sender. 
	     * That's what find_client does.
	     * find_client will find servers too, and since we don't use server
	     * masking, the find server call is useless (and very wasteful).
	     * now, there HAS to be a from and from->name and
	     * sender have to be the same
	     * for us to get to the next if. but the next if
	     * starts out with if(!from)
	     * so this is UNREACHABLE CODE! AGH! - lucas
	     *
	     *  if (!from || mycmp(from->name, sender))
	     *     from = find_server(sender, (aClient *) NULL);
	     *  else if (!from && strchr(sender, '@'))
	     *     from = find_nickserv(sender, (aClient *) NULL);
	     */

	    para[0] = sender;
	    /*
	     * Hmm! If the client corresponding to the prefix is not
	     * found--what is the correct action??? Now, I will ignore the
	     * message (old IRC just let it through as if the prefix just
	     * wasn't there...) --msa
	     */
	    if (!from) 
	    {
		Debug((DEBUG_ERROR, "Unknown prefix (%s)(%s) from (%s)",
		       sender, buffer, cptr->name));

		ircstp->is_unpf++;
		remove_unknown(cptr, sender, buffer);
		 
		return -1;
	    }

	    if (from->from != cptr) 
	    {
		ircstp->is_wrdi++;
		Debug((DEBUG_ERROR, "Message (%s) coming from (%s)",
		       buffer, cptr->name));
		
		return cancel_clients(cptr, from, buffer);
	    }
	}
	while (*ch == ' ')
	    ch++;
    }

    if (*ch == '\0') 
    {
	ircstp->is_empt++;
	Debug((DEBUG_NOTICE, "Empty message from host %s:%s",
	       cptr->name, from->name));
	return (-1);
    }
    /*
     * Extract the command code from the packet.  Point s to the end
     * of the command code and calculate the length using pointer
     * arithmetic.  Note: only need length for numerics and *all*
     * numerics must have parameters and thus a space after the command
     * code. -avalon
     * 
     * ummm???? - Dianora
     */

  /* Reparse point for /msg raw - Tux` */
	reparse: 

    /* check for numeric */
    if (*(ch + 3) == ' ' && IsDigit(*ch) && IsDigit(*(ch + 1)) &&
	IsDigit(*(ch + 2))) 
    {
	mptr = (struct Message *) NULL;
	numeric = (*ch - '0') * 100 + (*(ch + 1) - '0') *
	    10 + (*(ch + 2) - '0');
	paramcount = MAXPARA;
	ircstp->is_num++;
	s = ch + 3;
	*s++ = '\0';
    }
    else 
    {
	s = strchr(ch, ' ');
	
	if (s)
	    *s++ = '\0';
	
	mptr = tree_parse(ch);
	
	if ((mptr && mptr->func == m_private) && 
		(s && !strncasecmp(s, "raw ", 4)))
	{
		ch = index(s, ':');
		if (ch++)
			goto reparse;
	}
	else if (!mptr || !mptr->cmd) 
	{
	    /*
	     * only send error messages to things that actually sent
	     * buffers to us and only people, too.
	     */
	    if (buffer[0] != '\0') 
	    {
		if (IsPerson(from))
		    sendto_one(from, ":%s %d %s %s :Unknown command",
			       me.name, ERR_UNKNOWNCOMMAND, from->name, ch);
		Debug((DEBUG_ERROR, "Unknown (%s) from %s",
		       ch, get_client_name(cptr, TRUE)));
	    }
	    ircstp->is_unco++;
	    return -1;
	}
	
	paramcount = mptr->parameters;
	i = bufend - ((s) ? s : ch);
	mptr->bytes += i;
	/*
	 * Allow only 1 msg per 2 seconds (on average) to prevent
	 * dumping. to keep the response rate up, bursts of up to 5 msgs
	 * are allowed -SRB Opers can send 1 msg per second, burst of ~20
	 * -Taner
	 */
	if (!IsServer(cptr)) 
	{
        if (!NoMsgThrottle(cptr))
        {
#ifdef NO_OPER_FLOOD
            if (IsAnOper(cptr))
                /* "randomly" (weighted) increase the since */
                cptr->since += (cptr->receiveM % 10) ? 1 : 0;
            else
#endif
                cptr->since += (2 + i / 120);
        }
    }
    }
    /*
     * Must the following loop really be so devious? On surface it
     * splits the message to parameters from blank spaces. But, if
     * paramcount has been reached, the rest of the message goes into
     * this last parameter (about same effect as ":" has...) --msa
     */

    /* Note initially true: s==NULL || *(s-1) == '\0' !! */
    
    i = 1;
    if (s) 
    {
	if (paramcount > MAXPARA)
	    paramcount = MAXPARA;
	for (;;) 
	{
	    while (*s == ' ')
		*s++ = '\0';
	    
	    if (*s == '\0')
		break;
	    if (*s == ':') 
	    {
		/* The rest is a single parameter */
		para[i++] = s + 1;
		break;
	    }
	    para[i++] = s;
	    if (i >= paramcount)
            {
                if(paramcount == MAXPARA && strchr(s, ' '))
                {
                   sendto_realops_lev(DEBUG_LEV, "Overflowed MAXPARA on %s from %s",
			   mptr ? mptr->cmd : "numeric",
			   get_client_name(cptr, (IsServer(cptr) ? HIDEME : FALSE)));
                }
		break;
            }
	    
	    while(*s && *s != ' ')
		s++;
	}
    }
    
    para[i] = NULL;
    if (mptr == (struct Message *) NULL)
	return (do_numeric(numeric, cptr, from, i, para));
    
    mptr->count++;
    
    /* patch to avoid server flooding from unregistered connects */
    
    if (!IsRegistered(cptr) && !(mptr->flags & MF_UNREG)) {
	sendto_one(from, ":%s %d %s %s :Register first.",
		   me.name, ERR_NOTREGISTERED, from->name, ch);
	return -1;
    }
    
    if (IsRegisteredUser(cptr) && (mptr->flags & MF_RIDLE))
	from->user->last = timeofday;

    if (mptr->flags & MF_ALIAS)
         return mptr->func(cptr, from, i, para, &aliastab[mptr->aliasidx]);

    return (*mptr->func) (cptr, from, i, para);
}
예제 #7
0
파일: emul_generic.c 프로젝트: 5kg/gdb
INLINE_EMUL_GENERIC void
emul_add_tree_options(device *tree,
		      bfd *image,
		      const char *emul,
		      const char *env,
		      int oea_interrupt_prefix)
{
  int little_endian = 0;

  /* sort out little endian */
  if (tree_find_property(tree, "/options/little-endian?"))
    little_endian = tree_find_boolean_property(tree, "/options/little-endian?");
  else {
#ifdef bfd_little_endian	/* new bfd */
    little_endian = (image != NULL && bfd_little_endian(image));
#else
    little_endian = (image != NULL &&
		     !image->xvec->byteorder_big_p);
#endif
    tree_parse(tree, "/options/little-endian? %s",
	       little_endian ? "true" : "false");
  }

  /* misc other stuff */
  tree_parse(tree, "/openprom/options/oea-memory-size 0x%x",
	     OEA_MEMORY_SIZE);
  tree_parse(tree, "/openprom/options/oea-interrupt-prefix %d",
	     oea_interrupt_prefix);
  tree_parse(tree, "/openprom/options/smp 1");
  tree_parse(tree, "/openprom/options/env %s", env);
  tree_parse(tree, "/openprom/options/os-emul %s", emul);
  tree_parse(tree, "/openprom/options/strict-alignment? %s",
	     (WITH_ALIGNMENT == STRICT_ALIGNMENT)
	     ? "true" : "false");
  tree_parse(tree, "/openprom/options/floating-point? %s",
	     WITH_FLOATING_POINT ? "true" : "false");
  tree_parse(tree, "/openprom/options/use-stdio? %s",
	     ((WITH_STDIO == DO_USE_STDIO
	       || WITH_STDIO == 0)
	      ? "true" : "false"));
  tree_parse(tree, "/openprom/options/model \"%s",
	     model_name[WITH_DEFAULT_MODEL]);
  tree_parse(tree, "/openprom/options/model-issue %d",
	     MODEL_ISSUE_IGNORE);

  /* useful options */
}
static os_emul_data *
emul_bugapi_create(device *root,
		   bfd *image,
		   const char *name)
{
  device *node;
  os_emul_data *bugapi;
  char *filename;

  /* check it really is for us */
  if (name != NULL
      && strcmp(name, "bugapi") != 0
      && strcmp(name, "bug") != 0)
    return NULL;
  if (image != NULL
      && name == NULL
      && bfd_get_start_address(image) >= BUGAPI_END_ADDRESS)
    return NULL;

  bugapi = ZALLOC(os_emul_data);

  /* options */
  emul_add_tree_options(root, image, "bug", "oea",
			1 /*oea-interrupt-prefix*/);

  /* add some real hardware, include eeprom memory for the eeprom trap
     addresses */
  emul_add_tree_hardware(root);
  node = tree_parse(root, "/openprom/memory@0xfff00000");
  tree_parse(node, "./psim,description \"eeprom trap addresses");
  tree_parse(node, "./reg 0xfff00000 0x3000");

  bugapi->root = root;

  bugapi->memory_size
    = tree_find_integer_property(root, "/openprom/options/oea-memory-size");
  bugapi->interrupt_prefix =
    tree_find_integer_property(root, "/openprom/options/oea-interrupt-prefix");
  bugapi->interrupt_vector_address = (bugapi->interrupt_prefix
				      ? MASK(0, 43)
				      : 0);
  bugapi->system_call_address = (bugapi->interrupt_vector_address + 0x00c00);
  bugapi->stall_cpu_loop_address = (bugapi->system_call_address + 0x000f0);
  bugapi->top_of_stack = bugapi->memory_size - 0x1000;
  bugapi->little_endian
    = tree_find_boolean_property(root, "/options/little-endian?");
  bugapi->floating_point_available
    = tree_find_boolean_property(root, "/openprom/options/floating-point?");
  bugapi->input = NULL;
  bugapi->output = NULL;

  /* initialization */
  if (image != NULL)
    tree_parse(root, "/openprom/init/register/0.pc 0x%lx",
	       (unsigned long)bfd_get_start_address(image));
  tree_parse(root, "/openprom/init/register/pc 0x%lx",
	     (unsigned long)bugapi->stall_cpu_loop_address);
  tree_parse(root, "/openprom/init/register/sp 0x%lx",
	     (unsigned long)(bugapi->top_of_stack - 16));
  tree_parse(root, "/openprom/init/register/msr 0x%x",
	     (msr_recoverable_interrupt
	      | (bugapi->little_endian
		 ? (msr_little_endian_mode
		    | msr_interrupt_little_endian_mode)
		 : 0)
	      | (bugapi->floating_point_available
		 ? msr_floating_point_available
		 : 0)
	      | (bugapi->interrupt_prefix
		 ? msr_interrupt_prefix
		 : 0)
	      ));

  /* patch the system call instruction to call this emulation and then
     do an rfi */
  node = tree_parse(root, "/openprom/init/data@0x%lx",
		    (unsigned long)bugapi->system_call_address);
  tree_parse(node, "./psim,description \"system-call trap instruction");
  tree_parse(node, "./real-address 0x%lx",
	     (unsigned long)bugapi->system_call_address);
  tree_parse(node, "./data 0x%x", emul_call_instruction);
  node = tree_parse(root, "/openprom/init/data@0x%lx",
		    (unsigned long)bugapi->system_call_address + 4);
  tree_parse(node, "./psim,description \"return from interrupt instruction");
  tree_parse(node, "./real-address 0x%lx",
	     (unsigned long)bugapi->system_call_address + 4);
  tree_parse(node, "./data 0x%x",
	     emul_rfi_instruction);

  /* patch the end of the system call instruction so that it contains
     a loop to self instruction and point all the cpu's at this */
  node = tree_parse(root, "/openprom/init/data@0x%lx",
		    (unsigned long)bugapi->stall_cpu_loop_address);
  tree_parse(node, "./psim,description \"cpu-loop instruction");
  tree_parse(node, "./real-address 0x%lx",
	     (unsigned long)bugapi->stall_cpu_loop_address);
  tree_parse(node, "./data 0x%lx",
	     (unsigned long)emul_loop_instruction);

  if (image != NULL)
    tree_parse(root, "/openprom/init/stack/stack-type %s",
	       (image->xvec->flavour == bfd_target_elf_flavour
		? "ppc-elf"
		: "ppc-xcoff"));

  if (image != NULL)
    {
      filename = tree_quote_property (bfd_get_filename(image));
      tree_parse(root, "/openprom/init/load-binary/file-name %s",
		 filename);
      free (filename);
    }

  return bugapi;
}
예제 #9
0
psim_options(device *root,
             char **argv)
{
    device *current = root;
    int argp;
    if (argv == NULL)
        return NULL;
    argp = 0;
    while (argv[argp] != NULL && argv[argp][0] == '-') {
        char *p = argv[argp] + 1;
        char *param;
        while (*p != '\0') {
            switch (*p) {
            default:
                psim_usage(0);
                error ("");
                break;
            case 'c':
                param = find_arg("Missing <count> option for -c (max-iterations)\n", &argp, argv);
                tree_parse(root, "/openprom/options/max-iterations %s", param);
                break;
            case 'e':
                param = find_arg("Missing <emul> option for -e (os-emul)\n", &argp, argv);
                tree_parse(root, "/openprom/options/os-emul %s", param);
                break;
            case 'E':
                /* endian spec, ignored for now */
                param = find_arg("Missing <endian> option for -E (target-endian)\n", &argp, argv);
                if (strcmp (param, "big") == 0)
                    tree_parse (root, "/options/little-endian? false");
                else if (strcmp (param, "little") == 0)
                    tree_parse (root, "/options/little-endian? true");
                else
                {
                    printf_filtered ("Invalid <endian> option for -E (target-endian)\n");
                    psim_usage (0);
                }
                break;
            case 'f':
                param = find_arg("Missing <file> option for -f\n", &argp, argv);
                psim_merge_device_file(root, param);
                break;
            case 'h':
            case '?':
                psim_usage(1);
                break;
            case 'H':
                psim_usage(2);
                break;
            case 'i':
                if (isdigit(p[1])) {
                    tree_parse(root, "/openprom/trace/print-info %c", p[1]);
                    p++;
                }
                else {
                    tree_parse(root, "/openprom/trace/print-info 1");
                }
                break;
            case 'I':
                tree_parse(root, "/openprom/trace/print-info 2");
                tree_parse(root, "/openprom/options/model-issue %d",
                           MODEL_ISSUE_PROCESS);
                break;
            case 'm':
                param = find_arg("Missing <model> option for -m (model)\n", &argp, argv);
                tree_parse(root, "/openprom/options/model \"%s", param);
                break;
            case 'n':
                param = find_arg("Missing <nr-smp> option for -n (smp)\n", &argp, argv);
                tree_parse(root, "/openprom/options/smp %s", param);
                break;
            case 'o':
                param = find_arg("Missing <dev-spec> option for -o\n", &argp, argv);
                if (memcmp(param, "mpc860c0", 8) == 0)
                {
                    if (param[8] == '\0')
                        tree_parse(root, "/options/mpc860c0 5");
                    else if (param[8] == '=' && is_num(param+9, 1, 10, 0))
                    {
                        tree_parse(root, "/options/mpc860c0 %s", param+9);
                    }
                    else error("Invalid mpc860c0 option for -o\n");
                }
                else
                    current = tree_parse(current, "%s", param);
                break;
            case 'r':
                param = find_arg("Missing <ram-size> option for -r (oea-memory-size)\n", &argp, argv);
                tree_parse(root, "/openprom/options/oea-memory-size %s",
                           param);
                break;
            case 't':
                param = find_arg("Missing <trace> option for -t (trace/*)\n", &argp, argv);
                if (param[0] == '!')
                    tree_parse(root, "/openprom/trace/%s 0", param+1);
                else
                    tree_parse(root, "/openprom/trace/%s 1", param);
                break;
            case '-':
                /* it's a long option of the form --optionname=optionvalue.
                   Such options can be passed through if we are invoked by
                   gdb.  */
                if (strstr(argv[argp], "architecture") != NULL) {
                    /* we must consume the argument here, so that we get out
                       of the loop.  */
                    p = argv[argp] + strlen(argv[argp]) - 1;
                    printf_filtered("Warning - architecture parameter ignored\n");
                }
                else
                    error("Unrecognized option");
                break;
            }
            p += 1;
        }
        argp += 1;
    }
    /* force the trace node to process its options now *before* the tree
       initialization occures */
    device_ioctl(tree_find_device(root, "/openprom/trace"),
                 NULL, 0,
                 device_ioctl_set_trace);

    {
        void semantic_init(device* root);
        semantic_init(root);
    }

    /* return where the options end */
    return argv + argp;
}
예제 #10
0
void
build_tree(struct bu_list *br, struct region *rp)
{
    tree_parse(br, rp->reg_treetop);
}