[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