Skip to content

Commit

Permalink
dynamic linking effectively working, no dependency loading
Browse files Browse the repository at this point in the history
  • Loading branch information
nickbjohnson4224 committed Dec 9, 2011
1 parent f10bb60 commit f946b23
Show file tree
Hide file tree
Showing 17 changed files with 183 additions and 41 deletions.
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion daemon/init/Makefile
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions daemon/init/main.c
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion dl/Makefile
Expand Up @@ -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)
Expand Down
14 changes: 8 additions & 6 deletions dl/dl.h
Expand Up @@ -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);

Expand Down
20 changes: 18 additions & 2 deletions dl/elf.c
Expand Up @@ -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 */
Expand Down
119 changes: 112 additions & 7 deletions dl/elfc.c
Expand Up @@ -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
*
Expand 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) {
Expand All @@ -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 */
Expand All @@ -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]);
}
}
}
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
}
16 changes: 5 additions & 11 deletions dl/exec.c
Expand Up @@ -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);
Expand Down
7 changes: 6 additions & 1 deletion dl/plt_resolve.c
Expand Up @@ -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]);
}
5 changes: 0 additions & 5 deletions fish/main.c
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion kernel/fault/fault_page.c
Expand Up @@ -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);
Expand Down
12 changes: 12 additions & 0 deletions libc/c0.s
Expand Up @@ -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
1 change: 0 additions & 1 deletion libc/exec/exec.c
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions libc/init/init.c
Expand Up @@ -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;
Expand Down Expand Up @@ -189,5 +189,5 @@ void _init() {
}

/* execute main program */
exit(main(argc, argv));
exit(_main(argc, argv));
}
8 changes: 8 additions & 0 deletions libc/ipc/_on_event.s
Expand Up @@ -19,6 +19,8 @@ global _on_event
extern on_event
extern _done

extern _GLOBAL_OFFSET_TABLE_

section .text

_on_event:
Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion librdi/Makefile
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion util/echo/Makefile
Expand Up @@ -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)
Expand Down

0 comments on commit f946b23

Please sign in to comment.