Exemple #1
0
    /* main thread entrypoint */
    void thread_main()
    {
        /* if they want redirections, set up to receive the location */
        char *loc = 0;
        char **locp = ((options & NetReqNoRedirect) != 0 ? &loc : 0);

        /* set up a memory stream object to hold the reply */
        CVmExpandableMemoryStream *reply = new CVmExpandableMemoryStream(0);

        /* no reply headers yet */
        char *reply_hdrs = 0;

        /* figure the request option flags */
        int rflags = 0;
        if (https)
            rflags |= OS_HttpClient::OptHTTPS;

        /* get the length of the custom headers, if we have any */
        size_t hdrs_len = (hdrs != 0 ? strlen(hdrs) : 0);

        /* presume failure */
        int status = OS_HttpClient::ErrOther;

        /* send the request, catching any errors */
        err_try
        {
            /* send the request */
            status = OS_HttpClient::request(
                rflags, host, port, verb, resource, hdrs, hdrs_len, body,
                reply, &reply_hdrs, locp, 0);
        }
        err_catch (exc)
        {
        }
        
        /* 
         *   if the status is negative, a system-level error occurred, so
         *   there's no reply data - delete and forget the reply stream
         */
        if (status < 0)
        {
            delete reply;
            reply = 0;
        }
        err_end;
        
        /* 
         *   Always post a result event, even on failure, since the event is
         *   the way we transmit the status information back to the caller.
         *   Note that the event object takes ownership of the reply stream,
         *   headers string, and location string, and will free the
         *   underlying memory when the event object is deleted.
         */
        post_result(status, reply, reply_hdrs, loc);
    }
static int gdb_fileio_end(struct target *target, int result, int fileio_errno, bool ctrl_c)
{
	struct arm *arm = target_to_arm(target);
	struct gdb_fileio_info *fileio_info = target->fileio_info;

	/* clear pending status */
	arm->semihosting_hit_fileio = false;

	arm->semihosting_result = result;
	arm->semihosting_errno = fileio_errno;

	/* Some fileio results do not match up with what the semihosting
	 * operation expects; for these operations, we munge the results
	 * below:
	 */
	switch (arm->semihosting_op) {
	case 0x05:	/* SYS_WRITE */
		if (result < 0)
			arm->semihosting_result = fileio_info->param_3;
		else
			arm->semihosting_result = 0;
		break;

	case 0x06:	/* SYS_READ */
		if (result == (int)fileio_info->param_3)
			arm->semihosting_result = 0;
		if (result <= 0)
			arm->semihosting_result = fileio_info->param_3;
		break;

	case 0x0a:	/* SYS_SEEK */
		if (result > 0)
			arm->semihosting_result = 0;
		break;
	}

	return post_result(target);
}
/**
 * Checks for and processes an ARM semihosting request.  This is meant
 * to be called when the target is stopped due to a debug mode entry.
 * If the value 0 is returned then there was nothing to process. A non-zero
 * return value signifies that a request was processed and the target resumed,
 * or an error was encountered, in which case the caller must return
 * immediately.
 *
 * @param target Pointer to the ARM target to process.  This target must
 *	not represent an ARMv6-M or ARMv7-M processor.
 * @param retval Pointer to a location where the return code will be stored
 * @return non-zero value if a request was processed or an error encountered
 */
int arm_semihosting(struct target *target, int *retval)
{
	struct arm *arm = target_to_arm(target);
	struct armv7a_common *armv7a = target_to_armv7a(target);
	uint32_t pc, lr, spsr;
	struct reg *r;

	if (!arm->is_semihosting)
		return 0;

	if (is_arm7_9(target_to_arm7_9(target)) ||
	    is_armv7a(armv7a)) {
		uint32_t vbar = 0x00000000;

		if (arm->core_mode != ARM_MODE_SVC)
			return 0;

		if (is_armv7a(armv7a)) {
			struct arm_dpm *dpm = armv7a->arm.dpm;

			*retval = dpm->prepare(dpm);
			if (*retval == ERROR_OK) {
				*retval = dpm->instr_read_data_r0(dpm,
								 ARMV4_5_MRC(15, 0, 0, 12, 0, 0),
								 &vbar);

				dpm->finish(dpm);

				if (*retval != ERROR_OK)
					return 1;
			} else {
				return 1;
			}
		}

		/* Check for PC == 0x00000008 or 0xffff0008: Supervisor Call vector. */
		r = arm->pc;
		pc = buf_get_u32(r->value, 0, 32);
		if (pc != (vbar + 0x00000008) && pc != 0xffff0008)
			return 0;

		r = arm_reg_current(arm, 14);
		lr = buf_get_u32(r->value, 0, 32);

		/* Core-specific code should make sure SPSR is retrieved
		 * when the above checks pass...
		 */
		if (!arm->spsr->valid) {
			LOG_ERROR("SPSR not valid!");
			*retval = ERROR_FAIL;
			return 1;
		}

		spsr = buf_get_u32(arm->spsr->value, 0, 32);

		/* check instruction that triggered this trap */
		if (spsr & (1 << 5)) {
			/* was in Thumb (or ThumbEE) mode */
			uint8_t insn_buf[2];
			uint16_t insn;

			*retval = target_read_memory(target, lr-2, 2, 1, insn_buf);
			if (*retval != ERROR_OK)
				return 1;
			insn = target_buffer_get_u16(target, insn_buf);

			/* SVC 0xab */
			if (insn != 0xDFAB)
				return 0;
		} else if (spsr & (1 << 24)) {
			/* was in Jazelle mode */
			return 0;
		} else {
			/* was in ARM mode */
			uint8_t insn_buf[4];
			uint32_t insn;

			*retval = target_read_memory(target, lr-4, 4, 1, insn_buf);
			if (*retval != ERROR_OK)
				return 1;
			insn = target_buffer_get_u32(target, insn_buf);

			/* SVC 0x123456 */
			if (insn != 0xEF123456)
				return 0;
		}
	} else if (is_armv7m(target_to_armv7m(target))) {
		uint16_t insn;

		if (target->debug_reason != DBG_REASON_BREAKPOINT)
			return 0;

		r = arm->pc;
		pc = buf_get_u32(r->value, 0, 32);

		pc &= ~1;
		*retval = target_read_u16(target, pc, &insn);
		if (*retval != ERROR_OK)
			return 1;

		/* bkpt 0xAB */
		if (insn != 0xBEAB)
			return 0;
	} else {
		LOG_ERROR("Unsupported semi-hosting Target");
		return 0;
	}

	/* Perform semihosting if we are not waiting on a fileio
	 * operation to complete.
	 */
	if (!arm->semihosting_hit_fileio) {
		*retval = do_semihosting(target);
		if (*retval != ERROR_OK) {
			LOG_ERROR("Failed semihosting operation");
			return 0;
		}
	}

	/* Post result to target if we are not waiting on a fileio
	 * operation to complete:
	 */
	if (!arm->semihosting_hit_fileio) {
		*retval = post_result(target);
		if (*retval != ERROR_OK) {
			LOG_ERROR("Failed to post semihosting result");
			return 0;
		}

		*retval = target_resume(target, 1, 0, 0, 0);
		if (*retval != ERROR_OK) {
			LOG_ERROR("Failed to resume target");
			return 0;
		}

		return 1;
	}

	return 0;
}