Ejemplo n.º 1
0
int
mc_fseek(MC_FILE *fp, long offset, int whence)
{
#if !mxMC
	if (fp->aux != NULL)
		fseek(fp->aux, offset, whence);
#endif
	if (fp->ffs != NULL) {
		long pos;
		switch (whence) {
		case SEEK_SET:
			break;
		case SEEK_CUR:
			if ((pos = mc_ffs_position(fp->ffs, -1L, 0)) < 0L)
				return -1;
			offset += pos;
			break;
		case SEEK_END:
			if ((pos = mc_ffs_position(fp->ffs, 1L << 30, 0)) < 0L)
				return -1;
			offset += pos;
			break;
		}
		offset = mc_ffs_position(fp->ffs, offset, 1);
		if (offset >= 0L) {
			fp->pos = offset;
			fp->bp = fp->bufend = fp->buf;
		}
		return offset < 0L ? -1 : 0;
	}
	else if (fp->mmapped != NULL) {
		uint8_t *p;
		switch (whence) {
		default:
		case SEEK_SET:
			p = fp->buf + offset;
			break;
		case SEEK_CUR:
			p = fp->bp + offset;
			break;
		case SEEK_END:
			p = fp->bufend + offset;
			break;
		}
		if (p < fp->buf || p > fp->bufend) {
			mc_log_error("mc_fseek: range error\n");
			errno = ENXIO;
			return -1;
		}
		fp->bp = p;
		return 0;
	}
#if FTFS
	else if (fp->aux != NULL) {
		return mc_ft_fseek(fp->aux, offset, whence);
	}
#endif
	return 0;
}
Ejemplo n.º 2
0
int
mc_event_main(xsMachine *the, mc_event_shutdown_callback_t *cb)
{
	struct timeval tv;
	fd_set rs, ws;
	int n = -1, i;
	unsigned int flags;
	uint64_t timeInterval;
	struct sockaddr_in sin;
	int localevent_sock;

	mc_shutdown_callback = cb;
	g_status = -1;	/* not ready yet */
	if ((localevent_sock = lwip_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
		return -1;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(MC_LOCAL_EVENT_PORT);
	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	lwip_bind(localevent_sock, (struct sockaddr *)&sin, sizeof(sin));
	mc_event_register(localevent_sock, MC_SOCK_READ, mc_event_local_callback, the);
	mc_event_delegation_init();
	g_status = 0;	/* running */
	while (!g_status) {
		timeInterval = mc_event_process_timeout(the);
		if (timeInterval != 0) {
			tv.tv_sec = timeInterval / 1000;
			tv.tv_usec = (timeInterval % 1000) * 1000;
		}
		if (maxfd < 0) {	/* @@ what if only timer is running?? */
			mc_log_debug("event: no one is waiting!\n");
			break;	/* no one is waiting for anything! will be blocked forever unless break */
		}
		rs = reads;
		ws = writes;
		n = lwip_select(maxfd + 1, &rs, &ws, NULL, timeInterval > 0 ? &tv : NULL);
		if (mc_event_callback_any.callback != NULL)
			(*mc_event_callback_any.callback)(mc_event_callback_any.fd, (unsigned int)n, mc_event_callback_any.closure);
		if (n > 0) {
			for (i = 0; i <= maxfd; i++) {
				flags = 0;
				if (FD_ISSET(i, &rs))
					flags |= MC_SOCK_READ;
				if (FD_ISSET(i, &ws))
					flags |= MC_SOCK_WRITE;
				if (flags) {
					if (mc_event_callbacks[i].callback == NULL) {
						mc_log_error("event: %s ready for closed socket(%d)!?\n", flags & MC_SOCK_WRITE ? "write" : "read", i);
						continue;
					}
					(*mc_event_callbacks[i].callback)(i, flags, mc_event_callbacks[i].closure);
				}
			}
		}
	}
	mc_event_delegation_fin();
	lwip_close(localevent_sock);
	return g_exit_status;
}
Ejemplo n.º 3
0
int
mc_erase_volume(const char *volname)
{
	mc_partition_entry_t pe;
	void *mdev;
	int ret;

	if ((strlen(volname) > 0) && (volname[0] == '/'))
		volname++;

	if (mc_get_partition_by_name(volname, &pe, 0) != 0) {
		if (mc_get_partition_by_name(volname, &pe, -1) != 0) {
			mc_log_error("mc_erase_volume: no partition! %s\n", volname);
			return -1;
		}
	}
	if ((mdev = mc_flash_drv_open(pe.pe_dev)) == NULL) {
		mc_log_error("mc_erase_volume: mc_flash_drv_open failed\n");
		return -1;
	}
	ret = mc_flash_drv_erase(mdev, pe.pe_start, pe.pe_size);
	mc_flash_drv_close(mdev);
	return ret;
}
Ejemplo n.º 4
0
struct mc_timeout *
mc_interval_set(unsigned long interval, mc_timeout_callback_f callback, void *closure)
{
	int i;

	for (i = 0; i < MC_MAX_TIMEOUTS; i++) {
		if (mc_timeout_callbacks[i].status == MC_TIMEOUT_UNUSED) {
			struct mc_timeout *tc = &mc_timeout_callbacks[i];
			tc->interval = interval;
			tc->status = MC_TIMEOUT_STOP;
			tc->callback = callback;
			tc->closure = closure;
			return tc;
		}
	}
	mc_log_error("# Error: timeout: no slot!\n");
	return NULL;
}
Ejemplo n.º 5
0
int
mc_ftruncate(MC_FILE *fp, long length)
{
#if !mxMC
	if (fp->aux != NULL)
		ftruncate(fileno(fp->aux), length);
#endif
	if (fp->ffs == NULL) {
		mc_log_error("mc_ftruncate: fp->ffs is NULL\n");
		errno = ENXIO;
		return -1;
	}
	if (mc_ffs_position(fp->ffs, length, 1) >= 0 && mc_ffs_truncate(fp->ffs) == 0) {
		fp->pos = length;
		fp->length = length;
		fp->bp = fp->bufend = fp->buf;
		return 0;
	}
	else
		return -1;
}
Ejemplo n.º 6
0
int
mc_check_volume(const char *volname, int recovery)
{
	mc_partition_entry_t pe;
	int err;

	if ((strlen(volname) > 0) && (volname[0] == '/'))
		volname++;
	if (mc_get_partition_by_name(volname, &pe, 1) != 0) {
		mc_log_error("mc_check_volume: partition not found: %s\n", volname);
		return -1;
	}
	switch (pe.pe_type) {
	case MC_PTYPE_USER_APP:
		err = mc_ffs_check(&pe, recovery, volname);
		break;
	default:
		err = 0;
		break;
	}
	return err;
}
Ejemplo n.º 7
0
size_t
mc_fwrite(const void *ptr, size_t size, size_t nmemb, MC_FILE *fp)
{
	size_t n;

	if (fp->ffs == NULL) {
		mc_log_error("mc_fwrite: fp->ffs is NULL\n");
		errno = EPERM;
		return 0;
	}
#if !mxMC
	if (fp->aux != NULL)
		fwrite(ptr, size, nmemb, fp->aux);
#endif
	n = mc_ffs_write(ptr, size, nmemb, fp->ffs);
	if (n == 0)
		return 0;
	fp->pos += n * size;
	if (fp->pos > (long)fp->length)
		fp->length = fp->pos;
	return n;
}
Ejemplo n.º 8
0
MC_FILE *
mc_fopen(const char *fullpath, const char *mode)
{
	MC_FILE *fp;

	errno = 0;
	if ((fp = mc_malloc(sizeof(MC_FILE))) == NULL) {
		errno = ENOMEM;
		mc_log_error("mc_fopen: mc_malloc failed\n");
		return NULL;
	}
	fp->ffs = NULL;
	fp->mmapped = NULL;
	fp->buf = NULL;
	fp->bp = fp->bufend = fp->buf;
	fp->length = 0;
	fp->pos = 0;
#if FTFS || !mxMC
	fp->aux = NULL;
#endif
	if ((mode[0] == 'r' && mode[1] != '+') && fullpath[0] != '/') {
		size_t sz;
		const void *p = mc_mmap(fullpath, &sz);
		if (p != NULL) {
			fp->mmapped = p;
			fp->length = sz;
			fp->bp = fp->buf = (uint8_t *)p;
			fp->bufend = fp->buf + sz;
			fp->pos = (long)sz;
		}
		else {
#if FTFS
			if ((fp->aux = mc_ft_fopen(fullpath, mode)) != NULL) {
				fp->length = mc_ft_fseek(fp->aux, 0L, SEEK_END);
				mc_ft_fseek(fp->aux, 0L, SEEK_SET);
			}
			else
				errno = ENOENT;
#else
			errno = ENOENT;
#endif
		}
	}
	else {
		uint32_t flags = 0;
#if !mxMC
		if (sync_with_native_path(fullpath)) {
			const char *path = mc_resolve_path(fullpath, *mode == 'r' ? 0 : 1);
			fp->aux = fopen(path, mode);
			errno = 0;
		}
#endif
		if (strlen(mode) > 1) {
			switch (mode[1]) {
			case '+':
				flags |= FFS_ORDWR;
				break;
			case 'p':
				flags |= FFS_OPASSIVE;
				break;
			case 'a':
				flags |= FFS_OACTIVE;
				break;
			}
		}
		if (mode[0] == 'w')
			flags |= FFS_OTRUNC | FFS_OCREAT;
		if ((fp->ffs = mc_ffs_open(fullpath, flags)) != NULL)
			fp->length = mc_ffs_position(fp->ffs, 1L << 30, mode[0] == 'a');
		else {
			/* errno must've been set */
			if (errno != ENOENT)
				mc_log_error("mc_fopen: ffs_open failed: %d\n", errno);
		}
	}
	if (errno == 0) {
		if (fp->mmapped == NULL) {
			if ((fp->buf = mc_malloc(MC_STREAM_BUFSIZ)) != NULL)
				fp->bufend = fp->bp = fp->buf;
			else {
				mc_log_error("mc_fopen: mc_malloc failed\n");
				errno = ENOMEM;
			}
		}
	}
	if (errno != 0) {
		if (fp != NULL)
			mc_fclose(fp);
		fp = NULL;
	}
	return fp;
}
Ejemplo n.º 9
0
static int
load_elf(const char *path, void **basep, struct mc_module **modp)
{
	struct mc_elf elf;
	unsigned int i;
	uint32_t psize = 0, sz;
	uint8_t *base = NULL;
	uint8_t *paddr = NULL, *adr;
	struct mc_module *mod = NULL;
	int err = -1;

	mc_log_debug("ELF: loading %s...\n", path);
	if (mc_elf_open(path, &elf) != 0) {
		mc_log_error("ELF: cannot open %s\n", path);
		return -1;
	}
	/* calculate the entire program size in VM */
	for (i = 0; i < NUM_EXT_SECTIONS; i++) {
		if (mc_elf_get_section_addr_and_size(&elf, ext_sections[i], &adr, &sz) != 0)
			continue;
		if (adr >= paddr) {
			paddr = adr;
			psize = (uint32_t)paddr + sz;
		}
	}
	mc_log_debug("ELF: allocating %d bytes...\n", (unsigned int)psize);
	if ((base = mc_malloc(psize)) == NULL)
		goto bail;
	/* load each section */
	for (i = 0; i < NUM_EXT_SECTIONS; i++) {
		if (mc_elf_load_section(&elf, ext_sections[i], base) != 0)
			mc_log_error("cannot load %s (%d)\n", ext_sections[i], err);
	}
#if 0
	/* adjust function(?) addresses */
	if (mc_elf_get_section_addr_and_size(&elf, ".got", &adr, &sz) == 0) {
		uint32_t *gadr = (uint32_t *)(adr + (uint32_t)base), *eadr = (uint32_t *)(adr + (uint32_t)base + sz);
		for (; gadr < eadr; gadr++) {
/*
			if (*gadr & 0xf0000000) {
				*gadr = (*gadr & ~0xf0000000) + (uint32_t)base;
				mc_log_debug("adjusted: 0x%lx\n", *gadr);
			}
*/
			*gadr += (uint32_t)base;
		}
	}
#endif
	/* relocate variables */
	if (mc_elf_set_position(&elf, ".rel.dyn") == 0) {
		struct elf_rel rel;
		while (mc_elf_read(&elf, &rel, sizeof(rel)) == 0) {
			switch (ELF32_R_TYPE(rel.info)) {
			case 0x17:	/* R_ARM_RELATIVE */
				*(uint32_t *)(rel.offset + (uint32_t)base) += (uint32_t)base;
				// mc_log_debug("RELOC (rel): %x: %x\n", rel.offset, *(uint32_t *)(rel.offset + (uint32_t)base));
				break;
			case 0x02: {	/* R_ARM_ABS32 */
				struct elf_sym sym;
				if (mc_elf_get(&elf, ".dynsym", &sym, sizeof(sym), ELF32_R_SYM(rel.info)) != 0) {
					mc_log_error("cannot read .dynsym %ld\n", ELF32_R_SYM(rel.info));
					goto bail;
				}
				*(uint32_t *)(rel.offset + (uint32_t)base) = sym.value + (uint32_t)base;
				// mc_log_debug("RELOC (abs): %x: %x\n", rel.offset, *(uint32_t *)(rel.offset + (uint32_t)base));
				break;
			}
			default:
				/* no-op */
				mc_log_error("RELOC unknown type: 0x%x\n", ELF32_R_TYPE(rel.info));
				break;
			}
		}
	}
	paddr = mc_elf_get_entry(&elf);
	// mc_log_debug("ELF: entry = 0x%lx, base = 0x%lx\n", (uint32_t)paddr, (uint32_t)base);
	paddr += (uint32_t)base;
	mod = (struct mc_module *)paddr;
	*mod->stubs = (const void **)ext_stubs;
	*mod->num_stubs = num_ext_stubs;
	*basep = base;
	*modp = mod;
	err = 0;

bail:
	mc_elf_close(&elf);
	if (err != 0 && base != NULL)
		mc_free(base);
	return err;
}