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
4ec770a1
Commit
4ec770a1
authored
Nov 28, 2022
by
Brendan Shanks
Committed by
Alexandre Julliard
Dec 01, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
loader: Add comments to 'start' in macOS preloader.
parent
57ce3b91
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
91 additions
and
38 deletions
+91
-38
preloader_mac.c
loader/preloader_mac.c
+91
-38
No files found.
loader/preloader_mac.c
View file @
4ec770a1
...
...
@@ -101,6 +101,47 @@ void *__stack_chk_guard = 0;
void
__stack_chk_fail_local
(
void
)
{
return
;
}
void
__stack_chk_fail
(
void
)
{
return
;
}
/*
* When 'start' is called, stack frame looks like:
*
* :
* | STRING AREA |
* +-------------+
* | 0 |
* +-------------+
* | exec_path | extra "apple" parameters start after NULL terminating env array
* +-------------+
* | 0 |
* +-------------+
* | env[n] |
* +-------------+
* :
* :
* +-------------+
* | env[0] |
* +-------------+
* | 0 |
* +-------------+
* | arg[argc-1] |
* +-------------+
* :
* :
* +-------------+
* | arg[0] |
* +-------------+
* | argc | argc is always 4 bytes long, even in 64-bit architectures
* +-------------+ <- sp
*
* Where arg[i] and env[i] point into the STRING AREA
*
* See also:
* macOS C runtime 'start':
* <https://github.com/apple-oss-distributions/Csu/blob/Csu-88/start.s>
*
* macOS dyld '__dyld_start' (pre-dyld4):
* <https://github.com/apple-oss-distributions/dyld/blob/dyld-852.2/src/dyldStartup.s>
*/
#ifdef __i386__
static
const
size_t
page_size
=
0x1000
;
...
...
@@ -132,13 +173,14 @@ static const size_t page_mask = 0xfff;
__ASM_GLOBAL_FUNC
(
start
,
__ASM_CFI
(
"
\t
.cfi_undefined %eip
\n
"
)
/* The first 16 bytes are used as a function signature on i386 */
"
\t
.byte 0x6a,0x00
\n
"
/* pushl $0 */
"
\t
.byte 0x89,0xe5
\n
"
/* movl %esp,%ebp */
"
\t
.byte 0x83,0xe4,0xf0
\n
"
/* andl $-16,%esp */
"
\t
.byte 0x83,0xec,0x10
\n
"
/* subl $16,%esp */
"
\t
.byte 0x8b,0x5d,0x04
\n
"
/* movl 4(%ebp),%ebx */
"
\t
.byte 0x89,0x5c,0x24,0x00
\n
"
/* movl %ebx,0(%esp) */
"
\t
.byte 0x6a,0x00
\n
"
/* pushl $0: push a zero for debugger end of frames marker */
"
\t
.byte 0x89,0xe5
\n
"
/* movl %esp,%ebp: pointer to base of kernel frame */
"
\t
.byte 0x83,0xe4,0xf0
\n
"
/* andl $-16,%esp: force SSE alignment */
"
\t
.byte 0x83,0xec,0x10
\n
"
/* subl $16,%esp: room for new argc, argv, & envp, SSE aligned */
"
\t
.byte 0x8b,0x5d,0x04
\n
"
/* movl 4(%ebp),%ebx: pickup argc in %ebx */
"
\t
.byte 0x89,0x5c,0x24,0x00
\n
"
/* movl %ebx,0(%esp): argc to reserved stack word */
/* call wld_start(stack, &is_unix_thread) */
"
\t
leal 4(%ebp),%eax
\n
"
"
\t
movl %eax,0(%esp)
\n
"
/* stack */
"
\t
leal 8(%esp),%eax
\n
"
...
...
@@ -146,16 +188,21 @@ __ASM_GLOBAL_FUNC( start,
"
\t
movl $0,(%eax)
\n
"
"
\t
call _wld_start
\n
"
/* argc/argv need to be fixed to remove argv[0].
* With LC_MAIN, pointers to argv/env/apple are passed so this is easy.
* With LC_UNIXTHREAD, argv[1] to the end of apple[] need to be moved.
*/
"
\t
movl 4(%ebp),%edi
\n
"
"
\t
decl %edi
\n
"
/*
argc
*/
"
\t
leal 12(%ebp),%esi
\n
"
/*
argv
*/
"
\t
leal 4(%esi,%edi,4),%edx
\n
"
/* env */
"
\t
movl %edx,%ecx
\n
"
/* apple data */
"
\t
decl %edi
\n
"
/*
%edi = argc (decremented)
*/
"
\t
leal 12(%ebp),%esi
\n
"
/*
%esi = &argv[1]
*/
"
\t
leal 4(%esi,%edi,4),%edx
\n
"
/*
%edx =
env */
"
\t
movl %edx,%ecx
\n
"
"1:
\t
movl (%ecx),%ebx
\n
"
"
\t
add $4,%ecx
\n
"
"
\t
orl %ebx,%ebx
\n
"
"
\t
jnz 1b
\n
"
"
\t
orl %ebx,%ebx
\n
"
/* look for the NULL ending the env[] array */
"
\t
jnz 1b
\n
"
/* %ecx = apple data */
/* jmp based on is_unix_thread */
"
\t
cmpl $0,8(%esp)
\n
"
"
\t
jne 2f
\n
"
...
...
@@ -164,16 +211,16 @@ __ASM_GLOBAL_FUNC( start,
"
\t
movl %esi,4(%esp)
\n
"
/* argv */
"
\t
movl %edx,8(%esp)
\n
"
/* env */
"
\t
movl %ecx,12(%esp)
\n
"
/* apple data */
"
\t
call *%eax
\n
"
"
\t
movl %eax,(%esp)
\n
"
"
\t
call _wld_exit
\n
"
"
\t
call *%eax
\n
"
/* call main(argc,argv,env,apple) */
"
\t
movl %eax,(%esp)
\n
"
/* pass result from main() to exit() */
"
\t
call _wld_exit
\n
"
/* need to use call to keep stack aligned */
"
\t
hlt
\n
"
/* LC_UNIXTHREAD */
"2:
\t
movl (%ecx),%ebx
\n
"
"
\t
add $4,%ecx
\n
"
"
\t
orl %ebx,%ebx
\n
"
"
\t
jnz 2b
\n
"
"
\t
orl %ebx,%ebx
\n
"
/* look for the NULL ending the apple[] array */
"
\t
jnz 2b
\n
"
/* %ecx = end of apple[] */
"
\t
subl %ebp,%ecx
\n
"
"
\t
subl $8,%ecx
\n
"
...
...
@@ -186,8 +233,8 @@ __ASM_GLOBAL_FUNC( start,
"
\t
cld
\n
"
"
\t
rep; movsd
\n
"
/* argv, ... */
"
\t
movl $0,%ebp
\n
"
"
\t
jmpl *%eax
\n
"
)
"
\t
movl $0,%ebp
\n
"
/* restore ebp back to zero */
"
\t
jmpl *%eax
\n
"
)
/* jump to the entry point */
#elif defined(__x86_64__)
...
...
@@ -221,41 +268,47 @@ static const size_t page_mask = 0xfff;
__ASM_GLOBAL_FUNC
(
start
,
__ASM_CFI
(
"
\t
.cfi_undefined %rip
\n
"
)
"
\t
pushq $0
\n
"
"
\t
movq %rsp,%rbp
\n
"
"
\t
andq $-16,%rsp
\n
"
"
\t
subq $16,%rsp
\n
"
"
\t
pushq $0
\n
"
/* push a zero for debugger end of frames marker */
"
\t
movq %rsp,%rbp
\n
"
/* pointer to base of kernel frame */
"
\t
andq $-16,%rsp
\n
"
/* force SSE alignment */
"
\t
subq $16,%rsp
\n
"
/* room for local variables */
/* call wld_start(stack, &is_unix_thread) */
"
\t
leaq 8(%rbp),%rdi
\n
"
/* stack */
"
\t
movq %rsp,%rsi
\n
"
/* &is_unix_thread */
"
\t
movq $0,(%rsi)
\n
"
"
\t
call _wld_start
\n
"
/* argc/argv need to be fixed to remove argv[0].
* With LC_MAIN, pointers to argv/env/apple are passed so this is easy.
* With LC_UNIXTHREAD, argv[1] to the end of apple[] need to be moved.
*/
"
\t
movq 8(%rbp),%rdi
\n
"
"
\t
dec %rdi
\n
"
/*
argc
*/
"
\t
leaq 24(%rbp),%rsi
\n
"
/*
argv
*/
"
\t
leaq 8(%rsi,%rdi,8),%rdx
\n
"
/* env */
"
\t
movq %rdx,%rcx
\n
"
/* apple data */
"
\t
dec %rdi
\n
"
/*
%rdi = argc (decremented)
*/
"
\t
leaq 24(%rbp),%rsi
\n
"
/*
%rsi = &argv[1]
*/
"
\t
leaq 8(%rsi,%rdi,8),%rdx
\n
"
/*
%rdx =
env */
"
\t
movq %rdx,%rcx
\n
"
"1:
\t
movq (%rcx),%r8
\n
"
"
\t
addq $8,%rcx
\n
"
"
\t
orq %r8,%r8
\n
"
"
\t
jnz 1b
\n
"
"
\t
orq %r8,%r8
\n
"
/* look for the NULL ending the env[] array */
"
\t
jnz 1b
\n
"
/* %rcx = apple data */
/* jmp based on is_unix_thread */
"
\t
cmpl $0,0(%rsp)
\n
"
"
\t
jne 2f
\n
"
/* LC_MAIN */
"
\t
addq $16,%rsp
\n
"
"
\t
call *%rax
\n
"
"
\t
movq %rax,%rdi
\n
"
"
\t
call _wld_exit
\n
"
"
\t
addq $16,%rsp
\n
"
/* remove local variables */
"
\t
call *%rax
\n
"
/* call main(argc,argv,env,apple) */
"
\t
movq %rax,%rdi
\n
"
/* pass result from main() to exit() */
"
\t
call _wld_exit
\n
"
/* need to use call to keep stack aligned */
"
\t
hlt
\n
"
/* LC_UNIXTHREAD */
"2:
\t
movq (%rcx),%r8
\n
"
"
\t
addq $8,%rcx
\n
"
"
\t
orq %r8,%r8
\n
"
"
\t
jnz 2b
\n
"
"
\t
orq %r8,%r8
\n
"
/* look for the NULL ending the apple[] array */
"
\t
jnz 2b
\n
"
/* %rcx = end of apple[] */
"
\t
subq %rbp,%rcx
\n
"
"
\t
subq $16,%rcx
\n
"
...
...
@@ -268,8 +321,8 @@ __ASM_GLOBAL_FUNC( start,
"
\t
cld
\n
"
"
\t
rep; movsq
\n
"
/* argv, ... */
"
\t
movq $0,%rbp
\n
"
"
\t
jmpq *%rax
\n
"
)
"
\t
movq $0,%rbp
\n
"
/* restore ebp back to zero */
"
\t
jmpq *%rax
\n
"
)
/* jump to the entry point */
#else
#error preloader not implemented for this CPU
...
...
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