forked from KolibriOS/kolibrios
newlib: dynamic loader
git-svn-id: svn://kolibrios.org@3809 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
89c2639856
commit
1707fbc555
@ -1,7 +1,7 @@
|
||||
|
||||
CC = gcc
|
||||
|
||||
CFLAGS = -c -O2 -fomit-frame-pointer
|
||||
CFLAGS = -c -O2 -fomit-frame-pointer -DBUILD_DLL
|
||||
LDFLAGS = -nostdlib -shared -s -T libcdll.lds --out-implib libcimp.a --image-base 0
|
||||
|
||||
LIBC_TOPDIR = .
|
||||
@ -21,11 +21,12 @@ STATIC_SRCS:= \
|
||||
crt/exit.S \
|
||||
pe/crtloader.c
|
||||
|
||||
DLL_SRCS:= \
|
||||
crt/crtbegin.c \
|
||||
crt/pseudo-reloc.c \
|
||||
LIBDLL_SRCS:= \
|
||||
crt/dllstart.c \
|
||||
crt/chkstk.S \
|
||||
crt/exit.S
|
||||
crt/exit.S \
|
||||
crt/pseudo-reloc.c \
|
||||
crt/setjmp.S
|
||||
|
||||
|
||||
LIBCDLL_SRCS:= \
|
||||
@ -39,7 +40,6 @@ LIBCRT_SRCS:= \
|
||||
crt/start.S \
|
||||
crt/chkstk.S \
|
||||
crt/crt3.c \
|
||||
crt/crtbegin.o \
|
||||
pe/crtloader.c
|
||||
|
||||
CORE_SRCS:= \
|
||||
@ -306,7 +306,7 @@ 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)))
|
||||
LIBDLL_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(LIBDLL_SRCS)))
|
||||
|
||||
LIBCDLL_OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(LIBCDLL_SRCS)))
|
||||
|
||||
@ -374,11 +374,8 @@ $(NAME).dll: $(LIB_OBJS) $(SRC_DEP) Makefile
|
||||
libcrt.a: $(LIBCRT_OBJS) Makefile
|
||||
ar rc libcrt.a $(LIBCRT_OBJS)
|
||||
|
||||
libdll.a: $(DLL_OBJS) Makefile
|
||||
ar rc libdll.a $(DLL_OBJS)
|
||||
|
||||
libc.obj: $(NAME).dll
|
||||
fasm pe/libc.asm ./libc.obj
|
||||
libdll.a: $(LIBDLL_OBJS) Makefile
|
||||
ar rc libdll.a $(LIBDLL_OBJS)
|
||||
|
||||
|
||||
static: $(NAME).a
|
||||
|
@ -1,9 +1,6 @@
|
||||
|
||||
extern void _pei386_runtime_relocator (void);
|
||||
|
||||
int DllStartup(void *module, int reason);// __attribute__ ((dllexport));
|
||||
|
||||
|
||||
int DllStartup(void *module, int reason)
|
||||
{
|
||||
_pei386_runtime_relocator();
|
||||
|
11
programs/develop/libraries/newlib/crt/dllstart.c
Normal file
11
programs/develop/libraries/newlib/crt/dllstart.c
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
void _pei386_runtime_relocator (void);
|
||||
|
||||
int DllStartup(void *module, int reason);
|
||||
|
||||
|
||||
int DllStartup(void *module, int reason)
|
||||
{
|
||||
_pei386_runtime_relocator();
|
||||
return 1;
|
||||
};
|
@ -1,8 +1,6 @@
|
||||
|
||||
OUTPUT_FORMAT(pei-i386)
|
||||
|
||||
ENTRY("____dll_start")
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
|
@ -209,20 +209,18 @@ void* load_libc()
|
||||
raw_img = uf.data;
|
||||
raw_size = uf.size;
|
||||
|
||||
|
||||
if(raw_img == NULL)
|
||||
return NULL;
|
||||
|
||||
// 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");
|
||||
user_free(raw_img);
|
||||
img_base = create_image(raw_img);
|
||||
};
|
||||
|
||||
img_base = create_image(raw_img);
|
||||
|
||||
user_free(raw_img);
|
||||
|
||||
return img_base;
|
||||
|
||||
|
@ -20,10 +20,8 @@
|
||||
|
||||
|
||||
void init_loader(void *libc_image);
|
||||
void* __fastcall create_image(void *raw);
|
||||
int __fastcall link_image(void *img_base);
|
||||
int __fastcall do_exec(uint32_t my_app, uint32_t *params);
|
||||
|
||||
void* create_image(void *raw);
|
||||
int link_image(void *img_base, PIMAGE_IMPORT_DESCRIPTOR imp);
|
||||
|
||||
extern char* __appenv;
|
||||
extern int __appenv_size;
|
||||
@ -148,6 +146,8 @@ void init_loader(void *libc_image)
|
||||
PIMAGE_EXPORT_DIRECTORY exp;
|
||||
|
||||
struct app_hdr *header;
|
||||
dll_path_t *path;
|
||||
|
||||
#if 0
|
||||
dll_path_t *path;
|
||||
int len;
|
||||
@ -212,16 +212,14 @@ void init_loader(void *libc_image)
|
||||
DBG("add libraries path %s\n", path->path);
|
||||
list_add_tail(&path->list, &path_list);
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
path = (dll_path_t*)malloc(sizeof(dll_path_t));
|
||||
INIT_LIST_HEAD(&path->list);
|
||||
path->path = "/sys/lib/";
|
||||
path->path_len = 9; /* FIXME */
|
||||
path->path = "/kolibrios/lib/";
|
||||
path->path_len = 15; /* FIXME */
|
||||
DBG("add libraries path %s\n", path->path);
|
||||
list_add_tail(&path->list, &path_list);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
INIT_LIST_HEAD(&libc_dll.list);
|
||||
|
||||
@ -273,7 +271,7 @@ static inline void sec_copy(void *dst, void *src, size_t len)
|
||||
};
|
||||
|
||||
|
||||
void* __fastcall create_image(void *raw)
|
||||
void* create_image(void *raw)
|
||||
{
|
||||
PIMAGE_DOS_HEADER dos;
|
||||
PIMAGE_NT_HEADERS32 nt;
|
||||
@ -361,16 +359,13 @@ void* __fastcall create_image(void *raw)
|
||||
return img_base;
|
||||
};
|
||||
|
||||
static jmp_buf loader_env;
|
||||
static loader_recursion;
|
||||
//static jmp_buf loader_env;
|
||||
//static loader_recursion;
|
||||
|
||||
int __fastcall link_image(void *img_base)
|
||||
int link_image(void *img_base, PIMAGE_IMPORT_DESCRIPTOR imp)
|
||||
{
|
||||
static jmp_buf loader_env;
|
||||
static recursion = -1;
|
||||
|
||||
PIMAGE_DOS_HEADER dos;
|
||||
PIMAGE_NT_HEADERS32 nt;
|
||||
int warn = 0;
|
||||
|
||||
recursion++;
|
||||
@ -383,16 +378,6 @@ int __fastcall link_image(void *img_base)
|
||||
};
|
||||
};
|
||||
|
||||
dos = (PIMAGE_DOS_HEADER)img_base;
|
||||
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
|
||||
|
||||
if(nt->OptionalHeader.DataDirectory[1].Size)
|
||||
{
|
||||
PIMAGE_IMPORT_DESCRIPTOR imp;
|
||||
|
||||
imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base,
|
||||
nt->OptionalHeader.DataDirectory[1].VirtualAddress);
|
||||
|
||||
while ( imp->Name )
|
||||
{
|
||||
PIMAGE_DOS_HEADER expdos;
|
||||
@ -540,7 +525,6 @@ int __fastcall link_image(void *img_base)
|
||||
}
|
||||
imp++; // advance to next IMAGE_IMPORT_DESCRIPTOR
|
||||
};
|
||||
};
|
||||
|
||||
recursion--;
|
||||
|
||||
@ -552,175 +536,15 @@ int __fastcall link_image(void *img_base)
|
||||
|
||||
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;
|
||||
};
|
||||
PIMAGE_IMPORT_DESCRIPTOR imp;
|
||||
|
||||
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;
|
||||
return link_image(NULL, imp);
|
||||
|
||||
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)
|
||||
{
|
||||
@ -804,13 +628,13 @@ void *get_proc_address(module_t *module, char *proc_name)
|
||||
|
||||
module_t* load_module(const char *name)
|
||||
{
|
||||
dll_path_t *dllpath;
|
||||
|
||||
char *path;
|
||||
int len;
|
||||
|
||||
len = strlen(name);
|
||||
|
||||
dll_path_t *dllpath;
|
||||
|
||||
list_for_each_entry(dllpath, &path_list, list)
|
||||
{
|
||||
PIMAGE_DOS_HEADER dos;
|
||||
@ -818,6 +642,7 @@ module_t* load_module(const char *name)
|
||||
PIMAGE_EXPORT_DIRECTORY exp;
|
||||
|
||||
module_t *module;
|
||||
ufile_t uf;
|
||||
void *raw_img;
|
||||
size_t raw_size;
|
||||
void *img_base;
|
||||
@ -828,10 +653,16 @@ module_t* load_module(const char *name)
|
||||
memcpy(path+dllpath->path_len, name, len);
|
||||
path[len+dllpath->path_len]=0;
|
||||
|
||||
// raw_img = load_file(path, &raw_size);
|
||||
// printf("%s %s\n", path);
|
||||
|
||||
uf = load_file(path);
|
||||
raw_img = uf.data;
|
||||
raw_size = uf.size;
|
||||
|
||||
if(raw_img == NULL)
|
||||
continue;
|
||||
|
||||
|
||||
if( validate_pe(raw_img, raw_size, 0) == 0)
|
||||
{
|
||||
printf("invalide module %s\n", path);
|
||||
@ -854,7 +685,7 @@ module_t* load_module(const char *name)
|
||||
{
|
||||
printf("%s epic fail: no enough memory\n",__FUNCTION__);
|
||||
user_free(img_base);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&module->list);
|
||||
@ -879,22 +710,24 @@ module_t* load_module(const char *name)
|
||||
|
||||
list_add_tail(&module->list, &libc_dll.list);
|
||||
|
||||
if( link_image(img_base))
|
||||
if(nt->OptionalHeader.DataDirectory[1].Size)
|
||||
{
|
||||
PIMAGE_IMPORT_DESCRIPTOR imp;
|
||||
int (*dll_startup)(module_t *mod, uint32_t reason);
|
||||
|
||||
imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base,
|
||||
nt->OptionalHeader.DataDirectory[1].VirtualAddress);
|
||||
|
||||
if(link_image(img_base, imp) == 0)
|
||||
return NULL;
|
||||
|
||||
dll_startup = get_proc_address(module, "DllStartup");
|
||||
if( dll_startup )
|
||||
{
|
||||
if( 0 == dll_startup(module, 1))
|
||||
return 0;
|
||||
}
|
||||
return NULL;
|
||||
};
|
||||
return module;
|
||||
};
|
||||
|
||||
return NULL;
|
||||
};
|
||||
|
||||
return NULL;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user