mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
overlay: use platform-native shared-library suffixes
Adapted from NyperYuhgard's PR #13 POSIX overlay work. Co-authored-by: NyperYuhgard <93950153+NyperYuhgard@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
# PR #13 POSIX cache-suffix provenance
|
||||
|
||||
Parked from NyperYuhgard's PSXrecomp PR #13, commit
|
||||
[`a39ab37dbc32f4889bf80331208b7510f497fc4f`](https://github.com/mstan/psxrecomp/commit/a39ab37dbc32f4889bf80331208b7510f497fc4f).
|
||||
|
||||
Native overlay artifacts use `.dll` on Windows and `.so` on POSIX hosts. The
|
||||
compiler, cache parser, manifest lookup, ABI cleanup, and cached-CRC lookup share
|
||||
that convention. POSIX loading/scanning itself is excluded because current master
|
||||
already has the newer implementation merged through PR #18.
|
||||
@@ -49,7 +49,7 @@ int overlay_loader_dispatch(CPUState *cpu, uint32_t addr);
|
||||
* (loaded DLLs stay loaded); emu thread only. */
|
||||
void overlay_loader_rescan(void);
|
||||
|
||||
/* True if the cache holds a DLL named <region_start8>_<crc8>.dll. */
|
||||
/* True if the cache holds <region_start8>_<crc8>.{dll,so}. */
|
||||
int overlay_loader_has_cached_crc(uint32_t region_start, uint32_t crc);
|
||||
|
||||
/* Returns number of functions currently registered in the dynamic table. */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Parsed <addr8>_<crc8>.dll cache filename. The parser is shared by the
|
||||
/* Parsed <addr8>_<crc8>.{dll,so} cache filename. The parser is shared by the
|
||||
* Windows and POSIX directory walkers so both platforms reject partial hex
|
||||
* fields and lookalike suffixes identically. */
|
||||
typedef struct PsxOverlayCacheFile {
|
||||
|
||||
@@ -22,6 +22,14 @@
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# define OVERLAY_SHARED_EXT ".dll"
|
||||
# define OVERLAY_SHARED_EXT_LEN 4
|
||||
#else
|
||||
# define OVERLAY_SHARED_EXT ".so"
|
||||
# define OVERLAY_SHARED_EXT_LEN 3
|
||||
#endif
|
||||
|
||||
/* ============================================================================
|
||||
* Inc3 — Per-entry validity + multi-candidate dispatch (design doc §8)
|
||||
*
|
||||
@@ -953,8 +961,11 @@ static void rebuild_lazy_manifest_index(void) {
|
||||
char path[800];
|
||||
snprintf(path, sizeof(path), "%s", s_cache_idx[ci].path);
|
||||
size_t n = strlen(path);
|
||||
if (n < 4 || strcmp(path + n - 4, ".dll") != 0) continue;
|
||||
snprintf(path + n - 4, sizeof(path) - (n - 4), ".ranges");
|
||||
if (n < OVERLAY_SHARED_EXT_LEN ||
|
||||
strcmp(path + n - OVERLAY_SHARED_EXT_LEN, OVERLAY_SHARED_EXT) != 0)
|
||||
continue;
|
||||
snprintf(path + n - OVERLAY_SHARED_EXT_LEN,
|
||||
sizeof(path) - (n - OVERLAY_SHARED_EXT_LEN), ".ranges");
|
||||
int man_n = 0;
|
||||
ManFn *man = parse_manifest(path, &man_n);
|
||||
if (!man) continue;
|
||||
@@ -1195,9 +1206,10 @@ static void remove_posix_dll_and_manifest(const char *dll_path) {
|
||||
remove(dll_path);
|
||||
char ranges[800];
|
||||
int n = snprintf(ranges, sizeof(ranges), "%s", dll_path);
|
||||
if (n >= 4 && (size_t)n + 4 < sizeof(ranges) &&
|
||||
strcmp(ranges + n - 4, ".dll") == 0) {
|
||||
memcpy(ranges + n - 4, ".ranges", 8);
|
||||
if (n >= OVERLAY_SHARED_EXT_LEN &&
|
||||
(size_t)n + 7 - OVERLAY_SHARED_EXT_LEN < sizeof(ranges) &&
|
||||
strcmp(ranges + n - OVERLAY_SHARED_EXT_LEN, OVERLAY_SHARED_EXT) == 0) {
|
||||
memcpy(ranges + n - OVERLAY_SHARED_EXT_LEN, ".ranges", 8);
|
||||
remove(ranges);
|
||||
}
|
||||
#else
|
||||
@@ -1565,7 +1577,9 @@ int overlay_loader_has_cached_crc(uint32_t region_start, uint32_t crc) {
|
||||
if (s_cache_idx[i].region_start != region_start) continue;
|
||||
const char *fn = strrchr(s_cache_idx[i].path, '/');
|
||||
fn = fn ? fn + 1 : s_cache_idx[i].path;
|
||||
if (strlen(fn) == 21 && (uint32_t)strtoul(fn + 9, NULL, 16) == crc)
|
||||
if (strlen(fn) == 17u + OVERLAY_SHARED_EXT_LEN &&
|
||||
strcmp(fn + 17, OVERLAY_SHARED_EXT) == 0 &&
|
||||
(uint32_t)strtoul(fn + 9, NULL, 16) == crc)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -2218,8 +2232,10 @@ static int load_one_dll(const char *dll_path) {
|
||||
char ranges_path[800];
|
||||
snprintf(ranges_path, sizeof(ranges_path), "%s", dll_path);
|
||||
size_t plen = strlen(ranges_path);
|
||||
if (plen >= 4 && strcmp(ranges_path + plen - 4, ".dll") == 0)
|
||||
snprintf(ranges_path + plen - 4, sizeof(ranges_path) - (plen - 4), ".ranges");
|
||||
if (plen >= OVERLAY_SHARED_EXT_LEN &&
|
||||
strcmp(ranges_path + plen - OVERLAY_SHARED_EXT_LEN, OVERLAY_SHARED_EXT) == 0)
|
||||
snprintf(ranges_path + plen - OVERLAY_SHARED_EXT_LEN,
|
||||
sizeof(ranges_path) - (plen - OVERLAY_SHARED_EXT_LEN), ".ranges");
|
||||
|
||||
int man_n = 0;
|
||||
ManFn *man = parse_manifest(ranges_path, &man_n);
|
||||
|
||||
@@ -24,8 +24,13 @@ static int parse_hex8(const char *text, uint32_t *value) {
|
||||
int psx_overlay_cache_name_parse(const char *name, uint32_t *region_start,
|
||||
uint32_t *content_crc) {
|
||||
uint32_t addr = 0, crc = 0;
|
||||
if (!name || strlen(name) != 21 || name[8] != '_' ||
|
||||
strcmp(name + 17, ".dll") != 0 ||
|
||||
#ifdef _WIN32
|
||||
static const char extension[] = ".dll";
|
||||
#else
|
||||
static const char extension[] = ".so";
|
||||
#endif
|
||||
if (!name || strlen(name) != 17 + sizeof(extension) - 1 || name[8] != '_' ||
|
||||
strcmp(name + 17, extension) != 0 ||
|
||||
!parse_hex8(name, &addr) || !parse_hex8(name + 9, &crc))
|
||||
return 0;
|
||||
if (region_start) *region_start = addr;
|
||||
|
||||
@@ -9,14 +9,14 @@ cache="$tmp/cache"
|
||||
base="$tmp/tags"
|
||||
expected="cg12_11111111"
|
||||
other="cg12_22222222"
|
||||
mkdir -p "$cache/00000000_11111111.dll" "$base/$expected" "$base/$other"
|
||||
mkdir -p "$cache/00000000_11111111.so" "$base/$expected" "$base/$other"
|
||||
|
||||
cc -std=c99 -Wall -Wextra -Werror -fPIC -shared \
|
||||
"$root/runtime/tests/overlay_posix_fixture.c" \
|
||||
-o "$cache/80010000_DEADBEEF.dll"
|
||||
: > "$cache/00000000_00000000.dll"
|
||||
: > "$cache/80010000_DEADBEG0.dll"
|
||||
: > "$base/$other/80020000_12345678.dll"
|
||||
-o "$cache/80010000_DEADBEEF.so"
|
||||
: > "$cache/00000000_00000000.so"
|
||||
: > "$cache/80010000_DEADBEG0.so"
|
||||
: > "$base/$other/80020000_12345678.so"
|
||||
|
||||
cc -std=c99 -Wall -Wextra -Werror \
|
||||
-I"$root/runtime/include" \
|
||||
|
||||
@@ -14,7 +14,7 @@ typedef struct ScanResult {
|
||||
static int record_cache_file(const PsxOverlayCacheFile *file, void *opaque) {
|
||||
ScanResult *result = (ScanResult *)opaque;
|
||||
result->count++;
|
||||
if (strcmp(file->name, "80010000_DEADBEEF.dll") == 0) {
|
||||
if (strcmp(file->name, "80010000_DEADBEEF.so") == 0) {
|
||||
result->addr = file->region_start;
|
||||
result->crc = file->content_crc;
|
||||
}
|
||||
@@ -23,16 +23,16 @@ static int record_cache_file(const PsxOverlayCacheFile *file, void *opaque) {
|
||||
|
||||
static void check_name_parser(void) {
|
||||
uint32_t addr = 1, crc = 1;
|
||||
assert(psx_overlay_cache_name_parse("00000000_00000000.dll", &addr, &crc));
|
||||
assert(psx_overlay_cache_name_parse("00000000_00000000.so", &addr, &crc));
|
||||
assert(addr == 0 && crc == 0);
|
||||
assert(psx_overlay_cache_name_parse("89abcdef_ABCDEF01.dll", &addr, &crc));
|
||||
assert(psx_overlay_cache_name_parse("89abcdef_ABCDEF01.so", &addr, &crc));
|
||||
assert(addr == 0x89ABCDEFu && crc == 0xABCDEF01u);
|
||||
|
||||
assert(!psx_overlay_cache_name_parse("G0010000_DEADBEEF.dll", &addr, &crc));
|
||||
assert(!psx_overlay_cache_name_parse("80010000_DEADBEG0.dll", &addr, &crc));
|
||||
assert(!psx_overlay_cache_name_parse("80010000_DEADBEEF.so", &addr, &crc));
|
||||
assert(!psx_overlay_cache_name_parse("80010000-DEADBEEF.dll", &addr, &crc));
|
||||
assert(!psx_overlay_cache_name_parse("80010000_DEADBEEF.dll.extra", &addr, &crc));
|
||||
assert(!psx_overlay_cache_name_parse("G0010000_DEADBEEF.so", &addr, &crc));
|
||||
assert(!psx_overlay_cache_name_parse("80010000_DEADBEG0.so", &addr, &crc));
|
||||
assert(!psx_overlay_cache_name_parse("80010000_DEADBEEF.dll", &addr, &crc));
|
||||
assert(!psx_overlay_cache_name_parse("80010000-DEADBEEF.so", &addr, &crc));
|
||||
assert(!psx_overlay_cache_name_parse("80010000_DEADBEEF.so.extra", &addr, &crc));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
@@ -55,7 +55,7 @@ int main(int argc, char **argv) {
|
||||
assert(handle == NULL); /* A directory is not a loadable overlay library. */
|
||||
|
||||
char fixture[1024];
|
||||
snprintf(fixture, sizeof(fixture), "%s/80010000_DEADBEEF.dll", argv[1]);
|
||||
snprintf(fixture, sizeof(fixture), "%s/80010000_DEADBEEF.so", argv[1]);
|
||||
handle = psx_overlay_posix_library_open(fixture, error, sizeof(error));
|
||||
assert(handle != NULL);
|
||||
typedef int (*AbiFn)(void);
|
||||
|
||||
@@ -151,6 +151,11 @@ def is_windows() -> bool:
|
||||
or platform.system().startswith(('MSYS', 'CYGWIN', 'MINGW')))
|
||||
|
||||
|
||||
def overlay_ext() -> str:
|
||||
"""Use the host platform's conventional shared-library suffix."""
|
||||
return '.dll' if is_windows() else '.so'
|
||||
|
||||
|
||||
def cache_arch_abi() -> str:
|
||||
"""Canonical cache arch-abi tag, IDENTICAL to overlay_loader.c's
|
||||
PSX_OVERLAY_ARCH_ABI ("<os>-<arch>": win|linux|macos + x64|arm64|x86).
|
||||
@@ -1686,7 +1691,7 @@ def compile_interior_fragment(interior: int, data: bytes, load_addr: int,
|
||||
key = binascii.crc32(b''.join(
|
||||
struct.pack('<II', ev, crc)
|
||||
for ev, crc, _ in sorted(frag_ids))) & 0xFFFFFFFF
|
||||
dll_path = os.path.join(cache_dir, f'{phys_addr:08X}_{key:08X}.dll')
|
||||
dll_path = os.path.join(cache_dir, f'{phys_addr:08X}_{key:08X}{overlay_ext()}')
|
||||
if os.path.exists(dll_path) and not args.force:
|
||||
return frag_ids # already built
|
||||
patched_c = os.path.join(tmp, 'frag_patched.c')
|
||||
@@ -1708,7 +1713,7 @@ def compile_interior_fragment(interior: int, data: bytes, load_addr: int,
|
||||
if not compile_dll(patched_c, dll_path, include_dirs,
|
||||
gcc=args.gcc, flavor=args.flavor):
|
||||
return None
|
||||
write_overlay_ranges_from(frag_ids, dll_path[:-4] + '.ranges')
|
||||
write_overlay_ranges_from(frag_ids, os.path.splitext(dll_path)[0] + '.ranges')
|
||||
return frag_ids
|
||||
|
||||
|
||||
@@ -2075,7 +2080,7 @@ def main():
|
||||
_interiors | _disp_roots, _executed))
|
||||
|
||||
if not args.static:
|
||||
dll_path = os.path.join(cache_dir, f'{phys_addr:08X}_{crc32:08X}.dll')
|
||||
dll_path = os.path.join(cache_dir, f'{phys_addr:08X}_{crc32:08X}{overlay_ext()}')
|
||||
|
||||
print(f'Overlay load=0x{load_addr:08X} size={size} crc32=0x{crc32:08X}')
|
||||
if args.static:
|
||||
@@ -2269,7 +2274,7 @@ def main():
|
||||
# Emit the per-entry code-range manifest beside the DLL from
|
||||
# the same func-id list we keyed the dedup on. The loader keys
|
||||
# it by the same filename stem with .ranges (replacing .dll).
|
||||
ranges_out = dll_path[:-4] + '.ranges'
|
||||
ranges_out = os.path.splitext(dll_path)[0] + '.ranges'
|
||||
if this_ids:
|
||||
nfn = write_overlay_ranges_from(this_ids, ranges_out)
|
||||
print(f' ranges: {nfn} functions -> {ranges_out}')
|
||||
|
||||
Reference in New Issue
Block a user