123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- #include "il2cpp-config.h"
- #include "utils/Memory.h"
- #if (IL2CPP_TARGET_JAVASCRIPT || IL2CPP_TARGET_LINUX || IL2CPP_TARGET_QNX && !RUNTIME_TINY) || IL2CPP_TARGET_ANDROID
- #include "os/Image.h"
- #if IL2CPP_TARGET_JAVASCRIPT
- #include <emscripten/emscripten.h>
- #else
- #include <dlfcn.h>
- #endif
- #if IL2CPP_ENABLE_NATIVE_INSTRUCTION_POINTER_EMISSION && (IL2CPP_TARGET_ANDROID || IL2CPP_TARGET_LINUX || IL2CPP_TARGET_QNX)
- #include <elf.h>
- #if __x86_64__ || __aarch64__
- # define ElfW(type) Elf64_##type
- #else
- # define ElfW(type) Elf32_##type
- #endif
- #endif
- #include <cstdio>
- extern char __start_il2cpp;
- extern char __stop_il2cpp;
- namespace il2cpp
- {
- namespace os
- {
- namespace Image
- {
- void* GetImageBase()
- {
- #if IL2CPP_TARGET_JAVASCRIPT
- emscripten_log(EM_LOG_NO_PATHS | EM_LOG_CONSOLE | EM_LOG_ERROR | EM_LOG_JS_STACK, "Warning: libil2cpp/os/Posix/Image.cpp: GetImageBase() called, but dynamic libraries are not available.");
- return NULL;
- #else
- Dl_info info;
- void* const anySymbol = reinterpret_cast<void*>(&GetImageBase);
- if (dladdr(anySymbol, &info))
- return info.dli_fbase;
- else
- return NULL;
- #endif
- }
- static IL2CPP_METHOD_ATTR void NoGeneratedCodeWorkaround()
- {
- }
- void InitializeManagedSection()
- {
- NoGeneratedCodeWorkaround();
- // Since the native linker creates the __start_il2cpp and __stop_il2cpp
- // globals, we can only use them when IL2CPP_PLATFORM_SUPPORTS_CUSTOM_SECTIONS
- // is defined. Otherwise, they will not exist, and this usage of them will cause
- // an unresolved external error in the native linker. This should be the only
- // place in runtime code that IL2CPP_PLATFORM_SUPPORTS_CUSTOM_SECTIONS is used.
- #if IL2CPP_PLATFORM_SUPPORTS_CUSTOM_SECTIONS
- SetManagedSectionStartAndEnd(&__start_il2cpp, &__stop_il2cpp);
- #endif
- }
- void Initialize()
- {
- InitializeManagedSection();
- }
- #if IL2CPP_ENABLE_NATIVE_INSTRUCTION_POINTER_EMISSION
- #if IL2CPP_TARGET_ANDROID || IL2CPP_TARGET_LINUX
- char* GetELFImageBuildID()
- {
- size_t imageBase = (size_t)GetImageBase();
- ElfW(Ehdr) * ehdr = (ElfW(Ehdr) *)imageBase;
- ElfW(Phdr) * phdr = (ElfW(Phdr) *)(imageBase + ehdr->e_phoff);
- // Bug fix requires the lowest PT_LOAD address, not the lowest PT_LOAD offset
- // https://unix.stackexchange.com/questions/669237/how-to-tell-whether-the-p-vaddr-in-elf-program-header-is-the-real-memory-address
- ElfW(Addr) pt_load_low = SIZE_MAX; // Set the max value, if it's not changed, assume a zero offset
- for (int i = 0; i < ehdr->e_phnum; i++)
- {
- if (phdr[i].p_type == PT_LOAD && phdr[i].p_vaddr < pt_load_low)
- {
- pt_load_low = phdr[i].p_vaddr;
- }
- }
- pt_load_low = (pt_load_low == SIZE_MAX) ? 0 : pt_load_low;
- for (int i = 0; i < ehdr->e_phnum; i++)
- {
- if (phdr[i].p_type == PT_NOTE)
- {
- size_t nhdr_ptr = phdr[i].p_vaddr + imageBase - pt_load_low;
- size_t nhdr_end = nhdr_ptr + phdr[i].p_memsz;
- int j = 0;
- while (nhdr_ptr < nhdr_end)
- {
- ElfW(Nhdr) * nhdr = (ElfW(Nhdr) *)nhdr_ptr;
- if (nhdr->n_type == NT_GNU_BUILD_ID)
- {
- uint8_t* image_build_id = (uint8_t *)((size_t)nhdr + sizeof(ElfW(Nhdr)) + nhdr->n_namesz);
- char* build_id = static_cast<char*>(IL2CPP_MALLOC(41));
- for (int j = 0; j < nhdr->n_descsz; j++)
- {
- snprintf(&build_id[j * 2], 3, "%02x", image_build_id[j]);
- }
- return build_id;
- }
- nhdr_ptr += sizeof(ElfW(Nhdr)) + nhdr->n_descsz + nhdr->n_namesz;
- }
- break;
- }
- }
- return NULL;
- }
- #endif
- char* GetImageUUID()
- {
- #if IL2CPP_TARGET_ANDROID || IL2CPP_TARGET_LINUX
- return GetELFImageBuildID();
- #else
- #error Implement GetImageUUID for this platform
- #endif
- }
- char* GetImageName()
- {
- #if IL2CPP_TARGET_ANDROID || IL2CPP_TARGET_LINUX
- Dl_info info;
- void* const anySymbol = reinterpret_cast<void*>(&GetImageBase);
- if (dladdr(anySymbol, &info))
- {
- size_t nameSize = strlen(info.dli_fname);
- char* imageName = (char*)IL2CPP_MALLOC(nameSize);
- strncpy(imageName, info.dli_fname, nameSize);
- return imageName;
- }
- else
- return NULL;
- #else
- #error Implement GetImageName for this platform
- #endif
- }
- #endif
- }
- }
- }
- #endif
|