Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4353 → Rev 4354

/branches/dynload/uspace/app/dltest/Makefile
33,12 → 33,11
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
RTLD_PREFIX = ../../lib/rtld
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I../../lib/libc -O0
LFLAGS := -Bdynamic -I/lib/rtld -rpath-link $(RTLD_PREFIX)
LFLAGS := -Bdynamic -I/lib/rtld -rpath-link $(LIBC_PREFIX)/shared
 
LIBS = $(LIBC_PREFIX)/shared/libc.so.0
 
/branches/dynload/uspace/app/bdsh/Makefile
33,7 → 33,6
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
RTLD_PREFIX = ../../lib/rtld
 
include $(LIBC_PREFIX)/Makefile.toolchain
include $(LIBC_PREFIX)/Makefile.app
/branches/dynload/uspace/app/dltest2/Makefile
33,18 → 33,11
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
RTLD_PREFIX = ../../lib/rtld
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -D__32_BITS__ -I../../srv/loader/include -I../../lib/rtld/include -I../../lib/libc -O0
#LFLAGS := -Bdynamic -I/lib/rtld -rpath-link $(RTLD_PREFIX)
LFLAGS := --whole-archive $(RTLD_PREFIX)/librtld.a --no-whole-archive
 
#LIBS = $(LIBC_PREFIX)/shared/libc.so.0
#LIBS = $(LIBC_PREFIX)/libc.a $(SOFTINT_PREFIX)/libsoftint.a ../../lib/libtest/libtest.so.0
LIBS = $(LIBC_PREFIX)/libc.a $(SOFTINT_PREFIX)/libsoftint.a
#
 
## Sources
#
69,7 → 62,6
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LFLAGS) $(LIBS) -o $@ -Map $(OUTPUT).map
# $(LD) -T $(LIBC_PREFIX)/shared/arch/$(UARCH)/_link2.ld $(OBJECTS) $(LFLAGS) $(LIBS) -o $@ -Map $(OUTPUT).map
 
disasm:
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
/branches/dynload/uspace/app/dload/Makefile
33,15 → 33,14
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
RTLD_PREFIX = ../../lib/rtld
 
include $(LIBC_PREFIX)/Makefile.toolchain
include arch/$(UARCH)/Makefile.inc
 
CFLAGS += -Iinclude -I../../srv/loader/include -I../../lib/rtld/include -O0 -ggdb
CFLAGS += -Iinclude -I../../srv/loader/include -I../../lib/libc/rtld/include -O0 -ggdb
LFLAGS +=
 
LIBS = $(RTLD_PREFIX)/librtld.a $(LIBC_PREFIX)/libc.a $(SOFTINT_PREFIX)/libsoftint.a
LIBS = $(LIBC_PREFIX)/libc.a $(SOFTINT_PREFIX)/libsoftint.a
DEFS += -DRELEASE=\"$(RELEASE)\"
 
## Sources
/branches/dynload/uspace/app/tester/Makefile
31,7 → 31,6
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
RTLD_PREFIX = ../../lib/rtld
 
include $(LIBC_PREFIX)/Makefile.toolchain
include $(LIBC_PREFIX)/Makefile.app
/branches/dynload/uspace/app/tetris/Makefile
1,6 → 1,5
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
RTLD_PREFIX = ../../lib/rtld
 
include $(LIBC_PREFIX)/Makefile.toolchain
include $(LIBC_PREFIX)/Makefile.app
/branches/dynload/uspace/app/klog/Makefile
31,7 → 31,6
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
RTLD_PREFIX = ../../lib/rtld
 
include $(LIBC_PREFIX)/Makefile.toolchain
include $(LIBC_PREFIX)/Makefile.app
/branches/dynload/uspace/app/trace/Makefile
31,7 → 31,6
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
RTLD_PREFIX = ../../lib/rtld
 
