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 .
+ *
+ */
+
+#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
+#include
+#include
+
+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(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 .
+ *
+ */
+
+#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 .
+ *
+ */
+
+#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
+
+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 .
+ *
+ */
+
+#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 .
+ *
+ */
+
+#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
+#include
+#include
+
+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(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 .
+ *
+ */
+
+#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 .
+ *
+ */
+
+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)