Permalink
Browse files

dynamic symbol resolution

  • Loading branch information...
nickbjohnson4224 committed Dec 9, 2011
1 parent b141919 commit c4e7abf599e4df25fc771d7e367e4152c841e897
Showing with 103 additions and 38 deletions.
  1. +7 −1 TODO
  2. +13 −0 dl/__plt_resolve.s
  3. +6 −1 dl/dl.h
  4. +41 −8 dl/elf.c
  5. +10 −2 dl/plt_resolve.c
  6. +6 −8 fish/main.c
  7. +14 −4 libc/exec/dl.c
  8. +2 −11 libc/natio/read.c
  9. +4 −3 libtest/test.c
View
8 TODO
@@ -86,12 +86,18 @@ For 0.9 Alpha:
+ address space layout
+ shared object relocation
+ shared object symbol lookup (basic)
- - dynamic symbol resolution (PLT)
+ + dynamic symbol resolution (PLT)
+ dependency graph traversal
- dependency loading
- finishing touches
- dl optimization
+- shared libraries
+ (-) ELF dynamic linking
+ - shared library daemon?
+ - mmap-ed file loading
+ - transition all binaries to dynamic
+
For 1.0 Beta:
- CLI improvements
View
@@ -0,0 +1,13 @@
+[bits 32]
+
+section .text
+
+global __plt_resolve:function __plt_resolve.end-__plt_resolve
+extern _plt_resolve
+
+__plt_resolve:
+ call _plt_resolve
+ add esp, 8
+ jmp eax
+
+.end:
View
@@ -43,6 +43,9 @@ void *_sym (void *object, const char *symbol);
void _uload(void *object);
int _error(void);
+uint32_t _plt_resolve(struct elf32_ehdr *image, uint32_t index);
+void __plt_resolve(void);
+
/* Executable and Linking Format ********************************************/
int elf_load (const struct elf32_ehdr *image, uintptr_t base);
@@ -56,8 +59,10 @@ const char *elf_get_strtab (const struct elf32_ehdr *image);
const char *elf_get_soname (const struct elf32_ehdr *image);
const struct elf32_sym *elf_get_symbol (const struct elf32_ehdr *image, const char *symbol);
const struct elf32_rel *elf_get_reltab (const struct elf32_ehdr *image, size_t *count);
+const struct elf32_rel *elf_get_pltrel (const struct elf32_ehdr *image, size_t *count);
-void elf_relocate_all(struct elf32_ehdr *image);
+uint32_t elf_relocate(struct elf32_ehdr *image, const struct elf32_rel *rel, const char *strtab, const struct elf32_sym *symtab);
+void elf_relocate_all(struct elf32_ehdr *image);
uint32_t elf_resolve_local(const struct elf32_ehdr *image, const char *symbol);
uint32_t elf_resolve (const struct elf32_ehdr *image, const char *symbol);
View
@@ -190,6 +190,27 @@ const char *elf_get_strtab(const struct elf32_ehdr *image) {
return NULL;
}
+const uint32_t *elf_get_gotplt(const struct elf32_ehdr *image) {
+ const struct elf32_dyn *dynamic;
+ size_t i;
+
+ dynamic = elf_get_dynamic(image);
+
+ if (!dynamic) {
+ /* no DYNAMIC segment */
+ return NULL;
+ }
+
+ for (i = 0; dynamic[i].tag != DT_NULL; i++) {
+ if (dynamic[i].tag == DT_PLTGOT) {
+ return (const uint32_t*) ((uintptr_t) image + dynamic[i].val);
+ }
+ }
+
+ /* no GOT in DYNAMIC segment */
+ return NULL;
+}
+
const struct elf32_rel *elf_get_reltab(const struct elf32_ehdr *image, size_t *count) {
const struct elf32_dyn *dynamic;
const struct elf32_rel *reltab = NULL;
@@ -240,7 +261,7 @@ const struct elf32_rel *elf_get_pltrel(const struct elf32_ehdr *image, size_t *c
return reltab;
}
-void elf_relocate(struct elf32_ehdr *image, const struct elf32_rel *rel,
+uint32_t elf_relocate(struct elf32_ehdr *image, const struct elf32_rel *rel,
const char *strtab, const struct elf32_sym *symtab) {
const struct elf32_sym *symbol = NULL;
@@ -282,27 +303,39 @@ void elf_relocate(struct elf32_ehdr *image, const struct elf32_rel *rel,
default:
break;
}
+
+ return symbol_value;
}
void elf_relocate_all(struct elf32_ehdr *image) {
const struct elf32_rel *reltab = NULL;
const struct elf32_sym *symtab = NULL;
+ uint32_t *got = NULL;
+ uint32_t *image32;
const char *strtab;
size_t count = 0;
size_t i;
symtab = elf_get_symtab(image);
strtab = elf_get_strtab(image);
+ got = (uint32_t*) elf_get_gotplt(image);
+ got[1] = (uint32_t) image;
+ got[2] = (uint32_t) __plt_resolve;
+
reltab = elf_get_reltab(image, &count);
- for (i = 0; i < count; i++) {
- elf_relocate(image, &reltab[i], strtab, symtab);
+ if (reltab) {
+ for (i = 0; i < count; i++) {
+ elf_relocate(image, &reltab[i], strtab, symtab);
+ }
}
- // TODO - do this lazily
reltab = elf_get_pltrel(image, &count);
- for (i = 0; i < count; i++) {
- elf_relocate(image, &reltab[i], strtab, symtab);
+ if (reltab) {
+ image32 = (void*) image;
+ for (i = 0; i < count; i++) {
+ image32[reltab[i].r_offset / 4] += (uint32_t) image;
+ }
}
}
@@ -364,7 +397,7 @@ const struct elf32_ehdr *elf_get_needed(const struct elf32_ehdr *image, size_t i
soname = &strtab[elf_get_dynval(dynamic, DT_NEEDED, i)];
- if (!soname) {
+ if (soname == strtab) {
return NULL;
}
@@ -444,7 +477,7 @@ uint32_t elf_resolve_local(const struct elf32_ehdr *image, const char *symbol) {
const struct elf32_sym *syment;
syment = elf_get_symbol(image, symbol);
- if (!syment) {
+ if (!syment || !syment->st_value) {
return 0;
}
View
@@ -16,7 +16,15 @@
#include "dl.h"
-int dl_plt_resolve(uint32_t *got, uint32_t index) {
+uint32_t _plt_resolve(struct elf32_ehdr *image, uint32_t index) {
+ const struct elf32_rel *reltab = NULL;
+ const struct elf32_sym *symtab = NULL;
+ const char *strtab;
+ size_t count = 0;
- return 0;
+ symtab = elf_get_symtab(image);
+ strtab = elf_get_strtab(image);
+
+ reltab = elf_get_pltrel(image, &count);
+ return elf_relocate(image, &reltab[index], strtab, symtab);
}
View
@@ -136,20 +136,18 @@ int main() {
size_t i, n;
char *argv[100];
- void *image;
uint32_t *object0, *object1;
- const char *symbol = "strcpy";
+ const char *symbol = "baz";
- image = load_exec("/lib/libc.so");
- object0 = dl->load(image, msize(image), 0);
+ object0 = dlopen("/lib/libc.so", 0);
printf("libc.so:\t%p\n", object0);
- image = load_exec("/lib/libtest.so");
- object1 = dl->load(image, msize(image), 0);
+ object1 = dlopen("/lib/libtest.so", 0);
printf("libtest.so:\t%p\n", object1);
- printf("libc.so:%s\t%p\n", symbol, dlsym(object0, symbol));
- printf("libtest.so:%s\t%p\n", symbol, dlsym(object1, symbol));
+ printf("libtest.so:__zab\t%p\n", dlsym(object1, "__zab"));
+
+ printf("%d\n", ((int (*)(int)) dlsym(object1, symbol))(7));
setenv("PWD", "/");
View
@@ -84,13 +84,23 @@ int load_dl(void *dl_image) {
return 0;
}
-void *dlopen(const char *filename, int flags);
+void *dlopen(const char *filename, int flags) {
+ void *image = load_exec(filename);
-void *dlload (void *image, size_t size, int flags);
+ if (!image) {
+ return NULL;
+ }
+
+ return dlload(image, msize(image), flags);
+}
+
+void *dlload(void *image, size_t size, int flags) {
+ return dl->load(image, size, flags);
+}
-void dlexec (void *object, char const **argv, char const **envp);
+void dlexec(void *object, char const **argv, char const **envp);
-void dlclose(void *object);
+void dlclose(void *object);
void *dlsym(void *object, const char *symbol) {
return dl->sym(object, symbol);
View
@@ -65,15 +65,6 @@ size_t rp_read(uint64_t file, void *buf, size_t size, uint64_t offset) {
return size;
}
-int __foo0 = 42;
-
-int __foo1(int x) __attribute__((noinline));
-int __foo1(int x) {
- int y = __foo0;
- __foo0 = x;
- return y;
-}
-
-int __foo2(int x) {
- return __foo1(1 + x);
+int __zab(int x) {
+ return x + 1;
}
View
@@ -10,9 +10,10 @@ int bar(int x) {
}
int bar1(int x) {
- return bar(x);
+ return 1 + bar(x - 1);
}
-void *baz(void) {
- return malloc(foo);
+int __zab(int);
+int baz(int x) {
+ return __zab(x + 1);
}

0 comments on commit c4e7abf

Please sign in to comment.