include $(LIBC_PREFIX)/Makefile.toolchain
include $(LIBC_PREFIX)/Makefile.app
/branches/dynload/uspace/lib/rtld/arch/ppc32/Makefile.inc
File deleted
\ No newline at end of file
/branches/dynload/uspace/lib/rtld/arch/ppc32/src/dynamic.c
File deleted
/branches/dynload/uspace/lib/rtld/arch/ppc32/src/reloc.c
File deleted
/branches/dynload/uspace/lib/rtld/arch/ppc32/include/elf_dyn.h
File deleted
/branches/dynload/uspace/lib/rtld/arch/ppc32/include/dynamic.h
File deleted
/branches/dynload/uspace/lib/rtld/arch/mips32/include/dynamic.h
File deleted
/branches/dynload/uspace/lib/rtld/arch/mips32/include/elf_dyn.h
File deleted
/branches/dynload/uspace/lib/rtld/arch/mips32/Makefile.inc
File deleted
/branches/dynload/uspace/lib/rtld/arch/mips32/src/dynamic.c
File deleted
/branches/dynload/uspace/lib/rtld/arch/mips32/src/reloc.c
File deleted
/branches/dynload/uspace/lib/rtld/arch/ia32/Makefile.inc
File deleted
/branches/dynload/uspace/lib/rtld/arch/ia32/src/dynamic.c
File deleted
/branches/dynload/uspace/lib/rtld/arch/ia32/src/reloc.c
File deleted
/branches/dynload/uspace/lib/rtld/arch/ia32/include/elf_dyn.h
File deleted
/branches/dynload/uspace/lib/rtld/arch/ia32/include/dynamic.h
File deleted
/branches/dynload/uspace/lib/rtld/Makefile
File deleted
/branches/dynload/uspace/lib/rtld/include/elf_dyn.h
File deleted
/branches/dynload/uspace/lib/rtld/include/rtld_arch.h
File deleted
/branches/dynload/uspace/lib/rtld/include/dynamic.h
File deleted
/branches/dynload/uspace/lib/rtld/include/module.h
File deleted
/branches/dynload/uspace/lib/rtld/include/rtld.h
File deleted
/branches/dynload/uspace/lib/rtld/include/symbol.h
File deleted
/branches/dynload/uspace/lib/rtld/dynamic.c
File deleted
/branches/dynload/uspace/lib/rtld/module.c
File deleted
/branches/dynload/uspace/lib/rtld/elf_load.c
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/dynload/uspace/lib/rtld/rtld.c
File deleted
/branches/dynload/uspace/lib/rtld/symbol.c
File deleted
/branches/dynload/uspace/lib/libc/rtld/elf_load.c
0,0 → 1,0
link ../../../srv/loader/elf_load.c
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/dynload/uspace/lib/libc/rtld/arch/ppc32/Makefile.inc
0,0 → 1,33
#
# 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 += \
rtld/arch/$(UARCH)/src/dynamic.c \
rtld/arch/$(UARCH)/src/reloc.c
/branches/dynload/uspace/lib/libc/rtld/arch/ppc32/include/dynamic.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 ppc32_DYNAMIC_H_
#define ppc32_DYNAMIC_H_
 
#include <sys/types.h>
 
typedef struct {
/* Empty. */
} dyn_info_arch_t;
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/arch/ppc32/include/elf_dyn.h
0,0 → 1,56
/*
* 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_ADDR16_LO 4
#define R_PPC_ADDR16_HI 5
#define R_PPC_ADDR16_HA 6
#define R_PPC_REL24 10
#define R_PPC_COPY 19
#define R_PPC_JMP_SLOT 21
#define R_PPC_RELATIVE 22
 
#define R_PPC_DTPMOD32 68
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/arch/ppc32/src/reloc.c
0,0 → 1,293
/*
* 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 <arch.h>
#include <elf_dyn.h>
#include <symbol.h>
#include <rtld.h>
#include <smc.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;
/* No lazy linking -- no pre-processing yet. */
return;
 
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;
uint16_t *r_ptr16;
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;
uint32_t t_addr;
uint32_t sym_size;
 
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;
 
DPRINTF("parse relocation table\n");
 
sym_table = m->dyn.sym_tab;
rt_entries = rt_size / sizeof(elf_rela_t);
str_tab = m->dyn.str_tab;
 
