newlib: crtdll

git-svn-id: svn://kolibrios.org@3805 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2013-07-10 19:26:24 +00:00
parent a2f86b00f9
commit 27ddc31f12
15 changed files with 381 additions and 138 deletions

View File

@ -27,22 +27,34 @@ STATIC_SRCS:= \
crt/crt2.c \ crt/crt2.c \
crt/chkstk.S \ crt/chkstk.S \
crt/exit.S \ crt/exit.S \
pe/crtloader.c \ pe/crtloader.c
crt/setjmp.S
DLL_SRCS:= \ DLL_SRCS:= \
crt/crtdll.c \ crt/crtdll.c \
crt/chkstk.S \ crt/chkstk.S \
crt/exit.S
LIBCDLL_SRCS:= \
crt/crtdll.c \
crt/pseudo-reloc.c \
crt/chkstk.S \
crt/exit.S \ crt/exit.S \
crt/setjmp.S \
pe/loader.c pe/loader.c
LIBCRT_SRCS:= \
crt/start.S \
crt/chkstk.S \
crt/crt3.c \
pe/crtloader.c
CORE_SRCS:= \ CORE_SRCS:= \
argz/buf_findstr.c \ argz/buf_findstr.c \
argz/envz_get.c \ argz/envz_get.c \
crt/emutls.c \ crt/emutls.c \
crt/thread.S \ crt/thread.S \
crt/tls.S \ crt/tls.S \
crt/setjmp.S \
crt/assert.c \ crt/assert.c \
crt/cpu_features.c \ crt/cpu_features.c \
ctype/ctype_.c \ ctype/ctype_.c \
@ -300,8 +312,12 @@ AMZ_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(AMZ_SRCS)))
STATIC_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(STATIC_SRCS))) STATIC_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(STATIC_SRCS)))
LIBCRT_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(LIBCRT_SRCS)))
DLL_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(DLL_SRCS))) DLL_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(DLL_SRCS)))
LIBCDLL_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(LIBCDLL_SRCS)))
CORE_OBJS = $(patsubst %.S, %.o, $(patsubst %.asm, %.obj,\ CORE_OBJS = $(patsubst %.S, %.o, $(patsubst %.asm, %.obj,\
$(patsubst %.c, %.o, $(CORE_SRCS)))) $(patsubst %.c, %.o, $(CORE_SRCS))))
@ -335,8 +351,8 @@ LIB_OBJS:= $(STATIC_OBJS)
else else
LIB_SRCS:= $(DLL_SRCS) LIB_SRCS:= $(LIBCDLL_SRCS)
LIB_OBJS:= $(DLL_OBJS) LIB_OBJS:= $(LIBCDLL_OBJS)
endif endif
@ -356,13 +372,16 @@ LIB_OBJS+= \
shared: $(NAME).dll libamz.a libc.obj shared: $(NAME).dll libcrt.a
$(NAME).dll: $(LIB_OBJS) $(SRC_DEP) Makefile $(NAME).dll: $(LIB_OBJS) $(SRC_DEP) Makefile
ld $(LDFLAGS) -L. -o $@ $(LIB_OBJS) -lgcc ld $(LDFLAGS) -L. -o $@ $(LIB_OBJS) -lgcc
libcrt.a: $(LIBCRT_OBJS) Makefile
ar rc libcrt.a $(LIBCRT_OBJS)
libamz.a: $(AMZ_OBJS) Makefile libamz.a: $(AMZ_OBJS) Makefile
ar rc libamz.a $(AMZ_OBJS) ar rc libamz.a $(AMZ_OBJS)

View File

