#include <algorithm>
#include <cstdint>
#include <dlfcn.h>
#include <initializer_list>
#include <mach-o/dyld.h>
#include <mach-o/getsect.h>
#include <cassert>
extern "C" {
unsigned long _CJMetadataSize;
uintptr_t _CJMetadataStart;
unsigned long _CJSDKVersionSize;
uintptr_t _CJSDKVersion;
unsigned long _CJMethodInfoSize;
uintptr_t _CJMethodInfo;
unsigned long _CJGlobalInitFuncSize;
uintptr_t _CJGlobalInitFunc;
unsigned long _CJStringPoolDictSize;
uintptr_t _CJStringPoolDict;
unsigned long _CJStringPoolSize;
uintptr_t _CJStringPool;
unsigned long _CJStackMapSize;
uintptr_t _CJStackMap;
unsigned long _CJGCTibSize;
uintptr_t _CJGCTib;
unsigned long _CJGCRootsSize;
uintptr_t _CJGCRoots;
unsigned long _CJTypeTemplateSize;
uintptr_t _CJTypeTemplate;
unsigned long _CJTypeInfoSize;
uintptr_t _CJTypeInfo;
unsigned long _CJTypeFieldsSize;
uintptr_t _CJTypeFields;
unsigned long _CJMTableSize;
uintptr_t _CJMTable;
unsigned long _CJInnerTypeExtensionsSize;
uintptr_t _CJInnerTypeExtensions;
unsigned long _CJOuterTypeExtensionsSize;
uintptr_t _CJOuterTypeExtensions;
unsigned long _CJStaticGITableSize;
uintptr_t _CJStaticGITable;
unsigned long _CJGCFlagsSize;
uintptr_t _CJGCFlags;
unsigned long _CJGCReflectPkgInfoSize;
uintptr_t _CJReflectPkgInfo;
unsigned long _CJReflectGVSize;
uintptr_t _CJReflectGV;
unsigned long _CJReflectGISize;
uintptr_t _CJReflectGI;
unsigned long _CJTypeExtSize;
uintptr_t _CJTypeExt;
int _CJMetaDataSize;
unsigned long* g_runtimeStaticStart;
unsigned long* g_runtimeStaticEnd;
static void InitSectionInformation(const struct mach_header_64* mhp)
{
_CJMetadataStart =
reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJMETAHEADER", "__cjmetaheader", &_CJMetadataSize));
_CJSDKVersion =
reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjsdkversion", &_CJSDKVersionSize));
_CJMethodInfo =
reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjmethodinfo", &_CJMethodInfoSize));
_CJGlobalInitFunc =
reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjglobalFunc", &_CJGlobalInitFuncSize));
_CJStringPoolDict =
reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjstrpooldict", &_CJStringPoolDictSize));
_CJStringPool =
reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjstrpool", &_CJStringPoolSize));
_CJStackMap = reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjstackmap", &_CJStackMapSize));
_CJGCTib = reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjgctib", &_CJGCTibSize));
_CJGCRoots = reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjgcroots", &_CJGCRootsSize));
_CJTypeTemplate =
reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjtemplate", &_CJTypeTemplateSize));
_CJTypeInfo = reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjtypeinfo", &_CJTypeInfoSize));
_CJTypeFields =
reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cj_fields", &_CJTypeFieldsSize));
_CJMTable = reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjmtable", &_CJMTableSize));
_CJInnerTypeExtensions = reinterpret_cast<uintptr_t>(
getsectiondata(mhp, "__CJ_METADATA", "__cjinnerty_eds", &_CJInnerTypeExtensionsSize));
_CJOuterTypeExtensions = reinterpret_cast<uintptr_t>(
getsectiondata(mhp, "__CJ_METADATA", "__cjouterty_eds", &_CJOuterTypeExtensionsSize));
_CJStaticGITable =
reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjstatic_gi", &_CJStaticGITableSize));
_CJGCFlags = reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjgcflags", &_CJGCFlagsSize));
_CJReflectPkgInfo =
reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjref_pkginfo", &_CJGCReflectPkgInfoSize));
_CJReflectGV = reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjref_gv", &_CJReflectGVSize));
_CJReflectGI = reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjref_gi", &_CJReflectGISize));
_CJTypeExt = reinterpret_cast<uintptr_t>(getsectiondata(mhp, "__CJ_METADATA", "__cjtype_ext", &_CJTypeExtSize));
unsigned long _CJRuntimeTextSize;
unsigned long _CJRuntimeText =
reinterpret_cast<unsigned long>(getsectiondata(mhp, "__TEXT", "__cjrt_text", &_CJRuntimeTextSize));
g_runtimeStaticStart = reinterpret_cast<unsigned long*>(_CJRuntimeText);
g_runtimeStaticEnd = reinterpret_cast<unsigned long*>(_CJRuntimeText + _CJRuntimeTextSize);
}
__attribute__((constructor)) void InitData()
{
Dl_info info;
const void* addr = reinterpret_cast<const void*>(&InitSectionInformation);
dladdr(addr, &info);
const char* dylib_name = info.dli_fname;
int count = _dyld_image_count();
int index = -1;
for (int i = 0; i < count; ++i) {
const char* name = _dyld_get_image_name(i);
if (strcmp(name, dylib_name) == 0) {
index = i;
break;
}
}
assert(index != -1);
const struct mach_header_64* mhp = reinterpret_cast<const struct mach_header_64*>(_dyld_get_image_header(index));
InitSectionInformation(mhp);
std::initializer_list<uintptr_t> addrs{
_CJSDKVersion, reinterpret_cast<uintptr_t>(_CJSDKVersion + _CJSDKVersionSize),
_CJMethodInfo, reinterpret_cast<uintptr_t>(_CJMethodInfo + _CJMethodInfoSize),
_CJGlobalInitFunc, reinterpret_cast<uintptr_t>(_CJGlobalInitFunc + _CJGlobalInitFuncSize),
_CJStringPoolDict, reinterpret_cast<uintptr_t>(_CJStringPoolDict + _CJStringPoolDictSize),
_CJStringPool, reinterpret_cast<uintptr_t>(_CJStringPool + _CJStringPoolSize),
_CJStackMap, reinterpret_cast<uintptr_t>(_CJStackMap + _CJStackMapSize),
_CJGCTib, reinterpret_cast<uintptr_t>(_CJGCTib + _CJGCTibSize),
_CJGCRoots, reinterpret_cast<uintptr_t>(_CJGCRoots + _CJGCRootsSize),
_CJTypeTemplate, reinterpret_cast<uintptr_t>(_CJTypeTemplate + _CJTypeTemplateSize),
_CJTypeInfo, reinterpret_cast<uintptr_t>(_CJTypeInfo + _CJTypeInfoSize),
_CJTypeFields, reinterpret_cast<uintptr_t>(_CJTypeFields + _CJTypeFieldsSize),
_CJMTable, reinterpret_cast<uintptr_t>(_CJMTable + _CJMTableSize),
_CJInnerTypeExtensions, reinterpret_cast<uintptr_t>(_CJInnerTypeExtensions + _CJInnerTypeExtensionsSize),
_CJOuterTypeExtensions, reinterpret_cast<uintptr_t>(_CJOuterTypeExtensions + _CJOuterTypeExtensionsSize),
_CJStaticGITable, reinterpret_cast<uintptr_t>(_CJStaticGITable + _CJStaticGITableSize),
_CJGCFlags, reinterpret_cast<uintptr_t>(_CJGCFlags + _CJGCFlagsSize),
_CJReflectPkgInfo, reinterpret_cast<uintptr_t>(_CJReflectPkgInfo + _CJGCReflectPkgInfoSize),
_CJReflectGV, reinterpret_cast<uintptr_t>(_CJReflectGV + _CJReflectGVSize),
_CJReflectGI, reinterpret_cast<uintptr_t>(_CJReflectGI + _CJReflectGISize),
_CJTypeExt, reinterpret_cast<uintptr_t>(_CJTypeExt + _CJTypeExtSize),
};
uintptr_t start = std::min<uintptr_t>(addrs);
uintptr_t end = std::max<uintptr_t>(addrs);
_CJMetaDataSize = end - start;
};
}