DPRINTF("address: 0x%x, entries: %d\n", (uintptr_t)rt, rt_entries);
for (i = 0; i < rt_entries; ++i) {
DPRINTF("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];
 
DPRINTF("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);
r_ptr16 = (uint16_t *)(r_offset + m->bias);
 
if (sym->st_name != 0) {
DPRINTF("rel_type: %x, rel_offset: 0x%x\n", rel_type, r_offset);
sym_def = symbol_def_find(str_tab + sym->st_name,
m, &dest);
DPRINTF("dest name: '%s'\n", dest->dyn.soname);
DPRINTF("dest bias: 0x%x\n", dest->bias);
if (sym_def) {
sym_addr = symbol_get_addr(sym_def, dest);
DPRINTF("symbol definition found, addr=0x%x\n", sym_addr);
} else {
DPRINTF("symbol definition not found\n");
continue;
}
}
 
switch (rel_type) {
case R_PPC_ADDR16_LO:
DPRINTF("fixup R_PPC_ADDR16_LO (#lo(s+a))\n");
*r_ptr16 = (sym_addr + r_addend) & 0xffff;
break;
 
case R_PPC_ADDR16_HI:
DPRINTF("fixup R_PPC_ADDR16_HI (#hi(s+a))\n");
*r_ptr16 = (sym_addr + r_addend) >> 16;
break;
 
case R_PPC_ADDR16_HA:
DPRINTF("fixup R_PPC_ADDR16_HA (#ha(s+a))\n");
t_addr = sym_addr + r_addend;
*r_ptr16 = (t_addr >> 16) + ((t_addr & 0x8000) ? 1 : 0);
break;
 
case R_PPC_JMP_SLOT:
DPRINTF("fixup R_PPC_JMP_SLOT (b+v)\n");
pidx = (r_ptr - _plt_ent) / 2;
if (pidx >= plt_n) {
DPRINTF("error: proc index out of range\n");
exit(1);
}
plt[18+2*pidx] = _b((void *)sym_addr, &plt[18+2*pidx]);
break;
 
case R_PPC_ADDR32:
DPRINTF("fixup R_PPC_ADDR32 (b+v+a)\n");
*r_ptr = r_addend + sym_addr;
break;
 
case R_PPC_COPY:
/*
* Copy symbol data from shared object to specified
* location.
*/
DPRINTF("fixup R_PPC_COPY (s)\n");
sym_size = sym->st_size;
if (sym_size != sym_def->st_size) {
printf("warning: mismatched symbol sizes\n");
/* Take the lower value. */
if (sym_size > sym_def->st_size)
sym_size = sym_def->st_size;
}
memcpy(r_ptr, (const void *)sym_addr, sym_size);
break;
case R_PPC_RELATIVE:
DPRINTF("fixup R_PPC_RELATIVE (b+a)\n");
*r_ptr = r_addend + m->bias;
break;
 
case R_PPC_REL24:
DPRINTF("fixup R_PPC_REL24 (s+a-p)>>2\n");
*r_ptr = (sym_addr + r_addend - (uint32_t)r_ptr) >> 2;
break;
 
case R_PPC_DTPMOD32:
/*
* We can ignore this as long as the only module
* with TLS variables is libc.so.
*/
DPRINTF("Ignoring R_PPC_DTPMOD32\n");
break;
 
default:
printf("Error: Unknown relocation type %d.\n",
rel_type);
exit(1);
break;
}
}
 
/*
* Synchronize the used portion of PLT. This is necessary since
* we are writing instructions.
*/
smc_coherence(&plt[18], plt_n * 2 * sizeof(uint32_t));
}
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/arch/ppc32/src/dynamic.c
0,0 → 1,51
/*
* 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 <elf_dyn.h>
#include <dynamic.h>
 
void dyn_parse_arch(elf_dyn_t *dp, size_t bias, dyn_info_t *info)
{
(void) dp;
(void) bias;
(void) info;
}
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/arch/mips32/Makefile.inc
0,0 → 1,33
#
# 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 += \
rtld/arch/$(UARCH)/src/dynamic.c \
rtld/arch/$(UARCH)/src/reloc.c
/branches/dynload/uspace/lib/libc/rtld/arch/mips32/include/elf_dyn.h
0,0 → 1,58
/*
* 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 mips32_ELF_DYN_H_
#define mips32_ELF_DYN_H_
 
/*
* mips32 program header types
*/
#define DT_MIPS_BASE_ADDRESS 0x70000006
#define DT_MIPS_LOCAL_GOTNO 0x7000000a
#define DT_MIPS_SYMTABNO 0x70000011
#define DT_MIPS_GOTSYM 0x70000013
 
/*
* mips32 relocation types
*/
 
#define R_MIPS_NONE 0
#define R_MIPS_REL32 3
 
#define R_MIPS_TLS_DTPMOD32 333 /* fixme */
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/arch/mips32/include/dynamic.h
0,0 → 1,54
/*
* 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 mips32_DYNAMIC_H_
#define mips32_DYNAMIC_H_
 
#include <sys/types.h>
 
typedef struct {
/** Number of local entries in GOT. */
uint32_t lgotno;
/** Index of first GOT-mapped dynamic symbol. */
uint32_t gotsym;
/** Number of entries in dynamic symbol table. */
uint32_t sym_no;
/** ???. */
uint32_t base;
} dyn_info_arch_t;
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/arch/mips32/src/dynamic.c
0,0 → 1,61
/*
* 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 <elf_dyn.h>
#include <dynamic.h>
 
void dyn_parse_arch(elf_dyn_t *dp, size_t bias, dyn_info_t *info)
{
// void *d_ptr;
elf_word d_val;
 
// d_ptr = (void *)((uint8_t *)dp->d_un.d_ptr + bias);
d_val = dp->d_un.d_val;
 
switch (dp->d_tag) {
case DT_MIPS_BASE_ADDRESS: info->arch.base = d_val; break;
case DT_MIPS_LOCAL_GOTNO: info->arch.lgotno = d_val; break;
case DT_MIPS_SYMTABNO: info->arch.sym_no = d_val; break;
case DT_MIPS_GOTSYM: info->arch.gotsym = d_val; break;
default: break;
}
}
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/arch/mips32/src/reloc.c
0,0 → 1,259
/*
* 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 <arch.h>
#include <elf_dyn.h>
#include <symbol.h>
#include <rtld.h>
 
void module_process_pre_arch(module_t *m)
{
elf_symbol_t *sym_table;
elf_symbol_t *sym_def;
elf_symbol_t *sym;
uint32_t gotsym;
uint32_t lgotno;
uint32_t *got;
char *str_tab;
int i, j;
 
uint32_t sym_addr;
module_t *dest;
 
got = (uint32_t *) m->dyn.plt_got;
sym_table = m->dyn.sym_tab;
str_tab = m->dyn.str_tab;
gotsym = m->dyn.arch.gotsym;
lgotno = m->dyn.arch.lgotno;
 
DPRINTF("** Relocate GOT entries **\n");
DPRINTF("MIPS base = 0x%x\n", m->dyn.arch.base);
 
/*
* Local entries.
*/
for (i = 0; i < gotsym; i++) {
/* FIXME: really subtract MIPS base? */
got[i] += m->bias - m->dyn.arch.base;
}
 
