static int ssl3_get_record(SSL *s)
	{
	int ssl_major,ssl_minor,al;
	int enc_err,n,i,ret= -1;
	SSL3_RECORD *rr;
	SSL_SESSION *sess;
	unsigned char *p;
	unsigned char md[EVP_MAX_MD_SIZE];
	short version;
	unsigned mac_size;
	int clear=0;
	size_t extra;

	rr= &(s->s3->rrec);
	sess=s->session;

	if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
		extra=SSL3_RT_MAX_EXTRA;
	else
		extra=0;
	if (extra != s->s3->rbuf.len - SSL3_RT_MAX_PACKET_SIZE)
		{
		/* actually likely an application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
		 * set after ssl3_setup_buffers() was done */
		SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR);
		return -1;
		}

again:
	/* check if we have the header */
	if (	(s->rstate != SSL_ST_READ_BODY) ||
		(s->packet_length < SSL3_RT_HEADER_LENGTH))
		{
		n=ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
		if (n <= 0) return(n); /* error or non-blocking */
		s->rstate=SSL_ST_READ_BODY;

		p=s->packet;

		/* Pull apart the header into the SSL3_RECORD */
		rr->type= *(p++);
		ssl_major= *(p++);
		ssl_minor= *(p++);
		version=(ssl_major<<8)|ssl_minor;
		n2s(p,rr->length);

		/* Lets check version */
		if (!s->first_packet)
			{
			if (version != s->version)
				{
				SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
                                if ((s->version & 0xFF00) == (version & 0xFF00))
                                	/* Send back error using their minor version number :-) */
					s->version = (unsigned short)version;
				al=SSL_AD_PROTOCOL_VERSION;
				goto f_err;
				}
			}

		if ((version>>8) != SSL3_VERSION_MAJOR)
			{
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
			goto err;
			}

		if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra)
			{
			al=SSL_AD_RECORD_OVERFLOW;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
			goto f_err;
			}

		/* now s->rstate == SSL_ST_READ_BODY */
		}

	/* s->rstate == SSL_ST_READ_BODY, get and decode the data */

	if (rr->length > s->packet_length-SSL3_RT_HEADER_LENGTH)
		{
		/* now s->packet_length == SSL3_RT_HEADER_LENGTH */
		i=rr->length;
		n=ssl3_read_n(s,i,i,1);
		if (n <= 0) return(n); /* error or non-blocking io */
		/* now n == rr->length,
		 * and s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length */
		}

	s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */

	/* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
	 * and we have that many bytes in s->packet
	 */
	rr->input= &(s->packet[SSL3_RT_HEADER_LENGTH]);

	/* ok, we can now read from 's->packet' data into 'rr'
	 * rr->input points at rr->length bytes, which
	 * need to be copied into rr->data by either
	 * the decryption or by the decompression
	 * When the data is 'copied' into the rr->data buffer,
	 * rr->input will be pointed at the new buffer */

	/* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
	 * rr->length bytes of encrypted compressed stuff. */

	/* check is not needed I believe */
	if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra)
		{
		al=SSL_AD_RECORD_OVERFLOW;
		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
		goto f_err;
		}

	/* decrypt in place in 'rr->input' */
	rr->data=rr->input;

	enc_err = s->method->ssl3_enc->enc(s,0);
	if (enc_err == 0)
		{
		/* SSLerr() and ssl3_send_alert() have been called */
		goto err;
		}

#ifdef TLS_DEBUG
printf("dec %d\n",rr->length);
{ unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
printf("\n");
#endif

	/* r->length is now the compressed data plus mac */
	if (	(sess == NULL) ||
		(s->enc_read_ctx == NULL) ||
		(s->read_hash == NULL))
		clear=1;

	if (!clear)
		{
		/* !clear => s->read_hash != NULL => mac_size != -1 */
		unsigned char *mac = NULL;
		unsigned char mac_tmp[EVP_MAX_MD_SIZE];
		mac_size=EVP_MD_size(s->read_hash);
		OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);

		/* orig_len is the length of the record before any padding was
		 * removed. This is public information, as is the MAC in use,
		 * therefore we can safely process the record in a different
		 * amount of time if it's too short to possibly contain a MAC.
		 */
		if (rr->orig_len < mac_size ||
		    /* CBC records must have a padding length byte too. */
		    (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
		     rr->orig_len < mac_size+1))
			{
			al=SSL_AD_DECODE_ERROR;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
			goto f_err;
			}

		if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE)
			{
			/* We update the length so that the TLS header bytes
			 * can be constructed correctly but we need to extract
			 * the MAC in constant time from within the record,
			 * without leaking the contents of the padding bytes.
			 * */
			mac = mac_tmp;
			ssl3_cbc_copy_mac(mac_tmp, rr, mac_size);
			rr->length -= mac_size;
			}
		else
			{
			/* In this case there's no padding, so |rec->orig_len|
			 * equals |rec->length| and we checked that there's
			 * enough bytes for |mac_size| above. */
			rr->length -= mac_size;
			mac = &rr->data[rr->length];
			}

		i=s->method->ssl3_enc->mac(s,md,0 /* not send */);
		if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
			enc_err = -1;
		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
			enc_err = -1;
		}

	if (enc_err < 0)
		{
		/* A separate 'decryption_failed' alert was introduced with TLS 1.0,
		 * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption
		 * failure is directly visible from the ciphertext anyway,
		 * we should not reveal which kind of error occured -- this
		 * might become visible to an attacker (e.g. via a logfile) */
		al=SSL_AD_BAD_RECORD_MAC;
		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
		goto f_err;
		}

	/* r->length is now just compressed */
	if (s->expand != NULL)
		{
		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra)
			{
			al=SSL_AD_RECORD_OVERFLOW;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
			goto f_err;
			}
		if (!ssl3_do_uncompress(s))
			{
			al=SSL_AD_DECOMPRESSION_FAILURE;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_DECOMPRESSION);
			goto f_err;
			}
		}

	if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH+extra)
		{
		al=SSL_AD_RECORD_OVERFLOW;
		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
		goto f_err;
		}

	rr->off=0;
	/* So at this point the following is true
	 * ssl->s3->rrec.type 	is the type of record
	 * ssl->s3->rrec.length	== number of bytes in record
	 * ssl->s3->rrec.off	== offset to first valid byte
	 * ssl->s3->rrec.data	== where to take bytes from, increment
	 *			   after use :-).
	 */

	/* we have pulled in a full packet so zero things */
	s->packet_length=0;

	/* just read a 0 length packet */
	if (rr->length == 0) goto again;

	return(1);

f_err:
	ssl3_send_alert(s,SSL3_AL_FATAL,al);
err:
	return(ret);
	}


int dtls1_enc(SSL *s, int send)
	{
	SSL3_RECORD *rec;
	EVP_CIPHER_CTX *ds;
	unsigned long l;
	int bs,i,j,k,mac_size=0;
	const EVP_CIPHER *enc;

	if (send)
		{
		if (s->write_hash)
			{
			mac_size=EVP_MD_size(s->write_hash);
			if (mac_size < 0)
				return -1;
			}
		ds=s->enc_write_ctx;
		rec= &(s->s3->wrec);
		if (s->enc_write_ctx == NULL)
			enc=NULL;
		else
			{
			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
			if ( rec->data != rec->input)
				/* we can't write into the input stream */
				fprintf(stderr, "%s:%d: rec->data != rec->input\n",
					__FILE__, __LINE__);
			else if ( EVP_CIPHER_block_size(ds->cipher) > 1)
				{
				if (RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)) <= 0)
					return -1;
				}
			}
		}
	else
		{
		if (s->read_hash)
			{
			mac_size=EVP_MD_size(s->read_hash);
			if (mac_size < 0)
				return -1;
			}
		ds=s->enc_read_ctx;
		rec= &(s->s3->rrec);
		if (s->enc_read_ctx == NULL)
			enc=NULL;
		else
			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
		}

#ifdef KSSL_DEBUG
	printf("dtls1_enc(%d)\n", send);
#endif    /* KSSL_DEBUG */

	if ((s->session == NULL) || (ds == NULL) ||
		(enc == NULL))
		{
		memmove(rec->data,rec->input,rec->length);
		rec->input=rec->data;
		}
	else
		{
		l=rec->length;
		bs=EVP_CIPHER_block_size(ds->cipher);

		if ((bs != 1) && send)
			{
			i=bs-((int)l%bs);

			/* Add weird padding of upto 256 bytes */

			/* we need to add 'i' padding bytes of value j */
			j=i-1;
			if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
				{
				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
					j++;
				}
			for (k=(int)l; k<(int)(l+i); k++)
				rec->input[k]=j;
			l+=i;
			rec->length+=i;
			}

#ifdef KSSL_DEBUG
		{
                unsigned long ui;
		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
                        (void *)ds,rec->data,rec->input,l);
		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n",
                        ds->buf_len, ds->cipher->key_len,
                        (unsigned long)DES_KEY_SZ,
			(unsigned long)DES_SCHEDULE_SZ,
                        ds->cipher->iv_len);
		printf("\t\tIV: ");
		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
		printf("\n");
		printf("\trec->input=");
		for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
		printf("\n");
		}
#endif	/* KSSL_DEBUG */

		if (!send)
			{
			if (l == 0 || l%bs != 0)
				return -1;
			}

		EVP_Cipher(ds,rec->data,rec->input,l);

#ifdef KSSL_DEBUG
		{
                unsigned long ki;
                printf("\trec->data=");
		for (ki=0; ki<l; ki++)
                        printf(" %02x", rec->data[ki]);  printf("\n");
                }
#endif	/* KSSL_DEBUG */

		rec->orig_len = rec->length;
		if ((bs != 1) && !send)
			return tls1_cbc_remove_padding(s, rec, bs, mac_size);
		}
	return(1);
	}


int archive_strncat_l ( struct archive_string * as , const void * _p , size_t n , struct archive_string_conv * sc ) {
 const void * s ;
 size_t length ;
 int i , r = 0 , r2 ;
 if ( _p == NULL || n == 0 ) {
 int tn = 1 ;
 if ( sc != NULL && ( sc -> flag & SCONV_TO_UTF16 ) ) tn = 2 ;
 if ( archive_string_ensure ( as , as -> length + tn ) == NULL ) return ( - 1 ) ;
 as -> s [ as -> length ] = 0 ;
 if ( tn == 2 ) as -> s [ as -> length + 1 ] = 0 ;
 return ( 0 ) ;
 }
 if ( sc == NULL ) {
 length = mbsnbytes ( _p , n ) ;
 if ( archive_string_append ( as , _p , length ) == NULL ) return ( - 1 ) ;
 return ( 0 ) ;
 }
 if ( sc -> flag & SCONV_FROM_UTF16 ) length = utf16nbytes ( _p , n ) ;
 else length = mbsnbytes ( _p , n ) ;
 s = _p ;
 i = 0 ;
 if ( sc -> nconverter > 1 ) {
 sc -> utftmp . length = 0 ;
 r2 = sc -> converter [ 0 ] ( & ( sc -> utftmp ) , s , length , sc ) ;
 if ( r2 != 0 && errno == ENOMEM ) return ( r2 ) ;
 if ( r > r2 ) r = r2 ;
 s = sc -> utftmp . s ;
 length = sc -> utftmp . length ;
 ++ i ;
 }
 r2 = sc -> converter [ i ] ( as , s , length , sc ) ;
 if ( r > r2 ) r = r2 ;
 return ( r ) ;
 }


static int ssl3_get_record(SSL *s)
	{
	int ssl_major,ssl_minor,al;
	int enc_err,n,i,ret= -1;
	SSL3_RECORD *rr;
	SSL_SESSION *sess;
	unsigned char *p;
	unsigned char md[EVP_MAX_MD_SIZE];
	short version;
	int mac_size;
	int clear=0;
	size_t extra;
	int decryption_failed_or_bad_record_mac = 0;
	unsigned char *mac = NULL;

	rr= &(s->s3->rrec);
	sess=s->session;

	if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
		extra=SSL3_RT_MAX_EXTRA;
	else
		extra=0;
	if (extra && !s->s3->init_extra)
		{
		/* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
		 * set after ssl3_setup_buffers() was done */
		SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR);
		return -1;
		}

again:
	/* check if we have the header */
	if (	(s->rstate != SSL_ST_READ_BODY) ||
		(s->packet_length < SSL3_RT_HEADER_LENGTH))
		{
		n=ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
		if (n <= 0) return(n); /* error or non-blocking */
		s->rstate=SSL_ST_READ_BODY;

		p=s->packet;

		/* Pull apart the header into the SSL3_RECORD */
		rr->type= *(p++);
		ssl_major= *(p++);
		ssl_minor= *(p++);
		version=(ssl_major<<8)|ssl_minor;
		n2s(p,rr->length);
#if 0
fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
#endif

		/* Lets check version */
		if (!s->first_packet)
			{
			if (version != s->version)
				{
				SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
                                if ((s->version & 0xFF00) == (version & 0xFF00))
                                	/* Send back error using their minor version number :-) */
					s->version = (unsigned short)version;
				al=SSL_AD_PROTOCOL_VERSION;
				goto f_err;
				}
			}

		if ((version>>8) != SSL3_VERSION_MAJOR)
			{
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
			goto err;
			}

		if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH)
			{
			al=SSL_AD_RECORD_OVERFLOW;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
			goto f_err;
			}

		/* now s->rstate == SSL_ST_READ_BODY */
		}

	/* s->rstate == SSL_ST_READ_BODY, get and decode the data */

	if (rr->length > s->packet_length-SSL3_RT_HEADER_LENGTH)
		{
		/* now s->packet_length == SSL3_RT_HEADER_LENGTH */
		i=rr->length;
		n=ssl3_read_n(s,i,i,1);
		if (n <= 0) return(n); /* error or non-blocking io */
		/* now n == rr->length,
		 * and s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length */
		}

	s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */

	/* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
	 * and we have that many bytes in s->packet
	 */
	rr->input= &(s->packet[SSL3_RT_HEADER_LENGTH]);

	/* ok, we can now read from 's->packet' data into 'rr'
	 * rr->input points at rr->length bytes, which
	 * need to be copied into rr->data by either
	 * the decryption or by the decompression
	 * When the data is 'copied' into the rr->data buffer,
	 * rr->input will be pointed at the new buffer */

	/* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
	 * rr->length bytes of encrypted compressed stuff. */

	/* check is not needed I believe */
	if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra)
		{
		al=SSL_AD_RECORD_OVERFLOW;
		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
		goto f_err;
		}

	/* decrypt in place in 'rr->input' */
	rr->data=rr->input;

	enc_err = s->method->ssl3_enc->enc(s,0);
	if (enc_err <= 0)
		{
		if (enc_err == 0)
			/* SSLerr() and ssl3_send_alert() have been called */
			goto err;

		/* Otherwise enc_err == -1, which indicates bad padding
		 * (rec->length has not been changed in this case).
		 * To minimize information leaked via timing, we will perform
		 * the MAC computation anyway. */
		decryption_failed_or_bad_record_mac = 1;
		}

