forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.cpp
245 lines (202 loc) · 7.62 KB
/
main.cpp
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#include <stdint.h>
//
// This is the mechanism whereby multiple linked modules contribute their global data for initialization at
// startup of the application.
//
// ILC creates sections in the output obj file to mark the beginning and end of merged global data.
// It defines sentinel symbols that are used to get the addresses of the start and end of global data
// at runtime. The section names are platform-specific to match platform-specific linker conventions.
//
#if defined(_MSC_VER)
#pragma section(".modules$A", read)
#pragma section(".modules$Z", read)
extern "C" __declspec(allocate(".modules$A")) void * __modules_a[];
extern "C" __declspec(allocate(".modules$Z")) void * __modules_z[];
__declspec(allocate(".modules$A")) void * __modules_a[] = { nullptr };
__declspec(allocate(".modules$Z")) void * __modules_z[] = { nullptr };
//
// Each obj file compiled from managed code has a .modules$I section containing a pointer to its ReadyToRun
// data (which points at eager class constructors, frozen strings, etc).
//
// The #pragma ... /merge directive folds the book-end sections and all .modules$I sections from all input
// obj files into .rdata in alphabetical order.
//
#pragma comment(linker, "/merge:.modules=.rdata")
//
// Unboxing stubs need to be merged, folded and sorted. They are delimited by two special sections (.unbox$A
// and .unbox$Z). All unboxing stubs are in .unbox$M sections.
//
#pragma comment(linker, "/merge:.unbox=.text")
char _bookend_a;
char _bookend_z;
//
// Generate bookends for the managed code section.
// We give them unique bodies to prevent folding.
//
#pragma code_seg(".managedcode$A")
void* __managedcode_a() { return &_bookend_a; }
#pragma code_seg(".managedcode$Z")
void* __managedcode_z() { return &_bookend_z; }
#pragma code_seg()
//
// Generate bookends for the unboxing stub section.
// We give them unique bodies to prevent folding.
//
#pragma code_seg(".unbox$A")
void* __unbox_a() { return &_bookend_a; }
#pragma code_seg(".unbox$Z")
void* __unbox_z() { return &_bookend_z; }
#pragma code_seg()
#else // _MSC_VER
#if defined(__APPLE__)
extern void * __modules_a[] __asm("section$start$__DATA$__modules");
extern void * __modules_z[] __asm("section$end$__DATA$__modules");
extern char __managedcode_a __asm("section$start$__TEXT$__managedcode");
extern char __managedcode_z __asm("section$end$__TEXT$__managedcode");
extern char __unbox_a __asm("section$start$__TEXT$__unbox");
extern char __unbox_z __asm("section$end$__TEXT$__unbox");
#else // __APPLE__
extern "C" void * __start___modules[];
extern "C" void * __stop___modules[];
static void * (&__modules_a)[] = __start___modules;
static void * (&__modules_z)[] = __stop___modules;
extern "C" char __start___managedcode;
extern "C" char __stop___managedcode;
static char& __managedcode_a = __start___managedcode;
static char& __managedcode_z = __stop___managedcode;
extern "C" char __start___unbox;
extern "C" char __stop___unbox;
static char& __unbox_a = __start___unbox;
static char& __unbox_z = __stop___unbox;
#endif // __APPLE__
#endif // _MSC_VER
extern "C" bool RhInitialize(bool isDll);
extern "C" void RhSetRuntimeInitializationCallback(int (*fPtr)());
extern "C" bool RhRegisterOSModule(void * pModule,
void * pvManagedCodeStartRange, uint32_t cbManagedCodeRange,
void * pvUnboxingStubsStartRange, uint32_t cbUnboxingStubsRange,
void ** pClasslibFunctions, uint32_t nClasslibFunctions);
extern "C" void* PalGetModuleHandleFromPointer(void* pointer);
extern "C" void GetRuntimeException();
extern "C" void FailFast();
extern "C" void AppendExceptionStackFrame();
extern "C" void GetSystemArrayEEType();
extern "C" void OnFirstChanceException();
extern "C" void OnUnhandledException();
extern "C" void IDynamicCastableIsInterfaceImplemented();
extern "C" void IDynamicCastableGetInterfaceImplementation();
#ifdef FEATURE_OBJCMARSHAL
extern "C" void ObjectiveCMarshalTryGetTaggedMemory();
extern "C" void ObjectiveCMarshalGetIsTrackedReferenceCallback();
extern "C" void ObjectiveCMarshalGetOnEnteredFinalizerQueueCallback();
extern "C" void ObjectiveCMarshalGetUnhandledExceptionPropagationHandler();
#endif
typedef void(*pfn)();
static const pfn c_classlibFunctions[] = {
&GetRuntimeException,
&FailFast,
nullptr, // &UnhandledExceptionHandler,
&AppendExceptionStackFrame,
nullptr, // &CheckStaticClassConstruction,
&GetSystemArrayEEType,
&OnFirstChanceException,
&OnUnhandledException,
&IDynamicCastableIsInterfaceImplemented,
&IDynamicCastableGetInterfaceImplementation,
#ifdef FEATURE_OBJCMARSHAL
&ObjectiveCMarshalTryGetTaggedMemory,
&ObjectiveCMarshalGetIsTrackedReferenceCallback,
&ObjectiveCMarshalGetOnEnteredFinalizerQueueCallback,
&ObjectiveCMarshalGetUnhandledExceptionPropagationHandler,
#else
nullptr,
nullptr,
nullptr,
nullptr,
#endif
};
#ifndef _countof
#define _countof(_array) (sizeof(_array)/sizeof(_array[0]))
#endif
extern "C" void InitializeModules(void* osModule, void ** modules, int count, void ** pClasslibFunctions, int nClasslibFunctions);
#ifndef NATIVEAOT_DLL
#define NATIVEAOT_ENTRYPOINT __managed__Main
#if defined(_WIN32)
extern "C" int __managed__Main(int argc, wchar_t* argv[]);
#else
extern "C" int __managed__Main(int argc, char* argv[]);
#endif
#else
#define NATIVEAOT_ENTRYPOINT __managed__Startup
extern "C" void __managed__Startup();
#endif // !NATIVEAOT_DLL
static int InitializeRuntime()
{
if (!RhInitialize(
#ifdef NATIVEAOT_DLL
/* isDll */ true
#else
/* isDll */ false
#endif
))
return -1;
void * osModule = PalGetModuleHandleFromPointer((void*)&NATIVEAOT_ENTRYPOINT);
// TODO: pass struct with parameters instead of the large signature of RhRegisterOSModule
if (!RhRegisterOSModule(
osModule,
(void*)&__managedcode_a, (uint32_t)((char *)&__managedcode_z - (char*)&__managedcode_a),
(void*)&__unbox_a, (uint32_t)((char *)&__unbox_z - (char*)&__unbox_a),
(void **)&c_classlibFunctions, _countof(c_classlibFunctions)))
{
return -1;
}
InitializeModules(osModule, __modules_a, (int)((__modules_z - __modules_a)), (void **)&c_classlibFunctions, _countof(c_classlibFunctions));
#ifdef NATIVEAOT_DLL
// Run startup method immediately for a native library
__managed__Startup();
#endif // NATIVEAOT_DLL
return 0;
}
#ifndef NATIVEAOT_DLL
#ifdef ENSURE_PRIMARY_STACK_SIZE
__attribute__((noinline, optnone))
static void EnsureStackSize(int stackSize)
{
volatile char* s = (char*)_alloca(stackSize);
*s = 0;
}
#endif // ENSURE_PRIMARY_STACK_SIZE
#if defined(_WIN32)
int __cdecl wmain(int argc, wchar_t* argv[])
#else
int main(int argc, char* argv[])
#endif
{
#ifdef ENSURE_PRIMARY_STACK_SIZE
// TODO: https://github.com/dotnet/runtimelab/issues/791
EnsureStackSize(1536 * 1024);
#endif
int initval = InitializeRuntime();
if (initval != 0)
return initval;
return __managed__Main(argc, argv);
}
#ifdef HAS_ADDRESS_SANITIZER
// We need to build the bootstrapper as a single object file, to ensure
// the linker can detect that we have ASAN components early enough in the build.
// Include our asan support sources for executable projects here to ensure they
// are compiled into the bootstrapper object.
#include "minipal/asansupport.cpp"
#endif // HAS_ADDRESS_SANITIZER
#endif // !NATIVEAOT_DLL
#ifdef NATIVEAOT_DLL
static struct InitializeRuntimePointerHelper
{
InitializeRuntimePointerHelper()
{
RhSetRuntimeInitializationCallback(&InitializeRuntime);
}
} initializeRuntimePointerHelper;
#endif // NATIVEAOT_DLL