DPRINTF("sym_ent = %d, gotsym = %d\n", m->dyn.arch.sym_no, gotsym);
DPRINTF("lgotno = %d\n", lgotno);
 
/*
* Iterate over GOT-mapped symbol entries.
*/
for (j = gotsym; j < m->dyn.arch.sym_no; j++) {
/* Corresponding (global) GOT entry. */
i = lgotno + j - gotsym;
 
DPRINTF("relocate GOT entry %d\n", i);
// getchar();
// getchar();
 
sym = &sym_table[j];
if (ELF32_R_TYPE(sym->st_info) == STT_FUNC) {
if (sym->st_shndx == SHN_UNDEF) {
if (sym->st_value == 0) {
/* 1 */
} else {
if (got[i] == sym->st_value) {
/* 2 */
DPRINTF("(2)\n");
got[i] += m->bias - m->dyn.arch.base;
continue;
} else {
/* 3 */
DPRINTF("(3)\n");
got[i] = sym->st_value + m->bias - m->dyn.arch.base;
continue;
}
}
} else {
/* 2 */
DPRINTF("(2)\n");
got[i] += m->bias - m->dyn.arch.base;
continue;
}
} else {
if (sym->st_shndx == SHN_UNDEF ||
sym->st_shndx == SHN_COMMON) {
/* 1 */
} else {
/* 1 */
}
}
DPRINTF("(1) symbol name='%s'\n", str_tab + sym->st_name);
sym_def = symbol_def_find(str_tab + sym->st_name, m, &dest);
if (sym_def) {
sym_addr = symbol_get_addr(sym_def, dest);
DPRINTF("symbol definition found, addr=0x%x\n", sym_addr);
} else {
DPRINTF("symbol definition not found\n");
continue;
}
DPRINTF("write 0x%x at 0x%x\n", sym_addr, (uint32_t) &got[i]);
got[i] = sym_addr;
}
 
DPRINTF("** Done **\n");
}
 
/**
* 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;
uint16_t *r_ptr16;
char *str_tab;
elf_symbol_t *sym_def;
module_t *dest;
 
uint32_t *got;
uint32_t gotsym;
uint32_t lgotno;
uint32_t ea;
 
DPRINTF("parse relocation table\n");
 
sym_table = m->dyn.sym_tab;
rt_entries = rt_size / sizeof(elf_rela_t);
str_tab = m->dyn.str_tab;
got = (uint32_t *) m->dyn.plt_got;
gotsym = m->dyn.arch.gotsym;
lgotno = m->dyn.arch.lgotno;
 
DPRINTF("got=0x%lx, gotsym=%d\n", (uintptr_t) got, gotsym);
 
DPRINTF("address: 0x%x, entries: %d\n", (uintptr_t)rt, rt_entries);
for (i = 0; i < rt_entries; ++i) {
DPRINTF("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];
 
DPRINTF("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);
r_ptr16 = (uint16_t *)(r_offset + m->bias);
 
if (sym->st_name != 0) {
DPRINTF("rel_type: %x, rel_offset: 0x%x\n", rel_type, r_offset);
DPRINTF("dest name: '%s'\n", dest->dyn.soname);
DPRINTF("dest bias: 0x%x\n", dest->bias);
if (sym_def) {
sym_addr = symbol_get_addr(sym_def, dest);
DPRINTF("symbol definition found, addr=0x%x\n", sym_addr);
} else {
DPRINTF("symbol definition not found\n");
continue;
}
}
 
DPRINTF("switch(%u)\n", rel_type);
 
switch (rel_type) {
case R_MIPS_NONE:
DPRINTF("Ignoring R_MIPS_NONE\n");
break;
 
case R_MIPS_REL32:
DPRINTF("fixup R_MIPS_REL32 (r - ea + s)\n");
if (sym_idx < gotsym)
ea = sym_addr;
else
ea = got[lgotno + sym_idx - gotsym];
 
*r_ptr += sym_addr - ea;
DPRINTF("p = 0x%x, val := 0x%x\n", (uint32_t) r_ptr,
*r_ptr);
// getchar();
break;
 
/* No other non-TLS relocation types should appear. */
 