#ifdef TLS_DEBUG
printf("dec %d\n",rr->length);
{ unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
printf("\n");
#endif

	/* r->length is now the compressed data plus mac */
	if (	(sess == NULL) ||
		(s->enc_read_ctx == NULL) ||
		(EVP_MD_CTX_md(s->read_hash) == NULL))
		clear=1;

	if (!clear)
		{
		/* !clear => s->read_hash != NULL => mac_size != -1 */
		mac_size=EVP_MD_CTX_size(s->read_hash);
		OPENSSL_assert(mac_size >= 0);

		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
			{
#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
			al=SSL_AD_RECORD_OVERFLOW;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
			goto f_err;
#else
			decryption_failed_or_bad_record_mac = 1;
#endif
			}
		/* check the MAC for rr->input (it's in mac_size bytes at the tail) */
		if (rr->length >= (unsigned int)mac_size)
			{
			rr->length -= mac_size;
			mac = &rr->data[rr->length];
			}
		else
			{
			/* record (minus padding) is too short to contain a MAC */
#if 0 /* OK only for stream ciphers */
			al=SSL_AD_DECODE_ERROR;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
			goto f_err;
#else
			decryption_failed_or_bad_record_mac = 1;
			rr->length = 0;
#endif
			}
		i=s->method->ssl3_enc->mac(s,md,0);
		if (i < 0 || mac == NULL || memcmp(md, mac, (size_t)mac_size) != 0)
			{
			decryption_failed_or_bad_record_mac = 1;
			}
		}

	if (decryption_failed_or_bad_record_mac)
		{
		/* A separate 'decryption_failed' alert was introduced with TLS 1.0,
		 * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption
		 * failure is directly visible from the ciphertext anyway,
		 * we should not reveal which kind of error occured -- this
		 * might become visible to an attacker (e.g. via a logfile) */
		al=SSL_AD_BAD_RECORD_MAC;
		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
		goto f_err;
		}

	/* r->length is now just compressed */
	if (s->expand != NULL)
		{
		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra)
			{
			al=SSL_AD_RECORD_OVERFLOW;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
			goto f_err;
			}
		if (!ssl3_do_uncompress(s))
			{
			al=SSL_AD_DECOMPRESSION_FAILURE;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_DECOMPRESSION);
			goto f_err;
			}
		}

	if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH+extra)
		{
		al=SSL_AD_RECORD_OVERFLOW;
		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
		goto f_err;
		}

	rr->off=0;
	/* So at this point the following is true
	 * ssl->s3->rrec.type 	is the type of record
	 * ssl->s3->rrec.length	== number of bytes in record
	 * ssl->s3->rrec.off	== offset to first valid byte
	 * ssl->s3->rrec.data	== where to take bytes from, increment
	 *			   after use :-).
	 */

	/* we have pulled in a full packet so zero things */
	s->packet_length=0;

	/* just read a 0 length packet */
	if (rr->length == 0) goto again;

#if 0
fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, rr->length);
#endif

	return(1);

f_err:
	ssl3_send_alert(s,SSL3_AL_FATAL,al);
err:
	return(ret);
	}


static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
	{
	int n;
	unsigned char mac[MAX_MAC_SIZE];
	unsigned char *p;
	int i;
	int mac_size;

 ssl2_read_again:
	if (SSL_in_init(s) && !s->in_handshake)
		{
		n=s->handshake_func(s);
		if (n < 0) return(n);
		if (n == 0)
			{
			SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_SSL_HANDSHAKE_FAILURE);
			return(-1);
			}
		}

	clear_sys_error();
	s->rwstate=SSL_NOTHING;
	if (len <= 0) return(len);

	if (s->s2->ract_data_length != 0) /* read from buffer */
		{
		if (len > s->s2->ract_data_length)
			n=s->s2->ract_data_length;
		else
			n=len;

		memcpy(buf,s->s2->ract_data,(unsigned int)n);
		if (!peek)
			{
			s->s2->ract_data_length-=n;
			s->s2->ract_data+=n;
			if (s->s2->ract_data_length == 0)
				s->rstate=SSL_ST_READ_HEADER;
			}

		return(n);
		}

	/* s->s2->ract_data_length == 0
	 *
	 * Fill the buffer, then goto ssl2_read_again.
	 */

	if (s->rstate == SSL_ST_READ_HEADER)
		{
		if (s->first_packet)
			{
			n=read_n(s,5,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0);
			if (n <= 0) return(n); /* error or non-blocking */
			s->first_packet=0;
			p=s->packet;
			if (!((p[0] & 0x80) && (
				(p[2] == SSL2_MT_CLIENT_HELLO) ||
				(p[2] == SSL2_MT_SERVER_HELLO))))
				{
				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_NON_SSLV2_INITIAL_PACKET);
				return(-1);
				}
			}
		else
			{
			n=read_n(s,2,SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2,0);
			if (n <= 0) return(n); /* error or non-blocking */
			}
		/* part read stuff */

		s->rstate=SSL_ST_READ_BODY;
		p=s->packet;
		/* Do header */
		/*s->s2->padding=0;*/
		s->s2->escape=0;
		s->s2->rlength=(((unsigned int)p[0])<<8)|((unsigned int)p[1]);
		if ((p[0] & TWO_BYTE_BIT))		/* Two byte header? */
			{
			s->s2->three_byte_header=0;
			s->s2->rlength&=TWO_BYTE_MASK;
			}
		else
			{
			s->s2->three_byte_header=1;
			s->s2->rlength&=THREE_BYTE_MASK;

			/* security >s2->escape */
			s->s2->escape=((p[0] & SEC_ESC_BIT))?1:0;
			}
		}

	if (s->rstate == SSL_ST_READ_BODY)
		{
		n=s->s2->rlength+2+s->s2->three_byte_header;
		if (n > (int)s->packet_length)
			{
			n-=s->packet_length;
			i=read_n(s,(unsigned int)n,(unsigned int)n,1);
			if (i <= 0) return(i); /* ERROR */
			}

		p= &(s->packet[2]);
		s->rstate=SSL_ST_READ_HEADER;
		if (s->s2->three_byte_header)
			s->s2->padding= *(p++);
		else	s->s2->padding=0;

		/* Data portion */
		if (s->s2->clear_text)
			{
			mac_size = 0;
			s->s2->mac_data=p;
			s->s2->ract_data=p;
			if (s->s2->padding)
				{
				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING);
				return(-1);
				}
			}
		else
			{
			mac_size=EVP_MD_CTX_size(s->read_hash);
			if (mac_size < 0)
				return -1;
			OPENSSL_assert(mac_size <= MAX_MAC_SIZE);
			s->s2->mac_data=p;
			s->s2->ract_data= &p[mac_size];
			if (s->s2->padding + mac_size > s->s2->rlength)
				{
				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_ILLEGAL_PADDING);
				return(-1);
				}
			}

		s->s2->ract_data_length=s->s2->rlength;
		/* added a check for length > max_size in case
		 * encryption was not turned on yet due to an error */
		if ((!s->s2->clear_text) &&
			(s->s2->rlength >= (unsigned int)mac_size))
			{
			ssl2_enc(s,0);
			s->s2->ract_data_length-=mac_size;
			ssl2_mac(s,mac,0);
			s->s2->ract_data_length-=s->s2->padding;
			if (	(memcmp(mac,s->s2->mac_data,
				(unsigned int)mac_size) != 0) ||
				(s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0))
				{
				SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE);
				return(-1);
				}
			}
		INC32(s->s2->read_sequence); /* expect next number */
		/* s->s2->ract_data is now available for processing */

		/* Possibly the packet that we just read had 0 actual data bytes.
		 * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.)
		 * In this case, returning 0 would be interpreted by the caller
		 * as indicating EOF, so it's not a good idea.  Instead, we just
		 * continue reading; thus ssl2_read_internal may have to process
		 * multiple packets before it can return.
		 *
		 * [Note that using select() for blocking sockets *never* guarantees
		 * that the next SSL_read will not block -- the available
		 * data may contain incomplete packets, and except for SSL 2,
		 * renegotiation can confuse things even more.] */

		goto ssl2_read_again; /* This should really be
		                       * "return ssl2_read(s,buf,len)",
		                       * but that would allow for
		                       * denial-of-service attacks if a
		                       * C compiler is used that does not
		                       * recognize end-recursion. */
		}
	else
		{
		SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_STATE);
			return(-1);
		}
	}


int qemuMonitorTextStartCPUs ( qemuMonitorPtr mon , virConnectPtr conn ) {
 char * reply ;
 if ( qemuMonitorTextCommandWithHandler ( mon , "cont" , qemuMonitorSendDiskPassphrase , conn , - 1 , & reply ) < 0 ) return - 1 ;
 VIR_FREE ( reply ) ;
 return 0 ;
 }


