mirror of
https://github.com/ptitSeb/box64.git
synced 2026-11-07 09:26:11 -10:00
[DYNACACHE] Added auto-generated DynaCache versions (#3858)
* [DYNACACHE] Added auto-generated DynaCache versions * Guarded dynacache_hashes.h with DYNAREC
This commit is contained in:
1 parent
75721e4f97
commit
6ccba477de
5 files changed
+132
-21
No files matched your search
@@ -58,6 +58,7 @@ build*/
|
||||
.cache
|
||||
.gdb_history
|
||||
src/git_head.h
|
||||
src/dynacache_hashes.h
|
||||
backup/
|
||||
|
||||
# Wrapper helper
|
||||
|
||||
+12
-1
@@ -393,9 +393,19 @@ if(BOX32)
|
||||
)
|
||||
endif()
|
||||
|
||||
# git_head.h is a generated file
|
||||
set(DYNACACHE_HASH_HEADER "${BOX64_ROOT}/src/dynacache_hashes.h")
|
||||
add_custom_target(generate_dynacache_hashes
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${BOX64_ROOT}/tools/gen_dynacache_hashes.py"
|
||||
--root "${BOX64_ROOT}"
|
||||
--output "${DYNACACHE_HASH_HEADER}"
|
||||
BYPRODUCTS "${DYNACACHE_HASH_HEADER}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# generated files
|
||||
set_source_files_properties(
|
||||
"${BOX64_ROOT}/src/git_head.h"
|
||||
"${BOX64_ROOT}/src/dynacache_hashes.h"
|
||||
PROPERTIES GENERATED TRUE
|
||||
HEADER_FILE_ONLY TRUE)
|
||||
|
||||
@@ -1299,6 +1309,7 @@ add_library(interpreter OBJECT ${INTERPRETER})
|
||||
|
||||
add_library(mainobj OBJECT ${OS_LINUX_SRC} ${ELFLOADER_SRC} ${WRAPPEDS} ${WRAPPEDS32})
|
||||
add_dependencies(mainobj generate_git_head_target)
|
||||
add_dependencies(mainobj generate_dynacache_hashes)
|
||||
|
||||
add_executable(${BOX64})
|
||||
target_link_libraries(${BOX64} mainobj)
|
||||
|
||||
+9
-20
@@ -21,6 +21,9 @@
|
||||
#include "rbtree.h"
|
||||
#include "wine_tools.h"
|
||||
#include "pe_tools.h"
|
||||
#ifdef DYNAREC
|
||||
#include "dynacache_hashes.h"
|
||||
#endif
|
||||
|
||||
box64env_t box64env = { 0 };
|
||||
|
||||
@@ -916,31 +919,17 @@ done:
|
||||
}
|
||||
|
||||
/*
|
||||
There is 3 version to change when evoling things, depending on what is changed:
|
||||
1. FILE_VERSION for the DynaCache infrastructure
|
||||
2. DYNAREC_VERSION for dynablock_t changes and other global dynarec change
|
||||
3. ARCH_VERSION for the architecture specific changes (and there is one per arch)
|
||||
There are 3 compatibility values for DynaCache:
|
||||
1. FILE_VERSION for the DynaCache infrastructure and file format
|
||||
2. DYNAREC_VERSION as the generated hash of common dynarec sources
|
||||
3. ARCH_VERSION as the generated hash of the active backend sources
|
||||
|
||||
An ARCH_VERSION of 0 means Unsupported and disable DynaCache.
|
||||
Dynacache will ignore any DynaCache file not exactly matching those 3 version.
|
||||
`box64 --dynacache-clean` can be used from command line to purge obsolete DyaCache files
|
||||
*/
|
||||
|
||||
#define FILE_VERSION 2
|
||||
#define HEADER_SIGN "DynaCache"
|
||||
#define SET_VERSION(MAJ, MIN, REV) (((MAJ)<<24)|((MIN)<<16)|(REV))
|
||||
#ifdef ARM64
|
||||
#define ARCH_VERSION SET_VERSION(0, 0, 14)
|
||||
#elif defined(RV64)
|
||||
#define ARCH_VERSION SET_VERSION(0, 0, 5)
|
||||
#elif defined(LA64)
|
||||
#define ARCH_VERSION SET_VERSION(0, 0, 8)
|
||||
#elif defined(PPC64LE)
|
||||
#define ARCH_VERSION SET_VERSION(0, 0, 1)
|
||||
#else
|
||||
#error meh!
|
||||
#endif
|
||||
#define DYNAREC_VERSION SET_VERSION(0, 1, 1)
|
||||
#define FILE_VERSION 2
|
||||
#define HEADER_SIGN "DynaCache"
|
||||
|
||||
typedef struct DynaCacheHeader_s {
|
||||
char sign[10]; //"DynaCache\0"
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import List, Set, Tuple
|
||||
|
||||
|
||||
ARCH_DIRS = ("arm64", "la64", "rv64", "ppc64le")
|
||||
GROUPS = (
|
||||
("COMMON", Path("src/dynarec"), set(ARCH_DIRS)),
|
||||
("ARM64", Path("src/dynarec/arm64"), set()),
|
||||
("LOONGARCH64", Path("src/dynarec/la64"), set()),
|
||||
("RISCV64", Path("src/dynarec/rv64"), set()),
|
||||
("PPC64LE", Path("src/dynarec/ppc64le"), set()),
|
||||
)
|
||||
|
||||
|
||||
def iter_files(base: Path, excluded_dirs: Set[str]) -> List[Path]:
|
||||
files: List[Path] = []
|
||||
for path in sorted(base.rglob("*")):
|
||||
if not path.is_file():
|
||||
continue
|
||||
rel_parts = path.relative_to(base).parts
|
||||
if excluded_dirs and rel_parts and rel_parts[0] in excluded_dirs:
|
||||
continue
|
||||
files.append(path)
|
||||
return files
|
||||
|
||||
|
||||
def hash_files(root: Path, files: List[Path]) -> int:
|
||||
digest = hashlib.sha256()
|
||||
for path in files:
|
||||
rel_path = path.relative_to(root).as_posix().encode("utf-8")
|
||||
digest.update(rel_path)
|
||||
digest.update(b"\0")
|
||||
digest.update(path.read_bytes())
|
||||
digest.update(b"\0")
|
||||
value = int.from_bytes(digest.digest()[:3], "big")
|
||||
return value or 1
|
||||
|
||||
|
||||
def render_header(root: Path) -> str:
|
||||
values: List[Tuple[str, int]] = []
|
||||
for name, rel_base, excluded_dirs in GROUPS:
|
||||
base = root / rel_base
|
||||
files = iter_files(base, excluded_dirs)
|
||||
if not files:
|
||||
raise RuntimeError(f"no files found for {name.lower()} hash in {base}")
|
||||
values.append((name, hash_files(root, files)))
|
||||
hashes = dict(values)
|
||||
|
||||
lines = [
|
||||
"/* Auto-generated by tools/gen_dynacache_hashes.py. Do not edit. */",
|
||||
"#ifndef __DYNACACHE_HASHES_H__",
|
||||
"#define __DYNACACHE_HASHES_H__",
|
||||
"",
|
||||
f"#define DYNAREC_VERSION 0x{hashes['COMMON']:06X}u",
|
||||
"",
|
||||
"#if defined(ARM64)",
|
||||
f"#define ARCH_VERSION 0x{hashes['ARM64']:06X}u",
|
||||
"#elif defined(RV64)",
|
||||
f"#define ARCH_VERSION 0x{hashes['RISCV64']:06X}u",
|
||||
"#elif defined(LA64)",
|
||||
f"#define ARCH_VERSION 0x{hashes['LOONGARCH64']:06X}u",
|
||||
"#elif defined(PPC64LE)",
|
||||
f"#define ARCH_VERSION 0x{hashes['PPC64LE']:06X}u",
|
||||
"#else",
|
||||
"#error Unsupported architecture",
|
||||
"#endif",
|
||||
"",
|
||||
"#endif",
|
||||
]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def write_if_changed(path: Path, content: str) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
if path.exists() and path.read_text(encoding="utf-8") == content:
|
||||
return
|
||||
tmp_path = path.with_suffix(f"{path.suffix}.{os.getpid()}.tmp")
|
||||
tmp_path.write_text(content, encoding="utf-8")
|
||||
tmp_path.replace(path)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--root", required=True)
|
||||
parser.add_argument("--output", required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
root = Path(args.root).resolve()
|
||||
output = Path(args.output).resolve()
|
||||
write_if_changed(output, render_header(root))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -119,6 +119,16 @@ include_directories(
|
||||
"${BOX64_ROOT}/external/musl/internal"
|
||||
)
|
||||
|
||||
set(DYNACACHE_HASH_HEADER "${BOX64_ROOT}/src/dynacache_hashes.h")
|
||||
add_custom_target(generate_dynacache_hashes
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${BOX64_ROOT}/tools/gen_dynacache_hashes.py"
|
||||
--root "${BOX64_ROOT}"
|
||||
--output "${DYNACACHE_HASH_HEADER}"
|
||||
BYPRODUCTS "${DYNACACHE_HASH_HEADER}"
|
||||
VERBATIM
|
||||
)
|
||||
add_dependencies(wowbox64 generate_dynacache_hashes)
|
||||
|
||||
set(DLLTOOL aarch64-w64-mingw32-dlltool)
|
||||
|
||||
function(import_dll name)
|
||||
|
||||
Reference in new issue
Block a user