case R_MIPS_TLS_DTPMOD32:
/*
* We can ignore this as long as the only module
* with TLS variables is libc.so.
*/
DPRINTF("Ignoring R_MIPS_DTPMOD32\n");
break;
 
default:
printf("Error: Unknown relocation type %d.\n",
rel_type);
exit(1);
break;
}
}
 
 
printf("relocation done\n");
}
 
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/libc/rtld/arch/ia32/Makefile.inc
0,0 → 1,33
#
# 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 += \
rtld/arch/$(UARCH)/src/dynamic.c \
rtld/arch/$(UARCH)/src/reloc.c
/branches/dynload/uspace/lib/libc/rtld/arch/ia32/include/dynamic.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 ia32_DYNAMIC_H_
#define ia32_DYNAMIC_H_
 
#include <sys/types.h>
 
typedef struct {
/* Empty. */
} dyn_info_arch_t;
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/arch/ia32/include/elf_dyn.h
0,0 → 1,54
/*
* 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_PC32 2
#define R_386_COPY 5
#define R_386_GLOB_DAT 6
#define R_386_JUMP_SLOT 7
#define R_386_RELATIVE 8
 
#define R_386_TLS_DTPMOD32 35
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/arch/ia32/src/dynamic.c
0,0 → 1,51
/*
* 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 <elf_dyn.h>
#include <dynamic.h>
 
void dyn_parse_arch(elf_dyn_t *dp, size_t bias, dyn_info_t *info)
{
(void) dp;
(void) bias;
(void) info;
}
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/arch/ia32/src/reloc.c
0,0 → 1,177
/*
* 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 <elf_dyn.h>
#include <symbol.h>
#include <rtld.h>
 
#include <rtld_arch.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;
uint32_t sym_size;
char *str_tab;
elf_symbol_t *sym_def;
module_t *dest;
 
DPRINTF("parse relocation table\n");
 
sym_table = m->dyn.sym_tab;
rt_entries = rt_size / sizeof(elf_rel_t);
str_tab = m->dyn.str_tab;
 
DPRINTF("address: 0x%x, entries: %d\n", (uintptr_t)rt, rt_entries);
for (i = 0; i < rt_entries; ++i) {
// DPRINTF("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];
 
/* DPRINTF("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) {
// DPRINTF("rel_type: %x, rel_offset: 0x%x\n", rel_type, r_offset);
sym_def = symbol_def_find(str_tab + sym->st_name,
m, &dest);
// DPRINTF("dest name: '%s'\n", dest->dyn.soname);
// DPRINTF("dest bias: 0x%x\n", dest->bias);
if (sym_def) {
sym_addr = symbol_get_addr(sym_def, dest);
// DPRINTF("symbol definition found, addr=0x%x\n", sym_addr);
} else {
DPRINTF("symbol definition not found\n");
continue;
}
}
 
switch (rel_type) {
case R_386_GLOB_DAT:
case R_386_JUMP_SLOT:
DPRINTF("fixup R_386_GLOB_DAT/JUMP_SLOT (b+v)\n");
*r_ptr = sym_addr;
break;
 
case R_386_32:
DPRINTF("fixup R_386_32 (b+v+a)\n");
*r_ptr += sym_addr;
break;
 
case R_386_PC32:
DPRINTF("fixup R_386_PC32 (b+v+a-p)\n");
*r_ptr += sym_addr - (uint32_t) r_ptr;
break;
 
case R_386_COPY:
/*
* Copy symbol data from shared object to specified
* location.
*/
DPRINTF("fixup R_386_COPY (s)\n");
sym_size = sym->st_size;
if (sym_size != sym_def->st_size) {
printf("Warning: Mismatched symbol sizes.\n");
/* Take the lower value. */
if (sym_size > sym_def->st_size)
sym_size = sym_def->st_size;
}
memcpy(r_ptr, (const void *)sym_addr, sym_size);
break;
case R_386_RELATIVE:
DPRINTF("fixup R_386_RELATIVE (b+a)\n");
*r_ptr += m->bias;
break;
 
