Permalink
Browse files

dynamic linking finished

  • Loading branch information...
1 parent 21f0392 commit e62f64db9957776d6593d39c38b0cd653f356bb6 @nickbjohnson4224 committed Dec 10, 2011
Showing with 255 additions and 21 deletions.
  1. +1 −1 Makefile
  2. +1 −1 TODO
  3. +4 −4 daemon/init/main.c
  4. +52 −0 dl/dep.c
  5. +1 −0 dl/dl.h
  6. +1 −1 dl/elfc.c
  7. +21 −2 dl/exec.c
  8. +1 −0 dl/interface.c
  9. +13 −0 dl/layout.c
  10. +1 −1 dl/load.c
  11. +53 −0 dl/pull.c
  12. +28 −0 libc/exec/dl.c
  13. +10 −7 libc/exec/exec.c
  14. +3 −0 libc/inc/rho/exec.h
  15. BIN libc/libc.so.1
  16. +0 −3 libc/stdlib/malloc.c
  17. BIN librdi/librdi.so.1
  18. +1 −1 ports/lua/Makefile
  19. +28 −0 util/layout/Makefile
  20. +36 −0 util/layout/main.c
View
@@ -21,7 +21,7 @@ CFLAGS += -Wpointer-arith -Wwrite-strings
CFLAGS += -Wno-unused-parameter -Wno-unused-function
CFLAGS += -O3 -fomit-frame-pointer
CFLAGS += -I$(BUILDDIR)/inc -ffreestanding -fPIC
-LDFLAGS := -L$(BUILDDIR)/lib -static
+LDFLAGS := -L$(BUILDDIR)/lib -Bdynamic
ARFLAGS := rcs
PPFLAGS := -x assembler-with-cpp -I$(BUILDDIR)/inc
View
2 TODO
@@ -88,7 +88,7 @@ For 0.9 Alpha:
+ shared object symbol lookup (basic)
+ dynamic symbol resolution (PLT)
+ dependency graph traversal
- - dependency loading
+ + dependency loading
- finishing touches
+ dl optimization
View
@@ -60,10 +60,10 @@ int main() {
boot_image = tar_parse((void*) BOOT_IMAGE);
/* Load shared libraries for drivers */
-// file = tar_find(boot_image, "lib/libc.so.1");
-// dlload(file->start, file->size, 0);
-// file = tar_find(boot_image, "lib/librdi.so.1");
-// dlload(file->start, file->size, 0);
+ file = tar_find(boot_image, "lib/libc.so.1");
+ if (file) dlpull(file->start, file->size, 0);
+ file = tar_find(boot_image, "lib/librdi.so.1");
+ if (file) dlpull(file->start, file->size, 0);
/* Initial Root Filesystem / Device Filesystem / System Filesystem (tmpfs) */
argv[0] = "tmpfs";
View
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009-2011 Nick Johnson <nickbjohnson4224 at gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include <rho/layout.h>
+#include <rho/arch.h>
+#include <rho/exec.h>
+
+#include "dl.h"
+
+char *_dep(void *object, uint32_t index, int loaded) {
+ struct elf_cache cache;
+ const char *name;
+ size_t i;
+
+ if (loaded) {
+ elf_gencache(&cache, object);
+ }
+ else {
+ elf_gencache_img(&cache, object);
+ }
+
+ if (!cache.dynamic) {
+ return NULL;
+ }
+
+ name = NULL;
+ for (i = 0; cache.dynamic[i].tag != DT_NULL; i++) {
+ if (cache.dynamic[i].tag == DT_NEEDED) {
+ if (!index--) {
+ name = &cache.strtab[cache.dynamic[i].val];
+ }
+ }
+ }
+
+ return (char*) name;
+}
View
@@ -34,6 +34,7 @@
*/
void *_load(void *image, size_t size, int flags);
+void *_pull(void *image, size_t size, int flags);
int _exec(void *image, size_t size, int flags);
int _init(void *object);
View
@@ -205,7 +205,7 @@ static const struct elf32_ehdr *elfc_get_needed(struct elf_cache *cache, size_t
return NULL;
}
- strlcpy(objname, "dl.so:", 28);
+ strlcpy(objname, "dl.obj:", 28);
strlcat(objname, soname, 28);
slt = sltget_name(objname);
View
@@ -32,6 +32,9 @@ int _exec(void *image, size_t size, int flags) {
void *entry;
size_t i;
+ const char *soname;
+ char imgname[28];
+
/* check executable */
if (elf_check(image)) {
return 1;
@@ -40,7 +43,7 @@ int _exec(void *image, size_t size, int flags) {
/*** POINT OF MAYBE RETURNING IF YOU, y'know, have to... ***/
/* copy executable high */
- temp = exec = (void*) sltalloc("dl.img.exec", size);
+ temp = exec = (void*) sltalloc("dl.img:exec", size);
if ((uintptr_t) image % PAGESZ) {
/* not aligned, copy */
@@ -54,6 +57,22 @@ int _exec(void *image, size_t size, int flags) {
/*** POINT OF NO RETURN ***/
+ /* load dependencies */
+ for (i = 0;; i++) {
+ soname = _dep(exec, i, 0);
+ if (!soname) break;
+
+ strlcpy(imgname, "dl.img:", 28);
+ strlcat(imgname, soname, 28);
+
+ slt = sltget_name(imgname);
+ if (!slt) continue;
+
+ _load((void*) slt->base, slt->size, 0);
+
+ sltfree_name(imgname);
+ }
+
/* clear lower memory */
slt = (void*) SLT_BASE;
slt_hdr = (void*) SLT_BASE;
@@ -74,7 +93,7 @@ int _exec(void *image, size_t size, int flags) {
/* remove executable image */
page_free(temp, size);
- sltfree_name("dl.img.exec");
+ sltfree_name("dl.img:exec");
/* reset event handler */
_when(0);
View
@@ -26,6 +26,7 @@
__attribute__ ((section (".head")))
struct dl __interface__ = {
.load = _load,
+ .pull = _pull,
.exec = _exec,
.dep = _dep,
View
@@ -17,13 +17,18 @@
#include <string.h>
#include <rho/layout.h>
+#include <rho/page.h>
void *sltalloc(const char *name, size_t size) {
struct slt32_entry *slt = (void*) SLT_BASE;
struct slt32_header *slt_hdr = (void*) SLT_BASE;
uint32_t base;
uint32_t i, t;
+ if (sltget_name(name)) {
+ sltfree_name(name);
+ }
+
size = (size & 0xFFF) ? (size & ~0xFFF) + 0x1000 : size;
base = 0;
@@ -67,6 +72,8 @@ void sltfree_addr(void *addr) {
i = slt_hdr->first;
if (slt[i].base <= (uint32_t) addr && (uint32_t) addr > slt[i].base + slt[i].size) {
+ page_free((void*) slt[i].base, slt[i].size);
+
slt_hdr->first = slt[i].next;
slt[i].next = slt_hdr->free;
slt_hdr->free = i;
@@ -77,6 +84,8 @@ void sltfree_addr(void *addr) {
else while (slt[i].next) {
if (slt[slt[i].next].base <= (uint32_t) addr
&& (uint32_t) addr < slt[slt[i].next].base + slt[slt[i].next].size) {
+ page_free((void*) slt[slt[i].next].base, slt[slt[i].next].size);
+
t = slt[i].next;
slt[i].next = slt[slt[i].next].next;
slt[t].next = slt_hdr->free;
@@ -103,6 +112,8 @@ void sltfree_name(const char *name) {
i = slt_hdr->first;
if (slt[i].hash == hash && !strcmp(slt[i].name, name)) {
+ page_free((void*) slt[i].base, slt[i].size);
+
slt_hdr->first = slt[i].next;
slt[i].next = slt_hdr->free;
slt_hdr->free = i;
@@ -112,6 +123,8 @@ void sltfree_name(const char *name) {
}
else while (slt[i].next) {
if (slt[slt[i].next].hash == hash && !strcmp(slt[slt[i].next].name, name)) {
+ page_free((void*) slt[slt[i].next].base, slt[slt[i].next].size);
+
t = slt[i].next;
slt[i].next = slt[slt[i].next].next;
slt[t].next = slt_hdr->free;
View
@@ -35,7 +35,7 @@ void *_load(void *image, size_t size, int flags) {
}
elf_gencache(&cache, elf32);
- strlcpy(regname, "dl.so:", 28);
+ strlcpy(regname, "dl.obj:", 28);
strlcat(regname, cache.soname, 28);
object = sltalloc(regname, cache.vsize);
View
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009-2011 Nick Johnson <nickbjohnson4224 at gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include <rho/layout.h>
+#include <rho/arch.h>
+#include <rho/exec.h>
+#include <rho/page.h>
+
+#include "dl.h"
+
+void *_pull(void *image, size_t size, int flags) {
+ struct elf32_ehdr *elf32 = image;
+ struct elf_cache cache;
+ char regname[28];
+ void *object;
+
+ /* check executable */
+ if (!elf32 || elf_check(elf32)) {
+ return NULL;
+ }
+
+ elf_gencache(&cache, elf32);
+ strlcpy(regname, "dl.img:", 28);
+ strlcat(regname, cache.soname, 28);
+
+ object = sltalloc(regname, size);
+
+// if ((uintptr_t) elf32 % PAGESZ) {
+ page_anon(object, size, PROT_READ | PROT_WRITE);
+ memcpy(object, elf32, size);
+// }
+// else {
+// page_self(object, elf32, size);
+// }
+
+ return (void*) object;
+}
View
@@ -111,6 +111,34 @@ void *dlload(void *image, size_t size, int flags) {
return dl->load(image, size, flags);
}
+void *dlpopen(const char *filename, int flags) {
+ void *image;
+ const char *depname;
+ char *deppath;
+ size_t i;
+
+ image = load_exec(filename);
+
+ if (!image) {
+ return NULL;
+ }
+
+ for (i = 0;; i++) {
+ depname = dldep(image, i, 0);
+ if (!depname) break;
+
+ deppath = strvcat("/lib/", depname, NULL);
+ dlpopen(deppath, 0);
+ free(deppath);
+ }
+
+ return dlpull(image, msize(image), flags);
+}
+
+void *dlpull(void *image, size_t size, int flags) {
+ return dl->pull(image, size, flags);
+}
+
void dlexec(void *object, char const **argv, char const **envp);
void dlclose(void *object);
View
@@ -40,6 +40,7 @@ int execiv(uint8_t *image, size_t size, char const **argv) {
char *pack;
char *deppath;
void *pack_region;
+ void *object;
uint32_t i;
if (!image) {
@@ -74,14 +75,16 @@ int execiv(uint8_t *image, size_t size, char const **argv) {
free(pack);
}
- /* load all dependencies */
- for (i = 0;; i++) {
- depname = dldep(image, i, 0);
- if (!depname) break;
+ /* pull all dependencies */
+ if (getppid() != 1) { // XXX - hack to prevent this from running on init
+ for (i = 0;; i++) {
+ depname = dldep(image, i, 0);
+ if (!depname) break;
- deppath = strvcat("/lib/", depname, NULL);
- dlopen(deppath, 0);
- free(deppath);
+ deppath = strvcat("/lib/", depname, NULL);
+ object = dlpopen(deppath, 0);
+ free(deppath);
+ }
}
if (dl->exec(image, size, 0)) {
View
@@ -46,6 +46,7 @@ char **loadarg(char *pack);
struct dl {
void *(*load) (void *image, size_t size, int flags);
+ void *(*pull) (void *image, size_t size, int flags);
int (*exec) (void *image, size_t size, int flags);
int (*init) (void *object);
@@ -66,7 +67,9 @@ struct dl {
extern struct dl *dl;
void *dlopen (const char *filename, int flags);
+void *dlpopen(const char *filename, int flags);
void *dlload (void *image, size_t size, int flags);
+void *dlpull (void *image, size_t size, int flags);
void dlinit (void *object);
void dlfini (void *object);
void dlexec (void *object, char const **argv, char const **envp);
View
Binary file not shown.
View
@@ -231,9 +231,6 @@ static struct heap_node *_find_node(uintptr_t index) {
// construct new tree (only happens on first allocation)
_tree = new_heap_node();
- if (sltget_name("libc.heap")) {
- sltfree_name("libc.heap");
- }
sltalloc("libc.heap", 0x20000000);
slt = sltget_name("libc.heap");
View
Binary file not shown.
View
@@ -5,7 +5,7 @@
CFLAGS += -Wno-cast-align
RANLIB := i586-pc-rhombus-ranlib
RM := rm -f
-LIBS := $(BUILDDIR)/lib/c0.o -lc
+LIBS := $(BUILDDIR)/lib/c0.o -Bdynamic -lc
SUBDIR := ports/lua
LUA_A= liblua.a
Oops, something went wrong.

0 comments on commit e62f64d

Please sign in to comment.