Fix a crash when using DSi mode in debug builds on macOS (#1976)

Store the BIOS images in `NDSArgs`/`DSiArgs` through pointers, not directly

- This will make it easier to keep such objects on the stack
This commit is contained in:
Jesse Talavera 2024-03-13 09:55:20 -04:00 committed by GitHub
parent ea1755bed0
commit 31a7f53282
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 45 additions and 39 deletions

View File

@ -69,6 +69,10 @@ struct JITArgs
bool FastMemory = true; bool FastMemory = true;
}; };
using ARM9BIOSImage = std::array<u8, ARM9BIOSSize>;
using ARM7BIOSImage = std::array<u8, ARM7BIOSSize>;
using DSiBIOSImage = std::array<u8, DSiBIOSSize>;
struct GDBArgs struct GDBArgs
{ {
u16 PortARM7 = 0; u16 PortARM7 = 0;
@ -95,11 +99,11 @@ struct NDSArgs
/// NDS ARM9 BIOS to install. /// NDS ARM9 BIOS to install.
/// Defaults to FreeBIOS, which is not compatible with DSi mode. /// Defaults to FreeBIOS, which is not compatible with DSi mode.
std::array<u8, ARM9BIOSSize> ARM9BIOS = bios_arm9_bin; std::unique_ptr<ARM9BIOSImage> ARM9BIOS = std::make_unique<ARM9BIOSImage>(bios_arm9_bin);
/// NDS ARM7 BIOS to install. /// NDS ARM7 BIOS to install.
/// Defaults to FreeBIOS, which is not compatible with DSi mode. /// Defaults to FreeBIOS, which is not compatible with DSi mode.
std::array<u8, ARM7BIOSSize> ARM7BIOS = bios_arm7_bin; std::unique_ptr<ARM7BIOSImage> ARM7BIOS = std::make_unique<ARM7BIOSImage>(bios_arm7_bin);
/// Firmware image to install. /// Firmware image to install.
/// Defaults to generated NDS firmware. /// Defaults to generated NDS firmware.
@ -131,8 +135,8 @@ struct NDSArgs
/// Contains no virtual methods, so there's no vtable. /// Contains no virtual methods, so there's no vtable.
struct DSiArgs final : public NDSArgs struct DSiArgs final : public NDSArgs
{ {
std::array<u8, DSiBIOSSize> ARM9iBIOS = BrokenBIOS<DSiBIOSSize>; std::unique_ptr<DSiBIOSImage> ARM9iBIOS = std::make_unique<DSiBIOSImage>(BrokenBIOS<DSiBIOSSize>);
std::array<u8, DSiBIOSSize> ARM7iBIOS = BrokenBIOS<DSiBIOSSize>; std::unique_ptr<DSiBIOSImage> ARM7iBIOS = std::make_unique<DSiBIOSImage>(BrokenBIOS<DSiBIOSSize>);
/// NAND image to install. /// NAND image to install.
/// Required, there is no default value. /// Required, there is no default value.

View File

@ -82,8 +82,8 @@ DSi::DSi(DSiArgs&& args) noexcept :
DSi_NDMA(1, 2, *this), DSi_NDMA(1, 2, *this),
DSi_NDMA(1, 3, *this), DSi_NDMA(1, 3, *this),
}, },
ARM7iBIOS(args.ARM7iBIOS), ARM7iBIOS(*args.ARM7iBIOS),
ARM9iBIOS(args.ARM9iBIOS), ARM9iBIOS(*args.ARM9iBIOS),
DSP(*this), DSP(*this),
SDMMC(*this, std::move(args.NANDImage), std::move(args.DSiSDCard)), SDMMC(*this, std::move(args.NANDImage), std::move(args.DSiSDCard)),
SDIO(*this), SDIO(*this),

View File

@ -80,8 +80,8 @@ NDS::NDS() noexcept :
NDSArgs { NDSArgs {
nullptr, nullptr,
nullptr, nullptr,
bios_arm9_bin, std::make_unique<ARM9BIOSImage>(bios_arm9_bin),
bios_arm7_bin, std::make_unique<ARM7BIOSImage>(bios_arm7_bin),
Firmware(0), Firmware(0),
} }
) )
@ -90,8 +90,8 @@ NDS::NDS() noexcept :
NDS::NDS(NDSArgs&& args, int type) noexcept : NDS::NDS(NDSArgs&& args, int type) noexcept :
ConsoleType(type), ConsoleType(type),
ARM7BIOS(args.ARM7BIOS), ARM7BIOS(*args.ARM7BIOS),
ARM9BIOS(args.ARM9BIOS), ARM9BIOS(*args.ARM9BIOS),
ARM7BIOSNative(CRC32(ARM7BIOS.data(), ARM7BIOS.size()) == ARM7BIOSCRC32), ARM7BIOSNative(CRC32(ARM7BIOS.data(), ARM7BIOS.size()) == ARM7BIOSCRC32),
ARM9BIOSNative(CRC32(ARM9BIOS.data(), ARM9BIOS.size()) == ARM9BIOSCRC32), ARM9BIOSNative(CRC32(ARM9BIOS.data(), ARM9BIOS.size()) == ARM9BIOSCRC32),
JIT(*this, args.JIT), JIT(*this, args.JIT),

