preloader: Setup a fake thread-local storage block pointed to by %gs.
This commit is contained in:
parent
c9b5569bc2
commit
a68d293bae
|
@ -405,6 +405,10 @@ unsigned short wine_ldt_alloc_fs(void)
|
||||||
struct modify_ldt_s ldt_info;
|
struct modify_ldt_s ldt_info;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* the preloader may have allocated it already */
|
||||||
|
global_fs_sel = wine_get_fs();
|
||||||
|
if (global_fs_sel && is_gdt_sel(global_fs_sel)) return global_fs_sel;
|
||||||
|
|
||||||
ldt_info.entry_number = -1;
|
ldt_info.entry_number = -1;
|
||||||
fill_modify_ldt_struct( &ldt_info, &null_entry );
|
fill_modify_ldt_struct( &ldt_info, &null_entry );
|
||||||
if ((ret = set_thread_area( &ldt_info ) < 0))
|
if ((ret = set_thread_area( &ldt_info ) < 0))
|
||||||
|
|
|
@ -163,6 +163,26 @@ void __bb_init_func(void) { return; }
|
||||||
void *__stack_chk_guard = 0;
|
void *__stack_chk_guard = 0;
|
||||||
void __stack_chk_fail(void) { return; }
|
void __stack_chk_fail(void) { return; }
|
||||||
|
|
||||||
|
/* data for setting up the glibc-style thread-local storage in %gs */
|
||||||
|
|
||||||
|
static int thread_data[256];
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
/* this is the kernel modify_ldt struct */
|
||||||
|
unsigned int entry_number;
|
||||||
|
unsigned long base_addr;
|
||||||
|
unsigned int limit;
|
||||||
|
unsigned int seg_32bit : 1;
|
||||||
|
unsigned int contents : 2;
|
||||||
|
unsigned int read_exec_only : 1;
|
||||||
|
unsigned int limit_in_pages : 1;
|
||||||
|
unsigned int seg_not_present : 1;
|
||||||
|
unsigned int useable : 1;
|
||||||
|
unsigned int garbage : 25;
|
||||||
|
} thread_ldt = { -1, (unsigned long)thread_data, 0xfffff, 1, 0, 0, 1, 0, 1, 0 };
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The _start function is the entry and exit point of this program
|
* The _start function is the entry and exit point of this program
|
||||||
*
|
*
|
||||||
|
@ -172,7 +192,17 @@ void __stack_chk_fail(void) { return; }
|
||||||
void _start();
|
void _start();
|
||||||
extern char _end[];
|
extern char _end[];
|
||||||
__ASM_GLOBAL_FUNC(_start,
|
__ASM_GLOBAL_FUNC(_start,
|
||||||
"\tmovl %esp,%eax\n"
|
"\tmovl $243,%eax\n" /* SYS_set_thread_area */
|
||||||
|
"\tmovl $thread_ldt,%ebx\n"
|
||||||
|
"\tint $0x80\n" /* allocate gs segment */
|
||||||
|
"\torl %eax,%eax\n"
|
||||||
|
"\tjl 1f\n"
|
||||||
|
"\tmovl thread_ldt,%eax\n" /* thread_ldt.entry_number */
|
||||||
|
"\tshl $3,%eax\n"
|
||||||
|
"\torl $3,%eax\n"
|
||||||
|
"\tmov %ax,%gs\n"
|
||||||
|
"\tmov %ax,%fs\n" /* set %fs too so libwine can retrieve it later on */
|
||||||
|
"1:\tmovl %esp,%eax\n"
|
||||||
"\tleal -136(%esp),%esp\n" /* allocate some space for extra aux values */
|
"\tleal -136(%esp),%esp\n" /* allocate some space for extra aux values */
|
||||||
"\tpushl %eax\n" /* orig stack pointer */
|
"\tpushl %eax\n" /* orig stack pointer */
|
||||||
"\tpushl %esp\n" /* ptr to orig stack pointer */
|
"\tpushl %esp\n" /* ptr to orig stack pointer */
|
||||||
|
|
Loading…
Reference in New Issue