Subversion Repositories HelenOS

Compare Revisions

Problem with comparison.

Ignore whitespace Rev HEAD → Rev 2982

/branches/dynload/uspace/lib/rtld/arch/ia32/src/reloc.c
0,0 → 1,126
/*
* 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>
 
/**
* 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, &dest);
printf("dest name: '%s'\n", dest->dyn.soname);
printf("dest bias: 0x%x\n", dest->bias);
if (sym_def) {
sym_addr = sym_def->st_value + dest->bias;
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;
}
}
 
}
 
/** @}
*/
/branches/dynload/uspace/lib/rtld/arch/ia32/src/bootstrap.c
0,0 → 1,243
/*
* 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>
 
void __main(void);
void __io_init(void);
void __exit(void);
 
static void kputint(unsigned i)
{
unsigned dummy;
asm volatile (
"movl $30, %%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;
 
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/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 $30, %%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/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__
 
ARCH_SOURCES := \
arch/$(ARCH)/src/entry.s \
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 = .;
}