Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2999 → Rev 2998

/branches/dynload/uspace/lib/rtld/module.c
File deleted
/branches/dynload/uspace/lib/rtld/include/module.h
File deleted
/branches/dynload/uspace/lib/rtld/include/symbol.h
38,7 → 38,7
#include <rtld.h>
#include <elf.h>
 
elf_symbol_t *symbol_def_find(char *name, module_t *origin, module_t **m);
elf_symbol_t *symbol_def_find(char *name, module_t **m);
uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m);
 
#endif
/branches/dynload/uspace/lib/rtld/include/rtld.h
36,20 → 36,20
#define RTLD_H_
 
#include <sys/types.h>
#include <libadt/list.h>
 
#include <dynamic.h>
#include <module.h>
 
typedef struct {
dyn_info_t dyn;
size_t bias;
} module_t;
 
typedef struct {
elf_dyn_t *rtld_dynamic;
module_t rtld;
 
module_t *program;
module_t *libc;
 
/** List of all loaded modules including rtld and the program */
link_t modules_head;
} runtime_env_t;
 
void _rtld_main(void);
/branches/dynload/uspace/lib/rtld/include/dynamic.h
89,9 → 89,6
 
/* Assume for now that there's at most one needed library */
char *needed;
 
/** Pointer to the module's dynamic section */
elf_dyn_t *dynamic;
} dyn_info_t;
 
void dynamic_parse(elf_dyn_t *dyn_ptr, size_t bias, dyn_info_t *info);
/branches/dynload/uspace/lib/rtld/symbol.c
103,50 → 103,23
return sym; /* Found */
}
 
/** Find the definition of a symbol.
*
* By definition in System V ABI, if module origin has the flag DT_SYMBOLIC,
* origin is searched first. Otherwise, or if the symbol hasn't been found,
* the module dependency graph is searched breadth-first, beginning
* from the executable program.
*
* @param name Name of the symbol to search for.
* @param origin Module in which the dependency originates.
* @param mod (output) Will be filled with a pointer to the module
* that contains the symbol.
*/
elf_symbol_t *symbol_def_find(char *name, module_t *origin, module_t **mod)
 
elf_symbol_t *symbol_def_find(char *name, module_t **m)
{
module_t *m;
elf_symbol_t *sym;
 
/* FIXME: support DT_SYMBOLIC */
//m = origin;
sym = def_find_in_module(name, runtime_env.program);
if (sym != NULL) { *m = runtime_env.program; return sym; }
 
/* Start in the executable program */
m = runtime_env.program;
sym = def_find_in_module(name, runtime_env.libc);
if (sym != NULL) { *m = runtime_env.libc; return sym; }
 
while (true) {
sym = def_find_in_module(name, m);
if (sym != NULL) {
*mod = m;
return sym;
}
sym = def_find_in_module(name, &runtime_env.rtld);
if (sym != NULL) { *m = &runtime_env.rtld; return sym; }
 
if (m->n_deps < 1) break;
 
/* FIXME: support branching */
if (m->n_deps > 1) {
printf("error: BFS unimplemented\n");
exit(1);
}
 
m = m->deps[0];
}
 
printf("Error, symbol '%s' not found anywhere\n", name);
exit(1);
return NULL; /* Not found */
printf("symbol found nowhere\n");
*m = NULL;
return NULL;
}
 
uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m)
/branches/dynload/uspace/lib/rtld/arch/ppc32/src/reloc.c
186,8 → 186,7
 
