/branches/dynload/uspace/app/iramfs/Makefile |
---|
87,5 → 87,5 |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
data.c: ../tetris/tetris |
data.c: ../../lib/rtld/rtld.so |
../../../tools/bin2c.py $< >$@ |
/branches/dynload/uspace/lib/rtld/ulibc.c |
---|
0,0 → 1,163 |
#include <stdio.h> |
#include <stdlib.h> |
#include <ipc/ipc.h> |
#include <syscall.h> |
#include <libc.h> |
#include <console.h> |
#include <ipc/services.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 */ |
); |
} |
int |
ipc_call_sync_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, |
ipcarg_t arg3, ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3, |
ipcarg_t *result4, ipcarg_t *result5) |
{ |
ipc_call_t resdata; |
int callres; |
callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1, |
arg2, arg3, (sysarg_t) &resdata); |
if (callres) |
return callres; |
if (result1) |
*result1 = IPC_GET_ARG1(resdata); |
if (result2) |
*result2 = IPC_GET_ARG2(resdata); |
if (result3) |
*result3 = IPC_GET_ARG3(resdata); |
if (result4) |
*result4 = IPC_GET_ARG4(resdata); |
if (result5) |
*result5 = IPC_GET_ARG5(resdata); |
return IPC_GET_RETVAL(resdata); |
} |
int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3) |
{ |
ipcarg_t newphid; |
int res; |
res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, |
NULL, NULL, NULL, NULL, &newphid); |
if (res) |
return res; |
return newphid; |
} |
static int console_phone = -1; |
ssize_t write_stderr(const void *buf, size_t count) |
{ |
return count; |
} |
ssize_t read_stdin(void *buf, size_t count) |
{ |
ipcarg_t r0, r1; |
size_t i = 0; |
while (i < count) { |
if (ipc_call_sync_0_2(console_phone, CONSOLE_GETCHAR, &r0, |
&r1) < 0) { |
return -1; |
} |
((char *) buf)[i++] = r0; |
} |
return i; |
} |
ssize_t write_stdout(const void *buf, size_t count) |
{ |
int i; |
for (i = 0; i < count; i++) |
ipc_call_sync_1_0(console_phone, CONSOLE_PUTCHAR, |
((const char *) buf)[i]); |
return count; |
} |
void open_stdin(void) |
{ |
kputint(0x1234); |
if (console_phone < 0) { |
while ((console_phone = ipc_connect_me_to(PHONE_NS, |
SERVICE_CONSOLE, 0, 0)) < 0) { |
//usleep(10000); |
} |
kputint(console_phone); |
} |
} |
void open_stdout(void) |
{ |
kputint(0x1235); |
if (console_phone < 0) { |
while ((console_phone = ipc_connect_me_to(PHONE_NS, |
SERVICE_CONSOLE, 0, 0)) < 0) { |
//usleep(10000); |
} |
kputint(console_phone); |
} |
} |
int get_cons_phone(void) |
{ |
return console_phone; |
} |
void __main(void) |
{ |
kputint(0x110); |
} |
void __io_init(void) |
{ |
open_stdin(); |
open_stdout(); |
} |
void __exit(void) |
{ |
kputint(0x112); |
} |
int putchar(int c) |
{ |
unsigned char ch = c; |
if (write_stdout((void *) &ch, 1) == 1) |
return c; |
return EOF; |
} |
int getchar(void) |
{ |
unsigned char c; |
if (read_stdin((void *) &c, 1) == 1) |
return c; |
return EOF; |
} |
int printf(const char *fmt, ...) |
{ |
while (*fmt) { |
putchar(*fmt++); |
} |
return 0; |
} |
/branches/dynload/uspace/lib/rtld/rtld.c |
---|
34,6 → 34,8 |
* @file |
*/ |
#include <stdio.h> |
static void kputint(unsigned i) |
{ |
unsigned dummy; |
46,9 → 48,18 |
); |
} |
int z = 42; |
void test_func(void); |
void test_func(void) |
{ |
kputint(-1); |
kputint(z); |
printf("Hello, world! (from rtld)\n"); |
getchar(); |
printf("x\n"); |
while(1); |
asm ( |
"movl $253, %%eax;" |
"int $0x30" |
/branches/dynload/uspace/lib/rtld/syscall.S |
---|
0,0 → 1,56 |
# |
# Copyright (c) 2007 Jakub Jermar |
# 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. |
# |
.text |
/** Syscall wrapper. |
* |
* Mind the order of arguments. First two arguments and the syscall number go to |
* scratch registers. An optimized version of this wrapper for fewer arguments |
* could benefit from this and not save unused registers on the stack. |
*/ |
.global __syscall |
__syscall: |
pushl %ebx |
pushl %esi |
pushl %edi |
pushl %ebp |
movl 20(%esp), %edx # First argument. |
movl 24(%esp), %ecx # Second argument. |
movl 28(%esp), %ebx # Third argument. |
movl 32(%esp), %esi # Fourth argument. |
movl 36(%esp), %edi # Fifth argument. |
movl 40(%esp), %ebp # Sixth argument. |
movl 44(%esp), %eax # Syscall number. |
int $0x30 |
popl %ebp |
popl %edi |
popl %esi |
popl %ebx |
ret |
/branches/dynload/uspace/lib/rtld/Makefile |
---|
32,15 → 32,15 |
## Setup toolchain |
# |
LIBC_PREFIX = ../../lib/libc |
LIBC_PREFIX = ../../lib/libc-shared |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
include arch/$(ARCH)/Makefile.inc |
CFLAGS += -I../../srv/kbd/include -fPIC -O0 -ggdb |
LFLAGS = -shared |
CFLAGS += -I../../srv/kbd/include -I../../srv/console -fPIC -O0 |
LFLAGS = -shared --no-undefined |
#LIBS = $(LIBC_PREFIX)/libc.a |
# LIBS = $(LIBC_PREFIX)/libc-pic.a |
LIBS = |
DEFS += -DRELEASE=\"$(RELEASE)\" |
57,7 → 57,9 |
OUTPUT = rtld.so |
GENERIC_SOURCES = \ |
rtld.c |
rtld.c \ |
ulibc.c \ |
syscall.S |
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) |
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES))) |
/branches/dynload/uspace/lib/rtld/arch/ia32/bootstrap.c |
---|
34,6 → 34,10 |
* @file |
*/ |
void __main(void); |
void __io_init(void); |
void __exit(void); |
void _rtld_main(void); |
#define ELF32_R_SYM(i) ((i)>>8) |
91,6 → 95,8 |
elf32_sym *sym_table; |
elf32_rel *rel_table; |
elf32_rel *jmp_rel_table; |
elf32_rel *jmp_rel_entries; |
asm volatile ( |
"movl $30, %eax;" |
108,11 → 114,13 |
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 */ |
127,6 → 135,8 |
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) { |
134,6 → 144,8 |
dval = dynamic[i].d_un.d_val; |
switch (dynamic[i].d_tag) { |
case 2/* DT_PLTRELSZ */: jmp_rel_entries = dval/8; break; |
case 23/* DT_JMPREL */: jmp_rel_table = dptr; break; |
case 3 /* DT_PLTGOT */: |
/* GOT address */ |
got = dptr; break; |
164,7 → 176,9 |
kputint(rel_type); |
kputint(r_offset); |
if (rel_type == 7 /* R_386_JUMP_SLOT */) { |
switch (rel_type) { |
case 6: /* R_386_GLOB_DAT */ |
case 7: /* R_386_JUMP_SLOT */ |
kputint(16); |
sym_idx = ELF32_R_SYM(r_info); |
173,15 → 187,83 |
kputint(sym_addr); |
*(unsigned *)(r_offset+bias) = sym_addr; |
break; |
case 1: /* 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 8: /* R_386_RELATIVE */ |
kputint(16); |
*(unsigned *)(r_offset+bias) += bias; |
break; |
} |
} |
kputint(-1); |
kputint(32); |
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 6: /* R_386_GLOB_DAT */ |
case 7: /* 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 1: /* 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 8: /* R_386_RELATIVE */ |
kputint(16); |
*(unsigned *)(r_offset+bias) += bias; |
break; |
} |
} |
kputint(-1); |
/* 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" |