static void encode_frame_to_data_rate ( VP8_COMP * cpi , unsigned long * size , unsigned char * dest , unsigned char * dest_end , unsigned int * frame_flags ) {
 int Q ;
 int frame_over_shoot_limit ;
 int frame_under_shoot_limit ;
 int Loop = 0 ;
 int loop_count ;
 VP8_COMMON * cm = & cpi -> common ;
 int active_worst_qchanged = 0 ;
 # if ! ( CONFIG_REALTIME_ONLY ) int q_low ;
 int q_high ;
 int zbin_oq_high ;
 int zbin_oq_low = 0 ;
 int top_index ;
 int bottom_index ;
 int overshoot_seen = 0 ;
 int undershoot_seen = 0 ;
 # endif int drop_mark = ( int ) ( cpi -> oxcf . drop_frames_water_mark * cpi -> oxcf . optimal_buffer_level / 100 ) ;
 int drop_mark75 = drop_mark * 2 / 3 ;
 int drop_mark50 = drop_mark / 4 ;
 int drop_mark25 = drop_mark / 8 ;
 vp8_clear_system_state ( ) ;
 # if CONFIG_MULTITHREAD if ( cpi -> b_lpf_running ) {
 sem_wait ( & cpi -> h_event_end_lpf ) ;
 cpi -> b_lpf_running = 0 ;
 }
 # endif if ( cpi -> force_next_frame_intra ) {
 cm -> frame_type = KEY_FRAME ;
 cpi -> force_next_frame_intra = 0 ;
 }
 # if ! ( CONFIG_REALTIME_ONLY ) if ( cpi -> pass == 2 ) {
 if ( cpi -> common . refresh_alt_ref_frame ) {
 cpi -> per_frame_bandwidth = cpi -> twopass . gf_bits ;
 cpi -> target_bandwidth = ( int ) ( cpi -> twopass . gf_bits * cpi -> output_framerate ) ;
 }
 }
 else # endif cpi -> per_frame_bandwidth = ( int ) ( cpi -> target_bandwidth / cpi -> output_framerate ) ;
 cm -> copy_buffer_to_gf = 0 ;
 cm -> copy_buffer_to_arf = 0 ;
 cpi -> mb . zbin_over_quant = 0 ;
 cpi -> mb . zbin_mode_boost = 0 ;
 cpi -> mb . zbin_mode_boost_enabled = 1 ;
 if ( cpi -> pass == 2 ) {
 if ( cpi -> gfu_boost <= 400 ) {
 cpi -> mb . zbin_mode_boost_enabled = 0 ;
 }
 }
 if ( cpi -> source_alt_ref_active ) cpi -> common . ref_frame_sign_bias [ ALTREF_FRAME ] = 1 ;
 else cpi -> common . ref_frame_sign_bias [ ALTREF_FRAME ] = 0 ;
 if ( ( cm -> current_video_frame == 0 ) || ( cm -> frame_flags & FRAMEFLAGS_KEY ) || ( cpi -> oxcf . auto_key && ( cpi -> frames_since_key % cpi -> key_frame_frequency == 0 ) ) ) {
 cm -> frame_type = KEY_FRAME ;
 # if CONFIG_TEMPORAL_DENOISING if ( cpi -> oxcf . noise_sensitivity == 4 ) {
 vp8_denoiser_set_parameters ( & cpi -> denoiser , kDenoiserOnYUV ) ;
 }
 # endif }
 # if CONFIG_MULTI_RES_ENCODING if ( cpi -> oxcf . mr_encoder_id ) {
 LOWER_RES_FRAME_INFO * low_res_frame_info = ( LOWER_RES_FRAME_INFO * ) cpi -> oxcf . mr_low_res_mode_info ;
 cm -> frame_type = low_res_frame_info -> frame_type ;
 if ( cm -> frame_type != KEY_FRAME ) {
 cpi -> mr_low_res_mv_avail = 1 ;
 cpi -> mr_low_res_mv_avail &= ! ( low_res_frame_info -> is_frame_dropped ) ;
 if ( cpi -> ref_frame_flags & VP8_LAST_FRAME ) cpi -> mr_low_res_mv_avail &= ( cpi -> current_ref_frames [ LAST_FRAME ] == low_res_frame_info -> low_res_ref_frames [ LAST_FRAME ] ) ;
 if ( cpi -> ref_frame_flags & VP8_GOLD_FRAME ) cpi -> mr_low_res_mv_avail &= ( cpi -> current_ref_frames [ GOLDEN_FRAME ] == low_res_frame_info -> low_res_ref_frames [ GOLDEN_FRAME ] ) ;
 if ( cpi -> ref_frame_flags & VP8_ALTR_FRAME ) cpi -> mr_low_res_mv_avail &= ( cpi -> current_ref_frames [ ALTREF_FRAME ] == low_res_frame_info -> low_res_ref_frames [ ALTREF_FRAME ] ) ;
 }
 }
 # endif cpi -> closest_reference_frame = LAST_FRAME ;
 if ( cm -> frame_type != KEY_FRAME ) {
 int i ;
 MV_REFERENCE_FRAME closest_ref = INTRA_FRAME ;
 if ( cpi -> ref_frame_flags & VP8_LAST_FRAME ) {
 closest_ref = LAST_FRAME ;
 }
 else if ( cpi -> ref_frame_flags & VP8_GOLD_FRAME ) {
 closest_ref = GOLDEN_FRAME ;
 }
 else if ( cpi -> ref_frame_flags & VP8_ALTR_FRAME ) {
 closest_ref = ALTREF_FRAME ;
 }
 for ( i = 1 ;
 i <= 3 ;
 i ++ ) {
 vpx_ref_frame_type_t ref_frame_type = ( vpx_ref_frame_type_t ) ( ( i == 3 ) ? 4 : i ) ;
 if ( cpi -> ref_frame_flags & ref_frame_type ) {
 if ( ( cm -> current_video_frame - cpi -> current_ref_frames [ i ] ) < ( cm -> current_video_frame - cpi -> current_ref_frames [ closest_ref ] ) ) {
 closest_ref = i ;
 }
 }
 }
 cpi -> closest_reference_frame = closest_ref ;
 }
 if ( cm -> frame_type == KEY_FRAME ) {
 int i ;
 setup_features ( cpi ) ;
 cpi -> source_alt_ref_active = 0 ;
 for ( i = 0 ;
 i < MAX_MODES ;
 i ++ ) {
 cpi -> mb . rd_thresh_mult [ i ] = 128 ;
 }
 vpx_memset ( cpi -> consec_zero_last , 0 , cm -> mb_rows * cm -> mb_cols ) ;
 }
 # if 0 {
 cpi -> one_pass_frame_index = cm -> current_video_frame % MAX_LAG_BUFFERS ;
 cpi -> one_pass_frame_stats [ cpi -> one_pass_frame_index ] . frames_so_far = 0 ;
 cpi -> one_pass_frame_stats [ cpi -> one_pass_frame_index ] . frame_intra_error = 0.0 ;
 cpi -> one_pass_frame_stats [ cpi -> one_pass_frame_index ] . frame_coded_error = 0.0 ;
 cpi -> one_pass_frame_stats [ cpi -> one_pass_frame_index ] . frame_pcnt_inter = 0.0 ;
 cpi -> one_pass_frame_stats [ cpi -> one_pass_frame_index ] . frame_pcnt_motion = 0.0 ;
 cpi -> one_pass_frame_stats [ cpi -> one_pass_frame_index ] . frame_mvr = 0.0 ;
 cpi -> one_pass_frame_stats [ cpi -> one_pass_frame_index ] . frame_mvr_abs = 0.0 ;
 cpi -> one_pass_frame_stats [ cpi -> one_pass_frame_index ] . frame_mvc = 0.0 ;
 cpi -> one_pass_frame_stats [ cpi -> one_pass_frame_index ] . frame_mvc_abs = 0.0 ;
 }
 # endif update_rd_ref_frame_probs ( cpi ) ;
 if ( cpi -> drop_frames_allowed ) {
 if ( ( cpi -> buffer_level > drop_mark ) && ( cpi -> decimation_factor > 0 ) ) cpi -> decimation_factor -- ;
 if ( cpi -> buffer_level > drop_mark75 && cpi -> decimation_factor > 0 ) cpi -> decimation_factor = 1 ;
 else if ( cpi -> buffer_level < drop_mark25 && ( cpi -> decimation_factor == 2 || cpi -> decimation_factor == 3 ) ) {
 cpi -> decimation_factor = 3 ;
 }
 else if ( cpi -> buffer_level < drop_mark50 && ( cpi -> decimation_factor == 1 || cpi -> decimation_factor == 2 ) ) {
 cpi -> decimation_factor = 2 ;
 }
 else if ( cpi -> buffer_level < drop_mark75 && ( cpi -> decimation_factor == 0 || cpi -> decimation_factor == 1 ) ) {
 cpi -> decimation_factor = 1 ;
 }
 }
 if ( cpi -> decimation_factor > 0 ) {
 switch ( cpi -> decimation_factor ) {
 case 1 : cpi -> per_frame_bandwidth = cpi -> per_frame_bandwidth * 3 / 2 ;
 break ;
 case 2 : cpi -> per_frame_bandwidth = cpi -> per_frame_bandwidth * 5 / 4 ;
 break ;
 case 3 : cpi -> per_frame_bandwidth = cpi -> per_frame_bandwidth * 5 / 4 ;
 break ;
 }
 if ( cm -> frame_type == KEY_FRAME ) {
 cpi -> decimation_count = cpi -> decimation_factor ;
 }
 else if ( cpi -> decimation_count > 0 ) {
 cpi -> decimation_count -- ;
 cpi -> bits_off_target += cpi -> av_per_frame_bandwidth ;
 if ( cpi -> bits_off_target > cpi -> oxcf . maximum_buffer_size ) cpi -> bits_off_target = cpi -> oxcf . maximum_buffer_size ;
 # if CONFIG_MULTI_RES_ENCODING vp8_store_drop_frame_info ( cpi ) ;
 # endif cm -> current_video_frame ++ ;
 cpi -> frames_since_key ++ ;
 cpi -> temporal_pattern_counter ++ ;
 # if CONFIG_INTERNAL_STATS cpi -> count ++ ;
 # endif cpi -> buffer_level = cpi -> bits_off_target ;
 if ( cpi -> oxcf . number_of_layers > 1 ) {
 unsigned int i ;
 for ( i = cpi -> current_layer + 1 ;
 i < cpi -> oxcf . number_of_layers ;
 i ++ ) {
 LAYER_CONTEXT * lc = & cpi -> layer_context [ i ] ;
 lc -> bits_off_target += ( int ) ( lc -> target_bandwidth / lc -> framerate ) ;
 if ( lc -> bits_off_target > lc -> maximum_buffer_size ) lc -> bits_off_target = lc -> maximum_buffer_size ;
 lc -> buffer_level = lc -> bits_off_target ;
 }
 }
 return ;
 }
 else cpi -> decimation_count = cpi -> decimation_factor ;
 }
 else cpi -> decimation_count = 0 ;
 if ( ! vp8_pick_frame_size ( cpi ) ) {
 # if CONFIG_MULTI_RES_ENCODING vp8_store_drop_frame_info ( cpi ) ;
 # endif cm -> current_video_frame ++ ;
 cpi -> frames_since_key ++ ;
 cpi -> temporal_pattern_counter ++ ;
 return ;
 }
 if ( ( cpi -> oxcf . end_usage == USAGE_STREAM_FROM_SERVER ) && ( cpi -> buffer_level >= cpi -> oxcf . optimal_buffer_level ) && cpi -> buffered_mode ) {
 int Adjustment = cpi -> active_worst_quality / 4 ;
 if ( Adjustment ) {
 int buff_lvl_step ;
 if ( cpi -> buffer_level < cpi -> oxcf . maximum_buffer_size ) {
 buff_lvl_step = ( int ) ( ( cpi -> oxcf . maximum_buffer_size - cpi -> oxcf . optimal_buffer_level ) / Adjustment ) ;
 if ( buff_lvl_step ) Adjustment = ( int ) ( ( cpi -> buffer_level - cpi -> oxcf . optimal_buffer_level ) / buff_lvl_step ) ;
 else Adjustment = 0 ;
 }
 cpi -> active_worst_quality -= Adjustment ;
 if ( cpi -> active_worst_quality < cpi -> active_best_quality ) cpi -> active_worst_quality = cpi -> active_best_quality ;
 }
 }
 if ( ( cpi -> pass == 2 ) || ( cpi -> ni_frames > 150 ) ) {
 vp8_clear_system_state ( ) ;
 Q = cpi -> active_worst_quality ;
 if ( cm -> frame_type == KEY_FRAME ) {
 if ( cpi -> pass == 2 ) {
 if ( cpi -> gfu_boost > 600 ) cpi -> active_best_quality = kf_low_motion_minq [ Q ] ;
 else cpi -> active_best_quality = kf_high_motion_minq [ Q ] ;
 if ( cpi -> this_key_frame_forced ) {
 if ( cpi -> active_best_quality > cpi -> avg_frame_qindex * 7 / 8 ) cpi -> active_best_quality = cpi -> avg_frame_qindex * 7 / 8 ;
 else if ( cpi -> active_best_quality < cpi -> avg_frame_qindex >> 2 ) cpi -> active_best_quality = cpi -> avg_frame_qindex >> 2 ;
 }
 }
 else cpi -> active_best_quality = kf_high_motion_minq [ Q ] ;
 }
 else if ( cpi -> oxcf . number_of_layers == 1 && ( cm -> refresh_golden_frame || cpi -> common . refresh_alt_ref_frame ) ) {
 if ( ( cpi -> frames_since_key > 1 ) && ( cpi -> avg_frame_qindex < cpi -> active_worst_quality ) ) {
 Q = cpi -> avg_frame_qindex ;
 }
 if ( ( cpi -> oxcf . end_usage == USAGE_CONSTRAINED_QUALITY ) && ( Q < cpi -> cq_target_quality ) ) {
 Q = cpi -> cq_target_quality ;
 }
 if ( cpi -> pass == 2 ) {
 if ( cpi -> gfu_boost > 1000 ) cpi -> active_best_quality = gf_low_motion_minq [ Q ] ;
 else if ( cpi -> gfu_boost < 400 ) cpi -> active_best_quality = gf_high_motion_minq [ Q ] ;
 else cpi -> active_best_quality = gf_mid_motion_minq [ Q ] ;
 if ( cpi -> oxcf . end_usage == USAGE_CONSTRAINED_QUALITY ) {
 cpi -> active_best_quality = cpi -> active_best_quality * 15 / 16 ;
 }
 }
 else cpi -> active_best_quality = gf_high_motion_minq [ Q ] ;
 }
 else {
 cpi -> active_best_quality = inter_minq [ Q ] ;
 if ( ( cpi -> oxcf . end_usage == USAGE_CONSTRAINED_QUALITY ) && ( cpi -> active_best_quality < cpi -> cq_target_quality ) ) {
 if ( cpi -> rolling_actual_bits < cpi -> min_frame_bandwidth ) cpi -> active_best_quality = cpi -> oxcf . cq_level ;
 else cpi -> active_best_quality = cpi -> cq_target_quality ;
 }
 }
 if ( cpi -> oxcf . end_usage == USAGE_STREAM_FROM_SERVER ) {
 if ( cpi -> buffer_level >= cpi -> oxcf . maximum_buffer_size ) cpi -> active_best_quality = cpi -> best_quality ;
 else if ( cpi -> buffer_level > cpi -> oxcf . optimal_buffer_level ) {
 int Fraction = ( int ) ( ( ( cpi -> buffer_level - cpi -> oxcf . optimal_buffer_level ) * 128 ) / ( cpi -> oxcf . maximum_buffer_size - cpi -> oxcf . optimal_buffer_level ) ) ;
 int min_qadjustment = ( ( cpi -> active_best_quality - cpi -> best_quality ) * Fraction ) / 128 ;
 cpi -> active_best_quality -= min_qadjustment ;
 }
 }
 }
 else if ( cpi -> oxcf . end_usage == USAGE_CONSTRAINED_QUALITY ) {
 if ( ( cm -> frame_type == KEY_FRAME ) || cm -> refresh_golden_frame || cpi -> common . refresh_alt_ref_frame ) {
 cpi -> active_best_quality = cpi -> best_quality ;
 }
 else if ( cpi -> active_best_quality < cpi -> cq_target_quality ) {
 cpi -> active_best_quality = cpi -> cq_target_quality ;
 }
 }
 if ( cpi -> active_worst_quality > cpi -> worst_quality ) cpi -> active_worst_quality = cpi -> worst_quality ;
 if ( cpi -> active_best_quality < cpi -> best_quality ) cpi -> active_best_quality = cpi -> best_quality ;
 if ( cpi -> active_worst_quality < cpi -> active_best_quality ) cpi -> active_worst_quality = cpi -> active_best_quality ;
 Q = vp8_regulate_q ( cpi , cpi -> this_frame_target ) ;
 # if ! ( CONFIG_REALTIME_ONLY ) if ( cm -> frame_type == KEY_FRAME ) zbin_oq_high = 0 ;
 else if ( ( cpi -> oxcf . number_of_layers == 1 ) && ( ( cm -> refresh_alt_ref_frame || ( cm -> refresh_golden_frame && ! cpi -> source_alt_ref_active ) ) ) ) {
 zbin_oq_high = 16 ;
 }
 else zbin_oq_high = ZBIN_OQ_MAX ;
 # endif if ( cpi -> cyclic_refresh_mode_enabled ) {
 if ( cpi -> current_layer == 0 ) cyclic_background_refresh ( cpi , Q , 0 ) ;
 else disable_segmentation ( cpi ) ;
 }
 vp8_compute_frame_size_bounds ( cpi , & frame_under_shoot_limit , & frame_over_shoot_limit ) ;
 # if ! ( CONFIG_REALTIME_ONLY ) bottom_index = cpi -> active_best_quality ;
 top_index = cpi -> active_worst_quality ;
 q_low = cpi -> active_best_quality ;
 q_high = cpi -> active_worst_quality ;
 # endif vp8_save_coding_context ( cpi ) ;
 loop_count = 0 ;
 scale_and_extend_source ( cpi -> un_scaled_source , cpi ) ;
 # if ! ( CONFIG_REALTIME_ONLY ) && CONFIG_POSTPROC && ! ( CONFIG_TEMPORAL_DENOISING ) if ( cpi -> oxcf . noise_sensitivity > 0 ) {
 unsigned char * src ;
 int l = 0 ;
 switch ( cpi -> oxcf . noise_sensitivity ) {
 case 1 : l = 20 ;
 break ;
 case 2 : l = 40 ;
 break ;
 case 3 : l = 60 ;
 break ;
 case 4 : l = 80 ;
 break ;
 case 5 : l = 100 ;
 break ;
 case 6 : l = 150 ;
 break ;
 }
 if ( cm -> frame_type == KEY_FRAME ) {
 vp8_de_noise ( cm , cpi -> Source , cpi -> Source , l , 1 , 0 ) ;
 }
 else {
 vp8_de_noise ( cm , cpi -> Source , cpi -> Source , l , 1 , 0 ) ;
 src = cpi -> Source -> y_buffer ;
 if ( cpi -> Source -> y_stride < 0 ) {
 src += cpi -> Source -> y_stride * ( cpi -> Source -> y_height - 1 ) ;
 }
 }
 }
 # endif # ifdef OUTPUT_YUV_SRC vp8_write_yuv_frame ( yuv_file , cpi -> Source ) ;
 # endif do {
 vp8_clear_system_state ( ) ;
 vp8_set_quantizer ( cpi , Q ) ;
 if ( cpi -> common . mb_no_coeff_skip ) {
 cpi -> prob_skip_false = cpi -> base_skip_false_prob [ Q ] ;
 if ( cm -> frame_type != KEY_FRAME ) {
 if ( cpi -> common . refresh_alt_ref_frame ) {
 if ( cpi -> last_skip_false_probs [ 2 ] != 0 ) cpi -> prob_skip_false = cpi -> last_skip_false_probs [ 2 ] ;
 }
 else if ( cpi -> common . refresh_golden_frame ) {
 if ( cpi -> last_skip_false_probs [ 1 ] != 0 ) cpi -> prob_skip_false = cpi -> last_skip_false_probs [ 1 ] ;
 }
 else {
 if ( cpi -> last_skip_false_probs [ 0 ] != 0 ) cpi -> prob_skip_false = cpi -> last_skip_false_probs [ 0 ] ;
 }
 if ( cpi -> prob_skip_false < 5 ) cpi -> prob_skip_false = 5 ;
 if ( cpi -> prob_skip_false > 250 ) cpi -> prob_skip_false = 250 ;
 if ( cpi -> oxcf . number_of_layers == 1 && cpi -> is_src_frame_alt_ref ) cpi -> prob_skip_false = 1 ;
 }
 # if 0 if ( cpi -> pass != 1 ) {
 FILE * f = fopen ( "skip.stt" , "a" ) ;
 fprintf ( f , "%d, %d, %4d " , cpi -> common . refresh_golden_frame , cpi -> common . refresh_alt_ref_frame , cpi -> prob_skip_false ) ;
 fclose ( f ) ;
 }
 # endif }
 if ( cm -> frame_type == KEY_FRAME ) {
 if ( resize_key_frame ( cpi ) ) {
 Q = vp8_regulate_q ( cpi , cpi -> this_frame_target ) ;
 if ( cpi -> cyclic_refresh_mode_enabled ) {
 if ( cpi -> current_layer == 0 ) cyclic_background_refresh ( cpi , Q , 0 ) ;
 else disable_segmentation ( cpi ) ;
 }
 vpx_memset ( cpi -> consec_zero_last , 0 , cm -> mb_rows * cm -> mb_cols ) ;
 vp8_set_quantizer ( cpi , Q ) ;
 }
 vp8_setup_key_frame ( cpi ) ;
 }
 # if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING {
 if ( cpi -> oxcf . error_resilient_mode ) cm -> refresh_entropy_probs = 0 ;
 if ( cpi -> oxcf . error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS ) {
 if ( cm -> frame_type == KEY_FRAME ) cm -> refresh_entropy_probs = 1 ;
 }
 if ( cm -> refresh_entropy_probs == 0 ) {
 vpx_memcpy ( & cm -> lfc , & cm -> fc , sizeof ( cm -> fc ) ) ;
 }
 vp8_update_coef_context ( cpi ) ;
 vp8_update_coef_probs ( cpi ) ;
 vp8_encode_frame ( cpi ) ;
 }
 # else vp8_encode_frame ( cpi ) ;
 cpi -> projected_frame_size -= vp8_estimate_entropy_savings ( cpi ) ;
 cpi -> projected_frame_size = ( cpi -> projected_frame_size > 0 ) ? cpi -> projected_frame_size : 0 ;
 # endif vp8_clear_system_state ( ) ;
 if ( cpi -> pass != 2 && cpi -> oxcf . auto_key && cm -> frame_type != KEY_FRAME && cpi -> compressor_speed != 2 ) {
 # if ! ( CONFIG_REALTIME_ONLY ) if ( decide_key_frame ( cpi ) ) {
 cm -> frame_type = KEY_FRAME ;
 vp8_pick_frame_size ( cpi ) ;
 cpi -> source_alt_ref_active = 0 ;
 setup_features ( cpi ) ;
 vp8_restore_coding_context ( cpi ) ;
 Q = vp8_regulate_q ( cpi , cpi -> this_frame_target ) ;
 vp8_compute_frame_size_bounds ( cpi , & frame_under_shoot_limit , & frame_over_shoot_limit ) ;
 bottom_index = cpi -> active_best_quality ;
 top_index = cpi -> active_worst_quality ;
 q_low = cpi -> active_best_quality ;
 q_high = cpi -> active_worst_quality ;
 loop_count ++ ;
 Loop = 1 ;
 continue ;
 }
 # endif }
 vp8_clear_system_state ( ) ;
 if ( frame_over_shoot_limit == 0 ) frame_over_shoot_limit = 1 ;
 if ( ( ( cpi -> pass != 2 ) || ( cpi -> oxcf . end_usage == USAGE_STREAM_FROM_SERVER ) ) && ( Q == cpi -> active_worst_quality ) && ( cpi -> active_worst_quality < cpi -> worst_quality ) && ( cpi -> projected_frame_size > frame_over_shoot_limit ) ) {
 int over_size_percent = ( ( cpi -> projected_frame_size - frame_over_shoot_limit ) * 100 ) / frame_over_shoot_limit ;
 while ( ( cpi -> active_worst_quality < cpi -> worst_quality ) && ( over_size_percent > 0 ) ) {
 cpi -> active_worst_quality ++ ;
 over_size_percent = ( int ) ( over_size_percent * 0.96 ) ;
 }
 # if ! ( CONFIG_REALTIME_ONLY ) top_index = cpi -> active_worst_quality ;
 # endif active_worst_qchanged = 1 ;
 }
 else active_worst_qchanged = 0 ;
 # if ! ( CONFIG_REALTIME_ONLY ) if ( ( cm -> frame_type == KEY_FRAME ) && cpi -> this_key_frame_forced ) {
 int last_q = Q ;
 int kf_err = vp8_calc_ss_err ( cpi -> Source , & cm -> yv12_fb [ cm -> new_fb_idx ] ) ;
 if ( kf_err > ( ( cpi -> ambient_err * 7 ) >> 3 ) ) {
 q_high = ( Q > q_low ) ? ( Q - 1 ) : q_low ;
 Q = ( q_high + q_low ) >> 1 ;
 }
 else if ( kf_err < ( cpi -> ambient_err >> 1 ) ) {
 q_low = ( Q < q_high ) ? ( Q + 1 ) : q_high ;
 Q = ( q_high + q_low + 1 ) >> 1 ;
 }
 if ( Q > q_high ) Q = q_high ;
 else if ( Q < q_low ) Q = q_low ;
 Loop = Q != last_q ;
 }
 else if ( recode_loop_test ( cpi , frame_over_shoot_limit , frame_under_shoot_limit , Q , top_index , bottom_index ) ) {
 int last_q = Q ;
 int Retries = 0 ;
 if ( cpi -> projected_frame_size > cpi -> this_frame_target ) {
 q_low = ( Q < q_high ) ? ( Q + 1 ) : q_high ;
 if ( cpi -> mb . zbin_over_quant > 0 ) zbin_oq_low = ( cpi -> mb . zbin_over_quant < zbin_oq_high ) ? ( cpi -> mb . zbin_over_quant + 1 ) : zbin_oq_high ;
 if ( undershoot_seen ) {
 if ( ! active_worst_qchanged ) vp8_update_rate_correction_factors ( cpi , 1 ) ;
 Q = ( q_high + q_low + 1 ) / 2 ;
 if ( Q < MAXQ ) cpi -> mb . zbin_over_quant = 0 ;
 else {
 zbin_oq_low = ( cpi -> mb . zbin_over_quant < zbin_oq_high ) ? ( cpi -> mb . zbin_over_quant + 1 ) : zbin_oq_high ;
 cpi -> mb . zbin_over_quant = ( zbin_oq_high + zbin_oq_low ) / 2 ;
 }
 }
 else {
 if ( ! active_worst_qchanged ) vp8_update_rate_correction_factors ( cpi , 0 ) ;
 Q = vp8_regulate_q ( cpi , cpi -> this_frame_target ) ;
 while ( ( ( Q < q_low ) || ( cpi -> mb . zbin_over_quant < zbin_oq_low ) ) && ( Retries < 10 ) ) {
 vp8_update_rate_correction_factors ( cpi , 0 ) ;
 Q = vp8_regulate_q ( cpi , cpi -> this_frame_target ) ;
 Retries ++ ;
 }
 }
 overshoot_seen = 1 ;
 }
 else {
 if ( cpi -> mb . zbin_over_quant == 0 ) q_high = ( Q > q_low ) ? ( Q - 1 ) : q_low ;
 else zbin_oq_high = ( cpi -> mb . zbin_over_quant > zbin_oq_low ) ? ( cpi -> mb . zbin_over_quant - 1 ) : zbin_oq_low ;
 if ( overshoot_seen ) {
 if ( ! active_worst_qchanged ) vp8_update_rate_correction_factors ( cpi , 1 ) ;
 Q = ( q_high + q_low ) / 2 ;
 if ( Q < MAXQ ) cpi -> mb . zbin_over_quant = 0 ;
 else cpi -> mb . zbin_over_quant = ( zbin_oq_high + zbin_oq_low ) / 2 ;
 }
 else {
 if ( ! active_worst_qchanged ) vp8_update_rate_correction_factors ( cpi , 0 ) ;
 Q = vp8_regulate_q ( cpi , cpi -> this_frame_target ) ;
 if ( ( cpi -> oxcf . end_usage == USAGE_CONSTRAINED_QUALITY ) && ( Q < q_low ) ) {
 q_low = Q ;
 }
 while ( ( ( Q > q_high ) || ( cpi -> mb . zbin_over_quant > zbin_oq_high ) ) && ( Retries < 10 ) ) {
 vp8_update_rate_correction_factors ( cpi , 0 ) ;
 Q = vp8_regulate_q ( cpi , cpi -> this_frame_target ) ;
 Retries ++ ;
 }
 }
 undershoot_seen = 1 ;
 }
 if ( Q > q_high ) Q = q_high ;
 else if ( Q < q_low ) Q = q_low ;
 cpi -> mb . zbin_over_quant = ( cpi -> mb . zbin_over_quant < zbin_oq_low ) ? zbin_oq_low : ( cpi -> mb . zbin_over_quant > zbin_oq_high ) ? zbin_oq_high : cpi -> mb . zbin_over_quant ;
 Loop = Q != last_q ;
 }
 else # endif Loop = 0 ;
 if ( cpi -> is_src_frame_alt_ref ) Loop = 0 ;
 if ( Loop == 1 ) {
 vp8_restore_coding_context ( cpi ) ;
 loop_count ++ ;
 # if CONFIG_INTERNAL_STATS cpi -> tot_recode_hits ++ ;
 # endif }
 }
 while ( Loop == 1 ) ;
 # if 0 {
 cpi -> one_pass_frame_stats [ cpi -> one_pass_frame_index ] . frame_coded_error = ( double ) cpi -> prediction_error ;
 cpi -> one_pass_frame_stats [ cpi -> one_pass_frame_index ] . frame_intra_error = ( double ) cpi -> intra_error ;
 cpi -> one_pass_frame_stats [ cpi -> one_pass_frame_index ] . frame_pcnt_inter = ( double ) ( 100 - cpi -> this_frame_percent_intra ) / 100.0 ;
 }
 # endif if ( cpi -> next_key_frame_forced && ( cpi -> twopass . frames_to_key == 0 ) ) {
 cpi -> ambient_err = vp8_calc_ss_err ( cpi -> Source , & cm -> yv12_fb [ cm -> new_fb_idx ] ) ;
 }
 # if CONFIG_MULTI_RES_ENCODING if ( ! cpi -> oxcf . mr_encoder_id && cm -> show_frame ) # else if ( cm -> show_frame ) # endif {
 int mb_row ;
 int mb_col ;
 MODE_INFO * tmp = cm -> mip ;
 if ( cm -> frame_type != KEY_FRAME ) {
 for ( mb_row = 0 ;
 mb_row < cm -> mb_rows + 1 ;
 mb_row ++ ) {
 for ( mb_col = 0 ;
 mb_col < cm -> mb_cols + 1 ;
 mb_col ++ ) {
 if ( tmp -> mbmi . ref_frame != INTRA_FRAME ) cpi -> lfmv [ mb_col + mb_row * ( cm -> mode_info_stride + 1 ) ] . as_int = tmp -> mbmi . mv . as_int ;
 cpi -> lf_ref_frame_sign_bias [ mb_col + mb_row * ( cm -> mode_info_stride + 1 ) ] = cm -> ref_frame_sign_bias [ tmp -> mbmi . ref_frame ] ;
 cpi -> lf_ref_frame [ mb_col + mb_row * ( cm -> mode_info_stride + 1 ) ] = tmp -> mbmi . ref_frame ;
 tmp ++ ;
 }
 }
 }
 }
 {
 int mb_row ;
 int mb_col ;
 MODE_INFO * tmp = cm -> mi ;
 cpi -> zeromv_count = 0 ;
 if ( cm -> frame_type != KEY_FRAME ) {
 for ( mb_row = 0 ;
 mb_row < cm -> mb_rows ;
 mb_row ++ ) {
 for ( mb_col = 0 ;
 mb_col < cm -> mb_cols ;
 mb_col ++ ) {
 if ( tmp -> mbmi . mode == ZEROMV && tmp -> mbmi . ref_frame == LAST_FRAME ) cpi -> zeromv_count ++ ;
 tmp ++ ;
 }
 tmp ++ ;
 }
 }
 }
 # if CONFIG_MULTI_RES_ENCODING vp8_cal_dissimilarity ( cpi ) ;
 # endif if ( cpi -> oxcf . number_of_layers == 1 ) vp8_update_gf_useage_maps ( cpi , cm , & cpi -> mb ) ;
 if ( cm -> frame_type == KEY_FRAME ) cm -> refresh_last_frame = 1 ;
 # if 0 {
 FILE * f = fopen ( "gfactive.stt" , "a" ) ;
 fprintf ( f , "%8d %8d %8d %8d %8d\n" , cm -> current_video_frame , ( 100 * cpi -> gf_active_count ) / ( cpi -> common . mb_rows * cpi -> common . mb_cols ) , cpi -> this_iiratio , cpi -> next_iiratio , cm -> refresh_golden_frame ) ;
 fclose ( f ) ;
 }
 # endif if ( ! cpi -> oxcf . error_resilient_mode && cm -> refresh_golden_frame ) cm -> copy_buffer_to_arf = 2 ;
 else cm -> copy_buffer_to_arf = 0 ;
 cm -> frame_to_show = & cm -> yv12_fb [ cm -> new_fb_idx ] ;
 # if CONFIG_TEMPORAL_DENOISING if ( cpi -> oxcf . noise_sensitivity == 4 && cpi -> frames_since_key % 8 == 0 && cm -> frame_type != KEY_FRAME ) {
 process_denoiser_mode_change ( cpi ) ;
 }
 # endif # if CONFIG_MULTITHREAD if ( cpi -> b_multi_threaded ) {
 sem_post ( & cpi -> h_event_start_lpf ) ;
 cpi -> b_lpf_running = 1 ;
 }
 else # endif {
 vp8_loopfilter_frame ( cpi , cm ) ;
 }
 update_reference_frames ( cpi ) ;
 # ifdef OUTPUT_YUV_DENOISED vp8_write_yuv_frame ( yuv_denoised_file , & cpi -> denoiser . yv12_running_avg [ INTRA_FRAME ] ) ;
 # endif # if ! ( CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING ) if ( cpi -> oxcf . error_resilient_mode ) {
 cm -> refresh_entropy_probs = 0 ;
 }
 # endif # if CONFIG_MULTITHREAD if ( cpi -> b_multi_threaded ) sem_wait ( & cpi -> h_event_end_lpf ) ;
 # endif vp8_pack_bitstream ( cpi , dest , dest_end , size ) ;
 # if CONFIG_MULTITHREAD if ( cpi -> b_lpf_running && cpi -> b_calculate_psnr ) {
 sem_wait ( & cpi -> h_event_end_lpf ) ;
 cpi -> b_lpf_running = 0 ;
 }
 # endif cm -> last_frame_type = cm -> frame_type ;
 cpi -> total_byte_count += ( * size ) ;
 cpi -> projected_frame_size = ( * size ) << 3 ;
 if ( cpi -> oxcf . number_of_layers > 1 ) {
 unsigned int i ;
 for ( i = cpi -> current_layer + 1 ;
 i < cpi -> oxcf . number_of_layers ;
 i ++ ) cpi -> layer_context [ i ] . total_byte_count += ( * size ) ;
 }
 if ( ! active_worst_qchanged ) vp8_update_rate_correction_factors ( cpi , 2 ) ;
 cpi -> last_q [ cm -> frame_type ] = cm -> base_qindex ;
 if ( cm -> frame_type == KEY_FRAME ) {
 vp8_adjust_key_frame_context ( cpi ) ;
 }
 if ( cm -> frame_type != KEY_FRAME ) cpi -> avg_frame_qindex = ( 2 + 3 * cpi -> avg_frame_qindex + cm -> base_qindex ) >> 2 ;
 if ( ( cm -> frame_type != KEY_FRAME ) && ( ( cpi -> oxcf . number_of_layers > 1 ) || ( ! cm -> refresh_golden_frame && ! cm -> refresh_alt_ref_frame ) ) ) {
 cpi -> ni_frames ++ ;
 if ( cpi -> pass == 2 ) {
 cpi -> ni_tot_qi += Q ;
 cpi -> ni_av_qi = ( cpi -> ni_tot_qi / cpi -> ni_frames ) ;
 }
 else {
 if ( cpi -> ni_frames > 150 ) {
 cpi -> ni_tot_qi += Q ;
 cpi -> ni_av_qi = ( cpi -> ni_tot_qi / cpi -> ni_frames ) ;
 }
 else {
 cpi -> ni_tot_qi += Q ;
 cpi -> ni_av_qi = ( ( cpi -> ni_tot_qi / cpi -> ni_frames ) + cpi -> worst_quality + 1 ) / 2 ;
 }
 if ( Q > cpi -> ni_av_qi ) cpi -> ni_av_qi = Q - 1 ;
 }
 }
 if ( ! cm -> show_frame ) cpi -> bits_off_target -= cpi -> projected_frame_size ;
 else cpi -> bits_off_target += cpi -> av_per_frame_bandwidth - cpi -> projected_frame_size ;
 if ( cpi -> bits_off_target > cpi -> oxcf . maximum_buffer_size ) cpi -> bits_off_target = cpi -> oxcf . maximum_buffer_size ;
 cpi -> rolling_target_bits = ( ( cpi -> rolling_target_bits * 3 ) + cpi -> this_frame_target + 2 ) / 4 ;
 cpi -> rolling_actual_bits = ( ( cpi -> rolling_actual_bits * 3 ) + cpi -> projected_frame_size + 2 ) / 4 ;
 cpi -> long_rolling_target_bits = ( ( cpi -> long_rolling_target_bits * 31 ) + cpi -> this_frame_target + 16 ) / 32 ;
 cpi -> long_rolling_actual_bits = ( ( cpi -> long_rolling_actual_bits * 31 ) + cpi -> projected_frame_size + 16 ) / 32 ;
 cpi -> total_actual_bits += cpi -> projected_frame_size ;
 cpi -> total_target_vs_actual += ( cpi -> this_frame_target - cpi -> projected_frame_size ) ;
 cpi -> buffer_level = cpi -> bits_off_target ;
 if ( cpi -> oxcf . number_of_layers > 1 ) {
 unsigned int i ;
 for ( i = cpi -> current_layer + 1 ;
 i < cpi -> oxcf . number_of_layers ;
 i ++ ) {
 LAYER_CONTEXT * lc = & cpi -> layer_context [ i ] ;
 int bits_off_for_this_layer = ( int ) ( lc -> target_bandwidth / lc -> framerate - cpi -> projected_frame_size ) ;
 lc -> bits_off_target += bits_off_for_this_layer ;
 if ( lc -> bits_off_target > lc -> maximum_buffer_size ) lc -> bits_off_target = lc -> maximum_buffer_size ;
 lc -> total_actual_bits += cpi -> projected_frame_size ;
 lc -> total_target_vs_actual += bits_off_for_this_layer ;
 lc -> buffer_level = lc -> bits_off_target ;
 }
 }
 if ( cm -> frame_type == KEY_FRAME ) {
 cpi -> twopass . kf_group_bits += cpi -> this_frame_target - cpi -> projected_frame_size ;
 if ( cpi -> twopass . kf_group_bits < 0 ) cpi -> twopass . kf_group_bits = 0 ;
 }
 else if ( cm -> refresh_golden_frame || cm -> refresh_alt_ref_frame ) {
 cpi -> twopass . gf_group_bits += cpi -> this_frame_target - cpi -> projected_frame_size ;
 if ( cpi -> twopass . gf_group_bits < 0 ) cpi -> twopass . gf_group_bits = 0 ;
 }
 if ( cm -> frame_type != KEY_FRAME ) {
 if ( cpi -> common . refresh_alt_ref_frame ) {
 cpi -> last_skip_false_probs [ 2 ] = cpi -> prob_skip_false ;
 cpi -> last_skip_probs_q [ 2 ] = cm -> base_qindex ;
 }
 else if ( cpi -> common . refresh_golden_frame ) {
 cpi -> last_skip_false_probs [ 1 ] = cpi -> prob_skip_false ;
 cpi -> last_skip_probs_q [ 1 ] = cm -> base_qindex ;
 }
 else {
 cpi -> last_skip_false_probs [ 0 ] = cpi -> prob_skip_false ;
 cpi -> last_skip_probs_q [ 0 ] = cm -> base_qindex ;
 cpi -> base_skip_false_prob [ cm -> base_qindex ] = cpi -> prob_skip_false ;
 }
 }
 # if 0 && CONFIG_INTERNAL_STATS {
 FILE * f = fopen ( "tmp.stt" , "a" ) ;
 vp8_clear_system_state ( ) ;
 if ( cpi -> twopass . total_left_stats . coded_error != 0.0 ) fprintf ( f , "%10d %10d %10d %10d %10d %10" PRId64 " %10" PRId64 "%10" PRId64 " %10d %6d %6d %6d %6d %5d %5d %5d %8d " "%8.2lf %" PRId64 " %10.3lf %10" PRId64 " %8d\n" , cpi -> common . current_video_frame , cpi -> this_frame_target , cpi -> projected_frame_size , ( cpi -> projected_frame_size - cpi -> this_frame_target ) , cpi -> total_target_vs_actual , cpi -> buffer_level , ( cpi -> oxcf . starting_buffer_level - cpi -> bits_off_target ) , cpi -> total_actual_bits , cm -> base_qindex , cpi -> active_best_quality , cpi -> active_worst_quality , cpi -> ni_av_qi , cpi -> cq_target_quality , cm -> refresh_golden_frame , cm -> refresh_alt_ref_frame , cm -> frame_type , cpi -> gfu_boost , cpi -> twopass . est_max_qcorrection_factor , cpi -> twopass . bits_left , cpi -> twopass . total_left_stats . coded_error , ( double ) cpi -> twopass . bits_left / cpi -> twopass . total_left_stats . coded_error , cpi -> tot_recode_hits ) ;
 else fprintf ( f , "%10d %10d %10d %10d %10d %10" PRId64 " %10" PRId64 "%10" PRId64 " %10d %6d %6d %6d %6d %5d %5d %5d %8d " "%8.2lf %" PRId64 " %10.3lf %8d\n" , cpi -> common . current_video_frame , cpi -> this_frame_target , cpi -> projected_frame_size , ( cpi -> projected_frame_size - cpi -> this_frame_target ) , cpi -> total_target_vs_actual , cpi -> buffer_level , ( cpi -> oxcf . starting_buffer_level - cpi -> bits_off_target ) , cpi -> total_actual_bits , cm -> base_qindex , cpi -> active_best_quality , cpi -> active_worst_quality , cpi -> ni_av_qi , cpi -> cq_target_quality , cm -> refresh_golden_frame , cm -> refresh_alt_ref_frame , cm -> frame_type , cpi -> gfu_boost , cpi -> twopass . est_max_qcorrection_factor , cpi -> twopass . bits_left , cpi -> twopass . total_left_stats . coded_error , cpi -> tot_recode_hits ) ;
 fclose ( f ) ;
 {
 FILE * fmodes = fopen ( "Modes.stt" , "a" ) ;
 fprintf ( fmodes , "%6d:%1d:%1d:%1d " , cpi -> common . current_video_frame , cm -> frame_type , cm -> refresh_golden_frame , cm -> refresh_alt_ref_frame ) ;
 fprintf ( fmodes , "\n" ) ;
 fclose ( fmodes ) ;
 }
 }
 # endif if ( cm -> refresh_golden_frame == 1 ) cm -> frame_flags = cm -> frame_flags | FRAMEFLAGS_GOLDEN ;
 else cm -> frame_flags = cm -> frame_flags & ~ FRAMEFLAGS_GOLDEN ;
 if ( cm -> refresh_alt_ref_frame == 1 ) cm -> frame_flags = cm -> frame_flags | FRAMEFLAGS_ALTREF ;
 else cm -> frame_flags = cm -> frame_flags & ~ FRAMEFLAGS_ALTREF ;
 if ( cm -> refresh_last_frame & cm -> refresh_golden_frame ) cpi -> gold_is_last = 1 ;
 else if ( cm -> refresh_last_frame ^ cm -> refresh_golden_frame ) cpi -> gold_is_last = 0 ;
 if ( cm -> refresh_last_frame & cm -> refresh_alt_ref_frame ) cpi -> alt_is_last = 1 ;
 else if ( cm -> refresh_last_frame ^ cm -> refresh_alt_ref_frame ) cpi -> alt_is_last = 0 ;
 if ( cm -> refresh_alt_ref_frame & cm -> refresh_golden_frame ) cpi -> gold_is_alt = 1 ;
 else if ( cm -> refresh_alt_ref_frame ^ cm -> refresh_golden_frame ) cpi -> gold_is_alt = 0 ;
 cpi -> ref_frame_flags = VP8_ALTR_FRAME | VP8_GOLD_FRAME | VP8_LAST_FRAME ;
 if ( cpi -> gold_is_last ) cpi -> ref_frame_flags &= ~ VP8_GOLD_FRAME ;
 if ( cpi -> alt_is_last ) cpi -> ref_frame_flags &= ~ VP8_ALTR_FRAME ;
 if ( cpi -> gold_is_alt ) cpi -> ref_frame_flags &= ~ VP8_ALTR_FRAME ;
 if ( ! cpi -> oxcf . error_resilient_mode ) {
 if ( cpi -> oxcf . play_alternate && cm -> refresh_alt_ref_frame && ( cm -> frame_type != KEY_FRAME ) ) update_alt_ref_frame_stats ( cpi ) ;
 else update_golden_frame_stats ( cpi ) ;
 }
 if ( cm -> frame_type == KEY_FRAME ) {
 * frame_flags = cm -> frame_flags | FRAMEFLAGS_KEY ;
 cm -> frame_type = INTER_FRAME ;
 cpi -> last_frame_percent_intra = 100 ;
 }
 else {
 * frame_flags = cm -> frame_flags & ~ FRAMEFLAGS_KEY ;
 cpi -> last_frame_percent_intra = cpi -> this_frame_percent_intra ;
 }
 cpi -> mb . e_mbd . update_mb_segmentation_map = 0 ;
 cpi -> mb . e_mbd . update_mb_segmentation_data = 0 ;
 cpi -> mb . e_mbd . mode_ref_lf_delta_update = 0 ;
 if ( cm -> show_frame ) {
 cm -> current_video_frame ++ ;
 cpi -> frames_since_key ++ ;
 cpi -> temporal_pattern_counter ++ ;
 }
 # if 0 {
 char filename [ 512 ] ;
 FILE * recon_file ;
 sprintf ( filename , "enc%04d.yuv" , ( int ) cm -> current_video_frame ) ;
 recon_file = fopen ( filename , "wb" ) ;
 fwrite ( cm -> yv12_fb [ cm -> lst_fb_idx ] . buffer_alloc , cm -> yv12_fb [ cm -> lst_fb_idx ] . frame_size , 1 , recon_file ) ;
 fclose ( recon_file ) ;
 }
 # endif }