if (sym->st_name != 0) {
printf("rel_type: %x, rel_offset: 0x%x\n", rel_type, r_offset);
sym_def = symbol_def_find(str_tab + sym->st_name,
m, &dest);
sym_def = symbol_def_find(str_tab + sym->st_name, &dest);
printf("dest name: '%s'\n", dest->dyn.soname);
printf("dest bias: 0x%x\n", dest->bias);
if (sym_def) {
/branches/dynload/uspace/lib/rtld/arch/ia32/src/reloc.c
95,8 → 95,7
 
if (sym->st_name != 0) {
// printf("rel_type: %x, rel_offset: 0x%x\n", rel_type, r_offset);
sym_def = symbol_def_find(str_tab + sym->st_name,
m, &dest);
sym_def = symbol_def_find(str_tab + sym->st_name, &dest);
// printf("dest name: '%s'\n", dest->dyn.soname);
// printf("dest bias: 0x%x\n", dest->bias);
if (sym_def) {
/branches/dynload/uspace/lib/rtld/Makefile
60,7 → 60,6
rtld.c \
elf_load.c \
dynamic.c \
module.c \
symbol.c
 
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
/branches/dynload/uspace/lib/rtld/rtld.c
42,11 → 42,27
#include <dynamic.h>
#include <pcb.h>
#include <elf_load.h>
#include <module.h>
#include <arch.h>
 
runtime_env_t runtime_env;
 
void module_process_relocs(module_t *m)
{
if (m->dyn.plt_rel == DT_REL) {
if (m->dyn.rel != NULL)
rel_table_process(m, m->dyn.rel, m->dyn.rel_sz);
/* FIXME: this seems wrong */
if (m->dyn.jmp_rel != NULL)
rel_table_process(m, m->dyn.jmp_rel, m->dyn.plt_rel_sz);
} else { /* (m->dyn.plt_rel == DT_RELA) */
printf("table type DT_RELA\n");
if (m->dyn.rela != NULL) {
printf("non-empty\n");
rela_table_process(m, m->dyn.rela, m->dyn.rela_sz);
}
}
}
 
void _rtld_main(void)
{
pcb_t *pcb;
57,17 → 73,13
int rc;
 
printf("Hello, world! (from rtld)\n");
// getchar();
 
/*
* First we need to process dynamic sections of the two modules
* that have been already loaded, that is, of ourselves and of
* the executable program.
*/
 
/* rtld_dynamic and rtld->bias were filled out by the bootstrap code */
rtld = &runtime_env.rtld;
printf("Parse rtld .dynamic section at 0x%x\n", runtime_env.rtld_dynamic);
dynamic_parse(runtime_env.rtld_dynamic, rtld->bias, &rtld->dyn);
// getchar();
 
pcb = __pcb_get();
printf("Parse program .dynamic section at 0x%x\n", pcb->dynamic);
75,33 → 87,34
prog.bias = 0;
prog.dyn.soname = "[program]";
 
/* Initialize list of loaded modules */
list_initialize(&runtime_env.modules_head);
list_append(&prog.modules_link, &runtime_env.modules_head);
list_append(&rtld->modules_link, &runtime_env.modules_head);
printf("Program requested library '%s'\n", prog.dyn.needed);
// getchar();
rc = elf_load_file("/libc.so.0", 0x20000, &lib_info);
if (rc < 0) {
printf("failed to load library\n");
return;
}
 
/* Pointer to program module. Used as root of the dependency graph */
dynamic_parse(lib_info.dynamic, 0x20000, &lib.dyn);
lib.bias = 0x20000;
printf("lib.bias=0x%x\n", lib.bias);
 
runtime_env.program = &prog;
runtime_env.libc = &lib;
 
/*
* Now we can continue with loading all other modules.
*/
/* Parse program's relocation tables */
printf("Resolve references in program\n");
module_process_relocs(&prog);
 
printf("Load all program dependencies\n");
module_load_deps(&prog);
/* Parse lib's relocation tables */
printf("Resolve references in library\n");
module_process_relocs(&lib);
 
/*
* Now relocate/link all modules together.
*/
printf("lib.bias=0x%x\n", lib.bias);
 
/* Process relocations in all modules */
printf("Relocate all modules\n");
modules_process_relocs();
 
/*
* Finally, run the main program.
*/
printf("Run program.. (at 0x%x)\n", (uintptr_t)pcb->entry);
getchar();
pcb->entry();
}
 
/branches/dynload/uspace/lib/rtld/dynamic.c
94,10 → 94,6
 
info->soname = info->str_tab + soname_idx;
info->rpath = info->str_tab + rpath_idx;
 
/* This will be useful for parsing dependencies later */
info->dynamic = dyn_ptr;
 
printf("str_tab=0x%x, soname_idx=0x%x, soname=0x%x\n",
(uintptr_t)info->soname, soname_idx, (uintptr_t)info->soname);
printf("soname='%s'\n", info->soname);