case R_386_TLS_DTPMOD32:
/*
* We can ignore this as long as the only module
* with TLS variables is libc.so.
*/
DPRINTF("Ignoring R_386_TLS_DTPMOD32\n");
break;
 
default:
printf("Error: Unknown relocation type %d\n",
rel_type);
exit(1);
}
 
}
 
}
 
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/libc/rtld/module.c
0,0 → 1,275
/*
* 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 <loader/pcb.h>
 
#include <rtld.h>
#include <dynamic.h>
#include <elf_load.h>
#include <rtld_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)
{
DPRINTF("module_process_relocs('%s')\n", m->dyn.soname);
 
/* Do not relocate twice. */
if (m->relocated) return;
 
module_process_pre_arch(m);
 
if (m->dyn.plt_rel == DT_REL) {
DPRINTF("table type DT_REL\n");
if (m->dyn.rel != NULL) {
DPRINTF("non-empty\n");
rel_table_process(m, m->dyn.rel, m->dyn.rel_sz);
}
/* FIXME: this seems wrong */
if (m->dyn.jmp_rel != NULL) {
DPRINTF("table type jmp-rel\n");
DPRINTF("non-empty\n");
rel_table_process(m, m->dyn.jmp_rel, m->dyn.plt_rel_sz);
}
} else { /* (m->dyn.plt_rel == DT_RELA) */
DPRINTF("table type DT_RELA\n");
if (m->dyn.rela != NULL) {
DPRINTF("non-empty\n");
rela_table_process(m, m->dyn.rela, m->dyn.rela_sz);
}
}
 
m->relocated = true;
}
 
/** 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 = str_rchr(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 (str_cmp(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 (str_size(name) > NAME_BUF_SIZE - 2) {
printf("soname too long. increase NAME_BUF_SIZE\n");
exit(1);
}
 
/* Prepend soname with '/lib/' */
str_cpy(name_buf, NAME_BUF_SIZE, "/lib/");
str_cpy(name_buf + 5, NAME_BUF_SIZE - 5, name);
 
/* FIXME: need to real allocation of address space */
m->bias = runtime_env->next_bias;
runtime_env->next_bias += 0x100000;
 
DPRINTF("filename:'%s'\n", name_buf);
printf("load '%s' at 0x%x\n", name_buf, m->bias);
 
rc = elf_load_file(name_buf, m->bias, ELDF_RW, &info);
if (rc != EE_OK) {
printf("Failed to load '%s'\n", name_buf);
exit(1);
}
 
if (info.dynamic == NULL) {
printf("Error: '%s' is not a dynamically-linked object.\n",
name_buf);
exit(1);
}
 
/* Pending relocation. */
m->relocated = false;
 
DPRINTF("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) {
/* There are no dependencies, so we are done. */
m->deps = NULL;
return;
}
 
m->deps = malloc(n * sizeof(module_t *));
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;
 
DPRINTF("%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;
}
}
 
/** Process relocations in modules.
*
* Processes relocations in @a start and all its dependencies.
* Modules that have already been relocated are unaffected.
*
* @param start The module where to start from.
*/
void modules_process_relocs(module_t *start)
{
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/libc/rtld/symbol.c
0,0 → 1,237
/*
* 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;
 
DPRINTF("def_find_in_module('%s', %s)\n", name, m->dyn.soname);
 
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 (str_cmp(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 in a module and its deps.
*
* Search the module dependency graph is breadth-first, beginning
* from the module @a start. Thus, @start and all its dependencies
* get searched.
*
* @param name Name of the symbol to search for.
* @param start Module in which to start the search..
* @param mod (output) Will be filled with a pointer to the module
* that contains the symbol.
*/
elf_symbol_t *symbol_bfs_find(char *name, module_t *start, module_t **mod)
{
module_t *m, *dm;
elf_symbol_t *sym, *s;
link_t queue_head;
size_t i;
 
/*
* 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);
start->bfs_tag = true;
list_append(&start->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 */
}
 
 
/** 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;
}
}
 
/* Not DT_SYMBOLIC or no match. Now try other locations. */
 
if (runtime_env->program) {
/* Program is dynamic -- start with program as root. */
return symbol_bfs_find(name, runtime_env->program, mod);
} else {
/* Program is static -- start with @a origin as root. */
return symbol_bfs_find(name, origin, mod);
}
}
 
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/libc/rtld/Makefile
0,0 → 1,97
#
# 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
include $(LIBC_PREFIX)/Makefile.toolchain
include arch/$(UARCH)/Makefile.inc
 