void qemu_boot_set(const char *boot_order, Error **errp) { Error *local_err = NULL; if (!boot_set_handler) { error_setg(errp, "no function defined to set boot device list for" " this architecture"); return; } validate_bootdevices(boot_order, &local_err); if (local_err) { error_propagate(errp, local_err); return; } if (boot_set_handler(boot_set_opaque, boot_order)) { error_setg(errp, "setting boot device list failed"); return; } }


int dtls1_enc(SSL *s, int send)
	{
	SSL3_RECORD *rec;
	EVP_CIPHER_CTX *ds;
	unsigned long l;
	int bs,i,ii,j,k,n=0;
	const EVP_CIPHER *enc;

	if (send)
		{
		if (EVP_MD_CTX_md(s->write_hash))
			{
			n=EVP_MD_CTX_size(s->write_hash);
			if (n < 0)
				return -1;
			}
		ds=s->enc_write_ctx;
		rec= &(s->s3->wrec);
		if (s->enc_write_ctx == NULL)
			enc=NULL;
		else
			{
			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
			if ( rec->data != rec->input)
				/* we can't write into the input stream */
				fprintf(stderr, "%s:%d: rec->data != rec->input\n",
					__FILE__, __LINE__);
			else if ( EVP_CIPHER_block_size(ds->cipher) > 1)
				{
				if (RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)) <= 0)
					return -1;
				}
			}
		}
	else
		{
		if (EVP_MD_CTX_md(s->read_hash))
			{
			n=EVP_MD_CTX_size(s->read_hash);
			if (n < 0)
				return -1;
			}
		ds=s->enc_read_ctx;
		rec= &(s->s3->rrec);
		if (s->enc_read_ctx == NULL)
			enc=NULL;
		else
			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
		}

