Subversion Repositories HelenOS

Compare Revisions

Problem with comparison.

Ignore whitespace Rev HEAD → Rev 3004

/branches/dynload/uspace/lib/rtld/arch/ppc32/src/runtime.c
0,0 → 1,72
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup rtld rtld
* @brief
* @{
*/
/**
* @file
*/
 
#include <sys/types.h>
#include <align.h>
#include <tls.h>
 
static void kputint(unsigned i)
{
asm volatile (
"mr %%r3, %0\n"
"li %%r9, 31\n"
"sc\n"
:
: "r" (i)
: "%r3","%r9"
) ;
}
 
typedef struct {
unsigned long int ti_module;
unsigned long int ti_offset;
} tls_index;
 
void *__tls_get_addr(tls_index *ti);
 
/* ppc32 uses TLS variant 1 */
void *__tls_get_addr(tls_index *ti)
{
uint8_t *tls;
 
/* The TLS section is just after TCB */
tls = (uint8_t *)__tcb_get() + sizeof(tcb_t);
 
return tls + ti->ti_offset;
}
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/arch/ppc32/src/bootstrap.c
0,0 → 1,333
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup rtld rtld
* @brief
* @{
*/
/**
* @file
*/
 
#include <elf_dyn.h>
#include <rtld.h>
#include <pcb.h>
 
// for testing printf
#include <stdio.h>
 
void __main(void);
void __io_init(void);
void __exit(void);
 
static void kputint(unsigned i)
{
asm volatile (
"mr %%r3, %0\n"
"li %%r9, 31\n"
"sc\n"
:
: "r" (i)
: "%r3","%r9"
) ;
}
 
#define __L(ptr) ((uint32_t)(ptr) & 0x0000ffff)
#define __HA(ptr) ((uint32_t)(ptr) >> 16)
 
// ldis r11, .PLTtable@ha
static inline uint32_t _ldis(unsigned rD, uint16_t imm16)
{
/* Special case of addis: ldis rD,SIMM == addis rD,0,SIMM */
return 0x3C000000 | (rD << 21) | imm16;
}
 
static inline uint32_t _lwz(unsigned rD, uint16_t disp16, unsigned rA)
{
return 0x80000000 | (rD << 21) | (rA << 16) | disp16;
}
 
static inline uint32_t _mtctr(unsigned rS)
{
/* mtctr rD == mtspr 9, rD */
return 0x7c0003a6 | (rS << 21) | (9/*CTR*/ << 16);
}
 
static inline uint32_t _bctr()
{
/* bcctr 0x1f, 0 */
return 0x4c000420 | (0x1f/*always*/ << 21);
}
 
/* branch */
static inline uint32_t _b(uint32_t *addr, uint32_t *location)
{
uint32_t raddr = ((uint32_t)addr - (uint32_t)location) & 0x03fffffc;
return 0x48000000 | raddr;
}
 
void test_func(void)
{
kputint(-1);
kputint(42);
kputint(-1);
}
 
int test_var = 0x818283;
 
void __bootstrap(void);
 
void __bootstrap(void)
{
unsigned bias;
uint32_t *plt;
elf_dyn_t *dynamic;
void *dptr;
unsigned dval;
int i;
 
size_t rel_entries;
size_t r_offset;
elf_word r_info;
unsigned rel_type;
elf_word sym_idx;
uintptr_t sym_addr;
elf_symbol_t *sym_table;
elf_rela_t *rel_table;
elf_rela_t *jmp_rel_table;
size_t jmp_rel_entries;
pcb_t *pcb;
uint32_t a, res;
uint32_t *r_ptr;
uint32_t *_plt_ent;
 
kputint(42);
pcb = __pcb_get();
 
/* The program loader (iloader) kindly provided us with these */
dynamic = pcb->rtld_dynamic;
bias = pcb->rtld_bias;
 
kputint(bias);
kputint((unsigned)dynamic);
 
/* parse DYNAMIC */
plt = 0;
sym_table = 0;
rel_table = 0;
rel_entries = 0;
jmp_rel_table = 0;
jmp_rel_entries = 0;
 
i = 0;
while (dynamic[i].d_tag != 0) {
// kputint((uintptr_t)&dynamic[i]);
// kputint((uintptr_t)&(dynamic[i].d_tag));
// kputint(dynamic[i].d_tag);
 
dptr = (void *)(dynamic[i].d_un.d_val + bias);
dval = dynamic[i].d_un.d_val;
 
// kputint(0x10);
register unsigned tag = dynamic[i].d_tag;
 
/*
* Note that switches only work because we are using
* -fno-jump-tables.
*/
switch (tag) {
case DT_PLTRELSZ: jmp_rel_entries = dval/sizeof(elf_rela_t); break;
case DT_JMPREL: jmp_rel_table = dptr; break;
case DT_PLTGOT:
/* PLT address */
plt = dptr; break;
case DT_SYMTAB: sym_table = dptr; break;
case DT_RELA: rel_table = dptr; break;
case DT_RELASZ: rel_entries = dval / sizeof(elf_rela_t); break;
default: break;
}
 
// kputint(0x20);
 
++i;
}
kputint(1);
kputint((unsigned)sym_table);
kputint((unsigned)rel_table);
kputint((unsigned)rel_entries);
 
/* Now relocate all our dynsyms */
kputint(-1);
 
// PLT entries start here. However, each occupies 2 words
_plt_ent = plt + 18;
 
// By definition of the ppc ABI, there's 1:1 correspondence
// between JMPREL entries and PLT entries
unsigned plt_n = jmp_rel_entries;
 
uint32_t *_plt_table;
uint32_t *_plt_call;
uint32_t *_plt_resolve;
 
_plt_resolve = plt;
_plt_call = plt + 6;
_plt_table = plt + 18 + plt_n;
for (i=0; i<rel_entries; i++) {
// kputint(i);
r_offset = rel_table[i].r_offset;
r_info = rel_table[i].r_info;
r_ptr = (uint32_t *)(r_offset + bias);
a = rel_table[i].r_addend;
// kputint(-2);
// kputint(a);
// kputint(ELF32_R_TYPE(r_info));
// kputint(ELF32_R_SYM(r_info));
rel_type = ELF32_R_TYPE(r_info);
 
// kputint(rel_type);
// kputint(r_offset);
 
switch (rel_type) {
case R_PPC_JMP_SLOT:
// kputint(0xa);
sym_idx = ELF32_R_SYM(r_info);
 
sym_addr = sym_table[sym_idx].st_value + bias;
// kputint(sym_idx);
// kputint(sym_addr);
 
// r_ptr should point to a plt entry...
uint32_t pidx = (r_ptr - _plt_ent) / 2;
if (pidx >= plt_n) {
kputint(0xee00ee00);
while(1);
}
// _plt_table[pidx] = sym_addr;
// kputint(pidx);
plt[18+2*pidx] = _b((void *)sym_addr, &plt[18+2*pidx]);
// kputint(&plt[18]);
// kputint(plt[18]);
// while(1);
// while(1);
//*r_ptr = sym_addr;
 
break;
 
case R_PPC_ADDR32:
kputint(0xb);
sym_idx = ELF32_R_SYM(r_info);
 
sym_addr = sym_table[sym_idx].st_value + bias;
kputint(sym_idx);
kputint(sym_addr);
 
*r_ptr = a + sym_addr;
break;
case R_PPC_RELATIVE:
kputint(0xc);
*r_ptr = a + bias;
break;
 
case R_PPC_REL24:
kputint(0xd);
sym_idx = ELF32_R_SYM(r_info);
sym_addr = sym_table[sym_idx].st_value + bias;
kputint(sym_addr);
res = (sym_addr - (uint32_t)r_ptr + a) >> 2;
kputint(res);
if (res & 0xff000000) {
/* out of range?? */
kputint(0xeeeeeeee);
//while(1);
}
*r_ptr = (*r_ptr & ~0x00ffffff) | (res & 0x00ffffff);
kputint(0x1d);
break;
}
}
 
kputint(-3);
if (plt != 0) {
 
/* .PLTcall: */
plt[6] = _ldis(11, __HA(_plt_table)); // ldis r11, .PLTtable@ha
plt[7] = _lwz(11, __L(_plt_table), 11); // lwz r11, .PLTtable@l(r11)
plt[8] = _mtctr(11); // mtctr r11
plt[9] = _bctr();
 
/* .PLTi, i = 0..N-1 */
/* kputint(-4);
for (i = 0; i < plt_n; ++i) {
//_plt_table[i] == function address;
plt[18+i] = _b(_plt_call, &plt[18+i]); // b .PLTcall
}
*/
kputint(-5);
kputint(_plt_table[0]);
}
 
kputint(-6);
/* This will come in handy */
runtime_env.rtld_dynamic = dynamic;
runtime_env.rtld.bias = bias;
 
// volatile int ff=1;
// while(ff);
kputint(-7);
test_func();
kputint(0x42);
kputint(test_var);
// while(1);
// while(1);
/* Init libc and run rtld main */
kputint(0x22);
__main();
 
kputint(33);
__io_init();
kputint(-1);
kputint(0x52);
// printf("Hello, world! (from ppc rtld)\n");
kputint(0x62);
// while(1);
kputint(34);
_rtld_main();
kputint(35);
__exit();
 
kputint(36);
}
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/arch/ppc32/src/reloc.c
0,0 → 1,234
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup rtld rtld
* @brief
* @{
*/
/**
* @file
*/
 
#include <stdio.h>
 
#include <arch.h>
#include <elf_dyn.h>
#include <symbol.h>
#include <rtld.h>
 
#define __L(ptr) ((uint32_t)(ptr) & 0x0000ffff)
#define __HA(ptr) ((uint32_t)(ptr) >> 16)
 
// ldis r11, .PLTtable@ha
static inline uint32_t _ldis(unsigned rD, uint16_t imm16)
{
/* Special case of addis: ldis rD,SIMM == addis rD,0,SIMM */
return 0x3C000000 | (rD << 21) | imm16;
}
 
static inline uint32_t _lwz(unsigned rD, uint16_t disp16, unsigned rA)
{
return 0x80000000 | (rD << 21) | (rA << 16) | disp16;
}
 
static inline uint32_t _mtctr(unsigned rS)
{
/* mtctr rD == mtspr 9, rD */
return 0x7c0003a6 | (rS << 21) | (9/*CTR*/ << 16);
}
 
static inline uint32_t _bctr()
{
/* bcctr 0x1f, 0 */
return 0x4c000420 | (0x1f/*always*/ << 21);
}
 
/* branch */
static inline uint32_t _b(uint32_t *addr, uint32_t *location)
{
uint32_t raddr = ((uint32_t)addr - (uint32_t)location) & 0x03fffffc;
return 0x48000000 | raddr;
}
 
 
/*
* Fill in PLT
*/
void module_process_pre_arch(module_t *m)
{
uint32_t *plt;
uint32_t *_plt_ent;
 
plt = m->dyn.plt_got;
if (!plt) {
/* Module has no PLT */
return;
}
 
// PLT entries start here. However, each occupies 2 words
_plt_ent = plt + 18;
 
// By definition of the ppc ABI, there's 1:1 correspondence
// between JMPREL entries and PLT entries
unsigned plt_n = m->dyn.plt_rel_sz / sizeof(elf_rela_t);
 
uint32_t *_plt_table;
uint32_t *_plt_call;
uint32_t *_plt_resolve;
 
_plt_resolve = plt;
_plt_call = plt + 6;
_plt_table = plt + 18 + plt_n;
 
/* .PLTcall: */
plt[6] = _ldis(11, __HA(_plt_table)); // ldis r11, .PLTtable@ha
plt[7] = _lwz(11, __L(_plt_table), 11); // lwz r11, .PLTtable@l(r11)
plt[8] = _mtctr(11); // mtctr r11
plt[9] = _bctr();
 
/* .PLTi, i = 0..N-1 */
// kputint(-4);
/* for (i = 0; i < plt_n; ++i) {
//_plt_table[i] == function address;
plt[18+i] = _b(_plt_call, &plt[18+i]); // b .PLTcall
}*/
}
 
void rel_table_process(module_t *m, elf_rel_t *rt, size_t rt_size)
{
/* Unused */
(void)m; (void)rt; (void)rt_size;
}
 
/**
* Process (fixup) all relocations in a relocation table.
*/
void rela_table_process(module_t *m, elf_rela_t *rt, size_t rt_size)
{
int i;
 
size_t rt_entries;
size_t r_offset;
elf_word r_info;
unsigned rel_type;
elf_word sym_idx;
uintptr_t sym_addr;
uintptr_t r_addend;
elf_symbol_t *sym_table;
elf_symbol_t *sym;
uint32_t *r_ptr;
char *str_tab;
elf_symbol_t *sym_def;
module_t *dest;
 
uint32_t *plt;
uint32_t *_plt_table;
uint32_t *_plt_ent;
uint32_t plt_n;
uint32_t pidx;
 
plt = m->dyn.plt_got;
plt_n = m->dyn.plt_rel_sz / sizeof(elf_rela_t);
_plt_ent = plt+ 18;
_plt_table = plt + 18 + plt_n;
 
printf("parse relocation table\n");
 
sym_table = m->dyn.sym_tab;
rt_entries = rt_size / sizeof(elf_rela_t);
str_tab = m->dyn.str_tab;
 
printf("address: 0x%x, entries: %d\n", (uintptr_t)rt, rt_entries);
for (i = 0; i < rt_entries; ++i) {
printf("symbol %d: ", i);
r_offset = rt[i].r_offset;
r_info = rt[i].r_info;
r_addend = rt[i].r_addend;
 
sym_idx = ELF32_R_SYM(r_info);
sym = &sym_table[sym_idx];
 
printf("name '%s', value 0x%x, size 0x%x\n",
str_tab + sym->st_name,
sym->st_value,
sym->st_size);
 
rel_type = ELF32_R_TYPE(r_info);
r_ptr = (uint32_t *)(r_offset + m->bias);
 
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);
printf("dest name: '%s'\n", dest->dyn.soname);
printf("dest bias: 0x%x\n", dest->bias);
if (sym_def) {
sym_addr = symbol_get_addr(sym_def, dest);
printf("symbol definition found, addr=0x%x\n", sym_addr);
} else {
printf("symbol definition not found\n");
continue;
}
}
 
switch (rel_type) {
case R_PPC_JMP_SLOT:
printf("fixup R_PPC_JMP_SLOT (b+v)\n");
pidx = (r_ptr - _plt_ent) / 2;
if (pidx >= plt_n) {
printf("error: proc index out of range\n");
//kputint(0xee00ee0ee00);
while(1);
}
//_plt_table[pidx] = sym_addr;
plt[18+2*pidx] = _b((void *)sym_addr, &plt[18+2*pidx]);
break;
 
case R_PPC_ADDR32:
printf("fixup R_PPC_ADDR32 (b+v+a)\n");
*r_ptr = r_addend + sym_addr;
break;
case R_PPC_RELATIVE:
printf("fixup R_PPC_RELATIVE (b+a)\n");
*r_ptr = r_addend + m->bias;
break;
case R_PPC_REL24:
printf("ignore R_PPC_REL24\n");
/*TODO*/
break;
}
}
 
}
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/arch/ppc32/Makefile.inc
0,0 → 1,36
#
# Copyright (c) 2008 Jiri Svoboda
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
CFLAGS += -D__32_BITS__ -fno-jump-tables
LFLAGS += -e __bootstrap
 
ARCH_SOURCES := \
arch/$(ARCH)/src/bootstrap.c \
arch/$(ARCH)/src/runtime.c \
arch/$(ARCH)/src/reloc.c
 
/branches/dynload/uspace/lib/rtld/arch/ppc32/_link.ld.in
0,0 → 1,86
ENTRY(__entry)
 
PHDRS {
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(6);
}
 
SECTIONS {
. = 0x1000;
 
.init ALIGN(0x1000) : SUBALIGN(0x1000) {
*(.init);
} :text
.text : {
*(.text);
*(.rodata*);
} :text
.rel.plt ALIGN(0x1000) : {
*(.rel.plt);
}
/*
*.rel.dyn MUST FOLLOW IMMEDIATELY after .rel.plt
* without alignment gap or DT_REL will be broken
*/
.rel.dyn : {
*(.rel.*);
} :text
 
.dynamic ALIGN(0x1000) : {
*(.dynamic);
} :text
 
.dynsym ALIGN(0x1000) : {
*(.dynsym);
} :text
 
.dynstr ALIGN(0x1000) : {
*(.dynstr);
} :text
 
/* data segment */
. = ALIGN(0x1000);
 
.data ALIGN(0x1000) : SUBALIGN(0x1000) {
*(.data);
*(.sdata);
} :data
 
.dynamic ALIGN(0x1000) : {
*(.dynamic);
} :text
 
.dynsym ALIGN(0x1000) : {
*(.dynsym);
} :text
 
.dynstr ALIGN(0x1000) : {
*(.dynstr);
} :text
 
.tdata : {
_tdata_start = .;
*(.tdata);
_tdata_end = .;
} :data
.tbss : {
_tbss_start = .;
*(.tbss);
_tbss_end = .;
} :data
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
.bss : {
*(.sbss);
*(COMMON);
*(.bss);
} :data
 
/* On ppc32 the plt section is uninitialized and must be here! */
.plt ALIGN(0x1000) : SUBALIGN(0x1000) {
*(.plt);
} :data
 
. = ALIGN(0x1000);
_heap = .;
}
/branches/dynload/uspace/lib/rtld/arch/ppc32/include/elf_dyn.h
0,0 → 1,50
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
* @{
*/
/** @file
*/
 
#ifndef ppc32_ELF_DYN_H_
#define ppc32_ELF_DYN_H_
 
/*
* ppc32 dynamic relocation types
*/
 
#define R_PPC_ADDR32 1
#define R_PPC_REL24 10
#define R_PPC_JMP_SLOT 21
#define R_PPC_RELATIVE 22
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/arch/ia32/src/runtime.c
0,0 → 1,77
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup rtld rtld
* @brief
* @{
*/
/**
* @file
*/
 
#include <sys/types.h>
#include <align.h>
#include <tls.h>
 
static void kputint(unsigned i)
{
unsigned dummy;
asm volatile (
"movl $31, %%eax;"
"int $0x30"
: "=d" (dummy) /* output - %edx clobbered */
: "d" (i) /* input */
: "%eax","%ecx" /* all scratch registers clobbered */
);
}
 
typedef struct {
unsigned long int ti_module;
unsigned long int ti_offset;
} tls_index;
 
void __attribute__ ((__regparm__ (1)))
*___tls_get_addr(tls_index *ti);
 
void __attribute__ ((__regparm__ (1)))
*___tls_get_addr(tls_index *ti)
{
size_t tls_size;
uint8_t *tls;
 
/* Calculate size of TLS block */
tls_size = ALIGN_UP(&_tbss_end - &_tdata_start, &_tls_alignment);
 
/* The TLS block is just before TCB */
tls = (uint8_t *)__tcb_get() - tls_size;
 
return tls + ti->ti_offset;
}
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/arch/ia32/src/bootstrap.c
0,0 → 1,251
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup rtld rtld
* @brief
* @{
*/
/**
* @file
*/
 
#include <elf_dyn.h>
#include <rtld.h>
#include <pcb.h>
 
void __main(void);
void __io_init(void);
void __exit(void);
 
static void kputint(unsigned i)
{
unsigned dummy;
asm volatile (
"movl $31, %%eax;"
"int $0x30"
: "=d" (dummy) /* output - %edx clobbered */
: "d" (i) /* input */
: "%eax","%ecx" /* all scratch registers clobbered */
);
}
 
void __bootstrap(void)
{
unsigned bias;
unsigned *got;
elf_dyn_t *dynamic;
void *dptr;
unsigned dval;
int i;
 
size_t rel_entries;
size_t r_offset;
elf_word r_info;
unsigned rel_type;
elf_word sym_idx;
uintptr_t sym_addr;
elf_symbol_t *sym_table;
elf_rel_t *rel_table;
elf_rel_t *jmp_rel_table;
size_t jmp_rel_entries;
pcb_t *pcb;
pcb = __pcb_get();
 
/* The program loader (iloader) kindly provided us with these */
dynamic = pcb->rtld_dynamic;
bias = pcb->rtld_bias;
/*
asm volatile (
// Calculate the bias into %0
// Generates "fake" R_386_RELATIVE run-time relocation
" call .L0;"
".L0: pop %0;"
" subl $.L0, %0;"
 
// Calculate run-time address of _DYNAMIC into %1
// Generates "fake" R_386_RELATIVE run-time relocation
" movl $_DYNAMIC, %1;" // Again, at link time 0-based VMA gets in
" addl %0, %1;" // Add bias to compute run-time address
 
: "=r" (bias), "=r" (dynamic)
);
*/
kputint(bias);
kputint((unsigned)dynamic);
 
/* parse DYNAMIC */
got = 0;
sym_table = 0;
rel_table = 0;
rel_entries = 0;
jmp_rel_table = 0;
jmp_rel_entries = 0;
 
i = 0;
while (dynamic[i].d_tag != 0) {
dptr = (void *)(dynamic[i].d_un.d_val + bias);
dval = dynamic[i].d_un.d_val;
 
switch (dynamic[i].d_tag) {
case DT_PLTRELSZ: jmp_rel_entries = dval/8; break;
case DT_JMPREL: jmp_rel_table = dptr; break;
case DT_PLTGOT:
/* GOT address */
got = dptr; break;
case DT_SYMTAB: sym_table = dptr; break;
case DT_REL: rel_table = dptr; break;
case DT_RELSZ: rel_entries = dval / 8; break;
default: break;
}
 
++i;
}
kputint(1);
kputint((unsigned)sym_table);
kputint((unsigned)rel_table);
kputint((unsigned)rel_entries);
 
/* Now relocate all our dynsyms */
kputint(-1);
for (i=0; i<rel_entries; i++) {
kputint(i);
r_offset = rel_table[i].r_offset;
r_info = rel_table[i].r_info;
 
rel_type = ELF32_R_TYPE(r_info);
 
kputint(rel_type);
kputint(r_offset);
 
switch (rel_type) {
case R_386_GLOB_DAT:
case R_386_JUMP_SLOT:
kputint(16);
sym_idx = ELF32_R_SYM(r_info);
 
sym_addr = sym_table[sym_idx].st_value + bias;
kputint(sym_idx);
kputint(sym_addr);
 
*(unsigned *)(r_offset+bias) = sym_addr;
break;
 
case R_386_32:
kputint(16);
sym_idx = ELF32_R_SYM(r_info);
 
sym_addr = sym_table[sym_idx].st_value + bias;
kputint(sym_idx);
kputint(sym_addr);
 
*(unsigned *)(r_offset+bias) += sym_addr;
break;
case R_386_RELATIVE:
kputint(16);
*(unsigned *)(r_offset+bias) += bias;
break;
}
}
 
kputint(-1);
for (i=0; i<jmp_rel_entries; i++) {
kputint(i);
r_offset = jmp_rel_table[i].r_offset;
r_info = jmp_rel_table[i].r_info;
 
rel_type = ELF32_R_TYPE(r_info);
 
kputint(rel_type);
kputint(r_offset);
 
switch (rel_type) {
case R_386_GLOB_DAT:
case R_386_JUMP_SLOT:
kputint(16);
sym_idx = ELF32_R_SYM(r_info);
 
sym_addr = sym_table[sym_idx].st_value + bias;
kputint(sym_idx);
kputint(sym_addr);
 
*(unsigned *)(r_offset+bias) = sym_addr;
break;
 
case R_386_32:
kputint(16);
sym_idx = ELF32_R_SYM(r_info);
 
sym_addr = sym_table[sym_idx].st_value + bias;
kputint(sym_idx);
kputint(sym_addr);
 
*(unsigned *)(r_offset+bias) += sym_addr;
break;
case R_386_RELATIVE:
kputint(16);
*(unsigned *)(r_offset+bias) += bias;
break;
}
}
 
kputint(-1);
 
/* This will come in handy */
runtime_env.rtld_dynamic = dynamic;
runtime_env.rtld.bias = bias;
/* Init libc and run rtld main */
__main();
 
kputint(33);
__io_init();
kputint(34);
_rtld_main();
kputint(35);
__exit();
 
kputint(36);
 
asm (
"movl $250, %%eax;"
"int $0x30"
: /* output */
: /* input */
: "%eax","%ecx","%edx" /* all scratch registers clobbered */
);
}
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/arch/ia32/src/reloc.c
0,0 → 1,139
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup rtld rtld
* @brief
* @{
*/
/**
* @file
*/
 
#include <stdio.h>
 
#include <arch.h>
#include <elf_dyn.h>
#include <symbol.h>
#include <rtld.h>
 
void module_process_pre_arch(module_t *m)
{
/* Unused */
}
 
 
/**
* Process (fixup) all relocations in a relocation table.
*/
void rel_table_process(module_t *m, elf_rel_t *rt, size_t rt_size)
{
int i;
 
size_t rt_entries;
size_t r_offset;
elf_word r_info;
unsigned rel_type;
elf_word sym_idx;
uintptr_t sym_addr;
elf_symbol_t *sym_table;
elf_symbol_t *sym;
uint32_t *r_ptr;
char *str_tab;
elf_symbol_t *sym_def;
module_t *dest;
 
printf("parse relocation table\n");
 
sym_table = m->dyn.sym_tab;
rt_entries = rt_size / sizeof(elf_rel_t);
str_tab = m->dyn.str_tab;
 
printf("address: 0x%x, entries: %d\n", (uintptr_t)rt, rt_entries);
for (i = 0; i < rt_entries; ++i) {
// printf("symbol %d: ", i);
r_offset = rt[i].r_offset;
r_info = rt[i].r_info;
 
sym_idx = ELF32_R_SYM(r_info);
sym = &sym_table[sym_idx];
 
/* printf("name '%s', value 0x%x, size 0x%x\n",
str_tab + sym->st_name,
sym->st_value,
sym->st_size);
*/
rel_type = ELF32_R_TYPE(r_info);
r_ptr = (uint32_t *)(r_offset + m->bias);
 
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);
// printf("dest name: '%s'\n", dest->dyn.soname);
// printf("dest bias: 0x%x\n", dest->bias);
if (sym_def) {
sym_addr = symbol_get_addr(sym_def, dest);
// printf("symbol definition found, addr=0x%x\n", sym_addr);
} else {
printf("symbol definition not found\n");
continue;
}
}
 
switch (rel_type) {
case R_386_GLOB_DAT:
case R_386_JUMP_SLOT:
// printf("fixup R_386_GLOB_DAT/JUMP_SLOT (b+v)\n");
*r_ptr = sym_addr;
break;
 
case R_386_32:
// printf("fixup R_386_32 (b+v+a)\n");
*r_ptr += sym_addr;
break;
case R_386_RELATIVE:
// printf("fixup R_386_RELATIVE (b+a)\n");
*r_ptr += m->bias;
break;
}
}
 
}
 
void rela_table_process(module_t *m, elf_rela_t *rt, size_t rt_size)
{
/* Unused */
(void)m; (void)rt; (void)rt_size;
}
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/arch/ia32/src/entry.s
0,0 → 1,42
#
# Copyright (c) 2005 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
.section .text
 
.globl __bootstrap
.hidden __bootstrap
 
.type __entry, @function
 
__entry:
mov %ss, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
 
call __bootstrap
/branches/dynload/uspace/lib/rtld/arch/ia32/Makefile.inc
0,0 → 1,36
#
# Copyright (c) 2008 Jiri Svoboda
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
CFLAGS += -D__32_BITS__
LFLAGS += -e __bootstrap
 
ARCH_SOURCES := \
arch/$(ARCH)/src/bootstrap.c \
arch/$(ARCH)/src/runtime.c \
arch/$(ARCH)/src/reloc.c
 
/branches/dynload/uspace/lib/rtld/arch/ia32/include/elf_dyn.h
0,0 → 1,50
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
* @{
*/
/** @file
*/
 
#ifndef ia32_ELF_DYN_H_
#define ia32_ELF_DYN_H_
 
/*
* ia32 dynamic relocation types
*/
 
#define R_386_32 1
#define R_386_GLOB_DAT 6
#define R_386_JUMP_SLOT 7
#define R_386_RELATIVE 8
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/arch/ia32/_link.ld.in
0,0 → 1,81
ENTRY(__entry)
 
PHDRS {
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(6);
}
 
SECTIONS {
. = 0x1000;
 
.init ALIGN(0x1000) : SUBALIGN(0x1000) {
*(.init);
} :text
.text : {
*(.text);
*(.text.*);
*(.rodata*);
} :text
 
.rel.plt ALIGN(0x1000) : {
*(.rel.plt);
}
/*
*.rel.dyn MUST FOLLOW IMMEDIATELY after .rel.plt
* without alignment gap or DT_REL will be broken
*/
.rel.dyn : {
*(.rel.*);
} :text
 
.plt ALIGN(0x1000) : SUBALIGN(0x1000) {
*(.plt);
} :text
 
.dynamic ALIGN(0x1000) : {
*(.dynamic);
} :text
 
.dynsym ALIGN(0x1000) : {
*(.dynsym);
} :text
 
.dynstr ALIGN(0x1000) : {
*(.dynstr);
} :text
 
.data ALIGN(0x1000) : SUBALIGN(0x1000) {
*(.data);
} :data
 
.data.rel ALIGN(0x1000) : {
*(.data.rel);
} :data
 
.got ALIGN(0x1000) : SUBALIGN(0x1000) {
*(.got);
} :data
.got.plt ALIGN(0x1000) : SUBALIGN(0x1000) {
*(.got.plt);
} :data
 
.bss : {
*(COMMON);
*(.bss);
} :data
 
.tdata : {
_tdata_start = .;
*(.tdata);
_tdata_end = .;
} :data
.tbss : {
_tbss_start = .;
*(.tbss);
_tbss_end = .;
} :data
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
. = ALIGN(0x1000);
_heap = .;
}
/branches/dynload/uspace/lib/rtld/include/module.h
0,0 → 1,71
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
* @{
*/
/** @file
*/
 
#ifndef MODULE_H_
#define MODULE_H_
 
#include <sys/types.h>
#include <dynamic.h>
#include <libadt/list.h>
 
typedef struct module {
dyn_info_t dyn;
size_t bias;
 
/** Array of pointers to directly dependent modules */
struct module **deps;
/** Number of fields in deps */
size_t n_deps;
 
/** Link to list of all modules in runtime environment */
link_t modules_link;
 
/** Link to BFS queue. Only used when doing a BFS of the module graph */
link_t queue_link;
/** Tag for modules already processed during a BFS */
bool bfs_tag;
} module_t;
 
void module_process_relocs(module_t *m);
module_t *module_find(char *name);
module_t *module_load(char *name);
void module_load_deps(module_t *m);
 
void modules_process_relocs(void);
void modules_untag(void);
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/include/dynamic.h
0,0 → 1,102
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
* @{
*/
/** @file
*/
 
#ifndef DYNAMIC_H_
#define DYNAMIC_H_
 
#include <bool.h>
#include <elf_dyn.h>
 
/**
* Holds the data extracted from an ELF Dynamic section.
*
* The data is already pre-processed: Pointers are adjusted
* to their final run-time values by adding the load bias
* and indices into the symbol table are converted to pointers.
*/
typedef struct {
/** Type of relocations used for the PLT, either DT_REL or DT_RELA */
int plt_rel;
 
/** Relocation table without explicit addends */
void *rel;
size_t rel_sz;
size_t rel_ent;
 
/** Relocation table with explicit addends */
void *rela;
size_t rela_sz;
size_t rela_ent;
 
/** PLT relocation table */
void *jmp_rel;
size_t plt_rel_sz;
 
/** Pointer to PLT/GOT (processor-specific) */
void *plt_got;
 
/** Hash table */
elf_word *hash;
 
/** String table */
char *str_tab;
size_t str_sz;
 
/** Symbol table */
void *sym_tab;
size_t sym_ent;
 
void *init; /**< Module initialization code */
void *fini; /**< Module cleanup code */
 
char *soname; /**< Library identifier */
char *rpath; /**< Library search path list */
 
bool symbolic;
bool text_rel;
bool bind_now;
 
/* 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);
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/include/rtld.h
0,0 → 1,62
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
* @{
*/
/** @file
*/
 
#ifndef RTLD_H_
#define RTLD_H_
 
#include <sys/types.h>
#include <libadt/list.h>
 
#include <dynamic.h>
#include <module.h>
 
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);
 
extern runtime_env_t runtime_env;
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/include/symbol.h
0,0 → 1,47
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
* @{
*/
/** @file
*/
 
#ifndef SYMBOL_H_
#define SYMBOL_H_
 
#include <rtld.h>
#include <elf.h>
 
elf_symbol_t *symbol_def_find(char *name, module_t *origin, module_t **m);
uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m);
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/include/elf_dyn.h
0,0 → 1,122
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
* @{
*/
/** @file
*/
 
#ifndef ELF_DYN_H_
#define ELF_DYN_H_
 
#include <arch/elf.h>
#include <sys/types.h>
 
#include <elf.h>
#include <arch/elf_dyn.h>
 
#define ELF32_R_SYM(i) ((i)>>8)
#define ELF32_R_TYPE(i) ((unsigned char)(i))
 
struct elf32_dyn {
elf_sword d_tag;
union {
elf_word d_val;
elf32_addr d_ptr;
} d_un;
};
 
struct elf32_rel {
elf32_addr r_offset;
elf_word r_info;
};
 
struct elf32_rela {
elf32_addr r_offset;
elf_word r_info;
elf_sword r_addend;
};
 
#ifdef __32_BITS__
typedef struct elf32_dyn elf_dyn_t;
typedef struct elf32_rel elf_rel_t;
typedef struct elf32_rela elf_rela_t;
#endif
 
/*
* Dynamic array tags
*/
#define DT_NULL 0
#define DT_NEEDED 1
#define DT_PLTRELSZ 2
#define DT_PLTGOT 3
#define DT_HASH 4
#define DT_STRTAB 5
#define DT_SYMTAB 6
#define DT_RELA 7
#define DT_RELASZ 8
#define DT_RELAENT 9
#define DT_STRSZ 10
#define DT_SYMENT 11
#define DT_INIT 12
#define DT_FINI 13
#define DT_SONAME 14
#define DT_RPATH 15
#define DT_SYMBOLIC 16
#define DT_REL 17
#define DT_RELSZ 18
#define DT_RELENT 19
#define DT_PLTREL 20
#define DT_DEBUG 21
#define DT_TEXTREL 22
#define DT_JMPREL 23
#define DT_BIND_NOW 24
#define DT_LOPROC 0x70000000
#define DT_HIPROC 0x7fffffff
 
/*
* Special section indexes
*/
#define SHN_UNDEF 0
#define SHN_LORESERVE 0xff00
#define SHN_LOPROC 0xff00
#define SHN_HIPROC 0xff1f
#define SHN_ABS 0xfff1
#define SHN_COMMON 0xfff2
#define SHN_HIRESERVE 0xffff
 
/*
* Special symbol table index
*/
#define STN_UNDEF 0
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/include/arch.h
0,0 → 1,48
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
* @{
*/
/** @file
*/
 
#ifndef ARCH_H_
#define ARCH_H_
 
#include <rtld.h>
 
void module_process_pre_arch(module_t *m);
 
void rel_table_process(module_t *m, elf_rel_t *rt, size_t rt_size);
void rela_table_process(module_t *m, elf_rela_t *rt, size_t rt_size);
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/module.c
0,0 → 1,239
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup rtld rtld
* @brief
* @{
*/
/**
* @file
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <libadt/list.h>
 
#include <rtld.h>
#include <dynamic.h>
#include <pcb.h>
#include <elf_load.h>
#include <arch.h>
#include <module.h>
 
/** (Eagerly) process all relocation tables in a module.
*
* Currently works as if LD_BIND_NOW was specified.
*/
void module_process_relocs(module_t *m)
{
printf("module_process_relocs('%s')\n", m->dyn.soname);
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);
}
}
}
 
/** Find module structure by soname/pathname.
*
* Used primarily to see if a module has already been loaded.
* Modules are compared according to their soname, i.e. possible
* path components are ignored.
*/
module_t *module_find(char *name)
{
link_t *head = &runtime_env.modules_head;
 
link_t *cur;
module_t *m;
char *p, *soname;
 
/*
* If name contains slashes, treat it as a pathname and
* construct soname by chopping off the path. Otherwise
* treat it as soname.
*/
p = strrchr(name, '/');
soname = p ? (p + 1) : name;
/* Traverse list of all modules. Not extremely fast, but simple */
for (cur = head->next; cur != head; cur = cur->next) {
m = list_get_instance(cur, module_t, modules_link);
if (strcmp(m->dyn.soname, soname) == 0) {
return m; /* Found */
}
}
return NULL; /* Not found */
}
 
#define NAME_BUF_SIZE 64
 
/** Load a module.
*
* Currently this trivially tries to load '/<name>'.
*/
module_t *module_load(char *name)
{
elf_info_t info;
char name_buf[NAME_BUF_SIZE];
module_t *m;
int rc;
m = malloc(sizeof(module_t));
if (!m) {
printf("malloc failed\n");
exit(1);
}
 
if (strlen(name) > NAME_BUF_SIZE - 2) {
printf("soname too long. increase NAME_BUF_SIZE\n");
exit(1);
}
 
/* Prepend soname with slash */
name_buf[0] = '/';
strcpy(name_buf + 1, name);
 
/* FIXME: need to vary bias / allocate address space */
m->bias = 0x20000;
printf("filename:'%s'\n", name_buf);
 
rc = elf_load_file(name_buf, m->bias, &info);
if (rc < 0) {
printf("Failed to load '%s'\n");
exit(1);
}
 
printf("parse dynamic section\n");
/* Parse ELF .dynamic section. Store info to m->dyn. */
dynamic_parse(info.dynamic, m->bias, &m->dyn);
 
/* Insert into the list of loaded modules */
list_append(&m->modules_link, &runtime_env.modules_head);
 
return m;
}
 
/** Load all modules on which m (transitively) depends.
*/
void module_load_deps(module_t *m)
{
elf_dyn_t *dp;
char *dep_name;
module_t *dm;
size_t n, i;
 
/* Count direct dependencies */
dp = m->dyn.dynamic;
n = 0;
 
while (dp->d_tag != DT_NULL) {
if (dp->d_tag == DT_NEEDED) ++n;
++dp;
}
 
/* Create an array of pointers to direct dependencies */
 
m->n_deps = n;
if (n > 0)
m->deps = malloc(n * sizeof(module_t *));
else
m->deps = NULL;
 
if (!m->deps) {
printf("malloc failed\n");
exit(1);
}
 
i = 0; /* Current dependency index */
dp = m->dyn.dynamic;
 
while (dp->d_tag != DT_NULL) {
if (dp->d_tag == DT_NEEDED) {
dep_name = m->dyn.str_tab + dp->d_un.d_val;
 
printf("%s needs %s\n", m->dyn.soname, dep_name);
dm = module_find(dep_name);
if (!dm) {
dm = module_load(dep_name);
module_load_deps(dm);
}
 
/* Save into deps table */
m->deps[i++] = dm;
}
++dp;
}
}
 
void modules_process_relocs(void)
{
link_t *head = &runtime_env.modules_head;
 
link_t *cur;
module_t *m;
 
for (cur = head->next; cur != head; cur = cur->next) {
m = list_get_instance(cur, module_t, modules_link);
 
/* Skip rtld, since it has already been processed */
if (m != &runtime_env.rtld) {
module_process_relocs(m);
}
}
}
 
/** Clear BFS tags of all modules.
*/
void modules_untag(void)
{
link_t *head = &runtime_env.modules_head;
 
link_t *cur;
module_t *m;
 
for (cur = head->next; cur != head; cur = cur->next) {
m = list_get_instance(cur, module_t, modules_link);
m->bfs_tag = false;
}
}
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/rtld.c
0,0 → 1,106
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup rtld rtld
* @brief
* @{
*/
/**
* @file
*/
 
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
 
#include <rtld.h>
#include <dynamic.h>
#include <pcb.h>
#include <elf_load.h>
#include <module.h>
#include <arch.h>
 
runtime_env_t runtime_env;
 
void _rtld_main(void)
{
pcb_t *pcb;
static module_t prog;
module_t *rtld;
 
printf("Hello, world! (from rtld)\n");
 
/*
* 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);
 
pcb = __pcb_get();
printf("Parse program .dynamic section at 0x%x\n", pcb->dynamic);
dynamic_parse(pcb->dynamic, 0, &prog.dyn);
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);
 
/* Pointer to program module. Used as root of the dependency graph */
runtime_env.program = &prog;
 
/*
* Now we can continue with loading all other modules.
*/
 
printf("Load all program dependencies\n");
module_load_deps(&prog);
 
/*
* Now relocate/link all modules together.
*/
 
/* 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);
pcb->entry();
}
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/symbol.c
0,0 → 1,210
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup rtld rtld
* @brief
* @{
*/
/**
* @file
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include <rtld.h>
#include <symbol.h>
#include <elf.h>
 
/*
* Hash tables are 32-bit (elf_word) even for 64-bit ELF files.
*/
static elf_word elf_hash(const unsigned char *name)
{
elf_word h = 0, g;
 
while (*name) {
h = (h << 4) + *name++;
g = h & 0xf0000000;
if (g != 0) h ^= g >> 24;
h &= ~g;
}
 
return h;
}
 
static elf_symbol_t *def_find_in_module(char *name, module_t *m)
{
elf_symbol_t *sym_table;
elf_symbol_t *s, *sym;
elf_word nbucket;
elf_word nchain;
elf_word i;
char *s_name;
elf_word bucket;
 
// module_name = m->dyn.soname;
// printf("def_find_in_module('%s', %s)\n", name, module_name);
 
sym_table = m->dyn.sym_tab;
nbucket = m->dyn.hash[0];
nchain = m->dyn.hash[1];
 
bucket = elf_hash((unsigned char *)name) % nbucket;
i = m->dyn.hash[2 + bucket];
 
sym = NULL;
while (i != STN_UNDEF) {
s = &sym_table[i];
s_name = m->dyn.str_tab + s->st_name;
 
if (strcmp(name, s_name) == 0) {
sym = s;
break;
}
 
i = m->dyn.hash[2 + nbucket + i];
}
 
if (!sym)
return NULL; /* Not found */
 
if (sym->st_shndx == SHN_UNDEF) {
/* Not a definition */
return NULL;
}
 
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)
{
module_t *m, *dm;
elf_symbol_t *sym, *s;
link_t queue_head;
size_t i;
 
if (origin->dyn.symbolic) {
/*
* Origin module has a DT_SYMBOLIC flag.
* Try this module first
*/
s = def_find_in_module(name, origin);
if (s != NULL) {
/* Found */
*mod = origin;
return s;
}
}
 
/* Otherwise start in the executable program */
 
/*
* Do a BFS using the queue_link and bfs_tag fields.
* Vertices (modules) are tagged the moment they are inserted
* into the queue. This prevents from visiting the same vertex
* more times in case of circular dependencies.
*/
 
/* Mark all vertices (modules) as unvisited */
modules_untag();
 
/* Insert root (the program) into the queue and tag it */
list_initialize(&queue_head);
runtime_env.program->bfs_tag = true;
list_append(&runtime_env.program->queue_link, &queue_head);
 
/* If the symbol is found, it will be stored in 'sym' */
sym = NULL;
 
/* While queue is not empty */
while (!list_empty(&queue_head)) {
/* Pop first element from the queue */
m = list_get_instance(queue_head.next, module_t, queue_link);
list_remove(&m->queue_link);
 
s = def_find_in_module(name, m);
if (s != NULL) {
/* Symbol found */
sym = s;
*mod = m;
break;
}
 
/*
* Insert m's untagged dependencies into the queue
* and tag them.
*/
for (i = 0; i < m->n_deps; ++i) {
dm = m->deps[i];
 
if (dm->bfs_tag == false) {
dm->bfs_tag = true;
list_append(&dm->queue_link, &queue_head);
}
}
}
 
/* Empty the queue so that we leave it in a clean state */
while (!list_empty(&queue_head))
list_remove(queue_head.next);
 
if (!sym) {
printf("Error, symbol '%s' not found anywhere\n", name);
exit(1);
return NULL; /* Not found */
}
 
return sym; /* Symbol found */
}
 
uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m)
{
if (sym->st_shndx == SHN_ABS) {
/* Do not add bias to absolute symbols */
return sym->st_value;
} else {
return sym->st_value + m->bias;
}
}
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/Makefile
0,0 → 1,103
#
# Copyright (c) 2005 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
include ../../../version
include ../../Makefile.config
 
## Setup toolchain
#
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
include arch/$(ARCH)/Makefile.inc
 
CFLAGS += -I../../app/iloader/include -Iinclude -fPIC -O0 -ggdb
LFLAGS += -shared --no-undefined -soname rtld.so
 
LIBS = $(LIBC_PREFIX)/libc.pic.a $(SOFTINT_PREFIX)/libsoftint.pic.a
DEFS += -DRELEASE=\"$(RELEASE)\"
 
ifdef REVISION
DEFS += "-DREVISION=\"$(REVISION)\""
endif
 
ifdef TIMESTAMP
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
endif
 
## Sources
#
 
OUTPUT = rtld.so
GENERIC_SOURCES = \
rtld.c \
elf_load.c \
dynamic.c \
module.c \
symbol.c
 
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
 
.PHONY: all clean depend disasm sections inc
 
all: inc $(OUTPUT) disasm sections
 
inc:
ln -sfn ../arch/$(ARCH)/include include/arch
 
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm $(OUTPUT).sections Makefile.depend *.o arch/$(ARCH)/_link.ld include/arch
find arch/$(ARCH)/ -name '*.o' -follow -exec rm \{\} \;
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(ARCH_SOURCES) $(GENERIC_SOURCES)> Makefile.depend
 
$(OUTPUT): $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(LIBS) arch/$(ARCH)/_link.ld
$(LD) -T arch/$(ARCH)/_link.ld $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm:
$(OBJDUMP) -d -S -s $(OUTPUT) >$(OUTPUT).disasm
 
sections:
$(OBJDUMP) -h $(OUTPUT) >$(OUTPUT).sections
 
arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in
$(CC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.s
$(AS) $(AFLAGS) $< -o $@
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
/branches/dynload/uspace/lib/rtld/dynamic.c
0,0 → 1,132
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup rtld rtld
* @brief
* @{
*/
/**
* @file
*/
 
#include <stdio.h>
#include <string.h>
 
#include <elf_dyn.h>
#include <dynamic.h>
 
void dynamic_parse(elf_dyn_t *dyn_ptr, size_t bias, dyn_info_t *info)
{
elf_dyn_t *dp = dyn_ptr;
 
void *d_ptr;
elf_word d_val;
 
elf_word soname_idx;
elf_word rpath_idx;
 
printf("memset\n");
memset(info, 0, sizeof(info));
 
soname_idx = 0;
rpath_idx = 0;
 
printf("pass 1\n");
while (dp->d_tag != DT_NULL) {
d_ptr = (void *)((uint8_t *)dp->d_un.d_ptr + bias);
d_val = dp->d_un.d_val;
 
switch (dp->d_tag) {
 
case DT_PLTRELSZ: info->plt_rel_sz = d_val; break;
case DT_PLTGOT: info->plt_got = d_ptr; break;
case DT_HASH: info->hash = d_ptr; break;
case DT_STRTAB: info->str_tab = d_ptr; break;
case DT_SYMTAB: info->sym_tab = d_ptr; break;
case DT_RELA: info->rela = d_ptr; break;
case DT_RELASZ: info->rela_sz = d_val; break;
case DT_RELAENT: info->rela_ent = d_val; break;
case DT_STRSZ: info->str_sz = d_val; break;
case DT_SYMENT: info->sym_ent = d_val; break;
case DT_INIT: info->init = d_ptr; break;
case DT_FINI: info->fini = d_ptr; break;
case DT_SONAME: soname_idx = d_val; break;
case DT_RPATH: rpath_idx = d_val; break;
case DT_SYMBOLIC: info->symbolic = true; break;
case DT_REL: info->rel = d_ptr; break;
case DT_RELSZ: info->rel_sz = d_val; break;
case DT_RELENT: info->rel_ent = d_val; break;
case DT_PLTREL: info->plt_rel = d_val; break;
case DT_TEXTREL: info->text_rel = true; break;
case DT_JMPREL: info->jmp_rel = d_ptr; break;
case DT_BIND_NOW: info->bind_now = true; break;
 
default: break;
}
 
++dp;
}
 
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);
printf("rpath='%s'\n", info->rpath);
printf("hash=0x%x\n", (uintptr_t)info->hash);
 
/*
* Now that we have a pointer to the string table,
* we can parse DT_NEEDED fields (which contain offsets into it).
*/
 
printf("pass 2\n");
dp = dyn_ptr;
while (dp->d_tag != DT_NULL) {
d_val = dp->d_un.d_val;
 
switch (dp->d_tag) {
case DT_NEEDED:
/* Assume just for now there's only one dependency */
info->needed = info->str_tab + d_val;
printf("needed:'%s'\n", info->needed);
break;
 
default: break;
}
 
++dp;
}
}
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/elf_load.c
0,0 → 1,0
link ../../app/iloader/elf_load.c
Property changes:
Added: svn:special
+*
\ No newline at end of property