示例#1
0
static gboolean
plugin_loader_free (GstPluginLoader * loader)
{
  GList *cur;
  gboolean got_plugin_details;

  fsync (loader->fd_w.fd);

  if (loader->child_running) {
    put_packet (loader, PACKET_EXIT, 0, NULL, 0);

    /* Swap packets with the child until it exits cleanly */
    while (!loader->rx_done) {
      if (exchange_packets (loader) || loader->rx_done)
        continue;

      if (!plugin_loader_replay_pending (loader))
        break;
      put_packet (loader, PACKET_EXIT, 0, NULL, 0);
    }

    plugin_loader_cleanup_child (loader);
  } else {
    close (loader->fd_w.fd);
    close (loader->fd_r.fd);
  }

  gst_poll_free (loader->fdset);

  g_free (loader->rx_buf);
  g_free (loader->tx_buf);

  if (loader->registry)
    gst_object_unref (loader->registry);

  got_plugin_details = loader->got_plugin_details;

  /* Free any pending plugin entries */
  cur = loader->pending_plugins;
  while (cur) {
    PendingPluginEntry *entry = (PendingPluginEntry *) (cur->data);
    g_free (entry->filename);
    g_slice_free (PendingPluginEntry, entry);

    cur = g_list_delete_link (cur, cur);
  }

  g_slice_free (GstPluginLoader, loader);

  return got_plugin_details;
}
示例#2
0
static void rsp_read_all_regs ( void )
{
  rsp_buf      buf;
  uint32_t     regbuf[MAX_GPRS];

  for ( int i = 0; i < MAX_GPRS; ++i )
  {
    dbg_cpu0_read_spr_e( SPR_GPR_BASE + i, &regbuf[i] );
    reg2hex( regbuf[i], &(buf.data[i * 8]) );
  }

  dbg_cpu0_read_spr_e( SPR_NPC, &regbuf[0] );
  dbg_cpu0_read_spr_e( SPR_SR , &regbuf[1] );
  // dbg_cpu0_read_spr_e( SPR_PPC, &regbuf[2] );  // The PPC register is not supported by the OR10 CPU.
  regbuf[2] = 0;

  // Note that reg2hex adds a NULL terminator; as such, they must be
  // put in buf.data in numerical order:  PPC, NPC, SR
  reg2hex( regbuf[2], &(buf.data[PPC_REGNUM * 8]) );
  reg2hex (regbuf[0], &(buf.data[NPC_REGNUM * 8]) );
  reg2hex (regbuf[1], &(buf.data[SR_REGNUM  * 8]) );

  //fprintf(stderr, "Read SPRs:  0x%08X, 0x%08X, 0x%08X\n", regbuf[0], regbuf[1], regbuf[2]);

  // Finalize the packet and send it.
  buf.data[NUM_REGS * 8] = 0;
  buf.len                = NUM_REGS * 8;
  put_packet( rsp.client_fd, &buf );
}
示例#3
0
void gdbstub_msg_write(const char *s, int len)
{
	char *bufptr;
	int wcount;
	int i;

	if (len == 0)
		len = strlen(s);

	/* 'O'utput */
	gdbmsgbuf[0] = 'O';

	/* Fill and send buffers... */
	while (len > 0) {
		bufptr = gdbmsgbuf + 1;

		/* Calculate how many this time */
		if ((len << 1) > (BUFMAX - 2))
			wcount = (BUFMAX - 2) >> 1;
		else
			wcount = len;

		/* Pack in hex chars */
		for (i = 0; i < wcount; i++)
			bufptr = pack_hex_byte(bufptr, s[i]);
		*bufptr = '\0';

		/* Move up */
		s += wcount;
		len -= wcount;

		/* Write packet */
		put_packet(gdbmsgbuf);
	}
示例#4
0
static gboolean
gst_plugin_loader_try_helper (GstPluginLoader * loader, gchar * location)
{
  char *argv[] = { location, (char *) "-l", NULL };

  GST_LOG ("Trying to spawn gst-plugin-scanner helper at %s", location);
  if (!g_spawn_async_with_pipes (NULL, argv, NULL,
          G_SPAWN_DO_NOT_REAP_CHILD /* | G_SPAWN_STDERR_TO_DEV_NULL */ ,
          NULL, NULL, &loader->child_pid, &loader->fd_w.fd, &loader->fd_r.fd,
          NULL, NULL))
    return FALSE;

  gst_poll_add_fd (loader->fdset, &loader->fd_w);
  gst_poll_add_fd (loader->fdset, &loader->fd_r);

  gst_poll_fd_ctl_read (loader->fdset, &loader->fd_r, TRUE);

  loader->tx_buf_write = loader->tx_buf_read = 0;

  put_packet (loader, PACKET_VERSION, 0, NULL, 0);
  if (!plugin_loader_sync_with_child (loader))
    return FALSE;

  loader->child_running = TRUE;

  return TRUE;
}
示例#5
0
Error PacketPeer::put_packet_buffer(const PoolVector<uint8_t> &p_buffer) {

	int len = p_buffer.size();
	if (len == 0)
		return OK;

	PoolVector<uint8_t>::Read r = p_buffer.read();
	return put_packet(&r[0], len);
}
示例#6
0
static gboolean
plugin_loader_sync_with_child (GstPluginLoader * l)
{
  put_packet (l, PACKET_SYNC, 0, NULL, 0);

  l->rx_got_sync = FALSE;
  while (!l->rx_got_sync) {
    if (!exchange_packets (l))
      return FALSE;
  }
  return TRUE;
}
示例#7
0
static void send_signal_reply_packet ( void )
{
  // In GDB jargon exceptions are called "signals" and have an associated signal ID.
  rsp_buf buf;

  buf.data[0] = 'S';
  buf.data[1] = get_hex_char( rsp.sigval >> 4 );
  buf.data[2] = get_hex_char( rsp.sigval % 16 );
  buf.data[3] = 0;
  buf.len     = strlen (buf.data);

  put_packet( rsp.client_fd, &buf );
}
示例#8
0
static gboolean
plugin_loader_load_and_sync (GstPluginLoader * l, PendingPluginEntry * entry)
{
  gint len;

  GST_DEBUG_OBJECT (l->registry, "Synchronously loading plugin file %s",
      entry->filename);

  len = strlen (entry->filename);
  put_packet (l, PACKET_LOAD_PLUGIN, entry->tag,
      (guint8 *) entry->filename, len + 1);

  return plugin_loader_sync_with_child (l);
}
示例#9
0
static gboolean
plugin_loader_replay_pending (GstPluginLoader * l)
{
  GList *cur, *next;

restart:
  if (!gst_plugin_loader_spawn (l))
    return FALSE;

  /* Load each plugin one by one synchronously until we find the
   * crashing one */
  while ((cur = l->pending_plugins)) {
    PendingPluginEntry *entry = (PendingPluginEntry *) (cur->data);

    if (!plugin_loader_load_and_sync (l, entry)) {
      /* Create dummy plugin entry to block re-scanning this file */
      GST_ERROR ("Plugin file %s failed to load. Blacklisting",
          entry->filename);
      plugin_loader_create_blacklist_plugin (l, entry);
      l->got_plugin_details = TRUE;
      /* Now remove this crashy plugin from the head of the list */
      l->pending_plugins = g_list_delete_link (cur, cur);
      g_free (entry->filename);
      g_slice_free (PendingPluginEntry, entry);
      if (l->pending_plugins == NULL)
        l->pending_plugins_tail = NULL;
      if (!gst_plugin_loader_spawn (l))
        return FALSE;
      break;
    }
  }

  /* We exited after finding the crashing one. If there's any more pending,
   * dispatch them post-haste, but don't wait */
  for (cur = l->pending_plugins; cur != NULL; cur = next) {
    PendingPluginEntry *entry = (PendingPluginEntry *) (cur->data);

    next = g_list_next (cur);

    put_packet (l, PACKET_LOAD_PLUGIN, entry->tag,
        (guint8 *) entry->filename, strlen (entry->filename) + 1);

    /* This might invalidate cur, which is why we grabbed 'next' above */
    if (!exchange_packets (l))
      goto restart;
  }

  return TRUE;
}
示例#10
0
/*
 * dump the file into the fd
 */
static void dump_file(gzFile fd, struct log_global_header *hdr)
{
   struct log_header_packet pck;
   struct log_header_info inf;
   struct dissector_info infbuf;
   u_char *pckbuf;
   int count = 0;

   /* loop until EOF */
   LOOP {
      switch (hdr->type) {
         case LOG_INFO:
            if (get_info(&inf, &infbuf) != E_SUCCESS) {
               printf("\n");
               return;
            }
            /* write the info */
            put_info(fd, &inf, &infbuf);
	    SAFE_FREE(infbuf.user);
            SAFE_FREE(infbuf.pass);
            SAFE_FREE(infbuf.info);
            SAFE_FREE(infbuf.banner);

            break;

         case LOG_PACKET:
            if (get_packet(&pck, &pckbuf) != E_SUCCESS) {
               printf("\n");
               return;
            }
            /* write the data */
            put_packet(fd, &pck, pckbuf);
            SAFE_FREE(pckbuf);
            break;
            
         default:
            FATAL_ERROR("Unknown log type");
            break;
      }
      
      /* a dot every 10 packets */
      if (count++ % 10 == 0) {
         printf(".");
         fflush(stdout);
      }
   }

}
示例#11
0
Error PacketPeer::put_var(const Variant &p_packet) {

	int len;
	Error err = encode_variant(p_packet, NULL, len); // compute len first
	if (err)
		return err;

	if (len == 0)
		return OK;

	uint8_t *buf = (uint8_t *)alloca(len);
	ERR_FAIL_COND_V(!buf, ERR_OUT_OF_MEMORY);
	err = encode_variant(p_packet, buf, len);
	ERR_FAIL_COND_V(err, err);

	return put_packet(buf, len);
}
示例#12
0
static gboolean
gst_plugin_loader_try_helper (GstPluginLoader * loader, gchar * location)
{
  char *argv[5] = { NULL, };
  int c = 0;

#if defined (__APPLE__) && defined (USR_BIN_ARCH_SWITCH)
  if (gst_plugin_loader_use_usr_bin_arch ()) {
    argv[c++] = (char *) "/usr/bin/arch";
    argv[c++] = (char *) USR_BIN_ARCH_SWITCH;
  }
#endif
  argv[c++] = location;
  argv[c++] = (char *) "-l";
  argv[c++] = NULL;

  if (c > 3) {
    GST_LOG ("Trying to spawn gst-plugin-scanner helper at %s with arch %s",
        location, argv[1]);
  } else {
    GST_LOG ("Trying to spawn gst-plugin-scanner helper at %s", location);
  }

  if (!g_spawn_async_with_pipes (NULL, argv, NULL,
          G_SPAWN_DO_NOT_REAP_CHILD /* | G_SPAWN_STDERR_TO_DEV_NULL */ ,
          NULL, NULL, &loader->child_pid, &loader->fd_w.fd, &loader->fd_r.fd,
          NULL, NULL))
    return FALSE;

  gst_poll_add_fd (loader->fdset, &loader->fd_w);
  gst_poll_add_fd (loader->fdset, &loader->fd_r);

  gst_poll_fd_ctl_read (loader->fdset, &loader->fd_r, TRUE);

  loader->tx_buf_write = loader->tx_buf_read = 0;

  put_packet (loader, PACKET_VERSION, 0, NULL, 0);
  if (!plugin_loader_sync_with_child (loader))
    return FALSE;

  loader->child_running = TRUE;

  return TRUE;
}
示例#13
0
static gboolean
plugin_loader_load (GstPluginLoader * loader, const gchar * filename,
    off_t file_size, time_t file_mtime)
{
  gint len;
  PendingPluginEntry *entry;

  if (!gst_plugin_loader_spawn (loader))
    return FALSE;

  /* Send a packet to the child requesting that it load the given file */
  GST_LOG_OBJECT (loader->registry,
      "Sending file %s to child. tag %u", filename, loader->next_tag);

  entry = g_slice_new (PendingPluginEntry);
  entry->tag = loader->next_tag++;
  entry->filename = g_strdup (filename);
  entry->file_size = file_size;
  entry->file_mtime = file_mtime;
  loader->pending_plugins_tail =
      g_list_append (loader->pending_plugins_tail, entry);

  if (loader->pending_plugins == NULL)
    loader->pending_plugins = loader->pending_plugins_tail;
  else
    loader->pending_plugins_tail = g_list_next (loader->pending_plugins_tail);

  len = strlen (filename);
  put_packet (loader, PACKET_LOAD_PLUGIN, entry->tag,
      (guint8 *) filename, len + 1);

  if (!exchange_packets (loader)) {
    if (!plugin_loader_replay_pending (loader))
      return FALSE;
  }

  return TRUE;
}
示例#14
0
static void rsp_read_mem ( const rsp_buf * const buf )
{
  unsigned int addr;
  unsigned int len;

  assert( buf->data[0] == 'm' );

  if ( 2 != sscanf( buf->data, "m%x,%x:", &addr, &len ) || len <= 0 )
  {
    throw std::runtime_error( "Illegal read memory packet." );
  }

  // Make sure we won't overflow the buffer (2 chars per byte).
  if ( len * 2 >= GDB_BUF_MAX )
  {
    throw std::runtime_error( "The read memory packet's reponse would overflow the packet buffer." );
  }

  std::vector< uint8_t > data;
  dbg_cpu0_read_mem( uint32_t( addr ), uint32_t( len ), &data );

  const unsigned actually_read_len = data.size();
  rsp_buf reply;

  for ( unsigned off = 0; off < actually_read_len; off++ )
  {
    const unsigned char ch = data[ off ];
    // printf( "Memory read, byte at %u: 0x%02X\n", off, ch );
    reply.data[off * 2]     = get_hex_char( ch >>   4 );
    reply.data[off * 2 + 1] = get_hex_char( ch &  0xf );
  }

  reply.data[actually_read_len * 2] = 0;  // End of string.
  reply.len = actually_read_len * 2;
  put_packet( rsp.client_fd, &reply );
}
示例#15
0
void main1(int argc, char** argv) {
	srand(time(0));
	//init
	protocol_init(argc, argv);
	//arguments
	windowSize = 22;
	retimer = 3300;//retransmit timer
	acktimer = 600;
	bufferSize = windowSize / 2;//buffer size
	//init datalink layer
	senderLeft = 0;//left edge of sender
	senderRight = 0;//right edge of sender, which has data unfilled
	receiverLeft = 0;//left edge of receiver
	//receiverRight = bufferSize - 1;//right edge of receiver
	isPhysicalLayerReady = -1;
	lastAck = windowSize - 1;
	//init buffer
	sender = (buffer*)malloc(sizeof(buffer)* bufferSize);
	receiver = (buffer*)malloc(sizeof(buffer)* bufferSize);
	for (int i = 0; i < bufferSize; i++) {
		sender[i].frameArrived = false;
		receiver[i].frameArrived = false;
		sender[i].hasSent = false;
		receiver[i].hasSent = false;
	}
	//init interfcace
	enable_network_layer();
	bool isNetworkEnabled = true;
	//init event args
	int eventArgs = -1;
	int eventKind = -1;
	//allocate temp space
	unsigned char temp[MAX_PACKET_SIZE + 11];
	//main loop
	while (true) {
		static int frameLength;
		eventKind = wait_for_event(&eventArgs);//get event
		switch (eventKind) {
		case PHYSICAL_LAYER_READY:
			isPhysicalLayerReady = 1;
			break;
		case NETWORK_LAYER_READY:
			//if buffer nearly full
			if (((senderRight > senderLeft) && (senderRight - senderLeft == bufferSize - 1)) || (senderRight < senderLeft) && (windowSize - senderLeft + senderRight == bufferSize - 1)) {
				disable_network_layer();
				isNetworkEnabled = false;
			}

			//store frame in buffer
			sender[senderRight % bufferSize].length = get_packet(sender[senderRight % bufferSize].data);

			//slide window
			senderRight = (senderRight + 1) % windowSize;
			break;
		case FRAME_RECEIVED:
			//init temperory variables
			frameLength = recv_frame(temp, MAX_PACKET_SIZE + 7);

			if (frameLength > MAX_PACKET_SIZE + 7)
				;//frame is too large, discard it
			else {
				//check crc
				if (crc32(temp, frameLength) != 0) {//crc faild
					if (isInBuffer(senderLeft, senderRight, temp[0] == FRAME_DATA ? temp[2] : temp[1], false)) {
						//send nak
						temp[0] = FRAME_NAK;//if the 2nd byte is error, it may sends false nak, but it doesn't matter
						mySendFrame(temp, 2);
					}
				}
				else {
					if (temp[0] == FRAME_ACK) {//if it's an ack frame
						if (isInBuffer(senderLeft, senderRight, temp[1], false)) {
							if (isInBuffer(lastAck, senderRight, temp[1], false))
								lastAck = temp[1];
							//else do noting
							break;
						}
					}
					else if (temp[0] == FRAME_NAK) {//if it's a nak frame
						if (isInBuffer(senderLeft, senderRight, temp[1], false)) {
							//retranmit
							temp[0] = 1;
							memcpy(temp + 3, sender[temp[1] % bufferSize].data, sender[temp[1] % bufferSize].length * sizeof(unsigned char));
							mySendFrame(temp, sender[temp[1] % bufferSize].length + 3);
							break;
						}
					}
					else if (temp[0] == FRAME_DATA) {//if it's a data frame
						if (isInBuffer(lastAck, senderRight, temp[2], false))
							lastAck = temp[2];
						if (isInBuffer(receiverLeft, (receiverLeft + bufferSize) % windowSize, temp[1], true)){
							if (!receiver[temp[1] % bufferSize].frameArrived) {
								receiver[temp[1] % bufferSize].frameArrived = true;
								receiver[temp[1] % bufferSize].length = frameLength - 7;
								for (int i = 0; i < frameLength - 7; i++) {
									receiver[temp[1] % bufferSize].data[i] = temp[3 + i];
								}
							}
						}
					}

				}

			}
			break;
		case DATA_TIMEOUT:
			//just retransmit the frame
			if (isInBuffer(lastAck, senderRight, eventArgs, false) && isInBuffer(senderLeft, senderRight, eventArgs, false)) {
				if (sender[eventArgs % bufferSize].hasSent) {//if it has been sent
					if (eventArgs == senderLeft || rand() % 10 > 10) {
						//build the frame
						temp[0] = FRAME_DATA;
						temp[1] = eventArgs;
						memcpy((void*)(temp + 3), sender[eventArgs % bufferSize].data, sender[eventArgs % bufferSize].length * sizeof(unsigned char));
						//transmit
						mySendFrame(temp, sender[eventArgs % bufferSize].length + 3);
					}
					else
						start_timer(eventArgs, retimer * (rand() % 10 / 10.0 + 1));
				}
			}
			break;
		case ACK_TIMEOUT:
			//just send an ack
			temp[0] = FRAME_ACK;
			mySendFrame(temp, 2);
			break;
		}


		//sliding the sender window
		//send
		{
			int i = senderLeft;
			while (isInBuffer(senderLeft, senderRight, i, false)) {
				if (sender[i % bufferSize].hasSent == false){
					if (isPhysicalLayerReady == 1 || isPhysicalLayerReady == -1 || phl_sq_len() < 1000) {
						//build the frame
						temp[0] = FRAME_DATA;
						temp[1] = i % windowSize;
						memcpy((void*)(temp + 3), sender[i % bufferSize].data, sender[i % bufferSize].length * sizeof(unsigned char));
						//transmit
						mySendFrame(temp, sender[i % bufferSize].length + 3);
						sender[i % bufferSize].hasSent = true;
						isPhysicalLayerReady = 0;
					}
					break;
				}
				i = (i + 1) % windowSize;
			}
		}
		//slide
		while (isInBuffer(senderLeft, senderRight, lastAck, false)) {//·â×°º¯Êý
			sender[senderLeft % bufferSize].hasSent = false;
			stop_timer(senderLeft);
			senderLeft = (senderLeft + 1) % windowSize;
		}
		//enable network layer
		if (!(((senderRight > senderLeft) && (senderRight - senderLeft == bufferSize)) || (senderRight < senderLeft) && (windowSize - senderLeft + senderRight == bufferSize)) && !isNetworkEnabled) {
			enable_network_layer();
			isNetworkEnabled = true;
		}


		//sliding the receiver window
		{
			int i = 0;
			for (i = 0; i < bufferSize; i++) {
				if (receiver[(receiverLeft + i) % bufferSize].frameArrived) {
					put_packet(receiver[(receiverLeft + i) % bufferSize].data, receiver[(receiverLeft + i) % bufferSize].length);
					receiver[(receiverLeft + i) % bufferSize].frameArrived = false;
				}
				else break;
			}
			receiverLeft = (receiverLeft + i) % windowSize;
		}
	}
}
示例#16
0
文件: gdbstub.c 项目: Blub/qemu
static int gdb_handle_packet(GDBState *s, const char *line_buf)
{
    CPUState *cpu;
    CPUClass *cc;
    const char *p;
    uint32_t thread;
    int ch, reg_size, type, res;
    char buf[MAX_PACKET_LENGTH];
    uint8_t mem_buf[MAX_PACKET_LENGTH];
    uint8_t *registers;
    target_ulong addr, len;

#ifdef DEBUG_GDB
    printf("command='%s'\n", line_buf);
#endif
    p = line_buf;
    ch = *p++;
    switch(ch) {
    case '?':
        /* TODO: Make this return the correct value for user-mode.  */
        snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
                 cpu_index(s->c_cpu));
        put_packet(s, buf);
        /* Remove all the breakpoints when this query is issued,
         * because gdb is doing and initial connect and the state
         * should be cleaned up.
         */
        gdb_breakpoint_remove_all();
        break;
    case 'c':
        if (*p != '\0') {
            addr = strtoull(p, (char **)&p, 16);
            gdb_set_cpu_pc(s, addr);
        }
        s->signal = 0;
        gdb_continue(s);
        return RS_IDLE;
    case 'C':
        s->signal = gdb_signal_to_target (strtoul(p, (char **)&p, 16));
        if (s->signal == -1)
            s->signal = 0;
        gdb_continue(s);
        return RS_IDLE;
    case 'v':
        if (strncmp(p, "Cont", 4) == 0) {
            int res_signal, res_thread;

            p += 4;
            if (*p == '?') {
                put_packet(s, "vCont;c;C;s;S");
                break;
            }
            res = 0;
            res_signal = 0;
            res_thread = 0;
            while (*p) {
                int action, signal;

                if (*p++ != ';') {
                    res = 0;
                    break;
                }
                action = *p++;
                signal = 0;
                if (action == 'C' || action == 'S') {
                    signal = gdb_signal_to_target(strtoul(p, (char **)&p, 16));
                    if (signal == -1) {
                        signal = 0;
                    }
                } else if (action != 'c' && action != 's') {
                    res = 0;
                    break;
                }
                thread = 0;
                if (*p == ':') {
                    thread = strtoull(p+1, (char **)&p, 16);
                }
                action = tolower(action);
                if (res == 0 || (res == 'c' && action == 's')) {
                    res = action;
                    res_signal = signal;
                    res_thread = thread;
                }
            }
            if (res) {
                if (res_thread != -1 && res_thread != 0) {
                    cpu = find_cpu(res_thread);
                    if (cpu == NULL) {
                        put_packet(s, "E22");
                        break;
                    }
                    s->c_cpu = cpu;
                }
                if (res == 's') {
                    cpu_single_step(s->c_cpu, sstep_flags);
                }
                s->signal = res_signal;
                gdb_continue(s);
                return RS_IDLE;
            }
            break;
        } else {
            goto unknown_command;
        }
    case 'k':
        /* Kill the target */
        fprintf(stderr, "\nQEMU: Terminated via GDBstub\n");
        exit(0);
    case 'D':
        /* Detach packet */
        gdb_breakpoint_remove_all();
        gdb_syscall_mode = GDB_SYS_DISABLED;
        gdb_continue(s);
        put_packet(s, "OK");
        break;
    case 's':
        if (*p != '\0') {
            addr = strtoull(p, (char **)&p, 16);
            gdb_set_cpu_pc(s, addr);
        }
        cpu_single_step(s->c_cpu, sstep_flags);
        gdb_continue(s);
        return RS_IDLE;
    case 'F':
    {
        target_ulong ret;
        target_ulong err;

        ret = strtoull(p, (char **)&p, 16);
        if (*p == ',') {
            p++;
            err = strtoull(p, (char **)&p, 16);
        } else {
            err = 0;
        }
        if (*p == ',')
            p++;
        type = *p;
        if (s->current_syscall_cb) {
            s->current_syscall_cb(s->c_cpu, ret, err);
            s->current_syscall_cb = NULL;
        }
        if (type == 'C') {
            put_packet(s, "T02");
        } else {
            gdb_continue(s);
        }
    }
    break;
    case 'g':
        cpu_synchronize_state(s->g_cpu);
        len = 0;
        for (addr = 0; addr < s->g_cpu->gdb_num_g_regs; addr++) {
            reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
            len += reg_size;
        }
        memtohex(buf, mem_buf, len);
        put_packet(s, buf);
        break;
    case 'G':
        cpu_synchronize_state(s->g_cpu);
        registers = mem_buf;
        len = strlen(p) / 2;
        hextomem((uint8_t *)registers, p, len);
        for (addr = 0; addr < s->g_cpu->gdb_num_g_regs && len > 0; addr++) {
            reg_size = gdb_write_register(s->g_cpu, registers, addr);
            len -= reg_size;
            registers += reg_size;
        }
        put_packet(s, "OK");
        break;
    case 'm':
        addr = strtoull(p, (char **)&p, 16);
        if (*p == ',')
            p++;
        len = strtoull(p, NULL, 16);

        /* memtohex() doubles the required space */
        if (len > MAX_PACKET_LENGTH / 2) {
            put_packet (s, "E22");
            break;
        }

        if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, false) != 0) {
            put_packet (s, "E14");
        } else {
            memtohex(buf, mem_buf, len);
            put_packet(s, buf);
        }
        break;
    case 'M':
        addr = strtoull(p, (char **)&p, 16);
        if (*p == ',')
            p++;
        len = strtoull(p, (char **)&p, 16);
        if (*p == ':')
            p++;

        /* hextomem() reads 2*len bytes */
        if (len > strlen(p) / 2) {
            put_packet (s, "E22");
            break;
        }
        hextomem(mem_buf, p, len);
        if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len,
                                   true) != 0) {
            put_packet(s, "E14");
        } else {
            put_packet(s, "OK");
        }
        break;
    case 'p':
        /* Older gdb are really dumb, and don't use 'g' if 'p' is avaialable.
           This works, but can be very slow.  Anything new enough to
           understand XML also knows how to use this properly.  */
        if (!gdb_has_xml)
            goto unknown_command;
        addr = strtoull(p, (char **)&p, 16);
        reg_size = gdb_read_register(s->g_cpu, mem_buf, addr);
        if (reg_size) {
            memtohex(buf, mem_buf, reg_size);
            put_packet(s, buf);
        } else {
            put_packet(s, "E14");
        }
        break;
    case 'P':
        if (!gdb_has_xml)
            goto unknown_command;
        addr = strtoull(p, (char **)&p, 16);
        if (*p == '=')
            p++;
        reg_size = strlen(p) / 2;
        hextomem(mem_buf, p, reg_size);
        gdb_write_register(s->g_cpu, mem_buf, addr);
        put_packet(s, "OK");
        break;
    case 'Z':
    case 'z':
        type = strtoul(p, (char **)&p, 16);
        if (*p == ',')
            p++;
        addr = strtoull(p, (char **)&p, 16);
        if (*p == ',')
            p++;
        len = strtoull(p, (char **)&p, 16);
        if (ch == 'Z')
            res = gdb_breakpoint_insert(addr, len, type);
        else
            res = gdb_breakpoint_remove(addr, len, type);
        if (res >= 0)
            put_packet(s, "OK");
        else if (res == -ENOSYS)
            put_packet(s, "");
        else
            put_packet(s, "E22");
        break;
    case 'H':
        type = *p++;
        thread = strtoull(p, (char **)&p, 16);
        if (thread == -1 || thread == 0) {
            put_packet(s, "OK");
            break;
        }
        cpu = find_cpu(thread);
        if (cpu == NULL) {
            put_packet(s, "E22");
            break;
        }
        switch (type) {
        case 'c':
            s->c_cpu = cpu;
            put_packet(s, "OK");
            break;
        case 'g':
            s->g_cpu = cpu;
            put_packet(s, "OK");
            break;
        default:
            put_packet(s, "E22");
            break;
        }
        break;
    case 'T':
        thread = strtoull(p, (char **)&p, 16);
        cpu = find_cpu(thread);

        if (cpu != NULL) {
            put_packet(s, "OK");
        } else {
            put_packet(s, "E22");
        }
        break;
    case 'q':
    case 'Q':
        /* parse any 'q' packets here */
        if (!strcmp(p,"qemu.sstepbits")) {
            /* Query Breakpoint bit definitions */
            snprintf(buf, sizeof(buf), "ENABLE=%x,NOIRQ=%x,NOTIMER=%x",
                     SSTEP_ENABLE,
                     SSTEP_NOIRQ,
                     SSTEP_NOTIMER);
            put_packet(s, buf);
            break;
        } else if (is_query_packet(p, "qemu.sstep", '=')) {
            /* Display or change the sstep_flags */
            p += 10;
            if (*p != '=') {
                /* Display current setting */
                snprintf(buf, sizeof(buf), "0x%x", sstep_flags);
                put_packet(s, buf);
                break;
            }
            p++;
            type = strtoul(p, (char **)&p, 16);
            sstep_flags = type;
            put_packet(s, "OK");
            break;
        } else if (strcmp(p,"C") == 0) {
            /* "Current thread" remains vague in the spec, so always return
             *  the first CPU (gdb returns the first thread). */
            put_packet(s, "QC1");
            break;
        } else if (strcmp(p,"fThreadInfo") == 0) {
            s->query_cpu = first_cpu;
            goto report_cpuinfo;
        } else if (strcmp(p,"sThreadInfo") == 0) {
report_cpuinfo:
            if (s->query_cpu) {
                snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu));
                put_packet(s, buf);
                s->query_cpu = CPU_NEXT(s->query_cpu);
            } else
                put_packet(s, "l");
            break;
        } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
            thread = strtoull(p+16, (char **)&p, 16);
            cpu = find_cpu(thread);
            if (cpu != NULL) {
                cpu_synchronize_state(cpu);
                /* memtohex() doubles the required space */
                len = snprintf((char *)mem_buf, sizeof(buf) / 2,
                               "CPU#%d [%s]", cpu->cpu_index,
                               cpu->halted ? "halted " : "running");
                memtohex(buf, mem_buf, len);
                put_packet(s, buf);
            }
            break;
        }
