Permalink
Browse files

dynamic linking effectively working, no dependency loading

  • Loading branch information...
1 parent f10bb60 commit f946b23edc6261c43cfdfb4c69f09d4aa16814c9 @nickbjohnson4224 committed Dec 9, 2011
Showing with 183 additions and 41 deletions.
  1. +1 −1 Makefile
  2. +1 −1 daemon/init/Makefile
  3. +6 −0 daemon/init/main.c
  4. +1 −1 dl/Makefile
  5. +8 −6 dl/dl.h
  6. +18 −2 dl/elf.c
  7. +112 −7 dl/elfc.c
  8. +5 −11 dl/exec.c
  9. +6 −1 dl/plt_resolve.c
  10. +0 −5 fish/main.c
  11. +1 −1 kernel/fault/fault_page.c
  12. +12 −0 libc/c0.s
  13. +0 −1 libc/exec/exec.c
  14. +2 −2 libc/init/init.c
  15. +8 −0 libc/ipc/_on_event.s
  16. +1 −1 librdi/Makefile
  17. +1 −1 util/echo/Makefile
View
@@ -65,7 +65,7 @@ image: all
@ cp bin/* boot/bin
@ cp lib/dl.so boot/lib
@ cp lib/libc.so boot/lib
- @ cp lib/libtest.so boot/lib
+ @ cp lib/librdi.so boot/lib
@ cp sbin/* boot/sbin
# @ cp -r etc/* boot/etc
View
@@ -4,7 +4,7 @@ SOURCES += $(BUILDDIR)/lib/c0.o
SUBDIR := daemon/init
TARGET := init
CFLAGS += -I$(BUILDDIR)/$(SUBDIR)/inc
-LDFLAGS += -lrdi -lc -static
+LDFLAGS += -static -lrdi -lc
ASFLAGS := -felf
all: $(TARGET)
View
@@ -59,6 +59,12 @@ int main() {
/* Boot Image */
boot_image = tar_parse((void*) BOOT_IMAGE);
+ /* Load shared libraries for drivers */
+ file = tar_find(boot_image, "lib/libc.so");
+ dlload(file->start, file->size, 0);
+ file = tar_find(boot_image, "lib/librdi.so");
+ dlload(file->start, file->size, 0);
+
/* Initial Root Filesystem / Device Filesystem / System Filesystem (tmpfs) */
argv[0] = "tmpfs";
argv[1] = NULL;
View
@@ -3,7 +3,7 @@ SOURCES += $(patsubst %.s,%.o,$(shell find . -name "*.s"))
SUBDIR := dl
HEADERS := $(shell find . -name "*.h")
TARGET := dl.so
-LDFLAGS := -T$(BUILDDIR)/$(SUBDIR)/link.ld
+LDFLAGS := -T$(BUILDDIR)/$(SUBDIR)/link.ld -static
ASFLAGS := -felf
all: $(TARGET)
View
14 dl/dl.h
@@ -70,12 +70,14 @@ struct elf_cache {
const uint32_t *pltgot;
};
-void elf_gencache(struct elf_cache *cache, const struct elf32_ehdr *image);
-
-uint32_t elfc_resolve (struct elf_cache *cache, const char *symbol);
-uint32_t elfc_relocate (struct elf_cache *cache, const struct elf32_rel *rel);
-void elfc_relocate_all (struct elf_cache *cache);
-void elfc_relocate_exec(struct elf_cache *cache);
+void elf_gencache (struct elf_cache *cache, const struct elf32_ehdr *image);
+void elf_gencache_exec(struct elf_cache *cache, const struct elf32_ehdr *image);
+
+uint32_t elfc_resolve (struct elf_cache *cache, const char *symbol);
+uint32_t elfc_relocate (struct elf_cache *cache, const struct elf32_rel *rel);
+void elfc_relocate_all (struct elf_cache *cache);
+uint32_t elfc_relocate_exec (struct elf_cache *cache, const struct elf32_rel *rel);
+void elfc_relocate_all_exec(struct elf_cache *cache);
int dl_enter(void *entry_ptr);
View
@@ -55,8 +55,24 @@ static void _elf_load_phdr(const struct elf32_ehdr *file, uintptr_t base, const
else {
/* is a read-only data/code segment */
- /* move memory */
- page_self((void*) seg_base, dst, phdr->p_filesz);
+ if ((uint32_t) seg_base % PAGESZ) {
+ /* image not page-aligned; copy */
+
+ /* allocate memory */
+ page_anon(dst, phdr->p_memsz, PROT_READ | PROT_WRITE);
+
+ /* copy data */
+ memcpy(dst, seg_base, phdr->p_filesz);
+
+ /* clear rest of segment */
+ memclr(&dst[phdr->p_filesz], phdr->p_memsz - phdr->p_filesz);
+ }
+ else {
+ /* image page-aligned; page flip */
+
+ /* move memory */
+ page_self((void*) seg_base, dst, phdr->p_filesz);
+ }
}
/* set proper permissions */
View
119 dl/elfc.c
@@ -70,6 +70,49 @@ uint32_t elfc_relocate(struct elf_cache *cache, const struct elf32_rel *rel) {
return symbol_value;
}
+uint32_t elfc_relocate_exec(struct elf_cache *cache, const struct elf32_rel *rel) {
+ const struct elf32_sym *symbol = NULL;
+ uint32_t *image32 = (void*) 0;
+ uint32_t symbol_value;
+
+ /* compute symbol value if needed */
+ switch (ELF32_R_TYPE(rel->r_info)) {
+ case R_386_GLOB_DAT:
+ case R_386_JMP_SLOT:
+ case R_386_32:
+ symbol = &cache->symtab[ELF32_R_SYM(rel->r_info)];
+
+ if (symbol->st_value) {
+ symbol_value = symbol->st_value;
+ }
+ else {
+ symbol_value = elfc_resolve(cache, &cache->strtab[symbol->st_name]);
+ }
+ break;
+ default:
+ symbol_value = 0;
+ }
+
+ /* perform relocation */
+ switch (ELF32_R_TYPE(rel->r_info)) {
+ case R_386_NONE:
+ case R_386_RELATIVE:
+ break;
+ break;
+ case R_386_GLOB_DAT:
+ case R_386_JMP_SLOT:
+ image32[rel->r_offset / 4] = symbol_value;
+ break;
+ case R_386_32:
+ image32[rel->r_offset / 4] += symbol_value;
+ break;
+ default:
+ break;
+ }
+
+ return symbol_value;
+}
+
/*****************************************************************************
* elfc_relocate_all
*
@@ -85,8 +128,10 @@ void elfc_relocate_all(struct elf_cache *cache) {
}
/* add special entries to GOT for PLT resolution */
- ((uint32_t*) cache->pltgot)[1] = (uint32_t) cache->image;
- ((uint32_t*) cache->pltgot)[2] = (uint32_t) __plt_resolve;
+ if (cache->pltgot) {
+ ((uint32_t*) cache->pltgot)[1] = (uint32_t) cache->image;
+ ((uint32_t*) cache->pltgot)[2] = (uint32_t) __plt_resolve;
+ }
/* perform normal relocations (data) */
if (cache->reltab) {
@@ -103,7 +148,7 @@ void elfc_relocate_all(struct elf_cache *cache) {
}
}
-void elfc_relocate_exec(struct elf_cache *cache) {
+void elfc_relocate_all_exec(struct elf_cache *cache) {
size_t i;
/* only relocate dynamic objects */
@@ -112,13 +157,15 @@ void elfc_relocate_exec(struct elf_cache *cache) {
}
/* add special entries to GOT for PLT resolution */
- ((uint32_t*) cache->pltgot)[1] = (uint32_t) cache->image;
- ((uint32_t*) cache->pltgot)[2] = (uint32_t) __plt_resolve;
+ if (cache->pltgot) {
+ ((uint32_t*) cache->pltgot)[1] = (uint32_t) cache->image;
+ ((uint32_t*) cache->pltgot)[2] = (uint32_t) __plt_resolve;
+ }
/* perform normal relocations (data) */
if (cache->reltab) {
for (i = 0; i < cache->reltabn; i++) {
- elfc_relocate(cache, &cache->reltab[i]);
+ elfc_relocate_exec(cache, &cache->reltab[i]);
}
}
}
@@ -317,7 +364,7 @@ void elf_gencache(struct elf_cache *cache, const struct elf32_ehdr *image) {
/* calulate image size */
for (i = 0; cache->segtab[i].p_type == PT_LOAD || cache->segtab[i].p_type == PT_DYNAMIC; i++);
- if (i) cache->vsize = cache->segtab[i - 1].p_vaddr + cache->segtab[i - 1].p_memsz;
+ if (i) cache->vsize = cache->segtab[i - 1].p_vaddr + cache->segtab[i - 1].p_memsz + 0x1000;
/* get DYNAMIC segment */
cache->dynamic = NULL;
@@ -339,6 +386,7 @@ void elf_gencache(struct elf_cache *cache, const struct elf32_ehdr *image) {
cache->strtab = NULL;
cache->pltgot = NULL;
cache->hash = NULL;
+ cache->soname = NULL;
for (i = 0; cache->dynamic[i].tag != DT_NULL; i++) {
switch (cache->dynamic[i].tag) {
case DT_SYMTAB: cache->symtab = (const struct elf32_sym*) (base + cache->dynamic[i].val); break;
@@ -355,3 +403,60 @@ void elf_gencache(struct elf_cache *cache, const struct elf32_ehdr *image) {
cache->soname = (cache->soname) ? &cache->strtab[(uintptr_t) cache->soname] : NULL;
}
+
+/*****************************************************************************
+ * elf_gencache_exec
+ *
+ * Generate an ELF cached image from an ELF image, storing the cache data in
+ * <cache>. This cache data is used to make lookups of various information
+ * about the image much faster.
+ */
+
+void elf_gencache_exec(struct elf_cache *cache, const struct elf32_ehdr *image) {
+ size_t i;
+
+ cache->image = image;
+
+ /* get segment table */
+ cache->segtab = (const struct elf32_phdr*) (image->e_phoff + (uintptr_t) image);
+
+ /* calulate image size */
+ cache->vsize = 0;
+
+ /* get DYNAMIC segment */
+ cache->dynamic = NULL;
+ for (i = 0; cache->segtab[i].p_type != PT_NULL; i++) {
+ if (cache->segtab[i].p_type == PT_DYNAMIC) {
+ cache->dynamic = (const struct elf32_dyn*) cache->segtab[i].p_vaddr;
+ break;
+ }
+ }
+
+ if (!cache->dynamic) {
+ return;
+ }
+
+ /* get various DYNAMIC values */
+ cache->symtab = NULL;
+ cache->reltab = NULL;
+ cache->jmprel = NULL;
+ cache->strtab = NULL;
+ cache->pltgot = NULL;
+ cache->hash = NULL;
+ cache->soname = NULL;
+ for (i = 0; cache->dynamic[i].tag != DT_NULL; i++) {
+ switch (cache->dynamic[i].tag) {
+ case DT_SYMTAB: cache->symtab = (const struct elf32_sym*) cache->dynamic[i].val; break;
+ case DT_REL: cache->reltab = (const struct elf32_rel*) cache->dynamic[i].val; break;
+ case DT_RELSZ: cache->reltabn = cache->dynamic[i].val / 8; break;
+ case DT_JMPREL: cache->jmprel = (const struct elf32_rel*) cache->dynamic[i].val; break;
+ case DT_PLTRELSZ: cache->jmpreln = cache->dynamic[i].val / 8; break;
+ case DT_STRTAB: cache->strtab = (const char*) cache->dynamic[i].val; break;
+ case DT_PLTGOT: cache->pltgot = (const uint32_t*) cache->dynamic[i].val; break;
+ case DT_HASH: cache->hash = (const uint32_t*) cache->dynamic[i].val; break;
+ case DT_SONAME: cache->soname = (const char*) cache->dynamic[i].val; break;
+ }
+ }
+
+ cache->soname = (cache->soname) ? &cache->strtab[(uintptr_t) cache->soname] : NULL;
+}
View
@@ -65,18 +65,12 @@ int _exec(void *image, size_t size, int flags) {
}
/* load executable */
- if (exec->e_type == ET_EXEC) {
- elf_load(exec, 0);
- exec = (void*) 0x100000;
- entry = (void*) exec->e_entry;
- }
- else {
- elf_load(exec, 0x100000);
- entry = (void*) (exec->e_entry + 0x100000);
+ elf_load(exec, 0);
+ exec = (void*) 0x100000;
+ entry = (void*) exec->e_entry;
- elf_gencache(&cache, exec);
- elfc_relocate_all(&cache);
- }
+ elf_gencache_exec(&cache, exec);
+ elfc_relocate_all_exec(&cache);
/* remove executable image */
page_free(temp, size);
View
@@ -19,6 +19,11 @@
uint32_t _plt_resolve(struct elf32_ehdr *image, uint32_t index) {
struct elf_cache cache;
+ if (image == (void*) 0x100000) {
+ elf_gencache_exec(&cache, image);
+ return elfc_relocate_exec(&cache, &cache.jmprel[index / 8]);
+ }
+
elf_gencache(&cache, image);
- return elfc_relocate(&cache, &cache.jmprel[index]);
+ return elfc_relocate(&cache, &cache.jmprel[index / 8]);
}
View
@@ -136,11 +136,6 @@ int main() {
size_t i, n;
char *argv[100];
- uint32_t *object;
-
- object = dlopen("/lib/libc.so", 0);
- printf("libc.so:\t%p\n", object);
-
setenv("PWD", "/");
while (1) {
@@ -60,7 +60,7 @@ struct thread *fault_page(struct thread *image) {
debug_printf("user stack: %x - %x\n", image->stack, image->stack + SEGSZ);
debug_printf("user stack dump: (ebp = %x)\n", image->ebp);
debug_dumpi((void*) image->useresp, 30);
-// debug_panic("page fault exception");
+ debug_panic("page fault exception");
process_freeze(image->proc);
return thread_send(image, image->proc->pid, PORT_PAGE, NULL);
View
@@ -18,6 +18,18 @@ section .text
global _start
extern _init
+extern main
+
+extern _GLOBAL_OFFSET_TABLE_
_start:
+
+ call .getgot
+.getgot:
+ pop ebx
+ add ebx, _GLOBAL_OFFSET_TABLE_+$$-.getgot wrt ..gotpc
+
+ mov eax, [ebx+main wrt ..got]
+ push eax
+
call _init wrt ..plt; libc initialization, runs main and exits
View
@@ -71,7 +71,6 @@ int execiv(uint8_t *image, size_t size, char const **argv) {
free(pack);
}
-
if (dl->exec(image, size, 0)) {
errno = ENOEXEC;
return -1;
View
@@ -105,7 +105,7 @@ static char *__type(rp_t source, int argc, char **argv) {
* library.
*/
-void _init() {
+void _init(int (*_main)(int, char**)) {
extern int main(int argc, char **argv);
extern void _on_event(void);
struct slt32_entry *slt;
@@ -189,5 +189,5 @@ void _init() {
}
/* execute main program */
- exit(main(argc, argv));
+ exit(_main(argc, argv));
}
View
@@ -19,6 +19,8 @@ global _on_event
extern on_event
extern _done
+extern _GLOBAL_OFFSET_TABLE_
+
section .text
_on_event:
@@ -28,6 +30,12 @@ _on_event:
push esi
push edx
push ecx
+
+ call _on_event.getgot
+.getgot:
+ pop ebx
+ add ebx, _GLOBAL_OFFSET_TABLE_+$$-.getgot wrt ..gotpc
+
call on_event wrt ..plt
add esp, 20
View
@@ -27,7 +27,7 @@ $(STATIC): $(HEADERS) $(SOURCES)
$(SHARED): $(HEADERS) $(SOURCES)
@ echo " LD " $(SUBDIR)/$(SHARED)
- @ $(LD) $(LDFLAGS) -shared $(SOURCES) -o $(SHARED)
+ @ $(LD) $(LDFLAGS) -shared $(SOURCES) -o $(SHARED) -soname librdi.so.1
@ echo " CP " $(SUBDIR)/$(SHARED) "->" $(BUILDDIR)/lib
@ cp $(SHARED) $(BUILDDIR)/lib
View
@@ -4,7 +4,7 @@ SOURCES += $(BUILDDIR)/lib/c0.o
SUBDIR := util/echo
TARGET := echo
CFLAGS += -I$(BUILDDIR)/$(SUBDIR)/inc
-LDFLAGS += -lc -pie
+LDFLAGS += -Bdynamic -lc
ASFLAGS := -felf
all: $(TARGET)

0 comments on commit f946b23

Please sign in to comment.