Skip to content

Commit

Permalink
Project: Makes several corrections; there are still more to come
Browse files Browse the repository at this point in the history
- JNIEnv is now correctly propagated throughout the entire backend
- Fixed improper access to JNIEnv* objects through an incorrect thread
- Addresses memory leaks in objects (JNIString, BiosInfo, among others)
- Corrects mishandling of BIOS files in both the frontend and backend
- Fixes interface crashes
- Reduces memory consumption
- Improves the logging system (now the parser can check the syntax of the text format before compilation)
- Enhances security in the code (libfmt)
  • Loading branch information
shadergz committed Jan 23, 2024
1 parent 0d7e74b commit d2a31b2
Show file tree
Hide file tree
Showing 38 changed files with 455 additions and 261 deletions.
2 changes: 2 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion app/src/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ set(COSMIC_MISC_DIR ${CMAKE_SOURCE_DIR}/cpp)
target_sources(cosmic PRIVATE
${COSMIC_DIR}/common/app.cpp
${COSMIC_DIR}/common/logger.cpp
${COSMIC_DIR}/common/except.cpp
${COSMIC_DIR}/cpu/cyclic32.cpp
${COSMIC_DIR}/cpu/verify_features.cpp
${COSMIC_DIR}/engine/ee_core.cpp
Expand Down Expand Up @@ -63,7 +64,7 @@ target_sources(cosmic PRIVATE
${COSMIC_DIR}/vu/vif_fifo.cpp
${COSMIC_DIR}/hle/bios_patch.cpp
${COSMIC_DIR}/hle/group_mgr.cpp
${COSMIC_DIR}/hle/bios_class.cpp
${COSMIC_DIR}/hle/bios_info.cpp
${COSMIC_DIR}/hle/syscall_gate.cpp
${COSMIC_DIR}/fs/bios_loader.cpp
${COSMIC_DIR}/iop/iop_core.cpp
Expand Down
12 changes: 7 additions & 5 deletions app/src/main/cpp/bios_jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,29 @@
extern "C"
JNIEXPORT jobject JNICALL
Java_emu_cosmic_helpers_BiosHelper_00024Companion_addBios(JNIEnv* env, jobject thiz, jobject descriptor, jint position) {
cosmic::hle::BiosInfo info{env};
cosmic::hle::BiosInfo info{};
info.position = position;

auto biosHld{AFileDescriptor_getFd(env, descriptor)};
auto biosMgr{cosmic::app->getBiosMgr()};
auto object{info.createInstance()};
cosmic::i32 find[2]{biosHld, 0};

auto object{info.createInstance()};
if (biosMgr->isAlreadyAdded(find)) {
biosMgr->loadBiosBy(object, find, false);
info.fillInstance(object);
return object;
}
info.chkAndLoad(biosHld);

info.chkAndLoad(biosHld);
biosMgr->storeAndFill(object, std::move(info));

return object;
}
extern "C"
JNIEXPORT jint JNICALL
Java_emu_cosmic_helpers_BiosHelper_00024Companion_setBios(JNIEnv* env, jobject thiz, jint pos) {
auto group{cosmic::app->getBiosMgr()};
cosmic::i32 by[2]{0, pos};

return group->choice(by, true);
}
extern "C"
Expand All @@ -41,7 +41,9 @@ Java_emu_cosmic_helpers_BiosHelper_00024Companion_removeBios(JNIEnv* env, jobjec
}
auto group{cosmic::app->getBiosMgr()};
jint* mangled{env->GetIntArrayElements(posFd, nullptr)};

bool hasRemoved{group->rmFromStorage(mangled)};

env->ReleaseIntArrayElements(posFd, mangled, 0);
return hasRemoved;
}
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/cpp/cosmic/common/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace cosmic {
std::shared_ptr<GlobalLogger> user;
std::shared_ptr<CoreApplication> app;

thread_local java::CosmicEnv cosmicEnv;

CoreApplication::CoreApplication() :
simulated(std::make_shared<console::VirtDevices>()) {

Expand All @@ -26,8 +28,8 @@ namespace cosmic {

user->success("Device {} accepted as the host device, Android API {}", getDeviceName(), apiLevel);

scene = std::make_shared<gpu::ExhibitionEngine>(device->android);
vm = std::make_unique<vm::EmuVm>(device->android, simulated, scene);
scene = std::make_shared<gpu::ExhibitionEngine>();
vm = std::make_unique<vm::EmuVm>(simulated, scene);
}
std::shared_ptr<hle::HleBiosGroup> CoreApplication::getBiosMgr() {
auto group{vm->biosHigh->group};
Expand Down
39 changes: 39 additions & 0 deletions app/src/main/cpp/cosmic/common/except.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include <common/except.h>
#include <common/global.h>

namespace cosmic {
jclass exceptionActivity{};
CosmicException::CosmicException(const std::string& format) :
std::runtime_error(format) {
user->error("{}", format);

msg = cosmicEnv->NewStringUTF(format.c_str());
title = lookupByActivity();
alertUser();
}
jstring CosmicException::lookupByActivity() {
const jclass emulation{cosmicEnv->FindClass("emu/cosmic/EmulationActivity$Companion")};
if (cosmicEnv->IsSameObject(exceptionActivity, emulation)) {
return cosmicEnv->NewStringUTF("Emulation Scene");
}
return cosmicEnv->NewStringUTF("General Exception");
}

void CosmicException::alertUser() {
alert = cosmicEnv->GetMethodID(exceptionActivity,
"displayAlert", "(Ljava/lang/String;Ljava/lang/String;)V");

if (alert) {
cosmicEnv->CallStaticVoidMethod(exceptionActivity, alert, title, msg);
}
cosmicEnv->DeleteLocalRef(title);
cosmicEnv->DeleteLocalRef(msg);
}

void CosmicException::setExceptionClass(jobject super) {
const jclass emuClass{cosmicEnv->FindClass("emu/cosmic/EmulationActivity")};
if (cosmicEnv->IsInstanceOf(super, emuClass)) {
exceptionActivity = cosmicEnv->FindClass("emu/cosmic/EmulationActivity$Companion");
}
}
}
30 changes: 18 additions & 12 deletions app/src/main/cpp/cosmic/common/except.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,30 @@
#include <exception>
#include <string>
#include <fmt/format.h>

#include <jni.h>
namespace cosmic {
class FatalError : public std::runtime_error {
class CosmicException : public std::runtime_error {
protected:
template <typename T, typename... Args>
FatalError(const T& format, Args&&... args)
: std::runtime_error(fmt::format(fmt::runtime(format), args...)) {}
template <typename T, typename... Args>
FatalError(const T& format)
: std::runtime_error(format) {}
CosmicException(const std::string& format);

public:
static void setExceptionClass(jobject super);
private:
jstring lookupByActivity();
void alertUser();

jstring msg{};
jstring title{};
jmethodID alert{};
};

#define DECLARE_EXCEPTION_TYPE(name, tag)\
class name : FatalError {\
class name : public CosmicException {\
public:\
template <typename T, typename... Args>\
name(T& format, Args&&... args) : FatalError("(" tag ") " + std::string(format), args...) {}\
template <typename T, typename... Args>\
name(T& format) : FatalError("(" tag ") " + std::string(format)) {}\
template <typename... Args>\
name(fmt::format_string<Args...> format, Args&&... args) :\
CosmicException("(" tag ") " + fmt::format(format, std::forward<Args>(args)...)) {}\
}

DECLARE_EXCEPTION_TYPE(Cop0Fail, "Cop0");
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/cpp/cosmic/common/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
#include <java/device_handler.h>
#include <common/app.h>
#include <common/logger.h>
#include <java/env.h>
namespace cosmic {
extern std::unique_ptr<java::JvmManager> device;
extern std::shared_ptr<GlobalLogger> user;
extern std::shared_ptr<CoreApplication> app;

extern thread_local java::CosmicEnv cosmicEnv;
}
33 changes: 17 additions & 16 deletions app/src/main/cpp/cosmic/common/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,37 @@ namespace cosmic {
class GlobalLogger {
public:
GlobalLogger();
template <typename T, typename... Args>
void bind(LoggerLevel msgLevel, const T& format, Args&&... args) {
template <typename... Args>
void bind(LoggerLevel msgLevel, fmt::format_string<Args...>& format, Args&&... args) {
for (auto deny : disableLevels) {
if (deny == msgLevel)
if (deny == msgLevel) {
return;
}
}

fmt::format_to(std::back_inserter(out), "{}", prodPrefix(msgLevel));
fmt::format_to(std::back_inserter(out), fmt::runtime(format), args...);
fmt::format_to(std::back_inserter(out), fmt::runtime(format), std::forward<Args>(args)...);
fmt::format_to(std::back_inserter(out), "\n");

__android_log_write(static_cast<android_LogPriority>(msgLevel), tag, out.data());
out.clear();
}

template <typename T, typename... Args>
void success(const T& format, Args&&... args) {
bind(Verbose, format, args...);
template <typename... Args>
void success(fmt::format_string<Args...> format, Args&&... args) {
bind(Verbose, format, std::forward<Args>(args)...);
}
template <typename T, typename... Args>
void info(const T& format, Args&&... args) {
bind(Info, format, args...);
template <typename... Args>
void info(fmt::format_string<Args...> format, Args&&... args) {
bind(Info, format, std::forward<Args>(args)...);
}
template <typename T, typename... Args>
void debug(const T& format, Args&&... args) {
bind(Debug, format, args...);
template <typename... Args>
void debug(fmt::format_string<Args...> format, Args&&... args) {
bind(Debug, format, std::forward<Args>(args)...);
}
template <typename T, typename... Args>
void error(const T& format, Args&&... args) {
bind(Error, format, args...);
template <typename... Args>
void error(fmt::format_string<Args...> format, Args&&... args) {
bind(Error, format, std::forward<Args>(args)...);
}
[[noreturn]] static void cause(const char* fail) {
__android_log_assert(fail, tag, "Assertion with a cause, execution flow has been broken");
Expand Down
12 changes: 8 additions & 4 deletions app/src/main/cpp/cosmic/creeper/ee/mipsiv_opcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,25 @@ namespace cosmic::creeper::ee {
return {};
}

[[maybe_unused]] thread_local std::array<const char*, 3> translatedGPRs{"Unk", "Unk", "Unk"};
thread_local std::array<const char*, 3> translatedGprs{"Unk", "Unk", "Unk"};
InvokeOpInfo MipsIvInterpreter::execBlackBox(u32 opcode) {
InvokeOpInfo decode{};
std::array<u8, 3> operands{};
for (u8 opi{}; opi < 3; opi++) {
operands[opi] = (opcode >> (11 + opi * 5)) & 0x1f;
#if TRANSLATE_REGISTERS
translatedGPRs[opi] = gprsId[operands.at(opi)];
translatedGprs[opi] = gprsId[operands.at(opi)];
#endif
}
#if TRANSLATE_REGISTERS
user->debug("(Mips FETCH) Opcode # {} PC # {} Decoded # 11, 16, 21: {}",
opcode, *cpu.eePc, fmt::join(translatedGPRs, " - "));
user->debug("(Mips FETCH) Opcode # {} pc # {} decoded # 11, 16, 21: {}",
opcode, *cpu->eePc, fmt::join(translatedGprs, " - "));
#endif
decode.ops = Operands(opcode, operands);
decode.execute = [](InvokeOpInfo& err) {
throw AppFail("Invalid or unrecognized opcode {:#x}, parameters: {}", err.ops.inst,
fmt::join(err.ops.gprs, "; "));
};

switch (opcode >> 26) {
case SpecialOpcodes: decode.execute = execSpecial(opcode, decode); break;
Expand Down
10 changes: 5 additions & 5 deletions app/src/main/cpp/cosmic/fs/bios_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace cosmic::fs {
void BiosLoader::triggerBios(hle::BiosInfo& info) {
biosf = info.fd;
}
bool BiosLoader::fetchBiosInfo(JNIEnv* android, hle::BiosInfo& bios) {
bool BiosLoader::fetchBiosInfo(hle::BiosInfo& bios) {
if (!romHeader)
romHeader = std::make_unique<os::MappedMemory<u8>>(hdrSize);

Expand All @@ -36,7 +36,7 @@ namespace cosmic::fs {
}
bios.dataCRC = cpu::check32(romGroup);

fillVersion(android, bios, std::span<char>{BitCast<char*>(romGroup.data()), romGroup.size()});
fillVersion(bios, std::span<char>{BitCast<char*>(romGroup.data()), romGroup.size()});
return true;
}
bool BiosLoader::isABios() {
Expand Down Expand Up @@ -87,7 +87,7 @@ namespace cosmic::fs {
return true;
}

void BiosLoader::fillVersion(JNIEnv* android, hle::BiosInfo& bios, std::span<char> info) {
void BiosLoader::fillVersion(hle::BiosInfo& bios, std::span<char> info) {
using namespace ranges::views;

const std::string month{&info[10], 2};
Expand All @@ -106,8 +106,8 @@ namespace cosmic::fs {
fmt::join(info | drop(8) | take(6), ""))};
// 12345678–123456

bios.dspName = java::JniString(android, biosName);
bios.details = java::JniString(android, biosDetails);
bios.dspName = java::JniString(biosName);
bios.details = java::JniString(biosDetails);
}

}
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/cpp/cosmic/fs/bios_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <memory>

#include <common/types.h>
#include <hle/bios_class.h>
#include <hle/bios_info.h>
#include <os/mapped.h>

namespace cosmic::fs {
Expand All @@ -20,15 +20,15 @@ namespace cosmic::fs {
static constexpr u16 hdrSize{0x3000};
BiosLoader() = default;

bool fetchBiosInfo(JNIEnv* android, hle::BiosInfo& bios);
bool fetchBiosInfo(hle::BiosInfo& bios);
void placeBios(std::span<u8> here);
void triggerBios(hle::BiosInfo& info);
private:
bool isABios();

Ref<RomEntry> getModule(const std::string model);
bool loadVersionInfo(Ref<RomEntry> entry, std::span<u8> info);
void fillVersion(JNIEnv* android, hle::BiosInfo& bios, std::span<char> info);
void fillVersion(hle::BiosInfo& bios, std::span<char> info);

DescriptorRaii biosf{};
std::unique_ptr<os::MappedMemory<u8>> romHeader;
Expand Down
13 changes: 7 additions & 6 deletions app/src/main/cpp/cosmic/gpu/exhibition_engine.cpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
#include <gpu/exhibition_engine.h>
#include <common/except.h>
#include <common/types.h>
#include <common/global.h>
namespace cosmic::gpu {
ExhibitionEngine::ExhibitionEngine(JNIEnv* env) : associated(env) {
ExhibitionEngine::ExhibitionEngine() {
}
ExhibitionEngine::~ExhibitionEngine() {
if (globalSurface)
associated->DeleteGlobalRef(globalSurface);
cosmicEnv->DeleteGlobalRef(globalSurface);
}
void ExhibitionEngine::inheritSurface(jobject surface) {
if (associated->IsSameObject(surface, nullptr))
if (cosmicEnv->IsSameObject(surface, nullptr))
return;
if (globalSurface)
associated->DeleteGlobalRef(globalSurface);
cosmicEnv->DeleteGlobalRef(globalSurface);

globalSurface = associated->NewGlobalRef(surface);
globalSurface = cosmicEnv->NewGlobalRef(surface);
if (!globalSurface) {
throw GpuFail("A Surface is required for us to control and inherit to the screen");
}
window = ANativeWindow_fromSurface(associated, globalSurface);
window = ANativeWindow_fromSurface(*cosmicEnv, globalSurface);
ANativeWindow_acquire(window);
if (scene.notifySurfaceChange)
scene.notifySurfaceChange(scene, surface);
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/cpp/cosmic/gpu/exhibition_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@
namespace cosmic::gpu {
class ExhibitionEngine {
public:
ExhibitionEngine(JNIEnv* env);
ExhibitionEngine();
~ExhibitionEngine();
void inheritSurface(jobject surface);
private:
jobject globalSurface{};
JNIEnv* associated{};
ANativeWindow* window{};

RenderApi graphics{HardwareOpenGL};
Expand Down
Loading

0 comments on commit d2a31b2

Please sign in to comment.