mirror of
https://github.com/geode-sdk/geode.git
synced 2025-02-17 00:30:26 -05:00
extract gnustl empty string from CCString
no more hardcoded addresses in android!!
This commit is contained in:
parent
925e72535d
commit
806499c8f4
4 changed files with 57 additions and 15 deletions
6
loader/include/Geode/cocos/cocoa/CCString.h
vendored
6
loader/include/Geode/cocos/cocoa/CCString.h
vendored
|
@ -51,7 +51,13 @@ public:
|
|||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
#ifndef GEODE_IS_ANDROID
|
||||
inline CCString() : m_sString("") {}
|
||||
#else
|
||||
// Make sure its imported because of gd::string stuff,
|
||||
// check android/main.cpp for more info
|
||||
CCString();
|
||||
#endif
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
|
|
|
@ -1,23 +1,15 @@
|
|||
#include <Geode/c++stl/gdstdlib.hpp>
|
||||
#include "../../c++stl/string-impl.hpp"
|
||||
#include "internalString.hpp"
|
||||
|
||||
#if defined(GEODE_IS_ANDROID32)
|
||||
|
||||
static auto constexpr NEW_SYM = "_Znwj";
|
||||
static constexpr uintptr_t STRING_EMPTY = 0xaa1c48 - 0x10000 - 0xc; // the internal struct size
|
||||
|
||||
#elif defined(GEODE_IS_ANDROID64)
|
||||
|
||||
static auto constexpr NEW_SYM = "_Znwm";
|
||||
static constexpr uintptr_t STRING_EMPTY = 0x12d8568 - 0x100000 - 0x18; // the internal struct size
|
||||
|
||||
#endif
|
||||
|
||||
static auto constexpr DELETE_SYM = "_ZdlPv";
|
||||
|
||||
// 2.2 addition
|
||||
// zmx please fix this
|
||||
|
||||
static void* getLibHandle() {
|
||||
static void* handle = dlopen("libcocos2dcpp.so", RTLD_LAZY | RTLD_NOLOAD);
|
||||
return handle;
|
||||
|
@ -54,13 +46,41 @@ void gd::operatorDelete(void* ptr) {
|
|||
return fnPtr(ptr);
|
||||
}
|
||||
|
||||
namespace geode::stl {
|
||||
static inline auto emptyInternalString() {
|
||||
return reinterpret_cast<StringData::Internal*>(
|
||||
geode::base::get() + STRING_EMPTY + sizeof(StringData::Internal)
|
||||
);
|
||||
}
|
||||
using namespace geode::stl;
|
||||
|
||||
void* g_ourInternalString = nullptr;
|
||||
|
||||
static auto& emptyInternalString() {
|
||||
static StringData::Internal* ptr = [] {
|
||||
StringData::Internal internal;
|
||||
internal.m_size = 0;
|
||||
internal.m_capacity = 0;
|
||||
// make our empty internal string different from gd's
|
||||
internal.m_refcount = 1'000'000'000;
|
||||
|
||||
// use char* so we can do easy pointer arithmetic with it
|
||||
auto* buffer = static_cast<char*>(gd::operatorNew(sizeof(internal) + 1));
|
||||
std::memcpy(buffer, &internal, sizeof(internal));
|
||||
buffer[sizeof(internal)] = 0;
|
||||
g_ourInternalString = reinterpret_cast<void*>(buffer);
|
||||
return reinterpret_cast<StringData::Internal*>(buffer + sizeof(internal));
|
||||
}();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void setEmptyInternalString(gd::string* str) {
|
||||
auto* internal = *reinterpret_cast<StringData::Internal**>(str);
|
||||
// make sure its empty
|
||||
if (internal[-1].m_size == 0 && internal[-1].m_capacity == 0 && internal[-1].m_refcount == 0) {
|
||||
emptyInternalString() = internal;
|
||||
if (g_ourInternalString != nullptr) {
|
||||
gd::operatorDelete(g_ourInternalString);
|
||||
g_ourInternalString = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace geode::stl {
|
||||
void StringImpl::setEmpty() {
|
||||
data.m_data = emptyInternalString();
|
||||
}
|
||||
|
|
5
loader/src/platform/android/internalString.hpp
Normal file
5
loader/src/platform/android/internalString.hpp
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/c++stl/string.hpp>
|
||||
|
||||
void setEmptyInternalString(gd::string* str);
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
#include "../load.hpp"
|
||||
#include <jni.h>
|
||||
#include "internalString.hpp"
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
// idk where to put this
|
||||
#include <EGL/egl.h>
|
||||
|
@ -21,6 +24,14 @@ extern "C" [[gnu::visibility("default")]] jint JNI_OnLoad(JavaVM* vm, void* rese
|
|||
geode::log::warn("Failed to remove update directory: {}", ec.message());
|
||||
}
|
||||
|
||||
{
|
||||
// Epic hack: get the empty internal string from CCString
|
||||
// avoid ::create as to not call autorelease
|
||||
auto* cc = new CCString();
|
||||
setEmptyInternalString(&cc->m_sString);
|
||||
delete cc;
|
||||
}
|
||||
|
||||
geodeEntry(nullptr);
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue