mirror of
https://github.com/scummvm/scummvm.git
synced 2026-05-21 05:40:43 +00:00
BACKENDS: ATARI: Implement plugins
This commit is contained in:
committed by
Miro Kropáček
parent
e09b9dfad6
commit
83ebddc748
@@ -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)
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
-------------
|
||||
|
||||
@@ -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
|
||||
-------------
|
||||
|
||||
@@ -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__)
|
||||
@@ -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__)
|
||||
@@ -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.");
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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) */
|
||||
@@ -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 */
|
||||
@@ -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__)
|
||||
@@ -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__)
|
||||
@@ -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_*) }
|
||||
}
|
||||
+5
-1
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user