#ifdef CONFIG_USER_ONLY
        else if (strcmp(p, "Offsets") == 0) {
            TaskState *ts = s->c_cpu->opaque;

            snprintf(buf, sizeof(buf),
                     "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
                     ";Bss=" TARGET_ABI_FMT_lx,
                     ts->info->code_offset,
                     ts->info->data_offset,
                     ts->info->data_offset);
            put_packet(s, buf);
            break;
        }
#else /* !CONFIG_USER_ONLY */
        else if (strncmp(p, "Rcmd,", 5) == 0) {
            int len = strlen(p + 5);

            if ((len % 2) != 0) {
                put_packet(s, "E01");
                break;
            }
            len = len / 2;
            hextomem(mem_buf, p + 5, len);
            mem_buf[len++] = 0;
            qemu_chr_be_write(s->mon_chr, mem_buf, len);
            put_packet(s, "OK");
            break;
        }
#endif /* !CONFIG_USER_ONLY */
        if (is_query_packet(p, "Supported", ':')) {
            snprintf(buf, sizeof(buf), "PacketSize=%x", MAX_PACKET_LENGTH);
            cc = CPU_GET_CLASS(first_cpu);
            if (cc->gdb_core_xml_file != NULL) {
                pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
            }
            put_packet(s, buf);
            break;
        }
        if (strncmp(p, "Xfer:features:read:", 19) == 0) {
            const char *xml;
            target_ulong total_len;

            cc = CPU_GET_CLASS(first_cpu);
            if (cc->gdb_core_xml_file == NULL) {
                goto unknown_command;
            }

            gdb_has_xml = true;
            p += 19;
            xml = get_feature_xml(p, &p, cc);
            if (!xml) {
                snprintf(buf, sizeof(buf), "E00");
                put_packet(s, buf);
                break;
            }

            if (*p == ':')
                p++;
            addr = strtoul(p, (char **)&p, 16);
            if (*p == ',')
                p++;
            len = strtoul(p, (char **)&p, 16);

            total_len = strlen(xml);
            if (addr > total_len) {
                snprintf(buf, sizeof(buf), "E00");
                put_packet(s, buf);
                break;
            }
            if (len > (MAX_PACKET_LENGTH - 5) / 2)
                len = (MAX_PACKET_LENGTH - 5) / 2;
            if (len < total_len - addr) {
                buf[0] = 'm';
                len = memtox(buf + 1, xml + addr, len);
            } else {
                buf[0] = 'l';
                len = memtox(buf + 1, xml + addr, total_len - addr);
            }
            put_packet_binary(s, buf, len + 1);
            break;
        }
        if (is_query_packet(p, "Attached", ':')) {
            put_packet(s, GDB_ATTACHED);
            break;
        }
        /* Unrecognised 'q' command.  */
        goto unknown_command;

    default:
unknown_command:
        /* put empty packet */
        buf[0] = '\0';
        put_packet(s, buf);
        break;
    }
    return RS_IDLE;
}
示例#17
0
文件: gdbstub.c 项目: Blub/qemu
static void gdb_vm_state_change(void *opaque, int running, RunState state)
{
    GDBState *s = gdbserver_state;
    CPUState *cpu = s->c_cpu;
    char buf[256];
    const char *type;
    int ret;

    if (running || s->state == RS_INACTIVE) {
        return;
    }
    /* Is there a GDB syscall waiting to be sent?  */
    if (s->current_syscall_cb) {
        put_packet(s, s->syscall_buf);
        return;
    }
    switch (state) {
    case RUN_STATE_DEBUG:
        if (cpu->watchpoint_hit) {
            switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
            case BP_MEM_READ:
                type = "r";
                break;
            case BP_MEM_ACCESS:
                type = "a";
                break;
            default:
                type = "";
                break;
            }
            snprintf(buf, sizeof(buf),
                     "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
                     GDB_SIGNAL_TRAP, cpu_index(cpu), type,
                     (target_ulong)cpu->watchpoint_hit->vaddr);
            cpu->watchpoint_hit = NULL;
            goto send_packet;
        }
        tb_flush(cpu);
        ret = GDB_SIGNAL_TRAP;
        break;
    case RUN_STATE_PAUSED:
        ret = GDB_SIGNAL_INT;
        break;
    case RUN_STATE_SHUTDOWN:
        ret = GDB_SIGNAL_QUIT;
        break;
    case RUN_STATE_IO_ERROR:
        ret = GDB_SIGNAL_IO;
        break;
    case RUN_STATE_WATCHDOG:
        ret = GDB_SIGNAL_ALRM;
        break;
    case RUN_STATE_INTERNAL_ERROR:
        ret = GDB_SIGNAL_ABRT;
        break;
    case RUN_STATE_SAVE_VM:
    case RUN_STATE_RESTORE_VM:
        return;
    case RUN_STATE_FINISH_MIGRATE:
        ret = GDB_SIGNAL_XCPU;
        break;
    default:
        ret = GDB_SIGNAL_UNKNOWN;
        break;
    }
    gdb_set_stop_cpu(cpu);
    snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(cpu));