@ -3,8 +3,8 @@
ENTRY(__start) ENTRY(__start)
SECTIONS SECTIONS
{ {
.text 0x000000: .text 0x000000:
{ {
LONG(0x554e454D); LONG(0x554e454D);
LONG(0x32305445); LONG(0x32305445);
LONG(1); LONG(1);
@ -15,6 +15,9 @@ SECTIONS
LONG(___cmdline); LONG(___cmdline);
LONG(___pgmname); /* full path */ LONG(___pgmname); /* full path */
LONG(0); /*FIXME tls data */ LONG(0); /*FIXME tls data */
LONG(__idata_start)
LONG(__idata_end)
LONG(_main)
*(.init) *(.init)
*(.text) *(.text)
@ -31,10 +34,10 @@ SECTIONS
*(.gcc_exc) *(.gcc_exc)
PROVIDE (etext = .); PROVIDE (etext = .);
*(.gcc_except_table) *(.gcc_except_table)
} }
.rdata ALIGN(64) : .rdata ALIGN(16) :
{ {
*(.rdata) *(.rdata)
*(SORT(.rdata$*)) *(SORT(.rdata$*))
___RUNTIME_PSEUDO_RELOC_LIST__ = .; ___RUNTIME_PSEUDO_RELOC_LIST__ = .;
@ -42,9 +45,9 @@ SECTIONS
*(.rdata_runtime_pseudo_reloc) *(.rdata_runtime_pseudo_reloc)
___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
__RUNTIME_PSEUDO_RELOC_LIST_END__ = .; __RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
} }
.CRT ALIGN(64) : .CRT ALIGN(16) :
{ {
___crt_xc_start__ = . ; ___crt_xc_start__ = . ;
*(SORT(.CRT$XC*)) /* C initialization */ *(SORT(.CRT$XC*)) /* C initialization */
___crt_xc_end__ = . ; ___crt_xc_end__ = . ;
@ -60,10 +63,10 @@ SECTIONS
___crt_xt_start__ = . ; ___crt_xt_start__ = . ;
*(SORT(.CRT$XT*)) /* Termination */ *(SORT(.CRT$XT*)) /* Termination */
___crt_xt_end__ = . ; ___crt_xt_end__ = . ;
} }
.data ALIGN(64) : .data ALIGN(64) :
{ {
PROVIDE ( __data_start__ = .) ; PROVIDE ( __data_start__ = .) ;
*(.data) *(.data)
*(.data2) *(.data2)
@ -74,22 +77,24 @@ SECTIONS
PROVIDE ( __data_end__ = .) ; PROVIDE ( __data_end__ = .) ;
*(.data_cygwin_nocopy) *(.data_cygwin_nocopy)
___iend = . ; ___iend = . ;
} }
.idata ALIGN(64): .idata ALIGN(16):
{ {
SORT(*)(.idata$2) __idata_start = .;
SORT(*)(.idata$3) SORT(*)(.idata$2)
SORT(*)(.idata$3)
/* These zeroes mark the end of the import list. */ /* These zeroes mark the end of the import list. */
LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
SORT(*)(.idata$4) SORT(*)(.idata$4)
SORT(*)(.idata$5) SORT(*)(.idata$5)
SORT(*)(.idata$6) SORT(*)(.idata$6)
SORT(*)(.idata$7) SORT(*)(.idata$7)
} __idata_end = . ;
}
bss ALIGN(64): bss ALIGN(16):
{ {
*(.bss) *(.bss)
*(COMMON) *(COMMON)
. = ALIGN(16); . = ALIGN(16);
@ -99,7 +104,7 @@ SECTIONS
. = . + 1024 + 16; . = . + 1024 + 16;
___stacktop = .; ___stacktop = .;
___memsize = . ; ___memsize = . ;
} }
/DISCARD/ : /DISCARD/ :
{ {

View File

@ -14,7 +14,7 @@ __alloca:
pushl %ecx /* save temp */ pushl %ecx /* save temp */
leal 8(%esp), %ecx /* point past return addr */ leal 8(%esp), %ecx /* point past return addr */
subl %eax, %ecx subl %eax, %ecx
cmpl %fs:4, %ecx # check low stack limit cmpl %fs:8, %ecx # check low stack limit
jb 1f jb 1f
movl %esp, %eax /* save old stack pointer */ movl %esp, %eax /* save old stack pointer */
@ -41,7 +41,7 @@ ___chkstk_ms:
1: 1:
subl $0x1000, %ecx /* yes, move pointer down 4k*/ subl $0x1000, %ecx /* yes, move pointer down 4k*/
cmpl %fs:4, %ecx /* check low stack limit */ cmpl %fs:8, %ecx /* check low stack limit */
jb 3f jb 3f
orl $0x0, (%ecx) /* probe there */ orl $0x0, (%ecx) /* probe there */

View File

@ -29,8 +29,8 @@
* a-good-idea use of include. */ * a-good-idea use of include. */
extern char __cmdline; extern char __cmdline[];
extern char __pgmname; extern char __pgmname[];
extern int main (int, char **, char **); extern int main (int, char **, char **);
@ -107,7 +107,7 @@ __crt_startup (void)
arg[0] = &__pgmname; arg[0] = &__pgmname;
if( __cmdline != 0) if( __cmdline[0] != 0)
{ {
_argc = 2; _argc = 2;
arg[1] = &__cmdline; arg[1] = &__cmdline;

View File

@ -9,8 +9,8 @@ __thread_startup (int (*entry)(void*), void *param,
int retval; int retval;
__asm__ __volatile__( // save stack limits __asm__ __volatile__( // save stack limits
"movl %0, %%fs:4 \n\t" // use TLS "movl %0, %%fs:8 \n\t" // use TLS
"movl %1, %%fs:8 \n\t" "movl %1, %%fs:12 \n\t"
::"r"(stacklow), "r"(stackhigh)); ::"r"(stacklow), "r"(stackhigh));
init_reent(); // initialize thread reentry structure init_reent(); // initialize thread reentry structure

View File

@ -0,0 +1,61 @@
/*
* crt1.c
* This file has no copyright assigned and is placed in the Public Domain.
* This file is a part of the mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER within the package.
*
* Source code for the startup proceedures used by all programs. This code
* is compiled to make crt1.o, which should be located in the library path.
*
*/
/* Hide the declaration of _fmode with dllimport attribute in stdlib.h to
avoid problems with older GCC. */
#include <newlib.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef void (*ctp)();
static void __do_global_ctors ()
{
extern int __CTOR_LIST__;
int *c = &__CTOR_LIST__;
c++;
while (*c)
{
ctp d = (ctp)*c;
(d)();
c++;
}
}
void *load_libc();
void __main (){};
void* get_entry_point(void *raw);
void __attribute__((noreturn))
__crt_startup (void)
{
struct app_hdr *header;
void *img;
void __attribute__((noreturn)) (*entry)(void *img);
img = load_libc();
if(img == NULL)
{
asm("int3");
asm ("int $0x40" ::"a"(-1));
};
entry = get_entry_point(img);
entry(img);
}

View File

@ -19,18 +19,21 @@ struct app_hdr
int stacktop; int stacktop;
char *cmdline; char *cmdline;
char *path; char *path;
int reserved;
void *__idata_start;
void *__idata_end;
void (*main)(int argc, char **argv, char **envp);
}; };
int _argc; int _argc;
char **_argv; char **_argv;
void __fastcall init_loader(void *libc_image);
void* __fastcall create_image(void *raw);
int __fastcall link_image(void *img_base);
void* get_entry_point(void *raw); void* get_entry_point(void *raw);
int (*entry)(int, char **, char **); int (*entry)(int, char **, char **);
void init_loader(void *libc_image);
void init_reent(); void init_reent();
@ -45,8 +48,8 @@ __thread_startup (int (*entry)(void*), void *param,
asm volatile ( "xchgw %bx, %bx"); asm volatile ( "xchgw %bx, %bx");
__asm__ __volatile__( // save stack limits __asm__ __volatile__( // save stack limits
"movl %0, %%fs:4 \n\t" // use TLS "movl %0, %%fs:8 \n\t" // use TLS
"movl %1, %%fs:8 \n\t" "movl %1, %%fs:12 \n\t"
::"r"(stacklow), "r"(stackhigh)); ::"r"(stacklow), "r"(stackhigh));
init_reent(); // initialize thread reentry structure init_reent(); // initialize thread reentry structure
@ -61,16 +64,22 @@ char * __libc_getenv(const char *name)
return NULL; return NULL;
} }
void _pei386_runtime_relocator (void);
int link_app();
char __appcwd[1024]; char __appcwd[1024];
int __appcwdlen; int __appcwdlen;
char* __appenv; char* __appenv;
int __appenv_size; int __appenv_size;
static char *arg[2];
extern char _tls_map[128];
void __attribute__((noreturn)) void __attribute__((noreturn))
crt_startup (void *libc_base, void *obj_base, uint32_t *params) libc_crt_startup (void *libc_base)
{ {
struct app_hdr *header; struct app_hdr *header = NULL;
char *arg[2];
int len; int len;
char *p; char *p;
@ -78,67 +87,39 @@ crt_startup (void *libc_base, void *obj_base, uint32_t *params)
void *my_app; void *my_app;
int retval = 0; int retval = 0;
// user_free(obj_base); _pei386_runtime_relocator();
memset(_tls_map, 0xFF, 32*4);
_tls_map[0] = 0xE0;
init_reent(); init_reent();
__initPOSIXHandles(); __initPOSIXHandles();
// __appenv = load_file("/sys/system.env", &__appenv_size); // __appenv = load_file("/sys/system.env", &__appenv_size);
init_loader(libc_base); init_loader(libc_base);
my_app = create_image((void*)(params[0])); if( link_app() == 0)
if( link_image(my_app)==0)
goto done; goto done;
header = (struct app_hdr*)NULL;
__appcwdlen = strrchr(header->path, '/') - header->path; __appcwdlen = strrchr(header->path, '/') - header->path;
__appcwdlen = __appcwdlen > 1022 ? 1022 : __appcwdlen; __appcwdlen = __appcwdlen > 1022 ? 1022 : __appcwdlen;
memcpy(__appcwd, header->path, __appcwdlen); memcpy(__appcwd, header->path, __appcwdlen);
set_cwd(__appcwd); set_cwd(__appcwd);
#ifdef BRAVE_NEW_WORLD
len = strlen(header->path);
p = alloca(len+1);
memcpy(p, header->path, len);
p[len]=0;
arg[0] = p;
#else
arg[0] = header->path; arg[0] = header->path;
#endif
_argc = 1; if( header->cmdline[0] != 0)
if( header->cmdline != 0)
{ {
#ifdef BRAVE_NEW_WORLD
len = strlen(header->cmdline);
if(len)
{
p = alloca(len+1);
memcpy(p, header->cmdline, len);
p[len]=0;
_argc = 2;
arg[1] = p;
};
#else
_argc = 2; _argc = 2;
arg[1] = header->cmdline; arg[1] = header->cmdline;
#endif }
}; else _argc = 1;
_argv = arg; _argv = arg;
entry = get_entry_point(my_app); header->main(_argc, _argv, NULL);
// __asm__ __volatile__("int3");
retval = entry(_argc, _argv, NULL);
done: done:
exit (retval); _exit (retval);
} }

View File

@ -12,7 +12,7 @@ __Exit:
movl 4(%esp), %edx #store exit code movl 4(%esp), %edx #store exit code
movl $68, %eax movl $68, %eax
movl $13, %ebx movl $13, %ebx
movl %fs:4, %ecx movl %fs:8, %ecx
int $0x40 #destroy stack int $0x40 #destroy stack
movl $-1, %eax movl $-1, %eax

View File

@ -3,6 +3,12 @@
.global __start .global __start
#tls:0 pid process id
#tls:4 tid reserved for thread slot
#tls:8 thread's stack low limit
#tls:12 thread's stack high limit
#tls:16 reseved for libc
.align 4 .align 4
__start: __start:
movl $68, %eax movl $68, %eax
@ -15,8 +21,8 @@ __start:
jz 1f jz 1f
addl %eax, %ecx addl %eax, %ecx
movl %eax, %fs:4 movl %eax, %fs:8
movl %ecx, %fs:8 #save stack base - low limit movl %ecx, %fs:12 #save stack base - low limit
#save stack top - high limit #save stack top - high limit
movl %ecx, %esp #reload stack movl %ecx, %esp #reload stack
@ -30,15 +36,8 @@ __start:
movl 30(%ebx), %eax movl 30(%ebx), %eax
movl %eax, %fs:0 #save pid movl %eax, %fs:0 #save pid
movl $__tls_map, %edi #init TLS addl $1024, %esp
movl $32, %ecx
xorl %eax, %eax
notl %eax
rep
stosl
movb $0xF0, __tls_map
jmp ___crt_startup jmp ___crt_startup
1: 1:
int3 #trap to debugger int3 #trap to debugger

View File

@ -827,7 +827,7 @@ static inline struct _reent *__getreent(void)
{ {
struct _reent *ent; struct _reent *ent;
__asm__ __volatile__( __asm__ __volatile__(
"movl %%fs:12, %0" "movl %%fs:16, %0"
:"=r"(ent)); :"=r"(ent));
return ent; return ent;
}; };

View File

@ -1,7 +1,7 @@
OUTPUT_FORMAT(pei-i386) OUTPUT_FORMAT(pei-i386)
ENTRY("_crt_startup") ENTRY("_libc_crt_startup")
SECTIONS SECTIONS
{ {
@ -14,6 +14,7 @@ SECTIONS
*(.text) *(.text)
*(SORT(.text$*)) *(SORT(.text$*))
*(.text.*) *(.text.*)
*(.gnu.linkonce.t.*)
*(.glue_7t) *(.glue_7t)
*(.glue_7) *(.glue_7)
___CTOR_LIST__ = .; __CTOR_LIST__ = . ; ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
@ -23,12 +24,14 @@ SECTIONS
*(.fini) *(.fini)
*(.rdata) *(.rdata)
*(SORT(.rdata$*)) *(SORT(.rdata$*))
___RUNTIME_PSEUDO_RELOC_LIST__ = .; __rt_psrelocs_start = .;
__RUNTIME_PSEUDO_RELOC_LIST__ = .;
*(.rdata_runtime_pseudo_reloc) *(.rdata_runtime_pseudo_reloc)
__rt_psrelocs_end = .;
__rt_psrelocs_size = __rt_psrelocs_end - __rt_psrelocs_start;
___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
__RUNTIME_PSEUDO_RELOC_LIST_END__ = .; __RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
__pei386_runtime_relocator = .; ___RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size;
__RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size;
} }
.data ALIGN(__section_alignment__): .data ALIGN(__section_alignment__):
@ -46,8 +49,10 @@ SECTIONS
.bss ALIGN(__section_alignment__): .bss ALIGN(__section_alignment__):
{ {
__bss_start__ = . ;
*(.bss) *(.bss)
*(COMMON) *(COMMON)
__bss_end__ = . ;
} }
.edata ALIGN(__section_alignment__): .edata ALIGN(__section_alignment__):

View File

@ -174,10 +174,10 @@ void* create_image(void *raw)
} }
reloc = MakePtr(PIMAGE_BASE_RELOCATION, reloc,reloc->SizeOfBlock); reloc = MakePtr(PIMAGE_BASE_RELOCATION, reloc,reloc->SizeOfBlock);
}; };
printf("unmap base %p offset %x %d page(s)\n", // printf("unmap base %p offset %x %d page(s)\n",
img_base, // img_base,
nt->OptionalHeader.DataDirectory[5].VirtualAddress, // nt->OptionalHeader.DataDirectory[5].VirtualAddress,
(nt->OptionalHeader.DataDirectory[5].Size+4095)>>12); // (nt->OptionalHeader.DataDirectory[5].Size+4095)>>12);
user_unmap(img_base,nt->OptionalHeader.DataDirectory[5].VirtualAddress, user_unmap(img_base,nt->OptionalHeader.DataDirectory[5].VirtualAddress,
nt->OptionalHeader.DataDirectory[5].Size); nt->OptionalHeader.DataDirectory[5].Size);
@ -185,6 +185,16 @@ void* create_image(void *raw)
return img_base; return img_base;
}; };
void* get_entry_point(void *raw)
{
PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS32 nt;
dos = (PIMAGE_DOS_HEADER)raw;
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
return MakePtr(void*, raw, nt->OptionalHeader.AddressOfEntryPoint);
};
void* load_libc() void* load_libc()
@ -195,17 +205,19 @@ void* load_libc()
ufile_t uf; ufile_t uf;
uf = load_file("/kolibrios/lib/libc.dll"); uf = load_file("/kolibrios/lib/libc.dll");
raw_img = uf.data; raw_img = uf.data;
raw_size = uf.size; raw_size = uf.size;
if(raw_img == NULL) if(raw_img == NULL)
return NULL; return NULL;
printf("libc.dll raw %p, size %d\n", raw_img, raw_size); // printf("libc.dll raw %p, size %d\n", raw_img, raw_size);
if( validate_pe(raw_img, raw_size, 0) == 0) if( validate_pe(raw_img, raw_size, 0) == 0)
{ {
printf("invalide libc.dll\n"); // printf("invalide libc.dll\n");
user_free(raw_img); user_free(raw_img);
}; };