View File

@ -131,8 +131,8 @@ std::unique_ptr<NDS> EmuThread::CreateConsole(
NDSArgs ndsargs { NDSArgs ndsargs {
std::move(ndscart), std::move(ndscart),
std::move(gbacart), std::move(gbacart),
*arm9bios, std::move(arm9bios),
*arm7bios, std::move(arm7bios),
std::move(*firmware), std::move(*firmware),
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
Config::JIT_Enable ? std::make_optional(jitargs) : std::nullopt, Config::JIT_Enable ? std::make_optional(jitargs) : std::nullopt,
@ -165,8 +165,8 @@ std::unique_ptr<NDS> EmuThread::CreateConsole(
auto sdcard = ROMManager::LoadDSiSDCard(); auto sdcard = ROMManager::LoadDSiSDCard();
DSiArgs args { DSiArgs args {
std::move(ndsargs), std::move(ndsargs),
*arm9ibios, std::move(arm9ibios),
*arm7ibios, std::move(arm7ibios),
std::move(*nand), std::move(*nand),
std::move(sdcard), std::move(sdcard),
Config::DSiFullBIOSBoot, Config::DSiFullBIOSBoot,

View File

@ -512,59 +512,59 @@ void LoadCheats(NDS& nds)
nds.AREngine.SetCodeFile(CheatsOn ? CheatFile : nullptr); nds.AREngine.SetCodeFile(CheatsOn ? CheatFile : nullptr);
} }
std::optional<std::array<u8, ARM9BIOSSize>> LoadARM9BIOS() noexcept std::unique_ptr<ARM9BIOSImage> LoadARM9BIOS() noexcept
{ {
if (!Config::ExternalBIOSEnable) if (!Config::ExternalBIOSEnable)
{ {
return Config::ConsoleType == 0 ? std::make_optional(bios_arm9_bin) : std::nullopt; return Config::ConsoleType == 0 ? std::make_unique<ARM9BIOSImage>(bios_arm9_bin) : nullptr;
} }
if (FileHandle* f = OpenLocalFile(Config::BIOS9Path, Read)) if (FileHandle* f = OpenLocalFile(Config::BIOS9Path, Read))
{ {
std::array<u8, ARM9BIOSSize> bios {}; std::unique_ptr<ARM9BIOSImage> bios = std::make_unique<ARM9BIOSImage>();
FileRewind(f); FileRewind(f);
FileRead(bios.data(), sizeof(bios), 1, f); FileRead(bios->data(), bios->size(), 1, f);
CloseFile(f); CloseFile(f);
Log(Info, "ARM9 BIOS loaded from %s\n", Config::BIOS9Path.c_str()); Log(Info, "ARM9 BIOS loaded from %s\n", Config::BIOS9Path.c_str());
return bios; return bios;
} }
Log(Warn, "ARM9 BIOS not found\n"); Log(Warn, "ARM9 BIOS not found\n");
return std::nullopt; return nullptr;
} }
std::optional<std::array<u8, ARM7BIOSSize>> LoadARM7BIOS() noexcept std::unique_ptr<ARM7BIOSImage> LoadARM7BIOS() noexcept
{ {
if (!Config::ExternalBIOSEnable) if (!Config::ExternalBIOSEnable)
{ {
return Config::ConsoleType == 0 ? std::make_optional(bios_arm7_bin) : std::nullopt; return Config::ConsoleType == 0 ? std::make_unique<ARM7BIOSImage>(bios_arm7_bin) : nullptr;
} }
if (FileHandle* f = OpenLocalFile(Config::BIOS7Path, Read)) if (FileHandle* f = OpenLocalFile(Config::BIOS7Path, Read))
{ {
std::array<u8, ARM7BIOSSize> bios {}; std::unique_ptr<ARM7BIOSImage> bios = std::make_unique<ARM7BIOSImage>();
FileRead(bios.data(), sizeof(bios), 1, f); FileRead(bios->data(), bios->size(), 1, f);
CloseFile(f); CloseFile(f);
Log(Info, "ARM7 BIOS loaded from %s\n", Config::BIOS7Path.c_str()); Log(Info, "ARM7 BIOS loaded from %s\n", Config::BIOS7Path.c_str());
return bios; return bios;
} }
Log(Warn, "ARM7 BIOS not found\n"); Log(Warn, "ARM7 BIOS not found\n");
return std::nullopt; return nullptr;
} }
std::optional<std::array<u8, DSiBIOSSize>> LoadDSiARM9BIOS() noexcept std::unique_ptr<DSiBIOSImage> LoadDSiARM9BIOS() noexcept
{ {
if (FileHandle* f = OpenLocalFile(Config::DSiBIOS9Path, Read)) if (FileHandle* f = OpenLocalFile(Config::DSiBIOS9Path, Read))
{ {
std::array<u8, DSiBIOSSize> bios {}; std::unique_ptr<DSiBIOSImage> bios = std::make_unique<DSiBIOSImage>();
FileRead(bios.data(), sizeof(bios), 1, f); FileRead(bios->data(), bios->size(), 1, f);
CloseFile(f); CloseFile(f);
if (!Config::DSiFullBIOSBoot) if (!Config::DSiFullBIOSBoot)
{ {
// herp // herp
*(u32*)&bios[0] = 0xEAFFFFFE; // overwrites the reset vector *(u32*)bios->data() = 0xEAFFFFFE; // overwrites the reset vector
// TODO!!!! // TODO!!!!
// hax the upper 32K out of the goddamn DSi // hax the upper 32K out of the goddamn DSi
@ -575,21 +575,21 @@ std::optional<std::array<u8, DSiBIOSSize>> LoadDSiARM9BIOS() noexcept
} }
Log(Warn, "ARM9i BIOS not found\n"); Log(Warn, "ARM9i BIOS not found\n");
return std::nullopt; return nullptr;
} }
std::optional<std::array<u8, DSiBIOSSize>> LoadDSiARM7BIOS() noexcept std::unique_ptr<DSiBIOSImage> LoadDSiARM7BIOS() noexcept
{ {
if (FileHandle* f = OpenLocalFile(Config::DSiBIOS7Path, Read)) if (FileHandle* f = OpenLocalFile(Config::DSiBIOS7Path, Read))
{ {
std::array<u8, DSiBIOSSize> bios {}; std::unique_ptr<DSiBIOSImage> bios = std::make_unique<DSiBIOSImage>();
FileRead(bios.data(), sizeof(bios), 1, f); FileRead(bios->data(), bios->size(), 1, f);
CloseFile(f); CloseFile(f);
if (!Config::DSiFullBIOSBoot) if (!Config::DSiFullBIOSBoot)
{ {
// herp // herp
*(u32*)&bios[0] = 0xEAFFFFFE; // overwrites the reset vector *(u32*)bios->data() = 0xEAFFFFFE; // overwrites the reset vector
// TODO!!!! // TODO!!!!
// hax the upper 32K out of the goddamn DSi // hax the upper 32K out of the goddamn DSi
@ -600,7 +600,7 @@ std::optional<std::array<u8, DSiBIOSSize>> LoadDSiARM7BIOS() noexcept
} }
Log(Warn, "ARM7i BIOS not found\n"); Log(Warn, "ARM7i BIOS not found\n");
return std::nullopt; return nullptr;
} }
Firmware GenerateFirmware(int type) noexcept Firmware GenerateFirmware(int type) noexcept

View File

@ -26,6 +26,8 @@
#include <QMainWindow> #include <QMainWindow>
#include "MemConstants.h" #include "MemConstants.h"
#include <Args.h>
#include <optional> #include <optional>
#include <string> #include <string>
#include <memory> #include <memory>
@ -56,11 +58,11 @@ void ClearBackupState();
/// Returns the configured ARM9 BIOS loaded from disk, /// Returns the configured ARM9 BIOS loaded from disk,
/// the FreeBIOS if external BIOS is disabled and we're in NDS mode, /// the FreeBIOS if external BIOS is disabled and we're in NDS mode,
/// or nullopt if loading failed. /// or nullptr if loading failed.
std::optional<std::array<u8, ARM9BIOSSize>> LoadARM9BIOS() noexcept; std::unique_ptr<ARM9BIOSImage> LoadARM9BIOS() noexcept;
std::optional<std::array<u8, ARM7BIOSSize>> LoadARM7BIOS() noexcept; std::unique_ptr<ARM7BIOSImage> LoadARM7BIOS() noexcept;
std::optional<std::array<u8, DSiBIOSSize>> LoadDSiARM9BIOS() noexcept; std::unique_ptr<DSiBIOSImage> LoadDSiARM9BIOS() noexcept;
std::optional<std::array<u8, DSiBIOSSize>> LoadDSiARM7BIOS() noexcept; std::unique_ptr<DSiBIOSImage> LoadDSiARM7BIOS() noexcept;
std::optional<FATStorageArgs> GetDSiSDCardArgs() noexcept; std::optional<FATStorageArgs> GetDSiSDCardArgs() noexcept;
std::optional<FATStorage> LoadDSiSDCard() noexcept; std::optional<FATStorage> LoadDSiSDCard() noexcept;
std::optional<FATStorageArgs> GetDLDISDCardArgs() noexcept; std::optional<FATStorageArgs> GetDLDISDCardArgs() noexcept;