send_packet:
    put_packet(s, buf);

    /* disable single step if it was enabled */
    cpu_single_step(cpu, 0);
}
示例#18
0
int main(int argc, char ** argv)
{
    int event, arg;
    struct FRAME r;
    int len = 0; 
    int i;

    protocol_init(argc, argv); 
    lprintf("Designed by JackalDire\n");

    disable_network_layer();

    for (;;) {
        event = wait_for_event(&arg);

        switch (event) {
        case NETWORK_LAYER_READY:
            get_packet(buffer[next_frame_to_send]); // fetch new packet from physical layer
            nbuffered++;
            send_data_frame();
            inc(&next_frame_to_send);
            break;

        case PHYSICAL_LAYER_READY:
            phl_ready = 1;
            break;

        case FRAME_RECEIVED: 
            len = recv_frame((unsigned char *)&r, sizeof r);
            if (len < 5 || crc32((unsigned char *)&r, len) != 0) {
                /* discard the error packet with wrong crc checksum  */
                /* TODO : add NAK to  accelerate resending */
                dbg_event("**** receiver error, bad CRC checksum, packet discarded.\n");
                break;
            }

            if (r.kind == FRAME_DATA) {
                dbg_frame("Recv DATA %d %d, ID %d\n", r.seq, r.ack, *(short *)r.data);
                if (r.seq == frame_expected) {
                    /* transmit the receive packet to network layer */
                    put_packet(r.data, PKT_LEN); // 7 = 3B other fields + 4B crc code
                    inc(&frame_expected);
                    start_ack_timer(ACK_TIMER);
                }
            }
            /* ACK n means packets earlier than n were received correctly,
             * so make packet ack_expeced ~ r.ack acknowledged */ 
            while (between(ack_expected, r.ack, next_frame_to_send)) {
                --nbuffered;
                stop_timer(ack_expected);
                inc(&ack_expected);
            }
            break; 

        case DATA_TIMEOUT:
            dbg_event("---- DATA %d timeout\n", arg); 
            next_frame_to_send = ack_expected;
            /* retransmit all packets in the buffer when timeout */ 
            for (i = 1; i <= nbuffered; ++i) {
                send_data_frame();
                inc(&next_frame_to_send);
            }
            break;
        
        
        case ACK_TIMEOUT:
            /* send a separate ACK frame if there is no outstream for a specific time */
            dbg_event("---- ACK %d timeout\n", arg);
            send_ack_frame();
        }
        
        /* disable networklayer when outstrem buffer if full */
        if (nbuffered < MAX_SEQ && phl_ready)
            enable_network_layer();
        else
            disable_network_layer(); 
   }
}
示例#19
0
static gboolean
handle_rx_packet (GstPluginLoader * l,
    guint pack_type, guint32 tag, guint8 * payload, guint payload_len)
{
  gboolean res = TRUE;

  switch (pack_type) {
    case PACKET_EXIT:
      gst_poll_fd_ctl_read (l->fdset, &l->fd_r, FALSE);
      if (l->is_child) {
        /* Respond */
        put_packet (l, PACKET_EXIT, 0, NULL, 0);
      }
      l->rx_done = TRUE;
      return TRUE;
    case PACKET_LOAD_PLUGIN:{
      if (!l->is_child)
        return TRUE;

      /* Payload is the filename to load */
      res = do_plugin_load (l, (gchar *) payload, tag);

      break;
    }
    case PACKET_PLUGIN_DETAILS:{
      gchar *tmp = (gchar *) payload;
      PendingPluginEntry *entry = NULL;
      GList *cur;

      GST_DEBUG_OBJECT (l->registry,
          "Received plugin details from child w/ tag %u. %d bytes info",
          tag, payload_len);

      /* Assume that tagged details come back in the order
       * we requested, and delete anything before (but not
       * including) this one */
      cur = l->pending_plugins;
      while (cur) {
        PendingPluginEntry *e = (PendingPluginEntry *) (cur->data);

        if (e->tag > tag)
          break;

        if (e->tag == tag) {
          entry = e;
          break;
        } else {
          cur = g_list_delete_link (cur, cur);
          g_free (e->filename);
          g_slice_free (PendingPluginEntry, e);
        }
      }

      l->pending_plugins = cur;
      if (cur == NULL)
        l->pending_plugins_tail = NULL;

      if (payload_len > 0) {
        GstPlugin *newplugin = NULL;
        if (!_priv_gst_registry_chunks_load_plugin (l->registry, &tmp,
                tmp + payload_len, &newplugin)) {
          /* Got garbage from the child, so fail and trigger replay of plugins */
          GST_ERROR_OBJECT (l->registry,
              "Problems loading plugin details with tag %u from scanner", tag);
          return FALSE;
        }

        newplugin->flags &= ~GST_PLUGIN_FLAG_CACHED;
        GST_LOG_OBJECT (l->registry,
            "marking plugin %p as registered as %s", newplugin,
            newplugin->filename);
        newplugin->registered = TRUE;

        /* We got a set of plugin details - remember it for later */
        l->got_plugin_details = TRUE;
      } else if (entry != NULL) {
        /* Create a blacklist entry for this file to prevent scanning every time */
        plugin_loader_create_blacklist_plugin (l, entry);
        l->got_plugin_details = TRUE;
      }

      if (entry != NULL) {
        g_free (entry->filename);
        g_slice_free (PendingPluginEntry, entry);
      }

      /* Remove the plugin entry we just loaded */
      cur = l->pending_plugins;
      if (cur != NULL)
        cur = g_list_delete_link (cur, cur);
      l->pending_plugins = cur;
      if (cur == NULL)
        l->pending_plugins_tail = NULL;

      break;
    }
    case PACKET_SYNC:
      if (l->is_child) {
        /* Respond with our reply - also a sync */
        put_packet (l, PACKET_SYNC, tag, NULL, 0);
        GST_LOG ("Got SYNC in child - replying");
      } else
        l->rx_got_sync = TRUE;
      break;
    case PACKET_VERSION:
      if (l->is_child) {
        /* Respond with our reply - a version packet, with the version */
        const gint version_len =
            sizeof (guint32) + GST_MAGIC_BINARY_VERSION_LEN;
        guint8 version_info[sizeof (guint32) + GST_MAGIC_BINARY_VERSION_LEN];
        memset (version_info, 0, version_len);
        GST_WRITE_UINT32_BE (version_info, loader_protocol_version);
        memcpy (version_info + sizeof (guint32), GST_MAGIC_BINARY_VERSION_STR,
            strlen (GST_MAGIC_BINARY_VERSION_STR));
        put_packet (l, PACKET_VERSION, tag, version_info, version_len);
        GST_LOG ("Got VERSION in child - replying %u", loader_protocol_version);
      } else {
        res = check_protocol_version (l, payload, payload_len);
      }
      break;
    default:
      return FALSE;             /* Invalid packet -> something is wrong */
  }

  return res;
}
示例#20
0
static gboolean
do_plugin_load (GstPluginLoader * l, const gchar * filename, guint tag)
{
  GstPlugin *newplugin;
  GList *chunks = NULL;

  GST_DEBUG ("Plugin scanner loading file %s. tag %u", filename, tag);

#if 0                           /* Test code - crash based on filename */
  if (strstr (filename, "coreelements") == NULL) {
    g_printerr ("Crashing on file %s\n", filename);
    g_printerr ("%d", *(gint *) (NULL));
  }
#endif

  newplugin = gst_plugin_load_file ((gchar *) filename, NULL);
  if (newplugin) {
    guint hdr_pos;
    guint offset;

    /* Now serialise the plugin details and send */
    if (!_priv_gst_registry_chunks_save_plugin (&chunks,
            gst_registry_get_default (), newplugin))
      goto fail;

    /* Store where the header is, write an empty one, then write
     * all the payload chunks, then fix up the header size */
    hdr_pos = l->tx_buf_write;
    offset = HEADER_SIZE;
    put_packet (l, PACKET_PLUGIN_DETAILS, tag, NULL, 0);

    if (chunks) {
      GList *walk;
      for (walk = chunks; walk; walk = g_list_next (walk)) {
        GstRegistryChunk *cur = walk->data;
        put_chunk (l, cur, &offset);

        _priv_gst_registry_chunk_free (cur);
      }

      g_list_free (chunks);

      /* Store the size of the written payload */
      GST_WRITE_UINT32_BE (l->tx_buf + hdr_pos + 4, offset - HEADER_SIZE);
    }
#if 0                           /* Test code - corrupt the tx buffer based on filename */
    if (strstr (filename, "sink") != NULL) {
      int fd, res;
      g_printerr ("Corrupting tx buf on file %s\n", filename);
      fd = open ("/dev/urandom", O_RDONLY);
      res = read (fd, l->tx_buf, l->tx_buf_size);
      close (fd);
    }
#endif

    gst_object_unref (newplugin);
  } else {
    put_packet (l, PACKET_PLUGIN_DETAILS, tag, NULL, 0);
  }

  return TRUE;
fail:
  put_packet (l, PACKET_PLUGIN_DETAILS, tag, NULL, 0);
  if (chunks) {
    GList *walk;
    for (walk = chunks; walk; walk = g_list_next (walk)) {
      GstRegistryChunk *cur = walk->data;

      _priv_gst_registry_chunk_free (cur);
    }

    g_list_free (chunks);
  }

  return FALSE;
}