View File

@ -7,7 +7,7 @@
#include <setjmp.h> #include <setjmp.h>
#include <envz.h> #include <envz.h>
#include <sys/kos_io.h> #include <kos32sys.h>
#include "list.h" #include "list.h"
#include "pe.h" #include "pe.h"
@ -19,7 +19,7 @@
#define DBG(format,...) #define DBG(format,...)
void __fastcall init_loader(void *libc_image); void init_loader(void *libc_image);
void* __fastcall create_image(void *raw); void* __fastcall create_image(void *raw);
int __fastcall link_image(void *img_base); int __fastcall link_image(void *img_base);
int __fastcall do_exec(uint32_t my_app, uint32_t *params); int __fastcall do_exec(uint32_t my_app, uint32_t *params);
@ -40,6 +40,10 @@ struct app_hdr
int stacktop; int stacktop;
char *cmdline; char *cmdline;
char *path; char *path;
int reserved;
void *__idata_start;
void *__idata_end;
void (*main)(int argc, char **argv, char **envp);
}; };
struct tag_module struct tag_module
@ -70,12 +74,11 @@ typedef struct
module_t* load_module(const char *name); module_t* load_module(const char *name);
LIST_HEAD(dll_list);
LIST_HEAD(path_list); LIST_HEAD(path_list);
static module_t libc_dll; static module_t libc_dll;
static char libc_name[] = "libc.dll"; static char libc_name[] = "libc.dll";
static char libc_path[] = "/sys/lib/libc.dll"; static char libc_path[] = "/KolibriOS/lib/libc.dll";
static inline int IsPowerOf2(uint32_t val) static inline int IsPowerOf2(uint32_t val)
{ {
@ -137,7 +140,7 @@ int validate_pe(void *raw, size_t raw_size, int is_exec)
} }
void __fastcall init_loader(void *libc_image) void init_loader(void *libc_image)
{ {
PIMAGE_DOS_HEADER dos; PIMAGE_DOS_HEADER dos;
@ -145,7 +148,7 @@ void __fastcall init_loader(void *libc_image)
PIMAGE_EXPORT_DIRECTORY exp; PIMAGE_EXPORT_DIRECTORY exp;
struct app_hdr *header; struct app_hdr *header;
#if 0
dll_path_t *path; dll_path_t *path;
int len; int len;
char *p; char *p;
@ -217,6 +220,7 @@ void __fastcall init_loader(void *libc_image)
path->path_len = 9; /* FIXME */ path->path_len = 9; /* FIXME */
DBG("add libraries path %s\n", path->path); DBG("add libraries path %s\n", path->path);
list_add_tail(&path->list, &path_list); list_add_tail(&path->list, &path_list);
#endif
#endif #endif
INIT_LIST_HEAD(&libc_dll.list); INIT_LIST_HEAD(&libc_dll.list);
@ -239,18 +243,18 @@ void __fastcall init_loader(void *libc_image)
libc_dll.img_exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,libc_image, libc_dll.img_exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,libc_image,
nt->OptionalHeader.DataDirectory[0].VirtualAddress); nt->OptionalHeader.DataDirectory[0].VirtualAddress);
list_add_tail(&libc_dll.list, &dll_list);
}; };
const module_t* find_module(const char *name) const module_t* find_module(const char *name)
{ {
module_t* mod; module_t* mod = &libc_dll;
list_for_each_entry(mod, &dll_list, list) do
{ {
if( !strncmp(name, mod->img_name, 16)) if( !strncmp(name, mod->img_name, 16))
return mod; return mod;
}; mod = (module_t*)mod->list.next;
}while(mod != &libc_dll);
return load_module(name); return load_module(name);
}; };
@ -268,15 +272,6 @@ static inline void sec_copy(void *dst, void *src, size_t len)
:::"ecx","esi","edi"); :::"ecx","esi","edi");
}; };
static inline void *user_alloc(size_t size)
{
void *val;
__asm__ __volatile__(
"int $0x40"
:"=eax"(val)
:"a"(68),"b"(12),"c"(size));
return val;
}
void* __fastcall create_image(void *raw) void* __fastcall create_image(void *raw)
{ {
@ -366,6 +361,9 @@ void* __fastcall create_image(void *raw)
return img_base; return img_base;
}; };
static jmp_buf loader_env;
static loader_recursion;
int __fastcall link_image(void *img_base) int __fastcall link_image(void *img_base)
{ {
static jmp_buf loader_env; static jmp_buf loader_env;
@ -552,6 +550,178 @@ int __fastcall link_image(void *img_base)
return 0; return 0;
} }
int link_app()
{
PIMAGE_IMPORT_DESCRIPTOR imp;
struct app_hdr *header = NULL;
int warn = 0;
if( unlikely(setjmp(loader_env) != 0))
{
loader_recursion = 0;
return 0;
};
imp = (PIMAGE_IMPORT_DESCRIPTOR)header->__idata_start;
while ( imp->Name )
{
PIMAGE_DOS_HEADER expdos;
PIMAGE_NT_HEADERS32 expnt;
PIMAGE_EXPORT_DIRECTORY exp;
PIMAGE_THUNK_DATA32 thunk;
void **iat;
char *libname;
uint32_t *exp_functions;
uint16_t *exp_ordinals;
char **exp_names;
const module_t *api;
libname=MakePtr(char*,imp->Name, NULL);
DBG("import from %s\n",libname);
api = find_module(libname);
if(unlikely(api == NULL))
{
printf("library %s not found\n", libname);
longjmp(loader_env, 1);
}
iat = MakePtr(void**,imp->FirstThunk, NULL);
if(imp->OriginalFirstThunk !=0 )
{
thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->OriginalFirstThunk, NULL);
}
else
{
thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->FirstThunk, NULL);
};
exp = api->img_exp;
exp_functions = MakePtr(uint32_t*,exp->AddressOfFunctions,api->start);
exp_ordinals = MakePtr(uint16_t*, exp->AddressOfNameOrdinals,api->start);
exp_names = MakePtr(char**, exp->AddressOfNames,api->start);
while ( thunk->u1.AddressOfData != 0 )
{
PIMAGE_IMPORT_BY_NAME imp_name;
if (thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)
{
// ordinal = (*func_list) & 0x7fffffff;
// *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->DllBase, Ordinal);
// if ((*ImportAddressList) == NULL)
// {
// DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName);
// RtlpRaiseImportNotFound(NULL, Ordinal, &ImportedModule->FullDllName);
// return STATUS_ENTRYPOINT_NOT_FOUND;
// }
}
else
{
char *export_name;
uint16_t ordinal;
void *function;
uint32_t minn;
uint32_t maxn;
imp_name = MakePtr(PIMAGE_IMPORT_BY_NAME,
thunk->u1.AddressOfData, NULL);
*iat = NULL;
DBG("import %s", imp_name->Name);
if(imp_name->Hint < exp->NumberOfNames)
{
export_name = MakePtr(char*,exp_names[imp_name->Hint],
api->start);
if(strcmp(imp_name->Name, export_name) == 0)
{
ordinal = exp_ordinals[imp_name->Hint];
function = MakePtr(void*,exp_functions[ordinal], api->start);
if((uint32_t)function >= (uint32_t)exp)
{
printf("forward %s\n", function);
warn=1;
}
else
{
DBG(" \t\tat %x\n", function);
*iat = function;
};
thunk++; // Advance to next thunk
iat++;
continue;
};
};
minn = 0;
maxn = exp->NumberOfNames - 1;
while (minn <= maxn)
{
int mid;
int res;
mid = (minn + maxn) / 2;
export_name = MakePtr(char*,exp_names[mid],api->start);
res = strcmp(export_name, imp_name->Name);
if (res == 0)
{
ordinal = exp_ordinals[mid];
function = MakePtr(void*,exp_functions[ordinal], api->start);
if((uint32_t)function >= (uint32_t)exp)
{
DBG("forward %s\n", function);
warn=1;
}
else
{
DBG(" \t\tat %x\n", function);
*iat = function;
};
break;
}
else if (minn == maxn)
{
printf(" unresolved %s\n",imp_name->Name);
warn=1;
break;
}
else if (res > 0)
{
maxn = mid - 1;
}
else
{
minn = mid + 1;
}
};
};
thunk++; // Advance to next thunk
iat++;
}
imp++; // advance to next IMAGE_IMPORT_DESCRIPTOR
};
if ( !warn )
return 1;
else
return 0;
}
void* get_entry_point(void *raw) void* get_entry_point(void *raw)
{ {
PIMAGE_DOS_HEADER dos; PIMAGE_DOS_HEADER dos;
@ -707,7 +877,7 @@ module_t* load_module(const char *name)
module->img_exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base, module->img_exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
nt->OptionalHeader.DataDirectory[0].VirtualAddress); nt->OptionalHeader.DataDirectory[0].VirtualAddress);
list_add_tail(&module->list, &dll_list); list_add_tail(&module->list, &libc_dll.list);
if( link_image(img_base)) if( link_image(img_base))
{ {

View File

@ -3,17 +3,8 @@
#include <_ansi.h> #include <_ansi.h>
#include <string.h> #include <string.h>
#include <reent.h> #include <reent.h>
#include <kos32sys.h>
static inline
void *user_alloc(int size)
{
void *val;
__asm__ __volatile__(
"int $0x40"
:"=eax"(val)
:"a"(68),"b"(12),"c"(size));
return val;
}
void init_reent() void init_reent()
{ {
@ -24,7 +15,7 @@ void init_reent()
_REENT_INIT_PTR(ent); _REENT_INIT_PTR(ent);
__asm__ __volatile__( __asm__ __volatile__(
"movl %0, %%fs:12" "movl %0, %%fs:16"
::"r"(ent)); ::"r"(ent));
__sinit(ent); __sinit(ent);
} }

View File

@ -11,7 +11,7 @@ void init_global_reent()
_REENT_INIT_PTR(ent); _REENT_INIT_PTR(ent);
__asm__ __volatile__( __asm__ __volatile__(
"movl %0, %%fs:12" "movl %0, %%fs:16"
::"r"(ent)); ::"r"(ent));
// __sinit(ent); // __sinit(ent);
} }