Beispiel #1
0
/*
 * dbg_write(client, adr, buf, len)
 *
 * Writes "len" bytes from "buf" to the memory of client "client" at its address "adr".
 *
 * Return value:
 *	0	Successful
 *	1	Error
 *
 */
int dbg_write(sid_t client, uintptr_t adr, const void* buf, size_t len)
{	
	uintptr_t l__offset = adr & 0xfff;
	uint8_t* l__tmp = dbg_prep_access(client, adr, len, PGA_WRITE);
		
	if (l__tmp == NULL) 
		return 1;
		
	/* Write data to buf */
	buf_copy(&l__tmp[l__offset], buf, len);
	if (*tls_errno)
	{
		dbg_isprintf("Can't copy data in dbg_write, because of %i.\n", *tls_errno);
		*tls_errno = 0;
		
		pmap_free(l__tmp);
		return 1;
	}

	/* Awake the client */
	hymk_awake_subject(client);	
	
	/* Free the buffer */
	pmap_free(l__tmp);
	return 0;
}
Beispiel #2
0
/// Convert a vim object to an `Object` instance, recursively expanding
/// Arrays/Dictionaries.
///
/// @param obj The source object
/// @return The converted value
Object vim_to_object(typval_T *obj)
{
  Object rv;
  // We use a lookup table to break out of cyclic references
  PMap(ptr_t) *lookup = pmap_new(ptr_t)();
  rv = vim_to_object_rec(obj, lookup);
  // Free the table
  pmap_free(ptr_t)(lookup);
  return rv;
}
Beispiel #3
0
/*
 * dbg_prep_access(client, adr, len, op)
 *
 * Prepares the memory access to a client "client" at address "adr"
 * and for a length of "len" bytes. The operation will bei "op" (PGA_READ 
 * or PGA_WRITE).
 *
 * Return value:
 *	!= NULL		VFS memory buffer
 *	== NULL		Error
 */
static void* dbg_prep_access(sid_t client, uintptr_t adr, size_t len, unsigned op)
{
	uintptr_t l__offset = adr & 0xfff;
	unsigned l__flags;
	
	/* Get the count of pages to read */
	int l__pages = len / 4096;
	if (l__offset) l__pages ++;
	if ((adr + len) % 4096) l__pages ++;

	adr &= (~0xfff);

	/* Read the operation flags */
	if (op == PGA_READ)
	{ 
		l__flags = MAP_READ;
	}
	else if (op == PGA_WRITE)
	{
		l__flags = MAP_WRITE;
	}
	else
	{
		return NULL;	
	}

	/* Keep it stopped */
	hymk_freeze_subject(client);
	if (*tls_errno) {dbg_isprintf("Can't freeze 0x%X for accessing to its memory, because of %i.\n", client, adr); *tls_errno = 0; return NULL;}
	
	/* Save its allow status */
	uint32_t l__old_sid = hysys_thrtab_read(client, THRTAB_MEMORY_OP_SID);
	if (*tls_errno) {dbg_isprintf("Can't read from the settings of 0x%X, because of %i.\n", client, adr); *tls_errno = 0; return NULL;}
	
	uintptr_t l__old_destadr = hysys_thrtab_read(client, THRTAB_MEMORY_OP_DESTADR);
	if (*tls_errno) {dbg_isprintf("Can't read from the settings of 0x%X, because of %i.\n", client, adr); *tls_errno = 0; return NULL;}
	
	uint32_t l__old_maxsize = hysys_thrtab_read(client, THRTAB_MEMORY_OP_MAXSIZE);
	if (*tls_errno) {dbg_isprintf("Can't read from the settings of 0x%X, because of %i.\n", client, adr); *tls_errno = 0; return NULL;}
	
	uint32_t l__old_allowed = hysys_thrtab_read(client, THRTAB_MEMORY_OP_ALLOWED);
	if (*tls_errno) {dbg_isprintf("Can't read from the settings of 0x%X, because of %i.\n", client, adr); *tls_errno = 0; return NULL;}
	
	/* Allocate an access buffer */
	void* l__tmp = pmap_alloc(l__pages * 4096);
	if (l__tmp == NULL) 
	{
		dbg_isprintf("Can't allocate %i bytes of VFS memory for sharing, because of %i.\n", l__pages, *tls_errno);
		*tls_errno = 0;
		return NULL;
	}
	
	/* Allow our new operation */
	hymk_allow((*tls_my_thread)->thread_sid, client, (void*)adr, l__pages, ALLOW_MAP|ALLOW_REVERSE);
	if (*tls_errno)
	{
		dbg_isprintf("Can't allow access to 0x%X at 0x%X for %i pages, because of %i.\n", client, adr, l__pages, *tls_errno);
		hymk_awake_subject(client);
		*tls_errno = 0;
		
		pmap_free(l__tmp);
		
		return NULL;
	}
	
	/* Map the page */
	hysys_map(client, l__tmp, l__pages, l__flags|MAP_REVERSE, 0);
	if (*tls_errno)
	{
		dbg_isprintf("Can't map data from client 0x%X, because of %i.\n", client, *tls_errno);
		*tls_errno = 0;
		
		/* Reset allow state */
		hymk_allow(l__old_sid, client, (void*)l__old_destadr, l__old_maxsize, l__old_allowed);
		if (*tls_errno)
		{
			dbg_isprintf("(1) Unable to reset allow state of client thread 0x%X, because of %i.\n", client, *tls_errno);
			*tls_errno = 0;
		}
			
		hymk_awake_subject(client);
			
		pmap_free(l__tmp);
		return NULL;
	}

	/* Reset allow state */
	hymk_allow(l__old_sid, client, (void*)l__old_destadr, l__old_maxsize, l__old_allowed);
	if (*tls_errno)
	{
		dbg_isprintf("(2) Unable to reset allow state of client thread 0x%X, because of %i", client, *tls_errno);
		*tls_errno = 0;
		
		hymk_awake_subject(client);
		
		pmap_free(l__tmp);
		return NULL;
	}
			
	/* Find inactive pages in our mapping by filling it with new page frames */
	uintptr_t l__tmpadr = adr;
	
	while (l__pages --)
	{
		/* There is a page which is not readable... */
		if (!(hymk_test_page(l__tmpadr, client) & op))
		{
			dbg_isprintf("Can't access to 0x%X at 0x%X to page 0x%X. Access denied (PGA-flags 0x%X for 0x%X).\n", client, adr, l__tmpadr, hymk_test_page(l__tmpadr, client), op);
			if (*tls_errno) 
			{
				dbg_isprintf("Can't test rights, because of %i.\n", *tls_errno);
				*tls_errno = 0;
			}
			
			pmap_free(l__tmp);
			return NULL;
		}
		
		l__tmpadr += 4096;
	}
	
	/* Make sure, that we are really access synchronized memory */
	HYSYS_MSYNC();

	return l__tmp;
}