#ifdef KSSL_DEBUG
	printf("dtls1_enc(%d)\n", send);
#endif    /* KSSL_DEBUG */

	if ((s->session == NULL) || (ds == NULL) ||
		(enc == NULL))
		{
		memmove(rec->data,rec->input,rec->length);
		rec->input=rec->data;
		}
	else
		{
		l=rec->length;
		bs=EVP_CIPHER_block_size(ds->cipher);

		if ((bs != 1) && send)
			{
			i=bs-((int)l%bs);

			/* Add weird padding of upto 256 bytes */

			/* we need to add 'i' padding bytes of value j */
			j=i-1;
			if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
				{
				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
					j++;
				}
			for (k=(int)l; k<(int)(l+i); k++)
				rec->input[k]=j;
			l+=i;
			rec->length+=i;
			}

#ifdef KSSL_DEBUG
		{
                unsigned long ui;
		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
                        ds,rec->data,rec->input,l);
		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
                        ds->buf_len, ds->cipher->key_len,
                        DES_KEY_SZ, DES_SCHEDULE_SZ,
                        ds->cipher->iv_len);
		printf("\t\tIV: ");
		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
		printf("\n");
		printf("\trec->input=");
		for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
		printf("\n");
		}
#endif	/* KSSL_DEBUG */

		if (!send)
			{
			if (l == 0 || l%bs != 0)
				return -1;
			}

		EVP_Cipher(ds,rec->data,rec->input,l);

#ifdef KSSL_DEBUG
		{
                unsigned long i;
                printf("\trec->data=");
		for (i=0; i<l; i++)
                        printf(" %02x", rec->data[i]);  printf("\n");
                }
