summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/obj.h3
-rw-r--r--arch/x86_64/hal/obj.c15
-rw-r--r--arch/x86_64/hal/obj.h11
-rw-r--r--arch/x86_64/sys/init.c1
-rw-r--r--arch/x86_64/sys/link.c19
-rw-r--r--sys/link.c52
-rw-r--r--sys/link.h21
-rw-r--r--sys/syscall.c29
8 files changed, 119 insertions, 32 deletions
diff --git a/api/obj.h b/api/obj.h
index 4d5e829..a9614b8 100644
--- a/api/obj.h
+++ b/api/obj.h
@@ -15,7 +15,8 @@ enum
JOVE_OBJ_INITRD_FILE,
JOVE_OBJ_FRAMEBUFFER,
JOVE_OBJ_VIRTTERM,
- JOVE_OBJ_MESSAGE
+ JOVE_OBJ_MESSAGE,
+ JOVE_OBJ_LINK,
};
typedef uint16_t objpath_part_t;
diff --git a/arch/x86_64/hal/obj.c b/arch/x86_64/hal/obj.c
index 8011347..c5d5c69 100644
--- a/arch/x86_64/hal/obj.c
+++ b/arch/x86_64/hal/obj.c
@@ -3,6 +3,7 @@
#include "paging.h"
#include "hal/obj.h"
#include "jove.h"
+#include "sys/link.h"
jove_owned_obj_t*
obj_take(jove_obj_t *obj)
@@ -20,7 +21,7 @@ obj_release(jove_owned_obj_t *obj)
if((uintptr_t)obj < IDENT_VIRT_BASE) {
reterr(EBADOBJ);
}
- release_mutex((atomic_flag*)&obj->lock);
+ release_mutex((atomic_flag*)&obj->locked.lock);
return (jove_obj_t*)obj;
}
@@ -33,25 +34,25 @@ obj_deref(jove_owned_obj_t *obj)
uint8_t
obj_gettype(jove_owned_obj_t *obj)
{
- return obj->type;
+ return obj->locked.type;
}
void
obj_settype(jove_owned_obj_t *obj, uint8_t type)
{
- obj->type = type;
+ obj->locked.type = type;
}
uintmax_t
obj_getvalue(jove_owned_obj_t *obj)
{
- return obj->value;
+ return obj->locked.value;
}
void
obj_setvalue(jove_owned_obj_t *obj, uintmax_t value)
{
- obj->value = value & 0x00007FFFFFFFFFFFULL;
+ obj->locked.value = value & 0x00007FFFFFFFFFFFULL;
}
jove_owned_obj_t*
@@ -59,14 +60,14 @@ objdir_getlocal(
jove_owned_obj_t *objdir_obj,
uint16_t entry)
{
- if(objdir_obj->type != JOVE_OBJ_OBJDIR) {
+ if(obj_gettype_linked(objdir_obj) != JOVE_OBJ_OBJDIR) {
reterr(EBADOBJ);
}
if(entry >= JOVE_OBJDIR_ENTRIES) {
reterr(EOOB);
}
- jove_objdir_t *objtab = obj_deref(objdir_obj);
+ jove_objdir_t *objtab = obj_deref_linked(objdir_obj);
return obj_take(&objtab->entries[entry]);
}
diff --git a/arch/x86_64/hal/obj.h b/arch/x86_64/hal/obj.h
index 78d7383..fcb7506 100644
--- a/arch/x86_64/hal/obj.h
+++ b/arch/x86_64/hal/obj.h
@@ -7,7 +7,7 @@
enum
{
- JOVE_OBJ_SERIAL_COM = 0x80,
+ JOVE_OBJ_SERIAL_COM = 0x40,
};
/*Represents a locked kernel object pointer inside of a object directory.*/
@@ -25,14 +25,9 @@ typedef union jove_obj
/*Represents an unlocked kernel object pointer.
*This object should only exist temporarily while accessing the underlying
*structure this object points to.*/
-typedef union jove_obj_locked
+typedef struct jove_locked_obj
{
- struct {
- uint8_t type;
- uint8_t lock;
- uint64_t value : 48;
- };
- uintmax_t data;
+ jove_obj_t locked;
} jove_owned_obj_t;
/*Object directories are always 1 page wide. Since an object inside the directory
diff --git a/arch/x86_64/sys/init.c b/arch/x86_64/sys/init.c
index cecca32..681ba09 100644
--- a/arch/x86_64/sys/init.c
+++ b/arch/x86_64/sys/init.c
@@ -134,7 +134,6 @@ init_setup(void)
}
//Copy data from section if SHT_PROGBITS
- kprintf("init: load %p : %p\n", base, limit);
memcpy((void*)phdr->p_vaddr, init_data + phdr->p_offset, phdr->p_memsz);
}
diff --git a/arch/x86_64/sys/link.c b/arch/x86_64/sys/link.c
new file mode 100644
index 0000000..96f8eeb
--- /dev/null
+++ b/arch/x86_64/sys/link.c
@@ -0,0 +1,19 @@
+#include "sys/link.h"
+
+jove_obj_t
+link_unlink(jove_owned_obj_t *link)
+{
+ struct obj_link *linkval = obj_deref(link);
+ if(--linkval->refcount == 1) {
+ jove_obj_t held_obj = linkval->obj;
+ link->locked = held_obj;
+ return (jove_obj_t) {
+ .lock = 0,
+ .type = JOVE_OBJ_UNTYPED,
+ .value = (uintptr_t)linkval
+ };
+ }else{
+ obj_settype(link, JOVE_OBJ_NONE);
+ }
+ return (jove_obj_t) { 0 };
+}
diff --git a/sys/link.c b/sys/link.c
new file mode 100644
index 0000000..5be9457
--- /dev/null
+++ b/sys/link.c
@@ -0,0 +1,52 @@
+#include "link.h"
+#include "arch/x86_64/hal/obj.h"
+#include "hal/memory.h"
+
+void*
+obj_deref_linked(jove_owned_obj_t *obj)
+{
+ switch(obj_gettype(obj)) {
+ case JOVE_OBJ_LINK: return obj_deref_linked(link_deref(obj));
+ default: return obj_deref(obj);
+ }
+}
+
+uint8_t
+obj_gettype_linked(jove_owned_obj_t *obj)
+{
+ switch(obj_gettype(obj)) {
+ case JOVE_OBJ_LINK: return obj_gettype_linked(link_deref(obj));
+ default: return obj_gettype(obj);
+ }
+}
+
+uint64_t
+obj_getvalue_linked(jove_owned_obj_t *obj)
+{
+ switch(obj_gettype(obj)) {
+ case JOVE_OBJ_LINK: return obj_getvalue_linked(link_deref(obj));
+ default: return obj_getvalue(obj);
+ }
+}
+
+jove_owned_obj_t*
+link_deref(jove_owned_obj_t *link)
+{
+ struct obj_link *linkval = obj_deref(link);
+ return obj_take(&linkval->obj);
+}
+
+jove_owned_obj_t *link_new(jove_obj_t *tgt, jove_owned_obj_t *dst)
+{
+ struct obj_link *linkval = obj_deref(dst);
+ linkval->obj = *tgt;
+ linkval->refcount = 2;
+
+ {
+ jove_owned_obj_t *tgt_owned = obj_take(tgt);
+ obj_settype(tgt_owned, JOVE_OBJ_LINK);
+ obj_setvalue(tgt_owned, (uintptr_t)linkval);
+ obj_release(tgt_owned);
+ }
+ return dst;
+}
diff --git a/sys/link.h b/sys/link.h
new file mode 100644
index 0000000..37fa1e8
--- /dev/null
+++ b/sys/link.h
@@ -0,0 +1,21 @@
+#ifndef _JOVE_SYS_LINK_HPP
+#define _JOVE_SYS_LINK_HPP 1
+
+#include "hal/obj.h"
+
+struct obj_link
+{
+ size_t refcount;
+ jove_obj_t obj;
+};
+
+void *obj_deref_linked(jove_owned_obj_t *obj);
+uint8_t obj_gettype_linked(jove_owned_obj_t *obj);
+uint64_t obj_getvalue_linked(jove_owned_obj_t *obj);
+
+jove_owned_obj_t *link_deref(jove_owned_obj_t *link);
+jove_obj_t link_unlink(jove_owned_obj_t *link);
+
+jove_owned_obj_t *link_new(jove_obj_t *tgt, jove_owned_obj_t *dst);
+
+#endif
diff --git a/sys/syscall.c b/sys/syscall.c
index 68a5ae6..9a98030 100644
--- a/sys/syscall.c
+++ b/sys/syscall.c
@@ -4,6 +4,7 @@
#include "hal/process.h"
#include "jove.h"
#include "lib/printf.h"
+#include "sys/link.h"
#include "sys/message.h"
int
@@ -33,6 +34,7 @@ static const syscall_handle_t s_syscall_handles[128] = {
[JOVE_OBJ_FRAMEBUFFER] = _syscall_handle_generic,
[JOVE_OBJ_VIRTTERM] = _syscall_handle_vtt,
[JOVE_OBJ_MESSAGE] = _syscall_handle_generic,
+ [JOVE_OBJ_LINK] = _syscall_handle_generic,
};
int
@@ -55,15 +57,11 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
return errno;
}
-#define SYSCALL_MIDWAY_CLEANUP \
- obj_release(message_obj); \
- obj_release(objdir); \
- obj_release(pcb_obj)
-
- if(obj_gettype(message_obj) != JOVE_OBJ_MESSAGE) {
+ int sysret = 0;
+ if(obj_gettype_linked(message_obj) != JOVE_OBJ_MESSAGE) {
kprintf("syscall: Process %i tried to call syscall with invalid object: %P\n", pcb_pid(pcb), message_path, message_pathlen);
- SYSCALL_MIDWAY_CLEANUP;
- return EBADOBJ;
+ sysret = EBADOBJ;
+ goto release_return;
}
size_t messagelen = message_len(message_obj);
@@ -75,18 +73,17 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
if(bytes_left < 0) {
//Target path exceeds message length.
kprintf("syscall: Process %i tried to call syscall with OOB target path.\n", pcb_pid(pcb));
- SYSCALL_MIDWAY_CLEANUP;
- return EBADPATH;
+ sysret = EBADPATH;
+ goto release_return;
}
jove_owned_obj_t *target = objdir_getobj(objdir, header->path, header->pathlen);
if(target == 0) {
//Could not find payload target in pcb rootdir.
kprintf("syscall: Process %i tried to call syscall with bad target path %P\n",
pcb_pid(pcb), header->path, header->pathlen);
- SYSCALL_MIDWAY_CLEANUP;
- return errno;
+ sysret = errno;
+ goto release_return;
}
- int sysret = 0;
uint8_t target_type = obj_gettype(target);
if(target_type > 0x7F) {
@@ -104,8 +101,10 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
pcb_obj, objdir, message_obj, target,
header, bytes_left, messagedata + header_bytes);
}
-
obj_release(target);
- SYSCALL_MIDWAY_CLEANUP;
+release_return:
+ obj_release(message_obj);
+ obj_release(objdir);
+ obj_release(pcb_obj);
return sysret;
}