[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH 3/7] init: loader_get_library() implementiert



+ libc: Ein neuer Callback loader_get_library() für den ELF-Loader, der
  ein ELF-Image einer Shared Library in den Speicher lädt

+ init: Implementierung von loader_get_library()

Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
 src/include/loader.h            | 11 ++++++
 src/kernel2/src/tasks/modules.c |  9 +++++
 src/modules/init/loader.c       | 82 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+)

diff --git a/src/include/loader.h b/src/include/loader.h
index 55c982b..0084613 100644
--- a/src/include/loader.h
+++ b/src/include/loader.h
@@ -88,6 +88,17 @@ bool loader_assign_mem(pid_t process, vaddr_t dest_address,
     vaddr_t src_address, size_t size);
 
 /**
+ * Lädt eine Shared Library in den Speicher.
+ *
+ * @param name Name der Shared Library
+ * @param image Enthält bei Erfolg einen Pointer auf ein Binärimage
+ * @param size Enthält bei Erfolg die Größe des Binärimages in Bytes
+ *
+ * @return 0 bei Erfolg, -errno im Fehlerfall
+ */
+int loader_get_library(const char* name, void** image, size_t* size);
+
+/**
  * Erstellt einen neuen Thread.
  *
  * @param process PID
diff --git a/src/kernel2/src/tasks/modules.c b/src/kernel2/src/tasks/modules.c
index 610498c..8d3c090 100644
--- a/src/kernel2/src/tasks/modules.c
+++ b/src/kernel2/src/tasks/modules.c
@@ -40,6 +40,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <loader.h>
+#include <errno.h>
 #include <syscall_structs.h>
 
 #include "multiboot.h"
@@ -275,6 +276,14 @@ bool loader_assign_mem(pid_t pid, vaddr_t dest_address,
 }
 
 /**
+ * Lädt eine Shared Library in den Speicher.
+ */
+int loader_get_library(const char* name, void** image, size_t* size)
+{
+    return -ENOSYS;
+}
+
+/**
  * Erstellt einen Thread in einem Prozess der anhand seiner PID gefunden wird.
  */
 bool loader_create_thread(pid_t pid, vaddr_t address) {
diff --git a/src/modules/init/loader.c b/src/modules/init/loader.c
index 58649e2..e3d67ba 100644
--- a/src/modules/init/loader.c
+++ b/src/modules/init/loader.c
@@ -38,6 +38,9 @@
 #include <loader.h>
 #include <lock.h>
 #include <init.h>
+#include <errno.h>
+#include <lostio.h>
+#include <stdlib.h>
 
 static struct {
     pid_t   pid;
@@ -46,6 +49,8 @@ static struct {
     lock_t  lock;
 } loader_state;
 
+size_t ainflate(void* src, size_t len, void** dest_ptr);
+
 /**
  * Speicher allozieren um ihn spaeter in einen neuen Prozess zu mappen. Diese
  * Funktion sollte nicht fuer "normale" Allokationen benutzt werden, da immer
@@ -80,6 +85,83 @@ bool loader_assign_mem(pid_t process, vaddr_t dest_address,
     return true;
 }
 
+/**
+ * Lädt eine Shared Library in den Speicher.
+ *
+ * @param name Name der Shared Library
+ * @param image Enthält bei Erfolg einen Pointer auf ein Binärimage
+ * @param size Enthält bei Erfolg die Größe des Binärimages in Bytes
+ *
+ * @return 0 bei Erfolg, -errno im Fehlerfall
+ */
+int loader_get_library(const char* name, void** image, size_t* size)
+{
+    io_resource_t* fd;
+    char* path;
+    void* p;
+    int ret;
+
+    ret = asprintf(&path, "file:/system/%s.so", name);
+    if (ret < 0) {
+        return -ENOMEM;
+    }
+
+    fd = lio_compat_open(path, IO_OPEN_MODE_READ);
+    free(path);
+    if (fd == NULL) {
+        return -ENOENT;
+    }
+
+    if (!lio_compat_seek(fd, 0, SEEK_END)) {
+        ret = -EIO;
+        goto fail;
+    }
+
+    ret = lio_compat_tell(fd);
+    if (ret < 0) {
+        goto fail;
+    }
+    *size = ret;
+
+    if (!lio_compat_seek(fd, 0, SEEK_SET)) {
+        ret = -EIO;
+        goto fail;
+    }
+
+    p = malloc(*size);
+    if (p == NULL) {
+        ret = -ENOMEM;
+        goto fail;
+    }
+
+    ret = lio_compat_read(p, 1, *size, fd);
+    if (ret < 0) {
+        free(p);
+        goto fail;
+    }
+
+    if (*(uint16_t*) p == 0x8b1f) {
+        /* gzip, erstmal entpacken */
+        void* buf;
+        size_t buf_len;
+
+        buf_len = ainflate(p, *size, &buf);
+        if (buf_len == 0) {
+            ret = -EINVAL;
+            goto fail;
+        }
+
+        free(p);
+        p = buf;
+        *size = buf_len;
+    }
+
+    *image = p;
+    ret = 0;
+fail:
+    lio_compat_close(fd);
+    return ret;
+}
 
 /**
  * Erstellt einen neuen Thread.
-- 
2.1.4