#endif	/* KSSL_DEBUG */

		if ((bs != 1) && !send)
			{
			ii=i=rec->data[l-1]; /* padding_length */
			i++;
			if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
				{
				/* First packet is even in size, so check */
				if ((memcmp(s->s3->read_sequence,
					"\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
					s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
					i--;
				}
			/* TLS 1.0 does not bound the number of padding bytes by the block size.
			 * All of them must have value 'padding_length'. */
			if (i + bs > (int)rec->length)
				{
				/* Incorrect padding. SSLerr() and ssl3_alert are done
				 * by caller: we don't want to reveal whether this is
				 * a decryption error or a MAC verification failure
				 * (see http://www.openssl.org/~bodo/tls-cbc.txt)
				 */
				return -1;
				}
			for (j=(int)(l-i); j<(int)l; j++)
				{
				if (rec->data[j] != ii)
					{
					/* Incorrect padding */
					return -1;
					}
				}
			rec->length-=i;

			rec->data += bs;    /* skip the implicit IV */
			rec->input += bs;
			rec->length -= bs;
			}
		}
	return(1);
	}


static uint64_t ehci_opreg_read(void *ptr, hwaddr addr, unsigned size) { EHCIState *s = ptr; uint32_t val; val = s->opreg[addr >> 2]; trace_usb_ehci_opreg_read(addr + s->opregbase, addr2str(addr), val); return val; }


int tls1_enc(SSL *s, int send)
	{
	SSL3_RECORD *rec;
	EVP_CIPHER_CTX *ds;
	unsigned long l;
	int bs,i,j,k,pad=0,ret,mac_size=0;
	const EVP_CIPHER *enc;

	if (send)
		{
		if (EVP_MD_CTX_md(s->write_hash))
			{
			n=EVP_MD_CTX_size(s->write_hash);
			OPENSSL_assert(n >= 0);
			}
		ds=s->enc_write_ctx;
		rec= &(s->s3->wrec);
		if (s->enc_write_ctx == NULL)
			enc=NULL;
		else
			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
		}
	else
		{
		if (EVP_MD_CTX_md(s->read_hash))
			{
			n=EVP_MD_CTX_size(s->read_hash);
			OPENSSL_assert(n >= 0);
			}
		ds=s->enc_read_ctx;
		rec= &(s->s3->rrec);
		if (s->enc_read_ctx == NULL)
			enc=NULL;
		else
			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
		}

#ifdef KSSL_DEBUG
	printf("tls1_enc(%d)\n", send);
#endif    /* KSSL_DEBUG */

	if ((s->session == NULL) || (ds == NULL) || (enc == NULL))
		{
		memmove(rec->data,rec->input,rec->length);
		rec->input=rec->data;
		ret = 1;
		}
	else
		{
		l=rec->length;
		bs=EVP_CIPHER_block_size(ds->cipher);

		if ((bs != 1) && send)
			{
			i=bs-((int)l%bs);

			/* Add weird padding of upto 256 bytes */

			/* we need to add 'i' padding bytes of value j */
			j=i-1;
			if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
				{
				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
					j++;
				}
			for (k=(int)l; k<(int)(l+i); k++)
				rec->input[k]=j;
			l+=i;
			rec->length+=i;
			}

#ifdef KSSL_DEBUG
		{
		unsigned long ui;
		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
			ds,rec->data,rec->input,l);
		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
			ds->buf_len, ds->cipher->key_len,
			DES_KEY_SZ, DES_SCHEDULE_SZ,
			ds->cipher->iv_len);
		printf("\t\tIV: ");
		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
		printf("\n");
		printf("\trec->input=");
		for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
		printf("\n");
		}
#endif	/* KSSL_DEBUG */

		if (!send)
			{
			if (l == 0 || l%bs != 0)
				{
				SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
				return 0;
				}
			}

		EVP_Cipher(ds,rec->data,rec->input,l);

#ifdef KSSL_DEBUG
		{
		unsigned long i;
		printf("\trec->data=");
		for (i=0; i<l; i++)
			printf(" %02x", rec->data[i]);  printf("\n");
		}
#endif	/* KSSL_DEBUG */

		rec->orig_len = rec->length;

		ret = 1;
		if (EVP_MD_CTX_md(s->read_hash) != NULL)
			mac_size = EVP_MD_CTX_size(s->read_hash);
		if ((bs != 1) && !send)
			ret = tls1_cbc_remove_padding(s, rec, bs, mac_size);
		if (pad && !send)
			rec->length -= pad;
		}
	return ret;
	}


static int dissect_s_supervisor_exception_detail ( proto_tree * tree , proto_item * item , tvbuff_t * tvb , int offset , int hf_size , int hf_data ) {
 int size ;
 proto_tree_add_item ( tree , hf_size , tvb , offset , 1 , ENC_LITTLE_ENDIAN ) ;
 size = tvb_get_guint8 ( tvb , offset ) ;
 proto_tree_add_item ( tree , hf_data , tvb , offset + 1 , size , ENC_NA ) ;
 proto_item_set_len ( item , size + 1 ) ;
 return size + 1 ;
 }


static const char * cmd_response_body_limit ( cmd_parms * cmd , void * _dcfg , const char * p1 ) {
 directory_config * dcfg = ( directory_config * ) _dcfg ;
 long int limit ;
 limit = strtol ( p1 , NULL , 10 ) ;
 if ( ( limit == LONG_MAX ) || ( limit == LONG_MIN ) || ( limit <= 0 ) ) {
 return apr_psprintf ( cmd -> pool , "ModSecurity: Invalid value for SecResponseBodyLimit: %s" , p1 ) ;
 }
 if ( limit > RESPONSE_BODY_HARD_LIMIT ) {
 return apr_psprintf ( cmd -> pool , "ModSecurity: Response size limit can not exceed the hard limit: %li" , RESPONSE_BODY_HARD_LIMIT ) ;
 }
 dcfg -> of_limit = limit ;
 return NULL ;
 }


void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f) { SaveStateEntry *se; QTAILQ_FOREACH(se, &savevm_handlers, entry) { if (se->save_live_state) { se->save_live_state(mon, f, -1, se->opaque); } } }


void ssl3_cbc_copy_mac(unsigned char* out,
		       const SSL3_RECORD *rec,
		       unsigned md_size,unsigned orig_len)
	{
#if defined(CBC_MAC_ROTATE_IN_PLACE)
	unsigned char rotated_mac_buf[EVP_MAX_MD_SIZE*2];
	unsigned char *rotated_mac;
#else
	unsigned char rotated_mac[EVP_MAX_MD_SIZE];
#endif

	/* mac_end is the index of |rec->data| just after the end of the MAC. */
	unsigned mac_end = rec->length;
	unsigned mac_start = mac_end - md_size;
	/* scan_start contains the number of bytes that we can ignore because
	 * the MAC's position can only vary by 255 bytes. */
	unsigned scan_start = 0;
	unsigned i, j;
	unsigned div_spoiler;
	unsigned rotate_offset;

	OPENSSL_assert(orig_len >= md_size);
	OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);

#if defined(CBC_MAC_ROTATE_IN_PLACE)
	rotated_mac = (unsigned char*) (((intptr_t)(rotated_mac_buf + 64)) & ~63);
#endif

	/* This information is public so it's safe to branch based on it. */
	if (orig_len > md_size + 255 + 1)
		scan_start = orig_len - (md_size + 255 + 1);
	/* div_spoiler contains a multiple of md_size that is used to cause the
	 * modulo operation to be constant time. Without this, the time varies
	 * based on the amount of padding when running on Intel chips at least.
	 *
	 * The aim of right-shifting md_size is so that the compiler doesn't
	 * figure out that it can remove div_spoiler as that would require it
	 * to prove that md_size is always even, which I hope is beyond it. */
	div_spoiler = md_size >> 1;
	div_spoiler <<= (sizeof(div_spoiler)-1)*8;
	rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;

	memset(rotated_mac, 0, md_size);
	for (i = scan_start; i < orig_len;)
		{
		for (j = 0; j < md_size && i < orig_len; i++, j++)
			{
			unsigned char mac_started = constant_time_ge(i, mac_start);
			unsigned char mac_ended = constant_time_ge(i, mac_end);
			unsigned char b = 0;
			b = rec->data[i];
			rotated_mac[j] |= b & mac_started & ~mac_ended;
			}
		}

	/* Now rotate the MAC */
#if defined(CBC_MAC_ROTATE_IN_PLACE)
	j = 0;
	for (i = 0; i < md_size; i++)
		{
		unsigned char offset = (div_spoiler + rotate_offset + i) % md_size;
		out[j++] = rotated_mac[offset];
		}
#else
	memset(out, 0, md_size);
	for (i = 0; i < md_size; i++)
		{
		unsigned char offset = (div_spoiler + md_size - rotate_offset + i) % md_size;
		for (j = 0; j < md_size; j++)
			out[j] |= rotated_mac[i] & constant_time_eq_8(j, offset);
		}
#endif
	}


static int pfkey_send_acquire ( struct xfrm_state * x , struct xfrm_tmpl * t , struct xfrm_policy * xp ) {
 struct sk_buff * skb ;
 struct sadb_msg * hdr ;
 struct sadb_address * addr ;
 struct sadb_x_policy * pol ;
 int sockaddr_size ;
 int size ;
 struct sadb_x_sec_ctx * sec_ctx ;
 struct xfrm_sec_ctx * xfrm_ctx ;
 int ctx_size = 0 ;
 sockaddr_size = pfkey_sockaddr_size ( x -> props . family ) ;
 if ( ! sockaddr_size ) return - EINVAL ;
 size = sizeof ( struct sadb_msg ) + ( sizeof ( struct sadb_address ) * 2 ) + ( sockaddr_size * 2 ) + sizeof ( struct sadb_x_policy ) ;
 if ( x -> id . proto == IPPROTO_AH ) size += count_ah_combs ( t ) ;
 else if ( x -> id . proto == IPPROTO_ESP ) size += count_esp_combs ( t ) ;
 if ( ( xfrm_ctx = x -> security ) ) {
 ctx_size = PFKEY_ALIGN8 ( xfrm_ctx -> ctx_len ) ;
 size += sizeof ( struct sadb_x_sec_ctx ) + ctx_size ;
 }
 skb = alloc_skb ( size + 16 , GFP_ATOMIC ) ;
 if ( skb == NULL ) return - ENOMEM ;
 hdr = ( struct sadb_msg * ) skb_put ( skb , sizeof ( struct sadb_msg ) ) ;
 hdr -> sadb_msg_version = PF_KEY_V2 ;
 hdr -> sadb_msg_type = SADB_ACQUIRE ;
 hdr -> sadb_msg_satype = pfkey_proto2satype ( x -> id . proto ) ;
 hdr -> sadb_msg_len = size / sizeof ( uint64_t ) ;
 hdr -> sadb_msg_errno = 0 ;
 hdr -> sadb_msg_reserved = 0 ;
 hdr -> sadb_msg_seq = x -> km . seq = get_acqseq ( ) ;
 hdr -> sadb_msg_pid = 0 ;
 addr = ( struct sadb_address * ) skb_put ( skb , sizeof ( struct sadb_address ) + sockaddr_size ) ;
 addr -> sadb_address_len = ( sizeof ( struct sadb_address ) + sockaddr_size ) / sizeof ( uint64_t ) ;
 addr -> sadb_address_exttype = SADB_EXT_ADDRESS_SRC ;
 addr -> sadb_address_proto = 0 ;
 addr -> sadb_address_reserved = 0 ;
 addr -> sadb_address_prefixlen = pfkey_sockaddr_fill ( & x -> props . saddr , 0 , ( struct sockaddr * ) ( addr + 1 ) , x -> props . family ) ;
 if ( ! addr -> sadb_address_prefixlen ) BUG ( ) ;
 addr = ( struct sadb_address * ) skb_put ( skb , sizeof ( struct sadb_address ) + sockaddr_size ) ;
 addr -> sadb_address_len = ( sizeof ( struct sadb_address ) + sockaddr_size ) / sizeof ( uint64_t ) ;
 addr -> sadb_address_exttype = SADB_EXT_ADDRESS_DST ;
 addr -> sadb_address_proto = 0 ;
 addr -> sadb_address_reserved = 0 ;
 addr -> sadb_address_prefixlen = pfkey_sockaddr_fill ( & x -> id . daddr , 0 , ( struct sockaddr * ) ( addr + 1 ) , x -> props . family ) ;
 if ( ! addr -> sadb_address_prefixlen ) BUG ( ) ;
 pol = ( struct sadb_x_policy * ) skb_put ( skb , sizeof ( struct sadb_x_policy ) ) ;
 pol -> sadb_x_policy_len = sizeof ( struct sadb_x_policy ) / sizeof ( uint64_t ) ;
 pol -> sadb_x_policy_exttype = SADB_X_EXT_POLICY ;
 pol -> sadb_x_policy_type = IPSEC_POLICY_IPSEC ;
 pol -> sadb_x_policy_dir = XFRM_POLICY_OUT + 1 ;
 pol -> sadb_x_policy_id = xp -> index ;
 if ( x -> id . proto == IPPROTO_AH ) dump_ah_combs ( skb , t ) ;
 else if ( x -> id . proto == IPPROTO_ESP ) dump_esp_combs ( skb , t ) ;
 if ( xfrm_ctx ) {
 sec_ctx = ( struct sadb_x_sec_ctx * ) skb_put ( skb , sizeof ( struct sadb_x_sec_ctx ) + ctx_size ) ;
 sec_ctx -> sadb_x_sec_len = ( sizeof ( struct sadb_x_sec_ctx ) + ctx_size ) / sizeof ( uint64_t ) ;
 sec_ctx -> sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX ;
 sec_ctx -> sadb_x_ctx_doi = xfrm_ctx -> ctx_doi ;
 sec_ctx -> sadb_x_ctx_alg = xfrm_ctx -> ctx_alg ;
 sec_ctx -> sadb_x_ctx_len = xfrm_ctx -> ctx_len ;
 memcpy ( sec_ctx + 1 , xfrm_ctx -> ctx_str , xfrm_ctx -> ctx_len ) ;
 }
 return pfkey_broadcast ( skb , GFP_ATOMIC , BROADCAST_REGISTERED , NULL , xs_net ( x ) ) ;
 }


