Files
RedHotRoast-ios/HybridCLRData/LocalIl2CppData-OSXEditor/il2cpp/libil2cpp/os/OSX/Image.cpp
T

184 lines
5.3 KiB
C++
Raw Normal View History

2026-07-17 14:03:00 +08:00
#include "il2cpp-config.h"
#include "utils/Memory.h"
#if IL2CPP_TARGET_DARWIN
#include "os/Image.h"
#include <mach-o/dyld.h>
#include <mach-o/getsect.h>
#include <mach-o/ldsyms.h>
#include <dlfcn.h>
#include <vector>
namespace il2cpp
{
namespace os
{
namespace Image
{
static void* s_ImageBase = NULL;
static int GetImageIndex()
{
// OSX/iOS uses ASLR (address space layout randomization), so
// find where the image is loaded. This is usually zero in the
// debugger for an executable, but non-zero when a debugger is not
// present.
std::vector<char> path;
uint32_t size = 0;
int error = _NSGetExecutablePath(NULL, &size);
IL2CPP_ASSERT(error == -1);
if (error != -1)
return -1;
path.resize(size);
error = _NSGetExecutablePath(&path[0], &size);
IL2CPP_ASSERT(error == 0);
if (error != 0)
return -1;
int gameAssemblyImageIndex = -1;
int executableImageIndex = -1;
int numberOfImages = _dyld_image_count();
for (uint32_t i = 0; i < numberOfImages; i++)
{
const char* imageName = _dyld_get_image_name(i);
if (strstr(imageName, "GameAssembly.dylib") != NULL || strstr(imageName, "UnityFramework.framework/UnityFramework") != NULL)
{
gameAssemblyImageIndex = i;
break;
}
else if (strstr(imageName, &path[0]) != NULL)
{
executableImageIndex = i;
}
}
if (gameAssemblyImageIndex != -1)
return gameAssemblyImageIndex;
else if (executableImageIndex != -1)
return executableImageIndex;
return -1;
}
static void InitializeImageBase()
{
// Gets info about the image containing InitializeImageBase
Dl_info info;
memset(&info, 0, sizeof(info));
int error = dladdr((void*)&InitializeImageBase, &info);
IL2CPP_ASSERT(error != 0);
if (error == 0)
return;
s_ImageBase = info.dli_fbase;
}
#if IL2CPP_SIZEOF_VOID_P == 8
typedef struct mach_header_64 arch_header_t;
#else
typedef struct mach_header arch_header_t;
#endif
static uint8_t* SectionDataFor(int imageIndex, unsigned long* size)
{
return getsectiondata((const arch_header_t*)_dyld_get_image_header(imageIndex), "__TEXT", IL2CPP_BINARY_SECTION_NAME, size);
}
static void InitializeManagedSection()
{
int imageIndex = GetImageIndex();
if (imageIndex == -1)
return;
unsigned long sectionSize = 0;
uint8_t* sectionData = SectionDataFor(imageIndex, &sectionSize);
if (sectionData == NULL)
{
// We did not find the managed section of the binary in the image where we
// think it should live. Maybe Unity is being embedded in another application.
// Let's search all of the images and find the first one that has our section
// in the binary.
//
// This won't work correctly if more than one Unity binary is embedded, but we
// don't support that case yet.
int numberOfImages = _dyld_image_count();
imageIndex = 0;
while (sectionData == NULL && imageIndex < numberOfImages)
{
sectionData = SectionDataFor(imageIndex, &sectionSize);
imageIndex++;
}
}
if (sectionData != NULL)
{
void* start = (void*)sectionData;
void* end = (uint8_t*)start + sectionSize;
SetManagedSectionStartAndEnd(start, end);
}
}
void Initialize()
{
InitializeImageBase();
InitializeManagedSection();
}
void* GetImageBase()
{
return s_ImageBase;
}
#if IL2CPP_ENABLE_NATIVE_INSTRUCTION_POINTER_EMISSION
char* GetImageUUID()
{
int imageIndex = GetImageIndex();
if (imageIndex == -1)
return NULL;
const struct mach_header_64* header = (mach_header_64*)_dyld_get_image_header(imageIndex);
const uint8_t *command = (const uint8_t *)(header + 1);
for (uint32_t idx = 0; idx < header->ncmds; ++idx)
{
if (((const struct load_command *)command)->cmd == LC_UUID)
{
command += sizeof(struct load_command);
char* uuid = static_cast<char*>(IL2CPP_MALLOC(33));
snprintf(uuid, 33, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
command[0], command[1], command[2], command[3],
command[4], command[5], command[6], command[7],
command[8], command[9], command[10], command[11],
command[12], command[13], command[14], command[15]);
return uuid;
}
else
{
command += ((const struct load_command *)command)->cmdsize;
}
}
return NULL;
}
char* GetImageName()
{
const char* imageName = _dyld_get_image_name(GetImageIndex());
size_t nameSize = strlen(imageName);
char* imageNameCopy = (char*)IL2CPP_MALLOC(nameSize + 1);
strncpy(imageNameCopy, imageName, nameSize + 1);
return imageNameCopy;
}
#endif
}
}
}
#endif