Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
0a086200
Commit
0a086200
authored
Dec 16, 2010
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
loader: Build the preloader for x86-64.
parent
fe031c93
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
166 additions
and
16 deletions
+166
-16
.gitignore
.gitignore
+1
-0
configure
configure
+6
-5
configure.ac
configure.ac
+5
-5
Makefile.in
loader/Makefile.in
+5
-4
main.c
loader/main.c
+7
-0
preloader.c
loader/preloader.c
+142
-2
No files found.
.gitignore
View file @
0a086200
...
...
@@ -262,6 +262,7 @@ loader/wine
loader/wine-installed
loader/wine-preloader
loader/wine64
loader/wine64-preloader
programs/Makeprog.rules
programs/rpcss/epm.h
programs/rpcss/epm_s.c
...
...
configure
View file @
0a086200
...
...
@@ -12736,11 +12736,12 @@ MAIN_BINARY="wine"
test
"x
$enable_win64
"
!=
"xyes"
||
MAIN_BINARY
=
"wine64"
case
$host_cpu
in
*
i[3456789]86
*
)
case
$host_os
in
linux
*
)
EXTRA_BINARIES
=
"wine-preloader"
case
$host_os
in
linux
*
)
case
$host_cpu
in
*
i[3456789]86
*
)
EXTRA_BINARIES
=
"wine-preloader"
;;
x86_64
*
)
EXTRA_BINARIES
=
"wine64-preloader"
;;
esac
;;
...
...
configure.ac
View file @
0a086200
...
...
@@ -1863,11 +1863,11 @@ esac
AC_SUBST(MAIN_BINARY,"wine")
test "x$enable_win64" != "xyes" || MAIN_BINARY="wine64"
case $host_
cpu
in
*i[[3456789]]86
*)
case $host_
os
in
linux*)
AC_SUBST(EXTRA_BINARIES,"wine
-preloader") ;;
case $host_
os
in
linux
*)
case $host_
cpu
in
*i[[3456789]]86*) AC_SUBST(EXTRA_BINARIES,"wine-preloader") ;;
x86_64*) AC_SUBST(EXTRA_BINARIES,"wine64
-preloader") ;;
esac
;;
esac
...
...
loader/Makefile.in
View file @
0a086200
...
...
@@ -9,9 +9,10 @@ EXTRA_BINARIES = @EXTRA_BINARIES@
PROGRAMS
=
\
wine
\
wine64
\
wine-installed
\
wine-preloader
wine-preloader
\
wine64
\
wine64-preloader
MANPAGE
=
wine.man
...
...
@@ -32,8 +33,8 @@ all: $(MAIN_BINARY) wine-installed $(EXTRA_BINARIES)
LIBPTHREAD
=
@LIBPTHREAD@
LDEXECFLAGS
=
@LDEXECFLAGS@
wine-preloader
:
preloader.o Makefile.in
$(CC)
-o
$@
-static
-nostartfiles
-nodefaultlibs
-Wl
,-Ttext
=
0x7c
0
00000 preloader.o
$(LIBPORT)
$(LDFLAGS)
wine-preloader
wine64-preloader
:
preloader.o Makefile.in
$(CC)
-o
$@
-static
-nostartfiles
-nodefaultlibs
-Wl
,-Ttext
=
0x7c
4
00000 preloader.o
$(LIBPORT)
$(LDFLAGS)
$(MAIN_BINARY)
:
main.o Makefile.in
$(CC)
-o
$@
$(LDEXECFLAGS)
main.o
$(LIBWINE)
$(LIBPORT)
$(LIBPTHREAD)
$(EXTRALIBS)
$(LDFLAGS)
$(LDRPATH_LOCAL)
...
...
loader/main.c
View file @
0a086200
...
...
@@ -164,6 +164,13 @@ static int pre_exec(void)
return
1
;
}
#elif defined(__linux__) && defined(__x86_64__)
static
int
pre_exec
(
void
)
{
return
1
;
/* we have a preloader on x86-64 */
}
#elif defined(__FreeBSD__) && defined(__i386__)
static
int
pre_exec
(
void
)
...
...
loader/preloader.c
View file @
0a086200
...
...
@@ -108,10 +108,17 @@
static
struct
wine_preload_info
preload_info
[]
=
{
#ifdef __i386__
{
(
void
*
)
0x00000000
,
0x00010000
},
/* low 64k */
{
(
void
*
)
0x00010000
,
0x00100000
},
/* DOS area */
{
(
void
*
)
0x00110000
,
0x67ef0000
},
/* low memory area */
{
(
void
*
)
0x7f000000
,
0x03000000
},
/* top-down allocations + shared heap + virtual heap */
#else
{
(
void
*
)
0x000000010000
,
0x00100000
},
/* DOS area */
{
(
void
*
)
0x000000110000
,
0x67ef0000
},
/* low memory area */
{
(
void
*
)
0x00007ff00000
,
0x000f0000
},
/* shared user data */
{
(
void
*
)
0x7ffffe000000
,
0x01ff0000
},
/* top-down allocations + virtual heap */
#endif
{
0
,
0
},
/* PE exe range set with WINEPRELOADRESERVE */
{
0
,
0
}
/* end of list */
};
...
...
@@ -166,6 +173,8 @@ void *__stack_chk_guard = 0;
void
__stack_chk_fail_local
(
void
)
{
return
;
}
void
__stack_chk_fail
(
void
)
{
return
;
}
#ifdef __i386__
/* data for setting up the glibc-style thread-local storage in %gs */
static
int
thread_data
[
256
];
...
...
@@ -333,6 +342,126 @@ static inline int wld_prctl( int code, long arg )
return
SYSCALL_RET
(
ret
);
}
#elif defined(__x86_64__)
/*
* The _start function is the entry and exit point of this program
*
* It calls wld_start, passing a pointer to the args it receives
* then jumps to the address wld_start returns.
*/
void
_start
(
void
);
extern
char
_end
[];
__ASM_GLOBAL_FUNC
(
_start
,
"movq %rsp,%rax
\n\t
"
"leaq -144(%rsp),%rsp
\n\t
"
/* allocate some space for extra aux values */
"movq %rsp,%rdi
\n\t
"
/* ptr to orig stack pointer */
"movq %rax,(%rdi)
\n\t
"
/* orig stack pointer */
"call wld_start
\n\t
"
"movq (%rsp),%rsp
\n\t
"
/* new stack pointer */
"pushq %rax
\n\t
"
/* ELF interpreter entry point */
"xorq %rax,%rax
\n\t
"
"xorq %rcx,%rcx
\n\t
"
"xorq %rdx,%rdx
\n\t
"
"xorq %rsi,%rsi
\n\t
"
"xorq %rdi,%rdi
\n\t
"
"xorq %r8,%r8
\n\t
"
"xorq %r9,%r9
\n\t
"
"xorq %r10,%r10
\n\t
"
"xorq %r11,%r11
\n\t
"
"ret"
)
#define SYSCALL_RET(ret) (((ret) < 0 && (ret) > -4096) ? -1 : (ret))
static
inline
__attribute__
((
noreturn
))
void
wld_exit
(
int
code
)
{
for
(;;)
/* avoid warning */
__asm__
__volatile__
(
"syscall"
:
:
"a"
(
SYS_exit
),
"D"
(
code
)
);
}
static
inline
int
wld_open
(
const
char
*
name
,
int
flags
)
{
int
ret
;
__asm__
__volatile__
(
"syscall"
:
"=a"
(
ret
)
:
"0"
(
SYS_open
),
"D"
(
name
),
"S"
(
flags
)
);
return
SYSCALL_RET
(
ret
);
}
static
inline
int
wld_close
(
int
fd
)
{
int
ret
;
__asm__
__volatile__
(
"syscall"
:
"=a"
(
ret
)
:
"0"
(
SYS_close
),
"D"
(
fd
)
);
return
SYSCALL_RET
(
ret
);
}
static
inline
ssize_t
wld_read
(
int
fd
,
void
*
buffer
,
size_t
len
)
{
int
ret
;
__asm__
__volatile__
(
"syscall"
:
"=a"
(
ret
)
:
"0"
(
SYS_read
),
"D"
(
fd
),
"S"
(
buffer
),
"d"
(
len
)
:
"memory"
);
return
SYSCALL_RET
(
ret
);
}
static
inline
ssize_t
wld_write
(
int
fd
,
const
void
*
buffer
,
size_t
len
)
{
int
ret
;
__asm__
__volatile__
(
"syscall"
:
"=a"
(
ret
)
:
"0"
(
SYS_write
),
"D"
(
fd
),
"S"
(
buffer
),
"d"
(
len
)
);
return
SYSCALL_RET
(
ret
);
}
static
inline
int
wld_mprotect
(
const
void
*
addr
,
size_t
len
,
int
prot
)
{
int
ret
;
__asm__
__volatile__
(
"syscall"
:
"=a"
(
ret
)
:
"0"
(
SYS_mprotect
),
"D"
(
addr
),
"S"
(
len
),
"d"
(
prot
)
);
return
SYSCALL_RET
(
ret
);
}
void
*
wld_mmap
(
void
*
start
,
size_t
len
,
int
prot
,
int
flags
,
int
fd
,
off_t
offset
);
__ASM_GLOBAL_FUNC
(
wld_mmap
,
"movq %rcx,%r10
\n\t
"
"movq $9,%rax
\n\t
"
/* SYS_mmap */
"syscall
\n\t
"
"ret"
);
static
inline
uid_t
wld_getuid
(
void
)
{
uid_t
ret
;
__asm__
(
"syscall"
:
"=a"
(
ret
)
:
"0"
(
SYS_getuid
)
);
return
ret
;
}
static
inline
uid_t
wld_geteuid
(
void
)
{
uid_t
ret
;
__asm__
(
"syscall"
:
"=a"
(
ret
)
:
"0"
(
SYS_geteuid
)
);
return
ret
;
}
static
inline
gid_t
wld_getgid
(
void
)
{
gid_t
ret
;
__asm__
(
"syscall"
:
"=a"
(
ret
)
:
"0"
(
SYS_getgid
)
);
return
ret
;
}
static
inline
gid_t
wld_getegid
(
void
)
{
gid_t
ret
;
__asm__
(
"syscall"
:
"=a"
(
ret
)
:
"0"
(
SYS_getegid
)
);
return
ret
;
}
static
inline
int
wld_prctl
(
int
code
,
int
arg
)
{
int
ret
;
__asm__
__volatile__
(
"syscall"
:
"=a"
(
ret
)
:
"D"
(
SYS_prctl
),
"S"
(
code
),
"d"
(
arg
)
);
return
SYSCALL_RET
(
ret
);
}
#else
#error preloader not implemented for this CPU
#endif
/* replacement for libc functions */
...
...
@@ -594,8 +723,13 @@ static void map_so_lib( const char *name, struct wld_link_map *l)
(
header
->
e_ident
[
3
]
!=
'F'
)
)
fatal_error
(
"%s: not an ELF binary... don't know how to load it
\n
"
,
name
);
#ifdef __i386__
if
(
header
->
e_machine
!=
EM_386
)
fatal_error
(
"%s: not an i386 ELF binary... don't know how to load it
\n
"
,
name
);
#elif defined(__x86_64__)
if
(
header
->
e_machine
!=
EM_X86_64
)
fatal_error
(
"%s: not an x86-64 ELF binary... don't know how to load it
\n
"
,
name
);
#endif
if
(
header
->
e_phnum
>
sizeof
(
loadcmds
)
/
sizeof
(
loadcmds
[
0
]))
fatal_error
(
"%s: oops... not enough space for load commands
\n
"
,
name
);
...
...
@@ -1082,8 +1216,14 @@ void* wld_start( void **stack )
if
(
reserve
)
preload_reserve
(
reserve
);
for
(
i
=
0
;
preload_info
[
i
].
size
;
i
++
)
{
if
(
wld_mmap
(
preload_info
[
i
].
addr
,
preload_info
[
i
].
size
,
PROT_NONE
,
MAP_FIXED
|
MAP_PRIVATE
|
MAP_ANON
|
MAP_NORESERVE
,
-
1
,
0
)
==
(
void
*
)
-
1
)
if
((
char
*
)
av
>=
(
char
*
)
preload_info
[
i
].
addr
&&
(
char
*
)
pargc
<=
(
char
*
)
preload_info
[
i
].
addr
+
preload_info
[
i
].
size
)
{
remove_preload_range
(
i
);
i
--
;
}
else
if
(
wld_mmap
(
preload_info
[
i
].
addr
,
preload_info
[
i
].
size
,
PROT_NONE
,
MAP_FIXED
|
MAP_PRIVATE
|
MAP_ANON
|
MAP_NORESERVE
,
-
1
,
0
)
==
(
void
*
)
-
1
)
{
/* don't warn for low 64k */
if
(
preload_info
[
i
].
addr
>=
(
void
*
)
0x10000
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment