/* * 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; }
/// 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; }
/* * 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; }