[Scummvm-git-logs] scummvm master -> 3a6a355c20c12f77a57cd85a278c36c9efb45254
mikrosk
noreply at scummvm.org
Sun Apr 26 16:05:40 UTC 2026
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
e09b9dfad6 PLUGINS: Provide __cxa_atexit & __cxa_finalize
83ebddc748 BACKENDS: ATARI: Implement plugins
b02c2de70f BACKENDS: ATARI: Match other platforms' plugin.ld ctors/dtors layout
3a6a355c20 BACKENDS: SDL: Add plugins support for Atari/FireBee
Commit: e09b9dfad6f686141120bd8ada4837459dd407bc
https://github.com/scummvm/scummvm/commit/e09b9dfad6f686141120bd8ada4837459dd407bc
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2026-04-27T02:05:36+10:00
Commit Message:
PLUGINS: Provide __cxa_atexit & __cxa_finalize
Atari's mintelf platform has ELF support but its libc does not provide
__cxa_atexit / __cxa_finalize, so -fuse-cxa-atexit cannot be used out of
the box. Add a minimal shim (plus a __dso_handle definition for the main
executable) so plugins can register and finalize their function-local
static destructors per DSO on unload.
Note: earlier version ran __cxa_finalize from the host via
findSymbol("__dso_handle"). That works as long as exactly one
__dso_handle ends up in the plugin's symtab (the plugin's own).
When the main binary also defines __dso_handle (so the host's
function-local statics can link with -fuse-cxa-atexit), it breaks: the
plugin link uses --just-symbols=<main binary> and imports that as a
second __dso_handle, and findSymbol can then return the host-imported
one instead of the plugin's own. The two addresses differ, so
__cxa_finalize matches nothing.
The plugin-side helper avoids the ambiguity on every target by using
whichever __dso_handle the plugin's own code already resolved against --
the same one embedded in its __cxa_atexit calls. (PSP2's plugin runtime
has always called __cxa_finalize from inside the plugin for the same
reason; see backends/plugins/psp2/plugin.cpp.)
Changed paths:
A backends/plugins/elf/cxa-atexit.cpp
backends/module.mk
backends/plugins/elf/elf-provider.cpp
backends/plugins/elf/elf-provider.h
backends/plugins/elf/plugin.syms
base/plugins.h
diff --git a/backends/module.mk b/backends/module.mk
index f64a8112bcf..e6b2daa873a 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -170,6 +170,7 @@ endif
ifdef USE_ELF_LOADER
MODULE_OBJS += \
plugins/elf/arm-loader.o \
+ plugins/elf/cxa-atexit.o \
plugins/elf/elf-loader.o \
plugins/elf/elf-provider.o \
plugins/elf/memory-manager.o \
diff --git a/backends/plugins/elf/cxa-atexit.cpp b/backends/plugins/elf/cxa-atexit.cpp
new file mode 100644
index 00000000000..4865a691962
--- /dev/null
+++ b/backends/plugins/elf/cxa-atexit.cpp
@@ -0,0 +1,116 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(ELF_LOADER_CXA_ATEXIT) && defined(__MINT__)
+
+#include "common/debug.h"
+#include "common/textconsole.h"
+
+#include <stdlib.h>
+
+/**
+ * Minimal __cxa_atexit / __cxa_finalize for targets whose libc lacks them
+ * (e.g. mintlib on Atari).
+ *
+ * With -fuse-cxa-atexit, GCC registers function-local static destructors via
+ * __cxa_atexit(&dtor, &obj, &__dso_handle). The third argument tags which
+ * DSO owns the registration. On plugin unload, ELFPlugin::unloadPlugin()
+ * calls __cxa_finalize(&plugin_dso_handle) to run and remove only that
+ * plugin's entries -- preventing dangling atexit pointers into freed memory.
+ *
+ * See also the detailed comment in elf-provider.cpp.
+ */
+
+#define CXA_ATEXIT_MAX 256
+
+struct CxaAtexitEntry {
+ void (*destructor)(void *);
+ void *arg;
+ void *dso_handle;
+};
+
+static CxaAtexitEntry s_entries[CXA_ATEXIT_MAX];
+static int s_count;
+
+extern "C" {
+
+// GCC with -fuse-cxa-atexit emits references to __dso_handle in every TU that
+// has function-local statics with non-trivial destructors. It is normally
+// provided by crtbegin.o; on targets whose startup files don't supply one,
+// define it here for the main executable. Its address uniquely identifies
+// the main DSO.
+void *__dso_handle = &__dso_handle;
+
+int __cxa_atexit(void (*destructor)(void *), void *arg, void *dso_handle) {
+ if (s_count >= CXA_ATEXIT_MAX) {
+ warning("elfloader: cxa-atexit table full (max=%d), dropping dtor %p dso=%p",
+ CXA_ATEXIT_MAX, (void *)destructor, dso_handle);
+ return -1;
+ }
+
+ s_entries[s_count].destructor = destructor;
+ s_entries[s_count].arg = arg;
+ s_entries[s_count].dso_handle = dso_handle;
+ s_count++;
+
+ debug(2, "elfloader: cxa-atexit register[%d] dtor=%p arg=%p dso=%p",
+ s_count - 1, (void *)destructor, arg, dso_handle);
+ return 0;
+}
+
+void __cxa_finalize(void *dso_handle) {
+ int ran = 0, matched = 0;
+
+ for (int i = s_count - 1; i >= 0; i--) {
+ if (s_entries[i].destructor == NULL)
+ continue;
+
+ if (dso_handle == NULL || s_entries[i].dso_handle == dso_handle) {
+ matched++;
+ void (*f)(void *) = s_entries[i].destructor;
+ void *a = s_entries[i].arg;
+ s_entries[i].destructor = NULL; // mark before calling (re-entrancy)
+ f(a);
+ ran++;
+ }
+ }
+
+ debug(2, "elfloader: cxa-atexit finalize(dso=%p): matched=%d ran=%d (total registered=%d)",
+ dso_handle, matched, ran, s_count);
+}
+
+} // extern "C"
+
+// Ensure the main binary's own statics are finalized at process exit.
+// Registered early via constructor so it runs late in the atexit sequence.
+static void cxa_finalize_all() {
+ __cxa_finalize(NULL);
+}
+
+static void register_cxa_cleanup() __attribute__((constructor, used));
+static void register_cxa_cleanup() {
+ // debug() / stdio aren't ready at constructor time, so no log here.
+ atexit(cxa_finalize_all);
+}
+
+#endif // defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(ELF_LOADER_CXA_ATEXIT) && defined(__MINT__)
diff --git a/backends/plugins/elf/elf-provider.cpp b/backends/plugins/elf/elf-provider.cpp
index 2c491c473a8..b579588ae05 100644
--- a/backends/plugins/elf/elf-provider.cpp
+++ b/backends/plugins/elf/elf-provider.cpp
@@ -23,10 +23,6 @@
#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER)
-#ifdef ELF_LOADER_CXA_ATEXIT
-#include <cxxabi.h>
-#endif
-
#include "backends/plugins/elf/elf-provider.h"
#include "backends/plugins/dynamic-plugin.h"
#include "backends/plugins/elf/memory-manager.h"
@@ -57,10 +53,13 @@
* __cxa_finalize(&__dso_handle) to call all destructors of only that DSO.
*
* Prerequisites:
- * - The used libc needs to support __cxa_atexit
+ * - The used libc needs to support __cxa_atexit (or the target must supply it;
+ * see backends/plugins/elf/cxa-atexit.cpp)
* - -fuse-cxa-atexit in CXXFLAGS
- * - Every plugin needs its own hidden __dso_handle symbol
- * This is automatically done via REGISTER_PLUGIN_DYNAMIC, see base/plugins.h
+ * - Every plugin needs its own hidden __dso_handle symbol, and an exported
+ * PLUGIN_finalize() helper that calls __cxa_finalize(&__dso_handle) from
+ * inside the plugin. This is automatically done via REGISTER_PLUGIN_DYNAMIC,
+ * see base/plugins.h.
*
* When __cxa_atexit can not be used, each plugin needs to link against
* libstdc++ to embed its own set of C++ ABI symbols. When not doing so,
@@ -137,11 +136,9 @@ bool ELFPlugin::loadPlugin() {
#ifdef ELF_LOADER_CXA_ATEXIT
if (ret) {
- // FIXME HACK: Reverse HACK of findSymbol() :P
- VoidFunc tmp;
- tmp = findSymbol("__dso_handle");
- memcpy(&_dso_handle, &tmp, sizeof(VoidFunc));
- debug(2, "elfloader: __dso_handle is %p", _dso_handle);
+ _finalizeFunc = findSymbol("PLUGIN_finalize");
+ if (!_finalizeFunc)
+ warning("elfloader: plugin '%s' is missing PLUGIN_finalize", _filename.toString(Common::Path::kNativeSeparator).c_str());
}
#endif
@@ -155,10 +152,10 @@ void ELFPlugin::unloadPlugin() {
if (_dlHandle) {
#ifdef ELF_LOADER_CXA_ATEXIT
- if (_dso_handle) {
- debug(2, "elfloader: calling __cxa_finalize");
- __cxxabiv1::__cxa_finalize(_dso_handle);
- _dso_handle = 0;
+ if (_finalizeFunc) {
+ debug(2, "elfloader: calling PLUGIN_finalize");
+ _finalizeFunc();
+ _finalizeFunc = 0;
}
#endif
diff --git a/backends/plugins/elf/elf-provider.h b/backends/plugins/elf/elf-provider.h
index 90a80b64598..6f03272a24c 100644
--- a/backends/plugins/elf/elf-provider.h
+++ b/backends/plugins/elf/elf-provider.h
@@ -44,7 +44,7 @@ protected:
typedef const char *(*CharFunc)();
DLObject *_dlHandle;
- void *_dso_handle;
+ VoidFunc _finalizeFunc;
virtual VoidFunc findSymbol(const char *symbol);
@@ -52,7 +52,7 @@ public:
ELFPlugin(const Common::Path &filename) :
DynamicPlugin(filename),
_dlHandle(0),
- _dso_handle(0) {
+ _finalizeFunc(0) {
}
virtual ~ELFPlugin() {
diff --git a/backends/plugins/elf/plugin.syms b/backends/plugins/elf/plugin.syms
index 97f9937f7a8..054b5cde104 100644
--- a/backends/plugins/elf/plugin.syms
+++ b/backends/plugins/elf/plugin.syms
@@ -3,8 +3,8 @@ PLUGIN_getVersion
PLUGIN_getType
PLUGIN_getTypeVersion
PLUGIN_getObject
+PLUGIN_finalize
___plugin_ctors
___plugin_ctors_end
___plugin_dtors
___plugin_dtors_end
-__dso_handle
diff --git a/base/plugins.h b/base/plugins.h
index 15b7bdd7f1e..52d4dace970 100644
--- a/base/plugins.h
+++ b/base/plugins.h
@@ -27,6 +27,10 @@
#include "common/str.h"
#include "backends/plugins/elf/version.h"
+#if defined(USE_ELF_LOADER) && defined(ELF_LOADER_CXA_ATEXIT)
+#include <cxxabi.h>
+#endif
+
#define INCLUDED_FROM_BASE_PLUGINS_H
#include "base/internal_plugins.h"
#undef INCLUDED_FROM_BASE_PLUGINS_H
@@ -64,8 +68,15 @@ extern const int pluginTypeVersions[PLUGIN_TYPE_MAX];
#if defined(USE_ELF_LOADER) && defined(ELF_LOADER_CXA_ATEXIT)
#define PLUGIN_DYNAMIC_DSO_HANDLE \
uint32 __dso_handle __attribute__((visibility("hidden"))) = 0;
+// Exported helper that runs __cxa_finalize from inside the plugin, so the
+// &__dso_handle argument is the plugin's own resolved address -- the same one
+// GCC embedded in its __cxa_atexit calls. Calling __cxa_finalize from the host
+// with a findSymbol() lookup is fragile (see elf-provider.cpp).
+#define PLUGIN_DYNAMIC_FINALIZE \
+ PLUGIN_EXPORT void PLUGIN_finalize() { __cxxabiv1::__cxa_finalize(&__dso_handle); }
#else
#define PLUGIN_DYNAMIC_DSO_HANDLE
+#define PLUGIN_DYNAMIC_FINALIZE
#endif
#ifdef USE_ELF_LOADER
@@ -106,6 +117,7 @@ extern const int pluginTypeVersions[PLUGIN_TYPE_MAX];
#define REGISTER_PLUGIN_DYNAMIC(ID,TYPE,PLUGINCLASS) \
extern "C" { \
PLUGIN_DYNAMIC_DSO_HANDLE \
+ PLUGIN_DYNAMIC_FINALIZE \
PLUGIN_DYNAMIC_BUILD_DATE \
PLUGIN_EXPORT int32 PLUGIN_getVersion() { return PLUGIN_VERSION; } \
PLUGIN_EXPORT int32 PLUGIN_getType() { return TYPE; } \
Commit: 83ebddc748e3d38d999ac6a17216cf1e5455c6cc
https://github.com/scummvm/scummvm/commit/83ebddc748e3d38d999ac6a17216cf1e5455c6cc
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2026-04-27T02:05:36+10:00
Commit Message:
BACKENDS: ATARI: Implement plugins
Changed paths:
A backends/plugins/atari/atari-provider.cpp
A backends/plugins/atari/atari-provider.h
A backends/plugins/elf/m68k-loader.cpp
A backends/plugins/elf/m68k-loader.h
A backends/plugins/firebee/firebee-provider.cpp
A backends/plugins/firebee/firebee-provider.h
A backends/plugins/mintelf/plugin.ld
backends/module.mk
backends/platform/atari/atari.mk
backends/platform/atari/build-release.sh
backends/platform/atari/build-release030.sh
backends/platform/atari/osystem_atari.cpp
backends/platform/atari/readme.txt
backends/platform/atari/readme.txt.in
backends/plugins/elf/elf-loader.cpp
backends/plugins/elf/elf32.h
base/plugins.cpp
configure
diff --git a/backends/module.mk b/backends/module.mk
index e6b2daa873a..4fb973b353e 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -173,6 +173,7 @@ MODULE_OBJS += \
plugins/elf/cxa-atexit.o \
plugins/elf/elf-loader.o \
plugins/elf/elf-provider.o \
+ plugins/elf/m68k-loader.o \
plugins/elf/memory-manager.o \
plugins/elf/mips-loader.o \
plugins/elf/ppc-loader.o \
@@ -428,6 +429,10 @@ MODULE_OBJS += \
graphics/atari/atari-supervidel.o \
graphics/atari/atari-surface.o \
mixer/atari/atari-mixer.o
+ifdef USE_ELF_LOADER
+MODULE_OBJS += \
+ plugins/atari/atari-provider.o
+endif
endif
ifeq ($(BACKEND),ds)
diff --git a/backends/platform/atari/atari.mk b/backends/platform/atari/atari.mk
index 77bd28c47ed..e57cf8713ff 100644
--- a/backends/platform/atari/atari.mk
+++ b/backends/platform/atari/atari.mk
@@ -17,7 +17,7 @@ FB_DATA := ${FB_DIR}
FB_DOCS := ${FB_DIR}/doc
FB_THEMES := ${FB_DIR}
-atarilitedist: $(EXECUTABLE)
+atarilitedist: $(EXECUTABLE) plugins
$(RM_REC) ${LITE_DIR}
$(MKDIR) ${LITE_DIR}
@@ -25,6 +25,13 @@ atarilitedist: $(EXECUTABLE)
$(NM) -C ${LITE_DIR}/$(EXECUTABLE) | grep -vF ' .L' | grep ' [TtWV] ' | $(CXXFILT) | sort -u > ${LITE_DIR}/scummvm.sym
$(STRIP) -s ${LITE_DIR}/$(EXECUTABLE)
+ifneq ($(PLUGINS),)
+ $(MKDIR) ${LITE_DIR}/plugins
+ $(CP) $(PLUGINS) ${LITE_DIR}/plugins
+ $(STRIP) --strip-debug ${LITE_DIR}/plugins/*$(PLUGIN_SUFFIX)
+ ! [ -f ${LITE_DIR}/plugins/detection$(PLUGIN_SUFFIX) ] || mv ${LITE_DIR}/plugins/detection$(PLUGIN_SUFFIX) ${LITE_DIR}/plugins/detectio$(PLUGIN_SUFFIX)
+endif
+
$(MKDIR) ${LITE_DOCS}
$(CP) $(DIST_FILES_DOCS) ${LITE_DOCS}
@@ -48,7 +55,7 @@ ifeq ($(CREATE_ZIP),y)
$(ZIP) -r -9 ../${LITE_DIR}.zip ${LITE_DIR}
endif
-atarifulldist: $(EXECUTABLE)
+atarifulldist: $(EXECUTABLE) plugins
$(RM_REC) ${FULL_DIR}
$(MKDIR) ${FULL_DIR}
@@ -56,6 +63,13 @@ atarifulldist: $(EXECUTABLE)
$(NM) -C ${FULL_DIR}/$(EXECUTABLE) | grep -vF ' .L' | grep ' [TtWV] ' | $(CXXFILT) | sort -u > ${FULL_DIR}/scummvm.sym
$(STRIP) -s ${FULL_DIR}/$(EXECUTABLE)
+ifneq ($(PLUGINS),)
+ $(MKDIR) ${FULL_DIR}/plugins
+ $(CP) $(PLUGINS) ${FULL_DIR}/plugins
+ $(STRIP) --strip-debug ${FULL_DIR}/plugins/*$(PLUGIN_SUFFIX)
+ ! [ -f ${FULL_DIR}/plugins/detection$(PLUGIN_SUFFIX) ] || mv ${FULL_DIR}/plugins/detection$(PLUGIN_SUFFIX) ${FULL_DIR}/plugins/detectio$(PLUGIN_SUFFIX)
+endif
+
$(MKDIR) ${FULL_DOCS}
$(CP) $(DIST_FILES_DOCS) ${FULL_DOCS}
diff --git a/backends/platform/atari/build-release.sh b/backends/platform/atari/build-release.sh
index d819bf02e5d..a8c1d6d5e7a 100755
--- a/backends/platform/atari/build-release.sh
+++ b/backends/platform/atari/build-release.sh
@@ -8,6 +8,7 @@ cd build-release
PLATFORM=m68k-atari-mintelf
FASTCALL=false
+PLUGINS=true
export ASFLAGS="-m68020-60"
export CXXFLAGS="-m68020-60 -DUSE_MOVE16 -DUSE_SUPERVIDEL -DUSE_SV_BLITTER -DDISABLE_LAUNCHERDISPLAY_GRID"
export LDFLAGS="-m68020-60"
@@ -21,6 +22,13 @@ then
LDFLAGS="$LDFLAGS -mfastcall"
fi
+if $PLUGINS
+then
+ PLUGINS_FLAGS="--enable-plugins --default-dynamic --enable-detection-dynamic"
+else
+ PLUGINS_FLAGS=""
+fi
+
if [ ! -f config.log ]
then
../configure \
@@ -28,7 +36,8 @@ then
--host=${PLATFORM} \
--enable-release \
--enable-verbose-build \
- --disable-engine=hugo,director,cine,ultima,pink,wage
+ --disable-engine=hugo,director,cine,ultima,pink,wage \
+ ${PLUGINS_FLAGS}
fi
make -j$(getconf _NPROCESSORS_CONF) atarifulldist
diff --git a/backends/platform/atari/build-release030.sh b/backends/platform/atari/build-release030.sh
index 80ec6781ef4..4c78cfee3e2 100755
--- a/backends/platform/atari/build-release030.sh
+++ b/backends/platform/atari/build-release030.sh
@@ -8,6 +8,7 @@ cd build-release030
PLATFORM=m68k-atari-mintelf
FASTCALL=false
+PLUGINS=true
export ASFLAGS="-m68030"
export CXXFLAGS="-m68030 -DDISABLE_FANCY_THEMES -DDISABLE_DOSBOX_OPL -DDISABLE_MAME_OPL"
export LDFLAGS="-m68030"
@@ -21,6 +22,13 @@ then
LDFLAGS="$LDFLAGS -mfastcall"
fi
+if $PLUGINS
+then
+ PLUGINS_FLAGS="--enable-plugins --default-dynamic --enable-detection-dynamic"
+else
+ PLUGINS_FLAGS=""
+fi
+
if [ ! -f config.log ]
then
../configure \
@@ -30,7 +38,8 @@ then
--disable-highres \
--disable-bink \
--enable-verbose-build \
- --disable-engine=hugo,director,cine,ultima
+ --disable-engine=hugo,director,cine,ultima \
+ ${PLUGINS_FLAGS}
fi
make -j$(getconf _NPROCESSORS_CONF) atarilitedist
diff --git a/backends/platform/atari/osystem_atari.cpp b/backends/platform/atari/osystem_atari.cpp
index 527f7b10001..b2ec8429151 100644
--- a/backends/platform/atari/osystem_atari.cpp
+++ b/backends/platform/atari/osystem_atari.cpp
@@ -43,6 +43,9 @@
#include "backends/platform/atari/osystem_atari.h"
#include "backends/audiocd/default/default-audiocd.h"
+#ifdef DYNAMIC_MODULES
+#include "backends/plugins/atari/atari-provider.h"
+#endif
#include "common/config-manager.h"
#include "backends/events/atari/atari-events.h"
#include "backends/events/default/default-events.h"
@@ -522,6 +525,10 @@ int main(int argc, char *argv[]) {
g_system = OSystem_Atari_create();
assert(g_system);
+#ifdef DYNAMIC_MODULES
+ PluginManager::instance().addPluginProvider(new AtariPluginProvider());
+#endif
+
// Invoke the actual ScummVM main entry point:
int res = scummvm_main(argc, argv);
g_system->destroy();
diff --git a/backends/platform/atari/readme.txt b/backends/platform/atari/readme.txt
index 199de1a38b3..504abf272b4 100644
--- a/backends/platform/atari/readme.txt
+++ b/backends/platform/atari/readme.txt
@@ -534,18 +534,10 @@ Future plans
- DSP-based sample mixer (WAV, FLAC, MP2).
-- Avoid loading music/speech files (and thus slowing down everything) if muted.
-
-- Cached audio/video streams (i.e. don't load only "audio_buffer_size" number
- of samples but cache, say, 1 second so disk i/o won't be so stressed).
-
-- Using Thorsten Otto's sharedlibs: https://tho-otto.de/sharedlibs.php for game
- engine plugins to relieve the huge binary size.
+- Avoid decoding music/speech files (and thus slowing down everything) if muted.
- True audio CD support via MetaDOS API.
-- OPL2LPT and Retrowave support (if I manage to purchase it somewhere).
-
Closing words
-------------
diff --git a/backends/platform/atari/readme.txt.in b/backends/platform/atari/readme.txt.in
index d2a13d4119e..f0ec035feb3 100644
--- a/backends/platform/atari/readme.txt.in
+++ b/backends/platform/atari/readme.txt.in
@@ -534,18 +534,10 @@ Future plans
- DSP-based sample mixer (WAV, FLAC, MP2).
-- Avoid loading music/speech files (and thus slowing down everything) if muted.
-
-- Cached audio/video streams (i.e. don't load only "audio_buffer_size" number
- of samples but cache, say, 1 second so disk i/o won't be so stressed).
-
-- Using Thorsten Otto's sharedlibs: https://tho-otto.de/sharedlibs.php for game
- engine plugins to relieve the huge binary size.
+- Avoid decoding music/speech files (and thus slowing down everything) if muted.
- True audio CD support via MetaDOS API.
-- OPL2LPT and Retrowave support (if I manage to purchase it somewhere).
-
Closing words
-------------
diff --git a/backends/plugins/atari/atari-provider.cpp b/backends/plugins/atari/atari-provider.cpp
new file mode 100644
index 00000000000..2c2aef4a91c
--- /dev/null
+++ b/backends/plugins/atari/atari-provider.cpp
@@ -0,0 +1,87 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+#include "common/scummsys.h"
+
+#if defined(DYNAMIC_MODULES) && defined(__MINT__) && defined(__ELF__) && !defined(__mcoldfire__)
+
+#include "backends/plugins/atari/atari-provider.h"
+#include "backends/plugins/elf/m68k-loader.h"
+
+#include <mint/cookie.h>
+#include <mint/mintbind.h>
+#include <mint/ssystem.h>
+
+class AtariDLObject final : public M68KDLObject {
+protected:
+ void relocateSymbols(ptrdiff_t offset) override {
+ // Symbols imported via `ld --just-symbols=$(EXECUTABLE)` (used by the
+ // plugin link step to resolve references into the main binary) end up as
+ // SHN_ABS with st_value = ELF VMA in the main binary. The atariprg loader
+ // loads the main binary at _base->p_tbase, so the runtime address is
+ // (ELF VMA + p_tbase). Patch SHN_ABS entries here; the base implementation
+ // then handles plugin-local symbols.
+ const uint32 mainOffset = (uint32)_base->p_tbase;
+ Elf32_Sym *s = _symtab;
+ for (uint32 c = _symbol_cnt; c--; s++) {
+ if (s->st_shndx == SHN_ABS)
+ s->st_value += mainOffset;
+ }
+
+ DLObject::relocateSymbols(offset);
+ }
+
+ void flushDataCache(void *ptr, uint32 len) const override {
+ if (Ssystem(-1, 0L, 0L) == 0) {
+ Ssystem(S_FLUSHCACHE, (long)ptr, (long)len);
+ } else {
+ long mcpu = 0;
+
+ if (Getcookie(C__CPU, &mcpu) == C_FOUND) {
+ if (mcpu >= 40) {
+ long oldssp = Super(SUP_SET);
+ __asm__ volatile (
+ ".word 0xF478\n\t" // cpusha dc
+ ".word 0xF498" // cinva ic
+ ::: "memory"
+ );
+ Super((void *)oldssp);
+ } else if (mcpu >= 20) {
+ long oldssp = Super(SUP_SET);
+ __asm__ volatile (
+ "movec %%cacr,%%d0\n\t"
+ "or.w #0x0008,%%d0\n\t" // CI
+ "movec %%d0,%%cacr"
+ ::: "d0", "cc", "memory"
+ );
+ Super((void *)oldssp);
+ }
+ }
+ }
+ }
+};
+
+Plugin *AtariPluginProvider::createPlugin(const Common::FSNode &node) const {
+ return new TemplatedELFPlugin<AtariDLObject>(node.getPath());
+}
+
+#endif // defined(DYNAMIC_MODULES) && defined(__MINT__) && defined(__ELF__) && !defined(__mcoldfire__)
diff --git a/backends/plugins/atari/atari-provider.h b/backends/plugins/atari/atari-provider.h
new file mode 100644
index 00000000000..fcc733906a6
--- /dev/null
+++ b/backends/plugins/atari/atari-provider.h
@@ -0,0 +1,36 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#if defined(DYNAMIC_MODULES) && defined(__MINT__) && defined(__ELF__) && !defined(__mcoldfire__)
+
+#ifndef BACKENDS_PLUGINS_ATARI_PROVIDER_H
+#define BACKENDS_PLUGINS_ATARI_PROVIDER_H
+
+#include "backends/plugins/elf/elf-provider.h"
+
+class AtariPluginProvider final : public ELFPluginProvider {
+public:
+ Plugin *createPlugin(const Common::FSNode &node) const override;
+};
+
+#endif // BACKENDS_PLUGINS_ATARI_PROVIDER_H
+
+#endif // defined(DYNAMIC_MODULES) && defined(__MINT__) && defined(__ELF__) && !defined(__mcoldfire__)
diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp
index 75469875c67..4be63738675 100644
--- a/backends/plugins/elf/elf-loader.cpp
+++ b/backends/plugins/elf/elf-loader.cpp
@@ -127,6 +127,9 @@ bool DLObject::readElfHeader(Elf32_Ehdr *ehdr) {
#endif
#ifdef PPC_TARGET
EM_PPC
+#endif
+#ifdef M68K_TARGET
+ EM_68K
#endif
) {
warning("elfloader: Wrong ELF file architecture.");
diff --git a/backends/plugins/elf/elf32.h b/backends/plugins/elf/elf32.h
index c436922bc73..2d406ab230d 100644
--- a/backends/plugins/elf/elf32.h
+++ b/backends/plugins/elf/elf32.h
@@ -81,6 +81,7 @@ typedef struct {
#define ET_CORE 4 /* core file */
// e_machine values
+#define EM_68K 4
#define EM_MIPS 8
#define EM_PPC 20
#define EM_ARM 40
@@ -245,6 +246,15 @@ typedef struct {
#define R_PPC_REL24 10
#define R_PPC_REL32 26
+// m68k relocation types
+#define R_68K_NONE 0
+#define R_68K_32 1
+#define R_68K_16 2
+#define R_68K_8 3
+#define R_68K_PC32 4
+#define R_68K_PC16 5
+#define R_68K_PC8 6
+
#endif // defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER)
#endif /* BACKENDS_ELF_H */
diff --git a/backends/plugins/elf/m68k-loader.cpp b/backends/plugins/elf/m68k-loader.cpp
new file mode 100644
index 00000000000..1e520fa55a2
--- /dev/null
+++ b/backends/plugins/elf/m68k-loader.cpp
@@ -0,0 +1,120 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(M68K_TARGET)
+
+#include "backends/plugins/elf/elf-loader.h"
+#include "backends/plugins/elf/m68k-loader.h"
+
+#include "common/debug.h"
+
+#include <mint/basepage.h>
+
+bool M68KDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) {
+ Elf32_Rela *rel = (Elf32_Rela *)malloc(size);
+
+ if (!rel) {
+ warning("elfloader: Could not allocate %d bytes for the relocation table", size);
+ return false;
+ }
+
+ if (!_file->seek(offset, SEEK_SET) || _file->read(rel, size) != size) {
+ warning("elfloader: Relocation table load failed.");
+ free(rel);
+ return false;
+ }
+
+ uint32 cnt = size / sizeof(*rel);
+
+ debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment);
+
+ for (uint32 i = 0; i < cnt; i++) {
+ Elf32_Sym *sym = _symtab + REL_INDEX(rel[i].r_info);
+ byte *src = relSegment + rel[i].r_offset - _segmentVMA;
+ uint32 value = sym->st_value + rel[i].r_addend;
+
+ switch (REL_TYPE(rel[i].r_info)) {
+ case R_68K_NONE:
+ break;
+ case R_68K_32:
+ *(uint32 *)src = value;
+ debug(8, "elfloader: R_68K_32 -> 0x%08x", *(uint32 *)src);
+ break;
+ case R_68K_16:
+ *(uint16 *)src = (uint16)value;
+ debug(8, "elfloader: R_68K_16 -> 0x%04x", *(uint16 *)src);
+ break;
+ case R_68K_8:
+ *src = (uint8)value;
+ debug(8, "elfloader: R_68K_8 -> 0x%02x", *src);
+ break;
+ case R_68K_PC32:
+ *(uint32 *)src = value - (uint32)src;
+ debug(8, "elfloader: R_68K_PC32 -> 0x%08x", *(uint32 *)src);
+ break;
+ case R_68K_PC16:
+ *(uint16 *)src = (uint16)(value - (uint32)src);
+ debug(8, "elfloader: R_68K_PC16 -> 0x%04x", *(uint16 *)src);
+ break;
+ case R_68K_PC8:
+ *src = (uint8)(value - (uint32)src);
+ debug(8, "elfloader: R_68K_PC8 -> 0x%02x", *src);
+ break;
+ default:
+ warning("elfloader: Unknown relocation type %d", REL_TYPE(rel[i].r_info));
+ free(rel);
+ return false;
+ }
+ }
+
+ free(rel);
+ return true;
+}
+
+bool M68KDLObject::relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) {
+ for (uint32 i = 0; i < ehdr->e_shnum; i++) {
+ Elf32_Shdr *curShdr = &(shdr[i]);
+
+ if ((curShdr->sh_type == SHT_REL) &&
+ curShdr->sh_entsize == sizeof(Elf32_Rel) &&
+ int32(curShdr->sh_link) == _symtab_sect &&
+ curShdr->sh_info < ehdr->e_shnum &&
+ (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) {
+ warning("elfloader: REL entries not supported on m68k!");
+ return false;
+ }
+
+ if ((curShdr->sh_type == SHT_RELA) &&
+ curShdr->sh_entsize == sizeof(Elf32_Rela) &&
+ int32(curShdr->sh_link) == _symtab_sect &&
+ curShdr->sh_info < ehdr->e_shnum &&
+ (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) {
+ if (!relocate(curShdr->sh_offset, curShdr->sh_size, _segment))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(M68K_TARGET) */
diff --git a/backends/plugins/elf/m68k-loader.h b/backends/plugins/elf/m68k-loader.h
new file mode 100644
index 00000000000..fd67ca08774
--- /dev/null
+++ b/backends/plugins/elf/m68k-loader.h
@@ -0,0 +1,39 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef BACKENDS_PLUGINS_M68K_LOADER_H
+#define BACKENDS_PLUGINS_M68K_LOADER_H
+
+#include "common/scummsys.h"
+
+#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(M68K_TARGET)
+
+#include "backends/plugins/elf/elf-loader.h"
+
+class M68KDLObject : public DLObject {
+protected:
+ bool relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) override;
+ bool relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) override;
+};
+
+#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(M68K_TARGET) */
+
+#endif /* BACKENDS_PLUGINS_M68K_LOADER_H */
diff --git a/backends/plugins/firebee/firebee-provider.cpp b/backends/plugins/firebee/firebee-provider.cpp
new file mode 100644
index 00000000000..011c74cfacb
--- /dev/null
+++ b/backends/plugins/firebee/firebee-provider.cpp
@@ -0,0 +1,91 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+#include "common/scummsys.h"
+
+#if defined(DYNAMIC_MODULES) && defined(__MINT__) && defined(__ELF__) && defined(__mcoldfire__)
+
+#include "backends/plugins/firebee/firebee-provider.h"
+#include "backends/plugins/elf/m68k-loader.h"
+
+#include <mint/cookie.h>
+#include <mint/mintbind.h>
+#include <mint/ssystem.h>
+
+class FireBeeDLObject final : public M68KDLObject {
+protected:
+ void relocateSymbols(ptrdiff_t offset) override {
+ // Symbols imported via `ld --just-symbols=$(EXECUTABLE)` (used by the
+ // plugin link step to resolve references into the main binary) end up as
+ // SHN_ABS with st_value = ELF VMA in the main binary. The atariprg loader
+ // loads the main binary at _base->p_tbase, so the runtime address is
+ // (ELF VMA + p_tbase). Patch SHN_ABS entries here; the base implementation
+ // then handles plugin-local symbols.
+ const uint32 mainOffset = (uint32)_base->p_tbase;
+ Elf32_Sym *s = _symtab;
+ for (uint32 c = _symbol_cnt; c--; s++) {
+ if (s->st_shndx == SHN_ABS)
+ s->st_value += mainOffset;
+ }
+
+ DLObject::relocateSymbols(offset);
+ }
+
+ void flushDataCache(void *ptr, uint32 len) const override {
+ if (Ssystem(-1, 0L, 0L) == 0) {
+ Ssystem(S_FLUSHCACHE, (long)ptr, (long)len);
+ } else {
+ // ignored for now
+ (void)ptr;
+ (void)len;
+
+ long oldssp = Super(SUP_SET);
+ __asm__ volatile (
+ "nop\n\t" // flush store buffer
+ "moveq.l #0,%%d0\n\t" // way = 0
+ "moveq.l #0,%%d1\n\t" // set = 0
+ "move.l %%d0,%%a0\n"
+ "1:\n\t"
+ "cpushl %%bc,(%%a0)\n\t" // push + invalidate line
+ "add.l #16,%%a0\n\t"
+ "addq.l #1,%%d1\n\t"
+ "cmpi.l #512,%%d1\n\t"
+ "bne.s 1b\n\t"
+ "moveq.l #0,%%d1\n\t"
+ "addq.l #1,%%d0\n\t"
+ "move.l %%d0,%%a0\n\t"
+ "cmpi.l #4,%%d0\n\t"
+ "bne.s 1b"
+ :
+ :
+ : "d0", "d1", "a0", "memory", "cc"
+ );
+ Super((void *)oldssp);
+ }
+ }
+};
+
+Plugin *FireBeePluginProvider::createPlugin(const Common::FSNode &node) const {
+ return new TemplatedELFPlugin<FireBeeDLObject>(node.getPath());
+}
+
+#endif // defined(DYNAMIC_MODULES) && defined(__MINT__) && defined(__ELF__) && defined(__mcoldfire__)
diff --git a/backends/plugins/firebee/firebee-provider.h b/backends/plugins/firebee/firebee-provider.h
new file mode 100644
index 00000000000..0eabb690ef9
--- /dev/null
+++ b/backends/plugins/firebee/firebee-provider.h
@@ -0,0 +1,36 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#if defined(DYNAMIC_MODULES) && defined(__MINT__) && defined(__ELF__) && defined(__mcoldfire__)
+
+#ifndef BACKENDS_PLUGINS_FIREBEE_PROVIDER_H
+#define BACKENDS_PLUGINS_FIREBEE_PROVIDER_H
+
+#include "backends/plugins/elf/elf-provider.h"
+
+class FireBeePluginProvider final : public ELFPluginProvider {
+public:
+ Plugin *createPlugin(const Common::FSNode &node) const override;
+};
+
+#endif // BACKENDS_PLUGINS_FIREBEE_PROVIDER_H
+
+#endif // defined(DYNAMIC_MODULES) && defined(__MINT__) && defined(__ELF__) && defined(__mcoldfire__)
diff --git a/backends/plugins/mintelf/plugin.ld b/backends/plugins/mintelf/plugin.ld
new file mode 100644
index 00000000000..29683d3b319
--- /dev/null
+++ b/backends/plugins/mintelf/plugin.ld
@@ -0,0 +1,163 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+OUTPUT_FORMAT("elf32-m68k")
+OUTPUT_ARCH(m68k)
+ENTRY(_start)
+
+PHDRS
+{
+ /* ScummVM's elf loader only allows a single segment. */
+ plugin PT_LOAD FLAGS(7) /* Read | Write | Execute */;
+}
+
+SECTIONS
+{
+ . = 0;
+
+ .text ALIGN(4) :
+ {
+ *(.text.unlikely .text.*_unlikely .text.unlikely.*)
+ *(.text.exit .text.exit.*)
+ *(.text.startup .text.startup.*)
+ *(.text.hot .text.hot.*)
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ *(.gnu.warning)
+ } : plugin
+
+ .rodata ALIGN(4) :
+ {
+ *(.rodata)
+ *(.rodata.*)
+ *(.gnu.linkonce.r*)
+ *(.rodata1)
+ . = ALIGN(4);
+ } : plugin
+
+ .preinit_array ALIGN(4) :
+ {
+ PROVIDE (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE (__preinit_array_end = .);
+ } : plugin
+
+ /* m68k-atari-mintelf gcc emits constructors into .init_array (and dtors
+ * into .fini_array). The ELF plugin loader walks ___plugin_ctors and
+ * ___plugin_dtors both forward; .init_array semantics match (ascending
+ * priority = construction order), but standard .fini_array is walked
+ * backward by a normal runtime, so we REVERSE the .fini_array sort here
+ * to get reverse-of-construction destruction order out of a forward
+ * walk. .ctors/.dtors are kept too in case any input object still uses
+ * the legacy sections. */
+ .ctors ALIGN(4) :
+ {
+ ___plugin_ctors = .;
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*)))
+ KEEP (*(.init_array))
+ KEEP (*(SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.ctors))
+ ___plugin_ctors_end = .;
+ } : plugin
+
+ .dtors ALIGN(4) :
+ {
+ ___plugin_dtors = .;
+ KEEP (*(SORT_BY_INIT_PRIORITY(REVERSE(.fini_array.*))))
+ KEEP (*(.fini_array))
+ KEEP (*(SORT_BY_INIT_PRIORITY(REVERSE(.dtors.*))))
+ KEEP (*(.dtors))
+ ___plugin_dtors_end = .;
+ } : plugin
+
+ .data ALIGN(4) :
+ {
+ *(.data)
+ *(.data.*)
+ *(.gnu.linkonce.d*)
+ CONSTRUCTORS
+ . = ALIGN(4);
+ } : plugin
+ .data1 :
+ {
+ *(.data1)
+ . = ALIGN(4);
+ } : plugin
+
+ __bss_start__ = .;
+ .bss ALIGN(4) :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(SORT(.bss.*))
+ *(.gnu.linkonce.b*)
+ *(COMMON)
+ . = ALIGN(4);
+ } : plugin
+ __bss_end__ = .;
+
+ __end__ = ABSOLUTE(.) ;
+
+ /* Discard sections that complicate post-processing */
+ /DISCARD/ : { *(.group .comment .note) }
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+
+ /* DWARF 3 */
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+
+ /* DWARF Extension. */
+ .debug_macro 0 : { *(.debug_macro) }
+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+
+ /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+}
diff --git a/base/plugins.cpp b/base/plugins.cpp
index 5bdf09c5691..93aaa7bcbfd 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -318,7 +318,11 @@ void PluginManagerUncached::init() {
unloadPluginsExcept(PLUGIN_TYPE_ENGINE, nullptr, false); // empty the engine plugins
#ifndef DETECTION_STATIC
- Common::String detectPluginName = "detection";
+#ifdef PLUGIN_DETECTION_NAME
+Common::String detectPluginName = PLUGIN_DETECTION_NAME;
+#else
+Common::String detectPluginName = "detection";
+#endif
#ifdef PLUGIN_SUFFIX
detectPluginName += PLUGIN_SUFFIX;
#endif
diff --git a/configure b/configure
index 97c8097738a..9a6f8c280e2 100755
--- a/configure
+++ b/configure
@@ -684,7 +684,7 @@ get_system_exe_extension() {
mingw* | *os2-emx)
_exeext=".exe"
;;
- mint)
+ mint*)
_exeext=".prg"
;;
emscripten)
@@ -1841,6 +1841,11 @@ kos32)
_host_cpu=i686
_host_alias=kos32
;;
+m68k-atari-mintelf*)
+ _host_os=mintelf
+ _host_cpu=m68k
+ _host_alias=$_host
+ ;;
m68k-atari-mint*)
_host_os=mint
_host_cpu=m68k
@@ -5203,6 +5208,18 @@ PLUGIN_EXTRA_DEPS =
PLUGIN_LDFLAGS += -shared
PRE_OBJS_FLAGS := -Wl,-export-dynamic -Wl,-whole-archive
POST_OBJS_FLAGS := -Wl,-no-whole-archive
+'
+ ;;
+ mintelf)
+ _elf_loader=yes
+ append_var DEFINES "-DM68K_TARGET"
+ append_var DEFINES "-DPLUGIN_DETECTION_NAME=\\\"detectio\\\""
+ append_var CXXFLAGS "-fuse-cxa-atexit"
+ append_var DEFINES "-DELF_LOADER_CXA_ATEXIT"
+ append_var DEFINES "-DUNCACHED_PLUGINS"
+ append_var DEFINES "-DELF_NO_MEM_MANAGER"
+_mak_plugins='
+PLUGIN_LDFLAGS += -Wl,-m,m68kelf,-T,$(srcdir)/backends/plugins/mintelf/plugin.ld
'
;;
*cygwin* | *mingw32* | mingw64)
Commit: b02c2de70fc7235b5ed9dba302a70c3e89aad181
https://github.com/scummvm/scummvm/commit/b02c2de70fc7235b5ed9dba302a70c3e89aad181
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2026-04-27T02:05:36+10:00
Commit Message:
BACKENDS: ATARI: Match other platforms' plugin.ld ctors/dtors layout
Revert the folding of .init_array / .fini_array into ___plugin_ctors /
___plugin_dtors. Other ELF-loader backends (3ds, riscos, wii, ds, psp)
keep these as separate sections, and the cross-platform migration to
walk .init_array / .fini_array directly from the loader will be done in
the future (see https://github.com/scummvm/scummvm/pull/7446).
m68k-atari-mintelf-gcc emits .init_array / .fini_array rather than
.ctors / .dtors. I have verified it two ways: scummvm.prg has populated
.init_array (6 entries) and .fini_array (1 entry); and adding a single
namespace-scope `static Foo g;` to an engine TU produces an .init_array
entry in the resulting .plg that lives outside ___plugin_ctors ..
___plugin_ctors_end. So with this layout, such an entry is silently
never run (same of every other ELF backend?). Fortunately, no engine has
such a static today (every built plugin has empty ctor/dtor ranges), so
nothing currently breaks.
Changed paths:
backends/plugins/mintelf/plugin.ld
diff --git a/backends/plugins/mintelf/plugin.ld b/backends/plugins/mintelf/plugin.ld
index 29683d3b319..c82b2802f9a 100644
--- a/backends/plugins/mintelf/plugin.ld
+++ b/backends/plugins/mintelf/plugin.ld
@@ -59,20 +59,26 @@ SECTIONS
PROVIDE (__preinit_array_end = .);
} : plugin
- /* m68k-atari-mintelf gcc emits constructors into .init_array (and dtors
- * into .fini_array). The ELF plugin loader walks ___plugin_ctors and
- * ___plugin_dtors both forward; .init_array semantics match (ascending
- * priority = construction order), but standard .fini_array is walked
- * backward by a normal runtime, so we REVERSE the .fini_array sort here
- * to get reverse-of-construction destruction order out of a forward
- * walk. .ctors/.dtors are kept too in case any input object still uses
- * the legacy sections. */
+ .init_array ALIGN(4) :
+ {
+ PROVIDE (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE (__init_array_end = .);
+ } : plugin
+
+ .fini_array ALIGN(4) :
+ {
+ PROVIDE (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE (__fini_array_end = .);
+ } : plugin
+
.ctors ALIGN(4) :
{
___plugin_ctors = .;
- KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*)))
- KEEP (*(.init_array))
- KEEP (*(SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
___plugin_ctors_end = .;
} : plugin
@@ -80,9 +86,7 @@ SECTIONS
.dtors ALIGN(4) :
{
___plugin_dtors = .;
- KEEP (*(SORT_BY_INIT_PRIORITY(REVERSE(.fini_array.*))))
- KEEP (*(.fini_array))
- KEEP (*(SORT_BY_INIT_PRIORITY(REVERSE(.dtors.*))))
+ KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
___plugin_dtors_end = .;
} : plugin
Commit: 3a6a355c20c12f77a57cd85a278c36c9efb45254
https://github.com/scummvm/scummvm/commit/3a6a355c20c12f77a57cd85a278c36c9efb45254
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2026-04-27T02:05:36+10:00
Commit Message:
BACKENDS: SDL: Add plugins support for Atari/FireBee
Changed paths:
backends/module.mk
backends/platform/atari/atari.mk
backends/platform/atari/build-firebee.sh
backends/platform/sdl/posix/posix-main.cpp
backends/plugins/posix/posix-provider.cpp
configure
diff --git a/backends/module.mk b/backends/module.mk
index 4fb973b353e..e329ae04fa2 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -238,9 +238,15 @@ endif
ifndef RISCOS
ifndef KOLIBRIOS
+ifdef USE_ATARI_PLUGIN_PROVIDER
+MODULE_OBJS += plugins/atari/atari-provider.o
+else ifdef USE_FIREBEE_PLUGIN_PROVIDER
+MODULE_OBJS += plugins/firebee/firebee-provider.o
+else
MODULE_OBJS += plugins/sdl/sdl-provider.o
endif
endif
+endif
# SDL 2 removed audio CD support
ifndef USE_SDL2
diff --git a/backends/platform/atari/atari.mk b/backends/platform/atari/atari.mk
index e57cf8713ff..244b38def91 100644
--- a/backends/platform/atari/atari.mk
+++ b/backends/platform/atari/atari.mk
@@ -108,13 +108,20 @@ ifeq ($(CREATE_ZIP),y)
$(ZIP) -r -9 ../${FULL_DIR}.zip ${FULL_DIR}
endif
-fbdist: $(EXECUTABLE)
+fbdist: $(EXECUTABLE) plugins
$(RM_REC) ${FB_DIR}
$(MKDIR) ${FB_DIR}
$(CP) $(EXECUTABLE) ${FB_DIR}
$(STRIP) -s ${FB_DIR}/$(EXECUTABLE)
+ifneq ($(PLUGINS),)
+ $(MKDIR) ${FB_DIR}/plugins
+ $(CP) $(PLUGINS) ${FB_DIR}/plugins
+ $(STRIP) --strip-debug ${FB_DIR}/plugins/*$(PLUGIN_SUFFIX)
+ ! [ -f ${FB_DIR}/plugins/detection$(PLUGIN_SUFFIX) ] || mv ${FB_DIR}/plugins/detection$(PLUGIN_SUFFIX) ${FB_DIR}/plugins/detectio$(PLUGIN_SUFFIX)
+endif
+
$(MKDIR) ${FB_DOCS}
$(CP) $(DIST_FILES_DOCS) ${FB_DOCS}
diff --git a/backends/platform/atari/build-firebee.sh b/backends/platform/atari/build-firebee.sh
index 51c5116f831..e175f5476a5 100755
--- a/backends/platform/atari/build-firebee.sh
+++ b/backends/platform/atari/build-firebee.sh
@@ -8,6 +8,7 @@ cd build-firebee
PLATFORM=m68k-atari-mintelf
FASTCALL=false
+PLUGINS=true
export CXXFLAGS="-mcpu=5475"
export LDFLAGS="-mcpu=5475"
#export CXXFLAGS="-m68020-60"
@@ -23,6 +24,13 @@ then
LDFLAGS="$LDFLAGS -mfastcall"
fi
+if $PLUGINS
+then
+ PLUGINS_FLAGS="--enable-plugins --default-dynamic --enable-detection-dynamic"
+else
+ PLUGINS_FLAGS=""
+fi
+
if [ ! -f config.log ]
then
../configure \
@@ -32,7 +40,8 @@ then
--with-freetype2-prefix="$(${PLATFORM}-gcc -print-sysroot)/usr/bin/${CPU_DIR}" \
--with-mikmod-prefix="$(${PLATFORM}-gcc -print-sysroot)/usr/bin/${CPU_DIR}" \
--enable-release \
- --enable-verbose-build
+ --enable-verbose-build \
+ ${PLUGINS_FLAGS}
fi
make -j$(getconf _NPROCESSORS_CONF) fbdist
diff --git a/backends/platform/sdl/posix/posix-main.cpp b/backends/platform/sdl/posix/posix-main.cpp
index 3bca233a86e..acdadd765ed 100644
--- a/backends/platform/sdl/posix/posix-main.cpp
+++ b/backends/platform/sdl/posix/posix-main.cpp
@@ -24,7 +24,13 @@
#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(OPENDINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(PSP2) && !defined(NINTENDO_SWITCH) && !defined(__EMSCRIPTEN__) && !defined(MIYOO) && !defined(MIYOOMINI) && !defined(SAILFISH)
#include "backends/platform/sdl/posix/posix.h"
+#ifdef USE_ATARI_PLUGIN_PROVIDER
+#include "backends/plugins/atari/atari-provider.h"
+#elif defined(USE_FIREBEE_PLUGIN_PROVIDER)
+#include "backends/plugins/firebee/firebee-provider.h"
+#else
#include "backends/plugins/sdl/sdl-provider.h"
+#endif
#include "base/main.h"
int main(int argc, char *argv[]) {
@@ -37,7 +43,13 @@ int main(int argc, char *argv[]) {
g_system->init();
#ifdef DYNAMIC_MODULES
+#if defined(USE_ATARI_PLUGIN_PROVIDER)
+ PluginManager::instance().addPluginProvider(new AtariPluginProvider());
+#elif defined(USE_FIREBEE_PLUGIN_PROVIDER)
+ PluginManager::instance().addPluginProvider(new FireBeePluginProvider());
+#else
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
+#endif
#endif
// Invoke the actual ScummVM main entry point:
diff --git a/backends/plugins/posix/posix-provider.cpp b/backends/plugins/posix/posix-provider.cpp
index 37c4656de3b..f669e0765ff 100644
--- a/backends/plugins/posix/posix-provider.cpp
+++ b/backends/plugins/posix/posix-provider.cpp
@@ -21,7 +21,7 @@
#include "common/scummsys.h"
-#if defined(DYNAMIC_MODULES) && defined(POSIX) && !defined(__3DS__)
+#if defined(DYNAMIC_MODULES) && defined(POSIX) && !defined(__3DS__) && !defined(__MINT__)
#include "backends/plugins/posix/posix-provider.h"
#include "backends/plugins/dynamic-plugin.h"
@@ -81,4 +81,4 @@ Plugin *POSIXPluginProvider::createPlugin(const Common::FSNode &node) const {
}
-#endif // defined(DYNAMIC_MODULES) && defined(POSIX)
+#endif // defined(DYNAMIC_MODULES) && defined(POSIX) && !defined(__3DS__) && !defined(__MINT__)
diff --git a/configure b/configure
index 9a6f8c280e2..bb52b25bd8c 100755
--- a/configure
+++ b/configure
@@ -3927,6 +3927,16 @@ if test -n "$_host"; then
_nuked_opl=no
_detection_features_full=no
+ if test "$_backend" = sdl; then
+ if cc_check_define __mcoldfire__; then
+ _firebee_plugin_provider=yes
+ else
+ _atari_plugin_provider=yes
+ fi
+ define_in_config_if_yes "$_atari_plugin_provider" 'USE_ATARI_PLUGIN_PROVIDER'
+ define_in_config_if_yes "$_firebee_plugin_provider" 'USE_FIREBEE_PLUGIN_PROVIDER'
+ fi
+
_port_mk="backends/platform/atari/atari.mk"
;;
maemo)
More information about the Scummvm-git-logs
mailing list