#CFLAGS += -Iinclude -I../../srv/loader/include -fPIC -O0 -ggdb
#LFLAGS += -shared --no-undefined -soname rtld.so
CFLAGS += -Iinclude -I../../srv/loader/include -O0 -ggdb
LFLAGS +=
 
PIC_CFLAGS := $(CFLAGS) -fPIC
 
DEFS += -DRELEASE=\"$(RELEASE)\"
 
## Sources
#
 
OUTPUT = librtld.a
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)))
 
OBJECTS := $(GENERIC_OBJECTS) $(ARCH_OBJECTS)
PIC_OBJECTS := $(addsuffix .pio,$(basename $(OBJECTS)))
 
.PHONY: all clean depend disasm sections inc
 
all: inc $(OUTPUT) librtld.pic.a
 
inc:
ln -sfn ../arch/$(UARCH)/include include/arch
 
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) librtld.pic.a $(OUTPUT).map $(OUTPUT).disasm $(OUTPUT).sections Makefile.depend *.o $(PIC_OBJECTS) arch/$(UARCH)/_link.ld include/arch
find arch/$(UARCH)/ -name '*.o' -follow -exec rm \{\} \;
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(ARCH_SOURCES) $(GENERIC_SOURCES)> Makefile.depend
 
$(OUTPUT): depend $(OBJECTS)
$(AR) rc $(OUTPUT) $(OBJECTS)
 
librtld.pic.a: depend $(PIC_OBJECTS)
$(AR) rc librtld.pic.a $(PIC_OBJECTS)
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.s
$(AS) $(AFLAGS) $< -o $@
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
 
%.pio: %.c
$(CC) $(DEFS) $(PIC_CFLAGS) -c $< -o $@
/branches/dynload/uspace/lib/libc/rtld/include/rtld.h
0,0 → 1,74
/*
* 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>
 
/* Define to enable debugging mode. */
#undef RTLD_DEBUG
 
#ifdef RTLD_DEBUG
#define DPRINTF(format, ...) printf(format, ##__VA_ARGS__);
#else
#define DPRINTF(format, ...)
#endif
 
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;
 
/** Temporary hack to place each module at different address. */
uintptr_t next_bias;
} runtime_env_t;
 
extern runtime_env_t *runtime_env;
 
extern void rtld_init_static(void);
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/include/dynamic.h
0,0 → 1,107
/*
* 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>
#include <arch/dynamic.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 dyn_info {
/** 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;
 
/** Architecture-specific info. */
dyn_info_arch_t arch;
} dyn_info_t;
 
void dynamic_parse(elf_dyn_t *dyn_ptr, size_t bias, dyn_info_t *info);
void dyn_parse_arch(elf_dyn_t *dp, size_t bias, dyn_info_t *info);
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/include/module.h
0,0 → 1,74
/*
* 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;
 
/** True iff relocations have already been processed in this module. */
bool relocated;
 
/** 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(module_t *start);
void modules_untag(void);
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/include/symbol.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 SYMBOL_H_
#define SYMBOL_H_
 
#include <rtld.h>
#include <elf.h>
 
elf_symbol_t *symbol_bfs_find(char *name, module_t *start, module_t **mod);
elf_symbol_t *symbol_def_find(char *name, module_t *origin, module_t **mod);
uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m);
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/include/rtld_arch.h
0,0 → 1,51
/*
* 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_ARCH_H_
#define RTLD_ARCH_H_
 
#include <rtld.h>
#include <loader/pcb.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);
 
void program_run(void *entry, pcb_t *pcb);
 
#endif
 
/** @}
*/
/branches/dynload/uspace/lib/libc/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/libc/rtld/rtld.c
0,0 → 1,52
/*
* 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 <rtld.h>
 
runtime_env_t *runtime_env;
static runtime_env_t rt_env_static;
 
/** Initialize the loder for use in a statically-linked binary. */
void rtld_init_static(void)
{
runtime_env = &rt_env_static;
list_initialize(&runtime_env->modules_head);
runtime_env->next_bias = 0x2000000;
runtime_env->program = NULL;
}
 
