about summary refs log tree commit diff stats
path: root/src/emu/entrypoint.c
blob: 927ac0d15a9c2a86c3f2a429d32d7c62704fdfcd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "debug.h"
#include "x64run_private.h"
#include "box64cpu.h"
#include "box64cpu_util.h"
#include "elfloader.h"
#include "box32.h"

#ifdef ANDROID
void EXPORT my___libc_init(x64emu_t* emu, void* raw_args , void (*onexit)(void) , int (*main)(int, char**, char**), void const * const structors )
{
    //TODO: register fini
    // let's cheat and set all args...
    SetRDX(emu, (uintptr_t)my_context->envv);
    SetRSI(emu, (uintptr_t)my_context->argv);
    SetRDI(emu, (uintptr_t)my_context->argc);

    printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_init\n", my_context->argc, my_context->argv, my_context->envv, main);
    // should call structors->preinit_array and structors->init_array!
    // call main and finish
    Push64(emu, GetRBP(emu));   // set frame pointer
    SetRBP(emu, GetRSP(emu));   // save RSP
    SetRSP(emu, GetRSP(emu)&~0xFLL);    // Align RSP
    PushExit(emu);
    R_RIP=(uintptr_t)main;

    DynaRun(emu);

    SetRSP(emu, GetRBP(emu));   // restore RSP
    SetRBP(emu, Pop64(emu));    // restore RBP
    emu->quit = 1; // finished!
}
#else
EXPORT int32_t my___libc_start_main(x64emu_t* emu, int (*main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end))
{
    (void)argc; (void)ubp_av; (void)fini; (void)rtld_fini; (void)stack_end;

    if(init) {
        uintptr_t old_rsp = GetRSP(emu);
        uintptr_t old_rbp = GetRBP(emu); // should not be needed, but seems to be without dynarec
        Push64(emu, GetRBP(emu));   // set frame pointer
        SetRBP(emu, GetRSP(emu));   // save RSP
        SetRSP(emu, GetRSP(emu)&~0xFLL);    // Align RSP
        PushExit(emu);
        SetRDX(emu, (uint64_t)my_context->envv);
        SetRSI(emu, (uint64_t)my_context->argv);
        SetRDI(emu, (uint64_t)my_context->argc);
        R_RIP=(uint64_t)*init;
        printf_dump(LOG_DEBUG, "Calling init(%p) from __libc_start_main\n", *init);
        DynaRun(emu);
        if(emu->error)  // any error, don't bother with more
            return 0;
        SetRSP(emu, GetRBP(emu));   // restore RSP
        SetRBP(emu, Pop64(emu));    // restore RBP
        SetRSP(emu, old_rsp);
        SetRBP(emu, old_rbp);
        emu->quit = 0;
    } else {
        if(my_context->elfs[0]) {
            printf_dump(LOG_DEBUG, "Calling init from main elf\n");
            RunElfInit(my_context->elfs[0], emu);
        }
    }
    if(my_context->elfs[0]) {
        MarkElfInitDone(my_context->elfs[0]);
    }
    printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_start_main\n", my_context->argc, my_context->argv, my_context->envv, main);
    // call main and finish
    Push64(emu, GetRBP(emu));   // set frame pointer
    SetRBP(emu, GetRSP(emu));   // save RSP
    SetRSP(emu, GetRSP(emu)&~0xFLL);    // Align RSP
    PushExit(emu);
    SetRDX(emu, (uint64_t)my_context->envv);
    SetRSI(emu, (uint64_t)my_context->argv);
    SetRDI(emu, (uint64_t)my_context->argc);
    R_RIP=(uint64_t)main;

    DynaRun(emu);

    if(!emu->quit) {
        SetRSP(emu, GetRBP(emu));   // restore RSP
        SetRBP(emu, Pop64(emu));         // restore RBP
        emu->quit = 1;  // finished!
    }
    return (int)GetEAX(emu);
}
#ifdef BOX32
#ifdef ANDROID
void EXPORT my32___libc_init(x64emu_t* emu, void* raw_args , void (*onexit)(void) , int (*main)(int, char**, char**), void const * const structors )
{
    //TODO: register fini
    // let's cheat and set all args...
    Push_32(emu, (uint32_t)my_context->envv32);
    Push_32(emu, (uint32_t)my_context->argv32);
    Push_32(emu, (uint32_t)my_context->argc);

    printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_init\n", my_context->argc, my_context->argv, my_context->envv, main);
    // should call structors->preinit_array and structors->init_array!
    // call main and finish
    PushExit_32(emu);
    R_EIP=to_ptrv(main);

    DynaRun(emu);

    emu->quit = 1; // finished!
}
#else
int32_t EXPORT my32___libc_start_main(x64emu_t* emu, int *(main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end))
{
    // let's cheat and set all args...
    Push_32(emu, my_context->envv32);
    Push_32(emu, my_context->argv32);
    Push_32(emu, my_context->argc);
    if(init) {
        PushExit_32(emu);
        R_EIP=to_ptrv(*init);
        printf_log(LOG_DEBUG, "Calling init(%p) from __libc_start_main\n", *init);
        DynaRun(emu);
        if(emu->error)  // any error, don't bother with more
            return 0;
        emu->quit = 0;
    } else {
        if(my_context->elfs[0]) {
            printf_dump(LOG_DEBUG, "Calling init from main elf\n");
            RunElfInit(my_context->elfs[0], emu);
        }
    }
    if(my_context->elfs[0]) {
        MarkElfInitDone(my_context->elfs[0]);
    }
    printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_start_main\n", my_context->argc, my_context->argv, my_context->envv, main);
    // call main and finish
    PushExit_32(emu);
    R_EIP=to_ptrv(main);

    DynaRun(emu);

    emu->quit = 1; // finished!
    return 0;
}
#endif
#endif
#endif