1#define WIN32_LEAN_AND_MEAN
2#include <stdio.h>
3#include <windows.h>
4#include <stdlib.h>
5#include "objcrt.h"
6
7// Boundary symbols for metadata sections
8
9#pragma section(".objc_module_info$A",long,read,write)
10#pragma data_seg(".objc_module_info$A")
11static uintptr_t __objc_modStart = 0;
12#pragma section(".objc_module_info$C",long,read,write)
13#pragma data_seg(".objc_module_info$C")
14static uintptr_t __objc_modEnd = 0;
15
16#pragma section(".objc_protocol$A",long,read,write)
17#pragma data_seg(".objc_protocol$A")
18static uintptr_t __objc_protoStart = 0;
19#pragma section(".objc_protocol$C",long,read,write)
20#pragma data_seg(".objc_protocol$C")
21static uintptr_t __objc_protoEnd = 0;
22
23#pragma section(".objc_image_info$A",long,read,write)
24#pragma data_seg(".objc_image_info$A")
25static uintptr_t __objc_iiStart = 0;
26#pragma section(".objc_image_info$C",long,read,write)
27#pragma data_seg(".objc_image_info$C")
28static uintptr_t __objc_iiEnd = 0;
29
30#pragma section(".objc_message_refs$A",long,read,write)
31#pragma data_seg(".objc_message_refs$A")
32static uintptr_t __objc_selrefsStart = 0;
33#pragma section(".objc_message_refs$C",long,read,write)
34#pragma data_seg(".objc_message_refs$C")
35static uintptr_t __objc_selrefsEnd = 0;
36
37#pragma section(".objc_class_refs$A",long,read,write)
38#pragma data_seg(".objc_class_refs$A")
39static uintptr_t __objc_clsrefsStart = 0;
40#pragma section(".objc_class_refs$C",long,read,write)
41#pragma data_seg(".objc_class_refs$C")
42static uintptr_t __objc_clsrefsEnd = 0;
43
44#pragma data_seg()
45
46// Merge all metadata into .data
47// fixme order these by usage?
48#pragma comment(linker, "/MERGE:.objc_module_info=.data")
49#pragma comment(linker, "/MERGE:.objc_protocol=.data")
50#pragma comment(linker, "/MERGE:.objc_image_info=.data")
51#pragma comment(linker, "/MERGE:.objc_message_refs=.data")
52#pragma comment(linker, "/MERGE:.objc_class_refs=.data")
53
54
55// Image initializers
56
57static void *__hinfo = NULL;  // cookie from runtime
58extern IMAGE_DOS_HEADER __ImageBase;  // this image's header
59
60static int __objc_init(void)
61{
62    objc_sections sections = {
63        5,
64        &__objc_modStart, &__objc_modEnd,
65        &__objc_protoStart, &__objc_protoEnd,
66        &__objc_iiStart, &__objc_iiEnd,
67        &__objc_selrefsStart, &__objc_selrefsEnd,
68        &__objc_clsrefsStart, &__objc_clsrefsEnd,
69    };
70    __hinfo = _objc_init_image((HMODULE)&__ImageBase, &sections);
71    return 0;
72}
73
74static void __objc_unload(void)
75{
76    _objc_unload_image((HMODULE)&__ImageBase, __hinfo);
77}
78
79static int __objc_load(void)
80{
81    _objc_load_image((HMODULE)&__ImageBase, __hinfo);
82    return 0;
83}
84
85// run _objc_init_image ASAP
86#pragma section(".CRT$XIAA",long,read,write)
87#pragma data_seg(".CRT$XIAA")
88static void *__objc_init_fn = &__objc_init;
89
90// run _objc_load_image (+load methods) after all other initializers;
91// otherwise constant NSStrings are not initialized yet
92#pragma section(".CRT$XCUO",long,read,write)
93#pragma data_seg(".CRT$XCUO")
94static void *__objc_load_fn = &__objc_load;
95
96// _objc_unload_image is called by atexit(), not by an image terminator
97
98#pragma data_seg()
99