/** @}
*/
/branches/dynload/uspace/lib/libc/rtld/dynamic.c
0,0 → 1,136
/*
* 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>
#include <rtld.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;
 
DPRINTF("memset\n");
memset(info, 0, sizeof(info));
 
soname_idx = 0;
rpath_idx = 0;
 
DPRINTF("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:
if (dp->d_tag >= DT_LOPROC && dp->d_tag <= DT_HIPROC)
dyn_parse_arch(dp, bias, info);
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;
 
DPRINTF("str_tab=0x%x, soname_idx=0x%x, soname=0x%x\n",
(uintptr_t)info->soname, soname_idx, (uintptr_t)info->soname);
DPRINTF("soname='%s'\n", info->soname);
DPRINTF("rpath='%s'\n", info->rpath);
DPRINTF("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).
*/
 
DPRINTF("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;
DPRINTF("needed:'%s'\n", info->needed);
break;
 
default: break;
}
 
++dp;
}
}
 
/** @}
*/
/branches/dynload/uspace/lib/libc/shared/Makefile
34,7 → 34,7
LIBC_PREFIX = ../../../lib/libc
APP_LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../../lib/softint
RTLD_PREFIX = ../../../lib/rtld
 
include $(LIBC_PREFIX)/Makefile.toolchain
#include arch/$(UARCH)/Makefile.inc
ARCH_SOURCES :=
43,8 → 43,7
 
LIBS = \
$(LIBC_PREFIX)/libc.pic.a \
$(SOFTINT_PREFIX)/libsoftint.pic.a \
$(RTLD_PREFIX)/librtld.pic.a
$(SOFTINT_PREFIX)/libsoftint.pic.a
 
DEFS += -DRELEASE=\"$(RELEASE)\"
 
/branches/dynload/uspace/lib/libc/Makefile
32,14 → 32,14
 
LIBC_PREFIX = $(shell pwd)
SOFTINT_PREFIX = ../softint
RTLD_PREFIX = ../../lib/rtld
 
## Setup toolchain
#
 
include $(LIBC_PREFIX)/Makefile.toolchain
-include rtld/arch/$(UARCH)/Makefile.inc
 
CFLAGS += -I$(RTLD_PREFIX)/include -I../../srv/loader/include -D__32_BITS__
CFLAGS += -Irtld/include -I../../srv/loader/include -D__32_BITS__
PIC_CFLAGS := $(CFLAGS) -fPIC -D__IN_SHARED_LIBC__
 
## Sources
89,8 → 89,14
generic/mman.c \
generic/udebug.c \
generic/vfs/vfs.c \
generic/vfs/canonify.c
generic/vfs/canonify.c \
rtld/rtld.c \
rtld/elf_load.c \
rtld/dynamic.c \
rtld/module.c \
rtld/symbol.c
 
 
ARCH_SOURCES += \
arch/$(UARCH)/src/entry.s \
arch/$(UARCH)/src/thread_entry.s
108,11 → 114,12
ln -sfn ../../../../kernel/generic/include include/kernel
ln -sfn kernel/arch include/arch
ln -sfn ../arch/$(UARCH)/include include/libarch
ln -sfn ../arch/$(UARCH)/include rtld/include/arch
 
-include Makefile.depend
 
clean:
-rm -f include/kernel include/arch include/libarch libc.a libc.pic.a arch/$(UARCH)/_link.ld Makefile.depend
-rm -f include/kernel include/arch include/libarch rtld/include/arch libc.a libc.pic.a arch/$(UARCH)/_link.ld Makefile.depend
find . \( -name '*.o' -o -name '*.pio' \) -follow -exec rm \{\} \;
 
depend: kerninc
/branches/dynload/uspace/srv/kbd/Makefile
31,7 → 31,6
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
RTLD_PREFIX = ../../lib/rtld
 
include $(LIBC_PREFIX)/Makefile.toolchain
include $(LIBC_PREFIX)/Makefile.app
/branches/dynload/uspace/srv/pci/Makefile
31,7 → 31,6
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
RTLD_PREFIX = ../../lib/rtld
 
include $(LIBC_PREFIX)/Makefile.toolchain
include $(LIBC_PREFIX)/Makefile.app
/branches/dynload/uspace/Makefile
32,7 → 32,6
-include ../Makefile.config
 
DIRS = \
lib/rtld \
lib/libc \
lib/libfs \
lib/libblock \
79,13 → 78,10
 
.PHONY: all $(BUILDS) $(CLEANS) clean kerninc
 
all: ../Makefile.config ../config.h ../config.defs kerninc $(BUILDS)
all: ../Makefile.config ../config.h ../config.defs $(BUILDS)
 
clean: $(CLEANS)
 
kerninc:
$(MAKE) -C lib/libc kerninc
 
$(CLEANS):
-$(MAKE) -C $(basename $@) clean