static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1) { uint32_t insn, imm, shift, offset; uint32_t rd, rn, rm, rs; TCGv_i32 tmp; TCGv_i32 tmp2; TCGv_i32 tmp3; TCGv_i32 addr; TCGv_i64 tmp64; int op; int shiftop; int conds; int logic_cc; if (!(arm_feature(env, ARM_FEATURE_THUMB2) || arm_feature (env, ARM_FEATURE_M))) { /* Thumb-1 cores may need to treat bl and blx as a pair of 16-bit instructions to get correct prefetch abort behavior. */ insn = insn_hw1; if ((insn & (1 << 12)) == 0) { ARCH(5); /* Second half of blx. */ offset = ((insn & 0x7ff) << 1); tmp = load_reg(s, 14); tcg_gen_addi_i32(tmp, tmp, offset); tcg_gen_andi_i32(tmp, tmp, 0xfffffffc); tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, s->pc | 1); store_reg(s, 14, tmp2); gen_bx(s, tmp); return 0; } if (insn & (1 << 11)) { /* Second half of bl. */ offset = ((insn & 0x7ff) << 1) | 1; tmp = load_reg(s, 14); tcg_gen_addi_i32(tmp, tmp, offset); tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, s->pc | 1); store_reg(s, 14, tmp2); gen_bx(s, tmp); return 0; } if ((s->pc & ~TARGET_PAGE_MASK) == 0) { /* Instruction spans a page boundary. Implement it as two 16-bit instructions in case the second half causes an prefetch abort. */ offset = ((int32_t)insn << 21) >> 9; tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset); return 0; } /* Fall through to 32-bit decode. */ } insn = arm_lduw_code(env, s->pc, s->bswap_code); s->pc += 2; insn |= (uint32_t)insn_hw1 << 16; if ((insn & 0xf800e800) != 0xf000e800) { ARCH(6T2); } rn = (insn >> 16) & 0xf; rs = (insn >> 12) & 0xf; rd = (insn >> 8) & 0xf; rm = insn & 0xf; switch ((insn >> 25) & 0xf) { case 0: case 1: case 2: case 3: /* 16-bit instructions. Should never happen. */ abort(); case 4: if (insn & (1 << 22)) { /* Other load/store, table branch. */ if (insn & 0x01200000) { /* Load/store doubleword. */ if (rn == 15) { addr = tcg_temp_new_i32(); tcg_gen_movi_i32(addr, s->pc & ~3); } else { addr = load_reg(s, rn); } offset = (insn & 0xff) * 4; if ((insn & (1 << 23)) == 0) offset = -offset; if (insn & (1 << 24)) { tcg_gen_addi_i32(addr, addr, offset); offset = 0; } if (insn & (1 << 20)) { /* ldrd */ tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s)); store_reg(s, rs, tmp); tcg_gen_addi_i32(addr, addr, 4); tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s)); store_reg(s, rd, tmp); } else { /* strd */ tmp = load_reg(s, rs); tcg_gen_qemu_st32(tmp, addr, IS_USER(s)); tcg_temp_free_i32(tmp); tcg_gen_addi_i32(addr, addr, 4); tmp = load_reg(s, rd); tcg_gen_qemu_st32(tmp, addr, IS_USER(s)); tcg_temp_free_i32(tmp); } if (insn & (1 << 21)) { /* Base writeback. */ if (rn == 15) goto illegal_op; tcg_gen_addi_i32(addr, addr, offset - 4); store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } } else if ((insn & (1 << 23)) == 0) { /* Load/store exclusive word. */ addr = tcg_temp_local_new_i32(); load_reg_var(s, addr, rn); tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2); if (insn & (1 << 20)) { gen_load_exclusive(s, rs, 15, addr, 2); } else { gen_store_exclusive(s, rd, rs, 15, addr, 2); } tcg_temp_free_i32(addr); } else if ((insn & (7 << 5)) == 0) { /* Table Branch. */ if (rn == 15) { addr = tcg_temp_new_i32(); tcg_gen_movi_i32(addr, s->pc); } else { addr = load_reg(s, rn); } tmp = load_reg(s, rm); tcg_gen_add_i32(addr, addr, tmp); if (insn & (1 << 4)) { /* tbh */ tcg_gen_add_i32(addr, addr, tmp); tcg_temp_free_i32(tmp); tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s)); } else { /* tbb */ tcg_temp_free_i32(tmp); tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s)); } tcg_temp_free_i32(addr); tcg_gen_shli_i32(tmp, tmp, 1); tcg_gen_addi_i32(tmp, tmp, s->pc); store_reg(s, 15, tmp); } else { int op2 = (insn >> 6) & 0x3; op = (insn >> 4) & 0x3; switch (op2) { case 0: goto illegal_op; case 1: /* Load/store exclusive byte/halfword/doubleword */ if (op == 2) { goto illegal_op; } ARCH(7); break; case 2: /* Load-acquire/store-release */ if (op == 3) { goto illegal_op; } /* Fall through */ case 3: /* Load-acquire/store-release exclusive */ ARCH(8); break; } addr = tcg_temp_local_new_i32(); load_reg_var(s, addr, rn); if (!(op2 & 1)) { if (insn & (1 << 20)) { tmp = tcg_temp_new_i32(); switch (op) { case 0: /* ldab */ tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s)); break; case 1: /* ldah */ tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s)); break; case 2: /* lda */ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s)); break; default: abort(); } store_reg(s, rs, tmp); } else { tmp = load_reg(s, rs); switch (op) { case 0: /* stlb */ tcg_gen_qemu_st8(tmp, addr, IS_USER(s)); break; case 1: /* stlh */ tcg_gen_qemu_st16(tmp, addr, IS_USER(s)); break; case 2: /* stl */ tcg_gen_qemu_st32(tmp, addr, IS_USER(s)); break; default: abort(); } tcg_temp_free_i32(tmp); } } else if (insn & (1 << 20)) { gen_load_exclusive(s, rs, rd, addr, op); } else { gen_store_exclusive(s, rm, rs, rd, addr, op); } tcg_temp_free_i32(addr); } } else { /* Load/store multiple, RFE, SRS. */ if (((insn >> 23) & 1) == ((insn >> 24) & 1)) { /* RFE, SRS: not available in user mode or on M profile */ if (IS_USER(s) || IS_M(env)) { goto illegal_op; } if (insn & (1 << 20)) { /* rfe */ addr = load_reg(s, rn); if ((insn & (1 << 24)) == 0) tcg_gen_addi_i32(addr, addr, -8); /* Load PC into tmp and CPSR into tmp2. */ tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld32u(tmp, addr, 0); tcg_gen_addi_i32(addr, addr, 4); tmp2 = tcg_temp_new_i32(); tcg_gen_qemu_ld32u(tmp2, addr, 0); if (insn & (1 << 21)) { /* Base writeback. */ if (insn & (1 << 24)) { tcg_gen_addi_i32(addr, addr, 4); } else { tcg_gen_addi_i32(addr, addr, -4); } store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } gen_rfe(s, tmp, tmp2); } else { /* srs */ gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2, insn & (1 << 21)); } } else { int i, loaded_base = 0; TCGv_i32 loaded_var; /* Load/store multiple. */ addr = load_reg(s, rn); offset = 0; for (i = 0; i < 16; i++) { if (insn & (1 << i)) offset += 4; } if (insn & (1 << 24)) { tcg_gen_addi_i32(addr, addr, -offset); } TCGV_UNUSED_I32(loaded_var); for (i = 0; i < 16; i++) { if ((insn & (1 << i)) == 0) continue; if (insn & (1 << 20)) { /* Load. */ tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s)); if (i == 15) { gen_bx(s, tmp); } else if (i == rn) { loaded_var = tmp; loaded_base = 1; } else { store_reg(s, i, tmp); } } else { /* Store. */ tmp = load_reg(s, i); tcg_gen_qemu_st32(tmp, addr, IS_USER(s)); tcg_temp_free_i32(tmp); } tcg_gen_addi_i32(addr, addr, 4); } if (loaded_base) { store_reg(s, rn, loaded_var); } if (insn & (1 << 21)) { /* Base register writeback. */ if (insn & (1 << 24)) { tcg_gen_addi_i32(addr, addr, -offset); } /* Fault if writeback register is in register list. */ if (insn & (1 << rn)) goto illegal_op; store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } } } break; case 5: op = (insn >> 21) & 0xf; if (op == 6) { /* Halfword pack. */ tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3); if (insn & (1 << 5)) { /* pkhtb */ if (shift == 0) shift = 31; tcg_gen_sari_i32(tmp2, tmp2, shift); tcg_gen_andi_i32(tmp, tmp, 0xffff0000); tcg_gen_ext16u_i32(tmp2, tmp2); } else { /* pkhbt */ if (shift) tcg_gen_shli_i32(tmp2, tmp2, shift); tcg_gen_ext16u_i32(tmp, tmp); tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); } tcg_gen_or_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else { /* Data processing register constant shift. */ if (rn == 15) { tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rn); } tmp2 = load_reg(s, rm); shiftop = (insn >> 4) & 3; shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); conds = (insn & (1 << 20)) != 0; logic_cc = (conds && thumb2_logic_op(op)); gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2)) goto illegal_op; tcg_temp_free_i32(tmp2); if (rd != 15) { store_reg(s, rd, tmp); } else { tcg_temp_free_i32(tmp); } } break; case 13: /* Misc data processing. */ op = ((insn >> 22) & 6) | ((insn >> 7) & 1); if (op < 4 && (insn & 0xf000) != 0xf000) goto illegal_op; switch (op) { case 0: /* Register controlled shift. */ tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); if ((insn & 0x70) != 0) goto illegal_op; op = (insn >> 21) & 3; logic_cc = (insn & (1 << 20)) != 0; gen_arm_shift_reg(tmp, op, tmp2, logic_cc); if (logic_cc) gen_logic_CC(tmp); store_reg_bx(env, s, rd, tmp); break; case 1: /* Sign/zero extend. */ tmp = load_reg(s, rm); shift = (insn >> 4) & 3; /* ??? In many cases it's not necessary to do a rotate, a shift is sufficient. */ if (shift != 0) tcg_gen_rotri_i32(tmp, tmp, shift * 8); op = (insn >> 20) & 7; switch (op) { case 0: gen_sxth(tmp); break; case 1: gen_uxth(tmp); break; case 2: gen_sxtb16(tmp); break; case 3: gen_uxtb16(tmp); break; case 4: gen_sxtb(tmp); break; case 5: gen_uxtb(tmp); break; default: goto illegal_op; } if (rn != 15) { tmp2 = load_reg(s, rn); if ((op >> 1) == 1) { gen_add16(tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } } store_reg(s, rd, tmp); break; case 2: /* SIMD add/subtract. */ op = (insn >> 20) & 7; shift = (insn >> 4) & 7; if ((op & 3) == 3 || (shift & 3) == 3) goto illegal_op; tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); gen_thumb2_parallel_addsub(op, shift, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; case 3: /* Other data processing. */ op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7); if (op < 4) { /* Saturating add/subtract. */ tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); if (op & 1) gen_helper_double_saturate(tmp, cpu_env, tmp); if (op & 2) gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp); else gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); } else { tmp = load_reg(s, rn); switch (op) { case 0x0a: /* rbit */ gen_helper_rbit(tmp, tmp); break; case 0x08: /* rev */ tcg_gen_bswap32_i32(tmp, tmp); break; case 0x09: /* rev16 */ gen_rev16(tmp); break; case 0x0b: /* revsh */ gen_revsh(tmp); break; case 0x10: /* sel */ tmp2 = load_reg(s, rm); tmp3 = tcg_temp_new_i32(); tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE)); gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); tcg_temp_free_i32(tmp3); tcg_temp_free_i32(tmp2); break; case 0x18: /* clz */ gen_helper_clz(tmp, tmp); break; default: goto illegal_op; } } store_reg(s, rd, tmp); break; case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */ op = (insn >> 4) & 0xf; tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); switch ((insn >> 20) & 7) { case 0: /* 32 x 32 -> 32 */ tcg_gen_mul_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); if (op) tcg_gen_sub_i32(tmp, tmp2, tmp); else tcg_gen_add_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } break; case 1: /* 16 x 16 -> 32 */ gen_mulxy(tmp, tmp2, op & 2, op & 1); tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); } break; case 2: /* Dual multiply add. */ case 4: /* Dual multiply subtract. */ if (op) gen_swap_half(tmp2); gen_smul_dual(tmp, tmp2); if (insn & (1 << 22)) { /* This subtraction cannot overflow. */ tcg_gen_sub_i32(tmp, tmp, tmp2); } else { /* This addition cannot overflow 32 bits; * however it may overflow considered as a signed * operation, in which case we must set the Q flag. */ gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); } tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); } break; case 3: /* 32 * 16 -> 32msb */ if (op) tcg_gen_sari_i32(tmp2, tmp2, 16); else gen_sxth(tmp2); tmp64 = gen_muls_i64_i32(tmp, tmp2); tcg_gen_shri_i64(tmp64, tmp64, 16); tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); } break; case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */ tmp64 = gen_muls_i64_i32(tmp, tmp2); if (rs != 15) { tmp = load_reg(s, rs); if (insn & (1 << 20)) { tmp64 = gen_addq_msw(tmp64, tmp); } else { tmp64 = gen_subq_msw(tmp64, tmp); } } if (insn & (1 << 4)) { tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u); } tcg_gen_shri_i64(tmp64, tmp64, 32); tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); break; case 7: /* Unsigned sum of absolute differences. */ gen_helper_usad8(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); tcg_gen_add_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } break; } store_reg(s, rd, tmp); break; case 6: case 7: /* 64-bit multiply, Divide. */ op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70); tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); if ((op & 0x50) == 0x10) { /* sdiv, udiv */ if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) { goto illegal_op; } if (op & 0x20) gen_helper_udiv(tmp, tmp, tmp2); else gen_helper_sdiv(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else if ((op & 0xe) == 0xc) { /* Dual multiply accumulate long. */ if (op & 1) gen_swap_half(tmp2); gen_smul_dual(tmp, tmp2); if (op & 0x10) { tcg_gen_sub_i32(tmp, tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); } tcg_temp_free_i32(tmp2); /* BUGFIX */ tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); tcg_temp_free_i32(tmp); gen_addq(s, tmp64, rs, rd); gen_storeq_reg(s, rs, rd, tmp64); tcg_temp_free_i64(tmp64); } else { if (op & 0x20) { /* Unsigned 64-bit multiply */ tmp64 = gen_mulu_i64_i32(tmp, tmp2); } else { if (op & 8) { /* smlalxy */ gen_mulxy(tmp, tmp2, op & 2, op & 1); tcg_temp_free_i32(tmp2); tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); tcg_temp_free_i32(tmp); } else { /* Signed 64-bit multiply */ tmp64 = gen_muls_i64_i32(tmp, tmp2); } } if (op & 4) { /* umaal */ gen_addq_lo(s, tmp64, rs); gen_addq_lo(s, tmp64, rd); } else if (op & 0x40) { /* 64-bit accumulate. */ gen_addq(s, tmp64, rs, rd); } gen_storeq_reg(s, rs, rd, tmp64); tcg_temp_free_i64(tmp64); } break; } break; case 6: case 7: case 14: case 15: /* Coprocessor. */ if (((insn >> 24) & 3) == 3) { /* Translate into the equivalent ARM encoding. */ insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28); if (disas_neon_data_insn(env, s, insn)) goto illegal_op; } else { if (insn & (1 << 28)) goto illegal_op; if (disas_coproc_insn (env, s, insn)) goto illegal_op; } break; case 8: case 9: case 10: case 11: if (insn & (1 << 15)) { /* Branches, misc control. */ if (insn & 0x5000) { /* Unconditional branch. */ /* signextend(hw1[10:0]) -> offset[:12]. */ offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff; /* hw1[10:0] -> offset[11:1]. */ offset |= (insn & 0x7ff) << 1; /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22] offset[24:22] already have the same value because of the sign extension above. */ offset ^= ((~insn) & (1 << 13)) << 10; offset ^= ((~insn) & (1 << 11)) << 11; if (insn & (1 << 14)) { /* Branch and link. */ tcg_gen_movi_i32(cpu_R[14], s->pc | 1); } offset += s->pc; if (insn & (1 << 12)) { /* b/bl */ gen_jmp(s, offset); } else { /* blx */ offset &= ~(uint32_t)2; /* thumb2 bx, no need to check */ gen_bx_im(s, offset); } } else if (((insn >> 23) & 7) == 7) { /* Misc control */ if (insn & (1 << 13)) goto illegal_op; if (insn & (1 << 26)) { /* Secure monitor call (v6Z) */ goto illegal_op; /* not implemented. */ } else { op = (insn >> 20) & 7; switch (op) { case 0: /* msr cpsr. */ if (IS_M(env)) { tmp = load_reg(s, rn); addr = tcg_const_i32(insn & 0xff); gen_helper_v7m_msr(cpu_env, addr, tmp); tcg_temp_free_i32(addr); tcg_temp_free_i32(tmp); gen_lookup_tb(s); break; } /* fall through */ case 1: /* msr spsr. */ if (IS_M(env)) goto illegal_op; tmp = load_reg(s, rn); if (gen_set_psr(s, msr_mask(env, s, (insn >> 8) & 0xf, op == 1), op == 1, tmp)) goto illegal_op; break; case 2: /* cps, nop-hint. */ if (((insn >> 8) & 7) == 0) { gen_nop_hint(s, insn & 0xff); } /* Implemented as NOP in user mode. */ if (IS_USER(s)) break; offset = 0; imm = 0; if (insn & (1 << 10)) { if (insn & (1 << 7)) offset |= CPSR_A; if (insn & (1 << 6)) offset |= CPSR_I; if (insn & (1 << 5)) offset |= CPSR_F; if (insn & (1 << 9)) imm = CPSR_A | CPSR_I | CPSR_F; } if (insn & (1 << 8)) { offset |= 0x1f; imm |= (insn & 0x1f); } if (offset) { gen_set_psr_im(s, offset, 0, imm); } break; case 3: /* Special control operations. */ ARCH(7); op = (insn >> 4) & 0xf; switch (op) { case 2: /* clrex */ gen_clrex(s); break; case 4: /* dsb */ case 5: /* dmb */ case 6: /* isb */ /* These execute as NOPs. */ break; default: goto illegal_op; } break; case 4: /* bxj */ /* Trivial implementation equivalent to bx. */ tmp = load_reg(s, rn); gen_bx(s, tmp); break; case 5: /* Exception return. */ if (IS_USER(s)) { goto illegal_op; } if (rn != 14 || rd != 15) { goto illegal_op; } tmp = load_reg(s, rn); tcg_gen_subi_i32(tmp, tmp, insn & 0xff); gen_exception_return(s, tmp); break; case 6: /* mrs cpsr. */ tmp = tcg_temp_new_i32(); if (IS_M(env)) { addr = tcg_const_i32(insn & 0xff); gen_helper_v7m_mrs(tmp, cpu_env, addr); tcg_temp_free_i32(addr); } else { gen_helper_cpsr_read(tmp, cpu_env); } store_reg(s, rd, tmp); break; case 7: /* mrs spsr. */ /* Not accessible in user mode. */ if (IS_USER(s) || IS_M(env)) goto illegal_op; tmp = load_cpu_field(spsr); store_reg(s, rd, tmp); break; } } } else { /* Conditional branch. */ op = (insn >> 22) & 0xf; /* Generate a conditional jump to next instruction. */ s->condlabel = gen_new_label(); gen_test_cc(op ^ 1, s->condlabel); s->condjmp = 1; /* offset[11:1] = insn[10:0] */ offset = (insn & 0x7ff) << 1; /* offset[17:12] = insn[21:16]. */ offset |= (insn & 0x003f0000) >> 4; /* offset[31:20] = insn[26]. */ offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11; /* offset[18] = insn[13]. */ offset |= (insn & (1 << 13)) << 5; /* offset[19] = insn[11]. */ offset |= (insn & (1 << 11)) << 8; /* jump to the offset */ gen_jmp(s, s->pc + offset); } } else { /* Data processing immediate. */ if (insn & (1 << 25)) { if (insn & (1 << 24)) { if (insn & (1 << 20)) goto illegal_op; /* Bitfield/Saturate. */ op = (insn >> 21) & 7; imm = insn & 0x1f; shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); if (rn == 15) { tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rn); } switch (op) { case 2: /* Signed bitfield extract. */ imm++; if (shift + imm > 32) goto illegal_op; if (imm < 32) gen_sbfx(tmp, shift, imm); break; case 6: /* Unsigned bitfield extract. */ imm++; if (shift + imm > 32) goto illegal_op; if (imm < 32) gen_ubfx(tmp, shift, (1u << imm) - 1); break; case 3: /* Bitfield insert/clear. */ if (imm < shift) goto illegal_op; imm = imm + 1 - shift; if (imm != 32) { tmp2 = load_reg(s, rd); tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm); tcg_temp_free_i32(tmp2); } break; case 7: goto illegal_op; default: /* Saturate. */ if (shift) { if (op & 1) tcg_gen_sari_i32(tmp, tmp, shift); else tcg_gen_shli_i32(tmp, tmp, shift); } tmp2 = tcg_const_i32(imm); if (op & 4) { /* Unsigned. */ if ((op & 1) && shift == 0) gen_helper_usat16(tmp, cpu_env, tmp, tmp2); else gen_helper_usat(tmp, cpu_env, tmp, tmp2); } else { /* Signed. */ if ((op & 1) && shift == 0) gen_helper_ssat16(tmp, cpu_env, tmp, tmp2); else gen_helper_ssat(tmp, cpu_env, tmp, tmp2); } tcg_temp_free_i32(tmp2); break; } store_reg(s, rd, tmp); } else { imm = ((insn & 0x04000000) >> 15) | ((insn & 0x7000) >> 4) | (insn & 0xff); if (insn & (1 << 22)) { /* 16-bit immediate. */ imm |= (insn >> 4) & 0xf000; if (insn & (1 << 23)) { /* movt */ tmp = load_reg(s, rd); tcg_gen_ext16u_i32(tmp, tmp); tcg_gen_ori_i32(tmp, tmp, imm << 16); } else { /* movw */ tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, imm); } } else { /* Add/sub 12-bit immediate. */ if (rn == 15) { offset = s->pc & ~(uint32_t)3; if (insn & (1 << 23)) offset -= imm; else offset += imm; tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, offset); } else { tmp = load_reg(s, rn); if (insn & (1 << 23)) tcg_gen_subi_i32(tmp, tmp, imm); else tcg_gen_addi_i32(tmp, tmp, imm); } } store_reg(s, rd, tmp); } } else { int shifter_out = 0; /* modified 12-bit immediate. */ shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12); imm = (insn & 0xff); switch (shift) { case 0: /* XY */ /* Nothing to do. */ break; case 1: /* 00XY00XY */ imm |= imm << 16; break; case 2: /* XY00XY00 */ imm |= imm << 16; imm <<= 8; break; case 3: /* XYXYXYXY */ imm |= imm << 16; imm |= imm << 8; break; default: /* Rotated constant. */ shift = (shift << 1) | (imm >> 7); imm |= 0x80; imm = imm << (32 - shift); shifter_out = 1; break; } tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, imm); rn = (insn >> 16) & 0xf; if (rn == 15) { tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rn); } op = (insn >> 21) & 0xf; if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, shifter_out, tmp, tmp2)) goto illegal_op; tcg_temp_free_i32(tmp2); rd = (insn >> 8) & 0xf; if (rd != 15) { store_reg(s, rd, tmp); } else { tcg_temp_free_i32(tmp); } } } break; case 12: /* Load/store single data item. */ { int postinc = 0; int writeback = 0; int user; if ((insn & 0x01100000) == 0x01000000) { if (disas_neon_ls_insn(env, s, insn)) goto illegal_op; break; } op = ((insn >> 21) & 3) | ((insn >> 22) & 4); if (rs == 15) { if (!(insn & (1 << 20))) { goto illegal_op; } if (op != 2) { /* Byte or halfword load space with dest == r15 : memory hints. * Catch them early so we don't emit pointless addressing code. * This space is a mix of: * PLD/PLDW/PLI, which we implement as NOPs (note that unlike * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP * cores) * unallocated hints, which must be treated as NOPs * UNPREDICTABLE space, which we NOP or UNDEF depending on * which is easiest for the decoding logic * Some space which must UNDEF */ int op1 = (insn >> 23) & 3; int op2 = (insn >> 6) & 0x3f; if (op & 2) { goto illegal_op; } if (rn == 15) { /* UNPREDICTABLE, unallocated hint or * PLD/PLDW/PLI (literal) */ return 0; } if (op1 & 1) { return 0; /* PLD/PLDW/PLI or unallocated hint */ } if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) { return 0; /* PLD/PLDW/PLI or unallocated hint */ } /* UNDEF space, or an UNPREDICTABLE */ return 1; } } user = IS_USER(s); if (rn == 15) { addr = tcg_temp_new_i32(); /* PC relative. */ /* s->pc has already been incremented by 4. */ imm = s->pc & 0xfffffffc; if (insn & (1 << 23)) imm += insn & 0xfff; else imm -= insn & 0xfff; tcg_gen_movi_i32(addr, imm); } else { addr = load_reg(s, rn); if (insn & (1 << 23)) { /* Positive offset. */ imm = insn & 0xfff; tcg_gen_addi_i32(addr, addr, imm); } else { imm = insn & 0xff; switch ((insn >> 8) & 0xf) { case 0x0: /* Shifted Register. */ shift = (insn >> 4) & 0xf; if (shift > 3) { tcg_temp_free_i32(addr); goto illegal_op; } tmp = load_reg(s, rm); if (shift) tcg_gen_shli_i32(tmp, tmp, shift); tcg_gen_add_i32(addr, addr, tmp); tcg_temp_free_i32(tmp); break; case 0xc: /* Negative offset. */ tcg_gen_addi_i32(addr, addr, -imm); break; case 0xe: /* User privilege. */ tcg_gen_addi_i32(addr, addr, imm); user = 1; break; case 0x9: /* Post-decrement. */ imm = -imm; /* Fall through. */ case 0xb: /* Post-increment. */ postinc = 1; writeback = 1; break; case 0xd: /* Pre-decrement. */ imm = -imm; /* Fall through. */ case 0xf: /* Pre-increment. */ tcg_gen_addi_i32(addr, addr, imm); writeback = 1; break; default: tcg_temp_free_i32(addr); goto illegal_op; } } } if (insn & (1 << 20)) { /* Load. */ tmp = tcg_temp_new_i32(); switch (op) { case 0: tcg_gen_qemu_ld8u(tmp, addr, user); break; case 4: tcg_gen_qemu_ld8s(tmp, addr, user); break; case 1: tcg_gen_qemu_ld16u(tmp, addr, user); break; case 5: tcg_gen_qemu_ld16s(tmp, addr, user); break; case 2: tcg_gen_qemu_ld32u(tmp, addr, user); break; default: tcg_temp_free_i32(tmp); tcg_temp_free_i32(addr); goto illegal_op; } if (rs == 15) { gen_bx(s, tmp); } else { store_reg(s, rs, tmp); } } else { /* Store. */ tmp = load_reg(s, rs); switch (op) { case 0: tcg_gen_qemu_st8(tmp, addr, user); break; case 1: tcg_gen_qemu_st16(tmp, addr, user); break; case 2: tcg_gen_qemu_st32(tmp, addr, user); break; default: tcg_temp_free_i32(tmp); tcg_temp_free_i32(addr); goto illegal_op; } tcg_temp_free_i32(tmp); } if (postinc) tcg_gen_addi_i32(addr, addr, imm); if (writeback) { store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } } break; default: goto illegal_op; } return 0; illegal_op: return 1; }


