Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2951 → Rev 2952

/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;
43,12 → 45,21
: "=d" (dummy) /* output - %edx clobbered */
: "d" (i) /* input */
: "%eax","%ecx" /* all scratch registers clobbered */
);
);
}
 
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"
55,7 → 66,7
: /* output */
: /* input */
: "%eax","%ecx","%edx" /* all scratch registers clobbered */
);
);
}
 
 
/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,16 → 32,16
## 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 =
# LIBS = $(LIBC_PREFIX)/libc-pic.a
LIBS =
DEFS += -DRELEASE=\"$(RELEASE)\"
 
ifdef REVISION
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);
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;
 
kputint(32);
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"