void register_ber_syntax_dissector ( const char * syntax , int proto , dissector_t dissector ) {
 dissector_handle_t dissector_handle ;
 dissector_handle = create_dissector_handle ( dissector , proto ) ;
 dissector_add_string ( "ber.syntax" , syntax , dissector_handle ) ;
 }


static int rv40_h_loop_filter_strength(uint8_t *src, int stride, int beta, int beta2, int edge, int *p1, int *q1) { return rv40_loop_filter_strength(src, stride, 1, beta, beta2, edge, p1, q1); }


static int pxa2xx_pwrmode_write ( CPUARMState * env , const ARMCPRegInfo * ri , uint64_t value ) {
 PXA2xxState * s = ( PXA2xxState * ) ri -> opaque ;
 static const char * pwrmode [ 8 ] = {
 "Normal" , "Idle" , "Deep-idle" , "Standby" , "Sleep" , "reserved (!)" , "reserved (!)" , "Deep-sleep" , }
 ;
 if ( value & 8 ) {
 printf ( "%s: CPU voltage change attempt\n" , __func__ ) ;
 }
 switch ( value & 7 ) {
 case 0 : break ;
 case 1 : if ( ! ( s -> cm_regs [ CCCR >> 2 ] & ( 1 << 31 ) ) ) {
 cpu_interrupt ( CPU ( s -> cpu ) , CPU_INTERRUPT_HALT ) ;
 break ;
 }
 case 2 : cpu_interrupt ( CPU ( s -> cpu ) , CPU_INTERRUPT_HALT ) ;
 s -> pm_regs [ RCSR >> 2 ] |= 0x8 ;
 goto message ;
 case 3 : s -> cpu -> env . uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I ;
 s -> cpu -> env . cp15 . c1_sys = 0 ;
 s -> cpu -> env . cp15 . c1_coproc = 0 ;
 s -> cpu -> env . cp15 . c2_base0 = 0 ;
 s -> cpu -> env . cp15 . c3 = 0 ;
 s -> pm_regs [ PSSR >> 2 ] |= 0x8 ;
 s -> pm_regs [ RCSR >> 2 ] |= 0x8 ;
 memset ( s -> cpu -> env . regs , 0 , 4 * 15 ) ;
 s -> cpu -> env . regs [ 15 ] = s -> pm_regs [ PSPR >> 2 ] ;
 # if 0 buffer = 0xe59ff000 ;
 cpu_physical_memory_write ( 0 , & buffer , 4 ) ;
 buffer = s -> pm_regs [ PSPR >> 2 ] ;
 cpu_physical_memory_write ( 8 , & buffer , 4 ) ;
 # endif cpu_interrupt ( CPU ( arm_env_get_cpu ( cpu_single_env ) ) , CPU_INTERRUPT_HALT ) ;
 goto message ;
 default : message : printf ( "%s: machine entered %s mode\n" , __func__ , pwrmode [ value & 7 ] ) ;
 }
 return 0 ;
 }


tcp_listen(Slirp *slirp, u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags) { struct sockaddr_in addr; struct socket *so; int s, opt = 1; socklen_t addrlen = sizeof(addr); DEBUG_CALL("tcp_listen"); DEBUG_ARG("haddr = %x", haddr); DEBUG_ARG("hport = %d", hport); DEBUG_ARG("laddr = %x", laddr); DEBUG_ARG("lport = %d", lport); DEBUG_ARG("flags = %x", flags); so = socreate(slirp); if (!so) { return NULL; } /* Don't tcp_attach... we don't need so_snd nor so_rcv */ if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) { free(so); return NULL; } insque(so, &slirp->tcb); /* * SS_FACCEPTONCE sockets must time out. */ if (flags & SS_FACCEPTONCE) so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2; so->so_state &= SS_PERSISTENT_MASK; so->so_state |= (SS_FACCEPTCONN | flags); so->so_lport = lport; /* Kept in network format */ so->so_laddr.s_addr = laddr; /* Ditto */ addr.sin_family = AF_INET; addr.sin_addr.s_addr = haddr; addr.sin_port = hport; if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) || (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) || (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) || (listen(s,1) < 0)) { int tmperrno = errno; /* Don't clobber the real reason we failed */ close(s); sofree(so); /* Restore the real errno */ #ifdef _WIN32 WSASetLastError(tmperrno); #else errno = tmperrno; #endif return NULL; } setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); getsockname(s,(struct sockaddr *)&addr,&addrlen); so->so_fport = addr.sin_port; if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) so->so_faddr = slirp->vhost_addr; else so->so_faddr = addr.sin_addr; so->s = s; return so; }


void pdf_process_annot ( fz_context * ctx , pdf_processor * proc , pdf_document * doc , pdf_page * page , pdf_annot * annot , fz_cookie * cookie ) {
 int flags = pdf_to_int ( ctx , pdf_dict_get ( ctx , annot -> obj , PDF_NAME_F ) ) ;
 if ( flags & ( PDF_ANNOT_IS_INVISIBLE | PDF_ANNOT_IS_HIDDEN ) ) return ;
 if ( pdf_annot_type ( ctx , annot ) == PDF_ANNOT_POPUP ) return ;
 if ( proc -> usage ) {
 if ( ! strcmp ( proc -> usage , "Print" ) && ! ( flags & PDF_ANNOT_IS_PRINT ) ) return ;
 if ( ! strcmp ( proc -> usage , "View" ) && ( flags & PDF_ANNOT_IS_NO_VIEW ) ) return ;
 }
 if ( pdf_is_hidden_ocg ( ctx , doc -> ocg , NULL , proc -> usage , pdf_dict_get ( ctx , annot -> obj , PDF_NAME_OC ) ) ) return ;
 if ( proc -> op_q && proc -> op_cm && proc -> op_Do_form && proc -> op_Q && annot -> ap ) {
 fz_matrix matrix ;
 pdf_annot_transform ( ctx , annot , & matrix ) ;
 proc -> op_q ( ctx , proc ) ;
 proc -> op_cm ( ctx , proc , matrix . a , matrix . b , matrix . c , matrix . d , matrix . e , matrix . f ) ;
 proc -> op_Do_form ( ctx , proc , NULL , annot -> ap , pdf_page_resources ( ctx , page ) ) ;
 proc -> op_Q ( ctx , proc ) ;
 }
 }